vxrn 2.0.0-beta.98.1 → 2.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/backgroundComputation.mjs +145 -0
- package/dist/backgroundComputation.mjs.map +1 -0
- package/dist/backgroundComputation.native.js +163 -0
- package/dist/backgroundComputation.native.js.map +1 -0
- package/dist/backgroundComputationNative.mjs +16 -0
- package/dist/backgroundComputationNative.mjs.map +1 -0
- package/dist/backgroundComputationNative.native.js +18 -0
- package/dist/backgroundComputationNative.native.js.map +1 -0
- package/dist/config/getBaseViteConfigOnly.mjs +6 -10
- package/dist/config/getBaseViteConfigOnly.mjs.map +1 -1
- package/dist/config/getBaseViteConfigOnly.native.js +6 -10
- package/dist/config/getBaseViteConfigOnly.native.js.map +1 -1
- package/dist/config/getOptimizeDeps.mjs +2 -1
- package/dist/config/getOptimizeDeps.mjs.map +1 -1
- package/dist/config/getOptimizeDeps.native.js +2 -1
- package/dist/config/getOptimizeDeps.native.js.map +1 -1
- package/dist/config/getViteServerConfig.mjs +13 -0
- package/dist/config/getViteServerConfig.mjs.map +1 -1
- package/dist/config/getViteServerConfig.native.js +15 -1
- package/dist/config/getViteServerConfig.native.js.map +1 -1
- package/dist/constants/defaults.mjs +4 -0
- package/dist/constants/defaults.mjs.map +1 -1
- package/dist/constants/defaults.native.js +4 -0
- package/dist/constants/defaults.native.js.map +1 -1
- package/dist/exports/build.native.js +1 -1
- package/dist/exports/build.native.js.map +1 -1
- package/dist/exports/clean.native.js +1 -1
- package/dist/exports/clean.native.js.map +1 -1
- package/dist/exports/createServer.native.js +2 -2
- package/dist/exports/createServer.native.js.map +1 -1
- package/dist/exports/dev.mjs +3 -0
- package/dist/exports/dev.mjs.map +1 -1
- package/dist/exports/dev.native.js +6 -3
- package/dist/exports/dev.native.js.map +1 -1
- package/dist/exports/loadEnv.native.js +1 -1
- package/dist/exports/loadEnv.native.js.map +1 -1
- package/dist/exports/patch.native.js +1 -1
- package/dist/exports/patch.native.js.map +1 -1
- package/dist/exports/prebuild.mjs +0 -22
- package/dist/exports/prebuild.mjs.map +1 -1
- package/dist/exports/prebuild.native.js +1 -23
- package/dist/exports/prebuild.native.js.map +1 -1
- package/dist/exports/prebuildWithoutExpo.mjs +1133 -182
- package/dist/exports/prebuildWithoutExpo.mjs.map +1 -1
- package/dist/exports/prebuildWithoutExpo.native.js +1606 -244
- package/dist/exports/prebuildWithoutExpo.native.js.map +1 -1
- package/dist/exports/runAndroid.native.js +1 -1
- package/dist/exports/runAndroid.native.js.map +1 -1
- package/dist/exports/runIos.native.js +1 -1
- package/dist/exports/runIos.native.js.map +1 -1
- package/dist/exports/serve.native.js +1 -1
- package/dist/exports/serve.native.js.map +1 -1
- package/dist/exports/serveStaticAssets.native.js +1 -1
- package/dist/exports/serveStaticAssets.native.js.map +1 -1
- package/dist/index.js +4 -1
- package/dist/index.mjs +4 -1
- package/dist/index.native.js +4 -1
- package/dist/native-source-contract.mjs +3 -0
- package/dist/native-source-contract.native.js +3 -0
- package/dist/patches/builtInDepPatches.mjs +0 -13
- package/dist/patches/builtInDepPatches.mjs.map +1 -1
- package/dist/patches/builtInDepPatches.native.js +0 -13
- package/dist/patches/builtInDepPatches.native.js.map +1 -1
- package/dist/plugins/autoDepOptimizePlugin.mjs +3 -2
- package/dist/plugins/autoDepOptimizePlugin.mjs.map +1 -1
- package/dist/plugins/autoDepOptimizePlugin.native.js +6 -3
- package/dist/plugins/autoDepOptimizePlugin.native.js.map +1 -1
- package/dist/plugins/backgroundComputationPlugin.mjs +27 -0
- package/dist/plugins/backgroundComputationPlugin.mjs.map +1 -0
- package/dist/plugins/backgroundComputationPlugin.native.js +32 -0
- package/dist/plugins/backgroundComputationPlugin.native.js.map +1 -0
- package/dist/plugins/reactNativeCommonJsPlugin.native.js +3 -3
- package/dist/plugins/reactNativeCommonJsPlugin.native.js.map +1 -1
- package/dist/plugins/reactNativeDevAssetPlugin.mjs +2 -1
- package/dist/plugins/reactNativeDevAssetPlugin.mjs.map +1 -1
- package/dist/plugins/reactNativeDevAssetPlugin.native.js +3 -2
- package/dist/plugins/reactNativeDevAssetPlugin.native.js.map +1 -1
- package/dist/plugins/reactNativeDevServer.mjs +87 -24
- package/dist/plugins/reactNativeDevServer.mjs.map +1 -1
- package/dist/plugins/reactNativeDevServer.native.js +162 -45
- package/dist/plugins/reactNativeDevServer.native.js.map +1 -1
- package/dist/plugins/workletImportsPlugin.mjs +9 -30
- package/dist/plugins/workletImportsPlugin.mjs.map +1 -1
- package/dist/plugins/workletImportsPlugin.native.js +10 -35
- package/dist/plugins/workletImportsPlugin.native.js.map +1 -1
- package/dist/rn-commands/bundle/buildBundle.mjs +3 -3
- package/dist/rn-commands/bundle/buildBundle.mjs.map +1 -1
- package/dist/rn-commands/bundle/buildBundle.native.js +3 -3
- package/dist/rn-commands/bundle/buildBundle.native.js.map +1 -1
- package/dist/runtime/hmr-client.native.js +3 -7
- package/dist/runtime/hmr-client.native.js.map +1 -1
- package/dist/runtime/hmr-runtime.native.js +32 -40
- package/dist/runtime/hmr-runtime.native.js.map +1 -1
- package/dist/serve/node.native.js +2 -2
- package/dist/serve/node.native.js.map +1 -1
- package/dist/swift-package-id.mjs +3 -0
- package/dist/swift-package-id.native.js +3 -0
- package/dist/user-interface/index.native.js +6 -6
- package/dist/user-interface/index.native.js.map +1 -1
- package/dist/utils/compileNativeDevBytecode.mjs +93 -0
- package/dist/utils/compileNativeDevBytecode.mjs.map +1 -0
- package/dist/utils/compileNativeDevBytecode.native.js +98 -0
- package/dist/utils/compileNativeDevBytecode.native.js.map +1 -0
- package/dist/utils/createNativeDevEngine.mjs +227 -20
- package/dist/utils/createNativeDevEngine.mjs.map +1 -1
- package/dist/utils/createNativeDevEngine.native.js +249 -37
- package/dist/utils/createNativeDevEngine.native.js.map +1 -1
- package/dist/utils/execSync.native.js +1 -1
- package/dist/utils/execSync.native.js.map +1 -1
- package/dist/utils/getServerEntry.native.js +2 -2
- package/dist/utils/getServerEntry.native.js.map +1 -1
- package/dist/utils/nativeRun.mjs +32 -16
- package/dist/utils/nativeRun.mjs.map +1 -1
- package/dist/utils/nativeRun.native.js +43 -18
- package/dist/utils/nativeRun.native.js.map +1 -1
- package/dist/utils/nativeSourceContract.mjs +1823 -0
- package/dist/utils/nativeSourceContract.mjs.map +1 -0
- package/dist/utils/nativeSourceContract.native.js +2425 -0
- package/dist/utils/nativeSourceContract.native.js.map +1 -0
- package/dist/utils/patches.native.js +15 -24
- package/dist/utils/patches.native.js.map +1 -1
- package/dist/utils/printServerUrls.native.js +1 -1
- package/dist/utils/printServerUrls.native.js.map +1 -1
- package/dist/utils/scanDepsToOptimize.mjs +7 -1
- package/dist/utils/scanDepsToOptimize.mjs.map +1 -1
- package/dist/utils/scanDepsToOptimize.native.js +27 -2
- package/dist/utils/scanDepsToOptimize.native.js.map +1 -1
- package/dist/utils/swiftPackageId.mjs +31 -2
- package/dist/utils/swiftPackageId.mjs.map +1 -1
- package/dist/utils/swiftPackageId.native.js +50 -2
- package/dist/utils/swiftPackageId.native.js.map +1 -1
- package/dist/vxrn-vite-plugin.native.js +1 -1
- package/dist/vxrn-vite-plugin.native.js.map +1 -1
- package/expo-plugin.cjs +792 -2
- package/native-project-patches.cjs +201 -10
- package/package.json +34 -15
- package/src/backgroundComputation.ts +220 -0
- package/src/backgroundComputationNative.ts +23 -0
- package/src/config/getBaseViteConfigOnly.ts +8 -9
- package/src/config/getOptimizeDeps.ts +3 -1
- package/src/config/getViteServerConfig.ts +16 -0
- package/src/config/glbAssets.test.ts +228 -0
- package/src/constants/defaults.ts +6 -0
- package/src/exports/dev.ts +5 -1
- package/src/exports/expoPlugin.test.mjs +337 -15
- package/src/exports/prebuild.ts +0 -31
- package/src/exports/prebuildWithoutExpo.test.ts +1623 -46
- package/src/exports/prebuildWithoutExpo.ts +1606 -216
- package/src/index.ts +8 -0
- package/src/native-source-contract.ts +16 -0
- package/src/patches/builtInDepPatches.ts +0 -21
- package/src/plugins/autoDepOptimizePlugin.ts +7 -2
- package/src/plugins/backgroundComputationPlugin.test.ts +77 -0
- package/src/plugins/backgroundComputationPlugin.ts +29 -0
- package/src/plugins/reactNativeDevAssetPlugin.ts +5 -1
- package/src/plugins/reactNativeDevServer.test.ts +74 -0
- package/src/plugins/reactNativeDevServer.ts +145 -28
- package/src/plugins/rnCodegenPlugin.test.ts +30 -0
- package/src/plugins/workletImportsPlugin.ts +19 -37
- package/src/rn-commands/bundle/buildBundle.ts +5 -3
- package/src/swift-package-id.ts +1 -0
- package/src/utils/compileNativeDevBytecode.test.ts +168 -0
- package/src/utils/compileNativeDevBytecode.ts +117 -0
- package/src/utils/createNativeDevEngine.test.ts +643 -18
- package/src/utils/createNativeDevEngine.ts +278 -48
- package/src/utils/nativeRun.test.ts +125 -23
- package/src/utils/nativeRun.ts +51 -23
- package/src/utils/nativeSourceArtifacts.test.ts +39 -0
- package/src/utils/nativeSourceContract.test.ts +600 -0
- package/src/utils/nativeSourceContract.ts +1897 -0
- package/src/utils/scanDepsToOptimize.test.ts +80 -0
- package/src/utils/scanDepsToOptimize.ts +18 -7
- package/src/utils/swiftPackageId.ts +25 -1
- package/types/backgroundComputation.d.ts +28 -0
- package/types/backgroundComputation.d.ts.map +1 -0
- package/types/backgroundComputationNative.d.ts +2 -0
- package/types/backgroundComputationNative.d.ts.map +1 -0
- package/types/config/getBaseViteConfigOnly.d.ts.map +1 -1
- package/types/config/getOptimizeDeps.d.ts.map +1 -1
- package/types/config/getViteServerConfig.d.ts.map +1 -1
- package/types/constants/defaults.d.ts.map +1 -1
- package/types/exports/dev.d.ts.map +1 -1
- package/types/exports/prebuild.d.ts.map +1 -1
- package/types/exports/prebuildWithoutExpo.d.ts +6 -0
- package/types/exports/prebuildWithoutExpo.d.ts.map +1 -1
- package/types/index.d.ts +2 -0
- package/types/index.d.ts.map +1 -1
- package/types/native-source-contract.d.ts +2 -0
- package/types/native-source-contract.d.ts.map +1 -0
- package/types/patches/builtInDepPatches.d.ts.map +1 -1
- package/types/plugins/autoDepOptimizePlugin.d.ts.map +1 -1
- package/types/plugins/backgroundComputationPlugin.d.ts +3 -0
- package/types/plugins/backgroundComputationPlugin.d.ts.map +1 -0
- package/types/plugins/reactNativeDevAssetPlugin.d.ts.map +1 -1
- package/types/plugins/reactNativeDevServer.d.ts.map +1 -1
- package/types/plugins/workletImportsPlugin.d.ts.map +1 -1
- package/types/rn-commands/bundle/buildBundle.d.ts.map +1 -1
- package/types/swift-package-id.d.ts +2 -0
- package/types/swift-package-id.d.ts.map +1 -0
- package/types/utils/compileNativeDevBytecode.d.ts +3 -0
- package/types/utils/compileNativeDevBytecode.d.ts.map +1 -0
- package/types/utils/createNativeDevEngine.d.ts +7 -22
- package/types/utils/createNativeDevEngine.d.ts.map +1 -1
- package/types/utils/nativeRun.d.ts.map +1 -1
- package/types/utils/nativeSourceContract.d.ts +121 -0
- package/types/utils/nativeSourceContract.d.ts.map +1 -0
- package/types/utils/scanDepsToOptimize.d.ts +1 -0
- package/types/utils/scanDepsToOptimize.d.ts.map +1 -1
- package/types/utils/swiftPackageId.d.ts +1 -0
- package/types/utils/swiftPackageId.d.ts.map +1 -1
|
@@ -5,8 +5,8 @@ const path = require('node:path')
|
|
|
5
5
|
function hasNitroWebImage(root) {
|
|
6
6
|
const projectRequire = createRequire(path.join(root, 'package.json'))
|
|
7
7
|
try {
|
|
8
|
-
const
|
|
9
|
-
projectRequire.resolve('react-native-nitro-web-image/package.json', { paths: [
|
|
8
|
+
const oneRoot = path.dirname(projectRequire.resolve('one/package.json'))
|
|
9
|
+
projectRequire.resolve('react-native-nitro-web-image/package.json', { paths: [oneRoot] })
|
|
10
10
|
return true
|
|
11
11
|
} catch {
|
|
12
12
|
return false
|
|
@@ -36,6 +36,30 @@ function injectNitroWebImageModularHeaderIntoPodfile(podfile) {
|
|
|
36
36
|
*/
|
|
37
37
|
const FMT_CXX17_MARKER = '# [vxrn/one] fmt c++17 fix'
|
|
38
38
|
|
|
39
|
+
const WEBGPU_HEADERS_MARKER = '# [vxrn/one] webgpu isolated package headers'
|
|
40
|
+
|
|
41
|
+
function injectWebGPUHeaderPathsIntoPodfile(podfile) {
|
|
42
|
+
if (podfile.includes(WEBGPU_HEADERS_MARKER)) return podfile
|
|
43
|
+
const match = podfile.match(/post_install\s+do\s+\|installer\|/)
|
|
44
|
+
if (!match) throw new Error('[vxrn] Podfile lost its post_install anchor')
|
|
45
|
+
const patch = `
|
|
46
|
+
${WEBGPU_HEADERS_MARKER}
|
|
47
|
+
installer.pods_project.targets.each do |target|
|
|
48
|
+
next unless target.name == 'react-native-webgpu'
|
|
49
|
+
|
|
50
|
+
target.build_configurations.each do |build_config|
|
|
51
|
+
paths = Array(build_config.build_settings['HEADER_SEARCH_PATHS'] || '$(inherited)')
|
|
52
|
+
paths |= %w[cpp/rnwgpu cpp/rnwgpu/api cpp/rnwgpu/api/descriptors cpp/jsi].map do |directory|
|
|
53
|
+
"$(PODS_TARGET_SRCROOT)/#{directory}"
|
|
54
|
+
end
|
|
55
|
+
build_config.build_settings['HEADER_SEARCH_PATHS'] = paths
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
`
|
|
59
|
+
const insertAt = match.index + match[0].length
|
|
60
|
+
return podfile.slice(0, insertAt) + '\n' + patch + podfile.slice(insertAt)
|
|
61
|
+
}
|
|
62
|
+
|
|
39
63
|
function injectFmtCxx17FixIntoPodfile(podfile) {
|
|
40
64
|
if (podfile.includes(FMT_CXX17_MARKER)) {
|
|
41
65
|
return podfile
|
|
@@ -171,8 +195,14 @@ function replaceAppBuildGradleReactBlock(appBuildGradleContents) {
|
|
|
171
195
|
return appBuildGradleContents
|
|
172
196
|
}
|
|
173
197
|
|
|
198
|
+
// replace our resolver declarations together with the react block on re-prebuild.
|
|
199
|
+
const prefix = appBuildGradleContentLines
|
|
200
|
+
.slice(0, reactBlockStartIndex)
|
|
201
|
+
.join('\n')
|
|
202
|
+
.replaceAll(ANDROID_APP_BUILD_GRADLE_RESOLVERS, '')
|
|
203
|
+
.trimEnd()
|
|
174
204
|
return [
|
|
175
|
-
|
|
205
|
+
prefix,
|
|
176
206
|
ANDROID_APP_BUILD_GRADLE_REACT_BLOCK,
|
|
177
207
|
...appBuildGradleContentLines.slice(reactBlockEndIndex + 1),
|
|
178
208
|
].join('\n')
|
|
@@ -180,8 +210,7 @@ function replaceAppBuildGradleReactBlock(appBuildGradleContents) {
|
|
|
180
210
|
|
|
181
211
|
// TODO: Get the content of this block from @react-native-community/template (for example, get https://registry.npmjs.org/@react-native-community/template/0.76.6, find the tarball, download it into a tmp dir, extract it, read template/android/app/build.gradle, parse out the react block) to ensure it stays up to date.
|
|
182
212
|
// Note that we need to add patches marked with [vxrn/one], not just copy the block from the template as is.
|
|
183
|
-
const
|
|
184
|
-
def resolveNodePackage = { packageName ->
|
|
213
|
+
const ANDROID_APP_BUILD_GRADLE_RESOLVERS = `def resolveNodePackage = { packageName ->
|
|
185
214
|
providers.exec {
|
|
186
215
|
workingDir(rootDir)
|
|
187
216
|
commandLine("node", "--print", "require.resolve('" + packageName + "')")
|
|
@@ -193,7 +222,10 @@ def resolveReactNativeDependency = { packageName ->
|
|
|
193
222
|
workingDir(rootDir)
|
|
194
223
|
commandLine("node", "--print", "require('module').createRequire(require.resolve('react-native/package.json')).resolve('" + packageName + "')")
|
|
195
224
|
}.standardOutput.asText.get().trim()
|
|
196
|
-
}
|
|
225
|
+
}`
|
|
226
|
+
|
|
227
|
+
const ANDROID_APP_BUILD_GRADLE_REACT_BLOCK = `
|
|
228
|
+
${ANDROID_APP_BUILD_GRADLE_RESOLVERS}
|
|
197
229
|
|
|
198
230
|
react {
|
|
199
231
|
// [vxrn/one] the bundle command should find the entry file automatically,
|
|
@@ -211,9 +243,11 @@ react {
|
|
|
211
243
|
// the application has its own node_modules directory.
|
|
212
244
|
reactNativeDir = file(resolveNodePackage("react-native/package.json")).parentFile
|
|
213
245
|
codegenDir = file(resolveReactNativeDependency("@react-native/codegen/package.json")).parentFile
|
|
214
|
-
// [vxrn/one] cli
|
|
215
|
-
|
|
216
|
-
|
|
246
|
+
// [vxrn/one] vxrn owns the cli even when the app has no hoisted cli package
|
|
247
|
+
cliFile = file(providers.exec {
|
|
248
|
+
workingDir(rootDir)
|
|
249
|
+
commandLine("node", "--print", "require('module').createRequire(require.resolve('vxrn/package.json')).resolve('@react-native-community/cli/build/bin.js')")
|
|
250
|
+
}.standardOutput.asText.get().trim())
|
|
217
251
|
// [vxrn/one] resolve hermesc from the same react-native installation
|
|
218
252
|
hermesCommand = new File(file(resolveReactNativeDependency("hermes-compiler/package.json")).parentFile, "hermesc/%OS-BIN%/hermesc").absolutePath
|
|
219
253
|
|
|
@@ -292,6 +326,55 @@ function insertBeforeBundlePhaseRunner(input, codeToAdd) {
|
|
|
292
326
|
return input
|
|
293
327
|
}
|
|
294
328
|
|
|
329
|
+
function insertAfterBundlePhaseRunner(input, codeToAdd) {
|
|
330
|
+
for (const anchor of BUNDLE_PHASE_RUNNER_ANCHORS) {
|
|
331
|
+
const match = anchor.exec(input)
|
|
332
|
+
if (!match) continue
|
|
333
|
+
const lineEnd = input.indexOf('\n', match.index + match[0].length)
|
|
334
|
+
const insertAt = lineEnd === -1 ? input.length : lineEnd + 1
|
|
335
|
+
return input.slice(0, insertAt) + codeToAdd + '\n' + input.slice(insertAt)
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
if (!warnedMissingBundlePhaseRunnerAnchor) {
|
|
339
|
+
warnedMissingBundlePhaseRunnerAnchor = true
|
|
340
|
+
console.warn(
|
|
341
|
+
'[vxrn] could not find the `"$NODE_BINARY" .../scripts/react-native-xcode.sh` line in the iOS bundle phase; the One.Updates embedded manifest was not applied. The React Native template may have changed shape.'
|
|
342
|
+
)
|
|
343
|
+
}
|
|
344
|
+
return input
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
/**
|
|
348
|
+
* Write the One.Updates embedded manifest beside the release bundle after
|
|
349
|
+
* React Native's bundling runs. The id and timestamp are generated at build
|
|
350
|
+
* time; the runtime version is baked in by prebuild.
|
|
351
|
+
*/
|
|
352
|
+
const EMBEDDED_UPDATES_MANIFEST_MARKER =
|
|
353
|
+
'# [vxrn/one] the embedded update manifest lands beside the release bundle'
|
|
354
|
+
|
|
355
|
+
function addEmbeddedUpdatesManifestToBundleReactNativeShellScript(input, runtimeVersion) {
|
|
356
|
+
if (input.includes(EMBEDDED_UPDATES_MANIFEST_MARKER)) {
|
|
357
|
+
return input
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
const runtime = String(runtimeVersion).replace(/\\/g, '\\\\').replace(/"/g, '\\"')
|
|
361
|
+
const codeToAdd = [
|
|
362
|
+
'',
|
|
363
|
+
EMBEDDED_UPDATES_MANIFEST_MARKER,
|
|
364
|
+
'ONE_UPDATES_RESOURCES="$CONFIGURATION_BUILD_DIR/$UNLOCALIZED_RESOURCES_FOLDER_PATH"',
|
|
365
|
+
'if [ -f "$ONE_UPDATES_RESOURCES/main.jsbundle" ]; then',
|
|
366
|
+
` "\${NODE_BINARY:-node}" -e 'const fs = require("fs"); const manifest = { id: require("crypto").randomUUID(), createdAt: new Date().toISOString(), runtimeVersion: "${runtime}" }; fs.writeFileSync(process.argv[1], JSON.stringify(manifest));' "$ONE_UPDATES_RESOURCES/one-updates-embedded.json"`,
|
|
367
|
+
// react-native-xcode.sh exits 0 when hermesc fails, so a release build
|
|
368
|
+
// would otherwise ship with no bundle and nothing for the launcher to run.
|
|
369
|
+
'elif [[ "$CONFIGURATION" != *Debug* && -z "$SKIP_BUNDLING" ]]; then',
|
|
370
|
+
' echo "error: [one] release build has no main.jsbundle: the bundle phase failed" >&2',
|
|
371
|
+
' exit 1',
|
|
372
|
+
'fi',
|
|
373
|
+
].join('\n')
|
|
374
|
+
|
|
375
|
+
return insertAfterBundlePhaseRunner(input, codeToAdd)
|
|
376
|
+
}
|
|
377
|
+
|
|
295
378
|
/**
|
|
296
379
|
* React Native v0.76 defaults the CLI_PATH to an internal scripts/bundle.js for iOS (see: https://github.com/facebook/react-native/blob/v0.76.0/packages/react-native/scripts/react-native-xcode.sh#L93), which loads the bundle command directly from `@react-native/community-cli-plugin`, and will ignore the override of the bundle command in `react-native.config.cjs`.
|
|
297
380
|
* We need to set it back to the main CLI endpoint so the override of the bundle command in `react-native.config.cjs` can take effect.
|
|
@@ -305,7 +388,7 @@ function addSetCliPathToBundleReactNativeShellScript(input) {
|
|
|
305
388
|
|
|
306
389
|
const codeToAdd = `
|
|
307
390
|
${SET_CLI_PATH_MARKER}
|
|
308
|
-
export CLI_PATH="$("\${NODE_BINARY:-node}" --print "require('
|
|
391
|
+
export CLI_PATH="$("\${NODE_BINARY:-node}" --print "require('module').createRequire(require.resolve('vxrn/package.json')).resolve('@react-native-community/cli/build/bin.js')")"
|
|
309
392
|
`.trim()
|
|
310
393
|
|
|
311
394
|
return insertBeforeBundlePhaseRunner(input, codeToAdd)
|
|
@@ -572,13 +655,121 @@ function injectOneSwiftPackagesIntoPodfile(podfile) {
|
|
|
572
655
|
return podfile.slice(0, insertAt) + '\n' + lines.join('\n') + podfile.slice(insertAt)
|
|
573
656
|
}
|
|
574
657
|
|
|
658
|
+
// one notifications host entries, written by both one prebuild and
|
|
659
|
+
// vxrn/expo-plugin. the ios keys and android class names are read by one's
|
|
660
|
+
// native code, so they change together with it.
|
|
661
|
+
const ONE_NOTIFICATIONS = {
|
|
662
|
+
enabledInfoPlistKey: 'OneNativeNotificationsEnabled',
|
|
663
|
+
pushInfoPlistKey: 'OneNativeNotificationsPush',
|
|
664
|
+
apsEnvironment: 'development',
|
|
665
|
+
androidPermissions: [
|
|
666
|
+
'android.permission.POST_NOTIFICATIONS',
|
|
667
|
+
'android.permission.RECEIVE_BOOT_COMPLETED',
|
|
668
|
+
],
|
|
669
|
+
receiver: 'dev.onejs.onenative.OneNativeNotificationsReceiver',
|
|
670
|
+
receiverAction: 'android.intent.action.BOOT_COMPLETED',
|
|
671
|
+
pushService: 'dev.onejs.onenative.OneNativePushService',
|
|
672
|
+
pushServiceAction: 'com.google.firebase.MESSAGING_EVENT',
|
|
673
|
+
pushGradleProperty: 'oneNativePush',
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
// One.Updates: the Info.plist keys the launcher reads, and the release
|
|
677
|
+
// bundleURL both prebuilds point at it. the app target reaches the launcher's
|
|
678
|
+
// c entry point through its bridging header: it cannot import One, whose c++
|
|
679
|
+
// umbrella does not rebuild under the app's flags.
|
|
680
|
+
const ONE_UPDATES = {
|
|
681
|
+
urlInfoPlistKey: 'OneUpdatesURL',
|
|
682
|
+
runtimeVersionInfoPlistKey: 'OneUpdatesRuntimeVersion',
|
|
683
|
+
bridgingHeaderImport: '#import "OneUpdatesLauncherBridge.h"',
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
const RELEASE_BUNDLE_URL =
|
|
687
|
+
/(#else\n\s*)(return )?Bundle\.main\.url\(forResource: "main", withExtension: "jsbundle"\)(\n#endif)/
|
|
688
|
+
|
|
689
|
+
function pointReleaseBundleURLAtOneUpdates(appDelegate) {
|
|
690
|
+
if (appDelegate.includes('OneUpdatesBundleURL()')) {
|
|
691
|
+
return appDelegate
|
|
692
|
+
}
|
|
693
|
+
if (!RELEASE_BUNDLE_URL.test(appDelegate)) {
|
|
694
|
+
throw new Error(
|
|
695
|
+
'[vxrn] AppDelegate.swift changed shape: cannot point the release bundleURL at One.Updates'
|
|
696
|
+
)
|
|
697
|
+
}
|
|
698
|
+
return appDelegate.replace(RELEASE_BUNDLE_URL, '$1$2OneUpdatesBundleURL()$3')
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
// the launch screen hold: the app's react native delegate keeps the launch
|
|
702
|
+
// storyboard over the root view until react native's first content, through
|
|
703
|
+
// the OneHoldLaunchScreen c entry point in the bridging header.
|
|
704
|
+
const ONE_LAUNCH_SCREEN = {
|
|
705
|
+
bridgingHeaderImport: '#import "OneLaunchScreen.h"',
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
const REACT_NATIVE_DELEGATE_CLASS =
|
|
709
|
+
/^class ReactNativeDelegate: (ExpoReactNativeFactoryDelegate|RCTDefaultReactNativeFactoryDelegate) \{\n/m
|
|
710
|
+
|
|
711
|
+
function holdLaunchScreenOverRootView(appDelegate) {
|
|
712
|
+
if (appDelegate.includes('OneHoldLaunchScreen(')) {
|
|
713
|
+
return appDelegate
|
|
714
|
+
}
|
|
715
|
+
const match = appDelegate.match(REACT_NATIVE_DELEGATE_CLASS)
|
|
716
|
+
if (!match) {
|
|
717
|
+
throw new Error(
|
|
718
|
+
'[vxrn] AppDelegate.swift changed shape: cannot hold the launch screen over the react native root'
|
|
719
|
+
)
|
|
720
|
+
}
|
|
721
|
+
// expo's delegate re-declares the hook over UIView; react native's takes
|
|
722
|
+
// its RCTRootView.
|
|
723
|
+
const rootViewType = match[1] === 'ExpoReactNativeFactoryDelegate' ? 'UIView' : 'RCTRootView'
|
|
724
|
+
return appDelegate.replace(
|
|
725
|
+
match[0],
|
|
726
|
+
`${match[0]} // [vxrn/one] the launch screen stays over the root until react native's first content
|
|
727
|
+
override func customize(_ rootView: ${rootViewType}) {
|
|
728
|
+
super.customize(rootView)
|
|
729
|
+
OneHoldLaunchScreen(rootView)
|
|
730
|
+
}
|
|
731
|
+
|
|
732
|
+
`
|
|
733
|
+
)
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
// the android half of the launch screen hold: MainActivity hands its content
|
|
737
|
+
// to OneLaunchScreen right after super.onCreate, which every prebuilt
|
|
738
|
+
// activity has once addReactNativeScreensFix ran.
|
|
739
|
+
const SUPER_ON_CREATE = /^([ \t]*)super\.onCreate\(null\)$/m
|
|
740
|
+
|
|
741
|
+
function holdLaunchScreenInMainActivity(mainActivity) {
|
|
742
|
+
if (mainActivity.includes('OneLaunchScreen.hold(this)')) {
|
|
743
|
+
return mainActivity
|
|
744
|
+
}
|
|
745
|
+
if (!SUPER_ON_CREATE.test(mainActivity)) {
|
|
746
|
+
throw new Error(
|
|
747
|
+
'[vxrn] MainActivity.kt changed shape: cannot hold the launch screen after super.onCreate'
|
|
748
|
+
)
|
|
749
|
+
}
|
|
750
|
+
return mainActivity
|
|
751
|
+
.replace(/package\s+[\w.]+/, '$&\nimport com.margelo.nitro.one.OneLaunchScreen')
|
|
752
|
+
.replace(
|
|
753
|
+
SUPER_ON_CREATE,
|
|
754
|
+
"$1super.onCreate(null)\n$1// [vxrn/one] the launch screen stays until react native's first content\n$1OneLaunchScreen.hold(this)"
|
|
755
|
+
)
|
|
756
|
+
}
|
|
757
|
+
|
|
575
758
|
module.exports = {
|
|
759
|
+
injectWebGPUHeaderPathsIntoPodfile,
|
|
760
|
+
holdLaunchScreenInMainActivity,
|
|
761
|
+
ONE_NOTIFICATIONS,
|
|
762
|
+
ONE_UPDATES,
|
|
763
|
+
pointReleaseBundleURLAtOneUpdates,
|
|
764
|
+
ONE_LAUNCH_SCREEN,
|
|
765
|
+
holdLaunchScreenOverRootView,
|
|
576
766
|
hasNitroWebImage,
|
|
577
767
|
injectNitroWebImageModularHeaderIntoPodfile,
|
|
578
768
|
injectOneSwiftPackagesIntoPodfile,
|
|
579
769
|
addSetCliPathToBundleReactNativeShellScript,
|
|
580
770
|
addPodHermescToBundleReactNativeShellScript,
|
|
581
771
|
addDepsPatchToBundleReactNativeShellScript,
|
|
772
|
+
addEmbeddedUpdatesManifestToBundleReactNativeShellScript,
|
|
582
773
|
injectFmtCxx17FixIntoPodfile,
|
|
583
774
|
injectHermesMinificationPatchIntoPodfile,
|
|
584
775
|
injectReactNativeScreensGammaIntoPodfile,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vxrn",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.6.0",
|
|
4
4
|
"sideEffects": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -30,6 +30,22 @@
|
|
|
30
30
|
"./vite-plugin": {
|
|
31
31
|
"types": "./types/vxrn-vite-plugin.d.ts",
|
|
32
32
|
"default": "./dist/vxrn-vite-plugin.mjs"
|
|
33
|
+
},
|
|
34
|
+
"./native-source-contract": {
|
|
35
|
+
"types": "./types/native-source-contract.d.ts",
|
|
36
|
+
"default": "./dist/native-source-contract.mjs"
|
|
37
|
+
},
|
|
38
|
+
"./swift-package-id": {
|
|
39
|
+
"types": "./types/swift-package-id.d.ts",
|
|
40
|
+
"default": "./dist/swift-package-id.mjs"
|
|
41
|
+
},
|
|
42
|
+
"./background-computation": {
|
|
43
|
+
"types": "./types/backgroundComputation.d.ts",
|
|
44
|
+
"default": "./dist/backgroundComputation.mjs"
|
|
45
|
+
},
|
|
46
|
+
"./background-computation-native": {
|
|
47
|
+
"types": "./types/backgroundComputationNative.d.ts",
|
|
48
|
+
"default": "./dist/backgroundComputationNative.mjs"
|
|
33
49
|
}
|
|
34
50
|
},
|
|
35
51
|
"module": "dist",
|
|
@@ -62,18 +78,18 @@
|
|
|
62
78
|
"@jridgewell/remapping": "^2.3.0",
|
|
63
79
|
"@jridgewell/trace-mapping": "^0.3.25",
|
|
64
80
|
"@react-native/codegen": "^0.87.1",
|
|
81
|
+
"@react-native-community/cli": "^20.2.0",
|
|
65
82
|
"@react-native-community/cli-config": "^20.2.0",
|
|
66
83
|
"@react-native/dev-middleware": "^0.87.1",
|
|
67
|
-
"@vxrn/compiler": "2.
|
|
68
|
-
"@vxrn/debug": "2.
|
|
69
|
-
"@vxrn/query-string": "2.
|
|
70
|
-
"@vxrn/resolve": "2.
|
|
71
|
-
"@vxrn/
|
|
72
|
-
"@vxrn/
|
|
73
|
-
"@vxrn/
|
|
74
|
-
"@vxrn/
|
|
75
|
-
"@vxrn/vite-
|
|
76
|
-
"@vxrn/vite-plugin-metro": "2.0.0-beta.98.1",
|
|
84
|
+
"@vxrn/compiler": "2.6.0",
|
|
85
|
+
"@vxrn/debug": "2.6.0",
|
|
86
|
+
"@vxrn/query-string": "2.6.0",
|
|
87
|
+
"@vxrn/resolve": "2.6.0",
|
|
88
|
+
"@vxrn/url-parse": "2.6.0",
|
|
89
|
+
"@vxrn/utils": "2.6.0",
|
|
90
|
+
"@vxrn/vendor": "2.6.0",
|
|
91
|
+
"@vxrn/vite-flow": "2.6.0",
|
|
92
|
+
"@vxrn/vite-plugin-metro": "2.6.0",
|
|
77
93
|
"citty": "^0.1.6",
|
|
78
94
|
"dotenv": "^17.2.1",
|
|
79
95
|
"dotenv-expand": "^12.0.2",
|
|
@@ -95,26 +111,29 @@
|
|
|
95
111
|
"pkg-types": "^1.0.3",
|
|
96
112
|
"rolldown": "^1.2.8",
|
|
97
113
|
"semver": "^7.6.3",
|
|
98
|
-
"sharp": "^0.35.
|
|
114
|
+
"sharp": "^0.35.5",
|
|
99
115
|
"vite": "^8.2.2",
|
|
100
|
-
"ws": "^8.21.0"
|
|
116
|
+
"ws": "^8.21.0",
|
|
117
|
+
"sucrase": "3.35.1"
|
|
101
118
|
},
|
|
102
119
|
"devDependencies": {
|
|
103
120
|
"@biomejs/biome": "2.3.3",
|
|
104
121
|
"@jridgewell/gen-mapping": "^0.3.5",
|
|
105
|
-
"@
|
|
106
|
-
"@tamagui/build": "3.0.0-beta.1432.1",
|
|
122
|
+
"@tamagui/build": "3.0.3",
|
|
107
123
|
"@types/find-node-modules": "^2.1.2",
|
|
108
124
|
"@types/node": "^24.10.0",
|
|
109
125
|
"@types/ws": "^8.18.1",
|
|
110
126
|
"depcheck": "^1.4.7",
|
|
127
|
+
"hermes-compiler": "250829098.0.17",
|
|
111
128
|
"metro-source-map": "0.84.4",
|
|
112
129
|
"react-native": "0.87.1",
|
|
130
|
+
"typescript": "7.0.2",
|
|
113
131
|
"vitest": "^4.1.0"
|
|
114
132
|
},
|
|
115
133
|
"publishConfig": {
|
|
116
134
|
"access": "public"
|
|
117
135
|
},
|
|
136
|
+
"releaseSourceCommit": "9822993504bd9422425d1d6ee9bfbe96f84c909c",
|
|
118
137
|
"repository": {
|
|
119
138
|
"type": "git",
|
|
120
139
|
"url": "git+https://github.com/onejs/one.git",
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
import MagicString from 'magic-string'
|
|
2
|
+
import { parse } from 'sucrase/dist/parser/index.js'
|
|
3
|
+
import { IdentifierRole } from 'sucrase/dist/parser/tokenizer/index.js'
|
|
4
|
+
import { TokenType } from 'sucrase/dist/parser/tokenizer/types.js'
|
|
5
|
+
|
|
6
|
+
export type BackgroundModule = {
|
|
7
|
+
id: string
|
|
8
|
+
source: string
|
|
9
|
+
calculate: string
|
|
10
|
+
name: string
|
|
11
|
+
platform: 'web' | 'native'
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export type BackgroundTransformOptions = {
|
|
15
|
+
platform: 'web' | 'native'
|
|
16
|
+
resolve: (source: string, importer: string) => string
|
|
17
|
+
nativeModule?: (module: BackgroundModule) => string
|
|
18
|
+
workerFactory?: (module: BackgroundModule) => string
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const marker = '.__one_background_worker_'
|
|
22
|
+
const hex = (name: string) =>
|
|
23
|
+
[...new TextEncoder().encode(name)]
|
|
24
|
+
.map((byte) => byte.toString(16).padStart(2, '0'))
|
|
25
|
+
.join('')
|
|
26
|
+
|
|
27
|
+
// file-shaped worker entries survive Vite's query stripping and package graphs.
|
|
28
|
+
export function loadBackgroundComputationModule(
|
|
29
|
+
id: string
|
|
30
|
+
): BackgroundModule | undefined {
|
|
31
|
+
const match = id.match(/^(.*?)\.__one_background_worker_([a-f0-9]+)\.js(?:\?.*)?$/)
|
|
32
|
+
if (!match) return
|
|
33
|
+
const [, calculate, encoded] = match
|
|
34
|
+
const name = new TextDecoder().decode(
|
|
35
|
+
Uint8Array.from(encoded.match(/../g)!, (byte) => Number.parseInt(byte, 16))
|
|
36
|
+
)
|
|
37
|
+
return {
|
|
38
|
+
id,
|
|
39
|
+
calculate,
|
|
40
|
+
name,
|
|
41
|
+
platform: 'web',
|
|
42
|
+
source: `import { ${name} as calculate } from ${JSON.stringify(calculate)};
|
|
43
|
+
self.onmessage = ({ data: { revision, input } }) => {
|
|
44
|
+
try {
|
|
45
|
+
const value = calculate(input);
|
|
46
|
+
if (value instanceof Promise) throw new TypeError('background computations must be synchronous');
|
|
47
|
+
self.postMessage({ ok: true, result: { revision, value } });
|
|
48
|
+
} catch (error) {
|
|
49
|
+
self.postMessage({ ok: false, revision, error: String(error) });
|
|
50
|
+
}
|
|
51
|
+
};`,
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// hosts supply path resolution and worker transport; selection and protocol stay here.
|
|
56
|
+
export function transformBackgroundComputations(
|
|
57
|
+
source: string,
|
|
58
|
+
id: string,
|
|
59
|
+
options: BackgroundTransformOptions
|
|
60
|
+
) {
|
|
61
|
+
if (!source.includes('defineBackgroundComputation') || id.includes(marker)) return
|
|
62
|
+
const file = parse(
|
|
63
|
+
source,
|
|
64
|
+
!/\.[cm]?ts(?:\?|$)/.test(id),
|
|
65
|
+
/\.[cm]?tsx?(?:\?|$)/.test(id),
|
|
66
|
+
false
|
|
67
|
+
)
|
|
68
|
+
const { tokens } = file
|
|
69
|
+
const text = (index: number) =>
|
|
70
|
+
tokens[index] ? source.slice(tokens[index].start, tokens[index].end) : ''
|
|
71
|
+
const imports = new Map<string, { source: string; name: string }>()
|
|
72
|
+
const definitions = new Set<string>()
|
|
73
|
+
for (let index = 0; index < tokens.length; index++) {
|
|
74
|
+
if (text(index) !== 'import' || tokens[index].isType || text(index + 1) !== '{')
|
|
75
|
+
continue
|
|
76
|
+
const start = index + 2
|
|
77
|
+
let end = start
|
|
78
|
+
while (end < tokens.length && text(end) !== '}') end++
|
|
79
|
+
if (text(end + 1) !== 'from' || tokens[end + 2]?.type !== TokenType.string) continue
|
|
80
|
+
const specifier = text(end + 2).slice(1, -1)
|
|
81
|
+
for (let binding = start; binding < end; binding++) {
|
|
82
|
+
if (tokens[binding].isType || tokens[binding].type !== TokenType.name) continue
|
|
83
|
+
const name = text(binding)
|
|
84
|
+
const local = text(binding + 1) === 'as' ? text(binding + 2) : name
|
|
85
|
+
imports.set(local, { source: specifier, name })
|
|
86
|
+
if (specifier === 'one/background' && name === 'defineBackgroundComputation')
|
|
87
|
+
definitions.add(local)
|
|
88
|
+
if (local !== name) binding += 2
|
|
89
|
+
}
|
|
90
|
+
index = end + 2
|
|
91
|
+
}
|
|
92
|
+
if (!definitions.size) return
|
|
93
|
+
const code = new MagicString(source)
|
|
94
|
+
const modules: BackgroundModule[] = []
|
|
95
|
+
for (let index = 0; index < tokens.length; index++) {
|
|
96
|
+
const token = tokens[index]
|
|
97
|
+
if (token.identifierRole !== IdentifierRole.Access || !definitions.has(text(index)))
|
|
98
|
+
continue
|
|
99
|
+
let opening = index + 1
|
|
100
|
+
while (tokens[opening]?.isType) opening++
|
|
101
|
+
if (text(opening) !== '(') continue
|
|
102
|
+
let binding = index - 2
|
|
103
|
+
while (tokens[binding]?.isType) binding--
|
|
104
|
+
if (
|
|
105
|
+
token.scopeDepth !== 0 ||
|
|
106
|
+
text(index - 1) !== '=' ||
|
|
107
|
+
tokens[binding]?.identifierRole !== IdentifierRole.TopLevelDeclaration
|
|
108
|
+
)
|
|
109
|
+
throw new Error(
|
|
110
|
+
`[one background] ${id}: definitions must be module-scope variables`
|
|
111
|
+
)
|
|
112
|
+
const argument = tokens[opening + 1]
|
|
113
|
+
const calculate =
|
|
114
|
+
argument?.type === TokenType.name ? imports.get(text(opening + 1)) : undefined
|
|
115
|
+
if (!calculate || !calculate.source.startsWith('.') || text(opening + 2) !== ')')
|
|
116
|
+
throw new Error(
|
|
117
|
+
`[one background] ${id}: defineBackgroundComputation requires one named import from a relative pure module at module scope`
|
|
118
|
+
)
|
|
119
|
+
const resolved = options.resolve(calculate.source, id)
|
|
120
|
+
if (options.platform === 'native') {
|
|
121
|
+
const local = `__oneBackgroundCalculate${modules.length}`
|
|
122
|
+
const module: BackgroundModule = {
|
|
123
|
+
id: `${resolved}.__one_background_native_${hex(calculate.name)}.js`,
|
|
124
|
+
source: `export { ${calculate.name} } from ${JSON.stringify(resolved)};`,
|
|
125
|
+
calculate: resolved,
|
|
126
|
+
name: calculate.name,
|
|
127
|
+
platform: 'native',
|
|
128
|
+
}
|
|
129
|
+
const selected = options.nativeModule
|
|
130
|
+
? options.nativeModule(module)
|
|
131
|
+
: `${calculate.source}?one-background=${encodeURIComponent(calculate.name)}`
|
|
132
|
+
code.prepend(
|
|
133
|
+
`import { ${calculate.name} as ${local} } from ${JSON.stringify(selected)};\n`
|
|
134
|
+
)
|
|
135
|
+
code.overwrite(argument.start, argument.end, local)
|
|
136
|
+
modules.push(module)
|
|
137
|
+
} else {
|
|
138
|
+
const module = loadBackgroundComputationModule(
|
|
139
|
+
`${resolved}${marker}${hex(calculate.name)}.js`
|
|
140
|
+
)!
|
|
141
|
+
const factory = options.workerFactory
|
|
142
|
+
? options.workerFactory(module)
|
|
143
|
+
: `() => new Worker(new URL(${JSON.stringify(module.id)}, import.meta.url), { type: 'module' })`
|
|
144
|
+
code.appendLeft(tokens[opening + 2].start, `, ${factory}`)
|
|
145
|
+
modules.push(module)
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
if (!modules.length) return
|
|
149
|
+
return { code: code.toString(), map: code.generateMap({ hires: true }), modules }
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// selected graphs expose __exportN; both native hosts use this runtime cache wrapper.
|
|
153
|
+
export function createBackgroundWorkletModule(
|
|
154
|
+
bundle: string,
|
|
155
|
+
names: readonly string[],
|
|
156
|
+
key: string
|
|
157
|
+
) {
|
|
158
|
+
const loader = `__oneLoadWorkletModule_${key}`
|
|
159
|
+
return `function ${loader}() {
|
|
160
|
+
'worklet';
|
|
161
|
+
const cache = globalThis.__oneWorkletImportCache || (globalThis.__oneWorkletImportCache = new WeakMap());
|
|
162
|
+
let namespace = cache.get(${loader});
|
|
163
|
+
if (namespace === undefined) {
|
|
164
|
+
${bundle}
|
|
165
|
+
namespace = __oneWorkletBundle;
|
|
166
|
+
cache.set(${loader}, namespace);
|
|
167
|
+
}
|
|
168
|
+
return namespace;
|
|
169
|
+
}\n${names
|
|
170
|
+
.map(
|
|
171
|
+
(name, index) => `function __oneExport${index}(...args) {
|
|
172
|
+
'worklet';
|
|
173
|
+
return (0, ${loader}().__export${index})(...args);
|
|
174
|
+
}
|
|
175
|
+
export { __oneExport${index} as ${name} };`
|
|
176
|
+
)
|
|
177
|
+
.join('\n')}`
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
export function assertBackgroundDependency(source: string) {
|
|
181
|
+
const name = source.replaceAll('\\', '/')
|
|
182
|
+
if (
|
|
183
|
+
name.startsWith('node:') ||
|
|
184
|
+
/(?:^|\/node_modules\/)(?:react|react-native|react-native-worklets|react-native-reanimated|@react-native)(?:\/|$)/.test(
|
|
185
|
+
name
|
|
186
|
+
)
|
|
187
|
+
)
|
|
188
|
+
throw new Error(
|
|
189
|
+
`[one background] runtime dependency ${source} is not pure JavaScript`
|
|
190
|
+
)
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
export type BackgroundGraphModule = {
|
|
194
|
+
id: number
|
|
195
|
+
code: string
|
|
196
|
+
dependencies: readonly (number | null)[]
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
// graph hosts supply compiled CommonJS factories; runtime loading is isolated from the app.
|
|
200
|
+
export function bundleBackgroundGraph(
|
|
201
|
+
modules: readonly BackgroundGraphModule[],
|
|
202
|
+
entry: number,
|
|
203
|
+
names: readonly string[]
|
|
204
|
+
) {
|
|
205
|
+
return `var __oneWorkletBundle = (function () {
|
|
206
|
+
const factories = { ${modules.map((module) => `${module.id}: function(global, _require, _importDefault, _importAll, module, exports, _dependencyMap) {\n${module.code}\n}`).join(',\n')} };
|
|
207
|
+
const dependencies = ${JSON.stringify(Object.fromEntries(modules.map((module) => [module.id, module.dependencies])))};
|
|
208
|
+
const cache = Object.create(null);
|
|
209
|
+
function require(id) {
|
|
210
|
+
if (cache[id]) return cache[id].exports;
|
|
211
|
+
const module = cache[id] = { exports: {} };
|
|
212
|
+
factories[id](globalThis, require, importDefault, importAll, module, module.exports, dependencies[id]);
|
|
213
|
+
return module.exports;
|
|
214
|
+
}
|
|
215
|
+
function importDefault(id) { const value = require(id); return value && value.__esModule ? value.default : value; }
|
|
216
|
+
function importAll(id) { const value = require(id); return value && value.__esModule ? value : Object.assign({ default: value }, value); }
|
|
217
|
+
const namespace = require(${entry});
|
|
218
|
+
return { ${names.map((name, index) => `__export${index}: namespace[${JSON.stringify(name)}]`).join(', ')} };
|
|
219
|
+
})();`
|
|
220
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getClosureVariables,
|
|
3
|
+
JS_GLOBALS,
|
|
4
|
+
transformHermesLoops,
|
|
5
|
+
} from '@vxrn/compiler/worklet-utils'
|
|
6
|
+
import { parseSync } from 'oxc-parser'
|
|
7
|
+
|
|
8
|
+
// native compiler hosts validate the complete loader before worklet serialization.
|
|
9
|
+
export function prepareBackgroundWorkletModule(source: string, id: string) {
|
|
10
|
+
const code = transformHermesLoops(source, id)?.code ?? source
|
|
11
|
+
const parsed = parseSync(id, code, { lang: 'js' })
|
|
12
|
+
if (parsed.errors.length) throw new Error(parsed.errors[0].message)
|
|
13
|
+
const captures = getClosureVariables(
|
|
14
|
+
parsed.program.body[0],
|
|
15
|
+
new Set([...JS_GLOBALS, 'arguments'])
|
|
16
|
+
)
|
|
17
|
+
if (captures.length) {
|
|
18
|
+
throw new Error(
|
|
19
|
+
`[worklet imports] ${id} requires unsupported runtime globals: ${captures.join(', ')}`
|
|
20
|
+
)
|
|
21
|
+
}
|
|
22
|
+
return code
|
|
23
|
+
}
|
|
@@ -8,7 +8,6 @@ import type { VXRNOptionsFilled } from './getOptionsFilled'
|
|
|
8
8
|
|
|
9
9
|
export const dedupe = [
|
|
10
10
|
'one',
|
|
11
|
-
'@vxrn/safe-area',
|
|
12
11
|
'react',
|
|
13
12
|
'react-dom',
|
|
14
13
|
'react-dom/client',
|
|
@@ -21,11 +20,11 @@ export const dedupe = [
|
|
|
21
20
|
'@react-navigation/bottom-tabs',
|
|
22
21
|
'@tamagui/core',
|
|
23
22
|
'@tamagui/web',
|
|
23
|
+
'@tamagui/adapt',
|
|
24
24
|
'@tamagui/react-native-web',
|
|
25
25
|
'@tamagui/react-native-web-lite',
|
|
26
26
|
'tamagui',
|
|
27
27
|
'react-native-reanimated',
|
|
28
|
-
'escape-string-regexp',
|
|
29
28
|
]
|
|
30
29
|
|
|
31
30
|
/**
|
|
@@ -65,6 +64,7 @@ export async function getBaseViteConfig(
|
|
|
65
64
|
|
|
66
65
|
return {
|
|
67
66
|
mode,
|
|
67
|
+
assetsInclude: ['**/*.glb'],
|
|
68
68
|
|
|
69
69
|
// we load the config ourselves
|
|
70
70
|
// if you disable this is disables auto-reloading config changes
|
|
@@ -103,19 +103,18 @@ export async function getBaseViteConfig(
|
|
|
103
103
|
// react native 0.87 removed @react-native/assets-registry, but libraries
|
|
104
104
|
// like react-native-svg still import its registry
|
|
105
105
|
find: /^(react-native\/asset-registry|@react-native\/assets-registry\/registry)$/,
|
|
106
|
-
replacement:
|
|
106
|
+
replacement: 'react-native-web/dist/modules/AssetRegistry',
|
|
107
107
|
},
|
|
108
108
|
{
|
|
109
109
|
find: 'react-native/package.json',
|
|
110
|
-
replacement:
|
|
110
|
+
replacement: 'react-native-web/package.json',
|
|
111
111
|
},
|
|
112
|
+
// named by package so it resolves (from the root, through dedupe) only
|
|
113
|
+
// once something imports react-native: an app with no react-native
|
|
114
|
+
// imports needs no react-native-web.
|
|
112
115
|
{
|
|
113
116
|
find: 'react-native',
|
|
114
|
-
replacement:
|
|
115
|
-
},
|
|
116
|
-
{
|
|
117
|
-
find: 'react-native-safe-area-context',
|
|
118
|
-
replacement: resolvePath('@vxrn/safe-area', root),
|
|
117
|
+
replacement: 'react-native-web',
|
|
119
118
|
},
|
|
120
119
|
// bundle size optimizations
|
|
121
120
|
{
|