@moku-labs/web 1.15.0 → 1.16.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/dist/browser.d.mts +216 -26
- package/dist/browser.mjs +445 -84
- package/dist/index.cjs +473 -84
- package/dist/index.d.cts +249 -27
- package/dist/index.d.mts +249 -27
- package/dist/index.mjs +473 -84
- package/dist/{render-DLZEOe4M.cjs → render-KdufA3_b.cjs} +23 -0
- package/dist/{render-BNe0s7fr.mjs → render-UO4nimWr.mjs} +23 -1
- package/dist/testing.d.mts +383 -0
- package/dist/testing.mjs +847 -0
- package/package.json +7 -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 { COMPONENT_HOOK_NAMES, ComponentContext, ComponentDef, ComponentHooks, ComponentInstance, ExtractApi$1 as ExtractApi, PageData, ResolvedSpaConfig, SpaApi, SpaConfig, SpaContext, SpaDataReader, SpaEmitFunction, SpaEvents, SpaKernel, SpaKernelDeps, SpaRequire, SpaState };
|
|
875
|
+
export { COMPONENT_HOOK_NAMES, ComponentContext, ComponentDef, ComponentEventHandler, ComponentEvents, ComponentHooks, ComponentInstance, ComponentRender, ComponentRouteSlice, ComponentSpec, ComponentSpecExtras, ComponentStateFactory, ExtractApi$1 as ExtractApi, 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 = {
|
|
@@ -973,12 +973,77 @@ interface ResolvedSpaConfig {
|
|
|
973
973
|
components: ComponentDef[];
|
|
974
974
|
}
|
|
975
975
|
/**
|
|
976
|
-
*
|
|
977
|
-
*
|
|
978
|
-
*
|
|
979
|
-
*
|
|
976
|
+
* What a component's `render` may return:
|
|
977
|
+
* - a Preact `VNode` — committed into the host through the lazy Preact gate (`commitVNode`);
|
|
978
|
+
* - a `Node` — replaces the host's children;
|
|
979
|
+
* - a `string` — set as the host's `innerHTML`;
|
|
980
|
+
* - `void`/`undefined` — the render mutated the DOM itself (DOM-only islands → no Preact loaded).
|
|
980
981
|
*/
|
|
981
|
-
|
|
982
|
+
type RenderResult = import("preact").VNode | Node | string | void;
|
|
983
|
+
/**
|
|
984
|
+
* Factory that builds a component's typed per-instance state (mirrors a plugin's
|
|
985
|
+
* `createState`). Called ONCE at mount; the returned object is stored on the
|
|
986
|
+
* {@link ComponentInstance} and exposed read-only as `ctx.state`.
|
|
987
|
+
*
|
|
988
|
+
* @param ctx - The component context for this instance (state is not yet set).
|
|
989
|
+
* @returns The initial per-instance state.
|
|
990
|
+
* @example
|
|
991
|
+
* state: (ctx): BoardState => ({ boardId: ctx.params.id ?? "", cards: [] })
|
|
992
|
+
*/
|
|
993
|
+
type ComponentStateFactory<S extends object> = (ctx: ComponentContext<S>) => S;
|
|
994
|
+
/**
|
|
995
|
+
* Pure render of `(state, ctx)` → {@link RenderResult}. Called after mount-state-init
|
|
996
|
+
* and again (microtask-batched) after every `ctx.set`. Must be free of side effects
|
|
997
|
+
* beyond producing its result.
|
|
998
|
+
*
|
|
999
|
+
* @param state - The current per-instance state (read-only).
|
|
1000
|
+
* @param ctx - The component context for this instance.
|
|
1001
|
+
* @returns The render result to commit into the host.
|
|
1002
|
+
* @example
|
|
1003
|
+
* render: (state) => h(BoardView, { snapshot: state.snapshot })
|
|
1004
|
+
*/
|
|
1005
|
+
type ComponentRender<S extends object> = (state: Readonly<S>, ctx: ComponentContext<S>) => RenderResult;
|
|
1006
|
+
/**
|
|
1007
|
+
* A delegated DOM event handler. `target` is the element matched by the key's selector
|
|
1008
|
+
* (already resolved via `closest` — no `instanceof`/`closest` ceremony in the body).
|
|
1009
|
+
*
|
|
1010
|
+
* Typed `void` for ergonomics (the void-return rule accepts async handlers returning
|
|
1011
|
+
* `Promise<void>` too); the kernel ignores any returned value.
|
|
1012
|
+
*
|
|
1013
|
+
* @param ctx - The component context (carries the live per-instance `state`).
|
|
1014
|
+
* @param event - The raw DOM event.
|
|
1015
|
+
* @param target - The element matched by the selector (the host when no selector).
|
|
1016
|
+
* @returns void (a returned promise is ignored by the kernel).
|
|
1017
|
+
* @example
|
|
1018
|
+
* (ctx, event, button) => { event.preventDefault(); ctx.set({ open: true }); }
|
|
1019
|
+
*/
|
|
1020
|
+
type ComponentEventHandler<S extends object> = (ctx: ComponentContext<S>, event: Event, target: Element) => void;
|
|
1021
|
+
/**
|
|
1022
|
+
* Declarative delegated event map. Each key is `"<type> <selector>"` (the selector is
|
|
1023
|
+
* optional → a host-level listener). ONE real listener per event TYPE is attached to
|
|
1024
|
+
* the host; dispatch walks `event.target.closest(selector)` within the host. All
|
|
1025
|
+
* listeners are auto-removed on destroy.
|
|
1026
|
+
*
|
|
1027
|
+
* @example
|
|
1028
|
+
* events: {
|
|
1029
|
+
* "click [data-action='delete']": (ctx, _e, btn) => ctx.set(removeCard(ctx.state, btn)),
|
|
1030
|
+
* "submit [data-add]": (ctx, e) => { e.preventDefault(); add(ctx); }
|
|
1031
|
+
* }
|
|
1032
|
+
*/
|
|
1033
|
+
type ComponentEvents<S extends object> = Record<string, ComponentEventHandler<S>>;
|
|
1034
|
+
/**
|
|
1035
|
+
* Context handed to every component lifecycle hook, render, and event handler — the
|
|
1036
|
+
* bound element + page data, plus the matched route's `params`/`meta`/`locale` and a
|
|
1037
|
+
* link builder, so an island can read its route context (e.g. a `card` route's
|
|
1038
|
+
* `ctx.meta.focus` + `ctx.params.id`) directly, without the page bridging it through
|
|
1039
|
+
* `data-*` attributes.
|
|
1040
|
+
*
|
|
1041
|
+
* Generic over the per-instance state `S` (default `undefined` so every existing
|
|
1042
|
+
* hooks-only island still type-checks). The additive members (`state`/`set`/`flush`/
|
|
1043
|
+
* `cleanup`/`component`) are ALWAYS-PRESENT functions — never optional keys — so they
|
|
1044
|
+
* never trip `exactOptionalPropertyTypes`.
|
|
1045
|
+
*/
|
|
1046
|
+
interface ComponentContext<S = undefined> {
|
|
982
1047
|
/** The element the component instance is bound to. */
|
|
983
1048
|
el: Element;
|
|
984
1049
|
/** Page data extracted from the `script#__DATA__` payload. */
|
|
@@ -991,9 +1056,52 @@ interface ComponentContext {
|
|
|
991
1056
|
readonly locale: string;
|
|
992
1057
|
/** Build a link to a named route by pattern substitution (same output as `app.router.toUrl`). */
|
|
993
1058
|
readonly url: (name: string, params?: Record<string, string>) => string;
|
|
1059
|
+
/** The live per-instance state (the object returned by `spec.state`). `undefined` for legacy hooks-only islands. */
|
|
1060
|
+
readonly state: S;
|
|
1061
|
+
/**
|
|
1062
|
+
* Merge a patch into the per-instance state, then schedule ONE batched render.
|
|
1063
|
+
* Accepts a partial object or an updater `(prev) => partial`. A no-op for legacy
|
|
1064
|
+
* islands with no `state`/`render`.
|
|
1065
|
+
*
|
|
1066
|
+
* @param patch - A partial state object, or an updater returning one.
|
|
1067
|
+
* @returns void
|
|
1068
|
+
* @example
|
|
1069
|
+
* ctx.set({ open: true });
|
|
1070
|
+
* ctx.set(prev => ({ count: prev.count + 1 }));
|
|
1071
|
+
*/
|
|
1072
|
+
set(patch: Partial<S> | ((prev: Readonly<S>) => Partial<S>)): void;
|
|
1073
|
+
/**
|
|
1074
|
+
* Force a synchronous render now (drains any pending scheduled render). Rarely
|
|
1075
|
+
* needed in app code — `ctx.set` already schedules one; mainly a test seam.
|
|
1076
|
+
*
|
|
1077
|
+
* @returns void
|
|
1078
|
+
* @example
|
|
1079
|
+
* ctx.flush();
|
|
1080
|
+
*/
|
|
1081
|
+
flush(): void;
|
|
1082
|
+
/**
|
|
1083
|
+
* Register a disposer run on `onDestroy` (subscriptions, timers, manual/global
|
|
1084
|
+
* listeners the declarative `events` map cannot cover). Disposers run LIFO.
|
|
1085
|
+
*
|
|
1086
|
+
* @param dispose - The teardown function.
|
|
1087
|
+
* @returns void
|
|
1088
|
+
* @example
|
|
1089
|
+
* ctx.cleanup(onPatch(p => applyPatch(ctx, p)));
|
|
1090
|
+
*/
|
|
1091
|
+
cleanup(dispose: () => void): void;
|
|
1092
|
+
/**
|
|
1093
|
+
* Resolve another island's registered `api` by name. Returns `undefined` when no
|
|
1094
|
+
* provider is registered (optional-dependency semantics, mirroring `ctx.has`).
|
|
1095
|
+
*
|
|
1096
|
+
* @param name - The provider island's component name.
|
|
1097
|
+
* @returns The provider's api, or `undefined`.
|
|
1098
|
+
* @example
|
|
1099
|
+
* ctx.component<LightboxApi>("lightbox")?.open(slides, index);
|
|
1100
|
+
*/
|
|
1101
|
+
component<T = unknown>(name: string): T | undefined;
|
|
994
1102
|
}
|
|
995
|
-
/** Lifecycle hooks a component may implement. */
|
|
996
|
-
interface ComponentHooks {
|
|
1103
|
+
/** Lifecycle hooks a component may implement. Generic over the per-instance state `S`. */
|
|
1104
|
+
interface ComponentHooks<S = undefined> {
|
|
997
1105
|
/**
|
|
998
1106
|
* Called once when the instance is created (before DOM attach).
|
|
999
1107
|
*
|
|
@@ -1002,7 +1110,7 @@ interface ComponentHooks {
|
|
|
1002
1110
|
* @example
|
|
1003
1111
|
* onCreate({ el }) { el.dataset.ready = "1"; }
|
|
1004
1112
|
*/
|
|
1005
|
-
onCreate?(ctx: ComponentContext): void;
|
|
1113
|
+
onCreate?(ctx: ComponentContext<S>): void;
|
|
1006
1114
|
/**
|
|
1007
1115
|
* Called after the instance is attached to its element.
|
|
1008
1116
|
*
|
|
@@ -1010,8 +1118,10 @@ interface ComponentHooks {
|
|
|
1010
1118
|
* @returns void
|
|
1011
1119
|
* @example
|
|
1012
1120
|
* onMount({ el }) { el.textContent = "0"; }
|
|
1121
|
+
* @example
|
|
1122
|
+
* async onMount(ctx) { ctx.set({ items: await load() }); } // async is allowed; the harness awaits it via settle()
|
|
1013
1123
|
*/
|
|
1014
|
-
onMount?(ctx: ComponentContext): void;
|
|
1124
|
+
onMount?(ctx: ComponentContext<S>): void;
|
|
1015
1125
|
/**
|
|
1016
1126
|
* Called when a navigation begins while this instance is mounted.
|
|
1017
1127
|
*
|
|
@@ -1020,7 +1130,7 @@ interface ComponentHooks {
|
|
|
1020
1130
|
* @example
|
|
1021
1131
|
* onNavStart({ el }) { el.dataset.loading = ""; }
|
|
1022
1132
|
*/
|
|
1023
|
-
onNavStart?(ctx: ComponentContext): void;
|
|
1133
|
+
onNavStart?(ctx: ComponentContext<S>): void;
|
|
1024
1134
|
/**
|
|
1025
1135
|
* Called when a navigation completes while this instance is mounted.
|
|
1026
1136
|
*
|
|
@@ -1029,7 +1139,7 @@ interface ComponentHooks {
|
|
|
1029
1139
|
* @example
|
|
1030
1140
|
* onNavEnd({ el }) { delete el.dataset.loading; }
|
|
1031
1141
|
*/
|
|
1032
|
-
onNavEnd?(ctx: ComponentContext): void;
|
|
1142
|
+
onNavEnd?(ctx: ComponentContext<S>): void;
|
|
1033
1143
|
/**
|
|
1034
1144
|
* Called before the instance is detached from its element.
|
|
1035
1145
|
*
|
|
@@ -1038,7 +1148,7 @@ interface ComponentHooks {
|
|
|
1038
1148
|
* @example
|
|
1039
1149
|
* onUnMount({ el }) { el.replaceChildren(); }
|
|
1040
1150
|
*/
|
|
1041
|
-
onUnMount?(ctx: ComponentContext): void;
|
|
1151
|
+
onUnMount?(ctx: ComponentContext<S>): void;
|
|
1042
1152
|
/**
|
|
1043
1153
|
* Called once when the instance is destroyed (after detach).
|
|
1044
1154
|
*
|
|
@@ -1047,17 +1157,60 @@ interface ComponentHooks {
|
|
|
1047
1157
|
* @example
|
|
1048
1158
|
* onDestroy({ el }) { delete el.dataset.ready; }
|
|
1049
1159
|
*/
|
|
1050
|
-
onDestroy?(ctx: ComponentContext): void;
|
|
1160
|
+
onDestroy?(ctx: ComponentContext<S>): void;
|
|
1051
1161
|
}
|
|
1052
1162
|
/** Allowed hook names — single source of truth for fail-fast validation. */
|
|
1053
1163
|
declare const COMPONENT_HOOK_NAMES: readonly ["onCreate", "onMount", "onNavStart", "onNavEnd", "onUnMount", "onDestroy"];
|
|
1054
|
-
/**
|
|
1164
|
+
/**
|
|
1165
|
+
* The plugin-mirror authoring form for {@link createComponent}: typed per-instance
|
|
1166
|
+
* `state`, `render`, declarative `events`, and a cross-island `api` on top of the
|
|
1167
|
+
* lifecycle hooks. All keys optional + additive; the presence of any spec-only key
|
|
1168
|
+
* (`state`/`render`/`events`/`api`) selects the spec overload of `createComponent`.
|
|
1169
|
+
*
|
|
1170
|
+
* @example
|
|
1171
|
+
* createComponent<{ boards: Board[] }>("board-list", {
|
|
1172
|
+
* state: () => ({ boards: [] }),
|
|
1173
|
+
* async onMount(ctx) { ctx.set({ boards: await ctx.component<Api>("api")!.list() }); },
|
|
1174
|
+
* render: (s) => h(BoardList, { boards: s.boards }),
|
|
1175
|
+
* events: { "submit [data-create]": (ctx, e) => { e.preventDefault(); create(ctx); } }
|
|
1176
|
+
* });
|
|
1177
|
+
*/
|
|
1178
|
+
interface ComponentSpec<S extends object = object, A = unknown> extends ComponentHooks<S> {
|
|
1179
|
+
/** Build typed per-instance state at mount (stored on the instance, not a module WeakMap). */
|
|
1180
|
+
state?: ComponentStateFactory<S>;
|
|
1181
|
+
/** Pure render re-invoked (microtask-batched) on every `ctx.set`. */
|
|
1182
|
+
render?: ComponentRender<S>;
|
|
1183
|
+
/** Declarative delegated DOM events with auto-teardown. */
|
|
1184
|
+
events?: ComponentEvents<S>;
|
|
1185
|
+
/** Public api factory — registered under the component name; reached via `app.spa.component(name)`. */
|
|
1186
|
+
api?: (ctx: ComponentContext<S>) => A;
|
|
1187
|
+
}
|
|
1188
|
+
/**
|
|
1189
|
+
* The spec extras carried on a {@link ComponentDef}, type-erased to `object` state
|
|
1190
|
+
* (authors keep full `S` inference at the `createComponent` call site; the registry
|
|
1191
|
+
* stores the runtime-only erased form). Absent for legacy `(name, hooks)` defs.
|
|
1192
|
+
*/
|
|
1193
|
+
interface ComponentSpecExtras {
|
|
1194
|
+
/** Per-instance state factory. */
|
|
1195
|
+
state?: ComponentStateFactory<object>;
|
|
1196
|
+
/** Render called on mount + after every `ctx.set`. */
|
|
1197
|
+
render?: ComponentRender<object>;
|
|
1198
|
+
/** Declarative delegated events. */
|
|
1199
|
+
events?: ComponentEvents<object>;
|
|
1200
|
+
/** Public api factory registered under the component name. */
|
|
1201
|
+
api?: (ctx: ComponentContext<object>) => unknown;
|
|
1202
|
+
}
|
|
1203
|
+
/** A registered component definition (an opaque token; author inference lives on `createComponent`). */
|
|
1055
1204
|
interface ComponentDef {
|
|
1056
1205
|
/** Unique component name (matched against `data-component`). */
|
|
1057
1206
|
name: string;
|
|
1058
|
-
/** Lifecycle hooks. */
|
|
1059
|
-
hooks: ComponentHooks
|
|
1207
|
+
/** Lifecycle hooks (the subset shared with the legacy form). */
|
|
1208
|
+
hooks: ComponentHooks<object>;
|
|
1209
|
+
/** Plugin-mirror extras (state/render/events/api). Absent for legacy `(name, hooks)` defs. */
|
|
1210
|
+
spec?: ComponentSpecExtras;
|
|
1060
1211
|
}
|
|
1212
|
+
/** The matched-route slice carried on a live instance (params/meta/locale + link builder). */
|
|
1213
|
+
type ComponentRouteSlice = Pick<ComponentContext, "params" | "meta" | "locale" | "url">;
|
|
1061
1214
|
/** A live, mounted component instance. */
|
|
1062
1215
|
interface ComponentInstance {
|
|
1063
1216
|
/** The definition this instance was created from. */
|
|
@@ -1070,6 +1223,26 @@ interface ComponentInstance {
|
|
|
1070
1223
|
* page-specific: full unmount/destroy on every navigation.
|
|
1071
1224
|
*/
|
|
1072
1225
|
persistent: boolean;
|
|
1226
|
+
/** The single per-instance context reused by every hook, event handler, and render. */
|
|
1227
|
+
ctx: ComponentContext<object>;
|
|
1228
|
+
/** Live per-instance state (the object returned by `spec.state`), or undefined for hooks-only islands. */
|
|
1229
|
+
state: object | undefined;
|
|
1230
|
+
/** This instance's public api (the object returned by `spec.api`), or undefined when none declared. */
|
|
1231
|
+
api: unknown;
|
|
1232
|
+
/** Current matched-route slice (updated on navigation; read by `ctx.params/meta/locale/url`). */
|
|
1233
|
+
route: ComponentRouteSlice;
|
|
1234
|
+
/** Current page data payload (updated on navigation; read by `ctx.data`). */
|
|
1235
|
+
data: PageData;
|
|
1236
|
+
/** Disposers from `ctx.cleanup` + the declarative `events` listeners — run LIFO on destroy. */
|
|
1237
|
+
cleanups: Array<() => void>;
|
|
1238
|
+
/** Synchronously drain a pending render (the `ctx.flush` implementation). */
|
|
1239
|
+
flush: () => void;
|
|
1240
|
+
/** True while a render is queued for the next microtask — coalesces multiple `set` calls. */
|
|
1241
|
+
renderScheduled: boolean;
|
|
1242
|
+
/** Re-entrancy depth guard for the render scheduler (a render that calls `ctx.set`). */
|
|
1243
|
+
renderDepth: number;
|
|
1244
|
+
/** onMount's returned promise (+ render-module load) — awaited by the test harness's `settle()`. */
|
|
1245
|
+
mountPromise: Promise<void> | undefined;
|
|
1073
1246
|
}
|
|
1074
1247
|
/** Page data payload parsed from the inline `script#__DATA__` element. */
|
|
1075
1248
|
type PageData = Record<string, unknown>;
|
|
@@ -1153,6 +1326,8 @@ interface SpaState {
|
|
|
1153
1326
|
registeredComponents: Map<string, ComponentDef>;
|
|
1154
1327
|
/** Live component instances keyed by their bound element. */
|
|
1155
1328
|
instances: Map<Element, ComponentInstance>;
|
|
1329
|
+
/** Registered island apis by component name (the cross-island `ctx.component`/`app.spa.component` seam). */
|
|
1330
|
+
componentApis: Map<string, unknown>;
|
|
1156
1331
|
/** The current resolved URL (pathname + search). */
|
|
1157
1332
|
currentUrl: string;
|
|
1158
1333
|
/** Teardown handle for the attached router listeners (null when detached). */
|
|
@@ -1190,6 +1365,16 @@ type SpaApi = {
|
|
|
1190
1365
|
* const url = app.spa.current(); // "/about"
|
|
1191
1366
|
*/
|
|
1192
1367
|
current(): string;
|
|
1368
|
+
/**
|
|
1369
|
+
* Resolve a registered island's api by name (the cross-island seam). Returns
|
|
1370
|
+
* `undefined` when no provider with that name is currently registered.
|
|
1371
|
+
*
|
|
1372
|
+
* @param name - The provider island's component name.
|
|
1373
|
+
* @returns The provider's api, or `undefined`.
|
|
1374
|
+
* @example
|
|
1375
|
+
* app.spa.component<LightboxApi>("lightbox")?.open(slides, 0);
|
|
1376
|
+
*/
|
|
1377
|
+
component<T = unknown>(name: string): T | undefined;
|
|
1193
1378
|
};
|
|
1194
1379
|
declare namespace types_d_exports {
|
|
1195
1380
|
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 };
|
|
@@ -1856,7 +2041,7 @@ type Api$2 = {
|
|
|
1856
2041
|
createProject(): Promise<CreateProjectResult>;
|
|
1857
2042
|
};
|
|
1858
2043
|
declare namespace types_d_exports$1 {
|
|
1859
|
-
export { Api$1 as Api, BuildOptions, BuildSummary, CliErrorCode, CliRenderer, Command, Config$1 as Config, DeployOptions, DeployOutcome, FileResponseFunction, PreviewOptions, ReloadInfo, ServeOptions, ServeStaticFunction, ServeStaticOptions, ServerHandle, ServerInfo, State$1 as State, WatchHandle };
|
|
2044
|
+
export { Api$1 as Api, BuildOptions, BuildSummary, CliErrorCode, CliRenderer, Command, Config$1 as Config, DeployOptions, DeployOutcome, FileResponseFunction, PreviewOptions, ReloadInfo, ServeOptions, ServeStaticFunction, ServeStaticOptions, ServerHandle, ServerInfo, State$1 as State, UpdateOptions, WatchHandle };
|
|
1860
2045
|
}
|
|
1861
2046
|
/**
|
|
1862
2047
|
* A cli error `code` from the config-validation and runtime taxonomy. Mirrors the
|
|
@@ -2269,6 +2454,20 @@ type DeployOutcome = {
|
|
|
2269
2454
|
type BuildOptions = {
|
|
2270
2455
|
/** Assert `outDir/notFoundFile` exists after the build. Defaults to `true`. */assertNotFound?: boolean;
|
|
2271
2456
|
};
|
|
2457
|
+
/**
|
|
2458
|
+
* Options for `cli.update()` — the per-session dev-output opt-ins, mirroring the
|
|
2459
|
+
* relevant subset of {@link ServeOptions}. Each defaults to `false`: an incremental
|
|
2460
|
+
* rebuild skips expensive, preview-irrelevant outputs (OG images / sitemap / feeds)
|
|
2461
|
+
* for speed, and a flag re-enables that one output for the rebuild.
|
|
2462
|
+
*
|
|
2463
|
+
* @example
|
|
2464
|
+
* await app.cli.update(["src/styles.css"], { feeds: true });
|
|
2465
|
+
*/
|
|
2466
|
+
type UpdateOptions = {
|
|
2467
|
+
/** Re-enable OG-image generation for this rebuild. Defaults to `false`. */og?: boolean; /** Re-enable `sitemap.xml` + `robots.txt` for this rebuild. Defaults to `false`. */
|
|
2468
|
+
sitemap?: boolean; /** Re-enable RSS/Atom/JSON feeds for this rebuild. Defaults to `false`. */
|
|
2469
|
+
feeds?: boolean;
|
|
2470
|
+
};
|
|
2272
2471
|
/**
|
|
2273
2472
|
* Options for `cli.serve()`.
|
|
2274
2473
|
*
|
|
@@ -2330,6 +2529,24 @@ type Api$1 = {
|
|
|
2330
2529
|
* const summary = await app.cli.build();
|
|
2331
2530
|
*/
|
|
2332
2531
|
build(options?: BuildOptions): Promise<BuildSummary>;
|
|
2532
|
+
/**
|
|
2533
|
+
* Incremental dev rebuild from a set of changed paths — the fast counterpart to
|
|
2534
|
+
* {@link build} for a long-lived EXTERNAL dev loop (e.g. an `@moku-labs/worker` dev
|
|
2535
|
+
* session driving the composed web client via `dev({ onChange })`). Reuses the build
|
|
2536
|
+
* plugin's incremental engine: skips the destructive clean, scopes the rebuild to
|
|
2537
|
+
* `changes` (re-reads only changed Markdown, reuses cached page renders whose data is
|
|
2538
|
+
* unchanged), and applies the dev overrides (minify off; OG/sitemap/feeds off unless
|
|
2539
|
+
* re-enabled per {@link UpdateOptions}). An unclassifiable path forces a full rebuild.
|
|
2540
|
+
* Unlike {@link build} it renders no command header and skips the not-found assertion
|
|
2541
|
+
* (it's a per-change dev rebuild, not a release build).
|
|
2542
|
+
*
|
|
2543
|
+
* @param changes - The paths changed since the last build (the incremental hint).
|
|
2544
|
+
* @param options - Optional per-session dev-output opt-ins.
|
|
2545
|
+
* @returns The rebuild summary (`outDir`, `pageCount`, `durationMs`).
|
|
2546
|
+
* @example
|
|
2547
|
+
* await app.cli.update(["src/islands/board.ts"]);
|
|
2548
|
+
*/
|
|
2549
|
+
update(changes: readonly string[], options?: UpdateOptions): Promise<BuildSummary>;
|
|
2333
2550
|
/**
|
|
2334
2551
|
* Dev loop: build once, serve `dist/` in-process (live-reload injected), watch
|
|
2335
2552
|
* `watchDirs`, debounced rebuild + reload. Resolves when SIGINT/SIGTERM tears down.
|
|
@@ -3283,21 +3500,26 @@ declare const sitePlugin: import("@moku-labs/core").PluginInstance<"site", Confi
|
|
|
3283
3500
|
//#endregion
|
|
3284
3501
|
//#region src/plugins/spa/components.d.ts
|
|
3285
3502
|
/**
|
|
3286
|
-
* Create a validated component definition.
|
|
3287
|
-
*
|
|
3288
|
-
*
|
|
3503
|
+
* Create a validated component definition. Accepts either the legacy hooks-only form
|
|
3504
|
+
* (`createComponent("counter", { onMount() {} })`) or the plugin-mirror spec form
|
|
3505
|
+
* (`createComponent("board", { state, render, events, api, ...hooks })`). Spec-only
|
|
3506
|
+
* keys (`state`/`render`/`events`/`api`) are partitioned out before hook-name
|
|
3507
|
+
* validation, so a real typo (e.g. `onMout`) still throws immediately while the spec
|
|
3508
|
+
* keys are accepted.
|
|
3289
3509
|
*
|
|
3290
3510
|
* @param name - Unique component name.
|
|
3291
|
-
* @param
|
|
3511
|
+
* @param spec - Lifecycle hooks, or the `{ state, render, events, api, ...hooks }` spec.
|
|
3292
3512
|
* @returns A `ComponentDef` ready to `register`.
|
|
3293
|
-
* @throws {Error} If `name` is empty,
|
|
3294
|
-
*
|
|
3513
|
+
* @throws {Error} If `name` is empty, a hook key is unknown, or an extra/hook value has the wrong shape.
|
|
3514
|
+
* @example
|
|
3515
|
+
* const counter = createComponent("counter", { onMount({ el }) { el.textContent = "0"; } });
|
|
3295
3516
|
* @example
|
|
3296
|
-
* const
|
|
3297
|
-
*
|
|
3517
|
+
* const list = createComponent<{ items: string[] }>("list", {
|
|
3518
|
+
* state: () => ({ items: [] }),
|
|
3519
|
+
* render: (s) => h(List, { items: s.items })
|
|
3298
3520
|
* });
|
|
3299
3521
|
*/
|
|
3300
|
-
declare function createComponent(name: string,
|
|
3522
|
+
declare function createComponent<S extends object = object, A = unknown>(name: string, spec: ComponentSpec<S, A>): ComponentDef;
|
|
3301
3523
|
//#endregion
|
|
3302
3524
|
//#region src/plugins/spa/lazy-embed.d.ts
|
|
3303
3525
|
/**
|