@solidjs/signals 2.0.0-rc.7 → 2.0.0-rc.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/dev-shared.js +5243 -0
- package/dist/dev.attribution.js +2333 -0
- package/dist/dev.js +1229 -6834
- package/dist/observe/affects.js +127 -0
- package/dist/observe/attribution.js +1 -0
- package/dist/observe/boundaries.js +586 -0
- package/dist/observe/core/action.js +167 -0
- package/dist/observe/core/async.js +736 -0
- package/dist/observe/core/attribution-hooks.js +60 -0
- package/dist/observe/core/attribution.js +2318 -0
- package/dist/{types-cjs/core/constants.d.cts → observe/core/constants.js} +129 -73
- package/dist/{types-cjs/core/context.d.cts → observe/core/context.js} +37 -12
- package/dist/observe/core/core.js +1289 -0
- package/dist/observe/core/dev.js +232 -0
- package/dist/observe/core/effect.js +179 -0
- package/dist/observe/core/error.js +80 -0
- package/dist/observe/core/external.js +98 -0
- package/dist/observe/core/graph.js +155 -0
- package/dist/observe/core/heap.js +147 -0
- package/dist/observe/core/invariants.js +43 -0
- package/dist/observe/core/lanes.js +168 -0
- package/dist/observe/core/optimistic.js +438 -0
- package/dist/observe/core/owner.js +308 -0
- package/dist/observe/core/scheduler.js +1190 -0
- package/dist/observe/core/verdict.js +551 -0
- package/dist/observe/index.js +55 -0
- package/dist/observe/map.js +482 -0
- package/dist/{types-cjs/signals.d.cts → observe/signals.js} +295 -317
- package/dist/observe/store/index.js +38 -0
- package/dist/observe/store/next/optimistic.js +651 -0
- package/dist/observe/store/next/projection.js +242 -0
- package/dist/observe/store/next/reconcile.js +373 -0
- package/dist/observe/store/next/store.js +2213 -0
- package/dist/observe/store/next/target.js +51 -0
- package/dist/observe/store/store.js +323 -0
- package/dist/observe/store/storePath.js +103 -0
- package/dist/observe/store/utils.js +210 -0
- package/dist/prod/attribution.js +32 -0
- package/dist/prod/core/action.js +52 -32
- package/dist/prod/core/async.js +171 -127
- package/dist/prod/core/constants.js +24 -1
- package/dist/prod/core/context.js +3 -3
- package/dist/prod/core/core.js +434 -291
- package/dist/prod/core/effect.js +54 -34
- package/dist/prod/core/external.js +2 -2
- package/dist/prod/core/graph.js +32 -32
- package/dist/prod/core/heap.js +49 -44
- package/dist/prod/core/lanes.js +45 -38
- package/dist/prod/core/optimistic.js +207 -73
- package/dist/prod/core/owner.js +43 -39
- package/dist/prod/core/scheduler.js +319 -190
- package/dist/prod/core/verdict.js +67 -67
- package/dist/prod/index.js +9 -3
- package/dist/prod/map.js +292 -141
- package/dist/prod/signals.js +7 -10
- package/dist/prod/store/next/optimistic.js +140 -125
- package/dist/prod/store/next/projection.js +3 -3
- package/dist/prod/store/next/reconcile.js +87 -84
- package/dist/prod/store/next/store.js +524 -280
- package/dist/prod/store/next/target.js +32 -10
- package/dist/prod/store/store.js +12 -14
- package/dist/prod/store/utils.js +36 -27
- package/dist/types/attribution.d.ts +15 -0
- package/dist/types/attribution.prod.d.ts +13 -0
- package/dist/types/core/async.d.ts +1 -1
- package/dist/types/core/attribution-hooks.d.ts +119 -6
- package/dist/types/core/attribution.d.ts +208 -53
- package/dist/types/core/constants.d.ts +23 -0
- package/dist/types/core/core.d.ts +7 -0
- package/dist/types/core/dev.d.ts +124 -26
- package/dist/types/core/effect.d.ts +8 -1
- package/dist/types/core/index.d.ts +2 -1
- package/dist/types/core/lanes.d.ts +8 -1
- package/dist/types/core/scheduler.d.ts +60 -0
- package/dist/types/core/types.d.ts +29 -9
- package/dist/types/index.d.ts +9 -2
- package/dist/types/map.d.ts +2 -0
- package/dist/types/store/index.d.ts +1 -0
- package/dist/types/store/next/store.d.ts +5 -0
- package/dist/types/store/next/target.d.ts +36 -9
- package/dist/types/store/utils.d.ts +7 -0
- package/package.json +21 -17
- package/dist/node.cjs +0 -10541
- package/dist/node.dev.cjs +0 -13724
- package/dist/types-cjs/affects.d.cts +0 -47
- package/dist/types-cjs/boundaries.d.cts +0 -175
- package/dist/types-cjs/core/action.d.cts +0 -64
- package/dist/types-cjs/core/async.d.cts +0 -23
- package/dist/types-cjs/core/attribution-hooks.d.cts +0 -127
- package/dist/types-cjs/core/attribution.d.cts +0 -495
- package/dist/types-cjs/core/core.d.cts +0 -185
- package/dist/types-cjs/core/dev.d.cts +0 -136
- package/dist/types-cjs/core/effect.d.cts +0 -30
- package/dist/types-cjs/core/error.d.cts +0 -56
- package/dist/types-cjs/core/external.d.cts +0 -15
- package/dist/types-cjs/core/graph.d.cts +0 -28
- package/dist/types-cjs/core/heap.d.cts +0 -24
- package/dist/types-cjs/core/index.d.cts +0 -13
- package/dist/types-cjs/core/invariants.d.cts +0 -59
- package/dist/types-cjs/core/lanes.d.cts +0 -54
- package/dist/types-cjs/core/optimistic.d.cts +0 -6
- package/dist/types-cjs/core/owner.d.cts +0 -124
- package/dist/types-cjs/core/scheduler.d.cts +0 -236
- package/dist/types-cjs/core/types.d.cts +0 -204
- package/dist/types-cjs/core/verdict.d.cts +0 -2
- package/dist/types-cjs/index.d.cts +0 -10
- package/dist/types-cjs/map.d.cts +0 -69
- package/dist/types-cjs/package.json +0 -3
- package/dist/types-cjs/store/index.d.cts +0 -18
- package/dist/types-cjs/store/next/optimistic.d.cts +0 -25
- package/dist/types-cjs/store/next/projection.d.cts +0 -8
- package/dist/types-cjs/store/next/reconcile.d.cts +0 -10
- package/dist/types-cjs/store/next/store.d.cts +0 -121
- package/dist/types-cjs/store/next/target.d.cts +0 -166
- package/dist/types-cjs/store/store.d.cts +0 -143
- package/dist/types-cjs/store/storePath.d.cts +0 -58
- package/dist/types-cjs/store/utils.d.cts +0 -74
|
@@ -1,11 +1,33 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Ownership (
|
|
3
|
-
*
|
|
4
|
-
*
|
|
2
|
+
* Ownership stamp (#3360): every backing the store ALLOCATES (CoW clones,
|
|
3
|
+
* privatized committed backings) carries its owning target under this
|
|
4
|
+
* enumerable symbol. One property write replaces the two weak-collection
|
|
5
|
+
* registrations (ownership set + raw→target map) a fresh object used to pay
|
|
6
|
+
* per draft — V8's identity-hash + ephemeron cost dominated the one-key
|
|
7
|
+
* write floor. Enumerable so a spread copy (the plain-data clone path) stays
|
|
8
|
+
* on the fast path and carries the stamp along.
|
|
9
|
+
*
|
|
10
|
+
* Owned backings are never user-reachable (`snapshot` copies them, the traps
|
|
11
|
+
* hide the key), so every raw key walk in the store must skip `$OWNER`, and
|
|
12
|
+
* ownership is answered by `isOwned` — a user object never carries it.
|
|
13
|
+
* Overlay drafts (`Object.create(v)` over an owned `v`) inherit the stamp.
|
|
5
14
|
*/
|
|
6
|
-
const
|
|
15
|
+
const $OWNER = Symbol(0);
|
|
7
16
|
|
|
8
|
-
/** raw → target
|
|
17
|
+
/** raw → target for UNOWNED backings (user-ingested, adopted); owned
|
|
18
|
+
* backings resolve through their `$OWNER` stamp. Boundary mechanism (O8). */ const storeNextLookup = new WeakMap;
|
|
19
|
+
|
|
20
|
+
/** A backing the store allocated and may mutate in place. */ function isOwned(e) {
|
|
21
|
+
return e[$OWNER] !== undefined;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/** raw → target within a family (`null` = plain stores / the global map).
|
|
25
|
+
* The stamp answers for backings owned by a target OF THAT FAMILY; anything
|
|
26
|
+
* else (user objects, adoptees, another family's backings the family
|
|
27
|
+
* re-registered for its own wrapper) resolves through the family's map. */ function lookupTarget(e, o) {
|
|
28
|
+
const t = e[$OWNER];
|
|
29
|
+
return t !== undefined && t.fam === o ? t : (o?.map ?? storeNextLookup).get(e);
|
|
30
|
+
}
|
|
9
31
|
|
|
10
32
|
function devAssertNeverUserMutation(e) {
|
|
11
33
|
return;
|
|
@@ -19,11 +41,11 @@ function setOptHooks(e) {
|
|
|
19
41
|
|
|
20
42
|
/** Sticky descendants flag walk (§6d): reconcile's keyed pruning descends
|
|
21
43
|
* only where subscriptions exist at/below. Nodes AND patches count. */ function markDescendants(e) {
|
|
22
|
-
let
|
|
23
|
-
while (
|
|
24
|
-
|
|
25
|
-
|
|
44
|
+
let o = e;
|
|
45
|
+
while (o && !o.d) {
|
|
46
|
+
o.d = true;
|
|
47
|
+
o = o.u;
|
|
26
48
|
}
|
|
27
49
|
}
|
|
28
50
|
|
|
29
|
-
export { devAssertNeverUserMutation, markDescendants, optHooks,
|
|
51
|
+
export { $OWNER, devAssertNeverUserMutation, isOwned, lookupTarget, markDescendants, optHooks, setOptHooks, storeNextLookup };
|
package/dist/prod/store/store.js
CHANGED
|
@@ -8,7 +8,7 @@ import "../core/verdict.js";
|
|
|
8
8
|
|
|
9
9
|
import "../core/effect.js";
|
|
10
10
|
|
|
11
|
-
import {
|
|
11
|
+
import { $OWNER, lookupTarget as lookupTarget$1 } from "./next/target.js";
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
14
|
* Brand symbols used internally by the store proxy / projection plumbing.
|
|
@@ -24,13 +24,9 @@ $AFFECTS = Symbol(0);
|
|
|
24
24
|
const STORE_VALUE = "v", STORE_NODE = "n", STORE_HAS = "h";
|
|
25
25
|
|
|
26
26
|
function lookupTarget(e, t) {
|
|
27
|
-
// Family
|
|
28
|
-
// lookup
|
|
29
|
-
|
|
30
|
-
const o = t.get(e);
|
|
31
|
-
if (o !== undefined) return o[$TARGET] ?? o;
|
|
32
|
-
}
|
|
33
|
-
return storeNextLookup.get(e);
|
|
27
|
+
// Family registrations (projections/optimistic) first, then the global
|
|
28
|
+
// next lookup. Proxies resolve through $TARGET directly.
|
|
29
|
+
return (t ? lookupTarget$1(e, t) : undefined) ?? lookupTarget$1(e, null);
|
|
34
30
|
}
|
|
35
31
|
|
|
36
32
|
// Values marked raw never acquire a proxy identity: wrap() serves them as-is
|
|
@@ -202,9 +198,9 @@ s) {
|
|
|
202
198
|
// scope must mark them like any property node.
|
|
203
199
|
if (f.k) o.push(f.k);
|
|
204
200
|
if (f.dk) o.push(f.dk);
|
|
205
|
-
// Carry the effective
|
|
206
|
-
//
|
|
207
|
-
r = f.fam
|
|
201
|
+
// Carry the effective family into untouched descendants (projections/
|
|
202
|
+
// optimistic stores register children under their family).
|
|
203
|
+
r = f.fam ?? r;
|
|
208
204
|
}
|
|
209
205
|
// Overlays are gone (next has no layer): raw enumeration; the optimistic
|
|
210
206
|
// view composition above already folded armed-node membership/values in.
|
|
@@ -214,6 +210,7 @@ s) {
|
|
|
214
210
|
}
|
|
215
211
|
const e = Object.getOwnPropertySymbols(n);
|
|
216
212
|
for (let f = 0, c = e.length; f < c; f++) {
|
|
213
|
+
if (e[f] === $OWNER) continue;
|
|
217
214
|
const c = Object.getOwnPropertyDescriptor(n, e[f]);
|
|
218
215
|
if (!c || c.get) continue;
|
|
219
216
|
walkAffectsScope(c.value, t, o, r, s);
|
|
@@ -221,6 +218,7 @@ s) {
|
|
|
221
218
|
} else {
|
|
222
219
|
const e = Reflect.ownKeys(n);
|
|
223
220
|
for (let f = 0, c = e.length; f < c; f++) {
|
|
221
|
+
if (e[f] === $OWNER) continue;
|
|
224
222
|
const c = Object.getOwnPropertyDescriptor(n, e[f]);
|
|
225
223
|
if (!c || c.get) continue;
|
|
226
224
|
walkAffectsScope(c.value, t, o, r, s);
|
|
@@ -252,7 +250,7 @@ s) {
|
|
|
252
250
|
// Callers guard on `pendingCheckActive`, which only flips inside
|
|
253
251
|
// isPending() — the verdict layer is loaded and its hook installed.
|
|
254
252
|
const o = e[STORE_NODE]?.[$AFFECTS];
|
|
255
|
-
if (o?.o?.t) GlobalQueue.
|
|
253
|
+
if (o?.o?.t) GlobalQueue.ri(o);
|
|
256
254
|
if (affectsScopes.size) {
|
|
257
255
|
// Chained backings (§7b): a wrapper's STORE_VALUE can be another store's
|
|
258
256
|
// proxy — marks cover by identity of the BASE raw, so resolve the chain
|
|
@@ -263,7 +261,7 @@ s) {
|
|
|
263
261
|
let t = r;
|
|
264
262
|
for (;;) {
|
|
265
263
|
if (s.scope.has(t)) {
|
|
266
|
-
GlobalQueue.
|
|
264
|
+
GlobalQueue.ri(e);
|
|
267
265
|
break;
|
|
268
266
|
}
|
|
269
267
|
const o = t?.[$TARGET];
|
|
@@ -302,7 +300,7 @@ s) {
|
|
|
302
300
|
inherited: []
|
|
303
301
|
});
|
|
304
302
|
const r = [ t ];
|
|
305
|
-
walkAffectsScope(e[$PROXY], o, r, e.fam
|
|
303
|
+
walkAffectsScope(e[$PROXY], o, r, e.fam, new Set);
|
|
306
304
|
return r;
|
|
307
305
|
}
|
|
308
306
|
const o = e.n?.[t] ?? nextAffectsNodeResolver(e, t);
|
package/dist/prod/store/utils.js
CHANGED
|
@@ -51,6 +51,15 @@ function resolveSource(e) {
|
|
|
51
51
|
|
|
52
52
|
const $SOURCES = Symbol(0);
|
|
53
53
|
|
|
54
|
+
/** @internal The flattened sources behind a `merge()` PROXY, or undefined.
|
|
55
|
+
* Only the proxy form: its writes are no-ops, so the sources are the whole
|
|
56
|
+
* truth. merge()'s plain-object form also records `$SOURCES` (so nested
|
|
57
|
+
* merges flatten), but it is a real object callers may mutate afterwards
|
|
58
|
+
* (html's tagged templates assign props after spreading) — those own writes
|
|
59
|
+
* live on the object, not in the sources, so it must be read directly. */ function mergeSources(e) {
|
|
60
|
+
return e != null && e[$PROXY] === e ? e[$SOURCES] : undefined;
|
|
61
|
+
}
|
|
62
|
+
|
|
54
63
|
/**
|
|
55
64
|
* Merges multiple props-like objects into a single proxy that *preserves
|
|
56
65
|
* reactivity*. Reads are forwarded to the right-most source that defines the
|
|
@@ -77,9 +86,9 @@ const $SOURCES = Symbol(0);
|
|
|
77
86
|
for (let n = 0; n < e.length; n++) {
|
|
78
87
|
const o = e[n];
|
|
79
88
|
r = r || !!o && $PROXY in o;
|
|
80
|
-
const
|
|
81
|
-
if (
|
|
82
|
-
for (let e = 0; e <
|
|
89
|
+
const u = !!o && o[$SOURCES];
|
|
90
|
+
if (u) {
|
|
91
|
+
for (let e = 0; e < u.length; e++) t.push(u[e]);
|
|
83
92
|
} else t.push(typeof o === "function" ? (r = true, createMemo(o)) : o);
|
|
84
93
|
}
|
|
85
94
|
if (SUPPORTS_PROXY && r) {
|
|
@@ -109,21 +118,21 @@ const $SOURCES = Symbol(0);
|
|
|
109
118
|
}
|
|
110
119
|
const n = Object.create(null);
|
|
111
120
|
let o = false;
|
|
112
|
-
let
|
|
113
|
-
for (let e =
|
|
121
|
+
let u = t.length - 1;
|
|
122
|
+
for (let e = u; e >= 0; e--) {
|
|
114
123
|
const r = t[e];
|
|
115
124
|
if (!r) {
|
|
116
|
-
e ===
|
|
125
|
+
e === u && u--;
|
|
117
126
|
continue;
|
|
118
127
|
}
|
|
119
|
-
const
|
|
120
|
-
for (let t =
|
|
121
|
-
const
|
|
122
|
-
if (
|
|
123
|
-
if (!n[
|
|
124
|
-
o = o || e !==
|
|
125
|
-
const t = Object.getOwnPropertyDescriptor(r,
|
|
126
|
-
n[
|
|
128
|
+
const c = Object.getOwnPropertyNames(r);
|
|
129
|
+
for (let t = c.length - 1; t >= 0; t--) {
|
|
130
|
+
const s = c[t];
|
|
131
|
+
if (s === "__proto__" || s === "constructor") continue;
|
|
132
|
+
if (!n[s]) {
|
|
133
|
+
o = o || e !== u;
|
|
134
|
+
const t = Object.getOwnPropertyDescriptor(r, s);
|
|
135
|
+
n[s] = t.get ? {
|
|
127
136
|
enumerable: true,
|
|
128
137
|
configurable: true,
|
|
129
138
|
get: t.get.bind(r)
|
|
@@ -131,15 +140,15 @@ const $SOURCES = Symbol(0);
|
|
|
131
140
|
}
|
|
132
141
|
}
|
|
133
142
|
}
|
|
134
|
-
if (!o) return t[
|
|
135
|
-
const
|
|
136
|
-
const
|
|
137
|
-
for (let e =
|
|
138
|
-
const r =
|
|
139
|
-
if (t.get) Object.defineProperty(
|
|
143
|
+
if (!o) return t[u];
|
|
144
|
+
const c = {};
|
|
145
|
+
const s = Object.keys(n);
|
|
146
|
+
for (let e = s.length - 1; e >= 0; e--) {
|
|
147
|
+
const r = s[e], t = n[r];
|
|
148
|
+
if (t.get) Object.defineProperty(c, r, t); else c[r] = t.value;
|
|
140
149
|
}
|
|
141
|
-
|
|
142
|
-
return
|
|
150
|
+
c[$SOURCES] = t;
|
|
151
|
+
return c;
|
|
143
152
|
}
|
|
144
153
|
|
|
145
154
|
/**
|
|
@@ -189,13 +198,13 @@ const $SOURCES = Symbol(0);
|
|
|
189
198
|
const t = {};
|
|
190
199
|
const n = Object.getOwnPropertyNames(e);
|
|
191
200
|
const o = r.length > 4 && n.length > r.length ? new Set(r) : undefined;
|
|
192
|
-
for (const
|
|
193
|
-
if (o ? !o.has(
|
|
194
|
-
const r = Object.getOwnPropertyDescriptor(e,
|
|
195
|
-
!r.get && !r.set && r.enumerable && r.writable && r.configurable ? t[
|
|
201
|
+
for (const u of n) {
|
|
202
|
+
if (o ? !o.has(u) : !r.includes(u)) {
|
|
203
|
+
const r = Object.getOwnPropertyDescriptor(e, u);
|
|
204
|
+
!r.get && !r.set && r.enumerable && r.writable && r.configurable ? t[u] = r.value : Object.defineProperty(t, u, r);
|
|
196
205
|
}
|
|
197
206
|
}
|
|
198
207
|
return t;
|
|
199
208
|
}
|
|
200
209
|
|
|
201
|
-
export { merge, omit };
|
|
210
|
+
export { merge, mergeSources, omit };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@solidjs/signals/attribution` — the "why did this run" engine.
|
|
3
|
+
*
|
|
4
|
+
* A separate entry on purpose: the core ships only the hook slot
|
|
5
|
+
* (`OBSERVE.attribution.install`) and the interaction frame
|
|
6
|
+
* (`OBSERVE.attribution.withInteraction`); the engine that turns hook facts
|
|
7
|
+
* into re-run explanations, cost tables, holds and feedback lives here, so an
|
|
8
|
+
* observe build carries it only when something imports this module. The dev
|
|
9
|
+
* and observe tiers resolve to this file; the prod tier resolves to
|
|
10
|
+
* `attribution.prod.ts`, an inert engine with the same surface, so app code
|
|
11
|
+
* can import it unconditionally.
|
|
12
|
+
*/
|
|
13
|
+
export { attribution } from "./core/attribution.js";
|
|
14
|
+
export type { Acknowledgement, Attribution, AttributionFeedbackTables, AttributionOptions, AttributionRecords, AttributionRecordType, ChangeKind, ChangeOrigin, ChangeRecord, FallbackStats, FeedbackInteraction, FeedbackNavigation, FeedbackSource, FlightLink, FlightStats, HeldWrite, HoldEvent, InteractionEvent, NavigationEvent, NavigationHop, RerunEvent, ScopeCost, WaterfallRecord, WriteCost } from "./core/attribution.js";
|
|
15
|
+
export type { InteractionRef, NavigationRef, OriginRef } from "./core/attribution-hooks.js";
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@solidjs/signals/attribution` as the prod tier resolves it.
|
|
3
|
+
*
|
|
4
|
+
* A prod build has no hook sites — `__OBSERVE__` folded every one out — so an
|
|
5
|
+
* engine installed there would never hear a fact. Rather than make apps guard
|
|
6
|
+
* the import per tier, prod resolves this inert twin: the same `Attribution`
|
|
7
|
+
* surface, every query empty, `enable()` a no-op. Type-checked against the
|
|
8
|
+
* real engine's interface so the two cannot drift.
|
|
9
|
+
*/
|
|
10
|
+
import type { Attribution } from "./core/attribution.js";
|
|
11
|
+
export declare const attribution: Attribution;
|
|
12
|
+
export type { Acknowledgement, Attribution, AttributionFeedbackTables, AttributionOptions, AttributionRecords, AttributionRecordType, ChangeKind, ChangeOrigin, ChangeRecord, FallbackStats, FeedbackInteraction, FeedbackNavigation, FeedbackSource, FlightLink, FlightStats, HeldWrite, HoldEvent, InteractionEvent, NavigationEvent, NavigationHop, RerunEvent, ScopeCost, WaterfallRecord, WriteCost } from "./core/attribution.js";
|
|
13
|
+
export type { InteractionRef, NavigationRef, OriginRef } from "./core/attribution-hooks.js";
|
|
@@ -14,7 +14,7 @@ export declare function setPendingError(el: Computed<any>, source?: Computed<any
|
|
|
14
14
|
export declare function forEachDependent(el: Computed<any>, fn: (node: Computed<any>, link: Link) => void): void;
|
|
15
15
|
export declare function releaseSettledDependents(el: Computed<any>): void;
|
|
16
16
|
export declare function settleErroredDependents(el: Computed<any>, error: any): void;
|
|
17
|
-
export declare function settlePendingSource(el: Computed<any>): void;
|
|
17
|
+
export declare function settlePendingSource(el: Computed<any>, source?: Computed<any>): void;
|
|
18
18
|
export declare function isThenable<T>(value: T | PromiseLike<T>): value is PromiseLike<T>;
|
|
19
19
|
/** Fire and clear a node's iterator-flight cancellation hook (#3122). */
|
|
20
20
|
export declare function releaseFlightTeardown(el: Computed<any>): void;
|
|
@@ -1,22 +1,47 @@
|
|
|
1
1
|
import type { Transition } from "./scheduler.js";
|
|
2
2
|
import type { Computed, Signal } from "./types.js";
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
4
|
+
* Observe-tier hook points for the reactive core.
|
|
5
5
|
*
|
|
6
6
|
* Core's obligation is to call these with true facts at the moments they
|
|
7
7
|
* happen; ALL attribution semantics (stamps, cause chains, timings, warnings)
|
|
8
|
-
* live in the engine that installs them
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
8
|
+
* live in the engine that installs them — `@solidjs/signals/attribution`, a
|
|
9
|
+
* separate entry so an observe build that never enables it never ships it
|
|
10
|
+
* (same pattern as the GlobalQueue._* feature slots). `attrHooks` is null
|
|
11
|
+
* unless an engine is installed, so the disabled cost is one null check per
|
|
12
|
+
* site, and prod builds fold every site out behind __OBSERVE__.
|
|
12
13
|
*
|
|
13
14
|
* IMPORTANT for implementers of call sites: a hook call must never sit inside
|
|
14
15
|
* a `try` block — rollup's tryCatchDeoptimization retains functions referenced
|
|
15
|
-
* inside `try` even behind a folded
|
|
16
|
+
* inside `try` even behind a folded __OBSERVE__ guard, which re-couples the
|
|
16
17
|
* engine into prod bundles (#2883 harness). Set a local flag inside the try
|
|
17
18
|
* and call the hook after the catch.
|
|
18
19
|
*/
|
|
19
20
|
export interface AttributionHooks {
|
|
21
|
+
/**
|
|
22
|
+
* `withInteraction` opened a user-interaction frame: root writes until the
|
|
23
|
+
* matching `interactionEnd` were performed by the handler of `ref`. Frames
|
|
24
|
+
* nest strictly (synchronous dispatch), so the engine keeps a stack.
|
|
25
|
+
*/
|
|
26
|
+
interactionStart(ref: InteractionRef): void;
|
|
27
|
+
interactionEnd(): void;
|
|
28
|
+
/**
|
|
29
|
+
* `withOrigin` opened a declared-origin frame: root writes until the
|
|
30
|
+
* matching `originEnd` are the unit of work `ref` describes (a router's
|
|
31
|
+
* navigation). Nests inside an interaction frame — a link click that
|
|
32
|
+
* navigates — or stands alone (a redirect from an action, a programmatic
|
|
33
|
+
* `navigate()`). Frames nest strictly, so the engine keeps a stack.
|
|
34
|
+
*/
|
|
35
|
+
originStart(ref: OriginRef): void;
|
|
36
|
+
originEnd(): void;
|
|
37
|
+
/**
|
|
38
|
+
* A `flush()` drain finished: every batch it processed either committed
|
|
39
|
+
* (its effects have run) or was parked in a held transition (`holdStart`
|
|
40
|
+
* fired for it). Fires once per drain, after the loop — not per batch, and
|
|
41
|
+
* not for a `flush()` call that found nothing to do. Gives the engine the
|
|
42
|
+
* "committed, screen updated" instant for writes no transition ever held.
|
|
43
|
+
*/
|
|
44
|
+
flushEnd(): void;
|
|
20
45
|
/**
|
|
21
46
|
* A recompute is starting; `el._deps` still holds the previous run's links.
|
|
22
47
|
* Always paired with `recomputeEnd` (recompute has no early returns).
|
|
@@ -123,5 +148,93 @@ export interface AttributionHooks {
|
|
|
123
148
|
*/
|
|
124
149
|
boundaryFallback(boundary: object, tree: Computed<any> | undefined, shown: boolean): void;
|
|
125
150
|
}
|
|
151
|
+
/** A user interaction, as a rendering runtime describes it to `withInteraction`. */
|
|
152
|
+
export interface InteractionRef {
|
|
153
|
+
/** Event type — `click`, `keydown`, `input`… */
|
|
154
|
+
type: string;
|
|
155
|
+
/** The element hit, e.g. `button#next "Next →"`. */
|
|
156
|
+
target?: string;
|
|
157
|
+
/** Dispatch time on the `performance.now()` clock; defaults to now. */
|
|
158
|
+
at?: number;
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* A navigation, as a router describes it to `withOrigin` around the location
|
|
162
|
+
* write it is about to perform. Match eagerly and describe before writing:
|
|
163
|
+
* the engine keys the work the write causes — the hold behind route data,
|
|
164
|
+
* the re-runs, the verdicts — to this record, and names it by the
|
|
165
|
+
* parametrized route so occurrences fold together.
|
|
166
|
+
*
|
|
167
|
+
* The engine keeps the object and reads `name`, `to` and `params` again when
|
|
168
|
+
* the navigation settles (and when a hold on it is judged), so a router whose
|
|
169
|
+
* match is not final at write time — a lazy route subtree that resolves inside
|
|
170
|
+
* the hold — may describe coarsely (`/admin/*`) and assign the exact pattern
|
|
171
|
+
* and params onto the same object once it knows them. `from` and `at` are
|
|
172
|
+
* read once, when the frame opens.
|
|
173
|
+
*/
|
|
174
|
+
export interface NavigationRef {
|
|
175
|
+
kind: "navigation";
|
|
176
|
+
/** The matched route pattern — `/users/:id`. The name every consumer groups by. */
|
|
177
|
+
name?: string;
|
|
178
|
+
/** Concrete destination path. */
|
|
179
|
+
to?: string;
|
|
180
|
+
/** Concrete path being left. */
|
|
181
|
+
from?: string;
|
|
182
|
+
/** Route params the pattern bound — `{ id: "42" }` (optional params unbound: `undefined`). */
|
|
183
|
+
params?: Readonly<Record<string, string | undefined>>;
|
|
184
|
+
/**
|
|
185
|
+
* When the navigation was requested on the `performance.now()` clock;
|
|
186
|
+
* defaults to now. A router whose request predates the write (loaders
|
|
187
|
+
* awaited before the location moves) passes its own start here.
|
|
188
|
+
*/
|
|
189
|
+
at?: number;
|
|
190
|
+
/**
|
|
191
|
+
* `>= 1`: this frame is the Nth redirect hop of the navigation still
|
|
192
|
+
* pending — a guard or loader sent it elsewhere before it landed — not a
|
|
193
|
+
* new navigation. The engine folds it onto that pending record: the record
|
|
194
|
+
* keeps the user's request time and interaction, its destination becomes
|
|
195
|
+
* this one, and the abandoned destination is kept in `redirects`. Without
|
|
196
|
+
* a pending navigation to fold onto it opens a navigation of its own.
|
|
197
|
+
*/
|
|
198
|
+
redirect?: number;
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* What `withOrigin` accepts: a declared unit of work whose writes the engine
|
|
202
|
+
* should attribute as a whole. A discriminated union so kinds can be added
|
|
203
|
+
* (a form submission, a tab switch) without the seam changing shape; the
|
|
204
|
+
* engine knows `navigation` today.
|
|
205
|
+
*/
|
|
206
|
+
export type OriginRef = NavigationRef;
|
|
126
207
|
export declare let attrHooks: AttributionHooks | null;
|
|
127
208
|
export declare function setAttributionHooks(hooks: AttributionHooks | null): void;
|
|
209
|
+
/**
|
|
210
|
+
* Run `fn` as the handler of a user interaction: every root write it performs
|
|
211
|
+
* (and every action step, effect or flight the write causes) is attributed to
|
|
212
|
+
* `ref` by whichever engine is installed. The web runtime wraps event
|
|
213
|
+
* dispatch in this; custom renderers and test harnesses call it themselves.
|
|
214
|
+
* With no engine installed it is `fn()` — the wiring, not the engine, so it
|
|
215
|
+
* lives in core and is reachable as `OBSERVE.attribution.withInteraction`.
|
|
216
|
+
*
|
|
217
|
+
* The `finally` is deliberate and safe under the try rule above: this
|
|
218
|
+
* function is referenced only from the `OBSERVE` object, which prod builds
|
|
219
|
+
* fold to `undefined`, so nothing retains it there.
|
|
220
|
+
*/
|
|
221
|
+
export declare function withInteraction<T>(ref: InteractionRef, fn: () => T): T;
|
|
222
|
+
/**
|
|
223
|
+
* Run `fn` as a declared unit of work — a router's navigation: every root
|
|
224
|
+
* write it performs is attributed to `ref` (and, through it, to the enclosing
|
|
225
|
+
* interaction when there is one), so the hold those writes wait in, the
|
|
226
|
+
* re-runs they cause and the verdicts on them all carry the route's name
|
|
227
|
+
* instead of a bare signal's. Same contract as `withInteraction`: the wiring,
|
|
228
|
+
* not the engine; `fn()` with no engine installed. Reachable as
|
|
229
|
+
* `OBSERVE.attribution.withOrigin`.
|
|
230
|
+
*
|
|
231
|
+
* ```ts
|
|
232
|
+
* OBSERVE
|
|
233
|
+
* ? OBSERVE.attribution.withOrigin(
|
|
234
|
+
* { kind: "navigation", name: match.pattern, to, from, params: match.params },
|
|
235
|
+
* () => setLocation(to)
|
|
236
|
+
* )
|
|
237
|
+
* : setLocation(to);
|
|
238
|
+
* ```
|
|
239
|
+
*/
|
|
240
|
+
export declare function withOrigin<T>(ref: OriginRef, fn: () => T): T;
|