@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,245 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Static Entity Connector
|
|
3
|
+
*
|
|
4
|
+
* In-memory Map-based connector for prototyping and testing.
|
|
5
|
+
* Supports filter, sort, and pagination operations.
|
|
6
|
+
*
|
|
7
|
+
* @module @pwfabric/runtime/entity/connectors/static
|
|
8
|
+
*/
|
|
9
|
+
// ============================================================
|
|
10
|
+
// STATIC CONNECTOR
|
|
11
|
+
// ============================================================
|
|
12
|
+
/**
|
|
13
|
+
* In-memory static connector for prototyping and testing.
|
|
14
|
+
* Stores data in a Map keyed by entity type, then by instance id.
|
|
15
|
+
*/
|
|
16
|
+
export class StaticConnector {
|
|
17
|
+
name;
|
|
18
|
+
type = 'static';
|
|
19
|
+
store = new Map();
|
|
20
|
+
counter = 0;
|
|
21
|
+
constructor(name = 'static') {
|
|
22
|
+
this.name = name;
|
|
23
|
+
}
|
|
24
|
+
async create(entityType, data) {
|
|
25
|
+
const typeStore = this.getOrCreateTypeStore(entityType);
|
|
26
|
+
const id = this.generateId();
|
|
27
|
+
const record = { ...data, id };
|
|
28
|
+
typeStore.set(id, record);
|
|
29
|
+
return { success: true, data: record };
|
|
30
|
+
}
|
|
31
|
+
async read(entityType, instanceId) {
|
|
32
|
+
const typeStore = this.store.get(entityType);
|
|
33
|
+
if (!typeStore) {
|
|
34
|
+
return { success: false, error: `Entity type '${entityType}' has no data` };
|
|
35
|
+
}
|
|
36
|
+
const record = typeStore.get(instanceId);
|
|
37
|
+
if (!record) {
|
|
38
|
+
return { success: false, error: `Instance '${instanceId}' not found` };
|
|
39
|
+
}
|
|
40
|
+
return { success: true, data: { ...record } };
|
|
41
|
+
}
|
|
42
|
+
async update(entityType, instanceId, data) {
|
|
43
|
+
const typeStore = this.store.get(entityType);
|
|
44
|
+
if (!typeStore) {
|
|
45
|
+
return { success: false, error: `Entity type '${entityType}' has no data` };
|
|
46
|
+
}
|
|
47
|
+
const existing = typeStore.get(instanceId);
|
|
48
|
+
if (!existing) {
|
|
49
|
+
return { success: false, error: `Instance '${instanceId}' not found` };
|
|
50
|
+
}
|
|
51
|
+
const updated = { ...existing, ...data, id: instanceId };
|
|
52
|
+
typeStore.set(instanceId, updated);
|
|
53
|
+
return { success: true, data: updated };
|
|
54
|
+
}
|
|
55
|
+
async delete(entityType, instanceId) {
|
|
56
|
+
const typeStore = this.store.get(entityType);
|
|
57
|
+
if (!typeStore) {
|
|
58
|
+
return { success: false, error: `Entity type '${entityType}' has no data` };
|
|
59
|
+
}
|
|
60
|
+
const existing = typeStore.get(instanceId);
|
|
61
|
+
if (!existing) {
|
|
62
|
+
return { success: false, error: `Instance '${instanceId}' not found` };
|
|
63
|
+
}
|
|
64
|
+
typeStore.delete(instanceId);
|
|
65
|
+
return { success: true, data: existing };
|
|
66
|
+
}
|
|
67
|
+
async query(entityType, query) {
|
|
68
|
+
const typeStore = this.store.get(entityType);
|
|
69
|
+
if (!typeStore) {
|
|
70
|
+
return {
|
|
71
|
+
success: true,
|
|
72
|
+
result: {
|
|
73
|
+
items: [],
|
|
74
|
+
total: 0,
|
|
75
|
+
offset: 0,
|
|
76
|
+
limit: query.pagination?.limit ?? 50,
|
|
77
|
+
hasMore: false,
|
|
78
|
+
},
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
let items = Array.from(typeStore.values());
|
|
82
|
+
// Apply filters
|
|
83
|
+
if (query.filter) {
|
|
84
|
+
items = this.applyFilter(items, query.filter);
|
|
85
|
+
}
|
|
86
|
+
const total = items.length;
|
|
87
|
+
// Apply sort
|
|
88
|
+
if (query.sort && query.sort.length > 0) {
|
|
89
|
+
items = this.applySort(items, query.sort);
|
|
90
|
+
}
|
|
91
|
+
// Apply pagination
|
|
92
|
+
const offset = query.pagination?.offset ?? 0;
|
|
93
|
+
const limit = query.pagination?.limit ?? 50;
|
|
94
|
+
const paginatedItems = items.slice(offset, offset + limit);
|
|
95
|
+
return {
|
|
96
|
+
success: true,
|
|
97
|
+
result: {
|
|
98
|
+
items: paginatedItems,
|
|
99
|
+
total,
|
|
100
|
+
offset,
|
|
101
|
+
limit,
|
|
102
|
+
hasMore: offset + limit < total,
|
|
103
|
+
},
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Seed data into the connector for testing
|
|
108
|
+
*/
|
|
109
|
+
seed(entityType, records) {
|
|
110
|
+
const typeStore = this.getOrCreateTypeStore(entityType);
|
|
111
|
+
for (const record of records) {
|
|
112
|
+
const id = record.id ?? this.generateId();
|
|
113
|
+
typeStore.set(id, { ...record, id });
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Clear all data from the connector
|
|
118
|
+
*/
|
|
119
|
+
clear() {
|
|
120
|
+
this.store.clear();
|
|
121
|
+
this.counter = 0;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Clear data for a specific entity type
|
|
125
|
+
*/
|
|
126
|
+
clearType(entityType) {
|
|
127
|
+
this.store.delete(entityType);
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Get the total count of records for an entity type
|
|
131
|
+
*/
|
|
132
|
+
count(entityType) {
|
|
133
|
+
return this.store.get(entityType)?.size ?? 0;
|
|
134
|
+
}
|
|
135
|
+
getOrCreateTypeStore(entityType) {
|
|
136
|
+
let typeStore = this.store.get(entityType);
|
|
137
|
+
if (!typeStore) {
|
|
138
|
+
typeStore = new Map();
|
|
139
|
+
this.store.set(entityType, typeStore);
|
|
140
|
+
}
|
|
141
|
+
return typeStore;
|
|
142
|
+
}
|
|
143
|
+
generateId() {
|
|
144
|
+
this.counter++;
|
|
145
|
+
return `inst_${this.counter}`;
|
|
146
|
+
}
|
|
147
|
+
applyFilter(items, filter) {
|
|
148
|
+
let result = items;
|
|
149
|
+
// Apply the main condition
|
|
150
|
+
if (filter.field && filter.operator) {
|
|
151
|
+
result = result.filter((item) => this.matchesCondition(item, filter));
|
|
152
|
+
}
|
|
153
|
+
// Apply AND conditions
|
|
154
|
+
if (filter.and && filter.and.length > 0) {
|
|
155
|
+
for (const andFilter of filter.and) {
|
|
156
|
+
result = this.applyFilter(result, andFilter);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
// Apply OR conditions
|
|
160
|
+
if (filter.or && filter.or.length > 0) {
|
|
161
|
+
const orResults = new Set();
|
|
162
|
+
for (const orFilter of filter.or) {
|
|
163
|
+
const orMatches = this.applyFilter(result, orFilter);
|
|
164
|
+
for (const match of orMatches) {
|
|
165
|
+
orResults.add(match);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
result = Array.from(orResults);
|
|
169
|
+
}
|
|
170
|
+
return result;
|
|
171
|
+
}
|
|
172
|
+
matchesCondition(item, filter) {
|
|
173
|
+
const fieldValue = item[filter.field];
|
|
174
|
+
const filterValue = filter.value;
|
|
175
|
+
switch (filter.operator) {
|
|
176
|
+
case 'eq':
|
|
177
|
+
return fieldValue === filterValue;
|
|
178
|
+
case 'neq':
|
|
179
|
+
return fieldValue !== filterValue;
|
|
180
|
+
case 'gt':
|
|
181
|
+
return typeof fieldValue === 'number' && typeof filterValue === 'number'
|
|
182
|
+
? fieldValue > filterValue
|
|
183
|
+
: false;
|
|
184
|
+
case 'gte':
|
|
185
|
+
return typeof fieldValue === 'number' && typeof filterValue === 'number'
|
|
186
|
+
? fieldValue >= filterValue
|
|
187
|
+
: false;
|
|
188
|
+
case 'lt':
|
|
189
|
+
return typeof fieldValue === 'number' && typeof filterValue === 'number'
|
|
190
|
+
? fieldValue < filterValue
|
|
191
|
+
: false;
|
|
192
|
+
case 'lte':
|
|
193
|
+
return typeof fieldValue === 'number' && typeof filterValue === 'number'
|
|
194
|
+
? fieldValue <= filterValue
|
|
195
|
+
: false;
|
|
196
|
+
case 'in':
|
|
197
|
+
return Array.isArray(filterValue) ? filterValue.includes(fieldValue) : false;
|
|
198
|
+
case 'contains':
|
|
199
|
+
return typeof fieldValue === 'string' && typeof filterValue === 'string'
|
|
200
|
+
? fieldValue.includes(filterValue)
|
|
201
|
+
: false;
|
|
202
|
+
case 'startsWith':
|
|
203
|
+
return typeof fieldValue === 'string' && typeof filterValue === 'string'
|
|
204
|
+
? fieldValue.startsWith(filterValue)
|
|
205
|
+
: false;
|
|
206
|
+
default:
|
|
207
|
+
return false;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
applySort(items, sortFields) {
|
|
211
|
+
return [...items].sort((a, b) => {
|
|
212
|
+
for (const sortField of sortFields) {
|
|
213
|
+
const aVal = a[sortField.field];
|
|
214
|
+
const bVal = b[sortField.field];
|
|
215
|
+
let comparison = 0;
|
|
216
|
+
if (typeof aVal === 'string' && typeof bVal === 'string') {
|
|
217
|
+
comparison = aVal.localeCompare(bVal);
|
|
218
|
+
}
|
|
219
|
+
else if (typeof aVal === 'number' && typeof bVal === 'number') {
|
|
220
|
+
comparison = aVal - bVal;
|
|
221
|
+
}
|
|
222
|
+
else if (aVal === undefined || aVal === null) {
|
|
223
|
+
comparison = -1;
|
|
224
|
+
}
|
|
225
|
+
else if (bVal === undefined || bVal === null) {
|
|
226
|
+
comparison = 1;
|
|
227
|
+
}
|
|
228
|
+
if (comparison !== 0) {
|
|
229
|
+
return sortField.direction === 'desc' ? -comparison : comparison;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
return 0;
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
// ============================================================
|
|
237
|
+
// FACTORY FUNCTION
|
|
238
|
+
// ============================================================
|
|
239
|
+
/**
|
|
240
|
+
* Create a static connector
|
|
241
|
+
*/
|
|
242
|
+
export function createStaticConnector(name) {
|
|
243
|
+
return new StaticConnector(name);
|
|
244
|
+
}
|
|
245
|
+
//# sourceMappingURL=static.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"static.js","sourceRoot":"","sources":["../../../src/entity/connectors/static.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Static Entity Connector\n *\n * In-memory Map-based connector for prototyping and testing.\n * Supports filter, sort, and pagination operations.\n *\n * @module @pwfabric/runtime/entity/connectors/static\n */\n\nimport type {\n EntityTypeId,\n EntityInstanceId,\n EntityQuery,\n EntityFilter,\n EntitySortField,\n} from '../types.js'\nimport type { EntityConnector, ConnectorResult, ConnectorQueryResult } from '../connector.js'\n\n// ============================================================\n// STATIC CONNECTOR\n// ============================================================\n\n/**\n * In-memory static connector for prototyping and testing.\n * Stores data in a Map keyed by entity type, then by instance id.\n */\nexport class StaticConnector implements EntityConnector {\n readonly name: string\n readonly type = 'static' as const\n\n private readonly store = new Map<EntityTypeId, Map<EntityInstanceId, Record<string, unknown>>>()\n private counter = 0\n\n constructor(name = 'static') {\n this.name = name\n }\n\n async create(entityType: EntityTypeId, data: Record<string, unknown>): Promise<ConnectorResult> {\n const typeStore = this.getOrCreateTypeStore(entityType)\n const id = this.generateId()\n const record = { ...data, id }\n\n typeStore.set(id, record)\n\n return { success: true, data: record }\n }\n\n async read(entityType: EntityTypeId, instanceId: EntityInstanceId): Promise<ConnectorResult> {\n const typeStore = this.store.get(entityType)\n if (!typeStore) {\n return { success: false, error: `Entity type '${entityType}' has no data` }\n }\n\n const record = typeStore.get(instanceId)\n if (!record) {\n return { success: false, error: `Instance '${instanceId}' not found` }\n }\n\n return { success: true, data: { ...record } }\n }\n\n async update(\n entityType: EntityTypeId,\n instanceId: EntityInstanceId,\n data: Record<string, unknown>\n ): Promise<ConnectorResult> {\n const typeStore = this.store.get(entityType)\n if (!typeStore) {\n return { success: false, error: `Entity type '${entityType}' has no data` }\n }\n\n const existing = typeStore.get(instanceId)\n if (!existing) {\n return { success: false, error: `Instance '${instanceId}' not found` }\n }\n\n const updated = { ...existing, ...data, id: instanceId }\n typeStore.set(instanceId, updated)\n\n return { success: true, data: updated }\n }\n\n async delete(entityType: EntityTypeId, instanceId: EntityInstanceId): Promise<ConnectorResult> {\n const typeStore = this.store.get(entityType)\n if (!typeStore) {\n return { success: false, error: `Entity type '${entityType}' has no data` }\n }\n\n const existing = typeStore.get(instanceId)\n if (!existing) {\n return { success: false, error: `Instance '${instanceId}' not found` }\n }\n\n typeStore.delete(instanceId)\n\n return { success: true, data: existing }\n }\n\n async query(entityType: EntityTypeId, query: EntityQuery): Promise<ConnectorQueryResult> {\n const typeStore = this.store.get(entityType)\n if (!typeStore) {\n return {\n success: true,\n result: {\n items: [],\n total: 0,\n offset: 0,\n limit: query.pagination?.limit ?? 50,\n hasMore: false,\n },\n }\n }\n\n let items = Array.from(typeStore.values())\n\n // Apply filters\n if (query.filter) {\n items = this.applyFilter(items, query.filter)\n }\n\n const total = items.length\n\n // Apply sort\n if (query.sort && query.sort.length > 0) {\n items = this.applySort(items, query.sort)\n }\n\n // Apply pagination\n const offset = query.pagination?.offset ?? 0\n const limit = query.pagination?.limit ?? 50\n const paginatedItems = items.slice(offset, offset + limit)\n\n return {\n success: true,\n result: {\n items: paginatedItems,\n total,\n offset,\n limit,\n hasMore: offset + limit < total,\n },\n }\n }\n\n /**\n * Seed data into the connector for testing\n */\n seed(entityType: EntityTypeId, records: Record<string, unknown>[]): void {\n const typeStore = this.getOrCreateTypeStore(entityType)\n for (const record of records) {\n const id = (record.id as EntityInstanceId) ?? this.generateId()\n typeStore.set(id, { ...record, id })\n }\n }\n\n /**\n * Clear all data from the connector\n */\n clear(): void {\n this.store.clear()\n this.counter = 0\n }\n\n /**\n * Clear data for a specific entity type\n */\n clearType(entityType: EntityTypeId): void {\n this.store.delete(entityType)\n }\n\n /**\n * Get the total count of records for an entity type\n */\n count(entityType: EntityTypeId): number {\n return this.store.get(entityType)?.size ?? 0\n }\n\n private getOrCreateTypeStore(\n entityType: EntityTypeId\n ): Map<EntityInstanceId, Record<string, unknown>> {\n let typeStore = this.store.get(entityType)\n if (!typeStore) {\n typeStore = new Map()\n this.store.set(entityType, typeStore)\n }\n return typeStore\n }\n\n private generateId(): EntityInstanceId {\n this.counter++\n return `inst_${this.counter}` as EntityInstanceId\n }\n\n private applyFilter(\n items: Record<string, unknown>[],\n filter: EntityFilter\n ): Record<string, unknown>[] {\n let result = items\n\n // Apply the main condition\n if (filter.field && filter.operator) {\n result = result.filter((item) => this.matchesCondition(item, filter))\n }\n\n // Apply AND conditions\n if (filter.and && filter.and.length > 0) {\n for (const andFilter of filter.and) {\n result = this.applyFilter(result, andFilter)\n }\n }\n\n // Apply OR conditions\n if (filter.or && filter.or.length > 0) {\n const orResults = new Set<Record<string, unknown>>()\n for (const orFilter of filter.or) {\n const orMatches = this.applyFilter(result, orFilter)\n for (const match of orMatches) {\n orResults.add(match)\n }\n }\n result = Array.from(orResults)\n }\n\n return result\n }\n\n private matchesCondition(item: Record<string, unknown>, filter: EntityFilter): boolean {\n const fieldValue = item[filter.field]\n const filterValue = filter.value\n\n switch (filter.operator) {\n case 'eq':\n return fieldValue === filterValue\n case 'neq':\n return fieldValue !== filterValue\n case 'gt':\n return typeof fieldValue === 'number' && typeof filterValue === 'number'\n ? fieldValue > filterValue\n : false\n case 'gte':\n return typeof fieldValue === 'number' && typeof filterValue === 'number'\n ? fieldValue >= filterValue\n : false\n case 'lt':\n return typeof fieldValue === 'number' && typeof filterValue === 'number'\n ? fieldValue < filterValue\n : false\n case 'lte':\n return typeof fieldValue === 'number' && typeof filterValue === 'number'\n ? fieldValue <= filterValue\n : false\n case 'in':\n return Array.isArray(filterValue) ? filterValue.includes(fieldValue) : false\n case 'contains':\n return typeof fieldValue === 'string' && typeof filterValue === 'string'\n ? fieldValue.includes(filterValue)\n : false\n case 'startsWith':\n return typeof fieldValue === 'string' && typeof filterValue === 'string'\n ? fieldValue.startsWith(filterValue)\n : false\n default:\n return false\n }\n }\n\n private applySort(\n items: Record<string, unknown>[],\n sortFields: readonly EntitySortField[]\n ): Record<string, unknown>[] {\n return [...items].sort((a, b) => {\n for (const sortField of sortFields) {\n const aVal = a[sortField.field]\n const bVal = b[sortField.field]\n\n let comparison = 0\n\n if (typeof aVal === 'string' && typeof bVal === 'string') {\n comparison = aVal.localeCompare(bVal)\n } else if (typeof aVal === 'number' && typeof bVal === 'number') {\n comparison = aVal - bVal\n } else if (aVal === undefined || aVal === null) {\n comparison = -1\n } else if (bVal === undefined || bVal === null) {\n comparison = 1\n }\n\n if (comparison !== 0) {\n return sortField.direction === 'desc' ? -comparison : comparison\n }\n }\n return 0\n })\n }\n}\n\n// ============================================================\n// FACTORY FUNCTION\n// ============================================================\n\n/**\n * Create a static connector\n */\nexport function createStaticConnector(name?: string): StaticConnector {\n return new StaticConnector(name)\n}\n"]}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Entity DataSource Adapter
|
|
3
|
+
*
|
|
4
|
+
* Wraps EntityStore.query() as a minimal DataSource-compatible
|
|
5
|
+
* adapter so the surface expression system can resolve entity data via the
|
|
6
|
+
* existing {{data.sourceName.field}} binding path.
|
|
7
|
+
*
|
|
8
|
+
* @module @pwfabric/runtime/entity/entity-datasource
|
|
9
|
+
*/
|
|
10
|
+
import type { EntityFacade } from './facade.js';
|
|
11
|
+
import type { EntityTypeId, EntityQuery, EntityQueryResult } from './types.js';
|
|
12
|
+
/**
|
|
13
|
+
* Configuration for an EntityDataSource instance.
|
|
14
|
+
* Matches the `entity`-typed entry in a surface definition's dataSources array.
|
|
15
|
+
*/
|
|
16
|
+
export interface EntityDataSourceConfig {
|
|
17
|
+
/** Unique identifier — matches the surface definition id used in expressions */
|
|
18
|
+
readonly id: string;
|
|
19
|
+
/** Entity type to query (e.g. 'Employee', 'Product') */
|
|
20
|
+
readonly entityType: EntityTypeId;
|
|
21
|
+
/** Optional query parameters (filter, sort, pagination) */
|
|
22
|
+
readonly query?: EntityQuery;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Minimal DataSource-compatible adapter for entity queries.
|
|
26
|
+
* fetch() delegates to EntityFacade.resolveBinding() and returns EntityQueryResult.
|
|
27
|
+
* Results are accessible via {{data.sourceName.items}} / {{data.sourceName.total}}.
|
|
28
|
+
*/
|
|
29
|
+
export interface EntityDataSource {
|
|
30
|
+
readonly id: string;
|
|
31
|
+
readonly type: 'entity';
|
|
32
|
+
fetch(): Promise<EntityQueryResult>;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Creates an EntityDataSource that wraps EntityStore.query() for a specific
|
|
36
|
+
* entity type. Register with the surface data context to make results
|
|
37
|
+
* available in block expression props.
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* ```ts
|
|
41
|
+
* const employeesSource = createEntityDataSource(facade, {
|
|
42
|
+
* id: 'employees',
|
|
43
|
+
* entityType: 'Employee',
|
|
44
|
+
* query: { sort: [{ field: 'name', direction: 'asc' }] },
|
|
45
|
+
* })
|
|
46
|
+
* const result = await employeesSource.fetch()
|
|
47
|
+
* // result.items — array of employee records
|
|
48
|
+
* ```
|
|
49
|
+
*/
|
|
50
|
+
export declare function createEntityDataSource(facade: EntityFacade, config: EntityDataSourceConfig): EntityDataSource;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Entity DataSource Adapter
|
|
3
|
+
*
|
|
4
|
+
* Wraps EntityStore.query() as a minimal DataSource-compatible
|
|
5
|
+
* adapter so the surface expression system can resolve entity data via the
|
|
6
|
+
* existing {{data.sourceName.field}} binding path.
|
|
7
|
+
*
|
|
8
|
+
* @module @pwfabric/runtime/entity/entity-datasource
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Creates an EntityDataSource that wraps EntityStore.query() for a specific
|
|
12
|
+
* entity type. Register with the surface data context to make results
|
|
13
|
+
* available in block expression props.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```ts
|
|
17
|
+
* const employeesSource = createEntityDataSource(facade, {
|
|
18
|
+
* id: 'employees',
|
|
19
|
+
* entityType: 'Employee',
|
|
20
|
+
* query: { sort: [{ field: 'name', direction: 'asc' }] },
|
|
21
|
+
* })
|
|
22
|
+
* const result = await employeesSource.fetch()
|
|
23
|
+
* // result.items — array of employee records
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
export function createEntityDataSource(facade, config) {
|
|
27
|
+
return {
|
|
28
|
+
id: config.id,
|
|
29
|
+
type: 'entity',
|
|
30
|
+
fetch: () => facade.resolveBinding(config.entityType, config.query),
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=entity-datasource.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"entity-datasource.js","sourceRoot":"","sources":["../../src/entity/entity-datasource.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAiCH;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,sBAAsB,CACpC,MAAoB,EACpB,MAA8B;IAE9B,OAAO;QACL,EAAE,EAAE,MAAM,CAAC,EAAE;QACb,IAAI,EAAE,QAAQ;QACd,KAAK,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,KAAK,CAAC;KACpE,CAAA;AACH,CAAC","sourcesContent":["/**\n * Entity DataSource Adapter\n *\n * Wraps EntityStore.query() as a minimal DataSource-compatible\n * adapter so the surface expression system can resolve entity data via the\n * existing {{data.sourceName.field}} binding path.\n *\n * @module @pwfabric/runtime/entity/entity-datasource\n */\n\nimport type { EntityFacade } from './facade.js'\nimport type { EntityTypeId, EntityQuery, EntityQueryResult } from './types.js'\n\n// ============================================================\n// ENTITY DATA SOURCE\n// ============================================================\n\n/**\n * Configuration for an EntityDataSource instance.\n * Matches the `entity`-typed entry in a surface definition's dataSources array.\n */\nexport interface EntityDataSourceConfig {\n /** Unique identifier — matches the surface definition id used in expressions */\n readonly id: string\n /** Entity type to query (e.g. 'Employee', 'Product') */\n readonly entityType: EntityTypeId\n /** Optional query parameters (filter, sort, pagination) */\n readonly query?: EntityQuery\n}\n\n/**\n * Minimal DataSource-compatible adapter for entity queries.\n * fetch() delegates to EntityFacade.resolveBinding() and returns EntityQueryResult.\n * Results are accessible via {{data.sourceName.items}} / {{data.sourceName.total}}.\n */\nexport interface EntityDataSource {\n readonly id: string\n readonly type: 'entity'\n fetch(): Promise<EntityQueryResult>\n}\n\n/**\n * Creates an EntityDataSource that wraps EntityStore.query() for a specific\n * entity type. Register with the surface data context to make results\n * available in block expression props.\n *\n * @example\n * ```ts\n * const employeesSource = createEntityDataSource(facade, {\n * id: 'employees',\n * entityType: 'Employee',\n * query: { sort: [{ field: 'name', direction: 'asc' }] },\n * })\n * const result = await employeesSource.fetch()\n * // result.items — array of employee records\n * ```\n */\nexport function createEntityDataSource(\n facade: EntityFacade,\n config: EntityDataSourceConfig\n): EntityDataSource {\n return {\n id: config.id,\n type: 'entity',\n fetch: () => facade.resolveBinding(config.entityType, config.query),\n }\n}\n"]}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Entity Facade
|
|
3
|
+
*
|
|
4
|
+
* Facade that combines Registry, Store, ConnectorRegistry, and
|
|
5
|
+
* EntityLifecycleEngine into a single facade for surface integration.
|
|
6
|
+
*
|
|
7
|
+
* Renamed from EntityCapability to EntityFacade to avoid collision
|
|
8
|
+
* with the canonical Platform Capability interface.
|
|
9
|
+
*
|
|
10
|
+
* de-behaviorization: `behaviors` field renamed to `entityLifecycle`.
|
|
11
|
+
* `behaviors` kept as deprecated accessor for one minor version.
|
|
12
|
+
*
|
|
13
|
+
* @module @pwfabric/runtime/entity/facade
|
|
14
|
+
*/
|
|
15
|
+
import type { EntityTypeId, EntityDefinition, EntityQuery, EntityQueryResult, EntityAggregate, EntityAggregateResult } from './types.js';
|
|
16
|
+
import type { EntityRegistry } from './registry.js';
|
|
17
|
+
import type { EntityStore } from './store.js';
|
|
18
|
+
import type { ConnectorRegistry } from './connector.js';
|
|
19
|
+
import type { EntityLifecycleEngine } from './behavior.js';
|
|
20
|
+
/**
|
|
21
|
+
* Facade that provides unified access to the entity system
|
|
22
|
+
*/
|
|
23
|
+
export interface EntityFacade {
|
|
24
|
+
/** Entity type registry */
|
|
25
|
+
readonly registry: EntityRegistry;
|
|
26
|
+
/** Entity CRUD store */
|
|
27
|
+
readonly store: EntityStore;
|
|
28
|
+
/** Connector registry for data source binding */
|
|
29
|
+
readonly connectors: ConnectorRegistry;
|
|
30
|
+
/** Entity lifecycle engine for hook registration and execution (onCreate/onUpdate/onDelete/onRead) */
|
|
31
|
+
readonly entityLifecycle: EntityLifecycleEngine;
|
|
32
|
+
/**
|
|
33
|
+
* Convenience method to register an entity definition and bind it to a connector
|
|
34
|
+
*/
|
|
35
|
+
registerEntity(definition: EntityDefinition, connectorName: string): void;
|
|
36
|
+
/**
|
|
37
|
+
* Resolve a binding for Surface expression resolution.
|
|
38
|
+
* Queries the entity store for the given entity type and query.
|
|
39
|
+
*/
|
|
40
|
+
resolveBinding(entityType: EntityTypeId, query?: EntityQuery): Promise<EntityQueryResult>;
|
|
41
|
+
/**
|
|
42
|
+
* Resolve an AGGREGATE source: one number over the collection.
|
|
43
|
+
* Rejects when the number cannot be served (never answers a false 0).
|
|
44
|
+
* OPTIONAL so a host facade built before this still type-checks; the
|
|
45
|
+
* renderer lists and reduces in memory when it is absent.
|
|
46
|
+
*/
|
|
47
|
+
resolveAggregate?(entityType: EntityTypeId, aggregate: EntityAggregate): Promise<EntityAggregateResult>;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Default implementation of EntityFacade
|
|
51
|
+
*/
|
|
52
|
+
export declare class DefaultEntityFacade implements EntityFacade {
|
|
53
|
+
readonly registry: EntityRegistry;
|
|
54
|
+
readonly store: EntityStore;
|
|
55
|
+
readonly connectors: ConnectorRegistry;
|
|
56
|
+
readonly entityLifecycle: EntityLifecycleEngine;
|
|
57
|
+
constructor(registry: EntityRegistry, store: EntityStore, connectors: ConnectorRegistry, entityLifecycle: EntityLifecycleEngine);
|
|
58
|
+
registerEntity(definition: EntityDefinition, connectorName: string): void;
|
|
59
|
+
resolveBinding(entityType: EntityTypeId, query?: EntityQuery): Promise<EntityQueryResult>;
|
|
60
|
+
resolveAggregate(entityType: EntityTypeId, aggregate: EntityAggregate): Promise<EntityAggregateResult>;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Create an entity facade with all subsystems wired together
|
|
64
|
+
*/
|
|
65
|
+
export declare function createEntityFacade(options?: {
|
|
66
|
+
registry?: EntityRegistry;
|
|
67
|
+
connectors?: ConnectorRegistry;
|
|
68
|
+
/** Primary option — entity lifecycle engine for hook registration */
|
|
69
|
+
entityLifecycle?: EntityLifecycleEngine;
|
|
70
|
+
}): EntityFacade;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Entity Facade
|
|
3
|
+
*
|
|
4
|
+
* Facade that combines Registry, Store, ConnectorRegistry, and
|
|
5
|
+
* EntityLifecycleEngine into a single facade for surface integration.
|
|
6
|
+
*
|
|
7
|
+
* Renamed from EntityCapability to EntityFacade to avoid collision
|
|
8
|
+
* with the canonical Platform Capability interface.
|
|
9
|
+
*
|
|
10
|
+
* de-behaviorization: `behaviors` field renamed to `entityLifecycle`.
|
|
11
|
+
* `behaviors` kept as deprecated accessor for one minor version.
|
|
12
|
+
*
|
|
13
|
+
* @module @pwfabric/runtime/entity/facade
|
|
14
|
+
*/
|
|
15
|
+
import { createEntityRegistry } from './registry.js';
|
|
16
|
+
import { createEntityStore } from './store.js';
|
|
17
|
+
import { createConnectorRegistry } from './connector.js';
|
|
18
|
+
import { createEntityLifecycleEngine } from './behavior.js';
|
|
19
|
+
import { aggregateThrough } from './aggregate.js';
|
|
20
|
+
// ============================================================
|
|
21
|
+
// DEFAULT ENTITY FACADE
|
|
22
|
+
// ============================================================
|
|
23
|
+
/**
|
|
24
|
+
* Default implementation of EntityFacade
|
|
25
|
+
*/
|
|
26
|
+
export class DefaultEntityFacade {
|
|
27
|
+
registry;
|
|
28
|
+
store;
|
|
29
|
+
connectors;
|
|
30
|
+
entityLifecycle;
|
|
31
|
+
constructor(registry, store, connectors, entityLifecycle) {
|
|
32
|
+
this.registry = registry;
|
|
33
|
+
this.store = store;
|
|
34
|
+
this.connectors = connectors;
|
|
35
|
+
this.entityLifecycle = entityLifecycle;
|
|
36
|
+
}
|
|
37
|
+
registerEntity(definition, connectorName) {
|
|
38
|
+
// Register the entity definition
|
|
39
|
+
this.registry.register(definition);
|
|
40
|
+
// Bind entity type to connector
|
|
41
|
+
this.connectors.bind(definition.id, connectorName);
|
|
42
|
+
}
|
|
43
|
+
async resolveBinding(entityType, query) {
|
|
44
|
+
return this.store.query(entityType, query ?? {});
|
|
45
|
+
}
|
|
46
|
+
async resolveAggregate(entityType, aggregate) {
|
|
47
|
+
if (typeof this.store.aggregate === 'function')
|
|
48
|
+
return this.store.aggregate(entityType, aggregate);
|
|
49
|
+
// A host store without `aggregate`: list through `query`, reduce here.
|
|
50
|
+
const store = this.store;
|
|
51
|
+
const result = await aggregateThrough({ query: async (t, q) => ({ success: true, result: await store.query(t, q) }) }, entityType, aggregate);
|
|
52
|
+
if (!result.success)
|
|
53
|
+
throw new Error(result.error);
|
|
54
|
+
return result.result;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
// ============================================================
|
|
58
|
+
// FACTORY FUNCTION
|
|
59
|
+
// ============================================================
|
|
60
|
+
/**
|
|
61
|
+
* Create an entity facade with all subsystems wired together
|
|
62
|
+
*/
|
|
63
|
+
export function createEntityFacade(options) {
|
|
64
|
+
const registry = options?.registry ?? createEntityRegistry();
|
|
65
|
+
const connectors = options?.connectors ?? createConnectorRegistry();
|
|
66
|
+
const entityLifecycle = options?.entityLifecycle ?? createEntityLifecycleEngine();
|
|
67
|
+
const store = createEntityStore(registry, connectors);
|
|
68
|
+
return new DefaultEntityFacade(registry, store, connectors, entityLifecycle);
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=facade.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"facade.js","sourceRoot":"","sources":["../../src/entity/facade.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAeH,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAA;AACpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAC9C,OAAO,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAA;AACxD,OAAO,EAAE,2BAA2B,EAAE,MAAM,eAAe,CAAA;AAC3D,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAA;AA0CjD,+DAA+D;AAC/D,wBAAwB;AACxB,+DAA+D;AAE/D;;GAEG;AACH,MAAM,OAAO,mBAAmB;IACrB,QAAQ,CAAgB;IACxB,KAAK,CAAa;IAClB,UAAU,CAAmB;IAC7B,eAAe,CAAuB;IAE/C,YACE,QAAwB,EACxB,KAAkB,EAClB,UAA6B,EAC7B,eAAsC;QAEtC,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAA;QACxB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAA;QAClB,IAAI,CAAC,UAAU,GAAG,UAAU,CAAA;QAC5B,IAAI,CAAC,eAAe,GAAG,eAAe,CAAA;IACxC,CAAC;IAED,cAAc,CAAC,UAA4B,EAAE,aAAqB;QAChE,iCAAiC;QACjC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAA;QAElC,gCAAgC;QAChC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,EAAE,aAAa,CAAC,CAAA;IACpD,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,UAAwB,EAAE,KAAmB;QAChE,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,UAAU,EAAE,KAAK,IAAI,EAAE,CAAC,CAAA;IAClD,CAAC;IAED,KAAK,CAAC,gBAAgB,CAAC,UAAwB,EAAE,SAA0B;QACzE,IAAI,OAAO,IAAI,CAAC,KAAK,CAAC,SAAS,KAAK,UAAU;YAAE,OAAO,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,UAAU,EAAE,SAAS,CAAC,CAAA;QAClG,uEAAuE;QACvE,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAA;QACxB,MAAM,MAAM,GAAG,MAAM,gBAAgB,CACnC,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAC/E,UAAU,EACV,SAAS,CACV,CAAA;QACD,IAAI,CAAC,MAAM,CAAC,OAAO;YAAE,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;QAClD,OAAO,MAAM,CAAC,MAAM,CAAA;IACtB,CAAC;CACF;AAED,+DAA+D;AAC/D,mBAAmB;AACnB,+DAA+D;AAE/D;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAAC,OAKlC;IACC,MAAM,QAAQ,GAAG,OAAO,EAAE,QAAQ,IAAI,oBAAoB,EAAE,CAAA;IAC5D,MAAM,UAAU,GAAG,OAAO,EAAE,UAAU,IAAI,uBAAuB,EAAE,CAAA;IACnE,MAAM,eAAe,GACnB,OAAO,EAAE,eAAe,IAAI,2BAA2B,EAAE,CAAA;IAC3D,MAAM,KAAK,GAAG,iBAAiB,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAA;IAErD,OAAO,IAAI,mBAAmB,CAAC,QAAQ,EAAE,KAAK,EAAE,UAAU,EAAE,eAAe,CAAC,CAAA;AAC9E,CAAC","sourcesContent":["/**\n * Entity Facade\n *\n * Facade that combines Registry, Store, ConnectorRegistry, and\n * EntityLifecycleEngine into a single facade for surface integration.\n *\n * Renamed from EntityCapability to EntityFacade to avoid collision\n * with the canonical Platform Capability interface.\n *\n * de-behaviorization: `behaviors` field renamed to `entityLifecycle`.\n * `behaviors` kept as deprecated accessor for one minor version.\n *\n * @module @pwfabric/runtime/entity/facade\n */\n\nimport type {\n EntityTypeId,\n EntityDefinition,\n EntityQuery,\n EntityQueryResult,\n EntityAggregate,\n EntityAggregateResult,\n} from './types.js'\nimport type { EntityRegistry } from './registry.js'\nimport type { EntityStore } from './store.js'\nimport type { ConnectorRegistry } from './connector.js'\nimport type { EntityLifecycleEngine } from './behavior.js'\n\nimport { createEntityRegistry } from './registry.js'\nimport { createEntityStore } from './store.js'\nimport { createConnectorRegistry } from './connector.js'\nimport { createEntityLifecycleEngine } from './behavior.js'\nimport { aggregateThrough } from './aggregate.js'\n\n// ============================================================\n// ENTITY FACADE INTERFACE\n// ============================================================\n\n/**\n * Facade that provides unified access to the entity system\n */\nexport interface EntityFacade {\n /** Entity type registry */\n readonly registry: EntityRegistry\n\n /** Entity CRUD store */\n readonly store: EntityStore\n\n /** Connector registry for data source binding */\n readonly connectors: ConnectorRegistry\n\n /** Entity lifecycle engine for hook registration and execution (onCreate/onUpdate/onDelete/onRead) */\n readonly entityLifecycle: EntityLifecycleEngine\n\n /**\n * Convenience method to register an entity definition and bind it to a connector\n */\n registerEntity(definition: EntityDefinition, connectorName: string): void\n\n /**\n * Resolve a binding for Surface expression resolution.\n * Queries the entity store for the given entity type and query.\n */\n resolveBinding(entityType: EntityTypeId, query?: EntityQuery): Promise<EntityQueryResult>\n\n /**\n * Resolve an AGGREGATE source: one number over the collection.\n * Rejects when the number cannot be served (never answers a false 0).\n * OPTIONAL so a host facade built before this still type-checks; the\n * renderer lists and reduces in memory when it is absent.\n */\n resolveAggregate?(entityType: EntityTypeId, aggregate: EntityAggregate): Promise<EntityAggregateResult>\n}\n\n// ============================================================\n// DEFAULT ENTITY FACADE\n// ============================================================\n\n/**\n * Default implementation of EntityFacade\n */\nexport class DefaultEntityFacade implements EntityFacade {\n readonly registry: EntityRegistry\n readonly store: EntityStore\n readonly connectors: ConnectorRegistry\n readonly entityLifecycle: EntityLifecycleEngine\n\n constructor(\n registry: EntityRegistry,\n store: EntityStore,\n connectors: ConnectorRegistry,\n entityLifecycle: EntityLifecycleEngine\n ) {\n this.registry = registry\n this.store = store\n this.connectors = connectors\n this.entityLifecycle = entityLifecycle\n }\n\n registerEntity(definition: EntityDefinition, connectorName: string): void {\n // Register the entity definition\n this.registry.register(definition)\n\n // Bind entity type to connector\n this.connectors.bind(definition.id, connectorName)\n }\n\n async resolveBinding(entityType: EntityTypeId, query?: EntityQuery): Promise<EntityQueryResult> {\n return this.store.query(entityType, query ?? {})\n }\n\n async resolveAggregate(entityType: EntityTypeId, aggregate: EntityAggregate): Promise<EntityAggregateResult> {\n if (typeof this.store.aggregate === 'function') return this.store.aggregate(entityType, aggregate)\n // A host store without `aggregate`: list through `query`, reduce here.\n const store = this.store\n const result = await aggregateThrough(\n { query: async (t, q) => ({ success: true, result: await store.query(t, q) }) },\n entityType,\n aggregate\n )\n if (!result.success) throw new Error(result.error)\n return result.result\n }\n}\n\n// ============================================================\n// FACTORY FUNCTION\n// ============================================================\n\n/**\n * Create an entity facade with all subsystems wired together\n */\nexport function createEntityFacade(options?: {\n registry?: EntityRegistry\n connectors?: ConnectorRegistry\n /** Primary option — entity lifecycle engine for hook registration */\n entityLifecycle?: EntityLifecycleEngine\n}): EntityFacade {\n const registry = options?.registry ?? createEntityRegistry()\n const connectors = options?.connectors ?? createConnectorRegistry()\n const entityLifecycle =\n options?.entityLifecycle ?? createEntityLifecycleEngine()\n const store = createEntityStore(registry, connectors)\n\n return new DefaultEntityFacade(registry, store, connectors, entityLifecycle)\n}\n"]}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP Entity Connector
|
|
3
|
+
*
|
|
4
|
+
* REST API connector for entity data persistence and retrieval.
|
|
5
|
+
* Implements the EntityConnector interface using fetch for HTTP communication.
|
|
6
|
+
*
|
|
7
|
+
* @module @pwfabric/runtime/entity/http-connector
|
|
8
|
+
*/
|
|
9
|
+
import type { EntityTypeId, EntityInstanceId, EntityQuery, EntityAggregate } from './types.js';
|
|
10
|
+
import type { EntityConnector, EntityConnectorType, ConnectorResult, ConnectorQueryResult, ConnectorAggregateResult } from './connector.js';
|
|
11
|
+
/**
|
|
12
|
+
* HTTP connector authentication configuration
|
|
13
|
+
*/
|
|
14
|
+
export interface HttpAuthConfig {
|
|
15
|
+
readonly type: 'bearer' | 'api-key' | 'basic';
|
|
16
|
+
/**
|
|
17
|
+
* A fixed value, or a RESOLVER re-invoked on every request.
|
|
18
|
+
*
|
|
19
|
+
* A string or a resolver. A delegated PKCE token expires within about an
|
|
20
|
+
* hour, so a fixed string cannot serve a session; an engine that needs a
|
|
21
|
+
* live token passes a resolver instead of reimplementing the transport
|
|
22
|
+
* (and losing retry, timeout and the result envelope on the way).
|
|
23
|
+
*
|
|
24
|
+
* A string is used as is; a resolver is awaited per request and its answer
|
|
25
|
+
* is never cached here, which is the whole point.
|
|
26
|
+
*/
|
|
27
|
+
readonly token?: string | (() => Promise<string | null>);
|
|
28
|
+
readonly apiKey?: string;
|
|
29
|
+
readonly headerName?: string;
|
|
30
|
+
readonly username?: string;
|
|
31
|
+
readonly password?: string;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* HTTP connector retry configuration
|
|
35
|
+
*/
|
|
36
|
+
export interface HttpRetryConfig {
|
|
37
|
+
readonly maxRetries: number;
|
|
38
|
+
readonly baseDelay: number;
|
|
39
|
+
readonly maxDelay: number;
|
|
40
|
+
readonly retryableStatuses: readonly number[];
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* HTTP connector configuration
|
|
44
|
+
*/
|
|
45
|
+
export interface HttpConnectorConfig {
|
|
46
|
+
readonly baseUrl: string;
|
|
47
|
+
readonly headers?: Record<string, string>;
|
|
48
|
+
readonly timeout?: number;
|
|
49
|
+
readonly auth?: HttpAuthConfig;
|
|
50
|
+
/**
|
|
51
|
+
* Fetch credentials mode. Set 'include' so cookie-authoritative APIs
|
|
52
|
+
* receive the session cookie on cross-origin entity requests
|
|
53
|
+
* the visitor facade has no bearer token to send.
|
|
54
|
+
*/
|
|
55
|
+
readonly credentials?: RequestCredentials;
|
|
56
|
+
readonly retry?: HttpRetryConfig;
|
|
57
|
+
/**
|
|
58
|
+
* Query parameters this API requires on every read.
|
|
59
|
+
*
|
|
60
|
+
* GENERIC, and the distinction matters because three vendor-shaped widenings
|
|
61
|
+
* were proposed and reverted the same day. Azure wants `api-version`, plenty
|
|
62
|
+
* of APIs want `format=json`, Graph wants `expand=fields`: "this endpoint
|
|
63
|
+
* takes constant parameters" is a REST fact, not one provider's dance, and no
|
|
64
|
+
* provider name appears here.
|
|
65
|
+
*
|
|
66
|
+
* It exists because the alternative is worse. A caller that put its constants
|
|
67
|
+
* in `entityPathMapper` would produce `...?expand=fields?limit=50` the moment
|
|
68
|
+
* a query carried pagination, and `...?expand=fields/1` on a delete — the URL
|
|
69
|
+
* is assembled as `params ? url + '?' + params : url`.
|
|
70
|
+
*/
|
|
71
|
+
readonly defaultQueryParams?: Readonly<Record<string, string>>;
|
|
72
|
+
readonly entityPathMapper?: (entityType: EntityTypeId) => string;
|
|
73
|
+
/**
|
|
74
|
+
* Maps a vendor response body to the connector's query result shape
|
|
75
|
+
* `entityPathMapper`'s response-side twin.
|
|
76
|
+
*
|
|
77
|
+
* `entityPathMapper` has always let a caller say how an entity type becomes a
|
|
78
|
+
* URL path; nothing let it say how the answer comes back. So a vendor whose
|
|
79
|
+
* body is its own shape — Graph replies `{ value: [{ id, fields }] }`, not
|
|
80
|
+
* `{ items }` — could not use this class at all, and that was the other half
|
|
81
|
+
* of why every Graph engine forked. Absent, the built-in shapes below apply
|
|
82
|
+
* unchanged.
|
|
83
|
+
*/
|
|
84
|
+
readonly responseMapper?: (raw: unknown) => {
|
|
85
|
+
items: unknown[];
|
|
86
|
+
total?: number;
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* HTTP/REST connector for entity data operations.
|
|
91
|
+
* Maps entity CRUD operations to standard REST API endpoints.
|
|
92
|
+
*/
|
|
93
|
+
export declare class HttpEntityConnector implements EntityConnector {
|
|
94
|
+
readonly name: string;
|
|
95
|
+
readonly type: EntityConnectorType;
|
|
96
|
+
private readonly config;
|
|
97
|
+
constructor(name: string, config: HttpConnectorConfig);
|
|
98
|
+
create(entityType: EntityTypeId, data: Record<string, unknown>): Promise<ConnectorResult>;
|
|
99
|
+
read(entityType: EntityTypeId, instanceId: EntityInstanceId): Promise<ConnectorResult>;
|
|
100
|
+
update(entityType: EntityTypeId, instanceId: EntityInstanceId, data: Record<string, unknown>): Promise<ConnectorResult>;
|
|
101
|
+
delete(entityType: EntityTypeId, instanceId: EntityInstanceId): Promise<ConnectorResult>;
|
|
102
|
+
query(entityType: EntityTypeId, query: EntityQuery): Promise<ConnectorQueryResult>;
|
|
103
|
+
/**
|
|
104
|
+
* One number over the collection, computed by the server.
|
|
105
|
+
*
|
|
106
|
+
* `GET <base>/<type>/count[?filter=]` for a plain count and
|
|
107
|
+
* `GET <base>/<type>/aggregate?fn=&field=&filter=` for the rest — the two
|
|
108
|
+
* routes a host registers ahead of the read-one route.
|
|
109
|
+
* Constants (`defaultQueryParams`) and `entityPathMapper` apply as on
|
|
110
|
+
* every other read.
|
|
111
|
+
*/
|
|
112
|
+
aggregate(entityType: EntityTypeId, aggregate: EntityAggregate): Promise<ConnectorAggregateResult>;
|
|
113
|
+
private buildUrl;
|
|
114
|
+
private buildQueryParams;
|
|
115
|
+
private buildHeaders;
|
|
116
|
+
private resolveAuthHeader;
|
|
117
|
+
private request;
|
|
118
|
+
private sleep;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Create an HTTP entity connector
|
|
122
|
+
*/
|
|
123
|
+
export declare function createHttpConnector(name: string, config: HttpConnectorConfig): HttpEntityConnector;
|