@moku-labs/web 1.16.1 → 2.0.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/README.md CHANGED
@@ -171,7 +171,7 @@ There are two entry points, and the difference is a hard guarantee, not a tree-s
171
171
  | Entry | Format | For | Includes |
172
172
  |---|---|---|---|
173
173
  | **`@moku-labs/web`** | dual ESM + CJS | Node SSG builds | the full surface — add `content` / `build` / `deploy` / `cli` and wire `dotenv()` / `processEnv()` |
174
- | **`@moku-labs/web/browser`** | ESM-only | client bundles | the same `createApp` over the same isomorphic defaults, plus `dataPlugin`, the route DSL, `createComponent`, `browserEnv`, and the SEO head primitives — **with all node-only code excluded** (`build` / `deploy` / `cli` and the `dotenv` / `processEnv` / `fileSystemContent` providers), and `browserEnv()` pre-wired as the default `env` provider |
174
+ | **`@moku-labs/web/browser`** | ESM-only | client bundles | the same `createApp` over the same isomorphic defaults, plus `dataPlugin`, the route DSL, `createIsland`, `browserEnv`, and the SEO head primitives — **with all node-only code excluded** (`build` / `deploy` / `cli` and the `dotenv` / `processEnv` / `fileSystemContent` providers), and `browserEnv()` pre-wired as the default `env` provider |
175
175
 
176
176
  Importing `@moku-labs/web/browser` can **never** drag node/native code into a client bundle, regardless of bundler or tree-shaking — its static import graph references zero node-only modules. This is stronger and more reliable than importing the main entry and relying on `"sideEffects": false`, where building entries together can merge node code into a shared chunk. (The browser entry keeps the `contentPlugin` *shell* so build-only loaders can `ctx.require(contentPlugin)`; the node Markdown source lives in `fileSystemContent`, which the entry does **not** export.) CI proves it:
177
177
 
@@ -871,7 +871,7 @@ type Api$1 = {
871
871
  composeTitle(head: HeadConfig | undefined): string;
872
872
  };
873
873
  declare namespace types_d_exports$4 {
874
- export { AnyVNode, COMPONENT_HOOK_NAMES, ComponentContext, ComponentDef, ComponentEventHandler, ComponentEvents, ComponentHooks, ComponentInstance, ComponentRender, ComponentRouteSlice, ComponentSpec, ComponentSpecExtras, ComponentStateFactory, ExtractApi, PageData, RenderResult, ResolvedSpaConfig, SpaApi, SpaConfig, SpaContext, SpaDataReader, SpaEmitFunction, SpaEvents, SpaKernel, SpaKernelDeps, SpaRequire, SpaState };
874
+ export { AnyVNode, ExtractApi, ISLAND_HOOK_NAMES, IslandContext, IslandDef, IslandEventHandler, IslandEvents, IslandHooks, IslandInstance, IslandRender, IslandRouteSlice, IslandSpec, IslandSpecExtras, IslandStateFactory, PageData, RenderResult, ResolvedSpaConfig, SpaApi, SpaConfig, SpaContext, SpaDataReader, SpaEmitFunction, SpaEvents, SpaKernel, SpaKernelDeps, SpaRequire, SpaState };
875
875
  }
876
876
  /** Payload map for the events `spa` emits, used to type the kernel's `emit` closure. */
