@esportsplus/reactivity 0.8.0 → 0.9.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/build/signal.js DELETED
@@ -1,325 +0,0 @@
1
- import { isArray, isObject } from '@esportsplus/utilities';
2
- import { REACTIVE, STATE_CHECK, STATE_DIRTY, STATE_IN_HEAP, STATE_NONE, STATE_RECOMPUTING } from './constants.js';
3
- let dirtyHeap = new Array(2000), maxDirty = 0, markedHeap = false, minDirty = 0, observer = null;
4
- function cleanup(node) {
5
- if (!node.cleanup) {
6
- return;
7
- }
8
- if (isArray(node.cleanup)) {
9
- for (let i = 0; i < node.cleanup.length; i++) {
10
- node.cleanup[i]();
11
- }
12
- }
13
- else {
14
- node.cleanup();
15
- }
16
- node.cleanup = null;
17
- }
18
- function deleteFromHeap(n) {
19
- let state = n.state;
20
- if (!(state & STATE_IN_HEAP)) {
21
- return;
22
- }
23
- n.state = state & ~STATE_IN_HEAP;
24
- let height = n.height;
25
- if (n.prevHeap === n) {
26
- dirtyHeap[height] = undefined;
27
- }
28
- else {
29
- let next = n.nextHeap, dhh = dirtyHeap[height], end = next ?? dhh;
30
- if (n === dhh) {
31
- dirtyHeap[height] = next;
32
- }
33
- else {
34
- n.prevHeap.nextHeap = next;
35
- }
36
- end.prevHeap = n.prevHeap;
37
- }
38
- n.nextHeap = undefined;
39
- n.prevHeap = n;
40
- }
41
- function insertIntoHeap(n) {
42
- let state = n.state;
43
- if (state & STATE_IN_HEAP) {
44
- return;
45
- }
46
- n.state = state | STATE_IN_HEAP;
47
- let height = n.height, heapAtHeight = dirtyHeap[height];
48
- if (heapAtHeight === undefined) {
49
- dirtyHeap[height] = n;
50
- }
51
- else {
52
- let tail = heapAtHeight.prevHeap;
53
- tail.nextHeap = n;
54
- n.prevHeap = tail;
55
- heapAtHeight.prevHeap = n;
56
- }
57
- if (height > maxDirty) {
58
- maxDirty = height;
59
- if (height >= dirtyHeap.length) {
60
- dirtyHeap.length += 250;
61
- }
62
- }
63
- }
64
- function link(dep, sub) {
65
- let prevDep = sub.depsTail;
66
- if (prevDep !== null && prevDep.dep === dep) {
67
- return;
68
- }
69
- let nextDep = null;
70
- if (sub.state & STATE_RECOMPUTING) {
71
- nextDep = prevDep !== null ? prevDep.nextDep : sub.deps;
72
- if (nextDep !== null && nextDep.dep === dep) {
73
- sub.depsTail = nextDep;
74
- return;
75
- }
76
- }
77
- let prevSub = dep.subsTail, newLink = sub.depsTail =
78
- dep.subsTail = {
79
- dep,
80
- sub,
81
- nextDep,
82
- prevSub,
83
- nextSub: null,
84
- };
85
- if (prevDep !== null) {
86
- prevDep.nextDep = newLink;
87
- }
88
- else {
89
- sub.deps = newLink;
90
- }
91
- if (prevSub !== null) {
92
- prevSub.nextSub = newLink;
93
- }
94
- else {
95
- dep.subs = newLink;
96
- }
97
- }
98
- function markHeap() {
99
- if (markedHeap) {
100
- return;
101
- }
102
- markedHeap = true;
103
- for (let i = 0; i <= maxDirty; i++) {
104
- for (let el = dirtyHeap[i]; el !== undefined; el = el.nextHeap) {
105
- markNode(el);
106
- }
107
- }
108
- }
109
- function markNode(el, newState = STATE_DIRTY) {
110
- let state = el.state;
111
- if ((state & (STATE_CHECK | STATE_DIRTY)) >= newState) {
112
- return;
113
- }
114
- el.state = state | newState;
115
- for (let link = el.subs; link !== null; link = link.nextSub) {
116
- markNode(link.sub, STATE_CHECK);
117
- }
118
- }
119
- function recompute(el, del) {
120
- if (del) {
121
- deleteFromHeap(el);
122
- }
123
- else {
124
- el.nextHeap = undefined;
125
- el.prevHeap = el;
126
- }
127
- cleanup(el);
128
- let o = observer, ok = true, value;
129
- observer = el;
130
- el.depsTail = null;
131
- el.state = STATE_RECOMPUTING;
132
- try {
133
- value = el.fn(oncleanup);
134
- }
135
- catch (e) {
136
- ok = false;
137
- }
138
- observer = o;
139
- el.state = STATE_NONE;
140
- let depsTail = el.depsTail, toRemove = depsTail !== null ? depsTail.nextDep : el.deps;
141
- if (toRemove !== null) {
142
- do {
143
- toRemove = unlink(toRemove);
144
- } while (toRemove !== null);
145
- if (depsTail !== null) {
146
- depsTail.nextDep = null;
147
- }
148
- else {
149
- el.deps = null;
150
- }
151
- }
152
- if (ok && value !== el.value) {
153
- el.value = value;
154
- for (let s = el.subs; s !== null; s = s.nextSub) {
155
- let o = s.sub, state = o.state;
156
- if (state & STATE_CHECK) {
157
- o.state = state | STATE_DIRTY;
158
- }
159
- insertIntoHeap(o);
160
- }
161
- }
162
- if (stabilize.state.value === STATE_NONE) {
163
- root(() => signal.set(stabilize.state, STATE_DIRTY));
164
- }
165
- }
166
- function unlink(link) {
167
- let dep = link.dep, nextDep = link.nextDep, nextSub = link.nextSub, prevSub = link.prevSub;
168
- if (nextSub !== null) {
169
- nextSub.prevSub = prevSub;
170
- }
171
- else {
172
- dep.subsTail = prevSub;
173
- }
174
- if (prevSub !== null) {
175
- prevSub.nextSub = nextSub;
176
- }
177
- else {
178
- dep.subs = nextSub;
179
- if (nextSub === null && 'fn' in dep) {
180
- dispose(dep);
181
- }
182
- }
183
- return nextDep;
184
- }
185
- function update(el) {
186
- if (el.state & STATE_CHECK) {
187
- for (let d = el.deps; d; d = d.nextDep) {
188
- let dep = d.dep;
189
- if ('fn' in dep) {
190
- update(dep);
191
- }
192
- if (el.state & STATE_DIRTY) {
193
- break;
194
- }
195
- }
196
- }
197
- if (el.state & STATE_DIRTY) {
198
- recompute(el, true);
199
- }
200
- el.state = STATE_NONE;
201
- }
202
- const computed = (fn) => {
203
- let self = {
204
- [REACTIVE]: true,
205
- cleanup: null,
206
- deps: null,
207
- depsTail: null,
208
- fn: fn,
209
- height: 0,
210
- nextHeap: undefined,
211
- prevHeap: null,
212
- state: STATE_NONE,
213
- subs: null,
214
- subsTail: null,
215
- value: undefined,
216
- };
217
- self.prevHeap = self;
218
- if (observer) {
219
- if (observer.depsTail === null) {
220
- self.height = observer.height;
221
- recompute(self, false);
222
- }
223
- else {
224
- self.height = observer.height + 1;
225
- insertIntoHeap(self);
226
- }
227
- link(self, observer);
228
- }
229
- else {
230
- recompute(self, false);
231
- }
232
- return self;
233
- };
234
- const dispose = (el) => {
235
- deleteFromHeap(el);
236
- let dep = el.deps;
237
- while (dep !== null) {
238
- dep = unlink(dep);
239
- }
240
- el.deps = null;
241
- cleanup(el);
242
- };
243
- const isComputed = (value) => {
244
- return isObject(value) && REACTIVE in value && 'fn' in value;
245
- };
246
- const isReactive = (value) => {
247
- return isObject(value) && REACTIVE in value;
248
- };
249
- const isSignal = (value) => {
250
- return isObject(value) && REACTIVE in value && 'fn' in value === false;
251
- };
252
- const oncleanup = (fn) => {
253
- if (!observer) {
254
- return fn;
255
- }
256
- let node = observer;
257
- if (!node.cleanup) {
258
- node.cleanup = fn;
259
- }
260
- else if (isArray(node.cleanup)) {
261
- node.cleanup.push(fn);
262
- }
263
- else {
264
- node.cleanup = [node.cleanup, fn];
265
- }
266
- return fn;
267
- };
268
- const read = (el) => {
269
- if (observer) {
270
- link(el, observer);
271
- if ('fn' in el) {
272
- let height = el.height;
273
- if (height >= observer.height) {
274
- observer.height = height + 1;
275
- }
276
- if (height >= minDirty ||
277
- el.state & (STATE_DIRTY | STATE_CHECK)) {
278
- markHeap();
279
- update(el);
280
- }
281
- }
282
- }
283
- return el.value;
284
- };
285
- const root = (fn) => {
286
- let o = observer;
287
- observer = null;
288
- let value = fn();
289
- observer = o;
290
- return value;
291
- };
292
- const signal = (value) => {
293
- return {
294
- [REACTIVE]: true,
295
- subs: null,
296
- subsTail: null,
297
- value,
298
- };
299
- };
300
- signal.set = (el, v) => {
301
- if (el.value === v) {
302
- return;
303
- }
304
- el.value = v;
305
- for (let link = el.subs; link !== null; link = link.nextSub) {
306
- markedHeap = false;
307
- insertIntoHeap(link.sub);
308
- }
309
- };
310
- const stabilize = () => {
311
- root(() => {
312
- for (minDirty = 0; minDirty <= maxDirty; minDirty++) {
313
- let el = dirtyHeap[minDirty];
314
- dirtyHeap[minDirty] = undefined;
315
- while (el !== undefined) {
316
- let next = el.nextHeap;
317
- recompute(el, false);
318
- el = next;
319
- }
320
- }
321
- signal.set(stabilize.state, STATE_NONE);
322
- });
323
- };
324
- stabilize.state = signal(STATE_NONE);
325
- export { computed, dispose, isComputed, isReactive, isSignal, oncleanup, read, root, signal, stabilize };
package/src/scheduler.ts DELETED
@@ -1,27 +0,0 @@
1
- import { STATE_DIRTY, STATE_NONE } from './constants';
2
- import { computed, dispose, read, signal, stabilize } from './signal';
3
- import { Computed } from './types';
4
-
5
-
6
- let c: Computed<void> | null = null;
7
-
8
-
9
- const scheduler = (schedule: (task: VoidFunction) => void) => {
10
- if (c) {
11
- dispose(c);
12
- }
13
-
14
- c = computed(() => {
15
- if (read(state) !== STATE_DIRTY) {
16
- return;
17
- }
18
-
19
- schedule(stabilize);
20
- });
21
- };
22
-
23
- const state = signal(STATE_NONE);
24
-
25
-
26
- export default scheduler;
27
- export { state };