@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,236 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SEO Capability Implementation
|
|
3
|
+
*
|
|
4
|
+
* Meta tag generation, JSON-LD structured data, and Open Graph tags
|
|
5
|
+
*
|
|
6
|
+
* All outputs are plain serializable objects suitable for SSR.
|
|
7
|
+
*
|
|
8
|
+
* @module @pwfabric/runtime/seo/generator
|
|
9
|
+
*/
|
|
10
|
+
// ============================================================
|
|
11
|
+
// DEFAULT SEO CAPABILITY
|
|
12
|
+
// ============================================================
|
|
13
|
+
/**
|
|
14
|
+
* Default SEO capability implementation
|
|
15
|
+
*/
|
|
16
|
+
export class DefaultSeoCapability {
|
|
17
|
+
defaults;
|
|
18
|
+
constructor(defaults) {
|
|
19
|
+
this.defaults = {
|
|
20
|
+
siteName: defaults?.siteName ?? '',
|
|
21
|
+
titleSeparator: defaults?.titleSeparator ?? ' | ',
|
|
22
|
+
defaultViewport: defaults?.defaultViewport ?? 'width=device-width, initial-scale=1',
|
|
23
|
+
defaultCharset: defaults?.defaultCharset ?? 'utf-8',
|
|
24
|
+
defaultRobots: defaults?.defaultRobots ?? 'index, follow',
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
generateMetaTags(input) {
|
|
28
|
+
const meta = [];
|
|
29
|
+
const link = [];
|
|
30
|
+
// Title (may include site name suffix)
|
|
31
|
+
let title = input.title;
|
|
32
|
+
if (this.defaults.siteName && !title.includes(this.defaults.siteName)) {
|
|
33
|
+
title = `${input.title}${this.defaults.titleSeparator}${this.defaults.siteName}`;
|
|
34
|
+
}
|
|
35
|
+
// Charset
|
|
36
|
+
const charset = input.charset ?? this.defaults.defaultCharset;
|
|
37
|
+
meta.push({ httpEquiv: 'Content-Type', content: `text/html; charset=${charset}` });
|
|
38
|
+
// Viewport
|
|
39
|
+
const viewport = input.viewport ?? this.defaults.defaultViewport;
|
|
40
|
+
meta.push({ name: 'viewport', content: viewport });
|
|
41
|
+
// Description
|
|
42
|
+
if (input.description) {
|
|
43
|
+
meta.push({ name: 'description', content: input.description });
|
|
44
|
+
}
|
|
45
|
+
// Keywords
|
|
46
|
+
if (input.keywords && input.keywords.length > 0) {
|
|
47
|
+
meta.push({ name: 'keywords', content: input.keywords.join(', ') });
|
|
48
|
+
}
|
|
49
|
+
// Author
|
|
50
|
+
if (input.author) {
|
|
51
|
+
meta.push({ name: 'author', content: input.author });
|
|
52
|
+
}
|
|
53
|
+
// Robots
|
|
54
|
+
const robots = input.robots ?? this.defaults.defaultRobots;
|
|
55
|
+
meta.push({ name: 'robots', content: robots });
|
|
56
|
+
// Canonical
|
|
57
|
+
if (input.canonical) {
|
|
58
|
+
link.push({ rel: 'canonical', href: input.canonical });
|
|
59
|
+
}
|
|
60
|
+
// Custom tags
|
|
61
|
+
if (input.custom) {
|
|
62
|
+
for (const customTag of input.custom) {
|
|
63
|
+
meta.push(customTag);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return { title, meta, link };
|
|
67
|
+
}
|
|
68
|
+
generateStructuredData(input) {
|
|
69
|
+
const data = {
|
|
70
|
+
'@context': 'https://schema.org',
|
|
71
|
+
'@type': input.type,
|
|
72
|
+
name: input.name,
|
|
73
|
+
};
|
|
74
|
+
if (input.description) {
|
|
75
|
+
data.description = input.description;
|
|
76
|
+
}
|
|
77
|
+
if (input.url) {
|
|
78
|
+
data.url = input.url;
|
|
79
|
+
}
|
|
80
|
+
if (input.image) {
|
|
81
|
+
data.image = input.image;
|
|
82
|
+
}
|
|
83
|
+
if (input.datePublished) {
|
|
84
|
+
data.datePublished = input.datePublished;
|
|
85
|
+
}
|
|
86
|
+
if (input.dateModified) {
|
|
87
|
+
data.dateModified = input.dateModified;
|
|
88
|
+
}
|
|
89
|
+
// Author
|
|
90
|
+
if (input.author) {
|
|
91
|
+
data.author = {
|
|
92
|
+
'@type': input.author.type,
|
|
93
|
+
name: input.author.name,
|
|
94
|
+
...(input.author.url ? { url: input.author.url } : {}),
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
// Publisher
|
|
98
|
+
if (input.publisher) {
|
|
99
|
+
const publisher = {
|
|
100
|
+
'@type': 'Organization',
|
|
101
|
+
name: input.publisher.name,
|
|
102
|
+
};
|
|
103
|
+
if (input.publisher.url) {
|
|
104
|
+
publisher.url = input.publisher.url;
|
|
105
|
+
}
|
|
106
|
+
if (input.publisher.logo) {
|
|
107
|
+
publisher.logo = {
|
|
108
|
+
'@type': 'ImageObject',
|
|
109
|
+
url: input.publisher.logo,
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
data.publisher = publisher;
|
|
113
|
+
}
|
|
114
|
+
// Breadcrumbs
|
|
115
|
+
if (input.breadcrumbs && input.breadcrumbs.length > 0) {
|
|
116
|
+
data['@type'] = 'BreadcrumbList';
|
|
117
|
+
data.itemListElement = input.breadcrumbs.map((crumb, index) => ({
|
|
118
|
+
'@type': 'ListItem',
|
|
119
|
+
position: index + 1,
|
|
120
|
+
name: crumb.name,
|
|
121
|
+
item: crumb.url,
|
|
122
|
+
}));
|
|
123
|
+
}
|
|
124
|
+
// FAQ
|
|
125
|
+
if (input.faq && input.faq.length > 0) {
|
|
126
|
+
data['@type'] = 'FAQPage';
|
|
127
|
+
data.mainEntity = input.faq.map((item) => ({
|
|
128
|
+
'@type': 'Question',
|
|
129
|
+
name: item.question,
|
|
130
|
+
acceptedAnswer: {
|
|
131
|
+
'@type': 'Answer',
|
|
132
|
+
text: item.answer,
|
|
133
|
+
},
|
|
134
|
+
}));
|
|
135
|
+
}
|
|
136
|
+
// Custom properties
|
|
137
|
+
if (input.custom) {
|
|
138
|
+
for (const [key, value] of Object.entries(input.custom)) {
|
|
139
|
+
if (key !== '@context' && key !== '@type') {
|
|
140
|
+
data[key] = value;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
const script = JSON.stringify(data);
|
|
145
|
+
return { script, data };
|
|
146
|
+
}
|
|
147
|
+
generateOpenGraph(input) {
|
|
148
|
+
const meta = [];
|
|
149
|
+
// Required OG tags
|
|
150
|
+
meta.push({ property: 'og:title', content: input.title });
|
|
151
|
+
meta.push({ property: 'og:type', content: input.type ?? 'website' });
|
|
152
|
+
// Optional OG tags
|
|
153
|
+
if (input.description) {
|
|
154
|
+
meta.push({ property: 'og:description', content: input.description });
|
|
155
|
+
}
|
|
156
|
+
if (input.url) {
|
|
157
|
+
meta.push({ property: 'og:url', content: input.url });
|
|
158
|
+
}
|
|
159
|
+
if (input.image) {
|
|
160
|
+
meta.push({ property: 'og:image', content: input.image });
|
|
161
|
+
if (input.imageWidth) {
|
|
162
|
+
meta.push({ property: 'og:image:width', content: String(input.imageWidth) });
|
|
163
|
+
}
|
|
164
|
+
if (input.imageHeight) {
|
|
165
|
+
meta.push({ property: 'og:image:height', content: String(input.imageHeight) });
|
|
166
|
+
}
|
|
167
|
+
if (input.imageAlt) {
|
|
168
|
+
meta.push({ property: 'og:image:alt', content: input.imageAlt });
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
if (input.siteName) {
|
|
172
|
+
meta.push({ property: 'og:site_name', content: input.siteName });
|
|
173
|
+
}
|
|
174
|
+
if (input.locale) {
|
|
175
|
+
meta.push({ property: 'og:locale', content: input.locale });
|
|
176
|
+
}
|
|
177
|
+
if (input.localeAlternates) {
|
|
178
|
+
for (const alt of input.localeAlternates) {
|
|
179
|
+
meta.push({ property: 'og:locale:alternate', content: alt });
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
// Article-specific tags
|
|
183
|
+
if (input.article) {
|
|
184
|
+
if (input.article.publishedTime) {
|
|
185
|
+
meta.push({ property: 'article:published_time', content: input.article.publishedTime });
|
|
186
|
+
}
|
|
187
|
+
if (input.article.modifiedTime) {
|
|
188
|
+
meta.push({ property: 'article:modified_time', content: input.article.modifiedTime });
|
|
189
|
+
}
|
|
190
|
+
if (input.article.author) {
|
|
191
|
+
meta.push({ property: 'article:author', content: input.article.author });
|
|
192
|
+
}
|
|
193
|
+
if (input.article.section) {
|
|
194
|
+
meta.push({ property: 'article:section', content: input.article.section });
|
|
195
|
+
}
|
|
196
|
+
if (input.article.tags) {
|
|
197
|
+
for (const tag of input.article.tags) {
|
|
198
|
+
meta.push({ property: 'article:tag', content: tag });
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
// Twitter card
|
|
203
|
+
if (input.twitter) {
|
|
204
|
+
meta.push({ name: 'twitter:card', content: input.twitter.card ?? 'summary' });
|
|
205
|
+
if (input.twitter.site) {
|
|
206
|
+
meta.push({ name: 'twitter:site', content: input.twitter.site });
|
|
207
|
+
}
|
|
208
|
+
if (input.twitter.creator) {
|
|
209
|
+
meta.push({ name: 'twitter:creator', content: input.twitter.creator });
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
return { meta };
|
|
213
|
+
}
|
|
214
|
+
generateAll(config) {
|
|
215
|
+
const output = {
|
|
216
|
+
metaTags: this.generateMetaTags(config.meta),
|
|
217
|
+
};
|
|
218
|
+
if (config.structuredData) {
|
|
219
|
+
output.structuredData = this.generateStructuredData(config.structuredData);
|
|
220
|
+
}
|
|
221
|
+
if (config.openGraph) {
|
|
222
|
+
output.openGraph = this.generateOpenGraph(config.openGraph);
|
|
223
|
+
}
|
|
224
|
+
return output;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
// ============================================================
|
|
228
|
+
// FACTORY FUNCTION
|
|
229
|
+
// ============================================================
|
|
230
|
+
/**
|
|
231
|
+
* Create an SEO capability instance
|
|
232
|
+
*/
|
|
233
|
+
export function createSeoCapability(defaults) {
|
|
234
|
+
return new DefaultSeoCapability(defaults);
|
|
235
|
+
}
|
|
236
|
+
//# sourceMappingURL=generator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generator.js","sourceRoot":"","sources":["../../src/seo/generator.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * SEO Capability Implementation\n *\n * Meta tag generation, JSON-LD structured data, and Open Graph tags\n *\n * All outputs are plain serializable objects suitable for SSR.\n *\n * @module @pwfabric/runtime/seo/generator\n */\n\nimport type {\n SeoCapability,\n MetaTagInput,\n MetaTagOutput,\n MetaTag,\n LinkTag,\n StructuredDataInput,\n StructuredDataOutput,\n OpenGraphInput,\n OpenGraphOutput,\n SeoConfig,\n SeoOutput,\n} from './types.js'\n\n// ============================================================\n// DEFAULT SEO CAPABILITY\n// ============================================================\n\n/**\n * Default SEO capability implementation\n */\nexport class DefaultSeoCapability implements SeoCapability {\n private readonly defaults: SeoDefaults\n\n constructor(defaults?: Partial<SeoDefaults>) {\n this.defaults = {\n siteName: defaults?.siteName ?? '',\n titleSeparator: defaults?.titleSeparator ?? ' | ',\n defaultViewport: defaults?.defaultViewport ?? 'width=device-width, initial-scale=1',\n defaultCharset: defaults?.defaultCharset ?? 'utf-8',\n defaultRobots: defaults?.defaultRobots ?? 'index, follow',\n }\n }\n\n generateMetaTags(input: MetaTagInput): MetaTagOutput {\n const meta: MetaTag[] = []\n const link: LinkTag[] = []\n\n // Title (may include site name suffix)\n let title = input.title\n if (this.defaults.siteName && !title.includes(this.defaults.siteName)) {\n title = `${input.title}${this.defaults.titleSeparator}${this.defaults.siteName}`\n }\n\n // Charset\n const charset = input.charset ?? this.defaults.defaultCharset\n meta.push({ httpEquiv: 'Content-Type', content: `text/html; charset=${charset}` })\n\n // Viewport\n const viewport = input.viewport ?? this.defaults.defaultViewport\n meta.push({ name: 'viewport', content: viewport })\n\n // Description\n if (input.description) {\n meta.push({ name: 'description', content: input.description })\n }\n\n // Keywords\n if (input.keywords && input.keywords.length > 0) {\n meta.push({ name: 'keywords', content: input.keywords.join(', ') })\n }\n\n // Author\n if (input.author) {\n meta.push({ name: 'author', content: input.author })\n }\n\n // Robots\n const robots = input.robots ?? this.defaults.defaultRobots\n meta.push({ name: 'robots', content: robots })\n\n // Canonical\n if (input.canonical) {\n link.push({ rel: 'canonical', href: input.canonical })\n }\n\n // Custom tags\n if (input.custom) {\n for (const customTag of input.custom) {\n meta.push(customTag)\n }\n }\n\n return { title, meta, link }\n }\n\n generateStructuredData(input: StructuredDataInput): StructuredDataOutput {\n const data: Record<string, unknown> = {\n '@context': 'https://schema.org',\n '@type': input.type,\n name: input.name,\n }\n\n if (input.description) {\n data.description = input.description\n }\n\n if (input.url) {\n data.url = input.url\n }\n\n if (input.image) {\n data.image = input.image\n }\n\n if (input.datePublished) {\n data.datePublished = input.datePublished\n }\n\n if (input.dateModified) {\n data.dateModified = input.dateModified\n }\n\n // Author\n if (input.author) {\n data.author = {\n '@type': input.author.type,\n name: input.author.name,\n ...(input.author.url ? { url: input.author.url } : {}),\n }\n }\n\n // Publisher\n if (input.publisher) {\n const publisher: Record<string, unknown> = {\n '@type': 'Organization',\n name: input.publisher.name,\n }\n if (input.publisher.url) {\n publisher.url = input.publisher.url\n }\n if (input.publisher.logo) {\n publisher.logo = {\n '@type': 'ImageObject',\n url: input.publisher.logo,\n }\n }\n data.publisher = publisher\n }\n\n // Breadcrumbs\n if (input.breadcrumbs && input.breadcrumbs.length > 0) {\n data['@type'] = 'BreadcrumbList'\n data.itemListElement = input.breadcrumbs.map((crumb, index) => ({\n '@type': 'ListItem',\n position: index + 1,\n name: crumb.name,\n item: crumb.url,\n }))\n }\n\n // FAQ\n if (input.faq && input.faq.length > 0) {\n data['@type'] = 'FAQPage'\n data.mainEntity = input.faq.map((item) => ({\n '@type': 'Question',\n name: item.question,\n acceptedAnswer: {\n '@type': 'Answer',\n text: item.answer,\n },\n }))\n }\n\n // Custom properties\n if (input.custom) {\n for (const [key, value] of Object.entries(input.custom)) {\n if (key !== '@context' && key !== '@type') {\n data[key] = value\n }\n }\n }\n\n const script = JSON.stringify(data)\n\n return { script, data }\n }\n\n generateOpenGraph(input: OpenGraphInput): OpenGraphOutput {\n const meta: MetaTag[] = []\n\n // Required OG tags\n meta.push({ property: 'og:title', content: input.title })\n meta.push({ property: 'og:type', content: input.type ?? 'website' })\n\n // Optional OG tags\n if (input.description) {\n meta.push({ property: 'og:description', content: input.description })\n }\n\n if (input.url) {\n meta.push({ property: 'og:url', content: input.url })\n }\n\n if (input.image) {\n meta.push({ property: 'og:image', content: input.image })\n if (input.imageWidth) {\n meta.push({ property: 'og:image:width', content: String(input.imageWidth) })\n }\n if (input.imageHeight) {\n meta.push({ property: 'og:image:height', content: String(input.imageHeight) })\n }\n if (input.imageAlt) {\n meta.push({ property: 'og:image:alt', content: input.imageAlt })\n }\n }\n\n if (input.siteName) {\n meta.push({ property: 'og:site_name', content: input.siteName })\n }\n\n if (input.locale) {\n meta.push({ property: 'og:locale', content: input.locale })\n }\n\n if (input.localeAlternates) {\n for (const alt of input.localeAlternates) {\n meta.push({ property: 'og:locale:alternate', content: alt })\n }\n }\n\n // Article-specific tags\n if (input.article) {\n if (input.article.publishedTime) {\n meta.push({ property: 'article:published_time', content: input.article.publishedTime })\n }\n if (input.article.modifiedTime) {\n meta.push({ property: 'article:modified_time', content: input.article.modifiedTime })\n }\n if (input.article.author) {\n meta.push({ property: 'article:author', content: input.article.author })\n }\n if (input.article.section) {\n meta.push({ property: 'article:section', content: input.article.section })\n }\n if (input.article.tags) {\n for (const tag of input.article.tags) {\n meta.push({ property: 'article:tag', content: tag })\n }\n }\n }\n\n // Twitter card\n if (input.twitter) {\n meta.push({ name: 'twitter:card', content: input.twitter.card ?? 'summary' })\n if (input.twitter.site) {\n meta.push({ name: 'twitter:site', content: input.twitter.site })\n }\n if (input.twitter.creator) {\n meta.push({ name: 'twitter:creator', content: input.twitter.creator })\n }\n }\n\n return { meta }\n }\n\n generateAll(config: SeoConfig): SeoOutput {\n const output: {\n metaTags: MetaTagOutput\n structuredData?: StructuredDataOutput\n openGraph?: OpenGraphOutput\n } = {\n metaTags: this.generateMetaTags(config.meta),\n }\n\n if (config.structuredData) {\n output.structuredData = this.generateStructuredData(config.structuredData)\n }\n\n if (config.openGraph) {\n output.openGraph = this.generateOpenGraph(config.openGraph)\n }\n\n return output\n }\n}\n\n// ============================================================\n// DEFAULTS\n// ============================================================\n\ninterface SeoDefaults {\n siteName: string\n titleSeparator: string\n defaultViewport: string\n defaultCharset: string\n defaultRobots: string\n}\n\n// ============================================================\n// FACTORY FUNCTION\n// ============================================================\n\n/**\n * Create an SEO capability instance\n */\nexport function createSeoCapability(defaults?: {\n siteName?: string\n titleSeparator?: string\n defaultViewport?: string\n defaultCharset?: string\n defaultRobots?: string\n}): SeoCapability {\n return new DefaultSeoCapability(defaults)\n}\n"]}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SEO Capability Module
|
|
3
|
+
*
|
|
4
|
+
* Meta tag generation, structured data, and Open Graph tags
|
|
5
|
+
*
|
|
6
|
+
* Exports:
|
|
7
|
+
* - Types: MetaTagInput, StructuredDataInput, OpenGraphInput, SeoCapability, etc.
|
|
8
|
+
* - Implementations: DefaultSeoCapability
|
|
9
|
+
* - Factory functions: createSeoCapability
|
|
10
|
+
*
|
|
11
|
+
* @module @pwfabric/runtime/seo
|
|
12
|
+
*/
|
|
13
|
+
export type { MetaTag, MetaTagInput, MetaTagOutput, LinkTag, StructuredDataType, StructuredDataInput, PersonInput, OrganizationInput, BreadcrumbInput, FaqInput, StructuredDataOutput, OpenGraphType, OpenGraphInput, OpenGraphArticle, TwitterCardInput, OpenGraphOutput, SeoCapability, SeoConfig, SeoOutput, } from './types.js';
|
|
14
|
+
export { DefaultSeoCapability, createSeoCapability } from './generator.js';
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SEO Capability Module
|
|
3
|
+
*
|
|
4
|
+
* Meta tag generation, structured data, and Open Graph tags
|
|
5
|
+
*
|
|
6
|
+
* Exports:
|
|
7
|
+
* - Types: MetaTagInput, StructuredDataInput, OpenGraphInput, SeoCapability, etc.
|
|
8
|
+
* - Implementations: DefaultSeoCapability
|
|
9
|
+
* - Factory functions: createSeoCapability
|
|
10
|
+
*
|
|
11
|
+
* @module @pwfabric/runtime/seo
|
|
12
|
+
*/
|
|
13
|
+
// Implementations
|
|
14
|
+
export { DefaultSeoCapability, createSeoCapability } from './generator.js';
|
|
15
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/seo/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAyBH,kBAAkB;AAClB,OAAO,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAA","sourcesContent":["/**\n * SEO Capability Module\n *\n * Meta tag generation, structured data, and Open Graph tags\n *\n * Exports:\n * - Types: MetaTagInput, StructuredDataInput, OpenGraphInput, SeoCapability, etc.\n * - Implementations: DefaultSeoCapability\n * - Factory functions: createSeoCapability\n *\n * @module @pwfabric/runtime/seo\n */\n\n// Types\nexport type {\n MetaTag,\n MetaTagInput,\n MetaTagOutput,\n LinkTag,\n StructuredDataType,\n StructuredDataInput,\n PersonInput,\n OrganizationInput,\n BreadcrumbInput,\n FaqInput,\n StructuredDataOutput,\n OpenGraphType,\n OpenGraphInput,\n OpenGraphArticle,\n TwitterCardInput,\n OpenGraphOutput,\n SeoCapability,\n SeoConfig,\n SeoOutput,\n} from './types.js'\n\n// Implementations\nexport { DefaultSeoCapability, createSeoCapability } from './generator.js'\n"]}
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SEO Capability Types
|
|
3
|
+
*
|
|
4
|
+
* Meta tag generation, structured data, and Open Graph tags
|
|
5
|
+
*
|
|
6
|
+
* @module @pwfabric/runtime/seo/types
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Meta tag definition
|
|
10
|
+
*/
|
|
11
|
+
export interface MetaTag {
|
|
12
|
+
readonly name?: string;
|
|
13
|
+
readonly property?: string;
|
|
14
|
+
readonly httpEquiv?: string;
|
|
15
|
+
readonly content: string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Input for generating meta tags
|
|
19
|
+
*/
|
|
20
|
+
export interface MetaTagInput {
|
|
21
|
+
readonly title: string;
|
|
22
|
+
readonly description?: string;
|
|
23
|
+
readonly keywords?: readonly string[];
|
|
24
|
+
readonly author?: string;
|
|
25
|
+
readonly robots?: string;
|
|
26
|
+
readonly canonical?: string;
|
|
27
|
+
readonly viewport?: string;
|
|
28
|
+
readonly charset?: string;
|
|
29
|
+
readonly custom?: readonly MetaTag[];
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Generated meta tag output (serializable for SSR)
|
|
33
|
+
*/
|
|
34
|
+
export interface MetaTagOutput {
|
|
35
|
+
readonly title: string;
|
|
36
|
+
readonly meta: readonly MetaTag[];
|
|
37
|
+
readonly link: readonly LinkTag[];
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Link tag definition
|
|
41
|
+
*/
|
|
42
|
+
export interface LinkTag {
|
|
43
|
+
readonly rel: string;
|
|
44
|
+
readonly href: string;
|
|
45
|
+
readonly type?: string;
|
|
46
|
+
readonly hreflang?: string;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* JSON-LD structured data type
|
|
50
|
+
*/
|
|
51
|
+
export type StructuredDataType = 'WebSite' | 'WebPage' | 'Article' | 'Organization' | 'Person' | 'BreadcrumbList' | 'FAQPage' | 'Product' | 'LocalBusiness' | string;
|
|
52
|
+
/**
|
|
53
|
+
* Input for generating structured data
|
|
54
|
+
*/
|
|
55
|
+
export interface StructuredDataInput {
|
|
56
|
+
readonly type: StructuredDataType;
|
|
57
|
+
readonly name: string;
|
|
58
|
+
readonly description?: string;
|
|
59
|
+
readonly url?: string;
|
|
60
|
+
readonly image?: string | readonly string[];
|
|
61
|
+
readonly datePublished?: string;
|
|
62
|
+
readonly dateModified?: string;
|
|
63
|
+
readonly author?: PersonInput | OrganizationInput;
|
|
64
|
+
readonly publisher?: OrganizationInput;
|
|
65
|
+
readonly breadcrumbs?: readonly BreadcrumbInput[];
|
|
66
|
+
readonly faq?: readonly FaqInput[];
|
|
67
|
+
readonly custom?: Readonly<Record<string, unknown>>;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Person input for structured data
|
|
71
|
+
*/
|
|
72
|
+
export interface PersonInput {
|
|
73
|
+
readonly type: 'Person';
|
|
74
|
+
readonly name: string;
|
|
75
|
+
readonly url?: string;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Organization input for structured data
|
|
79
|
+
*/
|
|
80
|
+
export interface OrganizationInput {
|
|
81
|
+
readonly type: 'Organization';
|
|
82
|
+
readonly name: string;
|
|
83
|
+
readonly url?: string;
|
|
84
|
+
readonly logo?: string;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Breadcrumb input
|
|
88
|
+
*/
|
|
89
|
+
export interface BreadcrumbInput {
|
|
90
|
+
readonly name: string;
|
|
91
|
+
readonly url: string;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* FAQ input
|
|
95
|
+
*/
|
|
96
|
+
export interface FaqInput {
|
|
97
|
+
readonly question: string;
|
|
98
|
+
readonly answer: string;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Generated JSON-LD output (serializable)
|
|
102
|
+
*/
|
|
103
|
+
export interface StructuredDataOutput {
|
|
104
|
+
readonly script: string;
|
|
105
|
+
readonly data: Readonly<Record<string, unknown>>;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Open Graph type
|
|
109
|
+
*/
|
|
110
|
+
export type OpenGraphType = 'website' | 'article' | 'profile' | 'video' | 'music' | string;
|
|
111
|
+
/**
|
|
112
|
+
* Input for generating Open Graph tags
|
|
113
|
+
*/
|
|
114
|
+
export interface OpenGraphInput {
|
|
115
|
+
readonly title: string;
|
|
116
|
+
readonly description?: string;
|
|
117
|
+
readonly url?: string;
|
|
118
|
+
readonly image?: string;
|
|
119
|
+
readonly imageWidth?: number;
|
|
120
|
+
readonly imageHeight?: number;
|
|
121
|
+
readonly imageAlt?: string;
|
|
122
|
+
readonly type?: OpenGraphType;
|
|
123
|
+
readonly siteName?: string;
|
|
124
|
+
readonly locale?: string;
|
|
125
|
+
readonly localeAlternates?: readonly string[];
|
|
126
|
+
readonly article?: OpenGraphArticle;
|
|
127
|
+
readonly twitter?: TwitterCardInput;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Article-specific Open Graph data
|
|
131
|
+
*/
|
|
132
|
+
export interface OpenGraphArticle {
|
|
133
|
+
readonly publishedTime?: string;
|
|
134
|
+
readonly modifiedTime?: string;
|
|
135
|
+
readonly author?: string;
|
|
136
|
+
readonly section?: string;
|
|
137
|
+
readonly tags?: readonly string[];
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Twitter card input
|
|
141
|
+
*/
|
|
142
|
+
export interface TwitterCardInput {
|
|
143
|
+
readonly card?: 'summary' | 'summary_large_image' | 'app' | 'player';
|
|
144
|
+
readonly site?: string;
|
|
145
|
+
readonly creator?: string;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Generated Open Graph output (serializable)
|
|
149
|
+
*/
|
|
150
|
+
export interface OpenGraphOutput {
|
|
151
|
+
readonly meta: readonly MetaTag[];
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* SEO capability interface for generating SEO-related markup
|
|
155
|
+
*/
|
|
156
|
+
export interface SeoCapability {
|
|
157
|
+
/** Generate meta tags from input */
|
|
158
|
+
generateMetaTags(input: MetaTagInput): MetaTagOutput;
|
|
159
|
+
/** Generate JSON-LD structured data */
|
|
160
|
+
generateStructuredData(input: StructuredDataInput): StructuredDataOutput;
|
|
161
|
+
/** Generate Open Graph (and Twitter card) tags */
|
|
162
|
+
generateOpenGraph(input: OpenGraphInput): OpenGraphOutput;
|
|
163
|
+
/** Combine all SEO outputs into a single serializable object */
|
|
164
|
+
generateAll(config: SeoConfig): SeoOutput;
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Combined SEO configuration
|
|
168
|
+
*/
|
|
169
|
+
export interface SeoConfig {
|
|
170
|
+
readonly meta: MetaTagInput;
|
|
171
|
+
readonly structuredData?: StructuredDataInput;
|
|
172
|
+
readonly openGraph?: OpenGraphInput;
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Combined SEO output (serializable for SSR)
|
|
176
|
+
*/
|
|
177
|
+
export interface SeoOutput {
|
|
178
|
+
readonly metaTags: MetaTagOutput;
|
|
179
|
+
readonly structuredData?: StructuredDataOutput;
|
|
180
|
+
readonly openGraph?: OpenGraphOutput;
|
|
181
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/seo/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG","sourcesContent":["/**\n * SEO Capability Types\n *\n * Meta tag generation, structured data, and Open Graph tags\n *\n * @module @pwfabric/runtime/seo/types\n */\n\n// ============================================================\n// META TAGS\n// ============================================================\n\n/**\n * Meta tag definition\n */\nexport interface MetaTag {\n readonly name?: string\n readonly property?: string\n readonly httpEquiv?: string\n readonly content: string\n}\n\n/**\n * Input for generating meta tags\n */\nexport interface MetaTagInput {\n readonly title: string\n readonly description?: string\n readonly keywords?: readonly string[]\n readonly author?: string\n readonly robots?: string\n readonly canonical?: string\n readonly viewport?: string\n readonly charset?: string\n readonly custom?: readonly MetaTag[]\n}\n\n/**\n * Generated meta tag output (serializable for SSR)\n */\nexport interface MetaTagOutput {\n readonly title: string\n readonly meta: readonly MetaTag[]\n readonly link: readonly LinkTag[]\n}\n\n/**\n * Link tag definition\n */\nexport interface LinkTag {\n readonly rel: string\n readonly href: string\n readonly type?: string\n readonly hreflang?: string\n}\n\n// ============================================================\n// STRUCTURED DATA (JSON-LD)\n// ============================================================\n\n/**\n * JSON-LD structured data type\n */\nexport type StructuredDataType =\n | 'WebSite'\n | 'WebPage'\n | 'Article'\n | 'Organization'\n | 'Person'\n | 'BreadcrumbList'\n | 'FAQPage'\n | 'Product'\n | 'LocalBusiness'\n | string\n\n/**\n * Input for generating structured data\n */\nexport interface StructuredDataInput {\n readonly type: StructuredDataType\n readonly name: string\n readonly description?: string\n readonly url?: string\n readonly image?: string | readonly string[]\n readonly datePublished?: string\n readonly dateModified?: string\n readonly author?: PersonInput | OrganizationInput\n readonly publisher?: OrganizationInput\n readonly breadcrumbs?: readonly BreadcrumbInput[]\n readonly faq?: readonly FaqInput[]\n readonly custom?: Readonly<Record<string, unknown>>\n}\n\n/**\n * Person input for structured data\n */\nexport interface PersonInput {\n readonly type: 'Person'\n readonly name: string\n readonly url?: string\n}\n\n/**\n * Organization input for structured data\n */\nexport interface OrganizationInput {\n readonly type: 'Organization'\n readonly name: string\n readonly url?: string\n readonly logo?: string\n}\n\n/**\n * Breadcrumb input\n */\nexport interface BreadcrumbInput {\n readonly name: string\n readonly url: string\n}\n\n/**\n * FAQ input\n */\nexport interface FaqInput {\n readonly question: string\n readonly answer: string\n}\n\n/**\n * Generated JSON-LD output (serializable)\n */\nexport interface StructuredDataOutput {\n readonly script: string\n readonly data: Readonly<Record<string, unknown>>\n}\n\n// ============================================================\n// OPEN GRAPH\n// ============================================================\n\n/**\n * Open Graph type\n */\nexport type OpenGraphType = 'website' | 'article' | 'profile' | 'video' | 'music' | string\n\n/**\n * Input for generating Open Graph tags\n */\nexport interface OpenGraphInput {\n readonly title: string\n readonly description?: string\n readonly url?: string\n readonly image?: string\n readonly imageWidth?: number\n readonly imageHeight?: number\n readonly imageAlt?: string\n readonly type?: OpenGraphType\n readonly siteName?: string\n readonly locale?: string\n readonly localeAlternates?: readonly string[]\n readonly article?: OpenGraphArticle\n readonly twitter?: TwitterCardInput\n}\n\n/**\n * Article-specific Open Graph data\n */\nexport interface OpenGraphArticle {\n readonly publishedTime?: string\n readonly modifiedTime?: string\n readonly author?: string\n readonly section?: string\n readonly tags?: readonly string[]\n}\n\n/**\n * Twitter card input\n */\nexport interface TwitterCardInput {\n readonly card?: 'summary' | 'summary_large_image' | 'app' | 'player'\n readonly site?: string\n readonly creator?: string\n}\n\n/**\n * Generated Open Graph output (serializable)\n */\nexport interface OpenGraphOutput {\n readonly meta: readonly MetaTag[]\n}\n\n// ============================================================\n// SEO CAPABILITY INTERFACE\n// ============================================================\n\n/**\n * SEO capability interface for generating SEO-related markup\n */\nexport interface SeoCapability {\n /** Generate meta tags from input */\n generateMetaTags(input: MetaTagInput): MetaTagOutput\n\n /** Generate JSON-LD structured data */\n generateStructuredData(input: StructuredDataInput): StructuredDataOutput\n\n /** Generate Open Graph (and Twitter card) tags */\n generateOpenGraph(input: OpenGraphInput): OpenGraphOutput\n\n /** Combine all SEO outputs into a single serializable object */\n generateAll(config: SeoConfig): SeoOutput\n}\n\n/**\n * Combined SEO configuration\n */\nexport interface SeoConfig {\n readonly meta: MetaTagInput\n readonly structuredData?: StructuredDataInput\n readonly openGraph?: OpenGraphInput\n}\n\n/**\n * Combined SEO output (serializable for SSR)\n */\nexport interface SeoOutput {\n readonly metaTags: MetaTagOutput\n readonly structuredData?: StructuredDataOutput\n readonly openGraph?: OpenGraphOutput\n}\n"]}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* State Management Module
|
|
3
|
+
*
|
|
4
|
+
* State management capability for surfaces
|
|
5
|
+
*
|
|
6
|
+
* Exports:
|
|
7
|
+
* - Types: StateStore, SurfaceStateManager, StateChangeEvent, etc.
|
|
8
|
+
* - Implementations: InMemoryStateStore, DefaultSurfaceStateManager
|
|
9
|
+
* - Factory functions: createStateStore, createSurfaceStateManager
|
|
10
|
+
*
|
|
11
|
+
* @module @pwfabric/runtime/state
|
|
12
|
+
*/
|
|
13
|
+
export type { StateStore, SurfaceStateManager, StateChangeEvent, StateChangeListener, StateStoreConfig, StateHistoryEntry, } from './types.js';
|
|
14
|
+
export { InMemoryStateStore, createStateStore } from './store.js';
|
|
15
|
+
export { DefaultSurfaceStateManager, createSurfaceStateManager } from './manager.js';
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* State Management Module
|
|
3
|
+
*
|
|
4
|
+
* State management capability for surfaces
|
|
5
|
+
*
|
|
6
|
+
* Exports:
|
|
7
|
+
* - Types: StateStore, SurfaceStateManager, StateChangeEvent, etc.
|
|
8
|
+
* - Implementations: InMemoryStateStore, DefaultSurfaceStateManager
|
|
9
|
+
* - Factory functions: createStateStore, createSurfaceStateManager
|
|
10
|
+
*
|
|
11
|
+
* @module @pwfabric/runtime/state
|
|
12
|
+
*/
|
|
13
|
+
// Implementations
|
|
14
|
+
export { InMemoryStateStore, createStateStore } from './store.js';
|
|
15
|
+
export { DefaultSurfaceStateManager, createSurfaceStateManager } from './manager.js';
|
|
16
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/state/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAYH,kBAAkB;AAClB,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AACjE,OAAO,EAAE,0BAA0B,EAAE,yBAAyB,EAAE,MAAM,cAAc,CAAA","sourcesContent":["/**\n * State Management Module\n *\n * State management capability for surfaces\n *\n * Exports:\n * - Types: StateStore, SurfaceStateManager, StateChangeEvent, etc.\n * - Implementations: InMemoryStateStore, DefaultSurfaceStateManager\n * - Factory functions: createStateStore, createSurfaceStateManager\n *\n * @module @pwfabric/runtime/state\n */\n\n// Types\nexport type {\n StateStore,\n SurfaceStateManager,\n StateChangeEvent,\n StateChangeListener,\n StateStoreConfig,\n StateHistoryEntry,\n} from './types.js'\n\n// Implementations\nexport { InMemoryStateStore, createStateStore } from './store.js'\nexport { DefaultSurfaceStateManager, createSurfaceStateManager } from './manager.js'\n"]}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Surface State Manager
|
|
3
|
+
*
|
|
4
|
+
* Manager for surface-scoped state stores
|
|
5
|
+
*
|
|
6
|
+
* @module @pwfabric/runtime/state/manager
|
|
7
|
+
*/
|
|
8
|
+
import type { SurfaceStateManager, StateStore, StateStoreConfig } from './types.js';
|
|
9
|
+
/**
|
|
10
|
+
* Default implementation of SurfaceStateManager
|
|
11
|
+
* Manages multiple state stores, one per surface
|
|
12
|
+
*/
|
|
13
|
+
export declare class DefaultSurfaceStateManager implements SurfaceStateManager {
|
|
14
|
+
private readonly stores;
|
|
15
|
+
private readonly defaultConfig;
|
|
16
|
+
constructor(defaultConfig?: StateStoreConfig);
|
|
17
|
+
createStore<T>(surfaceId: string, initialState: T): StateStore<T>;
|
|
18
|
+
getStore<T>(surfaceId: string): StateStore<T> | undefined;
|
|
19
|
+
hasStore(surfaceId: string): boolean;
|
|
20
|
+
destroyStore(surfaceId: string): void;
|
|
21
|
+
destroyAll(): void;
|
|
22
|
+
getSurfaceIds(): string[];
|
|
23
|
+
/**
|
|
24
|
+
* Get or create a store for a surface
|
|
25
|
+
* Creates a new store with empty initial state if it doesn't exist
|
|
26
|
+
*/
|
|
27
|
+
getOrCreateStore<T>(surfaceId: string, initialState?: T): StateStore<T>;
|
|
28
|
+
private normalizeInitialState;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Create a surface state manager
|
|
32
|
+
*/
|
|
33
|
+
export declare function createSurfaceStateManager(config?: StateStoreConfig): SurfaceStateManager;
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Surface State Manager
|
|
3
|
+
*
|
|
4
|
+
* Manager for surface-scoped state stores
|
|
5
|
+
*
|
|
6
|
+
* @module @pwfabric/runtime/state/manager
|
|
7
|
+
*/
|
|
8
|
+
import { InMemoryStateStore } from './store.js';
|
|
9
|
+
// ============================================================
|
|
10
|
+
// DEFAULT SURFACE STATE MANAGER
|
|
11
|
+
// ============================================================
|
|
12
|
+
/**
|
|
13
|
+
* Default implementation of SurfaceStateManager
|
|
14
|
+
* Manages multiple state stores, one per surface
|
|
15
|
+
*/
|
|
16
|
+
export class DefaultSurfaceStateManager {
|
|
17
|
+
stores = new Map();
|
|
18
|
+
defaultConfig;
|
|
19
|
+
constructor(defaultConfig = {}) {
|
|
20
|
+
this.defaultConfig = defaultConfig;
|
|
21
|
+
}
|
|
22
|
+
createStore(surfaceId, initialState) {
|
|
23
|
+
// If store already exists, throw error to prevent accidental overwrites
|
|
24
|
+
if (this.stores.has(surfaceId)) {
|
|
25
|
+
throw new Error(`State store already exists for surface: ${surfaceId}`);
|
|
26
|
+
}
|
|
27
|
+
// Convert single value initialState to object format if needed
|
|
28
|
+
const stateObject = this.normalizeInitialState(initialState);
|
|
29
|
+
const store = new InMemoryStateStore(stateObject, this.defaultConfig);
|
|
30
|
+
this.stores.set(surfaceId, store);
|
|
31
|
+
return store;
|
|
32
|
+
}
|
|
33
|
+
getStore(surfaceId) {
|
|
34
|
+
return this.stores.get(surfaceId);
|
|
35
|
+
}
|
|
36
|
+
hasStore(surfaceId) {
|
|
37
|
+
return this.stores.has(surfaceId);
|
|
38
|
+
}
|
|
39
|
+
destroyStore(surfaceId) {
|
|
40
|
+
const store = this.stores.get(surfaceId);
|
|
41
|
+
if (store) {
|
|
42
|
+
store.clear();
|
|
43
|
+
this.stores.delete(surfaceId);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
destroyAll() {
|
|
47
|
+
for (const store of this.stores.values()) {
|
|
48
|
+
store.clear();
|
|
49
|
+
}
|
|
50
|
+
this.stores.clear();
|
|
51
|
+
}
|
|
52
|
+
getSurfaceIds() {
|
|
53
|
+
return Array.from(this.stores.keys());
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Get or create a store for a surface
|
|
57
|
+
* Creates a new store with empty initial state if it doesn't exist
|
|
58
|
+
*/
|
|
59
|
+
getOrCreateStore(surfaceId, initialState) {
|
|
60
|
+
const existing = this.getStore(surfaceId);
|
|
61
|
+
if (existing) {
|
|
62
|
+
return existing;
|
|
63
|
+
}
|
|
64
|
+
return this.createStore(surfaceId, initialState ?? {});
|
|
65
|
+
}
|
|
66
|
+
normalizeInitialState(initialState) {
|
|
67
|
+
// If already an object (but not null/array), use it directly
|
|
68
|
+
if (initialState !== null && typeof initialState === 'object' && !Array.isArray(initialState)) {
|
|
69
|
+
return initialState;
|
|
70
|
+
}
|
|
71
|
+
// Otherwise, wrap in a 'value' key
|
|
72
|
+
return { value: initialState };
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Create a surface state manager
|
|
77
|
+
*/
|
|
78
|
+
export function createSurfaceStateManager(config) {
|
|
79
|
+
return new DefaultSurfaceStateManager(config);
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=manager.js.map
|