877
877
  type SpaEvents = {
@@ -881,12 +881,12 @@ type SpaEvents = {
881
881
  }; /** The swap completed and the new URL is active. */
882
882
  "spa:navigated": {
883
883
  url: string;
884
- }; /** A component instance attached to an element. */
885
- "spa:component-mount": {
884
+ }; /** A island instance attached to an element. */
885
+ "spa:island-mount": {
886
886
  name: string;
887
887
  el: Element;
888
- }; /** A component instance detached from an element. */
889
- "spa:component-unmount": {
888
+ }; /** A island instance detached from an element. */
889
+ "spa:island-unmount": {
890
890
  name: string;
891
891
  el: Element;
892
892
  };
@@ -955,10 +955,10 @@ type SpaConfig = {
955
955
  */
956
956
  progressBar?: boolean;
957
957
  /**
958
- * Components to auto-register at init (in addition to runtime `register`).
958
+ * Islands to auto-register at init (in addition to runtime `register`).
959
959
  * Defaults to an empty array.
960
960
  */
961
- components?: ComponentDef[];
961
+ islands?: IslandDef[];
962
962
  };
963
963
  /** Resolved SPA config after defaults are applied. */
964
964
  interface ResolvedSpaConfig {
@@ -968,11 +968,11 @@ interface ResolvedSpaConfig {
968
968
  viewTransitions: boolean;
969
969
  /** Whether the progress bar is enabled. */
970
970
  progressBar: boolean;
971
- /** Pre-registered components. */
972
- components: ComponentDef[];
971
+ /** Pre-registered islands. */
972
+ islands: IslandDef[];
973
973
  }
974
974
  /**
975
- * What a component's `render` may return:
975
+ * What a island's `render` may return:
976
976
  * - a Preact `VNode` — committed into the host through the lazy Preact gate (`commitVNode`);
977
977
  * - a `Node` — replaces the host's children;
978
978
  * - a `string` — set as the host's `innerHTML`;
@@ -984,30 +984,33 @@ type RenderResult = AnyVNode | Node | string | void;
984
984
  * `VNode<SomeProps>`; the props generic is invariant under `exactOptionalPropertyTypes`,
985
985
  * so the only supertype that accepts every concrete `VNode<P>` is `VNode<any>`.
986
986
  */
987
+ /**
988
+ *
989
+ */
987
990
  type AnyVNode = import("preact").VNode<any>;
988
991
  /**
989
- * Factory that builds a component's typed per-instance state (mirrors a plugin's
992
+ * Factory that builds a island's typed per-instance state (mirrors a plugin's
990
993
  * `createState`). Called ONCE at mount; the returned object is stored on the
991
- * {@link ComponentInstance} and exposed read-only as `ctx.state`.
994
+ * {@link IslandInstance} and exposed read-only as `ctx.state`.
992
995
  *
993
- * @param ctx - The component context for this instance (state is not yet set).
996
+ * @param ctx - The island context for this instance (state is not yet set).
994
997
  * @returns The initial per-instance state.
995
998
  * @example
996
999
  * state: (ctx): BoardState => ({ boardId: ctx.params.id ?? "", cards: [] })
997
1000
  */
998
- type ComponentStateFactory<S extends object> = (ctx: ComponentContext<S>) => S;
1001
+ type IslandStateFactory<S extends object> = (ctx: IslandContext<S>) => S;
999
1002
  /**
1000
1003
  * Pure render of `(state, ctx)` → {@link RenderResult}. Called after mount-state-init
1001
1004
  * and again (microtask-batched) after every `ctx.set`. Must be free of side effects
1002
1005
  * beyond producing its result.
1003
1006
  *
1004
1007
  * @param state - The current per-instance state (read-only).
1005
- * @param ctx - The component context for this instance.
1008
+ * @param ctx - The island context for this instance.
1006
1009
  * @returns The render result to commit into the host.
1007
1010
  * @example
1008
1011
  * render: (state) => h(BoardView, { snapshot: state.snapshot })
1009
1012
  */
1010
- type ComponentRender<S extends object> = (state: Readonly<S>, ctx: ComponentContext<S>) => RenderResult;
1013
+ type IslandRender<S extends object> = (state: Readonly<S>, ctx: IslandContext<S>) => RenderResult;
1011
1014
  /**
1012
1015
  * A delegated DOM event handler. `target` is the element matched by the key's selector
1013
1016
  * (already resolved via `closest` — no `instanceof`/`closest` ceremony in the body).
@@ -1015,14 +1018,14 @@ type ComponentRender<S extends object> = (state: Readonly<S>, ctx: ComponentCont
1015
1018
  * Typed `void` for ergonomics (the void-return rule accepts async handlers returning
1016
1019
  * `Promise<void>` too); the kernel ignores any returned value.
1017
1020
  *
1018
- * @param ctx - The component context (carries the live per-instance `state`).
1021
+ * @param ctx - The island context (carries the live per-instance `state`).
1019
1022
  * @param event - The raw DOM event.
1020
1023
  * @param target - The element matched by the selector (the host when no selector).
1021
1024
  * @returns void (a returned promise is ignored by the kernel).
1022
1025
  * @example
1023
1026
  * (ctx, event, button) => { event.preventDefault(); ctx.set({ open: true }); }
1024
1027
  */
1025
- type ComponentEventHandler<S extends object> = (ctx: ComponentContext<S>, event: Event, target: Element) => void;
1028
+ type IslandEventHandler<S extends object> = (ctx: IslandContext<S>, event: Event, target: Element) => void;
1026
1029
  /**
1027
1030
  * Declarative delegated event map. Each key is `"<type> <selector>"` (the selector is
1028
1031
  * optional → a host-level listener). ONE real listener per event TYPE is attached to
@@ -1035,9 +1038,9 @@ type ComponentEventHandler<S extends object> = (ctx: ComponentContext<S>, event:
1035
1038
  * "submit [data-add]": (ctx, e) => { e.preventDefault(); add(ctx); }
1036
1039
  * }
1037
1040
  */
1038
- type ComponentEvents<S extends object> = Record<string, ComponentEventHandler<S>>;
1041
+ type IslandEvents<S extends object> = Record<string, IslandEventHandler<S>>;
1039
1042
  /**
1040
- * Context handed to every component lifecycle hook, render, and event handler — the
1043
+ * Context handed to every island lifecycle hook, render, and event handler — the
1041
1044
  * bound element + page data, plus the matched route's `params`/`meta`/`locale` and a
1042
1045
  * link builder, so an island can read its route context (e.g. a `card` route's
1043
1046
  * `ctx.meta.focus` + `ctx.params.id`) directly, without the page bridging it through
@@ -1045,11 +1048,11 @@ type ComponentEvents<S extends object> = Record<string, ComponentEventHandler<S>
1045
1048
  *
1046
1049
  * Generic over the per-instance state `S` (default `undefined` so every existing
1047
1050
  * hooks-only island still type-checks). The additive members (`state`/`set`/`flush`/
1048
- * `cleanup`/`component`) are ALWAYS-PRESENT functions — never optional keys — so they
1051
+ * `cleanup`/`island`) are ALWAYS-PRESENT functions — never optional keys — so they
1049
1052
  * never trip `exactOptionalPropertyTypes`.
1050
1053
  */
1051
- interface ComponentContext<S = undefined> {
1052
- /** The element the component instance is bound to. */
1054
+ interface IslandContext<S = undefined> {
1055
+ /** The element the island instance is bound to. */
1053
1056
  el: Element;
1054
1057
  /** Page data extracted from the `script#__DATA__` payload. */
1055
1058
  data: PageData;
@@ -1098,128 +1101,128 @@ interface ComponentContext<S = undefined> {
1098
1101
  * Resolve another island's registered `api` by name. Returns `undefined` when no
1099
1102
  * provider is registered (optional-dependency semantics, mirroring `ctx.has`).
1100
1103
  *
1101
- * @param name - The provider island's component name.
1104
+ * @param name - The provider island's island name.
1102
1105
  * @returns The provider's api, or `undefined`.
1103
1106
  * @example
1104
- * ctx.component<LightboxApi>("lightbox")?.open(slides, index);
1107
+ * ctx.island<LightboxApi>("lightbox")?.open(slides, index);
1105
1108
  */
1106
- component<T = unknown>(name: string): T | undefined;
1109
+ island<T = unknown>(name: string): T | undefined;
1107
1110
  }
1108
- /** Lifecycle hooks a component may implement. Generic over the per-instance state `S`. */
1109
- interface ComponentHooks<S = undefined> {
1111
+ /** Lifecycle hooks a island may implement. Generic over the per-instance state `S`. */
1112
+ interface IslandHooks<S = undefined> {
1110
1113
  /**
1111
1114
  * Called once when the instance is created (before DOM attach).
1112
1115
  *
1113
- * @param ctx - The component context for this instance.
1116
+ * @param ctx - The island context for this instance.
1114
1117
  * @returns void
1115
1118
  * @example
1116
1119
  * onCreate({ el }) { el.dataset.ready = "1"; }
1117
1120
  */
1118
- onCreate?(ctx: ComponentContext<S>): void;
1121
+ onCreate?(ctx: IslandContext<S>): void;
1119
1122
  /**
1120
1123
  * Called after the instance is attached to its element.
1121
1124
  *
1122
- * @param ctx - The component context for this instance.
1125
+ * @param ctx - The island context for this instance.
1123
1126
  * @returns void
1124
1127
  * @example
1125
1128
  * onMount({ el }) { el.textContent = "0"; }
1126
1129
  * @example
1127
1130
  * async onMount(ctx) { ctx.set({ items: await load() }); } // async is allowed; the harness awaits it via settle()
1128
1131
  */
1129
- onMount?(ctx: ComponentContext<S>): void;
1132
+ onMount?(ctx: IslandContext<S>): void;
1130
1133
  /**
1131
1134
  * Called when a navigation begins while this instance is mounted.
1132
1135
  *
1133
- * @param ctx - The component context for this instance.
1136
+ * @param ctx - The island context for this instance.
1134
1137
  * @returns void
1135
1138
  * @example
1136
1139
  * onNavStart({ el }) { el.dataset.loading = ""; }
1137
1140
  */
1138
- onNavStart?(ctx: ComponentContext<S>): void;
1141
+ onNavStart?(ctx: IslandContext<S>): void;
1139
1142
  /**
1140
1143
  * Called when a navigation completes while this instance is mounted.
1141
1144
  *
1142
- * @param ctx - The component context for this instance.
1145
+ * @param ctx - The island context for this instance.
1143
1146
  * @returns void
1144
1147
  * @example
1145
1148
  * onNavEnd({ el }) { delete el.dataset.loading; }
1146
1149
  */
1147
- onNavEnd?(ctx: ComponentContext<S>): void;
1150
+ onNavEnd?(ctx: IslandContext<S>): void;
1148
1151
  /**
1149
1152
  * Called before the instance is detached from its element.
1150
1153
  *
1151
- * @param ctx - The component context for this instance.
1154
+ * @param ctx - The island context for this instance.
1152
1155
  * @returns void
1153
1156
  * @example
1154
1157
  * onUnMount({ el }) { el.replaceChildren(); }
1155
1158
  */
1156
- onUnMount?(ctx: ComponentContext<S>): void;
1159
+ onUnMount?(ctx: IslandContext<S>): void;
1157
1160
  /**
1158
1161
  * Called once when the instance is destroyed (after detach).
1159
1162
  *
1160
- * @param ctx - The component context for this instance.
1163
+ * @param ctx - The island context for this instance.
1161
1164
  * @returns void
1162
1165
  * @example
1163
1166
  * onDestroy({ el }) { delete el.dataset.ready; }
1164
1167
  */
1165
- onDestroy?(ctx: ComponentContext<S>): void;
1168
+ onDestroy?(ctx: IslandContext<S>): void;
1166
1169
  }
1167
1170
  /** Allowed hook names — single source of truth for fail-fast validation. */
1168
- declare const COMPONENT_HOOK_NAMES: readonly ["onCreate", "onMount", "onNavStart", "onNavEnd", "onUnMount", "onDestroy"];
1171
+ declare const ISLAND_HOOK_NAMES: readonly ["onCreate", "onMount", "onNavStart", "onNavEnd", "onUnMount", "onDestroy"];
1169
1172
  /**
1170
- * The plugin-mirror authoring form for {@link createComponent}: typed per-instance
1173
+ * The plugin-mirror authoring form for {@link createIsland}: typed per-instance
1171
1174
  * `state`, `render`, declarative `events`, and a cross-island `api` on top of the
1172
1175
  * lifecycle hooks. All keys optional + additive; the presence of any spec-only key
1173
- * (`state`/`render`/`events`/`api`) selects the spec overload of `createComponent`.
1176
+ * (`state`/`render`/`events`/`api`) selects the spec overload of `createIsland`.
1174
1177
  *
1175
1178
  * @example
1176
- * createComponent<{ boards: Board[] }>("board-list", {
1179
+ * createIsland<{ boards: Board[] }>("board-list", {
1177
1180
  * state: () => ({ boards: [] }),
1178
- * async onMount(ctx) { ctx.set({ boards: await ctx.component<Api>("api")!.list() }); },
1181
+ * async onMount(ctx) { ctx.set({ boards: await ctx.island<Api>("api")!.list() }); },
1179
1182
  * render: (s) => h(BoardList, { boards: s.boards }),
1180
1183
  * events: { "submit [data-create]": (ctx, e) => { e.preventDefault(); create(ctx); } }
1181
1184
  * });
1182
1185
  */
1183
- interface ComponentSpec<S extends object = object, A = unknown> extends ComponentHooks<S> {
1186
+ interface IslandSpec<S extends object = object, A = unknown> extends IslandHooks<S> {
1184
1187
  /** Build typed per-instance state at mount (stored on the instance, not a module WeakMap). */
1185
- state?: ComponentStateFactory<S>;
1188
+ state?: IslandStateFactory<S>;
1186
1189
  /** Pure render re-invoked (microtask-batched) on every `ctx.set`. */
1187
- render?: ComponentRender<S>;
1190
+ render?: IslandRender<S>;
1188
1191
  /** Declarative delegated DOM events with auto-teardown. */
1189
- events?: ComponentEvents<S>;
1190
- /** Public api factory — registered under the component name; reached via `app.spa.component(name)`. */
1191
- api?: (ctx: ComponentContext<S>) => A;
1192
+ events?: IslandEvents<S>;
1193
+ /** Public api factory — registered under the island name; reached via `app.spa.island(name)`. */
1194
+ api?: (ctx: IslandContext<S>) => A;
1192
1195
  }
1193
1196
  /**
1194
- * The spec extras carried on a {@link ComponentDef}, type-erased to `object` state
1195
- * (authors keep full `S` inference at the `createComponent` call site; the registry
1197
+ * The spec extras carried on a {@link IslandDef}, type-erased to `object` state
1198
+ * (authors keep full `S` inference at the `createIsland` call site; the registry
1196
1199
  * stores the runtime-only erased form). Absent for legacy `(name, hooks)` defs.
1197
1200
  */
1198
- interface ComponentSpecExtras {
1201
+ interface IslandSpecExtras {
1199
1202
  /** Per-instance state factory. */
1200
- state?: ComponentStateFactory<object>;
1203
+ state?: IslandStateFactory<object>;
1201
1204
  /** Render called on mount + after every `ctx.set`. */
1202
- render?: ComponentRender<object>;
1205
+ render?: IslandRender<object>;
1203
1206
  /** Declarative delegated events. */
1204
- events?: ComponentEvents<object>;
1205
- /** Public api factory registered under the component name. */
1206
- api?: (ctx: ComponentContext<object>) => unknown;
1207
+ events?: IslandEvents<object>;
1208
+ /** Public api factory registered under the island name. */
1209
+ api?: (ctx: IslandContext<object>) => unknown;
1207
1210
  }
1208
- /** A registered component definition (an opaque token; author inference lives on `createComponent`). */
1209
- interface ComponentDef {
1210
- /** Unique component name (matched against `data-component`). */
1211
+ /** A registered island definition (an opaque token; author inference lives on `createIsland`). */
1212
+ interface IslandDef {
1213
+ /** Unique island name (matched against `data-island`). */
1211
1214
  name: string;
1212
1215
  /** Lifecycle hooks (the subset shared with the legacy form). */
1213
- hooks: ComponentHooks<object>;
1216
+ hooks: IslandHooks<object>;
1214
1217
  /** Plugin-mirror extras (state/render/events/api). Absent for legacy `(name, hooks)` defs. */
1215
- spec?: ComponentSpecExtras;
1218
+ spec?: IslandSpecExtras;
1216
1219
  }
1217
1220
  /** The matched-route slice carried on a live instance (params/meta/locale + link builder). */
1218
- type ComponentRouteSlice = Pick<ComponentContext, "params" | "meta" | "locale" | "url">;
1219
- /** A live, mounted component instance. */
1220
- interface ComponentInstance {
1221
+ type IslandRouteSlice = Pick<IslandContext, "params" | "meta" | "locale" | "url">;
1222
+ /** A live, mounted island instance. */
1223
+ interface IslandInstance {
1221
1224
  /** The definition this instance was created from. */
1222
- def: ComponentDef;
1225
+ def: IslandDef;
1223
1226
  /** The element this instance is bound to. */
1224
1227
  el: Element;
1225
1228
  /**
@@ -1229,13 +1232,13 @@ interface ComponentInstance {
1229
1232
  */
1230
1233
  persistent: boolean;
1231
1234
  /** The single per-instance context reused by every hook, event handler, and render. */
1232
- ctx: ComponentContext<object>;
1235
+ ctx: IslandContext<object>;
1233
1236
  /** Live per-instance state (the object returned by `spec.state`), or undefined for hooks-only islands. */
1234
1237
  state: object | undefined;
1235
1238
  /** This instance's public api (the object returned by `spec.api`), or undefined when none declared. */
1236
1239
  api: unknown;
1237
1240
  /** Current matched-route slice (updated on navigation; read by `ctx.params/meta/locale/url`). */
1238
- route: ComponentRouteSlice;
1241
+ route: IslandRouteSlice;
1239
1242
  /** Current page data payload (updated on navigation; read by `ctx.data`). */
1240
1243
  data: PageData;
1241
1244
  /** Disposers from `ctx.cleanup` + the declarative `events` listeners — run LIFO on destroy. */
@@ -1275,7 +1278,7 @@ interface SpaKernelDeps {
1275
1278
  /** The single shared SPA kernel — pure factory over state/config/emit/deps. */
1276
1279
  interface SpaKernel {
1277
1280
  /**
1278
- * Validate config, register config.components, seed currentUrl.
1281
+ * Validate config, register config.islands, seed currentUrl.
1279
1282
  *
1280
1283
  * @returns void
1281
1284
  * @example
@@ -1291,14 +1294,14 @@ interface SpaKernel {
1291
1294
  */
1292
1295
  boot(): void;
1293
1296
  /**
1294
- * Register a component definition (last-registered-wins).
1297
+ * Register a island definition (last-registered-wins).
1295
1298
  *
1296
- * @param component - The component definition to register.
1299
+ * @param island - The island definition to register.
1297
1300
  * @returns void
1298
1301
  * @example
1299
1302
  * kernel.register(counter);
1300
1303
  */
1301
- register(component: ComponentDef): void;
1304
+ register(island: IslandDef): void;
1302
1305
  /**
1303
1306
  * Process a navigation to `path`: fetch then swap then head-sync then emit.
1304
1307
  *
@@ -1309,7 +1312,7 @@ interface SpaKernel {
1309
1312
  */
1310
1313
  processNav(path: string): void;
1311
1314
  /**
1312
- * Query the swap region and mount components for matching elements.
1315
+ * Query the swap region and mount islands for matching elements.
1313
1316
  *
1314
1317
  * @returns void
1315
1318
  * @example
@@ -1327,12 +1330,12 @@ interface SpaKernel {
1327
1330
  }
1328
1331
  /** Internal mutable state for the spa plugin (all kernel data lives here). */
1329
1332
  interface SpaState {
1330
- /** Components registered by name (last-registered-wins). */
1331
- registeredComponents: Map<string, ComponentDef>;
1332
- /** Live component instances keyed by their bound element. */
1333
- instances: Map<Element, ComponentInstance>;
1334
- /** Registered island apis by component name (the cross-island `ctx.component`/`app.spa.component` seam). */
1335
- componentApis: Map<string, unknown>;
1333
+ /** Islands registered by name (last-registered-wins). */
1334
+ registeredIslands: Map<string, IslandDef>;
1335
+ /** Live island instances keyed by their bound element. */
1336
+ instances: Map<Element, IslandInstance>;
1337
+ /** Registered island apis by island name (the cross-island `ctx.island`/`app.spa.island` seam). */
1338
+ islandApis: Map<string, unknown>;
1336
1339
  /** The current resolved URL (pathname + search). */
1337
1340
  currentUrl: string;
1338
1341
  /** Teardown handle for the attached router listeners (null when detached). */
@@ -1345,14 +1348,14 @@ interface SpaState {
1345
1348
  /** Public API of the spa plugin (registration / control surface). */
1346
1349
  type SpaApi = {
1347
1350
  /**
1348
- * Register a component definition for client mounting.
1351
+ * Register a island definition for client mounting.
1349
1352
  *
1350
- * @param component - The component definition created via `createComponent`.
1353
+ * @param island - The island definition created via `createIsland`.
1351
1354
  * @returns void
1352
1355
  * @example
1353
1356
  * app.spa.register(counter);
1354
1357
  */
1355
- register(component: ComponentDef): void;
1358
+ register(island: IslandDef): void;
1356
1359
  /**
1357
1360
  * Programmatically navigate to a path (client runtime; no-op without a DOM).
1358
1361
  *
@@ -1374,12 +1377,12 @@ type SpaApi = {
1374
1377
  * Resolve a registered island's api by name (the cross-island seam). Returns
1375
1378
  * `undefined` when no provider with that name is currently registered.
1376
1379
  *
1377
- * @param name - The provider island's component name.
1380
+ * @param name - The provider island's island name.
1378
1381
  * @returns The provider's api, or `undefined`.
1379
1382
  * @example
1380
- * app.spa.component<LightboxApi>("lightbox")?.open(slides, 0);
1383
+ * app.spa.island<LightboxApi>("lightbox")?.open(slides, 0);
1381
1384
  */
1382
- component<T = unknown>(name: string): T | undefined;
1385
+ island<T = unknown>(name: string): T | undefined;
1383
1386
  };
1384
1387
  //#endregion
1385
1388
  //#region src/plugins/site/index.d.ts
@@ -1597,43 +1600,43 @@ declare const headPlugin: import("@moku-labs/core").PluginInstance<"head", Confi
1597
1600
  buildArticleHead: typeof buildArticleHead;
1598
1601
  };
1599
1602
  //#endregion
1600
- //#region src/plugins/spa/components.d.ts
1603
+ //#region src/plugins/spa/islands.d.ts
1601
1604
  /**
1602
- * Create a validated component definition. Accepts either the legacy hooks-only form
1603
- * (`createComponent("counter", { onMount() {} })`) or the plugin-mirror spec form
1604
- * (`createComponent("board", { state, render, events, api, ...hooks })`). Spec-only
1605
+ * Create a validated island definition. Accepts either the legacy hooks-only form
1606
+ * (`createIsland("counter", { onMount() {} })`) or the plugin-mirror spec form
1607
+ * (`createIsland("board", { state, render, events, api, ...hooks })`). Spec-only
1605
1608
  * keys (`state`/`render`/`events`/`api`) are partitioned out before hook-name
1606
1609
  * validation, so a real typo (e.g. `onMout`) still throws immediately while the spec
1607
1610
  * keys are accepted.
1608
1611
  *
1609
- * @param name - Unique component name.
1612
+ * @param name - Unique island name.
1610
1613
  * @param spec - Lifecycle hooks, or the `{ state, render, events, api, ...hooks }` spec.
1611
- * @returns A `ComponentDef` ready to `register`.
1614
+ * @returns A `IslandDef` ready to `register`.
1612
1615
  * @throws {Error} If `name` is empty, a hook key is unknown, or an extra/hook value has the wrong shape.
1613
1616
  * @example
1614
- * const counter = createComponent("counter", { onMount({ el }) { el.textContent = "0"; } });
1617
+ * const counter = createIsland("counter", { onMount({ el }) { el.textContent = "0"; } });
1615
1618
  * @example
1616
- * const list = createComponent<{ items: string[] }>("list", {
1619
+ * const list = createIsland<{ items: string[] }>("list", {
1617
1620
  * state: () => ({ items: [] }),
1618
1621
  * render: (s) => h(List, { items: s.items })
1619
1622
  * });
1620
1623
  */
1621
- declare function createComponent<S extends object = object, A = unknown>(name: string, spec: ComponentSpec<S, A>): ComponentDef;
1624
+ declare function createIsland<S extends object = object, A = unknown>(name: string, spec: IslandSpec<S, A>): IslandDef;
1622
1625
  //#endregion
1623
1626
  //#region src/plugins/spa/lazy-embed.d.ts
1624
1627
  /**
1625
1628
  * Lazy-embed island: facade button click → real `<iframe loading="lazy">`.
1626
1629
  * The companion of the content pipeline's `::embed` directive.
1627
1630
  */
1628
- declare const lazyEmbed: ComponentDef;
1631
+ declare const lazyEmbed: IslandDef;
1629
1632
  //#endregion
1630
1633
  //#region src/plugins/spa/index.d.ts
1631
1634
  /**
1632
1635
  * SPA plugin — progressive client-side navigation layered over the static site:
1633
1636
  * swaps a page region on navigation, with an optional progress bar and View
1634
- * Transitions. Register interactive islands with {@link createComponent}. Depends
1635
- * on router and head; emits `spa:navigate`, `spa:navigated`, `spa:component-mount`,
1636
- * and `spa:component-unmount`.
1637
+ * Transitions. Register interactive islands with {@link createIsland}. Depends
1638
+ * on router and head; emits `spa:navigate`, `spa:navigated`, `spa:island-mount`,
1639
+ * and `spa:island-unmount`.
1637
1640
  *
1638
1641
  * @example Enable view transitions and a custom swap region
1639
1642
  * ```ts
@@ -1656,11 +1659,11 @@ declare const spaPlugin: import("@moku-labs/core").PluginInstance<"spa", SpaConf
1656
1659
  "spa:navigated": {
1657
1660
  url: string;
1658
1661
  };
1659
- "spa:component-mount": {
1662
+ "spa:island-mount": {
1660
1663
  name: string;
1661
1664
  el: Element;
1662
1665
  };
1663
- "spa:component-unmount": {
1666
+ "spa:island-unmount": {
1664
1667
  name: string;
1665
1668
  el: Element;
1666
1669
  };
@@ -2036,7 +2039,7 @@ type GalleryProps = {
2036
2039
  /**
2037
2040
  * A consumer-supplied gallery component: a Preact function component over
2038
2041
  * {@link GalleryProps}, rendered (at build time, to static markup) as the inner
2039
- * content — inside the framework-owned `<div data-component="gallery">` that carries
2042
+ * content — inside the framework-owned `<div data-island="gallery">` that carries
2040
2043
  * the island hook. Defaults to the built-in `GalleryTrack`.
2041
2044
  */
2042
2045
  type GalleryComponent = FunctionComponent<GalleryProps>;
@@ -2359,11 +2362,11 @@ declare const createApp: <const ExtraPlugins extends readonly import("@moku-labs
2359
2362
  "spa:navigated": {
2360
2363
  url: string;
2361
2364
  };
2362
- "spa:component-mount": {
2365
+ "spa:island-mount": {
2363
2366
  name: string;
2364
2367
  el: Element;
2365
2368
  };
2366
- "spa:component-unmount": {
2369
+ "spa:island-unmount": {
2367
2370
  name: string;
2368
2371
  el: Element;
2369
2372
  };
@@ -2388,11 +2391,11 @@ declare const createApp: <const ExtraPlugins extends readonly import("@moku-labs
2388
2391
  "spa:navigated": {
2389
2392
  url: string;
2390
2393
  };
2391
- "spa:component-mount": {
2394
+ "spa:island-mount": {
2392
2395
  name: string;
2393
2396
  el: Element;
2394
2397
  };
2395
- "spa:component-unmount": {
2398
+ "spa:island-unmount": {
2396
2399
  name: string;
2397
2400
  el: Element;
2398
2401
  };
@@ -2414,4 +2417,4 @@ declare const createApp: <const ExtraPlugins extends readonly import("@moku-labs
2414
2417
  */
2415
2418
  declare const createPlugin: import("@moku-labs/core").BoundCreatePluginFunction<Config$5, 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>]>>;
2416
2419
  //#endregion
2417
- export { types_d_exports as Content, types_d_exports$1 as Data, type Env, types_d_exports$2 as Head, type Log, types_d_exports$3 as Router, types_d_exports$4 as Spa, browserEnv, buildArticleHead, canonical, contentPlugin, createApp, createComponent, createPlugin, createUrls, dataPlugin, defineRoutes, envPlugin, feedLink, headPlugin, hreflang, i18nPlugin, jsonLd, lazyEmbed, logPlugin, meta, og, route, routerPlugin, sitePlugin, spaPlugin, twitter };
2420
+ export { types_d_exports as Content, types_d_exports$1 as Data, type Env, types_d_exports$2 as Head, type Log, types_d_exports$3 as Router, types_d_exports$4 as Spa, browserEnv, buildArticleHead, canonical, contentPlugin, createApp, createIsland, createPlugin, createUrls, dataPlugin, defineRoutes, envPlugin, feedLink, headPlugin, hreflang, i18nPlugin, jsonLd, lazyEmbed, logPlugin, meta, og, route, routerPlugin, sitePlugin, spaPlugin, twitter };