@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
@@ -1,6 +1,7 @@
1
+ import { SparkError } from "@legendapp/spark-desktop-app/src/contracts";
1
2
  /** Only default storage is portable today. Authentication/service overrides are not implemented. */
2
3
  export type SecureStoreOptions = Record<string, never>;
3
4
  export function validateItem(key: string, options: SecureStoreOptions) {
4
- if (typeof key !== "string" || !/^[\w.-]+$/.test(key) || key.length > 200) throw new Error("SecureStore keys must be 1–200 alphanumeric, '.', '-', or '_' characters");
5
- if (!options || Object.keys(options).length) throw Object.assign(new Error("SecureStore options are not supported by the shared API yet"), { code: "E_UNSUPPORTED_OPTION" });
5
+ if (typeof key !== "string" || !/^[\w.-]+$/.test(key) || key.length > 200) throw new SparkError("E_INVALID_ARGUMENT", "SecureStore keys must be 1–200 alphanumeric, '.', '-', or '_' characters");
6
+ if (!options || typeof options !== "object" || Array.isArray(options) || Object.keys(options).length) throw new SparkError("E_UNSUPPORTED_OPTION", "SecureStore options are not supported by the shared API");
6
7
  }
@@ -1,5 +1,8 @@
1
+ import { SparkError } from "@legendapp/spark-desktop-app/src/contracts";
2
+ import type { SecureStoreOptions } from "./options";
1
3
  export type { SecureStoreOptions } from "./options";
2
4
  export async function isAvailableAsync(): Promise<boolean> { return false; }
3
- const unavailable = async (..._args: unknown[]): Promise<never> => { throw Object.assign(new Error("Secure storage is unavailable on this platform"), { code: "E_UNAVAILABLE" }); };
4
- export const getItemAsync = unavailable, setItemAsync = unavailable, deleteItemAsync = unavailable;
5
- export const secureStorage = { get: getItemAsync, set: setItemAsync, remove: deleteItemAsync };
5
+ function unavailable(): never { throw new SparkError("E_UNSUPPORTED_PLATFORM", "Secure storage is unavailable on this platform"); }
6
+ export async function getItemAsync(_key: string, _options?: SecureStoreOptions): Promise<string | null> { return unavailable(); }
7
+ export async function setItemAsync(_key: string, _value: string, _options?: SecureStoreOptions): Promise<void> { return unavailable(); }
8
+ export async function deleteItemAsync(_key: string, _options?: SecureStoreOptions): Promise<void> { return unavailable(); }
@@ -1,13 +1,20 @@
1
1
  {
2
2
  "name": "@legendapp/spark-settings",
3
- "version": "0.0.1-next.2",
3
+ "version": "0.0.1-next.4",
4
4
  "license": "MIT",
5
5
  "main": "src/index.ts",
6
6
  "files": [
7
7
  "src"
8
8
  ],
9
9
  "dependencies": {
10
- "@legendapp/spark-file-system": "0.0.1-next.2"
10
+ "@legendapp/spark-file-system": "0.0.1-next.4",
11
+ "@legendapp/state": "^3.0.0-beta.42",
12
+ "@legendapp/spark-desktop-app": "0.0.1-next.4"
11
13
  },
12
- "private": true
14
+ "private": true,
15
+ "spark": {
16
+ "sdk": true
17
+ },
18
+ "peerDependencies": {},
19
+ "peerDependenciesMeta": {}
13
20
  }
@@ -0,0 +1,11 @@
1
+ import type { SettingsStorage } from "./store";
2
+ /** Loaded lazily so custom backends and observable types do not require a native host. */
3
+ export const fileStorage: SettingsStorage = {
4
+ async read(path) {
5
+ const files = await import("@legendapp/spark-file-system");
6
+ try { return await files.readText(path); }
7
+ catch (error) { if ((error as { code?: string }).code === "E_NOT_FOUND") return undefined; throw error; }
8
+ },
9
+ async write(path, value) { await (await import("@legendapp/spark-file-system")).writeText(path, value); },
10
+ async remove(path) { await (await import("@legendapp/spark-file-system")).remove(path); },
11
+ };
@@ -1,7 +1,8 @@
1
1
  import * as files from "@legendapp/spark-file-system";
