Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions NuGet.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<clear />
<add key="react-native" value="https://pkgs.dev.azure.com/ms/react-native/_packaging/react-native-public/nuget/v3/index.json" />
<add key="Nuget.org" value="https://api.nuget.org/v3/index.json" />
</packageSources>
<disabledPackageSources>
<clear />
</disabledPackageSources>
</configuration>
6 changes: 6 additions & 0 deletions example/NuGet.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<!-- This placeholder file is reserved for future use, but also to prevent
using the config from the cpp-app template, allowing the lib to rely on
config file added to its root. -->
</configuration>
1 change: 1 addition & 0 deletions example/android/gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ newArchEnabled=true
# Use this property to enable or disable the Hermes JS engine.
# If set to false, you will be using JSC instead.
hermesEnabled=true
hermesV1Enabled=true

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need it? I don't think I had any problems without it, and RN docs for v0.84 tell Hermes V1 is the default with no need for any config changes?

https://reactnative.dev/blog/2026/02/11/react-native-0.84#hermes-v1-as-default

@hsjoberg hsjoberg Mar 27, 2026

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is mysterious yes as Hermes V1 is the default now.
However, I ran into gradle dependencies issues without setting this flag explicitly.

FAILURE: Build failed with an exception.

* What went wrong:
Could not determine the dependencies of task ':app:compileDebugJavaWithJavac'.
> Could not resolve all dependencies for configuration ':app:debugCompileClasspath'.
   > Could not find com.facebook.react:hermes-android:0.84.0.
     Required by:
         project ':app'

I guess if it works for you in the example app without then should be fine. Maybe some local machine shenanigans.

I can dig deeper on this one if you want.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like build problems on Android without this flag were caused by having react-native-windows@0.82 installed alongside react-native@0.84. Gonna remove react-native-windows for now from all package.json files, so that it does not mess anything on other platforms, and to run the example on Windows it will be necessary to install it explicitly.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see. Yeah that's reasonable.
Hopefully react-native-windows gets up-to-date soon.


# Use this property to enable edge-to-edge display support.
# This allows your app to draw behind system bars for an immersive UI.
Expand Down
35 changes: 32 additions & 3 deletions example/metro.config.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
const path = require('path');
const { getDefaultConfig } = require('@react-native/metro-config');
const { withMetroConfig } = require('react-native-monorepo-config');
const {getDefaultConfig, mergeConfig} = require('@react-native/metro-config');
const {withMetroConfig} = require('react-native-monorepo-config');

const fs = require('fs');

const rnwPath = fs.realpathSync(
path.resolve(require.resolve('react-native-windows/package.json'), '..'),
);
const normalizedRnwPath = rnwPath.replace(/[/\\]/g, '/');

const root = path.resolve(__dirname, '..');

Expand All @@ -10,9 +17,31 @@ const root = path.resolve(__dirname, '..');
*
* @type {import('metro-config').MetroConfig}
*/

const config = withMetroConfig(getDefaultConfig(__dirname), {
root,
dirname: __dirname,
});

