@askrjs/askr 0.0.84 → 0.0.86

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 (71) hide show
  1. package/dist/{access-ePqdQqkV.js → access-Dpfoi4cA.js} +7 -1
  2. package/dist/actions/index.d.ts +1 -1
  3. package/dist/actions/index.js +3 -3
  4. package/dist/{activity-pySy9t7Y.d.ts → activity-B1I5HJQI.d.ts} +1 -1
  5. package/dist/{activity-CZiPgZy0.js → activity-BvgvaMZA.js} +53 -16
  6. package/dist/benchmark.js +8 -8
  7. package/dist/boot/index.d.ts +3 -3
  8. package/dist/boot/index.js +1 -1
  9. package/dist/{boot-D28lesMw.js → boot-CViTpUiB.js} +22 -20
  10. package/dist/{cleanup-ARiXproi.js → cleanup-c837KVij.js} +16 -6
  11. package/dist/{component-cleanup-Bug5tSiG.js → component-cleanup-BUfUleGZ.js} +2 -2
  12. package/dist/{component-internal-Bw4Mf9fd.js → component-internal-DcrLymUJ.js} +5 -5
  13. package/dist/components/index.d.ts +1 -1
  14. package/dist/components/index.js +1 -1
  15. package/dist/control/index.d.ts +1 -1
  16. package/dist/control/index.js +1 -1
  17. package/dist/{control-Y8F73Uln.d.ts → control-DhUZU4_V.d.ts} +2 -1
  18. package/dist/{control-nrS65oG3.js → control-oLADku43.js} +4 -4
  19. package/dist/{csp-nonce-ZTlD_EnK.js → csp-nonce-Bc52OIVc.js} +19 -2
  20. package/dist/data/index.js +3 -3
  21. package/dist/{data-BRS5woEh.js → data-DGrD3-qA.js} +5 -5
  22. package/dist/{data-runtime-D68YOo9L.js → data-runtime-Ck3tJDDQ.js} +1 -1
  23. package/dist/default-portal-runtime-DvMvWJVp.js +20 -0
  24. package/dist/{authoring-DQPG0VAm.js → deferred-nleQtdfY.js} +85 -5
  25. package/dist/{effect-B487asyz.js → effect-lnxQIpJG.js} +2 -2
  26. package/dist/{fastlane-BOr4lSLl.js → fastlane-CrfB3QG0.js} +2 -2
  27. package/dist/{for-internal-DjpV8ioj.js → for-internal-B_mnQhan.js} +18 -6
  28. package/dist/foundations/index.d.ts +1 -1
  29. package/dist/foundations/index.js +1 -2
  30. package/dist/foundations/state/index.d.ts +1 -1
  31. package/dist/foundations/state/index.js +1 -1
  32. package/dist/foundations/structures/index.d.ts +2 -2
  33. package/dist/foundations/structures/index.js +2 -3
  34. package/dist/fx/index.js +1 -1
  35. package/dist/{index-BApH3laU.d.ts → index-DflhL1h8.d.ts} +20 -16
  36. package/dist/{index-_UN08Pg1.d.ts → index-pIgGaXvS.d.ts} +19 -3
  37. package/dist/{index-DUXXZ31H.d.ts → index-r-nt13FE.d.ts} +1 -1
  38. package/dist/index.d.ts +3 -3
  39. package/dist/index.js +12 -12
  40. package/dist/{lifecycle-batch-CFI4NKpJ.js → lifecycle-batch-Dfpid9-A.js} +39 -20
  41. package/dist/{lifecycle-operations-KYOIcM5R.js → lifecycle-operations-BrYrBsXY.js} +1 -1
  42. package/dist/manifest-D1P9uTlz.js +53 -0
  43. package/dist/{navigate-Dr3cjOSz.js → navigate-BwAPbpCb.js} +17 -16
  44. package/dist/{navigate-CgVIrrSs.d.ts → navigate-NyIjQUwI.d.ts} +1 -1
  45. package/dist/{query-registry-BL6rjGsO.js → query-registry-CPW_6nwF.js} +1 -1
  46. package/dist/{readable-_GQGe_St.js → readable-B5NtV7V0.js} +1 -1
  47. package/dist/render-context-D0Hoj9dW.js +161 -0
  48. package/dist/{renderer-B9j5IV1q.js → renderer-D9DL9R2D.js} +58 -17
  49. package/dist/{deferred-oqtAJ4iH.js → resolution-YHwi4Bav.js} +234 -222
  50. package/dist/resource-operation-ys6eDoRJ.js +304 -0
  51. package/dist/resources/index.d.ts +2 -2
  52. package/dist/resources/index.js +5 -5
  53. package/dist/{route-matching-IfQZmqkN.js → route-matching-DqULzZtC.js} +46 -277
  54. package/dist/router/index.d.ts +12 -10
  55. package/dist/router/index.js +10 -7
  56. package/dist/{selector-DJ1-N1K-.js → selector-Ck_Pp9av.js} +2 -2
  57. package/dist/ssg/index.d.ts +9 -3
  58. package/dist/ssg/index.js +31 -15
  59. package/dist/ssr/index.d.ts +7 -3
  60. package/dist/ssr/index.js +2 -2
  61. package/dist/{ssr-CtC4lChT.js → ssr-B98593qJ.js} +53 -27
  62. package/dist/ssr-DSHd_Q9K.js +25 -0
  63. package/dist/{state-BzIMC6-i.js → state-DCjONcHK.js} +4 -3
  64. package/dist/{portal-pHBoqwYd.js → structures-DsOm-clq.js} +236 -7
  65. package/dist/testing/index.d.ts +2 -2
  66. package/dist/testing/index.js +4 -4
  67. package/dist/{verify-hydration-BguOSco9.js → verify-hydration-ww1dgwea.js} +5 -4
  68. package/package.json +2 -2
  69. package/dist/render-context-D-DFk2WN.js +0 -73
  70. package/dist/ssr-CbQO5xd3.js +0 -12
  71. package/dist/structures-D3vO-WMN.js +0 -221
