@askrjs/askr 0.0.1
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/LICENSE +201 -0
- package/README.md +298 -0
- package/dist/chunk-4CV4JOE5.js +27 -0
- package/dist/chunk-4CV4JOE5.js.map +1 -0
- package/dist/chunk-HIWJVOS4.js +503 -0
- package/dist/chunk-HIWJVOS4.js.map +1 -0
- package/dist/chunk-L7RL4LYV.js +3442 -0
- package/dist/chunk-L7RL4LYV.js.map +1 -0
- package/dist/chunk-UUM5W2RM.js +84 -0
- package/dist/chunk-UUM5W2RM.js.map +1 -0
- package/dist/chunk-YNH3D4KW.js +29 -0
- package/dist/chunk-YNH3D4KW.js.map +1 -0
- package/dist/index.cjs +4733 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +446 -0
- package/dist/index.d.ts +446 -0
- package/dist/index.js +683 -0
- package/dist/index.js.map +1 -0
- package/dist/jsx/jsx-dev-runtime.cjs +40 -0
- package/dist/jsx/jsx-dev-runtime.cjs.map +1 -0
- package/dist/jsx/jsx-dev-runtime.d.cts +16 -0
- package/dist/jsx/jsx-dev-runtime.d.ts +16 -0
- package/dist/jsx/jsx-dev-runtime.js +16 -0
- package/dist/jsx/jsx-dev-runtime.js.map +1 -0
- package/dist/jsx/jsx-runtime.cjs +45 -0
- package/dist/jsx/jsx-runtime.cjs.map +1 -0
- package/dist/jsx/jsx-runtime.d.cts +17 -0
- package/dist/jsx/jsx-runtime.d.ts +17 -0
- package/dist/jsx/jsx-runtime.js +14 -0
- package/dist/jsx/jsx-runtime.js.map +1 -0
- package/dist/navigate-NLQOZQGM.js +16 -0
- package/dist/navigate-NLQOZQGM.js.map +1 -0
- package/dist/route-TVYWYCEJ.js +31 -0
- package/dist/route-TVYWYCEJ.js.map +1 -0
- package/dist/ssr-4ELUFK65.js +24 -0
- package/dist/ssr-4ELUFK65.js.map +1 -0
- package/dist/types-DUDmnzD8.d.cts +38 -0
- package/dist/types-DUDmnzD8.d.ts +38 -0
- package/package.json +83 -0
- package/src/jsx/jsx-dev-runtime.ts +26 -0
- package/src/jsx/jsx-runtime.ts +36 -0
- package/src/jsx/react-jsx-runtime.d.ts +0 -0
- package/src/jsx/types.ts +27 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,683 @@
|
|
|
1
|
+
import {
|
|
2
|
+
initializeNavigation,
|
|
3
|
+
navigate,
|
|
4
|
+
registerAppInstance
|
|
5
|
+
} from "./chunk-UUM5W2RM.js";
|
|
6
|
+
import {
|
|
7
|
+
SSRDataMissingError,
|
|
8
|
+
collectResources,
|
|
9
|
+
getCurrentRenderData,
|
|
10
|
+
getCurrentSSRContext,
|
|
11
|
+
getNextKey,
|
|
12
|
+
renderToStream,
|
|
13
|
+
renderToString,
|
|
14
|
+
renderToStringSync,
|
|
15
|
+
renderToStringSyncForUrl,
|
|
16
|
+
resolveResources,
|
|
17
|
+
throwSSRDataMissing
|
|
18
|
+
} from "./chunk-HIWJVOS4.js";
|
|
19
|
+
import {
|
|
20
|
+
cleanupComponent,
|
|
21
|
+
clearRoutes,
|
|
22
|
+
createComponentInstance,
|
|
23
|
+
defineContext,
|
|
24
|
+
getCurrentComponentInstance,
|
|
25
|
+
getCurrentContextFrame,
|
|
26
|
+
getCurrentInstance,
|
|
27
|
+
getLoadedNamespaces,
|
|
28
|
+
getNamespaceRoutes,
|
|
29
|
+
getNextStateIndex,
|
|
30
|
+
getRoutes,
|
|
31
|
+
getSignal,
|
|
32
|
+
globalScheduler,
|
|
33
|
+
init_component,
|
|
34
|
+
init_context,
|
|
35
|
+
init_dom,
|
|
36
|
+
init_fastlane,
|
|
37
|
+
init_invariant,
|
|
38
|
+
init_logger,
|
|
39
|
+
init_scheduler,
|
|
40
|
+
invariant,
|
|
41
|
+
isBulkCommitActive,
|
|
42
|
+
logger,
|
|
43
|
+
mountComponent,
|
|
44
|
+
readContext,
|
|
45
|
+
removeAllListeners,
|
|
46
|
+
route,
|
|
47
|
+
scheduleEventHandler,
|
|
48
|
+
setServerLocation,
|
|
49
|
+
unloadNamespace,
|
|
50
|
+
withAsyncResourceContext
|
|
51
|
+
} from "./chunk-L7RL4LYV.js";
|
|
52
|
+
import {
|
|
53
|
+
Fragment,
|
|
54
|
+
init_jsx_runtime,
|
|
55
|
+
jsx,
|
|
56
|
+
jsxs
|
|
57
|
+
} from "./chunk-YNH3D4KW.js";
|
|
58
|
+
import "./chunk-4CV4JOE5.js";
|
|
59
|
+
|
|
60
|
+
// src/runtime/state.ts
|
|
61
|
+
init_scheduler();
|
|
62
|
+
init_component();
|
|
63
|
+
init_invariant();
|
|
64
|
+
init_fastlane();
|
|
65
|
+
function state(initialValue) {
|
|
66
|
+
const instance = getCurrentInstance();
|
|
67
|
+
if (!instance) {
|
|
68
|
+
throw new Error(
|
|
69
|
+
"state() can only be called during component render execution. Move state() calls to the top level of your component function."
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
const index = getNextStateIndex();
|
|
73
|
+
const stateValues = instance.stateValues;
|
|
74
|
+
if (index < instance.stateIndexCheck) {
|
|
75
|
+
throw new Error(
|
|
76
|
+
`State index violation: state() call at index ${index}, but previously saw index ${instance.stateIndexCheck}. This happens when state() is called conditionally (inside if/for/etc). Move all state() calls to the top level of your component function, before any conditionals.`
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
invariant(
|
|
80
|
+
index >= instance.stateIndexCheck,
|
|
81
|
+
"[State] State indices must increase monotonically"
|
|
82
|
+
);
|
|
83
|
+
instance.stateIndexCheck = index;
|
|
84
|
+
if (instance.firstRenderComplete) {
|
|
85
|
+
if (!instance.expectedStateIndices.includes(index)) {
|
|
86
|
+
throw new Error(
|
|
87
|
+
`Hook order violation: state() called at index ${index}, but this index was not in the first render's sequence [${instance.expectedStateIndices.join(", ")}]. This usually means state() is inside a conditional or loop. Move all state() calls to the top level of your component function.`
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
} else {
|
|
91
|
+
instance.expectedStateIndices.push(index);
|
|
92
|
+
}
|
|
93
|
+
if (stateValues[index]) {
|
|
94
|
+
const existing = stateValues[index];
|
|
95
|
+
if (existing._owner !== instance) {
|
|
96
|
+
throw new Error(
|
|
97
|
+
`State ownership violation: state() called at index ${index} is owned by a different component instance. State ownership is positional and immutable.`
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
return existing;
|
|
101
|
+
}
|
|
102
|
+
const cell = createStateCell(initialValue, instance);
|
|
103
|
+
stateValues[index] = cell;
|
|
104
|
+
return cell;
|
|
105
|
+
}
|
|
106
|
+
function createStateCell(initialValue, instance) {
|
|
107
|
+
let value = initialValue;
|
|
108
|
+
const readers = /* @__PURE__ */ new Map();
|
|
109
|
+
function read() {
|
|
110
|
+
read._hasBeenRead = true;
|
|
111
|
+
const inst = getCurrentInstance();
|
|
112
|
+
if (inst && inst._currentRenderToken !== void 0) {
|
|
113
|
+
if (!inst._pendingReadStates) inst._pendingReadStates = /* @__PURE__ */ new Set();
|
|
114
|
+
inst._pendingReadStates.add(read);
|
|
115
|
+
}
|
|
116
|
+
return value;
|
|
117
|
+
}
|
|
118
|
+
read._readers = readers;
|
|
119
|
+
read._owner = instance;
|
|
120
|
+
read.set = (newValue) => {
|
|
121
|
+
const currentInst = getCurrentInstance();
|
|
122
|
+
if (currentInst !== null && process.env.NODE_ENV !== "production") {
|
|
123
|
+
throw new Error(
|
|
124
|
+
`[Askr] state.set() cannot be called during component render. State mutations during render break the actor model and cause infinite loops. Move state updates to event handlers or use conditional rendering instead.`
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
if (currentInst !== null && process.env.NODE_ENV === "production") {
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
if (Object.is(value, newValue)) return;
|
|
131
|
+
if (isBulkCommitActive()) {
|
|
132
|
+
value = newValue;
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
value = newValue;
|
|
136
|
+
const readersMap = read._readers;
|
|
137
|
+
if (readersMap) {
|
|
138
|
+
for (const [subInst, token] of readersMap) {
|
|
139
|
+
if (subInst.lastRenderToken !== token) continue;
|
|
140
|
+
if (!subInst.hasPendingUpdate) {
|
|
141
|
+
subInst.hasPendingUpdate = true;
|
|
142
|
+
const subTask = subInst._pendingFlushTask;
|
|
143
|
+
if (subTask) globalScheduler.enqueue(subTask);
|
|
144
|
+
else
|
|
145
|
+
globalScheduler.enqueue(() => {
|
|
146
|
+
subInst.hasPendingUpdate = false;
|
|
147
|
+
subInst.notifyUpdate?.();
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
const readersMapForOwner = readersMap;
|
|
153
|
+
const ownerRecordedToken = readersMapForOwner?.get(instance);
|
|
154
|
+
const ownerShouldEnqueue = (
|
|
155
|
+
// Normal case: owner read this state in last committed render
|
|
156
|
+
ownerRecordedToken !== void 0 && instance.lastRenderToken === ownerRecordedToken
|
|
157
|
+
);
|
|
158
|
+
if (ownerShouldEnqueue && !instance.hasPendingUpdate) {
|
|
159
|
+
instance.hasPendingUpdate = true;
|
|
160
|
+
const task = instance._pendingFlushTask;
|
|
161
|
+
if (task) globalScheduler.enqueue(task);
|
|
162
|
+
else
|
|
163
|
+
globalScheduler.enqueue(() => {
|
|
164
|
+
instance.hasPendingUpdate = false;
|
|
165
|
+
instance.notifyUpdate?.();
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
};
|
|
169
|
+
return read;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// src/index.ts
|
|
173
|
+
init_component();
|
|
174
|
+
init_scheduler();
|
|
175
|
+
init_context();
|
|
176
|
+
|
|
177
|
+
// src/runtime/operations.ts
|
|
178
|
+
init_component();
|
|
179
|
+
init_context();
|
|
180
|
+
|
|
181
|
+
// src/runtime/resource_cell.ts
|
|
182
|
+
init_context();
|
|
183
|
+
init_logger();
|
|
184
|
+
var ResourceCell = class {
|
|
185
|
+
constructor(fn, deps, resourceFrame) {
|
|
186
|
+
this.value = null;
|
|
187
|
+
this.pending = true;
|
|
188
|
+
this.error = null;
|
|
189
|
+
this.generation = 0;
|
|
190
|
+
this.controller = null;
|
|
191
|
+
this.deps = null;
|
|
192
|
+
this.resourceFrame = null;
|
|
193
|
+
this.subscribers = /* @__PURE__ */ new Set();
|
|
194
|
+
this.fn = fn;
|
|
195
|
+
this.deps = deps ? deps.slice() : null;
|
|
196
|
+
this.resourceFrame = resourceFrame;
|
|
197
|
+
this.snapshot = {
|
|
198
|
+
value: null,
|
|
199
|
+
pending: true,
|
|
200
|
+
error: null,
|
|
201
|
+
refresh: () => this.refresh()
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
subscribe(cb) {
|
|
205
|
+
this.subscribers.add(cb);
|
|
206
|
+
return () => this.subscribers.delete(cb);
|
|
207
|
+
}
|
|
208
|
+
notifySubscribers() {
|
|
209
|
+
this.snapshot.value = this.value;
|
|
210
|
+
this.snapshot.pending = this.pending;
|
|
211
|
+
this.snapshot.error = this.error;
|
|
212
|
+
for (const cb of this.subscribers) cb();
|
|
213
|
+
}
|
|
214
|
+
start(ssr = false, notify = true) {
|
|
215
|
+
const generation = this.generation;
|
|
216
|
+
this.controller?.abort();
|
|
217
|
+
const controller = new AbortController();
|
|
218
|
+
this.controller = controller;
|
|
219
|
+
this.pending = true;
|
|
220
|
+
this.error = null;
|
|
221
|
+
if (notify) this.notifySubscribers();
|
|
222
|
+
let result;
|
|
223
|
+
try {
|
|
224
|
+
result = withAsyncResourceContext(
|
|
225
|
+
this.resourceFrame,
|
|
226
|
+
() => this.fn({ signal: controller.signal })
|
|
227
|
+
);
|
|
228
|
+
} catch (err) {
|
|
229
|
+
this.pending = false;
|
|
230
|
+
this.error = err;
|
|
231
|
+
if (notify) this.notifySubscribers();
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
if (!(result instanceof Promise)) {
|
|
235
|
+
this.value = result;
|
|
236
|
+
this.pending = false;
|
|
237
|
+
this.error = null;
|
|
238
|
+
if (notify) this.notifySubscribers();
|
|
239
|
+
return;
|
|
240
|
+
}
|
|
241
|
+
if (ssr) {
|
|
242
|
+
throwSSRDataMissing();
|
|
243
|
+
}
|
|
244
|
+
result.then((val) => {
|
|
245
|
+
if (this.generation !== generation) return;
|
|
246
|
+
if (this.controller !== controller) return;
|
|
247
|
+
this.value = val;
|
|
248
|
+
this.pending = false;
|
|
249
|
+
this.error = null;
|
|
250
|
+
this.notifySubscribers();
|
|
251
|
+
}).catch((err) => {
|
|
252
|
+
if (this.generation !== generation) return;
|
|
253
|
+
this.pending = false;
|
|
254
|
+
this.error = err;
|
|
255
|
+
try {
|
|
256
|
+
logger.error("[Askr] Async resource error:", err);
|
|
257
|
+
} catch {
|
|
258
|
+
}
|
|
259
|
+
this.notifySubscribers();
|
|
260
|
+
});
|
|
261
|
+
}
|
|
262
|
+
refresh() {
|
|
263
|
+
this.generation++;
|
|
264
|
+
this.controller?.abort();
|
|
265
|
+
this.start();
|
|
266
|
+
}
|
|
267
|
+
abort() {
|
|
268
|
+
this.controller?.abort();
|
|
269
|
+
}
|
|
270
|
+
};
|
|
271
|
+
|
|
272
|
+
// src/runtime/operations.ts
|
|
273
|
+
function resource(fn, deps = []) {
|
|
274
|
+
const instance = getCurrentComponentInstance();
|
|
275
|
+
const inst = instance;
|
|
276
|
+
if (!instance) {
|
|
277
|
+
const renderData2 = getCurrentRenderData();
|
|
278
|
+
if (renderData2) {
|
|
279
|
+
const key = getNextKey();
|
|
280
|
+
if (!(key in renderData2)) {
|
|
281
|
+
throwSSRDataMissing();
|
|
282
|
+
}
|
|
283
|
+
const val = renderData2[key];
|
|
284
|
+
return {
|
|
285
|
+
value: val,
|
|
286
|
+
pending: false,
|
|
287
|
+
error: null,
|
|
288
|
+
refresh: () => {
|
|
289
|
+
}
|
|
290
|
+
};
|
|
291
|
+
}
|
|
292
|
+
const ssrCtx = getCurrentSSRContext();
|
|
293
|
+
if (ssrCtx) {
|
|
294
|
+
throwSSRDataMissing();
|
|
295
|
+
}
|
|
296
|
+
return {
|
|
297
|
+
value: null,
|
|
298
|
+
pending: true,
|
|
299
|
+
error: null,
|
|
300
|
+
refresh: () => {
|
|
301
|
+
}
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
const renderData = getCurrentRenderData();
|
|
305
|
+
if (renderData) {
|
|
306
|
+
const key = getNextKey();
|
|
307
|
+
if (!(key in renderData)) {
|
|
308
|
+
throwSSRDataMissing();
|
|
309
|
+
}
|
|
310
|
+
const val = renderData[key];
|
|
311
|
+
const holder2 = state({
|
|
312
|
+
cell: void 0,
|
|
313
|
+
snapshot: {
|
|
314
|
+
value: val,
|
|
315
|
+
pending: false,
|
|
316
|
+
error: null,
|
|
317
|
+
refresh: () => {
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
});
|
|
321
|
+
const h2 = holder2();
|
|
322
|
+
h2.snapshot.value = val;
|
|
323
|
+
h2.snapshot.pending = false;
|
|
324
|
+
h2.snapshot.error = null;
|
|
325
|
+
holder2.set(h2);
|
|
326
|
+
return h2.snapshot;
|
|
327
|
+
}
|
|
328
|
+
const holder = state({
|
|
329
|
+
cell: void 0,
|
|
330
|
+
snapshot: {
|
|
331
|
+
value: null,
|
|
332
|
+
pending: true,
|
|
333
|
+
error: null,
|
|
334
|
+
refresh: () => {
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
});
|
|
338
|
+
const h = holder();
|
|
339
|
+
if (!h.cell) {
|
|
340
|
+
const frame = getCurrentContextFrame();
|
|
341
|
+
const cell2 = new ResourceCell(fn, deps, frame);
|
|
342
|
+
h.cell = cell2;
|
|
343
|
+
h.snapshot = cell2.snapshot;
|
|
344
|
+
const unsubscribe = cell2.subscribe(() => {
|
|
345
|
+
const cur = holder();
|
|
346
|
+
cur.snapshot.value = cell2.snapshot.value;
|
|
347
|
+
cur.snapshot.pending = cell2.snapshot.pending;
|
|
348
|
+
cur.snapshot.error = cell2.snapshot.error;
|
|
349
|
+
holder.set(cur);
|
|
350
|
+
try {
|
|
351
|
+
inst._enqueueRun?.();
|
|
352
|
+
} catch {
|
|
353
|
+
}
|
|
354
|
+
});
|
|
355
|
+
inst.cleanupFns.push(() => {
|
|
356
|
+
unsubscribe();
|
|
357
|
+
cell2.abort();
|
|
358
|
+
});
|
|
359
|
+
try {
|
|
360
|
+
cell2.start(inst.ssr ?? false, false);
|
|
361
|
+
if (!cell2.pending) {
|
|
362
|
+
const cur = holder();
|
|
363
|
+
cur.snapshot.value = cell2.value;
|
|
364
|
+
cur.snapshot.pending = cell2.pending;
|
|
365
|
+
cur.snapshot.error = cell2.error;
|
|
366
|
+
}
|
|
367
|
+
} catch (err) {
|
|
368
|
+
if (err instanceof SSRDataMissingError) throw err;
|
|
369
|
+
cell2.error = err;
|
|
370
|
+
cell2.pending = false;
|
|
371
|
+
const cur = holder();
|
|
372
|
+
cur.snapshot.value = cell2.value;
|
|
373
|
+
cur.snapshot.pending = cell2.pending;
|
|
374
|
+
cur.snapshot.error = cell2.error;
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
const cell = h.cell;
|
|
378
|
+
const depsChanged = !cell.deps || cell.deps.length !== deps.length || cell.deps.some((d, i) => d !== deps[i]);
|
|
379
|
+
if (depsChanged) {
|
|
380
|
+
cell.deps = deps.slice();
|
|
381
|
+
cell.generation++;
|
|
382
|
+
cell.pending = true;
|
|
383
|
+
cell.error = null;
|
|
384
|
+
try {
|
|
385
|
+
cell.start(inst.ssr ?? false, false);
|
|
386
|
+
if (!cell.pending) {
|
|
387
|
+
const cur = holder();
|
|
388
|
+
cur.snapshot.value = cell.value;
|
|
389
|
+
cur.snapshot.pending = cell.pending;
|
|
390
|
+
cur.snapshot.error = cell.error;
|
|
391
|
+
}
|
|
392
|
+
} catch (err) {
|
|
393
|
+
if (err instanceof SSRDataMissingError) throw err;
|
|
394
|
+
cell.error = err;
|
|
395
|
+
cell.pending = false;
|
|
396
|
+
const cur = holder();
|
|
397
|
+
cur.snapshot.value = cell.value;
|
|
398
|
+
cur.snapshot.pending = cell.pending;
|
|
399
|
+
cur.snapshot.error = cell.error;
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
return h.snapshot;
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
// src/app/createApp.ts
|
|
406
|
+
init_component();
|
|
407
|
+
init_scheduler();
|
|
408
|
+
init_logger();
|
|
409
|
+
init_dom();
|
|
410
|
+
var componentIdCounter = 0;
|
|
411
|
+
var instancesByRoot = /* @__PURE__ */ new WeakMap();
|
|
412
|
+
var CLEANUP_SYMBOL = /* @__PURE__ */ Symbol.for("__tempoCleanup__");
|
|
413
|
+
function createApp(config) {
|
|
414
|
+
if (!config || typeof config !== "object") {
|
|
415
|
+
throw new Error("createApp requires a config object");
|
|
416
|
+
}
|
|
417
|
+
if ("routes" in config) {
|
|
418
|
+
throw new Error(
|
|
419
|
+
"The `createApp` API is removed. Use `createSPA({ root, routes })` for routed apps, or `hydrateSPA({ root, routes })` for SSR hydration."
|
|
420
|
+
);
|
|
421
|
+
}
|
|
422
|
+
const appCfg = config;
|
|
423
|
+
createIsland({
|
|
424
|
+
root: appCfg.root,
|
|
425
|
+
component: appCfg.component
|
|
426
|
+
});
|
|
427
|
+
}
|
|
428
|
+
function attachCleanupForRoot(rootElement, instance) {
|
|
429
|
+
rootElement[CLEANUP_SYMBOL] = () => {
|
|
430
|
+
removeAllListeners(rootElement);
|
|
431
|
+
cleanupComponent(instance);
|
|
432
|
+
};
|
|
433
|
+
try {
|
|
434
|
+
const descriptor = Object.getOwnPropertyDescriptor(rootElement, "innerHTML") || Object.getOwnPropertyDescriptor(
|
|
435
|
+
Object.getPrototypeOf(rootElement),
|
|
436
|
+
"innerHTML"
|
|
437
|
+
) || Object.getOwnPropertyDescriptor(Element.prototype, "innerHTML");
|
|
438
|
+
if (descriptor && (descriptor.get || descriptor.set)) {
|
|
439
|
+
Object.defineProperty(rootElement, "innerHTML", {
|
|
440
|
+
get: descriptor.get ? function() {
|
|
441
|
+
return descriptor.get.call(this);
|
|
442
|
+
} : void 0,
|
|
443
|
+
set: function(value) {
|
|
444
|
+
if (value === "" && instancesByRoot.get(this) === instance) {
|
|
445
|
+
removeAllListeners(rootElement);
|
|
446
|
+
cleanupComponent(instance);
|
|
447
|
+
}
|
|
448
|
+
if (descriptor.set) {
|
|
449
|
+
return descriptor.set.call(this, value);
|
|
450
|
+
}
|
|
451
|
+
},
|
|
452
|
+
configurable: true
|
|
453
|
+
});
|
|
454
|
+
}
|
|
455
|
+
} catch {
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
function mountOrUpdate(rootElement, componentFn) {
|
|
459
|
+
const existingCleanup = rootElement[CLEANUP_SYMBOL];
|
|
460
|
+
if (existingCleanup) existingCleanup();
|
|
461
|
+
let instance = instancesByRoot.get(rootElement);
|
|
462
|
+
if (instance) {
|
|
463
|
+
removeAllListeners(rootElement);
|
|
464
|
+
cleanupComponent(instance);
|
|
465
|
+
instance.fn = componentFn;
|
|
466
|
+
instance.evaluationGeneration++;
|
|
467
|
+
instance.mounted = false;
|
|
468
|
+
instance.expectedStateIndices = [];
|
|
469
|
+
instance.firstRenderComplete = false;
|
|
470
|
+
instance.isRoot = true;
|
|
471
|
+
} else {
|
|
472
|
+
const componentId = String(++componentIdCounter);
|
|
473
|
+
instance = createComponentInstance(
|
|
474
|
+
componentId,
|
|
475
|
+
componentFn,
|
|
476
|
+
{},
|
|
477
|
+
rootElement
|
|
478
|
+
);
|
|
479
|
+
instancesByRoot.set(rootElement, instance);
|
|
480
|
+
instance.isRoot = true;
|
|
481
|
+
}
|
|
482
|
+
attachCleanupForRoot(rootElement, instance);
|
|
483
|
+
mountComponent(instance);
|
|
484
|
+
globalScheduler.flush();
|
|
485
|
+
}
|
|
486
|
+
function createIsland(config) {
|
|
487
|
+
if (!config || typeof config !== "object") {
|
|
488
|
+
throw new Error("createIsland requires a config object");
|
|
489
|
+
}
|
|
490
|
+
if (typeof config.component !== "function") {
|
|
491
|
+
throw new Error("createIsland: component must be a function");
|
|
492
|
+
}
|
|
493
|
+
const rootElement = typeof config.root === "string" ? document.getElementById(config.root) : config.root;
|
|
494
|
+
if (!rootElement) throw new Error(`Root element not found: ${config.root}`);
|
|
495
|
+
if ("routes" in config) {
|
|
496
|
+
throw new Error(
|
|
497
|
+
"createIsland does not accept routes; use createSPA for routed apps"
|
|
498
|
+
);
|
|
499
|
+
}
|
|
500
|
+
mountOrUpdate(rootElement, config.component);
|
|
501
|
+
}
|
|
502
|
+
async function createSPA(config) {
|
|
503
|
+
if (!config || typeof config !== "object") {
|
|
504
|
+
throw new Error("createSPA requires a config object");
|
|
505
|
+
}
|
|
506
|
+
if (!Array.isArray(config.routes) || config.routes.length === 0) {
|
|
507
|
+
throw new Error(
|
|
508
|
+
"createSPA requires a route table. If you are enhancing existing HTML, use createIsland instead."
|
|
509
|
+
);
|
|
510
|
+
}
|
|
511
|
+
const rootElement = typeof config.root === "string" ? document.getElementById(config.root) : config.root;
|
|
512
|
+
if (!rootElement) throw new Error(`Root element not found: ${config.root}`);
|
|
513
|
+
const { clearRoutes: clearRoutes2, route: route2, lockRouteRegistration, resolveRoute } = await import("./route-TVYWYCEJ.js");
|
|
514
|
+
clearRoutes2();
|
|
515
|
+
for (const r of config.routes) {
|
|
516
|
+
route2(r.path, r.handler, r.namespace);
|
|
517
|
+
}
|
|
518
|
+
if (process.env.NODE_ENV === "production") lockRouteRegistration();
|
|
519
|
+
const path = typeof window !== "undefined" ? window.location.pathname : "/";
|
|
520
|
+
const resolved = resolveRoute(path);
|
|
521
|
+
if (!resolved) {
|
|
522
|
+
if (process.env.NODE_ENV !== "production") {
|
|
523
|
+
logger.warn(
|
|
524
|
+
`createSPA: no route found for current path (${path}). Mounting empty placeholder; navigation will activate routes when requested.`
|
|
525
|
+
);
|
|
526
|
+
}
|
|
527
|
+
mountOrUpdate(rootElement, () => ({ type: "div", children: [] }));
|
|
528
|
+
const instance2 = instancesByRoot.get(rootElement);
|
|
529
|
+
if (!instance2) throw new Error("Internal error: app instance missing");
|
|
530
|
+
registerAppInstance(instance2, path);
|
|
531
|
+
initializeNavigation();
|
|
532
|
+
return;
|
|
533
|
+
}
|
|
534
|
+
mountOrUpdate(rootElement, resolved.handler);
|
|
535
|
+
const instance = instancesByRoot.get(rootElement);
|
|
536
|
+
if (!instance) throw new Error("Internal error: app instance missing");
|
|
537
|
+
registerAppInstance(instance, path);
|
|
538
|
+
initializeNavigation();
|
|
539
|
+
}
|
|
540
|
+
async function hydrateSPA(config) {
|
|
541
|
+
if (!config || typeof config !== "object") {
|
|
542
|
+
throw new Error("hydrateSPA requires a config object");
|
|
543
|
+
}
|
|
544
|
+
if (!Array.isArray(config.routes) || config.routes.length === 0) {
|
|
545
|
+
throw new Error(
|
|
546
|
+
"hydrateSPA requires a route table. If you are enhancing existing HTML, use createIsland instead."
|
|
547
|
+
);
|
|
548
|
+
}
|
|
549
|
+
const rootElement = typeof config.root === "string" ? document.getElementById(config.root) : config.root;
|
|
550
|
+
if (!rootElement) throw new Error(`Root element not found: ${config.root}`);
|
|
551
|
+
const serverHTML = rootElement.innerHTML;
|
|
552
|
+
const {
|
|
553
|
+
clearRoutes: clearRoutes2,
|
|
554
|
+
route: route2,
|
|
555
|
+
setServerLocation: setServerLocation2,
|
|
556
|
+
lockRouteRegistration,
|
|
557
|
+
resolveRoute
|
|
558
|
+
} = await import("./route-TVYWYCEJ.js");
|
|
559
|
+
clearRoutes2();
|
|
560
|
+
for (const r of config.routes) {
|
|
561
|
+
route2(r.path, r.handler, r.namespace);
|
|
562
|
+
}
|
|
563
|
+
const path = typeof window !== "undefined" ? window.location.pathname : "/";
|
|
564
|
+
setServerLocation2(path);
|
|
565
|
+
if (process.env.NODE_ENV === "production") lockRouteRegistration();
|
|
566
|
+
const resolved = resolveRoute(path);
|
|
567
|
+
if (!resolved) {
|
|
568
|
+
throw new Error(`hydrateSPA: no route found for current path (${path}).`);
|
|
569
|
+
}
|
|
570
|
+
const { renderToStringSync: renderToStringSync2 } = await import("./ssr-4ELUFK65.js");
|
|
571
|
+
const expectedHTML = renderToStringSync2(() => {
|
|
572
|
+
const out = resolved.handler(resolved.params);
|
|
573
|
+
return out ?? {
|
|
574
|
+
type: "div",
|
|
575
|
+
children: []
|
|
576
|
+
};
|
|
577
|
+
});
|
|
578
|
+
const serverContainer = document.createElement("div");
|
|
579
|
+
serverContainer.innerHTML = serverHTML;
|
|
580
|
+
const expectedContainer = document.createElement("div");
|
|
581
|
+
expectedContainer.innerHTML = expectedHTML;
|
|
582
|
+
if (!serverContainer.isEqualNode(expectedContainer)) {
|
|
583
|
+
throw new Error(
|
|
584
|
+
"[Askr] Hydration mismatch detected. Server HTML does not match expected server-render output."
|
|
585
|
+
);
|
|
586
|
+
}
|
|
587
|
+
mountOrUpdate(rootElement, resolved.handler);
|
|
588
|
+
const { registerAppInstance: registerAppInstance2, initializeNavigation: initializeNavigation2 } = await import("./navigate-NLQOZQGM.js");
|
|
589
|
+
const instance = instancesByRoot.get(rootElement);
|
|
590
|
+
if (!instance) throw new Error("Internal error: app instance missing");
|
|
591
|
+
registerAppInstance2(instance, path);
|
|
592
|
+
initializeNavigation2();
|
|
593
|
+
}
|
|
594
|
+
function cleanupApp(root) {
|
|
595
|
+
const rootElement = typeof root === "string" ? document.getElementById(root) : root;
|
|
596
|
+
if (!rootElement) return;
|
|
597
|
+
const cleanupFn = rootElement[CLEANUP_SYMBOL];
|
|
598
|
+
if (typeof cleanupFn === "function") {
|
|
599
|
+
cleanupFn();
|
|
600
|
+
}
|
|
601
|
+
instancesByRoot.delete(rootElement);
|
|
602
|
+
}
|
|
603
|
+
function hasApp(root) {
|
|
604
|
+
const rootElement = typeof root === "string" ? document.getElementById(root) : root;
|
|
605
|
+
if (!rootElement) return false;
|
|
606
|
+
return instancesByRoot.has(rootElement);
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
// src/router/layouts.ts
|
|
610
|
+
function layout(Layout) {
|
|
611
|
+
return (children) => Layout({ children });
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
// src/components/Link.tsx
|
|
615
|
+
function Link({ href, children }) {
|
|
616
|
+
return {
|
|
617
|
+
type: "a",
|
|
618
|
+
props: {
|
|
619
|
+
href,
|
|
620
|
+
children,
|
|
621
|
+
onClick: (e) => {
|
|
622
|
+
const event = e;
|
|
623
|
+
const button = event.button ?? 0;
|
|
624
|
+
if (button !== 0 || // not left-click
|
|
625
|
+
event.ctrlKey || // Ctrl/Cmd+click
|
|
626
|
+
event.metaKey || // Cmd on Mac
|
|
627
|
+
event.shiftKey || // Shift+click
|
|
628
|
+
event.altKey) {
|
|
629
|
+
return;
|
|
630
|
+
}
|
|
631
|
+
event.preventDefault();
|
|
632
|
+
navigate(href);
|
|
633
|
+
}
|
|
634
|
+
}
|
|
635
|
+
};
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
// src/index.ts
|
|
639
|
+
init_jsx_runtime();
|
|
640
|
+
if (typeof globalThis !== "undefined") {
|
|
641
|
+
const g = globalThis;
|
|
642
|
+
if (!g.createApp) g.createApp = createApp;
|
|
643
|
+
if (!g.createIsland) g.createIsland = createIsland;
|
|
644
|
+
if (!g.createSPA) g.createSPA = createSPA;
|
|
645
|
+
if (!g.hydrateSPA) g.hydrateSPA = hydrateSPA;
|
|
646
|
+
if (!g.route) g.route = route;
|
|
647
|
+
if (!g.getRoutes) g.getRoutes = getRoutes;
|
|
648
|
+
if (!g.navigate) g.navigate = navigate;
|
|
649
|
+
}
|
|
650
|
+
export {
|
|
651
|
+
Fragment,
|
|
652
|
+
Link,
|
|
653
|
+
cleanupApp,
|
|
654
|
+
clearRoutes,
|
|
655
|
+
collectResources,
|
|
656
|
+
createApp,
|
|
657
|
+
createIsland,
|
|
658
|
+
createSPA,
|
|
659
|
+
defineContext,
|
|
660
|
+
getLoadedNamespaces,
|
|
661
|
+
getNamespaceRoutes,
|
|
662
|
+
getRoutes,
|
|
663
|
+
getSignal,
|
|
664
|
+
hasApp,
|
|
665
|
+
hydrateSPA,
|
|
666
|
+
jsx,
|
|
667
|
+
jsxs,
|
|
668
|
+
layout,
|
|
669
|
+
navigate,
|
|
670
|
+
readContext,
|
|
671
|
+
renderToStream,
|
|
672
|
+
renderToString,
|
|
673
|
+
renderToStringSync,
|
|
674
|
+
renderToStringSyncForUrl,
|
|
675
|
+
resolveResources,
|
|
676
|
+
resource,
|
|
677
|
+
route,
|
|
678
|
+
scheduleEventHandler,
|
|
679
|
+
setServerLocation,
|
|
680
|
+
state,
|
|
681
|
+
unloadNamespace
|
|
682
|
+
};
|
|
683
|
+
//# sourceMappingURL=index.js.map
|