@ankhorage/runtime 4.1.2 → 5.0.2

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 (86) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/README.md +6 -6
  3. package/dist/RuntimeRenderer.d.ts +7 -7
  4. package/dist/RuntimeRenderer.d.ts.map +1 -1
  5. package/dist/RuntimeRenderer.js +40 -80
  6. package/dist/RuntimeRenderer.js.map +1 -1
  7. package/dist/RuntimeRendererConfig.d.ts +7 -22
  8. package/dist/RuntimeRendererConfig.d.ts.map +1 -1
  9. package/dist/RuntimeRendererConfig.js +5 -8
  10. package/dist/RuntimeRendererConfig.js.map +1 -1
  11. package/dist/RuntimeScreen.d.ts.map +1 -1
  12. package/dist/RuntimeScreen.js +10 -5
  13. package/dist/RuntimeScreen.js.map +1 -1
  14. package/dist/bindings.d.ts +4 -8
  15. package/dist/bindings.d.ts.map +1 -1
  16. package/dist/bindings.js +2 -4
  17. package/dist/bindings.js.map +1 -1
  18. package/dist/index.d.ts +10 -12
  19. package/dist/index.d.ts.map +1 -1
  20. package/dist/index.js +5 -6
  21. package/dist/index.js.map +1 -1
  22. package/dist/runtimeActionRegistry.d.ts +19 -24
  23. package/dist/runtimeActionRegistry.d.ts.map +1 -1
  24. package/dist/runtimeActionRegistry.js +90 -306
  25. package/dist/runtimeActionRegistry.js.map +1 -1
  26. package/dist/runtimeApiCapabilities.d.ts +11 -0
  27. package/dist/runtimeApiCapabilities.d.ts.map +1 -0
  28. package/dist/runtimeApiCapabilities.js +67 -0
  29. package/dist/runtimeApiCapabilities.js.map +1 -0
  30. package/dist/runtimeBindings.d.ts +28 -17
  31. package/dist/runtimeBindings.d.ts.map +1 -1
  32. package/dist/runtimeBindings.js +157 -197
  33. package/dist/runtimeBindings.js.map +1 -1
  34. package/dist/runtimeCapabilityExecutor.d.ts +8 -0
  35. package/dist/runtimeCapabilityExecutor.d.ts.map +1 -0
  36. package/dist/runtimeCapabilityExecutor.js +21 -0
  37. package/dist/runtimeCapabilityExecutor.js.map +1 -0
  38. package/dist/runtimeEventExecution.d.ts +1 -4
  39. package/dist/runtimeEventExecution.d.ts.map +1 -1
  40. package/dist/runtimeEventExecution.js.map +1 -1
  41. package/dist/runtimeEventOperationLifecycle.d.ts +4 -3
  42. package/dist/runtimeEventOperationLifecycle.d.ts.map +1 -1
  43. package/dist/runtimeEventOperationLifecycle.js +5 -5
  44. package/dist/runtimeEventOperationLifecycle.js.map +1 -1
  45. package/dist/runtimeNodeProps.d.ts +12 -24
  46. package/dist/runtimeNodeProps.d.ts.map +1 -1
  47. package/dist/runtimeNodeProps.js +27 -121
  48. package/dist/runtimeNodeProps.js.map +1 -1
  49. package/dist/runtimeRepeat.d.ts +6 -2
  50. package/dist/runtimeRepeat.d.ts.map +1 -1
  51. package/dist/runtimeRepeat.js +29 -108
  52. package/dist/runtimeRepeat.js.map +1 -1
  53. package/dist/runtimeScreenLoaders.d.ts +27 -42
  54. package/dist/runtimeScreenLoaders.d.ts.map +1 -1
  55. package/dist/runtimeScreenLoaders.js +113 -273
  56. package/dist/runtimeScreenLoaders.js.map +1 -1
  57. package/package.json +12 -6
  58. package/paradox/badges/npm.svg +3 -3
  59. package/paradox/components.md +6 -7
  60. package/paradox/diagrams/architecture-overview.mmd +25 -79
  61. package/paradox/diagrams/export-graph.mmd +67 -105
  62. package/paradox/diagrams/module-relationships.mmd +19 -59
  63. package/paradox/diagrams/sequences/apply-runtime-binding-data-path.mmd +14 -0
  64. package/paradox/diagrams/sequences/create-component-event-from-handler-args.mmd +0 -13
  65. package/paradox/diagrams/sequences/create-runtime-screen-loader-request-key.mmd +5 -0
  66. package/paradox/diagrams/sequences/execute-runtime-binding-invocation.mmd +19 -0
  67. package/paradox/diagrams/sequences/resolve-binding-input-map-sync.mmd +5 -0
  68. package/paradox/diagrams/sequences/resolve-binding-input-map.mmd +5 -0
  69. package/paradox/diagrams/sequences/runtime-screen.mmd +6 -3
  70. package/paradox/diagrams/sequences/use-runtime-screen-operation-loaders.mmd +6 -3
  71. package/paradox/exports.json +610 -848
  72. package/paradox/exports.md +280 -308
  73. package/paradox/index.html +1120 -2266
  74. package/paradox/paradox.json +2724 -5528
  75. package/dist/runtimeApiOperations.d.ts +0 -8
  76. package/dist/runtimeApiOperations.d.ts.map +0 -1
  77. package/dist/runtimeApiOperations.js +0 -38
  78. package/dist/runtimeApiOperations.js.map +0 -1
  79. package/dist/runtimeApiSelection.d.ts +0 -8
  80. package/dist/runtimeApiSelection.d.ts.map +0 -1
  81. package/dist/runtimeApiSelection.js +0 -52
  82. package/dist/runtimeApiSelection.js.map +0 -1
  83. package/dist/runtimeDbPersist.d.ts +0 -34
  84. package/dist/runtimeDbPersist.d.ts.map +0 -1
  85. package/dist/runtimeDbPersist.js +0 -73
  86. package/dist/runtimeDbPersist.js.map +0 -1
@@ -1,358 +1,142 @@
1
- import { isCapabilityId } from '@ankhorage/capability';
2
- import { resolveRuntimeBindingOperationSelection } from './runtimeApiSelection';
3
- import { createRuntimeBindingOperationKey, resolveBindingInputMap, } from './runtimeBindings';
1
+ import { isRecord } from '@ankhorage/utility/object';
2
+ import { executeRuntimeBindingInvocation, resolveRuntimeBindingExpressionSync, } from './runtimeBindings';
4
3
  import { resolveRuntimeEventOperationErrorMessage, } from './runtimeEventOperationLifecycle';
