@solidjs/signals 2.0.0-rc.14 → 2.0.0-rc.16

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 (98) hide show
  1. package/dist/dev-shared.js +882 -405
  2. package/dist/dev.attribution.js +172 -66
  3. package/dist/dev.js +1529 -745
  4. package/dist/observe/affects-marks.js +86 -0
  5. package/dist/observe/affects.js +32 -80
  6. package/dist/observe/boundaries.js +202 -166
  7. package/dist/observe/core/async.js +192 -141
  8. package/dist/observe/core/attribution-queries.js +1 -1
  9. package/dist/observe/core/attribution.js +315 -214
  10. package/dist/observe/core/constants.js +23 -4
  11. package/dist/observe/core/context.js +3 -3
  12. package/dist/observe/core/core.js +532 -360
  13. package/dist/observe/core/dev.js +63 -35
  14. package/dist/observe/core/effect.js +47 -47
  15. package/dist/observe/core/error.js +5 -3
  16. package/dist/observe/core/external.js +5 -6
  17. package/dist/observe/core/graph.js +56 -42
  18. package/dist/observe/core/heap.js +33 -33
  19. package/dist/observe/core/identities.js +62 -0
  20. package/dist/observe/core/lanes.js +242 -229
  21. package/dist/observe/core/owner.js +62 -50
  22. package/dist/observe/core/scheduler.js +322 -168
  23. package/dist/observe/core/truth.js +45 -0
  24. package/dist/observe/core/verdict.js +114 -64
  25. package/dist/observe/deferred.js +184 -0
  26. package/dist/observe/index.js +7 -1
  27. package/dist/observe/map.js +339 -254
  28. package/dist/observe/reveal.js +77 -77
  29. package/dist/observe/signals.js +54 -33
  30. package/dist/observe/store/affects.js +76 -69
  31. package/dist/observe/store/edges.js +39 -0
  32. package/dist/observe/store/hooks.js +13 -0
  33. package/dist/observe/store/index.js +0 -2
  34. package/dist/observe/store/optimistic.js +82 -44
  35. package/dist/observe/store/projection.js +83 -64
  36. package/dist/observe/store/reconcile.js +32 -30
  37. package/dist/observe/store/store.js +219 -123
  38. package/dist/prod/affects-marks.js +86 -0
  39. package/dist/prod/affects.js +33 -79
  40. package/dist/prod/boundaries.js +185 -149
  41. package/dist/prod/core/async.js +176 -135
  42. package/dist/prod/core/constants.js +23 -4
  43. package/dist/prod/core/context.js +3 -3
  44. package/dist/prod/core/core.js +521 -353
  45. package/dist/prod/core/effect.js +66 -66
  46. package/dist/prod/core/error.js +5 -3
  47. package/dist/prod/core/external.js +5 -6
  48. package/dist/prod/core/graph.js +56 -42
  49. package/dist/prod/core/heap.js +38 -38
  50. package/dist/prod/core/identities.js +62 -0
  51. package/dist/prod/core/lanes.js +237 -224
  52. package/dist/prod/core/owner.js +62 -51
  53. package/dist/prod/core/scheduler.js +312 -158
  54. package/dist/prod/core/truth.js +45 -0
  55. package/dist/prod/core/verdict.js +113 -63
  56. package/dist/prod/deferred.js +182 -0
  57. package/dist/prod/index.js +7 -1
  58. package/dist/prod/map.js +366 -281
  59. package/dist/prod/reveal.js +77 -77
  60. package/dist/prod/signals.js +59 -38
  61. package/dist/prod/store/affects.js +76 -69
  62. package/dist/prod/store/edges.js +39 -0
  63. package/dist/prod/store/hooks.js +13 -0
  64. package/dist/prod/store/index.js +0 -2
  65. package/dist/prod/store/optimistic.js +121 -84
  66. package/dist/prod/store/projection.js +46 -34
  67. package/dist/prod/store/reconcile.js +32 -30
  68. package/dist/prod/store/store.js +205 -116
  69. package/dist/types/affects-marks.d.ts +14 -0
  70. package/dist/types/boundaries.d.ts +5 -1
  71. package/dist/types/core/async.d.ts +10 -0
  72. package/dist/types/core/attribution.d.ts +6 -2
  73. package/dist/types/core/constants.d.ts +18 -1
  74. package/dist/types/core/core.d.ts +77 -5
  75. package/dist/types/core/dev.d.ts +43 -13
  76. package/dist/types/core/graph.d.ts +11 -0
  77. package/dist/types/core/identities.d.ts +17 -0
  78. package/dist/types/core/index.d.ts +2 -1
  79. package/dist/types/core/lanes.d.ts +2 -4
  80. package/dist/types/core/owner.d.ts +5 -3
  81. package/dist/types/core/scheduler.d.ts +59 -34
  82. package/dist/types/core/truth.d.ts +16 -0
  83. package/dist/types/core/types.d.ts +21 -6
  84. package/dist/types/core/verdict.d.ts +32 -0
  85. package/dist/types/deferred.d.ts +28 -0
  86. package/dist/types/index.d.ts +6 -0
  87. package/dist/types/map.d.ts +2 -2
  88. package/dist/types/signals.d.ts +28 -7
  89. package/dist/types/store/affects.d.ts +11 -0
  90. package/dist/types/store/edges.d.ts +9 -0
  91. package/dist/types/store/hooks.d.ts +48 -0
  92. package/dist/types/store/index.d.ts +10 -4
  93. package/dist/types/store/optimistic.d.ts +3 -2
  94. package/dist/types/store/projection.d.ts +4 -3
  95. package/dist/types/store/store.d.ts +4 -39
  96. package/dist/types/store/target.d.ts +16 -8
  97. package/dist/types/store/types.d.ts +14 -0
  98. package/package.json +1 -1
