@legendapp/spark 0.0.1-next.2 → 0.0.1-next.3

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 (399) 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/config-plugin.d.cts +2 -0
  7. package/contracts.ts +2 -0
  8. package/diagnostics.ts +1 -0
  9. package/expo-config.d.cts +1 -0
  10. package/metro.cjs +4 -1
  11. package/metro.d.cts +12 -0
  12. package/native.cjs +3 -1
  13. package/native.d.cts +6 -0
  14. package/package.json +82 -14
  15. package/schema.json +276 -58
  16. package/settings-observable.ts +1 -0
  17. package/settings-window.ts +1 -0
  18. package/shortcuts-commands.ts +1 -0
  19. package/shortcuts-keyboard.ts +3 -0
  20. package/ui-classnames.ts +1 -0
  21. package/ui-glass.ts +1 -0
  22. package/ui-search.ts +1 -0
  23. package/ui-sidebar.ts +1 -0
  24. package/ui-split-view.ts +1 -0
  25. package/ui-symbol.ts +1 -0
  26. package/vendor/node_modules/@legendapp/spark-ai/package.json +19 -0
  27. package/vendor/node_modules/@legendapp/spark-ai/src/availability.ts +17 -0
  28. package/vendor/node_modules/@legendapp/spark-ai/src/index.ts +15 -0
  29. package/vendor/node_modules/@legendapp/spark-ai/src/invocations.ts +34 -0
  30. package/vendor/node_modules/@legendapp/spark-ai/src/output.ts +62 -0
  31. package/vendor/node_modules/@legendapp/spark-ai/src/run.ts +12 -0
  32. package/vendor/node_modules/@legendapp/spark-ai/src/types.ts +16 -0
  33. package/vendor/node_modules/@legendapp/spark-audio/macos/RNSparkAudio.h +2 -1
  34. package/vendor/node_modules/@legendapp/spark-audio/macos/RNSparkAudio.mm +126 -24
  35. package/vendor/node_modules/@legendapp/spark-audio/package.json +5 -2
  36. package/vendor/node_modules/@legendapp/spark-audio/src/NativeSparkAudio.ts +5 -1
  37. package/vendor/node_modules/@legendapp/spark-audio/src/desktop.ts +36 -32
  38. package/vendor/node_modules/@legendapp/spark-audio/src/events.ts +11 -0
  39. package/vendor/node_modules/@legendapp/spark-audio/src/hooks.ts +65 -0
  40. package/vendor/node_modules/@legendapp/spark-audio/src/index.web.ts +92 -33
  41. package/vendor/node_modules/@legendapp/spark-audio/src/media-session-unavailable.ts +6 -4
  42. package/vendor/node_modules/@legendapp/spark-audio/src/media-session.ts +52 -19
  43. package/vendor/node_modules/@legendapp/spark-audio/src/media-session.web.ts +18 -10
  44. package/vendor/node_modules/@legendapp/spark-audio/src/media-types.ts +40 -13
  45. package/vendor/node_modules/@legendapp/spark-audio/src/mobile.ts +40 -32
  46. package/vendor/node_modules/@legendapp/spark-audio/src/player.ts +97 -0
  47. package/vendor/node_modules/@legendapp/spark-audio/src/status-listeners.ts +21 -15
  48. package/vendor/node_modules/@legendapp/spark-audio/src/types.ts +9 -4
  49. package/vendor/node_modules/@legendapp/spark-audio/windows/SparkAudio/SparkAudio.h +67 -20
  50. package/vendor/node_modules/@legendapp/spark-auth-session/package.json +4 -3
  51. package/vendor/node_modules/@legendapp/spark-auth-session/src/core.ts +60 -42
  52. package/vendor/node_modules/@legendapp/spark-auth-session/src/index.ts +28 -12
  53. package/vendor/node_modules/@legendapp/spark-auth-session/src/mobile.ts +97 -41
  54. package/vendor/node_modules/@legendapp/spark-auth-session/src/types.ts +20 -9
  55. package/vendor/node_modules/@legendapp/spark-cli/dist/add-desktop.js +50 -7
  56. package/vendor/node_modules/@legendapp/spark-cli/dist/build-mode.js +1 -1
  57. package/vendor/node_modules/@legendapp/spark-cli/dist/build.js +83 -48
  58. package/vendor/node_modules/@legendapp/spark-cli/dist/cli-arguments.js +60 -0
  59. package/vendor/node_modules/@legendapp/spark-cli/dist/commands.js +7 -2
  60. package/vendor/node_modules/@legendapp/spark-cli/dist/create.js +31 -5
  61. package/vendor/node_modules/@legendapp/spark-cli/dist/credentials.js +69 -23
  62. package/vendor/node_modules/@legendapp/spark-cli/dist/dev-command.js +12 -3
  63. package/vendor/node_modules/@legendapp/spark-cli/dist/dev.js +12 -9
  64. package/vendor/node_modules/@legendapp/spark-cli/dist/examples.js +1 -1
  65. package/vendor/node_modules/@legendapp/spark-cli/dist/expo-dev-patch.cjs +4 -2
  66. package/vendor/node_modules/@legendapp/spark-cli/dist/expo-metro.cjs +1 -1
  67. package/vendor/node_modules/@legendapp/spark-cli/dist/expo-node.js +3 -3
  68. package/vendor/node_modules/@legendapp/spark-cli/dist/index.js +10 -38
  69. package/vendor/node_modules/@legendapp/spark-cli/dist/local.js +1 -1
  70. package/vendor/node_modules/@legendapp/spark-cli/dist/metro.cjs +26 -5
  71. package/vendor/node_modules/@legendapp/spark-cli/dist/native-metadata.js +26 -0
  72. package/vendor/node_modules/@legendapp/spark-cli/dist/native-patch-preflight.js +84 -0
  73. package/vendor/node_modules/@legendapp/spark-cli/dist/native-preparation.js +88 -0
  74. package/vendor/node_modules/@legendapp/spark-cli/dist/notary-profiles.js +75 -0
  75. package/vendor/node_modules/@legendapp/spark-cli/dist/package.js +4 -2
  76. package/vendor/node_modules/@legendapp/spark-cli/dist/platform.js +16 -2
  77. package/vendor/node_modules/@legendapp/spark-cli/dist/project.js +66 -13
  78. package/vendor/node_modules/@legendapp/spark-cli/dist/release.js +84 -4
  79. package/vendor/node_modules/@legendapp/spark-cli/dist/release.json +23 -18
  80. package/vendor/node_modules/@legendapp/spark-cli/dist/runner-install.js +145 -31
  81. package/vendor/node_modules/@legendapp/spark-cli/dist/signing.js +4 -3
  82. package/vendor/node_modules/@legendapp/spark-cli/dist/updates.js +41 -4
  83. package/vendor/node_modules/@legendapp/spark-cli/dist/windows.js +4 -1
  84. package/vendor/node_modules/@legendapp/spark-cli/package.json +7 -6
  85. package/vendor/node_modules/@legendapp/spark-cli/templates/blank-typescript/App.tsx +6 -12
  86. package/vendor/node_modules/@legendapp/spark-cli/templates/blank-typescript/desktop.config.json +5 -3
  87. package/vendor/node_modules/@legendapp/spark-cli/templates/blank-typescript/package.json +11 -9
  88. package/vendor/node_modules/@legendapp/spark-cli/templates/diff-lite/Git.macos.tsx +2 -2
  89. package/vendor/node_modules/@legendapp/spark-cli/templates/document-editor/Integration.macos.tsx +23 -21
  90. package/vendor/node_modules/@legendapp/spark-cli/templates/document-editor/Integration.windows.tsx +23 -21
  91. package/vendor/node_modules/@legendapp/spark-cli/templates/document-editor/io.desktop.ts +11 -8
  92. package/vendor/node_modules/@legendapp/spark-cli/templates/document-editor/io.macos.ts +3 -3
  93. package/vendor/node_modules/@legendapp/spark-cli/templates/example-shared/Lifecycle.desktop.tsx +8 -14
  94. package/vendor/node_modules/@legendapp/spark-cli/templates/example-shared/OpenFiles.desktop.tsx +5 -10
  95. package/vendor/node_modules/@legendapp/spark-cli/templates/example-shared/io.desktop.ts +11 -8
  96. package/vendor/node_modules/@legendapp/spark-cli/templates/example-shared/io.macos.ts +3 -3
  97. package/vendor/node_modules/@legendapp/spark-cli/templates/music-lite/assets.desktop.ts +2 -2
  98. package/vendor/node_modules/@legendapp/spark-cli/templates/notes-lite/Activation.desktop.tsx +2 -2
  99. package/vendor/node_modules/@legendapp/spark-cli/templates/notes-lite/Desktop.desktop.ts +37 -15
  100. package/vendor/node_modules/@legendapp/spark-cli/templates/notes-lite/session.ts +5 -6
  101. package/vendor/node_modules/@legendapp/spark-cli/templates/notes-lite/window-session.ts +5 -4
  102. package/vendor/node_modules/@legendapp/spark-cli/templates/universal/desktop.config.json +5 -3
  103. package/vendor/node_modules/@legendapp/spark-cli/templates/universal/metro.config.js +1 -1
  104. package/vendor/node_modules/@legendapp/spark-cli/templates/universal/package.json +13 -11
  105. package/vendor/node_modules/@legendapp/spark-cli/templates/universal/react-native.config.js +1 -1
  106. package/vendor/node_modules/@legendapp/spark-cli/templates/windows/package.json +13 -11
  107. package/vendor/node_modules/@legendapp/spark-cli/templates/windows/react-native.config.js +1 -1
  108. package/vendor/node_modules/@legendapp/spark-clipboard/macos/RNDesktopClipboard.mm +10 -16
  109. package/vendor/node_modules/@legendapp/spark-clipboard/package.json +2 -2
  110. package/vendor/node_modules/@legendapp/spark-clipboard/src/NativeDesktopClipboard.ts +1 -1
  111. package/vendor/node_modules/@legendapp/spark-clipboard/src/desktop.ts +55 -31
  112. package/vendor/node_modules/@legendapp/spark-clipboard/src/expo.ts +21 -11
  113. package/vendor/node_modules/@legendapp/spark-clipboard/src/options.ts +8 -0
  114. package/vendor/node_modules/@legendapp/spark-clipboard/src/types.ts +10 -0
  115. package/vendor/node_modules/@legendapp/spark-clipboard/windows/SparkClipboard/SparkClipboard.h +38 -15
  116. package/vendor/node_modules/@legendapp/spark-clipboard/windows/SparkClipboard/SparkClipboard.vcxproj +2 -0
  117. package/vendor/node_modules/@legendapp/spark-codex/RNCodex.podspec +22 -0
  118. package/vendor/node_modules/@legendapp/spark-codex/cpp/HybridCodexAppServer.hpp +23 -0
  119. package/vendor/node_modules/@legendapp/spark-codex/cpp/HybridCodexAppServer.mm +1529 -0
  120. package/vendor/node_modules/@legendapp/spark-codex/nitro.json +21 -0
  121. package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/.gitattributes +1 -0
  122. package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/ios/RNCodex+autolinking.rb +62 -0
  123. package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/ios/RNCodex-Swift-Cxx-Bridge.cpp +17 -0
  124. package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/ios/RNCodex-Swift-Cxx-Bridge.hpp +27 -0
  125. package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/ios/RNCodex-Swift-Cxx-Umbrella.hpp +38 -0
  126. package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/ios/RNCodexAutolinking.mm +35 -0
  127. package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/ios/RNCodexAutolinking.swift +16 -0
  128. package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/shared/c++/CodexAvailability.hpp +95 -0
  129. package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/shared/c++/CodexRunResult.hpp +99 -0
  130. package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/shared/c++/HybridCodexAppServerSpec.cpp +24 -0
  131. package/vendor/node_modules/@legendapp/spark-codex/nitrogen/generated/shared/c++/HybridCodexAppServerSpec.hpp +71 -0
  132. package/vendor/node_modules/@legendapp/spark-codex/package.json +35 -0
  133. package/vendor/node_modules/@legendapp/spark-codex/react-native.config.js +11 -0
  134. package/vendor/node_modules/@legendapp/spark-codex/src/Codex.nitro.ts +30 -0
  135. package/vendor/node_modules/@legendapp/spark-codex/src/index.ts +65 -0
  136. package/vendor/node_modules/@legendapp/spark-codex/src/native.ts +6 -0
  137. package/vendor/node_modules/@legendapp/spark-commands/package.json +21 -0
  138. package/vendor/node_modules/@legendapp/spark-commands/src/bindings.ts +90 -0
  139. package/vendor/node_modules/@legendapp/spark-commands/src/index.tsx +400 -0
  140. package/vendor/node_modules/@legendapp/spark-commands/src/router.ts +138 -0
  141. package/vendor/node_modules/@legendapp/spark-commands/src/storage.ts +20 -0
  142. package/vendor/node_modules/@legendapp/spark-context-menu/macos/RNContextMenu.mm +7 -8
  143. package/vendor/node_modules/@legendapp/spark-context-menu/package.json +4 -3
  144. package/vendor/node_modules/@legendapp/spark-context-menu/src/NativeContextMenu.ts +1 -1
  145. package/vendor/node_modules/@legendapp/spark-context-menu/src/index.ts +26 -26
  146. package/vendor/node_modules/@legendapp/spark-context-menu/windows/SparkContextMenu/SparkContextMenu.h +3 -2
  147. package/vendor/node_modules/@legendapp/spark-desktop-app/RNDesktopApp.podspec +2 -1
  148. package/vendor/node_modules/@legendapp/spark-desktop-app/cpp/SparkBinaryJSI.hpp +89 -0
  149. package/vendor/node_modules/@legendapp/spark-desktop-app/cpp/SparkBinaryWindows.hpp +22 -0
  150. package/vendor/node_modules/@legendapp/spark-desktop-app/macos/RNDesktopApp.mm +13 -7
  151. package/vendor/node_modules/@legendapp/spark-desktop-app/macos/SparkBinaryJSI.h +48 -0
  152. package/vendor/node_modules/@legendapp/spark-desktop-app/macos/SparkDesktop.h +4 -0
  153. package/vendor/node_modules/@legendapp/spark-desktop-app/macos/SparkDesktop.mm +33 -33
  154. package/vendor/node_modules/@legendapp/spark-desktop-app/macos/SparkDesktopError.h +20 -0
  155. package/vendor/node_modules/@legendapp/spark-desktop-app/macos/SparkLifecycle.h +26 -0
  156. package/vendor/node_modules/@legendapp/spark-desktop-app/macos/SparkLifecycle.mm +49 -0
  157. package/vendor/node_modules/@legendapp/spark-desktop-app/macos/SparkQuitCoordinator.h +9 -0
  158. package/vendor/node_modules/@legendapp/spark-desktop-app/macos/SparkQuitCoordinator.mm +70 -0
  159. package/vendor/node_modules/@legendapp/spark-desktop-app/macos/SparkWindow.mm +9 -6
  160. package/vendor/node_modules/@legendapp/spark-desktop-app/macos/recent-documents/RNRecentDocumentController.mm +55 -0
  161. package/vendor/node_modules/@legendapp/spark-desktop-app/package.json +5 -3
  162. package/vendor/node_modules/@legendapp/spark-desktop-app/src/NativeDesktopApp.ts +1 -1
  163. package/vendor/node_modules/@legendapp/spark-desktop-app/src/api.ts +86 -40
  164. package/vendor/node_modules/@legendapp/spark-desktop-app/src/contracts/accelerator.ts +40 -0
  165. package/vendor/node_modules/@legendapp/spark-desktop-app/src/contracts/index.ts +56 -0
  166. package/vendor/node_modules/@legendapp/spark-desktop-app/src/contracts/menu.ts +114 -0
  167. package/vendor/node_modules/@legendapp/spark-desktop-app/src/contracts/native-buffer.ts +22 -0
  168. package/vendor/node_modules/@legendapp/spark-desktop-app/src/contracts/path.ts +24 -0
  169. package/vendor/node_modules/@legendapp/spark-desktop-app/src/events.ts +75 -0
  170. package/vendor/node_modules/@legendapp/spark-desktop-app/src/index.ts +2 -0
  171. package/vendor/node_modules/@legendapp/spark-desktop-app/src/index.windows.ts +2 -0
  172. package/vendor/node_modules/@legendapp/spark-desktop-app/src/open-requests.ts +43 -0
  173. package/vendor/node_modules/@legendapp/spark-desktop-app/src/restoration.ts +11 -0
  174. package/vendor/node_modules/@legendapp/spark-desktop-app/src/transport.ts +10 -0
  175. package/vendor/node_modules/@legendapp/spark-desktop-config/app.plugin.cjs +10 -5
  176. package/vendor/node_modules/@legendapp/spark-desktop-config/app.plugin.d.cts +3 -0
  177. package/vendor/node_modules/@legendapp/spark-desktop-config/autolinking.cjs +35 -0
  178. package/vendor/node_modules/@legendapp/spark-desktop-config/config.cjs +16 -3
  179. package/vendor/node_modules/@legendapp/spark-desktop-config/config.d.cts +89 -9
  180. package/vendor/node_modules/@legendapp/spark-desktop-config/expo.d.cts +3 -0
  181. package/vendor/node_modules/@legendapp/spark-desktop-config/identity.cjs +3 -2
  182. package/vendor/node_modules/@legendapp/spark-desktop-config/lifecycle.cjs +20 -0
  183. package/vendor/node_modules/@legendapp/spark-desktop-config/package.json +6 -5
  184. package/vendor/node_modules/@legendapp/spark-desktop-config/schema.json +276 -58
  185. package/vendor/node_modules/@legendapp/spark-desktop-config/updates.cjs +1 -0
  186. package/vendor/node_modules/@legendapp/spark-desktop-config/validation.cjs +35 -0
  187. package/vendor/node_modules/@legendapp/spark-desktop-config/windows.plugin.cjs +2 -1
  188. package/vendor/node_modules/@legendapp/spark-desktop-host/AppDelegate.mm +129 -11
  189. package/vendor/node_modules/@legendapp/spark-desktop-host/package.json +2 -2
  190. package/vendor/node_modules/@legendapp/spark-desktop-host/windows/application.inc +277 -121
  191. package/vendor/node_modules/@legendapp/spark-desktop-links/common/AuthLoopback.h +5 -7
  192. package/vendor/node_modules/@legendapp/spark-desktop-links/macos/RNDesktopLinks.mm +10 -9
  193. package/vendor/node_modules/@legendapp/spark-desktop-links/package.json +2 -2
  194. package/vendor/node_modules/@legendapp/spark-desktop-links/src/NativeDesktopLinks.ts +1 -1
  195. package/vendor/node_modules/@legendapp/spark-desktop-links/src/api.ts +27 -33
  196. package/vendor/node_modules/@legendapp/spark-desktop-links/src/expo.ts +3 -4
  197. package/vendor/node_modules/@legendapp/spark-desktop-links/src/native.ts +9 -0
  198. package/vendor/node_modules/@legendapp/spark-desktop-links/windows/SparkLinks/SparkLinks.h +22 -22
  199. package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/RNDesktopShortcuts.podspec +1 -0
  200. package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/macos/RNDesktopShortcuts.mm +1 -1
  201. package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/macos/keyboard-manager/RNKeyboardManager.h +9 -0
  202. package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/macos/keyboard-manager/RNKeyboardManager.mm +307 -0
  203. package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/package.json +8 -5
  204. package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/src/NativeDesktopShortcuts.ts +1 -1
  205. package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/src/api.ts +39 -14
  206. package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/src/keyboard-manager/NativeKeyboardManager.ts +12 -0
  207. package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/src/keyboard-manager/codes.ts +108 -0
  208. package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/src/keyboard-manager/index.ts +99 -0
  209. package/vendor/node_modules/@legendapp/spark-desktop-windows/RNDesktopWindows.podspec +2 -0
  210. package/vendor/node_modules/@legendapp/spark-desktop-windows/macos/RNDesktopWindows.mm +229 -103
  211. package/vendor/node_modules/@legendapp/spark-desktop-windows/macos/SparkWindowGeometry.h +63 -0
  212. package/vendor/node_modules/@legendapp/spark-desktop-windows/macos/window-manager/LegendWindowRegistry.h +20 -0
  213. package/vendor/node_modules/@legendapp/spark-desktop-windows/macos/window-manager/LegendWindowRegistry.mm +27 -0
  214. package/vendor/node_modules/@legendapp/spark-desktop-windows/macos/window-manager/RNWindowManager.h +12 -0
  215. package/vendor/node_modules/@legendapp/spark-desktop-windows/macos/window-manager/RNWindowManager.mm +3130 -0
  216. package/vendor/node_modules/@legendapp/spark-desktop-windows/macos/window-manager/RNWindowManagerStartup.mm +31 -0
  217. package/vendor/node_modules/@legendapp/spark-desktop-windows/macos/window-manager/SidebarStartupFallbacks.mm +14 -0
  218. package/vendor/node_modules/@legendapp/spark-desktop-windows/package.json +10 -6
  219. package/vendor/node_modules/@legendapp/spark-desktop-windows/src/NativeDesktopWindowManager.ts +1 -1
  220. package/vendor/node_modules/@legendapp/spark-desktop-windows/src/api.ts +144 -70
  221. package/vendor/node_modules/@legendapp/spark-desktop-windows/src/diagnostics.ts +17 -0
  222. package/vendor/node_modules/@legendapp/spark-desktop-windows/src/index.ts +3 -1
  223. package/vendor/node_modules/@legendapp/spark-desktop-windows/src/index.windows.ts +3 -1
  224. package/vendor/node_modules/@legendapp/spark-desktop-windows/src/macos-adapter.ts +53 -0
  225. package/vendor/node_modules/@legendapp/spark-desktop-windows/src/macos.ts +51 -0
  226. package/vendor/node_modules/@legendapp/spark-desktop-windows/src/transport.ts +41 -0
  227. package/vendor/node_modules/@legendapp/spark-desktop-windows/src/types.ts +140 -0
  228. package/vendor/node_modules/@legendapp/spark-desktop-windows/src/validation.ts +162 -0
  229. package/vendor/node_modules/@legendapp/spark-desktop-windows/src/window-manager/NativeWindowManager.ts +28 -0
  230. package/vendor/node_modules/@legendapp/spark-desktop-windows/src/windows/WindowProvider.tsx +20 -0
  231. package/vendor/node_modules/@legendapp/spark-desktop-windows/src/windows/createWindowsNavigator.tsx +78 -0
  232. package/vendor/node_modules/@legendapp/spark-desktop-windows/src/windows/index.ts +6 -0
  233. package/vendor/node_modules/@legendapp/spark-desktop-windows/src/windows/primaryWindowLifecycle.ts +34 -0
  234. package/vendor/node_modules/@legendapp/spark-desktop-windows/src/windows/types.ts +11 -0
  235. package/vendor/node_modules/@legendapp/spark-desktop-windows/src/windows/usePrimaryWindowLifecycle.ts +18 -0
  236. package/vendor/node_modules/@legendapp/spark-desktop-windows/src/windows/useWindowFocusEffect.ts +17 -0
  237. package/vendor/node_modules/@legendapp/spark-documents/package.json +22 -0
  238. package/vendor/node_modules/@legendapp/spark-documents/src/controller.ts +97 -0
  239. package/vendor/node_modules/@legendapp/spark-documents/src/documentTransition.ts +13 -0
  240. package/vendor/node_modules/@legendapp/spark-documents/src/hooks.ts +139 -0
  241. package/vendor/node_modules/@legendapp/spark-documents/src/index.tsx +50 -0
  242. package/vendor/node_modules/@legendapp/spark-documents/src/reload.ts +39 -0
  243. package/vendor/node_modules/@legendapp/spark-documents/src/requests.ts +15 -0
  244. package/vendor/node_modules/@legendapp/spark-drag-drop/package.json +4 -3
  245. package/vendor/node_modules/@legendapp/spark-drag-drop/src/DesktopDragViewNativeComponent.ts +1 -1
  246. package/vendor/node_modules/@legendapp/spark-drag-drop/src/contracts.ts +73 -18
  247. package/vendor/node_modules/@legendapp/spark-drag-drop/src/index.tsx +58 -15
  248. package/vendor/node_modules/@legendapp/spark-drag-drop/windows/SparkDragDrop/SparkDragDrop.h +14 -8
  249. package/vendor/node_modules/@legendapp/spark-file-dialog/ios/RNFileDialog.mm +34 -121
  250. package/vendor/node_modules/@legendapp/spark-file-dialog/package.json +12 -5
  251. package/vendor/node_modules/@legendapp/spark-file-dialog/src/NativeFileDialog.ts +1 -5
  252. package/vendor/node_modules/@legendapp/spark-file-dialog/src/index.ts +19 -84
  253. package/vendor/node_modules/@legendapp/spark-file-dialog/src/native.ts +12 -0
  254. package/vendor/node_modules/@legendapp/spark-file-dialog/src/options.ts +34 -14
  255. package/vendor/node_modules/@legendapp/spark-file-dialog/src/types.ts +26 -0
  256. package/vendor/node_modules/@legendapp/spark-file-dialog/windows/SparkFileDialog/SparkFileDialog.h +42 -58
  257. package/vendor/node_modules/@legendapp/spark-file-system/RNDesktopFileSystem.podspec +1 -0
  258. package/vendor/node_modules/@legendapp/spark-file-system/macos/RNDesktopFileSystem.mm +32 -21
  259. package/vendor/node_modules/@legendapp/spark-file-system/macos/SparkFileMutations.h +24 -0
  260. package/vendor/node_modules/@legendapp/spark-file-system/macos/SparkFileMutations.mm +215 -0
  261. package/vendor/node_modules/@legendapp/spark-file-system/macos/file-scanner/RNFileScanner.h +9 -0
  262. package/vendor/node_modules/@legendapp/spark-file-system/macos/file-scanner/RNFileScanner.mm +82 -0
  263. package/vendor/node_modules/@legendapp/spark-file-system/macos/file-scanner/RNFileScannerCore.h +47 -0
  264. package/vendor/node_modules/@legendapp/spark-file-system/macos/file-scanner/RNFileScannerCore.mm +306 -0
  265. package/vendor/node_modules/@legendapp/spark-file-system/package.json +8 -6
  266. package/vendor/node_modules/@legendapp/spark-file-system/src/NativeDesktopFileSystem.ts +1 -1
  267. package/vendor/node_modules/@legendapp/spark-file-system/src/file-scanner/NativeFileScanner.ts +11 -0
  268. package/vendor/node_modules/@legendapp/spark-file-system/src/file-scanner/index.ts +93 -0
  269. package/vendor/node_modules/@legendapp/spark-file-system/src/handles.ts +48 -14
  270. package/vendor/node_modules/@legendapp/spark-file-system/src/index.ts +134 -45
  271. package/vendor/node_modules/@legendapp/spark-file-system/src/path.ts +1 -9
  272. package/vendor/node_modules/@legendapp/spark-file-system/windows/SparkFileSystem/SparkFileSystem.h +102 -26
  273. package/vendor/node_modules/@legendapp/spark-file-system/windows/SparkFileSystem/SparkFileSystem.vcxproj +2 -0
  274. package/vendor/node_modules/@legendapp/spark-global-shortcuts/RNDesktopGlobalShortcuts.podspec +1 -0
  275. package/vendor/node_modules/@legendapp/spark-global-shortcuts/macos/RNDesktopGlobalShortcuts.mm +7 -4
  276. package/vendor/node_modules/@legendapp/spark-global-shortcuts/package.json +4 -3
  277. package/vendor/node_modules/@legendapp/spark-global-shortcuts/src/NativeDesktopGlobalShortcuts.ts +1 -1
  278. package/vendor/node_modules/@legendapp/spark-global-shortcuts/src/index.ts +39 -10
  279. package/vendor/node_modules/@legendapp/spark-global-shortcuts/windows/SparkGlobalShortcuts/SparkGlobalShortcuts.h +5 -4
  280. package/vendor/node_modules/@legendapp/spark-message-dialog/macos/RNDesktopMessageDialog.mm +2 -2
  281. package/vendor/node_modules/@legendapp/spark-message-dialog/package.json +2 -2
  282. package/vendor/node_modules/@legendapp/spark-message-dialog/src/NativeDesktopMessageDialog.ts +1 -1
  283. package/vendor/node_modules/@legendapp/spark-message-dialog/src/index.ts +48 -11
  284. package/vendor/node_modules/@legendapp/spark-native-menu/ios/RNNativeMenu.mm +141 -609
  285. package/vendor/node_modules/@legendapp/spark-native-menu/package.json +9 -4
  286. package/vendor/node_modules/@legendapp/spark-native-menu/src/NativeMenu.ts +2 -7
  287. package/vendor/node_modules/@legendapp/spark-native-menu/src/api.ts +76 -121
  288. package/vendor/node_modules/@legendapp/spark-native-menu/src/hooks.ts +97 -0
  289. package/vendor/node_modules/@legendapp/spark-native-menu/src/windows-menus.ts +43 -37
  290. package/vendor/node_modules/@legendapp/spark-notifications/macos/RNDesktopNotifications.mm +75 -30
  291. package/vendor/node_modules/@legendapp/spark-notifications/package.json +2 -2
  292. package/vendor/node_modules/@legendapp/spark-notifications/src/NativeDesktopNotifications.ts +1 -1
  293. package/vendor/node_modules/@legendapp/spark-notifications/src/index.ts +130 -42
  294. package/vendor/node_modules/@legendapp/spark-notifications/windows/SparkNotifications/SparkNotifications.h +46 -8
  295. package/vendor/node_modules/@legendapp/spark-processes/macos/RNDesktopProcesses.mm +94 -21
  296. package/vendor/node_modules/@legendapp/spark-processes/package.json +4 -3
  297. package/vendor/node_modules/@legendapp/spark-processes/src/NativeDesktopProcesses.ts +1 -1
  298. package/vendor/node_modules/@legendapp/spark-processes/src/index.ts +124 -28
  299. package/vendor/node_modules/@legendapp/spark-processes/src/types.ts +34 -0
  300. package/vendor/node_modules/@legendapp/spark-processes/windows/SparkProcesses/SparkProcesses.h +83 -34
  301. package/vendor/node_modules/@legendapp/spark-processes/windows/SparkProcesses/SparkProcesses.vcxproj +2 -0
  302. package/vendor/node_modules/@legendapp/spark-secure-storage/macos/RNDesktopSecureStorage.mm +49 -40
  303. package/vendor/node_modules/@legendapp/spark-secure-storage/package.json +2 -2
  304. package/vendor/node_modules/@legendapp/spark-secure-storage/src/NativeDesktopSecureStorage.ts +1 -1
  305. package/vendor/node_modules/@legendapp/spark-secure-storage/src/desktop.ts +16 -14
  306. package/vendor/node_modules/@legendapp/spark-secure-storage/src/expo.ts +0 -1
  307. package/vendor/node_modules/@legendapp/spark-secure-storage/src/options.ts +3 -2
  308. package/vendor/node_modules/@legendapp/spark-secure-storage/src/unavailable.ts +6 -3
  309. package/vendor/node_modules/@legendapp/spark-settings/package.json +10 -3
  310. package/vendor/node_modules/@legendapp/spark-settings/src/fileStorage.ts +11 -0
  311. package/vendor/node_modules/@legendapp/spark-settings/src/index.ts +7 -9
  312. package/vendor/node_modules/@legendapp/spark-settings/src/storage/index.ts +142 -0
  313. package/vendor/node_modules/@legendapp/spark-settings/src/store.ts +63 -21
  314. package/vendor/node_modules/@legendapp/spark-settings-ui/package.json +20 -0
  315. package/vendor/node_modules/@legendapp/spark-settings-ui/src/index.tsx +436 -0
  316. package/vendor/node_modules/@legendapp/spark-settings-ui/src/options.ts +10 -0
  317. package/vendor/node_modules/@legendapp/spark-sqlite/package.json +3 -3
  318. package/vendor/node_modules/@legendapp/spark-sqlite/src/database.ts +182 -0
  319. package/vendor/node_modules/@legendapp/spark-sqlite/src/index.ts +19 -6
  320. package/vendor/node_modules/@legendapp/spark-sqlite/src/types.ts +22 -0
  321. package/vendor/node_modules/@legendapp/spark-system/macos/RNDesktopSystem.mm +36 -11
  322. package/vendor/node_modules/@legendapp/spark-system/package.json +2 -2
  323. package/vendor/node_modules/@legendapp/spark-system/src/NativeDesktopSystem.ts +1 -1
  324. package/vendor/node_modules/@legendapp/spark-system/src/index.ts +89 -32
  325. package/vendor/node_modules/@legendapp/spark-system/windows/SparkSystem/SparkSystem.h +8 -4
  326. package/vendor/node_modules/@legendapp/spark-tray/macos/RNDesktopTray.mm +20 -8
  327. package/vendor/node_modules/@legendapp/spark-tray/package.json +2 -2
  328. package/vendor/node_modules/@legendapp/spark-tray/src/NativeDesktopTray.ts +1 -1
  329. package/vendor/node_modules/@legendapp/spark-tray/src/index.ts +91 -34
  330. package/vendor/node_modules/@legendapp/spark-tray/windows/SparkTray/SparkTray.h +45 -15
  331. package/vendor/node_modules/@legendapp/spark-ui/macos/RNSparkButton.mm +2 -1
  332. package/vendor/node_modules/@legendapp/spark-ui/macos/RNSparkTextInput.mm +10 -2
  333. package/vendor/node_modules/@legendapp/spark-ui/macos/appkit-split-view/RNSidebarSplitViewComponent.h +15 -0
  334. package/vendor/node_modules/@legendapp/spark-ui/macos/appkit-split-view/RNSidebarSplitViewComponent.mm +1182 -0
  335. package/vendor/node_modules/@legendapp/spark-ui/macos/glass-effect-view/RNGlassEffectView.mm +72 -0
  336. package/vendor/node_modules/@legendapp/spark-ui/macos/native-select/RNNativeSegmentedControl.h +15 -0
  337. package/vendor/node_modules/@legendapp/spark-ui/macos/native-select/RNNativeSegmentedControl.mm +194 -0
  338. package/vendor/node_modules/@legendapp/spark-ui/macos/native-select/RNNativeSelect.h +15 -0
  339. package/vendor/node_modules/@legendapp/spark-ui/macos/native-select/RNNativeSelect.mm +180 -0
  340. package/vendor/node_modules/@legendapp/spark-ui/macos/sf-symbol/RNSFSymbol.h +15 -0
  341. package/vendor/node_modules/@legendapp/spark-ui/macos/sf-symbol/RNSFSymbol.mm +155 -0
  342. package/vendor/node_modules/@legendapp/spark-ui/macos/sidebar/RNSidebar.h +18 -0
  343. package/vendor/node_modules/@legendapp/spark-ui/macos/sidebar/RNSidebar.mm +645 -0
  344. package/vendor/node_modules/@legendapp/spark-ui/macos/text-input-search/RNTextInputSearch.h +15 -0
  345. package/vendor/node_modules/@legendapp/spark-ui/macos/text-input-search/RNTextInputSearch.mm +164 -0
  346. package/vendor/node_modules/@legendapp/spark-ui/package.json +16 -4
  347. package/vendor/node_modules/@legendapp/spark-ui/src/SparkSelectNativeComponent.ts +3 -1
  348. package/vendor/node_modules/@legendapp/spark-ui/src/SparkTextInputNativeComponent.ts +6 -2
  349. package/vendor/node_modules/@legendapp/spark-ui/src/appkit-split-view/SidebarSplitViewNativeComponent.ts +31 -0
  350. package/vendor/node_modules/@legendapp/spark-ui/src/appkit-split-view/index.tsx +77 -0
  351. package/vendor/node_modules/@legendapp/spark-ui/src/availability.ts +10 -0
  352. package/vendor/node_modules/@legendapp/spark-ui/src/classnames/index.ts +8 -0
  353. package/vendor/node_modules/@legendapp/spark-ui/src/control.ts +42 -0
  354. package/vendor/node_modules/@legendapp/spark-ui/src/desktop.tsx +56 -0
  355. package/vendor/node_modules/@legendapp/spark-ui/src/glass-effect-view/index.tsx +15 -0
  356. package/vendor/node_modules/@legendapp/spark-ui/src/index.android.tsx +35 -21
  357. package/vendor/node_modules/@legendapp/spark-ui/src/index.ios.tsx +55 -26
  358. package/vendor/node_modules/@legendapp/spark-ui/src/index.tsx +1 -27
  359. package/vendor/node_modules/@legendapp/spark-ui/src/index.web.tsx +45 -14
  360. package/vendor/node_modules/@legendapp/spark-ui/src/index.windows.tsx +1 -42
  361. package/vendor/node_modules/@legendapp/spark-ui/src/mobile-input.tsx +11 -0
  362. package/vendor/node_modules/@legendapp/spark-ui/src/native-select/NativeSegmentedControlNativeComponent.ts +17 -0
  363. package/vendor/node_modules/@legendapp/spark-ui/src/native-select/NativeSelectNativeComponent.ts +17 -0
  364. package/vendor/node_modules/@legendapp/spark-ui/src/select.ts +5 -3
  365. package/vendor/node_modules/@legendapp/spark-ui/src/sf-symbol/SFSymbolNativeComponent.ts +13 -0
  366. package/vendor/node_modules/@legendapp/spark-ui/src/sf-symbol/index.tsx +27 -0
  367. package/vendor/node_modules/@legendapp/spark-ui/src/sidebar/SidebarItemNativeComponent.ts +25 -0
  368. package/vendor/node_modules/@legendapp/spark-ui/src/sidebar/SidebarNativeComponent.ts +24 -0
  369. package/vendor/node_modules/@legendapp/spark-ui/src/sidebar/index.tsx +104 -0
  370. package/vendor/node_modules/@legendapp/spark-ui/src/specialized.ts +22 -0
  371. package/vendor/node_modules/@legendapp/spark-ui/src/text-input-search/TextInputSearchNativeComponent.ts +33 -0
  372. package/vendor/node_modules/@legendapp/spark-ui/src/text-input-search/index.tsx +34 -0
  373. package/vendor/node_modules/@legendapp/spark-ui/src/types.ts +30 -19
  374. package/vendor/node_modules/@legendapp/spark-ui/uniwind.ts +3 -1
  375. package/vendor/node_modules/@legendapp/spark-ui/uniwind.web.ts +3 -1
  376. package/vendor/node_modules/@legendapp/spark-ui/windows/SparkUI/SparkUI.h +16 -11
  377. package/vendor/node_modules/@legendapp/spark-updates/macos/RNDesktopUpdates.mm +21 -8
  378. package/vendor/node_modules/@legendapp/spark-updates/package.json +2 -2
  379. package/vendor/node_modules/@legendapp/spark-updates/src/NativeDesktopUpdates.ts +3 -2
  380. package/vendor/node_modules/@legendapp/spark-updates/src/index.ts +71 -15
  381. package/vendor/node_modules/@legendapp/spark-webview/package.json +2 -2
  382. package/vendor/node_modules/@legendapp/spark-webview/src/WebView.tsx +11 -0
  383. package/vendor/node_modules/@legendapp/spark-webview/src/adapter.ts +55 -0
  384. package/vendor/node_modules/@legendapp/spark-webview/src/index.ts +2 -2
  385. package/vendor/node_modules/@legendapp/spark-webview/src/types.ts +32 -0
  386. package/vendor/node_modules/@legendapp/spark-webview/src/view-props.ts +28 -0
  387. package/vendor/node_modules/@legendapp/spark-window-options/index.cjs +51 -14
  388. package/vendor/node_modules/@legendapp/spark-window-options/index.d.ts +21 -8
  389. package/vendor/node_modules/@legendapp/spark-window-options/package.json +1 -1
  390. package/windows-macos.ts +1 -0
  391. package/expo-metro.cjs +0 -1
  392. package/message-dialog.ts +0 -1
  393. package/universal.cjs +0 -1
  394. package/vendor/node_modules/@legendapp/spark-desktop-shortcuts/src/accelerator.ts +0 -22
  395. package/vendor/node_modules/@legendapp/spark-desktop-windows/src/windows-options.ts +0 -11
  396. package/vendor/node_modules/@legendapp/spark-file-dialog/src/index.windows.ts +0 -15
  397. package/vendor/node_modules/@legendapp/spark-global-shortcuts/src/accelerator.ts +0 -22
  398. package/vendor/node_modules/@legendapp/spark-ui/macos/RNSparkSelect.h +0 -4
  399. package/vendor/node_modules/@legendapp/spark-ui/macos/RNSparkSelect.mm +0 -53
