round-core 0.0.2 → 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/benchmarks.yml +44 -0
- package/LICENSE +21 -0
- package/README.md +78 -48
- package/Round.png +0 -0
- package/benchmarks/apps/react/index.html +9 -0
- package/benchmarks/apps/react/main.jsx +25 -0
- package/benchmarks/apps/react/vite.config.js +12 -0
- package/benchmarks/apps/round/index.html +11 -0
- package/benchmarks/apps/round/main.jsx +22 -0
- package/benchmarks/apps/round/vite.config.js +15 -0
- package/benchmarks/bun.lock +497 -0
- package/benchmarks/dist-bench/react/assets/index-9KGqIPOU.js +8 -0
- package/benchmarks/dist-bench/react/index.html +10 -0
- package/benchmarks/dist-bench/round/assets/index-CBBIRhox.js +52 -0
- package/benchmarks/dist-bench/round/index.html +8 -0
- package/benchmarks/package.json +22 -0
- package/benchmarks/scripts/measure-build.js +64 -0
- package/benchmarks/tests/runtime.bench.js +51 -0
- package/benchmarks/vitest.config.js +8 -0
- package/dist/cli.js +582 -0
- package/dist/index.js +1975 -0
- package/dist/vite-plugin.js +736 -0
- package/logo.svg +9 -72
- package/package.json +14 -6
- package/src/cli.js +10 -3
- package/src/compiler/transformer.js +61 -2
- package/src/compiler/vite-plugin.js +5 -1
- package/src/runtime/context.js +17 -1
- package/src/runtime/dom.js +90 -42
- package/src/runtime/lifecycle.js +1 -1
- package/src/runtime/suspense.js +39 -17
- package/vite.config.build.js +47 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,1975 @@
|
|
|
1
|
+
import { marked } from "marked";
|
|
2
|
+
let reporter = null;
|
|
3
|
+
function setErrorReporter(fn) {
|
|
4
|
+
reporter = typeof fn === "function" ? fn : null;
|
|
5
|
+
}
|
|
6
|
+
function reportErrorSafe(error, info) {
|
|
7
|
+
if (!reporter) return;
|
|
8
|
+
try {
|
|
9
|
+
reporter(error, info);
|
|
10
|
+
} catch {
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
const componentStack = [];
|
|
14
|
+
function getCurrentComponent() {
|
|
15
|
+
return componentStack[componentStack.length - 1];
|
|
16
|
+
}
|
|
17
|
+
function runInLifecycle(componentInstance, fn) {
|
|
18
|
+
componentStack.push(componentInstance);
|
|
19
|
+
try {
|
|
20
|
+
return fn();
|
|
21
|
+
} finally {
|
|
22
|
+
componentStack.pop();
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
function createComponentInstance() {
|
|
26
|
+
return {
|
|
27
|
+
mountHooks: [],
|
|
28
|
+
unmountHooks: [],
|
|
29
|
+
updateHooks: [],
|
|
30
|
+
nodes: [],
|
|
31
|
+
isMounted: false,
|
|
32
|
+
mountTimerId: null
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
function onMount(fn) {
|
|
36
|
+
const component = getCurrentComponent();
|
|
37
|
+
if (component) {
|
|
38
|
+
component.mountHooks.push(fn);
|
|
39
|
+
} else {
|
|
40
|
+
setTimeout(() => {
|
|
41
|
+
try {
|
|
42
|
+
fn();
|
|
43
|
+
} catch (e) {
|
|
44
|
+
reportErrorSafe(e, { phase: "onMount" });
|
|
45
|
+
}
|
|
46
|
+
}, 0);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
function onUnmount(fn) {
|
|
50
|
+
const component = getCurrentComponent();
|
|
51
|
+
if (component) {
|
|
52
|
+
component.unmountHooks.push(fn);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
const onCleanup = onUnmount;
|
|
56
|
+
function onUpdate(fn) {
|
|
57
|
+
const component = getCurrentComponent();
|
|
58
|
+
if (component) {
|
|
59
|
+
component.updateHooks.push(fn);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
function mountComponent(component) {
|
|
63
|
+
if (component.isMounted) return;
|
|
64
|
+
try {
|
|
65
|
+
const root = component?.nodes?.[0];
|
|
66
|
+
if (root && root instanceof Node && root.isConnected === false) {
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
} catch {
|
|
70
|
+
}
|
|
71
|
+
component.isMounted = true;
|
|
72
|
+
component.mountHooks.forEach((hook) => {
|
|
73
|
+
try {
|
|
74
|
+
const cleanup2 = hook();
|
|
75
|
+
if (typeof cleanup2 === "function") {
|
|
76
|
+
component.unmountHooks.push(cleanup2);
|
|
77
|
+
}
|
|
78
|
+
} catch (e) {
|
|
79
|
+
reportErrorSafe(e, { phase: "mount", component: component.name ?? null });
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
function unmountComponent(component) {
|
|
84
|
+
if (!component.isMounted) return;
|
|
85
|
+
if (component.mountTimerId != null) {
|
|
86
|
+
try {
|
|
87
|
+
clearTimeout(component.mountTimerId);
|
|
88
|
+
} catch {
|
|
89
|
+
}
|
|
90
|
+
component.mountTimerId = null;
|
|
91
|
+
}
|
|
92
|
+
component.isMounted = false;
|
|
93
|
+
component.unmountHooks.forEach((hook) => {
|
|
94
|
+
try {
|
|
95
|
+
hook();
|
|
96
|
+
} catch (e) {
|
|
97
|
+
reportErrorSafe(e, { phase: "unmount", component: component.name ?? null });
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
function triggerUpdate(component) {
|
|
102
|
+
if (!component.isMounted) return;
|
|
103
|
+
component.updateHooks.forEach((hook) => {
|
|
104
|
+
try {
|
|
105
|
+
hook();
|
|
106
|
+
} catch (e) {
|
|
107
|
+
reportErrorSafe(e, { phase: "update", component: component.name ?? null });
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
const observer = typeof MutationObserver !== "undefined" ? new MutationObserver((mutations) => {
|
|
112
|
+
mutations.forEach((mutation) => {
|
|
113
|
+
if (mutation.removedNodes.length > 0) {
|
|
114
|
+
mutation.removedNodes.forEach((node) => {
|
|
115
|
+
if (node._componentInstance) {
|
|
116
|
+
unmountComponent(node._componentInstance);
|
|
117
|
+
}
|
|
118
|
+
cleanupNodeRecursively(node);
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
}) : null;
|
|
123
|
+
function cleanupNodeRecursively(node) {
|
|
124
|
+
if (node._componentInstance) {
|
|
125
|
+
unmountComponent(node._componentInstance);
|
|
126
|
+
}
|
|
127
|
+
node.childNodes.forEach(cleanupNodeRecursively);
|
|
128
|
+
}
|
|
129
|
+
function initLifecycleRoot(rootNode) {
|
|
130
|
+
if (!rootNode) return;
|
|
131
|
+
if (!observer) return;
|
|
132
|
+
observer.observe(rootNode, { childList: true, subtree: true });
|
|
133
|
+
}
|
|
134
|
+
const Lifecycle = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
135
|
+
__proto__: null,
|
|
136
|
+
createComponentInstance,
|
|
137
|
+
getCurrentComponent,
|
|
138
|
+
initLifecycleRoot,
|
|
139
|
+
mountComponent,
|
|
140
|
+
onCleanup,
|
|
141
|
+
onMount,
|
|
142
|
+
onUnmount,
|
|
143
|
+
onUpdate,
|
|
144
|
+
runInLifecycle,
|
|
145
|
+
triggerUpdate,
|
|
146
|
+
unmountComponent
|
|
147
|
+
}, Symbol.toStringTag, { value: "Module" }));
|
|
148
|
+
let context = [];
|
|
149
|
+
function isPromiseLike$2(v) {
|
|
150
|
+
return v && (typeof v === "object" || typeof v === "function") && typeof v.then === "function";
|
|
151
|
+
}
|
|
152
|
+
function subscribe(running, subscriptions) {
|
|
153
|
+
subscriptions.add(running);
|
|
154
|
+
running.dependencies.add(subscriptions);
|
|
155
|
+
}
|
|
156
|
+
function untrack(fn) {
|
|
157
|
+
context.push(null);
|
|
158
|
+
try {
|
|
159
|
+
return typeof fn === "function" ? fn() : void 0;
|
|
160
|
+
} finally {
|
|
161
|
+
context.pop();
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
function effect(arg1, arg2, arg3) {
|
|
165
|
+
let callback;
|
|
166
|
+
let explicitDeps = null;
|
|
167
|
+
let options = { onLoad: true };
|
|
168
|
+
let owner = getCurrentComponent();
|
|
169
|
+
if (typeof arg1 === "function") {
|
|
170
|
+
callback = arg1;
|
|
171
|
+
if (arg2 && typeof arg2 === "object") {
|
|
172
|
+
options = { ...options, ...arg2 };
|
|
173
|
+
}
|
|
174
|
+
} else {
|
|
175
|
+
explicitDeps = arg1;
|
|
176
|
+
callback = arg2;
|
|
177
|
+
if (arg3 && typeof arg3 === "object") {
|
|
178
|
+
options = { ...options, ...arg3 };
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
const execute = () => {
|
|
182
|
+
if (typeof execute._cleanup === "function") {
|
|
183
|
+
try {
|
|
184
|
+
execute._cleanup();
|
|
185
|
+
} catch (e) {
|
|
186
|
+
const name = owner ? owner.name ?? "Anonymous" : null;
|
|
187
|
+
reportErrorSafe(e, { phase: "effect.cleanup", component: name });
|
|
188
|
+
}
|
|
189
|
+
execute._cleanup = null;
|
|
190
|
+
}
|
|
191
|
+
cleanup(execute);
|
|
192
|
+
context.push(execute);
|
|
193
|
+
try {
|
|
194
|
+
if (explicitDeps) {
|
|
195
|
+
if (Array.isArray(explicitDeps)) {
|
|
196
|
+
explicitDeps.forEach((dep) => {
|
|
197
|
+
if (typeof dep === "function") dep();
|
|
198
|
+
});
|
|
199
|
+
} else if (typeof explicitDeps === "function") {
|
|
200
|
+
explicitDeps();
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
if (typeof callback === "function") {
|
|
204
|
+
const res = callback();
|
|
205
|
+
if (typeof res === "function") {
|
|
206
|
+
execute._cleanup = res;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
if (owner && owner.isMounted) triggerUpdate(owner);
|
|
210
|
+
} catch (e) {
|
|
211
|
+
if (isPromiseLike$2(e)) throw e;
|
|
212
|
+
const name = owner ? owner.name ?? "Anonymous" : null;
|
|
213
|
+
reportErrorSafe(e, { phase: "effect", component: name });
|
|
214
|
+
} finally {
|
|
215
|
+
context.pop();
|
|
216
|
+
}
|
|
217
|
+
};
|
|
218
|
+
execute.dependencies = /* @__PURE__ */ new Set();
|
|
219
|
+
execute._cleanup = null;
|
|
220
|
+
if (options.onLoad) {
|
|
221
|
+
onMount(execute);
|
|
222
|
+
} else {
|
|
223
|
+
execute();
|
|
224
|
+
}
|
|
225
|
+
return () => {
|
|
226
|
+
if (typeof execute._cleanup === "function") {
|
|
227
|
+
try {
|
|
228
|
+
execute._cleanup();
|
|
229
|
+
} catch (e) {
|
|
230
|
+
const name = owner ? owner.name ?? "Anonymous" : null;
|
|
231
|
+
reportErrorSafe(e, { phase: "effect.cleanup", component: name });
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
execute._cleanup = null;
|
|
235
|
+
cleanup(execute);
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
function cleanup(running) {
|
|
239
|
+
running.dependencies.forEach((dep) => dep.delete(running));
|
|
240
|
+
running.dependencies.clear();
|
|
241
|
+
}
|
|
242
|
+
function defineBindMarkerIfNeeded(source, target) {
|
|
243
|
+
if (source && source.bind === true) {
|
|
244
|
+
try {
|
|
245
|
+
Object.defineProperty(target, "bind", {
|
|
246
|
+
enumerable: true,
|
|
247
|
+
configurable: false,
|
|
248
|
+
writable: false,
|
|
249
|
+
value: true
|
|
250
|
+
});
|
|
251
|
+
} catch {
|
|
252
|
+
try {
|
|
253
|
+
target.bind = true;
|
|
254
|
+
} catch {
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
function attachHelpers(s) {
|
|
260
|
+
if (!s || typeof s !== "function") return s;
|
|
261
|
+
if (typeof s.transform === "function" && typeof s.validate === "function" && typeof s.$pick === "function") return s;
|
|
262
|
+
s.$pick = (p) => {
|
|
263
|
+
return pick(s, p);
|
|
264
|
+
};
|
|
265
|
+
s.transform = (fromInput, toOutput) => {
|
|
266
|
+
const fromFn = typeof fromInput === "function" ? fromInput : (v) => v;
|
|
267
|
+
const toFn = typeof toOutput === "function" ? toOutput : (v) => v;
|
|
268
|
+
const wrapped = function(...args) {
|
|
269
|
+
if (args.length > 0) {
|
|
270
|
+
return s(fromFn(args[0]));
|
|
271
|
+
}
|
|
272
|
+
return toFn(s());
|
|
273
|
+
};
|
|
274
|
+
wrapped.peek = () => toFn(s.peek());
|
|
275
|
+
Object.defineProperty(wrapped, "value", {
|
|
276
|
+
enumerable: true,
|
|
277
|
+
get() {
|
|
278
|
+
return wrapped.peek();
|
|
279
|
+
},
|
|
280
|
+
set(v) {
|
|
281
|
+
wrapped(v);
|
|
282
|
+
}
|
|
283
|
+
});
|
|
284
|
+
defineBindMarkerIfNeeded(s, wrapped);
|
|
285
|
+
return attachHelpers(wrapped);
|
|
286
|
+
};
|
|
287
|
+
s.validate = (validator, options = {}) => {
|
|
288
|
+
const validateFn = typeof validator === "function" ? validator : null;
|
|
289
|
+
const error = signal(null);
|
|
290
|
+
const validateOn = options && typeof options === "object" && typeof options.validateOn === "string" ? options.validateOn : "input";
|
|
291
|
+
const validateInitial = Boolean(options && typeof options === "object" && options.validateInitial);
|
|
292
|
+
const wrapped = function(...args) {
|
|
293
|
+
if (args.length > 0) {
|
|
294
|
+
const next = args[0];
|
|
295
|
+
if (validateFn) {
|
|
296
|
+
let res = true;
|
|
297
|
+
try {
|
|
298
|
+
res = validateFn(next, s.peek());
|
|
299
|
+
} catch {
|
|
300
|
+
res = "Invalid value";
|
|
301
|
+
}
|
|
302
|
+
if (res === true || res === void 0 || res === null) {
|
|
303
|
+
error(null);
|
|
304
|
+
return s(next);
|
|
305
|
+
}
|
|
306
|
+
if (typeof res === "string" && res.length) {
|
|
307
|
+
error(res);
|
|
308
|
+
} else {
|
|
309
|
+
error("Invalid value");
|
|
310
|
+
}
|
|
311
|
+
return s.peek();
|
|
312
|
+
}
|
|
313
|
+
error(null);
|
|
314
|
+
return s(next);
|
|
315
|
+
}
|
|
316
|
+
return s();
|
|
317
|
+
};
|
|
318
|
+
wrapped.check = () => {
|
|
319
|
+
if (!validateFn) {
|
|
320
|
+
error(null);
|
|
321
|
+
return true;
|
|
322
|
+
}
|
|
323
|
+
const cur = s.peek();
|
|
324
|
+
let res = true;
|
|
325
|
+
try {
|
|
326
|
+
res = validateFn(cur, cur);
|
|
327
|
+
} catch {
|
|
328
|
+
res = "Invalid value";
|
|
329
|
+
}
|
|
330
|
+
if (res === true || res === void 0 || res === null) {
|
|
331
|
+
error(null);
|
|
332
|
+
return true;
|
|
333
|
+
}
|
|
334
|
+
if (typeof res === "string" && res.length) error(res);
|
|
335
|
+
else error("Invalid value");
|
|
336
|
+
return false;
|
|
337
|
+
};
|
|
338
|
+
wrapped.peek = () => s.peek();
|
|
339
|
+
Object.defineProperty(wrapped, "value", {
|
|
340
|
+
enumerable: true,
|
|
341
|
+
get() {
|
|
342
|
+
return wrapped.peek();
|
|
343
|
+
},
|
|
344
|
+
set(v) {
|
|
345
|
+
wrapped(v);
|
|
346
|
+
}
|
|
347
|
+
});
|
|
348
|
+
wrapped.error = error;
|
|
349
|
+
wrapped.__round_validateOn = validateOn;
|
|
350
|
+
if (validateInitial) {
|
|
351
|
+
try {
|
|
352
|
+
wrapped.check();
|
|
353
|
+
} catch {
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
defineBindMarkerIfNeeded(s, wrapped);
|
|
357
|
+
return attachHelpers(wrapped);
|
|
358
|
+
};
|
|
359
|
+
return s;
|
|
360
|
+
}
|
|
361
|
+
function signal(initialValue) {
|
|
362
|
+
let value = initialValue;
|
|
363
|
+
const subscriptions = /* @__PURE__ */ new Set();
|
|
364
|
+
const read = () => {
|
|
365
|
+
const running = context[context.length - 1];
|
|
366
|
+
if (running) {
|
|
367
|
+
subscribe(running, subscriptions);
|
|
368
|
+
}
|
|
369
|
+
return value;
|
|
370
|
+
};
|
|
371
|
+
const peek = () => value;
|
|
372
|
+
const write = (newValue) => {
|
|
373
|
+
if (value !== newValue) {
|
|
374
|
+
value = newValue;
|
|
375
|
+
[...subscriptions].forEach((sub) => sub());
|
|
376
|
+
}
|
|
377
|
+
return value;
|
|
378
|
+
};
|
|
379
|
+
const signal2 = function(...args) {
|
|
380
|
+
if (args.length > 0) {
|
|
381
|
+
return write(args[0]);
|
|
382
|
+
}
|
|
383
|
+
return read();
|
|
384
|
+
};
|
|
385
|
+
Object.defineProperty(signal2, "value", {
|
|
386
|
+
enumerable: true,
|
|
387
|
+
get() {
|
|
388
|
+
return peek();
|
|
389
|
+
},
|
|
390
|
+
set(v) {
|
|
391
|
+
write(v);
|
|
392
|
+
}
|
|
393
|
+
});
|
|
394
|
+
signal2.peek = peek;
|
|
395
|
+
return attachHelpers(signal2);
|
|
396
|
+
}
|
|
397
|
+
function bindable(initialValue) {
|
|
398
|
+
const s = signal(initialValue);
|
|
399
|
+
try {
|
|
400
|
+
Object.defineProperty(s, "bind", {
|
|
401
|
+
enumerable: true,
|
|
402
|
+
configurable: false,
|
|
403
|
+
writable: false,
|
|
404
|
+
value: true
|
|
405
|
+
});
|
|
406
|
+
} catch {
|
|
407
|
+
try {
|
|
408
|
+
s.bind = true;
|
|
409
|
+
} catch {
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
return attachHelpers(s);
|
|
413
|
+
}
|
|
414
|
+
function isSignalLike(v) {
|
|
415
|
+
return typeof v === "function" && typeof v.peek === "function" && "value" in v;
|
|
416
|
+
}
|
|
417
|
+
function getIn(obj, path) {
|
|
418
|
+
let cur = obj;
|
|
419
|
+
for (const key of path) {
|
|
420
|
+
if (cur == null) return void 0;
|
|
421
|
+
cur = cur[key];
|
|
422
|
+
}
|
|
423
|
+
return cur;
|
|
424
|
+
}
|
|
425
|
+
function setIn(obj, path, value) {
|
|
426
|
+
if (!Array.isArray(path) || path.length === 0) return value;
|
|
427
|
+
const root = obj && typeof obj === "object" ? obj : {};
|
|
428
|
+
const out = Array.isArray(root) ? root.slice() : { ...root };
|
|
429
|
+
let curOut = out;
|
|
430
|
+
let curIn = root;
|
|
431
|
+
for (let i = 0; i < path.length - 1; i++) {
|
|
432
|
+
const key = path[i];
|
|
433
|
+
const nextIn = curIn && typeof curIn === "object" ? curIn[key] : void 0;
|
|
434
|
+
const nextOut = nextIn && typeof nextIn === "object" ? Array.isArray(nextIn) ? nextIn.slice() : { ...nextIn } : {};
|
|
435
|
+
curOut[key] = nextOut;
|
|
436
|
+
curOut = nextOut;
|
|
437
|
+
curIn = nextIn;
|
|
438
|
+
}
|
|
439
|
+
curOut[path[path.length - 1]] = value;
|
|
440
|
+
return out;
|
|
441
|
+
}
|
|
442
|
+
function parsePath(path) {
|
|
443
|
+
if (Array.isArray(path)) return path.map((p) => String(p));
|
|
444
|
+
if (typeof path === "string") return path.split(".").filter(Boolean);
|
|
445
|
+
return [String(path)];
|
|
446
|
+
}
|
|
447
|
+
function pick(root, path) {
|
|
448
|
+
if (!isSignalLike(root)) {
|
|
449
|
+
throw new Error("[round] pick(root, path) expects root to be a signal (use bindable.object(...) or signal({...})).");
|
|
450
|
+
}
|
|
451
|
+
const pathArr = parsePath(path);
|
|
452
|
+
const view = function(...args) {
|
|
453
|
+
if (args.length > 0) {
|
|
454
|
+
const nextRoot = setIn(root.peek(), pathArr, args[0]);
|
|
455
|
+
return root(nextRoot);
|
|
456
|
+
}
|
|
457
|
+
const v = root();
|
|
458
|
+
return getIn(v, pathArr);
|
|
459
|
+
};
|
|
460
|
+
view.peek = () => getIn(root.peek(), pathArr);
|
|
461
|
+
Object.defineProperty(view, "value", {
|
|
462
|
+
enumerable: true,
|
|
463
|
+
get() {
|
|
464
|
+
return view.peek();
|
|
465
|
+
},
|
|
466
|
+
set(v) {
|
|
467
|
+
view(v);
|
|
468
|
+
}
|
|
469
|
+
});
|
|
470
|
+
if (root.bind === true) {
|
|
471
|
+
try {
|
|
472
|
+
Object.defineProperty(view, "bind", {
|
|
473
|
+
enumerable: true,
|
|
474
|
+
configurable: false,
|
|
475
|
+
writable: false,
|
|
476
|
+
value: true
|
|
477
|
+
});
|
|
478
|
+
} catch {
|
|
479
|
+
try {
|
|
480
|
+
view.bind = true;
|
|
481
|
+
} catch {
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
return view;
|
|
486
|
+
}
|
|
487
|
+
function createBindableObjectProxy(root, basePath) {
|
|
488
|
+
const cache = /* @__PURE__ */ new Map();
|
|
489
|
+
const handler = {
|
|
490
|
+
get(_target, prop) {
|
|
491
|
+
if (prop === Symbol.toStringTag) return "BindableObject";
|
|
492
|
+
if (prop === Symbol.iterator) return void 0;
|
|
493
|
+
if (prop === "peek") return () => basePath.length ? pick(root, basePath).peek() : root.peek();
|
|
494
|
+
if (prop === "value") return basePath.length ? pick(root, basePath).peek() : root.peek();
|
|
495
|
+
if (prop === "bind") return true;
|
|
496
|
+
if (prop === "$pick") {
|
|
497
|
+
return (p) => {
|
|
498
|
+
const nextPath2 = basePath.concat(parsePath(p));
|
|
499
|
+
return createBindableObjectProxy(root, nextPath2);
|
|
500
|
+
};
|
|
501
|
+
}
|
|
502
|
+
if (prop === "_root") return root;
|
|
503
|
+
if (prop === "_path") return basePath.slice();
|
|
504
|
+
if (prop === "call" || prop === "apply") {
|
|
505
|
+
return Reflect.get(_target, prop);
|
|
506
|
+
}
|
|
507
|
+
const key = String(prop);
|
|
508
|
+
const nextPath = basePath.concat(key);
|
|
509
|
+
const cacheKey = nextPath.join(".");
|
|
510
|
+
if (cache.has(cacheKey)) return cache.get(cacheKey);
|
|
511
|
+
try {
|
|
512
|
+
const stored = getIn(root.peek(), nextPath);
|
|
513
|
+
if (isSignalLike(stored)) {
|
|
514
|
+
cache.set(cacheKey, stored);
|
|
515
|
+
return stored;
|
|
516
|
+
}
|
|
517
|
+
} catch {
|
|
518
|
+
}
|
|
519
|
+
const next = createBindableObjectProxy(root, nextPath);
|
|
520
|
+
cache.set(cacheKey, next);
|
|
521
|
+
return next;
|
|
522
|
+
},
|
|
523
|
+
set(_target, prop, value) {
|
|
524
|
+
const key = String(prop);
|
|
525
|
+
const nextPath = basePath.concat(key);
|
|
526
|
+
try {
|
|
527
|
+
const stored = getIn(root.peek(), nextPath);
|
|
528
|
+
if (isSignalLike(stored)) {
|
|
529
|
+
stored(value);
|
|
530
|
+
return true;
|
|
531
|
+
}
|
|
532
|
+
} catch {
|
|
533
|
+
}
|
|
534
|
+
pick(root, nextPath)(value);
|
|
535
|
+
return true;
|
|
536
|
+
},
|
|
537
|
+
has(_target, prop) {
|
|
538
|
+
try {
|
|
539
|
+
if (Reflect.has(_target, prop)) return true;
|
|
540
|
+
} catch {
|
|
541
|
+
}
|
|
542
|
+
const v = basePath.length ? pick(root, basePath).peek() : root.peek();
|
|
543
|
+
return v != null && Object.prototype.hasOwnProperty.call(v, prop);
|
|
544
|
+
}
|
|
545
|
+
};
|
|
546
|
+
const fn = function(...args) {
|
|
547
|
+
if (args.length > 0) {
|
|
548
|
+
if (basePath.length) return pick(root, basePath)(args[0]);
|
|
549
|
+
return root(args[0]);
|
|
550
|
+
}
|
|
551
|
+
if (basePath.length) return pick(root, basePath)();
|
|
552
|
+
return root();
|
|
553
|
+
};
|
|
554
|
+
fn.peek = () => basePath.length ? pick(root, basePath).peek() : root.peek();
|
|
555
|
+
Object.defineProperty(fn, "value", {
|
|
556
|
+
enumerable: true,
|
|
557
|
+
get() {
|
|
558
|
+
return fn.peek();
|
|
559
|
+
},
|
|
560
|
+
set(v) {
|
|
561
|
+
fn(v);
|
|
562
|
+
}
|
|
563
|
+
});
|
|
564
|
+
try {
|
|
565
|
+
Object.defineProperty(fn, "bind", {
|
|
566
|
+
enumerable: true,
|
|
567
|
+
configurable: false,
|
|
568
|
+
writable: false,
|
|
569
|
+
value: true
|
|
570
|
+
});
|
|
571
|
+
} catch {
|
|
572
|
+
try {
|
|
573
|
+
fn.bind = true;
|
|
574
|
+
} catch {
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
return new Proxy(fn, handler);
|
|
578
|
+
}
|
|
579
|
+
bindable.object = function(initialObject = {}) {
|
|
580
|
+
const root = bindable(initialObject && typeof initialObject === "object" ? initialObject : {});
|
|
581
|
+
return createBindableObjectProxy(root, []);
|
|
582
|
+
};
|
|
583
|
+
function derive(fn) {
|
|
584
|
+
const derived = signal();
|
|
585
|
+
effect(() => {
|
|
586
|
+
derived(fn());
|
|
587
|
+
}, { onLoad: false });
|
|
588
|
+
return () => derived();
|
|
589
|
+
}
|
|
590
|
+
const Signals = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
591
|
+
__proto__: null,
|
|
592
|
+
bindable,
|
|
593
|
+
derive,
|
|
594
|
+
effect,
|
|
595
|
+
pick,
|
|
596
|
+
signal,
|
|
597
|
+
untrack
|
|
598
|
+
}, Symbol.toStringTag, { value: "Module" }));
|
|
599
|
+
let nextContextId = 1;
|
|
600
|
+
const contextStack = [];
|
|
601
|
+
function pushContext(values) {
|
|
602
|
+
contextStack.push(values);
|
|
603
|
+
}
|
|
604
|
+
function popContext() {
|
|
605
|
+
contextStack.pop();
|
|
606
|
+
}
|
|
607
|
+
function readContext(ctx) {
|
|
608
|
+
for (let i = contextStack.length - 1; i >= 0; i--) {
|
|
609
|
+
const layer = contextStack[i];
|
|
610
|
+
if (layer && Object.prototype.hasOwnProperty.call(layer, ctx.id)) {
|
|
611
|
+
return layer[ctx.id];
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
return ctx.defaultValue;
|
|
615
|
+
}
|
|
616
|
+
function createContext(defaultValue) {
|
|
617
|
+
const ctx = {
|
|
618
|
+
id: nextContextId++,
|
|
619
|
+
defaultValue,
|
|
620
|
+
Provider: null
|
|
621
|
+
};
|
|
622
|
+
function Provider(props = {}) {
|
|
623
|
+
const value = props.value;
|
|
624
|
+
const child = Array.isArray(props.children) ? props.children[0] : props.children;
|
|
625
|
+
const childFn = typeof child === "function" ? child : () => child;
|
|
626
|
+
return createElement("span", { style: { display: "contents" } }, () => {
|
|
627
|
+
pushContext({ [ctx.id]: value });
|
|
628
|
+
try {
|
|
629
|
+
return childFn();
|
|
630
|
+
} finally {
|
|
631
|
+
popContext();
|
|
632
|
+
}
|
|
633
|
+
});
|
|
634
|
+
}
|
|
635
|
+
ctx.Provider = Provider;
|
|
636
|
+
return ctx;
|
|
637
|
+
}
|
|
638
|
+
function bindContext(ctx) {
|
|
639
|
+
return () => {
|
|
640
|
+
const provided = readContext(ctx);
|
|
641
|
+
if (typeof provided === "function") {
|
|
642
|
+
try {
|
|
643
|
+
return provided();
|
|
644
|
+
} catch {
|
|
645
|
+
return provided;
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
return provided;
|
|
649
|
+
};
|
|
650
|
+
}
|
|
651
|
+
function captureContext() {
|
|
652
|
+
return contextStack.slice();
|
|
653
|
+
}
|
|
654
|
+
function runInContext(snapshot, fn) {
|
|
655
|
+
const prev = contextStack.slice();
|
|
656
|
+
contextStack.length = 0;
|
|
657
|
+
contextStack.push(...snapshot);
|
|
658
|
+
try {
|
|
659
|
+
return fn();
|
|
660
|
+
} finally {
|
|
661
|
+
contextStack.length = 0;
|
|
662
|
+
contextStack.push(...prev);
|
|
663
|
+
}
|
|
664
|
+
}
|
|
665
|
+
const Context = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
666
|
+
__proto__: null,
|
|
667
|
+
bindContext,
|
|
668
|
+
captureContext,
|
|
669
|
+
createContext,
|
|
670
|
+
readContext,
|
|
671
|
+
runInContext
|
|
672
|
+
}, Symbol.toStringTag, { value: "Module" }));
|
|
673
|
+
function isPromiseLike$1(v) {
|
|
674
|
+
return v && (typeof v === "object" || typeof v === "function") && typeof v.then === "function";
|
|
675
|
+
}
|
|
676
|
+
const SuspenseContext = createContext(null);
|
|
677
|
+
function lazy(loader) {
|
|
678
|
+
if (typeof loader !== "function") {
|
|
679
|
+
throw new Error("lazy(loader) expects a function that returns a Promise");
|
|
680
|
+
}
|
|
681
|
+
let status = "uninitialized";
|
|
682
|
+
let promise = null;
|
|
683
|
+
let component = null;
|
|
684
|
+
let error = null;
|
|
685
|
+
function pickComponent(mod) {
|
|
686
|
+
if (!mod) return null;
|
|
687
|
+
if (typeof mod === "function") return mod;
|
|
688
|
+
if (typeof mod.default === "function") return mod.default;
|
|
689
|
+
if (typeof mod.Counter === "function") return mod.Counter;
|
|
690
|
+
const fns = [];
|
|
691
|
+
for (const k of Object.keys(mod)) {
|
|
692
|
+
if (typeof mod[k] === "function") fns.push(mod[k]);
|
|
693
|
+
}
|
|
694
|
+
if (fns.length === 1) return fns[0];
|
|
695
|
+
return null;
|
|
696
|
+
}
|
|
697
|
+
return function LazyComponent(props = {}) {
|
|
698
|
+
if (status === "resolved") {
|
|
699
|
+
return createElement(component, props);
|
|
700
|
+
}
|
|
701
|
+
if (status === "rejected") {
|
|
702
|
+
throw error;
|
|
703
|
+
}
|
|
704
|
+
if (!promise) {
|
|
705
|
+
status = "pending";
|
|
706
|
+
try {
|
|
707
|
+
promise = Promise.resolve(loader()).then((mod) => {
|
|
708
|
+
const resolved = pickComponent(mod);
|
|
709
|
+
if (typeof resolved !== "function") {
|
|
710
|
+
throw new Error("lazy() loaded module does not export a component");
|
|
711
|
+
}
|
|
712
|
+
component = resolved;
|
|
713
|
+
status = "resolved";
|
|
714
|
+
}).catch((e) => {
|
|
715
|
+
error = e instanceof Error ? e : new Error(String(e));
|
|
716
|
+
status = "rejected";
|
|
717
|
+
});
|
|
718
|
+
} catch (e) {
|
|
719
|
+
error = e instanceof Error ? e : new Error(String(e));
|
|
720
|
+
status = "rejected";
|
|
721
|
+
throw error;
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
throw promise;
|
|
725
|
+
};
|
|
726
|
+
}
|
|
727
|
+
function Suspense(props = {}) {
|
|
728
|
+
const tick = signal(0);
|
|
729
|
+
const pending = /* @__PURE__ */ new Set();
|
|
730
|
+
const waiting = /* @__PURE__ */ new Set();
|
|
731
|
+
const child = Array.isArray(props.children) ? props.children[0] : props.children;
|
|
732
|
+
const childFn = typeof child === "function" ? child : () => child;
|
|
733
|
+
const register = (promise) => {
|
|
734
|
+
if (!waiting.has(promise)) {
|
|
735
|
+
waiting.add(promise);
|
|
736
|
+
pending.add(promise);
|
|
737
|
+
promise.then(
|
|
738
|
+
() => {
|
|
739
|
+
waiting.delete(promise);
|
|
740
|
+
pending.delete(promise);
|
|
741
|
+
tick(tick.peek() + 1);
|
|
742
|
+
},
|
|
743
|
+
() => {
|
|
744
|
+
waiting.delete(promise);
|
|
745
|
+
pending.delete(promise);
|
|
746
|
+
tick(tick.peek() + 1);
|
|
747
|
+
}
|
|
748
|
+
);
|
|
749
|
+
}
|
|
750
|
+
};
|
|
751
|
+
return createElement(SuspenseContext.Provider, {
|
|
752
|
+
value: { register }
|
|
753
|
+
}, () => {
|
|
754
|
+
tick();
|
|
755
|
+
if (pending.size > 0) {
|
|
756
|
+
return props.fallback ?? null;
|
|
757
|
+
}
|
|
758
|
+
try {
|
|
759
|
+
const res = childFn();
|
|
760
|
+
if (isPromiseLike$1(res)) {
|
|
761
|
+
register(res);
|
|
762
|
+
return props.fallback ?? null;
|
|
763
|
+
}
|
|
764
|
+
return res ?? null;
|
|
765
|
+
} catch (e) {
|
|
766
|
+
if (isPromiseLike$1(e)) {
|
|
767
|
+
register(e);
|
|
768
|
+
return props.fallback ?? null;
|
|
769
|
+
}
|
|
770
|
+
throw e;
|
|
771
|
+
}
|
|
772
|
+
});
|
|
773
|
+
}
|
|
774
|
+
const Suspense$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
775
|
+
__proto__: null,
|
|
776
|
+
Suspense,
|
|
777
|
+
SuspenseContext,
|
|
778
|
+
lazy
|
|
779
|
+
}, Symbol.toStringTag, { value: "Module" }));
|
|
780
|
+
const warnedSignals = /* @__PURE__ */ new Set();
|
|
781
|
+
function isPromiseLike(v) {
|
|
782
|
+
return v && (typeof v === "object" || typeof v === "function") && typeof v.then === "function";
|
|
783
|
+
}
|
|
784
|
+
function warnSignalDirectUsage(fn, kind) {
|
|
785
|
+
try {
|
|
786
|
+
if (typeof fn !== "function") return;
|
|
787
|
+
if (typeof fn.peek !== "function") return;
|
|
788
|
+
if (!("value" in fn)) return;
|
|
789
|
+
if (kind === "child") return;
|
|
790
|
+
if (typeof kind === "string" && kind.startsWith("prop:")) return;
|
|
791
|
+
const key = `${kind}:${fn.name ?? "signal"}`;
|
|
792
|
+
if (warnedSignals.has(key)) return;
|
|
793
|
+
warnedSignals.add(key);
|
|
794
|
+
console.warn(`[round] Prefer {signal()} (reactive) or {signal.value} (static). Direct {signal} usage is allowed but discouraged.`);
|
|
795
|
+
} catch {
|
|
796
|
+
}
|
|
797
|
+
}
|
|
798
|
+
function createElement(tag, props = {}, ...children) {
|
|
799
|
+
if (typeof tag === "function") {
|
|
800
|
+
const componentInstance = createComponentInstance();
|
|
801
|
+
const componentName = tag?.name ?? "Anonymous";
|
|
802
|
+
componentInstance.name = componentName;
|
|
803
|
+
let node = runInLifecycle(componentInstance, () => {
|
|
804
|
+
const componentProps = { ...props, children };
|
|
805
|
+
try {
|
|
806
|
+
const res = untrack(() => tag(componentProps));
|
|
807
|
+
if (isPromiseLike(res)) throw res;
|
|
808
|
+
return res;
|
|
809
|
+
} catch (e) {
|
|
810
|
+
if (isPromiseLike(e)) {
|
|
811
|
+
const suspense = readContext(SuspenseContext);
|
|
812
|
+
if (!suspense) {
|
|
813
|
+
throw new Error("cannot instance a lazy component outside a suspense");
|
|
814
|
+
}
|
|
815
|
+
throw e;
|
|
816
|
+
}
|
|
817
|
+
reportErrorSafe(e, { phase: "component.render", component: componentName });
|
|
818
|
+
return createElement("div", { style: { padding: "16px" } }, `Error in ${componentName}`);
|
|
819
|
+
}
|
|
820
|
+
});
|
|
821
|
+
if (Array.isArray(node)) {
|
|
822
|
+
const wrapper = document.createElement("span");
|
|
823
|
+
wrapper.style.display = "contents";
|
|
824
|
+
node.forEach((n) => appendChild(wrapper, n));
|
|
825
|
+
node = wrapper;
|
|
826
|
+
}
|
|
827
|
+
if (node instanceof Node) {
|
|
828
|
+
node._componentInstance = componentInstance;
|
|
829
|
+
componentInstance.nodes.push(node);
|
|
830
|
+
componentInstance.mountTimerId = setTimeout(() => {
|
|
831
|
+
componentInstance.mountTimerId = null;
|
|
832
|
+
mountComponent(componentInstance);
|
|
833
|
+
}, 0);
|
|
834
|
+
}
|
|
835
|
+
return node;
|
|
836
|
+
}
|
|
837
|
+
if (typeof tag === "string") {
|
|
838
|
+
const isCustomElement = tag.includes("-");
|
|
839
|
+
const isStandard = /^(a|abbr|address|area|article|aside|audio|b|base|bdi|bdo|blockquote|body|br|button|canvas|caption|cite|code|col|colgroup|data|datalist|dd|del|details|dfn|dialog|div|dl|dt|em|embed|fieldset|figcaption|figure|footer|form|h1|h2|h3|h4|h5|h6|head|header|hgroup|hr|html|i|iframe|img|input|ins|kbd|label|legend|li|link|main|map|mark|meta|meter|nav|noscript|object|ol|optgroup|option|output|p|param|picture|pre|progress|q|rp|rt|ruby|s|samp|script|search|section|select|slot|small|source|span|strong|style|sub|summary|sup|svg|table|tbody|td|template|textarea|tfoot|th|thead|time|title|tr|track|u|ul|var|video|wbr|menu|animate|animateMotion|animateTransform|circle|clipPath|defs|desc|ellipse|feBlend|feColorMatrix|feComponentTransfer|feComposite|feConvolveMatrix|feDiffuseLighting|feDisplacementMap|feDistantLight|feDropShadow|feFlood|feFuncA|feFuncB|feFuncG|feFuncR|feGaussianBlur|feImage|feMerge|feMergeNode|feMorphology|feOffset|fePointLight|feSpecularLighting|feSpotLight|feTile|feTurbulence|filter|foreignObject|g|image|line|linearGradient|marker|mask|metadata|mpath|path|pattern|polygon|polyline|radialGradient|rect|set|stop|switch|symbol|text|textPath|tspan|use|view)$/.test(tag);
|
|
840
|
+
const isCustomConfigured = typeof __ROUND_CUSTOM_TAGS__ !== "undefined" && __ROUND_CUSTOM_TAGS__.includes(tag);
|
|
841
|
+
if (!isCustomElement && !isStandard && !isCustomConfigured && /^[a-z]/.test(tag)) {
|
|
842
|
+
throw new Error(`Component names must start with an uppercase letter: <${tag} />`);
|
|
843
|
+
}
|
|
844
|
+
}
|
|
845
|
+
const element = document.createElement(tag);
|
|
846
|
+
if (props) {
|
|
847
|
+
Object.entries(props).forEach(([key, value]) => {
|
|
848
|
+
if (key === "bind:value" || key === "bind:checked") {
|
|
849
|
+
const isSignalLike2 = typeof value === "function" && typeof value.peek === "function" && "value" in value;
|
|
850
|
+
const isBindable = isSignalLike2 && value.bind === true;
|
|
851
|
+
if (!isSignalLike2) {
|
|
852
|
+
try {
|
|
853
|
+
console.warn("[round] bind:* expects a signal/bindable. Example: const name = bindable(''); <input bind:value={name} />");
|
|
854
|
+
} catch {
|
|
855
|
+
}
|
|
856
|
+
return;
|
|
857
|
+
}
|
|
858
|
+
if (!isBindable) {
|
|
859
|
+
try {
|
|
860
|
+
console.warn("[round] bind:* is intended to be used with bindable(). Plain signal() is accepted but discouraged.");
|
|
861
|
+
} catch {
|
|
862
|
+
}
|
|
863
|
+
}
|
|
864
|
+
const isValueBinding = key === "bind:value";
|
|
865
|
+
const isCheckedBinding = key === "bind:checked";
|
|
866
|
+
const el = element;
|
|
867
|
+
const tagName = String(el.tagName ?? "").toLowerCase();
|
|
868
|
+
const type = String(el.getAttribute?.("type") ?? "").toLowerCase();
|
|
869
|
+
const isInput = tagName === "input";
|
|
870
|
+
const isTextarea = tagName === "textarea";
|
|
871
|
+
const isSelect = tagName === "select";
|
|
872
|
+
if (isCheckedBinding && !(isInput && (type === "checkbox" || type === "radio"))) {
|
|
873
|
+
try {
|
|
874
|
+
console.warn(`[round] bind:checked is only supported on <input type="checkbox|radio">. Got <${tagName}${type ? ` type="${type}"` : ""}>.`);
|
|
875
|
+
} catch {
|
|
876
|
+
}
|
|
877
|
+
return;
|
|
878
|
+
}
|
|
879
|
+
if (isValueBinding && !(isInput || isTextarea || isSelect)) {
|
|
880
|
+
try {
|
|
881
|
+
console.warn(`[round] bind:value is only supported on <input>, <textarea>, and <select>. Got <${tagName}>.`);
|
|
882
|
+
} catch {
|
|
883
|
+
}
|
|
884
|
+
return;
|
|
885
|
+
}
|
|
886
|
+
const coerceFromDom = () => {
|
|
887
|
+
if (isCheckedBinding) {
|
|
888
|
+
if (type === "radio") {
|
|
889
|
+
return Boolean(el.checked);
|
|
890
|
+
}
|
|
891
|
+
return Boolean(el.checked);
|
|
892
|
+
}
|
|
893
|
+
if (isInput && type === "number") {
|
|
894
|
+
const raw = el.value;
|
|
895
|
+
if (raw === "") return "";
|
|
896
|
+
const n = Number(raw);
|
|
897
|
+
return Number.isFinite(n) ? n : raw;
|
|
898
|
+
}
|
|
899
|
+
if (isSelect && el.multiple) {
|
|
900
|
+
try {
|
|
901
|
+
return Array.from(el.selectedOptions ?? []).map((o) => o.value);
|
|
902
|
+
} catch {
|
|
903
|
+
return [];
|
|
904
|
+
}
|
|
905
|
+
}
|
|
906
|
+
return el.value;
|
|
907
|
+
};
|
|
908
|
+
const writeToDom = (v) => {
|
|
909
|
+
if (isCheckedBinding) {
|
|
910
|
+
const b = Boolean(v);
|
|
911
|
+
if (type === "radio") {
|
|
912
|
+
el.checked = b;
|
|
913
|
+
} else {
|
|
914
|
+
el.checked = b;
|
|
915
|
+
}
|
|
916
|
+
return;
|
|
917
|
+
}
|
|
918
|
+
if (isSelect && el.multiple) {
|
|
919
|
+
const arr = Array.isArray(v) ? v.map((x) => String(x)) : [];
|
|
920
|
+
try {
|
|
921
|
+
Array.from(el.options ?? []).forEach((opt) => {
|
|
922
|
+
opt.selected = arr.includes(opt.value);
|
|
923
|
+
});
|
|
924
|
+
} catch {
|
|
925
|
+
}
|
|
926
|
+
return;
|
|
927
|
+
}
|
|
928
|
+
el.value = v ?? "";
|
|
929
|
+
};
|
|
930
|
+
const warnTypeMismatch = (next) => {
|
|
931
|
+
try {
|
|
932
|
+
if (isCheckedBinding && typeof next !== "boolean") {
|
|
933
|
+
console.warn("[round] bind:checked expects a boolean signal value.");
|
|
934
|
+
}
|
|
935
|
+
if (isValueBinding && isSelect && el.multiple && !Array.isArray(next)) {
|
|
936
|
+
console.warn("[round] bind:value on <select multiple> expects an array signal value.");
|
|
937
|
+
}
|
|
938
|
+
if (isValueBinding && isInput && type === "number" && !(typeof next === "number" || typeof next === "string")) {
|
|
939
|
+
console.warn('[round] bind:value on <input type="number"> expects number|string (empty string allowed).');
|
|
940
|
+
}
|
|
941
|
+
} catch {
|
|
942
|
+
}
|
|
943
|
+
};
|
|
944
|
+
effect(() => {
|
|
945
|
+
const v = value();
|
|
946
|
+
warnTypeMismatch(v);
|
|
947
|
+
writeToDom(v);
|
|
948
|
+
}, { onLoad: false });
|
|
949
|
+
const validateOn = isValueBinding && value && typeof value === "function" ? value.__round_validateOn : null;
|
|
950
|
+
const valueEvent = validateOn === "blur" ? "blur" : isSelect ? "change" : "input";
|
|
951
|
+
const eventName = isCheckedBinding ? "change" : valueEvent;
|
|
952
|
+
el.addEventListener(eventName, (e) => {
|
|
953
|
+
try {
|
|
954
|
+
const target = e.currentTarget;
|
|
955
|
+
if (!target) return;
|
|
956
|
+
const next = coerceFromDom();
|
|
957
|
+
value(next);
|
|
958
|
+
} catch {
|
|
959
|
+
}
|
|
960
|
+
});
|
|
961
|
+
return;
|
|
962
|
+
}
|
|
963
|
+
if (key.startsWith("on") && typeof value === "function") {
|
|
964
|
+
element.addEventListener(key.toLowerCase().substring(2), value);
|
|
965
|
+
return;
|
|
966
|
+
}
|
|
967
|
+
if (key === "dangerouslySetInnerHTML") {
|
|
968
|
+
if (typeof value === "function") {
|
|
969
|
+
effect(() => {
|
|
970
|
+
const v = value();
|
|
971
|
+
if (v && typeof v === "object" && "__html" in v) {
|
|
972
|
+
element.innerHTML = v.__html ?? "";
|
|
973
|
+
}
|
|
974
|
+
}, { onLoad: false });
|
|
975
|
+
} else if (value && typeof value === "object" && "__html" in value) {
|
|
976
|
+
element.innerHTML = value.__html ?? "";
|
|
977
|
+
}
|
|
978
|
+
return;
|
|
979
|
+
}
|
|
980
|
+
if (key === "style") {
|
|
981
|
+
if (typeof value === "function") {
|
|
982
|
+
effect(() => {
|
|
983
|
+
const v = value();
|
|
984
|
+
if (v && typeof v === "object") {
|
|
985
|
+
Object.assign(element.style, v);
|
|
986
|
+
}
|
|
987
|
+
}, { onLoad: false });
|
|
988
|
+
return;
|
|
989
|
+
}
|
|
990
|
+
if (value && typeof value === "object") {
|
|
991
|
+
Object.assign(element.style, value);
|
|
992
|
+
return;
|
|
993
|
+
}
|
|
994
|
+
}
|
|
995
|
+
if (typeof value === "function") {
|
|
996
|
+
warnSignalDirectUsage(value, `prop:${key}`);
|
|
997
|
+
effect(() => {
|
|
998
|
+
const val = value();
|
|
999
|
+
if (key === "className") element.className = val;
|
|
1000
|
+
else if (key === "value") element.value = val;
|
|
1001
|
+
else if (key === "checked") element.checked = Boolean(val);
|
|
1002
|
+
else element.setAttribute(key, val);
|
|
1003
|
+
}, { onLoad: false });
|
|
1004
|
+
return;
|
|
1005
|
+
}
|
|
1006
|
+
if (key === "classList") {
|
|
1007
|
+
if (value && typeof value === "object") {
|
|
1008
|
+
Object.entries(value).forEach(([className, condition]) => {
|
|
1009
|
+
if (typeof condition === "function") {
|
|
1010
|
+
effect(() => {
|
|
1011
|
+
element.classList.toggle(className, !!condition());
|
|
1012
|
+
}, { onLoad: false });
|
|
1013
|
+
} else {
|
|
1014
|
+
element.classList.toggle(className, !!condition);
|
|
1015
|
+
}
|
|
1016
|
+
});
|
|
1017
|
+
}
|
|
1018
|
+
return;
|
|
1019
|
+
}
|
|
1020
|
+
if (key === "className") element.className = value;
|
|
1021
|
+
else if (key === "value") element.value = value;
|
|
1022
|
+
else if (key === "checked") element.checked = Boolean(value);
|
|
1023
|
+
else element.setAttribute(key, value);
|
|
1024
|
+
});
|
|
1025
|
+
}
|
|
1026
|
+
children.forEach((child) => appendChild(element, child));
|
|
1027
|
+
return element;
|
|
1028
|
+
}
|
|
1029
|
+
function appendChild(parent, child) {
|
|
1030
|
+
if (child === null || child === void 0) return;
|
|
1031
|
+
if (Array.isArray(child)) {
|
|
1032
|
+
child.forEach((c) => appendChild(parent, c));
|
|
1033
|
+
return;
|
|
1034
|
+
}
|
|
1035
|
+
if (typeof child === "string" || typeof child === "number") {
|
|
1036
|
+
parent.appendChild(document.createTextNode(child));
|
|
1037
|
+
return;
|
|
1038
|
+
}
|
|
1039
|
+
if (typeof child === "function") {
|
|
1040
|
+
warnSignalDirectUsage(child, "child");
|
|
1041
|
+
const placeholder = document.createTextNode("");
|
|
1042
|
+
parent.appendChild(placeholder);
|
|
1043
|
+
let currentNode = placeholder;
|
|
1044
|
+
const ctxSnapshot = captureContext();
|
|
1045
|
+
effect(() => {
|
|
1046
|
+
runInContext(ctxSnapshot, () => {
|
|
1047
|
+
let val;
|
|
1048
|
+
try {
|
|
1049
|
+
val = child();
|
|
1050
|
+
if (isPromiseLike(val)) throw val;
|
|
1051
|
+
} catch (e) {
|
|
1052
|
+
if (isPromiseLike(e)) {
|
|
1053
|
+
const suspense = readContext(SuspenseContext);
|
|
1054
|
+
if (suspense && typeof suspense.register === "function") {
|
|
1055
|
+
suspense.register(e);
|
|
1056
|
+
return;
|
|
1057
|
+
}
|
|
1058
|
+
throw new Error("cannot instance a lazy component outside a suspense");
|
|
1059
|
+
}
|
|
1060
|
+
reportErrorSafe(e, { phase: "child.dynamic" });
|
|
1061
|
+
val = createElement("div", { style: { padding: "16px" } }, "Error");
|
|
1062
|
+
}
|
|
1063
|
+
if (Array.isArray(val)) {
|
|
1064
|
+
if (!(currentNode instanceof Element) || !currentNode._roundArrayWrapper) {
|
|
1065
|
+
const wrapper = document.createElement("span");
|
|
1066
|
+
wrapper.style.display = "contents";
|
|
1067
|
+
wrapper._roundArrayWrapper = true;
|
|
1068
|
+
if (currentNode.parentNode) {
|
|
1069
|
+
currentNode.parentNode.replaceChild(wrapper, currentNode);
|
|
1070
|
+
currentNode = wrapper;
|
|
1071
|
+
}
|
|
1072
|
+
}
|
|
1073
|
+
while (currentNode.firstChild) currentNode.removeChild(currentNode.firstChild);
|
|
1074
|
+
val.forEach((v) => appendChild(currentNode, v));
|
|
1075
|
+
return;
|
|
1076
|
+
}
|
|
1077
|
+
if (val instanceof Node) {
|
|
1078
|
+
if (currentNode !== val) {
|
|
1079
|
+
if (currentNode.parentNode) {
|
|
1080
|
+
currentNode.parentNode.replaceChild(val, currentNode);
|
|
1081
|
+
currentNode = val;
|
|
1082
|
+
}
|
|
1083
|
+
}
|
|
1084
|
+
} else {
|
|
1085
|
+
const textContent = val === null || val === void 0 ? "" : val;
|
|
1086
|
+
if (currentNode instanceof Element) {
|
|
1087
|
+
const newText = document.createTextNode(textContent);
|
|
1088
|
+
if (currentNode.parentNode) {
|
|
1089
|
+
currentNode.parentNode.replaceChild(newText, currentNode);
|
|
1090
|
+
currentNode = newText;
|
|
1091
|
+
}
|
|
1092
|
+
} else {
|
|
1093
|
+
currentNode.textContent = textContent;
|
|
1094
|
+
}
|
|
1095
|
+
}
|
|
1096
|
+
});
|
|
1097
|
+
}, { onLoad: false });
|
|
1098
|
+
return;
|
|
1099
|
+
}
|
|
1100
|
+
if (child instanceof Node) {
|
|
1101
|
+
parent.appendChild(child);
|
|
1102
|
+
return;
|
|
1103
|
+
}
|
|
1104
|
+
}
|
|
1105
|
+
function Fragment(props) {
|
|
1106
|
+
return props.children;
|
|
1107
|
+
}
|
|
1108
|
+
const DOM = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
1109
|
+
__proto__: null,
|
|
1110
|
+
Fragment,
|
|
1111
|
+
createElement
|
|
1112
|
+
}, Symbol.toStringTag, { value: "Module" }));
|
|
1113
|
+
const hasWindow$1 = typeof window !== "undefined" && typeof document !== "undefined";
|
|
1114
|
+
const ROUTING_TRAILING_SLASH = typeof __ROUND_ROUTING_TRAILING_SLASH__ !== "undefined" ? Boolean(__ROUND_ROUTING_TRAILING_SLASH__) : true;
|
|
1115
|
+
const currentPath = signal(hasWindow$1 ? window.location.pathname : "/");
|
|
1116
|
+
let listenerInitialized = false;
|
|
1117
|
+
let lastPathEvaluated = null;
|
|
1118
|
+
const pathHasMatch = signal(false);
|
|
1119
|
+
const pathEvalReady = signal(true);
|
|
1120
|
+
let defaultNotFoundComponent = null;
|
|
1121
|
+
let autoNotFoundMounted = false;
|
|
1122
|
+
let userProvidedNotFound = false;
|
|
1123
|
+
function ensureListener() {
|
|
1124
|
+
if (!hasWindow$1 || listenerInitialized) return;
|
|
1125
|
+
listenerInitialized = true;
|
|
1126
|
+
mountAutoNotFound();
|
|
1127
|
+
window.addEventListener("popstate", () => {
|
|
1128
|
+
currentPath(window.location.pathname);
|
|
1129
|
+
});
|
|
1130
|
+
}
|
|
1131
|
+
function getPathname() {
|
|
1132
|
+
return normalizePathname(currentPath());
|
|
1133
|
+
}
|
|
1134
|
+
function usePathname() {
|
|
1135
|
+
return () => normalizePathname(currentPath());
|
|
1136
|
+
}
|
|
1137
|
+
function getLocation() {
|
|
1138
|
+
if (!hasWindow$1) {
|
|
1139
|
+
return { pathname: normalizePathname("/"), search: "", hash: "" };
|
|
1140
|
+
}
|
|
1141
|
+
return {
|
|
1142
|
+
pathname: normalizePathname(window.location.pathname),
|
|
1143
|
+
search: window.location.search ?? "",
|
|
1144
|
+
hash: window.location.hash ?? ""
|
|
1145
|
+
};
|
|
1146
|
+
}
|
|
1147
|
+
function useLocation() {
|
|
1148
|
+
return () => {
|
|
1149
|
+
const pathname = normalizePathname(currentPath());
|
|
1150
|
+
if (!hasWindow$1) return { pathname, search: "", hash: "" };
|
|
1151
|
+
return { pathname, search: window.location.search ?? "", hash: window.location.hash ?? "" };
|
|
1152
|
+
};
|
|
1153
|
+
}
|
|
1154
|
+
function getRouteReady() {
|
|
1155
|
+
const pathname = normalizePathname(currentPath());
|
|
1156
|
+
return Boolean(pathEvalReady()) && lastPathEvaluated === pathname;
|
|
1157
|
+
}
|
|
1158
|
+
function useRouteReady() {
|
|
1159
|
+
return () => {
|
|
1160
|
+
const pathname = normalizePathname(currentPath());
|
|
1161
|
+
return Boolean(pathEvalReady()) && lastPathEvaluated === pathname;
|
|
1162
|
+
};
|
|
1163
|
+
}
|
|
1164
|
+
function getIsNotFound() {
|
|
1165
|
+
const pathname = normalizePathname(currentPath());
|
|
1166
|
+
if (!(Boolean(pathEvalReady()) && lastPathEvaluated === pathname)) return false;
|
|
1167
|
+
return !Boolean(pathHasMatch());
|
|
1168
|
+
}
|
|
1169
|
+
function useIsNotFound() {
|
|
1170
|
+
return () => {
|
|
1171
|
+
const pathname = normalizePathname(currentPath());
|
|
1172
|
+
if (!(Boolean(pathEvalReady()) && lastPathEvaluated === pathname)) return false;
|
|
1173
|
+
return !Boolean(pathHasMatch());
|
|
1174
|
+
};
|
|
1175
|
+
}
|
|
1176
|
+
function mountAutoNotFound() {
|
|
1177
|
+
if (!hasWindow$1 || autoNotFoundMounted) return;
|
|
1178
|
+
autoNotFoundMounted = true;
|
|
1179
|
+
const host = document.getElementById("app") ?? document.body;
|
|
1180
|
+
const root = document.createElement("div");
|
|
1181
|
+
root.setAttribute("data-round-auto-notfound", "1");
|
|
1182
|
+
host.appendChild(root);
|
|
1183
|
+
const view = createElement("span", { style: { display: "contents" } }, () => {
|
|
1184
|
+
if (userProvidedNotFound) return null;
|
|
1185
|
+
const pathname = normalizePathname(currentPath());
|
|
1186
|
+
const ready = pathEvalReady();
|
|
1187
|
+
const hasMatch = pathHasMatch();
|
|
1188
|
+
if (!ready) return null;
|
|
1189
|
+
if (lastPathEvaluated !== pathname) return null;
|
|
1190
|
+
if (hasMatch) return null;
|
|
1191
|
+
const Comp = defaultNotFoundComponent;
|
|
1192
|
+
if (typeof Comp === "function") {
|
|
1193
|
+
return createElement(Comp, { pathname });
|
|
1194
|
+
}
|
|
1195
|
+
return createElement(
|
|
1196
|
+
"div",
|
|
1197
|
+
{ style: { padding: "16px" } },
|
|
1198
|
+
createElement("h1", null, "404"),
|
|
1199
|
+
createElement("p", null, "Page not found: ", pathname)
|
|
1200
|
+
);
|
|
1201
|
+
});
|
|
1202
|
+
root.appendChild(view);
|
|
1203
|
+
}
|
|
1204
|
+
function navigate(to, options = {}) {
|
|
1205
|
+
if (!hasWindow$1) return;
|
|
1206
|
+
ensureListener();
|
|
1207
|
+
const normalizedTo = normalizeTo(to);
|
|
1208
|
+
const replace = Boolean(options.replace);
|
|
1209
|
+
if (replace) window.history.replaceState({}, "", normalizedTo);
|
|
1210
|
+
else window.history.pushState({}, "", normalizedTo);
|
|
1211
|
+
currentPath(window.location.pathname);
|
|
1212
|
+
}
|
|
1213
|
+
function applyHead({ title, meta, links, icon, favicon }) {
|
|
1214
|
+
if (!hasWindow$1) return;
|
|
1215
|
+
if (typeof title === "string") {
|
|
1216
|
+
document.title = title;
|
|
1217
|
+
}
|
|
1218
|
+
document.querySelectorAll('[data-round-head="1"]').forEach((n) => n.remove());
|
|
1219
|
+
const iconHref = icon ?? favicon;
|
|
1220
|
+
if (typeof iconHref === "string" && iconHref.length) {
|
|
1221
|
+
const el = document.createElement("link");
|
|
1222
|
+
el.setAttribute("data-round-head", "1");
|
|
1223
|
+
el.setAttribute("rel", "icon");
|
|
1224
|
+
el.setAttribute("href", iconHref);
|
|
1225
|
+
document.head.appendChild(el);
|
|
1226
|
+
}
|
|
1227
|
+
if (Array.isArray(links)) {
|
|
1228
|
+
links.forEach((l) => {
|
|
1229
|
+
if (!l || typeof l !== "object") return;
|
|
1230
|
+
const el = document.createElement("link");
|
|
1231
|
+
el.setAttribute("data-round-head", "1");
|
|
1232
|
+
Object.entries(l).forEach(([k, v]) => {
|
|
1233
|
+
if (v === null || v === void 0) return;
|
|
1234
|
+
el.setAttribute(k, String(v));
|
|
1235
|
+
});
|
|
1236
|
+
document.head.appendChild(el);
|
|
1237
|
+
});
|
|
1238
|
+
}
|
|
1239
|
+
if (Array.isArray(meta)) {
|
|
1240
|
+
meta.forEach((entry) => {
|
|
1241
|
+
if (!entry) return;
|
|
1242
|
+
const el = document.createElement("meta");
|
|
1243
|
+
el.setAttribute("data-round-head", "1");
|
|
1244
|
+
if (Array.isArray(entry) && entry.length >= 2) {
|
|
1245
|
+
const [name, content] = entry;
|
|
1246
|
+
if (typeof name === "string") el.setAttribute("name", name);
|
|
1247
|
+
el.setAttribute("content", String(content ?? ""));
|
|
1248
|
+
} else if (typeof entry === "object") {
|
|
1249
|
+
Object.entries(entry).forEach(([k, v]) => {
|
|
1250
|
+
if (v === null || v === void 0) return;
|
|
1251
|
+
el.setAttribute(k, String(v));
|
|
1252
|
+
});
|
|
1253
|
+
} else {
|
|
1254
|
+
return;
|
|
1255
|
+
}
|
|
1256
|
+
document.head.appendChild(el);
|
|
1257
|
+
});
|
|
1258
|
+
} else if (meta && typeof meta === "object") {
|
|
1259
|
+
Object.entries(meta).forEach(([name, content]) => {
|
|
1260
|
+
if (typeof name !== "string") return;
|
|
1261
|
+
const el = document.createElement("meta");
|
|
1262
|
+
el.setAttribute("data-round-head", "1");
|
|
1263
|
+
el.setAttribute("name", name);
|
|
1264
|
+
el.setAttribute("content", String(content ?? ""));
|
|
1265
|
+
document.head.appendChild(el);
|
|
1266
|
+
});
|
|
1267
|
+
}
|
|
1268
|
+
}
|
|
1269
|
+
function startHead(_head) {
|
|
1270
|
+
return _head;
|
|
1271
|
+
}
|
|
1272
|
+
function splitUrl(url) {
|
|
1273
|
+
const str = String(url ?? "");
|
|
1274
|
+
const hashIdx = str.indexOf("#");
|
|
1275
|
+
const queryIdx = str.indexOf("?");
|
|
1276
|
+
const cutIdx = hashIdx === -1 ? queryIdx : queryIdx === -1 ? hashIdx : Math.min(hashIdx, queryIdx);
|
|
1277
|
+
if (cutIdx === -1) return { path: str, suffix: "" };
|
|
1278
|
+
return { path: str.slice(0, cutIdx), suffix: str.slice(cutIdx) };
|
|
1279
|
+
}
|
|
1280
|
+
function normalizePathname(p) {
|
|
1281
|
+
let pathname = String(p ?? "/");
|
|
1282
|
+
if (!pathname.startsWith("/")) pathname = "/" + pathname;
|
|
1283
|
+
if (pathname.length > 1) {
|
|
1284
|
+
if (ROUTING_TRAILING_SLASH) {
|
|
1285
|
+
if (!pathname.endsWith("/")) pathname += "/";
|
|
1286
|
+
} else {
|
|
1287
|
+
if (pathname.endsWith("/")) pathname = pathname.slice(0, -1);
|
|
1288
|
+
}
|
|
1289
|
+
}
|
|
1290
|
+
return pathname;
|
|
1291
|
+
}
|
|
1292
|
+
function normalizeTo(to) {
|
|
1293
|
+
const { path, suffix } = splitUrl(to);
|
|
1294
|
+
if (!path.startsWith("/")) return String(to ?? "");
|
|
1295
|
+
return normalizePathname(path) + suffix;
|
|
1296
|
+
}
|
|
1297
|
+
function matchRoute(route, pathname) {
|
|
1298
|
+
const r = normalizePathname(route);
|
|
1299
|
+
const p = normalizePathname(pathname);
|
|
1300
|
+
return r === p;
|
|
1301
|
+
}
|
|
1302
|
+
function beginPathEvaluation(pathname) {
|
|
1303
|
+
if (pathname !== lastPathEvaluated) {
|
|
1304
|
+
lastPathEvaluated = pathname;
|
|
1305
|
+
pathHasMatch(false);
|
|
1306
|
+
pathEvalReady(false);
|
|
1307
|
+
setTimeout(() => {
|
|
1308
|
+
if (lastPathEvaluated !== pathname) return;
|
|
1309
|
+
pathEvalReady(true);
|
|
1310
|
+
}, 0);
|
|
1311
|
+
}
|
|
1312
|
+
}
|
|
1313
|
+
function setNotFound(Component) {
|
|
1314
|
+
defaultNotFoundComponent = Component;
|
|
1315
|
+
}
|
|
1316
|
+
function Route(props = {}) {
|
|
1317
|
+
ensureListener();
|
|
1318
|
+
return createElement("span", { style: { display: "contents" } }, () => {
|
|
1319
|
+
const pathname = normalizePathname(currentPath());
|
|
1320
|
+
beginPathEvaluation(pathname);
|
|
1321
|
+
const route = props.route ?? "/";
|
|
1322
|
+
if (!matchRoute(route, pathname)) return null;
|
|
1323
|
+
pathHasMatch(true);
|
|
1324
|
+
const mergedHead = props.head && typeof props.head === "object" ? props.head : {};
|
|
1325
|
+
const meta = props.description ? [{ name: "description", content: String(props.description) }].concat(mergedHead.meta ?? props.meta ?? []) : mergedHead.meta ?? props.meta;
|
|
1326
|
+
const links = mergedHead.links ?? props.links;
|
|
1327
|
+
const title = mergedHead.title ?? props.title;
|
|
1328
|
+
const icon = mergedHead.icon ?? props.icon;
|
|
1329
|
+
const favicon = mergedHead.favicon ?? props.favicon;
|
|
1330
|
+
applyHead({ title, meta, links, icon, favicon });
|
|
1331
|
+
return props.children;
|
|
1332
|
+
});
|
|
1333
|
+
}
|
|
1334
|
+
function Page(props = {}) {
|
|
1335
|
+
ensureListener();
|
|
1336
|
+
return createElement("span", { style: { display: "contents" } }, () => {
|
|
1337
|
+
const pathname = normalizePathname(currentPath());
|
|
1338
|
+
beginPathEvaluation(pathname);
|
|
1339
|
+
const route = props.route ?? "/";
|
|
1340
|
+
if (!matchRoute(route, pathname)) return null;
|
|
1341
|
+
pathHasMatch(true);
|
|
1342
|
+
const mergedHead = props.head && typeof props.head === "object" ? props.head : {};
|
|
1343
|
+
const meta = props.description ? [{ name: "description", content: String(props.description) }].concat(mergedHead.meta ?? props.meta ?? []) : mergedHead.meta ?? props.meta;
|
|
1344
|
+
const links = mergedHead.links ?? props.links;
|
|
1345
|
+
const title = mergedHead.title ?? props.title;
|
|
1346
|
+
const icon = mergedHead.icon ?? props.icon;
|
|
1347
|
+
const favicon = mergedHead.favicon ?? props.favicon;
|
|
1348
|
+
applyHead({ title, meta, links, icon, favicon });
|
|
1349
|
+
return props.children;
|
|
1350
|
+
});
|
|
1351
|
+
}
|
|
1352
|
+
function NotFound(props = {}) {
|
|
1353
|
+
ensureListener();
|
|
1354
|
+
userProvidedNotFound = true;
|
|
1355
|
+
return createElement("span", { style: { display: "contents" } }, () => {
|
|
1356
|
+
const pathname = normalizePathname(currentPath());
|
|
1357
|
+
beginPathEvaluation(pathname);
|
|
1358
|
+
const ready = pathEvalReady();
|
|
1359
|
+
const hasMatch = pathHasMatch();
|
|
1360
|
+
if (!ready) return null;
|
|
1361
|
+
if (lastPathEvaluated !== pathname) return null;
|
|
1362
|
+
if (hasMatch) return null;
|
|
1363
|
+
const Comp = props.component ?? defaultNotFoundComponent;
|
|
1364
|
+
if (typeof Comp === "function") {
|
|
1365
|
+
return createElement(Comp, { pathname });
|
|
1366
|
+
}
|
|
1367
|
+
if (props.children !== void 0) return props.children;
|
|
1368
|
+
return createElement(
|
|
1369
|
+
"div",
|
|
1370
|
+
{ style: { padding: "16px" } },
|
|
1371
|
+
createElement("h1", null, "404"),
|
|
1372
|
+
createElement("p", null, "Page not found: ", pathname)
|
|
1373
|
+
);
|
|
1374
|
+
});
|
|
1375
|
+
}
|
|
1376
|
+
function Link(props = {}) {
|
|
1377
|
+
ensureListener();
|
|
1378
|
+
const rawHref = props.href ?? props.to ?? "#";
|
|
1379
|
+
const href = spaNormalizeHref(rawHref);
|
|
1380
|
+
const spa = props.spa !== void 0 ? Boolean(props.spa) : true;
|
|
1381
|
+
const reload = Boolean(props.reload);
|
|
1382
|
+
const onClick = (e) => {
|
|
1383
|
+
if (typeof props.onClick === "function") props.onClick(e);
|
|
1384
|
+
if (e.defaultPrevented) return;
|
|
1385
|
+
if (!spa || reload) return;
|
|
1386
|
+
if (e.button !== 0) return;
|
|
1387
|
+
if (e.metaKey || e.ctrlKey || e.shiftKey || e.altKey) return;
|
|
1388
|
+
e.preventDefault();
|
|
1389
|
+
navigate(href);
|
|
1390
|
+
};
|
|
1391
|
+
const { children, to, ...rest } = props;
|
|
1392
|
+
const normalizedChildren = Array.isArray(children) ? children : children === void 0 || children === null ? [] : [children];
|
|
1393
|
+
return createElement("a", { ...rest, href, onClick }, ...normalizedChildren);
|
|
1394
|
+
}
|
|
1395
|
+
function spaNormalizeHref(href) {
|
|
1396
|
+
const str = String(href ?? "#");
|
|
1397
|
+
if (!str.startsWith("/")) return str;
|
|
1398
|
+
return normalizeTo(str);
|
|
1399
|
+
}
|
|
1400
|
+
const Router = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
1401
|
+
__proto__: null,
|
|
1402
|
+
Link,
|
|
1403
|
+
NotFound,
|
|
1404
|
+
Page,
|
|
1405
|
+
Route,
|
|
1406
|
+
getIsNotFound,
|
|
1407
|
+
getLocation,
|
|
1408
|
+
getPathname,
|
|
1409
|
+
getRouteReady,
|
|
1410
|
+
navigate,
|
|
1411
|
+
setNotFound,
|
|
1412
|
+
startHead,
|
|
1413
|
+
useIsNotFound,
|
|
1414
|
+
useLocation,
|
|
1415
|
+
usePathname,
|
|
1416
|
+
useRouteReady
|
|
1417
|
+
}, Symbol.toStringTag, { value: "Module" }));
|
|
1418
|
+
const mdLoaders = typeof import.meta !== "undefined" && typeof import.meta.glob === "function" ? /* @__PURE__ */ Object.assign({}) : {};
|
|
1419
|
+
function Markdown(props = {}) {
|
|
1420
|
+
const html = signal("");
|
|
1421
|
+
const parse = (md) => {
|
|
1422
|
+
try {
|
|
1423
|
+
return marked.parse(md ?? "");
|
|
1424
|
+
} catch {
|
|
1425
|
+
return "";
|
|
1426
|
+
}
|
|
1427
|
+
};
|
|
1428
|
+
if (typeof props.content === "string") {
|
|
1429
|
+
html(parse(props.content));
|
|
1430
|
+
}
|
|
1431
|
+
onMount(async () => {
|
|
1432
|
+
if (typeof props.src !== "string") return;
|
|
1433
|
+
const base = typeof props.base === "string" ? props.base : "/src";
|
|
1434
|
+
const resolved = props.src.startsWith("./") ? base + props.src.slice(1) : props.src;
|
|
1435
|
+
const loader = mdLoaders[resolved];
|
|
1436
|
+
if (typeof loader === "function") {
|
|
1437
|
+
try {
|
|
1438
|
+
const text = await loader();
|
|
1439
|
+
html(parse(text ?? ""));
|
|
1440
|
+
return;
|
|
1441
|
+
} catch (e) {
|
|
1442
|
+
reportErrorSafe(e instanceof Error ? e : new Error(`Failed to load markdown: ${resolved}`), { phase: "markdown.load", component: "Markdown" });
|
|
1443
|
+
html("");
|
|
1444
|
+
return;
|
|
1445
|
+
}
|
|
1446
|
+
}
|
|
1447
|
+
try {
|
|
1448
|
+
const r = await fetch(resolved);
|
|
1449
|
+
if (!r.ok) {
|
|
1450
|
+
reportErrorSafe(new Error(`Markdown not found: ${resolved} (HTTP ${r.status})`), { phase: "markdown.fetch", component: "Markdown" });
|
|
1451
|
+
html("");
|
|
1452
|
+
return;
|
|
1453
|
+
}
|
|
1454
|
+
const text = await r.text();
|
|
1455
|
+
const looksLikeHtml = /^\s*<!doctype\s+html\b|^\s*<html\b/i.test(text);
|
|
1456
|
+
if (looksLikeHtml) {
|
|
1457
|
+
reportErrorSafe(new Error(`Markdown not found (served HTML fallback): ${resolved}`), { phase: "markdown.fetch", component: "Markdown" });
|
|
1458
|
+
html("");
|
|
1459
|
+
return;
|
|
1460
|
+
}
|
|
1461
|
+
html(parse(text));
|
|
1462
|
+
} catch (e) {
|
|
1463
|
+
reportErrorSafe(e instanceof Error ? e : new Error(`Failed to fetch markdown: ${resolved}`), { phase: "markdown.fetch", component: "Markdown" });
|
|
1464
|
+
html("");
|
|
1465
|
+
}
|
|
1466
|
+
});
|
|
1467
|
+
const className = props.className ?? props.theme ?? "";
|
|
1468
|
+
return createElement("div", {
|
|
1469
|
+
className,
|
|
1470
|
+
dangerouslySetInnerHTML: () => ({ __html: html() })
|
|
1471
|
+
});
|
|
1472
|
+
}
|
|
1473
|
+
const Markdown$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
1474
|
+
__proto__: null,
|
|
1475
|
+
Markdown
|
|
1476
|
+
}, Symbol.toStringTag, { value: "Module" }));
|
|
1477
|
+
const errors = signal([]);
|
|
1478
|
+
let lastSentKey = null;
|
|
1479
|
+
let lastSentAt = 0;
|
|
1480
|
+
let lastStoredKey = null;
|
|
1481
|
+
let lastStoredAt = 0;
|
|
1482
|
+
function reportError(error, info = {}) {
|
|
1483
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
1484
|
+
const stack = err.stack ? String(err.stack) : "";
|
|
1485
|
+
const message = err.message;
|
|
1486
|
+
const phase = info.phase ?? null;
|
|
1487
|
+
const component = info.component ?? null;
|
|
1488
|
+
const key = `${message}|${component ?? ""}|${phase ?? ""}|${stack}`;
|
|
1489
|
+
const now = Date.now();
|
|
1490
|
+
if (lastStoredKey === key && now - lastStoredAt < 1500) {
|
|
1491
|
+
return;
|
|
1492
|
+
}
|
|
1493
|
+
lastStoredKey = key;
|
|
1494
|
+
lastStoredAt = now;
|
|
1495
|
+
const entry = {
|
|
1496
|
+
error: err,
|
|
1497
|
+
message,
|
|
1498
|
+
stack,
|
|
1499
|
+
phase,
|
|
1500
|
+
component,
|
|
1501
|
+
time: now
|
|
1502
|
+
};
|
|
1503
|
+
const current = typeof errors.peek === "function" ? errors.peek() : errors();
|
|
1504
|
+
errors([entry, ...Array.isArray(current) ? current : []]);
|
|
1505
|
+
try {
|
|
1506
|
+
const where = entry.component ? ` in ${entry.component}` : "";
|
|
1507
|
+
const phase2 = entry.phase ? ` (${entry.phase})` : "";
|
|
1508
|
+
const label = `[round] Runtime error${where}${phase2}`;
|
|
1509
|
+
if (typeof console.groupCollapsed === "function") {
|
|
1510
|
+
console.groupCollapsed(label);
|
|
1511
|
+
console.error(entry.error);
|
|
1512
|
+
if (entry.stack) console.log(entry.stack);
|
|
1513
|
+
if (info && Object.keys(info).length) console.log("info:", info);
|
|
1514
|
+
console.groupEnd();
|
|
1515
|
+
} else {
|
|
1516
|
+
console.error(label);
|
|
1517
|
+
console.error(entry.error);
|
|
1518
|
+
if (entry.stack) console.log(entry.stack);
|
|
1519
|
+
if (info && Object.keys(info).length) console.log("info:", info);
|
|
1520
|
+
}
|
|
1521
|
+
} catch {
|
|
1522
|
+
}
|
|
1523
|
+
try {
|
|
1524
|
+
if (void 0) ;
|
|
1525
|
+
} catch {
|
|
1526
|
+
}
|
|
1527
|
+
}
|
|
1528
|
+
function clearErrors() {
|
|
1529
|
+
errors([]);
|
|
1530
|
+
}
|
|
1531
|
+
function useErrors() {
|
|
1532
|
+
return errors;
|
|
1533
|
+
}
|
|
1534
|
+
setErrorReporter(reportError);
|
|
1535
|
+
function ErrorProvider(props = {}) {
|
|
1536
|
+
return createElement("span", { style: { display: "contents" } }, () => {
|
|
1537
|
+
const list = useErrors()();
|
|
1538
|
+
if (!Array.isArray(list) || list.length === 0) return props.children ?? null;
|
|
1539
|
+
const first = list[0];
|
|
1540
|
+
return createElement(
|
|
1541
|
+
"div",
|
|
1542
|
+
{
|
|
1543
|
+
style: {
|
|
1544
|
+
position: "fixed",
|
|
1545
|
+
inset: "0",
|
|
1546
|
+
zIndex: 2147483647,
|
|
1547
|
+
display: "flex",
|
|
1548
|
+
alignItems: "center",
|
|
1549
|
+
justifyContent: "center",
|
|
1550
|
+
padding: "24px",
|
|
1551
|
+
background: "rgba(17, 24, 39, 0.72)",
|
|
1552
|
+
backdropFilter: "blur(10px)",
|
|
1553
|
+
WebkitBackdropFilter: "blur(10px)"
|
|
1554
|
+
}
|
|
1555
|
+
},
|
|
1556
|
+
createElement(
|
|
1557
|
+
"div",
|
|
1558
|
+
{
|
|
1559
|
+
style: {
|
|
1560
|
+
width: "min(900px, 100%)",
|
|
1561
|
+
borderRadius: "14px",
|
|
1562
|
+
border: "1px solid rgba(255,255,255,0.12)",
|
|
1563
|
+
background: "rgba(0,0,0,0.55)",
|
|
1564
|
+
boxShadow: "0 30px 80px rgba(0,0,0,0.55)",
|
|
1565
|
+
color: "#fff",
|
|
1566
|
+
overflow: "hidden"
|
|
1567
|
+
}
|
|
1568
|
+
},
|
|
1569
|
+
createElement(
|
|
1570
|
+
"div",
|
|
1571
|
+
{
|
|
1572
|
+
style: {
|
|
1573
|
+
padding: "14px 16px",
|
|
1574
|
+
display: "flex",
|
|
1575
|
+
alignItems: "center",
|
|
1576
|
+
gap: "10px",
|
|
1577
|
+
borderBottom: "1px solid rgba(255,255,255,0.10)",
|
|
1578
|
+
background: "linear-gradient(180deg, rgba(255,255,255,0.06), rgba(255,255,255,0))"
|
|
1579
|
+
}
|
|
1580
|
+
},
|
|
1581
|
+
createElement("div", {
|
|
1582
|
+
style: {
|
|
1583
|
+
width: "10px",
|
|
1584
|
+
height: "10px",
|
|
1585
|
+
borderRadius: "999px",
|
|
1586
|
+
background: "#ef4444",
|
|
1587
|
+
boxShadow: "0 0 0 4px rgba(239,68,68,0.18)"
|
|
1588
|
+
}
|
|
1589
|
+
}),
|
|
1590
|
+
createElement("strong", { style: { fontFamily: "ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Arial" } }, "Round Error"),
|
|
1591
|
+
createElement("span", { style: { opacity: 0.75, fontFamily: "ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Arial", fontSize: "12px" } }, new Date(first.time).toLocaleString()),
|
|
1592
|
+
createElement("button", {
|
|
1593
|
+
style: {
|
|
1594
|
+
marginLeft: "auto",
|
|
1595
|
+
border: "1px solid rgba(255,255,255,0.16)",
|
|
1596
|
+
background: "rgba(255,255,255,0.08)",
|
|
1597
|
+
color: "#fff",
|
|
1598
|
+
padding: "8px 10px",
|
|
1599
|
+
borderRadius: "10px",
|
|
1600
|
+
cursor: "pointer"
|
|
1601
|
+
},
|
|
1602
|
+
onMouseOver: (e) => {
|
|
1603
|
+
try {
|
|
1604
|
+
e.currentTarget.style.background = "rgba(255,255,255,0.12)";
|
|
1605
|
+
} catch {
|
|
1606
|
+
}
|
|
1607
|
+
},
|
|
1608
|
+
onMouseOut: (e) => {
|
|
1609
|
+
try {
|
|
1610
|
+
e.currentTarget.style.background = "rgba(255,255,255,0.08)";
|
|
1611
|
+
} catch {
|
|
1612
|
+
}
|
|
1613
|
+
},
|
|
1614
|
+
onClick: () => clearErrors()
|
|
1615
|
+
}, "Dismiss")
|
|
1616
|
+
),
|
|
1617
|
+
createElement(
|
|
1618
|
+
"div",
|
|
1619
|
+
{
|
|
1620
|
+
style: {
|
|
1621
|
+
padding: "16px",
|
|
1622
|
+
fontFamily: 'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace'
|
|
1623
|
+
}
|
|
1624
|
+
},
|
|
1625
|
+
createElement("div", { style: { fontSize: "14px", fontWeight: "700" } }, String(first.message ?? "Error")),
|
|
1626
|
+
createElement(
|
|
1627
|
+
"div",
|
|
1628
|
+
{ style: { marginTop: "10px", opacity: 0.85, fontSize: "12px", lineHeight: "18px" } },
|
|
1629
|
+
first.component ? createElement("div", null, createElement("span", { style: { opacity: 0.75 } }, "Component: "), String(first.component)) : null,
|
|
1630
|
+
first.phase ? createElement("div", null, createElement("span", { style: { opacity: 0.75 } }, "Phase: "), String(first.phase)) : null
|
|
1631
|
+
),
|
|
1632
|
+
first.stack ? createElement("pre", {
|
|
1633
|
+
style: {
|
|
1634
|
+
marginTop: "12px",
|
|
1635
|
+
padding: "12px",
|
|
1636
|
+
borderRadius: "12px",
|
|
1637
|
+
background: "rgba(0,0,0,0.55)",
|
|
1638
|
+
border: "1px solid rgba(255,255,255,0.10)",
|
|
1639
|
+
whiteSpace: "pre-wrap",
|
|
1640
|
+
fontSize: "12px",
|
|
1641
|
+
lineHeight: "18px",
|
|
1642
|
+
overflow: "auto",
|
|
1643
|
+
maxHeight: "55vh"
|
|
1644
|
+
}
|
|
1645
|
+
}, String(first.stack)) : null
|
|
1646
|
+
)
|
|
1647
|
+
)
|
|
1648
|
+
);
|
|
1649
|
+
});
|
|
1650
|
+
}
|
|
1651
|
+
function initErrorHandling(container) {
|
|
1652
|
+
if (typeof document === "undefined") return;
|
|
1653
|
+
if (!container || !(container instanceof Element)) return;
|
|
1654
|
+
if (!document.querySelector('[data-round-error-style="1"]')) {
|
|
1655
|
+
const style = document.createElement("style");
|
|
1656
|
+
style.setAttribute("data-round-error-style", "1");
|
|
1657
|
+
style.textContent = `
|
|
1658
|
+
[data-round-error-root="1"] pre{scrollbar-width:thin;scrollbar-color:rgba(255,255,255,0.28) rgba(255,255,255,0.06);}
|
|
1659
|
+
[data-round-error-root="1"] pre::-webkit-scrollbar{width:10px;height:10px;}
|
|
1660
|
+
[data-round-error-root="1"] pre::-webkit-scrollbar-track{background:rgba(255,255,255,0.06);border-radius:999px;}
|
|
1661
|
+
[data-round-error-root="1"] pre::-webkit-scrollbar-thumb{background:rgba(255,255,255,0.22);border-radius:999px;border:2px solid rgba(0,0,0,0.35);}
|
|
1662
|
+
[data-round-error-root="1"] pre::-webkit-scrollbar-thumb:hover{background:rgba(255,255,255,0.32);}
|
|
1663
|
+
`.trim();
|
|
1664
|
+
document.head.appendChild(style);
|
|
1665
|
+
}
|
|
1666
|
+
if (!document.querySelector('[data-round-error-root="1"]')) {
|
|
1667
|
+
const root = document.createElement("div");
|
|
1668
|
+
root.setAttribute("data-round-error-root", "1");
|
|
1669
|
+
container.appendChild(root);
|
|
1670
|
+
root.appendChild(createElement(ErrorProvider, null));
|
|
1671
|
+
}
|
|
1672
|
+
if (!window.__round_error_handlers_installed) {
|
|
1673
|
+
window.__round_error_handlers_installed = true;
|
|
1674
|
+
window.addEventListener("error", (e) => {
|
|
1675
|
+
reportError(e?.error ?? e?.message ?? e, { phase: "window.error" });
|
|
1676
|
+
});
|
|
1677
|
+
window.addEventListener("unhandledrejection", (e) => {
|
|
1678
|
+
reportError(e?.reason ?? e, { phase: "window.unhandledrejection" });
|
|
1679
|
+
});
|
|
1680
|
+
}
|
|
1681
|
+
}
|
|
1682
|
+
const Errors = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
1683
|
+
__proto__: null,
|
|
1684
|
+
ErrorProvider,
|
|
1685
|
+
initErrorHandling,
|
|
1686
|
+
reportError
|
|
1687
|
+
}, Symbol.toStringTag, { value: "Module" }));
|
|
1688
|
+
function ErrorBoundary(props = {}) {
|
|
1689
|
+
const error = signal(null);
|
|
1690
|
+
const name = props.name ?? "ErrorBoundary";
|
|
1691
|
+
const fallback = props.fallback;
|
|
1692
|
+
const resetKey = props.resetKey;
|
|
1693
|
+
let lastResetKey = resetKey;
|
|
1694
|
+
return createElement("span", { style: { display: "contents" } }, () => {
|
|
1695
|
+
if (resetKey !== void 0 && resetKey !== lastResetKey) {
|
|
1696
|
+
lastResetKey = resetKey;
|
|
1697
|
+
if (error()) error(null);
|
|
1698
|
+
}
|
|
1699
|
+
const err = error();
|
|
1700
|
+
if (err) {
|
|
1701
|
+
if (typeof fallback === "function") {
|
|
1702
|
+
try {
|
|
1703
|
+
return fallback({ error: err });
|
|
1704
|
+
} catch (e) {
|
|
1705
|
+
reportError(e, { phase: "ErrorBoundary.fallback", component: name });
|
|
1706
|
+
return createElement("div", { style: { padding: "16px" } }, "ErrorBoundary fallback crashed");
|
|
1707
|
+
}
|
|
1708
|
+
}
|
|
1709
|
+
if (fallback !== void 0) return fallback;
|
|
1710
|
+
return createElement("div", { style: { padding: "16px" } }, "Something went wrong.");
|
|
1711
|
+
}
|
|
1712
|
+
const renderFn = typeof props.render === "function" ? props.render : typeof props.children === "function" ? props.children : null;
|
|
1713
|
+
if (typeof renderFn !== "function") return props.children ?? null;
|
|
1714
|
+
try {
|
|
1715
|
+
return renderFn();
|
|
1716
|
+
} catch (e) {
|
|
1717
|
+
if (!error() || error() !== e) error(e);
|
|
1718
|
+
reportError(e, { phase: "ErrorBoundary.render", component: name });
|
|
1719
|
+
return null;
|
|
1720
|
+
}
|
|
1721
|
+
});
|
|
1722
|
+
}
|
|
1723
|
+
function hasWindow() {
|
|
1724
|
+
return typeof window !== "undefined" && typeof document !== "undefined";
|
|
1725
|
+
}
|
|
1726
|
+
function createStore(initialState = {}, actions = null) {
|
|
1727
|
+
const state = initialState && typeof initialState === "object" ? initialState : {};
|
|
1728
|
+
const signals = /* @__PURE__ */ Object.create(null);
|
|
1729
|
+
const persistState = {
|
|
1730
|
+
enabled: false,
|
|
1731
|
+
key: null,
|
|
1732
|
+
storage: null,
|
|
1733
|
+
persisting: false,
|
|
1734
|
+
persistNow: null,
|
|
1735
|
+
watchers: /* @__PURE__ */ new Set()
|
|
1736
|
+
};
|
|
1737
|
+
for (const k of Object.keys(state)) {
|
|
1738
|
+
signals[k] = bindable(state[k]);
|
|
1739
|
+
}
|
|
1740
|
+
function setKey(k, v) {
|
|
1741
|
+
const key = String(k);
|
|
1742
|
+
if (!Object.prototype.hasOwnProperty.call(signals, key)) {
|
|
1743
|
+
signals[key] = bindable(state[key]);
|
|
1744
|
+
}
|
|
1745
|
+
state[key] = v;
|
|
1746
|
+
signals[key](v);
|
|
1747
|
+
if (persistState.enabled && typeof persistState.persistNow === "function") {
|
|
1748
|
+
persistState.persistNow();
|
|
1749
|
+
}
|
|
1750
|
+
return v;
|
|
1751
|
+
}
|
|
1752
|
+
function patch(obj) {
|
|
1753
|
+
if (!obj || typeof obj !== "object") return;
|
|
1754
|
+
for (const [k, v] of Object.entries(obj)) {
|
|
1755
|
+
setKey(k, v);
|
|
1756
|
+
}
|
|
1757
|
+
}
|
|
1758
|
+
function getSnapshot(reactive = false) {
|
|
1759
|
+
const out = {};
|
|
1760
|
+
for (const k of Object.keys(signals)) {
|
|
1761
|
+
out[k] = reactive ? signals[k]() : signals[k].peek();
|
|
1762
|
+
}
|
|
1763
|
+
return out;
|
|
1764
|
+
}
|
|
1765
|
+
const store = {
|
|
1766
|
+
use(key) {
|
|
1767
|
+
const k = String(key);
|
|
1768
|
+
if (!Object.prototype.hasOwnProperty.call(signals, k)) {
|
|
1769
|
+
signals[k] = bindable(state[k]);
|
|
1770
|
+
if (!Object.prototype.hasOwnProperty.call(state, k)) {
|
|
1771
|
+
try {
|
|
1772
|
+
reportErrorSafe(new Error(`Store key not found: ${k}`), { phase: "store.use", component: "createStore" });
|
|
1773
|
+
} catch {
|
|
1774
|
+
}
|
|
1775
|
+
}
|
|
1776
|
+
}
|
|
1777
|
+
if (persistState.enabled) {
|
|
1778
|
+
const sig = signals[k];
|
|
1779
|
+
if (sig && typeof sig === "function" && !persistState.watchers.has(k)) {
|
|
1780
|
+
persistState.watchers.add(k);
|
|
1781
|
+
effect(() => {
|
|
1782
|
+
sig();
|
|
1783
|
+
if (persistState.persisting) return;
|
|
1784
|
+
if (typeof persistState.persistNow === "function") persistState.persistNow();
|
|
1785
|
+
}, { onLoad: false });
|
|
1786
|
+
}
|
|
1787
|
+
}
|
|
1788
|
+
return signals[k];
|
|
1789
|
+
},
|
|
1790
|
+
set(key, value) {
|
|
1791
|
+
return setKey(key, value);
|
|
1792
|
+
},
|
|
1793
|
+
patch,
|
|
1794
|
+
snapshot(options = {}) {
|
|
1795
|
+
const reactive = options && typeof options === "object" && options.reactive === true;
|
|
1796
|
+
return getSnapshot(reactive);
|
|
1797
|
+
},
|
|
1798
|
+
actions: {}
|
|
1799
|
+
};
|
|
1800
|
+
if (actions && typeof actions === "object") {
|
|
1801
|
+
Object.entries(actions).forEach(([name, reducer]) => {
|
|
1802
|
+
if (typeof reducer !== "function") return;
|
|
1803
|
+
const fn = (...args) => {
|
|
1804
|
+
try {
|
|
1805
|
+
const next = reducer(getSnapshot(false), ...args);
|
|
1806
|
+
if (next && typeof next === "object") {
|
|
1807
|
+
patch(next);
|
|
1808
|
+
}
|
|
1809
|
+
return next;
|
|
1810
|
+
} catch (e) {
|
|
1811
|
+
reportErrorSafe(e, { phase: "store.action", component: String(name) });
|
|
1812
|
+
}
|
|
1813
|
+
};
|
|
1814
|
+
store.actions[name] = fn;
|
|
1815
|
+
store[name] = fn;
|
|
1816
|
+
});
|
|
1817
|
+
}
|
|
1818
|
+
store.persist = (storageKey, optionsOrStorage) => {
|
|
1819
|
+
if (typeof storageKey !== "string" || !storageKey.length) return store;
|
|
1820
|
+
const isStorageLike = optionsOrStorage && typeof optionsOrStorage.getItem === "function" && typeof optionsOrStorage.setItem === "function";
|
|
1821
|
+
const opts = !isStorageLike && optionsOrStorage && typeof optionsOrStorage === "object" ? optionsOrStorage : {};
|
|
1822
|
+
const st = isStorageLike ? optionsOrStorage : opts.storage ?? (hasWindow() ? window.localStorage : null);
|
|
1823
|
+
if (!st || typeof st.getItem !== "function" || typeof st.setItem !== "function") return store;
|
|
1824
|
+
const debounceMs = Number.isFinite(Number(opts.debounce)) ? Number(opts.debounce) : 0;
|
|
1825
|
+
const exclude = Array.isArray(opts.exclude) ? opts.exclude.map(String) : [];
|
|
1826
|
+
try {
|
|
1827
|
+
const raw = st.getItem(storageKey);
|
|
1828
|
+
if (raw) {
|
|
1829
|
+
const parsed = JSON.parse(raw);
|
|
1830
|
+
if (parsed && typeof parsed === "object") {
|
|
1831
|
+
const filtered = exclude.length ? Object.fromEntries(Object.entries(parsed).filter(([k]) => !exclude.includes(String(k)))) : parsed;
|
|
1832
|
+
patch(filtered);
|
|
1833
|
+
}
|
|
1834
|
+
}
|
|
1835
|
+
} catch {
|
|
1836
|
+
}
|
|
1837
|
+
const persistNow = () => {
|
|
1838
|
+
try {
|
|
1839
|
+
persistState.persisting = true;
|
|
1840
|
+
const snap = getSnapshot(false);
|
|
1841
|
+
const out = exclude.length ? Object.fromEntries(Object.entries(snap).filter(([k]) => !exclude.includes(String(k)))) : snap;
|
|
1842
|
+
st.setItem(storageKey, JSON.stringify(out));
|
|
1843
|
+
} catch {
|
|
1844
|
+
} finally {
|
|
1845
|
+
persistState.persisting = false;
|
|
1846
|
+
}
|
|
1847
|
+
};
|
|
1848
|
+
let debounceId = null;
|
|
1849
|
+
const schedulePersist = () => {
|
|
1850
|
+
if (debounceMs <= 0) return persistNow();
|
|
1851
|
+
try {
|
|
1852
|
+
if (debounceId != null) clearTimeout(debounceId);
|
|
1853
|
+
} catch {
|
|
1854
|
+
}
|
|
1855
|
+
debounceId = setTimeout(() => {
|
|
1856
|
+
debounceId = null;
|
|
1857
|
+
persistNow();
|
|
1858
|
+
}, debounceMs);
|
|
1859
|
+
};
|
|
1860
|
+
persistState.enabled = true;
|
|
1861
|
+
persistState.key = storageKey;
|
|
1862
|
+
persistState.storage = st;
|
|
1863
|
+
persistState.persistNow = schedulePersist;
|
|
1864
|
+
const origSet = store.set;
|
|
1865
|
+
store.set = (k, v) => {
|
|
1866
|
+
const res = origSet(k, v);
|
|
1867
|
+
schedulePersist();
|
|
1868
|
+
return res;
|
|
1869
|
+
};
|
|
1870
|
+
const origPatch = store.patch;
|
|
1871
|
+
store.patch = (obj) => {
|
|
1872
|
+
origPatch(obj);
|
|
1873
|
+
schedulePersist();
|
|
1874
|
+
};
|
|
1875
|
+
Object.keys(store.actions).forEach((name) => {
|
|
1876
|
+
const orig = store.actions[name];
|
|
1877
|
+
if (typeof orig !== "function") return;
|
|
1878
|
+
store.actions[name] = (...args) => {
|
|
1879
|
+
const res = orig(...args);
|
|
1880
|
+
schedulePersist();
|
|
1881
|
+
return res;
|
|
1882
|
+
};
|
|
1883
|
+
store[name] = store.actions[name];
|
|
1884
|
+
});
|
|
1885
|
+
Object.keys(signals).forEach((k) => {
|
|
1886
|
+
try {
|
|
1887
|
+
store.use(k);
|
|
1888
|
+
} catch {
|
|
1889
|
+
}
|
|
1890
|
+
});
|
|
1891
|
+
schedulePersist();
|
|
1892
|
+
return store;
|
|
1893
|
+
};
|
|
1894
|
+
return store;
|
|
1895
|
+
}
|
|
1896
|
+
const Store = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
1897
|
+
__proto__: null,
|
|
1898
|
+
createStore
|
|
1899
|
+
}, Symbol.toStringTag, { value: "Module" }));
|
|
1900
|
+
function render(Component, container) {
|
|
1901
|
+
initLifecycleRoot(container);
|
|
1902
|
+
initErrorHandling(container);
|
|
1903
|
+
try {
|
|
1904
|
+
const root = createElement(Component);
|
|
1905
|
+
container.appendChild(root);
|
|
1906
|
+
} catch (e) {
|
|
1907
|
+
reportError(e, { phase: "render", component: Component?.name ?? "App" });
|
|
1908
|
+
}
|
|
1909
|
+
}
|
|
1910
|
+
const index = {
|
|
1911
|
+
...Signals,
|
|
1912
|
+
...DOM,
|
|
1913
|
+
...Lifecycle,
|
|
1914
|
+
...Router,
|
|
1915
|
+
...Markdown$1,
|
|
1916
|
+
...Errors,
|
|
1917
|
+
...Suspense$1,
|
|
1918
|
+
...Context,
|
|
1919
|
+
...Store,
|
|
1920
|
+
render
|
|
1921
|
+
};
|
|
1922
|
+
export {
|
|
1923
|
+
ErrorBoundary,
|
|
1924
|
+
ErrorProvider,
|
|
1925
|
+
Fragment,
|
|
1926
|
+
Link,
|
|
1927
|
+
Markdown,
|
|
1928
|
+
NotFound,
|
|
1929
|
+
Page,
|
|
1930
|
+
Route,
|
|
1931
|
+
Suspense,
|
|
1932
|
+
SuspenseContext,
|
|
1933
|
+
bindContext,
|
|
1934
|
+
bindable,
|
|
1935
|
+
captureContext,
|
|
1936
|
+
clearErrors,
|
|
1937
|
+
createComponentInstance,
|
|
1938
|
+
createContext,
|
|
1939
|
+
createElement,
|
|
1940
|
+
createStore,
|
|
1941
|
+
index as default,
|
|
1942
|
+
derive,
|
|
1943
|
+
effect,
|
|
1944
|
+
getCurrentComponent,
|
|
1945
|
+
getIsNotFound,
|
|
1946
|
+
getLocation,
|
|
1947
|
+
getPathname,
|
|
1948
|
+
getRouteReady,
|
|
1949
|
+
initErrorHandling,
|
|
1950
|
+
initLifecycleRoot,
|
|
1951
|
+
lazy,
|
|
1952
|
+
mountComponent,
|
|
1953
|
+
navigate,
|
|
1954
|
+
onCleanup,
|
|
1955
|
+
onMount,
|
|
1956
|
+
onUnmount,
|
|
1957
|
+
onUpdate,
|
|
1958
|
+
pick,
|
|
1959
|
+
readContext,
|
|
1960
|
+
render,
|
|
1961
|
+
reportError,
|
|
1962
|
+
runInContext,
|
|
1963
|
+
runInLifecycle,
|
|
1964
|
+
setNotFound,
|
|
1965
|
+
signal,
|
|
1966
|
+
startHead,
|
|
1967
|
+
triggerUpdate,
|
|
1968
|
+
unmountComponent,
|
|
1969
|
+
untrack,
|
|
1970
|
+
useErrors,
|
|
1971
|
+
useIsNotFound,
|
|
1972
|
+
useLocation,
|
|
1973
|
+
usePathname,
|
|
1974
|
+
useRouteReady
|
|
1975
|
+
};
|