@askrjs/askr 0.2.2 → 0.2.4

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 (80) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/README.md +32 -4
  3. package/dist/{access-d_DCdwqn.js → access-BucjYZcX.js} +15 -10
  4. package/dist/actions/index.d.ts +1 -1
  5. package/dist/actions/index.js +5 -4
  6. package/dist/{activity-CAJ5eho-.d.ts → activity-DooIuxQO.d.ts} +2 -2
  7. package/dist/{activity-B2Yy7Wz9.js → activity-FirwPXA_.js} +14 -2
  8. package/dist/{compose-ref-1Fhs7mbF.js → aria-hKjThHcp.js} +1 -18
  9. package/dist/benchmark.d.ts +1 -1
  10. package/dist/benchmark.js +8 -8
  11. package/dist/boot/index.d.ts +4 -2
  12. package/dist/boot/index.js +1 -1
  13. package/dist/{boot-DVwjHCNh.js → boot-tWyF6121.js} +14 -15
  14. package/dist/{cleanup-DPtpXtA4.js → cleanup-TXSsApEl.js} +6 -11
  15. package/dist/{component-cleanup-DPe8claJ.js → component-cleanup-jdbgjkT1.js} +2 -2
  16. package/dist/{component-internal-xW_OnTmC.js → component-internal-C4hKKQBF.js} +16 -7
  17. package/dist/components/index.d.ts +2 -2
  18. package/dist/compose-ref-Bfaf4kUC.js +20 -0
  19. package/dist/control/index.d.ts +1 -1
  20. package/dist/control/index.js +1 -1
  21. package/dist/{control-BLVTE1gO.js → control-C-wSaq9V.js} +4 -4
  22. package/dist/{control-DdFw-Caz.d.ts → control-Cxag1yqV.d.ts} +1 -1
  23. package/dist/{csp-nonce-CCnMtOW-.js → csp-nonce-9NFUb7hJ.js} +1 -1
  24. package/dist/data/index.d.ts +1 -1
  25. package/dist/data/index.js +1 -1
  26. package/dist/{data-BjUf0PPS.js → data-ghKopAbp.js} +49 -49
  27. package/dist/{deferred-BRw0gbn5.js → deferred-CxjWCkIn.js} +2 -2
  28. package/dist/{effect-BQP5o0Kx.js → effect-CNwstBBD.js} +2 -2
  29. package/dist/{fastlane-DUxiFV9S.js → fastlane-BKZduiBQ.js} +2 -2
  30. package/dist/{for-internal-DKcYl3nl.js → for-internal-DyBHfKJA.js} +33 -25
  31. package/dist/foundations/icon/index.d.ts +1 -1
  32. package/dist/foundations/index.d.ts +2 -2
  33. package/dist/foundations/index.js +1 -1
  34. package/dist/foundations/interactions/index.d.ts +1 -1
  35. package/dist/foundations/interactions/index.js +1 -1
  36. package/dist/foundations/state/index.d.ts +1 -1
  37. package/dist/foundations/state/index.js +1 -1
  38. package/dist/foundations/structures/index.d.ts +2 -2
  39. package/dist/foundations/structures/index.js +1 -1
  40. package/dist/foundations/utilities/index.d.ts +1 -1
  41. package/dist/foundations/utilities/index.js +2 -1
  42. package/dist/fx/index.d.ts +1 -1
  43. package/dist/fx/index.js +1 -1
  44. package/dist/{index-CzH-0LcA.d.ts → index-B1gu0_m0.d.ts} +2 -0
  45. package/dist/{index-r5THqzPN.d.ts → index-CTpMmzgN.d.ts} +2 -2
  46. package/dist/{index-DSqXWc77.d.ts → index-Dgjbo2gU.d.ts} +58 -4
  47. package/dist/index.d.ts +3 -3
  48. package/dist/index.js +10 -10
  49. package/dist/{interactions-B-7vkBgx.js → interactions-D102JxBR.js} +10 -3
  50. package/dist/jsx-dev-runtime.d.ts +2 -2
  51. package/dist/jsx-runtime-Cg7GqY1S.d.ts +2 -0
  52. package/dist/{jsx-runtime-Cdd6Gkb0.d.ts → jsx-runtime-gVIaTPw0.d.ts} +2 -2
  53. package/dist/jsx-runtime.d.ts +2 -2
  54. package/dist/{lifecycle-batch-BYECQw8T.js → lifecycle-batch-63aXFf2S.js} +2 -2
  55. package/dist/{lifecycle-operations-DJk_5MrD.js → lifecycle-operations-Q0k3EFnG.js} +94 -2
  56. package/dist/{navigate-wel1e6cU.d.ts → navigate-F4sHgWbw.d.ts} +3 -1
  57. package/dist/{navigate-DvJvo--6.js → navigate-ZZu1IV0B.js} +88 -13
  58. package/dist/{readable-D-JIKCg2.js → readable-Di1fzSwm.js} +1 -1
  59. package/dist/{renderer-RjZ8LHbt.js → renderer-Cl23O0hV.js} +154 -137
  60. package/dist/{resolution-dVYwYXrI.js → resolution-ClD-K7Lz.js} +3 -3
  61. package/dist/{resource-operation-4qFIM02d.js → resource-operation-Vz1S5h2k.js} +4 -4
  62. package/dist/resources/index.d.ts +3 -37
  63. package/dist/resources/index.js +6 -6
  64. package/dist/router/index.d.ts +4 -4
  65. package/dist/router/index.js +7 -7
  66. package/dist/{selector-NQiYHwZC.js → selector-CsKuomw0.js} +17 -16
  67. package/dist/shared-CYBH3F8I.js +27 -0
  68. package/dist/ssg/index.d.ts +1 -1
  69. package/dist/ssg/index.js +4 -4
  70. package/dist/ssr/index.d.ts +8 -2
  71. package/dist/ssr/index.js +1 -1
  72. package/dist/{ssr-F87AcFMt.js → ssr-Doog-AfJ.js} +26 -15
  73. package/dist/{state-Ks-sWTQi.js → state-BGJgYSyQ.js} +3 -3
  74. package/dist/{structures-C-wmHCi6.js → structures-DFyK5AdQ.js} +4 -4
  75. package/dist/testing/index.d.ts +3 -1
  76. package/dist/testing/index.js +6 -5
  77. package/dist/{types-DkVJhVs9.d.ts → types-DWVrKn9N.d.ts} +5 -0
  78. package/dist/{verify-hydration-CThsx0pq.js → verify-hydration-BZPJ_kYa.js} +1 -1
  79. package/package.json +7 -7
  80. package/dist/jsx-runtime-BTzDdBJ_.d.ts +0 -2
