@dxos/plugin-automation 0.8.4-main.937b3ca → 0.8.4-main.9be5663bfe

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 (261) 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-JOXPQ27I.mjs → chunk-WQLEMRPU.mjs} +9 -38
  5. package/dist/lib/browser/chunk-WQLEMRPU.mjs.map +7 -0
  6. package/dist/lib/browser/cli/index.mjs +122 -107
  7. package/dist/lib/browser/cli/index.mjs.map +3 -3
  8. package/dist/lib/browser/create-trigger-from-template-JZ62EZTB.mjs +77 -0
  9. package/dist/lib/browser/create-trigger-from-template-JZ62EZTB.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 +60 -92
  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 +4 -4
  18. package/dist/lib/node-esm/chunk-HSLMI22Q.mjs +11 -0
  19. package/dist/lib/node-esm/{chunk-RX52VKI2.mjs → chunk-JWZAVQLF.mjs} +9 -37
  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 +122 -107
  24. package/dist/lib/node-esm/cli/index.mjs.map +3 -3
  25. package/dist/lib/node-esm/create-trigger-from-template-224Z7WJI.mjs +78 -0
  26. package/dist/lib/node-esm/create-trigger-from-template-224Z7WJI.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 +60 -92
  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 +4 -4
  35. package/dist/types/src/AutomationPlugin.d.ts.map +1 -1
  36. package/dist/types/src/capabilities/app-graph-builder.d.ts +6 -0
  37. package/dist/types/src/capabilities/app-graph-builder.d.ts.map +1 -0
  38. package/dist/types/src/capabilities/compute-runtime.d.ts +6 -0
  39. package/dist/types/src/capabilities/compute-runtime.d.ts.map +1 -0
  40. package/dist/types/src/capabilities/index.d.ts +6 -4
  41. package/dist/types/src/capabilities/index.d.ts.map +1 -1
  42. package/dist/types/src/capabilities/node.d.ts +3 -0
  43. package/dist/types/src/capabilities/node.d.ts.map +1 -0
  44. package/dist/types/src/capabilities/operation-handler.d.ts +6 -0
  45. package/dist/types/src/capabilities/operation-handler.d.ts.map +1 -0
  46. package/dist/types/src/capabilities/react-surface.d.ts +5 -0
  47. package/dist/types/src/capabilities/react-surface.d.ts.map +1 -0
  48. package/dist/types/src/cli/commands/trigger/create/index.d.ts +1 -1
  49. package/dist/types/src/cli/commands/trigger/create/queue.d.ts +1 -1
  50. package/dist/types/src/cli/commands/trigger/create/queue.d.ts.map +1 -1
  51. package/dist/types/src/cli/commands/trigger/create/subscription.d.ts +1 -1
  52. package/dist/types/src/cli/commands/trigger/create/subscription.d.ts.map +1 -1
  53. package/dist/types/src/cli/commands/trigger/create/timer.d.ts +1 -1
  54. package/dist/types/src/cli/commands/trigger/create/timer.d.ts.map +1 -1
  55. package/dist/types/src/cli/commands/trigger/list.d.ts +1 -1
  56. package/dist/types/src/cli/commands/trigger/list.d.ts.map +1 -1
  57. package/dist/types/src/cli/commands/trigger/remove.d.ts +1 -1
  58. package/dist/types/src/cli/commands/trigger/update/queue.d.ts.map +1 -1
  59. package/dist/types/src/cli/commands/trigger/update/subscription.d.ts.map +1 -1
  60. package/dist/types/src/cli/commands/trigger/update/timer.d.ts.map +1 -1
  61. package/dist/types/src/cli/commands/trigger/util.d.ts +2 -2
  62. package/dist/types/src/cli/commands/trigger/util.d.ts.map +1 -1
  63. package/dist/types/src/cli/plugin.d.ts.map +1 -1
  64. package/dist/types/src/components/AutomationPanel/AutomationPanel.d.ts +3 -4
  65. package/dist/types/src/components/AutomationPanel/AutomationPanel.d.ts.map +1 -1
  66. package/dist/types/src/components/AutomationPanel/AutomationPanel.stories.d.ts +28 -30
  67. package/dist/types/src/components/AutomationPanel/AutomationPanel.stories.d.ts.map +1 -1
  68. package/dist/types/src/components/FunctionsPanel/FunctionsPanel.d.ts.map +1 -1
  69. package/dist/types/src/components/FunctionsRegistry/FunctionsRegistry.d.ts.map +1 -1
  70. package/dist/types/src/components/FunctionsRegistry/index.d.ts +3 -1
  71. package/dist/types/src/components/FunctionsRegistry/index.d.ts.map +1 -1
  72. package/dist/types/src/components/TriggerEditor/FunctionInputEditor.d.ts +2 -2
  73. package/dist/types/src/components/TriggerEditor/FunctionInputEditor.d.ts.map +1 -1
  74. package/dist/types/src/components/TriggerEditor/SpecSelector.d.ts.map +1 -1
  75. package/dist/types/src/components/TriggerEditor/TriggerEditor.d.ts.map +1 -1
  76. package/dist/types/src/components/TriggerEditor/TriggerEditor.stories.d.ts +91 -91
  77. package/dist/types/src/components/TriggerEditor/TriggerEditor.stories.d.ts.map +1 -1
  78. package/dist/types/src/components/index.d.ts +3 -4
  79. package/dist/types/src/components/index.d.ts.map +1 -1
  80. package/dist/types/src/containers/AutomationSettings/AutomationSettings.d.ts +4 -0
  81. package/dist/types/src/containers/AutomationSettings/AutomationSettings.d.ts.map +1 -0
  82. package/dist/types/src/containers/AutomationSettings/index.d.ts +2 -0
  83. package/dist/types/src/containers/AutomationSettings/index.d.ts.map +1 -0
  84. package/dist/types/src/{components → containers/FunctionsContainer}/FunctionsContainer.d.ts +0 -1
  85. package/dist/types/src/containers/FunctionsContainer/FunctionsContainer.d.ts.map +1 -0
  86. package/dist/types/src/containers/FunctionsContainer/index.d.ts +2 -0
  87. package/dist/types/src/containers/FunctionsContainer/index.d.ts.map +1 -0
  88. package/dist/types/src/containers/TriggerSettings/TriggerSettings.d.ts.map +1 -0
  89. package/dist/types/src/containers/TriggerSettings/index.d.ts +3 -0
  90. package/dist/types/src/containers/TriggerSettings/index.d.ts.map +1 -0
  91. package/dist/types/src/containers/index.d.ts +5 -0
  92. package/dist/types/src/containers/index.d.ts.map +1 -0
  93. package/dist/types/src/hooks/index.d.ts +2 -0
  94. package/dist/types/src/hooks/index.d.ts.map +1 -1
  95. package/dist/types/src/hooks/useComputeRuntime.d.ts +7 -0
  96. package/dist/types/src/hooks/useComputeRuntime.d.ts.map +1 -0
  97. package/dist/types/src/hooks/useComputeRuntimeCallback.d.ts +1 -4
  98. package/dist/types/src/hooks/useComputeRuntimeCallback.d.ts.map +1 -1
  99. package/dist/types/src/hooks/useComputeRuntimeService.d.ts +5 -0
  100. package/dist/types/src/hooks/useComputeRuntimeService.d.ts.map +1 -0
  101. package/dist/types/src/hooks/useTriggerRuntimeControls.d.ts +2 -1
  102. package/dist/types/src/hooks/useTriggerRuntimeControls.d.ts.map +1 -1
  103. package/dist/types/src/index.d.ts +2 -5
  104. package/dist/types/src/index.d.ts.map +1 -1
  105. package/dist/types/src/operations/create-trigger-from-template.d.ts +5 -0
  106. package/dist/types/src/operations/create-trigger-from-template.d.ts.map +1 -0
  107. package/dist/types/src/operations/definitions.d.ts +19 -0
  108. package/dist/types/src/operations/definitions.d.ts.map +1 -0
  109. package/dist/types/src/operations/index.d.ts +4 -0
  110. package/dist/types/src/operations/index.d.ts.map +1 -0
  111. package/dist/types/src/testing/test-functions.d.ts +204 -2
  112. package/dist/types/src/testing/test-functions.d.ts.map +1 -1
  113. package/dist/types/src/translations.d.ts +29 -31
  114. package/dist/types/src/translations.d.ts.map +1 -1
  115. package/dist/types/src/types/capabilities.d.ts +6 -3
  116. package/dist/types/src/types/capabilities.d.ts.map +1 -1
  117. package/dist/types/src/types/schema.d.ts +9 -30
  118. package/dist/types/src/types/schema.d.ts.map +1 -1
  119. package/dist/types/tsconfig.tsbuildinfo +1 -1
  120. package/package.json +73 -46
  121. package/src/AutomationPlugin.tsx +13 -10
  122. package/src/capabilities/app-graph-builder.ts +62 -0
  123. package/src/capabilities/compute-runtime.ts +248 -0
  124. package/src/capabilities/index.ts +10 -4
  125. package/src/capabilities/operation-handler.ts +16 -0
  126. package/src/capabilities/react-surface.tsx +59 -0
  127. package/src/cli/commands/trigger/create/queue.ts +7 -6
  128. package/src/cli/commands/trigger/create/subscription.ts +7 -6
  129. package/src/cli/commands/trigger/create/timer.ts +7 -6
  130. package/src/cli/commands/trigger/list.ts +3 -2
  131. package/src/cli/commands/trigger/remove.ts +2 -2
  132. package/src/cli/commands/trigger/update/queue.ts +21 -21
  133. package/src/cli/commands/trigger/update/subscription.ts +20 -19
  134. package/src/cli/commands/trigger/update/timer.ts +21 -20
  135. package/src/cli/commands/trigger/util.ts +43 -29
  136. package/src/cli/plugin.ts +6 -6
  137. package/src/components/AutomationPanel/AutomationPanel.stories.tsx +10 -8
  138. package/src/components/AutomationPanel/AutomationPanel.tsx +160 -87
  139. package/src/components/FunctionsPanel/FunctionsPanel.tsx +37 -31
  140. package/src/components/FunctionsRegistry/FunctionsRegistry.tsx +27 -24
  141. package/src/components/FunctionsRegistry/index.ts +4 -1
  142. package/src/components/TriggerEditor/FunctionInputEditor.tsx +17 -8
  143. package/src/components/TriggerEditor/SpecSelector.tsx +12 -3
  144. package/src/components/TriggerEditor/TriggerEditor.stories.tsx +56 -13
  145. package/src/components/TriggerEditor/TriggerEditor.tsx +46 -17
  146. package/src/components/index.ts +1 -2
  147. package/src/containers/AutomationSettings/AutomationSettings.tsx +28 -0
  148. package/src/containers/AutomationSettings/index.ts +5 -0
  149. package/src/containers/FunctionsContainer/FunctionsContainer.tsx +34 -0
  150. package/src/containers/FunctionsContainer/index.ts +5 -0
  151. package/src/{components → containers/TriggerSettings}/TriggerSettings.tsx +8 -7
  152. package/src/containers/TriggerSettings/index.ts +6 -0
  153. package/src/containers/index.ts +9 -0
  154. package/src/hooks/index.ts +3 -0
  155. package/src/hooks/useComputeRuntime.ts +16 -0
  156. package/src/hooks/useComputeRuntimeCallback.ts +4 -39
  157. package/src/hooks/useComputeRuntimeService.ts +24 -0
  158. package/src/hooks/useTriggerRuntimeControls.ts +22 -8
  159. package/src/index.ts +2 -6
  160. package/src/meta.ts +2 -2
  161. package/src/operations/create-trigger-from-template.ts +75 -0
  162. package/src/operations/definitions.ts +28 -0
  163. package/src/operations/index.ts +9 -0
  164. package/src/testing/test-functions.ts +8 -5
  165. package/src/translations.ts +35 -36
  166. package/src/types/capabilities.ts +20 -6
  167. package/src/types/events.ts +2 -2
  168. package/src/types/schema.ts +3 -24
  169. package/dist/lib/browser/AutomationPanel-FAS6ADCW.mjs +0 -11
  170. package/dist/lib/browser/AutomationSettings-XN2OIYWL.mjs +0 -56
  171. package/dist/lib/browser/AutomationSettings-XN2OIYWL.mjs.map +0 -7
  172. package/dist/lib/browser/FunctionsContainer-6QLC7JP4.mjs +0 -129
  173. package/dist/lib/browser/FunctionsContainer-6QLC7JP4.mjs.map +0 -7
  174. package/dist/lib/browser/FunctionsPanel-ZX4J75UM.mjs +0 -10
  175. package/dist/lib/browser/app-graph-builder-LAQMEBMH.mjs +0 -84
  176. package/dist/lib/browser/app-graph-builder-LAQMEBMH.mjs.map +0 -7
  177. package/dist/lib/browser/chunk-54PANILA.mjs +0 -14
  178. package/dist/lib/browser/chunk-54PANILA.mjs.map +0 -7
  179. package/dist/lib/browser/chunk-BFUIVUQH.mjs +0 -102
  180. package/dist/lib/browser/chunk-BFUIVUQH.mjs.map +0 -7
  181. package/dist/lib/browser/chunk-BKFQBKYO.mjs +0 -8
  182. package/dist/lib/browser/chunk-BKFQBKYO.mjs.map +0 -7
  183. package/dist/lib/browser/chunk-JOXPQ27I.mjs.map +0 -7
  184. package/dist/lib/browser/chunk-PZNBEKO5.mjs +0 -17
  185. package/dist/lib/browser/chunk-PZNBEKO5.mjs.map +0 -7
  186. package/dist/lib/browser/chunk-QW3EM35H.mjs +0 -248
  187. package/dist/lib/browser/chunk-QW3EM35H.mjs.map +0 -7
  188. package/dist/lib/browser/chunk-RAF2FJST.mjs +0 -86
  189. package/dist/lib/browser/chunk-RAF2FJST.mjs.map +0 -7
  190. package/dist/lib/browser/chunk-YWLEY2FD.mjs +0 -200
  191. package/dist/lib/browser/chunk-YWLEY2FD.mjs.map +0 -7
  192. package/dist/lib/browser/compute-runtime-WTWLQ67J.mjs +0 -114
  193. package/dist/lib/browser/compute-runtime-WTWLQ67J.mjs.map +0 -7
  194. package/dist/lib/browser/operation-resolver-Q3MWOR7K.mjs +0 -82
  195. package/dist/lib/browser/operation-resolver-Q3MWOR7K.mjs.map +0 -7
  196. package/dist/lib/browser/react-surface-EV3AC62F.mjs +0 -65
  197. package/dist/lib/browser/react-surface-EV3AC62F.mjs.map +0 -7
  198. package/dist/lib/node-esm/AutomationPanel-B7NAGDFA.mjs +0 -12
  199. package/dist/lib/node-esm/AutomationPanel-B7NAGDFA.mjs.map +0 -7
  200. package/dist/lib/node-esm/AutomationSettings-M5PMZJ6P.mjs +0 -57
  201. package/dist/lib/node-esm/AutomationSettings-M5PMZJ6P.mjs.map +0 -7
  202. package/dist/lib/node-esm/FunctionsContainer-J4O2ULWR.mjs +0 -130
  203. package/dist/lib/node-esm/FunctionsContainer-J4O2ULWR.mjs.map +0 -7
  204. package/dist/lib/node-esm/FunctionsPanel-SS6GIVNU.mjs +0 -11
  205. package/dist/lib/node-esm/FunctionsPanel-SS6GIVNU.mjs.map +0 -7
  206. package/dist/lib/node-esm/app-graph-builder-4UCMXHYY.mjs +0 -85
  207. package/dist/lib/node-esm/app-graph-builder-4UCMXHYY.mjs.map +0 -7
  208. package/dist/lib/node-esm/chunk-2CKVH7JC.mjs +0 -201
  209. package/dist/lib/node-esm/chunk-2CKVH7JC.mjs.map +0 -7
  210. package/dist/lib/node-esm/chunk-5FXNN3MV.mjs +0 -19
  211. package/dist/lib/node-esm/chunk-5FXNN3MV.mjs.map +0 -7
  212. package/dist/lib/node-esm/chunk-7QRUPEHH.mjs +0 -16
  213. package/dist/lib/node-esm/chunk-7QRUPEHH.mjs.map +0 -7
  214. package/dist/lib/node-esm/chunk-HQLVREIX.mjs +0 -87
  215. package/dist/lib/node-esm/chunk-HQLVREIX.mjs.map +0 -7
  216. package/dist/lib/node-esm/chunk-K7GCM342.mjs +0 -10
  217. package/dist/lib/node-esm/chunk-K7GCM342.mjs.map +0 -7
  218. package/dist/lib/node-esm/chunk-KWKWOGS5.mjs +0 -103
  219. package/dist/lib/node-esm/chunk-KWKWOGS5.mjs.map +0 -7
  220. package/dist/lib/node-esm/chunk-LJAXQ6CX.mjs +0 -249
  221. package/dist/lib/node-esm/chunk-LJAXQ6CX.mjs.map +0 -7
  222. package/dist/lib/node-esm/chunk-RX52VKI2.mjs.map +0 -7
  223. package/dist/lib/node-esm/compute-runtime-ZHROOBLY.mjs +0 -115
  224. package/dist/lib/node-esm/compute-runtime-ZHROOBLY.mjs.map +0 -7
  225. package/dist/lib/node-esm/operation-resolver-R5GA4YNO.mjs +0 -83
  226. package/dist/lib/node-esm/operation-resolver-R5GA4YNO.mjs.map +0 -7
  227. package/dist/lib/node-esm/react-surface-S6VZJCEZ.mjs +0 -66
  228. package/dist/lib/node-esm/react-surface-S6VZJCEZ.mjs.map +0 -7
  229. package/dist/types/src/capabilities/app-graph-builder/app-graph-builder.d.ts +0 -6
  230. package/dist/types/src/capabilities/app-graph-builder/app-graph-builder.d.ts.map +0 -1
  231. package/dist/types/src/capabilities/app-graph-builder/index.d.ts +0 -3
  232. package/dist/types/src/capabilities/app-graph-builder/index.d.ts.map +0 -1
  233. package/dist/types/src/capabilities/compute-runtime/compute-runtime.d.ts +0 -6
  234. package/dist/types/src/capabilities/compute-runtime/compute-runtime.d.ts.map +0 -1
  235. package/dist/types/src/capabilities/compute-runtime/index.d.ts +0 -3
  236. package/dist/types/src/capabilities/compute-runtime/index.d.ts.map +0 -1
  237. package/dist/types/src/capabilities/operation-resolver/index.d.ts +0 -3
  238. package/dist/types/src/capabilities/operation-resolver/index.d.ts.map +0 -1
  239. package/dist/types/src/capabilities/operation-resolver/operation-resolver.d.ts +0 -5
  240. package/dist/types/src/capabilities/operation-resolver/operation-resolver.d.ts.map +0 -1
  241. package/dist/types/src/capabilities/react-surface/index.d.ts +0 -3
  242. package/dist/types/src/capabilities/react-surface/index.d.ts.map +0 -1
  243. package/dist/types/src/capabilities/react-surface/react-surface.d.ts +0 -5
  244. package/dist/types/src/capabilities/react-surface/react-surface.d.ts.map +0 -1
  245. package/dist/types/src/components/AutomationSettings.d.ts +0 -5
  246. package/dist/types/src/components/AutomationSettings.d.ts.map +0 -1
  247. package/dist/types/src/components/FunctionsContainer.d.ts.map +0 -1
  248. package/dist/types/src/components/TriggerSettings.d.ts.map +0 -1
  249. package/src/capabilities/app-graph-builder/app-graph-builder.ts +0 -71
  250. package/src/capabilities/app-graph-builder/index.ts +0 -7
  251. package/src/capabilities/compute-runtime/compute-runtime.ts +0 -133
  252. package/src/capabilities/operation-resolver/index.ts +0 -7
  253. package/src/capabilities/operation-resolver/operation-resolver.ts +0 -79
  254. package/src/capabilities/react-surface/index.ts +0 -7
  255. package/src/capabilities/react-surface/react-surface.tsx +0 -60
  256. package/src/components/AutomationSettings.tsx +0 -30
  257. package/src/components/FunctionsContainer.tsx +0 -36
  258. /package/dist/lib/browser/{AutomationPanel-FAS6ADCW.mjs.map → chunk-J5LGTIGS.mjs.map} +0 -0
  259. /package/dist/lib/{browser/FunctionsPanel-ZX4J75UM.mjs.map → node-esm/chunk-HSLMI22Q.mjs.map} +0 -0
  260. /package/dist/types/src/{components → containers/TriggerSettings}/TriggerSettings.d.ts +0 -0
  261. /package/src/capabilities/{compute-runtime/index.ts → node.ts} +0 -0
