@askrjs/askr 0.3.0 → 0.4.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.
- package/CHANGELOG.md +874 -0
- package/README.md +61 -29
- package/capabilities.json +19 -9
- package/dist/actions/index.js +56 -12
- package/dist/benchmark.js +10 -15
- package/dist/boot/index.d.ts +3 -2
- package/dist/boot/index.js +1 -1
- package/dist/boot-DaoTYoCw.js +3989 -0
- package/dist/browser-activity-CB8e-V4f.js +220 -0
- package/dist/components/index.d.ts +8 -1
- package/dist/components/index.js +1 -43
- package/dist/{aria-hKjThHcp.js → compose-ref-DWzdbxsD.js} +41 -4
- package/dist/control/index.d.ts +2 -0
- package/dist/control/index.js +1 -1
- package/dist/control-nfpT2fbK.js +209 -0
- package/dist/core.d.ts +5 -9
- package/dist/csp-nonce-DwGw1A6Q.js +35 -0
- package/dist/data/index.js +3 -3
- package/dist/{data-2edW0jhF.js → data-BCwClJiF.js} +283 -94
- package/dist/data-runtime-C1bFAlba.js +242 -0
- package/dist/{deferred-CbgNhf67.js → deferred-bEEHHvic.js} +42 -20
- package/dist/domains/actions.d.ts +8 -3
- package/dist/domains/component.d.ts +1 -107
- package/dist/domains/context.d.ts +0 -15
- package/dist/domains/control.d.ts +36 -249
- package/dist/domains/data.d.ts +31 -13
- package/dist/domains/diagnostics.d.ts +1 -2
- package/dist/domains/lifecycle.d.ts +2 -5
- package/dist/domains/refs.d.ts +0 -2
- package/dist/domains/routing.d.ts +43 -8
- package/dist/domains/scheduler.d.ts +1 -76
- package/dist/domains/server.d.ts +5 -2
- package/dist/domains/state.d.ts +2 -5
- package/dist/domains/telemetry.d.ts +0 -2
- package/dist/elements.d.ts +214 -51
- package/dist/error-boundary-Bpwofwps.js +293 -0
- package/dist/foundations/icon/index.d.ts +0 -58
- package/dist/foundations/icon/index.js +2 -2
- package/dist/foundations/index.js +2 -1
- package/dist/foundations/interactions/index.js +1 -1
- package/dist/foundations/state/index.d.ts +3 -3
- package/dist/foundations/state/index.js +5 -3
- package/dist/foundations/structures/index.js +2 -1
- package/dist/foundations/utilities/index.d.ts +2 -0
- package/dist/foundations/utilities/index.js +1 -2
- package/dist/fx/index.d.ts +31 -58
- package/dist/fx/index.js +313 -195
- package/dist/hooks-BimKStr4.js +202 -0
- package/dist/index.d.ts +11 -74
- package/dist/index.js +8 -447
- package/dist/instance-BAnfmXOR.js +988 -0
- package/dist/{interactions-CTeACdT_.js → interactions-D2BoREb-.js} +3 -2
- package/dist/jsx-dev-runtime.d.ts +41 -18
- package/dist/jsx-dev-runtime.js +1 -6
- package/dist/{jsx-runtime-CPJXAOBF.js → jsx-runtime-C4idqHY0.js} +18 -7
- package/dist/jsx-runtime.js +1 -1
- package/dist/jsx.d.ts +61 -37
- package/dist/{manifest-D1P3UNWV.js → manifest-CW9gyNBY.js} +3 -3
- package/dist/{navigate-prC5V8XV.js → navigate-CP_0Zy5U.js} +454 -87
- package/dist/navigation.d.ts +12 -3
- package/dist/peer-types.d.ts +8 -0
- package/dist/portal-DuOKfnLa.js +349 -0
- package/dist/promise-Dz8iIHAm.js +16 -0
- package/dist/query-registry-WMCN0BJL.js +320 -0
- package/dist/readable-DFWOsTac.js +21 -0
- package/dist/{render-context-B7ohlh6t.js → render-context-DGHnEveC.js} +27 -11
- package/dist/render-sync-IC5lMFpq.js +1240 -0
- package/dist/resolution-Cx82-xjW.js +1244 -0
- package/dist/resource-CLjB7RBQ.js +377 -0
- package/dist/resources/index.d.ts +21 -11
- package/dist/resources/index.js +45 -244
- package/dist/router/index.d.ts +14 -5
- package/dist/router/index.js +22 -53
- package/dist/scope-CwpVSHVf.js +55 -0
- package/dist/{shared-kU8yvryp.js → shared-O2ZnmYAf.js} +1 -7
- package/dist/{snapshot-source-An4iKajG.js → snapshot-Cjx4N988.js} +6 -1
- package/dist/ssg/index.d.ts +1 -2
- package/dist/ssg/index.js +5 -13
- package/dist/ssr/index.d.ts +26 -28
- package/dist/ssr/index.js +4 -4
- package/dist/{ssr-CiNm6Vzl.js → ssr-BJ8ug7zH.js} +133 -122
- package/dist/ssr-DoV-vJ-5.js +229 -0
- package/dist/state-DWO1KzkX.js +232 -0
- package/dist/structures-D4dDMqHX.js +231 -0
- package/dist/testing/index.d.ts +8 -4
- package/dist/testing/index.js +29 -34
- package/dist/url-CnbfpX0K.js +185 -0
- package/dist/utilities.d.ts +48 -2
- package/dist/verify-hydration-DpVaDnqz.js +152 -0
- package/package.json +19 -9
- package/dist/access-CEA2pOry.js +0 -1046
- package/dist/activity-oy2YFTFF.js +0 -201
- package/dist/boot-BMBMWUGI.js +0 -1084
- package/dist/capabilities-Bbf0mlp9.js +0 -42
- package/dist/compose-ref-v0qGlHoN.js +0 -26
- package/dist/control-BR_mrX__.js +0 -173
- package/dist/control-C-ApnFs1.js +0 -20
- package/dist/csp-nonce-BfFWcd0w.js +0 -173
- package/dist/data-runtime-CxoY98lX.js +0 -149
- package/dist/default-portal-runtime-DvMvWJVp.js +0 -20
- package/dist/dom-renderer.d.ts +0 -77
- package/dist/domains/renderer.d.ts +0 -127
- package/dist/eager-control.d.ts +0 -8
- package/dist/effect-C3Zsc1k6.js +0 -292
- package/dist/for-state-BDykeOJL.js +0 -1753
- package/dist/instance-VAFYVJOa.js +0 -1027
- package/dist/notify-DxxuDPeY.js +0 -266
- package/dist/portal-w3oQ6oQU.js +0 -29
- package/dist/query-registry-LrYpQsDJ.js +0 -83
- package/dist/render-resolved-BC0W7_5b.js +0 -1123
- package/dist/renderer-CT0HeY58.js +0 -8623
- package/dist/resolution-3DskUkjG.js +0 -577
- package/dist/resource-18-sFRl9.js +0 -344
- package/dist/route-matching-CUzZ31gT.js +0 -551
- package/dist/router-internal-7nuNEHfG.js +0 -36
- package/dist/scope-Cq_iYbTR.js +0 -403
- package/dist/selector-BSPVkjKP.js +0 -311
- package/dist/ssr-EPjwJH5R.js +0 -29
- package/dist/state-BXJfudq1.js +0 -91
- package/dist/structures-CjEzfj4h.js +0 -654
- package/dist/timer-C7uqnJVt.js +0 -85
- package/dist/verify-hydration-ikaxotf7.js +0 -27
- package/dist/vnode-D24p6IW2.js +0 -7
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
import { a as getDefaultDataRuntime, d as writePrefetchedQueryData, i as findDataRuntimeState, t as createDataRuntime } from "./data-runtime-C1bFAlba.js";
|
|
2
|
+
//#region src/common/deferred-value.ts
|
|
3
|
+
const DEFERRED_VALUE = Symbol.for("@askrjs/askr/deferred-value");
|
|
4
|
+
const DEFERRED_BOUNDARY = Symbol.for("@askrjs/askr/deferred-boundary");
|
|
5
|
+
/** Wrap a promise as a {@link Deferred} value that tracks its settled state and result. */
|
|
6
|
+
function defer(promise) {
|
|
7
|
+
let state = "pending";
|
|
8
|
+
let value;
|
|
9
|
+
let error;
|
|
10
|
+
const normalized = Promise.resolve(promise);
|
|
11
|
+
normalized.then((resolved) => {
|
|
12
|
+
state = "fulfilled";
|
|
13
|
+
value = resolved;
|
|
14
|
+
}, (reason) => {
|
|
15
|
+
state = "rejected";
|
|
16
|
+
error = reason;
|
|
17
|
+
});
|
|
18
|
+
return Object.freeze(Object.defineProperties({}, {
|
|
19
|
+
state: {
|
|
20
|
+
enumerable: true,
|
|
21
|
+
get: () => state
|
|
22
|
+
},
|
|
23
|
+
value: {
|
|
24
|
+
enumerable: true,
|
|
25
|
+
get: () => value
|
|
26
|
+
},
|
|
27
|
+
error: {
|
|
28
|
+
enumerable: true,
|
|
29
|
+
get: () => error
|
|
30
|
+
},
|
|
31
|
+
promise: { value: normalized },
|
|
32
|
+
[DEFERRED_VALUE]: { value: true }
|
|
33
|
+
}));
|
|
34
|
+
}
|
|
35
|
+
/** Check whether `value` is a {@link Deferred} produced by {@link defer}. */
|
|
36
|
+
function isDeferred(value) {
|
|
37
|
+
if (!value || typeof value !== "object") return false;
|
|
38
|
+
const marker = Object.getOwnPropertyDescriptor(value, DEFERRED_VALUE);
|
|
39
|
+
return Boolean(marker && "value" in marker && marker.value === true);
|
|
40
|
+
}
|
|
41
|
+
/** @internal Reconstruct settled server data without importing deferred rendering. */
|
|
42
|
+
function reviveDeferredValue(state, value, error) {
|
|
43
|
+
const promise = state === "fulfilled" ? Promise.resolve(value) : Promise.reject(error);
|
|
44
|
+
if (state === "rejected") promise.catch(() => void 0);
|
|
45
|
+
return Object.freeze(Object.defineProperties({}, {
|
|
46
|
+
state: {
|
|
47
|
+
enumerable: true,
|
|
48
|
+
value: state
|
|
49
|
+
},
|
|
50
|
+
value: {
|
|
51
|
+
enumerable: true,
|
|
52
|
+
value
|
|
53
|
+
},
|
|
54
|
+
error: {
|
|
55
|
+
enumerable: true,
|
|
56
|
+
value: error
|
|
57
|
+
},
|
|
58
|
+
promise: { value: promise },
|
|
59
|
+
[DEFERRED_VALUE]: { value: true }
|
|
60
|
+
}));
|
|
61
|
+
}
|
|
62
|
+
//#endregion
|
|
63
|
+
//#region src/common/json-transport.ts
|
|
64
|
+
/** Diagnostic path for an own property of the value at `parent`. */
|
|
65
|
+
function jsonTransportPropertyPath(parent, key) {
|
|
66
|
+
if (/^(?:0|[1-9]\d*)$/.test(key)) return `${parent}[${key}]`;
|
|
67
|
+
if (/^[A-Za-z_$][\w$]*$/.test(key)) return `${parent}.${key}`;
|
|
68
|
+
return `${parent}[${JSON.stringify(key)}]`;
|
|
69
|
+
}
|
|
70
|
+
/** Format a diagnostic path only when a value actually fails. */
|
|
71
|
+
function pathOf(frame, key) {
|
|
72
|
+
const keys = key === void 0 ? [] : [key];
|
|
73
|
+
for (let at = frame; at.p; at = at.p) keys.push(at.k);
|
|
74
|
+
let path = "$";
|
|
75
|
+
for (let index = keys.length - 1; index >= 0; index -= 1) path = jsonTransportPropertyPath(path, keys[index]);
|
|
76
|
+
return path;
|
|
77
|
+
}
|
|
78
|
+
function primitiveReason(value) {
|
|
79
|
+
switch (typeof value) {
|
|
80
|
+
case "number": return Number.isFinite(value) ? void 0 : "non-finite numbers are not supported";
|
|
81
|
+
case "undefined": return "undefined is not supported";
|
|
82
|
+
case "bigint": return "bigint is not supported";
|
|
83
|
+
case "symbol": return "symbols are not supported";
|
|
84
|
+
case "function": return "functions are not supported";
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
function objectLabel(value) {
|
|
88
|
+
if (value instanceof Date) return "Date";
|
|
89
|
+
if (value instanceof Map) return "Map";
|
|
90
|
+
if (value instanceof Set) return "Set";
|
|
91
|
+
const constructor = value.constructor;
|
|
92
|
+
return typeof constructor === "function" && constructor.name ? constructor.name : "class instance";
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Validate that `value` survives the hydration JSON transport unchanged:
|
|
96
|
+
* `null`, strings, booleans, finite numbers, dense arrays, plain objects, and
|
|
97
|
+
* framework deferred values. Anything `JSON.stringify()` would drop, coerce, or
|
|
98
|
+
* reject (undefined, functions, bigint, `Date`, `Map`, class instances, cycles,
|
|
99
|
+
* and so on) throws a `TypeError` naming `subject` and the value's path, then
|
|
100
|
+
* `hint`. Accessors are rejected without being invoked. The walk is
|
|
101
|
+
* iterative, so nesting depth is bounded by memory rather than the call
|
|
102
|
+
* stack, and paths are formatted only on failure.
|
|
103
|
+
*/
|
|
104
|
+
function validateJsonTransportValue(value, subject, hint) {
|
|
105
|
+
const fail = (path, reason) => {
|
|
106
|
+
throw new TypeError(`[Askr] ${subject} at "${path}" is not JSON transport-safe: ${reason}. ${hint}`);
|
|
107
|
+
};
|
|
108
|
+
const stack = [];
|
|
109
|
+
const ancestors = /* @__PURE__ */ new Set();
|
|
110
|
+
const visit = (child, parent, key) => {
|
|
111
|
+
const reason = primitiveReason(child);
|
|
112
|
+
if (reason) fail(parent ? pathOf(parent, key) : "$", reason);
|
|
113
|
+
if (child !== null && typeof child === "object") stack.push({
|
|
114
|
+
o: child,
|
|
115
|
+
p: parent,
|
|
116
|
+
k: key,
|
|
117
|
+
seen: false
|
|
118
|
+
});
|
|
119
|
+
};
|
|
120
|
+
visit(value, void 0, "");
|
|
121
|
+
while (stack.length > 0) {
|
|
122
|
+
const frame = stack[stack.length - 1];
|
|
123
|
+
const object = frame.o;
|
|
124
|
+
if (frame.seen) {
|
|
125
|
+
stack.pop();
|
|
126
|
+
ancestors.delete(object);
|
|
127
|
+
continue;
|
|
128
|
+
}
|
|
129
|
+
if (ancestors.has(object)) fail(pathOf(frame), "cyclic references are not supported");
|
|
130
|
+
frame.seen = true;
|
|
131
|
+
ancestors.add(object);
|
|
132
|
+
const hasSymbols = Object.getOwnPropertySymbols(object).length > 0;
|
|
133
|
+
if (hasSymbols && isDeferred(object)) {
|
|
134
|
+
if (object.state === "fulfilled") visit(object.value, frame, "value");
|
|
135
|
+
continue;
|
|
136
|
+
}
|
|
137
|
+
const array = Array.isArray(object) ? object : void 0;
|
|
138
|
+
if (!array) {
|
|
139
|
+
const prototype = Object.getPrototypeOf(object);
|
|
140
|
+
if (prototype !== Object.prototype && prototype !== null) fail(pathOf(frame), `${objectLabel(object)} instances are not supported; use a plain object`);
|
|
141
|
+
}
|
|
142
|
+
if (hasSymbols) fail(pathOf(frame), "symbol-keyed properties are not supported");
|
|
143
|
+
const keys = Object.keys(object);
|
|
144
|
+
let named = false;
|
|
145
|
+
if (array) {
|
|
146
|
+
const length = array.length;
|
|
147
|
+
if (keys.length !== length || length > 0 && keys[length - 1] !== String(length - 1)) {
|
|
148
|
+
for (let index = 0; index < length; index += 1) if (!(index in array)) fail(pathOf(frame, String(index)), "sparse arrays are not supported");
|
|
149
|
+
named = true;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
const names = Object.getOwnPropertyNames(object);
|
|
153
|
+
if (names.length !== keys.length + (array ? 1 : 0)) {
|
|
154
|
+
for (const name of names) if (!(array && name === "length") && !keys.includes(name)) fail(pathOf(frame, name), "non-enumerable properties are not supported");
|
|
155
|
+
}
|
|
156
|
+
const firstChild = stack.length;
|
|
157
|
+
for (const key of keys) {
|
|
158
|
+
const descriptor = Object.getOwnPropertyDescriptor(object, key);
|
|
159
|
+
if (!("value" in descriptor)) fail(pathOf(frame, key), "accessors are not supported");
|
|
160
|
+
if (named && (!/^(?:0|[1-9]\d*)$/.test(key) || Number(key) >= array.length)) fail(pathOf(frame, key), "named array properties are not supported");
|
|
161
|
+
visit(descriptor.value, frame, key);
|
|
162
|
+
}
|
|
163
|
+
for (let low = firstChild, high = stack.length - 1; low < high;) {
|
|
164
|
+
const child = stack[low];
|
|
165
|
+
stack[low++] = stack[high];
|
|
166
|
+
stack[high--] = child;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
//#endregion
|
|
171
|
+
//#region src/common/telemetry.ts
|
|
172
|
+
function withTelemetry(span, fields, work) {
|
|
173
|
+
return span ? span(fields, work) : work();
|
|
174
|
+
}
|
|
175
|
+
//#endregion
|
|
176
|
+
//#region src/data/query-registry.ts
|
|
177
|
+
/** Pair a {@link QueryDefinition} with the server-side handler that resolves it. */
|
|
178
|
+
function serveQuery(query, handler) {
|
|
179
|
+
return Object.freeze({
|
|
180
|
+
query,
|
|
181
|
+
handler
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
/** Build a {@link ServerQueryRegistry} from one or more {@link serveQuery} entries. */
|
|
185
|
+
function defineServerQueries(...entries) {
|
|
186
|
+
const frozenEntries = Object.freeze([...entries]);
|
|
187
|
+
const handlers = new Map(entries.map((entry) => [entry.query, entry.handler]));
|
|
188
|
+
return Object.freeze({
|
|
189
|
+
entries: frozenEntries,
|
|
190
|
+
get(query) {
|
|
191
|
+
return handlers.get(query);
|
|
192
|
+
}
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
/** Freeze and return a reusable {@link QueryDefinition}. */
|
|
196
|
+
function defineQuery(definition) {
|
|
197
|
+
return Object.freeze({ ...definition });
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Throw when query data cannot cross the hydration JSON transport unchanged.
|
|
201
|
+
* SSR preloads check before anything streams; dehydration checks again.
|
|
202
|
+
*/
|
|
203
|
+
function assertQueryDataTransportSafe(key, value) {
|
|
204
|
+
validateJsonTransportValue(value, `Query data for key ${JSON.stringify(key)}`, "Return JSON-compatible query data.");
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Settle with `promise`, or reject with the reason of the first of `signals`
|
|
208
|
+
* to abort.
|
|
209
|
+
*/
|
|
210
|
+
function raceAbort(promise, signals) {
|
|
211
|
+
return new Promise((resolve, reject) => {
|
|
212
|
+
const abort = () => reject(signals.find((each) => each.aborted).reason);
|
|
213
|
+
for (const each of signals) {
|
|
214
|
+
if (each.aborted) abort();
|
|
215
|
+
each.addEventListener("abort", abort);
|
|
216
|
+
}
|
|
217
|
+
promise.then(resolve, reject).finally(() => {
|
|
218
|
+
for (const each of signals) each.removeEventListener("abort", abort);
|
|
219
|
+
});
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Create a {@link QueryPrefetchContext} for prefetching query data ahead of
|
|
224
|
+
* render, e.g. during SSR route resolution.
|
|
225
|
+
*/
|
|
226
|
+
function createQueryPrefetchContext(options = {}) {
|
|
227
|
+
const runtime = options.runtime ?? (options.mode === "spa" ? getDefaultDataRuntime() : createDataRuntime());
|
|
228
|
+
const signal = options.signal ?? new AbortController().signal;
|
|
229
|
+
const storePrefetchedValue = (key, value) => {
|
|
230
|
+
if (signal.aborted) return false;
|
|
231
|
+
if (runtime.queryCache.has(key)) return true;
|
|
232
|
+
const runtimeState = options.mode !== "ssr" && typeof window !== "undefined" ? findDataRuntimeState(runtime) : void 0;
|
|
233
|
+
if (runtimeState) writePrefetchedQueryData(runtimeState, key, value);
|
|
234
|
+
else {
|
|
235
|
+
if (options.mode === "ssr") assertQueryDataTransportSafe(key, value);
|
|
236
|
+
runtime.queryData.set(key, value);
|
|
237
|
+
}
|
|
238
|
+
return true;
|
|
239
|
+
};
|
|
240
|
+
return {
|
|
241
|
+
runtime,
|
|
242
|
+
request: options.request,
|
|
243
|
+
signal,
|
|
244
|
+
mode: options.mode ?? "spa",
|
|
245
|
+
async prefetch(query, input) {
|
|
246
|
+
return withTelemetry(options.telemetry?.queryPrefetch, {}, async () => {
|
|
247
|
+
const key = query.key(input);
|
|
248
|
+
if (runtime.queryCache.has(key) || runtime.queryData.has(key)) return true;
|
|
249
|
+
const handler = options.mode === "ssr" ? options.registry?.get(query) : void 0;
|
|
250
|
+
if (options.mode === "ssr" && !handler) return false;
|
|
251
|
+
const inflight = findDataRuntimeState(runtime)?.prefetches ?? /* @__PURE__ */ new Map();
|
|
252
|
+
for (;;) {
|
|
253
|
+
let pending = inflight.get(key);
|
|
254
|
+
const joined = pending !== void 0 && !(pending.signal.aborted && !signal.aborted);
|
|
255
|
+
if (!joined) {
|
|
256
|
+
let promise;
|
|
257
|
+
try {
|
|
258
|
+
promise = Promise.resolve(handler ? handler({
|
|
259
|
+
input,
|
|
260
|
+
request: options.request,
|
|
261
|
+
signal
|
|
262
|
+
}) : query.fetch(input, { signal }));
|
|
263
|
+
} catch (error) {
|
|
264
|
+
promise = Promise.reject(error);
|
|
265
|
+
}
|
|
266
|
+
pending = {
|
|
267
|
+
signal,
|
|
268
|
+
promise,
|
|
269
|
+
waiters: 0
|
|
270
|
+
};
|
|
271
|
+
inflight.set(key, pending);
|
|
272
|
+
}
|
|
273
|
+
const current = pending;
|
|
274
|
+
current.waiters += 1;
|
|
275
|
+
try {
|
|
276
|
+
let value;
|
|
277
|
+
try {
|
|
278
|
+
value = await (joined ? raceAbort(current.promise, [signal, current.signal]) : current.promise);
|
|
279
|
+
} catch (error) {
|
|
280
|
+
if (current.signal.aborted && !signal.aborted) continue;
|
|
281
|
+
throw error;
|
|
282
|
+
}
|
|
283
|
+
return !current.invalidated && storePrefetchedValue(key, value);
|
|
284
|
+
} finally {
|
|
285
|
+
current.waiters -= 1;
|
|
286
|
+
if (current.waiters === 0 && inflight.get(key) === current) inflight.delete(key);
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
/** Prefetch `query` with `input` into a {@link QueryPrefetchContext}'s runtime. */
|
|
294
|
+
async function prefetchQuery(context, query, input) {
|
|
295
|
+
return context.prefetch(query, input);
|
|
296
|
+
}
|
|
297
|
+
/**
|
|
298
|
+
* Extract a runtime's cached query data into a JSON-serializable snapshot.
|
|
299
|
+
* Throws a `TypeError` naming the key and path of any value that would not
|
|
300
|
+
* survive JSON transport unchanged (for example a `Date`, `Map`, or bigint).
|
|
301
|
+
*/
|
|
302
|
+
function dehydrateDataRuntime(runtime) {
|
|
303
|
+
const result = {};
|
|
304
|
+
for (const [key, value] of runtime.queryData) {
|
|
305
|
+
assertQueryDataTransportSafe(key, value);
|
|
306
|
+
result[key] = value;
|
|
307
|
+
}
|
|
308
|
+
return result;
|
|
309
|
+
}
|
|
310
|
+
/** Load a {@link dehydrateDataRuntime} snapshot back into a runtime's query cache. */
|
|
311
|
+
function hydrateDataRuntime(runtime, data) {
|
|
312
|
+
if (!data || typeof data !== "object" || Array.isArray(data)) return;
|
|
313
|
+
const runtimeState = findDataRuntimeState(runtime);
|
|
314
|
+
for (const [key, value] of Object.entries(data)) {
|
|
315
|
+
runtimeState?.unreadPrefetches.delete(key);
|
|
316
|
+
runtime.queryData.set(key, value);
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
//#endregion
|
|
320
|
+
export { hydrateDataRuntime as a, withTelemetry as c, DEFERRED_BOUNDARY as d, defer as f, dehydrateDataRuntime as i, jsonTransportPropertyPath as l, reviveDeferredValue as m, defineQuery as n, prefetchQuery as o, isDeferred as p, defineServerQueries as r, serveQuery as s, createQueryPrefetchContext as t, validateJsonTransportValue as u };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
//#region src/core/reactive/readable.ts
|
|
2
|
+
/**
|
|
3
|
+
* Readables: callables that read a reactive value (`state()` cells and
|
|
4
|
+
* `derive()` results). A function prop or child that returns a readable
|
|
5
|
+
* renders the readable's value.
|
|
6
|
+
*/
|
|
7
|
+
const READABLE = Symbol.for("askr.readable");
|
|
8
|
+
function markReadable(fn) {
|
|
9
|
+
Object.defineProperty(fn, READABLE, { value: true });
|
|
10
|
+
return fn;
|
|
11
|
+
}
|
|
12
|
+
function isReadable(value) {
|
|
13
|
+
return typeof value === "function" && value[READABLE] === true;
|
|
14
|
+
}
|
|
15
|
+
/** Call `fn`; if it returns a readable, read that too. */
|
|
16
|
+
function readValue(fn) {
|
|
17
|
+
const value = fn();
|
|
18
|
+
return isReadable(value) ? value() : value;
|
|
19
|
+
}
|
|
20
|
+
//#endregion
|
|
21
|
+
export { readValue as n, markReadable as t };
|
|
@@ -21,6 +21,7 @@ function createPageRenderEnvelope(input = {}) {
|
|
|
21
21
|
return Object.freeze({
|
|
22
22
|
version: PAGE_RENDER_ENVELOPE_VERSION,
|
|
23
23
|
resources: ownedRecord(input.resources),
|
|
24
|
+
...input.queries ? { queries: ownedRecord(input.queries) } : {},
|
|
24
25
|
route: input.route,
|
|
25
26
|
framework: ownedRecord(input.framework)
|
|
26
27
|
});
|
|
@@ -38,18 +39,14 @@ function pageRenderEnvelope(value, fallback = {}) {
|
|
|
38
39
|
});
|
|
39
40
|
}
|
|
40
41
|
function replacePageRoute(value, route) {
|
|
41
|
-
const current = pageRenderEnvelope(value);
|
|
42
42
|
return createPageRenderEnvelope({
|
|
43
|
-
|
|
44
|
-
route
|
|
45
|
-
framework: current.framework
|
|
43
|
+
...pageRenderEnvelope(value),
|
|
44
|
+
route
|
|
46
45
|
});
|
|
47
46
|
}
|
|
48
47
|
function withPageFramework(value, framework) {
|
|
49
|
-
const current = pageRenderEnvelope(value);
|
|
50
48
|
return createPageRenderEnvelope({
|
|
51
|
-
|
|
52
|
-
route: current.route,
|
|
49
|
+
...pageRenderEnvelope(value),
|
|
53
50
|
framework
|
|
54
51
|
});
|
|
55
52
|
}
|
|
@@ -69,7 +66,7 @@ function getHydrationRenderUrl(value) {
|
|
|
69
66
|
return typeof url === "string" ? url : void 0;
|
|
70
67
|
}
|
|
71
68
|
function isEmptyPageRenderEnvelope(value) {
|
|
72
|
-
return value.route === void 0 && Object.keys(value.resources).length === 0 && Object.keys(value.framework).length === 0;
|
|
69
|
+
return value.route === void 0 && Object.keys(value.resources).length === 0 && Object.keys(value.queries ?? {}).length === 0 && Object.keys(value.framework).length === 0;
|
|
73
70
|
}
|
|
74
71
|
//#endregion
|
|
75
72
|
//#region src/common/render-context.ts
|
|
@@ -86,6 +83,25 @@ function configureRenderContextProvider(nextProvider) {
|
|
|
86
83
|
function getActiveRenderContext() {
|
|
87
84
|
return provider.getRenderContext();
|
|
88
85
|
}
|
|
86
|
+
const deferredBoundaryParents = /* @__PURE__ */ new WeakMap();
|
|
87
|
+
/**
|
|
88
|
+
* Scope deferred boundaries registered in `context` under an already streamed
|
|
89
|
+
* parent boundary, so nested ids (`d:0.0`) never collide with top-level ones.
|
|
90
|
+
*/
|
|
91
|
+
function setDeferredBoundaryParent(context, parentId) {
|
|
92
|
+
deferredBoundaryParents.set(context, parentId);
|
|
93
|
+
}
|
|
94
|
+
/** Register a pending `Resolve` boundary for streaming and return its deterministic id. */
|
|
95
|
+
function registerDeferredBoundary(context, registration) {
|
|
96
|
+
const parent = deferredBoundaryParents.get(context);
|
|
97
|
+
const index = context.deferredBoundaries.length;
|
|
98
|
+
const id = parent === void 0 ? `d:${index}` : `${parent}.${index}`;
|
|
99
|
+
context.deferredBoundaries.push({
|
|
100
|
+
id,
|
|
101
|
+
...registration
|
|
102
|
+
});
|
|
103
|
+
return id;
|
|
104
|
+
}
|
|
89
105
|
/** Register request-local CSS produced during SSR without importing the SSR renderer in clients. */
|
|
90
106
|
function registerSSRStyle(id, cssText) {
|
|
91
107
|
const context = getActiveRenderContext();
|
|
@@ -129,8 +145,8 @@ function isHydrationVerificationRender() {
|
|
|
129
145
|
return hydrationVerificationDepth > 0;
|
|
130
146
|
}
|
|
131
147
|
/** @internal Read a server-captured resource branch without invoking its loader. */
|
|
132
|
-
function getResourceVerificationSnapshot(key) {
|
|
133
|
-
const snapshots =
|
|
148
|
+
function getResourceVerificationSnapshot(key, framework = getCurrentRenderData()?.framework) {
|
|
149
|
+
const snapshots = framework?.[RESOURCE_VERIFICATION_SNAPSHOTS];
|
|
134
150
|
if (!snapshots || typeof snapshots !== "object" || Array.isArray(snapshots)) return null;
|
|
135
151
|
if (!Object.prototype.hasOwnProperty.call(snapshots, key)) return null;
|
|
136
152
|
const snapshot = snapshots[key];
|
|
@@ -174,4 +190,4 @@ function throwSSRDataMissing() {
|
|
|
174
190
|
throw new SSRDataMissingError();
|
|
175
191
|
}
|
|
176
192
|
//#endregion
|
|
177
|
-
export {
|
|
193
|
+
export { withHydrationRenderUrl as C, replacePageRoute as S, SSRDataMissingError as T, createPageRenderEnvelope as _, getResourceVerificationSnapshot as a, isPageRenderEnvelope as b, registerDeferredBoundary as c, startHydrationRenderPhase as d, startRenderPhase as f, withHydrationVerificationRender as g, throwSSRDataMissing as h, getNextRenderKey as i, registerSSRStyle as l, stopRenderPhase as m, getActiveRenderContext as n, isHydrationVerificationRender as o, stopHydrationRenderPhase as p, getCurrentRenderData as r, recordResourceVerificationSnapshot as s, configureRenderContextProvider as t, setDeferredBoundaryParent as u, getHydrationRenderUrl as v, withPageFramework as w, pageRenderEnvelope as x, isEmptyPageRenderEnvelope as y };
|