cradova 3.9.0 → 3.10.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/dist/index.js +88 -78
- package/dist/primitives/classes.d.ts +12 -15
- package/dist/primitives/functions.d.ts +1 -1
- package/dist/primitives/types.d.ts +4 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -503,18 +503,18 @@ class cradovaEvent {
|
|
|
503
503
|
window.CradovaEvent = new cradovaEvent;
|
|
504
504
|
|
|
505
505
|
class Store {
|
|
506
|
-
|
|
506
|
+
$_internal_data;
|
|
507
507
|
constructor(data, notifier) {
|
|
508
|
-
this
|
|
509
|
-
for (const key in this
|
|
510
|
-
if (this.
|
|
508
|
+
this.$_internal_data = data;
|
|
509
|
+
for (const key in this.$_internal_data) {
|
|
510
|
+
if (this.$_internal_data.hasOwnProperty(key)) {
|
|
511
511
|
Object.defineProperty(this, key, {
|
|
512
512
|
get() {
|
|
513
|
-
return this
|
|
513
|
+
return this.$_internal_data[key];
|
|
514
514
|
},
|
|
515
515
|
set(value) {
|
|
516
|
+
this.$_internal_data[key] = value;
|
|
516
517
|
notifier(key, value);
|
|
517
|
-
this._data[key] = value;
|
|
518
518
|
},
|
|
519
519
|
enumerable: true,
|
|
520
520
|
configurable: true
|
|
@@ -522,39 +522,22 @@ class Store {
|
|
|
522
522
|
}
|
|
523
523
|
}
|
|
524
524
|
}
|
|
525
|
-
_set(
|
|
526
|
-
this
|
|
525
|
+
_set(data) {
|
|
526
|
+
this.$_internal_data = data;
|
|
527
|
+
return Object.keys(this.$_internal_data);
|
|
527
528
|
}
|
|
528
529
|
}
|
|
529
530
|
|
|
530
531
|
class List2 {
|
|
531
532
|
_data;
|
|
532
533
|
_dirtyIndices;
|
|
533
|
-
_subscribers;
|
|
534
534
|
notifier;
|
|
535
535
|
constructor(initialData, notifier) {
|
|
536
536
|
this._data = initialData || [];
|
|
537
537
|
this._dirtyIndices = new Set;
|
|
538
538
|
this.notifier = notifier;
|
|
539
|
-
this._subscribers = {
|
|
540
|
-
dataChanged: [],
|
|
541
|
-
itemUpdated: []
|
|
542
|
-
};
|
|
543
539
|
this._dirtyIndices.add("all");
|
|
544
540
|
}
|
|
545
|
-
_publish(eventType, payload) {
|
|
546
|
-
const subs = this._subscribers[eventType];
|
|
547
|
-
if (subs) {
|
|
548
|
-
for (let i2 = 0;i2 < subs.length; i2++) {
|
|
549
|
-
subs[i2](payload);
|
|
550
|
-
}
|
|
551
|
-
}
|
|
552
|
-
}
|
|
553
|
-
_subscribe(eventType, callback) {
|
|
554
|
-
if (this._subscribers[eventType]) {
|
|
555
|
-
this._subscribers[eventType].push(callback);
|
|
556
|
-
}
|
|
557
|
-
}
|
|
558
541
|
get items() {
|
|
559
542
|
return {
|
|
560
543
|
[Symbol.iterator]: () => {
|
|
@@ -579,7 +562,6 @@ class List2 {
|
|
|
579
562
|
this._data[index] = newItemData;
|
|
580
563
|
this._dirtyIndices.add(index);
|
|
581
564
|
this.notifier("itemUpdated", { index, newItemData });
|
|
582
|
-
this._publish("itemUpdated", { index, newItemData });
|
|
583
565
|
}
|
|
584
566
|
}
|
|
585
567
|
push(itemData, index) {
|
|
@@ -589,30 +571,28 @@ class List2 {
|
|
|
589
571
|
this._data.splice(index, 0, itemData);
|
|
590
572
|
this._dirtyIndices.add("all");
|
|
591
573
|
this.notifier("dataChanged", { type: "add", index });
|
|
592
|
-
this._publish("dataChanged", { type: "add", index });
|
|
593
574
|
}
|
|
594
575
|
remove(index, count = 1) {
|
|
595
576
|
if (index >= 0 && index < this._data.length && count > 0) {
|
|
596
577
|
this._data.splice(index, count);
|
|
597
578
|
this._dirtyIndices.add("all");
|
|
598
|
-
this.
|
|
579
|
+
this.notifier("dataChanged", { type: "remove", index });
|
|
599
580
|
}
|
|
600
581
|
}
|
|
601
|
-
|
|
582
|
+
_set(newData) {
|
|
602
583
|
this._data = newData || [];
|
|
603
584
|
this._dirtyIndices.clear();
|
|
604
585
|
this._dirtyIndices.add("all");
|
|
605
|
-
|
|
606
|
-
this._publish("dataChanged", { type: "reset" });
|
|
586
|
+
return ["dataChanged"];
|
|
607
587
|
}
|
|
608
|
-
|
|
588
|
+
_isDirty(index = "all") {
|
|
609
589
|
if (this._dirtyIndices.has(index)) {
|
|
610
590
|
this._dirtyIndices.delete(index);
|
|
611
591
|
return true;
|
|
612
592
|
}
|
|
613
593
|
return false;
|
|
614
594
|
}
|
|
615
|
-
|
|
595
|
+
_clearAllDirty() {
|
|
616
596
|
this._dirtyIndices.clear();
|
|
617
597
|
}
|
|
618
598
|
}
|
|
@@ -620,65 +600,66 @@ class List2 {
|
|
|
620
600
|
class Signal {
|
|
621
601
|
pn;
|
|
622
602
|
subs = {};
|
|
603
|
+
isList = false;
|
|
623
604
|
listening_subs = {};
|
|
624
|
-
store
|
|
625
|
-
list = [];
|
|
605
|
+
store;
|
|
626
606
|
passers;
|
|
627
|
-
constructor({
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
this.
|
|
633
|
-
|
|
607
|
+
constructor(initial, props) {
|
|
608
|
+
if (!initial || typeof initial !== "object") {
|
|
609
|
+
throw new Error("Initial signal value must be an array or object");
|
|
610
|
+
}
|
|
611
|
+
if (!Array.isArray(initial)) {
|
|
612
|
+
this.store = new Store(initial, (key) => {
|
|
613
|
+
this.publish(key);
|
|
614
|
+
});
|
|
615
|
+
} else {
|
|
616
|
+
this.isList = true;
|
|
617
|
+
this.store = new List2(initial, (eventType) => {
|
|
618
|
+
this.publish(eventType);
|
|
619
|
+
});
|
|
620
|
+
}
|
|
634
621
|
this.subs = {};
|
|
635
|
-
this.list = new List2(list, (eventType, value) => {
|
|
636
|
-
this.publish(eventType, value);
|
|
637
|
-
});
|
|
638
622
|
if (props && props.persistName) {
|
|
639
623
|
this.pn = props.persistName;
|
|
640
624
|
const key = localStorage.getItem(props.persistName);
|
|
641
625
|
if (key && key !== "undefined") {
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
626
|
+
const restored = JSON.parse(key);
|
|
627
|
+
if (!Array.isArray(restored)) {
|
|
628
|
+
this.store = new Store(restored, (key2) => {
|
|
629
|
+
this.publish(key2);
|
|
630
|
+
});
|
|
631
|
+
} else {
|
|
632
|
+
this.isList = true;
|
|
633
|
+
this.store = new List2(restored, (eventType) => {
|
|
634
|
+
this.publish(eventType);
|
|
635
|
+
});
|
|
651
636
|
}
|
|
652
637
|
}
|
|
653
638
|
}
|
|
654
639
|
}
|
|
655
|
-
publish(eventName
|
|
656
|
-
|
|
657
|
-
subs.forEach((c) => {
|
|
640
|
+
publish(eventName) {
|
|
641
|
+
this.subs[eventName]?.forEach((c) => {
|
|
658
642
|
funcManager.recall(c);
|
|
659
643
|
});
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
fn({ [eventName]: data });
|
|
664
|
-
}
|
|
665
|
-
}
|
|
644
|
+
this.listening_subs[eventName]?.forEach((c) => {
|
|
645
|
+
c(this.store);
|
|
646
|
+
});
|
|
666
647
|
if (this.pn) {
|
|
667
|
-
localStorage.setItem(this.pn, JSON.stringify(this.store));
|
|
648
|
+
localStorage.setItem(this.pn, JSON.stringify(this.isList ? this.store.items : this.store.$_internal_data));
|
|
668
649
|
}
|
|
669
650
|
}
|
|
670
|
-
|
|
651
|
+
set(NEW) {
|
|
671
652
|
const s = new Set;
|
|
653
|
+
const events = this.store._set(NEW);
|
|
672
654
|
const s2 = new Set;
|
|
673
|
-
for (const
|
|
674
|
-
this.
|
|
675
|
-
const subs = this.subs[eventName];
|
|
655
|
+
for (const event of events) {
|
|
656
|
+
const subs = this.subs[event];
|
|
676
657
|
if (subs) {
|
|
677
658
|
subs.forEach((c) => {
|
|
678
659
|
s.add(c);
|
|
679
660
|
});
|
|
680
661
|
}
|
|
681
|
-
const subs2 = this.listening_subs[
|
|
662
|
+
const subs2 = this.listening_subs[event];
|
|
682
663
|
if (subs2) {
|
|
683
664
|
for (const fn of subs2) {
|
|
684
665
|
s2.add(fn);
|
|
@@ -691,7 +672,7 @@ class Signal {
|
|
|
691
672
|
for (const fn of s2.values())
|
|
692
673
|
fn(events);
|
|
693
674
|
if (this.pn) {
|
|
694
|
-
localStorage.setItem(this.pn, JSON.stringify(this.store));
|
|
675
|
+
localStorage.setItem(this.pn, JSON.stringify(this.isList ? this.store.items : this.store.$_internal_data));
|
|
695
676
|
}
|
|
696
677
|
}
|
|
697
678
|
subscribe(eventName, comp) {
|
|
@@ -737,6 +718,35 @@ class Signal {
|
|
|
737
718
|
}
|
|
738
719
|
this.listening_subs[eventName].push(listener);
|
|
739
720
|
}
|
|
721
|
+
computed(eventName, element) {
|
|
722
|
+
let el = element(this.store);
|
|
723
|
+
if (el === undefined || !(el instanceof HTMLElement)) {
|
|
724
|
+
console.error(` ✘ Cradova err: ${String(element)} is not a valid element or function`);
|
|
725
|
+
return;
|
|
726
|
+
}
|
|
727
|
+
const listener = () => {
|
|
728
|
+
const newEl = element(this.store);
|
|
729
|
+
if (newEl === undefined || !(newEl instanceof HTMLElement)) {
|
|
730
|
+
console.error(` ✘ Cradova err: ${String(element)} is not a valid element or function`);
|
|
731
|
+
return;
|
|
732
|
+
}
|
|
733
|
+
listener.element.insertAdjacentElement("beforebegin", newEl);
|
|
734
|
+
listener.element.remove();
|
|
735
|
+
listener.element = newEl;
|
|
736
|
+
};
|
|
737
|
+
listener.element = el;
|
|
738
|
+
if (Array.isArray(eventName)) {
|
|
739
|
+
eventName.forEach((en) => {
|
|
740
|
+
this.listen(en, listener);
|
|
741
|
+
});
|
|
742
|
+
return el;
|
|
743
|
+
}
|
|
744
|
+
if (!this.listening_subs[eventName]) {
|
|
745
|
+
this.listening_subs[eventName] = [];
|
|
746
|
+
}
|
|
747
|
+
this.listening_subs[eventName].push(listener);
|
|
748
|
+
return el;
|
|
749
|
+
}
|
|
740
750
|
get pass() {
|
|
741
751
|
if (this.passers) {
|
|
742
752
|
return this.passers;
|
|
@@ -1038,10 +1048,10 @@ class VirtualList {
|
|
|
1038
1048
|
this.renderScheduled = false;
|
|
1039
1049
|
this.container = container;
|
|
1040
1050
|
this.scheduleRender();
|
|
1041
|
-
this.dataStore.
|
|
1051
|
+
this.dataStore.listen("dataChanged", () => {
|
|
1042
1052
|
this.scheduleRender();
|
|
1043
1053
|
});
|
|
1044
|
-
this.dataStore.
|
|
1054
|
+
this.dataStore.listen("itemUpdated", () => {
|
|
1045
1055
|
this.scheduleRender();
|
|
1046
1056
|
});
|
|
1047
1057
|
}
|
|
@@ -1052,11 +1062,11 @@ class VirtualList {
|
|
|
1052
1062
|
requestAnimationFrame(this.render.bind(this));
|
|
1053
1063
|
}
|
|
1054
1064
|
render() {
|
|
1055
|
-
const loop2 = Math.max(this.dataStore.
|
|
1056
|
-
const needsFullRender = this.dataStore.
|
|
1065
|
+
const loop2 = Math.max(this.dataStore.store.length, this.container.children.length);
|
|
1066
|
+
const needsFullRender = this.dataStore.store._isDirty();
|
|
1057
1067
|
for (let i2 = 0;i2 < loop2; i2++) {
|
|
1058
|
-
if (needsFullRender || this.dataStore.
|
|
1059
|
-
const dataItem = this.dataStore.
|
|
1068
|
+
if (needsFullRender || this.dataStore.store._isDirty(i2)) {
|
|
1069
|
+
const dataItem = this.dataStore.store.get(i2);
|
|
1060
1070
|
const newDOM = this.renderItem(dataItem, i2);
|
|
1061
1071
|
const oldDOM = this.container.children[i2];
|
|
1062
1072
|
if (newDOM instanceof HTMLElement) {
|
|
@@ -1077,7 +1087,7 @@ class VirtualList {
|
|
|
1077
1087
|
}
|
|
1078
1088
|
}
|
|
1079
1089
|
if (needsFullRender) {
|
|
1080
|
-
this.dataStore.
|
|
1090
|
+
this.dataStore.store._clearAllDirty();
|
|
1081
1091
|
}
|
|
1082
1092
|
this.renderScheduled = false;
|
|
1083
1093
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { browserPageType, Comp, CradovaPageType } from "./types.js";
|
|
1
|
+
import type { browserPageType, Comp, CradovaPageType, VJS_params_TYPE } from "./types.js";
|
|
2
2
|
declare class List<Type extends any[]> {
|
|
3
3
|
notifier: (eventType: "dataChanged" | "itemUpdated", newItemData: Type[number]) => void;
|
|
4
4
|
constructor(initialData: Type, notifier: (eventType: "dataChanged" | "itemUpdated", newItemData: Type[number]) => void);
|
|
@@ -9,7 +9,6 @@ declare class List<Type extends any[]> {
|
|
|
9
9
|
update(index: number, newItemData: Type[number]): void;
|
|
10
10
|
push(itemData: Type[number], index?: number): void;
|
|
11
11
|
remove(index: number, count?: number): void;
|
|
12
|
-
set(newData: Type): void;
|
|
13
12
|
}
|
|
14
13
|
/**
|
|
15
14
|
* Cradova Signal
|
|
@@ -21,17 +20,14 @@ declare class List<Type extends any[]> {
|
|
|
21
20
|
* - persist changes to localStorage
|
|
22
21
|
* @constructor initial: Record<string, any>, props: {persist}
|
|
23
22
|
*/
|
|
24
|
-
export declare class Signal<
|
|
23
|
+
export declare class Signal<Type = any> {
|
|
25
24
|
private pn?;
|
|
26
25
|
private subs;
|
|
26
|
+
private isList;
|
|
27
27
|
private listening_subs;
|
|
28
|
-
store:
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
constructor({ store, list, }: {
|
|
32
|
-
store?: StoreType;
|
|
33
|
-
list?: ListType;
|
|
34
|
-
}, props?: {
|
|
28
|
+
store: Type extends Array<any> ? List<Type> : Type extends Record<string, any> ? Type : never;
|
|
29
|
+
passers?: Record<keyof Type, [string, Signal<Type>]>;
|
|
30
|
+
constructor(initial: Type, props?: {
|
|
35
31
|
persistName?: string | undefined;
|
|
36
32
|
});
|
|
37
33
|
/**
|
|
@@ -39,7 +35,7 @@ export declare class Signal<StoreType extends Record<string, any>, ListType exte
|
|
|
39
35
|
* ----
|
|
40
36
|
* fires actions if any available
|
|
41
37
|
*/
|
|
42
|
-
|
|
38
|
+
set(NEW: Type): void;
|
|
43
39
|
/**
|
|
44
40
|
* Cradova Signal
|
|
45
41
|
* ----
|
|
@@ -48,7 +44,7 @@ export declare class Signal<StoreType extends Record<string, any>, ListType exte
|
|
|
48
44
|
* @param name of event.
|
|
49
45
|
* @param Comp component to bind to.
|
|
50
46
|
*/
|
|
51
|
-
subscribe<T extends keyof
|
|
47
|
+
subscribe<T extends keyof Type>(eventName: T | "dataChanged" | "itemUpdated" | T[], comp: Comp | ((this: Comp) => HTMLDivElement)): void;
|
|
52
48
|
/**
|
|
53
49
|
* Cradova Signal
|
|
54
50
|
* ----
|
|
@@ -57,13 +53,14 @@ export declare class Signal<StoreType extends Record<string, any>, ListType exte
|
|
|
57
53
|
* @param name of event.
|
|
58
54
|
* @param callback function to call.
|
|
59
55
|
*/
|
|
60
|
-
listen<T extends keyof
|
|
56
|
+
listen<T extends keyof Type>(eventName: T | "dataChanged" | "itemUpdated" | T[], listener: (store: Type extends Array<any> ? List<Type> : Type extends Record<string, any> ? Type : never) => void): void;
|
|
57
|
+
computed<T extends keyof Type>(eventName: T | "dataChanged" | "itemUpdated" | T[], element: (store: Type extends Array<any> ? List<Type> : Type extends Record<string, any> ? Type : never) => HTMLElement | VJS_params_TYPE<HTMLElement>): HTMLElement | undefined;
|
|
61
58
|
/**
|
|
62
59
|
* Cradova Signal
|
|
63
60
|
* ----
|
|
64
61
|
* subscribe an element to an event
|
|
65
62
|
*/
|
|
66
|
-
get pass(): Record<keyof
|
|
63
|
+
get pass(): Record<keyof Type, [string, Signal<any>]>;
|
|
67
64
|
/**
|
|
68
65
|
* Cradova Signal
|
|
69
66
|
* ----
|
|
@@ -164,6 +161,6 @@ export declare class __raw_ref<T = unknown> {
|
|
|
164
161
|
bind(name: string): [__raw_ref<T>, string];
|
|
165
162
|
}
|
|
166
163
|
export declare class VirtualList {
|
|
167
|
-
constructor(container: HTMLElement, dataStore: Signal<any
|
|
164
|
+
constructor(container: HTMLElement, dataStore: Signal<any[]>, renderItemFunction: (item: any, index: number) => HTMLElement);
|
|
168
165
|
}
|
|
169
166
|
export {};
|
|
@@ -34,7 +34,7 @@ export declare const funcManager: {
|
|
|
34
34
|
cleanupEffects(component: Comp): void;
|
|
35
35
|
unmount(component: Comp): void;
|
|
36
36
|
};
|
|
37
|
-
export declare const List: <T>(signal: Signal<
|
|
37
|
+
export declare const List: <T>(signal: Signal<T[]>, item: (item: T) => HTMLElement, options?: {
|
|
38
38
|
className?: string;
|
|
39
39
|
id?: string;
|
|
40
40
|
style?: Partial<CSS.Properties>;
|
|
@@ -8,8 +8,10 @@ interface Attributes<E extends HTMLElement> {
|
|
|
8
8
|
[key: `aria-${string}`]: string | undefined;
|
|
9
9
|
[key: `on${string}`]: ((this: E, event: Event) => void) | undefined;
|
|
10
10
|
}
|
|
11
|
-
type
|
|
12
|
-
|
|
11
|
+
type StandardEvents<E extends HTMLElement> = {
|
|
12
|
+
[key in keyof E]: E[key] extends (this: E, event: Event) => void ? key : never;
|
|
13
|
+
}[keyof E];
|
|
14
|
+
export type VJS_params_TYPE<E extends HTMLElement> = (undefined | undefined[] | string | string[] | HTMLElement | HTMLElement[] | DocumentFragment | DocumentFragment[] | (() => HTMLElement) | (() => HTMLElement)[] | [string, Signal<any>] | VJS_params_TYPE<E> | VJS_params_TYPE<E>[] | (Attributes<E> & Omit<Partial<E>, keyof Attributes<E> | StandardEvents<E>>))[];
|
|
13
15
|
export type CradovaPageType = {
|
|
14
16
|
/**
|
|
15
17
|
* Cradova page
|