@dxos/plugin-automation 0.8.4-main.72ec0f3 → 0.8.4-main.74a063c4e0

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 (282) hide show
  1. package/dist/lib/browser/chunk-J5LGTIGS.mjs +10 -0
  2. package/dist/lib/browser/chunk-POEIL4RN.mjs +44 -0
  3. package/dist/lib/browser/chunk-POEIL4RN.mjs.map +7 -0
  4. package/dist/lib/browser/chunk-WQLEMRPU.mjs +54 -0
  5. package/dist/lib/browser/chunk-WQLEMRPU.mjs.map +7 -0
  6. package/dist/lib/browser/cli/index.mjs +1122 -0
  7. package/dist/lib/browser/cli/index.mjs.map +7 -0
  8. package/dist/lib/browser/create-trigger-from-template-JPF5BFMX.mjs +77 -0
  9. package/dist/lib/browser/create-trigger-from-template-JPF5BFMX.mjs.map +7 -0
  10. package/dist/lib/browser/hooks/index.mjs +79 -7
  11. package/dist/lib/browser/hooks/index.mjs.map +4 -4
  12. package/dist/lib/browser/index.mjs +72 -112
  13. package/dist/lib/browser/index.mjs.map +4 -4
  14. package/dist/lib/browser/meta.json +1 -1
  15. package/dist/lib/browser/operations/index.mjs +14 -0
  16. package/dist/lib/browser/operations/index.mjs.map +7 -0
  17. package/dist/lib/browser/types/index.mjs +10 -4
  18. package/dist/lib/node-esm/chunk-HSLMI22Q.mjs +11 -0
  19. package/dist/lib/node-esm/{chunk-ECJKIUBO.mjs → chunk-JWZAVQLF.mjs} +24 -7
  20. package/dist/lib/node-esm/chunk-JWZAVQLF.mjs.map +7 -0
  21. package/dist/lib/node-esm/chunk-SP3P4OUI.mjs +45 -0
  22. package/dist/lib/node-esm/chunk-SP3P4OUI.mjs.map +7 -0
  23. package/dist/lib/node-esm/cli/index.mjs +1123 -0
  24. package/dist/lib/node-esm/cli/index.mjs.map +7 -0
  25. package/dist/lib/node-esm/create-trigger-from-template-FT75A4SF.mjs +78 -0
  26. package/dist/lib/node-esm/create-trigger-from-template-FT75A4SF.mjs.map +7 -0
  27. package/dist/lib/node-esm/hooks/index.mjs +79 -7
  28. package/dist/lib/node-esm/hooks/index.mjs.map +4 -4
  29. package/dist/lib/node-esm/index.mjs +72 -112
  30. package/dist/lib/node-esm/index.mjs.map +4 -4
  31. package/dist/lib/node-esm/meta.json +1 -1
  32. package/dist/lib/node-esm/operations/index.mjs +15 -0
  33. package/dist/lib/node-esm/operations/index.mjs.map +7 -0
  34. package/dist/lib/node-esm/types/index.mjs +10 -4
  35. package/dist/types/src/AutomationPlugin.d.ts +2 -1
  36. package/dist/types/src/AutomationPlugin.d.ts.map +1 -1
  37. package/dist/types/src/capabilities/app-graph-builder.d.ts +4 -2
  38. package/dist/types/src/capabilities/app-graph-builder.d.ts.map +1 -1
  39. package/dist/types/src/capabilities/compute-runtime.d.ts +4 -3
  40. package/dist/types/src/capabilities/compute-runtime.d.ts.map +1 -1
  41. package/dist/types/src/capabilities/index.d.ts +6 -5
  42. package/dist/types/src/capabilities/index.d.ts.map +1 -1
  43. package/dist/types/src/capabilities/node.d.ts +3 -0
  44. package/dist/types/src/capabilities/node.d.ts.map +1 -0
  45. package/dist/types/src/capabilities/operation-handler.d.ts +6 -0
  46. package/dist/types/src/capabilities/operation-handler.d.ts.map +1 -0
  47. package/dist/types/src/capabilities/react-surface.d.ts +3 -2
  48. package/dist/types/src/capabilities/react-surface.d.ts.map +1 -1
  49. package/dist/types/src/cli/commands/index.d.ts +2 -0
  50. package/dist/types/src/cli/commands/index.d.ts.map +1 -0
  51. package/dist/types/src/cli/commands/trigger/create/index.d.ts +25 -0
  52. package/dist/types/src/cli/commands/trigger/create/index.d.ts.map +1 -0
  53. package/dist/types/src/cli/commands/trigger/create/queue.d.ts +13 -0
  54. package/dist/types/src/cli/commands/trigger/create/queue.d.ts.map +1 -0
  55. package/dist/types/src/cli/commands/trigger/create/subscription.d.ts +15 -0
  56. package/dist/types/src/cli/commands/trigger/create/subscription.d.ts.map +1 -0
  57. package/dist/types/src/cli/commands/trigger/create/timer.d.ts +13 -0
  58. package/dist/types/src/cli/commands/trigger/create/timer.d.ts.map +1 -0
  59. package/dist/types/src/cli/commands/trigger/index.d.ts +57 -0
  60. package/dist/types/src/cli/commands/trigger/index.d.ts.map +1 -0
  61. package/dist/types/src/cli/commands/trigger/list.d.ts +7 -0
  62. package/dist/types/src/cli/commands/trigger/list.d.ts.map +1 -0
  63. package/dist/types/src/cli/commands/trigger/options.d.ts +11 -0
  64. package/dist/types/src/cli/commands/trigger/options.d.ts.map +1 -0
  65. package/dist/types/src/cli/commands/trigger/remove.d.ts +8 -0
  66. package/dist/types/src/cli/commands/trigger/remove.d.ts.map +1 -0
  67. package/dist/types/src/cli/commands/trigger/update/index.d.ts +28 -0
  68. package/dist/types/src/cli/commands/trigger/update/index.d.ts.map +1 -0
  69. package/dist/types/src/cli/commands/trigger/update/queue.d.ts +12 -0
  70. package/dist/types/src/cli/commands/trigger/update/queue.d.ts.map +1 -0
  71. package/dist/types/src/cli/commands/trigger/update/subscription.d.ts +13 -0
  72. package/dist/types/src/cli/commands/trigger/update/subscription.d.ts.map +1 -0
  73. package/dist/types/src/cli/commands/trigger/update/timer.d.ts +11 -0
  74. package/dist/types/src/cli/commands/trigger/update/timer.d.ts.map +1 -0
  75. package/dist/types/src/cli/commands/trigger/util.d.ts +46 -0
  76. package/dist/types/src/cli/commands/trigger/util.d.ts.map +1 -0
  77. package/dist/types/src/cli/index.d.ts +2 -0
  78. package/dist/types/src/cli/index.d.ts.map +1 -0
  79. package/dist/types/src/cli/plugin.d.ts +3 -0
  80. package/dist/types/src/cli/plugin.d.ts.map +1 -0
  81. package/dist/types/src/components/AutomationPanel/AutomationPanel.d.ts +4 -5
  82. package/dist/types/src/components/AutomationPanel/AutomationPanel.d.ts.map +1 -1
  83. package/dist/types/src/components/AutomationPanel/AutomationPanel.stories.d.ts +28 -29
  84. package/dist/types/src/components/AutomationPanel/AutomationPanel.stories.d.ts.map +1 -1
  85. package/dist/types/src/components/FunctionsPanel/FunctionsPanel.d.ts.map +1 -1
  86. package/dist/types/src/components/FunctionsRegistry/FunctionsRegistry.d.ts.map +1 -1
  87. package/dist/types/src/components/FunctionsRegistry/index.d.ts +3 -1
  88. package/dist/types/src/components/FunctionsRegistry/index.d.ts.map +1 -1
  89. package/dist/types/src/components/TriggerEditor/FunctionInputEditor.d.ts +12 -9
  90. package/dist/types/src/components/TriggerEditor/FunctionInputEditor.d.ts.map +1 -1
  91. package/dist/types/src/components/TriggerEditor/SpecSelector.d.ts +6 -3
  92. package/dist/types/src/components/TriggerEditor/SpecSelector.d.ts.map +1 -1
  93. package/dist/types/src/components/TriggerEditor/TriggerEditor.d.ts +7 -6
  94. package/dist/types/src/components/TriggerEditor/TriggerEditor.d.ts.map +1 -1
  95. package/dist/types/src/components/TriggerEditor/TriggerEditor.stories.d.ts +98 -31
  96. package/dist/types/src/components/TriggerEditor/TriggerEditor.stories.d.ts.map +1 -1
  97. package/dist/types/src/components/index.d.ts +3 -4
  98. package/dist/types/src/components/index.d.ts.map +1 -1
  99. package/dist/types/src/containers/AutomationSettings/AutomationSettings.d.ts +4 -0
  100. package/dist/types/src/containers/AutomationSettings/AutomationSettings.d.ts.map +1 -0
  101. package/dist/types/src/containers/AutomationSettings/index.d.ts +2 -0
  102. package/dist/types/src/containers/AutomationSettings/index.d.ts.map +1 -0
  103. package/dist/types/src/{components → containers/FunctionsContainer}/FunctionsContainer.d.ts +0 -1
  104. package/dist/types/src/containers/FunctionsContainer/FunctionsContainer.d.ts.map +1 -0
  105. package/dist/types/src/containers/FunctionsContainer/index.d.ts +2 -0
  106. package/dist/types/src/containers/FunctionsContainer/index.d.ts.map +1 -0
  107. package/dist/types/src/containers/TriggerSettings/TriggerSettings.d.ts +6 -0
  108. package/dist/types/src/containers/TriggerSettings/TriggerSettings.d.ts.map +1 -0
  109. package/dist/types/src/containers/TriggerSettings/index.d.ts +3 -0
  110. package/dist/types/src/containers/TriggerSettings/index.d.ts.map +1 -0
  111. package/dist/types/src/containers/index.d.ts +5 -0
  112. package/dist/types/src/containers/index.d.ts.map +1 -0
  113. package/dist/types/src/hooks/index.d.ts +2 -0
  114. package/dist/types/src/hooks/index.d.ts.map +1 -1
  115. package/dist/types/src/hooks/useComputeRuntime.d.ts +7 -0
  116. package/dist/types/src/hooks/useComputeRuntime.d.ts.map +1 -0
  117. package/dist/types/src/hooks/useComputeRuntimeCallback.d.ts +4 -7
  118. package/dist/types/src/hooks/useComputeRuntimeCallback.d.ts.map +1 -1
  119. package/dist/types/src/hooks/useComputeRuntimeService.d.ts +5 -0
  120. package/dist/types/src/hooks/useComputeRuntimeService.d.ts.map +1 -0
  121. package/dist/types/src/hooks/useTriggerRuntimeControls.d.ts +4 -3
  122. package/dist/types/src/hooks/useTriggerRuntimeControls.d.ts.map +1 -1
  123. package/dist/types/src/index.d.ts +2 -6
  124. package/dist/types/src/index.d.ts.map +1 -1
  125. package/dist/types/src/meta.d.ts +2 -2
  126. package/dist/types/src/meta.d.ts.map +1 -1
  127. package/dist/types/src/operations/create-trigger-from-template.d.ts +5 -0
  128. package/dist/types/src/operations/create-trigger-from-template.d.ts.map +1 -0
  129. package/dist/types/src/operations/definitions.d.ts +19 -0
  130. package/dist/types/src/operations/definitions.d.ts.map +1 -0
  131. package/dist/types/src/operations/index.d.ts +4 -0
  132. package/dist/types/src/operations/index.d.ts.map +1 -0
  133. package/dist/types/src/testing/test-functions.d.ts +204 -3
  134. package/dist/types/src/testing/test-functions.d.ts.map +1 -1
  135. package/dist/types/src/translations.d.ts +29 -30
  136. package/dist/types/src/translations.d.ts.map +1 -1
  137. package/dist/types/src/types/capabilities.d.ts +25 -0
  138. package/dist/types/src/types/capabilities.d.ts.map +1 -0
  139. package/dist/types/src/types/events.d.ts +5 -0
  140. package/dist/types/src/types/events.d.ts.map +1 -0
  141. package/dist/types/src/types/index.d.ts +2 -0
  142. package/dist/types/src/types/index.d.ts.map +1 -1
  143. package/dist/types/src/types/schema.d.ts +11 -3
  144. package/dist/types/src/types/schema.d.ts.map +1 -1
  145. package/dist/types/tsconfig.tsbuildinfo +1 -1
  146. package/package.json +89 -50
  147. package/src/AutomationPlugin.tsx +18 -35
  148. package/src/capabilities/app-graph-builder.ts +54 -79
  149. package/src/capabilities/compute-runtime.ts +172 -53
  150. package/src/capabilities/index.ts +9 -7
  151. package/src/capabilities/node.ts +7 -0
  152. package/src/capabilities/operation-handler.ts +16 -0
  153. package/src/capabilities/react-surface.tsx +49 -46
  154. package/src/cli/commands/index.ts +5 -0
  155. package/src/cli/commands/trigger/create/index.ts +14 -0
  156. package/src/cli/commands/trigger/create/queue.ts +90 -0
  157. package/src/cli/commands/trigger/create/subscription.ts +129 -0
  158. package/src/cli/commands/trigger/create/timer.ts +94 -0
  159. package/src/cli/commands/trigger/index.ts +16 -0
  160. package/src/cli/commands/trigger/list.ts +68 -0
  161. package/src/cli/commands/trigger/options.ts +59 -0
  162. package/src/cli/commands/trigger/remove.ts +45 -0
  163. package/src/cli/commands/trigger/update/index.ts +14 -0
  164. package/src/cli/commands/trigger/update/queue.ts +195 -0
  165. package/src/cli/commands/trigger/update/subscription.ts +279 -0
  166. package/src/cli/commands/trigger/update/timer.ts +194 -0
  167. package/src/cli/commands/trigger/util.ts +409 -0
  168. package/src/cli/index.ts +5 -0
  169. package/src/cli/plugin.ts +23 -0
  170. package/src/components/AutomationPanel/AutomationPanel.stories.tsx +10 -8
  171. package/src/components/AutomationPanel/AutomationPanel.tsx +174 -75
  172. package/src/components/FunctionsPanel/FunctionsPanel.tsx +42 -41
  173. package/src/components/FunctionsRegistry/FunctionsRegistry.tsx +28 -49
  174. package/src/components/FunctionsRegistry/index.ts +4 -1
  175. package/src/components/TriggerEditor/FunctionInputEditor.tsx +34 -33
  176. package/src/components/TriggerEditor/SpecSelector.tsx +20 -9
  177. package/src/components/TriggerEditor/TriggerEditor.stories.tsx +80 -34
  178. package/src/components/TriggerEditor/TriggerEditor.tsx +90 -48
  179. package/src/components/index.ts +1 -2
  180. package/src/containers/AutomationSettings/AutomationSettings.tsx +28 -0
  181. package/src/containers/AutomationSettings/index.ts +5 -0
  182. package/src/containers/FunctionsContainer/FunctionsContainer.tsx +34 -0
  183. package/src/containers/FunctionsContainer/index.ts +5 -0
  184. package/src/containers/TriggerSettings/TriggerSettings.tsx +26 -0
  185. package/src/containers/TriggerSettings/index.ts +6 -0
  186. package/src/containers/index.ts +9 -0
  187. package/src/hooks/index.ts +3 -0
  188. package/src/hooks/useComputeRuntime.ts +16 -0
  189. package/src/hooks/useComputeRuntimeCallback.ts +8 -44
  190. package/src/hooks/useComputeRuntimeService.ts +24 -0
  191. package/src/hooks/useTriggerRuntimeControls.ts +28 -14
  192. package/src/index.ts +2 -7
  193. package/src/meta.ts +3 -3
  194. package/src/operations/create-trigger-from-template.ts +75 -0
  195. package/src/operations/definitions.ts +28 -0
  196. package/src/operations/index.ts +9 -0
  197. package/src/testing/test-functions.ts +9 -6
  198. package/src/translations.ts +35 -34
  199. package/src/types/capabilities.ts +56 -0
  200. package/src/types/events.ts +11 -0
  201. package/src/types/index.ts +2 -0
  202. package/src/types/schema.ts +5 -5
  203. package/dist/lib/browser/AutomationPanel-7OECLR5N.mjs +0 -11
  204. package/dist/lib/browser/AutomationSettings-KCZISXI6.mjs +0 -68
  205. package/dist/lib/browser/AutomationSettings-KCZISXI6.mjs.map +0 -7
  206. package/dist/lib/browser/FunctionsContainer-MIWEISRR.mjs +0 -151
  207. package/dist/lib/browser/FunctionsContainer-MIWEISRR.mjs.map +0 -7
  208. package/dist/lib/browser/FunctionsPanel-CRW6SJUN.mjs +0 -10
  209. package/dist/lib/browser/app-graph-builder-W7LLC6XW.mjs +0 -81
  210. package/dist/lib/browser/app-graph-builder-W7LLC6XW.mjs.map +0 -7
  211. package/dist/lib/browser/chunk-EPEXQP45.mjs +0 -14
  212. package/dist/lib/browser/chunk-EPEXQP45.mjs.map +0 -7
  213. package/dist/lib/browser/chunk-JW7XSPYW.mjs +0 -267
  214. package/dist/lib/browser/chunk-JW7XSPYW.mjs.map +0 -7
  215. package/dist/lib/browser/chunk-LZQFZO3B.mjs +0 -17
  216. package/dist/lib/browser/chunk-LZQFZO3B.mjs.map +0 -7
  217. package/dist/lib/browser/chunk-NAPXRXTY.mjs +0 -100
  218. package/dist/lib/browser/chunk-NAPXRXTY.mjs.map +0 -7
  219. package/dist/lib/browser/chunk-QKFBHAGN.mjs +0 -184
  220. package/dist/lib/browser/chunk-QKFBHAGN.mjs.map +0 -7
  221. package/dist/lib/browser/chunk-TWWFNOIR.mjs +0 -109
  222. package/dist/lib/browser/chunk-TWWFNOIR.mjs.map +0 -7
  223. package/dist/lib/browser/chunk-XAKZ4ANY.mjs +0 -15
  224. package/dist/lib/browser/chunk-XAKZ4ANY.mjs.map +0 -7
  225. package/dist/lib/browser/chunk-YBPJCY3F.mjs +0 -38
  226. package/dist/lib/browser/chunk-YBPJCY3F.mjs.map +0 -7
  227. package/dist/lib/browser/compute-runtime-EIQTHJFZ.mjs +0 -113
  228. package/dist/lib/browser/compute-runtime-EIQTHJFZ.mjs.map +0 -7
  229. package/dist/lib/browser/intent-resolver-5HR7M7T6.mjs +0 -77
  230. package/dist/lib/browser/intent-resolver-5HR7M7T6.mjs.map +0 -7
  231. package/dist/lib/browser/react-surface-YQW7WCFW.mjs +0 -64
  232. package/dist/lib/browser/react-surface-YQW7WCFW.mjs.map +0 -7
  233. package/dist/lib/node-esm/AutomationPanel-HCVFNHGQ.mjs +0 -12
  234. package/dist/lib/node-esm/AutomationPanel-HCVFNHGQ.mjs.map +0 -7
  235. package/dist/lib/node-esm/AutomationSettings-UUUPVNUJ.mjs +0 -69
  236. package/dist/lib/node-esm/AutomationSettings-UUUPVNUJ.mjs.map +0 -7
  237. package/dist/lib/node-esm/FunctionsContainer-6OB3JN5O.mjs +0 -152
  238. package/dist/lib/node-esm/FunctionsContainer-6OB3JN5O.mjs.map +0 -7
  239. package/dist/lib/node-esm/FunctionsPanel-RVVCS6VH.mjs +0 -11
  240. package/dist/lib/node-esm/FunctionsPanel-RVVCS6VH.mjs.map +0 -7
  241. package/dist/lib/node-esm/app-graph-builder-SLQOO7GH.mjs +0 -82
  242. package/dist/lib/node-esm/app-graph-builder-SLQOO7GH.mjs.map +0 -7
  243. package/dist/lib/node-esm/chunk-6YRKST6M.mjs +0 -185
  244. package/dist/lib/node-esm/chunk-6YRKST6M.mjs.map +0 -7
  245. package/dist/lib/node-esm/chunk-CEVIVRTY.mjs +0 -19
  246. package/dist/lib/node-esm/chunk-CEVIVRTY.mjs.map +0 -7
  247. package/dist/lib/node-esm/chunk-CPP35BE6.mjs +0 -16
  248. package/dist/lib/node-esm/chunk-CPP35BE6.mjs.map +0 -7
  249. package/dist/lib/node-esm/chunk-ECJKIUBO.mjs.map +0 -7
  250. package/dist/lib/node-esm/chunk-KB7NFEYY.mjs +0 -16
  251. package/dist/lib/node-esm/chunk-KB7NFEYY.mjs.map +0 -7
  252. package/dist/lib/node-esm/chunk-PICJ2REN.mjs +0 -101
  253. package/dist/lib/node-esm/chunk-PICJ2REN.mjs.map +0 -7
  254. package/dist/lib/node-esm/chunk-RVK52XGK.mjs +0 -110
  255. package/dist/lib/node-esm/chunk-RVK52XGK.mjs.map +0 -7
  256. package/dist/lib/node-esm/chunk-W76WUTZY.mjs +0 -268
  257. package/dist/lib/node-esm/chunk-W76WUTZY.mjs.map +0 -7
  258. package/dist/lib/node-esm/compute-runtime-URROOC34.mjs +0 -114
  259. package/dist/lib/node-esm/compute-runtime-URROOC34.mjs.map +0 -7
  260. package/dist/lib/node-esm/intent-resolver-KDRYB5BC.mjs +0 -78
  261. package/dist/lib/node-esm/intent-resolver-KDRYB5BC.mjs.map +0 -7
  262. package/dist/lib/node-esm/react-surface-NNHYNBO6.mjs +0 -65
  263. package/dist/lib/node-esm/react-surface-NNHYNBO6.mjs.map +0 -7
  264. package/dist/types/src/capabilities/capabilities.d.ts +0 -20
  265. package/dist/types/src/capabilities/capabilities.d.ts.map +0 -1
  266. package/dist/types/src/capabilities/intent-resolver.d.ts +0 -4
  267. package/dist/types/src/capabilities/intent-resolver.d.ts.map +0 -1
  268. package/dist/types/src/components/AutomationSettings.d.ts +0 -5
  269. package/dist/types/src/components/AutomationSettings.d.ts.map +0 -1
  270. package/dist/types/src/components/FunctionsContainer.d.ts.map +0 -1
  271. package/dist/types/src/components/TriggerSettings.d.ts +0 -6
  272. package/dist/types/src/components/TriggerSettings.d.ts.map +0 -1
  273. package/dist/types/src/events.d.ts +0 -4
  274. package/dist/types/src/events.d.ts.map +0 -1
  275. package/src/capabilities/capabilities.ts +0 -41
  276. package/src/capabilities/intent-resolver.ts +0 -72
  277. package/src/components/AutomationSettings.tsx +0 -30
  278. package/src/components/FunctionsContainer.tsx +0 -36
  279. package/src/components/TriggerSettings.tsx +0 -25
  280. package/src/events.ts +0 -11
  281. /package/dist/lib/browser/{AutomationPanel-7OECLR5N.mjs.map → chunk-J5LGTIGS.mjs.map} +0 -0
  282. /package/dist/lib/{browser/FunctionsPanel-CRW6SJUN.mjs.map → node-esm/chunk-HSLMI22Q.mjs.map} +0 -0
