@dxos/plugin-script 0.7.4-staging.f7e8224 → 0.7.5-labs.071a3e2

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 (267) hide show
  1. package/dist/lib/browser/{AutomationPanel-PMTZROAZ.mjs → AutomationPanel-J3SZ5L3Y.mjs} +4 -11
  2. package/dist/lib/browser/AutomationPanel-J3SZ5L3Y.mjs.map +7 -0
  3. package/dist/lib/browser/ScriptContainer-LGW52UAJ.mjs +688 -0
  4. package/dist/lib/browser/ScriptContainer-LGW52UAJ.mjs.map +7 -0
  5. package/dist/lib/browser/chunk-2UXYECEH.mjs +236 -0
  6. package/dist/lib/browser/chunk-2UXYECEH.mjs.map +7 -0
  7. package/dist/lib/browser/{chunk-K7KY6YMG.mjs → chunk-45LXDWNF.mjs} +2 -2
  8. package/dist/lib/browser/chunk-6MOQ4BP3.mjs +15 -0
  9. package/dist/lib/browser/chunk-6MOQ4BP3.mjs.map +7 -0
  10. package/dist/lib/browser/chunk-FVVCAWNP.mjs +21 -0
  11. package/dist/lib/browser/chunk-FVVCAWNP.mjs.map +7 -0
  12. package/dist/lib/browser/chunk-N46LE7FS.mjs +40 -0
  13. package/dist/lib/browser/chunk-N46LE7FS.mjs.map +7 -0
  14. package/dist/lib/browser/{chunk-4UTRJLQ3.mjs → chunk-SDHKTS6H.mjs} +2 -51
  15. package/dist/lib/browser/{chunk-4UTRJLQ3.mjs.map → chunk-SDHKTS6H.mjs.map} +4 -4
  16. package/dist/lib/browser/chunk-VIX22OMB.mjs +60 -0
  17. package/dist/lib/browser/chunk-VIX22OMB.mjs.map +7 -0
  18. package/dist/lib/browser/compiler-K3FNRDDN.mjs +84 -0
  19. package/dist/lib/browser/compiler-K3FNRDDN.mjs.map +7 -0
  20. package/dist/lib/browser/index.mjs +109 -357
  21. package/dist/lib/browser/index.mjs.map +4 -4
  22. package/dist/lib/browser/intent-resolver-CMKQTLBG.mjs +45 -0
  23. package/dist/lib/browser/intent-resolver-CMKQTLBG.mjs.map +7 -0
  24. package/dist/lib/browser/meta.json +1 -1
  25. package/dist/lib/browser/react-surface-XACNR5NR.mjs +65 -0
  26. package/dist/lib/browser/react-surface-XACNR5NR.mjs.map +7 -0
  27. package/dist/lib/browser/settings-SZCDKHWO.mjs +24 -0
  28. package/dist/lib/browser/settings-SZCDKHWO.mjs.map +7 -0
  29. package/dist/lib/browser/types.mjs +10 -0
  30. package/dist/lib/node/{AutomationPanel-AAGQREH7.cjs → AutomationPanel-4M55FURO.cjs} +16 -17
  31. package/dist/lib/node/AutomationPanel-4M55FURO.cjs.map +7 -0
  32. package/dist/lib/node/ScriptContainer-UI2MDBYG.cjs +692 -0
  33. package/dist/lib/node/ScriptContainer-UI2MDBYG.cjs.map +7 -0
  34. package/dist/lib/node/{chunk-6LYX73ZT.cjs → chunk-5UH3F7TA.cjs} +11 -8
  35. package/dist/lib/node/chunk-5UH3F7TA.cjs.map +7 -0
  36. package/dist/lib/node/chunk-73345ZL6.cjs +264 -0
  37. package/dist/lib/node/chunk-73345ZL6.cjs.map +7 -0
  38. package/dist/lib/node/{meta.cjs → chunk-ALY3N6PW.cjs} +12 -8
  39. package/dist/lib/node/chunk-ALY3N6PW.cjs.map +7 -0
  40. package/dist/lib/node/chunk-DJGLGRQV.cjs +60 -0
  41. package/dist/lib/node/chunk-DJGLGRQV.cjs.map +7 -0
  42. package/dist/lib/node/{chunk-4INUJLXL.cjs → chunk-IID7WUQS.cjs} +6 -6
  43. package/dist/lib/node/chunk-PKT5DD3O.cjs +70 -0
  44. package/dist/lib/node/chunk-PKT5DD3O.cjs.map +7 -0
  45. package/dist/lib/node/{chunk-WPP65EYS.cjs → chunk-T4TXCRN5.cjs} +6 -44
  46. package/dist/lib/node/chunk-T4TXCRN5.cjs.map +7 -0
  47. package/dist/lib/node/compiler-P2HQB22H.cjs +104 -0
  48. package/dist/lib/node/compiler-P2HQB22H.cjs.map +7 -0
  49. package/dist/lib/node/index.cjs +106 -346
  50. package/dist/lib/node/index.cjs.map +4 -4
  51. package/dist/lib/node/intent-resolver-V5ASU5DW.cjs +59 -0
  52. package/dist/lib/node/intent-resolver-V5ASU5DW.cjs.map +7 -0
  53. package/dist/lib/node/meta.json +1 -1
  54. package/dist/lib/node/react-surface-Y3RD5FW7.cjs +84 -0
  55. package/dist/lib/node/react-surface-Y3RD5FW7.cjs.map +7 -0
  56. package/dist/lib/node/settings-SZFSMSKM.cjs +38 -0
  57. package/dist/lib/node/settings-SZFSMSKM.cjs.map +7 -0
  58. package/dist/lib/node/{types/index.cjs → types.cjs} +6 -8
  59. package/dist/lib/node/types.cjs.map +7 -0
  60. package/dist/lib/node-esm/{AutomationPanel-ETQEDY5I.mjs → AutomationPanel-W6SKG35R.mjs} +4 -11
  61. package/dist/lib/node-esm/AutomationPanel-W6SKG35R.mjs.map +7 -0
  62. package/dist/lib/node-esm/ScriptContainer-F7SNP53Z.mjs +689 -0
  63. package/dist/lib/node-esm/ScriptContainer-F7SNP53Z.mjs.map +7 -0
  64. package/dist/lib/node-esm/{chunk-OFYGBUNI.mjs → chunk-CGF7EOGD.mjs} +2 -2
  65. package/dist/lib/node-esm/chunk-CP5LXTK5.mjs +16 -0
  66. package/dist/lib/node-esm/chunk-CP5LXTK5.mjs.map +7 -0
  67. package/dist/lib/node-esm/{chunk-4SRPREUK.mjs → chunk-G76M6O46.mjs} +2 -51
  68. package/dist/lib/node-esm/{chunk-4SRPREUK.mjs.map → chunk-G76M6O46.mjs.map} +4 -4
  69. package/dist/lib/node-esm/chunk-NBAL5DXN.mjs +62 -0
  70. package/dist/lib/node-esm/chunk-NBAL5DXN.mjs.map +7 -0
  71. package/dist/lib/node-esm/{chunk-SLTZMY34.mjs → chunk-P2V2Y5LV.mjs} +7 -4
  72. package/dist/lib/node-esm/chunk-P2V2Y5LV.mjs.map +7 -0
  73. package/dist/lib/node-esm/chunk-PRGBYF4B.mjs +237 -0
  74. package/dist/lib/node-esm/chunk-PRGBYF4B.mjs.map +7 -0
  75. package/dist/lib/node-esm/chunk-UNQFIERE.mjs +41 -0
  76. package/dist/lib/node-esm/chunk-UNQFIERE.mjs.map +7 -0
  77. package/dist/lib/node-esm/compiler-PDN46H4Y.mjs +85 -0
  78. package/dist/lib/node-esm/compiler-PDN46H4Y.mjs.map +7 -0
  79. package/dist/lib/node-esm/index.mjs +109 -357
  80. package/dist/lib/node-esm/index.mjs.map +4 -4
  81. package/dist/lib/node-esm/intent-resolver-75BHFRUK.mjs +46 -0
  82. package/dist/lib/node-esm/intent-resolver-75BHFRUK.mjs.map +7 -0
  83. package/dist/lib/node-esm/meta.json +1 -1
  84. package/dist/lib/node-esm/react-surface-PKUVZH4S.mjs +66 -0
  85. package/dist/lib/node-esm/react-surface-PKUVZH4S.mjs.map +7 -0
  86. package/dist/lib/node-esm/settings-GR4O2WHZ.mjs +25 -0
  87. package/dist/lib/node-esm/settings-GR4O2WHZ.mjs.map +7 -0
  88. package/dist/lib/node-esm/types.mjs +11 -0
  89. package/dist/types/src/ScriptPlugin.d.ts +1 -3
  90. package/dist/types/src/ScriptPlugin.d.ts.map +1 -1
  91. package/dist/types/src/capabilities/capabilities.d.ts +5 -0
  92. package/dist/types/src/capabilities/capabilities.d.ts.map +1 -0
  93. package/dist/types/src/capabilities/compiler.d.ts +4 -0
  94. package/dist/types/src/capabilities/compiler.d.ts.map +1 -0
  95. package/dist/types/src/capabilities/index.d.ts +6 -0
  96. package/dist/types/src/capabilities/index.d.ts.map +1 -0
  97. package/dist/types/src/capabilities/intent-resolver.d.ts +4 -0
  98. package/dist/types/src/capabilities/intent-resolver.d.ts.map +1 -0
  99. package/dist/types/src/capabilities/react-surface.d.ts +4 -0
  100. package/dist/types/src/capabilities/react-surface.d.ts.map +1 -0
  101. package/dist/types/src/capabilities/settings.d.ts +4 -0
  102. package/dist/types/src/capabilities/settings.d.ts.map +1 -0
  103. package/dist/types/src/components/AutomationPanel/AutomationPanel.d.ts +2 -2
  104. package/dist/types/src/components/AutomationPanel/AutomationPanel.d.ts.map +1 -1
  105. package/dist/types/src/components/ScriptContainer.d.ts +10 -2
  106. package/dist/types/src/components/ScriptContainer.d.ts.map +1 -1
  107. package/dist/types/src/components/ScriptSettings/ScriptSettings.d.ts.map +1 -1
  108. package/dist/types/src/components/ScriptSettingsPanel.d.ts +1 -1
  109. package/dist/types/src/components/ScriptSettingsPanel.d.ts.map +1 -1
  110. package/dist/types/src/components/ScriptToolbar/ScriptToolbar.d.ts +11 -0
  111. package/dist/types/src/components/ScriptToolbar/ScriptToolbar.d.ts.map +1 -0
  112. package/dist/types/src/components/{Toolbar/Toolbar.stories.d.ts → ScriptToolbar/ScriptToolbar.stories.d.ts} +1 -1
  113. package/dist/types/src/components/ScriptToolbar/ScriptToolbar.stories.d.ts.map +1 -0
  114. package/dist/types/src/components/ScriptToolbar/index.d.ts +2 -0
  115. package/dist/types/src/components/ScriptToolbar/index.d.ts.map +1 -0
  116. package/dist/types/src/components/TypescriptEditor/TypescriptEditor.d.ts +4 -2
  117. package/dist/types/src/components/TypescriptEditor/TypescriptEditor.d.ts.map +1 -1
  118. package/dist/types/src/components/TypescriptEditor/TypescriptEditor.stories.d.ts.map +1 -1
  119. package/dist/types/src/components/index.d.ts +1 -1
  120. package/dist/types/src/components/index.d.ts.map +1 -1
  121. package/dist/types/src/hooks/deploy.d.ts +48 -0
  122. package/dist/types/src/hooks/deploy.d.ts.map +1 -0
  123. package/dist/types/src/hooks/format.d.ts +25 -0
  124. package/dist/types/src/hooks/format.d.ts.map +1 -0
  125. package/dist/types/src/hooks/index.d.ts +7 -0
  126. package/dist/types/src/hooks/index.d.ts.map +1 -0
  127. package/dist/types/src/hooks/template.d.ts +31 -0
  128. package/dist/types/src/hooks/template.d.ts.map +1 -0
  129. package/dist/types/src/hooks/useToolbarAction.d.ts +14 -0
  130. package/dist/types/src/hooks/useToolbarAction.d.ts.map +1 -0
  131. package/dist/types/src/hooks/useToolbarState.d.ts +10 -0
  132. package/dist/types/src/hooks/useToolbarState.d.ts.map +1 -0
  133. package/dist/types/src/hooks/view.d.ts +33 -0
  134. package/dist/types/src/hooks/view.d.ts.map +1 -0
  135. package/dist/types/src/index.d.ts +2 -4
  136. package/dist/types/src/index.d.ts.map +1 -1
  137. package/dist/types/src/meta.d.ts +2 -2
  138. package/dist/types/src/meta.d.ts.map +1 -1
  139. package/dist/types/src/templates/echo.d.ts.map +1 -1
  140. package/dist/types/src/templates/email.d.ts +2 -1
  141. package/dist/types/src/templates/email.d.ts.map +1 -1
  142. package/dist/types/src/templates/forex-effect.d.ts +6 -0
  143. package/dist/types/src/templates/forex-effect.d.ts.map +1 -0
  144. package/dist/types/src/templates/forex.d.ts +1 -1
  145. package/dist/types/src/templates/forex.d.ts.map +1 -1
  146. package/dist/types/src/{templates.d.ts → templates/index.d.ts} +1 -1
  147. package/dist/types/src/templates/index.d.ts.map +1 -0
  148. package/dist/types/src/translations.d.ts +54 -0
  149. package/dist/types/src/translations.d.ts.map +1 -1
  150. package/dist/types/src/types.d.ts +30 -0
  151. package/dist/types/src/types.d.ts.map +1 -0
  152. package/dist/types/tsconfig.tsbuildinfo +1 -0
  153. package/package.json +46 -55
  154. package/src/ScriptPlugin.tsx +57 -145
  155. package/src/bundler/bundler.test.ts +4 -3
  156. package/src/capabilities/capabilities.ts +12 -0
  157. package/src/capabilities/compiler.ts +33 -0
  158. package/src/capabilities/index.ts +12 -0
  159. package/src/capabilities/intent-resolver.ts +46 -0
  160. package/src/capabilities/react-surface.tsx +54 -0
  161. package/src/capabilities/settings.ts +14 -0
  162. package/src/compiler/compiler.browser.test.ts +1 -1
  163. package/src/components/AutomationPanel/AutomationPanel.tsx +2 -4
  164. package/src/components/FrameContainer/FrameContainer.tsx +1 -1
  165. package/src/components/ScriptContainer.tsx +69 -9
  166. package/src/components/ScriptSettings/ScriptSettings.tsx +28 -4
  167. package/src/components/ScriptSettingsPanel.tsx +139 -52
  168. package/src/components/{Toolbar/Toolbar.stories.tsx → ScriptToolbar/ScriptToolbar.stories.tsx} +2 -2
  169. package/src/components/ScriptToolbar/ScriptToolbar.tsx +53 -0
  170. package/src/components/{Toolbar → ScriptToolbar}/index.ts +1 -1
  171. package/src/components/TypescriptEditor/TypescriptEditor.stories.tsx +2 -0
  172. package/src/components/TypescriptEditor/TypescriptEditor.tsx +73 -8
  173. package/src/hooks/deploy.ts +158 -0
  174. package/src/hooks/format.ts +47 -0
  175. package/src/hooks/index.ts +11 -0
  176. package/src/hooks/template.ts +64 -0
  177. package/src/hooks/useToolbarAction.ts +54 -0
  178. package/src/hooks/useToolbarState.ts +16 -0
  179. package/src/hooks/view.ts +52 -0
  180. package/src/index.ts +2 -6
  181. package/src/meta.ts +4 -2
  182. package/src/templates/echo.ts +5 -1
  183. package/src/templates/email.ts +26 -23
  184. package/src/templates/forex-effect.ts +42 -0
  185. package/src/templates/forex.ts +21 -13
  186. package/src/{templates.ts → templates/index.ts} +12 -5
  187. package/src/translations.ts +20 -1
  188. package/src/types.ts +39 -0
  189. package/dist/lib/browser/AutomationPanel-PMTZROAZ.mjs.map +0 -7
  190. package/dist/lib/browser/ScriptContainer-RYZFYCNK.mjs +0 -425
  191. package/dist/lib/browser/ScriptContainer-RYZFYCNK.mjs.map +0 -7
  192. package/dist/lib/browser/chunk-C7VBULMK.mjs +0 -18
  193. package/dist/lib/browser/chunk-C7VBULMK.mjs.map +0 -7
  194. package/dist/lib/browser/chunk-QFZUFT5G.mjs +0 -48
  195. package/dist/lib/browser/chunk-QFZUFT5G.mjs.map +0 -7
  196. package/dist/lib/browser/chunk-U3OP64V4.mjs +0 -123
  197. package/dist/lib/browser/chunk-U3OP64V4.mjs.map +0 -7
  198. package/dist/lib/browser/edge/index.mjs +0 -19
  199. package/dist/lib/browser/meta.mjs +0 -9
  200. package/dist/lib/browser/types/index.mjs +0 -12
  201. package/dist/lib/browser/types/index.mjs.map +0 -7
  202. package/dist/lib/node/AutomationPanel-AAGQREH7.cjs.map +0 -7
  203. package/dist/lib/node/ScriptContainer-FZ44UIRC.cjs +0 -427
  204. package/dist/lib/node/ScriptContainer-FZ44UIRC.cjs.map +0 -7
  205. package/dist/lib/node/chunk-6LYX73ZT.cjs.map +0 -7
  206. package/dist/lib/node/chunk-CS25QNKZ.cjs +0 -151
  207. package/dist/lib/node/chunk-CS25QNKZ.cjs.map +0 -7
  208. package/dist/lib/node/chunk-DQYAU2CJ.cjs +0 -67
  209. package/dist/lib/node/chunk-DQYAU2CJ.cjs.map +0 -7
  210. package/dist/lib/node/chunk-WPP65EYS.cjs.map +0 -7
  211. package/dist/lib/node/edge/index.cjs +0 -41
  212. package/dist/lib/node/edge/index.cjs.map +0 -7
  213. package/dist/lib/node/meta.cjs.map +0 -7
  214. package/dist/lib/node/types/index.cjs.map +0 -7
  215. package/dist/lib/node-esm/AutomationPanel-ETQEDY5I.mjs.map +0 -7
  216. package/dist/lib/node-esm/ScriptContainer-3PKDW34A.mjs +0 -426
  217. package/dist/lib/node-esm/ScriptContainer-3PKDW34A.mjs.map +0 -7
  218. package/dist/lib/node-esm/chunk-36DLLQ6E.mjs +0 -125
  219. package/dist/lib/node-esm/chunk-36DLLQ6E.mjs.map +0 -7
  220. package/dist/lib/node-esm/chunk-GMVPKT6A.mjs +0 -49
  221. package/dist/lib/node-esm/chunk-GMVPKT6A.mjs.map +0 -7
  222. package/dist/lib/node-esm/chunk-SLTZMY34.mjs.map +0 -7
  223. package/dist/lib/node-esm/edge/index.mjs +0 -20
  224. package/dist/lib/node-esm/edge/index.mjs.map +0 -7
  225. package/dist/lib/node-esm/meta.mjs +0 -10
  226. package/dist/lib/node-esm/meta.mjs.map +0 -7
  227. package/dist/lib/node-esm/types/index.mjs +0 -13
  228. package/dist/lib/node-esm/types/index.mjs.map +0 -7
  229. package/dist/types/src/components/ScriptBlock/ScriptBlock.d.ts +0 -12
  230. package/dist/types/src/components/ScriptBlock/ScriptBlock.d.ts.map +0 -1
  231. package/dist/types/src/components/ScriptBlock/ScriptBlock.stories.d.ts +0 -6
  232. package/dist/types/src/components/ScriptBlock/ScriptBlock.stories.d.ts.map +0 -1
  233. package/dist/types/src/components/ScriptBlock/index.d.ts +0 -2
  234. package/dist/types/src/components/ScriptBlock/index.d.ts.map +0 -1
  235. package/dist/types/src/components/ScriptEditor.d.ts +0 -9
  236. package/dist/types/src/components/ScriptEditor.d.ts.map +0 -1
  237. package/dist/types/src/components/Toolbar/Toolbar.d.ts +0 -23
  238. package/dist/types/src/components/Toolbar/Toolbar.d.ts.map +0 -1
  239. package/dist/types/src/components/Toolbar/Toolbar.stories.d.ts.map +0 -1
  240. package/dist/types/src/components/Toolbar/index.d.ts +0 -2
  241. package/dist/types/src/components/Toolbar/index.d.ts.map +0 -1
  242. package/dist/types/src/edge/functions.d.ts +0 -25
  243. package/dist/types/src/edge/functions.d.ts.map +0 -1
  244. package/dist/types/src/edge/index.d.ts +0 -2
  245. package/dist/types/src/edge/index.d.ts.map +0 -1
  246. package/dist/types/src/templates.d.ts.map +0 -1
  247. package/dist/types/src/types/index.d.ts +0 -3
  248. package/dist/types/src/types/index.d.ts.map +0 -1
  249. package/dist/types/src/types/schema.d.ts +0 -71
  250. package/dist/types/src/types/schema.d.ts.map +0 -1
  251. package/dist/types/src/types/types.d.ts +0 -8
  252. package/dist/types/src/types/types.d.ts.map +0 -1
  253. package/src/components/ScriptBlock/ScriptBlock.stories.tsx +0 -52
  254. package/src/components/ScriptBlock/ScriptBlock.tsx +0 -102
  255. package/src/components/ScriptBlock/index.ts +0 -5
  256. package/src/components/ScriptEditor.tsx +0 -191
  257. package/src/components/Toolbar/Toolbar.tsx +0 -177
  258. package/src/edge/functions.ts +0 -116
  259. package/src/edge/index.ts +0 -7
  260. package/src/types/index.ts +0 -6
  261. package/src/types/schema.ts +0 -44
  262. package/src/types/types.ts +0 -29
  263. /package/dist/lib/browser/{chunk-K7KY6YMG.mjs.map → chunk-45LXDWNF.mjs.map} +0 -0
  264. /package/dist/lib/browser/{edge/index.mjs.map → types.mjs.map} +0 -0
  265. /package/dist/lib/node/{chunk-4INUJLXL.cjs.map → chunk-IID7WUQS.cjs.map} +0 -0
  266. /package/dist/lib/node-esm/{chunk-OFYGBUNI.mjs.map → chunk-CGF7EOGD.mjs.map} +0 -0
  267. /package/dist/lib/{browser/meta.mjs.map → node-esm/types.mjs.map} +0 -0
