@askrjs/askr 0.2.3 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (117) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/dist/access-CEA2pOry.js +1046 -0
  3. package/dist/actions/index.d.ts +16 -2
  4. package/dist/actions/index.js +5 -5
  5. package/dist/{activity-ZxJXI9hF.js → activity-oy2YFTFF.js} +22 -16
  6. package/dist/benchmark.js +8 -9
  7. package/dist/boot/index.d.ts +21 -9
  8. package/dist/boot/index.js +1 -1
  9. package/dist/{boot-D4GaLA0d.js → boot-BMBMWUGI.js} +680 -440
  10. package/dist/capabilities-Bbf0mlp9.js +42 -0
  11. package/dist/components/index.d.ts +11 -8
  12. package/dist/components/index.js +1 -1
  13. package/dist/{compose-ref-Bfaf4kUC.js → compose-ref-v0qGlHoN.js} +7 -1
  14. package/dist/control/index.d.ts +20 -2
  15. package/dist/control/index.js +1 -1
  16. package/dist/{control-57x3wa4J.js → control-BR_mrX__.js} +4 -4
  17. package/dist/core.d.ts +163 -0
  18. package/dist/csp-nonce-BfFWcd0w.js +173 -0
  19. package/dist/data/index.d.ts +74 -2
  20. package/dist/data/index.js +3 -3
  21. package/dist/{data-B7XCDeC8.js → data-2edW0jhF.js} +133 -138
  22. package/dist/{data-runtime-7t_Y0iv3.js → data-runtime-CxoY98lX.js} +22 -15
  23. package/dist/{deferred-BELyvMsC.js → deferred-CbgNhf67.js} +5 -5
  24. package/dist/dom-renderer.d.ts +77 -0
  25. package/dist/domains/actions.d.ts +70 -0
  26. package/dist/domains/component.d.ts +119 -0
  27. package/dist/domains/context.d.ts +73 -0
  28. package/dist/domains/control.d.ts +328 -0
  29. package/dist/domains/data.d.ts +461 -0
  30. package/dist/domains/diagnostics.d.ts +21 -0
  31. package/dist/domains/lifecycle.d.ts +112 -0
  32. package/dist/domains/refs.d.ts +18 -0
  33. package/dist/domains/renderer.d.ts +127 -0
  34. package/dist/domains/routing.d.ts +501 -0
  35. package/dist/domains/scheduler.d.ts +79 -0
  36. package/dist/domains/server.d.ts +112 -0
  37. package/dist/domains/state.d.ts +129 -0
  38. package/dist/domains/telemetry.d.ts +29 -0
  39. package/dist/eager-control.d.ts +8 -0
  40. package/dist/{effect-4LwBwV58.js → effect-C3Zsc1k6.js} +14 -41
  41. package/dist/{types-DkVJhVs9.d.ts → elements.d.ts} +84 -42
  42. package/dist/{for-internal-DeoSg_AV.js → for-state-BDykeOJL.js} +623 -511
  43. package/dist/foundations/icon/index.d.ts +67 -16
  44. package/dist/foundations/icon/index.js +1 -1
  45. package/dist/foundations/index.d.ts +26 -3
  46. package/dist/foundations/index.js +1 -1
  47. package/dist/foundations/interactions/index.d.ts +73 -34
  48. package/dist/foundations/interactions/index.js +1 -1
  49. package/dist/foundations/state/index.d.ts +12 -5
  50. package/dist/foundations/state/index.js +1 -1
  51. package/dist/foundations/structures/index.d.ts +44 -3
  52. package/dist/foundations/structures/index.js +1 -1
  53. package/dist/foundations/utilities/index.d.ts +34 -3
  54. package/dist/foundations/utilities/index.js +1 -1
  55. package/dist/fx/index.d.ts +72 -25
  56. package/dist/fx/index.js +8 -8
  57. package/dist/index.d.ts +121 -4
  58. package/dist/index.js +316 -47
  59. package/dist/{component-internal-Dl02WQKS.js → instance-VAFYVJOa.js} +495 -283
  60. package/dist/{interactions-D102JxBR.js → interactions-CTeACdT_.js} +1 -1
  61. package/dist/jsx-dev-runtime.d.ts +51 -11
  62. package/dist/jsx-globals.d.ts +2 -0
  63. package/dist/jsx-runtime-CPJXAOBF.js +43 -0
  64. package/dist/jsx-runtime.d.ts +17 -3
  65. package/dist/jsx-runtime.js +2 -42
  66. package/dist/jsx.d.ts +108 -0
  67. package/dist/{manifest-D6rfj_jC.js → manifest-D1P3UNWV.js} +4 -9
  68. package/dist/{navigate-C46GtScG.js → navigate-prC5V8XV.js} +204 -476
  69. package/dist/{navigate-wel1e6cU.d.ts → navigation.d.ts} +10 -8
  70. package/dist/{readable-CEcteIDE.js → notify-DxxuDPeY.js} +96 -34
  71. package/dist/{query-registry-Bua3cDyb.js → query-registry-LrYpQsDJ.js} +1 -1
  72. package/dist/{compose-ref-DOJHoW5X.d.ts → refs.d.ts} +11 -7
  73. package/dist/{ssr-BaC5qHEw.js → render-resolved-BC0W7_5b.js} +165 -558
  74. package/dist/{renderer-BhXofszH.js → renderer-CT0HeY58.js} +6866 -5715
  75. package/dist/{resolution-t8J0yNaU.js → resolution-3DskUkjG.js} +189 -180
  76. package/dist/{resource-operation-B8q-QRUx.js → resource-18-sFRl9.js} +98 -58
  77. package/dist/resources/index.d.ts +64 -46
  78. package/dist/resources/index.js +215 -9
  79. package/dist/route-activity.d.ts +21 -0
  80. package/dist/{route-matching-Bo6UqG-5.js → route-matching-CUzZ31gT.js} +68 -82
  81. package/dist/router/index.d.ts +378 -79
  82. package/dist/router/index.js +9 -9
  83. package/dist/router-internal-7nuNEHfG.js +36 -0
  84. package/dist/scope-Cq_iYbTR.js +403 -0
  85. package/dist/{selector-C7rIpOnN.js → selector-BSPVkjKP.js} +41 -41
  86. package/dist/{shared-CGrx2AOL.js → shared-kU8yvryp.js} +3 -6
  87. package/dist/{snapshot-source-BB42xgwb.js → snapshot-source-An4iKajG.js} +1 -1
  88. package/dist/ssg/index.d.ts +51 -15
  89. package/dist/ssg/index.js +269 -209
  90. package/dist/ssr/index.d.ts +121 -68
  91. package/dist/ssr/index.js +2 -1
  92. package/dist/ssr-CiNm6Vzl.js +393 -0
  93. package/dist/{ssr-DSHd_Q9K.js → ssr-EPjwJH5R.js} +5 -1
  94. package/dist/{state-BzhOW2TX.js → state-BXJfudq1.js} +10 -15
  95. package/dist/{structures-BwfeO4Iz.js → structures-CjEzfj4h.js} +37 -57
  96. package/dist/{index-r5THqzPN.d.ts → structures.d.ts} +57 -36
  97. package/dist/testing/index.d.ts +125 -24
  98. package/dist/testing/index.js +26 -62
  99. package/dist/timer-C7uqnJVt.js +85 -0
  100. package/dist/{index-B1gu0_m0.d.ts → utilities.d.ts} +24 -13
  101. package/dist/{verify-hydration-_Q6avFp0.js → verify-hydration-ikaxotf7.js} +8 -5
  102. package/package.json +13 -15
  103. package/dist/access-Rr7CMa06.js +0 -507
  104. package/dist/activity-CAJ5eho-.d.ts +0 -14
  105. package/dist/benchmark.d.ts +0 -26
  106. package/dist/cleanup-DsrbV-rr.js +0 -535
  107. package/dist/component-cleanup-DjpwO9WX.js +0 -143
  108. package/dist/component-scope-4I3yEMkb.js +0 -195
  109. package/dist/control-DdFw-Caz.d.ts +0 -8
  110. package/dist/csp-nonce-C9OuML0U.js +0 -72
  111. package/dist/css-BuPaTOfe.js +0 -70
  112. package/dist/fastlane-Buz1Rvlr.js +0 -166
  113. package/dist/index-DSqXWc77.d.ts +0 -1402
  114. package/dist/jsx-runtime-BTzDdBJ_.d.ts +0 -2
  115. package/dist/jsx-runtime-Cdd6Gkb0.d.ts +0 -38
  116. package/dist/lifecycle-batch-Be-CLDjV.js +0 -253
  117. package/dist/lifecycle-operations-C5m03NQc.js +0 -195
