@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.
Files changed (422) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +10 -4
  3. package/ai-codex.ts +1 -0
  4. package/ai.ts +1 -0
  5. package/app-documents.ts +1 -0
  6. package/camera.ts +13 -0
  7. package/config-plugin.d.cts +2 -0
  8. package/contracts.ts +2 -0
  9. package/diagnostics.ts +1 -0
  10. package/expo-config.d.cts +1 -0
  11. package/metro.cjs +4 -1
  12. package/metro.d.cts +12 -0
  13. package/native.cjs +3 -1
  14. package/native.d.cts +6 -0
  15. package/package.json +93 -15
  16. package/patches/camera/react-native-nitro-image.patch +320 -0
  17. package/patches/camera/react-native-nitro-modules.patch +50 -0
  18. package/patches/camera/react-native-vision-camera.patch +2662 -0
  19. package/patches/camera/upstream.json +22 -0
  20. package/patches/dependencies.json +8 -0
  21. package/patches/react-native-enriched-markdown@1.0.2.patch +8684 -0
  22. package/postinstall.cjs +1 -0
  23. package/schema.json +276 -58
  24. package/settings-observable.ts +1 -0
  25. package/settings-window.ts +1 -0
  26. package/shortcuts-commands.ts +1 -0
  27. package/shortcuts-keyboard.ts +3 -0
  28. package/ui-classnames.ts +1 -0
  29. package/ui-glass.ts +1 -0
  30. package/ui-search.ts +1 -0
  31. package/ui-sidebar.ts +1 -0
  32. package/ui-split-view.ts +1 -0
  33. package/ui-swipe.ts +1 -0
  34. package/ui-symbol.ts +1 -0
  35. package/vendor/node_modules/@legendapp/spark-ai/package.json +19 -0
  36. package/vendor/node_modules/@legendapp/spark-ai/src/availability.ts +17 -0
  37. package/vendor/node_modules/@legendapp/spark-ai/src/index.ts +15 -0
  38. package/vendor/node_modules/@legendapp/spark-ai/src/invocations.ts +34 -0
  39. package/vendor/node_modules/@legendapp/spark-ai/src/output.ts +62 -0
  40. package/vendor/node_modules/@legendapp/spark-ai/src/run.ts +12 -0
  41. package/vendor/node_modules/@legendapp/spark-ai/src/types.ts +16 -0
  42. package/vendor/node_modules/@legendapp/spark-audio/macos/RNSparkAudio.h +2 -1
  43. package/vendor/node_modules/@legendapp/spark-audio/macos/RNSparkAudio.mm +126 -24
  44. package/vendor/node_modules/@legendapp/spark-audio/package.json +5 -2
  45. package/vendor/node_modules/@legendapp/spark-audio/src/NativeSparkAudio.ts +5 -1
  46. package/vendor/node_modules/@legendapp/spark-audio/src/desktop.ts +36 -32
  47. package/vendor/node_modules/@legendapp/spark-audio/src/events.ts +11 -0
  48. package/vendor/node_modules/@legendapp/spark-audio/src/hooks.ts +65 -0
  49. package/vendor/node_modules/@legendapp/spark-audio/src/index.web.ts +92 -33
  50. package/vendor/node_modules/@legendapp/spark-audio/src/media-session-unavailable.ts +6 -4
  51. package/vendor/node_modules/@legendapp/spark-audio/src/media-session.ts +52 -19
  52. package/vendor/node_modules/@legendapp/spark-audio/src/media-session.web.ts +18 -10
  53. package/vendor/node_modules/@legendapp/spark-audio/src/media-types.ts +40 -13
  54. package/vendor/node_modules/@legendapp/spark-audio/src/mobile.ts +40 -32
  55. package/vendor/node_modules/@legendapp/spark-audio/src/player.ts +97 -0
  56. package/vendor/node_modules/@legendapp/spark-audio/src/status-listeners.ts +21 -15
  57. package/vendor/node_modules/@legendapp/spark-audio/src/types.ts +9 -4
  58. package/vendor/node_modules/@legendapp/spark-audio/windows/SparkAudio/SparkAudio.h +67 -20
  59. package/vendor/node_modules/@legendapp/spark-auth-session/package.json +4 -3
  60. package/vendor/node_modules/@legendapp/spark-auth-session/src/core.ts +60 -42
  61. package/vendor/node_modules/@legendapp/spark-auth-session/src/index.ts +28 -12
  62. package/vendor/node_modules/@legendapp/spark-auth-session/src/mobile.ts +97 -41
  63. package/vendor/node_modules/@legendapp/spark-auth-session/src/types.ts +20 -9
  64. package/vendor/node_modules/@legendapp/spark-cli/dist/add-desktop.js +50 -7
  65. package/vendor/node_modules/@legendapp/spark-cli/dist/build-mode.js +1 -1
  66. package/vendor/node_modules/@legendapp/spark-cli/dist/build.js +145 -59
  67. package/vendor/node_modules/@legendapp/spark-cli/dist/cli-arguments.js +61 -0
  68. package/vendor/node_modules/@legendapp/spark-cli/dist/commands.js +10 -4
  69. package/vendor/node_modules/@legendapp/spark-cli/dist/create.js +37 -8
  70. package/vendor/node_modules/@legendapp/spark-cli/dist/credentials.js +86 -25
  71. package/vendor/node_modules/@legendapp/spark-cli/dist/dependency-pins.js +132 -0
  72. package/vendor/node_modules/@legendapp/spark-cli/dist/dev-command.js +13 -4
  73. package/vendor/node_modules/@legendapp/spark-cli/dist/dev.js +13 -10
  74. package/vendor/node_modules/@legendapp/spark-cli/dist/errors.js +100 -0
  75. package/vendor/node_modules/@legendapp/spark-cli/dist/examples.js +2 -2
  76. package/vendor/node_modules/@legendapp/spark-cli/dist/expo-dev-patch.cjs +4 -2
  77. package/vendor/node_modules/@legendapp/spark-cli/dist/expo-metro.cjs +1 -1
  78. package/vendor/node_modules/@legendapp/spark-cli/dist/expo-native.cjs +5 -1
  79. package/vendor/node_modules/@legendapp/spark-cli/dist/expo-node.js +3 -3
  80. package/vendor/node_modules/@legendapp/spark-cli/dist/helpers.js +1 -1
  81. package/vendor/node_modules/@legendapp/spark-cli/dist/index.js +52 -44
  82. package/vendor/node_modules/@legendapp/spark-cli/dist/json.js +16 -0
  83. package/vendor/node_modules/@legendapp/spark-cli/dist/local.js +1 -1
  84. package/vendor/node_modules/@legendapp/spark-cli/dist/metro.cjs +26 -5
  85. package/vendor/node_modules/@legendapp/spark-cli/dist/native-metadata.js +26 -0
  86. package/vendor/node_modules/@legendapp/spark-cli/dist/native-patch-preflight.js +86 -0
  87. package/vendor/node_modules/@legendapp/spark-cli/dist/native-preparation.js +88 -0
  88. package/vendor/node_modules/@legendapp/spark-cli/dist/notary-profiles.js +75 -0
  89. package/vendor/node_modules/@legendapp/spark-cli/dist/package.js +4 -2
  90. package/vendor/node_modules/@legendapp/spark-cli/dist/platform.js +16 -2
  91. package/vendor/node_modules/@legendapp/spark-cli/dist/process.js +7 -0
  92. package/vendor/node_modules/@legendapp/spark-cli/dist/project.js +90 -32
  93. package/vendor/node_modules/@legendapp/spark-cli/dist/release.js +86 -5
  94. package/vendor/node_modules/@legendapp/spark-cli/dist/release.json +23 -18
  95. package/vendor/node_modules/@legendapp/spark-cli/dist/runner-install.js +145 -31
  96. package/vendor/node_modules/@legendapp/spark-cli/dist/signing.js +4 -3
  97. package/vendor/node_modules/@legendapp/spark-cli/dist/universal.cjs +2 -1
  98. package/vendor/node_modules/@legendapp/spark-cli/dist/updates.js +41 -4
  99. package/vendor/node_modules/@legendapp/spark-cli/dist/windows.js +5 -9
  100. package/vendor/node_modules/@legendapp/spark-cli/package.json +7 -6
  101. package/vendor/node_modules/@legendapp/spark-cli/templates/blank-typescript/App.tsx +6 -12
  102. package/vendor/node_modules/@legendapp/spark-cli/templates/blank-typescript/desktop.config.json +5 -3
  103. package/vendor/node_modules/@legendapp/spark-cli/templates/blank-typescript/package.json +12 -10
  104. package/vendor/node_modules/@legendapp/spark-cli/templates/diff-lite/Git.macos.tsx +2 -2
  105. package/vendor/node_modules/@legendapp/spark-cli/templates/document-editor/Integration.macos.tsx +23 -21
  106. package/vendor/node_modules/@legendapp/spark-cli/templates/document-editor/Integration.windows.tsx +23 -21
  107. package/vendor/node_modules/@legendapp/spark-cli/templates/document-editor/io.desktop.ts +11 -8
  108. package/vendor/node_modules/@legendapp/spark-cli/templates/document-editor/io.macos.ts +3 -3
  109. package/vendor/node_modules/@legendapp/spark-cli/templates/example-shared/Lifecycle.desktop.tsx +8 -14
  110. package/vendor/node_modules/@legendapp/spark-cli/templates/example-shared/OpenFiles.desktop.tsx +5 -10
  111. package/vendor/node_modules/@legendapp/spark-cli/templates/example-shared/io.desktop.ts +11 -8
  112. package/vendor/node_modules/@legendapp/spark-cli/templates/example-shared/io.macos.ts +3 -3
  113. package/vendor/node_modules/@legendapp/spark-cli/templates/music-lite/assets.desktop.ts +2 -2
  114. package/vendor/node_modules/@legendapp/spark-cli/templates/notes-lite/Activation.desktop.tsx +2 -2
  115. package/vendor/node_modules/@legendapp/spark-cli/templates/notes-lite/Desktop.desktop.ts +37 -15
  116. package/vendor/node_modules/@legendapp/spark-cli/templates/notes-lite/session.ts +5 -6
  117. package/vendor/node_modules/@legendapp/spark-cli/templates/notes-lite/window-session.ts +5 -4
  118. package/vendor/node_modules/@legendapp/spark-cli/templates/universal/desktop.config.json +5 -3
  119. package/vendor/node_modules/@legendapp/spark-cli/templates/universal/metro.config.js +1 -1
  120. package/vendor/node_modules/@legendapp/spark-cli/templates/universal/package.json +14 -12
  121. package/vendor/node_modules/@legendapp/spark-cli/templates/universal/react-native.config.js +1 -1
  122. package/vendor/node_modules/@legendapp/spark-cli/templates/windows/package.json +14 -12
  123. package/vendor/node_modules/@legendapp/spark-cli/templates/windows/react-native.config.js +1 -1
  124. package/vendor/node_modules/@legendapp/spark-clipboard/macos/RNDesktopClipboard.mm +10 -16
  125. package/vendor/node_modules/@legendapp/spark-clipboard/package.json +2 -2
  126. package/vendor/node_modules/@legendapp/spark-clipboard/src/NativeDesktopClipboard.ts +1 -1
  127. package/vendor/node_modules/@legendapp/spark-clipboard/src/desktop.ts +55 -31
  128. package/vendor/node_modules/@legendapp/spark-clipboard/src/expo.ts +21 -11
  129. package/vendor/node_modules/@legendapp/spark-clipboard/src/options.ts +8 -0
  130. package/vendor/node_modules/@legendapp/spark-clipboard/src/types.ts +10 -0
  131. package/vendor/node_modules/@legendapp/spark-clipboard/windows/SparkClipboard/SparkClipboard.h +38 -15
  132. package/vendor/node_modules/@legendapp/spark-clipboard/windows/SparkClipboard/SparkClipboard.vcxproj +2 -0
  133. package/vendor/node_modules/@legendapp/spark-codex/RNCodex.podspec +22 -0
  134. package/vendor/node_modules/@legendapp/spark-codex/cpp/HybridCodexAppServer.hpp +23 -0
  135. package/vendor/node_modules/@legendapp/spark-codex/cpp/HybridCodexAppServer.mm +1529 -0
  136. package/vendor/node_modules/@legendapp/spark-codex/nitro.json +21 -0
  137. package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/.gitattributes +1 -0
  138. package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/ios/RNCodex+autolinking.rb +62 -0
  139. package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/ios/RNCodex-Swift-Cxx-Bridge.cpp +17 -0
  140. package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/ios/RNCodex-Swift-Cxx-Bridge.hpp +27 -0
  141. package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/ios/RNCodex-Swift-Cxx-Umbrella.hpp +38 -0
  142. package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/ios/RNCodexAutolinking.mm +35 -0
  143. package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/ios/RNCodexAutolinking.swift +16 -0
  144. package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/shared/c++/CodexAvailability.hpp +95 -0
  145. package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/shared/c++/CodexRunResult.hpp +99 -0
  146. package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/shared/c++/HybridCodexAppServerSpec.cpp +24 -0
  147. package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/shared/c++/HybridCodexAppServerSpec.hpp +71 -0
  148. package/vendor/node_modules/@legendapp/spark-codex/package.json +35 -0
  149. package/vendor/node_modules/@legendapp/spark-codex/react-native.config.js +11 -0
  150. package/vendor/node_modules/@legendapp/spark-codex/src/Codex.nitro.ts +30 -0
  151. package/vendor/node_modules/@legendapp/spark-codex/src/index.ts +65 -0
  152. package/vendor/node_modules/@legendapp/spark-codex/src/native.ts +6 -0
  153. package/vendor/node_modules/@legendapp/spark-commands/package.json +21 -0
  154. package/vendor/node_modules/@legendapp/spark-commands/src/bindings.ts +90 -0
  155. package/vendor/node_modules/@legendapp/spark-commands/src/index.tsx +400 -0
  156. package/vendor/node_modules/@legendapp/spark-commands/src/router.ts +138 -0
  157. package/vendor/node_modules/@legendapp/spark-commands/src/storage.ts +20 -0
  158. package/vendor/node_modules/@legendapp/spark-context-menu/macos/RNContextMenu.mm +7 -8
  159. package/vendor/node_modules/@legendapp/spark-context-menu/package.json +4 -3
  160. package/vendor/node_modules/@legendapp/spark-context-menu/src/NativeContextMenu.ts +1 -1
  161. package/vendor/node_modules/@legendapp/spark-context-menu/src/index.ts +26 -26
  162. package/vendor/node_modules/@legendapp/spark-context-menu/windows/SparkContextMenu/SparkContextMenu.h +3 -2
  163. package/vendor/node_modules/@legendapp/spark-desktop-app/RNDesktopApp.podspec +2 -1
  164. package/vendor/node_modules/@legendapp/spark-desktop-app/cpp/SparkBinaryJSI.hpp +89 -0
  165. package/vendor/node_modules/@legendapp/spark-desktop-app/cpp/SparkBinaryWindows.hpp +22 -0
  166. package/vendor/node_modules/@legendapp/spark-desktop-app/macos/RNDesktopApp.mm +13 -7
  167. package/vendor/node_modules/@legendapp/spark-desktop-app/macos/SparkBinaryJSI.h +48 -0
  168. package/vendor/node_modules/@legendapp/spark-desktop-app/macos/SparkDesktop.h +4 -0
  169. package/vendor/node_modules/@legendapp/spark-desktop-app/macos/SparkDesktop.mm +33 -33
  170. package/vendor/node_modules/@legendapp/spark-desktop-app/macos/SparkDesktopError.h +20 -0
  171. package/vendor/node_modules/@legendapp/spark-desktop-app/macos/SparkLifecycle.h +26 -0
  172. package/vendor/node_modules/@legendapp/spark-desktop-app/macos/SparkLifecycle.mm +49 -0
  173. package/vendor/node_modules/@legendapp/spark-desktop-app/macos/SparkQuitCoordinator.h +9 -0
  174. package/vendor/node_modules/@legendapp/spark-desktop-app/macos/SparkQuitCoordinator.mm +70 -0
  175. package/vendor/node_modules/@legendapp/spark-desktop-app/macos/SparkWindow.mm +9 -6
  176. package/vendor/node_modules/@legendapp/spark-desktop-app/macos/recent-documents/RNRecentDocumentController.mm +55 -0
  177. package/vendor/node_modules/@legendapp/spark-desktop-app/package.json +5 -3
  178. package/vendor/node_modules/@legendapp/spark-desktop-app/src/NativeDesktopApp.ts +1 -1
  179. package/vendor/node_modules/@legendapp/spark-desktop-app/src/api.ts +86 -40
  180. package/vendor/node_modules/@legendapp/spark-desktop-app/src/contracts/accelerator.ts +40 -0
  181. package/vendor/node_modules/@legendapp/spark-desktop-app/src/contracts/index.ts +56 -0
  182. package/vendor/node_modules/@legendapp/spark-desktop-app/src/contracts/menu.ts +116 -0
  183. package/vendor/node_modules/@legendapp/spark-desktop-app/src/contracts/native-buffer.ts +22 -0
  184. package/vendor/node_modules/@legendapp/spark-desktop-app/src/contracts/path.ts +24 -0
  185. package/vendor/node_modules/@legendapp/spark-desktop-app/src/events.ts +75 -0
  186. package/vendor/node_modules/@legendapp/spark-desktop-app/src/index.ts +2 -0
  187. package/vendor/node_modules/@legendapp/spark-desktop-app/src/index.windows.ts +2 -0
  188. package/vendor/node_modules/@legendapp/spark-desktop-app/src/open-requests.ts +43 -0
  189. package/vendor/node_modules/@legendapp/spark-desktop-app/src/restoration.ts +11 -0
  190. package/vendor/node_modules/@legendapp/spark-desktop-app/src/transport.ts +10 -0
  191. package/vendor/node_modules/@legendapp/spark-desktop-config/app.plugin.cjs +10 -5
  192. package/vendor/node_modules/@legendapp/spark-desktop-config/app.plugin.d.cts +3 -0
  193. package/vendor/node_modules/@legendapp/spark-desktop-config/autolinking.cjs +35 -0
  194. package/vendor/node_modules/@legendapp/spark-desktop-config/config.cjs +18 -3
  195. package/vendor/node_modules/@legendapp/spark-desktop-config/config.d.cts +89 -9
  196. package/vendor/node_modules/@legendapp/spark-desktop-config/expo.cjs +1 -0
  197. package/vendor/node_modules/@legendapp/spark-desktop-config/expo.d.cts +3 -0
  198. package/vendor/node_modules/@legendapp/spark-desktop-config/identity.cjs +3 -2
  199. package/vendor/node_modules/@legendapp/spark-desktop-config/lifecycle.cjs +20 -0
  200. package/vendor/node_modules/@legendapp/spark-desktop-config/native-patches.cjs +106 -0
  201. package/vendor/node_modules/@legendapp/spark-desktop-config/native-patches.d.cts +1 -0
  202. package/vendor/node_modules/@legendapp/spark-desktop-config/package.json +7 -5
  203. package/vendor/node_modules/@legendapp/spark-desktop-config/schema.json +276 -58
  204. package/vendor/node_modules/@legendapp/spark-desktop-config/updates.cjs +1 -0
  205. package/vendor/node_modules/@legendapp/spark-desktop-config/validation.cjs +35 -0
  206. package/vendor/node_modules/@legendapp/spark-desktop-config/windows.plugin.cjs +2 -1
  207. package/vendor/node_modules/@legendapp/spark-desktop-host/AppDelegate.mm +129 -11
  208. package/vendor/node_modules/@legendapp/spark-desktop-host/package.json +2 -2
  209. package/vendor/node_modules/@legendapp/spark-desktop-host/windows/application.inc +277 -121
  210. package/vendor/node_modules/@legendapp/spark-desktop-links/common/AuthLoopback.h +5 -7
  211. package/vendor/node_modules/@legendapp/spark-desktop-links/macos/RNDesktopLinks.mm +10 -9
  212. package/vendor/node_modules/@legendapp/spark-desktop-links/package.json +2 -2
  213. package/vendor/node_modules/@legendapp/spark-desktop-links/src/NativeDesktopLinks.ts +1 -1
  214. package/vendor/node_modules/@legendapp/spark-desktop-links/src/api.ts +27 -33
  215. package/vendor/node_modules/@legendapp/spark-desktop-links/src/expo.ts +3 -4
  216. package/vendor/node_modules/@legendapp/spark-desktop-links/src/native.ts +9 -0
  217. package/vendor/node_modules/@legendapp/spark-desktop-links/windows/SparkLinks/SparkLinks.h +22 -22
  218. package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/RNDesktopShortcuts.podspec +1 -0
  219. package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/macos/RNDesktopShortcuts.mm +1 -1
  220. package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/macos/keyboard-manager/RNKeyboardManager.h +9 -0
  221. package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/macos/keyboard-manager/RNKeyboardManager.mm +307 -0
  222. package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/package.json +8 -5
  223. package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/src/NativeDesktopShortcuts.ts +1 -1
  224. package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/src/api.ts +39 -14
  225. package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/src/keyboard-manager/NativeKeyboardManager.ts +12 -0
  226. package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/src/keyboard-manager/codes.ts +108 -0
  227. package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/src/keyboard-manager/index.ts +99 -0
  228. package/vendor/node_modules/@legendapp/spark-desktop-windows/RNDesktopWindows.podspec +2 -0
  229. package/vendor/node_modules/@legendapp/spark-desktop-windows/macos/RNDesktopWindows.mm +229 -103
  230. package/vendor/node_modules/@legendapp/spark-desktop-windows/macos/SparkWindowGeometry.h +63 -0
  231. package/vendor/node_modules/@legendapp/spark-desktop-windows/macos/window-manager/LegendWindowRegistry.h +20 -0
  232. package/vendor/node_modules/@legendapp/spark-desktop-windows/macos/window-manager/LegendWindowRegistry.mm +27 -0
  233. package/vendor/node_modules/@legendapp/spark-desktop-windows/macos/window-manager/RNWindowManager.h +12 -0
  234. package/vendor/node_modules/@legendapp/spark-desktop-windows/macos/window-manager/RNWindowManager.mm +3169 -0
  235. package/vendor/node_modules/@legendapp/spark-desktop-windows/macos/window-manager/RNWindowManagerStartup.mm +31 -0
  236. package/vendor/node_modules/@legendapp/spark-desktop-windows/macos/window-manager/SidebarStartupFallbacks.mm +14 -0
  237. package/vendor/node_modules/@legendapp/spark-desktop-windows/package.json +10 -6
  238. package/vendor/node_modules/@legendapp/spark-desktop-windows/src/NativeDesktopWindowManager.ts +1 -1
  239. package/vendor/node_modules/@legendapp/spark-desktop-windows/src/api.ts +146 -70
  240. package/vendor/node_modules/@legendapp/spark-desktop-windows/src/diagnostics.ts +17 -0
  241. package/vendor/node_modules/@legendapp/spark-desktop-windows/src/index.ts +3 -1
  242. package/vendor/node_modules/@legendapp/spark-desktop-windows/src/index.windows.ts +3 -1
  243. package/vendor/node_modules/@legendapp/spark-desktop-windows/src/macos-adapter.ts +53 -0
  244. package/vendor/node_modules/@legendapp/spark-desktop-windows/src/macos.ts +51 -0
  245. package/vendor/node_modules/@legendapp/spark-desktop-windows/src/transport.ts +41 -0
  246. package/vendor/node_modules/@legendapp/spark-desktop-windows/src/types.ts +140 -0
  247. package/vendor/node_modules/@legendapp/spark-desktop-windows/src/validation.ts +162 -0
  248. package/vendor/node_modules/@legendapp/spark-desktop-windows/src/window-manager/NativeWindowManager.ts +28 -0
  249. package/vendor/node_modules/@legendapp/spark-desktop-windows/src/windows/WindowProvider.tsx +20 -0
  250. package/vendor/node_modules/@legendapp/spark-desktop-windows/src/windows/createWindowsNavigator.tsx +78 -0
  251. package/vendor/node_modules/@legendapp/spark-desktop-windows/src/windows/index.ts +6 -0
  252. package/vendor/node_modules/@legendapp/spark-desktop-windows/src/windows/primaryWindowLifecycle.ts +34 -0
  253. package/vendor/node_modules/@legendapp/spark-desktop-windows/src/windows/types.ts +11 -0
  254. package/vendor/node_modules/@legendapp/spark-desktop-windows/src/windows/usePrimaryWindowLifecycle.ts +18 -0
  255. package/vendor/node_modules/@legendapp/spark-desktop-windows/src/windows/useWindowFocusEffect.ts +17 -0
  256. package/vendor/node_modules/@legendapp/spark-documents/package.json +22 -0
  257. package/vendor/node_modules/@legendapp/spark-documents/src/controller.ts +97 -0
  258. package/vendor/node_modules/@legendapp/spark-documents/src/documentTransition.ts +13 -0
  259. package/vendor/node_modules/@legendapp/spark-documents/src/hooks.ts +139 -0
  260. package/vendor/node_modules/@legendapp/spark-documents/src/index.tsx +50 -0
  261. package/vendor/node_modules/@legendapp/spark-documents/src/reload.ts +39 -0
  262. package/vendor/node_modules/@legendapp/spark-documents/src/requests.ts +15 -0
  263. package/vendor/node_modules/@legendapp/spark-drag-drop/package.json +4 -3
  264. package/vendor/node_modules/@legendapp/spark-drag-drop/src/DesktopDragViewNativeComponent.ts +1 -1
  265. package/vendor/node_modules/@legendapp/spark-drag-drop/src/contracts.ts +73 -18
  266. package/vendor/node_modules/@legendapp/spark-drag-drop/src/index.tsx +58 -15
  267. package/vendor/node_modules/@legendapp/spark-drag-drop/windows/SparkDragDrop/SparkDragDrop.h +14 -8
  268. package/vendor/node_modules/@legendapp/spark-file-dialog/ios/RNFileDialog.mm +34 -121
  269. package/vendor/node_modules/@legendapp/spark-file-dialog/package.json +12 -5
  270. package/vendor/node_modules/@legendapp/spark-file-dialog/src/NativeFileDialog.ts +1 -5
  271. package/vendor/node_modules/@legendapp/spark-file-dialog/src/index.ts +19 -84
  272. package/vendor/node_modules/@legendapp/spark-file-dialog/src/native.ts +12 -0
  273. package/vendor/node_modules/@legendapp/spark-file-dialog/src/options.ts +34 -14
  274. package/vendor/node_modules/@legendapp/spark-file-dialog/src/types.ts +26 -0
  275. package/vendor/node_modules/@legendapp/spark-file-dialog/windows/SparkFileDialog/SparkFileDialog.h +42 -58
  276. package/vendor/node_modules/@legendapp/spark-file-system/RNDesktopFileSystem.podspec +1 -0
  277. package/vendor/node_modules/@legendapp/spark-file-system/macos/RNDesktopFileSystem.mm +32 -21
  278. package/vendor/node_modules/@legendapp/spark-file-system/macos/SparkFileMutations.h +24 -0
  279. package/vendor/node_modules/@legendapp/spark-file-system/macos/SparkFileMutations.mm +215 -0
  280. package/vendor/node_modules/@legendapp/spark-file-system/macos/file-scanner/RNFileScanner.h +9 -0
  281. package/vendor/node_modules/@legendapp/spark-file-system/macos/file-scanner/RNFileScanner.mm +82 -0
  282. package/vendor/node_modules/@legendapp/spark-file-system/macos/file-scanner/RNFileScannerCore.h +47 -0
  283. package/vendor/node_modules/@legendapp/spark-file-system/macos/file-scanner/RNFileScannerCore.mm +306 -0
  284. package/vendor/node_modules/@legendapp/spark-file-system/package.json +8 -6
  285. package/vendor/node_modules/@legendapp/spark-file-system/src/NativeDesktopFileSystem.ts +1 -1
  286. package/vendor/node_modules/@legendapp/spark-file-system/src/file-scanner/NativeFileScanner.ts +11 -0
  287. package/vendor/node_modules/@legendapp/spark-file-system/src/file-scanner/index.ts +93 -0
  288. package/vendor/node_modules/@legendapp/spark-file-system/src/handles.ts +48 -14
  289. package/vendor/node_modules/@legendapp/spark-file-system/src/index.ts +134 -45
  290. package/vendor/node_modules/@legendapp/spark-file-system/src/path.ts +1 -9
  291. package/vendor/node_modules/@legendapp/spark-file-system/windows/SparkFileSystem/SparkFileSystem.h +102 -26
  292. package/vendor/node_modules/@legendapp/spark-file-system/windows/SparkFileSystem/SparkFileSystem.vcxproj +2 -0
  293. package/vendor/node_modules/@legendapp/spark-global-shortcuts/RNDesktopGlobalShortcuts.podspec +1 -0
  294. package/vendor/node_modules/@legendapp/spark-global-shortcuts/macos/RNDesktopGlobalShortcuts.mm +7 -4
  295. package/vendor/node_modules/@legendapp/spark-global-shortcuts/package.json +4 -3
  296. package/vendor/node_modules/@legendapp/spark-global-shortcuts/src/NativeDesktopGlobalShortcuts.ts +1 -1
  297. package/vendor/node_modules/@legendapp/spark-global-shortcuts/src/index.ts +39 -10
  298. package/vendor/node_modules/@legendapp/spark-global-shortcuts/windows/SparkGlobalShortcuts/SparkGlobalShortcuts.h +5 -4
  299. package/vendor/node_modules/@legendapp/spark-message-dialog/macos/RNDesktopMessageDialog.mm +2 -2
  300. package/vendor/node_modules/@legendapp/spark-message-dialog/package.json +2 -2
  301. package/vendor/node_modules/@legendapp/spark-message-dialog/src/NativeDesktopMessageDialog.ts +1 -1
  302. package/vendor/node_modules/@legendapp/spark-message-dialog/src/index.ts +48 -11
  303. package/vendor/node_modules/@legendapp/spark-native-menu/ios/RNNativeMenu.mm +141 -609
  304. package/vendor/node_modules/@legendapp/spark-native-menu/package.json +9 -4
  305. package/vendor/node_modules/@legendapp/spark-native-menu/src/NativeMenu.ts +2 -7
  306. package/vendor/node_modules/@legendapp/spark-native-menu/src/api.ts +76 -121
  307. package/vendor/node_modules/@legendapp/spark-native-menu/src/hooks.ts +97 -0
  308. package/vendor/node_modules/@legendapp/spark-native-menu/src/windows-menus.ts +43 -37
  309. package/vendor/node_modules/@legendapp/spark-notifications/macos/RNDesktopNotifications.mm +75 -30
  310. package/vendor/node_modules/@legendapp/spark-notifications/package.json +2 -2
  311. package/vendor/node_modules/@legendapp/spark-notifications/src/NativeDesktopNotifications.ts +1 -1
  312. package/vendor/node_modules/@legendapp/spark-notifications/src/index.ts +130 -42
  313. package/vendor/node_modules/@legendapp/spark-notifications/windows/SparkNotifications/SparkNotifications.h +51 -8
  314. package/vendor/node_modules/@legendapp/spark-processes/macos/RNDesktopProcesses.mm +94 -21
  315. package/vendor/node_modules/@legendapp/spark-processes/package.json +4 -3
  316. package/vendor/node_modules/@legendapp/spark-processes/src/NativeDesktopProcesses.ts +1 -1
  317. package/vendor/node_modules/@legendapp/spark-processes/src/index.ts +124 -28
  318. package/vendor/node_modules/@legendapp/spark-processes/src/types.ts +34 -0
  319. package/vendor/node_modules/@legendapp/spark-processes/windows/SparkProcesses/SparkProcesses.h +83 -34
  320. package/vendor/node_modules/@legendapp/spark-processes/windows/SparkProcesses/SparkProcesses.vcxproj +2 -0
  321. package/vendor/node_modules/@legendapp/spark-secure-storage/macos/RNDesktopSecureStorage.mm +49 -40
  322. package/vendor/node_modules/@legendapp/spark-secure-storage/package.json +2 -2
  323. package/vendor/node_modules/@legendapp/spark-secure-storage/src/NativeDesktopSecureStorage.ts +1 -1
  324. package/vendor/node_modules/@legendapp/spark-secure-storage/src/desktop.ts +16 -14
  325. package/vendor/node_modules/@legendapp/spark-secure-storage/src/expo.ts +0 -1
  326. package/vendor/node_modules/@legendapp/spark-secure-storage/src/options.ts +3 -2
  327. package/vendor/node_modules/@legendapp/spark-secure-storage/src/unavailable.ts +6 -3
  328. package/vendor/node_modules/@legendapp/spark-settings/package.json +10 -3
  329. package/vendor/node_modules/@legendapp/spark-settings/src/fileStorage.ts +11 -0
  330. package/vendor/node_modules/@legendapp/spark-settings/src/index.ts +7 -9
  331. package/vendor/node_modules/@legendapp/spark-settings/src/storage/index.ts +142 -0
  332. package/vendor/node_modules/@legendapp/spark-settings/src/store.ts +63 -21
  333. package/vendor/node_modules/@legendapp/spark-settings-ui/package.json +20 -0
  334. package/vendor/node_modules/@legendapp/spark-settings-ui/src/index.tsx +436 -0
  335. package/vendor/node_modules/@legendapp/spark-settings-ui/src/options.ts +10 -0
  336. package/vendor/node_modules/@legendapp/spark-sqlite/package.json +3 -3
  337. package/vendor/node_modules/@legendapp/spark-sqlite/src/database.ts +182 -0
  338. package/vendor/node_modules/@legendapp/spark-sqlite/src/index.ts +19 -6
  339. package/vendor/node_modules/@legendapp/spark-sqlite/src/types.ts +22 -0
  340. package/vendor/node_modules/@legendapp/spark-system/macos/RNDesktopSystem.mm +36 -11
  341. package/vendor/node_modules/@legendapp/spark-system/package.json +2 -2
  342. package/vendor/node_modules/@legendapp/spark-system/src/NativeDesktopSystem.ts +1 -1
  343. package/vendor/node_modules/@legendapp/spark-system/src/index.ts +89 -32
  344. package/vendor/node_modules/@legendapp/spark-system/windows/SparkSystem/SparkSystem.h +8 -4
  345. package/vendor/node_modules/@legendapp/spark-tray/macos/RNDesktopTray.mm +20 -8
  346. package/vendor/node_modules/@legendapp/spark-tray/package.json +2 -2
  347. package/vendor/node_modules/@legendapp/spark-tray/src/NativeDesktopTray.ts +1 -1
  348. package/vendor/node_modules/@legendapp/spark-tray/src/index.ts +91 -34
  349. package/vendor/node_modules/@legendapp/spark-tray/windows/SparkTray/SparkTray.h +45 -15
  350. package/vendor/node_modules/@legendapp/spark-ui/macos/RNSparkButton.mm +2 -1
  351. package/vendor/node_modules/@legendapp/spark-ui/macos/RNSparkTextInput.mm +10 -2
  352. package/vendor/node_modules/@legendapp/spark-ui/macos/appkit-split-view/RNSidebarSplitViewComponent.h +15 -0
  353. package/vendor/node_modules/@legendapp/spark-ui/macos/appkit-split-view/RNSidebarSplitViewComponent.mm +1419 -0
  354. package/vendor/node_modules/@legendapp/spark-ui/macos/glass-effect-view/RNGlassEffectView.mm +72 -0
  355. package/vendor/node_modules/@legendapp/spark-ui/macos/native-select/RNNativeSegmentedControl.h +15 -0
  356. package/vendor/node_modules/@legendapp/spark-ui/macos/native-select/RNNativeSegmentedControl.mm +194 -0
  357. package/vendor/node_modules/@legendapp/spark-ui/macos/native-select/RNNativeSelect.h +15 -0
  358. package/vendor/node_modules/@legendapp/spark-ui/macos/native-select/RNNativeSelect.mm +180 -0
  359. package/vendor/node_modules/@legendapp/spark-ui/macos/sf-symbol/RNSFSymbol.h +15 -0
  360. package/vendor/node_modules/@legendapp/spark-ui/macos/sf-symbol/RNSFSymbol.mm +155 -0
  361. package/vendor/node_modules/@legendapp/spark-ui/macos/sidebar/RNSidebar.h +18 -0
  362. package/vendor/node_modules/@legendapp/spark-ui/macos/sidebar/RNSidebar.mm +645 -0
  363. package/vendor/node_modules/@legendapp/spark-ui/macos/swipe-actions/RNSwipeActions.h +10 -0
  364. package/vendor/node_modules/@legendapp/spark-ui/macos/swipe-actions/RNSwipeActions.mm +422 -0
  365. package/vendor/node_modules/@legendapp/spark-ui/macos/text-input-search/RNTextInputSearch.h +15 -0
  366. package/vendor/node_modules/@legendapp/spark-ui/macos/text-input-search/RNTextInputSearch.mm +164 -0
  367. package/vendor/node_modules/@legendapp/spark-ui/package.json +17 -4
  368. package/vendor/node_modules/@legendapp/spark-ui/src/SparkSelectNativeComponent.ts +3 -1
  369. package/vendor/node_modules/@legendapp/spark-ui/src/SparkTextInputNativeComponent.ts +6 -2
  370. package/vendor/node_modules/@legendapp/spark-ui/src/appkit-split-view/SidebarSplitViewNativeComponent.ts +37 -0
  371. package/vendor/node_modules/@legendapp/spark-ui/src/appkit-split-view/index.tsx +86 -0
  372. package/vendor/node_modules/@legendapp/spark-ui/src/availability.ts +10 -0
  373. package/vendor/node_modules/@legendapp/spark-ui/src/classnames/index.ts +8 -0
  374. package/vendor/node_modules/@legendapp/spark-ui/src/control.ts +42 -0
  375. package/vendor/node_modules/@legendapp/spark-ui/src/desktop.tsx +56 -0
  376. package/vendor/node_modules/@legendapp/spark-ui/src/glass-effect-view/index.tsx +15 -0
  377. package/vendor/node_modules/@legendapp/spark-ui/src/index.android.tsx +35 -21
  378. package/vendor/node_modules/@legendapp/spark-ui/src/index.ios.tsx +55 -26
  379. package/vendor/node_modules/@legendapp/spark-ui/src/index.tsx +1 -27
  380. package/vendor/node_modules/@legendapp/spark-ui/src/index.web.tsx +45 -14
  381. package/vendor/node_modules/@legendapp/spark-ui/src/index.windows.tsx +1 -42
  382. package/vendor/node_modules/@legendapp/spark-ui/src/mobile-input.tsx +11 -0
  383. package/vendor/node_modules/@legendapp/spark-ui/src/native-select/NativeSegmentedControlNativeComponent.ts +17 -0
  384. package/vendor/node_modules/@legendapp/spark-ui/src/native-select/NativeSelectNativeComponent.ts +17 -0
  385. package/vendor/node_modules/@legendapp/spark-ui/src/select.ts +5 -3
  386. package/vendor/node_modules/@legendapp/spark-ui/src/sf-symbol/SFSymbolNativeComponent.ts +13 -0
  387. package/vendor/node_modules/@legendapp/spark-ui/src/sf-symbol/index.tsx +27 -0
  388. package/vendor/node_modules/@legendapp/spark-ui/src/sidebar/SidebarItemNativeComponent.ts +25 -0
  389. package/vendor/node_modules/@legendapp/spark-ui/src/sidebar/SidebarNativeComponent.ts +24 -0
  390. package/vendor/node_modules/@legendapp/spark-ui/src/sidebar/index.tsx +104 -0
  391. package/vendor/node_modules/@legendapp/spark-ui/src/specialized.ts +22 -0
  392. package/vendor/node_modules/@legendapp/spark-ui/src/swipe-actions/SwipeActionsNativeComponent.ts +11 -0
  393. package/vendor/node_modules/@legendapp/spark-ui/src/swipe-actions/index.tsx +41 -0
  394. package/vendor/node_modules/@legendapp/spark-ui/src/text-input-search/TextInputSearchNativeComponent.ts +33 -0
  395. package/vendor/node_modules/@legendapp/spark-ui/src/text-input-search/index.tsx +34 -0
  396. package/vendor/node_modules/@legendapp/spark-ui/src/types.ts +30 -19
  397. package/vendor/node_modules/@legendapp/spark-ui/uniwind.ts +3 -1
  398. package/vendor/node_modules/@legendapp/spark-ui/uniwind.web.ts +3 -1
  399. package/vendor/node_modules/@legendapp/spark-ui/windows/SparkUI/SparkUI.h +16 -11
  400. package/vendor/node_modules/@legendapp/spark-updates/macos/RNDesktopUpdates.mm +21 -8
  401. package/vendor/node_modules/@legendapp/spark-updates/package.json +2 -2
  402. package/vendor/node_modules/@legendapp/spark-updates/src/NativeDesktopUpdates.ts +3 -2
  403. package/vendor/node_modules/@legendapp/spark-updates/src/index.ts +71 -15
  404. package/vendor/node_modules/@legendapp/spark-webview/package.json +2 -2
  405. package/vendor/node_modules/@legendapp/spark-webview/src/WebView.tsx +11 -0
  406. package/vendor/node_modules/@legendapp/spark-webview/src/adapter.ts +55 -0
  407. package/vendor/node_modules/@legendapp/spark-webview/src/index.ts +2 -2
  408. package/vendor/node_modules/@legendapp/spark-webview/src/types.ts +32 -0
  409. package/vendor/node_modules/@legendapp/spark-webview/src/view-props.ts +28 -0
  410. package/vendor/node_modules/@legendapp/spark-window-options/index.cjs +51 -14
  411. package/vendor/node_modules/@legendapp/spark-window-options/index.d.ts +21 -8
  412. package/vendor/node_modules/@legendapp/spark-window-options/package.json +1 -1
  413. package/windows-macos.ts +1 -0
  414. package/expo-metro.cjs +0 -1
  415. package/message-dialog.ts +0 -1
  416. package/universal.cjs +0 -1
  417. package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/src/accelerator.ts +0 -22
  418. package/vendor/node_modules/@legendapp/spark-desktop-windows/src/windows-options.ts +0 -11
  419. package/vendor/node_modules/@legendapp/spark-file-dialog/src/index.windows.ts +0 -15
  420. package/vendor/node_modules/@legendapp/spark-global-shortcuts/src/accelerator.ts +0 -22
  421. package/vendor/node_modules/@legendapp/spark-ui/macos/RNSparkSelect.h +0 -4
  422. 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 const architecture = (platform) => platform === "windows" ? windowsArchitecture() : "arm64";
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 || !["macos", "windows"].includes(platforms[0]))
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, mkdirSync, readFileSync, readdirSync, realpathSync, writeFileSync, renameSync, } from "node:fs";
10
+ import { existsSync, readFileSync, readdirSync, realpathSync, } from "node:fs";
9
11
  import path from "node:path";
