@pwfabric/runtime 0.0.0-stage → 1.0.0-rc.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.
- package/LICENSE +90 -0
- package/README.md +43 -2
- package/dist/a11y/announcer.d.ts +65 -0
- package/dist/a11y/announcer.js +140 -0
- package/dist/a11y/announcer.js.map +1 -0
- package/dist/a11y/contrast.d.ts +54 -0
- package/dist/a11y/contrast.js +93 -0
- package/dist/a11y/contrast.js.map +1 -0
- package/dist/a11y/focus.d.ts +123 -0
- package/dist/a11y/focus.js +282 -0
- package/dist/a11y/focus.js.map +1 -0
- package/dist/a11y/index.d.ts +21 -0
- package/dist/a11y/index.js +18 -0
- package/dist/a11y/index.js.map +1 -0
- package/dist/a11y/keyboard.d.ts +144 -0
- package/dist/a11y/keyboard.js +317 -0
- package/dist/a11y/keyboard.js.map +1 -0
- package/dist/adapters/default-image.d.ts +25 -0
- package/dist/adapters/default-image.js +37 -0
- package/dist/adapters/default-image.js.map +1 -0
- package/dist/adapters/index.d.ts +27 -0
- package/dist/adapters/index.js +28 -0
- package/dist/adapters/index.js.map +1 -0
- package/dist/adapters/next-image.d.ts +38 -0
- package/dist/adapters/next-image.js +124 -0
- package/dist/adapters/next-image.js.map +1 -0
- package/dist/adapters/types.d.ts +61 -0
- package/dist/adapters/types.js +11 -0
- package/dist/adapters/types.js.map +1 -0
- package/dist/analytics/index.d.ts +14 -0
- package/dist/analytics/index.js +15 -0
- package/dist/analytics/index.js.map +1 -0
- package/dist/analytics/tracker.d.ts +65 -0
- package/dist/analytics/tracker.js +251 -0
- package/dist/analytics/tracker.js.map +1 -0
- package/dist/analytics/types.d.ts +130 -0
- package/dist/analytics/types.js +11 -0
- package/dist/analytics/types.js.map +1 -0
- package/dist/auth/index.d.ts +15 -0
- package/dist/auth/index.js +14 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/auth/provider.d.ts +132 -0
- package/dist/auth/provider.js +473 -0
- package/dist/auth/provider.js.map +1 -0
- package/dist/auth/types.d.ts +117 -0
- package/dist/auth/types.js +9 -0
- package/dist/auth/types.js.map +1 -0
- package/dist/binding/collection.d.ts +190 -0
- package/dist/binding/collection.js +358 -0
- package/dist/binding/collection.js.map +1 -0
- package/dist/binding/datasource.d.ts +319 -0
- package/dist/binding/datasource.js +556 -0
- package/dist/binding/datasource.js.map +1 -0
- package/dist/binding/engine.d.ts +65 -0
- package/dist/binding/engine.js +268 -0
- package/dist/binding/engine.js.map +1 -0
- package/dist/binding/expression.d.ts +150 -0
- package/dist/binding/expression.js +787 -0
- package/dist/binding/expression.js.map +1 -0
- package/dist/binding/index.d.ts +19 -0
- package/dist/binding/index.js +14 -0
- package/dist/binding/index.js.map +1 -0
- package/dist/binding/two-way.d.ts +149 -0
- package/dist/binding/two-way.js +462 -0
- package/dist/binding/two-way.js.map +1 -0
- package/dist/binding/types.d.ts +119 -0
- package/dist/binding/types.js +9 -0
- package/dist/binding/types.js.map +1 -0
- package/dist/blocks/component-types.d.ts +81 -0
- package/dist/blocks/component-types.js +11 -0
- package/dist/blocks/component-types.js.map +1 -0
- package/dist/blocks/composition-rules.d.ts +168 -0
- package/dist/blocks/composition-rules.js +391 -0
- package/dist/blocks/composition-rules.js.map +1 -0
- package/dist/blocks/hooks.d.ts +31 -0
- package/dist/blocks/hooks.js +42 -0
- package/dist/blocks/hooks.js.map +1 -0
- package/dist/blocks/index.d.ts +14 -0
- package/dist/blocks/index.js +23 -0
- package/dist/blocks/index.js.map +1 -0
- package/dist/blocks/registry.d.ts +84 -0
- package/dist/blocks/registry.js +136 -0
- package/dist/blocks/registry.js.map +1 -0
- package/dist/blocks/rule-engine.d.ts +131 -0
- package/dist/blocks/rule-engine.js +321 -0
- package/dist/blocks/rule-engine.js.map +1 -0
- package/dist/blocks/surface-event-context.d.ts +13 -0
- package/dist/blocks/surface-event-context.js +14 -0
- package/dist/blocks/surface-event-context.js.map +1 -0
- package/dist/blocks/surface-id-context.d.ts +13 -0
- package/dist/blocks/surface-id-context.js +15 -0
- package/dist/blocks/surface-id-context.js.map +1 -0
- package/dist/bus.d.ts +41 -0
- package/dist/bus.js +158 -0
- package/dist/bus.js.map +1 -0
- package/dist/cache/index.d.ts +9 -0
- package/dist/cache/index.js +10 -0
- package/dist/cache/index.js.map +1 -0
- package/dist/cache/memory.d.ts +32 -0
- package/dist/cache/memory.js +138 -0
- package/dist/cache/memory.js.map +1 -0
- package/dist/cache/types.d.ts +62 -0
- package/dist/cache/types.js +9 -0
- package/dist/cache/types.js.map +1 -0
- package/dist/capability/index.d.ts +72 -0
- package/dist/capability/index.js +87 -0
- package/dist/capability/index.js.map +1 -0
- package/dist/capability/kernel-capabilities.d.ts +31 -0
- package/dist/capability/kernel-capabilities.js +36 -0
- package/dist/capability/kernel-capabilities.js.map +1 -0
- package/dist/capability/platform-capabilities.d.ts +71 -0
- package/dist/capability/platform-capabilities.js +267 -0
- package/dist/capability/platform-capabilities.js.map +1 -0
- package/dist/capability/type-mapping.d.ts +70 -0
- package/dist/capability/type-mapping.js +107 -0
- package/dist/capability/type-mapping.js.map +1 -0
- package/dist/capability/validation.d.ts +46 -0
- package/dist/capability/validation.js +54 -0
- package/dist/capability/validation.js.map +1 -0
- package/dist/connectors/declared-connector.d.ts +48 -0
- package/dist/connectors/declared-connector.js +333 -0
- package/dist/connectors/declared-connector.js.map +1 -0
- package/dist/connectors/engine-registry.d.ts +50 -0
- package/dist/connectors/engine-registry.js +135 -0
- package/dist/connectors/engine-registry.js.map +1 -0
- package/dist/connectors/index.d.ts +14 -0
- package/dist/connectors/index.js +14 -0
- package/dist/connectors/index.js.map +1 -0
- package/dist/connectors/module-loader.d.ts +70 -0
- package/dist/connectors/module-loader.js +143 -0
- package/dist/connectors/module-loader.js.map +1 -0
- package/dist/connectors/types.d.ts +174 -0
- package/dist/connectors/types.js +23 -0
- package/dist/connectors/types.js.map +1 -0
- package/dist/context.d.ts +27 -0
- package/dist/context.js +38 -0
- package/dist/context.js.map +1 -0
- package/dist/data/DataCapabilityProvider.d.ts +39 -0
- package/dist/data/DataCapabilityProvider.js +58 -0
- package/dist/data/DataCapabilityProvider.js.map +1 -0
- package/dist/data/index.d.ts +17 -0
- package/dist/data/index.js +18 -0
- package/dist/data/index.js.map +1 -0
- package/dist/data/manager.d.ts +40 -0
- package/dist/data/manager.js +442 -0
- package/dist/data/manager.js.map +1 -0
- package/dist/data/types.d.ts +218 -0
- package/dist/data/types.js +2 -0
- package/dist/data/types.js.map +1 -0
- package/dist/entity/aggregate.d.ts +8 -0
- package/dist/entity/aggregate.js +24 -0
- package/dist/entity/aggregate.js.map +1 -0
- package/dist/entity/apply-query.d.ts +58 -0
- package/dist/entity/apply-query.js +264 -0
- package/dist/entity/apply-query.js.map +1 -0
- package/dist/entity/behavior.d.ts +94 -0
- package/dist/entity/behavior.js +78 -0
- package/dist/entity/behavior.js.map +1 -0
- package/dist/entity/connector.d.ts +141 -0
- package/dist/entity/connector.js +89 -0
- package/dist/entity/connector.js.map +1 -0
- package/dist/entity/connectors/index.d.ts +12 -0
- package/dist/entity/connectors/index.js +11 -0
- package/dist/entity/connectors/index.js.map +1 -0
- package/dist/entity/connectors/static.d.ts +51 -0
- package/dist/entity/connectors/static.js +245 -0
- package/dist/entity/connectors/static.js.map +1 -0
- package/dist/entity/entity-datasource.d.ts +50 -0
- package/dist/entity/entity-datasource.js +33 -0
- package/dist/entity/entity-datasource.js.map +1 -0
- package/dist/entity/facade.d.ts +70 -0
- package/dist/entity/facade.js +70 -0
- package/dist/entity/facade.js.map +1 -0
- package/dist/entity/http-connector.d.ts +123 -0
- package/dist/entity/http-connector.js +295 -0
- package/dist/entity/http-connector.js.map +1 -0
- package/dist/entity/index.d.ts +38 -0
- package/dist/entity/index.js +31 -0
- package/dist/entity/index.js.map +1 -0
- package/dist/entity/postgres-connector.d.ts +64 -0
- package/dist/entity/postgres-connector.js +239 -0
- package/dist/entity/postgres-connector.js.map +1 -0
- package/dist/entity/registry.d.ts +59 -0
- package/dist/entity/registry.js +90 -0
- package/dist/entity/registry.js.map +1 -0
- package/dist/entity/store.d.ts +66 -0
- package/dist/entity/store.js +349 -0
- package/dist/entity/store.js.map +1 -0
- package/dist/entity/types.d.ts +180 -0
- package/dist/entity/types.js +10 -0
- package/dist/entity/types.js.map +1 -0
- package/dist/execution-context.d.ts +88 -0
- package/dist/execution-context.js +146 -0
- package/dist/execution-context.js.map +1 -0
- package/dist/executor.d.ts +27 -0
- package/dist/executor.js +33 -0
- package/dist/executor.js.map +1 -0
- package/dist/forms/form-entity-bridge.d.ts +94 -0
- package/dist/forms/form-entity-bridge.js +96 -0
- package/dist/forms/form-entity-bridge.js.map +1 -0
- package/dist/forms/form-write-target.d.ts +34 -0
- package/dist/forms/form-write-target.js +81 -0
- package/dist/forms/form-write-target.js.map +1 -0
- package/dist/forms/index.d.ts +22 -0
- package/dist/forms/index.js +25 -0
- package/dist/forms/index.js.map +1 -0
- package/dist/forms/named-control-values.d.ts +27 -0
- package/dist/forms/named-control-values.js +42 -0
- package/dist/forms/named-control-values.js.map +1 -0
- package/dist/forms/processor.d.ts +55 -0
- package/dist/forms/processor.js +154 -0
- package/dist/forms/processor.js.map +1 -0
- package/dist/forms/types.d.ts +174 -0
- package/dist/forms/types.js +33 -0
- package/dist/forms/types.js.map +1 -0
- package/dist/forms/validator.d.ts +61 -0
- package/dist/forms/validator.js +218 -0
- package/dist/forms/validator.js.map +1 -0
- package/dist/graph/index.d.ts +10 -0
- package/dist/graph/index.js +9 -0
- package/dist/graph/index.js.map +1 -0
- package/dist/graph/resolver.d.ts +66 -0
- package/dist/graph/resolver.js +243 -0
- package/dist/graph/resolver.js.map +1 -0
- package/dist/graph/types.d.ts +125 -0
- package/dist/graph/types.js +9 -0
- package/dist/graph/types.js.map +1 -0
- package/dist/hooks/useInstalledAtoms.d.ts +96 -0
- package/dist/hooks/useInstalledAtoms.js +92 -0
- package/dist/hooks/useInstalledAtoms.js.map +1 -0
- package/dist/i18n/index.d.ts +15 -0
- package/dist/i18n/index.js +14 -0
- package/dist/i18n/index.js.map +1 -0
- package/dist/i18n/translator.d.ts +76 -0
- package/dist/i18n/translator.js +357 -0
- package/dist/i18n/translator.js.map +1 -0
- package/dist/i18n/types.d.ts +93 -0
- package/dist/i18n/types.js +9 -0
- package/dist/i18n/types.js.map +1 -0
- package/dist/index.d.ts +64 -0
- package/dist/index.js +95 -0
- package/dist/index.js.map +1 -0
- package/dist/kernel.d.ts +47 -0
- package/dist/kernel.js +258 -0
- package/dist/kernel.js.map +1 -0
- package/dist/perf/budget.d.ts +92 -0
- package/dist/perf/budget.js +122 -0
- package/dist/perf/budget.js.map +1 -0
- package/dist/perf/index.d.ts +16 -0
- package/dist/perf/index.js +13 -0
- package/dist/perf/index.js.map +1 -0
- package/dist/perf/render-timer.d.ts +90 -0
- package/dist/perf/render-timer.js +136 -0
- package/dist/perf/render-timer.js.map +1 -0
- package/dist/perf/reporter.d.ts +126 -0
- package/dist/perf/reporter.js +241 -0
- package/dist/perf/reporter.js.map +1 -0
- package/dist/perf/web-vitals.d.ts +111 -0
- package/dist/perf/web-vitals.js +268 -0
- package/dist/perf/web-vitals.js.map +1 -0
- package/dist/registry.d.ts +63 -0
- package/dist/registry.js +126 -0
- package/dist/registry.js.map +1 -0
- package/dist/render/BehaviorSurfaceProvider.d.ts +65 -0
- package/dist/render/BehaviorSurfaceProvider.js +185 -0
- package/dist/render/BehaviorSurfaceProvider.js.map +1 -0
- package/dist/render/BlockErrorBoundary.d.ts +26 -0
- package/dist/render/BlockErrorBoundary.js +41 -0
- package/dist/render/BlockErrorBoundary.js.map +1 -0
- package/dist/render/DataBoundSurfaceRenderer.d.ts +78 -0
- package/dist/render/DataBoundSurfaceRenderer.js +998 -0
- package/dist/render/DataBoundSurfaceRenderer.js.map +1 -0
- package/dist/render/DynamicBlockWrapper.d.ts +23 -0
- package/dist/render/DynamicBlockWrapper.js +117 -0
- package/dist/render/DynamicBlockWrapper.js.map +1 -0
- package/dist/render/appearance-resolver.d.ts +50 -0
- package/dist/render/appearance-resolver.js +78 -0
- package/dist/render/appearance-resolver.js.map +1 -0
- package/dist/render/capability-gate.d.ts +69 -0
- package/dist/render/capability-gate.js +94 -0
- package/dist/render/capability-gate.js.map +1 -0
- package/dist/render/conditional-states-css.d.ts +41 -0
- package/dist/render/conditional-states-css.js +82 -0
- package/dist/render/conditional-states-css.js.map +1 -0
- package/dist/render/connections-context.d.ts +31 -0
- package/dist/render/connections-context.js +34 -0
- package/dist/render/connections-context.js.map +1 -0
- package/dist/render/dark-theme-css.d.ts +36 -0
- package/dist/render/dark-theme-css.js +67 -0
- package/dist/render/dark-theme-css.js.map +1 -0
- package/dist/render/data-binding-types.d.ts +191 -0
- package/dist/render/data-binding-types.js +11 -0
- package/dist/render/data-binding-types.js.map +1 -0
- package/dist/render/data-cache.d.ts +30 -0
- package/dist/render/data-cache.js +37 -0
- package/dist/render/data-cache.js.map +1 -0
- package/dist/render/derive-dark-theme.d.ts +17 -0
- package/dist/render/derive-dark-theme.js +18 -0
- package/dist/render/derive-dark-theme.js.map +1 -0
- package/dist/render/dynamic-artifact-context.d.ts +77 -0
- package/dist/render/dynamic-artifact-context.js +89 -0
- package/dist/render/dynamic-artifact-context.js.map +1 -0
- package/dist/render/dynamic-block-loader.d.ts +80 -0
- package/dist/render/dynamic-block-loader.js +197 -0
- package/dist/render/dynamic-block-loader.js.map +1 -0
- package/dist/render/endpoint.d.ts +18 -0
- package/dist/render/endpoint.js +109 -0
- package/dist/render/endpoint.js.map +1 -0
- package/dist/render/entity-facade-context.d.ts +34 -0
- package/dist/render/entity-facade-context.js +37 -0
- package/dist/render/entity-facade-context.js.map +1 -0
- package/dist/render/group-states-css.d.ts +41 -0
- package/dist/render/group-states-css.js +73 -0
- package/dist/render/group-states-css.js.map +1 -0
- package/dist/render/hooks/useSurfaceEvents.d.ts +8 -0
- package/dist/render/hooks/useSurfaceEvents.js +9 -0
- package/dist/render/hooks/useSurfaceEvents.js.map +1 -0
- package/dist/render/hooks/useSurfaceId.d.ts +8 -0
- package/dist/render/hooks/useSurfaceId.js +9 -0
- package/dist/render/hooks/useSurfaceId.js.map +1 -0
- package/dist/render/index.d.ts +48 -0
- package/dist/render/index.js +61 -0
- package/dist/render/index.js.map +1 -0
- package/dist/render/interaction-rule-engine.d.ts +12 -0
- package/dist/render/interaction-rule-engine.js +47 -0
- package/dist/render/interaction-rule-engine.js.map +1 -0
- package/dist/render/keyframes-css.d.ts +31 -0
- package/dist/render/keyframes-css.js +44 -0
- package/dist/render/keyframes-css.js.map +1 -0
- package/dist/render/query-state.d.ts +3 -0
- package/dist/render/query-state.js +70 -0
- package/dist/render/query-state.js.map +1 -0
- package/dist/render/renderer.d.ts +44 -0
- package/dist/render/renderer.js +937 -0
- package/dist/render/renderer.js.map +1 -0
- package/dist/render/resolve-expressions.d.ts +37 -0
- package/dist/render/resolve-expressions.js +309 -0
- package/dist/render/resolve-expressions.js.map +1 -0
- package/dist/render/responsive-style-css.d.ts +42 -0
- package/dist/render/responsive-style-css.js +123 -0
- package/dist/render/responsive-style-css.js.map +1 -0
- package/dist/render/responsive.d.ts +49 -0
- package/dist/render/responsive.js +99 -0
- package/dist/render/responsive.js.map +1 -0
- package/dist/render/scoped-css.d.ts +71 -0
- package/dist/render/scoped-css.js +102 -0
- package/dist/render/scoped-css.js.map +1 -0
- package/dist/render/shell-selection.d.ts +69 -0
- package/dist/render/shell-selection.js +117 -0
- package/dist/render/shell-selection.js.map +1 -0
- package/dist/render/states-css.d.ts +32 -0
- package/dist/render/states-css.js +63 -0
- package/dist/render/states-css.js.map +1 -0
- package/dist/render/surface-data-context.d.ts +18 -0
- package/dist/render/surface-data-context.js +21 -0
- package/dist/render/surface-data-context.js.map +1 -0
- package/dist/render/surface-event-bus.d.ts +19 -0
- package/dist/render/surface-event-bus.js +68 -0
- package/dist/render/surface-event-bus.js.map +1 -0
- package/dist/render/surface-event-context.d.ts +11 -0
- package/dist/render/surface-event-context.js +12 -0
- package/dist/render/surface-event-context.js.map +1 -0
- package/dist/render/surface-id-context.d.ts +8 -0
- package/dist/render/surface-id-context.js +9 -0
- package/dist/render/surface-id-context.js.map +1 -0
- package/dist/render/theme-utils.d.ts +14 -0
- package/dist/render/theme-utils.js +15 -0
- package/dist/render/theme-utils.js.map +1 -0
- package/dist/render/types.d.ts +282 -0
- package/dist/render/types.js +9 -0
- package/dist/render/types.js.map +1 -0
- package/dist/render/visibility-css.d.ts +42 -0
- package/dist/render/visibility-css.js +119 -0
- package/dist/render/visibility-css.js.map +1 -0
- package/dist/render/width-scope.d.ts +34 -0
- package/dist/render/width-scope.js +44 -0
- package/dist/render/width-scope.js.map +1 -0
- package/dist/render/write-only-sources.d.ts +33 -0
- package/dist/render/write-only-sources.js +99 -0
- package/dist/render/write-only-sources.js.map +1 -0
- package/dist/routing/index.d.ts +14 -0
- package/dist/routing/index.js +15 -0
- package/dist/routing/index.js.map +1 -0
- package/dist/routing/router.d.ts +42 -0
- package/dist/routing/router.js +218 -0
- package/dist/routing/router.js.map +1 -0
- package/dist/routing/types.d.ts +124 -0
- package/dist/routing/types.js +9 -0
- package/dist/routing/types.js.map +1 -0
- package/dist/seo/generator.d.ts +39 -0
- package/dist/seo/generator.js +236 -0
- package/dist/seo/generator.js.map +1 -0
- package/dist/seo/index.d.ts +14 -0
- package/dist/seo/index.js +15 -0
- package/dist/seo/index.js.map +1 -0
- package/dist/seo/types.d.ts +181 -0
- package/dist/seo/types.js +9 -0
- package/dist/seo/types.js.map +1 -0
- package/dist/state/index.d.ts +15 -0
- package/dist/state/index.js +16 -0
- package/dist/state/index.js.map +1 -0
- package/dist/state/manager.d.ts +33 -0
- package/dist/state/manager.js +81 -0
- package/dist/state/manager.js.map +1 -0
- package/dist/state/store.d.ts +40 -0
- package/dist/state/store.js +145 -0
- package/dist/state/store.js.map +1 -0
- package/dist/state/types.d.ts +107 -0
- package/dist/state/types.js +9 -0
- package/dist/state/types.js.map +1 -0
- package/dist/surface/expression.d.ts +65 -0
- package/dist/surface/expression.js +179 -0
- package/dist/surface/expression.js.map +1 -0
- package/dist/surface/index.d.ts +32 -0
- package/dist/surface/index.js +25 -0
- package/dist/surface/index.js.map +1 -0
- package/dist/surface/interpreter.d.ts +96 -0
- package/dist/surface/interpreter.js +231 -0
- package/dist/surface/interpreter.js.map +1 -0
- package/dist/surface/layout.d.ts +54 -0
- package/dist/surface/layout.js +288 -0
- package/dist/surface/layout.js.map +1 -0
- package/dist/surface/output.d.ts +90 -0
- package/dist/surface/output.js +104 -0
- package/dist/surface/output.js.map +1 -0
- package/dist/surface/primitives.d.ts +180 -0
- package/dist/surface/primitives.js +339 -0
- package/dist/surface/primitives.js.map +1 -0
- package/dist/surface/renderer.d.ts +96 -0
- package/dist/surface/renderer.js +190 -0
- package/dist/surface/renderer.js.map +1 -0
- package/dist/surface/schemas.d.ts +181 -0
- package/dist/surface/schemas.js +142 -0
- package/dist/surface/schemas.js.map +1 -0
- package/dist/surface/transforms.d.ts +144 -0
- package/dist/surface/transforms.js +120 -0
- package/dist/surface/transforms.js.map +1 -0
- package/dist/surface/types.d.ts +160 -0
- package/dist/surface/types.js +51 -0
- package/dist/surface/types.js.map +1 -0
- package/dist/surface/validation.d.ts +123 -0
- package/dist/surface/validation.js +147 -0
- package/dist/surface/validation.js.map +1 -0
- package/dist/validator.d.ts +55 -0
- package/dist/validator.js +100 -0
- package/dist/validator.js.map +1 -0
- package/package.json +106 -3
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Execution Context
|
|
3
|
+
*
|
|
4
|
+
* Runtime execution context for capability execution
|
|
5
|
+
*
|
|
6
|
+
* @module @pwfabric/runtime/execution-context
|
|
7
|
+
*/
|
|
8
|
+
import type { CapabilityId, FabricId, ManifestationId, ExecutionContext, ExecutionLogger, ExecutionResult, Timestamp } from '@pwfabric/contracts';
|
|
9
|
+
/**
|
|
10
|
+
* Console-based execution logger
|
|
11
|
+
*/
|
|
12
|
+
export declare class ConsoleExecutionLogger implements ExecutionLogger {
|
|
13
|
+
private readonly traceId;
|
|
14
|
+
private readonly spanId;
|
|
15
|
+
constructor(traceId: string, spanId: string);
|
|
16
|
+
debug(message: string, data?: Record<string, unknown>): void;
|
|
17
|
+
info(message: string, data?: Record<string, unknown>): void;
|
|
18
|
+
warn(message: string, data?: Record<string, unknown>): void;
|
|
19
|
+
error(message: string, data?: Record<string, unknown>): void;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* No-op logger for silent execution
|
|
23
|
+
*/
|
|
24
|
+
export declare class NoOpExecutionLogger implements ExecutionLogger {
|
|
25
|
+
debug(_message: string, _data?: Record<string, unknown>): void;
|
|
26
|
+
info(_message: string, _data?: Record<string, unknown>): void;
|
|
27
|
+
warn(_message: string, _data?: Record<string, unknown>): void;
|
|
28
|
+
error(_message: string, _data?: Record<string, unknown>): void;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Invocation handler type for resolving capability execution
|
|
32
|
+
*/
|
|
33
|
+
export type InvocationHandler = <TInput, TOutput>(capabilityId: CapabilityId, input: TInput) => Promise<ExecutionResult<TOutput>>;
|
|
34
|
+
/**
|
|
35
|
+
* Runtime execution context options
|
|
36
|
+
*/
|
|
37
|
+
export interface RuntimeExecutionContextOptions {
|
|
38
|
+
traceId: string;
|
|
39
|
+
spanId: string;
|
|
40
|
+
parentSpanId?: string;
|
|
41
|
+
fabricId: FabricId;
|
|
42
|
+
manifestationId?: ManifestationId;
|
|
43
|
+
timeout?: number;
|
|
44
|
+
data?: Record<string, unknown>;
|
|
45
|
+
logger?: ExecutionLogger;
|
|
46
|
+
invoker: InvocationHandler;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Runtime execution context implementation
|
|
50
|
+
*/
|
|
51
|
+
export declare class RuntimeExecutionContext implements ExecutionContext {
|
|
52
|
+
readonly traceId: string;
|
|
53
|
+
readonly spanId: string;
|
|
54
|
+
readonly parentSpanId?: string;
|
|
55
|
+
readonly fabricId: FabricId;
|
|
56
|
+
readonly manifestationId?: ManifestationId;
|
|
57
|
+
readonly startedAt: Timestamp;
|
|
58
|
+
readonly timeout?: number;
|
|
59
|
+
readonly data: Record<string, unknown>;
|
|
60
|
+
readonly logger: ExecutionLogger;
|
|
61
|
+
private readonly invoker;
|
|
62
|
+
constructor(options: RuntimeExecutionContextOptions);
|
|
63
|
+
invoke<TInput, TOutput>(capabilityId: CapabilityId, input: TInput): Promise<ExecutionResult<TOutput>>;
|
|
64
|
+
child(spanId: string): ExecutionContext;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Generate a unique trace ID
|
|
68
|
+
*/
|
|
69
|
+
export declare function generateTraceId(): string;
|
|
70
|
+
/**
|
|
71
|
+
* Generate a unique span ID
|
|
72
|
+
*/
|
|
73
|
+
export declare function generateSpanId(): string;
|
|
74
|
+
/**
|
|
75
|
+
* Options for creating an execution context
|
|
76
|
+
*/
|
|
77
|
+
export interface CreateExecutionContextOptions {
|
|
78
|
+
fabricId: FabricId;
|
|
79
|
+
manifestationId?: ManifestationId;
|
|
80
|
+
timeout?: number;
|
|
81
|
+
data?: Record<string, unknown>;
|
|
82
|
+
silent?: boolean;
|
|
83
|
+
invoker: InvocationHandler;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Create a new execution context
|
|
87
|
+
*/
|
|
88
|
+
export declare function createExecutionContext(options: CreateExecutionContextOptions): RuntimeExecutionContext;
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Execution Context
|
|
3
|
+
*
|
|
4
|
+
* Runtime execution context for capability execution
|
|
5
|
+
*
|
|
6
|
+
* @module @pwfabric/runtime/execution-context
|
|
7
|
+
*/
|
|
8
|
+
// ============================================================
|
|
9
|
+
// LOGGER IMPLEMENTATION
|
|
10
|
+
// ============================================================
|
|
11
|
+
/**
|
|
12
|
+
* Console-based execution logger
|
|
13
|
+
*/
|
|
14
|
+
export class ConsoleExecutionLogger {
|
|
15
|
+
traceId;
|
|
16
|
+
spanId;
|
|
17
|
+
constructor(traceId, spanId) {
|
|
18
|
+
this.traceId = traceId;
|
|
19
|
+
this.spanId = spanId;
|
|
20
|
+
}
|
|
21
|
+
debug(message, data) {
|
|
22
|
+
console.debug(`[${this.traceId}:${this.spanId}] DEBUG: ${message}`, data || '');
|
|
23
|
+
}
|
|
24
|
+
info(message, data) {
|
|
25
|
+
console.info(`[${this.traceId}:${this.spanId}] INFO: ${message}`, data || '');
|
|
26
|
+
}
|
|
27
|
+
warn(message, data) {
|
|
28
|
+
console.warn(`[${this.traceId}:${this.spanId}] WARN: ${message}`, data || '');
|
|
29
|
+
}
|
|
30
|
+
error(message, data) {
|
|
31
|
+
console.error(`[${this.traceId}:${this.spanId}] ERROR: ${message}`, data || '');
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* No-op logger for silent execution
|
|
36
|
+
*/
|
|
37
|
+
export class NoOpExecutionLogger {
|
|
38
|
+
debug(_message, _data) {
|
|
39
|
+
// No-op
|
|
40
|
+
}
|
|
41
|
+
info(_message, _data) {
|
|
42
|
+
// No-op
|
|
43
|
+
}
|
|
44
|
+
warn(_message, _data) {
|
|
45
|
+
// No-op
|
|
46
|
+
}
|
|
47
|
+
error(_message, _data) {
|
|
48
|
+
// No-op
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Runtime execution context implementation
|
|
53
|
+
*/
|
|
54
|
+
export class RuntimeExecutionContext {
|
|
55
|
+
traceId;
|
|
56
|
+
spanId;
|
|
57
|
+
parentSpanId;
|
|
58
|
+
fabricId;
|
|
59
|
+
manifestationId;
|
|
60
|
+
startedAt;
|
|
61
|
+
timeout;
|
|
62
|
+
data;
|
|
63
|
+
logger;
|
|
64
|
+
invoker;
|
|
65
|
+
constructor(options) {
|
|
66
|
+
this.traceId = options.traceId;
|
|
67
|
+
this.spanId = options.spanId;
|
|
68
|
+
if (options.parentSpanId !== undefined) {
|
|
69
|
+
this.parentSpanId = options.parentSpanId;
|
|
70
|
+
}
|
|
71
|
+
this.fabricId = options.fabricId;
|
|
72
|
+
if (options.manifestationId !== undefined) {
|
|
73
|
+
this.manifestationId = options.manifestationId;
|
|
74
|
+
}
|
|
75
|
+
this.startedAt = Date.now();
|
|
76
|
+
if (options.timeout !== undefined) {
|
|
77
|
+
this.timeout = options.timeout;
|
|
78
|
+
}
|
|
79
|
+
this.data = options.data ?? {};
|
|
80
|
+
this.logger = options.logger ?? new ConsoleExecutionLogger(this.traceId, this.spanId);
|
|
81
|
+
this.invoker = options.invoker;
|
|
82
|
+
}
|
|
83
|
+
invoke(capabilityId, input) {
|
|
84
|
+
return this.invoker(capabilityId, input);
|
|
85
|
+
}
|
|
86
|
+
child(spanId) {
|
|
87
|
+
const childOptions = {
|
|
88
|
+
traceId: this.traceId,
|
|
89
|
+
spanId,
|
|
90
|
+
parentSpanId: this.spanId,
|
|
91
|
+
fabricId: this.fabricId,
|
|
92
|
+
invoker: this.invoker,
|
|
93
|
+
data: { ...this.data },
|
|
94
|
+
logger: new ConsoleExecutionLogger(this.traceId, spanId),
|
|
95
|
+
};
|
|
96
|
+
if (this.manifestationId !== undefined) {
|
|
97
|
+
childOptions.manifestationId = this.manifestationId;
|
|
98
|
+
}
|
|
99
|
+
if (this.timeout !== undefined) {
|
|
100
|
+
childOptions.timeout = this.timeout;
|
|
101
|
+
}
|
|
102
|
+
return new RuntimeExecutionContext(childOptions);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
// ============================================================
|
|
106
|
+
// CONTEXT FACTORY
|
|
107
|
+
// ============================================================
|
|
108
|
+
/**
|
|
109
|
+
* Generate a unique trace ID
|
|
110
|
+
*/
|
|
111
|
+
export function generateTraceId() {
|
|
112
|
+
return `trace_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Generate a unique span ID
|
|
116
|
+
*/
|
|
117
|
+
export function generateSpanId() {
|
|
118
|
+
return `span_${Math.random().toString(36).substr(2, 9)}`;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Create a new execution context
|
|
122
|
+
*/
|
|
123
|
+
export function createExecutionContext(options) {
|
|
124
|
+
const traceId = generateTraceId();
|
|
125
|
+
const spanId = generateSpanId();
|
|
126
|
+
const contextOptions = {
|
|
127
|
+
traceId,
|
|
128
|
+
spanId,
|
|
129
|
+
fabricId: options.fabricId,
|
|
130
|
+
invoker: options.invoker,
|
|
131
|
+
logger: options.silent
|
|
132
|
+
? new NoOpExecutionLogger()
|
|
133
|
+
: new ConsoleExecutionLogger(traceId, spanId),
|
|
134
|
+
};
|
|
135
|
+
if (options.manifestationId) {
|
|
136
|
+
contextOptions.manifestationId = options.manifestationId;
|
|
137
|
+
}
|
|
138
|
+
if (options.timeout) {
|
|
139
|
+
contextOptions.timeout = options.timeout;
|
|
140
|
+
}
|
|
141
|
+
if (options.data) {
|
|
142
|
+
contextOptions.data = options.data;
|
|
143
|
+
}
|
|
144
|
+
return new RuntimeExecutionContext(contextOptions);
|
|
145
|
+
}
|
|
146
|
+
//# sourceMappingURL=execution-context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"execution-context.js","sourceRoot":"","sources":["../src/execution-context.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Execution Context\n *\n * Runtime execution context for capability execution\n *\n * @module @pwfabric/runtime/execution-context\n */\n\nimport type {\n CapabilityId,\n FabricId,\n ManifestationId,\n ExecutionContext,\n ExecutionLogger,\n ExecutionResult,\n Timestamp,\n} from '@pwfabric/contracts'\n\n// ============================================================\n// LOGGER IMPLEMENTATION\n// ============================================================\n\n/**\n * Console-based execution logger\n */\nexport class ConsoleExecutionLogger implements ExecutionLogger {\n constructor(\n private readonly traceId: string,\n private readonly spanId: string\n ) {}\n\n debug(message: string, data?: Record<string, unknown>): void {\n console.debug(`[${this.traceId}:${this.spanId}] DEBUG: ${message}`, data || '')\n }\n\n info(message: string, data?: Record<string, unknown>): void {\n console.info(`[${this.traceId}:${this.spanId}] INFO: ${message}`, data || '')\n }\n\n warn(message: string, data?: Record<string, unknown>): void {\n console.warn(`[${this.traceId}:${this.spanId}] WARN: ${message}`, data || '')\n }\n\n error(message: string, data?: Record<string, unknown>): void {\n console.error(`[${this.traceId}:${this.spanId}] ERROR: ${message}`, data || '')\n }\n}\n\n/**\n * No-op logger for silent execution\n */\nexport class NoOpExecutionLogger implements ExecutionLogger {\n debug(_message: string, _data?: Record<string, unknown>): void {\n // No-op\n }\n info(_message: string, _data?: Record<string, unknown>): void {\n // No-op\n }\n warn(_message: string, _data?: Record<string, unknown>): void {\n // No-op\n }\n error(_message: string, _data?: Record<string, unknown>): void {\n // No-op\n }\n}\n\n// ============================================================\n// EXECUTION CONTEXT IMPLEMENTATION\n// ============================================================\n\n/**\n * Invocation handler type for resolving capability execution\n */\nexport type InvocationHandler = <TInput, TOutput>(\n capabilityId: CapabilityId,\n input: TInput\n) => Promise<ExecutionResult<TOutput>>\n\n/**\n * Runtime execution context options\n */\nexport interface RuntimeExecutionContextOptions {\n traceId: string\n spanId: string\n parentSpanId?: string\n fabricId: FabricId\n manifestationId?: ManifestationId\n timeout?: number\n data?: Record<string, unknown>\n logger?: ExecutionLogger\n invoker: InvocationHandler\n}\n\n/**\n * Runtime execution context implementation\n */\nexport class RuntimeExecutionContext implements ExecutionContext {\n readonly traceId: string\n readonly spanId: string\n readonly parentSpanId?: string\n readonly fabricId: FabricId\n readonly manifestationId?: ManifestationId\n readonly startedAt: Timestamp\n readonly timeout?: number\n readonly data: Record<string, unknown>\n readonly logger: ExecutionLogger\n\n private readonly invoker: InvocationHandler\n\n constructor(options: RuntimeExecutionContextOptions) {\n this.traceId = options.traceId\n this.spanId = options.spanId\n if (options.parentSpanId !== undefined) {\n this.parentSpanId = options.parentSpanId\n }\n this.fabricId = options.fabricId\n if (options.manifestationId !== undefined) {\n this.manifestationId = options.manifestationId\n }\n this.startedAt = Date.now()\n if (options.timeout !== undefined) {\n this.timeout = options.timeout\n }\n this.data = options.data ?? {}\n this.logger = options.logger ?? new ConsoleExecutionLogger(this.traceId, this.spanId)\n this.invoker = options.invoker\n }\n\n invoke<TInput, TOutput>(\n capabilityId: CapabilityId,\n input: TInput\n ): Promise<ExecutionResult<TOutput>> {\n return this.invoker(capabilityId, input)\n }\n\n child(spanId: string): ExecutionContext {\n const childOptions: RuntimeExecutionContextOptions = {\n traceId: this.traceId,\n spanId,\n parentSpanId: this.spanId,\n fabricId: this.fabricId,\n invoker: this.invoker,\n data: { ...this.data },\n logger: new ConsoleExecutionLogger(this.traceId, spanId),\n }\n if (this.manifestationId !== undefined) {\n childOptions.manifestationId = this.manifestationId\n }\n if (this.timeout !== undefined) {\n childOptions.timeout = this.timeout\n }\n return new RuntimeExecutionContext(childOptions)\n }\n}\n\n// ============================================================\n// CONTEXT FACTORY\n// ============================================================\n\n/**\n * Generate a unique trace ID\n */\nexport function generateTraceId(): string {\n return `trace_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`\n}\n\n/**\n * Generate a unique span ID\n */\nexport function generateSpanId(): string {\n return `span_${Math.random().toString(36).substr(2, 9)}`\n}\n\n/**\n * Options for creating an execution context\n */\nexport interface CreateExecutionContextOptions {\n fabricId: FabricId\n manifestationId?: ManifestationId\n timeout?: number\n data?: Record<string, unknown>\n silent?: boolean\n invoker: InvocationHandler\n}\n\n/**\n * Create a new execution context\n */\nexport function createExecutionContext(\n options: CreateExecutionContextOptions\n): RuntimeExecutionContext {\n const traceId = generateTraceId()\n const spanId = generateSpanId()\n\n const contextOptions: RuntimeExecutionContextOptions = {\n traceId,\n spanId,\n fabricId: options.fabricId,\n invoker: options.invoker,\n logger: options.silent\n ? new NoOpExecutionLogger()\n : new ConsoleExecutionLogger(traceId, spanId),\n }\n\n if (options.manifestationId) {\n contextOptions.manifestationId = options.manifestationId\n }\n if (options.timeout) {\n contextOptions.timeout = options.timeout\n }\n if (options.data) {\n contextOptions.data = options.data\n }\n\n return new RuntimeExecutionContext(contextOptions)\n}\n"]}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Task executor for PWFabric runtime
|
|
3
|
+
*/
|
|
4
|
+
import { type Result } from '@pwfabric/core';
|
|
5
|
+
import { type RuntimeContext } from './context.js';
|
|
6
|
+
/**
|
|
7
|
+
* Task definition
|
|
8
|
+
*/
|
|
9
|
+
export interface Task<TInput, TOutput> {
|
|
10
|
+
name: string;
|
|
11
|
+
execute: (input: TInput, ctx: RuntimeContext) => Promise<TOutput>;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Executor options
|
|
15
|
+
*/
|
|
16
|
+
export interface ExecutorOptions {
|
|
17
|
+
timeout?: number;
|
|
18
|
+
retries?: number;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Execute a task with the given input
|
|
22
|
+
*/
|
|
23
|
+
export declare function executeTask<TInput, TOutput>(task: Task<TInput, TOutput>, input: TInput, options?: ExecutorOptions): Promise<Result<TOutput, Error>>;
|
|
24
|
+
/**
|
|
25
|
+
* Create a task definition
|
|
26
|
+
*/
|
|
27
|
+
export declare function defineTask<TInput, TOutput>(name: string, execute: (input: TInput, ctx: RuntimeContext) => Promise<TOutput>): Task<TInput, TOutput>;
|
package/dist/executor.js
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Task executor for PWFabric runtime
|
|
3
|
+
*/
|
|
4
|
+
import { ok, err } from '@pwfabric/core';
|
|
5
|
+
import { createContext } from './context.js';
|
|
6
|
+
/**
|
|
7
|
+
* Execute a task with the given input
|
|
8
|
+
*/
|
|
9
|
+
export async function executeTask(task, input, options = {}) {
|
|
10
|
+
const ctx = createContext(task.name);
|
|
11
|
+
const { timeout = 30000 } = options;
|
|
12
|
+
ctx.logger.info(`Starting task: ${task.name}`);
|
|
13
|
+
try {
|
|
14
|
+
const result = await Promise.race([
|
|
15
|
+
task.execute(input, ctx),
|
|
16
|
+
new Promise((_, reject) => setTimeout(() => reject(new Error(`Task ${task.name} timed out after ${timeout}ms`)), timeout)),
|
|
17
|
+
]);
|
|
18
|
+
ctx.logger.info(`Task ${task.name} completed successfully`);
|
|
19
|
+
return ok(result);
|
|
20
|
+
}
|
|
21
|
+
catch (error) {
|
|
22
|
+
const err_ = error instanceof Error ? error : new Error(String(error));
|
|
23
|
+
ctx.logger.error(`Task ${task.name} failed`, { error: err_.message });
|
|
24
|
+
return err(err_);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Create a task definition
|
|
29
|
+
*/
|
|
30
|
+
export function defineTask(name, execute) {
|
|
31
|
+
return { name, execute };
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=executor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"executor.js","sourceRoot":"","sources":["../src/executor.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAe,EAAE,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAA;AACrD,OAAO,EAAuB,aAAa,EAAE,MAAM,cAAc,CAAA;AAkBjE;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,IAA2B,EAC3B,KAAa,EACb,UAA2B,EAAE;IAE7B,MAAM,GAAG,GAAG,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACpC,MAAM,EAAE,OAAO,GAAG,KAAK,EAAE,GAAG,OAAO,CAAA;IAEnC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,kBAAkB,IAAI,CAAC,IAAI,EAAE,CAAC,CAAA;IAE9C,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC;YAChC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;YACxB,IAAI,OAAO,CAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,CAC/B,UAAU,CACR,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,QAAQ,IAAI,CAAC,IAAI,oBAAoB,OAAO,IAAI,CAAC,CAAC,EACzE,OAAO,CACR,CACF;SACF,CAAC,CAAA;QAEF,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI,yBAAyB,CAAC,CAAA;QAC3D,OAAO,EAAE,CAAC,MAAM,CAAC,CAAA;IACnB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAA;QACtE,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,IAAI,CAAC,IAAI,SAAS,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,CAAA;QACrE,OAAO,GAAG,CAAC,IAAI,CAAC,CAAA;IAClB,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,UAAU,CACxB,IAAY,EACZ,OAAiE;IAEjE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAA;AAC1B,CAAC","sourcesContent":["/**\n * Task executor for PWFabric runtime\n */\n\nimport { type Result, ok, err } from '@pwfabric/core'\nimport { type RuntimeContext, createContext } from './context.js'\n\n/**\n * Task definition\n */\nexport interface Task<TInput, TOutput> {\n name: string\n execute: (input: TInput, ctx: RuntimeContext) => Promise<TOutput>\n}\n\n/**\n * Executor options\n */\nexport interface ExecutorOptions {\n timeout?: number\n retries?: number\n}\n\n/**\n * Execute a task with the given input\n */\nexport async function executeTask<TInput, TOutput>(\n task: Task<TInput, TOutput>,\n input: TInput,\n options: ExecutorOptions = {}\n): Promise<Result<TOutput, Error>> {\n const ctx = createContext(task.name)\n const { timeout = 30000 } = options\n\n ctx.logger.info(`Starting task: ${task.name}`)\n\n try {\n const result = await Promise.race([\n task.execute(input, ctx),\n new Promise<never>((_, reject) =>\n setTimeout(\n () => reject(new Error(`Task ${task.name} timed out after ${timeout}ms`)),\n timeout\n )\n ),\n ])\n\n ctx.logger.info(`Task ${task.name} completed successfully`)\n return ok(result)\n } catch (error) {\n const err_ = error instanceof Error ? error : new Error(String(error))\n ctx.logger.error(`Task ${task.name} failed`, { error: err_.message })\n return err(err_)\n }\n}\n\n/**\n * Create a task definition\n */\nexport function defineTask<TInput, TOutput>(\n name: string,\n execute: (input: TInput, ctx: RuntimeContext) => Promise<TOutput>\n): Task<TInput, TOutput> {\n return { name, execute }\n}\n"]}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Form → Entity Declarative Bridge
|
|
3
|
+
*
|
|
4
|
+
* Attaches a form-to-entity bridge to the SurfaceEventBus.
|
|
5
|
+
* When a specified form emits 'form:submit', writes to the data source the
|
|
6
|
+
* binding names — our own store or anyone else's endpoint.
|
|
7
|
+
*
|
|
8
|
+
* Requires `platform/entities` capability (platform/input retired;
|
|
9
|
+
* form submissions now flow exclusively through entity_records).
|
|
10
|
+
*
|
|
11
|
+
* @module @pwfabric/runtime/forms/form-entity-bridge
|
|
12
|
+
*/
|
|
13
|
+
import type { SurfaceEventBus } from '@pwfabric/contracts';
|
|
14
|
+
import type { EntityMutationResult, EntityOperationError } from '../entity/types.js';
|
|
15
|
+
export type { Unsubscribe } from '@pwfabric/contracts';
|
|
16
|
+
export interface FormEntityBridgeConfig {
|
|
17
|
+
/** The form block ID to listen for. */
|
|
18
|
+
formId: string;
|
|
19
|
+
/**
|
|
20
|
+
* The DATA SOURCE this form writes to.
|
|
21
|
+
*
|
|
22
|
+
* It used to be `entityType` — a platform model — which is why "why can we
|
|
23
|
+
* not POST to our own endpoint?" was a question with no answer: the form's
|
|
24
|
+
* only expressible destination was our store. A source has an address, and
|
|
25
|
+
* our store's address is one of them.
|
|
26
|
+
*
|
|
27
|
+
* The read half already worked this way; this is the write half catching up.
|
|
28
|
+
*/
|
|
29
|
+
sourceId: string;
|
|
30
|
+
/** How to write. Defaults to POST — the only shape a form has ever had. */
|
|
31
|
+
method?: 'POST' | 'PUT' | 'PATCH';
|
|
32
|
+
/**
|
|
33
|
+
* Optional mapping from form values to entity data.
|
|
34
|
+
* If omitted, form values are passed as-is.
|
|
35
|
+
*/
|
|
36
|
+
mapping?: (values: Record<string, unknown>) => Record<string, unknown>;
|
|
37
|
+
/** Called on successful entity creation. */
|
|
38
|
+
onSuccess?: (result: EntityMutationResult & {
|
|
39
|
+
success: true;
|
|
40
|
+
}) => void;
|
|
41
|
+
/** Called when entity creation fails. */
|
|
42
|
+
onError?: (error: EntityOperationError) => void;
|
|
43
|
+
/**
|
|
44
|
+
* Optional path to navigate to after success.
|
|
45
|
+
* Uses window.location.assign (client-side only).
|
|
46
|
+
*/
|
|
47
|
+
successRedirect?: string;
|
|
48
|
+
/**
|
|
49
|
+
* Surface-state keys the bridge drives across the create lifecycle, so the
|
|
50
|
+
* UI reflects the REAL API result (not an optimistic onSubmitAction):
|
|
51
|
+
* `loading` true while the create is in flight, then `success` OR `error`.
|
|
52
|
+
* Each is a boolean set via setState; gate blocks with if:{{state.<key>}}.
|
|
53
|
+
*/
|
|
54
|
+
statusKeys?: {
|
|
55
|
+
loading?: string;
|
|
56
|
+
success?: string;
|
|
57
|
+
error?: string;
|
|
58
|
+
/**
|
|
59
|
+
* Where the writer's OWN WORDS go on failure — the server's status and
|
|
60
|
+
* message, or the validation sentence naming the fields. Cleared (`''`)
|
|
61
|
+
* when an attempt starts and on success, so a toast bound to it never
|
|
62
|
+
* shows yesterday's refusal. Without it a page can only say "it failed"
|
|
63
|
+
* and has to invent why.
|
|
64
|
+
*/
|
|
65
|
+
message?: string;
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Where a form's submission is actually sent.
|
|
70
|
+
*
|
|
71
|
+
* One method, because a form has one job. The host decides what a source id
|
|
72
|
+
* means — the entity facade for a platform-backed source, an HTTP call for a
|
|
73
|
+
* rest one — which is what lets the same declaration serve both without the
|
|
74
|
+
* bridge knowing the difference.
|
|
75
|
+
*/
|
|
76
|
+
export interface FormWriter {
|
|
77
|
+
write(sourceId: string, values: Record<string, unknown>, method: 'POST' | 'PUT' | 'PATCH'): Promise<EntityMutationResult>;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Attaches a form-to-entity bridge to the SurfaceEventBus.
|
|
81
|
+
* When the specified form emits 'form:submit', writes to the source the
|
|
82
|
+
* binding names.
|
|
83
|
+
*
|
|
84
|
+
* Requires `platform/entities` capability active (platform/input retired).
|
|
85
|
+
*
|
|
86
|
+
* @returns Unsubscribe function — call on surface unmount.
|
|
87
|
+
*/
|
|
88
|
+
export declare function attachFormEntityBridge(bus: SurfaceEventBus, writer: FormWriter, config: FormEntityBridgeConfig,
|
|
89
|
+
/**
|
|
90
|
+
* Completes what the form block gathered before it is mapped and written —
|
|
91
|
+
* the host adds the named controls `FormData` cannot see (a control drawn
|
|
92
|
+
* from buttons has no native field; see forms/named-control-values).
|
|
93
|
+
*/
|
|
94
|
+
completeValues?: (formId: string, values: Record<string, unknown>) => Record<string, unknown>): () => void;
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Form → Entity Declarative Bridge
|
|
3
|
+
*
|
|
4
|
+
* Attaches a form-to-entity bridge to the SurfaceEventBus.
|
|
5
|
+
* When a specified form emits 'form:submit', writes to the data source the
|
|
6
|
+
* binding names — our own store or anyone else's endpoint.
|
|
7
|
+
*
|
|
8
|
+
* Requires `platform/entities` capability (platform/input retired;
|
|
9
|
+
* form submissions now flow exclusively through entity_records).
|
|
10
|
+
*
|
|
11
|
+
* @module @pwfabric/runtime/forms/form-entity-bridge
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* Attaches a form-to-entity bridge to the SurfaceEventBus.
|
|
15
|
+
* When the specified form emits 'form:submit', writes to the source the
|
|
16
|
+
* binding names.
|
|
17
|
+
*
|
|
18
|
+
* Requires `platform/entities` capability active (platform/input retired).
|
|
19
|
+
*
|
|
20
|
+
* @returns Unsubscribe function — call on surface unmount.
|
|
21
|
+
*/
|
|
22
|
+
export function attachFormEntityBridge(bus, writer, config,
|
|
23
|
+
/**
|
|
24
|
+
* Completes what the form block gathered before it is mapped and written —
|
|
25
|
+
* the host adds the named controls `FormData` cannot see (a control drawn
|
|
26
|
+
* from buttons has no native field; see forms/named-control-values).
|
|
27
|
+
*/
|
|
28
|
+
completeValues) {
|
|
29
|
+
// Drive a surface-state boolean via setState on the bus → handleEvent
|
|
30
|
+
// (DataBoundInner) applies it. Lets the UI reflect the REAL create lifecycle.
|
|
31
|
+
const sk = config.statusKeys;
|
|
32
|
+
const setState = (surfaceId, blockId, key, value) => {
|
|
33
|
+
bus.emit({
|
|
34
|
+
type: 'capability:form-status',
|
|
35
|
+
surfaceId,
|
|
36
|
+
...(blockId ? { blockId } : {}),
|
|
37
|
+
payload: { action: { type: 'setState', key, value } },
|
|
38
|
+
timestamp: Date.now(),
|
|
39
|
+
});
|
|
40
|
+
};
|
|
41
|
+
return bus.on('form:submit', async (descriptor) => {
|
|
42
|
+
// Only handle events for the configured form
|
|
43
|
+
if (descriptor.blockId !== config.formId)
|
|
44
|
+
return;
|
|
45
|
+
const gathered = descriptor.payload?.values ?? {};
|
|
46
|
+
const rawValues = completeValues ? completeValues(config.formId, gathered) : gathered;
|
|
47
|
+
const mapped = config.mapping ? config.mapping(rawValues) : rawValues;
|
|
48
|
+
// Lifecycle start: loading on, clear any prior success/error so the UI is
|
|
49
|
+
// accurate for THIS attempt.
|
|
50
|
+
if (sk?.loading)
|
|
51
|
+
setState(descriptor.surfaceId, descriptor.blockId, sk.loading, true);
|
|
52
|
+
if (sk?.success)
|
|
53
|
+
setState(descriptor.surfaceId, descriptor.blockId, sk.success, false);
|
|
54
|
+
if (sk?.error)
|
|
55
|
+
setState(descriptor.surfaceId, descriptor.blockId, sk.error, false);
|
|
56
|
+
if (sk?.message)
|
|
57
|
+
setState(descriptor.surfaceId, descriptor.blockId, sk.message, '');
|
|
58
|
+
const result = await writer.write(config.sourceId, mapped, config.method ?? 'POST');
|
|
59
|
+
// Loading off regardless of outcome.
|
|
60
|
+
if (sk?.loading)
|
|
61
|
+
setState(descriptor.surfaceId, descriptor.blockId, sk.loading, false);
|
|
62
|
+
if (result.success) {
|
|
63
|
+
config.onSuccess?.(result);
|
|
64
|
+
// Success is bound to the API result (not optimistic).
|
|
65
|
+
if (sk?.success)
|
|
66
|
+
setState(descriptor.surfaceId, descriptor.blockId, sk.success, true);
|
|
67
|
+
// Reactive read half: re-fetch data sources so an entity-backed list
|
|
68
|
+
// (dataSource kind:'entity') reflects the just-created record.
|
|
69
|
+
bus.emit({
|
|
70
|
+
type: 'entity:created',
|
|
71
|
+
surfaceId: descriptor.surfaceId,
|
|
72
|
+
...(descriptor.blockId ? { blockId: descriptor.blockId } : {}),
|
|
73
|
+
// Keyed by the SOURCE, because that is what a reader re-fetches. It
|
|
74
|
+
// used to be the entity type, which only a platform-backed list could
|
|
75
|
+
// match.
|
|
76
|
+
payload: { action: { type: 'refreshAll' }, sourceId: config.sourceId },
|
|
77
|
+
timestamp: Date.now(),
|
|
78
|
+
});
|
|
79
|
+
if (config.successRedirect) {
|
|
80
|
+
// Client-side navigation — safe to call in browser context
|
|
81
|
+
if (typeof window !== 'undefined') {
|
|
82
|
+
window.location.assign(config.successRedirect);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
config.onError?.(result.error);
|
|
88
|
+
// Failure is bound to the API result — and so are its words.
|
|
89
|
+
if (sk?.error)
|
|
90
|
+
setState(descriptor.surfaceId, descriptor.blockId, sk.error, true);
|
|
91
|
+
if (sk?.message)
|
|
92
|
+
setState(descriptor.surfaceId, descriptor.blockId, sk.message, result.error.message);
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=form-entity-bridge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"form-entity-bridge.js","sourceRoot":"","sources":["../../src/forms/form-entity-bridge.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Form → Entity Declarative Bridge\n *\n * Attaches a form-to-entity bridge to the SurfaceEventBus.\n * When a specified form emits 'form:submit', writes to the data source the\n * binding names — our own store or anyone else's endpoint.\n *\n * Requires `platform/entities` capability (platform/input retired;\n * form submissions now flow exclusively through entity_records).\n *\n * @module @pwfabric/runtime/forms/form-entity-bridge\n */\n\nimport type { SurfaceEventBus } from '@pwfabric/contracts'\nimport type { EntityMutationResult, EntityOperationError } from '../entity/types.js'\n\n// Re-export Unsubscribe from contracts for convenience\nexport type { Unsubscribe } from '@pwfabric/contracts'\n\nexport interface FormEntityBridgeConfig {\n /** The form block ID to listen for. */\n formId: string\n /**\n * The DATA SOURCE this form writes to.\n *\n * It used to be `entityType` — a platform model — which is why \"why can we\n * not POST to our own endpoint?\" was a question with no answer: the form's\n * only expressible destination was our store. A source has an address, and\n * our store's address is one of them.\n *\n * The read half already worked this way; this is the write half catching up.\n */\n sourceId: string\n /** How to write. Defaults to POST — the only shape a form has ever had. */\n method?: 'POST' | 'PUT' | 'PATCH'\n /**\n * Optional mapping from form values to entity data.\n * If omitted, form values are passed as-is.\n */\n mapping?: (values: Record<string, unknown>) => Record<string, unknown>\n /** Called on successful entity creation. */\n onSuccess?: (result: EntityMutationResult & { success: true }) => void\n /** Called when entity creation fails. */\n onError?: (error: EntityOperationError) => void\n /**\n * Optional path to navigate to after success.\n * Uses window.location.assign (client-side only).\n */\n successRedirect?: string\n /**\n * Surface-state keys the bridge drives across the create lifecycle, so the\n * UI reflects the REAL API result (not an optimistic onSubmitAction):\n * `loading` true while the create is in flight, then `success` OR `error`.\n * Each is a boolean set via setState; gate blocks with if:{{state.<key>}}.\n */\n statusKeys?: {\n loading?: string\n success?: string\n error?: string\n /**\n * Where the writer's OWN WORDS go on failure — the server's status and\n * message, or the validation sentence naming the fields. Cleared (`''`)\n * when an attempt starts and on success, so a toast bound to it never\n * shows yesterday's refusal. Without it a page can only say \"it failed\"\n * and has to invent why.\n */\n message?: string\n }\n}\n\n/**\n * Where a form's submission is actually sent.\n *\n * One method, because a form has one job. The host decides what a source id\n * means — the entity facade for a platform-backed source, an HTTP call for a\n * rest one — which is what lets the same declaration serve both without the\n * bridge knowing the difference.\n */\nexport interface FormWriter {\n write(\n sourceId: string,\n values: Record<string, unknown>,\n method: 'POST' | 'PUT' | 'PATCH'\n ): Promise<EntityMutationResult>\n}\n\n/**\n * Attaches a form-to-entity bridge to the SurfaceEventBus.\n * When the specified form emits 'form:submit', writes to the source the\n * binding names.\n *\n * Requires `platform/entities` capability active (platform/input retired).\n *\n * @returns Unsubscribe function — call on surface unmount.\n */\nexport function attachFormEntityBridge(\n bus: SurfaceEventBus,\n writer: FormWriter,\n config: FormEntityBridgeConfig,\n /**\n * Completes what the form block gathered before it is mapped and written —\n * the host adds the named controls `FormData` cannot see (a control drawn\n * from buttons has no native field; see forms/named-control-values).\n */\n completeValues?: (formId: string, values: Record<string, unknown>) => Record<string, unknown>\n): () => void {\n // Drive a surface-state boolean via setState on the bus → handleEvent\n // (DataBoundInner) applies it. Lets the UI reflect the REAL create lifecycle.\n const sk = config.statusKeys\n const setState = (surfaceId: string, blockId: string | undefined, key: string, value: unknown): void => {\n bus.emit({\n type: 'capability:form-status',\n surfaceId,\n ...(blockId ? { blockId } : {}),\n payload: { action: { type: 'setState', key, value } },\n timestamp: Date.now(),\n })\n }\n\n return bus.on('form:submit', async (descriptor) => {\n // Only handle events for the configured form\n if (descriptor.blockId !== config.formId) return\n\n const gathered = (descriptor.payload?.values as Record<string, unknown>) ?? {}\n const rawValues = completeValues ? completeValues(config.formId, gathered) : gathered\n const mapped = config.mapping ? config.mapping(rawValues) : rawValues\n\n // Lifecycle start: loading on, clear any prior success/error so the UI is\n // accurate for THIS attempt.\n if (sk?.loading) setState(descriptor.surfaceId, descriptor.blockId, sk.loading, true)\n if (sk?.success) setState(descriptor.surfaceId, descriptor.blockId, sk.success, false)\n if (sk?.error) setState(descriptor.surfaceId, descriptor.blockId, sk.error, false)\n if (sk?.message) setState(descriptor.surfaceId, descriptor.blockId, sk.message, '')\n\n const result = await writer.write(config.sourceId, mapped, config.method ?? 'POST')\n\n // Loading off regardless of outcome.\n if (sk?.loading) setState(descriptor.surfaceId, descriptor.blockId, sk.loading, false)\n\n if (result.success) {\n config.onSuccess?.(result)\n // Success is bound to the API result (not optimistic).\n if (sk?.success) setState(descriptor.surfaceId, descriptor.blockId, sk.success, true)\n // Reactive read half: re-fetch data sources so an entity-backed list\n // (dataSource kind:'entity') reflects the just-created record.\n bus.emit({\n type: 'entity:created',\n surfaceId: descriptor.surfaceId,\n ...(descriptor.blockId ? { blockId: descriptor.blockId } : {}),\n // Keyed by the SOURCE, because that is what a reader re-fetches. It\n // used to be the entity type, which only a platform-backed list could\n // match.\n payload: { action: { type: 'refreshAll' }, sourceId: config.sourceId },\n timestamp: Date.now(),\n })\n if (config.successRedirect) {\n // Client-side navigation — safe to call in browser context\n if (typeof window !== 'undefined') {\n window.location.assign(config.successRedirect)\n }\n }\n } else {\n config.onError?.(result.error)\n // Failure is bound to the API result — and so are its words.\n if (sk?.error) setState(descriptor.surfaceId, descriptor.blockId, sk.error, true)\n if (sk?.message) setState(descriptor.surfaceId, descriptor.blockId, sk.message, result.error.message)\n }\n })\n}\n"]}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Form write target — WHICH verb, WHICH record, and what a refusal means.
|
|
3
|
+
*
|
|
4
|
+
* A form binding says how it wants to write (`method: 'PATCH'`), but a PATCH
|
|
5
|
+
* has to name a record and the page only knows one from what its source
|
|
6
|
+
* loaded. When nothing loaded there is nothing to patch; the honest write is a
|
|
7
|
+
* create. Otherwise a Profile form would send `PATCH /records/Attendee` — the
|
|
8
|
+
* collection, no id — the API would answer 404 "Route not found", and the
|
|
9
|
+
* page would report it as a field-validation problem with no field
|
|
10
|
+
* highlighted.
|
|
11
|
+
*
|
|
12
|
+
* Two pure functions, so the rule is testable without a DOM and the same
|
|
13
|
+
* answer serves the in-process facade and the HTTP path alike.
|
|
14
|
+
*
|
|
15
|
+
* @module @pwfabric/runtime/forms/form-write-target
|
|
16
|
+
*/
|
|
17
|
+
import type { DataFetchError } from '../data/types.js';
|
|
18
|
+
import type { EntityOperationError } from '../entity/types.js';
|
|
19
|
+
export type FormWriteMethod = 'POST' | 'PUT' | 'PATCH';
|
|
20
|
+
export interface FormWriteTarget {
|
|
21
|
+
readonly method: FormWriteMethod;
|
|
22
|
+
/** Present only for an update — the id of the record the source has loaded. */
|
|
23
|
+
readonly recordId?: string;
|
|
24
|
+
}
|
|
25
|
+
export declare function resolveFormWriteTarget(method: FormWriteMethod, bound: unknown): FormWriteTarget;
|
|
26
|
+
/**
|
|
27
|
+
* Translate a data-layer refusal into what the form should say.
|
|
28
|
+
*
|
|
29
|
+
* "Check the highlighted fields" is reserved for a 400 that names fields.
|
|
30
|
+
* Anything else is the server refusing, and the server's own status and
|
|
31
|
+
* words are the message — a 404 on the collection path is a routing fact,
|
|
32
|
+
* not a problem with what the visitor typed.
|
|
33
|
+
*/
|
|
34
|
+
export declare function toFormWriteError(err: DataFetchError): EntityOperationError;
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Form write target — WHICH verb, WHICH record, and what a refusal means.
|
|
3
|
+
*
|
|
4
|
+
* A form binding says how it wants to write (`method: 'PATCH'`), but a PATCH
|
|
5
|
+
* has to name a record and the page only knows one from what its source
|
|
6
|
+
* loaded. When nothing loaded there is nothing to patch; the honest write is a
|
|
7
|
+
* create. Otherwise a Profile form would send `PATCH /records/Attendee` — the
|
|
8
|
+
* collection, no id — the API would answer 404 "Route not found", and the
|
|
9
|
+
* page would report it as a field-validation problem with no field
|
|
10
|
+
* highlighted.
|
|
11
|
+
*
|
|
12
|
+
* Two pure functions, so the rule is testable without a DOM and the same
|
|
13
|
+
* answer serves the in-process facade and the HTTP path alike.
|
|
14
|
+
*
|
|
15
|
+
* @module @pwfabric/runtime/forms/form-write-target
|
|
16
|
+
*/
|
|
17
|
+
/**
|
|
18
|
+
* The record a source currently binds, if any.
|
|
19
|
+
*
|
|
20
|
+
* A list source binds an array (the platform's record reads always do — see
|
|
21
|
+
* `LIST_KINDS` in DataBoundSurfaceRenderer); a single-record source may bind
|
|
22
|
+
* an object. The FIRST row is the record a form on that page edits: a
|
|
23
|
+
* profile page reads "me", a settings page reads "the one preference row".
|
|
24
|
+
*/
|
|
25
|
+
function boundRecord(bound) {
|
|
26
|
+
const candidate = Array.isArray(bound) ? bound[0] : bound;
|
|
27
|
+
return candidate !== null && typeof candidate === 'object' && !Array.isArray(candidate)
|
|
28
|
+
? candidate
|
|
29
|
+
: undefined;
|
|
30
|
+
}
|
|
31
|
+
export function resolveFormWriteTarget(method, bound) {
|
|
32
|
+
if (method === 'POST')
|
|
33
|
+
return { method: 'POST' };
|
|
34
|
+
const id = boundRecord(bound)?.['id'];
|
|
35
|
+
const recordId = typeof id === 'string' ? id : typeof id === 'number' ? String(id) : undefined;
|
|
36
|
+
return recordId ? { method, recordId } : { method: 'POST' };
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* The field paths a validation refusal names.
|
|
40
|
+
*
|
|
41
|
+
* The API answers `VALIDATION_FAILED` with `path: message; path: message`
|
|
42
|
+
* (the host's app-records API). Read the paths out so a
|
|
43
|
+
* form can highlight them; keep the whole sentence so the visitor can too.
|
|
44
|
+
*/
|
|
45
|
+
function fieldPathsOf(message) {
|
|
46
|
+
return message
|
|
47
|
+
.split(';')
|
|
48
|
+
.map((part) => part.trim())
|
|
49
|
+
.filter((part) => part.includes(':'))
|
|
50
|
+
.map((part) => part.slice(0, part.indexOf(':')).trim())
|
|
51
|
+
.filter((path) => path.length > 0 && !/\s/.test(path));
|
|
52
|
+
}
|
|
53
|
+
const VALIDATION_CODES = new Set(['VALIDATION_FAILED', 'INVALID_BODY']);
|
|
54
|
+
/**
|
|
55
|
+
* Translate a data-layer refusal into what the form should say.
|
|
56
|
+
*
|
|
57
|
+
* "Check the highlighted fields" is reserved for a 400 that names fields.
|
|
58
|
+
* Anything else is the server refusing, and the server's own status and
|
|
59
|
+
* words are the message — a 404 on the collection path is a routing fact,
|
|
60
|
+
* not a problem with what the visitor typed.
|
|
61
|
+
*/
|
|
62
|
+
export function toFormWriteError(err) {
|
|
63
|
+
const { status, code, message } = err;
|
|
64
|
+
if (status === undefined) {
|
|
65
|
+
return { type: 'connector', message: `Could not reach the server: ${message}` };
|
|
66
|
+
}
|
|
67
|
+
if (status === 400 && (code === undefined || VALIDATION_CODES.has(code))) {
|
|
68
|
+
return {
|
|
69
|
+
type: 'validation',
|
|
70
|
+
message: `Check the highlighted fields — ${message}`,
|
|
71
|
+
details: { status, code, fields: fieldPathsOf(message) },
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
const type = status === 404 ? 'not_found' : status === 401 || status === 403 ? 'unauthorized' : 'connector';
|
|
75
|
+
return {
|
|
76
|
+
type,
|
|
77
|
+
message: `The server could not save this record (${status}): ${message}`,
|
|
78
|
+
details: { status, code },
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=form-write-target.js.map
|