@@ -1,183 +1,9 @@
1
+ import { P as isPromiseLike, m as defineScope, v as readScope } from "./instance-VAFYVJOa.js";
1
2
  import { n as Fragment, t as ELEMENT_TYPE } from "./jsx-DRS-qjiN.js";
2
- import { p as defineScope, y as readScope } from "./component-internal-Dl02WQKS.js";
3
- import { p as isPromiseLike } from "./lifecycle-batch-Be-CLDjV.js";
4
3
  import { S as withPageFramework, b as replacePageRoute, n as getActiveRenderContext } from "./render-context-B7ohlh6t.js";
5
- import { i as ROUTE_ROOT_COMPONENT } from "./csp-nonce-C9OuML0U.js";
6
- import { c as withTelemetry, t as createQueryPrefetchContext } from "./query-registry-Bua3cDyb.js";
7
- import { c as removeRouteBasePath, i as getMatchingRouteRecord, l as buildRouteContext, o as addRouteBasePath, s as normalizeRouteBasePath, u as buildRouteContextBase, v as getActiveRouteAuthOptions } from "./route-matching-Bo6UqG-5.js";
8
- //#region src/router/route-data-loader.ts
9
- /** Thrown when a route's `loader` rejects; wraps the original `cause`. */
10
- var RouteDataLoadError = class extends Error {
11
- constructor(route, phase, cause) {
12
- const detail = cause instanceof Error ? cause.message : String(cause);
13
- super("[Askr] Route data loader failed for \"" + route + "\" during " + phase + " loading: " + detail);
14
- this.name = "RouteDataLoadError";
15
- this.route = route;
16
- this.phase = phase;
17
- this.cause = cause;
18
- }
19
- };
20
- function isAbortError(error) {
21
- return typeof error === "object" && error !== null && "name" in error && error.name === "AbortError";
22
- }
23
- function loadPhase(mode) {
24
- if (mode === "spa") return "client";
25
- if (mode === "ssg") return "ssg";
26
- return "server";
27
- }
28
- /** @internal Add route context to failures from lazyRouteData(). */
29
- function _wrapRouteDataLoadError(error, context) {
30
- if (error instanceof RouteDataLoadError || isAbortError(error)) throw error;
31
- throw new RouteDataLoadError(context.href || context.pathname, loadPhase(context.mode), error);
32
- }
33
- //#endregion
34
- //#region src/router/lazy.ts
35
- const pendingLazy = /* @__PURE__ */ new Set();
36
- const lazyStates = /* @__PURE__ */ new WeakMap();
37
- const handlerLazyComponents = /* @__PURE__ */ new WeakMap();
38
- function startLazyLoad(state) {
39
- if (state.promise) return state.promise;
40
- let promise;
41
- promise = Promise.resolve().then(state.factory).then((mod) => {
42
- state.resolved = typeof mod === "function" ? mod : mod.default;
43
- state.loadError = null;
44
- state.hasLoadError = false;
45
- }, (err) => {
46
- state.loadError = err;
47
- state.hasLoadError = true;
48
- }).finally(() => {
49
- if (state.hasLoadError) state.promise = null;
50
- pendingLazy.delete(promise);
51
- });
52
- state.promise = promise;
53
- pendingLazy.add(promise);
54
- return promise;
55
- }
56
- /** Wrap a dynamic-import factory as a {@link LazyRouteComponent}, loaded on first use. */
57
- function lazy(factory) {
58
- const state = {
59
- factory,
60
- promise: null,
61
- resolved: null,
62
- loadError: null,
63
- hasLoadError: false
64
- };
65
- const component = ((params) => {
66
- if (state.hasLoadError) throw state.loadError;
67
- if (!state.resolved) throw new Error("lazy() component used before it was resolved. Matched routes load automatically; call component.preload() for explicit preloading.");
68
- return state.resolved(params);
69
- });
70
- Object.defineProperty(component, "preload", { value: () => startLazyLoad(state) });
71
- lazyStates.set(component, state);
72
- return component;
73
- }
74
- /**
75
- * Create a cached route loader backed by a dynamic import. The module is only
76
- * requested when the owning route matches, unless preload() is called.
77
- */
78
- function lazyRouteData(factory, select) {
79
- let imported = null;
80
- const load = () => {
81
- if (imported) return imported;
82
- imported = Promise.resolve().then(factory).catch((error) => {
83
- imported = null;
84
- throw error;
85
- });
86
- return imported;
87
- };
88
- const loader = ((context) => load().then((module) => select ? select(module, context) : module).catch((error) => _wrapRouteDataLoadError(error, context)));
89
- Object.defineProperty(loader, "preload", { value: () => load().then(() => void 0) });
90
- return loader;
91
- }
92
- function _preloadRouteRecord(record) {
93
- const imports = [
94
- record.component,
95
- ...record.pageChain.map((scope) => scope.component),
96
- ...record.layoutChain.map((scope) => scope.component)
97
- ].flatMap((component) => {
98
- const state = lazyStates.get(component);
99
- return state ? [startLazyLoad(state)] : [];
100
- });
101
- return imports.length > 0 ? Promise.all(imports).then(() => void 0) : null;
102
- }
103
- function _associateLazyHandler(handler, components) {
104
- handlerLazyComponents.set(handler, components);
105
- }
106
- function _preloadRouteHandler(handler) {
107
- const imports = (handlerLazyComponents.get(handler) ?? []).flatMap((component) => {
108
- const state = lazyStates.get(component);
109
- return state ? [startLazyLoad(state)] : [];
110
- });
111
- return imports.length > 0 ? Promise.all(imports).then(() => void 0) : null;
112
- }
113
- //#endregion
114
- //#region src/router/rendering.ts
115
- const outletScope = defineScope(null);
116
- /** Renders the nested route content for the enclosing layout or page scope. */
117
- function Outlet() {
118
- return {
119
- $$typeof: ELEMENT_TYPE,
120
- type: Fragment,
121
- props: { children: readScope(outletScope) },
122
- key: null
123
- };
124
- }
125
- function applyPageChain(pageChain, params, content, deferComponents = false) {
126
- let nextContent = content;
127
- for (let i = pageChain.length - 1; i >= 0; i--) nextContent = outletScope({
128
- value: nextContent,
129
- children: deferComponents ? createRouteComponentVNode(pageChain[i].component, params) : pageChain[i].component(params)
130
- });
131
- return nextContent;
132
- }
133
- function createRouteComponentVNode(component, params, routeRoot = false) {
134
- return {
135
- $$typeof: ELEMENT_TYPE,
136
- type: component,
137
- props: params,
138
- key: null,
139
- ...routeRoot ? { [ROUTE_ROOT_COMPONENT]: true } : {}
140
- };
141
- }
142
- function createRouteHandler(component, pageChain, layoutChain, deferComponents = false) {
143
- const handler = (params) => {
144
- let content = deferComponents ? createRouteComponentVNode(component, params, true) : component(params);
145
- content = applyPageChain(pageChain, params, content, deferComponents);
146
- for (let i = layoutChain.length - 1; i >= 0; i--) {
147
- const layout = layoutChain[i].component;
148
- content = layout({ children: content });
149
- }
150
- return content;
151
- };
152
- _associateLazyHandler(handler, [
153
- component,
154
- ...pageChain.map((scope) => scope.component),
155
- ...layoutChain.map((scope) => scope.component)
156
- ]);
157
- return handler;
158
- }
159
- function getRenderHandler(record) {
160
- return record.renderHandler ?? createRouteHandler(record.component, record.pageChain, record.layoutChain, true);
161
- }
162
- //#endregion
163
- //#region src/router/auth.ts
164
- let clientAuth = Object.freeze({
165
- authenticated: false,
166
- principal: null,
167
- session: null,
168
- tenant: null
169
- });
170
- /** Return the identity resolved for the route currently being rendered. */
171
- function currentAuth() {
172
- return getActiveRenderContext()?.authContext ?? clientAuth;
173
- }
174
- /** @internal Updated atomically with route resolution. */
175
- function setCurrentAuth(context) {
176
- clientAuth = context;
177
- const render = getActiveRenderContext();
178
- if (render) render.authContext = context;
179
- }
180
- //#endregion
4
+ import { t as ROUTE_ROOT_COMPONENT } from "./router-internal-7nuNEHfG.js";
5
+ import { c as withTelemetry, t as createQueryPrefetchContext } from "./query-registry-LrYpQsDJ.js";
6
+ import { c as removeRouteBasePath, i as getMatchingRouteRecord, l as buildRouteContext, o as addRouteBasePath, s as normalizeRouteBasePath, u as buildRouteContextBase, y as getActiveRouteAuthOptions } from "./route-matching-CUzZ31gT.js";
181
7
  //#region src/common/deferred-value.ts
