@async/framework 0.7.0 → 0.9.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 CHANGED
@@ -1,5 +1,27 @@
1
1
  # Changelog
2
2
 
3
+ ## Unreleased
4
+
5
+ ## 0.9.0 - 2026-06-17
6
+
7
+ - Added `createBoundaryReceiver(...)` for optional out-of-order boundary patch
8
+ delivery with per-boundary sequence checks, signal/cache effect ordering,
9
+ scheduler flushing, redirects, and destroyed parent-scope filtering.
10
+
11
+ ## 0.8.0 - 2026-06-17
12
+
13
+ - Split browser and server entrypoints with `@async/framework/browser`,
14
+ `@async/framework/server`, browser-only CDN bundles, and server-only local
15
+ function registry exports.
16
+ - Added `createRequestContextStore(...)` for Node request-scoped server
17
+ function context using `AsyncLocalStorage`.
18
+ - Added the Layer 1.5 scheduler for deterministic signal binding, lifecycle,
19
+ effect, async, and post-flush phases.
20
+ - Added browser microtask scheduling by default and manual scheduler flushing for
21
+ server render paths.
22
+ - Threaded `this.scheduler` through loader, handler, component, async signal,
23
+ server, router, and partial contexts.
24
+
3
25
  ## 0.7.0 - 2026-06-17
4
26
 
5
27
  - Added router navigation abort/version guards so stale route partials cannot
package/README.md CHANGED
@@ -53,6 +53,8 @@ primitives. It keeps the runtime small and explicit:
53
53
  - Handlers live in a registry and run through delegated DOM events.
54
54
  - Async signals use native `AbortSignal` cancellation and suppress stale async
55
55
  completions.
56
+ - A small scheduler batches signal-driven DOM bindings, lifecycle callbacks,
57
+ effects, and async refreshes without adding a render loop.
56
58
  - Browser and server cache declarations are structurally split.
57
59
  - Boundaries can be swapped out of order and rescanned, which keeps server
58
60
  streaming and partial HTML replacement simple.
@@ -68,7 +70,7 @@ next level on every app.
68
70
 
69
71
  | Layer | Name | Requirement | Purpose |
70
72
  | --- | --- | --- | --- |
71
- | 1 | Runtime bootloader | No build. CDN or direct ESM import. | Signals, async signals, handlers, command events, lifecycle pseudo-events, scoped fragments, and boundary swaps. |
73
+ | 1 | Runtime bootloader | No build. CDN or direct ESM import. | Signals, async signals, scheduler, handlers, command events, lifecycle pseudo-events, scoped fragments, and boundary swaps. |
72
74
  | 2 | App/server layer | Light server integration. No app compiler required. | `Async.use(...)`, router modes, server function proxy, partial registry, SSR output, browser activation, and split browser/server cache. |
73
75
  | 3 | Authoring build | Build step required. | JSX, ESM, and TypeScript authoring that lowers into Layer 1 HTML attributes and Layer 2 registries. |
74
76
  | 4 | Chunk and resumability metadata | Build metadata required. | Lazy module manifests, visibility/prefetch hints, resource graphs, and resumability records that the bootloader can consume. |
@@ -90,18 +92,18 @@ and package lifecycle tooling. Browser consumers import ESM directly.
90
92
 
91
93
  ## CDN
92
94
 
93
- The package ships root CDN artifacts for UNPKG and can be loaded without a
95
+ The package ships browser CDN artifacts for UNPKG and can be loaded without a
94
96
  build step. Use `@latest` for quick prototypes, and pin an exact version in
95
97
  production:
96
98
 
97
99
  | File | Format | Use |
98
100
  | --- | --- | --- |
