@tanstack/store 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.
Files changed (64) hide show
  1. package/dist/cjs/alien.cjs +345 -0
  2. package/dist/cjs/alien.cjs.map +1 -0
  3. package/dist/cjs/alien.d.cts +57 -0
  4. package/dist/cjs/atom.cjs +222 -0
  5. package/dist/cjs/atom.cjs.map +1 -0
  6. package/dist/cjs/atom.d.cts +16 -0
  7. package/dist/cjs/batch.cjs +15 -0
  8. package/dist/cjs/batch.cjs.map +1 -0
  9. package/dist/cjs/batch.d.cts +1 -0
  10. package/dist/cjs/index.cjs +8 -12
  11. package/dist/cjs/index.cjs.map +1 -1
  12. package/dist/cjs/index.d.cts +3 -4
  13. package/dist/cjs/store.cjs +22 -29
  14. package/dist/cjs/store.cjs.map +1 -1
  15. package/dist/cjs/store.d.cts +11 -30
  16. package/dist/cjs/types.d.cts +47 -20
  17. package/dist/esm/alien.d.ts +57 -0
  18. package/dist/esm/alien.js +345 -0
  19. package/dist/esm/alien.js.map +1 -0
  20. package/dist/esm/atom.d.ts +16 -0
  21. package/dist/esm/atom.js +222 -0
  22. package/dist/esm/atom.js.map +1 -0
  23. package/dist/esm/batch.d.ts +1 -0
  24. package/dist/esm/batch.js +15 -0
  25. package/dist/esm/batch.js.map +1 -0
  26. package/dist/esm/index.d.ts +3 -4
  27. package/dist/esm/index.js +8 -12
  28. package/dist/esm/index.js.map +1 -1
  29. package/dist/esm/store.d.ts +11 -30
  30. package/dist/esm/store.js +23 -30
  31. package/dist/esm/store.js.map +1 -1
  32. package/dist/esm/types.d.ts +47 -20
  33. package/package.json +6 -7
  34. package/src/alien.ts +654 -0
  35. package/src/atom.ts +298 -0
  36. package/src/batch.ts +12 -0
  37. package/src/index.ts +3 -4
  38. package/src/store.ts +33 -72
  39. package/src/types.ts +60 -24
  40. package/dist/cjs/derived.cjs +0 -130
  41. package/dist/cjs/derived.cjs.map +0 -1
  42. package/dist/cjs/derived.d.cts +0 -50
  43. package/dist/cjs/effect.cjs +0 -24
  44. package/dist/cjs/effect.cjs.map +0 -1
  45. package/dist/cjs/effect.d.cts +0 -18
  46. package/dist/cjs/scheduler.cjs +0 -103
  47. package/dist/cjs/scheduler.cjs.map +0 -1
  48. package/dist/cjs/scheduler.d.cts +0 -27
  49. package/dist/cjs/types.cjs +0 -7
  50. package/dist/cjs/types.cjs.map +0 -1
  51. package/dist/esm/derived.d.ts +0 -50
  52. package/dist/esm/derived.js +0 -130
  53. package/dist/esm/derived.js.map +0 -1
  54. package/dist/esm/effect.d.ts +0 -18
  55. package/dist/esm/effect.js +0 -24
  56. package/dist/esm/effect.js.map +0 -1
  57. package/dist/esm/scheduler.d.ts +0 -27
  58. package/dist/esm/scheduler.js +0 -103
  59. package/dist/esm/scheduler.js.map +0 -1
  60. package/dist/esm/types.js +0 -7
  61. package/dist/esm/types.js.map +0 -1
  62. package/src/derived.ts +0 -219
  63. package/src/effect.ts +0 -42
  64. package/src/scheduler.ts +0 -146