2
2
  import { settingsFilename } from "./filename";
3
3
  import { createSettingsStore } from "./store";
4
- export { createSettingsStore, type Json, type SettingsStorage } from "./store";
4
+ import { fileStorage } from "./fileStorage";
5
+ export { createSettingsStore, type Json, type SettingsStorage, type SettingsStore, type SettingsStoreOptions, type SettingsReadOptions } from "./store";
5
6
  let directory: Promise<string> | undefined;
6
7
  async function file(key: string) {
7
8
  directory ??= files.getDirectory("data").then(async root => {
@@ -9,11 +10,8 @@ async function file(key: string) {
9
10
  }).catch(error => { directory = undefined; throw error; });
10
11
  return `${await directory}/${settingsFilename(key)}`;
11
12
  }
12
- export const settings = createSettingsStore({
13
- async read(key) {
14
- try { return await files.readText(await file(key)); }
15
- catch (error) { if ((error as { code?: string }).code === "E_NOT_FOUND") return null; throw error; }
16
- },
17
- async write(key, value) { await files.writeText(await file(key), value); },
18
- async remove(key) { await files.remove(await file(key)); },
19
- });
13
+ export const settings = createSettingsStore({ storage: {
14
+ async read(key) { return fileStorage.read(await file(key)); },
15
+ async write(key, value) { await fileStorage.write(await file(key), value); },
16
+ async remove(key) { await fileStorage.remove(await file(key)); },
17
+ } });
@@ -0,0 +1,142 @@
1
+ import { internal, observable, type Observable } from "@legendapp/state";
2
+ import { SparkError } from "@legendapp/spark-desktop-app/src/contracts";
3
+ import { absolutePath } from "@legendapp/spark-desktop-app/src/contracts/path";
4
+ import type { SettingsStorage } from "../store";
5
+ import { fileStorage } from "../fileStorage";
6
+
7
+ export interface ObservableFileOptions<T> {
8
+ /** Absolute native path, including the extension. Parent directory must exist. */
9
+ path: string;
10
+ initialValue: T;
11
+ /** Validate/convert persisted data. Missing files use initialValue. */
12
+ decode(value: unknown): T | Promise<T>;
13
+ /** Convert a snapshot for persistence. Omit to use Legend State serialization. */
14
+ encode?(value: T): unknown | Promise<unknown>;
15
+ storage?: SettingsStorage;
16
+ debounceMs?: number;
17
+ saveDefault?: boolean;
18
+ }
19
+ export interface ObservableFile<T> {
20
+ /** Legend State owns this observable API. Mutations after close are not persisted. */
21
+ value$: Observable<T>;
22
+ /** Most recent persistence failure; cleared after a successful save. */
23
+ error$: Observable<Error | undefined>;
24
+ /** Save a snapshot of all changes made before this call, including inside batches. */
25
+ flush(): Promise<void>;
26
+ /** Stop automatic saves immediately and flush a final snapshot. Failed closes retry. */
27
+ close(): Promise<void>;
28
+ }
29
+ function stringify(value: unknown): string | undefined {
30
+ if (value === undefined) return undefined;
31
+ // Legend's helper returns falsy input unchanged. File storage always needs text.
32
+ const text = value ? internal.safeStringify(value) : JSON.stringify(value);
33
+ if (typeof text !== "string") throw new SparkError("E_INVALID_DATA", "Value cannot be serialized");
34
+ return text;
35
+ }
36
+ function parse(text: string | undefined): unknown {
37
+ if (text === undefined) return undefined;
38
+ if (typeof text !== "string" || text.length === 0) throw new SparkError("E_INVALID_DATA", "Expected serialized settings");
39
+ return internal.safeParse(text);
40
+ }
41
+
42
+ /** Await readiness before editing. Load/decode failures preserve existing bytes.
43
+ * Writes are serialized within this handle, not across handles or processes.
44
+ * Root undefined removes the file; null is persisted. Date/Map/Set use Legend encoding.
45
+ */
46
+ export async function createObservableFile<T>(options: ObservableFileOptions<T>): Promise<ObservableFile<T>> {
47
+ if (!options || typeof options !== "object" || Array.isArray(options)) throw new SparkError("E_INVALID_ARGUMENT", "Expected observable file options");
48
+ for (const key of Object.keys(options)) if (!["path", "initialValue", "decode", "encode", "storage", "debounceMs", "saveDefault"].includes(key)) throw new SparkError("E_UNSUPPORTED_OPTION", `Unsupported observable file option: ${key}`);
49
+ const path = absolutePath(options.path, typeof options.path === "string" && options.path.startsWith("/") ? "macos" : "windows");
50
+ const { decode, encode, storage = fileStorage, debounceMs = 300, saveDefault = false } = options;
51
+ if (typeof decode !== "function" || (encode !== undefined && typeof encode !== "function")) throw new SparkError("E_INVALID_ARGUMENT", "Expected a decoder and optional encoder");
52
+ if (!Number.isFinite(debounceMs) || debounceMs < 0 || debounceMs > 2147483647 || typeof saveDefault !== "boolean") throw new SparkError("E_INVALID_ARGUMENT", "Invalid persistence timing options");
53
+ if (!storage || [storage.read, storage.write, storage.remove].some(method => typeof method !== "function")) throw new SparkError("E_INVALID_ARGUMENT", "Expected read/write/remove storage methods");
54
+ const text = await storage.read(path);
55
+ let initial: T;
56
+ try { initial = text === undefined ? parse(stringify(options.initialValue)) as T : await decode(parse(text)); }
57
+ catch (cause) { throw new SparkError("E_INVALID_DATA", "Could not decode observable file", { cause }); }
58
+ const value$ = observable(initial) as Observable<T>;
59
+ const error$ = observable<Error | undefined>();
60
+ const recordError = (error: unknown) => error$.set(error instanceof Error ? error : new SparkError("E_NATIVE", "Persistence failed", { cause: error }));
61
+ let persisted = stringify(initial);
62
+ let timer: ReturnType<typeof setTimeout> | undefined;
63
+ let queue: Promise<void> = Promise.resolve();
64
+ let closing = false, closed = false;
65
+ let closingSnapshot: string | undefined;
66
+ let capturedClose = false;
67
+ let closePromise: Promise<void> | undefined;
68
+ const clearTimer = () => { if (timer !== undefined) clearTimeout(timer); timer = undefined; };
69
+ function snapshot(): string | undefined { return stringify(value$.peek()); }
70
+ function save(snapshotText: string | undefined, force = false): Promise<void> {
71
+ const next = queue.catch(() => {}).then(async () => {
72
+ if (force || persisted !== snapshotText) {
73
+ // The serialized snapshot is already isolated from later observable mutations.
74
+ const output = encode ? stringify(await encode(parse(snapshotText) as T)) : snapshotText;
75
+ if (output === undefined) await storage.remove(path);
76
+ else await storage.write(path, output);
77
+ persisted = snapshotText;
78
+ }
79
+ error$.set(undefined);
80
+ }).catch(error => { recordError(error); throw error; });
81
+ queue = next;
82
+ // Automatic writes report through error$; explicit callers still receive rejection.
83
+ void next.catch(() => {});
84
+ return next;
85
+ }
86
+ const unsubscribe = value$.onChange(() => {
87
+ if (closing) return;
88
+ clearTimer();
89
+ timer = setTimeout(() => {
90
+ timer = undefined;
91
+ try { void save(snapshot()); } catch (error) { recordError(error); }
92
+ }, debounceMs);
93
+ }, { immediate: true });
94
+ const handle: ObservableFile<T> = {
95
+ value$, error$,
96
+ async flush() {
97
+ if (closing) throw new SparkError("E_CLOSED", "Observable file is closing or closed");
98
+ clearTimer();
99
+ try { await save(snapshot()); } catch (error) { recordError(error); throw error; }
100
+ },
101
+ close() {
102
+ if (closed) return Promise.resolve();
103
+ if (closePromise) return closePromise;
104
+ closing = true; clearTimer(); unsubscribe();
105
+ // Capture synchronously, before consumers can mutate after calling close.
106
+ try { if (!capturedClose) { closingSnapshot = snapshot(); capturedClose = true; } }
107
+ catch (error) { recordError(error); return Promise.reject(error); }
108
+ closePromise = save(closingSnapshot).then(() => { closed = true; }).finally(() => { closePromise = undefined; });
109
+ return closePromise;
110
+ },
111
+ };
112
+ if (saveDefault && text === undefined) {
113
+ try { await save(persisted, true); }
114
+ catch (error) { unsubscribe(); throw error; }
115
+ }
116
+ return handle;
117
+ }
118
+
119
+ export interface ObservableSettingsField<T> {
120
+ defaultValue: T;
121
+ decode(value: unknown): T;
122
+ }
123
+ export type ObservableSettingsFields = Record<string, ObservableSettingsField<any>>;
124
+ export type ObservableSettingsValues<F extends ObservableSettingsFields> = { [K in keyof F]: F[K] extends ObservableSettingsField<infer T> ? T : never };
125
+ export interface ObservableSettingsOptions<F extends ObservableSettingsFields> extends Omit<ObservableFileOptions<ObservableSettingsValues<F>>, "initialValue" | "decode" | "encode"> { fields: F }
126
+ /** Field defaults apply only to absent fields; stored null is passed to the decoder.
127
+ * Unknown fields are omitted. Use value$.field directly with Legend State's useValue.
128
+ */
129
+ export async function createObservableSettings<const F extends ObservableSettingsFields>(options: ObservableSettingsOptions<F>): Promise<ObservableFile<ObservableSettingsValues<F>>> {
130
+ if (!options || !options.fields || typeof options.fields !== "object" || Array.isArray(options.fields)) throw new SparkError("E_INVALID_ARGUMENT", "Expected settings fields");
131
+ const { fields, ...rest } = options;
132
+ const entries = Object.entries(fields);
133
+ if (entries.some(([, field]) => !field || typeof field.decode !== "function")) throw new SparkError("E_INVALID_ARGUMENT", "Each field requires a decoder");
134
+ return createObservableFile({
135
+ ...rest,
136
+ initialValue: Object.fromEntries(entries.map(([key, field]) => [key, field.defaultValue])) as ObservableSettingsValues<F>,
137
+ decode(value) {
138
+ if (!value || typeof value !== "object" || Array.isArray(value)) throw new SparkError("E_INVALID_DATA", "Expected a settings object");
139
+ return Object.fromEntries(entries.map(([key, field]) => [key, Object.hasOwn(value, key) ? field.decode((value as Record<string, unknown>)[key]) : field.defaultValue])) as ObservableSettingsValues<F>;
140
+ },
141
+ });
142
+ }
@@ -1,35 +1,77 @@
1
+ import { SparkError } from "@legendapp/spark-desktop-app/src/contracts";
1
2
  export type Json = null | boolean | number | string | Json[] | { [key: string]: Json };
2
- export type SettingsStorage = { read(key: string): Promise<string | null>; write(key: string, value: string): Promise<void>; remove(key: string): Promise<void> };
3
- function serialize(value: Json): string {
4
- return JSON.stringify(value, (_key, item: unknown) => {
5
- if (item === undefined || typeof item === "function" || typeof item === "symbol" || typeof item === "bigint" ||
6
- (typeof item === "number" && !Number.isFinite(item))) throw new Error("Settings must contain finite JSON values");
7
- return item;
8
- });
3
+ export interface SettingsStorage {
4
+ read(key: string): Promise<string | undefined>;
5
+ write(key: string, value: string): Promise<void>;
6
+ remove(key: string): Promise<void>;
9
7
  }
10
- /** Mutations are serialized per key, including failed updates. Await writes before quitting. */
11
- export function createSettingsStore(storage: SettingsStorage) {
8
+ export interface SettingsStoreOptions { storage: SettingsStorage }
9
+ export interface SettingsReadOptions<T> { decode(value: Json): T }
10
+ export interface SettingsStore {
11
+ get(key: string): Promise<Json | undefined>;
12
+ get<T>(key: string, options: SettingsReadOptions<T>): Promise<T | undefined>;
13
+ set(key: string, value: Json): Promise<void>;
14
+ remove(key: string): Promise<void>;
15
+ update<T extends Json>(key: string, updater: (value: Json | undefined) => T | Promise<T>): Promise<T>;
16
+ }
17
+ function validateJson(value: unknown, ancestors = new Set<object>()): void {
18
+ if (value === null || typeof value === "boolean" || typeof value === "string") return;
19
+ if (typeof value === "number" && Number.isFinite(value)) return;
20
+ if (typeof value !== "object" || !value || ancestors.has(value) || (!Array.isArray(value) && Object.getPrototypeOf(value) !== Object.prototype && Object.getPrototypeOf(value) !== null)) throw new SparkError("E_INVALID_ARGUMENT", "Settings must contain finite JSON values without cycles");
21
+ ancestors.add(value);
22
+ try {
23
+ if (Array.isArray(value)) { for (const item of value) validateJson(item, ancestors); return; }
24
+ if (Object.getOwnPropertySymbols(value).length) throw new SparkError("E_INVALID_ARGUMENT", "Settings cannot have symbol keys");
25
+ for (const key of Object.keys(value)) validateJson((value as Record<string, unknown>)[key], ancestors);
26
+ } finally { ancestors.delete(value); }
27
+ }
28
+ // Serialization itself snapshots before the operation can wait in the per-key queue.
29
+ const serialize = (value: Json) => { validateJson(value); return JSON.stringify(value); };
30
+ function validateParsedNumbers(value: Json): void {
31
+ if (typeof value === "number" && !Number.isFinite(value)) throw new SparkError("E_INVALID_DATA", "Stored settings contain non-finite numbers");
32
+ if (Array.isArray(value)) { for (const item of value) validateParsedNumbers(item); }
33
+ else if (value && typeof value === "object") for (const key of Object.keys(value)) validateParsedNumbers(value[key]);
34
+ }
35
+ /** This store serializes operations per key. It does not lock other stores/processes.
36
+ * Updaters must not await another operation on the same key in this store. */
37
+ export function createSettingsStore(options: SettingsStoreOptions): SettingsStore {
38
+ if (!options || typeof options !== "object" || Array.isArray(options)) throw new SparkError("E_INVALID_ARGUMENT", "Expected settings store options");
39
+ if (Object.keys(options).some(key => key !== "storage")) throw new SparkError("E_UNSUPPORTED_OPTION", "Unsupported settings store option");
40
+ const { storage } = options;
41
+ if (!storage || [storage.read, storage.write, storage.remove].some(method => typeof method !== "function")) throw new SparkError("E_INVALID_ARGUMENT", "Expected read/write/remove storage methods");
12
42
  const pending = new Map<string, Promise<unknown>>();
13
- const validate = (key: string) => { if (!key.length || key.length > 200) throw new Error("Setting keys must contain 1–200 characters"); };
14
43
  function enqueue<T>(key: string, operation: () => Promise<T>): Promise<T> {
15
- validate(key);
16
- const next = (pending.get(key) ?? Promise.resolve()).catch(() => {}).then(operation);
44
+ if (typeof key !== "string" || !key.length || key.length > 200 || key.includes("\0")) throw new SparkError("E_INVALID_ARGUMENT", "Setting keys must contain 1–200 characters without NUL");
45
+ const previous = pending.get(key);
46
+ let next: Promise<T>;
47
+ try { next = previous ? previous.then(operation, operation) : operation(); }
48
+ catch (error) { next = Promise.reject(error); }
17
49
  pending.set(key, next);
18
- void next.finally(() => { if (pending.get(key) === next) pending.delete(key); }).catch(() => {});
50
+ const settled = () => { if (pending.get(key) === next) pending.delete(key); };
51
+ void next.then(settled, settled);
19
52
  return next;
20
53
  }
21
- async function read<T extends Json>(key: string): Promise<T | null> {
54
+ async function read(key: string): Promise<Json | undefined> {
22
55
  const value = await storage.read(key);
23
- // Corruption is an error; never silently replace it with defaults.
24
- return value === null ? null : JSON.parse(value) as T;
56
+ if (value === undefined) return undefined;
57
+ if (typeof value !== "string") throw new SparkError("E_INVALID_DATA", "Storage reads must return text or undefined");
58
+ try { const parsed = JSON.parse(value) as Json; validateParsedNumbers(parsed); return parsed; }
59
+ catch (cause) { throw new SparkError("E_INVALID_DATA", "Stored settings are not valid JSON", { cause }); }
60
+ }
61
+ async function get(key: string): Promise<Json | undefined>;
62
+ async function get<T>(key: string, options: SettingsReadOptions<T>): Promise<T | undefined>;
63
+ async function get<T>(key: string, options?: SettingsReadOptions<T>): Promise<Json | T | undefined> {
64
+ if (options !== undefined && (!options || typeof options.decode !== "function" || Object.keys(options).some(key => key !== "decode"))) throw new SparkError("E_INVALID_ARGUMENT", "Expected a settings decoder");
65
+ return enqueue(key, async () => { const value = await read(key); return value === undefined || !options ? value : options.decode(value); });
25
66
  }
26
67
  return {
27
- get<T extends Json>(key: string) { return enqueue(key, () => read<T>(key)); },
28
- set(key: string, value: Json) { const json = serialize(value); return enqueue(key, () => storage.write(key, json)); },
29
- remove(key: string) { return enqueue(key, () => storage.remove(key)); },
30
- update<T extends Json>(key: string, update: (value: T | null) => T | Promise<T>) {
68
+ get,
69
+ async set(key, value) { const json = serialize(value); await enqueue(key, () => storage.write(key, json)); },
70
+ async remove(key) { await enqueue(key, () => storage.remove(key)); },
71
+ async update(key, updater) {
72
+ if (typeof updater !== "function") throw new SparkError("E_INVALID_ARGUMENT", "Expected a settings updater");
31
73
  return enqueue(key, async () => {
32
- const value = await update(await read<T>(key));
74
+ const value = await updater(await read(key));
33
75
  await storage.write(key, serialize(value)); return value;
34
76
  });
35
77
  },
@@ -0,0 +1,20 @@
1
+ {
2
+ "name": "@legendapp/spark-settings-ui",
3
+ "version": "0.0.1-next.4",
4
+ "private": true,
5
+ "license": "MIT",
6
+ "main": "src/index.tsx",
7
+ "files": [
8
+ "src"
9
+ ],
10
+ "dependencies": {
11
+ "@legendapp/spark-ui": "0.0.1-next.4",
12
+ "@legendapp/spark-desktop-windows": "0.0.1-next.4",
13
+ "@legendapp/spark-desktop-app": "0.0.1-next.4"
14
+ },
15
+ "peerDependencies": {
16
+ "react": "19.1.4",
17
+ "react-native": "0.81.6",
18
+ "@legendapp/list": ">=3.3.0"
19
+ }
20
+ }