@@ -6,43 +6,55 @@ import * as Array from 'effect/Array';
6
6
  import * as EFn from 'effect/Function';
7
7
  import * as Match from 'effect/Match';
8
8
  import * as Schema from 'effect/Schema';
9
- import React, { useMemo, useState } from 'react';
9
+ import React, { useCallback, useMemo, useState } from 'react';
10
10
 
11
+ import { useTypeOptions } from '@dxos/app-toolkit/ui';
12
+ import { Context } from '@dxos/context';
11
13
  import { Filter, Obj, Tag } from '@dxos/echo';
12
- import { Function, Script, Trigger } from '@dxos/functions';
13
- import { useTypeOptions } from '@dxos/plugin-space';
14
+ import { Script, Trigger } from '@dxos/functions';
15
+ import { KEY_QUEUE_CURSOR } from '@dxos/functions-runtime';
16
+ import { FunctionsServiceClient } from '@dxos/functions-runtime/edge';
17
+ import { Operation } from '@dxos/operation';
14
18
  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';
19
+ import { type Space, useObject, useQuery } from '@dxos/react-client/echo';
20
+ import { Clipboard, IconButton, type IconButtonProps, Input, Separator, useTranslation } from '@dxos/react-ui';
21
+ import { Settings } from '@dxos/react-ui-form';
18
22
  import { List } from '@dxos/react-ui-list';
