@async/framework 0.8.0 → 0.10.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@async/framework",
3
- "version": "0.8.0",
3
+ "version": "0.10.0",
4
4
  "description": "No-build Loader app runtime with browser and server entrypoints, signals, command events, route partials, cache split, SSR activation, and streaming boundaries.",
5
5
  "type": "module",
6
6
  "packageManager": "pnpm@11.1.0",
package/server.d.ts CHANGED
@@ -13,6 +13,7 @@ export type RegistryType =
13
13
  | "partial"
14
14
  | "route"
15
15
  | "component"
16
+ | "asyncSignal"
16
17
  | "cache.browser"
17
18
  | "cache.server"
18
19
  | "cache.browser.entries"
@@ -34,6 +35,20 @@ export interface NormalizedAttributeConfig {
34
35
 
35
36
  export type TemplatePrimitive = string | number | boolean | null | undefined;
36
37
  export type TemplateLike = TemplateResult | TemplatePrimitive | Node | TemplateLike[];
38
+ export interface LazyDescriptor {
39
+ url: string;
40
+ [key: string]: unknown;
41
+ }
42
+ export interface RegistryAssetsConfig {
43
+ baseUrl?: string;
44
+ paths?: Partial<Record<"component" | "handler" | "asyncSignal" | "partial" | "route", string>>;
45
+ }
46
+ export interface LazyRegistry {
47
+ registryAssets: Required<Pick<RegistryAssetsConfig, "baseUrl">> & { paths: Record<string, string> };
48
+ resolveUrl(type: "component" | "handler" | "asyncSignal" | "partial" | "route", id: string, descriptor: LazyDescriptor): { moduleUrl: string; exportNames: string[]; url: string };
49
+ resolve<T = unknown>(type: "component" | "handler" | "asyncSignal" | "partial" | "route", id: string, descriptor: LazyDescriptor): Promise<T>;
50
+ inspect(): { registryAssets: unknown; modules: string[]; exports: string[] };
51
+ }
37
52
 
38
53
  export interface TemplateResult {
39
54
  readonly strings: TemplateStringsArray;
@@ -75,6 +90,7 @@ export interface Scheduler {
75
90
  afterFlush(job: () => MaybePromise<unknown>, options?: { scope?: unknown; boundary?: string; key?: string }): Cleanup;
76
91
  cancelScope(scope: unknown): this;
77
92
  markScopeDestroyed(scope: unknown): this;
93
+ isScopeDestroyed(scope: unknown): boolean;
78
94
  destroy(): void;
79
95
  inspect(): SchedulerInspection;
80
96
  }
@@ -208,8 +224,8 @@ export interface HandlerContext {
208
224
  export type HandlerFunction = (this: HandlerContext, context: HandlerContext) => MaybePromise<unknown>;
209
225
 
210
226
  export interface HandlerRegistry extends RegistryInspection<HandlerFunction> {
211
- register(id: string, fn: HandlerFunction): string;
212
- registerMany(map?: Record<string, HandlerFunction>): this;
227
+ register(id: string, fn: HandlerFunction | LazyDescriptor): string;
228
+ registerMany(map?: Record<string, HandlerFunction | LazyDescriptor>): this;
213
229
  unregister(id: string): boolean;
214
230
  resolve(id: string): HandlerFunction | undefined;
215
231
  run(ref: string, context?: Partial<HandlerContext>): Promise<unknown[]>;
@@ -321,8 +337,8 @@ export interface PartialContext {
321
337
  export type PartialFunction = (this: PartialContext, props: Record<string, unknown>) => MaybePromise<TemplateLike | ServerEnvelope>;
322
338
 
323
339
  export interface PartialRegistry extends RegistryInspection<PartialFunction> {
324
- register(id: string, fn: PartialFunction): string;
325
- registerMany(map?: Record<string, PartialFunction>): this;
340
+ register(id: string, fn: PartialFunction | LazyDescriptor): string;
341
+ registerMany(map?: Record<string, PartialFunction | LazyDescriptor>): this;
326
342
  unregister(id: string): boolean;
327
343
  resolve(id: string): PartialFunction | undefined;
328
344
  render(id: string, props?: Record<string, unknown>, context?: Partial<PartialContext>): Promise<ServerEnvelope>;
@@ -422,8 +438,8 @@ export interface SuspenseViews {
422
438
  }
423
439
 
424
440
  export interface ComponentRegistry extends RegistryInspection<ComponentFunction> {
425
- register(id: string, Component: ComponentFunction): string;
426
- registerMany(map?: Record<string, ComponentFunction>): this;
441
+ register(id: string, Component: ComponentFunction | LazyDescriptor): string;
442
+ registerMany(map?: Record<string, ComponentFunction | LazyDescriptor>): this;
427
443
  unregister(id: string): boolean;
428
444
  resolve(id: string): ComponentFunction | undefined;
429
445
  }
@@ -458,6 +474,53 @@ export interface LoaderInstance {
458
474
  export type AsyncLoaderOptions = LoaderOptions;
459
475
  export type AsyncLoaderInstance = LoaderInstance;
460
476
 
477
+ export interface BoundaryPatch {
478
+ boundary: string;
479
+ seq: number;
480
+ html?: TemplateLike;
481
+ signals?: Record<string, unknown>;
482
+ cache?: { browser?: Record<string, unknown> };
483
+ redirect?: string;
484
+ error?: unknown;
485
+ parentScope?: string;
486
+ scope?: string;
487
+ meta?: Record<string, unknown>;
488
+ }
489
+
490
+ export type BoundaryApplyResult =
491
+ | { status: "applied"; boundary: string; seq: number }
492
+ | { status: "ignored-stale"; boundary: string; seq: number; lastSeq: number }
493
+ | { status: "ignored-destroyed"; boundary: string; seq: number; parentScope?: string }
494
+ | { status: "redirected"; boundary: string; seq: number; redirect: string }
495
+ | { status: "errored"; boundary: string; seq: number; error: Error };
496
+
497
+ export interface BoundaryReceiverInspection {
498
+ destroyed: boolean;
499
+ boundaries: Record<string, { lastSeq: number; applied: number; ignored: number; errored?: number; lastStatus?: BoundaryApplyResult["status"] }>;
500
+ recent: Array<{ boundary: string; seq: number; status: BoundaryApplyResult["status"]; lastSeq?: number; parentScope?: string; redirect?: string }>;
501
+ }
502
+
503
+ export interface BoundaryReceiverOptions {
504
+ loader: LoaderInstance;
505
+ signals?: SignalRegistry;
506
+ cache?: CacheRegistry;
507
+ scheduler?: Scheduler;
508
+ router?: Router;
509
+ onApply?(result: BoundaryApplyResult, patch: BoundaryPatch): void;
510
+ onIgnore?(result: BoundaryApplyResult, patch: BoundaryPatch): void;
511
+ onError?(error: Error, result: BoundaryApplyResult, patch: BoundaryPatch): void;
512
+ throwOnError?: boolean;
513
+ recentLimit?: number;
514
+ isScopeDestroyed?(scope: string): boolean;
515
+ }
516
+
517
+ export interface BoundaryReceiver {
518
+ apply(patch: BoundaryPatch): Promise<BoundaryApplyResult>;
519
+ inspect(): BoundaryReceiverInspection;
520
+ reset(boundary?: string): this;
521
+ destroy(): void;
522
+ }
523
+
461
524
  export interface RegistryStore {
462
525
  target: RuntimeTarget;
463
526
  register(type: RegistryType, id: string, value: unknown): string;
@@ -476,22 +539,24 @@ export interface RegistryStore {
476
539
 
477
540
  export interface RegistrySnapshot {
478
541
  signal: Record<string, unknown>;
479
- handler: Record<string, { id: string; kind: "handler" }>;
480
- server: Record<string, { id: string; kind: "server" }>;
481
- partial: Record<string, { id: string; kind: "partial" }>;
542
+ handler: Record<string, { id?: string } | LazyDescriptor>;
543
+ server: Record<string, { id?: string } | LazyDescriptor>;
544
+ partial: Record<string, { id?: string } | LazyDescriptor>;
482
545
  route: Record<string, RouteDefinition>;
483
- component: Record<string, { id: string; kind: "component" }>;
546
+ component: Record<string, { id?: string } | LazyDescriptor>;
547
+ asyncSignal: Record<string, { id?: string } | LazyDescriptor>;
484
548
  cache: { browser: Record<string, CacheDefinition>; server: Record<string, CacheDefinition> };
485
549
  entries: { browser: Record<string, unknown>; server: Record<string, unknown> };
486
550
  }
487
551
 
488
552
  export interface AppDefinition {
489
553
  signal?: SignalMap;
490
- handler?: Record<string, HandlerFunction>;
554
+ handler?: Record<string, HandlerFunction | LazyDescriptor>;
491
555
  server?: Record<string, ServerFunction>;
492
- partial?: Record<string, PartialFunction>;
556
+ partial?: Record<string, PartialFunction | LazyDescriptor>;
493
557
  route?: Record<string, RouteDefinition | string>;
494
- component?: Record<string, ComponentFunction>;
558
+ component?: Record<string, ComponentFunction | LazyDescriptor>;
559
+ asyncSignal?: Record<string, AsyncSignalFunction | LazyDescriptor>;
495
560
  cache?: {
496
561
  browser?: Record<string, CacheDefinition | CacheDefinitionOptions>;
497
562
  server?: Record<string, CacheDefinition | CacheDefinitionOptions>;
@@ -499,25 +564,43 @@ export interface AppDefinition {
499
564
  entries?: { browser?: Record<string, unknown>; server?: Record<string, unknown> };
500
565
  }
501
566
 
567
+ export interface RegistryRuntimeSnapshot extends AppDefinition {
568
+ signals?: Record<string, unknown>;
569
+ }
570
+
571
+ export interface RootInspection {
572
+ count: number;
573
+ roots: Array<{ root: Document | Element | DocumentFragment; loader: LoaderInstance; primary: boolean }>;
574
+ }
575
+
502
576
  export interface AppHub {
503
577
  registry: RegistryStore;
504
578
  runtime?: AppRuntime;
505
579
  use(type: "signal", entries: SignalMap): this;
506
- use(type: "handler", entries: Record<string, HandlerFunction>): this;
580
+ use(type: "handler", entries: Record<string, HandlerFunction | LazyDescriptor>): this;
507
581
  use(type: "server", entries: Record<string, ServerFunction>): this;
508
- use(type: "partial", entries: Record<string, PartialFunction>): this;
582
+ use(type: "partial", entries: Record<string, PartialFunction | LazyDescriptor>): this;
509
583
  use(type: "route", entries: Record<string, RouteDefinition | string>): this;
510
- use(type: "component", entries: Record<string, ComponentFunction>): this;
584
+ use(type: "component", entries: Record<string, ComponentFunction | LazyDescriptor>): this;
585
+ use(type: "asyncSignal", entries: Record<string, AsyncSignalFunction | LazyDescriptor>): this;
511
586
  use(moduleObject: AppDefinition): this;
512
587
  snapshot(): AppDefinition;
513
588
  start(options?: CreateAppOptions): AppRuntime;
589
+ attachRoot(root: Document | Element | DocumentFragment): AppRuntime;
590
+ detachRoot(root?: Document | Element | DocumentFragment): this;
591
+ applySnapshot(snapshot: RegistryRuntimeSnapshot, options?: { strict?: boolean }): this;
592
+ inspectRoots(): RootInspection;
514
593
  }
515
594
 
516
595
  export interface CreateAppOptions extends LoaderOptions {
517
596
  target?: RuntimeTarget;
518
597
  mode?: RouterMode;
519
598
  boundary?: string;
520
- snapshot?: { signals?: Record<string, unknown>; cache?: { browser?: Record<string, unknown> } };
599
+ snapshot?: RegistryRuntimeSnapshot;
600
+ registryAssets?: RegistryAssetsConfig;
601
+ importModule?: (url: string) => MaybePromise<Record<string, unknown>>;
602
+ lazyRegistry?: LazyRegistry;
603
+ strictSnapshots?: boolean;
521
604
  registry?: RegistryStore;
522
605
  loader?: LoaderInstance;
523
606
  router?: Router | false;
@@ -556,6 +639,10 @@ export interface AppRuntime {
556
639
  attributes: NormalizedAttributeConfig;
557
640
  start(): this;
558
641
  use(type: Parameters<AppHub["use"]>[0], entries?: unknown): this;
642
+ attachRoot(root: Document | Element | DocumentFragment): this;
643
+ detachRoot(root?: Document | Element | DocumentFragment): this;
644
+ applySnapshot(snapshot: RegistryRuntimeSnapshot, options?: { strict?: boolean }): this;
645
+ inspectRoots(): RootInspection;
559
646
  render(url: string | URL): Promise<RenderResult>;
560
647
  destroy(): void;
561
648
  }
@@ -566,13 +653,22 @@ export interface AsyncNamespace extends AppHub {
566
653
  createApp: typeof createApp;
567
654
  defineApp: typeof defineApp;
568
655
  readSnapshot: typeof readSnapshot;
656
+ attachRoot: AppHub["attachRoot"];
657
+ detachRoot: AppHub["detachRoot"];
658
+ applySnapshot: AppHub["applySnapshot"];
659
+ inspectRoots: AppHub["inspectRoots"];
569
660
  attributeName: typeof attributeName;
570
661
  defineAttributeConfig: typeof defineAttributeConfig;
662
+ createBoundaryReceiver: typeof createBoundaryReceiver;
571
663
  createCacheRegistry: typeof createCacheRegistry;
572
664
  defineCache: typeof defineCache;
573
665
  component: typeof component;
574
666
  createComponentRegistry: typeof createComponentRegistry;
575
667
  defineComponent: typeof defineComponent;
668
+ defineAsyncContainerElement: typeof defineAsyncContainerElement;
669
+ defineAsyncSuspenseElement: typeof defineAsyncSuspenseElement;
670
+ defineRegistrySnapshot: typeof defineRegistrySnapshot;
671
+ createLazyRegistry: typeof createLazyRegistry;
576
672
  delay: typeof delay;
577
673
  createHandlerRegistry: typeof createHandlerRegistry;
578
674
  html: typeof html;
@@ -602,14 +698,19 @@ export declare function asyncSignal<T = unknown>(id: string, fn: AsyncSignalFunc
602
698
  export declare const Async: AppHub;
603
699
  export declare function createApp(appOrDefinition?: AppHub | AppDefinition, options?: CreateAppOptions): AppRuntime;
604
700
  export declare function defineApp(initial?: AppDefinition): AppHub;
605
- export declare function readSnapshot(root?: Document | Element, options?: { attributes?: AttributeConfig }): { signals?: Record<string, unknown>; cache?: { browser?: Record<string, unknown> } };
701
+ export declare function readSnapshot(root?: Document | Element, options?: { attributes?: AttributeConfig }): RegistryRuntimeSnapshot;
606
702
  export declare function attributeName(attributes: AttributeConfig | undefined, type: keyof NormalizedAttributeConfig, name: string): string;
607
703
  export declare function defineAttributeConfig(config?: AttributeConfig): NormalizedAttributeConfig;
704
+ export declare function createBoundaryReceiver(options: BoundaryReceiverOptions): BoundaryReceiver;
608
705
  export declare function createCacheRegistry(initialMap?: Record<string, CacheDefinition | CacheDefinitionOptions>, options?: { now?: () => number; registry?: RegistryStore; type?: "cache.browser" | "cache.server" }): CacheRegistry;
609
706
  export declare function defineCache(options?: CacheDefinitionOptions): CacheDefinition;
610
707
  export declare function component<TProps extends Record<string, unknown> = Record<string, unknown>>(fn: ComponentFunction<TProps>): ComponentFunction<TProps>;
611
708
  export declare function createComponentRegistry(initialMap?: Record<string, ComponentFunction>, options?: { registry?: RegistryStore; type?: "component" }): ComponentRegistry;
612
709
  export declare function defineComponent<TProps extends Record<string, unknown> = Record<string, unknown>>(fn: ComponentFunction<TProps>): ComponentFunction<TProps>;
710
+ export declare function defineAsyncContainerElement(options?: { tagName?: string; app?: AppHub; Async?: AppHub; customElements?: CustomElementRegistry; HTMLElement?: typeof HTMLElement; window?: Window }): CustomElementConstructor;
711
+ export declare function defineAsyncSuspenseElement(options?: { tagName?: string; customElements?: CustomElementRegistry; HTMLElement?: typeof HTMLElement; window?: Window }): CustomElementConstructor;
712
+ export declare function defineRegistrySnapshot<T extends RegistryRuntimeSnapshot>(snapshot?: T): T;
713
+ export declare function createLazyRegistry(options?: { registryAssets?: RegistryAssetsConfig; assets?: RegistryAssetsConfig; importModule?: (url: string) => MaybePromise<Record<string, unknown>> }): LazyRegistry;
613
714
  export declare function delay(ms: number, signal?: AbortSignal): Promise<void>;
614
715
  export declare function createHandlerRegistry(initialMap?: Record<string, HandlerFunction>, options?: { registry?: RegistryStore; type?: "handler" }): HandlerRegistry;
615
716
  export declare function html(strings: TemplateStringsArray, ...values: unknown[]): TemplateResult;