sigmx 0.1.0 → 0.2.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 +54 -43
- package/dist/cli.js +3 -1
- package/dist/cli.js.map +2 -2
- package/dist/kernel/compile.d.ts +8 -9
- package/dist/kernel/compile.js +102 -67
- package/dist/kernel/compile.js.map +2 -2
- package/dist/kernel/contracts.d.ts +12 -13
- package/dist/kernel/index.d.ts +11 -12
- package/dist/kernel/index.js +14 -12
- package/dist/kernel/index.js.map +3 -3
- package/dist/kernel/precompile.d.ts +8 -12
- package/dist/kernel/precompile.js +33 -76
- package/dist/kernel/precompile.js.map +2 -2
- package/dist/kernel/precompiled.d.ts +7 -4
- package/dist/kernel/precompiled.js +5 -5
- package/dist/kernel/precompiled.js.map +2 -2
- package/dist/kernel/reactive.d.ts +13 -11
- package/dist/kernel/reactive.js +96 -71
- package/dist/kernel/reactive.js.map +3 -3
- package/dist/kernel/runtime.js +85 -63
- package/dist/kernel/runtime.js.map +3 -3
- package/dist/kernel/scan.d.ts +2 -11
- package/dist/kernel/scan.js +26 -9
- package/dist/kernel/scan.js.map +2 -2
- package/dist/kernel/state.d.ts +5 -8
- package/dist/kernel/state.js +114 -76
- package/dist/kernel/state.js.map +2 -2
- package/dist/kernel/strict-csp.d.ts +0 -5
- package/dist/kernel/strict-csp.js +2 -2
- package/dist/kernel/strict-csp.js.map +2 -2
- package/dist/lib/casing.d.ts +4 -1
- package/dist/lib/casing.js +8 -1
- package/dist/lib/casing.js.map +2 -2
- package/dist/lib/objects.d.ts +5 -4
- package/dist/lib/objects.js +13 -5
- package/dist/lib/objects.js.map +2 -2
- package/dist/lib/schedule.d.ts +3 -5
- package/dist/lib/schedule.js +12 -10
- package/dist/lib/schedule.js.map +2 -2
- package/dist/lib/sse.d.ts +10 -1
- package/dist/lib/sse.js +32 -28
- package/dist/lib/sse.js.map +2 -2
- package/dist/plugins/def.d.ts +5 -0
- package/dist/plugins/def.js +22 -0
- package/dist/plugins/def.js.map +7 -0
- package/dist/plugins/directives/attribute-sync.js +8 -12
- package/dist/plugins/directives/attribute-sync.js.map +2 -2
- package/dist/plugins/directives/boost.d.ts +1 -1
- package/dist/plugins/directives/boost.js +34 -30
- package/dist/plugins/directives/boost.js.map +2 -2
- package/dist/plugins/directives/busy-flag.js +13 -16
- package/dist/plugins/directives/busy-flag.js.map +2 -2
- package/dist/plugins/directives/class-toggle.js +17 -16
- package/dist/plugins/directives/class-toggle.js.map +2 -2
- package/dist/plugins/directives/cloak.js +2 -7
- package/dist/plugins/directives/cloak.js.map +2 -2
- package/dist/plugins/directives/collapse.js +36 -37
- package/dist/plugins/directives/collapse.js.map +2 -2
- package/dist/plugins/directives/declare.js +5 -8
- package/dist/plugins/directives/declare.js.map +2 -2
- package/dist/plugins/directives/derive.js +9 -15
- package/dist/plugins/directives/derive.js.map +2 -2
- package/dist/plugins/directives/element-ref.js +8 -8
- package/dist/plugins/directives/element-ref.js.map +2 -2
- package/dist/plugins/directives/event-listener.js +18 -23
- package/dist/plugins/directives/event-listener.js.map +2 -2
- package/dist/plugins/directives/frame-loop.js +9 -14
- package/dist/plugins/directives/frame-loop.js.map +2 -2
- package/dist/plugins/directives/html.js +6 -7
- package/dist/plugins/directives/html.js.map +2 -2
- package/dist/plugins/directives/inline-style.js +17 -20
- package/dist/plugins/directives/inline-style.js.map +2 -2
- package/dist/plugins/directives/mask.js +19 -23
- package/dist/plugins/directives/mask.js.map +2 -2
- package/dist/plugins/directives/media-query.d.ts +4 -1
- package/dist/plugins/directives/media-query.js +13 -12
- package/dist/plugins/directives/media-query.js.map +2 -2
- package/dist/plugins/directives/on-mount.js +4 -9
- package/dist/plugins/directives/on-mount.js.map +2 -2
- package/dist/plugins/directives/patch-listener.js +24 -19
- package/dist/plugins/directives/patch-listener.js.map +2 -2
- package/dist/plugins/directives/remove-me.js +7 -8
- package/dist/plugins/directives/remove-me.js.map +2 -2
- package/dist/plugins/directives/scroll-to.d.ts +4 -1
- package/dist/plugins/directives/scroll-to.js +8 -14
- package/dist/plugins/directives/scroll-to.js.map +2 -2
- package/dist/plugins/directives/size-watch.js +7 -12
- package/dist/plugins/directives/size-watch.js.map +2 -2
- package/dist/plugins/directives/state-dump.js +6 -10
- package/dist/plugins/directives/state-dump.js.map +2 -2
- package/dist/plugins/directives/storage-sync.js +13 -9
- package/dist/plugins/directives/storage-sync.js.map +2 -2
- package/dist/plugins/directives/teleport.js +8 -14
- package/dist/plugins/directives/teleport.js.map +2 -2
- package/dist/plugins/directives/text-content.js +6 -7
- package/dist/plugins/directives/text-content.js.map +2 -2
- package/dist/plugins/directives/timer.js +7 -13
- package/dist/plugins/directives/timer.js.map +2 -2
- package/dist/plugins/directives/transition.d.ts +1 -2
- package/dist/plugins/directives/transition.js +32 -34
- package/dist/plugins/directives/transition.js.map +2 -2
- package/dist/plugins/directives/tween.d.ts +2 -2
- package/dist/plugins/directives/tween.js +34 -50
- package/dist/plugins/directives/tween.js.map +2 -2
- package/dist/plugins/directives/two-way-bind.d.ts +1 -1
- package/dist/plugins/directives/two-way-bind.js +70 -67
- package/dist/plugins/directives/two-way-bind.js.map +2 -2
- package/dist/plugins/directives/url-params.js +36 -59
- package/dist/plugins/directives/url-params.js.map +3 -3
- package/dist/plugins/directives/url-replace.js +6 -7
- package/dist/plugins/directives/url-replace.js.map +2 -2
- package/dist/plugins/directives/validity.js +6 -9
- package/dist/plugins/directives/validity.js.map +2 -2
- package/dist/plugins/directives/viewport.js +18 -23
- package/dist/plugins/directives/viewport.js.map +2 -2
- package/dist/plugins/directives/visibility.js +9 -14
- package/dist/plugins/directives/visibility.js.map +2 -2
- package/dist/plugins/directives/watch.d.ts +0 -1
- package/dist/plugins/directives/watch.js +2 -8
- package/dist/plugins/directives/watch.js.map +2 -2
- package/dist/plugins/functions/bulk-set.js +10 -7
- package/dist/plugins/functions/bulk-set.js.map +2 -2
- package/dist/plugins/functions/bulk-toggle.js +10 -7
- package/dist/plugins/functions/bulk-toggle.js.map +2 -2
- package/dist/plugins/functions/confirm.js +2 -2
- package/dist/plugins/functions/confirm.js.map +2 -2
- package/dist/plugins/functions/copy-text.js +5 -5
- package/dist/plugins/functions/copy-text.js.map +2 -2
- package/dist/plugins/functions/dispatch.js +5 -5
- package/dist/plugins/functions/dispatch.js.map +2 -2
- package/dist/plugins/functions/locale-format.d.ts +4 -1
- package/dist/plugins/functions/locale-format.js +9 -16
- package/dist/plugins/functions/locale-format.js.map +2 -2
- package/dist/plugins/functions/range-map.js +6 -6
- package/dist/plugins/functions/range-map.js.map +2 -2
- package/dist/plugins/functions/request.d.ts +7 -3
- package/dist/plugins/functions/request.js +85 -80
- package/dist/plugins/functions/request.js.map +2 -2
- package/dist/plugins/functions/untracked-read.js +3 -2
- package/dist/plugins/functions/untracked-read.js.map +2 -2
- package/dist/plugins/functions/websocket.d.ts +3 -3
- package/dist/plugins/functions/websocket.js +18 -25
- package/dist/plugins/functions/websocket.js.map +2 -2
- package/dist/plugins/index.d.ts +34 -36
- package/dist/plugins/index.js +31 -35
- package/dist/plugins/index.js.map +2 -2
- package/dist/plugins/server-events/apply-elements.d.ts +1 -1
- package/dist/plugins/server-events/apply-elements.js +41 -40
- package/dist/plugins/server-events/apply-elements.js.map +2 -2
- package/dist/plugins/server-events/apply-state.js +9 -12
- package/dist/plugins/server-events/apply-state.js.map +2 -2
- package/dist/plugins/server-events/morph.d.ts +0 -2
- package/dist/plugins/server-events/morph.js +58 -55
- package/dist/plugins/server-events/morph.js.map +3 -3
- package/dist/presets/all.d.ts +0 -1
- package/dist/presets/all.js +22 -26
- package/dist/presets/all.js.map +2 -2
- package/dist/presets/essentials.d.ts +0 -1
- package/dist/presets/essentials.js +27 -9
- package/dist/presets/essentials.js.map +2 -2
- package/dist/presets/minimal.d.ts +0 -1
- package/dist/presets/minimal.js +2 -2
- package/dist/presets/minimal.js.map +2 -2
- package/dist/server.d.ts +108 -0
- package/dist/server.js +218 -0
- package/dist/server.js.map +7 -0
- package/dist/sigmx.standalone.js +1 -1
- package/dist/standalone.js.map +2 -2
- package/dist/vite.d.ts +2 -2
- package/dist/vite.js +48 -15
- package/dist/vite.js.map +2 -2
- package/package.json +21 -2
- package/dist/auto.d.ts +0 -1
- package/dist/auto.js +0 -7
- package/dist/auto.js.map +0 -7
- package/dist/core/csp.d.ts +0 -7
- package/dist/core/csp.js +0 -20
- package/dist/core/csp.js.map +0 -7
- package/dist/core/engine.d.ts +0 -10
- package/dist/core/engine.js +0 -200
- package/dist/core/engine.js.map +0 -7
- package/dist/core/expr.d.ts +0 -12
- package/dist/core/expr.js +0 -94
- package/dist/core/expr.js.map +0 -7
- package/dist/core/index.d.ts +0 -16
- package/dist/core/index.js +0 -46
- package/dist/core/index.js.map +0 -7
- package/dist/core/signals.d.ts +0 -42
- package/dist/core/signals.js +0 -195
- package/dist/core/signals.js.map +0 -7
- package/dist/core/store.d.ts +0 -32
- package/dist/core/store.js +0 -185
- package/dist/core/store.js.map +0 -7
- package/dist/core/types.d.ts +0 -101
- package/dist/core/types.js +0 -1
- package/dist/core/types.js.map +0 -7
- package/dist/plugins/actions/clipboard.d.ts +0 -2
- package/dist/plugins/actions/clipboard.js +0 -11
- package/dist/plugins/actions/clipboard.js.map +0 -7
- package/dist/plugins/actions/fit.d.ts +0 -2
- package/dist/plugins/actions/fit.js +0 -14
- package/dist/plugins/actions/fit.js.map +0 -7
- package/dist/plugins/actions/intl.d.ts +0 -2
- package/dist/plugins/actions/intl.js +0 -21
- package/dist/plugins/actions/intl.js.map +0 -7
- package/dist/plugins/actions/peek.d.ts +0 -2
- package/dist/plugins/actions/peek.js +0 -6
- package/dist/plugins/actions/peek.js.map +0 -7
- package/dist/plugins/actions/setAll.d.ts +0 -2
- package/dist/plugins/actions/setAll.js +0 -11
- package/dist/plugins/actions/setAll.js.map +0 -7
- package/dist/plugins/actions/toggleAll.d.ts +0 -2
- package/dist/plugins/actions/toggleAll.js +0 -11
- package/dist/plugins/actions/toggleAll.js.map +0 -7
- package/dist/plugins/attributes/attr.d.ts +0 -2
- package/dist/plugins/attributes/attr.js +0 -20
- package/dist/plugins/attributes/attr.js.map +0 -7
- package/dist/plugins/attributes/bind.d.ts +0 -6
- package/dist/plugins/attributes/bind.js +0 -81
- package/dist/plugins/attributes/bind.js.map +0 -7
- package/dist/plugins/attributes/class.d.ts +0 -2
- package/dist/plugins/attributes/class.js +0 -22
- package/dist/plugins/attributes/class.js.map +0 -7
- package/dist/plugins/attributes/computed.d.ts +0 -2
- package/dist/plugins/attributes/computed.js +0 -20
- package/dist/plugins/attributes/computed.js.map +0 -7
- package/dist/plugins/attributes/customValidity.d.ts +0 -2
- package/dist/plugins/attributes/customValidity.js +0 -14
- package/dist/plugins/attributes/customValidity.js.map +0 -7
- package/dist/plugins/attributes/effect.d.ts +0 -2
- package/dist/plugins/attributes/effect.js +0 -12
- package/dist/plugins/attributes/effect.js.map +0 -7
- package/dist/plugins/attributes/indicator.d.ts +0 -2
- package/dist/plugins/attributes/indicator.js +0 -20
- package/dist/plugins/attributes/indicator.js.map +0 -7
- package/dist/plugins/attributes/init.d.ts +0 -2
- package/dist/plugins/attributes/init.js +0 -14
- package/dist/plugins/attributes/init.js.map +0 -7
- package/dist/plugins/attributes/jsonSignals.d.ts +0 -2
- package/dist/plugins/attributes/jsonSignals.js +0 -15
- package/dist/plugins/attributes/jsonSignals.js.map +0 -7
- package/dist/plugins/attributes/matchMedia.d.ts +0 -2
- package/dist/plugins/attributes/matchMedia.js +0 -19
- package/dist/plugins/attributes/matchMedia.js.map +0 -7
- package/dist/plugins/attributes/on.d.ts +0 -5
- package/dist/plugins/attributes/on.js +0 -28
- package/dist/plugins/attributes/on.js.map +0 -7
- package/dist/plugins/attributes/onIntersect.d.ts +0 -2
- package/dist/plugins/attributes/onIntersect.js +0 -28
- package/dist/plugins/attributes/onIntersect.js.map +0 -7
- package/dist/plugins/attributes/onInterval.d.ts +0 -2
- package/dist/plugins/attributes/onInterval.js +0 -18
- package/dist/plugins/attributes/onInterval.js.map +0 -7
- package/dist/plugins/attributes/onRaf.d.ts +0 -1
- package/dist/plugins/attributes/onRaf.js +0 -19
- package/dist/plugins/attributes/onRaf.js.map +0 -7
- package/dist/plugins/attributes/onResize.d.ts +0 -1
- package/dist/plugins/attributes/onResize.js +0 -17
- package/dist/plugins/attributes/onResize.js.map +0 -7
- package/dist/plugins/attributes/onSignalPatch.d.ts +0 -5
- package/dist/plugins/attributes/onSignalPatch.js +0 -35
- package/dist/plugins/attributes/onSignalPatch.js.map +0 -7
- package/dist/plugins/attributes/persist.d.ts +0 -6
- package/dist/plugins/attributes/persist.js +0 -16
- package/dist/plugins/attributes/persist.js.map +0 -7
- package/dist/plugins/attributes/queryString.d.ts +0 -5
- package/dist/plugins/attributes/queryString.js +0 -54
- package/dist/plugins/attributes/queryString.js.map +0 -7
- package/dist/plugins/attributes/ref.d.ts +0 -2
- package/dist/plugins/attributes/ref.js +0 -13
- package/dist/plugins/attributes/ref.js.map +0 -7
- package/dist/plugins/attributes/replaceUrl.d.ts +0 -1
- package/dist/plugins/attributes/replaceUrl.js +0 -11
- package/dist/plugins/attributes/replaceUrl.js.map +0 -7
- package/dist/plugins/attributes/scrollIntoView.d.ts +0 -2
- package/dist/plugins/attributes/scrollIntoView.js +0 -19
- package/dist/plugins/attributes/scrollIntoView.js.map +0 -7
- package/dist/plugins/attributes/show.d.ts +0 -2
- package/dist/plugins/attributes/show.js +0 -19
- package/dist/plugins/attributes/show.js.map +0 -7
- package/dist/plugins/attributes/signals.d.ts +0 -2
- package/dist/plugins/attributes/signals.js +0 -13
- package/dist/plugins/attributes/signals.js.map +0 -7
- package/dist/plugins/attributes/style.d.ts +0 -2
- package/dist/plugins/attributes/style.js +0 -25
- package/dist/plugins/attributes/style.js.map +0 -7
- package/dist/plugins/attributes/text.d.ts +0 -1
- package/dist/plugins/attributes/text.js +0 -13
- package/dist/plugins/attributes/text.js.map +0 -7
- package/dist/plugins/attributes/viewTransition.d.ts +0 -1
- package/dist/plugins/attributes/viewTransition.js +0 -11
- package/dist/plugins/attributes/viewTransition.js.map +0 -7
- package/dist/plugins/directives/transition-name.d.ts +0 -1
- package/dist/plugins/directives/transition-name.js +0 -11
- package/dist/plugins/directives/transition-name.js.map +0 -7
- package/dist/plugins/directives/trap.d.ts +0 -5
- package/dist/plugins/directives/trap.js +0 -48
- package/dist/plugins/directives/trap.js.map +0 -7
- package/dist/sigmx.auto.js +0 -5
- package/dist/utils/object.d.ts +0 -9
- package/dist/utils/object.js +0 -26
- package/dist/utils/object.js.map +0 -7
- package/dist/utils/text.d.ts +0 -7
- package/dist/utils/text.js +0 -15
- package/dist/utils/text.js.map +0 -7
- package/dist/utils/timing.d.ts +0 -14
- package/dist/utils/timing.js +0 -58
- package/dist/utils/timing.js.map +0 -7
package/dist/kernel/reactive.js
CHANGED
|
@@ -5,19 +5,15 @@ let flushing = false;
|
|
|
5
5
|
const queue = /* @__PURE__ */ new Set();
|
|
6
6
|
const settled = /* @__PURE__ */ new Set();
|
|
7
7
|
class Signal {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
/** @internal */
|
|
11
|
-
e = 0;
|
|
12
|
-
/** @internal */
|
|
13
|
-
f = /* @__PURE__ */ new Set();
|
|
8
|
+
d = 0;
|
|
9
|
+
e = /* @__PURE__ */ new Set();
|
|
14
10
|
constructor(v) {
|
|
15
11
|
this.a = v;
|
|
16
12
|
}
|
|
17
13
|
get value() {
|
|
18
14
|
if (active) {
|
|
19
|
-
active.b.set(this, this.
|
|
20
|
-
this.
|
|
15
|
+
active.b.set(this, this.d);
|
|
16
|
+
this.e.add(active);
|
|
21
17
|
}
|
|
22
18
|
return this.a;
|
|
23
19
|
}
|
|
@@ -27,28 +23,20 @@ class Signal {
|
|
|
27
23
|
this.bump();
|
|
28
24
|
}
|
|
29
25
|
}
|
|
30
|
-
/** Read without subscribing. */
|
|
31
26
|
peek() {
|
|
32
27
|
return this.a;
|
|
33
28
|
}
|
|
34
29
|
/** Notify subscribers without replacing the value (after mutating an array or object in place). */
|
|
35
30
|
bump() {
|
|
36
|
-
this.
|
|
37
|
-
for (const s of this.
|
|
38
|
-
|
|
31
|
+
this.d++;
|
|
32
|
+
for (const s of this.e) s.g();
|
|
33
|
+
depth || flush();
|
|
39
34
|
}
|
|
40
35
|
}
|
|
41
36
|
const release = (t) => {
|
|
42
|
-
for (const d of t.b.keys()) d.
|
|
37
|
+
for (const d of t.b.keys()) d.e.delete(t);
|
|
43
38
|
t.b.clear();
|
|
44
39
|
};
|
|
45
|
-
const stale = (t) => {
|
|
46
|
-
for (const [d, seen] of t.b) {
|
|
47
|
-
if (d instanceof Computed) d.i();
|
|
48
|
-
if (d.e !== seen) return true;
|
|
49
|
-
}
|
|
50
|
-
return false;
|
|
51
|
-
};
|
|
52
40
|
const capture = (t, fn) => {
|
|
53
41
|
release(t);
|
|
54
42
|
const prev = active;
|
|
@@ -59,85 +47,93 @@ const capture = (t, fn) => {
|
|
|
59
47
|
active = prev;
|
|
60
48
|
}
|
|
61
49
|
};
|
|
50
|
+
const stale = (t) => {
|
|
51
|
+
if (!t.b.size) return true;
|
|
52
|
+
for (const [d, seen] of t.b) {
|
|
53
|
+
if (d instanceof Computed) d.l();
|
|
54
|
+
if (d.d !== seen) return true;
|
|
55
|
+
}
|
|
56
|
+
return false;
|
|
57
|
+
};
|
|
62
58
|
class Computed extends Signal {
|
|
63
59
|
b = /* @__PURE__ */ new Map();
|
|
64
|
-
|
|
65
|
-
g = true;
|
|
66
|
-
/** @internal */
|
|
67
|
-
c;
|
|
60
|
+
c = true;
|
|
68
61
|
constructor(fn) {
|
|
69
62
|
super(void 0);
|
|
70
|
-
this.
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
this
|
|
76
|
-
|
|
77
|
-
const x = capture(this, this.c);
|
|
63
|
+
this.h = fn;
|
|
64
|
+
}
|
|
65
|
+
l() {
|
|
66
|
+
if (!this.c) return;
|
|
67
|
+
this.c = false;
|
|
68
|
+
if (!stale(this)) return;
|
|
69
|
+
const x = capture(this, this.h);
|
|
78
70
|
if (!Object.is(x, this.a)) {
|
|
79
71
|
this.a = x;
|
|
80
|
-
this.
|
|
72
|
+
this.d++;
|
|
81
73
|
}
|
|
82
74
|
}
|
|
83
75
|
get value() {
|
|
84
|
-
this.
|
|
76
|
+
this.l();
|
|
85
77
|
return super.value;
|
|
86
78
|
}
|
|
87
79
|
set value(_) {
|
|
88
|
-
throw new Error("computed
|
|
80
|
+
throw new Error("computed is read-only");
|
|
89
81
|
}
|
|
90
|
-
|
|
91
|
-
this.
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
h() {
|
|
95
|
-
if (!this.g) {
|
|
96
|
-
this.g = true;
|
|
97
|
-
for (const s of this.f) s.h();
|
|
82
|
+
g() {
|
|
83
|
+
if (!this.c) {
|
|
84
|
+
this.c = true;
|
|
85
|
+
for (const s of this.e) s.g();
|
|
98
86
|
}
|
|
99
87
|
}
|
|
88
|
+
/** Unsubscribe from every dependency; the computed is no longer recalculated. Public: the store calls it. */
|
|
89
|
+
dispose() {
|
|
90
|
+
release(this);
|
|
91
|
+
this.c = false;
|
|
92
|
+
}
|
|
100
93
|
}
|
|
101
94
|
class Effect {
|
|
102
95
|
b = /* @__PURE__ */ new Map();
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
c;
|
|
107
|
-
l;
|
|
96
|
+
f = false;
|
|
97
|
+
i = false;
|
|
98
|
+
j = /* @__PURE__ */ new Set();
|
|
108
99
|
constructor(fn, onError) {
|
|
109
|
-
this.
|
|
110
|
-
this.
|
|
100
|
+
this.h = fn;
|
|
101
|
+
this.m = onError;
|
|
111
102
|
}
|
|
112
|
-
|
|
113
|
-
if (!this.
|
|
114
|
-
this.
|
|
103
|
+
g() {
|
|
104
|
+
if (!this.i && !this.f) {
|
|
105
|
+
this.f = true;
|
|
115
106
|
queue.add(this);
|
|
116
107
|
}
|
|
117
108
|
}
|
|
118
109
|
n() {
|
|
119
|
-
this.
|
|
120
|
-
if (this.
|
|
121
|
-
for (const c of this.d) c.m();
|
|
122
|
-
this.d.clear();
|
|
110
|
+
this.f = false;
|
|
111
|
+
if (this.i) return;
|
|
123
112
|
const prevOwner = owner;
|
|
124
113
|
owner = this;
|
|
125
114
|
depth++;
|
|
126
115
|
try {
|
|
127
|
-
|
|
116
|
+
if (stale(this)) {
|
|
117
|
+
this.o();
|
|
118
|
+
capture(this, this.h);
|
|
119
|
+
}
|
|
128
120
|
} catch (e) {
|
|
129
|
-
if (!this.
|
|
130
|
-
this.
|
|
121
|
+
if (!this.m) throw e;
|
|
122
|
+
this.m(e);
|
|
131
123
|
} finally {
|
|
132
124
|
depth--;
|
|
133
125
|
owner = prevOwner;
|
|
134
126
|
}
|
|
135
127
|
}
|
|
136
|
-
|
|
137
|
-
this.k
|
|
128
|
+
o() {
|
|
129
|
+
for (const c of this.j) c.k();
|
|
130
|
+
this.j.clear();
|
|
131
|
+
}
|
|
132
|
+
k() {
|
|
133
|
+
this.i = true;
|
|
138
134
|
release(this);
|
|
139
|
-
|
|
140
|
-
this.
|
|
135
|
+
if (active === this) active = void 0;
|
|
136
|
+
this.o();
|
|
141
137
|
queue.delete(this);
|
|
142
138
|
}
|
|
143
139
|
}
|
|
@@ -145,17 +141,31 @@ const signal = (value) => new Signal(value);
|
|
|
145
141
|
const computed = (fn) => new Computed(fn);
|
|
146
142
|
const effect = (fn, onError) => {
|
|
147
143
|
const e = new Effect(fn, onError);
|
|
148
|
-
owner?.
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
144
|
+
owner?.j.add(e);
|
|
145
|
+
try {
|
|
146
|
+
e.n();
|
|
147
|
+
depth || flush();
|
|
148
|
+
} catch (err) {
|
|
149
|
+
e.k();
|
|
150
|
+
throw err;
|
|
151
|
+
}
|
|
152
|
+
return () => e.k();
|
|
153
|
+
};
|
|
154
|
+
const rootEffect = (fn, onError) => {
|
|
155
|
+
const prev = owner;
|
|
156
|
+
owner = void 0;
|
|
157
|
+
try {
|
|
158
|
+
return effect(fn, onError);
|
|
159
|
+
} finally {
|
|
160
|
+
owner = prev;
|
|
161
|
+
}
|
|
152
162
|
};
|
|
153
163
|
const batch = (fn) => {
|
|
154
164
|
depth++;
|
|
155
165
|
try {
|
|
156
166
|
return fn();
|
|
157
167
|
} finally {
|
|
158
|
-
|
|
168
|
+
--depth || flush();
|
|
159
169
|
}
|
|
160
170
|
};
|
|
161
171
|
const untracked = (fn) => {
|
|
@@ -174,18 +184,32 @@ const onSettled = (fn) => {
|
|
|
174
184
|
const flush = () => {
|
|
175
185
|
if (flushing || depth) return;
|
|
176
186
|
flushing = true;
|
|
187
|
+
let thrown;
|
|
188
|
+
let failed = false;
|
|
177
189
|
try {
|
|
178
190
|
let guard = 0;
|
|
179
191
|
while (queue.size) {
|
|
180
|
-
if (++guard > 1e5)
|
|
192
|
+
if (++guard > 1e5) {
|
|
193
|
+
for (const e2 of queue) e2.f = false;
|
|
194
|
+
queue.clear();
|
|
195
|
+
throw new Error("effect loop");
|
|
196
|
+
}
|
|
181
197
|
const e = queue.values().next().value;
|
|
182
198
|
queue.delete(e);
|
|
183
|
-
|
|
199
|
+
try {
|
|
200
|
+
e.n();
|
|
201
|
+
} catch (err) {
|
|
202
|
+
if (!failed) {
|
|
203
|
+
failed = true;
|
|
204
|
+
thrown = err;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
184
207
|
}
|
|
185
208
|
} finally {
|
|
186
209
|
flushing = false;
|
|
187
210
|
}
|
|
188
211
|
for (const fn of settled) fn();
|
|
212
|
+
if (failed) throw thrown;
|
|
189
213
|
};
|
|
190
214
|
export {
|
|
191
215
|
Computed,
|
|
@@ -195,6 +219,7 @@ export {
|
|
|
195
219
|
effect,
|
|
196
220
|
flush,
|
|
197
221
|
onSettled,
|
|
222
|
+
rootEffect,
|
|
198
223
|
signal,
|
|
199
224
|
untracked
|
|
200
225
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/kernel/reactive.ts"],
|
|
4
|
-
"sourcesContent": ["//
|
|
5
|
-
"mappings": "
|
|
6
|
-
"names": ["
|
|
4
|
+
"sourcesContent": ["// Members prefixed with `_` are internal and get mangled by the build.\n\ninterface Tracker {\n _deps: Map<Signal<any>, number>;\n _invalidate(): void;\n}\n\nlet active: Tracker | undefined;\nlet owner: Effect | undefined;\nlet depth = 0;\nlet flushing = false;\nconst queue = new Set<Effect>();\nconst settled = new Set<() => void>();\n\nexport class Signal<T> {\n declare _v: T;\n _ver = 0;\n _subs = new Set<Tracker>();\n constructor(v: T) {\n this._v = v;\n }\n get value(): T {\n if (active) {\n active._deps.set(this, this._ver);\n this._subs.add(active);\n }\n return this._v;\n }\n set value(x: T) {\n if (!Object.is(x, this._v)) {\n this._v = x;\n this.bump();\n }\n }\n peek(): T {\n return this._v;\n }\n /** Notify subscribers without replacing the value (after mutating an array or object in place). */\n bump(): void {\n this._ver++;\n for (const s of this._subs) s._invalidate();\n depth || flush();\n }\n}\n\n/** Drop `t`'s subscriptions. */\nconst release = (t: Tracker): void => {\n for (const d of t._deps.keys()) d._subs.delete(t);\n t._deps.clear();\n};\n\n/** Drop `t`'s subscriptions, then run `fn` with `t` as the active tracker so its reads re-subscribe. */\nconst capture = <R>(t: Tracker, fn: () => R): R => {\n release(t);\n const prev = active;\n active = t;\n try {\n return fn();\n } finally {\n active = prev;\n }\n};\n\n/** True when `t` has never run or any dependency's version moved since. Refreshes computeds on the way. */\nconst stale = (t: Tracker): boolean => {\n if (!t._deps.size) return true;\n for (const [d, seen] of t._deps) {\n if (d instanceof Computed) d._refresh();\n if (d._ver !== seen) return true;\n }\n return false;\n};\n\nexport class Computed<T> extends Signal<T> implements Tracker {\n declare _fn: () => T;\n _deps = new Map<Signal<any>, number>();\n _dirty = true;\n constructor(fn: () => T) {\n super(undefined as T);\n this._fn = fn;\n }\n _refresh(): void {\n if (!this._dirty) return;\n this._dirty = false;\n if (!stale(this)) return;\n const x = capture(this, this._fn);\n if (!Object.is(x, this._v)) {\n this._v = x;\n this._ver++;\n }\n }\n override get value(): T {\n this._refresh();\n return super.value;\n }\n override set value(_: T) {\n throw new Error('computed is read-only');\n }\n _invalidate(): void {\n if (!this._dirty) {\n this._dirty = true;\n for (const s of this._subs) s._invalidate();\n }\n }\n /** Unsubscribe from every dependency; the computed is no longer recalculated. Public: the store calls it. */\n dispose(): void {\n release(this);\n this._dirty = false;\n }\n}\n\nclass Effect implements Tracker {\n _deps = new Map<Signal<any>, number>();\n _queued = false;\n _dead = false;\n _kids = new Set<Effect>();\n declare _fn: () => void;\n declare _onError?: (e: unknown) => void;\n constructor(fn: () => void, onError?: (e: unknown) => void) {\n this._fn = fn;\n this._onError = onError;\n }\n _invalidate(): void {\n if (!this._dead && !this._queued) {\n this._queued = true;\n queue.add(this);\n }\n }\n _exec(): void {\n this._queued = false;\n if (this._dead) return;\n const prevOwner = owner;\n owner = this;\n depth++;\n try {\n // `stale` refreshes computeds, which may throw: that belongs to this effect's error handling.\n if (stale(this)) {\n this._drop();\n capture(this, this._fn);\n }\n } catch (e) {\n if (!this._onError) throw e;\n this._onError(e);\n } finally {\n depth--;\n owner = prevOwner;\n }\n }\n _drop(): void {\n for (const c of this._kids) c._dispose();\n this._kids.clear();\n }\n _dispose(): void {\n this._dead = true;\n release(this);\n if (active === this) active = undefined; // disposed from inside its own run: stop subscribing\n this._drop();\n queue.delete(this);\n }\n}\n\nexport const signal = <T>(value: T): Signal<T> => new Signal(value);\nexport const computed = <T>(fn: () => T): Computed<T> => new Computed(fn);\n\n/**\n * Run `fn` now and again whenever a signal it read changes. Effects created inside another\n * effect are disposed when the parent re-runs. Returns a disposer.\n */\nexport const effect = (fn: () => void, onError?: (e: unknown) => void): (() => void) => {\n const e = new Effect(fn, onError);\n owner?._kids.add(e);\n try {\n e._exec();\n depth || flush();\n } catch (err) {\n e._dispose(); // a first run that throws (or loops) without a handler leaves nothing subscribed\n throw err;\n }\n return () => e._dispose();\n};\n\n/**\n * Like `effect`, but never owned by the effect that happens to be running: for long-lived effects\n * such as mounted attributes, which must not die when an unrelated parent effect re-runs.\n */\nexport const rootEffect = (fn: () => void, onError?: (e: unknown) => void): (() => void) => {\n const prev = owner;\n owner = undefined;\n try {\n return effect(fn, onError);\n } finally {\n owner = prev;\n }\n};\n\nexport const batch = <R>(fn: () => R): R => {\n depth++;\n try {\n return fn();\n } finally {\n --depth || flush();\n }\n};\n\nexport const untracked = <R>(fn: () => R): R => {\n const prev = active;\n active = undefined;\n try {\n return fn();\n } finally {\n active = prev;\n }\n};\n\nexport const onSettled = (fn: () => void): (() => void) => {\n settled.add(fn);\n return () => settled.delete(fn);\n};\n\nexport const flush = (): void => {\n if (flushing || depth) return;\n flushing = true;\n let thrown: unknown;\n let failed = false;\n try {\n let guard = 0;\n while (queue.size) {\n if (++guard > 1e5) {\n // Leave nothing behind, or every later flush would trip the same guard; the effects stay\n // subscribed and run again on their next change.\n for (const e of queue) e._queued = false;\n queue.clear();\n throw new Error('effect loop');\n }\n const e = queue.values().next().value as Effect;\n queue.delete(e);\n try {\n e._exec();\n } catch (err) {\n // One throwing effect (no onError) must not starve the others; rethrow after the flush.\n if (!failed) {\n failed = true;\n thrown = err;\n }\n }\n }\n } finally {\n flushing = false;\n }\n for (const fn of settled) fn();\n if (failed) throw thrown;\n};\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["_ver", "_subs", "_v", "_deps", "_invalidate", "_refresh", "_dirty", "_fn", "_queued", "_dead", "_kids", "_onError", "_exec", "_drop", "_dispose", "e"]
|
|
7
7
|
}
|
package/dist/kernel/runtime.js
CHANGED
|
@@ -1,66 +1,59 @@
|
|
|
1
|
+
import { recase } from "../lib/casing.js";
|
|
1
2
|
import { functionCompiler } from "./compile.js";
|
|
2
|
-
import {
|
|
3
|
+
import { rootEffect } from "./reactive.js";
|
|
3
4
|
import { createStore } from "./state.js";
|
|
4
|
-
|
|
5
|
-
const
|
|
6
|
-
const tree = (n) => isEl(n) ? [n, ...n.querySelectorAll("*")] : n instanceof ShadowRoot ? [...n.querySelectorAll("*")] : [];
|
|
7
|
-
const parsed = /* @__PURE__ */ new Map();
|
|
5
|
+
const isEl = (n) => n.nodeType === 1;
|
|
6
|
+
const tree = (n) => n.querySelectorAll ? [...isEl(n) ? [n] : [], ...n.querySelectorAll("*")] : [];
|
|
8
7
|
const parseAttr = (raw) => {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
}
|
|
21
|
-
|
|
8
|
+
const [head, ...modParts] = raw.split("__");
|
|
9
|
+
const [, plugin, key] = /^([^:]*)(?::(.*))?$/.exec(head);
|
|
10
|
+
return {
|
|
11
|
+
plugin,
|
|
12
|
+
key,
|
|
13
|
+
mods: new Map(
|
|
14
|
+
modParts.map((m) => {
|
|
15
|
+
const [name, ...args] = m.split(".");
|
|
16
|
+
return [name, args];
|
|
17
|
+
})
|
|
18
|
+
)
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
const cut = (list, s) => {
|
|
22
|
+
for (const p of list) if (s.startsWith(p)) return s.slice(p.length);
|
|
22
23
|
};
|
|
23
|
-
const fail = (message, info) => Object.assign(new Error(message), { info });
|
|
24
24
|
const createRuntime = (options) => {
|
|
25
25
|
const prefixes = [].concat(options.prefix ?? "data-");
|
|
26
26
|
const eventPrefixes = [].concat(options.eventPrefix ?? "sigmx-");
|
|
27
27
|
const store = options.store ?? createStore();
|
|
28
|
-
const compiler = options.compile ?? functionCompiler;
|
|
29
28
|
const { expressions } = options;
|
|
30
29
|
const onError = options.onError ?? ((e, info) => console.error(e, info));
|
|
31
30
|
const attributes = /* @__PURE__ */ Object.create(null);
|
|
32
|
-
const actions = /* @__PURE__ */ Object.create(null);
|
|
33
|
-
const handlers = /* @__PURE__ */ Object.create(null);
|
|
34
31
|
const runtime = {
|
|
35
32
|
prefixes,
|
|
36
33
|
attr: (name) => prefixes[0] + name,
|
|
37
34
|
store,
|
|
38
|
-
compiler,
|
|
35
|
+
compiler: options.compile ?? functionCompiler,
|
|
39
36
|
emit: (type, detail) => document.dispatchEvent(new CustomEvent(`sigmx-${type}`, { detail })),
|
|
40
37
|
call: (name, ctx, args) => {
|
|
41
|
-
const a = actions[name];
|
|
38
|
+
const a = runtime.actions[name];
|
|
42
39
|
if (!a) throw ctx.error(`unknown action @${name}`);
|
|
43
40
|
return a.call(ctx, ...args);
|
|
44
41
|
},
|
|
45
42
|
eventPrefixes,
|
|
46
43
|
handle: (event, data) => {
|
|
47
|
-
const
|
|
48
|
-
const h = handlers[p ? event.slice(p.length) : event];
|
|
44
|
+
const h = runtime.handlers[cut(eventPrefixes, event) ?? event];
|
|
49
45
|
h?.handle(runtime, data);
|
|
50
46
|
return !!h;
|
|
51
47
|
},
|
|
52
48
|
attributes,
|
|
53
|
-
actions,
|
|
54
|
-
handlers
|
|
49
|
+
actions: /* @__PURE__ */ Object.create(null),
|
|
50
|
+
handlers: /* @__PURE__ */ Object.create(null)
|
|
55
51
|
};
|
|
56
52
|
const mounted = /* @__PURE__ */ new Map();
|
|
57
53
|
const roots = /* @__PURE__ */ new Set();
|
|
58
|
-
const ignoreSelf = prefixes.map((p) => `[${p}ignore__self]`).join();
|
|
59
54
|
const ignoreAny = prefixes.map((p) => `[${p}ignore]`).join();
|
|
60
|
-
const ignored = (el) =>
|
|
61
|
-
|
|
62
|
-
for (const p of prefixes) if (attr.startsWith(p)) return attr.slice(p.length);
|
|
63
|
-
};
|
|
55
|
+
const ignored = (el) => !!el.closest(ignoreAny);
|
|
56
|
+
let destroyed = false;
|
|
64
57
|
const unmount = (els) => {
|
|
65
58
|
for (const el of els) {
|
|
66
59
|
const m = mounted.get(el);
|
|
@@ -72,20 +65,30 @@ const createRuntime = (options) => {
|
|
|
72
65
|
m?.get(attr)?.();
|
|
73
66
|
m?.delete(attr);
|
|
74
67
|
};
|
|
75
|
-
const actionsFor = (el, evt, error, cleanup) => {
|
|
76
|
-
const ctx = { el, evt, store, runtime, error, cleanup };
|
|
77
|
-
return new Proxy({}, { get: (_, name) => (...args) => runtime.call(name, ctx, args) });
|
|
78
|
-
};
|
|
79
68
|
const mount = (el, attr, raw, value, only) => {
|
|
80
69
|
const { plugin: name, key, mods } = parseAttr(raw);
|
|
81
70
|
const plugin = attributes[name];
|
|
82
71
|
if (!plugin || only && !only.has(name)) return;
|
|
83
72
|
unmountAttr(el, attr);
|
|
84
73
|
const disposers = [];
|
|
74
|
+
const cleanup = (f) => {
|
|
75
|
+
disposers.push(f);
|
|
76
|
+
return () => {
|
|
77
|
+
const i = disposers.indexOf(f);
|
|
78
|
+
if (i >= 0) disposers.splice(i, 1);
|
|
79
|
+
};
|
|
80
|
+
};
|
|
85
81
|
const info = { plugin: name, el, attr };
|
|
86
|
-
const error = (message, extra) =>
|
|
82
|
+
const error = (message, extra) => Object.assign(new Error(`${prefixes[0]}${name}: ${message}`), { info: { ...info, ...extra } });
|
|
87
83
|
const report = (e) => onError(e, info);
|
|
88
84
|
let fn;
|
|
85
|
+
const watched = /* @__PURE__ */ new WeakSet();
|
|
86
|
+
const watch = (r) => {
|
|
87
|
+
if (r instanceof Promise && !watched.has(r)) {
|
|
88
|
+
watched.add(r);
|
|
89
|
+
r.catch(report);
|
|
90
|
+
}
|
|
91
|
+
};
|
|
89
92
|
const ctx = {
|
|
90
93
|
el,
|
|
91
94
|
plugin: name,
|
|
@@ -95,10 +98,27 @@ const createRuntime = (options) => {
|
|
|
95
98
|
mods,
|
|
96
99
|
cased: (style = "camel") => recase(key ?? "", mods.get("case")?.[0] || style),
|
|
97
100
|
evaluate: (evt, ...args) => {
|
|
98
|
-
|
|
99
|
-
|
|
101
|
+
if (plugin.literal && !mods.has("dynamic")) return value;
|
|
102
|
+
fn ??= expressions(value, ["el", "evt", ...plugin.args ?? []]);
|
|
103
|
+
const actx = { el, evt, store, runtime, error, cleanup, report };
|
|
104
|
+
const actions = new Proxy(
|
|
105
|
+
{},
|
|
106
|
+
{
|
|
107
|
+
get: (_, name2) => (...args2) => {
|
|
108
|
+
const r2 = runtime.call(name2, actx, args2);
|
|
109
|
+
watch(r2);
|
|
110
|
+
return r2;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
);
|
|
114
|
+
const r = fn(store, actions, el, evt, ...args);
|
|
115
|
+
watch(r);
|
|
116
|
+
return r;
|
|
117
|
+
},
|
|
118
|
+
// Root-owned: an attribute mounted from inside another effect must outlive that effect's re-runs.
|
|
119
|
+
effect: (f) => {
|
|
120
|
+
cleanup(rootEffect(f, report));
|
|
100
121
|
},
|
|
101
|
-
effect: (f) => disposers.push(effect(f, report)),
|
|
102
122
|
listen: (target, type, f, opts) => {
|
|
103
123
|
const h = (e) => {
|
|
104
124
|
try {
|
|
@@ -108,25 +128,33 @@ const createRuntime = (options) => {
|
|
|
108
128
|
}
|
|
109
129
|
};
|
|
110
130
|
target.addEventListener(type, h, opts);
|
|
111
|
-
|
|
131
|
+
cleanup(() => target.removeEventListener(type, h, opts));
|
|
112
132
|
},
|
|
113
|
-
cleanup
|
|
133
|
+
cleanup,
|
|
114
134
|
error,
|
|
135
|
+
report,
|
|
115
136
|
store,
|
|
116
137
|
runtime
|
|
117
138
|
};
|
|
118
139
|
let m = mounted.get(el);
|
|
119
|
-
if (!m)
|
|
140
|
+
if (!m) {
|
|
141
|
+
m = /* @__PURE__ */ new Map();
|
|
142
|
+
mounted.set(el, m);
|
|
143
|
+
}
|
|
120
144
|
m.set(attr, () => {
|
|
121
145
|
for (const d of disposers.splice(0)) d();
|
|
122
146
|
});
|
|
123
147
|
try {
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
148
|
+
for (const [k, v] of [
|
|
149
|
+
["key", key],
|
|
150
|
+
["value", value]
|
|
151
|
+
]) {
|
|
152
|
+
const rule = plugin[k];
|
|
153
|
+
if (rule && rule === "required" === !v) throw error(`${rule === "required" ? "needs a" : "takes no"} ${k}`);
|
|
154
|
+
}
|
|
128
155
|
const r = plugin.mount(ctx);
|
|
129
|
-
if (typeof r === "function")
|
|
156
|
+
if (typeof r === "function") cleanup(r);
|
|
157
|
+
else watch(r);
|
|
130
158
|
} catch (e) {
|
|
131
159
|
report(e);
|
|
132
160
|
}
|
|
@@ -135,18 +163,18 @@ const createRuntime = (options) => {
|
|
|
135
163
|
for (const el of els) {
|
|
136
164
|
if (ignored(el)) continue;
|
|
137
165
|
for (const { name, value } of [...el.attributes]) {
|
|
138
|
-
const raw =
|
|
139
|
-
if (raw) mount(el, name, raw, value, only);
|
|
166
|
+
const raw = cut(prefixes, name);
|
|
167
|
+
if (raw && !mounted.get(el)?.has(name)) mount(el, name, raw, value, only);
|
|
140
168
|
}
|
|
141
169
|
}
|
|
142
170
|
};
|
|
143
171
|
const observer = new MutationObserver((records) => {
|
|
144
172
|
for (const { type, target, attributeName, addedNodes, removedNodes } of records) {
|
|
145
173
|
if (type === "childList") {
|
|
146
|
-
for (const n of removedNodes) unmount(tree(n));
|
|
174
|
+
for (const n of removedNodes) if (!n.isConnected) unmount(tree(n));
|
|
147
175
|
for (const n of addedNodes) mountEls(tree(n));
|
|
148
176
|
} else if (attributeName && isEl(target) && !ignored(target)) {
|
|
149
|
-
const raw =
|
|
177
|
+
const raw = cut(prefixes, attributeName);
|
|
150
178
|
if (!raw) continue;
|
|
151
179
|
const value = target.getAttribute(attributeName);
|
|
152
180
|
if (value === null) unmountAttr(target, attributeName);
|
|
@@ -154,26 +182,19 @@ const createRuntime = (options) => {
|
|
|
154
182
|
}
|
|
155
183
|
}
|
|
156
184
|
});
|
|
157
|
-
let ready = false;
|
|
158
185
|
const apply = (root = document.documentElement, observe = true, only) => {
|
|
186
|
+
if (destroyed) return;
|
|
159
187
|
mountEls(tree(root), only);
|
|
160
188
|
if (observe && !roots.has(root)) {
|
|
161
189
|
observer.observe(root, { subtree: true, childList: true, attributes: true });
|
|
162
190
|
roots.add(root);
|
|
163
191
|
}
|
|
164
|
-
if (!ready && roots.has(document.documentElement)) {
|
|
165
|
-
ready = true;
|
|
166
|
-
runtime.emit("ready");
|
|
167
|
-
}
|
|
168
192
|
};
|
|
169
193
|
const use = (...plugins) => {
|
|
170
194
|
const added = /* @__PURE__ */ new Set();
|
|
171
195
|
for (const p of plugins) {
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
added.add(p.name);
|
|
175
|
-
} else if (p.type === "action") actions[p.name] = p;
|
|
176
|
-
else handlers[p.name] = p;
|
|
196
|
+
runtime[`${p.type}s`][p.name] = p;
|
|
197
|
+
if (p.type === "attribute") added.add(p.name);
|
|
177
198
|
}
|
|
178
199
|
if (added.size) for (const r of roots) apply(r, false, added);
|
|
179
200
|
};
|
|
@@ -188,6 +209,7 @@ const createRuntime = (options) => {
|
|
|
188
209
|
apply: (root, observe) => apply(root, observe),
|
|
189
210
|
use,
|
|
190
211
|
destroy: () => {
|
|
212
|
+
destroyed = true;
|
|
191
213
|
observer.disconnect();
|
|
192
214
|
stopPatches();
|
|
193
215
|
unmount([...mounted.keys()]);
|