@moku-labs/web 2.2.2 → 2.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -278,7 +278,7 @@ interface PathMatcher {
278
278
  };
279
279
  } | null;
280
280
  }
281
- declare namespace types_d_exports$6 {
281
+ declare namespace types_d_exports$7 {
282
282
  export { Api$5 as Api, ClientRoute, CompileInput, CompiledRoute, Config$5 as Config, ExtractApi$2 as ExtractApi, ExtractRouteParams, ExtractSegmentParameter, GenerateContext, HeadConfig$1 as HeadConfig, LayoutContext, LoadContext, MatcherTable, Prettify, RouteBuilder, RouteContext, RouteDefinition, RouteHandlers, RouteMap, RouteRequire, RouteState, RouterApi, RouterConfig, RouterState, ScrollMode, State$5 as State, TransitionMode, TypedRoute, Urls };
283
283
  }
284
284
  /**
@@ -739,7 +739,7 @@ type Config$5 = RouterConfig;
739
739
  type State$5 = RouterState;
740
740
  /** Re-export under the canonical `Api` name for the plugin-types barrel. */
741
741
  type Api$5 = RouterApi;
742
- declare namespace types_d_exports$5 {
742
+ declare namespace types_d_exports$6 {
743
743
  export { Api$4 as Api, ArticleMeta, Config$4 as Config, HeadConfig, HeadDefaults, HeadElement, ResolvedRoute, State$4 as State };
744
744
  }
745
745
  /**
@@ -914,7 +914,7 @@ type Api$4 = {
914
914
  */
915
915
  composeTitle(head: HeadConfig | undefined): string;
916
916
  };
917
- declare namespace types_d_exports$7 {
917
+ declare namespace types_d_exports$8 {
918
918
  export { AnyVNode, ExtractApi$1 as ExtractApi, ISLAND_HOOK_NAMES, IslandContext, IslandDef, IslandEventHandler, IslandEvents, IslandHooks, IslandInstance, IslandRender, IslandRouteSlice, IslandSpec, IslandSpecExtras, IslandStateFactory, NavigateOptions, PageData, RenderResult, ResolvedSpaConfig, ScrollMode, SpaApi, SpaConfig, SpaContext, SpaDataReader, SpaEmitFunction, SpaEvents, SpaKernel, SpaKernelDeps, SpaRequire, SpaState, TransitionMode };
919
919
  }
920
920
  /** Per-navigation options for the programmatic navigators (`ctx.navigate` / `app.spa.navigate`). */
@@ -1956,7 +1956,7 @@ declare const buildPlugin: import("@moku-labs/core").PluginInstance<"build", Con
1956
1956
  * const trigger: WorkflowTrigger = "versioned-tag";
1957
1957
  */
1958
1958
  type WorkflowTrigger = "auto" | "versioned-tag" | "dispatch";
1959
- declare namespace types_d_exports$4 {
1959
+ declare namespace types_d_exports$5 {
1960
1960
  export { Api$2 as Api, Config$2 as Config, CreateProjectResult, DeployErrorCode, DeployInitOptions, DeployResult, DeployRunOptions, InitResult, SpawnFunction, SpawnOptions, SpawnedProcess, State$2 as State, WorkflowTrigger, WranglerErrorKind };
1961
1961
  }
1962
1962
  /**
@@ -2736,6 +2736,159 @@ type Api$1 = {
2736
2736
  */
2737
2737
  declare const cliPlugin: import("@moku-labs/core").PluginInstance<"cli", Config$1, State$1, Api$1, {}> & Record<never, never>;
2738
2738
  declare namespace types_d_exports$2 {
2739
+ export { CollectionConfig, CollectionProvider, CollectionShard, CollectionState, CollectionWriteSummary };
2740
+ }
2741
+ /**
2742
+ * @file collection plugin — type definitions (Standard tier).
2743
+ *
2744
+ * The `collection` plugin is the **static-data collection provider** — the
2745
+ * collection-keyed sibling of the page-path-keyed `data` plugin. It owns ONE
2746
+ * thing: the contract `(collection, shard) → persisted JSON file`. It knows
2747
+ * NOTHING about what the data *is* — no domain types appear here. A consumer
2748
+ * decides its own shard shape (`at`'s `T`).
2749
+ *
2750
+ * - **Node (build):** `write(entries)` persists one JSON file per shard, keyed by
2751
+ * `(collection, shard)` via {@link CollectionProvider.fileFor}. The build
2752
+ * supplies the entries (it already authored the shards), so there is no
2753
+ * expansion here.
2754
+ * - **Browser (runtime):** `at(collection, shard)` fetches + caches that file as
2755
+ * `unknown`, which the consumer reads on demand.
2756
+ *
2757
+ * The Node-only file-writing code (`node:fs`) is isolated behind a lazy `import()`
2758
+ * inside `write()`, so composing `collection` in a browser app keeps the bundle
2759
+ * free of `node:*`.
2760
+ */
2761
+ /**
2762
+ * Configuration for {@link collectionPlugin}. All fields have defaults (see
2763
+ * `./config`).
2764
+ *
2765
+ * @example
2766
+ * ```ts
2767
+ * const cfg: CollectionConfig = { baseUrl: "/" };
2768
+ * ```
2769
+ */
2770
+ type CollectionConfig = {
2771
+ /**
2772
+ * READ side (browser): site-root URL prefix the client fetches the per-shard
2773
+ * JSON from. The collection name is the top directory under it, so the fetched
2774
+ * URL is `baseUrl + collection + "/" + shard + ".json"`. Default `"/"`.
2775
+ */
2776
+ baseUrl: string;
2777
+ };
2778
+ /** One build-authored shard to persist — the build produces these. */
2779
+ interface CollectionShard {
2780
+ /** The collection name — the top directory (e.g. `"bank"`). */
2781
+ collection: string;
2782
+ /**
2783
+ * The shard key WITHIN the collection (e.g. `"en/animals"`); may contain `/`,
2784
+ * which is preserved as a nested path. Maps to a file via
2785
+ * {@link CollectionProvider.fileFor}.
2786
+ */
2787
+ shard: string;
2788
+ /** The serializable data for this shard. */
2789
+ data: unknown;
2790
+ }
2791
+ /** Summary returned by {@link CollectionProvider.write} and cached in state. */
2792
+ interface CollectionWriteSummary {
2793
+ /** Number of per-shard JSON files written. */
2794
+ fileCount: number;
2795
+ /** Total bytes written across all files. */
2796
+ bytes: number;
2797
+ /** The written file paths, relative to the build `outDir`. */
2798
+ files: string[];
2799
+ }
2800
+ /**
2801
+ * Internal collection state. `lastWrite` records the most recent `write()` (Node);
2802
+ * `cache` memoizes fetched per-`(collection, shard)` data (browser, lazy). Both
2803
+ * empty until their respective side first runs.
2804
+ */
2805
+ interface CollectionState {
2806
+ /** Result of the last `write()`, or `null` if it has not run yet (Node). */
2807
+ lastWrite: CollectionWriteSummary | null;
2808
+ /** Per-`(collection, shard)` fetched data, cached after the first `at()` (browser). */
2809
+ cache: Map<string, unknown>;
2810
+ }
2811
+ /**
2812
+ * Public API mounted at `app.collection` — the static-data collection provider.
2813
+ * `write()` is the Node persist side; `at()` is the browser read side;
2814
+ * `urlFor`/`fileFor` are the pure URL convention shared by both so the written
2815
+ * file and fetched URL can never drift.
2816
+ *
2817
+ * @example
2818
+ * ```ts
2819
+ * // Node build (build supplies the shards it already authored):
2820
+ * await app.collection.write([{ collection: "bank", shard: "en/animals", data }]);
2821
+ *
2822
+ * // Browser: fetch a shard on demand, read by the consumer:
2823
+ * const raw = await app.collection.at("bank", "en/animals"); // unknown | null (null on failure)
2824
+ * ```
2825
+ */
2826
+ type CollectionProvider = {
2827
+ /**
2828
+ * READ (browser) — fetch (and cache) the persisted data for a `(collection,
2829
+ * shard)` key from `config.baseUrl`. Returns the raw parsed JSON as `unknown`;
2830
+ * returns `null` if the fetch or JSON parse fails.
2831
+ *
2832
+ * @param collection - The collection name (e.g. `"bank"`).
2833
+ * @param shard - The shard key within the collection (e.g. `"en/animals"`).
2834
+ * @returns The shard's raw data, or `null` on failure.
2835
+ */
2836
+ at(collection: string, shard: string): Promise<unknown | null>;
2837
+ /**
2838
+ * WRITE (Node) — persist one JSON file per entry, keyed by `(collection, shard)`
2839
+ * via {@link CollectionProvider.fileFor}. Called by the build after it authors
2840
+ * the shards. Lazily loads its `node:fs` writer, so it never contaminates a
2841
+ * browser bundle.
2842
+ *
2843
+ * @param entries - The per-shard data to persist.
2844
+ * @param options - Optional overrides.
2845
+ * @param options.outDir - Build output directory to write under (default `./dist`).
2846
+ * @returns A summary of the written files.
2847
+ */
2848
+ write(entries: readonly CollectionShard[], options?: {
2849
+ outDir?: string;
2850
+ }): Promise<CollectionWriteSummary>;
2851
+ /**
2852
+ * PURE — the browser fetch URL for a `(collection, shard)` key (e.g.
2853
+ * `("bank", "en/animals")` → `/bank/en/animals.json`). Shared with
2854
+ * {@link CollectionProvider.fileFor}.
2855
+ *
2856
+ * @param collection - The collection name.
2857
+ * @param shard - The shard key within the collection.
2858
+ * @returns The site-root-relative shard URL.
2859
+ */
2860
+ urlFor(collection: string, shard: string): string;
2861
+ /**
2862
+ * PURE — the `outDir`-relative file path for a `(collection, shard)` key (e.g.
2863
+ * `("bank", "en/animals")` → `bank/en/animals.json`). Shared with
2864
+ * {@link CollectionProvider.urlFor}.
2865
+ *
2866
+ * @param collection - The collection name.
2867
+ * @param shard - The shard key within the collection.
2868
+ * @returns The output-relative file path.
2869
+ */
2870
+ fileFor(collection: string, shard: string): string;
2871
+ };
2872
+ //#endregion
2873
+ //#region src/plugins/collection/index.d.ts
2874
+ /**
2875
+ * Collection plugin — the static-data collection provider. Mounts
2876
+ * `write(entries)` (Node persist), `at(collection, shard)` (browser read), and the
2877
+ * pure `urlFor`/`fileFor` convention at `app.collection`.
2878
+ *
2879
+ * @example
2880
+ * ```ts
2881
+ * // Node build: write build-authored shards during/after the build's pages phase.
2882
+ * const app = createApp({ plugins: [collectionPlugin, buildPlugin] });
2883
+ * await app.build.run();
2884
+ * await app.collection.write([{ collection: "bank", shard: "en/animals", data }]);
2885
+ *
2886
+ * // Browser app: compose `collectionPlugin` too; fetch a shard on demand.
2887
+ * const raw = await app.collection.at("bank", "en/animals"); // unknown | null
2888
+ * ```
2889
+ */
2890
+ declare const collectionPlugin: import("@moku-labs/core").PluginInstance<"collection", CollectionConfig, CollectionState, CollectionProvider, {}> & Record<never, never>;
2891
+ declare namespace types_d_exports$3 {
2739
2892
  export { Api, Article, ArticleCard, ComputedFields, Config, ContentApiContext, ContentEvents, ContentProvider, ContentProviderState, EmbedFacade, EmbedFacadeProps, EmbedOptions, FileSystemContentOptions, Frontmatter, GalleryComponent, GalleryOptions, GalleryProps, GallerySlide, GalleryTransformOptions, LoadAllOptions, MermaidDiagramOptions, State };
2740
2893
  }
2741
2894
  /**
@@ -3234,7 +3387,7 @@ declare const contentPlugin: import("@moku-labs/core").PluginInstance<"content",
3234
3387
  paths: readonly string[];
3235
3388
  };
3236
3389
  }> & Record<never, never>;
3237
- declare namespace types_d_exports$3 {
3390
+ declare namespace types_d_exports$4 {
3238
3391
  export { DataConfig, DataEntry, DataProvider, DataState, DataWriteSummary };
3239
3392
  }
3240
3393
  /**
@@ -3900,6 +4053,42 @@ declare function EmbedFacadeButton(props: EmbedFacadeProps): VNode;
3900
4053
  */
3901
4054
  declare function GalleryTrack(props: GalleryProps): VNode;
3902
4055
  //#endregion
4056
+ //#region src/plugins/collection/convention.d.ts
4057
+ /**
4058
+ * Compute the browser fetch URL for a `(collection, shard)` key: the `baseUrl`
4059
+ * prefix joined with the {@link shardSuffix}. Exported so standalone consumers can
4060
+ * derive the same URL without composing the plugin.
4061
+ *
4062
+ * @param baseUrl - The site-root URL prefix (ends with `/`, e.g. `"/"`).
4063
+ * @param collection - The collection name (e.g. `"bank"`).
4064
+ * @param shard - The shard key within the collection (e.g. `"en/animals"`).
4065
+ * @returns The site-root-relative shard URL (e.g. `/bank/en/animals.json`).
4066
+ * @example
4067
+ * ```ts
4068
+ * collectionUrl("/", "bank", "en/animals"); // "/bank/en/animals.json"
4069
+ * ```
4070
+ */
4071
+ declare function collectionUrl(baseUrl: string, collection: string, shard: string): string;
4072
+ //#endregion
4073
+ //#region src/plugins/collection/read.d.ts
4074
+ /**
4075
+ * Fetch + parse a build-authored collection shard over HTTP. Builds the shard URL
4076
+ * via {@link collectionUrl}, fetches it, and throws on a non-OK response so the
4077
+ * caller (`collection.at`) can decide whether to fall back.
4078
+ *
4079
+ * @template T - The expected shape of the parsed shard JSON.
4080
+ * @param baseUrl - The site-root URL prefix (ends with `/`, e.g. `"/"`).
4081
+ * @param collection - The collection name (e.g. `"bank"`).
4082
+ * @param shard - The shard key within the collection (e.g. `"en/animals"`).
4083
+ * @returns The parsed shard JSON, typed as `T`.
4084
+ * @throws {Error} If the fetch is not OK.
4085
+ * @example
4086
+ * ```ts
4087
+ * const animals = await loadCollectionShard<Animal[]>("/", "bank", "en/animals");
4088
+ * ```
4089
+ */
4090
+ declare function loadCollectionShard<T>(baseUrl: string, collection: string, shard: string): Promise<T>;
4091
+ //#endregion
3903
4092
  //#region src/index.d.ts
3904
4093
  /**
3905
4094
  * Create and initialize a `@moku-labs/web` application — the Layer-3 entry point.
@@ -4006,4 +4195,4 @@ declare const createApp: <const ExtraPlugins extends readonly import("@moku-labs
4006
4195
  */
4007
4196
  declare const createPlugin: import("@moku-labs/core").BoundCreatePluginFunction<Config$8, Events, import("@moku-labs/core").CoreApisFromTuple<[import("@moku-labs/core").CorePluginInstance<"log", import("@moku-labs/common").LogConfig, import("@moku-labs/common").LogState, import("@moku-labs/common").LogApi>, import("@moku-labs/core").CorePluginInstance<"env", import("@moku-labs/common").EnvConfig, import("@moku-labs/common").EnvState, import("@moku-labs/common").EnvApi>]>>;
4008
4197
  //#endregion
4009
- export { types_d_exports as Build, type Channel, type ChannelKeepAlive, type ChannelOptions, type ChannelReconnect, types_d_exports$1 as Cli, types_d_exports$2 as Content, types_d_exports$3 as Data, types_d_exports$4 as Deploy, type EmbedFacade, EmbedFacadeButton, type EmbedFacadeProps, type EmbedOptions, type Env, type GalleryComponent, type GalleryOptions, type GalleryProps, type GallerySlide, GalleryTrack, types_d_exports$5 as Head, type Log, types_d_exports$6 as Router, types_d_exports$7 as Spa, browserEnv, buildArticleHead, buildPlugin, canonical, cliPlugin, cloudflareBindings, contentPlugin, createApp, createChannel, createIsland, createPlugin, createUrls, dataPlugin, defineRoutes, deployPlugin, dotenv, envPlugin, feedLink, fileSystemContent, hardNavigate, headPlugin, hreflang, i18nPlugin, jsonLd, lazyEmbed, logPlugin, meta, navigate, og, processEnv, route, routerPlugin, sitePlugin, spaPlugin, twitter };
4198
+ export { types_d_exports as Build, type Channel, type ChannelKeepAlive, type ChannelOptions, type ChannelReconnect, types_d_exports$1 as Cli, types_d_exports$2 as Collection, types_d_exports$3 as Content, types_d_exports$4 as Data, types_d_exports$5 as Deploy, type EmbedFacade, EmbedFacadeButton, type EmbedFacadeProps, type EmbedOptions, type Env, type GalleryComponent, type GalleryOptions, type GalleryProps, type GallerySlide, GalleryTrack, types_d_exports$6 as Head, type Log, types_d_exports$7 as Router, types_d_exports$8 as Spa, browserEnv, buildArticleHead, buildPlugin, canonical, cliPlugin, cloudflareBindings, collectionPlugin, collectionUrl, contentPlugin, createApp, createChannel, createIsland, createPlugin, createUrls, dataPlugin, defineRoutes, deployPlugin, dotenv, envPlugin, feedLink, fileSystemContent, hardNavigate, headPlugin, hreflang, i18nPlugin, jsonLd, lazyEmbed, loadCollectionShard, logPlugin, meta, navigate, og, processEnv, route, routerPlugin, sitePlugin, spaPlugin, twitter };
package/dist/index.d.mts CHANGED
@@ -276,7 +276,7 @@ interface PathMatcher {
276
276
  };
277
277
  } | null;
278
278
  }
279
- declare namespace types_d_exports$6 {
279
+ declare namespace types_d_exports$7 {
280
280
  export { Api$5 as Api, ClientRoute, CompileInput, CompiledRoute, Config$5 as Config, ExtractApi$2 as ExtractApi, ExtractRouteParams, ExtractSegmentParameter, GenerateContext, HeadConfig$1 as HeadConfig, LayoutContext, LoadContext, MatcherTable, Prettify, RouteBuilder, RouteContext, RouteDefinition, RouteHandlers, RouteMap, RouteRequire, RouteState, RouterApi, RouterConfig, RouterState, ScrollMode, State$5 as State, TransitionMode, TypedRoute, Urls };
281
281
  }
282
282
  /**
@@ -737,7 +737,7 @@ type Config$5 = RouterConfig;
737
737
  type State$5 = RouterState;
738
738
  /** Re-export under the canonical `Api` name for the plugin-types barrel. */
739
739
  type Api$5 = RouterApi;
740
- declare namespace types_d_exports$5 {
740
+ declare namespace types_d_exports$6 {
741
741
  export { Api$4 as Api, ArticleMeta, Config$4 as Config, HeadConfig, HeadDefaults, HeadElement, ResolvedRoute, State$4 as State };
742
742
  }
743
743
  /**
@@ -912,7 +912,7 @@ type Api$4 = {
912
912
  */
913
913
  composeTitle(head: HeadConfig | undefined): string;
914
914
  };
915
- declare namespace types_d_exports$7 {
915
+ declare namespace types_d_exports$8 {
916
916
  export { AnyVNode, ExtractApi$1 as ExtractApi, ISLAND_HOOK_NAMES, IslandContext, IslandDef, IslandEventHandler, IslandEvents, IslandHooks, IslandInstance, IslandRender, IslandRouteSlice, IslandSpec, IslandSpecExtras, IslandStateFactory, NavigateOptions, PageData, RenderResult, ResolvedSpaConfig, ScrollMode, SpaApi, SpaConfig, SpaContext, SpaDataReader, SpaEmitFunction, SpaEvents, SpaKernel, SpaKernelDeps, SpaRequire, SpaState, TransitionMode };
917
917
  }
918
918
  /** Per-navigation options for the programmatic navigators (`ctx.navigate` / `app.spa.navigate`). */
@@ -1954,7 +1954,7 @@ declare const buildPlugin: import("@moku-labs/core").PluginInstance<"build", Con
1954
1954
  * const trigger: WorkflowTrigger = "versioned-tag";
1955
1955
  */
1956
1956
  type WorkflowTrigger = "auto" | "versioned-tag" | "dispatch";
1957
- declare namespace types_d_exports$4 {
1957
+ declare namespace types_d_exports$5 {
1958
1958
  export { Api$2 as Api, Config$2 as Config, CreateProjectResult, DeployErrorCode, DeployInitOptions, DeployResult, DeployRunOptions, InitResult, SpawnFunction, SpawnOptions, SpawnedProcess, State$2 as State, WorkflowTrigger, WranglerErrorKind };
1959
1959
  }
1960
1960
  /**
@@ -2734,6 +2734,159 @@ type Api$1 = {
2734
2734
  */
2735
2735
  declare const cliPlugin: import("@moku-labs/core").PluginInstance<"cli", Config$1, State$1, Api$1, {}> & Record<never, never>;
2736
2736
  declare namespace types_d_exports$2 {
2737
+ export { CollectionConfig, CollectionProvider, CollectionShard, CollectionState, CollectionWriteSummary };
2738
+ }
2739
+ /**
2740
+ * @file collection plugin — type definitions (Standard tier).
2741
+ *
2742
+ * The `collection` plugin is the **static-data collection provider** — the
2743
+ * collection-keyed sibling of the page-path-keyed `data` plugin. It owns ONE
2744
+ * thing: the contract `(collection, shard) → persisted JSON file`. It knows
2745
+ * NOTHING about what the data *is* — no domain types appear here. A consumer
2746
+ * decides its own shard shape (`at`'s `T`).
2747
+ *
2748
+ * - **Node (build):** `write(entries)` persists one JSON file per shard, keyed by
2749
+ * `(collection, shard)` via {@link CollectionProvider.fileFor}. The build
2750
+ * supplies the entries (it already authored the shards), so there is no
2751
+ * expansion here.
2752
+ * - **Browser (runtime):** `at(collection, shard)` fetches + caches that file as
2753
+ * `unknown`, which the consumer reads on demand.
2754
+ *
2755
+ * The Node-only file-writing code (`node:fs`) is isolated behind a lazy `import()`
2756
+ * inside `write()`, so composing `collection` in a browser app keeps the bundle
2757
+ * free of `node:*`.
2758
+ */
2759
+ /**
2760
+ * Configuration for {@link collectionPlugin}. All fields have defaults (see
2761
+ * `./config`).
2762
+ *
2763
+ * @example
2764
+ * ```ts
2765
+ * const cfg: CollectionConfig = { baseUrl: "/" };
2766
+ * ```
2767
+ */
2768
+ type CollectionConfig = {
2769
+ /**
2770
+ * READ side (browser): site-root URL prefix the client fetches the per-shard
2771
+ * JSON from. The collection name is the top directory under it, so the fetched
2772
+ * URL is `baseUrl + collection + "/" + shard + ".json"`. Default `"/"`.
2773
+ */
2774
+ baseUrl: string;
2775
+ };
2776
+ /** One build-authored shard to persist — the build produces these. */
2777
+ interface CollectionShard {
2778
+ /** The collection name — the top directory (e.g. `"bank"`). */
2779
+ collection: string;
2780
+ /**
2781
+ * The shard key WITHIN the collection (e.g. `"en/animals"`); may contain `/`,
2782
+ * which is preserved as a nested path. Maps to a file via
2783
+ * {@link CollectionProvider.fileFor}.
2784
+ */
2785
+ shard: string;
2786
+ /** The serializable data for this shard. */
2787
+ data: unknown;
2788
+ }
2789
+ /** Summary returned by {@link CollectionProvider.write} and cached in state. */
2790
+ interface CollectionWriteSummary {
2791
+ /** Number of per-shard JSON files written. */
2792
+ fileCount: number;
2793
+ /** Total bytes written across all files. */
2794
+ bytes: number;
2795
+ /** The written file paths, relative to the build `outDir`. */
2796
+ files: string[];
2797
+ }
2798
+ /**
2799
+ * Internal collection state. `lastWrite` records the most recent `write()` (Node);
2800
+ * `cache` memoizes fetched per-`(collection, shard)` data (browser, lazy). Both
2801
+ * empty until their respective side first runs.
2802
+ */
2803
+ interface CollectionState {
2804
+ /** Result of the last `write()`, or `null` if it has not run yet (Node). */
2805
+ lastWrite: CollectionWriteSummary | null;
2806
+ /** Per-`(collection, shard)` fetched data, cached after the first `at()` (browser). */
2807
+ cache: Map<string, unknown>;
2808
+ }
2809
+ /**
2810
+ * Public API mounted at `app.collection` — the static-data collection provider.
2811
+ * `write()` is the Node persist side; `at()` is the browser read side;
2812
+ * `urlFor`/`fileFor` are the pure URL convention shared by both so the written
2813
+ * file and fetched URL can never drift.
2814
+ *
2815
+ * @example
2816
+ * ```ts
2817
+ * // Node build (build supplies the shards it already authored):
2818
+ * await app.collection.write([{ collection: "bank", shard: "en/animals", data }]);
2819
+ *
2820
+ * // Browser: fetch a shard on demand, read by the consumer:
2821
+ * const raw = await app.collection.at("bank", "en/animals"); // unknown | null (null on failure)
2822
+ * ```
2823
+ */
2824
+ type CollectionProvider = {
2825
+ /**
2826
+ * READ (browser) — fetch (and cache) the persisted data for a `(collection,
2827
+ * shard)` key from `config.baseUrl`. Returns the raw parsed JSON as `unknown`;
2828
+ * returns `null` if the fetch or JSON parse fails.
2829
+ *
2830
+ * @param collection - The collection name (e.g. `"bank"`).
2831
+ * @param shard - The shard key within the collection (e.g. `"en/animals"`).
2832
+ * @returns The shard's raw data, or `null` on failure.
2833
+ */
2834
+ at(collection: string, shard: string): Promise<unknown | null>;
2835
+ /**
2836
+ * WRITE (Node) — persist one JSON file per entry, keyed by `(collection, shard)`
2837
+ * via {@link CollectionProvider.fileFor}. Called by the build after it authors
2838
+ * the shards. Lazily loads its `node:fs` writer, so it never contaminates a
2839
+ * browser bundle.
2840
+ *
2841
+ * @param entries - The per-shard data to persist.
2842
+ * @param options - Optional overrides.
2843
+ * @param options.outDir - Build output directory to write under (default `./dist`).
2844
+ * @returns A summary of the written files.
2845
+ */
2846
+ write(entries: readonly CollectionShard[], options?: {
2847
+ outDir?: string;
2848
+ }): Promise<CollectionWriteSummary>;
2849
+ /**
2850
+ * PURE — the browser fetch URL for a `(collection, shard)` key (e.g.
2851
+ * `("bank", "en/animals")` → `/bank/en/animals.json`). Shared with
2852
+ * {@link CollectionProvider.fileFor}.
2853
+ *
2854
+ * @param collection - The collection name.
2855
+ * @param shard - The shard key within the collection.
2856
+ * @returns The site-root-relative shard URL.
2857
+ */
2858
+ urlFor(collection: string, shard: string): string;
2859
+ /**
2860
+ * PURE — the `outDir`-relative file path for a `(collection, shard)` key (e.g.
2861
+ * `("bank", "en/animals")` → `bank/en/animals.json`). Shared with
2862
+ * {@link CollectionProvider.urlFor}.
2863
+ *
2864
+ * @param collection - The collection name.
2865
+ * @param shard - The shard key within the collection.
2866
+ * @returns The output-relative file path.
2867
+ */
2868
+ fileFor(collection: string, shard: string): string;
2869
+ };
2870
+ //#endregion
2871
+ //#region src/plugins/collection/index.d.ts
2872
+ /**
2873
+ * Collection plugin — the static-data collection provider. Mounts
2874
+ * `write(entries)` (Node persist), `at(collection, shard)` (browser read), and the
2875
+ * pure `urlFor`/`fileFor` convention at `app.collection`.
2876
+ *
2877
+ * @example
2878
+ * ```ts
2879
+ * // Node build: write build-authored shards during/after the build's pages phase.
2880
+ * const app = createApp({ plugins: [collectionPlugin, buildPlugin] });
2881
+ * await app.build.run();
2882
+ * await app.collection.write([{ collection: "bank", shard: "en/animals", data }]);
2883
+ *
2884
+ * // Browser app: compose `collectionPlugin` too; fetch a shard on demand.
2885
+ * const raw = await app.collection.at("bank", "en/animals"); // unknown | null
2886
+ * ```
2887
+ */
2888
+ declare const collectionPlugin: import("@moku-labs/core").PluginInstance<"collection", CollectionConfig, CollectionState, CollectionProvider, {}> & Record<never, never>;
2889
+ declare namespace types_d_exports$3 {
2737
2890
  export { Api, Article, ArticleCard, ComputedFields, Config, ContentApiContext, ContentEvents, ContentProvider, ContentProviderState, EmbedFacade, EmbedFacadeProps, EmbedOptions, FileSystemContentOptions, Frontmatter, GalleryComponent, GalleryOptions, GalleryProps, GallerySlide, GalleryTransformOptions, LoadAllOptions, MermaidDiagramOptions, State };
2738
2891
  }
2739
2892
  /**
@@ -3232,7 +3385,7 @@ declare const contentPlugin: import("@moku-labs/core").PluginInstance<"content",
3232
3385
  paths: readonly string[];
3233
3386
  };
3234
3387
  }> & Record<never, never>;
3235
- declare namespace types_d_exports$3 {
3388
+ declare namespace types_d_exports$4 {
3236
3389
  export { DataConfig, DataEntry, DataProvider, DataState, DataWriteSummary };
3237
3390
  }
3238
3391
  /**
@@ -3898,6 +4051,42 @@ declare function EmbedFacadeButton(props: EmbedFacadeProps): VNode;
3898
4051
  */
3899
4052
  declare function GalleryTrack(props: GalleryProps): VNode;
3900
4053
  //#endregion
4054
+ //#region src/plugins/collection/convention.d.ts
4055
+ /**
4056
+ * Compute the browser fetch URL for a `(collection, shard)` key: the `baseUrl`
4057
+ * prefix joined with the {@link shardSuffix}. Exported so standalone consumers can
4058
+ * derive the same URL without composing the plugin.
4059
+ *
4060
+ * @param baseUrl - The site-root URL prefix (ends with `/`, e.g. `"/"`).
4061
+ * @param collection - The collection name (e.g. `"bank"`).
4062
+ * @param shard - The shard key within the collection (e.g. `"en/animals"`).
4063
+ * @returns The site-root-relative shard URL (e.g. `/bank/en/animals.json`).
4064
+ * @example
4065
+ * ```ts
4066
+ * collectionUrl("/", "bank", "en/animals"); // "/bank/en/animals.json"
4067
+ * ```
4068
+ */
4069
+ declare function collectionUrl(baseUrl: string, collection: string, shard: string): string;
4070
+ //#endregion
4071
+ //#region src/plugins/collection/read.d.ts
4072
+ /**
4073
+ * Fetch + parse a build-authored collection shard over HTTP. Builds the shard URL
4074
+ * via {@link collectionUrl}, fetches it, and throws on a non-OK response so the
4075
+ * caller (`collection.at`) can decide whether to fall back.
4076
+ *
4077
+ * @template T - The expected shape of the parsed shard JSON.
4078
+ * @param baseUrl - The site-root URL prefix (ends with `/`, e.g. `"/"`).
4079
+ * @param collection - The collection name (e.g. `"bank"`).
4080
+ * @param shard - The shard key within the collection (e.g. `"en/animals"`).
4081
+ * @returns The parsed shard JSON, typed as `T`.
4082
+ * @throws {Error} If the fetch is not OK.
4083
+ * @example
4084
+ * ```ts
4085
+ * const animals = await loadCollectionShard<Animal[]>("/", "bank", "en/animals");
4086
+ * ```
4087
+ */
4088
+ declare function loadCollectionShard<T>(baseUrl: string, collection: string, shard: string): Promise<T>;
4089
+ //#endregion
3901
4090
  //#region src/index.d.ts
3902
4091
  /**
3903
4092
  * Create and initialize a `@moku-labs/web` application — the Layer-3 entry point.
@@ -4004,4 +4193,4 @@ declare const createApp: <const ExtraPlugins extends readonly import("@moku-labs
4004
4193
  */
4005
4194
  declare const createPlugin: import("@moku-labs/core").BoundCreatePluginFunction<Config$8, Events, import("@moku-labs/core").CoreApisFromTuple<[import("@moku-labs/core").CorePluginInstance<"log", import("@moku-labs/common").LogConfig, import("@moku-labs/common").LogState, import("@moku-labs/common").LogApi>, import("@moku-labs/core").CorePluginInstance<"env", import("@moku-labs/common").EnvConfig, import("@moku-labs/common").EnvState, import("@moku-labs/common").EnvApi>]>>;
4006
4195
  //#endregion
4007
- export { types_d_exports as Build, type Channel, type ChannelKeepAlive, type ChannelOptions, type ChannelReconnect, types_d_exports$1 as Cli, types_d_exports$2 as Content, types_d_exports$3 as Data, types_d_exports$4 as Deploy, type EmbedFacade, EmbedFacadeButton, type EmbedFacadeProps, type EmbedOptions, type Env, type GalleryComponent, type GalleryOptions, type GalleryProps, type GallerySlide, GalleryTrack, types_d_exports$5 as Head, type Log, types_d_exports$6 as Router, types_d_exports$7 as Spa, browserEnv, buildArticleHead, buildPlugin, canonical, cliPlugin, cloudflareBindings, contentPlugin, createApp, createChannel, createIsland, createPlugin, createUrls, dataPlugin, defineRoutes, deployPlugin, dotenv, envPlugin, feedLink, fileSystemContent, hardNavigate, headPlugin, hreflang, i18nPlugin, jsonLd, lazyEmbed, logPlugin, meta, navigate, og, processEnv, route, routerPlugin, sitePlugin, spaPlugin, twitter };
4196
+ export { types_d_exports as Build, type Channel, type ChannelKeepAlive, type ChannelOptions, type ChannelReconnect, types_d_exports$1 as Cli, types_d_exports$2 as Collection, types_d_exports$3 as Content, types_d_exports$4 as Data, types_d_exports$5 as Deploy, type EmbedFacade, EmbedFacadeButton, type EmbedFacadeProps, type EmbedOptions, type Env, type GalleryComponent, type GalleryOptions, type GalleryProps, type GallerySlide, GalleryTrack, types_d_exports$6 as Head, type Log, types_d_exports$7 as Router, types_d_exports$8 as Spa, browserEnv, buildArticleHead, buildPlugin, canonical, cliPlugin, cloudflareBindings, collectionPlugin, collectionUrl, contentPlugin, createApp, createChannel, createIsland, createPlugin, createUrls, dataPlugin, defineRoutes, deployPlugin, dotenv, envPlugin, feedLink, fileSystemContent, hardNavigate, headPlugin, hreflang, i18nPlugin, jsonLd, lazyEmbed, loadCollectionShard, logPlugin, meta, navigate, og, processEnv, route, routerPlugin, sitePlugin, spaPlugin, twitter };