19
- import { ghostHover, mx } from '@dxos/react-ui-theme';
20
- import { View } from '@dxos/schema';
21
- import { Project } from '@dxos/types';
23
+ import { Pipeline } from '@dxos/types';
24
+ import { ghostHover, mx } from '@dxos/ui-theme';
25
+ import { isNonNullable } from '@dxos/util';
26
+
27
+ import { meta } from '#meta';
22
28
 
23
- import { meta } from '../../meta';
24
29
  import { TriggerEditor, type TriggerEditorProps } from '../TriggerEditor';
25
30
 
26
- const grid = 'grid grid-cols-[40px_1fr_32px] min-bs-[2.5rem]';
31
+ const grid = 'grid grid-cols-[40px_1fr_32px_32px] min-h-[2.5rem]';
27
32
 
28
- export type AutomationPanelProps = ThemedClassName<{
33
+ export type AutomationPanelProps = {
29
34
  space: Space;
30
- object?: Obj.Any;
35
+ object?: Obj.Unknown;
31
36
  initialTrigger?: Trigger.Trigger;
32
37
  onDone?: () => void;
33
- }>;
38
+ };
34
39
 
35
40
  // TODO(burdon): Factor out common layout with ViewEditor.
36
- export const AutomationPanel = ({ classNames, space, object, initialTrigger, onDone }: AutomationPanelProps) => {
41
+ export const AutomationPanel = ({ space, object, initialTrigger, onDone }: AutomationPanelProps) => {
37
42
  const { t } = useTranslation(meta.id);
38
43
  const client = useClient();
39
- const functions = useQuery(space, Filter.type(Function.Function));
40
- const triggers = useQuery(space, Filter.type(Trigger.Trigger));
44
+ const functionsServiceClient = useMemo(() => FunctionsServiceClient.fromClient(client), [client]);
45
+ const functions = useQuery(space.db, Filter.type(Operation.PersistentOperation));
46
+ const triggers = useQuery(space.db, Filter.type(Trigger.Trigger));
41
47
  const filteredTriggers = useMemo(() => {
42
48
  return object ? triggers.filter(triggerMatch(object)) : triggers;
43
49
  }, [object, triggers]);
44
- const tags = useQuery(space, Filter.type(Tag.Tag));
45
- const types = useTypeOptions({ space, annotation: ['dynamic', 'limited-static', 'object-form'] });
50
+ const tags = useQuery(space.db, Filter.type(Tag.Tag));
51
+ const types = useTypeOptions({
52
+ space,
53
+ annotation: {
54
+ location: ['database', 'runtime'],
55
+ kind: ['user'],
56
+ },
57
+ });
46
58
 
47
59
  const [trigger, setTrigger] = useState<Trigger.Trigger | undefined>(initialTrigger);
48
60
  const [selected, setSelected] = useState<Trigger.Trigger>();
@@ -65,7 +77,9 @@ export const AutomationPanel = ({ classNames, space, object, initialTrigger, onD
65
77
 
66
78
  const handleSave: TriggerEditorProps['onSave'] = (trigger) => {
67
79
  if (selected) {
68
- Object.assign(selected, trigger);
80
+ Obj.change(selected, (mutable) => {
81
+ Object.assign(mutable, trigger);
82
+ });
69
83
  } else {
70
84
  space.db.add(Trigger.make(trigger));
71
85
  }
@@ -80,11 +94,22 @@ export const AutomationPanel = ({ classNames, space, object, initialTrigger, onD
80
94
  onDone?.();
81
95
  };
82
96
 
97
+ const handleForceRunTrigger = async (trigger: Trigger.Trigger) => {
98
+ await functionsServiceClient.forceRunCronTrigger(Context.default(), space.id, trigger.id);
99
+ };
100
+
101
+ const handleResetCursor = async (trigger: Trigger.Trigger) => {
102
+ Obj.change(trigger, (obj) => {
103
+ Obj.deleteKeys(obj, KEY_QUEUE_CURSOR);
104
+ });
105
+ await space.db.flush({ indexes: true });
106
+ };
107
+
83
108
  if (trigger) {
84
109
  return (
85
- <ControlItem title={t('trigger editor title')}>
110
+ <Settings.Item title={t('trigger-editor.title')} description={t('trigger-editor.description')}>
86
111
  <TriggerEditor
87
- space={space}
112
+ db={space.db}
88
113
  trigger={trigger}
89
114
  readonlySpec={Boolean(object)}
90
115
  tags={tags}
@@ -92,12 +117,12 @@ export const AutomationPanel = ({ classNames, space, object, initialTrigger, onD
92
117
  onSave={handleSave}
93
118
  onCancel={handleCancel}
94
119
  />
95
- </ControlItem>
120
+ </Settings.Item>
96
121
  );
97
122
  }
98
123
 
99
124
  return (
100
- <div className={mx(controlItemClasses, classNames)}>
125
+ <Settings.Panel>
101
126
  {filteredTriggers.length > 0 && (
102
127
  <List.Root<Trigger.Trigger>
103
128
  items={filteredTriggers}
@@ -105,74 +130,148 @@ export const AutomationPanel = ({ classNames, space, object, initialTrigger, onD
105
130
  getId={(field) => field.id}
106
131
  >
107
132
  {({ items: filteredTriggers }) => (
108
- <div role='list' className='flex flex-col is-full'>
109
- {filteredTriggers?.map((trigger) => {
110
- const copyAction = getCopyAction(client, trigger);
111
- return (
112
- <List.Item<Trigger.Trigger>
113
- key={trigger.id}
114
- item={trigger}
115
- classNames={mx(grid, ghostHover, 'items-center', 'pli-2')}
116
- >
117
- <Input.Root>
118
- <Input.Switch
119
- checked={trigger.enabled}
120
- onCheckedChange={(checked) => (trigger.enabled = checked)}
121
- />
122
- </Input.Root>
123
-
124
- <div className={'flex'}>
125
- <List.ItemTitle
126
- classNames='pli-1 cursor-pointer is-0 shrink truncate'
127
- onClick={() => handleSelect(trigger)}
128
- >
129
- {getFunctionName(functions, trigger) ?? '∅'}
130
- </List.ItemTitle>
131
-
132
- {/* TODO: a better way to expose copy action */}
133
- {copyAction && (
134
- <Clipboard.IconButton
135
- label={t(copyAction.translationKey)}
136
- value={copyAction.contentProvider()}
137
- />
138
- )}
139
- </div>
140
-
141
- <List.ItemDeleteButton onClick={() => handleDelete(trigger)} />
142
- </List.Item>
143
- );
144
- })}
133
+ <div role='list' className='flex flex-col w-full'>
134
+ {filteredTriggers?.map((trigger) => (
135
+ <TriggerListItem
136
+ key={trigger.id}
137
+ trigger={trigger}
138
+ functions={functions}
139
+ onSelect={handleSelect}
140
+ onDelete={handleDelete}
141
+ onResetCursor={handleResetCursor}
142
+ onForceRun={handleForceRunTrigger}
143
+ />
144
+ ))}
145
145
  </div>
146
146
  )}
147
147
  </List.Root>
148
148
  )}
149
- {filteredTriggers.length > 0 && <Separator classNames='mlb-4' />}
150
- <IconButton icon='ph--plus--regular' label={t('new trigger label')} onClick={handleAdd} />
151
- </div>
149
+
150
+ {filteredTriggers.length > 0 && <Separator classNames='my-4' />}
151
+ <IconButton icon='ph--plus--regular' label={t('new-trigger.label')} onClick={handleAdd} />
152
+ </Settings.Panel>
153
+ );
154
+ };
155
+
156
+ const TriggerListItem = ({
157
+ trigger,
158
+ functions,
159
+ onSelect,
160
+ onDelete,
161
+ onResetCursor,
162
+ onForceRun,
163
+ }: {
164
+ trigger: Trigger.Trigger;
165
+ functions: Operation.PersistentOperation[];
166
+ onSelect?: (trigger: Trigger.Trigger) => void;
167
+ onDelete?: (trigger: Trigger.Trigger) => void;
168
+ onResetCursor?: (trigger: Trigger.Trigger) => void;
169
+ onForceRun?: (trigger: Trigger.Trigger) => void;
170
+ }) => {
171
+ const client = useClient();
172
+ const copyAction = getCopyAction(client, trigger);
173
+ const { t } = useTranslation(meta.id);
174
+ const cursor = Obj.getKeys(trigger, KEY_QUEUE_CURSOR).at(0)?.id;
175
+ const [snapshot, updateTrigger] = useObject(trigger);
176
+
177
+ const enabled = snapshot.enabled ?? false;
178
+ const onEnabledChange = (checked: boolean) => {
179
+ updateTrigger((trigger) => {
180
+ trigger.enabled = checked;
181
+ });
182
+ };
183
+
184
+ const handleSelect = useCallback(() => {
185
+ onSelect?.(trigger);
186
+ }, [onSelect, trigger]);
187
+
188
+ const handleDelete = useCallback(() => {
189
+ onDelete?.(trigger);
190
+ }, [onDelete, trigger]);
191
+
192
+ const handleResetCursor = useCallback(() => {
193
+ onResetCursor?.(trigger);
194
+ }, [onResetCursor, trigger]);
195
+
196
+ const handleForceRun = useCallback(() => {
197
+ onForceRun?.(trigger);
198
+ }, [onForceRun, trigger]);
199
+
200
+ const actionProps = useMemo<IconButtonProps | undefined>(() => {
201
+ if (trigger.spec?.kind === 'timer' && onForceRun) {
202
+ return {
203
+ disabled: !enabled || trigger.spec?.kind !== 'timer',
204
+ icon: 'ph--play--regular',
205
+ label: 'Force run',
206
+ onClick: handleForceRun,
207
+ };
208
+ }
209
+
210
+ if (trigger.spec?.kind === 'queue' && onResetCursor) {
211
+ return {
212
+ disabled: !cursor,
213
+ icon: 'ph--arrow-clockwise--regular',
214
+ label: 'Reset cursor',
215
+ onClick: handleResetCursor,
216
+ };
217
+ }
218
+ }, [enabled, trigger.spec?.kind, handleForceRun]);
219
+
220
+ return (
221
+ <List.Item<Obj.Snapshot<Trigger.Trigger>>
222
+ key={trigger.id}
223
+ item={snapshot}
224
+ classNames={mx(grid, ghostHover, 'items-center', 'px-2')}
225
+ >
226
+ <Input.Root>
227
+ <Input.Switch checked={enabled} onCheckedChange={onEnabledChange} />
228
+ </Input.Root>
229
+
230
+ <div className={'flex'}>
231
+ <List.ItemTitle classNames='px-1 cursor-pointer w-0 shrink truncate' onClick={handleSelect}>
232
+ {getFunctionName(functions, trigger) ?? '∅'}
233
+ {cursor && <div className='text-xs text-description truncate ml-4'>Position: {cursor}</div>}
234
+ </List.ItemTitle>
235
+
236
+ {copyAction && (
237
+ <Clipboard.IconButton label={t(copyAction.translationKey)} value={copyAction.contentProvider()} />
238
+ )}
239
+ </div>
240
+
241
+ {actionProps ? <List.ItemIconButton {...actionProps} autoHide={false} /> : <div />}
242
+
243
+ {onDelete && <List.ItemDeleteButton onClick={handleDelete} />}
244
+ </List.Item>
152
245
  );
153
246
  };
154
247
 
155
248
  const getCopyAction = (client: Client, trigger: Trigger.Trigger | undefined) => {
156
249
  if (trigger?.spec?.kind === 'email') {
157
- return { translationKey: 'trigger copy email', contentProvider: () => `${getSpace(trigger)!.id}@dxos.network` };
250
+ return {
251
+ translationKey: 'trigger copy email' as const,
252
+ contentProvider: () => `${Obj.getDatabase(trigger)!.spaceId}@dxos.network`,
253
+ };
158
254
  }
159
255
 
160
256
  if (trigger?.spec?.kind === 'webhook') {
161
- return { translationKey: 'trigger copy url', contentProvider: () => getWebhookUrl(client, trigger) };
257
+ return {
258
+ translationKey: 'trigger copy url' as const,
259
+ contentProvider: () => getWebhookUrl(client, trigger!),
260
+ };
162
261
  }
163
262
 
164
263
  return undefined;
165
264
  };
166
265
 
167
266
  const getWebhookUrl = (client: Client, trigger: Trigger.Trigger) => {
168
- const spaceId = getSpace(trigger)!.id;
267
+ const spaceId = Obj.getDatabase(trigger)!.spaceId;
169
268
  const edgeUrl = new URL(client.config.values.runtime!.services!.edge!.url!);
170
269
  const isSecure = edgeUrl.protocol.startsWith('https') || edgeUrl.protocol.startsWith('wss');
171
270
  edgeUrl.protocol = isSecure ? 'https' : 'http';
172
271
  return new URL(`/webhook/${spaceId}:${trigger.id}`, edgeUrl).toString();
173
272
  };
174
273
 
175
- const getFunctionName = (functions: Function.Function[], trigger: Trigger.Trigger) => {
274
+ const getFunctionName = (functions: Operation.PersistentOperation[], trigger: Trigger.Trigger) => {
176
275
  // TODO(wittjosiah): Truncation should be done in the UI.
177
276
  // Warning that the List component is currently a can of worms.
178
277
  const shortId = trigger.function && `${trigger.function.dxn.toString().slice(0, 16)}…`;
@@ -182,18 +281,18 @@ const getFunctionName = (functions: Function.Function[], trigger: Trigger.Trigge
182
281
 
183
282
  const scriptMatch = (script: Script.Script) => (trigger: Trigger.Trigger) => {
184
283
  const fn = trigger.function?.target;
185
- if (!Obj.instanceOf(Function.Function, fn)) {
284
+ if (!Obj.instanceOf(Operation.PersistentOperation, fn)) {
186
285
  return false;
187
286
  }
188
287
 
189
288
  return fn.source?.target === script;
190
289
  };
191
290
 
192
- const projectMatch = (project: Project.Project) => {
291
+ const projectMatch = (project: Pipeline.Pipeline) => {
193
292
  const viewQueries = EFn.pipe(
194
- project.collections,
195
- Array.map((collection) => collection.target),
196
- Array.filter(Schema.is(View.View)),
293
+ project.columns,
294
+ Array.map((column) => column.view.target),
295
+ Array.filter(isNonNullable),
197
296
  Array.map((view) => Obj.getSnapshot(view).query.ast),
198
297
  Array.map((ast) => JSON.stringify(ast)),
199
298
  );
@@ -209,14 +308,14 @@ const projectMatch = (project: Project.Project) => {
209
308
  };
210
309
  };
211
310
 
212
- const triggerMatch = Match.type<Obj.Any>().pipe(
311
+ const triggerMatch = Match.type<Obj.Unknown>().pipe(
213
312
  Match.withReturnType<(trigger: Trigger.Trigger) => boolean>(),
214
313
  Match.when(
215
314
  (obj) => Obj.instanceOf(Script.Script, obj),
216
315
  (obj) => scriptMatch(obj),
217
316
  ),
218
317
  Match.when(
219
- (obj) => Obj.instanceOf(Project.Project, obj),
318
+ (obj) => Obj.instanceOf(Pipeline.Pipeline, obj),
220
319
  (obj) => projectMatch(obj),
221
320
  ),
222
321
  Match.orElse((_obj) => () => true),
@@ -5,20 +5,18 @@
5
5
  import * as Schema from 'effect/Schema';
6
6
  import React, { useCallback, useMemo } from 'react';
7
7
 
8
- import { LayoutAction, createIntent } from '@dxos/app-framework';
9
- import { useIntentDispatcher } from '@dxos/app-framework/react';
10
- import { Obj } from '@dxos/echo';
11
- import { Function, Script } from '@dxos/functions';
12
- import { SpaceAction } from '@dxos/plugin-space/types';
8
+ import { useOperationInvoker } from '@dxos/app-framework/ui';
9
+ import { LayoutOperation, getObjectPathFromObject } from '@dxos/app-toolkit';
10
+ import { Script } from '@dxos/functions';
11
+ import { Operation } from '@dxos/operation';
12
+ import { SpaceOperation } from '@dxos/plugin-space/operations';
13
13
  import { Filter, type Space, useQuery } from '@dxos/react-client/echo';
14
- import { Button, IconButton, useTranslation } from '@dxos/react-ui';
15
- import { controlItemClasses } from '@dxos/react-ui-form';
14
+ import { IconButton, useTranslation } from '@dxos/react-ui';
15
+ import { Settings } from '@dxos/react-ui-form';
16
16
  import { List } from '@dxos/react-ui-list';
17
- import { ghostHover, mx } from '@dxos/react-ui-theme';
17
+ import { ghostHover, mx } from '@dxos/ui-theme';
18
18
 
19
- import { meta } from '../../meta';
20
-
21
- const grid = 'grid grid-cols-[1fr_auto] min-bs-[2.5rem]';
19
+ import { meta } from '#meta';
22
20
 
23
21
  export type FunctionsPanelProps = {
24
22
  space: Space;
@@ -26,9 +24,9 @@ export type FunctionsPanelProps = {
26
24
 
27
25
  export const FunctionsPanel = ({ space }: FunctionsPanelProps) => {
28
26
  const { t } = useTranslation(meta.id);
29
- const functions = useQuery(space, Filter.type(Function.Function));
30
- const scripts = useQuery(space, Filter.type(Script.Script));
31
- 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();
32
30
 
33
31
  const functionToScriptMap = useMemo(
34
32
  () =>
@@ -49,7 +47,7 @@ export const FunctionsPanel = ({ space }: FunctionsPanelProps) => {
49
47
  );
50
48
 
51
49
  const getScriptName = useCallback(
52
- (func: Function.Function) => {
50
+ (func: Operation.PersistentOperation) => {
53
51
  const script = functionToScriptMap[func.id];
54
52
  return script?.name;
55
53
  },
@@ -57,50 +55,55 @@ export const FunctionsPanel = ({ space }: FunctionsPanelProps) => {
57
55
  );
58
56
 
59
57
  const handleGoToScript = useCallback(
60
- (func: Function.Function) => {
58
+ (func: Operation.PersistentOperation) => {
61
59
  const script = functionToScriptMap[func.id];
62
60
  if (script) {
63
- void dispatch(
64
- createIntent(LayoutAction.Open, {
65
- part: 'main',
66
- subject: [Obj.getDXN(script).toString()],
67
- }),
68
- );
61
+ void invokePromise(LayoutOperation.Open, { subject: [getObjectPathFromObject(script)] });
69
62
  }
70
63
  },
71
- [functionToScriptMap, dispatch],
64
+ [functionToScriptMap, invokePromise],
72
65
  );
73
66
 
74
67
  const handleDelete = useCallback(
75
- (func: Function.Function) => dispatch(createIntent(SpaceAction.RemoveObjects, { objects: [func] })),
76
- [dispatch],
68
+ (func: Operation.PersistentOperation) => invokePromise(SpaceOperation.RemoveObjects, { objects: [func] }),
69
+ [invokePromise],
77
70
  );
78
71
 
79
72
  return (
80
- <div role='none' className={mx(controlItemClasses)}>
73
+ <Settings.Panel>
81
74
  {functions.length > 0 && (
82
- <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
+ >
83
80
  {({ items }) => (
84
- <div role='list' className='flex flex-col is-full'>
81
+ <div role='list' className='flex flex-col w-full'>
85
82
  {items?.map((func) => (
86
- <List.Item<Function.Function>
83
+ <List.Item<Operation.PersistentOperation>
87
84
  key={func.id}
88
85
  item={func}
89
- 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
+ )}
90
90
  >
91
91
  <div className='flex flex-col truncate'>
92
92
  <List.ItemTitle classNames='truncate'>{func.name}</List.ItemTitle>
93
- {getScriptName(func) && (
94
- <div className='text-xs text-description truncate'>{getScriptName(func)}</div>
95
- )}
93
+ {getScriptName(func) && <p className='text-xs text-description truncate'>{getScriptName(func)}</p>}
96
94
  </div>
97
- {functionToScriptMap[func.id] && (
98
- <Button onClick={() => handleGoToScript(func)}>{t('go to function source button label')}</Button>
99
- )}
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 />}
100
103
  <IconButton
101
- iconOnly
102
104
  icon='ph--trash--regular'
103
- label={t('delete function button label')}
105
+ iconOnly
106
+ label={t('delete-function-button.label')}
104
107
  onClick={() => handleDelete(func)}
105
108
  />
106
109
  </List.Item>
@@ -109,8 +112,6 @@ export const FunctionsPanel = ({ space }: FunctionsPanelProps) => {
109
112
  )}
110
113
  </List.Root>
111
114
  )}
112
-
113
- {functions.length === 0 && <div className='text-center plb-4 text-gray-500'>{t('no functions found')}</div>}
114
- </div>
115
+ </Settings.Panel>
115
116
  );
116
117
  };
@@ -2,27 +2,23 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import * as Array from 'effect/Array';
6
- import * as EffectFunction from 'effect/Function';
7
- import * as Order from 'effect/Order';
8
5
  import * as Schema from 'effect/Schema';
9
6
  import { useState } from 'react';
10
7
  import React, { useCallback } from 'react';
11
8
 
12
- import { Obj } from '@dxos/echo';
13
- import { Function } from '@dxos/functions';
9
+ import { Context } from '@dxos/context';
14
10
  import { getDeployedFunctions } from '@dxos/functions-runtime/edge';
11
+ import * as OperationModule from '@dxos/operation';
15
12
  import { useClient } from '@dxos/react-client';
16
13
  import { Filter, Query, type Space, useQuery } from '@dxos/react-client/echo';
17
- import { useAsyncEffect } from '@dxos/react-ui';
18
- import { IconButton, useTranslation } from '@dxos/react-ui';
19
- import { controlItemClasses } from '@dxos/react-ui-form';
14
+ import { IconButton, useAsyncEffect, useTranslation } from '@dxos/react-ui';
15
+ import { Settings } from '@dxos/react-ui-form';
20
16
  import { List } from '@dxos/react-ui-list';
21
- import { ghostHover, mx } from '@dxos/react-ui-theme';
17
+ import { ghostHover, mx } from '@dxos/ui-theme';
22
18
 
23
- import { meta } from '../../meta';
19
+ import { meta } from '#meta';
24
20
 
25
- const grid = 'grid grid-cols-[1fr_1fr_auto] min-bs-[2.5rem]';
21
+ const grid = 'grid grid-cols-[1fr_1fr_auto] min-h-[2.5rem]';
26
22
 
27
23
  type FunctionsRegistryProps = {
28
24
  space: Space;
@@ -31,12 +27,12 @@ type FunctionsRegistryProps = {
31
27
  export const FunctionsRegistry = ({ space }: FunctionsRegistryProps) => {
32
28
  const client = useClient();
33
29
  const [loading, setLoading] = useState(true);
34
- const [functions, setFunctions] = useState<Function.Function[]>([]);
30
+ const [functions, setFunctions] = useState<OperationModule.Operation.PersistentOperation[]>([]);
35
31
  const { t } = useTranslation(meta.id);
36
32
 
37
- const dbFunctions = useQuery(space, Filter.type(Function.Function));
33
+ const dbFunctions = useQuery(space.db, Filter.type(OperationModule.Operation.PersistentOperation));
38
34
 
39
- const state = (func: Function.Function) => {
35
+ const state = (func: OperationModule.Operation.PersistentOperation) => {
40
36
  const dbFunction = dbFunctions.find((f) => f.key === func.key);
41
37
  if (!dbFunction) {
42
38
  return 'import';
@@ -49,55 +45,41 @@ export const FunctionsRegistry = ({ space }: FunctionsRegistryProps) => {
49
45
 
50
46
  useAsyncEffect(async () => {
51
47
  setLoading(true);
52
- const functions = await getDeployedFunctions(client);
48
+ const functions = await getDeployedFunctions(Context.default(), client, true);
53
49
  setFunctions(functions);
54
50
  setLoading(false);
55
51
  }, []);
56
52
 
57
- const dedupedFunctions = EffectFunction.pipe(
58
- functions,
59
- Array.filter((_) => _.key !== undefined),
60
- Array.sort(Order.reverse(Order.mapInput(Order.string, (_: Function.Function) => _.updated ?? ''))),
61
- Array.dedupeWith((self, that) => self.key === that.key),
62
- Array.sort(Order.mapInput(Order.string, (_: Function.Function) => _.key ?? '')),
63
- );
64
-
65
53
  const hanleImportOrUpdate = useCallback(
66
- async (func: Function.Function) => {
67
- const {
68
- objects: [existingFunc],
69
- } = await space.db.query(Query.type(Function.Function, { key: func.key })).run();
54
+ async (func: OperationModule.Operation.PersistentOperation) => {
55
+ const functions = await space.db
56
+ .query(Query.type(OperationModule.Operation.PersistentOperation, { key: func.key }))
57
+ .run();
58
+ const [existingFunc] = functions;
70
59
  if (!existingFunc) {
71
60
  space.db.add(func);
72
61
  return;
73
62
  }
74
- existingFunc.version = func.version;
75
- existingFunc.updated = func.updated;
76
- existingFunc.name = func.name;
77
- existingFunc.description = func.description;
78
- // TODO(dmaretskyi): A workaround for an ECHO bug.
79
- existingFunc.inputSchema = JSON.parse(JSON.stringify(func.inputSchema));
80
- existingFunc.outputSchema = JSON.parse(JSON.stringify(func.outputSchema));
81
- Obj.getMeta(existingFunc).keys = JSON.parse(JSON.stringify(Obj.getMeta(func).keys));
63
+ OperationModule.Operation.setFrom(existingFunc, func);
82
64
  },
83
65
  [space],
84
66
  );
85
67
 
86
68
  return (
87
- <div role='none' className={mx(controlItemClasses)}>
88
- {dedupedFunctions.length > 0 && (
89
- <List.Root<Function.Function>
90
- items={dedupedFunctions}
91
- isItem={Schema.is(Function.Function)}
69
+ <Settings.Panel>
70
+ {functions.length > 0 && (
71
+ <List.Root<OperationModule.Operation.PersistentOperation>
72
+ items={functions}
73
+ isItem={Schema.is(OperationModule.Operation.PersistentOperation)}
92
74
  getId={(func) => func.id}
93
75
  >
94
76
  {({ items }) => (
95
- <div role='list' className='flex flex-col is-full'>
77
+ <div role='list' className='flex flex-col w-full'>
96
78
  {items?.map((func) => (
97
- <List.Item<Function.Function>
79
+ <List.Item<OperationModule.Operation.PersistentOperation>
98
80
  key={func.id}
99
81
  item={func}
100
- classNames={mx(grid, ghostHover, 'items-center', 'pli-2', 'min-bs-[3rem]')}
82
+ classNames={mx(grid, ghostHover, 'items-center', 'px-2', 'min-h-[3rem]')}
101
83
  >
102
84
  <div className='flex flex-col truncate'>
103
85
  <List.ItemTitle classNames='truncate'>{func.name}</List.ItemTitle>
@@ -114,7 +96,7 @@ export const FunctionsRegistry = ({ space }: FunctionsRegistryProps) => {
114
96
  iconOnly
115
97
  icon={state(func) === 'update' ? 'ph--arrows-clockwise--regular' : 'ph--download--regular'}
116
98
  label={
117
- state(func) === 'update' ? t('update function button label') : t('import function button label')
99
+ state(func) === 'update' ? t('update-function-button.label') : t('import-function-button.label')
118
100
  }
119
101
  disabled={state(func) === 'none'}
120
102
  onClick={() => hanleImportOrUpdate(func)}
@@ -126,10 +108,7 @@ export const FunctionsRegistry = ({ space }: FunctionsRegistryProps) => {
126
108
  </List.Root>
127
109
  )}
128
110
 
129
- {dedupedFunctions.length === 0 && !loading && (
130
- <div className='text-center plb-4 text-gray-500'>{t('no functions found')}</div>
131
- )}
132
- {loading && <div className='text-center plb-4 text-gray-500'>{t('loading functions')}</div>}
133
- </div>
111
+ {loading && <div className='text-center py-4 text-gray-500'>{t('loading-functions.message')}</div>}
112
+ </Settings.Panel>
134
113
  );
135
114
  };
@@ -2,4 +2,7 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- export { FunctionsRegistry } from './FunctionsRegistry';
5
+ import { FunctionsRegistry } from './FunctionsRegistry';
6
+
7
+ export { FunctionsRegistry };
8
+ export default FunctionsRegistry;