@dxos/plugin-script 0.8.1-staging.391c573 → 0.8.1-staging.97aedb1

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 (264) hide show
  1. package/dist/lib/browser/DeploymentDialog-AEPYJKPO.mjs +12 -0
  2. package/dist/lib/browser/DeploymentDialog-AEPYJKPO.mjs.map +7 -0
  3. package/dist/lib/browser/{ScriptContainer-4FIJVITA.mjs → ScriptContainer-R25PRK2D.mjs} +26 -39
  4. package/dist/lib/browser/ScriptContainer-R25PRK2D.mjs.map +7 -0
  5. package/dist/lib/browser/app-graph-builder-RRLY67QC.mjs +64 -0
  6. package/dist/lib/browser/app-graph-builder-RRLY67QC.mjs.map +7 -0
  7. package/dist/lib/browser/{artifact-definition-GTL3ZSF2.mjs → artifact-definition-WXFYD2V5.mjs} +10 -9
  8. package/dist/lib/browser/artifact-definition-WXFYD2V5.mjs.map +7 -0
  9. package/dist/lib/browser/{chunk-SFG422OU.mjs → chunk-2CGZFDCR.mjs} +290 -277
  10. package/dist/lib/browser/chunk-2CGZFDCR.mjs.map +7 -0
  11. package/dist/lib/browser/chunk-4VD3K3PY.mjs +15 -0
  12. package/dist/lib/browser/{chunk-6MOQ4BP3.mjs.map → chunk-4VD3K3PY.mjs.map} +3 -3
  13. package/dist/lib/browser/chunk-CSZXPLYY.mjs +147 -0
  14. package/dist/lib/browser/chunk-CSZXPLYY.mjs.map +7 -0
  15. package/dist/lib/browser/chunk-KLEOGVXY.mjs +352 -0
  16. package/dist/lib/browser/chunk-KLEOGVXY.mjs.map +7 -0
  17. package/dist/lib/browser/chunk-MQZQB5VD.mjs +233 -0
  18. package/dist/lib/browser/chunk-MQZQB5VD.mjs.map +7 -0
  19. package/dist/lib/browser/{chunk-JL34HAEL.mjs → chunk-R2CHVWJ2.mjs} +5 -4
  20. package/dist/lib/browser/chunk-R2CHVWJ2.mjs.map +7 -0
  21. package/dist/lib/browser/chunk-SUCBNCEQ.mjs +87 -0
  22. package/dist/lib/browser/chunk-SUCBNCEQ.mjs.map +7 -0
  23. package/dist/lib/browser/{chunk-FVVCAWNP.mjs → chunk-WSK3YQXI.mjs} +9 -3
  24. package/dist/lib/browser/chunk-WSK3YQXI.mjs.map +7 -0
  25. package/dist/lib/browser/{compiler-YY2XSKHQ.mjs → compiler-56LTBEQB.mjs} +7 -7
  26. package/dist/lib/browser/index.mjs +65 -61
  27. package/dist/lib/browser/index.mjs.map +3 -3
  28. package/dist/lib/browser/intent-resolver-WCVXKRBR.mjs +90 -0
  29. package/dist/lib/browser/intent-resolver-WCVXKRBR.mjs.map +7 -0
  30. package/dist/lib/browser/meta.json +1 -1
  31. package/dist/lib/browser/react-surface-WXZVPNGI.mjs +117 -0
  32. package/dist/lib/browser/react-surface-WXZVPNGI.mjs.map +7 -0
  33. package/dist/lib/browser/{settings-HIWURVAS.mjs → settings-Z7B37V2I.mjs} +6 -6
  34. package/dist/lib/browser/{settings-HIWURVAS.mjs.map → settings-Z7B37V2I.mjs.map} +3 -3
  35. package/dist/lib/browser/types.mjs +5 -2
  36. package/dist/lib/node/DeploymentDialog-O4MU4OMF.cjs +33 -0
  37. package/dist/lib/node/DeploymentDialog-O4MU4OMF.cjs.map +7 -0
  38. package/dist/lib/node/{ScriptContainer-54GQSZCU.cjs → ScriptContainer-5KY6ZOQD.cjs} +29 -40
  39. package/dist/lib/node/ScriptContainer-5KY6ZOQD.cjs.map +7 -0
  40. package/dist/lib/node/app-graph-builder-6I2BWD46.cjs +80 -0
  41. package/dist/lib/node/app-graph-builder-6I2BWD46.cjs.map +7 -0
  42. package/dist/lib/node/{artifact-definition-64KZC4UT.cjs → artifact-definition-6NVXEHJD.cjs} +16 -15
  43. package/dist/lib/node/artifact-definition-6NVXEHJD.cjs.map +7 -0
  44. package/dist/lib/node/chunk-65MIJR3Q.cjs +173 -0
  45. package/dist/lib/node/chunk-65MIJR3Q.cjs.map +7 -0
  46. package/dist/lib/node/chunk-F4DP7WON.cjs +372 -0
  47. package/dist/lib/node/chunk-F4DP7WON.cjs.map +7 -0
  48. package/dist/lib/node/{chunk-ALY3N6PW.cjs → chunk-JICWAOWZ.cjs} +6 -6
  49. package/dist/lib/node/{chunk-ALY3N6PW.cjs.map → chunk-JICWAOWZ.cjs.map} +3 -3
  50. package/dist/lib/node/{chunk-45OE3V5M.cjs → chunk-SLDJM45C.cjs} +286 -272
  51. package/dist/lib/node/chunk-SLDJM45C.cjs.map +7 -0
  52. package/dist/lib/node/chunk-VYBEBLDO.cjs +251 -0
  53. package/dist/lib/node/chunk-VYBEBLDO.cjs.map +7 -0
  54. package/dist/lib/node/chunk-X7MHLHHS.cjs +91 -0
  55. package/dist/lib/node/chunk-X7MHLHHS.cjs.map +7 -0
  56. package/dist/lib/node/{chunk-VJ73IG7P.cjs → chunk-XFZPWFEG.cjs} +8 -7
  57. package/dist/lib/node/chunk-XFZPWFEG.cjs.map +7 -0
  58. package/dist/lib/node/{chunk-5UH3F7TA.cjs → chunk-YJQZHKKA.cjs} +11 -4
  59. package/dist/lib/node/chunk-YJQZHKKA.cjs.map +7 -0
  60. package/dist/lib/node/{compiler-UIBLKJKG.cjs → compiler-W2RU3M7U.cjs} +8 -8
  61. package/dist/lib/node/index.cjs +75 -71
  62. package/dist/lib/node/index.cjs.map +3 -3
  63. package/dist/lib/node/intent-resolver-J4NBDNFH.cjs +100 -0
  64. package/dist/lib/node/intent-resolver-J4NBDNFH.cjs.map +7 -0
  65. package/dist/lib/node/meta.json +1 -1
  66. package/dist/lib/node/react-surface-27KTUBIZ.cjs +129 -0
  67. package/dist/lib/node/react-surface-27KTUBIZ.cjs.map +7 -0
  68. package/dist/lib/node/{settings-ZASSNBKR.cjs → settings-EI6VPNKN.cjs} +9 -9
  69. package/dist/lib/node/{settings-ZASSNBKR.cjs.map → settings-EI6VPNKN.cjs.map} +3 -3
  70. package/dist/lib/node/types.cjs +6 -4
  71. package/dist/lib/node/types.cjs.map +2 -2
  72. package/dist/lib/node-esm/DeploymentDialog-SSQSWLHX.mjs +13 -0
  73. package/dist/lib/node-esm/DeploymentDialog-SSQSWLHX.mjs.map +7 -0
  74. package/dist/lib/node-esm/{ScriptContainer-JAQY5F3X.mjs → ScriptContainer-W2F4FGDV.mjs} +26 -39
  75. package/dist/lib/node-esm/ScriptContainer-W2F4FGDV.mjs.map +7 -0
  76. package/dist/lib/node-esm/app-graph-builder-H5XLRVX3.mjs +65 -0
  77. package/dist/lib/node-esm/app-graph-builder-H5XLRVX3.mjs.map +7 -0
  78. package/dist/lib/node-esm/{artifact-definition-SF46QOO7.mjs → artifact-definition-KQ64AYBP.mjs} +10 -9
  79. package/dist/lib/node-esm/artifact-definition-KQ64AYBP.mjs.map +7 -0
  80. package/dist/lib/node-esm/{chunk-LBFWIT3Y.mjs → chunk-4MTPYMV2.mjs} +290 -277
  81. package/dist/lib/node-esm/chunk-4MTPYMV2.mjs.map +7 -0
  82. package/dist/lib/node-esm/{chunk-CP5LXTK5.mjs → chunk-EB5DSAD4.mjs} +5 -5
  83. package/dist/lib/node-esm/{chunk-CP5LXTK5.mjs.map → chunk-EB5DSAD4.mjs.map} +3 -3
  84. package/dist/lib/node-esm/chunk-F4HA5C34.mjs +234 -0
  85. package/dist/lib/node-esm/chunk-F4HA5C34.mjs.map +7 -0
  86. package/dist/lib/node-esm/{chunk-P2V2Y5LV.mjs → chunk-FDEAVT67.mjs} +9 -3
  87. package/dist/lib/node-esm/chunk-FDEAVT67.mjs.map +7 -0
  88. package/dist/lib/node-esm/chunk-MU3JKVL2.mjs +148 -0
  89. package/dist/lib/node-esm/chunk-MU3JKVL2.mjs.map +7 -0
  90. package/dist/lib/node-esm/chunk-PBGVTGL2.mjs +353 -0
  91. package/dist/lib/node-esm/chunk-PBGVTGL2.mjs.map +7 -0
  92. package/dist/lib/node-esm/chunk-QDYGTY4L.mjs +89 -0
  93. package/dist/lib/node-esm/chunk-QDYGTY4L.mjs.map +7 -0
  94. package/dist/lib/node-esm/{chunk-FHQKFLM7.mjs → chunk-RW2APVMV.mjs} +5 -4
  95. package/dist/lib/node-esm/chunk-RW2APVMV.mjs.map +7 -0
  96. package/dist/lib/node-esm/{compiler-XTXFGZJM.mjs → compiler-VT5C2Z3T.mjs} +7 -7
  97. package/dist/lib/node-esm/index.mjs +65 -61
  98. package/dist/lib/node-esm/index.mjs.map +3 -3
  99. package/dist/lib/node-esm/intent-resolver-PDZ2A26X.mjs +91 -0
  100. package/dist/lib/node-esm/intent-resolver-PDZ2A26X.mjs.map +7 -0
  101. package/dist/lib/node-esm/meta.json +1 -1
  102. package/dist/lib/node-esm/react-surface-UCUVDVSH.mjs +118 -0
  103. package/dist/lib/node-esm/react-surface-UCUVDVSH.mjs.map +7 -0
  104. package/dist/lib/node-esm/{settings-FDGLXN4I.mjs → settings-HU5UEFRF.mjs} +6 -6
  105. package/dist/lib/node-esm/{settings-FDGLXN4I.mjs.map → settings-HU5UEFRF.mjs.map} +3 -3
  106. package/dist/lib/node-esm/types.mjs +5 -2
  107. package/dist/types/src/ScriptPlugin.d.ts.map +1 -1
  108. package/dist/types/src/capabilities/app-graph-builder.d.ts +181 -0
  109. package/dist/types/src/capabilities/app-graph-builder.d.ts.map +1 -0
  110. package/dist/types/src/capabilities/artifact-definition.d.ts.map +1 -1
  111. package/dist/types/src/capabilities/capabilities.d.ts.map +1 -1
  112. package/dist/types/src/capabilities/index.d.ts +178 -1
  113. package/dist/types/src/capabilities/index.d.ts.map +1 -1
  114. package/dist/types/src/capabilities/intent-resolver.d.ts.map +1 -1
  115. package/dist/types/src/capabilities/react-surface.d.ts.map +1 -1
  116. package/dist/types/src/components/DeploymentDialog/DeploymentDialog.d.ts +11 -0
  117. package/dist/types/src/components/DeploymentDialog/DeploymentDialog.d.ts.map +1 -0
  118. package/dist/types/src/components/DeploymentDialog/DeploymentDialog.stories.d.ts +18 -0
  119. package/dist/types/src/components/DeploymentDialog/DeploymentDialog.stories.d.ts.map +1 -0
  120. package/dist/types/src/components/DeploymentDialog/index.d.ts +4 -0
  121. package/dist/types/src/components/DeploymentDialog/index.d.ts.map +1 -0
  122. package/dist/types/src/components/ScriptContainer.d.ts +3 -3
  123. package/dist/types/src/components/ScriptContainer.d.ts.map +1 -1
  124. package/dist/types/src/components/ScriptToolbar/ScriptToolbar.d.ts.map +1 -1
  125. package/dist/types/src/components/Settings/ScriptObjectSettings.d.ts +8 -0
  126. package/dist/types/src/components/Settings/ScriptObjectSettings.d.ts.map +1 -0
  127. package/dist/types/src/components/{ScriptSettings/ScriptSettings.d.ts → Settings/ScriptPluginSettings.d.ts} +2 -2
  128. package/dist/types/src/components/Settings/ScriptPluginSettings.d.ts.map +1 -0
  129. package/dist/types/src/components/Settings/index.d.ts +3 -0
  130. package/dist/types/src/components/Settings/index.d.ts.map +1 -0
  131. package/dist/types/src/components/TestPanel/TestPanel.d.ts +7 -0
  132. package/dist/types/src/components/TestPanel/TestPanel.d.ts.map +1 -0
  133. package/dist/types/src/components/TestPanel/index.d.ts +2 -0
  134. package/dist/types/src/components/TestPanel/index.d.ts.map +1 -0
  135. package/dist/types/src/components/index.d.ts +8 -5
  136. package/dist/types/src/components/index.d.ts.map +1 -1
  137. package/dist/types/src/hooks/deploy.d.ts +16 -12
  138. package/dist/types/src/hooks/deploy.d.ts.map +1 -1
  139. package/dist/types/src/hooks/index.d.ts +1 -1
  140. package/dist/types/src/hooks/index.d.ts.map +1 -1
  141. package/dist/types/src/hooks/useCreateAndDeployScriptTemplates.d.ts +17 -0
  142. package/dist/types/src/hooks/useCreateAndDeployScriptTemplates.d.ts.map +1 -0
  143. package/dist/types/src/hooks/useToolbarAction.d.ts +2 -3
  144. package/dist/types/src/hooks/useToolbarAction.d.ts.map +1 -1
  145. package/dist/types/src/hooks/useToolbarState.d.ts +2 -8
  146. package/dist/types/src/hooks/useToolbarState.d.ts.map +1 -1
  147. package/dist/types/src/meta.d.ts +3 -9
  148. package/dist/types/src/meta.d.ts.map +1 -1
  149. package/dist/types/src/templates/chess.d.ts.map +1 -1
  150. package/dist/types/src/templates/data-generator.d.ts +10 -0
  151. package/dist/types/src/templates/data-generator.d.ts.map +1 -0
  152. package/dist/types/src/templates/forex-effect.d.ts.map +1 -1
  153. package/dist/types/src/templates/gmail.d.ts +3 -0
  154. package/dist/types/src/templates/gmail.d.ts.map +1 -0
  155. package/dist/types/src/templates/index.d.ts.map +1 -1
  156. package/dist/types/src/translations.d.ts +68 -21
  157. package/dist/types/src/translations.d.ts.map +1 -1
  158. package/dist/types/src/types.d.ts +12 -2
  159. package/dist/types/src/types.d.ts.map +1 -1
  160. package/dist/types/src/util/deploy.d.ts +25 -0
  161. package/dist/types/src/util/deploy.d.ts.map +1 -0
  162. package/dist/types/src/util/functions.d.ts +11 -0
  163. package/dist/types/src/util/functions.d.ts.map +1 -0
  164. package/dist/types/src/util/index.d.ts +3 -0
  165. package/dist/types/src/util/index.d.ts.map +1 -0
  166. package/package.json +51 -49
  167. package/src/ScriptPlugin.tsx +12 -17
  168. package/src/capabilities/app-graph-builder.ts +47 -0
  169. package/src/capabilities/artifact-definition.ts +2 -1
  170. package/src/capabilities/capabilities.ts +2 -2
  171. package/src/capabilities/index.ts +2 -1
  172. package/src/capabilities/intent-resolver.ts +39 -5
  173. package/src/capabilities/react-surface.tsx +64 -25
  174. package/src/capabilities/settings.ts +2 -2
  175. package/src/components/DeploymentDialog/DeploymentDialog.stories.tsx +39 -0
  176. package/src/components/DeploymentDialog/DeploymentDialog.tsx +112 -0
  177. package/src/components/DeploymentDialog/index.ts +9 -0
  178. package/src/components/ScriptContainer.tsx +21 -32
  179. package/src/components/ScriptToolbar/ScriptToolbar.tsx +3 -4
  180. package/src/components/{ScriptSettingsPanel.tsx → Settings/ScriptObjectSettings.tsx} +120 -102
  181. package/src/components/{ScriptSettings/ScriptSettings.tsx → Settings/ScriptPluginSettings.tsx} +3 -3
  182. package/src/components/Settings/index.ts +6 -0
  183. package/src/components/{DebugPanel/DebugPanel.tsx → TestPanel/TestPanel.tsx} +8 -14
  184. package/src/components/{LogsPanel → TestPanel}/index.ts +1 -1
  185. package/src/components/index.ts +4 -4
  186. package/src/hooks/deploy.ts +31 -80
  187. package/src/hooks/index.ts +1 -1
  188. package/src/hooks/useCreateAndDeployScriptTemplates.ts +59 -0
  189. package/src/hooks/useToolbarAction.ts +9 -13
  190. package/src/hooks/useToolbarState.ts +1 -2
  191. package/src/meta.ts +7 -2
  192. package/src/templates/chess.ts +4 -0
  193. package/src/templates/data-generator.ts +73 -0
  194. package/src/templates/discord.ts +1 -1
  195. package/src/templates/forex-effect.ts +2 -1
  196. package/src/templates/gmail.ts +244 -0
  197. package/src/templates/index.ts +14 -0
  198. package/src/translations.ts +28 -10
  199. package/src/types.ts +4 -0
  200. package/src/util/deploy.ts +126 -0
  201. package/src/util/functions.ts +53 -0
  202. package/src/util/index.ts +6 -0
  203. package/dist/lib/browser/ScriptContainer-4FIJVITA.mjs.map +0 -7
  204. package/dist/lib/browser/artifact-definition-GTL3ZSF2.mjs.map +0 -7
  205. package/dist/lib/browser/chunk-4SSKJNMZ.mjs +0 -69
  206. package/dist/lib/browser/chunk-4SSKJNMZ.mjs.map +0 -7
  207. package/dist/lib/browser/chunk-6MOQ4BP3.mjs +0 -15
  208. package/dist/lib/browser/chunk-7TZYIGBS.mjs +0 -541
  209. package/dist/lib/browser/chunk-7TZYIGBS.mjs.map +0 -7
  210. package/dist/lib/browser/chunk-FVVCAWNP.mjs.map +0 -7
  211. package/dist/lib/browser/chunk-JL34HAEL.mjs.map +0 -7
  212. package/dist/lib/browser/chunk-SFG422OU.mjs.map +0 -7
  213. package/dist/lib/browser/intent-resolver-BJ76DBGE.mjs +0 -45
  214. package/dist/lib/browser/intent-resolver-BJ76DBGE.mjs.map +0 -7
  215. package/dist/lib/browser/react-surface-HXCDELEA.mjs +0 -79
  216. package/dist/lib/browser/react-surface-HXCDELEA.mjs.map +0 -7
  217. package/dist/lib/node/ScriptContainer-54GQSZCU.cjs.map +0 -7
  218. package/dist/lib/node/artifact-definition-64KZC4UT.cjs.map +0 -7
  219. package/dist/lib/node/chunk-45OE3V5M.cjs.map +0 -7
  220. package/dist/lib/node/chunk-5UH3F7TA.cjs.map +0 -7
  221. package/dist/lib/node/chunk-CJ45RBS4.cjs +0 -563
  222. package/dist/lib/node/chunk-CJ45RBS4.cjs.map +0 -7
  223. package/dist/lib/node/chunk-VJ73IG7P.cjs.map +0 -7
  224. package/dist/lib/node/chunk-XCQNFRZ6.cjs +0 -77
  225. package/dist/lib/node/chunk-XCQNFRZ6.cjs.map +0 -7
  226. package/dist/lib/node/intent-resolver-HQ3FGK2K.cjs +0 -59
  227. package/dist/lib/node/intent-resolver-HQ3FGK2K.cjs.map +0 -7
  228. package/dist/lib/node/react-surface-QQL4EDUS.cjs +0 -95
  229. package/dist/lib/node/react-surface-QQL4EDUS.cjs.map +0 -7
  230. package/dist/lib/node-esm/ScriptContainer-JAQY5F3X.mjs.map +0 -7
  231. package/dist/lib/node-esm/artifact-definition-SF46QOO7.mjs.map +0 -7
  232. package/dist/lib/node-esm/chunk-4YUSGXJ2.mjs +0 -71
  233. package/dist/lib/node-esm/chunk-4YUSGXJ2.mjs.map +0 -7
  234. package/dist/lib/node-esm/chunk-FHQKFLM7.mjs.map +0 -7
  235. package/dist/lib/node-esm/chunk-LBFWIT3Y.mjs.map +0 -7
  236. package/dist/lib/node-esm/chunk-P2V2Y5LV.mjs.map +0 -7
  237. package/dist/lib/node-esm/chunk-RI35DJSW.mjs +0 -542
  238. package/dist/lib/node-esm/chunk-RI35DJSW.mjs.map +0 -7
  239. package/dist/lib/node-esm/intent-resolver-CDTQKQD4.mjs +0 -46
  240. package/dist/lib/node-esm/intent-resolver-CDTQKQD4.mjs.map +0 -7
  241. package/dist/lib/node-esm/react-surface-PCW5HN3B.mjs +0 -80
  242. package/dist/lib/node-esm/react-surface-PCW5HN3B.mjs.map +0 -7
  243. package/dist/types/src/components/DebugPanel/DebugPanel.d.ts +0 -7
  244. package/dist/types/src/components/DebugPanel/DebugPanel.d.ts.map +0 -1
  245. package/dist/types/src/components/DebugPanel/index.d.ts +0 -2
  246. package/dist/types/src/components/DebugPanel/index.d.ts.map +0 -1
  247. package/dist/types/src/components/LogsPanel/LogsPanel.d.ts +0 -8
  248. package/dist/types/src/components/LogsPanel/LogsPanel.d.ts.map +0 -1
  249. package/dist/types/src/components/LogsPanel/index.d.ts +0 -2
  250. package/dist/types/src/components/LogsPanel/index.d.ts.map +0 -1
  251. package/dist/types/src/components/ScriptSettings/ScriptSettings.d.ts.map +0 -1
  252. package/dist/types/src/components/ScriptSettings/index.d.ts +0 -2
  253. package/dist/types/src/components/ScriptSettings/index.d.ts.map +0 -1
  254. package/dist/types/src/components/ScriptSettingsPanel.d.ts +0 -7
  255. package/dist/types/src/components/ScriptSettingsPanel.d.ts.map +0 -1
  256. package/dist/types/src/hooks/view.d.ts +0 -33
  257. package/dist/types/src/hooks/view.d.ts.map +0 -1
  258. package/src/components/DebugPanel/index.ts +0 -5
  259. package/src/components/LogsPanel/LogsPanel.tsx +0 -111
  260. package/src/components/ScriptSettings/index.ts +0 -5
  261. package/src/hooks/view.ts +0 -52
  262. /package/dist/lib/browser/{compiler-YY2XSKHQ.mjs.map → compiler-56LTBEQB.mjs.map} +0 -0
  263. /package/dist/lib/node/{compiler-UIBLKJKG.cjs.map → compiler-W2RU3M7U.cjs.map} +0 -0
  264. /package/dist/lib/node-esm/{compiler-XTXFGZJM.mjs.map → compiler-VT5C2Z3T.mjs.map} +0 -0