182
8
  const DEFERRED_VALUE = Symbol.for("@askrjs/askr/deferred-value");
183
9
  const DEFERRED_BOUNDARY = Symbol.for("@askrjs/askr/deferred-boundary");
@@ -386,6 +212,177 @@ function withoutRouteHydrationMetadata(framework) {
386
212
  return next;
387
213
  }
388
214
  //#endregion
215
+ //#region src/router/route-data-loader.ts
216
+ /** Thrown when a route's `loader` rejects; wraps the original `cause`. */
217
+ var RouteDataLoadError = class extends Error {
218
+ constructor(route, phase, cause) {
219
+ const detail = cause instanceof Error ? cause.message : String(cause);
220
+ super("[Askr] Route data loader failed for \"" + route + "\" during " + phase + " loading: " + detail);
221
+ this.name = "RouteDataLoadError";
222
+ this.route = route;
223
+ this.phase = phase;
224
+ this.cause = cause;
225
+ }
226
+ };
227
+ function isAbortError(error) {
228
+ return typeof error === "object" && error !== null && "name" in error && error.name === "AbortError";
229
+ }
230
+ function loadPhase(mode) {
231
+ if (mode === "spa") return "client";
232
+ if (mode === "ssg") return "ssg";
233
+ return "server";
234
+ }
235
+ /** @internal Add route context to failures from lazyRouteData(). */
236
+ function _wrapRouteDataLoadError(error, context) {
237
+ if (error instanceof RouteDataLoadError || isAbortError(error)) throw error;
238
+ throw new RouteDataLoadError(context.href || context.pathname, loadPhase(context.mode), error);
239
+ }
240
+ //#endregion
241
+ //#region src/router/lazy.ts
242
+ const pendingLazy = /* @__PURE__ */ new Set();
243
+ const lazyStates = /* @__PURE__ */ new WeakMap();
244
+ const handlerLazyComponents = /* @__PURE__ */ new WeakMap();
245
+ function startLazyLoad(state) {
246
+ if (state.promise) return state.promise;
247
+ let promise;
248
+ promise = Promise.resolve().then(state.factory).then((mod) => {
249
+ state.resolved = typeof mod === "function" ? mod : mod.default;
250
+ state.loadError = null;
251
+ state.hasLoadError = false;
252
+ }, (err) => {
253
+ state.loadError = err;
254
+ state.hasLoadError = true;
255
+ }).finally(() => {
256
+ if (state.hasLoadError) state.promise = null;
257
+ pendingLazy.delete(promise);
258
+ });
259
+ state.promise = promise;
260
+ pendingLazy.add(promise);
261
+ return promise;
262
+ }
263
+ /** Wrap a dynamic-import factory as a {@link LazyRouteComponent}, loaded on first use. */
264
+ function lazy(factory) {
265
+ const state = {
266
+ factory,
267
+ promise: null,
268
+ resolved: null,
269
+ loadError: null,
270
+ hasLoadError: false
271
+ };
272
+ const component = ((params) => {
273
+ if (state.hasLoadError) throw state.loadError;
274
+ if (!state.resolved) throw new Error("lazy() component used before it was resolved. Matched routes load automatically; call component.preload() for explicit preloading.");
275
+ return state.resolved(params);
276
+ });
277
+ Object.defineProperty(component, "preload", { value: () => startLazyLoad(state) });
278
+ lazyStates.set(component, state);
279
+ return component;
280
+ }
281
+ /**
282
+ * Create a cached route loader backed by a dynamic import. The module is only
283
+ * requested when the owning route matches, unless preload() is called.
284
+ */
285
+ function lazyRouteData(factory, select) {
286
+ let imported = null;
287
+ const load = () => {
288
+ if (imported) return imported;
289
+ imported = Promise.resolve().then(factory).catch((error) => {
290
+ imported = null;
291
+ throw error;
292
+ });
293
+ return imported;
294
+ };
295
+ const loader = ((context) => load().then((module) => select ? select(module, context) : module).catch((error) => _wrapRouteDataLoadError(error, context)));
296
+ Object.defineProperty(loader, "preload", { value: () => load().then(() => void 0) });
297
+ return loader;
298
+ }
299
+ function _preloadRouteRecord(record) {
300
+ const imports = [
301
+ record.component,
302
+ ...record.pageChain.map((scope) => scope.component),
303
+ ...record.layoutChain.map((scope) => scope.component)
304
+ ].flatMap((component) => {
305
+ const state = lazyStates.get(component);
306
+ return state ? [startLazyLoad(state)] : [];
307
+ });
308
+ return imports.length > 0 ? Promise.all(imports).then(() => void 0) : null;
309
+ }
310
+ function _associateLazyHandler(handler, components) {
311
+ handlerLazyComponents.set(handler, components);
312
+ }
313
+ function _preloadRouteHandler(handler) {
314
+ const imports = (handlerLazyComponents.get(handler) ?? []).flatMap((component) => {
315
+ const state = lazyStates.get(component);
316
+ return state ? [startLazyLoad(state)] : [];
317
+ });
318
+ return imports.length > 0 ? Promise.all(imports).then(() => void 0) : null;
319
+ }
320
+ //#endregion
321
+ //#region src/router/rendering.ts
322
+ const outletScope = defineScope(null);
323
+ /** Renders the nested route content for the enclosing layout or page scope. */
324
+ function Outlet() {
325
+ return {
326
+ $$typeof: ELEMENT_TYPE,
327
+ type: Fragment,
328
+ props: { children: readScope(outletScope) },
329
+ key: null
330
+ };
331
+ }
332
+ function applyPageChain(pageChain, params, content, deferComponents = false) {
333
+ let nextContent = content;
334
+ for (let i = pageChain.length - 1; i >= 0; i--) nextContent = outletScope({
335
+ value: nextContent,
336
+ children: deferComponents ? createRouteComponentVNode(pageChain[i].component, params) : pageChain[i].component(params)
337
+ });
338
+ return nextContent;
339
+ }
340
+ function createRouteComponentVNode(component, params, routeRoot = false) {
341
+ return {
342
+ $$typeof: ELEMENT_TYPE,
343
+ type: component,
344
+ props: params,
345
+ key: null,
346
+ ...routeRoot ? { [ROUTE_ROOT_COMPONENT]: true } : {}
347
+ };
348
+ }
349
+ function createRouteHandler(component, pageChain, layoutChain, deferComponents = false) {
350
+ const handler = (params) => {
351
+ let content = deferComponents ? createRouteComponentVNode(component, params, true) : component(params);
352
+ content = applyPageChain(pageChain, params, content, deferComponents);
353
+ for (let i = layoutChain.length - 1; i >= 0; i--) {
354
+ const layout = layoutChain[i].component;
355
+ content = layout({ children: content });
356
+ }
357
+ return content;
358
+ };
359
+ _associateLazyHandler(handler, [
360
+ component,
361
+ ...pageChain.map((scope) => scope.component),
362
+ ...layoutChain.map((scope) => scope.component)
363
+ ]);
364
+ return handler;
365
+ }
366
+ function getRenderHandler(record) {
367
+ return record.renderHandler ?? createRouteHandler(record.component, record.pageChain, record.layoutChain, true);
368
+ }
369
+ let clientAuth = Object.freeze({
370
+ authenticated: false,
371
+ principal: null,
372
+ session: null,
373
+ tenant: null
374
+ });
375
+ /** Return the identity resolved for the route currently being rendered. */
376
+ function currentAuth() {
377
+ return getActiveRenderContext()?.authContext ?? clientAuth;
378
+ }
379
+ /** @internal Updated atomically with route resolution. */
380
+ function setCurrentAuth(context) {
381
+ clientAuth = context;
382
+ const render = getActiveRenderContext();
383
+ if (render) render.authContext = context;
384
+ }
385
+ //#endregion
389
386
  //#region src/router/resolution.ts
