@ankhorage/runtime 0.1.1 → 0.2.1

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 (117) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/README.md +20 -5
  3. package/dist/ManifestContext.d.ts +16 -0
  4. package/dist/ManifestContext.d.ts.map +1 -0
  5. package/dist/ManifestContext.js +26 -0
  6. package/dist/ManifestContext.js.map +1 -0
  7. package/dist/RuntimeRenderer.d.ts +24 -0
  8. package/dist/RuntimeRenderer.d.ts.map +1 -0
  9. package/dist/RuntimeRenderer.js +302 -0
  10. package/dist/RuntimeRenderer.js.map +1 -0
  11. package/dist/RuntimeRendererConfig.d.ts +51 -0
  12. package/dist/RuntimeRendererConfig.d.ts.map +1 -0
  13. package/dist/RuntimeRendererConfig.js +70 -0
  14. package/dist/RuntimeRendererConfig.js.map +1 -0
  15. package/dist/RuntimeScreen.d.ts +11 -0
  16. package/dist/RuntimeScreen.d.ts.map +1 -0
  17. package/dist/RuntimeScreen.js +59 -0
  18. package/dist/RuntimeScreen.js.map +1 -0
  19. package/dist/appExtensionRegistry.d.ts +3 -0
  20. package/dist/appExtensionRegistry.d.ts.map +1 -0
  21. package/dist/appExtensionRegistry.js +2 -0
  22. package/dist/appExtensionRegistry.js.map +1 -0
  23. package/dist/componentRegistry.d.ts +4 -0
  24. package/dist/componentRegistry.d.ts.map +1 -0
  25. package/dist/componentRegistry.js +6 -0
  26. package/dist/componentRegistry.js.map +1 -0
  27. package/dist/index.d.ts +27 -52
  28. package/dist/index.d.ts.map +1 -1
  29. package/dist/index.js +16 -30
  30. package/dist/index.js.map +1 -1
  31. package/dist/readme-usage.js +4 -4
  32. package/dist/readme-usage.js.map +1 -1
  33. package/dist/registry.d.ts +7 -0
  34. package/dist/registry.d.ts.map +1 -0
  35. package/dist/registry.js +49 -0
  36. package/dist/registry.js.map +1 -0
  37. package/dist/rendering.d.ts +17 -0
  38. package/dist/rendering.d.ts.map +1 -0
  39. package/dist/rendering.js +24 -0
  40. package/dist/rendering.js.map +1 -0
  41. package/dist/runtimeActionRegistry.d.ts +55 -0
  42. package/dist/runtimeActionRegistry.d.ts.map +1 -0
  43. package/dist/runtimeActionRegistry.js +323 -0
  44. package/dist/runtimeActionRegistry.js.map +1 -0
  45. package/dist/runtimeApiLoaders.d.ts +35 -0
  46. package/dist/runtimeApiLoaders.d.ts.map +1 -0
  47. package/dist/runtimeApiLoaders.js +218 -0
  48. package/dist/runtimeApiLoaders.js.map +1 -0
  49. package/dist/runtimeBindings.d.ts +52 -0
  50. package/dist/runtimeBindings.d.ts.map +1 -0
  51. package/dist/runtimeBindings.js +299 -0
  52. package/dist/runtimeBindings.js.map +1 -0
  53. package/dist/runtimeDataSourceOperations.d.ts +8 -0
  54. package/dist/runtimeDataSourceOperations.d.ts.map +1 -0
  55. package/dist/runtimeDataSourceOperations.js +58 -0
  56. package/dist/runtimeDataSourceOperations.js.map +1 -0
  57. package/dist/runtimeDbPersist.d.ts +34 -0
  58. package/dist/runtimeDbPersist.d.ts.map +1 -0
  59. package/dist/runtimeDbPersist.js +73 -0
  60. package/dist/runtimeDbPersist.js.map +1 -0
  61. package/dist/runtimeEventExecution.d.ts +11 -0
  62. package/dist/runtimeEventExecution.d.ts.map +1 -0
  63. package/dist/runtimeEventExecution.js +17 -0
  64. package/dist/runtimeEventExecution.js.map +1 -0
  65. package/dist/runtimeManifest.d.ts +53 -0
  66. package/dist/runtimeManifest.d.ts.map +1 -0
  67. package/dist/runtimeManifest.js +31 -0
  68. package/dist/runtimeManifest.js.map +1 -0
  69. package/dist/runtimeNodeProps.d.ts +22 -0
  70. package/dist/runtimeNodeProps.d.ts.map +1 -0
  71. package/dist/runtimeNodeProps.js +130 -0
  72. package/dist/runtimeNodeProps.js.map +1 -0
  73. package/dist/runtimeRepeat.d.ts +27 -0
  74. package/dist/runtimeRepeat.d.ts.map +1 -0
  75. package/dist/runtimeRepeat.js +129 -0
  76. package/dist/runtimeRepeat.js.map +1 -0
  77. package/dist/runtimeRepeatDiagnostics.d.ts +3 -0
  78. package/dist/runtimeRepeatDiagnostics.d.ts.map +1 -0
  79. package/dist/runtimeRepeatDiagnostics.js +14 -0
  80. package/dist/runtimeRepeatDiagnostics.js.map +1 -0
  81. package/dist/runtimeRepeatEmptyState.d.ts +7 -0
  82. package/dist/runtimeRepeatEmptyState.d.ts.map +1 -0
  83. package/dist/runtimeRepeatEmptyState.js +10 -0
  84. package/dist/runtimeRepeatEmptyState.js.map +1 -0
  85. package/dist/runtimeScreenLoaders.d.ts +71 -0
  86. package/dist/runtimeScreenLoaders.d.ts.map +1 -0
  87. package/dist/runtimeScreenLoaders.js +309 -0
  88. package/dist/runtimeScreenLoaders.js.map +1 -0
  89. package/dist/runtimeStateAdapter.d.ts +6 -0
  90. package/dist/runtimeStateAdapter.d.ts.map +1 -0
  91. package/dist/runtimeStateAdapter.js +162 -0
  92. package/dist/runtimeStateAdapter.js.map +1 -0
  93. package/package.json +19 -2
  94. package/paradox/badges/npm.svg +3 -3
  95. package/paradox/components.md +72 -0
  96. package/paradox/diagrams/architecture-overview.mmd +135 -1
  97. package/paradox/diagrams/export-graph.mmd +303 -18
  98. package/paradox/diagrams/module-relationships.mmd +98 -1
  99. package/paradox/diagrams/sequences/create-component-event-from-handler-args.mmd +24 -0
  100. package/paradox/diagrams/sequences/execute-db-persist-action.mmd +16 -0
  101. package/paradox/diagrams/sequences/merge-runtime-renderer-config.mmd +11 -0
  102. package/paradox/diagrams/sequences/resolve-db-persist-input.mmd +13 -0
  103. package/paradox/diagrams/sequences/resolve-runtime-action-payload.mmd +8 -0
  104. package/paradox/diagrams/sequences/resolve-runtime-action-value.mmd +5 -0
  105. package/paradox/diagrams/sequences/runtime-renderer-config-provider.mmd +17 -0
  106. package/paradox/diagrams/sequences/runtime-screen.mmd +17 -0
  107. package/paradox/diagrams/sequences/use-manifest-context.mmd +5 -0
  108. package/paradox/diagrams/sequences/use-manifest.mmd +5 -0
  109. package/paradox/diagrams/sequences/use-optional-manifest-context.mmd +5 -0
  110. package/paradox/diagrams/sequences/use-runtime-renderer-config.mmd +5 -0
  111. package/paradox/diagrams/sequences/use-runtime-screen-operation-loaders.mmd +5 -0
  112. package/paradox/diagrams/sequences/validate-runtime-binding-operation-ref.mmd +8 -0
  113. package/paradox/diagrams/sequences/wrap-runtime-event-props.mmd +5 -0
  114. package/paradox/exports.json +3385 -330
  115. package/paradox/exports.md +1051 -38
  116. package/paradox/index.html +8291 -450
  117. package/paradox/paradox.json +10013 -511