package/src/alien.ts ADDED
@@ -0,0 +1,654 @@
1
+ /* eslint-disable */
2
+ // Adapted from Alien Signals
3
+ // https://github.com/stackblitz/alien-signals/
4
+
5
+ export interface ReactiveNode {
6
+ deps?: Link
7
+ depsTail?: Link
8
+ subs?: Link
9
+ subsTail?: Link
10
+ flags: ReactiveFlags
11
+ }
12
+
13
+ export interface Link {
14
+ version: number
15
+ dep: ReactiveNode
16
+ sub: ReactiveNode
17
+ prevSub: Link | undefined
18
+ nextSub: Link | undefined
19
+ prevDep: Link | undefined
20
+ nextDep: Link | undefined
21
+ }
22
+
23
+ interface Stack<T> {
24
+ value: T
25
+ prev: Stack<T> | undefined
26
+ }
27
+
28
+ export const enum ReactiveFlags {
29
+ None = 0,
30
+ Mutable = 1,
31
+ Watching = 2,
32
+ RecursedCheck = 4,
33
+ Recursed = 8,
34
+ Dirty = 16,
35
+ Pending = 32,
36
+ }
37
+
38
+ export function createReactiveSystem({
39
+ update,
40
+ notify,
41
+ unwatched,
42
+ }: {
43
+ update(sub: ReactiveNode): boolean
44
+ notify(sub: ReactiveNode): void
45
+ unwatched(sub: ReactiveNode): void
46
+ }) {
47
+ return {
48
+ link,
49
+ unlink,
50
+ propagate,
51
+ checkDirty,
52
+ shallowPropagate,
53
+ }
54
+
55
+ function link(dep: ReactiveNode, sub: ReactiveNode, version: number): void {
56
+ const prevDep = sub.depsTail
57
+ if (prevDep !== undefined && prevDep.dep === dep) {
58
+ return
59
+ }
60
+ const nextDep = prevDep !== undefined ? prevDep.nextDep : sub.deps
61
+ if (nextDep !== undefined && nextDep.dep === dep) {
62
+ nextDep.version = version
63
+ sub.depsTail = nextDep
64
+ return
65
+ }
66
+ const prevSub = dep.subsTail
67
+ if (
68
+ prevSub !== undefined &&
69
+ prevSub.version === version &&
70
+ prevSub.sub === sub
71
+ ) {
72
+ return
73
+ }
74
+ const newLink =
75
+ (sub.depsTail =
76
+ dep.subsTail =
77
+ {
78
+ version,
79
+ dep,
80
+ sub,
81
+ prevDep,
82
+ nextDep,
83
+ prevSub,
84
+ nextSub: undefined,
85
+ })
86
+ if (nextDep !== undefined) {
87
+ nextDep.prevDep = newLink
88
+ }
89
+ if (prevDep !== undefined) {
90
+ prevDep.nextDep = newLink
91
+ } else {
92
+ sub.deps = newLink
93
+ }
94
+ if (prevSub !== undefined) {
95
+ prevSub.nextSub = newLink
96
+ } else {
97
+ dep.subs = newLink
98
+ }
99
+ }
100
+
101
+ function unlink(link: Link, sub = link.sub): Link | undefined {
102
+ const dep = link.dep
103
+ const prevDep = link.prevDep
104
+ const nextDep = link.nextDep
105
+ const nextSub = link.nextSub
106
+ const prevSub = link.prevSub
107
+ if (nextDep !== undefined) {
108
+ nextDep.prevDep = prevDep
109
+ } else {
110
+ sub.depsTail = prevDep
111
+ }
112
+ if (prevDep !== undefined) {
113
+ prevDep.nextDep = nextDep
114
+ } else {
115
+ sub.deps = nextDep
116
+ }
117
+ if (nextSub !== undefined) {
118
+ nextSub.prevSub = prevSub
119
+ } else {
120
+ dep.subsTail = prevSub
121
+ }
122
+ if (prevSub !== undefined) {
123
+ prevSub.nextSub = nextSub
124
+ } else if ((dep.subs = nextSub) === undefined) {
125
+ unwatched(dep)
126
+ }
127
+ return nextDep
128
+ }
129
+
130
+ function propagate(link: Link): void {
131
+ let next = link.nextSub
132
+ let stack: Stack<Link | undefined> | undefined
133
+
134
+ top: do {
135
+ const sub = link.sub
136
+ let flags = sub.flags
137
+
138
+ if (
139
+ !(
140
+ flags &
141
+ (ReactiveFlags.RecursedCheck |
142
+ ReactiveFlags.Recursed |
143
+ ReactiveFlags.Dirty |
144
+ ReactiveFlags.Pending)
145
+ )
146
+ ) {
147
+ sub.flags = flags | ReactiveFlags.Pending
148
+ } else if (
149
+ !(flags & (ReactiveFlags.RecursedCheck | ReactiveFlags.Recursed))
150
+ ) {
151
+ flags = ReactiveFlags.None
152
+ } else if (!(flags & ReactiveFlags.RecursedCheck)) {
153
+ sub.flags = (flags & ~ReactiveFlags.Recursed) | ReactiveFlags.Pending
154
+ } else if (
155
+ !(flags & (ReactiveFlags.Dirty | ReactiveFlags.Pending)) &&
156
+ isValidLink(link, sub)
157
+ ) {
158
+ sub.flags = flags | (ReactiveFlags.Recursed | ReactiveFlags.Pending)
159
+ flags &= ReactiveFlags.Mutable
160
+ } else {
161
+ flags = ReactiveFlags.None
162
+ }
163
+
164
+ if (flags & ReactiveFlags.Watching) {
165
+ notify(sub)
166
+ }
167
+
168
+ if (flags & ReactiveFlags.Mutable) {
169
+ const subSubs = sub.subs
170
+ if (subSubs !== undefined) {
171
+ const nextSub = (link = subSubs).nextSub
172
+ if (nextSub !== undefined) {
173
+ stack = { value: next, prev: stack }
174
+ next = nextSub
175
+ }
176
+ continue
177
+ }
178
+ }
179
+
180
+ if ((link = next!) !== undefined) {
181
+ next = link.nextSub
182
+ continue
183
+ }
184
+
185
+ while (stack !== undefined) {
186
+ link = stack.value!
187
+ stack = stack.prev
188
+ if (link !== undefined) {
189
+ next = link.nextSub
190
+ continue top
191
+ }
192
+ }
193
+
194
+ break
195
+ } while (true)
196
+ }
197
+
198
+ function checkDirty(link: Link, sub: ReactiveNode): boolean {
199
+ let stack: Stack<Link> | undefined
200
+ let checkDepth = 0
201
+ let dirty = false
202
+
203
+ top: do {
204
+ const dep = link.dep
205
+ const flags = dep.flags
206
+
207
+ if (sub.flags & ReactiveFlags.Dirty) {
208
+ dirty = true
209
+ } else if (
210
+ (flags & (ReactiveFlags.Mutable | ReactiveFlags.Dirty)) ===
211
+ (ReactiveFlags.Mutable | ReactiveFlags.Dirty)
212
+ ) {
213
+ if (update(dep)) {
214
+ const subs = dep.subs!
215
+ if (subs.nextSub !== undefined) {
216
+ shallowPropagate(subs)
217
+ }
218
+ dirty = true
219
+ }
220
+ } else if (
221
+ (flags & (ReactiveFlags.Mutable | ReactiveFlags.Pending)) ===
222
+ (ReactiveFlags.Mutable | ReactiveFlags.Pending)
223
+ ) {
224
+ if (link.nextSub !== undefined || link.prevSub !== undefined) {
225
+ stack = { value: link, prev: stack }
226
+ }
227
+ link = dep.deps!
228
+ sub = dep
229
+ ++checkDepth
230
+ continue
231
+ }
232
+
233
+ if (!dirty) {
234
+ const nextDep = link.nextDep
235
+ if (nextDep !== undefined) {
236
+ link = nextDep
237
+ continue
238
+ }
239
+ }
240
+
241
+ while (checkDepth--) {
242
+ const firstSub = sub.subs!
243
+ const hasMultipleSubs = firstSub.nextSub !== undefined
244
+ if (hasMultipleSubs) {
245
+ link = stack!.value
246
+ stack = stack!.prev
247
+ } else {
248
+ link = firstSub
249
+ }
250
+ if (dirty) {
251
+ if (update(sub)) {
252
+ if (hasMultipleSubs) {
253
+ shallowPropagate(firstSub)
254
+ }
255
+ sub = link.sub
256
+ continue
257
+ }
258
+ dirty = false
259
+ } else {
260
+ sub.flags &= ~ReactiveFlags.Pending
261
+ }
262
+ sub = link.sub
263
+ const nextDep = link.nextDep
264
+ if (nextDep !== undefined) {
265
+ link = nextDep
266
+ continue top
267
+ }
268
+ }
269
+
270
+ return dirty
271
+ } while (true)
272
+ }
273
+
274
+ function shallowPropagate(link: Link): void {
275
+ do {
276
+ const sub = link.sub
277
+ const flags = sub.flags
278
+ if (
279
+ (flags & (ReactiveFlags.Pending | ReactiveFlags.Dirty)) ===
280
+ ReactiveFlags.Pending
281
+ ) {
282
+ sub.flags = flags | ReactiveFlags.Dirty
283
+ if (
284
+ (flags & (ReactiveFlags.Watching | ReactiveFlags.RecursedCheck)) ===
285
+ ReactiveFlags.Watching
286
+ ) {
287
+ notify(sub)
288
+ }
289
+ }
290
+ } while ((link = link.nextSub!) !== undefined)
291
+ }
292
+
293
+ function isValidLink(checkLink: Link, sub: ReactiveNode): boolean {
294
+ let link = sub.depsTail
295
+ while (link !== undefined) {
296
+ if (link === checkLink) {
297
+ return true
298
+ }
299
+ link = link.prevDep
300
+ }
301
+ return false
302
+ }
303
+ }
304
+
305
+ interface EffectNode extends ReactiveNode {
306
+ fn(): void
307
+ }
308
+
309
+ interface ComputedNode<T = any> extends ReactiveNode {
310
+ value: T | undefined
311
+ getter: (previousValue?: T) => T
312
+ }
313
+
314
+ interface SignalNode<T = any> extends ReactiveNode {
315
+ currentValue: T
316
+ pendingValue: T
317
+ }
318
+
319
+ let cycle = 0
320
+ let batchDepth = 0
321
+ let notifyIndex = 0
322
+ let queuedLength = 0
323
+ let activeSub: ReactiveNode | undefined
324
+
325
+ const queued: (EffectNode | undefined)[] = []
326
+ const { link, unlink, propagate, checkDirty, shallowPropagate } =
327
+ createReactiveSystem({
328
+ update(node: SignalNode | ComputedNode): boolean {
329
+ if (node.depsTail !== undefined) {
330
+ return updateComputed(node as ComputedNode)
331
+ } else {
332
+ return updateSignal(node as SignalNode)
333
+ }
334
+ },
335
+ notify(effect: EffectNode) {
336
+ let insertIndex = queuedLength
337
+ let firstInsertedIndex = insertIndex
338
+
339
+ do {
340
+ queued[insertIndex++] = effect
341
+ effect.flags &= ~ReactiveFlags.Watching
342
+ effect = effect.subs?.sub as EffectNode
343
+ if (effect === undefined || !(effect.flags & ReactiveFlags.Watching)) {
344
+ break
345
+ }
346
+ } while (true)
347
+
348
+ queuedLength = insertIndex
349
+
350
+ while (firstInsertedIndex < --insertIndex) {
351
+ const left = queued[firstInsertedIndex]
352
+ queued[firstInsertedIndex++] = queued[insertIndex]
353
+ queued[insertIndex] = left
354
+ }
355
+ },
356
+ unwatched(node) {
357
+ if (!(node.flags & ReactiveFlags.Mutable)) {
358
+ effectScopeOper.call(node)
359
+ } else if (node.depsTail !== undefined) {
360
+ node.depsTail = undefined
361
+ node.flags = ReactiveFlags.Mutable | ReactiveFlags.Dirty
362
+ purgeDeps(node)
363
+ }
364
+ },
365
+ })
366
+
367
+ export function getActiveSub(): ReactiveNode | undefined {
368
+ return activeSub
369
+ }
370
+
371
+ export function setActiveSub(sub?: ReactiveNode) {
372
+ const prevSub = activeSub
373
+ activeSub = sub
374
+ return prevSub
375
+ }
376
+
377
+ export function getBatchDepth(): number {
378
+ return batchDepth
379
+ }
380
+
381
+ export function startBatch() {
382
+ ++batchDepth
383
+ }
384
+
385
+ export function endBatch() {
386
+ if (!--batchDepth) {
387
+ flush()
388
+ }
389
+ }
390
+
391
+ export function isSignal(fn: () => void): boolean {
392
+ return fn.name === 'bound ' + signalOper.name
393
+ }
394
+
395
+ export function isComputed(fn: () => void): boolean {
396
+ return fn.name === 'bound ' + computedOper.name
397
+ }
398
+
399
+ export function isEffect(fn: () => void): boolean {
400
+ return fn.name === 'bound ' + effectOper.name
401
+ }
402
+
403
+ export function isEffectScope(fn: () => void): boolean {
404
+ return fn.name === 'bound ' + effectScopeOper.name
405
+ }
406
+
407
+ export function signal<T>(): {
408
+ (): T | undefined
409
+ (value: T | undefined): void
410
+ }
411
+ export function signal<T>(initialValue: T): {
412
+ (): T
413
+ (value: T): void
414
+ }
415
+ export function signal<T>(initialValue?: T): {
416
+ (): T | undefined
417
+ (value: T | undefined): void
418
+ } {
419
+ return signalOper.bind({
420
+ currentValue: initialValue,
421
+ pendingValue: initialValue,
422
+ subs: undefined,
423
+ subsTail: undefined,
424
+ flags: ReactiveFlags.Mutable,
425
+ }) as () => T | undefined
426
+ }
427
+
428
+ export function computed<T>(getter: (previousValue?: T) => T): () => T {
429
+ return computedOper.bind({
430
+ value: undefined,
431
+ subs: undefined,
432
+ subsTail: undefined,
433
+ deps: undefined,
434
+ depsTail: undefined,
435
+ flags: ReactiveFlags.None,
436
+ getter: getter as (previousValue?: unknown) => unknown,
437
+ }) as () => T
438
+ }
439
+
440
+ export function effect(fn: () => void): () => void {
441
+ const e: EffectNode = {
442
+ fn,
443
+ subs: undefined,
444
+ subsTail: undefined,
445
+ deps: undefined,
446
+ depsTail: undefined,
447
+ flags: ReactiveFlags.Watching | ReactiveFlags.RecursedCheck,
448
+ }
449
+ const prevSub = setActiveSub(e)
450
+ if (prevSub !== undefined) {
451
+ link(e, prevSub, 0)
452
+ }
453
+ try {
454
+ e.fn()
455
+ } finally {
456
+ activeSub = prevSub
457
+ e.flags &= ~ReactiveFlags.RecursedCheck
458
+ }
459
+ return effectOper.bind(e)
460
+ }
461
+
462
+ export function effectScope(fn: () => void): () => void {
463
+ const e: ReactiveNode = {
464
+ deps: undefined,
465
+ depsTail: undefined,
466
+ subs: undefined,
467
+ subsTail: undefined,
468
+ flags: ReactiveFlags.None,
469
+ }
470
+ const prevSub = setActiveSub(e)
471
+ if (prevSub !== undefined) {
472
+ link(e, prevSub, 0)
473
+ }
474
+ try {
475
+ fn()
476
+ } finally {
477
+ activeSub = prevSub
478
+ }
479
+ return effectScopeOper.bind(e)
480
+ }
481
+
482
+ export function trigger(fn: () => void) {
483
+ const sub: ReactiveNode = {
484
+ deps: undefined,
485
+ depsTail: undefined,
486
+ flags: ReactiveFlags.Watching,
487
+ }
488
+ const prevSub = setActiveSub(sub)
489
+ try {
490
+ fn()
491
+ } finally {
492
+ activeSub = prevSub
493
+ let link = sub.deps
494
+ while (link !== undefined) {
495
+ const dep = link.dep
496
+ link = unlink(link, sub)
497
+ const subs = dep.subs
498
+ if (subs !== undefined) {
499
+ sub.flags = ReactiveFlags.None
500
+ propagate(subs)
501
+ shallowPropagate(subs)
502
+ }
503
+ }
504
+ if (!batchDepth) {
505
+ flush()
506
+ }
507
+ }
508
+ }
509
+
510
+ function updateComputed(c: ComputedNode): boolean {
511
+ ++cycle
512
+ c.depsTail = undefined
513
+ c.flags = ReactiveFlags.Mutable | ReactiveFlags.RecursedCheck
514
+ const prevSub = setActiveSub(c)
515
+ try {
516
+ const oldValue = c.value
517
+ return oldValue !== (c.value = c.getter(oldValue))
518
+ } finally {
519
+ activeSub = prevSub
520
+ c.flags &= ~ReactiveFlags.RecursedCheck
521
+ purgeDeps(c)
522
+ }
523
+ }
524
+
525
+ function updateSignal(s: SignalNode): boolean {
526
+ s.flags = ReactiveFlags.Mutable
527
+ return s.currentValue !== (s.currentValue = s.pendingValue)
528
+ }
529
+
530
+ function run(e: EffectNode): void {
531
+ const flags = e.flags
532
+ if (
533
+ flags & ReactiveFlags.Dirty ||
534
+ (flags & ReactiveFlags.Pending && checkDirty(e.deps!, e))
535
+ ) {
536
+ ++cycle
537
+ e.depsTail = undefined
538
+ e.flags = ReactiveFlags.Watching | ReactiveFlags.RecursedCheck
539
+ const prevSub = setActiveSub(e)
540
+ try {
541
+ ;(e as EffectNode).fn()
542
+ } finally {
543
+ activeSub = prevSub
544
+ e.flags &= ~ReactiveFlags.RecursedCheck
545
+ purgeDeps(e)
546
+ }
547
+ } else {
548
+ e.flags = ReactiveFlags.Watching
549
+ }
550
+ }
551
+
552
+ function flush(): void {
553
+ try {
554
+ while (notifyIndex < queuedLength) {
555
+ const effect = queued[notifyIndex]!
556
+ queued[notifyIndex++] = undefined
557
+ run(effect)
558
+ }
559
+ } finally {
560
+ while (notifyIndex < queuedLength) {
561
+ const effect = queued[notifyIndex]!
562
+ queued[notifyIndex++] = undefined
563
+ effect.flags |= ReactiveFlags.Watching | ReactiveFlags.Recursed
564
+ }
565
+ notifyIndex = 0
566
+ queuedLength = 0
567
+ }
568
+ }
569
+
570
+ function computedOper<T>(this: ComputedNode<T>): T {
571
+ const flags = this.flags
572
+ if (
573
+ flags & ReactiveFlags.Dirty ||
574
+ (flags & ReactiveFlags.Pending &&
575
+ (checkDirty(this.deps!, this) ||
576
+ ((this.flags = flags & ~ReactiveFlags.Pending), false)))
577
+ ) {
578
+ if (updateComputed(this)) {
579
+ const subs = this.subs
580
+ if (subs !== undefined) {
581
+ shallowPropagate(subs)
582
+ }
583
+ }
584
+ } else if (!flags) {
585
+ this.flags = ReactiveFlags.Mutable | ReactiveFlags.RecursedCheck
586
+ const prevSub = setActiveSub(this)
587
+ try {
588
+ this.value = this.getter()
589
+ } finally {
590
+ activeSub = prevSub
591
+ this.flags &= ~ReactiveFlags.RecursedCheck
592
+ }
593
+ }
594
+ const sub = activeSub
595
+ if (sub !== undefined) {
596
+ link(this, sub, cycle)
597
+ }
598
+ return this.value!
599
+ }
600
+
601
+ function signalOper<T>(this: SignalNode<T>, ...value: [T]): T | void {
602
+ if (value.length) {
603
+ if (this.pendingValue !== (this.pendingValue = value[0])) {
604
+ this.flags = ReactiveFlags.Mutable | ReactiveFlags.Dirty
605
+ const subs = this.subs
606
+ if (subs !== undefined) {
607
+ propagate(subs)
608
+ if (!batchDepth) {
609
+ flush()
610
+ }
611
+ }
612
+ }
613
+ } else {
614
+ if (this.flags & ReactiveFlags.Dirty) {
615
+ if (updateSignal(this)) {
616
+ const subs = this.subs
617
+ if (subs !== undefined) {
618
+ shallowPropagate(subs)
619
+ }
620
+ }
621
+ }
622
+ let sub = activeSub
623
+ while (sub !== undefined) {
624
+ if (sub.flags & (ReactiveFlags.Mutable | ReactiveFlags.Watching)) {
625
+ link(this, sub, cycle)
626
+ break
627
+ }
628
+ sub = sub.subs?.sub
629
+ }
630
+ return this.currentValue
631
+ }
632
+ }
633
+
634
+ function effectOper(this: EffectNode): void {
635
+ effectScopeOper.call(this)
636
+ }
637
+
638
+ function effectScopeOper(this: ReactiveNode): void {
639
+ this.depsTail = undefined
640
+ this.flags = ReactiveFlags.None
641
+ purgeDeps(this)
642
+ const sub = this.subs
643
+ if (sub !== undefined) {
644
+ unlink(sub)
645
+ }
646
+ }
647
+
648
+ function purgeDeps(sub: ReactiveNode) {
649
+ const depsTail = sub.depsTail
650
+ let dep = depsTail !== undefined ? depsTail.nextDep : sub.deps
651
+ while (dep !== undefined) {
652
+ dep = unlink(dep, sub)
653
+ }
654
+ }