@noego/wood 0.4.9 → 0.5.0
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/README.md +118 -42
- package/bin/axe.js +313 -98
- package/dist/{loader/__fixtures__/layouts/app.load.cjs → automation/actions.cjs} +3 -13
- package/dist/automation/actions.cjs.map +1 -0
- package/dist/automation/actions.d.cts +57 -0
- package/dist/automation/actions.d.ts +57 -0
- package/dist/automation/actions.js +1 -0
- package/dist/automation/actions.js.map +1 -0
- package/dist/automation/actions_executor.cjs +101 -0
- package/dist/automation/actions_executor.cjs.map +1 -0
- package/dist/automation/actions_executor.d.cts +16 -0
- package/dist/automation/actions_executor.d.ts +16 -0
- package/dist/automation/actions_executor.js +76 -0
- package/dist/automation/actions_executor.js.map +1 -0
- package/dist/automation/connection.cjs +86 -0
- package/dist/automation/connection.cjs.map +1 -0
- package/dist/automation/connection.d.cts +18 -0
- package/dist/automation/connection.d.ts +18 -0
- package/dist/automation/connection.js +51 -0
- package/dist/automation/connection.js.map +1 -0
- package/dist/{middleware/__fixtures__/middleware/sequence.cjs → automation/errors.cjs} +25 -22
- package/dist/automation/errors.cjs.map +1 -0
- package/dist/automation/errors.d.cts +31 -0
- package/dist/automation/errors.d.ts +31 -0
- package/dist/automation/errors.js +24 -0
- package/dist/automation/errors.js.map +1 -0
- package/dist/automation/index.cjs +49 -0
- package/dist/automation/index.cjs.map +1 -0
- package/dist/automation/index.d.cts +16 -0
- package/dist/automation/index.d.ts +16 -0
- package/dist/automation/index.js +15 -0
- package/dist/automation/index.js.map +1 -0
- package/dist/automation/introspection_reader.cjs +75 -0
- package/dist/automation/introspection_reader.cjs.map +1 -0
- package/dist/automation/introspection_reader.d.cts +20 -0
- package/dist/automation/introspection_reader.d.ts +20 -0
- package/dist/automation/introspection_reader.js +48 -0
- package/dist/automation/introspection_reader.js.map +1 -0
- package/dist/automation/locator.cjs +102 -0
- package/dist/automation/locator.cjs.map +1 -0
- package/dist/automation/locator.d.cts +51 -0
- package/dist/automation/locator.d.ts +51 -0
- package/dist/automation/locator.js +75 -0
- package/dist/automation/locator.js.map +1 -0
- package/dist/{loader/__fixtures__/views/test/page.load.cjs → automation/observation.cjs} +3 -13
- package/dist/automation/observation.cjs.map +1 -0
- package/dist/automation/observation.d.cts +44 -0
- package/dist/automation/observation.d.ts +44 -0
- package/dist/automation/observation.js +1 -0
- package/dist/automation/observation.js.map +1 -0
- package/dist/{controller/__fixtures__/controllers/test.cjs → automation/receipts.cjs} +3 -15
- package/dist/automation/receipts.cjs.map +1 -0
- package/dist/automation/receipts.d.cts +27 -0
- package/dist/automation/receipts.d.ts +27 -0
- package/dist/automation/receipts.js +1 -0
- package/dist/automation/receipts.js.map +1 -0
- package/dist/automation/scenario.cjs +696 -0
- package/dist/automation/scenario.cjs.map +1 -0
- package/dist/automation/scenario.d.cts +89 -0
- package/dist/automation/scenario.d.ts +89 -0
- package/dist/automation/scenario.js +660 -0
- package/dist/automation/scenario.js.map +1 -0
- package/dist/automation/scrolling.cjs +17 -0
- package/dist/automation/scrolling.cjs.map +1 -0
- package/dist/automation/scrolling.d.cts +51 -0
- package/dist/automation/scrolling.d.ts +51 -0
- package/dist/automation/scrolling.js +1 -0
- package/dist/automation/scrolling.js.map +1 -0
- package/dist/automation/scrolling_executor.cjs +109 -0
- package/dist/automation/scrolling_executor.cjs.map +1 -0
- package/dist/automation/scrolling_executor.d.cts +13 -0
- package/dist/automation/scrolling_executor.d.ts +13 -0
- package/dist/automation/scrolling_executor.js +84 -0
- package/dist/automation/scrolling_executor.js.map +1 -0
- package/dist/automation/target_identity.cjs +17 -0
- package/dist/automation/target_identity.cjs.map +1 -0
- package/dist/automation/target_identity.d.cts +28 -0
- package/dist/automation/target_identity.d.ts +28 -0
- package/dist/automation/target_identity.js +1 -0
- package/dist/automation/target_identity.js.map +1 -0
- package/dist/automation/target_registry.cjs +148 -0
- package/dist/automation/target_registry.cjs.map +1 -0
- package/dist/automation/target_registry.d.cts +32 -0
- package/dist/automation/target_registry.d.ts +32 -0
- package/dist/automation/target_registry.js +122 -0
- package/dist/automation/target_registry.js.map +1 -0
- package/dist/automation/waits.cjs +17 -0
- package/dist/automation/waits.cjs.map +1 -0
- package/dist/automation/waits.d.cts +44 -0
- package/dist/automation/waits.d.ts +44 -0
- package/dist/automation/waits.js +1 -0
- package/dist/automation/waits.js.map +1 -0
- package/dist/automation/waits_executor.cjs +104 -0
- package/dist/automation/waits_executor.cjs.map +1 -0
- package/dist/automation/waits_executor.d.cts +14 -0
- package/dist/automation/waits_executor.d.ts +14 -0
- package/dist/automation/waits_executor.js +79 -0
- package/dist/automation/waits_executor.js.map +1 -0
- package/dist/bridge/backend_bridge.cjs.map +1 -1
- package/dist/bridge/backend_bridge.js.map +1 -1
- package/dist/client/index.cjs +78 -21
- package/dist/client/index.cjs.map +1 -1
- package/dist/client/index.d.cts +19 -3
- package/dist/client/index.d.ts +19 -3
- package/dist/client/index.js +80 -22
- package/dist/client/index.js.map +1 -1
- package/dist/client/renderer_log_transport.cjs +151 -0
- package/dist/client/renderer_log_transport.cjs.map +1 -0
- package/dist/client/renderer_log_transport.d.cts +54 -0
- package/dist/client/renderer_log_transport.d.ts +54 -0
- package/dist/client/renderer_log_transport.js +123 -0
- package/dist/client/renderer_log_transport.js.map +1 -0
- package/dist/codegen/controller_registration_generator.cjs +13 -2
- package/dist/codegen/controller_registration_generator.cjs.map +1 -1
- package/dist/codegen/controller_registration_generator.d.cts +12 -1
- package/dist/codegen/controller_registration_generator.d.ts +12 -1
- package/dist/codegen/controller_registration_generator.js +10 -1
- package/dist/codegen/controller_registration_generator.js.map +1 -1
- package/dist/codegen/index.d.cts +1 -0
- package/dist/codegen/index.d.ts +1 -0
- package/dist/codegen/preload_generator.cjs +13 -6
- package/dist/codegen/preload_generator.cjs.map +1 -1
- package/dist/codegen/preload_generator.d.cts +11 -2
- package/dist/codegen/preload_generator.d.ts +11 -2
- package/dist/codegen/preload_generator.js +13 -6
- package/dist/codegen/preload_generator.js.map +1 -1
- package/dist/codegen/renderer_app_generator.cjs +95 -44
- package/dist/codegen/renderer_app_generator.cjs.map +1 -1
- package/dist/codegen/renderer_app_generator.js +95 -44
- package/dist/codegen/renderer_app_generator.js.map +1 -1
- package/dist/codegen/type_generator.cjs +1 -0
- package/dist/codegen/type_generator.cjs.map +1 -1
- package/dist/codegen/type_generator.js +1 -0
- package/dist/codegen/type_generator.js.map +1 -1
- package/dist/config/config_parser.cjs +95 -4
- package/dist/config/config_parser.cjs.map +1 -1
- package/dist/config/config_parser.d.cts +10 -2
- package/dist/config/config_parser.d.ts +10 -2
- package/dist/config/config_parser.js +92 -3
- package/dist/config/config_parser.js.map +1 -1
- package/dist/config/index.cjs +6 -2
- package/dist/config/index.cjs.map +1 -1
- package/dist/config/index.d.cts +2 -2
- package/dist/config/index.d.ts +2 -2
- package/dist/config/index.js +8 -2
- package/dist/config/index.js.map +1 -1
- package/dist/controller/controller_resolver.cjs +51 -3
- package/dist/controller/controller_resolver.cjs.map +1 -1
- package/dist/controller/controller_resolver.d.cts +27 -4
- package/dist/controller/controller_resolver.d.ts +27 -4
- package/dist/controller/controller_resolver.js +48 -2
- package/dist/controller/controller_resolver.js.map +1 -1
- package/dist/controller/index.cjs +6 -2
- package/dist/controller/index.cjs.map +1 -1
- package/dist/controller/index.d.cts +1 -1
- package/dist/controller/index.d.ts +1 -1
- package/dist/controller/index.js +4 -2
- package/dist/controller/index.js.map +1 -1
- package/dist/dev/wood_dev_server.cjs +4 -1
- package/dist/dev/wood_dev_server.cjs.map +1 -1
- package/dist/dev/wood_dev_server.js +5 -2
- package/dist/dev/wood_dev_server.js.map +1 -1
- package/dist/dev/yaml_watcher.cjs +1 -1
- package/dist/dev/yaml_watcher.cjs.map +1 -1
- package/dist/dev/yaml_watcher.d.cts +4 -0
- package/dist/dev/yaml_watcher.d.ts +4 -0
- package/dist/dev/yaml_watcher.js +1 -1
- package/dist/dev/yaml_watcher.js.map +1 -1
- package/dist/frontend/frontend_lifecycle.cjs +74 -0
- package/dist/frontend/frontend_lifecycle.cjs.map +1 -0
- package/dist/frontend/frontend_lifecycle.d.cts +50 -0
- package/dist/frontend/frontend_lifecycle.d.ts +50 -0
- package/dist/frontend/frontend_lifecycle.js +50 -0
- package/dist/frontend/frontend_lifecycle.js.map +1 -0
- package/dist/frontend/frontend_page.cjs +122 -0
- package/dist/frontend/frontend_page.cjs.map +1 -0
- package/dist/frontend/frontend_page.d.cts +62 -0
- package/dist/frontend/frontend_page.d.ts +62 -0
- package/dist/frontend/frontend_page.js +98 -0
- package/dist/frontend/frontend_page.js.map +1 -0
- package/dist/frontend/frontend_surface.cjs +249 -0
- package/dist/frontend/frontend_surface.cjs.map +1 -0
- package/dist/frontend/frontend_surface.d.cts +64 -0
- package/dist/frontend/frontend_surface.d.ts +64 -0
- package/dist/frontend/frontend_surface.js +224 -0
- package/dist/frontend/frontend_surface.js.map +1 -0
- package/dist/frontend/index.cjs +52 -0
- package/dist/frontend/index.cjs.map +1 -0
- package/dist/frontend/index.d.cts +10 -0
- package/dist/frontend/index.d.ts +10 -0
- package/dist/frontend/index.js +19 -0
- package/dist/frontend/index.js.map +1 -0
- package/dist/frontend/page_catalog.cjs +135 -0
- package/dist/frontend/page_catalog.cjs.map +1 -0
- package/dist/frontend/page_catalog.d.cts +56 -0
- package/dist/frontend/page_catalog.d.ts +56 -0
- package/dist/frontend/page_catalog.js +108 -0
- package/dist/frontend/page_catalog.js.map +1 -0
- package/dist/frontend/tracked_transport.cjs +55 -0
- package/dist/frontend/tracked_transport.cjs.map +1 -0
- package/dist/frontend/tracked_transport.d.cts +36 -0
- package/dist/frontend/tracked_transport.d.ts +36 -0
- package/dist/frontend/tracked_transport.js +31 -0
- package/dist/frontend/tracked_transport.js.map +1 -0
- package/dist/frontend/work_registry.cjs +153 -0
- package/dist/frontend/work_registry.cjs.map +1 -0
- package/dist/frontend/work_registry.d.cts +70 -0
- package/dist/frontend/work_registry.d.ts +70 -0
- package/dist/frontend/work_registry.js +128 -0
- package/dist/frontend/work_registry.js.map +1 -0
- package/dist/index.cjs +24 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +11 -7
- package/dist/index.d.ts +11 -7
- package/dist/index.js +27 -4
- package/dist/index.js.map +1 -1
- package/dist/main/index.cjs +10 -0
- package/dist/main/index.cjs.map +1 -1
- package/dist/main/index.d.cts +14 -2
- package/dist/main/index.d.ts +14 -2
- package/dist/main/index.js +16 -0
- package/dist/main/index.js.map +1 -1
- package/dist/middleware/middleware_resolver.cjs +22 -1
- package/dist/middleware/middleware_resolver.cjs.map +1 -1
- package/dist/middleware/middleware_resolver.d.cts +13 -1
- package/dist/middleware/middleware_resolver.d.ts +13 -1
- package/dist/middleware/middleware_resolver.js +22 -1
- package/dist/middleware/middleware_resolver.js.map +1 -1
- package/dist/navigation/automation_introspection.cjs +110 -0
- package/dist/navigation/automation_introspection.cjs.map +1 -0
- package/dist/navigation/automation_introspection.d.cts +60 -0
- package/dist/navigation/automation_introspection.d.ts +60 -0
- package/dist/navigation/automation_introspection.js +85 -0
- package/dist/navigation/automation_introspection.js.map +1 -0
- package/dist/navigation/index.cjs +10 -2
- package/dist/navigation/index.cjs.map +1 -1
- package/dist/navigation/index.d.cts +27 -1
- package/dist/navigation/index.d.ts +27 -1
- package/dist/navigation/index.js +6 -1
- package/dist/navigation/index.js.map +1 -1
- package/dist/{middleware/__fixtures__/middleware/auth.cjs → navigation/layout_preservation.cjs} +18 -20
- package/dist/navigation/layout_preservation.cjs.map +1 -0
- package/dist/navigation/layout_preservation.d.cts +2 -0
- package/dist/navigation/layout_preservation.d.ts +2 -0
- package/dist/navigation/layout_preservation.js +18 -0
- package/dist/navigation/layout_preservation.js.map +1 -0
- package/dist/parser/index.cjs +2 -0
- package/dist/parser/index.cjs.map +1 -1
- package/dist/parser/index.d.cts +1 -1
- package/dist/parser/index.d.ts +1 -1
- package/dist/parser/index.js +2 -1
- package/dist/parser/index.js.map +1 -1
- package/dist/parser/operations_parser.cjs +6 -0
- package/dist/parser/operations_parser.cjs.map +1 -1
- package/dist/parser/operations_parser.d.cts +9 -2
- package/dist/parser/operations_parser.d.ts +9 -2
- package/dist/parser/operations_parser.js +5 -0
- package/dist/parser/operations_parser.js.map +1 -1
- package/dist/parser/views_parser.cjs.map +1 -1
- package/dist/parser/views_parser.js.map +1 -1
- package/dist/router/index.d.cts +1 -0
- package/dist/router/index.d.ts +1 -0
- package/dist/router/wood_router.cjs +35 -3
- package/dist/router/wood_router.cjs.map +1 -1
- package/dist/router/wood_router.d.cts +15 -0
- package/dist/router/wood_router.d.ts +15 -0
- package/dist/router/wood_router.js +36 -4
- package/dist/router/wood_router.js.map +1 -1
- package/dist/runtime/get_container.cjs +9 -34
- package/dist/runtime/get_container.cjs.map +1 -1
- package/dist/runtime/get_container.d.cts +24 -4
- package/dist/runtime/get_container.d.ts +24 -4
- package/dist/runtime/get_container.js +8 -23
- package/dist/runtime/get_container.js.map +1 -1
- package/dist/runtime/index.cjs +9 -0
- package/dist/runtime/index.cjs.map +1 -1
- package/dist/runtime/index.d.cts +5 -2
- package/dist/runtime/index.d.ts +5 -2
- package/dist/runtime/index.js +10 -1
- package/dist/runtime/index.js.map +1 -1
- package/dist/runtime/renderer_config_extension.cjs +50 -0
- package/dist/runtime/renderer_config_extension.cjs.map +1 -0
- package/dist/runtime/renderer_config_extension.d.cts +19 -0
- package/dist/runtime/renderer_config_extension.d.ts +19 -0
- package/dist/runtime/renderer_config_extension.js +24 -0
- package/dist/runtime/renderer_config_extension.js.map +1 -0
- package/dist/runtime/renderer_log_batch_receiver.cjs +73 -0
- package/dist/runtime/renderer_log_batch_receiver.cjs.map +1 -0
- package/dist/runtime/renderer_log_batch_receiver.d.cts +29 -0
- package/dist/runtime/renderer_log_batch_receiver.d.ts +29 -0
- package/dist/runtime/renderer_log_batch_receiver.js +48 -0
- package/dist/runtime/renderer_log_batch_receiver.js.map +1 -0
- package/dist/runtime/renderer_trace_batch_receiver_registry.d.cts +1 -1
- package/dist/runtime/renderer_trace_batch_receiver_registry.d.ts +1 -1
- package/dist/runtime/runtime.cjs +14 -0
- package/dist/runtime/runtime.cjs.map +1 -1
- package/dist/runtime/runtime.d.cts +2 -1
- package/dist/runtime/runtime.d.ts +2 -1
- package/dist/runtime/runtime.js +14 -0
- package/dist/runtime/runtime.js.map +1 -1
- package/dist/stick/index.cjs.map +1 -1
- package/dist/stick/index.js.map +1 -1
- package/dist/testing/automation_assertions.cjs +417 -0
- package/dist/testing/automation_assertions.cjs.map +1 -0
- package/dist/testing/automation_assertions.d.cts +44 -0
- package/dist/testing/automation_assertions.d.ts +44 -0
- package/dist/testing/automation_assertions.js +385 -0
- package/dist/testing/automation_assertions.js.map +1 -0
- package/dist/testing/browser.cjs +130 -57
- package/dist/testing/browser.cjs.map +1 -1
- package/dist/testing/browser.d.cts +10 -4
- package/dist/testing/browser.d.ts +10 -4
- package/dist/testing/browser.js +132 -53
- package/dist/testing/browser.js.map +1 -1
- package/dist/testing/create_controller_harness.cjs +28 -8
- package/dist/testing/create_controller_harness.cjs.map +1 -1
- package/dist/testing/create_controller_harness.d.cts +18 -2
- package/dist/testing/create_controller_harness.d.ts +18 -2
- package/dist/testing/create_controller_harness.js +28 -8
- package/dist/testing/create_controller_harness.js.map +1 -1
- package/dist/testing/create_router_bridge.d.cts +1 -0
- package/dist/testing/create_router_bridge.d.ts +1 -0
- package/dist/testing/create_test_router.d.cts +1 -0
- package/dist/testing/create_test_router.d.ts +1 -0
- package/dist/testing/geometry.cjs +109 -0
- package/dist/testing/geometry.cjs.map +1 -0
- package/dist/testing/geometry.d.cts +45 -0
- package/dist/testing/geometry.d.ts +45 -0
- package/dist/testing/geometry.js +79 -0
- package/dist/testing/geometry.js.map +1 -0
- package/dist/testing/index.cjs +62 -2
- package/dist/testing/index.cjs.map +1 -1
- package/dist/testing/index.d.cts +23 -4
- package/dist/testing/index.d.ts +23 -4
- package/dist/testing/index.js +50 -2
- package/dist/testing/index.js.map +1 -1
- package/dist/{controller/__fixtures__/controllers/not_a_class.cjs → testing/test_wood.cjs} +15 -7
- package/dist/testing/test_wood.cjs.map +1 -0
- package/dist/testing/test_wood.d.cts +16 -0
- package/dist/testing/test_wood.d.ts +16 -0
- package/dist/testing/test_wood.js +12 -0
- package/dist/testing/test_wood.js.map +1 -0
- package/dist/testing/test_wood_config.cjs +272 -0
- package/dist/testing/test_wood_config.cjs.map +1 -0
- package/dist/testing/test_wood_config.d.cts +111 -0
- package/dist/testing/test_wood_config.d.ts +111 -0
- package/dist/testing/test_wood_config.js +247 -0
- package/dist/testing/test_wood_config.js.map +1 -0
- package/dist/testing/wood_config_source.cjs +146 -0
- package/dist/testing/wood_config_source.cjs.map +1 -0
- package/dist/testing/wood_config_source.d.cts +36 -0
- package/dist/testing/wood_config_source.d.ts +36 -0
- package/dist/testing/wood_config_source.js +112 -0
- package/dist/testing/wood_config_source.js.map +1 -0
- package/dist/testing/wood_env_renderer.cjs +210 -0
- package/dist/testing/wood_env_renderer.cjs.map +1 -0
- package/dist/testing/wood_env_renderer.d.cts +74 -0
- package/dist/testing/wood_env_renderer.d.ts +74 -0
- package/dist/testing/wood_env_renderer.js +188 -0
- package/dist/testing/wood_env_renderer.js.map +1 -0
- package/dist/testing/wood_test_selection.cjs +94 -0
- package/dist/testing/wood_test_selection.cjs.map +1 -0
- package/dist/testing/wood_test_selection.d.cts +39 -0
- package/dist/testing/wood_test_selection.d.ts +39 -0
- package/dist/testing/wood_test_selection.js +68 -0
- package/dist/testing/wood_test_selection.js.map +1 -0
- package/dist/trace-testing/index.d.cts +1 -2
- package/dist/trace-testing/index.d.ts +1 -2
- package/dist/trace-testing/trace_recorder.cjs +1 -1
- package/dist/trace-testing/trace_recorder.cjs.map +1 -1
- package/dist/trace-testing/trace_recorder.d.cts +1 -2
- package/dist/trace-testing/trace_recorder.d.ts +1 -2
- package/dist/trace-testing/trace_recorder.js +1 -1
- package/dist/trace-testing/trace_recorder.js.map +1 -1
- package/dist/trace-transport/index.d.cts +1 -1
- package/dist/trace-transport/index.d.ts +1 -1
- package/dist/{trace_hub-Cob54qRx.d.cts → trace_hub-Cpo_nVze.d.cts} +21 -1
- package/dist/{trace_hub-Cob54qRx.d.ts → trace_hub-Cpo_nVze.d.ts} +21 -1
- package/dist/tracing/index.cjs +9 -2
- package/dist/tracing/index.cjs.map +1 -1
- package/dist/tracing/index.d.cts +3 -2
- package/dist/tracing/index.d.ts +3 -2
- package/dist/tracing/index.js +7 -1
- package/dist/tracing/index.js.map +1 -1
- package/dist/tracing/renderer_trace_batch_host.d.cts +1 -1
- package/dist/tracing/renderer_trace_batch_host.d.ts +1 -1
- package/dist/tracing/renderer_trace_batch_transport.cjs +48 -6
- package/dist/tracing/renderer_trace_batch_transport.cjs.map +1 -1
- package/dist/tracing/renderer_trace_batch_transport.d.cts +17 -1
- package/dist/tracing/renderer_trace_batch_transport.d.ts +17 -1
- package/dist/tracing/renderer_trace_batch_transport.js +48 -6
- package/dist/tracing/renderer_trace_batch_transport.js.map +1 -1
- package/dist/tracing/trace_batch_adapter.cjs +110 -0
- package/dist/tracing/trace_batch_adapter.cjs.map +1 -0
- package/dist/tracing/trace_batch_adapter.d.cts +36 -0
- package/dist/tracing/trace_batch_adapter.d.ts +36 -0
- package/dist/tracing/trace_batch_adapter.js +86 -0
- package/dist/tracing/trace_batch_adapter.js.map +1 -0
- package/dist/tracing/trace_commit_writer.d.cts +1 -1
- package/dist/tracing/trace_commit_writer.d.ts +1 -1
- package/dist/tracing/trace_hub.cjs +87 -20
- package/dist/tracing/trace_hub.cjs.map +1 -1
- package/dist/tracing/trace_hub.d.cts +1 -1
- package/dist/tracing/trace_hub.d.ts +1 -1
- package/dist/tracing/trace_hub.js +85 -20
- package/dist/tracing/trace_hub.js.map +1 -1
- package/dist/tracing/trace_provider.cjs +21 -6
- package/dist/tracing/trace_provider.cjs.map +1 -1
- package/dist/tracing/trace_provider.d.cts +13 -4
- package/dist/tracing/trace_provider.d.ts +13 -4
- package/dist/tracing/trace_provider.js +22 -7
- package/dist/tracing/trace_provider.js.map +1 -1
- package/dist/tracing/types/wood_trace_batch.types.cjs.map +1 -1
- package/dist/tracing/types/wood_trace_batch.types.d.cts +15 -1
- package/dist/tracing/types/wood_trace_batch.types.d.ts +15 -1
- package/dist/tracing/types/wood_trace_sink.types.d.cts +1 -1
- package/dist/tracing/types/wood_trace_sink.types.d.ts +1 -1
- package/dist/tracing/wood_trace_batch_contract.cjs +2 -0
- package/dist/tracing/wood_trace_batch_contract.cjs.map +1 -1
- package/dist/tracing/wood_trace_batch_contract.d.cts +1 -1
- package/dist/tracing/wood_trace_batch_contract.d.ts +1 -1
- package/dist/tracing/wood_trace_batch_contract.js +2 -0
- package/dist/tracing/wood_trace_batch_contract.js.map +1 -1
- package/dist/transport/build_transport_bridge.cjs +4 -2
- package/dist/transport/build_transport_bridge.cjs.map +1 -1
- package/dist/transport/build_transport_bridge.d.cts +7 -1
- package/dist/transport/build_transport_bridge.d.ts +7 -1
- package/dist/transport/build_transport_bridge.js +2 -1
- package/dist/transport/build_transport_bridge.js.map +1 -1
- package/dist/transport/in_process_router_transport.d.cts +1 -0
- package/dist/transport/in_process_router_transport.d.ts +1 -0
- package/dist/transport/index.d.cts +1 -0
- package/dist/transport/index.d.ts +1 -0
- package/dist/types/config.cjs.map +1 -1
- package/dist/types/config.d.cts +47 -1
- package/dist/types/config.d.ts +47 -1
- package/dist/types/context.cjs +12 -0
- package/dist/types/context.cjs.map +1 -1
- package/dist/types/context.d.cts +27 -1
- package/dist/types/context.d.ts +27 -1
- package/dist/types/context.js +4 -0
- package/dist/types/context.js.map +1 -1
- package/dist/types/index.d.cts +2 -2
- package/dist/types/index.d.ts +2 -2
- package/dist/types/operations.cjs.map +1 -1
- package/dist/types/operations.d.cts +2 -0
- package/dist/types/operations.d.ts +2 -0
- package/docs/axe.md +706 -0
- package/package.json +19 -5
- package/src/components/NavigationShell.scopes.browser.test.ts +363 -0
- package/src/components/NavigationShell.svelte +126 -49
- package/dist/controller/__fixtures__/controllers/chat.cjs +0 -32
- package/dist/controller/__fixtures__/controllers/chat.cjs.map +0 -1
- package/dist/controller/__fixtures__/controllers/chat.d.cts +0 -11
- package/dist/controller/__fixtures__/controllers/chat.d.ts +0 -11
- package/dist/controller/__fixtures__/controllers/chat.js +0 -12
- package/dist/controller/__fixtures__/controllers/chat.js.map +0 -1
- package/dist/controller/__fixtures__/controllers/not_a_class.cjs.map +0 -1
- package/dist/controller/__fixtures__/controllers/not_a_class.d.cts +0 -3
- package/dist/controller/__fixtures__/controllers/not_a_class.d.ts +0 -3
- package/dist/controller/__fixtures__/controllers/not_a_class.js +0 -5
- package/dist/controller/__fixtures__/controllers/not_a_class.js.map +0 -1
- package/dist/controller/__fixtures__/controllers/settings.controller.cjs +0 -32
- package/dist/controller/__fixtures__/controllers/settings.controller.cjs.map +0 -1
- package/dist/controller/__fixtures__/controllers/settings.controller.d.cts +0 -12
- package/dist/controller/__fixtures__/controllers/settings.controller.d.ts +0 -12
- package/dist/controller/__fixtures__/controllers/settings.controller.js +0 -12
- package/dist/controller/__fixtures__/controllers/settings.controller.js.map +0 -1
- package/dist/controller/__fixtures__/controllers/test.cjs.map +0 -1
- package/dist/controller/__fixtures__/controllers/test.d.cts +0 -7
- package/dist/controller/__fixtures__/controllers/test.d.ts +0 -7
- package/dist/controller/__fixtures__/controllers/test.js +0 -9
- package/dist/controller/__fixtures__/controllers/test.js.map +0 -1
- package/dist/loader/__fixtures__/layouts/app.load.cjs.map +0 -1
- package/dist/loader/__fixtures__/layouts/app.load.d.cts +0 -5
- package/dist/loader/__fixtures__/layouts/app.load.d.ts +0 -5
- package/dist/loader/__fixtures__/layouts/app.load.js +0 -7
- package/dist/loader/__fixtures__/layouts/app.load.js.map +0 -1
- package/dist/loader/__fixtures__/views/test/page.load.cjs.map +0 -1
- package/dist/loader/__fixtures__/views/test/page.load.d.cts +0 -6
- package/dist/loader/__fixtures__/views/test/page.load.d.ts +0 -6
- package/dist/loader/__fixtures__/views/test/page.load.js +0 -7
- package/dist/loader/__fixtures__/views/test/page.load.js.map +0 -1
- package/dist/middleware/__fixtures__/middleware/auth.cjs.map +0 -1
- package/dist/middleware/__fixtures__/middleware/auth.d.cts +0 -6
- package/dist/middleware/__fixtures__/middleware/auth.d.ts +0 -6
- package/dist/middleware/__fixtures__/middleware/auth.js +0 -19
- package/dist/middleware/__fixtures__/middleware/auth.js.map +0 -1
- package/dist/middleware/__fixtures__/middleware/sequence.cjs.map +0 -1
- package/dist/middleware/__fixtures__/middleware/sequence.d.cts +0 -7
- package/dist/middleware/__fixtures__/middleware/sequence.d.ts +0 -7
- package/dist/middleware/__fixtures__/middleware/sequence.js +0 -21
- package/dist/middleware/__fixtures__/middleware/sequence.js.map +0 -1
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { ViewDef } from '../types/views.cjs';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Renderer page catalog and aperture selection (18A D-FAS-04).
|
|
5
|
+
*
|
|
6
|
+
* Wood's canonical page identity is the existing `window.page` view key
|
|
7
|
+
* (`main.chat_dom`) — the first segment of the views YAML dot path is the
|
|
8
|
+
* window name, the rest the page name. No renderer "module" concept is
|
|
9
|
+
* invented; renderer grouping uses its natural window identity.
|
|
10
|
+
*
|
|
11
|
+
* Selection defines the allowed production page graph. It never chooses
|
|
12
|
+
* the currently open page (`frontend.open` does, explicitly) and it never
|
|
13
|
+
* widens itself: opening or navigating outside the aperture fails with a
|
|
14
|
+
* diagnostic naming the aperture and the fix.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
interface RendererSelection {
|
|
18
|
+
/** Every page belonging to one production window catalog. */
|
|
19
|
+
window?: string;
|
|
20
|
+
/** Exactly one renderer page (canonical `window.page` identity). */
|
|
21
|
+
page?: string;
|
|
22
|
+
/** Explicit pages needed by one flow. */
|
|
23
|
+
pages?: string[];
|
|
24
|
+
}
|
|
25
|
+
declare class PageCatalogError extends Error {
|
|
26
|
+
constructor(message: string);
|
|
27
|
+
}
|
|
28
|
+
declare function pageIdentity(view: ViewDef): string;
|
|
29
|
+
type ViewsSource = string | ViewDef[];
|
|
30
|
+
declare function parseViewsSource(source: ViewsSource): ViewDef[];
|
|
31
|
+
/**
|
|
32
|
+
* The production renderer page catalog: every view keyed by its canonical
|
|
33
|
+
* `window.page` identity, with aperture selection and open/navigation
|
|
34
|
+
* resolution (short leaf names accepted only when unambiguous).
|
|
35
|
+
*/
|
|
36
|
+
declare class PageCatalog {
|
|
37
|
+
private readonly byIdentity;
|
|
38
|
+
constructor(views: ViewDef[]);
|
|
39
|
+
get size(): number;
|
|
40
|
+
all(): ViewDef[];
|
|
41
|
+
/**
|
|
42
|
+
* Apply a renderer aperture selection. Exactly one of `window`, `page`,
|
|
43
|
+
* `pages` must be supplied (they are mutually exclusive in the final
|
|
44
|
+
* effective selection).
|
|
45
|
+
*/
|
|
46
|
+
select(selection: RendererSelection): PageCatalog;
|
|
47
|
+
/**
|
|
48
|
+
* Resolve a page identity for `frontend.open()` or navigation. The
|
|
49
|
+
* canonical `window.page` identity is always accepted; a short leaf name
|
|
50
|
+
* is accepted only when exactly one selected page has that leaf.
|
|
51
|
+
*/
|
|
52
|
+
resolve(page: string): ViewDef;
|
|
53
|
+
has(identity: string): boolean;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export { PageCatalog, PageCatalogError, type RendererSelection, type ViewsSource, pageIdentity, parseViewsSource };
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { ViewDef } from '../types/views.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Renderer page catalog and aperture selection (18A D-FAS-04).
|
|
5
|
+
*
|
|
6
|
+
* Wood's canonical page identity is the existing `window.page` view key
|
|
7
|
+
* (`main.chat_dom`) — the first segment of the views YAML dot path is the
|
|
8
|
+
* window name, the rest the page name. No renderer "module" concept is
|
|
9
|
+
* invented; renderer grouping uses its natural window identity.
|
|
10
|
+
*
|
|
11
|
+
* Selection defines the allowed production page graph. It never chooses
|
|
12
|
+
* the currently open page (`frontend.open` does, explicitly) and it never
|
|
13
|
+
* widens itself: opening or navigating outside the aperture fails with a
|
|
14
|
+
* diagnostic naming the aperture and the fix.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
interface RendererSelection {
|
|
18
|
+
/** Every page belonging to one production window catalog. */
|
|
19
|
+
window?: string;
|
|
20
|
+
/** Exactly one renderer page (canonical `window.page` identity). */
|
|
21
|
+
page?: string;
|
|
22
|
+
/** Explicit pages needed by one flow. */
|
|
23
|
+
pages?: string[];
|
|
24
|
+
}
|
|
25
|
+
declare class PageCatalogError extends Error {
|
|
26
|
+
constructor(message: string);
|
|
27
|
+
}
|
|
28
|
+
declare function pageIdentity(view: ViewDef): string;
|
|
29
|
+
type ViewsSource = string | ViewDef[];
|
|
30
|
+
declare function parseViewsSource(source: ViewsSource): ViewDef[];
|
|
31
|
+
/**
|
|
32
|
+
* The production renderer page catalog: every view keyed by its canonical
|
|
33
|
+
* `window.page` identity, with aperture selection and open/navigation
|
|
34
|
+
* resolution (short leaf names accepted only when unambiguous).
|
|
35
|
+
*/
|
|
36
|
+
declare class PageCatalog {
|
|
37
|
+
private readonly byIdentity;
|
|
38
|
+
constructor(views: ViewDef[]);
|
|
39
|
+
get size(): number;
|
|
40
|
+
all(): ViewDef[];
|
|
41
|
+
/**
|
|
42
|
+
* Apply a renderer aperture selection. Exactly one of `window`, `page`,
|
|
43
|
+
* `pages` must be supplied (they are mutually exclusive in the final
|
|
44
|
+
* effective selection).
|
|
45
|
+
*/
|
|
46
|
+
select(selection: RendererSelection): PageCatalog;
|
|
47
|
+
/**
|
|
48
|
+
* Resolve a page identity for `frontend.open()` or navigation. The
|
|
49
|
+
* canonical `window.page` identity is always accepted; a short leaf name
|
|
50
|
+
* is accepted only when exactly one selected page has that leaf.
|
|
51
|
+
*/
|
|
52
|
+
resolve(page: string): ViewDef;
|
|
53
|
+
has(identity: string): boolean;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export { PageCatalog, PageCatalogError, type RendererSelection, type ViewsSource, pageIdentity, parseViewsSource };
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { parseViews } from "../parser/views_parser.js";
|
|
2
|
+
class PageCatalogError extends Error {
|
|
3
|
+
constructor(message) {
|
|
4
|
+
super(message);
|
|
5
|
+
this.name = "PageCatalogError";
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
function pageIdentity(view) {
|
|
9
|
+
return `${view.windowName}.${view.pageName}`;
|
|
10
|
+
}
|
|
11
|
+
function listIdentities(views) {
|
|
12
|
+
const identities = [...views].map(pageIdentity);
|
|
13
|
+
if (!identities.length) return "the source defines no views";
|
|
14
|
+
return `available pages:
|
|
15
|
+
${identities.join("\n ")}`;
|
|
16
|
+
}
|
|
17
|
+
function parseViewsSource(source) {
|
|
18
|
+
if (Array.isArray(source)) return source;
|
|
19
|
+
if (typeof source === "string") return parseViews(source);
|
|
20
|
+
throw new PageCatalogError("views must be YAML content or parsed ViewDef[]");
|
|
21
|
+
}
|
|
22
|
+
class PageCatalog {
|
|
23
|
+
constructor(views) {
|
|
24
|
+
this.byIdentity = /* @__PURE__ */ new Map();
|
|
25
|
+
for (const view of views) {
|
|
26
|
+
const identity = pageIdentity(view);
|
|
27
|
+
if (this.byIdentity.has(identity)) {
|
|
28
|
+
throw new PageCatalogError(`duplicate page identity "${identity}" in views source`);
|
|
29
|
+
}
|
|
30
|
+
this.byIdentity.set(identity, view);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
get size() {
|
|
34
|
+
return this.byIdentity.size;
|
|
35
|
+
}
|
|
36
|
+
all() {
|
|
37
|
+
return [...this.byIdentity.values()];
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Apply a renderer aperture selection. Exactly one of `window`, `page`,
|
|
41
|
+
* `pages` must be supplied (they are mutually exclusive in the final
|
|
42
|
+
* effective selection).
|
|
43
|
+
*/
|
|
44
|
+
select(selection) {
|
|
45
|
+
const forms = ["window", "page", "pages"].filter(
|
|
46
|
+
(key) => selection[key] !== void 0
|
|
47
|
+
);
|
|
48
|
+
if (forms.length !== 1) {
|
|
49
|
+
throw new PageCatalogError(
|
|
50
|
+
"renderer selection requires exactly one of { window }, { page }, or { pages }" + (forms.length ? `; got: ${forms.join(", ")}` : "")
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
if (selection.window !== void 0) {
|
|
54
|
+
const matched2 = this.all().filter((view) => view.windowName === selection.window);
|
|
55
|
+
if (!matched2.length) {
|
|
56
|
+
const windows = [...new Set(this.all().map((view) => view.windowName))];
|
|
57
|
+
throw new PageCatalogError(
|
|
58
|
+
`unknown window "${selection.window}"; ` + (windows.length ? `available windows: ${windows.join(", ")}` : "the source defines no views")
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
return new PageCatalog(matched2);
|
|
62
|
+
}
|
|
63
|
+
const requested = selection.page !== void 0 ? [selection.page] : selection.pages;
|
|
64
|
+
if (!requested.length) {
|
|
65
|
+
throw new PageCatalogError("renderer selection { pages } requires at least one page identity");
|
|
66
|
+
}
|
|
67
|
+
const matched = requested.map((identity) => {
|
|
68
|
+
const view = this.byIdentity.get(identity);
|
|
69
|
+
if (!view) {
|
|
70
|
+
throw new PageCatalogError(
|
|
71
|
+
`unknown page "${identity}"; ${listIdentities(this.byIdentity.values())}`
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
return view;
|
|
75
|
+
});
|
|
76
|
+
return new PageCatalog(matched);
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Resolve a page identity for `frontend.open()` or navigation. The
|
|
80
|
+
* canonical `window.page` identity is always accepted; a short leaf name
|
|
81
|
+
* is accepted only when exactly one selected page has that leaf.
|
|
82
|
+
*/
|
|
83
|
+
resolve(page) {
|
|
84
|
+
const exact = this.byIdentity.get(page);
|
|
85
|
+
if (exact) return exact;
|
|
86
|
+
const leafMatches = this.all().filter((view) => view.pageName === page);
|
|
87
|
+
if (leafMatches.length === 1) return leafMatches[0];
|
|
88
|
+
if (leafMatches.length > 1) {
|
|
89
|
+
throw new PageCatalogError(
|
|
90
|
+
`page "${page}" is ambiguous in the selected aperture; use a fully qualified identity: ` + leafMatches.map(pageIdentity).join(", ")
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
throw new PageCatalogError(
|
|
94
|
+
`page "${page}" is not in the selected aperture; ${listIdentities(this.byIdentity.values())}
|
|
95
|
+
Widen the selection with select({ renderer: { window | pages } }) if this navigation is intentional.`
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
has(identity) {
|
|
99
|
+
return this.byIdentity.has(identity);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
export {
|
|
103
|
+
PageCatalog,
|
|
104
|
+
PageCatalogError,
|
|
105
|
+
pageIdentity,
|
|
106
|
+
parseViewsSource
|
|
107
|
+
};
|
|
108
|
+
//# sourceMappingURL=page_catalog.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/frontend/page_catalog.ts"],"sourcesContent":["/**\n * Renderer page catalog and aperture selection (18A D-FAS-04).\n *\n * Wood's canonical page identity is the existing `window.page` view key\n * (`main.chat_dom`) — the first segment of the views YAML dot path is the\n * window name, the rest the page name. No renderer \"module\" concept is\n * invented; renderer grouping uses its natural window identity.\n *\n * Selection defines the allowed production page graph. It never chooses\n * the currently open page (`frontend.open` does, explicitly) and it never\n * widens itself: opening or navigating outside the aperture fails with a\n * diagnostic naming the aperture and the fix.\n */\nimport type { ViewDef } from '../types/index.js';\nimport { parseViews } from '../parser/views_parser.js';\n\nexport interface RendererSelection {\n /** Every page belonging to one production window catalog. */\n window?: string;\n /** Exactly one renderer page (canonical `window.page` identity). */\n page?: string;\n /** Explicit pages needed by one flow. */\n pages?: string[];\n}\n\nexport class PageCatalogError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'PageCatalogError';\n }\n}\n\nexport function pageIdentity(view: ViewDef): string {\n return `${view.windowName}.${view.pageName}`;\n}\n\nfunction listIdentities(views: Iterable<ViewDef>): string {\n const identities = [...views].map(pageIdentity);\n if (!identities.length) return 'the source defines no views';\n return `available pages:\\n ${identities.join('\\n ')}`;\n}\n\nexport type ViewsSource = string | ViewDef[];\n\nexport function parseViewsSource(source: ViewsSource): ViewDef[] {\n if (Array.isArray(source)) return source;\n if (typeof source === 'string') return parseViews(source);\n throw new PageCatalogError('views must be YAML content or parsed ViewDef[]');\n}\n\n/**\n * The production renderer page catalog: every view keyed by its canonical\n * `window.page` identity, with aperture selection and open/navigation\n * resolution (short leaf names accepted only when unambiguous).\n */\nexport class PageCatalog {\n private readonly byIdentity = new Map<string, ViewDef>();\n\n constructor(views: ViewDef[]) {\n for (const view of views) {\n const identity = pageIdentity(view);\n if (this.byIdentity.has(identity)) {\n throw new PageCatalogError(`duplicate page identity \"${identity}\" in views source`);\n }\n this.byIdentity.set(identity, view);\n }\n }\n\n get size(): number {\n return this.byIdentity.size;\n }\n\n all(): ViewDef[] {\n return [...this.byIdentity.values()];\n }\n\n /**\n * Apply a renderer aperture selection. Exactly one of `window`, `page`,\n * `pages` must be supplied (they are mutually exclusive in the final\n * effective selection).\n */\n select(selection: RendererSelection): PageCatalog {\n const forms = (['window', 'page', 'pages'] as const).filter(\n (key) => selection[key] !== undefined,\n );\n if (forms.length !== 1) {\n throw new PageCatalogError(\n 'renderer selection requires exactly one of { window }, { page }, or { pages }' +\n (forms.length ? `; got: ${forms.join(', ')}` : ''),\n );\n }\n\n if (selection.window !== undefined) {\n const matched = this.all().filter((view) => view.windowName === selection.window);\n if (!matched.length) {\n const windows = [...new Set(this.all().map((view) => view.windowName))];\n throw new PageCatalogError(\n `unknown window \"${selection.window}\"; ` +\n (windows.length ? `available windows: ${windows.join(', ')}` : 'the source defines no views'),\n );\n }\n return new PageCatalog(matched);\n }\n\n const requested = selection.page !== undefined ? [selection.page] : selection.pages!;\n if (!requested.length) {\n throw new PageCatalogError('renderer selection { pages } requires at least one page identity');\n }\n const matched = requested.map((identity) => {\n const view = this.byIdentity.get(identity);\n if (!view) {\n throw new PageCatalogError(\n `unknown page \"${identity}\"; ${listIdentities(this.byIdentity.values())}`,\n );\n }\n return view;\n });\n return new PageCatalog(matched);\n }\n\n /**\n * Resolve a page identity for `frontend.open()` or navigation. The\n * canonical `window.page` identity is always accepted; a short leaf name\n * is accepted only when exactly one selected page has that leaf.\n */\n resolve(page: string): ViewDef {\n const exact = this.byIdentity.get(page);\n if (exact) return exact;\n\n const leafMatches = this.all().filter((view) => view.pageName === page);\n if (leafMatches.length === 1) return leafMatches[0];\n if (leafMatches.length > 1) {\n throw new PageCatalogError(\n `page \"${page}\" is ambiguous in the selected aperture; use a fully qualified identity: ` +\n leafMatches.map(pageIdentity).join(', '),\n );\n }\n\n throw new PageCatalogError(\n `page \"${page}\" is not in the selected aperture; ${listIdentities(this.byIdentity.values())}\\n` +\n 'Widen the selection with select({ renderer: { window | pages } }) if this navigation is intentional.',\n );\n }\n\n has(identity: string): boolean {\n return this.byIdentity.has(identity);\n }\n}\n"],"mappings":"AAcA,SAAS,kBAAkB;AAWpB,MAAM,yBAAyB,MAAM;AAAA,EAC1C,YAAY,SAAiB;AAC3B,UAAM,OAAO;AACb,SAAK,OAAO;AAAA,EACd;AACF;AAEO,SAAS,aAAa,MAAuB;AAClD,SAAO,GAAG,KAAK,UAAU,IAAI,KAAK,QAAQ;AAC5C;AAEA,SAAS,eAAe,OAAkC;AACxD,QAAM,aAAa,CAAC,GAAG,KAAK,EAAE,IAAI,YAAY;AAC9C,MAAI,CAAC,WAAW,OAAQ,QAAO;AAC/B,SAAO;AAAA,IAAuB,WAAW,KAAK,MAAM,CAAC;AACvD;AAIO,SAAS,iBAAiB,QAAgC;AAC/D,MAAI,MAAM,QAAQ,MAAM,EAAG,QAAO;AAClC,MAAI,OAAO,WAAW,SAAU,QAAO,WAAW,MAAM;AACxD,QAAM,IAAI,iBAAiB,gDAAgD;AAC7E;AAOO,MAAM,YAAY;AAAA,EAGvB,YAAY,OAAkB;AAF9B,SAAiB,aAAa,oBAAI,IAAqB;AAGrD,eAAW,QAAQ,OAAO;AACxB,YAAM,WAAW,aAAa,IAAI;AAClC,UAAI,KAAK,WAAW,IAAI,QAAQ,GAAG;AACjC,cAAM,IAAI,iBAAiB,4BAA4B,QAAQ,mBAAmB;AAAA,MACpF;AACA,WAAK,WAAW,IAAI,UAAU,IAAI;AAAA,IACpC;AAAA,EACF;AAAA,EAEA,IAAI,OAAe;AACjB,WAAO,KAAK,WAAW;AAAA,EACzB;AAAA,EAEA,MAAiB;AACf,WAAO,CAAC,GAAG,KAAK,WAAW,OAAO,CAAC;AAAA,EACrC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,OAAO,WAA2C;AAChD,UAAM,QAAS,CAAC,UAAU,QAAQ,OAAO,EAAY;AAAA,MACnD,CAAC,QAAQ,UAAU,GAAG,MAAM;AAAA,IAC9B;AACA,QAAI,MAAM,WAAW,GAAG;AACtB,YAAM,IAAI;AAAA,QACR,mFACC,MAAM,SAAS,UAAU,MAAM,KAAK,IAAI,CAAC,KAAK;AAAA,MACjD;AAAA,IACF;AAEA,QAAI,UAAU,WAAW,QAAW;AAClC,YAAMA,WAAU,KAAK,IAAI,EAAE,OAAO,CAAC,SAAS,KAAK,eAAe,UAAU,MAAM;AAChF,UAAI,CAACA,SAAQ,QAAQ;AACnB,cAAM,UAAU,CAAC,GAAG,IAAI,IAAI,KAAK,IAAI,EAAE,IAAI,CAAC,SAAS,KAAK,UAAU,CAAC,CAAC;AACtE,cAAM,IAAI;AAAA,UACR,mBAAmB,UAAU,MAAM,SAClC,QAAQ,SAAS,sBAAsB,QAAQ,KAAK,IAAI,CAAC,KAAK;AAAA,QACjE;AAAA,MACF;AACA,aAAO,IAAI,YAAYA,QAAO;AAAA,IAChC;AAEA,UAAM,YAAY,UAAU,SAAS,SAAY,CAAC,UAAU,IAAI,IAAI,UAAU;AAC9E,QAAI,CAAC,UAAU,QAAQ;AACrB,YAAM,IAAI,iBAAiB,kEAAkE;AAAA,IAC/F;AACA,UAAM,UAAU,UAAU,IAAI,CAAC,aAAa;AAC1C,YAAM,OAAO,KAAK,WAAW,IAAI,QAAQ;AACzC,UAAI,CAAC,MAAM;AACT,cAAM,IAAI;AAAA,UACR,iBAAiB,QAAQ,MAAM,eAAe,KAAK,WAAW,OAAO,CAAC,CAAC;AAAA,QACzE;AAAA,MACF;AACA,aAAO;AAAA,IACT,CAAC;AACD,WAAO,IAAI,YAAY,OAAO;AAAA,EAChC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,QAAQ,MAAuB;AAC7B,UAAM,QAAQ,KAAK,WAAW,IAAI,IAAI;AACtC,QAAI,MAAO,QAAO;AAElB,UAAM,cAAc,KAAK,IAAI,EAAE,OAAO,CAAC,SAAS,KAAK,aAAa,IAAI;AACtE,QAAI,YAAY,WAAW,EAAG,QAAO,YAAY,CAAC;AAClD,QAAI,YAAY,SAAS,GAAG;AAC1B,YAAM,IAAI;AAAA,QACR,SAAS,IAAI,8EACb,YAAY,IAAI,YAAY,EAAE,KAAK,IAAI;AAAA,MACzC;AAAA,IACF;AAEA,UAAM,IAAI;AAAA,MACR,SAAS,IAAI,sCAAsC,eAAe,KAAK,WAAW,OAAO,CAAC,CAAC;AAAA;AAAA,IAE7F;AAAA,EACF;AAAA,EAEA,IAAI,UAA2B;AAC7B,WAAO,KAAK,WAAW,IAAI,QAAQ;AAAA,EACrC;AACF;","names":["matched"]}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var tracked_transport_exports = {};
|
|
20
|
+
__export(tracked_transport_exports, {
|
|
21
|
+
TrackedTransport: () => TrackedTransport
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(tracked_transport_exports);
|
|
24
|
+
class TrackedTransport {
|
|
25
|
+
constructor(inner, registry, currentOwner) {
|
|
26
|
+
this.inner = inner;
|
|
27
|
+
this.registry = registry;
|
|
28
|
+
this.currentOwner = currentOwner;
|
|
29
|
+
}
|
|
30
|
+
invoke(channel, payload) {
|
|
31
|
+
return this.registry.track(this.inner.invoke(channel, payload), {
|
|
32
|
+
label: `invoke ${channel}`,
|
|
33
|
+
kind: "invoke",
|
|
34
|
+
owner: this.currentOwner()
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
subscribe(channel, listener) {
|
|
38
|
+
const owner = this.currentOwner();
|
|
39
|
+
return this.inner.subscribe(channel, (payload) => {
|
|
40
|
+
const result = listener(payload);
|
|
41
|
+
if (result && typeof result.then === "function") {
|
|
42
|
+
this.registry.track(result, {
|
|
43
|
+
label: `event ${channel}`,
|
|
44
|
+
kind: "event-delivery",
|
|
45
|
+
owner
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
52
|
+
0 && (module.exports = {
|
|
53
|
+
TrackedTransport
|
|
54
|
+
});
|
|
55
|
+
//# sourceMappingURL=tracked_transport.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/frontend/tracked_transport.ts"],"sourcesContent":["/**\n * Work-tracking decorator over any `WoodRpcTransport` (18A D-FAS-01 §2.2).\n *\n * Every client invocation registers finite owned work at the transport seam;\n * every queued event delivery to a frontend listener is finite owned work\n * (promise-returning listeners are awaited). A subscription itself is a\n * resident resource — it never blocks settling and is removed when the\n * owning page/application lifecycle ends.\n *\n * This is a wrapper, not a modification: `InProcessRouterTransport` and the\n * shared bridge builders are untouched, so existing harness users see no\n * behavior change.\n *\n * Honesty note: backend work that continues after `invoke` resolves (e.g. a\n * stream emitting after the dispatch returned) is only observable when its\n * emissions arrive as tracked event deliveries. `settle()` drains queued\n * deliveries; it does not claim to await a backend's private timeline —\n * tests script the external boundary or await a terminal event.\n */\nimport type { WoodRpcTransport } from '../transport/wood_rpc_transport.js';\nimport type { WorkRegistry } from './work_registry.js';\n\nexport class TrackedTransport implements WoodRpcTransport {\n constructor(\n private readonly inner: WoodRpcTransport,\n private readonly registry: WorkRegistry,\n /** Captures the owning lifecycle identity at call/subscription time. */\n private readonly currentOwner: () => string,\n ) {}\n\n invoke(channel: string, payload?: unknown): Promise<unknown> {\n return this.registry.track(this.inner.invoke(channel, payload), {\n label: `invoke ${channel}`,\n kind: 'invoke',\n owner: this.currentOwner(),\n });\n }\n\n subscribe(channel: string, listener: (payload: unknown) => void): () => void {\n // Owner is fixed at subscription time: deliveries belong to the\n // subscribing page, not to whichever context happens to be active\n // when the backend pushes.\n const owner = this.currentOwner();\n return this.inner.subscribe(channel, (payload) => {\n // Deliver SYNCHRONOUSLY — identical to the production bridge path.\n // Deferring delivery to a microtask would reorder produce/consume\n // loops the product paces at the event seam. Only an asynchronous\n // continuation (a promise-returning listener) becomes tracked work.\n const result = listener(payload) as unknown;\n if (result && typeof (result as Promise<unknown>).then === 'function') {\n this.registry.track(result as Promise<unknown>, {\n label: `event ${channel}`,\n kind: 'event-delivery',\n owner,\n });\n }\n });\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAsBO,MAAM,iBAA6C;AAAA,EACxD,YACmB,OACA,UAEA,cACjB;AAJiB;AACA;AAEA;AAAA,EAChB;AAAA,EAEH,OAAO,SAAiB,SAAqC;AAC3D,WAAO,KAAK,SAAS,MAAM,KAAK,MAAM,OAAO,SAAS,OAAO,GAAG;AAAA,MAC9D,OAAO,UAAU,OAAO;AAAA,MACxB,MAAM;AAAA,MACN,OAAO,KAAK,aAAa;AAAA,IAC3B,CAAC;AAAA,EACH;AAAA,EAEA,UAAU,SAAiB,UAAkD;AAI3E,UAAM,QAAQ,KAAK,aAAa;AAChC,WAAO,KAAK,MAAM,UAAU,SAAS,CAAC,YAAY;AAKhD,YAAM,SAAS,SAAS,OAAO;AAC/B,UAAI,UAAU,OAAQ,OAA4B,SAAS,YAAY;AACrE,aAAK,SAAS,MAAM,QAA4B;AAAA,UAC9C,OAAO,SAAS,OAAO;AAAA,UACvB,MAAM;AAAA,UACN;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF,CAAC;AAAA,EACH;AACF;","names":[]}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { WoodRpcTransport } from '../transport/wood_rpc_transport.cjs';
|
|
2
|
+
import { WorkRegistry } from './work_registry.cjs';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Work-tracking decorator over any `WoodRpcTransport` (18A D-FAS-01 §2.2).
|
|
6
|
+
*
|
|
7
|
+
* Every client invocation registers finite owned work at the transport seam;
|
|
8
|
+
* every queued event delivery to a frontend listener is finite owned work
|
|
9
|
+
* (promise-returning listeners are awaited). A subscription itself is a
|
|
10
|
+
* resident resource — it never blocks settling and is removed when the
|
|
11
|
+
* owning page/application lifecycle ends.
|
|
12
|
+
*
|
|
13
|
+
* This is a wrapper, not a modification: `InProcessRouterTransport` and the
|
|
14
|
+
* shared bridge builders are untouched, so existing harness users see no
|
|
15
|
+
* behavior change.
|
|
16
|
+
*
|
|
17
|
+
* Honesty note: backend work that continues after `invoke` resolves (e.g. a
|
|
18
|
+
* stream emitting after the dispatch returned) is only observable when its
|
|
19
|
+
* emissions arrive as tracked event deliveries. `settle()` drains queued
|
|
20
|
+
* deliveries; it does not claim to await a backend's private timeline —
|
|
21
|
+
* tests script the external boundary or await a terminal event.
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
declare class TrackedTransport implements WoodRpcTransport {
|
|
25
|
+
private readonly inner;
|
|
26
|
+
private readonly registry;
|
|
27
|
+
/** Captures the owning lifecycle identity at call/subscription time. */
|
|
28
|
+
private readonly currentOwner;
|
|
29
|
+
constructor(inner: WoodRpcTransport, registry: WorkRegistry,
|
|
30
|
+
/** Captures the owning lifecycle identity at call/subscription time. */
|
|
31
|
+
currentOwner: () => string);
|
|
32
|
+
invoke(channel: string, payload?: unknown): Promise<unknown>;
|
|
33
|
+
subscribe(channel: string, listener: (payload: unknown) => void): () => void;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export { TrackedTransport };
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { WoodRpcTransport } from '../transport/wood_rpc_transport.js';
|
|
2
|
+
import { WorkRegistry } from './work_registry.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Work-tracking decorator over any `WoodRpcTransport` (18A D-FAS-01 §2.2).
|
|
6
|
+
*
|
|
7
|
+
* Every client invocation registers finite owned work at the transport seam;
|
|
8
|
+
* every queued event delivery to a frontend listener is finite owned work
|
|
9
|
+
* (promise-returning listeners are awaited). A subscription itself is a
|
|
10
|
+
* resident resource — it never blocks settling and is removed when the
|
|
11
|
+
* owning page/application lifecycle ends.
|
|
12
|
+
*
|
|
13
|
+
* This is a wrapper, not a modification: `InProcessRouterTransport` and the
|
|
14
|
+
* shared bridge builders are untouched, so existing harness users see no
|
|
15
|
+
* behavior change.
|
|
16
|
+
*
|
|
17
|
+
* Honesty note: backend work that continues after `invoke` resolves (e.g. a
|
|
18
|
+
* stream emitting after the dispatch returned) is only observable when its
|
|
19
|
+
* emissions arrive as tracked event deliveries. `settle()` drains queued
|
|
20
|
+
* deliveries; it does not claim to await a backend's private timeline —
|
|
21
|
+
* tests script the external boundary or await a terminal event.
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
declare class TrackedTransport implements WoodRpcTransport {
|
|
25
|
+
private readonly inner;
|
|
26
|
+
private readonly registry;
|
|
27
|
+
/** Captures the owning lifecycle identity at call/subscription time. */
|
|
28
|
+
private readonly currentOwner;
|
|
29
|
+
constructor(inner: WoodRpcTransport, registry: WorkRegistry,
|
|
30
|
+
/** Captures the owning lifecycle identity at call/subscription time. */
|
|
31
|
+
currentOwner: () => string);
|
|
32
|
+
invoke(channel: string, payload?: unknown): Promise<unknown>;
|
|
33
|
+
subscribe(channel: string, listener: (payload: unknown) => void): () => void;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export { TrackedTransport };
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
class TrackedTransport {
|
|
2
|
+
constructor(inner, registry, currentOwner) {
|
|
3
|
+
this.inner = inner;
|
|
4
|
+
this.registry = registry;
|
|
5
|
+
this.currentOwner = currentOwner;
|
|
6
|
+
}
|
|
7
|
+
invoke(channel, payload) {
|
|
8
|
+
return this.registry.track(this.inner.invoke(channel, payload), {
|
|
9
|
+
label: `invoke ${channel}`,
|
|
10
|
+
kind: "invoke",
|
|
11
|
+
owner: this.currentOwner()
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
subscribe(channel, listener) {
|
|
15
|
+
const owner = this.currentOwner();
|
|
16
|
+
return this.inner.subscribe(channel, (payload) => {
|
|
17
|
+
const result = listener(payload);
|
|
18
|
+
if (result && typeof result.then === "function") {
|
|
19
|
+
this.registry.track(result, {
|
|
20
|
+
label: `event ${channel}`,
|
|
21
|
+
kind: "event-delivery",
|
|
22
|
+
owner
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
export {
|
|
29
|
+
TrackedTransport
|
|
30
|
+
};
|
|
31
|
+
//# sourceMappingURL=tracked_transport.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/frontend/tracked_transport.ts"],"sourcesContent":["/**\n * Work-tracking decorator over any `WoodRpcTransport` (18A D-FAS-01 §2.2).\n *\n * Every client invocation registers finite owned work at the transport seam;\n * every queued event delivery to a frontend listener is finite owned work\n * (promise-returning listeners are awaited). A subscription itself is a\n * resident resource — it never blocks settling and is removed when the\n * owning page/application lifecycle ends.\n *\n * This is a wrapper, not a modification: `InProcessRouterTransport` and the\n * shared bridge builders are untouched, so existing harness users see no\n * behavior change.\n *\n * Honesty note: backend work that continues after `invoke` resolves (e.g. a\n * stream emitting after the dispatch returned) is only observable when its\n * emissions arrive as tracked event deliveries. `settle()` drains queued\n * deliveries; it does not claim to await a backend's private timeline —\n * tests script the external boundary or await a terminal event.\n */\nimport type { WoodRpcTransport } from '../transport/wood_rpc_transport.js';\nimport type { WorkRegistry } from './work_registry.js';\n\nexport class TrackedTransport implements WoodRpcTransport {\n constructor(\n private readonly inner: WoodRpcTransport,\n private readonly registry: WorkRegistry,\n /** Captures the owning lifecycle identity at call/subscription time. */\n private readonly currentOwner: () => string,\n ) {}\n\n invoke(channel: string, payload?: unknown): Promise<unknown> {\n return this.registry.track(this.inner.invoke(channel, payload), {\n label: `invoke ${channel}`,\n kind: 'invoke',\n owner: this.currentOwner(),\n });\n }\n\n subscribe(channel: string, listener: (payload: unknown) => void): () => void {\n // Owner is fixed at subscription time: deliveries belong to the\n // subscribing page, not to whichever context happens to be active\n // when the backend pushes.\n const owner = this.currentOwner();\n return this.inner.subscribe(channel, (payload) => {\n // Deliver SYNCHRONOUSLY — identical to the production bridge path.\n // Deferring delivery to a microtask would reorder produce/consume\n // loops the product paces at the event seam. Only an asynchronous\n // continuation (a promise-returning listener) becomes tracked work.\n const result = listener(payload) as unknown;\n if (result && typeof (result as Promise<unknown>).then === 'function') {\n this.registry.track(result as Promise<unknown>, {\n label: `event ${channel}`,\n kind: 'event-delivery',\n owner,\n });\n }\n });\n }\n}\n"],"mappings":"AAsBO,MAAM,iBAA6C;AAAA,EACxD,YACmB,OACA,UAEA,cACjB;AAJiB;AACA;AAEA;AAAA,EAChB;AAAA,EAEH,OAAO,SAAiB,SAAqC;AAC3D,WAAO,KAAK,SAAS,MAAM,KAAK,MAAM,OAAO,SAAS,OAAO,GAAG;AAAA,MAC9D,OAAO,UAAU,OAAO;AAAA,MACxB,MAAM;AAAA,MACN,OAAO,KAAK,aAAa;AAAA,IAC3B,CAAC;AAAA,EACH;AAAA,EAEA,UAAU,SAAiB,UAAkD;AAI3E,UAAM,QAAQ,KAAK,aAAa;AAChC,WAAO,KAAK,MAAM,UAAU,SAAS,CAAC,YAAY;AAKhD,YAAM,SAAS,SAAS,OAAO;AAC/B,UAAI,UAAU,OAAQ,OAA4B,SAAS,YAAY;AACrE,aAAK,SAAS,MAAM,QAA4B;AAAA,UAC9C,OAAO,SAAS,OAAO;AAAA,UACvB,MAAM;AAAA,UACN;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF,CAAC;AAAA,EACH;AACF;","names":[]}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var work_registry_exports = {};
|
|
20
|
+
__export(work_registry_exports, {
|
|
21
|
+
FrontendWorkError: () => FrontendWorkError,
|
|
22
|
+
WorkRegistry: () => WorkRegistry
|
|
23
|
+
});
|
|
24
|
+
module.exports = __toCommonJS(work_registry_exports);
|
|
25
|
+
const MAX_DRAIN_PASSES = 100;
|
|
26
|
+
class FrontendWorkError extends Error {
|
|
27
|
+
constructor(message, failures = []) {
|
|
28
|
+
super(message);
|
|
29
|
+
this.failures = failures;
|
|
30
|
+
this.name = "FrontendWorkError";
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
function describe(work) {
|
|
34
|
+
return `[${work.kind}] ${work.label} (owner: ${work.owner})`;
|
|
35
|
+
}
|
|
36
|
+
class WorkRegistry {
|
|
37
|
+
constructor() {
|
|
38
|
+
this.nextId = 1;
|
|
39
|
+
/** Total registrations ever — the fixed-point signal for draining. */
|
|
40
|
+
this.registrations = 0;
|
|
41
|
+
this.inFlight = /* @__PURE__ */ new Map();
|
|
42
|
+
this.failures = [];
|
|
43
|
+
/** How many failures a completed drain has already reported. */
|
|
44
|
+
this.reportedFailures = 0;
|
|
45
|
+
this.drainChain = Promise.resolve();
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Register finite owned work. Returns a promise with the work's own
|
|
49
|
+
* settlement semantics — callers may await it directly; the registry
|
|
50
|
+
* additionally observes completion (success or failure) for draining.
|
|
51
|
+
*/
|
|
52
|
+
track(work, options) {
|
|
53
|
+
const descriptor = {
|
|
54
|
+
id: this.nextId++,
|
|
55
|
+
label: options.label,
|
|
56
|
+
kind: options.kind ?? "tracked",
|
|
57
|
+
owner: options.owner ?? "application"
|
|
58
|
+
};
|
|
59
|
+
this.registrations += 1;
|
|
60
|
+
const promise = typeof work === "function" ? work() : work;
|
|
61
|
+
const observed = promise.then(
|
|
62
|
+
() => void 0,
|
|
63
|
+
(error) => {
|
|
64
|
+
this.failures.push({ ...descriptor, error });
|
|
65
|
+
}
|
|
66
|
+
).finally(() => {
|
|
67
|
+
this.inFlight.delete(descriptor.id);
|
|
68
|
+
});
|
|
69
|
+
this.inFlight.set(descriptor.id, { descriptor, observed });
|
|
70
|
+
return promise;
|
|
71
|
+
}
|
|
72
|
+
/** Descriptors of currently incomplete owned work. */
|
|
73
|
+
pending() {
|
|
74
|
+
return [...this.inFlight.values()].map((entry) => entry.descriptor);
|
|
75
|
+
}
|
|
76
|
+
/** Every owned-work failure observed so far (accumulates across drains). */
|
|
77
|
+
errors() {
|
|
78
|
+
return [...this.failures];
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Fixed-point drain: await all pending owned work, run the adapter flush
|
|
82
|
+
* hooks, repeat until one full pass observes no pending work and causes
|
|
83
|
+
* no new registrations. Concurrent drains queue — each caller gets its
|
|
84
|
+
* own complete pass over whatever work exists when its turn arrives.
|
|
85
|
+
*
|
|
86
|
+
* Rejects with `FrontendWorkError` naming the owners when owned work
|
|
87
|
+
* failed since the previous drain, or when the pass bound is exceeded
|
|
88
|
+
* (repeating owned work), listing pending and repeating labels.
|
|
89
|
+
*/
|
|
90
|
+
drain(flushHooks = []) {
|
|
91
|
+
const run = this.drainChain.then(() => this.drainOnce(flushHooks));
|
|
92
|
+
this.drainChain = run.then(
|
|
93
|
+
() => void 0,
|
|
94
|
+
() => void 0
|
|
95
|
+
);
|
|
96
|
+
return run;
|
|
97
|
+
}
|
|
98
|
+
async drainOnce(flushHooks) {
|
|
99
|
+
const seenPerLabel = /* @__PURE__ */ new Map();
|
|
100
|
+
for (let pass = 1; pass <= MAX_DRAIN_PASSES; pass++) {
|
|
101
|
+
const registrationsBefore = this.registrations;
|
|
102
|
+
const snapshot = [...this.inFlight.values()];
|
|
103
|
+
for (const { descriptor } of snapshot) {
|
|
104
|
+
seenPerLabel.set(descriptor.label, (seenPerLabel.get(descriptor.label) ?? 0) + 1);
|
|
105
|
+
}
|
|
106
|
+
await Promise.all(snapshot.map((entry) => entry.observed));
|
|
107
|
+
for (const hook of flushHooks) {
|
|
108
|
+
await hook();
|
|
109
|
+
}
|
|
110
|
+
await Promise.resolve();
|
|
111
|
+
await Promise.resolve();
|
|
112
|
+
const stable = this.inFlight.size === 0 && this.registrations === registrationsBefore;
|
|
113
|
+
if (stable) {
|
|
114
|
+
this.throwNewFailures();
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
const pendingLines = this.pending().map(describe);
|
|
119
|
+
const repeating = [...seenPerLabel.entries()].filter(([, count]) => count > 3).map(([label, count]) => `${label} (seen in ${count} passes)`);
|
|
120
|
+
throw new FrontendWorkError(
|
|
121
|
+
`settle did not converge within ${MAX_DRAIN_PASSES} drain passes.
|
|
122
|
+
` + (pendingLines.length ? `Still pending:
|
|
123
|
+
${pendingLines.join("\n ")}
|
|
124
|
+
` : "") + (repeating.length ? `Repeating owned work:
|
|
125
|
+
${repeating.join("\n ")}
|
|
126
|
+
` : "") + "Owned work keeps creating more owned work \u2014 this names the owners; it is not a timeout.",
|
|
127
|
+
this.takeNewFailures()
|
|
128
|
+
);
|
|
129
|
+
}
|
|
130
|
+
takeNewFailures() {
|
|
131
|
+
const fresh = this.failures.slice(this.reportedFailures);
|
|
132
|
+
this.reportedFailures = this.failures.length;
|
|
133
|
+
return fresh;
|
|
134
|
+
}
|
|
135
|
+
throwNewFailures() {
|
|
136
|
+
const fresh = this.takeNewFailures();
|
|
137
|
+
if (!fresh.length) return;
|
|
138
|
+
const lines = fresh.map(
|
|
139
|
+
(failure) => `${describe(failure)}: ${failure.error instanceof Error ? failure.error.message : String(failure.error)}`
|
|
140
|
+
);
|
|
141
|
+
throw new FrontendWorkError(
|
|
142
|
+
`owned frontend work failed:
|
|
143
|
+
${lines.join("\n ")}`,
|
|
144
|
+
fresh
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
149
|
+
0 && (module.exports = {
|
|
150
|
+
FrontendWorkError,
|
|
151
|
+
WorkRegistry
|
|
152
|
+
});
|
|
153
|
+
//# sourceMappingURL=work_registry.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/frontend/work_registry.ts"],"sourcesContent":["/**\n * Owned-work registry for the frontend application slice (18A D-FAS-01).\n *\n * `act()` and `settle()` drain framework-owned finite work registered here\n * through production seams (transport invokes, event deliveries, navigation\n * transitions, tracked lifecycle tasks). The registry never patches global\n * async primitives and never guesses at event-loop emptiness: work exists\n * only because an owner registered it, and a drain is a fixed point —\n * repeated passes until one complete pass creates no new owned work.\n *\n * Floating promises and bare timers are explicitly outside the guarantee;\n * they are product lifecycle bugs, not framework blind spots to paper over.\n */\n\nexport type WorkKind =\n | 'invoke'\n | 'event-delivery'\n | 'navigation'\n | 'initialize'\n | 'tracked'\n | (string & {});\n\nexport interface WorkOptions {\n /** Human-readable diagnostic label, e.g. `invoke messages.send`. */\n label: string;\n kind?: WorkKind;\n /** Owning lifecycle identity, e.g. `page main.chat_dom` or `application`. */\n owner?: string;\n}\n\nexport interface WorkDescriptor {\n readonly id: number;\n readonly label: string;\n readonly kind: WorkKind;\n readonly owner: string;\n}\n\nexport interface WorkFailure extends WorkDescriptor {\n readonly error: unknown;\n}\n\n/** Safety bound on drain passes — a diagnostic limit, not the readiness mechanism. */\nconst MAX_DRAIN_PASSES = 100;\n\nexport class FrontendWorkError extends Error {\n constructor(message: string, readonly failures: readonly WorkFailure[] = []) {\n super(message);\n this.name = 'FrontendWorkError';\n }\n}\n\nfunction describe(work: WorkDescriptor): string {\n return `[${work.kind}] ${work.label} (owner: ${work.owner})`;\n}\n\nexport class WorkRegistry {\n private nextId = 1;\n /** Total registrations ever — the fixed-point signal for draining. */\n private registrations = 0;\n private readonly inFlight = new Map<number, { descriptor: WorkDescriptor; observed: Promise<void> }>();\n private readonly failures: WorkFailure[] = [];\n /** How many failures a completed drain has already reported. */\n private reportedFailures = 0;\n private drainChain: Promise<void> = Promise.resolve();\n\n /**\n * Register finite owned work. Returns a promise with the work's own\n * settlement semantics — callers may await it directly; the registry\n * additionally observes completion (success or failure) for draining.\n */\n track<T>(work: Promise<T> | (() => Promise<T>), options: WorkOptions): Promise<T> {\n const descriptor: WorkDescriptor = {\n id: this.nextId++,\n label: options.label,\n kind: options.kind ?? 'tracked',\n owner: options.owner ?? 'application',\n };\n\n this.registrations += 1;\n const promise = typeof work === 'function' ? work() : work;\n\n // Observe settlement without altering the caller's promise semantics.\n const observed = promise.then(\n () => undefined,\n (error) => {\n this.failures.push({ ...descriptor, error });\n },\n ).finally(() => {\n this.inFlight.delete(descriptor.id);\n });\n\n this.inFlight.set(descriptor.id, { descriptor, observed });\n return promise;\n }\n\n /** Descriptors of currently incomplete owned work. */\n pending(): WorkDescriptor[] {\n return [...this.inFlight.values()].map((entry) => entry.descriptor);\n }\n\n /** Every owned-work failure observed so far (accumulates across drains). */\n errors(): readonly WorkFailure[] {\n return [...this.failures];\n }\n\n /**\n * Fixed-point drain: await all pending owned work, run the adapter flush\n * hooks, repeat until one full pass observes no pending work and causes\n * no new registrations. Concurrent drains queue — each caller gets its\n * own complete pass over whatever work exists when its turn arrives.\n *\n * Rejects with `FrontendWorkError` naming the owners when owned work\n * failed since the previous drain, or when the pass bound is exceeded\n * (repeating owned work), listing pending and repeating labels.\n */\n drain(flushHooks: ReadonlyArray<() => void | Promise<void>> = []): Promise<void> {\n const run = this.drainChain.then(() => this.drainOnce(flushHooks));\n // Keep the chain alive regardless of this drain's outcome.\n this.drainChain = run.then(\n () => undefined,\n () => undefined,\n );\n return run;\n }\n\n private async drainOnce(flushHooks: ReadonlyArray<() => void | Promise<void>>): Promise<void> {\n const seenPerLabel = new Map<string, number>();\n\n for (let pass = 1; pass <= MAX_DRAIN_PASSES; pass++) {\n const registrationsBefore = this.registrations;\n const snapshot = [...this.inFlight.values()];\n\n for (const { descriptor } of snapshot) {\n seenPerLabel.set(descriptor.label, (seenPerLabel.get(descriptor.label) ?? 0) + 1);\n }\n\n // Observed promises never reject (failures are recorded by track());\n // awaiting them cannot abort the pass mid-way.\n await Promise.all(snapshot.map((entry) => entry.observed));\n\n for (const hook of flushHooks) {\n await hook();\n }\n\n // Give completion continuations a microtask to register follow-on\n // owned work before the fixed point is tested.\n await Promise.resolve();\n await Promise.resolve();\n\n const stable = this.inFlight.size === 0 && this.registrations === registrationsBefore;\n if (stable) {\n this.throwNewFailures();\n return;\n }\n }\n\n const pendingLines = this.pending().map(describe);\n const repeating = [...seenPerLabel.entries()]\n .filter(([, count]) => count > 3)\n .map(([label, count]) => `${label} (seen in ${count} passes)`);\n\n throw new FrontendWorkError(\n `settle did not converge within ${MAX_DRAIN_PASSES} drain passes.\\n` +\n (pendingLines.length ? `Still pending:\\n ${pendingLines.join('\\n ')}\\n` : '') +\n (repeating.length ? `Repeating owned work:\\n ${repeating.join('\\n ')}\\n` : '') +\n 'Owned work keeps creating more owned work — this names the owners; it is not a timeout.',\n this.takeNewFailures(),\n );\n }\n\n private takeNewFailures(): WorkFailure[] {\n const fresh = this.failures.slice(this.reportedFailures);\n this.reportedFailures = this.failures.length;\n return fresh;\n }\n\n private throwNewFailures(): void {\n const fresh = this.takeNewFailures();\n if (!fresh.length) return;\n const lines = fresh.map(\n (failure) =>\n `${describe(failure)}: ${failure.error instanceof Error ? failure.error.message : String(failure.error)}`,\n );\n throw new FrontendWorkError(\n `owned frontend work failed:\\n ${lines.join('\\n ')}`,\n fresh,\n );\n }\n}\n"],"mappings":"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","names":[]}
|