@dxos/plugin-automation 0.8.4-main.9735255 → 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.
- package/dist/lib/browser/chunk-J5LGTIGS.mjs +10 -0
- package/dist/lib/browser/chunk-POEIL4RN.mjs +44 -0
- package/dist/lib/browser/chunk-POEIL4RN.mjs.map +7 -0
- package/dist/lib/browser/{chunk-JOXPQ27I.mjs → chunk-WQLEMRPU.mjs} +9 -38
- package/dist/lib/browser/chunk-WQLEMRPU.mjs.map +7 -0
- package/dist/lib/browser/cli/index.mjs +122 -107
- package/dist/lib/browser/cli/index.mjs.map +3 -3
- package/dist/lib/browser/create-trigger-from-template-JZ62EZTB.mjs +77 -0
- package/dist/lib/browser/create-trigger-from-template-JZ62EZTB.mjs.map +7 -0
- package/dist/lib/browser/hooks/index.mjs +79 -7
- package/dist/lib/browser/hooks/index.mjs.map +4 -4
- package/dist/lib/browser/index.mjs +60 -92
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/operations/index.mjs +14 -0
- package/dist/lib/browser/operations/index.mjs.map +7 -0
- package/dist/lib/browser/types/index.mjs +4 -4
- package/dist/lib/node-esm/chunk-HSLMI22Q.mjs +11 -0
- package/dist/lib/node-esm/{chunk-RX52VKI2.mjs → chunk-JWZAVQLF.mjs} +9 -37
- package/dist/lib/node-esm/chunk-JWZAVQLF.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-SP3P4OUI.mjs +45 -0
- package/dist/lib/node-esm/chunk-SP3P4OUI.mjs.map +7 -0
- package/dist/lib/node-esm/cli/index.mjs +122 -107
- package/dist/lib/node-esm/cli/index.mjs.map +3 -3
- package/dist/lib/node-esm/create-trigger-from-template-224Z7WJI.mjs +78 -0
- package/dist/lib/node-esm/create-trigger-from-template-224Z7WJI.mjs.map +7 -0
- package/dist/lib/node-esm/hooks/index.mjs +79 -7
- package/dist/lib/node-esm/hooks/index.mjs.map +4 -4
- package/dist/lib/node-esm/index.mjs +60 -92
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/operations/index.mjs +15 -0
- package/dist/lib/node-esm/operations/index.mjs.map +7 -0
- package/dist/lib/node-esm/types/index.mjs +4 -4
- package/dist/types/src/AutomationPlugin.d.ts.map +1 -1
- package/dist/types/src/capabilities/app-graph-builder.d.ts +6 -0
- package/dist/types/src/capabilities/app-graph-builder.d.ts.map +1 -0
- package/dist/types/src/capabilities/compute-runtime.d.ts +6 -0
- package/dist/types/src/capabilities/compute-runtime.d.ts.map +1 -0
- package/dist/types/src/capabilities/index.d.ts +6 -4
- package/dist/types/src/capabilities/index.d.ts.map +1 -1
- package/dist/types/src/capabilities/node.d.ts +3 -0
- package/dist/types/src/capabilities/node.d.ts.map +1 -0
- package/dist/types/src/capabilities/operation-handler.d.ts +6 -0
- package/dist/types/src/capabilities/operation-handler.d.ts.map +1 -0
- package/dist/types/src/capabilities/react-surface.d.ts +5 -0
- package/dist/types/src/capabilities/react-surface.d.ts.map +1 -0
- package/dist/types/src/cli/commands/trigger/create/index.d.ts +1 -1
- package/dist/types/src/cli/commands/trigger/create/queue.d.ts +1 -1
- package/dist/types/src/cli/commands/trigger/create/queue.d.ts.map +1 -1
- package/dist/types/src/cli/commands/trigger/create/subscription.d.ts +1 -1
- package/dist/types/src/cli/commands/trigger/create/subscription.d.ts.map +1 -1
- package/dist/types/src/cli/commands/trigger/create/timer.d.ts +1 -1
- package/dist/types/src/cli/commands/trigger/create/timer.d.ts.map +1 -1
- package/dist/types/src/cli/commands/trigger/list.d.ts +1 -1
- package/dist/types/src/cli/commands/trigger/list.d.ts.map +1 -1
- package/dist/types/src/cli/commands/trigger/remove.d.ts +1 -1
- package/dist/types/src/cli/commands/trigger/update/queue.d.ts.map +1 -1
- package/dist/types/src/cli/commands/trigger/update/subscription.d.ts.map +1 -1
- package/dist/types/src/cli/commands/trigger/update/timer.d.ts.map +1 -1
- package/dist/types/src/cli/commands/trigger/util.d.ts +2 -2
- package/dist/types/src/cli/commands/trigger/util.d.ts.map +1 -1
- package/dist/types/src/cli/plugin.d.ts.map +1 -1
- package/dist/types/src/components/AutomationPanel/AutomationPanel.d.ts +3 -4
- package/dist/types/src/components/AutomationPanel/AutomationPanel.d.ts.map +1 -1
- package/dist/types/src/components/AutomationPanel/AutomationPanel.stories.d.ts +28 -30
- package/dist/types/src/components/AutomationPanel/AutomationPanel.stories.d.ts.map +1 -1
- package/dist/types/src/components/FunctionsPanel/FunctionsPanel.d.ts.map +1 -1
- package/dist/types/src/components/FunctionsRegistry/FunctionsRegistry.d.ts.map +1 -1
- package/dist/types/src/components/FunctionsRegistry/index.d.ts +3 -1
- package/dist/types/src/components/FunctionsRegistry/index.d.ts.map +1 -1
- package/dist/types/src/components/TriggerEditor/FunctionInputEditor.d.ts +2 -2
- package/dist/types/src/components/TriggerEditor/FunctionInputEditor.d.ts.map +1 -1
- package/dist/types/src/components/TriggerEditor/SpecSelector.d.ts.map +1 -1
- package/dist/types/src/components/TriggerEditor/TriggerEditor.d.ts.map +1 -1
- package/dist/types/src/components/TriggerEditor/TriggerEditor.stories.d.ts +91 -91
- package/dist/types/src/components/TriggerEditor/TriggerEditor.stories.d.ts.map +1 -1
- package/dist/types/src/components/index.d.ts +3 -4
- package/dist/types/src/components/index.d.ts.map +1 -1
- package/dist/types/src/containers/AutomationSettings/AutomationSettings.d.ts +4 -0
- package/dist/types/src/containers/AutomationSettings/AutomationSettings.d.ts.map +1 -0
- package/dist/types/src/containers/AutomationSettings/index.d.ts +2 -0
- package/dist/types/src/containers/AutomationSettings/index.d.ts.map +1 -0
- package/dist/types/src/{components → containers/FunctionsContainer}/FunctionsContainer.d.ts +0 -1
- package/dist/types/src/containers/FunctionsContainer/FunctionsContainer.d.ts.map +1 -0
- package/dist/types/src/containers/FunctionsContainer/index.d.ts +2 -0
- package/dist/types/src/containers/FunctionsContainer/index.d.ts.map +1 -0
- package/dist/types/src/containers/TriggerSettings/TriggerSettings.d.ts.map +1 -0
- package/dist/types/src/containers/TriggerSettings/index.d.ts +3 -0
- package/dist/types/src/containers/TriggerSettings/index.d.ts.map +1 -0
- package/dist/types/src/containers/index.d.ts +5 -0
- package/dist/types/src/containers/index.d.ts.map +1 -0
- package/dist/types/src/hooks/index.d.ts +2 -0
- package/dist/types/src/hooks/index.d.ts.map +1 -1
- package/dist/types/src/hooks/useComputeRuntime.d.ts +7 -0
- package/dist/types/src/hooks/useComputeRuntime.d.ts.map +1 -0
- package/dist/types/src/hooks/useComputeRuntimeCallback.d.ts +1 -4
- package/dist/types/src/hooks/useComputeRuntimeCallback.d.ts.map +1 -1
- package/dist/types/src/hooks/useComputeRuntimeService.d.ts +5 -0
- package/dist/types/src/hooks/useComputeRuntimeService.d.ts.map +1 -0
- package/dist/types/src/hooks/useTriggerRuntimeControls.d.ts +2 -1
- package/dist/types/src/hooks/useTriggerRuntimeControls.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +2 -5
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/operations/create-trigger-from-template.d.ts +5 -0
- package/dist/types/src/operations/create-trigger-from-template.d.ts.map +1 -0
- package/dist/types/src/operations/definitions.d.ts +19 -0
- package/dist/types/src/operations/definitions.d.ts.map +1 -0
- package/dist/types/src/operations/index.d.ts +4 -0
- package/dist/types/src/operations/index.d.ts.map +1 -0
- package/dist/types/src/testing/test-functions.d.ts +2 -0
- package/dist/types/src/testing/test-functions.d.ts.map +1 -1
- package/dist/types/src/translations.d.ts +29 -31
- package/dist/types/src/translations.d.ts.map +1 -1
- package/dist/types/src/types/capabilities.d.ts +6 -3
- package/dist/types/src/types/capabilities.d.ts.map +1 -1
- package/dist/types/src/types/schema.d.ts +9 -30
- package/dist/types/src/types/schema.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +73 -46
- package/src/AutomationPlugin.tsx +13 -10
- package/src/capabilities/app-graph-builder.ts +62 -0
- package/src/capabilities/compute-runtime.ts +248 -0
- package/src/capabilities/index.ts +10 -4
- package/src/capabilities/operation-handler.ts +16 -0
- package/src/capabilities/react-surface.tsx +59 -0
- package/src/cli/commands/trigger/create/queue.ts +7 -6
- package/src/cli/commands/trigger/create/subscription.ts +7 -6
- package/src/cli/commands/trigger/create/timer.ts +7 -6
- package/src/cli/commands/trigger/list.ts +3 -2
- package/src/cli/commands/trigger/remove.ts +2 -2
- package/src/cli/commands/trigger/update/queue.ts +21 -21
- package/src/cli/commands/trigger/update/subscription.ts +20 -19
- package/src/cli/commands/trigger/update/timer.ts +21 -20
- package/src/cli/commands/trigger/util.ts +43 -29
- package/src/cli/plugin.ts +6 -6
- package/src/components/AutomationPanel/AutomationPanel.stories.tsx +10 -8
- package/src/components/AutomationPanel/AutomationPanel.tsx +160 -87
- package/src/components/FunctionsPanel/FunctionsPanel.tsx +37 -31
- package/src/components/FunctionsRegistry/FunctionsRegistry.tsx +27 -24
- package/src/components/FunctionsRegistry/index.ts +4 -1
- package/src/components/TriggerEditor/FunctionInputEditor.tsx +17 -8
- package/src/components/TriggerEditor/SpecSelector.tsx +12 -3
- package/src/components/TriggerEditor/TriggerEditor.stories.tsx +56 -13
- package/src/components/TriggerEditor/TriggerEditor.tsx +46 -17
- package/src/components/index.ts +1 -2
- package/src/containers/AutomationSettings/AutomationSettings.tsx +28 -0
- package/src/containers/AutomationSettings/index.ts +5 -0
- package/src/containers/FunctionsContainer/FunctionsContainer.tsx +34 -0
- package/src/containers/FunctionsContainer/index.ts +5 -0
- package/src/{components → containers/TriggerSettings}/TriggerSettings.tsx +8 -7
- package/src/containers/TriggerSettings/index.ts +6 -0
- package/src/containers/index.ts +9 -0
- package/src/hooks/index.ts +3 -0
- package/src/hooks/useComputeRuntime.ts +16 -0
- package/src/hooks/useComputeRuntimeCallback.ts +4 -39
- package/src/hooks/useComputeRuntimeService.ts +24 -0
- package/src/hooks/useTriggerRuntimeControls.ts +22 -8
- package/src/index.ts +2 -6
- package/src/meta.ts +2 -2
- package/src/operations/create-trigger-from-template.ts +75 -0
- package/src/operations/definitions.ts +28 -0
- package/src/operations/index.ts +9 -0
- package/src/testing/test-functions.ts +8 -5
- package/src/translations.ts +35 -36
- package/src/types/capabilities.ts +20 -6
- package/src/types/events.ts +2 -2
- package/src/types/schema.ts +3 -24
- package/dist/lib/browser/AutomationPanel-FAS6ADCW.mjs +0 -11
- package/dist/lib/browser/AutomationSettings-XN2OIYWL.mjs +0 -56
- package/dist/lib/browser/AutomationSettings-XN2OIYWL.mjs.map +0 -7
- package/dist/lib/browser/FunctionsContainer-6QLC7JP4.mjs +0 -129
- package/dist/lib/browser/FunctionsContainer-6QLC7JP4.mjs.map +0 -7
- package/dist/lib/browser/FunctionsPanel-ZX4J75UM.mjs +0 -10
- package/dist/lib/browser/app-graph-builder-LAQMEBMH.mjs +0 -84
- package/dist/lib/browser/app-graph-builder-LAQMEBMH.mjs.map +0 -7
- package/dist/lib/browser/chunk-54PANILA.mjs +0 -14
- package/dist/lib/browser/chunk-54PANILA.mjs.map +0 -7
- package/dist/lib/browser/chunk-BFUIVUQH.mjs +0 -102
- package/dist/lib/browser/chunk-BFUIVUQH.mjs.map +0 -7
- package/dist/lib/browser/chunk-BKFQBKYO.mjs +0 -8
- package/dist/lib/browser/chunk-BKFQBKYO.mjs.map +0 -7
- package/dist/lib/browser/chunk-JOXPQ27I.mjs.map +0 -7
- package/dist/lib/browser/chunk-PZNBEKO5.mjs +0 -17
- package/dist/lib/browser/chunk-PZNBEKO5.mjs.map +0 -7
- package/dist/lib/browser/chunk-QW3EM35H.mjs +0 -248
- package/dist/lib/browser/chunk-QW3EM35H.mjs.map +0 -7
- package/dist/lib/browser/chunk-RAF2FJST.mjs +0 -86
- package/dist/lib/browser/chunk-RAF2FJST.mjs.map +0 -7
- package/dist/lib/browser/chunk-YWLEY2FD.mjs +0 -200
- package/dist/lib/browser/chunk-YWLEY2FD.mjs.map +0 -7
- package/dist/lib/browser/compute-runtime-WTWLQ67J.mjs +0 -114
- package/dist/lib/browser/compute-runtime-WTWLQ67J.mjs.map +0 -7
- package/dist/lib/browser/operation-resolver-Q3MWOR7K.mjs +0 -82
- package/dist/lib/browser/operation-resolver-Q3MWOR7K.mjs.map +0 -7
- package/dist/lib/browser/react-surface-EV3AC62F.mjs +0 -65
- package/dist/lib/browser/react-surface-EV3AC62F.mjs.map +0 -7
- package/dist/lib/node-esm/AutomationPanel-B7NAGDFA.mjs +0 -12
- package/dist/lib/node-esm/AutomationPanel-B7NAGDFA.mjs.map +0 -7
- package/dist/lib/node-esm/AutomationSettings-M5PMZJ6P.mjs +0 -57
- package/dist/lib/node-esm/AutomationSettings-M5PMZJ6P.mjs.map +0 -7
- package/dist/lib/node-esm/FunctionsContainer-J4O2ULWR.mjs +0 -130
- package/dist/lib/node-esm/FunctionsContainer-J4O2ULWR.mjs.map +0 -7
- package/dist/lib/node-esm/FunctionsPanel-SS6GIVNU.mjs +0 -11
- package/dist/lib/node-esm/FunctionsPanel-SS6GIVNU.mjs.map +0 -7
- package/dist/lib/node-esm/app-graph-builder-4UCMXHYY.mjs +0 -85
- package/dist/lib/node-esm/app-graph-builder-4UCMXHYY.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-2CKVH7JC.mjs +0 -201
- package/dist/lib/node-esm/chunk-2CKVH7JC.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-5FXNN3MV.mjs +0 -19
- package/dist/lib/node-esm/chunk-5FXNN3MV.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-7QRUPEHH.mjs +0 -16
- package/dist/lib/node-esm/chunk-7QRUPEHH.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-HQLVREIX.mjs +0 -87
- package/dist/lib/node-esm/chunk-HQLVREIX.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-K7GCM342.mjs +0 -10
- package/dist/lib/node-esm/chunk-K7GCM342.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-KWKWOGS5.mjs +0 -103
- package/dist/lib/node-esm/chunk-KWKWOGS5.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-LJAXQ6CX.mjs +0 -249
- package/dist/lib/node-esm/chunk-LJAXQ6CX.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-RX52VKI2.mjs.map +0 -7
- package/dist/lib/node-esm/compute-runtime-ZHROOBLY.mjs +0 -115
- package/dist/lib/node-esm/compute-runtime-ZHROOBLY.mjs.map +0 -7
- package/dist/lib/node-esm/operation-resolver-R5GA4YNO.mjs +0 -83
- package/dist/lib/node-esm/operation-resolver-R5GA4YNO.mjs.map +0 -7
- package/dist/lib/node-esm/react-surface-S6VZJCEZ.mjs +0 -66
- package/dist/lib/node-esm/react-surface-S6VZJCEZ.mjs.map +0 -7
- package/dist/types/src/capabilities/app-graph-builder/app-graph-builder.d.ts +0 -6
- package/dist/types/src/capabilities/app-graph-builder/app-graph-builder.d.ts.map +0 -1
- package/dist/types/src/capabilities/app-graph-builder/index.d.ts +0 -3
- package/dist/types/src/capabilities/app-graph-builder/index.d.ts.map +0 -1
- package/dist/types/src/capabilities/compute-runtime/compute-runtime.d.ts +0 -6
- package/dist/types/src/capabilities/compute-runtime/compute-runtime.d.ts.map +0 -1
- package/dist/types/src/capabilities/compute-runtime/index.d.ts +0 -3
- package/dist/types/src/capabilities/compute-runtime/index.d.ts.map +0 -1
- package/dist/types/src/capabilities/operation-resolver/index.d.ts +0 -3
- package/dist/types/src/capabilities/operation-resolver/index.d.ts.map +0 -1
- package/dist/types/src/capabilities/operation-resolver/operation-resolver.d.ts +0 -5
- package/dist/types/src/capabilities/operation-resolver/operation-resolver.d.ts.map +0 -1
- package/dist/types/src/capabilities/react-surface/index.d.ts +0 -3
- package/dist/types/src/capabilities/react-surface/index.d.ts.map +0 -1
- package/dist/types/src/capabilities/react-surface/react-surface.d.ts +0 -5
- package/dist/types/src/capabilities/react-surface/react-surface.d.ts.map +0 -1
- package/dist/types/src/components/AutomationSettings.d.ts +0 -5
- package/dist/types/src/components/AutomationSettings.d.ts.map +0 -1
- package/dist/types/src/components/FunctionsContainer.d.ts.map +0 -1
- package/dist/types/src/components/TriggerSettings.d.ts.map +0 -1
- package/src/capabilities/app-graph-builder/app-graph-builder.ts +0 -71
- package/src/capabilities/app-graph-builder/index.ts +0 -7
- package/src/capabilities/compute-runtime/compute-runtime.ts +0 -133
- package/src/capabilities/operation-resolver/index.ts +0 -7
- package/src/capabilities/operation-resolver/operation-resolver.ts +0 -79
- package/src/capabilities/react-surface/index.ts +0 -7
- package/src/capabilities/react-surface/react-surface.tsx +0 -60
- package/src/components/AutomationSettings.tsx +0 -30
- package/src/components/FunctionsContainer.tsx +0 -36
- /package/dist/lib/browser/{AutomationPanel-FAS6ADCW.mjs.map → chunk-J5LGTIGS.mjs.map} +0 -0
- /package/dist/lib/{browser/FunctionsPanel-ZX4J75UM.mjs.map → node-esm/chunk-HSLMI22Q.mjs.map} +0 -0
- /package/dist/types/src/{components → containers/TriggerSettings}/TriggerSettings.d.ts +0 -0
- /package/src/capabilities/{compute-runtime/index.ts → node.ts} +0 -0
|
@@ -5,17 +5,17 @@
|
|
|
5
5
|
import type * as SchemaAST from 'effect/SchemaAST';
|
|
6
6
|
import React, { useCallback, useMemo } from 'react';
|
|
7
7
|
|
|
8
|
-
import { type Database,
|
|
8
|
+
import { type Database, JsonSchema, Obj, Ref } from '@dxos/echo';
|
|
9
9
|
import { type JsonPath } from '@dxos/echo/internal';
|
|
10
|
-
import { type
|
|
10
|
+
import { type Operation } from '@dxos/operation';
|
|
11
11
|
import { useOnTransition, useTranslation } from '@dxos/react-ui';
|
|
12
12
|
import { Form, type FormFieldStateProps, type FormRootProps, useFormValues } from '@dxos/react-ui-form';
|
|
13
13
|
|
|
14
|
-
import { meta } from '
|
|
14
|
+
import { meta } from '#meta';
|
|
15
15
|
|
|
16
16
|
export type FunctionInputEditorProps = {
|
|
17
17
|
type: SchemaAST.AST;
|
|
18
|
-
functions:
|
|
18
|
+
functions: Operation.PersistentOperation[];
|
|
19
19
|
db?: Database.Database;
|
|
20
20
|
} & FormFieldStateProps;
|
|
21
21
|
|
|
@@ -48,9 +48,12 @@ export const FunctionInputEditor = ({ type, functions, db, getValue, onValueChan
|
|
|
48
48
|
);
|
|
49
49
|
|
|
50
50
|
const inputSchema = useMemo(() => selectedFunction?.inputSchema, [selectedFunction]);
|
|
51
|
-
const effectSchema = useMemo(() => (inputSchema ?
|
|
51
|
+
const effectSchema = useMemo(() => (inputSchema ? JsonSchema.toEffectSchema(inputSchema) : undefined), [inputSchema]);
|
|
52
52
|
const propertyCount = inputSchema?.properties ? Object.keys(inputSchema.properties).length : 0;
|
|
53
|
-
const
|
|
53
|
+
const defaultValues = useMemo(() => {
|
|
54
|
+
const raw = getValue() ?? {};
|
|
55
|
+
return Obj.isObject(raw) ? { ...Obj.getSnapshot(raw) } : { ...raw };
|
|
56
|
+
}, [getValue]);
|
|
54
57
|
|
|
55
58
|
const handleValuesChanged = useCallback<NonNullable<FormRootProps['onValuesChanged']>>(
|
|
56
59
|
(values) => {
|
|
@@ -65,8 +68,14 @@ export const FunctionInputEditor = ({ type, functions, db, getValue, onValueChan
|
|
|
65
68
|
|
|
66
69
|
return (
|
|
67
70
|
<>
|
|
68
|
-
<Form.Label label={t('function
|
|
69
|
-
<Form.Root
|
|
71
|
+
<Form.Label label={t('function-parameters.label')} asChild />
|
|
72
|
+
<Form.Root
|
|
73
|
+
key={selectedFunction.id}
|
|
74
|
+
schema={effectSchema}
|
|
75
|
+
defaultValues={defaultValues}
|
|
76
|
+
db={db}
|
|
77
|
+
onValuesChanged={handleValuesChanged}
|
|
78
|
+
>
|
|
70
79
|
<Form.FieldSet />
|
|
71
80
|
</Form.Root>
|
|
72
81
|
</>
|
|
@@ -9,7 +9,7 @@ import { Trigger } from '@dxos/functions';
|
|
|
9
9
|
import { useTranslation } from '@dxos/react-ui';
|
|
10
10
|
import { type FormFieldComponentProps, SelectField, useFormFieldState } from '@dxos/react-ui-form';
|
|
11
11
|
|
|
12
|
-
import { meta } from '
|
|
12
|
+
import { meta } from '#meta';
|
|
13
13
|
|
|
14
14
|
export type SpecSelectorProps = FormFieldComponentProps;
|
|
15
15
|
|
|
@@ -31,7 +31,7 @@ export const SpecSelector = (props: SpecSelectorProps) => {
|
|
|
31
31
|
},
|
|
32
32
|
};
|
|
33
33
|
case 'queue':
|
|
34
|
-
return { kind: 'queue', queue: 'dxn:' };
|
|
34
|
+
return { kind: 'queue', queue: 'dxn:queue:default' };
|
|
35
35
|
case 'email':
|
|
36
36
|
return { kind: 'email' };
|
|
37
37
|
case 'webhook':
|
|
@@ -52,11 +52,20 @@ export const SpecSelector = (props: SpecSelectorProps) => {
|
|
|
52
52
|
[props.type, specProps],
|
|
53
53
|
);
|
|
54
54
|
|
|
55
|
+
const kindLabels: Record<string, string> = {
|
|
56
|
+
timer: t('trigger-type.timer.label'),
|
|
57
|
+
webhook: t('trigger-type.webhook.label'),
|
|
58
|
+
websocket: t('trigger-type.websocket.label'),
|
|
59
|
+
subscription: t('trigger-type.subscription.label'),
|
|
60
|
+
email: t('trigger-type.email.label'),
|
|
61
|
+
queue: t('trigger-type.queue.label'),
|
|
62
|
+
};
|
|
63
|
+
|
|
55
64
|
const options = useMemo(
|
|
56
65
|
() =>
|
|
57
66
|
Trigger.Kinds.map((kind) => ({
|
|
58
67
|
value: kind,
|
|
59
|
-
label:
|
|
68
|
+
label: kindLabels[kind],
|
|
60
69
|
})),
|
|
61
70
|
[t],
|
|
62
71
|
);
|
|
@@ -4,28 +4,30 @@
|
|
|
4
4
|
|
|
5
5
|
import { type Meta, type StoryObj } from '@storybook/react-vite';
|
|
6
6
|
import React, { useState } from 'react';
|
|
7
|
+
import { expect, userEvent, within } from 'storybook/test';
|
|
7
8
|
|
|
8
9
|
import { Filter, Obj, Ref, Tag, Type } from '@dxos/echo';
|
|
9
|
-
import {
|
|
10
|
+
import { Trigger } from '@dxos/functions';
|
|
10
11
|
import { invariant } from '@dxos/invariant';
|
|
11
|
-
import {
|
|
12
|
+
import { Operation } from '@dxos/operation';
|
|
13
|
+
import { random } from '@dxos/random';
|
|
12
14
|
import { useQuery } from '@dxos/react-client/echo';
|
|
13
15
|
import { TestSchema, useClientStory, withClientProvider } from '@dxos/react-client/testing';
|
|
14
16
|
import { useAsyncEffect } from '@dxos/react-ui';
|
|
15
|
-
import { withLayout, withTheme } from '@dxos/react-ui/testing';
|
|
16
17
|
import { translations as formTranslations } from '@dxos/react-ui-form';
|
|
17
|
-
import {
|
|
18
|
+
import { withLayout, withTheme } from '@dxos/react-ui/testing';
|
|
19
|
+
import { Employer, Organization, Person, Pipeline } from '@dxos/types';
|
|
18
20
|
|
|
19
|
-
import { functions } from '
|
|
20
|
-
import { translations } from '../../translations';
|
|
21
|
+
import { functions } from '#testing';
|
|
21
22
|
|
|
23
|
+
import { translations } from '../../translations';
|
|
22
24
|
import { TriggerEditor, type TriggerEditorProps } from './TriggerEditor';
|
|
23
25
|
|
|
24
26
|
const types = [
|
|
25
27
|
// TODO(burdon): Get label from annotation.
|
|
26
28
|
{ value: Organization.Organization.typename, label: 'Organization' },
|
|
27
29
|
{ value: Person.Person.typename, label: 'Person' },
|
|
28
|
-
{ value: Type.getTypename(
|
|
30
|
+
{ value: Type.getTypename(Pipeline.Pipeline), label: 'Project' },
|
|
29
31
|
{ value: Employer.Employer.typename, label: 'Employer' },
|
|
30
32
|
];
|
|
31
33
|
|
|
@@ -39,7 +41,7 @@ const DefaultStory = (props: Partial<TriggerEditorProps>) => {
|
|
|
39
41
|
return;
|
|
40
42
|
}
|
|
41
43
|
|
|
42
|
-
const functions = await space.db.query(Filter.type(
|
|
44
|
+
const functions = await space.db.query(Filter.type(Operation.PersistentOperation)).run();
|
|
43
45
|
const fn = functions.find((fn) => fn.name === 'example.com/function/forex');
|
|
44
46
|
invariant(fn);
|
|
45
47
|
const trigger = space.db.add(
|
|
@@ -72,16 +74,16 @@ const DefaultStory = (props: Partial<TriggerEditorProps>) => {
|
|
|
72
74
|
};
|
|
73
75
|
|
|
74
76
|
const meta = {
|
|
75
|
-
title: 'plugins/plugin-automation/TriggerEditor',
|
|
77
|
+
title: 'plugins/plugin-automation/components/TriggerEditor',
|
|
76
78
|
component: TriggerEditor as any,
|
|
77
79
|
render: DefaultStory,
|
|
78
80
|
decorators: [
|
|
79
|
-
withTheme,
|
|
81
|
+
withTheme(),
|
|
80
82
|
withLayout({ layout: 'column' }),
|
|
81
83
|
withClientProvider({
|
|
82
84
|
createIdentity: true,
|
|
83
85
|
createSpace: true,
|
|
84
|
-
types: [Tag.Tag,
|
|
86
|
+
types: [Tag.Tag, Operation.PersistentOperation, Trigger.Trigger, TestSchema.ContactType],
|
|
85
87
|
onCreateSpace: ({ space }) => {
|
|
86
88
|
// Tags.
|
|
87
89
|
['Important', 'Investor', 'New'].forEach((label) => {
|
|
@@ -90,14 +92,14 @@ const meta = {
|
|
|
90
92
|
|
|
91
93
|
// Functions.
|
|
92
94
|
functions.forEach((fn) => {
|
|
93
|
-
space.db.add(
|
|
95
|
+
space.db.add(Obj.make(Operation.PersistentOperation, { ...fn, version: fn.version ?? '0.1.0' }));
|
|
94
96
|
});
|
|
95
97
|
|
|
96
98
|
// Objects.
|
|
97
99
|
Array.from({ length: 10 }).map(() => {
|
|
98
100
|
return space.db.add(
|
|
99
101
|
Obj.make(TestSchema.ContactType, {
|
|
100
|
-
name:
|
|
102
|
+
name: random.person.fullName(),
|
|
101
103
|
identifiers: [],
|
|
102
104
|
}),
|
|
103
105
|
);
|
|
@@ -122,3 +124,44 @@ export const ReadonlySpec: Story = {
|
|
|
122
124
|
readonlySpec: true,
|
|
123
125
|
},
|
|
124
126
|
};
|
|
127
|
+
|
|
128
|
+
export const Spec: Story = {
|
|
129
|
+
play: async ({ canvasElement }) => {
|
|
130
|
+
const canvas = within(canvasElement);
|
|
131
|
+
const webhookText = await canvas.findByText('Webhook', {}, { timeout: 10_000 });
|
|
132
|
+
const combobox = webhookText.closest('[role="combobox"]') as HTMLElement;
|
|
133
|
+
await expect(combobox).not.toBeDisabled();
|
|
134
|
+
|
|
135
|
+
// Helper to switch to a kind via keyboard.
|
|
136
|
+
// TODO(wittjosiah): Radix Select in popper mode doesn't close on click.
|
|
137
|
+
// Use keyboard navigation: open, type first letter to jump, Enter to select.
|
|
138
|
+
const selectKind = async (combobox: HTMLElement, firstLetter: string) => {
|
|
139
|
+
combobox.focus();
|
|
140
|
+
await userEvent.keyboard('{Enter}');
|
|
141
|
+
await userEvent.keyboard(firstLetter);
|
|
142
|
+
await userEvent.keyboard('{Enter}');
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
// Timer — should show "Cron" field.
|
|
146
|
+
await selectKind(combobox, 't');
|
|
147
|
+
await expect(canvas.findByLabelText('Cron')).resolves.toBeInTheDocument();
|
|
148
|
+
|
|
149
|
+
// Email — no extra fields; Cron should be gone.
|
|
150
|
+
await selectKind(combobox, 'e');
|
|
151
|
+
await expect(combobox).not.toBeDisabled();
|
|
152
|
+
await expect(canvas.queryByLabelText('Cron')).not.toBeInTheDocument();
|
|
153
|
+
|
|
154
|
+
// Webhook — should show "Method" field.
|
|
155
|
+
await selectKind(combobox, 'w');
|
|
156
|
+
await expect(canvas.findByLabelText('Method')).resolves.toBeInTheDocument();
|
|
157
|
+
|
|
158
|
+
// Subscription — should show query editor.
|
|
159
|
+
await selectKind(combobox, 's');
|
|
160
|
+
await expect(combobox).not.toBeDisabled();
|
|
161
|
+
await expect(canvas.queryByLabelText('Method')).not.toBeInTheDocument();
|
|
162
|
+
|
|
163
|
+
// Feed — should show DXN field (the queue address). DXN is a combobox, not an input, so use getByText.
|
|
164
|
+
await selectKind(combobox, 'f');
|
|
165
|
+
await expect(canvas.findByText('DXN')).resolves.toBeInTheDocument();
|
|
166
|
+
},
|
|
167
|
+
};
|
|
@@ -5,8 +5,9 @@
|
|
|
5
5
|
import React, { useCallback, useMemo } from 'react';
|
|
6
6
|
|
|
7
7
|
import { ComputeGraph } from '@dxos/conductor';
|
|
8
|
-
import { DXN, type Database, type Query } from '@dxos/echo';
|
|
9
|
-
import {
|
|
8
|
+
import { DXN, type Database, Entity, Feed, Obj, type Query } from '@dxos/echo';
|
|
9
|
+
import { Script, Trigger } from '@dxos/functions';
|
|
10
|
+
import { Operation } from '@dxos/operation';
|
|
10
11
|
import { Filter, Ref, useQuery } from '@dxos/react-client/echo';
|
|
11
12
|
import { Input } from '@dxos/react-ui';
|
|
12
13
|
import { QueryForm, type QueryFormProps } from '@dxos/react-ui-components';
|
|
@@ -36,20 +37,31 @@ export type TriggerEditorProps = {
|
|
|
36
37
|
Pick<FormRootProps<TriggerFormSchema>, 'onSave' | 'onCancel'>;
|
|
37
38
|
|
|
38
39
|
export const TriggerEditor = ({ db, types, tags, readonlySpec, trigger, ...formProps }: TriggerEditorProps) => {
|
|
39
|
-
const fieldMap = useCustomInputs({
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
40
|
+
const fieldMap = useCustomInputs({ db, types, tags, readonlySpec });
|
|
41
|
+
|
|
42
|
+
const handleValuesChanged = useCallback(
|
|
43
|
+
(newValues: Partial<TriggerFormSchema>) => {
|
|
44
|
+
Obj.change(trigger, (trigger) => {
|
|
45
|
+
Object.assign(trigger, newValues);
|
|
46
|
+
});
|
|
47
|
+
},
|
|
48
|
+
[trigger],
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
const triggerSchema = useMemo(() => omitId(Trigger.Trigger), []);
|
|
52
|
+
const defaultValues = useMemo(() => {
|
|
53
|
+
const { id: _, ...values } = trigger;
|
|
54
|
+
return values;
|
|
55
|
+
}, [trigger]);
|
|
45
56
|
|
|
46
57
|
return (
|
|
47
58
|
<Form.Root<TriggerFormSchema>
|
|
48
59
|
{...formProps}
|
|
49
|
-
schema={omitId(Trigger.Trigger)}
|
|
50
|
-
values={trigger}
|
|
51
60
|
db={db}
|
|
61
|
+
schema={triggerSchema}
|
|
62
|
+
defaultValues={defaultValues}
|
|
52
63
|
fieldMap={fieldMap}
|
|
64
|
+
onValuesChanged={handleValuesChanged}
|
|
53
65
|
>
|
|
54
66
|
<Form.Viewport>
|
|
55
67
|
<Form.Content>
|
|
@@ -67,9 +79,10 @@ type UseCustomInputsProps = {
|
|
|
67
79
|
} & Pick<QueryFormProps, 'types' | 'tags'>;
|
|
68
80
|
|
|
69
81
|
const useCustomInputs = ({ db, readonlySpec, types, tags }: UseCustomInputsProps): FormFieldMap => {
|
|
70
|
-
const functions = useQuery(db, Filter.type(
|
|
82
|
+
const functions = useQuery(db, Filter.type(Operation.PersistentOperation));
|
|
71
83
|
const workflows = useQuery(db, Filter.type(ComputeGraph));
|
|
72
84
|
const scripts = useQuery(db, Filter.type(Script.Script));
|
|
85
|
+
const feeds = useQuery(db, Filter.type(Feed.Feed));
|
|
73
86
|
|
|
74
87
|
return useMemo(
|
|
75
88
|
(): FormFieldMap => ({
|
|
@@ -105,11 +118,14 @@ const useCustomInputs = ({ db, readonlySpec, types, tags }: UseCustomInputsProps
|
|
|
105
118
|
},
|
|
106
119
|
|
|
107
120
|
// Spec selector.
|
|
108
|
-
|
|
121
|
+
'spec.kind': (props) => <SpecSelector {...props} readonly={readonlySpec} />,
|
|
122
|
+
|
|
123
|
+
// Queue feed selector with parent labels.
|
|
124
|
+
'spec.queue': (props) => <SelectField {...props} options={getFeedQueueOptions(feeds)} />,
|
|
109
125
|
|
|
110
126
|
// TODO(wittjosiah): Copied from ViewEditor.
|
|
111
127
|
// Query input editor.
|
|
112
|
-
|
|
128
|
+
'spec.query': (props) => {
|
|
113
129
|
const handleChange = useCallback(
|
|
114
130
|
(query: Query.Any) => props.onValueChange(props.type, { ast: query.ast }),
|
|
115
131
|
[props.type, props.onValueChange],
|
|
@@ -124,9 +140,9 @@ const useCustomInputs = ({ db, readonlySpec, types, tags }: UseCustomInputsProps
|
|
|
124
140
|
},
|
|
125
141
|
|
|
126
142
|
// Function input editor.
|
|
127
|
-
|
|
143
|
+
input: (props) => <FunctionInputEditor {...props} functions={functions} db={db} />,
|
|
128
144
|
}),
|
|
129
|
-
[workflows, scripts, functions, readonlySpec],
|
|
145
|
+
[workflows, scripts, functions, feeds, readonlySpec],
|
|
130
146
|
);
|
|
131
147
|
};
|
|
132
148
|
|
|
@@ -134,7 +150,20 @@ const getWorkflowOptions = (graphs: ComputeGraph[]) => {
|
|
|
134
150
|
return graphs.map((graph) => ({ label: `compute-${graph.id}`, value: `dxn:echo:@:${graph.id}` }));
|
|
135
151
|
};
|
|
136
152
|
|
|
137
|
-
const getFunctionOptions = (scripts: Script.Script[], functions:
|
|
138
|
-
const getLabel = (fn:
|
|
153
|
+
const getFunctionOptions = (scripts: Script.Script[], functions: Operation.PersistentOperation[]) => {
|
|
154
|
+
const getLabel = (fn: Operation.PersistentOperation) =>
|
|
155
|
+
scripts.find((s) => fn.source?.target?.id === s.id)?.name ?? fn.name;
|
|
139
156
|
return functions.map((fn) => ({ label: getLabel(fn), value: `dxn:echo:@:${fn.id}` }));
|
|
140
157
|
};
|
|
158
|
+
|
|
159
|
+
const getFeedQueueOptions = (feeds: Feed.Feed[]) => {
|
|
160
|
+
return feeds.flatMap((feed) => {
|
|
161
|
+
const queueDxn = Feed.getQueueDxn(feed);
|
|
162
|
+
if (!queueDxn) {
|
|
163
|
+
return [];
|
|
164
|
+
}
|
|
165
|
+
const parent = Obj.getParent(feed);
|
|
166
|
+
const label = parent ? Entity.getLabel(parent) : Entity.getLabel(feed);
|
|
167
|
+
return [{ label: label ?? feed.id, value: queueDxn.toString() }];
|
|
168
|
+
});
|
|
169
|
+
};
|
package/src/components/index.ts
CHANGED
|
@@ -7,6 +7,5 @@ import { lazy } from 'react';
|
|
|
7
7
|
export * from './TriggerEditor';
|
|
8
8
|
|
|
9
9
|
export const AutomationPanel = lazy(() => import('./AutomationPanel'));
|
|
10
|
-
export const AutomationSettings = lazy(() => import('./AutomationSettings'));
|
|
11
|
-
export const FunctionsContainer = lazy(() => import('./FunctionsContainer'));
|
|
12
10
|
export const FunctionsPanel = lazy(() => import('./FunctionsPanel'));
|
|
11
|
+
export const FunctionsRegistry = lazy(() => import('./FunctionsRegistry'));
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import React from 'react';
|
|
6
|
+
|
|
7
|
+
import { useTranslation } from '@dxos/react-ui';
|
|
8
|
+
import { Settings } from '@dxos/react-ui-form';
|
|
9
|
+
|
|
10
|
+
import { meta } from '#meta';
|
|
11
|
+
|
|
12
|
+
import { AutomationPanel, type AutomationPanelProps } from '../../components/AutomationPanel';
|
|
13
|
+
import { TriggersSettings } from '../TriggerSettings';
|
|
14
|
+
|
|
15
|
+
export const AutomationSettings = (props: AutomationPanelProps) => {
|
|
16
|
+
const { t } = useTranslation(meta.id);
|
|
17
|
+
return (
|
|
18
|
+
<Settings.Viewport>
|
|
19
|
+
<Settings.Section
|
|
20
|
+
title={t('automation-verbose.label', { ns: meta.id })}
|
|
21
|
+
description={t('automation.description', { ns: meta.id })}
|
|
22
|
+
>
|
|
23
|
+
<AutomationPanel {...props} />
|
|
24
|
+
<TriggersSettings db={props.space.db} />
|
|
25
|
+
</Settings.Section>
|
|
26
|
+
</Settings.Viewport>
|
|
27
|
+
);
|
|
28
|
+
};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import React from 'react';
|
|
6
|
+
|
|
7
|
+
import { type Space } from '@dxos/react-client/echo';
|
|
8
|
+
import { useTranslation } from '@dxos/react-ui';
|
|
9
|
+
import { Settings } from '@dxos/react-ui-form';
|
|
10
|
+
|
|
11
|
+
import { meta } from '#meta';
|
|
12
|
+
|
|
13
|
+
import { FunctionsPanel } from '../../components/FunctionsPanel';
|
|
14
|
+
import { FunctionsRegistry } from '../../components/FunctionsRegistry';
|
|
15
|
+
|
|
16
|
+
export const FunctionsContainer = ({ space }: { space: Space }) => {
|
|
17
|
+
const { t } = useTranslation(meta.id);
|
|
18
|
+
return (
|
|
19
|
+
<Settings.Viewport>
|
|
20
|
+
<Settings.Section
|
|
21
|
+
title={t('functions-verbose.label', { ns: meta.id })}
|
|
22
|
+
description={t('functions.description', { ns: meta.id })}
|
|
23
|
+
>
|
|
24
|
+
<FunctionsPanel space={space} />
|
|
25
|
+
</Settings.Section>
|
|
26
|
+
<Settings.Section
|
|
27
|
+
title={t('functions-registry-verbose.label', { ns: meta.id })}
|
|
28
|
+
description={t('functions-registry.description', { ns: meta.id })}
|
|
29
|
+
>
|
|
30
|
+
<FunctionsRegistry space={space} />
|
|
31
|
+
</Settings.Section>
|
|
32
|
+
</Settings.Viewport>
|
|
33
|
+
);
|
|
34
|
+
};
|
|
@@ -6,20 +6,21 @@ import React from 'react';
|
|
|
6
6
|
|
|
7
7
|
import { type Database } from '@dxos/echo';
|
|
8
8
|
import { Input, useTranslation } from '@dxos/react-ui';
|
|
9
|
-
import {
|
|
9
|
+
import { Settings } from '@dxos/react-ui-form';
|
|
10
10
|
|
|
11
|
-
import { useTriggerRuntimeControls } from '
|
|
12
|
-
import { meta } from '
|
|
11
|
+
import { useTriggerRuntimeControls } from '#hooks';
|
|
12
|
+
import { meta } from '#meta';
|
|
13
13
|
|
|
14
14
|
export const TriggersSettings = ({ db }: { db: Database.Database }) => {
|
|
15
|
-
const {
|
|
15
|
+
const { state, start, stop } = useTriggerRuntimeControls(db);
|
|
16
|
+
const isRunning = state?.enabled ?? false;
|
|
16
17
|
const { t } = useTranslation(meta.id);
|
|
17
18
|
|
|
18
19
|
return (
|
|
19
|
-
<div className='
|
|
20
|
-
<
|
|
20
|
+
<div className='grid grid-cols-1 md:grid-cols-[1fr_min-content]'>
|
|
21
|
+
<Settings.Item title={t('runtime.label')} description={t('runtime.description')}>
|
|
21
22
|
<Input.Switch classNames='justify-self-end' checked={isRunning} onCheckedChange={isRunning ? stop : start} />
|
|
22
|
-
</
|
|
23
|
+
</Settings.Item>
|
|
23
24
|
</div>
|
|
24
25
|
);
|
|
25
26
|
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { type ComponentType, lazy } from 'react';
|
|
6
|
+
|
|
7
|
+
export const AutomationSettings: ComponentType<any> = lazy(() => import('./AutomationSettings'));
|
|
8
|
+
export const FunctionsContainer: ComponentType<any> = lazy(() => import('./FunctionsContainer'));
|
|
9
|
+
export const TriggerSettings: ComponentType<any> = lazy(() => import('./TriggerSettings'));
|
package/src/hooks/index.ts
CHANGED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { useCapability } from '@dxos/app-framework/ui';
|
|
6
|
+
import { SpaceId } from '@dxos/keys';
|
|
7
|
+
|
|
8
|
+
import { AutomationCapabilities } from '../types';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Resolves the compute runtime for a space.
|
|
12
|
+
*/
|
|
13
|
+
export const useComputeRuntime = (id: SpaceId | undefined): AutomationCapabilities.ComputeRuntime | undefined => {
|
|
14
|
+
const computeRuntime = useCapability(AutomationCapabilities.ComputeRuntime);
|
|
15
|
+
return id !== undefined ? computeRuntime.getRuntime(id) : undefined;
|
|
16
|
+
};
|
|
@@ -2,17 +2,14 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import * as Cause from 'effect/Cause';
|
|
6
5
|
import * as Effect from 'effect/Effect';
|
|
7
|
-
import * as Exit from 'effect/Exit';
|
|
8
6
|
import { type DependencyList, useCallback } from 'react';
|
|
9
7
|
|
|
10
|
-
import { useCapability } from '@dxos/app-framework/react';
|
|
11
8
|
import { type Key } from '@dxos/echo';
|
|
12
|
-
import { type FunctionDefinition, FunctionInvocationService, TracingService } from '@dxos/functions';
|
|
13
|
-
import { log } from '@dxos/log';
|
|
14
9
|
|
|
15
|
-
import { AutomationCapabilities } from '
|
|
10
|
+
import { AutomationCapabilities } from '#types';
|
|
11
|
+
|
|
12
|
+
import { useComputeRuntime } from './useComputeRuntime';
|
|
16
13
|
|
|
17
14
|
/**
|
|
18
15
|
* Create an effectful function that has access to compute services
|
|
@@ -23,8 +20,7 @@ export const useComputeRuntimeCallback = <T>(
|
|
|
23
20
|
fn: () => Effect.Effect<T, any, AutomationCapabilities.ComputeServices>,
|
|
24
21
|
deps?: DependencyList,
|
|
25
22
|
): (() => Promise<T>) => {
|
|
26
|
-
const
|
|
27
|
-
const runtime = id !== undefined ? computeRuntime.getRuntime(id) : undefined;
|
|
23
|
+
const runtime = useComputeRuntime(id);
|
|
28
24
|
|
|
29
25
|
return useCallback(() => {
|
|
30
26
|
if (!runtime) {
|
|
@@ -34,34 +30,3 @@ export const useComputeRuntimeCallback = <T>(
|
|
|
34
30
|
return runtime.runPromise(fn());
|
|
35
31
|
}, [runtime, ...(deps ?? [])]);
|
|
36
32
|
};
|
|
37
|
-
|
|
38
|
-
// TODO(wittjosiah): Function invoking should automatically be traced (DX-647).
|
|
39
|
-
export const invokeFunctionWithTracing = <I, O>(functionDef: FunctionDefinition<I, O>, inputData: I) =>
|
|
40
|
-
Effect.gen(function* () {
|
|
41
|
-
const tracer = yield* TracingService;
|
|
42
|
-
const trace = yield* tracer.traceInvocationStart({
|
|
43
|
-
target: undefined,
|
|
44
|
-
payload: {
|
|
45
|
-
data: {},
|
|
46
|
-
},
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
// Invoke the function.
|
|
50
|
-
const result = yield* FunctionInvocationService.invokeFunction(functionDef, inputData).pipe(
|
|
51
|
-
Effect.provide(trace.invocationTraceQueue ? TracingService.layerInvocation(trace) : TracingService.layerNoop),
|
|
52
|
-
Effect.exit,
|
|
53
|
-
);
|
|
54
|
-
|
|
55
|
-
if (Exit.isFailure(result)) {
|
|
56
|
-
const error = Cause.prettyErrors(result.cause)[0];
|
|
57
|
-
log.error(error.message, error.cause ?? error.stack);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
yield* tracer.traceInvocationEnd({
|
|
61
|
-
trace,
|
|
62
|
-
// TODO(dmaretskyi): Might miss errors.
|
|
63
|
-
exception: Exit.isFailure(result) ? Cause.prettyErrors(result.cause)[0] : undefined,
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
return result;
|
|
67
|
-
});
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2026 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import * as Context from 'effect/Context';
|
|
6
|
+
import { use } from 'react';
|
|
7
|
+
import { useMemo } from 'react';
|
|
8
|
+
|
|
9
|
+
import { unwrapExit } from '@dxos/effect';
|
|
10
|
+
import { SpaceId } from '@dxos/keys';
|
|
11
|
+
|
|
12
|
+
import { AutomationCapabilities } from '../types';
|
|
13
|
+
import { useComputeRuntime } from './useComputeRuntime';
|
|
14
|
+
|
|
15
|
+
export const useComputeRuntimeService = <T extends Context.Tag<any, any>>(
|
|
16
|
+
tag: T,
|
|
17
|
+
spaceId?: SpaceId,
|
|
18
|
+
): (Context.Tag.Service<T> & AutomationCapabilities.ComputeRuntime) | undefined => {
|
|
19
|
+
const runtime = useComputeRuntime(spaceId);
|
|
20
|
+
if (!runtime) {
|
|
21
|
+
return undefined;
|
|
22
|
+
}
|
|
23
|
+
return unwrapExit(use(useMemo(() => runtime.runPromiseExit(tag), [runtime, tag])));
|
|
24
|
+
};
|
|
@@ -2,19 +2,23 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
+
import { Atom, useAtomValue } from '@effect-atom/atom-react';
|
|
6
|
+
import type * as Context from 'effect/Context';
|
|
5
7
|
import * as Effect from 'effect/Effect';
|
|
8
|
+
import { useEffect, useState } from 'react';
|
|
6
9
|
|
|
7
10
|
import { type Database, Filter } from '@dxos/echo';
|
|
8
11
|
import { Trigger } from '@dxos/functions';
|
|
9
|
-
import { TriggerDispatcher } from '@dxos/functions-runtime';
|
|
12
|
+
import { TriggerDispatcher, type TriggerDispatcherState } from '@dxos/functions-runtime';
|
|
10
13
|
import { useQuery } from '@dxos/react-client/echo';
|
|
11
|
-
import { useAsyncState } from '@dxos/react-ui';
|
|
12
14
|
|
|
13
15
|
import { useComputeRuntimeCallback } from './useComputeRuntimeCallback';
|
|
14
16
|
|
|
15
17
|
interface TriggerRuntimeControls {
|
|
16
18
|
triggers: Trigger.Trigger[];
|
|
17
|
-
|
|
19
|
+
|
|
20
|
+
state: TriggerDispatcherState | undefined;
|
|
21
|
+
|
|
18
22
|
start: () => void;
|
|
19
23
|
stop: () => void;
|
|
20
24
|
}
|
|
@@ -22,16 +26,27 @@ interface TriggerRuntimeControls {
|
|
|
22
26
|
export const useTriggerRuntimeControls = (db: Database.Database | undefined): TriggerRuntimeControls => {
|
|
23
27
|
const triggers = useQuery(db, Filter.type(Trigger.Trigger));
|
|
24
28
|
|
|
25
|
-
const [
|
|
26
|
-
|
|
29
|
+
const [dispatcher, setDispatcher] = useState<Context.Tag.Service<TriggerDispatcher> | undefined>(undefined);
|
|
30
|
+
|
|
31
|
+
const init = useComputeRuntimeCallback(
|
|
32
|
+
db?.spaceId,
|
|
33
|
+
Effect.fnUntraced(function* () {
|
|
34
|
+
const dispatcher = yield* TriggerDispatcher;
|
|
35
|
+
setDispatcher(dispatcher);
|
|
36
|
+
}),
|
|
27
37
|
);
|
|
28
38
|
|
|
39
|
+
useEffect(() => {
|
|
40
|
+
void init();
|
|
41
|
+
}, []);
|
|
42
|
+
|
|
43
|
+
const state = useAtomValue(dispatcher?.state ?? Atom.make(undefined));
|
|
44
|
+
|
|
29
45
|
const start = useComputeRuntimeCallback(
|
|
30
46
|
db?.spaceId,
|
|
31
47
|
Effect.fnUntraced(function* () {
|
|
32
48
|
const dispatcher = yield* TriggerDispatcher;
|
|
33
49
|
yield* dispatcher.start();
|
|
34
|
-
setIsRunningState(true);
|
|
35
50
|
}),
|
|
36
51
|
);
|
|
37
52
|
|
|
@@ -40,13 +55,12 @@ export const useTriggerRuntimeControls = (db: Database.Database | undefined): Tr
|
|
|
40
55
|
Effect.fnUntraced(function* () {
|
|
41
56
|
const dispatcher = yield* TriggerDispatcher;
|
|
42
57
|
yield* dispatcher.stop();
|
|
43
|
-
setIsRunningState(false);
|
|
44
58
|
}),
|
|
45
59
|
);
|
|
46
60
|
|
|
47
61
|
return {
|
|
48
62
|
triggers,
|
|
49
|
-
|
|
63
|
+
state,
|
|
50
64
|
start: () => void start(),
|
|
51
65
|
stop: () => void stop(),
|
|
52
66
|
};
|