cradova 3.12.4 → 3.13.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 +21 -145
- package/dist/primitives/classes.d.ts +3 -6
- package/dist/primitives/functions.d.ts +1 -8
- package/dist/primitives/types.d.ts +1 -11
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -174,7 +174,7 @@ function useState(initialValue) {
|
|
|
174
174
|
}
|
|
175
175
|
if (!Object.is(currentState, nextState)) {
|
|
176
176
|
self._state[idx] = nextState;
|
|
177
|
-
|
|
177
|
+
compManager.recall(self);
|
|
178
178
|
}
|
|
179
179
|
};
|
|
180
180
|
return [self._state[idx], setState];
|
|
@@ -199,7 +199,7 @@ function useEffect(effect, deps) {
|
|
|
199
199
|
tracker[idx].deps = deps;
|
|
200
200
|
}
|
|
201
201
|
if (needsRun) {
|
|
202
|
-
|
|
202
|
+
compManager.scheduleEffect(self, idx, effect);
|
|
203
203
|
}
|
|
204
204
|
}
|
|
205
205
|
function useMemo(factory, deps) {
|
|
@@ -252,7 +252,7 @@ function useReducer(reducer, initialArg, initializer) {
|
|
|
252
252
|
}
|
|
253
253
|
if (!Object.is(currentState, nextState)) {
|
|
254
254
|
currentTracker.state = nextState;
|
|
255
|
-
|
|
255
|
+
compManager.recall(self);
|
|
256
256
|
}
|
|
257
257
|
};
|
|
258
258
|
return [tracker[idx].state, dispatch];
|
|
@@ -279,7 +279,7 @@ function resetComponent(comp) {
|
|
|
279
279
|
comp._effect_index = -1;
|
|
280
280
|
comp._memo_index = -1;
|
|
281
281
|
comp._reducer_index = -1;
|
|
282
|
-
|
|
282
|
+
compManager.cleanupEffects(comp);
|
|
283
283
|
return comp;
|
|
284
284
|
}
|
|
285
285
|
return comp;
|
|
@@ -293,7 +293,7 @@ var toComp = (comp, args) => {
|
|
|
293
293
|
comp._memo_tracker = [];
|
|
294
294
|
comp._reducer_tracker = [];
|
|
295
295
|
comp._args = args;
|
|
296
|
-
return
|
|
296
|
+
return compManager.render(comp);
|
|
297
297
|
};
|
|
298
298
|
var toCompNoRender = (comp) => {
|
|
299
299
|
if (typeof comp._state_index !== "number") {
|
|
@@ -305,10 +305,10 @@ var toCompNoRender = (comp) => {
|
|
|
305
305
|
comp._effect_index = -1;
|
|
306
306
|
comp._memo_index = -1;
|
|
307
307
|
comp._reducer_index = -1;
|
|
308
|
-
|
|
308
|
+
compManager.cleanupEffects(comp);
|
|
309
309
|
return comp;
|
|
310
310
|
};
|
|
311
|
-
var
|
|
311
|
+
var compManager = {
|
|
312
312
|
render(component) {
|
|
313
313
|
const html = component(component, ...component._args || []);
|
|
314
314
|
if (html instanceof HTMLElement) {
|
|
@@ -411,21 +411,6 @@ var funcManager = {
|
|
|
411
411
|
this._effectsToRun.delete(component);
|
|
412
412
|
}
|
|
413
413
|
};
|
|
414
|
-
var List = (signal, item, options) => {
|
|
415
|
-
const list = div({
|
|
416
|
-
className: options?.className,
|
|
417
|
-
id: options?.id,
|
|
418
|
-
style: options?.style
|
|
419
|
-
}, {
|
|
420
|
-
onmount() {
|
|
421
|
-
const vl = new VirtualList(this, signal, item);
|
|
422
|
-
return () => {
|
|
423
|
-
vl.destroy();
|
|
424
|
-
};
|
|
425
|
-
}
|
|
426
|
-
});
|
|
427
|
-
return list;
|
|
428
|
-
};
|
|
429
414
|
function invoke(fn, ...args) {
|
|
430
415
|
return toComp(fn, args);
|
|
431
416
|
}
|
|
@@ -534,9 +519,6 @@ class SilentStore {
|
|
|
534
519
|
for (const key in this.$store.$_internal_data) {
|
|
535
520
|
if (this.$store.$_internal_data.hasOwnProperty(key)) {
|
|
536
521
|
Object.defineProperty(this, key, {
|
|
537
|
-
get() {
|
|
538
|
-
return this.$store.$_internal_data[key];
|
|
539
|
-
},
|
|
540
522
|
set(value) {
|
|
541
523
|
this.$store.$_internal_data[key] = value;
|
|
542
524
|
},
|
|
@@ -548,7 +530,7 @@ class SilentStore {
|
|
|
548
530
|
}
|
|
549
531
|
}
|
|
550
532
|
|
|
551
|
-
class
|
|
533
|
+
class List {
|
|
552
534
|
_data;
|
|
553
535
|
_dirtyIndices;
|
|
554
536
|
notifier;
|
|
@@ -638,7 +620,7 @@ class Signal {
|
|
|
638
620
|
this.silentStore = new SilentStore(this.store);
|
|
639
621
|
} else {
|
|
640
622
|
this.isList = true;
|
|
641
|
-
this.store = new
|
|
623
|
+
this.store = new List(initial, (eventType) => {
|
|
642
624
|
this.publish(eventType);
|
|
643
625
|
});
|
|
644
626
|
}
|
|
@@ -654,7 +636,7 @@ class Signal {
|
|
|
654
636
|
this.silentStore = new SilentStore(this.store);
|
|
655
637
|
} else if (Array.isArray(restored)) {
|
|
656
638
|
this.isList = true;
|
|
657
|
-
this.store = new
|
|
639
|
+
this.store = new List(restored, (eventType) => {
|
|
658
640
|
this.publish(eventType);
|
|
659
641
|
});
|
|
660
642
|
}
|
|
@@ -664,14 +646,14 @@ class Signal {
|
|
|
664
646
|
publish(eventName) {
|
|
665
647
|
this.subscribers[eventName]?.forEach((c) => {
|
|
666
648
|
if (c.published) {
|
|
667
|
-
|
|
649
|
+
compManager.recall(c);
|
|
668
650
|
} else {
|
|
669
651
|
c();
|
|
670
652
|
}
|
|
671
653
|
});
|
|
672
654
|
this.subscribers["__ALL__"]?.forEach((c) => {
|
|
673
655
|
if (c.published) {
|
|
674
|
-
|
|
656
|
+
compManager.recall(c);
|
|
675
657
|
} else {
|
|
676
658
|
c();
|
|
677
659
|
}
|
|
@@ -698,7 +680,7 @@ class Signal {
|
|
|
698
680
|
}
|
|
699
681
|
for (const c of s.values()) {
|
|
700
682
|
if (c.published) {
|
|
701
|
-
|
|
683
|
+
compManager.recall(c);
|
|
702
684
|
} else {
|
|
703
685
|
c();
|
|
704
686
|
}
|
|
@@ -811,9 +793,8 @@ class Page {
|
|
|
811
793
|
_name;
|
|
812
794
|
_html;
|
|
813
795
|
_template;
|
|
814
|
-
_snapshot;
|
|
815
|
-
_snapshot_html;
|
|
816
796
|
_unload_CB;
|
|
797
|
+
_activate_CB;
|
|
817
798
|
constructor(pageParams) {
|
|
818
799
|
const { template, name } = pageParams;
|
|
819
800
|
if (typeof template !== "function") {
|
|
@@ -821,56 +802,23 @@ class Page {
|
|
|
821
802
|
}
|
|
822
803
|
this._html = template;
|
|
823
804
|
this._name = name || document.title;
|
|
824
|
-
this._snapshot = pageParams.snapshotIsolation || false;
|
|
825
|
-
}
|
|
826
|
-
async _takeSnapShot() {
|
|
827
|
-
if (RouterBox.doc.dataset["snapshot"] === "true")
|
|
828
|
-
return;
|
|
829
|
-
try {
|
|
830
|
-
const response = await fetch(location.href);
|
|
831
|
-
if (!response.ok)
|
|
832
|
-
throw new Error("Failed to fetch the page");
|
|
833
|
-
const html = await response.text();
|
|
834
|
-
const parser = new DOMParser;
|
|
835
|
-
const doc = parser.parseFromString(html, "text/html");
|
|
836
|
-
doc.title = this._name;
|
|
837
|
-
const wrapper = doc.querySelector('[data-wrapper="app"]');
|
|
838
|
-
if (wrapper) {
|
|
839
|
-
wrapper.setAttribute("data-snapshot", "true");
|
|
840
|
-
wrapper.innerHTML = this._snapshot_html;
|
|
841
|
-
} else {
|
|
842
|
-
console.error("Wrapper or template is not found");
|
|
843
|
-
return;
|
|
844
|
-
}
|
|
845
|
-
const snapshot = doc.documentElement.outerHTML;
|
|
846
|
-
await fetch(location.origin, {
|
|
847
|
-
body: snapshot,
|
|
848
|
-
method: "POST",
|
|
849
|
-
headers: {
|
|
850
|
-
"Content-Type": "text/html",
|
|
851
|
-
"cradova-snapshot": location.href.slice(location.origin.length)
|
|
852
|
-
}
|
|
853
|
-
});
|
|
854
|
-
} catch (error) {
|
|
855
|
-
console.error("Snapshot error:", error);
|
|
856
|
-
}
|
|
857
|
-
this._snapshot_html = undefined;
|
|
858
805
|
}
|
|
859
806
|
set onDeactivate(cb) {
|
|
860
807
|
this._unload_CB = cb;
|
|
861
808
|
}
|
|
809
|
+
set onActivate(cb) {
|
|
810
|
+
this._activate_CB = cb;
|
|
811
|
+
}
|
|
862
812
|
async _load() {
|
|
863
813
|
if (this._name)
|
|
864
814
|
document.title = this._name;
|
|
865
815
|
window.CradovaEvent.dispatchEvent("after_page_is_killed");
|
|
866
816
|
this._template = div({ id: "page" }, this._html);
|
|
867
817
|
RouterBox.doc.innerHTML = "";
|
|
868
|
-
if (this._snapshot)
|
|
869
|
-
this._snapshot_html = this._template.outerHTML;
|
|
870
818
|
RouterBox.doc.appendChild(this._template);
|
|
819
|
+
if (this._activate_CB)
|
|
820
|
+
await this._activate_CB.apply(this);
|
|
871
821
|
window.CradovaEvent.dispatchEvent("after_comp_is_mounted");
|
|
872
|
-
if (this._snapshot)
|
|
873
|
-
this._takeSnapShot();
|
|
874
822
|
}
|
|
875
823
|
}
|
|
876
824
|
|
|
@@ -922,7 +870,7 @@ class RouterBoxClass {
|
|
|
922
870
|
this.pageData.params = params;
|
|
923
871
|
}
|
|
924
872
|
await route._load();
|
|
925
|
-
this.lastNavigatedRouteController && this.lastNavigatedRouteController._unload_CB?.();
|
|
873
|
+
this.lastNavigatedRouteController && (this.lastNavigatedRouteController._template = undefined) && this.lastNavigatedRouteController._unload_CB?.apply(this.lastNavigatedRouteController);
|
|
926
874
|
this.lastNavigatedRoute = url;
|
|
927
875
|
this.lastNavigatedRouteController = route;
|
|
928
876
|
} catch (error) {
|
|
@@ -1101,75 +1049,6 @@ class RefInstance {
|
|
|
1101
1049
|
return [this, name];
|
|
1102
1050
|
}
|
|
1103
1051
|
}
|
|
1104
|
-
|
|
1105
|
-
class VirtualList {
|
|
1106
|
-
dataStore;
|
|
1107
|
-
renderItem;
|
|
1108
|
-
renderScheduled;
|
|
1109
|
-
container;
|
|
1110
|
-
idxs = [];
|
|
1111
|
-
constructor(container, dataStore, renderItemFunction) {
|
|
1112
|
-
this.dataStore = dataStore;
|
|
1113
|
-
this.renderItem = renderItemFunction;
|
|
1114
|
-
this.renderScheduled = false;
|
|
1115
|
-
this.container = container;
|
|
1116
|
-
this.scheduleRender();
|
|
1117
|
-
this.idxs.push(dataStore.subscribers["dataChanged"]?.length || 0);
|
|
1118
|
-
this.dataStore.notify("dataChanged", () => {
|
|
1119
|
-
this.scheduleRender();
|
|
1120
|
-
});
|
|
1121
|
-
this.idxs.push(dataStore.subscribers["itemUpdated"]?.length || 0);
|
|
1122
|
-
this.dataStore.notify("itemUpdated", () => {
|
|
1123
|
-
this.scheduleRender();
|
|
1124
|
-
});
|
|
1125
|
-
}
|
|
1126
|
-
scheduleRender() {
|
|
1127
|
-
if (this.renderScheduled)
|
|
1128
|
-
return;
|
|
1129
|
-
this.renderScheduled = true;
|
|
1130
|
-
requestAnimationFrame(this.render.bind(this));
|
|
1131
|
-
}
|
|
1132
|
-
render() {
|
|
1133
|
-
const loop2 = Math.max(this.dataStore.store.length, this.container.children.length);
|
|
1134
|
-
const needsFullRender = this.dataStore.store._isDirty();
|
|
1135
|
-
for (let i2 = 0;i2 < loop2; i2++) {
|
|
1136
|
-
if (needsFullRender || this.dataStore.store._isDirty(i2)) {
|
|
1137
|
-
const dataItem = this.dataStore.store.get(i2);
|
|
1138
|
-
const newDOM = this.renderItem(dataItem, i2);
|
|
1139
|
-
const oldDOM = this.container.children[i2];
|
|
1140
|
-
if (newDOM instanceof HTMLElement) {
|
|
1141
|
-
if (oldDOM) {
|
|
1142
|
-
if (dataItem === undefined) {
|
|
1143
|
-
oldDOM.remove();
|
|
1144
|
-
continue;
|
|
1145
|
-
}
|
|
1146
|
-
this.container.replaceChild(newDOM, oldDOM);
|
|
1147
|
-
} else {
|
|
1148
|
-
this.container.appendChild(newDOM);
|
|
1149
|
-
}
|
|
1150
|
-
} else {
|
|
1151
|
-
if (oldDOM) {
|
|
1152
|
-
oldDOM.remove();
|
|
1153
|
-
}
|
|
1154
|
-
}
|
|
1155
|
-
}
|
|
1156
|
-
}
|
|
1157
|
-
if (needsFullRender) {
|
|
1158
|
-
this.dataStore.store._clearAllDirty();
|
|
1159
|
-
}
|
|
1160
|
-
this.renderScheduled = false;
|
|
1161
|
-
}
|
|
1162
|
-
destroy() {
|
|
1163
|
-
this.renderItem = null;
|
|
1164
|
-
this.container.innerHTML = "";
|
|
1165
|
-
this.container = null;
|
|
1166
|
-
this.renderScheduled = false;
|
|
1167
|
-
this.dataStore.subscribers["dataChanged"].splice(this.idxs[0], 1);
|
|
1168
|
-
this.dataStore.subscribers["itemUpdated"].splice(this.idxs[1], 1);
|
|
1169
|
-
this.idxs.length = 0;
|
|
1170
|
-
this.dataStore = null;
|
|
1171
|
-
}
|
|
1172
|
-
}
|
|
1173
1052
|
export {
|
|
1174
1053
|
video,
|
|
1175
1054
|
useExternalEffect,
|
|
@@ -1207,23 +1086,20 @@ export {
|
|
|
1207
1086
|
h3,
|
|
1208
1087
|
h2,
|
|
1209
1088
|
h1,
|
|
1210
|
-
funcManager,
|
|
1211
1089
|
fragment,
|
|
1212
1090
|
form,
|
|
1213
1091
|
footer,
|
|
1214
1092
|
div,
|
|
1215
|
-
cradovaEvent,
|
|
1216
1093
|
cra,
|
|
1094
|
+
compManager,
|
|
1217
1095
|
canvas,
|
|
1218
1096
|
button,
|
|
1219
1097
|
audio,
|
|
1220
1098
|
a,
|
|
1221
|
-
VirtualList,
|
|
1222
1099
|
Signal,
|
|
1223
1100
|
Router,
|
|
1224
1101
|
RefInstance,
|
|
1225
1102
|
Page,
|
|
1226
|
-
List,
|
|
1227
1103
|
$switch,
|
|
1228
1104
|
$case
|
|
1229
1105
|
};
|
|
@@ -65,9 +65,10 @@ export declare class Signal<Type = any> {
|
|
|
65
65
|
* @param template
|
|
66
66
|
*/
|
|
67
67
|
export declare class Page {
|
|
68
|
+
_activate_CB?: (this: Page) => Promise<void> | void;
|
|
68
69
|
constructor(pageParams: CradovaPageType);
|
|
69
|
-
|
|
70
|
-
set
|
|
70
|
+
set onDeactivate(cb: (this: Page) => Promise<void> | void);
|
|
71
|
+
set onActivate(cb: (this: Page) => Promise<void> | void);
|
|
71
72
|
}
|
|
72
73
|
/** cradova router
|
|
73
74
|
* ---
|
|
@@ -151,8 +152,4 @@ export declare class RefInstance<T = unknown> {
|
|
|
151
152
|
*/
|
|
152
153
|
bind(name: string): [RefInstance<T>, string];
|
|
153
154
|
}
|
|
154
|
-
export declare class VirtualList {
|
|
155
|
-
idxs: number[];
|
|
156
|
-
constructor(container: HTMLElement, dataStore: Signal<any[]>, renderItemFunction: (item: any, index: number) => HTMLElement);
|
|
157
|
-
}
|
|
158
155
|
export {};
|
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
import * as CSS from "csstype";
|
|
2
1
|
import type { Comp, VJS_params_TYPE } from "./types.js";
|
|
3
|
-
import { Signal } from "./classes.js";
|
|
4
2
|
export declare const cra: <E extends HTMLElement>(tag: string) => (...Children_and_Properties: VJS_params_TYPE<E>) => E;
|
|
5
3
|
type Case<K> = (key: K) => HTMLElement | undefined;
|
|
6
4
|
export declare const $case: (value: any, element: any) => Case<any>;
|
|
@@ -16,7 +14,7 @@ export declare const fragment: (children: VJS_params_TYPE<HTMLElement>) => Docum
|
|
|
16
14
|
export declare const isArrowFunc: (fn: Function) => boolean;
|
|
17
15
|
export declare const toComp: (comp: Comp, args?: any[]) => HTMLElement | undefined;
|
|
18
16
|
export declare const toCompNoRender: (comp: Comp) => Comp;
|
|
19
|
-
export declare const
|
|
17
|
+
export declare const compManager: {
|
|
20
18
|
render(component: Comp): HTMLElement | undefined;
|
|
21
19
|
recall(component: Comp): void;
|
|
22
20
|
activate(component: Comp): void;
|
|
@@ -29,11 +27,6 @@ export declare const funcManager: {
|
|
|
29
27
|
cleanupEffects(component: Comp): void;
|
|
30
28
|
unmount(component: Comp): void;
|
|
31
29
|
};
|
|
32
|
-
export declare const List: <T>(signal: Signal<T[]>, item: (item: T) => HTMLElement, options?: {
|
|
33
|
-
className?: string;
|
|
34
|
-
id?: string;
|
|
35
|
-
style?: Partial<CSS.Properties>;
|
|
36
|
-
}) => HTMLDivElement;
|
|
37
30
|
/**
|
|
38
31
|
* Invokes a function with the provided arguments.
|
|
39
32
|
* @param fn - The function to invoke.
|
|
@@ -28,17 +28,7 @@ export type CradovaPageType = {
|
|
|
28
28
|
* @returns void
|
|
29
29
|
* .
|
|
30
30
|
*/
|
|
31
|
-
template: (
|
|
32
|
-
/**
|
|
33
|
-
* Cradova page
|
|
34
|
-
* ---
|
|
35
|
-
* a snapshot is the initial render of a page.
|
|
36
|
-
* snapshot isolation allows for good SEO guarantee with the flexibility of client based rendering
|
|
37
|
-
* the origin server should accept post requesting to save a snapshot of this page for future use.
|
|
38
|
-
* the origin server should respond with the snapshot for future request to the page url
|
|
39
|
-
* the origin server should implement suitable mechanisms to invalidate it's caches
|
|
40
|
-
*/
|
|
41
|
-
snapshotIsolation?: boolean;
|
|
31
|
+
template: () => HTMLElement | ((ctx: Comp) => HTMLElement) | Comp;
|
|
42
32
|
};
|
|
43
33
|
export type browserPageType<importType = Page> = importType | Promise<importType> | (() => Promise<importType>);
|
|
44
34
|
export interface Comp extends Function {
|