@@ -1,28 +1,39 @@
1
+ import type { Ref } from "react";
1
2
  import type { StyleProp, ViewStyle } from "react-native";
2
-
3
+ import type { SparkError } from "@legendapp/spark-desktop-app/src/contracts";
4
+ /** A layout-only ref; backend objects and native control methods stay internal. */
5
+ export interface ControlRef { measureInWindow(callback: (x: number, y: number, width: number, height: number) => void): void }
6
+ export interface ControlProps {
7
+ disabled?: boolean;
8
+ accessibilityLabel?: string;
9
+ style?: StyleProp<ViewStyle>;
10
+ testID?: string;
11
+ ref?: Ref<ControlRef>;
12
+ onError?: (error: SparkError) => void;
13
+ }
3
14
  /** A native text button. Layout styles affect its frame, not OS-managed chrome. */
4
- export type ButtonProps = {
15
+ export interface ButtonProps extends ControlProps {
5
16
  children: string;
6
17
  onPress?: () => void;
7
- disabled?: boolean;
8
18
  variant?: "default" | "bordered" | "borderless";
9
- style?: StyleProp<ViewStyle>;
10
- testID?: string;
11
- };
12
-
13
- /** Uncontrolled single-line input. defaultValue is read once per mount. */
14
- export type TextInputProps = {
19
+ }
20
+ export interface ControlledTextInputProps extends ControlProps {
21
+ value: string;
22
+ defaultValue?: never;
23
+ onChangeText?: (text: string) => void;
24
+ }
25
+ export interface UncontrolledTextInputProps extends ControlProps {
26
+ value?: never;
27
+ /** Read only on mount. Remount to reset an uncontrolled input. */
15
28
  defaultValue?: string;
16
29
  onChangeText?: (text: string) => void;
17
- accessibilityLabel?: string;
18
- style?: StyleProp<ViewStyle>;
19
- testID?: string;
20
- };
21
- export type SelectProps = {
22
- options: readonly { label: string; value: string }[];
30
+ }
31
+ export type TextInputProps = ControlledTextInputProps | UncontrolledTextInputProps;
32
+ export interface SelectOption { label: string; value: string }
33
+ export interface SelectProps extends ControlProps {
34
+ options: readonly SelectOption[];
23
35
  value: string;
24
36
  onValueChange: (value: string) => void;
25
- accessibilityLabel?: string;
26
- style?: StyleProp<ViewStyle>;
27
- testID?: string;
28
- };
37
+ }
38
+ export interface SegmentedControlProps extends SelectProps {}
39
+ export type ControlKind = "button" | "text-input" | "select" | "segmented-control";
@@ -1,8 +1,10 @@
1
1
  import { withUniwind } from "uniwind";