390
387
  const anonymous = () => ({
391
388
  authenticated: false,
@@ -401,6 +398,10 @@ function getRouteRenderContext(result) {
401
398
  function getRouteRenderData(result) {
402
399
  return routeRenderData.get(result);
403
400
  }
401
+ /** Router-owned inspection of the record selected by request resolution. */
402
+ function resolvedRouteHasLoader(result) {
403
+ return typeof result.record?.options?.loader === "function";
404
+ }
404
405
  function createRouteRenderResult(record, params, context, handler) {
405
406
  const result = {
406
407
  kind: "render",
@@ -527,6 +528,14 @@ function resolveMatchedRoute(record, params, context, authOptions, request, tele
527
528
  const decision = record.options.auth(context.auth);
528
529
  return isPromiseLike(decision) ? Promise.resolve(decision).then(continueResolution) : continueResolution(decision);
529
530
  }
531
+ /**
532
+ * Callers may omit `signal`, and `RouteRequestOptions.signal` is optional in the
533
+ * published contract. Route context still needs an `AbortSignal`, so this stands
534
+ * in for "this caller supplied no cancellation". It never aborts: a route loader
535
+ * receiving it cannot be cancelled through `context.signal`. Prefer passing a
536
+ * real signal.
537
+ */
538
+ const NEVER_ABORTED = new AbortController().signal;
530
539
  /** Resolve `target` against a route registry, applying auth/policies to produce a render/redirect/deny result. */
531
540
  function resolveRouteRequest(target, options) {
532
541
  if (!options?.registry) throw new TypeError("resolveRouteRequest requires options.registry.");
@@ -538,7 +547,7 @@ function resolveRouteRequest(target, options) {
538
547
  const match = getMatchingRouteRecord(logicalTarget, records);
539
548
  if (!match) return null;
540
549
  const mode = options.mode ?? getDefaultRouteMode();
541
- const signal = options.signal ?? getActiveRenderContext()?.signal ?? new AbortController().signal;
550
+ const signal = options.signal ?? getActiveRenderContext()?.signal ?? NEVER_ABORTED;
542
551
  const authOptions = getActiveRouteAuthOptions(options.auth ?? options.registry.manifest.auth);
543
552
  const base = buildRouteContextBase(logicalTarget, match.params, {
544
553
  mode,
@@ -565,4 +574,4 @@ function resolveRouteRequest(target, options) {
565
574
  });
566
575
  }
567
576
  //#endregion
568
- export { RouteDataLoadError as S, createRouteHandler as _, resolveRouteRequest as a, lazy as b, prepareRouteHydrationData as c, DEFERRED_BOUNDARY as d, defer as f, Outlet as g, currentAuth as h, hasRouteRenderData as i, validateRouteHydrationData as l, reviveDeferredValue as m, getRouteRenderContext as n, getRouteHydrationMetadata as o, isDeferred as p, getRouteRenderData as r, guardHydratedRouteData as s, bindResolvedRouteData as t, withoutRouteHydrationMetadata as u, getRenderHandler as v, lazyRouteData as x, _preloadRouteHandler as y };
577
+ export { reviveDeferredValue as C, isDeferred as S, prepareRouteHydrationData as _, resolveRouteRequest as a, DEFERRED_BOUNDARY as b, Outlet as c, _preloadRouteHandler as d, lazy as f, guardHydratedRouteData as g, getRouteHydrationMetadata as h, hasRouteRenderData as i, createRouteHandler as l, RouteDataLoadError as m, getRouteRenderContext as n, resolvedRouteHasLoader as o, lazyRouteData as p, getRouteRenderData as r, currentAuth as s, bindResolvedRouteData as t, getRenderHandler as u, validateRouteHydrationData as v, defer as x, withoutRouteHydrationMetadata as y };
@@ -1,11 +1,10 @@
1
- import { t as enqueueRuntimeLane, y as logger } from "./access-Rr7CMa06.js";
2
- import { f as getCurrentComponentInstance } from "./component-scope-4I3yEMkb.js";
3
- import { m as getCurrentContextFrame, u as registerCommitOperationForInstance, x as withAsyncResourceContext } from "./component-internal-Dl02WQKS.js";
4
- import { p as isPromiseLike } from "./lifecycle-batch-Be-CLDjV.js";
5
- import { t as brandSnapshotSource } from "./snapshot-source-BB42xgwb.js";
1
+ import { t as enqueueRuntimeLane, v as logger } from "./access-CEA2pOry.js";
2
+ import { P as isPromiseLike, d as registerCommitOperationForInstance, h as getCurrentContextFrame, y as withAsyncResourceContext } from "./instance-VAFYVJOa.js";
3
+ import { O as ownCleanup, f as getCurrentComponentInstance } from "./scope-Cq_iYbTR.js";
4
+ import { t as brandSnapshotSource } from "./snapshot-source-An4iKajG.js";
6
5
  import { C as SSRDataMissingError, a as getResourceVerificationSnapshot, i as getNextRenderKey, n as getActiveRenderContext, o as isHydrationVerificationRender, p as throwSSRDataMissing, r as getCurrentRenderData, s as recordResourceVerificationSnapshot } from "./render-context-B7ohlh6t.js";
7
- import { t as state } from "./state-BzhOW2TX.js";
8
- //#region src/runtime/resource-cell.ts
6
+ import { t as state } from "./state-BXJfudq1.js";
7
+ //#region src/runtime/lifecycle/resource-cell.ts
9
8
  /**
10
9
  * Pure, component-agnostic ResourceCell state machine.
11
10
  * - Holds value/pending/error/generation/controller
@@ -45,59 +44,82 @@ var ResourceCell = class {
45
44
  this.snapshot.value = this.value;
46
45
  this.snapshot.pending = this.pending;
47
46
  this.snapshot.error = this.error;
48
- for (const cb of this.subscribers) cb();
47
+ for (const cb of this.subscribers) try {
48
+ cb();
49
+ } catch (error) {
50
+ this.reportError(error, "Resource subscriber error");
51
+ }
52
+ }
53
+ reportError(error, label = "Async resource error") {
54
+ try {
55
+ logger.error(`[Askr] ${label}${this.ownerName ? ` in ${this.ownerName}` : ""}:`, error);
56
+ } catch {}
49
57
  }
50
58
  start(ssr = false, notify = true) {
51
59
  if (this.disposed) return;
52
60
  const generation = this.generation;
53
- this.controller?.abort();
61
+ const previous = this.controller;
54
62
  const controller = new AbortController();
55
63
  this.controller = controller;
64
+ const current = () => this.generation === generation && this.controller === controller && !controller.signal.aborted;
65
+ previous?.abort();
66
+ if (!current()) return;
56
67
  this.pending = true;
57
68
  this.error = null;
58
69
  if (notify) this.notifySubscribers();
70
+ if (!current()) return;
71
+ const fail = (reason, asynchronous = false) => {
72
+ if (!current()) return;
73
+ let error;
74
+ try {
75
+ if (asynchronous && (reason instanceof Error && reason.name === "AbortError" || typeof DOMException !== "undefined" && reason instanceof DOMException && reason.name === "AbortError")) return;
76
+ error = reason instanceof Error ? reason : new Error(String(reason));
77
+ } catch {
78
+ error = /* @__PURE__ */ new Error("Resource error normalization failed");
79
+ }
80
+ if (!current()) return;
81
+ this.pending = false;
82
+ this.error = error;
83
+ if (asynchronous) this.reportError(reason);
84
+ if (current() && (notify || asynchronous)) this.notifySubscribers();
85
+ };
59
86
  let result;
87
+ let asynchronous;
60
88
  try {
61
89
  result = withAsyncResourceContext(this.resourceFrame, () => this.fn({ signal: controller.signal }));
90
+ asynchronous = isPromiseLike(result);
62
91
  } catch (err) {
63
- this.pending = false;
64
- this.error = err instanceof Error ? err : new Error(String(err));
65
- if (notify) this.notifySubscribers();
92
+ fail(err);
66
93
  return;
67
94
  }
68
- if (!isPromiseLike(result)) {
95
+ if (!asynchronous) {
96
+ if (!current()) return;
69
97
  this.value = result;
70
98
  this.pending = false;
71
99
  this.error = null;
72
100
  if (notify) this.notifySubscribers();
73
101
  return;
74
102
  }
75
- if (ssr) throwSSRDataMissing();
76
- Promise.resolve(result).then((val) => {
77
- if (this.generation !== generation) return;
78
- if (this.controller !== controller) return;
79
- if (controller.signal.aborted) return;
80
- this.value = val;
81
- this.pending = false;
82
- this.error = null;
83
- this.notifySubscribers();
84
- }).catch((err) => {
85
- if (this.generation !== generation) return;
86
- if (this.controller !== controller) return;
87
- if (controller.signal.aborted || err instanceof Error && err.name === "AbortError" || typeof DOMException !== "undefined" && err instanceof DOMException && err.name === "AbortError") return;
88
- this.pending = false;
89
- this.error = err instanceof Error ? err : new Error(String(err));
90
- try {
91
- if (this.ownerName) logger.error(`[Askr] Async resource error in ${this.ownerName}:`, err);
92
- else logger.error("[Askr] Async resource error:", err);
93
- } catch {}
94
- this.notifySubscribers();
95
- });
103
+ if (ssr) {
104
+ new Promise((resolve) => resolve(result)).then(void 0, () => {});
105
+ controller.abort();
106
+ throwSSRDataMissing();
107
+ }
108
+ try {
109
+ Promise.resolve(result).then((val) => {
110
+ if (!current()) return;
111
+ this.value = val;
112
+ this.pending = false;
113
+ this.error = null;
114
+ this.notifySubscribers();
115
+ }, (err) => fail(err, true));
116
+ } catch (err) {
117
+ fail(err);
118
+ }
96
119
  }
97
120
  refresh() {
98
121
  if (this.disposed) return;
99
122
  this.generation++;
100
- this.controller?.abort();
101
123
  this.start();
102
124
  }
103
125
  abort() {
@@ -111,7 +133,7 @@ var ResourceCell = class {
111
133
  }
112
134
  };
113
135
  //#endregion
114
- //#region src/runtime/resource-operation.ts
136
+ //#region src/runtime/lifecycle/resource.ts
115
137
  function hydrationVerificationSnapshot() {
116
138
  return brandSnapshotSource({
117
139
  value: null,
@@ -121,6 +143,42 @@ function hydrationVerificationSnapshot() {
121
143
  });
122
144
  }
123
145
  /**
146
+ * What resource data, if any, the current render was given.
147
+ *
148
+ * Both the outside-a-component path and the in-component path asked this
149
+ * question, each spelling out the same two-part test by hand. One answer keeps
150
+ * the "is this a hydrating render with preloaded values" decision from drifting
151
+ * between them.
152
+ */
153
+ function resolveResourceRenderData() {
154
+ const renderData = getCurrentRenderData()?.resources;
155
+ return {
156
+ renderData,
157
+ hasPreloadedData: Boolean(renderData && (getActiveRenderContext()?.resourceDataProvided || Object.keys(renderData).some((key) => key.startsWith("r:"))))
158
+ };
159
+ }
160
+ /**
161
+ * Resolve a resource declared outside any component instance.
162
+ *
163
+ * Only legitimate during a synchronous SSR render that already carries resolved
164
+ * data; every other caller is creating a resource where it cannot be owned.
165
+ */
166
+ function resolveResourceWithoutInstance() {
167
+ const { renderData, hasPreloadedData } = resolveResourceRenderData();
168
+ if (renderData && hasPreloadedData) {
169
+ const key = getNextRenderKey();
170
+ if (!(key in renderData)) throwSSRDataMissing();
171
+ return brandSnapshotSource({
172
+ value: renderData[key],
173
+ pending: false,
174
+ error: null,
175
+ refresh: () => {}
176
+ });
177
+ }
178
+ if (getActiveRenderContext()) throwSSRDataMissing();
179
+ throw new Error("[Askr] resource() must be called during component render inside an app. Do not create resources at module scope or outside render.");
180
+ }
181
+ /**
124
182
  * Resource primitive — simple, deterministic async primitive
125
183
  * Usage: resource(fn, deps)
126
184
  * - fn receives { signal }
@@ -133,24 +191,8 @@ function hydrationVerificationSnapshot() {
133
191
  function resource(fn, deps = []) {
134
192
  const instance = getCurrentComponentInstance();
135
193
  const inst = instance;
136
- if (!instance) {
137
- const renderData = getCurrentRenderData()?.resources;
138
- if (renderData && (getActiveRenderContext()?.resourceDataProvided || Object.keys(renderData).some((key) => key.startsWith("r:")))) {
139
- const key = getNextRenderKey();
140
- if (!(key in renderData)) throwSSRDataMissing();
141
- const val = renderData[key];
142
- return brandSnapshotSource({
143
- value: val,
144
- pending: false,
145
- error: null,
146
- refresh: () => {}
147
- });
148
- }
149
- if (getActiveRenderContext()) throwSSRDataMissing();
150
- throw new Error("[Askr] resource() must be called during component render inside an app. Do not create resources at module scope or outside render.");
151
- }
152
- const renderData = getCurrentRenderData()?.resources;
153
- const hasPreloadedResourceData = Boolean(renderData && (getActiveRenderContext()?.resourceDataProvided || Object.keys(renderData).some((key) => key.startsWith("r:"))));
194
+ if (!instance) return resolveResourceWithoutInstance();
195
+ const { renderData, hasPreloadedData: hasPreloadedResourceData } = resolveResourceRenderData();
154
196
  const renderKey = inst.ssr || hasPreloadedResourceData ? getNextRenderKey() : null;
155
197
  const verificationSnapshot = renderKey ? getResourceVerificationSnapshot(renderKey) : null;
156
198
  if (renderData && hasPreloadedResourceData && renderKey && renderKey in renderData) {
@@ -209,10 +251,8 @@ function resource(fn, deps = []) {
209
251
  inst.notifyUpdate?.();
210
252
  } catch {}
211
253
  });
212
- (inst.cleanupFns ??= []).push(() => {
213
- unsubscribe();
214
- cell.dispose();
215
- });
254
+ ownCleanup(inst.owner, unsubscribe);
255
+ ownCleanup(inst.owner, () => cell.dispose());
216
256
  if (inst.ssr) {
217
257
  cell.start(true, false);
218
258
  if (!cell.pending) {