valyrian.js 7.2.11 → 8.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -6
- package/dist/flux-store/index.d.ts +32 -0
- package/dist/flux-store/index.d.ts.map +1 -0
- package/dist/flux-store/index.js +258 -0
- package/dist/flux-store/index.js.map +7 -0
- package/dist/flux-store/index.min.js +1 -0
- package/dist/flux-store/index.min.js.map +1 -0
- package/dist/flux-store/index.mjs +237 -0
- package/dist/flux-store/index.mjs.map +7 -0
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +42 -75
- package/dist/hooks/index.js.map +2 -2
- package/dist/hooks/index.min.js +1 -0
- package/dist/hooks/index.min.js.map +1 -0
- package/dist/hooks/index.mjs +43 -76
- package/dist/hooks/index.mjs.map +2 -2
- package/dist/index.d.ts +52 -54
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +397 -328
- package/dist/index.js.map +3 -3
- package/dist/index.min.js +1 -1
- package/dist/index.min.js.map +1 -1
- package/dist/index.mjs +397 -328
- package/dist/index.mjs.map +3 -3
- package/dist/native-store/index.d.ts +14 -0
- package/dist/native-store/index.d.ts.map +1 -0
- package/dist/native-store/index.js +103 -0
- package/dist/native-store/index.js.map +7 -0
- package/dist/native-store/index.min.js +1 -0
- package/dist/native-store/index.min.js.map +1 -0
- package/dist/native-store/index.mjs +82 -0
- package/dist/native-store/index.mjs.map +7 -0
- package/dist/node/index.d.ts.map +1 -1
- package/dist/node/index.js +223 -86
- package/dist/node/index.js.map +4 -4
- package/dist/node/index.mjs +223 -86
- package/dist/node/index.mjs.map +4 -4
- package/dist/node/node.sw.js +152 -0
- package/dist/node/utils/inline.d.ts.map +1 -1
- package/dist/node/utils/node.sw.js +152 -0
- package/dist/node/utils/session-storage.d.ts +22 -0
- package/dist/node/utils/session-storage.d.ts.map +1 -0
- package/dist/node/utils/sw.d.ts.map +1 -1
- package/dist/node/utils/tree-adapter.d.ts +9 -0
- package/dist/node/utils/tree-adapter.d.ts.map +1 -1
- package/dist/pulse-store/index.d.ts +13 -0
- package/dist/pulse-store/index.d.ts.map +1 -0
- package/dist/pulse-store/index.js +143 -0
- package/dist/pulse-store/index.js.map +7 -0
- package/dist/pulse-store/index.min.js +1 -0
- package/dist/pulse-store/index.min.js.map +1 -0
- package/dist/pulse-store/index.mjs +122 -0
- package/dist/pulse-store/index.mjs.map +7 -0
- package/dist/request/index.d.ts.map +1 -1
- package/dist/request/index.js +68 -89
- package/dist/request/index.js.map +2 -2
- package/dist/request/index.min.js +1 -0
- package/dist/request/index.min.js.map +1 -0
- package/dist/request/index.mjs +68 -89
- package/dist/request/index.mjs.map +2 -2
- package/dist/router/index.d.ts +32 -31
- package/dist/router/index.d.ts.map +1 -1
- package/dist/router/index.js +256 -104
- package/dist/router/index.js.map +3 -3
- package/dist/router/index.min.js +1 -0
- package/dist/router/index.min.js.map +1 -0
- package/dist/router/index.mjs +256 -104
- package/dist/router/index.mjs.map +3 -3
- package/dist/signals/index.d.ts +6 -0
- package/dist/signals/index.d.ts.map +1 -0
- package/dist/signals/index.js +92 -0
- package/dist/signals/index.js.map +7 -0
- package/dist/signals/index.min.js +1 -0
- package/dist/signals/index.min.js.map +1 -0
- package/dist/signals/index.mjs +71 -0
- package/dist/signals/index.mjs.map +7 -0
- package/dist/suspense/index.d.ts +6 -0
- package/dist/suspense/index.d.ts.map +1 -0
- package/dist/suspense/index.js +67 -0
- package/dist/suspense/index.js.map +7 -0
- package/dist/suspense/index.min.js +1 -0
- package/dist/suspense/index.min.js.map +1 -0
- package/dist/suspense/index.mjs +46 -0
- package/dist/suspense/index.mjs.map +7 -0
- package/dist/sw/index.min.js +1 -0
- package/dist/sw/index.min.js.map +1 -0
- package/dist/translate/index.d.ts +19 -0
- package/dist/translate/index.d.ts.map +1 -0
- package/dist/translate/index.js +150 -0
- package/dist/translate/index.js.map +7 -0
- package/dist/translate/index.min.js +1 -0
- package/dist/translate/index.min.js.map +1 -0
- package/dist/translate/index.mjs +129 -0
- package/dist/translate/index.mjs.map +7 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/utils/deep-freeze.d.ts +3 -0
- package/dist/utils/deep-freeze.d.ts.map +1 -0
- package/dist/utils/getter-setter.d.ts +3 -0
- package/dist/utils/getter-setter.d.ts.map +1 -0
- package/dist/utils/has-changed.d.ts +2 -0
- package/dist/utils/has-changed.d.ts.map +1 -0
- package/dist/utils/index.d.ts +4 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +138 -0
- package/dist/utils/index.js.map +7 -0
- package/dist/utils/index.min.js +1 -0
- package/dist/utils/index.min.js.map +1 -0
- package/dist/utils/index.mjs +115 -0
- package/dist/utils/index.mjs.map +7 -0
- package/lib/flux-store/index.ts +301 -0
- package/lib/hooks/index.ts +52 -101
- package/lib/index.ts +479 -719
- package/lib/native-store/index.ts +106 -0
- package/lib/node/index.ts +5 -3
- package/lib/node/utils/icons.ts +5 -5
- package/lib/node/utils/inline.ts +17 -17
- package/lib/node/utils/node.sw.js +152 -0
- package/lib/node/utils/session-storage.ts +117 -0
- package/lib/node/utils/sw.ts +35 -11
- package/lib/node/utils/tree-adapter.ts +99 -52
- package/lib/pulse-store/index.ts +181 -0
- package/lib/request/index.ts +86 -116
- package/lib/router/index.ts +358 -170
- package/lib/signals/index.ts +98 -0
- package/lib/suspense/index.ts +57 -0
- package/lib/translate/index.ts +156 -0
- package/lib/utils/deep-freeze.ts +54 -0
- package/lib/utils/getter-setter.ts +40 -0
- package/lib/utils/has-changed.ts +43 -0
- package/lib/utils/index.ts +3 -0
- package/package.json +38 -50
- package/tsconfig.json +1 -1
- package/dist/dataset/index.d.ts +0 -24
- package/dist/dataset/index.d.ts.map +0 -1
- package/dist/dataset/index.js +0 -178
- package/dist/dataset/index.js.map +0 -7
- package/dist/dataset/index.mjs +0 -157
- package/dist/dataset/index.mjs.map +0 -7
- package/dist/node/node.sw.tpl +0 -133
- package/dist/node/utils/node.sw.tpl +0 -133
- package/dist/proxy-signal/index.d.ts +0 -23
- package/dist/proxy-signal/index.d.ts.map +0 -1
- package/dist/proxy-signal/index.js +0 -138
- package/dist/proxy-signal/index.js.map +0 -7
- package/dist/proxy-signal/index.mjs +0 -117
- package/dist/proxy-signal/index.mjs.map +0 -7
- package/dist/signal/index.d.ts +0 -20
- package/dist/signal/index.d.ts.map +0 -1
- package/dist/signal/index.js +0 -95
- package/dist/signal/index.js.map +0 -7
- package/dist/signal/index.mjs +0 -74
- package/dist/signal/index.mjs.map +0 -7
- package/dist/store/index.d.ts +0 -16
- package/dist/store/index.d.ts.map +0 -1
- package/dist/store/index.js +0 -93
- package/dist/store/index.js.map +0 -7
- package/dist/store/index.mjs +0 -72
- package/dist/store/index.mjs.map +0 -7
- package/lib/dataset/index.ts +0 -193
- package/lib/index.d.ts +0 -0
- package/lib/interfaces.ts.bak +0 -141
- package/lib/node/utils/node.sw.tpl +0 -133
- package/lib/proxy-signal/index.ts +0 -187
- package/lib/signal/index.ts +0 -161
- package/lib/store/index.ts +0 -101
|
@@ -53,6 +53,16 @@ export class Node implements Node {
|
|
|
53
53
|
this.parent_node = node;
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
+
#dataset: Record<string | number, any> = {};
|
|
57
|
+
|
|
58
|
+
get dataset() {
|
|
59
|
+
return this.#dataset;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
set dataset(value) {
|
|
63
|
+
this.#dataset = value;
|
|
64
|
+
}
|
|
65
|
+
|
|
56
66
|
constructor() {}
|
|
57
67
|
|
|
58
68
|
appendChild<T extends Node>(node: T): T {
|
|
@@ -69,7 +79,7 @@ export class Node implements Node {
|
|
|
69
79
|
node.parentNode && node.parentNode.removeChild(node as Node);
|
|
70
80
|
node.parentNode = this;
|
|
71
81
|
if (child) {
|
|
72
|
-
|
|
82
|
+
const idx = this.childNodes.indexOf(child);
|
|
73
83
|
this.childNodes.splice(idx, 0, node);
|
|
74
84
|
} else {
|
|
75
85
|
this.childNodes.push(node);
|
|
@@ -87,19 +97,24 @@ export class Node implements Node {
|
|
|
87
97
|
}
|
|
88
98
|
removeChild<T extends Node>(child: T): T {
|
|
89
99
|
if (child && child.parentNode === this) {
|
|
90
|
-
|
|
100
|
+
const idx = (this.childNodes as unknown as Node[]).indexOf(child);
|
|
91
101
|
(this.childNodes as unknown as Node[]).splice(idx, 1);
|
|
92
102
|
child.parentNode = null;
|
|
93
103
|
}
|
|
94
104
|
return child;
|
|
95
105
|
}
|
|
106
|
+
|
|
107
|
+
remove(): Node {
|
|
108
|
+
return this.parentNode ? this.parentNode.removeChild(this) : this;
|
|
109
|
+
}
|
|
110
|
+
|
|
96
111
|
cloneNode(deep?: boolean | undefined): Node {
|
|
97
112
|
if (this.nodeType === 3) {
|
|
98
113
|
return new Text(this.nodeValue);
|
|
99
114
|
}
|
|
100
115
|
|
|
101
116
|
if (this.nodeType === 1) {
|
|
102
|
-
|
|
117
|
+
const node = new Element();
|
|
103
118
|
node.nodeType = this.nodeType;
|
|
104
119
|
this.nodeName = this.nodeName;
|
|
105
120
|
if (this.attributes) {
|
|
@@ -107,6 +122,11 @@ export class Node implements Node {
|
|
|
107
122
|
node.setAttribute(this.attributes[i].nodeName, this.attributes[i].nodeValue);
|
|
108
123
|
}
|
|
109
124
|
}
|
|
125
|
+
|
|
126
|
+
for (const key in this.dataset) {
|
|
127
|
+
node.dataset[key] = this.dataset[key];
|
|
128
|
+
}
|
|
129
|
+
|
|
110
130
|
if (deep) {
|
|
111
131
|
for (let i = 0, l = this.childNodes.length; i < l; i++) {
|
|
112
132
|
node.appendChild(this.childNodes[i].cloneNode(deep));
|
|
@@ -115,14 +135,14 @@ export class Node implements Node {
|
|
|
115
135
|
return node;
|
|
116
136
|
}
|
|
117
137
|
|
|
118
|
-
|
|
138
|
+
const node = new Node();
|
|
119
139
|
node.nodeType = this.nodeType;
|
|
120
140
|
node.nodeName = this.nodeName;
|
|
121
141
|
return node;
|
|
122
142
|
}
|
|
123
143
|
|
|
124
144
|
setAttribute(name: string, value: any) {
|
|
125
|
-
|
|
145
|
+
const attr = {
|
|
126
146
|
nodeName: name,
|
|
127
147
|
nodeValue: value
|
|
128
148
|
};
|
|
@@ -266,8 +286,8 @@ export class Text extends Node {
|
|
|
266
286
|
|
|
267
287
|
function updateElementStyles(element: Element, state: Record<string, any>) {
|
|
268
288
|
let str = "";
|
|
269
|
-
for (
|
|
270
|
-
|
|
289
|
+
for (const key in state) {
|
|
290
|
+
const value = state[key];
|
|
271
291
|
if (typeof value !== "undefined" && value !== null && String(value).length > 0) {
|
|
272
292
|
str += `${key}: ${state[key]};`;
|
|
273
293
|
}
|
|
@@ -324,11 +344,23 @@ export class Element extends Node {
|
|
|
324
344
|
throw new Error("Cannot set style");
|
|
325
345
|
}
|
|
326
346
|
|
|
347
|
+
get className(): string {
|
|
348
|
+
return this.getAttribute("class") || "";
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
set className(value: string | boolean) {
|
|
352
|
+
if (value == null || value === false) {
|
|
353
|
+
this.removeAttribute("class");
|
|
354
|
+
} else {
|
|
355
|
+
this.setAttribute("class", String(value));
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
|
|
327
359
|
classList = {
|
|
328
360
|
toggle: (item: any, force: any) => {
|
|
329
361
|
if (item) {
|
|
330
|
-
|
|
331
|
-
|
|
362
|
+
const classes = (this.className || "").split(" ");
|
|
363
|
+
const itemIndex = classes.indexOf(item);
|
|
332
364
|
if (force && itemIndex === -1) {
|
|
333
365
|
classes.push(item);
|
|
334
366
|
}
|
|
@@ -337,16 +369,28 @@ export class Element extends Node {
|
|
|
337
369
|
classes.splice(itemIndex, 1);
|
|
338
370
|
}
|
|
339
371
|
|
|
340
|
-
|
|
372
|
+
const final = classes.join(" ").trim();
|
|
341
373
|
if (final.length) {
|
|
342
|
-
this.
|
|
374
|
+
this.className = classes.join(" ").trim();
|
|
343
375
|
} else {
|
|
344
|
-
this.
|
|
376
|
+
this.className = false;
|
|
345
377
|
}
|
|
346
378
|
}
|
|
347
379
|
}
|
|
348
380
|
};
|
|
349
381
|
|
|
382
|
+
get id(): string {
|
|
383
|
+
return this.getAttribute("id") || "";
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
set id(value: string | boolean) {
|
|
387
|
+
if (value == null || value === false) {
|
|
388
|
+
this.removeAttribute("id");
|
|
389
|
+
} else {
|
|
390
|
+
this.setAttribute("id", String(value));
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
|
|
350
394
|
set textContent(text) {
|
|
351
395
|
this.nodeValue = String(text);
|
|
352
396
|
this.childNodes = this.nodeValue ? [new Text(this.nodeValue)] : [];
|
|
@@ -374,7 +418,7 @@ export class Element extends Node {
|
|
|
374
418
|
|
|
375
419
|
set innerHTML(html) {
|
|
376
420
|
this.textContent = "";
|
|
377
|
-
|
|
421
|
+
const result = htmlToDom(html);
|
|
378
422
|
if (result instanceof DocumentFragment) {
|
|
379
423
|
for (let i = 0, l = result.childNodes.length; i < l; i++) {
|
|
380
424
|
this.appendChild(result.childNodes[i]);
|
|
@@ -402,20 +446,23 @@ export class Document extends Element {
|
|
|
402
446
|
super();
|
|
403
447
|
this.nodeType = 9;
|
|
404
448
|
this.nodeName = "#document";
|
|
449
|
+
this.body = this.createElement("body");
|
|
405
450
|
}
|
|
406
451
|
|
|
452
|
+
body: Element;
|
|
453
|
+
|
|
407
454
|
createDocumentFragment(): DocumentFragment {
|
|
408
455
|
return new DocumentFragment();
|
|
409
456
|
}
|
|
410
457
|
|
|
411
458
|
createElement(type: string) {
|
|
412
|
-
|
|
459
|
+
const element = new Element();
|
|
413
460
|
element.nodeName = type.toUpperCase();
|
|
414
461
|
return element;
|
|
415
462
|
}
|
|
416
463
|
|
|
417
464
|
createElementNS(ns: string, type: string) {
|
|
418
|
-
|
|
465
|
+
const element = this.createElement(type);
|
|
419
466
|
element.baseURI = ns;
|
|
420
467
|
return element;
|
|
421
468
|
}
|
|
@@ -425,7 +472,7 @@ export class Document extends Element {
|
|
|
425
472
|
}
|
|
426
473
|
}
|
|
427
474
|
|
|
428
|
-
|
|
475
|
+
const selfClosingTags = [
|
|
429
476
|
"area",
|
|
430
477
|
"base",
|
|
431
478
|
"br",
|
|
@@ -449,7 +496,7 @@ export function domToHtml(dom: Element): string {
|
|
|
449
496
|
}
|
|
450
497
|
|
|
451
498
|
if (dom.nodeType === 1) {
|
|
452
|
-
|
|
499
|
+
const name = dom.nodeName.toLowerCase();
|
|
453
500
|
let str = "<" + name;
|
|
454
501
|
for (let i = 0, l = dom.attributes.length; i < l; i++) {
|
|
455
502
|
str += " " + dom.attributes[i].nodeName + '="' + dom.attributes[i].nodeValue + '"';
|
|
@@ -459,7 +506,7 @@ export function domToHtml(dom: Element): string {
|
|
|
459
506
|
str += ">";
|
|
460
507
|
if (dom.childNodes && dom.childNodes.length > 0) {
|
|
461
508
|
for (let i = 0, l = dom.childNodes.length; i < l; i++) {
|
|
462
|
-
|
|
509
|
+
const child = domToHtml(dom.childNodes[i] as Element);
|
|
463
510
|
if (child) {
|
|
464
511
|
str += child;
|
|
465
512
|
}
|
|
@@ -492,9 +539,9 @@ export function domToHyperscript(childNodes: ChildNodes, depth = 1) {
|
|
|
492
539
|
let str = `\n${spaces}v("${item.nodeName}", `;
|
|
493
540
|
|
|
494
541
|
if (item.attributes) {
|
|
495
|
-
|
|
542
|
+
const attrs: Record<string, any> = {};
|
|
496
543
|
for (let i = 0, l = item.attributes.length; i < l; i++) {
|
|
497
|
-
|
|
544
|
+
const attr = item.attributes[i];
|
|
498
545
|
attrs[attr.nodeName] = attr.nodeValue;
|
|
499
546
|
}
|
|
500
547
|
str += JSON.stringify(attrs);
|
|
@@ -534,21 +581,21 @@ interface ObjectIndexItemWithContent extends ObjectIndexItem {
|
|
|
534
581
|
interface ObjectIndexList extends Array<ObjectIndexItem> {}
|
|
535
582
|
|
|
536
583
|
function findTexts(item: ObjectIndexItemWithContent, html: string) {
|
|
537
|
-
|
|
584
|
+
const newChildren: ObjectIndexItemWithContent[] = [];
|
|
538
585
|
|
|
539
586
|
// If the item has children
|
|
540
587
|
if (item.children.length) {
|
|
541
588
|
// Search for texts in the children.
|
|
542
589
|
for (let i = 0; i < item.children.length; i++) {
|
|
543
|
-
|
|
544
|
-
|
|
590
|
+
const child = item.children[i];
|
|
591
|
+
const nextChild = item.children[i + 1];
|
|
545
592
|
|
|
546
593
|
// If is the first child and the child startsAt is greater than the item contentStartsAt then
|
|
547
594
|
// the content between the item contentStartsAt and the child startsAt is a text child of the item.
|
|
548
595
|
if (i === 0 && child.startsAt > item.contentStartsAt) {
|
|
549
|
-
|
|
596
|
+
const childContent = html.substring(item.contentStartsAt, child.startsAt);
|
|
550
597
|
|
|
551
|
-
|
|
598
|
+
const childText: ObjectIndexItemWithContent = {
|
|
552
599
|
tagName: "#text",
|
|
553
600
|
startsAt: item.contentStartsAt,
|
|
554
601
|
endsAt: item.contentStartsAt + childContent.length,
|
|
@@ -568,9 +615,9 @@ function findTexts(item: ObjectIndexItemWithContent, html: string) {
|
|
|
568
615
|
// If there is a next child and the child endsAt is less than the next child startsAt then
|
|
569
616
|
// the content between the child endsAt and the next child startsAt is a text child of the item.
|
|
570
617
|
if (nextChild && child.endsAt < nextChild.startsAt) {
|
|
571
|
-
|
|
618
|
+
const childContent = html.substring(child.endsAt, nextChild.startsAt);
|
|
572
619
|
|
|
573
|
-
|
|
620
|
+
const childText: ObjectIndexItemWithContent = {
|
|
574
621
|
tagName: "#text",
|
|
575
622
|
startsAt: child.endsAt,
|
|
576
623
|
endsAt: child.endsAt + childContent.length,
|
|
@@ -587,9 +634,9 @@ function findTexts(item: ObjectIndexItemWithContent, html: string) {
|
|
|
587
634
|
// If there are no next child and the child endsAt is less than the item contentEndsAt then
|
|
588
635
|
// the content between the child endsAt and the item contentEndsAt is a text child of the item.
|
|
589
636
|
if (!nextChild && child.endsAt < item.contentEndsAt) {
|
|
590
|
-
|
|
637
|
+
const childContent = html.substring(child.endsAt, item.contentEndsAt);
|
|
591
638
|
|
|
592
|
-
|
|
639
|
+
const childText: ObjectIndexItemWithContent = {
|
|
593
640
|
tagName: "#text",
|
|
594
641
|
startsAt: child.endsAt,
|
|
595
642
|
endsAt: child.endsAt + childContent.length,
|
|
@@ -611,10 +658,10 @@ function findTexts(item: ObjectIndexItemWithContent, html: string) {
|
|
|
611
658
|
// If the item has no children then set the contents between the item contentStartsAt and the item contentEndsAt
|
|
612
659
|
// as a text child of the item.
|
|
613
660
|
if (!item.children.length) {
|
|
614
|
-
|
|
661
|
+
const childContent = html.substring(item.contentStartsAt, item.contentEndsAt);
|
|
615
662
|
|
|
616
663
|
if (childContent.length) {
|
|
617
|
-
|
|
664
|
+
const childText: ObjectIndexItemWithContent = {
|
|
618
665
|
tagName: "#text",
|
|
619
666
|
startsAt: item.contentStartsAt,
|
|
620
667
|
endsAt: item.contentEndsAt,
|
|
@@ -642,12 +689,12 @@ function convertToDom<T extends Node>(item: ObjectIndexItemWithContent): T {
|
|
|
642
689
|
? document.createDocumentFragment()
|
|
643
690
|
: document.createElement(item.tagName)) as unknown as T;
|
|
644
691
|
|
|
645
|
-
for (
|
|
692
|
+
for (const key in item.attributes) {
|
|
646
693
|
node.setAttribute(key, item.attributes[key]);
|
|
647
694
|
}
|
|
648
695
|
|
|
649
696
|
for (let i = 0; i < item.children.length; i++) {
|
|
650
|
-
|
|
697
|
+
const child = convertToDom(item.children[i]);
|
|
651
698
|
node.appendChild(child);
|
|
652
699
|
}
|
|
653
700
|
}
|
|
@@ -658,23 +705,23 @@ function convertToDom<T extends Node>(item: ObjectIndexItemWithContent): T {
|
|
|
658
705
|
// eslint-disable-next-line sonarjs/cognitive-complexity
|
|
659
706
|
function getObjectIndexTree(html: string): DocumentFragment {
|
|
660
707
|
let item;
|
|
661
|
-
|
|
662
|
-
|
|
708
|
+
const regex = RegExp("<([^>|^!]+)>", "g");
|
|
709
|
+
const items: ObjectIndexList = [];
|
|
663
710
|
|
|
664
711
|
// Make the initial list of items.
|
|
665
712
|
while ((item = regex.exec(html))) {
|
|
666
713
|
// If is a closing tag
|
|
667
714
|
if (item[0].startsWith("</")) {
|
|
668
|
-
|
|
715
|
+
const lastOpenedItem = [...items].reverse().find((item) => item.endsAt === null);
|
|
669
716
|
if (lastOpenedItem) {
|
|
670
717
|
lastOpenedItem.endsAt = item.index + item[0].length;
|
|
671
718
|
lastOpenedItem.contentEndsAt = item.index;
|
|
672
719
|
|
|
673
720
|
// Find the last opened item again, this will be the parent of the current item.
|
|
674
|
-
|
|
721
|
+
const parent = [...items].reverse().find((item) => item.endsAt === null);
|
|
675
722
|
if (parent) {
|
|
676
723
|
// Find the index of the current item in the items array.
|
|
677
|
-
|
|
724
|
+
const index = items.indexOf(lastOpenedItem);
|
|
678
725
|
// Remove the last opened item from the items array.
|
|
679
726
|
items.splice(index, 1);
|
|
680
727
|
|
|
@@ -687,7 +734,7 @@ function getObjectIndexTree(html: string): DocumentFragment {
|
|
|
687
734
|
}
|
|
688
735
|
|
|
689
736
|
// If is an opening tag
|
|
690
|
-
|
|
737
|
+
const element: ObjectIndexItem = {
|
|
691
738
|
tagName: item[1].split(" ")[0],
|
|
692
739
|
startsAt: item.index,
|
|
693
740
|
endsAt: null,
|
|
@@ -700,10 +747,10 @@ function getObjectIndexTree(html: string): DocumentFragment {
|
|
|
700
747
|
|
|
701
748
|
// Find the attributes of the tag.
|
|
702
749
|
let string = (item[1] || "").substring(element.tagName.length + 1).replace(/\/$/g, "");
|
|
703
|
-
|
|
750
|
+
const attributesWithValues = string.match(/\S+="[^"]+"/g);
|
|
704
751
|
|
|
705
752
|
if (attributesWithValues) {
|
|
706
|
-
for (
|
|
753
|
+
for (const attribute of attributesWithValues) {
|
|
707
754
|
const [name, ...value] = attribute.trim().split("=");
|
|
708
755
|
string = string.replace(attribute, "");
|
|
709
756
|
if (value) {
|
|
@@ -712,9 +759,9 @@ function getObjectIndexTree(html: string): DocumentFragment {
|
|
|
712
759
|
}
|
|
713
760
|
}
|
|
714
761
|
|
|
715
|
-
|
|
762
|
+
const attributesWithBooleanValues = string.match(/\s\S+=[^"]+/g);
|
|
716
763
|
if (attributesWithBooleanValues) {
|
|
717
|
-
for (
|
|
764
|
+
for (const attribute of attributesWithBooleanValues) {
|
|
718
765
|
const [name, ...value] = attribute.trim().split("=");
|
|
719
766
|
string = string.replace(attribute, "");
|
|
720
767
|
if (value) {
|
|
@@ -723,9 +770,9 @@ function getObjectIndexTree(html: string): DocumentFragment {
|
|
|
723
770
|
}
|
|
724
771
|
}
|
|
725
772
|
|
|
726
|
-
|
|
773
|
+
const attributesWithEmptyValues = string.match(/\s?\S+/g);
|
|
727
774
|
if (attributesWithEmptyValues) {
|
|
728
|
-
for (
|
|
775
|
+
for (const attribute of attributesWithEmptyValues) {
|
|
729
776
|
const name = attribute.trim();
|
|
730
777
|
element.attributes[name] = true;
|
|
731
778
|
}
|
|
@@ -737,7 +784,7 @@ function getObjectIndexTree(html: string): DocumentFragment {
|
|
|
737
784
|
element.contentStartsAt = element.contentEndsAt = element.endsAt;
|
|
738
785
|
|
|
739
786
|
// Find the last opened item, this will be the parent of the current item.
|
|
740
|
-
|
|
787
|
+
const parent = [...items].reverse().find((item) => item.endsAt === null);
|
|
741
788
|
if (parent) {
|
|
742
789
|
// Add the last opened item as a child of the parent.
|
|
743
790
|
parent.children.push(element);
|
|
@@ -748,7 +795,7 @@ function getObjectIndexTree(html: string): DocumentFragment {
|
|
|
748
795
|
items.push(element);
|
|
749
796
|
}
|
|
750
797
|
|
|
751
|
-
|
|
798
|
+
const fragmentItem: ObjectIndexItemWithContent = {
|
|
752
799
|
tagName: "#document-fragment",
|
|
753
800
|
startsAt: 0,
|
|
754
801
|
endsAt: html.length,
|
|
@@ -777,16 +824,16 @@ export function htmlToDom(html: string): Element | Text | DocumentFragment {
|
|
|
777
824
|
// search for the first opening tag.
|
|
778
825
|
const openingTag = html.match(/<[^>]+>/g);
|
|
779
826
|
|
|
780
|
-
|
|
827
|
+
const document = new Document();
|
|
781
828
|
|
|
782
829
|
// If the opening tag is not found, return a document fragment node with the html string as text content.
|
|
783
830
|
if (!openingTag) {
|
|
784
|
-
|
|
831
|
+
const documentFragment = document.createDocumentFragment();
|
|
785
832
|
documentFragment.appendChild(document.createTextNode(html));
|
|
786
833
|
return documentFragment;
|
|
787
834
|
}
|
|
788
835
|
|
|
789
|
-
|
|
836
|
+
const fragment = getObjectIndexTree(html);
|
|
790
837
|
|
|
791
838
|
if (fragment.childNodes.length > 1) {
|
|
792
839
|
return fragment;
|
|
@@ -796,8 +843,8 @@ export function htmlToDom(html: string): Element | Text | DocumentFragment {
|
|
|
796
843
|
}
|
|
797
844
|
|
|
798
845
|
export function htmlToHyperscript(html: string) {
|
|
799
|
-
|
|
800
|
-
|
|
846
|
+
const domTree = htmlToDom(html);
|
|
847
|
+
const hyperscript = domToHyperscript(domTree instanceof DocumentFragment ? domTree.childNodes : [domTree]);
|
|
801
848
|
return `[${hyperscript}\n]`;
|
|
802
849
|
}
|
|
803
850
|
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
/* eslint-disable no-console */
|
|
2
|
+
import { updateVnode, Vnode, VnodeWithDom, current } from "valyrian.js";
|
|
3
|
+
import { deepCloneUnfreeze, deepFreeze, hasChanged } from "valyrian.js/utils";
|
|
4
|
+
|
|
5
|
+
type State = Record<string, any>;
|
|
6
|
+
|
|
7
|
+
// An action or pulse type definition
|
|
8
|
+
// eslint-disable-next-line no-unused-vars
|
|
9
|
+
export type Pulse<StateType> = (state: StateType, ...args: any[]) => void | Promise<void>;
|
|
10
|
+
|
|
11
|
+
// A collection of pulses
|
|
12
|
+
export type Pulses<StateType> = {
|
|
13
|
+
[key: string]: Pulse<StateType>;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
// A proxy state
|
|
17
|
+
// This is a state that is proxied to automatically subscribe to changes
|
|
18
|
+
// And is used internally to update the vnode when the state changes
|
|
19
|
+
type ProxyState<StateType> = StateType & {
|
|
20
|
+
[key: string]: any;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
// The effect stack
|
|
24
|
+
const effectStack: Function[] = [];
|
|
25
|
+
|
|
26
|
+
// Creates the store
|
|
27
|
+
// eslint-disable-next-line sonarjs/cognitive-complexity
|
|
28
|
+
function createStore<StateType extends State, PulsesType extends Pulses<StateType>>(
|
|
29
|
+
initialState: StateType | (() => StateType),
|
|
30
|
+
pulses: PulsesType,
|
|
31
|
+
immutable = false
|
|
32
|
+
): () => [ProxyState<StateType>, PulsesType] {
|
|
33
|
+
const subscribers = new Set<Function>();
|
|
34
|
+
const vnodesToUpdate = new WeakSet<Vnode>();
|
|
35
|
+
|
|
36
|
+
// Initialize the localState for this store
|
|
37
|
+
const localState = (typeof initialState === "function" ? initialState() : initialState) || {};
|
|
38
|
+
|
|
39
|
+
function isMutable() {
|
|
40
|
+
if (immutable) {
|
|
41
|
+
throw new Error("You need to call a pulse to modify the state");
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// We create a proxy for the state
|
|
46
|
+
const proxyState = new Proxy(localState || {}, {
|
|
47
|
+
get: (state, prop: string) => {
|
|
48
|
+
const currentEffect = effectStack[effectStack.length - 1];
|
|
49
|
+
if (currentEffect && !subscribers.has(currentEffect)) {
|
|
50
|
+
subscribers.add(currentEffect);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const currentVnode = current.vnode as VnodeWithDom;
|
|
54
|
+
if (currentVnode && !vnodesToUpdate.has(currentVnode)) {
|
|
55
|
+
const subscription = () => {
|
|
56
|
+
if (!currentVnode.dom) {
|
|
57
|
+
subscribers.delete(subscription);
|
|
58
|
+
vnodesToUpdate.delete(currentVnode);
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
updateVnode(currentVnode);
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
subscribers.add(subscription);
|
|
66
|
+
vnodesToUpdate.add(currentVnode);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return state[prop];
|
|
70
|
+
},
|
|
71
|
+
// If the user tries to set directly it will throw an error
|
|
72
|
+
set: (state, prop: string, value: any) => {
|
|
73
|
+
isMutable();
|
|
74
|
+
Reflect.set(state, prop, value);
|
|
75
|
+
return true;
|
|
76
|
+
},
|
|
77
|
+
// If the user tries to delete directly it will throw an error
|
|
78
|
+
deleteProperty: (state, prop: string) => {
|
|
79
|
+
isMutable();
|
|
80
|
+
Reflect.deleteProperty(state, prop);
|
|
81
|
+
return true;
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
function syncState(newState: StateType) {
|
|
86
|
+
for (const key in newState) {
|
|
87
|
+
localState[key] = immutable ? deepFreeze(newState[key]) : newState[key];
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
for (const key in localState) {
|
|
91
|
+
if (!(key in newState)) {
|
|
92
|
+
Reflect.deleteProperty(localState, key);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function setState(newState: StateType) {
|
|
98
|
+
if (!hasChanged(localState, newState)) {
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
syncState(newState);
|
|
103
|
+
|
|
104
|
+
subscribers.forEach((subscriber) => subscriber());
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function getPulseMethod(key: string) {
|
|
108
|
+
return (...args: any[]) => {
|
|
109
|
+
const currentState = deepCloneUnfreeze(localState);
|
|
110
|
+
const pulse = pulses[key](currentState, ...args);
|
|
111
|
+
|
|
112
|
+
if (pulse instanceof Promise) {
|
|
113
|
+
return pulse
|
|
114
|
+
.then(() => setState(currentState))
|
|
115
|
+
.catch((error) => {
|
|
116
|
+
console.error("Error in pulse:", error);
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
setState(currentState);
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const boundPulses: Record<string, Pulse<StateType>> = {};
|
|
125
|
+
for (const key in pulses) {
|
|
126
|
+
if (typeof pulses[key] !== "function") {
|
|
127
|
+
throw new Error(`Pulse '${key}' must be a function`);
|
|
128
|
+
}
|
|
129
|
+
boundPulses[key] = getPulseMethod(key);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
const pulsesProxy = new Proxy(boundPulses, {
|
|
133
|
+
get: (pulses, prop: string) => {
|
|
134
|
+
if (!(prop in pulses)) {
|
|
135
|
+
throw new Error(`Pulse '${prop}' does not exist`);
|
|
136
|
+
}
|
|
137
|
+
return pulses[prop];
|
|
138
|
+
}
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
function usePulseStore(): [ProxyState<StateType>, PulsesType] {
|
|
142
|
+
return [proxyState, pulsesProxy as PulsesType];
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
syncState(localState);
|
|
146
|
+
|
|
147
|
+
return usePulseStore;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// Creates a pulse store with an immutable state by default
|
|
151
|
+
export function createPulseStore<StateType extends State, PulsesType extends Pulses<StateType>>(
|
|
152
|
+
initialState: StateType,
|
|
153
|
+
pulses: PulsesType
|
|
154
|
+
): () => [ProxyState<StateType>, PulsesType] {
|
|
155
|
+
return createStore(initialState, pulses, true);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// Creates a mutable store, useful for performance, but not recommended
|
|
159
|
+
export function createMutableStore<StateType extends State, PulsesType extends Pulses<StateType>>(
|
|
160
|
+
initialState: StateType,
|
|
161
|
+
pulses: PulsesType
|
|
162
|
+
): () => [ProxyState<StateType>, PulsesType] {
|
|
163
|
+
console.warn(
|
|
164
|
+
"Warning: You are working with a mutable state. This can lead to unpredictable behavior. All state changes made outside of a pulse will not trigger a re-render."
|
|
165
|
+
);
|
|
166
|
+
return createStore(initialState, pulses, false);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// Creates an effect
|
|
170
|
+
export function createEffect(effect: Function) {
|
|
171
|
+
const runEffect = () => {
|
|
172
|
+
try {
|
|
173
|
+
effectStack.push(runEffect);
|
|
174
|
+
effect();
|
|
175
|
+
} finally {
|
|
176
|
+
effectStack.pop();
|
|
177
|
+
}
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
runEffect();
|
|
181
|
+
}
|