rnxsim 0.1.363 → 0.1.365
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/cli/outbound-endpoints.ts +2 -6
- package/dist-cli/bin.js +5 -5
- package/dist-cli/chunks/{agent-EN7USQWO.js → agent-BVMNQFKF.js} +2 -2
- package/dist-cli/chunks/{agent-wrapper-4K2P2EBF.js → agent-wrapper-B6YFXGC3.js} +2 -2
- package/dist-cli/chunks/app-fonts-MEI6R6XR.js +4 -0
- package/dist-cli/chunks/{assert-WEQDRDJ2.js → assert-JGHI53HV.js} +2 -2
- package/dist-cli/chunks/{auth-U5GBY5SE.js → auth-STEOXUS7.js} +2 -2
- package/dist-cli/chunks/{beta-WOKLQLOJ.js → beta-HT3FLS5T.js} +2 -2
- package/dist-cli/chunks/{camera-GRMP2HT3.js → camera-ZCLFSLON.js} +2 -2
- package/dist-cli/chunks/{chunk-TIZP26F4.js → chunk-25BTVHK2.js} +2 -2
- package/dist-cli/chunks/{chunk-YFF6YFYJ.js → chunk-2CXHDTQ5.js} +1 -1
- package/dist-cli/chunks/{chunk-TK4ZQQAL.js → chunk-2JFZ5Z7Q.js} +1 -1
- package/dist-cli/chunks/{chunk-QVUS7OHN.js → chunk-2SFMW5K6.js} +1 -1
- package/dist-cli/chunks/{chunk-6BGR523F.js → chunk-4WFN4DFR.js} +2 -2
- package/dist-cli/chunks/{chunk-4QK74NWP.js → chunk-52ES4API.js} +2 -2
- package/dist-cli/chunks/{chunk-FFWDCXTD.js → chunk-5AS7S6HY.js} +2 -2
- package/dist-cli/chunks/{chunk-SIKPB3GL.js → chunk-5VHWQGGF.js} +1 -1
- package/dist-cli/chunks/{chunk-GLYEL265.js → chunk-622E4JET.js} +1 -1
- package/dist-cli/chunks/{chunk-DK764ET6.js → chunk-67ATAITF.js} +2 -2
- package/dist-cli/chunks/{chunk-2AELGO56.js → chunk-6BAF6GFS.js} +1 -1
- package/dist-cli/chunks/{chunk-ZSFETJZV.js → chunk-BGRGP3QR.js} +1 -1
- package/dist-cli/chunks/{chunk-7CT75XQF.js → chunk-CYIE65QN.js} +1 -1
- package/dist-cli/chunks/{chunk-PDGEVGHU.js → chunk-DBJZUCFP.js} +2 -2
- package/dist-cli/chunks/{chunk-KCHXGTYQ.js → chunk-DQFOHIRF.js} +1 -1
- package/dist-cli/chunks/{chunk-MOC4QX3B.js → chunk-EAFKG5R3.js} +2 -2
- package/dist-cli/chunks/{chunk-DFL5AISK.js → chunk-EFL2ASZO.js} +1 -1
- package/dist-cli/chunks/{chunk-GMW6T2K6.js → chunk-EFXNSJ55.js} +2 -2
- package/dist-cli/chunks/{chunk-NUU3SWLR.js → chunk-EVBQDQVY.js} +1 -1
- package/dist-cli/chunks/{chunk-X2ITJOHZ.js → chunk-FHWZPUGC.js} +1 -1
- package/dist-cli/chunks/{chunk-23MIH7SN.js → chunk-FIXRGPUT.js} +1 -1
- package/dist-cli/chunks/{chunk-EAXYIY5U.js → chunk-GK7PGYFH.js} +1 -1
- package/dist-cli/chunks/{chunk-BPYGMBOL.js → chunk-GZEUDDAW.js} +2 -2
- package/dist-cli/chunks/{chunk-WIV5YAQT.js → chunk-HIDS3PYC.js} +2 -2
- package/dist-cli/chunks/{chunk-WYD5DEEU.js → chunk-IWPS3EKJ.js} +2 -2
- package/dist-cli/chunks/{chunk-5N5BWVZK.js → chunk-J66US2OZ.js} +1 -1
- package/dist-cli/chunks/{chunk-MM2XAXTN.js → chunk-JAFF4RAU.js} +1 -1
- package/dist-cli/chunks/{chunk-GKKO7RE2.js → chunk-JRPU5TFI.js} +3 -3
- package/dist-cli/chunks/{chunk-ZSLOAO3P.js → chunk-M5KJCLUW.js} +3 -3
- package/dist-cli/chunks/{chunk-4ZGUXZ6U.js → chunk-MACI34ST.js} +3 -3
- package/dist-cli/chunks/chunk-MCHKBFUL.js +4 -0
- package/dist-cli/chunks/{chunk-42O6RKCS.js → chunk-MR3YPNUI.js} +2 -2
- package/dist-cli/chunks/{chunk-QXBFDUCQ.js → chunk-MRNW4GVL.js} +2 -2
- package/dist-cli/chunks/{chunk-VXN2HAHP.js → chunk-NEH4T67X.js} +2 -2
- package/dist-cli/chunks/{chunk-ZCHCE6WJ.js → chunk-O2ORLK6W.js} +2 -2
- package/dist-cli/chunks/{chunk-KWFRIVXW.js → chunk-O6P4N2JD.js} +2 -2
- package/dist-cli/chunks/{chunk-BWTDQWRB.js → chunk-OSZ5HZSI.js} +2 -2
- package/dist-cli/chunks/{chunk-HJN6LXR5.js → chunk-QIQL7Y5V.js} +2 -2
- package/dist-cli/chunks/{chunk-LV4BJLQU.js → chunk-R4FQZXJC.js} +2 -2
- package/dist-cli/chunks/{chunk-74RRQIWF.js → chunk-RI3NS77J.js} +1 -1
- package/dist-cli/chunks/{chunk-BAPVTWIM.js → chunk-TKCGP3DD.js} +2 -2
- package/dist-cli/chunks/{chunk-S6CNNXSR.js → chunk-TULWPOAY.js} +2 -2
- package/dist-cli/chunks/{chunk-FADHHMJU.js → chunk-UR345KM3.js} +2 -2
- package/dist-cli/chunks/{chunk-IY2WWLFH.js → chunk-W3UIDI3W.js} +2 -2
- package/dist-cli/chunks/{chunk-FNVWTY57.js → chunk-WGNDJARS.js} +1 -1
- package/dist-cli/chunks/{chunk-XYPCBRGY.js → chunk-X5ZOZVHC.js} +1 -1
- package/dist-cli/chunks/{chunk-HGPDQPIG.js → chunk-XKRUNS7A.js} +2 -2
- package/dist-cli/chunks/{chunk-FAWMDCMJ.js → chunk-XPOTXF5Q.js} +2 -2
- package/dist-cli/chunks/{chunk-WPXQ7CNQ.js → chunk-XR4KID25.js} +2 -2
- package/dist-cli/chunks/{chunk-AGUR7LE7.js → chunk-XRO5WQXP.js} +1 -1
- package/dist-cli/chunks/{chunk-YSLE3K2S.js → chunk-XXNPISER.js} +2 -2
- package/dist-cli/chunks/{chunk-PH4W36KI.js → chunk-YE3M3YD4.js} +3 -3
- package/dist-cli/chunks/{chunk-46BMZYP7.js → chunk-ZCP4CRP6.js} +2 -2
- package/dist-cli/chunks/{chunk-KJ5SZIXX.js → chunk-ZGD7GZRI.js} +2 -2
- package/dist-cli/chunks/{chunk-2IVWNQDE.js → chunk-ZGH5U4AJ.js} +2 -2
- package/dist-cli/chunks/{chunk-4CMRJ7UX.js → chunk-ZTWUNK45.js} +2 -2
- package/dist-cli/chunks/{cleanup-ZVQLJLTY.js → cleanup-G4TEYVKY.js} +2 -2
- package/dist-cli/chunks/cli-version-ZM3PVKQ5.js +4 -0
- package/dist-cli/chunks/{compat-7T2VZZDL.js → compat-EZ5NP32J.js} +2 -2
- package/dist-cli/chunks/{config-E7OULENQ.js → config-27M2DGCS.js} +2 -2
- package/dist-cli/chunks/{control-X5O5UXPP.js → control-4QR43FXV.js} +2 -2
- package/dist-cli/chunks/daemon-2U4CJ6AT.js +4 -0
- package/dist-cli/chunks/{debug-LK6GRYHR.js → debug-EXU3D7PC.js} +3 -3
- package/dist-cli/chunks/{desktop-2LAHHUP6.js → desktop-SHHPZAWQ.js} +3 -3
- package/dist-cli/chunks/{detox-7GF6V6E6.js → detox-RQ6FFSBS.js} +2 -2
- package/dist-cli/chunks/{device-G3IF4IRA.js → device-4NI26HG6.js} +2 -2
- package/dist-cli/chunks/{diagnose-6G2RJWVP.js → diagnose-P4SFXH6J.js} +2 -2
- package/dist-cli/chunks/{disk-cleanup-PRAJROKV.js → disk-cleanup-BUAKWYMY.js} +2 -2
- package/dist-cli/chunks/drivers-OVCUPQTM.js +4 -0
- package/dist-cli/chunks/{film-CGVAWXPR.js → film-Y2BAQINB.js} +3 -3
- package/dist-cli/chunks/flow-ELTLKKZ3.js +4 -0
- package/dist-cli/chunks/help-CDEZAG2L.js +4 -0
- package/dist-cli/chunks/{hidden-runtime-alias-FCDWZQM3.js → hidden-runtime-alias-U2MAY2XV.js} +2 -2
- package/dist-cli/chunks/{home-paths-JEUBFYPY.js → home-paths-PAJMZCOS.js} +2 -2
- package/dist-cli/chunks/inspect-VVQRPJLS.js +4 -0
- package/dist-cli/chunks/install-desktop-YXSRKR35.js +4 -0
- package/dist-cli/chunks/{login-HBPZL3QX.js → login-D53XKBEO.js} +2 -2
- package/dist-cli/chunks/{logout-SVBZGGEI.js → logout-HZQKLNUJ.js} +2 -2
- package/dist-cli/chunks/{maestro-445CMWSH.js → maestro-XSS2KX6L.js} +3 -3
- package/dist-cli/chunks/{maestro-generate-4JWKONR2.js → maestro-generate-DNDQX3JQ.js} +3 -3
- package/dist-cli/chunks/{mode-M6GVNTDZ.js → mode-LEVGOKI3.js} +2 -2
- package/dist-cli/chunks/{optional-demo-registry-Q5CATNHD.js → optional-demo-registry-2XZIJNDG.js} +2 -2
- package/dist-cli/chunks/{perf-MBNYDE6X.js → perf-OKMAXDLB.js} +2 -2
- package/dist-cli/chunks/{permissions-HNLQIZJD.js → permissions-VG5TBUTN.js} +2 -2
- package/dist-cli/chunks/privacy-MNRHREME.js +4 -0
- package/dist-cli/chunks/{record-MH3BLHON.js → record-BQYGZOMV.js} +3 -3
- package/dist-cli/chunks/{report-issue-6HQHCFBG.js → report-issue-HCPZESWE.js} +2 -2
- package/dist-cli/chunks/reset-R4E4W4YI.js +4 -0
- package/dist-cli/chunks/runtime-XRQZ7W34.js +4 -0
- package/dist-cli/chunks/{screenshot-command-D6VS6GDA.js → screenshot-command-DWEYPJE7.js} +3 -3
- package/dist-cli/chunks/{screenshot-layers-MC7JHOO2.js → screenshot-layers-5GMBXLO7.js} +2 -2
- package/dist-cli/chunks/{screenshots-capture-PUQTDG5I.js → screenshots-capture-5KCI7IZD.js} +2 -2
- package/dist-cli/chunks/serve-QNKTA2HR.js +56 -0
- package/dist-cli/chunks/setup-RNMM5GO5.js +4 -0
- package/dist-cli/chunks/{skills-IJDXM6IC.js → skills-DOEALD3X.js} +2 -2
- package/dist-cli/chunks/{state-KCBXBFZZ.js → state-3HH2IHIF.js} +2 -2
- package/dist-cli/chunks/{storage-RBYDWRJC.js → storage-E7WUWN3E.js} +2 -2
- package/dist-cli/chunks/store-HUPZUCFG.js +4 -0
- package/dist-cli/chunks/telemetry-IJ53XR2Y.js +4 -0
- package/dist-cli/chunks/{timeline-RPEEEB3A.js → timeline-IKNUGQ2A.js} +2 -2
- package/dist-cli/chunks/{upgrade-TFLWCW3P.js → upgrade-VS3OKXE2.js} +2 -2
- package/dist-cli/chunks/upload-A57NAAHF.js +4 -0
- package/dist-cli/chunks/{version-LHPE2VT4.js → version-F4XHNTBZ.js} +2 -2
- package/dist-cli/chunks/{web-QJ74GCNZ.js → web-F72724QL.js} +2 -2
- package/dist-cli/chunks/welcome-B72RRMBW.js +5 -0
- package/dist-cli/chunks/{what-happened-JXBBC5U7.js → what-happened-APK7YKOV.js} +2 -2
- package/dist-lib/agent-daemon-client.cjs +1 -1
- package/dist-lib/agent-events.cjs +1 -1
- package/dist-lib/agent-identity.cjs +1 -1
- package/dist-lib/agent-sessions.cjs +1 -1
- package/dist-lib/attached-projects.cjs +1 -1
- package/dist-lib/auth/shared-session.cjs +1 -1
- package/dist-lib/backend-origin.cjs +1 -1
- package/dist-lib/beta.cjs +1 -1
- package/dist-lib/beta.mjs +1 -1
- package/dist-lib/bridge-constants.cjs +1 -1
- package/dist-lib/bridge-contract.cjs +1 -1
- package/dist-lib/cli-constants.cjs +1 -1
- package/dist-lib/config.cjs +1 -1
- package/dist-lib/detox/index.cjs +1 -1
- package/dist-lib/dev-bundle-resolution.cjs +1 -1
- package/dist-lib/home-paths.cjs +1 -1
- package/dist-lib/host/bridge-host.cjs +89 -154
- package/dist-lib/host/fetch-proxy-handler.cjs +36 -3
- package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
- package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
- package/dist-lib/host/replacement-module-handler.cjs +60 -107
- package/dist-lib/host/websocket-proxy.cjs +1 -1
- package/dist-lib/index.cjs +60 -105
- package/dist-lib/jump-to-source-babel.cjs +1 -1
- package/dist-lib/menu.cjs +1 -1
- package/dist-lib/menu.mjs +1 -1
- package/dist-lib/metro-production-bundle.cjs +1 -1
- package/dist-lib/metro-production-bundle.mjs +1 -1
- package/dist-lib/metro.cjs +60 -105
- package/dist-lib/profiles.cjs +1 -1
- package/dist-lib/public-brand.cjs +1 -1
- package/dist-lib/react-native-host-modules.cjs +1 -1
- package/dist-lib/react-native-host-modules.mjs +1 -1
- package/dist-lib/render-mode.cjs +1 -1
- package/dist-lib/scripts/dev-server-scanner.cjs +1 -1
- package/dist-lib/sdk.cjs +1 -1
- package/dist-lib/sdk.mjs +1 -1
- package/dist-lib/skills.cjs +126 -189
- package/dist-lib/vite.cjs +59 -104
- package/package.json +1 -1
- package/src/host/bridge-host.ts +2 -50
- package/src/host/fetch-proxy-handler.ts +40 -3
- package/src/host/replacement-module-handler.ts +65 -117
- package/dist-cli/chunks/app-fonts-7B5E7UDM.js +0 -4
- package/dist-cli/chunks/chunk-FQGTATLA.js +0 -4
- package/dist-cli/chunks/cli-version-KAVMACHT.js +0 -4
- package/dist-cli/chunks/daemon-GEDFARBC.js +0 -4
- package/dist-cli/chunks/drivers-4WSF4T4I.js +0 -4
- package/dist-cli/chunks/flow-MEDCS46T.js +0 -4
- package/dist-cli/chunks/help-KOAHGOH4.js +0 -4
- package/dist-cli/chunks/inspect-IU5HFVKF.js +0 -4
- package/dist-cli/chunks/install-desktop-5Q2WB4QO.js +0 -4
- package/dist-cli/chunks/privacy-UL6QT67W.js +0 -4
- package/dist-cli/chunks/reset-GHLOGMF3.js +0 -4
- package/dist-cli/chunks/runtime-JK43NPS6.js +0 -4
- package/dist-cli/chunks/serve-4UDVILST.js +0 -118
- package/dist-cli/chunks/setup-5IHFDPBA.js +0 -4
- package/dist-cli/chunks/store-O2PYGAXL.js +0 -4
- package/dist-cli/chunks/telemetry-B2CPDQID.js +0 -4
- package/dist-cli/chunks/upload-2GJWZG6R.js +0 -4
- package/dist-cli/chunks/welcome-5XJPBRJD.js +0 -5
package/dist-lib/vite.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! rnx v0.1.
|
|
1
|
+
/*! rnx v0.1.365 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
2
|
let __sootsim_import_meta_url = ''; try { __sootsim_import_meta_url = require('url').pathToFileURL(__filename).href; } catch {}
|
|
3
3
|
"use strict";
|
|
4
4
|
var __create = Object.create;
|
|
@@ -202,7 +202,6 @@ function isLoopbackHost(hostname) {
|
|
|
202
202
|
|
|
203
203
|
// src/host/replacement-module-handler.ts
|
|
204
204
|
var REPLACEMENT_MODULE_ROUTE = "/__sootsim-replacement-module";
|
|
205
|
-
var REPLACEMENT_RUNTIME_PREFIX = "/__sootsim-replacement-runtime";
|
|
206
205
|
function getReplacementLoader(filePath) {
|
|
207
206
|
const ext = import_node_path3.default.extname(filePath).toLowerCase();
|
|
208
207
|
switch (ext) {
|
|
@@ -218,88 +217,6 @@ function getReplacementLoader(filePath) {
|
|
|
218
217
|
return null;
|
|
219
218
|
}
|
|
220
219
|
}
|
|
221
|
-
function reactRuntimeSource(reactBridgeUrl) {
|
|
222
|
-
if (reactBridgeUrl) {
|
|
223
|
-
return `export * from ${JSON.stringify(reactBridgeUrl)};
|
|
224
|
-
import React from ${JSON.stringify(reactBridgeUrl)};
|
|
225
|
-
export default React;
|
|
226
|
-
`;
|
|
227
|
-
}
|
|
228
|
-
return `const bridge = globalThis.__sootsim_react_bridge
|
|
229
|
-
if (!bridge) throw new Error('[rnx] replacement React bridge is not ready')
|
|
230
|
-
export default bridge.default
|
|
231
|
-
export const Activity = bridge.Activity
|
|
232
|
-
export const Children = bridge.Children
|
|
233
|
-
export const Component = bridge.Component
|
|
234
|
-
export const Fragment = bridge.Fragment
|
|
235
|
-
export const Profiler = bridge.Profiler
|
|
236
|
-
export const PureComponent = bridge.PureComponent
|
|
237
|
-
export const StrictMode = bridge.StrictMode
|
|
238
|
-
export const Suspense = bridge.Suspense
|
|
239
|
-
export const __CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE = bridge.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE
|
|
240
|
-
export const __COMPILER_RUNTIME = bridge.__COMPILER_RUNTIME
|
|
241
|
-
export const __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = bridge.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED
|
|
242
|
-
export const act = bridge.act
|
|
243
|
-
export const cache = bridge.cache
|
|
244
|
-
export const cacheSignal = bridge.cacheSignal
|
|
245
|
-
export const captureOwnerStack = bridge.captureOwnerStack
|
|
246
|
-
export const cloneElement = bridge.cloneElement
|
|
247
|
-
export const createContext = bridge.createContext
|
|
248
|
-
export const createElement = bridge.createElement
|
|
249
|
-
export const createRef = bridge.createRef
|
|
250
|
-
export const forwardRef = bridge.forwardRef
|
|
251
|
-
export const isValidElement = bridge.isValidElement
|
|
252
|
-
export const lazy = bridge.lazy
|
|
253
|
-
export const memo = bridge.memo
|
|
254
|
-
export const startTransition = bridge.startTransition
|
|
255
|
-
export const unstable_useCacheRefresh = bridge.unstable_useCacheRefresh
|
|
256
|
-
export const use = bridge.use
|
|
257
|
-
export const useActionState = bridge.useActionState
|
|
258
|
-
export const useCallback = bridge.useCallback
|
|
259
|
-
export const useContext = bridge.useContext
|
|
260
|
-
export const useDebugValue = bridge.useDebugValue
|
|
261
|
-
export const useDeferredValue = bridge.useDeferredValue
|
|
262
|
-
export const useEffect = bridge.useEffect
|
|
263
|
-
export const useEffectEvent = bridge.useEffectEvent
|
|
264
|
-
export const useId = bridge.useId
|
|
265
|
-
export const useImperativeHandle = bridge.useImperativeHandle
|
|
266
|
-
export const useInsertionEffect = bridge.useInsertionEffect
|
|
267
|
-
export const useLayoutEffect = bridge.useLayoutEffect
|
|
268
|
-
export const useMemo = bridge.useMemo
|
|
269
|
-
export const useOptimistic = bridge.useOptimistic
|
|
270
|
-
export const useReducer = bridge.useReducer
|
|
271
|
-
export const useRef = bridge.useRef
|
|
272
|
-
export const useState = bridge.useState
|
|
273
|
-
export const useSyncExternalStore = bridge.useSyncExternalStore
|
|
274
|
-
export const useTransition = bridge.useTransition
|
|
275
|
-
export const version = bridge.version
|
|
276
|
-
`;
|
|
277
|
-
}
|
|
278
|
-
function reactNativeRuntimeSource() {
|
|
279
|
-
return `const rn = globalThis.__sootsim_components__ || {}
|
|
280
|
-
export default rn
|
|
281
|
-
export const View = rn.View
|
|
282
|
-
export const Text = rn.Text
|
|
283
|
-
export const Image = rn.Image
|
|
284
|
-
export const ScrollView = rn.ScrollView
|
|
285
|
-
export const FlatList = rn.FlatList
|
|
286
|
-
export const Pressable = rn.Pressable
|
|
287
|
-
export const TouchableOpacity = rn.TouchableOpacity
|
|
288
|
-
export const TouchableWithoutFeedback = rn.TouchableWithoutFeedback
|
|
289
|
-
export const TouchableHighlight = rn.TouchableHighlight
|
|
290
|
-
export const TextInput = rn.TextInput
|
|
291
|
-
export const ActivityIndicator = rn.ActivityIndicator
|
|
292
|
-
export const KeyboardAvoidingView = rn.KeyboardAvoidingView
|
|
293
|
-
export const Button = rn.Button
|
|
294
|
-
export const Modal = rn.Modal
|
|
295
|
-
export const Switch = rn.Switch
|
|
296
|
-
export const StyleSheet = rn.StyleSheet
|
|
297
|
-
export const Platform = rn.Platform
|
|
298
|
-
export const Keyboard = rn.Keyboard
|
|
299
|
-
export const Dimensions = rn.Dimensions
|
|
300
|
-
export const Appearance = rn.Appearance
|
|
301
|
-
`;
|
|
302
|
-
}
|
|
303
220
|
function sendJavaScript(req, res, source) {
|
|
304
221
|
const origin = req.headers.origin;
|
|
305
222
|
let allowedOrigin;
|
|
@@ -341,14 +258,6 @@ async function handleReplacementModuleRequest(req, res, options = {}) {
|
|
|
341
258
|
return true;
|
|
342
259
|
}
|
|
343
260
|
}
|
|
344
|
-
if (url.pathname === `${REPLACEMENT_RUNTIME_PREFIX}/react`) {
|
|
345
|
-
sendJavaScript(req, res, reactRuntimeSource(options.reactBridgeUrl));
|
|
346
|
-
return true;
|
|
347
|
-
}
|
|
348
|
-
if (url.pathname === `${REPLACEMENT_RUNTIME_PREFIX}/react-native`) {
|
|
349
|
-
sendJavaScript(req, res, reactNativeRuntimeSource());
|
|
350
|
-
return true;
|
|
351
|
-
}
|
|
352
261
|
if (url.pathname !== REPLACEMENT_MODULE_ROUTE) return false;
|
|
353
262
|
if (options.requestToken && url.searchParams.get("token") !== options.requestToken) {
|
|
354
263
|
res.writeHead(403, { "Content-Type": "text/plain; charset=utf-8" });
|
|
@@ -372,6 +281,7 @@ async function handleReplacementModuleRequest(req, res, options = {}) {
|
|
|
372
281
|
res.end("replacement file path must be absolute");
|
|
373
282
|
return true;
|
|
374
283
|
}
|
|
284
|
+
const runtimePackages = new Set(url.searchParams.getAll("runtimePackage"));
|
|
375
285
|
let resolvedProjectRoot;
|
|
376
286
|
if (options.projectRoot) {
|
|
377
287
|
const lexicalProjectRoot = import_node_path3.default.resolve(options.projectRoot);
|
|
@@ -414,19 +324,64 @@ async function handleReplacementModuleRequest(req, res, options = {}) {
|
|
|
414
324
|
tsconfigRaw: { compilerOptions: { jsx: "react" } },
|
|
415
325
|
sourcemap: "inline",
|
|
416
326
|
logLevel: "silent",
|
|
417
|
-
|
|
327
|
+
plugins: [
|
|
328
|
+
{
|
|
329
|
+
name: "sootsim-replacement-runtime",
|
|
330
|
+
setup(runtimeBuild) {
|
|
331
|
+
runtimeBuild.onResolve(
|
|
332
|
+
{
|
|
333
|
+
filter: /^(react|react-native|react\/jsx-runtime|react\/jsx-dev-runtime)$/
|
|
334
|
+
},
|
|
335
|
+
(args) => ({ path: args.path, namespace: "sootsim-replacement-runtime" })
|
|
336
|
+
);
|
|
337
|
+
runtimeBuild.onResolve(
|
|
338
|
+
{ filter: /.*/ },
|
|
339
|
+
(args) => runtimePackages.has(args.path) ? { path: args.path, namespace: "sootsim-replacement-runtime" } : void 0
|
|
340
|
+
);
|
|
341
|
+
runtimeBuild.onLoad(
|
|
342
|
+
{ filter: /.*/, namespace: "sootsim-replacement-runtime" },
|
|
343
|
+
(args) => {
|
|
344
|
+
if (args.path === "react-native") {
|
|
345
|
+
return {
|
|
346
|
+
contents: `const bridge = globalThis.__sootsim_components__
|
|
347
|
+
if (!bridge) throw new Error('[rnx] replacement React Native bridge is not ready')
|
|
348
|
+
module.exports = bridge`,
|
|
349
|
+
loader: "js"
|
|
350
|
+
};
|
|
351
|
+
}
|
|
352
|
+
if (args.path === "react") {
|
|
353
|
+
return {
|
|
354
|
+
contents: `const bridge = globalThis.__sootsim_react_bridge
|
|
355
|
+
if (!bridge) throw new Error('[rnx] replacement React bridge is not ready')
|
|
356
|
+
module.exports = bridge`,
|
|
357
|
+
loader: "js"
|
|
358
|
+
};
|
|
359
|
+
}
|
|
360
|
+
if (args.path !== "react/jsx-runtime" && args.path !== "react/jsx-dev-runtime") {
|
|
361
|
+
return {
|
|
362
|
+
contents: `const packages = globalThis.__sootsim_config_package_modules
|
|
363
|
+
const bridge = packages?.[${JSON.stringify(args.path)}]
|
|
364
|
+
if (!bridge) throw new Error(${JSON.stringify(`[rnx] replacement package bridge ${args.path} is not ready`)})
|
|
365
|
+
module.exports = bridge`,
|
|
366
|
+
loader: "js"
|
|
367
|
+
};
|
|
368
|
+
}
|
|
369
|
+
return {
|
|
370
|
+
contents: `const React = globalThis.__sootsim_react_bridge
|
|
371
|
+
if (!React) throw new Error('[rnx] replacement React bridge is not ready')
|
|
372
|
+
exports.Fragment = React.Fragment
|
|
373
|
+
exports.jsx = (type, props, key) => React.createElement(type, key === undefined ? props : { ...props, key })
|
|
374
|
+
exports.jsxs = exports.jsx
|
|
375
|
+
exports.jsxDEV = exports.jsx`,
|
|
376
|
+
loader: "js"
|
|
377
|
+
};
|
|
378
|
+
}
|
|
379
|
+
);
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
]
|
|
418
383
|
});
|
|
419
|
-
|
|
420
|
-
const hasReactBinding = /\bimport\s+(?:\*\s+as\s+React|React(?:\s*,|\s+from)|\{[^}]*\bdefault\s+as\s+React\b)/.test(
|
|
421
|
-
bundledCode
|
|
422
|
-
);
|
|
423
|
-
const reactImport = /\bReact\.(?:createElement|Fragment)\b/.test(bundledCode) && !hasReactBinding ? `import * as React from '${REPLACEMENT_RUNTIME_PREFIX}/react';
|
|
424
|
-
` : "";
|
|
425
|
-
const runtimeCode = (reactImport + bundledCode).replace(
|
|
426
|
-
/from\s*["']react-native["']/g,
|
|
427
|
-
`from '${REPLACEMENT_RUNTIME_PREFIX}/react-native'`
|
|
428
|
-
).replace(/from\s*["']react["']/g, `from '${REPLACEMENT_RUNTIME_PREFIX}/react'`);
|
|
429
|
-
sendJavaScript(req, res, runtimeCode);
|
|
384
|
+
sendJavaScript(req, res, result.outputFiles[0]?.text ?? "");
|
|
430
385
|
} catch (error) {
|
|
431
386
|
const message = error instanceof Error ? error.message : String(error);
|
|
432
387
|
res.writeHead(500, { "Content-Type": "text/plain; charset=utf-8" });
|
package/package.json
CHANGED
package/src/host/bridge-host.ts
CHANGED
|
@@ -7,7 +7,6 @@ import {
|
|
|
7
7
|
scanDevServers,
|
|
8
8
|
type DiscoveredServer,
|
|
9
9
|
} from '../../scripts/dev-server-scanner.ts'
|
|
10
|
-
import { isLoopbackHost } from '../backend-origin.ts'
|
|
11
10
|
import {
|
|
12
11
|
DEFAULT_SOOTSIM_BRIDGE_PORT,
|
|
13
12
|
SOOTSIM_BRIDGE_SIM_CLOSE_CODE,
|
|
@@ -44,6 +43,7 @@ import { sootsimRuntime } from '../runtime-delivery.ts'
|
|
|
44
43
|
import { AgentHost, type AgentHostOptions } from './agent-host.ts'
|
|
45
44
|
import {
|
|
46
45
|
handleAppApiRequest,
|
|
46
|
+
handleBundleProxyRequest,
|
|
47
47
|
handleFetchProxyRequest,
|
|
48
48
|
isAppApiRequestUrl,
|
|
49
49
|
isFetchProxyRequestUrl,
|
|
@@ -1669,55 +1669,7 @@ export class SootSimBridgeHost {
|
|
|
1669
1669
|
// cross-origin URL without CORS headers, and metro doesn't set them.
|
|
1670
1670
|
// we proxy the request and stream the response back.
|
|
1671
1671
|
if (url.pathname === '/__bundle-proxy') {
|
|
1672
|
-
|
|
1673
|
-
if (!target) {
|
|
1674
|
-
res.writeHead(400, { 'Content-Type': 'text/plain' })
|
|
1675
|
-
res.end('bundle-proxy: missing url query param')
|
|
1676
|
-
return
|
|
1677
|
-
}
|
|
1678
|
-
let parsedTarget: URL
|
|
1679
|
-
try {
|
|
1680
|
-
parsedTarget = new URL(target)
|
|
1681
|
-
} catch {
|
|
1682
|
-
res.writeHead(400, { 'Content-Type': 'text/plain' })
|
|
1683
|
-
res.end('bundle-proxy: invalid url')
|
|
1684
|
-
return
|
|
1685
|
-
}
|
|
1686
|
-
// limit to local loopback targets — preventing the daemon from being
|
|
1687
|
-
// turned into an open proxy for arbitrary internet fetches.
|
|
1688
|
-
if (!isLoopbackHost(parsedTarget.hostname)) {
|
|
1689
|
-
res.writeHead(403, { 'Content-Type': 'text/plain' })
|
|
1690
|
-
res.end('bundle-proxy: only loopback targets allowed')
|
|
1691
|
-
return
|
|
1692
|
-
}
|
|
1693
|
-
void (async () => {
|
|
1694
|
-
try {
|
|
1695
|
-
const upstream = await fetch(parsedTarget.toString(), {
|
|
1696
|
-
redirect: 'follow',
|
|
1697
|
-
})
|
|
1698
|
-
const headers: Record<string, string> = {}
|
|
1699
|
-
const ct = upstream.headers.get('content-type')
|
|
1700
|
-
if (ct) headers['Content-Type'] = ct
|
|
1701
|
-
headers['Cache-Control'] = 'no-store'
|
|
1702
|
-
res.writeHead(upstream.status, headers)
|
|
1703
|
-
if (!upstream.body) {
|
|
1704
|
-
res.end()
|
|
1705
|
-
return
|
|
1706
|
-
}
|
|
1707
|
-
const reader = upstream.body.getReader()
|
|
1708
|
-
while (true) {
|
|
1709
|
-
const { done, value } = await reader.read()
|
|
1710
|
-
if (done) break
|
|
1711
|
-
res.write(Buffer.from(value))
|
|
1712
|
-
}
|
|
1713
|
-
res.end()
|
|
1714
|
-
} catch (err) {
|
|
1715
|
-
res.writeHead(502, { 'Content-Type': 'text/plain' })
|
|
1716
|
-
res.end(
|
|
1717
|
-
`bundle-proxy: upstream fetch failed: ${err instanceof Error ? err.message : String(err)}`,
|
|
1718
|
-
)
|
|
1719
|
-
}
|
|
1720
|
-
})()
|
|
1672
|
+
void handleBundleProxyRequest(req, res)
|
|
1721
1673
|
return
|
|
1722
1674
|
}
|
|
1723
1675
|
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
import http, { type IncomingMessage, type ServerResponse } from 'http'
|
|
27
27
|
import https from 'https'
|
|
28
28
|
import { finished, pipeline } from 'stream/promises'
|
|
29
|
-
import { isLoopbackHost } from '../backend-origin.ts'
|
|
29
|
+
import { isLoopbackHost, normalizeHostname } from '../backend-origin.ts'
|
|
30
30
|
import {
|
|
31
31
|
FETCH_PROXY_BROWSER_USER_AGENT,
|
|
32
32
|
getFetchProxyTargetHeaders,
|
|
@@ -149,6 +149,10 @@ export function isFetchProxyRequestUrl(rawUrl: string | undefined): boolean {
|
|
|
149
149
|
return rawUrl?.startsWith('/__fetch-proxy?') || rawUrl?.startsWith('/__proxy?') || false
|
|
150
150
|
}
|
|
151
151
|
|
|
152
|
+
export function isBundleProxyRequestUrl(rawUrl: string | undefined): boolean {
|
|
153
|
+
return rawUrl?.startsWith('/__bundle-proxy?') ?? false
|
|
154
|
+
}
|
|
155
|
+
|
|
152
156
|
export function isAppApiRequestUrl(rawUrl: string | undefined): boolean {
|
|
153
157
|
if (!rawUrl) return false
|
|
154
158
|
if (rawUrl.startsWith('/__app-api?')) return true
|
|
@@ -220,7 +224,7 @@ export async function handleFetchProxyRequest(
|
|
|
220
224
|
const proxyRes = await new Promise<IncomingMessage>((resolve, reject) => {
|
|
221
225
|
const proxyReq = transport.request(
|
|
222
226
|
{
|
|
223
|
-
hostname: targetUrl.hostname,
|
|
227
|
+
hostname: normalizeHostname(targetUrl.hostname),
|
|
224
228
|
port: targetUrl.port || (targetUrl.protocol === 'https:' ? 443 : 80),
|
|
225
229
|
path: targetUrl.pathname + targetUrl.search,
|
|
226
230
|
method,
|
|
@@ -310,6 +314,39 @@ export async function handleFetchProxyRequest(
|
|
|
310
314
|
}
|
|
311
315
|
}
|
|
312
316
|
|
|
317
|
+
export async function handleBundleProxyRequest(
|
|
318
|
+
req: IncomingMessage,
|
|
319
|
+
res: ServerResponse,
|
|
320
|
+
): Promise<void> {
|
|
321
|
+
const params = new URLSearchParams((req.url || '').split('?')[1] || '')
|
|
322
|
+
const target = params.get('url')
|
|
323
|
+
if (!target) {
|
|
324
|
+
applyFetchProxyCors(res)
|
|
325
|
+
res.writeHead(400, { 'Content-Type': 'text/plain' })
|
|
326
|
+
res.end('bundle-proxy: missing url query param')
|
|
327
|
+
return
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
let targetUrl: URL
|
|
331
|
+
try {
|
|
332
|
+
targetUrl = new URL(target)
|
|
333
|
+
} catch {
|
|
334
|
+
applyFetchProxyCors(res)
|
|
335
|
+
res.writeHead(400, { 'Content-Type': 'text/plain' })
|
|
336
|
+
res.end('bundle-proxy: invalid url')
|
|
337
|
+
return
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
if (!isLoopbackHost(targetUrl.hostname)) {
|
|
341
|
+
applyFetchProxyCors(res)
|
|
342
|
+
res.writeHead(403, { 'Content-Type': 'text/plain' })
|
|
343
|
+
res.end('bundle-proxy: only loopback targets allowed')
|
|
344
|
+
return
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
await handleFetchProxyRequest(req, res)
|
|
348
|
+
}
|
|
349
|
+
|
|
313
350
|
export function handleAppApiRequest(req: IncomingMessage, res: ServerResponse): boolean {
|
|
314
351
|
// returns true if it handled the request, false if the caller should fall
|
|
315
352
|
// through. /__app-api requires `origin` query param for stateless mode;
|
|
@@ -365,7 +402,7 @@ export function handleAppApiRequest(req: IncomingMessage, res: ServerResponse):
|
|
|
365
402
|
|
|
366
403
|
const proxyReq = transport.request(
|
|
367
404
|
{
|
|
368
|
-
hostname: targetUrl.hostname,
|
|
405
|
+
hostname: normalizeHostname(targetUrl.hostname),
|
|
369
406
|
port: targetUrl.port || (targetUrl.protocol === 'https:' ? 443 : 80),
|
|
370
407
|
path: targetUrl.pathname + targetUrl.search,
|
|
371
408
|
method: req.method,
|
|
@@ -5,10 +5,8 @@ import { isLoopbackHost } from '../backend-origin.ts'
|
|
|
5
5
|
import type { IncomingMessage, ServerResponse } from 'node:http'
|
|
6
6
|
|
|
7
7
|
export const REPLACEMENT_MODULE_ROUTE = '/__sootsim-replacement-module'
|
|
8
|
-
export const REPLACEMENT_RUNTIME_PREFIX = '/__sootsim-replacement-runtime'
|
|
9
8
|
|
|
10
9
|
export interface ReplacementModuleHandlerOptions {
|
|
11
|
-
reactBridgeUrl?: string
|
|
12
10
|
projectRoot?: string
|
|
13
11
|
requireLoopbackOrigin?: boolean
|
|
14
12
|
requestToken?: string
|
|
@@ -30,92 +28,6 @@ function getReplacementLoader(filePath: string): 'js' | 'jsx' | 'ts' | 'tsx' | n
|
|
|
30
28
|
}
|
|
31
29
|
}
|
|
32
30
|
|
|
33
|
-
function reactRuntimeSource(reactBridgeUrl?: string): string {
|
|
34
|
-
if (reactBridgeUrl) {
|
|
35
|
-
return (
|
|
36
|
-
`export * from ${JSON.stringify(reactBridgeUrl)};\n` +
|
|
37
|
-
`import React from ${JSON.stringify(reactBridgeUrl)};\n` +
|
|
38
|
-
`export default React;\n`
|
|
39
|
-
)
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
return `const bridge = globalThis.__sootsim_react_bridge
|
|
43
|
-
if (!bridge) throw new Error('[rnx] replacement React bridge is not ready')
|
|
44
|
-
export default bridge.default
|
|
45
|
-
export const Activity = bridge.Activity
|
|
46
|
-
export const Children = bridge.Children
|
|
47
|
-
export const Component = bridge.Component
|
|
48
|
-
export const Fragment = bridge.Fragment
|
|
49
|
-
export const Profiler = bridge.Profiler
|
|
50
|
-
export const PureComponent = bridge.PureComponent
|
|
51
|
-
export const StrictMode = bridge.StrictMode
|
|
52
|
-
export const Suspense = bridge.Suspense
|
|
53
|
-
export const __CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE = bridge.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE
|
|
54
|
-
export const __COMPILER_RUNTIME = bridge.__COMPILER_RUNTIME
|
|
55
|
-
export const __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = bridge.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED
|
|
56
|
-
export const act = bridge.act
|
|
57
|
-
export const cache = bridge.cache
|
|
58
|
-
export const cacheSignal = bridge.cacheSignal
|
|
59
|
-
export const captureOwnerStack = bridge.captureOwnerStack
|
|
60
|
-
export const cloneElement = bridge.cloneElement
|
|
61
|
-
export const createContext = bridge.createContext
|
|
62
|
-
export const createElement = bridge.createElement
|
|
63
|
-
export const createRef = bridge.createRef
|
|
64
|
-
export const forwardRef = bridge.forwardRef
|
|
65
|
-
export const isValidElement = bridge.isValidElement
|
|
66
|
-
export const lazy = bridge.lazy
|
|
67
|
-
export const memo = bridge.memo
|
|
68
|
-
export const startTransition = bridge.startTransition
|
|
69
|
-
export const unstable_useCacheRefresh = bridge.unstable_useCacheRefresh
|
|
70
|
-
export const use = bridge.use
|
|
71
|
-
export const useActionState = bridge.useActionState
|
|
72
|
-
export const useCallback = bridge.useCallback
|
|
73
|
-
export const useContext = bridge.useContext
|
|
74
|
-
export const useDebugValue = bridge.useDebugValue
|
|
75
|
-
export const useDeferredValue = bridge.useDeferredValue
|
|
76
|
-
export const useEffect = bridge.useEffect
|
|
77
|
-
export const useEffectEvent = bridge.useEffectEvent
|
|
78
|
-
export const useId = bridge.useId
|
|
79
|
-
export const useImperativeHandle = bridge.useImperativeHandle
|
|
80
|
-
export const useInsertionEffect = bridge.useInsertionEffect
|
|
81
|
-
export const useLayoutEffect = bridge.useLayoutEffect
|
|
82
|
-
export const useMemo = bridge.useMemo
|
|
83
|
-
export const useOptimistic = bridge.useOptimistic
|
|
84
|
-
export const useReducer = bridge.useReducer
|
|
85
|
-
export const useRef = bridge.useRef
|
|
86
|
-
export const useState = bridge.useState
|
|
87
|
-
export const useSyncExternalStore = bridge.useSyncExternalStore
|
|
88
|
-
export const useTransition = bridge.useTransition
|
|
89
|
-
export const version = bridge.version
|
|
90
|
-
`
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
function reactNativeRuntimeSource(): string {
|
|
94
|
-
return `const rn = globalThis.__sootsim_components__ || {}
|
|
95
|
-
export default rn
|
|
96
|
-
export const View = rn.View
|
|
97
|
-
export const Text = rn.Text
|
|
98
|
-
export const Image = rn.Image
|
|
99
|
-
export const ScrollView = rn.ScrollView
|
|
100
|
-
export const FlatList = rn.FlatList
|
|
101
|
-
export const Pressable = rn.Pressable
|
|
102
|
-
export const TouchableOpacity = rn.TouchableOpacity
|
|
103
|
-
export const TouchableWithoutFeedback = rn.TouchableWithoutFeedback
|
|
104
|
-
export const TouchableHighlight = rn.TouchableHighlight
|
|
105
|
-
export const TextInput = rn.TextInput
|
|
106
|
-
export const ActivityIndicator = rn.ActivityIndicator
|
|
107
|
-
export const KeyboardAvoidingView = rn.KeyboardAvoidingView
|
|
108
|
-
export const Button = rn.Button
|
|
109
|
-
export const Modal = rn.Modal
|
|
110
|
-
export const Switch = rn.Switch
|
|
111
|
-
export const StyleSheet = rn.StyleSheet
|
|
112
|
-
export const Platform = rn.Platform
|
|
113
|
-
export const Keyboard = rn.Keyboard
|
|
114
|
-
export const Dimensions = rn.Dimensions
|
|
115
|
-
export const Appearance = rn.Appearance
|
|
116
|
-
`
|
|
117
|
-
}
|
|
118
|
-
|
|
119
31
|
function sendJavaScript(req: IncomingMessage, res: ServerResponse, source: string): void {
|
|
120
32
|
const origin = req.headers.origin
|
|
121
33
|
let allowedOrigin: string | undefined
|
|
@@ -138,10 +50,7 @@ export function isReplacementModuleRequestUrl(rawUrl?: string): boolean {
|
|
|
138
50
|
if (!rawUrl) return false
|
|
139
51
|
try {
|
|
140
52
|
const pathname = new URL(rawUrl, 'http://rnx.local').pathname
|
|
141
|
-
return
|
|
142
|
-
pathname === REPLACEMENT_MODULE_ROUTE ||
|
|
143
|
-
pathname.startsWith(`${REPLACEMENT_RUNTIME_PREFIX}/`)
|
|
144
|
-
)
|
|
53
|
+
return pathname === REPLACEMENT_MODULE_ROUTE
|
|
145
54
|
} catch {
|
|
146
55
|
return false
|
|
147
56
|
}
|
|
@@ -178,14 +87,6 @@ export async function handleReplacementModuleRequest(
|
|
|
178
87
|
}
|
|
179
88
|
}
|
|
180
89
|
|
|
181
|
-
if (url.pathname === `${REPLACEMENT_RUNTIME_PREFIX}/react`) {
|
|
182
|
-
sendJavaScript(req, res, reactRuntimeSource(options.reactBridgeUrl))
|
|
183
|
-
return true
|
|
184
|
-
}
|
|
185
|
-
if (url.pathname === `${REPLACEMENT_RUNTIME_PREFIX}/react-native`) {
|
|
186
|
-
sendJavaScript(req, res, reactNativeRuntimeSource())
|
|
187
|
-
return true
|
|
188
|
-
}
|
|
189
90
|
if (url.pathname !== REPLACEMENT_MODULE_ROUTE) return false
|
|
190
91
|
|
|
191
92
|
if (options.requestToken && url.searchParams.get('token') !== options.requestToken) {
|
|
@@ -214,6 +115,8 @@ export async function handleReplacementModuleRequest(
|
|
|
214
115
|
return true
|
|
215
116
|
}
|
|
216
117
|
|
|
118
|
+
const runtimePackages = new Set(url.searchParams.getAll('runtimePackage'))
|
|
119
|
+
|
|
217
120
|
let resolvedProjectRoot: string | undefined
|
|
218
121
|
if (options.projectRoot) {
|
|
219
122
|
const lexicalProjectRoot = path.resolve(options.projectRoot)
|
|
@@ -259,24 +162,69 @@ export async function handleReplacementModuleRequest(
|
|
|
259
162
|
tsconfigRaw: { compilerOptions: { jsx: 'react' } },
|
|
260
163
|
sourcemap: 'inline',
|
|
261
164
|
logLevel: 'silent',
|
|
262
|
-
|
|
165
|
+
plugins: [
|
|
166
|
+
{
|
|
167
|
+
name: 'sootsim-replacement-runtime',
|
|
168
|
+
setup(runtimeBuild) {
|
|
169
|
+
runtimeBuild.onResolve(
|
|
170
|
+
{
|
|
171
|
+
filter:
|
|
172
|
+
/^(react|react-native|react\/jsx-runtime|react\/jsx-dev-runtime)$/,
|
|
173
|
+
},
|
|
174
|
+
(args) => ({ path: args.path, namespace: 'sootsim-replacement-runtime' }),
|
|
175
|
+
)
|
|
176
|
+
runtimeBuild.onResolve({ filter: /.*/ }, (args) =>
|
|
177
|
+
runtimePackages.has(args.path)
|
|
178
|
+
? { path: args.path, namespace: 'sootsim-replacement-runtime' }
|
|
179
|
+
: undefined,
|
|
180
|
+
)
|
|
181
|
+
runtimeBuild.onLoad(
|
|
182
|
+
{ filter: /.*/, namespace: 'sootsim-replacement-runtime' },
|
|
183
|
+
(args) => {
|
|
184
|
+
if (args.path === 'react-native') {
|
|
185
|
+
return {
|
|
186
|
+
contents: `const bridge = globalThis.__sootsim_components__
|
|
187
|
+
if (!bridge) throw new Error('[rnx] replacement React Native bridge is not ready')
|
|
188
|
+
module.exports = bridge`,
|
|
189
|
+
loader: 'js',
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
if (args.path === 'react') {
|
|
193
|
+
return {
|
|
194
|
+
contents: `const bridge = globalThis.__sootsim_react_bridge
|
|
195
|
+
if (!bridge) throw new Error('[rnx] replacement React bridge is not ready')
|
|
196
|
+
module.exports = bridge`,
|
|
197
|
+
loader: 'js',
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
if (
|
|
201
|
+
args.path !== 'react/jsx-runtime' &&
|
|
202
|
+
args.path !== 'react/jsx-dev-runtime'
|
|
203
|
+
) {
|
|
204
|
+
return {
|
|
205
|
+
contents: `const packages = globalThis.__sootsim_config_package_modules
|
|
206
|
+
const bridge = packages?.[${JSON.stringify(args.path)}]
|
|
207
|
+
if (!bridge) throw new Error(${JSON.stringify(`[rnx] replacement package bridge ${args.path} is not ready`)})
|
|
208
|
+
module.exports = bridge`,
|
|
209
|
+
loader: 'js',
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
return {
|
|
213
|
+
contents: `const React = globalThis.__sootsim_react_bridge
|
|
214
|
+
if (!React) throw new Error('[rnx] replacement React bridge is not ready')
|
|
215
|
+
exports.Fragment = React.Fragment
|
|
216
|
+
exports.jsx = (type, props, key) => React.createElement(type, key === undefined ? props : { ...props, key })
|
|
217
|
+
exports.jsxs = exports.jsx
|
|
218
|
+
exports.jsxDEV = exports.jsx`,
|
|
219
|
+
loader: 'js',
|
|
220
|
+
}
|
|
221
|
+
},
|
|
222
|
+
)
|
|
223
|
+
},
|
|
224
|
+
},
|
|
225
|
+
],
|
|
263
226
|
})
|
|
264
|
-
|
|
265
|
-
const hasReactBinding =
|
|
266
|
-
/\bimport\s+(?:\*\s+as\s+React|React(?:\s*,|\s+from)|\{[^}]*\bdefault\s+as\s+React\b)/.test(
|
|
267
|
-
bundledCode,
|
|
268
|
-
)
|
|
269
|
-
const reactImport =
|
|
270
|
-
/\bReact\.(?:createElement|Fragment)\b/.test(bundledCode) && !hasReactBinding
|
|
271
|
-
? `import * as React from '${REPLACEMENT_RUNTIME_PREFIX}/react';\n`
|
|
272
|
-
: ''
|
|
273
|
-
const runtimeCode = (reactImport + bundledCode)
|
|
274
|
-
.replace(
|
|
275
|
-
/from\s*["']react-native["']/g,
|
|
276
|
-
`from '${REPLACEMENT_RUNTIME_PREFIX}/react-native'`,
|
|
277
|
-
)
|
|
278
|
-
.replace(/from\s*["']react["']/g, `from '${REPLACEMENT_RUNTIME_PREFIX}/react'`)
|
|
279
|
-
sendJavaScript(req, res, runtimeCode)
|
|
227
|
+
sendJavaScript(req, res, result.outputFiles[0]?.text ?? '')
|
|
280
228
|
} catch (error) {
|
|
281
229
|
const message = error instanceof Error ? error.message : String(error)
|
|
282
230
|
res.writeHead(500, { 'Content-Type': 'text/plain; charset=utf-8' })
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
/*! rnx v0.1.363 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
|
|
2
|
-
import { createRequire as __sootsimCreateRequire } from 'node:module'
|
|
3
|
-
var require = __sootsimCreateRequire(import.meta.url)
|
|
4
|
-
import{o as p}from"./chunk-4ZGUXZ6U.js";import"./chunk-XYPCBRGY.js";import"./chunk-YFF6YFYJ.js";import"./chunk-NUU3SWLR.js";import{existsSync as h,mkdirSync as d,readFileSync as y,writeFileSync as g}from"node:fs";import{join as m}from"node:path";import{gzipSync as w}from"node:zlib";function f(t,e){let o=t.indexOf(`--${e}`);if(o!==-1&&o+1<t.length)return t[o+1];let r=t.find(i=>i.startsWith(`--${e}=`));return r?r.slice(e.length+3):void 0}async function x(t){let e=f(t,"wire")||"",o=f(t,"out-dir"),r=f(t,"manifest");if((!o||!r)&&(console.error(" usage: rnx app-fonts stage --wire <wire> --out-dir <dir> --manifest <path>"),process.exit(1)),!e.trim()){console.log("no app fonts declared \u2014 nothing to stage");return}d(o,{recursive:!0});let i=await p(e,{onStaged:({url:n,byteLength:s})=>console.log(` staged app font: ${n} (${(s/1024).toFixed(1)} KiB)`),onError:(n,s)=>console.error(` warning: failed to fetch app font ${n}: ${s instanceof Error?s.message:s}`)}),a=[];for(let n of i){let s=w(n.bytes);g(m(o,n.urlhash),s),a.push({url:n.url,urlhash:n.urlhash,contentType:n.contentType,encoding:"gzip",sizeBytes:s.length,rawBytes:n.bytes.byteLength})}let c=[];if(h(r))try{let n=JSON.parse(y(r,"utf8"));Array.isArray(n)&&(c=n)}catch{}let u=new Set(c.map(n=>n.urlhash)),l=[...c,...a.filter(n=>!u.has(n.urlhash))];g(r,JSON.stringify(l)),console.log(`staged ${a.length} app font(s); manifest now has ${l.length} file(s)`)}async function E(t){let e=t[0];if(e==="stage"){await x(t.slice(1));return}console.error(` unknown app-fonts subcommand: ${e??"(none)"}`),console.error(" available: stage"),process.exit(1)}export{E as runAppFonts};
|