@legendapp/spark 0.0.1-next.2 → 0.0.1-next.4
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/README.md +10 -4
- package/ai-codex.ts +1 -0
- package/ai.ts +1 -0
- package/app-documents.ts +1 -0
- package/camera.ts +13 -0
- package/config-plugin.d.cts +2 -0
- package/contracts.ts +2 -0
- package/diagnostics.ts +1 -0
- package/expo-config.d.cts +1 -0
- package/metro.cjs +4 -1
- package/metro.d.cts +12 -0
- package/native.cjs +3 -1
- package/native.d.cts +6 -0
- package/package.json +93 -15
- package/patches/camera/react-native-nitro-image.patch +320 -0
- package/patches/camera/react-native-nitro-modules.patch +50 -0
- package/patches/camera/react-native-vision-camera.patch +2662 -0
- package/patches/camera/upstream.json +22 -0
- package/patches/dependencies.json +8 -0
- package/patches/react-native-enriched-markdown@1.0.2.patch +8684 -0
- package/postinstall.cjs +1 -0
- package/schema.json +276 -58
- package/settings-observable.ts +1 -0
- package/settings-window.ts +1 -0
- package/shortcuts-commands.ts +1 -0
- package/shortcuts-keyboard.ts +3 -0
- package/ui-classnames.ts +1 -0
- package/ui-glass.ts +1 -0
- package/ui-search.ts +1 -0
- package/ui-sidebar.ts +1 -0
- package/ui-split-view.ts +1 -0
- package/ui-swipe.ts +1 -0
- package/ui-symbol.ts +1 -0
- package/vendor/node_modules/@legendapp/spark-ai/package.json +19 -0
- package/vendor/node_modules/@legendapp/spark-ai/src/availability.ts +17 -0
- package/vendor/node_modules/@legendapp/spark-ai/src/index.ts +15 -0
- package/vendor/node_modules/@legendapp/spark-ai/src/invocations.ts +34 -0
- package/vendor/node_modules/@legendapp/spark-ai/src/output.ts +62 -0
- package/vendor/node_modules/@legendapp/spark-ai/src/run.ts +12 -0
- package/vendor/node_modules/@legendapp/spark-ai/src/types.ts +16 -0
- package/vendor/node_modules/@legendapp/spark-audio/macos/RNSparkAudio.h +2 -1
- package/vendor/node_modules/@legendapp/spark-audio/macos/RNSparkAudio.mm +126 -24
- package/vendor/node_modules/@legendapp/spark-audio/package.json +5 -2
- package/vendor/node_modules/@legendapp/spark-audio/src/NativeSparkAudio.ts +5 -1
- package/vendor/node_modules/@legendapp/spark-audio/src/desktop.ts +36 -32
- package/vendor/node_modules/@legendapp/spark-audio/src/events.ts +11 -0
- package/vendor/node_modules/@legendapp/spark-audio/src/hooks.ts +65 -0
- package/vendor/node_modules/@legendapp/spark-audio/src/index.web.ts +92 -33
- package/vendor/node_modules/@legendapp/spark-audio/src/media-session-unavailable.ts +6 -4
- package/vendor/node_modules/@legendapp/spark-audio/src/media-session.ts +52 -19
- package/vendor/node_modules/@legendapp/spark-audio/src/media-session.web.ts +18 -10
- package/vendor/node_modules/@legendapp/spark-audio/src/media-types.ts +40 -13
- package/vendor/node_modules/@legendapp/spark-audio/src/mobile.ts +40 -32
- package/vendor/node_modules/@legendapp/spark-audio/src/player.ts +97 -0
- package/vendor/node_modules/@legendapp/spark-audio/src/status-listeners.ts +21 -15
- package/vendor/node_modules/@legendapp/spark-audio/src/types.ts +9 -4
- package/vendor/node_modules/@legendapp/spark-audio/windows/SparkAudio/SparkAudio.h +67 -20
- package/vendor/node_modules/@legendapp/spark-auth-session/package.json +4 -3
- package/vendor/node_modules/@legendapp/spark-auth-session/src/core.ts +60 -42
- package/vendor/node_modules/@legendapp/spark-auth-session/src/index.ts +28 -12
- package/vendor/node_modules/@legendapp/spark-auth-session/src/mobile.ts +97 -41
- package/vendor/node_modules/@legendapp/spark-auth-session/src/types.ts +20 -9
- package/vendor/node_modules/@legendapp/spark-cli/dist/add-desktop.js +50 -7
- package/vendor/node_modules/@legendapp/spark-cli/dist/build-mode.js +1 -1
- package/vendor/node_modules/@legendapp/spark-cli/dist/build.js +145 -59
- package/vendor/node_modules/@legendapp/spark-cli/dist/cli-arguments.js +61 -0
- package/vendor/node_modules/@legendapp/spark-cli/dist/commands.js +10 -4
- package/vendor/node_modules/@legendapp/spark-cli/dist/create.js +37 -8
- package/vendor/node_modules/@legendapp/spark-cli/dist/credentials.js +86 -25
- package/vendor/node_modules/@legendapp/spark-cli/dist/dependency-pins.js +132 -0
- package/vendor/node_modules/@legendapp/spark-cli/dist/dev-command.js +13 -4
- package/vendor/node_modules/@legendapp/spark-cli/dist/dev.js +13 -10
- package/vendor/node_modules/@legendapp/spark-cli/dist/errors.js +100 -0
- package/vendor/node_modules/@legendapp/spark-cli/dist/examples.js +2 -2
- package/vendor/node_modules/@legendapp/spark-cli/dist/expo-dev-patch.cjs +4 -2
- package/vendor/node_modules/@legendapp/spark-cli/dist/expo-metro.cjs +1 -1
- package/vendor/node_modules/@legendapp/spark-cli/dist/expo-native.cjs +5 -1
- package/vendor/node_modules/@legendapp/spark-cli/dist/expo-node.js +3 -3
- package/vendor/node_modules/@legendapp/spark-cli/dist/helpers.js +1 -1
- package/vendor/node_modules/@legendapp/spark-cli/dist/index.js +52 -44
- package/vendor/node_modules/@legendapp/spark-cli/dist/json.js +16 -0
- package/vendor/node_modules/@legendapp/spark-cli/dist/local.js +1 -1
- package/vendor/node_modules/@legendapp/spark-cli/dist/metro.cjs +26 -5
- package/vendor/node_modules/@legendapp/spark-cli/dist/native-metadata.js +26 -0
- package/vendor/node_modules/@legendapp/spark-cli/dist/native-patch-preflight.js +86 -0
- package/vendor/node_modules/@legendapp/spark-cli/dist/native-preparation.js +88 -0
- package/vendor/node_modules/@legendapp/spark-cli/dist/notary-profiles.js +75 -0
- package/vendor/node_modules/@legendapp/spark-cli/dist/package.js +4 -2
- package/vendor/node_modules/@legendapp/spark-cli/dist/platform.js +16 -2
- package/vendor/node_modules/@legendapp/spark-cli/dist/process.js +7 -0
- package/vendor/node_modules/@legendapp/spark-cli/dist/project.js +90 -32
- package/vendor/node_modules/@legendapp/spark-cli/dist/release.js +86 -5
- package/vendor/node_modules/@legendapp/spark-cli/dist/release.json +23 -18
- package/vendor/node_modules/@legendapp/spark-cli/dist/runner-install.js +145 -31
- package/vendor/node_modules/@legendapp/spark-cli/dist/signing.js +4 -3
- package/vendor/node_modules/@legendapp/spark-cli/dist/universal.cjs +2 -1
- package/vendor/node_modules/@legendapp/spark-cli/dist/updates.js +41 -4
- package/vendor/node_modules/@legendapp/spark-cli/dist/windows.js +5 -9
- package/vendor/node_modules/@legendapp/spark-cli/package.json +7 -6
- package/vendor/node_modules/@legendapp/spark-cli/templates/blank-typescript/App.tsx +6 -12
- package/vendor/node_modules/@legendapp/spark-cli/templates/blank-typescript/desktop.config.json +5 -3
- package/vendor/node_modules/@legendapp/spark-cli/templates/blank-typescript/package.json +12 -10
- package/vendor/node_modules/@legendapp/spark-cli/templates/diff-lite/Git.macos.tsx +2 -2
- package/vendor/node_modules/@legendapp/spark-cli/templates/document-editor/Integration.macos.tsx +23 -21
- package/vendor/node_modules/@legendapp/spark-cli/templates/document-editor/Integration.windows.tsx +23 -21
- package/vendor/node_modules/@legendapp/spark-cli/templates/document-editor/io.desktop.ts +11 -8
- package/vendor/node_modules/@legendapp/spark-cli/templates/document-editor/io.macos.ts +3 -3
- package/vendor/node_modules/@legendapp/spark-cli/templates/example-shared/Lifecycle.desktop.tsx +8 -14
- package/vendor/node_modules/@legendapp/spark-cli/templates/example-shared/OpenFiles.desktop.tsx +5 -10
- package/vendor/node_modules/@legendapp/spark-cli/templates/example-shared/io.desktop.ts +11 -8
- package/vendor/node_modules/@legendapp/spark-cli/templates/example-shared/io.macos.ts +3 -3
- package/vendor/node_modules/@legendapp/spark-cli/templates/music-lite/assets.desktop.ts +2 -2
- package/vendor/node_modules/@legendapp/spark-cli/templates/notes-lite/Activation.desktop.tsx +2 -2
- package/vendor/node_modules/@legendapp/spark-cli/templates/notes-lite/Desktop.desktop.ts +37 -15
- package/vendor/node_modules/@legendapp/spark-cli/templates/notes-lite/session.ts +5 -6
- package/vendor/node_modules/@legendapp/spark-cli/templates/notes-lite/window-session.ts +5 -4
- package/vendor/node_modules/@legendapp/spark-cli/templates/universal/desktop.config.json +5 -3
- package/vendor/node_modules/@legendapp/spark-cli/templates/universal/metro.config.js +1 -1
- package/vendor/node_modules/@legendapp/spark-cli/templates/universal/package.json +14 -12
- package/vendor/node_modules/@legendapp/spark-cli/templates/universal/react-native.config.js +1 -1
- package/vendor/node_modules/@legendapp/spark-cli/templates/windows/package.json +14 -12
- package/vendor/node_modules/@legendapp/spark-cli/templates/windows/react-native.config.js +1 -1
- package/vendor/node_modules/@legendapp/spark-clipboard/macos/RNDesktopClipboard.mm +10 -16
- package/vendor/node_modules/@legendapp/spark-clipboard/package.json +2 -2
- package/vendor/node_modules/@legendapp/spark-clipboard/src/NativeDesktopClipboard.ts +1 -1
- package/vendor/node_modules/@legendapp/spark-clipboard/src/desktop.ts +55 -31
- package/vendor/node_modules/@legendapp/spark-clipboard/src/expo.ts +21 -11
- package/vendor/node_modules/@legendapp/spark-clipboard/src/options.ts +8 -0
- package/vendor/node_modules/@legendapp/spark-clipboard/src/types.ts +10 -0
- package/vendor/node_modules/@legendapp/spark-clipboard/windows/SparkClipboard/SparkClipboard.h +38 -15
- package/vendor/node_modules/@legendapp/spark-clipboard/windows/SparkClipboard/SparkClipboard.vcxproj +2 -0
- package/vendor/node_modules/@legendapp/spark-codex/RNCodex.podspec +22 -0
- package/vendor/node_modules/@legendapp/spark-codex/cpp/HybridCodexAppServer.hpp +23 -0
- package/vendor/node_modules/@legendapp/spark-codex/cpp/HybridCodexAppServer.mm +1529 -0
- package/vendor/node_modules/@legendapp/spark-codex/nitro.json +21 -0
- package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/.gitattributes +1 -0
- package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/ios/RNCodex+autolinking.rb +62 -0
- package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/ios/RNCodex-Swift-Cxx-Bridge.cpp +17 -0
- package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/ios/RNCodex-Swift-Cxx-Bridge.hpp +27 -0
- package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/ios/RNCodex-Swift-Cxx-Umbrella.hpp +38 -0
- package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/ios/RNCodexAutolinking.mm +35 -0
- package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/ios/RNCodexAutolinking.swift +16 -0
- package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/shared/c++/CodexAvailability.hpp +95 -0
- package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/shared/c++/CodexRunResult.hpp +99 -0
- package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/shared/c++/HybridCodexAppServerSpec.cpp +24 -0
- package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/shared/c++/HybridCodexAppServerSpec.hpp +71 -0
- package/vendor/node_modules/@legendapp/spark-codex/package.json +35 -0
- package/vendor/node_modules/@legendapp/spark-codex/react-native.config.js +11 -0
- package/vendor/node_modules/@legendapp/spark-codex/src/Codex.nitro.ts +30 -0
- package/vendor/node_modules/@legendapp/spark-codex/src/index.ts +65 -0
- package/vendor/node_modules/@legendapp/spark-codex/src/native.ts +6 -0
- package/vendor/node_modules/@legendapp/spark-commands/package.json +21 -0
- package/vendor/node_modules/@legendapp/spark-commands/src/bindings.ts +90 -0
- package/vendor/node_modules/@legendapp/spark-commands/src/index.tsx +400 -0
- package/vendor/node_modules/@legendapp/spark-commands/src/router.ts +138 -0
- package/vendor/node_modules/@legendapp/spark-commands/src/storage.ts +20 -0
- package/vendor/node_modules/@legendapp/spark-context-menu/macos/RNContextMenu.mm +7 -8
- package/vendor/node_modules/@legendapp/spark-context-menu/package.json +4 -3
- package/vendor/node_modules/@legendapp/spark-context-menu/src/NativeContextMenu.ts +1 -1
- package/vendor/node_modules/@legendapp/spark-context-menu/src/index.ts +26 -26
- package/vendor/node_modules/@legendapp/spark-context-menu/windows/SparkContextMenu/SparkContextMenu.h +3 -2
- package/vendor/node_modules/@legendapp/spark-desktop-app/RNDesktopApp.podspec +2 -1
- package/vendor/node_modules/@legendapp/spark-desktop-app/cpp/SparkBinaryJSI.hpp +89 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/cpp/SparkBinaryWindows.hpp +22 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/macos/RNDesktopApp.mm +13 -7
- package/vendor/node_modules/@legendapp/spark-desktop-app/macos/SparkBinaryJSI.h +48 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/macos/SparkDesktop.h +4 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/macos/SparkDesktop.mm +33 -33
- package/vendor/node_modules/@legendapp/spark-desktop-app/macos/SparkDesktopError.h +20 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/macos/SparkLifecycle.h +26 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/macos/SparkLifecycle.mm +49 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/macos/SparkQuitCoordinator.h +9 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/macos/SparkQuitCoordinator.mm +70 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/macos/SparkWindow.mm +9 -6
- package/vendor/node_modules/@legendapp/spark-desktop-app/macos/recent-documents/RNRecentDocumentController.mm +55 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/package.json +5 -3
- package/vendor/node_modules/@legendapp/spark-desktop-app/src/NativeDesktopApp.ts +1 -1
- package/vendor/node_modules/@legendapp/spark-desktop-app/src/api.ts +86 -40
- package/vendor/node_modules/@legendapp/spark-desktop-app/src/contracts/accelerator.ts +40 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/src/contracts/index.ts +56 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/src/contracts/menu.ts +116 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/src/contracts/native-buffer.ts +22 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/src/contracts/path.ts +24 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/src/events.ts +75 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/src/index.ts +2 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/src/index.windows.ts +2 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/src/open-requests.ts +43 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/src/restoration.ts +11 -0
- package/vendor/node_modules/@legendapp/spark-desktop-app/src/transport.ts +10 -0
- package/vendor/node_modules/@legendapp/spark-desktop-config/app.plugin.cjs +10 -5
- package/vendor/node_modules/@legendapp/spark-desktop-config/app.plugin.d.cts +3 -0
- package/vendor/node_modules/@legendapp/spark-desktop-config/autolinking.cjs +35 -0
- package/vendor/node_modules/@legendapp/spark-desktop-config/config.cjs +18 -3
- package/vendor/node_modules/@legendapp/spark-desktop-config/config.d.cts +89 -9
- package/vendor/node_modules/@legendapp/spark-desktop-config/expo.cjs +1 -0
- package/vendor/node_modules/@legendapp/spark-desktop-config/expo.d.cts +3 -0
- package/vendor/node_modules/@legendapp/spark-desktop-config/identity.cjs +3 -2
- package/vendor/node_modules/@legendapp/spark-desktop-config/lifecycle.cjs +20 -0
- package/vendor/node_modules/@legendapp/spark-desktop-config/native-patches.cjs +106 -0
- package/vendor/node_modules/@legendapp/spark-desktop-config/native-patches.d.cts +1 -0
- package/vendor/node_modules/@legendapp/spark-desktop-config/package.json +7 -5
- package/vendor/node_modules/@legendapp/spark-desktop-config/schema.json +276 -58
- package/vendor/node_modules/@legendapp/spark-desktop-config/updates.cjs +1 -0
- package/vendor/node_modules/@legendapp/spark-desktop-config/validation.cjs +35 -0
- package/vendor/node_modules/@legendapp/spark-desktop-config/windows.plugin.cjs +2 -1
- package/vendor/node_modules/@legendapp/spark-desktop-host/AppDelegate.mm +129 -11
- package/vendor/node_modules/@legendapp/spark-desktop-host/package.json +2 -2
- package/vendor/node_modules/@legendapp/spark-desktop-host/windows/application.inc +277 -121
- package/vendor/node_modules/@legendapp/spark-desktop-links/common/AuthLoopback.h +5 -7
- package/vendor/node_modules/@legendapp/spark-desktop-links/macos/RNDesktopLinks.mm +10 -9
- package/vendor/node_modules/@legendapp/spark-desktop-links/package.json +2 -2
- package/vendor/node_modules/@legendapp/spark-desktop-links/src/NativeDesktopLinks.ts +1 -1
- package/vendor/node_modules/@legendapp/spark-desktop-links/src/api.ts +27 -33
- package/vendor/node_modules/@legendapp/spark-desktop-links/src/expo.ts +3 -4
- package/vendor/node_modules/@legendapp/spark-desktop-links/src/native.ts +9 -0
- package/vendor/node_modules/@legendapp/spark-desktop-links/windows/SparkLinks/SparkLinks.h +22 -22
- package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/RNDesktopShortcuts.podspec +1 -0
- package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/macos/RNDesktopShortcuts.mm +1 -1
- package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/macos/keyboard-manager/RNKeyboardManager.h +9 -0
- package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/macos/keyboard-manager/RNKeyboardManager.mm +307 -0
- package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/package.json +8 -5
- package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/src/NativeDesktopShortcuts.ts +1 -1
- package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/src/api.ts +39 -14
- package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/src/keyboard-manager/NativeKeyboardManager.ts +12 -0
- package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/src/keyboard-manager/codes.ts +108 -0
- package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/src/keyboard-manager/index.ts +99 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/RNDesktopWindows.podspec +2 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/macos/RNDesktopWindows.mm +229 -103
- package/vendor/node_modules/@legendapp/spark-desktop-windows/macos/SparkWindowGeometry.h +63 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/macos/window-manager/LegendWindowRegistry.h +20 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/macos/window-manager/LegendWindowRegistry.mm +27 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/macos/window-manager/RNWindowManager.h +12 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/macos/window-manager/RNWindowManager.mm +3169 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/macos/window-manager/RNWindowManagerStartup.mm +31 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/macos/window-manager/SidebarStartupFallbacks.mm +14 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/package.json +10 -6
- package/vendor/node_modules/@legendapp/spark-desktop-windows/src/NativeDesktopWindowManager.ts +1 -1
- package/vendor/node_modules/@legendapp/spark-desktop-windows/src/api.ts +146 -70
- package/vendor/node_modules/@legendapp/spark-desktop-windows/src/diagnostics.ts +17 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/src/index.ts +3 -1
- package/vendor/node_modules/@legendapp/spark-desktop-windows/src/index.windows.ts +3 -1
- package/vendor/node_modules/@legendapp/spark-desktop-windows/src/macos-adapter.ts +53 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/src/macos.ts +51 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/src/transport.ts +41 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/src/types.ts +140 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/src/validation.ts +162 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/src/window-manager/NativeWindowManager.ts +28 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/src/windows/WindowProvider.tsx +20 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/src/windows/createWindowsNavigator.tsx +78 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/src/windows/index.ts +6 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/src/windows/primaryWindowLifecycle.ts +34 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/src/windows/types.ts +11 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/src/windows/usePrimaryWindowLifecycle.ts +18 -0
- package/vendor/node_modules/@legendapp/spark-desktop-windows/src/windows/useWindowFocusEffect.ts +17 -0
- package/vendor/node_modules/@legendapp/spark-documents/package.json +22 -0
- package/vendor/node_modules/@legendapp/spark-documents/src/controller.ts +97 -0
- package/vendor/node_modules/@legendapp/spark-documents/src/documentTransition.ts +13 -0
- package/vendor/node_modules/@legendapp/spark-documents/src/hooks.ts +139 -0
- package/vendor/node_modules/@legendapp/spark-documents/src/index.tsx +50 -0
- package/vendor/node_modules/@legendapp/spark-documents/src/reload.ts +39 -0
- package/vendor/node_modules/@legendapp/spark-documents/src/requests.ts +15 -0
- package/vendor/node_modules/@legendapp/spark-drag-drop/package.json +4 -3
- package/vendor/node_modules/@legendapp/spark-drag-drop/src/DesktopDragViewNativeComponent.ts +1 -1
- package/vendor/node_modules/@legendapp/spark-drag-drop/src/contracts.ts +73 -18
- package/vendor/node_modules/@legendapp/spark-drag-drop/src/index.tsx +58 -15
- package/vendor/node_modules/@legendapp/spark-drag-drop/windows/SparkDragDrop/SparkDragDrop.h +14 -8
- package/vendor/node_modules/@legendapp/spark-file-dialog/ios/RNFileDialog.mm +34 -121
- package/vendor/node_modules/@legendapp/spark-file-dialog/package.json +12 -5
- package/vendor/node_modules/@legendapp/spark-file-dialog/src/NativeFileDialog.ts +1 -5
- package/vendor/node_modules/@legendapp/spark-file-dialog/src/index.ts +19 -84
- package/vendor/node_modules/@legendapp/spark-file-dialog/src/native.ts +12 -0
- package/vendor/node_modules/@legendapp/spark-file-dialog/src/options.ts +34 -14
- package/vendor/node_modules/@legendapp/spark-file-dialog/src/types.ts +26 -0
- package/vendor/node_modules/@legendapp/spark-file-dialog/windows/SparkFileDialog/SparkFileDialog.h +42 -58
- package/vendor/node_modules/@legendapp/spark-file-system/RNDesktopFileSystem.podspec +1 -0
- package/vendor/node_modules/@legendapp/spark-file-system/macos/RNDesktopFileSystem.mm +32 -21
- package/vendor/node_modules/@legendapp/spark-file-system/macos/SparkFileMutations.h +24 -0
- package/vendor/node_modules/@legendapp/spark-file-system/macos/SparkFileMutations.mm +215 -0
- package/vendor/node_modules/@legendapp/spark-file-system/macos/file-scanner/RNFileScanner.h +9 -0
- package/vendor/node_modules/@legendapp/spark-file-system/macos/file-scanner/RNFileScanner.mm +82 -0
- package/vendor/node_modules/@legendapp/spark-file-system/macos/file-scanner/RNFileScannerCore.h +47 -0
- package/vendor/node_modules/@legendapp/spark-file-system/macos/file-scanner/RNFileScannerCore.mm +306 -0
- package/vendor/node_modules/@legendapp/spark-file-system/package.json +8 -6
- package/vendor/node_modules/@legendapp/spark-file-system/src/NativeDesktopFileSystem.ts +1 -1
- package/vendor/node_modules/@legendapp/spark-file-system/src/file-scanner/NativeFileScanner.ts +11 -0
- package/vendor/node_modules/@legendapp/spark-file-system/src/file-scanner/index.ts +93 -0
- package/vendor/node_modules/@legendapp/spark-file-system/src/handles.ts +48 -14
- package/vendor/node_modules/@legendapp/spark-file-system/src/index.ts +134 -45
- package/vendor/node_modules/@legendapp/spark-file-system/src/path.ts +1 -9
- package/vendor/node_modules/@legendapp/spark-file-system/windows/SparkFileSystem/SparkFileSystem.h +102 -26
- package/vendor/node_modules/@legendapp/spark-file-system/windows/SparkFileSystem/SparkFileSystem.vcxproj +2 -0
- package/vendor/node_modules/@legendapp/spark-global-shortcuts/RNDesktopGlobalShortcuts.podspec +1 -0
- package/vendor/node_modules/@legendapp/spark-global-shortcuts/macos/RNDesktopGlobalShortcuts.mm +7 -4
- package/vendor/node_modules/@legendapp/spark-global-shortcuts/package.json +4 -3
- package/vendor/node_modules/@legendapp/spark-global-shortcuts/src/NativeDesktopGlobalShortcuts.ts +1 -1
- package/vendor/node_modules/@legendapp/spark-global-shortcuts/src/index.ts +39 -10
- package/vendor/node_modules/@legendapp/spark-global-shortcuts/windows/SparkGlobalShortcuts/SparkGlobalShortcuts.h +5 -4
- package/vendor/node_modules/@legendapp/spark-message-dialog/macos/RNDesktopMessageDialog.mm +2 -2
- package/vendor/node_modules/@legendapp/spark-message-dialog/package.json +2 -2
- package/vendor/node_modules/@legendapp/spark-message-dialog/src/NativeDesktopMessageDialog.ts +1 -1
- package/vendor/node_modules/@legendapp/spark-message-dialog/src/index.ts +48 -11
- package/vendor/node_modules/@legendapp/spark-native-menu/ios/RNNativeMenu.mm +141 -609
- package/vendor/node_modules/@legendapp/spark-native-menu/package.json +9 -4
- package/vendor/node_modules/@legendapp/spark-native-menu/src/NativeMenu.ts +2 -7
- package/vendor/node_modules/@legendapp/spark-native-menu/src/api.ts +76 -121
- package/vendor/node_modules/@legendapp/spark-native-menu/src/hooks.ts +97 -0
- package/vendor/node_modules/@legendapp/spark-native-menu/src/windows-menus.ts +43 -37
- package/vendor/node_modules/@legendapp/spark-notifications/macos/RNDesktopNotifications.mm +75 -30
- package/vendor/node_modules/@legendapp/spark-notifications/package.json +2 -2
- package/vendor/node_modules/@legendapp/spark-notifications/src/NativeDesktopNotifications.ts +1 -1
- package/vendor/node_modules/@legendapp/spark-notifications/src/index.ts +130 -42
- package/vendor/node_modules/@legendapp/spark-notifications/windows/SparkNotifications/SparkNotifications.h +51 -8
- package/vendor/node_modules/@legendapp/spark-processes/macos/RNDesktopProcesses.mm +94 -21
- package/vendor/node_modules/@legendapp/spark-processes/package.json +4 -3
- package/vendor/node_modules/@legendapp/spark-processes/src/NativeDesktopProcesses.ts +1 -1
- package/vendor/node_modules/@legendapp/spark-processes/src/index.ts +124 -28
- package/vendor/node_modules/@legendapp/spark-processes/src/types.ts +34 -0
- package/vendor/node_modules/@legendapp/spark-processes/windows/SparkProcesses/SparkProcesses.h +83 -34
- package/vendor/node_modules/@legendapp/spark-processes/windows/SparkProcesses/SparkProcesses.vcxproj +2 -0
- package/vendor/node_modules/@legendapp/spark-secure-storage/macos/RNDesktopSecureStorage.mm +49 -40
- package/vendor/node_modules/@legendapp/spark-secure-storage/package.json +2 -2
- package/vendor/node_modules/@legendapp/spark-secure-storage/src/NativeDesktopSecureStorage.ts +1 -1
- package/vendor/node_modules/@legendapp/spark-secure-storage/src/desktop.ts +16 -14
- package/vendor/node_modules/@legendapp/spark-secure-storage/src/expo.ts +0 -1
- package/vendor/node_modules/@legendapp/spark-secure-storage/src/options.ts +3 -2
- package/vendor/node_modules/@legendapp/spark-secure-storage/src/unavailable.ts +6 -3
- package/vendor/node_modules/@legendapp/spark-settings/package.json +10 -3
- package/vendor/node_modules/@legendapp/spark-settings/src/fileStorage.ts +11 -0
- package/vendor/node_modules/@legendapp/spark-settings/src/index.ts +7 -9
- package/vendor/node_modules/@legendapp/spark-settings/src/storage/index.ts +142 -0
- package/vendor/node_modules/@legendapp/spark-settings/src/store.ts +63 -21
- package/vendor/node_modules/@legendapp/spark-settings-ui/package.json +20 -0
- package/vendor/node_modules/@legendapp/spark-settings-ui/src/index.tsx +436 -0
- package/vendor/node_modules/@legendapp/spark-settings-ui/src/options.ts +10 -0
- package/vendor/node_modules/@legendapp/spark-sqlite/package.json +3 -3
- package/vendor/node_modules/@legendapp/spark-sqlite/src/database.ts +182 -0
- package/vendor/node_modules/@legendapp/spark-sqlite/src/index.ts +19 -6
- package/vendor/node_modules/@legendapp/spark-sqlite/src/types.ts +22 -0
- package/vendor/node_modules/@legendapp/spark-system/macos/RNDesktopSystem.mm +36 -11
- package/vendor/node_modules/@legendapp/spark-system/package.json +2 -2
- package/vendor/node_modules/@legendapp/spark-system/src/NativeDesktopSystem.ts +1 -1
- package/vendor/node_modules/@legendapp/spark-system/src/index.ts +89 -32
- package/vendor/node_modules/@legendapp/spark-system/windows/SparkSystem/SparkSystem.h +8 -4
- package/vendor/node_modules/@legendapp/spark-tray/macos/RNDesktopTray.mm +20 -8
- package/vendor/node_modules/@legendapp/spark-tray/package.json +2 -2
- package/vendor/node_modules/@legendapp/spark-tray/src/NativeDesktopTray.ts +1 -1
- package/vendor/node_modules/@legendapp/spark-tray/src/index.ts +91 -34
- package/vendor/node_modules/@legendapp/spark-tray/windows/SparkTray/SparkTray.h +45 -15
- package/vendor/node_modules/@legendapp/spark-ui/macos/RNSparkButton.mm +2 -1
- package/vendor/node_modules/@legendapp/spark-ui/macos/RNSparkTextInput.mm +10 -2
- package/vendor/node_modules/@legendapp/spark-ui/macos/appkit-split-view/RNSidebarSplitViewComponent.h +15 -0
- package/vendor/node_modules/@legendapp/spark-ui/macos/appkit-split-view/RNSidebarSplitViewComponent.mm +1419 -0
- package/vendor/node_modules/@legendapp/spark-ui/macos/glass-effect-view/RNGlassEffectView.mm +72 -0
- package/vendor/node_modules/@legendapp/spark-ui/macos/native-select/RNNativeSegmentedControl.h +15 -0
- package/vendor/node_modules/@legendapp/spark-ui/macos/native-select/RNNativeSegmentedControl.mm +194 -0
- package/vendor/node_modules/@legendapp/spark-ui/macos/native-select/RNNativeSelect.h +15 -0
- package/vendor/node_modules/@legendapp/spark-ui/macos/native-select/RNNativeSelect.mm +180 -0
- package/vendor/node_modules/@legendapp/spark-ui/macos/sf-symbol/RNSFSymbol.h +15 -0
- package/vendor/node_modules/@legendapp/spark-ui/macos/sf-symbol/RNSFSymbol.mm +155 -0
- package/vendor/node_modules/@legendapp/spark-ui/macos/sidebar/RNSidebar.h +18 -0
- package/vendor/node_modules/@legendapp/spark-ui/macos/sidebar/RNSidebar.mm +645 -0
- package/vendor/node_modules/@legendapp/spark-ui/macos/swipe-actions/RNSwipeActions.h +10 -0
- package/vendor/node_modules/@legendapp/spark-ui/macos/swipe-actions/RNSwipeActions.mm +422 -0
- package/vendor/node_modules/@legendapp/spark-ui/macos/text-input-search/RNTextInputSearch.h +15 -0
- package/vendor/node_modules/@legendapp/spark-ui/macos/text-input-search/RNTextInputSearch.mm +164 -0
- package/vendor/node_modules/@legendapp/spark-ui/package.json +17 -4
- package/vendor/node_modules/@legendapp/spark-ui/src/SparkSelectNativeComponent.ts +3 -1
- package/vendor/node_modules/@legendapp/spark-ui/src/SparkTextInputNativeComponent.ts +6 -2
- package/vendor/node_modules/@legendapp/spark-ui/src/appkit-split-view/SidebarSplitViewNativeComponent.ts +37 -0
- package/vendor/node_modules/@legendapp/spark-ui/src/appkit-split-view/index.tsx +86 -0
- package/vendor/node_modules/@legendapp/spark-ui/src/availability.ts +10 -0
- package/vendor/node_modules/@legendapp/spark-ui/src/classnames/index.ts +8 -0
- package/vendor/node_modules/@legendapp/spark-ui/src/control.ts +42 -0
- package/vendor/node_modules/@legendapp/spark-ui/src/desktop.tsx +56 -0
- package/vendor/node_modules/@legendapp/spark-ui/src/glass-effect-view/index.tsx +15 -0
- package/vendor/node_modules/@legendapp/spark-ui/src/index.android.tsx +35 -21
- package/vendor/node_modules/@legendapp/spark-ui/src/index.ios.tsx +55 -26
- package/vendor/node_modules/@legendapp/spark-ui/src/index.tsx +1 -27
- package/vendor/node_modules/@legendapp/spark-ui/src/index.web.tsx +45 -14
- package/vendor/node_modules/@legendapp/spark-ui/src/index.windows.tsx +1 -42
- package/vendor/node_modules/@legendapp/spark-ui/src/mobile-input.tsx +11 -0
- package/vendor/node_modules/@legendapp/spark-ui/src/native-select/NativeSegmentedControlNativeComponent.ts +17 -0
- package/vendor/node_modules/@legendapp/spark-ui/src/native-select/NativeSelectNativeComponent.ts +17 -0
- package/vendor/node_modules/@legendapp/spark-ui/src/select.ts +5 -3
- package/vendor/node_modules/@legendapp/spark-ui/src/sf-symbol/SFSymbolNativeComponent.ts +13 -0
- package/vendor/node_modules/@legendapp/spark-ui/src/sf-symbol/index.tsx +27 -0
- package/vendor/node_modules/@legendapp/spark-ui/src/sidebar/SidebarItemNativeComponent.ts +25 -0
- package/vendor/node_modules/@legendapp/spark-ui/src/sidebar/SidebarNativeComponent.ts +24 -0
- package/vendor/node_modules/@legendapp/spark-ui/src/sidebar/index.tsx +104 -0
- package/vendor/node_modules/@legendapp/spark-ui/src/specialized.ts +22 -0
- package/vendor/node_modules/@legendapp/spark-ui/src/swipe-actions/SwipeActionsNativeComponent.ts +11 -0
- package/vendor/node_modules/@legendapp/spark-ui/src/swipe-actions/index.tsx +41 -0
- package/vendor/node_modules/@legendapp/spark-ui/src/text-input-search/TextInputSearchNativeComponent.ts +33 -0
- package/vendor/node_modules/@legendapp/spark-ui/src/text-input-search/index.tsx +34 -0
- package/vendor/node_modules/@legendapp/spark-ui/src/types.ts +30 -19
- package/vendor/node_modules/@legendapp/spark-ui/uniwind.ts +3 -1
- package/vendor/node_modules/@legendapp/spark-ui/uniwind.web.ts +3 -1
- package/vendor/node_modules/@legendapp/spark-ui/windows/SparkUI/SparkUI.h +16 -11
- package/vendor/node_modules/@legendapp/spark-updates/macos/RNDesktopUpdates.mm +21 -8
- package/vendor/node_modules/@legendapp/spark-updates/package.json +2 -2
- package/vendor/node_modules/@legendapp/spark-updates/src/NativeDesktopUpdates.ts +3 -2
- package/vendor/node_modules/@legendapp/spark-updates/src/index.ts +71 -15
- package/vendor/node_modules/@legendapp/spark-webview/package.json +2 -2
- package/vendor/node_modules/@legendapp/spark-webview/src/WebView.tsx +11 -0
- package/vendor/node_modules/@legendapp/spark-webview/src/adapter.ts +55 -0
- package/vendor/node_modules/@legendapp/spark-webview/src/index.ts +2 -2
- package/vendor/node_modules/@legendapp/spark-webview/src/types.ts +32 -0
- package/vendor/node_modules/@legendapp/spark-webview/src/view-props.ts +28 -0
- package/vendor/node_modules/@legendapp/spark-window-options/index.cjs +51 -14
- package/vendor/node_modules/@legendapp/spark-window-options/index.d.ts +21 -8
- package/vendor/node_modules/@legendapp/spark-window-options/package.json +1 -1
- package/windows-macos.ts +1 -0
- package/expo-metro.cjs +0 -1
- package/message-dialog.ts +0 -1
- package/universal.cjs +0 -1
- package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/src/accelerator.ts +0 -22
- package/vendor/node_modules/@legendapp/spark-desktop-windows/src/windows-options.ts +0 -11
- package/vendor/node_modules/@legendapp/spark-file-dialog/src/index.windows.ts +0 -15
- package/vendor/node_modules/@legendapp/spark-global-shortcuts/src/accelerator.ts +0 -22
- package/vendor/node_modules/@legendapp/spark-ui/macos/RNSparkSelect.h +0 -4
- package/vendor/node_modules/@legendapp/spark-ui/macos/RNSparkSelect.mm +0 -53
|
@@ -23,12 +23,26 @@ export function windowsArchitecture(host = process.platform, machineArch = machi
|
|
|
23
23
|
}
|
|
24
24
|
return "x64";
|
|
25
25
|
}
|
|
26
|
-
export
|
|
26
|
+
export function macOSArchitecture(machineArch = machine(), env = process.env) {
|
|
27
|
+
const explicit = env.SPARK_MACOS_ARCH?.toLowerCase();
|
|
28
|
+
if (explicit !== undefined) {
|
|
29
|
+
if (explicit === "arm64" || explicit === "x64")
|
|
30
|
+
return explicit;
|
|
31
|
+
throw new Error("SPARK_MACOS_ARCH must be arm64 or x64.");
|
|
32
|
+
}
|
|
33
|
+
if (machineArch === "arm64" || machineArch === "aarch64")
|
|
34
|
+
return "arm64";
|
|
35
|
+
if (["x64", "x86_64"].includes(machineArch))
|
|
36
|
+
return "x64";
|
|
37
|
+
throw new Error(`Unsupported macOS architecture: ${machineArch}.`);
|
|
38
|
+
}
|
|
39
|
+
export const macOSXcodeArchitecture = (arch) => arch === "x64" ? "x86_64" : "arm64";
|
|
40
|
+
export const architecture = (platform) => platform === "windows" ? windowsArchitecture() : macOSArchitecture();
|
|
27
41
|
export function projectPlatform(root) {
|
|
28
42
|
if (!["app.json", "desktop.config.json"].some(name => existsSync(path.join(root, name))))
|
|
29
43
|
return "macos";
|
|
30
44
|
const platforms = readConfig(root).expo?.platforms ?? ["macos"];
|
|
31
|
-
if (platforms.length !== 1 ||
|
|
45
|
+
if (platforms.length !== 1 || (platforms[0] !== "macos" && platforms[0] !== "windows"))
|
|
32
46
|
throw new Error("Select a desktop target with --platform macos or --platform windows.");
|
|
33
47
|
return platforms[0];
|
|
34
48
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { readJson } from "./json.js";
|
|
1
2
|
import path from "node:path";
|
|
2
3
|
import { spawn as nodeSpawn } from "node:child_process";
|
|
3
4
|
import { createRequire } from "node:module";
|
|
@@ -55,3 +56,9 @@ export function spawnProcess(argv, options = {}) {
|
|
|
55
56
|
return result;
|
|
56
57
|
}
|
|
57
58
|
export { which } from "./executable.js";
|
|
59
|
+
// Windows .cmd shims are shell programs; run the package's actual JS entry.
|
|
60
|
+
export function nodeCommand(root, name, bin, args = []) {
|
|
61
|
+
const req = createRequire(path.join(root, "package.json"));
|
|
62
|
+
const file = req.resolve(`${name}/package.json`), pkg = readJson(file);
|
|
63
|
+
return ["node", path.resolve(path.dirname(file), typeof pkg.bin === "string" ? pkg.bin : pkg.bin[bin]), ...args];
|
|
64
|
+
}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { nativeWindowOptions } from "@legendapp/spark-window-options";
|
|
2
|
+
import { prepareNativePatches } from "@legendapp/spark-desktop-config/native-patches.cjs";
|
|
1
3
|
import { macOSReleaseSettings } from "./macos-release.js";
|
|
2
4
|
import { projectPlatform, architecture } from "./platform.js";
|
|
3
5
|
import { resolveHelpers } from "./helpers.js";
|
|
@@ -5,23 +7,11 @@ import { readConfig as readAppConfig, prepareConfig, writeUpdates, statePath, is
|
|
|
5
7
|
export { readAppConfig, prepareConfig, writeUpdates, statePath, isUniversal };
|
|
6
8
|
import { createHash } from "node:crypto";
|
|
7
9
|
import { createRequire } from "node:module";
|
|
8
|
-
import { existsSync,
|
|
10
|
+
import { existsSync, readFileSync, readdirSync, realpathSync, } from "node:fs";
|
|
9
11
|
import path from "node:path";
|
|
10
|
-
|
|
11
|
-
export
|
|
12
|
-
|
|
13
|
-
}
|
|
14
|
-
export function writeJson(file, value) {
|
|
15
|
-
const content = JSON.stringify(value, null, 2) + "\n";
|
|
16
|
-
// Metro watches JSON too: rewriting unchanged session state on every runtime
|
|
17
|
-
// check causes empty Fast Refresh updates even when app code has not changed.
|
|
18
|
-
if (existsSync(file) && readFileSync(file, "utf8") === content)
|
|
19
|
-
return;
|
|
20
|
-
mkdirSync(path.dirname(file), { recursive: true });
|
|
21
|
-
const temporary = `${file}.${process.pid}.tmp`;
|
|
22
|
-
writeFileSync(temporary, content);
|
|
23
|
-
renameSync(temporary, file);
|
|
24
|
-
}
|
|
12
|
+
import { readJson, writeJson } from "./json.js";
|
|
13
|
+
export { readJson, writeJson };
|
|
14
|
+
export const VERSION = "0.0.1-next.4";
|
|
25
15
|
export function digest(value) {
|
|
26
16
|
return createHash("sha256").update(value).digest("hex");
|
|
27
17
|
}
|
|
@@ -38,13 +28,13 @@ export function entryFile(root) {
|
|
|
38
28
|
}
|
|
39
29
|
export function installedPackages(root) {
|
|
40
30
|
const found = new Map();
|
|
41
|
-
const
|
|
42
|
-
|
|
43
|
-
];
|
|
31
|
+
const manifest = readJson(path.join(root, "package.json"));
|
|
32
|
+
const appRequire = createRequire(path.join(root, "package.json"));
|
|
33
|
+
const queue = [{ root, json: manifest, app: true }];
|
|
44
34
|
const visited = new Set();
|
|
45
35
|
while (queue.length) {
|
|
46
36
|
const current = queue.shift();
|
|
47
|
-
const
|
|
37
|
+
const contextualRequire = createRequire(path.join(current.root, current.json.spark?.bundledModuleRoot ?? ".", "package.json"));
|
|
48
38
|
const bundled = current.json.spark?.bundledModules ?? current.json.bundledDependencies ?? current.json.bundleDependencies;
|
|
49
39
|
const names = Object.keys({
|
|
50
40
|
...Object.fromEntries((Array.isArray(bundled) ? bundled : []).map(name => [name, true])),
|
|
@@ -57,6 +47,9 @@ export function installedPackages(root) {
|
|
|
57
47
|
.filter(([name]) => !current.json.peerDependenciesMeta?.[name]?.optional)),
|
|
58
48
|
}).sort();
|
|
59
49
|
for (const name of names) {
|
|
50
|
+
// Linked workspace packages resolve peers from their original checkout.
|
|
51
|
+
// Explicit app overrides must select the app's installed native copy.
|
|
52
|
+
const req = Object.hasOwn(manifest.overrides ?? {}, name) ? appRequire : contextualRequire;
|
|
60
53
|
let file;
|
|
61
54
|
try {
|
|
62
55
|
file = req.resolve(`${name}/package.json`);
|
|
@@ -64,11 +57,19 @@ export function installedPackages(root) {
|
|
|
64
57
|
catch {
|
|
65
58
|
// Packages with exports hiding package.json still have an owning directory.
|
|
66
59
|
try {
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
60
|
+
// Subpath-only packages (e.g. @legendapp/list/react-native) may
|
|
61
|
+
// expose neither package.json nor a root entry. Inspect Node's
|
|
62
|
+
// package search locations without requiring a public root export.
|
|
63
|
+
const manifest = req.resolve.paths(name)?.map(base => path.join(base, name, "package.json"))
|
|
64
|
+
.find(candidate => existsSync(candidate));
|
|
65
|
+
if (manifest)
|
|
66
|
+
file = manifest;
|
|
67
|
+
else {
|
|
68
|
+
let dir = path.dirname(req.resolve(name));
|
|
69
|
+
while ((!existsSync(path.join(dir, "package.json")) || typeof readJson(path.join(dir, "package.json")).name !== "string") && dir !== path.dirname(dir))
|
|
70
|
+
dir = path.dirname(dir);
|
|
71
|
+
file = path.join(dir, "package.json");
|
|
72
|
+
}
|
|
72
73
|
}
|
|
73
74
|
catch {
|
|
74
75
|
if (current.app &&
|
|
@@ -122,16 +123,31 @@ export function hashFiles(root, entries, windows = false) {
|
|
|
122
123
|
visit(entry);
|
|
123
124
|
return hash.digest("hex");
|
|
124
125
|
}
|
|
125
|
-
export function nativePackages(root) {
|
|
126
|
+
export function nativePackages(root, { applyExcludes = true } = {}) {
|
|
127
|
+
prepareNativePatches(root);
|
|
126
128
|
const installed = installedPackages(root);
|
|
127
129
|
if (projectPlatform(root) === "windows")
|
|
128
130
|
return windowsNativePackages(root, installed);
|
|
131
|
+
const excluded = ["app.json", "desktop.config.json"].some(file => existsSync(path.join(root, file)))
|
|
132
|
+
? readAppConfig(root).expo?.autolinking?.exclude ?? [] : [];
|
|
133
|
+
if (!applyExcludes) {
|
|
134
|
+
const appRequire = createRequire(path.join(root, "package.json"));
|
|
135
|
+
for (const name of excluded) {
|
|
136
|
+
if (installed.some(pkg => pkg.name === name))
|
|
137
|
+
continue;
|
|
138
|
+
const file = appRequire.resolve.paths(name)?.map(base => path.join(base, name, "package.json")).find(file => existsSync(file));
|
|
139
|
+
if (!file)
|
|
140
|
+
continue;
|
|
141
|
+
const json = readJson(file);
|
|
142
|
+
installed.push({ name: json.name, root: realpathSync(path.dirname(file)), json });
|
|
143
|
+
}
|
|
144
|
+
installed.sort((a, b) => a.name.localeCompare(b.name));
|
|
145
|
+
}
|
|
129
146
|
// Host/CNG code can change the native ABI without adding a TurboModule.
|
|
130
147
|
// Fold it into the mandatory app module's compatibility signature for Go.
|
|
131
148
|
const adapters = installed.filter(pkg => ["@legendapp/spark-desktop-host", "@legendapp/spark-desktop-config"].includes(pkg.name))
|
|
132
149
|
.map(pkg => hashFiles(pkg.root, ["package.json", "AppDelegate.mm", ...readdirSync(pkg.root).filter(name => name.endsWith(".cjs"))])).join(":");
|
|
133
|
-
|
|
134
|
-
return installed.filter(pkg => !excluded.includes(pkg.name))
|
|
150
|
+
return installed.filter(pkg => !applyExcludes || !excluded.includes(pkg.name))
|
|
135
151
|
.filter((pkg) => pkg.json.codegenConfig ||
|
|
136
152
|
pkg.json.spark?.nativeModules ||
|
|
137
153
|
readdirSync(pkg.root).some((name) => name.endsWith(".podspec") || name === "expo-module.config.json"))
|
|
@@ -168,12 +184,12 @@ export function dependencyStamp(root) {
|
|
|
168
184
|
"react-native.config.js",
|
|
169
185
|
]);
|
|
170
186
|
}
|
|
171
|
-
export function selection(packages, used, include = []) {
|
|
187
|
+
export function selection(packages, used, include = [], excluded = []) {
|
|
172
188
|
const selected = new Set([
|
|
173
189
|
...packages.filter((p) => !p.sdk).map((p) => p.name),
|
|
174
190
|
...used,
|
|
175
191
|
...include,
|
|
176
|
-
]);
|
|
192
|
+
].filter(name => !excluded.includes(name)));
|
|
177
193
|
const reasons = {};
|
|
178
194
|
for (const pkg of packages)
|
|
179
195
|
if (selected.has(pkg.name))
|
|
@@ -196,6 +212,8 @@ export function selection(packages, used, include = []) {
|
|
|
196
212
|
for (const name of nativeDeps) {
|
|
197
213
|
if (!packages.some((p) => p.name === name))
|
|
198
214
|
throw new Error(`${pkg.name} requires missing native package ${name}`);
|
|
215
|
+
if (excluded.includes(name))
|
|
216
|
+
continue;
|
|
199
217
|
if (!selected.has(name)) {
|
|
200
218
|
selected.add(name);
|
|
201
219
|
reasons[name] = `native dependency of ${pkg.name}`;
|
|
@@ -218,6 +236,43 @@ export function hostSourceSignature(root) {
|
|
|
218
236
|
.filter(pkg => ["@legendapp/spark-desktop-host", "@legendapp/spark-desktop-config"].includes(pkg.name))
|
|
219
237
|
.map(pkg => [pkg.name, hashFiles(pkg.root, ["package.json", "AppDelegate.mm", "windows", ...readdirSync(pkg.root).filter(file => file.endsWith(".cjs"))])])));
|
|
220
238
|
}
|
|
239
|
+
export function nativePreparationInputs(root, packages) {
|
|
240
|
+
return {
|
|
241
|
+
config: readAppConfig(root),
|
|
242
|
+
packages: packages.map((p) => [
|
|
243
|
+
p.name,
|
|
244
|
+
// CocoaPods records physical source paths, even for identical packages.
|
|
245
|
+
p.root,
|
|
246
|
+
hashFiles(p.root, [
|
|
247
|
+
"package.json",
|
|
248
|
+
p.json.codegenConfig?.jsSrcsDir ?? "src",
|
|
249
|
+
...readdirSync(p.root).filter((name) => name.endsWith(".podspec")),
|
|
250
|
+
]),
|
|
251
|
+
]),
|
|
252
|
+
plugin: hostSourceSignature(root),
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
export function nativePreparationFingerprint(root, packages) {
|
|
256
|
+
return digest(JSON.stringify(nativePreparationInputs(root, packages)));
|
|
257
|
+
}
|
|
258
|
+
export function nativeProjectFingerprint(inputs, packages) {
|
|
259
|
+
return digest(JSON.stringify({
|
|
260
|
+
config: inputs.config,
|
|
261
|
+
plugin: inputs.plugin,
|
|
262
|
+
packages: packages.map(p => [p.name, p.root, hashFiles(p.root, ["package.json"])]),
|
|
263
|
+
}));
|
|
264
|
+
}
|
|
265
|
+
export function localSigningIdentity(root, mode) {
|
|
266
|
+
if (mode !== "dev")
|
|
267
|
+
return "-";
|
|
268
|
+
const file = stateFile(root, "settings.json");
|
|
269
|
+
const identity = existsSync(file) ? readJson(file).macOSDevelopmentIdentity : undefined;
|
|
270
|
+
if (identity === undefined)
|
|
271
|
+
return "-";
|
|
272
|
+
if (typeof identity !== "string" || !identity.trim() || identity.startsWith("-"))
|
|
273
|
+
throw new Error("macOSDevelopmentIdentity must name a signing certificate or its SHA-1 fingerprint");
|
|
274
|
+
return identity;
|
|
275
|
+
}
|
|
221
276
|
export function runtimeFor(root, packages, mode) {
|
|
222
277
|
const platform = projectPlatform(root);
|
|
223
278
|
const modules = Object.fromEntries(packages.map((p) => [p.name, p.signature]));
|
|
@@ -240,7 +295,10 @@ export function runtimeFor(root, packages, mode) {
|
|
|
240
295
|
mode,
|
|
241
296
|
modules,
|
|
242
297
|
fingerprint: digest(JSON.stringify({
|
|
243
|
-
|
|
298
|
+
arch: architecture(platform),
|
|
299
|
+
// Rebuild cached hosts generated before canonical plist restoration.
|
|
300
|
+
...(platform === "macos" ? { nativeMetadataVersion: 1 } : {}),
|
|
301
|
+
...(platform === "macos" && mode === "dev" ? { developmentIdentity: localSigningIdentity(root, mode) } : {}),
|
|
244
302
|
...(platform === "macos" && mode === "release" ? { releaseSettings: macOSReleaseSettings } : {}),
|
|
245
303
|
modules,
|
|
246
304
|
pins,
|
|
@@ -297,7 +355,7 @@ export function projectEnvironment(root) {
|
|
|
297
355
|
if (typeof projectId !== "string" || !projectId.length || projectId.length > 200)
|
|
298
356
|
throw new Error("Set extra.spark.projectId to a stable project identifier before launching the Spark Runner.");
|
|
299
357
|
return {
|
|
300
|
-
SPARK_WINDOW_CONFIG: JSON.stringify(config.extra?.spark?.window ?? {}),
|
|
358
|
+
SPARK_WINDOW_CONFIG: JSON.stringify(nativeWindowOptions(config.extra?.spark?.window ?? {})),
|
|
301
359
|
SPARK_PROJECT_ID: projectId,
|
|
302
360
|
SPARK_PROJECT_NAME: typeof config.name === "string" ? config.name : path.basename(root),
|
|
303
361
|
SPARK_PROJECT_VERSION: typeof config.version === "string" ? config.version : "0.0.0",
|
|
@@ -1,18 +1,22 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { createHash, randomUUID } from "node:crypto";
|
|
2
|
+
import { closeSync, existsSync, mkdirSync, openSync, readFileSync, renameSync, rmSync, writeSync } from "node:fs";
|
|
2
3
|
import path from "node:path";
|
|
3
|
-
import { readJson
|
|
4
|
+
import { readJson } from "./json.js";
|
|
4
5
|
import { localArchive } from "./package-manager.js";
|
|
6
|
+
const VERSION = readJson(path.resolve(import.meta.dirname, "../package.json")).version;
|
|
5
7
|
export const releaseBase = (version) => `https://github.com/LegendApp/legend-spark/releases/download/v${version}`;
|
|
6
8
|
export function validateRelease(value) {
|
|
7
9
|
if (value?.schema !== 1 || value.version !== VERSION || !/^[a-f0-9]{40}$/.test(value.revision) || !value.packages || !value.runners)
|
|
8
10
|
throw new Error("Invalid or incompatible Spark release manifest");
|
|
11
|
+
if (Object.keys(value.packages).some(name => !/^(?:@[a-z0-9][a-z0-9._-]*\/)?[a-z0-9][a-z0-9._-]*$/.test(name)))
|
|
12
|
+
throw new Error("Invalid Spark package name");
|
|
9
13
|
for (const asset of [...Object.values(value.packages), ...Object.values(value.runners)]) {
|
|
10
14
|
const url = new URL(asset.url);
|
|
11
15
|
if (url.href !== asset.url || !/^[A-Za-z0-9._-]+$/.test(url.pathname.split("/").at(-1) ?? "") || !asset.url.startsWith(releaseBase(VERSION) + "/") || url.search || url.hash || !/^[a-f0-9]{64}$/.test(asset.sha256) || !Number.isSafeInteger(asset.size) || asset.size <= 0)
|
|
12
16
|
throw new Error("Invalid Spark release asset");
|
|
13
17
|
}
|
|
14
18
|
for (const [target, asset] of Object.entries(value.runners)) {
|
|
15
|
-
if (
|
|
19
|
+
if (!["macos-arm64", "macos-x64"].includes(target) || path.basename(asset.app) !== asset.app || !asset.app.endsWith(".app") || !/^[A-Z0-9]{10}$/.test(asset.teamId) || !/^[a-f0-9]+$/.test(asset.fingerprint))
|
|
16
20
|
throw new Error("Invalid Runner release target");
|
|
17
21
|
}
|
|
18
22
|
return value;
|
|
@@ -21,7 +25,7 @@ export function installedRelease() {
|
|
|
21
25
|
const file = path.join(import.meta.dirname, "release.json");
|
|
22
26
|
return existsSync(file) ? validateRelease(readJson(file)) : undefined;
|
|
23
27
|
}
|
|
24
|
-
/**
|
|
28
|
+
/** Local SDK archives keep their manifest-relative paths; release archives become portable project-relative files. */
|
|
25
29
|
export function packageSources(manifest, release = installedRelease()) {
|
|
26
30
|
let sources;
|
|
27
31
|
if (manifest) {
|
|
@@ -36,7 +40,84 @@ export function packageSources(manifest, release = installedRelease()) {
|
|
|
36
40
|
if (!release)
|
|
37
41
|
throw new Error("This SDK has no published release metadata. Pack or register a local SDK first.");
|
|
38
42
|
validateRelease(release);
|
|
39
|
-
sources = { ...Object.fromEntries(Object.entries(release.packages).map(([name, asset]) => [name, asset
|
|
43
|
+
sources = { ...Object.fromEntries(Object.entries(release.packages).map(([name, asset]) => [name, `file:./spark-packages/${packageArchiveName(name, asset)}`])), "@legendapp/spark": VERSION };
|
|
40
44
|
}
|
|
41
45
|
return sources;
|
|
42
46
|
}
|
|
47
|
+
function packageArchiveName(name, asset) {
|
|
48
|
+
return `${name.replace(/^@/, "").replaceAll("/", "-")}-${asset.sha256}.tgz`;
|
|
49
|
+
}
|
|
50
|
+
/** Download and verify release bytes before installing; relative vendored files survive moves and ordinary clones. */
|
|
51
|
+
export async function materializeReleasePackages(release, projectRoot, fetcher = fetch) {
|
|
52
|
+
validateRelease(release);
|
|
53
|
+
const directory = path.join(projectRoot, "spark-packages");
|
|
54
|
+
mkdirSync(directory, { recursive: true });
|
|
55
|
+
const pending = Object.entries(release.packages).map(([name, asset]) => ({ name, asset, file: path.join(directory, packageArchiveName(name, asset)) }));
|
|
56
|
+
for (const { name, asset, file } of pending) {
|
|
57
|
+
if (!existsSync(file))
|
|
58
|
+
continue;
|
|
59
|
+
const bytes = readFileSync(file);
|
|
60
|
+
if (bytes.length !== asset.size || createHash("sha256").update(bytes).digest("hex") !== asset.sha256)
|
|
61
|
+
throw new Error(`Existing verified Spark package archive is corrupt: ${name}`);
|
|
62
|
+
}
|
|
63
|
+
for (const { name, asset, file } of pending) {
|
|
64
|
+
if (existsSync(file))
|
|
65
|
+
continue;
|
|
66
|
+
const response = await fetcher(asset.url, { signal: AbortSignal.timeout(120_000) });
|
|
67
|
+
if (!response.ok)
|
|
68
|
+
throw new Error(`Download Spark package ${name}: HTTP ${response.status}`);
|
|
69
|
+
const temporary = `${file}.tmp-${process.pid}-${randomUUID()}`;
|
|
70
|
+
const fd = openSync(temporary, "wx");
|
|
71
|
+
const hash = createHash("sha256");
|
|
72
|
+
let size = 0;
|
|
73
|
+
let open = true;
|
|
74
|
+
try {
|
|
75
|
+
if (!response.body)
|
|
76
|
+
throw new Error(`Download Spark package ${name}: response has no body`);
|
|
77
|
+
const reader = response.body.getReader();
|
|
78
|
+
try {
|
|
79
|
+
while (true) {
|
|
80
|
+
const { done, value } = await reader.read();
|
|
81
|
+
if (done)
|
|
82
|
+
break;
|
|
83
|
+
size += value.byteLength;
|
|
84
|
+
if (size > asset.size) {
|
|
85
|
+
await reader.cancel();
|
|
86
|
+
throw new Error(`Spark package archive exceeds its declared size: ${name}`);
|
|
87
|
+
}
|
|
88
|
+
hash.update(value);
|
|
89
|
+
let offset = 0;
|
|
90
|
+
while (offset < value.byteLength)
|
|
91
|
+
offset += writeSync(fd, value, offset, value.byteLength - offset);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
finally {
|
|
95
|
+
reader.releaseLock();
|
|
96
|
+
}
|
|
97
|
+
if (size !== asset.size || hash.digest("hex") !== asset.sha256)
|
|
98
|
+
throw new Error(`Spark package archive checksum or size mismatch: ${name}`);
|
|
99
|
+
closeSync(fd);
|
|
100
|
+
open = false;
|
|
101
|
+
renameSync(temporary, file);
|
|
102
|
+
}
|
|
103
|
+
catch (error) {
|
|
104
|
+
if (open)
|
|
105
|
+
closeSync(fd);
|
|
106
|
+
rmSync(temporary, { force: true });
|
|
107
|
+
throw error;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
/** Recheck vendored bytes immediately before a package manager can run lifecycle scripts. */
|
|
112
|
+
export function verifyMaterializedReleasePackages(release, projectRoot) {
|
|
113
|
+
validateRelease(release);
|
|
114
|
+
const directory = path.join(projectRoot, "spark-packages");
|
|
115
|
+
for (const [name, asset] of Object.entries(release.packages)) {
|
|
116
|
+
const file = path.join(directory, packageArchiveName(name, asset));
|
|
117
|
+
if (!existsSync(file))
|
|
118
|
+
throw new Error(`Verified Spark package archive is missing: ${name}`);
|
|
119
|
+
const bytes = readFileSync(file);
|
|
120
|
+
if (bytes.length !== asset.size || createHash("sha256").update(bytes).digest("hex") !== asset.sha256)
|
|
121
|
+
throw new Error(`Verified Spark package archive changed before installation: ${name}`);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
@@ -1,37 +1,42 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schema": 1,
|
|
3
|
-
"version": "0.0.1-next.
|
|
4
|
-
"revision": "
|
|
3
|
+
"version": "0.0.1-next.4",
|
|
4
|
+
"revision": "23bfaba5d57e9eda98422f1187fd65037ac11d01",
|
|
5
5
|
"packages": {
|
|
6
6
|
"@react-native-runtimes/core": {
|
|
7
|
-
"url": "https://github.com/LegendApp/legend-spark/releases/download/v0.0.1-next.
|
|
8
|
-
"size":
|
|
9
|
-
"sha256": "
|
|
7
|
+
"url": "https://github.com/LegendApp/legend-spark/releases/download/v0.0.1-next.4/runtimes-985164a87eb0.tgz",
|
|
8
|
+
"size": 53886,
|
|
9
|
+
"sha256": "138644fcfaf60b172c9f206c66c6d160515dd8803c70264687d0f503294c9c0b"
|
|
10
10
|
},
|
|
11
11
|
"react-native-nitro-modules": {
|
|
12
|
-
"url": "https://github.com/LegendApp/legend-spark/releases/download/v0.0.1-next.
|
|
13
|
-
"size":
|
|
14
|
-
"sha256": "
|
|
12
|
+
"url": "https://github.com/LegendApp/legend-spark/releases/download/v0.0.1-next.4/react-native-nitro-modules-0.37.0-56a36548e4e3.tgz",
|
|
13
|
+
"size": 145386,
|
|
14
|
+
"sha256": "56a36548e4e3236d3805dc75774a1c293034318d2825580c0b86d4079cce80ae"
|
|
15
15
|
},
|
|
16
16
|
"@op-engineering/op-sqlite": {
|
|
17
|
-
"url": "https://github.com/LegendApp/legend-spark/releases/download/v0.0.1-next.
|
|
18
|
-
"size":
|
|
19
|
-
"sha256": "
|
|
17
|
+
"url": "https://github.com/LegendApp/legend-spark/releases/download/v0.0.1-next.4/op-engineering-op-sqlite-18.2.1-809aacdae6a3.tgz",
|
|
18
|
+
"size": 112508531,
|
|
19
|
+
"sha256": "809aacdae6a375f1524022533800253ee89beb931cdb5ab02781acecfa53aeac"
|
|
20
20
|
},
|
|
21
21
|
"react-native-webview": {
|
|
22
|
-
"url": "https://github.com/LegendApp/legend-spark/releases/download/v0.0.1-next.
|
|
23
|
-
"size":
|
|
24
|
-
"sha256": "
|
|
22
|
+
"url": "https://github.com/LegendApp/legend-spark/releases/download/v0.0.1-next.4/react-native-webview-16.0.0-bc2c08eb8de7.tgz",
|
|
23
|
+
"size": 116287,
|
|
24
|
+
"sha256": "bc2c08eb8de7b979d90a641ce63b3241c034f836c76c77b794716473b3b43216"
|
|
25
|
+
},
|
|
26
|
+
"expo-audio": {
|
|
27
|
+
"url": "https://github.com/LegendApp/legend-spark/releases/download/v0.0.1-next.4/expo-audio-1.1.1-c4ae56565c36.tgz",
|
|
28
|
+
"size": 381084,
|
|
29
|
+
"sha256": "c4ae56565c365086e134ab9edd15ce981a2149bda07d9e9553e151def5fe7fec"
|
|
25
30
|
}
|
|
26
31
|
},
|
|
27
32
|
"runners": {
|
|
28
33
|
"macos-arm64": {
|
|
29
|
-
"url": "https://github.com/LegendApp/legend-spark/releases/download/v0.0.1-next.
|
|
30
|
-
"size":
|
|
31
|
-
"sha256": "
|
|
34
|
+
"url": "https://github.com/LegendApp/legend-spark/releases/download/v0.0.1-next.4/spark-runner-macos-arm64.zip",
|
|
35
|
+
"size": 17395353,
|
|
36
|
+
"sha256": "6334c66020c8ddd0ff3f6c154b8fb97e01ceb952a26254765b816bd6055dabb1",
|
|
32
37
|
"app": "SparkRunner.app",
|
|
33
38
|
"teamId": "56DD97VT22",
|
|
34
|
-
"fingerprint": "
|
|
39
|
+
"fingerprint": "64932dc5718a49253e5f76a9ae26c3553059893b1e0c6dcff7b05f86c2c787e2"
|
|
35
40
|
}
|
|
36
41
|
}
|
|
37
42
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
|
-
import { closeSync, existsSync, mkdirSync, mkdtempSync, openSync, readFileSync, renameSync, rmSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { closeSync, existsSync, ftruncateSync, lstatSync, mkdirSync, mkdtempSync, openSync, readFileSync, renameSync, rmSync, statSync, writeFileSync } from "node:fs";
|
|
3
|
+
import { spawn } from "node:child_process";
|
|
3
4
|
import { open } from "node:fs/promises";
|
|
4
5
|
import path from "node:path";
|
|
5
6
|
import { setTimeout as sleep } from "node:timers/promises";
|
|
@@ -9,6 +10,142 @@ import { architecture } from "./platform.js";
|
|
|
9
10
|
import { VERSION } from "./project.js";
|
|
10
11
|
import { installedRelease } from "./release.js";
|
|
11
12
|
const defaults = { fetch: globalThis.fetch, run };
|
|
13
|
+
function readLegacyPid(lock) {
|
|
14
|
+
try {
|
|
15
|
+
const content = readFileSync(lock, "utf8").trim();
|
|
16
|
+
if (/^\d+$/.test(content))
|
|
17
|
+
return Number(content);
|
|
18
|
+
}
|
|
19
|
+
catch (error) {
|
|
20
|
+
if (error.code !== "ENOENT")
|
|
21
|
+
throw error;
|
|
22
|
+
}
|
|
23
|
+
return undefined;
|
|
24
|
+
}
|
|
25
|
+
/** The kernel releases this advisory lock if the installer exits, including on a crash. */
|
|
26
|
+
export async function acquireRunnerLock(lock, waitMs = 600_000) {
|
|
27
|
+
const deadline = Date.now() + waitMs;
|
|
28
|
+
let child;
|
|
29
|
+
let exited;
|
|
30
|
+
while (true) {
|
|
31
|
+
if (Date.now() >= deadline)
|
|
32
|
+
throw new Error("Another process is installing Runner. Retry desktop launch when it finishes.");
|
|
33
|
+
const existingPid = readLegacyPid(lock);
|
|
34
|
+
if (existingPid) {
|
|
35
|
+
try {
|
|
36
|
+
process.kill(existingPid, 0);
|
|
37
|
+
if (Date.now() >= deadline)
|
|
38
|
+
throw new Error("Another process is installing Runner. Retry desktop launch when it finishes.");
|
|
39
|
+
await sleep(Math.min(1000, deadline - Date.now()));
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
if (error.code !== "ESRCH")
|
|
44
|
+
throw error;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
const existed = existsSync(lock);
|
|
48
|
+
const observed = existed ? lstatSync(lock) : undefined;
|
|
49
|
+
const remaining = Math.max(1, deadline - Date.now());
|
|
50
|
+
child = spawn("/usr/bin/lockf", ["-k", "-t", String(Math.max(1, Math.ceil(remaining / 1000))), lock, process.execPath, "-e", "process.stdout.write('locked\\n'); process.stdin.resume()"], { detached: true, stdio: ["pipe", "pipe", "pipe"] });
|
|
51
|
+
let stderr = "";
|
|
52
|
+
child.stderr.setEncoding("utf8").on("data", chunk => { stderr += chunk; });
|
|
53
|
+
exited = new Promise(resolve => child.once("close", (code, signal) => resolve({ code, signal })));
|
|
54
|
+
try {
|
|
55
|
+
await new Promise((resolve, reject) => {
|
|
56
|
+
let output = "";
|
|
57
|
+
child.stdout.setEncoding("utf8").on("data", chunk => {
|
|
58
|
+
output += chunk;
|
|
59
|
+
if (output.includes("locked\n"))
|
|
60
|
+
resolve();
|
|
61
|
+
});
|
|
62
|
+
child.once("error", reject);
|
|
63
|
+
void exited.then(({ code }) => reject(new Error(`Could not acquire Runner install lock${stderr ? `: ${stderr.trim()}` : ` (lockf exited ${code})`}`)));
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
catch (error) {
|
|
67
|
+
try {
|
|
68
|
+
process.kill(-child.pid, "SIGTERM");
|
|
69
|
+
}
|
|
70
|
+
catch { }
|
|
71
|
+
await exited;
|
|
72
|
+
throw error;
|
|
73
|
+
}
|
|
74
|
+
const stopKeeper = async () => { child.stdin.end(); await exited; };
|
|
75
|
+
let fd;
|
|
76
|
+
try {
|
|
77
|
+
const acquired = lstatSync(lock);
|
|
78
|
+
if (observed && (acquired.dev !== observed.dev || acquired.ino !== observed.ino)) {
|
|
79
|
+
await stopKeeper();
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
const content = readFileSync(lock, "utf8").trim();
|
|
83
|
+
const legacyPid = readLegacyPid(lock);
|
|
84
|
+
if (legacyPid) {
|
|
85
|
+
let legacyLive = false;
|
|
86
|
+
try {
|
|
87
|
+
process.kill(legacyPid, 0);
|
|
88
|
+
legacyLive = true;
|
|
89
|
+
}
|
|
90
|
+
catch (error) {
|
|
91
|
+
if (error.code !== "ESRCH")
|
|
92
|
+
throw error;
|
|
93
|
+
}
|
|
94
|
+
if (legacyLive) {
|
|
95
|
+
await stopKeeper();
|
|
96
|
+
if (Date.now() >= deadline)
|
|
97
|
+
throw new Error("Another process is installing Runner. Retry desktop launch when it finishes.");
|
|
98
|
+
await sleep(Math.min(1000, deadline - Date.now()));
|
|
99
|
+
continue;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
else if (!content && existed) {
|
|
103
|
+
const age = Date.now() - statSync(lock).mtimeMs;
|
|
104
|
+
if (age < 30_000) {
|
|
105
|
+
await stopKeeper();
|
|
106
|
+
if (Date.now() >= deadline)
|
|
107
|
+
throw new Error("Another process is installing Runner. Retry desktop launch when it finishes.");
|
|
108
|
+
await sleep(Math.min(1000, deadline - Date.now()));
|
|
109
|
+
continue;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
fd = openSync(lock, "r+");
|
|
113
|
+
ftruncateSync(fd, 0);
|
|
114
|
+
writeFileSync(fd, `v2:${process.pid}`);
|
|
115
|
+
closeSync(fd);
|
|
116
|
+
fd = undefined;
|
|
117
|
+
break;
|
|
118
|
+
}
|
|
119
|
+
catch (error) {
|
|
120
|
+
if (fd !== undefined) {
|
|
121
|
+
try {
|
|
122
|
+
closeSync(fd);
|
|
123
|
+
}
|
|
124
|
+
catch { }
|
|
125
|
+
}
|
|
126
|
+
await stopKeeper();
|
|
127
|
+
throw error;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
let released = false;
|
|
131
|
+
let releasePromise;
|
|
132
|
+
let unexpectedExit;
|
|
133
|
+
void exited.then(result => { if (!released)
|
|
134
|
+
unexpectedExit = result; });
|
|
135
|
+
const release = () => releasePromise ??= (async () => {
|
|
136
|
+
released = true;
|
|
137
|
+
child.stdin.end();
|
|
138
|
+
const result = await exited;
|
|
139
|
+
if (result.code !== 0)
|
|
140
|
+
throw new Error(`Runner install lock process exited unexpectedly (${result.signal ?? result.code}).`);
|
|
141
|
+
})();
|
|
142
|
+
return Object.assign(release, {
|
|
143
|
+
assertAlive() {
|
|
144
|
+
if (unexpectedExit)
|
|
145
|
+
throw new Error(`Runner install lock process exited unexpectedly (${unexpectedExit.signal ?? unexpectedExit.code}).`);
|
|
146
|
+
},
|
|
147
|
+
});
|
|
148
|
+
}
|
|
12
149
|
export async function downloadAsset(asset, file, request = globalThis.fetch) {
|
|
13
150
|
for (let attempt = 0; attempt < 3; attempt++) {
|
|
14
151
|
let handle;
|
|
@@ -50,7 +187,7 @@ export async function downloadAsset(asset, file, request = globalThis.fetch) {
|
|
|
50
187
|
}
|
|
51
188
|
async function verify(app, asset, deps) {
|
|
52
189
|
const runtime = readRuntime(app);
|
|
53
|
-
if (!runtime || runtime.mode !== "go" || runtime.platform !== "macos" || runtime.arch !== "
|
|
190
|
+
if (!runtime || runtime.mode !== "go" || runtime.platform !== "macos" || runtime.arch !== architecture("macos") || runtime.fingerprint !== asset.fingerprint)
|
|
54
191
|
throw new Error("Downloaded Runner has incompatible runtime metadata");
|
|
55
192
|
await deps.run(path.dirname(app), ["codesign", "--verify", "--deep", "--strict", app], { capture: true });
|
|
56
193
|
const signature = await deps.run(path.dirname(app), ["codesign", "-dvvv", app], { capture: true });
|
|
@@ -65,32 +202,7 @@ export async function installRunner(asset, cache = sparkHome(), deps = defaults)
|
|
|
65
202
|
const app = path.join(destination, asset.app);
|
|
66
203
|
mkdirSync(parent, { recursive: true });
|
|
67
204
|
const lock = `${destination}.lock`;
|
|
68
|
-
|
|
69
|
-
for (let attempt = 0; !owned && attempt < 600; attempt++) {
|
|
70
|
-
try {
|
|
71
|
-
const fd = openSync(lock, "wx");
|
|
72
|
-
writeFileSync(fd, String(process.pid));
|
|
73
|
-
closeSync(fd);
|
|
74
|
-
owned = true;
|
|
75
|
-
}
|
|
76
|
-
catch (error) {
|
|
77
|
-
if (error.code !== "EEXIST")
|
|
78
|
-
throw error;
|
|
79
|
-
const pid = Number(readFileSync(lock, "utf8"));
|
|
80
|
-
if (Number.isInteger(pid) && pid > 0) {
|
|
81
|
-
try {
|
|
82
|
-
process.kill(pid, 0);
|
|
83
|
-
}
|
|
84
|
-
catch (probe) {
|
|
85
|
-
if (probe.code === "ESRCH")
|
|
86
|
-
rmSync(lock, { force: true });
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
await sleep(1000);
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
if (!owned)
|
|
93
|
-
throw new Error("Another process is installing Runner. Retry desktop launch when it finishes.");
|
|
205
|
+
const releaseLock = await acquireRunnerLock(lock);
|
|
94
206
|
let staging;
|
|
95
207
|
try {
|
|
96
208
|
if (existsSync(app)) {
|
|
@@ -110,8 +222,10 @@ export async function installRunner(asset, cache = sparkHome(), deps = defaults)
|
|
|
110
222
|
// Only publisher-pinned bytes reach the platform extractor.
|
|
111
223
|
await deps.run(staging, ["ditto", "-x", "-k", archive, unpacked], { capture: true });
|
|
112
224
|
await verify(path.join(unpacked, asset.app), asset, deps);
|
|
225
|
+
releaseLock.assertAlive();
|
|
113
226
|
renameSync(unpacked, destination);
|
|
114
227
|
}
|
|
228
|
+
releaseLock.assertAlive();
|
|
115
229
|
registerRuntime(app);
|
|
116
230
|
console.log("Spark Runner installed and verified.");
|
|
117
231
|
return app;
|
|
@@ -119,7 +233,7 @@ export async function installRunner(asset, cache = sparkHome(), deps = defaults)
|
|
|
119
233
|
finally {
|
|
120
234
|
if (staging)
|
|
121
235
|
rmSync(staging, { recursive: true, force: true });
|
|
122
|
-
|
|
236
|
+
await releaseLock();
|
|
123
237
|
}
|
|
124
238
|
}
|
|
125
239
|
export async function acquireRunner(platform) {
|
|
@@ -130,8 +244,8 @@ export async function acquireRunner(platform) {
|
|
|
130
244
|
const asset = release.runners[target];
|
|
131
245
|
if (!asset)
|
|
132
246
|
throw new Error(`This Spark release has no Runner for ${target}. Use a custom development build.`);
|
|
133
|
-
if (process.platform !== "darwin"
|
|
134
|
-
throw new Error("This release's Runner requires
|
|
247
|
+
if (process.platform !== "darwin")
|
|
248
|
+
throw new Error("This release's macOS Runner requires macOS.");
|
|
135
249
|
app = await installRunner(asset);
|
|
136
250
|
}
|
|
137
251
|
return app;
|