10
- export const VERSION = "0.0.1-next.2";
11
- export function readJson(file) {
12
- return JSON.parse(readFileSync(file, "utf8"));
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 queue = [
42
- { root, json: readJson(path.join(root, "package.json")), app: true },
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 req = createRequire(path.join(current.root, current.json.spark?.bundledModuleRoot ?? ".", "package.json"));
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
- let dir = path.dirname(req.resolve(name));
68
- while ((!existsSync(path.join(dir, "package.json")) || typeof readJson(path.join(dir, "package.json")).name !== "string") &&
69
- dir !== path.dirname(dir))
70
- dir = path.dirname(dir);
71
- file = path.join(dir, "package.json");
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
- const excluded = isUniversal(root) ? readAppConfig(root).expo?.autolinking?.exclude ?? [] : [];
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
- ...(platform === "windows" ? { arch: architecture(platform) } : {}),
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 { existsSync } from "node:fs";
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, VERSION } from "./project.js";
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 (target !== "macos-arm64" || path.basename(asset.app) !== asset.app || !asset.app.endsWith(".app") || !/^[A-Z0-9]{10}$/.test(asset.teamId) || !/^[a-f0-9]+$/.test(asset.fingerprint))
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
- /** Registry versions and immutable HTTPS archives survive project moves and clones. */
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.url])), "@legendapp/spark": VERSION };
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.2",
4
- "revision": "6359fee375c5b0549b43f339d4e856db4bcb7c98",
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.2/runtimes-31ac67156c18.tgz",
8
- "size": 53885,
9
- "sha256": "a8e532d0a1e8d7c23953e94612d58f0e660a685e58645075c5180304c8462515"
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.2/react-native-nitro-modules-0.35.7-7c494d2176d7.tgz",
13
- "size": 138548,
14
- "sha256": "7c494d2176d7f144ee5d518fd8c03b24f29c22bba520b7cebd71ba7d60cb56d3"
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.2/op-engineering-op-sqlite-18.2.1-ebd60a4eb0d4.tgz",
18
- "size": 115455003,
19
- "sha256": "ebd60a4eb0d4a0a2d48c7ca455cf3668879ff64a258bed108c2393d53679cf3c"
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.2/react-native-webview-16.0.0-33882a035641.tgz",
23
- "size": 116112,
24
- "sha256": "33882a03564141b8b5c56cc7e99e0d425f3a53b59db966d9412bb85ef6f0abf3"
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.2/spark-runner-macos-arm64.zip",
30
- "size": 12455131,
31
- "sha256": "77635060c84c536d67af10496e21a65fb57f279a7f165d362f1ca81829c95e69",
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": "fef5859c9685b017d0132277f593c732512dec23b2c57bc6c53ce695e821406d"
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 !== "arm64" || runtime.fingerprint !== asset.fingerprint)
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
- let owned = false;
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
- rmSync(lock, { force: true });
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" || process.arch !== "arm64")
134
- throw new Error("This release's Runner requires Apple Silicon macOS and arm64 Node.");
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;