@noego/wood 0.6.2 → 0.7.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/README.md +7 -0
- package/dist/browser-test-setup.cjs +29 -0
- package/dist/browser-test-setup.cjs.map +1 -0
- package/dist/browser-test-setup.d.cts +8 -0
- package/dist/browser-test-setup.d.ts +8 -0
- package/dist/browser-test-setup.js +9 -0
- package/dist/browser-test-setup.js.map +1 -0
- package/dist/client/global_polyfill.d.cts +1 -0
- package/dist/client/global_polyfill.d.ts +1 -0
- package/dist/client/index.cjs +7 -0
- package/dist/client/index.cjs.map +1 -1
- package/dist/client/index.d.cts +7 -4
- package/dist/client/index.d.ts +7 -4
- package/dist/client/index.js +6 -1
- package/dist/client/index.js.map +1 -1
- package/dist/codegen/renderer_app_generator.cjs +97 -24
- package/dist/codegen/renderer_app_generator.cjs.map +1 -1
- package/dist/codegen/renderer_app_generator.js +97 -24
- package/dist/codegen/renderer_app_generator.js.map +1 -1
- package/dist/codegen/type_generator.cjs +9 -0
- package/dist/codegen/type_generator.cjs.map +1 -1
- package/dist/codegen/type_generator.js +9 -0
- package/dist/codegen/type_generator.js.map +1 -1
- package/dist/config/config_parser.cjs +10 -0
- package/dist/config/config_parser.cjs.map +1 -1
- package/dist/config/config_parser.js +10 -0
- package/dist/config/config_parser.js.map +1 -1
- package/dist/fetch.cjs +38 -0
- package/dist/fetch.cjs.map +1 -0
- package/dist/fetch.d.cts +7 -0
- package/dist/fetch.d.ts +7 -0
- package/dist/fetch.js +12 -0
- package/dist/fetch.js.map +1 -0
- package/dist/frontend/frontend_page.cjs +3 -3
- package/dist/frontend/frontend_page.cjs.map +1 -1
- package/dist/frontend/frontend_page.d.cts +1 -1
- package/dist/frontend/frontend_page.d.ts +1 -1
- package/dist/frontend/frontend_page.js +3 -3
- package/dist/frontend/frontend_page.js.map +1 -1
- package/dist/frontend/frontend_surface.cjs +31 -17
- package/dist/frontend/frontend_surface.cjs.map +1 -1
- package/dist/frontend/frontend_surface.d.cts +12 -2
- package/dist/frontend/frontend_surface.d.ts +12 -2
- package/dist/frontend/frontend_surface.js +37 -17
- package/dist/frontend/frontend_surface.js.map +1 -1
- package/dist/frontend/index.d.cts +2 -0
- package/dist/frontend/index.d.ts +2 -0
- package/dist/index.cjs +5 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +25 -0
- package/dist/index.d.ts +25 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/loader/index.cjs +19 -2
- package/dist/loader/index.cjs.map +1 -1
- package/dist/loader/index.d.cts +1 -0
- package/dist/loader/index.d.ts +1 -0
- package/dist/loader/index.js +19 -1
- package/dist/loader/index.js.map +1 -1
- package/dist/loader/loader_orchestration.cjs +82 -0
- package/dist/loader/loader_orchestration.cjs.map +1 -0
- package/dist/loader/loader_orchestration.d.cts +66 -0
- package/dist/loader/loader_orchestration.d.ts +66 -0
- package/dist/loader/loader_orchestration.js +51 -0
- package/dist/loader/loader_orchestration.js.map +1 -0
- package/dist/loader/loader_runner.cjs +46 -41
- package/dist/loader/loader_runner.cjs.map +1 -1
- package/dist/loader/loader_runner.d.cts +12 -6
- package/dist/loader/loader_runner.d.ts +12 -6
- package/dist/loader/loader_runner.js +50 -41
- package/dist/loader/loader_runner.js.map +1 -1
- package/dist/native_browser.types-BY2daUOS.d.ts +189 -0
- package/dist/native_browser.types-vWXtE4rM.d.cts +189 -0
- package/dist/navigation/index.cjs +15 -2
- package/dist/navigation/index.cjs.map +1 -1
- package/dist/navigation/index.d.cts +2 -0
- package/dist/navigation/index.d.ts +2 -0
- package/dist/navigation/index.js +8 -1
- package/dist/navigation/index.js.map +1 -1
- package/dist/runtime/get_container.cjs +2 -0
- package/dist/runtime/get_container.cjs.map +1 -1
- package/dist/runtime/get_container.js +2 -0
- package/dist/runtime/get_container.js.map +1 -1
- package/dist/runtime/index.cjs +5 -0
- package/dist/runtime/index.cjs.map +1 -1
- package/dist/runtime/index.d.cts +2 -0
- package/dist/runtime/index.d.ts +2 -0
- package/dist/runtime/index.js +3 -0
- package/dist/runtime/index.js.map +1 -1
- package/dist/runtime/runtime_capabilities.cjs +35 -0
- package/dist/runtime/runtime_capabilities.cjs.map +1 -0
- package/dist/runtime/runtime_capabilities.d.cts +6 -0
- package/dist/runtime/runtime_capabilities.d.ts +6 -0
- package/dist/runtime/runtime_capabilities.js +11 -0
- package/dist/runtime/runtime_capabilities.js.map +1 -0
- package/dist/runtime/runtime_module.cjs +2 -0
- package/dist/runtime/runtime_module.cjs.map +1 -1
- package/dist/runtime/runtime_module.js +2 -0
- package/dist/runtime/runtime_module.js.map +1 -1
- package/dist/test-wood.cjs +150 -0
- package/dist/test-wood.cjs.map +1 -0
- package/dist/test-wood.d.cts +62 -0
- package/dist/test-wood.d.ts +62 -0
- package/dist/test-wood.js +115 -0
- package/dist/test-wood.js.map +1 -0
- package/dist/testing/browser.cjs +92 -163
- package/dist/testing/browser.cjs.map +1 -1
- package/dist/testing/browser.d.cts +14 -13
- package/dist/testing/browser.d.ts +14 -13
- package/dist/testing/browser.js +88 -162
- package/dist/testing/browser.js.map +1 -1
- package/dist/testing/create_controller_harness.d.cts +2 -1
- package/dist/testing/create_controller_harness.d.ts +2 -1
- package/dist/testing/create_router_bridge.cjs +19 -15
- package/dist/testing/create_router_bridge.cjs.map +1 -1
- package/dist/testing/create_router_bridge.d.cts +8 -1
- package/dist/testing/create_router_bridge.d.ts +8 -1
- package/dist/testing/create_router_bridge.js +18 -15
- package/dist/testing/create_router_bridge.js.map +1 -1
- package/dist/testing/index.cjs +12 -4
- package/dist/testing/index.cjs.map +1 -1
- package/dist/testing/index.d.cts +11 -5
- package/dist/testing/index.d.ts +11 -5
- package/dist/testing/index.js +9 -3
- package/dist/testing/index.js.map +1 -1
- package/dist/testing/native_browser/browser_pool.cjs +31 -0
- package/dist/testing/native_browser/browser_pool.cjs.map +1 -0
- package/dist/testing/native_browser/browser_pool.d.cts +1 -0
- package/dist/testing/native_browser/browser_pool.d.ts +1 -0
- package/dist/testing/native_browser/browser_pool.js +6 -0
- package/dist/testing/native_browser/browser_pool.js.map +1 -0
- package/dist/testing/native_browser/happy_dom_tab.cjs +107 -0
- package/dist/testing/native_browser/happy_dom_tab.cjs.map +1 -0
- package/dist/testing/native_browser/happy_dom_tab.d.cts +35 -0
- package/dist/testing/native_browser/happy_dom_tab.d.ts +35 -0
- package/dist/testing/native_browser/happy_dom_tab.js +73 -0
- package/dist/testing/native_browser/happy_dom_tab.js.map +1 -0
- package/dist/testing/native_browser/happy_dom_transfer.cjs +29 -0
- package/dist/testing/native_browser/happy_dom_transfer.cjs.map +1 -0
- package/dist/testing/native_browser/happy_dom_transfer.d.cts +1 -0
- package/dist/testing/native_browser/happy_dom_transfer.d.ts +1 -0
- package/dist/testing/native_browser/happy_dom_transfer.js +5 -0
- package/dist/testing/native_browser/happy_dom_transfer.js.map +1 -0
- package/dist/testing/native_browser/host_transport.cjs +89 -0
- package/dist/testing/native_browser/host_transport.cjs.map +1 -0
- package/dist/testing/native_browser/host_transport.d.cts +44 -0
- package/dist/testing/native_browser/host_transport.d.ts +44 -0
- package/dist/testing/native_browser/host_transport.js +65 -0
- package/dist/testing/native_browser/host_transport.js.map +1 -0
- package/dist/testing/native_browser/native_browser.types.cjs +17 -0
- package/dist/testing/native_browser/native_browser.types.cjs.map +1 -0
- package/dist/testing/native_browser/native_browser.types.d.cts +31 -0
- package/dist/testing/native_browser/native_browser.types.d.ts +31 -0
- package/dist/testing/native_browser/native_browser.types.js +1 -0
- package/dist/testing/native_browser/native_browser.types.js.map +1 -0
- package/dist/testing/native_browser/native_browser_environment.cjs +143 -0
- package/dist/testing/native_browser/native_browser_environment.cjs.map +1 -0
- package/dist/testing/native_browser/native_browser_environment.d.cts +36 -0
- package/dist/testing/native_browser/native_browser_environment.d.ts +36 -0
- package/dist/testing/native_browser/native_browser_environment.js +109 -0
- package/dist/testing/native_browser/native_browser_environment.js.map +1 -0
- package/dist/testing/native_browser/native_browser_lifecycle.cjs +31 -0
- package/dist/testing/native_browser/native_browser_lifecycle.cjs.map +1 -0
- package/dist/testing/native_browser/native_browser_lifecycle.d.cts +1 -0
- package/dist/testing/native_browser/native_browser_lifecycle.d.ts +1 -0
- package/dist/testing/native_browser/native_browser_lifecycle.js +6 -0
- package/dist/testing/native_browser/native_browser_lifecycle.js.map +1 -0
- package/dist/testing/native_browser/playwright_tab.cjs +124 -0
- package/dist/testing/native_browser/playwright_tab.cjs.map +1 -0
- package/dist/testing/native_browser/playwright_tab.d.cts +35 -0
- package/dist/testing/native_browser/playwright_tab.d.ts +35 -0
- package/dist/testing/native_browser/playwright_tab.js +100 -0
- package/dist/testing/native_browser/playwright_tab.js.map +1 -0
- package/dist/testing/native_browser/renderer_compilation.cjs +149 -0
- package/dist/testing/native_browser/renderer_compilation.cjs.map +1 -0
- package/dist/testing/native_browser/renderer_compilation.d.cts +35 -0
- package/dist/testing/native_browser/renderer_compilation.d.ts +35 -0
- package/dist/testing/native_browser/renderer_compilation.js +115 -0
- package/dist/testing/native_browser/renderer_compilation.js.map +1 -0
- package/dist/testing/native_browser/renderer_entry.cjs +148 -0
- package/dist/testing/native_browser/renderer_entry.cjs.map +1 -0
- package/dist/testing/native_browser/renderer_entry.d.cts +13 -0
- package/dist/testing/native_browser/renderer_entry.d.ts +13 -0
- package/dist/testing/native_browser/renderer_entry.js +114 -0
- package/dist/testing/native_browser/renderer_entry.js.map +1 -0
- package/dist/testing/registration_only_root.cjs +61 -5
- package/dist/testing/registration_only_root.cjs.map +1 -1
- package/dist/testing/registration_only_root.d.cts +25 -4
- package/dist/testing/registration_only_root.d.ts +25 -4
- package/dist/testing/registration_only_root.js +60 -5
- package/dist/testing/registration_only_root.js.map +1 -1
- package/dist/testing/runner_importer.cjs +75 -0
- package/dist/testing/runner_importer.cjs.map +1 -0
- package/dist/testing/runner_importer.d.cts +8 -0
- package/dist/testing/runner_importer.d.ts +8 -0
- package/dist/testing/runner_importer.js +41 -0
- package/dist/testing/runner_importer.js.map +1 -0
- package/dist/testing/test_wood_config.cjs +407 -273
- package/dist/testing/test_wood_config.cjs.map +1 -1
- package/dist/testing/test_wood_config.d.cts +18 -123
- package/dist/testing/test_wood_config.d.ts +18 -123
- package/dist/testing/test_wood_config.js +416 -271
- package/dist/testing/test_wood_config.js.map +1 -1
- package/dist/testing/wood_config_source.cjs +12 -0
- package/dist/testing/wood_config_source.cjs.map +1 -1
- package/dist/testing/wood_config_source.d.cts +10 -0
- package/dist/testing/wood_config_source.d.ts +10 -0
- package/dist/testing/wood_config_source.js +12 -0
- package/dist/testing/wood_config_source.js.map +1 -1
- package/dist/testing/wood_env_renderer.cjs +31 -4
- package/dist/testing/wood_env_renderer.cjs.map +1 -1
- package/dist/testing/wood_env_renderer.d.cts +14 -1
- package/dist/testing/wood_env_renderer.d.ts +14 -1
- package/dist/testing/wood_env_renderer.js +31 -4
- package/dist/testing/wood_env_renderer.js.map +1 -1
- package/dist/testing/wood_lazy_runtime.cjs +109 -0
- package/dist/testing/wood_lazy_runtime.cjs.map +1 -0
- package/dist/testing/wood_lazy_runtime.d.cts +36 -0
- package/dist/testing/wood_lazy_runtime.d.ts +36 -0
- package/dist/testing/wood_lazy_runtime.js +84 -0
- package/dist/testing/wood_lazy_runtime.js.map +1 -0
- package/dist/testing/wood_test_selection.cjs +34 -55
- package/dist/testing/wood_test_selection.cjs.map +1 -1
- package/dist/testing/wood_test_selection.d.cts +18 -24
- package/dist/testing/wood_test_selection.d.ts +18 -24
- package/dist/testing/wood_test_selection.js +30 -54
- package/dist/testing/wood_test_selection.js.map +1 -1
- package/dist/testing-api.cjs +17 -0
- package/dist/testing-api.cjs.map +1 -0
- package/dist/testing-api.d.cts +18 -0
- package/dist/testing-api.d.ts +18 -0
- package/dist/testing-api.js +1 -0
- package/dist/testing-api.js.map +1 -0
- package/dist/types/config.cjs.map +1 -1
- package/dist/types/config.d.cts +4 -0
- package/dist/types/config.d.ts +4 -0
- package/docs/native-browser-testing.md +164 -0
- package/package.json +31 -5
- package/src/components/NavigationShell.browser.test.ts +10 -10
- package/src/components/NavigationShell.cleanup.browser.test.ts +57 -0
- package/src/components/NavigationShell.scopes.browser.test.ts +5 -5
- package/src/components/NavigationShell.svelte +50 -24
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/frontend/frontend_surface.ts"],"sourcesContent":["/**\n * The Node frontend application surface (spec 18 §12–13, 18A D-FAS-01/02).\n *\n * frontend.open({ page, params, query }) — explicit initial page\n * frontend.current() — production navigation result\n * frontend.act(fn) / frontend.settle() — owned-work fixed-point drains\n * frontend.errors — observed owned-work failures\n *\n * Runtime honesty (D-FAS-02): this is the plain-Node tier. It proves\n * explicit PageController behavior, $state/$derived reachable through it,\n * backend calls, events, and navigation identity/lifecycle. It does not\n * create a Svelte component/root context and therefore proves no $effect,\n * mount/unmount, or DOM behavior — those belong to the happy-dom tier.\n *\n * Isolation: every environment owns its own Navigation instance, renderer\n * root, transport, and work registry. Nothing here writes globalThis and\n * nothing calls the production client getters — two environments run\n * concurrently without cross-talk. A controller that calls the module-level\n * `go()`/`getNavigation()` free functions bypasses its environment; this\n * tier requires constructor-injected `Navigation`.\n */\nimport { ExecutionContext, LoadAs } from '@noego/ioc';\nimport { Navigation, type NavigationEntry } from '../navigation/index.js';\nimport { computePreservedLayoutDepth } from '../navigation/layout_preservation.js';\nimport { cleanupAll } from '../controller/cleanup.js';\nimport { disposeControllerLifecycle, guardControllerLifecycleOnce } from '../controller/controller_lifecycle.js';\nimport type { ViewDef } from '../types/index.js';\nimport { PageCatalog, PageCatalogError, pageIdentity } from './page_catalog.js';\nimport { WorkRegistry, FrontendWorkError, type WorkFailure } from './work_registry.js';\nimport { FrontendLifecycleOwner, type FrontendLifecycle } from './frontend_lifecycle.js';\nimport { createFrontendPage, type FrontendPage, type FrontendPageHandle, type MountedLayout } from './frontend_page.js';\n\nexport interface FrontendOpenOptions {\n /** Required production page identity (`window.page`, or unambiguous leaf). */\n page: string;\n params?: Record<string, string>;\n query?: Record<string, string>;\n}\n\nexport interface FrontendApplicationSurface {\n open(options: FrontendOpenOptions): Promise<FrontendPage>;\n current(): FrontendPage | null;\n act(action: () => unknown | Promise<unknown>): Promise<void>;\n settle(): Promise<void>;\n readonly errors: readonly WorkFailure[];\n /** The environment-local production Navigation instance. */\n readonly navigation: Navigation;\n /** Internal: dispose the active page and application lifecycles. */\n dispose(): Promise<void>;\n}\n\ninterface ScopeLike {\n extend(): ScopeLike;\n get(token: unknown): Promise<unknown>;\n registerClass?(target: unknown, options?: unknown): void;\n registerFunction?(token: unknown, factory: () => unknown, options?: unknown): void;\n registerValue?(token: unknown, value: unknown): void;\n dispose?(): Promise<void>;\n}\n\n/**\n * A mounted layout controller and the scope that owns it. A layout declared\n * `preserve: true` owns a DEDICATED scope that survives page transitions\n * (production parity: `createControllerSet`); every other layout shares the\n * page scope and dies with the page.\n */\ninterface ActiveLayout extends MountedLayout {\n index: number;\n /** Non-null only for a preserved layout that owns its scope. */\n ownScope: ScopeLike | null;\n /**\n * A preserved layout outlives the page that built it, so it cannot borrow\n * that page's lifecycle owner — it owns one, disposed when the layout is\n * finally dropped.\n */\n ownLifecycle: FrontendLifecycleOwner | null;\n}\n\ninterface ActivePage {\n identity: string;\n view: ViewDef;\n scope: ScopeLike;\n lifecycle: FrontendLifecycleOwner;\n handle: FrontendPageHandle;\n controller: unknown;\n layouts: ActiveLayout[];\n}\n\nexport interface PageScopeContext {\n kind: 'page' | 'layout';\n /** Layout index within the view's layout stack (layout scopes only). */\n layoutIndex?: number;\n /** Controller identity bound to this scope. */\n controller: string;\n}\n\nexport interface CreateFrontendSurfaceOptions {\n /** The selected renderer aperture. */\n catalog: PageCatalog;\n /** Fresh renderer root for this environment (separate from the main root). */\n rendererRoot: ScopeLike;\n registry: WorkRegistry;\n /** Environment-local Navigation (also registered on the renderer root). */\n navigation: Navigation;\n /** Resolve a production controller identity to its class. */\n resolveController: (identity: string, view: ViewDef) => Promise<new (...args: never[]) => unknown>;\n /** Per-pass reactive flush hooks from the active runtime adapter (Node: none). */\n flushHooks?: ReadonlyArray<() => void | Promise<void>>;\n /**\n * Register per-scope services on a newly created scope (bridge client,\n * etc.). Called for the page scope, and once for each PRESERVED layout\n * that owns a dedicated scope — `context.kind` says which, so a caller\n * that tracks \"the page scope\" does not mistake a layout scope for it.\n */\n configurePageScope?: (\n scope: ScopeLike,\n view: ViewDef,\n context: PageScopeContext,\n ) => void | Promise<void>;\n}\n\n/**\n * Plain (undecorated) controller classes are registered on their scope so\n * they resolve — unless the hierarchy already decided how the token resolves\n * (a renderer-root substitution of the controller class), which keeps\n * winning inside the page scope.\n */\nfunction registerControllerUnlessBound(scope: ScopeLike, ControllerClass: unknown): void {\n const registrable = scope as { isRegistered?(token: unknown): boolean };\n if (typeof registrable.isRegistered === 'function' && registrable.isRegistered(ControllerClass)) return;\n if (typeof scope.registerClass === 'function') scope.registerClass(ControllerClass);\n}\n\nexport function createFrontendSurface(options: CreateFrontendSurfaceOptions): FrontendApplicationSurface {\n const { catalog, rendererRoot, registry, navigation } = options;\n const flushHooks = options.flushHooks ?? [];\n const application = new FrontendLifecycleOwner(registry, 'application');\n\n let active: ActivePage | null = null;\n let transitioning = false;\n let disposed = false;\n let navigationQueue: Promise<void> = Promise.resolve();\n let closing: Promise<void> | undefined;\n const retainedPageScopes = new Map<ScopeLike, FrontendLifecycleOwner>();\n const locallyOwnedControllers = new WeakSet<object>();\n const markController = (instance: unknown, token: unknown) => {\n const root = rendererRoot as ScopeLike & { isRegistered?(token: unknown): boolean };\n if (!root.isRegistered?.(token) && instance && typeof instance === 'object') locallyOwnedControllers.add(instance);\n guardControllerLifecycleOnce(instance);\n };\n const disposeLocalController = (instance: unknown) => instance && typeof instance === 'object' && locallyOwnedControllers.has(instance)\n ? disposeControllerLifecycle(instance) : Promise.resolve();\n\n const currentOwner = (): string => (active ? `page ${active.identity}` : 'application');\n\n async function constructPage(\n view: ViewDef,\n params: Record<string, string>,\n query: Record<string, string>,\n preserved: ActiveLayout[] = [],\n ): Promise<ActivePage> {\n const identity = pageIdentity(view);\n if (!view.controller) {\n throw new PageCatalogError(\n `page \"${identity}\" declares no controller in its view definition; ` +\n 'the Node application slice drives public PageController input and needs one.',\n );\n }\n\n const ControllerClass = await options.resolveController(view.controller, view);\n const scope = rendererRoot.extend();\n const lifecycle = new FrontendLifecycleOwner(registry, `page ${identity}`);\n\n const rollback: Array<() => unknown | Promise<unknown>> = [\n () => ExecutionContext.run(scope as never, () => scope.dispose?.()),\n () => lifecycle.dispose(),\n ];\n try {\n // The page lifecycle is injectable so controllers can register\n // deliberately detached finite work (D-FAS-01 §2.2). Scoped, not\n // Singleton: the lifecycle belongs to this page scope alone — a\n // Singleton would store at the hierarchy root and leak the first\n // page's lifecycle into every later page.\n scope.registerFunction?.(FrontendLifecycleOwner, () => lifecycle, { loadAs: LoadAs.Scoped });\n await ExecutionContext.run(scope as never, () => options.configurePageScope?.(scope, view, { kind: 'page', controller: view.controller! }));\n registerControllerUnlessBound(scope, ControllerClass);\n\n // Layout controllers mount BEFORE the view controller (production\n // ordering in `createControllerSet`): a page controller may legitimately\n // read state a layout controller published during construction.\n const layouts: ActiveLayout[] = [...preserved];\n for (let index = preserved.length; index < view.layouts.length; index += 1) {\n const layoutIdentity = view.layoutControllers?.[index];\n if (!layoutIdentity) continue;\n const preserve = view.layoutPreserve?.[index] === true;\n const LayoutClass = await options.resolveController(layoutIdentity, view);\n const ownScope = preserve ? rendererRoot.extend() : null;\n const ownLifecycle = ownScope\n ? new FrontendLifecycleOwner(registry, `layout ${layoutIdentity}`)\n : null;\n const layoutScope = ownScope ?? scope;\n if (ownScope) {\n rollback.push(() => ExecutionContext.run(ownScope as never, () => ownScope.dispose?.()));\n rollback.push(() => ownLifecycle!.dispose());\n ownScope.registerFunction?.(FrontendLifecycleOwner, () => ownLifecycle!, { loadAs: LoadAs.Scoped });\n await ExecutionContext.run(ownScope as never, () => options.configurePageScope?.(ownScope, view, {\n kind: 'layout',\n layoutIndex: index,\n controller: layoutIdentity,\n }));\n }\n registerControllerUnlessBound(layoutScope, LayoutClass);\n const instance = (await ExecutionContext.run(layoutScope as never, () =>\n layoutScope.get(LayoutClass),\n )) as Record<string, unknown>;\n markController(instance, LayoutClass);\n rollback.push(() => ExecutionContext.run(layoutScope as never, () => disposeLocalController(instance)));\n layouts.push({\n index,\n path: view.layouts[index],\n controller: layoutIdentity,\n preserve,\n instance,\n scope: layoutScope,\n ownScope,\n ownLifecycle,\n });\n }\n\n const controller = (await ExecutionContext.run(scope as never, () =>\n scope.get(ControllerClass),\n )) as Record<string, unknown>;\n\n markController(controller, ControllerClass);\n rollback.push(() => ExecutionContext.run(scope as never, () => disposeLocalController(controller)));\n\n if (typeof controller.initialize === 'function') {\n await registry.track(\n Promise.resolve(\n ExecutionContext.run(scope as never, () =>\n (controller.initialize as (load: unknown) => unknown)({ params, query }),\n ),\n ).then(() => undefined),\n { label: `initialize ${identity}`, kind: 'initialize', owner: `page ${identity}` },\n );\n }\n\n const handle = createFrontendPage({\n identity,\n controller,\n scope,\n layouts,\n onClose: async () => {\n await disposePage(identity);\n },\n });\n\n return { identity, view, scope, lifecycle, handle, controller, layouts };\n } catch (error) {\n try { await cleanupAll(rollback.reverse(), 'Wood page rollback failed'); }\n catch (cleanupError) { throw Object.assign(new Error('Wood page construction and cleanup failed'), { cause: error, errors: [error, cleanupError] }); }\n throw error;\n }\n }\n\n /**\n * End a page: the page lifecycle owner first (abort signal, owned\n * resources), then the IoC scopes — scope disposal is what runs each\n * controller's production `dispose()`/`destroy()` hook, so nothing here\n * calls those directly. Layouts in the preserved prefix keep running:\n * they belong to the next page now.\n */\n async function endPage(page: ActivePage, preservedDepth = 0): Promise<void> {\n page.handle.invalidate();\n // Production teardown order (NavigationShell.disposeControllerSet): the\n // page controller's hook, then each ending layout's, then the lifecycle\n // owner and the IoC scopes. The hooks are once-guarded, so the scope\n // disposal below does not run them a second time.\n const steps: Array<() => unknown | Promise<unknown>> = [\n () => ExecutionContext.run(page.scope as never, () => disposeLocalController(page.controller)),\n ];\n for (const layout of page.layouts) {\n if (layout.index < preservedDepth) continue;\n steps.push(() => ExecutionContext.run(layout.scope as never, () => disposeLocalController(layout.instance)));\n steps.push(() => layout.ownLifecycle?.dispose());\n if (layout.ownScope) steps.push(() => ExecutionContext.run(layout.ownScope as never, () => layout.ownScope!.dispose?.()));\n }\n const carriesPageScope = page.layouts.some(layout => layout.index < preservedDepth && layout.scope === page.scope);\n if (carriesPageScope) retainedPageScopes.set(page.scope, page.lifecycle);\n else {\n steps.push(() => page.lifecycle.dispose());\n steps.push(() => ExecutionContext.run(page.scope as never, () => page.scope.dispose?.()));\n }\n for (const [scope, lifecycle] of retainedPageScopes) {\n if (active?.layouts.some(layout => layout.scope === scope)) continue;\n retainedPageScopes.delete(scope);\n steps.push(() => lifecycle.dispose());\n steps.push(() => ExecutionContext.run(scope as never, () => scope.dispose?.()));\n }\n await cleanupAll(steps, 'Wood page cleanup failed');\n }\n\n async function disposePage(identity: string): Promise<void> {\n if (!active || active.identity !== identity) return;\n const ended = active;\n active = null;\n await endPage(ended);\n }\n\n async function transitionTo(entry: NavigationEntry): Promise<void> {\n if (disposed) return;\n // Resolve the destination through the selected aperture — navigation\n // outside it fails without widening the environment.\n const view = catalog.resolve(entry.page);\n const previous = active;\n // Preserved layouts carry over as live instances — the transition never\n // reconstructs them (production `preserve: true` semantics).\n // Same preservation rule the renderer's NavigationShell applies.\n const depth = previous\n ? computePreservedLayoutDepth(\n { layoutPaths: previous.view.layouts, layoutControllers: previous.view.layoutControllers, layoutPreserve: previous.view.layoutPreserve },\n { layoutPaths: view.layouts, layoutControllers: view.layoutControllers, layoutPreserve: view.layoutPreserve },\n entry.options ?? {},\n )\n : 0;\n const carried = previous ? previous.layouts.filter((layout) => layout.index < depth) : [];\n const next = await constructPage(view, entry.params, entry.query, carried);\n if (disposed) {\n await endPage(next, depth);\n return;\n }\n active = next;\n if (previous) {\n await endPage(previous, depth);\n }\n }\n\n // Production navigation drives page transitions: a controller calling its\n // injected Navigation.go()/replace() inside the aperture triggers one\n // tracked finite navigation transition (18A D-FAS-01 §2.2).\n const unsubscribe = navigation.subscribe((entry) => {\n if (!entry || transitioning || disposed) return;\n if (active && entry.page === active.identity) return;\n if (!active) return; // initial open() seeds navigation itself\n const transition = navigationQueue.then(() => transitionTo(entry));\n navigationQueue = transition.catch(() => {});\n registry.track(transition, {\n label: `navigate ${active.identity} -> ${entry.page}`,\n kind: 'navigation',\n owner: currentOwner(),\n });\n });\n\n return {\n navigation,\n\n async open(openOptions: FrontendOpenOptions): Promise<FrontendPage> {\n if (disposed || transitioning) throw new PageCatalogError('Wood frontend is closed or opening a page');\n if (!openOptions || typeof openOptions.page !== 'string' || !openOptions.page.length) {\n throw new PageCatalogError('frontend.open() requires an explicit { page } identity');\n }\n if (active) {\n throw new PageCatalogError(\n `frontend.open() is test bootstrap; page \"${active.identity}\" is already open. ` +\n 'Drive production navigation for subsequent route changes, or close() the page first.',\n );\n }\n const view = catalog.resolve(openOptions.page);\n const params = openOptions.params ?? {};\n const query = openOptions.query ?? {};\n\n transitioning = true;\n try {\n // Seed production navigation state BEFORE construction: controllers\n // and their services legitimately read the current route (params,\n // query) during construction/initialize, exactly as in production\n // where the route exists before the page loads.\n navigation.replace(pageIdentity(view), params, query);\n const opened = await constructPage(view, params, query);\n if (disposed) { await endPage(opened); throw new PageCatalogError('Wood frontend was disposed during page construction'); }\n active = opened;\n } finally {\n transitioning = false;\n }\n return active.handle.page;\n },\n\n current(): FrontendPage | null {\n return active ? active.handle.page : null;\n },\n\n async act(action: () => unknown | Promise<unknown>): Promise<void> {\n void registry.track(\n Promise.resolve().then(() => action()).then(() => undefined),\n { label: 'act()', kind: 'tracked', owner: currentOwner() },\n ).catch(() => {\n // The failure is recorded by the registry; drain reports it with\n // its owner rather than losing the aggregate view.\n });\n await registry.drain(flushHooks);\n },\n\n async settle(): Promise<void> {\n await registry.drain(flushHooks);\n },\n\n get errors(): readonly WorkFailure[] {\n return registry.errors();\n },\n\n dispose(): Promise<void> {\n if (closing) return closing;\n disposed = true;\n unsubscribe();\n const ended = active;\n active = null;\n return closing = cleanupAll([\n () => ended ? endPage(ended) : undefined,\n () => application.dispose(),\n ], 'Wood frontend cleanup failed');\n },\n };\n}\n\nexport type { FrontendLifecycle };\nexport { FrontendWorkError };\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/frontend/frontend_surface.ts"],"sourcesContent":["/**\n * The Node frontend application surface (spec 18 §12–13, 18A D-FAS-01/02).\n *\n * frontend.open({ page, params, query }) — explicit initial page\n * frontend.current() — production navigation result\n * frontend.act(fn) / frontend.settle() — owned-work fixed-point drains\n * frontend.errors — observed owned-work failures\n *\n * Runtime honesty (D-FAS-02): this is the plain-Node tier. It proves\n * explicit PageController behavior, $state/$derived reachable through it,\n * backend calls, events, and navigation identity/lifecycle. It does not\n * create a Svelte component/root context and therefore proves no $effect,\n * mount/unmount, or DOM behavior — those belong to the happy-dom tier.\n *\n * Isolation: every environment owns its own Navigation instance, renderer\n * root, transport, and work registry. Nothing here writes globalThis and\n * nothing calls the production client getters — two environments run\n * concurrently without cross-talk. A controller that calls the module-level\n * `go()`/`getNavigation()` free functions bypasses its environment; this\n * tier requires constructor-injected `Navigation`.\n */\nimport { ExecutionContext, LoadAs } from '@noego/ioc';\nimport { Navigation, type NavigationEntry } from '../navigation/index.js';\nimport { computePreservedLayoutDepth } from '../navigation/layout_preservation.js';\nimport { createNavigationMountKey } from '../navigation/navigation_identity.js';\nimport { cleanupAll } from '../controller/cleanup.js';\nimport { disposeControllerLifecycle, guardControllerLifecycleOnce } from '../controller/controller_lifecycle.js';\nimport {\n createLoaderRequest,\n initializeArgument,\n initializeController,\n NO_LOADERS,\n runViewLoaders,\n type ViewLoaderSet,\n} from '../loader/loader_orchestration.js';\nimport type { ViewDef } from '../types/index.js';\nimport { PageCatalog, PageCatalogError, pageIdentity } from './page_catalog.js';\nimport { WorkRegistry, FrontendWorkError, type WorkFailure } from './work_registry.js';\nimport { FrontendLifecycleOwner, type FrontendLifecycle } from './frontend_lifecycle.js';\nimport { createFrontendPage, type FrontendPage, type FrontendPageHandle, type MountedLayout } from './frontend_page.js';\n\nexport interface FrontendOpenOptions {\n /** Required production page identity (`window.page`, or unambiguous leaf). */\n page: string;\n params?: Record<string, string>;\n query?: Record<string, string>;\n}\n\nexport interface FrontendApplicationSurface {\n open(options: FrontendOpenOptions): Promise<FrontendPage>;\n current(): FrontendPage | null;\n act(action: () => unknown | Promise<unknown>): Promise<void>;\n settle(): Promise<void>;\n readonly errors: readonly WorkFailure[];\n /** The environment-local production Navigation instance. */\n readonly navigation: Navigation;\n /** Internal: dispose the active page and application lifecycles. */\n dispose(): Promise<void>;\n}\n\ninterface ScopeLike {\n extend(): ScopeLike;\n get(token: unknown): Promise<unknown>;\n registerClass?(target: unknown, options?: unknown): void;\n registerFunction?(token: unknown, factory: () => unknown, options?: unknown): void;\n registerValue?(token: unknown, value: unknown): void;\n dispose?(): Promise<void>;\n}\n\n/**\n * A mounted layout controller and the scope that owns it. A layout declared\n * `preserve: true` owns a DEDICATED scope that survives page transitions\n * (production parity: `createControllerSet`); every other layout shares the\n * page scope and dies with the page.\n */\ninterface ActiveLayout extends MountedLayout {\n index: number;\n /** Non-null only for a preserved layout that owns its scope. */\n ownScope: ScopeLike | null;\n /**\n * A preserved layout outlives the page that built it, so it cannot borrow\n * that page's lifecycle owner — it owns one, disposed when the layout is\n * finally dropped.\n */\n ownLifecycle: FrontendLifecycleOwner | null;\n}\n\ninterface ActivePage {\n identity: string;\n mountKey: string;\n view: ViewDef;\n scope: ScopeLike;\n lifecycle: FrontendLifecycleOwner;\n handle: FrontendPageHandle;\n controller: unknown;\n layouts: ActiveLayout[];\n}\n\nexport interface PageScopeContext {\n kind: 'page' | 'layout';\n /** Layout index within the view's layout stack (layout scopes only). */\n layoutIndex?: number;\n /** Controller identity when the source binds one (static pages omit it). */\n controller?: string;\n}\n\nexport interface CreateFrontendSurfaceOptions {\n /** The selected renderer aperture. */\n catalog: PageCatalog;\n /** Fresh renderer root for this environment (separate from the main root). */\n rendererRoot: ScopeLike;\n registry: WorkRegistry;\n /** Environment-local Navigation (also registered on the renderer root). */\n navigation: Navigation;\n /** Resolve a production controller identity to its class. */\n resolveController: (identity: string, view: ViewDef) => Promise<new (...args: never[]) => unknown>;\n /**\n * Resolve the page/layout data loaders of a view (companion `.load`\n * sources, already discovered and imported by the caller). Omitted: no\n * loaders — controllers initialize with `{ params, query }` exactly as\n * before. Loaders run under the page scope on every open/navigation,\n * layouts (non-preserved) first, then the view, BEFORE controllers exist.\n */\n resolveLoaders?: (view: ViewDef) => ViewLoaderSet | Promise<ViewLoaderSet>;\n /** Per-pass reactive flush hooks from the active runtime adapter (Node: none). */\n flushHooks?: ReadonlyArray<() => void | Promise<void>>;\n /**\n * Register per-scope services on a newly created scope (bridge client,\n * etc.). Called for the page scope, and once for each PRESERVED layout\n * that owns a dedicated scope — `context.kind` says which, so a caller\n * that tracks \"the page scope\" does not mistake a layout scope for it.\n */\n configurePageScope?: (\n scope: ScopeLike,\n view: ViewDef,\n context: PageScopeContext,\n ) => void | Promise<void>;\n}\n\n/**\n * Plain (undecorated) controller classes are registered on their scope so\n * they resolve — unless the hierarchy already decided how the token resolves\n * (a renderer-root substitution of the controller class), which keeps\n * winning inside the page scope.\n */\nfunction registerControllerUnlessBound(scope: ScopeLike, ControllerClass: unknown): void {\n const registrable = scope as { isRegistered?(token: unknown): boolean };\n if (typeof registrable.isRegistered === 'function' && registrable.isRegistered(ControllerClass)) return;\n if (typeof scope.registerClass === 'function') scope.registerClass(ControllerClass);\n}\n\nexport function createFrontendSurface(options: CreateFrontendSurfaceOptions): FrontendApplicationSurface {\n const { catalog, rendererRoot, registry, navigation } = options;\n const flushHooks = options.flushHooks ?? [];\n const application = new FrontendLifecycleOwner(registry, 'application');\n\n let active: ActivePage | null = null;\n let transitioning = false;\n let disposed = false;\n let navigationQueue: Promise<void> = Promise.resolve();\n let closing: Promise<void> | undefined;\n const retainedPageScopes = new Map<ScopeLike, FrontendLifecycleOwner>();\n const locallyOwnedControllers = new WeakSet<object>();\n const markController = (instance: unknown, token: unknown) => {\n const root = rendererRoot as ScopeLike & { isRegistered?(token: unknown): boolean };\n if (!root.isRegistered?.(token) && instance && typeof instance === 'object') locallyOwnedControllers.add(instance);\n guardControllerLifecycleOnce(instance);\n };\n const disposeLocalController = (instance: unknown) => instance && typeof instance === 'object' && locallyOwnedControllers.has(instance)\n ? disposeControllerLifecycle(instance) : Promise.resolve();\n\n const currentOwner = (): string => (active ? `page ${active.identity}` : 'application');\n\n async function constructPage(\n view: ViewDef,\n params: Record<string, string>,\n query: Record<string, string>,\n preserved: ActiveLayout[] = [],\n preservedDepth = 0,\n ): Promise<ActivePage> {\n const identity = pageIdentity(view);\n const ControllerClass = view.controller\n ? await options.resolveController(view.controller, view) : undefined;\n const scope = rendererRoot.extend();\n const lifecycle = new FrontendLifecycleOwner(registry, `page ${identity}`);\n\n const rollback: Array<() => unknown | Promise<unknown>> = [\n () => ExecutionContext.run(scope as never, () => scope.dispose?.()),\n () => lifecycle.dispose(),\n ];\n try {\n // The page lifecycle is injectable so controllers can register\n // deliberately detached finite work (D-FAS-01 §2.2). Scoped, not\n // Singleton: the lifecycle belongs to this page scope alone — a\n // Singleton would store at the hierarchy root and leak the first\n // page's lifecycle into every later page.\n scope.registerFunction?.(FrontendLifecycleOwner, () => lifecycle, { loadAs: LoadAs.Scoped });\n await ExecutionContext.run(scope as never, () => options.configurePageScope?.(scope, view, { kind: 'page', controller: view.controller }));\n if (ControllerClass) registerControllerUnlessBound(scope, ControllerClass);\n\n // Data loaders run first (shared orchestration): the route is already\n // seeded, no controller exists yet, and a failure rolls the page back.\n const route = { params, query };\n const loaderSet = options.resolveLoaders ? await options.resolveLoaders(view) : NO_LOADERS;\n const loaded = await ExecutionContext.run(scope as never, () =>\n runViewLoaders(loaderSet, createLoaderRequest(identity, route), preservedDepth),\n );\n\n // Layout controllers mount BEFORE the view controller (production\n // ordering in `createControllerSet`): a page controller may legitimately\n // read state a layout controller published during construction.\n const layouts: ActiveLayout[] = [...preserved];\n for (let index = preservedDepth; index < view.layouts.length; index += 1) {\n const layoutIdentity = view.layoutControllers?.[index];\n if (!layoutIdentity) continue;\n const preserve = view.layoutPreserve?.[index] === true;\n const LayoutClass = await options.resolveController(layoutIdentity, view);\n const ownScope = preserve ? rendererRoot.extend() : null;\n const ownLifecycle = ownScope\n ? new FrontendLifecycleOwner(registry, `layout ${layoutIdentity}`)\n : null;\n const layoutScope = ownScope ?? scope;\n if (ownScope) {\n rollback.push(() => ExecutionContext.run(ownScope as never, () => ownScope.dispose?.()));\n rollback.push(() => ownLifecycle!.dispose());\n ownScope.registerFunction?.(FrontendLifecycleOwner, () => ownLifecycle!, { loadAs: LoadAs.Scoped });\n await ExecutionContext.run(ownScope as never, () => options.configurePageScope?.(ownScope, view, {\n kind: 'layout',\n layoutIndex: index,\n controller: layoutIdentity,\n }));\n }\n registerControllerUnlessBound(layoutScope, LayoutClass);\n const instance = (await ExecutionContext.run(layoutScope as never, () =>\n layoutScope.get(LayoutClass),\n )) as Record<string, unknown>;\n markController(instance, LayoutClass);\n rollback.push(() => ExecutionContext.run(layoutScope as never, () => disposeLocalController(instance)));\n if (typeof instance.initialize === 'function') {\n await registry.track(\n Promise.resolve(\n ExecutionContext.run(layoutScope as never, () =>\n initializeController(instance, initializeArgument(route, loaded.layouts[index] ?? null)),\n ),\n ).then(() => undefined),\n { label: `initialize layout ${layoutIdentity}`, kind: 'initialize', owner: `page ${identity}` },\n );\n }\n layouts.push({\n index,\n path: view.layouts[index],\n controller: layoutIdentity,\n preserve,\n instance,\n scope: layoutScope,\n ownScope,\n ownLifecycle,\n });\n }\n\n const controller = ControllerClass ? (await ExecutionContext.run(scope as never, () =>\n scope.get(ControllerClass),\n )) as Record<string, unknown> : undefined;\n\n if (controller) markController(controller, ControllerClass);\n rollback.push(() => ExecutionContext.run(scope as never, () => disposeLocalController(controller)));\n\n if (typeof controller?.initialize === 'function') {\n await registry.track(\n Promise.resolve(\n ExecutionContext.run(scope as never, () =>\n initializeController(controller, initializeArgument(route, loaded.view)),\n ),\n ).then(() => undefined),\n { label: `initialize ${identity}`, kind: 'initialize', owner: `page ${identity}` },\n );\n }\n\n const handle = createFrontendPage({\n identity,\n controller,\n scope,\n layouts,\n onClose: async () => {\n await disposePage(identity);\n },\n });\n\n return { identity, mountKey: createNavigationMountKey(identity, params), view, scope, lifecycle, handle, controller, layouts };\n } catch (error) {\n try { await cleanupAll(rollback.reverse(), 'Wood page rollback failed'); }\n catch (cleanupError) { throw Object.assign(new Error('Wood page construction and cleanup failed'), { cause: error, errors: [error, cleanupError] }); }\n throw error;\n }\n }\n\n /**\n * End a page: the page lifecycle owner first (abort signal, owned\n * resources), then the IoC scopes — scope disposal is what runs each\n * controller's production `dispose()`/`destroy()` hook, so nothing here\n * calls those directly. Layouts in the preserved prefix keep running:\n * they belong to the next page now.\n */\n async function endPage(page: ActivePage, preservedDepth = 0): Promise<void> {\n page.handle.invalidate();\n // Production teardown order (NavigationShell.disposeControllerSet): the\n // page controller's hook, then each ending layout's, then the lifecycle\n // owner and the IoC scopes. The hooks are once-guarded, so the scope\n // disposal below does not run them a second time.\n const steps: Array<() => unknown | Promise<unknown>> = [\n () => ExecutionContext.run(page.scope as never, () => disposeLocalController(page.controller)),\n ];\n for (const layout of page.layouts) {\n if (layout.index < preservedDepth) continue;\n steps.push(() => ExecutionContext.run(layout.scope as never, () => disposeLocalController(layout.instance)));\n steps.push(() => layout.ownLifecycle?.dispose());\n if (layout.ownScope) steps.push(() => ExecutionContext.run(layout.ownScope as never, () => layout.ownScope!.dispose?.()));\n }\n const carriesPageScope = page.layouts.some(layout => layout.index < preservedDepth && layout.scope === page.scope);\n if (carriesPageScope) retainedPageScopes.set(page.scope, page.lifecycle);\n else {\n steps.push(() => page.lifecycle.dispose());\n steps.push(() => ExecutionContext.run(page.scope as never, () => page.scope.dispose?.()));\n }\n for (const [scope, lifecycle] of retainedPageScopes) {\n if (active?.layouts.some(layout => layout.scope === scope)) continue;\n retainedPageScopes.delete(scope);\n steps.push(() => lifecycle.dispose());\n steps.push(() => ExecutionContext.run(scope as never, () => scope.dispose?.()));\n }\n await cleanupAll(steps, 'Wood page cleanup failed');\n }\n\n async function disposePage(identity: string): Promise<void> {\n if (!active || active.identity !== identity) return;\n const ended = active;\n active = null;\n await endPage(ended);\n }\n\n async function transitionTo(entry: NavigationEntry): Promise<void> {\n if (disposed) return;\n // Resolve the destination through the selected aperture — navigation\n // outside it fails without widening the environment.\n const view = catalog.resolve(entry.page);\n const previous = active;\n // Preserved layouts carry over as live instances — the transition never\n // reconstructs them (production `preserve: true` semantics).\n // Same preservation rule the renderer's NavigationShell applies.\n const depth = previous\n ? computePreservedLayoutDepth(\n { layoutPaths: previous.view.layouts, layoutControllers: previous.view.layoutControllers, layoutPreserve: previous.view.layoutPreserve },\n { layoutPaths: view.layouts, layoutControllers: view.layoutControllers, layoutPreserve: view.layoutPreserve },\n entry.options ?? {},\n )\n : 0;\n const carried = previous ? previous.layouts.filter((layout) => layout.index < depth) : [];\n const next = await constructPage(view, entry.params, entry.query, carried, depth);\n if (disposed) {\n await endPage(next, depth);\n return;\n }\n active = next;\n if (previous) {\n await endPage(previous, depth);\n }\n }\n\n // Production navigation drives page transitions: a controller calling its\n // injected Navigation.go()/replace() inside the aperture triggers one\n // tracked finite navigation transition (18A D-FAS-01 §2.2).\n const unsubscribe = navigation.subscribe((entry) => {\n if (!entry || transitioning || disposed) return;\n if (active && createNavigationMountKey(entry.page, entry.params) === active.mountKey) return;\n if (!active) return; // initial open() seeds navigation itself\n const transition = navigationQueue.then(() => transitionTo(entry));\n navigationQueue = transition.catch(() => {});\n registry.track(transition, {\n label: `navigate ${active.identity} -> ${entry.page}`,\n kind: 'navigation',\n owner: currentOwner(),\n });\n });\n\n return {\n navigation,\n\n async open(openOptions: FrontendOpenOptions): Promise<FrontendPage> {\n if (disposed || transitioning) throw new PageCatalogError('Wood frontend is closed or opening a page');\n if (!openOptions || typeof openOptions.page !== 'string' || !openOptions.page.length) {\n throw new PageCatalogError('frontend.open() requires an explicit { page } identity');\n }\n if (active) {\n throw new PageCatalogError(\n `frontend.open() is test bootstrap; page \"${active.identity}\" is already open. ` +\n 'Drive production navigation for subsequent route changes, or close() the page first.',\n );\n }\n const view = catalog.resolve(openOptions.page);\n const params = openOptions.params ?? {};\n const query = openOptions.query ?? {};\n\n transitioning = true;\n try {\n // Seed production navigation state BEFORE construction: controllers\n // and their services legitimately read the current route (params,\n // query) during construction/initialize, exactly as in production\n // where the route exists before the page loads.\n navigation.replace(pageIdentity(view), params, query);\n const opened = await constructPage(view, params, query);\n if (disposed) { await endPage(opened); throw new PageCatalogError('Wood frontend was disposed during page construction'); }\n active = opened;\n } finally {\n transitioning = false;\n }\n return active.handle.page;\n },\n\n current(): FrontendPage | null {\n return active ? active.handle.page : null;\n },\n\n async act(action: () => unknown | Promise<unknown>): Promise<void> {\n void registry.track(\n Promise.resolve().then(() => action()).then(() => undefined),\n { label: 'act()', kind: 'tracked', owner: currentOwner() },\n ).catch(() => {\n // The failure is recorded by the registry; drain reports it with\n // its owner rather than losing the aggregate view.\n });\n await registry.drain(flushHooks);\n },\n\n async settle(): Promise<void> {\n await registry.drain(flushHooks);\n },\n\n get errors(): readonly WorkFailure[] {\n return registry.errors();\n },\n\n dispose(): Promise<void> {\n if (closing) return closing;\n disposed = true;\n unsubscribe();\n const ended = active;\n active = null;\n return closing = cleanupAll([\n () => ended ? endPage(ended) : undefined,\n () => application.dispose(),\n ], 'Wood frontend cleanup failed');\n },\n };\n}\n\nexport type { FrontendLifecycle };\nexport { FrontendWorkError };\n"],"mappings":"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","names":[]}
|
package/dist/frontend/index.d.ts
CHANGED
package/dist/index.cjs
CHANGED
|
@@ -41,6 +41,7 @@ __export(index_exports, {
|
|
|
41
41
|
WindowStateStore: () => import_window.WindowStateStore,
|
|
42
42
|
WoodAuthError: () => import_types.WoodAuthError,
|
|
43
43
|
WoodRouter: () => import_router.WoodRouter,
|
|
44
|
+
WoodTestBuilder: () => import_test_wood.WoodTestBuilder,
|
|
44
45
|
WoodTraceBatchContract: () => import_tracing.WoodTraceBatchContract,
|
|
45
46
|
WoodValidationError: () => import_types.WoodValidationError,
|
|
46
47
|
buildControllerArgs: () => import_controller.buildControllerArgs,
|
|
@@ -95,6 +96,7 @@ __export(index_exports, {
|
|
|
95
96
|
setRendererTraceEnabled: () => import_tracing.setRendererTraceEnabled,
|
|
96
97
|
setRendererTraceTransport: () => import_tracing.setRendererTraceTransport,
|
|
97
98
|
startBackendLoop: () => import_bridge.startBackendLoop,
|
|
99
|
+
testWood: () => import_test_wood.testWood,
|
|
98
100
|
usesOperationContext: () => import_controller.usesOperationContext,
|
|
99
101
|
woodBatchToTraceBatch: () => import_tracing.woodBatchToTraceBatch,
|
|
100
102
|
writeWoodDevMetadata: () => import_dev_metadata.writeWoodDevMetadata
|
|
@@ -125,6 +127,7 @@ var import_runtime = require("./runtime/index.js");
|
|
|
125
127
|
var import_navigation = require("./navigation/index.cjs");
|
|
126
128
|
var import_ipc = require("./ipc/index.cjs");
|
|
127
129
|
var import_tracing = require("./tracing/index.js");
|
|
130
|
+
var import_test_wood = require("./test-wood.js");
|
|
128
131
|
// Annotate the CommonJS export names for ESM import in node:
|
|
129
132
|
0 && (module.exports = {
|
|
130
133
|
BackendBridge,
|
|
@@ -150,6 +153,7 @@ var import_tracing = require("./tracing/index.js");
|
|
|
150
153
|
WindowStateStore,
|
|
151
154
|
WoodAuthError,
|
|
152
155
|
WoodRouter,
|
|
156
|
+
WoodTestBuilder,
|
|
153
157
|
WoodTraceBatchContract,
|
|
154
158
|
WoodValidationError,
|
|
155
159
|
buildControllerArgs,
|
|
@@ -204,6 +208,7 @@ var import_tracing = require("./tracing/index.js");
|
|
|
204
208
|
setRendererTraceEnabled,
|
|
205
209
|
setRendererTraceTransport,
|
|
206
210
|
startBackendLoop,
|
|
211
|
+
testWood,
|
|
207
212
|
usesOperationContext,
|
|
208
213
|
woodBatchToTraceBatch,
|
|
209
214
|
writeWoodDevMetadata
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["// @noego/wood — Declarative Electron desktop apps using the noego ecosystem\n\n// Types\nexport type {\n WoodConfig,\n WindowDef,\n DevConfig,\n ElectronBuilderConfig,\n OperationDef,\n RawOperationsDocument,\n RawModuleDef,\n RawOperationEntry,\n RawModuleOperationEntry,\n ViewDef,\n RawViewsDocument,\n RawViewEntry,\n ParameterDef,\n IpcContext,\n WoodMiddlewareContext,\n WoodMiddlewareFn,\n RequestData,\n ControllerArgs,\n LoaderResult,\n BridgeMessage,\n BridgeRequest,\n BridgeResponse,\n BridgeReady,\n BridgePush,\n BridgeElectronApi,\n SerializedError,\n ContextMenuContext,\n ContextMenuItem,\n ContextMenuEvent,\n} from './types/index.cjs';\n\n// Errors\nexport { WoodAuthError, WoodValidationError, BackendRestartingError } from './types/index.cjs';\n\n// Config\nexport {\n parseConfig,\n resolveRendererTraceBatching,\n RENDERER_TRACE_BATCHING_DEFAULTS,\n} from './config/index.cjs';\nexport type { ObservabilityConfig, RendererTraceBatchingConfig } from './config/index.cjs';\n\n// Parsers\nexport { parseOperations, parseOperationsDocument, parseOperationsFile } from './parser/index.cjs';\nexport { parseViews, parseViewsFile } from './parser/index.cjs';\n\n// Router\nexport { WoodRouter } from './router/index.cjs';\n\n// Validation\nexport { SchemaValidator } from './validation/index.cjs';\n\n// Middleware\nexport { MiddlewareResolver, buildMiddlewareContext, executeMiddleware } from './middleware/index.cjs';\n\n// Controller\nexport { ControllerResolver, buildControllerArgs, buildOperationContext, usesOperationContext, disposeControllerLifecycle } from './controller/index.cjs';\nexport type { ControllerLifecycle } from './controller/index.cjs';\n\n// Codegen\nexport { generatePreload } from './codegen/index.cjs';\nexport { generateTypes } from './codegen/index.cjs';\nexport { generateChannelMap } from './codegen/index.cjs';\nexport { generateTestMock } from './codegen/index.cjs';\nexport { generateControllerRegistration } from './codegen/index.cjs';\nexport type { ControllerRegistrationOptions } from './codegen/index.cjs';\nexport { generateRuntime } from './codegen/index.cjs';\nexport type { RuntimeGeneratorOptions } from './codegen/index.cjs';\nexport { generateRendererViewManifest } from './codegen/index.cjs';\nexport type { RendererViewManifestGeneratorOptions } from './codegen/index.cjs';\nexport { generateRendererControllerRegistration } from './codegen/index.cjs';\nexport type { RendererControllerRegistrationOptions } from './codegen/index.cjs';\nexport { generateRendererApp } from './codegen/index.cjs';\nexport type { RendererAppGeneratorOptions } from './codegen/index.cjs';\n\n// Window\nexport { WindowManager, WindowStateStore } from './window/index.cjs';\nexport type { ScreenLike, WindowBounds } from './window/index.cjs';\n\n// Loader\nexport { LoaderRunner } from './loader/index.cjs';\n\n// Bridge\nexport { BackendBridge, startBackendLoop, pushEvent } from './bridge/index.cjs';\n\n// Dev metadata (lightweight; safe at runtime)\n// Heavy dev tooling (WoodDevServer, BackendWatcher, YamlWatcher,\n// EsbuildBackend) is available via the '@noego/wood/dev' subpath only,\n// so production consumers never load esbuild/chokidar.\nexport {\n DEFAULT_WOOD_REMOTE_DEBUGGING_PORT,\n WOOD_DEV_DIRECTORY,\n WOOD_DEV_METADATA_BASENAME,\n resolveWoodRemoteDebuggingPort,\n resolveWoodDevDirectory,\n resolveWoodDevMetadataPath,\n writeWoodDevMetadata,\n readWoodDevMetadata,\n removeWoodDevMetadata,\n} from './dev/dev_metadata.js';\nexport type { WoodDevMetadata } from './dev/dev_metadata.js';\n\n// Runtime\nexport {\n createWoodRoot,\n getContainer,\n clearContainerRegistryForTests,\n getApplicationRoot,\n setApplicationRoot,\n clearApplicationRootForTests,\n clearRendererTraceBatchReceiverForTests,\n getRendererTraceBatchReceiver,\n runtime,\n setRendererTraceBatchReceiver,\n} from './runtime/index.js';\nexport type {\n GetContainerOptions,\n RuntimeOptions,\n RuntimeResult,\n RegisterRuntimeRouter,\n} from './runtime/index.cjs';\n\n// Navigation\nexport { Navigation, getNavigation, go, goto, goback } from './navigation/index.cjs';\nexport type { NavigationEntry, NavigationOptions } from './navigation/index.cjs';\n\n// Isomorphic IPC API\nexport { Ipc, getIpc } from './ipc/index.cjs';\nexport type { IpcPushOptions } from './ipc/index.cjs';\n\n// Tracing\nexport {\n FrameworkTracer,\n MainTracer,\n RendererTracer,\n TestTracer,\n TraceProvider,\n TraceProviderConfiguration,\n TraceCommitWriter,\n clearTraceHubForTests,\n getTraceEvents$,\n getTraceProducerId,\n ingestRemoteTraceEvent,\n publishMainTrace,\n publishTestTrace,\n registerTraceSink,\n setRendererTraceEnabled,\n setRendererTraceTransport,\n woodBatchToTraceBatch,\n WoodTraceBatchContract,\n} from './tracing/index.js';\nexport type { WoodTraceBatchConversion } from './tracing/index.js';\nexport type {\n TraceCommitRow,\n TraceCommitWriterOptions,\n TraceFlushOptions,\n TraceFlushResult,\n WoodTracePersistencePort,\n TraceDispatchResult,\n TraceEvent,\n TraceInput,\n TraceLevel,\n TraceProcess,\n TraceProviderMode,\n TraceRuntimeContext,\n TraceRuntime,\n TraceWaitOptions,\n WoodRendererTraceEvent,\n WoodRendererTraceInput,\n WoodTraceBatch,\n WoodTraceBatchAcknowledgement,\n WoodTraceBatchReceiver,\n WoodTraceBatchRuntimeContext,\n WoodTraceEventSink,\n WoodTraceEventSnapshot,\n WoodTraceSinkDisposer,\n} from './tracing/index.js';\n\n// Testing —
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["// @noego/wood — Declarative Electron desktop apps using the noego ecosystem\n\n// Types\nexport type {\n WoodConfig,\n WindowDef,\n DevConfig,\n ElectronBuilderConfig,\n OperationDef,\n RawOperationsDocument,\n RawModuleDef,\n RawOperationEntry,\n RawModuleOperationEntry,\n ViewDef,\n RawViewsDocument,\n RawViewEntry,\n ParameterDef,\n IpcContext,\n WoodMiddlewareContext,\n WoodMiddlewareFn,\n RequestData,\n ControllerArgs,\n LoaderResult,\n BridgeMessage,\n BridgeRequest,\n BridgeResponse,\n BridgeReady,\n BridgePush,\n BridgeElectronApi,\n SerializedError,\n ContextMenuContext,\n ContextMenuItem,\n ContextMenuEvent,\n} from './types/index.cjs';\n\n// Errors\nexport { WoodAuthError, WoodValidationError, BackendRestartingError } from './types/index.cjs';\n\n// Config\nexport {\n parseConfig,\n resolveRendererTraceBatching,\n RENDERER_TRACE_BATCHING_DEFAULTS,\n} from './config/index.cjs';\nexport type { ObservabilityConfig, RendererTraceBatchingConfig } from './config/index.cjs';\n\n// Parsers\nexport { parseOperations, parseOperationsDocument, parseOperationsFile } from './parser/index.cjs';\nexport { parseViews, parseViewsFile } from './parser/index.cjs';\n\n// Router\nexport { WoodRouter } from './router/index.cjs';\n\n// Validation\nexport { SchemaValidator } from './validation/index.cjs';\n\n// Middleware\nexport { MiddlewareResolver, buildMiddlewareContext, executeMiddleware } from './middleware/index.cjs';\n\n// Controller\nexport { ControllerResolver, buildControllerArgs, buildOperationContext, usesOperationContext, disposeControllerLifecycle } from './controller/index.cjs';\nexport type { ControllerLifecycle } from './controller/index.cjs';\n\n// Codegen\nexport { generatePreload } from './codegen/index.cjs';\nexport { generateTypes } from './codegen/index.cjs';\nexport { generateChannelMap } from './codegen/index.cjs';\nexport { generateTestMock } from './codegen/index.cjs';\nexport { generateControllerRegistration } from './codegen/index.cjs';\nexport type { ControllerRegistrationOptions } from './codegen/index.cjs';\nexport { generateRuntime } from './codegen/index.cjs';\nexport type { RuntimeGeneratorOptions } from './codegen/index.cjs';\nexport { generateRendererViewManifest } from './codegen/index.cjs';\nexport type { RendererViewManifestGeneratorOptions } from './codegen/index.cjs';\nexport { generateRendererControllerRegistration } from './codegen/index.cjs';\nexport type { RendererControllerRegistrationOptions } from './codegen/index.cjs';\nexport { generateRendererApp } from './codegen/index.cjs';\nexport type { RendererAppGeneratorOptions } from './codegen/index.cjs';\n\n// Window\nexport { WindowManager, WindowStateStore } from './window/index.cjs';\nexport type { ScreenLike, WindowBounds } from './window/index.cjs';\n\n// Loader\nexport { LoaderRunner } from './loader/index.cjs';\n\n// Bridge\nexport { BackendBridge, startBackendLoop, pushEvent } from './bridge/index.cjs';\n\n// Dev metadata (lightweight; safe at runtime)\n// Heavy dev tooling (WoodDevServer, BackendWatcher, YamlWatcher,\n// EsbuildBackend) is available via the '@noego/wood/dev' subpath only,\n// so production consumers never load esbuild/chokidar.\nexport {\n DEFAULT_WOOD_REMOTE_DEBUGGING_PORT,\n WOOD_DEV_DIRECTORY,\n WOOD_DEV_METADATA_BASENAME,\n resolveWoodRemoteDebuggingPort,\n resolveWoodDevDirectory,\n resolveWoodDevMetadataPath,\n writeWoodDevMetadata,\n readWoodDevMetadata,\n removeWoodDevMetadata,\n} from './dev/dev_metadata.js';\nexport type { WoodDevMetadata } from './dev/dev_metadata.js';\n\n// Runtime\nexport {\n createWoodRoot,\n getContainer,\n clearContainerRegistryForTests,\n getApplicationRoot,\n setApplicationRoot,\n clearApplicationRootForTests,\n clearRendererTraceBatchReceiverForTests,\n getRendererTraceBatchReceiver,\n runtime,\n setRendererTraceBatchReceiver,\n} from './runtime/index.js';\nexport type {\n GetContainerOptions,\n RuntimeOptions,\n RuntimeResult,\n RegisterRuntimeRouter,\n} from './runtime/index.cjs';\n\n// Navigation\nexport { Navigation, getNavigation, go, goto, goback } from './navigation/index.cjs';\nexport type { NavigationEntry, NavigationOptions } from './navigation/index.cjs';\n\n// Isomorphic IPC API\nexport { Ipc, getIpc } from './ipc/index.cjs';\nexport type { IpcPushOptions } from './ipc/index.cjs';\n\n// Tracing\nexport {\n FrameworkTracer,\n MainTracer,\n RendererTracer,\n TestTracer,\n TraceProvider,\n TraceProviderConfiguration,\n TraceCommitWriter,\n clearTraceHubForTests,\n getTraceEvents$,\n getTraceProducerId,\n ingestRemoteTraceEvent,\n publishMainTrace,\n publishTestTrace,\n registerTraceSink,\n setRendererTraceEnabled,\n setRendererTraceTransport,\n woodBatchToTraceBatch,\n WoodTraceBatchContract,\n} from './tracing/index.js';\nexport type { WoodTraceBatchConversion } from './tracing/index.js';\nexport type {\n TraceCommitRow,\n TraceCommitWriterOptions,\n TraceFlushOptions,\n TraceFlushResult,\n WoodTracePersistencePort,\n TraceDispatchResult,\n TraceEvent,\n TraceInput,\n TraceLevel,\n TraceProcess,\n TraceProviderMode,\n TraceRuntimeContext,\n TraceRuntime,\n TraceWaitOptions,\n WoodRendererTraceEvent,\n WoodRendererTraceInput,\n WoodTraceBatch,\n WoodTraceBatchAcknowledgement,\n WoodTraceBatchReceiver,\n WoodTraceBatchRuntimeContext,\n WoodTraceEventSink,\n WoodTraceEventSnapshot,\n WoodTraceSinkDisposer,\n} from './tracing/index.js';\n\n// Testing facade — production-safe: records the builder here and loads the\n// '@noego/wood/testing' implementation (DOM, Playwright, Electron mocks)\n// only inside build(). Compatibility helpers stay on the subpath export.\nexport { testWood, WoodTestBuilder } from './test-wood.js';\nexport type { WoodTestSelection } from './test-wood.js';\nexport type { TestWoodEnvironment, WoodDomMode } from './testing/index.js';\nexport type { WoodTestApi, WoodTestRawApi } from './testing-api.js';\n\nexport type { WoodBrowserHost, NativeWoodPage, NativeWoodTestEnvironment, WoodTestEnvironmentFor, WoodBrowserOpenOptions } from './testing/native_browser/native_browser.types.js';\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAoCA,mBAA2E;AAG3E,oBAIO;AAIP,oBAA8E;AAC9E,IAAAA,iBAA2C;AAG3C,oBAA2B;AAG3B,wBAAgC;AAGhC,wBAA8E;AAG9E,wBAAiI;AAIjI,qBAAgC;AAChC,IAAAC,kBAA8B;AAC9B,IAAAA,kBAAmC;AACnC,IAAAA,kBAAiC;AACjC,IAAAA,kBAA+C;AAE/C,IAAAA,kBAAgC;AAEhC,IAAAA,kBAA6C;AAE7C,IAAAA,kBAAuD;AAEvD,IAAAA,kBAAoC;AAIpC,oBAAgD;AAIhD,oBAA6B;AAG7B,oBAA2D;AAM3D,0BAUO;AAIP,qBAWO;AASP,wBAA4D;AAI5D,iBAA4B;AAI5B,qBAmBO;AA+BP,uBAA0C;","names":["import_parser","import_codegen"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -40,6 +40,11 @@ export { TraceCommitRow, TraceCommitWriter, TraceCommitWriterOptions, TraceFlush
|
|
|
40
40
|
export { FrameworkTracer, MainTracer, RendererTracer, TestTracer, TraceProvider, TraceProviderConfiguration, TraceProviderMode, TraceRuntime } from './tracing/trace_provider.cjs';
|
|
41
41
|
export { Navigation, NavigationEntry, getNavigation, go, goback, goto } from './navigation/index.cjs';
|
|
42
42
|
export { Ipc, getIpc } from './ipc/index.cjs';
|
|
43
|
+
export { WoodTestBuilder, WoodTestSelection, testWood } from './test-wood.cjs';
|
|
44
|
+
export { N as NativeWoodPage, a as NativeWoodTestEnvironment, T as TestWoodEnvironment, W as WoodBrowserHost, b as WoodBrowserOpenOptions, c as WoodTestEnvironmentFor } from './native_browser.types-vWXtE4rM.cjs';
|
|
45
|
+
export { WoodTestApi, WoodTestRawApi } from './testing-api.cjs';
|
|
46
|
+
export { WoodDomMode } from './testing/wood_test_selection.cjs';
|
|
47
|
+
import './testing/browser.cjs';
|
|
43
48
|
export { IpcPushOptions } from './ipc/shared.cjs';
|
|
44
49
|
export { NavigationOptions } from './navigation/layout_preservation.cjs';
|
|
45
50
|
import '@noego/ioc';
|
|
@@ -50,3 +55,23 @@ import 'rxjs';
|
|
|
50
55
|
import '@noego/trace';
|
|
51
56
|
import '@noego/telemetry/core';
|
|
52
57
|
import './navigation/automation_introspection.cjs';
|
|
58
|
+
import './loader/loader_orchestration.cjs';
|
|
59
|
+
import '@noego/testing/fetch';
|
|
60
|
+
import '@noego/testing';
|
|
61
|
+
import 'playwright';
|
|
62
|
+
import 'happy-dom';
|
|
63
|
+
import './testing/wood_config_source.cjs';
|
|
64
|
+
import './testing/create_router_bridge.cjs';
|
|
65
|
+
import './frontend/frontend_surface.cjs';
|
|
66
|
+
import './frontend/page_catalog.cjs';
|
|
67
|
+
import './frontend/work_registry.cjs';
|
|
68
|
+
import './frontend/frontend_lifecycle.cjs';
|
|
69
|
+
import './frontend/frontend_page.cjs';
|
|
70
|
+
import './testing/wood_env_renderer.cjs';
|
|
71
|
+
import './testing/wood_dom_animation.cjs';
|
|
72
|
+
import './testing/registration_only_root.cjs';
|
|
73
|
+
import './testing/test_wood.cjs';
|
|
74
|
+
import './trace-testing/trace_recorder.cjs';
|
|
75
|
+
import '@noego/trace/testing';
|
|
76
|
+
import './transport/wood_rpc_transport.cjs';
|
|
77
|
+
import './testing/geometry.cjs';
|
package/dist/index.d.ts
CHANGED
|
@@ -40,6 +40,11 @@ export { TraceCommitRow, TraceCommitWriter, TraceCommitWriterOptions, TraceFlush
|
|
|
40
40
|
export { FrameworkTracer, MainTracer, RendererTracer, TestTracer, TraceProvider, TraceProviderConfiguration, TraceProviderMode, TraceRuntime } from './tracing/trace_provider.js';
|
|
41
41
|
export { Navigation, NavigationEntry, getNavigation, go, goback, goto } from './navigation/index.js';
|
|
42
42
|
export { Ipc, getIpc } from './ipc/index.js';
|
|
43
|
+
export { WoodTestBuilder, WoodTestSelection, testWood } from './test-wood.js';
|
|
44
|
+
export { N as NativeWoodPage, a as NativeWoodTestEnvironment, T as TestWoodEnvironment, W as WoodBrowserHost, b as WoodBrowserOpenOptions, c as WoodTestEnvironmentFor } from './native_browser.types-BY2daUOS.js';
|
|
45
|
+
export { WoodTestApi, WoodTestRawApi } from './testing-api.js';
|
|
46
|
+
export { WoodDomMode } from './testing/wood_test_selection.js';
|
|
47
|
+
import './testing/browser.js';
|
|
43
48
|
export { IpcPushOptions } from './ipc/shared.js';
|
|
44
49
|
export { NavigationOptions } from './navigation/layout_preservation.js';
|
|
45
50
|
import '@noego/ioc';
|
|
@@ -50,3 +55,23 @@ import 'rxjs';
|
|
|
50
55
|
import '@noego/trace';
|
|
51
56
|
import '@noego/telemetry/core';
|
|
52
57
|
import './navigation/automation_introspection.js';
|
|
58
|
+
import './loader/loader_orchestration.js';
|
|
59
|
+
import '@noego/testing/fetch';
|
|
60
|
+
import '@noego/testing';
|
|
61
|
+
import 'playwright';
|
|
62
|
+
import 'happy-dom';
|
|
63
|
+
import './testing/wood_config_source.js';
|
|
64
|
+
import './testing/create_router_bridge.js';
|
|
65
|
+
import './frontend/frontend_surface.js';
|
|
66
|
+
import './frontend/page_catalog.js';
|
|
67
|
+
import './frontend/work_registry.js';
|
|
68
|
+
import './frontend/frontend_lifecycle.js';
|
|
69
|
+
import './frontend/frontend_page.js';
|
|
70
|
+
import './testing/wood_env_renderer.js';
|
|
71
|
+
import './testing/wood_dom_animation.js';
|
|
72
|
+
import './testing/registration_only_root.js';
|
|
73
|
+
import './testing/test_wood.js';
|
|
74
|
+
import './trace-testing/trace_recorder.js';
|
|
75
|
+
import '@noego/trace/testing';
|
|
76
|
+
import './transport/wood_rpc_transport.js';
|
|
77
|
+
import './testing/geometry.js';
|
package/dist/index.js
CHANGED
|
@@ -67,6 +67,7 @@ import {
|
|
|
67
67
|
woodBatchToTraceBatch,
|
|
68
68
|
WoodTraceBatchContract
|
|
69
69
|
} from "./tracing/index.js";
|
|
70
|
+
import { testWood, WoodTestBuilder } from "./test-wood.js";
|
|
70
71
|
export {
|
|
71
72
|
BackendBridge,
|
|
72
73
|
BackendRestartingError,
|
|
@@ -91,6 +92,7 @@ export {
|
|
|
91
92
|
WindowStateStore,
|
|
92
93
|
WoodAuthError,
|
|
93
94
|
WoodRouter,
|
|
95
|
+
WoodTestBuilder,
|
|
94
96
|
WoodTraceBatchContract,
|
|
95
97
|
WoodValidationError,
|
|
96
98
|
buildControllerArgs,
|
|
@@ -145,6 +147,7 @@ export {
|
|
|
145
147
|
setRendererTraceEnabled,
|
|
146
148
|
setRendererTraceTransport,
|
|
147
149
|
startBackendLoop,
|
|
150
|
+
testWood,
|
|
148
151
|
usesOperationContext,
|
|
149
152
|
woodBatchToTraceBatch,
|
|
150
153
|
writeWoodDevMetadata
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["// @noego/wood — Declarative Electron desktop apps using the noego ecosystem\n\n// Types\nexport type {\n WoodConfig,\n WindowDef,\n DevConfig,\n ElectronBuilderConfig,\n OperationDef,\n RawOperationsDocument,\n RawModuleDef,\n RawOperationEntry,\n RawModuleOperationEntry,\n ViewDef,\n RawViewsDocument,\n RawViewEntry,\n ParameterDef,\n IpcContext,\n WoodMiddlewareContext,\n WoodMiddlewareFn,\n RequestData,\n ControllerArgs,\n LoaderResult,\n BridgeMessage,\n BridgeRequest,\n BridgeResponse,\n BridgeReady,\n BridgePush,\n BridgeElectronApi,\n SerializedError,\n ContextMenuContext,\n ContextMenuItem,\n ContextMenuEvent,\n} from './types/index.js';\n\n// Errors\nexport { WoodAuthError, WoodValidationError, BackendRestartingError } from './types/index.js';\n\n// Config\nexport {\n parseConfig,\n resolveRendererTraceBatching,\n RENDERER_TRACE_BATCHING_DEFAULTS,\n} from './config/index.js';\nexport type { ObservabilityConfig, RendererTraceBatchingConfig } from './config/index.js';\n\n// Parsers\nexport { parseOperations, parseOperationsDocument, parseOperationsFile } from './parser/index.js';\nexport { parseViews, parseViewsFile } from './parser/index.js';\n\n// Router\nexport { WoodRouter } from './router/index.js';\n\n// Validation\nexport { SchemaValidator } from './validation/index.js';\n\n// Middleware\nexport { MiddlewareResolver, buildMiddlewareContext, executeMiddleware } from './middleware/index.js';\n\n// Controller\nexport { ControllerResolver, buildControllerArgs, buildOperationContext, usesOperationContext, disposeControllerLifecycle } from './controller/index.js';\nexport type { ControllerLifecycle } from './controller/index.js';\n\n// Codegen\nexport { generatePreload } from './codegen/index.js';\nexport { generateTypes } from './codegen/index.js';\nexport { generateChannelMap } from './codegen/index.js';\nexport { generateTestMock } from './codegen/index.js';\nexport { generateControllerRegistration } from './codegen/index.js';\nexport type { ControllerRegistrationOptions } from './codegen/index.js';\nexport { generateRuntime } from './codegen/index.js';\nexport type { RuntimeGeneratorOptions } from './codegen/index.js';\nexport { generateRendererViewManifest } from './codegen/index.js';\nexport type { RendererViewManifestGeneratorOptions } from './codegen/index.js';\nexport { generateRendererControllerRegistration } from './codegen/index.js';\nexport type { RendererControllerRegistrationOptions } from './codegen/index.js';\nexport { generateRendererApp } from './codegen/index.js';\nexport type { RendererAppGeneratorOptions } from './codegen/index.js';\n\n// Window\nexport { WindowManager, WindowStateStore } from './window/index.js';\nexport type { ScreenLike, WindowBounds } from './window/index.js';\n\n// Loader\nexport { LoaderRunner } from './loader/index.js';\n\n// Bridge\nexport { BackendBridge, startBackendLoop, pushEvent } from './bridge/index.js';\n\n// Dev metadata (lightweight; safe at runtime)\n// Heavy dev tooling (WoodDevServer, BackendWatcher, YamlWatcher,\n// EsbuildBackend) is available via the '@noego/wood/dev' subpath only,\n// so production consumers never load esbuild/chokidar.\nexport {\n DEFAULT_WOOD_REMOTE_DEBUGGING_PORT,\n WOOD_DEV_DIRECTORY,\n WOOD_DEV_METADATA_BASENAME,\n resolveWoodRemoteDebuggingPort,\n resolveWoodDevDirectory,\n resolveWoodDevMetadataPath,\n writeWoodDevMetadata,\n readWoodDevMetadata,\n removeWoodDevMetadata,\n} from './dev/dev_metadata.js';\nexport type { WoodDevMetadata } from './dev/dev_metadata.js';\n\n// Runtime\nexport {\n createWoodRoot,\n getContainer,\n clearContainerRegistryForTests,\n getApplicationRoot,\n setApplicationRoot,\n clearApplicationRootForTests,\n clearRendererTraceBatchReceiverForTests,\n getRendererTraceBatchReceiver,\n runtime,\n setRendererTraceBatchReceiver,\n} from './runtime/index.js';\nexport type {\n GetContainerOptions,\n RuntimeOptions,\n RuntimeResult,\n RegisterRuntimeRouter,\n} from './runtime/index.js';\n\n// Navigation\nexport { Navigation, getNavigation, go, goto, goback } from './navigation/index.js';\nexport type { NavigationEntry, NavigationOptions } from './navigation/index.js';\n\n// Isomorphic IPC API\nexport { Ipc, getIpc } from './ipc/index.js';\nexport type { IpcPushOptions } from './ipc/index.js';\n\n// Tracing\nexport {\n FrameworkTracer,\n MainTracer,\n RendererTracer,\n TestTracer,\n TraceProvider,\n TraceProviderConfiguration,\n TraceCommitWriter,\n clearTraceHubForTests,\n getTraceEvents$,\n getTraceProducerId,\n ingestRemoteTraceEvent,\n publishMainTrace,\n publishTestTrace,\n registerTraceSink,\n setRendererTraceEnabled,\n setRendererTraceTransport,\n woodBatchToTraceBatch,\n WoodTraceBatchContract,\n} from './tracing/index.js';\nexport type { WoodTraceBatchConversion } from './tracing/index.js';\nexport type {\n TraceCommitRow,\n TraceCommitWriterOptions,\n TraceFlushOptions,\n TraceFlushResult,\n WoodTracePersistencePort,\n TraceDispatchResult,\n TraceEvent,\n TraceInput,\n TraceLevel,\n TraceProcess,\n TraceProviderMode,\n TraceRuntimeContext,\n TraceRuntime,\n TraceWaitOptions,\n WoodRendererTraceEvent,\n WoodRendererTraceInput,\n WoodTraceBatch,\n WoodTraceBatchAcknowledgement,\n WoodTraceBatchReceiver,\n WoodTraceBatchRuntimeContext,\n WoodTraceEventSink,\n WoodTraceEventSnapshot,\n WoodTraceSinkDisposer,\n} from './tracing/index.js';\n\n// Testing —
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["// @noego/wood — Declarative Electron desktop apps using the noego ecosystem\n\n// Types\nexport type {\n WoodConfig,\n WindowDef,\n DevConfig,\n ElectronBuilderConfig,\n OperationDef,\n RawOperationsDocument,\n RawModuleDef,\n RawOperationEntry,\n RawModuleOperationEntry,\n ViewDef,\n RawViewsDocument,\n RawViewEntry,\n ParameterDef,\n IpcContext,\n WoodMiddlewareContext,\n WoodMiddlewareFn,\n RequestData,\n ControllerArgs,\n LoaderResult,\n BridgeMessage,\n BridgeRequest,\n BridgeResponse,\n BridgeReady,\n BridgePush,\n BridgeElectronApi,\n SerializedError,\n ContextMenuContext,\n ContextMenuItem,\n ContextMenuEvent,\n} from './types/index.js';\n\n// Errors\nexport { WoodAuthError, WoodValidationError, BackendRestartingError } from './types/index.js';\n\n// Config\nexport {\n parseConfig,\n resolveRendererTraceBatching,\n RENDERER_TRACE_BATCHING_DEFAULTS,\n} from './config/index.js';\nexport type { ObservabilityConfig, RendererTraceBatchingConfig } from './config/index.js';\n\n// Parsers\nexport { parseOperations, parseOperationsDocument, parseOperationsFile } from './parser/index.js';\nexport { parseViews, parseViewsFile } from './parser/index.js';\n\n// Router\nexport { WoodRouter } from './router/index.js';\n\n// Validation\nexport { SchemaValidator } from './validation/index.js';\n\n// Middleware\nexport { MiddlewareResolver, buildMiddlewareContext, executeMiddleware } from './middleware/index.js';\n\n// Controller\nexport { ControllerResolver, buildControllerArgs, buildOperationContext, usesOperationContext, disposeControllerLifecycle } from './controller/index.js';\nexport type { ControllerLifecycle } from './controller/index.js';\n\n// Codegen\nexport { generatePreload } from './codegen/index.js';\nexport { generateTypes } from './codegen/index.js';\nexport { generateChannelMap } from './codegen/index.js';\nexport { generateTestMock } from './codegen/index.js';\nexport { generateControllerRegistration } from './codegen/index.js';\nexport type { ControllerRegistrationOptions } from './codegen/index.js';\nexport { generateRuntime } from './codegen/index.js';\nexport type { RuntimeGeneratorOptions } from './codegen/index.js';\nexport { generateRendererViewManifest } from './codegen/index.js';\nexport type { RendererViewManifestGeneratorOptions } from './codegen/index.js';\nexport { generateRendererControllerRegistration } from './codegen/index.js';\nexport type { RendererControllerRegistrationOptions } from './codegen/index.js';\nexport { generateRendererApp } from './codegen/index.js';\nexport type { RendererAppGeneratorOptions } from './codegen/index.js';\n\n// Window\nexport { WindowManager, WindowStateStore } from './window/index.js';\nexport type { ScreenLike, WindowBounds } from './window/index.js';\n\n// Loader\nexport { LoaderRunner } from './loader/index.js';\n\n// Bridge\nexport { BackendBridge, startBackendLoop, pushEvent } from './bridge/index.js';\n\n// Dev metadata (lightweight; safe at runtime)\n// Heavy dev tooling (WoodDevServer, BackendWatcher, YamlWatcher,\n// EsbuildBackend) is available via the '@noego/wood/dev' subpath only,\n// so production consumers never load esbuild/chokidar.\nexport {\n DEFAULT_WOOD_REMOTE_DEBUGGING_PORT,\n WOOD_DEV_DIRECTORY,\n WOOD_DEV_METADATA_BASENAME,\n resolveWoodRemoteDebuggingPort,\n resolveWoodDevDirectory,\n resolveWoodDevMetadataPath,\n writeWoodDevMetadata,\n readWoodDevMetadata,\n removeWoodDevMetadata,\n} from './dev/dev_metadata.js';\nexport type { WoodDevMetadata } from './dev/dev_metadata.js';\n\n// Runtime\nexport {\n createWoodRoot,\n getContainer,\n clearContainerRegistryForTests,\n getApplicationRoot,\n setApplicationRoot,\n clearApplicationRootForTests,\n clearRendererTraceBatchReceiverForTests,\n getRendererTraceBatchReceiver,\n runtime,\n setRendererTraceBatchReceiver,\n} from './runtime/index.js';\nexport type {\n GetContainerOptions,\n RuntimeOptions,\n RuntimeResult,\n RegisterRuntimeRouter,\n} from './runtime/index.js';\n\n// Navigation\nexport { Navigation, getNavigation, go, goto, goback } from './navigation/index.js';\nexport type { NavigationEntry, NavigationOptions } from './navigation/index.js';\n\n// Isomorphic IPC API\nexport { Ipc, getIpc } from './ipc/index.js';\nexport type { IpcPushOptions } from './ipc/index.js';\n\n// Tracing\nexport {\n FrameworkTracer,\n MainTracer,\n RendererTracer,\n TestTracer,\n TraceProvider,\n TraceProviderConfiguration,\n TraceCommitWriter,\n clearTraceHubForTests,\n getTraceEvents$,\n getTraceProducerId,\n ingestRemoteTraceEvent,\n publishMainTrace,\n publishTestTrace,\n registerTraceSink,\n setRendererTraceEnabled,\n setRendererTraceTransport,\n woodBatchToTraceBatch,\n WoodTraceBatchContract,\n} from './tracing/index.js';\nexport type { WoodTraceBatchConversion } from './tracing/index.js';\nexport type {\n TraceCommitRow,\n TraceCommitWriterOptions,\n TraceFlushOptions,\n TraceFlushResult,\n WoodTracePersistencePort,\n TraceDispatchResult,\n TraceEvent,\n TraceInput,\n TraceLevel,\n TraceProcess,\n TraceProviderMode,\n TraceRuntimeContext,\n TraceRuntime,\n TraceWaitOptions,\n WoodRendererTraceEvent,\n WoodRendererTraceInput,\n WoodTraceBatch,\n WoodTraceBatchAcknowledgement,\n WoodTraceBatchReceiver,\n WoodTraceBatchRuntimeContext,\n WoodTraceEventSink,\n WoodTraceEventSnapshot,\n WoodTraceSinkDisposer,\n} from './tracing/index.js';\n\n// Testing facade — production-safe: records the builder here and loads the\n// '@noego/wood/testing' implementation (DOM, Playwright, Electron mocks)\n// only inside build(). Compatibility helpers stay on the subpath export.\nexport { testWood, WoodTestBuilder } from './test-wood.js';\nexport type { WoodTestSelection } from './test-wood.js';\nexport type { TestWoodEnvironment, WoodDomMode } from './testing/index.js';\nexport type { WoodTestApi, WoodTestRawApi } from './testing-api.js';\n\nexport type { WoodBrowserHost, NativeWoodPage, NativeWoodTestEnvironment, WoodTestEnvironmentFor, WoodBrowserOpenOptions } from './testing/native_browser/native_browser.types.js';\n"],"mappings":"AAoCA,SAAS,eAAe,qBAAqB,8BAA8B;AAG3E;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAIP,SAAS,iBAAiB,yBAAyB,2BAA2B;AAC9E,SAAS,YAAY,sBAAsB;AAG3C,SAAS,kBAAkB;AAG3B,SAAS,uBAAuB;AAGhC,SAAS,oBAAoB,wBAAwB,yBAAyB;AAG9E,SAAS,oBAAoB,qBAAqB,uBAAuB,sBAAsB,kCAAkC;AAIjI,SAAS,uBAAuB;AAChC,SAAS,qBAAqB;AAC9B,SAAS,0BAA0B;AACnC,SAAS,wBAAwB;AACjC,SAAS,sCAAsC;AAE/C,SAAS,uBAAuB;AAEhC,SAAS,oCAAoC;AAE7C,SAAS,8CAA8C;AAEvD,SAAS,2BAA2B;AAIpC,SAAS,eAAe,wBAAwB;AAIhD,SAAS,oBAAoB;AAG7B,SAAS,eAAe,kBAAkB,iBAAiB;AAM3D;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAIP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AASP,SAAS,YAAY,eAAe,IAAI,MAAM,cAAc;AAI5D,SAAS,KAAK,cAAc;AAI5B;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AA+BP,SAAS,UAAU,uBAAuB;","names":[]}
|
package/dist/loader/index.cjs
CHANGED
|
@@ -18,12 +18,29 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
18
18
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
19
|
var loader_exports = {};
|
|
20
20
|
__export(loader_exports, {
|
|
21
|
-
|
|
21
|
+
LOADER_COMPANION_SUFFIXES: () => import_loader_orchestration.LOADER_COMPANION_SUFFIXES,
|
|
22
|
+
LoaderRunner: () => import_loader_runner.LoaderRunner,
|
|
23
|
+
NO_LOADERS: () => import_loader_orchestration.NO_LOADERS,
|
|
24
|
+
assertDataLoader: () => import_loader_orchestration.assertDataLoader,
|
|
25
|
+
createLoaderRequest: () => import_loader_orchestration.createLoaderRequest,
|
|
26
|
+
initializeArgument: () => import_loader_orchestration.initializeArgument,
|
|
27
|
+
initializeController: () => import_loader_orchestration.initializeController,
|
|
28
|
+
loaderCompanionCandidates: () => import_loader_orchestration.loaderCompanionCandidates,
|
|
29
|
+
runViewLoaders: () => import_loader_orchestration.runViewLoaders
|
|
22
30
|
});
|
|
23
31
|
module.exports = __toCommonJS(loader_exports);
|
|
24
32
|
var import_loader_runner = require("./loader_runner.cjs");
|
|
33
|
+
var import_loader_orchestration = require("./loader_orchestration.cjs");
|
|
25
34
|
// Annotate the CommonJS export names for ESM import in node:
|
|
26
35
|
0 && (module.exports = {
|
|
27
|
-
|
|
36
|
+
LOADER_COMPANION_SUFFIXES,
|
|
37
|
+
LoaderRunner,
|
|
38
|
+
NO_LOADERS,
|
|
39
|
+
assertDataLoader,
|
|
40
|
+
createLoaderRequest,
|
|
41
|
+
initializeArgument,
|
|
42
|
+
initializeController,
|
|
43
|
+
loaderCompanionCandidates,
|
|
44
|
+
runViewLoaders
|
|
28
45
|
});
|
|
29
46
|
//# sourceMappingURL=index.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/loader/index.ts"],"sourcesContent":["export { LoaderRunner } from './loader_runner.cjs';\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,2BAA6B;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/loader/index.ts"],"sourcesContent":["export { LoaderRunner } from './loader_runner.cjs';\nexport {\n assertDataLoader,\n createLoaderRequest,\n initializeArgument,\n initializeController,\n loaderCompanionCandidates,\n LOADER_COMPANION_SUFFIXES,\n NO_LOADERS,\n runViewLoaders,\n} from './loader_orchestration.cjs';\nexport type {\n DataLoader,\n LoadedData,\n RouteInput,\n ViewLoaderResult,\n ViewLoaderSet,\n} from './loader_orchestration.cjs';\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,2BAA6B;AAC7B,kCASO;","names":[]}
|
package/dist/loader/index.d.cts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
export { LoaderRunner } from './loader_runner.cjs';
|
|
2
|
+
export { DataLoader, LOADER_COMPANION_SUFFIXES, LoadedData, NO_LOADERS, RouteInput, ViewLoaderResult, ViewLoaderSet, assertDataLoader, createLoaderRequest, initializeArgument, initializeController, loaderCompanionCandidates, runViewLoaders } from './loader_orchestration.cjs';
|
|
2
3
|
import '../types/context.cjs';
|
|
3
4
|
import '../types/views.cjs';
|
package/dist/loader/index.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
export { LoaderRunner } from './loader_runner.js';
|
|
2
|
+
export { DataLoader, LOADER_COMPANION_SUFFIXES, LoadedData, NO_LOADERS, RouteInput, ViewLoaderResult, ViewLoaderSet, assertDataLoader, createLoaderRequest, initializeArgument, initializeController, loaderCompanionCandidates, runViewLoaders } from './loader_orchestration.js';
|
|
2
3
|
import '../types/context.js';
|
|
3
4
|
import '../types/views.js';
|
package/dist/loader/index.js
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
import { LoaderRunner } from "./loader_runner.js";
|
|
2
|
+
import {
|
|
3
|
+
assertDataLoader,
|
|
4
|
+
createLoaderRequest,
|
|
5
|
+
initializeArgument,
|
|
6
|
+
initializeController,
|
|
7
|
+
loaderCompanionCandidates,
|
|
8
|
+
LOADER_COMPANION_SUFFIXES,
|
|
9
|
+
NO_LOADERS,
|
|
10
|
+
runViewLoaders
|
|
11
|
+
} from "./loader_orchestration.js";
|
|
2
12
|
export {
|
|
3
|
-
|
|
13
|
+
LOADER_COMPANION_SUFFIXES,
|
|
14
|
+
LoaderRunner,
|
|
15
|
+
NO_LOADERS,
|
|
16
|
+
assertDataLoader,
|
|
17
|
+
createLoaderRequest,
|
|
18
|
+
initializeArgument,
|
|
19
|
+
initializeController,
|
|
20
|
+
loaderCompanionCandidates,
|
|
21
|
+
runViewLoaders
|
|
4
22
|
};
|
|
5
23
|
//# sourceMappingURL=index.js.map
|
package/dist/loader/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/loader/index.ts"],"sourcesContent":["export { LoaderRunner } from './loader_runner.js';\n"],"mappings":"AAAA,SAAS,oBAAoB;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/loader/index.ts"],"sourcesContent":["export { LoaderRunner } from './loader_runner.js';\nexport {\n assertDataLoader,\n createLoaderRequest,\n initializeArgument,\n initializeController,\n loaderCompanionCandidates,\n LOADER_COMPANION_SUFFIXES,\n NO_LOADERS,\n runViewLoaders,\n} from './loader_orchestration.js';\nexport type {\n DataLoader,\n LoadedData,\n RouteInput,\n ViewLoaderResult,\n ViewLoaderSet,\n} from './loader_orchestration.js';\n"],"mappings":"AAAA,SAAS,oBAAoB;AAC7B;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;","names":[]}
|
|
@@ -0,0 +1,82 @@
|
|
|
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 loader_orchestration_exports = {};
|
|
20
|
+
__export(loader_orchestration_exports, {
|
|
21
|
+
LOADER_COMPANION_SUFFIXES: () => LOADER_COMPANION_SUFFIXES,
|
|
22
|
+
NO_LOADERS: () => NO_LOADERS,
|
|
23
|
+
assertDataLoader: () => assertDataLoader,
|
|
24
|
+
createLoaderRequest: () => createLoaderRequest,
|
|
25
|
+
initializeArgument: () => initializeArgument,
|
|
26
|
+
initializeController: () => initializeController,
|
|
27
|
+
loaderCompanionCandidates: () => loaderCompanionCandidates,
|
|
28
|
+
runViewLoaders: () => runViewLoaders
|
|
29
|
+
});
|
|
30
|
+
module.exports = __toCommonJS(loader_orchestration_exports);
|
|
31
|
+
const LOADER_COMPANION_SUFFIXES = [".load.ts", ".load.js"];
|
|
32
|
+
function loaderCompanionCandidates(viewPath) {
|
|
33
|
+
if (!/\.svelte$/.test(viewPath)) return [];
|
|
34
|
+
const base = viewPath.replace(/\.svelte$/, "");
|
|
35
|
+
return LOADER_COMPANION_SUFFIXES.map((suffix) => base + suffix);
|
|
36
|
+
}
|
|
37
|
+
const NO_LOADERS = Object.freeze({ layouts: Object.freeze([]), view: null });
|
|
38
|
+
function createLoaderRequest(page, route) {
|
|
39
|
+
return {
|
|
40
|
+
url: page,
|
|
41
|
+
params: { ...route.params },
|
|
42
|
+
query: { ...route.query },
|
|
43
|
+
context: {},
|
|
44
|
+
headers: {}
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
function assertDataLoader(value, label) {
|
|
48
|
+
if (typeof value !== "function") {
|
|
49
|
+
throw new TypeError(`${label} must default-export a loader function (request) => data`);
|
|
50
|
+
}
|
|
51
|
+
return value;
|
|
52
|
+
}
|
|
53
|
+
async function runViewLoaders(set, request, preservedDepth = 0) {
|
|
54
|
+
const layouts = [];
|
|
55
|
+
for (let index = 0; index < set.layouts.length; index += 1) {
|
|
56
|
+
const loader = index < preservedDepth ? null : set.layouts[index];
|
|
57
|
+
layouts.push(loader ? { data: await loader(request) } : null);
|
|
58
|
+
}
|
|
59
|
+
const view = set.view ? { data: await set.view(request) } : null;
|
|
60
|
+
return { layouts, view };
|
|
61
|
+
}
|
|
62
|
+
function initializeArgument(route, loaded) {
|
|
63
|
+
const base = { params: route.params, query: route.query };
|
|
64
|
+
return loaded ? { ...base, data: loaded.data } : base;
|
|
65
|
+
}
|
|
66
|
+
async function initializeController(controller, argument) {
|
|
67
|
+
const initialize = controller?.initialize;
|
|
68
|
+
if (typeof initialize !== "function") return;
|
|
69
|
+
await initialize.call(controller, argument);
|
|
70
|
+
}
|
|
71
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
72
|
+
0 && (module.exports = {
|
|
73
|
+
LOADER_COMPANION_SUFFIXES,
|
|
74
|
+
NO_LOADERS,
|
|
75
|
+
assertDataLoader,
|
|
76
|
+
createLoaderRequest,
|
|
77
|
+
initializeArgument,
|
|
78
|
+
initializeController,
|
|
79
|
+
loaderCompanionCandidates,
|
|
80
|
+
runViewLoaders
|
|
81
|
+
});
|
|
82
|
+
//# sourceMappingURL=loader_orchestration.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/loader/loader_orchestration.ts"],"sourcesContent":["/**\n * Shared page/layout data-loader orchestration.\n *\n * One implementation, three callers: the generated production renderer app\n * (`createControllerSet`), the Node frontend application surface\n * (`constructPage`) and the main-process `LoaderRunner`. It is deliberately\n * free of Node APIs so it ships to the browser through `@noego/wood/navigation`.\n *\n * Convention: a view `pages/chat.svelte` MAY have a companion loader\n * `pages/chat.load.ts` whose DEFAULT export is `(request: RequestData) =>\n * data`. Discovery (does the companion exist?) is a build-time concern of the\n * caller (codegen, the test config source, the runner); this module only\n * defines the companion identity and executes an already-resolved set:\n * layouts in stack order (outermost first), then the view. A layout carried\n * over from the previous page (`preservedDepth`) is never re-run.\n */\nimport type { RequestData } from '../types/context.cjs';\n\nexport type DataLoader = (request: RequestData) => unknown;\n\n/** Companion suffixes, in resolution order; more than one present is ambiguous. */\nexport const LOADER_COMPANION_SUFFIXES = ['.load.ts', '.load.js'] as const;\n\n/** The companion loader candidates for a `.svelte` view path (empty for other files). */\nexport function loaderCompanionCandidates(viewPath: string): string[] {\n if (!/\\.svelte$/.test(viewPath)) return [];\n const base = viewPath.replace(/\\.svelte$/, '');\n return LOADER_COMPANION_SUFFIXES.map((suffix) => base + suffix);\n}\n\n/** Loaders resolved for one view: index-aligned with the layout stack; `null` = no loader. */\nexport interface ViewLoaderSet {\n readonly layouts: ReadonlyArray<DataLoader | null>;\n readonly view: DataLoader | null;\n}\n\n/** A loader ran and produced `data` (which may legitimately be `undefined`). */\nexport interface LoadedData {\n readonly data: unknown;\n}\n\n/** Index-aligned outcome; `null` where no loader exists or the layout was preserved. */\nexport interface ViewLoaderResult {\n readonly layouts: ReadonlyArray<LoadedData | null>;\n readonly view: LoadedData | null;\n}\n\nexport interface RouteInput {\n readonly params: Record<string, string>;\n readonly query: Record<string, string>;\n}\n\nexport const NO_LOADERS: ViewLoaderSet = Object.freeze({ layouts: Object.freeze([]), view: null });\n\n/** The request a page/layout loader receives (`url` is the page identity). */\nexport function createLoaderRequest(page: string, route: RouteInput): RequestData {\n return {\n url: page,\n params: { ...route.params },\n query: { ...route.query },\n context: {},\n headers: {},\n };\n}\n\n/** A loader module's default export must be a function; anything else is a source error. */\nexport function assertDataLoader(value: unknown, label: string): DataLoader {\n if (typeof value !== 'function') {\n throw new TypeError(`${label} must default-export a loader function (request) => data`);\n }\n return value as DataLoader;\n}\n\n/**\n * Execute a view's loaders: layouts from `preservedDepth` in stack order,\n * then the view. Any failure rejects — the caller owns rollback.\n */\nexport async function runViewLoaders(\n set: ViewLoaderSet,\n request: RequestData,\n preservedDepth = 0,\n): Promise<ViewLoaderResult> {\n const layouts: Array<LoadedData | null> = [];\n for (let index = 0; index < set.layouts.length; index += 1) {\n const loader = index < preservedDepth ? null : set.layouts[index];\n layouts.push(loader ? { data: await loader(request) } : null);\n }\n const view = set.view ? { data: await set.view(request) } : null;\n return { layouts, view };\n}\n\n/**\n * The argument a controller's `initialize()` receives: `{ params, query }`\n * exactly as before when the controller has no loader, plus `data` when one\n * ran for it.\n */\nexport function initializeArgument(\n route: RouteInput,\n loaded: LoadedData | null | undefined,\n): { params: Record<string, string>; query: Record<string, string>; data?: unknown } {\n const base = { params: route.params, query: route.query };\n return loaded ? { ...base, data: loaded.data } : base;\n}\n\n/** Call `initialize(argument)` when the controller declares one. */\nexport async function initializeController(controller: unknown, argument: unknown): Promise<void> {\n const initialize = (controller as { initialize?: unknown } | null)?.initialize;\n if (typeof initialize !== 'function') return;\n await (initialize as (argument: unknown) => unknown).call(controller, argument);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAqBO,MAAM,4BAA4B,CAAC,YAAY,UAAU;AAGzD,SAAS,0BAA0B,UAA4B;AACpE,MAAI,CAAC,YAAY,KAAK,QAAQ,EAAG,QAAO,CAAC;AACzC,QAAM,OAAO,SAAS,QAAQ,aAAa,EAAE;AAC7C,SAAO,0BAA0B,IAAI,CAAC,WAAW,OAAO,MAAM;AAChE;AAwBO,MAAM,aAA4B,OAAO,OAAO,EAAE,SAAS,OAAO,OAAO,CAAC,CAAC,GAAG,MAAM,KAAK,CAAC;AAG1F,SAAS,oBAAoB,MAAc,OAAgC;AAChF,SAAO;AAAA,IACL,KAAK;AAAA,IACL,QAAQ,EAAE,GAAG,MAAM,OAAO;AAAA,IAC1B,OAAO,EAAE,GAAG,MAAM,MAAM;AAAA,IACxB,SAAS,CAAC;AAAA,IACV,SAAS,CAAC;AAAA,EACZ;AACF;AAGO,SAAS,iBAAiB,OAAgB,OAA2B;AAC1E,MAAI,OAAO,UAAU,YAAY;AAC/B,UAAM,IAAI,UAAU,GAAG,KAAK,0DAA0D;AAAA,EACxF;AACA,SAAO;AACT;AAMA,eAAsB,eACpB,KACA,SACA,iBAAiB,GACU;AAC3B,QAAM,UAAoC,CAAC;AAC3C,WAAS,QAAQ,GAAG,QAAQ,IAAI,QAAQ,QAAQ,SAAS,GAAG;AAC1D,UAAM,SAAS,QAAQ,iBAAiB,OAAO,IAAI,QAAQ,KAAK;AAChE,YAAQ,KAAK,SAAS,EAAE,MAAM,MAAM,OAAO,OAAO,EAAE,IAAI,IAAI;AAAA,EAC9D;AACA,QAAM,OAAO,IAAI,OAAO,EAAE,MAAM,MAAM,IAAI,KAAK,OAAO,EAAE,IAAI;AAC5D,SAAO,EAAE,SAAS,KAAK;AACzB;AAOO,SAAS,mBACd,OACA,QACmF;AACnF,QAAM,OAAO,EAAE,QAAQ,MAAM,QAAQ,OAAO,MAAM,MAAM;AACxD,SAAO,SAAS,EAAE,GAAG,MAAM,MAAM,OAAO,KAAK,IAAI;AACnD;AAGA,eAAsB,qBAAqB,YAAqB,UAAkC;AAChG,QAAM,aAAc,YAAgD;AACpE,MAAI,OAAO,eAAe,WAAY;AACtC,QAAO,WAA8C,KAAK,YAAY,QAAQ;AAChF;","names":[]}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { RequestData } from '../types/context.cjs';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Shared page/layout data-loader orchestration.
|
|
5
|
+
*
|
|
6
|
+
* One implementation, three callers: the generated production renderer app
|
|
7
|
+
* (`createControllerSet`), the Node frontend application surface
|
|
8
|
+
* (`constructPage`) and the main-process `LoaderRunner`. It is deliberately
|
|
9
|
+
* free of Node APIs so it ships to the browser through `@noego/wood/navigation`.
|
|
10
|
+
*
|
|
11
|
+
* Convention: a view `pages/chat.svelte` MAY have a companion loader
|
|
12
|
+
* `pages/chat.load.ts` whose DEFAULT export is `(request: RequestData) =>
|
|
13
|
+
* data`. Discovery (does the companion exist?) is a build-time concern of the
|
|
14
|
+
* caller (codegen, the test config source, the runner); this module only
|
|
15
|
+
* defines the companion identity and executes an already-resolved set:
|
|
16
|
+
* layouts in stack order (outermost first), then the view. A layout carried
|
|
17
|
+
* over from the previous page (`preservedDepth`) is never re-run.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
type DataLoader = (request: RequestData) => unknown;
|
|
21
|
+
/** Companion suffixes, in resolution order; more than one present is ambiguous. */
|
|
22
|
+
declare const LOADER_COMPANION_SUFFIXES: readonly [".load.ts", ".load.js"];
|
|
23
|
+
/** The companion loader candidates for a `.svelte` view path (empty for other files). */
|
|
24
|
+
declare function loaderCompanionCandidates(viewPath: string): string[];
|
|
25
|
+
/** Loaders resolved for one view: index-aligned with the layout stack; `null` = no loader. */
|
|
26
|
+
interface ViewLoaderSet {
|
|
27
|
+
readonly layouts: ReadonlyArray<DataLoader | null>;
|
|
28
|
+
readonly view: DataLoader | null;
|
|
29
|
+
}
|
|
30
|
+
/** A loader ran and produced `data` (which may legitimately be `undefined`). */
|
|
31
|
+
interface LoadedData {
|
|
32
|
+
readonly data: unknown;
|
|
33
|
+
}
|
|
34
|
+
/** Index-aligned outcome; `null` where no loader exists or the layout was preserved. */
|
|
35
|
+
interface ViewLoaderResult {
|
|
36
|
+
readonly layouts: ReadonlyArray<LoadedData | null>;
|
|
37
|
+
readonly view: LoadedData | null;
|
|
38
|
+
}
|
|
39
|
+
interface RouteInput {
|
|
40
|
+
readonly params: Record<string, string>;
|
|
41
|
+
readonly query: Record<string, string>;
|
|
42
|
+
}
|
|
43
|
+
declare const NO_LOADERS: ViewLoaderSet;
|
|
44
|
+
/** The request a page/layout loader receives (`url` is the page identity). */
|
|
45
|
+
declare function createLoaderRequest(page: string, route: RouteInput): RequestData;
|
|
46
|
+
/** A loader module's default export must be a function; anything else is a source error. */
|
|
47
|
+
declare function assertDataLoader(value: unknown, label: string): DataLoader;
|
|
48
|
+
/**
|
|
49
|
+
* Execute a view's loaders: layouts from `preservedDepth` in stack order,
|
|
50
|
+
* then the view. Any failure rejects — the caller owns rollback.
|
|
51
|
+
*/
|
|
52
|
+
declare function runViewLoaders(set: ViewLoaderSet, request: RequestData, preservedDepth?: number): Promise<ViewLoaderResult>;
|
|
53
|
+
/**
|
|
54
|
+
* The argument a controller's `initialize()` receives: `{ params, query }`
|
|
55
|
+
* exactly as before when the controller has no loader, plus `data` when one
|
|
56
|
+
* ran for it.
|
|
57
|
+
*/
|
|
58
|
+
declare function initializeArgument(route: RouteInput, loaded: LoadedData | null | undefined): {
|
|
59
|
+
params: Record<string, string>;
|
|
60
|
+
query: Record<string, string>;
|
|
61
|
+
data?: unknown;
|
|
62
|
+
};
|
|
63
|
+
/** Call `initialize(argument)` when the controller declares one. */
|
|
64
|
+
declare function initializeController(controller: unknown, argument: unknown): Promise<void>;
|
|
65
|
+
|
|
66
|
+
export { type DataLoader, LOADER_COMPANION_SUFFIXES, type LoadedData, NO_LOADERS, type RouteInput, type ViewLoaderResult, type ViewLoaderSet, assertDataLoader, createLoaderRequest, initializeArgument, initializeController, loaderCompanionCandidates, runViewLoaders };
|