@solidjs/signals 2.0.0-rc.1 → 2.0.0-rc.11

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 (150) hide show
  1. package/dist/dev-shared.js +7155 -0
  2. package/dist/dev.attribution.js +3307 -0
  3. package/dist/dev.js +5765 -4496
  4. package/dist/observe/affects.js +129 -0
  5. package/dist/observe/attribution.js +7 -0
  6. package/dist/observe/boundaries.js +793 -0
  7. package/dist/observe/core/action.js +177 -0
  8. package/dist/observe/core/async.js +849 -0
  9. package/dist/observe/core/attribution-costs.js +66 -0
  10. package/dist/observe/core/attribution-feedback.js +280 -0
  11. package/dist/observe/core/attribution-hooks.js +83 -0
  12. package/dist/observe/core/attribution-queries.js +43 -0
  13. package/dist/observe/core/attribution.js +2904 -0
  14. package/dist/observe/core/constants.js +283 -0
  15. package/dist/{types-cjs/core/context.d.cts → observe/core/context.js} +37 -12
  16. package/dist/observe/core/core.js +1999 -0
  17. package/dist/observe/core/dev.js +343 -0
  18. package/dist/observe/core/effect.js +200 -0
  19. package/dist/observe/core/error-hooks.js +71 -0
  20. package/dist/observe/core/error.js +80 -0
  21. package/dist/observe/core/external.js +98 -0
  22. package/dist/observe/core/graph.js +155 -0
  23. package/dist/observe/core/heap.js +147 -0
  24. package/dist/observe/core/invariants.js +45 -0
  25. package/dist/observe/core/lanes.js +205 -0
  26. package/dist/observe/core/optimistic.js +669 -0
  27. package/dist/observe/core/owner.js +353 -0
  28. package/dist/observe/core/scheduler.js +1561 -0
  29. package/dist/observe/core/verdict.js +674 -0
  30. package/dist/observe/index.js +59 -0
  31. package/dist/observe/map.js +507 -0
  32. package/dist/observe/signals.js +731 -0
  33. package/dist/observe/store/index.js +44 -0
  34. package/dist/observe/store/next/optimistic.js +717 -0
  35. package/dist/observe/store/next/projection.js +266 -0
  36. package/dist/observe/store/next/reconcile.js +375 -0
  37. package/dist/observe/store/next/store.js +2480 -0
  38. package/dist/observe/store/next/target.js +51 -0
  39. package/dist/observe/store/store.js +331 -0
  40. package/dist/observe/store/storePath.js +103 -0
  41. package/dist/observe/store/utils.js +1070 -0
  42. package/dist/prod/affects.js +10 -9
  43. package/dist/prod/attribution.js +45 -0
  44. package/dist/prod/boundaries.js +388 -178
  45. package/dist/prod/core/action.js +65 -37
  46. package/dist/prod/core/async.js +378 -163
  47. package/dist/prod/core/attribution-hooks.js +3 -0
  48. package/dist/prod/core/constants.js +186 -1
  49. package/dist/prod/core/context.js +10 -16
  50. package/dist/prod/core/core.js +1546 -416
  51. package/dist/prod/core/dev.js +18 -1
  52. package/dist/prod/core/effect.js +119 -79
  53. package/dist/prod/core/error-hooks.js +71 -0
  54. package/dist/prod/core/error.js +13 -1
  55. package/dist/prod/core/external.js +4 -4
  56. package/dist/prod/core/graph.js +105 -54
  57. package/dist/prod/core/heap.js +72 -65
  58. package/dist/prod/core/invariants.js +3 -2
  59. package/dist/prod/core/lanes.js +117 -52
  60. package/dist/prod/core/optimistic.js +500 -104
  61. package/dist/prod/core/owner.js +131 -84
  62. package/dist/prod/core/scheduler.js +1012 -241
  63. package/dist/prod/core/verdict.js +417 -112
  64. package/dist/prod/index.js +20 -8
  65. package/dist/prod/map.js +355 -171
  66. package/dist/prod/signals.js +363 -32
  67. package/dist/prod/store/index.js +2 -0
  68. package/dist/prod/store/next/optimistic.js +530 -197
  69. package/dist/prod/store/next/projection.js +142 -57
  70. package/dist/prod/store/next/reconcile.js +149 -103
  71. package/dist/prod/store/next/store.js +1470 -346
  72. package/dist/prod/store/next/target.js +40 -9
  73. package/dist/prod/store/store.js +23 -19
  74. package/dist/prod/store/utils.js +997 -130
  75. package/dist/types/attribution.d.ts +19 -0
  76. package/dist/types/attribution.prod.d.ts +22 -0
  77. package/dist/types/boundaries.d.ts +78 -5
  78. package/dist/types/core/action.d.ts +12 -5
  79. package/dist/types/core/async.d.ts +3 -1
  80. package/dist/types/core/attribution-costs.d.ts +35 -0
  81. package/dist/types/core/attribution-feedback.d.ts +133 -0
  82. package/dist/types/core/attribution-hooks.d.ts +304 -0
  83. package/dist/types/core/attribution-queries.d.ts +24 -0
  84. package/dist/types/core/attribution.d.ts +892 -0
  85. package/dist/types/core/constants.d.ts +179 -0
  86. package/dist/types/core/core.d.ts +299 -25
  87. package/dist/types/core/dev.d.ts +421 -8
  88. package/dist/types/core/effect.d.ts +8 -1
  89. package/dist/types/core/error-hooks.d.ts +71 -0
  90. package/dist/types/core/error.d.ts +9 -0
  91. package/dist/types/core/graph.d.ts +23 -0
  92. package/dist/types/core/heap.d.ts +5 -3
  93. package/dist/types/core/index.d.ts +6 -3
  94. package/dist/types/core/invariants.d.ts +5 -1
  95. package/dist/types/core/lanes.d.ts +51 -19
  96. package/dist/types/core/owner.d.ts +15 -3
  97. package/dist/types/core/scheduler.d.ts +252 -1
  98. package/dist/types/core/types.d.ts +124 -41
  99. package/dist/types/index.d.ts +18 -5
  100. package/dist/types/map.d.ts +2 -0
  101. package/dist/types/signals.d.ts +145 -13
  102. package/dist/types/store/index.d.ts +7 -6
  103. package/dist/types/store/next/optimistic.d.ts +18 -13
  104. package/dist/types/store/next/projection.d.ts +5 -2
  105. package/dist/types/store/next/reconcile.d.ts +7 -0
  106. package/dist/types/store/next/store.d.ts +83 -11
  107. package/dist/types/store/next/target.d.ts +108 -11
  108. package/dist/types/store/store.d.ts +20 -11
  109. package/dist/types/store/utils.d.ts +188 -0
  110. package/package.json +31 -26
  111. package/dist/node.cjs +0 -8137
  112. package/dist/types/store/optimistic.d.ts +0 -45
  113. package/dist/types/store/projection.d.ts +0 -70
  114. package/dist/types/store/reconcile.d.ts +0 -46
  115. package/dist/types-cjs/affects.d.cts +0 -47
  116. package/dist/types-cjs/boundaries.d.cts +0 -175
  117. package/dist/types-cjs/core/action.d.cts +0 -64
  118. package/dist/types-cjs/core/async.d.cts +0 -21
  119. package/dist/types-cjs/core/constants.d.cts +0 -71
  120. package/dist/types-cjs/core/core.d.cts +0 -156
  121. package/dist/types-cjs/core/dev.d.cts +0 -64
  122. package/dist/types-cjs/core/effect.d.cts +0 -30
  123. package/dist/types-cjs/core/error.d.cts +0 -47
  124. package/dist/types-cjs/core/external.d.cts +0 -15
  125. package/dist/types-cjs/core/graph.d.cts +0 -5
  126. package/dist/types-cjs/core/heap.d.cts +0 -22
  127. package/dist/types-cjs/core/index.d.cts +0 -13
  128. package/dist/types-cjs/core/invariants.d.cts +0 -59
  129. package/dist/types-cjs/core/lanes.d.cts +0 -56
  130. package/dist/types-cjs/core/optimistic.d.cts +0 -6
  131. package/dist/types-cjs/core/owner.d.cts +0 -124
  132. package/dist/types-cjs/core/scheduler.d.cts +0 -172
  133. package/dist/types-cjs/core/types.d.cts +0 -148
  134. package/dist/types-cjs/core/verdict.d.cts +0 -2
  135. package/dist/types-cjs/index.d.cts +0 -10
  136. package/dist/types-cjs/map.d.cts +0 -69
  137. package/dist/types-cjs/package.json +0 -3
  138. package/dist/types-cjs/signals.d.cts +0 -624
  139. package/dist/types-cjs/store/index.d.cts +0 -19
  140. package/dist/types-cjs/store/next/optimistic.d.cts +0 -20
  141. package/dist/types-cjs/store/next/projection.d.cts +0 -24
  142. package/dist/types-cjs/store/next/reconcile.d.cts +0 -3
  143. package/dist/types-cjs/store/next/store.d.cts +0 -71
  144. package/dist/types-cjs/store/next/target.d.cts +0 -99
  145. package/dist/types-cjs/store/optimistic.d.cts +0 -45
  146. package/dist/types-cjs/store/projection.d.cts +0 -70
  147. package/dist/types-cjs/store/reconcile.d.cts +0 -46
  148. package/dist/types-cjs/store/store.d.cts +0 -138
  149. package/dist/types-cjs/store/storePath.d.cts +0 -58
  150. package/dist/types-cjs/store/utils.d.cts +0 -74
