@dxos/plugin-automation 0.8.4-main.ae835ea → 0.8.4-main.bc2380dfbc

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 (339) hide show
  1. package/LICENSE +102 -5
  2. package/README.md +1 -1
  3. package/dist/lib/neutral/AutomationPanel-T5O4DNQF.mjs +11 -0
  4. package/dist/lib/neutral/AutomationPlugin.mjs +10 -0
  5. package/dist/lib/neutral/AutomationPlugin.node.mjs +1112 -0
  6. package/dist/lib/neutral/AutomationPlugin.node.mjs.map +7 -0
  7. package/dist/lib/neutral/AutomationPlugin.workerd.mjs +23 -0
  8. package/dist/lib/neutral/AutomationPlugin.workerd.mjs.map +7 -0
  9. package/dist/lib/neutral/AutomationSettings-UVS5STCS.mjs +31 -0
  10. package/dist/lib/neutral/AutomationSettings-UVS5STCS.mjs.map +7 -0
  11. package/dist/lib/neutral/FunctionsContainer-CDCM65U4.mjs +38 -0
  12. package/dist/lib/neutral/FunctionsContainer-CDCM65U4.mjs.map +7 -0
  13. package/dist/lib/neutral/FunctionsPanel-SVRKRUXZ.mjs +97 -0
  14. package/dist/lib/neutral/FunctionsPanel-SVRKRUXZ.mjs.map +7 -0
  15. package/dist/lib/neutral/FunctionsRegistry-7ITCFJCW.mjs +95 -0
  16. package/dist/lib/neutral/FunctionsRegistry-7ITCFJCW.mjs.map +7 -0
  17. package/dist/lib/neutral/TriggerSettings-XCHIZPOR.mjs +9 -0
  18. package/dist/lib/neutral/app-graph-builder-GDCGRYEP.mjs +75 -0
  19. package/dist/lib/neutral/app-graph-builder-GDCGRYEP.mjs.map +7 -0
  20. package/dist/lib/neutral/capabilities/index.mjs +15 -0
  21. package/dist/lib/neutral/capabilities/index.mjs.map +7 -0
  22. package/dist/lib/neutral/capabilities/node.mjs +13 -0
  23. package/dist/lib/neutral/capabilities/node.mjs.map +7 -0
  24. package/dist/lib/neutral/chunk-2JP77CMN.mjs +42 -0
  25. package/dist/lib/neutral/chunk-2JP77CMN.mjs.map +7 -0
  26. package/dist/lib/neutral/chunk-2UYFDJO6.mjs +12 -0
  27. package/dist/lib/neutral/chunk-2UYFDJO6.mjs.map +7 -0
  28. package/dist/lib/{browser/chunk-LZQFZO3B.mjs → neutral/chunk-ATECY555.mjs} +7 -4
  29. package/dist/lib/neutral/chunk-ATECY555.mjs.map +7 -0
  30. package/dist/lib/neutral/chunk-CNFKEN7S.mjs +37 -0
  31. package/dist/lib/neutral/chunk-CNFKEN7S.mjs.map +7 -0
  32. package/dist/lib/neutral/chunk-DSCOLDT5.mjs +93 -0
  33. package/dist/lib/neutral/chunk-DSCOLDT5.mjs.map +7 -0
  34. package/dist/lib/neutral/chunk-J5LGTIGS.mjs +10 -0
  35. package/dist/lib/neutral/chunk-JKVVCWSL.mjs +307 -0
  36. package/dist/lib/neutral/chunk-JKVVCWSL.mjs.map +7 -0
  37. package/dist/lib/neutral/chunk-K3C5ZTZA.mjs +285 -0
  38. package/dist/lib/neutral/chunk-K3C5ZTZA.mjs.map +7 -0
  39. package/dist/lib/neutral/chunk-M3TIHFXN.mjs +8 -0
  40. package/dist/lib/neutral/chunk-M3TIHFXN.mjs.map +7 -0
  41. package/dist/lib/neutral/components/index.mjs +16 -0
  42. package/dist/lib/neutral/compute-runtime-D7MPZJ4R.mjs +222 -0
  43. package/dist/lib/neutral/compute-runtime-D7MPZJ4R.mjs.map +7 -0
  44. package/dist/lib/neutral/containers/index.mjs +13 -0
  45. package/dist/lib/neutral/containers/index.mjs.map +7 -0
  46. package/dist/lib/neutral/create-trigger-from-template-7K3OYOHQ.mjs +68 -0
  47. package/dist/lib/neutral/create-trigger-from-template-7K3OYOHQ.mjs.map +7 -0
  48. package/dist/lib/neutral/hooks/index.mjs +129 -0
  49. package/dist/lib/neutral/hooks/index.mjs.map +7 -0
  50. package/dist/lib/neutral/index.mjs +20 -0
  51. package/dist/lib/neutral/meta.json +1 -0
  52. package/dist/lib/neutral/meta.mjs +8 -0
  53. package/dist/lib/neutral/operation-handler-YXGYH5W5.mjs +13 -0
  54. package/dist/lib/neutral/operation-handler-YXGYH5W5.mjs.map +7 -0
  55. package/dist/lib/neutral/operations/index.mjs +8 -0
  56. package/dist/lib/neutral/plugin.mjs +16 -0
  57. package/dist/lib/neutral/plugin.mjs.map +7 -0
  58. package/dist/lib/neutral/react-surface-3OGMAMKV.mjs +57 -0
  59. package/dist/lib/neutral/react-surface-3OGMAMKV.mjs.map +7 -0
  60. package/dist/lib/neutral/testing.mjs +8 -0
  61. package/dist/lib/neutral/testing.mjs.map +7 -0
  62. package/dist/lib/neutral/translations.mjs +47 -0
  63. package/dist/lib/neutral/translations.mjs.map +7 -0
  64. package/dist/lib/neutral/types/index.mjs +16 -0
  65. package/dist/lib/neutral/types/index.mjs.map +7 -0
  66. package/dist/types/src/AutomationPlugin.d.ts +3 -1
  67. package/dist/types/src/AutomationPlugin.d.ts.map +1 -1
  68. package/dist/types/src/AutomationPlugin.node.d.ts +4 -0
  69. package/dist/types/src/AutomationPlugin.node.d.ts.map +1 -0
  70. package/dist/types/src/AutomationPlugin.test.d.ts +2 -0
  71. package/dist/types/src/AutomationPlugin.test.d.ts.map +1 -0
  72. package/dist/types/src/AutomationPlugin.workerd.d.ts +4 -0
  73. package/dist/types/src/AutomationPlugin.workerd.d.ts.map +1 -0
  74. package/dist/types/src/capabilities/app-graph-builder.d.ts +4 -2
  75. package/dist/types/src/capabilities/app-graph-builder.d.ts.map +1 -1
  76. package/dist/types/src/capabilities/compute-runtime.d.ts +12 -3
  77. package/dist/types/src/capabilities/compute-runtime.d.ts.map +1 -1
  78. package/dist/types/src/capabilities/index.d.ts +6 -5
  79. package/dist/types/src/capabilities/index.d.ts.map +1 -1
  80. package/dist/types/src/capabilities/node.d.ts +6 -0
  81. package/dist/types/src/capabilities/node.d.ts.map +1 -0
  82. package/dist/types/src/capabilities/operation-handler.d.ts +6 -0
  83. package/dist/types/src/capabilities/operation-handler.d.ts.map +1 -0
  84. package/dist/types/src/capabilities/react-surface.d.ts +3 -2
  85. package/dist/types/src/capabilities/react-surface.d.ts.map +1 -1
  86. package/dist/types/src/commands/index.d.ts +2 -0
  87. package/dist/types/src/commands/index.d.ts.map +1 -0
  88. package/dist/types/src/commands/trigger/create/index.d.ts +25 -0
  89. package/dist/types/src/commands/trigger/create/index.d.ts.map +1 -0
  90. package/dist/types/src/commands/trigger/create/queue.d.ts +13 -0
  91. package/dist/types/src/commands/trigger/create/queue.d.ts.map +1 -0
  92. package/dist/types/src/commands/trigger/create/subscription.d.ts +15 -0
  93. package/dist/types/src/commands/trigger/create/subscription.d.ts.map +1 -0
  94. package/dist/types/src/commands/trigger/create/timer.d.ts +13 -0
  95. package/dist/types/src/commands/trigger/create/timer.d.ts.map +1 -0
  96. package/dist/types/src/commands/trigger/index.d.ts +57 -0
  97. package/dist/types/src/commands/trigger/index.d.ts.map +1 -0
  98. package/dist/types/src/commands/trigger/list.d.ts +7 -0
  99. package/dist/types/src/commands/trigger/list.d.ts.map +1 -0
  100. package/dist/types/src/commands/trigger/options.d.ts +11 -0
  101. package/dist/types/src/commands/trigger/options.d.ts.map +1 -0
  102. package/dist/types/src/commands/trigger/remove.d.ts +8 -0
  103. package/dist/types/src/commands/trigger/remove.d.ts.map +1 -0
  104. package/dist/types/src/commands/trigger/update/index.d.ts +28 -0
  105. package/dist/types/src/commands/trigger/update/index.d.ts.map +1 -0
  106. package/dist/types/src/commands/trigger/update/queue.d.ts +12 -0
  107. package/dist/types/src/commands/trigger/update/queue.d.ts.map +1 -0
  108. package/dist/types/src/commands/trigger/update/subscription.d.ts +13 -0
  109. package/dist/types/src/commands/trigger/update/subscription.d.ts.map +1 -0
  110. package/dist/types/src/commands/trigger/update/timer.d.ts +11 -0
  111. package/dist/types/src/commands/trigger/update/timer.d.ts.map +1 -0
  112. package/dist/types/src/commands/trigger/util.d.ts +46 -0
  113. package/dist/types/src/commands/trigger/util.d.ts.map +1 -0
  114. package/dist/types/src/components/AutomationPanel/AutomationPanel.d.ts +5 -6
  115. package/dist/types/src/components/AutomationPanel/AutomationPanel.d.ts.map +1 -1
  116. package/dist/types/src/components/AutomationPanel/AutomationPanel.stories.d.ts +32 -28
  117. package/dist/types/src/components/AutomationPanel/AutomationPanel.stories.d.ts.map +1 -1
  118. package/dist/types/src/components/AutomationPanel/index.d.ts.map +1 -1
  119. package/dist/types/src/components/FunctionsPanel/FunctionsPanel.d.ts.map +1 -1
  120. package/dist/types/src/components/FunctionsPanel/index.d.ts.map +1 -1
  121. package/dist/types/src/components/FunctionsRegistry/FunctionsRegistry.d.ts +8 -0
  122. package/dist/types/src/components/FunctionsRegistry/FunctionsRegistry.d.ts.map +1 -0
  123. package/dist/types/src/components/FunctionsRegistry/index.d.ts +4 -0
  124. package/dist/types/src/components/FunctionsRegistry/index.d.ts.map +1 -0
  125. package/dist/types/src/components/TriggerEditor/FunctionInputEditor.d.ts +12 -9
  126. package/dist/types/src/components/TriggerEditor/FunctionInputEditor.d.ts.map +1 -1
  127. package/dist/types/src/components/TriggerEditor/SpecSelector.d.ts +6 -3
  128. package/dist/types/src/components/TriggerEditor/SpecSelector.d.ts.map +1 -1
  129. package/dist/types/src/components/TriggerEditor/TriggerEditor.d.ts +8 -7
  130. package/dist/types/src/components/TriggerEditor/TriggerEditor.d.ts.map +1 -1
  131. package/dist/types/src/components/TriggerEditor/TriggerEditor.stories.d.ts +104 -30
  132. package/dist/types/src/components/TriggerEditor/TriggerEditor.stories.d.ts.map +1 -1
  133. package/dist/types/src/components/index.d.ts +3 -4
  134. package/dist/types/src/components/index.d.ts.map +1 -1
  135. package/dist/types/src/containers/AutomationSettings/AutomationSettings.d.ts +6 -0
  136. package/dist/types/src/containers/AutomationSettings/AutomationSettings.d.ts.map +1 -0
  137. package/dist/types/src/containers/AutomationSettings/index.d.ts +2 -0
  138. package/dist/types/src/containers/AutomationSettings/index.d.ts.map +1 -0
  139. package/dist/types/src/containers/FunctionsContainer/FunctionsContainer.d.ts +4 -0
  140. package/dist/types/src/containers/FunctionsContainer/FunctionsContainer.d.ts.map +1 -0
  141. package/dist/types/src/containers/FunctionsContainer/index.d.ts +2 -0
  142. package/dist/types/src/containers/FunctionsContainer/index.d.ts.map +1 -0
  143. package/dist/types/src/containers/TriggerSettings/TriggerSettings.d.ts.map +1 -0
  144. package/dist/types/src/containers/TriggerSettings/index.d.ts +3 -0
  145. package/dist/types/src/containers/TriggerSettings/index.d.ts.map +1 -0
  146. package/dist/types/src/containers/index.d.ts +5 -0
  147. package/dist/types/src/containers/index.d.ts.map +1 -0
  148. package/dist/types/src/hooks/index.d.ts +2 -0
  149. package/dist/types/src/hooks/index.d.ts.map +1 -1
  150. package/dist/types/src/hooks/useComputeRuntime.d.ts +8 -0
  151. package/dist/types/src/hooks/useComputeRuntime.d.ts.map +1 -0
  152. package/dist/types/src/hooks/useComputeRuntimeCallback.d.ts +5 -4
  153. package/dist/types/src/hooks/useComputeRuntimeCallback.d.ts.map +1 -1
  154. package/dist/types/src/hooks/useComputeRuntimeService.d.ts +17 -0
  155. package/dist/types/src/hooks/useComputeRuntimeService.d.ts.map +1 -0
  156. package/dist/types/src/hooks/useTriggerRuntimeControls.d.ts +5 -4
  157. package/dist/types/src/hooks/useTriggerRuntimeControls.d.ts.map +1 -1
  158. package/dist/types/src/index.d.ts +1 -5
  159. package/dist/types/src/index.d.ts.map +1 -1
  160. package/dist/types/src/meta.d.ts +2 -2
  161. package/dist/types/src/meta.d.ts.map +1 -1
  162. package/dist/types/src/operations/create-trigger-from-template.d.ts +5 -0
  163. package/dist/types/src/operations/create-trigger-from-template.d.ts.map +1 -0
  164. package/dist/types/src/operations/index.d.ts +3 -0
  165. package/dist/types/src/operations/index.d.ts.map +1 -0
  166. package/dist/types/src/plugin.d.ts +4 -0
  167. package/dist/types/src/plugin.d.ts.map +1 -0
  168. package/dist/types/src/testing/test-functions.d.ts +204 -3
  169. package/dist/types/src/testing/test-functions.d.ts.map +1 -1
  170. package/dist/types/src/testing.d.ts +2 -0
  171. package/dist/types/src/testing.d.ts.map +1 -0
  172. package/dist/types/src/translations.d.ts +32 -29
  173. package/dist/types/src/translations.d.ts.map +1 -1
  174. package/dist/types/src/types/AutomationCapabilities.d.ts +22 -0
  175. package/dist/types/src/types/AutomationCapabilities.d.ts.map +1 -0
  176. package/dist/types/src/types/AutomationEvents.d.ts +3 -0
  177. package/dist/types/src/types/AutomationEvents.d.ts.map +1 -0
  178. package/dist/types/src/types/AutomationOperation.d.ts +19 -0
  179. package/dist/types/src/types/AutomationOperation.d.ts.map +1 -0
  180. package/dist/types/src/types/index.d.ts +3 -0
  181. package/dist/types/src/types/index.d.ts.map +1 -1
  182. package/dist/types/src/types/schema.d.ts +11 -3
  183. package/dist/types/src/types/schema.d.ts.map +1 -1
  184. package/dist/types/tsconfig.tsbuildinfo +1 -1
  185. package/package.json +142 -68
  186. package/src/AutomationPlugin.node.ts +29 -0
  187. package/src/AutomationPlugin.test.ts +27 -0
  188. package/src/AutomationPlugin.tsx +20 -37
  189. package/src/AutomationPlugin.workerd.ts +18 -0
  190. package/src/capabilities/app-graph-builder.ts +59 -80
  191. package/src/capabilities/compute-runtime.ts +266 -78
  192. package/src/capabilities/index.ts +9 -7
  193. package/src/capabilities/node.ts +13 -0
  194. package/src/capabilities/operation-handler.ts +16 -0
  195. package/src/capabilities/react-surface.tsx +49 -45
  196. package/src/commands/index.ts +5 -0
  197. package/src/commands/trigger/create/index.ts +14 -0
  198. package/src/commands/trigger/create/queue.ts +86 -0
  199. package/src/commands/trigger/create/subscription.ts +125 -0
  200. package/src/commands/trigger/create/timer.ts +90 -0
  201. package/src/commands/trigger/index.ts +16 -0
  202. package/src/commands/trigger/list.ts +70 -0
  203. package/src/commands/trigger/options.ts +59 -0
  204. package/src/commands/trigger/remove.ts +44 -0
  205. package/src/commands/trigger/update/index.ts +14 -0
  206. package/src/commands/trigger/update/queue.ts +194 -0
  207. package/src/commands/trigger/update/subscription.ts +278 -0
  208. package/src/commands/trigger/update/timer.ts +193 -0
  209. package/src/commands/trigger/util.ts +412 -0
  210. package/src/components/AutomationPanel/AutomationPanel.stories.tsx +14 -7
  211. package/src/components/AutomationPanel/AutomationPanel.tsx +229 -85
  212. package/src/components/FunctionsPanel/FunctionsPanel.tsx +42 -34
  213. package/src/components/FunctionsRegistry/FunctionsRegistry.tsx +119 -0
  214. package/src/components/FunctionsRegistry/index.ts +8 -0
  215. package/src/components/TriggerEditor/FunctionInputEditor.tsx +34 -33
  216. package/src/components/TriggerEditor/SpecSelector.tsx +25 -19
  217. package/src/components/TriggerEditor/TriggerEditor.stories.tsx +90 -38
  218. package/src/components/TriggerEditor/TriggerEditor.tsx +89 -48
  219. package/src/components/index.ts +1 -2
  220. package/src/containers/AutomationSettings/AutomationSettings.tsx +31 -0
  221. package/src/containers/AutomationSettings/index.ts +5 -0
  222. package/src/containers/FunctionsContainer/FunctionsContainer.tsx +33 -0
  223. package/src/containers/FunctionsContainer/index.ts +5 -0
  224. package/src/containers/TriggerSettings/TriggerSettings.tsx +48 -0
  225. package/src/containers/TriggerSettings/index.ts +6 -0
  226. package/src/containers/index.ts +9 -0
  227. package/src/hooks/index.ts +3 -0
  228. package/src/hooks/useComputeRuntime.ts +30 -0
  229. package/src/hooks/useComputeRuntimeCallback.ts +11 -12
  230. package/src/hooks/useComputeRuntimeService.ts +64 -0
  231. package/src/hooks/useTriggerRuntimeControls.ts +32 -14
  232. package/src/index.ts +1 -6
  233. package/src/meta.ts +5 -4
  234. package/src/operations/create-trigger-from-template.ts +71 -0
  235. package/src/operations/index.ts +7 -0
  236. package/src/plugin.ts +11 -0
  237. package/src/testing/test-functions.ts +12 -9
  238. package/src/testing.ts +7 -0
  239. package/src/translations.ts +39 -34
  240. package/src/types/AutomationCapabilities.ts +48 -0
  241. package/src/types/AutomationEvents.ts +11 -0
  242. package/src/types/AutomationOperation.ts +30 -0
  243. package/src/types/index.ts +4 -0
  244. package/src/types/schema.ts +5 -5
  245. package/dist/lib/browser/AutomationPanel-LBXJDM6Z.mjs +0 -11
  246. package/dist/lib/browser/AutomationSettings-IIEI5D2K.mjs +0 -68
  247. package/dist/lib/browser/AutomationSettings-IIEI5D2K.mjs.map +0 -7
  248. package/dist/lib/browser/FunctionsContainer-IZTCGNJZ.mjs +0 -36
  249. package/dist/lib/browser/FunctionsContainer-IZTCGNJZ.mjs.map +0 -7
  250. package/dist/lib/browser/FunctionsPanel-HFCK3JRB.mjs +0 -10
  251. package/dist/lib/browser/app-graph-builder-7VKA2GS3.mjs +0 -81
  252. package/dist/lib/browser/app-graph-builder-7VKA2GS3.mjs.map +0 -7
  253. package/dist/lib/browser/chunk-CVYJM6OO.mjs +0 -66
  254. package/dist/lib/browser/chunk-CVYJM6OO.mjs.map +0 -7
  255. package/dist/lib/browser/chunk-FHSN7G4H.mjs +0 -107
  256. package/dist/lib/browser/chunk-FHSN7G4H.mjs.map +0 -7
  257. package/dist/lib/browser/chunk-GCGHLQM2.mjs +0 -15
  258. package/dist/lib/browser/chunk-GCGHLQM2.mjs.map +0 -7
  259. package/dist/lib/browser/chunk-JW7XSPYW.mjs +0 -267
  260. package/dist/lib/browser/chunk-JW7XSPYW.mjs.map +0 -7
  261. package/dist/lib/browser/chunk-K5YNWESC.mjs +0 -183
  262. package/dist/lib/browser/chunk-K5YNWESC.mjs.map +0 -7
  263. package/dist/lib/browser/chunk-LZQFZO3B.mjs.map +0 -7
  264. package/dist/lib/browser/chunk-XXZNGORC.mjs +0 -14
  265. package/dist/lib/browser/chunk-XXZNGORC.mjs.map +0 -7
  266. package/dist/lib/browser/chunk-YBPJCY3F.mjs +0 -38
  267. package/dist/lib/browser/chunk-YBPJCY3F.mjs.map +0 -7
  268. package/dist/lib/browser/compute-runtime-PFYRMGN2.mjs +0 -114
  269. package/dist/lib/browser/compute-runtime-PFYRMGN2.mjs.map +0 -7
  270. package/dist/lib/browser/hooks/index.mjs +0 -11
  271. package/dist/lib/browser/index.mjs +0 -126
  272. package/dist/lib/browser/index.mjs.map +0 -7
  273. package/dist/lib/browser/intent-resolver-5HR7M7T6.mjs +0 -77
  274. package/dist/lib/browser/intent-resolver-5HR7M7T6.mjs.map +0 -7
  275. package/dist/lib/browser/meta.json +0 -1
  276. package/dist/lib/browser/react-surface-WPMY3EX2.mjs +0 -63
  277. package/dist/lib/browser/react-surface-WPMY3EX2.mjs.map +0 -7
  278. package/dist/lib/browser/types/index.mjs +0 -8
  279. package/dist/lib/node-esm/AutomationPanel-NVEIUIZP.mjs +0 -12
  280. package/dist/lib/node-esm/AutomationSettings-VIIEPI2P.mjs +0 -69
  281. package/dist/lib/node-esm/AutomationSettings-VIIEPI2P.mjs.map +0 -7
  282. package/dist/lib/node-esm/FunctionsContainer-KKRCIXGB.mjs +0 -37
  283. package/dist/lib/node-esm/FunctionsContainer-KKRCIXGB.mjs.map +0 -7
  284. package/dist/lib/node-esm/FunctionsPanel-74ELGR7P.mjs +0 -11
  285. package/dist/lib/node-esm/app-graph-builder-RTOFJNFV.mjs +0 -82
  286. package/dist/lib/node-esm/app-graph-builder-RTOFJNFV.mjs.map +0 -7
  287. package/dist/lib/node-esm/chunk-3BJ6BR3E.mjs +0 -67
  288. package/dist/lib/node-esm/chunk-3BJ6BR3E.mjs.map +0 -7
  289. package/dist/lib/node-esm/chunk-CEVIVRTY.mjs +0 -19
  290. package/dist/lib/node-esm/chunk-CEVIVRTY.mjs.map +0 -7
  291. package/dist/lib/node-esm/chunk-ECJKIUBO.mjs +0 -39
  292. package/dist/lib/node-esm/chunk-ECJKIUBO.mjs.map +0 -7
  293. package/dist/lib/node-esm/chunk-JOCKHLFT.mjs +0 -108
  294. package/dist/lib/node-esm/chunk-JOCKHLFT.mjs.map +0 -7
  295. package/dist/lib/node-esm/chunk-MRYKW5TM.mjs +0 -16
  296. package/dist/lib/node-esm/chunk-MRYKW5TM.mjs.map +0 -7
  297. package/dist/lib/node-esm/chunk-U5Q2NI7H.mjs +0 -16
  298. package/dist/lib/node-esm/chunk-U5Q2NI7H.mjs.map +0 -7
  299. package/dist/lib/node-esm/chunk-W76WUTZY.mjs +0 -268
  300. package/dist/lib/node-esm/chunk-W76WUTZY.mjs.map +0 -7
  301. package/dist/lib/node-esm/chunk-Y7PJXFCJ.mjs +0 -184
  302. package/dist/lib/node-esm/chunk-Y7PJXFCJ.mjs.map +0 -7
  303. package/dist/lib/node-esm/compute-runtime-IXCSD3W7.mjs +0 -115
  304. package/dist/lib/node-esm/compute-runtime-IXCSD3W7.mjs.map +0 -7
  305. package/dist/lib/node-esm/hooks/index.mjs +0 -12
  306. package/dist/lib/node-esm/index.mjs +0 -127
  307. package/dist/lib/node-esm/index.mjs.map +0 -7
  308. package/dist/lib/node-esm/intent-resolver-KDRYB5BC.mjs +0 -78
  309. package/dist/lib/node-esm/intent-resolver-KDRYB5BC.mjs.map +0 -7
  310. package/dist/lib/node-esm/meta.json +0 -1
  311. package/dist/lib/node-esm/react-surface-Y2BBJV2I.mjs +0 -64
  312. package/dist/lib/node-esm/react-surface-Y2BBJV2I.mjs.map +0 -7
  313. package/dist/lib/node-esm/types/index.mjs +0 -9
  314. package/dist/types/src/capabilities/capabilities.d.ts +0 -19
  315. package/dist/types/src/capabilities/capabilities.d.ts.map +0 -1
  316. package/dist/types/src/capabilities/intent-resolver.d.ts +0 -4
  317. package/dist/types/src/capabilities/intent-resolver.d.ts.map +0 -1
  318. package/dist/types/src/components/AutomationSettings.d.ts +0 -5
  319. package/dist/types/src/components/AutomationSettings.d.ts.map +0 -1
  320. package/dist/types/src/components/FunctionsContainer.d.ts +0 -7
  321. package/dist/types/src/components/FunctionsContainer.d.ts.map +0 -1
  322. package/dist/types/src/components/TriggerSettings.d.ts.map +0 -1
  323. package/dist/types/src/events.d.ts +0 -4
  324. package/dist/types/src/events.d.ts.map +0 -1
  325. package/src/capabilities/capabilities.ts +0 -48
  326. package/src/capabilities/intent-resolver.ts +0 -72
  327. package/src/components/AutomationSettings.tsx +0 -30
  328. package/src/components/FunctionsContainer.tsx +0 -29
  329. package/src/components/TriggerSettings.tsx +0 -25
  330. package/src/events.ts +0 -11
  331. /package/dist/lib/{browser/AutomationPanel-LBXJDM6Z.mjs.map → neutral/AutomationPanel-T5O4DNQF.mjs.map} +0 -0
  332. /package/dist/lib/{browser/FunctionsPanel-HFCK3JRB.mjs.map → neutral/AutomationPlugin.mjs.map} +0 -0
  333. /package/dist/lib/{browser/hooks/index.mjs.map → neutral/TriggerSettings-XCHIZPOR.mjs.map} +0 -0
  334. /package/dist/lib/{browser/types/index.mjs.map → neutral/chunk-J5LGTIGS.mjs.map} +0 -0
  335. /package/dist/lib/{node-esm/hooks → neutral/components}/index.mjs.map +0 -0
  336. /package/dist/lib/{node-esm/types → neutral}/index.mjs.map +0 -0
  337. /package/dist/lib/{node-esm/AutomationPanel-NVEIUIZP.mjs.map → neutral/meta.mjs.map} +0 -0
  338. /package/dist/lib/{node-esm/FunctionsPanel-74ELGR7P.mjs.map → neutral/operations/index.mjs.map} +0 -0
  339. /package/dist/types/src/{components → containers/TriggerSettings}/TriggerSettings.d.ts +0 -0
