@askrjs/askr 0.2.3 → 0.3.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.
Files changed (117) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/dist/access-CEA2pOry.js +1046 -0
  3. package/dist/actions/index.d.ts +16 -2
  4. package/dist/actions/index.js +5 -5
  5. package/dist/{activity-ZxJXI9hF.js → activity-oy2YFTFF.js} +22 -16
  6. package/dist/benchmark.js +8 -9
  7. package/dist/boot/index.d.ts +21 -9
  8. package/dist/boot/index.js +1 -1
  9. package/dist/{boot-D4GaLA0d.js → boot-BMBMWUGI.js} +680 -440
  10. package/dist/capabilities-Bbf0mlp9.js +42 -0
  11. package/dist/components/index.d.ts +11 -8
  12. package/dist/components/index.js +1 -1
  13. package/dist/{compose-ref-Bfaf4kUC.js → compose-ref-v0qGlHoN.js} +7 -1
  14. package/dist/control/index.d.ts +20 -2
  15. package/dist/control/index.js +1 -1
  16. package/dist/{control-57x3wa4J.js → control-BR_mrX__.js} +4 -4
  17. package/dist/core.d.ts +163 -0
  18. package/dist/csp-nonce-BfFWcd0w.js +173 -0
  19. package/dist/data/index.d.ts +74 -2
  20. package/dist/data/index.js +3 -3
  21. package/dist/{data-B7XCDeC8.js → data-2edW0jhF.js} +133 -138
  22. package/dist/{data-runtime-7t_Y0iv3.js → data-runtime-CxoY98lX.js} +22 -15
  23. package/dist/{deferred-BELyvMsC.js → deferred-CbgNhf67.js} +5 -5
  24. package/dist/dom-renderer.d.ts +77 -0
  25. package/dist/domains/actions.d.ts +70 -0
  26. package/dist/domains/component.d.ts +119 -0
  27. package/dist/domains/context.d.ts +73 -0
  28. package/dist/domains/control.d.ts +328 -0
  29. package/dist/domains/data.d.ts +461 -0
  30. package/dist/domains/diagnostics.d.ts +21 -0
  31. package/dist/domains/lifecycle.d.ts +112 -0
  32. package/dist/domains/refs.d.ts +18 -0
  33. package/dist/domains/renderer.d.ts +127 -0
  34. package/dist/domains/routing.d.ts +501 -0
  35. package/dist/domains/scheduler.d.ts +79 -0
  36. package/dist/domains/server.d.ts +112 -0
  37. package/dist/domains/state.d.ts +129 -0
  38. package/dist/domains/telemetry.d.ts +29 -0
  39. package/dist/eager-control.d.ts +8 -0
  40. package/dist/{effect-4LwBwV58.js → effect-C3Zsc1k6.js} +14 -41
  41. package/dist/{types-DkVJhVs9.d.ts → elements.d.ts} +84 -42
  42. package/dist/{for-internal-DeoSg_AV.js → for-state-BDykeOJL.js} +623 -511
  43. package/dist/foundations/icon/index.d.ts +67 -16
  44. package/dist/foundations/icon/index.js +1 -1
  45. package/dist/foundations/index.d.ts +26 -3
  46. package/dist/foundations/index.js +1 -1
  47. package/dist/foundations/interactions/index.d.ts +73 -34
  48. package/dist/foundations/interactions/index.js +1 -1
  49. package/dist/foundations/state/index.d.ts +12 -5
  50. package/dist/foundations/state/index.js +1 -1
  51. package/dist/foundations/structures/index.d.ts +44 -3
  52. package/dist/foundations/structures/index.js +1 -1
  53. package/dist/foundations/utilities/index.d.ts +34 -3
  54. package/dist/foundations/utilities/index.js +1 -1
  55. package/dist/fx/index.d.ts +72 -25
  56. package/dist/fx/index.js +8 -8
  57. package/dist/index.d.ts +121 -4
  58. package/dist/index.js +316 -47
  59. package/dist/{component-internal-Dl02WQKS.js → instance-VAFYVJOa.js} +495 -283
  60. package/dist/{interactions-D102JxBR.js → interactions-CTeACdT_.js} +1 -1
  61. package/dist/jsx-dev-runtime.d.ts +51 -11
  62. package/dist/jsx-globals.d.ts +2 -0
  63. package/dist/jsx-runtime-CPJXAOBF.js +43 -0
  64. package/dist/jsx-runtime.d.ts +17 -3
  65. package/dist/jsx-runtime.js +2 -42
  66. package/dist/jsx.d.ts +108 -0
  67. package/dist/{manifest-D6rfj_jC.js → manifest-D1P3UNWV.js} +4 -9
  68. package/dist/{navigate-C46GtScG.js → navigate-prC5V8XV.js} +204 -476
  69. package/dist/{navigate-wel1e6cU.d.ts → navigation.d.ts} +10 -8
  70. package/dist/{readable-CEcteIDE.js → notify-DxxuDPeY.js} +96 -34
  71. package/dist/{query-registry-Bua3cDyb.js → query-registry-LrYpQsDJ.js} +1 -1
  72. package/dist/{compose-ref-DOJHoW5X.d.ts → refs.d.ts} +11 -7
  73. package/dist/{ssr-BaC5qHEw.js → render-resolved-BC0W7_5b.js} +165 -558
  74. package/dist/{renderer-BhXofszH.js → renderer-CT0HeY58.js} +6866 -5715
  75. package/dist/{resolution-t8J0yNaU.js → resolution-3DskUkjG.js} +189 -180
  76. package/dist/{resource-operation-B8q-QRUx.js → resource-18-sFRl9.js} +98 -58
  77. package/dist/resources/index.d.ts +64 -46
  78. package/dist/resources/index.js +215 -9
  79. package/dist/route-activity.d.ts +21 -0
  80. package/dist/{route-matching-Bo6UqG-5.js → route-matching-CUzZ31gT.js} +68 -82
  81. package/dist/router/index.d.ts +378 -79
  82. package/dist/router/index.js +9 -9
  83. package/dist/router-internal-7nuNEHfG.js +36 -0
  84. package/dist/scope-Cq_iYbTR.js +403 -0
  85. package/dist/{selector-C7rIpOnN.js → selector-BSPVkjKP.js} +41 -41
  86. package/dist/{shared-CGrx2AOL.js → shared-kU8yvryp.js} +3 -6
  87. package/dist/{snapshot-source-BB42xgwb.js → snapshot-source-An4iKajG.js} +1 -1
  88. package/dist/ssg/index.d.ts +51 -15
  89. package/dist/ssg/index.js +269 -209
  90. package/dist/ssr/index.d.ts +121 -68
  91. package/dist/ssr/index.js +2 -1
  92. package/dist/ssr-CiNm6Vzl.js +393 -0
  93. package/dist/{ssr-DSHd_Q9K.js → ssr-EPjwJH5R.js} +5 -1
  94. package/dist/{state-BzhOW2TX.js → state-BXJfudq1.js} +10 -15
  95. package/dist/{structures-BwfeO4Iz.js → structures-CjEzfj4h.js} +37 -57
  96. package/dist/{index-r5THqzPN.d.ts → structures.d.ts} +57 -36
  97. package/dist/testing/index.d.ts +125 -24
  98. package/dist/testing/index.js +26 -62
  99. package/dist/timer-C7uqnJVt.js +85 -0
  100. package/dist/{index-B1gu0_m0.d.ts → utilities.d.ts} +24 -13
  101. package/dist/{verify-hydration-_Q6avFp0.js → verify-hydration-ikaxotf7.js} +8 -5
  102. package/package.json +13 -15
  103. package/dist/access-Rr7CMa06.js +0 -507
  104. package/dist/activity-CAJ5eho-.d.ts +0 -14
  105. package/dist/benchmark.d.ts +0 -26
  106. package/dist/cleanup-DsrbV-rr.js +0 -535
  107. package/dist/component-cleanup-DjpwO9WX.js +0 -143
  108. package/dist/component-scope-4I3yEMkb.js +0 -195
  109. package/dist/control-DdFw-Caz.d.ts +0 -8
  110. package/dist/csp-nonce-C9OuML0U.js +0 -72
  111. package/dist/css-BuPaTOfe.js +0 -70
  112. package/dist/fastlane-Buz1Rvlr.js +0 -166
  113. package/dist/index-DSqXWc77.d.ts +0 -1402
  114. package/dist/jsx-runtime-BTzDdBJ_.d.ts +0 -2
  115. package/dist/jsx-runtime-Cdd6Gkb0.d.ts +0 -38
  116. package/dist/lifecycle-batch-Be-CLDjV.js +0 -253
  117. package/dist/lifecycle-operations-C5m03NQc.js +0 -195