4
+ /*** Creates a registry that dispatches every authored event through one capability executor. */
5
5
  export function createRuntimeActionRegistry(options = {}) {
6
- const actionHandlers = { ...(options.actionHandlers ?? {}) };
7
6
  return {
8
7
  async dispatchComponentEvent(args) {
9
- await dispatchRuntimeComponentEvent({
10
- ...args,
11
- actionHandlers,
12
- apis: args.apis ?? options.apis,
13
- dataBindings: args.dataBindings ?? options.dataBindings,
14
- executeAction: args.executeAction ?? options.executeAction,
15
- executeOperation: args.executeOperation ?? options.executeOperation,
16
- eventOperationLifecycle: args.eventOperationLifecycle ?? options.eventOperationLifecycle,
17
- operationResults: args.operationResults ?? options.operationResults,
18
- writeOperationResult: args.writeOperationResult ?? options.writeOperationResult,
19
- });
20
- },
21
- registerActionHandler(type, handler) {
22
- actionHandlers[type] = handler;
23
- return () => {
24
- delete actionHandlers[type];
25
- };
8
+ await dispatchRuntimeComponentEvent({ ...options, ...args });
26
9
  },
27
10
  };
28
11
  }
12
+ /*** Executes every matching event invocation through the canonical capability path. */
29
13
  export async function dispatchRuntimeComponentEvent(args) {
30
- const { node, event, eventName = inferLocalEventName(event.type), actionHandlers } = args;
31
- const eventBindings = args.dataBindings?.[node.id]?.events?.[eventName] ??
32
- args.dataBindings?.[node.id]?.events?.[event.type] ??
14
+ const eventName = args.eventName ?? inferLocalEventName(args.event.type);
15
+ const bindings = args.dataBindings?.[args.node.id]?.events?.[eventName] ??
16
+ args.dataBindings?.[args.node.id]?.events?.[args.event.type] ??
33
17
  [];
34
18
  const diagnostics = [];
35
- const dispatchOperationResults = {
36
- ...(args.operationResults ?? {}),
37
- };
38
- const resolutionArgs = {
39
- ...args,
40
- operationResults: dispatchOperationResults,
41
- };
42
- for (const binding of eventBindings) {
43
- if (!matchesBindingCondition(binding.when, resolutionArgs))
19
+ const resultSlots = { ...(args.resultSlots ?? {}) };
20
+ for (const binding of bindings) {
21
+ const context = {
22
+ context: args.context,
23
+ event: args.event,
24
+ executeCapability: args.executeCapability,
25
+ resultSlots,
26
+ writeResultSlot: (slot, value) => {
27
+ resultSlots[slot] = value;
28
+ args.writeResultSlot?.(slot, value);
29
+ },
30
+ };
31
+ if (!matchesBindingCondition(binding.when, context))
44
32
  continue;
45
- if (binding.target.kind === 'action') {
46
- const capabilityId = resolveCapabilityId(binding.target.type);
47
- if (capabilityId === null) {
48
- diagnostics.push({
49
- code: 'invalid-action-capability',
50
- message: `Action '${binding.target.type}' is not a canonical namespaced capability id.`,
51
- severity: 'error',
52
- });
53
- continue;
54
- }
55
- const resolvedPayload = await resolveObjectEventBindingInput(binding.input, resolutionArgs, diagnostics);
56
- const action = resolvedPayload === undefined
57
- ? { type: capabilityId }
58
- : { type: capabilityId, payload: resolvedPayload };
59
- if (resolutionArgs.executeAction) {
60
- await resolutionArgs.executeAction({
61
- action,
62
- event,
63
- node,
64
- resolvedPayload,
65
- });
66
- continue;
67
- }
68
- const handler = actionHandlers?.[capabilityId];
69
- if (handler) {
70
- await handler({
71
- action,
72
- event,
73
- node,
74
- resolvedPayload,
75
- });
76
- continue;
77
- }
33
+ const lifecycle = args.eventOperationLifecycle?.start({
34
+ capability: binding.target.capability,
35
+ nodeId: args.node.id,
36
+ });
37
+ if (args.eventOperationLifecycle !== undefined && lifecycle === undefined)
38
+ break;
39
+ try {
40
+ const result = await executeRuntimeBindingInvocation(binding.target, context, { event: args.event, node: args.node }, diagnostics);
41
+ if (lifecycle !== undefined && result?.ok)
42
+ args.eventOperationLifecycle?.succeed(lifecycle);
43
+ else if (lifecycle !== undefined)
44
+ args.eventOperationLifecycle?.fail(lifecycle, resolveRuntimeEventOperationErrorMessage(diagnostics));
45
+ }
46
+ catch {
78
47
  diagnostics.push({
79
- code: 'missing-action-handler',
80
- message: `Action '${capabilityId}' could not be executed because no runtime executor or handler is registered.`,
48
+ code: 'adapter-error',
49
+ message: `Capability '${binding.target.capability}' could not be completed. Please try again.`,
81
50
  severity: 'error',
82
51
  });
83
- continue;
84
- }
85
- const operationSucceeded = await dispatchRuntimeOperationEventBinding({
86
- args: resolutionArgs,
87
- binding,
88
- diagnostics,
89
- operationResults: dispatchOperationResults,
90
- target: binding.target,
91
- });
92
- if (!operationSucceeded) {
52
+ if (lifecycle !== undefined)
53
+ args.eventOperationLifecycle?.fail(lifecycle, resolveRuntimeEventOperationErrorMessage(diagnostics));
93
54
  break;
94
55
  }
95
56
  }
96
57
  return diagnostics;
97
58
  }
59
+ /*** Wraps component callbacks so manifest event bindings retain the original callback behavior. */
98
60
  export function wrapRuntimeEventProps(args) {
99
- const { node, props, disableActions, dispatchComponentEvent } = args;
100
- const wrappedProps = { ...props };
101
- const nodeEventBindings = args.dataBindings?.[node.id]?.events;
102
- if (disableActions || !nodeEventBindings) {
103
- return wrappedProps;
104
- }
105
- for (const eventName of Object.keys(nodeEventBindings)) {
61
+ const props = { ...args.props };
62
+ if (args.disableActions || args.dataBindings?.[args.node.id]?.events === undefined)
63
+ return props;
64
+ for (const eventName of Object.keys(args.dataBindings[args.node.id]?.events ?? {})) {
106
65
  const propName = eventNameToCallbackProp(eventName);
107
- const existingHandler = wrappedProps[propName];
108
- wrappedProps[propName] = (...handlerArgs) => {
109
- let existingResult;
110
- if (isRuntimeEventHandler(existingHandler)) {
111
- existingResult = existingHandler(...handlerArgs);
112
- }
113
- void dispatchComponentEvent({
66
+ const existing = props[propName];
67
+ props[propName] = (...handlerArgs) => {
68
+ const result = isRuntimeEventHandler(existing) ? existing(...handlerArgs) : undefined;
69
+ void args.dispatchComponentEvent({
114
70
  context: args.context,
115
71
  dataBindings: args.dataBindings,
116
- event: createComponentEventFromHandlerArgs({ eventName, handlerArgs, node }),
72
+ event: createComponentEventFromHandlerArgs({
73
+ capability: args.resolveEventCapability?.({ eventName, node: args.node }),
74
+ eventName,
75
+ handlerArgs,
76
+ node: args.node,
77
+ }),
117
78
  eventName,
118
- node,
119
- operationResults: args.operationResults,
79
+ node: args.node,
80
+ resultSlots: args.resultSlots,
120
81
  state: args.state,
121
82
  });
122
- return existingResult;
83
+ return result;
123
84
  };
124
85
  }
125
- return wrappedProps;
86
+ return props;
126
87
  }
88
+ /*** Maps a platform callback invocation to the portable component event representation. */
127
89
  export function createComponentEventFromHandlerArgs(args) {
128
- const { node, eventName, handlerArgs } = args;
129
90
  return {
130
- payload: createPayloadForEvent(eventName, handlerArgs),
131
- sourceNodeId: node.id,
132
- type: localEventNameToEventType(eventName),
91
+ payload: createPayloadForEvent(args.eventName, args.handlerArgs),
92
+ sourceNodeId: args.node.id,
93
+ type: args.capability ?? args.eventName,
133
94
  };
134
95
  }
135
- export function resolveRuntimeActionPayload(payload, args) {
136
- if (payload === undefined) {
137
- return undefined;
138
- }
139
- return resolveRuntimeActionValue(payload, args);
140
- }
96
+ /*** Resolves an authored expression-shaped payload for imperative consumers. */
141
97
  export function resolveRuntimeActionValue(value, args) {
142
- if (!isRecord(value))
143
- return undefined;
144
- return Object.fromEntries(Object.entries(value).map(([key, entry]) => [key, resolveRuntimeActionValueEntry(entry, args)]));
145
- }
146
- async function dispatchRuntimeOperationEventBinding(args) {
147
- const { binding, diagnostics, target } = args;
148
- const invocation = args.args.eventOperationLifecycle?.start({
149
- nodeId: args.args.node.id,
150
- operation: target.operation,
151
- });
152
- if (args.args.eventOperationLifecycle !== undefined && invocation === undefined) {
153
- return false;
154
- }
155
- const failLifecycle = () => {
156
- if (invocation === undefined)
157
- return;
158
- args.args.eventOperationLifecycle?.fail(invocation, resolveRuntimeEventOperationErrorMessage(diagnostics));
159
- };
160
- if (args.args.executeOperation === undefined) {
161
- diagnostics.push({
162
- apiId: target.operation.apiId,
163
- code: 'missing-adapter',
164
- endpointId: target.operation.endpointId,
165
- operationId: target.operation.operationId,
166
- message: 'Event API operation binding requires an injected operation executor.',
167
- severity: 'error',
168
- });
169
- failLifecycle();
170
- return false;
171
- }
172
- const selection = resolveRuntimeBindingOperationSelection(target.operation, args.args.apis, diagnostics);
173
- if (selection === undefined) {
174
- failLifecycle();
175
- return false;
176
- }
177
- let result;
178
- try {
179
- result = await args.args.executeOperation({
180
- api: selection.api,
181
- endpoint: selection.endpoint,
182
- input: await resolveEventBindingInput(binding.input, args.args, diagnostics),
183
- node: args.args.node,
184
- operation: target.operation,
185
- });
186
- }
187
- catch {
188
- diagnostics.push({
189
- apiId: target.operation.apiId,
190
- code: 'adapter-error',
191
- endpointId: target.operation.endpointId,
192
- message: 'The operation could not be completed. Please try again.',
193
- operationId: target.operation.operationId,
194
- severity: 'error',
195
- });
196
- failLifecycle();
197
- return false;
198
- }
199
- diagnostics.push(...(result.diagnostics ?? []));
200
- if (result.ok) {
201
- const operationKey = createRuntimeBindingOperationKey(target.operation);
202
- args.operationResults[operationKey] = result.data;
203
- args.args.writeOperationResult?.(operationKey, result.data);
204
- if (invocation !== undefined) {
205
- args.args.eventOperationLifecycle?.succeed(invocation);
206
- }
207
- return true;
208
- }
209
- failLifecycle();
210
- return false;
98
+ return resolveRuntimeBindingExpressionSync(value, args);
211
99
  }
212
- function resolveRuntimeActionValueEntry(value, args) {
213
- if (Array.isArray(value))
214
- return value.map((item) => resolveRuntimeActionValueEntry(item, args));
215
- if (!isRecord(value))
216
- return value;
217
- if (!('valueFrom' in value)) {
218
- return Object.fromEntries(Object.entries(value).map(([key, entry]) => [
219
- key,
220
- resolveRuntimeActionValueEntry(entry, args),
221
- ]));
222
- }
223
- return undefined;
224
- }
225
- async function resolveObjectEventBindingInput(input, args, diagnostics) {
226
- const value = await resolveEventBindingInput(input, args, diagnostics);
227
- return isRecord(value) ? value : undefined;
228
- }
229
- async function resolveEventBindingInput(input, args, diagnostics) {
230
- return resolveBindingInputMap(input, {
231
- apis: args.apis,
232
- context: args.context,
233
- dataBindings: args.dataBindings,
234
- event: args.event,
235
- executeOperation: args.executeOperation,
236
- operationResults: args.operationResults,
237
- }, diagnostics);
238
- }
239
- function matchesBindingCondition(condition, args) {
100
+ function matchesBindingCondition(condition, context) {
240
101
  if (condition === undefined)
241
102
  return true;
242
- const value = readBindingConditionSource(condition, args);
243
- switch (condition.operator) {
244
- case 'eq':
245
- return value === condition.value;
246
- case 'exists':
247
- return value !== undefined;
248
- case 'neq':
249
- return value !== condition.value;
250
- case 'notExists':
251
- return value === undefined;
252
- }
253
- }
254
- function readBindingConditionSource(condition, args) {
255
- switch (condition.source.kind) {
256
- case 'context':
257
- return readPath(args.context, condition.source.path);
258
- case 'event':
259
- return readPath(args.event, condition.source.path);
260
- case 'literal':
261
- return condition.source.value;
262
- case 'operation': {
263
- const operationResult = args.operationResults?.[createRuntimeBindingOperationKey(condition.source.operation)];
264
- return condition.source.path === undefined
265
- ? operationResult
266
- : readPath(operationResult, condition.source.path);
267
- }
268
- case 'state':
269
- return readPath(args.state, condition.source.path);
270
- }
271
- }
272
- function createPayloadForEvent(eventName, handlerArgs) {
273
- if (eventName === 'barcodeScanned') {
274
- return createBarcodeScannedPayload(handlerArgs[0]);
275
- }
276
- if (eventName === 'submit') {
277
- return { values: asRecord(handlerArgs[0]) ?? {} };
278
- }
103
+ const source = resolveRuntimeBindingExpressionSync(condition.source, context);
104
+ const value = condition.value === undefined
105
+ ? undefined
106
+ : resolveRuntimeBindingExpressionSync(condition.value, context);
107
+ if (condition.operator === 'exists')
108
+ return source !== undefined;
109
+ if (condition.operator === 'notExists')
110
+ return source === undefined;
111
+ if (condition.operator === 'eq')
112
+ return source === value;
113
+ return source !== value;
114
+ }
115
+ function createPayloadForEvent(eventName, args) {
116
+ if (eventName === 'submit')
117
+ return { values: asRecord(args[0]) ?? {} };
118
+ if (eventName === 'changeText' || eventName === 'valueChange')
119
+ return { value: args[0] };
120
+ if (eventName === 'checkedChange')
121
+ return { checked: args[0] };
279
122
  if (eventName === 'itemPress') {
280
- const item = asRecord(handlerArgs[0]) ?? {};
281
- const itemId = readItemId(handlerArgs[0]);
282
- return itemId === undefined ? { item } : { itemId, item };
123
+ const item = asRecord(args[0]) ?? {};
124
+ return typeof item.id === 'string' || typeof item.id === 'number'
125
+ ? { item, itemId: item.id }
126
+ : { item };
283
127
  }
284
- if (eventName === 'changeText' || eventName === 'valueChange') {
285
- return { value: handlerArgs[0] };
286
- }
287
- if (eventName === 'checkedChange') {
288
- return { checked: handlerArgs[0] };
289
- }
290
- if (eventName === 'manualEntry') {
291
- return handlerArgs[0] === undefined ? {} : { value: handlerArgs[0] };
292
- }
293
- if (eventName === 'requestPermission' || eventName === 'press') {
294
- return {};
295
- }
296
- return asRecord(handlerArgs[0]) ?? {};
297
- }
298
- function localEventNameToEventType(eventName) {
299
- if (eventName === 'itemPress')
300
- return 'collection.itemPress';
301
- if (eventName === 'press')
302
- return 'button.press';
303
- if (eventName === 'submit')
304
- return 'form.submit';
305
- return eventName;
128
+ return asRecord(args[0]) ?? {};
306
129
  }
307
130
  function inferLocalEventName(eventType) {
308
- const parts = eventType.split('.');
309
- return parts.at(-1) ?? eventType;
131
+ return eventType.split('.').at(-1) ?? eventType;
310
132
  }
311
133
  function eventNameToCallbackProp(eventName) {
312
134
  return `on${eventName.charAt(0).toUpperCase()}${eventName.slice(1)}`;
313
135
  }
314
- /*** Resolve a canonical namespaced capability id from authored action metadata. */
315
- function resolveCapabilityId(value) {
316
- return isCapabilityId(value) ? value : null;
317
- }
318
136
  function isRuntimeEventHandler(value) {
319
137
  return typeof value === 'function';
320
138
  }
321
- function readPath(source, path) {
322
- if (path.length === 0)
323
- return source;
324
- return path.split('.').reduce((currentValue, part) => {
325
- if (!isRecord(currentValue))
326
- return undefined;
327
- return currentValue[part];
328
- }, source);
329
- }
330
- function createBarcodeScannedPayload(value) {
331
- if (typeof value === 'string') {
332
- return { value };
333
- }
334
- if (!isRecord(value)) {
335
- return {};
336
- }
337
- const payload = {};
338
- if (typeof value.value === 'string')
339
- payload.value = value.value;
340
- if (typeof value.type === 'string')
341
- payload.type = value.type;
342
- return payload;
343
- }
344
- function readItemId(value) {
345
- if (typeof value === 'string' || typeof value === 'number')
346
- return value;
347
- if (!isRecord(value))
348
- return undefined;
349
- const id = value.id ?? value.itemId;
350
- return typeof id === 'string' || typeof id === 'number' ? id : undefined;
351
- }
352
139
  function asRecord(value) {
353
140
  return isRecord(value) ? value : undefined;
354
141
  }
355
- function isRecord(value) {
356
- return typeof value === 'object' && value !== null && !Array.isArray(value);
357
- }
358
142
  //# sourceMappingURL=runtimeActionRegistry.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"runtimeActionRegistry.js","sourceRoot":"","sources":["../src/runtimeActionRegistry.ts"],"names":[],"mappings":"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","sourcesContent":["import { isCapabilityId } from '@ankhorage/capability';\nimport type {\n ApiDefinitionRegistry,\n BindingCondition,\n BindingInputMap,\n BindingValue,\n ComponentDataBindingRegistry,\n ComponentEventDto,\n DataSourceDiagnostic,\n EventBinding,\n EventBindingTarget,\n UiNode,\n} from '@ankhorage/contracts';\nimport type { Capability } from '@ankhorage/contracts/capability';\n\nimport { resolveRuntimeBindingOperationSelection } from './runtimeApiSelection';\nimport {\n createRuntimeBindingOperationKey,\n resolveBindingInputMap,\n type RuntimeBindingOperationExecutor,\n type RuntimeBindingOperationResultCache,\n type RuntimeBindingOperationResultWriter,\n} from './runtimeBindings';\nimport {\n resolveRuntimeEventOperationErrorMessage,\n type RuntimeEventOperationLifecycle,\n} from './runtimeEventOperationLifecycle';\nimport type { RuntimeActionHandler, RuntimeActionHandlers } from './RuntimeRendererConfig';\n\ntype RuntimeEventPayload = Record<string, unknown>;\n\ntype RuntimeEventHandler = (...args: unknown[]) => unknown;\n\ntype RuntimeOperationEventTarget = Extract<EventBindingTarget, { readonly kind: 'operation' }>;\n\nexport interface RuntimeActionRegistry {\n dispatchComponentEvent(args: RuntimeComponentEventDispatchArgs): Promise<void>;\n registerActionHandler(type: Capability['id'], handler: RuntimeActionHandler): () => void;\n}\n\nexport interface RuntimeActionResolutionScope {\n readonly context?: Record<string, unknown>;\n readonly operationResults?: RuntimeBindingOperationResultCache;\n readonly state?: Record<string, unknown>;\n}\n\nexport interface RuntimeActionResolutionArgs extends RuntimeActionResolutionScope {\n readonly event: ComponentEventDto<string, object>;\n}\n\nexport interface RuntimeComponentEventDispatchArgs extends RuntimeActionResolutionScope {\n readonly node: UiNode;\n readonly event: ComponentEventDto<string, object>;\n readonly eventName?: string;\n readonly executeAction?: RuntimeActionHandler;\n readonly apis?: ApiDefinitionRegistry;\n readonly dataBindings?: ComponentDataBindingRegistry;\n readonly executeOperation?: RuntimeBindingOperationExecutor;\n readonly writeOperationResult?: RuntimeBindingOperationResultWriter;\n readonly eventOperationLifecycle?: RuntimeEventOperationLifecycle;\n}\n\nexport interface RuntimeEventPropWrapArgs extends RuntimeActionResolutionScope {\n readonly node: UiNode;\n readonly props: Record<string, unknown>;\n readonly disableActions: boolean;\n readonly dataBindings?: ComponentDataBindingRegistry;\n readonly dispatchComponentEvent: (\n args: RuntimeComponentEventDispatchArgs,\n ) => Promise<void> | void;\n}\n\nexport function createRuntimeActionRegistry(\n options: {\n actionHandlers?: RuntimeActionHandlers;\n apis?: ApiDefinitionRegistry;\n dataBindings?: ComponentDataBindingRegistry;\n executeAction?: RuntimeActionHandler;\n executeOperation?: RuntimeBindingOperationExecutor;\n eventOperationLifecycle?: RuntimeEventOperationLifecycle;\n operationResults?: RuntimeBindingOperationResultCache;\n writeOperationResult?: RuntimeBindingOperationResultWriter;\n } = {},\n): RuntimeActionRegistry {\n const actionHandlers: RuntimeActionHandlers = { ...(options.actionHandlers ?? {}) };\n\n return {\n async dispatchComponentEvent(args) {\n await dispatchRuntimeComponentEvent({\n ...args,\n actionHandlers,\n apis: args.apis ?? options.apis,\n dataBindings: args.dataBindings ?? options.dataBindings,\n executeAction: args.executeAction ?? options.executeAction,\n executeOperation: args.executeOperation ?? options.executeOperation,\n eventOperationLifecycle: args.eventOperationLifecycle ?? options.eventOperationLifecycle,\n operationResults: args.operationResults ?? options.operationResults,\n writeOperationResult: args.writeOperationResult ?? options.writeOperationResult,\n });\n },\n registerActionHandler(type, handler) {\n actionHandlers[type] = handler;\n\n return () => {\n delete actionHandlers[type];\n };\n },\n };\n}\n\nexport async function dispatchRuntimeComponentEvent(\n args: RuntimeComponentEventDispatchArgs & {\n readonly actionHandlers?: RuntimeActionHandlers;\n },\n): Promise<readonly DataSourceDiagnostic[]> {\n const { node, event, eventName = inferLocalEventName(event.type), actionHandlers } = args;\n const eventBindings: readonly EventBinding[] =\n args.dataBindings?.[node.id]?.events?.[eventName] ??\n args.dataBindings?.[node.id]?.events?.[event.type] ??\n [];\n const diagnostics: DataSourceDiagnostic[] = [];\n const dispatchOperationResults: Record<string, BindingValue | undefined> = {\n ...(args.operationResults ?? {}),\n };\n const resolutionArgs: RuntimeComponentEventDispatchArgs = {\n ...args,\n operationResults: dispatchOperationResults,\n };\n\n for (const binding of eventBindings) {\n if (!matchesBindingCondition(binding.when, resolutionArgs)) continue;\n\n if (binding.target.kind === 'action') {\n const capabilityId = resolveCapabilityId(binding.target.type);\n if (capabilityId === null) {\n diagnostics.push({\n code: 'invalid-action-capability',\n message: `Action '${binding.target.type}' is not a canonical namespaced capability id.`,\n severity: 'error',\n });\n continue;\n }\n\n const resolvedPayload = await resolveObjectEventBindingInput(\n binding.input,\n resolutionArgs,\n diagnostics,\n );\n const action =\n resolvedPayload === undefined\n ? { type: capabilityId }\n : { type: capabilityId, payload: resolvedPayload };\n if (resolutionArgs.executeAction) {\n await resolutionArgs.executeAction({\n action,\n event,\n node,\n resolvedPayload,\n });\n continue;\n }\n\n const handler = actionHandlers?.[capabilityId];\n if (handler) {\n await handler({\n action,\n event,\n node,\n resolvedPayload,\n });\n continue;\n }\n\n diagnostics.push({\n code: 'missing-action-handler',\n message: `Action '${capabilityId}' could not be executed because no runtime executor or handler is registered.`,\n severity: 'error',\n });\n continue;\n }\n\n const operationSucceeded = await dispatchRuntimeOperationEventBinding({\n args: resolutionArgs,\n binding,\n diagnostics,\n operationResults: dispatchOperationResults,\n target: binding.target,\n });\n\n if (!operationSucceeded) {\n break;\n }\n }\n\n return diagnostics;\n}\n\nexport function wrapRuntimeEventProps(args: RuntimeEventPropWrapArgs): Record<string, unknown> {\n const { node, props, disableActions, dispatchComponentEvent } = args;\n const wrappedProps: Record<string, unknown> = { ...props };\n const nodeEventBindings = args.dataBindings?.[node.id]?.events;\n\n if (disableActions || !nodeEventBindings) {\n return wrappedProps;\n }\n\n for (const eventName of Object.keys(nodeEventBindings)) {\n const propName = eventNameToCallbackProp(eventName);\n const existingHandler = wrappedProps[propName];\n\n wrappedProps[propName] = (...handlerArgs: unknown[]) => {\n let existingResult: unknown;\n\n if (isRuntimeEventHandler(existingHandler)) {\n existingResult = existingHandler(...handlerArgs);\n }\n\n void dispatchComponentEvent({\n context: args.context,\n dataBindings: args.dataBindings,\n event: createComponentEventFromHandlerArgs({ eventName, handlerArgs, node }),\n eventName,\n node,\n operationResults: args.operationResults,\n state: args.state,\n });\n\n return existingResult;\n };\n }\n\n return wrappedProps;\n}\n\nexport function createComponentEventFromHandlerArgs(args: {\n readonly node: UiNode;\n readonly eventName: string;\n readonly handlerArgs: readonly unknown[];\n}): ComponentEventDto<string, RuntimeEventPayload> {\n const { node, eventName, handlerArgs } = args;\n\n return {\n payload: createPayloadForEvent(eventName, handlerArgs),\n sourceNodeId: node.id,\n type: localEventNameToEventType(eventName),\n };\n}\n\nexport function resolveRuntimeActionPayload(\n payload: object | undefined,\n args: RuntimeActionResolutionArgs,\n): object | undefined {\n if (payload === undefined) {\n return undefined;\n }\n\n return resolveRuntimeActionValue(payload, args);\n}\n\nexport function resolveRuntimeActionValue(\n value: unknown,\n args: RuntimeActionResolutionArgs,\n): object | undefined {\n if (!isRecord(value)) return undefined;\n\n return Object.fromEntries(\n Object.entries(value).map(([key, entry]) => [key, resolveRuntimeActionValueEntry(entry, args)]),\n );\n}\n\nasync function dispatchRuntimeOperationEventBinding(args: {\n readonly args: RuntimeComponentEventDispatchArgs;\n readonly binding: EventBinding;\n readonly diagnostics: DataSourceDiagnostic[];\n readonly operationResults: Record<string, BindingValue | undefined>;\n readonly target: RuntimeOperationEventTarget;\n}): Promise<boolean> {\n const { binding, diagnostics, target } = args;\n const invocation = args.args.eventOperationLifecycle?.start({\n nodeId: args.args.node.id,\n operation: target.operation,\n });\n\n if (args.args.eventOperationLifecycle !== undefined && invocation === undefined) {\n return false;\n }\n\n const failLifecycle = () => {\n if (invocation === undefined) return;\n args.args.eventOperationLifecycle?.fail(\n invocation,\n resolveRuntimeEventOperationErrorMessage(diagnostics),\n );\n };\n\n if (args.args.executeOperation === undefined) {\n diagnostics.push({\n apiId: target.operation.apiId,\n code: 'missing-adapter',\n endpointId: target.operation.endpointId,\n operationId: target.operation.operationId,\n message: 'Event API operation binding requires an injected operation executor.',\n severity: 'error',\n });\n failLifecycle();\n return false;\n }\n\n const selection = resolveRuntimeBindingOperationSelection(\n target.operation,\n args.args.apis,\n diagnostics,\n );\n if (selection === undefined) {\n failLifecycle();\n return false;\n }\n\n let result;\n try {\n result = await args.args.executeOperation({\n api: selection.api,\n endpoint: selection.endpoint,\n input: await resolveEventBindingInput(binding.input, args.args, diagnostics),\n node: args.args.node,\n operation: target.operation,\n });\n } catch {\n diagnostics.push({\n apiId: target.operation.apiId,\n code: 'adapter-error',\n endpointId: target.operation.endpointId,\n message: 'The operation could not be completed. Please try again.',\n operationId: target.operation.operationId,\n severity: 'error',\n });\n failLifecycle();\n return false;\n }\n diagnostics.push(...(result.diagnostics ?? []));\n\n if (result.ok) {\n const operationKey = createRuntimeBindingOperationKey(target.operation);\n args.operationResults[operationKey] = result.data;\n args.args.writeOperationResult?.(operationKey, result.data);\n if (invocation !== undefined) {\n args.args.eventOperationLifecycle?.succeed(invocation);\n }\n return true;\n }\n\n failLifecycle();\n return false;\n}\n\nfunction resolveRuntimeActionValueEntry(\n value: unknown,\n args: RuntimeActionResolutionArgs,\n): unknown {\n if (Array.isArray(value)) return value.map((item) => resolveRuntimeActionValueEntry(item, args));\n if (!isRecord(value)) return value;\n if (!('valueFrom' in value)) {\n return Object.fromEntries(\n Object.entries(value).map(([key, entry]) => [\n key,\n resolveRuntimeActionValueEntry(entry, args),\n ]),\n );\n }\n\n return undefined;\n}\n\nasync function resolveObjectEventBindingInput(\n input: BindingInputMap | undefined,\n args: RuntimeComponentEventDispatchArgs,\n diagnostics: DataSourceDiagnostic[],\n): Promise<object | undefined> {\n const value = await resolveEventBindingInput(input, args, diagnostics);\n return isRecord(value) ? value : undefined;\n}\n\nasync function resolveEventBindingInput(\n input: BindingInputMap | undefined,\n args: RuntimeComponentEventDispatchArgs,\n diagnostics: DataSourceDiagnostic[],\n) {\n return resolveBindingInputMap(\n input,\n {\n apis: args.apis,\n context: args.context,\n dataBindings: args.dataBindings,\n event: args.event,\n executeOperation: args.executeOperation,\n operationResults: args.operationResults,\n },\n diagnostics,\n );\n}\n\nfunction matchesBindingCondition(\n condition: BindingCondition | undefined,\n args: RuntimeActionResolutionArgs,\n): boolean {\n if (condition === undefined) return true;\n\n const value = readBindingConditionSource(condition, args);\n\n switch (condition.operator) {\n case 'eq':\n return value === condition.value;\n case 'exists':\n return value !== undefined;\n case 'neq':\n return value !== condition.value;\n case 'notExists':\n return value === undefined;\n }\n}\n\nfunction readBindingConditionSource(\n condition: BindingCondition,\n args: RuntimeActionResolutionArgs,\n): unknown {\n switch (condition.source.kind) {\n case 'context':\n return readPath(args.context, condition.source.path);\n case 'event':\n return readPath(args.event, condition.source.path);\n case 'literal':\n return condition.source.value;\n case 'operation': {\n const operationResult =\n args.operationResults?.[createRuntimeBindingOperationKey(condition.source.operation)];\n return condition.source.path === undefined\n ? operationResult\n : readPath(operationResult, condition.source.path);\n }\n case 'state':\n return readPath(args.state, condition.source.path);\n }\n}\n\nfunction createPayloadForEvent(\n eventName: string,\n handlerArgs: readonly unknown[],\n): RuntimeEventPayload {\n if (eventName === 'barcodeScanned') {\n return createBarcodeScannedPayload(handlerArgs[0]);\n }\n\n if (eventName === 'submit') {\n return { values: asRecord(handlerArgs[0]) ?? {} };\n }\n\n if (eventName === 'itemPress') {\n const item = asRecord(handlerArgs[0]) ?? {};\n const itemId = readItemId(handlerArgs[0]);\n\n return itemId === undefined ? { item } : { itemId, item };\n }\n\n if (eventName === 'changeText' || eventName === 'valueChange') {\n return { value: handlerArgs[0] };\n }\n\n if (eventName === 'checkedChange') {\n return { checked: handlerArgs[0] };\n }\n\n if (eventName === 'manualEntry') {\n return handlerArgs[0] === undefined ? {} : { value: handlerArgs[0] };\n }\n\n if (eventName === 'requestPermission' || eventName === 'press') {\n return {};\n }\n\n return asRecord(handlerArgs[0]) ?? {};\n}\n\nfunction localEventNameToEventType(eventName: string): string {\n if (eventName === 'itemPress') return 'collection.itemPress';\n if (eventName === 'press') return 'button.press';\n if (eventName === 'submit') return 'form.submit';\n\n return eventName;\n}\n\nfunction inferLocalEventName(eventType: string): string {\n const parts = eventType.split('.');\n\n return parts.at(-1) ?? eventType;\n}\n\nfunction eventNameToCallbackProp(eventName: string): string {\n return `on${eventName.charAt(0).toUpperCase()}${eventName.slice(1)}`;\n}\n\n/*** Resolve a canonical namespaced capability id from authored action metadata. */\nfunction resolveCapabilityId(value: string): Capability['id'] | null {\n return isCapabilityId(value) ? value : null;\n}\n\nfunction isRuntimeEventHandler(value: unknown): value is RuntimeEventHandler {\n return typeof value === 'function';\n}\n\nfunction readPath(source: unknown, path: string): unknown {\n if (path.length === 0) return source;\n\n return path.split('.').reduce<unknown>((currentValue, part) => {\n if (!isRecord(currentValue)) return undefined;\n return currentValue[part];\n }, source);\n}\n\nfunction createBarcodeScannedPayload(value: unknown): RuntimeEventPayload {\n if (typeof value === 'string') {\n return { value };\n }\n\n if (!isRecord(value)) {\n return {};\n }\n\n const payload: RuntimeEventPayload = {};\n if (typeof value.value === 'string') payload.value = value.value;\n if (typeof value.type === 'string') payload.type = value.type;\n\n return payload;\n}\n\nfunction readItemId(value: unknown): string | number | undefined {\n if (typeof value === 'string' || typeof value === 'number') return value;\n if (!isRecord(value)) return undefined;\n\n const id = value.id ?? value.itemId;\n\n return typeof id === 'string' || typeof id === 'number' ? id : undefined;\n}\n\nfunction asRecord(value: unknown): Record<string, unknown> | undefined {\n return isRecord(value) ? value : undefined;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n"]}
1
+ {"version":3,"file":"runtimeActionRegistry.js","sourceRoot":"","sources":["../src/runtimeActionRegistry.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n BindingCondition,\n BindingExpression,\n BindingValue,\n ComponentDataBindingRegistry,\n ComponentEventDto,\n DataSourceDiagnostic,\n UiNode,\n} from '@ankhorage/contracts';\nimport type { Capability } from '@ankhorage/contracts/capability';\nimport { isRecord } from '@ankhorage/utility/object';\n\nimport {\n executeRuntimeBindingInvocation,\n resolveRuntimeBindingExpressionSync,\n type RuntimeBindingResultCache,\n type RuntimeBindingResultWriter,\n type RuntimeCapabilityExecutor,\n} from './runtimeBindings';\nimport {\n resolveRuntimeEventOperationErrorMessage,\n type RuntimeEventOperationLifecycle,\n} from './runtimeEventOperationLifecycle';\n\ntype RuntimeEventPayload = Record<string, unknown>;\ntype RuntimeEventHandler = (...args: unknown[]) => unknown;\n\nexport type RuntimeEventCapabilityResolver = (args: {\n readonly eventName: string;\n readonly node: UiNode;\n}) => Capability['id'] | undefined;\n\nexport interface RuntimeActionRegistry {\n dispatchComponentEvent(args: RuntimeComponentEventDispatchArgs): Promise<void>;\n}\n\nexport interface RuntimeActionResolutionScope {\n readonly context?: Record<string, unknown>;\n readonly resultSlots?: RuntimeBindingResultCache;\n readonly state?: Record<string, unknown>;\n}\n\nexport interface RuntimeActionResolutionArgs extends RuntimeActionResolutionScope {\n readonly event: ComponentEventDto<string, object>;\n}\n\nexport interface RuntimeComponentEventDispatchArgs extends RuntimeActionResolutionScope {\n readonly node: UiNode;\n readonly event: ComponentEventDto<string, object>;\n readonly eventName?: string;\n readonly dataBindings?: ComponentDataBindingRegistry;\n readonly executeCapability?: RuntimeCapabilityExecutor;\n readonly writeResultSlot?: RuntimeBindingResultWriter;\n readonly eventOperationLifecycle?: RuntimeEventOperationLifecycle;\n}\n\nexport interface RuntimeEventPropWrapArgs extends RuntimeActionResolutionScope {\n readonly node: UiNode;\n readonly props: Record<string, unknown>;\n readonly disableActions: boolean;\n readonly dataBindings?: ComponentDataBindingRegistry;\n readonly dispatchComponentEvent: (\n args: RuntimeComponentEventDispatchArgs,\n ) => Promise<void> | void;\n readonly resolveEventCapability?: RuntimeEventCapabilityResolver;\n}\n\n/*** Creates a registry that dispatches every authored event through one capability executor. */\nexport function createRuntimeActionRegistry(\n options: Pick<\n RuntimeComponentEventDispatchArgs,\n | 'dataBindings'\n | 'eventOperationLifecycle'\n | 'executeCapability'\n | 'resultSlots'\n | 'writeResultSlot'\n > = {},\n): RuntimeActionRegistry {\n return {\n async dispatchComponentEvent(args) {\n await dispatchRuntimeComponentEvent({ ...options, ...args });\n },\n };\n}\n\n/*** Executes every matching event invocation through the canonical capability path. */\nexport async function dispatchRuntimeComponentEvent(\n args: RuntimeComponentEventDispatchArgs,\n): Promise<readonly DataSourceDiagnostic[]> {\n const eventName = args.eventName ?? inferLocalEventName(args.event.type);\n const bindings =\n args.dataBindings?.[args.node.id]?.events?.[eventName] ??\n args.dataBindings?.[args.node.id]?.events?.[args.event.type] ??\n [];\n const diagnostics: DataSourceDiagnostic[] = [];\n const resultSlots: Record<string, BindingValue | undefined> = { ...(args.resultSlots ?? {}) };\n\n for (const binding of bindings) {\n const context = {\n context: args.context,\n event: args.event,\n executeCapability: args.executeCapability,\n resultSlots,\n writeResultSlot: (slot: string, value: BindingValue) => {\n resultSlots[slot] = value;\n args.writeResultSlot?.(slot, value);\n },\n };\n if (!matchesBindingCondition(binding.when, context)) continue;\n\n const lifecycle = args.eventOperationLifecycle?.start({\n capability: binding.target.capability,\n nodeId: args.node.id,\n });\n if (args.eventOperationLifecycle !== undefined && lifecycle === undefined) break;\n\n try {\n const result = await executeRuntimeBindingInvocation(\n binding.target,\n context,\n { event: args.event, node: args.node },\n diagnostics,\n );\n if (lifecycle !== undefined && result?.ok) args.eventOperationLifecycle?.succeed(lifecycle);\n else if (lifecycle !== undefined)\n args.eventOperationLifecycle?.fail(\n lifecycle,\n resolveRuntimeEventOperationErrorMessage(diagnostics),\n );\n } catch {\n diagnostics.push({\n code: 'adapter-error',\n message: `Capability '${binding.target.capability}' could not be completed. Please try again.`,\n severity: 'error',\n });\n if (lifecycle !== undefined)\n args.eventOperationLifecycle?.fail(\n lifecycle,\n resolveRuntimeEventOperationErrorMessage(diagnostics),\n );\n break;\n }\n }\n\n return diagnostics;\n}\n\n/*** Wraps component callbacks so manifest event bindings retain the original callback behavior. */\nexport function wrapRuntimeEventProps(args: RuntimeEventPropWrapArgs): Record<string, unknown> {\n const props = { ...args.props };\n if (args.disableActions || args.dataBindings?.[args.node.id]?.events === undefined) return props;\n\n for (const eventName of Object.keys(args.dataBindings[args.node.id]?.events ?? {})) {\n const propName = eventNameToCallbackProp(eventName);\n const existing = props[propName];\n props[propName] = (...handlerArgs: unknown[]) => {\n const result = isRuntimeEventHandler(existing) ? existing(...handlerArgs) : undefined;\n void args.dispatchComponentEvent({\n context: args.context,\n dataBindings: args.dataBindings,\n event: createComponentEventFromHandlerArgs({\n capability: args.resolveEventCapability?.({ eventName, node: args.node }),\n eventName,\n handlerArgs,\n node: args.node,\n }),\n eventName,\n node: args.node,\n resultSlots: args.resultSlots,\n state: args.state,\n });\n return result;\n };\n }\n return props;\n}\n\n/*** Maps a platform callback invocation to the portable component event representation. */\nexport function createComponentEventFromHandlerArgs(args: {\n readonly capability?: Capability['id'];\n readonly node: UiNode;\n readonly eventName: string;\n readonly handlerArgs: readonly unknown[];\n}): ComponentEventDto<string, RuntimeEventPayload> {\n return {\n payload: createPayloadForEvent(args.eventName, args.handlerArgs),\n sourceNodeId: args.node.id,\n type: args.capability ?? args.eventName,\n };\n}\n\n/*** Resolves an authored expression-shaped payload for imperative consumers. */\nexport function resolveRuntimeActionValue(\n value: BindingExpression,\n args: RuntimeActionResolutionArgs,\n): BindingValue | undefined {\n return resolveRuntimeBindingExpressionSync(value, args);\n}\n\nfunction matchesBindingCondition(\n condition: BindingCondition | undefined,\n context: Parameters<typeof resolveRuntimeBindingExpressionSync>[1],\n): boolean {\n if (condition === undefined) return true;\n const source = resolveRuntimeBindingExpressionSync(condition.source, context);\n const value =\n condition.value === undefined\n ? undefined\n : resolveRuntimeBindingExpressionSync(condition.value, context);\n if (condition.operator === 'exists') return source !== undefined;\n if (condition.operator === 'notExists') return source === undefined;\n if (condition.operator === 'eq') return source === value;\n return source !== value;\n}\n\nfunction createPayloadForEvent(eventName: string, args: readonly unknown[]): RuntimeEventPayload {\n if (eventName === 'submit') return { values: asRecord(args[0]) ?? {} };\n if (eventName === 'changeText' || eventName === 'valueChange') return { value: args[0] };\n if (eventName === 'checkedChange') return { checked: args[0] };\n if (eventName === 'itemPress') {\n const item = asRecord(args[0]) ?? {};\n return typeof item.id === 'string' || typeof item.id === 'number'\n ? { item, itemId: item.id }\n : { item };\n }\n return asRecord(args[0]) ?? {};\n}\n\nfunction inferLocalEventName(eventType: string): string {\n return eventType.split('.').at(-1) ?? eventType;\n}\n\nfunction eventNameToCallbackProp(eventName: string): string {\n return `on${eventName.charAt(0).toUpperCase()}${eventName.slice(1)}`;\n}\n\nfunction isRuntimeEventHandler(value: unknown): value is RuntimeEventHandler {\n return typeof value === 'function';\n}\n\nfunction asRecord(value: unknown): Record<string, unknown> | undefined {\n return isRecord(value) ? value : undefined;\n}\n"]}
@@ -0,0 +1,11 @@
1
+ import type { ApiDefinitionRegistry } from '@ankhorage/contracts';
2
+ import type { EndpointTestCredentialResolver, EndpointTestFetch } from '@ankhorage/data-sources';
3
+ import type { RuntimeCapabilityExecutor } from './runtimeBindings';
4
+ export interface RuntimeApiCapabilityExecutorOptions {
5
+ readonly apis: ApiDefinitionRegistry;
6
+ readonly fetch?: EndpointTestFetch;
7
+ readonly credentialResolver?: EndpointTestCredentialResolver;
8
+ }
9
+ /*** Creates the canonical API capability adapter over Runtime's existing data-operation executor. */
10
+ export declare function createRuntimeApiCapabilityExecutor(options: RuntimeApiCapabilityExecutorOptions): RuntimeCapabilityExecutor;
11
+ //# sourceMappingURL=runtimeApiCapabilities.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtimeApiCapabilities.d.ts","sourceRoot":"","sources":["../src/runtimeApiCapabilities.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,qBAAqB,EAGtB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,KAAK,EAAE,8BAA8B,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAIjG,OAAO,KAAK,EAGV,yBAAyB,EAC1B,MAAM,mBAAmB,CAAC;AAE3B,MAAM,WAAW,mCAAmC;IAClD,QAAQ,CAAC,IAAI,EAAE,qBAAqB,CAAC;IACrC,QAAQ,CAAC,KAAK,CAAC,EAAE,iBAAiB,CAAC;IACnC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,8BAA8B,CAAC;CAC9D;AAED,qGAAqG;AACrG,wBAAgB,kCAAkC,CAChD,OAAO,EAAE,mCAAmC,GAC3C,yBAAyB,CAE3B"}
@@ -0,0 +1,67 @@
1
+ import { testEndpoint } from '@ankhorage/data-sources';
2
+ import { isRecord } from '@ankhorage/utility/object';
3
+ /*** Creates the canonical API capability adapter over Runtime's existing data-operation executor. */
4
+ export function createRuntimeApiCapabilityExecutor(options) {
5
+ return async (args) => executeRuntimeApiCapabilityAsync(args, options);
6
+ }
7
+ async function executeRuntimeApiCapabilityAsync(args, options) {
8
+ const target = resolveApiCapabilityTarget(args.capability, options.apis);
9
+ if (target === undefined)
10
+ return missingApiCapability(args.capability);
11
+ const values = asBindingValueRecord(args.input);
12
+ if (args.input !== undefined && values === undefined)
13
+ return invalidApiCapabilityInput(args.capability);
14
+ const result = await testEndpoint({
15
+ api: target.api,
16
+ credentialResolver: options.credentialResolver,
17
+ endpointId: target.endpointId,
18
+ fetch: options.fetch,
19
+ operationId: target.operationId,
20
+ values,
21
+ });
22
+ return result.ok
23
+ ? { data: result.data ?? null, diagnostics: result.diagnostics, ok: true }
24
+ : { diagnostics: result.diagnostics, ok: false };
25
+ }
26
+ function resolveApiCapabilityTarget(capability, apis) {
27
+ if (!capability.startsWith('api.'))
28
+ return undefined;
29
+ const target = capability.slice(4);
30
+ const delimiter = target.indexOf('.');
31
+ if (delimiter < 1 || delimiter === target.length - 1)
32
+ return undefined;
33
+ const apiId = target.slice(0, delimiter);
34
+ const operationId = target.slice(delimiter + 1);
35
+ const api = Object.entries(apis).find(([id]) => id === apiId)?.[1];
36
+ if (api === undefined)
37
+ return undefined;
38
+ const endpoint = Object.values(api.endpoints).find((candidate) => Object.hasOwn(candidate.operations, operationId));
39
+ return endpoint === undefined ? undefined : { api, endpointId: endpoint.id, operationId };
40
+ }
41
+ function asBindingValueRecord(value) {
42
+ return isBindingValueRecord(value) ? value : undefined;
43
+ }
44
+ function isBindingValueRecord(value) {
45
+ return isRecord(value);
46
+ }
47
+ function missingApiCapability(capability) {
48
+ return {
49
+ diagnostics: [
50
+ {
51
+ code: 'missing-operation',
52
+ message: `API capability '${capability}' does not resolve to a configured API operation.`,
53
+ severity: 'error',
54
+ },
55
+ ],
56
+ ok: false,
57
+ };
58
+ }
59
+ function invalidApiCapabilityInput(capability) {
60
+ const diagnostic = {
61
+ code: 'invalid-config',
62
+ message: `API capability '${capability}' input must resolve to an object.`,
63
+ severity: 'error',
64
+ };
65
+ return { diagnostics: [diagnostic], ok: false };
66
+ }
67
+ //# sourceMappingURL=runtimeApiCapabilities.js.map