package/CHANGELOG.md CHANGED
@@ -2,6 +2,16 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## 0.2.3 — 2026-08-25
6
+
7
+ - fix(data): make mutation invalidation and reconcile retries generation-safe
8
+ when asynchronous submissions are superseded.
9
+ - fix(renderer): keep DOM-range ownership consistent when anchors are
10
+ re-registered.
11
+ - fix(interactions): respect RTL arrow-key direction in roving focus.
12
+ - fix(runtime): harden scheduler, hydration, SSR, and error-boundary failure
13
+ paths.
14
+
5
15
  - feat(data): add lifecycle-owned dynamic keyed query collections with bounded
6
16
  initial loading, aggregate state, per-key retry, and shared query caching.
7
17
  - fix(runtime): reject recursive `derive()` and `selector()` reads before a
package/README.md CHANGED
@@ -3,9 +3,11 @@
3
3
  [![CI](https://github.com/askrjs/askr/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/askrjs/askr/actions/workflows/ci.yml)
4
4
  [![npm version](https://img.shields.io/npm/v/%40askrjs%2Faskr.svg)](https://www.npmjs.com/package/@askrjs/askr)
5
5
 
6
- Askr is an actor-backed UI runtime for TypeScript applications.
7
- It provides explicit reactivity, routed application startup, server-side rendering,
8
- and static-site generation entrypoints.
6
+ Askr is a lane-scheduled UI runtime for TypeScript applications. Its
7
+ single-threaded scheduler serializes queued framework work; it is not a
8
+ message-passing actor system. Askr provides explicit reactivity, routed
9
+ application startup, server-side rendering, and static-site generation
10
+ entrypoints.
9
11
 
10
12
  ## Quick Start
11
13
 
@@ -22,6 +24,9 @@ function Counter() {
22
24
  createIsland({ root: document.body, component: Counter });
23
25
  ```
24
26
 
27
+ The tuple form above and the direct callable form below are equivalent; see
28
+ [State usage forms](#state-usage-forms) for when each is convenient.
29
+
25
30
  ## What It Provides
26
31
 
27
32
  ### Runtime
@@ -41,12 +46,30 @@ on their own subpaths.
41
46
 
42
47
  State is read through getter functions and updated through setter functions.
43
48
 
49
+ #### State usage forms
50
+
51
+ `state()` returns one callable state cell that is also iterable. Destructuring
52
+ it gives the cell as the getter and its `.set()` method as the setter:
53
+
44
54
  ```ts
45
55
  const [count, setCount] = state(0);
46
56
  console.log(count());
47
57
  setCount(1);
48
58
  ```
49
59
 
60
+ The same state can be kept as one value and updated through `.set()`:
61
+
62
+ ```ts
63
+ const count = state(0);
64
+ console.log(count());
65
+ count.set(1);
66
+ ```
67
+
68
+ Prefer destructuring when local getter and setter names make event handlers
69
+ clear. Prefer the direct form when passing the state cell around as one value or
70
+ when keeping reads and writes under one name. Both forms have the same tracking,
71
+ scheduling, and update semantics.
72
+
50
73
  ### Routing and app startup
51
74
 
52
75
  Startup belongs in `@askrjs/askr/boot`. Routing helpers live in
@@ -86,7 +109,12 @@ return <div>{data.value.name}</div>;
86
109
  }
87
110
  ```
88
111
 
89
- Query and mutation helpers live in `@askrjs/askr/data`.
112
+ `@askrjs/askr/data` is the canonical entrypoint for all query, mutation,
113
+ invalidation, and data-runtime helpers. The root package retains query creation
114
+ and collection, definition and serving, prefetch, and hydration exports for
115
+ compatibility with existing applications. Mutation, invalidation, and
116
+ data-runtime control remain subpath-only. New code should import the whole data surface from
117
+ `@askrjs/askr/data` rather than split related imports across entrypoints.
90
118
 
91
119
  ### Developer error boundaries
92
120
 
@@ -282,7 +282,15 @@ var Scheduler = class {
282
282
  const target = typeof targetVersion === "number" ? targetVersion : this.flushVersion + 1;
283
283
  if (this.flushVersion >= target) return Promise.resolve();
284
284
  return new Promise((resolve, reject) => {
285
- const timer = setTimeout(() => {
285
+ const waiter = {
286
+ target,
287
+ resolve,
288
+ reject
289
+ };
290
+ waiter.timer = setTimeout(() => {
291
+ const index = this.waiters.indexOf(waiter);
292
+ if (index >= 0) this.waiters.splice(index, 1);
293
+ if (waiter.timer !== void 0) clearTimeout(waiter.timer);
286
294
  const diag = {
287
295
  flushVersion: this.flushVersion,
288
296
  queueLen: this.getPendingTaskCount(),
@@ -292,12 +300,7 @@ var Scheduler = class {
292
300
  };
293
301
  reject(/* @__PURE__ */ new Error(`waitForFlush timeout ${timeoutMs}ms: ${JSON.stringify(diag)}`));
294
302
  }, timeoutMs);
295
- this.waiters.push({
296
- target,
297
- resolve,
298
- reject,
299
- timer
300
- });
303
+ this.waiters.push(waiter);
301
304
  });
302
305
  }
303
306
  getState() {
@@ -331,8 +334,10 @@ var Scheduler = class {
331
334
  return fn();
332
335
  } finally {
333
336
  this.inHandler = prevInHandler;
334
- if (!this.inHandler) if (flushMode === "sync") this.flushIfQueued();
335
- else this.scheduleFlushKick();
337
+ if (!this.inHandler) {
338
+ if (flushMode === "sync") this.flushIfQueued();
339
+ else this.scheduleFlushKick();
340
+ }
336
341
  }
337
342
  }
338
343
  setInHandler(v) {
@@ -377,7 +382,7 @@ var Scheduler = class {
377
382
  const ready = [];
378
383
  const remaining = [];
379
384
  for (const w of this.waiters) if (this.flushVersion >= w.target) {
380
- if (w.timer) clearTimeout(w.timer);
385
+ if (w.timer !== void 0) clearTimeout(w.timer);
381
386
  ready.push(w.resolve);
382
387
  } else remaining.push(w);
383
388
  this.waiters = remaining;
@@ -1,2 +1,2 @@
1
- import { a as action, i as ActionValidationError, n as ActionForm, o as defineAction, r as ActionStatus, t as ActionDescriptor } from "../index-DSqXWc77.js";
1
+ import { a as action, i as ActionValidationError, n as ActionForm, o as defineAction, r as ActionStatus, t as ActionDescriptor } from "../index-Dgjbo2gU.js";
2
2
  export { ActionDescriptor, ActionForm, ActionStatus, ActionValidationError, action, defineAction };
@@ -1,8 +1,9 @@
1
1
  import { d as getCurrentAppRenderRuntime } from "../component-scope-4I3yEMkb.js";
2
2
  import { r as getCurrentRenderData } from "../render-context-B7ohlh6t.js";
3
- import { t as state } from "../state-Ks-sWTQi.js";
3
+ import { t as state } from "../state-BGJgYSyQ.js";
4
4
  import { jsx, jsxs } from "../jsx-runtime.js";
5
5
  import { c as resolveDataRuntimeState, s as invalidateQueriesForRuntime } from "../data-runtime-7t_Y0iv3.js";
6
+ import { r as isCurrentAsyncGeneration } from "../shared-CYBH3F8I.js";
6
7
  //#region src/actions/runtime.ts
7
8
  const emptyFramework = Object.freeze({});
8
9
  /** @internal Read Askr-owned state from the current application root. */
@@ -97,8 +98,8 @@ function action(descriptor) {
97
98
  if (!response.ok) throw envelope.error ?? validationError(envelope, descriptor.id) ?? /* @__PURE__ */ new Error(`Action failed (${response.status}).`);
98
99
  const redirect = typeof envelope.redirect === "string" ? normalizeActionRedirect(envelope.redirect) : void 0;
99
100
  const invalidates = Array.isArray(envelope.invalidates) ? envelope.invalidates.filter((prefix) => typeof prefix === "string") : descriptor.invalidates;
100
- if (generation === actionSubmissionGenerations.get(value)) {
101
- for (const prefix of invalidates) invalidateQueriesForRuntime(runtime, prefix, true);
101
+ for (const prefix of invalidates) invalidateQueriesForRuntime(runtime, prefix, true);
102
+ if (isCurrentAsyncGeneration(actionSubmissionGenerations.get(value) ?? 0, generation)) {
102
103
  setValue({
103
104
  pending: false,
104
105
  result: envelope.result
@@ -107,7 +108,7 @@ function action(descriptor) {
107
108
  }
108
109
  return envelope.result;
109
110
  } catch (error) {
110
- if (generation === actionSubmissionGenerations.get(value)) setValue({
111
+ if (isCurrentAsyncGeneration(actionSubmissionGenerations.get(value) ?? 0, generation)) setValue({
111
112
  pending: false,
112
113
  error
113
114
  });
@@ -1,4 +1,4 @@
1
- import { Rt as RouteSnapshot, wt as RouteParams } from "./index-DSqXWc77.js";
1
+ import { $t as RouteSnapshot, zt as RouteParams } from "./index-Dgjbo2gU.js";
2
2
  //#region src/router/activity.d.ts
3
3
  /** Options for {@link onRouteChange}. */
4
4
  interface RouteChangeOptions {
@@ -9,6 +9,6 @@ type RouteChangeCleanup = void | (() => void);
9
9
  /** Register a callback to run whenever the active route changes, with optional cleanup. */
10
10
  declare function onRouteChange(fn: (current: RouteSnapshot, previous: RouteSnapshot | null) => RouteChangeCleanup, options?: RouteChangeOptions): void;
11
11
  /** Read the currently active route's {@link RouteSnapshot}; reactive during component render. */
12
- declare function currentRoute<TParams extends RouteParams = RouteParams>(): RouteSnapshot<TParams>;
12
+ declare function currentRoute<TParams extends RouteParams = RouteParams, TState = unknown>(): RouteSnapshot<TParams, TState>;
13
13
  //#endregion
14
14
  export { onRouteChange as i, RouteChangeOptions as n, currentRoute as r, RouteChangeCleanup as t };
@@ -1,6 +1,6 @@
1
1
  import { d as getCurrentAppRenderRuntime, f as getCurrentComponentInstance, i as claimHookIndex } from "./component-scope-4I3yEMkb.js";
2
- import { a as registerCommitOperation } from "./component-internal-xW_OnTmC.js";
3
- import { l as notifyReadableReaders, o as markReactivePropsDirtySource, s as markReadableDerivedSubscribersDirty, u as recordReadableRead } from "./readable-D-JIKCg2.js";
2
+ import { a as registerCommitOperation } from "./component-internal-C4hKKQBF.js";
3
+ import { l as notifyReadableReaders, o as markReactivePropsDirtySource, s as markReadableDerivedSubscribersDirty, u as recordReadableRead } from "./readable-Di1fzSwm.js";
4
4
  import { n as getActiveRenderContext } from "./render-context-B7ohlh6t.js";
5
5
  import { n as syncRouteActivitySnapshot } from "./route-activity-CNJfpwx-.js";
6
6
  import { b as getActiveRoutes, c as removeRouteBasePath, d as deepFreeze, f as makeQuery, n as computeMatchesFromRoutes, p as parseLocation, y as getActiveRouteBasePath } from "./route-matching-Bo6UqG-5.js";
@@ -83,6 +83,14 @@ function onRouteChange(fn, options = {}) {
83
83
  });
84
84
  }
85
85
  let serverLocation = null;
86
+ function readLocationState() {
87
+ const historyState = typeof window !== "undefined" && window.history?.state ? window.history.state : null;
88
+ const hasState = historyState?.askrHasState === true;
89
+ return {
90
+ hasState,
91
+ state: hasState ? historyState.askrState : void 0
92
+ };
93
+ }
86
94
  function logicalRoutePathname(pathname) {
87
95
  const logical = removeRouteBasePath(pathname, getActiveRouteBasePath());
88
96
  return logical === void 0 ? void 0 : parseLocation(logical).pathname;
@@ -111,11 +119,13 @@ function buildRouteSnapshot(pathname, search, hash) {
111
119
  pathname = location.pathname;
112
120
  const query = makeQuery(search);
113
121
  const matches = location.withinBasePath ? computeMatchesFromRoutes(pathname, getActiveRoutes()) : [];
122
+ const locationState = readLocationState();
114
123
  return Object.freeze({
115
124
  path: pathname,
116
125
  params: deepFreeze({ ...matches[0]?.params }),
117
126
  query,
118
127
  hash: hash || null,
128
+ ...locationState,
119
129
  matches: Object.freeze(matches)
120
130
  });
121
131
  }
@@ -172,11 +182,13 @@ function readCurrentRouteSnapshot() {
172
182
  const matches = withinBasePath ? computeMatchesFromRoutes(pathname, getActiveRoutes()) : [];
173
183
  const routeParams = (withinBasePath ? getActiveRenderContext()?.params : void 0) ?? matches[0]?.params ?? {};
174
184
  const params = deepFreeze({ ...routeParams });
185
+ const locationState = readLocationState();
175
186
  return Object.freeze({
176
187
  path: pathname,
177
188
  params,
178
189
  query,
179
190
  hash: hash || null,
191
+ ...locationState,
180
192
  matches: Object.freeze(matches)
181
193
  });
182
194
  }
@@ -85,21 +85,4 @@ function ariaSelected(selected) {
85
85
  return selected === void 0 ? {} : { "aria-selected": String(selected) };
86
86
  }
87
87
  //#endregion
88
- //#region src/foundations/utilities/compose-ref.ts
89
- /** Write `value` to a {@link Ref}, ignoring failures on readonly object refs. */
90
- function setRef(ref, value) {
91
- if (!ref) return;
92
- if (typeof ref === "function") {
93
- ref(value);
94
- return;
95
- }
96
- if (Object.isExtensible(ref)) ref.current = value;
97
- }
98
- /** Combine multiple refs into one callback ref that writes to all of them. */
99
- function composeRefs(...refs) {
100
- return (value) => {
101
- for (const ref of refs) setRef(ref, value);
102
- };
103
- }
104
- //#endregion
105
- export { ariaSelected as a, ariaExpanded as i, setRef as n, mergeProps as o, ariaDisabled as r, composeHandlers as s, composeRefs as t };
88
+ export { composeHandlers as a, mergeProps as i, ariaExpanded as n, ariaSelected as r, ariaDisabled as t };
@@ -1,4 +1,4 @@
1
- import "./jsx-runtime-BTzDdBJ_.js";
1
+ import "./jsx-runtime-Cg7GqY1S.js";
2
2
  //#region src/bench/components/benchmark-row.d.ts
3
3
  interface BenchmarkRowData {
4
4
  id: number;
package/dist/benchmark.js CHANGED
@@ -1,10 +1,10 @@
1
- import { r as flushRuntimeScheduler } from "./access-d_DCdwqn.js";
2
- import { t as state } from "./state-Ks-sWTQi.js";
3
- import { t as selector } from "./selector-NQiYHwZC.js";
4
- import { t as installRendererBridge } from "./renderer-RjZ8LHbt.js";
5
- import { i as For } from "./control-BLVTE1gO.js";
1
+ import { r as flushRuntimeScheduler } from "./access-BucjYZcX.js";
2
+ import { t as state } from "./state-BGJgYSyQ.js";
3
+ import { t as selector } from "./selector-CsKuomw0.js";
4
+ import { t as installRendererBridge } from "./renderer-Cl23O0hV.js";
5
+ import { i as For } from "./control-C-wSaq9V.js";
6
6
  import { jsx, jsxs } from "./jsx-runtime.js";
7
- import { t as createIsland } from "./boot-DVwjHCNh.js";
7
+ import { t as createIsland } from "./boot-tWyF6121.js";
8
8
  //#region src/bench/components/benchmark-row.tsx
9
9
  function BenchmarkRow({ item, isSelected, onSelect, onRemove }) {
10
10
  return /* @__PURE__ */ jsxs("tr", {
@@ -63,8 +63,8 @@ function BenchmarkTable({ rows, isSelected, onSelect, onRemove }) {
63
63
  installRendererBridge();
64
64
  const benchmarkMetadata = {
65
65
  packageName: "@askrjs/askr",
66
- packageVersion: "0.2.2",
67
- buildLabel: "0.2.2-local"
66
+ packageVersion: "0.2.4",
67
+ buildLabel: "0.2.4-local"
68
68
  };
69
69
  function getBenchmarkMetadata() {
70
70
  return { ...benchmarkMetadata };
@@ -1,11 +1,13 @@
1
- import { Bt as DataRuntime, dt as RouteAuthOptions, jt as RouteRegistry, sn as ComponentFunction } from "../index-DSqXWc77.js";
2
- import { a as ScrollRestorationOptions } from "../navigate-wel1e6cU.js";
1
+ import { Et as RouteAuthOptions, Kt as RouteRegistry, Sn as ComponentFunction, tn as DataRuntime } from "../index-Dgjbo2gU.js";
2
+ import { a as ScrollRestorationOptions } from "../navigate-F4sHgWbw.js";
3
3
  //#region src/boot/types.d.ts
4
4
  /** Configuration for {@link createIsland}: mounts one component onto existing DOM. */
5
5
  type IslandConfig = {
6
6
  root: Element | string;
7
7
  component: ComponentFunction;
8
8
  cspNonce?: string;
9
+ /** Optional data runtime owned by this island's render and event lifecycle. */
10
+ dataRuntime?: DataRuntime;
9
11
  cleanupStrict?: boolean;
10
12
  routes?: never;
11
13
  };
@@ -1,2 +1,2 @@
1
- import { a as cleanupApp, i as hydrateSPA, n as createIslands, o as hasApp, r as createSPA, t as createIsland } from "../boot-DVwjHCNh.js";
1
+ import { a as cleanupApp, i as hydrateSPA, n as createIslands, o as hasApp, r as createSPA, t as createIsland } from "../boot-tWyF6121.js";
2
2
  export { cleanupApp, createIsland, createIslands, createSPA, hasApp, hydrateSPA };
@@ -1,19 +1,19 @@
1
- import { S as isProductionEnvironment, r as flushRuntimeScheduler, x as isDevelopmentEnvironment, y as logger } from "./access-d_DCdwqn.js";
1
+ import { S as isProductionEnvironment, r as flushRuntimeScheduler, x as isDevelopmentEnvironment, y as logger } from "./access-BucjYZcX.js";
2
2
  import { n as Fragment, t as ELEMENT_TYPE } from "./jsx-DRS-qjiN.js";
3
- import { n as createComponentInstance, r as executeComponent } from "./component-internal-xW_OnTmC.js";
4
- import { t as cleanupComponent } from "./component-cleanup-DPe8claJ.js";
5
- import { p as isPromiseLike } from "./lifecycle-batch-BYECQw8T.js";
6
- import { _ as teardownNodeSubtree, d as removeAllListeners } from "./cleanup-DPtpXtA4.js";
3
+ import { n as createComponentInstance, r as executeComponent } from "./component-internal-C4hKKQBF.js";
4
+ import { t as cleanupComponent } from "./component-cleanup-jdbgjkT1.js";
5
+ import { p as isPromiseLike } from "./lifecycle-batch-63aXFf2S.js";
6
+ import { _ as teardownNodeSubtree, d as removeAllListeners } from "./cleanup-TXSsApEl.js";
7
7
  import { r as assertExecutionModel, t as _applyManifest } from "./manifest-D6rfj_jC.js";
8
8
  import { d as stopHydrationRenderPhase, l as startHydrationRenderPhase, y as pageRenderEnvelope } from "./render-context-B7ohlh6t.js";
9
- import { a as setStaticChildSlotsCacheEnabled, c as endHydrationDirectListenerMode, d as discardHydrationListenerTransaction, i as registerDeferredHydrationBoundary, l as beginHydrationListenerTransaction, n as activateHydrationBoundary$1, o as withIntrinsicHydrationAdoption, r as clearDeferredHydrationBoundaries, s as beginHydrationDirectListenerMode, t as installRendererBridge, u as commitHydrationListenerTransaction } from "./renderer-RjZ8LHbt.js";
10
- import { r as validateCspNonce, t as CspNonceScope } from "./csp-nonce-CCnMtOW-.js";
9
+ import { a as setStaticChildSlotsCacheEnabled, c as endHydrationDirectListenerMode, d as discardHydrationListenerTransaction, i as registerDeferredHydrationBoundary, l as beginHydrationListenerTransaction, n as activateHydrationBoundary$1, o as withIntrinsicHydrationAdoption, r as clearDeferredHydrationBoundaries, s as beginHydrationDirectListenerMode, t as installRendererBridge, u as commitHydrationListenerTransaction } from "./renderer-Cl23O0hV.js";
10
+ import { r as validateCspNonce, t as CspNonceScope } from "./csp-nonce-9NFUb7hJ.js";
11
11
  import { i as getDefaultDataRuntime } from "./data-runtime-7t_Y0iv3.js";
12
12
  import { a as hydrateDataRuntime } from "./query-registry-Bua3cDyb.js";
13
13
  import { I as lockRouteRegistration, P as hasRegisteredRoutes, _ as clearRouteState, m as _setActiveRouteAuthOptions } from "./route-matching-Bo6UqG-5.js";
14
- import { a as resolveRouteRequest, i as hasRouteRenderData, m as reviveDeferredValue, n as getRouteRenderContext, r as getRouteRenderData } from "./resolution-dVYwYXrI.js";
15
- import { o as createAppRenderRuntime, r as setServerLocation } from "./activity-B2Yy7Wz9.js";
16
- import { f as registerAppInstance, g as unregisterAppInstance, i as resolveRouteMeta, o as configureScrollRestoration, r as reconcileRouteMeta, t as initializeNavigation } from "./navigate-DvJvo--6.js";
14
+ import { a as resolveRouteRequest, i as hasRouteRenderData, m as reviveDeferredValue, n as getRouteRenderContext, r as getRouteRenderData } from "./resolution-ClD-K7Lz.js";
15
+ import { o as createAppRenderRuntime, r as setServerLocation } from "./activity-FirwPXA_.js";
16
+ import { f as registerAppInstance, g as unregisterAppInstance, i as resolveRouteMeta, o as configureScrollRestoration, r as reconcileRouteMeta, t as initializeNavigation } from "./navigate-ZZu1IV0B.js";
17
17
  import { n as disposeRegisteredDefaultPortalScope, r as getDefaultPortalHost } from "./default-portal-runtime-DvMvWJVp.js";
18
18
  import "./ssr-DSHd_Q9K.js";
19
19
  //#region src/boot/hydration.ts
@@ -109,9 +109,7 @@ function shouldVerifyHydrationMarkup(config) {
109
109
  return !isProductionEnvironment();
110
110
  }
111
111
  async function applySelectiveHydration(rootElement, resolved, path, cleanupStrict, hydrateOptions, source, hooks, interactionReplay) {
112
- const hasPermanentSkips = (hydrateOptions.skipSelectors?.length ?? 0) > 0;
113
112
  const hasBelowFoldDeferral = !!hydrateOptions.deferBelowFold;
114
- const hasSelectiveBoundaries = hasPermanentSkips || hasBelowFoldDeferral;
115
113
  let staticChildSlotsCacheSuspended = false;
116
114
  let releaseSelectiveHydrationResources = () => {};
117
115
  const restoreStaticChildSlotsCache = () => {
@@ -146,7 +144,7 @@ async function applySelectiveHydration(rootElement, resolved, path, cleanupStric
146
144
  unregisterRootCleanupCallback = hooks.registerRootCleanupCallback(rootElement, releaseSelectiveHydrationResources);
147
145
  window.addEventListener("scroll", handleScroll, { passive: true });
148
146
  }
149
- if (hydrateOptions.deferUntilIdle && !hasSelectiveBoundaries) {
147
+ if (hydrateOptions.deferUntilIdle && !hasBelowFoldDeferral) {
150
148
  await queueIdleWork(() => {
151
149
  hooks.mountOrUpdate(rootElement, (() => resolved.handler(resolved.params)), {
152
150
  cleanupStrict,
@@ -630,7 +628,8 @@ function createIsland(config) {
630
628
  if (hasRegisteredRoutes()) throw new Error("Routes are not supported with islands. Use createSPA (client) or createSSR (server) instead.");
631
629
  mountOrUpdate(rootElement, config.component, {
632
630
  cleanupStrict: config.cleanupStrict,
633
- cspNonce: config.cspNonce
631
+ cspNonce: config.cspNonce,
632
+ appRuntime: createAppRenderRuntime({ dataRuntime: config.dataRuntime ?? getDefaultDataRuntime() })
634
633
  });
635
634
  }
636
635
  /**
@@ -786,7 +785,7 @@ async function hydrateSPA(config) {
786
785
  cspNonce: config.cspNonce
787
786
  }));
788
787
  if (shouldVerifyHydrationMarkup(config)) {
789
- const { verifyHydrationSyncForUrl } = await import("./verify-hydration-CThsx0pq.js");
788
+ const { verifyHydrationSyncForUrl } = await import("./verify-hydration-BZPJ_kYa.js");
790
789
  if (!verifyHydrationSyncForUrl({
791
790
  root: rootElement,
792
791
  url: currentUrl,
@@ -1,8 +1,9 @@
1
- import { l as runRuntimeHandlerScope, y as logger } from "./access-d_DCdwqn.js";
2
- import "./fastlane-DUxiFV9S.js";
1
+ import { l as runRuntimeHandlerScope, y as logger } from "./access-BucjYZcX.js";
2
+ import "./fastlane-BKZduiBQ.js";
3
3
  import { T as withAppRenderRuntime, d as getCurrentAppRenderRuntime } from "./component-scope-4I3yEMkb.js";
4
- import { t as cleanupComponent } from "./component-cleanup-DPe8claJ.js";
5
- import { u as registerLifecycleTransaction } from "./lifecycle-batch-BYECQw8T.js";
4
+ import { t as cleanupComponent } from "./component-cleanup-jdbgjkT1.js";
5
+ import { u as registerLifecycleTransaction } from "./lifecycle-batch-63aXFf2S.js";
6
+ import { n as setRef } from "./compose-ref-Bfaf4kUC.js";
6
7
  //#region src/runtime/events.ts
7
8
  /**
8
9
  * Event delegation system for Askr
@@ -281,13 +282,7 @@ function replaceElementRefBookkeeping(element, ref) {
281
282
  } else elementRefs.delete(element);
282
283
  }
283
284
  function applyRefValue(ref, value) {
284
- const resolvedRef = ref;
285
- if (!resolvedRef) return;
286
- if (typeof resolvedRef === "function") {
287
- resolvedRef(value);
288
- return;
289
- }
290
- if (Object.isExtensible(resolvedRef)) resolvedRef.current = value;
285
+ setRef(ref, value);
291
286
  }
292
287
  function updateElementRef(element, ref) {
293
288
  if (registerLifecycleTransaction({}, () => updateElementRefImmediately(element, ref), () => void 0)) return;
@@ -1,6 +1,6 @@
1
- import { S as isProductionEnvironment, x as isDevelopmentEnvironment, y as logger } from "./access-d_DCdwqn.js";
1
+ import { S as isProductionEnvironment, x as isDevelopmentEnvironment, y as logger } from "./access-BucjYZcX.js";
2
2
  import { a as clearCurrentComponentScope, y as restoreCurrentComponentScope } from "./component-scope-4I3yEMkb.js";
3
- import { n as cleanupReadableSubscriptions, t as cleanupReadableSubscriptionSources } from "./readable-D-JIKCg2.js";
3
+ import { n as cleanupReadableSubscriptions, t as cleanupReadableSubscriptionSources } from "./readable-Di1fzSwm.js";
4
4
  //#region src/runtime/state-diagnostics.ts
5
5
  /**
6
6
  * Report state cells that were never read during a component's completed
@@ -1,10 +1,10 @@
1
1
  import { a as markTransparentComponentResult, i as markEagerControlPrimitive } from "./control-C-ApnFs1.js";
2
- import { S as isProductionEnvironment, n as enqueueRuntimeTask, o as getRuntimeRenderer, x as isDevelopmentEnvironment, y as logger } from "./access-d_DCdwqn.js";
3
- import { i as tryRuntimeFastLaneSync, n as isBulkCommitActive } from "./fastlane-DUxiFV9S.js";
2
+ import { S as isProductionEnvironment, n as enqueueRuntimeTask, o as getRuntimeRenderer, x as isDevelopmentEnvironment, y as logger } from "./access-BucjYZcX.js";
3
+ import { i as tryRuntimeFastLaneSync, n as isBulkCommitActive } from "./fastlane-BKZduiBQ.js";
4
4
  import { C as restoreRenderScopedComponent, S as restoreInlineRenderTracking, _ as getSignalForInstance, b as restoreDomCommitScope, c as enterDomCommitScope, f as getCurrentComponentInstance, l as enterRenderScopedComponent, m as getCurrentPortalScope, n as captureInlineComponentScope, o as clearRenderTracking, p as getCurrentInstance, r as captureInlineRenderTracking, s as enterComponentExecutionScope, t as beginRenderTracking, u as exitComponentExecutionScope, v as resetRenderState, x as restoreInlineComponentScope } from "./component-scope-4I3yEMkb.js";
5
5
  import { r as STATIC_CHILDREN, t as ELEMENT_TYPE } from "./jsx-DRS-qjiN.js";
6
- import { i as finalizeReadableSubscriptions } from "./readable-D-JIKCg2.js";
7
- import { a as enqueueLifecycleCommitForInstance, d as discardCommitOperations, f as executeCommittedLifecycleOperations, n as captureInlineRenderSnapshot$1, o as finalizeInlineReadSubscriptions, p as isPromiseLike, r as discardLifecycleCommitBatch, s as flushLifecycleCommitBatch, t as beginLifecycleCommitBatch } from "./lifecycle-batch-BYECQw8T.js";
6
+ import { i as finalizeReadableSubscriptions } from "./readable-Di1fzSwm.js";
7
+ import { a as enqueueLifecycleCommitForInstance, d as discardCommitOperations, f as executeCommittedLifecycleOperations, n as captureInlineRenderSnapshot$1, o as finalizeInlineReadSubscriptions, p as isPromiseLike, r as discardLifecycleCommitBatch, s as flushLifecycleCommitBatch, t as beginLifecycleCommitBatch } from "./lifecycle-batch-63aXFf2S.js";
8
8
  //#region src/runtime/context.ts
9
9
  const TransparentContextScopeComponent = markTransparentComponentResult(ContextScopeComponent);
10
10
  let nextScopeIdentityKey = 0;
@@ -689,7 +689,7 @@ function commitRenderedComponent(instance) {
689
689
  function mountInstanceInline(instance, target) {
690
690
  instance.target = target;
691
691
  try {
692
- if (target instanceof Element) {
692
+ if (typeof Element !== "undefined" && target instanceof Element) {
693
693
  const host = target;
694
694
  const instances = host.__ASKR_INSTANCES;
695
695
  if (!instances) {
@@ -702,7 +702,16 @@ function mountInstanceInline(instance, target) {
702
702
  host.__ASKR_INSTANCE = nextInstances[0] ?? instance;
703
703
  }
704
704
  }
705
- } catch (err) {}
705
+ } catch (err) {
706
+ if (isDevelopmentEnvironment()) {
707
+ const componentName = instance.fn.name || instance.id;
708
+ let hostName = "unknown";
709
+ try {
710
+ hostName = target?.tagName?.toLowerCase() || hostName;
711
+ } catch {}
712
+ logger.warn(`[askr] Failed to record DOM ownership for ${componentName} on <${hostName}>.`, err);
713
+ }
714
+ }
706
715
  instance.notifyUpdate = instance._enqueueRun;
707
716
  const wasFirstMount = !instance.mounted;
708
717
  instance.mounted = true;
@@ -803,4 +812,4 @@ function warnInstanceOnce(instance, key, message) {
803
812
  logger.warn(message);
804
813
  }
805
814
  //#endregion
806
- export { withContext as S, haveEquivalentContextFrames as _, registerCommitOperation as a, rebaseVNodeTreeWithContextFrame as b, createBoundaryReset as c, configureRenderDiagnostics as d, callWithContext as f, getVNodeContextFrame as g, getExecutionContextFrame as h, mountInstanceInline as i, reportBoundaryError as l, getCurrentContextFrame as m, createComponentInstance as n, renderComponentInline as o, defineScope as p, executeComponent as r, renderScopedComponent as s, captureInlineRenderSnapshot as t, registerCommitOperationForInstance as u, markVNodeTreeWithContextFrame as v, withAsyncResourceContext as x, readScope as y };
815
+ export { withContext as C, withAsyncResourceContext as S, getVNodeContextFrame as _, registerCommitOperation as a, readScope as b, createBoundaryReset as c, registerCommitOperationForInstance as d, configureRenderDiagnostics as f, getExecutionContextFrame as g, getCurrentContextFrame as h, mountInstanceInline as i, reportBoundaryError as l, defineScope as m, createComponentInstance as n, renderComponentInline as o, callWithContext as p, executeComponent as r, renderScopedComponent as s, captureInlineRenderSnapshot as t, routeComponentErrorToBoundary as u, haveEquivalentContextFrames as v, rebaseVNodeTreeWithContextFrame as x, markVNodeTreeWithContextFrame as y };
@@ -1,5 +1,5 @@
1
- import { ln as VNode } from "../index-DSqXWc77.js";
2
- import { r as JSXElement, s as Props } from "../types-DkVJhVs9.js";
1
+ import { wn as VNode } from "../index-Dgjbo2gU.js";
2
+ import { r as JSXElement, s as Props } from "../types-DWVrKn9N.js";
3
3
  //#region src/common/error-boundary.d.ts
4
4
  type ErrorBoundaryContent = VNode | readonly VNode[];
5
5
  type ErrorBoundaryFallbackValue = ErrorBoundaryContent | Node;
@@ -0,0 +1,20 @@
1
+ //#region src/foundations/utilities/compose-ref.ts
2
+ /** Write `value` to a {@link Ref}, ignoring failures on readonly object refs. */
3
+ function setRef(ref, value) {
4
+ if (!ref) return;
5
+ if (typeof ref === "function") {
6
+ ref(value);
7
+ return;
8
+ }
9
+ try {
10
+ ref.current = value;
11
+ } catch {}
12
+ }
13
+ /** Combine multiple refs into one callback ref that writes to all of them. */
14
+ function composeRefs(...refs) {
15
+ return (value) => {
16
+ for (const ref of refs) setRef(ref, value);
17
+ };
18
+ }
19
+ //#endregion
20
+ export { setRef as n, composeRefs as t };
@@ -1,2 +1,2 @@
1
- import { F as Show, I as ShowProps, L as For, M as CaseProps, N as Match, P as MatchProps, R as ForProps, j as Case } from "../index-DSqXWc77.js";
1
+ import { F as Show, I as ShowProps, L as For, M as CaseProps, N as Match, P as MatchProps, R as ForProps, j as Case } from "../index-Dgjbo2gU.js";
2
2
  export { Case, type CaseProps, For, type ForProps, Match, type MatchProps, Show, type ShowProps };
@@ -1,2 +1,2 @@
1
- import { i as For, n as Match, r as Show, t as Case } from "../control-BLVTE1gO.js";
1
+ import { i as For, n as Match, r as Show, t as Case } from "../control-C-wSaq9V.js";
2
2
  export { Case, For, Match, Show };
@@ -1,9 +1,9 @@
1
1
  import { i as markEagerControlPrimitive, t as __CONTROL_BOUNDARY__ } from "./control-C-ApnFs1.js";
2
- import { x as isDevelopmentEnvironment } from "./access-d_DCdwqn.js";
2
+ import { x as isDevelopmentEnvironment } from "./access-BucjYZcX.js";
3
3
  import { n as Fragment } from "./jsx-DRS-qjiN.js";
4
- import { m as createShowState, p as createCaseState, s as useForState } from "./for-internal-DKcYl3nl.js";
5
- import { t as createFineGrainedEffect } from "./effect-BQP5o0Kx.js";
6
- import { t as state } from "./state-Ks-sWTQi.js";
4
+ import { m as createShowState, p as createCaseState, s as useForState } from "./for-internal-DyBHfKJA.js";
5
+ import { t as createFineGrainedEffect } from "./effect-CNwstBBD.js";
6
+ import { t as state } from "./state-BGJgYSyQ.js";
7
7
  //#region src/control/shared.ts
8
8
  function normalizeBoundaryChild(value) {
9
9
  if (Array.isArray(value)) {
@@ -1,4 +1,4 @@
1
- import { s as Props } from "./types-DkVJhVs9.js";
1
+ import { s as Props } from "./types-DWVrKn9N.js";
2
2
  //#region src/common/control.d.ts
3
3
  declare const EAGER_CONTROL_PRIMITIVE: unique symbol;
4
4
  type EagerControlPrimitive<P extends Props = Props> = ((props: P) => unknown) & {
@@ -1,4 +1,4 @@
1
- import { p as defineScope, y as readScope } from "./component-internal-xW_OnTmC.js";
1
+ import { b as readScope, m as defineScope } from "./component-internal-C4hKKQBF.js";
2
2
  //#region src/common/url.ts
3
3
  const SAFE_URL_SCHEMES = /* @__PURE__ */ new Set([
4
4
  "http",
@@ -1,2 +1,2 @@
1
- import { $t as QueryKeyPart, Bt as DataRuntime, C as createMutation, Gt as MutationOptions, Ht as InvalidateOnIntervalOptions, Jt as QueryCollectionEntry, Kt as Query, Qt as QueryDefinition, S as createQuery, Ut as InvalidateOptions, Vt as DataRuntimeOptions, Wt as Mutation, Xt as QueryCollectionOptions, Yt as QueryCollectionKey, Zt as QueryConsistency, _ as invalidate, b as createDataRuntime, c as ServerQueryRegistry, d as defineServerQueries, en as QueryPrefetchContext, f as dehydrateDataRuntime, g as createQueryCollection, h as serveQuery, l as createQueryPrefetchContext, m as prefetchQuery, nn as QueryStaleReason, p as hydrateDataRuntime, qt as QueryCollection, rn as ServerQueryHandler, s as ServerQueryEntry, tn as QueryScope, u as defineQuery, v as invalidateOnInterval, x as getDefaultDataRuntime, y as queryScope } from "../index-DSqXWc77.js";
1
+ import { C as createMutation, S as createQuery, _ as invalidate, _n as QueryStaleReason, an as Mutation, b as createDataRuntime, c as ServerQueryRegistry, cn as QueryCollection, d as defineServerQueries, dn as QueryCollectionOptions, f as dehydrateDataRuntime, fn as QueryConsistency, g as createQueryCollection, gn as QueryScope, h as serveQuery, hn as QueryPrefetchContext, in as InvalidateOptions, l as createQueryPrefetchContext, ln as QueryCollectionEntry, m as prefetchQuery, mn as QueryKeyPart, nn as DataRuntimeOptions, on as MutationOptions, p as hydrateDataRuntime, pn as QueryDefinition, rn as InvalidateOnIntervalOptions, s as ServerQueryEntry, sn as Query, tn as DataRuntime, u as defineQuery, un as QueryCollectionKey, v as invalidateOnInterval, vn as ServerQueryHandler, x as getDefaultDataRuntime, y as queryScope } from "../index-Dgjbo2gU.js";
2
2
  export { type DataRuntime, type DataRuntimeOptions, type InvalidateOnIntervalOptions, type InvalidateOptions, type Mutation, type MutationOptions, type Query, type QueryCollection, type QueryCollectionEntry, type QueryCollectionKey, type QueryCollectionOptions, type QueryConsistency, type QueryDefinition, type QueryKeyPart, type QueryPrefetchContext, type QueryScope, type QueryStaleReason, type ServerQueryEntry, type ServerQueryHandler, type ServerQueryRegistry, createDataRuntime, createMutation, createQuery, createQueryCollection, createQueryPrefetchContext, defineQuery, defineServerQueries, dehydrateDataRuntime, getDefaultDataRuntime, hydrateDataRuntime, invalidate, invalidateOnInterval, prefetchQuery, queryScope, serveQuery };
@@ -1,4 +1,4 @@
1
1
  import { i as getDefaultDataRuntime, t as createDataRuntime } from "../data-runtime-7t_Y0iv3.js";
2
- import { c as invalidateOnInterval, l as queryScope, n as createQuery, r as createMutation, s as invalidate, t as createQueryCollection } from "../data-BjUf0PPS.js";
2
+ import { a as invalidateOnInterval, i as invalidate, n as createQuery, o as queryScope, r as createMutation, t as createQueryCollection } from "../data-ghKopAbp.js";
3
3
  import { a as hydrateDataRuntime, i as dehydrateDataRuntime, n as defineQuery, o as prefetchQuery, r as defineServerQueries, s as serveQuery, t as createQueryPrefetchContext } from "../query-registry-Bua3cDyb.js";
4
4
  export { createDataRuntime, createMutation, createQuery, createQueryCollection, createQueryPrefetchContext, defineQuery, defineServerQueries, dehydrateDataRuntime, getDefaultDataRuntime, hydrateDataRuntime, invalidate, invalidateOnInterval, prefetchQuery, queryScope, serveQuery };