@askrjs/askr 0.0.3 → 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -5
- package/dist/chunk-64C7W2AE.js +43 -0
- package/dist/chunk-64C7W2AE.js.map +1 -0
- package/dist/chunk-6FLMH4EL.js +124 -0
- package/dist/chunk-6FLMH4EL.js.map +1 -0
- package/dist/{chunk-JHOGWTAW.js → chunk-FJUXFA72.js} +2 -2
- package/dist/chunk-FJUXFA72.js.map +1 -0
- package/dist/{chunk-H3NSVHA7.js → chunk-VRAEBIJ3.js} +7 -5
- package/dist/chunk-VRAEBIJ3.js.map +1 -0
- package/dist/chunk-WTFWRSHB.js +98 -0
- package/dist/chunk-WTFWRSHB.js.map +1 -0
- package/dist/chunk-XHKZGJE3.js +2907 -0
- package/dist/chunk-XHKZGJE3.js.map +1 -0
- package/dist/chunk-Z5ZSTLYF.js +420 -0
- package/dist/chunk-Z5ZSTLYF.js.map +1 -0
- package/dist/fx/index.cjs +1193 -0
- package/dist/fx/index.cjs.map +1 -0
- package/dist/fx/index.d.cts +186 -0
- package/dist/fx/index.d.ts +186 -0
- package/dist/fx/index.js +418 -0
- package/dist/fx/index.js.map +1 -0
- package/dist/index.cjs +1369 -2525
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +74 -407
- package/dist/index.d.ts +74 -407
- package/dist/index.js +63 -803
- package/dist/index.js.map +1 -1
- package/dist/jsx/jsx-dev-runtime.cjs +1 -1
- package/dist/jsx/jsx-dev-runtime.cjs.map +1 -1
- package/dist/jsx/jsx-dev-runtime.d.cts +3 -2
- package/dist/jsx/jsx-dev-runtime.d.ts +3 -2
- package/dist/jsx/jsx-dev-runtime.js +1 -1
- package/dist/jsx/jsx-runtime.d.cts +2 -1
- package/dist/jsx/jsx-runtime.d.ts +2 -1
- package/dist/jsx/jsx-runtime.js +1 -1
- package/dist/{types-DLTViI21.d.cts → jsx-AzPM8gMS.d.cts} +6 -21
- package/dist/{types-DLTViI21.d.ts → jsx-AzPM8gMS.d.ts} +6 -21
- package/dist/{navigate-CZEUXFPM.js → navigate-LUVYHYZZ.js} +5 -4
- package/dist/resources/index.cjs +1200 -0
- package/dist/resources/index.cjs.map +1 -0
- package/dist/resources/index.d.cts +21 -0
- package/dist/resources/index.d.ts +21 -0
- package/dist/resources/index.js +278 -0
- package/dist/resources/index.js.map +1 -0
- package/dist/{route-USEXGOBT.js → route-BCND6MPK.js} +4 -3
- package/dist/{chunk-2ONGHQ7Z.js → router/index.cjs} +775 -643
- package/dist/router/index.cjs.map +1 -0
- package/dist/router/index.d.cts +64 -0
- package/dist/router/index.d.ts +64 -0
- package/dist/router/index.js +49 -0
- package/dist/router/index.js.map +1 -0
- package/dist/router-DaGtH1Sq.d.cts +36 -0
- package/dist/router-DaGtH1Sq.d.ts +36 -0
- package/dist/ssr/index.cjs +4059 -0
- package/dist/ssr/index.cjs.map +1 -0
- package/dist/ssr/index.d.cts +123 -0
- package/dist/ssr/index.d.ts +123 -0
- package/dist/{chunk-OFW6DFBM.js → ssr/index.js} +202 -252
- package/dist/ssr/index.js.map +1 -0
- package/dist/types-CZ5sWur5.d.cts +23 -0
- package/dist/types-CZHOAiC1.d.ts +23 -0
- package/package.json +19 -6
- package/src/jsx/types.ts +4 -17
- package/dist/chunk-2ONGHQ7Z.js.map +0 -1
- package/dist/chunk-H3NSVHA7.js.map +0 -1
- package/dist/chunk-JHOGWTAW.js.map +0 -1
- package/dist/chunk-OFW6DFBM.js.map +0 -1
- package/dist/ssr-QJ5NTQR6.js +0 -28
- package/dist/ssr-QJ5NTQR6.js.map +0 -1
- /package/dist/{navigate-CZEUXFPM.js.map → navigate-LUVYHYZZ.js.map} +0 -0
- /package/dist/{route-USEXGOBT.js.map → route-BCND6MPK.js.map} +0 -0
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
import {
|
|
2
|
+
state
|
|
3
|
+
} from "../chunk-6FLMH4EL.js";
|
|
4
|
+
import {
|
|
5
|
+
SSRDataMissingError,
|
|
6
|
+
getSSRBridge
|
|
7
|
+
} from "../chunk-64C7W2AE.js";
|
|
8
|
+
import {
|
|
9
|
+
getCurrentComponentInstance,
|
|
10
|
+
getCurrentContextFrame,
|
|
11
|
+
globalScheduler,
|
|
12
|
+
logger,
|
|
13
|
+
withAsyncResourceContext
|
|
14
|
+
} from "../chunk-XHKZGJE3.js";
|
|
15
|
+
import "../chunk-SALJX5PZ.js";
|
|
16
|
+
import "../chunk-FJUXFA72.js";
|
|
17
|
+
|
|
18
|
+
// src/runtime/resource-cell.ts
|
|
19
|
+
var ResourceCell = class {
|
|
20
|
+
constructor(fn, deps, resourceFrame) {
|
|
21
|
+
this.value = null;
|
|
22
|
+
this.pending = true;
|
|
23
|
+
this.error = null;
|
|
24
|
+
this.generation = 0;
|
|
25
|
+
this.controller = null;
|
|
26
|
+
this.deps = null;
|
|
27
|
+
this.resourceFrame = null;
|
|
28
|
+
this.subscribers = /* @__PURE__ */ new Set();
|
|
29
|
+
this.fn = fn;
|
|
30
|
+
this.deps = deps ? deps.slice() : null;
|
|
31
|
+
this.resourceFrame = resourceFrame;
|
|
32
|
+
this.snapshot = {
|
|
33
|
+
value: null,
|
|
34
|
+
pending: true,
|
|
35
|
+
error: null,
|
|
36
|
+
refresh: () => this.refresh()
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
subscribe(cb) {
|
|
40
|
+
this.subscribers.add(cb);
|
|
41
|
+
return () => this.subscribers.delete(cb);
|
|
42
|
+
}
|
|
43
|
+
notifySubscribers() {
|
|
44
|
+
this.snapshot.value = this.value;
|
|
45
|
+
this.snapshot.pending = this.pending;
|
|
46
|
+
this.snapshot.error = this.error;
|
|
47
|
+
for (const cb of this.subscribers) cb();
|
|
48
|
+
}
|
|
49
|
+
start(ssr = false, notify = true) {
|
|
50
|
+
const generation = this.generation;
|
|
51
|
+
this.controller?.abort();
|
|
52
|
+
const controller = new AbortController();
|
|
53
|
+
this.controller = controller;
|
|
54
|
+
this.pending = true;
|
|
55
|
+
this.error = null;
|
|
56
|
+
if (notify) this.notifySubscribers();
|
|
57
|
+
let result;
|
|
58
|
+
try {
|
|
59
|
+
result = withAsyncResourceContext(
|
|
60
|
+
this.resourceFrame,
|
|
61
|
+
() => this.fn({ signal: controller.signal })
|
|
62
|
+
);
|
|
63
|
+
} catch (err) {
|
|
64
|
+
this.pending = false;
|
|
65
|
+
this.error = err;
|
|
66
|
+
if (notify) this.notifySubscribers();
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
if (!(result instanceof Promise)) {
|
|
70
|
+
this.value = result;
|
|
71
|
+
this.pending = false;
|
|
72
|
+
this.error = null;
|
|
73
|
+
if (notify) this.notifySubscribers();
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
if (ssr) {
|
|
77
|
+
getSSRBridge().throwSSRDataMissing();
|
|
78
|
+
}
|
|
79
|
+
result.then((val) => {
|
|
80
|
+
if (this.generation !== generation) return;
|
|
81
|
+
if (this.controller !== controller) return;
|
|
82
|
+
this.value = val;
|
|
83
|
+
this.pending = false;
|
|
84
|
+
this.error = null;
|
|
85
|
+
this.notifySubscribers();
|
|
86
|
+
}).catch((err) => {
|
|
87
|
+
if (this.generation !== generation) return;
|
|
88
|
+
this.pending = false;
|
|
89
|
+
this.error = err;
|
|
90
|
+
try {
|
|
91
|
+
if (this.ownerName) {
|
|
92
|
+
logger.error(
|
|
93
|
+
`[Askr] Async resource error in ${this.ownerName}:`,
|
|
94
|
+
err
|
|
95
|
+
);
|
|
96
|
+
} else {
|
|
97
|
+
logger.error("[Askr] Async resource error:", err);
|
|
98
|
+
}
|
|
99
|
+
} catch {
|
|
100
|
+
}
|
|
101
|
+
this.notifySubscribers();
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
refresh() {
|
|
105
|
+
this.generation++;
|
|
106
|
+
this.controller?.abort();
|
|
107
|
+
this.start();
|
|
108
|
+
}
|
|
109
|
+
abort() {
|
|
110
|
+
this.controller?.abort();
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
// src/runtime/operations.ts
|
|
115
|
+
function resource(fn, deps = []) {
|
|
116
|
+
const instance = getCurrentComponentInstance();
|
|
117
|
+
const inst = instance;
|
|
118
|
+
if (!instance) {
|
|
119
|
+
const ssr2 = getSSRBridge();
|
|
120
|
+
const renderData2 = ssr2.getCurrentRenderData();
|
|
121
|
+
if (renderData2) {
|
|
122
|
+
const key = ssr2.getNextKey();
|
|
123
|
+
if (!(key in renderData2)) {
|
|
124
|
+
ssr2.throwSSRDataMissing();
|
|
125
|
+
}
|
|
126
|
+
const val = renderData2[key];
|
|
127
|
+
return {
|
|
128
|
+
value: val,
|
|
129
|
+
pending: false,
|
|
130
|
+
error: null,
|
|
131
|
+
refresh: () => {
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
const ssrCtx = ssr2.getCurrentSSRContext();
|
|
136
|
+
if (ssrCtx) {
|
|
137
|
+
ssr2.throwSSRDataMissing();
|
|
138
|
+
}
|
|
139
|
+
throw new Error(
|
|
140
|
+
"[Askr] resource() must be called during component render inside an app. Do not create resources at module scope or outside render."
|
|
141
|
+
);
|
|
142
|
+
}
|
|
143
|
+
const ssr = getSSRBridge();
|
|
144
|
+
const renderData = ssr.getCurrentRenderData();
|
|
145
|
+
if (renderData) {
|
|
146
|
+
const key = ssr.getNextKey();
|
|
147
|
+
if (!(key in renderData)) {
|
|
148
|
+
ssr.throwSSRDataMissing();
|
|
149
|
+
}
|
|
150
|
+
const val = renderData[key];
|
|
151
|
+
const holder2 = state({
|
|
152
|
+
cell: void 0,
|
|
153
|
+
snapshot: {
|
|
154
|
+
value: val,
|
|
155
|
+
pending: false,
|
|
156
|
+
error: null,
|
|
157
|
+
refresh: () => {
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
const h2 = holder2();
|
|
162
|
+
h2.snapshot.value = val;
|
|
163
|
+
h2.snapshot.pending = false;
|
|
164
|
+
h2.snapshot.error = null;
|
|
165
|
+
holder2.set(h2);
|
|
166
|
+
return h2.snapshot;
|
|
167
|
+
}
|
|
168
|
+
const holder = state(
|
|
169
|
+
{
|
|
170
|
+
cell: void 0,
|
|
171
|
+
snapshot: {
|
|
172
|
+
value: null,
|
|
173
|
+
pending: true,
|
|
174
|
+
error: null,
|
|
175
|
+
refresh: () => {
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
);
|
|
180
|
+
const h = holder();
|
|
181
|
+
if (!h.cell) {
|
|
182
|
+
const frame = getCurrentContextFrame();
|
|
183
|
+
const cell2 = new ResourceCell(fn, deps, frame);
|
|
184
|
+
cell2.ownerName = inst.fn?.name || "<anonymous>";
|
|
185
|
+
h.cell = cell2;
|
|
186
|
+
h.snapshot = cell2.snapshot;
|
|
187
|
+
const unsubscribe = cell2.subscribe(() => {
|
|
188
|
+
const cur = holder();
|
|
189
|
+
cur.snapshot.value = cell2.snapshot.value;
|
|
190
|
+
cur.snapshot.pending = cell2.snapshot.pending;
|
|
191
|
+
cur.snapshot.error = cell2.snapshot.error;
|
|
192
|
+
holder.set(cur);
|
|
193
|
+
try {
|
|
194
|
+
inst._enqueueRun?.();
|
|
195
|
+
} catch {
|
|
196
|
+
}
|
|
197
|
+
});
|
|
198
|
+
inst.cleanupFns.push(() => {
|
|
199
|
+
unsubscribe();
|
|
200
|
+
cell2.abort();
|
|
201
|
+
});
|
|
202
|
+
if (inst.ssr) {
|
|
203
|
+
cell2.start(true, false);
|
|
204
|
+
if (!cell2.pending) {
|
|
205
|
+
const cur = holder();
|
|
206
|
+
cur.snapshot.value = cell2.value;
|
|
207
|
+
cur.snapshot.pending = cell2.pending;
|
|
208
|
+
cur.snapshot.error = cell2.error;
|
|
209
|
+
}
|
|
210
|
+
} else {
|
|
211
|
+
globalScheduler.enqueue(() => {
|
|
212
|
+
try {
|
|
213
|
+
cell2.start(false, false);
|
|
214
|
+
} catch (err) {
|
|
215
|
+
const cur = holder();
|
|
216
|
+
cur.snapshot.value = cell2.value;
|
|
217
|
+
cur.snapshot.pending = cell2.pending;
|
|
218
|
+
cur.snapshot.error = err ?? null;
|
|
219
|
+
holder.set(cur);
|
|
220
|
+
inst._enqueueRun?.();
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
if (!cell2.pending) {
|
|
224
|
+
const cur = holder();
|
|
225
|
+
cur.snapshot.value = cell2.value;
|
|
226
|
+
cur.snapshot.pending = cell2.pending;
|
|
227
|
+
cur.snapshot.error = cell2.error;
|
|
228
|
+
holder.set(cur);
|
|
229
|
+
inst._enqueueRun?.();
|
|
230
|
+
}
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
const cell = h.cell;
|
|
235
|
+
const depsChanged = !cell.deps || cell.deps.length !== deps.length || cell.deps.some((d, i) => d !== deps[i]);
|
|
236
|
+
if (depsChanged) {
|
|
237
|
+
cell.deps = deps.slice();
|
|
238
|
+
cell.generation++;
|
|
239
|
+
cell.pending = true;
|
|
240
|
+
cell.error = null;
|
|
241
|
+
try {
|
|
242
|
+
if (inst.ssr) {
|
|
243
|
+
cell.start(true, false);
|
|
244
|
+
if (!cell.pending) {
|
|
245
|
+
const cur = holder();
|
|
246
|
+
cur.snapshot.value = cell.value;
|
|
247
|
+
cur.snapshot.pending = cell.pending;
|
|
248
|
+
cur.snapshot.error = cell.error;
|
|
249
|
+
}
|
|
250
|
+
} else {
|
|
251
|
+
globalScheduler.enqueue(() => {
|
|
252
|
+
cell.start(false, false);
|
|
253
|
+
if (!cell.pending) {
|
|
254
|
+
const cur = holder();
|
|
255
|
+
cur.snapshot.value = cell.value;
|
|
256
|
+
cur.snapshot.pending = cell.pending;
|
|
257
|
+
cur.snapshot.error = cell.error;
|
|
258
|
+
holder.set(cur);
|
|
259
|
+
inst._enqueueRun?.();
|
|
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
|
+
export {
|
|
276
|
+
resource
|
|
277
|
+
};
|
|
278
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/runtime/resource-cell.ts","../../src/runtime/operations.ts"],"sourcesContent":["import { withAsyncResourceContext, type ContextFrame } from './context';\nimport { logger } from '../dev/logger';\nimport { getSSRBridge } from './ssr-bridge';\n\n/**\n * Pure, component-agnostic ResourceCell state machine.\n * - Holds value/pending/error/generation/controller\n * - Exposes a stable `snapshot` object: { value, pending, error, refresh }\n * - Uses `withAsyncResourceContext` to bind the synchronous execution step\n * to a captured frame. Continuations after await do not see the frame.\n */\nexport class ResourceCell<U> {\n value: U | null = null;\n pending = true;\n error: Error | null = null;\n generation = 0;\n controller: AbortController | null = null;\n deps: unknown[] | null = null;\n resourceFrame: ContextFrame | null = null;\n\n // Optional debug label set by caller (component name) to improve logs\n ownerName?: string;\n\n private subscribers = new Set<() => void>();\n\n readonly snapshot: {\n value: U | null;\n pending: boolean;\n error: Error | null;\n refresh: () => void;\n };\n\n private readonly fn: (opts: { signal: AbortSignal }) => Promise<U> | U;\n\n constructor(\n fn: (opts: { signal: AbortSignal }) => Promise<U> | U,\n deps: unknown[] | null,\n resourceFrame: ContextFrame | null\n ) {\n this.fn = fn;\n this.deps = deps ? deps.slice() : null;\n this.resourceFrame = resourceFrame;\n this.snapshot = {\n value: null,\n pending: true,\n error: null,\n refresh: () => this.refresh(),\n };\n }\n\n subscribe(cb: () => void): () => void {\n this.subscribers.add(cb);\n return () => this.subscribers.delete(cb);\n }\n\n private notifySubscribers() {\n this.snapshot.value = this.value;\n this.snapshot.pending = this.pending;\n this.snapshot.error = this.error;\n for (const cb of this.subscribers) cb();\n }\n\n start(ssr = false, notify = true) {\n const generation = this.generation;\n\n this.controller?.abort();\n const controller = new AbortController();\n this.controller = controller;\n this.pending = true;\n this.error = null;\n if (notify) this.notifySubscribers();\n\n let result: Promise<U> | U;\n try {\n // Execute only the synchronous step inside the frozen resource frame.\n result = withAsyncResourceContext(this.resourceFrame, () =>\n this.fn({ signal: controller.signal })\n );\n } catch (err) {\n this.pending = false;\n this.error = err as Error;\n if (notify) this.notifySubscribers();\n return;\n }\n\n if (!(result instanceof Promise)) {\n this.value = result as U;\n this.pending = false;\n this.error = null;\n if (notify) this.notifySubscribers();\n return;\n }\n\n if (ssr) {\n // During SSR async results are disallowed\n getSSRBridge().throwSSRDataMissing();\n }\n\n (result as Promise<U>)\n .then((val) => {\n if (this.generation !== generation) return;\n if (this.controller !== controller) return;\n this.value = val;\n this.pending = false;\n this.error = null;\n this.notifySubscribers();\n })\n .catch((err) => {\n if (this.generation !== generation) return;\n this.pending = false;\n this.error = err as Error;\n try {\n if (this.ownerName) {\n logger.error(\n `[Askr] Async resource error in ${this.ownerName}:`,\n err\n );\n } else {\n logger.error('[Askr] Async resource error:', err);\n }\n } catch {\n /* ignore logging errors */\n }\n this.notifySubscribers();\n });\n }\n\n refresh() {\n this.generation++;\n this.controller?.abort();\n this.start();\n }\n\n abort() {\n this.controller?.abort();\n }\n}\n","import {\n getCurrentComponentInstance,\n registerMountOperation,\n type ComponentInstance,\n} from './component';\nimport { getCurrentContextFrame } from './context';\nimport { ResourceCell } from './resource-cell';\nimport { state } from './state';\nimport { globalScheduler } from './scheduler';\nimport { getSSRBridge } from './ssr-bridge';\nimport { SSRDataMissingError } from '../common/ssr-errors';\n\n// Memoization cache for derive() (centralized)\n\nexport interface ResourceResult<T> {\n value: T | null;\n pending: boolean;\n error: Error | null;\n refresh(): void;\n}\n\n/**\n * Resource primitive — simple, deterministic async primitive\n * Usage: resource(fn, deps)\n * - fn receives { signal }\n * - captures execution context once at creation (synchronous step only)\n * - executes at most once per generation; stale async results are ignored\n * - refresh() cancels in-flight execution, increments generation and re-runs\n * - exposes { value, pending, error, refresh }\n * - during SSR, async results are disallowed and will throw synchronously\n */\nexport function resource<T>(\n fn: (opts: { signal: AbortSignal }) => Promise<T> | T,\n deps: unknown[] = []\n): ResourceResult<T> {\n const instance = getCurrentComponentInstance();\n // Create a non-null alias early so it can be used in nested closures\n // without TypeScript complaining about possible null access.\n const inst = instance as ComponentInstance;\n\n if (!instance) {\n const ssr = getSSRBridge();\n // If we're in a synchronous SSR render that has resolved data, use it.\n const renderData = ssr.getCurrentRenderData();\n if (renderData) {\n const key = ssr.getNextKey();\n if (!(key in renderData)) {\n ssr.throwSSRDataMissing();\n }\n const val = renderData[key] as T;\n return {\n value: val,\n pending: false,\n error: null,\n refresh: () => {},\n } as ResourceResult<T>;\n }\n\n // If we are in an SSR render pass without supplied data, throw for clarity.\n const ssrCtx = ssr.getCurrentSSRContext();\n if (ssrCtx) {\n ssr.throwSSRDataMissing();\n }\n\n // No active component instance and not in SSR render with data.\n // Autopilot invariant: resources must be created during render within an app.\n throw new Error(\n '[Askr] resource() must be called during component render inside an app. ' +\n 'Do not create resources at module scope or outside render.'\n );\n }\n\n // Internal ResourceCell — pure state machine now moved to its own module\n // to keep component wiring separate and ensure no component access here.\n // (See ./resource-cell.ts)\n\n // If we're in a synchronous SSR render that was supplied resolved data, use it\n const ssr = getSSRBridge();\n const renderData = ssr.getCurrentRenderData();\n if (renderData) {\n // Deterministic key generation: the collection step and render step use\n // the same incremental key generation to align resources.\n const key = ssr.getNextKey();\n if (!(key in renderData)) {\n ssr.throwSSRDataMissing();\n }\n\n // Commit synchronous value from render data and return a stable snapshot\n const val = renderData[key] as T;\n\n const holder = state<{\n cell?: ResourceCell<T>;\n snapshot: ResourceResult<T>;\n }>({\n cell: undefined,\n snapshot: {\n value: val,\n pending: false,\n error: null,\n refresh: () => {},\n },\n });\n\n const h = holder();\n h.snapshot.value = val;\n h.snapshot.pending = false;\n h.snapshot.error = null;\n holder.set(h);\n return h.snapshot;\n }\n\n // Persist a holder so the snapshot identity is stable across renders.\n const holder = state<{ cell?: ResourceCell<T>; snapshot: ResourceResult<T> }>(\n {\n cell: undefined,\n snapshot: {\n value: null,\n pending: true,\n error: null,\n refresh: () => {},\n },\n }\n );\n\n const h = holder();\n\n // Initialize cell on first call\n if (!h.cell) {\n const frame = getCurrentContextFrame();\n const cell = new ResourceCell<T>(fn, deps, frame);\n // Attach debug label (component name) for richer logs\n cell.ownerName = inst.fn?.name || '<anonymous>';\n h.cell = cell;\n h.snapshot = cell.snapshot as ResourceResult<T>;\n\n // Subscribe and schedule component updates when cell changes\n const unsubscribe = cell.subscribe(() => {\n const cur = holder();\n cur.snapshot.value = cell.snapshot.value;\n cur.snapshot.pending = cell.snapshot.pending;\n cur.snapshot.error = cell.snapshot.error;\n holder.set(cur);\n try {\n inst._enqueueRun?.();\n } catch {\n // ignore\n }\n });\n\n // Cleanup on unmount\n inst.cleanupFns.push(() => {\n unsubscribe();\n cell.abort();\n });\n\n // Render invariant: do NOT start async work during render on the client.\n // SSR remains strict/synchronous and must throw immediately if async is encountered.\n if (inst.ssr) {\n // SSR: must run synchronously so missing data throws during render\n cell.start(true, false);\n if (!cell.pending) {\n const cur = holder();\n cur.snapshot.value = cell.value;\n cur.snapshot.pending = cell.pending;\n cur.snapshot.error = cell.error;\n }\n } else {\n // Client: start after render via scheduler (never inline)\n globalScheduler.enqueue(() => {\n try {\n cell.start(false, false);\n } catch (err) {\n // Non-SSR: reflect synchronous errors into snapshot via manual update\n const cur = holder();\n cur.snapshot.value = cell.value;\n cur.snapshot.pending = cell.pending;\n cur.snapshot.error = (err as Error) ?? null;\n holder.set(cur);\n inst._enqueueRun?.();\n return;\n }\n\n // If the resource completed synchronously, subscribers were not notified.\n // Force a re-render so the component can observe the value.\n if (!cell.pending) {\n const cur = holder();\n cur.snapshot.value = cell.value;\n cur.snapshot.pending = cell.pending;\n cur.snapshot.error = cell.error;\n holder.set(cur);\n inst._enqueueRun?.();\n }\n });\n }\n }\n\n const cell = h.cell!;\n\n // Detect dependency changes and refresh immediately\n const depsChanged =\n !cell.deps ||\n cell.deps.length !== deps.length ||\n cell.deps.some((d, i) => d !== deps[i]);\n\n if (depsChanged) {\n cell.deps = deps.slice();\n cell.generation++;\n cell.pending = true;\n cell.error = null;\n try {\n if (inst.ssr) {\n cell.start(true, false);\n if (!cell.pending) {\n const cur = holder();\n cur.snapshot.value = cell.value;\n cur.snapshot.pending = cell.pending;\n cur.snapshot.error = cell.error;\n }\n } else {\n globalScheduler.enqueue(() => {\n cell.start(false, false);\n if (!cell.pending) {\n const cur = holder();\n cur.snapshot.value = cell.value;\n cur.snapshot.pending = cell.pending;\n cur.snapshot.error = cell.error;\n holder.set(cur);\n inst._enqueueRun?.();\n }\n });\n }\n } catch (err) {\n if (err instanceof SSRDataMissingError) throw err;\n cell.error = err as Error;\n cell.pending = false;\n const cur = holder();\n cur.snapshot.value = cell.value;\n cur.snapshot.pending = cell.pending;\n cur.snapshot.error = cell.error;\n // Do not call holder.set() here; this is still render.\n }\n }\n\n // Return the stable snapshot object owned by the cell\n return h.snapshot;\n}\n\nexport function on(\n target: EventTarget,\n event: string,\n handler: EventListener\n): void {\n const ownerIsRoot = getCurrentComponentInstance()?.isRoot ?? false;\n // Register the listener to be attached on mount. If the owner is not the\n // root app instance, fail loudly to prevent silent no-op behavior.\n registerMountOperation(() => {\n if (!ownerIsRoot) {\n throw new Error('[Askr] on() may only be used in root components');\n }\n target.addEventListener(event, handler);\n // Return cleanup function\n return () => {\n target.removeEventListener(event, handler);\n };\n });\n}\n\nexport function timer(intervalMs: number, fn: () => void): void {\n const ownerIsRoot = getCurrentComponentInstance()?.isRoot ?? false;\n // Register the timer to be started on mount. Fail loudly when used outside\n // of the root component to avoid silent no-ops.\n registerMountOperation(() => {\n if (!ownerIsRoot) {\n throw new Error('[Askr] timer() may only be used in root components');\n }\n const id = setInterval(fn, intervalMs);\n // Return cleanup function\n return () => {\n clearInterval(id);\n };\n });\n}\n\nexport function stream<T>(\n _source: unknown,\n _options?: Record<string, unknown>\n): { value: T | null; pending: boolean; error: Error | null } {\n // Stub implementation: no-op.\n return { value: null, pending: true, error: null };\n}\n\nexport function task(\n fn: () => void | (() => void) | Promise<void | (() => void)>\n): void {\n const ownerIsRoot = getCurrentComponentInstance()?.isRoot ?? false;\n // Register the task to run on mount. Fail loudly when used outside the root\n // component so callers get immediate feedback rather than silent no-op.\n registerMountOperation(async () => {\n if (!ownerIsRoot) {\n throw new Error('[Askr] task() may only be used in root components');\n }\n // Execute the task (may be async) and return its cleanup\n return await fn();\n });\n}\n\n/**\n * Capture the result of a synchronous expression at call time and return a\n * thunk that returns the captured value later. This is a low-level helper for\n * cases where async continuations need to observe a snapshot of values at the\n * moment scheduling occurred.\n *\n * Usage (public API):\n * const snapshot = capture(() => someState());\n * Promise.resolve().then(() => { use(snapshot()); });\n */\nexport function capture<T>(fn: () => T): () => T {\n const value = fn();\n return () => value;\n}\n"],"mappings":"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","names":["ssr","renderData","holder","h","cell"]}
|
|
@@ -11,9 +11,10 @@ import {
|
|
|
11
11
|
route,
|
|
12
12
|
setServerLocation,
|
|
13
13
|
unloadNamespace
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-Z5ZSTLYF.js";
|
|
15
|
+
import "./chunk-XHKZGJE3.js";
|
|
15
16
|
import "./chunk-SALJX5PZ.js";
|
|
16
|
-
import "./chunk-
|
|
17
|
+
import "./chunk-FJUXFA72.js";
|
|
17
18
|
export {
|
|
18
19
|
_lockRouteRegistrationForTests,
|
|
19
20
|
_unlockRouteRegistrationForTests,
|
|
@@ -28,4 +29,4 @@ export {
|
|
|
28
29
|
setServerLocation,
|
|
29
30
|
unloadNamespace
|
|
30
31
|
};
|
|
31
|
-
//# sourceMappingURL=route-
|
|
32
|
+
//# sourceMappingURL=route-BCND6MPK.js.map
|