@@ -1,10 +1,10 @@
1
- import { GlobalQueue } from "../core/scheduler.js";
1
+ import { GlobalQueue, releaseMarksHook } from "../core/scheduler.js";
2
2
 
3
- import { installAffectsHooks, getNode, optHooks } from "./store.js";
3
+ import { optHooks, installAffectsHooks } from "./hooks.js";
4
4
 
5
5
  import { lookupTarget, $OWNER } from "./target.js";
6
6
 
7
- import { isWrappable, $TARGET } from "./types.js";
7
+ import { $TARGET } from "./types.js";
8
8
 
9
9
  /**
10
10
  * Store — the store half of `affects()` (plan sec. 29, plan sec. 37; A24 (4), #2882,
@@ -23,113 +23,120 @@ import { isWrappable, $TARGET } from "./types.js";
23
23
  * the verdict. A mark declared on a draft (inside a setter) or over an
24
24
  * optimistic family walks the view the writer sees.
25
25
  *
26
- * Installed by `store/index.ts`: a program with stores carries it; one
27
- * without pays nothing (affects.ts asks `GlobalQueue._storeMarks`).
26
+ * Imported by `affects()`, which installs it on its first store target
27
+ * (#3891, after #3912): a program with stores that never declares a mark
28
+ * carries none of it. It never imports store.ts — the engine's top level —
29
+ * so a program declaring marks without stores carries this module alone:
30
+ * the store's nodes and its wrappability test come through `GlobalQueue`
31
+ * (`_storeNode`, `_storeWrappable`), and node birth and the untracked traps
32
+ * reach back through `affectsHooks` (hooks.ts).
28
33
  */
29
34
  /** The keyless mark's carrier key: a leaf of the record no read serves. */ const $AFFECTS = Symbol(0);
30
35
 
31
36
  const scopes = new Map;
32
37
 
