@askrjs/askr 0.0.36 → 0.0.37

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.
Files changed (96) hide show
  1. package/README.md +17 -9
  2. package/dist/bench/components/benchmark-table.js +1 -1
  3. package/dist/bench/components/benchmark-table.js.map +1 -1
  4. package/dist/benchmark.js +3 -3
  5. package/dist/boot/index.d.ts +1 -7
  6. package/dist/boot/index.d.ts.map +1 -1
  7. package/dist/boot/index.js +22 -13
  8. package/dist/boot/index.js.map +1 -1
  9. package/dist/components/index.d.ts +2 -0
  10. package/dist/components/index.js +2 -0
  11. package/dist/components/link.d.ts +4 -5
  12. package/dist/components/link.d.ts.map +1 -1
  13. package/dist/components/link.js +2 -1
  14. package/dist/components/link.js.map +1 -1
  15. package/dist/foundations/icon/icon.d.ts.map +1 -1
  16. package/dist/foundations/icon/icon.js.map +1 -1
  17. package/dist/foundations/icon/icon.types.d.ts +2 -1
  18. package/dist/foundations/icon/icon.types.d.ts.map +1 -1
  19. package/dist/foundations/icon/index.d.ts +3 -0
  20. package/dist/foundations/icon/index.js +2 -0
  21. package/dist/foundations/index.d.ts +1 -18
  22. package/dist/foundations/index.js +2 -18
  23. package/dist/foundations/interactions/index.d.ts +7 -0
  24. package/dist/foundations/interactions/index.js +7 -0
  25. package/dist/foundations/interactions/interaction-policy.js +2 -2
  26. package/dist/foundations/state/index.d.ts +2 -0
  27. package/dist/foundations/state/index.js +2 -0
  28. package/dist/foundations/structures/index.d.ts +8 -0
  29. package/dist/foundations/structures/index.js +7 -0
  30. package/dist/foundations/utilities/index.d.ts +7 -0
  31. package/dist/foundations/utilities/index.js +6 -0
  32. package/dist/index.d.ts +2 -16
  33. package/dist/index.js +1 -17
  34. package/dist/index.js.map +1 -1
  35. package/dist/jsx-dev-runtime.d.ts +1 -1
  36. package/dist/jsx-dev-runtime.js.map +1 -1
  37. package/dist/jsx-runtime.d.ts +1 -1
  38. package/dist/jsx-runtime.js.map +1 -1
  39. package/dist/renderer/dom.js +26 -366
  40. package/dist/renderer/dom.js.map +1 -1
  41. package/dist/renderer/evaluate.js.map +1 -1
  42. package/dist/renderer/fastpath.js +20 -18
  43. package/dist/renderer/fastpath.js.map +1 -1
  44. package/dist/renderer/for-commit.js +486 -0
  45. package/dist/renderer/for-commit.js.map +1 -0
  46. package/dist/renderer/index.js.map +1 -1
  47. package/dist/renderer/keyed.js +84 -23
  48. package/dist/renderer/keyed.js.map +1 -1
  49. package/dist/renderer/reconcile.js +11 -18
  50. package/dist/renderer/reconcile.js.map +1 -1
  51. package/dist/renderer/utils.js +5 -1
  52. package/dist/renderer/utils.js.map +1 -1
  53. package/dist/resources/index.d.ts +1 -2
  54. package/dist/resources/index.js +1 -2
  55. package/dist/router/route.js +1 -1
  56. package/dist/runtime/for.d.ts.map +1 -1
  57. package/dist/runtime/for.js +33 -21
  58. package/dist/runtime/for.js.map +1 -1
  59. package/dist/runtime/operations.js +1 -1
  60. package/dist/runtime/selector.d.ts.map +1 -1
  61. package/dist/runtime/selector.js +180 -103
  62. package/dist/runtime/selector.js.map +1 -1
  63. package/dist/ssg/index.d.ts +1 -6
  64. package/dist/ssg/index.js +1 -6
  65. package/dist/ssr/context.d.ts +2 -1
  66. package/dist/ssr/context.d.ts.map +1 -1
  67. package/dist/ssr/context.js +28 -11
  68. package/dist/ssr/context.js.map +1 -1
  69. package/dist/ssr/index.d.ts +2 -31
  70. package/dist/ssr/index.d.ts.map +1 -1
  71. package/dist/ssr/index.js +4 -46
  72. package/dist/ssr/index.js.map +1 -1
  73. package/dist/ssr/render-keys.js +1 -12
  74. package/dist/ssr/render-keys.js.map +1 -1
  75. package/dist/ssr/verify-hydration.js +25 -0
  76. package/dist/ssr/verify-hydration.js.map +1 -0
  77. package/package.json +39 -16
  78. package/dist/_virtual/_rolldown/runtime.js +0 -7
  79. package/dist/foundations/core.d.ts +0 -15
  80. package/dist/foundations/core.js +0 -13
  81. package/dist/foundations/structures.d.ts +0 -7
  82. package/dist/foundations/structures.js +0 -6
  83. package/dist/ssg/batch-render.d.ts +0 -16
  84. package/dist/ssg/batch-render.d.ts.map +0 -1
  85. package/dist/ssg/generate-metadata.d.ts +0 -24
  86. package/dist/ssg/generate-metadata.d.ts.map +0 -1
  87. package/dist/ssg/resolve-ssg-data.d.ts +0 -23
  88. package/dist/ssg/resolve-ssg-data.d.ts.map +0 -1
  89. package/dist/ssg/route-utils.d.ts +0 -16
  90. package/dist/ssg/route-utils.d.ts.map +0 -1
  91. package/dist/ssg/write-static-files.d.ts +0 -15
  92. package/dist/ssg/write-static-files.d.ts.map +0 -1
  93. package/dist/ssr/render-keys.d.ts +0 -37
  94. package/dist/ssr/render-keys.d.ts.map +0 -1
  95. package/dist/ssr/stream-render.js +0 -88
  96. package/dist/ssr/stream-render.js.map +0 -1
package/README.md CHANGED
@@ -7,7 +7,8 @@ and static-site generation entrypoints.
7
7
  ## Quick Start
8
8
 
9
9
  ```ts
10
- import { createIsland, state } from '@askrjs/askr';
10
+ import { state } from '@askrjs/askr';
11
+ import { createIsland } from '@askrjs/askr/boot';
11
12
 
12
13
  function Counter() {
13
14
  const [count, setCount] = state(0);
@@ -23,8 +24,11 @@ createIsland({ root: document.body, component: Counter });
23
24
  ### Runtime
24
25
 
25
26
  `@askrjs/askr` exports the core runtime primitives: `state()`, `derive()`,
26
- `selector()`, `resource()`, `ErrorBoundary`, routing helpers, JSX control-flow
27
- helpers, and SSR/SSG entrypoints.
27
+ `selector()`, `defineContext()`, `readContext()`, `getSignal()`, and the JSX
28
+ runtime exports.
29
+
30
+ App startup, routing, async resources, data helpers, and error boundaries live
31
+ on their own subpaths.
28
32
 
29
33
  ### Explicit reactivity
30
34
 
@@ -42,15 +46,17 @@ Startup belongs in `@askrjs/askr/boot`. Routing helpers live in
42
46
  `@askrjs/askr/router`.
43
47
 
44
48
  ```ts
45
- import { createIsland, createSPA } from '@askrjs/askr/boot';
46
- import { getRoutes, route } from '@askrjs/askr/router';
49
+ import { createSPA } from '@askrjs/askr/boot';
50
+ import { getManifest, registerRoutes, route } from '@askrjs/askr/router';
47
51
 
48
- route('/', () => <Home />);
49
- route('/about', () => <About />);
52
+ registerRoutes(() => {
53
+ route('/', () => <Home />);
54
+ route('/about', () => <About />);
55
+ });
50
56
 
51
57
  createSPA({
52
58
  root: document.body,
53
- routes: getRoutes(),
59
+ manifest: getManifest(),
54
60
  });
55
61
  ```
56
62
 
@@ -73,6 +79,8 @@ return <div>{data.value.name}</div>;
73
79
  }
74
80
  ```
75
81
 
82
+ Query and mutation helpers live in `@askrjs/askr/data`.
83
+
76
84
  ### Developer error boundaries
77
85
 
78
86
  `ErrorBoundary` is the opt-in boundary primitive for render-time failures. It
@@ -80,7 +88,7 @@ renders a visible fallback in development, still logs the underlying error, and
80
88
  can reset when your app state changes.
81
89
 