@@ -5,14 +5,16 @@
5
5
  import { type Meta, type StoryObj } from '@storybook/react-vite';
6
6
  import React from 'react';
7
7
 
8
- import { Function, Trigger } from '@dxos/functions';
8
+ import { Obj } from '@dxos/echo';
9
+ import { Trigger } from '@dxos/functions';
10
+ import { Operation } from '@dxos/operation';
9
11
  import { useSpaces } from '@dxos/react-client/echo';
10
12
  import { withClientProvider } from '@dxos/react-client/testing';
11
13
  import { withTheme } from '@dxos/react-ui/testing';
12
14
 
13
- import { functions } from '../../testing';
14
- import { translations } from '../../translations';
15
+ import { functions } from '#testing';
15
16
 
17
+ import { translations } from '../../translations';
16
18
  import { AutomationPanel } from './AutomationPanel';
17
19
 
18
20
  const DefaultStory = () => {
@@ -20,25 +22,25 @@ const DefaultStory = () => {
20
22
  const space = spaces[1];
21
23
 
22
24
  return (
23
- <div className='is-96'>
25
+ <div className='w-96'>
24
26
  <AutomationPanel space={space} />
25
27
  </div>
26
28
  );
27
29
  };
28
30
 
29
31
  const meta = {
30
- title: 'plugins/plugin-automation/AutomationPanel',
32
+ title: 'plugins/plugin-automation/components/AutomationPanel',
31
33
  component: AutomationPanel as any,
32
34
  render: DefaultStory,
33
35
  decorators: [
34
- withTheme,
36
+ withTheme(),
35
37
  withClientProvider({
36
38
  createIdentity: true,
37
39
  createSpace: true,
38
- types: [Function.Function, Trigger.Trigger],
40
+ types: [Operation.PersistentOperation, Trigger.Trigger],
39
41
  onCreateSpace: ({ space }) => {
40
42
  for (const fn of functions) {
41
- space.db.add(Function.make(fn));
43
+ space.db.add(Obj.make(Operation.PersistentOperation, { ...fn, version: fn.version ?? '0.1.0' }));
42
44
  }
43
45
  },
44
46
  }),
@@ -6,39 +6,43 @@ 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';
14
+ import { Script, Trigger } from '@dxos/functions';
15
+ import { KEY_QUEUE_CURSOR } from '@dxos/functions-runtime';
13
16
  import { FunctionsServiceClient } from '@dxos/functions-runtime/edge';
14
- import { useTypeOptions } from '@dxos/plugin-space';
17
+ import { Operation } from '@dxos/operation';
15
18
  import { type Client, useClient } from '@dxos/react-client';
16
- import { type Space, useQuery } from '@dxos/react-client/echo';
17
- import { Clipboard, IconButton, Input, Separator, type ThemedClassName, useTranslation } from '@dxos/react-ui';
18
- 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';
19
22
  import { List } from '@dxos/react-ui-list';
20
- import { Project } from '@dxos/types';
23
+ import { Pipeline } from '@dxos/types';
21
24
  import { ghostHover, mx } from '@dxos/ui-theme';
22
25
  import { isNonNullable } from '@dxos/util';
23
26
 
24
- import { meta } from '../../meta';
27
+ import { meta } from '#meta';
28
+
25
29
  import { TriggerEditor, type TriggerEditorProps } from '../TriggerEditor';
26
30
 
27
- const grid = 'grid grid-cols-[40px_1fr_32px_32px] min-bs-[2.5rem]';
31
+ const grid = 'grid grid-cols-[40px_1fr_32px_32px] min-h-[2.5rem]';
28
32
 
29
- export type AutomationPanelProps = ThemedClassName<{
33
+ export type AutomationPanelProps = {
30
34
  space: Space;
31
35
  object?: Obj.Unknown;
32
36
  initialTrigger?: Trigger.Trigger;
33
37
  onDone?: () => void;
34
- }>;
38
+ };
35
39
 
36
40
  // TODO(burdon): Factor out common layout with ViewEditor.
37
- export const AutomationPanel = ({ classNames, space, object, initialTrigger, onDone }: AutomationPanelProps) => {
41
+ export const AutomationPanel = ({ space, object, initialTrigger, onDone }: AutomationPanelProps) => {
38
42
  const { t } = useTranslation(meta.id);
39
43
  const client = useClient();
40
44
  const functionsServiceClient = useMemo(() => FunctionsServiceClient.fromClient(client), [client]);
41
- const functions = useQuery(space.db, Filter.type(Function.Function));
45
+ const functions = useQuery(space.db, Filter.type(Operation.PersistentOperation));
42
46
  const triggers = useQuery(space.db, Filter.type(Trigger.Trigger));
43
47
  const filteredTriggers = useMemo(() => {
44
48
  return object ? triggers.filter(triggerMatch(object)) : triggers;
@@ -49,7 +53,6 @@ export const AutomationPanel = ({ classNames, space, object, initialTrigger, onD
49
53
  annotation: {
50
54
  location: ['database', 'runtime'],
51
55
  kind: ['user'],
52
- registered: ['registered'],
53
56
  },
54
57
  });
55
58
 
@@ -74,7 +77,9 @@ export const AutomationPanel = ({ classNames, space, object, initialTrigger, onD
74
77
 
75
78
  const handleSave: TriggerEditorProps['onSave'] = (trigger) => {
76
79
  if (selected) {
77
- Object.assign(selected, trigger);
80
+ Obj.change(selected, (selected) => {
81
+ Object.assign(selected, trigger);
82
+ });
78
83
  } else {
79
84
  space.db.add(Trigger.make(trigger));
80
85
  }
@@ -90,12 +95,19 @@ export const AutomationPanel = ({ classNames, space, object, initialTrigger, onD
90
95
  };
91
96
 
92
97
  const handleForceRunTrigger = async (trigger: Trigger.Trigger) => {
93
- await functionsServiceClient.forceRunCronTrigger(space.id, trigger.id);
98
+ await functionsServiceClient.forceRunCronTrigger(Context.default(), space.id, trigger.id);
99
+ };
100
+
101
+ const handleResetCursor = async (trigger: Trigger.Trigger) => {
102
+ Obj.change(trigger, (trigger) => {
103
+ Obj.deleteKeys(trigger, KEY_QUEUE_CURSOR);
104
+ });
105
+ await space.db.flush({ indexes: true });
94
106
  };
95
107
 
96
108
  if (trigger) {
97
109
  return (
98
- <ControlItem title={t('trigger editor title')}>
110
+ <Settings.Item title={t('trigger-editor.title')} description={t('trigger-editor.description')}>
99
111
  <TriggerEditor
100
112
  db={space.db}
101
113
  trigger={trigger}
@@ -105,88 +117,149 @@ export const AutomationPanel = ({ classNames, space, object, initialTrigger, onD
105
117
  onSave={handleSave}
106
118
  onCancel={handleCancel}
107
119
  />
108
- </ControlItem>
120
+ </Settings.Item>
109
121
  );
110
122
  }
111
123
 
112
124
  return (
113
- <div className={mx(controlItemClasses, classNames)}>
114
- {filteredTriggers.length > 0 && (
115
- <List.Root<Trigger.Trigger>
116
- items={filteredTriggers}
117
- isItem={Schema.is(Trigger.Trigger)}
118
- getId={(field) => field.id}
119
- >
120
- {({ items: filteredTriggers }) => (
121
- <div role='list' className='flex flex-col is-full'>
122
- {filteredTriggers?.map((trigger) => {
123
- const copyAction = getCopyAction(client, trigger);
124
- return (
125
- <List.Item<Trigger.Trigger>
125
+ <Settings.Panel>
126
+ <Clipboard.Provider>
127
+ {filteredTriggers.length > 0 && (
128
+ <List.Root<Trigger.Trigger>
129
+ items={filteredTriggers}
130
+ isItem={Schema.is(Trigger.Trigger)}
131
+ getId={(field) => field.id}
132
+ >
133
+ {({ items: filteredTriggers }) => (
134
+ <div role='list' className='flex flex-col w-full'>
135
+ {filteredTriggers?.map((trigger) => (
136
+ <TriggerListItem
126
137
  key={trigger.id}
127
- item={trigger}
128
- classNames={mx(grid, ghostHover, 'items-center', 'pli-2')}
129
- >
130
- <Input.Root>
131
- <Input.Switch
132
- checked={trigger.enabled}
133
- onCheckedChange={(checked) =>
134
- Obj.change(trigger, (t) => {
135
- t.enabled = checked;
136
- })
137
- }
138
- />
139
- </Input.Root>
140
-
141
- <div className={'flex'}>
142
- <List.ItemTitle
143
- classNames='pli-1 cursor-pointer is-0 shrink truncate'
144
- onClick={() => handleSelect(trigger)}
145
- >
146
- {getFunctionName(functions, trigger) ?? '∅'}
147
- </List.ItemTitle>
148
-
149
- {/* TODO: a better way to expose copy action */}
150
- {copyAction && (
151
- <Clipboard.IconButton
152
- label={t(copyAction.translationKey)}
153
- value={copyAction.contentProvider()}
154
- />
155
- )}
156
- </div>
157
-
158
- <List.ItemButton
159
- autoHide={false}
160
- disabled={!trigger.enabled || trigger.spec?.kind !== 'timer'}
161
- icon='ph--play--regular'
162
- label='Force run'
163
- onClick={() => handleForceRunTrigger(trigger)}
164
- />
165
-
166
- <List.ItemDeleteButton onClick={() => handleDelete(trigger)} />
167
- </List.Item>
168
- );
169
- })}
170
- </div>
171
- )}
172
- </List.Root>
173
- )}
174
- {filteredTriggers.length > 0 && <Separator classNames='mlb-4' />}
175
- <IconButton icon='ph--plus--regular' label={t('new trigger label')} onClick={handleAdd} />
176
- </div>
138
+ trigger={trigger}
139
+ functions={functions}
140
+ onSelect={handleSelect}
141
+ onDelete={handleDelete}
142
+ onResetCursor={handleResetCursor}
143
+ onForceRun={handleForceRunTrigger}
144
+ />
145
+ ))}
146
+ </div>
147
+ )}
148
+ </List.Root>
149
+ )}
150
+
151
+ {filteredTriggers.length > 0 && <Separator classNames='my-4' />}
152
+ <IconButton icon='ph--plus--regular' label={t('new-trigger.label')} onClick={handleAdd} />
153
+ </Clipboard.Provider>
154
+ </Settings.Panel>
155
+ );
156
+ };
157
+
158
+ const TriggerListItem = ({
159
+ trigger,
160
+ functions,
161
+ onSelect,
162
+ onDelete,
163
+ onResetCursor,
164
+ onForceRun,
165
+ }: {
166
+ trigger: Trigger.Trigger;
167
+ functions: Operation.PersistentOperation[];
168
+ onSelect?: (trigger: Trigger.Trigger) => void;
169
+ onDelete?: (trigger: Trigger.Trigger) => void;
170
+ onResetCursor?: (trigger: Trigger.Trigger) => void;
171
+ onForceRun?: (trigger: Trigger.Trigger) => void;
172
+ }) => {
173
+ const client = useClient();
174
+ const copyAction = getCopyAction(client, trigger);
175
+ const { t } = useTranslation(meta.id);
176
+ const cursor = Obj.getKeys(trigger, KEY_QUEUE_CURSOR).at(0)?.id;
177
+ const [snapshot, updateTrigger] = useObject(trigger);
178
+
179
+ const enabled = snapshot.enabled ?? false;
180
+ const onEnabledChange = (checked: boolean) => {
181
+ updateTrigger((trigger) => {
182
+ trigger.enabled = checked;
183
+ });
184
+ };
185
+
186
+ const handleSelect = useCallback(() => {
187
+ onSelect?.(trigger);
188
+ }, [onSelect, trigger]);
189
+
190
+ const handleDelete = useCallback(() => {
191
+ onDelete?.(trigger);
192
+ }, [onDelete, trigger]);
193
+
194
+ const handleResetCursor = useCallback(() => {
195
+ onResetCursor?.(trigger);
196
+ }, [onResetCursor, trigger]);
197
+
198
+ const handleForceRun = useCallback(() => {
199
+ onForceRun?.(trigger);
200
+ }, [onForceRun, trigger]);
201
+
202
+ const actionProps = useMemo<IconButtonProps | undefined>(() => {
203
+ if (trigger.spec?.kind === 'timer' && onForceRun) {
204
+ return {
205
+ disabled: !enabled || trigger.spec?.kind !== 'timer',
206
+ icon: 'ph--play--regular',
207
+ label: 'Force run',
208
+ onClick: handleForceRun,
209
+ };
210
+ }
211
+
212
+ if (trigger.spec?.kind === 'queue' && onResetCursor) {
213
+ return {
214
+ disabled: !cursor,
215
+ icon: 'ph--arrow-clockwise--regular',
216
+ label: 'Reset cursor',
217
+ onClick: handleResetCursor,
218
+ };
219
+ }
220
+ }, [enabled, trigger.spec?.kind, handleForceRun]);
221
+
222
+ return (
223
+ <List.Item<Obj.Snapshot<Trigger.Trigger>>
224
+ key={trigger.id}
225
+ item={snapshot}
226
+ classNames={mx(grid, ghostHover, 'items-center', 'px-2')}
227
+ >
228
+ <Input.Root>
229
+ <Input.Switch checked={enabled} onCheckedChange={onEnabledChange} />
230
+ </Input.Root>
231
+
232
+ <div className={'flex'}>
233
+ <List.ItemTitle classNames='px-1 cursor-pointer w-0 shrink truncate' onClick={handleSelect}>
234
+ {getFunctionName(functions, trigger) ?? '∅'}
235
+ {cursor && <div className='text-xs text-description truncate ml-4'>Position: {cursor}</div>}
236
+ </List.ItemTitle>
237
+
238
+ {copyAction && (
239
+ <Clipboard.IconButton label={t(copyAction.translationKey)} value={copyAction.contentProvider()} />
240
+ )}
241
+ </div>
242
+
243
+ {actionProps ? <List.ItemIconButton {...actionProps} autoHide={false} /> : <div />}
244
+
245
+ {onDelete && <List.ItemDeleteButton onClick={handleDelete} />}
246
+ </List.Item>
177
247
  );
178
248
  };
179
249
 
180
250
  const getCopyAction = (client: Client, trigger: Trigger.Trigger | undefined) => {
181
251
  if (trigger?.spec?.kind === 'email') {
182
252
  return {
183
- translationKey: 'trigger copy email',
253
+ translationKey: 'trigger copy email' as const,
184
254
  contentProvider: () => `${Obj.getDatabase(trigger)!.spaceId}@dxos.network`,
185
255
  };
186
256
  }
187
257
 
188
258
  if (trigger?.spec?.kind === 'webhook') {
189
- return { translationKey: 'trigger copy url', contentProvider: () => getWebhookUrl(client, trigger) };
259
+ return {
260
+ translationKey: 'trigger copy url' as const,
261
+ contentProvider: () => getWebhookUrl(client, trigger!),
262
+ };
190
263
  }
191
264
 
192
265
  return undefined;
@@ -200,7 +273,7 @@ const getWebhookUrl = (client: Client, trigger: Trigger.Trigger) => {
200
273
  return new URL(`/webhook/${spaceId}:${trigger.id}`, edgeUrl).toString();
201
274
  };
202
275
 
203
- const getFunctionName = (functions: Function.Function[], trigger: Trigger.Trigger) => {
276
+ const getFunctionName = (functions: Operation.PersistentOperation[], trigger: Trigger.Trigger) => {
204
277
  // TODO(wittjosiah): Truncation should be done in the UI.
205
278
  // Warning that the List component is currently a can of worms.
206
279
  const shortId = trigger.function && `${trigger.function.dxn.toString().slice(0, 16)}…`;
@@ -210,14 +283,14 @@ const getFunctionName = (functions: Function.Function[], trigger: Trigger.Trigge
210
283
 
211
284
  const scriptMatch = (script: Script.Script) => (trigger: Trigger.Trigger) => {
212
285
  const fn = trigger.function?.target;
213
- if (!Obj.instanceOf(Function.Function, fn)) {
286
+ if (!Obj.instanceOf(Operation.PersistentOperation, fn)) {
214
287
  return false;
215
288
  }
216
289
 
217
290
  return fn.source?.target === script;
218
291
  };
219
292
 
220
- const projectMatch = (project: Project.Project) => {
293
+ const projectMatch = (project: Pipeline.Pipeline) => {
221
294
  const viewQueries = EFn.pipe(
222
295
  project.columns,
223
296
  Array.map((column) => column.view.target),
@@ -244,7 +317,7 @@ const triggerMatch = Match.type<Obj.Unknown>().pipe(
244
317
  (obj) => scriptMatch(obj),
245
318
  ),
246
319
  Match.when(
247
- (obj) => Obj.instanceOf(Project.Project, obj),
320
+ (obj) => Obj.instanceOf(Pipeline.Pipeline, obj),
248
321
  (obj) => projectMatch(obj),
249
322
  ),
250
323
  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 { Common } from '@dxos/app-framework';
9
- import { useOperationInvoker } from '@dxos/app-framework/react';
10
- import { Obj } from '@dxos/echo';
11
- import { Function, Script } from '@dxos/functions';
12
- import { SpaceOperation } 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
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,7 +24,7 @@ export type FunctionsPanelProps = {
26
24
 
27
25
  export const FunctionsPanel = ({ space }: FunctionsPanelProps) => {
28
26
  const { t } = useTranslation(meta.id);
29
- const functions = useQuery(space.db, Filter.type(Function.Function));
27
+ const functions = useQuery(space.db, Filter.type(Operation.PersistentOperation));
30
28
  const scripts = useQuery(space.db, Filter.type(Script.Script));
31
29
  const { invokePromise } = useOperationInvoker();
32
30
 
@@ -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,45 +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 invokePromise(Common.LayoutOperation.Open, { subject: [Obj.getDXN(script).toString()] });
61
+ void invokePromise(LayoutOperation.Open, { subject: [getObjectPathFromObject(script)] });
64
62
  }
65
63
  },
66
64
  [functionToScriptMap, invokePromise],
67
65
  );
68
66
 
69
67
  const handleDelete = useCallback(
70
- (func: Function.Function) => invokePromise(SpaceOperation.RemoveObjects, { objects: [func] }),
68
+ (func: Operation.PersistentOperation) => invokePromise(SpaceOperation.RemoveObjects, { objects: [func] }),
71
69
  [invokePromise],
72
70
  );
73
71
 
74
72
  return (
75
- <div role='none' className={mx(controlItemClasses)}>
73
+ <Settings.Panel>
76
74
  {functions.length > 0 && (
77
- <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
+ >
78
80
  {({ items }) => (
79
- <div role='list' className='flex flex-col is-full'>
81
+ <div role='list' className='flex flex-col w-full'>
80
82
  {items?.map((func) => (
81
- <List.Item<Function.Function>
83
+ <List.Item<Operation.PersistentOperation>
82
84
  key={func.id}
83
85
  item={func}
84
- 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
+ )}
85
90
  >
86
91
  <div className='flex flex-col truncate'>
87
92
  <List.ItemTitle classNames='truncate'>{func.name}</List.ItemTitle>
88
- {getScriptName(func) && (
89
- <div className='text-xs text-description truncate'>{getScriptName(func)}</div>
90
- )}
93
+ {getScriptName(func) && <p className='text-xs text-description truncate'>{getScriptName(func)}</p>}
91
94
  </div>
92
- {functionToScriptMap[func.id] && (
93
- <Button onClick={() => handleGoToScript(func)}>{t('go to function source button label')}</Button>
94
- )}
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 />}
95
103
  <IconButton
96
- iconOnly
97
104
  icon='ph--trash--regular'
98
- label={t('delete function button label')}
105
+ iconOnly
106
+ label={t('delete-function-button.label')}
99
107
  onClick={() => handleDelete(func)}
100
108
  />
101
109
  </List.Item>
@@ -104,8 +112,6 @@ export const FunctionsPanel = ({ space }: FunctionsPanelProps) => {
104
112
  )}
105
113
  </List.Root>
106
114
  )}
107
-
108
- {functions.length === 0 && <div className='text-center plb-4 text-gray-500'>{t('no functions found')}</div>}
109
- </div>
115
+ </Settings.Panel>
110
116
  );
111
117
  };
@@ -6,19 +6,19 @@ import * as Schema from 'effect/Schema';
6
6
  import { useState } from 'react';
7
7
  import React, { useCallback } from 'react';
8
8
 
9
- import { Function } from '@dxos/functions';
9
+ import { Context } from '@dxos/context';
10
10
  import { getDeployedFunctions } from '@dxos/functions-runtime/edge';
11
+ import * as OperationModule from '@dxos/operation';
11
12
  import { useClient } from '@dxos/react-client';
12
13
  import { Filter, Query, type Space, useQuery } from '@dxos/react-client/echo';
13
- import { useAsyncEffect } from '@dxos/react-ui';
14
- import { IconButton, useTranslation } from '@dxos/react-ui';
15
- import { controlItemClasses } from '@dxos/react-ui-form';
14
+ import { IconButton, useAsyncEffect, useTranslation } from '@dxos/react-ui';
15
+ import { Settings } from '@dxos/react-ui-form';
16
16
  import { List } from '@dxos/react-ui-list';
17
17
  import { ghostHover, mx } from '@dxos/ui-theme';
18
18
 
19
- import { meta } from '../../meta';
19
+ import { meta } from '#meta';
20
20
 
21
- 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]';
22
22
 
23
23
  type FunctionsRegistryProps = {
24
24
  space: Space;
@@ -27,12 +27,12 @@ type FunctionsRegistryProps = {
27
27
  export const FunctionsRegistry = ({ space }: FunctionsRegistryProps) => {
28
28
  const client = useClient();
29
29
  const [loading, setLoading] = useState(true);
30
- const [functions, setFunctions] = useState<Function.Function[]>([]);
30
+ const [functions, setFunctions] = useState<OperationModule.Operation.PersistentOperation[]>([]);
31
31
  const { t } = useTranslation(meta.id);
32
32
 
33
- const dbFunctions = useQuery(space.db, Filter.type(Function.Function));
33
+ const dbFunctions = useQuery(space.db, Filter.type(OperationModule.Operation.PersistentOperation));
34
34
 
35
- const state = (func: Function.Function) => {
35
+ const state = (func: OperationModule.Operation.PersistentOperation) => {
36
36
  const dbFunction = dbFunctions.find((f) => f.key === func.key);
37
37
  if (!dbFunction) {
38
38
  return 'import';
@@ -45,35 +45,41 @@ export const FunctionsRegistry = ({ space }: FunctionsRegistryProps) => {
45
45
 
46
46
  useAsyncEffect(async () => {
47
47
  setLoading(true);
48
- const functions = await getDeployedFunctions(client, true);
48
+ const functions = await getDeployedFunctions(Context.default(), client, true);
49
49
  setFunctions(functions);
50
50
  setLoading(false);
51
51
  }, []);
52
52
 
53
53
  const hanleImportOrUpdate = useCallback(
54
- async (func: Function.Function) => {
55
- const functions = 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();
56
58
  const [existingFunc] = functions;
57
59
  if (!existingFunc) {
58
60
  space.db.add(func);
59
61
  return;
60
62
  }
61
- Function.setFrom(existingFunc, func);
63
+ OperationModule.Operation.setFrom(existingFunc, func);
62
64
  },
63
65
  [space],
64
66
  );
65
67
 
66
68
  return (
67
- <div role='none' className={mx(controlItemClasses)}>
69
+ <Settings.Panel>
68
70
  {functions.length > 0 && (
69
- <List.Root<Function.Function> items={functions} isItem={Schema.is(Function.Function)} getId={(func) => func.id}>
71
+ <List.Root<OperationModule.Operation.PersistentOperation>
72
+ items={functions}
73
+ isItem={Schema.is(OperationModule.Operation.PersistentOperation)}
74
+ getId={(func) => func.id}
75
+ >
70
76
  {({ items }) => (
71
- <div role='list' className='flex flex-col is-full'>
77
+ <div role='list' className='flex flex-col w-full'>
72
78
  {items?.map((func) => (
73
- <List.Item<Function.Function>
79
+ <List.Item<OperationModule.Operation.PersistentOperation>
74
80
  key={func.id}
75
81
  item={func}
76
- classNames={mx(grid, ghostHover, 'items-center', 'pli-2', 'min-bs-[3rem]')}
82
+ classNames={mx(grid, ghostHover, 'items-center', 'px-2', 'min-h-[3rem]')}
77
83
  >
78
84
  <div className='flex flex-col truncate'>
79
85
  <List.ItemTitle classNames='truncate'>{func.name}</List.ItemTitle>
@@ -90,7 +96,7 @@ export const FunctionsRegistry = ({ space }: FunctionsRegistryProps) => {
90
96
  iconOnly
91
97
  icon={state(func) === 'update' ? 'ph--arrows-clockwise--regular' : 'ph--download--regular'}
92
98
  label={
93
- 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')
94
100
  }
95
101
  disabled={state(func) === 'none'}
96
102
  onClick={() => hanleImportOrUpdate(func)}
@@ -102,10 +108,7 @@ export const FunctionsRegistry = ({ space }: FunctionsRegistryProps) => {
102
108
  </List.Root>
103
109
  )}
104
110
 
105
- {functions.length === 0 && !loading && (
106
- <div className='text-center plb-4 text-gray-500'>{t('no functions found')}</div>
107
- )}
108
- {loading && <div className='text-center plb-4 text-gray-500'>{t('loading functions')}</div>}
109
- </div>
111
+ {loading && <div className='text-center py-4 text-gray-500'>{t('loading-functions.message')}</div>}
112
+ </Settings.Panel>
110
113
  );
111
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;