@@ -10,27 +10,110 @@ import { FunctionType, type ScriptType, getInvocationUrl, getUserFunctionUrlInMe
10
10
  import { log } from '@dxos/log';
11
11
  import { useClient } from '@dxos/react-client';
12
12
  import { Filter, getMeta, getSpace, useQuery } from '@dxos/react-client/echo';
13
- import { Button, Clipboard, Input, Separator, useControlledState, useTranslation } from '@dxos/react-ui';
13
+ import { Button, Clipboard, Input, useControlledState, useTranslation } from '@dxos/react-ui';
14
14
  import { AccessTokenType } from '@dxos/schema';
15
15
 
16
- import { SCRIPT_PLUGIN } from '../meta';
16
+ import { SCRIPT_PLUGIN } from '../../meta';
17
17
 
18
- // TODO(wittjosiah): Factor out.
19
- // From https://stackoverflow.com/a/67243723/2804332
20
- const kebabize = (str: string) => str.replace(/[A-Z]+(?![a-z])|[A-Z]/g, ($, ofs) => (ofs ? '-' : '') + $.toLowerCase());
18
+ export type ScriptObjectSettingsProps = {
19
+ object: ScriptType;
20
+ };
21
21
 
22
- export type ScriptSettingsPanelProps = {
23
- script: ScriptType;
22
+ export const ScriptObjectSettings = ({ object }: ScriptObjectSettingsProps) => {
23
+ return (
24
+ <>
25
+ <Binding object={object} />
26
+ <Publishing object={object} />
27
+ </>
28
+ );
24
29
  };
25
30
 
26
- export const ScriptSettingsPanel = ({ script }: ScriptSettingsPanelProps) => {
31
+ export const ScriptProperties = ({ object }: ScriptObjectSettingsProps) => {
32
+ const { t } = useTranslation(SCRIPT_PLUGIN);
33
+ return (
34
+ <Input.Root>
35
+ <Input.Label>{t('description label')}</Input.Label>
36
+ <Input.TextInput
37
+ placeholder={t('description placeholder')}
38
+ value={object.description ?? ''}
39
+ onChange={(event) => {
40
+ object.description = event.target.value;
41
+ }}
42
+ />
43
+ </Input.Root>
44
+ );
45
+ };
46
+
47
+ const Binding = ({ object }: ScriptObjectSettingsProps) => {
27
48
  const { t } = useTranslation(SCRIPT_PLUGIN);
28
- const { dispatchPromise: dispatch } = useIntentDispatcher();
29
49
  const client = useClient();
30
- const space = getSpace(script);
31
- const [fn] = useQuery(space, Filter.schema(FunctionType, { source: script }));
50
+ const space = getSpace(object);
51
+ const [fn] = useQuery(space, Filter.schema(FunctionType, { source: object }));
52
+
53
+ const functionPath = fn && getUserFunctionUrlInMetadata(getMeta(fn));
54
+ const functionUrl =
55
+ functionPath &&
56
+ getInvocationUrl(functionPath, client.config.values.runtime?.services?.edge?.url ?? '', {
57
+ spaceId: space?.id,
58
+ });
59
+
60
+ const [binding, setBinding] = useControlledState(fn?.binding ?? '');
61
+ const handleBindingChange = useCallback(
62
+ (event: ChangeEvent<HTMLInputElement>) => {
63
+ setBinding(event.target.value);
64
+ },
65
+ [setBinding],
66
+ );
67
+
68
+ const handleBindingBlur = useCallback(() => {
69
+ fn.binding = binding;
70
+ }, [fn, binding]);
71
+
72
+ if (!fn || !functionUrl) {
73
+ return null;
74
+ }
75
+
76
+ // TODO(burdon): Use form.
77
+ return (
78
+ <div role='form' className='flex flex-col p-2 gap-2'>
79
+ <h2>{t('remote function settings heading')}</h2>
80
+ <Input.Root>
81
+ <div role='none' className='flex flex-col gap-1'>
82
+ <Input.Label>{t('function url label')}</Input.Label>
83
+ <div role='none' className='flex gap-1'>
84
+ <Input.TextInput
85
+ disabled
86
+ value={functionUrl}
87
+ onChange={(event) => {
88
+ fn.name = event.target.value;
89
+ }}
90
+ />
91
+ <Clipboard.IconButton value={functionUrl} />
92
+ </div>
93
+ </div>
94
+ </Input.Root>
95
+ <Input.Root>
96
+ <div role='none' className='flex flex-col gap-1'>
97
+ <Input.Label>{t('function binding label')}</Input.Label>
98
+ <Input.TextInput
99
+ placeholder={t('function binding placeholder')}
100
+ value={binding}
101
+ onChange={handleBindingChange}
102
+ onBlur={handleBindingBlur}
103
+ />
104
+ </div>
105
+ </Input.Root>
106
+ </div>
107
+ );
108
+ };
109
+
110
+ // TODO(burdon): Move to separate tab?
111
+ const Publishing = ({ object }: ScriptObjectSettingsProps) => {
112
+ const { t } = useTranslation(SCRIPT_PLUGIN);
113
+ const { dispatchPromise: dispatch } = useIntentDispatcher();
114
+ const space = getSpace(object);
32
115
  const [githubToken] = useQuery(space, Filter.schema(AccessTokenType, { source: 'github.com' }));
33
- const gistKey = getMeta(script).keys.find(({ source }) => source === 'github.com');
116
+ const gistKey = getMeta(object).keys.find(({ source }) => source === 'github.com');
34
117
  const [gistUrl, setGistUrl] = useState<string | undefined>();
35
118
 
36
119
  useEffect(() => {
@@ -57,24 +140,6 @@ export const ScriptSettingsPanel = ({ script }: ScriptSettingsPanelProps) => {
57
140
  return () => clearTimeout(timeout);
58
141
  }, [githubToken, gistKey]);
59
142
 
60
- const [binding, setBinding] = useControlledState(fn?.binding ?? '');
61
- const handleBindingChange = useCallback(
62
- (event: ChangeEvent<HTMLInputElement>) => {
63
- setBinding(event.target.value);
64
- },
65
- [setBinding],
66
- );
67
- const handleBindingBlur = useCallback(() => {
68
- fn.binding = binding;
69
- }, [fn, binding]);
70
-
71
- const functionPath = fn && getUserFunctionUrlInMetadata(getMeta(fn));
72
- const functionUrl =
73
- functionPath &&
74
- getInvocationUrl(functionPath, client.config.values.runtime?.services?.edge?.url ?? '', {
75
- spaceId: space?.id,
76
- });
77
-
78
143
  const handleOpenTokenManager = useCallback(
79
144
  () => dispatch(createIntent(SettingsAction.Open, { plugin: 'dxos.org/plugin/token-manager' })),
80
145
  [],
@@ -84,13 +149,13 @@ export const ScriptSettingsPanel = ({ script }: ScriptSettingsPanelProps) => {
84
149
  const handlePublish = useCallback(async () => {
85
150
  setPublishing(true);
86
151
  const octokit = new Octokit({ auth: githubToken.token });
87
- const source = await script.source.load();
88
- const filename = script.name ? kebabize(script.name) : 'composer-script';
152
+ const source = await object.source.load();
153
+ const filename = object.name ? kebabize(object.name) : 'composer-script';
89
154
  const files = { [`${filename}.ts`]: { content: source.content } };
90
155
 
91
156
  try {
92
157
  // TODO(wittjosiah): Factor out to intent.
93
- const meta = getMeta(script);
158
+ const meta = getMeta(object);
94
159
  const githubKey = meta.keys.find(({ source }) => source === 'github.com');
95
160
  const gistId = githubKey?.id;
96
161
  if (gistId) {
@@ -110,79 +175,32 @@ export const ScriptSettingsPanel = ({ script }: ScriptSettingsPanelProps) => {
110
175
  } finally {
111
176
  setPublishing(false);
112
177
  }
113
- }, [script, githubToken]);
178
+ }, [object, githubToken]);
114
179
 
115
180
  return (
116
- <>
117
- <div role='form' className='flex flex-col w-full p-2 gap-4'>
118
- <Input.Root>
119
- <div role='none' className='flex flex-col gap-1'>
120
- <Input.Label>{t('description label')}</Input.Label>
121
- <Input.TextInput
122
- placeholder={t('description placeholder')}
123
- value={script.description ?? ''}
124
- onChange={(event) => {
125
- script.description = event.target.value;
126
- }}
127
- />
128
- </div>
129
- </Input.Root>
181
+ <div className='flex flex-col p-2 gap-4'>
182
+ <div>
183
+ <h2>{t('script publish settings label')}</h2>
184
+ <p className='text-description text-sm'>{t('script publish settings description')}</p>
130
185
  </div>
131
- {fn && functionUrl && (
132
- <>
133
- <Separator />
134
- <div role='form' className='flex flex-col w-full p-2 gap-4'>
135
- <h2>{t('remote function settings heading')}</h2>
136
- <Input.Root>
137
- <div role='none' className='flex flex-col gap-1'>
138
- <Input.Label>{t('function url label')}</Input.Label>
139
- <div role='none' className='flex gap-1'>
140
- <Input.TextInput
141
- disabled
142
- value={functionUrl}
143
- onChange={(event) => {
144
- fn.name = event.target.value;
145
- }}
146
- />
147
- <Clipboard.IconButton value={functionUrl} />
148
- </div>
149
- </div>
150
- </Input.Root>
151
- <Input.Root>
152
- <div role='none' className='flex flex-col gap-1'>
153
- <Input.Label>{t('function binding label')}</Input.Label>
154
- <Input.TextInput
155
- placeholder={t('function binding placeholder')}
156
- value={binding}
157
- onChange={handleBindingChange}
158
- onBlur={handleBindingBlur}
159
- />
160
- </div>
161
- </Input.Root>
162
- </div>
163
- </>
186
+ {!githubToken && (
187
+ <div className='flex flex-col gap-2'>
188
+ <span>{t('no github token label')}</span>
189
+ <Button onClick={handleOpenTokenManager}>{t('open token manager label')}</Button>
190
+ </div>
164
191
  )}
165
- <Separator />
166
- <div className='flex flex-col w-full p-2 gap-4'>
167
- <div>
168
- <h2>{t('script publish settings label')}</h2>
169
- <p className='text-description text-sm'>{t('script publish settings description')}</p>
192
+ {githubToken && (
193
+ <div className='flex justify-end gap-2'>
194
+ {gistUrl && <Clipboard.IconButton value={gistUrl} />}
195
+ <Button disabled={publishing} onClick={handlePublish}>
196
+ {t(publishing ? 'publishing label' : 'publish label')}
197
+ </Button>
170
198
  </div>
171
- {!githubToken && (
172
- <div className='flex flex-col items-center justify-center gap-2'>
173
- <span>{t('no github token label')}</span>
174
- <Button onClick={handleOpenTokenManager}>{t('open token manager label')}</Button>
175
- </div>
176
- )}
177
- {githubToken && (
178
- <div className='flex justify-end gap-2'>
179
- {gistUrl && <Clipboard.IconButton value={gistUrl} />}
180
- <Button disabled={publishing} onClick={handlePublish}>
181
- {t(publishing ? 'publishing label' : 'publish label')}
182
- </Button>
183
- </div>
184
- )}
185
- </div>
186
- </>
199
+ )}
200
+ </div>
187
201
  );
188
202
  };
203
+
204
+ // TODO(wittjosiah): Factor out.
205
+ // From https://stackoverflow.com/a/67243723/2804332
206
+ const kebabize = (str: string) => str.replace(/[A-Z]+(?![a-z])|[A-Z]/g, ($, ofs) => (ofs ? '-' : '') + $.toLowerCase());
@@ -10,11 +10,11 @@ import { Button, Select, useTranslation } from '@dxos/react-ui';
10
10
  import { type EditorInputMode, EditorInputModes } from '@dxos/react-ui-editor';
11
11
  import { DeprecatedFormContainer, DeprecatedFormInput } from '@dxos/react-ui-form';
12
12
 
13
- import { SCRIPT_PLUGIN } from '../../meta';
13
+ import { meta } from '../../meta';
14
14
  import { type ScriptSettingsProps } from '../../types';
15
15
 
16
- export const ScriptSettings = ({ settings }: { settings: ScriptSettingsProps }) => {
17
- const { t } = useTranslation(SCRIPT_PLUGIN);
16
+ export const ScriptPluginSettings = ({ settings }: { settings: ScriptSettingsProps }) => {
17
+ const { t } = useTranslation(meta.id);
18
18
  const client = useClient();
19
19
 
20
20
  // TODO(burdon): Check token.
@@ -0,0 +1,6 @@
1
+ //
2
+ // Copyright 2024 DXOS.org
3
+ //
4
+
5
+ export * from './ScriptObjectSettings';
6
+ export * from './ScriptPluginSettings';
@@ -18,11 +18,12 @@ type State = 'pending' | 'responding';
18
18
  */
19
19
  type Message = { type: 'request' | 'response'; text?: string; data?: any; error?: Error };
20
20
 
21
- export type DebugPanelProps = ThemedClassName<{
21
+ export type TestPanelProps = ThemedClassName<{
22
22
  functionUrl?: string;
23
23
  }>;
24
24
 
25
- export const DebugPanel = ({ classNames, functionUrl }: DebugPanelProps) => {
25
+ // TODO(burdon): Need persistent history (currently lost when switching tabs)..
26
+ export const TestPanel = ({ classNames, functionUrl }: TestPanelProps) => {
26
27
  const { t } = useTranslation(SCRIPT_PLUGIN);
27
28
 
28
29
  const inputRef = useRef<HTMLInputElement>(null);
@@ -30,7 +31,7 @@ export const DebugPanel = ({ classNames, functionUrl }: DebugPanelProps) => {
30
31
  const [result, setResult] = useState('');
31
32
  const [state, setState] = useState<State | null>(null);
32
33
 
33
- // TODO(burdon): Persistent history -- at least for session (non-space ECHO data?)
34
+ // TODO(burdon): Persistent history (thread).
34
35
  const [history, setHistory] = useState<Message[]>([]);
35
36
 
36
37
  const scrollerRef = useRef<HTMLDivElement>(null);
@@ -161,8 +162,8 @@ export const DebugPanel = ({ classNames, functionUrl }: DebugPanelProps) => {
161
162
  <div className={mx('flex flex-col h-full overflow-hidden', classNames)}>
162
163
  {/* TODO(burdon): Replace with Thread. */}
163
164
  <MessageThread ref={scrollerRef} state={state} result={result} history={history} />
164
-
165
- <Toolbar.Root classNames='p-1'>
165
+ {/* TODO(burdon): Replace with Form based on the function's input schema. */}
166
+ <Toolbar.Root classNames='p-2'>
166
167
  <Input.Root>
167
168
  <Input.TextInput
168
169
  ref={inputRef}
@@ -185,7 +186,6 @@ export const DebugPanel = ({ classNames, functionUrl }: DebugPanelProps) => {
185
186
  };
186
187
 
187
188
  // TODO(burdon): Replace with thread?
188
- // TODO(burdon): Button to delete individual messages.
189
189
  // TODO(burdon): Button to edit/re-run question.
190
190
  type MessageThreadProps = {
191
191
  state: State | null;
@@ -195,10 +195,6 @@ type MessageThreadProps = {
195
195
 
196
196
  const MessageThread = forwardRef<HTMLDivElement, MessageThreadProps>(
197
197
  ({ state, history, result }: MessageThreadProps, forwardedRef) => {
198
- if (!history.length && !result.length) {
199
- return null;
200
- }
201
-
202
198
  return (
203
199
  <div ref={forwardedRef} className='flex flex-col gap-6 h-full p-2 overflow-x-hidden overflow-y-auto'>
204
200
  {history.map((message, i) => (
@@ -250,9 +246,7 @@ const MessageItem = ({ classNames, message }: ThemedClassName<{ message: Message
250
246
  };
251
247
 
252
248
  const RobotAvatar = () => (
253
- <Avatar.Root size={6} variant='circle'>
254
- <Avatar.Frame>
255
- <Avatar.Icon icon='ph--robot--regular' />
256
- </Avatar.Frame>
249
+ <Avatar.Root>
250
+ <Avatar.Content size={6} variant='circle' icon='ph--robot--regular' />
257
251
  </Avatar.Root>
258
252
  );
@@ -2,4 +2,4 @@
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
- export * from './LogsPanel';
5
+ export * from './TestPanel';
@@ -4,9 +4,9 @@
4
4
 
5
5
  import { lazy } from 'react';
6
6
 
7
- export * from './DebugPanel';
8
- export * from './LogsPanel';
9
- export * from './ScriptSettings';
10
- export * from './ScriptSettingsPanel';
7
+ export * from './Settings';
8
+ export * from './TestPanel';
9
+ export { DEPLOYMENT_DIALOG } from './DeploymentDialog';
11
10
 
12
11
  export const ScriptContainer = lazy(() => import('./ScriptContainer'));
12
+ export const DeploymentDialog = lazy(() => import('./DeploymentDialog'));
@@ -4,28 +4,20 @@
4
4
 
5
5
  import { useCallback, useEffect, useMemo } from 'react';
6
6
 
7
- import {
8
- FunctionType,
9
- type ScriptType,
10
- getInvocationUrl,
11
- getUserFunctionUrlInMetadata,
12
- incrementSemverPatch,
13
- setUserFunctionUrlInMetadata,
14
- uploadWorkerFunction,
15
- } from '@dxos/functions';
16
- import { Bundler } from '@dxos/functions/bundler';
7
+ import { FunctionType, type ScriptType, getUserFunctionUrlInMetadata } from '@dxos/functions';
17
8
  import { log } from '@dxos/log';
18
9
  import { useClient } from '@dxos/react-client';
19
- import { Filter, create, getMeta, getSpace, makeRef, useQuery } from '@dxos/react-client/echo';
10
+ import { Filter, getMeta, getSpace, useQuery } from '@dxos/react-client/echo';
20
11
  import { useTranslation } from '@dxos/react-ui';
21
12
  import { createMenuAction } from '@dxos/react-ui-menu';
13
+ import { errorMessageColors } from '@dxos/react-ui-theme';
22
14
 
23
- import { type ViewState } from './view';
24
15
  import { SCRIPT_PLUGIN } from '../meta';
16
+ import { deployScript, getFunctionUrl, isScriptDeployed } from '../util';
25
17
 
26
18
  export type DeployActionProperties = { type: 'deploy' } | { type: 'copy' };
27
19
 
28
- export type DeployState = ViewState & {
20
+ export type DeployState = {
29
21
  deploying: boolean;
30
22
  deployed: boolean;
31
23
  functionUrl: string;
@@ -37,6 +29,7 @@ export const createDeploy = (state: Partial<DeployState>) => {
37
29
  label: state.error ?? ['no error label', { ns: SCRIPT_PLUGIN }],
38
30
  icon: 'ph--warning-circle--regular',
39
31
  hidden: !state.error,
32
+ classNames: state.error && errorMessageColors,
40
33
  });
41
34
 
42
35
  const deployAction = createMenuAction<DeployActionProperties>('deploy', {
@@ -64,31 +57,36 @@ export const createDeploy = (state: Partial<DeployState>) => {
64
57
  };
65
58
  };
66
59
 
67
- export const useDeployDeps = ({ script }: { script: ScriptType }) => {
68
- const space = getSpace(script);
69
- const [fn] = useQuery(space, Filter.schema(FunctionType, { source: script }));
70
- const client = useClient();
71
- const existingFunctionUrl = useMemo(() => fn && getUserFunctionUrlInMetadata(getMeta(fn)), [fn]);
72
- return { space, fn, client, existingFunctionUrl };
73
- };
74
-
75
60
  export const useDeployState = ({ state, script }: { state: Partial<DeployState>; script: ScriptType }) => {
76
- const { space, client, existingFunctionUrl } = useDeployDeps({ script });
61
+ const { space, client, fn, existingFunctionUrl } = useDeployDeps({ script });
77
62
  useEffect(() => {
78
63
  if (!existingFunctionUrl) {
79
64
  return;
80
65
  }
81
66
 
82
- state.functionUrl = getInvocationUrl(existingFunctionUrl, client.config.values.runtime?.services?.edge?.url ?? '', {
83
- spaceId: space?.id,
67
+ state.functionUrl = getFunctionUrl({
68
+ script,
69
+ fn,
70
+ edgeUrl: client.config.values.runtime?.services?.edge?.url ?? '',
84
71
  });
85
- }, [existingFunctionUrl, space]);
72
+ }, [existingFunctionUrl, space, fn, script, client.config.values.runtime?.services?.edge?.url]);
86
73
 
87
74
  useEffect(() => {
88
- state.deployed = Boolean(existingFunctionUrl) && !script.changed;
89
- }, [script.changed, existingFunctionUrl]);
75
+ state.deployed = isScriptDeployed({ script, fn });
76
+ }, [script.changed, existingFunctionUrl, fn, script]);
77
+ };
78
+
79
+ export const useDeployDeps = ({ script }: { script: ScriptType }) => {
80
+ const space = getSpace(script);
81
+ const [fn] = useQuery(space, Filter.schema(FunctionType, { source: script }));
82
+ const client = useClient();
83
+ const existingFunctionUrl = useMemo(() => fn && getUserFunctionUrlInMetadata(getMeta(fn)), [fn]);
84
+ return { space, fn, client, existingFunctionUrl };
90
85
  };
91
86
 
87
+ /**
88
+ * Manage EDGE function deployment.
89
+ */
92
90
  export const useDeployHandler = ({ state, script }: { state: Partial<DeployState>; script: ScriptType }) => {
93
91
  const { space, fn, client, existingFunctionUrl } = useDeployDeps({ script });
94
92
  const { t } = useTranslation(SCRIPT_PLUGIN);
@@ -101,62 +99,15 @@ export const useDeployHandler = ({ state, script }: { state: Partial<DeployState
101
99
  state.error = undefined;
102
100
  state.deploying = true;
103
101
 
104
- try {
105
- const existingFunctionId = existingFunctionUrl?.split('/').at(-1);
106
-
107
- const bundler = new Bundler({ platform: 'browser', sandboxedModules: [], remoteModules: {} });
108
- const buildResult = await bundler.bundle({ source: script.source.target!.content });
109
- if (buildResult.error || !buildResult.bundle) {
110
- throw buildResult.error;
111
- }
112
-
113
- const { functionId, version, meta } = await uploadWorkerFunction({
114
- client,
115
- spaceId: space.id,
116
- version: fn ? incrementSemverPatch(fn.version) : '0.0.1',
117
- functionId: existingFunctionId,
118
- source: buildResult.bundle,
119
- });
120
- if (functionId === undefined || version === undefined) {
121
- throw new Error(`Upload didn't return expected data: functionId=${functionId}, version=${version}`);
122
- }
123
-
124
- log.info('function uploaded', { functionId, version });
125
- if (fn) {
126
- fn.version = version;
127
- }
128
-
129
- const deployedFunction =
130
- fn ?? space.db.add(create(FunctionType, { name: functionId, version, source: makeRef(script) }));
131
-
132
- script.changed = false;
133
- if (script.description !== undefined && script.description.trim() !== '') {
134
- deployedFunction.description = script.description;
135
- } else if (meta.description) {
136
- deployedFunction.description = meta.description;
137
- } else {
138
- log.verbose('no description in function metadata', { functionId });
139
- }
140
-
141
- if (meta.inputSchema) {
142
- deployedFunction.inputSchema = meta.inputSchema;
143
- } else {
144
- log.verbose('no input schema in function metadata', { functionId });
145
- }
146
-
147
- if (meta.outputSchema) {
148
- deployedFunction.outputSchema = meta.outputSchema;
149
- } else {
150
- log.verbose('no output schema in function metadata', { functionId });
151
- }
152
-
153
- setUserFunctionUrlInMetadata(getMeta(deployedFunction), `/${space.id}/${functionId}`);
154
- } catch (err: any) {
155
- log.catch(err);
102
+ const result = await deployScript({ script, client, space, fn, existingFunctionUrl });
103
+
104
+ if (!result.success) {
105
+ log.catch(result.error);
156
106
  state.error = t('upload failed label');
157
107
  }
108
+
158
109
  state.deploying = false;
159
- }, [fn, client, t, existingFunctionUrl, script, script.name, script.source, space?.id ?? null]);
110
+ }, [fn, client, t, existingFunctionUrl, script, space]);
160
111
  };
161
112
 
162
113
  export const useCopyHandler = ({ state }: { state: Partial<DeployState> }) =>
@@ -5,7 +5,7 @@
5
5
  export * from './deploy';
6
6
  export * from './format';
7
7
  export * from './template';
8
- export * from './view';
9
8
 
9
+ export * from './useCreateAndDeployScriptTemplates';
10
10
  export * from './useToolbarAction';
11
11
  export * from './useToolbarState';
@@ -0,0 +1,59 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { pipe } from 'effect/Function';
6
+ import { useCallback, useState } from 'react';
7
+
8
+ import { chain, createIntent, useIntentDispatcher } from '@dxos/app-framework';
9
+ import { isInstanceOf } from '@dxos/echo-schema';
10
+ import { ScriptType } from '@dxos/functions';
11
+ import { invariant } from '@dxos/invariant';
12
+ import { SpaceAction } from '@dxos/plugin-space/types';
13
+ import { useClient } from '@dxos/react-client';
14
+ import { type Space } from '@dxos/react-client/echo';
15
+
16
+ import { type Template } from '../templates';
17
+ import { ScriptAction } from '../types';
18
+ import { deployScript } from '../util';
19
+
20
+ type DeploymentStatus = 'idle' | 'pending' | 'success' | 'error';
21
+
22
+ /**
23
+ * Hook for creating and deploying multiple script templates concurrently.
24
+ *
25
+ * Takes a space and an array of script template IDs, then provides a callback
26
+ * function that creates each script from its template and deploys it to the space.
27
+ * All creation / deployment operations run concurrently for improved performance.
28
+ */
29
+ export const useCreateAndDeployScriptTemplates = (space: Space | undefined, scriptTemplates: Template[]) => {
30
+ const { dispatchPromise: dispatch } = useIntentDispatcher();
31
+ const client = useClient();
32
+ const [status, setStatus] = useState<DeploymentStatus>('idle');
33
+ const [error, setError] = useState<Error | undefined>(undefined);
34
+
35
+ const handleCreateAndDeployScripts = useCallback(async () => {
36
+ invariant(space);
37
+ setStatus('pending');
38
+ setError(undefined);
39
+
40
+ const deploymentResults = await Promise.all(
41
+ scriptTemplates.map(async (template) => {
42
+ const result = await dispatch(
43
+ pipe(
44
+ createIntent(ScriptAction.Create, { space, initialTemplateId: template.id }),
45
+ chain(SpaceAction.AddObject, { target: space }),
46
+ ),
47
+ );
48
+ invariant(isInstanceOf(ScriptType, result.data?.object));
49
+
50
+ return deployScript({ space, client, script: result.data.object });
51
+ }),
52
+ );
53
+
54
+ const hasErrors = deploymentResults.some((result) => !result.success);
55
+ setStatus(hasErrors ? 'error' : 'success');
56
+ }, [space, dispatch, client, scriptTemplates]);
57
+
58
+ return { handleCreateAndDeployScripts, status, error };
59
+ };
@@ -12,30 +12,26 @@ import { type DeployActionProperties, useDeployHandler, useCopyHandler } from '.
12
12
  import { type FormatActionProperties, useFormatHandler } from './format';
13
13
  import { type TemplateActionProperties, useTemplateSelectHandler } from './template';
14
14
  import { type ScriptToolbarState } from './useToolbarState';
15
- import { type ViewActionProperties } from './view';
16
15
 
17
- export type ScriptToolbarActionProperties =
18
- | TemplateActionProperties
19
- | ViewActionProperties
20
- | FormatActionProperties
21
- | DeployActionProperties;
16
+ export type ScriptToolbarActionProperties = TemplateActionProperties | FormatActionProperties | DeployActionProperties;
22
17
 
23
18
  export type ScriptToolbarAction = MenuAction<ScriptToolbarActionProperties>;
24
19
 
25
- export const useToolbarAction = (props: { state: ScriptToolbarState; script: ScriptType }) => {
20
+ export const useToolbarAction = (props: {
21
+ state: ScriptToolbarState;
22
+ script: ScriptType;
23
+ }): MenuActionHandler<ScriptToolbarAction> => {
26
24
  const handleTemplateSelect = useTemplateSelectHandler(props);
27
25
  const handleFormat = useFormatHandler(props);
28
26
  const handleDeploy = useDeployHandler(props);
29
27
  const handleCopy = useCopyHandler(props);
30
- return useCallback(
31
- ((action: ScriptToolbarAction) => {
28
+
29
+ return useCallback<MenuActionHandler<ScriptToolbarAction>>(
30
+ (action: ScriptToolbarAction) => {
32
31
  switch (action.properties.type) {
33
32
  case 'template':
34
33
  handleTemplateSelect(action.properties.value);
35
34
  break;
36
- case 'view':
37
- props.state.view = action.properties.value;
38
- break;
39
35
  case 'format':
40
36
  void handleFormat();
41
37
  break;
@@ -48,7 +44,7 @@ export const useToolbarAction = (props: { state: ScriptToolbarState; script: Scr
48
44
  default:
49
45
  log.error('Unknown action type', action);
50
46
  }
51
- }) as MenuActionHandler,
47
+ },
52
48
  [handleTemplateSelect, handleFormat, handleDeploy, handleCopy],
53
49
  );
54
50
  };
@@ -7,9 +7,8 @@ import { useMemo } from 'react';
7
7
  import { create } from '@dxos/live-object';
8
8
 
9
9
  import { type DeployState } from './deploy';
10
- import { type ViewState } from './view';
11
10
 
12
- export type ScriptToolbarState = Partial<DeployState & ViewState>;
11
+ export type ScriptToolbarState = Partial<DeployState>;
13
12
 
14
13
  // TODO(burdon): Replace with context provider?
15
14
  export const useToolbarState = (initialState: ScriptToolbarState = {}) => {