@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 +1 -1
- package/dist/browser.d.mts +111 -108
- package/dist/browser.mjs +189 -189
- package/dist/index.cjs +226 -206
- package/dist/index.d.cts +124 -108
- package/dist/index.d.mts +124 -108
- package/dist/index.mjs +226 -206
- 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 +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -872,7 +872,7 @@ type Api$4 = {
|
|
|
872
872
|
composeTitle(head: HeadConfig | undefined): string;
|
|
873
873
|
};
|
|
874
874
|
declare namespace types_d_exports$7 {
|
|
875
|
-
export { AnyVNode,
|
|
875
|
+
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 };
|
|
876
876
|
}
|
|
877
877
|
/** Payload map for the events `spa` emits, used to type the kernel's `emit` closure. */
|
|
878
878
|
type SpaEvents = {
|
|
@@ -882,12 +882,12 @@ type SpaEvents = {
|
|
|
882
882
|
}; /** The swap completed and the new URL is active. */
|
|
883
883
|
"spa:navigated": {
|
|
884
884
|
url: string;
|
|
885
|
-
}; /** A
|
|
886
|
-
"spa:
|
|
885
|
+
}; /** A island instance attached to an element. */
|
|
886
|
+
"spa:island-mount": {
|
|
887
887
|
name: string;
|
|
888
888
|
el: Element;
|
|
889
|
-
}; /** A
|
|
890
|
-
"spa:
|
|
889
|
+
}; /** A island instance detached from an element. */
|
|
890
|
+
"spa:island-unmount": {
|
|
891
891
|
name: string;
|
|
892
892
|
el: Element;
|
|
893
893
|
};
|
|
@@ -956,10 +956,10 @@ type SpaConfig = {
|
|
|
956
956
|
*/
|
|
957
957
|
progressBar?: boolean;
|
|
958
958
|
/**
|
|
959
|
-
*
|
|
959
|
+
* Islands to auto-register at init (in addition to runtime `register`).
|
|
960
960
|
* Defaults to an empty array.
|
|
961
961
|
*/
|
|
962
|
-
|
|
962
|
+
islands?: IslandDef[];
|
|
963
963
|
};
|
|
964
964
|
/** Resolved SPA config after defaults are applied. */
|
|
965
965
|
interface ResolvedSpaConfig {
|
|
@@ -969,11 +969,11 @@ interface ResolvedSpaConfig {
|
|
|
969
969
|
viewTransitions: boolean;
|
|
970
970
|
/** Whether the progress bar is enabled. */
|
|
971
971
|
progressBar: boolean;
|
|
972
|
-
/** Pre-registered
|
|
973
|
-
|
|
972
|
+
/** Pre-registered islands. */
|
|
973
|
+
islands: IslandDef[];
|
|
974
974
|
}
|
|
975
975
|
/**
|
|
976
|
-
* What a
|
|
976
|
+
* What a island's `render` may return:
|
|
977
977
|
* - a Preact `VNode` — committed into the host through the lazy Preact gate (`commitVNode`);
|
|
978
978
|
* - a `Node` — replaces the host's children;
|
|
979
979
|
* - a `string` — set as the host's `innerHTML`;
|
|
@@ -985,30 +985,33 @@ type RenderResult = AnyVNode | Node | string | void;
|
|
|
985
985
|
* `VNode<SomeProps>`; the props generic is invariant under `exactOptionalPropertyTypes`,
|
|
986
986
|
* so the only supertype that accepts every concrete `VNode<P>` is `VNode<any>`.
|
|
987
987
|
*/
|
|
988
|
+
/**
|
|
989
|
+
*
|
|
990
|
+
*/
|
|
988
991
|
type AnyVNode = import("preact").VNode<any>;
|
|
989
992
|
/**
|
|
990
|
-
* Factory that builds a
|
|
993
|
+
* Factory that builds a island's typed per-instance state (mirrors a plugin's
|
|
991
994
|
* `createState`). Called ONCE at mount; the returned object is stored on the
|
|
992
|
-
* {@link
|
|
995
|
+
* {@link IslandInstance} and exposed read-only as `ctx.state`.
|
|
993
996
|
*
|
|
994
|
-
* @param ctx - The
|
|
997
|
+
* @param ctx - The island context for this instance (state is not yet set).
|
|
995
998
|
* @returns The initial per-instance state.
|
|
996
999
|
* @example
|
|
997
1000
|
* state: (ctx): BoardState => ({ boardId: ctx.params.id ?? "", cards: [] })
|
|
998
1001
|
*/
|
|
999
|
-
type
|
|
1002
|
+
type IslandStateFactory<S extends object> = (ctx: IslandContext<S>) => S;
|
|
1000
1003
|
/**
|
|
1001
1004
|
* Pure render of `(state, ctx)` → {@link RenderResult}. Called after mount-state-init
|
|
1002
1005
|
* and again (microtask-batched) after every `ctx.set`. Must be free of side effects
|
|
1003
1006
|
* beyond producing its result.
|
|
1004
1007
|
*
|
|
1005
1008
|
* @param state - The current per-instance state (read-only).
|
|
1006
|
-
* @param ctx - The
|
|
1009
|
+
* @param ctx - The island context for this instance.
|
|
1007
1010
|
* @returns The render result to commit into the host.
|
|
1008
1011
|
* @example
|
|
1009
1012
|
* render: (state) => h(BoardView, { snapshot: state.snapshot })
|
|
1010
1013
|
*/
|
|
1011
|
-
type
|
|
1014
|
+
type IslandRender<S extends object> = (state: Readonly<S>, ctx: IslandContext<S>) => RenderResult;
|
|
1012
1015
|
/**
|
|
1013
1016
|
* A delegated DOM event handler. `target` is the element matched by the key's selector
|
|
1014
1017
|
* (already resolved via `closest` — no `instanceof`/`closest` ceremony in the body).
|
|
@@ -1016,14 +1019,14 @@ type ComponentRender<S extends object> = (state: Readonly<S>, ctx: ComponentCont
|
|
|
1016
1019
|
* Typed `void` for ergonomics (the void-return rule accepts async handlers returning
|
|
1017
1020
|
* `Promise<void>` too); the kernel ignores any returned value.
|
|
1018
1021
|
*
|
|
1019
|
-
* @param ctx - The
|
|
1022
|
+
* @param ctx - The island context (carries the live per-instance `state`).
|
|
1020
1023
|
* @param event - The raw DOM event.
|
|
1021
1024
|
* @param target - The element matched by the selector (the host when no selector).
|
|
1022
1025
|
* @returns void (a returned promise is ignored by the kernel).
|
|
1023
1026
|
* @example
|
|
1024
1027
|
* (ctx, event, button) => { event.preventDefault(); ctx.set({ open: true }); }
|
|
1025
1028
|
*/
|
|
1026
|
-
type
|
|
1029
|
+
type IslandEventHandler<S extends object> = (ctx: IslandContext<S>, event: Event, target: Element) => void;
|
|
1027
1030
|
/**
|
|
1028
1031
|
* Declarative delegated event map. Each key is `"<type> <selector>"` (the selector is
|
|
1029
1032
|
* optional → a host-level listener). ONE real listener per event TYPE is attached to
|
|
@@ -1036,9 +1039,9 @@ type ComponentEventHandler<S extends object> = (ctx: ComponentContext<S>, event:
|
|
|
1036
1039
|
* "submit [data-add]": (ctx, e) => { e.preventDefault(); add(ctx); }
|
|
1037
1040
|
* }
|
|
1038
1041
|
*/
|
|
1039
|
-
type
|
|
1042
|
+
type IslandEvents<S extends object> = Record<string, IslandEventHandler<S>>;
|
|
1040
1043
|
/**
|
|
1041
|
-
* Context handed to every
|
|
1044
|
+
* Context handed to every island lifecycle hook, render, and event handler — the
|
|
1042
1045
|
* bound element + page data, plus the matched route's `params`/`meta`/`locale` and a
|
|
1043
1046
|
* link builder, so an island can read its route context (e.g. a `card` route's
|
|
1044
1047
|
* `ctx.meta.focus` + `ctx.params.id`) directly, without the page bridging it through
|
|
@@ -1046,11 +1049,11 @@ type ComponentEvents<S extends object> = Record<string, ComponentEventHandler<S>
|
|
|
1046
1049
|
*
|
|
1047
1050
|
* Generic over the per-instance state `S` (default `undefined` so every existing
|
|
1048
1051
|
* hooks-only island still type-checks). The additive members (`state`/`set`/`flush`/
|
|
1049
|
-
* `cleanup`/`
|
|
1052
|
+
* `cleanup`/`island`) are ALWAYS-PRESENT functions — never optional keys — so they
|
|
1050
1053
|
* never trip `exactOptionalPropertyTypes`.
|
|
1051
1054
|
*/
|
|
1052
|
-
interface
|
|
1053
|
-
/** The element the
|
|
1055
|
+
interface IslandContext<S = undefined> {
|
|
1056
|
+
/** The element the island instance is bound to. */
|
|
1054
1057
|
el: Element;
|
|
1055
1058
|
/** Page data extracted from the `script#__DATA__` payload. */
|
|
1056
1059
|
data: PageData;
|
|
@@ -1099,128 +1102,128 @@ interface ComponentContext<S = undefined> {
|
|
|
1099
1102
|
* Resolve another island's registered `api` by name. Returns `undefined` when no
|
|
1100
1103
|
* provider is registered (optional-dependency semantics, mirroring `ctx.has`).
|
|
1101
1104
|
*
|
|
1102
|
-
* @param name - The provider island's
|
|
1105
|
+
* @param name - The provider island's island name.
|
|
1103
1106
|
* @returns The provider's api, or `undefined`.
|
|
1104
1107
|
* @example
|
|
1105
|
-
* ctx.
|
|
1108
|
+
* ctx.island<LightboxApi>("lightbox")?.open(slides, index);
|
|
1106
1109
|
*/
|
|
1107
|
-
|
|
1110
|
+
island<T = unknown>(name: string): T | undefined;
|
|
1108
1111
|
}
|
|
1109
|
-
/** Lifecycle hooks a
|
|
1110
|
-
interface
|
|
1112
|
+
/** Lifecycle hooks a island may implement. Generic over the per-instance state `S`. */
|
|
1113
|
+
interface IslandHooks<S = undefined> {
|
|
1111
1114
|
/**
|
|
1112
1115
|
* Called once when the instance is created (before DOM attach).
|
|
1113
1116
|
*
|
|
1114
|
-
* @param ctx - The
|
|
1117
|
+
* @param ctx - The island context for this instance.
|
|
1115
1118
|
* @returns void
|
|
1116
1119
|
* @example
|
|
1117
1120
|
* onCreate({ el }) { el.dataset.ready = "1"; }
|
|
1118
1121
|
*/
|
|
1119
|
-
onCreate?(ctx:
|
|
1122
|
+
onCreate?(ctx: IslandContext<S>): void;
|
|
1120
1123
|
/**
|
|
1121
1124
|
* Called after the instance is attached to its element.
|
|
1122
1125
|
*
|
|
1123
|
-
* @param ctx - The
|
|
1126
|
+
* @param ctx - The island context for this instance.
|
|
1124
1127
|
* @returns void
|
|
1125
1128
|
* @example
|
|
1126
1129
|
* onMount({ el }) { el.textContent = "0"; }
|
|
1127
1130
|
* @example
|
|
1128
1131
|
* async onMount(ctx) { ctx.set({ items: await load() }); } // async is allowed; the harness awaits it via settle()
|
|
1129
1132
|
*/
|
|
1130
|
-
onMount?(ctx:
|
|
1133
|
+
onMount?(ctx: IslandContext<S>): void;
|
|
1131
1134
|
/**
|
|
1132
1135
|
* Called when a navigation begins while this instance is mounted.
|
|
1133
1136
|
*
|
|
1134
|
-
* @param ctx - The
|
|
1137
|
+
* @param ctx - The island context for this instance.
|
|
1135
1138
|
* @returns void
|
|
1136
1139
|
* @example
|
|
1137
1140
|
* onNavStart({ el }) { el.dataset.loading = ""; }
|
|
1138
1141
|
*/
|
|
1139
|
-
onNavStart?(ctx:
|
|
1142
|
+
onNavStart?(ctx: IslandContext<S>): void;
|
|
1140
1143
|
/**
|
|
1141
1144
|
* Called when a navigation completes while this instance is mounted.
|
|
1142
1145
|
*
|
|
1143
|
-
* @param ctx - The
|
|
1146
|
+
* @param ctx - The island context for this instance.
|
|
1144
1147
|
* @returns void
|
|
1145
1148
|
* @example
|
|
1146
1149
|
* onNavEnd({ el }) { delete el.dataset.loading; }
|
|
1147
1150
|
*/
|
|
1148
|
-
onNavEnd?(ctx:
|
|
1151
|
+
onNavEnd?(ctx: IslandContext<S>): void;
|
|
1149
1152
|
/**
|
|
1150
1153
|
* Called before the instance is detached from its element.
|
|
1151
1154
|
*
|
|
1152
|
-
* @param ctx - The
|
|
1155
|
+
* @param ctx - The island context for this instance.
|
|
1153
1156
|
* @returns void
|
|
1154
1157
|
* @example
|
|
1155
1158
|
* onUnMount({ el }) { el.replaceChildren(); }
|
|
1156
1159
|
*/
|
|
1157
|
-
onUnMount?(ctx:
|
|
1160
|
+
onUnMount?(ctx: IslandContext<S>): void;
|
|
1158
1161
|
/**
|
|
1159
1162
|
* Called once when the instance is destroyed (after detach).
|
|
1160
1163
|
*
|
|
1161
|
-
* @param ctx - The
|
|
1164
|
+
* @param ctx - The island context for this instance.
|
|
1162
1165
|
* @returns void
|
|
1163
1166
|
* @example
|
|
1164
1167
|
* onDestroy({ el }) { delete el.dataset.ready; }
|
|
1165
1168
|
*/
|
|
1166
|
-
onDestroy?(ctx:
|
|
1169
|
+
onDestroy?(ctx: IslandContext<S>): void;
|
|
1167
1170
|
}
|
|
1168
1171
|
/** Allowed hook names — single source of truth for fail-fast validation. */
|
|
1169
|
-
declare const
|
|
1172
|
+
declare const ISLAND_HOOK_NAMES: readonly ["onCreate", "onMount", "onNavStart", "onNavEnd", "onUnMount", "onDestroy"];
|
|
1170
1173
|
/**
|
|
1171
|
-
* The plugin-mirror authoring form for {@link
|
|
1174
|
+
* The plugin-mirror authoring form for {@link createIsland}: typed per-instance
|
|
1172
1175
|
* `state`, `render`, declarative `events`, and a cross-island `api` on top of the
|
|
1173
1176
|
* lifecycle hooks. All keys optional + additive; the presence of any spec-only key
|
|
1174
|
-
* (`state`/`render`/`events`/`api`) selects the spec overload of `
|
|
1177
|
+
* (`state`/`render`/`events`/`api`) selects the spec overload of `createIsland`.
|
|
1175
1178
|
*
|
|
1176
1179
|
* @example
|
|
1177
|
-
*
|
|
1180
|
+
* createIsland<{ boards: Board[] }>("board-list", {
|
|
1178
1181
|
* state: () => ({ boards: [] }),
|
|
1179
|
-
* async onMount(ctx) { ctx.set({ boards: await ctx.
|
|
1182
|
+
* async onMount(ctx) { ctx.set({ boards: await ctx.island<Api>("api")!.list() }); },
|
|
1180
1183
|
* render: (s) => h(BoardList, { boards: s.boards }),
|
|
1181
1184
|
* events: { "submit [data-create]": (ctx, e) => { e.preventDefault(); create(ctx); } }
|
|
1182
1185
|
* });
|
|
1183
1186
|
*/
|
|
1184
|
-
interface
|
|
1187
|
+
interface IslandSpec<S extends object = object, A = unknown> extends IslandHooks<S> {
|
|
1185
1188
|
/** Build typed per-instance state at mount (stored on the instance, not a module WeakMap). */
|
|
1186
|
-
state?:
|
|
1189
|
+
state?: IslandStateFactory<S>;
|
|
1187
1190
|
/** Pure render re-invoked (microtask-batched) on every `ctx.set`. */
|
|
1188
|
-
render?:
|
|
1191
|
+
render?: IslandRender<S>;
|
|
1189
1192
|
/** Declarative delegated DOM events with auto-teardown. */
|
|
1190
|
-
events?:
|
|
1191
|
-
/** Public api factory — registered under the
|
|
1192
|
-
api?: (ctx:
|
|
1193
|
+
events?: IslandEvents<S>;
|
|
1194
|
+
/** Public api factory — registered under the island name; reached via `app.spa.island(name)`. */
|
|
1195
|
+
api?: (ctx: IslandContext<S>) => A;
|
|
1193
1196
|
}
|
|
1194
1197
|
/**
|
|
1195
|
-
* The spec extras carried on a {@link
|
|
1196
|
-
* (authors keep full `S` inference at the `
|
|
1198
|
+
* The spec extras carried on a {@link IslandDef}, type-erased to `object` state
|
|
1199
|
+
* (authors keep full `S` inference at the `createIsland` call site; the registry
|
|
1197
1200
|
* stores the runtime-only erased form). Absent for legacy `(name, hooks)` defs.
|
|
1198
1201
|
*/
|
|
1199
|
-
interface
|
|
1202
|
+
interface IslandSpecExtras {
|
|
1200
1203
|
/** Per-instance state factory. */
|
|
1201
|
-
state?:
|
|
1204
|
+
state?: IslandStateFactory<object>;
|
|
1202
1205
|
/** Render called on mount + after every `ctx.set`. */
|
|
1203
|
-
render?:
|
|
1206
|
+
render?: IslandRender<object>;
|
|
1204
1207
|
/** Declarative delegated events. */
|
|
1205
|
-
events?:
|
|
1206
|
-
/** Public api factory registered under the
|
|
1207
|
-
api?: (ctx:
|
|
1208
|
+
events?: IslandEvents<object>;
|
|
1209
|
+
/** Public api factory registered under the island name. */
|
|
1210
|
+
api?: (ctx: IslandContext<object>) => unknown;
|
|
1208
1211
|
}
|
|
1209
|
-
/** A registered
|
|
1210
|
-
interface
|
|
1211
|
-
/** Unique
|
|
1212
|
+
/** A registered island definition (an opaque token; author inference lives on `createIsland`). */
|
|
1213
|
+
interface IslandDef {
|
|
1214
|
+
/** Unique island name (matched against `data-island`). */
|
|
1212
1215
|
name: string;
|
|
1213
1216
|
/** Lifecycle hooks (the subset shared with the legacy form). */
|
|
1214
|
-
hooks:
|
|
1217
|
+
hooks: IslandHooks<object>;
|
|
1215
1218
|
/** Plugin-mirror extras (state/render/events/api). Absent for legacy `(name, hooks)` defs. */
|
|
1216
|
-
spec?:
|
|
1219
|
+
spec?: IslandSpecExtras;
|
|
1217
1220
|
}
|
|
1218
1221
|
/** The matched-route slice carried on a live instance (params/meta/locale + link builder). */
|
|
1219
|
-
type
|
|
1220
|
-
/** A live, mounted
|
|
1221
|
-
interface
|
|
1222
|
+
type IslandRouteSlice = Pick<IslandContext, "params" | "meta" | "locale" | "url">;
|
|
1223
|
+
/** A live, mounted island instance. */
|
|
1224
|
+
interface IslandInstance {
|
|
1222
1225
|
/** The definition this instance was created from. */
|
|
1223
|
-
def:
|
|
1226
|
+
def: IslandDef;
|
|
1224
1227
|
/** The element this instance is bound to. */
|
|
1225
1228
|
el: Element;
|
|
1226
1229
|
/**
|
|
@@ -1230,13 +1233,13 @@ interface ComponentInstance {
|
|
|
1230
1233
|
*/
|
|
1231
1234
|
persistent: boolean;
|
|
1232
1235
|
/** The single per-instance context reused by every hook, event handler, and render. */
|
|
1233
|
-
ctx:
|
|
1236
|
+
ctx: IslandContext<object>;
|
|
1234
1237
|
/** Live per-instance state (the object returned by `spec.state`), or undefined for hooks-only islands. */
|
|
1235
1238
|
state: object | undefined;
|
|
1236
1239
|
/** This instance's public api (the object returned by `spec.api`), or undefined when none declared. */
|
|
1237
1240
|
api: unknown;
|
|
1238
1241
|
/** Current matched-route slice (updated on navigation; read by `ctx.params/meta/locale/url`). */
|
|
1239
|
-
route:
|
|
1242
|
+
route: IslandRouteSlice;
|
|
1240
1243
|
/** Current page data payload (updated on navigation; read by `ctx.data`). */
|
|
1241
1244
|
data: PageData;
|
|
1242
1245
|
/** Disposers from `ctx.cleanup` + the declarative `events` listeners — run LIFO on destroy. */
|
|
@@ -1276,7 +1279,7 @@ interface SpaKernelDeps {
|
|
|
1276
1279
|
/** The single shared SPA kernel — pure factory over state/config/emit/deps. */
|
|
1277
1280
|
interface SpaKernel {
|
|
1278
1281
|
/**
|
|
1279
|
-
* Validate config, register config.
|
|
1282
|
+
* Validate config, register config.islands, seed currentUrl.
|
|
1280
1283
|
*
|
|
1281
1284
|
* @returns void
|
|
1282
1285
|
* @example
|
|
@@ -1292,14 +1295,14 @@ interface SpaKernel {
|
|
|
1292
1295
|
*/
|
|
1293
1296
|
boot(): void;
|
|
1294
1297
|
/**
|
|
1295
|
-
* Register a
|
|
1298
|
+
* Register a island definition (last-registered-wins).
|
|
1296
1299
|
*
|
|
1297
|
-
* @param
|
|
1300
|
+
* @param island - The island definition to register.
|
|
1298
1301
|
* @returns void
|
|
1299
1302
|
* @example
|
|
1300
1303
|
* kernel.register(counter);
|
|
1301
1304
|
*/
|
|
1302
|
-
register(
|
|
1305
|
+
register(island: IslandDef): void;
|
|
1303
1306
|
/**
|
|
1304
1307
|
* Process a navigation to `path`: fetch then swap then head-sync then emit.
|
|
1305
1308
|
*
|
|
@@ -1310,7 +1313,7 @@ interface SpaKernel {
|
|
|
1310
1313
|
*/
|
|
1311
1314
|
processNav(path: string): void;
|
|
1312
1315
|
/**
|
|
1313
|
-
* Query the swap region and mount
|
|
1316
|
+
* Query the swap region and mount islands for matching elements.
|
|
1314
1317
|
*
|
|
1315
1318
|
* @returns void
|
|
1316
1319
|
* @example
|
|
@@ -1328,12 +1331,12 @@ interface SpaKernel {
|
|
|
1328
1331
|
}
|
|
1329
1332
|
/** Internal mutable state for the spa plugin (all kernel data lives here). */
|
|
1330
1333
|
interface SpaState {
|
|
1331
|
-
/**
|
|
1332
|
-
|
|
1333
|
-
/** Live
|
|
1334
|
-
instances: Map<Element,
|
|
1335
|
-
/** Registered island apis by
|
|
1336
|
-
|
|
1334
|
+
/** Islands registered by name (last-registered-wins). */
|
|
1335
|
+
registeredIslands: Map<string, IslandDef>;
|
|
1336
|
+
/** Live island instances keyed by their bound element. */
|
|
1337
|
+
instances: Map<Element, IslandInstance>;
|
|
1338
|
+
/** Registered island apis by island name (the cross-island `ctx.island`/`app.spa.island` seam). */
|
|
1339
|
+
islandApis: Map<string, unknown>;
|
|
1337
1340
|
/** The current resolved URL (pathname + search). */
|
|
1338
1341
|
currentUrl: string;
|
|
1339
1342
|
/** Teardown handle for the attached router listeners (null when detached). */
|
|
@@ -1346,14 +1349,14 @@ interface SpaState {
|
|
|
1346
1349
|
/** Public API of the spa plugin (registration / control surface). */
|
|
1347
1350
|
type SpaApi = {
|
|
1348
1351
|
/**
|
|
1349
|
-
* Register a
|
|
1352
|
+
* Register a island definition for client mounting.
|
|
1350
1353
|
*
|
|
1351
|
-
* @param
|
|
1354
|
+
* @param island - The island definition created via `createIsland`.
|
|
1352
1355
|
* @returns void
|
|
1353
1356
|
* @example
|
|
1354
1357
|
* app.spa.register(counter);
|
|
1355
1358
|
*/
|
|
1356
|
-
register(
|
|
1359
|
+
register(island: IslandDef): void;
|
|
1357
1360
|
/**
|
|
1358
1361
|
* Programmatically navigate to a path (client runtime; no-op without a DOM).
|
|
1359
1362
|
*
|
|
@@ -1375,12 +1378,12 @@ type SpaApi = {
|
|
|
1375
1378
|
* Resolve a registered island's api by name (the cross-island seam). Returns
|
|
1376
1379
|
* `undefined` when no provider with that name is currently registered.
|
|
1377
1380
|
*
|
|
1378
|
-
* @param name - The provider island's
|
|
1381
|
+
* @param name - The provider island's island name.
|
|
1379
1382
|
* @returns The provider's api, or `undefined`.
|
|
1380
1383
|
* @example
|
|
1381
|
-
* app.spa.
|
|
1384
|
+
* app.spa.island<LightboxApi>("lightbox")?.open(slides, 0);
|
|
1382
1385
|
*/
|
|
1383
|
-
|
|
1386
|
+
island<T = unknown>(name: string): T | undefined;
|
|
1384
1387
|
};
|
|
1385
1388
|
declare namespace types_d_exports {
|
|
1386
1389
|
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 };
|
|
@@ -2219,6 +2222,19 @@ type CliRenderer = {
|
|
|
2219
2222
|
* render.check(false, "CLOUDFLARE_API_TOKEN is set", "Create one at …");
|
|
2220
2223
|
*/
|
|
2221
2224
|
check(ok: boolean, label: string, detail?: string): void;
|
|
2225
|
+
/**
|
|
2226
|
+
* Mark the build TUI as externally driven. When `on`, the per-phase build tree and the BUILD
|
|
2227
|
+
* summary block are suppressed, so an external dev driver (e.g. the worker's `dev({ onChange })`
|
|
2228
|
+
* loop, which calls `update()` and renders its own concise rebuild line) is the sole source of
|
|
2229
|
+
* rebuild output — no duplicate full TUI on each incremental rebuild. Off by default; a standalone
|
|
2230
|
+
* `build()` / `serve()` keeps the full TUI.
|
|
2231
|
+
*
|
|
2232
|
+
* @param on - Whether an external driver owns the dev TUI.
|
|
2233
|
+
* @returns Nothing.
|
|
2234
|
+
* @example
|
|
2235
|
+
* render.setDriven(true);
|
|
2236
|
+
*/
|
|
2237
|
+
setDriven(on: boolean): void;
|
|
2222
2238
|
/**
|
|
2223
2239
|
* Stop any running animation (the live `serve()` idle pulse, a phase/rebuild spinner)
|
|
2224
2240
|
* and release the renderer's interval timer. Called by `serve()`'s SIGINT/SIGTERM
|
|
@@ -2831,7 +2847,7 @@ type GalleryProps = {
|
|
|
2831
2847
|
/**
|
|
2832
2848
|
* A consumer-supplied gallery component: a Preact function component over
|
|
2833
2849
|
* {@link GalleryProps}, rendered (at build time, to static markup) as the inner
|
|
2834
|
-
* content — inside the framework-owned `<div data-
|
|
2850
|
+
* content — inside the framework-owned `<div data-island="gallery">` that carries
|
|
2835
2851
|
* the island hook. Defaults to the built-in `GalleryTrack`.
|
|
2836
2852
|
*/
|
|
2837
2853
|
type GalleryComponent = FunctionComponent<GalleryProps>;
|
|
@@ -3504,43 +3520,43 @@ declare const routerPlugin: import("@moku-labs/core").PluginInstance<"router", R
|
|
|
3504
3520
|
*/
|
|
3505
3521
|
declare const sitePlugin: import("@moku-labs/core").PluginInstance<"site", Config$7, Record<string, never>, Api$7, {}> & Record<never, never>;
|
|
3506
3522
|
//#endregion
|
|
3507
|
-
//#region src/plugins/spa/
|
|
3523
|
+
//#region src/plugins/spa/islands.d.ts
|
|
3508
3524
|
/**
|
|
3509
|
-
* Create a validated
|
|
3510
|
-
* (`
|
|
3511
|
-
* (`
|
|
3525
|
+
* Create a validated island definition. Accepts either the legacy hooks-only form
|
|
3526
|
+
* (`createIsland("counter", { onMount() {} })`) or the plugin-mirror spec form
|
|
3527
|
+
* (`createIsland("board", { state, render, events, api, ...hooks })`). Spec-only
|
|
3512
3528
|
* keys (`state`/`render`/`events`/`api`) are partitioned out before hook-name
|
|
3513
3529
|
* validation, so a real typo (e.g. `onMout`) still throws immediately while the spec
|
|
3514
3530
|
* keys are accepted.
|
|
3515
3531
|
*
|
|
3516
|
-
* @param name - Unique
|
|
3532
|
+
* @param name - Unique island name.
|
|
3517
3533
|
* @param spec - Lifecycle hooks, or the `{ state, render, events, api, ...hooks }` spec.
|
|
3518
|
-
* @returns A `
|
|
3534
|
+
* @returns A `IslandDef` ready to `register`.
|
|
3519
3535
|
* @throws {Error} If `name` is empty, a hook key is unknown, or an extra/hook value has the wrong shape.
|
|
3520
3536
|
* @example
|
|
3521
|
-
* const counter =
|
|
3537
|
+
* const counter = createIsland("counter", { onMount({ el }) { el.textContent = "0"; } });
|
|
3522
3538
|
* @example
|
|
3523
|
-
* const list =
|
|
3539
|
+
* const list = createIsland<{ items: string[] }>("list", {
|
|
3524
3540
|
* state: () => ({ items: [] }),
|
|
3525
3541
|
* render: (s) => h(List, { items: s.items })
|
|
3526
3542
|
* });
|
|
3527
3543
|
*/
|
|
3528
|
-
declare function
|
|
3544
|
+
declare function createIsland<S extends object = object, A = unknown>(name: string, spec: IslandSpec<S, A>): IslandDef;
|
|
3529
3545
|
//#endregion
|
|
3530
3546
|
//#region src/plugins/spa/lazy-embed.d.ts
|
|
3531
3547
|
/**
|
|
3532
3548
|
* Lazy-embed island: facade button click → real `<iframe loading="lazy">`.
|
|
3533
3549
|
* The companion of the content pipeline's `::embed` directive.
|
|
3534
3550
|
*/
|
|
3535
|
-
declare const lazyEmbed:
|
|
3551
|
+
declare const lazyEmbed: IslandDef;
|
|
3536
3552
|
//#endregion
|
|
3537
3553
|
//#region src/plugins/spa/index.d.ts
|
|
3538
3554
|
/**
|
|
3539
3555
|
* SPA plugin — progressive client-side navigation layered over the static site:
|
|
3540
3556
|
* swaps a page region on navigation, with an optional progress bar and View
|
|
3541
|
-
* Transitions. Register interactive islands with {@link
|
|
3542
|
-
* on router and head; emits `spa:navigate`, `spa:navigated`, `spa:
|
|
3543
|
-
* and `spa:
|
|
3557
|
+
* Transitions. Register interactive islands with {@link createIsland}. Depends
|
|
3558
|
+
* on router and head; emits `spa:navigate`, `spa:navigated`, `spa:island-mount`,
|
|
3559
|
+
* and `spa:island-unmount`.
|
|
3544
3560
|
*
|
|
3545
3561
|
* @example Enable view transitions and a custom swap region
|
|
3546
3562
|
* ```ts
|
|
@@ -3563,11 +3579,11 @@ declare const spaPlugin: import("@moku-labs/core").PluginInstance<"spa", SpaConf
|
|
|
3563
3579
|
"spa:navigated": {
|
|
3564
3580
|
url: string;
|
|
3565
3581
|
};
|
|
3566
|
-
"spa:
|
|
3582
|
+
"spa:island-mount": {
|
|
3567
3583
|
name: string;
|
|
3568
3584
|
el: Element;
|
|
3569
3585
|
};
|
|
3570
|
-
"spa:
|
|
3586
|
+
"spa:island-unmount": {
|
|
3571
3587
|
name: string;
|
|
3572
3588
|
el: Element;
|
|
3573
3589
|
};
|
|
@@ -3678,11 +3694,11 @@ declare const createApp: <const ExtraPlugins extends readonly import("@moku-labs
|
|
|
3678
3694
|
"spa:navigated": {
|
|
3679
3695
|
url: string;
|
|
3680
3696
|
};
|
|
3681
|
-
"spa:
|
|
3697
|
+
"spa:island-mount": {
|
|
3682
3698
|
name: string;
|
|
3683
3699
|
el: Element;
|
|
3684
3700
|
};
|
|
3685
|
-
"spa:
|
|
3701
|
+
"spa:island-unmount": {
|
|
3686
3702
|
name: string;
|
|
3687
3703
|
el: Element;
|
|
3688
3704
|
};
|
|
@@ -3707,11 +3723,11 @@ declare const createApp: <const ExtraPlugins extends readonly import("@moku-labs
|
|
|
3707
3723
|
"spa:navigated": {
|
|
3708
3724
|
url: string;
|
|
3709
3725
|
};
|
|
3710
|
-
"spa:
|
|
3726
|
+
"spa:island-mount": {
|
|
3711
3727
|
name: string;
|
|
3712
3728
|
el: Element;
|
|
3713
3729
|
};
|
|
3714
|
-
"spa:
|
|
3730
|
+
"spa:island-unmount": {
|
|
3715
3731
|
name: string;
|
|
3716
3732
|
el: Element;
|
|
3717
3733
|
};
|
|
@@ -3733,4 +3749,4 @@ declare const createApp: <const ExtraPlugins extends readonly import("@moku-labs
|
|
|
3733
3749
|
*/
|
|
3734
3750
|
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>]>>;
|
|
3735
3751
|
//#endregion
|
|
3736
|
-
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,
|
|
3752
|
+
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 };
|