@@ -0,0 +1,158 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { useCallback, useEffect, useMemo } from 'react';
6
+
7
+ import {
8
+ FunctionType,
9
+ getInvocationUrl,
10
+ getUserFunctionUrlInMetadata,
11
+ incrementSemverPatch,
12
+ type ScriptType,
13
+ setUserFunctionUrlInMetadata,
14
+ uploadWorkerFunction,
15
+ } from '@dxos/functions';
16
+ import { log } from '@dxos/log';
17
+ import { useClient } from '@dxos/react-client';
18
+ import { Filter, create, getMeta, getSpace, makeRef, useQuery } from '@dxos/react-client/echo';
19
+ import { useTranslation } from '@dxos/react-ui';
20
+ import { createMenuAction } from '@dxos/react-ui-menu';
21
+
22
+ import { type ViewState } from './view';
23
+ import { Bundler } from '../bundler';
24
+ import { SCRIPT_PLUGIN } from '../meta';
25
+
26
+ export type DeployActionProperties = { type: 'deploy' } | { type: 'copy' };
27
+
28
+ export type DeployState = ViewState & {
29
+ deploying: boolean;
30
+ deployed: boolean;
31
+ functionUrl: string;
32
+ error: string;
33
+ };
34
+
35
+ export const createDeploy = (state: Partial<DeployState>) => {
36
+ const errorItem = createMenuAction('error', {
37
+ label: state.error ?? ['no error label', { ns: SCRIPT_PLUGIN }],
38
+ icon: 'ph--warning-circle--regular',
39
+ hidden: !state.error,
40
+ });
41
+
42
+ const deployAction = createMenuAction<DeployActionProperties>('deploy', {
43
+ type: 'deploy',
44
+ label: [state.deploying ? 'pending label' : 'deploy label', { ns: SCRIPT_PLUGIN }],
45
+ icon: state.deploying ? 'ph--spinner-gap--regular' : 'ph--cloud-arrow-up--regular',
46
+ disabled: state.deploying,
47
+ classNames: state.deploying ? '[&_svg]:animate-spin' : '',
48
+ });
49
+
50
+ const copyAction = createMenuAction<DeployActionProperties>('copy', {
51
+ type: 'copy',
52
+ label: ['copy link label', { ns: SCRIPT_PLUGIN }],
53
+ icon: 'ph--link--regular',
54
+ disabled: !state.functionUrl,
55
+ });
56
+
57
+ return {
58
+ nodes: [errorItem, deployAction, copyAction],
59
+ edges: [
60
+ { source: 'root', target: 'error' },
61
+ { source: 'root', target: 'deploy' },
62
+ { source: 'root', target: 'copy' },
63
+ ],
64
+ };
65
+ };
66
+
67
+ const useDeployDeps = ({ state, script }: { state: Partial<DeployState>; 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
+ export const useDeployState = ({ state, script }: { state: Partial<DeployState>; script: ScriptType }) => {
76
+ const { space, client, existingFunctionUrl } = useDeployDeps({ state, script });
77
+ useEffect(() => {
78
+ if (!existingFunctionUrl) {
79
+ return;
80
+ }
81
+
82
+ state.functionUrl = getInvocationUrl(existingFunctionUrl, client.config.values.runtime?.services?.edge?.url ?? '', {
83
+ spaceId: space?.id,
84
+ });
85
+ }, [existingFunctionUrl, space]);
86
+
87
+ useEffect(() => {
88
+ state.deployed = Boolean(existingFunctionUrl) && !script.changed;
89
+ }, [script.changed, existingFunctionUrl]);
90
+ };
91
+
92
+ export const useDeployHandler = ({ state, script }: { state: Partial<DeployState>; script: ScriptType }) => {
93
+ const { space, fn, client, existingFunctionUrl } = useDeployDeps({ state, script });
94
+ const { t } = useTranslation(SCRIPT_PLUGIN);
95
+
96
+ return useCallback(async () => {
97
+ if (!script.source || !space) {
98
+ return;
99
+ }
100
+
101
+ state.error = undefined;
102
+ state.deploying = true;
103
+
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(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
+ deployedFunction.description = script.description;
134
+
135
+ if (meta.inputSchema) {
136
+ deployedFunction.inputSchema = meta.inputSchema;
137
+ } else {
138
+ log.verbose('no input schema in function metadata', { functionId });
139
+ }
140
+
141
+ setUserFunctionUrlInMetadata(getMeta(deployedFunction), `/${space.id}/${functionId}`);
142
+
143
+ state.view = 'split';
144
+ } catch (err: any) {
145
+ log.catch(err);
146
+ state.error = t('upload failed label');
147
+ }
148
+ state.deploying = false;
149
+ }, [fn, client, t, existingFunctionUrl, script, script.name, script.source, space?.id ?? null]);
150
+ };
151
+
152
+ export const useCopyHandler = ({ state }: { state: Partial<DeployState> }) =>
153
+ useCallback(async () => {
154
+ if (!state.functionUrl) {
155
+ return;
156
+ }
157
+ await navigator.clipboard.writeText(state.functionUrl);
158
+ }, [state.functionUrl]);
@@ -0,0 +1,47 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { format } from 'prettier';
6
+ import prettierPluginEstree from 'prettier/plugins/estree';
7
+ import prettierPluginTypescript from 'prettier/plugins/typescript';
8
+ import { useCallback } from 'react';
9
+
10
+ import { type ScriptType } from '@dxos/functions';
11
+ import { log } from '@dxos/log';
12
+ import { createMenuAction } from '@dxos/react-ui-menu';
13
+
14
+ import { SCRIPT_PLUGIN } from '../meta';
15
+
16
+ export type FormatActionProperties = { type: 'format' };
17
+
18
+ export const createFormat = () => {
19
+ const formatAction = createMenuAction('format', {
20
+ label: ['format label', { ns: SCRIPT_PLUGIN }],
21
+ icon: 'ph--magic-wand--regular',
22
+ });
23
+
24
+ return {
25
+ nodes: [formatAction],
26
+ edges: [{ source: 'root', target: 'format' }],
27
+ };
28
+ };
29
+
30
+ export const useFormatHandler = ({ script }: { script: ScriptType }) =>
31
+ useCallback(async () => {
32
+ if (!script.source) {
33
+ return;
34
+ }
35
+
36
+ try {
37
+ script.source.target!.content = await format(script.source.target!.content, {
38
+ parser: 'typescript',
39
+ plugins: [prettierPluginEstree, prettierPluginTypescript],
40
+ semi: true,
41
+ singleQuote: true,
42
+ });
43
+ } catch (err: any) {
44
+ // TODO(wittjosiah): Show error in UI.
45
+ log.catch(err);
46
+ }
47
+ }, [script.source]);
@@ -0,0 +1,11 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ export * from './deploy';
6
+ export * from './format';
7
+ export * from './template';
8
+ export * from './view';
9
+
10
+ export * from './useToolbarAction';
11
+ export * from './useToolbarState';
@@ -0,0 +1,64 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { useCallback } from 'react';
6
+
7
+ import { FUNCTIONS_PRESET_META_KEY, type ScriptType } from '@dxos/functions';
8
+ import { getMeta } from '@dxos/live-object';
9
+ import { createMenuItemGroup, createMenuAction } from '@dxos/react-ui-menu';
10
+
11
+ import { SCRIPT_PLUGIN } from '../meta';
12
+ import { templates } from '../templates';
13
+
14
+ export type TemplateActionProperties = { type: 'template'; value: string };
15
+
16
+ const createTemplateSelectGroup = () => {
17
+ return createMenuItemGroup('template-select', {
18
+ label: ['template select group label', { ns: SCRIPT_PLUGIN }],
19
+ variant: 'dropdownMenu',
20
+ });
21
+ };
22
+
23
+ const createTemplateSelectActions = () => {
24
+ return templates.map((template) => {
25
+ return createMenuAction<TemplateActionProperties>(`template--${template.id}`, {
26
+ label: template.name,
27
+ value: template.id,
28
+ type: 'template',
29
+ });
30
+ });
31
+ };
32
+
33
+ export const createTemplateSelect = () => {
34
+ const templateSelectGroup = createTemplateSelectGroup();
35
+ const templateSelectActions = createTemplateSelectActions();
36
+ return {
37
+ nodes: [templateSelectGroup, ...templateSelectActions],
38
+ edges: [
39
+ { source: 'root', target: 'template-select' },
40
+ ...templateSelectActions.map((action) => ({ source: 'template-select', target: action.id })),
41
+ ],
42
+ };
43
+ };
44
+
45
+ export const useTemplateSelectHandler = ({ script }: { script: ScriptType }) => {
46
+ return useCallback(
47
+ (templateId: string) => {
48
+ const template = templates.find((template) => template.id === templateId);
49
+ if (template) {
50
+ script.name = template.name;
51
+ script.source!.target!.content = template.source;
52
+ const metaKeys = getMeta(script).keys;
53
+ const oldPresetIndex = metaKeys.findIndex((key) => key.source === FUNCTIONS_PRESET_META_KEY);
54
+ if (oldPresetIndex >= 0) {
55
+ metaKeys.splice(oldPresetIndex, 1);
56
+ }
57
+ if (template.presetId) {
58
+ metaKeys.push({ source: FUNCTIONS_PRESET_META_KEY, id: template.presetId });
59
+ }
60
+ }
61
+ },
62
+ [script],
63
+ );
64
+ };
@@ -0,0 +1,54 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { useCallback } from 'react';
6
+
7
+ import { type ScriptType } from '@dxos/functions';
8
+ import { log } from '@dxos/log';
9
+ import { type MenuAction, type MenuActionHandler } from '@dxos/react-ui-menu';
10
+
11
+ import { type DeployActionProperties, useDeployHandler, useCopyHandler } from './deploy';
12
+ import { type FormatActionProperties, useFormatHandler } from './format';
13
+ import { type TemplateActionProperties, useTemplateSelectHandler } from './template';
14
+ import { type ScriptToolbarState } from './useToolbarState';
15
+ import { type ViewActionProperties } from './view';
16
+
17
+ export type ScriptToolbarActionProperties =
18
+ | TemplateActionProperties
19
+ | ViewActionProperties
20
+ | FormatActionProperties
21
+ | DeployActionProperties;
22
+
23
+ export type ScriptToolbarAction = MenuAction<ScriptToolbarActionProperties>;
24
+
25
+ export const useToolbarAction = (props: { state: ScriptToolbarState; script: ScriptType }) => {
26
+ const handleTemplateSelect = useTemplateSelectHandler(props);
27
+ const handleFormat = useFormatHandler(props);
28
+ const handleDeploy = useDeployHandler(props);
29
+ const handleCopy = useCopyHandler(props);
30
+ return useCallback(
31
+ ((action: ScriptToolbarAction) => {
32
+ switch (action.properties.type) {
33
+ case 'template':
34
+ handleTemplateSelect(action.properties.value);
35
+ break;
36
+ case 'view':
37
+ props.state.view = action.properties.value;
38
+ break;
39
+ case 'format':
40
+ void handleFormat();
41
+ break;
42
+ case 'deploy':
43
+ void handleDeploy();
44
+ break;
45
+ case 'copy':
46
+ void handleCopy();
47
+ break;
48
+ default:
49
+ log.error('Unknown action type', action);
50
+ }
51
+ }) as MenuActionHandler,
52
+ [handleTemplateSelect, handleFormat, handleDeploy, handleCopy],
53
+ );
54
+ };
@@ -0,0 +1,16 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { useMemo } from 'react';
6
+
7
+ import { create } from '@dxos/live-object';
8
+
9
+ import { type DeployState } from './deploy';
10
+ import { type ViewState } from './view';
11
+
12
+ export type ScriptToolbarState = Partial<DeployState & ViewState>;
13
+
14
+ export const useToolbarState = (initialState: ScriptToolbarState = {}) => {
15
+ return useMemo(() => create<ScriptToolbarState>(initialState), []);
16
+ };
@@ -0,0 +1,52 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { createMenuAction, createMenuItemGroup } from '@dxos/react-ui-menu';
6
+
7
+ import { SCRIPT_PLUGIN } from '../meta';
8
+
9
+ export type ViewType = 'editor' | 'split' | 'debug';
10
+
11
+ export type ViewState = { view: ViewType };
12
+
13
+ export type ViewActionProperties = { type: 'view'; value: ViewType };
14
+
15
+ const views: Record<ViewType, string> = {
16
+ editor: 'ph--code--regular',
17
+ split: 'ph--square-split-vertical--regular',
18
+ debug: 'ph--bug--regular',
19
+ };
20
+
21
+ const createViewGroupItem = (state: Partial<ViewState>) => {
22
+ return createMenuItemGroup('view', {
23
+ label: ['view group label', { ns: SCRIPT_PLUGIN }],
24
+ variant: 'dropdownMenu',
25
+ applyActive: true,
26
+ value: state.view,
27
+ });
28
+ };
29
+
30
+ const createViewActions = (state: Partial<ViewState>) => {
31
+ return Object.entries(views).map(([viewType, icon]) => {
32
+ return createMenuAction<ViewActionProperties>(`view--${viewType}`, {
33
+ type: 'view',
34
+ value: viewType as ViewType,
35
+ label: [`view ${viewType} label`, { ns: SCRIPT_PLUGIN }],
36
+ icon,
37
+ checked: state.view === viewType,
38
+ });
39
+ });
40
+ };
41
+
42
+ export const createView = (state: Partial<ViewState>) => {
43
+ const viewGroupItem = createViewGroupItem(state);
44
+ const viewActions = createViewActions(state);
45
+ return {
46
+ nodes: [viewGroupItem, ...viewActions],
47
+ edges: [
48
+ { source: 'root', target: 'view' },
49
+ ...viewActions.map((action) => ({ source: 'view', target: action.id })),
50
+ ],
51
+ };
52
+ };
package/src/index.ts CHANGED
@@ -2,13 +2,9 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- import { ScriptPlugin } from './ScriptPlugin';
6
-
7
- export default ScriptPlugin;
8
-
9
5
  export * from './bundler';
10
- export * from './compiler';
6
+ export { ScriptCapabilities } from './capabilities';
11
7
  export * from './components';
12
- export * from './types';
8
+ export * from './meta';
13
9
 
14
10
  export * from './ScriptPlugin';
package/src/meta.ts CHANGED
@@ -6,11 +6,13 @@ import { type PluginMeta } from '@dxos/app-framework';
6
6
 
7
7
  export const SCRIPT_PLUGIN = 'dxos.org/plugin/script';
8
8
 
9
- export default {
9
+ export const meta = {
10
10
  id: SCRIPT_PLUGIN,
11
11
  name: 'Scripts',
12
- description: 'Distributed functions.',
12
+ description:
13
+ 'Scripts in Composer allow you to deploy custom functions that run on the edge. These functions can be referenced by your AI agent and called inside of cells in any Sheet. Use scripts to interact with API’s or external data inside of Composer.',
13
14
  icon: 'ph--code--regular',
14
15
  source: 'https://github.com/dxos/dxos/tree/main/packages/plugins/experimental/plugin-explorer',
15
16
  tags: ['experimental'],
17
+ screenshots: ['https://dxos.network/plugin-details-scripts-dark.png'],
16
18
  } satisfies PluginMeta;
@@ -11,5 +11,9 @@ export default async ({
11
11
  },
12
12
  }: any) => {
13
13
  const data = await request.json();
14
- return new Response(JSON.stringify(data ?? {}), { headers: { 'Content-Type': 'application/json' } });
14
+ return new Response(JSON.stringify(data ?? {}), {
15
+ headers: {
16
+ 'Content-Type': 'application/json',
17
+ },
18
+ });
15
19
  };
@@ -3,7 +3,8 @@
3
3
  //
4
4
 
5
5
  /**
6
- * Stores a message into ECHO Mailbox object.
6
+ * Appends a message to the end of a Document configured through a trigger.
7
+ * Trigger must have a targetDocumentId field set in Meta.
7
8
  */
8
9
  export default async ({
9
10
  event: {
@@ -11,28 +12,30 @@ export default async ({
11
12
  },
12
13
  context: { space },
13
14
  }: any) => {
14
- const {
15
- data: {
16
- objects: [message],
17
- },
18
- } = await request.json();
15
+ const { data, trigger } = (await request.json()) as RequestPayload;
19
16
 
20
- const mailbox = await space.crud.query({ __typename: 'dxos.org/type/MailboxType' }).first();
21
- if (!mailbox) {
22
- return new Response('Mailbox not found.', { status: 500 });
23
- }
17
+ const documentId = trigger.meta.targetDocumentId;
18
+ const document = await space.db.query({ id: documentId }, { format: 'plain' }).first();
24
19
 
25
- await space.crud.push(
26
- { id: mailbox.id },
27
- {
28
- sender: { email: message.from },
29
- timestamp: new Date(message.created).toISOString(),
30
- text: message.body,
31
- properties: {
32
- subject: message.subject,
33
- to: [{ email: message.to }],
34
- },
35
- },
36
- );
37
- return new Response(JSON.stringify(message));
20
+ const contentId = document.content['/'].split(':')[3];
21
+ const documentContent = await space.db.query({ id: contentId }, { format: 'plain' }).first();
22
+ const modifiedContent = [
23
+ documentContent.content,
24
+ '',
25
+ '---',
26
+ `**From:** ${data.from}`,
27
+ `**Subject:** ${data.subject}`,
28
+ `**Date:** ${data.created}`,
29
+ '',
30
+ data.body,
31
+ ].join('\n');
32
+
33
+ await space.db.update({ id: contentId }, { content: modifiedContent });
34
+
35
+ return new Response(JSON.stringify({ success: true }));
36
+ };
37
+
38
+ type RequestPayload = {
39
+ data: { from: string; subject: string; created: string; body: string };
40
+ trigger: { meta: { targetDocumentId: string } };
38
41
  };
@@ -0,0 +1,42 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ // @ts-ignore
6
+ import { defineFunction, S } from 'dxos:functions';
7
+ import {
8
+ HttpClient,
9
+ HttpClientRequest,
10
+ HttpClientResponse,
11
+ HttpClientError,
12
+ // @ts-ignore
13
+ } from 'https://esm.sh/@effect/platform@0.61.0?deps=effect@3.6.0';
14
+ // @ts-ignore
15
+ import type { Cause } from 'https://esm.sh/effect@3.6.0';
16
+ // @ts-ignore
17
+ import { Effect, Schedule } from 'https://esm.sh/effect@3.6.0';
18
+
19
+ /**
20
+ * Returns the exchange rate between two currencies.
21
+ */
22
+ export default defineFunction({
23
+ inputSchema: S.Struct({
24
+ from: S.String.annotations({ description: 'The source currency' }),
25
+ to: S.String.annotations({ description: 'The target currency' }),
26
+ }),
27
+
28
+ outputSchema: S.String,
29
+
30
+ handler: async ({
31
+ event: {
32
+ data: { from, to },
33
+ },
34
+ }: any) =>
35
+ HttpClientRequest.get(`https://free.ratesdb.com/v1/rates?from=${from}&to=${to}`).pipe(
36
+ HttpClient.fetchOk,
37
+ HttpClientResponse.json,
38
+ Effect.timeout('1 second'),
39
+ Effect.retry(Schedule.exponential(1000).pipe(Schedule.compose(Schedule.recurs(3)))),
40
+ Effect.map(({ data: { rates } }: any) => rates[to].toString()),
41
+ ),
42
+ });
@@ -1,21 +1,29 @@
1
1
  //
2
- // Copyright 2024 DXOS.org
2
+ // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
+ // @ts-ignore
6
+ import { defineFunction, S } from 'dxos:functions';
7
+
5
8
  /**
6
9
  * Returns the exchange rate between two currencies.
7
10
  */
8
- export default async ({
9
- event: {
10
- data: { request },
11
- },
12
- }: any) => {
13
- const { args: [from = 'EUR', to = 'USD'] = [] } = await request.json();
11
+ export default defineFunction({
12
+ inputSchema: S.Struct({
13
+ from: S.String.annotations({ description: 'The source currency' }),
14
+ to: S.String.annotations({ description: 'The target currency' }),
15
+ }),
14
16
 
15
- const res = await fetch(`https://free.ratesdb.com/v1/rates?from=${from}&to=${to}`);
16
- const {
17
- data: { rates },
18
- } = await res.json();
17
+ handler: async ({
18
+ event: {
19
+ data: { from, to },
20
+ },
21
+ }: any) => {
22
+ const res = await fetch(`https://free.ratesdb.com/v1/rates?from=${from}&to=${to}`);
23
+ const {
24
+ data: { rates },
25
+ } = await res.json();
19
26
 
20
- return new Response(rates[to].toString());
21
- };
27
+ return rates[to].toString();
28
+ },
29
+ });
@@ -3,15 +3,17 @@
3
3
  //
4
4
 
5
5
  // @ts-ignore
6
- import chat from './templates/chat.ts?raw';
6
+ import chat from './chat.ts?raw';
7
7
  // @ts-ignore
8
- import chess from './templates/chess.ts?raw';
8
+ import chess from './chess.ts?raw';
9
9
  // @ts-ignore
10
- import echo from './templates/echo.ts?raw';
10
+ import echo from './echo.ts?raw';
11
11
  // @ts-ignore
12
- import email from './templates/email.ts?raw';
12
+ import email from './email.ts?raw';
13
13
  // @ts-ignore
14
- import forex from './templates/forex.ts?raw';
14
+ import forex from './forex.ts?raw';
15
+ // @ts-ignore
16
+ import forexEffect from './forex-effect.ts?raw';
15
17
 
16
18
  const removeHeader = (str: string) => str.split('\n').slice(4).join('\n');
17
19
 
@@ -33,6 +35,11 @@ export const templates: Template[] = [
33
35
  name: 'Forex',
34
36
  source: removeHeader(forex),
35
37
  },
38
+ {
39
+ id: 'dxos.org/script/forex-effect',
40
+ name: 'Forex (Effect)',
41
+ source: removeHeader(forexEffect),
42
+ },
36
43
  {
37
44
  id: 'dxos.org/script/gpt',
38
45
  name: 'Gpt',
@@ -2,8 +2,9 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
+ import { ScriptType } from '@dxos/functions';
6
+
5
7
  import { SCRIPT_PLUGIN } from './meta';
6
- import { ScriptType } from './types';
7
8
 
8
9
  export default [
9
10
  {
@@ -16,6 +17,8 @@ export default [
16
17
  'object title placeholder': 'New script',
17
18
  'create object label': 'Create script',
18
19
  'create stack section label': 'Create script',
20
+ 'description label': 'Description',
21
+ 'description placeholder': 'Describe what the script does.',
19
22
  'binding placeholder': 'Function name',
20
23
  'function request placeholder': 'Function request',
21
24
  'deploy label': 'Deploy',
@@ -31,6 +34,22 @@ export default [
31
34
  'function url label': 'Invocation URL',
32
35
  'function binding label': 'Function binding',
33
36
  'function binding placeholder': 'BINDING',
37
+ 'script publish settings label': 'Publishing',
38
+ 'script publish settings description': 'Scripts can be shared publicly as Github gists.',
39
+ 'no github token label': 'This space has no Github access token available.',
40
+ 'open token manager label': 'Open Token Manager',
41
+ 'publish label': 'Publish',
42
+ 'publishing label': 'Publishing',
43
+ 'editor input mode label': 'Editor input mode',
44
+ 'select editor input mode placeholder': 'Select editor input mode…',
45
+ 'settings editor input mode default label': 'Default',
46
+ 'settings editor input mode vim label': 'Vim',
47
+ 'settings editor input mode vscode label': 'VS Code',
48
+ 'view group label': 'View',
49
+ 'view editor label': 'Editor',
50
+ 'view split label': 'Split',
51
+ 'view debug label': 'Debug',
52
+ 'template select group label': 'Select template',
34
53
  },
35
54
  },
36
55
  },