@@ -1,278 +1,4 @@
1
- import { t as enqueueRuntimeLane, v as logger } from "./access-ePqdQqkV.js";
2
- import { c as registerCommitOperationForInstance, d as getCurrentContextFrame, v as withAsyncResourceContext } from "./component-internal-Bw4Mf9fd.js";
3
- import { f as getCurrentComponentInstance } from "./component-scope-DzJEbYGE.js";
4
- import { p as isPromiseLike } from "./lifecycle-batch-CFI4NKpJ.js";
5
- import { t as brandSnapshotSource } from "./snapshot-source-BB42xgwb.js";
6
- import { d as SSRDataMissingError, i as getNextRenderKey, n as getActiveRenderContext, r as getCurrentRenderData, u as throwSSRDataMissing } from "./render-context-D-DFk2WN.js";
7
- import { t as state } from "./state-BzIMC6-i.js";
8
- //#region src/runtime/resource-cell.ts
9
- /**
10
- * Pure, component-agnostic ResourceCell state machine.
11
- * - Holds value/pending/error/generation/controller
12
- * - Exposes a stable `snapshot` object: { value, pending, error, refresh }
13
- * - Uses `withAsyncResourceContext` to bind the synchronous execution step
14
- * to a captured frame. Continuations after await do not see the frame.
15
- */
16
- var ResourceCell = class {
17
- constructor(fn, deps, resourceFrame) {
18
- this.value = null;
19
- this.pending = true;
20
- this.error = null;
21
- this.generation = 0;
22
- this.controller = null;
23
- this.deps = null;
24
- this.resourceFrame = null;
25
- this.subscribers = /* @__PURE__ */ new Set();
26
- this.disposed = false;
27
- this.fn = fn;
28
- this.deps = deps ? deps.slice() : null;
29
- this.resourceFrame = resourceFrame;
30
- this.snapshot = brandSnapshotSource({
31
- value: null,
32
- pending: true,
33
- error: null,
34
- refresh: () => this.refresh()
35
- });
36
- }
37
- setLoader(fn) {
38
- this.fn = fn;
39
- }
40
- subscribe(cb) {
41
- this.subscribers.add(cb);
42
- return () => this.subscribers.delete(cb);
43
- }
44
- notifySubscribers() {
45
- this.snapshot.value = this.value;
46
- this.snapshot.pending = this.pending;
47
- this.snapshot.error = this.error;
48
- for (const cb of this.subscribers) cb();
49
- }
50
- start(ssr = false, notify = true) {
51
- if (this.disposed) return;
52
- const generation = this.generation;
53
- this.controller?.abort();
54
- const controller = new AbortController();
55
- this.controller = controller;
56
- this.pending = true;
57
- this.error = null;
58
- if (notify) this.notifySubscribers();
59
- let result;
60
- try {
61
- result = withAsyncResourceContext(this.resourceFrame, () => this.fn({ signal: controller.signal }));
62
- } catch (err) {
63
- this.pending = false;
64
- this.error = err instanceof Error ? err : new Error(String(err));
65
- if (notify) this.notifySubscribers();
66
- return;
67
- }
68
- if (!isPromiseLike(result)) {
69
- this.value = result;
70
- this.pending = false;
71
- this.error = null;
72
- if (notify) this.notifySubscribers();
73
- return;
74
- }
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
- });
96
- }
97
- refresh() {
98
- if (this.disposed) return;
99
- this.generation++;
100
- this.controller?.abort();
101
- this.start();
102
- }
103
- abort() {
104
- this.controller?.abort();
105
- }
106
- dispose() {
107
- if (this.disposed) return;
108
- this.disposed = true;
109
- this.controller?.abort();
110
- this.subscribers.clear();
111
- }
112
- };
113
- //#endregion
114
- //#region src/runtime/resource-operation.ts
115
- /**
116
- * Resource primitive — simple, deterministic async primitive
117
- * Usage: resource(fn, deps)
118
- * - fn receives { signal }
119
- * - captures execution context once at creation (synchronous step only)
120
- * - executes at most once per generation; stale async results are ignored
121
- * - refresh() cancels in-flight execution, increments generation and re-runs
122
- * - exposes { value, pending, error, refresh }
123
- * - during SSR, async results are disallowed and will throw synchronously
124
- */
125
- function resource(fn, deps = []) {
126
- const instance = getCurrentComponentInstance();
127
- const inst = instance;
128
- if (!instance) {
129
- const renderData = getCurrentRenderData()?.resources;
130
- if (renderData && (getActiveRenderContext()?.resourceDataProvided || Object.keys(renderData).some((key) => key.startsWith("r:")))) {
131
- const key = getNextRenderKey();
132
- if (!(key in renderData)) throwSSRDataMissing();
133
- const val = renderData[key];
134
- return brandSnapshotSource({
135
- value: val,
136
- pending: false,
137
- error: null,
138
- refresh: () => {}
139
- });
140
- }
141
- if (getActiveRenderContext()) throwSSRDataMissing();
142
- throw new Error("[Askr] resource() must be called during component render inside an app. Do not create resources at module scope or outside render.");
143
- }
144
- const renderData = getCurrentRenderData()?.resources;
145
- if (renderData && (getActiveRenderContext()?.resourceDataProvided || Object.keys(renderData).some((key) => key.startsWith("r:")))) {
146
- const key = getNextRenderKey();
147
- if (!(key in renderData)) throwSSRDataMissing();
148
- const val = renderData[key];
149
- const h = state({
150
- cell: void 0,
151
- snapshot: brandSnapshotSource({
152
- value: val,
153
- pending: false,
154
- error: null,
155
- refresh: () => {}
156
- })
157
- })();
158
- h.snapshot.value = val;
159
- h.snapshot.pending = false;
160
- h.snapshot.error = null;
161
- return h.snapshot;
162
- }
163
- const holder = state({
164
- cell: void 0,
165
- snapshot: brandSnapshotSource({
166
- value: null,
167
- pending: true,
168
- error: null,
169
- refresh: () => {}
170
- })
171
- });
172
- const h = holder();
173
- if (!h.cell) {
174
- const cell = new ResourceCell(fn, deps, getCurrentContextFrame());
175
- cell.ownerName = inst.fn?.name || "<anonymous>";
176
- h.cell = cell;
177
- h.snapshot = cell.snapshot;
178
- const unsubscribe = cell.subscribe(() => {
179
- const cur = holder();
180
- cur.snapshot.value = cell.snapshot.value;
181
- cur.snapshot.pending = cell.snapshot.pending;
182
- cur.snapshot.error = cell.snapshot.error;
183
- holder.set(cur);
184
- try {
185
- inst.notifyUpdate?.();
186
- } catch {}
187
- });
188
- (inst.cleanupFns ??= []).push(() => {
189
- unsubscribe();
190
- cell.dispose();
191
- });
192
- if (inst.ssr) {
193
- cell.start(true, false);
194
- if (!cell.pending) {
195
- const cur = holder();
196
- cur.snapshot.value = cell.value;
197
- cur.snapshot.pending = cell.pending;
198
- cur.snapshot.error = cell.error;
199
- }
200
- } else {
201
- const scheduledGeneration = cell.generation;
202
- registerCommitOperationForInstance(inst, () => {
203
- enqueueRuntimeLane("post", () => {
204
- if (!inst.notifyUpdate || cell.generation !== scheduledGeneration) return;
205
- try {
206
- cell.start(false, false);
207
- } catch (err) {
208
- const cur = holder();
209
- cur.snapshot.value = cell.value;
210
- cur.snapshot.pending = cell.pending;
211
- cur.snapshot.error = err ?? null;
212
- holder.set(cur);
213
- inst.notifyUpdate?.();
214
- return;
215
- }
216
- if (!cell.pending) {
217
- const cur = holder();
218
- cur.snapshot.value = cell.value;
219
- cur.snapshot.pending = cell.pending;
220
- cur.snapshot.error = cell.error;
221
- holder.set(cur);
222
- inst.notifyUpdate?.();
223
- }
224
- });
225
- });
226
- }
227
- }
228
- const cell = h.cell;
229
- cell.setLoader(fn);
230
- if (!cell.deps || cell.deps.length !== deps.length || cell.deps.some((d, i) => !Object.is(d, deps[i]))) {
231
- cell.deps = deps.slice();
232
- cell.generation++;
233
- cell.pending = true;
234
- cell.error = null;
235
- h.snapshot.pending = true;
236
- h.snapshot.error = null;
237
- try {
238
- if (inst.ssr) {
239
- cell.start(true, false);
240
- if (!cell.pending) {
241
- const cur = holder();
242
- cur.snapshot.value = cell.value;
243
- cur.snapshot.pending = cell.pending;
244
- cur.snapshot.error = cell.error;
245
- }
246
- } else {
247
- const scheduledGeneration = cell.generation;
248
- registerCommitOperationForInstance(inst, () => {
249
- enqueueRuntimeLane("post", () => {
250
- if (!inst.notifyUpdate || cell.generation !== scheduledGeneration) return;
251
- cell.start(false, false);
252
- if (!cell.pending) {
253
- const cur = holder();
254
- cur.snapshot.value = cell.value;
255
- cur.snapshot.pending = cell.pending;
256
- cur.snapshot.error = cell.error;
257
- holder.set(cur);
258
- inst.notifyUpdate?.();
259
- }
260
- });
261
- });
262
- }
263
- } catch (err) {
264
- if (err instanceof SSRDataMissingError) throw err;
265
- cell.error = err;
266
- cell.pending = false;
267
- const cur = holder();
268
- cur.snapshot.value = cell.value;
269
- cur.snapshot.pending = cell.pending;
270
- cur.snapshot.error = cell.error;
271
- }
272
- }
273
- return h.snapshot;
274
- }
275
- //#endregion
1
+ import { n as getActiveRenderContext } from "./render-context-D0Hoj9dW.js";
276
2
  //#region src/router/match.ts