2
- import { Button as NativeButton, TextInput as NativeTextInput, Select as NativeSelect } from "./src/index";
2
+ import { Button as NativeButton, TextInput as NativeTextInput, Select as NativeSelect, SegmentedControl as NativeSegmentedControl } from "./src/index";
3
3
 
4
4
  // Optional, module-level bindings preserve each platform's native implementation.
5
5
  // className maps to the existing layout style; explicit style wins on conflicts.
6
6
  export const Button = withUniwind(NativeButton);
7
7
  export const TextInput = withUniwind(NativeTextInput);
8
8
  export const Select = withUniwind(NativeSelect);
9
+
10
+ export const SegmentedControl = withUniwind(NativeSegmentedControl);
@@ -1,7 +1,7 @@
1
1
  import { createElement, type ComponentType } from "react";
2
2
  import type { StyleProp, ViewStyle } from "react-native";
3
3
  import { useResolveClassNames } from "uniwind";
4
- import { Button as NativeButton, TextInput as NativeTextInput, Select as NativeSelect } from "./src/index";
4
+ import { Button as NativeButton, TextInput as NativeTextInput, Select as NativeSelect, SegmentedControl as NativeSegmentedControl } from "./src/index";
5
5
 
6
6
  function withSparkClasses<Props extends { style?: StyleProp<ViewStyle> }>(Component: ComponentType<Props>) {
7
7
  return function UniwindControl({ className = "", style, ...props }: Props & { className?: string }) {
@@ -15,3 +15,5 @@ function withSparkClasses<Props extends { style?: StyleProp<ViewStyle> }>(Compon
15
15
  export const Button = withSparkClasses(NativeButton);
16
16
  export const TextInput = withSparkClasses(NativeTextInput);
17
17
  export const Select = withSparkClasses(NativeSelect);
18
+
19
+ export const SegmentedControl = withSparkClasses(NativeSegmentedControl);
@@ -16,18 +16,17 @@ namespace React = Microsoft::ReactNative;
16
16
  namespace Composition = Microsoft::ReactNative::Composition;
17
17
  namespace Xaml = Microsoft::UI::Xaml;
18
18
  namespace Json = Windows::Data::Json;
19
- REACT_MODULE(SparkUIAvailability, L"NativeSparkUI")
20
- struct SparkUIAvailability {
21
- REACT_SYNC_METHOD(isAvailable)
22
- bool isAvailable() noexcept { return true; }
23
- };
24
19
  struct Props : implements<Props, React::IComponentProps> {
25
20
  React::ViewProps view{nullptr};
26
- std::string title, defaultText, itemsJson = "[]", value, variant = "default";
27
- bool disabled = false;
21
+ std::string title, defaultText, text, itemsJson = "[]", value, variant = "default";
22
+ bool disabled = false, controlled = false;
23
+ int32_t eventCount = 0;
28
24
  void SetProp(uint32_t, hstring const &name, React::IJSValueReader const &reader) noexcept {
29
25
  if (name == L"title") React::ReadValue(reader, title);
30
26
  else if (name == L"defaultText") React::ReadValue(reader, defaultText);
27
+ else if (name == L"text") React::ReadValue(reader, text);
28
+ else if (name == L"controlled") React::ReadValue(reader, controlled);
29
+ else if (name == L"eventCount") React::ReadValue(reader, eventCount);
31
30
  else if (name == L"itemsJson") React::ReadValue(reader, itemsJson);
32
31
  else if (name == L"value") React::ReadValue(reader, value);
33
32
  else if (name == L"variant") React::ReadValue(reader, variant);
@@ -56,10 +55,13 @@ struct Control : implements<Control, Windows::Foundation::IInspectable> {
56
55
  std::string kind, failure, items;
57
56
  std::vector<std::string> values;
58
57
  bool initialized = false, updating = false;
58
+ int32_t eventCount = 0;
59
59
  void Emit(hstring const &name, std::string const &key = "", std::string const &value = "") {
60
- if (emitter) emitter.DispatchEvent(name, [key, value](React::IJSValueWriter const &writer) {
60
+ const auto count = eventCount;
61
+ if (emitter) emitter.DispatchEvent(name, [key, value, name, count](React::IJSValueWriter const &writer) {
61
62
  writer.WriteObjectBegin();
62
63
  if (!key.empty()) { writer.WritePropertyName(to_hstring(key)); writer.WriteString(to_hstring(value)); }
64
+ if (name == L"textChange") { writer.WritePropertyName(L"eventCount"); writer.WriteInt64(count); }
63
65
  writer.WriteObjectEnd();
64
66
  });
65
67
  }
@@ -78,7 +80,7 @@ struct Control : implements<Control, Windows::Foundation::IInspectable> {
78
80
  } else if (kind == "TextInput") {
79
81
  Xaml::Controls::TextBox input;
80
82
  input.TextChanged([weak](auto const &sender, auto const &) {
81
- if (auto self = weak.get(); self && !self->updating) self->Emit(L"textChange", "text", to_string(sender.template as<Xaml::Controls::TextBox>().Text()));
83
+ if (auto self = weak.get(); self && !self->updating && self->control.IsEnabled()) { ++self->eventCount; self->Emit(L"textChange", "text", to_string(sender.template as<Xaml::Controls::TextBox>().Text())); }
82
84
  });
83
85
  control = input;
84
86
  } else {
@@ -113,14 +115,16 @@ struct Control : implements<Control, Windows::Foundation::IInspectable> {
113
115
  updating = true;
114
116
  control.IsEnabled(!props.disabled);
115
117
  Xaml::Automation::AutomationProperties::SetAutomationId(control, props.view.TestId());
116
- Xaml::Automation::AutomationProperties::SetName(control, kind == "Button" ? to_hstring(props.title) : props.view.AccessibilityLabel());
118
+ Xaml::Automation::AutomationProperties::SetName(control, props.view.AccessibilityLabel().empty() && kind == "Button" ? to_hstring(props.title) : props.view.AccessibilityLabel());
117
119
  if (kind == "Button") {
118
120
  auto button = control.as<Xaml::Controls::Button>();
119
121
  button.Content(box_value(to_hstring(props.title)));
120
122
  // WinUI owns hover, pressed, keyboard, disabled, and accessibility states.
121
123
  button.BorderThickness(props.variant == "borderless" ? Xaml::Thickness{0, 0, 0, 0} : Xaml::Thickness{1, 1, 1, 1});
122
124
  } else if (kind == "TextInput") {
123
- if (!initialized) control.as<Xaml::Controls::TextBox>().Text(to_hstring(props.defaultText));
125
+ auto input = control.as<Xaml::Controls::TextBox>();
126
+ if (!initialized) input.Text(to_hstring(props.defaultText));
127
+ if (props.controlled && props.eventCount >= eventCount && input.Text() != to_hstring(props.text)) input.Text(to_hstring(props.text));
124
128
  } else {
125
129
  auto select = control.as<Xaml::Controls::ComboBox>();
126
130
  if (items != props.itemsJson) {
@@ -153,6 +157,7 @@ inline void RegisterControls(React::IReactPackageBuilder const &package) {
153
157
  if (previous) {
154
158
  auto old = get_self<Props>(previous);
155
159
  props->title = old->title; props->defaultText = old->defaultText; props->itemsJson = old->itemsJson;
160
+ props->text = old->text; props->controlled = old->controlled; props->eventCount = old->eventCount;
156
161
  props->value = old->value; props->variant = old->variant; props->disabled = old->disabled;
157
162
  }
158
163
  props->view = view; return props.as<React::IComponentProps>();
@@ -22,7 +22,7 @@ static NSString *UnavailableReason(void) {
22
22
  + (instancetype)shared { static SparkUpdater *updater; static dispatch_once_t once; dispatch_once(&once, ^{ updater = [SparkUpdater new]; }); return updater; }
23
23
  - (NSDictionary *)status {
24
24
  NSString *reason = UnavailableReason();
25
- NSMutableDictionary *result = [@{ @"available": @(!reason), @"started": @(self.started), @"canCheck": @(self.started && self.controller.updater.canCheckForUpdates), @"automaticallyChecks": @(self.started && self.controller.updater.automaticallyChecksForUpdates) } mutableCopy];
25
+ NSMutableDictionary *result = [@{ @"available": @(!reason), @"started": @(self.started), @"canCheck": @(self.started && self.controller.updater.canCheckForUpdates), @"automaticallyChecks": @(self.started && self.controller.updater.automaticallyChecksForUpdates), @"checkIntervalSeconds": reason ? NSNull.null : @(self.started ? self.controller.updater.updateCheckInterval : 3600) } mutableCopy];
26
26
  if (reason) result[@"reason"] = reason;
27
27
  if (!reason) result[@"feedURL"] = [NSBundle.mainBundle objectForInfoDictionaryKey:@"SUFeedURL"];
28
28
  return result;
@@ -55,17 +55,30 @@ RCT_EXPORT_MODULE(NativeDesktopUpdates)
55
55
  [NSRunLoop.mainRunLoop performBlock:^{
56
56
  SparkUpdater *updater = [SparkUpdater shared];
57
57
  if ([method isEqual:@"status"]) { resolve(SparkJSON([updater status])); return; }
58
- if (![@[@"start", @"check", @"automatic"] containsObject:method]) { SparkInvalid(reject, @"Unknown update operation"); return; }
58
+ if (![@[@"start", @"check", @"background", @"configure"] containsObject:method]) { SparkInvalid(reject, @"Unknown update operation"); return; }
59
+ NSDictionary *args = SparkArgs(json);
60
+ if ([method isEqual:@"configure"]) {
61
+ id enabled = args[@"automaticallyChecks"], interval = args[@"checkIntervalSeconds"];
62
+ if ((enabled && (![enabled isKindOfClass:NSNumber.class] || CFGetTypeID((__bridge CFTypeRef)enabled) != CFBooleanGetTypeID())) ||
63
+ (interval && (![interval isKindOfClass:NSNumber.class] || CFGetTypeID((__bridge CFTypeRef)interval) == CFBooleanGetTypeID() || !isfinite([interval doubleValue]) || [interval doubleValue] <= 0))) {
64
+ SparkInvalid(reject, @"Invalid updater configuration"); return;
65
+ }
66
+ }
59
67
  NSString *reason = UnavailableReason();
60
- if (reason) { reject(@"E_UPDATES_UNAVAILABLE", [@"Updates require a configured standalone release app; current state: " stringByAppendingString:reason], nil); return; }
68
+ if (reason) { reject(@"E_UNAVAILABLE", [@"Updates require a configured standalone release app; current state: " stringByAppendingString:reason], nil); return; }
61
69
  NSError *error = nil;
62
- if (![updater start:&error]) { reject(@"E_UPDATES_START", error.localizedDescription ?: @"Could not start updater", error); return; }
70
+ if (![updater start:&error]) { reject(@"E_NATIVE", error.localizedDescription ?: @"Could not start updater", error); return; }
63
71
  if ([method isEqual:@"check"]) {
64
- if (!updater.controller.updater.canCheckForUpdates) { reject(@"E_UPDATES_BUSY", @"An update session is already running", nil); return; }
72
+ if (!updater.controller.updater.canCheckForUpdates) { reject(@"E_BUSY", @"An update session is already running", nil); return; }
65
73
  [updater.controller checkForUpdates:nil]; resolve(@"null");
66
- } else if ([method isEqual:@"automatic"]) {
67
- updater.controller.updater.automaticallyChecksForUpdates = [SparkArgs(json)[@"enabled"] boolValue]; resolve(@"null");
68
- } else resolve(SparkJSON([updater status]));
74
+ } else if ([method isEqual:@"background"]) {
75
+ if (!updater.controller.updater.canCheckForUpdates) { reject(@"E_BUSY", @"An update session is already running", nil); return; }
76
+ [updater.controller.updater checkForUpdatesInBackground]; resolve(@"null");
77
+ } else if ([method isEqual:@"configure"]) {
78
+ if (args[@"automaticallyChecks"]) updater.controller.updater.automaticallyChecksForUpdates = [args[@"automaticallyChecks"] boolValue];
79
+ if (args[@"checkIntervalSeconds"]) updater.controller.updater.updateCheckInterval = [args[@"checkIntervalSeconds"] doubleValue];
80
+ resolve(@"null");
81
+ } else resolve(@"null");
69
82
  }];
70
83
  }
71
84
  - (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:(const facebook::react::ObjCTurboModule::InitParams &)params { return std::make_shared<facebook::react::NativeDesktopUpdatesSpecJSI>(params); }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@legendapp/spark-updates",
3
- "version": "0.0.1-next.2",
3
+ "version": "0.0.1-next.3",
4
4
  "license": "MIT",
5
5
  "main": "src/index.ts",
6
6
  "react-native": "src/index.ts",
@@ -38,7 +38,7 @@
38
38
  ]
39
39
  },
40
40
  "dependencies": {
41
- "@legendapp/spark-desktop-app": "0.0.1-next.2"
41
+ "@legendapp/spark-desktop-app": "0.0.1-next.3"
42
42
  },
43
43
  "private": true
44
44
  }
@@ -1,4 +1,5 @@
1
1
  import type { TurboModule } from "react-native";
2
2
  import { TurboModuleRegistry } from "react-native";
3
- export interface Spec extends TurboModule { call(method: string, args: string): Promise<string>; }
4
- export default TurboModuleRegistry.getEnforcing<Spec>("NativeDesktopUpdates");
3
+ export interface Spec extends TurboModule {
4
+ call(method: string, args: string): Promise<string>; }
5
+ export default TurboModuleRegistry.get<Spec>("NativeDesktopUpdates");
@@ -1,23 +1,79 @@
1
+ import { Platform } from "react-native";
1
2
  import Native from "./NativeDesktopUpdates";
2
- import { onDesktopEvent } from "@legendapp/spark-desktop-app";
3
+ import { onDesktopEvent } from "@legendapp/spark-desktop-app/src/events";
4
+ import { SparkError, invokeNative, parseNativeResult, type Subscription } from "@legendapp/spark-desktop-app/src/contracts";
5
+ export type { Subscription } from "@legendapp/spark-desktop-app/src/contracts";
3
6
 
7
+ export type UpdateUnavailableReason = "unsupported-platform" | "missing-module" | "go" | "development" | "unconfigured";
4
8
  export type UpdateStatus = {
5
- available: boolean;
6
- reason?: "go" | "development" | "unconfigured";
9
+ available: true;
7
10
  started: boolean;
8
11
  canCheck: boolean;
9
12
  automaticallyChecks: boolean;
10
- feedURL?: string;
13
+ checkIntervalSeconds: number;
14
+ feedURL: string;
15
+ } | {
16
+ available: false;
17
+ reason: UpdateUnavailableReason;
18
+ started: false;
19
+ canCheck: false;
20
+ automaticallyChecks: false;
21
+ checkIntervalSeconds: null;
11
22
  };
12
- export type UpdateEvent = { type: "update"; state: "checking" | "available" | "notAvailable" | "downloading" | "downloaded" | "installing" | "error"; version?: string; message?: string };
13
- async function call<T = void>(method: string, args: object = {}): Promise<T> { return JSON.parse(await Native.call(method, JSON.stringify(args))) as T; }
14
- export const getUpdateStatus = () => call<UpdateStatus>("status");
15
- /** Start Sparkle's scheduler after the application is ready. Safe to call again. */
16
- export const startUpdates = () => call<UpdateStatus>("start");
17
- /** Opens Sparkle's standard check/download/install UI. Resolves when the check starts. */
18
- export const checkForUpdates = () => call("check");
19
- /** Change this only in response to the user's preference; Sparkle persists it. */
20
- export const setAutomaticUpdateChecks = (enabled: boolean) => call("automatic", { enabled });
21
- export function onUpdateEvent(listener: (event: UpdateEvent) => void) {
22
- return onDesktopEvent(event => { if (event.type === "update") listener(event as UpdateEvent); });
23
+ export interface UpdateConfiguration { automaticallyChecks?: boolean; checkIntervalSeconds?: number }
24
+ export interface CheckForUpdatesOptions { mode?: "interactive" | "background" }
25
+ export type UpdateEvent =
26
+ | { type: "update"; state: "checking" | "notAvailable" }
27
+ | { type: "update"; state: "available" | "downloading" | "downloaded" | "installing"; version: string }
28
+ | { type: "update"; state: "error"; message: string };
29
+ function native() {
30
+ if (Platform.OS !== "macos") throw new SparkError("E_UNSUPPORTED_PLATFORM", "Native app updates require macOS");
31
+ if (!Native) throw new SparkError("E_MODULE_UNAVAILABLE", "Native app updater is not installed");
32
+ return Native;
33
+ }
34
+ const unavailable = (reason: UpdateUnavailableReason): UpdateStatus => ({ available: false, reason, started: false, canCheck: false, automaticallyChecks: false, checkIntervalSeconds: null });
35
+ function validStatus(value: unknown): value is UpdateStatus {
36
+ if (!value || typeof value !== "object") return false;
37
+ const status = value as UpdateStatus;
38
+ if (status.available === false) return ["go", "development", "unconfigured"].includes(status.reason) && status.started === false && status.canCheck === false && status.automaticallyChecks === false && status.checkIntervalSeconds === null;
39
+ return status.available === true && typeof status.started === "boolean" && typeof status.canCheck === "boolean" && typeof status.automaticallyChecks === "boolean" && Number.isFinite(status.checkIntervalSeconds) && status.checkIntervalSeconds > 0 && typeof status.feedURL === "string" && status.feedURL.startsWith("https://");
40
+ }
41
+ async function command(method: string, args: object = {}): Promise<void> {
42
+ parseNativeResult(await invokeNative(() => native().call(method, JSON.stringify(args))), (value): value is null => value === null);
43
+ }
44
+ /** Querying never starts the updater. Missing modules and unsupported targets are reported. */
45
+ export async function getUpdateStatus(): Promise<UpdateStatus> {
46
+ if (Platform.OS !== "macos") return unavailable("unsupported-platform");
47
+ if (!Native) return unavailable("missing-module");
48
+ return parseNativeResult(await invokeNative(() => native().call("status", "{}")), validStatus);
49
+ }
50
+ /** Start the scheduler after app readiness. Repeated starts are safe. */
51
+ export async function startUpdates(): Promise<void> { await command("start"); }
52
+ function options(value: unknown, keys: string[]) {
53
+ if (!value || typeof value !== "object" || Array.isArray(value)) throw new SparkError("E_INVALID_ARGUMENT", "Expected update options");
54
+ for (const key of Object.keys(value)) if (!keys.includes(key)) throw new SparkError("E_UNSUPPORTED_OPTION", `Unsupported update option: ${key}`);
55
+ }
56
+ /** Resolves when initiated. Events describe progress, not the returned promise. */
57
+ export async function checkForUpdates(config: CheckForUpdatesOptions = {}): Promise<void> {
58
+ options(config, ["mode"]);
59
+ const mode = config.mode ?? "interactive";
60
+ if (!["interactive", "background"].includes(mode)) throw new SparkError("E_INVALID_ARGUMENT", "Invalid update check mode");
61
+ await command(mode === "interactive" ? "check" : "background");
62
+ }
63
+ /** Omission keeps a preference unchanged. Sparkle persists the user's choices. */
64
+ export async function configureUpdates(config: UpdateConfiguration): Promise<void> {
65
+ options(config, ["automaticallyChecks", "checkIntervalSeconds"]);
66
+ if (config.automaticallyChecks !== undefined && typeof config.automaticallyChecks !== "boolean") throw new SparkError("E_INVALID_ARGUMENT", "automaticallyChecks must be boolean");
67
+ if (config.checkIntervalSeconds !== undefined && (!Number.isFinite(config.checkIntervalSeconds) || config.checkIntervalSeconds <= 0)) throw new SparkError("E_INVALID_ARGUMENT", "Update interval must be positive finite seconds");
68
+ await command("configure", config);
69
+ }
70
+ export function onUpdateEvent(listener: (event: UpdateEvent) => void): Subscription {
71
+ if (typeof listener !== "function") throw new SparkError("E_INVALID_ARGUMENT", "Expected an update listener");
72
+ native();
73
+ return onDesktopEvent(event => {
74
+ if (event.type !== "update" || typeof event.state !== "string") return;
75
+ const version = typeof event.version === "string", message = typeof event.message === "string";
76
+ const valid = ["checking", "notAvailable"].includes(event.state) || (["available", "downloading", "downloaded", "installing"].includes(event.state) && version) || (event.state === "error" && message);
77
+ if (valid) listener(event as unknown as UpdateEvent);
78
+ }, { types: ["update"] });
23
79
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@legendapp/spark-webview",
3
- "version": "0.0.1-next.2",
3
+ "version": "0.0.1-next.3",
4
4
  "license": "MIT",
5
5
  "main": "src/index.ts",
6
6
  "react-native": "src/index.ts",
@@ -9,7 +9,7 @@
9
9
  ],
10
10
  "dependencies": {
11
11
  "react-native-webview": "16.0.0",
12
- "@legendapp/spark-desktop-app": "0.0.1-next.2"
12
+ "@legendapp/spark-desktop-app": "0.0.1-next.3"
13
13
  },
14
14
  "private": true
15
15
  }
@@ -0,0 +1,11 @@
1
+ import { forwardRef, useImperativeHandle, useRef } from "react";
2
+ import { WebView as BackendWebView } from "react-native-webview";
3
+ import { backendProps, webViewRef } from "./adapter";
4
+ import type { WebViewProps, WebViewRef } from "./types";
5
+
6
+ /** Spark-owned props, events and ref; backend-specific APIs remain private. */
7
+ export const WebView = forwardRef<WebViewRef, WebViewProps>(function WebView(props, ref) {
8
+ const native = useRef<BackendWebView>(null);
9
+ useImperativeHandle(ref, () => webViewRef(() => native.current), []);
10
+ return <BackendWebView {...backendProps(props)} ref={native} />;
11
+ });
@@ -0,0 +1,55 @@
1
+ import { SparkError } from "@legendapp/spark-desktop-app/src/contracts";
2
+ import type { WebViewProps as BackendProps } from "react-native-webview";
3
+ import { viewPropKeys } from "./view-props";
4
+ import type { ViewPropKey } from "./view-props";
5
+ import type { WebViewProps, WebViewRef } from "./types";
6
+
7
+ const ownedProps = new Set(["source", "javaScriptEnabled", "injectedJavaScript", "allowedOrigins", "onMessage", "onLoad", "onError", "onNavigationChange", "onNavigationRequest"]);
8
+ /** React Native view props pass through; upstream WebView's specialized surface stays private. */
9
+ const forwardedProps = new Set<string>(viewPropKeys);
10
+ export function backendProps(props: WebViewProps): BackendProps {
11
+ for (const key of Object.keys(props)) {
12
+ if (!ownedProps.has(key) && !forwardedProps.has(key)) throw new SparkError("E_UNSUPPORTED_OPTION", `Unsupported WebView prop: ${key}`);
13
+ }
14
+ const { source } = props;
15
+ if (!source || (typeof source.uri === "string") === (typeof source.html === "string")) {
16
+ throw new SparkError("E_INVALID_ARGUMENT", "WebView source must specify either uri or html");
17
+ }
18
+ const view: Record<string, unknown> = {};
19
+ for (const key of viewPropKeys) {
20
+ const value = props[key as ViewPropKey];
21
+ if (value !== undefined) view[key] = value;
22
+ }
23
+ return {
24
+ ...view,
25
+ source: typeof source.html === "string" ? { html: source.html, baseUrl: source.baseUri } : { uri: source.uri!, headers: source.headers },
26
+ javaScriptEnabled: props.javaScriptEnabled ?? true,
27
+ injectedJavaScript: props.injectedJavaScript,
28
+ originWhitelist: props.allowedOrigins ? [...props.allowedOrigins] : typeof source.html === "string" ? ["*"] : ["http://*", "https://*"],
29
+ onMessage: props.onMessage ? ({ nativeEvent: event }) => props.onMessage!({ data: event.data, uri: event.url }) : undefined,
30
+ onLoad: props.onLoad ? ({ nativeEvent: event }) => props.onLoad!({ uri: event.url }) : undefined,
31
+ onError: props.onError ? ({ nativeEvent: event }) => props.onError!({ type: "load", uri: event.url, code: event.code, message: event.description }) : undefined,
32
+ onHttpError: props.onError ? ({ nativeEvent: event }) => props.onError!({ type: "http", uri: event.url, status: event.statusCode, message: event.description }) : undefined,
33
+ onNavigationStateChange: props.onNavigationChange ? event => props.onNavigationChange!({ uri: event.url, title: event.title, loading: event.loading, canGoBack: event.canGoBack, canGoForward: event.canGoForward }) : undefined,
34
+ onShouldStartLoadWithRequest: props.onNavigationRequest ? event => props.onNavigationRequest!({ uri: event.url, mainFrame: typeof event.isTopFrame === "boolean" ? event.isTopFrame : null }) : undefined,
35
+ };
36
+ }
37
+
38
+ export function webViewRef(current: () => WebViewRef | null): WebViewRef {
39
+ function view() {
40
+ const value = current();
41
+ if (!value) throw new SparkError("E_CLOSED", "WebView is not mounted");
42
+ return value;
43
+ }
44
+ return {
45
+ reload: () => view().reload(), goBack: () => view().goBack(), goForward: () => view().goForward(),
46
+ postMessage(message) {
47
+ if (typeof message !== "string") throw new SparkError("E_INVALID_ARGUMENT", "WebView messages must be strings");
48
+ view().postMessage(message);
49
+ },
50
+ injectJavaScript(script) {
51
+ if (typeof script !== "string") throw new SparkError("E_INVALID_ARGUMENT", "WebView scripts must be strings");
52
+ view().injectJavaScript(script);
53
+ },
54
+ };
55
+ }
@@ -1,2 +1,2 @@
1
- export { WebView } from "react-native-webview";
2
- export type { WebViewProps, WebViewMessageEvent, WebViewNavigation } from "react-native-webview";
1
+ export { WebView } from "./WebView";
2
+ export type { WebViewProps, WebViewRef, WebViewSource, WebViewMessageEvent, WebViewNavigation, WebViewNavigationRequest, WebViewErrorEvent } from "./types";
@@ -0,0 +1,32 @@
1
+ import type { ViewProps } from "react-native";
2
+ export type WebViewSource =
3
+ | { uri: string; headers?: Record<string, string>; html?: never; baseUri?: never }
4
+ | { html: string; baseUri?: string; uri?: never; headers?: never };
5
+ export type WebViewMessageEvent = { data: string; uri: string };
6
+ export type WebViewNavigation = { uri: string; title: string; loading: boolean; canGoBack: boolean; canGoForward: boolean };
7
+ export type WebViewNavigationRequest = { uri: string; mainFrame: boolean | null };
8
+ export type WebViewErrorEvent =
9
+ | { type: "load"; uri: string; code: number; message: string }
10
+ | { type: "http"; uri: string; status: number; message: string };
11
+ /** React Native's view props are accepted; WebView-specific behavior is owned here. Children are not: the rendered content is the source document. */
12
+ export interface WebViewProps extends Omit<ViewProps, "children"> {
13
+ source: WebViewSource;
14
+ javaScriptEnabled?: boolean;
15
+ /** Script executed after page load. Applies to trusted document content. */
16
+ injectedJavaScript?: string;
17
+ /** Origin patterns accepted by the current adapter; default is HTTP/HTTPS. Inline HTML permits all origins. */
18
+ allowedOrigins?: readonly string[];
19
+ onMessage?: (event: WebViewMessageEvent) => void;
20
+ onLoad?: (event: { uri: string }) => void;
21
+ onError?: (event: WebViewErrorEvent) => void;
22
+ onNavigationChange?: (event: WebViewNavigation) => void;
23
+ /** Synchronous native navigation decision where emitted; not a network security boundary. */
24
+ onNavigationRequest?: (event: WebViewNavigationRequest) => boolean;
25
+ }
26
+ export interface WebViewRef {
27
+ reload(): void;
28
+ goBack(): void;
29
+ goForward(): void;
30
+ postMessage(message: string): void;
31
+ injectJavaScript(script: string): void;
32
+ }
@@ -0,0 +1,28 @@
1
+ import type { ViewProps } from "react-native";
2
+
3
+ /**
4
+ * React Native's own view props, forwarded to the backend view. `children` is omitted:
5
+ * a WebView renders a document, not React children. The `satisfies` clause makes the
6
+ * list fail to compile if it names something React Native does not accept.
7
+ */
8
+ export const viewPropKeys = [
9
+ "accessibilityActions", "accessibilityElementsHidden", "accessibilityHint", "accessibilityIgnoresInvertColors",
10
+ "accessibilityLabel", "accessibilityLabelledBy", "accessibilityLanguage", "accessibilityLargeContentTitle",
11
+ "accessibilityLiveRegion", "accessibilityRespondsToUserInteraction", "accessibilityRole",
12
+ "accessibilityShowsLargeContentViewer", "accessibilityState", "accessibilityValue", "accessibilityViewIsModal",
13
+ "accessible", "aria-busy", "aria-checked", "aria-disabled", "aria-expanded", "aria-hidden", "aria-label",
14
+ "aria-labelledby", "aria-live", "aria-modal", "aria-selected", "aria-valuemax", "aria-valuemin", "aria-valuenow",
15
+ "aria-valuetext", "collapsable", "collapsableChildren", "focusable", "hasTVPreferredFocus", "hitSlop", "id",
16
+ "importantForAccessibility", "isTVSelectable", "nativeID", "needsOffscreenAlphaCompositing",
17
+ "onAccessibilityAction", "onAccessibilityEscape", "onAccessibilityTap", "onBlur", "onFocus", "onLayout",
18
+ "onMagicTap", "onMoveShouldSetResponder", "onMoveShouldSetResponderCapture", "onPointerCancel",
19
+ "onPointerCancelCapture", "onPointerDown", "onPointerDownCapture", "onPointerEnter", "onPointerEnterCapture",
20
+ "onPointerLeave", "onPointerLeaveCapture", "onPointerMove", "onPointerMoveCapture", "onPointerUp",
21
+ "onPointerUpCapture", "onResponderEnd", "onResponderGrant", "onResponderMove", "onResponderReject",
22
+ "onResponderRelease", "onResponderStart", "onResponderTerminate", "onResponderTerminationRequest",
23
+ "onStartShouldSetResponder", "onStartShouldSetResponderCapture", "onTouchCancel", "onTouchEnd",
24
+ "onTouchEndCapture", "onTouchMove", "onTouchStart", "pointerEvents", "removeClippedSubviews",
25
+ "renderToHardwareTextureAndroid", "role", "screenReaderFocusable", "shouldRasterizeIOS", "style", "tabIndex",
26
+ "testID", "tvParallaxMagnification", "tvParallaxShiftDistanceX", "tvParallaxShiftDistanceY", "tvParallaxTiltAngle",
27
+ ] as const satisfies readonly (keyof Omit<ViewProps, "children">)[];
28
+ export type ViewPropKey = (typeof viewPropKeys)[number];
@@ -1,25 +1,62 @@
1
1
  const enums = {
2
2
  titleBarStyle: ["default", "overlay", "hidden", "borderless"],
3
3
  appearance: ["system", "light", "dark"],
4
- material: ["none", "sidebar", "windowBackground", "hudWindow", "popover"],
5
4
  };
6
- const dimensions = ["width", "height", "minWidth", "minHeight", "maxWidth", "maxHeight"];
7
- const booleans = ["resizable", "closable", "minimizable", "alwaysOnTop", "transparent", "hasShadow", "trafficLights", "restoreFrame"];
5
+ const booleans = ["resizable", "closable", "minimizable", "alwaysOnTop", "transparent", "hasShadow", "restoreBounds"];
6
+ const dimension = { type: "number", minimum: 100, maximum: 20000 };
7
+ const size = { type: "object", required: ["width", "height"], additionalProperties: false, properties: { width: dimension, height: dimension } };
8
+ const materials = ["none", "sidebar", "windowBackground", "hudWindow", "popover"];
9
+ const schema = {
10
+ type: "object", additionalProperties: false,
11
+ properties: {
12
+ size, minSize: { anyOf: [size, { type: "null" }] }, maxSize: { anyOf: [size, { type: "null" }] },
13
+ ...Object.fromEntries(booleans.map(key => [key, { type: "boolean" }])),
14
+ ...Object.fromEntries(Object.entries(enums).map(([key, values]) => [key, { enum: values }])),
15
+ title: { type: "string" }, backgroundColor: { type: "string", pattern: "^#[0-9a-fA-F]{6}([0-9a-fA-F]{2})?$" },
16
+ macos: { type: "object", additionalProperties: false, properties: {
17
+ backgroundMaterial: { enum: materials },
18
+ titleBar: { type: "object", additionalProperties: false, properties: { trafficLights: { type: "boolean" } } },
19
+ } },
20
+ },
21
+ };
22
+ function object(value, allowed, name) {
23
+ if (!value || typeof value !== "object" || Array.isArray(value)) throw new Error(`${name} must be an object`);
24
+ for (const key of Object.keys(value)) if (!allowed.includes(key)) throw new Error(`Unknown ${name} option: ${key}`);
25
+ }
8
26
  function validateWindow(options) {
9
- if (!options || typeof options !== "object" || Array.isArray(options)) throw new Error("window must be an object");
10
- const allowed = [...dimensions, ...booleans, ...Object.keys(enums), "title", "backgroundColor"];
11
- for (const key of Object.keys(options)) if (!allowed.includes(key)) throw new Error(`Unknown window option: ${key}`);
12
- for (const key of dimensions) if (options[key] !== undefined && (!Number.isFinite(options[key]) || options[key] < 100 || options[key] > 20000)) throw new Error(`${key} must be between 100 and 20000 points`);
13
- for (const axis of ["Width", "Height"]) {
14
- const min = options[`min${axis}`] ?? 100, max = options[`max${axis}`] ?? 20000;
15
- if (min > max) throw new Error(`min${axis} exceeds max${axis}`);
16
- const size = options[axis.toLowerCase()];
17
- if (size !== undefined && (size < min || size > max)) throw new Error(`${axis.toLowerCase()} is outside its constraints`);
27
+ object(options, Object.keys(schema.properties), "window");
28
+ for (const key of ["size", "minSize", "maxSize"]) if (options[key] !== undefined && !(key !== "size" && options[key] === null)) {
29
+ object(options[key], ["width", "height"], key);
30
+ for (const axis of ["width", "height"]) if (!Number.isFinite(options[key][axis]) || options[key][axis] < 100 || options[key][axis] > 20000) throw new Error(`${key}.${axis} must be between 100 and 20000 logical units`);
31
+ }
32
+ for (const axis of ["width", "height"]) {
33
+ const min = options.minSize?.[axis] ?? 100, max = options.maxSize?.[axis] ?? 20000;
34
+ if (min > max) throw new Error(`minSize.${axis} exceeds maxSize.${axis}`);
35
+ if (options.size && (options.size[axis] < min || options.size[axis] > max)) throw new Error(`size.${axis} is outside its constraints`);
18
36
  }
19
37
  for (const key of booleans) if (options[key] !== undefined && typeof options[key] !== "boolean") throw new Error(`${key} must be a boolean`);
20
38
  for (const [key, values] of Object.entries(enums)) if (options[key] !== undefined && !values.includes(options[key])) throw new Error(`Invalid ${key}`);
21
39
  if (options.title !== undefined && typeof options.title !== "string") throw new Error("title must be a string");
22
- if (options.backgroundColor !== undefined && !/^#[0-9a-fA-F]{6}([0-9a-fA-F]{2})?$/.test(options.backgroundColor)) throw new Error("backgroundColor must be #RRGGBB or #RRGGBBAA");
40
+ if (options.backgroundColor !== undefined && (typeof options.backgroundColor !== "string" || !new RegExp(schema.properties.backgroundColor.pattern).test(options.backgroundColor))) throw new Error("backgroundColor must be #RRGGBB or #RRGGBBAA");
41
+ if (options.macos !== undefined) {
42
+ object(options.macos, ["backgroundMaterial", "titleBar"], "macos");
43
+ if (options.macos.backgroundMaterial !== undefined && !materials.includes(options.macos.backgroundMaterial)) throw new Error("Invalid macos.backgroundMaterial");
44
+ if (options.macos.titleBar !== undefined) {
45
+ object(options.macos.titleBar, ["trafficLights"], "macos.titleBar");
46
+ if (options.macos.titleBar.trafficLights !== undefined && typeof options.macos.titleBar.trafficLights !== "boolean") throw new Error("trafficLights must be a boolean");
47
+ }
48
+ }
23
49
  return options;
24
50
  }
25
- module.exports = { validateWindow, dimensions, booleans, enums };
51
+ // Private host transport. Consumers only author the grouped configuration above.
52
+ function nativeWindowOptions(value) {
53
+ const { size, minSize, maxSize, restoreBounds, macos, ...result } = validateWindow(value);
54
+ for (const [prefix, dimensions] of [["", size], ["min", minSize], ["max", maxSize]]) if (dimensions) {
55
+ for (const axis of ["width", "height"]) result[prefix ? prefix + axis[0].toUpperCase() + axis.slice(1) : axis] = dimensions[axis];
56
+ }
57
+ if (restoreBounds !== undefined) result.restoreFrame = restoreBounds;
58
+ if (macos?.backgroundMaterial !== undefined) result.material = macos.backgroundMaterial;
59
+ if (macos?.titleBar?.trafficLights !== undefined) result.trafficLights = macos.titleBar.trafficLights;
60
+ return result;
61
+ }
62
+ module.exports = { validateWindow, nativeWindowOptions, schema };
@@ -1,12 +1,25 @@
1
- export type WindowStyle = {
1
+ export interface WindowSize { width: number; height: number }
2
+ /** Initial outer frame dimensions in logical units, matching the runtime window API. */
3
+ export interface WindowConfiguration {
2
4
  title?: string;
3
- width?: number; height?: number;
4
- minWidth?: number; minHeight?: number; maxWidth?: number; maxHeight?: number;
5
- resizable?: boolean; closable?: boolean; minimizable?: boolean;
6
- alwaysOnTop?: boolean; transparent?: boolean; hasShadow?: boolean; trafficLights?: boolean; restoreFrame?: boolean;
5
+ size?: WindowSize;
6
+ minSize?: WindowSize | null;
7
+ maxSize?: WindowSize | null;
8
+ resizable?: boolean;
9
+ closable?: boolean;
10
+ minimizable?: boolean;
11
+ alwaysOnTop?: boolean;
12
+ transparent?: boolean;
13
+ hasShadow?: boolean;
14
+ restoreBounds?: boolean;
7
15
  titleBarStyle?: "default" | "overlay" | "hidden" | "borderless";
8
16
  appearance?: "system" | "light" | "dark";
9
- material?: "none" | "sidebar" | "windowBackground" | "hudWindow" | "popover";
10
17
  backgroundColor?: string;
11
- };
12
- export function validateWindow(options: unknown): WindowStyle;
18
+ macos?: {
19
+ backgroundMaterial?: "none" | "sidebar" | "windowBackground" | "hudWindow" | "popover";
20
+ titleBar?: { trafficLights?: boolean };
21
+ };
22
+ }
23
+ export function validateWindow(options: unknown): WindowConfiguration;
24
+ export function nativeWindowOptions(options: unknown): Record<string, string | number | boolean>;
25
+ export const schema: Record<string, unknown>;
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@legendapp/spark-window-options",
3
- "version": "0.0.1-next.2",
3
+ "version": "0.0.1-next.3",
4
4
  "license": "MIT",
5
5
  "main": "index.cjs",
6
6
  "types": "index.d.ts",