@askrjs/askr 0.0.3 → 0.0.5
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/fx.d.ts +186 -0
- package/dist/fx.js +636 -0
- package/dist/fx.js.map +1 -0
- package/dist/index.d.ts +74 -407
- package/dist/index.js +3706 -779
- package/dist/index.js.map +1 -1
- package/dist/{types-DLTViI21.d.ts → jsx-AzPM8gMS.d.ts} +6 -21
- package/dist/{jsx/jsx-dev-runtime.d.ts → jsx-dev-runtime.d.ts} +3 -2
- package/dist/jsx-dev-runtime.js +17 -0
- package/dist/jsx-dev-runtime.js.map +1 -0
- package/dist/jsx-runtime.d.ts +14 -0
- package/dist/{chunk-SALJX5PZ.js → jsx-runtime.js} +6 -9
- package/dist/jsx-runtime.js.map +1 -0
- package/dist/resources.d.ts +21 -0
- package/dist/resources.js +785 -0
- package/dist/resources.js.map +1 -0
- package/dist/router-DaGtH1Sq.d.ts +36 -0
- package/dist/router.d.ts +64 -0
- package/dist/{chunk-2ONGHQ7Z.js → router.js} +719 -689
- package/dist/router.js.map +1 -0
- package/dist/ssr.d.ts +123 -0
- package/dist/{index.cjs → ssr.js} +1472 -2737
- package/dist/ssr.js.map +1 -0
- package/dist/types-uOPfcrdz.d.ts +25 -0
- package/dist/vite/index.d.ts +17 -0
- package/dist/vite/index.js +2306 -0
- package/dist/vite/index.js.map +1 -0
- package/package.json +37 -28
- package/dist/chunk-2ONGHQ7Z.js.map +0 -1
- package/dist/chunk-H3NSVHA7.js +0 -80
- package/dist/chunk-H3NSVHA7.js.map +0 -1
- package/dist/chunk-JHOGWTAW.js +0 -16
- package/dist/chunk-JHOGWTAW.js.map +0 -1
- package/dist/chunk-OFW6DFBM.js +0 -716
- package/dist/chunk-OFW6DFBM.js.map +0 -1
- package/dist/chunk-SALJX5PZ.js.map +0 -1
- package/dist/index.cjs.map +0 -1
- package/dist/index.d.cts +0 -501
- package/dist/jsx/jsx-dev-runtime.cjs +0 -46
- package/dist/jsx/jsx-dev-runtime.cjs.map +0 -1
- package/dist/jsx/jsx-dev-runtime.d.cts +0 -11
- package/dist/jsx/jsx-dev-runtime.js +0 -19
- package/dist/jsx/jsx-dev-runtime.js.map +0 -1
- package/dist/jsx/jsx-runtime.cjs +0 -54
- package/dist/jsx/jsx-runtime.cjs.map +0 -1
- package/dist/jsx/jsx-runtime.d.cts +0 -20
- package/dist/jsx/jsx-runtime.d.ts +0 -20
- package/dist/jsx/jsx-runtime.js +0 -16
- package/dist/jsx/jsx-runtime.js.map +0 -1
- package/dist/navigate-CZEUXFPM.js +0 -16
- package/dist/navigate-CZEUXFPM.js.map +0 -1
- package/dist/route-USEXGOBT.js +0 -31
- package/dist/route-USEXGOBT.js.map +0 -1
- package/dist/ssr-QJ5NTQR6.js +0 -28
- package/dist/ssr-QJ5NTQR6.js.map +0 -1
- package/dist/types-DLTViI21.d.cts +0 -50
- package/src/jsx/index.ts +0 -4
- package/src/jsx/jsx-dev-runtime.ts +0 -23
- package/src/jsx/jsx-runtime.ts +0 -48
- package/src/jsx/types.ts +0 -46
- package/src/jsx/utils.ts +0 -19
|
@@ -1,40 +1,69 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
var __defProp = Object.defineProperty;
|
|
3
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
-
var __esm = (fn, res) => function __init() {
|
|
7
|
-
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
8
|
-
};
|
|
9
2
|
var __export = (target, all) => {
|
|
10
3
|
for (var name in all)
|
|
11
4
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
12
5
|
};
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
6
|
+
|
|
7
|
+
// src/router/route.ts
|
|
8
|
+
var route_exports = {};
|
|
9
|
+
__export(route_exports, {
|
|
10
|
+
_lockRouteRegistrationForTests: () => _lockRouteRegistrationForTests,
|
|
11
|
+
_unlockRouteRegistrationForTests: () => _unlockRouteRegistrationForTests,
|
|
12
|
+
clearRoutes: () => clearRoutes,
|
|
13
|
+
getLoadedNamespaces: () => getLoadedNamespaces,
|
|
14
|
+
getNamespaceRoutes: () => getNamespaceRoutes,
|
|
15
|
+
getRoutes: () => getRoutes,
|
|
16
|
+
lockRouteRegistration: () => lockRouteRegistration,
|
|
17
|
+
registerRoute: () => registerRoute,
|
|
18
|
+
resolveRoute: () => resolveRoute,
|
|
19
|
+
route: () => route,
|
|
20
|
+
setServerLocation: () => setServerLocation,
|
|
21
|
+
unloadNamespace: () => unloadNamespace
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
// src/router/match.ts
|
|
25
|
+
function match(path, pattern) {
|
|
26
|
+
const normalizedPath = path.endsWith("/") && path !== "/" ? path.slice(0, -1) : path;
|
|
27
|
+
const normalizedPattern = pattern.endsWith("/") && pattern !== "/" ? pattern.slice(0, -1) : pattern;
|
|
28
|
+
const pathSegments = normalizedPath.split("/").filter(Boolean);
|
|
29
|
+
const patternSegments = normalizedPattern.split("/").filter(Boolean);
|
|
30
|
+
if (patternSegments.length === 1 && patternSegments[0] === "*") {
|
|
31
|
+
return {
|
|
32
|
+
matched: true,
|
|
33
|
+
params: {
|
|
34
|
+
"*": pathSegments.length > 1 ? normalizedPath : pathSegments[0]
|
|
35
|
+
}
|
|
36
|
+
};
|
|
18
37
|
}
|
|
19
|
-
|
|
20
|
-
};
|
|
21
|
-
|
|
38
|
+
if (pathSegments.length !== patternSegments.length) {
|
|
39
|
+
return { matched: false, params: {} };
|
|
40
|
+
}
|
|
41
|
+
const params = {};
|
|
42
|
+
for (let i = 0; i < patternSegments.length; i++) {
|
|
43
|
+
const patternSegment = patternSegments[i];
|
|
44
|
+
const pathSegment = pathSegments[i];
|
|
45
|
+
if (patternSegment.startsWith("{") && patternSegment.endsWith("}")) {
|
|
46
|
+
const paramName = patternSegment.slice(1, -1);
|
|
47
|
+
params[paramName] = decodeURIComponent(pathSegment);
|
|
48
|
+
} else if (patternSegment === "*") {
|
|
49
|
+
params["*"] = pathSegment;
|
|
50
|
+
} else if (patternSegment !== pathSegment) {
|
|
51
|
+
return { matched: false, params: {} };
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return { matched: true, params };
|
|
55
|
+
}
|
|
22
56
|
|
|
23
57
|
// src/dev/invariant.ts
|
|
24
58
|
function invariant(condition, message, context) {
|
|
25
59
|
if (!condition) {
|
|
26
|
-
const contextStr =
|
|
60
|
+
const contextStr = "";
|
|
27
61
|
throw new Error(`[Askr Invariant] ${message}${contextStr}`);
|
|
28
62
|
}
|
|
29
63
|
}
|
|
30
64
|
function assertSchedulingPrecondition(condition, violationMessage) {
|
|
31
65
|
invariant(condition, `[Scheduler Precondition] ${violationMessage}`);
|
|
32
66
|
}
|
|
33
|
-
var init_invariant = __esm({
|
|
34
|
-
"src/dev/invariant.ts"() {
|
|
35
|
-
"use strict";
|
|
36
|
-
}
|
|
37
|
-
});
|
|
38
67
|
|
|
39
68
|
// src/dev/logger.ts
|
|
40
69
|
function callConsole(method, args) {
|
|
@@ -48,322 +77,279 @@ function callConsole(method, args) {
|
|
|
48
77
|
}
|
|
49
78
|
}
|
|
50
79
|
}
|
|
51
|
-
var logger
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
"
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
callConsole("warn", args);
|
|
67
|
-
},
|
|
68
|
-
error: (...args) => {
|
|
69
|
-
callConsole("error", args);
|
|
70
|
-
}
|
|
71
|
-
};
|
|
80
|
+
var logger = {
|
|
81
|
+
debug: (...args) => {
|
|
82
|
+
if (process.env.NODE_ENV === "production") return;
|
|
83
|
+
callConsole("debug", args);
|
|
84
|
+
},
|
|
85
|
+
info: (...args) => {
|
|
86
|
+
if (process.env.NODE_ENV === "production") return;
|
|
87
|
+
callConsole("info", args);
|
|
88
|
+
},
|
|
89
|
+
warn: (...args) => {
|
|
90
|
+
if (process.env.NODE_ENV === "production") return;
|
|
91
|
+
callConsole("warn", args);
|
|
92
|
+
},
|
|
93
|
+
error: (...args) => {
|
|
94
|
+
callConsole("error", args);
|
|
72
95
|
}
|
|
73
|
-
}
|
|
96
|
+
};
|
|
74
97
|
|
|
75
98
|
// src/runtime/scheduler.ts
|
|
99
|
+
var MAX_FLUSH_DEPTH = 50;
|
|
76
100
|
function isBulkCommitActive() {
|
|
77
101
|
try {
|
|
78
102
|
const fb = globalThis.__ASKR_FASTLANE;
|
|
79
103
|
return typeof fb?.isBulkCommitActive === "function" ? !!fb.isBulkCommitActive() : false;
|
|
80
104
|
} catch (e) {
|
|
81
|
-
void e;
|
|
82
105
|
return false;
|
|
83
106
|
}
|
|
84
107
|
}
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
+
var Scheduler = class {
|
|
109
|
+
constructor() {
|
|
110
|
+
this.q = [];
|
|
111
|
+
this.head = 0;
|
|
112
|
+
this.running = false;
|
|
113
|
+
this.inHandler = false;
|
|
114
|
+
this.depth = 0;
|
|
115
|
+
this.executionDepth = 0;
|
|
116
|
+
// for compat with existing diagnostics
|
|
117
|
+
// Monotonic flush version increments at end of each flush
|
|
118
|
+
this.flushVersion = 0;
|
|
119
|
+
// Best-effort microtask kick scheduling
|
|
120
|
+
this.kickScheduled = false;
|
|
121
|
+
// Escape hatch flag for runWithSyncProgress
|
|
122
|
+
this.allowSyncProgress = false;
|
|
123
|
+
// Waiters waiting for flushVersion >= target
|
|
124
|
+
this.waiters = [];
|
|
125
|
+
// Keep a lightweight taskCount for compatibility/diagnostics
|
|
126
|
+
this.taskCount = 0;
|
|
127
|
+
}
|
|
128
|
+
enqueue(task) {
|
|
129
|
+
assertSchedulingPrecondition(
|
|
130
|
+
typeof task === "function",
|
|
131
|
+
"enqueue() requires a function"
|
|
132
|
+
);
|
|
133
|
+
if (isBulkCommitActive() && !this.allowSyncProgress) {
|
|
134
|
+
if (process.env.NODE_ENV !== "production") {
|
|
135
|
+
throw new Error(
|
|
136
|
+
"[Scheduler] enqueue() during bulk commit (not allowed)"
|
|
137
|
+
);
|
|
108
138
|
}
|
|
139
|
+
return;
|
|
109
140
|
}
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
"use strict";
|
|
116
|
-
init_invariant();
|
|
117
|
-
init_logger();
|
|
118
|
-
MAX_FLUSH_DEPTH = 50;
|
|
119
|
-
Scheduler = class {
|
|
120
|
-
constructor() {
|
|
121
|
-
this.q = [];
|
|
122
|
-
this.head = 0;
|
|
123
|
-
this.running = false;
|
|
124
|
-
this.inHandler = false;
|
|
125
|
-
this.depth = 0;
|
|
126
|
-
this.executionDepth = 0;
|
|
127
|
-
// for compat with existing diagnostics
|
|
128
|
-
// Monotonic flush version increments at end of each flush
|
|
129
|
-
this.flushVersion = 0;
|
|
130
|
-
// Best-effort microtask kick scheduling
|
|
141
|
+
this.q.push(task);
|
|
142
|
+
this.taskCount++;
|
|
143
|
+
if (!this.running && !this.kickScheduled && !this.inHandler && !isBulkCommitActive()) {
|
|
144
|
+
this.kickScheduled = true;
|
|
145
|
+
queueMicrotask(() => {
|
|
131
146
|
this.kickScheduled = false;
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
enqueue(task2) {
|
|
140
|
-
assertSchedulingPrecondition(
|
|
141
|
-
typeof task2 === "function",
|
|
142
|
-
"enqueue() requires a function"
|
|
143
|
-
);
|
|
144
|
-
if (isBulkCommitActive() && !this.allowSyncProgress) {
|
|
145
|
-
if (process.env.NODE_ENV !== "production") {
|
|
146
|
-
throw new Error(
|
|
147
|
-
"[Scheduler] enqueue() during bulk commit (not allowed)"
|
|
148
|
-
);
|
|
149
|
-
}
|
|
150
|
-
return;
|
|
151
|
-
}
|
|
152
|
-
this.q.push(task2);
|
|
153
|
-
this.taskCount++;
|
|
154
|
-
if (!this.running && !this.kickScheduled && !this.inHandler && !isBulkCommitActive()) {
|
|
155
|
-
this.kickScheduled = true;
|
|
156
|
-
queueMicrotask(() => {
|
|
157
|
-
this.kickScheduled = false;
|
|
158
|
-
if (this.running) return;
|
|
159
|
-
if (isBulkCommitActive()) return;
|
|
160
|
-
try {
|
|
161
|
-
this.flush();
|
|
162
|
-
} catch (err) {
|
|
163
|
-
setTimeout(() => {
|
|
164
|
-
throw err;
|
|
165
|
-
});
|
|
166
|
-
}
|
|
147
|
+
if (this.running) return;
|
|
148
|
+
if (isBulkCommitActive()) return;
|
|
149
|
+
try {
|
|
150
|
+
this.flush();
|
|
151
|
+
} catch (err) {
|
|
152
|
+
setTimeout(() => {
|
|
153
|
+
throw err;
|
|
167
154
|
});
|
|
168
155
|
}
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
flush() {
|
|
160
|
+
invariant(
|
|
161
|
+
!this.running,
|
|
162
|
+
"[Scheduler] flush() called while already running"
|
|
163
|
+
);
|
|
164
|
+
if (process.env.NODE_ENV !== "production") {
|
|
165
|
+
if (isBulkCommitActive() && !this.allowSyncProgress) {
|
|
166
|
+
throw new Error(
|
|
167
|
+
"[Scheduler] flush() started during bulk commit (not allowed)"
|
|
174
168
|
);
|
|
175
|
-
if (process.env.NODE_ENV !== "production") {
|
|
176
|
-
if (isBulkCommitActive() && !this.allowSyncProgress) {
|
|
177
|
-
throw new Error(
|
|
178
|
-
"[Scheduler] flush() started during bulk commit (not allowed)"
|
|
179
|
-
);
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
this.running = true;
|
|
183
|
-
this.depth = 0;
|
|
184
|
-
let fatal = null;
|
|
185
|
-
try {
|
|
186
|
-
while (this.head < this.q.length) {
|
|
187
|
-
this.depth++;
|
|
188
|
-
if (process.env.NODE_ENV !== "production" && this.depth > MAX_FLUSH_DEPTH) {
|
|
189
|
-
throw new Error(
|
|
190
|
-
`[Scheduler] exceeded MAX_FLUSH_DEPTH (${MAX_FLUSH_DEPTH}). Likely infinite update loop.`
|
|
191
|
-
);
|
|
192
|
-
}
|
|
193
|
-
const task2 = this.q[this.head++];
|
|
194
|
-
try {
|
|
195
|
-
this.executionDepth++;
|
|
196
|
-
task2();
|
|
197
|
-
this.executionDepth--;
|
|
198
|
-
} catch (err) {
|
|
199
|
-
if (this.executionDepth > 0) this.executionDepth = 0;
|
|
200
|
-
fatal = err;
|
|
201
|
-
break;
|
|
202
|
-
}
|
|
203
|
-
if (this.taskCount > 0) this.taskCount--;
|
|
204
|
-
}
|
|
205
|
-
} finally {
|
|
206
|
-
this.running = false;
|
|
207
|
-
this.depth = 0;
|
|
208
|
-
this.executionDepth = 0;
|
|
209
|
-
if (this.head >= this.q.length) {
|
|
210
|
-
this.q.length = 0;
|
|
211
|
-
this.head = 0;
|
|
212
|
-
} else if (this.head > 0) {
|
|
213
|
-
const remaining = this.q.length - this.head;
|
|
214
|
-
if (this.head > 1024 || this.head > remaining) {
|
|
215
|
-
this.q = this.q.slice(this.head);
|
|
216
|
-
} else {
|
|
217
|
-
for (let i = 0; i < remaining; i++) {
|
|
218
|
-
this.q[i] = this.q[this.head + i];
|
|
219
|
-
}
|
|
220
|
-
this.q.length = remaining;
|
|
221
|
-
}
|
|
222
|
-
this.head = 0;
|
|
223
|
-
}
|
|
224
|
-
this.flushVersion++;
|
|
225
|
-
this.resolveWaiters();
|
|
226
|
-
}
|
|
227
|
-
if (fatal) throw fatal;
|
|
228
169
|
}
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
};
|
|
241
|
-
g.setTimeout = () => {
|
|
242
|
-
throw new Error(
|
|
243
|
-
"[Scheduler] setTimeout not allowed during runWithSyncProgress"
|
|
244
|
-
);
|
|
245
|
-
};
|
|
170
|
+
}
|
|
171
|
+
this.running = true;
|
|
172
|
+
this.depth = 0;
|
|
173
|
+
let fatal = null;
|
|
174
|
+
try {
|
|
175
|
+
while (this.head < this.q.length) {
|
|
176
|
+
this.depth++;
|
|
177
|
+
if (process.env.NODE_ENV !== "production" && this.depth > MAX_FLUSH_DEPTH) {
|
|
178
|
+
throw new Error(
|
|
179
|
+
`[Scheduler] exceeded MAX_FLUSH_DEPTH (${MAX_FLUSH_DEPTH}). Likely infinite update loop.`
|
|
180
|
+
);
|
|
246
181
|
}
|
|
247
|
-
const
|
|
182
|
+
const task = this.q[this.head++];
|
|
248
183
|
try {
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
if (
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
"[Scheduler] tasks remain after runWithSyncProgress flush"
|
|
257
|
-
);
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
return res;
|
|
261
|
-
} finally {
|
|
262
|
-
if (process.env.NODE_ENV !== "production") {
|
|
263
|
-
g.queueMicrotask = origQueueMicrotask;
|
|
264
|
-
g.setTimeout = origSetTimeout;
|
|
265
|
-
}
|
|
266
|
-
try {
|
|
267
|
-
if (this.flushVersion === startVersion) {
|
|
268
|
-
this.flushVersion++;
|
|
269
|
-
this.resolveWaiters();
|
|
270
|
-
}
|
|
271
|
-
} catch (e) {
|
|
272
|
-
void e;
|
|
273
|
-
}
|
|
274
|
-
this.allowSyncProgress = prev;
|
|
184
|
+
this.executionDepth++;
|
|
185
|
+
task();
|
|
186
|
+
this.executionDepth--;
|
|
187
|
+
} catch (err) {
|
|
188
|
+
if (this.executionDepth > 0) this.executionDepth = 0;
|
|
189
|
+
fatal = err;
|
|
190
|
+
break;
|
|
275
191
|
}
|
|
192
|
+
if (this.taskCount > 0) this.taskCount--;
|
|
276
193
|
}
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
reject(
|
|
292
|
-
new Error(
|
|
293
|
-
`waitForFlush timeout ${timeoutMs}ms: ${JSON.stringify(diag)}`
|
|
294
|
-
)
|
|
295
|
-
);
|
|
296
|
-
}, timeoutMs);
|
|
297
|
-
this.waiters.push({ target, resolve, reject, timer });
|
|
298
|
-
});
|
|
299
|
-
}
|
|
300
|
-
getState() {
|
|
301
|
-
return {
|
|
302
|
-
queueLength: this.q.length - this.head,
|
|
303
|
-
running: this.running,
|
|
304
|
-
depth: this.depth,
|
|
305
|
-
executionDepth: this.executionDepth,
|
|
306
|
-
taskCount: this.taskCount,
|
|
307
|
-
flushVersion: this.flushVersion,
|
|
308
|
-
// New fields for optional inspection
|
|
309
|
-
inHandler: this.inHandler,
|
|
310
|
-
allowSyncProgress: this.allowSyncProgress
|
|
311
|
-
};
|
|
194
|
+
} finally {
|
|
195
|
+
this.running = false;
|
|
196
|
+
this.depth = 0;
|
|
197
|
+
this.executionDepth = 0;
|
|
198
|
+
if (this.head >= this.q.length) {
|
|
199
|
+
this.q.length = 0;
|
|
200
|
+
this.head = 0;
|
|
201
|
+
} else if (this.head > 0) {
|
|
202
|
+
const remaining = this.q.length - this.head;
|
|
203
|
+
for (let i = 0; i < remaining; i++) {
|
|
204
|
+
this.q[i] = this.q[this.head + i];
|
|
205
|
+
}
|
|
206
|
+
this.q.length = remaining;
|
|
207
|
+
this.head = 0;
|
|
312
208
|
}
|
|
313
|
-
|
|
314
|
-
|
|
209
|
+
this.flushVersion++;
|
|
210
|
+
this.resolveWaiters();
|
|
211
|
+
}
|
|
212
|
+
if (fatal) throw fatal;
|
|
213
|
+
}
|
|
214
|
+
runWithSyncProgress(fn) {
|
|
215
|
+
const prev = this.allowSyncProgress;
|
|
216
|
+
this.allowSyncProgress = true;
|
|
217
|
+
const g = globalThis;
|
|
218
|
+
const origQueueMicrotask = g.queueMicrotask;
|
|
219
|
+
const origSetTimeout = g.setTimeout;
|
|
220
|
+
if (process.env.NODE_ENV !== "production") {
|
|
221
|
+
g.queueMicrotask = () => {
|
|
222
|
+
throw new Error(
|
|
223
|
+
"[Scheduler] queueMicrotask not allowed during runWithSyncProgress"
|
|
224
|
+
);
|
|
225
|
+
};
|
|
226
|
+
g.setTimeout = () => {
|
|
227
|
+
throw new Error(
|
|
228
|
+
"[Scheduler] setTimeout not allowed during runWithSyncProgress"
|
|
229
|
+
);
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
const startVersion = this.flushVersion;
|
|
233
|
+
try {
|
|
234
|
+
const res = fn();
|
|
235
|
+
if (!this.running && this.q.length - this.head > 0) {
|
|
236
|
+
this.flush();
|
|
315
237
|
}
|
|
316
|
-
|
|
317
|
-
|
|
238
|
+
if (process.env.NODE_ENV !== "production") {
|
|
239
|
+
if (this.q.length - this.head > 0) {
|
|
240
|
+
throw new Error(
|
|
241
|
+
"[Scheduler] tasks remain after runWithSyncProgress flush"
|
|
242
|
+
);
|
|
243
|
+
}
|
|
318
244
|
}
|
|
319
|
-
|
|
320
|
-
|
|
245
|
+
return res;
|
|
246
|
+
} finally {
|
|
247
|
+
if (process.env.NODE_ENV !== "production") {
|
|
248
|
+
g.queueMicrotask = origQueueMicrotask;
|
|
249
|
+
g.setTimeout = origSetTimeout;
|
|
321
250
|
}
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
if (this.running) {
|
|
327
|
-
this.q.length = this.head;
|
|
328
|
-
this.taskCount = Math.max(0, this.taskCount - remaining);
|
|
329
|
-
queueMicrotask(() => {
|
|
330
|
-
try {
|
|
331
|
-
this.flushVersion++;
|
|
332
|
-
this.resolveWaiters();
|
|
333
|
-
} catch (e) {
|
|
334
|
-
void e;
|
|
335
|
-
}
|
|
336
|
-
});
|
|
337
|
-
return remaining;
|
|
251
|
+
try {
|
|
252
|
+
if (this.flushVersion === startVersion) {
|
|
253
|
+
this.flushVersion++;
|
|
254
|
+
this.resolveWaiters();
|
|
338
255
|
}
|
|
339
|
-
|
|
340
|
-
this.head = 0;
|
|
341
|
-
this.taskCount = Math.max(0, this.taskCount - remaining);
|
|
342
|
-
this.flushVersion++;
|
|
343
|
-
this.resolveWaiters();
|
|
344
|
-
return remaining;
|
|
256
|
+
} catch (e) {
|
|
345
257
|
}
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
258
|
+
this.allowSyncProgress = prev;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
waitForFlush(targetVersion, timeoutMs = 2e3) {
|
|
262
|
+
const target = typeof targetVersion === "number" ? targetVersion : this.flushVersion + 1;
|
|
263
|
+
if (this.flushVersion >= target) return Promise.resolve();
|
|
264
|
+
return new Promise((resolve, reject) => {
|
|
265
|
+
const timer = setTimeout(() => {
|
|
266
|
+
const ns = globalThis.__ASKR__ || {};
|
|
267
|
+
const diag = {
|
|
268
|
+
flushVersion: this.flushVersion,
|
|
269
|
+
queueLen: this.q.length - this.head,
|
|
270
|
+
running: this.running,
|
|
271
|
+
inHandler: this.inHandler,
|
|
272
|
+
bulk: isBulkCommitActive(),
|
|
273
|
+
namespace: ns
|
|
274
|
+
};
|
|
275
|
+
reject(
|
|
276
|
+
new Error(
|
|
277
|
+
`waitForFlush timeout ${timeoutMs}ms: ${JSON.stringify(diag)}`
|
|
278
|
+
)
|
|
279
|
+
);
|
|
280
|
+
}, timeoutMs);
|
|
281
|
+
this.waiters.push({ target, resolve, reject, timer });
|
|
282
|
+
});
|
|
283
|
+
}
|
|
284
|
+
getState() {
|
|
285
|
+
return {
|
|
286
|
+
queueLength: this.q.length - this.head,
|
|
287
|
+
running: this.running,
|
|
288
|
+
depth: this.depth,
|
|
289
|
+
executionDepth: this.executionDepth,
|
|
290
|
+
taskCount: this.taskCount,
|
|
291
|
+
flushVersion: this.flushVersion,
|
|
292
|
+
// New fields for optional inspection
|
|
293
|
+
inHandler: this.inHandler,
|
|
294
|
+
allowSyncProgress: this.allowSyncProgress
|
|
295
|
+
};
|
|
296
|
+
}
|
|
297
|
+
setInHandler(v) {
|
|
298
|
+
this.inHandler = v;
|
|
299
|
+
}
|
|
300
|
+
isInHandler() {
|
|
301
|
+
return this.inHandler;
|
|
302
|
+
}
|
|
303
|
+
isExecuting() {
|
|
304
|
+
return this.running || this.executionDepth > 0;
|
|
305
|
+
}
|
|
306
|
+
// Clear pending synchronous tasks (used by fastlane enter/exit)
|
|
307
|
+
clearPendingSyncTasks() {
|
|
308
|
+
const remaining = this.q.length - this.head;
|
|
309
|
+
if (remaining <= 0) return 0;
|
|
310
|
+
if (this.running) {
|
|
311
|
+
this.q.length = this.head;
|
|
312
|
+
this.taskCount = Math.max(0, this.taskCount - remaining);
|
|
313
|
+
queueMicrotask(() => {
|
|
314
|
+
try {
|
|
315
|
+
this.flushVersion++;
|
|
316
|
+
this.resolveWaiters();
|
|
317
|
+
} catch (e) {
|
|
357
318
|
}
|
|
358
|
-
|
|
359
|
-
|
|
319
|
+
});
|
|
320
|
+
return remaining;
|
|
321
|
+
}
|
|
322
|
+
this.q.length = 0;
|
|
323
|
+
this.head = 0;
|
|
324
|
+
this.taskCount = Math.max(0, this.taskCount - remaining);
|
|
325
|
+
this.flushVersion++;
|
|
326
|
+
this.resolveWaiters();
|
|
327
|
+
return remaining;
|
|
328
|
+
}
|
|
329
|
+
resolveWaiters() {
|
|
330
|
+
if (this.waiters.length === 0) return;
|
|
331
|
+
const ready = [];
|
|
332
|
+
const remaining = [];
|
|
333
|
+
for (const w of this.waiters) {
|
|
334
|
+
if (this.flushVersion >= w.target) {
|
|
335
|
+
if (w.timer) clearTimeout(w.timer);
|
|
336
|
+
ready.push(w.resolve);
|
|
337
|
+
} else {
|
|
338
|
+
remaining.push(w);
|
|
360
339
|
}
|
|
361
|
-
}
|
|
362
|
-
|
|
340
|
+
}
|
|
341
|
+
this.waiters = remaining;
|
|
342
|
+
for (const r of ready) r();
|
|
363
343
|
}
|
|
364
|
-
}
|
|
344
|
+
};
|
|
345
|
+
var globalScheduler = new Scheduler();
|
|
346
|
+
function isSchedulerExecuting() {
|
|
347
|
+
return globalScheduler.isExecuting();
|
|
348
|
+
}
|
|
365
349
|
|
|
366
350
|
// src/runtime/context.ts
|
|
351
|
+
var CONTEXT_FRAME_SYMBOL = /* @__PURE__ */ Symbol("__tempoContextFrame__");
|
|
352
|
+
var currentContextFrame = null;
|
|
367
353
|
function withContext(frame, fn) {
|
|
368
354
|
const oldFrame = currentContextFrame;
|
|
369
355
|
currentContextFrame = frame;
|
|
@@ -373,125 +359,9 @@ function withContext(frame, fn) {
|
|
|
373
359
|
currentContextFrame = oldFrame;
|
|
374
360
|
}
|
|
375
361
|
}
|
|
376
|
-
function withAsyncResourceContext(frame, fn) {
|
|
377
|
-
const oldFrame = currentAsyncResourceFrame;
|
|
378
|
-
currentAsyncResourceFrame = frame;
|
|
379
|
-
try {
|
|
380
|
-
return fn();
|
|
381
|
-
} finally {
|
|
382
|
-
currentAsyncResourceFrame = oldFrame;
|
|
383
|
-
}
|
|
384
|
-
}
|
|
385
|
-
function defineContext(defaultValue) {
|
|
386
|
-
const key = /* @__PURE__ */ Symbol("AskrContext");
|
|
387
|
-
return {
|
|
388
|
-
key,
|
|
389
|
-
defaultValue,
|
|
390
|
-
Scope: (props) => {
|
|
391
|
-
const value = props.value;
|
|
392
|
-
return {
|
|
393
|
-
type: ContextScopeComponent,
|
|
394
|
-
props: { key, value, children: props.children }
|
|
395
|
-
};
|
|
396
|
-
}
|
|
397
|
-
};
|
|
398
|
-
}
|
|
399
|
-
function readContext(context) {
|
|
400
|
-
const frame = currentContextFrame || currentAsyncResourceFrame;
|
|
401
|
-
if (!frame) {
|
|
402
|
-
throw new Error(
|
|
403
|
-
"readContext() can only be called during component render or async resource execution. Ensure you are calling this from inside your component or resource function."
|
|
404
|
-
);
|
|
405
|
-
}
|
|
406
|
-
let current2 = frame;
|
|
407
|
-
while (current2) {
|
|
408
|
-
const values = current2.values;
|
|
409
|
-
if (values && values.has(context.key)) {
|
|
410
|
-
return values.get(context.key);
|
|
411
|
-
}
|
|
412
|
-
current2 = current2.parent;
|
|
413
|
-
}
|
|
414
|
-
return context.defaultValue;
|
|
415
|
-
}
|
|
416
|
-
function ContextScopeComponent(props) {
|
|
417
|
-
const key = props["key"];
|
|
418
|
-
const value = props["value"];
|
|
419
|
-
const children = props["children"];
|
|
420
|
-
const instance = getCurrentComponentInstance();
|
|
421
|
-
const parentFrame = (() => {
|
|
422
|
-
if (currentContextFrame) return currentContextFrame;
|
|
423
|
-
if (instance && instance.ownerFrame) return instance.ownerFrame;
|
|
424
|
-
return null;
|
|
425
|
-
})();
|
|
426
|
-
const newFrame = {
|
|
427
|
-
parent: parentFrame,
|
|
428
|
-
values: /* @__PURE__ */ new Map([[key, value]])
|
|
429
|
-
};
|
|
430
|
-
function createFunctionChildInvoker(fn, frame, owner) {
|
|
431
|
-
return {
|
|
432
|
-
type: ContextFunctionChildInvoker,
|
|
433
|
-
props: { fn, __frame: frame, __owner: owner }
|
|
434
|
-
};
|
|
435
|
-
}
|
|
436
|
-
if (Array.isArray(children)) {
|
|
437
|
-
return children.map((child) => {
|
|
438
|
-
if (typeof child === "function") {
|
|
439
|
-
return createFunctionChildInvoker(
|
|
440
|
-
child,
|
|
441
|
-
newFrame,
|
|
442
|
-
getCurrentComponentInstance()
|
|
443
|
-
);
|
|
444
|
-
}
|
|
445
|
-
return markWithFrame(child, newFrame);
|
|
446
|
-
});
|
|
447
|
-
} else if (typeof children === "function") {
|
|
448
|
-
return createFunctionChildInvoker(
|
|
449
|
-
children,
|
|
450
|
-
newFrame,
|
|
451
|
-
getCurrentComponentInstance()
|
|
452
|
-
);
|
|
453
|
-
} else if (children) {
|
|
454
|
-
return markWithFrame(children, newFrame);
|
|
455
|
-
}
|
|
456
|
-
return null;
|
|
457
|
-
}
|
|
458
|
-
function markWithFrame(node, frame) {
|
|
459
|
-
if (typeof node === "object" && node !== null) {
|
|
460
|
-
const obj = node;
|
|
461
|
-
obj[CONTEXT_FRAME_SYMBOL] = frame;
|
|
462
|
-
const children = obj.children;
|
|
463
|
-
if (Array.isArray(children)) {
|
|
464
|
-
for (let i = 0; i < children.length; i++) {
|
|
465
|
-
const child = children[i];
|
|
466
|
-
if (child) {
|
|
467
|
-
children[i] = markWithFrame(child, frame);
|
|
468
|
-
}
|
|
469
|
-
}
|
|
470
|
-
} else if (children) {
|
|
471
|
-
obj.children = markWithFrame(children, frame);
|
|
472
|
-
}
|
|
473
|
-
}
|
|
474
|
-
return node;
|
|
475
|
-
}
|
|
476
|
-
function ContextFunctionChildInvoker(props) {
|
|
477
|
-
const { fn, __frame } = props;
|
|
478
|
-
const res = withContext(__frame, () => fn());
|
|
479
|
-
if (res) return markWithFrame(res, __frame);
|
|
480
|
-
return null;
|
|
481
|
-
}
|
|
482
362
|
function getCurrentContextFrame() {
|
|
483
363
|
return currentContextFrame;
|
|
484
364
|
}
|
|
485
|
-
var CONTEXT_FRAME_SYMBOL, currentContextFrame, currentAsyncResourceFrame;
|
|
486
|
-
var init_context = __esm({
|
|
487
|
-
"src/runtime/context.ts"() {
|
|
488
|
-
"use strict";
|
|
489
|
-
init_component();
|
|
490
|
-
CONTEXT_FRAME_SYMBOL = /* @__PURE__ */ Symbol("__tempoContextFrame__");
|
|
491
|
-
currentContextFrame = null;
|
|
492
|
-
currentAsyncResourceFrame = null;
|
|
493
|
-
}
|
|
494
|
-
});
|
|
495
365
|
|
|
496
366
|
// src/renderer/diag/index.ts
|
|
497
367
|
function getDiagMap() {
|
|
@@ -500,7 +370,6 @@ function getDiagMap() {
|
|
|
500
370
|
if (!root.__ASKR_DIAG) root.__ASKR_DIAG = {};
|
|
501
371
|
return root.__ASKR_DIAG;
|
|
502
372
|
} catch (e) {
|
|
503
|
-
void e;
|
|
504
373
|
return {};
|
|
505
374
|
}
|
|
506
375
|
}
|
|
@@ -524,7 +393,6 @@ function __ASKR_set(key, value) {
|
|
|
524
393
|
void e;
|
|
525
394
|
}
|
|
526
395
|
} catch (e) {
|
|
527
|
-
void e;
|
|
528
396
|
}
|
|
529
397
|
}
|
|
530
398
|
function __ASKR_incCounter(key) {
|
|
@@ -546,180 +414,8 @@ function __ASKR_incCounter(key) {
|
|
|
546
414
|
void e;
|
|
547
415
|
}
|
|
548
416
|
} catch (e) {
|
|
549
|
-
void e;
|
|
550
417
|
}
|
|
551
418
|
}
|
|
552
|
-
var init_diag = __esm({
|
|
553
|
-
"src/renderer/diag/index.ts"() {
|
|
554
|
-
"use strict";
|
|
555
|
-
}
|
|
556
|
-
});
|
|
557
|
-
|
|
558
|
-
// src/runtime/dev-namespace.ts
|
|
559
|
-
function getDevNamespace() {
|
|
560
|
-
if (process.env.NODE_ENV === "production") return {};
|
|
561
|
-
try {
|
|
562
|
-
const g = globalThis;
|
|
563
|
-
if (!g.__ASKR__) g.__ASKR__ = {};
|
|
564
|
-
return g.__ASKR__;
|
|
565
|
-
} catch {
|
|
566
|
-
return {};
|
|
567
|
-
}
|
|
568
|
-
}
|
|
569
|
-
function setDevValue(key, value) {
|
|
570
|
-
if (process.env.NODE_ENV === "production") return;
|
|
571
|
-
try {
|
|
572
|
-
getDevNamespace()[key] = value;
|
|
573
|
-
} catch {
|
|
574
|
-
}
|
|
575
|
-
}
|
|
576
|
-
function getDevValue(key) {
|
|
577
|
-
if (process.env.NODE_ENV === "production") return void 0;
|
|
578
|
-
try {
|
|
579
|
-
return getDevNamespace()[key];
|
|
580
|
-
} catch {
|
|
581
|
-
return void 0;
|
|
582
|
-
}
|
|
583
|
-
}
|
|
584
|
-
var init_dev_namespace = __esm({
|
|
585
|
-
"src/runtime/dev-namespace.ts"() {
|
|
586
|
-
"use strict";
|
|
587
|
-
}
|
|
588
|
-
});
|
|
589
|
-
|
|
590
|
-
// src/runtime/fastlane-shared.ts
|
|
591
|
-
function enterBulkCommit() {
|
|
592
|
-
_bulkCommitActive = true;
|
|
593
|
-
_appliedParents = /* @__PURE__ */ new WeakSet();
|
|
594
|
-
try {
|
|
595
|
-
const cleared = globalScheduler.clearPendingSyncTasks?.() ?? 0;
|
|
596
|
-
setDevValue("__ASKR_FASTLANE_CLEARED_TASKS", cleared);
|
|
597
|
-
} catch (err) {
|
|
598
|
-
if (process.env.NODE_ENV !== "production") throw err;
|
|
599
|
-
}
|
|
600
|
-
}
|
|
601
|
-
function exitBulkCommit() {
|
|
602
|
-
_bulkCommitActive = false;
|
|
603
|
-
_appliedParents = null;
|
|
604
|
-
}
|
|
605
|
-
function isBulkCommitActive2() {
|
|
606
|
-
return _bulkCommitActive;
|
|
607
|
-
}
|
|
608
|
-
function markFastPathApplied(parent) {
|
|
609
|
-
if (!_appliedParents) return;
|
|
610
|
-
try {
|
|
611
|
-
_appliedParents.add(parent);
|
|
612
|
-
} catch (e) {
|
|
613
|
-
void e;
|
|
614
|
-
}
|
|
615
|
-
}
|
|
616
|
-
function isFastPathApplied(parent) {
|
|
617
|
-
return !!(_appliedParents && _appliedParents.has(parent));
|
|
618
|
-
}
|
|
619
|
-
var _bulkCommitActive, _appliedParents;
|
|
620
|
-
var init_fastlane_shared = __esm({
|
|
621
|
-
"src/runtime/fastlane-shared.ts"() {
|
|
622
|
-
"use strict";
|
|
623
|
-
init_scheduler();
|
|
624
|
-
init_dev_namespace();
|
|
625
|
-
_bulkCommitActive = false;
|
|
626
|
-
_appliedParents = null;
|
|
627
|
-
}
|
|
628
|
-
});
|
|
629
|
-
|
|
630
|
-
// src/renderer/types.ts
|
|
631
|
-
function _isDOMElement(node) {
|
|
632
|
-
return typeof node === "object" && node !== null && "type" in node;
|
|
633
|
-
}
|
|
634
|
-
var init_types = __esm({
|
|
635
|
-
"src/renderer/types.ts"() {
|
|
636
|
-
"use strict";
|
|
637
|
-
}
|
|
638
|
-
});
|
|
639
|
-
|
|
640
|
-
// src/renderer/cleanup.ts
|
|
641
|
-
function cleanupSingleInstance(node, errors, strict) {
|
|
642
|
-
const inst = node.__ASKR_INSTANCE;
|
|
643
|
-
if (!inst) return;
|
|
644
|
-
try {
|
|
645
|
-
cleanupComponent(inst);
|
|
646
|
-
} catch (err) {
|
|
647
|
-
if (strict) errors.push(err);
|
|
648
|
-
else logger.warn("[Askr] cleanupComponent failed:", err);
|
|
649
|
-
}
|
|
650
|
-
try {
|
|
651
|
-
delete node.__ASKR_INSTANCE;
|
|
652
|
-
} catch (e) {
|
|
653
|
-
if (strict) errors.push(e);
|
|
654
|
-
}
|
|
655
|
-
}
|
|
656
|
-
function cleanupInstanceIfPresent(node, opts) {
|
|
657
|
-
if (!node || !(node instanceof Element)) return;
|
|
658
|
-
const errors = [];
|
|
659
|
-
const strict = opts?.strict ?? false;
|
|
660
|
-
try {
|
|
661
|
-
cleanupSingleInstance(node, errors, strict);
|
|
662
|
-
} catch (err) {
|
|
663
|
-
if (strict) errors.push(err);
|
|
664
|
-
else logger.warn("[Askr] cleanupInstanceIfPresent failed:", err);
|
|
665
|
-
}
|
|
666
|
-
try {
|
|
667
|
-
const descendants = node.querySelectorAll("*");
|
|
668
|
-
for (const d of Array.from(descendants)) {
|
|
669
|
-
try {
|
|
670
|
-
cleanupSingleInstance(d, errors, strict);
|
|
671
|
-
} catch (err) {
|
|
672
|
-
if (strict) errors.push(err);
|
|
673
|
-
else
|
|
674
|
-
logger.warn(
|
|
675
|
-
"[Askr] cleanupInstanceIfPresent descendant cleanup failed:",
|
|
676
|
-
err
|
|
677
|
-
);
|
|
678
|
-
}
|
|
679
|
-
}
|
|
680
|
-
} catch (err) {
|
|
681
|
-
if (strict) errors.push(err);
|
|
682
|
-
else
|
|
683
|
-
logger.warn(
|
|
684
|
-
"[Askr] cleanupInstanceIfPresent descendant query failed:",
|
|
685
|
-
err
|
|
686
|
-
);
|
|
687
|
-
}
|
|
688
|
-
if (errors.length > 0) {
|
|
689
|
-
throw new AggregateError(errors, "cleanupInstanceIfPresent failed");
|
|
690
|
-
}
|
|
691
|
-
}
|
|
692
|
-
function cleanupInstancesUnder(node, opts) {
|
|
693
|
-
cleanupInstanceIfPresent(node, opts);
|
|
694
|
-
}
|
|
695
|
-
function removeElementListeners(element) {
|
|
696
|
-
const map = elementListeners.get(element);
|
|
697
|
-
if (map) {
|
|
698
|
-
for (const [eventName, entry] of map) {
|
|
699
|
-
if (entry.options !== void 0)
|
|
700
|
-
element.removeEventListener(eventName, entry.handler, entry.options);
|
|
701
|
-
else element.removeEventListener(eventName, entry.handler);
|
|
702
|
-
}
|
|
703
|
-
elementListeners.delete(element);
|
|
704
|
-
}
|
|
705
|
-
}
|
|
706
|
-
function removeAllListeners(root) {
|
|
707
|
-
if (!root) return;
|
|
708
|
-
removeElementListeners(root);
|
|
709
|
-
const children = root.querySelectorAll("*");
|
|
710
|
-
for (let i = 0; i < children.length; i++) {
|
|
711
|
-
removeElementListeners(children[i]);
|
|
712
|
-
}
|
|
713
|
-
}
|
|
714
|
-
var elementListeners;
|
|
715
|
-
var init_cleanup = __esm({
|
|
716
|
-
"src/renderer/cleanup.ts"() {
|
|
717
|
-
"use strict";
|
|
718
|
-
init_component();
|
|
719
|
-
init_logger();
|
|
720
|
-
elementListeners = /* @__PURE__ */ new WeakMap();
|
|
721
|
-
}
|
|
722
|
-
});
|
|
723
419
|
|
|
724
420
|
// src/renderer/utils.ts
|
|
725
421
|
function parseEventName(propName) {
|
|
@@ -742,8 +438,8 @@ function createWrappedHandler(handler, flushAfter = false) {
|
|
|
742
438
|
} finally {
|
|
743
439
|
globalScheduler.setInHandler(false);
|
|
744
440
|
if (flushAfter) {
|
|
745
|
-
const
|
|
746
|
-
if ((
|
|
441
|
+
const state = globalScheduler.getState();
|
|
442
|
+
if ((state.queueLength ?? 0) > 0 && !state.running) {
|
|
747
443
|
queueMicrotask(() => {
|
|
748
444
|
try {
|
|
749
445
|
if (!globalScheduler.isExecuting()) globalScheduler.flush();
|
|
@@ -809,8 +505,7 @@ function extractKey(vnode) {
|
|
|
809
505
|
}
|
|
810
506
|
function buildKeyMapFromChildren(parent) {
|
|
811
507
|
const map = /* @__PURE__ */ new Map();
|
|
812
|
-
|
|
813
|
-
for (const ch of children) {
|
|
508
|
+
for (let ch = parent.firstElementChild; ch; ch = ch.nextElementSibling) {
|
|
814
509
|
const k = ch.getAttribute("data-key");
|
|
815
510
|
if (k !== null) {
|
|
816
511
|
map.set(k, ch);
|
|
@@ -851,16 +546,9 @@ function logFastPathDebug(message, indexOrData, data) {
|
|
|
851
546
|
function now() {
|
|
852
547
|
return typeof performance !== "undefined" && performance.now ? performance.now() : Date.now();
|
|
853
548
|
}
|
|
854
|
-
var init_utils = __esm({
|
|
855
|
-
"src/renderer/utils.ts"() {
|
|
856
|
-
"use strict";
|
|
857
|
-
init_scheduler();
|
|
858
|
-
init_logger();
|
|
859
|
-
init_diag();
|
|
860
|
-
}
|
|
861
|
-
});
|
|
862
549
|
|
|
863
550
|
// src/renderer/keyed.ts
|
|
551
|
+
var keyedElements = /* @__PURE__ */ new WeakMap();
|
|
864
552
|
function getKeyMapForElement(el) {
|
|
865
553
|
return keyedElements.get(el);
|
|
866
554
|
}
|
|
@@ -884,6 +572,7 @@ function populateKeyMapForElement(parent) {
|
|
|
884
572
|
} catch {
|
|
885
573
|
}
|
|
886
574
|
}
|
|
575
|
+
var _reconcilerRecordedParents = /* @__PURE__ */ new WeakSet();
|
|
887
576
|
function extractKeyedVnodes(newChildren) {
|
|
888
577
|
const result = [];
|
|
889
578
|
for (const child of newChildren) {
|
|
@@ -975,398 +664,739 @@ function isKeyedReorderFastPathEligible(parent, newChildren, oldKeyMap) {
|
|
|
975
664
|
hasPropChanges
|
|
976
665
|
};
|
|
977
666
|
}
|
|
978
|
-
var keyedElements, _reconcilerRecordedParents;
|
|
979
|
-
var init_keyed = __esm({
|
|
980
|
-
"src/renderer/keyed.ts"() {
|
|
981
|
-
"use strict";
|
|
982
|
-
init_utils();
|
|
983
|
-
keyedElements = /* @__PURE__ */ new WeakMap();
|
|
984
|
-
_reconcilerRecordedParents = /* @__PURE__ */ new WeakSet();
|
|
985
|
-
}
|
|
986
|
-
});
|
|
987
667
|
|
|
988
|
-
// src/jsx
|
|
989
|
-
var ELEMENT_TYPE
|
|
990
|
-
var
|
|
991
|
-
"src/jsx/types.ts"() {
|
|
992
|
-
"use strict";
|
|
993
|
-
ELEMENT_TYPE = /* @__PURE__ */ Symbol.for("askr.element");
|
|
994
|
-
Fragment = /* @__PURE__ */ Symbol.for("askr.fragment");
|
|
995
|
-
}
|
|
996
|
-
});
|
|
668
|
+
// src/common/jsx.ts
|
|
669
|
+
var ELEMENT_TYPE = /* @__PURE__ */ Symbol.for("askr.element");
|
|
670
|
+
var Fragment = /* @__PURE__ */ Symbol.for("askr.fragment");
|
|
997
671
|
|
|
998
|
-
// src/
|
|
999
|
-
function
|
|
1000
|
-
return {
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
}
|
|
1006
|
-
}
|
|
1007
|
-
|
|
1008
|
-
return jsxDEV(type, props, key);
|
|
672
|
+
// src/runtime/dev-namespace.ts
|
|
673
|
+
function getDevNamespace() {
|
|
674
|
+
if (process.env.NODE_ENV === "production") return {};
|
|
675
|
+
try {
|
|
676
|
+
const g = globalThis;
|
|
677
|
+
if (!g.__ASKR__) g.__ASKR__ = {};
|
|
678
|
+
return g.__ASKR__;
|
|
679
|
+
} catch {
|
|
680
|
+
return {};
|
|
681
|
+
}
|
|
1009
682
|
}
|
|
1010
|
-
function
|
|
1011
|
-
|
|
683
|
+
function setDevValue(key, value) {
|
|
684
|
+
if (process.env.NODE_ENV === "production") return;
|
|
685
|
+
try {
|
|
686
|
+
getDevNamespace()[key] = value;
|
|
687
|
+
} catch {
|
|
688
|
+
}
|
|
1012
689
|
}
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
Fragment2 = /* @__PURE__ */ Symbol.for("askr.fragment");
|
|
690
|
+
function getDevValue(key) {
|
|
691
|
+
if (process.env.NODE_ENV === "production") return void 0;
|
|
692
|
+
try {
|
|
693
|
+
return getDevNamespace()[key];
|
|
694
|
+
} catch {
|
|
695
|
+
return void 0;
|
|
1020
696
|
}
|
|
1021
|
-
}
|
|
697
|
+
}
|
|
1022
698
|
|
|
1023
|
-
// src/
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
699
|
+
// src/runtime/fastlane.ts
|
|
700
|
+
var _bulkCommitActive = false;
|
|
701
|
+
var _appliedParents = null;
|
|
702
|
+
function enterBulkCommit() {
|
|
703
|
+
_bulkCommitActive = true;
|
|
704
|
+
_appliedParents = /* @__PURE__ */ new WeakSet();
|
|
705
|
+
try {
|
|
706
|
+
const cleared = globalScheduler.clearPendingSyncTasks?.() ?? 0;
|
|
707
|
+
setDevValue("__ASKR_FASTLANE_CLEARED_TASKS", cleared);
|
|
708
|
+
} catch (err) {
|
|
709
|
+
if (process.env.NODE_ENV !== "production") throw err;
|
|
1031
710
|
}
|
|
1032
|
-
|
|
1033
|
-
|
|
711
|
+
}
|
|
712
|
+
function exitBulkCommit() {
|
|
713
|
+
_bulkCommitActive = false;
|
|
714
|
+
_appliedParents = null;
|
|
715
|
+
}
|
|
716
|
+
function isBulkCommitActive2() {
|
|
717
|
+
return _bulkCommitActive;
|
|
718
|
+
}
|
|
719
|
+
function markFastPathApplied(parent) {
|
|
720
|
+
if (!_appliedParents) return;
|
|
721
|
+
try {
|
|
722
|
+
_appliedParents.add(parent);
|
|
723
|
+
} catch (e) {
|
|
1034
724
|
}
|
|
1035
|
-
elementListeners.get(el).set(eventName, {
|
|
1036
|
-
handler: wrappedHandler,
|
|
1037
|
-
original: handler,
|
|
1038
|
-
options
|
|
1039
|
-
});
|
|
1040
725
|
}
|
|
1041
|
-
function
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
726
|
+
function isFastPathApplied(parent) {
|
|
727
|
+
return !!(_appliedParents && _appliedParents.has(parent));
|
|
728
|
+
}
|
|
729
|
+
function finalizeReadSubscriptions(instance) {
|
|
730
|
+
const newSet = instance._pendingReadStates ?? /* @__PURE__ */ new Set();
|
|
731
|
+
const oldSet = instance._lastReadStates ?? /* @__PURE__ */ new Set();
|
|
732
|
+
const token = instance._currentRenderToken;
|
|
733
|
+
if (token === void 0) return;
|
|
734
|
+
for (const s of oldSet) {
|
|
735
|
+
if (!newSet.has(s)) {
|
|
736
|
+
const readers = s._readers;
|
|
737
|
+
if (readers) readers.delete(instance);
|
|
1050
738
|
}
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
739
|
+
}
|
|
740
|
+
instance.lastRenderToken = token;
|
|
741
|
+
for (const s of newSet) {
|
|
742
|
+
let readers = s._readers;
|
|
743
|
+
if (!readers) {
|
|
744
|
+
readers = /* @__PURE__ */ new Map();
|
|
745
|
+
s._readers = readers;
|
|
1057
746
|
}
|
|
747
|
+
readers.set(instance, instance.lastRenderToken ?? 0);
|
|
1058
748
|
}
|
|
749
|
+
instance._lastReadStates = newSet;
|
|
750
|
+
instance._pendingReadStates = /* @__PURE__ */ new Set();
|
|
751
|
+
instance._currentRenderToken = void 0;
|
|
1059
752
|
}
|
|
1060
|
-
function
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
el.setAttribute("checked", String(Boolean(value)));
|
|
753
|
+
function unwrapFragmentForFastPath(vnode) {
|
|
754
|
+
if (!vnode || typeof vnode !== "object" || !("type" in vnode)) return vnode;
|
|
755
|
+
const v = vnode;
|
|
756
|
+
if (typeof v.type === "symbol" && (v.type === Fragment || String(v.type) === "Symbol(askr.fragment)")) {
|
|
757
|
+
const children = v.children || v.props?.children;
|
|
758
|
+
if (Array.isArray(children) && children.length > 0) {
|
|
759
|
+
for (const child of children) {
|
|
760
|
+
if (child && typeof child === "object" && "type" in child) {
|
|
761
|
+
const c = child;
|
|
762
|
+
if (typeof c.type === "string") {
|
|
763
|
+
return child;
|
|
764
|
+
}
|
|
765
|
+
}
|
|
766
|
+
}
|
|
1075
767
|
}
|
|
1076
768
|
}
|
|
769
|
+
return vnode;
|
|
1077
770
|
}
|
|
1078
|
-
function
|
|
1079
|
-
const
|
|
1080
|
-
if (
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
771
|
+
function classifyUpdate(instance, result) {
|
|
772
|
+
const unwrappedResult = unwrapFragmentForFastPath(result);
|
|
773
|
+
if (!unwrappedResult || typeof unwrappedResult !== "object" || !("type" in unwrappedResult))
|
|
774
|
+
return { useFastPath: false, reason: "not-vnode" };
|
|
775
|
+
const vnode = unwrappedResult;
|
|
776
|
+
if (vnode == null || typeof vnode.type !== "string")
|
|
777
|
+
return { useFastPath: false, reason: "not-intrinsic" };
|
|
778
|
+
const parent = instance.target;
|
|
779
|
+
if (!parent) return { useFastPath: false, reason: "no-root" };
|
|
780
|
+
const firstChild = parent.children[0];
|
|
781
|
+
if (!firstChild) return { useFastPath: false, reason: "no-first-child" };
|
|
782
|
+
if (firstChild.tagName.toLowerCase() !== String(vnode.type).toLowerCase())
|
|
783
|
+
return { useFastPath: false, reason: "root-tag-mismatch" };
|
|
784
|
+
const children = vnode.children || vnode.props?.children;
|
|
785
|
+
if (!Array.isArray(children))
|
|
786
|
+
return { useFastPath: false, reason: "no-children-array" };
|
|
787
|
+
for (const c of children) {
|
|
788
|
+
if (typeof c === "object" && c !== null && "type" in c && typeof c.type === "function") {
|
|
789
|
+
return { useFastPath: false, reason: "component-child-present" };
|
|
1096
790
|
}
|
|
1097
791
|
}
|
|
1098
|
-
if (
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
`Missing keys on dynamic lists in ${name}. Each child in a list should have a unique "key" prop.`
|
|
1104
|
-
);
|
|
1105
|
-
} catch {
|
|
1106
|
-
logger.warn(
|
|
1107
|
-
'Missing keys on dynamic lists. Each child in a list should have a unique "key" prop.'
|
|
1108
|
-
);
|
|
1109
|
-
}
|
|
792
|
+
if (instance.mountOperations.length > 0)
|
|
793
|
+
return { useFastPath: false, reason: "pending-mounts" };
|
|
794
|
+
try {
|
|
795
|
+
populateKeyMapForElement(firstChild);
|
|
796
|
+
} catch {
|
|
1110
797
|
}
|
|
798
|
+
const oldKeyMap = getKeyMapForElement(firstChild);
|
|
799
|
+
const decision = isKeyedReorderFastPathEligible(
|
|
800
|
+
firstChild,
|
|
801
|
+
children,
|
|
802
|
+
oldKeyMap
|
|
803
|
+
);
|
|
804
|
+
if (!decision.useFastPath || decision.totalKeyed < 128)
|
|
805
|
+
return { ...decision, useFastPath: false, reason: "renderer-declined" };
|
|
806
|
+
return { ...decision, useFastPath: true };
|
|
1111
807
|
}
|
|
1112
|
-
function
|
|
1113
|
-
|
|
1114
|
-
|
|
808
|
+
function commitReorderOnly(instance, result) {
|
|
809
|
+
const evaluate2 = globalThis.__ASKR_RENDERER?.evaluate;
|
|
810
|
+
if (typeof evaluate2 !== "function") {
|
|
811
|
+
logger.warn(
|
|
812
|
+
"[Tempo][FASTPATH][DEV] renderer.evaluate not available; declining fast-lane"
|
|
813
|
+
);
|
|
814
|
+
return false;
|
|
815
|
+
}
|
|
816
|
+
const schedBefore = process.env.NODE_ENV !== "production" ? globalScheduler.getState() : null;
|
|
817
|
+
enterBulkCommit();
|
|
818
|
+
try {
|
|
819
|
+
globalScheduler.runWithSyncProgress(() => {
|
|
820
|
+
evaluate2(result, instance.target);
|
|
1115
821
|
try {
|
|
1116
|
-
|
|
1117
|
-
} catch {
|
|
822
|
+
finalizeReadSubscriptions(instance);
|
|
823
|
+
} catch (e) {
|
|
824
|
+
if (process.env.NODE_ENV !== "production") throw e;
|
|
1118
825
|
}
|
|
826
|
+
});
|
|
827
|
+
const clearedAfter = globalScheduler.clearPendingSyncTasks?.() ?? 0;
|
|
828
|
+
setDevValue("__FASTLANE_CLEARED_AFTER", clearedAfter);
|
|
829
|
+
if (process.env.NODE_ENV !== "production") {
|
|
830
|
+
validateFastLaneInvariants(instance, schedBefore);
|
|
1119
831
|
}
|
|
1120
|
-
return
|
|
1121
|
-
}
|
|
1122
|
-
|
|
1123
|
-
return document.createTextNode(node);
|
|
1124
|
-
}
|
|
1125
|
-
if (typeof node === "number") {
|
|
1126
|
-
return document.createTextNode(String(node));
|
|
1127
|
-
}
|
|
1128
|
-
if (!node) {
|
|
1129
|
-
return null;
|
|
1130
|
-
}
|
|
1131
|
-
if (Array.isArray(node)) {
|
|
1132
|
-
const fragment = document.createDocumentFragment();
|
|
1133
|
-
for (const child of node) {
|
|
1134
|
-
const dom = createDOMNode(child);
|
|
1135
|
-
if (dom) fragment.appendChild(dom);
|
|
1136
|
-
}
|
|
1137
|
-
return fragment;
|
|
832
|
+
return true;
|
|
833
|
+
} finally {
|
|
834
|
+
exitBulkCommit();
|
|
1138
835
|
}
|
|
1139
|
-
if (
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
}
|
|
1145
|
-
if (typeof type === "function") {
|
|
1146
|
-
return createComponentElement(node, type, props);
|
|
1147
|
-
}
|
|
1148
|
-
if (typeof type === "symbol" && (type === Fragment2 || String(type) === "Symbol(Fragment)")) {
|
|
1149
|
-
return createFragmentElement(node, props);
|
|
836
|
+
if (process.env.NODE_ENV !== "production") {
|
|
837
|
+
if (isBulkCommitActive2()) {
|
|
838
|
+
throw new Error(
|
|
839
|
+
"Fast-lane invariant violated: bulk commit flag still set after commit"
|
|
840
|
+
);
|
|
1150
841
|
}
|
|
1151
842
|
}
|
|
1152
|
-
return null;
|
|
1153
843
|
}
|
|
1154
|
-
function
|
|
1155
|
-
const
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
844
|
+
function validateFastLaneInvariants(instance, schedBefore) {
|
|
845
|
+
const commitCount = getDevValue("__LAST_FASTPATH_COMMIT_COUNT") ?? 0;
|
|
846
|
+
const invariants = {
|
|
847
|
+
commitCount,
|
|
848
|
+
mountOps: instance.mountOperations.length,
|
|
849
|
+
cleanupFns: instance.cleanupFns.length
|
|
850
|
+
};
|
|
851
|
+
setDevValue("__LAST_FASTLANE_INVARIANTS", invariants);
|
|
852
|
+
if (commitCount !== 1) {
|
|
853
|
+
console.error(
|
|
854
|
+
"[FASTLANE][INV] commitCount",
|
|
855
|
+
commitCount,
|
|
856
|
+
"diag",
|
|
857
|
+
globalThis.__ASKR_DIAG
|
|
858
|
+
);
|
|
859
|
+
throw new Error(
|
|
860
|
+
"Fast-lane invariant violated: expected exactly one DOM commit during reorder-only commit"
|
|
861
|
+
);
|
|
1170
862
|
}
|
|
1171
|
-
|
|
1172
|
-
}
|
|
1173
|
-
function createComponentElement(node, type, props) {
|
|
1174
|
-
const frame = node[CONTEXT_FRAME_SYMBOL];
|
|
1175
|
-
const snapshot = frame || getCurrentContextFrame();
|
|
1176
|
-
const componentFn = type;
|
|
1177
|
-
const isAsync = componentFn.constructor.name === "AsyncFunction";
|
|
1178
|
-
if (isAsync) {
|
|
863
|
+
if (invariants.mountOps > 0) {
|
|
1179
864
|
throw new Error(
|
|
1180
|
-
"
|
|
865
|
+
"Fast-lane invariant violated: mount operations were registered during bulk commit"
|
|
1181
866
|
);
|
|
1182
867
|
}
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
`comp-${Math.random().toString(36).slice(2, 7)}`,
|
|
1187
|
-
componentFn,
|
|
1188
|
-
props || {},
|
|
1189
|
-
null
|
|
868
|
+
if (invariants.cleanupFns > 0) {
|
|
869
|
+
throw new Error(
|
|
870
|
+
"Fast-lane invariant violated: cleanup functions were added during bulk commit"
|
|
1190
871
|
);
|
|
1191
|
-
node.__instance = childInstance;
|
|
1192
872
|
}
|
|
1193
|
-
|
|
1194
|
-
|
|
873
|
+
const schedAfter = globalScheduler.getState();
|
|
874
|
+
if (schedBefore && schedAfter && schedAfter.taskCount > schedBefore.taskCount) {
|
|
875
|
+
console.error(
|
|
876
|
+
"[FASTLANE] schedBefore, schedAfter",
|
|
877
|
+
schedBefore,
|
|
878
|
+
schedAfter
|
|
879
|
+
);
|
|
880
|
+
console.error("[FASTLANE] enqueue logs", getDevValue("__ENQUEUE_LOGS"));
|
|
881
|
+
throw new Error(
|
|
882
|
+
"Fast-lane invariant violated: scheduler enqueued leftover work during bulk commit"
|
|
883
|
+
);
|
|
1195
884
|
}
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
885
|
+
let finalState = globalScheduler.getState();
|
|
886
|
+
const executing = globalScheduler.isExecuting();
|
|
887
|
+
let outstandingAfter = Math.max(
|
|
888
|
+
0,
|
|
889
|
+
finalState.taskCount - (executing ? 1 : 0)
|
|
1199
890
|
);
|
|
1200
|
-
if (
|
|
1201
|
-
|
|
1202
|
-
|
|
891
|
+
if (outstandingAfter !== 0) {
|
|
892
|
+
let attempts = 0;
|
|
893
|
+
while (attempts < 5) {
|
|
894
|
+
const cleared = globalScheduler.clearPendingSyncTasks?.() ?? 0;
|
|
895
|
+
if (cleared === 0) break;
|
|
896
|
+
attempts++;
|
|
897
|
+
}
|
|
898
|
+
finalState = globalScheduler.getState();
|
|
899
|
+
outstandingAfter = Math.max(
|
|
900
|
+
0,
|
|
901
|
+
finalState.taskCount - (globalScheduler.isExecuting() ? 1 : 0)
|
|
1203
902
|
);
|
|
903
|
+
if (outstandingAfter !== 0) {
|
|
904
|
+
console.error(
|
|
905
|
+
"[FASTLANE] Post-commit enqueue logs:",
|
|
906
|
+
getDevValue("__ENQUEUE_LOGS")
|
|
907
|
+
);
|
|
908
|
+
console.error(
|
|
909
|
+
"[FASTLANE] Cleared counts:",
|
|
910
|
+
getDevValue("__FASTLANE_CLEARED_TASKS"),
|
|
911
|
+
getDevValue("__FASTLANE_CLEARED_AFTER")
|
|
912
|
+
);
|
|
913
|
+
throw new Error(
|
|
914
|
+
`Fast-lane invariant violated: scheduler has ${finalState.taskCount} pending task(s) after commit`
|
|
915
|
+
);
|
|
916
|
+
}
|
|
1204
917
|
}
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
918
|
+
}
|
|
919
|
+
function tryRuntimeFastLaneSync(instance, result) {
|
|
920
|
+
const cls = classifyUpdate(instance, result);
|
|
921
|
+
if (!cls.useFastPath) {
|
|
922
|
+
setDevValue("__LAST_FASTPATH_STATS", void 0);
|
|
923
|
+
setDevValue("__LAST_FASTPATH_COMMIT_COUNT", 0);
|
|
924
|
+
return false;
|
|
1209
925
|
}
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
return placeholder;
|
|
926
|
+
try {
|
|
927
|
+
return commitReorderOnly(instance, result);
|
|
928
|
+
} catch (err) {
|
|
929
|
+
if (process.env.NODE_ENV !== "production") throw err;
|
|
930
|
+
return false;
|
|
1216
931
|
}
|
|
1217
|
-
const host = document.createElement("div");
|
|
1218
|
-
host.appendChild(dom);
|
|
1219
|
-
mountInstanceInline(childInstance, host);
|
|
1220
|
-
return host;
|
|
1221
932
|
}
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
933
|
+
if (typeof globalThis !== "undefined") {
|
|
934
|
+
globalThis.__ASKR_FASTLANE = {
|
|
935
|
+
isBulkCommitActive: isBulkCommitActive2,
|
|
936
|
+
enterBulkCommit,
|
|
937
|
+
exitBulkCommit,
|
|
938
|
+
tryRuntimeFastLaneSync,
|
|
939
|
+
markFastPathApplied,
|
|
940
|
+
isFastPathApplied
|
|
941
|
+
};
|
|
942
|
+
}
|
|
943
|
+
|
|
944
|
+
// src/common/vnode.ts
|
|
945
|
+
function _isDOMElement(node) {
|
|
946
|
+
return typeof node === "object" && node !== null && "type" in node;
|
|
947
|
+
}
|
|
948
|
+
|
|
949
|
+
// src/renderer/cleanup.ts
|
|
950
|
+
function cleanupSingleInstance(node, errors, strict) {
|
|
951
|
+
const inst = node.__ASKR_INSTANCE;
|
|
952
|
+
if (!inst) return;
|
|
953
|
+
try {
|
|
954
|
+
cleanupComponent(inst);
|
|
955
|
+
} catch (err) {
|
|
956
|
+
logger.warn("[Askr] cleanupComponent failed:", err);
|
|
957
|
+
}
|
|
958
|
+
try {
|
|
959
|
+
delete node.__ASKR_INSTANCE;
|
|
960
|
+
} catch (e) {
|
|
961
|
+
}
|
|
962
|
+
}
|
|
963
|
+
function forEachDescendantElement(root, visit) {
|
|
964
|
+
try {
|
|
965
|
+
const doc = root.ownerDocument;
|
|
966
|
+
const createTreeWalker = doc?.createTreeWalker;
|
|
967
|
+
if (typeof createTreeWalker === "function") {
|
|
968
|
+
const walker = createTreeWalker.call(doc, root, 1);
|
|
969
|
+
let n = walker.firstChild();
|
|
970
|
+
while (n) {
|
|
971
|
+
visit(n);
|
|
972
|
+
n = walker.nextNode();
|
|
1230
973
|
}
|
|
1231
|
-
|
|
1232
|
-
const dom = createDOMNode(children);
|
|
1233
|
-
if (dom) fragment.appendChild(dom);
|
|
974
|
+
return;
|
|
1234
975
|
}
|
|
976
|
+
} catch {
|
|
977
|
+
}
|
|
978
|
+
const descendants = root.querySelectorAll("*");
|
|
979
|
+
for (let i = 0; i < descendants.length; i++) {
|
|
980
|
+
visit(descendants[i]);
|
|
1235
981
|
}
|
|
1236
|
-
return fragment;
|
|
1237
982
|
}
|
|
1238
|
-
function
|
|
1239
|
-
if (!
|
|
1240
|
-
|
|
983
|
+
function cleanupInstanceIfPresent(node, opts) {
|
|
984
|
+
if (!node || !(node instanceof Element)) return;
|
|
985
|
+
const strict = false;
|
|
986
|
+
const errors = null;
|
|
987
|
+
try {
|
|
988
|
+
cleanupSingleInstance(node, errors, strict);
|
|
989
|
+
} catch (err) {
|
|
990
|
+
logger.warn("[Askr] cleanupInstanceIfPresent failed:", err);
|
|
1241
991
|
}
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
992
|
+
try {
|
|
993
|
+
forEachDescendantElement(node, (d) => {
|
|
994
|
+
try {
|
|
995
|
+
cleanupSingleInstance(d, errors, strict);
|
|
996
|
+
} catch (err) {
|
|
997
|
+
if (strict) ;
|
|
998
|
+
else
|
|
999
|
+
logger.warn(
|
|
1000
|
+
"[Askr] cleanupInstanceIfPresent descendant cleanup failed:",
|
|
1001
|
+
err
|
|
1002
|
+
);
|
|
1003
|
+
}
|
|
1004
|
+
});
|
|
1005
|
+
} catch (err) {
|
|
1006
|
+
logger.warn(
|
|
1007
|
+
"[Askr] cleanupInstanceIfPresent descendant query failed:",
|
|
1008
|
+
err
|
|
1009
|
+
);
|
|
1010
|
+
}
|
|
1011
|
+
}
|
|
1012
|
+
function cleanupInstancesUnder(node, opts) {
|
|
1013
|
+
cleanupInstanceIfPresent(node);
|
|
1014
|
+
}
|
|
1015
|
+
var elementListeners = /* @__PURE__ */ new WeakMap();
|
|
1016
|
+
function removeElementListeners(element) {
|
|
1017
|
+
const map = elementListeners.get(element);
|
|
1018
|
+
if (map) {
|
|
1019
|
+
for (const [eventName, entry] of map) {
|
|
1020
|
+
if (entry.options !== void 0)
|
|
1021
|
+
element.removeEventListener(eventName, entry.handler, entry.options);
|
|
1022
|
+
else element.removeEventListener(eventName, entry.handler);
|
|
1023
|
+
}
|
|
1024
|
+
elementListeners.delete(element);
|
|
1025
|
+
}
|
|
1026
|
+
}
|
|
1027
|
+
function removeAllListeners(root) {
|
|
1028
|
+
if (!root) return;
|
|
1029
|
+
removeElementListeners(root);
|
|
1030
|
+
forEachDescendantElement(root, removeElementListeners);
|
|
1031
|
+
}
|
|
1032
|
+
|
|
1033
|
+
// src/renderer/dom.ts
|
|
1034
|
+
var IS_DOM_AVAILABLE = typeof document !== "undefined";
|
|
1035
|
+
function addTrackedListener(el, eventName, handler) {
|
|
1036
|
+
const wrappedHandler = createWrappedHandler(handler, true);
|
|
1037
|
+
const options = getPassiveOptions(eventName);
|
|
1038
|
+
if (options !== void 0) {
|
|
1039
|
+
el.addEventListener(eventName, wrappedHandler, options);
|
|
1040
|
+
} else {
|
|
1041
|
+
el.addEventListener(eventName, wrappedHandler);
|
|
1042
|
+
}
|
|
1043
|
+
if (!elementListeners.has(el)) {
|
|
1044
|
+
elementListeners.set(el, /* @__PURE__ */ new Map());
|
|
1045
|
+
}
|
|
1046
|
+
elementListeners.get(el).set(eventName, {
|
|
1047
|
+
handler: wrappedHandler,
|
|
1048
|
+
original: handler,
|
|
1049
|
+
options
|
|
1050
|
+
});
|
|
1051
|
+
}
|
|
1052
|
+
function applyPropsToElement(el, props, tagName) {
|
|
1246
1053
|
for (const key in props) {
|
|
1247
1054
|
const value = props[key];
|
|
1248
1055
|
if (isSkippedProp(key)) continue;
|
|
1056
|
+
if (value === void 0 || value === null || value === false) continue;
|
|
1249
1057
|
const eventName = parseEventName(key);
|
|
1250
|
-
if (
|
|
1251
|
-
|
|
1252
|
-
el.className = "";
|
|
1253
|
-
} else if (eventName && existingListeners?.has(eventName)) {
|
|
1254
|
-
const entry = existingListeners.get(eventName);
|
|
1255
|
-
if (entry.options !== void 0) {
|
|
1256
|
-
el.removeEventListener(eventName, entry.handler, entry.options);
|
|
1257
|
-
} else {
|
|
1258
|
-
el.removeEventListener(eventName, entry.handler);
|
|
1259
|
-
}
|
|
1260
|
-
existingListeners.delete(eventName);
|
|
1261
|
-
} else {
|
|
1262
|
-
el.removeAttribute(key);
|
|
1263
|
-
}
|
|
1058
|
+
if (eventName) {
|
|
1059
|
+
addTrackedListener(el, eventName, value);
|
|
1264
1060
|
continue;
|
|
1265
1061
|
}
|
|
1266
1062
|
if (key === "class" || key === "className") {
|
|
1267
1063
|
el.className = String(value);
|
|
1268
1064
|
} else if (key === "value" || key === "checked") {
|
|
1269
|
-
el
|
|
1270
|
-
} else if (eventName) {
|
|
1271
|
-
desiredEventNames.add(eventName);
|
|
1272
|
-
const existing = existingListeners?.get(eventName);
|
|
1273
|
-
if (existing && existing.original === value) {
|
|
1274
|
-
continue;
|
|
1275
|
-
}
|
|
1276
|
-
if (existing) {
|
|
1277
|
-
el.removeEventListener(eventName, existing.handler);
|
|
1278
|
-
}
|
|
1279
|
-
const wrappedHandler = createWrappedHandler(
|
|
1280
|
-
value,
|
|
1281
|
-
false
|
|
1282
|
-
);
|
|
1283
|
-
const options = getPassiveOptions(eventName);
|
|
1284
|
-
if (options !== void 0) {
|
|
1285
|
-
el.addEventListener(eventName, wrappedHandler, options);
|
|
1286
|
-
} else {
|
|
1287
|
-
el.addEventListener(eventName, wrappedHandler);
|
|
1288
|
-
}
|
|
1289
|
-
if (!elementListeners.has(el)) {
|
|
1290
|
-
elementListeners.set(el, /* @__PURE__ */ new Map());
|
|
1291
|
-
}
|
|
1292
|
-
elementListeners.get(el).set(eventName, {
|
|
1293
|
-
handler: wrappedHandler,
|
|
1294
|
-
original: value,
|
|
1295
|
-
options
|
|
1296
|
-
});
|
|
1065
|
+
applyFormControlProp(el, key, value, tagName);
|
|
1297
1066
|
} else {
|
|
1298
1067
|
el.setAttribute(key, String(value));
|
|
1299
1068
|
}
|
|
1300
1069
|
}
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1070
|
+
}
|
|
1071
|
+
function applyFormControlProp(el, key, value, tagName) {
|
|
1072
|
+
if (key === "value") {
|
|
1073
|
+
if (tagNamesEqualIgnoreCase(tagName, "input") || tagNamesEqualIgnoreCase(tagName, "textarea") || tagNamesEqualIgnoreCase(tagName, "select")) {
|
|
1074
|
+
el.value = String(value);
|
|
1075
|
+
el.setAttribute("value", String(value));
|
|
1076
|
+
} else {
|
|
1077
|
+
el.setAttribute("value", String(value));
|
|
1078
|
+
}
|
|
1079
|
+
} else if (key === "checked") {
|
|
1080
|
+
if (tagNamesEqualIgnoreCase(tagName, "input")) {
|
|
1081
|
+
el.checked = Boolean(value);
|
|
1082
|
+
el.setAttribute("checked", String(Boolean(value)));
|
|
1083
|
+
} else {
|
|
1084
|
+
el.setAttribute("checked", String(Boolean(value)));
|
|
1308
1085
|
}
|
|
1309
|
-
if (existingListeners.size === 0) elementListeners.delete(el);
|
|
1310
|
-
}
|
|
1311
|
-
if (updateChildren) {
|
|
1312
|
-
const children = vnode.children || props.children;
|
|
1313
|
-
updateElementChildren(el, children);
|
|
1314
1086
|
}
|
|
1315
1087
|
}
|
|
1316
|
-
function
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1088
|
+
function materializeKey(el, vnode, props) {
|
|
1089
|
+
const vnodeKey = vnode.key ?? props?.key;
|
|
1090
|
+
if (vnodeKey !== void 0) {
|
|
1091
|
+
el.setAttribute("data-key", String(vnodeKey));
|
|
1320
1092
|
}
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1093
|
+
}
|
|
1094
|
+
function warnMissingKeys(children) {
|
|
1095
|
+
if (process.env.NODE_ENV === "production") return;
|
|
1096
|
+
let hasElements = false;
|
|
1097
|
+
let hasKeys = false;
|
|
1098
|
+
for (const item of children) {
|
|
1099
|
+
if (typeof item === "object" && item !== null && "type" in item) {
|
|
1100
|
+
hasElements = true;
|
|
1101
|
+
const rawKey = item.key ?? item.props?.key;
|
|
1102
|
+
if (rawKey !== void 0) {
|
|
1103
|
+
hasKeys = true;
|
|
1104
|
+
break;
|
|
1105
|
+
}
|
|
1326
1106
|
}
|
|
1327
|
-
return;
|
|
1328
1107
|
}
|
|
1329
|
-
if (
|
|
1330
|
-
|
|
1331
|
-
|
|
1108
|
+
if (hasElements && !hasKeys) {
|
|
1109
|
+
try {
|
|
1110
|
+
const inst = getCurrentInstance();
|
|
1111
|
+
const name = inst?.fn?.name || "<anonymous>";
|
|
1112
|
+
logger.warn(
|
|
1113
|
+
`Missing keys on dynamic lists in ${name}. Each child in a list should have a unique "key" prop.`
|
|
1114
|
+
);
|
|
1115
|
+
} catch {
|
|
1116
|
+
logger.warn(
|
|
1117
|
+
'Missing keys on dynamic lists. Each child in a list should have a unique "key" prop.'
|
|
1118
|
+
);
|
|
1119
|
+
}
|
|
1332
1120
|
}
|
|
1333
|
-
el.textContent = "";
|
|
1334
|
-
const dom = createDOMNode(children);
|
|
1335
|
-
if (dom) el.appendChild(dom);
|
|
1336
1121
|
}
|
|
1337
|
-
function
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
return;
|
|
1122
|
+
function createDOMNode(node) {
|
|
1123
|
+
if (!IS_DOM_AVAILABLE) {
|
|
1124
|
+
if (process.env.NODE_ENV !== "production") {
|
|
1125
|
+
try {
|
|
1126
|
+
logger.warn("[Askr] createDOMNode called in non-DOM environment");
|
|
1127
|
+
} catch {
|
|
1128
|
+
}
|
|
1345
1129
|
}
|
|
1130
|
+
return null;
|
|
1346
1131
|
}
|
|
1347
|
-
if (
|
|
1348
|
-
|
|
1132
|
+
if (typeof node === "string") {
|
|
1133
|
+
return document.createTextNode(node);
|
|
1349
1134
|
}
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1135
|
+
if (typeof node === "number") {
|
|
1136
|
+
return document.createTextNode(String(node));
|
|
1137
|
+
}
|
|
1138
|
+
if (!node) {
|
|
1139
|
+
return null;
|
|
1140
|
+
}
|
|
1141
|
+
if (Array.isArray(node)) {
|
|
1142
|
+
const fragment = document.createDocumentFragment();
|
|
1143
|
+
for (const child of node) {
|
|
1144
|
+
const dom = createDOMNode(child);
|
|
1145
|
+
if (dom) fragment.appendChild(dom);
|
|
1146
|
+
}
|
|
1147
|
+
return fragment;
|
|
1148
|
+
}
|
|
1149
|
+
if (typeof node === "object" && node !== null && "type" in node) {
|
|
1150
|
+
const type = node.type;
|
|
1151
|
+
const props = node.props || {};
|
|
1152
|
+
if (typeof type === "string") {
|
|
1153
|
+
return createIntrinsicElement(node, type, props);
|
|
1154
|
+
}
|
|
1155
|
+
if (typeof type === "function") {
|
|
1156
|
+
return createComponentElement(node, type, props);
|
|
1157
|
+
}
|
|
1158
|
+
if (typeof type === "symbol" && (type === Fragment || String(type) === "Symbol(Fragment)")) {
|
|
1159
|
+
return createFragmentElement(node, props);
|
|
1160
|
+
}
|
|
1161
|
+
}
|
|
1162
|
+
return null;
|
|
1163
|
+
}
|
|
1164
|
+
function createIntrinsicElement(node, type, props) {
|
|
1165
|
+
const el = document.createElement(type);
|
|
1166
|
+
materializeKey(el, node, props);
|
|
1167
|
+
applyPropsToElement(el, props, type);
|
|
1168
|
+
const children = props.children || node.children;
|
|
1169
|
+
if (children) {
|
|
1170
|
+
if (Array.isArray(children)) {
|
|
1171
|
+
warnMissingKeys(children);
|
|
1172
|
+
for (const child of children) {
|
|
1173
|
+
const dom = createDOMNode(child);
|
|
1174
|
+
if (dom) el.appendChild(dom);
|
|
1175
|
+
}
|
|
1176
|
+
} else {
|
|
1177
|
+
const dom = createDOMNode(children);
|
|
1178
|
+
if (dom) el.appendChild(dom);
|
|
1179
|
+
}
|
|
1180
|
+
}
|
|
1181
|
+
return el;
|
|
1182
|
+
}
|
|
1183
|
+
function createComponentElement(node, type, props) {
|
|
1184
|
+
const frame = node[CONTEXT_FRAME_SYMBOL];
|
|
1185
|
+
const snapshot = frame || getCurrentContextFrame();
|
|
1186
|
+
const componentFn = type;
|
|
1187
|
+
const isAsync = componentFn.constructor.name === "AsyncFunction";
|
|
1188
|
+
if (isAsync) {
|
|
1189
|
+
throw new Error(
|
|
1190
|
+
"Async components are not supported. Use resource() for async work."
|
|
1191
|
+
);
|
|
1192
|
+
}
|
|
1193
|
+
let childInstance = node.__instance;
|
|
1194
|
+
if (!childInstance) {
|
|
1195
|
+
childInstance = createComponentInstance(
|
|
1196
|
+
`comp-${Math.random().toString(36).slice(2, 7)}`,
|
|
1197
|
+
componentFn,
|
|
1198
|
+
props || {},
|
|
1199
|
+
null
|
|
1200
|
+
);
|
|
1201
|
+
node.__instance = childInstance;
|
|
1202
|
+
}
|
|
1203
|
+
if (snapshot) {
|
|
1204
|
+
childInstance.ownerFrame = snapshot;
|
|
1205
|
+
}
|
|
1206
|
+
const result = withContext(
|
|
1207
|
+
snapshot,
|
|
1208
|
+
() => renderComponentInline(childInstance)
|
|
1209
|
+
);
|
|
1210
|
+
if (result instanceof Promise) {
|
|
1211
|
+
throw new Error(
|
|
1212
|
+
"Async components are not supported. Components must return synchronously."
|
|
1213
|
+
);
|
|
1214
|
+
}
|
|
1215
|
+
const dom = withContext(snapshot, () => createDOMNode(result));
|
|
1216
|
+
if (dom instanceof Element) {
|
|
1217
|
+
mountInstanceInline(childInstance, dom);
|
|
1218
|
+
return dom;
|
|
1219
|
+
}
|
|
1220
|
+
if (!dom) {
|
|
1221
|
+
const placeholder = document.createComment("");
|
|
1222
|
+
childInstance._placeholder = placeholder;
|
|
1223
|
+
childInstance.mounted = true;
|
|
1224
|
+
childInstance.notifyUpdate = childInstance._enqueueRun;
|
|
1225
|
+
return placeholder;
|
|
1226
|
+
}
|
|
1227
|
+
const host = document.createElement("div");
|
|
1228
|
+
host.appendChild(dom);
|
|
1229
|
+
mountInstanceInline(childInstance, host);
|
|
1230
|
+
return host;
|
|
1231
|
+
}
|
|
1232
|
+
function createFragmentElement(node, props) {
|
|
1233
|
+
const fragment = document.createDocumentFragment();
|
|
1234
|
+
const children = props.children || node.children;
|
|
1235
|
+
if (children) {
|
|
1236
|
+
if (Array.isArray(children)) {
|
|
1237
|
+
for (const child of children) {
|
|
1238
|
+
const dom = createDOMNode(child);
|
|
1239
|
+
if (dom) fragment.appendChild(dom);
|
|
1240
|
+
}
|
|
1241
|
+
} else {
|
|
1242
|
+
const dom = createDOMNode(children);
|
|
1243
|
+
if (dom) fragment.appendChild(dom);
|
|
1244
|
+
}
|
|
1245
|
+
}
|
|
1246
|
+
return fragment;
|
|
1247
|
+
}
|
|
1248
|
+
function updateElementFromVnode(el, vnode, updateChildren = true) {
|
|
1249
|
+
if (!_isDOMElement(vnode)) {
|
|
1250
|
+
return;
|
|
1251
|
+
}
|
|
1252
|
+
const props = vnode.props || {};
|
|
1253
|
+
materializeKey(el, vnode, props);
|
|
1254
|
+
const existingListeners = elementListeners.get(el);
|
|
1255
|
+
let desiredEventNames = null;
|
|
1256
|
+
for (const key in props) {
|
|
1257
|
+
const value = props[key];
|
|
1258
|
+
if (isSkippedProp(key)) continue;
|
|
1259
|
+
const eventName = parseEventName(key);
|
|
1260
|
+
if (value === void 0 || value === null || value === false) {
|
|
1261
|
+
if (key === "class" || key === "className") {
|
|
1262
|
+
el.className = "";
|
|
1263
|
+
} else if (eventName && existingListeners?.has(eventName)) {
|
|
1264
|
+
const entry = existingListeners.get(eventName);
|
|
1265
|
+
if (entry.options !== void 0) {
|
|
1266
|
+
el.removeEventListener(eventName, entry.handler, entry.options);
|
|
1267
|
+
} else {
|
|
1268
|
+
el.removeEventListener(eventName, entry.handler);
|
|
1269
|
+
}
|
|
1270
|
+
existingListeners.delete(eventName);
|
|
1271
|
+
} else {
|
|
1272
|
+
el.removeAttribute(key);
|
|
1273
|
+
}
|
|
1274
|
+
continue;
|
|
1275
|
+
}
|
|
1276
|
+
if (key === "class" || key === "className") {
|
|
1277
|
+
el.className = String(value);
|
|
1278
|
+
} else if (key === "value" || key === "checked") {
|
|
1279
|
+
el[key] = value;
|
|
1280
|
+
} else if (eventName) {
|
|
1281
|
+
if (existingListeners && existingListeners.size > 0) {
|
|
1282
|
+
(desiredEventNames ??= /* @__PURE__ */ new Set()).add(eventName);
|
|
1283
|
+
}
|
|
1284
|
+
const existing = existingListeners?.get(eventName);
|
|
1285
|
+
if (existing && existing.original === value) {
|
|
1286
|
+
continue;
|
|
1287
|
+
}
|
|
1288
|
+
if (existing) {
|
|
1289
|
+
if (existing.options !== void 0) {
|
|
1290
|
+
el.removeEventListener(eventName, existing.handler, existing.options);
|
|
1291
|
+
} else {
|
|
1292
|
+
el.removeEventListener(eventName, existing.handler);
|
|
1293
|
+
}
|
|
1294
|
+
}
|
|
1295
|
+
const wrappedHandler = createWrappedHandler(
|
|
1296
|
+
value,
|
|
1297
|
+
false
|
|
1298
|
+
);
|
|
1299
|
+
const options = getPassiveOptions(eventName);
|
|
1300
|
+
if (options !== void 0) {
|
|
1301
|
+
el.addEventListener(eventName, wrappedHandler, options);
|
|
1302
|
+
} else {
|
|
1303
|
+
el.addEventListener(eventName, wrappedHandler);
|
|
1304
|
+
}
|
|
1305
|
+
if (!elementListeners.has(el)) {
|
|
1306
|
+
elementListeners.set(el, /* @__PURE__ */ new Map());
|
|
1307
|
+
}
|
|
1308
|
+
elementListeners.get(el).set(eventName, {
|
|
1309
|
+
handler: wrappedHandler,
|
|
1310
|
+
original: value,
|
|
1311
|
+
options
|
|
1312
|
+
});
|
|
1313
|
+
} else {
|
|
1314
|
+
el.setAttribute(key, String(value));
|
|
1315
|
+
}
|
|
1316
|
+
}
|
|
1317
|
+
if (existingListeners && existingListeners.size > 0) {
|
|
1318
|
+
if (desiredEventNames === null) {
|
|
1319
|
+
for (const [eventName, entry] of existingListeners) {
|
|
1320
|
+
if (entry.options !== void 0) {
|
|
1321
|
+
el.removeEventListener(eventName, entry.handler, entry.options);
|
|
1322
|
+
} else {
|
|
1323
|
+
el.removeEventListener(eventName, entry.handler);
|
|
1324
|
+
}
|
|
1325
|
+
}
|
|
1326
|
+
elementListeners.delete(el);
|
|
1327
|
+
} else {
|
|
1328
|
+
for (const [eventName, entry] of existingListeners) {
|
|
1329
|
+
if (!desiredEventNames.has(eventName)) {
|
|
1330
|
+
if (entry.options !== void 0) {
|
|
1331
|
+
el.removeEventListener(eventName, entry.handler, entry.options);
|
|
1332
|
+
} else {
|
|
1333
|
+
el.removeEventListener(eventName, entry.handler);
|
|
1334
|
+
}
|
|
1335
|
+
existingListeners.delete(eventName);
|
|
1336
|
+
}
|
|
1337
|
+
}
|
|
1338
|
+
if (existingListeners.size === 0) elementListeners.delete(el);
|
|
1339
|
+
}
|
|
1340
|
+
}
|
|
1341
|
+
if (updateChildren) {
|
|
1342
|
+
const children = vnode.children || props.children;
|
|
1343
|
+
updateElementChildren(el, children);
|
|
1344
|
+
}
|
|
1345
|
+
}
|
|
1346
|
+
function updateElementChildren(el, children) {
|
|
1347
|
+
if (!children) {
|
|
1348
|
+
el.textContent = "";
|
|
1349
|
+
return;
|
|
1350
|
+
}
|
|
1351
|
+
if (!Array.isArray(children) && (typeof children === "string" || typeof children === "number")) {
|
|
1352
|
+
if (el.childNodes.length === 1 && el.firstChild?.nodeType === 3) {
|
|
1353
|
+
el.firstChild.data = String(children);
|
|
1354
|
+
} else {
|
|
1355
|
+
el.textContent = String(children);
|
|
1356
|
+
}
|
|
1357
|
+
return;
|
|
1358
|
+
}
|
|
1359
|
+
if (Array.isArray(children)) {
|
|
1360
|
+
updateUnkeyedChildren(el, children);
|
|
1361
|
+
return;
|
|
1362
|
+
}
|
|
1363
|
+
el.textContent = "";
|
|
1364
|
+
const dom = createDOMNode(children);
|
|
1365
|
+
if (dom) el.appendChild(dom);
|
|
1366
|
+
}
|
|
1367
|
+
function updateUnkeyedChildren(parent, newChildren) {
|
|
1368
|
+
const existing = Array.from(parent.children);
|
|
1369
|
+
if (newChildren.length === 1 && existing.length === 0 && parent.childNodes.length === 1) {
|
|
1370
|
+
const firstNewChild = newChildren[0];
|
|
1371
|
+
const firstExisting = parent.firstChild;
|
|
1372
|
+
if ((typeof firstNewChild === "string" || typeof firstNewChild === "number") && firstExisting?.nodeType === 3) {
|
|
1373
|
+
firstExisting.data = String(firstNewChild);
|
|
1374
|
+
return;
|
|
1375
|
+
}
|
|
1376
|
+
}
|
|
1377
|
+
if (existing.length === 0 && parent.childNodes.length > 0) {
|
|
1378
|
+
parent.textContent = "";
|
|
1379
|
+
}
|
|
1380
|
+
const max = Math.max(existing.length, newChildren.length);
|
|
1381
|
+
for (let i = 0; i < max; i++) {
|
|
1382
|
+
const current2 = existing[i];
|
|
1383
|
+
const next = newChildren[i];
|
|
1384
|
+
if (next === void 0 && current2) {
|
|
1385
|
+
cleanupInstanceIfPresent(current2);
|
|
1386
|
+
current2.remove();
|
|
1387
|
+
continue;
|
|
1388
|
+
}
|
|
1389
|
+
if (!current2 && next !== void 0) {
|
|
1390
|
+
const dom = createDOMNode(next);
|
|
1391
|
+
if (dom) parent.appendChild(dom);
|
|
1392
|
+
continue;
|
|
1393
|
+
}
|
|
1394
|
+
if (!current2 || next === void 0) continue;
|
|
1395
|
+
if (typeof next === "string" || typeof next === "number") {
|
|
1396
|
+
current2.textContent = String(next);
|
|
1397
|
+
} else if (_isDOMElement(next)) {
|
|
1368
1398
|
if (typeof next.type === "string") {
|
|
1369
|
-
if (current2.tagName
|
|
1399
|
+
if (tagsEqualIgnoreCase(current2.tagName, next.type)) {
|
|
1370
1400
|
updateElementFromVnode(current2, next);
|
|
1371
1401
|
} else {
|
|
1372
1402
|
const dom = createDOMNode(next);
|
|
@@ -1399,31 +1429,38 @@ function performBulkPositionalKeyedTextUpdate(parent, keyedVnodes) {
|
|
|
1399
1429
|
let reused = 0;
|
|
1400
1430
|
let updatedKeys = 0;
|
|
1401
1431
|
const t0 = now();
|
|
1432
|
+
const debugFastPath = process.env.ASKR_FASTPATH_DEBUG === "1" || process.env.ASKR_FASTPATH_DEBUG === "true";
|
|
1402
1433
|
for (let i = 0; i < total; i++) {
|
|
1403
1434
|
const { key, vnode } = keyedVnodes[i];
|
|
1404
1435
|
const ch = parent.children[i];
|
|
1405
1436
|
if (ch && _isDOMElement(vnode) && typeof vnode.type === "string") {
|
|
1406
1437
|
const vnodeType = vnode.type;
|
|
1407
|
-
if (ch.tagName
|
|
1438
|
+
if (tagsEqualIgnoreCase(ch.tagName, vnodeType)) {
|
|
1408
1439
|
const children = vnode.children || vnode.props?.children;
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1440
|
+
if (debugFastPath) {
|
|
1441
|
+
logFastPathDebug("positional idx", i, {
|
|
1442
|
+
chTag: ch.tagName,
|
|
1443
|
+
vnodeType,
|
|
1444
|
+
chChildNodes: ch.childNodes.length,
|
|
1445
|
+
childrenType: Array.isArray(children) ? "array" : typeof children
|
|
1446
|
+
});
|
|
1447
|
+
}
|
|
1448
|
+
updateTextContent(ch, children, vnode);
|
|
1416
1449
|
setDataKey(ch, key, () => updatedKeys++);
|
|
1417
1450
|
reused++;
|
|
1418
1451
|
continue;
|
|
1419
1452
|
} else {
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1453
|
+
if (debugFastPath) {
|
|
1454
|
+
logFastPathDebug("positional tag mismatch", i, {
|
|
1455
|
+
chTag: ch.tagName,
|
|
1456
|
+
vnodeType
|
|
1457
|
+
});
|
|
1458
|
+
}
|
|
1424
1459
|
}
|
|
1425
1460
|
} else {
|
|
1426
|
-
|
|
1461
|
+
if (debugFastPath) {
|
|
1462
|
+
logFastPathDebug("positional missing or invalid", i, { ch: !!ch });
|
|
1463
|
+
}
|
|
1427
1464
|
}
|
|
1428
1465
|
replaceNodeAtPosition(parent, i, vnode);
|
|
1429
1466
|
}
|
|
@@ -1433,29 +1470,106 @@ function performBulkPositionalKeyedTextUpdate(parent, keyedVnodes) {
|
|
|
1433
1470
|
recordFastPathStats(stats, "bulkKeyedPositionalHits");
|
|
1434
1471
|
return stats;
|
|
1435
1472
|
}
|
|
1436
|
-
function updateTextContent(el, children) {
|
|
1473
|
+
function updateTextContent(el, children, vnode) {
|
|
1437
1474
|
if (typeof children === "string" || typeof children === "number") {
|
|
1438
1475
|
setTextNodeData(el, String(children));
|
|
1439
1476
|
} else if (Array.isArray(children) && children.length === 1 && (typeof children[0] === "string" || typeof children[0] === "number")) {
|
|
1440
1477
|
setTextNodeData(el, String(children[0]));
|
|
1441
1478
|
} else {
|
|
1442
|
-
|
|
1479
|
+
if (!tryUpdateTwoChildTextPattern(el, vnode)) {
|
|
1480
|
+
updateElementFromVnode(el, vnode);
|
|
1481
|
+
}
|
|
1443
1482
|
}
|
|
1444
1483
|
}
|
|
1445
|
-
function
|
|
1446
|
-
|
|
1447
|
-
|
|
1484
|
+
function tryUpdateTwoChildTextPattern(parentEl, vnode) {
|
|
1485
|
+
const vnodeChildren = vnode.children || vnode.props?.children;
|
|
1486
|
+
if (!Array.isArray(vnodeChildren) || vnodeChildren.length !== 2) return false;
|
|
1487
|
+
const c0 = vnodeChildren[0];
|
|
1488
|
+
const c1 = vnodeChildren[1];
|
|
1489
|
+
if (!_isDOMElement(c0) || !_isDOMElement(c1)) return false;
|
|
1490
|
+
if (typeof c0.type !== "string" || typeof c1.type !== "string") return false;
|
|
1491
|
+
const el0 = parentEl.children[0];
|
|
1492
|
+
const el1 = parentEl.children[1];
|
|
1493
|
+
if (!el0 || !el1) return false;
|
|
1494
|
+
if (!tagsEqualIgnoreCase(el0.tagName, c0.type)) return false;
|
|
1495
|
+
if (!tagsEqualIgnoreCase(el1.tagName, c1.type)) return false;
|
|
1496
|
+
const t0 = c0.children || c0.props?.children;
|
|
1497
|
+
const t1 = c1.children || c1.props?.children;
|
|
1498
|
+
if (typeof t0 === "string" || typeof t0 === "number") {
|
|
1499
|
+
setTextNodeData(el0, String(t0));
|
|
1500
|
+
} else if (Array.isArray(t0) && t0.length === 1 && (typeof t0[0] === "string" || typeof t0[0] === "number")) {
|
|
1501
|
+
setTextNodeData(el0, String(t0[0]));
|
|
1502
|
+
} else {
|
|
1503
|
+
return false;
|
|
1504
|
+
}
|
|
1505
|
+
if (typeof t1 === "string" || typeof t1 === "number") {
|
|
1506
|
+
setTextNodeData(el1, String(t1));
|
|
1507
|
+
} else if (Array.isArray(t1) && t1.length === 1 && (typeof t1[0] === "string" || typeof t1[0] === "number")) {
|
|
1508
|
+
setTextNodeData(el1, String(t1[0]));
|
|
1509
|
+
} else {
|
|
1510
|
+
return false;
|
|
1511
|
+
}
|
|
1512
|
+
return true;
|
|
1513
|
+
}
|
|
1514
|
+
function setTextNodeData(el, text) {
|
|
1515
|
+
if (el.childNodes.length === 1 && el.firstChild?.nodeType === 3) {
|
|
1516
|
+
el.firstChild.data = text;
|
|
1448
1517
|
} else {
|
|
1449
1518
|
el.textContent = text;
|
|
1450
1519
|
}
|
|
1451
1520
|
}
|
|
1452
1521
|
function setDataKey(el, key, onSet) {
|
|
1453
1522
|
try {
|
|
1454
|
-
|
|
1523
|
+
const next = String(key);
|
|
1524
|
+
if (el.getAttribute("data-key") === next) return;
|
|
1525
|
+
el.setAttribute("data-key", next);
|
|
1455
1526
|
onSet();
|
|
1456
1527
|
} catch {
|
|
1457
1528
|
}
|
|
1458
1529
|
}
|
|
1530
|
+
function upperCommonTagName(tag) {
|
|
1531
|
+
switch (tag) {
|
|
1532
|
+
case "div":
|
|
1533
|
+
return "DIV";
|
|
1534
|
+
case "span":
|
|
1535
|
+
return "SPAN";
|
|
1536
|
+
case "p":
|
|
1537
|
+
return "P";
|
|
1538
|
+
case "a":
|
|
1539
|
+
return "A";
|
|
1540
|
+
case "button":
|
|
1541
|
+
return "BUTTON";
|
|
1542
|
+
case "input":
|
|
1543
|
+
return "INPUT";
|
|
1544
|
+
case "ul":
|
|
1545
|
+
return "UL";
|
|
1546
|
+
case "ol":
|
|
1547
|
+
return "OL";
|
|
1548
|
+
case "li":
|
|
1549
|
+
return "LI";
|
|
1550
|
+
default:
|
|
1551
|
+
return null;
|
|
1552
|
+
}
|
|
1553
|
+
}
|
|
1554
|
+
function tagNamesEqualIgnoreCase(a, b) {
|
|
1555
|
+
if (a === b) return true;
|
|
1556
|
+
const len = a.length;
|
|
1557
|
+
if (len !== b.length) return false;
|
|
1558
|
+
for (let i = 0; i < len; i++) {
|
|
1559
|
+
const ac = a.charCodeAt(i);
|
|
1560
|
+
const bc = b.charCodeAt(i);
|
|
1561
|
+
if (ac === bc) continue;
|
|
1562
|
+
const an = ac >= 65 && ac <= 90 ? ac + 32 : ac;
|
|
1563
|
+
const bn = bc >= 65 && bc <= 90 ? bc + 32 : bc;
|
|
1564
|
+
if (an !== bn) return false;
|
|
1565
|
+
}
|
|
1566
|
+
return true;
|
|
1567
|
+
}
|
|
1568
|
+
function tagsEqualIgnoreCase(elementTagName, vnodeType) {
|
|
1569
|
+
const upperCommon = upperCommonTagName(vnodeType);
|
|
1570
|
+
if (upperCommon !== null && elementTagName === upperCommon) return true;
|
|
1571
|
+
return tagNamesEqualIgnoreCase(elementTagName, vnodeType);
|
|
1572
|
+
}
|
|
1459
1573
|
function replaceNodeAtPosition(parent, index, vnode) {
|
|
1460
1574
|
const dom = createDOMNode(vnode);
|
|
1461
1575
|
if (dom) {
|
|
@@ -1470,7 +1584,8 @@ function replaceNodeAtPosition(parent, index, vnode) {
|
|
|
1470
1584
|
}
|
|
1471
1585
|
function updateKeyedElementsMap(parent, keyedVnodes) {
|
|
1472
1586
|
try {
|
|
1473
|
-
const
|
|
1587
|
+
const existing = keyedElements.get(parent);
|
|
1588
|
+
const newKeyMap = existing ? (existing.clear(), existing) : /* @__PURE__ */ new Map();
|
|
1474
1589
|
for (let i = 0; i < keyedVnodes.length; i++) {
|
|
1475
1590
|
const k = keyedVnodes[i].key;
|
|
1476
1591
|
const ch = parent.children[i];
|
|
@@ -1492,7 +1607,6 @@ function performBulkTextReplace(parent, newChildren) {
|
|
|
1492
1607
|
else if (result === "created") created++;
|
|
1493
1608
|
}
|
|
1494
1609
|
const tBuild = now() - t0;
|
|
1495
|
-
cleanupRemovedNodes(parent, finalNodes);
|
|
1496
1610
|
const tCommit = commitBulkReplace(parent, finalNodes);
|
|
1497
1611
|
keyedElements.delete(parent);
|
|
1498
1612
|
const stats = {
|
|
@@ -1527,7 +1641,7 @@ function processElementVnode(vnode, existingNode, finalNodes) {
|
|
|
1527
1641
|
const vnodeObj = vnode;
|
|
1528
1642
|
if (typeof vnodeObj.type === "string") {
|
|
1529
1643
|
const tag = vnodeObj.type;
|
|
1530
|
-
if (existingNode && existingNode.nodeType === 1 && existingNode.tagName
|
|
1644
|
+
if (existingNode && existingNode.nodeType === 1 && tagsEqualIgnoreCase(existingNode.tagName, tag)) {
|
|
1531
1645
|
updateElementFromVnode(existingNode, vnode);
|
|
1532
1646
|
finalNodes.push(existingNode);
|
|
1533
1647
|
return "reused";
|
|
@@ -1540,24 +1654,21 @@ function processElementVnode(vnode, existingNode, finalNodes) {
|
|
|
1540
1654
|
}
|
|
1541
1655
|
return "skipped";
|
|
1542
1656
|
}
|
|
1543
|
-
function cleanupRemovedNodes(parent, keepNodes) {
|
|
1544
|
-
try {
|
|
1545
|
-
const toRemove = Array.from(parent.childNodes).filter(
|
|
1546
|
-
(n) => !keepNodes.includes(n)
|
|
1547
|
-
);
|
|
1548
|
-
for (const n of toRemove) {
|
|
1549
|
-
if (n instanceof Element) removeAllListeners(n);
|
|
1550
|
-
cleanupInstanceIfPresent(n);
|
|
1551
|
-
}
|
|
1552
|
-
} catch {
|
|
1553
|
-
}
|
|
1554
|
-
}
|
|
1555
1657
|
function commitBulkReplace(parent, nodes) {
|
|
1556
1658
|
const fragStart = Date.now();
|
|
1557
1659
|
const fragment = document.createDocumentFragment();
|
|
1558
1660
|
for (let i = 0; i < nodes.length; i++) {
|
|
1559
1661
|
fragment.appendChild(nodes[i]);
|
|
1560
1662
|
}
|
|
1663
|
+
try {
|
|
1664
|
+
for (let n = parent.firstChild; n; ) {
|
|
1665
|
+
const next = n.nextSibling;
|
|
1666
|
+
if (n instanceof Element) removeAllListeners(n);
|
|
1667
|
+
cleanupInstanceIfPresent(n);
|
|
1668
|
+
n = next;
|
|
1669
|
+
}
|
|
1670
|
+
} catch {
|
|
1671
|
+
}
|
|
1561
1672
|
recordDOMReplace("bulk-text-replace");
|
|
1562
1673
|
parent.replaceChildren(fragment);
|
|
1563
1674
|
return Date.now() - fragStart;
|
|
@@ -1644,22 +1755,6 @@ function recordBulkDiag(data) {
|
|
|
1644
1755
|
}
|
|
1645
1756
|
}
|
|
1646
1757
|
}
|
|
1647
|
-
var IS_DOM_AVAILABLE;
|
|
1648
|
-
var init_dom = __esm({
|
|
1649
|
-
"src/renderer/dom.ts"() {
|
|
1650
|
-
"use strict";
|
|
1651
|
-
init_logger();
|
|
1652
|
-
init_jsx_runtime();
|
|
1653
|
-
init_context();
|
|
1654
|
-
init_component();
|
|
1655
|
-
init_cleanup();
|
|
1656
|
-
init_diag();
|
|
1657
|
-
init_types();
|
|
1658
|
-
init_keyed();
|
|
1659
|
-
init_utils();
|
|
1660
|
-
IS_DOM_AVAILABLE = typeof document !== "undefined";
|
|
1661
|
-
}
|
|
1662
|
-
});
|
|
1663
1758
|
|
|
1664
1759
|
// src/renderer/fastpath.ts
|
|
1665
1760
|
function applyRendererFastPath(parent, keyedVnodes, oldKeyMap, unkeyedVnodes) {
|
|
@@ -1682,14 +1777,11 @@ function applyRendererFastPath(parent, keyedVnodes, oldKeyMap, unkeyedVnodes) {
|
|
|
1682
1777
|
parentChildrenArr[i] = pc[i];
|
|
1683
1778
|
} catch (e) {
|
|
1684
1779
|
parentChildrenArr = void 0;
|
|
1685
|
-
void e;
|
|
1686
1780
|
}
|
|
1687
1781
|
} else {
|
|
1688
1782
|
localOldKeyMap = /* @__PURE__ */ new Map();
|
|
1689
1783
|
try {
|
|
1690
|
-
|
|
1691
|
-
for (let i = 0; i < parentChildren.length; i++) {
|
|
1692
|
-
const ch = parentChildren[i];
|
|
1784
|
+
for (let ch = parent.firstElementChild; ch; ch = ch.nextElementSibling) {
|
|
1693
1785
|
const k = ch.getAttribute("data-key");
|
|
1694
1786
|
if (k !== null) {
|
|
1695
1787
|
localOldKeyMap.set(k, ch);
|
|
@@ -1699,7 +1791,6 @@ function applyRendererFastPath(parent, keyedVnodes, oldKeyMap, unkeyedVnodes) {
|
|
|
1699
1791
|
}
|
|
1700
1792
|
} catch (e) {
|
|
1701
1793
|
localOldKeyMap = void 0;
|
|
1702
|
-
void e;
|
|
1703
1794
|
}
|
|
1704
1795
|
}
|
|
1705
1796
|
const finalNodes = [];
|
|
@@ -1753,11 +1844,11 @@ function applyRendererFastPath(parent, keyedVnodes, oldKeyMap, unkeyedVnodes) {
|
|
|
1753
1844
|
fragmentAppendCount++;
|
|
1754
1845
|
}
|
|
1755
1846
|
try {
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
for (const n of toRemove) {
|
|
1847
|
+
for (let n = parent.firstChild; n; ) {
|
|
1848
|
+
const next = n.nextSibling;
|
|
1759
1849
|
if (n instanceof Element) removeAllListeners(n);
|
|
1760
1850
|
cleanupInstanceIfPresent(n);
|
|
1851
|
+
n = next;
|
|
1761
1852
|
}
|
|
1762
1853
|
} catch (e) {
|
|
1763
1854
|
void e;
|
|
@@ -1820,26 +1911,25 @@ function applyRendererFastPath(parent, keyedVnodes, oldKeyMap, unkeyedVnodes) {
|
|
|
1820
1911
|
}
|
|
1821
1912
|
return newKeyMap;
|
|
1822
1913
|
} catch (e) {
|
|
1823
|
-
void e;
|
|
1824
1914
|
return null;
|
|
1825
1915
|
}
|
|
1826
1916
|
}
|
|
1827
|
-
var init_fastpath = __esm({
|
|
1828
|
-
"src/renderer/fastpath.ts"() {
|
|
1829
|
-
"use strict";
|
|
1830
|
-
init_dom();
|
|
1831
|
-
init_keyed();
|
|
1832
|
-
init_logger();
|
|
1833
|
-
init_cleanup();
|
|
1834
|
-
init_diag();
|
|
1835
|
-
init_scheduler();
|
|
1836
|
-
init_fastlane_shared();
|
|
1837
|
-
}
|
|
1838
|
-
});
|
|
1839
1917
|
|
|
1840
1918
|
// src/renderer/reconcile.ts
|
|
1919
|
+
function tagNamesEqualIgnoreCase2(a, b) {
|
|
1920
|
+
if (a === b) return true;
|
|
1921
|
+
if (a.length !== b.length) return false;
|
|
1922
|
+
for (let i = 0; i < a.length; i++) {
|
|
1923
|
+
const ca = a.charCodeAt(i);
|
|
1924
|
+
const cb = b.charCodeAt(i);
|
|
1925
|
+
if (ca === cb) continue;
|
|
1926
|
+
const fa = ca >= 65 && ca <= 90 ? ca + 32 : ca;
|
|
1927
|
+
const fb = cb >= 65 && cb <= 90 ? cb + 32 : cb;
|
|
1928
|
+
if (fa !== fb) return false;
|
|
1929
|
+
}
|
|
1930
|
+
return true;
|
|
1931
|
+
}
|
|
1841
1932
|
function reconcileKeyedChildren(parent, newChildren, oldKeyMap) {
|
|
1842
|
-
logReconcileDebug(newChildren);
|
|
1843
1933
|
const { keyedVnodes, unkeyedVnodes } = partitionChildren(newChildren);
|
|
1844
1934
|
const fastPathResult = tryFastPaths(
|
|
1845
1935
|
parent,
|
|
@@ -1851,20 +1941,6 @@ function reconcileKeyedChildren(parent, newChildren, oldKeyMap) {
|
|
|
1851
1941
|
if (fastPathResult) return fastPathResult;
|
|
1852
1942
|
return performFullReconciliation(parent, newChildren, keyedVnodes, oldKeyMap);
|
|
1853
1943
|
}
|
|
1854
|
-
function logReconcileDebug(newChildren) {
|
|
1855
|
-
if (process.env.NODE_ENV !== "production") {
|
|
1856
|
-
try {
|
|
1857
|
-
logger.warn(
|
|
1858
|
-
"[Askr][RECONCILE] reconcileKeyedChildren newChildren sample",
|
|
1859
|
-
{
|
|
1860
|
-
sample: newChildren && newChildren.length && newChildren[0] || null,
|
|
1861
|
-
len: newChildren.length
|
|
1862
|
-
}
|
|
1863
|
-
);
|
|
1864
|
-
} catch {
|
|
1865
|
-
}
|
|
1866
|
-
}
|
|
1867
|
-
}
|
|
1868
1944
|
function partitionChildren(newChildren) {
|
|
1869
1945
|
const keyedVnodes = [];
|
|
1870
1946
|
const unkeyedVnodes = [];
|
|
@@ -1922,7 +1998,6 @@ function tryPositionalBulkUpdate(parent, keyedVnodes) {
|
|
|
1922
1998
|
const total = keyedVnodes.length;
|
|
1923
1999
|
if (total < 10) return null;
|
|
1924
2000
|
const matchCount = countPositionalMatches(parent, keyedVnodes);
|
|
1925
|
-
logPositionalCheck(total, matchCount, parent.children.length);
|
|
1926
2001
|
if (matchCount / total < 0.9) return null;
|
|
1927
2002
|
if (hasPositionalPropChanges(parent, keyedVnodes)) return null;
|
|
1928
2003
|
try {
|
|
@@ -1943,7 +2018,7 @@ function countPositionalMatches(parent, keyedVnodes) {
|
|
|
1943
2018
|
continue;
|
|
1944
2019
|
const el = parent.children[i];
|
|
1945
2020
|
if (!el) continue;
|
|
1946
|
-
if (el.tagName
|
|
2021
|
+
if (tagNamesEqualIgnoreCase2(el.tagName, vnode.type)) {
|
|
1947
2022
|
matchCount++;
|
|
1948
2023
|
}
|
|
1949
2024
|
}
|
|
@@ -1951,18 +2026,6 @@ function countPositionalMatches(parent, keyedVnodes) {
|
|
|
1951
2026
|
}
|
|
1952
2027
|
return matchCount;
|
|
1953
2028
|
}
|
|
1954
|
-
function logPositionalCheck(total, matchCount, parentChildren) {
|
|
1955
|
-
if (process.env.NODE_ENV !== "production") {
|
|
1956
|
-
try {
|
|
1957
|
-
logger.warn("[Askr][FASTPATH] positional check", {
|
|
1958
|
-
total,
|
|
1959
|
-
matchCount,
|
|
1960
|
-
parentChildren
|
|
1961
|
-
});
|
|
1962
|
-
} catch {
|
|
1963
|
-
}
|
|
1964
|
-
}
|
|
1965
|
-
}
|
|
1966
2029
|
function hasPositionalPropChanges(parent, keyedVnodes) {
|
|
1967
2030
|
try {
|
|
1968
2031
|
for (let i = 0; i < keyedVnodes.length; i++) {
|
|
@@ -1981,9 +2044,7 @@ function hasPositionalPropChanges(parent, keyedVnodes) {
|
|
|
1981
2044
|
function rebuildKeyedMap(parent) {
|
|
1982
2045
|
try {
|
|
1983
2046
|
const map = /* @__PURE__ */ new Map();
|
|
1984
|
-
|
|
1985
|
-
for (let i = 0; i < children.length; i++) {
|
|
1986
|
-
const el = children[i];
|
|
2047
|
+
for (let el = parent.firstElementChild; el; el = el.nextElementSibling) {
|
|
1987
2048
|
const k = el.getAttribute("data-key");
|
|
1988
2049
|
if (k !== null) {
|
|
1989
2050
|
map.set(k, el);
|
|
@@ -2044,18 +2105,19 @@ function createOldElResolver(parent, oldKeyMap, usedOldEls) {
|
|
|
2044
2105
|
}
|
|
2045
2106
|
function scanForElementByKey(parent, k, keyStr, usedOldEls) {
|
|
2046
2107
|
try {
|
|
2047
|
-
|
|
2048
|
-
for (const ch of children) {
|
|
2108
|
+
for (let ch = parent.firstElementChild; ch; ch = ch.nextElementSibling) {
|
|
2049
2109
|
if (usedOldEls.has(ch)) continue;
|
|
2050
2110
|
const attr = ch.getAttribute("data-key");
|
|
2051
2111
|
if (attr === keyStr) {
|
|
2052
2112
|
usedOldEls.add(ch);
|
|
2053
2113
|
return ch;
|
|
2054
2114
|
}
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2115
|
+
if (attr !== null) {
|
|
2116
|
+
const numAttr = Number(attr);
|
|
2117
|
+
if (!Number.isNaN(numAttr) && numAttr === k) {
|
|
2118
|
+
usedOldEls.add(ch);
|
|
2119
|
+
return ch;
|
|
2120
|
+
}
|
|
2059
2121
|
}
|
|
2060
2122
|
}
|
|
2061
2123
|
} catch {
|
|
@@ -2072,9 +2134,17 @@ function reconcileSingleChild(child, index, parent, resolveOldElOnce, usedOldEls
|
|
|
2072
2134
|
function reconcileKeyedChild(child, key, parent, resolveOldElOnce, newKeyMap) {
|
|
2073
2135
|
const el = resolveOldElOnce(key);
|
|
2074
2136
|
if (el && el.parentElement === parent) {
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2137
|
+
try {
|
|
2138
|
+
const childObj = child;
|
|
2139
|
+
if (childObj && typeof childObj === "object" && typeof childObj.type === "string") {
|
|
2140
|
+
if (tagNamesEqualIgnoreCase2(el.tagName, childObj.type)) {
|
|
2141
|
+
updateElementFromVnode(el, child);
|
|
2142
|
+
newKeyMap.set(key, el);
|
|
2143
|
+
return el;
|
|
2144
|
+
}
|
|
2145
|
+
}
|
|
2146
|
+
} catch {
|
|
2147
|
+
}
|
|
2078
2148
|
}
|
|
2079
2149
|
const dom = createDOMNode(child);
|
|
2080
2150
|
if (dom) {
|
|
@@ -2111,13 +2181,16 @@ function canReuseElement(existing, child) {
|
|
|
2111
2181
|
if (typeof child !== "object" || child === null || !("type" in child))
|
|
2112
2182
|
return false;
|
|
2113
2183
|
const childObj = child;
|
|
2114
|
-
const
|
|
2115
|
-
|
|
2184
|
+
const existingKey = existing.getAttribute("data-key");
|
|
2185
|
+
const hasNoKey = existingKey === null || existingKey === void 0;
|
|
2186
|
+
return hasNoKey && typeof childObj.type === "string" && tagNamesEqualIgnoreCase2(existing.tagName, childObj.type);
|
|
2116
2187
|
}
|
|
2117
2188
|
function findAvailableUnkeyedElement(parent, usedOldEls) {
|
|
2118
|
-
|
|
2119
|
-
(
|
|
2120
|
-
|
|
2189
|
+
for (let ch = parent.firstElementChild; ch; ch = ch.nextElementSibling) {
|
|
2190
|
+
if (usedOldEls.has(ch)) continue;
|
|
2191
|
+
if (ch.getAttribute("data-key") === null) return ch;
|
|
2192
|
+
}
|
|
2193
|
+
return void 0;
|
|
2121
2194
|
}
|
|
2122
2195
|
function tryReuseElement(avail, child, usedOldEls) {
|
|
2123
2196
|
if (typeof child === "string" || typeof child === "number") {
|
|
@@ -2127,7 +2200,7 @@ function tryReuseElement(avail, child, usedOldEls) {
|
|
|
2127
2200
|
}
|
|
2128
2201
|
if (typeof child === "object" && child !== null && "type" in child) {
|
|
2129
2202
|
const childObj = child;
|
|
2130
|
-
if (typeof childObj.type === "string" && avail.tagName
|
|
2203
|
+
if (typeof childObj.type === "string" && tagNamesEqualIgnoreCase2(avail.tagName, childObj.type)) {
|
|
2131
2204
|
updateElementFromVnode(avail, child);
|
|
2132
2205
|
usedOldEls.add(avail);
|
|
2133
2206
|
return avail;
|
|
@@ -2141,30 +2214,33 @@ function commitReconciliation(parent, finalNodes) {
|
|
|
2141
2214
|
fragment.appendChild(finalNodes[i]);
|
|
2142
2215
|
}
|
|
2143
2216
|
try {
|
|
2144
|
-
|
|
2145
|
-
|
|
2217
|
+
for (let n = parent.firstChild; n; ) {
|
|
2218
|
+
const next = n.nextSibling;
|
|
2146
2219
|
if (n instanceof Element) removeAllListeners(n);
|
|
2147
2220
|
cleanupInstanceIfPresent(n);
|
|
2221
|
+
n = next;
|
|
2148
2222
|
}
|
|
2149
2223
|
} catch {
|
|
2150
2224
|
}
|
|
2151
2225
|
recordDOMReplace("reconcile");
|
|
2152
2226
|
parent.replaceChildren(fragment);
|
|
2153
2227
|
}
|
|
2154
|
-
var init_reconcile = __esm({
|
|
2155
|
-
"src/renderer/reconcile.ts"() {
|
|
2156
|
-
"use strict";
|
|
2157
|
-
init_dom();
|
|
2158
|
-
init_keyed();
|
|
2159
|
-
init_cleanup();
|
|
2160
|
-
init_fastlane_shared();
|
|
2161
|
-
init_fastpath();
|
|
2162
|
-
init_logger();
|
|
2163
|
-
init_utils();
|
|
2164
|
-
}
|
|
2165
|
-
});
|
|
2166
2228
|
|
|
2167
2229
|
// src/renderer/evaluate.ts
|
|
2230
|
+
var domRanges = /* @__PURE__ */ new WeakMap();
|
|
2231
|
+
function tagNamesEqualIgnoreCase3(a, b) {
|
|
2232
|
+
if (a === b) return true;
|
|
2233
|
+
if (a.length !== b.length) return false;
|
|
2234
|
+
for (let i = 0; i < a.length; i++) {
|
|
2235
|
+
const ca = a.charCodeAt(i);
|
|
2236
|
+
const cb = b.charCodeAt(i);
|
|
2237
|
+
if (ca === cb) continue;
|
|
2238
|
+
const fa = ca >= 65 && ca <= 90 ? ca + 32 : ca;
|
|
2239
|
+
const fb = cb >= 65 && cb <= 90 ? cb + 32 : cb;
|
|
2240
|
+
if (fa !== fb) return false;
|
|
2241
|
+
}
|
|
2242
|
+
return true;
|
|
2243
|
+
}
|
|
2168
2244
|
function checkSimpleText(vnodeChildren) {
|
|
2169
2245
|
if (!Array.isArray(vnodeChildren)) {
|
|
2170
2246
|
if (typeof vnodeChildren === "string" || typeof vnodeChildren === "number") {
|
|
@@ -2187,8 +2263,7 @@ function tryUpdateTextInPlace(element, text) {
|
|
|
2187
2263
|
}
|
|
2188
2264
|
function buildKeyMapFromDOM(parent) {
|
|
2189
2265
|
const keyMap = /* @__PURE__ */ new Map();
|
|
2190
|
-
|
|
2191
|
-
for (const child of children) {
|
|
2266
|
+
for (let child = parent.firstElementChild; child; child = child.nextElementSibling) {
|
|
2192
2267
|
const k = child.getAttribute("data-key");
|
|
2193
2268
|
if (k !== null) {
|
|
2194
2269
|
keyMap.set(k, child);
|
|
@@ -2209,9 +2284,10 @@ function getOrBuildKeyMap(parent) {
|
|
|
2209
2284
|
return keyMap.size > 0 ? keyMap : void 0;
|
|
2210
2285
|
}
|
|
2211
2286
|
function hasKeyedChildren(children) {
|
|
2212
|
-
|
|
2213
|
-
(
|
|
2214
|
-
|
|
2287
|
+
for (let i = 0; i < children.length; i++) {
|
|
2288
|
+
if (extractKey(children[i]) !== void 0) return true;
|
|
2289
|
+
}
|
|
2290
|
+
return false;
|
|
2215
2291
|
}
|
|
2216
2292
|
function trackBulkTextStats(stats) {
|
|
2217
2293
|
if (process.env.NODE_ENV !== "production") {
|
|
@@ -2321,19 +2397,22 @@ function updateElementChildren2(element, vnodeChildren) {
|
|
|
2321
2397
|
function smartUpdateElement(element, vnode) {
|
|
2322
2398
|
const vnodeChildren = vnode.children || vnode.props?.children;
|
|
2323
2399
|
const textCheck = checkSimpleText(vnodeChildren);
|
|
2324
|
-
if (textCheck.isSimple && tryUpdateTextInPlace(element, textCheck.text)) {
|
|
2325
|
-
} else {
|
|
2400
|
+
if (textCheck.isSimple && tryUpdateTextInPlace(element, textCheck.text)) ; else {
|
|
2326
2401
|
updateElementChildren2(element, vnodeChildren);
|
|
2327
2402
|
}
|
|
2328
2403
|
updateElementFromVnode(element, vnode, false);
|
|
2329
2404
|
}
|
|
2330
2405
|
function processFragmentChildren(target, childArray) {
|
|
2331
|
-
|
|
2406
|
+
let existingNode = target.firstElementChild;
|
|
2332
2407
|
for (let i = 0; i < childArray.length; i++) {
|
|
2333
2408
|
const childVnode = childArray[i];
|
|
2334
|
-
const
|
|
2335
|
-
if (existingNode && _isDOMElement(childVnode) && typeof childVnode.type === "string" &&
|
|
2409
|
+
const nextExisting = existingNode ? existingNode.nextElementSibling : null;
|
|
2410
|
+
if (existingNode && _isDOMElement(childVnode) && typeof childVnode.type === "string" && tagNamesEqualIgnoreCase3(
|
|
2411
|
+
existingNode.tagName,
|
|
2412
|
+
childVnode.type
|
|
2413
|
+
)) {
|
|
2336
2414
|
smartUpdateElement(existingNode, childVnode);
|
|
2415
|
+
existingNode = nextExisting;
|
|
2337
2416
|
continue;
|
|
2338
2417
|
}
|
|
2339
2418
|
const newDom = createDOMNode(childVnode);
|
|
@@ -2344,39 +2423,29 @@ function processFragmentChildren(target, childArray) {
|
|
|
2344
2423
|
target.appendChild(newDom);
|
|
2345
2424
|
}
|
|
2346
2425
|
}
|
|
2426
|
+
existingNode = nextExisting;
|
|
2347
2427
|
}
|
|
2348
|
-
while (
|
|
2349
|
-
|
|
2428
|
+
while (existingNode) {
|
|
2429
|
+
const next = existingNode.nextElementSibling;
|
|
2430
|
+
target.removeChild(existingNode);
|
|
2431
|
+
existingNode = next;
|
|
2350
2432
|
}
|
|
2351
2433
|
}
|
|
2352
|
-
function createWrappedEventHandler(handler) {
|
|
2353
|
-
return (event) => {
|
|
2354
|
-
globalScheduler.setInHandler(true);
|
|
2355
|
-
try {
|
|
2356
|
-
handler(event);
|
|
2357
|
-
} catch (error) {
|
|
2358
|
-
logger.error("[Askr] Event handler error:", error);
|
|
2359
|
-
} finally {
|
|
2360
|
-
globalScheduler.setInHandler(false);
|
|
2361
|
-
}
|
|
2362
|
-
};
|
|
2363
|
-
}
|
|
2364
2434
|
function applyPropsToElement2(el, props) {
|
|
2365
2435
|
for (const [key, value] of Object.entries(props)) {
|
|
2366
2436
|
if (key === "children" || key === "key") continue;
|
|
2367
2437
|
if (value === void 0 || value === null || value === false) continue;
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
const wrappedHandler =
|
|
2371
|
-
|
|
2372
|
-
|
|
2438
|
+
const eventName = parseEventName(key);
|
|
2439
|
+
if (eventName) {
|
|
2440
|
+
const wrappedHandler = createWrappedHandler(
|
|
2441
|
+
value,
|
|
2442
|
+
false
|
|
2443
|
+
);
|
|
2444
|
+
const options = getPassiveOptions(eventName);
|
|
2445
|
+
if (options !== void 0)
|
|
2373
2446
|
el.addEventListener(eventName, wrappedHandler, options);
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
}
|
|
2377
|
-
if (!elementListeners.has(el)) {
|
|
2378
|
-
elementListeners.set(el, /* @__PURE__ */ new Map());
|
|
2379
|
-
}
|
|
2447
|
+
else el.addEventListener(eventName, wrappedHandler);
|
|
2448
|
+
if (!elementListeners.has(el)) elementListeners.set(el, /* @__PURE__ */ new Map());
|
|
2380
2449
|
elementListeners.get(el).set(eventName, {
|
|
2381
2450
|
handler: wrappedHandler,
|
|
2382
2451
|
original: value,
|
|
@@ -2419,7 +2488,6 @@ function evaluate(node, target, context) {
|
|
|
2419
2488
|
try {
|
|
2420
2489
|
console.warn("[Askr] evaluate() called in non-DOM environment; no-op.");
|
|
2421
2490
|
} catch (e) {
|
|
2422
|
-
void e;
|
|
2423
2491
|
}
|
|
2424
2492
|
}
|
|
2425
2493
|
return;
|
|
@@ -2458,7 +2526,7 @@ function evaluate(node, target, context) {
|
|
|
2458
2526
|
}
|
|
2459
2527
|
}
|
|
2460
2528
|
const firstChild = target.children[0];
|
|
2461
|
-
if (firstChild && _isDOMElement(vnode) && typeof vnode.type === "string" && firstChild.tagName
|
|
2529
|
+
if (firstChild && _isDOMElement(vnode) && typeof vnode.type === "string" && tagNamesEqualIgnoreCase3(firstChild.tagName, vnode.type)) {
|
|
2462
2530
|
smartUpdateElement(firstChild, vnode);
|
|
2463
2531
|
} else {
|
|
2464
2532
|
target.textContent = "";
|
|
@@ -2472,44 +2540,16 @@ function evaluate(node, target, context) {
|
|
|
2472
2540
|
}
|
|
2473
2541
|
}
|
|
2474
2542
|
}
|
|
2475
|
-
var domRanges;
|
|
2476
|
-
var init_evaluate = __esm({
|
|
2477
|
-
"src/renderer/evaluate.ts"() {
|
|
2478
|
-
"use strict";
|
|
2479
|
-
init_scheduler();
|
|
2480
|
-
init_logger();
|
|
2481
|
-
init_cleanup();
|
|
2482
|
-
init_keyed();
|
|
2483
|
-
init_reconcile();
|
|
2484
|
-
init_types();
|
|
2485
|
-
init_dom();
|
|
2486
|
-
init_diag();
|
|
2487
|
-
init_types2();
|
|
2488
|
-
domRanges = /* @__PURE__ */ new WeakMap();
|
|
2489
|
-
}
|
|
2490
|
-
});
|
|
2491
2543
|
|
|
2492
2544
|
// src/renderer/index.ts
|
|
2493
|
-
|
|
2494
|
-
|
|
2495
|
-
|
|
2496
|
-
|
|
2497
|
-
|
|
2498
|
-
|
|
2499
|
-
|
|
2500
|
-
|
|
2501
|
-
init_evaluate();
|
|
2502
|
-
init_keyed();
|
|
2503
|
-
if (typeof globalThis !== "undefined") {
|
|
2504
|
-
const _g = globalThis;
|
|
2505
|
-
_g.__ASKR_RENDERER = {
|
|
2506
|
-
evaluate,
|
|
2507
|
-
isKeyedReorderFastPathEligible,
|
|
2508
|
-
getKeyMapForElement
|
|
2509
|
-
};
|
|
2510
|
-
}
|
|
2511
|
-
}
|
|
2512
|
-
});
|
|
2545
|
+
if (typeof globalThis !== "undefined") {
|
|
2546
|
+
const _g = globalThis;
|
|
2547
|
+
_g.__ASKR_RENDERER = {
|
|
2548
|
+
evaluate,
|
|
2549
|
+
isKeyedReorderFastPathEligible,
|
|
2550
|
+
getKeyMapForElement
|
|
2551
|
+
};
|
|
2552
|
+
}
|
|
2513
2553
|
|
|
2514
2554
|
// src/runtime/component.ts
|
|
2515
2555
|
function createComponentInstance(id, fn, props, target) {
|
|
@@ -2561,26 +2601,13 @@ function createComponentInstance(id, fn, props, target) {
|
|
|
2561
2601
|
};
|
|
2562
2602
|
return instance;
|
|
2563
2603
|
}
|
|
2604
|
+
var currentInstance = null;
|
|
2564
2605
|
function getCurrentComponentInstance() {
|
|
2565
2606
|
return currentInstance;
|
|
2566
2607
|
}
|
|
2567
2608
|
function setCurrentComponentInstance(instance) {
|
|
2568
2609
|
currentInstance = instance;
|
|
2569
2610
|
}
|
|
2570
|
-
function registerMountOperation(operation) {
|
|
2571
|
-
const instance = getCurrentComponentInstance();
|
|
2572
|
-
if (instance) {
|
|
2573
|
-
if (isBulkCommitActive2()) {
|
|
2574
|
-
if (process.env.NODE_ENV !== "production") {
|
|
2575
|
-
throw new Error(
|
|
2576
|
-
"registerMountOperation called during bulk commit fast-lane"
|
|
2577
|
-
);
|
|
2578
|
-
}
|
|
2579
|
-
return;
|
|
2580
|
-
}
|
|
2581
|
-
instance.mountOperations.push(operation);
|
|
2582
|
-
}
|
|
2583
|
-
}
|
|
2584
2611
|
function executeMountOperations(instance) {
|
|
2585
2612
|
if (!instance.isRoot) return;
|
|
2586
2613
|
for (const operation of instance.mountOperations) {
|
|
@@ -2603,7 +2630,6 @@ function mountInstanceInline(instance, target) {
|
|
|
2603
2630
|
if (target instanceof Element)
|
|
2604
2631
|
target.__ASKR_INSTANCE = instance;
|
|
2605
2632
|
} catch (err) {
|
|
2606
|
-
void err;
|
|
2607
2633
|
}
|
|
2608
2634
|
instance.notifyUpdate = instance._enqueueRun;
|
|
2609
2635
|
const wasFirstMount = !instance.mounted;
|
|
@@ -2612,6 +2638,7 @@ function mountInstanceInline(instance, target) {
|
|
|
2612
2638
|
executeMountOperations(instance);
|
|
2613
2639
|
}
|
|
2614
2640
|
}
|
|
2641
|
+
var _globalRenderCounter = 0;
|
|
2615
2642
|
function runComponent(instance) {
|
|
2616
2643
|
instance.notifyUpdate = instance._enqueueRun;
|
|
2617
2644
|
instance._currentRenderToken = ++_globalRenderCounter;
|
|
@@ -2633,7 +2660,7 @@ function runComponent(instance) {
|
|
|
2633
2660
|
globalScheduler.enqueue(() => {
|
|
2634
2661
|
if (!instance.target && instance._placeholder) {
|
|
2635
2662
|
if (result === null || result === void 0) {
|
|
2636
|
-
|
|
2663
|
+
finalizeReadSubscriptions2(instance);
|
|
2637
2664
|
return;
|
|
2638
2665
|
}
|
|
2639
2666
|
const placeholder = instance._placeholder;
|
|
@@ -2653,7 +2680,7 @@ function runComponent(instance) {
|
|
|
2653
2680
|
instance.target = host;
|
|
2654
2681
|
instance._placeholder = void 0;
|
|
2655
2682
|
host.__ASKR_INSTANCE = instance;
|
|
2656
|
-
|
|
2683
|
+
finalizeReadSubscriptions2(instance);
|
|
2657
2684
|
} finally {
|
|
2658
2685
|
currentInstance = oldInstance;
|
|
2659
2686
|
}
|
|
@@ -2698,7 +2725,7 @@ function runComponent(instance) {
|
|
|
2698
2725
|
} finally {
|
|
2699
2726
|
currentInstance = oldInstance;
|
|
2700
2727
|
}
|
|
2701
|
-
|
|
2728
|
+
finalizeReadSubscriptions2(instance);
|
|
2702
2729
|
instance.mounted = true;
|
|
2703
2730
|
if (wasFirstMount && instance.mountOperations.length > 0) {
|
|
2704
2731
|
executeMountOperations(instance);
|
|
@@ -2717,7 +2744,6 @@ function runComponent(instance) {
|
|
|
2717
2744
|
}
|
|
2718
2745
|
}
|
|
2719
2746
|
} catch (_err) {
|
|
2720
|
-
void _err;
|
|
2721
2747
|
}
|
|
2722
2748
|
try {
|
|
2723
2749
|
try {
|
|
@@ -2750,7 +2776,7 @@ function renderComponentInline(instance) {
|
|
|
2750
2776
|
try {
|
|
2751
2777
|
const result = executeComponentSync(instance);
|
|
2752
2778
|
if (!hadToken) {
|
|
2753
|
-
|
|
2779
|
+
finalizeReadSubscriptions2(instance);
|
|
2754
2780
|
}
|
|
2755
2781
|
return result;
|
|
2756
2782
|
} finally {
|
|
@@ -2760,14 +2786,13 @@ function renderComponentInline(instance) {
|
|
|
2760
2786
|
}
|
|
2761
2787
|
function executeComponentSync(instance) {
|
|
2762
2788
|
instance.stateIndexCheck = -1;
|
|
2763
|
-
for (const
|
|
2764
|
-
if (
|
|
2765
|
-
|
|
2789
|
+
for (const state of instance.stateValues) {
|
|
2790
|
+
if (state) {
|
|
2791
|
+
state._hasBeenRead = false;
|
|
2766
2792
|
}
|
|
2767
2793
|
}
|
|
2768
2794
|
instance._pendingReadStates = /* @__PURE__ */ new Set();
|
|
2769
2795
|
currentInstance = instance;
|
|
2770
|
-
stateIndex = 0;
|
|
2771
2796
|
try {
|
|
2772
2797
|
const renderStartTime = process.env.NODE_ENV !== "production" ? Date.now() : 0;
|
|
2773
2798
|
const context = {
|
|
@@ -2791,8 +2816,8 @@ function executeComponentSync(instance) {
|
|
|
2791
2816
|
instance.firstRenderComplete = true;
|
|
2792
2817
|
}
|
|
2793
2818
|
for (let i = 0; i < instance.stateValues.length; i++) {
|
|
2794
|
-
const
|
|
2795
|
-
if (
|
|
2819
|
+
const state = instance.stateValues[i];
|
|
2820
|
+
if (state && !state._hasBeenRead) {
|
|
2796
2821
|
try {
|
|
2797
2822
|
const name = instance.fn?.name || "<anonymous>";
|
|
2798
2823
|
logger.warn(
|
|
@@ -2810,23 +2835,10 @@ function executeComponentSync(instance) {
|
|
|
2810
2835
|
currentInstance = null;
|
|
2811
2836
|
}
|
|
2812
2837
|
}
|
|
2813
|
-
function executeComponent(instance) {
|
|
2814
|
-
instance.abortController = new AbortController();
|
|
2815
|
-
instance.notifyUpdate = instance._enqueueRun;
|
|
2816
|
-
globalScheduler.enqueue(() => runComponent(instance));
|
|
2817
|
-
}
|
|
2818
2838
|
function getCurrentInstance() {
|
|
2819
2839
|
return currentInstance;
|
|
2820
2840
|
}
|
|
2821
|
-
function
|
|
2822
|
-
if (!currentInstance) {
|
|
2823
|
-
throw new Error(
|
|
2824
|
-
"getSignal() can only be called during component render execution. Ensure you are calling this from inside your component function."
|
|
2825
|
-
);
|
|
2826
|
-
}
|
|
2827
|
-
return currentInstance.abortController.signal;
|
|
2828
|
-
}
|
|
2829
|
-
function finalizeReadSubscriptions(instance) {
|
|
2841
|
+
function finalizeReadSubscriptions2(instance) {
|
|
2830
2842
|
const newSet = instance._pendingReadStates ?? /* @__PURE__ */ new Set();
|
|
2831
2843
|
const oldSet = instance._lastReadStates ?? /* @__PURE__ */ new Set();
|
|
2832
2844
|
const token = instance._currentRenderToken;
|
|
@@ -2850,12 +2862,6 @@ function finalizeReadSubscriptions(instance) {
|
|
|
2850
2862
|
instance._pendingReadStates = /* @__PURE__ */ new Set();
|
|
2851
2863
|
instance._currentRenderToken = void 0;
|
|
2852
2864
|
}
|
|
2853
|
-
function getNextStateIndex() {
|
|
2854
|
-
return stateIndex++;
|
|
2855
|
-
}
|
|
2856
|
-
function mountComponent(instance) {
|
|
2857
|
-
executeComponent(instance);
|
|
2858
|
-
}
|
|
2859
2865
|
function cleanupComponent(instance) {
|
|
2860
2866
|
const cleanupErrors = [];
|
|
2861
2867
|
for (const cleanup of instance.cleanupFns) {
|
|
@@ -2889,167 +2895,27 @@ function cleanupComponent(instance) {
|
|
|
2889
2895
|
instance.notifyUpdate = null;
|
|
2890
2896
|
instance.mounted = false;
|
|
2891
2897
|
}
|
|
2892
|
-
var currentInstance, stateIndex, _globalRenderCounter;
|
|
2893
|
-
var init_component = __esm({
|
|
2894
|
-
"src/runtime/component.ts"() {
|
|
2895
|
-
"use strict";
|
|
2896
|
-
init_scheduler();
|
|
2897
|
-
init_context();
|
|
2898
|
-
init_logger();
|
|
2899
|
-
init_diag();
|
|
2900
|
-
init_fastlane_shared();
|
|
2901
|
-
init_renderer();
|
|
2902
|
-
currentInstance = null;
|
|
2903
|
-
stateIndex = 0;
|
|
2904
|
-
_globalRenderCounter = 0;
|
|
2905
|
-
}
|
|
2906
|
-
});
|
|
2907
|
-
|
|
2908
|
-
// src/ssr/errors.ts
|
|
2909
|
-
var SSRDataMissingError;
|
|
2910
|
-
var init_errors = __esm({
|
|
2911
|
-
"src/ssr/errors.ts"() {
|
|
2912
|
-
"use strict";
|
|
2913
|
-
SSRDataMissingError = class _SSRDataMissingError extends Error {
|
|
2914
|
-
constructor(message = "Server-side rendering requires all data to be available synchronously. This component attempted to use async data during SSR.") {
|
|
2915
|
-
super(message);
|
|
2916
|
-
this.code = "SSR_DATA_MISSING";
|
|
2917
|
-
this.name = "SSRDataMissingError";
|
|
2918
|
-
Object.setPrototypeOf(this, _SSRDataMissingError.prototype);
|
|
2919
|
-
}
|
|
2920
|
-
};
|
|
2921
|
-
}
|
|
2922
|
-
});
|
|
2923
|
-
|
|
2924
|
-
// src/ssr/context.ts
|
|
2925
|
-
function withSSRContext(ctx, fn) {
|
|
2926
|
-
const prev = current;
|
|
2927
|
-
current = ctx;
|
|
2928
|
-
try {
|
|
2929
|
-
return fn();
|
|
2930
|
-
} finally {
|
|
2931
|
-
current = prev;
|
|
2932
|
-
}
|
|
2933
|
-
}
|
|
2934
|
-
function createRenderContext(seed = 12345) {
|
|
2935
|
-
return { seed };
|
|
2936
|
-
}
|
|
2937
|
-
function getCurrentSSRContext() {
|
|
2938
|
-
return currentSSRContext;
|
|
2939
|
-
}
|
|
2940
|
-
function runWithSSRContext(ctx, fn) {
|
|
2941
|
-
const prev = currentSSRContext;
|
|
2942
|
-
currentSSRContext = ctx;
|
|
2943
|
-
try {
|
|
2944
|
-
return fn();
|
|
2945
|
-
} finally {
|
|
2946
|
-
currentSSRContext = prev;
|
|
2947
|
-
}
|
|
2948
|
-
}
|
|
2949
|
-
function throwSSRDataMissing() {
|
|
2950
|
-
throw new SSRDataMissingError();
|
|
2951
|
-
}
|
|
2952
|
-
var current, currentSSRContext;
|
|
2953
|
-
var init_context2 = __esm({
|
|
2954
|
-
"src/ssr/context.ts"() {
|
|
2955
|
-
"use strict";
|
|
2956
|
-
init_errors();
|
|
2957
|
-
current = null;
|
|
2958
|
-
currentSSRContext = null;
|
|
2959
|
-
}
|
|
2960
|
-
});
|
|
2961
2898
|
|
|
2962
|
-
// src/
|
|
2963
|
-
|
|
2964
|
-
|
|
2965
|
-
|
|
2966
|
-
|
|
2967
|
-
keyCounter = 0;
|
|
2968
|
-
}
|
|
2969
|
-
function getNextKey() {
|
|
2970
|
-
return `r:${keyCounter++}`;
|
|
2971
|
-
}
|
|
2972
|
-
function startRenderPhase(data) {
|
|
2973
|
-
currentRenderData = data ?? null;
|
|
2974
|
-
resetKeyCounter();
|
|
2975
|
-
}
|
|
2976
|
-
function stopRenderPhase() {
|
|
2977
|
-
currentRenderData = null;
|
|
2978
|
-
resetKeyCounter();
|
|
2979
|
-
}
|
|
2980
|
-
async function resolvePlan(_plan) {
|
|
2981
|
-
throw new Error(
|
|
2982
|
-
`${PREPASS_REMOVED_MSG}; async resource plans are not supported`
|
|
2983
|
-
);
|
|
2984
|
-
}
|
|
2985
|
-
function collectResources(_opts) {
|
|
2986
|
-
throw new Error(`${PREPASS_REMOVED_MSG}; collectResources is disabled`);
|
|
2899
|
+
// src/runtime/execution-model.ts
|
|
2900
|
+
var EXECUTION_MODEL_KEY = /* @__PURE__ */ Symbol.for("__ASKR_EXECUTION_MODEL__");
|
|
2901
|
+
function getExecutionModel() {
|
|
2902
|
+
const g = globalThis;
|
|
2903
|
+
return g[EXECUTION_MODEL_KEY];
|
|
2987
2904
|
}
|
|
2988
|
-
var keyCounter, currentRenderData, PREPASS_REMOVED_MSG, resolveResources;
|
|
2989
|
-
var init_render_keys = __esm({
|
|
2990
|
-
"src/ssr/render-keys.ts"() {
|
|
2991
|
-
"use strict";
|
|
2992
|
-
keyCounter = 0;
|
|
2993
|
-
currentRenderData = null;
|
|
2994
|
-
PREPASS_REMOVED_MSG = "SSR collection/prepass is removed: SSR is strictly synchronous";
|
|
2995
|
-
resolveResources = resolvePlan;
|
|
2996
|
-
}
|
|
2997
|
-
});
|
|
2998
2905
|
|
|
2999
|
-
// src/router/
|
|
3000
|
-
|
|
3001
|
-
|
|
3002
|
-
|
|
3003
|
-
|
|
3004
|
-
|
|
3005
|
-
|
|
3006
|
-
|
|
3007
|
-
|
|
3008
|
-
params: {
|
|
3009
|
-
"*": pathSegments.length > 1 ? normalizedPath : pathSegments[0]
|
|
3010
|
-
}
|
|
3011
|
-
};
|
|
3012
|
-
}
|
|
3013
|
-
if (pathSegments.length !== patternSegments.length) {
|
|
3014
|
-
return { matched: false, params: {} };
|
|
3015
|
-
}
|
|
3016
|
-
const params = {};
|
|
3017
|
-
for (let i = 0; i < patternSegments.length; i++) {
|
|
3018
|
-
const patternSegment = patternSegments[i];
|
|
3019
|
-
const pathSegment = pathSegments[i];
|
|
3020
|
-
if (patternSegment.startsWith("{") && patternSegment.endsWith("}")) {
|
|
3021
|
-
const paramName = patternSegment.slice(1, -1);
|
|
3022
|
-
params[paramName] = decodeURIComponent(pathSegment);
|
|
3023
|
-
} else if (patternSegment === "*") {
|
|
3024
|
-
params["*"] = pathSegment;
|
|
3025
|
-
} else if (patternSegment !== pathSegment) {
|
|
3026
|
-
return { matched: false, params: {} };
|
|
3027
|
-
}
|
|
2906
|
+
// src/router/route.ts
|
|
2907
|
+
var routes = [];
|
|
2908
|
+
var namespaces = /* @__PURE__ */ new Set();
|
|
2909
|
+
var HAS_ROUTES_KEY = /* @__PURE__ */ Symbol.for("__ASKR_HAS_ROUTES__");
|
|
2910
|
+
function setHasRoutes(value) {
|
|
2911
|
+
try {
|
|
2912
|
+
const g = globalThis;
|
|
2913
|
+
g[HAS_ROUTES_KEY] = value;
|
|
2914
|
+
} catch {
|
|
3028
2915
|
}
|
|
3029
|
-
return { matched: true, params };
|
|
3030
2916
|
}
|
|
3031
|
-
|
|
3032
|
-
|
|
3033
|
-
"use strict";
|
|
3034
|
-
}
|
|
3035
|
-
});
|
|
3036
|
-
|
|
3037
|
-
// src/router/route.ts
|
|
3038
|
-
var route_exports = {};
|
|
3039
|
-
__export(route_exports, {
|
|
3040
|
-
_lockRouteRegistrationForTests: () => _lockRouteRegistrationForTests,
|
|
3041
|
-
_unlockRouteRegistrationForTests: () => _unlockRouteRegistrationForTests,
|
|
3042
|
-
clearRoutes: () => clearRoutes,
|
|
3043
|
-
getLoadedNamespaces: () => getLoadedNamespaces,
|
|
3044
|
-
getNamespaceRoutes: () => getNamespaceRoutes,
|
|
3045
|
-
getRoutes: () => getRoutes,
|
|
3046
|
-
lockRouteRegistration: () => lockRouteRegistration,
|
|
3047
|
-
registerRoute: () => registerRoute,
|
|
3048
|
-
resolveRoute: () => resolveRoute,
|
|
3049
|
-
route: () => route,
|
|
3050
|
-
setServerLocation: () => setServerLocation,
|
|
3051
|
-
unloadNamespace: () => unloadNamespace
|
|
3052
|
-
});
|
|
2917
|
+
setHasRoutes(false);
|
|
2918
|
+
var routesByDepth = /* @__PURE__ */ new Map();
|
|
3053
2919
|
function getDepth(path) {
|
|
3054
2920
|
const normalized = path.endsWith("/") && path !== "/" ? path.slice(0, -1) : path;
|
|
3055
2921
|
return normalized === "/" ? 0 : normalized.split("/").filter(Boolean).length;
|
|
@@ -3072,6 +2938,7 @@ function getSpecificity(path) {
|
|
|
3072
2938
|
}
|
|
3073
2939
|
return score;
|
|
3074
2940
|
}
|
|
2941
|
+
var serverLocation = null;
|
|
3075
2942
|
function setServerLocation(url) {
|
|
3076
2943
|
serverLocation = url;
|
|
3077
2944
|
}
|
|
@@ -3158,6 +3025,7 @@ function computeMatches(pathname) {
|
|
|
3158
3025
|
namespace: m.namespace
|
|
3159
3026
|
}));
|
|
3160
3027
|
}
|
|
3028
|
+
var registrationLocked = false;
|
|
3161
3029
|
function lockRouteRegistration() {
|
|
3162
3030
|
registrationLocked = true;
|
|
3163
3031
|
}
|
|
@@ -3168,6 +3036,11 @@ function _unlockRouteRegistrationForTests() {
|
|
|
3168
3036
|
registrationLocked = false;
|
|
3169
3037
|
}
|
|
3170
3038
|
function route(path, handler, namespace) {
|
|
3039
|
+
if (getExecutionModel() === "islands") {
|
|
3040
|
+
throw new Error(
|
|
3041
|
+
"Routes are not supported with islands. Use createSPA (client) or createSSR (server) instead."
|
|
3042
|
+
);
|
|
3043
|
+
}
|
|
3171
3044
|
if (typeof path === "undefined") {
|
|
3172
3045
|
const instance = getCurrentComponentInstance();
|
|
3173
3046
|
if (!instance) {
|
|
@@ -3210,7 +3083,7 @@ function route(path, handler, namespace) {
|
|
|
3210
3083
|
}
|
|
3211
3084
|
if (registrationLocked) {
|
|
3212
3085
|
throw new Error(
|
|
3213
|
-
"Route registration is locked after app startup. Register routes at module load time before calling
|
|
3086
|
+
"Route registration is locked after app startup. Register routes at module load time before calling createSPA or createSSR."
|
|
3214
3087
|
);
|
|
3215
3088
|
}
|
|
3216
3089
|
if (typeof handler !== "function") {
|
|
@@ -3220,6 +3093,7 @@ function route(path, handler, namespace) {
|
|
|
3220
3093
|
}
|
|
3221
3094
|
const routeObj = { path, handler, namespace };
|
|
3222
3095
|
routes.push(routeObj);
|
|
3096
|
+
setHasRoutes(true);
|
|
3223
3097
|
const depth = getDepth(path);
|
|
3224
3098
|
let depthRoutes = routesByDepth.get(depth);
|
|
3225
3099
|
if (!depthRoutes) {
|
|
@@ -3260,6 +3134,8 @@ function clearRoutes() {
|
|
|
3260
3134
|
routes.length = 0;
|
|
3261
3135
|
namespaces.clear();
|
|
3262
3136
|
routesByDepth.clear();
|
|
3137
|
+
registrationLocked = false;
|
|
3138
|
+
setHasRoutes(false);
|
|
3263
3139
|
}
|
|
3264
3140
|
function normalizeHandler(handler) {
|
|
3265
3141
|
if (handler == null) return void 0;
|
|
@@ -3355,186 +3231,40 @@ function resolveRoute(pathname) {
|
|
|
3355
3231
|
}
|
|
3356
3232
|
return null;
|
|
3357
3233
|
}
|
|
3358
|
-
var routes, namespaces, routesByDepth, serverLocation, registrationLocked;
|
|
3359
|
-
var init_route = __esm({
|
|
3360
|
-
"src/router/route.ts"() {
|
|
3361
|
-
"use strict";
|
|
3362
|
-
init_match();
|
|
3363
|
-
init_component();
|
|
3364
|
-
routes = [];
|
|
3365
|
-
namespaces = /* @__PURE__ */ new Set();
|
|
3366
|
-
routesByDepth = /* @__PURE__ */ new Map();
|
|
3367
|
-
serverLocation = null;
|
|
3368
|
-
registrationLocked = false;
|
|
3369
|
-
}
|
|
3370
|
-
});
|
|
3371
|
-
|
|
3372
|
-
// src/router/navigate.ts
|
|
3373
|
-
var navigate_exports = {};
|
|
3374
|
-
__export(navigate_exports, {
|
|
3375
|
-
cleanupNavigation: () => cleanupNavigation,
|
|
3376
|
-
initializeNavigation: () => initializeNavigation,
|
|
3377
|
-
navigate: () => navigate,
|
|
3378
|
-
registerAppInstance: () => registerAppInstance
|
|
3379
|
-
});
|
|
3380
|
-
function registerAppInstance(instance, _path) {
|
|
3381
|
-
currentInstance2 = instance;
|
|
3382
|
-
if (process.env.NODE_ENV === "production") {
|
|
3383
|
-
lockRouteRegistration();
|
|
3384
|
-
}
|
|
3385
|
-
}
|
|
3386
|
-
function navigate(path) {
|
|
3387
|
-
if (typeof window === "undefined") {
|
|
3388
|
-
return;
|
|
3389
|
-
}
|
|
3390
|
-
const resolved = resolveRoute(path);
|
|
3391
|
-
if (!resolved) {
|
|
3392
|
-
if (process.env.NODE_ENV !== "production") {
|
|
3393
|
-
logger.warn(`No route found for path: ${path}`);
|
|
3394
|
-
}
|
|
3395
|
-
return;
|
|
3396
|
-
}
|
|
3397
|
-
window.history.pushState({ path }, "", path);
|
|
3398
|
-
if (currentInstance2) {
|
|
3399
|
-
cleanupComponent(currentInstance2);
|
|
3400
|
-
currentInstance2.fn = resolved.handler;
|
|
3401
|
-
currentInstance2.props = resolved.params;
|
|
3402
|
-
currentInstance2.stateValues = [];
|
|
3403
|
-
currentInstance2.expectedStateIndices = [];
|
|
3404
|
-
currentInstance2.firstRenderComplete = false;
|
|
3405
|
-
currentInstance2.stateIndexCheck = -1;
|
|
3406
|
-
currentInstance2.evaluationGeneration++;
|
|
3407
|
-
currentInstance2.notifyUpdate = null;
|
|
3408
|
-
currentInstance2.abortController = new AbortController();
|
|
3409
|
-
mountComponent(currentInstance2);
|
|
3410
|
-
}
|
|
3411
|
-
}
|
|
3412
|
-
function handlePopState(_event) {
|
|
3413
|
-
const path = window.location.pathname;
|
|
3414
|
-
if (!currentInstance2) {
|
|
3415
|
-
return;
|
|
3416
|
-
}
|
|
3417
|
-
const resolved = resolveRoute(path);
|
|
3418
|
-
if (resolved) {
|
|
3419
|
-
cleanupComponent(currentInstance2);
|
|
3420
|
-
currentInstance2.fn = resolved.handler;
|
|
3421
|
-
currentInstance2.props = resolved.params;
|
|
3422
|
-
currentInstance2.stateValues = [];
|
|
3423
|
-
currentInstance2.expectedStateIndices = [];
|
|
3424
|
-
currentInstance2.firstRenderComplete = false;
|
|
3425
|
-
currentInstance2.stateIndexCheck = -1;
|
|
3426
|
-
currentInstance2.evaluationGeneration++;
|
|
3427
|
-
currentInstance2.notifyUpdate = null;
|
|
3428
|
-
currentInstance2.abortController = new AbortController();
|
|
3429
|
-
mountComponent(currentInstance2);
|
|
3430
|
-
}
|
|
3431
|
-
}
|
|
3432
|
-
function initializeNavigation() {
|
|
3433
|
-
if (typeof window !== "undefined") {
|
|
3434
|
-
window.addEventListener("popstate", handlePopState);
|
|
3435
|
-
}
|
|
3436
|
-
}
|
|
3437
|
-
function cleanupNavigation() {
|
|
3438
|
-
if (typeof window !== "undefined") {
|
|
3439
|
-
window.removeEventListener("popstate", handlePopState);
|
|
3440
|
-
}
|
|
3441
|
-
}
|
|
3442
|
-
var currentInstance2;
|
|
3443
|
-
var init_navigate = __esm({
|
|
3444
|
-
"src/router/navigate.ts"() {
|
|
3445
|
-
"use strict";
|
|
3446
|
-
init_route();
|
|
3447
|
-
init_component();
|
|
3448
|
-
init_logger();
|
|
3449
|
-
currentInstance2 = null;
|
|
3450
|
-
}
|
|
3451
|
-
});
|
|
3452
|
-
|
|
3453
|
-
// src/jsx/utils.ts
|
|
3454
|
-
function isElement(value) {
|
|
3455
|
-
return typeof value === "object" && value !== null && value.$$typeof === ELEMENT_TYPE;
|
|
3456
|
-
}
|
|
3457
|
-
function cloneElement(element, props) {
|
|
3458
|
-
return {
|
|
3459
|
-
...element,
|
|
3460
|
-
props: { ...element.props, ...props }
|
|
3461
|
-
};
|
|
3462
|
-
}
|
|
3463
|
-
var init_utils2 = __esm({
|
|
3464
|
-
"src/jsx/utils.ts"() {
|
|
3465
|
-
"use strict";
|
|
3466
|
-
init_types2();
|
|
3467
|
-
}
|
|
3468
|
-
});
|
|
3469
|
-
|
|
3470
|
-
// src/jsx/index.ts
|
|
3471
|
-
var init_jsx = __esm({
|
|
3472
|
-
"src/jsx/index.ts"() {
|
|
3473
|
-
"use strict";
|
|
3474
|
-
init_types2();
|
|
3475
|
-
init_utils2();
|
|
3476
|
-
}
|
|
3477
|
-
});
|
|
3478
3234
|
|
|
3479
3235
|
// src/foundations/portal.tsx
|
|
3480
3236
|
function definePortal() {
|
|
3481
3237
|
if (typeof createPortalSlot !== "function") {
|
|
3482
3238
|
let HostFallback2 = function() {
|
|
3483
|
-
|
|
3484
|
-
|
|
3485
|
-
|
|
3486
|
-
const owner = hosts.find((h) => h.mounted === true) || null;
|
|
3487
|
-
const mountedHosts = hosts.filter((h) => h.mounted === true);
|
|
3488
|
-
if (mountedHosts.length > 1) {
|
|
3489
|
-
logger.warn(
|
|
3490
|
-
"[Portal] multiple hosts are mounted for same portal; first mounted host will be owner"
|
|
3491
|
-
);
|
|
3492
|
-
}
|
|
3493
|
-
if (inst && owner && owner !== inst) {
|
|
3494
|
-
logger.debug(
|
|
3495
|
-
"[Portal] non-owner reader detected; only owner renders portal content"
|
|
3496
|
-
);
|
|
3239
|
+
if (owner && owner.mounted === false) {
|
|
3240
|
+
owner = null;
|
|
3241
|
+
pending = void 0;
|
|
3497
3242
|
}
|
|
3243
|
+
const inst = getCurrentComponentInstance();
|
|
3244
|
+
if (!owner && inst) owner = inst;
|
|
3498
3245
|
if (process.env.NODE_ENV !== "production") {
|
|
3499
3246
|
const ns = globalThis.__ASKR__ || (globalThis.__ASKR__ = {});
|
|
3500
3247
|
ns.__PORTAL_READS = (ns.__PORTAL_READS || 0) + 1;
|
|
3501
3248
|
}
|
|
3502
|
-
if (process.env.NODE_ENV !== "production"
|
|
3503
|
-
|
|
3504
|
-
|
|
3505
|
-
|
|
3506
|
-
|
|
3249
|
+
if (process.env.NODE_ENV !== "production") {
|
|
3250
|
+
if (inst && owner && inst !== owner && inst.mounted === true) {
|
|
3251
|
+
logger.warn(
|
|
3252
|
+
"[Portal] multiple mounted hosts detected; first mounted host is owner"
|
|
3253
|
+
);
|
|
3254
|
+
}
|
|
3507
3255
|
}
|
|
3508
|
-
return inst === owner ? pending : void 0;
|
|
3256
|
+
return inst && owner && inst === owner ? pending : void 0;
|
|
3509
3257
|
};
|
|
3510
|
-
|
|
3511
|
-
let hosts = [];
|
|
3258
|
+
let owner = null;
|
|
3512
3259
|
let pending;
|
|
3513
3260
|
HostFallback2.render = function RenderFallback(props) {
|
|
3514
|
-
|
|
3515
|
-
const owner = hosts.find((h) => h.mounted === true) || null;
|
|
3516
|
-
if (!owner) {
|
|
3517
|
-
logger.debug(
|
|
3518
|
-
"[Portal] fallback.write dropped -> no owner or not mounted",
|
|
3519
|
-
props?.children
|
|
3520
|
-
);
|
|
3521
|
-
return null;
|
|
3522
|
-
}
|
|
3523
|
-
pending = props.children;
|
|
3524
|
-
logger.debug("[Portal] fallback.write ->", pending, "owner=", owner.id);
|
|
3261
|
+
if (!owner || owner.mounted !== true) return null;
|
|
3525
3262
|
if (process.env.NODE_ENV !== "production") {
|
|
3526
3263
|
const ns = globalThis.__ASKR__ || (globalThis.__ASKR__ = {});
|
|
3527
3264
|
ns.__PORTAL_WRITES = (ns.__PORTAL_WRITES || 0) + 1;
|
|
3528
3265
|
}
|
|
3529
|
-
|
|
3530
|
-
|
|
3531
|
-
logger.debug(
|
|
3532
|
-
"[Portal] fallback.write notify ->",
|
|
3533
|
-
owner.id,
|
|
3534
|
-
!!owner.notifyUpdate
|
|
3535
|
-
);
|
|
3536
|
-
owner.notifyUpdate();
|
|
3537
|
-
}
|
|
3266
|
+
pending = props.children;
|
|
3267
|
+
if (owner.notifyUpdate) owner.notifyUpdate();
|
|
3538
3268
|
return null;
|
|
3539
3269
|
};
|
|
3540
3270
|
return HostFallback2;
|
|
@@ -3544,7 +3274,6 @@ function definePortal() {
|
|
|
3544
3274
|
return slot.read();
|
|
3545
3275
|
}
|
|
3546
3276
|
PortalHost.render = function PortalRender(props) {
|
|
3547
|
-
logger.debug("[Portal] write ->", props?.children);
|
|
3548
3277
|
if (process.env.NODE_ENV !== "production") {
|
|
3549
3278
|
const ns = globalThis.__ASKR__ || (globalThis.__ASKR__ = {});
|
|
3550
3279
|
ns.__PORTAL_WRITES = (ns.__PORTAL_WRITES || 0) + 1;
|
|
@@ -3554,26 +3283,16 @@ function definePortal() {
|
|
|
3554
3283
|
};
|
|
3555
3284
|
return PortalHost;
|
|
3556
3285
|
}
|
|
3557
|
-
|
|
3558
|
-
|
|
3559
|
-
_defaultPortalIsFallback = false;
|
|
3560
|
-
}
|
|
3286
|
+
var _defaultPortal;
|
|
3287
|
+
var _defaultPortalIsFallback = false;
|
|
3561
3288
|
function ensureDefaultPortal() {
|
|
3562
|
-
logger.debug(
|
|
3563
|
-
"[DefaultPortal] ensureDefaultPortal _defaultPortalIsFallback=",
|
|
3564
|
-
_defaultPortalIsFallback,
|
|
3565
|
-
"createPortalSlot=",
|
|
3566
|
-
typeof createPortalSlot === "function"
|
|
3567
|
-
);
|
|
3568
3289
|
if (!_defaultPortal) {
|
|
3569
3290
|
if (typeof createPortalSlot === "function") {
|
|
3570
3291
|
_defaultPortal = definePortal();
|
|
3571
3292
|
_defaultPortalIsFallback = false;
|
|
3572
|
-
logger.debug("[DefaultPortal] created real portal");
|
|
3573
3293
|
} else {
|
|
3574
3294
|
_defaultPortal = definePortal();
|
|
3575
3295
|
_defaultPortalIsFallback = true;
|
|
3576
|
-
logger.debug("[DefaultPortal] created fallback portal");
|
|
3577
3296
|
}
|
|
3578
3297
|
return _defaultPortal;
|
|
3579
3298
|
}
|
|
@@ -3586,32 +3305,122 @@ function ensureDefaultPortal() {
|
|
|
3586
3305
|
const fallback = definePortal();
|
|
3587
3306
|
_defaultPortal = fallback;
|
|
3588
3307
|
_defaultPortalIsFallback = true;
|
|
3589
|
-
logger.debug("[DefaultPortal] reverted to fallback portal");
|
|
3590
3308
|
}
|
|
3591
3309
|
return _defaultPortal;
|
|
3592
3310
|
}
|
|
3593
|
-
var
|
|
3594
|
-
|
|
3595
|
-
|
|
3596
|
-
|
|
3597
|
-
init_component();
|
|
3598
|
-
init_logger();
|
|
3599
|
-
_defaultPortalIsFallback = false;
|
|
3600
|
-
DefaultPortal = (() => {
|
|
3601
|
-
function Host() {
|
|
3602
|
-
const v = ensureDefaultPortal()();
|
|
3603
|
-
return v === void 0 ? null : v;
|
|
3604
|
-
}
|
|
3605
|
-
Host.render = function Render(props) {
|
|
3606
|
-
ensureDefaultPortal().render(props);
|
|
3607
|
-
return null;
|
|
3608
|
-
};
|
|
3609
|
-
return Host;
|
|
3610
|
-
})();
|
|
3311
|
+
var DefaultPortal = (() => {
|
|
3312
|
+
function Host() {
|
|
3313
|
+
const v = ensureDefaultPortal()();
|
|
3314
|
+
return v === void 0 ? null : v;
|
|
3611
3315
|
}
|
|
3612
|
-
|
|
3316
|
+
Host.render = function Render(props) {
|
|
3317
|
+
ensureDefaultPortal().render(props);
|
|
3318
|
+
return null;
|
|
3319
|
+
};
|
|
3320
|
+
return Host;
|
|
3321
|
+
})();
|
|
3322
|
+
|
|
3323
|
+
// src/common/ssr-errors.ts
|
|
3324
|
+
var SSRDataMissingError = class _SSRDataMissingError extends Error {
|
|
3325
|
+
constructor(message = "Server-side rendering requires all data to be available synchronously. This component attempted to use async data during SSR.") {
|
|
3326
|
+
super(message);
|
|
3327
|
+
this.code = "SSR_DATA_MISSING";
|
|
3328
|
+
this.name = "SSRDataMissingError";
|
|
3329
|
+
Object.setPrototypeOf(this, _SSRDataMissingError.prototype);
|
|
3330
|
+
}
|
|
3331
|
+
};
|
|
3332
|
+
function withSSRContext(ctx, fn) {
|
|
3333
|
+
try {
|
|
3334
|
+
return fn();
|
|
3335
|
+
} finally {
|
|
3336
|
+
}
|
|
3337
|
+
}
|
|
3338
|
+
function createRenderContext(seed = 12345) {
|
|
3339
|
+
return { seed };
|
|
3340
|
+
}
|
|
3341
|
+
function runWithSSRContext(ctx, fn) {
|
|
3342
|
+
try {
|
|
3343
|
+
return fn();
|
|
3344
|
+
} finally {
|
|
3345
|
+
}
|
|
3346
|
+
}
|
|
3347
|
+
function throwSSRDataMissing() {
|
|
3348
|
+
throw new SSRDataMissingError();
|
|
3349
|
+
}
|
|
3350
|
+
function startRenderPhase(data) {
|
|
3351
|
+
}
|
|
3352
|
+
var PREPASS_REMOVED_MSG = "SSR collection/prepass is removed: SSR is strictly synchronous";
|
|
3353
|
+
async function resolvePlan(_plan) {
|
|
3354
|
+
throw new Error(
|
|
3355
|
+
`${PREPASS_REMOVED_MSG}; async resource plans are not supported`
|
|
3356
|
+
);
|
|
3357
|
+
}
|
|
3358
|
+
function collectResources(_opts) {
|
|
3359
|
+
throw new Error(`${PREPASS_REMOVED_MSG}; collectResources is disabled`);
|
|
3360
|
+
}
|
|
3361
|
+
var resolveResources = resolvePlan;
|
|
3613
3362
|
|
|
3614
3363
|
// src/ssr/escape.ts
|
|
3364
|
+
var VOID_ELEMENTS = /* @__PURE__ */ new Set([
|
|
3365
|
+
"area",
|
|
3366
|
+
"base",
|
|
3367
|
+
"br",
|
|
3368
|
+
"col",
|
|
3369
|
+
"embed",
|
|
3370
|
+
"hr",
|
|
3371
|
+
"img",
|
|
3372
|
+
"input",
|
|
3373
|
+
"link",
|
|
3374
|
+
"meta",
|
|
3375
|
+
"param",
|
|
3376
|
+
"source",
|
|
3377
|
+
"track",
|
|
3378
|
+
"wbr"
|
|
3379
|
+
]);
|
|
3380
|
+
var escapeCache = /* @__PURE__ */ new Map();
|
|
3381
|
+
var MAX_CACHE_SIZE = 256;
|
|
3382
|
+
var TEXT_ESCAPE_TEST_RE = /[&<>]/;
|
|
3383
|
+
var TEXT_ESCAPE_RE = /[&<>]/g;
|
|
3384
|
+
var ATTR_ESCAPE_TEST_RE = /[&"'<>]/;
|
|
3385
|
+
var ATTR_ESCAPE_RE = /[&"'<>]/g;
|
|
3386
|
+
var CSS_UNSAFE_TEST_RE = /[{}<>\\]/;
|
|
3387
|
+
var CSS_UNSAFE_RE = /[{}<>\\]/g;
|
|
3388
|
+
var CSS_DANGEROUS_FN_RE = /(?:url|expression|javascript)\s*\(/i;
|
|
3389
|
+
var STYLE_PROP_CACHE = /* @__PURE__ */ new Map();
|
|
3390
|
+
var MAX_STYLE_PROP_CACHE_SIZE = 512;
|
|
3391
|
+
function toKebabCached(prop) {
|
|
3392
|
+
const cached = STYLE_PROP_CACHE.get(prop);
|
|
3393
|
+
if (cached !== void 0) return cached;
|
|
3394
|
+
const kebab = prop.replace(/[A-Z]/g, (m) => `-${m.toLowerCase()}`);
|
|
3395
|
+
if (STYLE_PROP_CACHE.size < MAX_STYLE_PROP_CACHE_SIZE) {
|
|
3396
|
+
STYLE_PROP_CACHE.set(prop, kebab);
|
|
3397
|
+
}
|
|
3398
|
+
return kebab;
|
|
3399
|
+
}
|
|
3400
|
+
function mapTextEscape(ch) {
|
|
3401
|
+
switch (ch) {
|
|
3402
|
+
case "&":
|
|
3403
|
+
return "&";
|
|
3404
|
+
case "<":
|
|
3405
|
+
return "<";
|
|
3406
|
+
default:
|
|
3407
|
+
return ">";
|
|
3408
|
+
}
|
|
3409
|
+
}
|
|
3410
|
+
function mapAttrEscape(ch) {
|
|
3411
|
+
switch (ch) {
|
|
3412
|
+
case "&":
|
|
3413
|
+
return "&";
|
|
3414
|
+
case '"':
|
|
3415
|
+
return """;
|
|
3416
|
+
case "'":
|
|
3417
|
+
return "'";
|
|
3418
|
+
case "<":
|
|
3419
|
+
return "<";
|
|
3420
|
+
default:
|
|
3421
|
+
return ">";
|
|
3422
|
+
}
|
|
3423
|
+
}
|
|
3615
3424
|
function escapeText(text) {
|
|
3616
3425
|
const useCache = text.length <= 64;
|
|
3617
3426
|
if (useCache) {
|
|
@@ -3619,13 +3428,13 @@ function escapeText(text) {
|
|
|
3619
3428
|
if (cached !== void 0) return cached;
|
|
3620
3429
|
}
|
|
3621
3430
|
const str = String(text);
|
|
3622
|
-
if (!
|
|
3431
|
+
if (!TEXT_ESCAPE_TEST_RE.test(str)) {
|
|
3623
3432
|
if (useCache && escapeCache.size < MAX_CACHE_SIZE) {
|
|
3624
3433
|
escapeCache.set(text, str);
|
|
3625
3434
|
}
|
|
3626
3435
|
return str;
|
|
3627
3436
|
}
|
|
3628
|
-
const result = str.replace(
|
|
3437
|
+
const result = str.replace(TEXT_ESCAPE_RE, mapTextEscape);
|
|
3629
3438
|
if (useCache && escapeCache.size < MAX_CACHE_SIZE) {
|
|
3630
3439
|
escapeCache.set(text, result);
|
|
3631
3440
|
}
|
|
@@ -3633,17 +3442,20 @@ function escapeText(text) {
|
|
|
3633
3442
|
}
|
|
3634
3443
|
function escapeAttr(value) {
|
|
3635
3444
|
const str = String(value);
|
|
3636
|
-
if (!
|
|
3445
|
+
if (!ATTR_ESCAPE_TEST_RE.test(str)) {
|
|
3637
3446
|
return str;
|
|
3638
3447
|
}
|
|
3639
|
-
return str.replace(
|
|
3448
|
+
return str.replace(ATTR_ESCAPE_RE, mapAttrEscape);
|
|
3640
3449
|
}
|
|
3641
3450
|
function escapeCssValue(value) {
|
|
3642
3451
|
const str = String(value);
|
|
3643
|
-
|
|
3452
|
+
const hasUnsafeChars = CSS_UNSAFE_TEST_RE.test(str);
|
|
3453
|
+
const openParen = str.indexOf("(");
|
|
3454
|
+
if (!hasUnsafeChars && openParen === -1) return str;
|
|
3455
|
+
if (openParen !== -1 && CSS_DANGEROUS_FN_RE.test(str)) {
|
|
3644
3456
|
return "";
|
|
3645
3457
|
}
|
|
3646
|
-
return str.replace(
|
|
3458
|
+
return hasUnsafeChars ? str.replace(CSS_UNSAFE_RE, "") : str;
|
|
3647
3459
|
}
|
|
3648
3460
|
function styleObjToCss(value) {
|
|
3649
3461
|
if (!value || typeof value !== "object") return null;
|
|
@@ -3652,7 +3464,7 @@ function styleObjToCss(value) {
|
|
|
3652
3464
|
let out = "";
|
|
3653
3465
|
for (const [k, v] of entries) {
|
|
3654
3466
|
if (v === null || v === void 0 || v === false) continue;
|
|
3655
|
-
const prop = k
|
|
3467
|
+
const prop = toKebabCached(k);
|
|
3656
3468
|
const safeValue = escapeCssValue(String(v));
|
|
3657
3469
|
if (safeValue) {
|
|
3658
3470
|
out += `${prop}:${safeValue};`;
|
|
@@ -3660,30 +3472,6 @@ function styleObjToCss(value) {
|
|
|
3660
3472
|
}
|
|
3661
3473
|
return out;
|
|
3662
3474
|
}
|
|
3663
|
-
var VOID_ELEMENTS, escapeCache, MAX_CACHE_SIZE;
|
|
3664
|
-
var init_escape = __esm({
|
|
3665
|
-
"src/ssr/escape.ts"() {
|
|
3666
|
-
"use strict";
|
|
3667
|
-
VOID_ELEMENTS = /* @__PURE__ */ new Set([
|
|
3668
|
-
"area",
|
|
3669
|
-
"base",
|
|
3670
|
-
"br",
|
|
3671
|
-
"col",
|
|
3672
|
-
"embed",
|
|
3673
|
-
"hr",
|
|
3674
|
-
"img",
|
|
3675
|
-
"input",
|
|
3676
|
-
"link",
|
|
3677
|
-
"meta",
|
|
3678
|
-
"param",
|
|
3679
|
-
"source",
|
|
3680
|
-
"track",
|
|
3681
|
-
"wbr"
|
|
3682
|
-
]);
|
|
3683
|
-
escapeCache = /* @__PURE__ */ new Map();
|
|
3684
|
-
MAX_CACHE_SIZE = 256;
|
|
3685
|
-
}
|
|
3686
|
-
});
|
|
3687
3475
|
|
|
3688
3476
|
// src/ssr/attrs.ts
|
|
3689
3477
|
function renderAttrs(props, opts) {
|
|
@@ -3692,8 +3480,11 @@ function renderAttrs(props, opts) {
|
|
|
3692
3480
|
}
|
|
3693
3481
|
let result = "";
|
|
3694
3482
|
let dangerousHtml;
|
|
3695
|
-
for (const
|
|
3483
|
+
for (const key in props) {
|
|
3484
|
+
if (!Object.prototype.hasOwnProperty.call(props, key)) continue;
|
|
3485
|
+
const value = props[key];
|
|
3696
3486
|
if (key === "children") continue;
|
|
3487
|
+
if (key === "key" || key === "ref") continue;
|
|
3697
3488
|
if (key === "dangerouslySetInnerHTML") {
|
|
3698
3489
|
if (value && typeof value === "object" && "__html" in value) {
|
|
3699
3490
|
dangerousHtml = String(value.__html);
|
|
@@ -3724,45 +3515,57 @@ function renderAttrs(props, opts) {
|
|
|
3724
3515
|
}
|
|
3725
3516
|
return result;
|
|
3726
3517
|
}
|
|
3727
|
-
var init_attrs = __esm({
|
|
3728
|
-
"src/ssr/attrs.ts"() {
|
|
3729
|
-
"use strict";
|
|
3730
|
-
init_escape();
|
|
3731
|
-
}
|
|
3732
|
-
});
|
|
3733
3518
|
|
|
3734
3519
|
// src/ssr/sink.ts
|
|
3735
|
-
var
|
|
3736
|
-
|
|
3737
|
-
|
|
3738
|
-
|
|
3739
|
-
|
|
3740
|
-
constructor() {
|
|
3741
|
-
this.chunks = [];
|
|
3742
|
-
}
|
|
3743
|
-
write(html) {
|
|
3744
|
-
if (html) this.chunks.push(html);
|
|
3745
|
-
}
|
|
3746
|
-
end() {
|
|
3747
|
-
}
|
|
3748
|
-
toString() {
|
|
3749
|
-
return this.chunks.join("");
|
|
3750
|
-
}
|
|
3751
|
-
};
|
|
3752
|
-
StreamSink = class {
|
|
3753
|
-
constructor(onChunk, onComplete) {
|
|
3754
|
-
this.onChunk = onChunk;
|
|
3755
|
-
this.onComplete = onComplete;
|
|
3756
|
-
}
|
|
3757
|
-
write(html) {
|
|
3758
|
-
if (html) this.onChunk(html);
|
|
3759
|
-
}
|
|
3760
|
-
end() {
|
|
3761
|
-
this.onComplete();
|
|
3762
|
-
}
|
|
3763
|
-
};
|
|
3520
|
+
var _StringSink = class _StringSink {
|
|
3521
|
+
constructor() {
|
|
3522
|
+
this.chunks = [];
|
|
3523
|
+
this.bufferChunks = [];
|
|
3524
|
+
this.bufferLen = 0;
|
|
3764
3525
|
}
|
|
3765
|
-
|
|
3526
|
+
write(html) {
|
|
3527
|
+
if (!html) return;
|
|
3528
|
+
this.bufferChunks.push(html);
|
|
3529
|
+
this.bufferLen += html.length;
|
|
3530
|
+
if (this.bufferLen >= _StringSink.FLUSH_THRESHOLD) {
|
|
3531
|
+
this.chunks.push(this.bufferChunks.join(""));
|
|
3532
|
+
this.bufferChunks.length = 0;
|
|
3533
|
+
this.bufferLen = 0;
|
|
3534
|
+
}
|
|
3535
|
+
}
|
|
3536
|
+
end() {
|
|
3537
|
+
if (this.bufferLen) {
|
|
3538
|
+
this.chunks.push(this.bufferChunks.join(""));
|
|
3539
|
+
this.bufferChunks.length = 0;
|
|
3540
|
+
this.bufferLen = 0;
|
|
3541
|
+
}
|
|
3542
|
+
}
|
|
3543
|
+
toString() {
|
|
3544
|
+
if (this.bufferLen) {
|
|
3545
|
+
this.chunks.push(this.bufferChunks.join(""));
|
|
3546
|
+
this.bufferChunks.length = 0;
|
|
3547
|
+
this.bufferLen = 0;
|
|
3548
|
+
}
|
|
3549
|
+
return this.chunks.join("");
|
|
3550
|
+
}
|
|
3551
|
+
};
|
|
3552
|
+
// Reduce array churn by batching many small writes into a larger buffer.
|
|
3553
|
+
// This is especially important for large SSR trees where we may write
|
|
3554
|
+
// hundreds of thousands of small fragments.
|
|
3555
|
+
_StringSink.FLUSH_THRESHOLD = 32 * 1024;
|
|
3556
|
+
var StringSink = _StringSink;
|
|
3557
|
+
var StreamSink = class {
|
|
3558
|
+
constructor(onChunk, onComplete) {
|
|
3559
|
+
this.onChunk = onChunk;
|
|
3560
|
+
this.onComplete = onComplete;
|
|
3561
|
+
}
|
|
3562
|
+
write(html) {
|
|
3563
|
+
if (html) this.onChunk(html);
|
|
3564
|
+
}
|
|
3565
|
+
end() {
|
|
3566
|
+
this.onComplete();
|
|
3567
|
+
}
|
|
3568
|
+
};
|
|
3766
3569
|
|
|
3767
3570
|
// src/ssr/stream-render.ts
|
|
3768
3571
|
function isVNodeLike(x) {
|
|
@@ -3790,7 +3593,7 @@ function isPromiseLike(x) {
|
|
|
3790
3593
|
const then = x.then;
|
|
3791
3594
|
return typeof then === "function";
|
|
3792
3595
|
}
|
|
3793
|
-
function
|
|
3596
|
+
function executeComponent(type, props, ctx) {
|
|
3794
3597
|
const res = type(props ?? {}, { signal: ctx.signal });
|
|
3795
3598
|
if (isPromiseLike(res)) {
|
|
3796
3599
|
throwSSRDataMissing();
|
|
@@ -3817,7 +3620,7 @@ function renderNodeToSink(node, sink, ctx) {
|
|
|
3817
3620
|
if (typeof type === "function") {
|
|
3818
3621
|
const out = withSSRContext(
|
|
3819
3622
|
ctx,
|
|
3820
|
-
() =>
|
|
3623
|
+
() => executeComponent(type, props, ctx)
|
|
3821
3624
|
);
|
|
3822
3625
|
renderNodeToSink(
|
|
3823
3626
|
out,
|
|
@@ -3843,30 +3646,10 @@ function renderNodeToSink(node, sink, ctx) {
|
|
|
3843
3646
|
}
|
|
3844
3647
|
sink.write(`</${tag}>`);
|
|
3845
3648
|
}
|
|
3846
|
-
var init_stream_render = __esm({
|
|
3847
|
-
"src/ssr/stream-render.ts"() {
|
|
3848
|
-
"use strict";
|
|
3849
|
-
init_jsx();
|
|
3850
|
-
init_context2();
|
|
3851
|
-
init_escape();
|
|
3852
|
-
init_attrs();
|
|
3853
|
-
}
|
|
3854
|
-
});
|
|
3855
3649
|
|
|
3856
3650
|
// src/ssr/index.ts
|
|
3857
|
-
|
|
3858
|
-
|
|
3859
|
-
SSRDataMissingError: () => SSRDataMissingError,
|
|
3860
|
-
collectResources: () => collectResources,
|
|
3861
|
-
popSSRStrictPurityGuard: () => popSSRStrictPurityGuard,
|
|
3862
|
-
pushSSRStrictPurityGuard: () => pushSSRStrictPurityGuard,
|
|
3863
|
-
renderToStream: () => renderToStream,
|
|
3864
|
-
renderToString: () => renderToString,
|
|
3865
|
-
renderToStringSync: () => renderToStringSync,
|
|
3866
|
-
renderToStringSyncForUrl: () => renderToStringSyncForUrl,
|
|
3867
|
-
resolvePlan: () => resolvePlan,
|
|
3868
|
-
resolveResources: () => resolveResources
|
|
3869
|
-
});
|
|
3651
|
+
process.env.NODE_ENV !== "production" && (process.env.ASKR_SSR_DEBUG === "1" || process.env.ASKR_SSR_DEBUG === "true");
|
|
3652
|
+
var __ssrGuardStack = [];
|
|
3870
3653
|
function pushSSRStrictPurityGuard() {
|
|
3871
3654
|
if (process.env.NODE_ENV === "production") return;
|
|
3872
3655
|
__ssrGuardStack.push({
|
|
@@ -3892,65 +3675,80 @@ function popSSRStrictPurityGuard() {
|
|
|
3892
3675
|
Reflect.set(Date, "now", prev.now);
|
|
3893
3676
|
}
|
|
3894
3677
|
}
|
|
3895
|
-
function
|
|
3896
|
-
if (
|
|
3897
|
-
if (typeof child === "
|
|
3898
|
-
|
|
3899
|
-
|
|
3900
|
-
|
|
3678
|
+
function renderChildSyncToSink(child, sink, ctx) {
|
|
3679
|
+
if (child === null || child === void 0 || child === false) return;
|
|
3680
|
+
if (typeof child === "string") {
|
|
3681
|
+
sink.write(escapeText(child));
|
|
3682
|
+
return;
|
|
3683
|
+
}
|
|
3684
|
+
if (typeof child === "number") {
|
|
3685
|
+
sink.write(escapeText(String(child)));
|
|
3686
|
+
return;
|
|
3687
|
+
}
|
|
3688
|
+
if (child && typeof child === "object" && "type" in child) {
|
|
3689
|
+
renderNodeSyncToSink(child, sink, ctx);
|
|
3901
3690
|
}
|
|
3902
|
-
return "";
|
|
3903
3691
|
}
|
|
3904
|
-
function
|
|
3905
|
-
if (!children || !Array.isArray(children) || children.length === 0) return
|
|
3906
|
-
let
|
|
3907
|
-
|
|
3908
|
-
|
|
3692
|
+
function renderChildrenSyncToSink(children, sink, ctx) {
|
|
3693
|
+
if (!children || !Array.isArray(children) || children.length === 0) return;
|
|
3694
|
+
for (let i = 0; i < children.length; i++) {
|
|
3695
|
+
renderChildSyncToSink(children[i], sink, ctx);
|
|
3696
|
+
}
|
|
3909
3697
|
}
|
|
3910
|
-
function
|
|
3698
|
+
function renderNodeSyncToSink(node, sink, ctx) {
|
|
3911
3699
|
const { type, props } = node;
|
|
3912
|
-
if (process.env.NODE_ENV !== "production") {
|
|
3913
|
-
try {
|
|
3914
|
-
logger.warn("[SSR] renderNodeSync type:", typeof type, type);
|
|
3915
|
-
} catch {
|
|
3916
|
-
}
|
|
3917
|
-
}
|
|
3918
3700
|
if (typeof type === "function") {
|
|
3919
3701
|
const result = executeComponentSync2(type, props, ctx);
|
|
3920
|
-
|
|
3921
|
-
|
|
3922
|
-
}
|
|
3923
|
-
return renderNodeSync(result, ctx);
|
|
3702
|
+
renderNodeSyncToSink(result, sink, ctx);
|
|
3703
|
+
return;
|
|
3924
3704
|
}
|
|
3925
3705
|
if (typeof type === "symbol") {
|
|
3926
3706
|
if (type === Fragment) {
|
|
3927
3707
|
const childrenArr = Array.isArray(node.children) ? node.children : Array.isArray(props?.children) ? props?.children : void 0;
|
|
3928
|
-
|
|
3929
|
-
|
|
3930
|
-
logger.warn("[SSR] fragment children length:", childrenArr?.length);
|
|
3931
|
-
} catch {
|
|
3932
|
-
}
|
|
3933
|
-
}
|
|
3934
|
-
return renderChildrenSync(childrenArr, ctx);
|
|
3708
|
+
renderChildrenSyncToSink(childrenArr, sink, ctx);
|
|
3709
|
+
return;
|
|
3935
3710
|
}
|
|
3936
3711
|
throw new Error(
|
|
3937
|
-
`
|
|
3712
|
+
`renderNodeSyncToSink: unsupported VNode symbol type: ${String(type)}`
|
|
3938
3713
|
);
|
|
3939
3714
|
}
|
|
3940
3715
|
const typeStr = type;
|
|
3941
3716
|
if (VOID_ELEMENTS.has(typeStr)) {
|
|
3942
|
-
const attrs2 = renderAttrs(props);
|
|
3943
|
-
|
|
3717
|
+
const attrs2 = props ? renderAttrs(props) : "";
|
|
3718
|
+
sink.write(`<${typeStr}${attrs2} />`);
|
|
3719
|
+
return;
|
|
3944
3720
|
}
|
|
3945
|
-
const
|
|
3946
|
-
|
|
3947
|
-
|
|
3948
|
-
|
|
3949
|
-
|
|
3721
|
+
const maybeDangerous = props ? props?.dangerouslySetInnerHTML : void 0;
|
|
3722
|
+
if (maybeDangerous !== void 0 && maybeDangerous !== null) {
|
|
3723
|
+
const { attrs: attrs2, dangerousHtml } = renderAttrs(props, {
|
|
3724
|
+
returnDangerousHtml: true
|
|
3725
|
+
});
|
|
3726
|
+
sink.write(`<${typeStr}${attrs2}>`);
|
|
3727
|
+
if (dangerousHtml !== void 0) {
|
|
3728
|
+
sink.write(dangerousHtml);
|
|
3729
|
+
} else {
|
|
3730
|
+
renderChildrenSyncToSink(node.children, sink, ctx);
|
|
3731
|
+
}
|
|
3732
|
+
sink.write(`</${typeStr}>`);
|
|
3733
|
+
return;
|
|
3950
3734
|
}
|
|
3735
|
+
const attrs = props ? renderAttrs(props) : "";
|
|
3951
3736
|
const children = node.children;
|
|
3952
|
-
|
|
3953
|
-
|
|
3737
|
+
if (Array.isArray(children) && children.length === 1) {
|
|
3738
|
+
const only = children[0];
|
|
3739
|
+
if (typeof only === "string") {
|
|
3740
|
+
sink.write(`<${typeStr}${attrs}>${escapeText(only)}</${typeStr}>`);
|
|
3741
|
+
return;
|
|
3742
|
+
}
|
|
3743
|
+
if (typeof only === "number") {
|
|
3744
|
+
const escaped = escapeText(String(only));
|
|
3745
|
+
sink.write(`<${typeStr}${attrs}>${escaped}</${typeStr}>`);
|
|
3746
|
+
return;
|
|
3747
|
+
}
|
|
3748
|
+
}
|
|
3749
|
+
sink.write(`<${typeStr}${attrs}>`);
|
|
3750
|
+
renderChildrenSyncToSink(children, sink, ctx);
|
|
3751
|
+
sink.write(`</${typeStr}>`);
|
|
3954
3752
|
}
|
|
3955
3753
|
function executeComponentSync2(component, props, ctx) {
|
|
3956
3754
|
try {
|
|
@@ -4019,9 +3817,11 @@ function renderToStringSync(component, props, options) {
|
|
|
4019
3817
|
if (!node) {
|
|
4020
3818
|
throw new Error("renderToStringSync: wrapped component returned empty");
|
|
4021
3819
|
}
|
|
4022
|
-
|
|
3820
|
+
const sink = new StringSink();
|
|
3821
|
+
renderNodeSyncToSink(node, sink, ctx);
|
|
3822
|
+
sink.end();
|
|
3823
|
+
return sink.toString();
|
|
4023
3824
|
} finally {
|
|
4024
|
-
stopRenderPhase();
|
|
4025
3825
|
}
|
|
4026
3826
|
}
|
|
4027
3827
|
function renderToStringSyncForUrl(opts) {
|
|
@@ -4068,9 +3868,11 @@ function renderToStringSyncForUrl(opts) {
|
|
|
4068
3868
|
};
|
|
4069
3869
|
};
|
|
4070
3870
|
const node = executeComponentSync2(wrapped, resolved.params || {}, ctx);
|
|
4071
|
-
|
|
3871
|
+
const sink = new StringSink();
|
|
3872
|
+
renderNodeSyncToSink(node, sink, ctx);
|
|
3873
|
+
sink.end();
|
|
3874
|
+
return sink.toString();
|
|
4072
3875
|
} finally {
|
|
4073
|
-
stopRenderPhase();
|
|
4074
3876
|
}
|
|
4075
3877
|
}
|
|
4076
3878
|
function renderToString(arg) {
|
|
@@ -4113,1079 +3915,12 @@ function renderToSinkInternal(opts) {
|
|
|
4113
3915
|
signal: void 0
|
|
4114
3916
|
};
|
|
4115
3917
|
const node = resolved.handler(resolved.params);
|
|
4116
|
-
startRenderPhase(data || null);
|
|
4117
3918
|
try {
|
|
4118
3919
|
renderNodeToSink(node, sink, ctx);
|
|
4119
3920
|
} finally {
|
|
4120
|
-
stopRenderPhase();
|
|
4121
|
-
}
|
|
4122
|
-
}
|
|
4123
|
-
var __ssrGuardStack;
|
|
4124
|
-
var init_ssr = __esm({
|
|
4125
|
-
"src/ssr/index.ts"() {
|
|
4126
|
-
"use strict";
|
|
4127
|
-
init_route();
|
|
4128
|
-
init_jsx();
|
|
4129
|
-
init_portal();
|
|
4130
|
-
init_context2();
|
|
4131
|
-
init_component();
|
|
4132
|
-
init_escape();
|
|
4133
|
-
init_attrs();
|
|
4134
|
-
init_logger();
|
|
4135
|
-
init_context2();
|
|
4136
|
-
init_sink();
|
|
4137
|
-
init_stream_render();
|
|
4138
|
-
init_render_keys();
|
|
4139
|
-
__ssrGuardStack = [];
|
|
4140
|
-
}
|
|
4141
|
-
});
|
|
4142
|
-
|
|
4143
|
-
// src/index.ts
|
|
4144
|
-
var index_exports = {};
|
|
4145
|
-
__export(index_exports, {
|
|
4146
|
-
DefaultPortal: () => DefaultPortal,
|
|
4147
|
-
Fragment: () => Fragment2,
|
|
4148
|
-
Link: () => Link,
|
|
4149
|
-
Slot: () => Slot,
|
|
4150
|
-
_resetDefaultPortal: () => _resetDefaultPortal,
|
|
4151
|
-
cleanupApp: () => cleanupApp,
|
|
4152
|
-
clearRoutes: () => clearRoutes,
|
|
4153
|
-
collectResources: () => collectResources,
|
|
4154
|
-
createIsland: () => createIsland,
|
|
4155
|
-
createSPA: () => createSPA,
|
|
4156
|
-
defineContext: () => defineContext,
|
|
4157
|
-
definePortal: () => definePortal,
|
|
4158
|
-
derive: () => derive,
|
|
4159
|
-
getLoadedNamespaces: () => getLoadedNamespaces,
|
|
4160
|
-
getNamespaceRoutes: () => getNamespaceRoutes,
|
|
4161
|
-
getRoutes: () => getRoutes,
|
|
4162
|
-
getSignal: () => getSignal,
|
|
4163
|
-
hasApp: () => hasApp,
|
|
4164
|
-
hydrateSPA: () => hydrateSPA,
|
|
4165
|
-
jsx: () => jsx,
|
|
4166
|
-
jsxs: () => jsxs,
|
|
4167
|
-
layout: () => layout,
|
|
4168
|
-
navigate: () => navigate,
|
|
4169
|
-
readContext: () => readContext,
|
|
4170
|
-
renderToStream: () => renderToStream,
|
|
4171
|
-
renderToString: () => renderToString,
|
|
4172
|
-
renderToStringSync: () => renderToStringSync,
|
|
4173
|
-
renderToStringSyncForUrl: () => renderToStringSyncForUrl,
|
|
4174
|
-
resolveResources: () => resolveResources,
|
|
4175
|
-
resource: () => resource,
|
|
4176
|
-
route: () => route,
|
|
4177
|
-
scheduleEventHandler: () => scheduleEventHandler,
|
|
4178
|
-
setServerLocation: () => setServerLocation,
|
|
4179
|
-
state: () => state,
|
|
4180
|
-
task: () => task,
|
|
4181
|
-
unloadNamespace: () => unloadNamespace
|
|
4182
|
-
});
|
|
4183
|
-
module.exports = __toCommonJS(index_exports);
|
|
4184
|
-
|
|
4185
|
-
// src/runtime/state.ts
|
|
4186
|
-
init_scheduler();
|
|
4187
|
-
init_component();
|
|
4188
|
-
init_invariant();
|
|
4189
|
-
init_fastlane_shared();
|
|
4190
|
-
function state(initialValue) {
|
|
4191
|
-
const instance = getCurrentInstance();
|
|
4192
|
-
if (!instance) {
|
|
4193
|
-
throw new Error(
|
|
4194
|
-
"state() can only be called during component render execution. Move state() calls to the top level of your component function."
|
|
4195
|
-
);
|
|
4196
|
-
}
|
|
4197
|
-
const index = getNextStateIndex();
|
|
4198
|
-
const stateValues = instance.stateValues;
|
|
4199
|
-
if (index < instance.stateIndexCheck) {
|
|
4200
|
-
throw new Error(
|
|
4201
|
-
`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.`
|
|
4202
|
-
);
|
|
4203
|
-
}
|
|
4204
|
-
invariant(
|
|
4205
|
-
index >= instance.stateIndexCheck,
|
|
4206
|
-
"[State] State indices must increase monotonically"
|
|
4207
|
-
);
|
|
4208
|
-
instance.stateIndexCheck = index;
|
|
4209
|
-
if (instance.firstRenderComplete) {
|
|
4210
|
-
if (!instance.expectedStateIndices.includes(index)) {
|
|
4211
|
-
throw new Error(
|
|
4212
|
-
`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.`
|
|
4213
|
-
);
|
|
4214
|
-
}
|
|
4215
|
-
} else {
|
|
4216
|
-
instance.expectedStateIndices.push(index);
|
|
4217
|
-
}
|
|
4218
|
-
if (stateValues[index]) {
|
|
4219
|
-
const existing = stateValues[index];
|
|
4220
|
-
if (existing._owner !== instance) {
|
|
4221
|
-
throw new Error(
|
|
4222
|
-
`State ownership violation: state() called at index ${index} is owned by a different component instance. State ownership is positional and immutable.`
|
|
4223
|
-
);
|
|
4224
|
-
}
|
|
4225
|
-
return existing;
|
|
4226
|
-
}
|
|
4227
|
-
const cell = createStateCell(initialValue, instance);
|
|
4228
|
-
stateValues[index] = cell;
|
|
4229
|
-
return cell;
|
|
4230
|
-
}
|
|
4231
|
-
function createStateCell(initialValue, instance) {
|
|
4232
|
-
let value = initialValue;
|
|
4233
|
-
const readers = /* @__PURE__ */ new Map();
|
|
4234
|
-
function read() {
|
|
4235
|
-
read._hasBeenRead = true;
|
|
4236
|
-
const inst = getCurrentInstance();
|
|
4237
|
-
if (inst && inst._currentRenderToken !== void 0) {
|
|
4238
|
-
if (!inst._pendingReadStates) inst._pendingReadStates = /* @__PURE__ */ new Set();
|
|
4239
|
-
inst._pendingReadStates.add(read);
|
|
4240
|
-
}
|
|
4241
|
-
return value;
|
|
4242
|
-
}
|
|
4243
|
-
read._readers = readers;
|
|
4244
|
-
read._owner = instance;
|
|
4245
|
-
read.set = (newValueOrUpdater) => {
|
|
4246
|
-
const currentInst = getCurrentInstance();
|
|
4247
|
-
if (currentInst !== null && process.env.NODE_ENV !== "production") {
|
|
4248
|
-
throw new Error(
|
|
4249
|
-
`[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.`
|
|
4250
|
-
);
|
|
4251
|
-
}
|
|
4252
|
-
if (currentInst !== null && process.env.NODE_ENV === "production") {
|
|
4253
|
-
if (typeof console !== "undefined" && console.warn) {
|
|
4254
|
-
console.warn(
|
|
4255
|
-
"[Askr] state.set() called during render - update skipped. Move state updates to event handlers."
|
|
4256
|
-
);
|
|
4257
|
-
}
|
|
4258
|
-
return;
|
|
4259
|
-
}
|
|
4260
|
-
let newValue;
|
|
4261
|
-
if (typeof newValueOrUpdater === "function") {
|
|
4262
|
-
const updater = newValueOrUpdater;
|
|
4263
|
-
newValue = updater(value);
|
|
4264
|
-
} else {
|
|
4265
|
-
newValue = newValueOrUpdater;
|
|
4266
|
-
}
|
|
4267
|
-
if (Object.is(value, newValue)) return;
|
|
4268
|
-
if (isBulkCommitActive2()) {
|
|
4269
|
-
value = newValue;
|
|
4270
|
-
return;
|
|
4271
|
-
}
|
|
4272
|
-
value = newValue;
|
|
4273
|
-
const readersMap = read._readers;
|
|
4274
|
-
if (readersMap) {
|
|
4275
|
-
for (const [subInst, token] of readersMap) {
|
|
4276
|
-
if (subInst.lastRenderToken !== token) continue;
|
|
4277
|
-
if (!subInst.hasPendingUpdate) {
|
|
4278
|
-
subInst.hasPendingUpdate = true;
|
|
4279
|
-
const subTask = subInst._pendingFlushTask;
|
|
4280
|
-
if (subTask) globalScheduler.enqueue(subTask);
|
|
4281
|
-
else
|
|
4282
|
-
globalScheduler.enqueue(() => {
|
|
4283
|
-
subInst.hasPendingUpdate = false;
|
|
4284
|
-
subInst.notifyUpdate?.();
|
|
4285
|
-
});
|
|
4286
|
-
}
|
|
4287
|
-
}
|
|
4288
|
-
}
|
|
4289
|
-
const readersMapForOwner = readersMap;
|
|
4290
|
-
const ownerRecordedToken = readersMapForOwner?.get(instance);
|
|
4291
|
-
const ownerShouldEnqueue = (
|
|
4292
|
-
// Normal case: owner read this state in last committed render
|
|
4293
|
-
ownerRecordedToken !== void 0 && instance.lastRenderToken === ownerRecordedToken
|
|
4294
|
-
);
|
|
4295
|
-
if (ownerShouldEnqueue && !instance.hasPendingUpdate) {
|
|
4296
|
-
instance.hasPendingUpdate = true;
|
|
4297
|
-
const task2 = instance._pendingFlushTask;
|
|
4298
|
-
if (task2) globalScheduler.enqueue(task2);
|
|
4299
|
-
else
|
|
4300
|
-
globalScheduler.enqueue(() => {
|
|
4301
|
-
instance.hasPendingUpdate = false;
|
|
4302
|
-
instance.notifyUpdate?.();
|
|
4303
|
-
});
|
|
4304
|
-
}
|
|
4305
|
-
};
|
|
4306
|
-
return read;
|
|
4307
|
-
}
|
|
4308
|
-
|
|
4309
|
-
// src/index.ts
|
|
4310
|
-
init_component();
|
|
4311
|
-
init_scheduler();
|
|
4312
|
-
init_context();
|
|
4313
|
-
|
|
4314
|
-
// src/runtime/operations.ts
|
|
4315
|
-
init_component();
|
|
4316
|
-
init_context();
|
|
4317
|
-
|
|
4318
|
-
// src/runtime/resource-cell.ts
|
|
4319
|
-
init_context();
|
|
4320
|
-
init_logger();
|
|
4321
|
-
init_context2();
|
|
4322
|
-
var ResourceCell = class {
|
|
4323
|
-
constructor(fn, deps, resourceFrame) {
|
|
4324
|
-
this.value = null;
|
|
4325
|
-
this.pending = true;
|
|
4326
|
-
this.error = null;
|
|
4327
|
-
this.generation = 0;
|
|
4328
|
-
this.controller = null;
|
|
4329
|
-
this.deps = null;
|
|
4330
|
-
this.resourceFrame = null;
|
|
4331
|
-
this.subscribers = /* @__PURE__ */ new Set();
|
|
4332
|
-
this.fn = fn;
|
|
4333
|
-
this.deps = deps ? deps.slice() : null;
|
|
4334
|
-
this.resourceFrame = resourceFrame;
|
|
4335
|
-
this.snapshot = {
|
|
4336
|
-
value: null,
|
|
4337
|
-
pending: true,
|
|
4338
|
-
error: null,
|
|
4339
|
-
refresh: () => this.refresh()
|
|
4340
|
-
};
|
|
4341
|
-
}
|
|
4342
|
-
subscribe(cb) {
|
|
4343
|
-
this.subscribers.add(cb);
|
|
4344
|
-
return () => this.subscribers.delete(cb);
|
|
4345
|
-
}
|
|
4346
|
-
notifySubscribers() {
|
|
4347
|
-
this.snapshot.value = this.value;
|
|
4348
|
-
this.snapshot.pending = this.pending;
|
|
4349
|
-
this.snapshot.error = this.error;
|
|
4350
|
-
for (const cb of this.subscribers) cb();
|
|
4351
|
-
}
|
|
4352
|
-
start(ssr = false, notify = true) {
|
|
4353
|
-
const generation = this.generation;
|
|
4354
|
-
this.controller?.abort();
|
|
4355
|
-
const controller = new AbortController();
|
|
4356
|
-
this.controller = controller;
|
|
4357
|
-
this.pending = true;
|
|
4358
|
-
this.error = null;
|
|
4359
|
-
if (notify) this.notifySubscribers();
|
|
4360
|
-
let result;
|
|
4361
|
-
try {
|
|
4362
|
-
result = withAsyncResourceContext(
|
|
4363
|
-
this.resourceFrame,
|
|
4364
|
-
() => this.fn({ signal: controller.signal })
|
|
4365
|
-
);
|
|
4366
|
-
} catch (err) {
|
|
4367
|
-
this.pending = false;
|
|
4368
|
-
this.error = err;
|
|
4369
|
-
if (notify) this.notifySubscribers();
|
|
4370
|
-
return;
|
|
4371
|
-
}
|
|
4372
|
-
if (!(result instanceof Promise)) {
|
|
4373
|
-
this.value = result;
|
|
4374
|
-
this.pending = false;
|
|
4375
|
-
this.error = null;
|
|
4376
|
-
if (notify) this.notifySubscribers();
|
|
4377
|
-
return;
|
|
4378
|
-
}
|
|
4379
|
-
if (ssr) {
|
|
4380
|
-
throwSSRDataMissing();
|
|
4381
|
-
}
|
|
4382
|
-
result.then((val) => {
|
|
4383
|
-
if (this.generation !== generation) return;
|
|
4384
|
-
if (this.controller !== controller) return;
|
|
4385
|
-
this.value = val;
|
|
4386
|
-
this.pending = false;
|
|
4387
|
-
this.error = null;
|
|
4388
|
-
this.notifySubscribers();
|
|
4389
|
-
}).catch((err) => {
|
|
4390
|
-
if (this.generation !== generation) return;
|
|
4391
|
-
this.pending = false;
|
|
4392
|
-
this.error = err;
|
|
4393
|
-
try {
|
|
4394
|
-
if (this.ownerName) {
|
|
4395
|
-
logger.error(
|
|
4396
|
-
`[Askr] Async resource error in ${this.ownerName}:`,
|
|
4397
|
-
err
|
|
4398
|
-
);
|
|
4399
|
-
} else {
|
|
4400
|
-
logger.error("[Askr] Async resource error:", err);
|
|
4401
|
-
}
|
|
4402
|
-
} catch {
|
|
4403
|
-
}
|
|
4404
|
-
this.notifySubscribers();
|
|
4405
|
-
});
|
|
4406
|
-
}
|
|
4407
|
-
refresh() {
|
|
4408
|
-
this.generation++;
|
|
4409
|
-
this.controller?.abort();
|
|
4410
|
-
this.start();
|
|
4411
|
-
}
|
|
4412
|
-
abort() {
|
|
4413
|
-
this.controller?.abort();
|
|
4414
|
-
}
|
|
4415
|
-
};
|
|
4416
|
-
|
|
4417
|
-
// src/shared/derive-cache.ts
|
|
4418
|
-
var deriveCacheMap = /* @__PURE__ */ new WeakMap();
|
|
4419
|
-
function getDeriveCache(instance) {
|
|
4420
|
-
let cache = deriveCacheMap.get(instance);
|
|
4421
|
-
if (!cache) {
|
|
4422
|
-
cache = /* @__PURE__ */ new Map();
|
|
4423
|
-
deriveCacheMap.set(instance, cache);
|
|
4424
|
-
}
|
|
4425
|
-
return cache;
|
|
4426
|
-
}
|
|
4427
|
-
|
|
4428
|
-
// src/runtime/operations.ts
|
|
4429
|
-
init_context2();
|
|
4430
|
-
init_render_keys();
|
|
4431
|
-
function resource(fn, deps = []) {
|
|
4432
|
-
const instance = getCurrentComponentInstance();
|
|
4433
|
-
const inst = instance;
|
|
4434
|
-
if (!instance) {
|
|
4435
|
-
const renderData2 = getCurrentRenderData();
|
|
4436
|
-
if (renderData2) {
|
|
4437
|
-
const key = getNextKey();
|
|
4438
|
-
if (!(key in renderData2)) {
|
|
4439
|
-
throwSSRDataMissing();
|
|
4440
|
-
}
|
|
4441
|
-
const val = renderData2[key];
|
|
4442
|
-
return {
|
|
4443
|
-
value: val,
|
|
4444
|
-
pending: false,
|
|
4445
|
-
error: null,
|
|
4446
|
-
refresh: () => {
|
|
4447
|
-
}
|
|
4448
|
-
};
|
|
4449
|
-
}
|
|
4450
|
-
const ssrCtx = getCurrentSSRContext();
|
|
4451
|
-
if (ssrCtx) {
|
|
4452
|
-
throwSSRDataMissing();
|
|
4453
|
-
}
|
|
4454
|
-
return {
|
|
4455
|
-
value: null,
|
|
4456
|
-
pending: true,
|
|
4457
|
-
error: null,
|
|
4458
|
-
refresh: () => {
|
|
4459
|
-
}
|
|
4460
|
-
};
|
|
4461
|
-
}
|
|
4462
|
-
const renderData = getCurrentRenderData();
|
|
4463
|
-
if (renderData) {
|
|
4464
|
-
const key = getNextKey();
|
|
4465
|
-
if (!(key in renderData)) {
|
|
4466
|
-
throwSSRDataMissing();
|
|
4467
|
-
}
|
|
4468
|
-
const val = renderData[key];
|
|
4469
|
-
const holder2 = state({
|
|
4470
|
-
cell: void 0,
|
|
4471
|
-
snapshot: {
|
|
4472
|
-
value: val,
|
|
4473
|
-
pending: false,
|
|
4474
|
-
error: null,
|
|
4475
|
-
refresh: () => {
|
|
4476
|
-
}
|
|
4477
|
-
}
|
|
4478
|
-
});
|
|
4479
|
-
const h2 = holder2();
|
|
4480
|
-
h2.snapshot.value = val;
|
|
4481
|
-
h2.snapshot.pending = false;
|
|
4482
|
-
h2.snapshot.error = null;
|
|
4483
|
-
holder2.set(h2);
|
|
4484
|
-
return h2.snapshot;
|
|
4485
|
-
}
|
|
4486
|
-
const holder = state({
|
|
4487
|
-
cell: void 0,
|
|
4488
|
-
snapshot: {
|
|
4489
|
-
value: null,
|
|
4490
|
-
pending: true,
|
|
4491
|
-
error: null,
|
|
4492
|
-
refresh: () => {
|
|
4493
|
-
}
|
|
4494
|
-
}
|
|
4495
|
-
});
|
|
4496
|
-
const h = holder();
|
|
4497
|
-
if (!h.cell) {
|
|
4498
|
-
const frame = getCurrentContextFrame();
|
|
4499
|
-
const cell2 = new ResourceCell(fn, deps, frame);
|
|
4500
|
-
cell2.ownerName = inst.fn?.name || "<anonymous>";
|
|
4501
|
-
h.cell = cell2;
|
|
4502
|
-
h.snapshot = cell2.snapshot;
|
|
4503
|
-
const unsubscribe = cell2.subscribe(() => {
|
|
4504
|
-
const cur = holder();
|
|
4505
|
-
cur.snapshot.value = cell2.snapshot.value;
|
|
4506
|
-
cur.snapshot.pending = cell2.snapshot.pending;
|
|
4507
|
-
cur.snapshot.error = cell2.snapshot.error;
|
|
4508
|
-
holder.set(cur);
|
|
4509
|
-
try {
|
|
4510
|
-
inst._enqueueRun?.();
|
|
4511
|
-
} catch {
|
|
4512
|
-
}
|
|
4513
|
-
});
|
|
4514
|
-
inst.cleanupFns.push(() => {
|
|
4515
|
-
unsubscribe();
|
|
4516
|
-
cell2.abort();
|
|
4517
|
-
});
|
|
4518
|
-
try {
|
|
4519
|
-
cell2.start(inst.ssr ?? false, false);
|
|
4520
|
-
if (!cell2.pending) {
|
|
4521
|
-
const cur = holder();
|
|
4522
|
-
cur.snapshot.value = cell2.value;
|
|
4523
|
-
cur.snapshot.pending = cell2.pending;
|
|
4524
|
-
cur.snapshot.error = cell2.error;
|
|
4525
|
-
}
|
|
4526
|
-
} catch (err) {
|
|
4527
|
-
if (err instanceof SSRDataMissingError) throw err;
|
|
4528
|
-
cell2.error = err;
|
|
4529
|
-
cell2.pending = false;
|
|
4530
|
-
const cur = holder();
|
|
4531
|
-
cur.snapshot.value = cell2.value;
|
|
4532
|
-
cur.snapshot.pending = cell2.pending;
|
|
4533
|
-
cur.snapshot.error = cell2.error;
|
|
4534
|
-
}
|
|
4535
|
-
}
|
|
4536
|
-
const cell = h.cell;
|
|
4537
|
-
const depsChanged = !cell.deps || cell.deps.length !== deps.length || cell.deps.some((d, i) => d !== deps[i]);
|
|
4538
|
-
if (depsChanged) {
|
|
4539
|
-
cell.deps = deps.slice();
|
|
4540
|
-
cell.generation++;
|
|
4541
|
-
cell.pending = true;
|
|
4542
|
-
cell.error = null;
|
|
4543
|
-
try {
|
|
4544
|
-
cell.start(inst.ssr ?? false, false);
|
|
4545
|
-
if (!cell.pending) {
|
|
4546
|
-
const cur = holder();
|
|
4547
|
-
cur.snapshot.value = cell.value;
|
|
4548
|
-
cur.snapshot.pending = cell.pending;
|
|
4549
|
-
cur.snapshot.error = cell.error;
|
|
4550
|
-
}
|
|
4551
|
-
} catch (err) {
|
|
4552
|
-
if (err instanceof SSRDataMissingError) throw err;
|
|
4553
|
-
cell.error = err;
|
|
4554
|
-
cell.pending = false;
|
|
4555
|
-
const cur = holder();
|
|
4556
|
-
cur.snapshot.value = cell.value;
|
|
4557
|
-
cur.snapshot.pending = cell.pending;
|
|
4558
|
-
cur.snapshot.error = cell.error;
|
|
4559
|
-
}
|
|
4560
|
-
}
|
|
4561
|
-
return h.snapshot;
|
|
4562
|
-
}
|
|
4563
|
-
function derive(source, map) {
|
|
4564
|
-
if (map === void 0 && typeof source === "function") {
|
|
4565
|
-
const value2 = source();
|
|
4566
|
-
if (value2 == null) return null;
|
|
4567
|
-
const instance2 = getCurrentComponentInstance();
|
|
4568
|
-
if (!instance2) {
|
|
4569
|
-
return value2;
|
|
4570
|
-
}
|
|
4571
|
-
const cache2 = getDeriveCache(instance2);
|
|
4572
|
-
if (cache2.has(value2)) return cache2.get(value2);
|
|
4573
|
-
cache2.set(value2, value2);
|
|
4574
|
-
return value2;
|
|
4575
|
-
}
|
|
4576
|
-
let value;
|
|
4577
|
-
if (typeof source === "function" && !("value" in source)) {
|
|
4578
|
-
value = source();
|
|
4579
|
-
} else {
|
|
4580
|
-
value = source?.value ?? source;
|
|
4581
3921
|
}
|
|
4582
|
-
if (value == null) return null;
|
|
4583
|
-
const instance = getCurrentComponentInstance();
|
|
4584
|
-
if (!instance) {
|
|
4585
|
-
return map(value);
|
|
4586
|
-
}
|
|
4587
|
-
const cache = getDeriveCache(instance);
|
|
4588
|
-
if (cache.has(value)) {
|
|
4589
|
-
return cache.get(value);
|
|
4590
|
-
}
|
|
4591
|
-
const result = map(value);
|
|
4592
|
-
cache.set(value, result);
|
|
4593
|
-
return result;
|
|
4594
|
-
}
|
|
4595
|
-
function task(fn) {
|
|
4596
|
-
const ownerIsRoot = getCurrentComponentInstance()?.isRoot ?? false;
|
|
4597
|
-
registerMountOperation(async () => {
|
|
4598
|
-
if (!ownerIsRoot) {
|
|
4599
|
-
throw new Error("[Askr] task() may only be used in root components");
|
|
4600
|
-
}
|
|
4601
|
-
return await fn();
|
|
4602
|
-
});
|
|
4603
3922
|
}
|
|
4604
3923
|
|
|
4605
|
-
|
|
4606
|
-
|
|
4607
|
-
|
|
4608
|
-
init_logger();
|
|
4609
|
-
init_navigate();
|
|
4610
|
-
init_jsx();
|
|
4611
|
-
init_portal();
|
|
4612
|
-
init_renderer();
|
|
4613
|
-
var componentIdCounter = 0;
|
|
4614
|
-
var instancesByRoot = /* @__PURE__ */ new WeakMap();
|
|
4615
|
-
var CLEANUP_SYMBOL = /* @__PURE__ */ Symbol.for("__tempoCleanup__");
|
|
4616
|
-
function attachCleanupForRoot(rootElement, instance) {
|
|
4617
|
-
rootElement[CLEANUP_SYMBOL] = () => {
|
|
4618
|
-
const errors = [];
|
|
4619
|
-
try {
|
|
4620
|
-
removeAllListeners(rootElement);
|
|
4621
|
-
} catch (e) {
|
|
4622
|
-
errors.push(e);
|
|
4623
|
-
}
|
|
4624
|
-
try {
|
|
4625
|
-
const descendants = rootElement.querySelectorAll("*");
|
|
4626
|
-
for (const d of Array.from(descendants)) {
|
|
4627
|
-
try {
|
|
4628
|
-
const inst = d.__ASKR_INSTANCE;
|
|
4629
|
-
if (inst) {
|
|
4630
|
-
try {
|
|
4631
|
-
cleanupComponent(inst);
|
|
4632
|
-
} catch (err) {
|
|
4633
|
-
errors.push(err);
|
|
4634
|
-
}
|
|
4635
|
-
try {
|
|
4636
|
-
delete d.__ASKR_INSTANCE;
|
|
4637
|
-
} catch (err) {
|
|
4638
|
-
errors.push(err);
|
|
4639
|
-
}
|
|
4640
|
-
}
|
|
4641
|
-
} catch (err) {
|
|
4642
|
-
errors.push(err);
|
|
4643
|
-
}
|
|
4644
|
-
}
|
|
4645
|
-
} catch (e) {
|
|
4646
|
-
errors.push(e);
|
|
4647
|
-
}
|
|
4648
|
-
try {
|
|
4649
|
-
cleanupComponent(instance);
|
|
4650
|
-
} catch (e) {
|
|
4651
|
-
errors.push(e);
|
|
4652
|
-
}
|
|
4653
|
-
if (errors.length > 0) {
|
|
4654
|
-
if (instance.cleanupStrict) {
|
|
4655
|
-
throw new AggregateError(errors, `cleanup failed for app root`);
|
|
4656
|
-
} else if (process.env.NODE_ENV !== "production") {
|
|
4657
|
-
for (const err of errors) logger.warn("[Askr] cleanup error:", err);
|
|
4658
|
-
}
|
|
4659
|
-
}
|
|
4660
|
-
};
|
|
4661
|
-
try {
|
|
4662
|
-
const descriptor = Object.getOwnPropertyDescriptor(rootElement, "innerHTML") || Object.getOwnPropertyDescriptor(
|
|
4663
|
-
Object.getPrototypeOf(rootElement),
|
|
4664
|
-
"innerHTML"
|
|
4665
|
-
) || Object.getOwnPropertyDescriptor(Element.prototype, "innerHTML");
|
|
4666
|
-
if (descriptor && (descriptor.get || descriptor.set)) {
|
|
4667
|
-
Object.defineProperty(rootElement, "innerHTML", {
|
|
4668
|
-
get: descriptor.get ? function() {
|
|
4669
|
-
return descriptor.get.call(this);
|
|
4670
|
-
} : void 0,
|
|
4671
|
-
set: function(value) {
|
|
4672
|
-
if (value === "" && instancesByRoot.get(this) === instance) {
|
|
4673
|
-
try {
|
|
4674
|
-
removeAllListeners(rootElement);
|
|
4675
|
-
} catch (e) {
|
|
4676
|
-
if (instance.cleanupStrict) throw e;
|
|
4677
|
-
if (process.env.NODE_ENV !== "production")
|
|
4678
|
-
logger.warn("[Askr] cleanup error:", e);
|
|
4679
|
-
}
|
|
4680
|
-
try {
|
|
4681
|
-
cleanupComponent(instance);
|
|
4682
|
-
} catch (e) {
|
|
4683
|
-
if (instance.cleanupStrict) throw e;
|
|
4684
|
-
if (process.env.NODE_ENV !== "production")
|
|
4685
|
-
logger.warn("[Askr] cleanup error:", e);
|
|
4686
|
-
}
|
|
4687
|
-
}
|
|
4688
|
-
if (descriptor.set) {
|
|
4689
|
-
return descriptor.set.call(this, value);
|
|
4690
|
-
}
|
|
4691
|
-
},
|
|
4692
|
-
configurable: true
|
|
4693
|
-
});
|
|
4694
|
-
}
|
|
4695
|
-
} catch {
|
|
4696
|
-
}
|
|
4697
|
-
}
|
|
4698
|
-
function mountOrUpdate(rootElement, componentFn, options) {
|
|
4699
|
-
const wrappedFn = (props, ctx) => {
|
|
4700
|
-
const out = componentFn(props, ctx);
|
|
4701
|
-
const portalVNode = {
|
|
4702
|
-
$$typeof: ELEMENT_TYPE,
|
|
4703
|
-
type: DefaultPortal,
|
|
4704
|
-
props: {},
|
|
4705
|
-
key: "__default_portal"
|
|
4706
|
-
};
|
|
4707
|
-
return {
|
|
4708
|
-
$$typeof: ELEMENT_TYPE,
|
|
4709
|
-
type: Fragment,
|
|
4710
|
-
props: {
|
|
4711
|
-
children: out === void 0 || out === null ? [portalVNode] : [out, portalVNode]
|
|
4712
|
-
}
|
|
4713
|
-
};
|
|
4714
|
-
};
|
|
4715
|
-
Object.defineProperty(wrappedFn, "name", {
|
|
4716
|
-
value: componentFn.name || "Component"
|
|
4717
|
-
});
|
|
4718
|
-
const existingCleanup = rootElement[CLEANUP_SYMBOL];
|
|
4719
|
-
if (existingCleanup) existingCleanup();
|
|
4720
|
-
let instance = instancesByRoot.get(rootElement);
|
|
4721
|
-
if (instance) {
|
|
4722
|
-
removeAllListeners(rootElement);
|
|
4723
|
-
try {
|
|
4724
|
-
cleanupComponent(instance);
|
|
4725
|
-
} catch (e) {
|
|
4726
|
-
if (process.env.NODE_ENV !== "production")
|
|
4727
|
-
logger.warn("[Askr] prior cleanup threw:", e);
|
|
4728
|
-
}
|
|
4729
|
-
instance.fn = wrappedFn;
|
|
4730
|
-
instance.evaluationGeneration++;
|
|
4731
|
-
instance.mounted = false;
|
|
4732
|
-
instance.expectedStateIndices = [];
|
|
4733
|
-
instance.firstRenderComplete = false;
|
|
4734
|
-
instance.isRoot = true;
|
|
4735
|
-
if (options && typeof options.cleanupStrict === "boolean") {
|
|
4736
|
-
instance.cleanupStrict = options.cleanupStrict;
|
|
4737
|
-
}
|
|
4738
|
-
} else {
|
|
4739
|
-
const componentId = String(++componentIdCounter);
|
|
4740
|
-
instance = createComponentInstance(componentId, wrappedFn, {}, rootElement);
|
|
4741
|
-
instancesByRoot.set(rootElement, instance);
|
|
4742
|
-
instance.isRoot = true;
|
|
4743
|
-
if (options && typeof options.cleanupStrict === "boolean") {
|
|
4744
|
-
instance.cleanupStrict = options.cleanupStrict;
|
|
4745
|
-
}
|
|
4746
|
-
}
|
|
4747
|
-
attachCleanupForRoot(rootElement, instance);
|
|
4748
|
-
mountComponent(instance);
|
|
4749
|
-
globalScheduler.flush();
|
|
4750
|
-
}
|
|
4751
|
-
function createIsland(config) {
|
|
4752
|
-
if (!config || typeof config !== "object") {
|
|
4753
|
-
throw new Error("createIsland requires a config object");
|
|
4754
|
-
}
|
|
4755
|
-
if (typeof config.component !== "function") {
|
|
4756
|
-
throw new Error("createIsland: component must be a function");
|
|
4757
|
-
}
|
|
4758
|
-
const rootElement = typeof config.root === "string" ? document.getElementById(config.root) : config.root;
|
|
4759
|
-
if (!rootElement) throw new Error(`Root element not found: ${config.root}`);
|
|
4760
|
-
if ("routes" in config) {
|
|
4761
|
-
throw new Error(
|
|
4762
|
-
"createIsland does not accept routes; use createSPA for routed apps"
|
|
4763
|
-
);
|
|
4764
|
-
}
|
|
4765
|
-
mountOrUpdate(rootElement, config.component, {
|
|
4766
|
-
cleanupStrict: config.cleanupStrict
|
|
4767
|
-
});
|
|
4768
|
-
}
|
|
4769
|
-
async function createSPA(config) {
|
|
4770
|
-
if (!config || typeof config !== "object") {
|
|
4771
|
-
throw new Error("createSPA requires a config object");
|
|
4772
|
-
}
|
|
4773
|
-
if (!Array.isArray(config.routes) || config.routes.length === 0) {
|
|
4774
|
-
throw new Error(
|
|
4775
|
-
"createSPA requires a route table. If you are enhancing existing HTML, use createIsland instead."
|
|
4776
|
-
);
|
|
4777
|
-
}
|
|
4778
|
-
const rootElement = typeof config.root === "string" ? document.getElementById(config.root) : config.root;
|
|
4779
|
-
if (!rootElement) throw new Error(`Root element not found: ${config.root}`);
|
|
4780
|
-
const { clearRoutes: clearRoutes2, route: route2, lockRouteRegistration: lockRouteRegistration2, resolveRoute: resolveRoute2 } = await Promise.resolve().then(() => (init_route(), route_exports));
|
|
4781
|
-
clearRoutes2();
|
|
4782
|
-
for (const r of config.routes) {
|
|
4783
|
-
route2(r.path, r.handler, r.namespace);
|
|
4784
|
-
}
|
|
4785
|
-
if (process.env.NODE_ENV === "production") lockRouteRegistration2();
|
|
4786
|
-
const path = typeof window !== "undefined" ? window.location.pathname : "/";
|
|
4787
|
-
const resolved = resolveRoute2(path);
|
|
4788
|
-
if (!resolved) {
|
|
4789
|
-
if (process.env.NODE_ENV !== "production") {
|
|
4790
|
-
logger.warn(
|
|
4791
|
-
`createSPA: no route found for current path (${path}). Mounting empty placeholder; navigation will activate routes when requested.`
|
|
4792
|
-
);
|
|
4793
|
-
}
|
|
4794
|
-
mountOrUpdate(rootElement, () => ({ type: "div", children: [] }), {
|
|
4795
|
-
cleanupStrict: false
|
|
4796
|
-
});
|
|
4797
|
-
const instance2 = instancesByRoot.get(rootElement);
|
|
4798
|
-
if (!instance2) throw new Error("Internal error: app instance missing");
|
|
4799
|
-
registerAppInstance(instance2, path);
|
|
4800
|
-
initializeNavigation();
|
|
4801
|
-
return;
|
|
4802
|
-
}
|
|
4803
|
-
mountOrUpdate(rootElement, resolved.handler, {
|
|
4804
|
-
cleanupStrict: false
|
|
4805
|
-
});
|
|
4806
|
-
const instance = instancesByRoot.get(rootElement);
|
|
4807
|
-
if (!instance) throw new Error("Internal error: app instance missing");
|
|
4808
|
-
registerAppInstance(instance, path);
|
|
4809
|
-
initializeNavigation();
|
|
4810
|
-
}
|
|
4811
|
-
async function hydrateSPA(config) {
|
|
4812
|
-
if (!config || typeof config !== "object") {
|
|
4813
|
-
throw new Error("hydrateSPA requires a config object");
|
|
4814
|
-
}
|
|
4815
|
-
if (!Array.isArray(config.routes) || config.routes.length === 0) {
|
|
4816
|
-
throw new Error(
|
|
4817
|
-
"hydrateSPA requires a route table. If you are enhancing existing HTML, use createIsland instead."
|
|
4818
|
-
);
|
|
4819
|
-
}
|
|
4820
|
-
const rootElement = typeof config.root === "string" ? document.getElementById(config.root) : config.root;
|
|
4821
|
-
if (!rootElement) throw new Error(`Root element not found: ${config.root}`);
|
|
4822
|
-
const serverHTML = rootElement.innerHTML;
|
|
4823
|
-
const {
|
|
4824
|
-
clearRoutes: clearRoutes2,
|
|
4825
|
-
route: route2,
|
|
4826
|
-
setServerLocation: setServerLocation2,
|
|
4827
|
-
lockRouteRegistration: lockRouteRegistration2,
|
|
4828
|
-
resolveRoute: resolveRoute2
|
|
4829
|
-
} = await Promise.resolve().then(() => (init_route(), route_exports));
|
|
4830
|
-
clearRoutes2();
|
|
4831
|
-
for (const r of config.routes) {
|
|
4832
|
-
route2(r.path, r.handler, r.namespace);
|
|
4833
|
-
}
|
|
4834
|
-
const path = typeof window !== "undefined" ? window.location.pathname : "/";
|
|
4835
|
-
setServerLocation2(path);
|
|
4836
|
-
if (process.env.NODE_ENV === "production") lockRouteRegistration2();
|
|
4837
|
-
const resolved = resolveRoute2(path);
|
|
4838
|
-
if (!resolved) {
|
|
4839
|
-
throw new Error(`hydrateSPA: no route found for current path (${path}).`);
|
|
4840
|
-
}
|
|
4841
|
-
const { renderToStringSync: renderToStringSync2 } = await Promise.resolve().then(() => (init_ssr(), ssr_exports));
|
|
4842
|
-
const expectedHTML = renderToStringSync2(() => {
|
|
4843
|
-
const out = resolved.handler(resolved.params);
|
|
4844
|
-
return out ?? {
|
|
4845
|
-
type: "div",
|
|
4846
|
-
children: []
|
|
4847
|
-
};
|
|
4848
|
-
});
|
|
4849
|
-
const serverContainer = document.createElement("div");
|
|
4850
|
-
serverContainer.innerHTML = serverHTML;
|
|
4851
|
-
const expectedContainer = document.createElement("div");
|
|
4852
|
-
expectedContainer.innerHTML = expectedHTML;
|
|
4853
|
-
if (!serverContainer.isEqualNode(expectedContainer)) {
|
|
4854
|
-
throw new Error(
|
|
4855
|
-
"[Askr] Hydration mismatch detected. Server HTML does not match expected server-render output."
|
|
4856
|
-
);
|
|
4857
|
-
}
|
|
4858
|
-
mountOrUpdate(rootElement, resolved.handler, {
|
|
4859
|
-
cleanupStrict: false
|
|
4860
|
-
});
|
|
4861
|
-
const { registerAppInstance: registerAppInstance2, initializeNavigation: initializeNavigation2 } = await Promise.resolve().then(() => (init_navigate(), navigate_exports));
|
|
4862
|
-
const instance = instancesByRoot.get(rootElement);
|
|
4863
|
-
if (!instance) throw new Error("Internal error: app instance missing");
|
|
4864
|
-
registerAppInstance2(instance, path);
|
|
4865
|
-
initializeNavigation2();
|
|
4866
|
-
}
|
|
4867
|
-
function cleanupApp(root) {
|
|
4868
|
-
const rootElement = typeof root === "string" ? document.getElementById(root) : root;
|
|
4869
|
-
if (!rootElement) return;
|
|
4870
|
-
const cleanupFn = rootElement[CLEANUP_SYMBOL];
|
|
4871
|
-
if (typeof cleanupFn === "function") {
|
|
4872
|
-
cleanupFn();
|
|
4873
|
-
}
|
|
4874
|
-
instancesByRoot.delete(rootElement);
|
|
4875
|
-
}
|
|
4876
|
-
function hasApp(root) {
|
|
4877
|
-
const rootElement = typeof root === "string" ? document.getElementById(root) : root;
|
|
4878
|
-
if (!rootElement) return false;
|
|
4879
|
-
return instancesByRoot.has(rootElement);
|
|
4880
|
-
}
|
|
4881
|
-
|
|
4882
|
-
// src/index.ts
|
|
4883
|
-
init_route();
|
|
4884
|
-
init_route();
|
|
4885
|
-
init_navigate();
|
|
4886
|
-
|
|
4887
|
-
// src/components/Link.tsx
|
|
4888
|
-
init_navigate();
|
|
4889
|
-
function Link({ href, children }) {
|
|
4890
|
-
return {
|
|
4891
|
-
type: "a",
|
|
4892
|
-
props: {
|
|
4893
|
-
href,
|
|
4894
|
-
children,
|
|
4895
|
-
onClick: (e) => {
|
|
4896
|
-
const event = e;
|
|
4897
|
-
const button = event.button ?? 0;
|
|
4898
|
-
if (button !== 0 || // not left-click
|
|
4899
|
-
event.ctrlKey || // Ctrl/Cmd+click
|
|
4900
|
-
event.metaKey || // Cmd on Mac
|
|
4901
|
-
event.shiftKey || // Shift+click
|
|
4902
|
-
event.altKey) {
|
|
4903
|
-
return;
|
|
4904
|
-
}
|
|
4905
|
-
event.preventDefault();
|
|
4906
|
-
navigate(href);
|
|
4907
|
-
}
|
|
4908
|
-
}
|
|
4909
|
-
};
|
|
4910
|
-
}
|
|
4911
|
-
|
|
4912
|
-
// src/foundations/layout.tsx
|
|
4913
|
-
function layout(Layout) {
|
|
4914
|
-
return (children, props) => Layout({ ...props, children });
|
|
4915
|
-
}
|
|
4916
|
-
|
|
4917
|
-
// src/foundations/slot.tsx
|
|
4918
|
-
init_logger();
|
|
4919
|
-
init_jsx();
|
|
4920
|
-
function Slot(props) {
|
|
4921
|
-
if (props.asChild) {
|
|
4922
|
-
const { children, ...rest } = props;
|
|
4923
|
-
if (isElement(children)) {
|
|
4924
|
-
return cloneElement(children, rest);
|
|
4925
|
-
}
|
|
4926
|
-
logger.warn("<Slot asChild> expects a single JSX element child.");
|
|
4927
|
-
return null;
|
|
4928
|
-
}
|
|
4929
|
-
return {
|
|
4930
|
-
$$typeof: ELEMENT_TYPE,
|
|
4931
|
-
type: Fragment,
|
|
4932
|
-
props: { children: props.children }
|
|
4933
|
-
};
|
|
4934
|
-
}
|
|
4935
|
-
|
|
4936
|
-
// src/index.ts
|
|
4937
|
-
init_portal();
|
|
4938
|
-
init_ssr();
|
|
4939
|
-
init_jsx_runtime();
|
|
4940
|
-
init_route();
|
|
4941
|
-
init_navigate();
|
|
4942
|
-
|
|
4943
|
-
// src/runtime/fastlane.ts
|
|
4944
|
-
init_scheduler();
|
|
4945
|
-
init_logger();
|
|
4946
|
-
init_component();
|
|
4947
|
-
init_renderer();
|
|
4948
|
-
init_fastlane_shared();
|
|
4949
|
-
init_types2();
|
|
4950
|
-
init_dev_namespace();
|
|
4951
|
-
function unwrapFragmentForFastPath(vnode) {
|
|
4952
|
-
if (!vnode || typeof vnode !== "object" || !("type" in vnode)) return vnode;
|
|
4953
|
-
const v = vnode;
|
|
4954
|
-
if (typeof v.type === "symbol" && (v.type === Fragment || String(v.type) === "Symbol(askr.fragment)")) {
|
|
4955
|
-
const children = v.children || v.props?.children;
|
|
4956
|
-
if (Array.isArray(children) && children.length > 0) {
|
|
4957
|
-
for (const child of children) {
|
|
4958
|
-
if (child && typeof child === "object" && "type" in child) {
|
|
4959
|
-
const c = child;
|
|
4960
|
-
if (typeof c.type === "string") {
|
|
4961
|
-
return child;
|
|
4962
|
-
}
|
|
4963
|
-
}
|
|
4964
|
-
}
|
|
4965
|
-
}
|
|
4966
|
-
}
|
|
4967
|
-
return vnode;
|
|
4968
|
-
}
|
|
4969
|
-
function classifyUpdate(instance, result) {
|
|
4970
|
-
const unwrappedResult = unwrapFragmentForFastPath(result);
|
|
4971
|
-
if (!unwrappedResult || typeof unwrappedResult !== "object" || !("type" in unwrappedResult))
|
|
4972
|
-
return { useFastPath: false, reason: "not-vnode" };
|
|
4973
|
-
const vnode = unwrappedResult;
|
|
4974
|
-
if (vnode == null || typeof vnode.type !== "string")
|
|
4975
|
-
return { useFastPath: false, reason: "not-intrinsic" };
|
|
4976
|
-
const parent = instance.target;
|
|
4977
|
-
if (!parent) return { useFastPath: false, reason: "no-root" };
|
|
4978
|
-
const firstChild = parent.children[0];
|
|
4979
|
-
if (!firstChild) return { useFastPath: false, reason: "no-first-child" };
|
|
4980
|
-
if (firstChild.tagName.toLowerCase() !== String(vnode.type).toLowerCase())
|
|
4981
|
-
return { useFastPath: false, reason: "root-tag-mismatch" };
|
|
4982
|
-
const children = vnode.children || vnode.props?.children;
|
|
4983
|
-
if (!Array.isArray(children))
|
|
4984
|
-
return { useFastPath: false, reason: "no-children-array" };
|
|
4985
|
-
for (const c of children) {
|
|
4986
|
-
if (typeof c === "object" && c !== null && "type" in c && typeof c.type === "function") {
|
|
4987
|
-
return { useFastPath: false, reason: "component-child-present" };
|
|
4988
|
-
}
|
|
4989
|
-
}
|
|
4990
|
-
if (instance.mountOperations.length > 0)
|
|
4991
|
-
return { useFastPath: false, reason: "pending-mounts" };
|
|
4992
|
-
try {
|
|
4993
|
-
populateKeyMapForElement(firstChild);
|
|
4994
|
-
} catch {
|
|
4995
|
-
}
|
|
4996
|
-
const oldKeyMap = getKeyMapForElement(firstChild);
|
|
4997
|
-
const decision = isKeyedReorderFastPathEligible(
|
|
4998
|
-
firstChild,
|
|
4999
|
-
children,
|
|
5000
|
-
oldKeyMap
|
|
5001
|
-
);
|
|
5002
|
-
if (!decision.useFastPath || decision.totalKeyed < 128)
|
|
5003
|
-
return { ...decision, useFastPath: false, reason: "renderer-declined" };
|
|
5004
|
-
return { ...decision, useFastPath: true };
|
|
5005
|
-
}
|
|
5006
|
-
function commitReorderOnly(instance, result) {
|
|
5007
|
-
const evaluate2 = globalThis.__ASKR_RENDERER?.evaluate;
|
|
5008
|
-
if (typeof evaluate2 !== "function") {
|
|
5009
|
-
logger.warn(
|
|
5010
|
-
"[Tempo][FASTPATH][DEV] renderer.evaluate not available; declining fast-lane"
|
|
5011
|
-
);
|
|
5012
|
-
return false;
|
|
5013
|
-
}
|
|
5014
|
-
const schedBefore = process.env.NODE_ENV !== "production" ? globalScheduler.getState() : null;
|
|
5015
|
-
enterBulkCommit();
|
|
5016
|
-
try {
|
|
5017
|
-
globalScheduler.runWithSyncProgress(() => {
|
|
5018
|
-
evaluate2(result, instance.target);
|
|
5019
|
-
try {
|
|
5020
|
-
finalizeReadSubscriptions(instance);
|
|
5021
|
-
} catch (e) {
|
|
5022
|
-
if (process.env.NODE_ENV !== "production") throw e;
|
|
5023
|
-
}
|
|
5024
|
-
});
|
|
5025
|
-
const clearedAfter = globalScheduler.clearPendingSyncTasks?.() ?? 0;
|
|
5026
|
-
setDevValue("__FASTLANE_CLEARED_AFTER", clearedAfter);
|
|
5027
|
-
if (process.env.NODE_ENV !== "production") {
|
|
5028
|
-
validateFastLaneInvariants(instance, schedBefore);
|
|
5029
|
-
}
|
|
5030
|
-
return true;
|
|
5031
|
-
} finally {
|
|
5032
|
-
exitBulkCommit();
|
|
5033
|
-
}
|
|
5034
|
-
if (process.env.NODE_ENV !== "production") {
|
|
5035
|
-
if (isBulkCommitActive2()) {
|
|
5036
|
-
throw new Error(
|
|
5037
|
-
"Fast-lane invariant violated: bulk commit flag still set after commit"
|
|
5038
|
-
);
|
|
5039
|
-
}
|
|
5040
|
-
}
|
|
5041
|
-
}
|
|
5042
|
-
function validateFastLaneInvariants(instance, schedBefore) {
|
|
5043
|
-
const commitCount = getDevValue("__LAST_FASTPATH_COMMIT_COUNT") ?? 0;
|
|
5044
|
-
const invariants = {
|
|
5045
|
-
commitCount,
|
|
5046
|
-
mountOps: instance.mountOperations.length,
|
|
5047
|
-
cleanupFns: instance.cleanupFns.length
|
|
5048
|
-
};
|
|
5049
|
-
setDevValue("__LAST_FASTLANE_INVARIANTS", invariants);
|
|
5050
|
-
if (commitCount !== 1) {
|
|
5051
|
-
console.error(
|
|
5052
|
-
"[FASTLANE][INV] commitCount",
|
|
5053
|
-
commitCount,
|
|
5054
|
-
"diag",
|
|
5055
|
-
globalThis.__ASKR_DIAG
|
|
5056
|
-
);
|
|
5057
|
-
throw new Error(
|
|
5058
|
-
"Fast-lane invariant violated: expected exactly one DOM commit during reorder-only commit"
|
|
5059
|
-
);
|
|
5060
|
-
}
|
|
5061
|
-
if (invariants.mountOps > 0) {
|
|
5062
|
-
throw new Error(
|
|
5063
|
-
"Fast-lane invariant violated: mount operations were registered during bulk commit"
|
|
5064
|
-
);
|
|
5065
|
-
}
|
|
5066
|
-
if (invariants.cleanupFns > 0) {
|
|
5067
|
-
throw new Error(
|
|
5068
|
-
"Fast-lane invariant violated: cleanup functions were added during bulk commit"
|
|
5069
|
-
);
|
|
5070
|
-
}
|
|
5071
|
-
const schedAfter = globalScheduler.getState();
|
|
5072
|
-
if (schedBefore && schedAfter && schedAfter.taskCount > schedBefore.taskCount) {
|
|
5073
|
-
console.error(
|
|
5074
|
-
"[FASTLANE] schedBefore, schedAfter",
|
|
5075
|
-
schedBefore,
|
|
5076
|
-
schedAfter
|
|
5077
|
-
);
|
|
5078
|
-
console.error("[FASTLANE] enqueue logs", getDevValue("__ENQUEUE_LOGS"));
|
|
5079
|
-
throw new Error(
|
|
5080
|
-
"Fast-lane invariant violated: scheduler enqueued leftover work during bulk commit"
|
|
5081
|
-
);
|
|
5082
|
-
}
|
|
5083
|
-
let finalState = globalScheduler.getState();
|
|
5084
|
-
const executing = globalScheduler.isExecuting();
|
|
5085
|
-
let outstandingAfter = Math.max(
|
|
5086
|
-
0,
|
|
5087
|
-
finalState.taskCount - (executing ? 1 : 0)
|
|
5088
|
-
);
|
|
5089
|
-
if (outstandingAfter !== 0) {
|
|
5090
|
-
let attempts = 0;
|
|
5091
|
-
while (attempts < 5) {
|
|
5092
|
-
const cleared = globalScheduler.clearPendingSyncTasks?.() ?? 0;
|
|
5093
|
-
if (cleared === 0) break;
|
|
5094
|
-
attempts++;
|
|
5095
|
-
}
|
|
5096
|
-
finalState = globalScheduler.getState();
|
|
5097
|
-
outstandingAfter = Math.max(
|
|
5098
|
-
0,
|
|
5099
|
-
finalState.taskCount - (globalScheduler.isExecuting() ? 1 : 0)
|
|
5100
|
-
);
|
|
5101
|
-
if (outstandingAfter !== 0) {
|
|
5102
|
-
console.error(
|
|
5103
|
-
"[FASTLANE] Post-commit enqueue logs:",
|
|
5104
|
-
getDevValue("__ENQUEUE_LOGS")
|
|
5105
|
-
);
|
|
5106
|
-
console.error(
|
|
5107
|
-
"[FASTLANE] Cleared counts:",
|
|
5108
|
-
getDevValue("__FASTLANE_CLEARED_TASKS"),
|
|
5109
|
-
getDevValue("__FASTLANE_CLEARED_AFTER")
|
|
5110
|
-
);
|
|
5111
|
-
throw new Error(
|
|
5112
|
-
`Fast-lane invariant violated: scheduler has ${finalState.taskCount} pending task(s) after commit`
|
|
5113
|
-
);
|
|
5114
|
-
}
|
|
5115
|
-
}
|
|
5116
|
-
}
|
|
5117
|
-
function tryRuntimeFastLaneSync(instance, result) {
|
|
5118
|
-
const cls = classifyUpdate(instance, result);
|
|
5119
|
-
if (!cls.useFastPath) {
|
|
5120
|
-
setDevValue("__LAST_FASTPATH_STATS", void 0);
|
|
5121
|
-
setDevValue("__LAST_FASTPATH_COMMIT_COUNT", 0);
|
|
5122
|
-
return false;
|
|
5123
|
-
}
|
|
5124
|
-
try {
|
|
5125
|
-
return commitReorderOnly(instance, result);
|
|
5126
|
-
} catch (err) {
|
|
5127
|
-
if (process.env.NODE_ENV !== "production") throw err;
|
|
5128
|
-
return false;
|
|
5129
|
-
}
|
|
5130
|
-
}
|
|
5131
|
-
if (typeof globalThis !== "undefined") {
|
|
5132
|
-
globalThis.__ASKR_FASTLANE = {
|
|
5133
|
-
isBulkCommitActive: isBulkCommitActive2,
|
|
5134
|
-
enterBulkCommit,
|
|
5135
|
-
exitBulkCommit,
|
|
5136
|
-
tryRuntimeFastLaneSync,
|
|
5137
|
-
markFastPathApplied,
|
|
5138
|
-
isFastPathApplied
|
|
5139
|
-
};
|
|
5140
|
-
}
|
|
5141
|
-
|
|
5142
|
-
// src/index.ts
|
|
5143
|
-
if (typeof globalThis !== "undefined") {
|
|
5144
|
-
const g = globalThis;
|
|
5145
|
-
if (!g.createIsland) g.createIsland = createIsland;
|
|
5146
|
-
if (!g.createSPA) g.createSPA = createSPA;
|
|
5147
|
-
if (!g.hydrateSPA) g.hydrateSPA = hydrateSPA;
|
|
5148
|
-
if (!g.route) g.route = route;
|
|
5149
|
-
if (!g.getRoutes) g.getRoutes = getRoutes;
|
|
5150
|
-
if (!g.navigate) g.navigate = navigate;
|
|
5151
|
-
}
|
|
5152
|
-
// Annotate the CommonJS export names for ESM import in node:
|
|
5153
|
-
0 && (module.exports = {
|
|
5154
|
-
DefaultPortal,
|
|
5155
|
-
Fragment,
|
|
5156
|
-
Link,
|
|
5157
|
-
Slot,
|
|
5158
|
-
_resetDefaultPortal,
|
|
5159
|
-
cleanupApp,
|
|
5160
|
-
clearRoutes,
|
|
5161
|
-
collectResources,
|
|
5162
|
-
createIsland,
|
|
5163
|
-
createSPA,
|
|
5164
|
-
defineContext,
|
|
5165
|
-
definePortal,
|
|
5166
|
-
derive,
|
|
5167
|
-
getLoadedNamespaces,
|
|
5168
|
-
getNamespaceRoutes,
|
|
5169
|
-
getRoutes,
|
|
5170
|
-
getSignal,
|
|
5171
|
-
hasApp,
|
|
5172
|
-
hydrateSPA,
|
|
5173
|
-
jsx,
|
|
5174
|
-
jsxs,
|
|
5175
|
-
layout,
|
|
5176
|
-
navigate,
|
|
5177
|
-
readContext,
|
|
5178
|
-
renderToStream,
|
|
5179
|
-
renderToString,
|
|
5180
|
-
renderToStringSync,
|
|
5181
|
-
renderToStringSyncForUrl,
|
|
5182
|
-
resolveResources,
|
|
5183
|
-
resource,
|
|
5184
|
-
route,
|
|
5185
|
-
scheduleEventHandler,
|
|
5186
|
-
setServerLocation,
|
|
5187
|
-
state,
|
|
5188
|
-
task,
|
|
5189
|
-
unloadNamespace
|
|
5190
|
-
});
|
|
5191
|
-
//# sourceMappingURL=index.cjs.map
|
|
3924
|
+
export { SSRDataMissingError, collectResources, popSSRStrictPurityGuard, pushSSRStrictPurityGuard, renderToStream, renderToString, renderToStringSync, renderToStringSyncForUrl, resolvePlan, resolveResources };
|
|
3925
|
+
//# sourceMappingURL=ssr.js.map
|
|
3926
|
+
//# sourceMappingURL=ssr.js.map
|