82
90
  ```ts
83
- import { ErrorBoundary } from '@askrjs/askr';
91
+ import { ErrorBoundary } from '@askrjs/askr/components';
84
92
 
85
93
  function App() {
86
94
  return (
@@ -1,7 +1,7 @@
1
1
  import { jsx } from "../../jsx-runtime.js";
2
2
  import "../../jsx-runtime2.js";
3
3
  import { For } from "../../control/for.js";
4
- import "../../index.js";
4
+ import "../../control/index.js";
5
5
  import { BenchmarkRow } from "./benchmark-row.js";
6
6
  //#region src/bench/components/benchmark-table.tsx
7
7
  function BenchmarkTable({ rows, isSelected, onSelect, onRemove }) {
@@ -1 +1 @@
1
- {"version":3,"file":"benchmark-table.js","names":[],"sources":["../../../src/bench/components/benchmark-table.tsx"],"sourcesContent":["import { For, type State } from '../../index';\nimport { BenchmarkRow, type BenchmarkRowData } from './benchmark-row';\n\ninterface BenchmarkTableProps {\n rows: State<BenchmarkRowData[]>;\n isSelected: (id: number) => boolean;\n onSelect: (id: number) => void;\n onRemove: (id: number) => void;\n}\n\nexport function BenchmarkTable({\n rows,\n isSelected,\n onSelect,\n onRemove,\n}: BenchmarkTableProps) {\n return (\n <table class=\"table table-hover table-striped test-data\">\n <tbody>\n {\n <For each={() => rows()} by={(item) => item.id}>\n {(item) => (\n <BenchmarkRow\n item={item}\n isSelected={isSelected}\n onSelect={onSelect}\n onRemove={onRemove}\n />\n )}\n </For>\n }\n </tbody>\n </table>\n );\n}\n"],"mappings":";;;;;;AAUA,SAAgB,eAAe,EAC7B,MACA,YACA,UACA,YACsB;CACtB,OACE,oBAAC,SAAD;EAAO,OAAM;YACX,oBAAC,SAAD,EAAA,UAEI,oBAAC,KAAD;GAAK,YAAY,MAAM;GAAE,KAAK,SAAS,KAAK;cACxC,SACA,oBAAC,cAAD;IACQ;IACM;IACF;IACA;IACV,CAAA;GAEA,CAAA,EAEF,CAAA;EACF,CAAA"}
1
+ {"version":3,"file":"benchmark-table.js","names":[],"sources":["../../../src/bench/components/benchmark-table.tsx"],"sourcesContent":["import { For } from '../../control';\nimport type { State } from '../../runtime/state';\nimport { BenchmarkRow, type BenchmarkRowData } from './benchmark-row';\n\ninterface BenchmarkTableProps {\n rows: State<BenchmarkRowData[]>;\n isSelected: (id: number) => boolean;\n onSelect: (id: number) => void;\n onRemove: (id: number) => void;\n}\n\nexport function BenchmarkTable({\n rows,\n isSelected,\n onSelect,\n onRemove,\n}: BenchmarkTableProps) {\n return (\n <table class=\"table table-hover table-striped test-data\">\n <tbody>\n {\n <For each={() => rows()} by={(item) => item.id}>\n {(item) => (\n <BenchmarkRow\n item={item}\n isSelected={isSelected}\n onSelect={onSelect}\n onRemove={onRemove}\n />\n )}\n </For>\n }\n </tbody>\n </table>\n );\n}\n"],"mappings":";;;;;;AAWA,SAAgB,eAAe,EAC7B,MACA,YACA,UACA,YACsB;CACtB,OACE,oBAAC,SAAD;EAAO,OAAM;YACX,oBAAC,SAAD,EAAA,UAEI,oBAAC,KAAD;GAAK,YAAY,MAAM;GAAE,KAAK,SAAS,KAAK;cACxC,SACA,oBAAC,cAAD;IACQ;IACM;IACF;IACA;IACV,CAAA;GAEA,CAAA,EAEF,CAAA;EACF,CAAA"}
package/dist/benchmark.js CHANGED
@@ -3,15 +3,15 @@ import { jsx } from "./jsx-runtime.js";
3
3
  import { installRendererBridge } from "./renderer/index.js";
4
4
  import { state } from "./runtime/state.js";
5
5
  import { selector } from "./runtime/selector.js";
6
- import { createIsland } from "./boot/index.js";
7
6
  import "./jsx-runtime2.js";
7
+ import { createIsland } from "./boot/index.js";
8
8
  import { BenchmarkTable } from "./bench/components/benchmark-table.js";
9
9
  //#region src/bench/benchmark-entry.tsx
10
10
  installRendererBridge();
11
11
  const benchmarkMetadata = {
12
12
  packageName: "@askrjs/askr",
13
- packageVersion: "0.0.36",
14
- buildLabel: "0.0.36-local"
13
+ packageVersion: "0.0.37",
14
+ buildLabel: "0.0.37-local"
15
15
  };
16
16
  function getBenchmarkMetadata() {
17
17
  return { ...benchmarkMetadata };
@@ -3,12 +3,6 @@ import { Route, RouteAuthOptions, RouteManifest } from "../common/router.js";
3
3
  import { ScrollRestorationOptions } from "../router/navigate.js";
4
4
 
5
5
  //#region src/boot/index.d.ts
6
- /**
7
- * Explicitly teardown an app mounted on `root` if present. This is the
8
- * recommended API for deterministic cleanup rather than relying on overriding
9
- * `innerHTML` setter behavior.
10
- */
11
- declare function teardownApp(_root: Element | string): void;
12
6
  type IslandConfig = {
13
7
  root: Element | string;
14
8
  component: ComponentFunction;
@@ -88,5 +82,5 @@ declare function cleanupApp(root: Element | string): void;
88
82
  */
89
83
  declare function hasApp(root: Element | string): boolean;
90
84
  //#endregion
91
- export { HydrateSPAConfig, IslandConfig, IslandsConfig, SPAConfig, cleanupApp, createIsland, createIslands, createSPA, hasApp, hydrateSPA, teardownApp };
85
+ export { HydrateSPAConfig, IslandConfig, IslandsConfig, SPAConfig, cleanupApp, createIsland, createIslands, createSPA, hasApp, hydrateSPA };
92
86
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../../src/boot/index.ts"],"mappings":";;;;;;AAsIA;;;;iBAAgB,WAAA,CAAY,KAAA,EAAO,OAAA;AAAA,KA4GvB,YAAA;EACV,IAAA,EAAM,OAAA;EACN,SAAA,EAAW,iBAAA;EAEX,aAAA;EAEA,MAAA;AAAA;AAAA,KAGU,aAAA;EACV,OAAA,EAAS,YAAA;AAAA;AAAA,KAGC,SAAA;EACV,IAAA,EAAM,OAAA;EALI;;;;;AAIZ;;EASE,QAAA,GAAW,aAAA,EARL;EAUN,MAAA,GAAS,KAAA;EACT,IAAA,GAAO,gBAAA;EACP,iBAAA,aAA8B,wBAAA;EAC9B,aAAA;EACA,SAAA;AAAA;AAAA,KAGU,gBAAA;EACV,IAAA,EAAM,OAAA,WAVN;EAYA,QAAA,GAAW,aAAA,EAVX;EAYA,MAAA,GAAS,KAAA;EACT,IAAA,GAAO,gBAAA;EACP,iBAAA,aAA8B,wBAAA;EAC9B,aAAA;EACA,OAAA;IACE,YAAA;IACA,cAAA;IACA,cAAA;IACA,aAAA;IACA,aAAA;EAAA;AAAA;;;;iBAOY,YAAA,CAAa,MAAA,EAAQ,YAAA;;;;;iBA6CrB,aAAA,CAAc,MAAA,EAAQ,aAAA;;;;;;;;;;;;;;;iBA2BhB,SAAA,CAAU,MAAA,EAAQ,SAAA,GAAY,OAAA;;;AAxEpD;;iBAqXsB,UAAA,CAAW,MAAA,EAAQ,gBAAA,GAAmB,OAAA;;;AAxU5D;;iBAsbgB,UAAA,CAAW,IAAA,EAAM,OAAA;;;AA3ZjC;iBA4agB,MAAA,CAAO,IAAA,EAAM,OAAA"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../../src/boot/index.ts"],"mappings":";;;;;KAwOY,YAAA;EACV,IAAA,EAAM,OAAA;EACN,SAAA,EAAW,iBAAA;EAEX,aAAA;EAEA,MAAA;AAAA;AAAA,KAGU,aAAA;EACV,OAAA,EAAS,YAAA;AAAA;AAAA,KAGC,SAAA;EACV,IAAA,EAAM,OAAA;EARA;AAGR;;;;;AAIA;EASE,QAAA,GAAW,aAAA;EAEX,MAAA,GAAS,KAAA;EACT,IAAA,GAAO,gBAAA;EACP,iBAAA,aAA8B,wBAAA;EAC9B,aAAA;EACA,SAAA;AAAA;AAAA,KAGU,gBAAA;EACV,IAAA,EAAM,OAAA,WAlBA;EAoBN,QAAA,GAAW,aAAA,EAZA;EAcX,MAAA,GAAS,KAAA;EACT,IAAA,GAAO,gBAAA;EACP,iBAAA,aAA8B,wBAAA;EAC9B,aAAA;EACA,OAAA;IACE,YAAA;IACA,cAAA;IACA,cAAA;IACA,aAAA;IACA,aAAA;EAAA;AAAA;;;;iBAOY,YAAA,CAAa,MAAA,EAAQ,YAAA;;;;;iBA6CrB,aAAA,CAAc,MAAA,EAAQ,aAAA;;;;;;;;;;;;;;;iBA2BhB,SAAA,CAAU,MAAA,EAAQ,SAAA,GAAY,OAAA;;;;AAxEpD;iBA0YsB,UAAA,CAAW,MAAA,EAAQ,gBAAA,GAAmB,OAAA;;;;AA7V5D;iBA4cgB,UAAA,CAAW,IAAA,EAAM,OAAA;;;;iBAiBjB,MAAA,CAAO,IAAA,EAAM,OAAA"}
@@ -4,6 +4,7 @@ import { globalScheduler } from "../runtime/scheduler.js";
4
4
  import { ELEMENT_TYPE, Fragment } from "../common/jsx.js";
5
5
  import { cleanupComponent, createComponentInstance, mountComponent } from "../runtime/component.js";
6
6
  import { removeAllListeners } from "../renderer/cleanup.js";
7
+ import { setStaticChildSlotsCacheEnabled } from "../renderer/dom.js";
7
8
  import { installRendererBridge } from "../renderer/index.js";
8
9
  import { assertExecutionModel } from "../runtime/execution-model.js";
9
10
  import { _applyManifest, _drainLazy, _setActiveRouteAuthOptions, _snapshotLazy, clearRoutes, lockRouteRegistration, resolveRoute, resolveRouteRequest, route, setServerLocation } from "../router/route.js";
@@ -63,14 +64,6 @@ function attachCleanupForRoot(rootElement, instance) {
63
64
  });
64
65
  } catch {}
65
66
  }
66
- /**
67
- * Explicitly teardown an app mounted on `root` if present. This is the
68
- * recommended API for deterministic cleanup rather than relying on overriding
69
- * `innerHTML` setter behavior.
70
- */
71
- function teardownApp(_root) {
72
- throw new Error("The `teardownApp` alias has been removed. Use `cleanupApp(root)` instead.");
73
- }
74
67
  function mountOrUpdate(rootElement, componentFn, options) {
75
68
  const wrappedFn = (props, ctx) => {
76
69
  const out = componentFn(props, ctx);
@@ -292,16 +285,27 @@ async function applySelectiveHydration(rootElement, resolved, path, cleanupStric
292
285
  const hasPermanentSkips = (hydrateOptions.skipSelectors?.length ?? 0) > 0;
293
286
  const hasBelowFoldDeferral = !!hydrateOptions.deferBelowFold;
294
287
  const hasSelectiveBoundaries = hasPermanentSkips || hasBelowFoldDeferral;
288
+ let staticChildSlotsCacheSuspended = false;
289
+ const restoreStaticChildSlotsCache = () => {
290
+ if (!staticChildSlotsCacheSuspended) return;
291
+ setStaticChildSlotsCacheEnabled(true);
292
+ staticChildSlotsCacheSuspended = false;
293
+ };
295
294
  if (hydrateOptions.skipSelectors?.length) markSkippedElements(rootElement, hydrateOptions.skipSelectors);
296
295
  let deferredBoundaries = [];
297
296
  if (hydrateOptions.deferBelowFold) {
297
+ setStaticChildSlotsCacheEnabled(false);
298
+ staticChildSlotsCacheSuspended = true;
298
299
  const foldY = hydrateOptions.foldThreshold ?? window.innerHeight;
299
300
  deferredBoundaries = collectDeferredBelowFoldBoundaries(rootElement, foldY);
300
301
  const handleScroll = () => {
301
302
  const { activated, remaining } = activateVisibleDeferredBoundaries(deferredBoundaries, foldY);
302
303
  if (!activated) return;
303
304
  flushHydrationActivation(rootElement);
304
- if (remaining === 0) window.removeEventListener("scroll", handleScroll);
305
+ if (remaining === 0) {
306
+ restoreStaticChildSlotsCache();
307
+ window.removeEventListener("scroll", handleScroll);
308
+ }
305
309
  };
306
310
  window.addEventListener("scroll", handleScroll, { passive: true });
307
311
  }
@@ -315,9 +319,14 @@ async function applySelectiveHydration(rootElement, resolved, path, cleanupStric
315
319
  mountOrUpdate(rootElement, (() => resolved.handler(resolved.params)), { cleanupStrict });
316
320
  await registerAppNavigation(rootElement, path);
317
321
  if (hydrateOptions.deferUntilIdle && deferredBoundaries.length > 0) await queueIdleWork(() => {
318
- const { activated } = activateVisibleDeferredBoundaries(deferredBoundaries, Number.POSITIVE_INFINITY);
319
- if (activated) flushHydrationActivation(rootElement);
322
+ try {
323
+ const { activated } = activateVisibleDeferredBoundaries(deferredBoundaries, Number.POSITIVE_INFINITY);
324
+ if (activated) flushHydrationActivation(rootElement);
325
+ } finally {
326
+ restoreStaticChildSlotsCache();
327
+ }
320
328
  });
329
+ if (deferredBoundaries.length === 0) restoreStaticChildSlotsCache();
321
330
  }
322
331
  /**
323
332
  * hydrateSPA: Hydrate server-rendered HTML.
@@ -350,7 +359,7 @@ async function hydrateSPA(config) {
350
359
  handler: r.handler,
351
360
  namespace: r.options.namespace
352
361
  })) : config.routes;
353
- const { verifyHydrationSyncForUrl } = await import("../ssr/index.js");
362
+ const { verifyHydrationSyncForUrl } = await import("../ssr/verify-hydration.js");
354
363
  if (!verifyHydrationSyncForUrl({
355
364
  root: rootElement,
356
365
  url: currentUrl,
@@ -391,6 +400,6 @@ function hasApp(root) {
391
400
  return instancesByRoot.has(rootElement);
392
401
  }
393
402
  //#endregion
394
- export { cleanupApp, createIsland, createIslands, createSPA, hasApp, hydrateSPA, teardownApp };
403
+ export { cleanupApp, createIsland, createIslands, createSPA, hasApp, hydrateSPA };
395
404
 
396
405
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../src/boot/index.ts"],"sourcesContent":["/**\n * App bootstrap and mount\n */\n\nimport {\n createComponentInstance,\n mountComponent,\n cleanupComponent,\n type ComponentFunction,\n type ComponentInstance,\n} from '../runtime/component';\nimport {\n isDevelopmentEnvironment,\n isProductionEnvironment,\n} from '../common/env';\nimport { logger } from '../dev/logger';\nimport { initializeNavigation, registerAppInstance } from '../router/navigate';\nimport {\n configureScrollRestoration,\n type ScrollRestorationOptions,\n} from '../router/navigate';\nimport {\n _applyManifest,\n _drainLazy,\n _setActiveRouteAuthOptions,\n _snapshotLazy,\n clearRoutes,\n lockRouteRegistration,\n resolveRoute,\n resolveRouteRequest,\n route as registerRoute,\n setServerLocation,\n} from '../router/route';\nimport { globalScheduler } from '../runtime/scheduler';\nimport { assertExecutionModel } from '../runtime/execution-model';\n\nconst HAS_ROUTES_KEY = Symbol.for('__ASKR_HAS_ROUTES__');\n\nlet componentIdCounter = 0;\n\n// Track instances by root element to support multiple createIsland calls on same root\nconst instancesByRoot = new WeakMap<Element, ComponentInstance>();\n\n// Symbol for storing cleanup on elements\nconst CLEANUP_SYMBOL = Symbol.for('__askrCleanup__');\n\n// Type for elements that have cleanup functions attached\ninterface ElementWithCleanup extends Element {\n [CLEANUP_SYMBOL]?: () => void;\n}\n\nfunction attachCleanupForRoot(\n rootElement: Element,\n instance: ComponentInstance\n) {\n (rootElement as ElementWithCleanup)[CLEANUP_SYMBOL] = () => {\n // Attempt to remove listeners and cleanup instances under the root.\n // In non-strict mode we preserve previous behavior by swallowing errors\n // (but logging in dev); in strict mode we aggregate and re-throw.\n const errors: unknown[] = [];\n try {\n removeAllListeners(rootElement);\n } catch (e) {\n errors.push(e);\n }\n\n try {\n cleanupComponent(instance as ComponentInstance);\n } catch (e) {\n errors.push(e);\n }\n\n if (errors.length > 0) {\n if (instance.cleanupStrict) {\n throw new AggregateError(errors, `cleanup failed for app root`);\n } else if (isDevelopmentEnvironment()) {\n for (const err of errors) logger.warn('[Askr] cleanup error:', err);\n }\n }\n };\n\n try {\n const descriptor =\n Object.getOwnPropertyDescriptor(rootElement, 'innerHTML') ||\n Object.getOwnPropertyDescriptor(\n Object.getPrototypeOf(rootElement),\n 'innerHTML'\n ) ||\n Object.getOwnPropertyDescriptor(Element.prototype, 'innerHTML');\n\n if (descriptor && (descriptor.get || descriptor.set)) {\n Object.defineProperty(rootElement, 'innerHTML', {\n get: descriptor.get\n ? function (this: Element) {\n return descriptor.get!.call(this);\n }\n : undefined,\n set: function (this: Element, value: string) {\n if (value === '' && instancesByRoot.get(this) === instance) {\n try {\n removeAllListeners(rootElement);\n } catch (e) {\n if (instance.cleanupStrict) throw e;\n if (isDevelopmentEnvironment()) {\n logger.warn('[Askr] cleanup error:', e);\n }\n }\n\n try {\n cleanupComponent(instance as ComponentInstance);\n } catch (e) {\n if (instance.cleanupStrict) throw e;\n if (isDevelopmentEnvironment()) {\n logger.warn('[Askr] cleanup error:', e);\n }\n }\n }\n if (descriptor.set) {\n return descriptor.set.call(this, value);\n }\n },\n configurable: true,\n });\n }\n } catch {\n // If Object.defineProperty fails, ignore\n }\n}\n\n/**\n * Explicitly teardown an app mounted on `root` if present. This is the\n * recommended API for deterministic cleanup rather than relying on overriding\n * `innerHTML` setter behavior.\n */\nexport function teardownApp(_root: Element | string) {\n throw new Error(\n 'The `teardownApp` alias has been removed. Use `cleanupApp(root)` instead.'\n );\n}\n\nimport { Fragment, ELEMENT_TYPE } from '../jsx';\n\nimport { DefaultPortal } from '../foundations/structures/portal';\n\nfunction mountOrUpdate(\n rootElement: Element,\n componentFn: ComponentFunction,\n options?: { cleanupStrict?: boolean }\n) {\n // Ensure root component always includes a DefaultPortal host by wrapping it.\n const wrappedFn: ComponentFunction = (props, ctx) => {\n const out = componentFn(props, ctx);\n const portalVNode = {\n $$typeof: ELEMENT_TYPE,\n type: DefaultPortal,\n props: {},\n key: '__default_portal',\n } as unknown;\n return {\n $$typeof: ELEMENT_TYPE,\n type: Fragment,\n props: {\n children:\n out === undefined || out === null\n ? [portalVNode]\n : [out, portalVNode],\n },\n } as unknown as ReturnType<ComponentFunction>;\n };\n // Preserve the original component name for debugging/dev warnings\n Object.defineProperty(wrappedFn, 'name', {\n value: componentFn.name || 'Component',\n });\n\n // Clean up existing cleanup function before mounting new one\n const existingCleanup = (rootElement as ElementWithCleanup)[CLEANUP_SYMBOL];\n if (existingCleanup) existingCleanup();\n\n let instance = instancesByRoot.get(rootElement);\n\n if (instance) {\n removeAllListeners(rootElement);\n try {\n cleanupComponent(instance);\n } catch (e) {\n // If previous cleanup threw in strict mode, log but continue mounting new instance\n if (isDevelopmentEnvironment()) {\n logger.warn('[Askr] prior cleanup threw:', e);\n }\n }\n\n instance.fn = wrappedFn;\n instance.evaluationGeneration++;\n instance.mounted = false;\n instance.expectedStateIndices = [];\n instance.firstRenderComplete = false;\n instance.isRoot = true;\n // Update strict flag if provided\n if (options && typeof options.cleanupStrict === 'boolean') {\n instance.cleanupStrict = options.cleanupStrict;\n }\n } else {\n const componentId = String(++componentIdCounter);\n instance = createComponentInstance(componentId, wrappedFn, {}, rootElement);\n instancesByRoot.set(rootElement, instance);\n instance.isRoot = true;\n // Initialize strict flag from options\n if (options && typeof options.cleanupStrict === 'boolean') {\n instance.cleanupStrict = options.cleanupStrict;\n }\n }\n\n attachCleanupForRoot(rootElement, instance);\n mountComponent(instance);\n globalScheduler.flush();\n}\n\nfunction bindResolvedRouteHandler(resolved: ResolvedRoute): ComponentFunction {\n return () =>\n resolved.handler(resolved.params) as ReturnType<ComponentFunction>;\n}\n\nfunction bindDeniedStatus(status: number): ComponentFunction {\n return () => ({\n type: 'div',\n props: {\n 'data-route-denied': String(status),\n },\n children: [String(status)],\n });\n}\n\n// New strongly-typed init functions\nimport type {\n Route,\n RouteManifest,\n ResolvedRoute,\n RouteAuthOptions,\n} from '../common/router';\nimport { installRendererBridge, removeAllListeners } from '../renderer';\ninstallRendererBridge();\n\nexport type IslandConfig = {\n root: Element | string;\n component: ComponentFunction;\n // Optional: surface cleanup errors during teardown for this island\n cleanupStrict?: boolean;\n // Explicitly disallow routes on islands at type level\n routes?: never;\n};\n\nexport type IslandsConfig = {\n islands: IslandConfig[];\n};\n\nexport type SPAConfig = {\n root: Element | string;\n /**\n * Preferred: pass the route manifest built via `registerRoutes(() => { ... })`.\n * ```ts\n * import { getManifest } from '@askrjs/askr/router';\n * await createSPA({ root: '#app', manifest: getManifest() });\n * ```\n */\n manifest?: RouteManifest;\n /** Legacy: flat route array — kept for backward compatibility and test fixtures. */\n routes?: Route[];\n auth?: RouteAuthOptions;\n scrollRestoration?: boolean | ScrollRestorationOptions;\n cleanupStrict?: boolean;\n component?: never;\n};\n\nexport type HydrateSPAConfig = {\n root: Element | string;\n /** Preferred manifest input — see `SPAConfig.manifest`. */\n manifest?: RouteManifest;\n /** Legacy flat route array. */\n routes?: Route[];\n auth?: RouteAuthOptions;\n scrollRestoration?: boolean | ScrollRestorationOptions;\n cleanupStrict?: boolean;\n hydrate?: {\n verifyMarkup?: boolean;\n deferUntilIdle?: boolean;\n deferBelowFold?: boolean;\n foldThreshold?: number;\n skipSelectors?: string[];\n };\n};\n\n/**\n * createIsland: Enhances existing DOM (no router, mounts once)\n */\nexport function createIsland(config: IslandConfig): void {\n assertExecutionModel('islands');\n if (!config || typeof config !== 'object') {\n throw new Error('createIsland requires a config object');\n }\n if (typeof config.component !== 'function') {\n throw new Error('createIsland: component must be a function');\n }\n\n const rootElement =\n typeof config.root === 'string'\n ? document.getElementById(config.root)\n : config.root;\n if (!rootElement) throw new Error(`Root element not found: ${config.root}`);\n\n // Islands must not initialize router or routes\n if ('routes' in config) {\n throw new Error(\n 'createIsland does not accept routes; use createSPA for routed apps'\n );\n }\n\n // Routes are never supported with islands.\n // If routes were registered (even at module load time), fail fast to avoid\n // surprising partial router behavior.\n try {\n const g = globalThis as unknown as Record<string | symbol, unknown>;\n if (g[HAS_ROUTES_KEY]) {\n throw new Error(\n 'Routes are not supported with islands. Use createSPA (client) or createSSR (server) instead.'\n );\n }\n } catch {\n // ignore\n }\n\n mountOrUpdate(rootElement, config.component, {\n cleanupStrict: config.cleanupStrict,\n });\n}\n\n/**\n * createIslands: Enhances one or more existing DOM roots (no router).\n * The only public islands constructor.\n */\nexport function createIslands(config: IslandsConfig): void {\n assertExecutionModel('islands');\n if (!config || typeof config !== 'object') {\n throw new Error('createIslands requires a config object');\n }\n if (!Array.isArray(config.islands) || config.islands.length === 0) {\n throw new Error('createIslands requires a non-empty islands array');\n }\n for (const island of config.islands) {\n createIsland(island);\n }\n}\n\n/**\n * createSPA: Initializes router and mounts the app with the provided route manifest or route table.\n *\n * Preferred usage with manifest:\n * ```ts\n * import { getManifest } from '@askrjs/askr/router';\n * await createSPA({ root: '#app', manifest: getManifest() });\n * ```\n *\n * Legacy usage with plain routes array (still supported):\n * ```ts\n * await createSPA({ root: '#app', routes: getRoutes() });\n * ```\n */\nexport async function createSPA(config: SPAConfig): Promise<void> {\n assertExecutionModel('spa');\n if (!config || typeof config !== 'object') {\n throw new Error('createSPA requires a config object');\n }\n\n const hasManifest =\n config.manifest != null && config.manifest.records.length > 0;\n const hasRoutes = Array.isArray(config.routes) && config.routes.length > 0;\n\n if (!hasManifest && !hasRoutes) {\n throw new Error(\n 'createSPA requires a route manifest or route table. ' +\n 'Pass `manifest: getManifest()` or `routes: getRoutes()`. ' +\n 'If you are enhancing existing HTML, use createIsland instead.'\n );\n }\n\n const rootElement =\n typeof config.root === 'string'\n ? document.getElementById(config.root)\n : config.root;\n if (!rootElement) throw new Error(`Root element not found: ${config.root}`);\n\n const pendingLazyAtBoot = _snapshotLazy();\n\n configureScrollRestoration(config.scrollRestoration);\n\n clearRoutes();\n\n if (hasManifest) {\n // Preferred path: apply pre-built manifest records directly\n _applyManifest(config.manifest!);\n } else {\n // Legacy path: register plain Route objects (no layout metadata)\n for (const r of config.routes!) {\n registerRoute(r.path, r.handler as Parameters<typeof registerRoute>[1]);\n }\n }\n\n const routeAuth = config.auth ?? config.manifest?.auth;\n _setActiveRouteAuthOptions(routeAuth);\n\n // Drain any lazy() imports so all split chunks are ready before mounting\n await _drainLazy(pendingLazyAtBoot);\n\n // Lock registration in production to prevent late registration surprises\n if (isProductionEnvironment()) lockRouteRegistration();\n\n // Mount the currently-resolved route handler (if any)\n let path = typeof window !== 'undefined' ? window.location.pathname : '/';\n let href =\n typeof window !== 'undefined'\n ? `${window.location.pathname}${window.location.search}${window.location.hash}`\n : path;\n let resolved = await resolveRouteRequest(href, { auth: routeAuth });\n\n while (\n typeof window !== 'undefined' &&\n resolved &&\n resolved.kind === 'redirect'\n ) {\n const redirectTarget = new URL(resolved.to, window.location.href);\n const redirectHref = `${redirectTarget.pathname}${redirectTarget.search}${redirectTarget.hash}`;\n window.history.replaceState({ path: redirectHref }, '', redirectHref);\n path = redirectTarget.pathname;\n href = redirectHref;\n resolved = await resolveRouteRequest(href, { auth: routeAuth });\n }\n\n if (!resolved) {\n mountOrUpdate(rootElement, () => ({ type: 'div', children: [] }), {\n cleanupStrict: config.cleanupStrict,\n });\n\n await registerAppNavigation(rootElement, path);\n return;\n }\n\n if (resolved.kind === 'redirect') {\n mountOrUpdate(rootElement, () => ({ type: 'div', children: [] }), {\n cleanupStrict: config.cleanupStrict,\n });\n\n await registerAppNavigation(rootElement, path);\n return;\n }\n\n mountOrUpdate(\n rootElement,\n resolved.kind === 'deny'\n ? bindDeniedStatus(resolved.status)\n : bindResolvedRouteHandler({\n handler: resolved.handler,\n params: resolved.params,\n }),\n {\n cleanupStrict: config.cleanupStrict,\n }\n );\n\n await registerAppNavigation(rootElement, path);\n}\n\n/**\n * Mark elements that should be skipped during hydration\n */\nfunction markSkippedElements(root: Element, skipSelectors: string[]): void {\n if (skipSelectors.length === 0) {\n return;\n }\n\n const uniqueSelectors = Array.from(new Set(skipSelectors));\n const selectorList = uniqueSelectors.join(', ');\n const elements = root.querySelectorAll(selectorList);\n elements.forEach((el) => el.setAttribute('data-skip-hydrate', 'true'));\n}\n\nfunction collectDeferredBelowFoldBoundaries(\n root: Element,\n foldY: number\n): Element[] {\n const boundaries: Element[] = [];\n const stack: Element[] = [];\n\n for (let index = root.children.length - 1; index >= 0; index -= 1) {\n stack.push(root.children[index]);\n }\n\n while (stack.length > 0) {\n const element = stack.pop()!;\n\n if (element.hasAttribute('data-skip-hydrate')) {\n continue;\n }\n\n const rect = element.getBoundingClientRect();\n if (rect.top >= foldY) {\n element.setAttribute('data-skip-hydrate', 'true');\n boundaries.push(element);\n continue;\n }\n\n for (let index = element.children.length - 1; index >= 0; index -= 1) {\n stack.push(element.children[index]);\n }\n }\n\n return boundaries;\n}\n\nfunction activateVisibleDeferredBoundaries(\n boundaries: Element[],\n foldY: number\n): { activated: boolean; remaining: number } {\n let activated = false;\n let remaining = 0;\n\n for (const element of boundaries) {\n if (!element.hasAttribute('data-skip-hydrate')) {\n continue;\n }\n\n const rect = element.getBoundingClientRect();\n if (rect.top < foldY) {\n element.removeAttribute('data-skip-hydrate');\n activated = true;\n } else {\n remaining += 1;\n }\n }\n\n return { activated, remaining };\n}\n\nfunction queueIdleWork(work: () => void): Promise<void> {\n return new Promise((resolve) => {\n if (typeof requestIdleCallback !== 'undefined') {\n requestIdleCallback(\n () => {\n work();\n resolve();\n },\n { timeout: 2000 }\n );\n return;\n }\n\n setTimeout(() => {\n work();\n resolve();\n }, 0);\n });\n}\n\nfunction flushHydrationActivation(rootElement: Element): void {\n const instance = instancesByRoot.get(rootElement);\n if (!instance) return;\n instance._enqueueRun?.();\n globalScheduler.flush();\n}\n\nfunction shouldVerifyHydrationMarkup(config: HydrateSPAConfig): boolean {\n const explicit = config.hydrate?.verifyMarkup;\n if (typeof explicit === 'boolean') {\n return explicit;\n }\n\n return !isProductionEnvironment();\n}\n\nasync function registerAppNavigation(rootElement: Element, path: string) {\n const instance = instancesByRoot.get(rootElement);\n if (!instance) throw new Error('Internal error: app instance missing');\n registerAppInstance(instance as ComponentInstance, path);\n initializeNavigation();\n}\n\n/**\n * Apply selective hydration with deferral options\n */\nasync function applySelectiveHydration(\n rootElement: Element,\n resolved: { handler: ComponentFunction; params: Record<string, unknown> },\n path: string,\n cleanupStrict: boolean | undefined,\n hydrateOptions: NonNullable<HydrateSPAConfig['hydrate']>\n): Promise<void> {\n const hasPermanentSkips = (hydrateOptions.skipSelectors?.length ?? 0) > 0;\n const hasBelowFoldDeferral = !!hydrateOptions.deferBelowFold;\n const hasSelectiveBoundaries = hasPermanentSkips || hasBelowFoldDeferral;\n\n if (hydrateOptions.skipSelectors?.length) {\n markSkippedElements(rootElement, hydrateOptions.skipSelectors);\n }\n\n let deferredBoundaries: Element[] = [];\n if (hydrateOptions.deferBelowFold) {\n const foldY = hydrateOptions.foldThreshold ?? window.innerHeight;\n deferredBoundaries = collectDeferredBelowFoldBoundaries(rootElement, foldY);\n\n const handleScroll = () => {\n const { activated, remaining } = activateVisibleDeferredBoundaries(\n deferredBoundaries,\n foldY\n );\n\n if (!activated) {\n return;\n }\n\n flushHydrationActivation(rootElement);\n\n if (remaining === 0) {\n window.removeEventListener('scroll', handleScroll);\n }\n };\n\n window.addEventListener('scroll', handleScroll, { passive: true });\n }\n\n if (hydrateOptions.deferUntilIdle && !hasSelectiveBoundaries) {\n await queueIdleWork(() => {\n mountOrUpdate(\n rootElement,\n (() => resolved.handler(resolved.params)) as ComponentFunction,\n {\n cleanupStrict,\n }\n );\n });\n await registerAppNavigation(rootElement, path);\n return;\n }\n\n mountOrUpdate(\n rootElement,\n (() => resolved.handler(resolved.params)) as ComponentFunction,\n {\n cleanupStrict,\n }\n );\n await registerAppNavigation(rootElement, path);\n\n if (hydrateOptions.deferUntilIdle && deferredBoundaries.length > 0) {\n await queueIdleWork(() => {\n const { activated } = activateVisibleDeferredBoundaries(\n deferredBoundaries,\n Number.POSITIVE_INFINITY\n );\n if (activated) {\n flushHydrationActivation(rootElement);\n }\n });\n }\n}\n\n/**\n * hydrateSPA: Hydrate server-rendered HTML.\n * Accepts either a `manifest` (preferred) or a legacy `routes` array.\n */\nexport async function hydrateSPA(config: HydrateSPAConfig): Promise<void> {\n assertExecutionModel('spa');\n if (!config || typeof config !== 'object') {\n throw new Error('hydrateSPA requires a config object');\n }\n\n const hasManifest =\n config.manifest != null && config.manifest.records.length > 0;\n const hasRoutes = Array.isArray(config.routes) && config.routes.length > 0;\n\n if (!hasManifest && !hasRoutes) {\n throw new Error(\n 'hydrateSPA requires a route manifest or route table. ' +\n 'Pass `manifest: getManifest()` or `routes: getRoutes()`. ' +\n 'If you are enhancing existing HTML, use createIsland instead.'\n );\n }\n\n const rootElement =\n typeof config.root === 'string'\n ? document.getElementById(config.root)\n : config.root;\n if (!rootElement) throw new Error(`Root element not found: ${config.root}`);\n\n const pendingLazyAtHydrationBoot = _snapshotLazy();\n\n configureScrollRestoration(config.scrollRestoration);\n\n clearRoutes();\n\n if (hasManifest) {\n _applyManifest(config.manifest!);\n } else {\n for (const r of config.routes!) {\n registerRoute(r.path, r.handler as Parameters<typeof registerRoute>[1]);\n }\n }\n\n _setActiveRouteAuthOptions(config.auth ?? config.manifest?.auth);\n\n // Drain any lazy() imports so all split chunks are ready before mounting\n await _drainLazy(pendingLazyAtHydrationBoot);\n\n const path = typeof window !== 'undefined' ? window.location.pathname : '/';\n const currentUrl =\n typeof window !== 'undefined'\n ? `${window.location.pathname}${window.location.search}${window.location.hash}`\n : path;\n setServerLocation(currentUrl);\n if (isProductionEnvironment()) lockRouteRegistration();\n\n const resolved = resolveRoute(path);\n if (!resolved) {\n throw new Error(`hydrateSPA: no route found for current path (${path}).`);\n }\n\n if (shouldVerifyHydrationMarkup(config)) {\n const legacyRouteTable = hasManifest\n ? config.manifest!.records.map((r) => ({\n path: r.path,\n handler: r.handler,\n namespace: r.options.namespace,\n }))\n : config.routes!;\n\n const { verifyHydrationSyncForUrl } = await import('../ssr');\n if (\n !verifyHydrationSyncForUrl({\n root: rootElement,\n url: currentUrl,\n routes: legacyRouteTable,\n })\n ) {\n throw new Error(\n '[Askr] Hydration mismatch detected. Server HTML does not match expected server-render output.'\n );\n }\n }\n\n const hydrateOptions = config.hydrate;\n if (hydrateOptions) {\n if (hydrateOptions.deferUntilIdle || hydrateOptions.deferBelowFold) {\n await applySelectiveHydration(\n rootElement,\n {\n handler: resolved.handler as ComponentFunction,\n params: resolved.params as Record<string, unknown>,\n },\n path,\n config.cleanupStrict,\n hydrateOptions\n );\n return;\n }\n\n if (hydrateOptions.skipSelectors?.length) {\n markSkippedElements(rootElement, hydrateOptions.skipSelectors);\n }\n }\n\n mountOrUpdate(rootElement, bindResolvedRouteHandler(resolved), {\n cleanupStrict: config.cleanupStrict,\n });\n await registerAppNavigation(rootElement, path);\n}\n\n/**\n * Cleanup an app mounted on a root element (element or id).\n * Safe to call multiple times — no-op when nothing is mounted.\n */\nexport function cleanupApp(root: Element | string): void {\n const rootElement =\n typeof root === 'string' ? document.getElementById(root) : root;\n\n if (!rootElement) return;\n\n const cleanupFn = (rootElement as ElementWithCleanup)[CLEANUP_SYMBOL];\n if (typeof cleanupFn === 'function') {\n cleanupFn();\n }\n\n instancesByRoot.delete(rootElement);\n}\n\n/**\n * Check whether an app is mounted on the given root\n */\nexport function hasApp(root: Element | string): boolean {\n const rootElement =\n typeof root === 'string' ? document.getElementById(root) : root;\n\n if (!rootElement) return false;\n return instancesByRoot.has(rootElement);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../src/boot/index.ts"],"sourcesContent":["/**\n * App bootstrap and mount\n */\n\nimport {\n createComponentInstance,\n mountComponent,\n cleanupComponent,\n type ComponentFunction,\n type ComponentInstance,\n} from '../runtime/component';\nimport {\n isDevelopmentEnvironment,\n isProductionEnvironment,\n} from '../common/env';\nimport { logger } from '../dev/logger';\nimport { initializeNavigation, registerAppInstance } from '../router/navigate';\nimport {\n configureScrollRestoration,\n type ScrollRestorationOptions,\n} from '../router/navigate';\nimport {\n _applyManifest,\n _drainLazy,\n _setActiveRouteAuthOptions,\n _snapshotLazy,\n clearRoutes,\n lockRouteRegistration,\n resolveRoute,\n resolveRouteRequest,\n route as registerRoute,\n setServerLocation,\n} from '../router/route';\nimport { globalScheduler } from '../runtime/scheduler';\nimport { assertExecutionModel } from '../runtime/execution-model';\nimport { setStaticChildSlotsCacheEnabled } from '../renderer/dom';\n\nconst HAS_ROUTES_KEY = Symbol.for('__ASKR_HAS_ROUTES__');\n\nlet componentIdCounter = 0;\n\n// Track instances by root element to support multiple createIsland calls on same root\nconst instancesByRoot = new WeakMap<Element, ComponentInstance>();\n\n// Symbol for storing cleanup on elements\nconst CLEANUP_SYMBOL = Symbol.for('__askrCleanup__');\n\n// Type for elements that have cleanup functions attached\ninterface ElementWithCleanup extends Element {\n [CLEANUP_SYMBOL]?: () => void;\n}\n\nfunction attachCleanupForRoot(\n rootElement: Element,\n instance: ComponentInstance\n) {\n (rootElement as ElementWithCleanup)[CLEANUP_SYMBOL] = () => {\n // Attempt to remove listeners and cleanup instances under the root.\n // In non-strict mode we preserve previous behavior by swallowing errors\n // (but logging in dev); in strict mode we aggregate and re-throw.\n const errors: unknown[] = [];\n try {\n removeAllListeners(rootElement);\n } catch (e) {\n errors.push(e);\n }\n\n try {\n cleanupComponent(instance as ComponentInstance);\n } catch (e) {\n errors.push(e);\n }\n\n if (errors.length > 0) {\n if (instance.cleanupStrict) {\n throw new AggregateError(errors, `cleanup failed for app root`);\n } else if (isDevelopmentEnvironment()) {\n for (const err of errors) logger.warn('[Askr] cleanup error:', err);\n }\n }\n };\n\n try {\n const descriptor =\n Object.getOwnPropertyDescriptor(rootElement, 'innerHTML') ||\n Object.getOwnPropertyDescriptor(\n Object.getPrototypeOf(rootElement),\n 'innerHTML'\n ) ||\n Object.getOwnPropertyDescriptor(Element.prototype, 'innerHTML');\n\n if (descriptor && (descriptor.get || descriptor.set)) {\n Object.defineProperty(rootElement, 'innerHTML', {\n get: descriptor.get\n ? function (this: Element) {\n return descriptor.get!.call(this);\n }\n : undefined,\n set: function (this: Element, value: string) {\n if (value === '' && instancesByRoot.get(this) === instance) {\n try {\n removeAllListeners(rootElement);\n } catch (e) {\n if (instance.cleanupStrict) throw e;\n if (isDevelopmentEnvironment()) {\n logger.warn('[Askr] cleanup error:', e);\n }\n }\n\n try {\n cleanupComponent(instance as ComponentInstance);\n } catch (e) {\n if (instance.cleanupStrict) throw e;\n if (isDevelopmentEnvironment()) {\n logger.warn('[Askr] cleanup error:', e);\n }\n }\n }\n if (descriptor.set) {\n return descriptor.set.call(this, value);\n }\n },\n configurable: true,\n });\n }\n } catch {\n // If Object.defineProperty fails, ignore\n }\n}\n\nimport { Fragment, ELEMENT_TYPE } from '../jsx';\n\nimport { DefaultPortal } from '../foundations/structures/portal';\n\nfunction mountOrUpdate(\n rootElement: Element,\n componentFn: ComponentFunction,\n options?: { cleanupStrict?: boolean }\n) {\n // Ensure root component always includes a DefaultPortal host by wrapping it.\n const wrappedFn: ComponentFunction = (props, ctx) => {\n const out = componentFn(props, ctx);\n const portalVNode = {\n $$typeof: ELEMENT_TYPE,\n type: DefaultPortal,\n props: {},\n key: '__default_portal',\n } as unknown;\n return {\n $$typeof: ELEMENT_TYPE,\n type: Fragment,\n props: {\n children:\n out === undefined || out === null\n ? [portalVNode]\n : [out, portalVNode],\n },\n } as unknown as ReturnType<ComponentFunction>;\n };\n // Preserve the original component name for debugging/dev warnings\n Object.defineProperty(wrappedFn, 'name', {\n value: componentFn.name || 'Component',\n });\n\n // Clean up existing cleanup function before mounting new one\n const existingCleanup = (rootElement as ElementWithCleanup)[CLEANUP_SYMBOL];\n if (existingCleanup) existingCleanup();\n\n let instance = instancesByRoot.get(rootElement);\n\n if (instance) {\n removeAllListeners(rootElement);\n try {\n cleanupComponent(instance);\n } catch (e) {\n // If previous cleanup threw in strict mode, log but continue mounting new instance\n if (isDevelopmentEnvironment()) {\n logger.warn('[Askr] prior cleanup threw:', e);\n }\n }\n\n instance.fn = wrappedFn;\n instance.evaluationGeneration++;\n instance.mounted = false;\n instance.expectedStateIndices = [];\n instance.firstRenderComplete = false;\n instance.isRoot = true;\n // Update strict flag if provided\n if (options && typeof options.cleanupStrict === 'boolean') {\n instance.cleanupStrict = options.cleanupStrict;\n }\n } else {\n const componentId = String(++componentIdCounter);\n instance = createComponentInstance(componentId, wrappedFn, {}, rootElement);\n instancesByRoot.set(rootElement, instance);\n instance.isRoot = true;\n // Initialize strict flag from options\n if (options && typeof options.cleanupStrict === 'boolean') {\n instance.cleanupStrict = options.cleanupStrict;\n }\n }\n\n attachCleanupForRoot(rootElement, instance);\n mountComponent(instance);\n globalScheduler.flush();\n}\n\nfunction bindResolvedRouteHandler(resolved: ResolvedRoute): ComponentFunction {\n return () =>\n resolved.handler(resolved.params) as ReturnType<ComponentFunction>;\n}\n\nfunction bindDeniedStatus(status: number): ComponentFunction {\n return () => ({\n type: 'div',\n props: {\n 'data-route-denied': String(status),\n },\n children: [String(status)],\n });\n}\n\n// New strongly-typed init functions\nimport type {\n Route,\n RouteManifest,\n ResolvedRoute,\n RouteAuthOptions,\n} from '../common/router';\nimport { installRendererBridge, removeAllListeners } from '../renderer';\ninstallRendererBridge();\n\nexport type IslandConfig = {\n root: Element | string;\n component: ComponentFunction;\n // Optional: surface cleanup errors during teardown for this island\n cleanupStrict?: boolean;\n // Explicitly disallow routes on islands at type level\n routes?: never;\n};\n\nexport type IslandsConfig = {\n islands: IslandConfig[];\n};\n\nexport type SPAConfig = {\n root: Element | string;\n /**\n * Preferred: pass the route manifest built via `registerRoutes(() => { ... })`.\n * ```ts\n * import { getManifest } from '@askrjs/askr/router';\n * await createSPA({ root: '#app', manifest: getManifest() });\n * ```\n */\n manifest?: RouteManifest;\n /** Legacy: flat route array — kept for backward compatibility and test fixtures. */\n routes?: Route[];\n auth?: RouteAuthOptions;\n scrollRestoration?: boolean | ScrollRestorationOptions;\n cleanupStrict?: boolean;\n component?: never;\n};\n\nexport type HydrateSPAConfig = {\n root: Element | string;\n /** Preferred manifest input — see `SPAConfig.manifest`. */\n manifest?: RouteManifest;\n /** Legacy flat route array. */\n routes?: Route[];\n auth?: RouteAuthOptions;\n scrollRestoration?: boolean | ScrollRestorationOptions;\n cleanupStrict?: boolean;\n hydrate?: {\n verifyMarkup?: boolean;\n deferUntilIdle?: boolean;\n deferBelowFold?: boolean;\n foldThreshold?: number;\n skipSelectors?: string[];\n };\n};\n\n/**\n * createIsland: Enhances existing DOM (no router, mounts once)\n */\nexport function createIsland(config: IslandConfig): void {\n assertExecutionModel('islands');\n if (!config || typeof config !== 'object') {\n throw new Error('createIsland requires a config object');\n }\n if (typeof config.component !== 'function') {\n throw new Error('createIsland: component must be a function');\n }\n\n const rootElement =\n typeof config.root === 'string'\n ? document.getElementById(config.root)\n : config.root;\n if (!rootElement) throw new Error(`Root element not found: ${config.root}`);\n\n // Islands must not initialize router or routes\n if ('routes' in config) {\n throw new Error(\n 'createIsland does not accept routes; use createSPA for routed apps'\n );\n }\n\n // Routes are never supported with islands.\n // If routes were registered (even at module load time), fail fast to avoid\n // surprising partial router behavior.\n try {\n const g = globalThis as unknown as Record<string | symbol, unknown>;\n if (g[HAS_ROUTES_KEY]) {\n throw new Error(\n 'Routes are not supported with islands. Use createSPA (client) or createSSR (server) instead.'\n );\n }\n } catch {\n // ignore\n }\n\n mountOrUpdate(rootElement, config.component, {\n cleanupStrict: config.cleanupStrict,\n });\n}\n\n/**\n * createIslands: Enhances one or more existing DOM roots (no router).\n * The only public islands constructor.\n */\nexport function createIslands(config: IslandsConfig): void {\n assertExecutionModel('islands');\n if (!config || typeof config !== 'object') {\n throw new Error('createIslands requires a config object');\n }\n if (!Array.isArray(config.islands) || config.islands.length === 0) {\n throw new Error('createIslands requires a non-empty islands array');\n }\n for (const island of config.islands) {\n createIsland(island);\n }\n}\n\n/**\n * createSPA: Initializes router and mounts the app with the provided route manifest or route table.\n *\n * Preferred usage with manifest:\n * ```ts\n * import { getManifest } from '@askrjs/askr/router';\n * await createSPA({ root: '#app', manifest: getManifest() });\n * ```\n *\n * Legacy usage with plain routes array (still supported):\n * ```ts\n * await createSPA({ root: '#app', routes: getRoutes() });\n * ```\n */\nexport async function createSPA(config: SPAConfig): Promise<void> {\n assertExecutionModel('spa');\n if (!config || typeof config !== 'object') {\n throw new Error('createSPA requires a config object');\n }\n\n const hasManifest =\n config.manifest != null && config.manifest.records.length > 0;\n const hasRoutes = Array.isArray(config.routes) && config.routes.length > 0;\n\n if (!hasManifest && !hasRoutes) {\n throw new Error(\n 'createSPA requires a route manifest or route table. ' +\n 'Pass `manifest: getManifest()` or `routes: getRoutes()`. ' +\n 'If you are enhancing existing HTML, use createIsland instead.'\n );\n }\n\n const rootElement =\n typeof config.root === 'string'\n ? document.getElementById(config.root)\n : config.root;\n if (!rootElement) throw new Error(`Root element not found: ${config.root}`);\n\n const pendingLazyAtBoot = _snapshotLazy();\n\n configureScrollRestoration(config.scrollRestoration);\n\n clearRoutes();\n\n if (hasManifest) {\n // Preferred path: apply pre-built manifest records directly\n _applyManifest(config.manifest!);\n } else {\n // Legacy path: register plain Route objects (no layout metadata)\n for (const r of config.routes!) {\n registerRoute(r.path, r.handler as Parameters<typeof registerRoute>[1]);\n }\n }\n\n const routeAuth = config.auth ?? config.manifest?.auth;\n _setActiveRouteAuthOptions(routeAuth);\n\n // Drain any lazy() imports so all split chunks are ready before mounting\n await _drainLazy(pendingLazyAtBoot);\n\n // Lock registration in production to prevent late registration surprises\n if (isProductionEnvironment()) lockRouteRegistration();\n\n // Mount the currently-resolved route handler (if any)\n let path = typeof window !== 'undefined' ? window.location.pathname : '/';\n let href =\n typeof window !== 'undefined'\n ? `${window.location.pathname}${window.location.search}${window.location.hash}`\n : path;\n let resolved = await resolveRouteRequest(href, { auth: routeAuth });\n\n while (\n typeof window !== 'undefined' &&\n resolved &&\n resolved.kind === 'redirect'\n ) {\n const redirectTarget = new URL(resolved.to, window.location.href);\n const redirectHref = `${redirectTarget.pathname}${redirectTarget.search}${redirectTarget.hash}`;\n window.history.replaceState({ path: redirectHref }, '', redirectHref);\n path = redirectTarget.pathname;\n href = redirectHref;\n resolved = await resolveRouteRequest(href, { auth: routeAuth });\n }\n\n if (!resolved) {\n mountOrUpdate(rootElement, () => ({ type: 'div', children: [] }), {\n cleanupStrict: config.cleanupStrict,\n });\n\n await registerAppNavigation(rootElement, path);\n return;\n }\n\n if (resolved.kind === 'redirect') {\n mountOrUpdate(rootElement, () => ({ type: 'div', children: [] }), {\n cleanupStrict: config.cleanupStrict,\n });\n\n await registerAppNavigation(rootElement, path);\n return;\n }\n\n mountOrUpdate(\n rootElement,\n resolved.kind === 'deny'\n ? bindDeniedStatus(resolved.status)\n : bindResolvedRouteHandler({\n handler: resolved.handler,\n params: resolved.params,\n }),\n {\n cleanupStrict: config.cleanupStrict,\n }\n );\n\n await registerAppNavigation(rootElement, path);\n}\n\n/**\n * Mark elements that should be skipped during hydration\n */\nfunction markSkippedElements(root: Element, skipSelectors: string[]): void {\n if (skipSelectors.length === 0) {\n return;\n }\n\n const uniqueSelectors = Array.from(new Set(skipSelectors));\n const selectorList = uniqueSelectors.join(', ');\n const elements = root.querySelectorAll(selectorList);\n elements.forEach((el) => el.setAttribute('data-skip-hydrate', 'true'));\n}\n\nfunction collectDeferredBelowFoldBoundaries(\n root: Element,\n foldY: number\n): Element[] {\n const boundaries: Element[] = [];\n const stack: Element[] = [];\n\n for (let index = root.children.length - 1; index >= 0; index -= 1) {\n stack.push(root.children[index]);\n }\n\n while (stack.length > 0) {\n const element = stack.pop()!;\n\n if (element.hasAttribute('data-skip-hydrate')) {\n continue;\n }\n\n const rect = element.getBoundingClientRect();\n if (rect.top >= foldY) {\n element.setAttribute('data-skip-hydrate', 'true');\n boundaries.push(element);\n continue;\n }\n\n for (let index = element.children.length - 1; index >= 0; index -= 1) {\n stack.push(element.children[index]);\n }\n }\n\n return boundaries;\n}\n\nfunction activateVisibleDeferredBoundaries(\n boundaries: Element[],\n foldY: number\n): { activated: boolean; remaining: number } {\n let activated = false;\n let remaining = 0;\n\n for (const element of boundaries) {\n if (!element.hasAttribute('data-skip-hydrate')) {\n continue;\n }\n\n const rect = element.getBoundingClientRect();\n if (rect.top < foldY) {\n element.removeAttribute('data-skip-hydrate');\n activated = true;\n } else {\n remaining += 1;\n }\n }\n\n return { activated, remaining };\n}\n\nfunction queueIdleWork(work: () => void): Promise<void> {\n return new Promise((resolve) => {\n if (typeof requestIdleCallback !== 'undefined') {\n requestIdleCallback(\n () => {\n work();\n resolve();\n },\n { timeout: 2000 }\n );\n return;\n }\n\n setTimeout(() => {\n work();\n resolve();\n }, 0);\n });\n}\n\nfunction flushHydrationActivation(rootElement: Element): void {\n const instance = instancesByRoot.get(rootElement);\n if (!instance) return;\n instance._enqueueRun?.();\n globalScheduler.flush();\n}\n\nfunction shouldVerifyHydrationMarkup(config: HydrateSPAConfig): boolean {\n const explicit = config.hydrate?.verifyMarkup;\n if (typeof explicit === 'boolean') {\n return explicit;\n }\n\n return !isProductionEnvironment();\n}\n\nasync function registerAppNavigation(rootElement: Element, path: string) {\n const instance = instancesByRoot.get(rootElement);\n if (!instance) throw new Error('Internal error: app instance missing');\n registerAppInstance(instance as ComponentInstance, path);\n initializeNavigation();\n}\n\n/**\n * Apply selective hydration with deferral options\n */\nasync function applySelectiveHydration(\n rootElement: Element,\n resolved: { handler: ComponentFunction; params: Record<string, unknown> },\n path: string,\n cleanupStrict: boolean | undefined,\n hydrateOptions: NonNullable<HydrateSPAConfig['hydrate']>\n): Promise<void> {\n const hasPermanentSkips = (hydrateOptions.skipSelectors?.length ?? 0) > 0;\n const hasBelowFoldDeferral = !!hydrateOptions.deferBelowFold;\n const hasSelectiveBoundaries = hasPermanentSkips || hasBelowFoldDeferral;\n let staticChildSlotsCacheSuspended = false;\n\n const restoreStaticChildSlotsCache = () => {\n if (!staticChildSlotsCacheSuspended) {\n return;\n }\n\n setStaticChildSlotsCacheEnabled(true);\n staticChildSlotsCacheSuspended = false;\n };\n\n if (hydrateOptions.skipSelectors?.length) {\n markSkippedElements(rootElement, hydrateOptions.skipSelectors);\n }\n\n let deferredBoundaries: Element[] = [];\n if (hydrateOptions.deferBelowFold) {\n setStaticChildSlotsCacheEnabled(false);\n staticChildSlotsCacheSuspended = true;\n const foldY = hydrateOptions.foldThreshold ?? window.innerHeight;\n deferredBoundaries = collectDeferredBelowFoldBoundaries(rootElement, foldY);\n\n const handleScroll = () => {\n const { activated, remaining } = activateVisibleDeferredBoundaries(\n deferredBoundaries,\n foldY\n );\n\n if (!activated) {\n return;\n }\n\n flushHydrationActivation(rootElement);\n\n if (remaining === 0) {\n restoreStaticChildSlotsCache();\n window.removeEventListener('scroll', handleScroll);\n }\n };\n\n window.addEventListener('scroll', handleScroll, { passive: true });\n }\n\n if (hydrateOptions.deferUntilIdle && !hasSelectiveBoundaries) {\n await queueIdleWork(() => {\n mountOrUpdate(\n rootElement,\n (() => resolved.handler(resolved.params)) as ComponentFunction,\n {\n cleanupStrict,\n }\n );\n });\n await registerAppNavigation(rootElement, path);\n return;\n }\n\n mountOrUpdate(\n rootElement,\n (() => resolved.handler(resolved.params)) as ComponentFunction,\n {\n cleanupStrict,\n }\n );\n await registerAppNavigation(rootElement, path);\n\n if (hydrateOptions.deferUntilIdle && deferredBoundaries.length > 0) {\n await queueIdleWork(() => {\n try {\n const { activated } = activateVisibleDeferredBoundaries(\n deferredBoundaries,\n Number.POSITIVE_INFINITY\n );\n if (activated) {\n flushHydrationActivation(rootElement);\n }\n } finally {\n restoreStaticChildSlotsCache();\n }\n });\n }\n\n if (deferredBoundaries.length === 0) {\n restoreStaticChildSlotsCache();\n }\n}\n\n/**\n * hydrateSPA: Hydrate server-rendered HTML.\n * Accepts either a `manifest` (preferred) or a legacy `routes` array.\n */\nexport async function hydrateSPA(config: HydrateSPAConfig): Promise<void> {\n assertExecutionModel('spa');\n if (!config || typeof config !== 'object') {\n throw new Error('hydrateSPA requires a config object');\n }\n\n const hasManifest =\n config.manifest != null && config.manifest.records.length > 0;\n const hasRoutes = Array.isArray(config.routes) && config.routes.length > 0;\n\n if (!hasManifest && !hasRoutes) {\n throw new Error(\n 'hydrateSPA requires a route manifest or route table. ' +\n 'Pass `manifest: getManifest()` or `routes: getRoutes()`. ' +\n 'If you are enhancing existing HTML, use createIsland instead.'\n );\n }\n\n const rootElement =\n typeof config.root === 'string'\n ? document.getElementById(config.root)\n : config.root;\n if (!rootElement) throw new Error(`Root element not found: ${config.root}`);\n\n const pendingLazyAtHydrationBoot = _snapshotLazy();\n\n configureScrollRestoration(config.scrollRestoration);\n\n clearRoutes();\n\n if (hasManifest) {\n _applyManifest(config.manifest!);\n } else {\n for (const r of config.routes!) {\n registerRoute(r.path, r.handler as Parameters<typeof registerRoute>[1]);\n }\n }\n\n _setActiveRouteAuthOptions(config.auth ?? config.manifest?.auth);\n\n // Drain any lazy() imports so all split chunks are ready before mounting\n await _drainLazy(pendingLazyAtHydrationBoot);\n\n const path = typeof window !== 'undefined' ? window.location.pathname : '/';\n const currentUrl =\n typeof window !== 'undefined'\n ? `${window.location.pathname}${window.location.search}${window.location.hash}`\n : path;\n setServerLocation(currentUrl);\n if (isProductionEnvironment()) lockRouteRegistration();\n\n const resolved = resolveRoute(path);\n if (!resolved) {\n throw new Error(`hydrateSPA: no route found for current path (${path}).`);\n }\n\n if (shouldVerifyHydrationMarkup(config)) {\n const legacyRouteTable = hasManifest\n ? config.manifest!.records.map((r) => ({\n path: r.path,\n handler: r.handler,\n namespace: r.options.namespace,\n }))\n : config.routes!;\n\n const { verifyHydrationSyncForUrl } =\n await import('../ssr/verify-hydration');\n if (\n !verifyHydrationSyncForUrl({\n root: rootElement,\n url: currentUrl,\n routes: legacyRouteTable,\n })\n ) {\n throw new Error(\n '[Askr] Hydration mismatch detected. Server HTML does not match expected server-render output.'\n );\n }\n }\n\n const hydrateOptions = config.hydrate;\n if (hydrateOptions) {\n if (hydrateOptions.deferUntilIdle || hydrateOptions.deferBelowFold) {\n await applySelectiveHydration(\n rootElement,\n {\n handler: resolved.handler as ComponentFunction,\n params: resolved.params as Record<string, unknown>,\n },\n path,\n config.cleanupStrict,\n hydrateOptions\n );\n return;\n }\n\n if (hydrateOptions.skipSelectors?.length) {\n markSkippedElements(rootElement, hydrateOptions.skipSelectors);\n }\n }\n\n mountOrUpdate(rootElement, bindResolvedRouteHandler(resolved), {\n cleanupStrict: config.cleanupStrict,\n });\n await registerAppNavigation(rootElement, path);\n}\n\n/**\n * Cleanup an app mounted on a root element (element or id).\n * Safe to call multiple times — no-op when nothing is mounted.\n */\nexport function cleanupApp(root: Element | string): void {\n const rootElement =\n typeof root === 'string' ? document.getElementById(root) : root;\n\n if (!rootElement) return;\n\n const cleanupFn = (rootElement as ElementWithCleanup)[CLEANUP_SYMBOL];\n if (typeof cleanupFn === 'function') {\n cleanupFn();\n }\n\n instancesByRoot.delete(rootElement);\n}\n\n/**\n * Check whether an app is mounted on the given root\n */\nexport function hasApp(root: Element | string): boolean {\n const rootElement =\n typeof root === 'string' ? document.getElementById(root) : root;\n\n if (!rootElement) return false;\n return instancesByRoot.has(rootElement);\n}\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import { ErrorBoundary, ErrorBoundaryFallbackRender, ErrorBoundaryProps } from "./error-boundary.js";
2
+ export { ErrorBoundary, type ErrorBoundaryFallbackRender, type ErrorBoundaryProps };
@@ -0,0 +1,2 @@
1
+ import { ErrorBoundary } from "./error-boundary.js";
2
+ export { ErrorBoundary };
@@ -1,8 +1,7 @@
1
+ import { Props } from "../common/props.js";
2
+ import { JSXElement } from "../common/jsx.js";
1
3
  //#region src/components/link.d.ts
2
- /**
3
- * Link component for client-side navigation
4
- */
5
- type LinkProps = Omit<JSX.IntrinsicElements['a'], 'children' | 'href' | 'class' | 'rel' | 'target' | 'aria-current' | 'aria-label'> & {
4
+ type LinkProps = Omit<Props, 'children' | 'href' | 'class' | 'rel' | 'target' | 'aria-current' | 'aria-label'> & {
6
5
  href: string;
7
6
  class?: string;
8
7
  children?: unknown;
@@ -62,7 +61,7 @@ declare function Link({
62
61
  'aria-current': ariaCurrent,
63
62
  'aria-label': ariaLabel,
64
63
  ...rest
65
- }: LinkProps): JSX.Element;
64
+ }: LinkProps): JSXElement;
66
65
  //#endregion
67
66
  export { Link, LinkProps };
68
67
  //# sourceMappingURL=link.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"link.d.ts","names":[],"sources":["../../src/components/link.tsx"],"mappings":";;AAQA;;KAAY,SAAA,GAAY,IAAA,CACtB,GAAA,CAAI,iBAAA;EASJ,IAAA;EACA,KAAA;EACA,QAAA;EAXI;;;;EAgBJ,GAAA;EAKA;;;;EAAA,MAAA;EA8Cc;;;;EAzCd,cAAA;EA4CA;;;EAjCA,YAAA;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA8Bc,IAAA,CAAA;EACd,IAAA;EACA,KAAA,EAAO,SAAA;EACP,QAAA;EACA,GAAA;EACA,MAAA;EAAA,gBACgB,WAAA;EAAA,cACF,SAAA;EAAA,GACX;AAAA,GACF,SAAA,GAAY,GAAA,CAAI,OAAA"}
1
+ {"version":3,"file":"link.d.ts","names":[],"sources":["../../src/components/link.tsx"],"mappings":";;;KAWY,SAAA,GAAY,IAAA,CACtB,KAAA;EASA,IAAA;EACA,KAAA;EACA,QAAA;EAXA;;;;EAgBA,GAAA;EAKA;;;;EAAA,MAAA;EA8Cc;;;;EAzCd,cAAA;EA4CA;;;EAjCA,YAAA;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA8Bc,IAAA,CAAA;EACd,IAAA;EACA,KAAA,EAAO,SAAA;EACP,QAAA;EACA,GAAA;EACA,MAAA;EAAA,gBACgB,WAAA;EAAA,cACF,SAAA;EAAA,GACX;AAAA,GACF,SAAA,GAAY,UAAA"}
@@ -1,8 +1,9 @@
1
+ import "../jsx/types.js";
1
2
  import { jsx } from "../jsx-runtime.js";
3
+ import "../jsx-runtime2.js";
2
4
  import { navigate } from "../router/navigate.js";
3
5
  import { mergeProps } from "../foundations/utilities/merge-props.js";
4
6
  import { applyInteractionPolicy } from "../foundations/interactions/interaction-policy.js";
5
- import "../jsx-runtime2.js";
6
7
  //#region src/components/link.tsx
7
8
  /**
8
9
  * Link component for client-side navigation
@@ -1 +1 @@
1
- {"version":3,"file":"link.js","names":[],"sources":["../../src/components/link.tsx"],"sourcesContent":["/**\n * Link component for client-side navigation\n */\n\nimport { navigate } from '../router/navigate';\nimport { applyInteractionPolicy } from '../foundations/interactions/interaction-policy';\nimport { mergeProps } from '../foundations/utilities/merge-props';\n\nexport type LinkProps = Omit<\n JSX.IntrinsicElements['a'],\n | 'children'\n | 'href'\n | 'class'\n | 'rel'\n | 'target'\n | 'aria-current'\n | 'aria-label'\n> & {\n href: string;\n class?: string;\n children?: unknown;\n /**\n * Optional rel attribute for link relationships.\n * Common values: \"noopener\", \"noreferrer\", \"nofollow\"\n */\n rel?: string;\n /**\n * Optional target attribute.\n * Use \"_blank\" for new tab/window.\n */\n target?: string;\n /**\n * Optional aria-current attribute for indicating current page/location.\n * Use \"page\" for the current page in navigation.\n */\n 'aria-current'?:\n | 'page'\n | 'step'\n | 'location'\n | 'date'\n | 'time'\n | 'true'\n | 'false';\n /**\n * Optional aria-label for accessibility when link text isn't descriptive enough.\n */\n 'aria-label'?: string;\n};\n\n/**\n * Link component that prevents default navigation and uses navigate()\n * Provides declarative way to navigate between routes\n *\n * Accessibility features:\n * - Proper semantic <a> element (not a button)\n * - Supports aria-current for indicating active page\n * - Supports aria-label for descriptive labels\n * - Keyboard accessible (Enter key handled by native <a> element)\n *\n * Respects native browser behaviors:\n * - Middle-click (opens in new tab)\n * - Ctrl/Cmd+click (opens in new tab)\n * - Shift+click (opens in new window)\n * - Alt+click (downloads link)\n * - Right-click context menu\n *\n * Best practices:\n * - Use target=\"_blank\" with rel=\"noopener noreferrer\" for external links\n * - Use aria-current=\"page\" for the current page in navigation\n * - Provide descriptive link text or aria-label\n *\n * Uses applyInteractionPolicy to enforce pit-of-success principles:\n * - Interaction behavior centralized in foundations\n * - Keyboard handling automatic\n * - Composable via mergeProps\n */\nexport function Link({\n href,\n class: className,\n children,\n rel,\n target,\n 'aria-current': ariaCurrent,\n 'aria-label': ariaLabel,\n ...rest\n}: LinkProps): JSX.Element {\n const interaction = applyInteractionPolicy({\n isNative: true,\n disabled: false,\n onPress: (e: Event) => {\n const event = e as MouseEvent;\n\n // Only intercept left-click without modifiers\n // Default button to 0 if undefined (for mock events in tests)\n const button = event.button ?? 0;\n if (\n button !== 0 || // not left-click\n event.ctrlKey || // Ctrl/Cmd+click\n event.metaKey || // Cmd on Mac\n event.shiftKey || // Shift+click\n event.altKey // Alt+click\n ) {\n return; // Let browser handle it (new tab, etc.)\n }\n\n // Don't intercept external links or explicit target\n if (target) {\n return; // Let browser handle it\n }\n\n event.preventDefault();\n navigate(href);\n },\n });\n\n const props = mergeProps(rest, {\n ...interaction,\n href,\n class: className,\n rel,\n target,\n 'aria-current': ariaCurrent,\n 'aria-label': ariaLabel,\n });\n\n return <a {...props}>{children}</a>;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4EA,SAAgB,KAAK,EACnB,MACA,OAAO,WACP,UACA,KACA,QACA,gBAAgB,aAChB,cAAc,WACd,GAAG,QACsB;CAwCzB,OAAO,oBAAC,KAAD;EAAG,GAVI,WAAW,MAAM;GAC7B,GA9BkB,uBAAuB;IACzC,UAAU;IACV,UAAU;IACV,UAAU,MAAa;KACrB,MAAM,QAAQ;KAKd,KADe,MAAM,UAAU,OAElB,KACX,MAAM,WACN,MAAM,WACN,MAAM,YACN,MAAM,QAEN;KAIF,IAAI,QACF;KAGF,MAAM,gBAAgB;KACtB,SAAS,KAAK;;IAEjB,CAGI;GACH;GACA,OAAO;GACP;GACA;GACA,gBAAgB;GAChB,cAAc;GACf,CAEa;EAAQ;EAAa,CAAA"}
1
+ {"version":3,"file":"link.js","names":[],"sources":["../../src/components/link.tsx"],"sourcesContent":["/**\n * Link component for client-side navigation\n */\n\nimport '../jsx/types';\nimport type { JSXElement } from '../common/jsx';\nimport type { Props } from '../common/props';\nimport { navigate } from '../router/navigate';\nimport { applyInteractionPolicy } from '../foundations/interactions/interaction-policy';\nimport { mergeProps } from '../foundations/utilities/merge-props';\n\nexport type LinkProps = Omit<\n Props,\n | 'children'\n | 'href'\n | 'class'\n | 'rel'\n | 'target'\n | 'aria-current'\n | 'aria-label'\n> & {\n href: string;\n class?: string;\n children?: unknown;\n /**\n * Optional rel attribute for link relationships.\n * Common values: \"noopener\", \"noreferrer\", \"nofollow\"\n */\n rel?: string;\n /**\n * Optional target attribute.\n * Use \"_blank\" for new tab/window.\n */\n target?: string;\n /**\n * Optional aria-current attribute for indicating current page/location.\n * Use \"page\" for the current page in navigation.\n */\n 'aria-current'?:\n | 'page'\n | 'step'\n | 'location'\n | 'date'\n | 'time'\n | 'true'\n | 'false';\n /**\n * Optional aria-label for accessibility when link text isn't descriptive enough.\n */\n 'aria-label'?: string;\n};\n\n/**\n * Link component that prevents default navigation and uses navigate()\n * Provides declarative way to navigate between routes\n *\n * Accessibility features:\n * - Proper semantic <a> element (not a button)\n * - Supports aria-current for indicating active page\n * - Supports aria-label for descriptive labels\n * - Keyboard accessible (Enter key handled by native <a> element)\n *\n * Respects native browser behaviors:\n * - Middle-click (opens in new tab)\n * - Ctrl/Cmd+click (opens in new tab)\n * - Shift+click (opens in new window)\n * - Alt+click (downloads link)\n * - Right-click context menu\n *\n * Best practices:\n * - Use target=\"_blank\" with rel=\"noopener noreferrer\" for external links\n * - Use aria-current=\"page\" for the current page in navigation\n * - Provide descriptive link text or aria-label\n *\n * Uses applyInteractionPolicy to enforce pit-of-success principles:\n * - Interaction behavior centralized in foundations\n * - Keyboard handling automatic\n * - Composable via mergeProps\n */\nexport function Link({\n href,\n class: className,\n children,\n rel,\n target,\n 'aria-current': ariaCurrent,\n 'aria-label': ariaLabel,\n ...rest\n}: LinkProps): JSXElement {\n const interaction = applyInteractionPolicy({\n isNative: true,\n disabled: false,\n onPress: (e: Event) => {\n const event = e as MouseEvent;\n\n // Only intercept left-click without modifiers\n // Default button to 0 if undefined (for mock events in tests)\n const button = event.button ?? 0;\n if (\n button !== 0 || // not left-click\n event.ctrlKey || // Ctrl/Cmd+click\n event.metaKey || // Cmd on Mac\n event.shiftKey || // Shift+click\n event.altKey // Alt+click\n ) {\n return; // Let browser handle it (new tab, etc.)\n }\n\n // Don't intercept external links or explicit target\n if (target) {\n return; // Let browser handle it\n }\n\n event.preventDefault();\n navigate(href);\n },\n });\n\n const props = mergeProps(rest, {\n ...interaction,\n href,\n class: className,\n rel,\n target,\n 'aria-current': ariaCurrent,\n 'aria-label': ariaLabel,\n });\n\n return <a {...props}>{children}</a>;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+EA,SAAgB,KAAK,EACnB,MACA,OAAO,WACP,UACA,KACA,QACA,gBAAgB,aAChB,cAAc,WACd,GAAG,QACqB;CAwCxB,OAAO,oBAAC,KAAD;EAAG,GAVI,WAAW,MAAM;GAC7B,GA9BkB,uBAAuB;IACzC,UAAU;IACV,UAAU;IACV,UAAU,MAAa;KACrB,MAAM,QAAQ;KAKd,KADe,MAAM,UAAU,OAElB,KACX,MAAM,WACN,MAAM,WACN,MAAM,YACN,MAAM,QAEN;KAIF,IAAI,QACF;KAGF,MAAM,gBAAgB;KACtB,SAAS,KAAK;;IAEjB,CAGI;GACH;GACA,OAAO;GACP;GACA;GACA,gBAAgB;GAChB,cAAc;GACf,CAEa;EAAQ;EAAa,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"icon.d.ts","names":[],"sources":["../../../src/foundations/icon/icon.tsx"],"mappings":";;;;iBAMgB,eAAA,CAAgB,KAAA,YAAiB,KAAA,IAAS,aAAA;AAAA,iBAO1C,sBAAA,CAAuB,IAAA;AAAA,iBAKvB,uBAAA,CAAwB,IAAA;AAAA,iBAOxB,8BAAA,CACd,WAAA,UACA,SAAA,EAAW,aAAA;AAAA,iBAYG,kBAAA,CACd,KAAA,WAAgB,eAAA;AAAA,iBAUF,aAAA,CAAA,GACX,MAAA,EAAQ,KAAA;AAAA,iBAMG,oBAAA,CAAA;EACd,IAAA;EACA,WAAA;EACA,KAAA;EACA,KAAA;EACA,KAAA;EACA;AAAA,GACC,IAAA,CACD,SAAA;;;;;;;;;;;;;;;;;;;;;iBA4Cc,QAAA,CAAA;EACd,IAAA;EACA,WAAA;EACA,KAAA;EACA,KAAA;EACA,KAAA,EAAO,SAAA;EACP,KAAA;EACA,QAAA;EACA,QAAA;EACA,GAAA;EAAA,GACG;AAAA,GACF,SAAA,GAAS,UAAA"}
1
+ {"version":3,"file":"icon.d.ts","names":[],"sources":["../../../src/foundations/icon/icon.tsx"],"mappings":";;;;iBAOgB,eAAA,CAAgB,KAAA,YAAiB,KAAA,IAAS,aAAA;AAAA,iBAO1C,sBAAA,CAAuB,IAAA;AAAA,iBAKvB,uBAAA,CAAwB,IAAA;AAAA,iBAOxB,8BAAA,CACd,WAAA,UACA,SAAA,EAAW,aAAA;AAAA,iBAYG,kBAAA,CACd,KAAA,WAAgB,eAAA;AAAA,iBAUF,aAAA,CAAA,GACX,MAAA,EAAQ,KAAA;AAAA,iBAMG,oBAAA,CAAA;EACd,IAAA;EACA,WAAA;EACA,KAAA;EACA,KAAA;EACA,KAAA;EACA;AAAA,GACC,IAAA,CACD,SAAA;;;;;;;;;;;;;;;;;;;;;iBA4Cc,QAAA,CAAA;EACd,IAAA;EACA,WAAA;EACA,KAAA;EACA,KAAA;EACA,KAAA,EAAO,SAAA;EACP,KAAA;EACA,QAAA;EACA,QAAA;EACA,GAAA;EAAA,GACG;AAAA,GACF,SAAA,GAAY,UAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"icon.js","names":[],"sources":["../../../src/foundations/icon/icon.tsx"],"sourcesContent":["/* eslint-disable askr/no-hardcoded-theme-tokens -- Icon exposes a stable CSS variable contract consumed by themes. */\nimport { jsx, jsxs } from '../../jsx/jsx-runtime';\nimport type { IconProps, IconSizeToken, IconStyleObject } from './icon.types';\n\nconst ICON_SIZE_TOKENS: readonly IconSizeToken[] = ['sm', 'md', 'lg', 'xl'];\n\nexport function isIconSizeToken(value: unknown): value is IconSizeToken {\n return (\n typeof value === 'string' &&\n ICON_SIZE_TOKENS.includes(value as IconSizeToken)\n );\n}\n\nexport function normalizeIconSizeValue(size: number | string): string {\n if (typeof size === 'number') return `${size}px`;\n return size;\n}\n\nexport function resolveIconSizeVariable(size: number | string): string {\n if (isIconSizeToken(size)) {\n return `var(--ak-icon-size-${size}, var(--ak-icon-size-md, 1.25rem))`;\n }\n return normalizeIconSizeValue(size);\n}\n\nexport function resolveIconStrokeWidthVariable(\n strokeWidth: number,\n sizeToken: IconSizeToken | undefined\n): string {\n if (sizeToken) {\n return `var(--ak-icon-stroke-width-${sizeToken}, var(--ak-icon-stroke-width-md, ${strokeWidth}))`;\n }\n return `var(--ak-icon-stroke-width-md, ${strokeWidth})`;\n}\n\nfunction camelToKebab(key: string): string {\n return key.replace(/([A-Z])/g, (match) => `-${match.toLowerCase()}`);\n}\n\nexport function serializeIconStyle(\n style: string | IconStyleObject | undefined\n): string {\n if (!style) return '';\n if (typeof style === 'string') return style.trim();\n return Object.entries(style)\n .filter(([, value]) => value !== undefined && value !== null)\n .map(([key, value]) => `${camelToKebab(key)}:${String(value)}`)\n .join(';');\n}\n\nexport function joinIconStyle(\n ...styles: Array<string | undefined>\n): string | undefined {\n const merged = styles.map((style) => style?.trim()).filter(Boolean);\n return merged.length > 0 ? merged.join(';') : undefined;\n}\n\nexport function getIconContractProps({\n size = 20,\n strokeWidth = 2,\n color = 'currentColor',\n title,\n style,\n iconName,\n}: Pick<\n IconProps,\n 'color' | 'iconName' | 'size' | 'strokeWidth' | 'style' | 'title'\n>) {\n const sizeToken = isIconSizeToken(size) ? size : undefined;\n const decorative = title ? undefined : 'true';\n const resolvedSize = resolveIconSizeVariable(size);\n const resolvedStrokeWidth = resolveIconStrokeWidthVariable(\n strokeWidth,\n sizeToken\n );\n const iconStyle = joinIconStyle(\n `--ak-icon-size:${resolvedSize}`,\n `--ak-icon-stroke-width:${resolvedStrokeWidth}`,\n 'display:inline-block',\n 'flex-shrink:0',\n 'width:var(--ak-icon-size)',\n 'height:var(--ak-icon-size)',\n 'stroke-width:var(--ak-icon-stroke-width)',\n serializeIconStyle(style)\n );\n\n return {\n sizeToken,\n decorative,\n iconStyle,\n attrs: {\n xmlns: 'http://www.w3.org/2000/svg',\n width: '24',\n height: '24',\n fill: 'none',\n stroke: color,\n 'stroke-width': 'var(--ak-icon-stroke-width)',\n role: 'img',\n 'aria-hidden': title ? undefined : 'true',\n style: iconStyle,\n 'data-slot': 'icon',\n 'data-icon': iconName,\n 'data-size': sizeToken,\n 'data-decorative': decorative,\n 'data-color': color === 'currentColor' ? 'current' : undefined,\n },\n };\n}\n\nexport function IconBase({\n size = 20,\n strokeWidth = 2,\n color = 'currentColor',\n title,\n class: className,\n style,\n iconName,\n children,\n ref,\n ...rest\n}: IconProps) {\n const { attrs } = getIconContractProps({\n size,\n strokeWidth,\n color,\n title,\n style,\n iconName,\n });\n\n const finalChildren = title\n ? [jsx('title', { children: title }), children]\n : children;\n\n return jsxs('svg', {\n ...rest,\n ...attrs,\n viewBox: rest.viewBox ?? '0 0 24 24',\n 'stroke-linecap': rest['stroke-linecap'] ?? 'round',\n 'stroke-linejoin': rest['stroke-linejoin'] ?? 'round',\n class: className,\n ref,\n children: finalChildren,\n });\n}\n"],"mappings":";;AAIA,MAAM,mBAA6C;CAAC;CAAM;CAAM;CAAM;CAAK;AAE3E,SAAgB,gBAAgB,OAAwC;CACtE,OACE,OAAO,UAAU,YACjB,iBAAiB,SAAS,MAAuB;;AAIrD,SAAgB,uBAAuB,MAA+B;CACpE,IAAI,OAAO,SAAS,UAAU,OAAO,GAAG,KAAK;CAC7C,OAAO;;AAGT,SAAgB,wBAAwB,MAA+B;CACrE,IAAI,gBAAgB,KAAK,EACvB,OAAO,sBAAsB,KAAK;CAEpC,OAAO,uBAAuB,KAAK;;AAGrC,SAAgB,+BACd,aACA,WACQ;CACR,IAAI,WACF,OAAO,8BAA8B,UAAU,mCAAmC,YAAY;CAEhG,OAAO,kCAAkC,YAAY;;AAGvD,SAAS,aAAa,KAAqB;CACzC,OAAO,IAAI,QAAQ,aAAa,UAAU,IAAI,MAAM,aAAa,GAAG;;AAGtE,SAAgB,mBACd,OACQ;CACR,IAAI,CAAC,OAAO,OAAO;CACnB,IAAI,OAAO,UAAU,UAAU,OAAO,MAAM,MAAM;CAClD,OAAO,OAAO,QAAQ,MAAM,CACzB,QAAQ,GAAG,WAAW,UAAU,UAAa,UAAU,KAAK,CAC5D,KAAK,CAAC,KAAK,WAAW,GAAG,aAAa,IAAI,CAAC,GAAG,OAAO,MAAM,GAAG,CAC9D,KAAK,IAAI;;AAGd,SAAgB,cACd,GAAG,QACiB;CACpB,MAAM,SAAS,OAAO,KAAK,UAAU,OAAO,MAAM,CAAC,CAAC,OAAO,QAAQ;CACnE,OAAO,OAAO,SAAS,IAAI,OAAO,KAAK,IAAI,GAAG;;AAGhD,SAAgB,qBAAqB,EACnC,OAAO,IACP,cAAc,GACd,QAAQ,gBACR,OACA,OACA,YAIC;CACD,MAAM,YAAY,gBAAgB,KAAK,GAAG,OAAO;CACjD,MAAM,aAAa,QAAQ,SAAY;CACvC,MAAM,eAAe,wBAAwB,KAAK;CAClD,MAAM,sBAAsB,+BAC1B,aACA,UACD;CACD,MAAM,YAAY,cAChB,kBAAkB,gBAClB,0BAA0B,uBAC1B,wBACA,iBACA,6BACA,8BACA,4CACA,mBAAmB,MAAM,CAC1B;CAED,OAAO;EACL;EACA;EACA;EACA,OAAO;GACL,OAAO;GACP,OAAO;GACP,QAAQ;GACR,MAAM;GACN,QAAQ;GACR,gBAAgB;GAChB,MAAM;GACN,eAAe,QAAQ,SAAY;GACnC,OAAO;GACP,aAAa;GACb,aAAa;GACb,aAAa;GACb,mBAAmB;GACnB,cAAc,UAAU,iBAAiB,YAAY;GACtD;EACF;;AAGH,SAAgB,SAAS,EACvB,OAAO,IACP,cAAc,GACd,QAAQ,gBACR,OACA,OAAO,WACP,OACA,UACA,UACA,KACA,GAAG,QACS;CACZ,MAAM,EAAE,UAAU,qBAAqB;EACrC;EACA;EACA;EACA;EACA;EACA;EACD,CAAC;CAEF,MAAM,gBAAgB,QAClB,CAAC,IAAI,SAAS,EAAE,UAAU,OAAO,CAAC,EAAE,SAAS,GAC7C;CAEJ,OAAO,KAAK,OAAO;EACjB,GAAG;EACH,GAAG;EACH,SAAS,KAAK,WAAW;EACzB,kBAAkB,KAAK,qBAAqB;EAC5C,mBAAmB,KAAK,sBAAsB;EAC9C,OAAO;EACP;EACA,UAAU;EACX,CAAC"}
1
+ {"version":3,"file":"icon.js","names":[],"sources":["../../../src/foundations/icon/icon.tsx"],"sourcesContent":["/* eslint-disable askr/no-hardcoded-theme-tokens -- Icon exposes a stable CSS variable contract consumed by themes. */\nimport { jsx, jsxs } from '../../jsx/jsx-runtime';\nimport type { JSXElement } from '../../common/jsx';\nimport type { IconProps, IconSizeToken, IconStyleObject } from './icon.types';\n\nconst ICON_SIZE_TOKENS: readonly IconSizeToken[] = ['sm', 'md', 'lg', 'xl'];\n\nexport function isIconSizeToken(value: unknown): value is IconSizeToken {\n return (\n typeof value === 'string' &&\n ICON_SIZE_TOKENS.includes(value as IconSizeToken)\n );\n}\n\nexport function normalizeIconSizeValue(size: number | string): string {\n if (typeof size === 'number') return `${size}px`;\n return size;\n}\n\nexport function resolveIconSizeVariable(size: number | string): string {\n if (isIconSizeToken(size)) {\n return `var(--ak-icon-size-${size}, var(--ak-icon-size-md, 1.25rem))`;\n }\n return normalizeIconSizeValue(size);\n}\n\nexport function resolveIconStrokeWidthVariable(\n strokeWidth: number,\n sizeToken: IconSizeToken | undefined\n): string {\n if (sizeToken) {\n return `var(--ak-icon-stroke-width-${sizeToken}, var(--ak-icon-stroke-width-md, ${strokeWidth}))`;\n }\n return `var(--ak-icon-stroke-width-md, ${strokeWidth})`;\n}\n\nfunction camelToKebab(key: string): string {\n return key.replace(/([A-Z])/g, (match) => `-${match.toLowerCase()}`);\n}\n\nexport function serializeIconStyle(\n style: string | IconStyleObject | undefined\n): string {\n if (!style) return '';\n if (typeof style === 'string') return style.trim();\n return Object.entries(style)\n .filter(([, value]) => value !== undefined && value !== null)\n .map(([key, value]) => `${camelToKebab(key)}:${String(value)}`)\n .join(';');\n}\n\nexport function joinIconStyle(\n ...styles: Array<string | undefined>\n): string | undefined {\n const merged = styles.map((style) => style?.trim()).filter(Boolean);\n return merged.length > 0 ? merged.join(';') : undefined;\n}\n\nexport function getIconContractProps({\n size = 20,\n strokeWidth = 2,\n color = 'currentColor',\n title,\n style,\n iconName,\n}: Pick<\n IconProps,\n 'color' | 'iconName' | 'size' | 'strokeWidth' | 'style' | 'title'\n>) {\n const sizeToken = isIconSizeToken(size) ? size : undefined;\n const decorative = title ? undefined : 'true';\n const resolvedSize = resolveIconSizeVariable(size);\n const resolvedStrokeWidth = resolveIconStrokeWidthVariable(\n strokeWidth,\n sizeToken\n );\n const iconStyle = joinIconStyle(\n `--ak-icon-size:${resolvedSize}`,\n `--ak-icon-stroke-width:${resolvedStrokeWidth}`,\n 'display:inline-block',\n 'flex-shrink:0',\n 'width:var(--ak-icon-size)',\n 'height:var(--ak-icon-size)',\n 'stroke-width:var(--ak-icon-stroke-width)',\n serializeIconStyle(style)\n );\n\n return {\n sizeToken,\n decorative,\n iconStyle,\n attrs: {\n xmlns: 'http://www.w3.org/2000/svg',\n width: '24',\n height: '24',\n fill: 'none',\n stroke: color,\n 'stroke-width': 'var(--ak-icon-stroke-width)',\n role: 'img',\n 'aria-hidden': title ? undefined : 'true',\n style: iconStyle,\n 'data-slot': 'icon',\n 'data-icon': iconName,\n 'data-size': sizeToken,\n 'data-decorative': decorative,\n 'data-color': color === 'currentColor' ? 'current' : undefined,\n },\n };\n}\n\nexport function IconBase({\n size = 20,\n strokeWidth = 2,\n color = 'currentColor',\n title,\n class: className,\n style,\n iconName,\n children,\n ref,\n ...rest\n}: IconProps): JSXElement {\n const { attrs } = getIconContractProps({\n size,\n strokeWidth,\n color,\n title,\n style,\n iconName,\n });\n\n const finalChildren = title\n ? [jsx('title', { children: title }), children]\n : children;\n\n return jsxs('svg', {\n ...rest,\n ...attrs,\n viewBox: rest.viewBox ?? '0 0 24 24',\n 'stroke-linecap': rest['stroke-linecap'] ?? 'round',\n 'stroke-linejoin': rest['stroke-linejoin'] ?? 'round',\n class: className,\n ref,\n children: finalChildren,\n });\n}\n"],"mappings":";;AAKA,MAAM,mBAA6C;CAAC;CAAM;CAAM;CAAM;CAAK;AAE3E,SAAgB,gBAAgB,OAAwC;CACtE,OACE,OAAO,UAAU,YACjB,iBAAiB,SAAS,MAAuB;;AAIrD,SAAgB,uBAAuB,MAA+B;CACpE,IAAI,OAAO,SAAS,UAAU,OAAO,GAAG,KAAK;CAC7C,OAAO;;AAGT,SAAgB,wBAAwB,MAA+B;CACrE,IAAI,gBAAgB,KAAK,EACvB,OAAO,sBAAsB,KAAK;CAEpC,OAAO,uBAAuB,KAAK;;AAGrC,SAAgB,+BACd,aACA,WACQ;CACR,IAAI,WACF,OAAO,8BAA8B,UAAU,mCAAmC,YAAY;CAEhG,OAAO,kCAAkC,YAAY;;AAGvD,SAAS,aAAa,KAAqB;CACzC,OAAO,IAAI,QAAQ,aAAa,UAAU,IAAI,MAAM,aAAa,GAAG;;AAGtE,SAAgB,mBACd,OACQ;CACR,IAAI,CAAC,OAAO,OAAO;CACnB,IAAI,OAAO,UAAU,UAAU,OAAO,MAAM,MAAM;CAClD,OAAO,OAAO,QAAQ,MAAM,CACzB,QAAQ,GAAG,WAAW,UAAU,UAAa,UAAU,KAAK,CAC5D,KAAK,CAAC,KAAK,WAAW,GAAG,aAAa,IAAI,CAAC,GAAG,OAAO,MAAM,GAAG,CAC9D,KAAK,IAAI;;AAGd,SAAgB,cACd,GAAG,QACiB;CACpB,MAAM,SAAS,OAAO,KAAK,UAAU,OAAO,MAAM,CAAC,CAAC,OAAO,QAAQ;CACnE,OAAO,OAAO,SAAS,IAAI,OAAO,KAAK,IAAI,GAAG;;AAGhD,SAAgB,qBAAqB,EACnC,OAAO,IACP,cAAc,GACd,QAAQ,gBACR,OACA,OACA,YAIC;CACD,MAAM,YAAY,gBAAgB,KAAK,GAAG,OAAO;CACjD,MAAM,aAAa,QAAQ,SAAY;CACvC,MAAM,eAAe,wBAAwB,KAAK;CAClD,MAAM,sBAAsB,+BAC1B,aACA,UACD;CACD,MAAM,YAAY,cAChB,kBAAkB,gBAClB,0BAA0B,uBAC1B,wBACA,iBACA,6BACA,8BACA,4CACA,mBAAmB,MAAM,CAC1B;CAED,OAAO;EACL;EACA;EACA;EACA,OAAO;GACL,OAAO;GACP,OAAO;GACP,QAAQ;GACR,MAAM;GACN,QAAQ;GACR,gBAAgB;GAChB,MAAM;GACN,eAAe,QAAQ,SAAY;GACnC,OAAO;GACP,aAAa;GACb,aAAa;GACb,aAAa;GACb,mBAAmB;GACnB,cAAc,UAAU,iBAAiB,YAAY;GACtD;EACF;;AAGH,SAAgB,SAAS,EACvB,OAAO,IACP,cAAc,GACd,QAAQ,gBACR,OACA,OAAO,WACP,OACA,UACA,UACA,KACA,GAAG,QACqB;CACxB,MAAM,EAAE,UAAU,qBAAqB;EACrC;EACA;EACA;EACA;EACA;EACA;EACD,CAAC;CAEF,MAAM,gBAAgB,QAClB,CAAC,IAAI,SAAS,EAAE,UAAU,OAAO,CAAC,EAAE,SAAS,GAC7C;CAEJ,OAAO,KAAK,OAAO;EACjB,GAAG;EACH,GAAG;EACH,SAAS,KAAK,WAAW;EACzB,kBAAkB,KAAK,qBAAqB;EAC5C,mBAAmB,KAAK,sBAAsB;EAC9C,OAAO;EACP;EACA,UAAU;EACX,CAAC"}
@@ -1,3 +1,4 @@
1
+ import { Props } from "../../common/props.js";
1
2
  import { Ref } from "../utilities/compose-ref.js";
2
3
 
3
4
  //#region src/foundations/icon/icon.types.d.ts
@@ -12,7 +13,7 @@ type IconOwnProps = {
12
13
  style?: string | IconStyleObject;
13
14
  iconName?: string;
14
15
  };
15
- type IconProps = Omit<JSX.IntrinsicElements['svg'], 'children' | 'class' | 'color' | 'height' | 'ref' | 'role' | 'stroke' | 'stroke-width' | 'style' | 'title' | 'width'> & IconOwnProps & {
16
+ type IconProps = Omit<Props, 'children' | 'class' | 'color' | 'height' | 'ref' | 'role' | 'stroke' | 'stroke-width' | 'style' | 'title' | 'width'> & IconOwnProps & {
16
17
  children?: unknown;
17
18
  ref?: Ref<SVGSVGElement>;
18
19
  };
@@ -1 +1 @@
1
- {"version":3,"file":"icon.types.d.ts","names":[],"sources":["../../../src/foundations/icon/icon.types.ts"],"mappings":";;;KAEY,aAAA;AAAA,KAEA,eAAA,GAAkB,MAAA;AAAA,KAElB,YAAA;EACV,IAAA;EACA,WAAA;EACA,KAAA;EACA,KAAA;EACA,KAAA;EACA,KAAA,YAAiB,eAAA;EACjB,QAAA;AAAA;AAAA,KAGU,SAAA,GAAY,IAAA,CACtB,GAAA,CAAI,iBAAA,iIAaJ,YAAA;EACE,QAAA;EACA,GAAA,GAAM,GAAA,CAAI,aAAA;AAAA"}
1
+ {"version":3,"file":"icon.types.d.ts","names":[],"sources":["../../../src/foundations/icon/icon.types.ts"],"mappings":";;;;KAIY,aAAA;AAAA,KAEA,eAAA,GAAkB,MAAA;AAAA,KAElB,YAAA;EACV,IAAA;EACA,WAAA;EACA,KAAA;EACA,KAAA;EACA,KAAA;EACA,KAAA,YAAiB,eAAA;EACjB,QAAA;AAAA;AAAA,KAGU,SAAA,GAAY,IAAA,CACtB,KAAA,0HAaA,YAAA;EACE,QAAA;EACA,GAAA,GAAM,GAAA,CAAI,aAAA;AAAA"}
@@ -0,0 +1,3 @@
1
+ import { IconOwnProps, IconProps, IconSizeToken, IconStyleObject } from "./icon.types.js";
2
+ import { IconBase, getIconContractProps, isIconSizeToken, joinIconStyle, normalizeIconSizeValue, resolveIconSizeVariable, resolveIconStrokeWidthVariable, serializeIconStyle } from "./icon.js";
3
+ export { IconBase, type IconOwnProps, type IconProps, type IconSizeToken, type IconStyleObject, getIconContractProps, isIconSizeToken, joinIconStyle, normalizeIconSizeValue, resolveIconSizeVariable, resolveIconStrokeWidthVariable, serializeIconStyle };
@@ -0,0 +1,2 @@
1
+ import { IconBase, getIconContractProps, isIconSizeToken, joinIconStyle, normalizeIconSizeValue, resolveIconSizeVariable, resolveIconStrokeWidthVariable, serializeIconStyle } from "./icon.js";
2
+ export { IconBase, getIconContractProps, isIconSizeToken, joinIconStyle, normalizeIconSizeValue, resolveIconSizeVariable, resolveIconStrokeWidthVariable, serializeIconStyle };
@@ -1,23 +1,6 @@
1
1
  import { JSXElement } from "../common/jsx.js";
2
- import { ComposeHandlersOptions, composeHandlers } from "./utilities/compose-handlers.js";
3
- import { mergeProps } from "./utilities/merge-props.js";
4
- import { ariaDisabled, ariaExpanded, ariaSelected } from "./utilities/aria.js";
5
- import { Ref, composeRefs, setRef } from "./utilities/compose-ref.js";
6
- import { FormatIdOptions, formatId } from "./utilities/use-id.js";
7
- import { DefaultPreventable, FocusLikeEvent, KeyboardLikeEvent, PointerLikeEvent, PropagationStoppable } from "./utilities/event-types.js";
8
- import { PressableOptions, PressableResult, pressable } from "./interactions/pressable.js";
9
- import { DismissableOptions, dismissable } from "./interactions/dismissable.js";
10
- import { FocusableOptions, FocusableResult, focusable } from "./interactions/focusable.js";
11
- import { HoverableOptions, HoverableResult, hoverable } from "./interactions/hoverable.js";
12
- import { Orientation, RovingFocusOptions, RovingFocusResult, rovingFocus } from "./interactions/roving-focus.js";
13
- import { InteractionPolicyInput, applyInteractionPolicy, mergeInteractionProps } from "./interactions/interaction-policy.js";
14
- import { ControllableState, controllableState, isControlled, makeControllable, resolveControllable } from "./state/controllable.js";
15
- import { IconOwnProps, IconProps, IconSizeToken, IconStyleObject } from "./icon/icon.types.js";
16
- import { IconBase, getIconContractProps, isIconSizeToken, joinIconStyle, normalizeIconSizeValue, resolveIconSizeVariable, resolveIconStrokeWidthVariable, serializeIconStyle } from "./icon/icon.js";
17
2
  import { LayoutComponent, layout } from "./structures/layout.js";
18
3
  import { Slot, SlotProps } from "./structures/slot.js";
19
4
  import { Presence, PresenceProps } from "./structures/presence.js";
20
5
  import { DefaultPortal, Portal, PortalProps, definePortal } from "./structures/portal.js";
21
- import { Collection, CollectionItem, createCollection } from "./structures/collection.js";
22
- import { Layer, LayerManager, LayerOptions, createLayer } from "./structures/layer.js";
23
- export { Collection, CollectionItem, ComposeHandlersOptions, ControllableState, DefaultPortal, DefaultPreventable, DismissableOptions, FocusLikeEvent, FocusableOptions, FocusableResult, FormatIdOptions, HoverableOptions, HoverableResult, IconBase, type IconOwnProps, type IconProps, type IconSizeToken, type IconStyleObject, InteractionPolicyInput, JSXElement, KeyboardLikeEvent, Layer, LayerManager, LayerOptions, LayoutComponent, Orientation, PointerLikeEvent, Portal, PortalProps, Presence, PresenceProps, PressableOptions, PressableResult, PropagationStoppable, Ref, RovingFocusOptions, RovingFocusResult, Slot, SlotProps, applyInteractionPolicy, ariaDisabled, ariaExpanded, ariaSelected, composeHandlers, composeRefs, controllableState, createCollection, createLayer, definePortal, dismissable, focusable, formatId, getIconContractProps, hoverable, isControlled, isIconSizeToken, joinIconStyle, layout, makeControllable, mergeInteractionProps, mergeProps, normalizeIconSizeValue, pressable, resolveControllable, resolveIconSizeVariable, resolveIconStrokeWidthVariable, rovingFocus, serializeIconStyle, setRef };
6
+ export { DefaultPortal, type JSXElement, type LayoutComponent, Portal, type PortalProps, Presence, type PresenceProps, Slot, type SlotProps, definePortal, layout };
@@ -1,22 +1,6 @@
1
1
  import { DefaultPortal, Portal, definePortal } from "./structures/portal.js";
2
- import { ariaDisabled, ariaExpanded, ariaSelected } from "./utilities/aria.js";
3
- import { pressable } from "./interactions/pressable.js";
4
- import { composeHandlers } from "./utilities/compose-handlers.js";
5
- import { composeRefs, setRef } from "./utilities/compose-ref.js";
6
- import { mergeProps } from "./utilities/merge-props.js";
7
- import { applyInteractionPolicy, mergeInteractionProps } from "./interactions/interaction-policy.js";
8
2
  import { layout } from "./structures/layout.js";
9
3
  import { Slot } from "./structures/slot.js";
10
4
  import { Presence } from "./structures/presence.js";
11
- import { createCollection } from "./structures/collection.js";
12
- import { createLayer } from "./structures/layer.js";
13
- import "./structures.js";
14
- import { formatId } from "./utilities/use-id.js";
15
- import { dismissable } from "./interactions/dismissable.js";
16
- import { focusable } from "./interactions/focusable.js";
17
- import { hoverable } from "./interactions/hoverable.js";
18
- import { rovingFocus } from "./interactions/roving-focus.js";
19
- import { controllableState, isControlled, makeControllable, resolveControllable } from "./state/controllable.js";
20
- import { IconBase, getIconContractProps, isIconSizeToken, joinIconStyle, normalizeIconSizeValue, resolveIconSizeVariable, resolveIconStrokeWidthVariable, serializeIconStyle } from "./icon/icon.js";
21
- import "./core.js";
22
- export { DefaultPortal, IconBase, Portal, Presence, Slot, applyInteractionPolicy, ariaDisabled, ariaExpanded, ariaSelected, composeHandlers, composeRefs, controllableState, createCollection, createLayer, definePortal, dismissable, focusable, formatId, getIconContractProps, hoverable, isControlled, isIconSizeToken, joinIconStyle, layout, makeControllable, mergeInteractionProps, mergeProps, normalizeIconSizeValue, pressable, resolveControllable, resolveIconSizeVariable, resolveIconStrokeWidthVariable, rovingFocus, serializeIconStyle, setRef };
5
+ import "./structures/index.js";
6
+ export { DefaultPortal, Portal, Presence, Slot, definePortal, layout };
@@ -0,0 +1,7 @@
1
+ import { PressableOptions, PressableResult, pressable } from "./pressable.js";
2
+ import { DismissableOptions, dismissable } from "./dismissable.js";
3
+ import { FocusableOptions, FocusableResult, focusable } from "./focusable.js";
4
+ import { HoverableOptions, HoverableResult, hoverable } from "./hoverable.js";
5
+ import { Orientation, RovingFocusOptions, RovingFocusResult, rovingFocus } from "./roving-focus.js";
6
+ import { InteractionPolicyInput, applyInteractionPolicy, mergeInteractionProps } from "./interaction-policy.js";
7
+ export { type DismissableOptions, type FocusableOptions, type FocusableResult, type HoverableOptions, type HoverableResult, type InteractionPolicyInput, type Orientation, type PressableOptions, type PressableResult, type RovingFocusOptions, type RovingFocusResult, applyInteractionPolicy, dismissable, focusable, hoverable, mergeInteractionProps, pressable, rovingFocus };
@@ -0,0 +1,7 @@
1
+ import { pressable } from "./pressable.js";
2
+ import { dismissable } from "./dismissable.js";
3
+ import { focusable } from "./focusable.js";
4
+ import { hoverable } from "./hoverable.js";
5
+ import { rovingFocus } from "./roving-focus.js";
6
+ import { applyInteractionPolicy, mergeInteractionProps } from "./interaction-policy.js";
7
+ export { applyInteractionPolicy, dismissable, focusable, hoverable, mergeInteractionProps, pressable, rovingFocus };