@@ -0,0 +1,59 @@
1
+ export { ContextNotFoundError, NoOwnerError, NotReadyError, TimeoutError } from "./core/error.js";
2
+
3
+ export { clearSnapshots, isEqual, markSnapshotScope, releaseSnapshotScope, runWithOwner, setSnapshotCapture, untrack } from "./core/core.js";
4
+
5
+ export { enableExternalSource } from "./core/external.js";
6
+
7
+ export { createOwner, createRoot, getNextChildId, getObserver, getOwner, isDisposed, peekNextChildId } from "./core/owner.js";
8
+
9
+ export { createContext, getContext, setContext } from "./core/context.js";
10
+
11
+ export { $REFRESH, SUPPORTS_PROXY } from "./core/constants.js";
12
+
13
+ import "./core/invariants.js";
14
+
15
+ import { OBSERVE as OBSERVE$1 } from "./core/dev.js";
16
+
17
+ export { setConsoleFooter } from "./core/dev.js";
18
+
19
+ export { ROOT_ERROR_HOOK, enforceLoadingBoundary, flush, resetErrorHalt } from "./core/scheduler.js";
20
+
21
+ export { isPending, latest } from "./core/verdict.js";
22
+
23
+ import "./core/effect.js";
24
+
25
+ export { action } from "./core/action.js";
26
+
27
+ export { configureClientErrors } from "./core/error-hooks.js";
28
+
29
+ export { createEffect, createMemo, createOptimistic, createReaction, createRenderEffect, createSignal, createTrackedEffect, onCleanup, onSettled, refresh, resolve, until } from "./signals.js";
30
+
31
+ export { affects } from "./affects.js";
32
+
33
+ export { mapArray, repeat } from "./map.js";
34
+
35
+ export { createStore, deep, reconcile, snapshot } from "./store/index.js";
36
+
37
+ export { createErrorBoundary, createLoadingBoundary, createRevealOrder, flatten } from "./boundaries.js";
38
+
39
+ export { $PROXY, $RECORD, $TARGET, $TRACK, isWrappable } from "./store/store.js";
40
+
41
+ export { MergeView, OmitView, SOURCE_MEMO, SOURCE_MERGE, SOURCE_OMIT, SOURCE_PLAIN, SOURCE_PROXY, hasStaticKeys, isStatic, merge, mergeSources, mergeView, omit, omitView, resolvedTable, sourceGet, sourceHas, sourceKeys, sourceOwners, viewOf } from "./store/utils.js";
42
+
43
+ export { createOptimisticStoreNext as createOptimisticStore } from "./store/next/optimistic.js";
44
+
45
+ export { createProjectionNext as createProjection } from "./store/next/projection.js";
46
+
47
+ export { storeHasFamily, storeHasOptimisticFamily, storeIsShallow } from "./store/next/store.js";
48
+
49
+ export { storePath } from "./store/storePath.js";
50
+
51
+ /**
52
+ * Observe tier (diagnostics channel, attribution hook slot + interaction
53
+ * frame): dev and observe builds. The attribution engine itself is the
54
+ * `@solidjs/signals/attribution` entry.
55
+ */ const OBSERVE = OBSERVE$1;
56
+
57
+ /** Dev tier (devtools hooks, graph traversal, console reporting): dev builds only. */ const DEV = undefined;
58
+
59
+ export { DEV, OBSERVE };
@@ -0,0 +1,507 @@
1
+ import { computed, runWithOwner, signal, currentOptimisticLane, setSignal } from "./core/core.js";
2
+
3
+ import { activeLanes } from "./core/lanes.js";
4
+
5
+ import { createOwner } from "./core/owner.js";
6
+
7
+ import { GlobalQueue } from "./core/scheduler.js";
8
+
9
+ import { CONFIG_AUTO_DISPOSE } from "./core/constants.js";
10
+
11
+ import { attrHooks } from "./core/attribution-hooks.js";
12
+
13
+ import "./core/invariants.js";
14
+
15
+ import "./core/dev.js";
16
+
17
+ import "./core/verdict.js";
18
+
19
+ import "./core/effect.js";
20
+
21
+ import { accessor } from "./signals.js";
22
+
23
+ import { $TRACK } from "./store/store.js";
24
+
25
+ import "./store/next/store.js";
26
+
27
+ function mapArray(t, e, i) {
28
+ const s = typeof i?.keyed === "function" ? i.keyed : undefined;
29
+ const r = e.length > 1;
30
+ const n = e;
31
+ const o = {
32
+ ie: createOwner(),
33
+ oi: 0,
34
+ hi: t,
35
+ fi: [],
36
+ ci: n,
37
+ ai: [],
38
+ ui: [],
39
+ zt: s,
40
+ li: s || i?.keyed === false ? [] : undefined,
41
+ pi: r && i?.keyed !== false ? [] : undefined,
42
+ di: i?.keyed === false,
43
+ mi: i?.fallback
44
+ };
45
+ const h = computed(updateKeyedMap.bind(o), i?.name ? {
46
+ name: i.name
47
+ } : undefined);
48
+ // Untracked reads inside the internal owner resolve via _parentComputed; routing
49
+ // them through node lets store-proxy lookups see pending writes (not stale _value).
50
+ o.ie.Yt = h;
51
+ h.C &= ~CONFIG_AUTO_DISPOSE;
52
+ return accessor(h);
53
+ }
54
+
55
+ const pureOptions = {
56
+ ownedWrite: true
57
+ };
58
+
59
+ function trySmallMove(t, e, i, s) {
60
+ const r = t.fi;
61
+ const n = t.oi - 1;
62
+ const o = [];
63
+ const h = [];
64
+ const f = [];
65
+ // flat triples: oldStart, newStart, length
66
+ let c = 256;
67
+ let a = s;
68
+ let u = s;
69
+ let l = false;
70
+ while (a <= n && u <= i - 1) {
71
+ const t = r[a];
72
+ const s = e[u];
73
+ if (t === s) {
74
+ if (!l) {
75
+ f.push(a, u, 0);
76
+ l = true;
77
+ }
78
+ f[f.length - 1]++;
79
+ a++;
80
+ u++;
81
+ continue;
82
+ }
83
+ l = false;
84
+ // Bounded realignment lookahead, shorter distance wins.
85
+ let p = -1;
86
+ let d = Math.min(32 - o.length, n - a, c);
87
+ for (let t = 1; t <= d; t++) {
88
+ if (r[a + t] === s) {
89
+ p = t;
90
+ break;
91
+ }
92
+ }
93
+ c -= p === -1 ? d : p;
94
+ let m = -1;
95
+ d = Math.min(32 - h.length, i - 1 - u, c);
96
+ for (let i = 1; i <= d; i++) {
97
+ if (e[u + i] === t) {
98
+ m = i;
99
+ break;
100
+ }
101
+ }
102
+ c -= m === -1 ? d : m;
103
+ if (p !== -1 && (m === -1 || p <= m)) {
104
+ while (p-- > 0) o.push(a++);
105
+ continue;
106
+ }
107
+ if (m !== -1) {
108
+ while (m-- > 0) h.push(u++);
109
+ continue;
110
+ }
111
+ if (c <= 0 || o.length === 32 || h.length === 32) return false;
112
+ o.push(a++);
113
+ h.push(u++);
114
+ }
115
+ for (;a <= n; a++) {
116
+ if (o.length === 32) return false;
117
+ o.push(a);
118
+ }
119
+ for (;u <= i - 1; u++) {
120
+ if (h.length === 32) return false;
121
+ h.push(u);
122
+ }
123
+ return commitSmallMove(t, e, i, o, h, f);
124
+ }
125
+
126
+ /** PHASE 2 of the small-move path, in its OWN function so that a pass which
127
+ * only SCANS and bails (a full replace: the first structural pass of a page,
128
+ * typically) compiles nothing but the scan — V8 parses and compiles lazily
129
+ * per function, and cold `replace` measured +0.5 ms with both phases in one
130
+ * body. Pairs displaced sources with destinations (an unmatched destination
131
+ * is a replacement/insertion → general path), then commits: slice() the live
132
+ * arrays, copy shifted runs, patch displaced pairs, dispose leftovers. */ function commitSmallMove(t, e, i, s, r, n) {
133
+ const o = t.fi;
134
+ let h;
135
+ let f;
136
+ let c;
137
+ if (r.length !== 0) {
138
+ c = new Array(s.length);
139
+ for (f = 0; f < r.length; f++) {
140
+ let t = -1;
141
+ for (h = 0; h < s.length; h++) {
142
+ if (!c[h] && o[s[h]] === e[r[f]]) {
143
+ t = h;
144
+ break;
145
+ }
146
+ }
147
+ if (t === -1) return false;
148
+ c[t] = true;
149
+ r[f] = r[f] << 6 | t;
150
+ // pack pairing (found < 32)
151
+ }
152
+ }
153
+ // DUPLICATES: the general path pairs equal identities by OCCURRENCE ORDER
154
+ // (the chained index map). Displaced↔displaced pairing above is ascending
155
+ // on both sides, so it agrees; but an aligned run was matched by POSITION,
156
+ // and if a displaced identity also occurs inside a run the two algorithms
157
+ // can hand different occurrences different owners (row-local state moves;
158
+ // a shrink could dispose the wrong one). Decline that case — general path.
159
+ if (s.length !== 0 || r.length !== 0) {
160
+ const t = new Set;
161
+ for (h = 0; h < s.length; h++) t.add(o[s[h]]);
162
+ for (f = 0; f < r.length; f++) t.add(e[r[f] >> 6]);
163
+ for (let e = 0; e < n.length; e += 3) {
164
+ const i = n[e];
165
+ for (let s = 0, r = n[e + 2]; s < r; s++) if (t.has(o[i + s])) return false;
166
+ }
167
+ }
168
+ const a = t.ai;
169
+ const u = t.ui;
170
+ const l = a.slice(0, i);
171
+ const p = u.slice(0, i);
172
+ for (let t = 0; t < n.length; t += 3) {
173
+ const e = n[t];
174
+ const i = n[t + 1];
175
+ if (e !== i) {
176
+ for (let s = 0; s < n[t + 2]; s++) {
177
+ l[i + s] = a[e + s];
178
+ p[i + s] = u[e + s];
179
+ }
180
+ }
181
+ }
182
+ for (f = 0; f < r.length; f++) {
183
+ const t = r[f] >> 6;
184
+ const e = s[r[f] & 63];
185
+ l[t] = a[e];
186
+ p[t] = u[e];
187
+ }
188
+ t.ai = l;
189
+ t.ui = p;
190
+ t.oi = i;
191
+ t.fi = e.slice(0);
192
+ // Dispose unmatched sources LAST (general-path ordering).
193
+ for (h = 0; h < s.length; h++) {
194
+ if (c === undefined || !c[h]) u[s[h]].dispose();
195
+ }
196
+ return true;
197
+ }
198
+
199
+ function updateKeyedMap() {
200
+ const t = this.hi() || [], e = t.length;
201
+ t[$TRACK];
202
+ // top level tracking
203
+ runWithOwner(this.ie, () => {
204
+ let i, s, r, n,
205
+ // Mappers write freshly-created row/index signals into the STAGE
206
+ // arrays (`rows`/`indexes`), never into `this._rows`/`this._indexes`.
207
+ o = this.li ? this.di ? () => {
208
+ r[s] = signal(t[s], pureOptions);
209
+ return this.ci(accessor(r[s]), s);
210
+ } : () => {
211
+ r[s] = signal(t[s], pureOptions);
212
+ n && (n[s] = signal(s, pureOptions));
213
+ return this.ci(accessor(r[s]), n ? accessor(n[s]) : undefined);
214
+ } : this.pi ? () => {
215
+ const e = t[s];
216
+ n[s] = signal(s, pureOptions);
217
+ return this.ci(e, accessor(n[s]));
218
+ } : () => {
219
+ const e = t[s];
220
+ return this.ci(e);
221
+ };
222
+ // fast path for empty arrays
223
+ if (e === 0) {
224
+ if (this.oi !== 0) {
225
+ this.ie.dispose(false);
226
+ this.ui = [];
227
+ this.fi = [];
228
+ this.ai = [];
229
+ this.oi = 0;
230
+ this.li && (this.li = []);
231
+ this.pi && (this.pi = []);
232
+ }
233
+ if (this.mi && !this.ai[0]) {
234
+ // an aborted fallback attempt leaves an owner without a mapping;
235
+ // dispose it before re-creating
236
+ this.ui[0]?.dispose();
237
+ this.ai[0] = runWithOwner(this.ui[0] = createOwner(), this.mi);
238
+ }
239
+ }
240
+ // fast path for new create
241
+ else if (this.oi === 0) {
242
+ const h = new Array(e);
243
+ const f = new Array(e);
244
+ r = this.li && new Array(e);
245
+ n = this.pi && new Array(e);
246
+ try {
247
+ for (s = 0; s < e; s++) h[s] = runWithOwner(f[s] = createOwner(), o);
248
+ } catch (t) {
249
+ for (i = 0; i <= s; i++) f[i]?.dispose();
250
+ throw t;
251
+ }
252
+ // commit
253
+ if (this.ui[0]) this.ui[0].dispose();
254
+ // previous fallback
255
+ this.ai = h;
256
+ this.ui = f;
257
+ r && (this.li = r);
258
+ n && (this.pi = n);
259
+ this.fi = t.slice(0);
260
+ this.oi = e;
261
+ } else {
262
+ let h, f, c, a, u, l, p, d, m,
263
+ // Dev (attribution engine installed): the items behind the exited and
264
+ // entered rows, for the list-identity census.
265
+ w, O;
266
+ // The pass's write to a per-slot signal (a row accessor in index mode,
267
+ // an index accessor in keyed mode). The list's frame lives in these
268
+ // writes as much as in the computed's result, so under a LANE pass they
269
+ // are the lane's frame too (F1): a plain `setSignal` staged them into
270
+ // the action's transaction and the row readers were served the
271
+ // committed value until the action landed — `<For>` without `keyed`
272
+ // showed the pre-action list for the whole action while the keyed modes
273
+ // showed the optimistic one. The engine publishes the write as a
274
+ // derived override on the slot (lanes stage, A17) and lands or
275
+ // supersedes it when a plain pass later writes a slot still carrying
276
+ // one (A18) — `landOnOverride`'s slot arm. Decided once per pass, not
277
+ // per slot: a lane pass marks the map (`_laneSlots`: its slots may
278
+ // carry overrides), a marked map routes every slot write through the
279
+ // engine while any lane is live — a slot's override resolves with its
280
+ // lane's transaction, or with the batch for an orphan lane
281
+ // (resolveOptimisticNodes, then cleanupCompletedLanes, both before the
282
+ // completion wakes any recompute), so a pass that finds no lane live
283
+ // knows the slots are clean and drops the mark — and an unmarked map
284
+ // takes `setSignal` directly. The engine is installed whenever a lane
285
+ // is active.
286
+ const _ = (this.wi = currentOptimisticLane !== null || this.wi && activeLanes.size !== 0) ? GlobalQueue.Vn : setSignal;
287
+ // skip common prefix
288
+ for (h = 0, f = Math.min(this.oi, e); h < f && (this.fi[h] === t[h] || this.li && compare(this.zt, this.fi[h], t[h])); h++) {
289
+ if (this.li) _(this.li[h], t[h]);
290
+ }
291
+ // skip common suffix — counted only; retained entries land in one pass
292
+ // at commit instead of being staged and copied twice
293
+ for (f = this.oi - 1, c = e - 1; f >= h && c >= h && (this.fi[f] === t[c] || this.li && compare(this.zt, this.fi[f], t[c])); f--,
294
+ c--) ;
295
+ // no structural change (every position matched in place at equal
296
+ // length — the common post-reconcile shape): keep the same mapped
297
+ // array identity so downstream consumers don't re-run at all
298
+ if (h === e && this.oi === e) {
299
+ this.fi = t.slice(0);
300
+ return;
301
+ }
302
+ // SMALL-MOVE FAST PATH: extracted to its own function — inlining it
303
+ // here bloats updateKeyedMap past the JIT's optimization budget and
304
+ // deoptimizes the GENERAL path (measured 2x on reverse). Gated to
305
+ // LARGE trimmed windows: when the trims already shrank the window
306
+ // (plain removals, tail edits), the general path is window-
307
+ // proportional and cheap — the fast path would only re-walk what the
308
+ // trims proved.
309
+ if (e <= this.oi && f - h > 64 && this.li === undefined && this.pi === undefined) {
310
+ // PROBE before the scan: a small move keeps a mid-window item within
311
+ // ±32 of its old position; a REPLACE (all fresh items — the shape
312
+ // every page's first structural pass usually is) has it nowhere.
313
+ // ~65 compares, no allocation, and the scan function is never
314
+ // compiled for a replace (its cold first-call compile was the cost).
315
+ const i = h + (c - h >> 1);
316
+ const s = t[i];
317
+ const r = Math.min(f, i + 32);
318
+ let n = Math.max(h, i - 32);
319
+ while (n <= r && this.fi[n] !== s) n++;
320
+ if (n <= r && trySmallMove(this, t, e, h)) return;
321
+ }
322
+ const y = e - this.oi;
323
+ const A = new Array(e);
324
+ const M = new Array(e);
325
+ r = this.li ? new Array(e) : undefined;
326
+ n = this.pi ? new Array(e) : undefined;
327
+ // 0) prepare a map of all indices in the changed window of newItems,
328
+ // scanning backwards so we encounter them in natural order
329
+ l = new Map;
330
+ p = new Array(c + 1);
331
+ for (s = c; s >= h; s--) {
332
+ a = t[s];
333
+ u = this.zt ? this.zt(a) : a;
334
+ i = l.get(u);
335
+ p[s] = i === undefined ? -1 : i;
336
+ l.set(u, s);
337
+ }
338
+ // 1) step through the old changed window and see if items can be found
339
+ // in the new set; if so, stage them at their new positions; if not,
340
+ // queue them for disposal at commit
341
+ for (i = h; i <= f; i++) {
342
+ a = this.fi[i];
343
+ u = this.zt ? this.zt(a) : a;
344
+ s = l.get(u);
345
+ if (s !== undefined && s !== -1) {
346
+ A[s] = this.ai[i];
347
+ M[s] = this.ui[i];
348
+ r && (r[s] = this.li[i]);
349
+ n && (n[s] = this.pi[i]);
350
+ s = p[s];
351
+ l.set(u, s);
352
+ } else {
353
+ (d ??= []).push(this.ui[i]);
354
+ if (true && attrHooks !== null) (w ??= []).push(a);
355
+ }
356
+ }
357
+ // 2) create new rows into the temp arrays; an abort disposes only these
358
+ try {
359
+ for (s = h; s <= c; s++) {
360
+ if (M[s] !== undefined) continue;
361
+ (m ??= []).push(M[s] = createOwner());
362
+ if (true && attrHooks !== null) (O ??= []).push(t[s]);
363
+ A[s] = runWithOwner(M[s], o);
364
+ }
365
+ } catch (t) {
366
+ if (m) for (i = 0; i < m.length; i++) m[i].dispose();
367
+ throw t;
368
+ }
369
+ // 3) commit: land the retained prefix and suffix plus the staged window
370
+ // into the fresh arrays, swap them in (new identity for downstream
371
+ // change propagation), then dispose exited rows
372
+ for (i = 0; i < h; i++) {
373
+ A[i] = this.ai[i];
374
+ M[i] = this.ui[i];
375
+ r && (r[i] = this.li[i]);
376
+ n && (n[i] = this.pi[i]);
377
+ }
378
+ for (s = h; s <= c; s++) {
379
+ if (r) _(r[s], t[s]);
380
+ if (n) _(n[s], s);
381
+ }
382
+ for (s = c + 1; s < e; s++) {
383
+ A[s] = this.ai[s - y];
384
+ M[s] = this.ui[s - y];
385
+ if (r) {
386
+ r[s] = this.li[s - y];
387
+ _(r[s], t[s]);
388
+ }
389
+ if (n) {
390
+ n[s] = this.pi[s - y];
391
+ if (y !== 0) _(n[s], s);
392
+ }
393
+ }
394
+ this.ai = A;
395
+ this.ui = M;
396
+ r && (this.li = r);
397
+ n && (this.pi = n);
398
+ this.oi = e;
399
+ // save a copy of the mapped items for the next update
400
+ this.fi = t.slice(0);
401
+ if (d) for (i = 0; i < d.length; i++) d[i].dispose();
402
+ if (true && attrHooks !== null && w !== undefined && O !== undefined) attrHooks.listChurn(this.ie.Yt, w, O, e, this.zt !== undefined);
403
+ }
404
+ });
405
+ return this.ai;
406
+ }
407
+
408
+ /**
409
+ * Reactively renders a callback `count` times, reusing previously-rendered
410
+ * entries when only the count changes. Underlying helper for `<Repeat>`.
411
+ *
412
+ * - `options.from` — start index (default `0`); useful for offset/windowed
413
+ * rendering.
414
+ * - `options.fallback` — accessor returning a value to show when count is `0`.
415
+ *
416
+ * @example
417
+ * ```ts
418
+ * const view = repeat(count, i => `Item ${i}`, { fallback: () => "empty" });
419
+ * ```
420
+ *
421
+ * @description https://docs.solidjs.com/reference/reactive-utilities/repeat
422
+ */ function repeat(t, e, i) {
423
+ const s = e;
424
+ const r = {
425
+ ie: createOwner(),
426
+ oi: 0,
427
+ Oi: 0,
428
+ _i: t,
429
+ ci: s,
430
+ ui: [],
431
+ ai: [],
432
+ yi: i?.from,
433
+ mi: i?.fallback
434
+ };
435
+ const n = computed(updateRepeat.bind(r));
436
+ // Same as mapArray: untracked reads inside the internal owner resolve via
437
+ // _parentComputed, so async reads in row callbacks register with the node
438
+ // (pending tracking + post-settle retry) instead of vanishing.
439
+ r.ie.Yt = n;
440
+ n.C &= ~CONFIG_AUTO_DISPOSE;
441
+ return accessor(n);
442
+ }
443
+
444
+ // Same staged-commit discipline as `updateKeyedMap` (#2903): the retained
445
+ // window overlap is copied into fresh arrays, missing indexes are created
446
+ // into them, and `this` is only touched — including disposal of rows leaving
447
+ // the window — after every `_map` call succeeded. A NotReadyError mid-pass
448
+ // disposes only the owners this pass created and leaves prior state intact
449
+ // for the post-settle retry. The overlap math also subsumes the previous
450
+ // disjoint-window/front-clear/end-clear/shift special cases.
451
+ function updateRepeat() {
452
+ const t = this._i();
453
+ const e = this.yi?.() || 0;
454
+ runWithOwner(this.ie, () => {
455
+ if (t === 0) {
456
+ if (this.oi !== 0) {
457
+ this.ie.dispose(false);
458
+ this.ui = [];
459
+ this.ai = [];
460
+ this.oi = 0;
461
+ // Reset offset to match the cleared data (#2767, repro 2).
462
+ this.Oi = 0;
463
+ }
464
+ if (this.mi && !this.ai[0]) {
465
+ // an aborted fallback attempt leaves an owner without a mapping;
466
+ // dispose it before re-creating
467
+ this.ui[0]?.dispose();
468
+ this.ai[0] = runWithOwner(this.ui[0] = createOwner(), this.mi);
469
+ }
470
+ return;
471
+ }
472
+ const i = e + t;
473
+ const s = this.Oi + this.oi;
474
+ // Retained overlap [keepStart, keepEnd) in global indexes; empty when the
475
+ // windows are disjoint or when coming from empty/fallback.
476
+ const r = Math.max(e, this.Oi);
477
+ const n = Math.min(i, s);
478
+ const o = new Array(t);
479
+ const h = new Array(t);
480
+ for (let t = r; t < n; t++) {
481
+ h[t - e] = this.ui[t - this.Oi];
482
+ o[t - e] = this.ai[t - this.Oi];
483
+ }
484
+ try {
485
+ for (let t = e; t < i; t++) {
486
+ if (t >= r && t < n) continue;
487
+ o[t - e] = runWithOwner(h[t - e] = createOwner(), () => this.ci(t));
488
+ }
489
+ } catch (t) {
490
+ for (let t = e; t < i; t++) if ((t < r || t >= n) && h[t - e]) h[t - e].dispose();
491
+ throw t;
492
+ }
493
+ // commit: dispose the previous fallback or the rows leaving the window
494
+ if (this.oi === 0) this.ui[0]?.dispose(); else for (let t = this.Oi; t < s; t++) if (t < e || t >= i) this.ui[t - this.Oi].dispose();
495
+ this.ai = o;
496
+ this.ui = h;
497
+ this.Oi = e;
498
+ this.oi = t;
499
+ });
500
+ return this.ai;
501
+ }
502
+
503
+ function compare(t, e, i) {
504
+ return t ? t(e) === t(i) : true;
505
+ }
506
+
507
+ export { mapArray, repeat };