@@ -0,0 +1,323 @@
1
+ import { createRuntimeBindingOperationKey, resolveBindingInputMap, } from './runtimeBindings';
2
+ export function createRuntimeActionRegistry(options = {}) {
3
+ const actionHandlers = { ...(options.actionHandlers ?? {}) };
4
+ return {
5
+ async dispatchComponentEvent(args) {
6
+ await dispatchRuntimeComponentEvent({
7
+ ...args,
8
+ actionHandlers,
9
+ dataBindings: args.dataBindings ?? options.dataBindings,
10
+ dataSources: args.dataSources ?? options.dataSources,
11
+ executeAction: args.executeAction ?? options.executeAction,
12
+ executeOperation: args.executeOperation ?? options.executeOperation,
13
+ operationResults: args.operationResults ?? options.operationResults,
14
+ writeOperationResult: args.writeOperationResult ?? options.writeOperationResult,
15
+ });
16
+ },
17
+ registerActionHandler(type, handler) {
18
+ actionHandlers[type] = handler;
19
+ return () => {
20
+ delete actionHandlers[type];
21
+ };
22
+ },
23
+ };
24
+ }
25
+ export async function dispatchRuntimeComponentEvent(args) {
26
+ const { node, event, eventName = inferLocalEventName(event.type), actionHandlers } = args;
27
+ const eventBindings = args.dataBindings?.[node.id]?.events?.[eventName] ??
28
+ args.dataBindings?.[node.id]?.events?.[event.type] ??
29
+ [];
30
+ const diagnostics = [];
31
+ const dispatchOperationResults = {
32
+ ...(args.operationResults ?? {}),
33
+ };
34
+ const resolutionArgs = {
35
+ ...args,
36
+ operationResults: dispatchOperationResults,
37
+ };
38
+ for (const binding of eventBindings) {
39
+ if (!matchesBindingCondition(binding.when, resolutionArgs))
40
+ continue;
41
+ if (binding.target.kind === 'action') {
42
+ const resolvedPayload = await resolveObjectEventBindingInput(binding.input, resolutionArgs, diagnostics);
43
+ const action = resolvedPayload === undefined
44
+ ? { type: binding.target.type }
45
+ : { type: binding.target.type, payload: resolvedPayload };
46
+ if (resolutionArgs.executeAction) {
47
+ await resolutionArgs.executeAction({
48
+ action,
49
+ event,
50
+ node,
51
+ resolvedPayload,
52
+ });
53
+ continue;
54
+ }
55
+ const handler = actionHandlers?.[binding.target.type];
56
+ if (handler) {
57
+ await handler({
58
+ action,
59
+ event,
60
+ node,
61
+ resolvedPayload,
62
+ });
63
+ continue;
64
+ }
65
+ diagnostics.push({
66
+ code: 'missing-action-handler',
67
+ message: `Action '${binding.target.type}' could not be executed because no runtime executor or handler is registered.`,
68
+ severity: 'error',
69
+ });
70
+ continue;
71
+ }
72
+ const operationSucceeded = await dispatchRuntimeOperationEventBinding({
73
+ args: resolutionArgs,
74
+ binding,
75
+ diagnostics,
76
+ operationResults: dispatchOperationResults,
77
+ target: binding.target,
78
+ });
79
+ if (!operationSucceeded) {
80
+ break;
81
+ }
82
+ }
83
+ return diagnostics;
84
+ }
85
+ export function wrapRuntimeEventProps(args) {
86
+ const { node, props, disableActions, dispatchComponentEvent } = args;
87
+ const wrappedProps = { ...props };
88
+ const nodeEventBindings = args.dataBindings?.[node.id]?.events;
89
+ if (disableActions || !nodeEventBindings) {
90
+ return wrappedProps;
91
+ }
92
+ for (const eventName of Object.keys(nodeEventBindings)) {
93
+ const propName = eventNameToCallbackProp(eventName);
94
+ const existingHandler = wrappedProps[propName];
95
+ wrappedProps[propName] = (...handlerArgs) => {
96
+ let existingResult;
97
+ if (isRuntimeEventHandler(existingHandler)) {
98
+ existingResult = existingHandler(...handlerArgs);
99
+ }
100
+ void dispatchComponentEvent({
101
+ context: args.context,
102
+ dataBindings: args.dataBindings,
103
+ event: createComponentEventFromHandlerArgs({ eventName, handlerArgs, node }),
104
+ eventName,
105
+ node,
106
+ operationResults: args.operationResults,
107
+ state: args.state,
108
+ });
109
+ return existingResult;
110
+ };
111
+ }
112
+ return wrappedProps;
113
+ }
114
+ export function createComponentEventFromHandlerArgs(args) {
115
+ const { node, eventName, handlerArgs } = args;
116
+ return {
117
+ payload: createPayloadForEvent(eventName, handlerArgs),
118
+ sourceNodeId: node.id,
119
+ type: localEventNameToEventType(eventName),
120
+ };
121
+ }
122
+ export function resolveRuntimeActionPayload(payload, args) {
123
+ if (payload === undefined) {
124
+ return undefined;
125
+ }
126
+ return resolveRuntimeActionValue(payload, args);
127
+ }
128
+ export function resolveRuntimeActionValue(value, args) {
129
+ if (!isRecord(value))
130
+ return undefined;
131
+ return Object.fromEntries(Object.entries(value).map(([key, entry]) => [key, resolveRuntimeActionValueEntry(entry, args)]));
132
+ }
133
+ async function dispatchRuntimeOperationEventBinding(args) {
134
+ const { binding, diagnostics, target } = args;
135
+ if (args.args.executeOperation === undefined) {
136
+ diagnostics.push({
137
+ code: 'missing-adapter',
138
+ dataSourceId: target.operation.dataSourceId,
139
+ endpointId: target.operation.endpointId,
140
+ operationId: target.operation.operationId,
141
+ message: 'Event operation binding requires an injected operation executor.',
142
+ severity: 'error',
143
+ });
144
+ return false;
145
+ }
146
+ const dataSource = args.args.dataSources?.[target.operation.dataSourceId];
147
+ if (dataSource === undefined) {
148
+ diagnostics.push({
149
+ code: 'missing-data-source',
150
+ dataSourceId: target.operation.dataSourceId,
151
+ endpointId: target.operation.endpointId,
152
+ operationId: target.operation.operationId,
153
+ message: `Data source '${target.operation.dataSourceId}' could not be found.`,
154
+ severity: 'error',
155
+ });
156
+ return false;
157
+ }
158
+ const endpoint = resolveEventOperationEndpoint(target, dataSource);
159
+ const result = await args.args.executeOperation({
160
+ dataSource,
161
+ endpoint,
162
+ input: await resolveEventBindingInput(binding.input, args.args, diagnostics),
163
+ node: args.args.node,
164
+ operation: target.operation,
165
+ });
166
+ diagnostics.push(...(result.diagnostics ?? []));
167
+ if (result.ok) {
168
+ const operationKey = createRuntimeBindingOperationKey(target.operation);
169
+ args.operationResults[operationKey] = result.data;
170
+ args.args.writeOperationResult?.(operationKey, result.data);
171
+ return true;
172
+ }
173
+ return false;
174
+ }
175
+ function resolveRuntimeActionValueEntry(value, args) {
176
+ if (Array.isArray(value))
177
+ return value.map((item) => resolveRuntimeActionValueEntry(item, args));
178
+ if (!isRecord(value))
179
+ return value;
180
+ if (!('valueFrom' in value)) {
181
+ return Object.fromEntries(Object.entries(value).map(([key, entry]) => [
182
+ key,
183
+ resolveRuntimeActionValueEntry(entry, args),
184
+ ]));
185
+ }
186
+ return undefined;
187
+ }
188
+ async function resolveObjectEventBindingInput(input, args, diagnostics) {
189
+ const value = await resolveEventBindingInput(input, args, diagnostics);
190
+ return isRecord(value) ? value : undefined;
191
+ }
192
+ async function resolveEventBindingInput(input, args, diagnostics) {
193
+ return resolveBindingInputMap(input, {
194
+ context: args.context,
195
+ dataBindings: args.dataBindings,
196
+ dataSources: args.dataSources,
197
+ event: args.event,
198
+ executeOperation: args.executeOperation,
199
+ operationResults: args.operationResults,
200
+ }, diagnostics);
201
+ }
202
+ function matchesBindingCondition(condition, args) {
203
+ if (condition === undefined)
204
+ return true;
205
+ const value = readBindingConditionSource(condition, args);
206
+ switch (condition.operator) {
207
+ case 'eq':
208
+ return value === condition.value;
209
+ case 'exists':
210
+ return value !== undefined;
211
+ case 'neq':
212
+ return value !== condition.value;
213
+ case 'notExists':
214
+ return value === undefined;
215
+ }
216
+ }
217
+ function readBindingConditionSource(condition, args) {
218
+ switch (condition.source.kind) {
219
+ case 'context':
220
+ return readPath(args.context, condition.source.path);
221
+ case 'event':
222
+ return readPath(args.event, condition.source.path);
223
+ case 'literal':
224
+ return condition.source.value;
225
+ case 'operation': {
226
+ const operationResult = args.operationResults?.[createRuntimeBindingOperationKey(condition.source.operation)];
227
+ return condition.source.path === undefined
228
+ ? operationResult
229
+ : readPath(operationResult, condition.source.path);
230
+ }
231
+ case 'state':
232
+ return readPath(args.state, condition.source.path);
233
+ }
234
+ }
235
+ function resolveEventOperationEndpoint(target, dataSource) {
236
+ if (target.operation.endpointId !== undefined) {
237
+ return dataSource.endpoints[target.operation.endpointId];
238
+ }
239
+ return Object.values(dataSource.endpoints).find((endpoint) => endpoint.operations[target.operation.operationId] !== undefined);
240
+ }
241
+ function createPayloadForEvent(eventName, handlerArgs) {
242
+ if (eventName === 'barcodeScanned') {
243
+ return createBarcodeScannedPayload(handlerArgs[0]);
244
+ }
245
+ if (eventName === 'submit') {
246
+ return { values: asRecord(handlerArgs[0]) ?? {} };
247
+ }
248
+ if (eventName === 'itemPress') {
249
+ const item = asRecord(handlerArgs[0]) ?? {};
250
+ const itemId = readItemId(handlerArgs[0]);
251
+ return itemId === undefined ? { item } : { itemId, item };
252
+ }
253
+ if (eventName === 'changeText' || eventName === 'valueChange') {
254
+ return { value: handlerArgs[0] };
255
+ }
256
+ if (eventName === 'checkedChange') {
257
+ return { checked: handlerArgs[0] };
258
+ }
259
+ if (eventName === 'manualEntry') {
260
+ return handlerArgs[0] === undefined ? {} : { value: handlerArgs[0] };
261
+ }
262
+ if (eventName === 'requestPermission') {
263
+ return {};
264
+ }
265
+ return {};
266
+ }
267
+ function localEventNameToEventType(eventName) {
268
+ if (eventName === 'itemPress')
269
+ return 'collection.itemPress';
270
+ if (eventName === 'press')
271
+ return 'button.press';
272
+ if (eventName === 'submit')
273
+ return 'form.submit';
274
+ return eventName;
275
+ }
276
+ function inferLocalEventName(eventType) {
277
+ const parts = eventType.split('.');
278
+ return parts.at(-1) ?? eventType;
279
+ }
280
+ function eventNameToCallbackProp(eventName) {
281
+ return `on${eventName.charAt(0).toUpperCase()}${eventName.slice(1)}`;
282
+ }
283
+ function isRuntimeEventHandler(value) {
284
+ return typeof value === 'function';
285
+ }
286
+ function readPath(source, path) {
287
+ if (path.length === 0)
288
+ return source;
289
+ return path.split('.').reduce((currentValue, part) => {
290
+ if (!isRecord(currentValue))
291
+ return undefined;
292
+ return currentValue[part];
293
+ }, source);
294
+ }
295
+ function createBarcodeScannedPayload(value) {
296
+ if (typeof value === 'string') {
297
+ return { value };
298
+ }
299
+ if (!isRecord(value)) {
300
+ return {};
301
+ }
302
+ const payload = {};
303
+ if (typeof value.value === 'string')
304
+ payload.value = value.value;
305
+ if (typeof value.type === 'string')
306
+ payload.type = value.type;
307
+ return payload;
308
+ }
309
+ function readItemId(value) {
310
+ if (typeof value === 'string' || typeof value === 'number')
311
+ return value;
312
+ if (!isRecord(value))
313
+ return undefined;
314
+ const id = value.id ?? value.itemId;
315
+ return typeof id === 'string' || typeof id === 'number' ? id : undefined;
316
+ }
317
+ function asRecord(value) {
318
+ return isRecord(value) ? value : undefined;
319
+ }
320
+ function isRecord(value) {
321
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
322
+ }
323
+ //# sourceMappingURL=runtimeActionRegistry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtimeActionRegistry.js","sourceRoot":"","sources":["../src/runtimeActionRegistry.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n BindingCondition,\n BindingInputMap,\n BindingValue,\n ComponentDataBindingRegistry,\n ComponentEventDto,\n DataEndpointConfig,\n DataSourceConfig,\n DataSourceDiagnostic,\n DataSourceRegistry,\n EventBinding,\n EventBindingTarget,\n UiNode,\n} from '@ankhorage/contracts';\n\nimport {\n createRuntimeBindingOperationKey,\n resolveBindingInputMap,\n type RuntimeBindingOperationExecutor,\n type RuntimeBindingOperationResultCache,\n type RuntimeBindingOperationResultWriter,\n} from './runtimeBindings';\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: string, 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 dataSources?: DataSourceRegistry;\n readonly dataBindings?: ComponentDataBindingRegistry;\n readonly executeOperation?: RuntimeBindingOperationExecutor;\n readonly writeOperationResult?: RuntimeBindingOperationResultWriter;\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 dataSources?: DataSourceRegistry;\n dataBindings?: ComponentDataBindingRegistry;\n executeAction?: RuntimeActionHandler;\n executeOperation?: RuntimeBindingOperationExecutor;\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 dataBindings: args.dataBindings ?? options.dataBindings,\n dataSources: args.dataSources ?? options.dataSources,\n executeAction: args.executeAction ?? options.executeAction,\n executeOperation: args.executeOperation ?? options.executeOperation,\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 resolvedPayload = await resolveObjectEventBindingInput(\n binding.input,\n resolutionArgs,\n diagnostics,\n );\n const action =\n resolvedPayload === undefined\n ? { type: binding.target.type }\n : { type: binding.target.type, 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?.[binding.target.type];\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 '${binding.target.type}' 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\n if (args.args.executeOperation === undefined) {\n diagnostics.push({\n code: 'missing-adapter',\n dataSourceId: target.operation.dataSourceId,\n endpointId: target.operation.endpointId,\n operationId: target.operation.operationId,\n message: 'Event operation binding requires an injected operation executor.',\n severity: 'error',\n });\n return false;\n }\n\n const dataSource = args.args.dataSources?.[target.operation.dataSourceId];\n if (dataSource === undefined) {\n diagnostics.push({\n code: 'missing-data-source',\n dataSourceId: target.operation.dataSourceId,\n endpointId: target.operation.endpointId,\n operationId: target.operation.operationId,\n message: `Data source '${target.operation.dataSourceId}' could not be found.`,\n severity: 'error',\n });\n return false;\n }\n\n const endpoint = resolveEventOperationEndpoint(target, dataSource);\n const result = await args.args.executeOperation({\n dataSource,\n endpoint,\n input: await resolveEventBindingInput(binding.input, args.args, diagnostics),\n node: args.args.node,\n operation: target.operation,\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 return true;\n }\n\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 context: args.context,\n dataBindings: args.dataBindings,\n dataSources: args.dataSources,\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 resolveEventOperationEndpoint(\n target: RuntimeOperationEventTarget,\n dataSource: DataSourceConfig,\n): DataEndpointConfig | undefined {\n if (target.operation.endpointId !== undefined) {\n return dataSource.endpoints[target.operation.endpointId];\n }\n\n return Object.values(dataSource.endpoints).find(\n (endpoint) => endpoint.operations[target.operation.operationId] !== undefined,\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') {\n return {};\n }\n\n return {};\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\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"]}
@@ -0,0 +1,35 @@
1
+ import type { ApiScreenDataLoaderDefinition, AppDataManifest, StateAdapter, StateValue } from '@ankhorage/contracts';
2
+ export type RuntimeApiLoaderMode = 'byId' | 'list' | 'one' | 'random';
3
+ export type RuntimeApiLoaderDefinition = ApiScreenDataLoaderDefinition;
4
+ export interface RuntimeApiLoaderDiagnostic {
5
+ readonly code: 'invalid-record' | 'missing-api' | 'missing-target-path' | 'state-set-failed' | 'unsupported-loader';
6
+ readonly message: string;
7
+ readonly apiId?: string;
8
+ readonly targetPath?: string;
9
+ }
10
+ export interface RuntimeApiLoaderExecutionResult {
11
+ readonly diagnostics: readonly RuntimeApiLoaderDiagnostic[];
12
+ }
13
+ export interface RuntimeApiLoaderMaterializationResult {
14
+ readonly state: Readonly<Record<string, StateValue>>;
15
+ readonly diagnostics: readonly RuntimeApiLoaderDiagnostic[];
16
+ }
17
+ export declare function materializeRuntimeApiLoaderState(args: {
18
+ readonly data?: AppDataManifest;
19
+ readonly loaders: readonly RuntimeApiLoaderDefinition[];
20
+ }): RuntimeApiLoaderMaterializationResult;
21
+ export declare function executeRuntimeApiLoaders(args: {
22
+ readonly data?: AppDataManifest;
23
+ readonly loaders: readonly RuntimeApiLoaderDefinition[];
24
+ readonly stateAdapter: StateAdapter;
25
+ }): RuntimeApiLoaderExecutionResult;
26
+ export declare function useRuntimeApiStateLoaders(args: {
27
+ readonly data?: AppDataManifest;
28
+ readonly loaders?: readonly RuntimeApiLoaderDefinition[];
29
+ readonly stateAdapter?: StateAdapter;
30
+ }): {
31
+ readonly diagnostics: readonly RuntimeApiLoaderDiagnostic[];
32
+ readonly stateAdapter: StateAdapter;
33
+ readonly stateVersion: number;
34
+ };
35
+ //# sourceMappingURL=runtimeApiLoaders.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtimeApiLoaders.d.ts","sourceRoot":"","sources":["../src/runtimeApiLoaders.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,6BAA6B,EAG7B,eAAe,EAEf,YAAY,EAEZ,UAAU,EACX,MAAM,sBAAsB,CAAC;AAK9B,MAAM,MAAM,oBAAoB,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,CAAC;AAEtE,MAAM,MAAM,0BAA0B,GAAG,6BAA6B,CAAC;AAEvE,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,IAAI,EACT,gBAAgB,GAChB,aAAa,GACb,qBAAqB,GACrB,kBAAkB,GAClB,oBAAoB,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,WAAW,+BAA+B;IAC9C,QAAQ,CAAC,WAAW,EAAE,SAAS,0BAA0B,EAAE,CAAC;CAC7D;AAED,MAAM,WAAW,qCAAqC;IACpD,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC;IACrD,QAAQ,CAAC,WAAW,EAAE,SAAS,0BAA0B,EAAE,CAAC;CAC7D;AAED,wBAAgB,gCAAgC,CAAC,IAAI,EAAE;IACrD,QAAQ,CAAC,IAAI,CAAC,EAAE,eAAe,CAAC;IAChC,QAAQ,CAAC,OAAO,EAAE,SAAS,0BAA0B,EAAE,CAAC;CACzD,GAAG,qCAAqC,CAuDxC;AAED,wBAAgB,wBAAwB,CAAC,IAAI,EAAE;IAC7C,QAAQ,CAAC,IAAI,CAAC,EAAE,eAAe,CAAC;IAChC,QAAQ,CAAC,OAAO,EAAE,SAAS,0BAA0B,EAAE,CAAC;IACxD,QAAQ,CAAC,YAAY,EAAE,YAAY,CAAC;CACrC,GAAG,+BAA+B,CAmBlC;AAED,wBAAgB,yBAAyB,CAAC,IAAI,EAAE;IAC9C,QAAQ,CAAC,IAAI,CAAC,EAAE,eAAe,CAAC;IAChC,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,0BAA0B,EAAE,CAAC;IACzD,QAAQ,CAAC,YAAY,CAAC,EAAE,YAAY,CAAC;CACtC,GAAG;IACF,QAAQ,CAAC,WAAW,EAAE,SAAS,0BAA0B,EAAE,CAAC;IAC5D,QAAQ,CAAC,YAAY,EAAE,YAAY,CAAC;IACpC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;CAC/B,CAsBA"}
@@ -0,0 +1,218 @@
1
+ import React from 'react';
2
+ import { createRuntimeMemoryStateAdapter } from './runtimeStateAdapter';
3
+ export function materializeRuntimeApiLoaderState(args) {
4
+ const state = {};
5
+ const diagnostics = [];
6
+ for (const loader of args.loaders) {
7
+ const targetPath = loader.targetPath.trim();
8
+ if (targetPath.length === 0) {
9
+ diagnostics.push({
10
+ code: 'missing-target-path',
11
+ apiId: loader.apiId,
12
+ message: `API loader for ${loader.apiId} must define a target path.`,
13
+ });
14
+ continue;
15
+ }
16
+ const api = args.data?.apis?.[loader.apiId];
17
+ const resource = getGeneratedApiCollectionResource(api);
18
+ if (api?.kind !== 'generated' || resource === null) {
19
+ diagnostics.push({
20
+ code: 'missing-api',
21
+ apiId: loader.apiId,
22
+ targetPath,
23
+ message: `Generated API ${loader.apiId} could not be found.`,
24
+ });
25
+ continue;
26
+ }
27
+ const selectedValue = selectApiLoaderValue({ api, resource, loader, diagnostics, targetPath });
28
+ if (selectedValue === undefined) {
29
+ continue;
30
+ }
31
+ const stateValue = toStateValue(selectedValue);
32
+ if (stateValue === undefined) {
33
+ diagnostics.push({
34
+ code: 'invalid-record',
35
+ apiId: loader.apiId,
36
+ targetPath,
37
+ message: `Generated API ${loader.apiId} produced a value that cannot be represented as runtime state.`,
38
+ });
39
+ continue;
40
+ }
41
+ const setResult = writeObjectPath(state, targetPath, stateValue);
42
+ if (!setResult.ok) {
43
+ diagnostics.push({
44
+ code: 'state-set-failed',
45
+ apiId: loader.apiId,
46
+ targetPath,
47
+ message: setResult.error.message,
48
+ });
49
+ }
50
+ }
51
+ return { state, diagnostics };
52
+ }
53
+ export function executeRuntimeApiLoaders(args) {
54
+ const materialized = materializeRuntimeApiLoaderState({
55
+ data: args.data,
56
+ loaders: args.loaders,
57
+ });
58
+ const diagnostics = [...materialized.diagnostics];
59
+ for (const [targetPath, value] of flattenStateEntries(materialized.state)) {
60
+ const result = args.stateAdapter.set(targetPath, value);
61
+ if (!result.ok) {
62
+ diagnostics.push({
63
+ code: 'state-set-failed',
64
+ targetPath,
65
+ message: result.error.message,
66
+ });
67
+ }
68
+ }
69
+ return { diagnostics };
70
+ }
71
+ export function useRuntimeApiStateLoaders(args) {
72
+ const fallbackStateAdapter = React.useMemo(() => createRuntimeMemoryStateAdapter(), []);
73
+ const stateAdapter = args.stateAdapter ?? fallbackStateAdapter;
74
+ const loaders = args.loaders ?? [];
75
+ const [stateVersion, setStateVersion] = React.useState(0);
76
+ const [diagnostics, setDiagnostics] = React.useState([]);
77
+ React.useEffect(() => {
78
+ const result = executeRuntimeApiLoaders({
79
+ data: args.data,
80
+ loaders,
81
+ stateAdapter,
82
+ });
83
+ setDiagnostics(result.diagnostics);
84
+ setStateVersion((current) => current + 1);
85
+ }, [args.data, loaders, stateAdapter]);
86
+ return {
87
+ diagnostics,
88
+ stateAdapter,
89
+ stateVersion,
90
+ };
91
+ }
92
+ function getGeneratedApiCollectionResource(api) {
93
+ if (api?.kind !== 'generated' || api.resource?.kind !== 'collection') {
94
+ return null;
95
+ }
96
+ return api.resource;
97
+ }
98
+ function selectApiLoaderValue(args) {
99
+ const seed = args.resource.seed ?? [];
100
+ const primaryKey = args.resource.collection.primaryKey ?? 'id';
101
+ switch (args.loader.mode) {
102
+ case 'list':
103
+ return seed;
104
+ case 'one':
105
+ return seed[0];
106
+ case 'random': {
107
+ const index = deterministicIndex(args.api.id, seed.length);
108
+ return index === undefined ? undefined : seed[index];
109
+ }
110
+ case 'byId': {
111
+ const loaderId = normalizePrimitiveId(args.loader.id);
112
+ if (loaderId === undefined)
113
+ return undefined;
114
+ return seed.find((record) => {
115
+ return normalizePrimitiveId(record[primaryKey]) === loaderId;
116
+ });
117
+ }
118
+ default:
119
+ args.diagnostics.push({
120
+ code: 'unsupported-loader',
121
+ apiId: args.loader.apiId,
122
+ targetPath: args.targetPath,
123
+ message: `API loader mode ${String(args.loader.mode)} is not supported.`,
124
+ });
125
+ return undefined;
126
+ }
127
+ }
128
+ function normalizePrimitiveId(value) {
129
+ if (typeof value === 'string')
130
+ return value;
131
+ if (typeof value === 'number')
132
+ return Number.isFinite(value) ? value.toString() : undefined;
133
+ if (typeof value === 'boolean')
134
+ return value ? 'true' : 'false';
135
+ return undefined;
136
+ }
137
+ function deterministicIndex(apiId, length) {
138
+ if (length === 0)
139
+ return undefined;
140
+ let hash = 0;
141
+ for (const char of apiId) {
142
+ hash = (hash * 31 + char.charCodeAt(0)) % length;
143
+ }
144
+ return hash;
145
+ }
146
+ function writeObjectPath(target, path, value) {
147
+ const parts = path
148
+ .split('.')
149
+ .map((part) => part.trim())
150
+ .filter(Boolean);
151
+ const [head, ...tail] = parts;
152
+ if (head === undefined) {
153
+ return {
154
+ ok: false,
155
+ error: {
156
+ code: 'invalid_path',
157
+ message: 'State target path must contain at least one segment.',
158
+ },
159
+ };
160
+ }
161
+ if (tail.length === 0) {
162
+ target[head] = value;
163
+ return { ok: true };
164
+ }
165
+ const existing = target[head];
166
+ const child = existing === undefined ? {} : existing;
167
+ if (!isMutableStateRecord(child)) {
168
+ return {
169
+ ok: false,
170
+ error: {
171
+ code: 'path_conflict',
172
+ message: `Cannot set nested state below non-object path segment "${head}".`,
173
+ },
174
+ };
175
+ }
176
+ target[head] = child;
177
+ return writeObjectPath(child, tail.join('.'), value);
178
+ }
179
+ function flattenStateEntries(source, prefix = '') {
180
+ return Object.entries(source).flatMap(([key, value]) => {
181
+ const path = prefix.length > 0 ? `${prefix}.${key}` : key;
182
+ return [[path, value]];
183
+ });
184
+ }
185
+ function toStateValue(value) {
186
+ if (value === null)
187
+ return null;
188
+ if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {
189
+ return value;
190
+ }
191
+ if (Array.isArray(value)) {
192
+ const items = [];
193
+ for (const item of value) {
194
+ const stateItem = toStateValue(item);
195
+ if (stateItem === undefined)
196
+ return undefined;
197
+ items.push(stateItem);
198
+ }
199
+ return items;
200
+ }
201
+ if (!isUnknownRecord(value))
202
+ return undefined;
203
+ const record = {};
204
+ for (const [key, entry] of Object.entries(value)) {
205
+ const stateEntry = toStateValue(entry);
206
+ if (stateEntry === undefined)
207
+ return undefined;
208
+ record[key] = stateEntry;
209
+ }
210
+ return record;
211
+ }
212
+ function isUnknownRecord(value) {
213
+ return typeof value === 'object' && value != null && !Array.isArray(value);
214
+ }
215
+ function isMutableStateRecord(value) {
216
+ return typeof value === 'object' && value != null && !Array.isArray(value);
217
+ }
218
+ //# sourceMappingURL=runtimeApiLoaders.js.map