@@ -3,45 +3,67 @@
3
3
  //
4
4
 
5
5
  import * as Array from 'effect/Array';
6
+ import * as Effect from 'effect/Effect';
6
7
  import * as EFn from 'effect/Function';
7
8
  import * as Match from 'effect/Match';
8
9
  import * as Schema from 'effect/Schema';
9
- import React, { useMemo, useState } from 'react';
10
+ import React, { useCallback, useMemo, useState } from 'react';
10
11
 
11
- import { Filter, Obj, Tag } from '@dxos/echo';
12
- import { Function, Script, Trigger } from '@dxos/functions';
13
- import { useTypeOptions } from '@dxos/plugin-space';
12
+ import { useTypeOptions } from '@dxos/app-toolkit/ui';
13
+ import { type ComputeEnvironment } from '@dxos/client-protocol';
14
+ import { Operation, Script, Trigger, TriggerEvent } from '@dxos/compute';
15
+ import { Context } from '@dxos/context';
16
+ import { Filter, Obj, Query, Tag } from '@dxos/echo';
17
+ import { KEY_QUEUE_CURSOR, TriggerDispatcher } from '@dxos/functions-runtime';
18
+ import { FunctionsServiceClient } from '@dxos/functions-runtime/edge';
19
+ import { log } from '@dxos/log';
14
20
  import { type Client, useClient } from '@dxos/react-client';
