@fluixi/reactive 1.0.0-alpha.82 → 1.0.0-alpha.84
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 +4 -0
- package/dist/cdn/reactive.cjs +2673 -1
- package/dist/cdn/reactive.global.js +2 -1
- package/dist/cdn/reactive.mjs +2657 -1
- package/dist/cdn/signal.cjs +299 -1
- package/dist/cdn/signal.d.ts +1 -1
- package/dist/cdn/signal.global.js +2 -1
- package/dist/cdn/signal.js +1 -1
- package/dist/cdn/signal.mjs +276 -1
- package/dist/index.cjs +2673 -1
- package/dist/index.mjs +2657 -1
- package/dist/lib/index.cjs +2674 -1
- package/dist/lib/index.js +1 -1
- package/dist/lib/index.mjs +2659 -1
- package/dist/lib/observable/index.cjs +386 -1
- package/dist/lib/observable/index.mjs +364 -1
- package/dist/lib/observable/observable.cjs +384 -1
- package/dist/lib/observable/observable.d.ts +0 -137
- package/dist/lib/observable/observable.d.ts.map +1 -1
- package/dist/lib/observable/observable.js +0 -71
- package/dist/lib/observable/observable.mjs +361 -1
- package/dist/lib/observable/subscription.cjs +180 -1
- package/dist/lib/observable/subscription.d.ts +0 -12
- package/dist/lib/observable/subscription.d.ts.map +1 -1
- package/dist/lib/observable/subscription.js +0 -12
- package/dist/lib/observable/subscription.mjs +157 -1
- package/dist/lib/observable/types.cjs +18 -1
- package/dist/lib/observable/types.d.ts.map +1 -1
- package/dist/lib/predicates.cjs +44 -1
- package/dist/lib/predicates.d.ts +2 -2
- package/dist/lib/predicates.js +2 -2
- package/dist/lib/predicates.mjs +23 -1
- package/dist/lib/signal/api.cjs +571 -1
- package/dist/lib/signal/api.d.ts +211 -1
- package/dist/lib/signal/api.d.ts.map +1 -1
- package/dist/lib/signal/api.js +207 -12
- package/dist/lib/signal/api.mjs +548 -1
- package/dist/lib/signal/cached-resource.cjs +672 -1
- package/dist/lib/signal/cached-resource.d.ts +28 -16
- package/dist/lib/signal/cached-resource.d.ts.map +1 -1
- package/dist/lib/signal/cached-resource.js +35 -29
- package/dist/lib/signal/cached-resource.mjs +650 -1
- package/dist/lib/signal/graph/children.cjs +325 -1
- package/dist/lib/signal/graph/children.js +1 -1
- package/dist/lib/signal/graph/children.mjs +302 -1
- package/dist/lib/signal/graph/compat.cjs +578 -1
- package/dist/lib/signal/graph/compat.d.ts +13 -13
- package/dist/lib/signal/graph/compat.d.ts.map +1 -1
- package/dist/lib/signal/graph/compat.js +51 -32
- package/dist/lib/signal/graph/compat.mjs +556 -1
- package/dist/lib/signal/graph/core.cjs +295 -1
- package/dist/lib/signal/graph/core.d.ts +28 -24
- package/dist/lib/signal/graph/core.d.ts.map +1 -1
- package/dist/lib/signal/graph/core.js +45 -31
- package/dist/lib/signal/graph/core.mjs +273 -1
- package/dist/lib/signal/graph/debounced.cjs +668 -1
- package/dist/lib/signal/graph/debounced.d.ts +5 -5
- package/dist/lib/signal/graph/debounced.d.ts.map +1 -1
- package/dist/lib/signal/graph/debounced.js +5 -5
- package/dist/lib/signal/graph/debounced.mjs +645 -1
- package/dist/lib/signal/graph/derived.cjs +496 -1
- package/dist/lib/signal/graph/derived.d.ts +1 -1
- package/dist/lib/signal/graph/derived.js +1 -1
- package/dist/lib/signal/graph/derived.mjs +473 -1
- package/dist/lib/signal/graph/detect.cjs +66 -1
- package/dist/lib/signal/graph/detect.mjs +45 -1
- package/dist/lib/signal/graph/error-boundary.cjs +301 -1
- package/dist/lib/signal/graph/error-boundary.js +3 -3
- package/dist/lib/signal/graph/error-boundary.mjs +278 -1
- package/dist/lib/signal/graph/index.cjs +305 -1
- package/dist/lib/signal/graph/index.d.ts +7 -6
- package/dist/lib/signal/graph/index.d.ts.map +1 -1
- package/dist/lib/signal/graph/index.js +7 -6
- package/dist/lib/signal/graph/index.mjs +283 -1
- package/dist/lib/signal/graph/observe.cjs +163 -0
- package/dist/lib/signal/graph/observe.d.ts +141 -0
- package/dist/lib/signal/graph/observe.d.ts.map +1 -0
- package/dist/lib/signal/graph/observe.js +149 -0
- package/dist/lib/signal/graph/observe.mjs +140 -0
- package/dist/lib/signal/graph/resource.cjs +620 -1
- package/dist/lib/signal/graph/resource.d.ts +1 -1
- package/dist/lib/signal/graph/resource.js +7 -8
- package/dist/lib/signal/graph/resource.mjs +597 -1
- package/dist/lib/signal/graph/runtime.cjs +501 -1
- package/dist/lib/signal/graph/runtime.d.ts +9 -9
- package/dist/lib/signal/graph/runtime.d.ts.map +1 -1
- package/dist/lib/signal/graph/runtime.js +56 -37
- package/dist/lib/signal/graph/runtime.mjs +478 -1
- package/dist/lib/signal/graph/signal-next.cjs +1208 -1
- package/dist/lib/signal/graph/signal-next.d.ts +5 -5
- package/dist/lib/signal/graph/signal-next.d.ts.map +1 -1
- package/dist/lib/signal/graph/signal-next.js +14 -12
- package/dist/lib/signal/graph/signal-next.mjs +1186 -1
- package/dist/lib/signal/graph/ssr-hooks.cjs +60 -1
- package/dist/lib/signal/graph/ssr-hooks.d.ts +6 -7
- package/dist/lib/signal/graph/ssr-hooks.d.ts.map +1 -1
- package/dist/lib/signal/graph/ssr-hooks.js +6 -7
- package/dist/lib/signal/graph/ssr-hooks.mjs +39 -1
- package/dist/lib/signal/graph/state.cjs +72 -1
- package/dist/lib/signal/graph/state.d.ts +43 -10
- package/dist/lib/signal/graph/state.d.ts.map +1 -1
- package/dist/lib/signal/graph/state.js +83 -21
- package/dist/lib/signal/graph/state.mjs +49 -1
- package/dist/lib/signal/graph/suspense.cjs +301 -1
- package/dist/lib/signal/graph/suspense.js +4 -4
- package/dist/lib/signal/graph/suspense.mjs +278 -1
- package/dist/lib/signal/index-legacy.cjs +2540 -1
- package/dist/lib/signal/index-legacy.d.ts +1 -1
- package/dist/lib/signal/index-legacy.js +1 -1
- package/dist/lib/signal/index-legacy.mjs +2518 -1
- package/dist/lib/signal/index.cjs +1275 -1
- package/dist/lib/signal/index.d.ts +5 -2
- package/dist/lib/signal/index.d.ts.map +1 -1
- package/dist/lib/signal/index.js +8 -3
- package/dist/lib/signal/index.mjs +1253 -1
- package/dist/lib/signal/list.cjs +549 -1
- package/dist/lib/signal/list.d.ts +5 -5
- package/dist/lib/signal/list.js +10 -10
- package/dist/lib/signal/list.mjs +526 -1
- package/dist/lib/signal/resource-api.cjs +626 -1
- package/dist/lib/signal/resource-api.d.ts +5 -5
- package/dist/lib/signal/resource-api.js +5 -5
- package/dist/lib/signal/resource-api.mjs +603 -1
- package/dist/lib/signal/signal.cjs +2023 -1
- package/dist/lib/signal/signal.d.ts +4 -4
- package/dist/lib/signal/signal.d.ts.map +1 -1
- package/dist/lib/signal/signal.js +22 -23
- package/dist/lib/signal/signal.mjs +2000 -1
- package/dist/lib/signal/types.cjs +38 -1
- package/dist/lib/signal/types.d.ts.map +1 -1
- package/dist/lib/signal/types.js +2 -2
- package/dist/lib/signal/types.mjs +17 -1
- package/dist/lib/signal/utilities.cjs +1012 -1
- package/dist/lib/signal/utilities.d.ts +0 -108
- package/dist/lib/signal/utilities.d.ts.map +1 -1
- package/dist/lib/signal/utilities.js +0 -158
- package/dist/lib/signal/utilities.mjs +990 -1
- package/dist/lib/store/api.cjs +612 -1
- package/dist/lib/store/api.d.ts +33 -0
- package/dist/lib/store/api.d.ts.map +1 -1
- package/dist/lib/store/api.js +41 -8
- package/dist/lib/store/api.mjs +596 -1
- package/dist/lib/store/index.cjs +691 -1
- package/dist/lib/store/index.js +1 -1
- package/dist/lib/store/index.mjs +676 -1
- package/dist/lib/store/setter.types.cjs +18 -1
- package/dist/lib/store/setter.types.d.ts +43 -3
- package/dist/lib/store/setter.types.d.ts.map +1 -1
- package/dist/lib/store/store.cjs +658 -1
- package/dist/lib/store/store.d.ts +72 -0
- package/dist/lib/store/store.d.ts.map +1 -1
- package/dist/lib/store/store.js +294 -11
- package/dist/lib/store/store.mjs +644 -1
- package/dist/lib/store/types.cjs +18 -1
- package/dist/lib/store/types.d.ts +1 -1
- package/dist/lib/store/types.d.ts.map +1 -1
- package/dist/lib/store/utils.cjs +43 -1
- package/dist/lib/store/utils.d.ts +1 -1
- package/dist/lib/store/utils.js +1 -1
- package/dist/lib/store/utils.mjs +22 -1
- package/dist/lib/subject.cjs +450 -1
- package/dist/lib/subject.js +3 -91
- package/dist/lib/subject.mjs +427 -1
- package/dist/tsconfig.lib.tsbuildinfo +1 -1
- package/dist/version.generated.cjs +27 -1
- package/dist/version.generated.d.ts +1 -1
- package/dist/version.generated.js +2 -2
- package/dist/version.generated.mjs +7 -1
- package/package.json +5 -4
package/dist/lib/signal/list.cjs
CHANGED
|
@@ -1 +1,549 @@
|
|
|
1
|
-
"use strict";
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/lib/signal/list.ts
|
|
21
|
+
var list_exports = {};
|
|
22
|
+
__export(list_exports, {
|
|
23
|
+
indexArray: () => indexArray,
|
|
24
|
+
keyArray: () => keyArray,
|
|
25
|
+
mapArray: () => mapArray
|
|
26
|
+
});
|
|
27
|
+
module.exports = __toCommonJS(list_exports);
|
|
28
|
+
|
|
29
|
+
// src/version.generated.ts
|
|
30
|
+
var VERSION = "1.0.0-alpha.84";
|
|
31
|
+
|
|
32
|
+
// src/lib/signal/graph/state.ts
|
|
33
|
+
var MAJOR = VERSION.split(".")[0];
|
|
34
|
+
var KEY = `__fluixi_signal_state_v${MAJOR}__`;
|
|
35
|
+
var VERSIONS_KEY = `__fluixi_signal_builds_v${MAJOR}__`;
|
|
36
|
+
var defaultSchedule = (run) => {
|
|
37
|
+
if (typeof queueMicrotask === "function") queueMicrotask(run);
|
|
38
|
+
else void Promise.resolve().then(run);
|
|
39
|
+
};
|
|
40
|
+
function defaults() {
|
|
41
|
+
return {
|
|
42
|
+
consumer: null,
|
|
43
|
+
untracked: false,
|
|
44
|
+
owner: null,
|
|
45
|
+
queue: [],
|
|
46
|
+
scheduled: false,
|
|
47
|
+
flushing: false,
|
|
48
|
+
batchDepth: 0,
|
|
49
|
+
hostSchedule: defaultSchedule,
|
|
50
|
+
onSuspend: null,
|
|
51
|
+
onError: null,
|
|
52
|
+
observer: null
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
var realm = globalThis;
|
|
56
|
+
function backfillState(existing) {
|
|
57
|
+
const fresh = defaults();
|
|
58
|
+
const target = existing;
|
|
59
|
+
for (const field of Object.keys(fresh)) {
|
|
60
|
+
if (!(field in existing)) target[field] = fresh[field];
|
|
61
|
+
}
|
|
62
|
+
return existing;
|
|
63
|
+
}
|
|
64
|
+
function claim() {
|
|
65
|
+
const existing = realm[KEY];
|
|
66
|
+
return existing ? backfillState(existing) : realm[KEY] = defaults();
|
|
67
|
+
}
|
|
68
|
+
var G = claim();
|
|
69
|
+
(realm[VERSIONS_KEY] ??= []).push(VERSION);
|
|
70
|
+
|
|
71
|
+
// src/lib/signal/graph/observe.ts
|
|
72
|
+
function observeReactiveNodes(next) {
|
|
73
|
+
G.observer = next;
|
|
74
|
+
return () => {
|
|
75
|
+
if (G.observer === next) G.observer = null;
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
var running = [];
|
|
79
|
+
var origin;
|
|
80
|
+
function reportReactiveNode(report) {
|
|
81
|
+
const observer = G.observer;
|
|
82
|
+
if (observer) {
|
|
83
|
+
observer.created(
|
|
84
|
+
report.parents === void 0 ? { ...report, parents: running, origin: report.origin ?? origin } : report
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
function enterReactiveRun(node) {
|
|
89
|
+
if (!G.observer) return false;
|
|
90
|
+
running.push(node);
|
|
91
|
+
return true;
|
|
92
|
+
}
|
|
93
|
+
function exitReactiveRun() {
|
|
94
|
+
running.pop();
|
|
95
|
+
}
|
|
96
|
+
function reportReactiveRun(node) {
|
|
97
|
+
G.observer?.ran?.(node);
|
|
98
|
+
}
|
|
99
|
+
function reportReactiveWrite(node, by) {
|
|
100
|
+
G.observer?.wrote?.(node, by);
|
|
101
|
+
}
|
|
102
|
+
function reportReactiveDispose(node) {
|
|
103
|
+
G.observer?.disposed?.(node);
|
|
104
|
+
}
|
|
105
|
+
var HOOK = "__FLUIXI_DEVTOOLS_HOOK__";
|
|
106
|
+
var hook = globalThis[HOOK];
|
|
107
|
+
if (typeof hook?.inject === "function") {
|
|
108
|
+
try {
|
|
109
|
+
hook.inject({ observeReactiveNodes, version: VERSION });
|
|
110
|
+
} catch {
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
function isObserved() {
|
|
114
|
+
return G.observer != null;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// src/lib/signal/graph/core.ts
|
|
118
|
+
var CLEAN = 0;
|
|
119
|
+
var CHECK = 1;
|
|
120
|
+
var DIRTY = 2;
|
|
121
|
+
var Source = class {
|
|
122
|
+
constructor() {
|
|
123
|
+
/** Computeds, and watched leaves, that read this node. */
|
|
124
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
125
|
+
this.observers = null;
|
|
126
|
+
/** Watchers eagerly observing this node, which is how `runtime.ts` schedules effects. */
|
|
127
|
+
this.watchers = null;
|
|
128
|
+
/** Bumped whenever this node's value actually changes (equality-gated). */
|
|
129
|
+
this.version = 0;
|
|
130
|
+
}
|
|
131
|
+
/** Settle this node so a reader sees a current value/version. Overridden by Computed. */
|
|
132
|
+
updateIfNecessary() {
|
|
133
|
+
}
|
|
134
|
+
/** Link the current consumer (if any) as an observer of this node. */
|
|
135
|
+
track() {
|
|
136
|
+
if (G.untracked) return;
|
|
137
|
+
const consumer = G.consumer;
|
|
138
|
+
if (!consumer) return;
|
|
139
|
+
(this.observers ??= /* @__PURE__ */ new Set()).add(consumer);
|
|
140
|
+
(consumer.sources ??= /* @__PURE__ */ new Set()).add(this);
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
var State = class extends Source {
|
|
144
|
+
constructor(value, options) {
|
|
145
|
+
super();
|
|
146
|
+
this._value = value;
|
|
147
|
+
this._equals = options?.equals === false ? () => false : options?.equals ?? Object.is;
|
|
148
|
+
}
|
|
149
|
+
get() {
|
|
150
|
+
this.track();
|
|
151
|
+
return this._value;
|
|
152
|
+
}
|
|
153
|
+
set(next) {
|
|
154
|
+
if (this._equals(this._value, next)) return;
|
|
155
|
+
this._value = next;
|
|
156
|
+
this.version++;
|
|
157
|
+
reportReactiveWrite(this, G.consumer);
|
|
158
|
+
if (this.observers) for (const o of [...this.observers]) o.markDirty(DIRTY);
|
|
159
|
+
notifyWatchers(this);
|
|
160
|
+
}
|
|
161
|
+
/** Read without subscribing (peek). */
|
|
162
|
+
peek() {
|
|
163
|
+
return this._value;
|
|
164
|
+
}
|
|
165
|
+
};
|
|
166
|
+
var Computed = class extends Source {
|
|
167
|
+
constructor(fn, options) {
|
|
168
|
+
super();
|
|
169
|
+
this._threw = false;
|
|
170
|
+
this._initialized = false;
|
|
171
|
+
this.state = DIRTY;
|
|
172
|
+
/** Nodes this computation read on its last run. Rebuilt on every run. */
|
|
173
|
+
this.sources = null;
|
|
174
|
+
this._fn = fn;
|
|
175
|
+
this._equals = options?.equals === false ? () => false : options?.equals ?? Object.is;
|
|
176
|
+
}
|
|
177
|
+
get() {
|
|
178
|
+
if (G.consumer === this) {
|
|
179
|
+
throw new Error("Signal.Computed cannot read itself");
|
|
180
|
+
}
|
|
181
|
+
this.track();
|
|
182
|
+
this.updateIfNecessary();
|
|
183
|
+
if (this._threw) throw this._error;
|
|
184
|
+
return this._value;
|
|
185
|
+
}
|
|
186
|
+
/** Settle, if CHECK, verify sources; if DIRTY (or never run), recompute. */
|
|
187
|
+
updateIfNecessary() {
|
|
188
|
+
if (this.state === CHECK) {
|
|
189
|
+
if (this.sources) {
|
|
190
|
+
for (const s of this.sources) {
|
|
191
|
+
s.updateIfNecessary();
|
|
192
|
+
if (this.state === DIRTY) break;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
if (this.state === DIRTY || !this._initialized) this.recompute();
|
|
197
|
+
this.state = CLEAN;
|
|
198
|
+
}
|
|
199
|
+
recompute() {
|
|
200
|
+
if (this.sources) {
|
|
201
|
+
for (const s of this.sources) s.observers?.delete(this);
|
|
202
|
+
this.sources.clear();
|
|
203
|
+
}
|
|
204
|
+
const prevConsumer = G.consumer;
|
|
205
|
+
const prevUntracked = G.untracked;
|
|
206
|
+
const watched = enterReactiveRun(this);
|
|
207
|
+
G.consumer = this;
|
|
208
|
+
G.untracked = false;
|
|
209
|
+
let next;
|
|
210
|
+
let threw = false;
|
|
211
|
+
let err;
|
|
212
|
+
try {
|
|
213
|
+
next = this._fn();
|
|
214
|
+
} catch (e) {
|
|
215
|
+
threw = true;
|
|
216
|
+
err = e;
|
|
217
|
+
next = this._value;
|
|
218
|
+
} finally {
|
|
219
|
+
G.consumer = prevConsumer;
|
|
220
|
+
G.untracked = prevUntracked;
|
|
221
|
+
if (watched) exitReactiveRun();
|
|
222
|
+
}
|
|
223
|
+
const changed = !this._initialized || this._threw !== threw || (threw ? err !== this._error : !this._equals(this._value, next));
|
|
224
|
+
this._initialized = true;
|
|
225
|
+
this._threw = threw;
|
|
226
|
+
this._error = err;
|
|
227
|
+
this._value = next;
|
|
228
|
+
reportReactiveRun(this);
|
|
229
|
+
if (changed) {
|
|
230
|
+
this.version++;
|
|
231
|
+
if (this.observers) for (const o of [...this.observers]) o.markDirty(DIRTY);
|
|
232
|
+
notifyWatchers(this);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Push a maybe-dirty mark. A direct observer of a changed node gets DIRTY; its
|
|
237
|
+
* own observers get CHECK (recurse), stopping where already marked, so the
|
|
238
|
+
* push is O(newly-dirtied) and never recomputes.
|
|
239
|
+
*/
|
|
240
|
+
markDirty(level) {
|
|
241
|
+
if (this.state >= level) return;
|
|
242
|
+
const wasClean = this.state === CLEAN;
|
|
243
|
+
this.state = level;
|
|
244
|
+
if (wasClean) {
|
|
245
|
+
if (this.observers) for (const o of [...this.observers]) o.markDirty(CHECK);
|
|
246
|
+
notifyWatchers(this);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
peek() {
|
|
250
|
+
this.updateIfNecessary();
|
|
251
|
+
if (this._threw) throw this._error;
|
|
252
|
+
return this._value;
|
|
253
|
+
}
|
|
254
|
+
};
|
|
255
|
+
function notifyWatchers(node) {
|
|
256
|
+
if (!node.watchers) return;
|
|
257
|
+
for (const w of [...node.watchers]) w._notify(node);
|
|
258
|
+
}
|
|
259
|
+
function untrack(fn) {
|
|
260
|
+
if (G.untracked) return fn();
|
|
261
|
+
G.untracked = true;
|
|
262
|
+
try {
|
|
263
|
+
return fn();
|
|
264
|
+
} finally {
|
|
265
|
+
G.untracked = false;
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
// src/lib/signal/graph/runtime.ts
|
|
270
|
+
function makeOwner(parent) {
|
|
271
|
+
return { cleanups: null, owned: null, parent, contexts: null };
|
|
272
|
+
}
|
|
273
|
+
function reportSuspend(promise) {
|
|
274
|
+
if (G.onSuspend) {
|
|
275
|
+
G.onSuspend(promise, G.owner);
|
|
276
|
+
return true;
|
|
277
|
+
}
|
|
278
|
+
return false;
|
|
279
|
+
}
|
|
280
|
+
function getOwner() {
|
|
281
|
+
return G.owner;
|
|
282
|
+
}
|
|
283
|
+
function runWithOwner(owner, fn) {
|
|
284
|
+
const prev = G.owner;
|
|
285
|
+
G.owner = owner;
|
|
286
|
+
try {
|
|
287
|
+
return fn();
|
|
288
|
+
} finally {
|
|
289
|
+
G.owner = prev;
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
function onCleanup(fn) {
|
|
293
|
+
if (!G.owner) return;
|
|
294
|
+
if (G.owner.disposed) {
|
|
295
|
+
fn();
|
|
296
|
+
return;
|
|
297
|
+
}
|
|
298
|
+
(G.owner.cleanups ??= []).push(fn);
|
|
299
|
+
}
|
|
300
|
+
function disposeOwner(owner, final = true) {
|
|
301
|
+
if (owner.disposed) return;
|
|
302
|
+
if (owner.owned) {
|
|
303
|
+
for (let i = owner.owned.length - 1; i >= 0; i--) disposeOwner(owner.owned[i]);
|
|
304
|
+
owner.owned = null;
|
|
305
|
+
}
|
|
306
|
+
if (owner.cleanups) {
|
|
307
|
+
for (let i = owner.cleanups.length - 1; i >= 0; i--) owner.cleanups[i]();
|
|
308
|
+
owner.cleanups = null;
|
|
309
|
+
}
|
|
310
|
+
if (final) owner.disposed = true;
|
|
311
|
+
}
|
|
312
|
+
function createRoot(fn) {
|
|
313
|
+
const owner = makeOwner(G.owner);
|
|
314
|
+
if (G.owner) (G.owner.owned ??= []).push(owner);
|
|
315
|
+
const prev = G.owner;
|
|
316
|
+
G.owner = owner;
|
|
317
|
+
try {
|
|
318
|
+
return fn(() => disposeOwner(owner));
|
|
319
|
+
} finally {
|
|
320
|
+
G.owner = prev;
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
function setScheduler(fn) {
|
|
324
|
+
G.hostSchedule = fn ?? ((run) => void Promise.resolve().then(run));
|
|
325
|
+
}
|
|
326
|
+
function flushSync() {
|
|
327
|
+
G.scheduled = false;
|
|
328
|
+
if (G.flushing) return;
|
|
329
|
+
G.flushing = true;
|
|
330
|
+
let guard = 0;
|
|
331
|
+
try {
|
|
332
|
+
while (G.queue.length) {
|
|
333
|
+
if (++guard > 1e5) throw new Error("[fluixi] effect flush did not settle (cycle?)");
|
|
334
|
+
const batchOf = G.queue;
|
|
335
|
+
G.queue = [];
|
|
336
|
+
for (const e of batchOf) {
|
|
337
|
+
e.queued = false;
|
|
338
|
+
if (!e.disposed) e.run();
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
} finally {
|
|
342
|
+
G.flushing = false;
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
function afterWrite() {
|
|
346
|
+
if (G.batchDepth === 0) flushSync();
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
// src/lib/signal/graph/compat.ts
|
|
350
|
+
function isThenable(v) {
|
|
351
|
+
return !!v && typeof v.then === "function";
|
|
352
|
+
}
|
|
353
|
+
setScheduler(() => {
|
|
354
|
+
});
|
|
355
|
+
var $SIGNAL = /* @__PURE__ */ Symbol.for("signal");
|
|
356
|
+
var $MEMO = /* @__PURE__ */ Symbol.for("memo");
|
|
357
|
+
var $NODE = /* @__PURE__ */ Symbol.for("signal-node");
|
|
358
|
+
function createSignal(value, options) {
|
|
359
|
+
const state = new State(value, { equals: options?.equals });
|
|
360
|
+
const read = (() => state.get());
|
|
361
|
+
const write = ((next) => {
|
|
362
|
+
const v = typeof next === "function" ? next(state.peek()) : next;
|
|
363
|
+
state.set(v);
|
|
364
|
+
afterWrite();
|
|
365
|
+
return v;
|
|
366
|
+
});
|
|
367
|
+
Object.defineProperty(read, $SIGNAL, { value: true, enumerable: true });
|
|
368
|
+
Object.defineProperty(read, $NODE, {
|
|
369
|
+
value: {
|
|
370
|
+
get value() {
|
|
371
|
+
return state.peek();
|
|
372
|
+
},
|
|
373
|
+
get version() {
|
|
374
|
+
return state.version;
|
|
375
|
+
}
|
|
376
|
+
},
|
|
377
|
+
enumerable: false
|
|
378
|
+
});
|
|
379
|
+
reportReactiveNode({
|
|
380
|
+
kind: "signal",
|
|
381
|
+
node: state,
|
|
382
|
+
handle: read,
|
|
383
|
+
name: options?.name,
|
|
384
|
+
set: write
|
|
385
|
+
});
|
|
386
|
+
if (isObserved()) onCleanup(() => reportReactiveDispose(state));
|
|
387
|
+
return [read, write];
|
|
388
|
+
}
|
|
389
|
+
function createMemo(fn, value, options) {
|
|
390
|
+
let prev = value;
|
|
391
|
+
const owner = getOwner();
|
|
392
|
+
const c = new Computed(
|
|
393
|
+
() => runWithOwner(owner, () => {
|
|
394
|
+
try {
|
|
395
|
+
return prev = fn(prev);
|
|
396
|
+
} catch (e) {
|
|
397
|
+
if (isThenable(e)) {
|
|
398
|
+
reportSuspend(e);
|
|
399
|
+
return prev;
|
|
400
|
+
}
|
|
401
|
+
throw e;
|
|
402
|
+
}
|
|
403
|
+
}),
|
|
404
|
+
{ equals: options?.equals }
|
|
405
|
+
);
|
|
406
|
+
const read = (() => c.get());
|
|
407
|
+
Object.defineProperty(read, $SIGNAL, { value: true, enumerable: true });
|
|
408
|
+
Object.defineProperty(read, $MEMO, { value: true, enumerable: true });
|
|
409
|
+
reportReactiveNode({ kind: "memo", node: c, handle: read, name: options?.name });
|
|
410
|
+
if (isObserved()) onCleanup(() => reportReactiveDispose(c));
|
|
411
|
+
return read;
|
|
412
|
+
}
|
|
413
|
+
function untrack2(fn) {
|
|
414
|
+
return untrack(fn);
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
// src/lib/signal/list.ts
|
|
418
|
+
function mapArray(list, mapFn, options) {
|
|
419
|
+
let items = [];
|
|
420
|
+
onCleanup(() => {
|
|
421
|
+
for (const e of items) e.dispose();
|
|
422
|
+
items = [];
|
|
423
|
+
});
|
|
424
|
+
return createMemo(() => {
|
|
425
|
+
const next = list() || [];
|
|
426
|
+
return untrack2(() => {
|
|
427
|
+
if (next.length === 0) {
|
|
428
|
+
for (const e of items) e.dispose();
|
|
429
|
+
items = [];
|
|
430
|
+
return options?.fallback ? options.fallback() : [];
|
|
431
|
+
}
|
|
432
|
+
const prevByItem = /* @__PURE__ */ new Map();
|
|
433
|
+
for (const e of items) if (!prevByItem.has(e.item)) prevByItem.set(e.item, e);
|
|
434
|
+
const result = [];
|
|
435
|
+
const used = /* @__PURE__ */ new Set();
|
|
436
|
+
for (let i = 0; i < next.length; i++) {
|
|
437
|
+
const value = next[i];
|
|
438
|
+
const reuse = prevByItem.get(value);
|
|
439
|
+
if (reuse && !used.has(reuse)) {
|
|
440
|
+
reuse.setIndex(i);
|
|
441
|
+
result.push(reuse);
|
|
442
|
+
used.add(reuse);
|
|
443
|
+
} else {
|
|
444
|
+
let rendered, setIndex, dispose;
|
|
445
|
+
createRoot((d) => {
|
|
446
|
+
dispose = d;
|
|
447
|
+
const [index, setIdx] = createSignal(i, { name: "row index" });
|
|
448
|
+
setIndex = setIdx;
|
|
449
|
+
rendered = mapFn(value, index);
|
|
450
|
+
});
|
|
451
|
+
const entry = { item: value, rendered, dispose, setIndex };
|
|
452
|
+
result.push(entry);
|
|
453
|
+
used.add(entry);
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
for (const e of items) if (!used.has(e)) e.dispose();
|
|
457
|
+
items = result;
|
|
458
|
+
return result.map((e) => e.rendered);
|
|
459
|
+
});
|
|
460
|
+
}, void 0, { name: "mapArray" });
|
|
461
|
+
}
|
|
462
|
+
function keyArray(list, keyFn, mapFn, options) {
|
|
463
|
+
let keys = [];
|
|
464
|
+
let entries = [];
|
|
465
|
+
onCleanup(() => {
|
|
466
|
+
for (const e of entries) e.dispose();
|
|
467
|
+
keys = [];
|
|
468
|
+
entries = [];
|
|
469
|
+
});
|
|
470
|
+
return createMemo(() => {
|
|
471
|
+
const next = list() || [];
|
|
472
|
+
return untrack2(() => {
|
|
473
|
+
if (next.length === 0) {
|
|
474
|
+
for (const e of entries) e.dispose();
|
|
475
|
+
keys = [];
|
|
476
|
+
entries = [];
|
|
477
|
+
return options?.fallback ? options.fallback() : [];
|
|
478
|
+
}
|
|
479
|
+
const prevByKey = /* @__PURE__ */ new Map();
|
|
480
|
+
for (let i = 0; i < keys.length; i++) prevByKey.set(keys[i], entries[i]);
|
|
481
|
+
const resultEntries = [];
|
|
482
|
+
const resultKeys = [];
|
|
483
|
+
const usedKeys = /* @__PURE__ */ new Set();
|
|
484
|
+
for (let i = 0; i < next.length; i++) {
|
|
485
|
+
const key = keyFn(next[i]);
|
|
486
|
+
const reuse = prevByKey.get(key);
|
|
487
|
+
if (reuse && !usedKeys.has(key)) {
|
|
488
|
+
reuse.setIndex(i);
|
|
489
|
+
resultEntries.push(reuse);
|
|
490
|
+
} else {
|
|
491
|
+
let rendered, setIndex, dispose;
|
|
492
|
+
createRoot((d) => {
|
|
493
|
+
dispose = d;
|
|
494
|
+
const [index, setIdx] = createSignal(i, { name: "row index" });
|
|
495
|
+
setIndex = setIdx;
|
|
496
|
+
const item = createMemo((prev) => {
|
|
497
|
+
const cur = list() || [];
|
|
498
|
+
const v = cur[index()];
|
|
499
|
+
return v !== void 0 && v !== null ? v : prev;
|
|
500
|
+
}, next[i]);
|
|
501
|
+
rendered = mapFn(item, index);
|
|
502
|
+
});
|
|
503
|
+
resultEntries.push({ rendered, dispose, setIndex });
|
|
504
|
+
}
|
|
505
|
+
resultKeys.push(key);
|
|
506
|
+
usedKeys.add(key);
|
|
507
|
+
}
|
|
508
|
+
for (const [key, e] of prevByKey) if (!usedKeys.has(key)) e.dispose();
|
|
509
|
+
keys = resultKeys;
|
|
510
|
+
entries = resultEntries;
|
|
511
|
+
return resultEntries.map((e) => e.rendered);
|
|
512
|
+
});
|
|
513
|
+
}, void 0, { name: "keyArray" });
|
|
514
|
+
}
|
|
515
|
+
function indexArray(list, mapFn, options) {
|
|
516
|
+
let slots = [];
|
|
517
|
+
onCleanup(() => {
|
|
518
|
+
for (const s of slots) s.dispose();
|
|
519
|
+
slots = [];
|
|
520
|
+
});
|
|
521
|
+
return createMemo(() => {
|
|
522
|
+
const next = list() || [];
|
|
523
|
+
return untrack2(() => {
|
|
524
|
+
if (next.length === 0) {
|
|
525
|
+
for (const s of slots) s.dispose();
|
|
526
|
+
slots = [];
|
|
527
|
+
return options?.fallback ? options.fallback() : [];
|
|
528
|
+
}
|
|
529
|
+
const prevLen = slots.length;
|
|
530
|
+
const nextLen = next.length;
|
|
531
|
+
for (let i = prevLen; i < nextLen; i++) {
|
|
532
|
+
let rendered, setItem, dispose;
|
|
533
|
+
const value = next[i];
|
|
534
|
+
createRoot((d) => {
|
|
535
|
+
dispose = d;
|
|
536
|
+
const [item, setVal] = createSignal(value);
|
|
537
|
+
setItem = setVal;
|
|
538
|
+
rendered = mapFn(item, i);
|
|
539
|
+
});
|
|
540
|
+
slots.push({ rendered, setItem, dispose });
|
|
541
|
+
}
|
|
542
|
+
for (let i = nextLen; i < prevLen; i++) slots[i].dispose();
|
|
543
|
+
if (nextLen < prevLen) slots = slots.slice(0, nextLen);
|
|
544
|
+
const survive = Math.min(prevLen, nextLen);
|
|
545
|
+
for (let i = 0; i < survive; i++) slots[i].setItem(next[i]);
|
|
546
|
+
return slots.map((s) => s.rendered);
|
|
547
|
+
});
|
|
548
|
+
}, void 0, { name: "indexArray" });
|
|
549
|
+
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Keyed list reconciliation primitives
|
|
2
|
+
* Keyed list reconciliation primitives, the reactive foundation for `<For>`,
|
|
3
3
|
* `<For by>` and `<Index>` (mirrors SolidJS `mapArray`/`keyArray`/`indexArray`).
|
|
4
4
|
*
|
|
5
5
|
* Each maps a reactive array to an array of mapped values and reuses per-item
|
|
6
6
|
* reactive scopes across updates so only changed items re-run their map fn. Every
|
|
7
|
-
* mapped item lives in its own `createRoot`, so it has a disposable owner scope
|
|
7
|
+
* mapped item lives in its own `createRoot`, so it has a disposable owner scope
|
|
8
8
|
* this is what keeps list items owner-stable (the thing ad-hoc array handling gets
|
|
9
9
|
* wrong).
|
|
10
10
|
*/
|
|
@@ -25,13 +25,13 @@ export declare function mapArray<T, U>(list: ListSource<T>, mapFn: (item: T, ind
|
|
|
25
25
|
* Key-function map. Like `mapArray` but reuse is keyed by `keyFn(item)` (so the
|
|
26
26
|
* same key survives object recreation), and the map fn receives a *live* item
|
|
27
27
|
* accessor (reads through to the current list value, so sub-property updates
|
|
28
|
-
* propagate). Backs `<For by={
|
|
28
|
+
* propagate). Backs `<For by={...}>`.
|
|
29
29
|
*/
|
|
30
30
|
export declare function keyArray<T, U>(list: ListSource<T>, keyFn: (item: T) => any, mapFn: (item: Accessor<T>, index: Accessor<number>) => U, options?: ListOptions): Accessor<U[]>;
|
|
31
31
|
/**
|
|
32
|
-
* Index-keyed map. Reuse is keyed by *position
|
|
32
|
+
* Index-keyed map. Reuse is keyed by *position*, growing adds slots, shrinking
|
|
33
33
|
* disposes trailing slots, and when the value at a position changes only that
|
|
34
|
-
* slot's item signal updates (the map fn is
|
|
34
|
+
* slot's item signal updates (the map fn is not re-run). The map fn receives a
|
|
35
35
|
* live item accessor and a plain (stable) index. Backs `<Index>`.
|
|
36
36
|
*/
|
|
37
37
|
export declare function indexArray<T, U>(list: ListSource<T>, mapFn: (item: Accessor<T>, index: number) => U, options?: ListOptions): Accessor<U[]>;
|
package/dist/lib/signal/list.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Keyed list reconciliation primitives
|
|
2
|
+
* Keyed list reconciliation primitives, the reactive foundation for `<For>`,
|
|
3
3
|
* `<For by>` and `<Index>` (mirrors SolidJS `mapArray`/`keyArray`/`indexArray`).
|
|
4
4
|
*
|
|
5
5
|
* Each maps a reactive array to an array of mapped values and reuses per-item
|
|
6
6
|
* reactive scopes across updates so only changed items re-run their map fn. Every
|
|
7
|
-
* mapped item lives in its own `createRoot`, so it has a disposable owner scope
|
|
7
|
+
* mapped item lives in its own `createRoot`, so it has a disposable owner scope
|
|
8
8
|
* this is what keeps list items owner-stable (the thing ad-hoc array handling gets
|
|
9
9
|
* wrong).
|
|
10
10
|
*/
|
|
@@ -46,7 +46,7 @@ export function mapArray(list, mapFn, options) {
|
|
|
46
46
|
let rendered, setIndex, dispose;
|
|
47
47
|
createRoot((d) => {
|
|
48
48
|
dispose = d;
|
|
49
|
-
const [index, setIdx] = createSignal(i);
|
|
49
|
+
const [index, setIdx] = createSignal(i, { name: 'row index' });
|
|
50
50
|
setIndex = setIdx;
|
|
51
51
|
rendered = mapFn(value, index);
|
|
52
52
|
});
|
|
@@ -61,13 +61,13 @@ export function mapArray(list, mapFn, options) {
|
|
|
61
61
|
items = result;
|
|
62
62
|
return result.map((e) => e.rendered);
|
|
63
63
|
});
|
|
64
|
-
});
|
|
64
|
+
}, undefined, { name: 'mapArray' });
|
|
65
65
|
}
|
|
66
66
|
/**
|
|
67
67
|
* Key-function map. Like `mapArray` but reuse is keyed by `keyFn(item)` (so the
|
|
68
68
|
* same key survives object recreation), and the map fn receives a *live* item
|
|
69
69
|
* accessor (reads through to the current list value, so sub-property updates
|
|
70
|
-
* propagate). Backs `<For by={
|
|
70
|
+
* propagate). Backs `<For by={...}>`.
|
|
71
71
|
*/
|
|
72
72
|
export function keyArray(list, keyFn, mapFn, options) {
|
|
73
73
|
let keys = [];
|
|
@@ -101,7 +101,7 @@ export function keyArray(list, keyFn, mapFn, options) {
|
|
|
101
101
|
let rendered, setIndex, dispose;
|
|
102
102
|
createRoot((d) => {
|
|
103
103
|
dispose = d;
|
|
104
|
-
const [index, setIdx] = createSignal(i);
|
|
104
|
+
const [index, setIdx] = createSignal(i, { name: 'row index' });
|
|
105
105
|
setIndex = setIdx;
|
|
106
106
|
// Live accessor: reads the current list at this index. Falls back to the
|
|
107
107
|
// last known value while the array is mid-shrink (idx out of bounds)
|
|
@@ -125,12 +125,12 @@ export function keyArray(list, keyFn, mapFn, options) {
|
|
|
125
125
|
entries = resultEntries;
|
|
126
126
|
return resultEntries.map((e) => e.rendered);
|
|
127
127
|
});
|
|
128
|
-
});
|
|
128
|
+
}, undefined, { name: 'keyArray' });
|
|
129
129
|
}
|
|
130
130
|
/**
|
|
131
|
-
* Index-keyed map. Reuse is keyed by *position
|
|
131
|
+
* Index-keyed map. Reuse is keyed by *position*, growing adds slots, shrinking
|
|
132
132
|
* disposes trailing slots, and when the value at a position changes only that
|
|
133
|
-
* slot's item signal updates (the map fn is
|
|
133
|
+
* slot's item signal updates (the map fn is not re-run). The map fn receives a
|
|
134
134
|
* live item accessor and a plain (stable) index. Backs `<Index>`.
|
|
135
135
|
*/
|
|
136
136
|
export function indexArray(list, mapFn, options) {
|
|
@@ -168,5 +168,5 @@ export function indexArray(list, mapFn, options) {
|
|
|
168
168
|
slots[i].setItem(next[i]);
|
|
169
169
|
return slots.map((s) => s.rendered);
|
|
170
170
|
});
|
|
171
|
-
});
|
|
171
|
+
}, undefined, { name: 'indexArray' });
|
|
172
172
|
}
|