@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,1070 @@
1
+ import "../core/core.js";
2
+
3
+ import { SUPPORTS_PROXY } from "../core/constants.js";
4
+
5
+ import "../core/dev.js";
6
+
7
+ import "../core/scheduler.js";
8
+
9
+ import "../core/invariants.js";
10
+
11
+ import "../core/verdict.js";
12
+
13
+ import "../core/effect.js";
14
+
15
+ import { createMemo } from "../signals.js";
16
+
17
+ import { $PROXY, $RECORD, $TARGET, ownEnumerableKeys } from "./store.js";
18
+
19
+ function trueFn() {
20
+ return true;
21
+ }
22
+
23
+ /** @internal What a source ENTRY is, decided once when the view is built
24
+ * (`merge()` learns it while flattening; `omit()` from its argument) and
25
+ * carried beside the entry — `MergeView.kinds[i]`, `OmitView.kind` — so no
26
+ * read has to ask. Asking is the cost: any brand check on a Proxy is a trap
27
+ * (`instanceof` is a `getPrototypeOf` trap, ~20 ns on a store — as much as
28
+ * the read itself), and a merge over a store did two per read. */ const SOURCE_PLAIN = 0;
29
+
30
+ // a plain object: own keys fixed, data is data
31
+ const SOURCE_OMIT = 1;
32
+
33
+ // an `OmitView` record (only as a merge entry)
34
+ const SOURCE_PROXY = 2;
35
+
36
+ // a store or foreign proxy: everything is a trap
37
+ const SOURCE_MEMO = 3;
38
+
39
+ // a function source (merge's memo): swaps objects
40
+ const SOURCE_MERGE = 4;
41
+
42
+ // a `MergeView` record (only as an omit's source)
43
+ const EMPTY = Object.freeze({});
44
+
45
+ // The object behind a LEAF entry (any kind but OMIT): a memo is read
46
+ // (tracked, as merge's own reads are) and a nullish result has no keys.
47
+ function leafOf(e, n) {
48
+ return n === SOURCE_MEMO ? (e = e()) == null ? EMPTY : e : e;
49
+ }
50
+
51
+ /** @internal The record behind an `omit()` proxy: `source` with `hidden`
52
+ * keys removed. It is the proxy's TARGET, so the shared handler reads it as
53
+ * plain fields — no per-instance closures — and it is what props consumers
54
+ * walk directly (`merge`, `spread`, `ssrElement`): a view never materializes
55
+ * a copy, and a consumer that knows the record never goes through its traps
56
+ * (a `getOwnPropertyDescriptor` trap per key allocates a descriptor and a
57
+ * getter, so enumerating a proxy costs more than the copy it was avoiding).
58
+ * `hidden` is a key list or a predicate (`omit(props, k => k[0] === "$")`).
59
+ *
60
+ * An omit over a `merge()` holds the merge's RECORD (`MergeView`, kind
61
+ * `SOURCE_MERGE`) — never its proxy, so no read hops through a trap — and is
62
+ * one record however many leaves the merge has. A consumer walks it as ONE
63
+ * filtered entry (`sourceKeys` / `sourceGet` recurse into the merge's
64
+ * sources by function call), and a later `merge()` over it carries the
65
+ * record as one entry instead of copying its leaves: on a component chain of
66
+ * defaults + omit + spread (`merge(omit(merge(omit(props))))`) the layers
67
+ * nest as records, each a few fields, where a flatten to leaf views built a
68
+ * view and a combined key list per leaf per layer — the largest allocation
69
+ * of a Kobalte-shaped render. A merge leaf may be merge's memo for a
70
+ * function source; it is resolved on access. */ class OmitView {
71
+ source;
72
+ kind;
73
+ hidden;
74
+ /** see `MergeView.table` */
75
+ table=0;
76
+ /** see `tableOwnKeys` / `tableDescriptor` */
77
+ keys=undefined;
78
+ descs=undefined;
79
+ constructor(e,
80
+ /** of `source` — PLAIN, PROXY (a store or a foreign proxy), MEMO, or
81
+ * MERGE (a `MergeView` record); never OMIT, a view over a view folds
82
+ * into one. */
83
+ n, t) {
84
+ this.source = e;
85
+ this.kind = n;
86
+ this.hidden = t;
87
+ }
88
+ }
89
+
90
+ function isHidden(e, n) {
91
+ const t = e.hidden;
92
+ return typeof t === "function" ? t(n) : t.includes(n);
93
+ }
94
+
95
+ // Both filters as one. Two key lists stay a key list (one `includes`, no
96
+ // closure); a predicate on either side needs a closure. An omit over a
97
+ // merge builds one combined list per leaf, per component layer, so the
98
+ // copy's form matters in every tier: `concat` runs the species/spreadable
99
+ // protocol (2–3× the cost of a copy once optimized), a hand loop is 2–4×
100
+ // `concat` in the interpreter and baseline tiers (a bytecode per element
101
+ // against one builtin), and a presized `new Array(n)` is holey, which takes
102
+ // `includes` off its fast path. `slice` + `push` of the (short) second list
103
+ // is within a third of the best form in every tier, and packed.
104
+ function combineHidden(e, n) {
105
+ if (typeof e !== "function" && typeof n !== "function") {
106
+ const t = e.slice();
107
+ for (let e = 0; e < n.length; e++) t.push(n[e]);
108
+ return t;
109
+ }
110
+ return t => (typeof e === "function" ? e(t) : e.includes(t)) || (typeof n === "function" ? n(t) : n.includes(t));
111
+ }
112
+
113
+ // The object a view filters (see `leafOf`).
114
+ function viewSource(e) {
115
+ return leafOf(e.source, e.kind);
116
+ }
117
+
118
+ // The record behind a `$PROXY`-marked object that is one of OUR views, else
119
+ // undefined for a store or a foreign proxy. ONE read: the view traps answer
120
+ // `$RECORD` first thing and a store's `get` trap answers it `undefined` on
121
+ // its symbol fast path, so the question never reaches a store's generic
122
+ // read path (firewall gate, tracked key read), which is what an unknown
123
+ // symbol would take — and a foreign proxy forwards it to a target that has
124
+ // no such key. Asking `$TARGET` first and then each view kind was two to
125
+ // four trap hops per source at every `merge()`, `omit()` and `ssrElement`.
126
+ // Call only after `$PROXY in o` is known true.
127
+ function recordOf(e) {
128
+ return e[$RECORD];
129
+ }
130
+
131
+ /** @internal The `OmitView` behind an `omit()` proxy, or undefined. */ function omitView(e) {
132
+ if (e == null || !($PROXY in e)) return undefined;
133
+ const n = e[$RECORD];
134
+ return n instanceof OmitView ? n : undefined;
135
+ }
136
+
137
+ // A props SOURCE ENTRY is a plain object, a proxy (store, merge, omit — the
138
+ // last two are normally unwrapped first: `mergeView` / `omitView`), a memo,
139
+ // or an `OmitView` record, and travels with its kind. These three answer for
140
+ // an entry what `Object.keys` / `in` / `[]` answer for an object, so every
141
+ // consumer walks entries with one code path, an `OmitView` is filtered
142
+ // rather than materialized, and nothing is asked of a proxy but the read.
143
+ // Own keys of a leaf: a proxy answers through ONE `ownKeys` trap (a store's
144
+ // keeps the key set tracked; `Object.keys` on a proxy would add a descriptor
145
+ // trap per key); a plain object its enumerable string keys. What a memo
146
+ // holds is only known once read.
147
+ function leafKeys(e, n) {
148
+ if (n === SOURCE_PLAIN) return Object.keys(e);
149
+ if (n === SOURCE_PROXY || e[$PROXY] === e) return Reflect.ownKeys(e);
150
+ return Object.keys(e);
151
+ }
152
+
153
+ /** @internal Own string keys of a source entry — every consumer skips
154
+ * symbols itself. */ function sourceKeys(e, n) {
155
+ if (n === SOURCE_OMIT) {
156
+ if (e.kind === SOURCE_MERGE) return mergeKeysOf(e.source, false, e);
157
+ const n = leafKeys(viewSource(e), e.kind);
158
+ const t = [];
159
+ for (let r = 0; r < n.length; r++) if (!isHidden(e, n[r])) t.push(n[r]);
160
+ return t;
161
+ }
162
+ return leafKeys(leafOf(e, n), n);
163
+ }
164
+
165
+ /** @internal `key in entry`. */ function sourceHas(e, n, t) {
166
+ if (n === SOURCE_OMIT) {
167
+ if (isHidden(e, t)) return false;
168
+ return e.kind === SOURCE_MERGE ? mergeHas(e.source, t) : t in viewSource(e);
169
+ }
170
+ return t in leafOf(e, n);
171
+ }
172
+
173
+ /** @internal `entry[key]` — the source's getter runs once, here. */ function sourceGet(e, n, t) {
174
+ if (n === SOURCE_OMIT) {
175
+ if (isHidden(e, t)) return undefined;
176
+ return e.kind === SOURCE_MERGE ? mergeGet(e.source, t) : viewSource(e)[t];
177
+ }
178
+ return leafOf(e, n)[t];
179
+ }
180
+
181
+ // An entry whose own key set is fixed: a plain object, or a view over one —
182
+ // an omit of a plain object, or of a merge whose entries all are. Not a
183
+ // store (its key set is a tracked signal), not a merge memo source (it
184
+ // swaps whole objects), and not any proxy that declares itself with
185
+ // `$PROXY in s` — a frames slot proxy answers `has` for every key and lists
186
+ // none, so only the `in` walk is right for it.
187
+ function entryHasStaticKeys(e, n) {
188
+ if (n === SOURCE_PLAIN) return true;
189
+ if (n !== SOURCE_OMIT) return false;
190
+ if (e.kind === SOURCE_PLAIN) return true;
191
+ return e.kind === SOURCE_MERGE && mergeHasStaticKeys(e.source);
192
+ }
193
+
194
+ function mergeHasStaticKeys(e) {
195
+ const n = e.sources, t = e.kinds;
196
+ for (let e = 0; e < n.length; e++) if (!entryHasStaticKeys(n[e], t[e])) return false;
197
+ return true;
198
+ }
199
+
200
+ /** @internal Whether the own key set of a props object cannot change
201
+ * reactively: a plain object, or a merge/omit view over plain objects only.
202
+ * A consumer may then decide from `Object.getOwnPropertyDescriptor` once —
203
+ * "no `children` key" or "a data `children`" holds for the object's lifetime,
204
+ * so no tracking scope is needed for it (#3388). For a store, or a view with
205
+ * a store or memo leaf, keys can appear later and the reactive path is the
206
+ * only correct one. */ function hasStaticKeys(e) {
207
+ if (!($PROXY in e)) return true;
208
+ const n = recordOf(e);
209
+ if (n instanceof MergeView) return mergeHasStaticKeys(n);
210
+ return n !== undefined && entryHasStaticKeys(n, SOURCE_OMIT);
211
+ }
212
+
213
+ /**
214
+ * Whether `o[key]` can never change for the lifetime of `o`: the key is a
215
+ * data property of a plain object, or is absent from an object whose key set
216
+ * is fixed. A getter, a key on a store, a memo-backed `merge()` source, or
217
+ * any key of an object whose keys can appear later (a store) is not static.
218
+ *
219
+ * Looks through `merge()`/`omit()` views to the leaf that owns the key. Any
220
+ * object will do, but props are the case it exists for: the compiler encodes
221
+ * a literal at the call site (`as="button"`) as a data property and an
222
+ * expression (`as={isLink() ? "a" : "button"}`) as a getter, so a component
223
+ * library reads the caller's own static/dynamic classification of a prop at
224
+ * runtime — identically on server and client, the compiler emitting the same
225
+ * own DESCRIPTORS on both (the object behind them may differ: the server
226
+ * builds props as a plain-prototype instance with shared getters) — and can
227
+ * take a no-computation path for the literal:
228
+ *
229
+ * ```tsx
230
+ * const Tag = dynamic(() => props.as, { static: isStatic(props, "as") });
231
+ * ```
232
+ *
233
+ * One descriptor lookup; no read of the value, nothing tracked.
234
+ */ function isStatic(e, n) {
235
+ if ($PROXY in e) {
236
+ // A store answers its descriptor trap with a value; through a view the
237
+ // descriptor is truthful (see `sourceDescriptor`). A foreign proxy is
238
+ // opaque: nothing about it is known to be fixed.
239
+ if (viewOf(e) === undefined) return false;
240
+ const t = Reflect.getOwnPropertyDescriptor(e, n);
241
+ return t === undefined ? hasStaticKeys(e) : t.get === undefined;
242
+ }
243
+ const t = Reflect.getOwnPropertyDescriptor(e, n);
244
+ return t === undefined || t.get === undefined && t.set === undefined;
245
+ }
246
+
247
+ function accessorDescriptor(e, n = true) {
248
+ return {
249
+ configurable: true,
250
+ enumerable: n,
251
+ get: e,
252
+ set: trueFn
253
+ };
254
+ }
255
+
256
+ /** The descriptor a consumer should see for `key` on an entry —
257
+ * the view proxies answer `getOwnPropertyDescriptor` with it, so it tells the
258
+ * truth through any depth of merge/omit layers.
259
+ *
260
+ * A DATA descriptor means "nothing reactive can hide behind this value": the
261
+ * key is a data property of a plain-object leaf — the compiler's own
262
+ * encoding of a static attribute. Everything else is an accessor: a getter
263
+ * on a leaf, a key on a store proxy (its "data" is a signal), or a key on a
264
+ * merge memo source (the whole object is reactive). That is what lets a
265
+ * consumer skip a reactive node for a static prop at the bottom of a
266
+ * component chain, and it is why the store case must NOT forward the store's
267
+ * own descriptor, which reports a value.
268
+ *
269
+ * `configurable: true` always — the target has no such property, and the
270
+ * Proxy invariants forbid reporting a non-configurable one. */
271
+ // `present` says the caller has already established `key in s` (a trap's
272
+ // shadowing walk did), so a store is not asked a second time.
273
+ function sourceDescriptor(e, n, t, r = false) {
274
+ if (n === SOURCE_OMIT) {
275
+ if (isHidden(e, t)) return undefined;
276
+ return sourceDescriptor(e.source, e.kind, t, r);
277
+ }
278
+ // An omit's merge record: the descriptor of the last entry that has the
279
+ // key, as the merge proxy's own trap answers (see `mergeDescriptor`).
280
+ if (n === SOURCE_MERGE) return mergeDescriptor(e, t);
281
+ // A memo source (`merge(() => …)`) is reactive wholesale: whatever shape
282
+ // the memo's current object has, the key is an accessor here.
283
+ if (n === SOURCE_MEMO) {
284
+ return r || t in leafOf(e, n) ? accessorDescriptor(() => leafOf(e, n)[t]) : undefined;
285
+ }
286
+ if (n === SOURCE_PROXY) {
287
+ // Another view (an omit's source may be a merge proxy) already answers
288
+ // truthfully. A store's reported "data" is a signal, and a foreign proxy
289
+ // (frames slot props) has no own descriptors: for both, existence is
290
+ // `in` and the kind is accessor — one trap, and never the store's
291
+ // descriptor path.
292
+ if (recordOf(e) !== undefined) return Reflect.getOwnPropertyDescriptor(e, t);
293
+ return r || t in e ? accessorDescriptor(() => e[t]) : undefined;
294
+ }
295
+ const i = Reflect.getOwnPropertyDescriptor(e, t);
296
+ if (i === undefined) return undefined;
297
+ if (i.get !== undefined || i.set !== undefined) return accessorDescriptor(() => e[t], i.enumerable);
298
+ // The proxy target has no such key, so the descriptor must be configurable;
299
+ // Reflect's is a fresh object, so a configurable one is handed out as is.
300
+ if (i.configurable) return i;
301
+ return {
302
+ configurable: true,
303
+ enumerable: i.enumerable,
304
+ writable: true,
305
+ value: i.value
306
+ };
307
+ }
308
+
309
+ // Own ENUMERABLE keys, symbols included, of an entry — the user-facing key
310
+ // set (`Object.keys(merged)`), where enumerability matters (#2769).
311
+ function sourceEnumerableKeys(e, n) {
312
+ {
313
+ if (e.kind === SOURCE_MERGE) return mergeEnumerableKeys(e.source, e);
314
+ const n = ownEnumerableKeys(viewSource(e));
315
+ const t = [];
316
+ for (let r = 0; r < n.length; r++) if (!isHidden(e, n[r])) t.push(n[r]);
317
+ return t;
318
+ }
319
+ }
320
+
321
+ // The target of a merge() proxy: the flattened sources, read by one shared
322
+ // handler — like OmitView, no per-instance closures. `sources` is what
323
+ // `mergeSources` answers.
324
+ /** @internal */ class MergeView {
325
+ sources;
326
+ kinds;
327
+ /** key → the plain leaf that owns it (later sources win), built by an
328
+ * enumeration or once the reads have paid for it (see `resolvedTable`)
329
+ * when every leaf has static keys; `null` when one doesn't. Until then
330
+ * the slot counts the per-key trap reads so far. One slot rather than a
331
+ * counter field of its own: a view is built per source per component
332
+ * layer, and each field initializer is a measurable share of a
333
+ * constructor that small in the lower JIT tiers. */
334
+ table=0;
335
+ /** see `tableOwnKeys` / `tableDescriptor` */
336
+ keys=undefined;
337
+ descs=undefined;
338
+ constructor(e,
339
+ /** `kinds[i]` is what `sources[i]` is (see `SourceKind`). */
340
+ n) {
341
+ this.sources = e;
342
+ this.kinds = n;
343
+ }
344
+ }
345
+
346
+ /** @internal The `MergeView` behind a `merge()` proxy — its flattened
347
+ * `sources` with their `kinds` — or undefined. */ function mergeView(e) {
348
+ if (e == null || !($PROXY in e)) return undefined;
349
+ const n = e[$RECORD];
350
+ return n instanceof MergeView ? n : undefined;
351
+ }
352
+
353
+ /** @internal The record behind a merge() or omit() proxy — a `MergeView`
354
+ * (flattened `sources` with their `kinds`) or an `OmitView` — or undefined
355
+ * for anything else (a plain object, a store, a foreign proxy). Two fast
356
+ * traps on a proxy (`has`, then `$RECORD`), none on a plain object. */ function viewOf(e) {
357
+ return e != null && $PROXY in e ? e[$RECORD] : undefined;
358
+ }
359
+
360
+ /** @internal The resolved key table of a merge/omit view — every own key of
361
+ * the view mapped to the plain object that owns it, in merged order (a key
362
+ * at the position of the last source that carries it, see `tableSet`) — or
363
+ * undefined when it has none: a leaf is a store or a memo source, whose
364
+ * keys can change, or the object is not a view at all.
365
+ *
366
+ * This is the flat object the eager copy used to build, made lazily and
367
+ * without copying: one pass over the leaves' own keys, then every
368
+ * `get`/`has`/descriptor is one lookup plus one read of the owning leaf, and
369
+ * a consumer (`spread` rerunning its effect) walks the table instead of
370
+ * re-deriving shadowing from the leaves each time. Own keys only, as the
371
+ * copy's were: a plain source's key set is fixed once merged (keys added to
372
+ * it later are not seen — the copy didn't see them either).
373
+ *
374
+ * It is built by an ENUMERATION — the `ownKeys` trap, or a consumer asking
375
+ * for it here — or once per-key reads have paid for it (`READS_FOR_TABLE`),
376
+ * not on the first read. A per-key read has a direct answer (a walk of the
377
+ * sources, last to first, one `in` each) whose cost is the source count,
378
+ * while the table's is every key of every leaf, so the walk wins until a
379
+ * view has been read about as many times as it has keys. On the server it
380
+ * never is: a component reads its props a few times, the element enumerates
381
+ * them once through its own source walk, and the view is gone — building on
382
+ * first read there cost a component chain a table per layer (profiled on
383
+ * the Kobalte-shaped chain: a third of SSR time in the table code and its
384
+ * garbage). On the
385
+ * client a view read on every reactive rerun crosses the threshold in its
386
+ * first few updates and is one lookup per read from then on, as before.
387
+ * Once built — by a `spread`, `Object.keys`, `{...props}`, or the count —
388
+ * every trap uses it. */ function resolvedTable(e) {
389
+ if (e == null || !($PROXY in e)) return undefined;
390
+ const n = recordOf(e);
391
+ if (n instanceof OmitView) return omitTable(n);
392
+ return n === undefined ? undefined : mergeTable(n);
393
+ }
394
+
395
+ function mergeTable(e) {
396
+ let n = e.table;
397
+ if (typeof n !== "object") {
398
+ // a read count: not decided yet
399
+ const t = e.sources, r = e.kinds;
400
+ for (let n = 0; n < t.length; n++) {
401
+ if (!entryHasStaticKeys(t[n], r[n])) {
402
+ e.table = null;
403
+ return undefined;
404
+ }
405
+ }
406
+ n = new Map;
407
+ collectTable(n, e, undefined);
408
+ e.table = n;
409
+ }
410
+ return n === null ? undefined : n;
411
+ }
412
+
413
+ // One pass over a merge record's leaves into `table`, through the nested
414
+ // omit-over-merge entries — the filters enclosing the current leaf are the
415
+ // `filters` stack — so a component chain builds ONE table at the view that
416
+ // asked, not one per layer. A key an entry hides that an EARLIER entry owned
417
+ // must stay: a filter applies to its own entry's contribution, not to the
418
+ // merge, which is exactly what the stack expresses. Every entry has static
419
+ // keys (the caller checked), so a leaf's own keys are the truth.
420
+ function collectTable(e, n, t) {
421
+ const r = n.sources, i = n.kinds;
422
+ for (let n = 0; n < r.length; n++) {
423
+ const f = r[n];
424
+ if (i[n] === SOURCE_OMIT) {
425
+ if (f.kind === SOURCE_MERGE) {
426
+ if (t === undefined) t = [ f ]; else t.push(f);
427
+ collectTable(e, f.source, t);
428
+ t.pop();
429
+ continue;
430
+ }
431
+ const n = f.source;
432
+ const r = Reflect.ownKeys(n);
433
+ for (let i = 0; i < r.length; i++) {
434
+ const u = r[i];
435
+ if (!isHidden(f, u) && !hiddenByAny(t, u)) tableSet(e, u, n);
436
+ }
437
+ } else {
438
+ const n = Reflect.ownKeys(f);
439
+ for (let r = 0; r < n.length; r++) {
440
+ const i = n[r];
441
+ if (!hiddenByAny(t, i)) tableSet(e, i, f);
442
+ }
443
+ }
444
+ }
445
+ }
446
+
447
+ function hiddenByAny(e, n) {
448
+ if (e !== undefined) for (let t = e.length - 1; t >= 0; t--) if (isHidden(e[t], n)) return true;
449
+ return false;
450
+ }
451
+
452
+ // Key order is the merged one — every key at the position of the LAST source
453
+ // that carries it — the order `ssrElement`'s array form serializes in and the
454
+ // eager copy enumerated in, so a spread through a view and a spread over the
455
+ // sources emit the same attribute order.
456
+ function tableSet(e, n, t) {
457
+ if (e.has(n)) e.delete(n);
458
+ e.set(n, t);
459
+ }
460
+
461
+ // An omit view's table: its source's (a merge's table, or a plain object's
462
+ // own keys) minus the hidden keys. Cached on the record.
463
+ function omitTable(e) {
464
+ let n = e.table;
465
+ if (typeof n !== "object") {
466
+ const t = e.source;
467
+ if (e.kind === SOURCE_MERGE) {
468
+ // One pass over the merge's leaves with this filter on the stack —
469
+ // the merge record builds no table of its own for it.
470
+ if (!mergeHasStaticKeys(t)) {
471
+ e.table = null;
472
+ return undefined;
473
+ }
474
+ n = new Map;
475
+ collectTable(n, t, [ e ]);
476
+ } else if (e.kind === SOURCE_PLAIN) {
477
+ n = new Map;
478
+ const r = Reflect.ownKeys(t);
479
+ for (let i = 0; i < r.length; i++) {
480
+ const f = r[i];
481
+ if (!isHidden(e, f)) n.set(f, t);
482
+ }
483
+ } else {
484
+ // a store or a memo: keys can change, no table
485
+ e.table = null;
486
+ return undefined;
487
+ }
488
+ e.table = n;
489
+ }
490
+ return n === null ? undefined : n;
491
+ }
492
+
493
+ // The user-facing key set of a resolved table: its keys that are enumerable
494
+ // on the leaf that owns them (`Object.keys(merged)`, #2769). Fixed, like the
495
+ // table, so it is built once per view: an `ownKeys` trap may hand back the
496
+ // same array every time (the engine copies it).
497
+ const propertyIsEnumerable = Object.prototype.propertyIsEnumerable;
498
+
499
+ function tableOwnKeys(e, n) {
500
+ let t = e.keys;
501
+ if (t === undefined) {
502
+ t = e.keys = [];
503
+ for (const [e, r] of n) if (propertyIsEnumerable.call(r, e)) t.push(e);
504
+ }
505
+ return t;
506
+ }
507
+
508
+ // The descriptor for a table key — its owning leaf's, truthful (see
509
+ // `sourceDescriptor`) — with the shape cached per key so an enumeration
510
+ // (`for…in`, `Object.keys`, `{...props}`: a descriptor trap per key, on
511
+ // every pass) does not re-read the leaf's descriptor and re-allocate a
512
+ // getter each time. An accessor reads live, so its descriptor is reused as
513
+ // is; a data descriptor is rebuilt with the current value.
514
+ function tableDescriptor(e, n, t) {
515
+ const r = n.get(t);
516
+ if (r === undefined) return undefined;
517
+ let i = e.descs;
518
+ if (i === undefined) i = e.descs = new Map;
519
+ let f = i.get(t);
520
+ if (f === undefined) {
521
+ f = sourceDescriptor(r, SOURCE_PLAIN, t);
522
+ if (f === undefined) return undefined;
523
+ i.set(t, f);
524
+ return f;
525
+ }
526
+ if (f.get !== undefined) return f;
527
+ return {
528
+ configurable: true,
529
+ enumerable: f.enumerable,
530
+ writable: f.writable,
531
+ value: r[t]
532
+ };
533
+ }
534
+
535
+ // Per-key trap reads a view takes before building its table, from the
536
+ // break-even: a build is ~60 ns per key (an `ownKeys` share, a `has`, a
537
+ // `set`), a walk ~20 ns per source (an `in`, a hidden-list check), and a
538
+ // leaf carries about five keys — so the table has paid for itself after
539
+ // ~15 reads. Measured on the Kobalte-shaped chain: a walk is 2× a lookup at
540
+ // depth 1 and up to 10× for a first-source key at depth 7 (a walk through
541
+ // seven nested layers, a hidden-list check at each), so a view read on
542
+ // every update wants the table; a view read a handful of times (every
543
+ // server-side view) never wants it.
544
+ const READS_FOR_TABLE = 16;
545
+
546
+ // The table for a per-key trap: the one a view HAS (built by an enumeration
547
+ // or an earlier read, see `resolvedTable`), or the one this read pays for,
548
+ // or none — a walk answers. One per view type, so a trap pays no type check.
549
+ // A settled slot is an object (the Map, or `null`); a number is the count.
550
+ function mergeReadTable(e) {
551
+ const n = e.table;
552
+ if (typeof n === "object") return n === null ? undefined : n;
553
+ if (n + 1 < READS_FOR_TABLE) {
554
+ e.table = n + 1;
555
+ return undefined;
556
+ }
557
+ return mergeTable(e);
558
+ }
559
+
560
+ // Only for an omit over a merge (`kind === SOURCE_MERGE`; the caller checks,
561
+ // inline — a call is not free in every tier): an omit over one object reads
562
+ // it directly — a list check and a property read, nothing a table would
563
+ // shorten.
564
+ function omitReadTable(e) {
565
+ const n = e.table;
566
+ if (typeof n === "object") return n === null ? undefined : n;
567
+ if (n + 1 < READS_FOR_TABLE) {
568
+ e.table = n + 1;
569
+ return undefined;
570
+ }
571
+ return omitTable(e);
572
+ }
573
+
574
+ // The table a record HAS — built already by an enumeration or a trap's read
575
+ // count — or undefined. What a nested walk asks: a record reached through an
576
+ // outer view's entry counts no reads of its own (the outer view decides for
577
+ // the whole tree, and its table build then builds the inner ones), so the
578
+ // inner merges of a component chain build nothing on the server where the
579
+ // leaves are read a few times each.
580
+ function tableOf(e) {
581
+ const n = e.table;
582
+ return typeof n === "object" && n !== null ? n : undefined;
583
+ }
584
+
585
+ // "no entry has the key" — distinct from an entry that holds `undefined`.
586
+ const MISSING = Symbol();
587
+
588
+ // The read: the value of the last entry that has the key, or MISSING. ONE
589
+ // walk — a nested omit-over-merge entry answers presence and value together,
590
+ // so a chain of layers is walked once per read, not once per layer per
591
+ // level.
592
+ function mergeLookup(e, n) {
593
+ const t = tableOf(e);
594
+ if (t !== undefined) {
595
+ const e = t.get(n);
596
+ return e === undefined ? MISSING : e[n];
597
+ }
598
+ const r = e.sources, i = e.kinds;
599
+ for (let e = r.length - 1; e >= 0; e--) {
600
+ const t = i[e];
601
+ // The common leaf first, read in place: a component's props view is a
602
+ // few plain objects, read once per key on the server.
603
+ if (t === SOURCE_PLAIN) {
604
+ const t = r[e];
605
+ if (n in t) return t[n];
606
+ continue;
607
+ }
608
+ if (t === SOURCE_OMIT) {
609
+ const t = r[e];
610
+ if (isHidden(t, n)) continue;
611
+ if (t.kind === SOURCE_MERGE) {
612
+ const e = mergeLookup(t.source, n);
613
+ if (e !== MISSING) return e;
614
+ continue;
615
+ }
616
+ const i = viewSource(t);
617
+ if (n in i) return i[n];
618
+ } else {
619
+ const i = leafOf(r[e], t);
620
+ if (n in i) return i[n];
621
+ }
622
+ }
623
+ return MISSING;
624
+ }
625
+
626
+ function mergeGet(e, n) {
627
+ const t = mergeLookup(e, n);
628
+ return t === MISSING ? undefined : t;
629
+ }
630
+
631
+ // `key in merge`, on the record.
632
+ function mergeHas(e, n) {
633
+ const t = tableOf(e);
634
+ if (t !== undefined) return t.has(n);
635
+ const r = e.sources, i = e.kinds;
636
+ for (let e = r.length - 1; e >= 0; e--) if (sourceHas(r[e], i[e], n)) return true;
637
+ return false;
638
+ }
639
+
640
+ // The proxy's `getOwnPropertyDescriptor`, on the record.
641
+ function mergeDescriptor(e, n) {
642
+ const t = tableOf(e);
643
+ if (t !== undefined) return tableDescriptor(e, t, n);
644
+ const r = e.sources, i = e.kinds;
645
+ for (let t = r.length - 1; t >= 0; t--) {
646
+ if (!sourceHas(r[t], i[t], n)) continue;
647
+ // `in` also answers for inherited keys, which have no own descriptor.
648
+ return sourceDescriptor(r[t], i[t], n, true) ?? accessorDescriptor(() => mergeGet(e, n));
649
+ }
650
+ return undefined;
651
+ }
652
+
653
+ // Own keys of a merge record in merged order — every key at the position
654
+ // of the LAST entry that carries it, the order the table keeps and
655
+ // `ssrElement` serializes in. `enumerable` selects the user-facing set
656
+ // (`Object.keys`, #2769) over every own string key (a consumer's walk);
657
+ // `filter` is the omit this record is read through, applied as the keys
658
+ // are gathered so an omit over a merge builds ONE list per layer. A list
659
+ // with `indexOf` rather than a Set: a props object has a dozen keys, and a
660
+ // Set's hash store was 2 KB per row on the Kobalte-shaped chain.
661
+ function mergeKeysOf(e, n, t) {
662
+ const r = [];
663
+ collectKeys(e, t === undefined ? undefined : [ t ], n, r, null);
664
+ return r;
665
+ }
666
+
667
+ // One pass over a merge record's leaves — through its nested omit-over-merge
668
+ // entries, `filters` the omits enclosing the current leaf (see
669
+ // `collectTable`) — appending each leaf's keys to `keys` in merged order
670
+ // (a key already listed moves to the end: later wins) and, when `owners` is
671
+ // given, the object that owns the key at the same index. A consumer that
672
+ // reads every key once (`ssrElement`) then reads `owners[i][keys[i]]`: no
673
+ // `in` walk per key, no table. A memo leaf is resolved once here.
674
+ function collectKeys(e, n, t, r, i) {
675
+ const f = e.sources, u = e.kinds;
676
+ for (let e = 0; e < f.length; e++) {
677
+ let o = f[e], c = u[e];
678
+ let s;
679
+ if (c === SOURCE_OMIT) {
680
+ if (o.kind === SOURCE_MERGE) {
681
+ if (n === undefined) n = [ o ]; else n.push(o);
682
+ collectKeys(o.source, n, t, r, i);
683
+ n.pop();
684
+ continue;
685
+ }
686
+ s = o;
687
+ c = o.kind;
688
+ o = o.source;
689
+ }
690
+ o = leafOf(o, c);
691
+ const d = t ? ownEnumerableKeys(o) : leafKeys(o, c);
692
+ for (let e = 0; e < d.length; e++) {
693
+ const t = d[e];
694
+ if (s !== undefined && isHidden(s, t)) continue;
695
+ if (hiddenByAny(n, t)) continue;
696
+ addKey(r, i, t, o);
697
+ }
698
+ }
699
+ }
700
+
701
+ // Append `key` owned by `owner`, moving an earlier listing to the end: later
702
+ // wins, and the position is the last owner's (the merged order).
703
+ function addKey(e, n, t, r) {
704
+ const i = e.indexOf(t);
705
+ if (i !== -1) {
706
+ e.splice(i, 1);
707
+ if (n !== null) n.splice(i, 1);
708
+ }
709
+ e.push(t);
710
+ if (n !== null) n.push(r);
711
+ }
712
+
713
+ /** @internal Every own string key of a props SOURCE — a plain object, a
714
+ * store or foreign proxy, or a merge/omit view — appended to `keys` in
715
+ * merged order with the object that owns each at the same index of
716
+ * `owners`: a key already listed (by this source or an earlier one) moves
717
+ * to the end, so several sources collected in turn give the order and the
718
+ * winners a merge of them would. A consumer that reads each key once
719
+ * (`ssrElement`) then reads `owners[i][keys[i]]` — the owner's getter runs
720
+ * there, once — and asks nothing else of a view: no table, no `in` walk per
721
+ * key through the merge/omit layers, no key list per leaf. One pass,
722
+ * however deep the layers nest. Symbols are listed; the consumer skips
723
+ * them. */ function sourceOwners(e, n, t) {
724
+ if ($PROXY in e) {
725
+ const r = viewOf(e);
726
+ if (r === undefined) {
727
+ // a store: one `ownKeys` trap, reads through `[]`
728
+ const r = Reflect.ownKeys(e);
729
+ for (let i = 0; i < r.length; i++) addKey(n, t, r[i], e);
730
+ return;
731
+ }
732
+ if (r instanceof OmitView) {
733
+ if (r.kind === SOURCE_MERGE) return collectKeys(r.source, [ r ], false, n, t);
734
+ const e = viewSource(r);
735
+ const i = leafKeys(e, r.kind);
736
+ for (let f = 0; f < i.length; f++) if (!isHidden(r, i[f])) addKey(n, t, i[f], e);
737
+ return;
738
+ }
739
+ return collectKeys(r, undefined, false, n, t);
740
+ }
741
+ const r = Object.keys(e);
742
+ for (let i = 0; i < r.length; i++) addKey(n, t, r[i], e);
743
+ }
744
+
745
+ // The user-facing key set of a merge record, read through `filter` if given.
746
+ function mergeEnumerableKeys(e, n) {
747
+ const t = mergeTable(e);
748
+ if (t === undefined) return mergeKeysOf(e, true, n);
749
+ const r = tableOwnKeys(e, t);
750
+ if (n === undefined) return r;
751
+ const i = [];
752
+ for (let e = 0; e < r.length; e++) if (!isHidden(n, r[e])) i.push(r[e]);
753
+ return i;
754
+ }
755
+
756
+ const mergeTraps = {
757
+ get(e, n, t) {
758
+ // The private keys are symbols; a string read (every prop) skips the
759
+ // compares. `$TARGET` is answered so a store check never walks the
760
+ // sources (a leaf that is a store would answer it).
761
+ if (typeof n === "symbol") {
762
+ if (n === $PROXY) return t;
763
+ if (n === $RECORD) return e;
764
+ if (n === $TARGET) return undefined;
765
+ }
766
+ // A trap read counts toward the table (see `mergeReadTable`); the walk
767
+ // itself is the record's. `mergeReadTable` and the plain walk of
768
+ // `mergeLookup` are inlined here: a trap is entered from the runtime, so
769
+ // nothing below it is inlined for it, and a component's props view is a
770
+ // few plain objects read once per key on the server — the walk is the
771
+ // whole read. A leaf that is not plain hands the walk to `mergeGet`,
772
+ // which starts over (a plain leaf walked twice is two `in` checks).
773
+ const r = e.table;
774
+ let i;
775
+ if (typeof r !== "object") {
776
+ if (r + 1 < READS_FOR_TABLE) {
777
+ e.table = r + 1;
778
+ const t = e.sources, i = e.kinds;
779
+ for (let r = t.length - 1; r >= 0; r--) {
780
+ if (i[r] !== SOURCE_PLAIN) return mergeGet(e, n);
781
+ // Read first, `in` only to tell a missing key from one holding
782
+ // undefined: the last source is the one that usually has the key.
783
+ const f = t[r][n];
784
+ if (f !== undefined || n in t[r]) return f;
785
+ }
786
+ return undefined;
787
+ }
788
+ i = mergeTable(e);
789
+ if (i === undefined) return mergeGet(e, n);
790
+ } else if (r === null) return mergeGet(e, n); else i = r;
791
+ const f = i.get(n);
792
+ return f === undefined ? undefined : f[n];
793
+ },
794
+ has(e, n) {
795
+ if (n === $PROXY) return true;
796
+ if (n === $TARGET || n === $RECORD) return false;
797
+ const t = mergeReadTable(e);
798
+ if (t !== undefined) return t.has(n);
799
+ return mergeHas(e, n);
800
+ },
801
+ set: trueFn,
802
+ deleteProperty: trueFn,
803
+ getOwnPropertyDescriptor(e, n) {
804
+ if (n === $PROXY || n === $TARGET || n === $RECORD) return undefined;
805
+ const t = mergeReadTable(e);
806
+ if (t !== undefined) return tableDescriptor(e, t, n);
807
+ return mergeDescriptor(e, n);
808
+ },
809
+ ownKeys(e) {
810
+ return mergeEnumerableKeys(e);
811
+ }
812
+ };
813
+
814
+ // An omit view reads its source directly — a hidden-key check and one
815
+ // property read; over a merge record, the merge's own walk by function call,
816
+ // never a trap. Once an enumeration or the read count has built its table
817
+ // (over a merge with plain leaves only: the merge's, filtered) every trap
818
+ // answers from that instead.
819
+ const omitTraps = {
820
+ get(e, n, t) {
821
+ if (n === $PROXY) return t;
822
+ // `$RECORD` is THIS view — never the underlying merge's record, which is
823
+ // unfiltered: handing a re-merge the merge's own sources would leak the
824
+ // omitted keys (#3014). A consumer walks the omit record as ONE filtered
825
+ // entry (`recordOf` tells the two records apart by class).
826
+ if (n === $RECORD) return e;
827
+ if (n === $TARGET) return undefined;
828
+ if (e.kind === SOURCE_MERGE) {
829
+ const t = omitReadTable(e);
830
+ if (t !== undefined) {
831
+ const e = t.get(n);
832
+ return e === undefined ? undefined : e[n];
833
+ }
834
+ if (isHidden(e, n)) return undefined;
835
+ return mergeGet(e.source, n);
836
+ }
837
+ if (isHidden(e, n)) return undefined;
838
+ return viewSource(e)[n];
839
+ },
840
+ has(e, n) {
841
+ if (n === $PROXY) return true;
842
+ if (n === $TARGET || n === $RECORD) return false;
843
+ if (e.kind === SOURCE_MERGE) {
844
+ const t = omitReadTable(e);
845
+ if (t !== undefined) return t.has(n);
846
+ if (isHidden(e, n)) return false;
847
+ return mergeHas(e.source, n);
848
+ }
849
+ if (isHidden(e, n)) return false;
850
+ return n in viewSource(e);
851
+ },
852
+ set: trueFn,
853
+ deleteProperty: trueFn,
854
+ getOwnPropertyDescriptor(e, n) {
855
+ if (n === $PROXY || n === $TARGET || n === $RECORD) return undefined;
856
+ if (e.kind === SOURCE_MERGE) {
857
+ const t = omitReadTable(e);
858
+ if (t !== undefined) return tableDescriptor(e, t, n);
859
+ }
860
+ return sourceDescriptor(e, SOURCE_OMIT, n);
861
+ },
862
+ ownKeys(e) {
863
+ if (e.kind === SOURCE_MERGE) {
864
+ const n = omitTable(e);
865
+ if (n !== undefined) return tableOwnKeys(e, n);
866
+ // No table (a store or memo leaf): the merge's own key set, filtered.
867
+ return sourceEnumerableKeys(e);
868
+ }
869
+ const n = Reflect.ownKeys(viewSource(e));
870
+ const t = [];
871
+ for (let r = 0; r < n.length; r++) if (!isHidden(e, n[r])) t.push(n[r]);
872
+ return t;
873
+ }
874
+ };
875
+
876
+ /** @internal The flattened sources behind a `merge()` proxy, or undefined.
877
+ * A merge's writes are no-ops, so its sources are the whole truth. A COPY of
878
+ * a merge (`{...merged}`, a descriptor copy) is a plain object that carries
879
+ * no sources — `ownKeys` never lists $RECORD — so what is on the copy is
880
+ * the truth there and every consumer reads it directly (#3384). */ function mergeSources(e) {
881
+ const n = mergeView(e);
882
+ return n === undefined ? undefined : n.sources;
883
+ }
884
+
885
+ /**
886
+ * Merges multiple props-like objects into a single proxy that *preserves
887
+ * reactivity*. Reads are forwarded to the right-most source that defines the
888
+ * property, so later sources override earlier ones (like `Object.assign`).
889
+ *
890
+ * Function arguments are treated as memo-backed sources — useful for passing
891
+ * derived defaults whose computation should track reactively.
892
+ *
893
+ * The result is a live VIEW of its sources, never a copy: creating it costs
894
+ * nothing per key, every read goes to the source that owns the key (a getter
895
+ * runs there, a data property is read live), and writing to it is a no-op.
896
+ * A single non-function source is returned as is. To own a mutable object,
897
+ * copy it: `{ ...merged }` snapshots the current values.
898
+ *
899
+ * Use this in component bodies to merge defaults / overrides without losing
900
+ * Solid's per-property tracking.
901
+ *
902
+ * Reading props, here and anywhere: a prop's getter is defined only for a
903
+ * read through its own object (`props.x`, `{ ...props }`, `Reflect.get`,
904
+ * these views). Forwarding its descriptor onto another object and reading it
905
+ * there is not supported — the compiler's server-side props keep their state
906
+ * on the instance, so the getter needs its object as receiver. A copy that
907
+ * must stay live defines its own getter that reads through the source, as
908
+ * the no-Proxy paths of merge() and omit() do.
909
+ *
910
+ * @example
911
+ * ```tsx
912
+ * function Button(_props: { label: string; type?: string; disabled?: boolean }) {
913
+ * const props = merge({ type: "button", disabled: false }, _props);
914
+ *
915
+ * return <button type={props.type} disabled={props.disabled}>{props.label}</button>;
916
+ * }
917
+ * ```
918
+ */ function merge(...e) {
919
+ if (e.length === 1 && typeof e[0] !== "function") return e[0];
920
+ // Sized to the argument count up front: a view is built per source per
921
+ // component layer, and growing two empty arrays by `push` was a third of
922
+ // its construction. A nested view's sources may run past the count (the
923
+ // array grows), a falsy source leaves it short (trimmed below).
924
+ const n = new Array(e.length);
925
+ const t = new Array(e.length);
926
+ let r = 0;
927
+ // The one non-falsy source, if there is exactly one: it IS the merge.
928
+ let i = undefined;
929
+ let f = 0;
930
+ for (let u = 0; u < e.length; u++) {
931
+ const o = e[u];
932
+ if (!o) continue;
933
+ f++;
934
+ i = o;
935
+ if (typeof o === "function") {
936
+ n[r] = createMemo(o);
937
+ t[r++] = SOURCE_MEMO;
938
+ continue;
939
+ }
940
+ if ($PROXY in o) {
941
+ // A store (or a foreign proxy) is a leaf as it is. A merge() proxy is
942
+ // flattened through: its writes are no-ops, so its sources are exactly
943
+ // what it reads. An omit() proxy joins as its view record — ONE entry,
944
+ // its filter travelling with it, whether it is over a plain object or
945
+ // a whole merge (never the merge's own sources, which would leak the
946
+ // omitted keys, #3014). A consumer's walk recurses into the record.
947
+ const e = recordOf(o);
948
+ if (e instanceof MergeView) {
949
+ for (let i = 0; i < e.sources.length; i++) {
950
+ n[r] = e.sources[i];
951
+ t[r++] = e.kinds[i];
952
+ }
953
+ } else if (e !== undefined) {
954
+ n[r] = e;
955
+ t[r++] = SOURCE_OMIT;
956
+ } else {
957
+ n[r] = o;
958
+ t[r++] = SOURCE_PROXY;
959
+ }
960
+ continue;
961
+ }
962
+ n[r] = o;
963
+ t[r++] = SOURCE_PLAIN;
964
+ }
965
+ if (r !== n.length) {
966
+ n.length = r;
967
+ t.length = r;
968
+ }
969
+ if (SUPPORTS_PROXY) {
970
+ if (f === 1 && typeof i !== "function") return i;
971
+ // Always a view, never a copy. Building a plain object here costs a
972
+ // descriptor read, a bound getter and a defineProperty per key per
973
+ // layer, and component libraries stack several layers per element
974
+ // (defaults → omit → call-site statics → …), so the copies dominated
975
+ // their render cost while every consumer that matters — `spread`,
976
+ // `ssrElement`, a nested merge — reads the flattened sources directly
977
+ // anyway (#3448). The view is O(1) to create and reads through to the
978
+ // sources, so a data property on a source is read live, like a getter.
979
+ // Writes to the result are no-ops (a consumer that needs its own object
980
+ // copies: `{...merged}`, which the traps answer truthfully). Copies of
981
+ // the result never carry $RECORD (#3384): `ownKeys` answers only the
982
+ // sources' keys.
983
+ return new Proxy(new MergeView(n, t), mergeTraps);
984
+ }
985
+ // No Proxy: an eager descriptor copy, semantics as close to the view as a
986
+ // plain object allows (getters stay live; data properties are snapshots).
987
+ const u = Object.create(null);
988
+ let o = false;
989
+ let c = n.length - 1;
990
+ for (let e = c; e >= 0; e--) {
991
+ const t = n[e];
992
+ if (!t) {
993
+ e === c && c--;
994
+ continue;
995
+ }
996
+ const r = Object.getOwnPropertyNames(t);
997
+ for (let n = r.length - 1; n >= 0; n--) {
998
+ const i = r[n];
999
+ if (i === "__proto__" || i === "constructor") continue;
1000
+ if (!u[i]) {
1001
+ o = o || e !== c;
1002
+ const n = Object.getOwnPropertyDescriptor(t, i);
1003
+ u[i] = n.get ? {
1004
+ enumerable: true,
1005
+ configurable: true,
1006
+ get: n.get.bind(t)
1007
+ } : n;
1008
+ }
1009
+ }
1010
+ }
1011
+ if (!o) return n[c];
1012
+ const s = {};
1013
+ const d = Object.keys(u);
1014
+ for (let e = d.length - 1; e >= 0; e--) {
1015
+ const n = d[e], t = u[n];
1016
+ if (t.get) Object.defineProperty(s, n, t); else s[n] = t.value;
1017
+ }
1018
+ return s;
1019
+ }
1020
+
1021
+ function omit(e, ...n) {
1022
+ let t = n.length === 1 && typeof n[0] === "function" ? n[0] : n;
1023
+ if (SUPPORTS_PROXY) {
1024
+ // A view over a view folds: one record, both filters, the original
1025
+ // source — so a consumer walks the real object however deep the omits go.
1026
+ // Over a merge() proxy the source is the merge's RECORD (see OmitView):
1027
+ // one record whatever the leaf count, read by function call.
1028
+ let n = e;
1029
+ let r = SOURCE_PLAIN;
1030
+ if (typeof e === "function") r = SOURCE_MEMO; else if ($PROXY in e) {
1031
+ r = SOURCE_PROXY;
1032
+ const i = recordOf(e);
1033
+ if (i instanceof OmitView) {
1034
+ n = i.source;
1035
+ r = i.kind;
1036
+ t = combineHidden(i.hidden, t);
1037
+ } else if (i !== undefined) {
1038
+ n = i;
1039
+ r = SOURCE_MERGE;
1040
+ }
1041
+ }
1042
+ return new Proxy(new OmitView(n, r, t), omitTraps);
1043
+ }
1044
+ const r = {};
1045
+ const i = Object.getOwnPropertyNames(e);
1046
+ const f = typeof t === "function" ? t : t.length > 4 && i.length > t.length ? (e => n => e.has(n))(new Set(t)) : e => t.includes(e);
1047
+ for (const n of i) {
1048
+ if (!f(n)) {
1049
+ const t = Object.getOwnPropertyDescriptor(e, n);
1050
+ if (!t.get && !t.set && t.enumerable && t.writable && t.configurable) {
1051
+ r[n] = t.value;
1052
+ } else if (t.get || t.set) {
1053
+ // An accessor is re-homed with its source as receiver, never copied
1054
+ // as-is: a props getter is only defined for a read THROUGH its own
1055
+ // object (the compiler's server props keep their state on the
1056
+ // instance, so a forwarded descriptor read on the copy throws). Same
1057
+ // rule as merge()'s copy path above.
1058
+ Object.defineProperty(r, n, {
1059
+ enumerable: t.enumerable,
1060
+ configurable: true,
1061
+ get: t.get && t.get.bind(e),
1062
+ set: t.set && t.set.bind(e)
1063
+ });
1064
+ } else Object.defineProperty(r, n, t);
1065
+ }
1066
+ }
1067
+ return r;
1068
+ }
1069
+
1070
+ 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 };