lightview 2.2.2 → 2.3.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/cDOMIntro.md +279 -0
- package/docs/about.html +15 -12
- package/docs/api/computed.html +1 -1
- package/docs/api/effects.html +1 -1
- package/docs/api/elements.html +56 -25
- package/docs/api/enhance.html +1 -1
- package/docs/api/hypermedia.html +1 -1
- package/docs/api/index.html +1 -1
- package/docs/api/nav.html +28 -3
- package/docs/api/signals.html +1 -1
- package/docs/api/state.html +283 -85
- package/docs/assets/js/examplify.js +2 -1
- package/docs/cdom-nav.html +3 -2
- package/docs/cdom.html +383 -114
- package/jprx/README.md +112 -71
- package/jprx/helpers/state.js +21 -0
- package/jprx/package.json +1 -1
- package/jprx/parser.js +136 -86
- package/jprx/specs/expressions.json +71 -0
- package/jprx/specs/helpers.json +150 -0
- package/lightview-all.js +618 -431
- package/lightview-cdom.js +311 -605
- package/lightview-router.js +6 -0
- package/lightview-x.js +226 -54
- package/lightview.js +351 -42
- package/package.json +2 -1
- package/src/lightview-cdom.js +211 -315
- package/src/lightview-router.js +10 -0
- package/src/lightview-x.js +121 -1
- package/src/lightview.js +88 -16
- package/src/reactivity/signal.js +73 -29
- package/src/reactivity/state.js +84 -21
- package/tests/cdom/fixtures/helpers.cdomc +24 -24
- package/tests/cdom/helpers.test.js +28 -28
- package/tests/cdom/parser.test.js +39 -114
- package/tests/cdom/reactivity.test.js +32 -29
- package/tests/jprx/spec.test.js +99 -0
- package/tests/cdom/loader.test.js +0 -125
package/lightview-cdom.js
CHANGED
|
@@ -17,6 +17,9 @@ var LightviewCDOM = function(exports) {
|
|
|
17
17
|
};
|
|
18
18
|
const registerHelper = (name, fn, options = {}) => {
|
|
19
19
|
helpers.set(name, fn);
|
|
20
|
+
if (globalThis.__LIGHTVIEW_INTERNALS__) {
|
|
21
|
+
globalThis.__LIGHTVIEW_INTERNALS__.helpers.set(name, fn);
|
|
22
|
+
}
|
|
20
23
|
if (options) helperOptions.set(name, options);
|
|
21
24
|
};
|
|
22
25
|
const registerOperator = (helperName, symbol, position, precedence) => {
|
|
@@ -31,7 +34,7 @@ var LightviewCDOM = function(exports) {
|
|
|
31
34
|
operators[position].set(symbol, { helper: helperName, precedence: prec });
|
|
32
35
|
};
|
|
33
36
|
const getLV = () => globalThis.Lightview || null;
|
|
34
|
-
const getRegistry
|
|
37
|
+
const getRegistry = () => {
|
|
35
38
|
var _a;
|
|
36
39
|
return ((_a = getLV()) == null ? void 0 : _a.registry) || null;
|
|
37
40
|
};
|
|
@@ -88,21 +91,14 @@ var LightviewCDOM = function(exports) {
|
|
|
88
91
|
};
|
|
89
92
|
const resolvePath = (path, context) => {
|
|
90
93
|
if (typeof path !== "string") return path;
|
|
91
|
-
const registry = getRegistry
|
|
94
|
+
const registry = getRegistry();
|
|
92
95
|
if (path === ".") return unwrapSignal(context);
|
|
93
|
-
if (path.startsWith("
|
|
96
|
+
if (path.startsWith("=/")) {
|
|
94
97
|
const [rootName, ...rest] = path.slice(2).split("/");
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
return traverse(localState[rootName], rest);
|
|
100
|
-
}
|
|
101
|
-
cur = cur.__parent__;
|
|
102
|
-
}
|
|
103
|
-
const rootSignal = registry == null ? void 0 : registry.get(rootName);
|
|
104
|
-
if (!rootSignal) return void 0;
|
|
105
|
-
return traverse(rootSignal, rest);
|
|
98
|
+
const LV = getLV();
|
|
99
|
+
const root = LV ? LV.get(rootName, { scope: (context == null ? void 0 : context.__node__) || context }) : registry == null ? void 0 : registry.get(rootName);
|
|
100
|
+
if (!root) return void 0;
|
|
101
|
+
return traverse(root, rest);
|
|
106
102
|
}
|
|
107
103
|
if (path.startsWith("./")) {
|
|
108
104
|
return traverse(context, path.slice(2).split("/"));
|
|
@@ -123,22 +119,15 @@ var LightviewCDOM = function(exports) {
|
|
|
123
119
|
};
|
|
124
120
|
const resolvePathAsContext = (path, context) => {
|
|
125
121
|
if (typeof path !== "string") return path;
|
|
126
|
-
const registry = getRegistry
|
|
122
|
+
const registry = getRegistry();
|
|
127
123
|
if (path === ".") return context;
|
|
128
|
-
if (path.startsWith("
|
|
124
|
+
if (path.startsWith("=/")) {
|
|
129
125
|
const segments = path.slice(2).split(/[/.]/);
|
|
130
126
|
const rootName = segments.shift();
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
return traverseAsContext(localState[rootName], segments);
|
|
136
|
-
}
|
|
137
|
-
cur = cur.__parent__;
|
|
138
|
-
}
|
|
139
|
-
const rootSignal = registry == null ? void 0 : registry.get(rootName);
|
|
140
|
-
if (!rootSignal) return void 0;
|
|
141
|
-
return traverseAsContext(rootSignal, segments);
|
|
127
|
+
const LV = getLV();
|
|
128
|
+
const root = LV ? LV.get(rootName, { scope: (context == null ? void 0 : context.__node__) || context }) : registry == null ? void 0 : registry.get(rootName);
|
|
129
|
+
if (!root) return void 0;
|
|
130
|
+
return traverseAsContext(root, segments);
|
|
142
131
|
}
|
|
143
132
|
if (path.startsWith("./")) {
|
|
144
133
|
return traverseAsContext(context, path.slice(2).split(/[\/.]/));
|
|
@@ -166,6 +155,7 @@ var LightviewCDOM = function(exports) {
|
|
|
166
155
|
return this.fn(context);
|
|
167
156
|
}
|
|
168
157
|
}
|
|
158
|
+
const isNode = (val) => val && typeof val === "object" && globalThis.Node && val instanceof globalThis.Node;
|
|
169
159
|
const resolveArgument = (arg, context, globalMode = false) => {
|
|
170
160
|
if (arg.startsWith("'") && arg.endsWith("'") || arg.startsWith('"') && arg.endsWith('"')) {
|
|
171
161
|
return { value: arg.slice(1, -1), isLiteral: true };
|
|
@@ -186,9 +176,21 @@ var LightviewCDOM = function(exports) {
|
|
|
186
176
|
isLazy: true
|
|
187
177
|
};
|
|
188
178
|
}
|
|
179
|
+
if (arg === "$this" || arg.startsWith("$this/") || arg.startsWith("$this.")) {
|
|
180
|
+
return {
|
|
181
|
+
value: new LazyValue((context2) => {
|
|
182
|
+
const node = (context2 == null ? void 0 : context2.__node__) || context2;
|
|
183
|
+
if (arg === "$this") return node;
|
|
184
|
+
const path = arg.startsWith("$this.") ? arg.slice(6) : arg.slice(6);
|
|
185
|
+
return resolvePath(path, node);
|
|
186
|
+
}),
|
|
187
|
+
isLazy: true
|
|
188
|
+
};
|
|
189
|
+
}
|
|
189
190
|
if (arg === "$event" || arg.startsWith("$event/") || arg.startsWith("$event.")) {
|
|
190
191
|
return {
|
|
191
|
-
value: new LazyValue((
|
|
192
|
+
value: new LazyValue((context2) => {
|
|
193
|
+
const event = (context2 == null ? void 0 : context2.$event) || (context2 == null ? void 0 : context2.event) || context2;
|
|
192
194
|
if (arg === "$event") return event;
|
|
193
195
|
const path = arg.startsWith("$event.") ? arg.slice(7) : arg.slice(7);
|
|
194
196
|
return resolvePath(path, event);
|
|
@@ -201,11 +203,23 @@ var LightviewCDOM = function(exports) {
|
|
|
201
203
|
const data = parseJPRX(arg);
|
|
202
204
|
const resolveTemplate = (node, context2) => {
|
|
203
205
|
if (typeof node === "string") {
|
|
204
|
-
if (node.startsWith("
|
|
206
|
+
if (node.startsWith("=")) {
|
|
205
207
|
const res = resolveExpression(node, context2);
|
|
206
208
|
const final = res instanceof LazyValue ? res.resolve(context2) : res;
|
|
207
209
|
return unwrapSignal(final);
|
|
208
210
|
}
|
|
211
|
+
if (node === "$this" || node.startsWith("$this/") || node.startsWith("$this.")) {
|
|
212
|
+
const path = node.startsWith("$this.") || node.startsWith("$this/") ? node.slice(6) : node.slice(6);
|
|
213
|
+
const ctxNode = (context2 == null ? void 0 : context2.__node__) || context2;
|
|
214
|
+
const res = node === "$this" ? ctxNode : resolvePath(path, ctxNode);
|
|
215
|
+
return unwrapSignal(res);
|
|
216
|
+
}
|
|
217
|
+
if (node === "$event" || node.startsWith("$event/") || node.startsWith("$event.")) {
|
|
218
|
+
const path = node.startsWith("$event.") || node.startsWith("$event/") ? node.slice(7) : node.slice(7);
|
|
219
|
+
const event = (context2 == null ? void 0 : context2.$event) || (context2 == null ? void 0 : context2.event) || (context2 && !isNode(context2) ? context2 : null);
|
|
220
|
+
const res = node === "$event" ? event : resolvePath(path, event);
|
|
221
|
+
return unwrapSignal(res);
|
|
222
|
+
}
|
|
209
223
|
if (node === "_" || node.startsWith("_/") || node.startsWith("_.")) {
|
|
210
224
|
const path = node.startsWith("_.") || node.startsWith("_/") ? node.slice(2) : node.slice(2);
|
|
211
225
|
const res = node === "_" ? context2 : resolvePath(path, context2);
|
|
@@ -223,7 +237,7 @@ var LightviewCDOM = function(exports) {
|
|
|
223
237
|
};
|
|
224
238
|
const hasReactive = (obj) => {
|
|
225
239
|
if (typeof obj === "string") {
|
|
226
|
-
return obj.startsWith("
|
|
240
|
+
return obj.startsWith("=") || obj.startsWith("_") || obj.startsWith("../");
|
|
227
241
|
}
|
|
228
242
|
if (Array.isArray(obj)) return obj.some(hasReactive);
|
|
229
243
|
if (obj && typeof obj === "object") return Object.values(obj).some(hasReactive);
|
|
@@ -242,9 +256,9 @@ var LightviewCDOM = function(exports) {
|
|
|
242
256
|
if (arg.includes("(")) {
|
|
243
257
|
let nestedExpr = arg;
|
|
244
258
|
if (arg.startsWith("/")) {
|
|
245
|
-
nestedExpr = "
|
|
246
|
-
} else if (globalMode && !arg.startsWith("
|
|
247
|
-
nestedExpr =
|
|
259
|
+
nestedExpr = "=" + arg;
|
|
260
|
+
} else if (globalMode && !arg.startsWith("=") && !arg.startsWith("./")) {
|
|
261
|
+
nestedExpr = `=/${arg}`;
|
|
248
262
|
}
|
|
249
263
|
const val = resolveExpression(nestedExpr, context);
|
|
250
264
|
if (val instanceof LazyValue) {
|
|
@@ -254,11 +268,11 @@ var LightviewCDOM = function(exports) {
|
|
|
254
268
|
}
|
|
255
269
|
let normalizedPath;
|
|
256
270
|
if (arg.startsWith("/")) {
|
|
257
|
-
normalizedPath = "
|
|
258
|
-
} else if (arg.startsWith("
|
|
271
|
+
normalizedPath = "=" + arg;
|
|
272
|
+
} else if (arg.startsWith("=") || arg.startsWith("./") || arg.startsWith("../")) {
|
|
259
273
|
normalizedPath = arg;
|
|
260
274
|
} else if (globalMode) {
|
|
261
|
-
normalizedPath =
|
|
275
|
+
normalizedPath = `=/${arg}`;
|
|
262
276
|
} else {
|
|
263
277
|
normalizedPath = `./${arg}`;
|
|
264
278
|
}
|
|
@@ -303,6 +317,8 @@ var LightviewCDOM = function(exports) {
|
|
|
303
317
|
// ... suffix
|
|
304
318
|
PLACEHOLDER: "PLACEHOLDER",
|
|
305
319
|
// _, _/path
|
|
320
|
+
THIS: "THIS",
|
|
321
|
+
// $this
|
|
306
322
|
EVENT: "EVENT",
|
|
307
323
|
// $event, $event.target
|
|
308
324
|
EOF: "EOF"
|
|
@@ -325,15 +341,16 @@ var LightviewCDOM = function(exports) {
|
|
|
325
341
|
i++;
|
|
326
342
|
continue;
|
|
327
343
|
}
|
|
328
|
-
if (expr[i] === "
|
|
329
|
-
|
|
330
|
-
|
|
344
|
+
if (expr[i] === "=" && i + 1 < len2) {
|
|
345
|
+
const prefixOps = [...operators.prefix.keys()].sort((a, b) => b.length - a.length);
|
|
346
|
+
let isPrefixOp = false;
|
|
347
|
+
for (const op of prefixOps) {
|
|
331
348
|
if (expr.slice(i + 1, i + 1 + op.length) === op) {
|
|
332
|
-
|
|
349
|
+
isPrefixOp = true;
|
|
333
350
|
break;
|
|
334
351
|
}
|
|
335
352
|
}
|
|
336
|
-
if (
|
|
353
|
+
if (isPrefixOp) {
|
|
337
354
|
i++;
|
|
338
355
|
continue;
|
|
339
356
|
}
|
|
@@ -369,7 +386,7 @@ var LightviewCDOM = function(exports) {
|
|
|
369
386
|
continue;
|
|
370
387
|
}
|
|
371
388
|
const validBefore = /[\s)]/.test(before) || i === 0 || tokens.length === 0 || tokens[tokens.length - 1].type === TokenType.LPAREN || tokens[tokens.length - 1].type === TokenType.COMMA || tokens[tokens.length - 1].type === TokenType.OPERATOR;
|
|
372
|
-
const validAfter = /[\s(
|
|
389
|
+
const validAfter = /[\s(=./'"0-9_]/.test(after) || i + op.length >= len2 || opSymbols.some((o) => expr.slice(i + op.length).startsWith(o));
|
|
373
390
|
if (validBefore || validAfter) {
|
|
374
391
|
matchedOp = op;
|
|
375
392
|
break;
|
|
@@ -425,6 +442,16 @@ var LightviewCDOM = function(exports) {
|
|
|
425
442
|
tokens.push({ type: TokenType.PLACEHOLDER, value: placeholder });
|
|
426
443
|
continue;
|
|
427
444
|
}
|
|
445
|
+
if (expr.slice(i, i + 5) === "$this") {
|
|
446
|
+
let thisPath = "$this";
|
|
447
|
+
i += 5;
|
|
448
|
+
while (i < len2 && /[a-zA-Z0-9_./]/.test(expr[i])) {
|
|
449
|
+
thisPath += expr[i];
|
|
450
|
+
i++;
|
|
451
|
+
}
|
|
452
|
+
tokens.push({ type: TokenType.THIS, value: thisPath });
|
|
453
|
+
continue;
|
|
454
|
+
}
|
|
428
455
|
if (expr.slice(i, i + 6) === "$event") {
|
|
429
456
|
let eventPath = "$event";
|
|
430
457
|
i += 6;
|
|
@@ -435,7 +462,7 @@ var LightviewCDOM = function(exports) {
|
|
|
435
462
|
tokens.push({ type: TokenType.EVENT, value: eventPath });
|
|
436
463
|
continue;
|
|
437
464
|
}
|
|
438
|
-
if (expr[i] === "
|
|
465
|
+
if (expr[i] === "=" || expr[i] === "." || expr[i] === "/") {
|
|
439
466
|
let path = "";
|
|
440
467
|
while (i < len2) {
|
|
441
468
|
let isOp = false;
|
|
@@ -495,7 +522,7 @@ var LightviewCDOM = function(exports) {
|
|
|
495
522
|
const hasOperatorSyntax = (expr) => {
|
|
496
523
|
if (!expr || typeof expr !== "string") return false;
|
|
497
524
|
if (expr.includes("(")) return false;
|
|
498
|
-
if (
|
|
525
|
+
if (/^=(\+\+|--|!!)\/?/.test(expr)) {
|
|
499
526
|
return true;
|
|
500
527
|
}
|
|
501
528
|
if (/(\+\+|--)$/.test(expr)) {
|
|
@@ -558,6 +585,9 @@ var LightviewCDOM = function(exports) {
|
|
|
558
585
|
tok = this.peek();
|
|
559
586
|
continue;
|
|
560
587
|
}
|
|
588
|
+
if (!operators.postfix.has(tok.value) && !operators.infix.has(tok.value)) {
|
|
589
|
+
break;
|
|
590
|
+
}
|
|
561
591
|
this.consume();
|
|
562
592
|
const nextTok = this.peek();
|
|
563
593
|
if (nextTok.type === TokenType.PATH || nextTok.type === TokenType.LITERAL || nextTok.type === TokenType.LPAREN || nextTok.type === TokenType.PLACEHOLDER || nextTok.type === TokenType.EVENT || nextTok.type === TokenType.OPERATOR && operators.prefix.has(nextTok.value)) {
|
|
@@ -595,6 +625,10 @@ var LightviewCDOM = function(exports) {
|
|
|
595
625
|
this.consume();
|
|
596
626
|
return { type: "Placeholder", value: tok.value };
|
|
597
627
|
}
|
|
628
|
+
if (tok.type === TokenType.THIS) {
|
|
629
|
+
this.consume();
|
|
630
|
+
return { type: "This", value: tok.value };
|
|
631
|
+
}
|
|
598
632
|
if (tok.type === TokenType.EVENT) {
|
|
599
633
|
this.consume();
|
|
600
634
|
return { type: "Event", value: tok.value };
|
|
@@ -630,8 +664,17 @@ var LightviewCDOM = function(exports) {
|
|
|
630
664
|
return resolvePath(path, item);
|
|
631
665
|
});
|
|
632
666
|
}
|
|
667
|
+
case "This": {
|
|
668
|
+
return new LazyValue((context2) => {
|
|
669
|
+
const node = (context2 == null ? void 0 : context2.__node__) || context2;
|
|
670
|
+
if (ast.value === "$this") return node;
|
|
671
|
+
const path = ast.value.startsWith("$this.") ? ast.value.slice(6) : ast.value.slice(6);
|
|
672
|
+
return resolvePath(path, node);
|
|
673
|
+
});
|
|
674
|
+
}
|
|
633
675
|
case "Event": {
|
|
634
|
-
return new LazyValue((
|
|
676
|
+
return new LazyValue((context2) => {
|
|
677
|
+
const event = (context2 == null ? void 0 : context2.$event) || (context2 == null ? void 0 : context2.event) || context2;
|
|
635
678
|
if (ast.value === "$event") return event;
|
|
636
679
|
const path = ast.value.startsWith("$event.") ? ast.value.slice(7) : ast.value.slice(7);
|
|
637
680
|
return resolvePath(path, event);
|
|
@@ -679,7 +722,12 @@ var LightviewCDOM = function(exports) {
|
|
|
679
722
|
const opts = helperOptions.get(opInfo.helper) || {};
|
|
680
723
|
const left = evaluateAST(ast.left, context, opts.pathAware);
|
|
681
724
|
const right = evaluateAST(ast.right, context, false);
|
|
682
|
-
|
|
725
|
+
const finalArgs = [];
|
|
726
|
+
if (Array.isArray(left) && ast.left.type === "Explosion") finalArgs.push(...left);
|
|
727
|
+
else finalArgs.push(unwrapSignal(left));
|
|
728
|
+
if (Array.isArray(right) && ast.right.type === "Explosion") finalArgs.push(...right);
|
|
729
|
+
else finalArgs.push(unwrapSignal(right));
|
|
730
|
+
return helper(...finalArgs);
|
|
683
731
|
}
|
|
684
732
|
default:
|
|
685
733
|
throw new Error(`JPRX: Unknown AST node type: ${ast.type}`);
|
|
@@ -706,14 +754,14 @@ var LightviewCDOM = function(exports) {
|
|
|
706
754
|
const fullPath = expr.slice(0, funcStart).trim();
|
|
707
755
|
const argsStr = expr.slice(funcStart + 1, -1);
|
|
708
756
|
const segments = fullPath.split("/");
|
|
709
|
-
let funcName = segments.pop().replace(
|
|
757
|
+
let funcName = segments.pop().replace(/^=/, "");
|
|
710
758
|
if (funcName === "" && (segments.length > 0 || fullPath === "/")) {
|
|
711
759
|
funcName = "/";
|
|
712
760
|
}
|
|
713
761
|
const navPath = segments.join("/");
|
|
714
|
-
const isGlobalExpr = expr.startsWith("
|
|
762
|
+
const isGlobalExpr = expr.startsWith("=/") || expr.startsWith("=");
|
|
715
763
|
let baseContext = context;
|
|
716
|
-
if (navPath && navPath !== "
|
|
764
|
+
if (navPath && navPath !== "=") {
|
|
717
765
|
baseContext = resolvePathAsContext(navPath, context);
|
|
718
766
|
}
|
|
719
767
|
const helper = helpers.get(funcName);
|
|
@@ -746,7 +794,7 @@ var LightviewCDOM = function(exports) {
|
|
|
746
794
|
let hasLazy = false;
|
|
747
795
|
for (let i = 0; i < argsList.length; i++) {
|
|
748
796
|
const arg = argsList[i];
|
|
749
|
-
const useGlobalMode = isGlobalExpr && (navPath === "
|
|
797
|
+
const useGlobalMode = isGlobalExpr && (navPath === "=" || !navPath);
|
|
750
798
|
const res = resolveArgument(arg, baseContext, useGlobalMode);
|
|
751
799
|
if (res.isLazy) hasLazy = true;
|
|
752
800
|
const shouldUnwrap = !(options.pathAware && i === 0);
|
|
@@ -770,7 +818,7 @@ var LightviewCDOM = function(exports) {
|
|
|
770
818
|
return helper(...finalArgs);
|
|
771
819
|
});
|
|
772
820
|
}
|
|
773
|
-
const result = helper(
|
|
821
|
+
const result = helper.apply((context == null ? void 0 : context.__node__) || null, resolvedArgs);
|
|
774
822
|
return unwrapSignal(result);
|
|
775
823
|
}
|
|
776
824
|
return unwrapSignal(resolvePath(expr, context));
|
|
@@ -892,7 +940,7 @@ var LightviewCDOM = function(exports) {
|
|
|
892
940
|
i++;
|
|
893
941
|
}
|
|
894
942
|
const word = input.slice(start, i);
|
|
895
|
-
if (word.startsWith("
|
|
943
|
+
if (word.startsWith("=")) {
|
|
896
944
|
return word;
|
|
897
945
|
}
|
|
898
946
|
if (word === "true") return true;
|
|
@@ -1030,7 +1078,7 @@ var LightviewCDOM = function(exports) {
|
|
|
1030
1078
|
i++;
|
|
1031
1079
|
continue;
|
|
1032
1080
|
}
|
|
1033
|
-
if (char === "
|
|
1081
|
+
if (char === "=") {
|
|
1034
1082
|
let expr = "";
|
|
1035
1083
|
let parenDepth = 0;
|
|
1036
1084
|
let braceDepth = 0;
|
|
@@ -1059,7 +1107,7 @@ var LightviewCDOM = function(exports) {
|
|
|
1059
1107
|
result += JSON.stringify(expr);
|
|
1060
1108
|
continue;
|
|
1061
1109
|
}
|
|
1062
|
-
if (/[a-zA-Z_
|
|
1110
|
+
if (/[a-zA-Z_$/./]/.test(char)) {
|
|
1063
1111
|
let word = "";
|
|
1064
1112
|
while (i < len2 && /[a-zA-Z0-9_$/.-]/.test(input[i])) {
|
|
1065
1113
|
word += input[i];
|
|
@@ -1449,6 +1497,21 @@ var LightviewCDOM = function(exports) {
|
|
|
1449
1497
|
if (typeof current === "object" && current !== null) return set(target, {});
|
|
1450
1498
|
return set(target, null);
|
|
1451
1499
|
};
|
|
1500
|
+
function state(val, options) {
|
|
1501
|
+
if (globalThis.Lightview) {
|
|
1502
|
+
const finalOptions = typeof options === "string" ? { name: options } : options;
|
|
1503
|
+
return globalThis.Lightview.state(val, finalOptions);
|
|
1504
|
+
}
|
|
1505
|
+
throw new Error("JPRX: $state requires a UI library implementation.");
|
|
1506
|
+
}
|
|
1507
|
+
function signal(val, options) {
|
|
1508
|
+
if (globalThis.Lightview) {
|
|
1509
|
+
const finalOptions = typeof options === "string" ? { name: options } : options;
|
|
1510
|
+
return globalThis.Lightview.signal(val, finalOptions);
|
|
1511
|
+
}
|
|
1512
|
+
throw new Error("JPRX: $signal requires a UI library implementation.");
|
|
1513
|
+
}
|
|
1514
|
+
const bind = (path, options) => ({ __JPRX_BIND__: true, path, options });
|
|
1452
1515
|
const registerStateHelpers = (register) => {
|
|
1453
1516
|
const opts = { pathAware: true };
|
|
1454
1517
|
register("set", set, opts);
|
|
@@ -1462,6 +1525,9 @@ var LightviewCDOM = function(exports) {
|
|
|
1462
1525
|
register("pop", pop, opts);
|
|
1463
1526
|
register("assign", assign, opts);
|
|
1464
1527
|
register("clear", clear, opts);
|
|
1528
|
+
register("state", state);
|
|
1529
|
+
register("signal", signal);
|
|
1530
|
+
register("bind", bind);
|
|
1465
1531
|
};
|
|
1466
1532
|
const fetchHelper = (url, options = {}) => {
|
|
1467
1533
|
const fetchOptions = { ...options };
|
|
@@ -1490,281 +1556,27 @@ var LightviewCDOM = function(exports) {
|
|
|
1490
1556
|
const _LV = globalThis.__LIGHTVIEW_INTERNALS__ || (globalThis.__LIGHTVIEW_INTERNALS__ = {
|
|
1491
1557
|
currentEffect: null,
|
|
1492
1558
|
registry: /* @__PURE__ */ new Map(),
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1559
|
+
// Global name -> Signal/Proxy
|
|
1560
|
+
localRegistries: /* @__PURE__ */ new WeakMap(),
|
|
1561
|
+
// Object/Element -> Map(name -> Signal/Proxy)
|
|
1562
|
+
futureSignals: /* @__PURE__ */ new Map(),
|
|
1563
|
+
// name -> Set of (signal) => void
|
|
1564
|
+
schemas: /* @__PURE__ */ new Map(),
|
|
1565
|
+
// name -> Schema (Draft 7+ or Shorthand)
|
|
1566
|
+
parents: /* @__PURE__ */ new WeakMap(),
|
|
1567
|
+
// Proxy -> Parent (Proxy/Element)
|
|
1568
|
+
helpers: /* @__PURE__ */ new Map(),
|
|
1569
|
+
// name -> function (used for transforms and expressions)
|
|
1570
|
+
hooks: {
|
|
1571
|
+
validate: (value, schema) => true
|
|
1572
|
+
// Hook for extensions (like JPRX) to provide full validation
|
|
1507
1573
|
}
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
if (args.length === 0) return f.value;
|
|
1512
|
-
f.value = args[0];
|
|
1513
|
-
};
|
|
1514
|
-
Object.defineProperty(f, "value", {
|
|
1515
|
-
get() {
|
|
1516
|
-
if (_LV.currentEffect) {
|
|
1517
|
-
subscribers.add(_LV.currentEffect);
|
|
1518
|
-
_LV.currentEffect.dependencies.add(subscribers);
|
|
1519
|
-
}
|
|
1520
|
-
return value;
|
|
1521
|
-
},
|
|
1522
|
-
set(newValue) {
|
|
1523
|
-
if (value !== newValue) {
|
|
1524
|
-
value = newValue;
|
|
1525
|
-
if (name && storage) {
|
|
1526
|
-
try {
|
|
1527
|
-
storage.setItem(name, JSON.stringify(value));
|
|
1528
|
-
} catch (e) {
|
|
1529
|
-
}
|
|
1530
|
-
}
|
|
1531
|
-
[...subscribers].forEach((effect2) => effect2());
|
|
1532
|
-
}
|
|
1533
|
-
}
|
|
1534
|
-
});
|
|
1535
|
-
if (name) {
|
|
1536
|
-
if (_LV.registry.has(name)) {
|
|
1537
|
-
if (_LV.registry.get(name) !== f) {
|
|
1538
|
-
throw new Error(`Lightview: A signal or state with the name "${name}" is already registered.`);
|
|
1539
|
-
}
|
|
1540
|
-
} else {
|
|
1541
|
-
_LV.registry.set(name, f);
|
|
1542
|
-
}
|
|
1543
|
-
}
|
|
1544
|
-
return f;
|
|
1545
|
-
};
|
|
1546
|
-
const getSignal = (name, defaultValue) => {
|
|
1547
|
-
if (!_LV.registry.has(name) && defaultValue !== void 0) {
|
|
1548
|
-
return signal(defaultValue, name);
|
|
1549
|
-
}
|
|
1550
|
-
return _LV.registry.get(name);
|
|
1551
|
-
};
|
|
1552
|
-
signal.get = getSignal;
|
|
1553
|
-
const effect = (fn) => {
|
|
1554
|
-
const execute = () => {
|
|
1555
|
-
if (!execute.active || execute.running) return;
|
|
1556
|
-
execute.dependencies.forEach((dep) => dep.delete(execute));
|
|
1557
|
-
execute.dependencies.clear();
|
|
1558
|
-
execute.running = true;
|
|
1559
|
-
_LV.currentEffect = execute;
|
|
1560
|
-
try {
|
|
1561
|
-
fn();
|
|
1562
|
-
} finally {
|
|
1563
|
-
_LV.currentEffect = null;
|
|
1564
|
-
execute.running = false;
|
|
1565
|
-
}
|
|
1566
|
-
};
|
|
1567
|
-
execute.active = true;
|
|
1568
|
-
execute.running = false;
|
|
1569
|
-
execute.dependencies = /* @__PURE__ */ new Set();
|
|
1570
|
-
execute.stop = () => {
|
|
1571
|
-
execute.dependencies.forEach((dep) => dep.delete(execute));
|
|
1572
|
-
execute.dependencies.clear();
|
|
1573
|
-
execute.active = false;
|
|
1574
|
-
};
|
|
1575
|
-
execute();
|
|
1576
|
-
return execute;
|
|
1577
|
-
};
|
|
1578
|
-
const getRegistry = () => _LV.registry;
|
|
1579
|
-
const stateCache = /* @__PURE__ */ new WeakMap();
|
|
1580
|
-
const stateSignals = /* @__PURE__ */ new WeakMap();
|
|
1581
|
-
const parents = /* @__PURE__ */ new WeakMap();
|
|
1574
|
+
});
|
|
1575
|
+
const internals = _LV;
|
|
1576
|
+
const { parents, schemas, hooks } = internals;
|
|
1582
1577
|
const protoMethods = (proto, test) => Object.getOwnPropertyNames(proto).filter((k) => typeof proto[k] === "function" && test(k));
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
const ARRAY_TRACKING = [
|
|
1586
|
-
"map",
|
|
1587
|
-
"forEach",
|
|
1588
|
-
"filter",
|
|
1589
|
-
"find",
|
|
1590
|
-
"findIndex",
|
|
1591
|
-
"some",
|
|
1592
|
-
"every",
|
|
1593
|
-
"reduce",
|
|
1594
|
-
"reduceRight",
|
|
1595
|
-
"includes",
|
|
1596
|
-
"indexOf",
|
|
1597
|
-
"lastIndexOf",
|
|
1598
|
-
"join",
|
|
1599
|
-
"slice",
|
|
1600
|
-
"concat",
|
|
1601
|
-
"flat",
|
|
1602
|
-
"flatMap",
|
|
1603
|
-
"at",
|
|
1604
|
-
"entries",
|
|
1605
|
-
"keys",
|
|
1606
|
-
"values"
|
|
1607
|
-
];
|
|
1608
|
-
const ARRAY_MUTATING = ["push", "pop", "shift", "unshift", "splice", "sort", "reverse", "fill", "copyWithin"];
|
|
1609
|
-
const ARRAY_ITERATION = ["map", "forEach", "filter", "find", "findIndex", "some", "every", "flatMap"];
|
|
1610
|
-
const getOrSet = (map2, key, factory) => {
|
|
1611
|
-
let v = map2.get(key);
|
|
1612
|
-
if (!v) {
|
|
1613
|
-
v = factory();
|
|
1614
|
-
map2.set(key, v);
|
|
1615
|
-
}
|
|
1616
|
-
return v;
|
|
1617
|
-
};
|
|
1618
|
-
const proxyGet = (target, prop, receiver, signals) => {
|
|
1619
|
-
if (prop === "__parent__") return parents.get(receiver);
|
|
1620
|
-
if (!signals.has(prop)) {
|
|
1621
|
-
signals.set(prop, signal(Reflect.get(target, prop, receiver)));
|
|
1622
|
-
}
|
|
1623
|
-
const signal$1 = signals.get(prop);
|
|
1624
|
-
const val = signal$1.value;
|
|
1625
|
-
if (typeof val === "object" && val !== null) {
|
|
1626
|
-
const childProxy = state(val);
|
|
1627
|
-
parents.set(childProxy, receiver);
|
|
1628
|
-
return childProxy;
|
|
1629
|
-
}
|
|
1630
|
-
return val;
|
|
1631
|
-
};
|
|
1632
|
-
const proxySet = (target, prop, value, receiver, signals) => {
|
|
1633
|
-
if (!signals.has(prop)) {
|
|
1634
|
-
signals.set(prop, signal(Reflect.get(target, prop, receiver)));
|
|
1635
|
-
}
|
|
1636
|
-
const success = Reflect.set(target, prop, value, receiver);
|
|
1637
|
-
const signal$1 = signals.get(prop);
|
|
1638
|
-
if (success && signal$1) signal$1.value = value;
|
|
1639
|
-
return success;
|
|
1640
|
-
};
|
|
1641
|
-
const createSpecialProxy = (obj, monitor, trackingProps = []) => {
|
|
1642
|
-
const signals = getOrSet(stateSignals, obj, () => /* @__PURE__ */ new Map());
|
|
1643
|
-
if (!signals.has(monitor)) {
|
|
1644
|
-
const initialValue = typeof obj[monitor] === "function" ? obj[monitor].call(obj) : obj[monitor];
|
|
1645
|
-
signals.set(monitor, signal(initialValue));
|
|
1646
|
-
}
|
|
1647
|
-
const isDate = obj instanceof Date;
|
|
1648
|
-
const isArray = Array.isArray(obj);
|
|
1649
|
-
const trackingMethods = isDate ? DATE_TRACKING : isArray ? ARRAY_TRACKING : trackingProps;
|
|
1650
|
-
const mutatingMethods = isDate ? DATE_MUTATING : isArray ? ARRAY_MUTATING : [];
|
|
1651
|
-
return new Proxy(obj, {
|
|
1652
|
-
get(target, prop, receiver) {
|
|
1653
|
-
if (prop === "__parent__") return parents.get(receiver);
|
|
1654
|
-
const value = target[prop];
|
|
1655
|
-
if (typeof value === "function") {
|
|
1656
|
-
const isTracking = trackingMethods.includes(prop);
|
|
1657
|
-
const isMutating = mutatingMethods.includes(prop);
|
|
1658
|
-
return function(...args) {
|
|
1659
|
-
if (isTracking) {
|
|
1660
|
-
const sig = signals.get(monitor);
|
|
1661
|
-
if (sig) void sig.value;
|
|
1662
|
-
}
|
|
1663
|
-
const startValue = typeof target[monitor] === "function" ? target[monitor].call(target) : target[monitor];
|
|
1664
|
-
if (isArray && ARRAY_ITERATION.includes(prop) && typeof args[0] === "function") {
|
|
1665
|
-
const originalCallback = args[0];
|
|
1666
|
-
args[0] = function(element, index2, array) {
|
|
1667
|
-
const wrappedElement = typeof element === "object" && element !== null ? state(element) : element;
|
|
1668
|
-
if (wrappedElement && typeof wrappedElement === "object") {
|
|
1669
|
-
parents.set(wrappedElement, receiver);
|
|
1670
|
-
}
|
|
1671
|
-
return originalCallback.call(this, wrappedElement, index2, array);
|
|
1672
|
-
};
|
|
1673
|
-
}
|
|
1674
|
-
const result = value.apply(target, args);
|
|
1675
|
-
const endValue = typeof target[monitor] === "function" ? target[monitor].call(target) : target[monitor];
|
|
1676
|
-
if (startValue !== endValue || isMutating) {
|
|
1677
|
-
const sig = signals.get(monitor);
|
|
1678
|
-
if (sig && sig.value !== endValue) {
|
|
1679
|
-
sig.value = endValue;
|
|
1680
|
-
}
|
|
1681
|
-
}
|
|
1682
|
-
return result;
|
|
1683
|
-
};
|
|
1684
|
-
}
|
|
1685
|
-
if (prop === monitor) {
|
|
1686
|
-
const sig = signals.get(monitor);
|
|
1687
|
-
return sig ? sig.value : Reflect.get(target, prop, receiver);
|
|
1688
|
-
}
|
|
1689
|
-
if (isArray && !isNaN(parseInt(prop))) {
|
|
1690
|
-
const monitorSig = signals.get(monitor);
|
|
1691
|
-
if (monitorSig) void monitorSig.value;
|
|
1692
|
-
}
|
|
1693
|
-
return proxyGet(target, prop, receiver, signals);
|
|
1694
|
-
},
|
|
1695
|
-
set(target, prop, value, receiver) {
|
|
1696
|
-
if (prop === monitor) {
|
|
1697
|
-
const success = Reflect.set(target, prop, value, receiver);
|
|
1698
|
-
if (success) {
|
|
1699
|
-
const sig = signals.get(monitor);
|
|
1700
|
-
if (sig) sig.value = value;
|
|
1701
|
-
}
|
|
1702
|
-
return success;
|
|
1703
|
-
}
|
|
1704
|
-
return proxySet(target, prop, value, receiver, signals);
|
|
1705
|
-
}
|
|
1706
|
-
});
|
|
1707
|
-
};
|
|
1708
|
-
const state = (obj, optionsOrName) => {
|
|
1709
|
-
if (typeof obj !== "object" || obj === null) return obj;
|
|
1710
|
-
const name = typeof optionsOrName === "string" ? optionsOrName : optionsOrName == null ? void 0 : optionsOrName.name;
|
|
1711
|
-
const storage = optionsOrName == null ? void 0 : optionsOrName.storage;
|
|
1712
|
-
if (name && storage) {
|
|
1713
|
-
try {
|
|
1714
|
-
const item = storage.getItem(name);
|
|
1715
|
-
if (item) {
|
|
1716
|
-
const loaded = JSON.parse(item);
|
|
1717
|
-
Array.isArray(obj) && Array.isArray(loaded) ? (obj.length = 0, obj.push(...loaded)) : Object.assign(obj, loaded);
|
|
1718
|
-
}
|
|
1719
|
-
} catch (e) {
|
|
1720
|
-
}
|
|
1721
|
-
}
|
|
1722
|
-
let proxy = stateCache.get(obj);
|
|
1723
|
-
if (!proxy) {
|
|
1724
|
-
const isArray = Array.isArray(obj), isDate = obj instanceof Date;
|
|
1725
|
-
const isSpecial = isArray || isDate;
|
|
1726
|
-
const monitor = isArray ? "length" : isDate ? "getTime" : null;
|
|
1727
|
-
if (isSpecial || !(obj instanceof RegExp || obj instanceof Map || obj instanceof Set || obj instanceof WeakMap || obj instanceof WeakSet)) {
|
|
1728
|
-
proxy = isSpecial ? createSpecialProxy(obj, monitor) : new Proxy(obj, {
|
|
1729
|
-
get(t, p, r) {
|
|
1730
|
-
if (p === "__parent__") return parents.get(r);
|
|
1731
|
-
return proxyGet(t, p, r, getOrSet(stateSignals, t, () => /* @__PURE__ */ new Map()));
|
|
1732
|
-
},
|
|
1733
|
-
set(t, p, v, r) {
|
|
1734
|
-
return proxySet(t, p, v, r, getOrSet(stateSignals, t, () => /* @__PURE__ */ new Map()));
|
|
1735
|
-
}
|
|
1736
|
-
});
|
|
1737
|
-
stateCache.set(obj, proxy);
|
|
1738
|
-
} else return obj;
|
|
1739
|
-
}
|
|
1740
|
-
if (name && storage) {
|
|
1741
|
-
effect(() => {
|
|
1742
|
-
try {
|
|
1743
|
-
storage.setItem(name, JSON.stringify(proxy));
|
|
1744
|
-
} catch (e) {
|
|
1745
|
-
}
|
|
1746
|
-
});
|
|
1747
|
-
}
|
|
1748
|
-
if (name) {
|
|
1749
|
-
const registry = getRegistry();
|
|
1750
|
-
if (registry.has(name)) {
|
|
1751
|
-
if (registry.get(name) !== proxy) {
|
|
1752
|
-
throw new Error(`Lightview: A signal or state with the name "${name}" is already registered.`);
|
|
1753
|
-
}
|
|
1754
|
-
} else {
|
|
1755
|
-
registry.set(name, proxy);
|
|
1756
|
-
}
|
|
1757
|
-
}
|
|
1758
|
-
return proxy;
|
|
1759
|
-
};
|
|
1760
|
-
const getState = (name, defaultValue) => {
|
|
1761
|
-
const registry = getRegistry();
|
|
1762
|
-
if (!registry.has(name) && defaultValue !== void 0) {
|
|
1763
|
-
return state(defaultValue, name);
|
|
1764
|
-
}
|
|
1765
|
-
return registry.get(name);
|
|
1766
|
-
};
|
|
1767
|
-
state.get = getState;
|
|
1578
|
+
protoMethods(Date.prototype, (k) => /^(to|get|valueOf)/.test(k));
|
|
1579
|
+
protoMethods(Date.prototype, (k) => /^set/.test(k));
|
|
1768
1580
|
registerMathHelpers(registerHelper);
|
|
1769
1581
|
registerLogicHelpers(registerHelper);
|
|
1770
1582
|
registerStringHelpers(registerHelper);
|
|
@@ -1777,6 +1589,74 @@ var LightviewCDOM = function(exports) {
|
|
|
1777
1589
|
registerStatsHelpers(registerHelper);
|
|
1778
1590
|
registerStateHelpers((name, fn) => registerHelper(name, fn, { pathAware: true }));
|
|
1779
1591
|
registerNetworkHelpers(registerHelper);
|
|
1592
|
+
registerHelper("move", (selector, location = "beforeend") => {
|
|
1593
|
+
return {
|
|
1594
|
+
isLazy: true,
|
|
1595
|
+
resolve: (eventOrNode) => {
|
|
1596
|
+
const isEvent = eventOrNode && typeof eventOrNode === "object" && "target" in eventOrNode;
|
|
1597
|
+
const node = isEvent ? eventOrNode.currentTarget || eventOrNode.target : eventOrNode;
|
|
1598
|
+
if (!(node instanceof Node) || !selector) return;
|
|
1599
|
+
const target = document.querySelector(selector);
|
|
1600
|
+
if (!target) {
|
|
1601
|
+
console.warn(`[Lightview-CDOM] move target not found: ${selector}`);
|
|
1602
|
+
return;
|
|
1603
|
+
}
|
|
1604
|
+
if (node.id) {
|
|
1605
|
+
const escapedId = CSS.escape(node.id);
|
|
1606
|
+
if (target.id === node.id && target !== node) {
|
|
1607
|
+
target.replaceWith(node);
|
|
1608
|
+
return;
|
|
1609
|
+
}
|
|
1610
|
+
const existing = target.querySelector(`#${escapedId}`);
|
|
1611
|
+
if (existing && existing !== node) {
|
|
1612
|
+
existing.replaceWith(node);
|
|
1613
|
+
return;
|
|
1614
|
+
}
|
|
1615
|
+
}
|
|
1616
|
+
globalThis.Lightview.$(target).content(node, location);
|
|
1617
|
+
}
|
|
1618
|
+
};
|
|
1619
|
+
}, { pathAware: true });
|
|
1620
|
+
registerHelper("mount", async (url, options = {}) => {
|
|
1621
|
+
const { target = "body", location = "beforeend" } = options;
|
|
1622
|
+
try {
|
|
1623
|
+
const fetchOptions = { ...options };
|
|
1624
|
+
delete fetchOptions.target;
|
|
1625
|
+
delete fetchOptions.location;
|
|
1626
|
+
const headers = { ...fetchOptions.headers };
|
|
1627
|
+
let body = fetchOptions.body;
|
|
1628
|
+
if (body !== void 0) {
|
|
1629
|
+
if (body !== null && typeof body === "object") {
|
|
1630
|
+
body = JSON.stringify(body);
|
|
1631
|
+
if (!headers["Content-Type"]) headers["Content-Type"] = "application/json";
|
|
1632
|
+
} else {
|
|
1633
|
+
body = String(body);
|
|
1634
|
+
if (!headers["Content-Type"]) headers["Content-Type"] = "text/plain";
|
|
1635
|
+
}
|
|
1636
|
+
fetchOptions.body = body;
|
|
1637
|
+
fetchOptions.headers = headers;
|
|
1638
|
+
}
|
|
1639
|
+
const response = await globalThis.fetch(url, fetchOptions);
|
|
1640
|
+
const contentType = response.headers.get("Content-Type") || "";
|
|
1641
|
+
const text = await response.text();
|
|
1642
|
+
let content = text;
|
|
1643
|
+
const isCDOM = contentType.includes("application/cdom") || contentType.includes("application/jprx") || contentType.includes("application/vdom") || contentType.includes("application/odom") || url.endsWith(".cdom") || url.endsWith(".jprx") || url.endsWith(".vdom") || url.endsWith(".odom");
|
|
1644
|
+
if (isCDOM || contentType.includes("application/json") && text.trim().startsWith("{")) {
|
|
1645
|
+
try {
|
|
1646
|
+
content = hydrate(parseJPRX(text));
|
|
1647
|
+
} catch (e) {
|
|
1648
|
+
}
|
|
1649
|
+
}
|
|
1650
|
+
const targetEl = document.querySelector(target);
|
|
1651
|
+
if (targetEl) {
|
|
1652
|
+
globalThis.Lightview.$(targetEl).content(content, location);
|
|
1653
|
+
} else {
|
|
1654
|
+
console.warn(`[Lightview-CDOM] $mount target not found: ${target}`);
|
|
1655
|
+
}
|
|
1656
|
+
} catch (err) {
|
|
1657
|
+
console.error(`[Lightview-CDOM] $mount failed for ${url}:`, err);
|
|
1658
|
+
}
|
|
1659
|
+
});
|
|
1780
1660
|
registerOperator("increment", "++", "prefix", 80);
|
|
1781
1661
|
registerOperator("increment", "++", "postfix", 80);
|
|
1782
1662
|
registerOperator("decrement", "--", "prefix", 80);
|
|
@@ -1791,309 +1671,135 @@ var LightviewCDOM = function(exports) {
|
|
|
1791
1671
|
registerOperator("gte", ">=", "infix", 40);
|
|
1792
1672
|
registerOperator("lte", "<=", "infix", 40);
|
|
1793
1673
|
registerOperator("neq", "!=", "infix", 40);
|
|
1794
|
-
const localStates = /* @__PURE__ */ new WeakMap();
|
|
1795
1674
|
const getContext = (node, event = null) => {
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
const ShadowRoot = globalThis.ShadowRoot;
|
|
1799
|
-
while (cur) {
|
|
1800
|
-
const local = localStates.get(cur) || (cur && typeof cur === "object" ? cur.__state__ : null);
|
|
1801
|
-
if (local) chain.unshift(local);
|
|
1802
|
-
cur = cur.parentElement || (cur && typeof cur === "object" ? cur.__parent__ : null) || (ShadowRoot && cur.parentNode instanceof ShadowRoot ? cur.parentNode.host : null);
|
|
1803
|
-
}
|
|
1804
|
-
const globalRegistry = getRegistry();
|
|
1805
|
-
const handler = {
|
|
1806
|
-
get(target, prop, receiver) {
|
|
1807
|
-
var _a;
|
|
1675
|
+
return new Proxy({}, {
|
|
1676
|
+
get(_, prop) {
|
|
1808
1677
|
if (prop === "$event" || prop === "event") return event;
|
|
1809
|
-
if (prop === "
|
|
1810
|
-
|
|
1811
|
-
const s = chain[i];
|
|
1812
|
-
if (prop in s) return s[prop];
|
|
1813
|
-
}
|
|
1814
|
-
if (globalRegistry && globalRegistry.has(prop)) return unwrapSignal(globalRegistry.get(prop));
|
|
1815
|
-
const globalState = (_a = globalThis.Lightview) == null ? void 0 : _a.state;
|
|
1816
|
-
if (globalState && prop in globalState) return unwrapSignal(globalState[prop]);
|
|
1817
|
-
return void 0;
|
|
1678
|
+
if (prop === "$this" || prop === "this" || prop === "__node__") return node;
|
|
1679
|
+
return unwrapSignal(globalThis.Lightview.getState(prop, { scope: node }));
|
|
1818
1680
|
},
|
|
1819
|
-
set(
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
if (prop in s) {
|
|
1824
|
-
s[prop] = value;
|
|
1825
|
-
return true;
|
|
1826
|
-
}
|
|
1827
|
-
}
|
|
1828
|
-
if (chain.length > 0) {
|
|
1829
|
-
chain[chain.length - 1][prop] = value;
|
|
1681
|
+
set(_, prop, value) {
|
|
1682
|
+
const res = globalThis.Lightview.getState(prop, { scope: node });
|
|
1683
|
+
if (res && (typeof res === "object" || typeof res === "function") && "value" in res) {
|
|
1684
|
+
res.value = value;
|
|
1830
1685
|
return true;
|
|
1831
1686
|
}
|
|
1832
|
-
const globalState = (_a = globalThis.Lightview) == null ? void 0 : _a.state;
|
|
1833
|
-
if (globalState && prop in globalState) {
|
|
1834
|
-
globalState[prop] = value;
|
|
1835
|
-
return true;
|
|
1836
|
-
}
|
|
1837
|
-
if (globalRegistry && globalRegistry.has(prop)) {
|
|
1838
|
-
const s = globalRegistry.get(prop);
|
|
1839
|
-
if (s && (typeof s === "object" || typeof s === "function") && "value" in s) {
|
|
1840
|
-
s.value = value;
|
|
1841
|
-
return true;
|
|
1842
|
-
}
|
|
1843
|
-
}
|
|
1844
1687
|
return false;
|
|
1845
|
-
},
|
|
1846
|
-
has(target, prop) {
|
|
1847
|
-
var _a;
|
|
1848
|
-
const exists = prop === "$event" || prop === "event" || !!chain.find((s) => prop in s);
|
|
1849
|
-
const inGlobal = ((_a = globalThis.Lightview) == null ? void 0 : _a.state) && prop in globalThis.Lightview.state || globalRegistry && globalRegistry.has(prop);
|
|
1850
|
-
return exists || inGlobal;
|
|
1851
|
-
},
|
|
1852
|
-
ownKeys(target) {
|
|
1853
|
-
var _a;
|
|
1854
|
-
const keys = /* @__PURE__ */ new Set();
|
|
1855
|
-
if (event) {
|
|
1856
|
-
keys.add("$event");
|
|
1857
|
-
keys.add("event");
|
|
1858
|
-
}
|
|
1859
|
-
for (const s of chain) {
|
|
1860
|
-
for (const key in s) keys.add(key);
|
|
1861
|
-
}
|
|
1862
|
-
const globalState = (_a = globalThis.Lightview) == null ? void 0 : _a.state;
|
|
1863
|
-
if (globalState) {
|
|
1864
|
-
for (const key in globalState) keys.add(key);
|
|
1865
|
-
}
|
|
1866
|
-
return Array.from(keys);
|
|
1867
|
-
},
|
|
1868
|
-
getOwnPropertyDescriptor(target, prop) {
|
|
1869
|
-
return { enumerable: true, configurable: true };
|
|
1870
|
-
}
|
|
1871
|
-
};
|
|
1872
|
-
return new Proxy({}, handler);
|
|
1873
|
-
};
|
|
1874
|
-
const handleCDOMState = (node) => {
|
|
1875
|
-
var _a;
|
|
1876
|
-
const attr = node["cdom-state"] || node.getAttribute && node.getAttribute("cdom-state");
|
|
1877
|
-
if (!attr || localStates.has(node)) return;
|
|
1878
|
-
try {
|
|
1879
|
-
const data = typeof attr === "object" ? attr : JSON.parse(attr);
|
|
1880
|
-
const s = state(data);
|
|
1881
|
-
localStates.set(node, s);
|
|
1882
|
-
if (node && typeof node === "object") {
|
|
1883
|
-
node.__state__ = s;
|
|
1884
|
-
}
|
|
1885
|
-
} catch (e) {
|
|
1886
|
-
(_a = globalThis.console) == null ? void 0 : _a.error("LightviewCDOM: Failed to parse cdom-state", e);
|
|
1887
|
-
}
|
|
1888
|
-
};
|
|
1889
|
-
const handleCDOMBind = (node) => {
|
|
1890
|
-
const path = node["cdom-bind"] || node.getAttribute("cdom-bind");
|
|
1891
|
-
if (!path) return;
|
|
1892
|
-
const type = node.type || "";
|
|
1893
|
-
const tagName = node.tagName.toLowerCase();
|
|
1894
|
-
let prop = "value";
|
|
1895
|
-
let event = "input";
|
|
1896
|
-
if (type === "checkbox" || type === "radio") {
|
|
1897
|
-
prop = "checked";
|
|
1898
|
-
event = "change";
|
|
1899
|
-
} else if (tagName === "select") {
|
|
1900
|
-
event = "change";
|
|
1901
|
-
}
|
|
1902
|
-
const context = getContext(node);
|
|
1903
|
-
let target = resolvePathAsContext(path, context);
|
|
1904
|
-
if (target && target.isBindingTarget && target.value === void 0) {
|
|
1905
|
-
const val = node[prop];
|
|
1906
|
-
if (val !== void 0 && val !== "") {
|
|
1907
|
-
set(context, { [target.key]: val });
|
|
1908
|
-
target = resolvePathAsContext(path, context);
|
|
1909
|
-
}
|
|
1910
|
-
}
|
|
1911
|
-
effect(() => {
|
|
1912
|
-
const val = unwrapSignal(target);
|
|
1913
|
-
if (node[prop] !== val) {
|
|
1914
|
-
node[prop] = val === void 0 ? "" : val;
|
|
1915
|
-
}
|
|
1916
|
-
});
|
|
1917
|
-
node.addEventListener(event, () => {
|
|
1918
|
-
const val = node[prop];
|
|
1919
|
-
if (target && target.isBindingTarget) {
|
|
1920
|
-
target.value = val;
|
|
1921
|
-
} else {
|
|
1922
|
-
set(context, { [path]: val });
|
|
1923
1688
|
}
|
|
1924
1689
|
});
|
|
1925
1690
|
};
|
|
1691
|
+
globalThis.Lightview.hooks.processAttribute = (domNode, key, value) => {
|
|
1692
|
+
if (value == null ? void 0 : value.__JPRX_BIND__) {
|
|
1693
|
+
const { path, options } = value;
|
|
1694
|
+
const type = domNode.type || "";
|
|
1695
|
+
const tagName = domNode.tagName.toLowerCase();
|
|
1696
|
+
let prop = "value";
|
|
1697
|
+
let event = "input";
|
|
1698
|
+
if (type === "checkbox" || type === "radio") {
|
|
1699
|
+
prop = "checked";
|
|
1700
|
+
event = "change";
|
|
1701
|
+
} else if (tagName === "select") {
|
|
1702
|
+
event = "change";
|
|
1703
|
+
}
|
|
1704
|
+
const res = globalThis.Lightview.get(path.replace(/^=/, ""), { scope: domNode });
|
|
1705
|
+
const runner = globalThis.Lightview.effect(() => {
|
|
1706
|
+
const val = unwrapSignal(res);
|
|
1707
|
+
if (domNode[prop] !== val) {
|
|
1708
|
+
domNode[prop] = val === void 0 ? "" : val;
|
|
1709
|
+
}
|
|
1710
|
+
});
|
|
1711
|
+
globalThis.Lightview.internals.trackEffect(domNode, runner);
|
|
1712
|
+
domNode.addEventListener(event, () => {
|
|
1713
|
+
if (res && "value" in res) res.value = domNode[prop];
|
|
1714
|
+
});
|
|
1715
|
+
return unwrapSignal(res) ?? domNode[prop];
|
|
1716
|
+
}
|
|
1717
|
+
return void 0;
|
|
1718
|
+
};
|
|
1926
1719
|
const activate = (root = document.body) => {
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
child = child.nextSibling;
|
|
1936
|
-
}
|
|
1937
|
-
};
|
|
1938
|
-
walk(root);
|
|
1720
|
+
};
|
|
1721
|
+
const makeEventHandler = (expr) => (eventOrNode) => {
|
|
1722
|
+
const isEvent = eventOrNode && typeof eventOrNode === "object" && "target" in eventOrNode;
|
|
1723
|
+
const target = isEvent ? eventOrNode.currentTarget || eventOrNode.target : eventOrNode;
|
|
1724
|
+
const context = getContext(target, isEvent ? eventOrNode : null);
|
|
1725
|
+
const result = resolveExpression(expr, context);
|
|
1726
|
+
if (result && typeof result === "object" && result.isLazy) return result.resolve(eventOrNode);
|
|
1727
|
+
return result;
|
|
1939
1728
|
};
|
|
1940
1729
|
const hydrate = (node, parent = null) => {
|
|
1730
|
+
var _a, _b, _c;
|
|
1941
1731
|
if (!node) return node;
|
|
1942
|
-
if (typeof node === "string" && node.startsWith("
|
|
1732
|
+
if (typeof node === "string" && node.startsWith("'=")) {
|
|
1733
|
+
return node.slice(1);
|
|
1734
|
+
}
|
|
1735
|
+
if (typeof node === "string" && node.startsWith("=")) {
|
|
1943
1736
|
return parseExpression(node, parent);
|
|
1944
1737
|
}
|
|
1738
|
+
if (typeof node !== "object") return node;
|
|
1945
1739
|
if (Array.isArray(node)) {
|
|
1946
1740
|
return node.map((item) => hydrate(item, parent));
|
|
1947
1741
|
}
|
|
1948
|
-
if (node instanceof String)
|
|
1949
|
-
|
|
1742
|
+
if (node instanceof String) return node.toString();
|
|
1743
|
+
if (parent && !("__parent__" in node)) {
|
|
1744
|
+
Object.defineProperty(node, "__parent__", { value: parent, enumerable: false, writable: true });
|
|
1745
|
+
(_c = (_b = (_a = globalThis.Lightview) == null ? void 0 : _a.internals) == null ? void 0 : _b.parents) == null ? void 0 : _c.set(node, parent);
|
|
1950
1746
|
}
|
|
1951
|
-
if (
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
});
|
|
1747
|
+
if (!node.tag) {
|
|
1748
|
+
let potentialTag = null;
|
|
1749
|
+
const reserved = ["children", "attributes", "tag", "__parent__"];
|
|
1750
|
+
for (const key in node) {
|
|
1751
|
+
if (reserved.includes(key) || key.startsWith("on")) continue;
|
|
1752
|
+
potentialTag = key;
|
|
1753
|
+
break;
|
|
1959
1754
|
}
|
|
1960
|
-
if (
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
1755
|
+
if (potentialTag) {
|
|
1756
|
+
const content = node[potentialTag];
|
|
1757
|
+
node.tag = potentialTag;
|
|
1758
|
+
if (Array.isArray(content)) {
|
|
1759
|
+
node.children = content;
|
|
1760
|
+
} else if (typeof content === "object") {
|
|
1761
|
+
node.attributes = node.attributes || {};
|
|
1762
|
+
for (const k in content) {
|
|
1763
|
+
if (k === "children") node.children = content[k];
|
|
1764
|
+
else node.attributes[k] = content[k];
|
|
1965
1765
|
}
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
"
|
|
1980
|
-
|
|
1981
|
-
"multiple",
|
|
1982
|
-
"rows",
|
|
1983
|
-
"cols",
|
|
1984
|
-
"size",
|
|
1985
|
-
"maxlength",
|
|
1986
|
-
"minlength",
|
|
1987
|
-
"autocomplete",
|
|
1988
|
-
// Common element attributes
|
|
1989
|
-
"id",
|
|
1990
|
-
"class",
|
|
1991
|
-
"className",
|
|
1992
|
-
"style",
|
|
1993
|
-
"title",
|
|
1994
|
-
"tabindex",
|
|
1995
|
-
"role",
|
|
1996
|
-
"href",
|
|
1997
|
-
"src",
|
|
1998
|
-
"alt",
|
|
1999
|
-
"width",
|
|
2000
|
-
"height",
|
|
2001
|
-
"target",
|
|
2002
|
-
"rel",
|
|
2003
|
-
// Data attributes
|
|
2004
|
-
"data",
|
|
2005
|
-
"label",
|
|
2006
|
-
"text",
|
|
2007
|
-
"description",
|
|
2008
|
-
"content",
|
|
2009
|
-
// Common data property names
|
|
2010
|
-
"price",
|
|
2011
|
-
"qty",
|
|
2012
|
-
"items",
|
|
2013
|
-
"count",
|
|
2014
|
-
"total",
|
|
2015
|
-
"amount",
|
|
2016
|
-
"url"
|
|
2017
|
-
];
|
|
2018
|
-
if (attrNames.includes(key)) {
|
|
2019
|
-
continue;
|
|
2020
|
-
}
|
|
2021
|
-
potentialTag = key;
|
|
2022
|
-
break;
|
|
2023
|
-
}
|
|
2024
|
-
if (potentialTag) {
|
|
2025
|
-
const content = node[potentialTag];
|
|
2026
|
-
if (content !== void 0 && content !== null) {
|
|
2027
|
-
node.tag = potentialTag;
|
|
2028
|
-
if (Array.isArray(content)) {
|
|
2029
|
-
node.children = content;
|
|
2030
|
-
} else if (typeof content === "object") {
|
|
2031
|
-
node.attributes = node.attributes || {};
|
|
2032
|
-
for (const k in content) {
|
|
2033
|
-
if (k === "children") {
|
|
2034
|
-
node.children = content[k];
|
|
2035
|
-
} else if (k.startsWith("cdom-")) {
|
|
2036
|
-
node[k] = content[k];
|
|
2037
|
-
} else {
|
|
2038
|
-
node.attributes[k] = content[k];
|
|
2039
|
-
}
|
|
2040
|
-
}
|
|
1766
|
+
} else node.children = [content];
|
|
1767
|
+
delete node[potentialTag];
|
|
1768
|
+
}
|
|
1769
|
+
}
|
|
1770
|
+
for (const key in node) {
|
|
1771
|
+
if (key === "tag" || key === "__parent__") continue;
|
|
1772
|
+
const value = node[key];
|
|
1773
|
+
if (key === "attributes" && typeof value === "object" && value !== null) {
|
|
1774
|
+
for (const attrKey in value) {
|
|
1775
|
+
const attrVal = value[attrKey];
|
|
1776
|
+
if (typeof attrVal === "string" && attrVal.startsWith("'=")) {
|
|
1777
|
+
value[attrKey] = attrVal.slice(1);
|
|
1778
|
+
} else if (typeof attrVal === "string" && attrVal.startsWith("=")) {
|
|
1779
|
+
if (attrKey.startsWith("on")) {
|
|
1780
|
+
value[attrKey] = makeEventHandler(attrVal);
|
|
2041
1781
|
} else {
|
|
2042
|
-
|
|
1782
|
+
value[attrKey] = parseExpression(attrVal, node);
|
|
2043
1783
|
}
|
|
2044
|
-
|
|
1784
|
+
} else if (typeof attrVal === "object" && attrVal !== null) {
|
|
1785
|
+
value[attrKey] = hydrate(attrVal, node);
|
|
2045
1786
|
}
|
|
2046
1787
|
}
|
|
1788
|
+
continue;
|
|
2047
1789
|
}
|
|
2048
|
-
if (
|
|
2049
|
-
|
|
2050
|
-
}
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
if (key === "
|
|
2054
|
-
|
|
2055
|
-
}
|
|
2056
|
-
if (typeof value === "string" && value.startsWith("$")) {
|
|
2057
|
-
if (key.startsWith("on")) {
|
|
2058
|
-
node[key] = (event) => {
|
|
2059
|
-
const element = event.currentTarget;
|
|
2060
|
-
const context = getContext(element, event);
|
|
2061
|
-
const result = resolveExpression(value, context);
|
|
2062
|
-
if (result && typeof result === "object" && result.isLazy && typeof result.resolve === "function") {
|
|
2063
|
-
return result.resolve(event);
|
|
2064
|
-
}
|
|
2065
|
-
return result;
|
|
2066
|
-
};
|
|
2067
|
-
} else if (key === "children") {
|
|
2068
|
-
node[key] = [parseExpression(value, node)];
|
|
2069
|
-
} else {
|
|
2070
|
-
node[key] = parseExpression(value, node);
|
|
2071
|
-
}
|
|
2072
|
-
} else if (key === "attributes" && typeof value === "object" && value !== null) {
|
|
2073
|
-
for (const attrKey in value) {
|
|
2074
|
-
const attrValue = value[attrKey];
|
|
2075
|
-
if (typeof attrValue === "string" && attrValue.startsWith("$")) {
|
|
2076
|
-
if (attrKey.startsWith("on")) {
|
|
2077
|
-
value[attrKey] = (event) => {
|
|
2078
|
-
const element = event.currentTarget;
|
|
2079
|
-
const context = getContext(element, event);
|
|
2080
|
-
const result = resolveExpression(attrValue, context);
|
|
2081
|
-
if (result && typeof result === "object" && result.isLazy && typeof result.resolve === "function") {
|
|
2082
|
-
return result.resolve(event);
|
|
2083
|
-
}
|
|
2084
|
-
return result;
|
|
2085
|
-
};
|
|
2086
|
-
} else {
|
|
2087
|
-
value[attrKey] = parseExpression(attrValue, node);
|
|
2088
|
-
}
|
|
2089
|
-
}
|
|
2090
|
-
}
|
|
2091
|
-
node[key] = value;
|
|
1790
|
+
if (typeof value === "string" && value.startsWith("'=")) {
|
|
1791
|
+
node[key] = value.slice(1);
|
|
1792
|
+
} else if (typeof value === "string" && value.startsWith("=")) {
|
|
1793
|
+
if (key === "onmount" || key === "onunmount" || key.startsWith("on")) {
|
|
1794
|
+
node[key] = makeEventHandler(value);
|
|
1795
|
+
} else if (key === "children") {
|
|
1796
|
+
node[key] = [parseExpression(value, node)];
|
|
2092
1797
|
} else {
|
|
2093
|
-
node[key] =
|
|
1798
|
+
node[key] = parseExpression(value, node);
|
|
2094
1799
|
}
|
|
1800
|
+
} else {
|
|
1801
|
+
node[key] = hydrate(value, node);
|
|
2095
1802
|
}
|
|
2096
|
-
return node;
|
|
2097
1803
|
}
|
|
2098
1804
|
return node;
|
|
2099
1805
|
};
|
|
@@ -2108,8 +1814,10 @@ var LightviewCDOM = function(exports) {
|
|
|
2108
1814
|
parseJPRX,
|
|
2109
1815
|
unwrapSignal,
|
|
2110
1816
|
getContext,
|
|
2111
|
-
handleCDOMState
|
|
2112
|
-
|
|
1817
|
+
handleCDOMState: () => {
|
|
1818
|
+
},
|
|
1819
|
+
handleCDOMBind: () => {
|
|
1820
|
+
},
|
|
2113
1821
|
activate,
|
|
2114
1822
|
hydrate,
|
|
2115
1823
|
version: "1.0.0"
|
|
@@ -2120,8 +1828,6 @@ var LightviewCDOM = function(exports) {
|
|
|
2120
1828
|
exports.activate = activate;
|
|
2121
1829
|
exports.default = LightviewCDOM2;
|
|
2122
1830
|
exports.getContext = getContext;
|
|
2123
|
-
exports.handleCDOMBind = handleCDOMBind;
|
|
2124
|
-
exports.handleCDOMState = handleCDOMState;
|
|
2125
1831
|
exports.hydrate = hydrate;
|
|
2126
1832
|
Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
|
|
2127
1833
|
return exports;
|