38
+ function scopeOf(e, o) {
39
+ let n = scopes.get(e);
40
+ if (n === undefined) scopes.set(e, n = {
41
+ eo: new Set,
42
+ oo: [],
43
+ ze: o
44
+ });
45
+ return n;
46
+ }
47
+
33
48
  /** The nodes an `affects(store[, key])` declaration marks (affects.ts
34
- * registers each). */ function storeMarks(e, n) {
35
- if (n === undefined) {
36
- const n = getNode(e, $AFFECTS);
37
- let o = scopes.get(n);
38
- if (o === undefined) scopes.set(n, o = {
39
- scope: new Set,
40
- inherited: []
41
- });
42
- const t = [ n ];
43
- walk(e.px, o, t, e.fam, new Set);
44
- return t;
49
+ * registers each). */ function storeMarks(e, o) {
50
+ const n = GlobalQueue.no(e, o === undefined ? $AFFECTS : o);
51
+ const t = scopeOf(n, o);
52
+ if (o === undefined) {
53
+ const o = [ n ];
54
+ walk(e.px, t, o, e.fam, new Set);
55
+ return o;
45
56
  }
46
- const o = e.n?.[n] ?? getNode(e, n);
47
- let t = scopes.get(o);
48
- if (t === undefined) scopes.set(o, t = {
49
- scope: new Set,
50
- inherited: [],
51
- key: n
52
- });
53
- t.scope.add(e.v);
54
- if (e.pb !== null) t.scope.add(e.pb);
55
- return [ o ];
57
+ t.eo.add(e.v);
58
+ if (e.pb !== null) t.eo.add(e.pb);
59
+ return [ n ];
56
60
  }
57
61
 
58
62
  /** The identities reachable from `value` into the scope (the draft's and
59
63
  * the committed backing both, when a draft is open; an optimistic family's
60
64
  * view), every live node under each record into `found`. Untracked by
61
- * construction: raws, never traps. */ function walk(e, n, o, t, s) {
62
- if (!isWrappable(e)) return;
65
+ * construction: raws, never traps. */ function walk(e, o, n, t, s) {
66
+ if (!GlobalQueue.so(e)) return;
63
67
  const f = e[$TARGET] ?? lookupTarget(e, t);
64
- let i = f !== undefined ? f.pb ?? f.v : e;
65
- if (s.has(i)) return;
66
- s.add(i);
67
- n.scope.add(i);
68
+ let r = f !== undefined ? f.pb ?? f.v : e;
69
+ if (s.has(r)) return;
70
+ s.add(r);
71
+ o.eo.add(r);
68
72
  if (f !== undefined) {
69
- if (f.pb !== null) n.scope.add(f.v);
73
+ if (f.pb !== null) o.eo.add(f.v);
70
74
  // The writer's view: the tick's own unflushed guesses are in motion too.
71
- if (f.fam?.opt === true) i = optHooks.view(f, i, true);
75
+ if (f.fam?.opt === true) r = optHooks.view(f, r, true);
72
76
  const e = f.n;
73
- if (e !== null) for (const n of Reflect.ownKeys(e))
77
+ if (e !== null) for (const o of Reflect.ownKeys(e))
74
78
  // Another mark's carrier is its own channel: counting it here would
75
79
  // extend that scope's lifetime to this declaration's.
76
- if (n !== $AFFECTS) o.push(e[n]);
80
+ if (o !== $AFFECTS) n.push(e[o]);
77
81
  const s = f.h;
78
- if (s !== null) for (const e of Reflect.ownKeys(s)) o.push(s[e]);
79
- if (f.k !== null) o.push(f.k);
80
- if (f.dk !== null) o.push(f.dk);
82
+ if (s !== null) for (const e of Reflect.ownKeys(s)) n.push(s[e]);
83
+ if (f.k !== null) n.push(f.k);
84
+ if (f.dk !== null) n.push(f.dk);
81
85
  t = f.fam ?? t;
82
86
  }
83
- for (const e of Reflect.ownKeys(i)) {
84
- if (e === $OWNER) continue;
85
- const f = Object.getOwnPropertyDescriptor(i, e);
86
- if (f === undefined || f.get !== undefined) continue;
87
- walk(f.value, n, o, t, s);
87
+ for (const e of Reflect.ownKeys(r)) if (e !== $OWNER) {
88
+ const f = Object.getOwnPropertyDescriptor(r, e);
89
+ if (f.get === undefined) walk(f.value, o, n, t, s);
88
90
  }
89
91
  }
90
92
 
91
93
  /** A live scope covering `t`'s identity (keyed: for `key`). Chained
92
94
  * backings (§7b): a view's backing is another store's proxy — marks cover
93
- * the BASE raw, so every identity along the chain is checked. */ function covering(e, n, o) {
95
+ * the BASE raw, so every identity along the chain is checked. */ function covering(e, o, n) {
94
96
  for (const [t, s] of scopes) {
95
- if (t === o || s.key !== undefined && s.key !== n) continue;
96
- for (let n = e.v; ;) {
97
- if (s.scope.has(n)) return t;
98
- const e = n?.[$TARGET];
97
+ if (t === n || s.ze !== undefined && s.ze !== o) continue;
98
+ for (let o = e.v; ;) {
99
+ if (s.eo.has(o)) return t;
100
+ const e = o?.[$TARGET];
99
101
  if (e === undefined) break;
100
- const o = e.pb ?? e.v;
101
- if (o === n) break;
102
- n = o;
102
+ const n = e.pb ?? e.v;
103
+ if (n === o) break;
104
+ o = n;
103
105
  }
104
106
  }
105
107
  return null;
106
108
  }
107
109
 
108
- installAffectsHooks({
110
+ /** The store's side: node birth and the untracked traps call it (store.ts,
111
+ * through `affectsHooks`) — with no live mark too: an empty scope map is
112
+ * no work. */ const hooks = {
109
113
  // A node born on a record a live mark covers inherits it (released with
110
114
  // the carrier's last registration).
111
- born(e, n, o) {
112
- if (o === $AFFECTS) return;
113
- const t = covering(e, o, n);
114
- if (t === null) return;
115
- GlobalQueue.h(n);
116
- scopes.get(t).inherited.push(n);
115
+ fo(e, o, n) {
116
+ if (scopes.size === 0 || n === $AFFECTS) return;
117
+ const t = covering(e, n, o);
118
+ if (!t) return;
119
+ GlobalQueue.N(o);
120
+ scopes.get(t).oo.push(o);
117
121
  },
118
122
  // An untracked probe (`isPending(() => s.x)` with no observer) reading a
119
123
  // record a live mark covers: no node carries the mark for it — the
120
124
  // verdict is told directly.
121
- witness(e, n) {
122
- const o = e.n?.[$AFFECTS];
123
- if (o !== undefined && o.m !== null && o.m.T !== 0 || covering(e, n) !== null) GlobalQueue.dt();
125
+ ro(e, o) {
126
+ if (e.n?.[$AFFECTS]?.T?.I || covering(e, o)) GlobalQueue.rt();
124
127
  }
125
- });
128
+ };
126
129
 
127
- GlobalQueue.O = storeMarks;
130
+ /** `affects()` calls it before a store-targeted declaration (idempotent). */ function installStoreAffects() {
131
+ installAffectsHooks(hooks);
132
+ }
128
133
 
129
134
  /** The carrier's last mark released (affects.ts): its scope dies, and the
130
- * nodes that inherited the mark release theirs. */ GlobalQueue.N = e => {
131
- const n = scopes.get(e);
132
- if (n === undefined) return;
135
+ * nodes that inherited the mark release theirs. */ function releaseMarkScope(e) {
136
+ const o = scopes.get(e);
137
+ if (o === undefined) return;
133
138
  scopes.delete(e);
134
- GlobalQueue.A(n.inherited);
135
- };
139
+ releaseMarksHook(o.oo);
140
+ }
141
+
142
+ export { installStoreAffects, releaseMarkScope, storeMarks };
@@ -0,0 +1,39 @@
1
+ import { CONFIG_SLOT_NODE } from "../core/constants.js";
2
+
3
+ import { signalName } from "../core/identities.js";
4
+
5
+ import { $TARGET } from "./types.js";
6
+
7
+ /**
8
+ * Deferred hydration, dependency edges for stores. Only the frames client
9
+ * imports this module, so nothing here ships without it.
10
+ *
11
+ * A plain store root (`createStore` over an object) is named like a plain
12
+ * signal (core/identities.ts: `<owner id>~<n>`, on the same count), and the
13
+ * whole store goes by that one name: the server records it for any read of
14
+ * the store, at any depth, and a setter call on the store — on its root or
15
+ * on a proxy nested in it — is a write to it. Its readers mount at the
16
+ * setter's entry, before the draft runs, as a plain signal's do.
17
+ */
18
+ /**
19
+ * @internal The name of the store `x` belongs to — `x` a store proxy (a
20
+ * setter's entry) or one of its property nodes (the setter notifying it) —
21
+ * or undefined when it has none or it cannot be placed: a projection or
22
+ * optimistic family, a store chained over another store's proxy, a root
23
+ * named twice, or a proxy reached through a store other than the one it
24
+ * was named as the root of.
25
+ */ function storeName(e) {
26
+ if (e === undefined) return undefined;
27
+ let n = e.l & CONFIG_SLOT_NODE ? e.O : e[$TARGET];
28
+ if (n === undefined) return undefined;
29
+ // Up to the root; a target on the way named as a root of its own is one
30
+ // object in two stores.
31
+ while (n.u !== null) {
32
+ if (n.fam !== null || n.ch || signalName(n) !== undefined) return undefined;
33
+ n = n.u;
34
+ }
35
+ if (n.fam !== null || n.ch) return undefined;
36
+ return signalName(n) || undefined;
37
+ }
38
+
39
+ export { storeName };
@@ -0,0 +1,13 @@
1
+ let optHooks = null;
2
+
3
+ function installOptHooks(o) {
4
+ optHooks = o;
5
+ }
6
+
7
+ let affectsHooks = null;
8
+
9
+ function installAffectsHooks(o) {
10
+ affectsHooks = o;
11
+ }
12
+
13
+ export { affectsHooks, installAffectsHooks, installOptHooks, optHooks };
@@ -2,8 +2,6 @@ import { createStore as createStore$1, deep as deep$1, snapshot as snapshot$1 }
2
2
 
3
3
  export { storeHasFamily, storeHasOptimisticFamily, storeIsShallow } from "./store.js";
4
4
 
5
- import "./affects.js";
6
-
7
5
  export { createOptimisticStore } from "./optimistic.js";
8
6
 
9
7
  import { createStoreDerived } from "./projection.js";