99
- | `framework.js` | ESM | Readable browser module bundle |
100
- | `framework.min.js` | ESM | Compact browser module bundle |
101
- | `framework.umd.js` | UMD | Readable script-tag/CommonJS-style bundle |
102
- | `framework.umd.min.js` | UMD | Compact script-tag/CommonJS-style bundle and default CDN file |
103
- | `framework.ts` | Bundled TypeScript source | TS-aware runtimes and higher-layer tooling |
104
- | `framework.d.ts` | Type declarations | TypeScript declarations for the public API |
101
+ | `browser.js` | ESM | Readable browser module bundle |
102
+ | `browser.min.js` | ESM | Compact browser module bundle |
103
+ | `browser.umd.js` | UMD | Readable script-tag/CommonJS-style bundle |
104
+ | `browser.umd.min.js` | UMD | Compact script-tag/CommonJS-style bundle and default CDN file |
105
+ | `browser.ts` | Bundled TypeScript source | TS-aware runtimes and higher-layer tooling |
106
+ | `browser.d.ts` | Type declarations | TypeScript declarations for the browser API |
105
107
 
106
108
  ```html
107
109
  <main async:container>
@@ -113,7 +115,7 @@ production:
113
115
  import {
114
116
  Async,
115
117
  createSignal
116
- } from "https://unpkg.com/@async/framework@latest/framework.js";
118
+ } from "https://unpkg.com/@async/framework@latest/browser.js";
117
119
 
118
120
  Async.use({
119
121
  signal: {
@@ -136,7 +138,7 @@ For a plain script tag, use the UMD bundle. In this UMD-only global form,
136
138
  call `Async.Loader(...)` directly.
137
139
 
138
140
  ```html
139
- <script src="https://unpkg.com/@async/framework@latest/framework.umd.min.js"></script>
141
+ <script src="https://unpkg.com/@async/framework@latest/browser.umd.min.js"></script>
140
142
  <script>