@@ -0,0 +1,1046 @@
1
+ import { a as clearCurrentComponentScope, s as endComponentScope } from "./scope-Cq_iYbTR.js";
2
+ //#region src/common/env.ts
3
+ function normalizeEnv(source) {
4
+ if (!source) return {};
5
+ const normalized = {};
6
+ for (const [key, value] of Object.entries(source)) if (typeof value === "string") normalized[key] = value;
7
+ else if (typeof value === "boolean" || typeof value === "number") normalized[key] = String(value);
8
+ return normalized;
9
+ }
10
+ function getBuildTimeEnv() {
11
+ const metaEnv = import.meta.env;
12
+ const normalized = normalizeEnv(metaEnv);
13
+ if (normalized.NODE_ENV == null && metaEnv) {
14
+ if (typeof metaEnv.MODE === "string" && metaEnv.MODE.length > 0) normalized.NODE_ENV = metaEnv.MODE;
15
+ else if (metaEnv.PROD === true || metaEnv.PROD === "true") normalized.NODE_ENV = "production";
16
+ else if (metaEnv.DEV === true || metaEnv.DEV === "true") normalized.NODE_ENV = "development";
17
+ }
18
+ return normalized;
19
+ }
20
+ function resolveNodeEnv(processNodeEnv, buildNodeEnv) {
21
+ if (buildNodeEnv === "production") return "production";
22
+ if (processNodeEnv != null) return processNodeEnv;
23
+ if (buildNodeEnv === "development") return "development";
24
+ return buildNodeEnv === "test" ? void 0 : buildNodeEnv;
25
+ }
26
+ function getRuntimeEnv() {
27
+ const processEnv = globalThis.process?.env ?? {};
28
+ const buildTimeEnv = getBuildTimeEnv();
29
+ return {
30
+ ...processEnv,
31
+ ...buildTimeEnv,
32
+ NODE_ENV: resolveNodeEnv(processEnv.NODE_ENV, buildTimeEnv.NODE_ENV)
33
+ };
34
+ }
35
+ function isProductionEnvironment() {
36
+ return getRuntimeEnv().NODE_ENV === "production";
37
+ }
38
+ function isDevelopmentEnvironment() {
39
+ return !isProductionEnvironment();
40
+ }
41
+ //#endregion
42
+ //#region src/common/invariant.ts
43
+ /**
44
+ * Invariant assertions shared by production runtime code.
45
+ */
46
+ function invariant(condition, message, context) {
47
+ if (!condition) {
48
+ const contextStr = context ? "\n" + JSON.stringify(context, null, 2) : "";
49
+ throw new Error(`[Askr Invariant] ${message}${contextStr}`);
50
+ }
51
+ }
52
+ function assertSchedulingPrecondition(condition, violationMessage) {
53
+ invariant(condition, `[Scheduler Precondition] ${violationMessage}`);
54
+ }
55
+ //#endregion
56
+ //#region src/runtime/diagnostics/perf-metrics.ts
57
+ const incrementPerfMetric = () => {};
58
+ const addPerfDuration = () => {};
59
+ //#endregion
60
+ //#region src/runtime/scheduler-scopes.ts
61
+ var SchedulerScopes = class {
62
+ constructor() {
63
+ this.handlerScopes = 0;
64
+ this.handlerFlag = false;
65
+ this.progressScopes = 0;
66
+ }
67
+ get inHandler() {
68
+ return this.handlerFlag || this.handlerScopes > 0;
69
+ }
70
+ get allowSyncProgress() {
71
+ return this.progressScopes > 0;
72
+ }
73
+ canKick(running) {
74
+ return !running && !this.inHandler && !this.allowSyncProgress;
75
+ }
76
+ adjustHandler(delta) {
77
+ this.handlerScopes += delta;
78
+ }
79
+ setHandlerFlag(value) {
80
+ this.handlerFlag = value;
81
+ }
82
+ adjustProgress(delta) {
83
+ this.progressScopes += delta;
84
+ }
85
+ };
86
+ //#endregion
87
+ //#region src/runtime/scheduled-work.ts
88
+ const workByTask = /* @__PURE__ */ new WeakMap();
89
+ var ScheduledWork = class {
90
+ constructor(run) {
91
+ this.pending = false;
92
+ this.task = () => {
93
+ this.pending = false;
94
+ run();
95
+ };
96
+ workByTask.set(this.task, this);
97
+ }
98
+ request(scheduler, lane) {
99
+ if (this.pending) return;
100
+ this.pending = true;
101
+ try {
102
+ scheduler.enqueueInLane(lane, this.task);
103
+ } catch (error) {
104
+ this.cancel();
105
+ throw error;
106
+ }
107
+ }
108
+ cancel() {
109
+ this.pending = false;
110
+ }
111
+ static release(task) {
112
+ workByTask.get(task)?.cancel();
113
+ }
114
+ };
115
+ //#endregion
116
+ //#region src/runtime/scheduler.ts
117
+ /**
118
+ * Serialized update scheduler — safer design (no inline execution, explicit flush)
119
+ *
120
+ * Key ideas:
121
+ * - Never execute a task inline from `enqueue`.
122
+ * - `flush()` is explicit and non-reentrant.
123
+ * - `runWithSyncProgress()` allows enqueues temporarily but does not run tasks
124
+ * inline; it runs `fn` and then does an explicit `flush()`.
125
+ * - `waitForFlush()` is race-free with a monotonic `flushVersion`.
126
+ */
127
+ const MAX_FLUSH_DEPTH = 50;
128
+ const SCHEDULER_LANES = [
129
+ "derived",
130
+ "component",
131
+ "reactive",
132
+ "post"
133
+ ];
134
+ var Scheduler = class {
135
+ constructor() {
136
+ this.bulkCommitProbe = () => false;
137
+ this.lanes = {
138
+ derived: {
139
+ tasks: [],
140
+ head: 0
141
+ },
142
+ component: {
143
+ tasks: [],
144
+ head: 0
145
+ },
146
+ reactive: {
147
+ tasks: [],
148
+ head: 0
149
+ },
150
+ post: {
151
+ tasks: [],
152
+ head: 0
153
+ }
154
+ };
155
+ this.scopes = new SchedulerScopes();
156
+ this.running = false;
157
+ this.depth = 0;
158
+ this.executionDepth = 0;
159
+ this.flushVersion = 0;
160
+ this.kickScheduled = false;
161
+ this.waiters = [];
162
+ this.taskCount = 0;
163
+ }
164
+ setBulkCommitProbe(probe) {
165
+ this.bulkCommitProbe = probe;
166
+ }
167
+ isBulkCommitActive() {
168
+ try {
169
+ return this.bulkCommitProbe();
170
+ } catch (e) {
171
+ return false;
172
+ }
173
+ }
174
+ hasPendingTasks() {
175
+ for (const lane of SCHEDULER_LANES) {
176
+ const queue = this.lanes[lane];
177
+ if (queue.head < queue.tasks.length) return true;
178
+ }
179
+ return false;
180
+ }
181
+ getPendingTaskCount() {
182
+ let total = 0;
183
+ for (const lane of SCHEDULER_LANES) {
184
+ const queue = this.lanes[lane];
185
+ total += queue.tasks.length - queue.head;
186
+ }
187
+ return total;
188
+ }
189
+ compactLane(queue) {
190
+ if (queue.head >= queue.tasks.length) {
191
+ queue.tasks.length = 0;
192
+ queue.head = 0;
193
+ return;
194
+ }
195
+ if (queue.head <= 0) return;
196
+ const remaining = queue.tasks.length - queue.head;
197
+ for (let i = 0; i < remaining; i++) queue.tasks[i] = queue.tasks[queue.head + i];
198
+ queue.tasks.length = remaining;
199
+ queue.head = 0;
200
+ }
201
+ scheduleFlushKick() {
202
+ if (this.kickScheduled || !this.scopes.canKick(this.running) || this.isBulkCommitActive() || !this.hasPendingTasks()) return;
203
+ this.kickScheduled = true;
204
+ queueMicrotask(() => {
205
+ this.kickScheduled = false;
206
+ if (!this.scopes.canKick(this.running) || this.isBulkCommitActive() || !this.hasPendingTasks()) return;
207
+ try {
208
+ this.flush();
209
+ } catch (err) {
210
+ setTimeout(() => {
211
+ throw err;
212
+ });
213
+ }
214
+ });
215
+ }
216
+ enqueue(task) {
217
+ this.enqueueInLane("component", task);
218
+ }
219
+ enqueueInLane(lane, task) {
220
+ assertSchedulingPrecondition(typeof task === "function", "enqueue() requires a function");
221
+ if (this.isBulkCommitActive() && !this.scopes.allowSyncProgress) {
222
+ ScheduledWork.release(task);
223
+ if (isDevelopmentEnvironment()) throw new Error("[Scheduler] enqueue() during bulk commit (not allowed)");
224
+ return;
225
+ }
226
+ this.lanes[lane].tasks.push(task);
227
+ this.taskCount++;
228
+ this.scheduleFlushKick();
229
+ }
230
+ flush() {
231
+ invariant(!this.running, "[Scheduler] flush() called while already running");
232
+ if (isDevelopmentEnvironment()) {
233
+ if (this.isBulkCommitActive() && !this.scopes.allowSyncProgress) throw new Error("[Scheduler] flush() started during bulk commit (not allowed)");
234
+ }
235
+ this.running = true;
236
+ this.depth = 0;
237
+ const failures = [];
238
+ let executedTaskCount = 0;
239
+ const executionsByTask = isDevelopmentEnvironment() ? /* @__PURE__ */ new Map() : null;
240
+ try {
241
+ while (true) {
242
+ let didRunTask = false;
243
+ for (const lane of SCHEDULER_LANES) {
244
+ const laneQueue = this.lanes[lane];
245
+ let executedInLane = 0;
246
+ while (laneQueue.head < laneQueue.tasks.length) {
247
+ const task = laneQueue.tasks[laneQueue.head++];
248
+ if (executionsByTask) {
249
+ const taskExecutions = (executionsByTask.get(task) ?? 0) + 1;
250
+ executionsByTask.set(task, taskExecutions);
251
+ this.depth = Math.max(this.depth, taskExecutions);
252
+ if (taskExecutions > MAX_FLUSH_DEPTH) throw new Error(`[Scheduler] exceeded MAX_FLUSH_DEPTH (${MAX_FLUSH_DEPTH}). Likely infinite update loop.`);
253
+ }
254
+ try {
255
+ this.executionDepth++;
256
+ task();
257
+ } catch (err) {
258
+ failures.push(err);
259
+ } finally {
260
+ if (this.executionDepth > 0) this.executionDepth--;
261
+ executedTaskCount++;
262
+ executedInLane++;
263
+ didRunTask = true;
264
+ }
265
+ }
266
+ if (executedInLane > 0) this.taskCount = Math.max(0, this.taskCount - executedInLane);
267
+ }
268
+ if (!didRunTask) break;
269
+ }
270
+ } finally {
271
+ this.running = false;
272
+ this.depth = 0;
273
+ this.executionDepth = 0;
274
+ for (const lane of SCHEDULER_LANES) {
275
+ const queue = this.lanes[lane];
276
+ if (queue.head > 0) this.compactLane(queue);
277
+ }
278
+ this.completeEpoch();
279
+ }
280
+ if (failures.length === 1) throw failures[0];
281
+ if (failures.length > 1) throw new AggregateError(failures, "Scheduler task failures");
282
+ }
283
+ runWithSyncProgress(fn) {
284
+ this.scopes.adjustProgress(1);
285
+ const startVersion = this.flushVersion;
286
+ try {
287
+ const res = fn();
288
+ if (!this.running && this.hasPendingTasks()) this.flush();
289
+ if (isDevelopmentEnvironment()) {
290
+ if (!this.running && this.hasPendingTasks()) throw new Error("[Scheduler] tasks remain after runWithSyncProgress flush");
291
+ }
292
+ return res;
293
+ } finally {
294
+ this.scopes.adjustProgress(-1);
295
+ if (this.flushVersion === startVersion) this.completeIdleEpoch();
296
+ this.scheduleFlushKick();
297
+ }
298
+ }
299
+ waitForFlush(targetVersion, timeoutMs = 2e3) {
300
+ const target = typeof targetVersion === "number" ? targetVersion : this.flushVersion + 1;
301
+ if (this.flushVersion >= target) return Promise.resolve();
302
+ return new Promise((resolve, reject) => {
303
+ const waiter = {
304
+ target,
305
+ resolve,
306
+ reject
307
+ };
308
+ waiter.timer = setTimeout(() => {
309
+ const index = this.waiters.indexOf(waiter);
310
+ if (index >= 0) this.waiters.splice(index, 1);
311
+ if (waiter.timer !== void 0) clearTimeout(waiter.timer);
312
+ const diag = {
313
+ flushVersion: this.flushVersion,
314
+ queueLen: this.getPendingTaskCount(),
315
+ running: this.running,
316
+ inHandler: this.scopes.inHandler,
317
+ bulk: this.isBulkCommitActive()
318
+ };
319
+ reject(/* @__PURE__ */ new Error(`waitForFlush timeout ${timeoutMs}ms: ${JSON.stringify(diag)}`));
320
+ }, timeoutMs);
321
+ this.waiters.push(waiter);
322
+ });
323
+ }
324
+ getState() {
325
+ return {
326
+ queueLength: this.getPendingTaskCount(),
327
+ running: this.running,
328
+ depth: this.depth,
329
+ executionDepth: this.executionDepth,
330
+ taskCount: this.taskCount,
331
+ flushVersion: this.flushVersion,
332
+ laneQueues: {
333
+ derived: this.lanes.derived.tasks.length - this.lanes.derived.head,
334
+ component: this.lanes.component.tasks.length - this.lanes.component.head,
335
+ reactive: this.lanes.reactive.tasks.length - this.lanes.reactive.head,
336
+ post: this.lanes.post.tasks.length - this.lanes.post.head
337
+ },
338
+ inHandler: this.scopes.inHandler,
339
+ allowSyncProgress: this.scopes.allowSyncProgress
340
+ };
341
+ }
342
+ getFlushVersion() {
343
+ return this.flushVersion;
344
+ }
345
+ flushIfQueued() {
346
+ if (!this.running && this.hasPendingTasks()) this.flush();
347
+ }
348
+ runInHandlerScope(fn, flushMode = "defer") {
349
+ this.scopes.adjustHandler(1);
350
+ try {
351
+ return fn();
352
+ } finally {
353
+ this.scopes.adjustHandler(-1);
354
+ if (!this.scopes.inHandler) {
355
+ if (flushMode === "sync") this.flushIfQueued();
356
+ else this.scheduleFlushKick();
357
+ }
358
+ }
359
+ }
360
+ setInHandler(v) {
361
+ this.scopes.setHandlerFlag(v);
362
+ if (!v) this.scheduleFlushKick();
363
+ }
364
+ isInHandler() {
365
+ return this.scopes.inHandler;
366
+ }
367
+ isExecuting() {
368
+ return this.running || this.executionDepth > 0;
369
+ }
370
+ clearPendingSyncTasks() {
371
+ const remaining = this.getPendingTaskCount();
372
+ if (remaining <= 0) return 0;
373
+ for (const lane of SCHEDULER_LANES) {
374
+ const queue = this.lanes[lane];
375
+ for (let index = queue.head; index < queue.tasks.length; index++) ScheduledWork.release(queue.tasks[index]);
376
+ queue.tasks.length = this.running ? queue.head : 0;
377
+ if (!this.running) queue.head = 0;
378
+ }
379
+ this.taskCount = Math.max(0, this.taskCount - remaining);
380
+ this.completeIdleEpoch();
381
+ return remaining;
382
+ }
383
+ completeIdleEpoch() {
384
+ if (!this.running && !this.scopes.allowSyncProgress && !this.hasPendingTasks()) this.completeEpoch();
385
+ }
386
+ completeEpoch() {
387
+ this.flushVersion++;
388
+ this.resolveWaiters();
389
+ }
390
+ resolveWaiters() {
391
+ if (this.waiters.length === 0) return;
392
+ const ready = [];
393
+ const remaining = [];
394
+ for (const w of this.waiters) if (this.flushVersion >= w.target) {
395
+ if (w.timer !== void 0) clearTimeout(w.timer);
396
+ ready.push(w.resolve);
397
+ } else remaining.push(w);
398
+ this.waiters = remaining;
399
+ for (const r of ready) r();
400
+ }
401
+ };
402
+ const globalScheduler = new Scheduler();
403
+ //#endregion
404
+ //#region src/runtime/transactions/coordinator.ts
405
+ const transactionCreation = Symbol("transaction creation");
406
+ let transactionState;
407
+ /** Read-only transaction identity with explicit resource and notification operations. */
408
+ var CommitTransaction = class {
409
+ #state;
410
+ static {
411
+ transactionState = (transaction) => transaction.#state;
412
+ }
413
+ constructor(coordinator, parent, token) {
414
+ if (token !== transactionCreation) throw new Error("[Askr] Transactions must be created by their coordinator.");
415
+ this.#state = {
416
+ phase: "preparing",
417
+ parent,
418
+ coordinator,
419
+ participants: [],
420
+ seen: void 0,
421
+ index: void 0,
422
+ resources: void 0,
423
+ errors: void 0,
424
+ completions: void 0,
425
+ deferNotifications: false
426
+ };
427
+ Object.freeze(this);
428
+ }
429
+ get phase() {
430
+ return this.#state.phase;
431
+ }
432
+ get parent() {
433
+ return this.#state.parent;
434
+ }
435
+ get coordinator() {
436
+ return this.#state.coordinator;
437
+ }
438
+ get participants() {
439
+ return Object.freeze(this.#state.participants.slice());
440
+ }
441
+ get errors() {
442
+ return Object.freeze(this.#state.errors?.slice() ?? []);
443
+ }
444
+ get resourceCount() {
445
+ return this.#state.resources?.size ?? 0;
446
+ }
447
+ /** Detached diagnostic collections cannot mutate coordinator bookkeeping. */
448
+ inspect() {
449
+ return {
450
+ index: new Map(Array.from(this.#state.index ?? [], ([kind, entries]) => [kind, new Map(entries)])),
451
+ resources: new Map(this.#state.resources),
452
+ seen: new Set(this.#state.seen),
453
+ completions: new Map(this.#state.completions)
454
+ };
455
+ }
456
+ get active() {
457
+ const phase = this.#state.phase;
458
+ return phase === "preparing" || phase === "applying" || phase === "publishing";
459
+ }
460
+ hasResource(key) {
461
+ return this.#state.resources?.has(key) ?? false;
462
+ }
463
+ resource(key) {
464
+ return this.#state.resources?.get(key);
465
+ }
466
+ captureResource(key, resource) {
467
+ if (!this.active) throw new Error("[Askr] Cannot capture a resource on a settled transaction.");
468
+ const resources = this.#state.resources ??= /* @__PURE__ */ new Map();
469
+ if (resources.has(key)) return resources.get(key);
470
+ resources.set(key, resource);
471
+ return resource;
472
+ }
473
+ setDeferredNotifications(enabled) {
474
+ if (!this.active) throw new Error("[Askr] Cannot configure a settled transaction.");
475
+ this.#state.deferNotifications = enabled;
476
+ }
477
+ participant(key, kind) {
478
+ return this.#state.index?.get(kind)?.get(key);
479
+ }
480
+ };
481
+ /** Reuse the larger map while preserving earlier values, including undefined. */
482
+ function mergeEarlierEntries(earlier, later, reuseLater = true) {
483
+ if (reuseLater && (!earlier || earlier.size < later.size)) {
484
+ for (const [key, value] of earlier ?? []) later.set(key, value);
485
+ return later;
486
+ }
487
+ earlier ??= /* @__PURE__ */ new Map();
488
+ for (const [key, value] of later) if (!earlier.has(key)) earlier.set(key, value);
489
+ return earlier;
490
+ }
491
+ /** One synchronous stack per runtime. This coordinator has no component,
492
+ * subscription, renderer, scheduler, or browser dependencies. */
493
+ var CommitCoordinator = class {
494
+ constructor(options = {}) {
495
+ this.frame = null;
496
+ this.options = options;
497
+ }
498
+ get current() {
499
+ return this.frame;
500
+ }
501
+ begin() {
502
+ const transaction = new CommitTransaction(this, this.frame?.active ? this.frame : null, transactionCreation);
503
+ this.frame = transaction;
504
+ return transaction;
505
+ }
506
+ register(participant) {
507
+ if (!this.frame?.active) return false;
508
+ this.add(this.frame, participant);
509
+ return true;
510
+ }
511
+ add(transaction, participant) {
512
+ const state = transactionState(transaction);
513
+ if (state.seen?.has(participant)) return;
514
+ if (participant.key) {
515
+ const kinds = state.index ??= /* @__PURE__ */ new Map();
516
+ let index = kinds.get(participant.kind);
517
+ if (!index) kinds.set(participant.kind, index = /* @__PURE__ */ new Map());
518
+ const previous = index.get(participant.key);
519
+ if (previous) {
520
+ this.validateCollision(previous, participant);
521
+ if (previous === participant) return;
522
+ if (participant.collision === "keep-first") {
523
+ (state.seen ??= /* @__PURE__ */ new Set()).add(participant);
524
+ return;
525
+ }
526
+ try {
527
+ participant.merge(previous);
528
+ (state.seen ??= /* @__PURE__ */ new Set()).add(participant);
529
+ } catch (error) {
530
+ state.participants.push(participant);
531
+ this.discardMergedTransactions(transaction);
532
+ throw error;
533
+ }
534
+ return;
535
+ }
536
+ index.set(participant.key, participant);
537
+ } else (state.seen ??= /* @__PURE__ */ new Set()).add(participant);
538
+ state.participants.push(participant);
539
+ }
540
+ validateCollision(previous, participant) {
541
+ if (previous !== participant && participant.collision !== "keep-first" && !participant.merge) throw new Error("[Askr] Participant collision requires merge or keep-first.");
542
+ }
543
+ discardMergedTransactions(transaction, mergedParent) {
544
+ const state = transactionState(transaction);
545
+ const affected = /* @__PURE__ */ new Set([transaction]);
546
+ const participants = new Set(state.participants);
547
+ const ancestors = [];
548
+ for (let ancestor = state.parent; ancestor; ancestor = transactionState(ancestor).parent) if (ancestor.active) ancestors.push(ancestor);
549
+ let changed;
550
+ do {
551
+ changed = false;
552
+ for (const ancestor of ancestors) if (!affected.has(ancestor) && (ancestor === mergedParent || transactionState(ancestor).participants.some((participant) => participants.has(participant)))) {
553
+ affected.add(ancestor);
554
+ changed = true;
555
+ for (const participant of transactionState(ancestor).participants) participants.add(participant);
556
+ }
557
+ } while (changed);
558
+ const frames = [transaction, ...ancestors.filter((ancestor) => affected.has(ancestor))];
559
+ const owners = /* @__PURE__ */ new Set();
560
+ for (let index = frames.length - 1; index >= 0; index--) {
561
+ const frame = frames[index];
562
+ const frameState = transactionState(frame);
563
+ frameState.phase = "discarding";
564
+ for (let member = frameState.participants.length - 1; member >= 0; member--) {
565
+ const participant = frameState.participants[member];
566
+ if (owners.has(participant)) frameState.participants.splice(member, 1);
567
+ else owners.add(participant);
568
+ }
569
+ }
570
+ for (const frame of frames) this.drainRollback(frame);
571
+ }
572
+ suspend(transaction) {
573
+ const state = transactionState(transaction);
574
+ this.assertOwned(transaction);
575
+ if (this.frame === transaction) this.frame = this.liveFrame(state.parent);
576
+ }
577
+ apply(transaction, operation) {
578
+ const state = transactionState(transaction);
579
+ this.assertOwned(transaction);
580
+ if (!transaction.active) throw new Error("[Askr] Cannot apply a settled transaction.");
581
+ const previous = this.frame;
582
+ const previousPhase = state.phase;
583
+ if (previous && previous !== transaction && previous.active) {
584
+ let ancestor = previous;
585
+ while (ancestor && ancestor !== transaction) ancestor = transactionState(ancestor).parent;
586
+ if (!ancestor) state.parent = previous;
587
+ }
588
+ this.frame = transaction;
589
+ state.phase = "applying";
590
+ try {
591
+ return operation();
592
+ } finally {
593
+ if (transaction.active) state.phase = previousPhase;
594
+ this.frame = this.liveFrame(previous);
595
+ }
596
+ }
597
+ /** State writes survive rollback. Their notifications wait until all
598
+ * framework restoration or post-commit work has finished. */
599
+ deferCompletion(key, complete) {
600
+ const transaction = this.frame;
601
+ if (!transaction || !this.notificationsDeferred()) return false;
602
+ const state = transactionState(transaction);
603
+ (state.completions ??= /* @__PURE__ */ new Map()).set(key, complete);
604
+ return true;
605
+ }
606
+ notificationsDeferred() {
607
+ let transaction = this.frame;
608
+ while (transaction) {
609
+ const state = transactionState(transaction);
610
+ if (state.deferNotifications && (transaction.active || state.phase === "discarding")) return true;
611
+ transaction = state.parent;
612
+ }
613
+ return false;
614
+ }
615
+ commit(transaction) {
616
+ const state = transactionState(transaction);
617
+ this.assertOwned(transaction);
618
+ if (!transaction.active || state.committing) return;
619
+ state.committing = true;
620
+ try {
621
+ const parent = state.parent;
622
+ if (parent?.active) {
623
+ this.joinParentTransaction(transaction, state, parent);
624
+ return;
625
+ }
626
+ this.applyAndSettle(transaction, state);
627
+ } finally {
628
+ state.committing = false;
629
+ }
630
+ }
631
+ /**
632
+ * Fold a nested transaction into its still-open parent.
633
+ *
634
+ * Nothing is applied here: the child's participants, index, resources and
635
+ * identity set move to the parent, which will run them when it commits. The
636
+ * work is in reconciling identity — a participant may already exist in the
637
+ * parent under the same key, in which case the two have to be merged, and a
638
+ * merge can register further participants of its own, so it runs with its own
639
+ * failure ownership.
640
+ */
641
+ joinParentTransaction(transaction, state, parent) {
642
+ const parentState = transactionState(parent);
643
+ let needsMerge = false;
644
+ let changedIdentity = false;
645
+ for (const participant of state.participants) {
646
+ if (participant.key && state.seen?.has(participant)) changedIdentity = true;
647
+ if (parentState.seen?.has(participant)) continue;
648
+ const previous = participant.key ? parent.participant(participant.key, participant.kind) : void 0;
649
+ if (previous) {
650
+ this.validateCollision(previous, participant);
651
+ if (previous !== participant && participant.collision !== "keep-first") needsMerge = true;
652
+ }
653
+ }
654
+ for (const [kind, index] of state.index?.entries() ?? []) {
655
+ index.forEach((participant, key) => {
656
+ if (participant.key !== key || participant.kind !== kind) changedIdentity = true;
657
+ });
658
+ if (changedIdentity) break;
659
+ }
660
+ if (needsMerge || changedIdentity) {
661
+ try {
662
+ for (const participant of state.participants) {
663
+ if (parentState.seen?.has(participant)) continue;
664
+ const previous = participant.key ? parent.participant(participant.key, participant.kind) : void 0;
665
+ if (previous && previous !== participant) {
666
+ if (participant.collision !== "keep-first") participant.merge(previous);
667
+ if (!parent.active) this.discard(transaction);
668
+ if (!transaction.active) return;
669
+ (parentState.seen ??= /* @__PURE__ */ new Set()).add(participant);
670
+ }
671
+ }
672
+ } catch (error) {
673
+ this.discardMergedTransactions(transaction, parent);
674
+ throw error;
675
+ }
676
+ for (const participant of state.participants) if (!participant.key || !parent.participant(participant.key, participant.kind)) this.add(parent, participant);
677
+ } else {
678
+ for (const participant of state.participants) {
679
+ if (parentState.seen?.has(participant)) {
680
+ if (participant.key) state.index.get(participant.kind).delete(participant.key);
681
+ continue;
682
+ }
683
+ if (participant.key) {
684
+ const previous = parent.participant(participant.key, participant.kind);
685
+ if (previous) {
686
+ if (previous !== participant) (state.seen ??= /* @__PURE__ */ new Set()).add(participant);
687
+ continue;
688
+ }
689
+ }
690
+ parentState.participants.push(participant);
691
+ }
692
+ for (const [kind, index] of state.index?.entries() ?? []) {
693
+ if (!index.size) continue;
694
+ const kinds = parentState.index ??= /* @__PURE__ */ new Map();
695
+ kinds.set(kind, mergeEarlierEntries(kinds.get(kind), index));
696
+ }
697
+ }
698
+ if (state.resources) parentState.resources = mergeEarlierEntries(parentState.resources, state.resources, !needsMerge && !changedIdentity);
699
+ if (state.seen) {
700
+ if (!parentState.seen) parentState.seen = state.seen;
701
+ else if (parentState.seen.size < state.seen.size) {
702
+ for (const participant of parentState.seen) state.seen.add(participant);
703
+ parentState.seen = state.seen;
704
+ } else for (const participant of state.seen) parentState.seen.add(participant);
705
+ }
706
+ this.mergeCompletions(transaction, parent);
707
+ state.phase = "joined";
708
+ this.suspend(transaction);
709
+ this.release(transaction);
710
+ }
711
+ /**
712
+ * Run a root transaction to completion.
713
+ *
714
+ * Apply and publish interleave because an application hook can render during
715
+ * either, appending participants that must themselves be applied before
716
+ * anything else publishes. Settlement then runs each remaining phase over
717
+ * every participant, collecting failures rather than stopping, so one broken
718
+ * cleanup cannot strand the rest.
719
+ *
720
+ * A participant that deactivates the transaction returns early from here,
721
+ * which deliberately skips settlement — the `finally` blocks still restore
722
+ * the frame and release.
723
+ */
724
+ applyAndSettle(transaction, state) {
725
+ const previous = this.frame;
726
+ this.frame = transaction;
727
+ let applied = 0;
728
+ let published = 0;
729
+ try {
730
+ while (applied < state.participants.length || published < state.participants.length) {
731
+ state.phase = "applying";
732
+ while (applied < state.participants.length) {
733
+ state.participants[applied++].apply?.();
734
+ if (!transaction.active) return;
735
+ }
736
+ state.phase = "publishing";
737
+ if (published < state.participants.length) state.participants[published++].publish?.();
738
+ if (!transaction.active) return;
739
+ }
740
+ } catch (error) {
741
+ this.discard(transaction);
742
+ throw error;
743
+ } finally {
744
+ this.frame = this.liveFrame(previous === transaction ? state.parent : previous);
745
+ }
746
+ state.phase = "settling";
747
+ try {
748
+ for (const phase of [
749
+ "settle",
750
+ "activate",
751
+ "complete"
752
+ ]) for (const participant of state.participants) try {
753
+ participant[phase]?.();
754
+ } catch (error) {
755
+ (state.errors ??= []).push(error);
756
+ }
757
+ this.complete(transaction, (error) => (state.errors ??= []).push(error));
758
+ state.phase = "committed";
759
+ if (state.errors?.length) this.options.settlementErrors?.(state.errors, transaction);
760
+ } finally {
761
+ state.phase = "committed";
762
+ this.release(transaction);
763
+ }
764
+ }
765
+ discard(transaction) {
766
+ this.assertOwned(transaction);
767
+ if (!transaction.active) return;
768
+ this.drainRollback(transaction);
769
+ }
770
+ drainRollback(transaction) {
771
+ const state = transactionState(transaction);
772
+ const previous = this.frame;
773
+ this.frame = transaction;
774
+ state.phase = "discarding";
775
+ const report = (error) => {
776
+ try {
777
+ this.options.rollbackError?.(error);
778
+ } catch {}
779
+ };
780
+ try {
781
+ for (let index = state.participants.length - 1; index >= 0; index--) try {
782
+ state.participants[index].rollback?.();
783
+ } catch (error) {
784
+ report(error);
785
+ }
786
+ } finally {
787
+ state.phase = "discarded";
788
+ this.frame = this.liveFrame(previous === transaction ? state.parent : previous);
789
+ if (state.parent?.active || state.parent?.phase === "discarding") this.mergeCompletions(transaction, state.parent);
790
+ else this.complete(transaction, report);
791
+ this.release(transaction);
792
+ }
793
+ }
794
+ mergeCompletions(transaction, parent) {
795
+ const state = transactionState(transaction);
796
+ if (!state.completions) return;
797
+ const parentState = transactionState(parent);
798
+ const completions = parentState.completions ??= /* @__PURE__ */ new Map();
799
+ for (const [key, complete] of state.completions) completions.set(key, complete);
800
+ }
801
+ complete(transaction, report) {
802
+ const state = transactionState(transaction);
803
+ for (const complete of state.completions?.values() ?? []) try {
804
+ complete();
805
+ } catch (error) {
806
+ report(error);
807
+ }
808
+ }
809
+ release(transaction) {
810
+ const state = transactionState(transaction);
811
+ state.participants.length = 0;
812
+ state.seen = void 0;
813
+ state.index = void 0;
814
+ state.resources = void 0;
815
+ state.completions?.clear();
816
+ state.completions = void 0;
817
+ }
818
+ liveFrame(transaction) {
819
+ while (transaction && !transaction.active) transaction = transactionState(transaction).parent;
820
+ return transaction;
821
+ }
822
+ assertOwned(transaction) {
823
+ if (transactionState(transaction).coordinator !== this) throw new Error("[Askr] Transaction belongs to another runtime.");
824
+ }
825
+ };
826
+ //#endregion
827
+ //#region src/common/logger.ts
828
+ /**
829
+ * Shared logger interface for runtime and tooling code.
830
+ *
831
+ * Debug, info, and warn stay silent in production. Errors always log.
832
+ */
833
+ function callConsole(method, args) {
834
+ const c = typeof console !== "undefined" ? console : void 0;
835
+ if (!c) return;
836
+ const fn = c[method];
837
+ if (typeof fn === "function") try {
838
+ fn.apply(console, args);
839
+ } catch {}
840
+ }
841
+ const logger = {
842
+ debug: (...args) => {
843
+ if (isProductionEnvironment()) return;
844
+ callConsole("debug", args);
845
+ },
846
+ info: (...args) => {
847
+ if (isProductionEnvironment()) return;
848
+ callConsole("info", args);
849
+ },
850
+ warn: (...args) => {
851
+ if (isProductionEnvironment()) return;
852
+ callConsole("warn", args);
853
+ },
854
+ error: (...args) => {
855
+ callConsole("error", args);
856
+ }
857
+ };
858
+ //#endregion
859
+ //#region src/runtime/runtime-state.ts
860
+ /**
861
+ * The renderer host for an environment that has no DOM renderer.
862
+ *
863
+ * This is not only a pre-boot placeholder: SSR and SSG never install a renderer,
864
+ * so it is the live host for the whole life of every server render. It
865
+ * therefore has to be usable, not merely loud, and it follows one rule:
866
+ *
867
+ * - Bookkeeping degrades. Capturing, releasing and inspecting hosts, scopes and
868
+ * key maps answer as though nothing is mounted, because during a server
869
+ * render nothing is.
870
+ * - Anything that would produce or destroy DOM throws. Reaching `evaluate`,
871
+ * `replaceComponentRange` or a teardown without a renderer means execution
872
+ * believed it had one, which is a bug worth surfacing rather than silently
873
+ * dropping the output.
874
+ *
875
+ * Browser composition replaces this through `installRuntimeRenderer`.
876
+ */
877
+ function createMissingRendererHost() {
878
+ const noop = () => void 0;
879
+ const missing = (method) => {
880
+ throw new Error(`[Askr] renderer host is not configured; cannot call ${method}().`);
881
+ };
882
+ return {
883
+ captureComponentHost: noop,
884
+ releaseComponentHost: noop,
885
+ detachPortalHostOutput: noop,
886
+ isComponentHostDetached() {
887
+ return false;
888
+ },
889
+ clearChildScopeHost(scope) {
890
+ scope.dom = void 0;
891
+ scope.range = void 0;
892
+ },
893
+ captureChildScopeHost: noop,
894
+ resolveScopeBoundary() {
895
+ return {
896
+ dom: void 0,
897
+ range: void 0
898
+ };
899
+ },
900
+ prepareScopeRemoval() {
901
+ return {
902
+ dom: void 0,
903
+ range: void 0
904
+ };
905
+ },
906
+ recordRemovedScopeBoundary: noop,
907
+ teardownScopeHost() {
908
+ return 0;
909
+ },
910
+ hasUnmountedComponentHost() {
911
+ return false;
912
+ },
913
+ recordInlineComponentHost(instance, target) {
914
+ instance.target = target;
915
+ },
916
+ applyComponentResult(instance) {
917
+ if (instance.target || instance._placeholder) return missing("applyComponentResult");
918
+ return false;
919
+ },
920
+ classifyComponentUpdate() {
921
+ return {
922
+ useFastPath: false,
923
+ reason: "no-root"
924
+ };
925
+ },
926
+ evaluate() {
927
+ missing("evaluate");
928
+ },
929
+ cleanupInstancesUnder() {
930
+ missing("cleanupInstancesUnder");
931
+ },
932
+ replaceComponentRange() {
933
+ return missing("replaceComponentRange");
934
+ },
935
+ teardownNodeSubtree() {
936
+ missing("teardownNodeSubtree");
937
+ },
938
+ populateKeyMapForElement: noop,
939
+ getKeyMapForElement: noop,
940
+ isKeyedReorderFastPathEligible() {
941
+ return {
942
+ useFastPath: false,
943
+ totalKeyed: 0,
944
+ totalChildren: 0,
945
+ currentKeyCount: 0,
946
+ moveCount: 0,
947
+ lisLen: 0,
948
+ hasPropChanges: false,
949
+ isWholeKeyedList: false
950
+ };
951
+ },
952
+ markReactivePropsDirtySource: noop
953
+ };
954
+ }
955
+ function createRuntimeState(scheduler = globalScheduler) {
956
+ return {
957
+ scheduler,
958
+ renderer: createMissingRendererHost(),
959
+ commits: new CommitCoordinator({
960
+ rollbackError(error) {
961
+ logger.error("[Askr] transaction rollback failed:", error);
962
+ },
963
+ settlementErrors(errors) {
964
+ logger.error("[Askr] committed lifecycle work failed:", new AggregateError(errors, "Committed lifecycle work failed"));
965
+ }
966
+ })
967
+ };
968
+ }
969
+ const defaultRuntimeState = createRuntimeState();
970
+ //#endregion
971
+ //#region src/runtime/access.ts
972
+ function getRuntimeScheduler() {
973
+ return defaultRuntimeState.scheduler;
974
+ }
975
+ function getRuntimeEvaluation() {
976
+ return defaultRuntimeState.renderer;
977
+ }
978
+ function getRuntimeCleanup() {
979
+ return defaultRuntimeState.renderer;
980
+ }
981
+ function getRuntimeScopes() {
982
+ return defaultRuntimeState.renderer;
983
+ }
984
+ function getRuntimeKeys() {
985
+ return defaultRuntimeState.renderer;
986
+ }
987
+ /** Not exported: `markRuntimeReactivePropsDirtySource` is its only caller. */
988
+ function getRuntimeReactivity() {
989
+ return defaultRuntimeState.renderer;
990
+ }
991
+ /** Native boot composition does not require a published extension view. */
992
+ function installRuntimeRenderer(renderer) {
993
+ defaultRuntimeState.renderer = renderer;
994
+ }
995
+ function enqueueRuntimeTask(task) {
996
+ getRuntimeScheduler().enqueue(task);
997
+ }
998
+ function enqueueRuntimeLane(lane, task) {
999
+ getRuntimeScheduler().enqueueInLane(lane, task);
1000
+ }
1001
+ function requestRuntimeWork(lane, work) {
1002
+ work.request(getRuntimeScheduler(), lane);
1003
+ }
1004
+ function runRuntimeHandlerScope(fn, flushMode = "defer") {
1005
+ const savedScope = clearCurrentComponentScope();
1006
+ try {
1007
+ return getRuntimeScheduler().runInHandlerScope(fn, flushMode);
1008
+ } finally {
1009
+ endComponentScope(savedScope);
1010
+ }
1011
+ }
1012
+ function runRuntimeWithSyncProgress(fn) {
1013
+ return getRuntimeScheduler().runWithSyncProgress(fn);
1014
+ }
1015
+ function isRuntimeSchedulerExecuting() {
1016
+ return getRuntimeScheduler().isExecuting();
1017
+ }
1018
+ function getRuntimeFlushVersion() {
1019
+ return getRuntimeScheduler().getFlushVersion();
1020
+ }
1021
+ function flushRuntimeScheduler() {
1022
+ getRuntimeScheduler().flush();
1023
+ }
1024
+ function markRuntimeReactivePropsDirtySource(source) {
1025
+ getRuntimeReactivity().markReactivePropsDirtySource(source);
1026
+ }
1027
+ /**
1028
+ * Wrap an event listener so its work runs inside a scheduler handler scope.
1029
+ *
1030
+ * Resolves the active scheduler per call rather than closing over the module
1031
+ * singleton, so a runtime constructed with its own scheduler schedules its own
1032
+ * handlers.
1033
+ */
1034
+ function scheduleEventHandler(handler) {
1035
+ return (event) => {
1036
+ try {
1037
+ getRuntimeScheduler().runInHandlerScope(() => {
1038
+ handler.call(null, event);
1039
+ });
1040
+ } catch (error) {
1041
+ logger.error("[Askr] Event handler error:", error);
1042
+ }
1043
+ };
1044
+ }
1045
+ //#endregion
1046
+ export { getRuntimeEnv as C, incrementPerfMetric as S, isProductionEnvironment as T, defaultRuntimeState as _, getRuntimeEvaluation as a, ScheduledWork as b, getRuntimeScopes as c, markRuntimeReactivePropsDirtySource as d, requestRuntimeWork as f, createRuntimeState as g, scheduleEventHandler as h, getRuntimeCleanup as i, installRuntimeRenderer as l, runRuntimeWithSyncProgress as m, enqueueRuntimeTask as n, getRuntimeFlushVersion as o, runRuntimeHandlerScope as p, flushRuntimeScheduler as r, getRuntimeKeys as s, enqueueRuntimeLane as t, isRuntimeSchedulerExecuting as u, logger as v, isDevelopmentEnvironment as w, addPerfDuration as x, SCHEDULER_LANES as y };