15
- import { type Space, getSpace, useQuery } from '@dxos/react-client/echo';
16
- import { Clipboard, IconButton, Input, Separator, type ThemedClassName, useTranslation } from '@dxos/react-ui';
17
- import { ControlItem, controlItemClasses } from '@dxos/react-ui-form';
21
+ import { type Space, useObject, useQuery } from '@dxos/react-client/echo';
22
+ import { Clipboard, IconButton, type IconButtonProps, Input, Separator, useTranslation } from '@dxos/react-ui';
23
+ import { Settings } from '@dxos/react-ui-form';
18
24
  import { List } from '@dxos/react-ui-list';
19
- import { ghostHover, mx } from '@dxos/react-ui-theme';
20
- import { DataType } from '@dxos/schema';
25
+ import { Pipeline } from '@dxos/types';
26
+ import { ghostHover, mx } from '@dxos/ui-theme';
27
+ import { isNonNullable } from '@dxos/util';
28
+
29
+ import { useComputeRuntime } from '#hooks';
30
+ import { meta } from '#meta';
21
31
 
22
- import { meta } from '../../meta';
23
32
  import { TriggerEditor, type TriggerEditorProps } from '../TriggerEditor';
24
33
 
25
- const grid = 'grid grid-cols-[40px_1fr_32px] min-bs-[2.5rem]';
34
+ const grid = 'grid grid-cols-[40px_1fr_32px_32px] min-h-[2.5rem]';
26
35
 
