@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
|
@@ -134,7 +134,7 @@ export async function validateApp(root, app, credentials, expected, notarized, e
|
|
|
134
134
|
app = realpathSync(app);
|
|
135
135
|
if (expected.runner) {
|
|
136
136
|
const runtime = readJson(path.join(app, "Contents/Resources/spark-runtime.json"));
|
|
137
|
-
if (runtime.mode !== "go" || runtime.platform !== "macos" || runtime.arch !==
|
|
137
|
+
if (runtime.mode !== "go" || runtime.platform !== "macos" || runtime.arch !== expected.arch)
|
|
138
138
|
throw new Error("Distribution app is not a macOS Spark Runner.");
|
|
139
139
|
}
|
|
140
140
|
else if (!existsSync(path.join(app, "Contents/Resources/main.jsbundle")))
|
|
@@ -145,8 +145,9 @@ export async function validateApp(root, app, credentials, expected, notarized, e
|
|
|
145
145
|
throw new Error(`Packaged ${key} does not match the release build.`);
|
|
146
146
|
}
|
|
147
147
|
const arches = (await execute(root, ["lipo", "-archs", path.join(app, "Contents/MacOS", info.CFBundleExecutable)], { capture: true })).trim().split(/\s+/);
|
|
148
|
-
|
|
149
|
-
|
|
148
|
+
const expectedArch = expected.arch === "x64" ? "x86_64" : "arm64";
|
|
149
|
+
if (arches.length !== 1 || arches[0] !== expectedArch)
|
|
150
|
+
throw new Error(`The package must contain a ${expectedArch} app.`);
|
|
150
151
|
await execute(root, ["codesign", "--verify", "--deep", "--strict", "--verbose=2", app], { capture: true });
|
|
151
152
|
const order = signingOrder(app);
|
|
152
153
|
const targets = await entitlementTargets(root, app, order, expected.entitlements, expected.byPath, execute);
|
|
@@ -2,13 +2,14 @@ const fs = require("node:fs");
|
|
|
2
2
|
const { readConfig, statePath, supportedPlatforms } = require("@legendapp/spark-desktop-config/config.cjs");
|
|
3
3
|
|
|
4
4
|
exports.nativeConfig = root => {
|
|
5
|
+
const patched = require("@legendapp/spark-desktop-config/native-patches.cjs").prepareNativePatches(root);
|
|
5
6
|
const { expo } = readConfig(root);
|
|
6
7
|
const platform = expo.platforms[0];
|
|
7
8
|
const platforms = process.platform === "win32" ? {} : { windows: { npmPackageName: "react-native-windows" } };
|
|
8
9
|
// Expo autolinking and React Native codegen have separate exclusion inputs.
|
|
9
10
|
// An excluded desktop provider must not enter an iOS module registry either.
|
|
10
11
|
const excluded = (expo.autolinking?.exclude ?? []).map(name => [name, { platforms: { ios: null, macos: null, android: null, windows: null } }]);
|
|
11
|
-
if (!["macos", "windows"].includes(platform)) return { platforms, dependencies: Object.fromEntries(excluded) };
|
|
12
|
+
if (!["macos", "windows"].includes(platform)) return { platforms, dependencies: { ...patched, ...Object.fromEntries(excluded) } };
|
|
12
13
|
const file = statePath(root, "native-selection.json");
|
|
13
14
|
const selection = fs.existsSync(file) ? JSON.parse(fs.readFileSync(file, "utf8")) : { included: [], excluded: [] };
|
|
14
15
|
return { platforms, dependencies: Object.fromEntries([
|
|
@@ -60,19 +60,56 @@ export function verifyUpdateSignature(archive, signature, publicKey) {
|
|
|
60
60
|
if (!/^[A-Za-z0-9+/]{86}==$/.test(signature) || !verify(null, readFileSync(archive), key, Buffer.from(signature, "base64")))
|
|
61
61
|
throw new Error("Update signature does not match the app's public key or archive");
|
|
62
62
|
}
|
|
63
|
+
const buildNumberPattern = /^[0-9]+(?:\.[0-9]+){0,2}$/;
|
|
64
|
+
function buildNumberParts(version) { return version.split(".").map(part => part.replace(/^0+(?=\d)/, "")); }
|
|
65
|
+
function canonicalBuildNumber(version) { return buildNumberParts(version).concat(["0", "0"]).slice(0, 3).join("."); }
|
|
66
|
+
function compareBuildNumbers(left, right) {
|
|
67
|
+
const a = buildNumberParts(left), b = buildNumberParts(right);
|
|
68
|
+
for (let index = 0; index < 3; index++) {
|
|
69
|
+
const x = a[index] ?? "0", y = b[index] ?? "0";
|
|
70
|
+
if (x.length !== y.length)
|
|
71
|
+
return x.length < y.length ? -1 : 1;
|
|
72
|
+
if (x !== y)
|
|
73
|
+
return x < y ? -1 : 1;
|
|
74
|
+
}
|
|
75
|
+
return 0;
|
|
76
|
+
}
|
|
77
|
+
export function validateUpdateBuildVersion(buildVersion, records, archiveHash) {
|
|
78
|
+
if (!buildNumberPattern.test(buildVersion))
|
|
79
|
+
throw new Error("Updates require a numeric macOS buildNumber, increasing for every release");
|
|
80
|
+
const seen = new Map();
|
|
81
|
+
for (const version of Object.keys(records)) {
|
|
82
|
+
if (!buildNumberPattern.test(version))
|
|
83
|
+
throw new Error(`Invalid build number in Spark update history: ${version}`);
|
|
84
|
+
const canonical = canonicalBuildNumber(version);
|
|
85
|
+
const equivalent = seen.get(canonical);
|
|
86
|
+
if (equivalent && equivalent !== version)
|
|
87
|
+
throw new Error(`Spark update history reuses the numeric build number as both ${equivalent} and ${version}.`);
|
|
88
|
+
seen.set(canonical, version);
|
|
89
|
+
if (compareBuildNumbers(version, buildVersion) === 0 && version !== buildVersion)
|
|
90
|
+
throw new Error(`Build ${buildVersion} aliases the recorded build number ${version}; use a new increasing macos.buildNumber spelling.`);
|
|
91
|
+
}
|
|
92
|
+
const existing = records[buildVersion];
|
|
93
|
+
if (existing) {
|
|
94
|
+
if (existing.sha256 !== archiveHash)
|
|
95
|
+
throw new Error(`Build ${buildVersion} was already packaged with different bytes. Increase macos.buildNumber before publishing another update.`);
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
for (const version of Object.keys(records)) {
|
|
99
|
+
if (compareBuildNumbers(buildVersion, version) <= 0)
|
|
100
|
+
throw new Error(`Build ${buildVersion} must be greater than every published build number. Increase macos.buildNumber before publishing another update.`);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
63
103
|
export async function prepareUpdate(root, archive, buildVersion, dependencies = { run, tools: sparkleTools }) {
|
|
64
104
|
const expo = readAppConfig(root).expo;
|
|
65
105
|
const updates = updateConfiguration(expo);
|
|
66
106
|
if (!updates)
|
|
67
107
|
return undefined;
|
|
68
|
-
if (!/^[0-9]+(?:\.[0-9]+){0,2}$/.test(buildVersion))
|
|
69
|
-
throw new Error("Updates require a numeric macOS buildNumber, increasing for every release");
|
|
70
108
|
const directory = path.join(root, "dist/updates");
|
|
71
109
|
const recordsFile = path.join(directory, "releases.json");
|
|
72
110
|
const records = existsSync(recordsFile) ? readJson(recordsFile) : {};
|
|
73
111
|
const hash = createHash("sha256").update(readFileSync(archive)).digest("hex");
|
|
74
|
-
|
|
75
|
-
throw new Error(`Build ${buildVersion} was already packaged with different bytes. Increase macos.buildNumber before publishing another update.`);
|
|
112
|
+
validateUpdateBuildVersion(buildVersion, records, hash);
|
|
76
113
|
const bin = await dependencies.tools(root, dependencies.run);
|
|
77
114
|
const keyArgs = dependencies.keyFile ? ["--ed-key-file", dependencies.keyFile] : ["--account", account(expo)];
|
|
78
115
|
const signature = (await dependencies.run(root, [path.join(bin, "sign_update"), ...keyArgs, "-p", archive], { capture: true })).trim();
|
|
@@ -1,19 +1,13 @@
|
|
|
1
|
-
import { which } from "./process.js";
|
|
1
|
+
import { which, nodeCommand } from "./process.js";
|
|
2
2
|
import { prepareWindowsGeometry } from "./windows-geometry.js";
|
|
3
3
|
import { copyHelpers } from "./helpers.js";
|
|
4
4
|
import { registerWindowsAssociations } from "./windows-associations.js";
|
|
5
5
|
import { checkExpoDesktopNode } from "./expo-node.js";
|
|
6
6
|
import { cpSync, existsSync, mkdirSync, mkdtempSync, readdirSync, renameSync, rmSync, readFileSync, writeFileSync } from "node:fs";
|
|
7
7
|
import path from "node:path";
|
|
8
|
-
import { createRequire } from "node:module";
|
|
9
8
|
import { run } from "./commands.js";
|
|
10
9
|
import { prepareConfig, nativePackages, runtimeFor, stateFile, readJson, writeJson, validateBuildModules, goConfigurationIssues, readAppConfig } from "./project.js";
|
|
11
|
-
|
|
12
|
-
export function nodeCommand(root, name, bin, args = []) {
|
|
13
|
-
const req = createRequire(path.join(root, "package.json"));
|
|
14
|
-
const file = req.resolve(`${name}/package.json`), pkg = readJson(file);
|
|
15
|
-
return ["node", path.resolve(path.dirname(file), typeof pkg.bin === "string" ? pkg.bin : pkg.bin[bin]), ...args];
|
|
16
|
-
}
|
|
10
|
+
import { assertNativePatchPreflight } from "./native-patch-preflight.js";
|
|
17
11
|
export async function preserveWindowsBuildOutputs(root, prepare) {
|
|
18
12
|
const windows = path.join(root, "windows");
|
|
19
13
|
const outputs = [];
|
|
@@ -54,6 +48,7 @@ export async function preserveWindowsBuildOutputs(root, prepare) {
|
|
|
54
48
|
}
|
|
55
49
|
}
|
|
56
50
|
export async function prepareWindows(root, mode) {
|
|
51
|
+
assertNativePatchPreflight(root);
|
|
57
52
|
await checkExpoDesktopNode(root);
|
|
58
53
|
prepareConfig(root);
|
|
59
54
|
prepareWindowsGeometry(root);
|
|
@@ -70,7 +65,7 @@ export async function prepareWindows(root, mode) {
|
|
|
70
65
|
const manifest = readFileSync(path.join(root, "package.json"), "utf8");
|
|
71
66
|
try {
|
|
72
67
|
await preserveWindowsBuildOutputs(root, async () => {
|
|
73
|
-
await run(root, nodeCommand(root, "expo-desktop", "expo-desktop", ["prebuild", "--platform", "windows", "--template", "expo-desktop-template-bare-minimum@54.81.1
|
|
68
|
+
await run(root, nodeCommand(root, "expo-desktop", "expo-desktop", ["prebuild", "--platform", "windows", "--template", "expo-desktop-template-bare-minimum@54.81.1", "--no-install"]), { env: { CI: "1" }, capture: true });
|
|
74
69
|
});
|
|
75
70
|
// The beta template expands all-platform dependencies. Keep the consumer's installed graph.
|
|
76
71
|
}
|
|
@@ -82,6 +77,7 @@ export async function prepareWindows(root, mode) {
|
|
|
82
77
|
export async function buildWindows(root, mode, force) {
|
|
83
78
|
if (mode !== "go" && mode !== "dev")
|
|
84
79
|
throw new Error("Windows currently supports Spark Runner runtimes and development builds. Use spark build --dev; production builds and packaging are not implemented.");
|
|
80
|
+
assertNativePatchPreflight(root);
|
|
85
81
|
if (process.platform !== "win32")
|
|
86
82
|
throw new Error("Windows native builds require Windows x64 or ARM64. Project generation and Metro bundle checks can run on macOS.");
|
|
87
83
|
for (const tool of ["node", "pwsh.exe", "dotnet.exe"])
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@legendapp/spark-cli",
|
|
3
|
-
"version": "0.0.1-next.
|
|
3
|
+
"version": "0.0.1-next.4",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
@@ -11,12 +11,13 @@
|
|
|
11
11
|
"node": ">=24.19.0"
|
|
12
12
|
},
|
|
13
13
|
"dependencies": {
|
|
14
|
-
"@legendapp/spark-desktop-config": "0.0.1-next.
|
|
15
|
-
"ws": "8.
|
|
16
|
-
"expo-desktop": "1.0.0
|
|
17
|
-
"npm": "11.
|
|
14
|
+
"@legendapp/spark-desktop-config": "0.0.1-next.4",
|
|
15
|
+
"ws": "8.21.0",
|
|
16
|
+
"expo-desktop": "1.0.0",
|
|
17
|
+
"npm": "11.21.0",
|
|
18
18
|
"typescript": "5.9.3",
|
|
19
|
-
"cross-spawn": "7.0.6"
|
|
19
|
+
"cross-spawn": "7.0.6",
|
|
20
|
+
"@legendapp/spark-window-options": "0.0.1-next.4"
|
|
20
21
|
},
|
|
21
22
|
"private": true
|
|
22
23
|
}
|
|
@@ -1,22 +1,16 @@
|
|
|
1
|
-
import React, {
|
|
1
|
+
import React, { useState } from "react";
|
|
2
2
|
import { Button, StyleSheet, Text, View } from "react-native";
|
|
3
3
|
import { openFileDialog } from "@legendapp/spark/dialogs";
|
|
4
|
-
import {
|
|
4
|
+
import { useMenu, type MenuRootItem } from "@legendapp/spark/menus";
|
|
5
5
|
|
|
6
|
-
const menus = [{ id: "hello",
|
|
6
|
+
const menus: MenuRootItem[] = [{ type: "submenu", id: "hello", label: "Hello", items: [{ type: "action", id: "greet", label: "Say Hello" }] }];
|
|
7
7
|
export default function App({ runtime }: { runtime?: { mode: string } }) {
|
|
8
8
|
const [message, setMessage] = useState("Ready");
|
|
9
|
-
|
|
10
|
-
configureMenus("hello-world", menus);
|
|
11
|
-
const subscription = addNativeMenuActionListener(action => {
|
|
12
|
-
if (action.ownerId === "hello-world" && action.itemId === "greet") setMessage("Hello from the native menu");
|
|
13
|
-
});
|
|
14
|
-
return () => { subscription.remove(); clearMenus("hello-world"); };
|
|
15
|
-
}, []);
|
|
9
|
+
useMenu({ id: "hello-world", items: menus, onAction: action => { if (action.itemId === "greet") setMessage("Hello from the native menu"); }, onError: error => setMessage(String(error)) });
|
|
16
10
|
async function chooseFile() {
|
|
17
11
|
try {
|
|
18
|
-
const files = await openFileDialog({ title: "Choose a file",
|
|
19
|
-
setMessage(files
|
|
12
|
+
const files = await openFileDialog({ title: "Choose a file", multiple: false });
|
|
13
|
+
setMessage(files.canceled ? "Dialog cancelled" : files.paths.join(", "));
|
|
20
14
|
} catch (error) { setMessage(String(error)); }
|
|
21
15
|
}
|
|
22
16
|
return <View style={styles.root}>
|
package/vendor/node_modules/@legendapp/spark-cli/templates/blank-typescript/desktop.config.json
CHANGED
|
@@ -3,9 +3,11 @@
|
|
|
3
3
|
"name": "HelloWorld",
|
|
4
4
|
"version": "0.0.1",
|
|
5
5
|
"window": {
|
|
6
|
-
"
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
"size": {
|
|
7
|
+
"width": 1000,
|
|
8
|
+
"height": 700
|
|
9
|
+
},
|
|
10
|
+
"restoreBounds": true
|
|
9
11
|
},
|
|
10
12
|
"macos": {
|
|
11
13
|
"bundleIdentifier": "so.legend.spark.prototype.helloworld"
|
|
@@ -13,13 +13,13 @@
|
|
|
13
13
|
"postinstall": "node node_modules/@legendapp/spark/init-template.cjs"
|
|
14
14
|
},
|
|
15
15
|
"dependencies": {
|
|
16
|
-
"@legendapp/spark": "0.0.1-next.
|
|
16
|
+
"@legendapp/spark": "0.0.1-next.4",
|
|
17
17
|
"expo": "54.0.37",
|
|
18
|
-
"expo-desktop": "1.0.0
|
|
19
|
-
"expo-desktop-prebuild-config": "1.1.0
|
|
20
|
-
"expo-desktop-config-plugins": "1.2.0
|
|
21
|
-
"expo-desktop-metro-config": "54.81.0
|
|
22
|
-
"expo-desktop-template-bare-minimum": "54.81.1
|
|
18
|
+
"expo-desktop": "1.0.0",
|
|
19
|
+
"expo-desktop-prebuild-config": "1.1.0",
|
|
20
|
+
"expo-desktop-config-plugins": "1.2.0",
|
|
21
|
+
"expo-desktop-metro-config": "54.81.0",
|
|
22
|
+
"expo-desktop-template-bare-minimum": "54.81.1",
|
|
23
23
|
"react": "19.1.4",
|
|
24
24
|
"react-native": "0.81.6",
|
|
25
25
|
"react-native-macos": "0.81.7",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
},
|
|
31
31
|
"overrides": {
|
|
32
32
|
"@expo/cli": "54.0.27",
|
|
33
|
-
"react-native-nitro-modules": "0.
|
|
33
|
+
"react-native-nitro-modules": "0.37.0",
|
|
34
34
|
"react-native-webview": "16.0.0",
|
|
35
35
|
"@op-engineering/op-sqlite": "18.2.1",
|
|
36
36
|
"expo-asset": "12.0.13",
|
|
@@ -39,10 +39,12 @@
|
|
|
39
39
|
"expo-font": "14.0.12",
|
|
40
40
|
"expo-keep-awake": "15.0.8",
|
|
41
41
|
"expo-modules-core": "3.0.30",
|
|
42
|
-
"expo-desktop-modules-core": "54.0.14
|
|
43
|
-
"expo-desktop-stubs": "54.0.14
|
|
42
|
+
"expo-desktop-modules-core": "54.0.14",
|
|
43
|
+
"expo-desktop-stubs": "54.0.14",
|
|
44
44
|
"react": "19.1.4",
|
|
45
|
-
"react-native": "0.81.6"
|
|
45
|
+
"react-native": "0.81.6",
|
|
46
|
+
"react-native-macos": "0.81.7",
|
|
47
|
+
"react-native-windows": "0.81.35"
|
|
46
48
|
},
|
|
47
49
|
"expo": {
|
|
48
50
|
"install": {
|
|
@@ -5,8 +5,8 @@ import { runCommand } from "@legendapp/spark/processes";
|
|
|
5
5
|
export function Git({ onResult, onError }: { onResult(text: string): void; onError(message: string): void }) {
|
|
6
6
|
const [busy, setBusy] = useState(false);
|
|
7
7
|
return <Button disabled={busy} onPress={() => { setBusy(true); void (async () => {
|
|
8
|
-
const paths = await openFileDialog({
|
|
9
|
-
const result = await runCommand({ executable: "/usr/bin/git", args: ["--no-pager", "diff", "--no-ext-diff", "--no-textconv", "--", "."], cwd: paths[0], timeoutMs: 10_000 });
|
|
8
|
+
const paths = await openFileDialog({ selection: "directories" }); if (paths.canceled) return;
|
|
9
|
+
const result = await runCommand({ executable: "/usr/bin/git", args: ["--no-pager", "diff", "--no-ext-diff", "--no-textconv", "--", "."], cwd: paths.paths[0], timeoutMs: 10_000 });
|
|
10
10
|
if (result.timedOut || result.outputTruncated || result.exitCode !== 0) throw new Error(result.stderr || "Git comparison failed or exceeded its output limit");
|
|
11
11
|
onResult(result.stdout || "No unstaged changes.");
|
|
12
12
|
})().catch(error => onError(String(error))).finally(() => setBusy(false)); }}>{busy ? "Reading Git…" : "Open Git changes"}</Button>;
|
package/vendor/node_modules/@legendapp/spark-cli/templates/document-editor/Integration.macos.tsx
CHANGED
|
@@ -1,17 +1,30 @@
|
|
|
1
1
|
import { useEffect, useState } from "react";
|
|
2
2
|
import { Text } from "react-native";
|
|
3
3
|
import { Button } from "@legendapp/spark/ui";
|
|
4
|
-
import { beforeWindowClose, openWindow,
|
|
4
|
+
import { beforeWindowClose, openWindow, setWindowOptions, addWindowListener } from "@legendapp/spark/windows";
|
|
5
5
|
import { beforeQuit } from "@legendapp/spark/app";
|
|
6
|
-
import {
|
|
6
|
+
import { useMenu, type MenuItem } from "@legendapp/spark/menus";
|
|
7
7
|
import { registerShortcut } from "@legendapp/spark/shortcuts";
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
8
|
+
import { subscribeToOpenRequests } from "@legendapp/spark/app/documents";
|
|
9
|
+
import { readText } from "@legendapp/spark/files";
|
|
10
10
|
import { sessions } from "./sessions";
|
|
11
11
|
import type { DocumentSession } from "./document";
|
|
12
|
+
const items: MenuItem[] = [{ type: "submenu", id: "file", target: { menu: "file" }, label: "File", items: [
|
|
13
|
+
{ type: "action", id: "new", label: "New" }, { type: "action", id: "open", label: "Open…" }, { type: "action", id: "save", label: "Save" }, { type: "action", id: "saveAs", label: "Save As…" },
|
|
14
|
+
] }];
|
|
12
15
|
let nextWindow = 0;
|
|
13
16
|
export function Integration({ session, windowId, documentId, onReady }: { session: DocumentSession; windowId: string; documentId: string; onReady: (ready: boolean) => void }) {
|
|
14
17
|
const [error, setError] = useState<string | null>(null);
|
|
18
|
+
const menu = useMenu({ id: `editor-${windowId}`, items, onAction: event => {
|
|
19
|
+
const actions: Record<string, () => unknown> = { new: () => session.newDocument(), open: () => session.open(), save: () => session.save(), saveAs: () => session.save(true) };
|
|
20
|
+
actions[event.itemId]?.();
|
|
21
|
+
}, onError: error => setError(String(error)) });
|
|
22
|
+
useEffect(() => {
|
|
23
|
+
if (menu.status !== "ready") return;
|
|
24
|
+
let disposed = false, focus: Awaited<ReturnType<typeof addWindowListener>> | undefined;
|
|
25
|
+
void addWindowListener(windowId, "focusChanged", event => { if (event.focused) void menu.menu.update({ items }).catch(error => setError(String(error))); }).then(value => { if (disposed) void value.remove(); else focus = value; }).catch(error => setError(String(error)));
|
|
26
|
+
return () => { disposed = true; void focus?.remove(); };
|
|
27
|
+
}, [menu, windowId]);
|
|
15
28
|
useEffect(() => {
|
|
16
29
|
let removed = false;
|
|
17
30
|
const cleanups: (() => void | Promise<void>)[] = [];
|
|
@@ -19,17 +32,8 @@ export function Integration({ session, windowId, documentId, onReady }: { sessio
|
|
|
19
32
|
const subscription = await registration;
|
|
20
33
|
if (removed) await subscription.remove(); else cleanups.push(() => subscription.remove());
|
|
21
34
|
};
|
|
22
|
-
const owner = `editor-${windowId}`;
|
|
23
35
|
const actions: Record<string, () => unknown> = { new: () => session.newDocument(), open: () => session.open(), save: () => session.save(), saveAs: () => session.save(true) };
|
|
24
|
-
const
|
|
25
|
-
{ id: "new", title: "New" }, { id: "open", title: "Open…" }, { id: "save", title: "Save" }, { id: "saveAs", title: "Save As…" },
|
|
26
|
-
] }]);
|
|
27
|
-
menus(); cleanups.push(() => clearMenus(owner));
|
|
28
|
-
const menu = addNativeMenuActionListener(event => { if (event.ownerId === owner) actions[event.itemId]?.(); });
|
|
29
|
-
cleanups.push(() => menu.remove());
|
|
30
|
-
const focus = onWindowEvent(event => { if (event.type === "focus" && event.windowId === windowId) menus(); });
|
|
31
|
-
cleanups.push(() => focus.remove());
|
|
32
|
-
const title = () => { const state = session.getSnapshot(); void setWindowTitle(windowId, `${state.file.name}${session.dirty ? " •" : ""}`).catch(e => setError(String(e))); };
|
|
36
|
+
const title = () => { const state = session.getSnapshot(); void setWindowOptions(windowId, { title: `${state.file.name}${session.dirty ? " •" : ""}` }).catch(e => setError(String(e))); };
|
|
33
37
|
title(); cleanups.push(session.subscribe(title));
|
|
34
38
|
void (async () => {
|
|
35
39
|
await retain(beforeWindowClose(windowId, session.canClose));
|
|
@@ -38,12 +42,10 @@ export function Integration({ session, windowId, documentId, onReady }: { sessio
|
|
|
38
42
|
}
|
|
39
43
|
if (windowId === "main") {
|
|
40
44
|
await retain(beforeQuit(async () => { for (const document of sessions.values()) if (!await document.canClose()) return false; return true; }));
|
|
41
|
-
await retain(
|
|
42
|
-
if (event.type !== "
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
-
const location = decodeURIComponent(match[1]!);
|
|
46
|
-
void readTextFile(location).then(text => session.load({ location, name: location.split("/").pop()! }, text)).catch(e => setError(String(e)));
|
|
45
|
+
await retain(subscribeToOpenRequests(event => {
|
|
46
|
+
if (event.type !== "file") return;
|
|
47
|
+
const location = event.path;
|
|
48
|
+
void readText(location).then(text => session.load({ location, name: location.split("/").pop()! }, text)).catch(e => setError(String(e)));
|
|
47
49
|
}));
|
|
48
50
|
}
|
|
49
51
|
if (!removed) onReady(true);
|
|
@@ -51,7 +53,7 @@ export function Integration({ session, windowId, documentId, onReady }: { sessio
|
|
|
51
53
|
return () => { removed = true; for (const cleanup of cleanups.reverse()) void Promise.resolve().then(cleanup).catch(console.error); };
|
|
52
54
|
}, [session, windowId, onReady]);
|
|
53
55
|
return <>
|
|
54
|
-
<Button onPress={() => {
|
|
56
|
+
<Button onPress={() => { const id = `document-${++nextWindow}`; void openWindow({ id, title: session.getSnapshot().file.name, component: "main", size: { width: 800, height: 600 }, props: { windowId: id, windowProps: { documentId } } }).catch(e => setError(String(e))); }}>Open another view</Button>
|
|
55
57
|
{error ? <Text accessibilityRole="alert">{error}</Text> : null}
|
|
56
58
|
</>;
|
|
57
59
|
}
|
package/vendor/node_modules/@legendapp/spark-cli/templates/document-editor/Integration.windows.tsx
CHANGED
|
@@ -1,17 +1,30 @@
|
|
|
1
1
|
import { useEffect, useState } from "react";
|
|
2
2
|
import { Text } from "react-native";
|
|
3
3
|
import { Button } from "@legendapp/spark/ui";
|
|
4
|
-
import { beforeWindowClose, openWindow,
|
|
4
|
+
import { beforeWindowClose, openWindow, setWindowOptions, addWindowListener } from "@legendapp/spark/windows";
|
|
5
5
|
import { beforeQuit } from "@legendapp/spark/app";
|
|
6
|
-
import {
|
|
6
|
+
import { useMenu, type MenuItem } from "@legendapp/spark/menus";
|
|
7
7
|
import { registerShortcut } from "@legendapp/spark/shortcuts";
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
8
|
+
import { subscribeToOpenRequests } from "@legendapp/spark/app/documents";
|
|
9
|
+
import { readText } from "@legendapp/spark/files";
|
|
10
10
|
import { sessions } from "./sessions";
|
|
11
11
|
import type { DocumentSession } from "./document";
|
|
12
|
+
const items: MenuItem[] = [{ type: "submenu", id: "file", target: { menu: "file" }, label: "File", items: [
|
|
13
|
+
{ type: "action", id: "new", label: "New" }, { type: "action", id: "open", label: "Open…" }, { type: "action", id: "save", label: "Save" }, { type: "action", id: "saveAs", label: "Save As…" },
|
|
14
|
+
] }];
|
|
12
15
|
let nextWindow = 0;
|
|
13
16
|
export function Integration({ session, windowId, documentId, onReady }: { session: DocumentSession; windowId: string; documentId: string; onReady: (ready: boolean) => void }) {
|
|
14
17
|
const [error, setError] = useState<string | null>(null);
|
|
18
|
+
const menu = useMenu({ id: `editor-${windowId}`, items, onAction: event => {
|
|
19
|
+
const actions: Record<string, () => unknown> = { new: () => session.newDocument(), open: () => session.open(), save: () => session.save(), saveAs: () => session.save(true) };
|
|
20
|
+
actions[event.itemId]?.();
|
|
21
|
+
}, onError: error => setError(String(error)) });
|
|
22
|
+
useEffect(() => {
|
|
23
|
+
if (menu.status !== "ready") return;
|
|
24
|
+
let disposed = false, focus: Awaited<ReturnType<typeof addWindowListener>> | undefined;
|
|
25
|
+
void addWindowListener(windowId, "focusChanged", event => { if (event.focused) void menu.menu.update({ items }).catch(error => setError(String(error))); }).then(value => { if (disposed) void value.remove(); else focus = value; }).catch(error => setError(String(error)));
|
|
26
|
+
return () => { disposed = true; void focus?.remove(); };
|
|
27
|
+
}, [menu, windowId]);
|
|
15
28
|
useEffect(() => {
|
|
16
29
|
let removed = false;
|
|
17
30
|
const cleanups: (() => void | Promise<void>)[] = [];
|
|
@@ -19,17 +32,8 @@ export function Integration({ session, windowId, documentId, onReady }: { sessio
|
|
|
19
32
|
const subscription = await registration;
|
|
20
33
|
if (removed) await subscription.remove(); else cleanups.push(() => subscription.remove());
|
|
21
34
|
};
|
|
22
|
-
const owner = `editor-${windowId}`;
|
|
23
35
|
const actions: Record<string, () => unknown> = { new: () => session.newDocument(), open: () => session.open(), save: () => session.save(), saveAs: () => session.save(true) };
|
|
24
|
-
const
|
|
25
|
-
{ id: "new", title: "New" }, { id: "open", title: "Open…" }, { id: "save", title: "Save" }, { id: "saveAs", title: "Save As…" },
|
|
26
|
-
] }]);
|
|
27
|
-
menus(); cleanups.push(() => clearMenus(owner));
|
|
28
|
-
const menu = addNativeMenuActionListener(event => { if (event.ownerId === owner) actions[event.itemId]?.(); });
|
|
29
|
-
cleanups.push(() => menu.remove());
|
|
30
|
-
const focus = onWindowEvent(event => { if (event.type === "focus" && event.windowId === windowId) menus(); });
|
|
31
|
-
cleanups.push(() => focus.remove());
|
|
32
|
-
const title = () => { const state = session.getSnapshot(); void setWindowTitle(windowId, `${state.file.name}${session.dirty ? " •" : ""}`).catch(e => setError(String(e))); };
|
|
36
|
+
const title = () => { const state = session.getSnapshot(); void setWindowOptions(windowId, { title: `${state.file.name}${session.dirty ? " •" : ""}` }).catch(e => setError(String(e))); };
|
|
33
37
|
title(); cleanups.push(session.subscribe(title));
|
|
34
38
|
void (async () => {
|
|
35
39
|
await retain(beforeWindowClose(windowId, session.canClose));
|
|
@@ -38,12 +42,10 @@ export function Integration({ session, windowId, documentId, onReady }: { sessio
|
|
|
38
42
|
}
|
|
39
43
|
if (windowId === "main") {
|
|
40
44
|
await retain(beforeQuit(async () => { for (const document of sessions.values()) if (!await document.canClose()) return false; return true; }));
|
|
41
|
-
await retain(
|
|
42
|
-
if (event.type !== "
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
-
const location = decodeURIComponent(match[1]!).replace(/^\/([A-Za-z]:)/, "$1").replace(/\//g, "\\");
|
|
46
|
-
void readTextFile(location).then(text => session.load({ location, name: location.split("/").pop()! }, text)).catch(e => setError(String(e)));
|
|
45
|
+
await retain(subscribeToOpenRequests(event => {
|
|
46
|
+
if (event.type !== "file") return;
|
|
47
|
+
const location = event.path;
|
|
48
|
+
void readText(location).then(text => session.load({ location, name: location.split("/").pop()! }, text)).catch(e => setError(String(e)));
|
|
47
49
|
}));
|
|
48
50
|
}
|
|
49
51
|
if (!removed) onReady(true);
|
|
@@ -51,7 +53,7 @@ export function Integration({ session, windowId, documentId, onReady }: { sessio
|
|
|
51
53
|
return () => { removed = true; for (const cleanup of cleanups.reverse()) void Promise.resolve().then(cleanup).catch(console.error); };
|
|
52
54
|
}, [session, windowId, onReady]);
|
|
53
55
|
return <>
|
|
54
|
-
<Button onPress={() => {
|
|
56
|
+
<Button onPress={() => { const id = `document-${++nextWindow}`; void openWindow({ id, title: session.getSnapshot().file.name, component: "main", size: { width: 800, height: 600 }, props: { windowId: id, windowProps: { documentId } } }).catch(e => setError(String(e))); }}>Open another view</Button>
|
|
55
57
|
{error ? <Text accessibilityRole="alert">{error}</Text> : null}
|
|
56
58
|
</>;
|
|
57
59
|
}
|
|
@@ -1,19 +1,22 @@
|
|
|
1
|
-
import { openFileDialog, saveFileDialog
|
|
1
|
+
import { openFileDialog, saveFileDialog } from "@legendapp/spark/dialogs";
|
|
2
|
+
import { readText, writeText, writeTextIfUnchanged } from "@legendapp/spark/files";
|
|
2
3
|
import { Alert } from "react-native";
|
|
3
4
|
import type { DocumentIO } from "./document";
|
|
4
5
|
export const io: DocumentIO = {
|
|
5
6
|
async open() {
|
|
6
|
-
const paths = await openFileDialog({
|
|
7
|
-
if (
|
|
8
|
-
const location = paths[0];
|
|
9
|
-
return { file: { location, name: location.split(/[\\/]/).pop()! }, text: await
|
|
7
|
+
const paths = await openFileDialog({ filters: [{ extensions: ["txt", "md", "json"] }], multiple: false });
|
|
8
|
+
if (paths.canceled) return null;
|
|
9
|
+
const location = paths.paths[0];
|
|
10
|
+
return { file: { location, name: location.split(/[\\/]/).pop()! }, text: await readText(location) };
|
|
10
11
|
},
|
|
11
12
|
async save(file, text, expected, saveAs) {
|
|
12
|
-
const
|
|
13
|
+
const result = saveAs || !file.location ? await saveFileDialog({ defaultName: file.name, filters: [{ extensions: ["txt", "md", "json"] }] }) : { canceled: false as const, path: file.location };
|
|
14
|
+
if (result.canceled) return null;
|
|
15
|
+
const location = result.path;
|
|
13
16
|
if (!location) return null;
|
|
14
17
|
if (location === file.location) {
|
|
15
|
-
if (!await
|
|
16
|
-
} else await
|
|
18
|
+
if (!(await writeTextIfUnchanged(location, expected, text)).written) throw new Error("The file changed outside the editor. Use Save As to keep your edits in another file.");
|
|
19
|
+
} else await writeText(location, text);
|
|
17
20
|
return { location, name: location.split(/[\\/]/).pop()! };
|
|
18
21
|
},
|
|
19
22
|
confirmDiscard: name => new Promise(resolve => Alert.alert("Unsaved changes", `Save changes to ${name}?`, [
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { io as desktop } from "./io.desktop";
|
|
2
|
-
import { showMessage } from "@legendapp/spark/
|
|
2
|
+
import { showMessage } from "@legendapp/spark/dialogs";
|
|
3
3
|
import type { DocumentIO } from "./document";
|
|
4
4
|
export const io: DocumentIO = { ...desktop, async confirmDiscard(name) {
|
|
5
|
-
const {
|
|
6
|
-
return
|
|
5
|
+
const { buttonId } = await showMessage({ title: "Unsaved changes", message: `Save changes to ${name}?`, buttons: [{ id: "cancel", label: "Cancel" }, { id: "discard", label: "Discard" }, { id: "save", label: "Save" }], cancelButtonId: "cancel", defaultButtonId: "save" });
|
|
6
|
+
return buttonId === "save" ? "save" : buttonId === "discard" ? "discard" : "cancel";
|
|
7
7
|
} };
|
package/vendor/node_modules/@legendapp/spark-cli/templates/example-shared/Lifecycle.desktop.tsx
CHANGED
|
@@ -1,25 +1,19 @@
|
|
|
1
1
|
import { useEffect } from "react";
|
|
2
2
|
import { Platform } from "react-native";
|
|
3
|
-
import { beforeWindowClose,
|
|
3
|
+
import { beforeWindowClose, setWindowOptions, addWindowListener } from "@legendapp/spark/windows";
|
|
4
4
|
import { beforeQuit } from "@legendapp/spark/app";
|
|
5
|
-
import {
|
|
6
|
-
import { registerShortcut
|
|
5
|
+
import { createMenu, type MenuItem } from "@legendapp/spark/menus";
|
|
6
|
+
import { registerShortcut } from "@legendapp/spark/shortcuts";
|
|
7
7
|
import { mountSerial } from "./lifetime";
|
|
8
8
|
import type { LifecycleProps } from "./lifecycle-types";
|
|
9
|
-
let activeMenuOwner: string | undefined;
|
|
10
9
|
export function Lifecycle({ title, windowId = "main", flush, quit, commands, onError }: LifecycleProps) {
|
|
11
|
-
useEffect(() => { void
|
|
10
|
+
useEffect(() => { void setWindowOptions(windowId, { title: title }).catch(error => onError(String(error))); }, [title, windowId, onError]);
|
|
12
11
|
useEffect(() => mountSerial(`window-${windowId}`, async retain => {
|
|
13
12
|
const owner = `example-${windowId}`;
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
};
|
|
19
|
-
menu();
|
|
20
|
-
await retain(Promise.resolve({ remove: () => { clearMenus(owner); if (activeMenuOwner === owner) activeMenuOwner = undefined; } }));
|
|
21
|
-
await retain(Promise.resolve(addNativeMenuActionListener(event => { if (event.ownerId === owner) commands.find(command => command.id === event.itemId)?.run(); })));
|
|
22
|
-
await retain(Promise.resolve(onWindowEvent(event => { if (event.windowId === windowId && event.type === "focus") menu(); })));
|
|
13
|
+
const items: MenuItem[] = [{ type: "submenu", id: "file", target: { menu: "file" }, label: "File", items: commands.map(({ id, title, key }) => ({ type: "action", id, label: title, shortcut: `CmdOrCtrl+${key}` })) }];
|
|
14
|
+
const menu = await createMenu({ id: owner, items, onAction: event => { commands.find(command => command.id === event.itemId)?.run(); } });
|
|
15
|
+
await retain(Promise.resolve(menu));
|
|
16
|
+
await retain(addWindowListener(windowId, "focusChanged", event => { if (event.focused) void menu.update({ items }).catch(error => onError(String(error))); }));
|
|
23
17
|
const guarded = (save: () => Promise<boolean>) => async () => {
|
|
24
18
|
try { return await save(); } catch (error) { onError(String(error)); return false; }
|
|
25
19
|
};
|
package/vendor/node_modules/@legendapp/spark-cli/templates/example-shared/OpenFiles.desktop.tsx
CHANGED
|
@@ -1,24 +1,19 @@
|
|
|
1
1
|
import { useEffect } from "react";
|
|
2
|
-
import {
|
|
3
|
-
import { onOpen } from "@legendapp/spark/links";
|
|
2
|
+
import { subscribeToOpenRequests } from "@legendapp/spark/app/documents";
|
|
4
3
|
import { mountSerial } from "./lifetime";
|
|
5
4
|
import type { OpenFilesProps } from "./OpenFiles";
|
|
6
|
-
//
|
|
5
|
+
// Each subscription replays queued launches to each subscription. Remounts must not import twice.
|
|
7
6
|
const imported = new Set<string>();
|
|
8
7
|
const importing = new Set<string>();
|
|
9
8
|
export function OpenFiles({ windowId = "main", onFile, onError }: OpenFilesProps) {
|
|
10
9
|
useEffect(() => {
|
|
11
10
|
if (windowId !== "main") return;
|
|
12
|
-
return mountSerial("file-activation", async retain => { await retain(
|
|
13
|
-
if (event.type !== "
|
|
11
|
+
return mountSerial("file-activation", async retain => { await retain(subscribeToOpenRequests(event => {
|
|
12
|
+
if (event.type !== "file") return;
|
|
14
13
|
if (imported.has(event.id) || importing.has(event.id)) return;
|
|
15
|
-
const match = /^file:\/\/(?:localhost)?(\/.*)$/.exec(event.url);
|
|
16
|
-
if (!match) { onError("Unsupported file URL"); return; }
|
|
17
14
|
importing.add(event.id);
|
|
18
15
|
void (async () => {
|
|
19
|
-
|
|
20
|
-
if (Platform.OS === "windows") path = path.replace(/^\/([a-z]:)/i, "$1").replace(/\//g, "\\");
|
|
21
|
-
await onFile(path);
|
|
16
|
+
await onFile(event.path);
|
|
22
17
|
imported.add(event.id);
|
|
23
18
|
if (imported.size > 200) imported.delete(imported.values().next().value!);
|
|
24
19
|
})().catch(error => onError(String(error))).finally(() => importing.delete(event.id));
|
|
@@ -1,19 +1,22 @@
|
|
|
1
|
-
import { openFileDialog, saveFileDialog
|
|
1
|
+
import { openFileDialog, saveFileDialog } from "@legendapp/spark/dialogs";
|
|
2
|
+
import { readText, writeText, writeTextIfUnchanged } from "@legendapp/spark/files";
|
|
2
3
|
import { Alert } from "react-native";
|
|
3
4
|
import type { DocumentIO } from "./document";
|
|
4
5
|
export const io: DocumentIO = {
|
|
5
6
|
async open() {
|
|
6
|
-
const paths = await openFileDialog({
|
|
7
|
-
if (
|
|
8
|
-
const location = paths[0];
|
|
9
|
-
return { file: { location, name: location.split(/[\\/]/).pop()! }, text: await
|
|
7
|
+
const paths = await openFileDialog({ filters: [{ extensions: ["txt", "md", "json"] }], multiple: false });
|
|
8
|
+
if (paths.canceled) return null;
|
|
9
|
+
const location = paths.paths[0];
|
|
10
|
+
return { file: { location, name: location.split(/[\\/]/).pop()! }, text: await readText(location) };
|
|
10
11
|
},
|
|
11
12
|
async save(file, text, expected, saveAs) {
|
|
12
|
-
const
|
|
13
|
+
const result = saveAs || !file.location ? await saveFileDialog({ defaultName: file.name, filters: [{ extensions: ["txt", "md", "json"] }] }) : { canceled: false as const, path: file.location };
|
|
14
|
+
if (result.canceled) return null;
|
|
15
|
+
const location = result.path;
|
|
13
16
|
if (!location) return null;
|
|
14
17
|
if (location === file.location) {
|
|
15
|
-
if (!await
|
|
16
|
-
} else await
|
|
18
|
+
if (!(await writeTextIfUnchanged(location, expected, text)).written) throw new Error("The file changed outside the editor. Use Save As to keep your edits in another file.");
|
|
19
|
+
} else await writeText(location, text);
|
|
17
20
|
return { location, name: location.split(/[\\/]/).pop()! };
|
|
18
21
|
},
|
|
19
22
|
confirmDiscard: name => new Promise(resolve => Alert.alert("Unsaved changes", `Save changes to ${name}?`, [
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { io as desktop } from "./io.desktop";
|
|
2
|
-
import { showMessage } from "@legendapp/spark/
|
|
2
|
+
import { showMessage } from "@legendapp/spark/dialogs";
|
|
3
3
|
import type { DocumentIO } from "./document";
|
|
4
4
|
export const io: DocumentIO = { ...desktop, async confirmDiscard(name) {
|
|
5
|
-
const {
|
|
6
|
-
return
|
|
5
|
+
const { buttonId } = await showMessage({ title: "Unsaved changes", message: `Save changes to ${name}?`, buttons: [{ id: "cancel", label: "Cancel" }, { id: "discard", label: "Discard" }, { id: "save", label: "Save" }], cancelButtonId: "cancel", defaultButtonId: "save" });
|
|
6
|
+
return buttonId === "save" ? "save" : buttonId === "discard" ? "discard" : "cancel";
|
|
7
7
|
} };
|