@askrjs/askr 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +874 -0
- package/README.md +61 -29
- package/capabilities.json +19 -9
- package/dist/actions/index.js +56 -12
- package/dist/benchmark.js +10 -15
- package/dist/boot/index.d.ts +3 -2
- package/dist/boot/index.js +1 -1
- package/dist/boot-DaoTYoCw.js +3989 -0
- package/dist/browser-activity-CB8e-V4f.js +220 -0
- package/dist/components/index.d.ts +8 -1
- package/dist/components/index.js +1 -43
- package/dist/{aria-hKjThHcp.js → compose-ref-DWzdbxsD.js} +41 -4
- package/dist/control/index.d.ts +2 -0
- package/dist/control/index.js +1 -1
- package/dist/control-nfpT2fbK.js +209 -0
- package/dist/core.d.ts +5 -9
- package/dist/csp-nonce-DwGw1A6Q.js +35 -0
- package/dist/data/index.js +3 -3
- package/dist/{data-2edW0jhF.js → data-BCwClJiF.js} +283 -94
- package/dist/data-runtime-C1bFAlba.js +242 -0
- package/dist/{deferred-CbgNhf67.js → deferred-bEEHHvic.js} +42 -20
- package/dist/domains/actions.d.ts +8 -3
- package/dist/domains/component.d.ts +1 -107
- package/dist/domains/context.d.ts +0 -15
- package/dist/domains/control.d.ts +36 -249
- package/dist/domains/data.d.ts +31 -13
- package/dist/domains/diagnostics.d.ts +1 -2
- package/dist/domains/lifecycle.d.ts +2 -5
- package/dist/domains/refs.d.ts +0 -2
- package/dist/domains/routing.d.ts +43 -8
- package/dist/domains/scheduler.d.ts +1 -76
- package/dist/domains/server.d.ts +5 -2
- package/dist/domains/state.d.ts +2 -5
- package/dist/domains/telemetry.d.ts +0 -2
- package/dist/elements.d.ts +214 -51
- package/dist/error-boundary-Bpwofwps.js +293 -0
- package/dist/foundations/icon/index.d.ts +0 -58
- package/dist/foundations/icon/index.js +2 -2
- package/dist/foundations/index.js +2 -1
- package/dist/foundations/interactions/index.js +1 -1
- package/dist/foundations/state/index.d.ts +3 -3
- package/dist/foundations/state/index.js +5 -3
- package/dist/foundations/structures/index.js +2 -1
- package/dist/foundations/utilities/index.d.ts +2 -0
- package/dist/foundations/utilities/index.js +1 -2
- package/dist/fx/index.d.ts +31 -58
- package/dist/fx/index.js +313 -195
- package/dist/hooks-BimKStr4.js +202 -0
- package/dist/index.d.ts +11 -74
- package/dist/index.js +8 -447
- package/dist/instance-BAnfmXOR.js +988 -0
- package/dist/{interactions-CTeACdT_.js → interactions-D2BoREb-.js} +3 -2
- package/dist/jsx-dev-runtime.d.ts +41 -18
- package/dist/jsx-dev-runtime.js +1 -6
- package/dist/{jsx-runtime-CPJXAOBF.js → jsx-runtime-C4idqHY0.js} +18 -7
- package/dist/jsx-runtime.js +1 -1
- package/dist/jsx.d.ts +61 -37
- package/dist/{manifest-D1P3UNWV.js → manifest-CW9gyNBY.js} +3 -3
- package/dist/{navigate-prC5V8XV.js → navigate-CP_0Zy5U.js} +454 -87
- package/dist/navigation.d.ts +12 -3
- package/dist/peer-types.d.ts +8 -0
- package/dist/portal-DuOKfnLa.js +349 -0
- package/dist/promise-Dz8iIHAm.js +16 -0
- package/dist/query-registry-WMCN0BJL.js +320 -0
- package/dist/readable-DFWOsTac.js +21 -0
- package/dist/{render-context-B7ohlh6t.js → render-context-DGHnEveC.js} +27 -11
- package/dist/render-sync-IC5lMFpq.js +1240 -0
- package/dist/resolution-Cx82-xjW.js +1244 -0
- package/dist/resource-CLjB7RBQ.js +377 -0
- package/dist/resources/index.d.ts +21 -11
- package/dist/resources/index.js +45 -244
- package/dist/router/index.d.ts +14 -5
- package/dist/router/index.js +22 -53
- package/dist/scope-CwpVSHVf.js +55 -0
- package/dist/{shared-kU8yvryp.js → shared-O2ZnmYAf.js} +1 -7
- package/dist/{snapshot-source-An4iKajG.js → snapshot-Cjx4N988.js} +6 -1
- package/dist/ssg/index.d.ts +1 -2
- package/dist/ssg/index.js +5 -13
- package/dist/ssr/index.d.ts +26 -28
- package/dist/ssr/index.js +4 -4
- package/dist/{ssr-CiNm6Vzl.js → ssr-BJ8ug7zH.js} +133 -122
- package/dist/ssr-DoV-vJ-5.js +229 -0
- package/dist/state-DWO1KzkX.js +232 -0
- package/dist/structures-D4dDMqHX.js +231 -0
- package/dist/testing/index.d.ts +8 -4
- package/dist/testing/index.js +29 -34
- package/dist/url-CnbfpX0K.js +185 -0
- package/dist/utilities.d.ts +48 -2
- package/dist/verify-hydration-DpVaDnqz.js +152 -0
- package/package.json +19 -9
- package/dist/access-CEA2pOry.js +0 -1046
- package/dist/activity-oy2YFTFF.js +0 -201
- package/dist/boot-BMBMWUGI.js +0 -1084
- package/dist/capabilities-Bbf0mlp9.js +0 -42
- package/dist/compose-ref-v0qGlHoN.js +0 -26
- package/dist/control-BR_mrX__.js +0 -173
- package/dist/control-C-ApnFs1.js +0 -20
- package/dist/csp-nonce-BfFWcd0w.js +0 -173
- package/dist/data-runtime-CxoY98lX.js +0 -149
- package/dist/default-portal-runtime-DvMvWJVp.js +0 -20
- package/dist/dom-renderer.d.ts +0 -77
- package/dist/domains/renderer.d.ts +0 -127
- package/dist/eager-control.d.ts +0 -8
- package/dist/effect-C3Zsc1k6.js +0 -292
- package/dist/for-state-BDykeOJL.js +0 -1753
- package/dist/instance-VAFYVJOa.js +0 -1027
- package/dist/notify-DxxuDPeY.js +0 -266
- package/dist/portal-w3oQ6oQU.js +0 -29
- package/dist/query-registry-LrYpQsDJ.js +0 -83
- package/dist/render-resolved-BC0W7_5b.js +0 -1123
- package/dist/renderer-CT0HeY58.js +0 -8623
- package/dist/resolution-3DskUkjG.js +0 -577
- package/dist/resource-18-sFRl9.js +0 -344
- package/dist/route-matching-CUzZ31gT.js +0 -551
- package/dist/router-internal-7nuNEHfG.js +0 -36
- package/dist/scope-Cq_iYbTR.js +0 -403
- package/dist/selector-BSPVkjKP.js +0 -311
- package/dist/ssr-EPjwJH5R.js +0 -29
- package/dist/state-BXJfudq1.js +0 -91
- package/dist/structures-CjEzfj4h.js +0 -654
- package/dist/timer-C7uqnJVt.js +0 -85
- package/dist/verify-hydration-ikaxotf7.js +0 -27
- package/dist/vnode-D24p6IW2.js +0 -7
|
@@ -1,1027 +0,0 @@
|
|
|
1
|
-
import { T as isProductionEnvironment, a as getRuntimeEvaluation, i as getRuntimeCleanup, m as runRuntimeWithSyncProgress, n as enqueueRuntimeTask, v as logger, w as isDevelopmentEnvironment } from "./access-CEA2pOry.js";
|
|
2
|
-
import { C as disposeOwnership, D as ownChild, E as getOwnershipSignal, O as ownCleanup, _ as restoreInlineRenderTracking, a as clearCurrentComponentScope, b as attachOwnership, c as enterComponentExecutionScope, f as getCurrentComponentInstance, g as resetRenderState, n as captureInlineComponentScope, o as clearRenderTracking, p as getCurrentPortalScope, r as captureInlineRenderTracking, s as endComponentScope, t as beginRenderTracking, u as enterRenderScopedComponent, x as componentRecordPrototype, y as OwnershipRecord } from "./scope-Cq_iYbTR.js";
|
|
3
|
-
import { t as adoptComponentParent } from "./capabilities-Bbf0mlp9.js";
|
|
4
|
-
import { f as runCommitTransaction, g as finalizeReadableSubscriptionsFromSnapshot, i as commitTransaction, l as registerCommitParticipant, m as cleanupReadableSubscriptionSources, n as applyTransaction, o as discardTransaction, p as suspendTransaction, r as beginCommitTransaction, s as getCurrentCommitTransaction } from "./notify-DxxuDPeY.js";
|
|
5
|
-
import { a as markTransparentComponentResult, i as markEagerControlPrimitive } from "./control-C-ApnFs1.js";
|
|
6
|
-
import { r as STATIC_CHILDREN, t as ELEMENT_TYPE } from "./jsx-DRS-qjiN.js";
|
|
7
|
-
//#region src/runtime/diagnostics/dev-namespace.ts
|
|
8
|
-
/**
|
|
9
|
-
* Set a value in the dev namespace (no-op in production).
|
|
10
|
-
*/
|
|
11
|
-
const setDevValue = () => {};
|
|
12
|
-
/**
|
|
13
|
-
* Increment a counter in the dev namespace (no-op in production).
|
|
14
|
-
* Safely handles non-number values by resetting to 1.
|
|
15
|
-
*/
|
|
16
|
-
const incDevCounter = () => {};
|
|
17
|
-
//#endregion
|
|
18
|
-
//#region src/common/dom-range.ts
|
|
19
|
-
/** Native records expose one renderer-maintained range index. Extension
|
|
20
|
-
* objects remain opaque and use the renderer's external index instead. */
|
|
21
|
-
const DIRECT_RANGE_OWNER = Symbol("askr.directRangeOwner");
|
|
22
|
-
//#endregion
|
|
23
|
-
//#region src/runtime/component/state.ts
|
|
24
|
-
/** Capture generation state without rewinding the monotonic render revision. */
|
|
25
|
-
function captureGenerationExecution(instance) {
|
|
26
|
-
return {
|
|
27
|
-
owner: instance.owner,
|
|
28
|
-
fn: instance.fn,
|
|
29
|
-
props: instance.props,
|
|
30
|
-
expectedStateIndices: instance.expectedStateIndices,
|
|
31
|
-
firstRenderComplete: instance.firstRenderComplete,
|
|
32
|
-
stateIndexCheck: instance.stateIndexCheck,
|
|
33
|
-
errorBoundaryState: instance.errorBoundaryState,
|
|
34
|
-
target: instance.target,
|
|
35
|
-
stateValues: instance.stateValues,
|
|
36
|
-
mountOperations: instance.mountOperations,
|
|
37
|
-
commitOperations: instance.commitOperations,
|
|
38
|
-
lifecycleSlots: instance.lifecycleSlots,
|
|
39
|
-
lifecycleGeneration: instance.lifecycleGeneration,
|
|
40
|
-
evaluationGeneration: instance.evaluationGeneration,
|
|
41
|
-
hasPendingUpdate: instance.hasPendingUpdate,
|
|
42
|
-
notifyUpdate: instance.notifyUpdate,
|
|
43
|
-
_placeholder: instance._placeholder,
|
|
44
|
-
_currentRenderToken: instance._currentRenderToken,
|
|
45
|
-
lastRenderToken: instance.lastRenderToken,
|
|
46
|
-
_pendingReadSources: instance._pendingReadSources,
|
|
47
|
-
_pendingReadSourceVersions: instance._pendingReadSourceVersions,
|
|
48
|
-
_appRenderRuntime: instance._appRenderRuntime
|
|
49
|
-
};
|
|
50
|
-
}
|
|
51
|
-
/** Inline execution capture excludes monotonic revision and subscription identity. */
|
|
52
|
-
function captureInlineExecution(instance) {
|
|
53
|
-
return {
|
|
54
|
-
props: instance.props,
|
|
55
|
-
firstRenderComplete: instance.firstRenderComplete,
|
|
56
|
-
ownerFrame: instance.ownerFrame,
|
|
57
|
-
portalScope: instance.portalScope,
|
|
58
|
-
isRoot: instance.isRoot,
|
|
59
|
-
_vnodeParentGeneration: instance._vnodeParentGeneration,
|
|
60
|
-
_vnodeOwner: instance._vnodeOwner,
|
|
61
|
-
_vnodeParent: instance._vnodeParent,
|
|
62
|
-
_vnodeKey: instance._vnodeKey,
|
|
63
|
-
_vnodePosition: instance._vnodePosition,
|
|
64
|
-
_wrapperDepth: instance._wrapperDepth,
|
|
65
|
-
cleanupStrict: instance.cleanupStrict
|
|
66
|
-
};
|
|
67
|
-
}
|
|
68
|
-
function restoreInlineExecution(instance, execution, hasVNodeKey) {
|
|
69
|
-
Object.assign(instance, execution);
|
|
70
|
-
if (!hasVNodeKey) delete instance._vnodeKey;
|
|
71
|
-
}
|
|
72
|
-
//#endregion
|
|
73
|
-
//#region src/runtime/component/inline-snapshot.ts
|
|
74
|
-
function createInlineRenderSnapshot(instance) {
|
|
75
|
-
return {
|
|
76
|
-
instance,
|
|
77
|
-
mounted: instance.owner.mounted,
|
|
78
|
-
parentInstance: instance.parentInstance,
|
|
79
|
-
parentLifetime: instance.owner.parent,
|
|
80
|
-
hasVNodeKey: "_vnodeKey" in instance,
|
|
81
|
-
execution: captureInlineExecution(instance)
|
|
82
|
-
};
|
|
83
|
-
}
|
|
84
|
-
function restoreInlineRenderSnapshot(snapshot) {
|
|
85
|
-
restoreInlineExecution(snapshot.instance, snapshot.execution, snapshot.hasVNodeKey);
|
|
86
|
-
snapshot.instance.owner.mounted = snapshot.mounted;
|
|
87
|
-
adoptComponentParent(snapshot.instance, snapshot.parentInstance, snapshot.parentLifetime ?? null);
|
|
88
|
-
}
|
|
89
|
-
//#endregion
|
|
90
|
-
//#region src/common/promise.ts
|
|
91
|
-
function isPromiseLike(value) {
|
|
92
|
-
return value !== null && (typeof value === "object" || typeof value === "function") && typeof value.then === "function";
|
|
93
|
-
}
|
|
94
|
-
/**
|
|
95
|
-
* Components must return synchronously; async work belongs in `resource()`.
|
|
96
|
-
*
|
|
97
|
-
* The rule was previously enforced by ten hand-written throws carrying three
|
|
98
|
-
* different messages. It is one rule, so it has one message and one guard.
|
|
99
|
-
*/
|
|
100
|
-
const ASYNC_COMPONENT_MESSAGE = "Async components are not supported. Use resource() for async work.";
|
|
101
|
-
function assertSyncComponentResult(result) {
|
|
102
|
-
if (isPromiseLike(result)) throw new Error(ASYNC_COMPONENT_MESSAGE);
|
|
103
|
-
}
|
|
104
|
-
//#endregion
|
|
105
|
-
//#region src/runtime/lifecycle/settlement.ts
|
|
106
|
-
const LIFECYCLE_COMMIT = {};
|
|
107
|
-
var LifecycleCommit = class {
|
|
108
|
-
constructor(instance, firstMount) {
|
|
109
|
-
this.kind = LIFECYCLE_COMMIT;
|
|
110
|
-
this.prepared = false;
|
|
111
|
-
this.key = instance;
|
|
112
|
-
this.owner = instance.owner;
|
|
113
|
-
this.generation = instance.owner.identity;
|
|
114
|
-
this.firstMount = firstMount;
|
|
115
|
-
}
|
|
116
|
-
merge(parent) {
|
|
117
|
-
parent.update(this.owner, this.generation, this.firstMount);
|
|
118
|
-
}
|
|
119
|
-
update(owner, generation, firstMount) {
|
|
120
|
-
this.firstMount = this.generation === generation ? this.firstMount || firstMount : firstMount;
|
|
121
|
-
this.owner = owner;
|
|
122
|
-
this.generation = generation;
|
|
123
|
-
}
|
|
124
|
-
live() {
|
|
125
|
-
return this.key.owner === this.owner && this.owner.identity === this.generation && !this.owner.disposed;
|
|
126
|
-
}
|
|
127
|
-
publish() {
|
|
128
|
-
if (!this.live()) return;
|
|
129
|
-
if (this.firstMount) {
|
|
130
|
-
this.mounts = this.key.mountOperations;
|
|
131
|
-
this.key.mountOperations = void 0;
|
|
132
|
-
}
|
|
133
|
-
this.commits = this.key.commitOperations;
|
|
134
|
-
this.key.commitOperations = void 0;
|
|
135
|
-
this.prepared = true;
|
|
136
|
-
}
|
|
137
|
-
activate() {
|
|
138
|
-
if (this.prepared && this.live()) executeOwnedLifecycleOperations(this.key.id, this.owner, this.mounts, this.commits);
|
|
139
|
-
}
|
|
140
|
-
rollback() {
|
|
141
|
-
if (!this.live()) return;
|
|
142
|
-
if (this.firstMount) this.key.mountOperations = void 0;
|
|
143
|
-
discardCommitOperations(this.key);
|
|
144
|
-
}
|
|
145
|
-
};
|
|
146
|
-
function enqueueLifecycleCommitForInstance(instance, firstMount) {
|
|
147
|
-
const transaction = getCurrentCommitTransaction();
|
|
148
|
-
if (!transaction) return false;
|
|
149
|
-
const previous = transaction.participant(instance, LIFECYCLE_COMMIT);
|
|
150
|
-
if (previous) previous.update(instance.owner, instance.owner.identity, firstMount);
|
|
151
|
-
else registerCommitParticipant(new LifecycleCommit(instance, firstMount));
|
|
152
|
-
return true;
|
|
153
|
-
}
|
|
154
|
-
function settleLifecycleOperationResult(owner, result) {
|
|
155
|
-
if (isPromiseLike(result)) Promise.resolve(result).then((cleanup) => {
|
|
156
|
-
if (typeof cleanup === "function") {
|
|
157
|
-
if (!owner.disposed && owner.mounted) {
|
|
158
|
-
ownCleanup(owner, cleanup);
|
|
159
|
-
return;
|
|
160
|
-
}
|
|
161
|
-
try {
|
|
162
|
-
cleanup();
|
|
163
|
-
} catch (err) {
|
|
164
|
-
logger.error("[Askr] async mount cleanup failed:", err);
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
}, (err) => {
|
|
168
|
-
logger.error("[Askr] async mount operation failed:", err);
|
|
169
|
-
});
|
|
170
|
-
else if (typeof result === "function") ownCleanup(owner, result);
|
|
171
|
-
}
|
|
172
|
-
function discardCommitOperations(instance) {
|
|
173
|
-
instance.commitOperations = void 0;
|
|
174
|
-
}
|
|
175
|
-
function executeOwnedLifecycleOperations(id, owner, mounts, commits) {
|
|
176
|
-
const errors = [];
|
|
177
|
-
for (const operations of [mounts, commits]) for (const operation of operations ?? []) try {
|
|
178
|
-
settleLifecycleOperationResult(owner, operation());
|
|
179
|
-
} catch (error) {
|
|
180
|
-
errors.push(error);
|
|
181
|
-
}
|
|
182
|
-
if (errors.length > 0) throw new AggregateError(errors, `Committed lifecycle operations failed for ${id}`);
|
|
183
|
-
}
|
|
184
|
-
//#endregion
|
|
185
|
-
//#region src/runtime/transactions/render.ts
|
|
186
|
-
const READ_COMMIT = {};
|
|
187
|
-
const INLINE_SNAPSHOT = {};
|
|
188
|
-
var ReadCommit = class {
|
|
189
|
-
constructor(instance, token, sources, versions) {
|
|
190
|
-
this.kind = READ_COMMIT;
|
|
191
|
-
this.key = instance;
|
|
192
|
-
this.update(token, sources, versions);
|
|
193
|
-
}
|
|
194
|
-
update(token, sources, versions) {
|
|
195
|
-
this.generation = this.key.owner.identity;
|
|
196
|
-
this.token = token;
|
|
197
|
-
this.sources = sources ? new Set(sources) : void 0;
|
|
198
|
-
this.versions = versions ? new Map(versions) : void 0;
|
|
199
|
-
}
|
|
200
|
-
merge(parent) {
|
|
201
|
-
const previous = parent;
|
|
202
|
-
previous.generation = this.generation;
|
|
203
|
-
previous.token = this.token;
|
|
204
|
-
previous.sources = this.sources;
|
|
205
|
-
previous.versions = this.versions;
|
|
206
|
-
}
|
|
207
|
-
publish() {
|
|
208
|
-
const instance = this.key;
|
|
209
|
-
if (instance.owner.disposed || instance.owner.identity !== this.generation) return;
|
|
210
|
-
const { readers, sources } = this.previous = {
|
|
211
|
-
sources: instance.owner.reads,
|
|
212
|
-
token: instance.lastRenderToken,
|
|
213
|
-
readers: /* @__PURE__ */ new Map()
|
|
214
|
-
};
|
|
215
|
-
for (const source of sources ?? []) readers.set(source, source._readers?.get(instance));
|
|
216
|
-
for (const source of this.sources ?? []) if (!readers.has(source)) readers.set(source, source._readers?.get(instance));
|
|
217
|
-
finalizeReadableSubscriptionsFromSnapshot(instance, this.token, this.sources, this.versions, this.generation);
|
|
218
|
-
}
|
|
219
|
-
rollback() {
|
|
220
|
-
const instance = this.key;
|
|
221
|
-
if (!this.previous || instance.owner.disposed || instance.owner.identity !== this.generation) return;
|
|
222
|
-
instance.owner.reads = this.previous.sources;
|
|
223
|
-
instance.lastRenderToken = this.previous.token;
|
|
224
|
-
const errors = [];
|
|
225
|
-
for (const [source, entry] of this.previous.readers) try {
|
|
226
|
-
source._readers?.get(instance);
|
|
227
|
-
if (entry) (source._readers ??= /* @__PURE__ */ new Map()).set(instance, entry);
|
|
228
|
-
else if (source._readers?.delete(instance) && false);
|
|
229
|
-
} catch (error) {
|
|
230
|
-
errors.push(error);
|
|
231
|
-
}
|
|
232
|
-
if (errors.length) throw new AggregateError(errors, "Read subscription restoration failed");
|
|
233
|
-
}
|
|
234
|
-
};
|
|
235
|
-
var InlineSnapshot = class {
|
|
236
|
-
constructor(instance) {
|
|
237
|
-
this.kind = INLINE_SNAPSHOT;
|
|
238
|
-
this.key = instance;
|
|
239
|
-
this.generation = instance.owner.identity;
|
|
240
|
-
this.snapshot = createInlineRenderSnapshot(instance);
|
|
241
|
-
this.revision = instance.renderRevision;
|
|
242
|
-
}
|
|
243
|
-
merge(parent) {
|
|
244
|
-
parent.revision = this.revision;
|
|
245
|
-
}
|
|
246
|
-
rollback() {
|
|
247
|
-
if (!this.key.owner.disposed && this.key.owner.identity === this.generation && this.key.renderRevision === this.revision) restoreInlineRenderSnapshot(this.snapshot);
|
|
248
|
-
}
|
|
249
|
-
};
|
|
250
|
-
function sealInlineRenderSnapshot(instance) {
|
|
251
|
-
const snapshot = getCurrentCommitTransaction()?.participant(instance, INLINE_SNAPSHOT);
|
|
252
|
-
if (snapshot) snapshot.revision = instance.renderRevision;
|
|
253
|
-
}
|
|
254
|
-
function captureInlineRenderSnapshot$1(instance) {
|
|
255
|
-
const transaction = getCurrentCommitTransaction();
|
|
256
|
-
if (!transaction || transaction.participant(instance, INLINE_SNAPSHOT)) return;
|
|
257
|
-
registerCommitParticipant(new InlineSnapshot(instance));
|
|
258
|
-
}
|
|
259
|
-
function finalizeInlineReadSubscriptions(instance, token, sources, versions) {
|
|
260
|
-
if (!sources?.size && !instance.owner.reads?.size) return;
|
|
261
|
-
const transaction = getCurrentCommitTransaction();
|
|
262
|
-
if (!transaction) {
|
|
263
|
-
runCommitTransaction(() => registerCommitParticipant(new ReadCommit(instance, token, sources, versions)));
|
|
264
|
-
return;
|
|
265
|
-
}
|
|
266
|
-
const existing = transaction.participant(instance, READ_COMMIT);
|
|
267
|
-
if (existing) existing.update(token, sources, versions);
|
|
268
|
-
else registerCommitParticipant(new ReadCommit(instance, token, sources, versions));
|
|
269
|
-
}
|
|
270
|
-
//#endregion
|
|
271
|
-
//#region src/runtime/diagnostics/state-diagnostics.ts
|
|
272
|
-
/**
|
|
273
|
-
* Report state cells that were never read during a component's completed
|
|
274
|
-
* lifetime. A branch that has not rendered yet is not evidence that its state
|
|
275
|
-
* is unused, so this diagnostic belongs at unmount rather than every commit.
|
|
276
|
-
*/
|
|
277
|
-
function warnUnusedStateReads(instance) {
|
|
278
|
-
if (!instance.owner.mounted) return;
|
|
279
|
-
const stateValues = instance.stateValues;
|
|
280
|
-
if (!stateValues?.length || isProductionEnvironment()) return;
|
|
281
|
-
for (let i = 0; i < stateValues.length; i++) {
|
|
282
|
-
const state = stateValues[i];
|
|
283
|
-
const diagnosticEligible = state?._unusedStateDiagnosticEligible;
|
|
284
|
-
const hasCommittedUsage = (state?._readers?.size ?? 0) > 0 || (state?._derivedSubscribers?.size ?? 0) > 0;
|
|
285
|
-
if (state && diagnosticEligible !== false && !state._hasEverBeenRead && !hasCommittedUsage) {
|
|
286
|
-
const warnings = instance.devWarningsEmitted ??= /* @__PURE__ */ new Set();
|
|
287
|
-
const key = `unused-state:${i}`;
|
|
288
|
-
if (warnings.has(key)) continue;
|
|
289
|
-
warnings.add(key);
|
|
290
|
-
try {
|
|
291
|
-
const name = instance.fn?.name || "<anonymous>";
|
|
292
|
-
logger.warn(`[askr] Unused state variable detected in ${name} at index ${i}. State should be read during render or removed.`);
|
|
293
|
-
} catch {
|
|
294
|
-
logger.warn("[askr] Unused state variable detected. State should be read during render or removed.");
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
}
|
|
298
|
-
}
|
|
299
|
-
//#endregion
|
|
300
|
-
//#region src/runtime/component/reset.ts
|
|
301
|
-
/** Pending work belongs to one generation and cannot survive its retirement. */
|
|
302
|
-
function resetComponentWork(instance) {
|
|
303
|
-
instance.hasPendingUpdate = false;
|
|
304
|
-
instance.notifyUpdate = null;
|
|
305
|
-
instance.mountOperations = void 0;
|
|
306
|
-
instance.commitOperations = void 0;
|
|
307
|
-
instance.lifecycleSlots = void 0;
|
|
308
|
-
instance._pendingReadSources = void 0;
|
|
309
|
-
instance._pendingReadSourceVersions = void 0;
|
|
310
|
-
instance._placeholder = void 0;
|
|
311
|
-
}
|
|
312
|
-
//#endregion
|
|
313
|
-
//#region src/runtime/component/cleanup.ts
|
|
314
|
-
function componentDisposalPhases(owner) {
|
|
315
|
-
const instance = owner.subject;
|
|
316
|
-
const active = instance.owner === owner;
|
|
317
|
-
const hadRendererHost = Boolean(instance.target || instance._placeholder);
|
|
318
|
-
let savedScope;
|
|
319
|
-
const errors = instance.cleanupStrict ? [] : void 0;
|
|
320
|
-
const retiredScopes = active ? void 0 : owner.scopedIndex;
|
|
321
|
-
const detachReads = () => {
|
|
322
|
-
retiredScopes?.clear();
|
|
323
|
-
cleanupReadableSubscriptionSources(instance, owner.reads, owner.identity);
|
|
324
|
-
};
|
|
325
|
-
const recordError = (message, error) => {
|
|
326
|
-
if (errors) errors.push(error);
|
|
327
|
-
else if (isDevelopmentEnvironment()) logger.warn(message, error);
|
|
328
|
-
};
|
|
329
|
-
return {
|
|
330
|
-
begin() {
|
|
331
|
-
savedScope = clearCurrentComponentScope();
|
|
332
|
-
if (active) {
|
|
333
|
-
instance.lifecycleGeneration++;
|
|
334
|
-
instance.evaluationGeneration++;
|
|
335
|
-
instance.hasPendingUpdate = false;
|
|
336
|
-
instance.notifyUpdate = null;
|
|
337
|
-
warnUnusedStateReads(instance);
|
|
338
|
-
}
|
|
339
|
-
},
|
|
340
|
-
beforeCleanup: active ? void 0 : detachReads,
|
|
341
|
-
afterCleanup: active ? detachReads : void 0,
|
|
342
|
-
recordError,
|
|
343
|
-
finish() {
|
|
344
|
-
try {
|
|
345
|
-
if (active && instance.owner === owner) {
|
|
346
|
-
try {
|
|
347
|
-
if (hadRendererHost) getRuntimeCleanup().releaseComponentHost(instance);
|
|
348
|
-
} catch (error) {
|
|
349
|
-
recordError("[Askr] host release failed:", error);
|
|
350
|
-
}
|
|
351
|
-
resetComponentWork(instance);
|
|
352
|
-
instance._portalErrorParent = void 0;
|
|
353
|
-
instance._portalErrorParentGeneration = void 0;
|
|
354
|
-
}
|
|
355
|
-
if (errors?.length) throw new AggregateError(errors, `Cleanup failed for component ${instance.id}`);
|
|
356
|
-
} finally {
|
|
357
|
-
endComponentScope(savedScope);
|
|
358
|
-
}
|
|
359
|
-
}
|
|
360
|
-
};
|
|
361
|
-
}
|
|
362
|
-
function createComponentOwnership(instance) {
|
|
363
|
-
const owner = new OwnershipRecord();
|
|
364
|
-
owner.subject = instance;
|
|
365
|
-
owner.lifecycle = componentDisposalPhases;
|
|
366
|
-
return owner;
|
|
367
|
-
}
|
|
368
|
-
function bindComponentOwnership(instance) {
|
|
369
|
-
instance.owner.subject = instance;
|
|
370
|
-
instance.owner.lifecycle = componentDisposalPhases;
|
|
371
|
-
}
|
|
372
|
-
/** Retire the captured lifetime without swapping the execution record. */
|
|
373
|
-
function cleanupComponentGeneration(_instance, owner) {
|
|
374
|
-
disposeOwnership(owner);
|
|
375
|
-
}
|
|
376
|
-
function cleanupComponent(instance) {
|
|
377
|
-
disposeOwnership(instance.owner);
|
|
378
|
-
}
|
|
379
|
-
function registerOwnedChildScope(instance, scope) {
|
|
380
|
-
ownChild(instance.owner, scope);
|
|
381
|
-
}
|
|
382
|
-
//#endregion
|
|
383
|
-
//#region src/runtime/context/vnode.ts
|
|
384
|
-
const CONTEXT_FRAME_SYMBOL = Symbol("__tempoContextFrame__");
|
|
385
|
-
const vnodeContextFrames = /* @__PURE__ */ new WeakMap();
|
|
386
|
-
function getVNodeContextFrame(node) {
|
|
387
|
-
if (typeof node !== "object" || node === null) return;
|
|
388
|
-
const objectNode = node;
|
|
389
|
-
return vnodeContextFrames.get(node) ?? objectNode[CONTEXT_FRAME_SYMBOL];
|
|
390
|
-
}
|
|
391
|
-
function markVNodeWithContextFrame(node, frame, overwrite = false) {
|
|
392
|
-
if (typeof node !== "object" || node === null) return;
|
|
393
|
-
if (!overwrite && getVNodeContextFrame(node)) return;
|
|
394
|
-
const objectNode = node;
|
|
395
|
-
if (Object.prototype.hasOwnProperty.call(node, CONTEXT_FRAME_SYMBOL)) try {
|
|
396
|
-
objectNode[CONTEXT_FRAME_SYMBOL] = frame;
|
|
397
|
-
return;
|
|
398
|
-
} catch {}
|
|
399
|
-
if (Object.isExtensible(node)) try {
|
|
400
|
-
Object.defineProperty(node, CONTEXT_FRAME_SYMBOL, {
|
|
401
|
-
value: frame,
|
|
402
|
-
writable: true,
|
|
403
|
-
enumerable: true,
|
|
404
|
-
configurable: true
|
|
405
|
-
});
|
|
406
|
-
return;
|
|
407
|
-
} catch {}
|
|
408
|
-
vnodeContextFrames.set(node, frame);
|
|
409
|
-
}
|
|
410
|
-
function isVNodeLike(value) {
|
|
411
|
-
if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
|
|
412
|
-
const objectValue = value;
|
|
413
|
-
if (objectValue.$$typeof === ELEMENT_TYPE) return true;
|
|
414
|
-
return "type" in objectValue && ("props" in objectValue || "children" in objectValue);
|
|
415
|
-
}
|
|
416
|
-
function markContextPropValue(value, frame, overwrite) {
|
|
417
|
-
if (Array.isArray(value)) {
|
|
418
|
-
for (const item of value) markContextPropValue(item, frame, overwrite);
|
|
419
|
-
return;
|
|
420
|
-
}
|
|
421
|
-
if (isVNodeLike(value)) markVNodeTreeWithContextFrame(value, frame, overwrite);
|
|
422
|
-
}
|
|
423
|
-
function markVNodeTreeWithContextFrame(node, frame, overwrite = false) {
|
|
424
|
-
if (!frame) return node;
|
|
425
|
-
if (Array.isArray(node)) {
|
|
426
|
-
for (const child of node) markVNodeTreeWithContextFrame(child, frame, overwrite);
|
|
427
|
-
return node;
|
|
428
|
-
}
|
|
429
|
-
if (typeof node !== "object" || node === null) return node;
|
|
430
|
-
markVNodeWithContextFrame(node, frame, overwrite);
|
|
431
|
-
const objectNode = node;
|
|
432
|
-
const props = typeof objectNode.props === "object" && objectNode.props !== null ? objectNode.props : null;
|
|
433
|
-
const children = props?.children ?? objectNode.children;
|
|
434
|
-
if (Array.isArray(children)) for (const child of children) markVNodeTreeWithContextFrame(child, frame, overwrite);
|
|
435
|
-
else if (children) markVNodeTreeWithContextFrame(children, frame, overwrite);
|
|
436
|
-
if (props) {
|
|
437
|
-
for (const key in props) if (key !== "children") markContextPropValue(props[key], frame, overwrite);
|
|
438
|
-
}
|
|
439
|
-
return node;
|
|
440
|
-
}
|
|
441
|
-
function isContextFrameDescendantOf(frame, ancestor) {
|
|
442
|
-
let current = frame;
|
|
443
|
-
while (current) {
|
|
444
|
-
if (current === ancestor) return true;
|
|
445
|
-
current = current.parent;
|
|
446
|
-
}
|
|
447
|
-
return false;
|
|
448
|
-
}
|
|
449
|
-
function rebaseContextFrame(frame, previousOwnerFrame, ownerFrame) {
|
|
450
|
-
if (isContextFrameDescendantOf(frame, ownerFrame)) return frame;
|
|
451
|
-
if (!previousOwnerFrame || !isContextFrameDescendantOf(frame, previousOwnerFrame)) return ownerFrame;
|
|
452
|
-
const nestedFrames = [];
|
|
453
|
-
let current = frame;
|
|
454
|
-
while (current && current !== previousOwnerFrame) {
|
|
455
|
-
nestedFrames.push(current);
|
|
456
|
-
current = current.parent;
|
|
457
|
-
}
|
|
458
|
-
let rebasedFrame = ownerFrame;
|
|
459
|
-
for (let index = nestedFrames.length - 1; index >= 0; index -= 1) {
|
|
460
|
-
const nestedFrame = nestedFrames[index];
|
|
461
|
-
rebasedFrame = {
|
|
462
|
-
parent: rebasedFrame,
|
|
463
|
-
values: nestedFrame.values ? new Map(nestedFrame.values) : null
|
|
464
|
-
};
|
|
465
|
-
}
|
|
466
|
-
return rebasedFrame;
|
|
467
|
-
}
|
|
468
|
-
/**
|
|
469
|
-
* Stamp a child-scope result with its current owner while retaining frames
|
|
470
|
-
* introduced by providers nested beneath that owner. Frames from an unrelated
|
|
471
|
-
* or previous owner are rebased so reused vnodes cannot keep stale context.
|
|
472
|
-
*/
|
|
473
|
-
function rebaseVNodeTreeWithContextFrame(node, ownerFrame, previousOwnerFrame = null) {
|
|
474
|
-
if (!ownerFrame) return node;
|
|
475
|
-
if (Array.isArray(node)) {
|
|
476
|
-
for (const child of node) rebaseVNodeTreeWithContextFrame(child, ownerFrame, previousOwnerFrame);
|
|
477
|
-
return node;
|
|
478
|
-
}
|
|
479
|
-
if (typeof node !== "object" || node === null) return node;
|
|
480
|
-
const existingFrame = getVNodeContextFrame(node);
|
|
481
|
-
const inheritedFrame = existingFrame ? rebaseContextFrame(existingFrame, previousOwnerFrame, ownerFrame) : ownerFrame;
|
|
482
|
-
markVNodeWithContextFrame(node, inheritedFrame, true);
|
|
483
|
-
const inheritedPreviousFrame = existingFrame ?? previousOwnerFrame;
|
|
484
|
-
const objectNode = node;
|
|
485
|
-
const props = typeof objectNode.props === "object" && objectNode.props !== null ? objectNode.props : null;
|
|
486
|
-
const children = props?.children ?? objectNode.children;
|
|
487
|
-
if (Array.isArray(children)) for (const child of children) rebaseVNodeTreeWithContextFrame(child, inheritedFrame, inheritedPreviousFrame);
|
|
488
|
-
else if (children) rebaseVNodeTreeWithContextFrame(children, inheritedFrame, inheritedPreviousFrame);
|
|
489
|
-
if (props) {
|
|
490
|
-
for (const key in props) if (key !== "children") {
|
|
491
|
-
const value = props[key];
|
|
492
|
-
if (Array.isArray(value)) {
|
|
493
|
-
for (const item of value) if (isVNodeLike(item)) rebaseVNodeTreeWithContextFrame(item, inheritedFrame, inheritedPreviousFrame);
|
|
494
|
-
} else if (isVNodeLike(value)) rebaseVNodeTreeWithContextFrame(value, inheritedFrame, inheritedPreviousFrame);
|
|
495
|
-
}
|
|
496
|
-
}
|
|
497
|
-
return node;
|
|
498
|
-
}
|
|
499
|
-
//#endregion
|
|
500
|
-
//#region src/runtime/context/context.ts
|
|
501
|
-
const TransparentContextScopeComponent = markTransparentComponentResult(ContextScopeComponent);
|
|
502
|
-
let nextScopeIdentityKey = 0;
|
|
503
|
-
/** @internal Compare immutable context snapshots by provider identity and value. */
|
|
504
|
-
function haveEquivalentContextFrames(left, right) {
|
|
505
|
-
let leftFrame = left;
|
|
506
|
-
let rightFrame = right;
|
|
507
|
-
while (true) {
|
|
508
|
-
while (leftFrame && !leftFrame.values?.size) leftFrame = leftFrame.parent;
|
|
509
|
-
while (rightFrame && !rightFrame.values?.size) rightFrame = rightFrame.parent;
|
|
510
|
-
if (leftFrame === rightFrame) return true;
|
|
511
|
-
if (!leftFrame || !rightFrame) return false;
|
|
512
|
-
const leftValues = leftFrame.values;
|
|
513
|
-
const rightValues = rightFrame.values;
|
|
514
|
-
if (leftValues?.size !== rightValues?.size) return false;
|
|
515
|
-
if (leftValues) {
|
|
516
|
-
if (!rightValues) return false;
|
|
517
|
-
for (const [key, value] of leftValues) if (!rightValues.has(key) || !Object.is(rightValues.get(key), value)) return false;
|
|
518
|
-
}
|
|
519
|
-
leftFrame = leftFrame.parent;
|
|
520
|
-
rightFrame = rightFrame.parent;
|
|
521
|
-
}
|
|
522
|
-
}
|
|
523
|
-
const ROOT_EXECUTION_FRAME = {
|
|
524
|
-
parent: null,
|
|
525
|
-
values: null
|
|
526
|
-
};
|
|
527
|
-
const executionFramesByParent = /* @__PURE__ */ new WeakMap();
|
|
528
|
-
/** @internal Reuse immutable empty wrappers for the same provider snapshot. */
|
|
529
|
-
function getExecutionContextFrame(parent) {
|
|
530
|
-
if (!parent) return ROOT_EXECUTION_FRAME;
|
|
531
|
-
let frame = executionFramesByParent.get(parent);
|
|
532
|
-
if (!frame) {
|
|
533
|
-
frame = {
|
|
534
|
-
parent,
|
|
535
|
-
values: null
|
|
536
|
-
};
|
|
537
|
-
executionFramesByParent.set(parent, frame);
|
|
538
|
-
}
|
|
539
|
-
return frame;
|
|
540
|
-
}
|
|
541
|
-
let currentContextFrame = null;
|
|
542
|
-
let currentAsyncResourceFrame = null;
|
|
543
|
-
/**
|
|
544
|
-
* Execute a function within a specific context frame.
|
|
545
|
-
*
|
|
546
|
-
* CORE PRIMITIVE for context restoration:
|
|
547
|
-
* - Saves the current context
|
|
548
|
-
* - Sets the provided frame as current
|
|
549
|
-
* - Executes the function
|
|
550
|
-
* - Restores the previous context in finally
|
|
551
|
-
*
|
|
552
|
-
* This ensures no context frame remains globally active across await.
|
|
553
|
-
*/
|
|
554
|
-
function withContext(frame, fn) {
|
|
555
|
-
const oldFrame = currentContextFrame;
|
|
556
|
-
currentContextFrame = frame;
|
|
557
|
-
try {
|
|
558
|
-
return fn();
|
|
559
|
-
} finally {
|
|
560
|
-
currentContextFrame = oldFrame;
|
|
561
|
-
}
|
|
562
|
-
}
|
|
563
|
-
/** @internal Invoke a two-argument function without allocating a wrapper. */
|
|
564
|
-
function callWithContext(frame, fn, args, context) {
|
|
565
|
-
const oldFrame = currentContextFrame;
|
|
566
|
-
currentContextFrame = frame;
|
|
567
|
-
try {
|
|
568
|
-
return fn(args, context);
|
|
569
|
-
} finally {
|
|
570
|
-
currentContextFrame = oldFrame;
|
|
571
|
-
}
|
|
572
|
-
}
|
|
573
|
-
/**
|
|
574
|
-
* Execute an async resource step within its frozen context snapshot.
|
|
575
|
-
*
|
|
576
|
-
* CRITICAL: This wrapper is applied only to synchronous execution steps of
|
|
577
|
-
* an async resource (the initial call). We intentionally DO NOT restore
|
|
578
|
-
* the resource frame for post-await continuations — continuations must not
|
|
579
|
-
* observe or rely on a live resource frame. This keeps semantics simple and
|
|
580
|
-
* deterministic: async resources see only their creation-time snapshot.
|
|
581
|
-
*/
|
|
582
|
-
function withAsyncResourceContext(frame, fn) {
|
|
583
|
-
const oldFrame = currentAsyncResourceFrame;
|
|
584
|
-
currentAsyncResourceFrame = frame;
|
|
585
|
-
try {
|
|
586
|
-
return fn();
|
|
587
|
-
} finally {
|
|
588
|
-
currentAsyncResourceFrame = oldFrame;
|
|
589
|
-
}
|
|
590
|
-
}
|
|
591
|
-
/** Create a new lexical {@link Scope} with `defaultValue`, readable via {@link readScope}. */
|
|
592
|
-
function defineScope(defaultValue) {
|
|
593
|
-
const key = Symbol("AskrContext");
|
|
594
|
-
const identityKey = nextScopeIdentityKey++;
|
|
595
|
-
const scope = markEagerControlPrimitive((props) => ({
|
|
596
|
-
$$typeof: ELEMENT_TYPE,
|
|
597
|
-
type: TransparentContextScopeComponent,
|
|
598
|
-
props: {
|
|
599
|
-
__askrIdentityKey: identityKey,
|
|
600
|
-
__scopeKey: key,
|
|
601
|
-
value: props.value,
|
|
602
|
-
children: props.children
|
|
603
|
-
},
|
|
604
|
-
key: null
|
|
605
|
-
}));
|
|
606
|
-
return Object.assign(scope, {
|
|
607
|
-
key,
|
|
608
|
-
defaultValue
|
|
609
|
-
});
|
|
610
|
-
}
|
|
611
|
-
function preserveStaticChildrenMarker(source, target) {
|
|
612
|
-
if (source[STATIC_CHILDREN] === true) Object.defineProperty(target, STATIC_CHILDREN, {
|
|
613
|
-
value: true,
|
|
614
|
-
enumerable: false,
|
|
615
|
-
configurable: true
|
|
616
|
-
});
|
|
617
|
-
return target;
|
|
618
|
-
}
|
|
619
|
-
function isPresentRenderable(value) {
|
|
620
|
-
return value !== null && value !== void 0 && value !== false;
|
|
621
|
-
}
|
|
622
|
-
/** Read the current value of a {@link Scope} during component render or an async resource. */
|
|
623
|
-
function readScope(context) {
|
|
624
|
-
const frame = currentContextFrame || currentAsyncResourceFrame;
|
|
625
|
-
if (!frame) throw new Error("readScope() can only be called during component render or async resource execution. Ensure you are calling this from inside your component or resource function.");
|
|
626
|
-
let current = frame;
|
|
627
|
-
while (current) {
|
|
628
|
-
const values = current.values;
|
|
629
|
-
if (values && values.has(context.key)) return values.get(context.key);
|
|
630
|
-
current = current.parent;
|
|
631
|
-
}
|
|
632
|
-
return context.defaultValue;
|
|
633
|
-
}
|
|
634
|
-
/**
|
|
635
|
-
* Internal component that manages context frame
|
|
636
|
-
* Used by a scope component to provide a shadowed value to its children.
|
|
637
|
-
*/
|
|
638
|
-
function ContextScopeComponent(props) {
|
|
639
|
-
const key = props["__scopeKey"];
|
|
640
|
-
const value = props["value"];
|
|
641
|
-
const children = props["children"];
|
|
642
|
-
const instance = getCurrentComponentInstance();
|
|
643
|
-
const newFrame = {
|
|
644
|
-
parent: (() => {
|
|
645
|
-
if (currentContextFrame) return currentContextFrame;
|
|
646
|
-
if (instance && instance.ownerFrame) return instance.ownerFrame;
|
|
647
|
-
return null;
|
|
648
|
-
})(),
|
|
649
|
-
values: /* @__PURE__ */ new Map([[key, value]])
|
|
650
|
-
};
|
|
651
|
-
function createFunctionChildInvoker(fn, frame, owner) {
|
|
652
|
-
return {
|
|
653
|
-
type: ContextFunctionChildInvoker,
|
|
654
|
-
props: {
|
|
655
|
-
fn,
|
|
656
|
-
__frame: frame,
|
|
657
|
-
__owner: owner
|
|
658
|
-
}
|
|
659
|
-
};
|
|
660
|
-
}
|
|
661
|
-
if (Array.isArray(children)) return preserveStaticChildrenMarker(children, children.map((child) => {
|
|
662
|
-
if (typeof child === "function") return createFunctionChildInvoker(child, newFrame, getCurrentComponentInstance());
|
|
663
|
-
return markWithFrame(child, newFrame);
|
|
664
|
-
}));
|
|
665
|
-
else if (typeof children === "function") return createFunctionChildInvoker(children, newFrame, getCurrentComponentInstance());
|
|
666
|
-
else if (isPresentRenderable(children)) return markWithFrame(children, newFrame);
|
|
667
|
-
return null;
|
|
668
|
-
}
|
|
669
|
-
/**
|
|
670
|
-
* Internal: Mark a vnode with a context frame
|
|
671
|
-
* The renderer will restore this frame before executing component functions
|
|
672
|
-
*/
|
|
673
|
-
function markWithFrame(node, frame) {
|
|
674
|
-
return markVNodeTreeWithContextFrame(node, frame, true);
|
|
675
|
-
}
|
|
676
|
-
/**
|
|
677
|
-
* Internal helper component: executes a function-child lazily inside the
|
|
678
|
-
* provided frame and marks the returned subtree with that frame so later
|
|
679
|
-
* component executions will restore the correct context frame.
|
|
680
|
-
*
|
|
681
|
-
* SNAPSHOT SEMANTIC: The frame passed here is the snapshot captured at render
|
|
682
|
-
* time. Any resources created during this execution will observe this frozen
|
|
683
|
-
* snapshot, ensuring deterministic behavior.
|
|
684
|
-
*/
|
|
685
|
-
function ContextFunctionChildInvoker(props) {
|
|
686
|
-
const { fn, __frame } = props;
|
|
687
|
-
const res = withContext(__frame, () => fn());
|
|
688
|
-
if (isPresentRenderable(res)) return markWithFrame(res, __frame);
|
|
689
|
-
return null;
|
|
690
|
-
}
|
|
691
|
-
/**
|
|
692
|
-
* Get the current context frame for inspection (used by tests/diagnostics only)
|
|
693
|
-
*/
|
|
694
|
-
function getCurrentContextFrame() {
|
|
695
|
-
return currentContextFrame;
|
|
696
|
-
}
|
|
697
|
-
//#endregion
|
|
698
|
-
//#region src/runtime/diagnostics/render-diagnostics.ts
|
|
699
|
-
let renderDiagnostics = {
|
|
700
|
-
slowRenderWarnings: true,
|
|
701
|
-
slowRenderThresholdMs: 5
|
|
702
|
-
};
|
|
703
|
-
/**
|
|
704
|
-
* Configure development render diagnostics and return a function that restores
|
|
705
|
-
* the previous configuration. Component counters and timing remain enabled
|
|
706
|
-
* when warning output is disabled.
|
|
707
|
-
*/
|
|
708
|
-
function configureRenderDiagnostics(options) {
|
|
709
|
-
if (options.slowRenderThresholdMs !== void 0 && (!Number.isFinite(options.slowRenderThresholdMs) || options.slowRenderThresholdMs < 0)) throw new TypeError("configureRenderDiagnostics slowRenderThresholdMs must be a finite, non-negative number.");
|
|
710
|
-
const previous = renderDiagnostics;
|
|
711
|
-
renderDiagnostics = {
|
|
712
|
-
slowRenderWarnings: options.slowRenderWarnings ?? previous.slowRenderWarnings,
|
|
713
|
-
slowRenderThresholdMs: options.slowRenderThresholdMs ?? previous.slowRenderThresholdMs
|
|
714
|
-
};
|
|
715
|
-
let restored = false;
|
|
716
|
-
return () => {
|
|
717
|
-
if (restored) return;
|
|
718
|
-
restored = true;
|
|
719
|
-
if (renderDiagnostics === previous) return;
|
|
720
|
-
renderDiagnostics = previous;
|
|
721
|
-
};
|
|
722
|
-
}
|
|
723
|
-
function shouldWarnSlowRender(renderTimeMs) {
|
|
724
|
-
return renderDiagnostics.slowRenderWarnings && renderTimeMs > renderDiagnostics.slowRenderThresholdMs;
|
|
725
|
-
}
|
|
726
|
-
//#endregion
|
|
727
|
-
//#region src/runtime/component/lifecycle.ts
|
|
728
|
-
function registerCommitOperationForInstance(instance, operation) {
|
|
729
|
-
if (instance) (instance.commitOperations ??= []).push(operation);
|
|
730
|
-
}
|
|
731
|
-
function commitLifecycleForInstance(instance, wasFirstMount) {
|
|
732
|
-
if ((instance.mountOperations?.length ?? 0) === 0 && (instance.commitOperations?.length ?? 0) === 0) return;
|
|
733
|
-
if (enqueueLifecycleCommitForInstance(instance, wasFirstMount)) return;
|
|
734
|
-
runCommitTransaction(() => enqueueLifecycleCommitForInstance(instance, wasFirstMount));
|
|
735
|
-
}
|
|
736
|
-
function commitRenderedComponent$1(instance) {
|
|
737
|
-
if (instance.owner.mounted && (instance.commitOperations?.length ?? 0) > 0) commitLifecycleForInstance(instance, false);
|
|
738
|
-
}
|
|
739
|
-
//#endregion
|
|
740
|
-
//#region src/runtime/component/error-boundary.ts
|
|
741
|
-
function createBoundaryReset(instance) {
|
|
742
|
-
return () => {
|
|
743
|
-
const boundaryState = instance.errorBoundaryState;
|
|
744
|
-
if (!boundaryState) return;
|
|
745
|
-
boundaryState.error = null;
|
|
746
|
-
boundaryState.notified = false;
|
|
747
|
-
queueMicrotask(() => {
|
|
748
|
-
instance._enqueueRun?.();
|
|
749
|
-
});
|
|
750
|
-
};
|
|
751
|
-
}
|
|
752
|
-
function reportBoundaryError(instance, error, onError) {
|
|
753
|
-
const boundaryState = instance.errorBoundaryState;
|
|
754
|
-
if (boundaryState && Object.is(boundaryState.error, error) && boundaryState.notified) return;
|
|
755
|
-
if (boundaryState) {
|
|
756
|
-
boundaryState.error = error;
|
|
757
|
-
boundaryState.notified = true;
|
|
758
|
-
}
|
|
759
|
-
try {
|
|
760
|
-
onError?.(error);
|
|
761
|
-
} catch (hookError) {
|
|
762
|
-
logger.error("[Askr] ErrorBoundary onError handler threw:", hookError);
|
|
763
|
-
}
|
|
764
|
-
logger.error("[Askr] ErrorBoundary caught render error:", error);
|
|
765
|
-
}
|
|
766
|
-
function getLivePortalErrorParent(instance) {
|
|
767
|
-
const parent = instance._portalErrorParent;
|
|
768
|
-
if (!parent || parent.owner.identity !== instance._portalErrorParentGeneration || parent.notifyUpdate === null) return null;
|
|
769
|
-
return parent;
|
|
770
|
-
}
|
|
771
|
-
function findLiveErrorBoundary(failedInstance) {
|
|
772
|
-
const visited = /* @__PURE__ */ new Set([failedInstance]);
|
|
773
|
-
const visit = (instance) => {
|
|
774
|
-
if (!instance || visited.has(instance)) return null;
|
|
775
|
-
visited.add(instance);
|
|
776
|
-
if (instance.errorBoundaryState && instance.notifyUpdate !== null) return instance;
|
|
777
|
-
return visit(getLivePortalErrorParent(instance)) ?? visit(instance.parentInstance);
|
|
778
|
-
};
|
|
779
|
-
return visit(getLivePortalErrorParent(failedInstance)) ?? visit(failedInstance.parentInstance);
|
|
780
|
-
}
|
|
781
|
-
/** Route a scheduled component failure to its nearest live render boundary. */
|
|
782
|
-
function routeComponentErrorToBoundary(failedInstance, error) {
|
|
783
|
-
const boundary = findLiveErrorBoundary(failedInstance);
|
|
784
|
-
if (!boundary) return false;
|
|
785
|
-
const onError = boundary.props.onError;
|
|
786
|
-
reportBoundaryError(boundary, error, typeof onError === "function" ? onError : void 0);
|
|
787
|
-
boundary._enqueueRun?.();
|
|
788
|
-
return true;
|
|
789
|
-
}
|
|
790
|
-
//#endregion
|
|
791
|
-
//#region src/runtime/component/commit.ts
|
|
792
|
-
function runScheduledComponent(instance, execute) {
|
|
793
|
-
const owner = instance.owner;
|
|
794
|
-
const ownershipGeneration = owner.identity;
|
|
795
|
-
const evaluationGeneration = instance.evaluationGeneration;
|
|
796
|
-
const transaction = beginCommitTransaction();
|
|
797
|
-
instance.notifyUpdate = instance._enqueueRun;
|
|
798
|
-
captureInlineRenderSnapshot$1(instance);
|
|
799
|
-
beginRenderTracking(instance);
|
|
800
|
-
const token = instance._currentRenderToken;
|
|
801
|
-
const renderRevision = instance.renderRevision;
|
|
802
|
-
let result;
|
|
803
|
-
let fast = false;
|
|
804
|
-
try {
|
|
805
|
-
result = execute(instance);
|
|
806
|
-
assertSyncComponentResult(result);
|
|
807
|
-
finalizeInlineReadSubscriptions(instance, token, instance._pendingReadSources, instance._pendingReadSourceVersions);
|
|
808
|
-
fast = getRuntimeEvaluation().classifyComponentUpdate(instance, result).useFastPath;
|
|
809
|
-
if (!fast) {}
|
|
810
|
-
} catch (error) {
|
|
811
|
-
discardTransaction(transaction);
|
|
812
|
-
if (!routeComponentErrorToBoundary(instance, error)) throw error;
|
|
813
|
-
return;
|
|
814
|
-
} finally {
|
|
815
|
-
clearRenderTracking(instance);
|
|
816
|
-
suspendTransaction(transaction);
|
|
817
|
-
}
|
|
818
|
-
const apply = () => {
|
|
819
|
-
if (owner.disposed || instance.owner !== owner || owner.identity !== ownershipGeneration || instance.evaluationGeneration !== evaluationGeneration || instance.renderRevision !== renderRevision) {
|
|
820
|
-
discardTransaction(transaction);
|
|
821
|
-
return;
|
|
822
|
-
}
|
|
823
|
-
try {
|
|
824
|
-
transaction.setDeferredNotifications(fast);
|
|
825
|
-
if (applyTransaction(transaction, () => {
|
|
826
|
-
const wasFirstMount = !owner.mounted;
|
|
827
|
-
if (!getRuntimeEvaluation().applyComponentResult(instance, result, fast ? "keyed-reorder" : "ordinary")) return false;
|
|
828
|
-
owner.mounted = true;
|
|
829
|
-
commitLifecycleForInstance(instance, wasFirstMount);
|
|
830
|
-
return true;
|
|
831
|
-
})) commitTransaction(transaction);
|
|
832
|
-
else discardTransaction(transaction);
|
|
833
|
-
} catch (error) {
|
|
834
|
-
discardTransaction(transaction);
|
|
835
|
-
if (!routeComponentErrorToBoundary(instance, error)) throw error;
|
|
836
|
-
} finally {
|
|
837
|
-
suspendTransaction(transaction);
|
|
838
|
-
}
|
|
839
|
-
};
|
|
840
|
-
if (fast) runRuntimeWithSyncProgress(apply);
|
|
841
|
-
else enqueueRuntimeTask(apply);
|
|
842
|
-
}
|
|
843
|
-
//#endregion
|
|
844
|
-
//#region src/runtime/component/instance.ts
|
|
845
|
-
/**
|
|
846
|
-
* Component instance lifecycle management
|
|
847
|
-
* Internal only — users never see this
|
|
848
|
-
*/
|
|
849
|
-
Object.defineProperty(componentRecordPrototype, DIRECT_RANGE_OWNER, { value: true });
|
|
850
|
-
const PRODUCTION_BUILD_ENABLED = isProductionEnvironment();
|
|
851
|
-
function ensurePendingRunTask(instance) {
|
|
852
|
-
const existing = instance._pendingRunTask;
|
|
853
|
-
if (existing) return existing;
|
|
854
|
-
const task = () => {
|
|
855
|
-
if (!instance.hasPendingUpdate) return;
|
|
856
|
-
instance.hasPendingUpdate = false;
|
|
857
|
-
if (instance.notifyUpdate === null) return;
|
|
858
|
-
runScheduledComponent(instance, executeComponentSync);
|
|
859
|
-
};
|
|
860
|
-
instance._pendingRunTask = task;
|
|
861
|
-
if (!instance._pendingFlushTask) instance._pendingFlushTask = task;
|
|
862
|
-
return task;
|
|
863
|
-
}
|
|
864
|
-
function enqueueComponentRun() {
|
|
865
|
-
if (this.owner.disposed || this.hasPendingUpdate) return;
|
|
866
|
-
this.hasPendingUpdate = true;
|
|
867
|
-
enqueueRuntimeTask(ensurePendingRunTask(this));
|
|
868
|
-
}
|
|
869
|
-
var ComponentExecutionContext = class {
|
|
870
|
-
constructor(owner) {
|
|
871
|
-
this.owner = owner;
|
|
872
|
-
}
|
|
873
|
-
get signal() {
|
|
874
|
-
return getOwnershipSignal(this.owner);
|
|
875
|
-
}
|
|
876
|
-
};
|
|
877
|
-
function createComponentInstance(id, fn, props, target, lifetimeParent) {
|
|
878
|
-
const parentInstance = getCurrentComponentInstance();
|
|
879
|
-
const portalScope = parentInstance?.portalScope ?? getCurrentPortalScope();
|
|
880
|
-
const instance = {
|
|
881
|
-
__proto__: componentRecordPrototype,
|
|
882
|
-
id,
|
|
883
|
-
fn,
|
|
884
|
-
props,
|
|
885
|
-
target,
|
|
886
|
-
range: void 0,
|
|
887
|
-
parentInstance,
|
|
888
|
-
portalScope: portalScope ?? null,
|
|
889
|
-
owner: new OwnershipRecord(),
|
|
890
|
-
stateValues: void 0,
|
|
891
|
-
evaluationGeneration: 0,
|
|
892
|
-
renderRevision: 0,
|
|
893
|
-
notifyUpdate: null,
|
|
894
|
-
_pendingFlushTask: void 0,
|
|
895
|
-
_pendingRunTask: void 0,
|
|
896
|
-
_enqueueRun: void 0,
|
|
897
|
-
stateIndexCheck: -1,
|
|
898
|
-
expectedStateIndices: void 0,
|
|
899
|
-
firstRenderComplete: false,
|
|
900
|
-
mountOperations: void 0,
|
|
901
|
-
commitOperations: void 0,
|
|
902
|
-
lifecycleSlots: void 0,
|
|
903
|
-
lifecycleGeneration: 0,
|
|
904
|
-
hasPendingUpdate: false,
|
|
905
|
-
ownerFrame: null,
|
|
906
|
-
ssr: false,
|
|
907
|
-
cleanupStrict: false,
|
|
908
|
-
isRoot: false,
|
|
909
|
-
_currentRenderToken: void 0,
|
|
910
|
-
lastRenderToken: 0,
|
|
911
|
-
_pendingReadSources: void 0,
|
|
912
|
-
_pendingReadSourceVersions: void 0,
|
|
913
|
-
devWarningsEmitted: void 0,
|
|
914
|
-
_portalErrorParent: void 0,
|
|
915
|
-
_portalErrorParentGeneration: void 0
|
|
916
|
-
};
|
|
917
|
-
instance._enqueueRun = enqueueComponentRun;
|
|
918
|
-
bindComponentOwnership(instance);
|
|
919
|
-
attachOwnership(instance.owner, lifetimeParent === null ? void 0 : lifetimeParent ?? parentInstance?.owner);
|
|
920
|
-
return instance;
|
|
921
|
-
}
|
|
922
|
-
/**
|
|
923
|
-
* Register a mount operation that will run after the component is mounted
|
|
924
|
-
* Used by operations (task, on, timer, etc) to execute after render completes
|
|
925
|
-
*/
|
|
926
|
-
function captureInlineRenderSnapshot(instance) {
|
|
927
|
-
captureInlineRenderSnapshot$1(instance);
|
|
928
|
-
}
|
|
929
|
-
function registerCommitOperation(operation) {
|
|
930
|
-
registerCommitOperationForInstance(getCurrentComponentInstance(), operation);
|
|
931
|
-
}
|
|
932
|
-
function commitRenderedComponent(instance) {
|
|
933
|
-
commitRenderedComponent$1(instance);
|
|
934
|
-
}
|
|
935
|
-
function mountInstanceInline(instance, target) {
|
|
936
|
-
getRuntimeEvaluation().recordInlineComponentHost(instance, target);
|
|
937
|
-
instance.notifyUpdate = instance._enqueueRun;
|
|
938
|
-
const wasFirstMount = !instance.owner.mounted;
|
|
939
|
-
instance.owner.mounted = true;
|
|
940
|
-
commitLifecycleForInstance(instance, wasFirstMount);
|
|
941
|
-
}
|
|
942
|
-
/**
|
|
943
|
-
* Run a component synchronously: execute function, handle result
|
|
944
|
-
* This is the internal workhorse that manages async continuations and generation tracking.
|
|
945
|
-
* Must always be called through the scheduler.
|
|
946
|
-
*
|
|
947
|
-
* ACTOR INVARIANT: This function is enqueued as a task, never called directly.
|
|
948
|
-
*/
|
|
949
|
-
function renderScopedComponent(instance, startStateIndex, render) {
|
|
950
|
-
instance.notifyUpdate = instance._enqueueRun;
|
|
951
|
-
resetRenderState(instance);
|
|
952
|
-
beginRenderTracking(instance);
|
|
953
|
-
const savedScope = enterRenderScopedComponent(instance, startStateIndex);
|
|
954
|
-
let didComplete = false;
|
|
955
|
-
try {
|
|
956
|
-
const result = withContext(getExecutionContextFrame(instance.ownerFrame), render);
|
|
957
|
-
didComplete = true;
|
|
958
|
-
return result;
|
|
959
|
-
} finally {
|
|
960
|
-
sealInlineRenderSnapshot(instance);
|
|
961
|
-
if (!didComplete) clearRenderTracking(instance);
|
|
962
|
-
endComponentScope(savedScope);
|
|
963
|
-
}
|
|
964
|
-
}
|
|
965
|
-
/**
|
|
966
|
-
* Execute a component's render function synchronously.
|
|
967
|
-
* Returns either a vnode/promise immediately (does NOT render).
|
|
968
|
-
* Rendering happens separately through the scheduled commit helper.
|
|
969
|
-
*/
|
|
970
|
-
function renderComponentInline(instance) {
|
|
971
|
-
instance.notifyUpdate = instance._enqueueRun;
|
|
972
|
-
const trackingSnapshot = captureInlineRenderTracking(instance);
|
|
973
|
-
const scopeSnapshot = captureInlineComponentScope();
|
|
974
|
-
const hadToken = trackingSnapshot.currentRenderToken !== void 0;
|
|
975
|
-
if (!hadToken) beginRenderTracking(instance);
|
|
976
|
-
try {
|
|
977
|
-
const result = executeComponentSync(instance);
|
|
978
|
-
if (!hadToken) instance.hasPendingUpdate = false;
|
|
979
|
-
if (!hadToken) finalizeInlineReadSubscriptions(instance, instance._currentRenderToken, instance._pendingReadSources, instance._pendingReadSourceVersions);
|
|
980
|
-
commitRenderedComponent(instance);
|
|
981
|
-
return result;
|
|
982
|
-
} finally {
|
|
983
|
-
restoreInlineRenderTracking(instance, trackingSnapshot);
|
|
984
|
-
endComponentScope(scopeSnapshot);
|
|
985
|
-
}
|
|
986
|
-
}
|
|
987
|
-
function executeComponentSync(instance) {
|
|
988
|
-
resetRenderState(instance);
|
|
989
|
-
const savedPortalScope = enterComponentExecutionScope(instance);
|
|
990
|
-
let didComplete = false;
|
|
991
|
-
try {
|
|
992
|
-
const trackRenderTime = !PRODUCTION_BUILD_ENABLED && isDevelopmentEnvironment();
|
|
993
|
-
const renderStartTime = trackRenderTime ? Date.now() : 0;
|
|
994
|
-
const context = new ComponentExecutionContext(instance.owner);
|
|
995
|
-
const result = callWithContext(getExecutionContextFrame(instance.ownerFrame), instance.fn, instance.props, context);
|
|
996
|
-
if (trackRenderTime) {
|
|
997
|
-
const renderTime = Date.now() - renderStartTime;
|
|
998
|
-
if (shouldWarnSlowRender(renderTime)) warnInstanceOnce(instance, "slow-render", `[askr] Slow render detected in ${instance.fn?.name || "<anonymous>"}: ${renderTime}ms. Consider optimizing component performance.`);
|
|
999
|
-
}
|
|
1000
|
-
if (!instance.firstRenderComplete) instance.firstRenderComplete = true;
|
|
1001
|
-
didComplete = true;
|
|
1002
|
-
return result;
|
|
1003
|
-
} finally {
|
|
1004
|
-
sealInlineRenderSnapshot(instance);
|
|
1005
|
-
if (!didComplete) discardCommitOperations(instance);
|
|
1006
|
-
endComponentScope(savedPortalScope);
|
|
1007
|
-
}
|
|
1008
|
-
}
|
|
1009
|
-
/**
|
|
1010
|
-
* Public entry point: Execute component with full lifecycle (execute + render)
|
|
1011
|
-
* Handles both initial mount and re-execution. Always enqueues through scheduler.
|
|
1012
|
-
* Single entry point to avoid lifecycle divergence.
|
|
1013
|
-
*/
|
|
1014
|
-
function executeComponent(instance) {
|
|
1015
|
-
instance.notifyUpdate = instance._enqueueRun;
|
|
1016
|
-
instance.hasPendingUpdate = true;
|
|
1017
|
-
enqueueRuntimeTask(ensurePendingRunTask(instance));
|
|
1018
|
-
}
|
|
1019
|
-
function warnInstanceOnce(instance, key, message) {
|
|
1020
|
-
if (isProductionEnvironment()) return;
|
|
1021
|
-
const warnings = instance.devWarningsEmitted ??= /* @__PURE__ */ new Set();
|
|
1022
|
-
if (warnings.has(key)) return;
|
|
1023
|
-
warnings.add(key);
|
|
1024
|
-
logger.warn(message);
|
|
1025
|
-
}
|
|
1026
|
-
//#endregion
|
|
1027
|
-
export { captureInlineRenderSnapshot$1 as A, rebaseVNodeTreeWithContextFrame as C, createComponentOwnership as D, cleanupComponentGeneration as E, captureGenerationExecution as F, DIRECT_RANGE_OWNER as I, incDevCounter as L, ASYNC_COMPONENT_MESSAGE as M, assertSyncComponentResult as N, registerOwnedChildScope as O, isPromiseLike as P, setDevValue as R, markVNodeTreeWithContextFrame as S, cleanupComponent as T, haveEquivalentContextFrames as _, registerCommitOperation as a, withContext as b, createBoundaryReset as c, registerCommitOperationForInstance as d, configureRenderDiagnostics as f, getExecutionContextFrame as g, getCurrentContextFrame as h, mountInstanceInline as i, finalizeInlineReadSubscriptions as j, resetComponentWork as k, reportBoundaryError as l, defineScope as m, createComponentInstance as n, renderComponentInline as o, callWithContext as p, executeComponent as r, renderScopedComponent as s, captureInlineRenderSnapshot as t, routeComponentErrorToBoundary as u, readScope as v, bindComponentOwnership as w, getVNodeContextFrame as x, withAsyncResourceContext as y };
|