@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,122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Performance Budget Enforcement
|
|
3
|
+
*
|
|
4
|
+
* Defines performance budgets based on web.dev recommendations
|
|
5
|
+
* and checks measured metrics against those budgets. Violations
|
|
6
|
+
* are reported with severity levels.
|
|
7
|
+
*
|
|
8
|
+
* @module @pwfabric/runtime/perf
|
|
9
|
+
*/
|
|
10
|
+
// ============================================================
|
|
11
|
+
// DEFAULT BUDGET
|
|
12
|
+
// ============================================================
|
|
13
|
+
/**
|
|
14
|
+
* Default performance budgets based on web.dev "good" thresholds.
|
|
15
|
+
*/
|
|
16
|
+
export const DEFAULT_BUDGET = {
|
|
17
|
+
lcp: 2500,
|
|
18
|
+
fid: 100,
|
|
19
|
+
cls: 0.1,
|
|
20
|
+
fcp: 1800,
|
|
21
|
+
ttfb: 800,
|
|
22
|
+
maxRenderTime: 100,
|
|
23
|
+
};
|
|
24
|
+
// ============================================================
|
|
25
|
+
// BUDGET CHECKER
|
|
26
|
+
// ============================================================
|
|
27
|
+
/**
|
|
28
|
+
* Multiplier above the budget threshold that escalates a
|
|
29
|
+
* violation from "warning" to "error". A value 20% over
|
|
30
|
+
* budget is a warning; more than 20% over is an error.
|
|
31
|
+
*/
|
|
32
|
+
const ERROR_MULTIPLIER = 1.2;
|
|
33
|
+
/** Mapping from budget keys to the metric keys used in check() */
|
|
34
|
+
const BUDGET_METRIC_MAP = new Map([
|
|
35
|
+
['lcp', 'lcp'],
|
|
36
|
+
['fid', 'fid'],
|
|
37
|
+
['cls', 'cls'],
|
|
38
|
+
['fcp', 'fcp'],
|
|
39
|
+
['ttfb', 'ttfb'],
|
|
40
|
+
['maxBundleSize', 'maxBundleSize'],
|
|
41
|
+
['maxRenderTime', 'maxRenderTime'],
|
|
42
|
+
]);
|
|
43
|
+
/**
|
|
44
|
+
* Checks measured performance metrics against a budget.
|
|
45
|
+
*
|
|
46
|
+
* Uses default web.dev "good" thresholds unless overridden.
|
|
47
|
+
* Violations are classified as "warning" (within 20% over)
|
|
48
|
+
* or "error" (more than 20% over).
|
|
49
|
+
*/
|
|
50
|
+
export class BudgetChecker {
|
|
51
|
+
budget;
|
|
52
|
+
/**
|
|
53
|
+
* @param budget - Custom budget thresholds (merged with defaults)
|
|
54
|
+
*/
|
|
55
|
+
constructor(budget) {
|
|
56
|
+
this.budget = budget ? { ...DEFAULT_BUDGET, ...budget } : { ...DEFAULT_BUDGET };
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Check a set of metrics against the current budget.
|
|
60
|
+
*
|
|
61
|
+
* @param metrics - Map of metric name to measured value
|
|
62
|
+
* @returns Check result with pass/fail and any violations
|
|
63
|
+
*/
|
|
64
|
+
check(metrics) {
|
|
65
|
+
const violations = [];
|
|
66
|
+
for (const [budgetKey, metricKey] of BUDGET_METRIC_MAP) {
|
|
67
|
+
const threshold = this.budget[budgetKey];
|
|
68
|
+
if (threshold === undefined) {
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
const actual = metrics[metricKey];
|
|
72
|
+
if (actual === undefined) {
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
if (actual > threshold) {
|
|
76
|
+
const severity = actual > threshold * ERROR_MULTIPLIER ? 'error' : 'warning';
|
|
77
|
+
violations.push({
|
|
78
|
+
metric: metricKey,
|
|
79
|
+
budget: threshold,
|
|
80
|
+
actual,
|
|
81
|
+
severity,
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return {
|
|
86
|
+
passed: violations.length === 0,
|
|
87
|
+
violations,
|
|
88
|
+
checkedAt: Date.now(),
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Update the performance budget.
|
|
93
|
+
*
|
|
94
|
+
* Merges the provided values with the existing budget.
|
|
95
|
+
*
|
|
96
|
+
* @param budget - Partial budget to merge
|
|
97
|
+
*/
|
|
98
|
+
setBudget(budget) {
|
|
99
|
+
this.budget = { ...this.budget, ...budget };
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Get the current performance budget.
|
|
103
|
+
*
|
|
104
|
+
* @returns Readonly copy of the budget
|
|
105
|
+
*/
|
|
106
|
+
getBudget() {
|
|
107
|
+
return { ...this.budget };
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
// ============================================================
|
|
111
|
+
// FACTORY
|
|
112
|
+
// ============================================================
|
|
113
|
+
/**
|
|
114
|
+
* Create a new BudgetChecker instance.
|
|
115
|
+
*
|
|
116
|
+
* @param budget - Optional custom budget thresholds
|
|
117
|
+
* @returns A new BudgetChecker
|
|
118
|
+
*/
|
|
119
|
+
export function createBudgetChecker(budget) {
|
|
120
|
+
return new BudgetChecker(budget);
|
|
121
|
+
}
|
|
122
|
+
//# sourceMappingURL=budget.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"budget.js","sourceRoot":"","sources":["../../src/perf/budget.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AA8CH,+DAA+D;AAC/D,iBAAiB;AACjB,+DAA+D;AAE/D;;GAEG;AACH,MAAM,CAAC,MAAM,cAAc,GAAgC;IACzD,GAAG,EAAE,IAAI;IACT,GAAG,EAAE,GAAG;IACR,GAAG,EAAE,GAAG;IACR,GAAG,EAAE,IAAI;IACT,IAAI,EAAE,GAAG;IACT,aAAa,EAAE,GAAG;CACV,CAAA;AAEV,+DAA+D;AAC/D,iBAAiB;AACjB,+DAA+D;AAE/D;;;;GAIG;AACH,MAAM,gBAAgB,GAAG,GAAG,CAAA;AAE5B,kEAAkE;AAClE,MAAM,iBAAiB,GAAiD,IAAI,GAAG,CAG7E;IACA,CAAC,KAAK,EAAE,KAAK,CAAC;IACd,CAAC,KAAK,EAAE,KAAK,CAAC;IACd,CAAC,KAAK,EAAE,KAAK,CAAC;IACd,CAAC,KAAK,EAAE,KAAK,CAAC;IACd,CAAC,MAAM,EAAE,MAAM,CAAC;IAChB,CAAC,eAAe,EAAE,eAAe,CAAC;IAClC,CAAC,eAAe,EAAE,eAAe,CAAC;CACnC,CAAC,CAAA;AAEF;;;;;;GAMG;AACH,MAAM,OAAO,aAAa;IAChB,MAAM,CAAmB;IAEjC;;OAEG;IACH,YAAY,MAA0B;QACpC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,EAAE,GAAG,cAAc,EAAE,GAAG,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,cAAc,EAAE,CAAA;IACjF,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,OAAwC;QAC5C,MAAM,UAAU,GAAsB,EAAE,CAAA;QAExC,KAAK,MAAM,CAAC,SAAS,EAAE,SAAS,CAAC,IAAI,iBAAiB,EAAE,CAAC;YACvD,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAA;YACxC,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;gBAC5B,SAAQ;YACV,CAAC;YAED,MAAM,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,CAAA;YACjC,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;gBACzB,SAAQ;YACV,CAAC;YAED,IAAI,MAAM,GAAG,SAAS,EAAE,CAAC;gBACvB,MAAM,QAAQ,GACZ,MAAM,GAAG,SAAS,GAAG,gBAAgB,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAA;gBAE7D,UAAU,CAAC,IAAI,CAAC;oBACd,MAAM,EAAE,SAAS;oBACjB,MAAM,EAAE,SAAS;oBACjB,MAAM;oBACN,QAAQ;iBACT,CAAC,CAAA;YACJ,CAAC;QACH,CAAC;QAED,OAAO;YACL,MAAM,EAAE,UAAU,CAAC,MAAM,KAAK,CAAC;YAC/B,UAAU;YACV,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;SACtB,CAAA;IACH,CAAC;IAED;;;;;;OAMG;IACH,SAAS,CAAC,MAAkC;QAC1C,IAAI,CAAC,MAAM,GAAG,EAAE,GAAG,IAAI,CAAC,MAAM,EAAE,GAAG,MAAM,EAAE,CAAA;IAC7C,CAAC;IAED;;;;OAIG;IACH,SAAS;QACP,OAAO,EAAE,GAAG,IAAI,CAAC,MAAM,EAAE,CAAA;IAC3B,CAAC;CACF;AAED,+DAA+D;AAC/D,UAAU;AACV,+DAA+D;AAE/D;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB,CAAC,MAA0B;IAC5D,OAAO,IAAI,aAAa,CAAC,MAAM,CAAC,CAAA;AAClC,CAAC","sourcesContent":["/**\n * Performance Budget Enforcement\n *\n * Defines performance budgets based on web.dev recommendations\n * and checks measured metrics against those budgets. Violations\n * are reported with severity levels.\n *\n * @module @pwfabric/runtime/perf\n */\n\n// ============================================================\n// TYPES\n// ============================================================\n\n/** Performance budget thresholds */\nexport interface PerformanceBudget {\n /** Max Largest Contentful Paint in ms */\n readonly lcp?: number\n /** Max First Input Delay in ms */\n readonly fid?: number\n /** Max Cumulative Layout Shift score */\n readonly cls?: number\n /** Max First Contentful Paint in ms */\n readonly fcp?: number\n /** Max Time to First Byte in ms */\n readonly ttfb?: number\n /** Max bundle size in bytes */\n readonly maxBundleSize?: number\n /** Max render time in ms */\n readonly maxRenderTime?: number\n}\n\n/** A single budget violation */\nexport interface BudgetViolation {\n /** Metric that violated the budget */\n readonly metric: string\n /** Budget threshold */\n readonly budget: number\n /** Actual measured value */\n readonly actual: number\n /** Severity: warning if within 20% over, error if more */\n readonly severity: 'warning' | 'error'\n}\n\n/** Result of checking metrics against a budget */\nexport interface BudgetCheckResult {\n /** Whether all metrics passed the budget */\n readonly passed: boolean\n /** List of violations (empty if passed) */\n readonly violations: readonly BudgetViolation[]\n /** Timestamp when the check was performed */\n readonly checkedAt: number\n}\n\n// ============================================================\n// DEFAULT BUDGET\n// ============================================================\n\n/**\n * Default performance budgets based on web.dev \"good\" thresholds.\n */\nexport const DEFAULT_BUDGET: Readonly<PerformanceBudget> = {\n lcp: 2500,\n fid: 100,\n cls: 0.1,\n fcp: 1800,\n ttfb: 800,\n maxRenderTime: 100,\n} as const\n\n// ============================================================\n// BUDGET CHECKER\n// ============================================================\n\n/**\n * Multiplier above the budget threshold that escalates a\n * violation from \"warning\" to \"error\". A value 20% over\n * budget is a warning; more than 20% over is an error.\n */\nconst ERROR_MULTIPLIER = 1.2\n\n/** Mapping from budget keys to the metric keys used in check() */\nconst BUDGET_METRIC_MAP: ReadonlyMap<keyof PerformanceBudget, string> = new Map<\n keyof PerformanceBudget,\n string\n>([\n ['lcp', 'lcp'],\n ['fid', 'fid'],\n ['cls', 'cls'],\n ['fcp', 'fcp'],\n ['ttfb', 'ttfb'],\n ['maxBundleSize', 'maxBundleSize'],\n ['maxRenderTime', 'maxRenderTime'],\n])\n\n/**\n * Checks measured performance metrics against a budget.\n *\n * Uses default web.dev \"good\" thresholds unless overridden.\n * Violations are classified as \"warning\" (within 20% over)\n * or \"error\" (more than 20% over).\n */\nexport class BudgetChecker {\n private budget: PerformanceBudget\n\n /**\n * @param budget - Custom budget thresholds (merged with defaults)\n */\n constructor(budget?: PerformanceBudget) {\n this.budget = budget ? { ...DEFAULT_BUDGET, ...budget } : { ...DEFAULT_BUDGET }\n }\n\n /**\n * Check a set of metrics against the current budget.\n *\n * @param metrics - Map of metric name to measured value\n * @returns Check result with pass/fail and any violations\n */\n check(metrics: Partial<Record<string, number>>): BudgetCheckResult {\n const violations: BudgetViolation[] = []\n\n for (const [budgetKey, metricKey] of BUDGET_METRIC_MAP) {\n const threshold = this.budget[budgetKey]\n if (threshold === undefined) {\n continue\n }\n\n const actual = metrics[metricKey]\n if (actual === undefined) {\n continue\n }\n\n if (actual > threshold) {\n const severity: 'warning' | 'error' =\n actual > threshold * ERROR_MULTIPLIER ? 'error' : 'warning'\n\n violations.push({\n metric: metricKey,\n budget: threshold,\n actual,\n severity,\n })\n }\n }\n\n return {\n passed: violations.length === 0,\n violations,\n checkedAt: Date.now(),\n }\n }\n\n /**\n * Update the performance budget.\n *\n * Merges the provided values with the existing budget.\n *\n * @param budget - Partial budget to merge\n */\n setBudget(budget: Partial<PerformanceBudget>): void {\n this.budget = { ...this.budget, ...budget }\n }\n\n /**\n * Get the current performance budget.\n *\n * @returns Readonly copy of the budget\n */\n getBudget(): Readonly<PerformanceBudget> {\n return { ...this.budget }\n }\n}\n\n// ============================================================\n// FACTORY\n// ============================================================\n\n/**\n * Create a new BudgetChecker instance.\n *\n * @param budget - Optional custom budget thresholds\n * @returns A new BudgetChecker\n */\nexport function createBudgetChecker(budget?: PerformanceBudget): BudgetChecker {\n return new BudgetChecker(budget)\n}\n"]}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Performance Monitoring Module
|
|
3
|
+
*
|
|
4
|
+
* Provides Core Web Vitals collection, surface render timing,
|
|
5
|
+
* performance budget enforcement, and unified reporting.
|
|
6
|
+
*
|
|
7
|
+
* @module @pwfabric/runtime/perf
|
|
8
|
+
*/
|
|
9
|
+
export type { WebVitalName, WebVitalRating, WebVitalMetric, WebVitalCallback, WebVitalsReport, } from './web-vitals.js';
|
|
10
|
+
export { WebVitalsCollector, createWebVitalsCollector, rateMetric } from './web-vitals.js';
|
|
11
|
+
export type { RenderMetrics, RenderTimerConfig } from './render-timer.js';
|
|
12
|
+
export { RenderTimer, createRenderTimer } from './render-timer.js';
|
|
13
|
+
export type { PerformanceBudget, BudgetViolation, BudgetCheckResult } from './budget.js';
|
|
14
|
+
export { DEFAULT_BUDGET, BudgetChecker, createBudgetChecker } from './budget.js';
|
|
15
|
+
export type { ReportDestination, ReporterConfig, PerformanceReport } from './reporter.js';
|
|
16
|
+
export { PerformanceReporter, createPerformanceReporter } from './reporter.js';
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Performance Monitoring Module
|
|
3
|
+
*
|
|
4
|
+
* Provides Core Web Vitals collection, surface render timing,
|
|
5
|
+
* performance budget enforcement, and unified reporting.
|
|
6
|
+
*
|
|
7
|
+
* @module @pwfabric/runtime/perf
|
|
8
|
+
*/
|
|
9
|
+
export { WebVitalsCollector, createWebVitalsCollector, rateMetric } from './web-vitals.js';
|
|
10
|
+
export { RenderTimer, createRenderTimer } from './render-timer.js';
|
|
11
|
+
export { DEFAULT_BUDGET, BudgetChecker, createBudgetChecker } from './budget.js';
|
|
12
|
+
export { PerformanceReporter, createPerformanceReporter } from './reporter.js';
|
|
13
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/perf/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAUH,OAAO,EAAE,kBAAkB,EAAE,wBAAwB,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAI1F,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AAIlE,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAA;AAIhF,OAAO,EAAE,mBAAmB,EAAE,yBAAyB,EAAE,MAAM,eAAe,CAAA","sourcesContent":["/**\n * Performance Monitoring Module\n *\n * Provides Core Web Vitals collection, surface render timing,\n * performance budget enforcement, and unified reporting.\n *\n * @module @pwfabric/runtime/perf\n */\n\n// Web Vitals collection\nexport type {\n WebVitalName,\n WebVitalRating,\n WebVitalMetric,\n WebVitalCallback,\n WebVitalsReport,\n} from './web-vitals.js'\nexport { WebVitalsCollector, createWebVitalsCollector, rateMetric } from './web-vitals.js'\n\n// Render timing\nexport type { RenderMetrics, RenderTimerConfig } from './render-timer.js'\nexport { RenderTimer, createRenderTimer } from './render-timer.js'\n\n// Performance budget\nexport type { PerformanceBudget, BudgetViolation, BudgetCheckResult } from './budget.js'\nexport { DEFAULT_BUDGET, BudgetChecker, createBudgetChecker } from './budget.js'\n\n// Reporter\nexport type { ReportDestination, ReporterConfig, PerformanceReport } from './reporter.js'\nexport { PerformanceReporter, createPerformanceReporter } from './reporter.js'\n"]}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Surface / Block Render Timing
|
|
3
|
+
*
|
|
4
|
+
* Tracks render durations for surfaces and blocks using
|
|
5
|
+
* high-resolution timing. Maintains a bounded history of
|
|
6
|
+
* render metrics for performance analysis.
|
|
7
|
+
*
|
|
8
|
+
* Uses `performance.now()` when available, falling back to
|
|
9
|
+
* `Date.now()` for SSR environments.
|
|
10
|
+
*
|
|
11
|
+
* @module @pwfabric/runtime/perf
|
|
12
|
+
*/
|
|
13
|
+
/** Metrics for a single surface render cycle */
|
|
14
|
+
export interface RenderMetrics {
|
|
15
|
+
/** Surface identifier */
|
|
16
|
+
readonly surfaceId: string;
|
|
17
|
+
/** High-resolution render start time */
|
|
18
|
+
readonly startTime: number;
|
|
19
|
+
/** High-resolution render end time */
|
|
20
|
+
readonly endTime: number;
|
|
21
|
+
/** Render duration in milliseconds */
|
|
22
|
+
readonly duration: number;
|
|
23
|
+
/** Number of blocks rendered */
|
|
24
|
+
readonly blockCount: number;
|
|
25
|
+
}
|
|
26
|
+
/** Configuration for the RenderTimer */
|
|
27
|
+
export interface RenderTimerConfig {
|
|
28
|
+
/** Maximum number of entries to keep in history (default: 100) */
|
|
29
|
+
maxEntries?: number;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Tracks surface render timing with bounded history.
|
|
33
|
+
*
|
|
34
|
+
* Call `startRender` before a surface renders and `endRender`
|
|
35
|
+
* when rendering completes. The timer records the duration and
|
|
36
|
+
* maintains a history of recent render metrics.
|
|
37
|
+
*/
|
|
38
|
+
export declare class RenderTimer {
|
|
39
|
+
private entries;
|
|
40
|
+
private history;
|
|
41
|
+
private readonly maxEntries;
|
|
42
|
+
/**
|
|
43
|
+
* @param config - Optional configuration
|
|
44
|
+
*/
|
|
45
|
+
constructor(config?: RenderTimerConfig);
|
|
46
|
+
/**
|
|
47
|
+
* Mark the start of a surface render.
|
|
48
|
+
*
|
|
49
|
+
* @param surfaceId - Unique identifier for the surface
|
|
50
|
+
* @param blockCount - Number of blocks being rendered (default: 0)
|
|
51
|
+
*/
|
|
52
|
+
startRender(surfaceId: string, blockCount?: number): void;
|
|
53
|
+
/**
|
|
54
|
+
* Mark the end of a surface render and record metrics.
|
|
55
|
+
*
|
|
56
|
+
* @param surfaceId - The surface identifier passed to `startRender`
|
|
57
|
+
* @returns The render metrics, or `undefined` if no matching start was found
|
|
58
|
+
*/
|
|
59
|
+
endRender(surfaceId: string): RenderMetrics | undefined;
|
|
60
|
+
/**
|
|
61
|
+
* Calculate the average render time across all recorded renders.
|
|
62
|
+
*
|
|
63
|
+
* @returns Average duration in milliseconds, or 0 if no renders recorded
|
|
64
|
+
*/
|
|
65
|
+
getAverageRenderTime(): number;
|
|
66
|
+
/**
|
|
67
|
+
* Get the full render history.
|
|
68
|
+
*
|
|
69
|
+
* @returns Readonly array of render metrics
|
|
70
|
+
*/
|
|
71
|
+
getHistory(): readonly RenderMetrics[];
|
|
72
|
+
/**
|
|
73
|
+
* Get the slowest renders, sorted by duration descending.
|
|
74
|
+
*
|
|
75
|
+
* @param count - Number of entries to return (default: 5)
|
|
76
|
+
* @returns Array of the slowest render metrics
|
|
77
|
+
*/
|
|
78
|
+
getSlowest(count?: number): RenderMetrics[];
|
|
79
|
+
/**
|
|
80
|
+
* Clear all history and active entries.
|
|
81
|
+
*/
|
|
82
|
+
clear(): void;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Create a new RenderTimer instance.
|
|
86
|
+
*
|
|
87
|
+
* @param config - Optional configuration
|
|
88
|
+
* @returns A new RenderTimer
|
|
89
|
+
*/
|
|
90
|
+
export declare function createRenderTimer(config?: RenderTimerConfig): RenderTimer;
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Surface / Block Render Timing
|
|
3
|
+
*
|
|
4
|
+
* Tracks render durations for surfaces and blocks using
|
|
5
|
+
* high-resolution timing. Maintains a bounded history of
|
|
6
|
+
* render metrics for performance analysis.
|
|
7
|
+
*
|
|
8
|
+
* Uses `performance.now()` when available, falling back to
|
|
9
|
+
* `Date.now()` for SSR environments.
|
|
10
|
+
*
|
|
11
|
+
* @module @pwfabric/runtime/perf
|
|
12
|
+
*/
|
|
13
|
+
// ============================================================
|
|
14
|
+
// TIMING UTILITY
|
|
15
|
+
// ============================================================
|
|
16
|
+
/**
|
|
17
|
+
* Get the current high-resolution timestamp.
|
|
18
|
+
*
|
|
19
|
+
* Falls back to `Date.now()` when `performance` is not available (SSR).
|
|
20
|
+
*/
|
|
21
|
+
function now() {
|
|
22
|
+
if (typeof performance !== 'undefined' && typeof performance.now === 'function') {
|
|
23
|
+
return performance.now();
|
|
24
|
+
}
|
|
25
|
+
return Date.now();
|
|
26
|
+
}
|
|
27
|
+
// ============================================================
|
|
28
|
+
// DEFAULTS
|
|
29
|
+
// ============================================================
|
|
30
|
+
const DEFAULT_MAX_ENTRIES = 100;
|
|
31
|
+
/**
|
|
32
|
+
* Tracks surface render timing with bounded history.
|
|
33
|
+
*
|
|
34
|
+
* Call `startRender` before a surface renders and `endRender`
|
|
35
|
+
* when rendering completes. The timer records the duration and
|
|
36
|
+
* maintains a history of recent render metrics.
|
|
37
|
+
*/
|
|
38
|
+
export class RenderTimer {
|
|
39
|
+
entries = new Map();
|
|
40
|
+
history = [];
|
|
41
|
+
maxEntries;
|
|
42
|
+
/**
|
|
43
|
+
* @param config - Optional configuration
|
|
44
|
+
*/
|
|
45
|
+
constructor(config) {
|
|
46
|
+
this.maxEntries = config?.maxEntries ?? DEFAULT_MAX_ENTRIES;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Mark the start of a surface render.
|
|
50
|
+
*
|
|
51
|
+
* @param surfaceId - Unique identifier for the surface
|
|
52
|
+
* @param blockCount - Number of blocks being rendered (default: 0)
|
|
53
|
+
*/
|
|
54
|
+
startRender(surfaceId, blockCount = 0) {
|
|
55
|
+
this.entries.set(surfaceId, {
|
|
56
|
+
startTime: now(),
|
|
57
|
+
blockCount,
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Mark the end of a surface render and record metrics.
|
|
62
|
+
*
|
|
63
|
+
* @param surfaceId - The surface identifier passed to `startRender`
|
|
64
|
+
* @returns The render metrics, or `undefined` if no matching start was found
|
|
65
|
+
*/
|
|
66
|
+
endRender(surfaceId) {
|
|
67
|
+
const entry = this.entries.get(surfaceId);
|
|
68
|
+
if (!entry) {
|
|
69
|
+
return undefined;
|
|
70
|
+
}
|
|
71
|
+
this.entries.delete(surfaceId);
|
|
72
|
+
const endTime = now();
|
|
73
|
+
const metrics = {
|
|
74
|
+
surfaceId,
|
|
75
|
+
startTime: entry.startTime,
|
|
76
|
+
endTime,
|
|
77
|
+
duration: endTime - entry.startTime,
|
|
78
|
+
blockCount: entry.blockCount,
|
|
79
|
+
};
|
|
80
|
+
this.history.push(metrics);
|
|
81
|
+
// Enforce bounded history
|
|
82
|
+
if (this.history.length > this.maxEntries) {
|
|
83
|
+
this.history = this.history.slice(-this.maxEntries);
|
|
84
|
+
}
|
|
85
|
+
return metrics;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Calculate the average render time across all recorded renders.
|
|
89
|
+
*
|
|
90
|
+
* @returns Average duration in milliseconds, or 0 if no renders recorded
|
|
91
|
+
*/
|
|
92
|
+
getAverageRenderTime() {
|
|
93
|
+
if (this.history.length === 0) {
|
|
94
|
+
return 0;
|
|
95
|
+
}
|
|
96
|
+
const total = this.history.reduce((sum, m) => sum + m.duration, 0);
|
|
97
|
+
return total / this.history.length;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Get the full render history.
|
|
101
|
+
*
|
|
102
|
+
* @returns Readonly array of render metrics
|
|
103
|
+
*/
|
|
104
|
+
getHistory() {
|
|
105
|
+
return this.history;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Get the slowest renders, sorted by duration descending.
|
|
109
|
+
*
|
|
110
|
+
* @param count - Number of entries to return (default: 5)
|
|
111
|
+
* @returns Array of the slowest render metrics
|
|
112
|
+
*/
|
|
113
|
+
getSlowest(count = 5) {
|
|
114
|
+
return [...this.history].sort((a, b) => b.duration - a.duration).slice(0, count);
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Clear all history and active entries.
|
|
118
|
+
*/
|
|
119
|
+
clear() {
|
|
120
|
+
this.entries.clear();
|
|
121
|
+
this.history = [];
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
// ============================================================
|
|
125
|
+
// FACTORY
|
|
126
|
+
// ============================================================
|
|
127
|
+
/**
|
|
128
|
+
* Create a new RenderTimer instance.
|
|
129
|
+
*
|
|
130
|
+
* @param config - Optional configuration
|
|
131
|
+
* @returns A new RenderTimer
|
|
132
|
+
*/
|
|
133
|
+
export function createRenderTimer(config) {
|
|
134
|
+
return new RenderTimer(config);
|
|
135
|
+
}
|
|
136
|
+
//# sourceMappingURL=render-timer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render-timer.js","sourceRoot":"","sources":["../../src/perf/render-timer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,+DAA+D;AAC/D,iBAAiB;AACjB,+DAA+D;AAE/D;;;;GAIG;AACH,SAAS,GAAG;IACV,IAAI,OAAO,WAAW,KAAK,WAAW,IAAI,OAAO,WAAW,CAAC,GAAG,KAAK,UAAU,EAAE,CAAC;QAChF,OAAO,WAAW,CAAC,GAAG,EAAE,CAAA;IAC1B,CAAC;IACD,OAAO,IAAI,CAAC,GAAG,EAAE,CAAA;AACnB,CAAC;AA0BD,+DAA+D;AAC/D,WAAW;AACX,+DAA+D;AAE/D,MAAM,mBAAmB,GAAG,GAAG,CAAA;AAY/B;;;;;;GAMG;AACH,MAAM,OAAO,WAAW;IACd,OAAO,GAAG,IAAI,GAAG,EAAwB,CAAA;IACzC,OAAO,GAAoB,EAAE,CAAA;IACpB,UAAU,CAAQ;IAEnC;;OAEG;IACH,YAAY,MAA0B;QACpC,IAAI,CAAC,UAAU,GAAG,MAAM,EAAE,UAAU,IAAI,mBAAmB,CAAA;IAC7D,CAAC;IAED;;;;;OAKG;IACH,WAAW,CAAC,SAAiB,EAAE,UAAU,GAAG,CAAC;QAC3C,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE;YAC1B,SAAS,EAAE,GAAG,EAAE;YAChB,UAAU;SACX,CAAC,CAAA;IACJ,CAAC;IAED;;;;;OAKG;IACH,SAAS,CAAC,SAAiB;QACzB,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAA;QACzC,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,SAAS,CAAA;QAClB,CAAC;QAED,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,CAAA;QAE9B,MAAM,OAAO,GAAG,GAAG,EAAE,CAAA;QACrB,MAAM,OAAO,GAAkB;YAC7B,SAAS;YACT,SAAS,EAAE,KAAK,CAAC,SAAS;YAC1B,OAAO;YACP,QAAQ,EAAE,OAAO,GAAG,KAAK,CAAC,SAAS;YACnC,UAAU,EAAE,KAAK,CAAC,UAAU;SAC7B,CAAA;QAED,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;QAE1B,0BAA0B;QAC1B,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;YAC1C,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;QACrD,CAAC;QAED,OAAO,OAAO,CAAA;IAChB,CAAC;IAED;;;;OAIG;IACH,oBAAoB;QAClB,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC9B,OAAO,CAAC,CAAA;QACV,CAAC;QACD,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAA;QAClE,OAAO,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAA;IACpC,CAAC;IAED;;;;OAIG;IACH,UAAU;QACR,OAAO,IAAI,CAAC,OAAO,CAAA;IACrB,CAAC;IAED;;;;;OAKG;IACH,UAAU,CAAC,KAAK,GAAG,CAAC;QAClB,OAAO,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAA;IAClF,CAAC;IAED;;OAEG;IACH,KAAK;QACH,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAA;QACpB,IAAI,CAAC,OAAO,GAAG,EAAE,CAAA;IACnB,CAAC;CACF;AAED,+DAA+D;AAC/D,UAAU;AACV,+DAA+D;AAE/D;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAC,MAA0B;IAC1D,OAAO,IAAI,WAAW,CAAC,MAAM,CAAC,CAAA;AAChC,CAAC","sourcesContent":["/**\n * Surface / Block Render Timing\n *\n * Tracks render durations for surfaces and blocks using\n * high-resolution timing. Maintains a bounded history of\n * render metrics for performance analysis.\n *\n * Uses `performance.now()` when available, falling back to\n * `Date.now()` for SSR environments.\n *\n * @module @pwfabric/runtime/perf\n */\n\n// ============================================================\n// TIMING UTILITY\n// ============================================================\n\n/**\n * Get the current high-resolution timestamp.\n *\n * Falls back to `Date.now()` when `performance` is not available (SSR).\n */\nfunction now(): number {\n if (typeof performance !== 'undefined' && typeof performance.now === 'function') {\n return performance.now()\n }\n return Date.now()\n}\n\n// ============================================================\n// TYPES\n// ============================================================\n\n/** Metrics for a single surface render cycle */\nexport interface RenderMetrics {\n /** Surface identifier */\n readonly surfaceId: string\n /** High-resolution render start time */\n readonly startTime: number\n /** High-resolution render end time */\n readonly endTime: number\n /** Render duration in milliseconds */\n readonly duration: number\n /** Number of blocks rendered */\n readonly blockCount: number\n}\n\n/** Configuration for the RenderTimer */\nexport interface RenderTimerConfig {\n /** Maximum number of entries to keep in history (default: 100) */\n maxEntries?: number\n}\n\n// ============================================================\n// DEFAULTS\n// ============================================================\n\nconst DEFAULT_MAX_ENTRIES = 100\n\n// ============================================================\n// RENDER TIMER\n// ============================================================\n\n/** Active render tracking entry */\ninterface ActiveRender {\n readonly startTime: number\n readonly blockCount: number\n}\n\n/**\n * Tracks surface render timing with bounded history.\n *\n * Call `startRender` before a surface renders and `endRender`\n * when rendering completes. The timer records the duration and\n * maintains a history of recent render metrics.\n */\nexport class RenderTimer {\n private entries = new Map<string, ActiveRender>()\n private history: RenderMetrics[] = []\n private readonly maxEntries: number\n\n /**\n * @param config - Optional configuration\n */\n constructor(config?: RenderTimerConfig) {\n this.maxEntries = config?.maxEntries ?? DEFAULT_MAX_ENTRIES\n }\n\n /**\n * Mark the start of a surface render.\n *\n * @param surfaceId - Unique identifier for the surface\n * @param blockCount - Number of blocks being rendered (default: 0)\n */\n startRender(surfaceId: string, blockCount = 0): void {\n this.entries.set(surfaceId, {\n startTime: now(),\n blockCount,\n })\n }\n\n /**\n * Mark the end of a surface render and record metrics.\n *\n * @param surfaceId - The surface identifier passed to `startRender`\n * @returns The render metrics, or `undefined` if no matching start was found\n */\n endRender(surfaceId: string): RenderMetrics | undefined {\n const entry = this.entries.get(surfaceId)\n if (!entry) {\n return undefined\n }\n\n this.entries.delete(surfaceId)\n\n const endTime = now()\n const metrics: RenderMetrics = {\n surfaceId,\n startTime: entry.startTime,\n endTime,\n duration: endTime - entry.startTime,\n blockCount: entry.blockCount,\n }\n\n this.history.push(metrics)\n\n // Enforce bounded history\n if (this.history.length > this.maxEntries) {\n this.history = this.history.slice(-this.maxEntries)\n }\n\n return metrics\n }\n\n /**\n * Calculate the average render time across all recorded renders.\n *\n * @returns Average duration in milliseconds, or 0 if no renders recorded\n */\n getAverageRenderTime(): number {\n if (this.history.length === 0) {\n return 0\n }\n const total = this.history.reduce((sum, m) => sum + m.duration, 0)\n return total / this.history.length\n }\n\n /**\n * Get the full render history.\n *\n * @returns Readonly array of render metrics\n */\n getHistory(): readonly RenderMetrics[] {\n return this.history\n }\n\n /**\n * Get the slowest renders, sorted by duration descending.\n *\n * @param count - Number of entries to return (default: 5)\n * @returns Array of the slowest render metrics\n */\n getSlowest(count = 5): RenderMetrics[] {\n return [...this.history].sort((a, b) => b.duration - a.duration).slice(0, count)\n }\n\n /**\n * Clear all history and active entries.\n */\n clear(): void {\n this.entries.clear()\n this.history = []\n }\n}\n\n// ============================================================\n// FACTORY\n// ============================================================\n\n/**\n * Create a new RenderTimer instance.\n *\n * @param config - Optional configuration\n * @returns A new RenderTimer\n */\nexport function createRenderTimer(config?: RenderTimerConfig): RenderTimer {\n return new RenderTimer(config)\n}\n"]}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Performance Metric Reporter
|
|
3
|
+
*
|
|
4
|
+
* Orchestrates Web Vitals collection, render timing, and budget
|
|
5
|
+
* checking into a unified reporting pipeline. Supports periodic
|
|
6
|
+
* automatic reporting or manual on-demand reports.
|
|
7
|
+
*
|
|
8
|
+
* @module @pwfabric/runtime/perf
|
|
9
|
+
*/
|
|
10
|
+
import type { WebVitalsReport } from './web-vitals.js';
|
|
11
|
+
import type { RenderMetrics } from './render-timer.js';
|
|
12
|
+
import type { PerformanceBudget, BudgetCheckResult } from './budget.js';
|
|
13
|
+
import { WebVitalsCollector } from './web-vitals.js';
|
|
14
|
+
import { RenderTimer } from './render-timer.js';
|
|
15
|
+
/** Where to send performance reports */
|
|
16
|
+
export type ReportDestination = 'console' | 'custom';
|
|
17
|
+
/** Reporter configuration */
|
|
18
|
+
export interface ReporterConfig {
|
|
19
|
+
/** Report destination */
|
|
20
|
+
readonly destination: ReportDestination;
|
|
21
|
+
/** Custom report handler (required when destination is 'custom') */
|
|
22
|
+
readonly onReport?: (report: PerformanceReport) => void | Promise<void>;
|
|
23
|
+
/** Reporting interval in ms (0 = manual only, default: 0) */
|
|
24
|
+
readonly interval?: number;
|
|
25
|
+
/** Whether to include render metrics (default: true) */
|
|
26
|
+
readonly includeRenderMetrics?: boolean;
|
|
27
|
+
/** Whether to include Web Vitals (default: true) */
|
|
28
|
+
readonly includeWebVitals?: boolean;
|
|
29
|
+
/** Performance budget to check against */
|
|
30
|
+
readonly budget?: PerformanceBudget;
|
|
31
|
+
}
|
|
32
|
+
/** A complete performance report */
|
|
33
|
+
export interface PerformanceReport {
|
|
34
|
+
/** Timestamp when the report was generated */
|
|
35
|
+
readonly timestamp: number;
|
|
36
|
+
/** Web Vitals snapshot */
|
|
37
|
+
readonly webVitals?: WebVitalsReport | undefined;
|
|
38
|
+
/** Render timing summary */
|
|
39
|
+
readonly renderMetrics?: {
|
|
40
|
+
readonly averageRenderTime: number;
|
|
41
|
+
readonly totalRenders: number;
|
|
42
|
+
readonly slowestRenders: readonly RenderMetrics[];
|
|
43
|
+
} | undefined;
|
|
44
|
+
/** Budget check result */
|
|
45
|
+
readonly budgetCheck?: BudgetCheckResult | undefined;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Orchestrates performance monitoring components and generates
|
|
49
|
+
* unified performance reports.
|
|
50
|
+
*
|
|
51
|
+
* Manages a WebVitalsCollector, RenderTimer, and BudgetChecker
|
|
52
|
+
* internally. Supports automatic periodic reporting or manual
|
|
53
|
+
* on-demand report generation.
|
|
54
|
+
*/
|
|
55
|
+
export declare class PerformanceReporter {
|
|
56
|
+
private readonly destination;
|
|
57
|
+
private readonly onReportCallback?;
|
|
58
|
+
private readonly interval;
|
|
59
|
+
private readonly includeRenderMetrics;
|
|
60
|
+
private readonly includeWebVitals;
|
|
61
|
+
private webVitals?;
|
|
62
|
+
private renderTimer?;
|
|
63
|
+
private budgetChecker?;
|
|
64
|
+
private intervalId?;
|
|
65
|
+
/**
|
|
66
|
+
* @param config - Reporter configuration
|
|
67
|
+
*/
|
|
68
|
+
constructor(config: ReporterConfig);
|
|
69
|
+
/**
|
|
70
|
+
* Start periodic reporting and Web Vitals collection.
|
|
71
|
+
*
|
|
72
|
+
* If an interval is configured, reports will be generated
|
|
73
|
+
* automatically at that interval. Web Vitals collection
|
|
74
|
+
* starts immediately.
|
|
75
|
+
*/
|
|
76
|
+
start(): void;
|
|
77
|
+
/**
|
|
78
|
+
* Generate and deliver a performance report.
|
|
79
|
+
*
|
|
80
|
+
* Collects metrics from all active sub-components, runs
|
|
81
|
+
* budget checks if configured, and delivers the report
|
|
82
|
+
* to the configured destination.
|
|
83
|
+
*
|
|
84
|
+
* @returns The generated performance report
|
|
85
|
+
*/
|
|
86
|
+
report(): Promise<PerformanceReport>;
|
|
87
|
+
/**
|
|
88
|
+
* Stop periodic reporting.
|
|
89
|
+
*
|
|
90
|
+
* Does not stop Web Vitals collection or clear history.
|
|
91
|
+
* Use `dispose()` for full cleanup.
|
|
92
|
+
*/
|
|
93
|
+
stop(): void;
|
|
94
|
+
/**
|
|
95
|
+
* Get the internal WebVitalsCollector.
|
|
96
|
+
*
|
|
97
|
+
* Useful for registering custom metric callbacks.
|
|
98
|
+
*
|
|
99
|
+
* @returns The collector, or undefined if Web Vitals are disabled
|
|
100
|
+
*/
|
|
101
|
+
getWebVitals(): WebVitalsCollector | undefined;
|
|
102
|
+
/**
|
|
103
|
+
* Get the internal RenderTimer.
|
|
104
|
+
*
|
|
105
|
+
* Useful for tracking surface render timing externally.
|
|
106
|
+
*
|
|
107
|
+
* @returns The timer, or undefined if render metrics are disabled
|
|
108
|
+
*/
|
|
109
|
+
getRenderTimer(): RenderTimer | undefined;
|
|
110
|
+
/**
|
|
111
|
+
* Stop reporting and release all resources.
|
|
112
|
+
*/
|
|
113
|
+
dispose(): void;
|
|
114
|
+
private buildWebVitalsSection;
|
|
115
|
+
private buildRenderMetricsSection;
|
|
116
|
+
private buildBudgetCheckSection;
|
|
117
|
+
private deliverReport;
|
|
118
|
+
private logToConsole;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Create a new PerformanceReporter instance.
|
|
122
|
+
*
|
|
123
|
+
* @param config - Reporter configuration
|
|
124
|
+
* @returns A new PerformanceReporter
|
|
125
|
+
*/
|
|
126
|
+
export declare function createPerformanceReporter(config: ReporterConfig): PerformanceReporter;
|