277
3
  function splitPathSegments(path) {
278
4
  const normalized = path.endsWith("/") && path !== "/" ? path.slice(0, -1) : path;
@@ -401,6 +127,7 @@ const registrationScopeStack = [];
401
127
  let registrationLocked = false;
402
128
  let defaultRouteAuthOptions;
403
129
  let activeClientRouteAuthOptions;
130
+ let defaultRouteBasePath = "";
404
131
  function getDepth(path) {
405
132
  const normalized = path.endsWith("/") && path !== "/" ? path.slice(0, -1) : path;
406
133
  return normalized === "/" ? 0 : normalized.split("/").filter(Boolean).length;
@@ -448,6 +175,15 @@ function getDefaultRouteAuthOptions() {
448
175
  function setDefaultRouteAuthOptions(auth) {
449
176
  defaultRouteAuthOptions = auth;
450
177
  }
178
+ function getDefaultRouteBasePath() {
179
+ return defaultRouteBasePath;
180
+ }
181
+ function setDefaultRouteBasePath(basePath) {
182
+ defaultRouteBasePath = basePath;
183
+ }
184
+ function getActiveRouteBasePath() {
185
+ return getActiveRenderContext()?.basePath ?? defaultRouteBasePath;
186
+ }
451
187
  function getCurrentLayoutChain() {
452
188
  const layoutChain = [];
453
189
  for (const scope of registrationScopeStack) if (scope.layout) layoutChain.push({ component: scope.layout });
@@ -514,6 +250,7 @@ function clearRouteState() {
514
250
  registrationLocked = false;
515
251
  defaultRouteAuthOptions = void 0;
516
252
  activeClientRouteAuthOptions = void 0;
253
+ defaultRouteBasePath = "";
517
254
  }
518
255
  function snapshotRouteState() {
519
256
  return {
@@ -523,6 +260,7 @@ function snapshotRouteState() {
523
260
  registrationLocked,
524
261
  defaultRouteAuthOptions,
525
262
  activeClientRouteAuthOptions,
263
+ defaultRouteBasePath,
526
264
  routesByDepth: [...routesByDepth.entries()].map(([depth, depthRoutes]) => [depth, [...depthRoutes]]),
527
265
  registrationScopeStack: [...registrationScopeStack]
528
266
  };
@@ -541,6 +279,7 @@ function restoreRouteState(snapshot) {
541
279
  registrationLocked = snapshot.registrationLocked;
542
280
  defaultRouteAuthOptions = snapshot.defaultRouteAuthOptions;
543
281
  activeClientRouteAuthOptions = snapshot.activeClientRouteAuthOptions;
282
+ defaultRouteBasePath = snapshot.defaultRouteBasePath;
544
283
  }
545
284
  //#endregion
546
285
  //#region src/router/route-context.ts
@@ -617,6 +356,34 @@ function buildRouteContext(target, params, options) {
617
356
  };
618
357
  }
619
358
  //#endregion
359
+ //#region src/router/base-path.ts
360
+ /** Normalize the public mount point used by one route registry. */
361
+ function normalizeRouteBasePath(value) {
362
+ if (value === void 0 || value === "" || value === "/") return "";
363
+ if (!value.startsWith("/") || /\/{2,}/.test(value) || value.includes("?") || value.includes("#") || value.includes("\\")) throw new TypeError(`Route basePath must be an absolute pathname without a query or hash. Received: ${JSON.stringify(value)}`);
364
+ const normalized = value.endsWith("/") ? value.slice(0, -1) : value;
365
+ if (normalized.split("/").some((segment) => segment === "." || segment === "..")) throw new TypeError("Route basePath must not contain dot segments.");
366
+ return normalized;
367
+ }
368
+ function parsedTarget(target) {
369
+ return new URL(target, "http://askr.invalid");
370
+ }
371
+ /** Add a registry mount point to one logical root-relative route target. */
372
+ function addRouteBasePath(target, basePath) {
373
+ if (!basePath || !target.startsWith("/") || target.startsWith("//")) return target;
374
+ const parsed = parsedTarget(target);
375
+ if (parsed.origin !== "http://askr.invalid" || parsed.pathname === basePath || parsed.pathname.startsWith(`${basePath}/`)) return target;
376
+ return `${basePath}${parsed.pathname}${parsed.search}${parsed.hash}`;
377
+ }
378
+ /** Remove a registry mount point and retain query/hash for logical matching. */
379
+ function removeRouteBasePath(target, basePath) {
380
+ const parsed = parsedTarget(target);
381
+ if (!basePath) return `${parsed.pathname}${parsed.search}${parsed.hash}`;
382
+ if (parsed.pathname === basePath || parsed.pathname === `${basePath}/`) return `/${parsed.search}${parsed.hash}`;
383
+ if (!parsed.pathname.startsWith(`${basePath}/`)) return void 0;
384
+ return `${parsed.pathname.slice(basePath.length)}${parsed.search}${parsed.hash}`;
385
+ }
386
+ //#endregion
620
387
  //#region src/router/route-matching.ts
621
388
  const routeSegsCache = /* @__PURE__ */ new WeakMap();
622
389
  const routeRankCache = /* @__PURE__ */ new WeakMap();
@@ -752,7 +519,9 @@ function computeMatchesFromRouteRecords(pathname, routeRecords) {
752
519
  }];
753
520
  }
754
521
  function computeRouteActivityMatches(pathname, options) {
755
- return computeMatchesFromRouteRecords(pathname, options.registry.manifest.records);
522
+ const logicalPath = removeRouteBasePath(pathname, normalizeRouteBasePath(options.registry.manifest.basePath));
523
+ if (logicalPath === void 0) return [];
524
+ return computeMatchesFromRouteRecords(logicalPath, options.registry.manifest.records);
756
525
  }
757
526
  function resolveRoute(pathname) {
758
527
  const normalized = pathname.endsWith("/") && pathname !== "/" ? pathname.slice(0, -1) : pathname;
@@ -784,4 +553,4 @@ function _resolveRouteMatchFromRoutes(pathname, routeList) {
784
553
  return findBestResolvedRouteFromRoutes(pathname, routeList);
785
554
  }
786
555
  //#endregion
787
- export { insertRecordSorted as A, getCurrentPathPrefix as C, getRouteRecords as D, getRouteList as E, snapshotRouteState as F, computeRank as I, normalizeRouteSegmentName as L, pushRegistrationScope as M, restoreRouteState as N, hasActivePageScope as O, setDefaultRouteAuthOptions as P, parseSegments as R, getCurrentPageScope as S, getDefaultRouteAuthOptions as T, getCurrentInheritedAuthRequirements as _, resolveRouteFromRoutes as a, getCurrentLayoutChain as b, deepFreeze as c, _setActiveRouteAuthOptions as d, addRouteToStores as f, getActiveRoutes as g, getActiveRouteAuthOptions as h, getMatchingRouteRecord as i, lockRouteRegistration as j, hasRegisteredRoutes as k, makeQuery as l, clearRouteState as m, computeMatchesFromRoutes as n, buildRouteContext as o, assertRouteRegistrationUnlocked as p, computeRouteActivityMatches as r, buildRouteContextBase as s, _resolveRouteMatchFromRoutes as t, parseLocation as u, getCurrentInheritedMeta as v, getCurrentScopeKind as w, getCurrentPageChain as x, getCurrentInheritedPolicies as y, resource as z };
556
+ export { getDefaultRouteBasePath as A, setDefaultRouteBasePath as B, getCurrentInheritedPolicies as C, getCurrentPathPrefix as D, getCurrentPageScope as E, insertRecordSorted as F, computeRank as H, lockRouteRegistration as I, pushRegistrationScope as L, getRouteRecords as M, hasActivePageScope as N, getCurrentScopeKind as O, hasRegisteredRoutes as P, restoreRouteState as R, getCurrentInheritedMeta as S, getCurrentPageChain as T, normalizeRouteSegmentName as U, snapshotRouteState as V, parseSegments as W, clearRouteState as _, resolveRouteFromRoutes as a, getActiveRoutes as b, removeRouteBasePath as c, deepFreeze as d, makeQuery as f, assertRouteRegistrationUnlocked as g, addRouteToStores as h, getMatchingRouteRecord as i, getRouteList as j, getDefaultRouteAuthOptions as k, buildRouteContext as l, _setActiveRouteAuthOptions as m, computeMatchesFromRoutes as n, addRouteBasePath as o, parseLocation as p, computeRouteActivityMatches as r, normalizeRouteBasePath as s, _resolveRouteMatchFromRoutes as t, buildRouteContextBase as u, getActiveRouteAuthOptions as v, getCurrentLayoutChain as w, getCurrentInheritedAuthRequirements as x, getActiveRouteBasePath as y, setDefaultRouteAuthOptions as z };
@@ -1,9 +1,9 @@
1
- import { u as RenderableChild } from "../control-Y8F73Uln.js";
1
+ import { u as RenderableChild } from "../control-DhUZU4_V.js";
2
2
  import { r as JSXElement, s as Props } from "../jsx-Dvr2SGRG.js";
3
- import { A as RouteHandler, B as RouteQuery, C as Route, D as RouteContext, E as RouteComponent, F as RouteMode, G as RouteRegistryOptions, H as RouteRef, I as RouteOptions, J as RouteRequestResult, K as RouteRenderResult, L as RouteParams, M as RouteMatch, N as RouteMeta, O as RouteDefinition, P as RouteMetaSource, R as RoutePathParams, S as ParsedSegment, T as RouteAuthResolver, U as RouteRefSearch, V as RouteRecord, W as RouteRegistry, X as RouteSearchValue, Y as RouteSearch, Z as RouteSnapshot, _ as AccessRedirectStatus, b as PageHelperOptions, f as AccessAllowDecision, g as AccessRedirectDecision, h as AccessDenyStatus, j as RouteManifest, k as RouteDestination, m as AccessDenyDecision, p as AccessDecision, q as RouteRequestOptions, v as GroupHelperOptions, w as RouteAuthOptions, x as PageScopeRecord, y as LayoutScopeRecord, z as RoutePolicy } from "../index-_UN08Pg1.js";
3
+ import { A as RouteHandler, B as RouteQuery, C as Route, D as RouteContext, E as RouteComponent, F as RouteMode, G as RouteRegistryOptions, H as RouteRef, I as RouteOptions, J as RouteRequestResult, K as RouteRenderResult, L as RouteParams, M as RouteMatch, N as RouteMeta, O as RouteDefinition, P as RouteMetaSource, R as RoutePathParams, S as ParsedSegment, T as RouteAuthResolver, U as RouteRefSearch, V as RouteRecord, W as RouteRegistry, X as RouteSearchValue, Y as RouteSearch, Z as RouteSnapshot, _ as AccessRedirectStatus, b as PageHelperOptions, f as AccessAllowDecision, g as AccessRedirectDecision, h as AccessDenyStatus, j as RouteManifest, k as RouteDestination, m as AccessDenyDecision, p as AccessDecision, q as RouteRequestOptions, v as GroupHelperOptions, w as RouteAuthOptions, x as PageScopeRecord, y as LayoutScopeRecord, z as RoutePolicy } from "../index-pIgGaXvS.js";
4
4
  import "../types-C9YcqVpk.js";
5
- import { a as ScrollRestorationOptions, i as NavigationScrollBehavior, n as NavigateOptions, r as HistoryScrollBehavior, t as navigate } from "../navigate-CgVIrrSs.js";
6
- import { i as onRouteChange, n as RouteChangeOptions, r as currentRoute, t as RouteChangeCleanup } from "../activity-pySy9t7Y.js";
5
+ import { a as ScrollRestorationOptions, i as NavigationScrollBehavior, n as NavigateOptions, r as HistoryScrollBehavior, t as navigate } from "../navigate-NyIjQUwI.js";
6
+ import { i as onRouteChange, n as RouteChangeOptions, r as currentRoute, t as RouteChangeCleanup } from "../activity-B1I5HJQI.js";
7
7
  import { AuthContext, AuthContext as AuthContext$1, AuthRequirement, AuthRequirement as AuthRequirement$1 } from "@askrjs/auth";
8
8
  import { ObjectSchema } from "@askrjs/schema";
9
9
  //#region src/router/route-query.d.ts
@@ -29,7 +29,7 @@ type RouteComponentParam<TComponent extends AnyRouteComponent> = Parameters<TCom
29
29
  type CompatibleAbsoluteRouteComponent<Path extends string, TComponent extends AnyRouteComponent> = Parameters<TComponent> extends [] ? TComponent : RoutePathParams<Path> extends RouteComponentParam<TComponent> ? TComponent : never;
30
30
  type CompatibleRelativeRouteComponent<Path extends string, TComponent extends AnyRouteComponent> = Parameters<TComponent> extends [] ? TComponent : RouteComponentParam<TComponent> extends Record<keyof RoutePathParams<Path>, string> ? TComponent : never;
31
31
  type CompatibleRouteComponent<Path extends string, TComponent extends AnyRouteComponent> = Path extends `/${string}` ? CompatibleAbsoluteRouteComponent<Path, TComponent> : CompatibleRelativeRouteComponent<Path, TComponent>;
32
- type RouteOptionsForComponent<Path extends string, TComponent extends AnyRouteComponent, TSearchSchema extends ObjectSchema<RouteSearch> | undefined = ObjectSchema<RouteSearch> | undefined> = Parameters<TComponent> extends [] ? RouteOptions<RoutePathParams<Path>, TSearchSchema> : RouteComponentParam<TComponent> extends RouteParams ? RouteOptions<RouteComponentParam<TComponent>, TSearchSchema> : RouteOptions<RoutePathParams<Path>, TSearchSchema>;
32
+ type RouteOptionsForComponent<Path extends string, TComponent extends AnyRouteComponent, TSearchSchema extends ObjectSchema<RouteSearch> | undefined = ObjectSchema<RouteSearch> | undefined, TLoaderData = unknown, TDehydratedData = TLoaderData> = Parameters<TComponent> extends [] ? RouteOptions<RoutePathParams<Path>, TSearchSchema, TLoaderData, TDehydratedData> : RouteComponentParam<TComponent> extends RouteParams ? RouteOptions<RouteComponentParam<TComponent>, TSearchSchema, TLoaderData, TDehydratedData> : RouteOptions<RoutePathParams<Path>, TSearchSchema, TLoaderData, TDehydratedData>;
33
33
  declare function group(options: GroupHelperOptions, fn: RouteDefinition): void;
34
34
  declare function page<const TPath extends string>(path: TPath, Component: RouteComponent<RoutePathParams<TPath>>, fn: RouteDefinition): void;
35
35
  declare function page<const TPath extends string, TComponent extends AnyRouteComponent>(path: TPath, Component: CompatibleRouteComponent<TPath, TComponent>, fn: RouteDefinition): void;
@@ -37,8 +37,8 @@ declare function page<const TPath extends string>(path: TPath, Component: RouteC
37
37
  declare function page<const TPath extends string, TComponent extends AnyRouteComponent>(path: TPath, Component: CompatibleRouteComponent<TPath, TComponent>, options: PageHelperOptions, fn: RouteDefinition): void;
38
38
  declare function index(Component: RouteComponent, options?: RouteOptions): void;
39
39
  declare function fallback(Component: RouteComponent): void;
40
- declare function route<const TPath extends string, const TSearchSchema extends ObjectSchema<RouteSearch> | undefined = undefined>(path: TPath, Component: RouteComponent<RoutePathParams<TPath>>, options?: RouteOptions<RoutePathParams<TPath>, TSearchSchema>): RouteRef<RoutePathParams<TPath>, RouteRefSearch<TSearchSchema>>;
41
- declare function route<const TPath extends string, TComponent extends AnyRouteComponent, const TSearchSchema extends ObjectSchema<RouteSearch> | undefined = undefined>(path: TPath, Component: CompatibleRouteComponent<TPath, TComponent>, options?: RouteOptionsForComponent<TPath, TComponent, TSearchSchema>): RouteRef<RoutePathParams<TPath>, RouteRefSearch<TSearchSchema>>;
40
+ declare function route<const TPath extends string, const TSearchSchema extends ObjectSchema<RouteSearch> | undefined = undefined, TLoaderData = unknown, TDehydratedData = TLoaderData>(path: TPath, Component: RouteComponent<RoutePathParams<TPath>>, options?: RouteOptions<RoutePathParams<TPath>, TSearchSchema, TLoaderData, TDehydratedData>): RouteRef<RoutePathParams<TPath>, RouteRefSearch<TSearchSchema>>;
41
+ declare function route<const TPath extends string, TComponent extends AnyRouteComponent, const TSearchSchema extends ObjectSchema<RouteSearch> | undefined = undefined, TLoaderData = unknown, TDehydratedData = TLoaderData>(path: TPath, Component: CompatibleRouteComponent<TPath, TComponent>, options?: RouteOptionsForComponent<TPath, TComponent, TSearchSchema, TLoaderData, TDehydratedData>): RouteRef<RoutePathParams<TPath>, RouteRefSearch<TSearchSchema>>;
42
42
  //#endregion
43
43
  //#region src/router/auth.d.ts
44
44
  /** Return the identity resolved for the route currently being rendered. */
@@ -81,7 +81,7 @@ declare function resolveRouteMeta(record: RouteRecord, context: RouteContext): P
81
81
  declare function reconcileRouteMeta(meta: Readonly<RouteMeta>, target?: Document): void;
82
82
  declare function serializeRouteMeta(meta: RouteMeta): string;
83
83
  //#endregion
84
- //#region src/router/deferred.d.ts
84
+ //#region src/common/deferred-value.d.ts
85
85
  declare const DEFERRED_VALUE: unique symbol;
86
86
  type DeferredState = 'pending' | 'fulfilled' | 'rejected';
87
87
  interface Deferred<T> {
@@ -91,14 +91,16 @@ interface Deferred<T> {
91
91
  readonly promise: Promise<T>;
92
92
  readonly [DEFERRED_VALUE]: true;
93
93
  }
94
+ declare function defer<T>(promise: PromiseLike<T>): Deferred<T>;
95
+ declare function isDeferred<T = unknown>(value: unknown): value is Deferred<T>;
96
+ //#endregion
97
+ //#region src/router/deferred.d.ts
94
98
  interface ResolveProps<T> {
95
99
  value: Deferred<T>;
96
100
  pending?: RenderableChild;
97
101
  rejected?: RenderableChild | ((error: unknown) => RenderableChild);
98
102
  children: (value: T) => RenderableChild;
99
103
  }
100
- declare function defer<T>(promise: PromiseLike<T>): Deferred<T>;
101
- declare function isDeferred<T = unknown>(value: unknown): value is Deferred<T>;
102
104
  declare function resolveDeferredValues<T>(input: T, signal?: AbortSignal): Promise<T>;
103
105
  declare function routeData<T>(): T;
104
106
  declare function Resolve<T>(props: ResolveProps<T>): JSXElement;
@@ -1,9 +1,11 @@
1
- import { a as resolveDeferredValues, b as Outlet, i as isDeferred, l as createRouteRegistry, m as resolveRouteRequest, n as Resolve, r as defer, s as routeData, w as lazy, y as currentAuth } from "../deferred-oqtAJ4iH.js";
2
- import { a as isSafeHref } from "../csp-nonce-ZTlD_EnK.js";
1
+ import { n as createRouteRegistry } from "../manifest-D1P9uTlz.js";
2
+ import { a as isSafeHref } from "../csp-nonce-Bc52OIVc.js";
3
3
  import { jsx } from "../jsx-runtime.js";
4
- import { a as route, i as page, n as group, r as index, t as fallback } from "../authoring-DQPG0VAm.js";
5
- import { n as onRouteChange, t as currentRoute } from "../activity-CZiPgZy0.js";
6
- import { a as serializeRouteMeta, c as getCurrentHref, d as parseTargetUrl, h as syncRegisteredRouteSnapshot, i as resolveRouteMeta, l as getRegisteredAppsSnapshot, m as syncAppRegistrationLocation, n as navigate, p as setCurrentRouteLocation, r as reconcileRouteMeta, s as saveScrollPosition, u as getWindowHref } from "../navigate-Dr3cjOSz.js";
4
+ import { o as addRouteBasePath, y as getActiveRouteBasePath } from "../route-matching-DqULzZtC.js";
5
+ import { a as group, c as route, i as fallback, n as resolveDeferredValues, o as index, r as routeData, s as page, t as Resolve } from "../deferred-nleQtdfY.js";
6
+ import { a as resolveRouteRequest, b as lazy, f as defer, g as Outlet, h as currentAuth, p as isDeferred } from "../resolution-YHwi4Bav.js";
7
+ import { n as onRouteChange, t as currentRoute } from "../activity-BvgvaMZA.js";
8
+ import { a as serializeRouteMeta, c as getCurrentHref, d as parseTargetUrl, h as syncRegisteredRouteSnapshot, i as resolveRouteMeta, l as getRegisteredAppsSnapshot, m as syncAppRegistrationLocation, n as navigate, p as setCurrentRouteLocation, r as reconcileRouteMeta, s as saveScrollPosition, u as getWindowHref } from "../navigate-BwAPbpCb.js";
7
9
  import { o as mergeProps } from "../compose-ref-Cc_YkUpM.js";
8
10
  import { t as applyInteractionPolicy } from "../interactions-DgGQyUQv.js";
9
11
  //#region src/router/route-query.ts
@@ -116,7 +118,7 @@ function formatSearchIssues(issues) {
116
118
  return issues.map((issue) => `${issue.path.length ? issue.path.join(".") : "search"}: ${issue.message}`).join("; ");
117
119
  }
118
120
  function to(route, params, search) {
119
- const path = buildPath(route, params);
121
+ const path = addRouteBasePath(buildPath(route, params), route.basePath ?? "");
120
122
  const parsedSearch = route.searchSchema?.safeParse(search ?? {});
121
123
  if (parsedSearch && !parsedSearch.success) throw new Error(`Invalid route search. ${formatSearchIssues(parsedSearch.issues)}`);
122
124
  const values = parsedSearch?.success ? parsedSearch.data : search;
@@ -167,7 +169,8 @@ function isSameOriginNavigableHref(href) {
167
169
  * - Composable via mergeProps
168
170
  */
169
171
  function Link({ href: suppliedHref, to, class: className, children, rel, target, "aria-current": ariaCurrent, "aria-label": ariaLabel, onPress, onClick, ...rest }) {
170
- const href = to?.href ?? suppliedHref;
172
+ const supplied = to?.href ?? suppliedHref;
173
+ const href = supplied ? addRouteBasePath(supplied, getActiveRouteBasePath()) : supplied;
171
174
  if (!href) throw new Error("Link requires href or to.");
172
175
  if (!isSafeHref(href)) throw new TypeError("Link href uses an unsafe URL scheme.");
173
176
  const handleNavigation = (e) => {
@@ -1,6 +1,6 @@
1
- import { t as enqueueRuntimeLane } from "./access-ePqdQqkV.js";
2
- import { c as markReadableUsage, f as syncDerivedDependencySubscriptions, l as notifyReadableReaders, o as markReactivePropsDirtySource, p as withDerivedReadTracking, r as clearDerivedDependencySubscriptions, s as markReadableDerivedSubscribersDirty, u as recordReadableRead } from "./readable-_GQGe_St.js";
1
+ import { t as enqueueRuntimeLane } from "./access-Dpfoi4cA.js";
3
2
  import { i as claimHookIndex, p as getCurrentInstance } from "./component-scope-DzJEbYGE.js";
3
+ import { c as markReadableUsage, f as syncDerivedDependencySubscriptions, l as notifyReadableReaders, o as markReactivePropsDirtySource, p as withDerivedReadTracking, r as clearDerivedDependencySubscriptions, s as markReadableDerivedSubscribersDirty, u as recordReadableRead } from "./readable-B5NtV7V0.js";
4
4
  //#region src/runtime/selector-store.ts
5
5
  const dirtySelectorRecords = /* @__PURE__ */ new Set();
6
6
  let hasPendingSelectorFlush = false;
@@ -1,5 +1,5 @@
1
- import { f as DocumentRenderArgs, m as DocumentRenderer, p as DocumentRenderContext } from "../control-Y8F73Uln.js";
2
- import { A as RouteHandler, I as RouteOptions, R as RoutePathParams, W as RouteRegistry, z as RoutePolicy } from "../index-_UN08Pg1.js";
1
+ import { _ as SSRStyleRegistrationValidation, f as DocumentRenderArgs, m as DocumentRenderer, p as DocumentRenderContext } from "../control-DhUZU4_V.js";
2
+ import { A as RouteHandler, I as RouteOptions, R as RoutePathParams, W as RouteRegistry, z as RoutePolicy } from "../index-pIgGaXvS.js";
3
3
  import { AuthRequirement } from "@askrjs/auth";
4
4
  import "node:fs/promises";
5
5
  //#region src/ssg/types.d.ts
@@ -31,6 +31,10 @@ interface RouteConfig<Path extends string = string> {
31
31
  invalidationKeys?: string[];
32
32
  /** Route loader resolved completely before static HTML is rendered. */
33
33
  loader?: RouteOptions['loader'];
34
+ /** Select the loader data transported for initial hydration. */
35
+ dehydrate?: RouteOptions['dehydrate'];
36
+ /** @internal Public mount point inherited from the owning registry. */
37
+ basePath?: string;
34
38
  /**
35
39
  * SSG entry generator for parameterized routes.
36
40
  *
@@ -54,6 +58,8 @@ interface SSGBaseOptions {
54
58
  dataOverrides?: Record<string, unknown>;
55
59
  /** Optional document wrapper for full HTML output */
56
60
  document?: DocumentRenderer;
61
+ /** Diagnose document renderers that omit request-local SSR style registrations. */
62
+ styleRegistrationValidation?: SSRStyleRegistrationValidation;
57
63
  /** Static files or directories published with the generated routes. */
58
64
  assets?: readonly SSGAssetSource[];
59
65
  /** Optional concurrency limit for rendering (default: 1) */
@@ -242,4 +248,4 @@ declare function createStaticGen(options: SSGOptions): {
242
248
  getResult(): SSGResult | null;
243
249
  };
244
250
  //#endregion
245
- export { type DiscoveredResources, type DocumentRenderArgs, type DocumentRenderContext, type DocumentRenderer, type RouteConfig, type RouteRenderReason, type RouteRenderResult, type RouteRenderStatus, type SSGAssetSource, type SSGGenerateOptions, type SSGMetadata, type SSGMode, type SSGOptions, type SSGResult, createStaticGen };
251
+ export { type DiscoveredResources, type DocumentRenderArgs, type DocumentRenderContext, type DocumentRenderer, type RouteConfig, type RouteRenderReason, type RouteRenderResult, type RouteRenderStatus, type SSGAssetSource, type SSGGenerateOptions, type SSGMetadata, type SSGMode, type SSGOptions, type SSGResult, type SSRStyleRegistrationValidation, createStaticGen };
package/dist/ssg/index.js CHANGED
@@ -1,8 +1,10 @@
1
- import "../access-ePqdQqkV.js";
2
- import { C as _preloadRouteHandler, S as getRenderHandler, a as resolveDeferredValues, l as createRouteRegistry, u as bindResolvedRouteData } from "../deferred-oqtAJ4iH.js";
3
- import { a as route } from "../authoring-DQPG0VAm.js";
4
- import { n as renderDocument } from "../ssr-CbQO5xd3.js";
5
- import { n as renderToString } from "../ssr-CtC4lChT.js";
1
+ import "../access-Dpfoi4cA.js";
2
+ import { n as createRouteRegistry } from "../manifest-D1P9uTlz.js";
3
+ import { o as addRouteBasePath } from "../route-matching-DqULzZtC.js";
4
+ import { c as route, n as resolveDeferredValues } from "../deferred-nleQtdfY.js";
5
+ import { c as prepareRouteHydrationData, t as bindResolvedRouteData, v as getRenderHandler, y as _preloadRouteHandler } from "../resolution-YHwi4Bav.js";
6
+ import { n as renderDocument } from "../ssr-DSHd_Q9K.js";
7
+ import { n as renderToString } from "../ssr-B98593qJ.js";
6
8
  import * as fs from "node:fs/promises";
7
9
  import * as pathModule from "node:path";
8
10
  import * as os from "node:os";
@@ -141,17 +143,21 @@ function validateRoutes(routes) {
141
143
  * Render multiple routes in parallel with error handling
142
144
  */
143
145
  async function batchRenderRoutes(routes, options = {}) {
144
- const { seed = 12345, dataMap = {}, concurrency = 1, document } = options;
146
+ const { seed = 12345, dataMap = {}, concurrency = 1, document, styleRegistrationValidation = "warn" } = options;
145
147
  const workerCount = Math.max(1, Math.min(concurrency, routes.length || 1));
146
148
  const results = [];
147
149
  results.length = routes.length;
148
150
  let nextIndex = 0;
149
- const sharedRegistry = new Set(routes.map((route) => route.path)).size === routes.length ? createRouteRegistry(() => {
151
+ const hasUniquePaths = new Set(routes.map((route) => route.path)).size === routes.length;
152
+ const basePaths = new Set(routes.map((route) => route.basePath ?? ""));
153
+ const sharedBasePath = basePaths.size === 1 ? routes[0]?.basePath : void 0;
154
+ const sharedRegistry = hasUniquePaths && basePaths.size <= 1 ? createRouteRegistry(() => {
150
155
  for (const route$1 of routes) route(route$1.path, route$1.handler, { namespace: route$1.namespace });
151
- }) : void 0;
156
+ }, { basePath: sharedBasePath }) : void 0;
152
157
  const renderOne = async (route$2) => {
153
158
  const startTime = performance.now();
154
159
  const url = interpolateRoutePath(route$2.path, route$2.params);
160
+ const publicUrl = addRouteBasePath(url, route$2.basePath ?? "");
155
161
  const requestUrl = new URL(url, "http://localhost");
156
162
  const resolvedData = resolveSsgRouteData(dataMap, route$2.path, url);
157
163
  const baseData = resolvedData.hasData ? resolvedData.data : void 0;
@@ -161,6 +167,7 @@ async function batchRenderRoutes(routes, options = {}) {
161
167
  try {
162
168
  await _preloadRouteHandler(mergedHandler);
163
169
  let routeData;
170
+ let routeHydration;
164
171
  let hasRouteData = false;
165
172
  if (route$2.loader) {
166
173
  const controller = new AbortController();
@@ -179,24 +186,30 @@ async function batchRenderRoutes(routes, options = {}) {
179
186
  },
180
187
  signal: controller.signal
181
188
  };
189
+ const request = new Request(requestUrl);
182
190
  const loaded = await route$2.loader({
183
191
  ...loadContext,
184
- request: new Request(requestUrl)
192
+ request
185
193
  });
186
194
  await resolveDeferredValues(loaded, controller.signal);
187
195
  routeData = loaded;
196
+ routeHydration = prepareRouteHydrationData(loaded, route$2.dehydrate, {
197
+ ...loadContext,
198
+ request
199
+ }, url);
188
200
  hasRouteData = true;
189
201
  }
190
- const renderedHandler = hasRouteData ? bindResolvedRouteData(mergedHandler, routeData) : mergedHandler;
202
+ const renderedHandler = hasRouteData ? bindResolvedRouteData(mergedHandler, routeData, routeHydration) : mergedHandler;
191
203
  const registry = hasRouteData || !sharedRegistry ? createRouteRegistry(() => {
192
204
  route(route$2.path, renderedHandler, { namespace: route$2.namespace });
193
- }) : sharedRegistry;
205
+ }, { basePath: route$2.basePath }) : sharedRegistry;
194
206
  phase = "render";
195
207
  const html = renderToString({
196
- url,
208
+ url: publicUrl,
197
209
  registry,
198
210
  seed,
199
211
  data: baseData,
212
+ styleRegistrationValidation: "off",
200
213
  document: document === void 0 ? void 0 : ({ appHtml, context }) => renderDocument(document, {
201
214
  appHtml,
202
215
  context: {
@@ -215,7 +228,7 @@ async function batchRenderRoutes(routes, options = {}) {
215
228
  cspNonce: context.cspNonce,
216
229
  styles: context.styles
217
230
  }
218
- }, "createStaticGen()")
231
+ }, "createStaticGen()", styleRegistrationValidation)
219
232
  });
220
233
  const duration = performance.now() - startTime;
221
234
  return {
@@ -632,7 +645,9 @@ function routeRegistryToRouteConfigs(registry) {
632
645
  auth: options.auth,
633
646
  policies: options.policies,
634
647
  entries: options.entries,
635
- loader: options.loader
648
+ loader: options.loader,
649
+ dehydrate: options.dehydrate,
650
+ basePath: registry.manifest.basePath
636
651
  });
637
652
  }
638
653
  return routeConfigs;
@@ -766,7 +781,8 @@ function createStaticGen(options) {
766
781
  seed,
767
782
  dataMap,
768
783
  concurrency: resolvedConcurrency,
769
- document: options.document
784
+ document: options.document,
785
+ styleRegistrationValidation: options.styleRegistrationValidation
770
786
  }) : [];
771
787
  performance.now() - renderStartTime;
772
788
  const renderedByRouteId = /* @__PURE__ */ new Map();