@moku-labs/web 0.3.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +224 -2
- package/dist/index.d.cts +303 -108
- package/dist/index.d.mts +303 -108
- package/dist/index.mjs +224 -2
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -851,7 +851,27 @@ const coreConfig = (0, _moku_labs_core.createCoreConfig)("web", {
|
|
|
851
851
|
env: { providers: [dotenv(), processEnv()] }
|
|
852
852
|
}
|
|
853
853
|
});
|
|
854
|
-
|
|
854
|
+
/**
|
|
855
|
+
* Create a custom plugin bound to this framework's `Config`/`Events` and the core
|
|
856
|
+
* plugin APIs (`log`, `env`). Plugin types are fully inferred from the spec
|
|
857
|
+
* object — never write them explicitly. This is the binding every built-in
|
|
858
|
+
* plugin is wired with, and the one consumer plugins should use too.
|
|
859
|
+
*
|
|
860
|
+
* @example
|
|
861
|
+
* ```ts
|
|
862
|
+
* const analytics = createPlugin("analytics", {
|
|
863
|
+
* config: { writeKey: "" },
|
|
864
|
+
* api: (ctx) => ({ track: (event: string) => ctx.log.info("analytics:track", { event }) })
|
|
865
|
+
* });
|
|
866
|
+
* ```
|
|
867
|
+
*/
|
|
868
|
+
const createPlugin$1 = coreConfig.createPlugin;
|
|
869
|
+
/**
|
|
870
|
+
* Step 2 of the factory chain — captures the framework's default plugin set and
|
|
871
|
+
* returns the consumer entry points ({@link createApp} + a re-exported
|
|
872
|
+
* `createPlugin`). Wired once in `src/index.ts`; consumers don't call it directly.
|
|
873
|
+
*/
|
|
874
|
+
const createCore = coreConfig.createCore;
|
|
855
875
|
//#endregion
|
|
856
876
|
//#region src/plugins/i18n/api.ts
|
|
857
877
|
/** Error prefix for all i18n lifecycle failures. */
|
|
@@ -979,6 +999,25 @@ function createI18nApi(ctx) {
|
|
|
979
999
|
}
|
|
980
1000
|
};
|
|
981
1001
|
}
|
|
1002
|
+
/**
|
|
1003
|
+
* Internationalization plugin — locale registry plus a flat translation helper
|
|
1004
|
+
* with default-locale fallback. Pure config-as-data (no state or events);
|
|
1005
|
+
* consumed read-only by content, router, head, and build.
|
|
1006
|
+
*
|
|
1007
|
+
* @example Register locales and translations
|
|
1008
|
+
* ```ts
|
|
1009
|
+
* const app = createApp({
|
|
1010
|
+
* pluginConfigs: {
|
|
1011
|
+
* i18n: {
|
|
1012
|
+
* locales: ["en", "uk"],
|
|
1013
|
+
* defaultLocale: "en",
|
|
1014
|
+
* localeNames: { en: "English", uk: "Українська" },
|
|
1015
|
+
* translations: { uk: { "nav.home": "Головна" } }
|
|
1016
|
+
* }
|
|
1017
|
+
* }
|
|
1018
|
+
* });
|
|
1019
|
+
* ```
|
|
1020
|
+
*/
|
|
982
1021
|
const i18nPlugin = createPlugin$1("i18n", {
|
|
983
1022
|
config: {
|
|
984
1023
|
locales: ["en"],
|
|
@@ -1774,6 +1813,26 @@ function validateContentConfig(config) {
|
|
|
1774
1813
|
* and `content:invalidated`.
|
|
1775
1814
|
* @see README.md
|
|
1776
1815
|
*/
|
|
1816
|
+
/**
|
|
1817
|
+
* Content plugin — Markdown pipeline: discovers files, parses frontmatter, renders
|
|
1818
|
+
* to sanitized HTML (rehype-sanitize unless `trustedContent`), and exposes a
|
|
1819
|
+
* locale-keyed Article model. Depends on i18n; emits `content:ready` and
|
|
1820
|
+
* `content:invalidated`.
|
|
1821
|
+
*
|
|
1822
|
+
* @example Point at a content directory and pick a Shiki theme
|
|
1823
|
+
* ```ts
|
|
1824
|
+
* const app = createApp({
|
|
1825
|
+
* pluginConfigs: {
|
|
1826
|
+
* content: {
|
|
1827
|
+
* contentDir: "./content",
|
|
1828
|
+
* shikiTheme: "github-dark",
|
|
1829
|
+
* defaultAuthor: "Ada Lovelace"
|
|
1830
|
+
* // trustedContent: true // ONLY for fully author-controlled Markdown — disables sanitize
|
|
1831
|
+
* }
|
|
1832
|
+
* }
|
|
1833
|
+
* });
|
|
1834
|
+
* ```
|
|
1835
|
+
*/
|
|
1777
1836
|
const contentPlugin = createPlugin$1("content", {
|
|
1778
1837
|
depends: [i18nPlugin],
|
|
1779
1838
|
events: contentEvents,
|
|
@@ -1937,6 +1996,25 @@ function createSiteApi(ctx) {
|
|
|
1937
1996
|
}
|
|
1938
1997
|
};
|
|
1939
1998
|
}
|
|
1999
|
+
/**
|
|
2000
|
+
* Site plugin — holds global, frozen site metadata (name, url, author,
|
|
2001
|
+
* description) and builds canonical URLs. Consumed by router, head, and build.
|
|
2002
|
+
* `name` and `url` must be non-empty (validated at `onInit`).
|
|
2003
|
+
*
|
|
2004
|
+
* @example Set your site identity
|
|
2005
|
+
* ```ts
|
|
2006
|
+
* const app = createApp({
|
|
2007
|
+
* pluginConfigs: {
|
|
2008
|
+
* site: {
|
|
2009
|
+
* name: "My Blog",
|
|
2010
|
+
* url: "https://blog.dev",
|
|
2011
|
+
* author: "Ada Lovelace",
|
|
2012
|
+
* description: "Notes on computing"
|
|
2013
|
+
* }
|
|
2014
|
+
* }
|
|
2015
|
+
* });
|
|
2016
|
+
* ```
|
|
2017
|
+
*/
|
|
1940
2018
|
const sitePlugin = createPlugin$1("site", {
|
|
1941
2019
|
config: {
|
|
1942
2020
|
name: "",
|
|
@@ -2566,6 +2644,26 @@ function defineRoutes(routes) {
|
|
|
2566
2644
|
function createState$4(_ctx) {
|
|
2567
2645
|
return { table: null };
|
|
2568
2646
|
}
|
|
2647
|
+
/**
|
|
2648
|
+
* Router plugin — typed, named route definitions with locale-aware URL generation
|
|
2649
|
+
* and matching. Author routes with {@link route} + {@link defineRoutes}. Depends
|
|
2650
|
+
* on site (base URL) and i18n (locales).
|
|
2651
|
+
*
|
|
2652
|
+
* @example Define routes and choose a render mode
|
|
2653
|
+
* ```ts
|
|
2654
|
+
* const app = createApp({
|
|
2655
|
+
* pluginConfigs: {
|
|
2656
|
+
* router: {
|
|
2657
|
+
* routes: defineRoutes({
|
|
2658
|
+
* home: route("/"),
|
|
2659
|
+
* article: route("/blog/{slug}/")
|
|
2660
|
+
* }),
|
|
2661
|
+
* mode: "hybrid" // "ssg" | "spa" | "hybrid" (default)
|
|
2662
|
+
* }
|
|
2663
|
+
* }
|
|
2664
|
+
* });
|
|
2665
|
+
* ```
|
|
2666
|
+
*/
|
|
2569
2667
|
const routerPlugin = createPlugin$1("router", {
|
|
2570
2668
|
depends: [sitePlugin, i18nPlugin],
|
|
2571
2669
|
helpers: {
|
|
@@ -3079,6 +3177,25 @@ function createState$3(_ctx) {
|
|
|
3079
3177
|
* @file head — Standard Plugin wiring harness (logic in primitives/compose/api/config).
|
|
3080
3178
|
* @see README.md
|
|
3081
3179
|
*/
|
|
3180
|
+
/**
|
|
3181
|
+
* Head plugin — composes per-route `<head>` metadata (title template, Open Graph,
|
|
3182
|
+
* Twitter cards, canonical, hreflang). Use the re-exported SEO primitives
|
|
3183
|
+
* ({@link meta}, {@link og}, {@link twitter}, …) inside a route's `.head()`.
|
|
3184
|
+
* Depends on site, i18n, and router.
|
|
3185
|
+
*
|
|
3186
|
+
* @example Set global head defaults
|
|
3187
|
+
* ```ts
|
|
3188
|
+
* const app = createApp({
|
|
3189
|
+
* pluginConfigs: {
|
|
3190
|
+
* head: {
|
|
3191
|
+
* titleTemplate: "%s — My Blog",
|
|
3192
|
+
* twitterCard: "summary_large_image",
|
|
3193
|
+
* twitterHandle: "@moku_labs"
|
|
3194
|
+
* }
|
|
3195
|
+
* }
|
|
3196
|
+
* });
|
|
3197
|
+
* ```
|
|
3198
|
+
*/
|
|
3082
3199
|
const headPlugin = createPlugin$1("head", {
|
|
3083
3200
|
depends: [
|
|
3084
3201
|
sitePlugin,
|
|
@@ -4086,6 +4203,27 @@ function createState$2(ctx) {
|
|
|
4086
4203
|
* @file build — Complex plugin: SSG orchestrator (wiring harness only).
|
|
4087
4204
|
* @see README.md
|
|
4088
4205
|
*/
|
|
4206
|
+
/**
|
|
4207
|
+
* Build plugin — the static-site-generation orchestrator. Renders every route to
|
|
4208
|
+
* `outDir`, and optionally emits feeds, a sitemap, optimized images, and OG
|
|
4209
|
+
* images. Depends on site, i18n, content, router, and head; emits `build:phase`.
|
|
4210
|
+
*
|
|
4211
|
+
* @example Configure the production build
|
|
4212
|
+
* ```ts
|
|
4213
|
+
* const app = createApp({
|
|
4214
|
+
* pluginConfigs: {
|
|
4215
|
+
* build: {
|
|
4216
|
+
* outDir: "dist",
|
|
4217
|
+
* minify: true,
|
|
4218
|
+
* feeds: true,
|
|
4219
|
+
* sitemap: true,
|
|
4220
|
+
* images: true,
|
|
4221
|
+
* ogImage: false // or an object to enable + configure OG-image generation
|
|
4222
|
+
* }
|
|
4223
|
+
* }
|
|
4224
|
+
* });
|
|
4225
|
+
* ```
|
|
4226
|
+
*/
|
|
4089
4227
|
const buildPlugin = createPlugin$1("build", {
|
|
4090
4228
|
depends: [
|
|
4091
4229
|
sitePlugin,
|
|
@@ -4885,6 +5023,24 @@ function createState$1(_ctx) {
|
|
|
4885
5023
|
* Depends: site. Emits: deploy:complete.
|
|
4886
5024
|
* @see README.md
|
|
4887
5025
|
*/
|
|
5026
|
+
/**
|
|
5027
|
+
* Deploy plugin — ships the built `outDir` to Cloudflare Pages via the injectable
|
|
5028
|
+
* wrangler subprocess, with entropy-gated secret scrubbing of logged output.
|
|
5029
|
+
* Depends on site; emits `deploy:complete`.
|
|
5030
|
+
*
|
|
5031
|
+
* @example Configure the deploy target
|
|
5032
|
+
* ```ts
|
|
5033
|
+
* const app = createApp({
|
|
5034
|
+
* pluginConfigs: {
|
|
5035
|
+
* deploy: {
|
|
5036
|
+
* target: "cloudflare-pages",
|
|
5037
|
+
* outDir: "dist",
|
|
5038
|
+
* productionBranch: "main"
|
|
5039
|
+
* }
|
|
5040
|
+
* }
|
|
5041
|
+
* });
|
|
5042
|
+
* ```
|
|
5043
|
+
*/
|
|
4888
5044
|
const deployPlugin = createPlugin$1("deploy", {
|
|
4889
5045
|
config: defaultConfig,
|
|
4890
5046
|
depends: [sitePlugin],
|
|
@@ -5857,6 +6013,26 @@ function disposeSpa() {
|
|
|
5857
6013
|
* Emits: spa:navigate, spa:navigated, spa:component-mount, spa:component-unmount.
|
|
5858
6014
|
* @see README.md
|
|
5859
6015
|
*/
|
|
6016
|
+
/**
|
|
6017
|
+
* SPA plugin — progressive client-side navigation layered over the static site:
|
|
6018
|
+
* swaps a page region on navigation, with an optional progress bar and View
|
|
6019
|
+
* Transitions. Register interactive islands with {@link createComponent}. Depends
|
|
6020
|
+
* on router and head; emits `spa:navigate`, `spa:navigated`, `spa:component-mount`,
|
|
6021
|
+
* and `spa:component-unmount`.
|
|
6022
|
+
*
|
|
6023
|
+
* @example Enable view transitions and a custom swap region
|
|
6024
|
+
* ```ts
|
|
6025
|
+
* const app = createApp({
|
|
6026
|
+
* pluginConfigs: {
|
|
6027
|
+
* spa: {
|
|
6028
|
+
* swapSelector: "main > section",
|
|
6029
|
+
* viewTransitions: true,
|
|
6030
|
+
* progressBar: true
|
|
6031
|
+
* }
|
|
6032
|
+
* }
|
|
6033
|
+
* });
|
|
6034
|
+
* ```
|
|
6035
|
+
*/
|
|
5860
6036
|
const spaPlugin = createPlugin$1("spa", {
|
|
5861
6037
|
depends: [routerPlugin, headPlugin],
|
|
5862
6038
|
config: defaultSpaConfig,
|
|
@@ -5891,7 +6067,13 @@ var types_exports$5 = /* @__PURE__ */ __exportAll({});
|
|
|
5891
6067
|
//#endregion
|
|
5892
6068
|
//#region src/plugins/router/types.ts
|
|
5893
6069
|
var types_exports$6 = /* @__PURE__ */ __exportAll({});
|
|
5894
|
-
|
|
6070
|
+
//#endregion
|
|
6071
|
+
//#region src/index.ts
|
|
6072
|
+
/**
|
|
6073
|
+
* @file `@moku-labs/web` — a Moku Layer-2 content static-site + SPA framework.
|
|
6074
|
+
* @see README.md
|
|
6075
|
+
*/
|
|
6076
|
+
const framework = createCore(coreConfig, {
|
|
5895
6077
|
plugins: [
|
|
5896
6078
|
sitePlugin,
|
|
5897
6079
|
i18nPlugin,
|
|
@@ -5904,6 +6086,46 @@ const { createApp, createPlugin } = createCore(coreConfig, {
|
|
|
5904
6086
|
],
|
|
5905
6087
|
pluginConfigs: {}
|
|
5906
6088
|
});
|
|
6089
|
+
/**
|
|
6090
|
+
* Create and initialize a `@moku-labs/web` application — the Layer-3 entry point.
|
|
6091
|
+
* Your overrides are merged over the framework defaults through the 4-level config
|
|
6092
|
+
* cascade, every plugin's lifecycle runs, and a fully-typed, frozen app is returned.
|
|
6093
|
+
*
|
|
6094
|
+
* @param options - Optional configuration:
|
|
6095
|
+
* - `pluginConfigs` — per-plugin overrides, keyed by plugin name
|
|
6096
|
+
* (`site`, `i18n`, `router`, `content`, `head`, `build`, `spa`, `deploy`, `env`).
|
|
6097
|
+
* - `config` — global framework config (e.g. `{ mode: "development" }`).
|
|
6098
|
+
* - `plugins` — extra consumer plugins, merged into the app and its return type.
|
|
6099
|
+
* - `onReady` / `onError` / `onStart` / `onStop` — lifecycle callbacks.
|
|
6100
|
+
* @returns The initialized app: `start()`, `stop()`, every plugin's API, and `log`.
|
|
6101
|
+
* @example
|
|
6102
|
+
* ```ts
|
|
6103
|
+
* const app = createApp({
|
|
6104
|
+
* pluginConfigs: {
|
|
6105
|
+
* site: { name: "My Blog", url: "https://blog.dev", author: "Ada", description: "Notes" },
|
|
6106
|
+
* router: { routes: defineRoutes({ home: route("/"), post: route("/blog/{slug}/") }) }
|
|
6107
|
+
* }
|
|
6108
|
+
* });
|
|
6109
|
+
* await app.start();
|
|
6110
|
+
* ```
|
|
6111
|
+
*/
|
|
6112
|
+
const createApp = framework.createApp;
|
|
6113
|
+
/**
|
|
6114
|
+
* Create a custom plugin bound to this framework's `Config`/`Events` and core
|
|
6115
|
+
* APIs. Plugin types are inferred from the spec object — never written explicitly.
|
|
6116
|
+
* Pass the result to {@link createApp} via `plugins`.
|
|
6117
|
+
*
|
|
6118
|
+
* @example
|
|
6119
|
+
* ```ts
|
|
6120
|
+
* const analytics = createPlugin("analytics", {
|
|
6121
|
+
* config: { writeKey: "" },
|
|
6122
|
+
* api: (ctx) => ({ track: (event: string) => ctx.log.info("analytics:track", { event }) })
|
|
6123
|
+
* });
|
|
6124
|
+
*
|
|
6125
|
+
* const app = createApp({ plugins: [analytics] });
|
|
6126
|
+
* ```
|
|
6127
|
+
*/
|
|
6128
|
+
const createPlugin = framework.createPlugin;
|
|
5907
6129
|
//#endregion
|
|
5908
6130
|
Object.defineProperty(exports, "Build", {
|
|
5909
6131
|
enumerable: true,
|