@nordcraft/runtime 1.0.0
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/README.md +5 -0
- package/dist/api/createAPI.d.ts +20 -0
- package/dist/api/createAPI.js +319 -0
- package/dist/api/createAPI.js.map +1 -0
- package/dist/api/createAPIv2.d.ts +7 -0
- package/dist/api/createAPIv2.js +686 -0
- package/dist/api/createAPIv2.js.map +1 -0
- package/dist/components/createComponent.d.ts +13 -0
- package/dist/components/createComponent.js +216 -0
- package/dist/components/createComponent.js.map +1 -0
- package/dist/components/createElement.d.ts +3 -0
- package/dist/components/createElement.js +208 -0
- package/dist/components/createElement.js.map +1 -0
- package/dist/components/createNode.d.ts +22 -0
- package/dist/components/createNode.js +272 -0
- package/dist/components/createNode.js.map +1 -0
- package/dist/components/createSlot.d.ts +3 -0
- package/dist/components/createSlot.js +49 -0
- package/dist/components/createSlot.js.map +1 -0
- package/dist/components/createText.d.ts +23 -0
- package/dist/components/createText.js +68 -0
- package/dist/components/createText.js.map +1 -0
- package/dist/components/createText.test.d.ts +1 -0
- package/dist/components/createText.test.js +113 -0
- package/dist/components/createText.test.js.map +1 -0
- package/dist/components/renderComponent.d.ts +34 -0
- package/dist/components/renderComponent.js +66 -0
- package/dist/components/renderComponent.js.map +1 -0
- package/dist/context/isContextProvider.d.ts +2 -0
- package/dist/context/isContextProvider.js +5 -0
- package/dist/context/isContextProvider.js.map +1 -0
- package/dist/context/subscribeToContext.d.ts +4 -0
- package/dist/context/subscribeToContext.js +93 -0
- package/dist/context/subscribeToContext.js.map +1 -0
- package/dist/custom-components/components.d.ts +1 -0
- package/dist/custom-components/components.js +2 -0
- package/dist/custom-components/components.js.map +1 -0
- package/dist/custom-components/toddle-portal.d.ts +6 -0
- package/dist/custom-components/toddle-portal.js +20 -0
- package/dist/custom-components/toddle-portal.js.map +1 -0
- package/dist/custom-element/ToddleComponent.d.ts +37 -0
- package/dist/custom-element/ToddleComponent.js +244 -0
- package/dist/custom-element/ToddleComponent.js.map +1 -0
- package/dist/custom-element/defineComponents.d.ts +26 -0
- package/dist/custom-element/defineComponents.js +42 -0
- package/dist/custom-element/defineComponents.js.map +1 -0
- package/dist/custom-element.main.d.ts +3 -0
- package/dist/custom-element.main.esm.js +266 -0
- package/dist/custom-element.main.esm.js.map +7 -0
- package/dist/custom-element.main.js +14 -0
- package/dist/custom-element.main.js.map +1 -0
- package/dist/debug/logState.d.ts +4 -0
- package/dist/debug/logState.js +19 -0
- package/dist/debug/logState.js.map +1 -0
- package/dist/editor/drag-drop/dragEnded.d.ts +2 -0
- package/dist/editor/drag-drop/dragEnded.js +56 -0
- package/dist/editor/drag-drop/dragEnded.js.map +1 -0
- package/dist/editor/drag-drop/dragMove.d.ts +3 -0
- package/dist/editor/drag-drop/dragMove.js +74 -0
- package/dist/editor/drag-drop/dragMove.js.map +1 -0
- package/dist/editor/drag-drop/dragReorder.d.ts +3 -0
- package/dist/editor/drag-drop/dragReorder.js +92 -0
- package/dist/editor/drag-drop/dragReorder.js.map +1 -0
- package/dist/editor/drag-drop/dragStarted.d.ts +9 -0
- package/dist/editor/drag-drop/dragStarted.js +100 -0
- package/dist/editor/drag-drop/dragStarted.js.map +1 -0
- package/dist/editor/drag-drop/dropHighlight.d.ts +16 -0
- package/dist/editor/drag-drop/dropHighlight.js +50 -0
- package/dist/editor/drag-drop/dropHighlight.js.map +1 -0
- package/dist/editor/drag-drop/getInsertAreas.d.ts +20 -0
- package/dist/editor/drag-drop/getInsertAreas.js +220 -0
- package/dist/editor/drag-drop/getInsertAreas.js.map +1 -0
- package/dist/editor-preview.main.d.ts +19 -0
- package/dist/editor-preview.main.js +1303 -0
- package/dist/editor-preview.main.js.map +1 -0
- package/dist/events/handleAction.d.ts +3 -0
- package/dist/events/handleAction.js +307 -0
- package/dist/events/handleAction.js.map +1 -0
- package/dist/page.main.d.ts +7 -0
- package/dist/page.main.esm.js +8 -0
- package/dist/page.main.esm.js.map +7 -0
- package/dist/page.main.js +395 -0
- package/dist/page.main.js.map +1 -0
- package/dist/signal/signal.d.ts +19 -0
- package/dist/signal/signal.js +65 -0
- package/dist/signal/signal.js.map +1 -0
- package/dist/styles/style.d.ts +4 -0
- package/dist/styles/style.js +196 -0
- package/dist/styles/style.js.map +1 -0
- package/dist/utils/BatchQueue.d.ts +10 -0
- package/dist/utils/BatchQueue.js +25 -0
- package/dist/utils/BatchQueue.js.map +1 -0
- package/dist/utils/createFormulaCache.d.ts +3 -0
- package/dist/utils/createFormulaCache.js +81 -0
- package/dist/utils/createFormulaCache.js.map +1 -0
- package/dist/utils/findNearestLine.d.ts +13 -0
- package/dist/utils/findNearestLine.js +74 -0
- package/dist/utils/findNearestLine.js.map +1 -0
- package/dist/utils/findNearestLine.test.d.ts +1 -0
- package/dist/utils/findNearestLine.test.js +59 -0
- package/dist/utils/findNearestLine.test.js.map +1 -0
- package/dist/utils/getDragData.d.ts +1 -0
- package/dist/utils/getDragData.js +10 -0
- package/dist/utils/getDragData.js.map +1 -0
- package/dist/utils/getElementTagName.d.ts +3 -0
- package/dist/utils/getElementTagName.js +7 -0
- package/dist/utils/getElementTagName.js.map +1 -0
- package/dist/utils/nodes.d.ts +21 -0
- package/dist/utils/nodes.js +89 -0
- package/dist/utils/nodes.js.map +1 -0
- package/dist/utils/omitStyle.d.ts +2 -0
- package/dist/utils/omitStyle.js +13 -0
- package/dist/utils/omitStyle.js.map +1 -0
- package/dist/utils/rectHasPoint.d.ts +2 -0
- package/dist/utils/rectHasPoint.js +4 -0
- package/dist/utils/rectHasPoint.js.map +1 -0
- package/dist/utils/setAttribute.d.ts +4 -0
- package/dist/utils/setAttribute.js +57 -0
- package/dist/utils/setAttribute.js.map +1 -0
- package/dist/utils/tryStartViewTransition.d.ts +5 -0
- package/dist/utils/tryStartViewTransition.js +14 -0
- package/dist/utils/tryStartViewTransition.js.map +1 -0
- package/dist/utils/url.d.ts +2 -0
- package/dist/utils/url.js +36 -0
- package/dist/utils/url.js.map +1 -0
- package/package.json +25 -0
- package/src/api/createAPI.ts +375 -0
- package/src/api/createAPIv2.ts +931 -0
- package/src/components/createComponent.ts +280 -0
- package/src/components/createElement.ts +240 -0
- package/src/components/createNode.ts +381 -0
- package/src/components/createSlot.ts +61 -0
- package/src/components/createText.test.ts +117 -0
- package/src/components/createText.ts +104 -0
- package/src/components/renderComponent.ts +145 -0
- package/src/context/isContextProvider.ts +12 -0
- package/src/context/subscribeToContext.ts +135 -0
- package/src/custom-components/components.ts +1 -0
- package/src/custom-components/toddle-portal.ts +19 -0
- package/src/custom-element/ToddleComponent.ts +315 -0
- package/src/custom-element/defineComponents.ts +65 -0
- package/src/custom-element.main.ts +24 -0
- package/src/debug/logState.ts +30 -0
- package/src/editor/drag-drop/dragEnded.ts +75 -0
- package/src/editor/drag-drop/dragMove.ts +95 -0
- package/src/editor/drag-drop/dragReorder.ts +137 -0
- package/src/editor/drag-drop/dragStarted.ts +145 -0
- package/src/editor/drag-drop/dropHighlight.ts +82 -0
- package/src/editor/drag-drop/getInsertAreas.ts +235 -0
- package/src/editor/types.d.ts +36 -0
- package/src/editor-preview.main.ts +1782 -0
- package/src/events/handleAction.ts +387 -0
- package/src/page.main.ts +489 -0
- package/src/signal/signal.ts +74 -0
- package/src/styles/style.ts +254 -0
- package/src/types.d.ts +93 -0
- package/src/utils/BatchQueue.ts +24 -0
- package/src/utils/createFormulaCache.ts +96 -0
- package/src/utils/findNearestLine.test.ts +65 -0
- package/src/utils/findNearestLine.ts +92 -0
- package/src/utils/getDragData.ts +11 -0
- package/src/utils/getElementTagName.ts +14 -0
- package/src/utils/nodes.ts +125 -0
- package/src/utils/omitStyle.ts +19 -0
- package/src/utils/rectHasPoint.ts +5 -0
- package/src/utils/setAttribute.ts +56 -0
- package/src/utils/tryStartViewTransition.ts +32 -0
- package/src/utils/url.ts +45 -0
|
@@ -0,0 +1,387 @@
|
|
|
1
|
+
/* eslint-disable no-console */
|
|
2
|
+
import type {
|
|
3
|
+
ActionModel,
|
|
4
|
+
ComponentData,
|
|
5
|
+
SetURLParameterAction,
|
|
6
|
+
} from '@nordcraft/core/dist/component/component.types'
|
|
7
|
+
import { applyFormula } from '@nordcraft/core/dist/formula/formula'
|
|
8
|
+
import { mapValues, omitKeys } from '@nordcraft/core/dist/utils/collections'
|
|
9
|
+
import { isDefined, toBoolean } from '@nordcraft/core/dist/utils/util'
|
|
10
|
+
import type { ComponentContext, Location } from '../types'
|
|
11
|
+
import { getLocationUrl } from '../utils/url'
|
|
12
|
+
|
|
13
|
+
// eslint-disable-next-line max-params
|
|
14
|
+
export function handleAction(
|
|
15
|
+
action: ActionModel,
|
|
16
|
+
data: ComponentData,
|
|
17
|
+
ctx: ComponentContext,
|
|
18
|
+
event?: Event,
|
|
19
|
+
) {
|
|
20
|
+
try {
|
|
21
|
+
if (!action) {
|
|
22
|
+
throw new Error('Action does not exist')
|
|
23
|
+
}
|
|
24
|
+
switch (action.type) {
|
|
25
|
+
case 'Switch': {
|
|
26
|
+
// find the first case that resolves to true.
|
|
27
|
+
// Only one case in a switch will be executed.
|
|
28
|
+
const actionList =
|
|
29
|
+
action.cases.find(({ condition }) =>
|
|
30
|
+
toBoolean(
|
|
31
|
+
applyFormula(condition, {
|
|
32
|
+
data,
|
|
33
|
+
component: ctx.component,
|
|
34
|
+
formulaCache: ctx.formulaCache,
|
|
35
|
+
root: ctx.root,
|
|
36
|
+
package: ctx.package,
|
|
37
|
+
toddle: ctx.toddle,
|
|
38
|
+
env: ctx.env,
|
|
39
|
+
}),
|
|
40
|
+
),
|
|
41
|
+
) ?? action.default
|
|
42
|
+
if (!actionList) {
|
|
43
|
+
return
|
|
44
|
+
}
|
|
45
|
+
// handle all actions for the case
|
|
46
|
+
for (const action of actionList.actions) {
|
|
47
|
+
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
48
|
+
handleAction(action, { ...data, ...ctx.dataSignal.get() }, ctx, event)
|
|
49
|
+
}
|
|
50
|
+
break
|
|
51
|
+
}
|
|
52
|
+
case 'SetVariable': {
|
|
53
|
+
const value = applyFormula(action.data, {
|
|
54
|
+
data,
|
|
55
|
+
component: ctx.component,
|
|
56
|
+
formulaCache: ctx.formulaCache,
|
|
57
|
+
root: ctx.root,
|
|
58
|
+
package: ctx.package,
|
|
59
|
+
toddle: ctx.toddle,
|
|
60
|
+
env: ctx.env,
|
|
61
|
+
})
|
|
62
|
+
ctx.dataSignal.update((data) => {
|
|
63
|
+
return {
|
|
64
|
+
...data,
|
|
65
|
+
Variables: {
|
|
66
|
+
...data.Variables,
|
|
67
|
+
[action.variable]: value,
|
|
68
|
+
},
|
|
69
|
+
}
|
|
70
|
+
})
|
|
71
|
+
break
|
|
72
|
+
}
|
|
73
|
+
case 'TriggerEvent': {
|
|
74
|
+
const payload = applyFormula(action.data, {
|
|
75
|
+
data,
|
|
76
|
+
component: ctx.component,
|
|
77
|
+
formulaCache: ctx.formulaCache,
|
|
78
|
+
root: ctx.root,
|
|
79
|
+
package: ctx.package,
|
|
80
|
+
toddle: ctx.toddle,
|
|
81
|
+
env: ctx.env,
|
|
82
|
+
})
|
|
83
|
+
ctx.triggerEvent(action.event, payload)
|
|
84
|
+
break
|
|
85
|
+
}
|
|
86
|
+
case 'SetURLParameter': {
|
|
87
|
+
ctx.toddle.locationSignal.update((current) => {
|
|
88
|
+
const value = applyFormula(action.data, {
|
|
89
|
+
data,
|
|
90
|
+
component: ctx.component,
|
|
91
|
+
formulaCache: ctx.formulaCache,
|
|
92
|
+
root: ctx.root,
|
|
93
|
+
package: ctx.package,
|
|
94
|
+
toddle: ctx.toddle,
|
|
95
|
+
env: ctx.env,
|
|
96
|
+
})
|
|
97
|
+
// historyMode was previously not declared explicitly, and we default
|
|
98
|
+
// to push for state changes and replace for query changes
|
|
99
|
+
let historyMode: SetURLParameterAction['historyMode'] | undefined
|
|
100
|
+
let newLocation: Location | undefined
|
|
101
|
+
// We should only match on p.type === 'param', but
|
|
102
|
+
// that would technically be a breaking change
|
|
103
|
+
if (current.route?.path.some((p) => p.name === action.parameter)) {
|
|
104
|
+
historyMode = 'push'
|
|
105
|
+
newLocation = {
|
|
106
|
+
...current,
|
|
107
|
+
params: {
|
|
108
|
+
...omitKeys(current.params, [action.parameter]),
|
|
109
|
+
[action.parameter]: value,
|
|
110
|
+
},
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
// We should check if the query parameter exists in the route
|
|
114
|
+
// but that would technically be a breaking change
|
|
115
|
+
// else if (Object.values(current.route?.query ?? {}).some((q) => q.name === action.parameter))
|
|
116
|
+
else {
|
|
117
|
+
historyMode = 'replace'
|
|
118
|
+
newLocation = {
|
|
119
|
+
...current,
|
|
120
|
+
query: {
|
|
121
|
+
...omitKeys(current.query, [action.parameter]),
|
|
122
|
+
...(isDefined(value) ? { [action.parameter]: value } : null),
|
|
123
|
+
},
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
if (!historyMode) {
|
|
127
|
+
// No path/query parameter matched
|
|
128
|
+
return current
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
const currentUrl = getLocationUrl(current)
|
|
132
|
+
const historyUrl = getLocationUrl(newLocation)
|
|
133
|
+
if (historyUrl !== currentUrl) {
|
|
134
|
+
// Default to the historyMode from the action, and fallback
|
|
135
|
+
// to the default (push for path change, replace for query change)
|
|
136
|
+
historyMode = action.historyMode ?? historyMode
|
|
137
|
+
// Update the window's history state
|
|
138
|
+
if (historyMode === 'push') {
|
|
139
|
+
window.history.pushState({}, '', historyUrl)
|
|
140
|
+
} else {
|
|
141
|
+
window.history.replaceState({}, '', historyUrl)
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
return newLocation
|
|
145
|
+
})
|
|
146
|
+
break
|
|
147
|
+
}
|
|
148
|
+
case 'Fetch': {
|
|
149
|
+
const api = ctx.apis[action.api]
|
|
150
|
+
if (!api) {
|
|
151
|
+
console.error('The api ', action.api, 'does not exist')
|
|
152
|
+
return
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
const isv2 = ctx.component.apis?.[action.api]?.version === 2
|
|
156
|
+
|
|
157
|
+
// Evaluate potential inputs here to make sure the api have the right values
|
|
158
|
+
// This is needed if the inputs are formulas referencing workflow parameters
|
|
159
|
+
const actionInputs = isv2
|
|
160
|
+
? mapValues(action.inputs ?? {}, (input) =>
|
|
161
|
+
applyFormula(input.formula, {
|
|
162
|
+
data,
|
|
163
|
+
component: ctx.component,
|
|
164
|
+
formulaCache: ctx.formulaCache,
|
|
165
|
+
root: ctx.root,
|
|
166
|
+
package: ctx.package,
|
|
167
|
+
toddle: ctx.toddle,
|
|
168
|
+
env: ctx.env,
|
|
169
|
+
}),
|
|
170
|
+
)
|
|
171
|
+
: undefined
|
|
172
|
+
|
|
173
|
+
const actionModels = isv2
|
|
174
|
+
? {
|
|
175
|
+
onCompleted: action.onSuccess?.actions,
|
|
176
|
+
onFailed: action.onError?.actions,
|
|
177
|
+
onMessage: action.onMessage?.actions,
|
|
178
|
+
}
|
|
179
|
+
: undefined
|
|
180
|
+
|
|
181
|
+
const triggerActions = (actions: ActionModel[]) => {
|
|
182
|
+
// Actions from the fetch action is handled by the api itself
|
|
183
|
+
if (isv2) {
|
|
184
|
+
return
|
|
185
|
+
}
|
|
186
|
+
for (const subAction of actions) {
|
|
187
|
+
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
188
|
+
handleAction(
|
|
189
|
+
subAction,
|
|
190
|
+
{ ...data, ...ctx.dataSignal.get() },
|
|
191
|
+
ctx,
|
|
192
|
+
event,
|
|
193
|
+
)
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
api.fetch({ actionInputs, actionModels }).then(
|
|
198
|
+
() => {
|
|
199
|
+
triggerActions(action.onSuccess.actions)
|
|
200
|
+
},
|
|
201
|
+
() => {
|
|
202
|
+
triggerActions(action.onError.actions)
|
|
203
|
+
},
|
|
204
|
+
)
|
|
205
|
+
break
|
|
206
|
+
}
|
|
207
|
+
case 'TriggerWorkflow': {
|
|
208
|
+
const parameters = mapValues(action.parameters ?? {}, (parameter) =>
|
|
209
|
+
applyFormula(parameter.formula, {
|
|
210
|
+
data,
|
|
211
|
+
component: ctx.component,
|
|
212
|
+
formulaCache: ctx.formulaCache,
|
|
213
|
+
root: ctx.root,
|
|
214
|
+
package: ctx.package,
|
|
215
|
+
toddle: ctx.toddle,
|
|
216
|
+
env: ctx.env,
|
|
217
|
+
}),
|
|
218
|
+
)
|
|
219
|
+
|
|
220
|
+
if (action.contextProvider) {
|
|
221
|
+
const provider =
|
|
222
|
+
ctx.providers[
|
|
223
|
+
[ctx.package, action.contextProvider].filter(isDefined).join('/')
|
|
224
|
+
] ?? ctx.providers[action.contextProvider]
|
|
225
|
+
const workflow = provider?.component.workflows?.[action.workflow]
|
|
226
|
+
if (!workflow) {
|
|
227
|
+
if (provider) {
|
|
228
|
+
console.warn(
|
|
229
|
+
`Cannot find workflow "${action.workflow}" on component "${action.contextProvider}". It has likely been removed or modified.`,
|
|
230
|
+
)
|
|
231
|
+
}
|
|
232
|
+
return
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
workflow.actions.forEach((action) =>
|
|
236
|
+
handleAction(
|
|
237
|
+
action,
|
|
238
|
+
{
|
|
239
|
+
...data,
|
|
240
|
+
...provider.ctx.dataSignal.get(),
|
|
241
|
+
Parameters: parameters,
|
|
242
|
+
},
|
|
243
|
+
provider.ctx,
|
|
244
|
+
event,
|
|
245
|
+
),
|
|
246
|
+
)
|
|
247
|
+
return
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
const workflow = ctx.component.workflows?.[action.workflow]
|
|
251
|
+
if (!workflow) {
|
|
252
|
+
console.warn(
|
|
253
|
+
`Workflow ${action.workflow} does not exist on component ${ctx.component.name}`,
|
|
254
|
+
)
|
|
255
|
+
return
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
workflow.actions.forEach((action) =>
|
|
259
|
+
handleAction(
|
|
260
|
+
action,
|
|
261
|
+
{
|
|
262
|
+
...data,
|
|
263
|
+
...ctx.dataSignal.get(),
|
|
264
|
+
Parameters: parameters,
|
|
265
|
+
},
|
|
266
|
+
ctx,
|
|
267
|
+
event,
|
|
268
|
+
),
|
|
269
|
+
)
|
|
270
|
+
break
|
|
271
|
+
}
|
|
272
|
+
default: {
|
|
273
|
+
try {
|
|
274
|
+
// create a handler for actions triggering events
|
|
275
|
+
const triggerActionEvent = (trigger: string, eventData: any) => {
|
|
276
|
+
const subEvent = action.events?.[trigger]
|
|
277
|
+
if (subEvent) {
|
|
278
|
+
subEvent.actions.forEach((action) =>
|
|
279
|
+
handleAction(
|
|
280
|
+
action,
|
|
281
|
+
eventData
|
|
282
|
+
? { ...data, ...ctx.dataSignal.get(), Event: eventData }
|
|
283
|
+
: { ...data, ...ctx.dataSignal.get() },
|
|
284
|
+
ctx,
|
|
285
|
+
eventData ?? event,
|
|
286
|
+
),
|
|
287
|
+
)
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
const newAction =
|
|
291
|
+
action.version === 2
|
|
292
|
+
? (ctx.toddle.getCustomAction ?? ctx.toddle.getCustomAction)(
|
|
293
|
+
action.name,
|
|
294
|
+
action.package ?? ctx.package,
|
|
295
|
+
)
|
|
296
|
+
: undefined
|
|
297
|
+
if (newAction) {
|
|
298
|
+
// First evaluate any arguments (input) to the action
|
|
299
|
+
const args = (action.arguments ?? []).reduce<
|
|
300
|
+
Record<string, unknown>
|
|
301
|
+
>(
|
|
302
|
+
(args, arg) => ({
|
|
303
|
+
...args,
|
|
304
|
+
[arg.name]: applyFormula(arg.formula, {
|
|
305
|
+
data,
|
|
306
|
+
component: ctx.component,
|
|
307
|
+
formulaCache: ctx.formulaCache,
|
|
308
|
+
root: ctx.root,
|
|
309
|
+
package: ctx.package,
|
|
310
|
+
toddle: ctx.toddle,
|
|
311
|
+
env: ctx.env,
|
|
312
|
+
}),
|
|
313
|
+
}),
|
|
314
|
+
{},
|
|
315
|
+
)
|
|
316
|
+
const result = newAction.handler?.(
|
|
317
|
+
args,
|
|
318
|
+
{
|
|
319
|
+
root: ctx.root,
|
|
320
|
+
triggerActionEvent,
|
|
321
|
+
},
|
|
322
|
+
event,
|
|
323
|
+
)
|
|
324
|
+
// If the result is a function, then it should behave as a cleanup function, that runs, usually when the component is unmounted.
|
|
325
|
+
// Useful for removeEventListeners, clearTimeout, etc.
|
|
326
|
+
if (
|
|
327
|
+
result &&
|
|
328
|
+
(typeof result === 'function' || result instanceof Promise)
|
|
329
|
+
) {
|
|
330
|
+
ctx.dataSignal.subscribe((data) => data, {
|
|
331
|
+
destroy: () => {
|
|
332
|
+
if (result instanceof Promise) {
|
|
333
|
+
result
|
|
334
|
+
.then((cleanup) => {
|
|
335
|
+
if (typeof cleanup === 'function') {
|
|
336
|
+
cleanup()
|
|
337
|
+
}
|
|
338
|
+
})
|
|
339
|
+
.catch((err) => console.error(err))
|
|
340
|
+
} else {
|
|
341
|
+
result()
|
|
342
|
+
}
|
|
343
|
+
},
|
|
344
|
+
})
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
return result
|
|
348
|
+
} else {
|
|
349
|
+
const legacyHandler = ctx.toddle.getAction(action.name)
|
|
350
|
+
if (!legacyHandler) {
|
|
351
|
+
console.error('Missing custom action', action.name)
|
|
352
|
+
return
|
|
353
|
+
}
|
|
354
|
+
// First evaluate any arguments (input) to the action
|
|
355
|
+
const args = action.arguments?.map((arg) =>
|
|
356
|
+
applyFormula(arg.formula, {
|
|
357
|
+
data,
|
|
358
|
+
component: ctx.component,
|
|
359
|
+
formulaCache: ctx.formulaCache,
|
|
360
|
+
root: ctx.root,
|
|
361
|
+
package: ctx.package,
|
|
362
|
+
toddle: ctx.toddle,
|
|
363
|
+
env: ctx.env,
|
|
364
|
+
}),
|
|
365
|
+
) ?? [
|
|
366
|
+
applyFormula(action.data, {
|
|
367
|
+
data,
|
|
368
|
+
component: ctx.component,
|
|
369
|
+
formulaCache: ctx.formulaCache,
|
|
370
|
+
root: ctx.root,
|
|
371
|
+
package: ctx.package,
|
|
372
|
+
toddle: ctx.toddle,
|
|
373
|
+
env: ctx.env,
|
|
374
|
+
}),
|
|
375
|
+
] // action.data is a fallback to handle an older version of the action spec.
|
|
376
|
+
return legacyHandler(args, { ...ctx, triggerActionEvent }, event)
|
|
377
|
+
}
|
|
378
|
+
} catch (err) {
|
|
379
|
+
console.error('Error in Custom Action', err)
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
} catch (e) {
|
|
384
|
+
console.error(e)
|
|
385
|
+
return null
|
|
386
|
+
}
|
|
387
|
+
}
|