module.exports = config;
module.exports = mergeConfig(config, {
resolver: {
blockList: [
// This stops "npx @react-native-community/cli run-windows" from causing the metro server to crash if its already running
new RegExp(
`${path.resolve(__dirname, 'windows').replace(/[/\\]/g, '/')}.*`,
),
// This prevents "npx @react-native-community/cli run-windows" from hitting: EBUSY: resource busy or locked, open msbuild.ProjectImports.zip or other files produced by msbuild
new RegExp(`${normalizedRnwPath}/build/.*`),
new RegExp(`${normalizedRnwPath}/target/.*`),
/.*\.ProjectImports\.zip/,
],
},
transformer: {
getTransformOptions: async () => ({
transform: {
experimentalImportSupport: false,
inlineRequires: true,
},
}),
},
});
6 changes: 4 additions & 2 deletions example/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"android:prod": "react-native run-android --mode release",
"ios": "react-native run-ios",
"start": "react-native start",
"windows": "react-native run-windows",
"windows:autolink": "./node_modules/.bin/rnc-cli autolink-windows --sln \"windows\\ReactNativeFsExample.sln\" --proj \"windows\\ReactNativeFsExample\\ReactNativeFsExample.vcxproj\"",
"build:android": "react-native build-android --extra-params \"--no-daemon --console=plain -PreactNativeArchitectures=arm64-v8a\"",
"build:ios": "react-native build-ios --mode Debug"
Expand All @@ -16,7 +17,8 @@
"lodash": "^4.17.23",
"react": "19.2.3",
"react-native": "0.84.0",
"react-native-safe-area-context": "^5.6.2"
"react-native-safe-area-context": "^5.6.2",
"react-native-windows": "0.82.0"
},
"devDependencies": {
"@babel/core": "^7.29.0",
Expand All @@ -40,7 +42,7 @@
"init-windows": {
"name": "ReactNativeFsExample",
"namespace": "ReactNativeFsExample",
"template": "old/uwp-cpp-app"
"template": "cpp-app"
}
}
}
6 changes: 6 additions & 0 deletions example/react-native.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@ module.exports = {
// So we explicitly specify the platforms with empty object
ios: {},
android: {},
windows: {},
},
},
'@dr.pogodin/react-native-static-server': {
platforms: {
windows: null,
},
},
},
Expand Down
1 change: 1 addition & 0 deletions example/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ const AppContent: FunctionComponent = () => {
{/* This does not quite fit into the test app style,
but I don't have time now to style the new test section well. */}
<Button
color="blue"
onPress={async () => {
const res = await pickFile();
Alert.alert(`Picked ${res.length} file(s)`, res.join('; '));
Expand Down
3 changes: 3 additions & 0 deletions example/src/methods/upload.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ const UPLOAD_FILES_CONTROL = Platform.select({

export const uploadTests: TestMethods = {
'uploadFiles() should upload files': async () => {
if (Platform.OS === 'windows') return Result.notAvailable('windows');
try {
// prepare
const server = await waitServer();
Expand Down Expand Up @@ -121,6 +122,7 @@ export const uploadTests: TestMethods = {
}
},
'uploadFiles() should handle HTTP errors': async () => {
if (Platform.OS === 'windows') return Result.notAvailable('windows');
try {
// prepare
const server = await waitServer();
Expand Down Expand Up @@ -154,6 +156,7 @@ export const uploadTests: TestMethods = {
}
},
'stopUpload() should stop an upload process [iOS]': async () => {
if (Platform.OS === 'windows') return Result.notAvailable('windows');

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess, this is effectively covered by the next line? Also the argument(s) of .notAvailable() is (are) the platforms where the feature is available / test should work; so to get correct error messages, all previous instance of .notAvailable() you added should have different arguments (and probably, it is a good idea for me to do something with that helper function to be less confusing).

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, good point this is silly. No need.

if (notPlatform('ios')) return Result.notAvailable('ios');
const uploadFileName = 'upload-file-3.txt'; //! no support for ÄÖÜ
try {
Expand Down
21 changes: 19 additions & 2 deletions example/src/testServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {
unlink,
} from '@dr.pogodin/react-native-fs';

import Server from '@dr.pogodin/react-native-static-server';
import type StaticServer from '@dr.pogodin/react-native-static-server';
import { Platform } from 'react-native';

// NOTE: The path resolved for server by resolveAssetsPath()
Expand All @@ -14,16 +14,23 @@ export const FILE_DIR = Platform.select({
default: `${TemporaryDirectoryPath}test-server`,
});

let serverPromise: Promise<Server> | undefined;
let serverPromise: Promise<StaticServer> | undefined;

export async function start() {
if (Platform.OS === 'windows') {
return undefined;
}

if (!serverPromise) {
serverPromise = new Promise(async (resolve, reject) => {
try {
try {
await unlink(FILE_DIR);
} catch {}
await mkdir(`${FILE_DIR}/dav`);
const Server = require(
'@dr.pogodin/react-native-static-server',
).default as typeof import('@dr.pogodin/react-native-static-server').default;
Comment on lines +31 to +33

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm... wouldn't it work with just?

const Server = await import('@dr.pogodin/react-native-static-server');

@hsjoberg hsjoberg Mar 27, 2026

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is enough yes, however adding as typeof import('@dr.pogodin/react-native-static-server').default; gave type info (any otherwise for me).

const server = new Server({
fileDir: FILE_DIR,
port: 3000,
Expand Down Expand Up @@ -59,6 +66,10 @@ export async function start() {
}

export async function stop() {
if (Platform.OS === 'windows') {
return;
}

if (serverPromise) {
const server = await serverPromise;
await server.stop();
Expand All @@ -67,5 +78,11 @@ export async function stop() {
}

export async function waitServer() {
if (Platform.OS === 'windows') {
throw new Error(
'@dr.pogodin/react-native-static-server is disabled on Windows until it supports RNW new architecture.',
);
}

return serverPromise || start();
}
138 changes: 46 additions & 92 deletions example/windows/.gitignore
Original file line number Diff line number Diff line change
@@ -1,92 +1,46 @@
*AppPackages*
*BundleArtifacts*

#OS junk files
[Tt]humbs.db
*.DS_Store

#Visual Studio files
*.[Oo]bj
*.user
*.aps
*.pch
*.vspscc
*.vssscc
*_i.c
*_p.c
*.ncb
*.suo
*.tlb
*.tlh
*.bak
*.[Cc]ache
*.ilk
*.log
*.lib
*.sbr
*.sdf
*.opensdf
*.opendb
*.unsuccessfulbuild
ipch/
[Oo]bj/
[Bb]in
[Dd]ebug*/
[Rr]elease*/
Ankh.NoLoad

# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb

#MonoDevelop
*.pidb
*.userprefs

#Tooling
_ReSharper*/
*.resharper
[Tt]est[Rr]esult*
*.sass-cache

#Project files
[Bb]uild/

#Subversion files
.svn

# Office Temp Files
~$*

# vim Temp Files
*~

#NuGet
packages/
*.nupkg

#ncrunch
*ncrunch*
*crunch*.local.xml

# visual studio database projects
*.dbmdl

#Test files
*.testsettings

#Other files
*.DotSettings
.vs/
*project.lock.json

#Files generated by the VS build
**/Generated Files/**

*AppPackages*
*BundleArtifacts*

#OS junk files
[Tt]humbs.db
*.DS_Store

#Visual Studio files
*.[Oo]bj
*.user
*.aps
*.pch
*.vspscc
*.vssscc
*_i.c
*_p.c
*.ncb
*.suo
*.tlb
*.tlh
*.bak
*.[Cc]ache
*.ilk
*.log
*.lib
*.sbr
*.sdf
*.opensdf
*.opendb
*.unsuccessfulbuild
ipch/
[Oo]bj/
[Bb]in
[Dd]ebug*/
[Rr]elease*/
Ankh.NoLoad
.vs/
# Visual C++ cache files

#Files generated by the VS build
**/Generated Files/**

#Files generated by MS build
*.binlog
*.err
*.wrn
Loading