basalt-core 0.0.0-rc5
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/LICENSE +21 -0
- package/dist/cli/basalt.d.ts +3 -0
- package/dist/cli/basalt.d.ts.map +1 -0
- package/dist/cli/basalt.js +47 -0
- package/dist/cli/basalt.js.map +1 -0
- package/dist/cli/bundle-cli.d.ts +12 -0
- package/dist/cli/bundle-cli.d.ts.map +1 -0
- package/dist/cli/bundle-cli.js +124 -0
- package/dist/cli/bundle-cli.js.map +1 -0
- package/dist/cli/bundleWithAssets.d.ts +79 -0
- package/dist/cli/bundleWithAssets.d.ts.map +1 -0
- package/dist/cli/bundleWithAssets.js +198 -0
- package/dist/cli/bundleWithAssets.js.map +1 -0
- package/dist/cli/desktop.d.ts +339 -0
- package/dist/cli/desktop.d.ts.map +1 -0
- package/dist/cli/desktop.js +1029 -0
- package/dist/cli/desktop.js.map +1 -0
- package/dist/cli/doctor.d.ts +31 -0
- package/dist/cli/doctor.d.ts.map +1 -0
- package/dist/cli/doctor.js +283 -0
- package/dist/cli/doctor.js.map +1 -0
- package/dist/cli/init.d.ts +77 -0
- package/dist/cli/init.d.ts.map +1 -0
- package/dist/cli/init.js +442 -0
- package/dist/cli/init.js.map +1 -0
- package/dist/cli/metro.d.ts +49 -0
- package/dist/cli/metro.d.ts.map +1 -0
- package/dist/cli/metro.js +148 -0
- package/dist/cli/metro.js.map +1 -0
- package/dist/cli/packageApp.d.ts +102 -0
- package/dist/cli/packageApp.d.ts.map +1 -0
- package/dist/cli/packageApp.js +319 -0
- package/dist/cli/packageApp.js.map +1 -0
- package/dist/cli/steps.d.ts +34 -0
- package/dist/cli/steps.d.ts.map +1 -0
- package/dist/cli/steps.js +53 -0
- package/dist/cli/steps.js.map +1 -0
- package/dist/metro-config.d.ts +168 -0
- package/dist/metro-config.d.ts.map +1 -0
- package/dist/metro-config.js +671 -0
- package/dist/metro-config.js.map +1 -0
- package/dist/react-native.config.d.ts +7 -0
- package/dist/react-native.config.d.ts.map +1 -0
- package/dist/react-native.config.js +80 -0
- package/dist/react-native.config.js.map +1 -0
- package/dist/src/DragSource.d.ts +52 -0
- package/dist/src/DragSource.d.ts.map +1 -0
- package/dist/src/DragSource.js +97 -0
- package/dist/src/DragSource.js.map +1 -0
- package/dist/src/DropTarget.d.ts +58 -0
- package/dist/src/DropTarget.d.ts.map +1 -0
- package/dist/src/DropTarget.js +131 -0
- package/dist/src/DropTarget.js.map +1 -0
- package/dist/src/KeyHandler.d.ts +57 -0
- package/dist/src/KeyHandler.d.ts.map +1 -0
- package/dist/src/KeyHandler.js +48 -0
- package/dist/src/KeyHandler.js.map +1 -0
- package/dist/src/Menu.d.ts +72 -0
- package/dist/src/Menu.d.ts.map +1 -0
- package/dist/src/Menu.js +179 -0
- package/dist/src/Menu.js.map +1 -0
- package/dist/src/TitleBar.d.ts +75 -0
- package/dist/src/TitleBar.d.ts.map +1 -0
- package/dist/src/TitleBar.js +236 -0
- package/dist/src/TitleBar.js.map +1 -0
- package/dist/src/Window.d.ts +87 -0
- package/dist/src/Window.d.ts.map +1 -0
- package/dist/src/Window.js +248 -0
- package/dist/src/Window.js.map +1 -0
- package/dist/src/closeRequest.d.ts +55 -0
- package/dist/src/closeRequest.d.ts.map +1 -0
- package/dist/src/closeRequest.js +134 -0
- package/dist/src/closeRequest.js.map +1 -0
- package/dist/src/index.d.ts +45 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +92 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/overrides/Alert.d.ts +69 -0
- package/dist/src/overrides/Alert.d.ts.map +1 -0
- package/dist/src/overrides/Alert.js +112 -0
- package/dist/src/overrides/Alert.js.map +1 -0
- package/dist/src/overrides/BaseViewConfig.d.ts +28 -0
- package/dist/src/overrides/BaseViewConfig.d.ts.map +1 -0
- package/dist/src/overrides/BaseViewConfig.js +72 -0
- package/dist/src/overrides/BaseViewConfig.js.map +1 -0
- package/dist/src/overrides/Platform.linux.d.ts +10 -0
- package/dist/src/overrides/Platform.linux.d.ts.map +1 -0
- package/dist/src/overrides/Platform.linux.js +15 -0
- package/dist/src/overrides/Platform.linux.js.map +1 -0
- package/dist/src/overrides/Platform.macos.d.ts +10 -0
- package/dist/src/overrides/Platform.macos.d.ts.map +1 -0
- package/dist/src/overrides/Platform.macos.js +15 -0
- package/dist/src/overrides/Platform.macos.js.map +1 -0
- package/dist/src/overrides/Platform.windows.d.ts +10 -0
- package/dist/src/overrides/Platform.windows.d.ts.map +1 -0
- package/dist/src/overrides/Platform.windows.js +15 -0
- package/dist/src/overrides/Platform.windows.js.map +1 -0
- package/dist/src/overrides/ReactDevToolsSettingsManager.d.ts +24 -0
- package/dist/src/overrides/ReactDevToolsSettingsManager.d.ts.map +1 -0
- package/dist/src/overrides/ReactDevToolsSettingsManager.js +30 -0
- package/dist/src/overrides/ReactDevToolsSettingsManager.js.map +1 -0
- package/dist/src/overrides/RefreshControl.d.ts +52 -0
- package/dist/src/overrides/RefreshControl.d.ts.map +1 -0
- package/dist/src/overrides/RefreshControl.js +92 -0
- package/dist/src/overrides/RefreshControl.js.map +1 -0
- package/dist/src/overrides/ScrollView.d.ts +39 -0
- package/dist/src/overrides/ScrollView.d.ts.map +1 -0
- package/dist/src/overrides/ScrollView.js +59 -0
- package/dist/src/overrides/ScrollView.js.map +1 -0
- package/dist/src/overrides/Share.d.ts +96 -0
- package/dist/src/overrides/Share.d.ts.map +1 -0
- package/dist/src/overrides/Share.js +97 -0
- package/dist/src/overrides/Share.js.map +1 -0
- package/dist/src/overrides/TextInput.d.ts +81 -0
- package/dist/src/overrides/TextInput.d.ts.map +1 -0
- package/dist/src/overrides/TextInput.js +213 -0
- package/dist/src/overrides/TextInput.js.map +1 -0
- package/dist/src/overrides/View.d.ts +36 -0
- package/dist/src/overrides/View.d.ts.map +1 -0
- package/dist/src/overrides/View.js +99 -0
- package/dist/src/overrides/View.js.map +1 -0
- package/dist/src/overrides/createPlatform.d.ts +32 -0
- package/dist/src/overrides/createPlatform.d.ts.map +1 -0
- package/dist/src/overrides/createPlatform.js +84 -0
- package/dist/src/overrides/createPlatform.js.map +1 -0
- package/dist/src/overrides/setUpDeveloperTools.d.ts +28 -0
- package/dist/src/overrides/setUpDeveloperTools.d.ts.map +1 -0
- package/dist/src/overrides/setUpDeveloperTools.js +84 -0
- package/dist/src/overrides/setUpDeveloperTools.js.map +1 -0
- package/dist/src/overrides/setUpXHR.d.ts +46 -0
- package/dist/src/overrides/setUpXHR.d.ts.map +1 -0
- package/dist/src/overrides/setUpXHR.js +236 -0
- package/dist/src/overrides/setUpXHR.js.map +1 -0
- package/dist/src/quitRequest.d.ts +55 -0
- package/dist/src/quitRequest.d.ts.map +1 -0
- package/dist/src/quitRequest.js +121 -0
- package/dist/src/quitRequest.js.map +1 -0
- package/dist/src/resourcePath.d.ts +18 -0
- package/dist/src/resourcePath.d.ts.map +1 -0
- package/dist/src/resourcePath.js +31 -0
- package/dist/src/resourcePath.js.map +1 -0
- package/dist/src/responseBody.d.ts +76 -0
- package/dist/src/responseBody.d.ts.map +1 -0
- package/dist/src/responseBody.js +94 -0
- package/dist/src/responseBody.js.map +1 -0
- package/dist/src/responseHeaders.d.ts +40 -0
- package/dist/src/responseHeaders.d.ts.map +1 -0
- package/dist/src/responseHeaders.js +75 -0
- package/dist/src/responseHeaders.js.map +1 -0
- package/dist/src/titleBarState.d.ts +43 -0
- package/dist/src/titleBarState.d.ts.map +1 -0
- package/dist/src/titleBarState.js +77 -0
- package/dist/src/titleBarState.js.map +1 -0
- package/dist/src/useContextMenu.d.ts +113 -0
- package/dist/src/useContextMenu.d.ts.map +1 -0
- package/dist/src/useContextMenu.js +109 -0
- package/dist/src/useContextMenu.js.map +1 -0
- package/dist/src/useDialog.d.ts +98 -0
- package/dist/src/useDialog.d.ts.map +1 -0
- package/dist/src/useDialog.js +112 -0
- package/dist/src/useDialog.js.map +1 -0
- package/dist/src/useDisplays.d.ts +70 -0
- package/dist/src/useDisplays.d.ts.map +1 -0
- package/dist/src/useDisplays.js +118 -0
- package/dist/src/useDisplays.js.map +1 -0
- package/dist/src/useHandledKeys.d.ts +38 -0
- package/dist/src/useHandledKeys.d.ts.map +1 -0
- package/dist/src/useHandledKeys.js +70 -0
- package/dist/src/useHandledKeys.js.map +1 -0
- package/dist/src/useWindow.d.ts +140 -0
- package/dist/src/useWindow.d.ts.map +1 -0
- package/dist/src/useWindow.js +233 -0
- package/dist/src/useWindow.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/native/CMakeLists.txt +355 -0
- package/native/bootstrap.sh +613 -0
- package/native/cmake/CompilerFlags.cmake +49 -0
- package/native/cmake/Expo.cmake +125 -0
- package/native/cmake/ReactNativeCore.cmake +612 -0
- package/native/cmake/Reanimated.cmake +108 -0
- package/native/cmake/Skia.cmake +379 -0
- package/native/cmake/ThirdParty.cmake +290 -0
- package/native/cmake/Worklets.cmake +67 -0
- package/native/cmake/codegen/CMakeLists.txt +32 -0
- package/native/core/AppIdentity.cpp +85 -0
- package/native/core/AppIdentity.h +59 -0
- package/native/core/AppPaths.cpp +96 -0
- package/native/core/AppPaths.h +53 -0
- package/native/core/AppearanceModule.cpp +60 -0
- package/native/core/AppearanceModule.h +40 -0
- package/native/core/Backface.h +59 -0
- package/native/core/BlobModule.cpp +283 -0
- package/native/core/BlobModule.h +76 -0
- package/native/core/BlobRegistry.cpp +75 -0
- package/native/core/BlobRegistry.h +44 -0
- package/native/core/ColorScheme.cpp +105 -0
- package/native/core/ColorScheme.h +59 -0
- package/native/core/ComponentRegistry.h +30 -0
- package/native/core/ControlMetrics.h +37 -0
- package/native/core/CoreModules.cpp +592 -0
- package/native/core/CoreModules.h +308 -0
- package/native/core/DebuggingOverlay.cpp +106 -0
- package/native/core/DebuggingOverlay.h +65 -0
- package/native/core/DesktopControls.cpp +232 -0
- package/native/core/DesktopControls.h +170 -0
- package/native/core/DevBundle.cpp +108 -0
- package/native/core/DevBundle.h +69 -0
- package/native/core/DevMenu.cpp +99 -0
- package/native/core/DevMenu.h +75 -0
- package/native/core/DialogModule.cpp +150 -0
- package/native/core/DialogModule.h +51 -0
- package/native/core/DragAndDrop.cpp +45 -0
- package/native/core/DragAndDrop.h +225 -0
- package/native/core/ExpoImageComponent.cpp +79 -0
- package/native/core/ExpoImageComponent.h +80 -0
- package/native/core/ExpoModules.cpp +415 -0
- package/native/core/ExpoModules.h +115 -0
- package/native/core/ExpoRuntime.cpp +366 -0
- package/native/core/ExpoRuntime.h +42 -0
- package/native/core/FocusRing.h +36 -0
- package/native/core/FontRegistry.h +51 -0
- package/native/core/GestureHandlerModule.cpp +136 -0
- package/native/core/GestureHandlerModule.h +71 -0
- package/native/core/Gestures.cpp +533 -0
- package/native/core/Gestures.h +145 -0
- package/native/core/HoverTracker.cpp +69 -0
- package/native/core/HoverTracker.h +109 -0
- package/native/core/HttpClient.cpp +282 -0
- package/native/core/ImageBytes.cpp +205 -0
- package/native/core/ImageBytes.h +29 -0
- package/native/core/ImageCache.cpp +51 -0
- package/native/core/ImageCache.h +89 -0
- package/native/core/JsRuntimeAccess.cpp +70 -0
- package/native/core/JsRuntimeAccess.h +60 -0
- package/native/core/JsiPromise.h +51 -0
- package/native/core/KeyEvents.cpp +116 -0
- package/native/core/KeyEvents.h +144 -0
- package/native/core/LogBoxSurface.cpp +46 -0
- package/native/core/LogBoxSurface.h +68 -0
- package/native/core/MenuModel.h +117 -0
- package/native/core/MenuModule.cpp +209 -0
- package/native/core/MenuModule.h +66 -0
- package/native/core/MountingWalk.h +524 -0
- package/native/core/PackageModules.cpp.in +25 -0
- package/native/core/PackageModules.h +50 -0
- package/native/core/PlatformConstantsModule.cpp +63 -0
- package/native/core/PlatformConstantsModule.h +64 -0
- package/native/core/PlatformServices.h +213 -0
- package/native/core/PointerButtons.h +63 -0
- package/native/core/PullToRefresh.cpp +57 -0
- package/native/core/PullToRefresh.h +73 -0
- package/native/core/ReanimatedCompat.h +47 -0
- package/native/core/ReanimatedModule.cpp +203 -0
- package/native/core/ReanimatedModule.h +55 -0
- package/native/core/ScrollAnimation.cpp +59 -0
- package/native/core/ScrollAnimation.h +70 -0
- package/native/core/ScrollBounds.cpp +26 -0
- package/native/core/ScrollBounds.h +68 -0
- package/native/core/ScrollIndicator.cpp +50 -0
- package/native/core/ScrollIndicator.h +69 -0
- package/native/core/ScrollMomentum.cpp +71 -0
- package/native/core/ScrollMomentum.h +73 -0
- package/native/core/ScrollSnap.cpp +123 -0
- package/native/core/ScrollSnap.h +80 -0
- package/native/core/ShareFallback.cpp +101 -0
- package/native/core/ShareFallback.h +45 -0
- package/native/core/SkiaPictureViewComponent.cpp +11 -0
- package/native/core/SkiaPictureViewComponent.h +47 -0
- package/native/core/SourceCodeModule.cpp +55 -0
- package/native/core/SourceCodeModule.h +53 -0
- package/native/core/StatusBarModule.cpp +23 -0
- package/native/core/StatusBarModule.h +42 -0
- package/native/core/TestDialog.cpp +148 -0
- package/native/core/TestDialog.h +96 -0
- package/native/core/TestKeys.cpp +78 -0
- package/native/core/TestKeys.h +50 -0
- package/native/core/TestQuitFile.cpp +33 -0
- package/native/core/TestQuitFile.h +60 -0
- package/native/core/TestSettle.h +192 -0
- package/native/core/TitleBarRegions.h +31 -0
- package/native/core/TurboModuleProxy.cpp +51 -0
- package/native/core/TurboModuleProxy.h +46 -0
- package/native/core/UIManagerAccess.cpp +43 -0
- package/native/core/UIManagerAccess.h +43 -0
- package/native/core/WindowBoundsCache.cpp +319 -0
- package/native/core/WindowControl.h +235 -0
- package/native/core/WindowHost.h +158 -0
- package/native/core/WindowMethods.cpp +167 -0
- package/native/core/WindowMethods.h +84 -0
- package/native/core/WindowsModule.cpp +448 -0
- package/native/core/WindowsModule.h +133 -0
- package/native/core/WorkletsModule.cpp +199 -0
- package/native/core/WorkletsModule.h +57 -0
- package/native/core/portability_probe.cpp +210 -0
- package/native/tests/EventRecorder.h +124 -0
- package/native/tests/TestHarness.cpp +109 -0
- package/native/tests/TestHarness.h +89 -0
- package/native/tests/TreeDump.h +49 -0
- package/native/tests/test_app_identity.cpp +114 -0
- package/native/tests/test_app_paths.cpp +48 -0
- package/native/tests/test_appearance.cpp +107 -0
- package/native/tests/test_backface.cpp +79 -0
- package/native/tests/test_blobs.cpp +157 -0
- package/native/tests/test_controls.cpp +185 -0
- package/native/tests/test_devbundle.cpp +103 -0
- package/native/tests/test_drag_and_drop.cpp +143 -0
- package/native/tests/test_gestures.cpp +331 -0
- package/native/tests/test_hover.cpp +92 -0
- package/native/tests/test_image_cache.cpp +109 -0
- package/native/tests/test_js_runtime_access.cpp +137 -0
- package/native/tests/test_key_events.cpp +235 -0
- package/native/tests/test_momentum.cpp +138 -0
- package/native/tests/test_quit_file.cpp +104 -0
- package/native/tests/test_scroll_animation.cpp +120 -0
- package/native/tests/test_scroll_bounds.cpp +66 -0
- package/native/tests/test_scroll_indicator.cpp +149 -0
- package/native/tests/test_scroll_snap.cpp +112 -0
- package/native/tests/test_settle.cpp +115 -0
- package/native/tests/test_share.cpp +75 -0
- package/native/tests/test_sourcecode.cpp +62 -0
- package/native/tests/test_window_close.cpp +119 -0
- package/native/tests/test_window_limits.cpp +123 -0
- package/package.json +43 -0
- package/react-native.config.js +86 -0
- package/supported-versions.json +66 -0
|
@@ -0,0 +1,671 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Metro configuration for this project's desktop platforms.
|
|
4
|
+
*
|
|
5
|
+
* An out-of-tree React Native platform has to do two things to Metro, and the
|
|
6
|
+
* second is the one that is not obvious.
|
|
7
|
+
*
|
|
8
|
+
* First, the platform has to be one Metro knows about, so that
|
|
9
|
+
* `Button.macos.js` wins over `Button.js` the way `Button.android.js` would.
|
|
10
|
+
*
|
|
11
|
+
* Second, some of React Native's own modules cannot work on a platform it has
|
|
12
|
+
* never heard of. There are three kinds, and each needs different handling:
|
|
13
|
+
*
|
|
14
|
+
* 1. **Self-importing shims.** React Native ships a family of files whose
|
|
15
|
+
* entire body is `import X from './X'; export default X;`, each marked
|
|
16
|
+
* with a note about "backwards compatibility of subpath (deep) imports".
|
|
17
|
+
* They exist so `react-native/Libraries/Image/Image` keeps working, and
|
|
18
|
+
* they rely on a platform-specific sibling winning the resolution. Bundle
|
|
19
|
+
* for one of these platforms and each resolves to *itself*, exports
|
|
20
|
+
* undefined, and kills whatever touches it -- as `Platform.constants`
|
|
21
|
+
* being undefined, or a view config being undefined, or a component being
|
|
22
|
+
* undefined.
|
|
23
|
+
*
|
|
24
|
+
* 2. **Modules with no neutral fallback at all**, which do not resolve, so
|
|
25
|
+
* there is no resolution to rewrite -- only a failure to intercept.
|
|
26
|
+
*
|
|
27
|
+
* 3. **Modules this project genuinely implements differently**, which is
|
|
28
|
+
* `Platform` and `TextInput`.
|
|
29
|
+
*
|
|
30
|
+
* React Native for Windows solves all of this with a whole override system and
|
|
31
|
+
* a fork of every file it replaces. This is the same idea at the smallest size
|
|
32
|
+
* that works.
|
|
33
|
+
*
|
|
34
|
+
* None of the three kinds is Linux-specific, which is the point of this file's
|
|
35
|
+
* shape: the answers are identical for linux, macos and windows, and only
|
|
36
|
+
* `Platform` differs, by one string. Anything that has to be written per
|
|
37
|
+
* platform is a `.linux.js` / `.macos.js` / `.windows.js` file in
|
|
38
|
+
* `src/overrides`, and the tables below name it.
|
|
39
|
+
*
|
|
40
|
+
* Usage, in an app's metro.config.js:
|
|
41
|
+
*
|
|
42
|
+
* const {withDesktopPlatforms} = require('basalt-core/metro-config');
|
|
43
|
+
* module.exports = withDesktopPlatforms(config);
|
|
44
|
+
*
|
|
45
|
+
* @format
|
|
46
|
+
*/
|
|
47
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
48
|
+
if (k2 === undefined) k2 = k;
|
|
49
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
50
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
51
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
52
|
+
}
|
|
53
|
+
Object.defineProperty(o, k2, desc);
|
|
54
|
+
}) : (function(o, m, k, k2) {
|
|
55
|
+
if (k2 === undefined) k2 = k;
|
|
56
|
+
o[k2] = m[k];
|
|
57
|
+
}));
|
|
58
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
59
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
60
|
+
}) : function(o, v) {
|
|
61
|
+
o["default"] = v;
|
|
62
|
+
});
|
|
63
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
64
|
+
var ownKeys = function(o) {
|
|
65
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
66
|
+
var ar = [];
|
|
67
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
68
|
+
return ar;
|
|
69
|
+
};
|
|
70
|
+
return ownKeys(o);
|
|
71
|
+
};
|
|
72
|
+
return function (mod) {
|
|
73
|
+
if (mod && mod.__esModule) return mod;
|
|
74
|
+
var result = {};
|
|
75
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
76
|
+
__setModuleDefault(result, mod);
|
|
77
|
+
return result;
|
|
78
|
+
};
|
|
79
|
+
})();
|
|
80
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
81
|
+
exports.APP_ID_PREFIX = exports.MISSING_MODULES = exports.PLATFORM_OVERRIDES = exports.SELF_IMPORTING_SHIMS = exports.DESKTOP_PLATFORMS = void 0;
|
|
82
|
+
exports.appIdFor = appIdFor;
|
|
83
|
+
exports.withDesktopPlatforms = withDesktopPlatforms;
|
|
84
|
+
exports.withLinuxPlatform = withLinuxPlatform;
|
|
85
|
+
const fs = __importStar(require("node:fs"));
|
|
86
|
+
const path = __importStar(require("node:path"));
|
|
87
|
+
const OVERRIDE_DIR = path.join(__dirname, 'src', 'overrides');
|
|
88
|
+
/**
|
|
89
|
+
* The platforms this package can bundle for.
|
|
90
|
+
*
|
|
91
|
+
* `macos` and `windows` deliberately match the names react-native-macos and
|
|
92
|
+
* react-native-windows use. A library that ships `Button.macos.js` for those
|
|
93
|
+
* forks resolves correctly here without knowing this project exists, and a
|
|
94
|
+
* library that does not is no worse off. Picking different names would have
|
|
95
|
+
* bought nothing and cost that.
|
|
96
|
+
*/
|
|
97
|
+
exports.DESKTOP_PLATFORMS = ['linux', 'macos', 'windows'];
|
|
98
|
+
/**
|
|
99
|
+
* Kind 1: React Native's self-importing deep-import shims.
|
|
100
|
+
*
|
|
101
|
+
* Each is answered with its own `.android.js` sibling rather than a file of
|
|
102
|
+
* ours. That is deliberate: these platforms report `PlatformConstantsAndroid`
|
|
103
|
+
* from C++, share ReactCommon's prop parsing, and drive the same components
|
|
104
|
+
* Android's JavaScript drives, so Android's implementation is the one that
|
|
105
|
+
* matches what is actually implemented here. Copying them would mean nine forks
|
|
106
|
+
* drifting silently from upstream.
|
|
107
|
+
*
|
|
108
|
+
* Found with:
|
|
109
|
+
*
|
|
110
|
+
* grep -rl 'backwards compatibility of subpath (deep) imports' Libraries src
|
|
111
|
+
*
|
|
112
|
+
* Spelled out rather than detected, so a new shim upstream produces an honest
|
|
113
|
+
* failure here rather than a silent redirect to Android.
|
|
114
|
+
*/
|
|
115
|
+
exports.SELF_IMPORTING_SHIMS = [
|
|
116
|
+
path.join('Libraries', 'Alert', 'RCTAlertManager.js'),
|
|
117
|
+
path.join('Libraries', 'Components', 'AccessibilityInfo', 'legacySendAccessibilityEvent.js'),
|
|
118
|
+
path.join('Libraries', 'Components', 'DrawerAndroid', 'DrawerLayoutAndroid.js'),
|
|
119
|
+
path.join('Libraries', 'Components', 'ToastAndroid', 'ToastAndroid.js'),
|
|
120
|
+
path.join('Libraries', 'Image', 'Image.js'),
|
|
121
|
+
path.join('Libraries', 'Network', 'RCTNetworking.js'),
|
|
122
|
+
path.join('Libraries', 'StyleSheet', 'PlatformColorValueTypes.js'),
|
|
123
|
+
path.join('Libraries', 'Utilities', 'BackHandler.js'),
|
|
124
|
+
// Platform.js belongs to this family too, but is answered by kind 3 below.
|
|
125
|
+
];
|
|
126
|
+
/**
|
|
127
|
+
* How this package's own overrides reach React Native's internals.
|
|
128
|
+
*
|
|
129
|
+
* A platform implementation has to import things React Native does not export:
|
|
130
|
+
* `NativeAlertManager`, `PolyfillFunctions`, the upstream `ScrollView` an
|
|
131
|
+
* override wraps. Written as `react-native/Libraries/...` that costs two
|
|
132
|
+
* warnings in every app that uses this package, in every bundle, for every
|
|
133
|
+
* import -- one from `@react-native/babel-preset`'s warn-on-deep-imports
|
|
134
|
+
* plugin, and one from Metro when the subpath is not in React Native's
|
|
135
|
+
* `exports`. Neither says anything a reader can act on: the deep import is
|
|
136
|
+
* deliberate, and there is no shallower path to the same file.
|
|
137
|
+
*
|
|
138
|
+
* So the overrides spell it this way instead, and the resolver below turns the
|
|
139
|
+
* prefix into an absolute path inside the React Native package. Babel's plugin
|
|
140
|
+
* looks at the literal specifier and this one does not begin with
|
|
141
|
+
* `react-native/`; Metro resolves an absolute path without consulting
|
|
142
|
+
* `exports`, and with its usual extension and platform machinery still
|
|
143
|
+
* applying. What is imported is exactly the same file.
|
|
144
|
+
*
|
|
145
|
+
* It is not a way of pretending the imports are not deep. `docs/` and the
|
|
146
|
+
* override headers say which internals this platform depends on; this only
|
|
147
|
+
* stops the tooling from saying it once per import per bundle.
|
|
148
|
+
*/
|
|
149
|
+
const UPSTREAM_PREFIX = 'basalt-core/upstream/';
|
|
150
|
+
/**
|
|
151
|
+
* Upstream files that are not in every supported React Native, and what to
|
|
152
|
+
* use instead where they are absent.
|
|
153
|
+
*
|
|
154
|
+
* `supported-versions.json` lists 0.86 and 0.87, and the abort API moved
|
|
155
|
+
* between them: 0.86's own `setUpXHR` polyfills `AbortController` from the
|
|
156
|
+
* `abort-controller` npm package, and 0.87 brought an implementation into
|
|
157
|
+
* React Native's source. An override written against the newer one therefore
|
|
158
|
+
* fails to *resolve* on the older -- a bundling error, not a runtime one, so
|
|
159
|
+
* no amount of try/catch in the override helps.
|
|
160
|
+
*
|
|
161
|
+
* Keyed by the path after the prefix, and consulted only when the upstream
|
|
162
|
+
* file is really not there, so the newer layout is what is used wherever it
|
|
163
|
+
* exists. The exports differ too; see src/overrides/setUpXHR.ts.
|
|
164
|
+
*/
|
|
165
|
+
const UPSTREAM_FALLBACKS = new Map([
|
|
166
|
+
['src/private/webapis/dom/abort-api/AbortController', 'abort-controller/dist/abort-controller'],
|
|
167
|
+
['src/private/webapis/dom/abort-api/AbortSignal', 'abort-controller/dist/abort-controller'],
|
|
168
|
+
]);
|
|
169
|
+
/**
|
|
170
|
+
* Kind 3: modules this project implements itself. Checked before the shim list,
|
|
171
|
+
* so `Platform` gets ours rather than Android's.
|
|
172
|
+
*
|
|
173
|
+
* A replacement is either a path, when every platform shares it, or a function
|
|
174
|
+
* of the platform when they do not. Only `Platform` needs the second form, and
|
|
175
|
+
* the one-line files it points at exist so that the difference between the
|
|
176
|
+
* platforms stays exactly one string. See src/overrides/createPlatform.js.
|
|
177
|
+
*/
|
|
178
|
+
exports.PLATFORM_OVERRIDES = [
|
|
179
|
+
[
|
|
180
|
+
// React Native's own file plus three props it registers and never declares:
|
|
181
|
+
// `onPointerDown`, `onPointerUp` and `onPointerCancel` are in
|
|
182
|
+
// `bubblingEventTypes` and parsed by ReactCommon, but missing from
|
|
183
|
+
// `validAttributes` -- so React never sends them and the event is dropped
|
|
184
|
+
// in C++. It was in SELF_IMPORTING_SHIMS until a right-click needed one.
|
|
185
|
+
path.join('Libraries', 'NativeComponent', 'BaseViewConfig.js'),
|
|
186
|
+
path.join(OVERRIDE_DIR, 'BaseViewConfig.js'),
|
|
187
|
+
],
|
|
188
|
+
[
|
|
189
|
+
path.join('Libraries', 'Utilities', 'Platform.js'),
|
|
190
|
+
(platform) => path.join(OVERRIDE_DIR, `Platform.${platform}.js`),
|
|
191
|
+
],
|
|
192
|
+
[
|
|
193
|
+
// Not a shim: React Native's TextInput.js branches on `Platform.OS` being
|
|
194
|
+
// exactly 'android' or 'ios' and renders undefined on anything else. See
|
|
195
|
+
// the header of the replacement for why it is a rewrite rather than a
|
|
196
|
+
// third branch.
|
|
197
|
+
path.join('Libraries', 'Components', 'TextInput', 'TextInput.js'),
|
|
198
|
+
path.join(OVERRIDE_DIR, 'TextInput.js'),
|
|
199
|
+
],
|
|
200
|
+
[
|
|
201
|
+
// Also not a shim, and the same failure: `Alert.alert()` branches on
|
|
202
|
+
// `Platform.OS` being exactly 'ios' or 'android' with no else, so on a
|
|
203
|
+
// desktop it returns having done nothing -- no dialog, no error. The
|
|
204
|
+
// AlertManager module has been there since phase 32 and was never reached.
|
|
205
|
+
path.join('Libraries', 'Alert', 'Alert.js'),
|
|
206
|
+
path.join(OVERRIDE_DIR, 'Alert.js'),
|
|
207
|
+
],
|
|
208
|
+
[
|
|
209
|
+
// Also not a shim. React Native's `Share.share()` branches on `Platform.OS`
|
|
210
|
+
// being exactly 'android' or 'ios' and rejects with "Unsupported platform"
|
|
211
|
+
// otherwise -- so the native module is never reached and implementing one
|
|
212
|
+
// changes nothing. See the header of the replacement.
|
|
213
|
+
path.join('Libraries', 'Share', 'Share.js'),
|
|
214
|
+
path.join(OVERRIDE_DIR, 'Share.js'),
|
|
215
|
+
],
|
|
216
|
+
[
|
|
217
|
+
// React Native's own file, plus the listener the host's developer menu
|
|
218
|
+
// needs: `DevSettings.reload()` is the only way into ReactHost's private
|
|
219
|
+
// reload, and there is no way to call it from C++. It runs from
|
|
220
|
+
// InitializeCore in every development bundle, so an app that imports
|
|
221
|
+
// nothing from this package still gets a working dev menu. See its header.
|
|
222
|
+
path.join('Libraries', 'Core', 'setUpDeveloperTools.js'),
|
|
223
|
+
path.join(OVERRIDE_DIR, 'setUpDeveloperTools.js'),
|
|
224
|
+
],
|
|
225
|
+
[
|
|
226
|
+
// Also not a shim: `RefreshControl.js` branches on `Platform.OS === 'ios'`
|
|
227
|
+
// with an `else` that renders Android's AndroidSwipeRefreshLayout, whose
|
|
228
|
+
// shadow node needs fbjni and which no desktop registers.
|
|
229
|
+
path.join('Libraries', 'Components', 'RefreshControl', 'RefreshControl.js'),
|
|
230
|
+
path.join(OVERRIDE_DIR, 'RefreshControl.js'),
|
|
231
|
+
],
|
|
232
|
+
[
|
|
233
|
+
// The one wrapper in this table rather than a rewrite. `ScrollView.render`
|
|
234
|
+
// places `refreshControl` in an `if (ios) ... else if (android)` with no
|
|
235
|
+
// `else`, so on a desktop the prop is dropped and the control never
|
|
236
|
+
// mounts. The replacement is React Native's own ScrollView with the child
|
|
237
|
+
// put back; see its header.
|
|
238
|
+
path.join('Libraries', 'Components', 'ScrollView', 'ScrollView.js'),
|
|
239
|
+
path.join(OVERRIDE_DIR, 'ScrollView.js'),
|
|
240
|
+
],
|
|
241
|
+
[
|
|
242
|
+
// Not a shim either: React Native's own View, with the keyboard props
|
|
243
|
+
// react-native-macos has. An app that declares a shortcut the way that
|
|
244
|
+
// platform does has them dropped in JavaScript otherwise, silently. See the
|
|
245
|
+
// override's header, including why a view without them renders upstream's
|
|
246
|
+
// directly rather than paying for hooks it does not use.
|
|
247
|
+
path.join('Libraries', 'Components', 'View', 'View.js'),
|
|
248
|
+
path.join(OVERRIDE_DIR, 'View.js'),
|
|
249
|
+
],
|
|
250
|
+
[
|
|
251
|
+
// Also not a shim. `fetch` is broken on this platform without it: every
|
|
252
|
+
// request asks for a blob response, which ReactCxxPlatform's
|
|
253
|
+
// NetworkingModule cannot produce, so the response getter throws before
|
|
254
|
+
// whatwg-fetch builds a Response. The replacement is React Native's own
|
|
255
|
+
// file with the blob response type routed through base64; see its header.
|
|
256
|
+
path.join('Libraries', 'Core', 'setUpXHR.js'),
|
|
257
|
+
path.join(OVERRIDE_DIR, 'setUpXHR.js'),
|
|
258
|
+
],
|
|
259
|
+
];
|
|
260
|
+
/**
|
|
261
|
+
* Kind 2: modules React Native ships only as `.android.js` and `.ios.js`, with
|
|
262
|
+
* no neutral file to resolve to. Keyed without an extension, because a request
|
|
263
|
+
* that fails to resolve is only known by its extensionless path.
|
|
264
|
+
*/
|
|
265
|
+
exports.MISSING_MODULES = [
|
|
266
|
+
[
|
|
267
|
+
path.join('rndevtools', 'ReactDevToolsSettingsManager'),
|
|
268
|
+
path.join(OVERRIDE_DIR, 'ReactDevToolsSettingsManager.js'),
|
|
269
|
+
],
|
|
270
|
+
];
|
|
271
|
+
/**
|
|
272
|
+
* Kind 4: a *library* that ships only `.ios` and `.android` files.
|
|
273
|
+
*
|
|
274
|
+
* `react-native-screens` has `TabsScreen.ios.tsx`, `TabsScreen.android.tsx` and
|
|
275
|
+
* `TabsScreen.web.tsx`, and an `index.ts` that says `from './TabsScreen'`.
|
|
276
|
+
* Resolution fails, and the whole bundle fails with it -- one component nothing
|
|
277
|
+
* in the app renders takes down a build that would otherwise have worked. Every
|
|
278
|
+
* library that has never heard of this platform is a candidate, which is all of
|
|
279
|
+
* them, so this cannot be a list of names.
|
|
280
|
+
*
|
|
281
|
+
* So a resolution that fails for a desktop platform is retried as another
|
|
282
|
+
* platform, in this order, and the first that resolves wins. The build gets a
|
|
283
|
+
* real implementation of the module rather than failing; if that implementation
|
|
284
|
+
* needs a native module this platform does not have, it fails at runtime like
|
|
285
|
+
* any other unsupported library, which is a much better place to fail.
|
|
286
|
+
*
|
|
287
|
+
* Android first, for the same reason `SELF_IMPORTING_SHIMS` are answered with
|
|
288
|
+
* their `.android.js` sibling: these platforms report `PlatformConstantsAndroid`
|
|
289
|
+
* and share ReactCommon's prop parsing. One order for all three desktops rather
|
|
290
|
+
* than a per-platform guess, because two desktops resolving *different*
|
|
291
|
+
* implementations of the same library is the one outcome worse than either.
|
|
292
|
+
*
|
|
293
|
+
* Set `platformFallbacks: []` to turn this off and get the resolution error.
|
|
294
|
+
*/
|
|
295
|
+
const PLATFORM_FALLBACKS = ['android', 'ios'];
|
|
296
|
+
/**
|
|
297
|
+
* How a host tells the dev server which desktop it is.
|
|
298
|
+
*
|
|
299
|
+
* ReactCxxPlatform's DevServerHelper builds its bundle URL from
|
|
300
|
+
* `constexpr DEFAULT_PLATFORM = "android"`, with no hook and no setting, so
|
|
301
|
+
* every desktop host asks Metro for an android bundle. Left alone, an app would
|
|
302
|
+
* be `Platform.OS === 'android'` under Fast Refresh and its real value in a
|
|
303
|
+
* release build, which is a far worse trap than either on its own.
|
|
304
|
+
*
|
|
305
|
+
* The request is therefore corrected on arrival, and the only thing in it that
|
|
306
|
+
* a host controls is `app=`, which comes from `ReactInstanceConfig::appId` and
|
|
307
|
+
* which Metro itself ignores. So the hosts set that to
|
|
308
|
+
* `basalt-<platform>` and this reads it back.
|
|
309
|
+
*
|
|
310
|
+
* It is a workaround and it should not have to exist. The fix is a `platform`
|
|
311
|
+
* field on ReactInstanceConfig, upstream.
|
|
312
|
+
*/
|
|
313
|
+
exports.APP_ID_PREFIX = 'basalt-';
|
|
314
|
+
function appIdFor(platform) {
|
|
315
|
+
return exports.APP_ID_PREFIX + platform;
|
|
316
|
+
}
|
|
317
|
+
// Whether `parent` contains `child`, or is it.
|
|
318
|
+
//
|
|
319
|
+
// Not `child.startsWith(parent)`. A React Native checkout at
|
|
320
|
+
// `/src/react-native` is a string prefix of this package at
|
|
321
|
+
// `/src/basalt-core/packages/basalt-core`, so the naive test
|
|
322
|
+
// reports that the package is already being watched when it is not, and Metro
|
|
323
|
+
// then refuses to read the very files this plugin hands it. Which is exactly
|
|
324
|
+
// the layout this repository is developed in.
|
|
325
|
+
function contains(parent, child) {
|
|
326
|
+
const relative = path.relative(parent, child);
|
|
327
|
+
return relative === '' || (!relative.startsWith('..') && !path.isAbsolute(relative));
|
|
328
|
+
}
|
|
329
|
+
// Matched on the tail of a path rather than an absolute one: the React Native
|
|
330
|
+
// checkout can be a node_modules copy, a sibling clone or a workspace symlink.
|
|
331
|
+
function matchTail(filePath, table, platform) {
|
|
332
|
+
for (const [tail, replacement] of table) {
|
|
333
|
+
if (filePath.endsWith(tail)) {
|
|
334
|
+
if (typeof replacement !== 'function') {
|
|
335
|
+
return replacement;
|
|
336
|
+
}
|
|
337
|
+
// A replacement chosen by platform cannot be chosen without one. Metro
|
|
338
|
+
// resolves with a null platform for its own internal requests, and the
|
|
339
|
+
// honest answer there is "this override does not apply" rather than a
|
|
340
|
+
// path with `Platform.null.js` in it.
|
|
341
|
+
return platform == null ? null : replacement(platform);
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
return null;
|
|
345
|
+
}
|
|
346
|
+
/**
|
|
347
|
+
* Where React Native is, as an absolute path.
|
|
348
|
+
*
|
|
349
|
+
* Asked of Metro rather than of Node. `require.resolve` answers from this
|
|
350
|
+
* file's own node_modules, which in this repository -- and in any monorepo or
|
|
351
|
+
* linked checkout -- is not where the copy being bundled lives; Metro already
|
|
352
|
+
* knows, because it has `extraNodeModules` and `nodeModulesPaths` and the
|
|
353
|
+
* app's root. Resolving the package's own entry point rather than a file
|
|
354
|
+
* inside it also keeps this out of the `exports` check, which is half of what
|
|
355
|
+
* UPSTREAM_PREFIX exists to avoid.
|
|
356
|
+
*/
|
|
357
|
+
let reactNativeRootCache = null;
|
|
358
|
+
function reactNativeRoot(resolve) {
|
|
359
|
+
if (reactNativeRootCache == null) {
|
|
360
|
+
reactNativeRootCache = path.dirname(resolve().filePath);
|
|
361
|
+
}
|
|
362
|
+
return reactNativeRootCache;
|
|
363
|
+
}
|
|
364
|
+
function replacementFor(filePath, platform) {
|
|
365
|
+
const own = matchTail(filePath, exports.PLATFORM_OVERRIDES, platform);
|
|
366
|
+
if (own != null) {
|
|
367
|
+
return own;
|
|
368
|
+
}
|
|
369
|
+
for (const shim of exports.SELF_IMPORTING_SHIMS) {
|
|
370
|
+
if (filePath.endsWith(shim)) {
|
|
371
|
+
// The sibling beside the shim, wherever that directory happens to be.
|
|
372
|
+
return filePath.replace(/\.js$/, '.android.js');
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
return null;
|
|
376
|
+
}
|
|
377
|
+
/**
|
|
378
|
+
* Rewrites a dev-server bundle request that says `android` to the desktop
|
|
379
|
+
* platform that actually asked for it. See APP_ID_PREFIX above.
|
|
380
|
+
*
|
|
381
|
+
* `fallback` is used when the request carries no `app=` this plugin recognises,
|
|
382
|
+
* which is what an older host or a hand-typed URL looks like.
|
|
383
|
+
*/
|
|
384
|
+
function correctBundlePlatform(url, platforms, fallback) {
|
|
385
|
+
if (!/\.(bundle|map)\b/.test(url)) {
|
|
386
|
+
return url;
|
|
387
|
+
}
|
|
388
|
+
if (!/([?&]platform=)android(&|$)/.test(url)) {
|
|
389
|
+
return url;
|
|
390
|
+
}
|
|
391
|
+
const app = /[?&]app=([^&]*)/.exec(url);
|
|
392
|
+
let target = fallback;
|
|
393
|
+
if (app != null && app[1].startsWith(exports.APP_ID_PREFIX)) {
|
|
394
|
+
const named = app[1].slice(exports.APP_ID_PREFIX.length);
|
|
395
|
+
if (platforms.includes(named)) {
|
|
396
|
+
target = named;
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
if (target == null) {
|
|
400
|
+
return url;
|
|
401
|
+
}
|
|
402
|
+
return url.replace(/([?&]platform=)android(&|$)/, `$1${target}$2`);
|
|
403
|
+
}
|
|
404
|
+
/**
|
|
405
|
+
* Adds this project's desktop platforms to Metro and installs the overrides.
|
|
406
|
+
*
|
|
407
|
+
* Composes with an existing `resolveRequest` and `rewriteRequestUrl` rather
|
|
408
|
+
* than replacing them, so an app that already has either keeps it.
|
|
409
|
+
*
|
|
410
|
+
* Options:
|
|
411
|
+
*
|
|
412
|
+
* platforms which of linux/macos/windows to enable. All of them by
|
|
413
|
+
* default: bundling is per-platform anyway, so there is
|
|
414
|
+
* nothing to be gained by making an app declare a subset.
|
|
415
|
+
* devServerPlatform what to assume a dev-server request is for when it does
|
|
416
|
+
* not say. Defaults to the first enabled platform. A host
|
|
417
|
+
* built from this repo always says, so this only matters
|
|
418
|
+
* for a URL typed by hand.
|
|
419
|
+
* platformFallbacks which platforms to retry a failed resolution as, in
|
|
420
|
+
* order. See PLATFORM_FALLBACKS. `[]` disables it.
|
|
421
|
+
*/
|
|
422
|
+
/** This package, by the name an app imports it as. */
|
|
423
|
+
const PACKAGE_NAME = 'basalt-core';
|
|
424
|
+
/**
|
|
425
|
+
* The capability packages, which an app installs only if it wants them.
|
|
426
|
+
*
|
|
427
|
+
* Named rather than discovered: a list is something a person can read, and the
|
|
428
|
+
* alternative -- scanning the app's dependencies for a prefix -- would also pick
|
|
429
|
+
* up the host packages, which are not imported from JavaScript at all.
|
|
430
|
+
*/
|
|
431
|
+
const CAPABILITY_PACKAGES = ['basalt-subprocess'];
|
|
432
|
+
/** Our own package a request names, or null. Matches `name` and `name/subpath`. */
|
|
433
|
+
function ownedPackage(request) {
|
|
434
|
+
for (const name of [PACKAGE_NAME, ...CAPABILITY_PACKAGES]) {
|
|
435
|
+
if (request === name || request.startsWith(`${name}/`)) {
|
|
436
|
+
return name;
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
return null;
|
|
440
|
+
}
|
|
441
|
+
function withDesktopPlatforms(config = {}, options = {}) {
|
|
442
|
+
const enabled = options.platforms ?? exports.DESKTOP_PLATFORMS;
|
|
443
|
+
const devServerPlatform = options.devServerPlatform ?? enabled[0];
|
|
444
|
+
const fallbacks = options.platformFallbacks ?? PLATFORM_FALLBACKS;
|
|
445
|
+
// One line per module, not per import of it: a library resolved through the
|
|
446
|
+
// fallback is usually imported from a dozen places.
|
|
447
|
+
const reported = new Set();
|
|
448
|
+
const resolver = config.resolver ?? {};
|
|
449
|
+
const existingResolveRequest = resolver.resolveRequest;
|
|
450
|
+
const server = config.server ?? {};
|
|
451
|
+
const existingRewrite = server.rewriteRequestUrl;
|
|
452
|
+
const platforms = resolver.platforms ?? [];
|
|
453
|
+
const withDesktop = [
|
|
454
|
+
...enabled.filter(name => !platforms.includes(name)),
|
|
455
|
+
...platforms,
|
|
456
|
+
];
|
|
457
|
+
// Metro will not read a file it is not watching, and this package hands it
|
|
458
|
+
// files -- the overrides above. Inside this repo that is already true, since
|
|
459
|
+
// `packages/` is on watchFolders; for anyone consuming the platform from a
|
|
460
|
+
// linked checkout or another monorepo it is not, and bundling fails with
|
|
461
|
+
// "Failed to get the SHA-1 for" the override rather than anything that names
|
|
462
|
+
// the cause. Found by bundling a real app from another tree.
|
|
463
|
+
const watchFolders = config.watchFolders ?? [];
|
|
464
|
+
const withOverrides = watchFolders.some(folder => contains(folder, __dirname))
|
|
465
|
+
? [...watchFolders]
|
|
466
|
+
: [...watchFolders, __dirname];
|
|
467
|
+
// Metro resolves this package's files by their real path and then looks for
|
|
468
|
+
// their dependencies by walking up from there. Installed normally that lands
|
|
469
|
+
// in the app's node_modules and everything is found. Linked from a checkout,
|
|
470
|
+
// or in a monorepo, it lands in this repository instead, where the app's
|
|
471
|
+
// dependencies are not -- and the failure names @babel/runtime, a helper this
|
|
472
|
+
// package's own compiled output needs, rather than naming the link.
|
|
473
|
+
//
|
|
474
|
+
// Naming the project's node_modules explicitly covers both.
|
|
475
|
+
//
|
|
476
|
+
// Every one from the project root upwards, not only the project's own, which
|
|
477
|
+
// is what Node's own resolution walks. A workspace hoists its dependencies to
|
|
478
|
+
// the repository root, so an app at `apps/desktop` has this package two
|
|
479
|
+
// directories above its own node_modules -- and Metro, unlike Node, only
|
|
480
|
+
// looks where it is told. The symptom is a module that resolves from
|
|
481
|
+
// `src/App.tsx` and not from `modules/something/index.ts`, because the
|
|
482
|
+
// relative walk from the deeper file runs out first. Found in kino, whose
|
|
483
|
+
// local Expo modules sit one directory deeper than its source.
|
|
484
|
+
const projectRoot = config.projectRoot ?? process.cwd();
|
|
485
|
+
const nodeModulesPaths = resolver.nodeModulesPaths ?? [];
|
|
486
|
+
const withProject = [...nodeModulesPaths];
|
|
487
|
+
for (let directory = projectRoot;;) {
|
|
488
|
+
const candidate = path.join(directory, 'node_modules');
|
|
489
|
+
// Only ones that exist: Metro tolerates the rest, and a list of every
|
|
490
|
+
// directory up to `/` is harder to read when something does go wrong.
|
|
491
|
+
if (!withProject.includes(candidate) && fs.existsSync(candidate)) {
|
|
492
|
+
withProject.push(candidate);
|
|
493
|
+
}
|
|
494
|
+
const parent = path.dirname(directory);
|
|
495
|
+
if (parent === directory) {
|
|
496
|
+
break;
|
|
497
|
+
}
|
|
498
|
+
directory = parent;
|
|
499
|
+
}
|
|
500
|
+
// And a direct answer for this package and its capability packages, as a
|
|
501
|
+
// fallback rather than an override.
|
|
502
|
+
//
|
|
503
|
+
// `nodeModulesPaths` above is the general fix and it is not enough on its own:
|
|
504
|
+
// Metro walks up from the *importing file*, and a file nested deeper than the
|
|
505
|
+
// app's source -- `modules/something/index.ts` next to `src/` -- runs out of
|
|
506
|
+
// parents before it reaches a workspace root. `extraNodeModules` is consulted
|
|
507
|
+
// only when the ordinary walk has already failed, so naming these cannot
|
|
508
|
+
// shadow an app's own copy of anything; it rescues the case where there was no
|
|
509
|
+
// answer at all.
|
|
510
|
+
//
|
|
511
|
+
// Resolved from the project root with Node's own algorithm, which follows the
|
|
512
|
+
// symlink a linked checkout leaves and finds nothing when the package is not
|
|
513
|
+
// installed -- in which case it is not named, and the failure stays the one
|
|
514
|
+
// about a missing dependency.
|
|
515
|
+
const linked = {};
|
|
516
|
+
for (const name of [PACKAGE_NAME, ...CAPABILITY_PACKAGES]) {
|
|
517
|
+
try {
|
|
518
|
+
const manifest = require.resolve(`${name}/package.json`, { paths: [projectRoot] });
|
|
519
|
+
linked[name] = path.dirname(manifest);
|
|
520
|
+
}
|
|
521
|
+
catch {
|
|
522
|
+
// Not installed. A capability package usually is not.
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
const extraNodeModules = { ...linked, ...(resolver.extraNodeModules ?? {}) };
|
|
526
|
+
// And watched, for the same reason this package's own directory is: Metro
|
|
527
|
+
// refuses to read a file outside `projectRoot` and `watchFolders`, with
|
|
528
|
+
// "Failed to get the SHA-1 for" the file rather than anything naming the
|
|
529
|
+
// cause. A capability package installed normally is inside the app's
|
|
530
|
+
// node_modules and already covered; one resolved through a link is not.
|
|
531
|
+
for (const directory of Object.values(linked)) {
|
|
532
|
+
if (!withOverrides.some(folder => contains(folder, directory))) {
|
|
533
|
+
withOverrides.push(directory);
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
return {
|
|
537
|
+
...config,
|
|
538
|
+
watchFolders: withOverrides,
|
|
539
|
+
server: {
|
|
540
|
+
...server,
|
|
541
|
+
rewriteRequestUrl: url => correctBundlePlatform(existingRewrite ? existingRewrite(url) : url, enabled, devServerPlatform),
|
|
542
|
+
},
|
|
543
|
+
resolver: {
|
|
544
|
+
...resolver,
|
|
545
|
+
platforms: withDesktop,
|
|
546
|
+
nodeModulesPaths: withProject,
|
|
547
|
+
extraNodeModules,
|
|
548
|
+
resolveRequest: (context, moduleName, platform) => {
|
|
549
|
+
// Metro resolves some of its own requests with no platform at all,
|
|
550
|
+
// and none of those are ours.
|
|
551
|
+
const ours = platform != null && enabled.includes(platform);
|
|
552
|
+
// This package's own overrides reaching React Native's internals. See
|
|
553
|
+
// UPSTREAM_PREFIX: the specifier becomes an absolute path so that
|
|
554
|
+
// neither Babel's deep-import plugin nor Metro's package-exports check
|
|
555
|
+
// has anything to warn about, and resolution is otherwise Metro's.
|
|
556
|
+
// Resolve first, then decide. Rewriting the request instead would mean
|
|
557
|
+
// reimplementing Metro's resolution to know what './Platform' meant
|
|
558
|
+
// from any given file.
|
|
559
|
+
const resolveName = (name, target) => existingResolveRequest
|
|
560
|
+
? existingResolveRequest(context, name, target)
|
|
561
|
+
: context.resolveRequest(context, name, target);
|
|
562
|
+
// This package's own overrides reaching React Native's internals. See
|
|
563
|
+
// UPSTREAM_PREFIX: the specifier becomes an absolute path so that
|
|
564
|
+
// neither Babel's deep-import plugin nor Metro's package-exports check
|
|
565
|
+
// has anything to warn about, and resolution is otherwise Metro's.
|
|
566
|
+
let request = moduleName;
|
|
567
|
+
if (request.startsWith(UPSTREAM_PREFIX)) {
|
|
568
|
+
const root = reactNativeRoot(() => resolveName('react-native', platform));
|
|
569
|
+
const within = request.slice(UPSTREAM_PREFIX.length);
|
|
570
|
+
const absolute = path.join(root, within);
|
|
571
|
+
const fallback = UPSTREAM_FALLBACKS.get(within);
|
|
572
|
+
// Only when the file is genuinely absent: a supported React Native
|
|
573
|
+
// that has it gets it. `.js` because that is what React Native's
|
|
574
|
+
// source is; a directory would have an index.js inside it.
|
|
575
|
+
request =
|
|
576
|
+
fallback != null && !fs.existsSync(`${absolute}.js`) && !fs.existsSync(absolute)
|
|
577
|
+
? fallback
|
|
578
|
+
: absolute;
|
|
579
|
+
}
|
|
580
|
+
// This package and its capability packages, answered here rather than
|
|
581
|
+
// left to whatever resolver the app has.
|
|
582
|
+
//
|
|
583
|
+
// `nodeModulesPaths` and `extraNodeModules` above are the polite way to
|
|
584
|
+
// say where these are, and an app is free to have a resolver that does
|
|
585
|
+
// not read either -- @rnx-kit's does not, and kino uses it. The result
|
|
586
|
+
// was an import of `basalt-core` from a file one directory
|
|
587
|
+
// deeper than the app's source resolving nowhere, with a message about
|
|
588
|
+
// node_modules directories that named neither this package nor the link
|
|
589
|
+
// it was installed through.
|
|
590
|
+
//
|
|
591
|
+
// Answered by Node's own algorithm from the project root, which follows
|
|
592
|
+
// a linked checkout's symlink. Only for *our* names, and only when Node
|
|
593
|
+
// finds them: anything else, including an app that shadows one on
|
|
594
|
+
// purpose, falls through to the resolution it would have had.
|
|
595
|
+
const owned = ownedPackage(request);
|
|
596
|
+
if (owned != null) {
|
|
597
|
+
try {
|
|
598
|
+
return {
|
|
599
|
+
type: 'sourceFile',
|
|
600
|
+
filePath: require.resolve(request, { paths: [projectRoot] }),
|
|
601
|
+
};
|
|
602
|
+
}
|
|
603
|
+
catch {
|
|
604
|
+
// Not installed, or a subpath its exports map does not offer. The
|
|
605
|
+
// app's resolver gets to produce the error, which will name the
|
|
606
|
+
// import rather than this.
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
const resolveAs = (target) => resolveName(request, target);
|
|
610
|
+
let resolution;
|
|
611
|
+
try {
|
|
612
|
+
resolution = resolveAs(platform);
|
|
613
|
+
}
|
|
614
|
+
catch (error) {
|
|
615
|
+
if (!ours) {
|
|
616
|
+
throw error;
|
|
617
|
+
}
|
|
618
|
+
if (moduleName.startsWith('.')) {
|
|
619
|
+
const requested = path.resolve(path.dirname(context.originModulePath ?? ''), moduleName);
|
|
620
|
+
const forMissing = matchTail(requested, exports.MISSING_MODULES, platform);
|
|
621
|
+
if (forMissing != null) {
|
|
622
|
+
return { type: 'sourceFile', filePath: forMissing };
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
// Kind 4. The original error is what gets thrown if every fallback
|
|
626
|
+
// fails too: it names the platform the app actually asked for.
|
|
627
|
+
resolution = null;
|
|
628
|
+
for (const fallback of fallbacks) {
|
|
629
|
+
try {
|
|
630
|
+
resolution = resolveAs(fallback);
|
|
631
|
+
}
|
|
632
|
+
catch {
|
|
633
|
+
continue;
|
|
634
|
+
}
|
|
635
|
+
const key = `${moduleName}\u0000${context.originModulePath ?? ''}`;
|
|
636
|
+
if (!reported.has(key)) {
|
|
637
|
+
reported.add(key);
|
|
638
|
+
console.warn(`basalt: '${moduleName}' has no ${platform} implementation; ` +
|
|
639
|
+
`using its ${fallback} one (from ${context.originModulePath ?? '?'})`);
|
|
640
|
+
}
|
|
641
|
+
break;
|
|
642
|
+
}
|
|
643
|
+
if (resolution == null) {
|
|
644
|
+
throw error;
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
if (!ours || resolution?.type !== 'sourceFile') {
|
|
648
|
+
return resolution;
|
|
649
|
+
}
|
|
650
|
+
const replacement = replacementFor(resolution.filePath, platform);
|
|
651
|
+
if (replacement == null || replacement === resolution.filePath) {
|
|
652
|
+
return resolution;
|
|
653
|
+
}
|
|
654
|
+
// An override importing the thing it overrides would loop forever.
|
|
655
|
+
if (path.resolve(context.originModulePath ?? '') === replacement) {
|
|
656
|
+
return resolution;
|
|
657
|
+
}
|
|
658
|
+
return { type: 'sourceFile', filePath: replacement };
|
|
659
|
+
},
|
|
660
|
+
},
|
|
661
|
+
};
|
|
662
|
+
}
|
|
663
|
+
/**
|
|
664
|
+
* The original name, kept working. Enables only `linux`, which is what it
|
|
665
|
+
* always did, so an app that has this in its metro.config.js keeps the exact
|
|
666
|
+
* behaviour it had.
|
|
667
|
+
*/
|
|
668
|
+
function withLinuxPlatform(config = {}) {
|
|
669
|
+
return withDesktopPlatforms(config, { platforms: ['linux'] });
|
|
670
|
+
}
|
|
671
|
+
//# sourceMappingURL=metro-config.js.map
|