141
143
  Async.use({
142
144
  signal: {
@@ -159,7 +161,7 @@ You can also use an import map so app code imports `@async/framework` by name:
159
161
  <script type="importmap">
160
162
  {
161
163
  "imports": {
162
- "@async/framework": "https://unpkg.com/@async/framework@latest/framework.js"
164
+ "@async/framework": "https://unpkg.com/@async/framework@latest/browser.js"
163
165
  }
164
166
  }
165
167
  </script>
@@ -187,6 +189,10 @@ You can also use an import map so app code imports `@async/framework` by name:
187
189
 
188
190
  ## Core API
189
191
 
192
+ For npm consumers, `@async/framework` uses conditional exports: browser-aware
193
+ tooling receives the browser entry, while Node receives the server-capable
194
+ entry. Use explicit subpaths when the target matters.
195
+
190
196
  ```js
191
197
  import {
192
198
  Async,
@@ -204,8 +210,8 @@ import {
204
210
  createRegistryStore,
205
211
  createRouteRegistry,
206
212
  createRouter,
213
+ createScheduler,
207
214
  createServerProxy,
208
- createServerRegistry,
209
215
  createSignalRegistry,
210
216
  defineAttributeConfig,
211
217
  defineApp,
@@ -218,7 +224,16 @@ import {
218
224
  readSnapshot,
219
225
  route,
220
226
  signal
221
- } from "@async/framework";
227
+ } from "@async/framework/browser";
228
+ ```
229
+
230
+ Server-only APIs live behind the server entry:
231
+
232
+ ```js
233
+ import {
234
+ createRequestContextStore,
235
+ createServerRegistry
236
+ } from "@async/framework/server";
222
237
  ```
223
238
 
224
239
  `Loader` is the canonical loader factory. `AsyncLoader` remains as a
@@ -373,6 +388,49 @@ signals.set("product.title", "Headphones");
373
388
 
374
389
  `signal(...)` remains a compatibility alias for `createSignal(...)`.
375
390
 
391
+ ### Scheduler
392
+
393
+ The scheduler is the Layer 1.5 ordering engine. Signal writes are still
394
+ synchronous:
395
+
396
+ ```js
397
+ signals.set("count", 3);
398
+ signals.get("count");
399
+ // 3
400
+ ```
401
+
402
+ DOM bindings, component lifecycle callbacks, component effects, and async signal
403
+ refreshes are scheduled through deterministic phases:
404
+
405
+ ```txt
406
+ binding -> lifecycle -> effect -> async -> post
407
+ ```
408
+
409
+ Browser runtimes use a microtask scheduler by default. Server runtimes use a
410
+ manual scheduler and drain it during `runtime.render(...)`.
411
+
412
+ ```js
413
+ import {
414
+ createScheduler
415
+ } from "@async/framework";
416
+
417
+ const scheduler = createScheduler({
418
+ strategy: "manual"
419
+ });
420
+
421
+ const runtime = Async.start({
422
+ root: document,
423
+ scheduler
424
+ });
425
+
426
+ signals.set("count", 1);
427
+ await scheduler.flush();
428
+ ```
429
+
430
+ Most apps do not need to call the scheduler directly. It is exposed for tests,
431
+ custom runtimes, streaming receivers, and higher layers that need explicit flush
432
+ boundaries.
433
+
376
434
  ### Async Signals
377
435
 
378
436
  Async signals add loading state, error state, versions, refresh, and cancel to a
@@ -401,6 +459,7 @@ The async function context includes:
401
459
  | `this.id` | Current async signal id |
402
460
  | `this.version` | Run version |
403
461
  | `this.abort` | Native `AbortSignal` with non-enumerable `cancel(reason?)` |
462
+ | `this.scheduler` | Current runtime scheduler |
404
463
  | `this.refresh()` | Start a new run |
405
464
 
406
465
  `this.abort` can be passed directly to `fetch` or to `delay`:
@@ -619,6 +678,10 @@ Server registries run locally on the server and proxies call an HTTP endpoint
619
678
  from the browser. Both expose the same dotted call shape.
620
679
 
621
680
  ```js
681
+ import {
682
+ createServerRegistry
683
+ } from "@async/framework/server";
684
+
622
685
  const server = createServerRegistry({
623
686
  "cart.add"(productId, quantity) {
624
687
  return {
@@ -634,6 +697,10 @@ const server = createServerRegistry({
634
697
  Client proxy:
635
698
 
636
699
  ```js
700
+ import {
701
+ createServerProxy
702
+ } from "@async/framework/browser";
703
+
637
704
  const server = createServerProxy({
638
705
  endpoint: "/__async/server",
639
706
  signals,
@@ -983,6 +1050,47 @@ loader.swap(
983
1050
  `swap(boundaryId, fragmentOrTemplate)` replaces the boundary contents and
984
1051
  rescans the inserted fragment.
985
1052
 
1053
+ When boundary patches can arrive independently, use `createBoundaryReceiver`.
1054
+ It keeps per-boundary sequence state, applies signal/cache effects before the
1055
+ HTML swap, flushes scheduled bindings, and ignores stale child patches after a
1056
+ parent scope is destroyed.
1057
+
1058
+ ```js
1059
+ import { createBoundaryReceiver } from "@async/framework/browser";
1060
+
1061
+ const receiver = createBoundaryReceiver({
1062
+ loader: runtime.loader,
1063
+ signals: runtime.signals,
1064
+ cache: runtime.browser.cache,
1065
+ scheduler: runtime.scheduler,
1066
+ router: runtime.router
1067
+ });
1068
+
1069
+ await receiver.apply({
1070
+ boundary: "product",
1071
+ seq: 1,
1072
+ signals: {
1073
+ product: { title: "Keyboard" }
1074
+ },
1075
+ cache: {
1076
+ browser: {
1077
+ "product:sku-1": { title: "Keyboard" }
1078
+ }
1079
+ },
1080
+ html: `
1081
+ <article>
1082
+ <h1 signal:text="product.title"></h1>
1083
+ <button type="button" on:click="server.cart.add(productId)">Add</button>
1084
+ </article>
1085
+ `
1086
+ });
1087
+ ```
1088
+
1089
+ Sequence numbers are tracked per boundary: `hero` patch `10` can apply before
1090
+ `reviews` patch `2`, while a later `hero` patch `9` is ignored. The receiver
1091
+ does not add transport management, a transaction log, hydration, or component
1092
+ rerendering.
1093
+
986
1094
  ## Examples
987
1095
 
988
1096
  | Example | Shows |
@@ -1022,7 +1130,7 @@ pnpm run release:check
1022
1130
  such as signals, handlers, server functions, partials, routes, and components.
1023
1131
  It writes `.async/registry-manifest.json` plus a per-file cache at
1024
1132
  `.async/registry-lint-cache.json`, skips generated root bundles such as
1025
- `framework.umd.min.js`, and fails only when the same registry type and id are
1133
+ `browser.umd.min.js`, and fails only when the same registry type and id are
1026
1134
  declared with different normalized content. Duplicate declarations with the
1027
1135
  same content are reported as dedupe candidates, not errors.
1028
1136
 
@@ -1,5 +1,5 @@
1
1
  // Generated by scripts/build-framework-bundle.js. Do not edit by hand.
2
- // Public type declarations for @async/framework.
2
+ // Browser type declarations for @async/framework/browser.
3
3
 
4
4
  export type RuntimeTarget = "browser" | "server";
5
5
  export type RouterMode = "csr" | "spa" | "ssr" | "ssr-spa" | "mpa";
@@ -40,6 +40,52 @@ export interface TemplateResult {
40
40
  readonly values: readonly unknown[];
41
41
  }
42
42
 
43
+ export type SchedulerStrategy = "microtask" | "manual";
44
+ export type SchedulerPhase = "binding" | "lifecycle" | "effect" | "async" | "post" | string;
45
+ export interface SchedulerJob {
46
+ id: number;
47
+ phase: SchedulerPhase;
48
+ scope?: unknown;
49
+ boundary?: string;
50
+ key?: string;
51
+ canceled: boolean;
52
+ cancel(): void;
53
+ }
54
+ export interface SchedulerOptions {
55
+ strategy?: SchedulerStrategy;
56
+ phases?: SchedulerPhase[];
57
+ maxDepth?: number;
58
+ onError?(error: unknown, job: SchedulerJob): void;
59
+ }
60
+ export interface SchedulerInspection {
61
+ strategy: SchedulerStrategy;
62
+ phases: SchedulerPhase[];
63
+ pending: Record<string, number>;
64
+ scopesDestroyed: number;
65
+ flushing: boolean;
66
+ scheduled: boolean;
67
+ }
68
+ export interface Scheduler {
69
+ strategy: SchedulerStrategy;
70
+ phases: SchedulerPhase[];
71
+ batch<T>(fn: () => T): T;
72
+ enqueue(phase: SchedulerPhase, job: () => MaybePromise<unknown>, options?: { scope?: unknown; boundary?: string; key?: string }): Cleanup;
73
+ flush(): Promise<void>;
74
+ flushScope(scope: unknown): Promise<void>;
75
+ afterFlush(job: () => MaybePromise<unknown>, options?: { scope?: unknown; boundary?: string; key?: string }): Cleanup;
76
+ cancelScope(scope: unknown): this;
77
+ markScopeDestroyed(scope: unknown): this;
78
+ isScopeDestroyed(scope: unknown): boolean;
79
+ destroy(): void;
80
+ inspect(): SchedulerInspection;
81
+ }
82
+
83
+ export interface RequestContextStore {
84
+ run<T>(context: Record<string, unknown> | undefined, fn: () => T): T;
85
+ get(): Record<string, unknown> | undefined;
86
+ snapshot(): Record<string, unknown>;
87
+ }
88
+
43
89
  export interface Signal<T = unknown> {
44
90
  readonly kind: "signal";
45
91
  value: T;
@@ -113,6 +159,7 @@ export interface AsyncSignalContext {
113
159
  router?: Router;
114
160
  loader?: LoaderInstance;
115
161
  cache?: CacheRegistry;
162
+ scheduler?: Scheduler;
116
163
  refresh(): Promise<unknown>;
117
164
  }
118
165
 
@@ -149,6 +196,7 @@ export interface HandlerContext {
149
196
  loader?: LoaderInstance;
150
197
  router?: Router;
151
198
  cache?: CacheRegistry;
199
+ scheduler?: Scheduler;
152
200
  event?: Event;
153
201
  element?: Element;
154
202
  el?: Element;
@@ -192,6 +240,7 @@ export interface ServerContext {
192
240
  locals?: unknown;
193
241
  abort?: AbortSignal;
194
242
  cache?: CacheRegistry;
243
+ scheduler?: Scheduler;
195
244
  server: ServerNamespace;
196
245
  [key: string]: unknown;
197
246
  }
@@ -216,6 +265,7 @@ export interface ServerProxyOptions {
216
265
  loader?: LoaderInstance;
217
266
  router?: Router;
218
267
  cache?: CacheRegistry;
268
+ scheduler?: Scheduler;
219
269
  headers?: Record<string, string>;
220
270
  }
221
271
 
@@ -263,6 +313,7 @@ export interface PartialContext {
263
313
  browserCache?: CacheRegistry;
264
314
  partials: PartialRegistry;
265
315
  abort?: AbortSignal;
316
+ scheduler?: Scheduler;
266
317
  request?: Request;
267
318
  locals?: unknown;
268
319
  [key: string]: unknown;
@@ -315,6 +366,7 @@ export interface RouterOptions {
315
366
  fetch?: typeof fetch;
316
367
  routeEndpoint?: string;
317
368
  attributes?: AttributeConfig;
369
+ scheduler?: Scheduler;
318
370
  }
319
371
 
320
372
  export interface Router {
@@ -328,6 +380,7 @@ export interface Router {
328
380
  server?: ServerNamespace;
329
381
  cache?: CacheRegistry;
330
382
  partials?: PartialRegistry;
383
+ scheduler: Scheduler;
331
384
  attributes: NormalizedAttributeConfig;
332
385
  start(): this;
333
386
  match(url: string | URL): RouteMatch | null;
@@ -346,6 +399,7 @@ export interface ComponentContext {
346
399
  server?: ServerNamespace;
347
400
  router?: Router;
348
401
  cache?: CacheRegistry;
402
+ scheduler?: Scheduler;
349
403
  signal<T = unknown>(initial: T): SignalRef<T>;
350
404
  signal<T = unknown>(name: string, initial: T): SignalRef<T>;
351
405
  computed<T = unknown>(name: string, fn: (this: ComponentContext) => T): SignalRef<T>;
@@ -382,6 +436,7 @@ export interface LoaderOptions {
382
436
  server?: ServerNamespace;
383
437
  router?: Router;
384
438
  cache?: CacheRegistry;
439
+ scheduler?: Scheduler;
385
440
  attributes?: AttributeConfig;
386
441
  }
387
442
 
@@ -392,6 +447,7 @@ export interface LoaderInstance {
392
447
  server?: ServerNamespace;
393
448
  router?: Router;
394
449
  cache?: CacheRegistry;
450
+ scheduler: Scheduler;
395
451
  attributes: NormalizedAttributeConfig;
396
452
  start(): this;
397
453
  scan(rootOrFragment?: Document | Element | DocumentFragment): this;
@@ -403,6 +459,53 @@ export interface LoaderInstance {
403
459
  export type AsyncLoaderOptions = LoaderOptions;
404
460
  export type AsyncLoaderInstance = LoaderInstance;
405
461
 
462
+ export interface BoundaryPatch {
463
+ boundary: string;
464
+ seq: number;
465
+ html?: TemplateLike;
466
+ signals?: Record<string, unknown>;
467
+ cache?: { browser?: Record<string, unknown> };
468
+ redirect?: string;
469
+ error?: unknown;
470
+ parentScope?: string;
471
+ scope?: string;
472
+ meta?: Record<string, unknown>;
473
+ }
474
+
475
+ export type BoundaryApplyResult =
476
+ | { status: "applied"; boundary: string; seq: number }
477
+ | { status: "ignored-stale"; boundary: string; seq: number; lastSeq: number }
478
+ | { status: "ignored-destroyed"; boundary: string; seq: number; parentScope?: string }
479
+ | { status: "redirected"; boundary: string; seq: number; redirect: string }
480
+ | { status: "errored"; boundary: string; seq: number; error: Error };
481
+
482
+ export interface BoundaryReceiverInspection {
483
+ destroyed: boolean;
484
+ boundaries: Record<string, { lastSeq: number; applied: number; ignored: number; errored?: number; lastStatus?: BoundaryApplyResult["status"] }>;
485
+ recent: Array<{ boundary: string; seq: number; status: BoundaryApplyResult["status"]; lastSeq?: number; parentScope?: string; redirect?: string }>;
486
+ }
487
+
488
+ export interface BoundaryReceiverOptions {
489
+ loader: LoaderInstance;
490
+ signals?: SignalRegistry;
491
+ cache?: CacheRegistry;
492
+ scheduler?: Scheduler;
493
+ router?: Router;
494
+ onApply?(result: BoundaryApplyResult, patch: BoundaryPatch): void;
495
+ onIgnore?(result: BoundaryApplyResult, patch: BoundaryPatch): void;
496
+ onError?(error: Error, result: BoundaryApplyResult, patch: BoundaryPatch): void;
497
+ throwOnError?: boolean;
498
+ recentLimit?: number;
499
+ isScopeDestroyed?(scope: string): boolean;
500
+ }
501
+
502
+ export interface BoundaryReceiver {
503
+ apply(patch: BoundaryPatch): Promise<BoundaryApplyResult>;
504
+ inspect(): BoundaryReceiverInspection;
505
+ reset(boundary?: string): this;
506
+ destroy(): void;
507
+ }
508
+
406
509
  export interface RegistryStore {
407
510
  target: RuntimeTarget;
408
511
  register(type: RegistryType, id: string, value: unknown): string;
@@ -473,6 +576,8 @@ export interface CreateAppOptions extends LoaderOptions {
473
576
  routeEndpoint?: string;
474
577
  request?: Request;
475
578
  locals?: unknown;
579
+ requestContext?: RequestContextStore;
580
+ scheduler?: Scheduler;
476
581
  }
477
582
 
478
583
  export interface RenderResult {
@@ -495,6 +600,7 @@ export interface AppRuntime {
495
600
  browser: { cache: CacheRegistry };
496
601
  loader?: LoaderInstance;
497
602
  router?: Router;
603
+ scheduler: Scheduler;
498
604
  attributes: NormalizedAttributeConfig;
499
605
  start(): this;
500
606
  use(type: Parameters<AppHub["use"]>[0], entries?: unknown): this;
@@ -510,6 +616,7 @@ export interface AsyncNamespace extends AppHub {
510
616
  readSnapshot: typeof readSnapshot;
511
617
  attributeName: typeof attributeName;
512
618
  defineAttributeConfig: typeof defineAttributeConfig;
619
+ createBoundaryReceiver: typeof createBoundaryReceiver;
513
620
  createCacheRegistry: typeof createCacheRegistry;
514
621
  defineCache: typeof defineCache;
515
622
  component: typeof component;
@@ -524,10 +631,13 @@ export interface AsyncNamespace extends AppHub {
524
631
  createRegistryStore: typeof createRegistryStore;
525
632
  createRouteRegistry: typeof createRouteRegistry;
526
633
  createRouter: typeof createRouter;
634
+ createScheduler: typeof createScheduler;
527
635
  defineRoute: typeof defineRoute;
528
636
  route: typeof route;
637
+ applyServerResult: typeof applyServerResult;
529
638
  createServerProxy: typeof createServerProxy;
530
- createServerRegistry: typeof createServerRegistry;
639
+ resolveServerCommandArguments: typeof resolveServerCommandArguments;
640
+ unwrapServerResult: typeof unwrapServerResult;
531
641
  computed: typeof computed;
532
642
  createSignal: typeof createSignal;
533
643
  createSignalRegistry: typeof createSignalRegistry;
@@ -542,6 +652,7 @@ export declare function defineApp(initial?: AppDefinition): AppHub;
542
652
  export declare function readSnapshot(root?: Document | Element, options?: { attributes?: AttributeConfig }): { signals?: Record<string, unknown>; cache?: { browser?: Record<string, unknown> } };
543
653
  export declare function attributeName(attributes: AttributeConfig | undefined, type: keyof NormalizedAttributeConfig, name: string): string;
544
654
  export declare function defineAttributeConfig(config?: AttributeConfig): NormalizedAttributeConfig;
655
+ export declare function createBoundaryReceiver(options: BoundaryReceiverOptions): BoundaryReceiver;
545
656
  export declare function createCacheRegistry(initialMap?: Record<string, CacheDefinition | CacheDefinitionOptions>, options?: { now?: () => number; registry?: RegistryStore; type?: "cache.browser" | "cache.server" }): CacheRegistry;
546
657
  export declare function defineCache(options?: CacheDefinitionOptions): CacheDefinition;
547
658
  export declare function component<TProps extends Record<string, unknown> = Record<string, unknown>>(fn: ComponentFunction<TProps>): ComponentFunction<TProps>;
@@ -556,11 +667,14 @@ export declare function createPartialRegistry(initialMap?: Record<string, Partia
556
667
  export declare function createRegistryStore(initial?: AppDefinition, options?: { target?: RuntimeTarget; backing?: unknown }): RegistryStore;
557
668
  export declare function createRouteRegistry(initialMap?: Record<string, RouteDefinition | string>, options?: { registry?: RegistryStore; type?: "route" }): RouteRegistry;
558
669
  export declare function createRouter(options?: RouterOptions): Router;
670
+ export declare function createScheduler(options?: SchedulerOptions): Scheduler;
559
671
  export declare function defineRoute(partial: string, options?: Omit<RouteDefinition, "partial">): RouteDefinition;
560
672
  export declare const route: typeof defineRoute;
673
+ export declare function applyServerResult(result: unknown, context?: Record<string, unknown>): Promise<unknown>;
561
674
  export declare function createServerProxy(options?: ServerProxyOptions): ServerNamespace;
562
- export declare function createServerRegistry(initialMap?: Record<string, ServerFunction>, options?: { registry?: RegistryStore; type?: "server" }): ServerNamespace;
563
- export declare function computed<T = unknown>(fn: (this: { signals: SignalRegistry; id: string; server?: ServerNamespace; router?: Router; loader?: LoaderInstance; cache?: CacheRegistry }) => T): ComputedSignal<T>;
675
+ export declare function resolveServerCommandArguments(args: Array<{ type: "local"; name: string } | { type: "signal"; path: string }>, context?: Record<string, unknown>): { args: unknown[]; signalValues: Record<string, unknown>; signalPaths: string[] };
676
+ export declare function unwrapServerResult<T = unknown>(result: ServerResult<T>): T | ServerResult<T>;
677
+ export declare function computed<T = unknown>(fn: (this: { signals: SignalRegistry; id: string; server?: ServerNamespace; router?: Router; loader?: LoaderInstance; cache?: CacheRegistry; scheduler?: Scheduler }) => T): ComputedSignal<T>;
564
678
  export declare function createSignal<T = unknown>(initial: T): Signal<T>;
565
679
  export declare function createSignalRegistry(initialMap?: SignalMap, options?: { registry?: RegistryStore; type?: "signal" }): SignalRegistry;
566
680
  export declare function effect(fn: () => unknown): EffectDefinition;