@moku-labs/web 1.17.0 → 2.0.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/README.md +1 -1
- package/dist/browser.d.mts +111 -108
- package/dist/browser.mjs +189 -189
- package/dist/index.cjs +198 -198
- package/dist/index.d.cts +111 -108
- package/dist/index.d.mts +111 -108
- package/dist/index.mjs +198 -198
- package/dist/{render-KdufA3_b.cjs → render-DHUcHCYs.cjs} +4 -4
- package/dist/{render-UO4nimWr.mjs → render-yXHc9BWI.mjs} +4 -4
- package/dist/testing.d.mts +59 -56
- package/dist/testing.mjs +50 -50
- package/package.json +3 -3
package/dist/index.d.mts
CHANGED
|
@@ -870,7 +870,7 @@ type Api$4 = {
|
|
|
870
870
|
composeTitle(head: HeadConfig | undefined): string;
|
|
871
871
|
};
|
|
872
872
|
declare namespace types_d_exports$7 {
|
|
873
|
-
export { AnyVNode,
|
|
873
|
+
export { AnyVNode, ExtractApi$1 as 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 };
|
|
874
874
|
}
|
|
875
875
|
/** Payload map for the events `spa` emits, used to type the kernel's `emit` closure. */
|
|
876
876
|
type SpaEvents = {
|
|
@@ -880,12 +880,12 @@ type SpaEvents = {
|
|
|
880
880
|
}; /** The swap completed and the new URL is active. */
|
|
881
881
|
"spa:navigated": {
|
|
882
882
|
url: string;
|
|
883
|
-
}; /** A
|
|
884
|
-
"spa:
|
|
883
|
+
}; /** A island instance attached to an element. */
|
|
884
|
+
"spa:island-mount": {
|
|
885
885
|
name: string;
|
|
886
886
|
el: Element;
|
|
887
|
-
}; /** A
|
|
888
|
-
"spa:
|
|
887
|
+
}; /** A island instance detached from an element. */
|
|
888
|
+
"spa:island-unmount": {
|
|
889
889
|
name: string;
|
|
890
890
|
el: Element;
|
|
891
891
|
};
|
|
@@ -954,10 +954,10 @@ type SpaConfig = {
|
|
|
954
954
|
*/
|
|
955
955
|
progressBar?: boolean;
|
|
956
956
|
/**
|
|
957
|
-
*
|
|
957
|
+
* Islands to auto-register at init (in addition to runtime `register`).
|
|
958
958
|
* Defaults to an empty array.
|
|
959
959
|
*/
|
|
960
|
-
|
|
960
|
+
islands?: IslandDef[];
|
|
961
961
|
};
|
|
962
962
|
/** Resolved SPA config after defaults are applied. */
|
|
963
963
|
interface ResolvedSpaConfig {
|
|
@@ -967,11 +967,11 @@ interface ResolvedSpaConfig {
|
|
|
967
967
|
viewTransitions: boolean;
|
|
968
968
|
/** Whether the progress bar is enabled. */
|
|
969
969
|
progressBar: boolean;
|
|
970
|
-
/** Pre-registered
|
|
971
|
-
|
|
970
|
+
/** Pre-registered islands. */
|
|
971
|
+
islands: IslandDef[];
|
|
972
972
|
}
|
|
973
973
|
/**
|
|
974
|
-
* What a
|
|
974
|
+
* What a island's `render` may return:
|
|
975
975
|
* - a Preact `VNode` — committed into the host through the lazy Preact gate (`commitVNode`);
|
|
976
976
|
* - a `Node` — replaces the host's children;
|
|
977
977
|
* - a `string` — set as the host's `innerHTML`;
|
|
@@ -983,30 +983,33 @@ type RenderResult = AnyVNode | Node | string | void;
|
|
|
983
983
|
* `VNode<SomeProps>`; the props generic is invariant under `exactOptionalPropertyTypes`,
|
|
984
984
|
* so the only supertype that accepts every concrete `VNode<P>` is `VNode<any>`.
|
|
985
985
|
*/
|
|
986
|
+
/**
|
|
987
|
+
*
|
|
988
|
+
*/
|
|
986
989
|
type AnyVNode = import("preact").VNode<any>;
|
|
987
990
|
/**
|
|
988
|
-
* Factory that builds a
|
|
991
|
+
* Factory that builds a island's typed per-instance state (mirrors a plugin's
|
|
989
992
|
* `createState`). Called ONCE at mount; the returned object is stored on the
|
|
990
|
-
* {@link
|
|
993
|
+
* {@link IslandInstance} and exposed read-only as `ctx.state`.
|
|
991
994
|
*
|
|
992
|
-
* @param ctx - The
|
|
995
|
+
* @param ctx - The island context for this instance (state is not yet set).
|
|
993
996
|
* @returns The initial per-instance state.
|
|
994
997
|
* @example
|
|
995
998
|
* state: (ctx): BoardState => ({ boardId: ctx.params.id ?? "", cards: [] })
|
|
996
999
|
*/
|
|
997
|
-
type
|
|
1000
|
+
type IslandStateFactory<S extends object> = (ctx: IslandContext<S>) => S;
|
|
998
1001
|
/**
|
|
999
1002
|
* Pure render of `(state, ctx)` → {@link RenderResult}. Called after mount-state-init
|
|
1000
1003
|
* and again (microtask-batched) after every `ctx.set`. Must be free of side effects
|
|
1001
1004
|
* beyond producing its result.
|
|
1002
1005
|
*
|
|
1003
1006
|
* @param state - The current per-instance state (read-only).
|
|
1004
|
-
* @param ctx - The
|
|
1007
|
+
* @param ctx - The island context for this instance.
|
|
1005
1008
|
* @returns The render result to commit into the host.
|
|
1006
1009
|
* @example
|
|
1007
1010
|
* render: (state) => h(BoardView, { snapshot: state.snapshot })
|
|
1008
1011
|
*/
|
|
1009
|
-
type
|
|
1012
|
+
type IslandRender<S extends object> = (state: Readonly<S>, ctx: IslandContext<S>) => RenderResult;
|
|
1010
1013
|
/**
|
|
1011
1014
|
* A delegated DOM event handler. `target` is the element matched by the key's selector
|
|
1012
1015
|
* (already resolved via `closest` — no `instanceof`/`closest` ceremony in the body).
|
|
@@ -1014,14 +1017,14 @@ type ComponentRender<S extends object> = (state: Readonly<S>, ctx: ComponentCont
|
|
|
1014
1017
|
* Typed `void` for ergonomics (the void-return rule accepts async handlers returning
|
|
1015
1018
|
* `Promise<void>` too); the kernel ignores any returned value.
|
|
1016
1019
|
*
|
|
1017
|
-
* @param ctx - The
|
|
1020
|
+
* @param ctx - The island context (carries the live per-instance `state`).
|
|
1018
1021
|
* @param event - The raw DOM event.
|
|
1019
1022
|
* @param target - The element matched by the selector (the host when no selector).
|
|
1020
1023
|
* @returns void (a returned promise is ignored by the kernel).
|
|
1021
1024
|
* @example
|
|
1022
1025
|
* (ctx, event, button) => { event.preventDefault(); ctx.set({ open: true }); }
|
|
1023
1026
|
*/
|
|
1024
|
-
type
|
|
1027
|
+
type IslandEventHandler<S extends object> = (ctx: IslandContext<S>, event: Event, target: Element) => void;
|
|
1025
1028
|
/**
|
|
1026
1029
|
* Declarative delegated event map. Each key is `"<type> <selector>"` (the selector is
|
|
1027
1030
|
* optional → a host-level listener). ONE real listener per event TYPE is attached to
|
|
@@ -1034,9 +1037,9 @@ type ComponentEventHandler<S extends object> = (ctx: ComponentContext<S>, event:
|
|
|
1034
1037
|
* "submit [data-add]": (ctx, e) => { e.preventDefault(); add(ctx); }
|
|
1035
1038
|
* }
|
|
1036
1039
|
*/
|
|
1037
|
-
type
|
|
1040
|
+
type IslandEvents<S extends object> = Record<string, IslandEventHandler<S>>;
|
|
1038
1041
|
/**
|
|
1039
|
-
* Context handed to every
|
|
1042
|
+
* Context handed to every island lifecycle hook, render, and event handler — the
|
|
1040
1043
|
* bound element + page data, plus the matched route's `params`/`meta`/`locale` and a
|
|
1041
1044
|
* link builder, so an island can read its route context (e.g. a `card` route's
|
|
1042
1045
|
* `ctx.meta.focus` + `ctx.params.id`) directly, without the page bridging it through
|
|
@@ -1044,11 +1047,11 @@ type ComponentEvents<S extends object> = Record<string, ComponentEventHandler<S>
|
|
|
1044
1047
|
*
|
|
1045
1048
|
* Generic over the per-instance state `S` (default `undefined` so every existing
|
|
1046
1049
|
* hooks-only island still type-checks). The additive members (`state`/`set`/`flush`/
|
|
1047
|
-
* `cleanup`/`
|
|
1050
|
+
* `cleanup`/`island`) are ALWAYS-PRESENT functions — never optional keys — so they
|
|
1048
1051
|
* never trip `exactOptionalPropertyTypes`.
|
|
1049
1052
|
*/
|
|
1050
|
-
interface
|
|
1051
|
-
/** The element the
|
|
1053
|
+
interface IslandContext<S = undefined> {
|
|
1054
|
+
/** The element the island instance is bound to. */
|
|
1052
1055
|
el: Element;
|
|
1053
1056
|
/** Page data extracted from the `script#__DATA__` payload. */
|
|
1054
1057
|
data: PageData;
|
|
@@ -1097,128 +1100,128 @@ interface ComponentContext<S = undefined> {
|
|
|
1097
1100
|
* Resolve another island's registered `api` by name. Returns `undefined` when no
|
|
1098
1101
|
* provider is registered (optional-dependency semantics, mirroring `ctx.has`).
|
|
1099
1102
|
*
|
|
1100
|
-
* @param name - The provider island's
|
|
1103
|
+
* @param name - The provider island's island name.
|
|
1101
1104
|
* @returns The provider's api, or `undefined`.
|
|
1102
1105
|
* @example
|
|
1103
|
-
* ctx.
|
|
1106
|
+
* ctx.island<LightboxApi>("lightbox")?.open(slides, index);
|
|
1104
1107
|
*/
|
|
1105
|
-
|
|
1108
|
+
island<T = unknown>(name: string): T | undefined;
|
|
1106
1109
|
}
|
|
1107
|
-
/** Lifecycle hooks a
|
|
1108
|
-
interface
|
|
1110
|
+
/** Lifecycle hooks a island may implement. Generic over the per-instance state `S`. */
|
|
1111
|
+
interface IslandHooks<S = undefined> {
|
|
1109
1112
|
/**
|
|
1110
1113
|
* Called once when the instance is created (before DOM attach).
|
|
1111
1114
|
*
|
|
1112
|
-
* @param ctx - The
|
|
1115
|
+
* @param ctx - The island context for this instance.
|
|
1113
1116
|
* @returns void
|
|
1114
1117
|
* @example
|
|
1115
1118
|
* onCreate({ el }) { el.dataset.ready = "1"; }
|
|
1116
1119
|
*/
|
|
1117
|
-
onCreate?(ctx:
|
|
1120
|
+
onCreate?(ctx: IslandContext<S>): void;
|
|
1118
1121
|
/**
|
|
1119
1122
|
* Called after the instance is attached to its element.
|
|
1120
1123
|
*
|
|
1121
|
-
* @param ctx - The
|
|
1124
|
+
* @param ctx - The island context for this instance.
|
|
1122
1125
|
* @returns void
|
|
1123
1126
|
* @example
|
|
1124
1127
|
* onMount({ el }) { el.textContent = "0"; }
|
|
1125
1128
|
* @example
|
|
1126
1129
|
* async onMount(ctx) { ctx.set({ items: await load() }); } // async is allowed; the harness awaits it via settle()
|
|
1127
1130
|
*/
|
|
1128
|
-
onMount?(ctx:
|
|
1131
|
+
onMount?(ctx: IslandContext<S>): void;
|
|
1129
1132
|
/**
|
|
1130
1133
|
* Called when a navigation begins while this instance is mounted.
|
|
1131
1134
|
*
|
|
1132
|
-
* @param ctx - The
|
|
1135
|
+
* @param ctx - The island context for this instance.
|
|
1133
1136
|
* @returns void
|
|
1134
1137
|
* @example
|
|
1135
1138
|
* onNavStart({ el }) { el.dataset.loading = ""; }
|
|
1136
1139
|
*/
|
|
1137
|
-
onNavStart?(ctx:
|
|
1140
|
+
onNavStart?(ctx: IslandContext<S>): void;
|
|
1138
1141
|
/**
|
|
1139
1142
|
* Called when a navigation completes while this instance is mounted.
|
|
1140
1143
|
*
|
|
1141
|
-
* @param ctx - The
|
|
1144
|
+
* @param ctx - The island context for this instance.
|
|
1142
1145
|
* @returns void
|
|
1143
1146
|
* @example
|
|
1144
1147
|
* onNavEnd({ el }) { delete el.dataset.loading; }
|
|
1145
1148
|
*/
|
|
1146
|
-
onNavEnd?(ctx:
|
|
1149
|
+
onNavEnd?(ctx: IslandContext<S>): void;
|
|
1147
1150
|
/**
|
|
1148
1151
|
* Called before the instance is detached from its element.
|
|
1149
1152
|
*
|
|
1150
|
-
* @param ctx - The
|
|
1153
|
+
* @param ctx - The island context for this instance.
|
|
1151
1154
|
* @returns void
|
|
1152
1155
|
* @example
|
|
1153
1156
|
* onUnMount({ el }) { el.replaceChildren(); }
|
|
1154
1157
|
*/
|
|
1155
|
-
onUnMount?(ctx:
|
|
1158
|
+
onUnMount?(ctx: IslandContext<S>): void;
|
|
1156
1159
|
/**
|
|
1157
1160
|
* Called once when the instance is destroyed (after detach).
|
|
1158
1161
|
*
|
|
1159
|
-
* @param ctx - The
|
|
1162
|
+
* @param ctx - The island context for this instance.
|
|
1160
1163
|
* @returns void
|
|
1161
1164
|
* @example
|
|
1162
1165
|
* onDestroy({ el }) { delete el.dataset.ready; }
|
|
1163
1166
|
*/
|
|
1164
|
-
onDestroy?(ctx:
|
|
1167
|
+
onDestroy?(ctx: IslandContext<S>): void;
|
|
1165
1168
|
}
|
|
1166
1169
|
/** Allowed hook names — single source of truth for fail-fast validation. */
|
|
1167
|
-
declare const
|
|
1170
|
+
declare const ISLAND_HOOK_NAMES: readonly ["onCreate", "onMount", "onNavStart", "onNavEnd", "onUnMount", "onDestroy"];
|
|
1168
1171
|
/**
|
|
1169
|
-
* The plugin-mirror authoring form for {@link
|
|
1172
|
+
* The plugin-mirror authoring form for {@link createIsland}: typed per-instance
|
|
1170
1173
|
* `state`, `render`, declarative `events`, and a cross-island `api` on top of the
|
|
1171
1174
|
* lifecycle hooks. All keys optional + additive; the presence of any spec-only key
|
|
1172
|
-
* (`state`/`render`/`events`/`api`) selects the spec overload of `
|
|
1175
|
+
* (`state`/`render`/`events`/`api`) selects the spec overload of `createIsland`.
|
|
1173
1176
|
*
|
|
1174
1177
|
* @example
|
|
1175
|
-
*
|
|
1178
|
+
* createIsland<{ boards: Board[] }>("board-list", {
|
|
1176
1179
|
* state: () => ({ boards: [] }),
|
|
1177
|
-
* async onMount(ctx) { ctx.set({ boards: await ctx.
|
|
1180
|
+
* async onMount(ctx) { ctx.set({ boards: await ctx.island<Api>("api")!.list() }); },
|
|
1178
1181
|
* render: (s) => h(BoardList, { boards: s.boards }),
|
|
1179
1182
|
* events: { "submit [data-create]": (ctx, e) => { e.preventDefault(); create(ctx); } }
|
|
1180
1183
|
* });
|
|
1181
1184
|
*/
|
|
1182
|
-
interface
|
|
1185
|
+
interface IslandSpec<S extends object = object, A = unknown> extends IslandHooks<S> {
|
|
1183
1186
|
/** Build typed per-instance state at mount (stored on the instance, not a module WeakMap). */
|
|
1184
|
-
state?:
|
|
1187
|
+
state?: IslandStateFactory<S>;
|
|
1185
1188
|
/** Pure render re-invoked (microtask-batched) on every `ctx.set`. */
|
|
1186
|
-
render?:
|
|
1189
|
+
render?: IslandRender<S>;
|
|
1187
1190
|
/** Declarative delegated DOM events with auto-teardown. */
|
|
1188
|
-
events?:
|
|
1189
|
-
/** Public api factory — registered under the
|
|
1190
|
-
api?: (ctx:
|
|
1191
|
+
events?: IslandEvents<S>;
|
|
1192
|
+
/** Public api factory — registered under the island name; reached via `app.spa.island(name)`. */
|
|
1193
|
+
api?: (ctx: IslandContext<S>) => A;
|
|
1191
1194
|
}
|
|
1192
1195
|
/**
|
|
1193
|
-
* The spec extras carried on a {@link
|
|
1194
|
-
* (authors keep full `S` inference at the `
|
|
1196
|
+
* The spec extras carried on a {@link IslandDef}, type-erased to `object` state
|
|
1197
|
+
* (authors keep full `S` inference at the `createIsland` call site; the registry
|
|
1195
1198
|
* stores the runtime-only erased form). Absent for legacy `(name, hooks)` defs.
|
|
1196
1199
|
*/
|
|
1197
|
-
interface
|
|
1200
|
+
interface IslandSpecExtras {
|
|
1198
1201
|
/** Per-instance state factory. */
|
|
1199
|
-
state?:
|
|
1202
|
+
state?: IslandStateFactory<object>;
|
|
1200
1203
|
/** Render called on mount + after every `ctx.set`. */
|
|
1201
|
-
render?:
|
|
1204
|
+
render?: IslandRender<object>;
|
|
1202
1205
|
/** Declarative delegated events. */
|
|
1203
|
-
events?:
|
|
1204
|
-
/** Public api factory registered under the
|
|
1205
|
-
api?: (ctx:
|
|
1206
|
+
events?: IslandEvents<object>;
|
|
1207
|
+
/** Public api factory registered under the island name. */
|
|
1208
|
+
api?: (ctx: IslandContext<object>) => unknown;
|
|
1206
1209
|
}
|
|
1207
|
-
/** A registered
|
|
1208
|
-
interface
|
|
1209
|
-
/** Unique
|
|
1210
|
+
/** A registered island definition (an opaque token; author inference lives on `createIsland`). */
|
|
1211
|
+
interface IslandDef {
|
|
1212
|
+
/** Unique island name (matched against `data-island`). */
|
|
1210
1213
|
name: string;
|
|
1211
1214
|
/** Lifecycle hooks (the subset shared with the legacy form). */
|
|
1212
|
-
hooks:
|
|
1215
|
+
hooks: IslandHooks<object>;
|
|
1213
1216
|
/** Plugin-mirror extras (state/render/events/api). Absent for legacy `(name, hooks)` defs. */
|
|
1214
|
-
spec?:
|
|
1217
|
+
spec?: IslandSpecExtras;
|
|
1215
1218
|
}
|
|
1216
1219
|
/** The matched-route slice carried on a live instance (params/meta/locale + link builder). */
|
|
1217
|
-
type
|
|
1218
|
-
/** A live, mounted
|
|
1219
|
-
interface
|
|
1220
|
+
type IslandRouteSlice = Pick<IslandContext, "params" | "meta" | "locale" | "url">;
|
|
1221
|
+
/** A live, mounted island instance. */
|
|
1222
|
+
interface IslandInstance {
|
|
1220
1223
|
/** The definition this instance was created from. */
|
|
1221
|
-
def:
|
|
1224
|
+
def: IslandDef;
|
|
1222
1225
|
/** The element this instance is bound to. */
|
|
1223
1226
|
el: Element;
|
|
1224
1227
|
/**
|
|
@@ -1228,13 +1231,13 @@ interface ComponentInstance {
|
|
|
1228
1231
|
*/
|
|
1229
1232
|
persistent: boolean;
|
|
1230
1233
|
/** The single per-instance context reused by every hook, event handler, and render. */
|
|
1231
|
-
ctx:
|
|
1234
|
+
ctx: IslandContext<object>;
|
|
1232
1235
|
/** Live per-instance state (the object returned by `spec.state`), or undefined for hooks-only islands. */
|
|
1233
1236
|
state: object | undefined;
|
|
1234
1237
|
/** This instance's public api (the object returned by `spec.api`), or undefined when none declared. */
|
|
1235
1238
|
api: unknown;
|
|
1236
1239
|
/** Current matched-route slice (updated on navigation; read by `ctx.params/meta/locale/url`). */
|
|
1237
|
-
route:
|
|
1240
|
+
route: IslandRouteSlice;
|
|
1238
1241
|
/** Current page data payload (updated on navigation; read by `ctx.data`). */
|
|
1239
1242
|
data: PageData;
|
|
1240
1243
|
/** Disposers from `ctx.cleanup` + the declarative `events` listeners — run LIFO on destroy. */
|
|
@@ -1274,7 +1277,7 @@ interface SpaKernelDeps {
|
|
|
1274
1277
|
/** The single shared SPA kernel — pure factory over state/config/emit/deps. */
|
|
1275
1278
|
interface SpaKernel {
|
|
1276
1279
|
/**
|
|
1277
|
-
* Validate config, register config.
|
|
1280
|
+
* Validate config, register config.islands, seed currentUrl.
|
|
1278
1281
|
*
|
|
1279
1282
|
* @returns void
|
|
1280
1283
|
* @example
|
|
@@ -1290,14 +1293,14 @@ interface SpaKernel {
|
|
|
1290
1293
|
*/
|
|
1291
1294
|
boot(): void;
|
|
1292
1295
|
/**
|
|
1293
|
-
* Register a
|
|
1296
|
+
* Register a island definition (last-registered-wins).
|
|
1294
1297
|
*
|
|
1295
|
-
* @param
|
|
1298
|
+
* @param island - The island definition to register.
|
|
1296
1299
|
* @returns void
|
|
1297
1300
|
* @example
|
|
1298
1301
|
* kernel.register(counter);
|
|
1299
1302
|
*/
|
|
1300
|
-
register(
|
|
1303
|
+
register(island: IslandDef): void;
|
|
1301
1304
|
/**
|
|
1302
1305
|
* Process a navigation to `path`: fetch then swap then head-sync then emit.
|
|
1303
1306
|
*
|
|
@@ -1308,7 +1311,7 @@ interface SpaKernel {
|
|
|
1308
1311
|
*/
|
|
1309
1312
|
processNav(path: string): void;
|
|
1310
1313
|
/**
|
|
1311
|
-
* Query the swap region and mount
|
|
1314
|
+
* Query the swap region and mount islands for matching elements.
|
|
1312
1315
|
*
|
|
1313
1316
|
* @returns void
|
|
1314
1317
|
* @example
|
|
@@ -1326,12 +1329,12 @@ interface SpaKernel {
|
|
|
1326
1329
|
}
|
|
1327
1330
|
/** Internal mutable state for the spa plugin (all kernel data lives here). */
|
|
1328
1331
|
interface SpaState {
|
|
1329
|
-
/**
|
|
1330
|
-
|
|
1331
|
-
/** Live
|
|
1332
|
-
instances: Map<Element,
|
|
1333
|
-
/** Registered island apis by
|
|
1334
|
-
|
|
1332
|
+
/** Islands registered by name (last-registered-wins). */
|
|
1333
|
+
registeredIslands: Map<string, IslandDef>;
|
|
1334
|
+
/** Live island instances keyed by their bound element. */
|
|
1335
|
+
instances: Map<Element, IslandInstance>;
|
|
1336
|
+
/** Registered island apis by island name (the cross-island `ctx.island`/`app.spa.island` seam). */
|
|
1337
|
+
islandApis: Map<string, unknown>;
|
|
1335
1338
|
/** The current resolved URL (pathname + search). */
|
|
1336
1339
|
currentUrl: string;
|
|
1337
1340
|
/** Teardown handle for the attached router listeners (null when detached). */
|
|
@@ -1344,14 +1347,14 @@ interface SpaState {
|
|
|
1344
1347
|
/** Public API of the spa plugin (registration / control surface). */
|
|
1345
1348
|
type SpaApi = {
|
|
1346
1349
|
/**
|
|
1347
|
-
* Register a
|
|
1350
|
+
* Register a island definition for client mounting.
|
|
1348
1351
|
*
|
|
1349
|
-
* @param
|
|
1352
|
+
* @param island - The island definition created via `createIsland`.
|
|
1350
1353
|
* @returns void
|
|
1351
1354
|
* @example
|
|
1352
1355
|
* app.spa.register(counter);
|
|
1353
1356
|
*/
|
|
1354
|
-
register(
|
|
1357
|
+
register(island: IslandDef): void;
|
|
1355
1358
|
/**
|
|
1356
1359
|
* Programmatically navigate to a path (client runtime; no-op without a DOM).
|
|
1357
1360
|
*
|
|
@@ -1373,12 +1376,12 @@ type SpaApi = {
|
|
|
1373
1376
|
* Resolve a registered island's api by name (the cross-island seam). Returns
|
|
1374
1377
|
* `undefined` when no provider with that name is currently registered.
|
|
1375
1378
|
*
|
|
1376
|
-
* @param name - The provider island's
|
|
1379
|
+
* @param name - The provider island's island name.
|
|
1377
1380
|
* @returns The provider's api, or `undefined`.
|
|
1378
1381
|
* @example
|
|
1379
|
-
* app.spa.
|
|
1382
|
+
* app.spa.island<LightboxApi>("lightbox")?.open(slides, 0);
|
|
1380
1383
|
*/
|
|
1381
|
-
|
|
1384
|
+
island<T = unknown>(name: string): T | undefined;
|
|
1382
1385
|
};
|
|
1383
1386
|
declare namespace types_d_exports {
|
|
1384
1387
|
export { Api$3 as Api, BuildCacheEntry, BuildEvents, BuildResult, BuildRunOverrides, Config$3 as Config, ExtractApi, OgFont, OgImageConfig, PhaseContext, PhaseEmit, PhaseLog, PhaseName, PhaseRequire, RenderCacheEntry, RichOgInput, RunOptions, State$3 as State };
|
|
@@ -2842,7 +2845,7 @@ type GalleryProps = {
|
|
|
2842
2845
|
/**
|
|
2843
2846
|
* A consumer-supplied gallery component: a Preact function component over
|
|
2844
2847
|
* {@link GalleryProps}, rendered (at build time, to static markup) as the inner
|
|
2845
|
-
* content — inside the framework-owned `<div data-
|
|
2848
|
+
* content — inside the framework-owned `<div data-island="gallery">` that carries
|
|
2846
2849
|
* the island hook. Defaults to the built-in `GalleryTrack`.
|
|
2847
2850
|
*/
|
|
2848
2851
|
type GalleryComponent = FunctionComponent<GalleryProps>;
|
|
@@ -3515,43 +3518,43 @@ declare const routerPlugin: import("@moku-labs/core").PluginInstance<"router", R
|
|
|
3515
3518
|
*/
|
|
3516
3519
|
declare const sitePlugin: import("@moku-labs/core").PluginInstance<"site", Config$7, Record<string, never>, Api$7, {}> & Record<never, never>;
|
|
3517
3520
|
//#endregion
|
|
3518
|
-
//#region src/plugins/spa/
|
|
3521
|
+
//#region src/plugins/spa/islands.d.ts
|
|
3519
3522
|
/**
|
|
3520
|
-
* Create a validated
|
|
3521
|
-
* (`
|
|
3522
|
-
* (`
|
|
3523
|
+
* Create a validated island definition. Accepts either the legacy hooks-only form
|
|
3524
|
+
* (`createIsland("counter", { onMount() {} })`) or the plugin-mirror spec form
|
|
3525
|
+
* (`createIsland("board", { state, render, events, api, ...hooks })`). Spec-only
|
|
3523
3526
|
* keys (`state`/`render`/`events`/`api`) are partitioned out before hook-name
|
|
3524
3527
|
* validation, so a real typo (e.g. `onMout`) still throws immediately while the spec
|
|
3525
3528
|
* keys are accepted.
|
|
3526
3529
|
*
|
|
3527
|
-
* @param name - Unique
|
|
3530
|
+
* @param name - Unique island name.
|
|
3528
3531
|
* @param spec - Lifecycle hooks, or the `{ state, render, events, api, ...hooks }` spec.
|
|
3529
|
-
* @returns A `
|
|
3532
|
+
* @returns A `IslandDef` ready to `register`.
|
|
3530
3533
|
* @throws {Error} If `name` is empty, a hook key is unknown, or an extra/hook value has the wrong shape.
|
|
3531
3534
|
* @example
|
|
3532
|
-
* const counter =
|
|
3535
|
+
* const counter = createIsland("counter", { onMount({ el }) { el.textContent = "0"; } });
|
|
3533
3536
|
* @example
|
|
3534
|
-
* const list =
|
|
3537
|
+
* const list = createIsland<{ items: string[] }>("list", {
|
|
3535
3538
|
* state: () => ({ items: [] }),
|
|
3536
3539
|
* render: (s) => h(List, { items: s.items })
|
|
3537
3540
|
* });
|
|
3538
3541
|
*/
|
|
3539
|
-
declare function
|
|
3542
|
+
declare function createIsland<S extends object = object, A = unknown>(name: string, spec: IslandSpec<S, A>): IslandDef;
|
|
3540
3543
|
//#endregion
|
|
3541
3544
|
//#region src/plugins/spa/lazy-embed.d.ts
|
|
3542
3545
|
/**
|
|
3543
3546
|
* Lazy-embed island: facade button click → real `<iframe loading="lazy">`.
|
|
3544
3547
|
* The companion of the content pipeline's `::embed` directive.
|
|
3545
3548
|
*/
|
|
3546
|
-
declare const lazyEmbed:
|
|
3549
|
+
declare const lazyEmbed: IslandDef;
|
|
3547
3550
|
//#endregion
|
|
3548
3551
|
//#region src/plugins/spa/index.d.ts
|
|
3549
3552
|
/**
|
|
3550
3553
|
* SPA plugin — progressive client-side navigation layered over the static site:
|
|
3551
3554
|
* swaps a page region on navigation, with an optional progress bar and View
|
|
3552
|
-
* Transitions. Register interactive islands with {@link
|
|
3553
|
-
* on router and head; emits `spa:navigate`, `spa:navigated`, `spa:
|
|
3554
|
-
* and `spa:
|
|
3555
|
+
* Transitions. Register interactive islands with {@link createIsland}. Depends
|
|
3556
|
+
* on router and head; emits `spa:navigate`, `spa:navigated`, `spa:island-mount`,
|
|
3557
|
+
* and `spa:island-unmount`.
|
|
3555
3558
|
*
|
|
3556
3559
|
* @example Enable view transitions and a custom swap region
|
|
3557
3560
|
* ```ts
|
|
@@ -3574,11 +3577,11 @@ declare const spaPlugin: import("@moku-labs/core").PluginInstance<"spa", SpaConf
|
|
|
3574
3577
|
"spa:navigated": {
|
|
3575
3578
|
url: string;
|
|
3576
3579
|
};
|
|
3577
|
-
"spa:
|
|
3580
|
+
"spa:island-mount": {
|
|
3578
3581
|
name: string;
|
|
3579
3582
|
el: Element;
|
|
3580
3583
|
};
|
|
3581
|
-
"spa:
|
|
3584
|
+
"spa:island-unmount": {
|
|
3582
3585
|
name: string;
|
|
3583
3586
|
el: Element;
|
|
3584
3587
|
};
|
|
@@ -3689,11 +3692,11 @@ declare const createApp: <const ExtraPlugins extends readonly import("@moku-labs
|
|
|
3689
3692
|
"spa:navigated": {
|
|
3690
3693
|
url: string;
|
|
3691
3694
|
};
|
|
3692
|
-
"spa:
|
|
3695
|
+
"spa:island-mount": {
|
|
3693
3696
|
name: string;
|
|
3694
3697
|
el: Element;
|
|
3695
3698
|
};
|
|
3696
|
-
"spa:
|
|
3699
|
+
"spa:island-unmount": {
|
|
3697
3700
|
name: string;
|
|
3698
3701
|
el: Element;
|
|
3699
3702
|
};
|
|
@@ -3718,11 +3721,11 @@ declare const createApp: <const ExtraPlugins extends readonly import("@moku-labs
|
|
|
3718
3721
|
"spa:navigated": {
|
|
3719
3722
|
url: string;
|
|
3720
3723
|
};
|
|
3721
|
-
"spa:
|
|
3724
|
+
"spa:island-mount": {
|
|
3722
3725
|
name: string;
|
|
3723
3726
|
el: Element;
|
|
3724
3727
|
};
|
|
3725
|
-
"spa:
|
|
3728
|
+
"spa:island-unmount": {
|
|
3726
3729
|
name: string;
|
|
3727
3730
|
el: Element;
|
|
3728
3731
|
};
|
|
@@ -3744,4 +3747,4 @@ declare const createApp: <const ExtraPlugins extends readonly import("@moku-labs
|
|
|
3744
3747
|
*/
|
|
3745
3748
|
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>]>>;
|
|
3746
3749
|
//#endregion
|
|
3747
|
-
export { types_d_exports as Build, 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,
|
|
3750
|
+
export { types_d_exports as Build, 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, createIsland, createPlugin, createUrls, dataPlugin, defineRoutes, deployPlugin, dotenv, envPlugin, feedLink, fileSystemContent, headPlugin, hreflang, i18nPlugin, jsonLd, lazyEmbed, logPlugin, meta, og, processEnv, route, routerPlugin, sitePlugin, spaPlugin, twitter };
|