27
- export type AutomationPanelProps = ThemedClassName<{
36
+ export type AutomationPanelProps = {
28
37
  space: Space;
29
- object?: Obj.Any;
38
+ object?: Obj.Unknown;
30
39
  initialTrigger?: Trigger.Trigger;
31
40
  onDone?: () => void;
32
- }>;
41
+ };
33
42
 
34
43
  // TODO(burdon): Factor out common layout with ViewEditor.
35
- export const AutomationPanel = ({ classNames, space, object, initialTrigger, onDone }: AutomationPanelProps) => {
44
+ export const AutomationPanel = ({ space, object, initialTrigger, onDone }: AutomationPanelProps) => {
36
45
  const { t } = useTranslation(meta.id);
37
46
  const client = useClient();
38
- const functions = useQuery(space, Filter.type(Function.Function));
39
- const triggers = useQuery(space, Filter.type(Trigger.Trigger));
47
+ const computeRuntime = useComputeRuntime(space.id);
48
+ const [properties] = useObject(space.properties);
49
+ const computeEnvironment = properties.computeEnvironment ?? 'local';
50
+ const functionsServiceClient = useMemo(() => FunctionsServiceClient.fromClient(client), [client]);
51
+ const functions = useQuery(space.db, Filter.type(Operation.PersistentOperation));
52
+ const triggers = useQuery(
53
+ space.db,
54
+ Query.select(Filter.type(Trigger.Trigger)).debugLabel('plugin-automation.AutomationPanel'),
55
+ );
40
56
  const filteredTriggers = useMemo(() => {
41
57
  return object ? triggers.filter(triggerMatch(object)) : triggers;
42
58
  }, [object, triggers]);
43
- const tags = useQuery(space, Filter.type(Tag.Tag));
44
- const types = useTypeOptions({ space, annotation: ['dynamic', 'limited-static', 'object-form'] });
59
+ const tags = useQuery(space.db, Filter.type(Tag.Tag));
60
+ const types = useTypeOptions({
61
+ db: space.db,
62
+ annotation: {
63
+ location: ['database', 'runtime'],
64
+ kind: ['user'],
65
+ },
66
+ });
45
67
 
46
68
  const [trigger, setTrigger] = useState<Trigger.Trigger | undefined>(initialTrigger);
47
69
  const [selected, setSelected] = useState<Trigger.Trigger>();
@@ -64,7 +86,9 @@ export const AutomationPanel = ({ classNames, space, object, initialTrigger, onD
64
86
 
65
87
  const handleSave: TriggerEditorProps['onSave'] = (trigger) => {
66
88
  if (selected) {
67
- Object.assign(selected, trigger);
89
+ Obj.update(selected, (selected) => {
90
+ Object.assign(selected, trigger);
91
+ });
68
92
  } else {
69
93
  space.db.add(Trigger.make(trigger));
70
94
  }
@@ -79,11 +103,52 @@ export const AutomationPanel = ({ classNames, space, object, initialTrigger, onD
79
103
  onDone?.();
80
104
  };
81
105
 
106
+ const handleForceRunTrigger = async (trigger: Trigger.Trigger) => {
107
+ if (computeEnvironment === 'disabled') {
108
+ return;
109
+ }
110
+
111
+ if (computeEnvironment === 'local') {
112
+ if (!computeRuntime) {
113
+ log.warn('force run trigger skipped: compute runtime not available', { spaceId: space.id });
114
+ return;
115
+ }
116
+
117
+ try {
118
+ await computeRuntime.runPromise(
119
+ Effect.gen(function* () {
120
+ const dispatcher = yield* TriggerDispatcher;
121
+ yield* dispatcher.invokeTrigger({
122
+ trigger,
123
+ event: { tick: Date.now() } satisfies TriggerEvent.TimerEvent,
124
+ });
125
+ }),
126
+ );
127
+ } catch (error) {
128
+ log.catch(error);
129
+ }
130
+ return;
131
+ }
132
+
133
+ try {
134
+ await functionsServiceClient.forceRunCronTrigger(Context.default(), space.id, trigger.id);
135
+ } catch (error) {
136
+ log.catch(error);
137
+ }
138
+ };
139
+
140
+ const handleResetCursor = async (trigger: Trigger.Trigger) => {
141
+ Obj.update(trigger, (trigger) => {
142
+ Obj.deleteKeys(trigger, KEY_QUEUE_CURSOR);
143
+ });
144
+ await space.db.flush({ indexes: true });
145
+ };
146
+
82
147
  if (trigger) {
83
148
  return (
84
- <ControlItem title={t('trigger editor title')}>
149
+ <Settings.Item title={t('trigger-editor.title')} description={t('trigger-editor.description')}>
85
150
  <TriggerEditor
86
- space={space}
151
+ db={space.db}
87
152
  trigger={trigger}
88
153
  readonlySpec={Boolean(object)}
89
154
  tags={tags}
@@ -91,87 +156,166 @@ export const AutomationPanel = ({ classNames, space, object, initialTrigger, onD
91
156
  onSave={handleSave}
92
157
  onCancel={handleCancel}
93
158
  />
94
- </ControlItem>
159
+ </Settings.Item>
95
160
  );
96
161
  }
97
162
 
98
163
  return (
99
- <div className={mx(controlItemClasses, classNames)}>
100
- {filteredTriggers.length > 0 && (
101
- <List.Root<Trigger.Trigger>
102
- items={filteredTriggers}
103
- isItem={Schema.is(Trigger.Trigger)}
104
- getId={(field) => field.id}
105
- >
106
- {({ items: filteredTriggers }) => (
107
- <div role='list' className='flex flex-col w-full'>
108
- {filteredTriggers?.map((trigger) => {
109
- const copyAction = getCopyAction(client, trigger);
110
- return (
111
- <List.Item<Trigger.Trigger>
164
+ <Settings.Panel>
165
+ <Clipboard.Provider>
166
+ {filteredTriggers.length > 0 && (
167
+ <List.Root<Trigger.Trigger>
168
+ items={filteredTriggers}
169
+ isItem={Schema.is(Trigger.Trigger)}
170
+ getId={(field) => field.id}
171
+ >
172
+ {({ items: filteredTriggers }) => (
173
+ <div role='list' className='flex flex-col w-full'>
174
+ {filteredTriggers?.map((trigger) => (
175
+ <TriggerListItem
112
176
  key={trigger.id}
113
- item={trigger}
114
- classNames={mx(grid, ghostHover, 'items-center', 'px-2')}
115
- >
116
- <Input.Root>
117
- <Input.Switch
118
- checked={trigger.enabled}
119
- onCheckedChange={(checked) => (trigger.enabled = checked)}
120
- />
121
- </Input.Root>
122
-
123
- <div className={'flex'}>
124
- <List.ItemTitle
125
- classNames='px-1 cursor-pointer w-0 shrink truncate'
126
- onClick={() => handleSelect(trigger)}
127
- >
128
- {getFunctionName(functions, trigger) ?? '∅'}
129
- </List.ItemTitle>
130
-
131
- {/* TODO: a better way to expose copy action */}
132
- {copyAction && (
133
- <Clipboard.IconButton
134
- label={t(copyAction.translationKey)}
135
- value={copyAction.contentProvider()}
136
- />
137
- )}
138
- </div>
139
-
140
- <List.ItemDeleteButton onClick={() => handleDelete(trigger)} />
141
- </List.Item>
142
- );
143
- })}
144
- </div>
145
- )}
146
- </List.Root>
147
- )}
148
- {filteredTriggers.length > 0 && <Separator classNames='mlb-4' />}
149
- <IconButton icon='ph--plus--regular' label={t('new trigger label')} onClick={handleAdd} />
150
- </div>
177
+ trigger={trigger}
178
+ functions={functions}
179
+ computeEnvironment={computeEnvironment}
180
+ onSelect={handleSelect}
181
+ onDelete={handleDelete}
182
+ onResetCursor={handleResetCursor}
183
+ onForceRun={handleForceRunTrigger}
184
+ />
185
+ ))}
186
+ </div>
187
+ )}
188
+ </List.Root>
189
+ )}
190
+
191
+ {filteredTriggers.length > 0 && <Separator classNames='my-4' />}
192
+ <IconButton icon='ph--plus--regular' label={t('new-trigger.label')} onClick={handleAdd} />
193
+ </Clipboard.Provider>
194
+ </Settings.Panel>
195
+ );
196
+ };
197
+
198
+ const TriggerListItem = ({
199
+ trigger,
200
+ functions,
201
+ computeEnvironment,
202
+ onSelect,
203
+ onDelete,
204
+ onResetCursor,
205
+ onForceRun,
206
+ }: {
207
+ trigger: Trigger.Trigger;
208
+ functions: Operation.PersistentOperation[];
209
+ computeEnvironment: ComputeEnvironment;
210
+ onSelect?: (trigger: Trigger.Trigger) => void;
211
+ onDelete?: (trigger: Trigger.Trigger) => void;
212
+ onResetCursor?: (trigger: Trigger.Trigger) => void;
213
+ onForceRun?: (trigger: Trigger.Trigger) => void;
214
+ }) => {
215
+ const client = useClient();
216
+ const copyAction = getCopyAction(client, trigger);
217
+ const { t } = useTranslation(meta.id);
218
+ const cursor = Obj.getKeys(trigger, KEY_QUEUE_CURSOR).at(0)?.id;
219
+ const [snapshot, updateTrigger] = useObject(trigger);
220
+
221
+ const enabled = snapshot.enabled ?? false;
222
+ const onEnabledChange = (checked: boolean) => {
223
+ updateTrigger((trigger) => {
224
+ trigger.enabled = checked;
225
+ });
226
+ };
227
+
228
+ const handleSelect = useCallback(() => {
229
+ onSelect?.(trigger);
230
+ }, [onSelect, trigger]);
231
+
232
+ const handleDelete = useCallback(() => {
233
+ onDelete?.(trigger);
234
+ }, [onDelete, trigger]);
235
+
236
+ const handleResetCursor = useCallback(() => {
237
+ onResetCursor?.(trigger);
238
+ }, [onResetCursor, trigger]);
239
+
240
+ const handleForceRun = useCallback(() => {
241
+ onForceRun?.(trigger);
242
+ }, [onForceRun, trigger]);
243
+
244
+ const actionProps = useMemo<IconButtonProps | undefined>(() => {
245
+ if (trigger.spec?.kind === 'timer' && onForceRun) {
246
+ return {
247
+ disabled: !enabled || computeEnvironment === 'disabled',
248
+ icon: 'ph--play--regular',
249
+ label: 'Force run',
250
+ onClick: handleForceRun,
251
+ };
252
+ }
253
+
254
+ if (trigger.spec?.kind === 'queue' && onResetCursor) {
255
+ return {
256
+ disabled: !cursor,
257
+ icon: 'ph--arrow-clockwise--regular',
258
+ label: 'Reset cursor',
259
+ onClick: handleResetCursor,
260
+ };
261
+ }
262
+ }, [computeEnvironment, enabled, trigger.spec?.kind, handleForceRun, onResetCursor]);
263
+
264
+ return (
265
+ <List.Item<Obj.Snapshot<Trigger.Trigger>>
266
+ key={trigger.id}
267
+ item={snapshot}
268
+ classNames={mx(grid, ghostHover, 'items-center', 'px-2')}
269
+ >
270
+ <Input.Root>
271
+ <Input.Switch checked={enabled} onCheckedChange={onEnabledChange} />
272
+ </Input.Root>
273
+
274
+ <div className={'flex'}>
275
+ <List.ItemTitle classNames='px-1 cursor-pointer w-0 shrink truncate' onClick={handleSelect}>
276
+ {getFunctionName(functions, trigger) ?? '∅'}
277
+ {cursor && <div className='text-xs text-description truncate ml-4'>Position: {cursor}</div>}
278
+ </List.ItemTitle>
279
+
280
+ {copyAction && (
281
+ <Clipboard.IconButton label={t(copyAction.translationKey)} value={copyAction.contentProvider()} />
282
+ )}
283
+ </div>
284
+
285
+ {actionProps ? <List.ItemIconButton {...actionProps} autoHide={false} /> : <div />}
286
+
287
+ {onDelete && <List.ItemDeleteButton onClick={handleDelete} />}
288
+ </List.Item>
151
289
  );
152
290
  };
153
291
 
154
292
  const getCopyAction = (client: Client, trigger: Trigger.Trigger | undefined) => {
155
293
  if (trigger?.spec?.kind === 'email') {
156
- return { translationKey: 'trigger copy email', contentProvider: () => `${getSpace(trigger)!.id}@dxos.network` };
294
+ return {
295
+ translationKey: 'trigger copy email' as const,
296
+ contentProvider: () => `${Obj.getDatabase(trigger)!.spaceId}@dxos.network`,
297
+ };
157
298
  }
158
299
 
159
300
  if (trigger?.spec?.kind === 'webhook') {
160
- return { translationKey: 'trigger copy url', contentProvider: () => getWebhookUrl(client, trigger) };
301
+ return {
302
+ translationKey: 'trigger copy url' as const,
303
+ contentProvider: () => getWebhookUrl(client, trigger!),
304
+ };
161
305
  }
162
306
 
163
307
  return undefined;
164
308
  };
165
309
 
166
310
  const getWebhookUrl = (client: Client, trigger: Trigger.Trigger) => {
167
- const spaceId = getSpace(trigger)!.id;
311
+ const spaceId = Obj.getDatabase(trigger)!.spaceId;
168
312
  const edgeUrl = new URL(client.config.values.runtime!.services!.edge!.url!);
169
313
  const isSecure = edgeUrl.protocol.startsWith('https') || edgeUrl.protocol.startsWith('wss');
170
314
  edgeUrl.protocol = isSecure ? 'https' : 'http';
171
315
  return new URL(`/webhook/${spaceId}:${trigger.id}`, edgeUrl).toString();
172
316
  };
173
317
 
174
- const getFunctionName = (functions: Function.Function[], trigger: Trigger.Trigger) => {
318
+ const getFunctionName = (functions: Operation.PersistentOperation[], trigger: Trigger.Trigger) => {
175
319
  // TODO(wittjosiah): Truncation should be done in the UI.
176
320
  // Warning that the List component is currently a can of worms.
177
321
  const shortId = trigger.function && `${trigger.function.dxn.toString().slice(0, 16)}…`;
@@ -181,18 +325,18 @@ const getFunctionName = (functions: Function.Function[], trigger: Trigger.Trigge
181
325
 
182
326
  const scriptMatch = (script: Script.Script) => (trigger: Trigger.Trigger) => {
183
327
  const fn = trigger.function?.target;
184
- if (!Obj.instanceOf(Function.Function, fn)) {
328
+ if (!Obj.instanceOf(Operation.PersistentOperation, fn)) {
185
329
  return false;
186
330
  }
187
331
 
188
332
  return fn.source?.target === script;
189
333
  };
190
334
 
191
- const projectMatch = (project: DataType.Project) => {
335
+ const projectMatch = (project: Pipeline.Pipeline) => {
192
336
  const viewQueries = EFn.pipe(
193
- project.collections,
194
- Array.map((collection) => collection.target),
195
- Array.filter(Schema.is(DataType.View)),
337
+ project.columns,
338
+ Array.map((column) => column.view.target),
339
+ Array.filter(isNonNullable),
196
340
  Array.map((view) => Obj.getSnapshot(view).query.ast),
197
341
  Array.map((ast) => JSON.stringify(ast)),
198
342
  );
@@ -208,14 +352,14 @@ const projectMatch = (project: DataType.Project) => {
208
352
  };
209
353
  };
210
354
 
211
- const triggerMatch = Match.type<Obj.Any>().pipe(
355
+ const triggerMatch = Match.type<Obj.Unknown>().pipe(
212
356
  Match.withReturnType<(trigger: Trigger.Trigger) => boolean>(),
213
357
  Match.when(
214
358
  (obj) => Obj.instanceOf(Script.Script, obj),
215
359
  (obj) => scriptMatch(obj),
216
360
  ),
217
361
  Match.when(
218
- (obj) => Obj.instanceOf(DataType.Project, obj),
362
+ (obj) => Obj.instanceOf(Pipeline.Pipeline, obj),
219
363
  (obj) => projectMatch(obj),
220
364
  ),
221
365
  Match.orElse((_obj) => () => true),
@@ -5,18 +5,18 @@
5
5
  import * as Schema from 'effect/Schema';
6
6
  import React, { useCallback, useMemo } from 'react';
7
7
 
8
- import { LayoutAction, createIntent, useIntentDispatcher } from '@dxos/app-framework';
9
- import { Function, Script } from '@dxos/functions';
10
- import { SpaceAction } from '@dxos/plugin-space/types';
11
- import { Filter, type Space, fullyQualifiedId, useQuery } from '@dxos/react-client/echo';
12
- import { Button, IconButton, useTranslation } from '@dxos/react-ui';
13
- import { controlItemClasses } from '@dxos/react-ui-form';
8
+ import { useOperationInvoker } from '@dxos/app-framework/ui';
9
+ import { LayoutOperation, getObjectPathFromObject } from '@dxos/app-toolkit';
10
+ import { Operation, Script } from '@dxos/compute';
11
+ import { Filter } from '@dxos/echo';
12
+ import { SpaceOperation } from '@dxos/plugin-space';
13
+ import { type Space, useQuery } from '@dxos/react-client/echo';
14
+ import { IconButton, useTranslation } from '@dxos/react-ui';
15
+ import { Settings } from '@dxos/react-ui-form';
14
16
  import { List } from '@dxos/react-ui-list';
15
- import { ghostHover, mx } from '@dxos/react-ui-theme';
17
+ import { ghostHover, mx } from '@dxos/ui-theme';
16
18
 
17
- import { meta } from '../../meta';
18
-
19
- const grid = 'grid grid-cols-[1fr_auto] min-bs-[2.5rem]';
19
+ import { meta } from '#meta';
20
20
 
21
21
  export type FunctionsPanelProps = {
22
22
  space: Space;
@@ -24,9 +24,9 @@ export type FunctionsPanelProps = {
24
24
 
25
25
  export const FunctionsPanel = ({ space }: FunctionsPanelProps) => {
26
26
  const { t } = useTranslation(meta.id);
27
- const functions = useQuery(space, Filter.type(Function.Function));
28
- const scripts = useQuery(space, Filter.type(Script.Script));
29
- const { dispatchPromise: dispatch } = useIntentDispatcher();
27
+ const functions = useQuery(space.db, Filter.type(Operation.PersistentOperation));
28
+ const scripts = useQuery(space.db, Filter.type(Script.Script));
29
+ const { invokePromise } = useOperationInvoker();
30
30
 
31
31
  const functionToScriptMap = useMemo(
32
32
  () =>
@@ -47,7 +47,7 @@ export const FunctionsPanel = ({ space }: FunctionsPanelProps) => {
47
47
  );
48
48
 
49
49
  const getScriptName = useCallback(
50
- (func: Function.Function) => {
50
+ (func: Operation.PersistentOperation) => {
51
51
  const script = functionToScriptMap[func.id];
52
52
  return script?.name;
53
53
  },
@@ -55,45 +55,55 @@ export const FunctionsPanel = ({ space }: FunctionsPanelProps) => {
55
55
  );
56
56
 
57
57
  const handleGoToScript = useCallback(
58
- (func: Function.Function) => {
58
+ (func: Operation.PersistentOperation) => {
59
59
  const script = functionToScriptMap[func.id];
60
60
  if (script) {
61
- void dispatch(createIntent(LayoutAction.Open, { part: 'main', subject: [fullyQualifiedId(script)] }));
61
+ void invokePromise(LayoutOperation.Open, { subject: [getObjectPathFromObject(script)] });
62
62
  }
63
63
  },
64
- [functionToScriptMap, dispatch],
64
+ [functionToScriptMap, invokePromise],
65
65
  );
66
66
 
67
67
  const handleDelete = useCallback(
68
- (func: Function.Function) => dispatch(createIntent(SpaceAction.RemoveObjects, { objects: [func] })),
69
- [dispatch],
68
+ (func: Operation.PersistentOperation) => invokePromise(SpaceOperation.RemoveObjects, { objects: [func] }),
69
+ [invokePromise],
70
70
  );
71
71
 
72
72
  return (
73
- <div role='none' className={mx(controlItemClasses)}>
73
+ <Settings.Panel>
74
74
  {functions.length > 0 && (
75
- <List.Root<Function.Function> items={functions} isItem={Schema.is(Function.Function)} getId={(func) => func.id}>
75
+ <List.Root<Operation.PersistentOperation>
76
+ items={functions}
77
+ isItem={Schema.is(Operation.PersistentOperation)}
78
+ getId={(func) => func.id}
79
+ >
76
80
  {({ items }) => (
77
81
  <div role='list' className='flex flex-col w-full'>
78
82
  {items?.map((func) => (
79
- <List.Item<Function.Function>
83
+ <List.Item<Operation.PersistentOperation>
80
84
  key={func.id}
81
85
  item={func}
82
- classNames={mx(grid, ghostHover, 'items-center', 'pli-2', 'min-bs-[3rem]')}
86
+ classNames={mx(
87
+ 'grid grid-cols-[1fr_min-content_auto] min-h-[2.5rem] min-h-[3rem] px-2 items-center',
88
+ ghostHover,
89
+ )}
83
90
  >
84
91
  <div className='flex flex-col truncate'>
85
92
  <List.ItemTitle classNames='truncate'>{func.name}</List.ItemTitle>
86
- {getScriptName(func) && (
87
- <div className='text-xs text-description truncate'>{getScriptName(func)}</div>
88
- )}
93
+ {getScriptName(func) && <p className='text-xs text-description truncate'>{getScriptName(func)}</p>}
89
94
  </div>
90
- {functionToScriptMap[func.id] && (
91
- <Button onClick={() => handleGoToScript(func)}>{t('go to function source button label')}</Button>
92
- )}
95
+ {(functionToScriptMap[func.id] && (
96
+ <IconButton
97
+ icon='ph--arrow-square-out--regular'
98
+ iconOnly
99
+ label={t('show-source-button.label')}
100
+ onClick={() => handleGoToScript(func)}
101
+ />
102
+ )) || <div />}
93
103
  <IconButton
94
- iconOnly
95
104
  icon='ph--trash--regular'
96
- label={t('delete function button label')}
105
+ iconOnly
106
+ label={t('delete-function-button.label')}
97
107
  onClick={() => handleDelete(func)}
98
108
  />
99
109
  </List.Item>
@@ -102,8 +112,6 @@ export const FunctionsPanel = ({ space }: FunctionsPanelProps) => {
102
112
  )}
103
113
  </List.Root>
104
114
  )}
105
-
106
- {functions.length === 0 && <div className='text-center plb-4 text-gray-500'>{t('no functions found')}</div>}
107
- </div>
115
+ </Settings.Panel>
108
116
  );
109
117
  };
@@ -0,0 +1,119 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import * as Schema from 'effect/Schema';
6
+ import { useState } from 'react';
7
+ import React, { useCallback } from 'react';
8
+
9
+ import * as OperationModule from '@dxos/compute';
10
+ import { Context } from '@dxos/context';
11
+ import { Filter, Obj } from '@dxos/echo';
12
+ import { getDeployedFunctions } from '@dxos/functions-runtime/edge';
13
+ import { useClient } from '@dxos/react-client';
14
+ import { type Space, useQuery } from '@dxos/react-client/echo';
15
+ import { IconButton, useAsyncEffect, useTranslation } from '@dxos/react-ui';
16
+ import { Settings } from '@dxos/react-ui-form';
17
+ import { List } from '@dxos/react-ui-list';
18
+ import { ghostHover, mx } from '@dxos/ui-theme';
19
+
20
+ import { meta } from '#meta';
21
+
22
+ const grid = 'grid grid-cols-[1fr_1fr_auto] min-h-[2.5rem]';
23
+
24
+ type FunctionsRegistryProps = {
25
+ space: Space;
26
+ };
27
+
28
+ export const FunctionsRegistry = ({ space }: FunctionsRegistryProps) => {
29
+ const client = useClient();
30
+ const [loading, setLoading] = useState(true);
31
+ const [functions, setFunctions] = useState<OperationModule.Operation.PersistentOperation[]>([]);
32
+ const { t } = useTranslation(meta.id);
33
+
34
+ const dbFunctions = useQuery(space.db, Filter.type(OperationModule.Operation.PersistentOperation));
35
+
36
+ const state = (func: OperationModule.Operation.PersistentOperation) => {
37
+ const funcKey = Obj.getMeta(func).key;
38
+ const dbFunction = dbFunctions.find((f) => Obj.getMeta(f).key === funcKey);
39
+ if (!dbFunction) {
40
+ return 'import';
41
+ }
42
+ if (Obj.getMeta(dbFunction).version === Obj.getMeta(func).version && dbFunction.updated === func.updated) {
43
+ return 'none';
44
+ }
45
+ return 'update';
46
+ };
47
+
48
+ useAsyncEffect(async () => {
49
+ setLoading(true);
50
+ const functions = await getDeployedFunctions(Context.default(), client, true);
51
+ setFunctions(functions);
52
+ setLoading(false);
53
+ }, []);
54
+
55
+ const hanleImportOrUpdate = useCallback(
56
+ async (func: OperationModule.Operation.PersistentOperation) => {
57
+ const funcKey = Obj.getMeta(func).key;
58
+ const functions = funcKey
59
+ ? await space.db
60
+ .query(Filter.and(Filter.type(OperationModule.Operation.PersistentOperation), Filter.key(funcKey)))
61
+ .run()
62
+ : [];
63
+ const [existingFunc] = functions;
64
+ if (!existingFunc) {
65
+ space.db.add(func);
66
+ return;
67
+ }
68
+ OperationModule.Operation.setFrom(existingFunc, func);
69
+ },
70
+ [space],
71
+ );
72
+
73
+ return (
74
+ <Settings.Panel>
75
+ {functions.length > 0 && (
76
+ <List.Root<OperationModule.Operation.PersistentOperation>
77
+ items={functions}
78
+ isItem={Schema.is(OperationModule.Operation.PersistentOperation)}
79
+ getId={(func) => func.id}
80
+ >
81
+ {({ items }) => (
82
+ <div role='list' className='flex flex-col w-full'>
83
+ {items?.map((func) => (
84
+ <List.Item<OperationModule.Operation.PersistentOperation>
85
+ key={func.id}
86
+ item={func}
87
+ classNames={mx(grid, ghostHover, 'items-center', 'px-2', 'min-h-[3rem]')}
88
+ >
89
+ <div className='flex flex-col truncate'>
90
+ <List.ItemTitle classNames='truncate'>{func.name}</List.ItemTitle>
91
+ <div className='text-xs text-description truncate'>{Obj.getMeta(func).key}</div>
92
+ </div>
93
+ <div className='flex flex-col truncate'>
94
+ <div className='text-xs text-description truncate'>{Obj.getMeta(func).version}</div>
95
+ <div className='text-xs text-description truncate'>
96
+ {func.updated ? `Uploaded ${new Date(func.updated).toLocaleString()}` : ''}
97
+ </div>
98
+ </div>
99
+
100
+ <IconButton
101
+ iconOnly
102
+ icon={state(func) === 'update' ? 'ph--arrows-clockwise--regular' : 'ph--download--regular'}
103
+ label={
104
+ state(func) === 'update' ? t('update-function-button.label') : t('import-function-button.label')
105
+ }
106
+ disabled={state(func) === 'none'}
107
+ onClick={() => hanleImportOrUpdate(func)}
108
+ />
109
+ </List.Item>
110
+ ))}
111
+ </div>
112
+ )}
113
+ </List.Root>
114
+ )}
115
+
116
+ {loading && <div className='text-center py-4 text-gray-500'>{t('loading-functions.message')}</div>}
117
+ </Settings.Panel>
118
+ );
119
+ };