@moku-labs/web 2.2.1 → 2.3.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 +190 -6
- package/dist/browser.mjs +119 -8
- package/dist/convention-Bs8SrQS9.mjs +109 -0
- package/dist/{convention-BpDfzX7e.cjs → convention-CLIDd9k-.cjs} +0 -43
- package/dist/convention-CsJw7CML.cjs +120 -0
- package/dist/index.cjs +326 -33
- package/dist/index.d.cts +209 -6
- package/dist/index.d.mts +209 -6
- package/dist/index.mjs +263 -11
- package/dist/writer-BBtgz9wt.cjs +90 -0
- package/dist/{writer-JdhX1Wld.cjs → writer-BEM-Pbgb.cjs} +4 -3
- package/dist/writer-C9BfpPio.mjs +87 -0
- package/package.json +1 -1
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
//#region src/plugins/collection/convention.ts
|
|
2
|
+
/**
|
|
3
|
+
* @file collection plugin — the pure URL/file convention (no `node:*`, no DOM).
|
|
4
|
+
*
|
|
5
|
+
* ONE function maps a `(collection, shard)` key to its shard suffix, so the browser
|
|
6
|
+
* fetch URL (`baseUrl + suffix`) and the on-disk file (`outDir + "/" + suffix`) are
|
|
7
|
+
* derived from the same source and cannot drift. The collection name is the top
|
|
8
|
+
* directory and the shard becomes a `.json` file beneath it (its INTERNAL slashes
|
|
9
|
+
* are kept as nested dirs):
|
|
10
|
+
* ("bank", "en/animals") → "bank/en/animals.json"
|
|
11
|
+
* ("bank", "ru") → "bank/ru.json"
|
|
12
|
+
* ("/bank/", "/en/") → "bank/en.json" (outer slashes trimmed)
|
|
13
|
+
*
|
|
14
|
+
* Encoding split: the FETCH suffix ({@link shardSuffix}) keeps the key's
|
|
15
|
+
* percent-encoding (the browser requests the encoded path); the FILE path
|
|
16
|
+
* ({@link relativeShardFile}) decodes it so the on-disk name is literal.
|
|
17
|
+
*/
|
|
18
|
+
/**
|
|
19
|
+
* Strip leading/trailing slashes from `collection` and `shard` (keeping the
|
|
20
|
+
* shard's INTERNAL slashes as nested path segments), then join them as
|
|
21
|
+
* `` `${collection}/${shard}.json` `` — the suffix shared by the fetch URL and the
|
|
22
|
+
* on-disk file.
|
|
23
|
+
*
|
|
24
|
+
* @param collection - The collection name (e.g. `"bank"`).
|
|
25
|
+
* @param shard - The shard key within the collection (e.g. `"en/animals"`).
|
|
26
|
+
* @returns The shard suffix (e.g. `"bank/en/animals.json"`).
|
|
27
|
+
* @example
|
|
28
|
+
* ```ts
|
|
29
|
+
* shardSuffix("bank", "en/animals"); // "bank/en/animals.json"
|
|
30
|
+
* shardSuffix("/bank/", "/ru/"); // "bank/ru.json"
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
function shardSuffix(collection, shard) {
|
|
34
|
+
return `${trimSlashes(collection)}/${trimSlashes(shard)}.json`;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Strip any leading and trailing slashes from a path segment, leaving its internal
|
|
38
|
+
* slashes intact.
|
|
39
|
+
*
|
|
40
|
+
* @param segment - The raw `collection` or `shard` value.
|
|
41
|
+
* @returns The segment without outer slashes.
|
|
42
|
+
* @example
|
|
43
|
+
* ```ts
|
|
44
|
+
* trimSlashes("/en/animals/"); // "en/animals"
|
|
45
|
+
* ```
|
|
46
|
+
*/
|
|
47
|
+
function trimSlashes(segment) {
|
|
48
|
+
let trimmed = segment;
|
|
49
|
+
while (trimmed.startsWith("/")) trimmed = trimmed.slice(1);
|
|
50
|
+
while (trimmed.endsWith("/")) trimmed = trimmed.slice(0, -1);
|
|
51
|
+
return trimmed;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Compute the browser fetch URL for a `(collection, shard)` key: the `baseUrl`
|
|
55
|
+
* prefix joined with the {@link shardSuffix}. Exported so standalone consumers can
|
|
56
|
+
* derive the same URL without composing the plugin.
|
|
57
|
+
*
|
|
58
|
+
* @param baseUrl - The site-root URL prefix (ends with `/`, e.g. `"/"`).
|
|
59
|
+
* @param collection - The collection name (e.g. `"bank"`).
|
|
60
|
+
* @param shard - The shard key within the collection (e.g. `"en/animals"`).
|
|
61
|
+
* @returns The site-root-relative shard URL (e.g. `/bank/en/animals.json`).
|
|
62
|
+
* @example
|
|
63
|
+
* ```ts
|
|
64
|
+
* collectionUrl("/", "bank", "en/animals"); // "/bank/en/animals.json"
|
|
65
|
+
* ```
|
|
66
|
+
*/
|
|
67
|
+
function collectionUrl(baseUrl, collection, shard) {
|
|
68
|
+
return `${baseUrl}${shardSuffix(collection, shard)}`;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Decode a shard suffix's percent-escapes so the on-disk file carries the literal
|
|
72
|
+
* name (servers decode the encoded fetch URL before filesystem lookup). Falls back
|
|
73
|
+
* to the raw suffix on malformed escapes.
|
|
74
|
+
*
|
|
75
|
+
* @param suffix - The computed shard suffix (possibly percent-encoded).
|
|
76
|
+
* @returns The decoded suffix, or the raw suffix on malformed escapes.
|
|
77
|
+
* @example
|
|
78
|
+
* ```ts
|
|
79
|
+
* decodeSuffix("bank/en/a%20%26%20b.json"); // "bank/en/a & b.json"
|
|
80
|
+
* ```
|
|
81
|
+
*/
|
|
82
|
+
function decodeSuffix(suffix) {
|
|
83
|
+
try {
|
|
84
|
+
return decodeURIComponent(suffix);
|
|
85
|
+
} catch {
|
|
86
|
+
return suffix;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Compute the `outDir`-relative shard file for a `(collection, shard)` key — the
|
|
91
|
+
* DECODED {@link shardSuffix} (servers resolve the decoded request path against
|
|
92
|
+
* literal file names). The collection name IS the top directory, so there is no
|
|
93
|
+
* extra output-dir wrapper. Shared by the Node writer and the pure `fileFor`
|
|
94
|
+
* accessor so the written file and the reported path never drift.
|
|
95
|
+
*
|
|
96
|
+
* @param collection - The collection name (e.g. `"bank"`).
|
|
97
|
+
* @param shard - The shard key within the collection (e.g. `"en/animals"`).
|
|
98
|
+
* @returns The `outDir`-relative file path (e.g. `bank/en/animals.json`).
|
|
99
|
+
* @example
|
|
100
|
+
* ```ts
|
|
101
|
+
* relativeShardFile("bank", "en/animals"); // "bank/en/animals.json"
|
|
102
|
+
* relativeShardFile("bank", "a%20%26%20b"); // "bank/a & b.json"
|
|
103
|
+
* ```
|
|
104
|
+
*/
|
|
105
|
+
function relativeShardFile(collection, shard) {
|
|
106
|
+
return decodeSuffix(shardSuffix(collection, shard));
|
|
107
|
+
}
|
|
108
|
+
//#endregion
|
|
109
|
+
Object.defineProperty(exports, "collectionUrl", {
|
|
110
|
+
enumerable: true,
|
|
111
|
+
get: function() {
|
|
112
|
+
return collectionUrl;
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
Object.defineProperty(exports, "relativeShardFile", {
|
|
116
|
+
enumerable: true,
|
|
117
|
+
get: function() {
|
|
118
|
+
return relativeShardFile;
|
|
119
|
+
}
|
|
120
|
+
});
|
package/dist/index.cjs
CHANGED
|
@@ -1,5 +1,37 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
|
|
2
|
+
//#region \0rolldown/runtime.js
|
|
3
|
+
var __create = Object.create;
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
8
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
+
var __exportAll = (all, no_symbols) => {
|
|
10
|
+
let target = {};
|
|
11
|
+
for (var name in all) __defProp(target, name, {
|
|
12
|
+
get: all[name],
|
|
13
|
+
enumerable: true
|
|
14
|
+
});
|
|
15
|
+
if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
|
|
16
|
+
return target;
|
|
17
|
+
};
|
|
18
|
+
var __copyProps = (to, from, except, desc) => {
|
|
19
|
+
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
20
|
+
key = keys[i];
|
|
21
|
+
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
22
|
+
get: ((k) => from[k]).bind(null, key),
|
|
23
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
return to;
|
|
27
|
+
};
|
|
28
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
29
|
+
value: mod,
|
|
30
|
+
enumerable: true
|
|
31
|
+
}) : target, mod));
|
|
32
|
+
//#endregion
|
|
33
|
+
const require_convention = require("./convention-CLIDd9k-.cjs");
|
|
34
|
+
const require_convention$1 = require("./convention-CsJw7CML.cjs");
|
|
3
35
|
let _moku_labs_common = require("@moku-labs/common");
|
|
4
36
|
let _moku_labs_core = require("@moku-labs/core");
|
|
5
37
|
let node_fs = require("node:fs");
|
|
@@ -7,8 +39,8 @@ let node_crypto = require("node:crypto");
|
|
|
7
39
|
let node_fs_promises = require("node:fs/promises");
|
|
8
40
|
let node_os = require("node:os");
|
|
9
41
|
let node_path = require("node:path");
|
|
10
|
-
let node_path$1 =
|
|
11
|
-
node_path =
|
|
42
|
+
let node_path$1 = __toESM(node_path, 1);
|
|
43
|
+
node_path = __toESM(node_path);
|
|
12
44
|
let feed = require("feed");
|
|
13
45
|
let preact = require("preact");
|
|
14
46
|
let preact_render_to_string = require("preact-render-to-string");
|
|
@@ -17,31 +49,31 @@ let node_readline = require("node:readline");
|
|
|
17
49
|
let node_url = require("node:url");
|
|
18
50
|
let _moku_labs_common_cli = require("@moku-labs/common/cli");
|
|
19
51
|
let gray_matter = require("gray-matter");
|
|
20
|
-
gray_matter =
|
|
52
|
+
gray_matter = __toESM(gray_matter, 1);
|
|
21
53
|
let _shikijs_rehype = require("@shikijs/rehype");
|
|
22
|
-
_shikijs_rehype =
|
|
54
|
+
_shikijs_rehype = __toESM(_shikijs_rehype, 1);
|
|
23
55
|
let rehype_sanitize = require("rehype-sanitize");
|
|
24
|
-
rehype_sanitize =
|
|
56
|
+
rehype_sanitize = __toESM(rehype_sanitize, 1);
|
|
25
57
|
let rehype_stringify = require("rehype-stringify");
|
|
26
|
-
rehype_stringify =
|
|
58
|
+
rehype_stringify = __toESM(rehype_stringify, 1);
|
|
27
59
|
let unified = require("unified");
|
|
28
60
|
let rehype_raw = require("rehype-raw");
|
|
29
|
-
rehype_raw =
|
|
61
|
+
rehype_raw = __toESM(rehype_raw, 1);
|
|
30
62
|
let remark_directive = require("remark-directive");
|
|
31
|
-
remark_directive =
|
|
63
|
+
remark_directive = __toESM(remark_directive, 1);
|
|
32
64
|
let remark_frontmatter = require("remark-frontmatter");
|
|
33
|
-
remark_frontmatter =
|
|
65
|
+
remark_frontmatter = __toESM(remark_frontmatter, 1);
|
|
34
66
|
let remark_gfm = require("remark-gfm");
|
|
35
|
-
remark_gfm =
|
|
67
|
+
remark_gfm = __toESM(remark_gfm, 1);
|
|
36
68
|
let remark_parse = require("remark-parse");
|
|
37
|
-
remark_parse =
|
|
69
|
+
remark_parse = __toESM(remark_parse, 1);
|
|
38
70
|
let remark_rehype = require("remark-rehype");
|
|
39
|
-
remark_rehype =
|
|
71
|
+
remark_rehype = __toESM(remark_rehype, 1);
|
|
40
72
|
let unist_util_visit = require("unist-util-visit");
|
|
41
73
|
let preact_jsx_runtime = require("preact/jsx-runtime");
|
|
42
74
|
let hast_util_sanitize = require("hast-util-sanitize");
|
|
43
75
|
let reading_time = require("reading-time");
|
|
44
|
-
reading_time =
|
|
76
|
+
reading_time = __toESM(reading_time, 1);
|
|
45
77
|
let node_process = require("node:process");
|
|
46
78
|
//#region src/config.ts
|
|
47
79
|
/**
|
|
@@ -4460,7 +4492,7 @@ function dataApi(ctx) {
|
|
|
4460
4492
|
* ```
|
|
4461
4493
|
*/
|
|
4462
4494
|
async write(entries, options) {
|
|
4463
|
-
const { writeData } = await Promise.resolve().then(() => require("./writer-
|
|
4495
|
+
const { writeData } = await Promise.resolve().then(() => require("./writer-BEM-Pbgb.cjs"));
|
|
4464
4496
|
return writeData(ctx, entries, options);
|
|
4465
4497
|
},
|
|
4466
4498
|
/**
|
|
@@ -4544,7 +4576,7 @@ function createDataState(_ctx) {
|
|
|
4544
4576
|
* isInvalidBaseUrl("_data"); // true
|
|
4545
4577
|
* ```
|
|
4546
4578
|
*/
|
|
4547
|
-
function isInvalidBaseUrl(baseUrl) {
|
|
4579
|
+
function isInvalidBaseUrl$1(baseUrl) {
|
|
4548
4580
|
return typeof baseUrl !== "string" || !baseUrl.startsWith("/");
|
|
4549
4581
|
}
|
|
4550
4582
|
/**
|
|
@@ -4559,7 +4591,7 @@ function isInvalidBaseUrl(baseUrl) {
|
|
|
4559
4591
|
* ```
|
|
4560
4592
|
*/
|
|
4561
4593
|
function validateDataConfig(config) {
|
|
4562
|
-
if (isInvalidBaseUrl(config.baseUrl)) throw new Error(`[web] data.baseUrl: must be a site-root-relative URL path starting with "/" (e.g. "/_data/").`);
|
|
4594
|
+
if (isInvalidBaseUrl$1(config.baseUrl)) throw new Error(`[web] data.baseUrl: must be a site-root-relative URL path starting with "/" (e.g. "/_data/").`);
|
|
4563
4595
|
}
|
|
4564
4596
|
//#endregion
|
|
4565
4597
|
//#region src/plugins/data/index.ts
|
|
@@ -9181,6 +9213,252 @@ const cliPlugin = createPlugin$1("cli", {
|
|
|
9181
9213
|
api: createApi$1
|
|
9182
9214
|
});
|
|
9183
9215
|
//#endregion
|
|
9216
|
+
//#region src/plugins/collection/read.ts
|
|
9217
|
+
/**
|
|
9218
|
+
* @file `loadCollectionShard` — the collection plugin's standalone BROWSER read
|
|
9219
|
+
* primitive. Internal to the `collection` plugin AND exported for standalone
|
|
9220
|
+
* consumers: `collection.at(...)` wraps it, and a room-layer consumer can import it
|
|
9221
|
+
* directly from `@moku-labs/web/browser`.
|
|
9222
|
+
*
|
|
9223
|
+
* Unlike the `data` plugin's isomorphic `loadJson`, this uses the `fetch` global
|
|
9224
|
+
* DIRECTLY (no `node:fs` branch). Consumers — and tests — rely on `fetch` even
|
|
9225
|
+
* under Node test environments, so there is no document sniffing here: a shard is
|
|
9226
|
+
* always fetched over HTTP from the build-authored URL. This keeps the module
|
|
9227
|
+
* fully node-free.
|
|
9228
|
+
*/
|
|
9229
|
+
/**
|
|
9230
|
+
* Fetch + parse a build-authored collection shard over HTTP. Builds the shard URL
|
|
9231
|
+
* via {@link collectionUrl}, fetches it, and throws on a non-OK response so the
|
|
9232
|
+
* caller (`collection.at`) can decide whether to fall back.
|
|
9233
|
+
*
|
|
9234
|
+
* @template T - The expected shape of the parsed shard JSON.
|
|
9235
|
+
* @param baseUrl - The site-root URL prefix (ends with `/`, e.g. `"/"`).
|
|
9236
|
+
* @param collection - The collection name (e.g. `"bank"`).
|
|
9237
|
+
* @param shard - The shard key within the collection (e.g. `"en/animals"`).
|
|
9238
|
+
* @returns The parsed shard JSON, typed as `T`.
|
|
9239
|
+
* @throws {Error} If the fetch is not OK.
|
|
9240
|
+
* @example
|
|
9241
|
+
* ```ts
|
|
9242
|
+
* const animals = await loadCollectionShard<Animal[]>("/", "bank", "en/animals");
|
|
9243
|
+
* ```
|
|
9244
|
+
*/
|
|
9245
|
+
async function loadCollectionShard(baseUrl, collection, shard) {
|
|
9246
|
+
const url = require_convention$1.collectionUrl(baseUrl, collection, shard);
|
|
9247
|
+
const response = await fetch(url);
|
|
9248
|
+
if (!response.ok) throw new Error(`[web] collection: failed to fetch ${url} (${String(response.status)}).`);
|
|
9249
|
+
return response.json();
|
|
9250
|
+
}
|
|
9251
|
+
//#endregion
|
|
9252
|
+
//#region src/plugins/collection/api.ts
|
|
9253
|
+
/**
|
|
9254
|
+
* @file collection plugin — API factory (the collection provider surface).
|
|
9255
|
+
*
|
|
9256
|
+
* Node-free by construction: this module statically imports only types + the pure
|
|
9257
|
+
* convention + the node-free `read` primitive. The Node write side (`write()`)
|
|
9258
|
+
* reaches its `node:fs` writer through a lazy `await import("./writer")` at call
|
|
9259
|
+
* time, so a browser bundle that composes `collection` for the read side never
|
|
9260
|
+
* pulls `node:*`. The read side (`at()`) uses only the `fetch`-based
|
|
9261
|
+
* `loadCollectionShard`.
|
|
9262
|
+
*/
|
|
9263
|
+
/**
|
|
9264
|
+
* Builds the collection provider — the static-data bridge. `write()` is the Node
|
|
9265
|
+
* persist side; `at()` is the browser read side; `urlFor`/`fileFor` are the pure
|
|
9266
|
+
* convention. No `onStart`/`onStop` (holds no long-lived resource).
|
|
9267
|
+
*
|
|
9268
|
+
* @param ctx - The collection plugin context.
|
|
9269
|
+
* @returns The {@link CollectionProvider} mounted at `app.collection`.
|
|
9270
|
+
* @example
|
|
9271
|
+
* ```ts
|
|
9272
|
+
* const api = collectionApi(ctx);
|
|
9273
|
+
* await api.write([{ collection: "bank", shard: "en/animals", data }]); // Node build
|
|
9274
|
+
* await api.at("bank", "en/animals"); // browser
|
|
9275
|
+
* ```
|
|
9276
|
+
*/
|
|
9277
|
+
function collectionApi(ctx) {
|
|
9278
|
+
return {
|
|
9279
|
+
/**
|
|
9280
|
+
* READ (browser) — fetch (and cache) the persisted data for a `(collection,
|
|
9281
|
+
* shard)` key. Returns the raw JSON as `unknown`; returns `null` if the fetch
|
|
9282
|
+
* or JSON parse fails (so the consumer can fall back). Wraps the throwing
|
|
9283
|
+
* {@link loadCollectionShard} reader into a soft null-returning app read.
|
|
9284
|
+
*
|
|
9285
|
+
* @param collection - The collection name (e.g. `"bank"`).
|
|
9286
|
+
* @param shard - The shard key within the collection (e.g. `"en/animals"`).
|
|
9287
|
+
* @returns The shard's raw data, or `null` on failure.
|
|
9288
|
+
* @example
|
|
9289
|
+
* ```ts
|
|
9290
|
+
* const raw = await api.at("bank", "en/animals");
|
|
9291
|
+
* ```
|
|
9292
|
+
*/
|
|
9293
|
+
async at(collection, shard) {
|
|
9294
|
+
const key = `${collection}/${shard}`;
|
|
9295
|
+
if (ctx.state.cache.has(key)) return ctx.state.cache.get(key);
|
|
9296
|
+
try {
|
|
9297
|
+
const data = await loadCollectionShard(ctx.config.baseUrl, collection, shard);
|
|
9298
|
+
ctx.state.cache.set(key, data);
|
|
9299
|
+
return data;
|
|
9300
|
+
} catch {
|
|
9301
|
+
return null;
|
|
9302
|
+
}
|
|
9303
|
+
},
|
|
9304
|
+
/**
|
|
9305
|
+
* WRITE (Node) — persist one JSON file per entry, keyed by `(collection,
|
|
9306
|
+
* shard)`. Called by the build after it authors the shards. Lazily loads its
|
|
9307
|
+
* `node:fs` writer (keeping a browser bundle node-free).
|
|
9308
|
+
*
|
|
9309
|
+
* @param entries - The per-shard data to persist.
|
|
9310
|
+
* @param options - Optional `{ outDir }` override (defaults to `./dist`).
|
|
9311
|
+
* @param options.outDir - Build output directory the write happens under.
|
|
9312
|
+
* @returns A summary of the written files.
|
|
9313
|
+
* @example
|
|
9314
|
+
* ```ts
|
|
9315
|
+
* await api.write([{ collection: "bank", shard: "ru", data }], { outDir: "dist" });
|
|
9316
|
+
* ```
|
|
9317
|
+
*/
|
|
9318
|
+
async write(entries, options) {
|
|
9319
|
+
const { writeCollection } = await Promise.resolve().then(() => require("./writer-BBtgz9wt.cjs"));
|
|
9320
|
+
return writeCollection(ctx, entries, options);
|
|
9321
|
+
},
|
|
9322
|
+
/**
|
|
9323
|
+
* PURE — the browser fetch URL for a `(collection, shard)` key.
|
|
9324
|
+
*
|
|
9325
|
+
* @param collection - The collection name.
|
|
9326
|
+
* @param shard - The shard key within the collection.
|
|
9327
|
+
* @returns The site-root-relative shard URL.
|
|
9328
|
+
* @example
|
|
9329
|
+
* ```ts
|
|
9330
|
+
* api.urlFor("bank", "en/animals"); // "/bank/en/animals.json"
|
|
9331
|
+
* ```
|
|
9332
|
+
*/
|
|
9333
|
+
urlFor(collection, shard) {
|
|
9334
|
+
return require_convention$1.collectionUrl(ctx.config.baseUrl, collection, shard);
|
|
9335
|
+
},
|
|
9336
|
+
/**
|
|
9337
|
+
* PURE — the `outDir`-relative file path for a `(collection, shard)` key.
|
|
9338
|
+
*
|
|
9339
|
+
* @param collection - The collection name.
|
|
9340
|
+
* @param shard - The shard key within the collection.
|
|
9341
|
+
* @returns The output-relative file path.
|
|
9342
|
+
* @example
|
|
9343
|
+
* ```ts
|
|
9344
|
+
* api.fileFor("bank", "en/animals"); // "bank/en/animals.json"
|
|
9345
|
+
* ```
|
|
9346
|
+
*/
|
|
9347
|
+
fileFor(collection, shard) {
|
|
9348
|
+
return require_convention$1.relativeShardFile(collection, shard);
|
|
9349
|
+
}
|
|
9350
|
+
};
|
|
9351
|
+
}
|
|
9352
|
+
//#endregion
|
|
9353
|
+
//#region src/plugins/collection/config.ts
|
|
9354
|
+
/**
|
|
9355
|
+
* Typed default collection config (R6: no inline `as`). `baseUrl` is the READ-side
|
|
9356
|
+
* site-root URL prefix the browser fetches shards from; the collection name is the
|
|
9357
|
+
* top directory under it. The default `"/"` serves shards straight from the site
|
|
9358
|
+
* root (e.g. `/bank/en/animals.json`).
|
|
9359
|
+
*
|
|
9360
|
+
* @example
|
|
9361
|
+
* ```ts
|
|
9362
|
+
* createPlugin("collection", { config: defaultCollectionConfig });
|
|
9363
|
+
* ```
|
|
9364
|
+
*/
|
|
9365
|
+
const defaultCollectionConfig = { baseUrl: "/" };
|
|
9366
|
+
//#endregion
|
|
9367
|
+
//#region src/plugins/collection/state.ts
|
|
9368
|
+
/**
|
|
9369
|
+
* Creates initial collection state: a null `lastWrite` slot (populated by the Node
|
|
9370
|
+
* `write()` side) and an empty `cache` (populated lazily by the browser
|
|
9371
|
+
* `at(collection, shard)` side on first fetch).
|
|
9372
|
+
*
|
|
9373
|
+
* @param _ctx - Minimal context with global and config.
|
|
9374
|
+
* @param _ctx.global - Global framework configuration.
|
|
9375
|
+
* @param _ctx.config - Resolved plugin configuration.
|
|
9376
|
+
* @returns Fresh collection state with no recorded write and an empty per-shard cache.
|
|
9377
|
+
* @example
|
|
9378
|
+
* ```ts
|
|
9379
|
+
* const state = createCollectionState({ global: {}, config });
|
|
9380
|
+
* ```
|
|
9381
|
+
*/
|
|
9382
|
+
function createCollectionState(_ctx) {
|
|
9383
|
+
return {
|
|
9384
|
+
lastWrite: null,
|
|
9385
|
+
cache: /* @__PURE__ */ new Map()
|
|
9386
|
+
};
|
|
9387
|
+
}
|
|
9388
|
+
//#endregion
|
|
9389
|
+
//#region src/plugins/collection/validate.ts
|
|
9390
|
+
/**
|
|
9391
|
+
* Reports whether a `baseUrl` value is invalid: it must be a string that ends with
|
|
9392
|
+
* a `"/"` so the collection name appends cleanly (`baseUrl + collection + "/" + …`).
|
|
9393
|
+
*
|
|
9394
|
+
* @param baseUrl - The candidate `baseUrl` value to check.
|
|
9395
|
+
* @returns `true` when `baseUrl` is not a string or does not end with "/".
|
|
9396
|
+
* @example
|
|
9397
|
+
* ```ts
|
|
9398
|
+
* isInvalidBaseUrl("/"); // false
|
|
9399
|
+
* isInvalidBaseUrl("/cdn"); // true
|
|
9400
|
+
* ```
|
|
9401
|
+
*/
|
|
9402
|
+
function isInvalidBaseUrl(baseUrl) {
|
|
9403
|
+
return typeof baseUrl !== "string" || !baseUrl.endsWith("/");
|
|
9404
|
+
}
|
|
9405
|
+
/**
|
|
9406
|
+
* Validates the resolved collection config: the browser `baseUrl` must be a string
|
|
9407
|
+
* ending with `"/"` so the collection name appends cleanly.
|
|
9408
|
+
*
|
|
9409
|
+
* @param config - The resolved plugin configuration.
|
|
9410
|
+
* @throws {Error} If `baseUrl` is not a string ending with "/".
|
|
9411
|
+
* @example
|
|
9412
|
+
* ```ts
|
|
9413
|
+
* validateCollectionConfig({ baseUrl: "/" });
|
|
9414
|
+
* ```
|
|
9415
|
+
*/
|
|
9416
|
+
function validateCollectionConfig(config) {
|
|
9417
|
+
if (isInvalidBaseUrl(config.baseUrl)) throw new Error(`[web] collection.baseUrl: must be a URL prefix ending with "/" (e.g. "/" or "/cdn/").`);
|
|
9418
|
+
}
|
|
9419
|
+
//#endregion
|
|
9420
|
+
//#region src/plugins/collection/index.ts
|
|
9421
|
+
/**
|
|
9422
|
+
* @file collection — Standard tier plugin (wiring-only). The static-data
|
|
9423
|
+
* COLLECTION provider — the collection-keyed sibling of the page-path-keyed `data`
|
|
9424
|
+
* plugin.
|
|
9425
|
+
*
|
|
9426
|
+
* Owns ONE contract — `(collection, shard) → persisted JSON file` — and nothing
|
|
9427
|
+
* about what the data is: `write(entries)` persists per-shard JSON on Node (the
|
|
9428
|
+
* build supplies the shards it already authored); `at(collection, shard)` fetches +
|
|
9429
|
+
* caches it in the browser as `unknown`, read on demand by the consumer. NOT a
|
|
9430
|
+
* framework default — the consumer composes it where needed (Node build AND/OR
|
|
9431
|
+
* browser app).
|
|
9432
|
+
*
|
|
9433
|
+
* **No hard `depends`** — fully browser-composable; the `node:fs` writer is behind
|
|
9434
|
+
* a lazy `import()` inside `write()`. Build ordering is a call-site contract: the
|
|
9435
|
+
* build writes shards during/after its pages phase, via `app.collection.write`.
|
|
9436
|
+
* No `onStart`/`onStop`.
|
|
9437
|
+
* @see README.md
|
|
9438
|
+
*/
|
|
9439
|
+
/**
|
|
9440
|
+
* Collection plugin — the static-data collection provider. Mounts
|
|
9441
|
+
* `write(entries)` (Node persist), `at(collection, shard)` (browser read), and the
|
|
9442
|
+
* pure `urlFor`/`fileFor` convention at `app.collection`.
|
|
9443
|
+
*
|
|
9444
|
+
* @example
|
|
9445
|
+
* ```ts
|
|
9446
|
+
* // Node build: write build-authored shards during/after the build's pages phase.
|
|
9447
|
+
* const app = createApp({ plugins: [collectionPlugin, buildPlugin] });
|
|
9448
|
+
* await app.build.run();
|
|
9449
|
+
* await app.collection.write([{ collection: "bank", shard: "en/animals", data }]);
|
|
9450
|
+
*
|
|
9451
|
+
* // Browser app: compose `collectionPlugin` too; fetch a shard on demand.
|
|
9452
|
+
* const raw = await app.collection.at("bank", "en/animals"); // unknown | null
|
|
9453
|
+
* ```
|
|
9454
|
+
*/
|
|
9455
|
+
const collectionPlugin = createPlugin$1("collection", {
|
|
9456
|
+
config: defaultCollectionConfig,
|
|
9457
|
+
createState: createCollectionState,
|
|
9458
|
+
onInit: (ctx) => validateCollectionConfig(ctx.config),
|
|
9459
|
+
api: collectionApi
|
|
9460
|
+
});
|
|
9461
|
+
//#endregion
|
|
9184
9462
|
//#region src/plugins/spa/api.ts
|
|
9185
9463
|
/**
|
|
9186
9464
|
* Creates the spa plugin API surface (registration / control). All methods
|
|
@@ -9346,7 +9624,7 @@ function syncHead(_head, doc) {
|
|
|
9346
9624
|
}
|
|
9347
9625
|
//#endregion
|
|
9348
9626
|
//#region src/plugins/spa/types.ts
|
|
9349
|
-
var types_exports$
|
|
9627
|
+
var types_exports$8 = /* @__PURE__ */ __exportAll({ ISLAND_HOOK_NAMES: () => ISLAND_HOOK_NAMES });
|
|
9350
9628
|
/** Allowed hook names — single source of truth for fail-fast validation. */
|
|
9351
9629
|
const ISLAND_HOOK_NAMES = [
|
|
9352
9630
|
"onCreate",
|
|
@@ -11206,10 +11484,12 @@ function createChannel(options) {
|
|
|
11206
11484
|
ws.addEventListener("open", () => {
|
|
11207
11485
|
reconnectAttempts = 0;
|
|
11208
11486
|
});
|
|
11209
|
-
ws.addEventListener("close", () => {
|
|
11487
|
+
ws.addEventListener("close", (event) => {
|
|
11210
11488
|
if (socket !== ws || desiredId === void 0) return;
|
|
11211
11489
|
socket = void 0;
|
|
11212
|
-
if (reconnectCfg)
|
|
11490
|
+
if (!reconnectCfg) return;
|
|
11491
|
+
if (options.shouldReconnect?.(event) === false) return;
|
|
11492
|
+
scheduleReconnect();
|
|
11213
11493
|
});
|
|
11214
11494
|
}
|
|
11215
11495
|
/**
|
|
@@ -11477,25 +11757,28 @@ const spaPlugin = createPlugin$1("spa", {
|
|
|
11477
11757
|
});
|
|
11478
11758
|
//#endregion
|
|
11479
11759
|
//#region src/plugins/build/types.ts
|
|
11480
|
-
var types_exports = /* @__PURE__ */
|
|
11760
|
+
var types_exports = /* @__PURE__ */ __exportAll({});
|
|
11481
11761
|
//#endregion
|
|
11482
11762
|
//#region src/plugins/cli/types.ts
|
|
11483
|
-
var types_exports$1 = /* @__PURE__ */
|
|
11763
|
+
var types_exports$1 = /* @__PURE__ */ __exportAll({});
|
|
11764
|
+
//#endregion
|
|
11765
|
+
//#region src/plugins/collection/types.ts
|
|
11766
|
+
var types_exports$2 = /* @__PURE__ */ __exportAll({});
|
|
11484
11767
|
//#endregion
|
|
11485
11768
|
//#region src/plugins/content/types.ts
|
|
11486
|
-
var types_exports$
|
|
11769
|
+
var types_exports$3 = /* @__PURE__ */ __exportAll({});
|
|
11487
11770
|
//#endregion
|
|
11488
11771
|
//#region src/plugins/data/types.ts
|
|
11489
|
-
var types_exports$
|
|
11772
|
+
var types_exports$4 = /* @__PURE__ */ __exportAll({});
|
|
11490
11773
|
//#endregion
|
|
11491
11774
|
//#region src/plugins/deploy/types.ts
|
|
11492
|
-
var types_exports$
|
|
11775
|
+
var types_exports$5 = /* @__PURE__ */ __exportAll({});
|
|
11493
11776
|
//#endregion
|
|
11494
11777
|
//#region src/plugins/head/types.ts
|
|
11495
|
-
var types_exports$
|
|
11778
|
+
var types_exports$6 = /* @__PURE__ */ __exportAll({});
|
|
11496
11779
|
//#endregion
|
|
11497
11780
|
//#region src/plugins/router/types.ts
|
|
11498
|
-
var types_exports$
|
|
11781
|
+
var types_exports$7 = /* @__PURE__ */ __exportAll({});
|
|
11499
11782
|
//#endregion
|
|
11500
11783
|
//#region node_modules/unist-util-stringify-position/lib/index.js
|
|
11501
11784
|
/**
|
|
@@ -13707,44 +13990,51 @@ Object.defineProperty(exports, "Cli", {
|
|
|
13707
13990
|
return types_exports$1;
|
|
13708
13991
|
}
|
|
13709
13992
|
});
|
|
13710
|
-
Object.defineProperty(exports, "
|
|
13993
|
+
Object.defineProperty(exports, "Collection", {
|
|
13711
13994
|
enumerable: true,
|
|
13712
13995
|
get: function() {
|
|
13713
13996
|
return types_exports$2;
|
|
13714
13997
|
}
|
|
13715
13998
|
});
|
|
13716
|
-
Object.defineProperty(exports, "
|
|
13999
|
+
Object.defineProperty(exports, "Content", {
|
|
13717
14000
|
enumerable: true,
|
|
13718
14001
|
get: function() {
|
|
13719
14002
|
return types_exports$3;
|
|
13720
14003
|
}
|
|
13721
14004
|
});
|
|
13722
|
-
Object.defineProperty(exports, "
|
|
14005
|
+
Object.defineProperty(exports, "Data", {
|
|
13723
14006
|
enumerable: true,
|
|
13724
14007
|
get: function() {
|
|
13725
14008
|
return types_exports$4;
|
|
13726
14009
|
}
|
|
13727
14010
|
});
|
|
14011
|
+
Object.defineProperty(exports, "Deploy", {
|
|
14012
|
+
enumerable: true,
|
|
14013
|
+
get: function() {
|
|
14014
|
+
return types_exports$5;
|
|
14015
|
+
}
|
|
14016
|
+
});
|
|
13728
14017
|
exports.EmbedFacadeButton = EmbedFacadeButton;
|
|
13729
14018
|
exports.GalleryTrack = GalleryTrack;
|
|
13730
14019
|
Object.defineProperty(exports, "Head", {
|
|
13731
14020
|
enumerable: true,
|
|
13732
14021
|
get: function() {
|
|
13733
|
-
return types_exports$
|
|
14022
|
+
return types_exports$6;
|
|
13734
14023
|
}
|
|
13735
14024
|
});
|
|
13736
14025
|
Object.defineProperty(exports, "Router", {
|
|
13737
14026
|
enumerable: true,
|
|
13738
14027
|
get: function() {
|
|
13739
|
-
return types_exports$
|
|
14028
|
+
return types_exports$7;
|
|
13740
14029
|
}
|
|
13741
14030
|
});
|
|
13742
14031
|
Object.defineProperty(exports, "Spa", {
|
|
13743
14032
|
enumerable: true,
|
|
13744
14033
|
get: function() {
|
|
13745
|
-
return types_exports$
|
|
14034
|
+
return types_exports$8;
|
|
13746
14035
|
}
|
|
13747
14036
|
});
|
|
14037
|
+
exports.__toESM = __toESM;
|
|
13748
14038
|
Object.defineProperty(exports, "browserEnv", {
|
|
13749
14039
|
enumerable: true,
|
|
13750
14040
|
get: function() {
|
|
@@ -13761,6 +14051,8 @@ Object.defineProperty(exports, "cloudflareBindings", {
|
|
|
13761
14051
|
return _moku_labs_common.cloudflareBindings;
|
|
13762
14052
|
}
|
|
13763
14053
|
});
|
|
14054
|
+
exports.collectionPlugin = collectionPlugin;
|
|
14055
|
+
exports.collectionUrl = require_convention$1.collectionUrl;
|
|
13764
14056
|
exports.contentPlugin = contentPlugin;
|
|
13765
14057
|
exports.createApp = createApp;
|
|
13766
14058
|
exports.createChannel = createChannel;
|
|
@@ -13790,6 +14082,7 @@ exports.hreflang = hreflang;
|
|
|
13790
14082
|
exports.i18nPlugin = i18nPlugin;
|
|
13791
14083
|
exports.jsonLd = jsonLd;
|
|
13792
14084
|
exports.lazyEmbed = lazyEmbed;
|
|
14085
|
+
exports.loadCollectionShard = loadCollectionShard;
|
|
13793
14086
|
Object.defineProperty(exports, "logPlugin", {
|
|
13794
14087
|
enumerable: true,
|
|
13795
14088
|
get: function() {
|