boltdocs 1.0.4 → 1.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/{SearchDialog-R36WKAQ7.mjs → SearchDialog-5EDRACEG.mjs} +1 -1
- package/dist/{SearchDialog-PYF3QMYG.css → SearchDialog-X57WPTNN.css} +54 -126
- package/dist/cache-EHR7SXRU.mjs +12 -0
- package/dist/chunk-GSYECEZY.mjs +381 -0
- package/dist/{chunk-TWSRXUFF.mjs → chunk-NS7WHDYA.mjs} +229 -418
- package/dist/client/index.css +54 -126
- package/dist/client/index.d.mts +5 -4
- package/dist/client/index.d.ts +5 -4
- package/dist/client/index.js +555 -580
- package/dist/client/index.mjs +304 -16
- package/dist/client/ssr.css +54 -126
- package/dist/client/ssr.js +257 -580
- package/dist/client/ssr.mjs +1 -1
- package/dist/{config-D2XmHJYe.d.mts → config-BD5ZHz15.d.mts} +7 -0
- package/dist/{config-D2XmHJYe.d.ts → config-BD5ZHz15.d.ts} +7 -0
- package/dist/node/index.d.mts +2 -2
- package/dist/node/index.d.ts +2 -2
- package/dist/node/index.js +457 -118
- package/dist/node/index.mjs +93 -136
- package/package.json +2 -2
- package/src/client/app/index.tsx +25 -54
- package/src/client/theme/components/mdx/mdx-components.css +39 -20
- package/src/client/theme/styles/markdown.css +1 -1
- package/src/client/theme/styles.css +0 -1
- package/src/client/theme/ui/Layout/Layout.tsx +2 -13
- package/src/client/theme/ui/Layout/responsive.css +0 -4
- package/src/client/theme/ui/Link/Link.tsx +52 -0
- package/src/client/theme/ui/NotFound/NotFound.tsx +0 -1
- package/src/client/theme/ui/OnThisPage/OnThisPage.tsx +45 -2
- package/src/client/theme/ui/Sidebar/Sidebar.tsx +44 -40
- package/src/client/theme/ui/Sidebar/sidebar.css +25 -58
- package/src/node/cache.ts +360 -46
- package/src/node/config.ts +7 -0
- package/src/node/mdx.ts +83 -4
- package/src/node/plugin/index.ts +3 -0
- package/src/node/routes/cache.ts +5 -1
- package/src/node/routes/index.ts +17 -2
- package/src/node/ssg/index.ts +4 -0
- package/dist/Playground-B2FA34BC.mjs +0 -6
- package/dist/chunk-WPT4MWTQ.mjs +0 -89
- package/src/client/theme/styles/home.css +0 -60
package/dist/node/index.js
CHANGED
|
@@ -5,6 +5,9 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
|
5
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
6
|
var __getProtoOf = Object.getPrototypeOf;
|
|
7
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __esm = (fn, res) => function __init() {
|
|
9
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
10
|
+
};
|
|
8
11
|
var __export = (target, all) => {
|
|
9
12
|
for (var name in all)
|
|
10
13
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
@@ -27,23 +30,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
27
30
|
));
|
|
28
31
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
32
|
|
|
30
|
-
// src/node/index.ts
|
|
31
|
-
var node_exports = {};
|
|
32
|
-
__export(node_exports, {
|
|
33
|
-
default: () => boltdocs,
|
|
34
|
-
generateStaticPages: () => generateStaticPages
|
|
35
|
-
});
|
|
36
|
-
module.exports = __toCommonJS(node_exports);
|
|
37
|
-
|
|
38
|
-
// src/node/plugin/index.ts
|
|
39
|
-
var import_vite = require("vite");
|
|
40
|
-
|
|
41
|
-
// src/node/routes/index.ts
|
|
42
|
-
var import_fast_glob = __toESM(require("fast-glob"));
|
|
43
|
-
|
|
44
33
|
// src/node/utils.ts
|
|
45
|
-
var import_fs = __toESM(require("fs"));
|
|
46
|
-
var import_gray_matter = __toESM(require("gray-matter"));
|
|
47
34
|
function normalizePath(p) {
|
|
48
35
|
return p.replace(/\\/g, "/");
|
|
49
36
|
}
|
|
@@ -89,82 +76,363 @@ function fileToRoutePath(relativePath) {
|
|
|
89
76
|
function capitalize(str) {
|
|
90
77
|
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
91
78
|
}
|
|
79
|
+
var import_fs, import_gray_matter;
|
|
80
|
+
var init_utils = __esm({
|
|
81
|
+
"src/node/utils.ts"() {
|
|
82
|
+
"use strict";
|
|
83
|
+
import_fs = __toESM(require("fs"));
|
|
84
|
+
import_gray_matter = __toESM(require("gray-matter"));
|
|
85
|
+
}
|
|
86
|
+
});
|
|
92
87
|
|
|
93
88
|
// src/node/cache.ts
|
|
94
|
-
var
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
}
|
|
131
|
-
/**
|
|
132
|
-
* Manually removes a specific file from the cache.
|
|
133
|
-
* Useful when forcefully invalidating a single updated file.
|
|
134
|
-
*
|
|
135
|
-
* @param filePath - The absolute path to the file
|
|
136
|
-
*/
|
|
137
|
-
invalidate(filePath) {
|
|
138
|
-
this.entries.delete(filePath);
|
|
139
|
-
}
|
|
140
|
-
/**
|
|
141
|
-
* Clears the entire cache, forcing all files to be re-parsed on the next request.
|
|
142
|
-
* Useful when global dependencies (like config) change.
|
|
143
|
-
*/
|
|
144
|
-
invalidateAll() {
|
|
145
|
-
this.entries.clear();
|
|
146
|
-
}
|
|
147
|
-
/**
|
|
148
|
-
* Removes cached entries for files that no longer exist on the filesystem.
|
|
149
|
-
* Prevents memory leaks from deleted files.
|
|
150
|
-
*
|
|
151
|
-
* @param currentFiles - A Set of absolute file paths currently discovered on the disk
|
|
152
|
-
*/
|
|
153
|
-
pruneStale(currentFiles) {
|
|
154
|
-
for (const key of this.entries.keys()) {
|
|
155
|
-
if (!currentFiles.has(key)) {
|
|
156
|
-
this.entries.delete(key);
|
|
89
|
+
var cache_exports = {};
|
|
90
|
+
__export(cache_exports, {
|
|
91
|
+
AssetCache: () => AssetCache,
|
|
92
|
+
FileCache: () => FileCache,
|
|
93
|
+
TransformCache: () => TransformCache,
|
|
94
|
+
flushCache: () => flushCache
|
|
95
|
+
});
|
|
96
|
+
async function flushCache() {
|
|
97
|
+
await backgroundQueue.flush();
|
|
98
|
+
}
|
|
99
|
+
var import_fs2, import_path, import_crypto, import_zlib, import_util, writeFile, readFile, mkdir, rename, unlink, CACHE_DIR, ASSETS_DIR, SHARDS_DIR, DEFAULT_LRU_LIMIT, DEFAULT_COMPRESS, LRUCache, BackgroundQueue, backgroundQueue, FileCache, TransformCache, AssetCache;
|
|
100
|
+
var init_cache = __esm({
|
|
101
|
+
"src/node/cache.ts"() {
|
|
102
|
+
"use strict";
|
|
103
|
+
import_fs2 = __toESM(require("fs"));
|
|
104
|
+
import_path = __toESM(require("path"));
|
|
105
|
+
import_crypto = __toESM(require("crypto"));
|
|
106
|
+
import_zlib = __toESM(require("zlib"));
|
|
107
|
+
import_util = require("util");
|
|
108
|
+
init_utils();
|
|
109
|
+
writeFile = (0, import_util.promisify)(import_fs2.default.writeFile);
|
|
110
|
+
readFile = (0, import_util.promisify)(import_fs2.default.readFile);
|
|
111
|
+
mkdir = (0, import_util.promisify)(import_fs2.default.mkdir);
|
|
112
|
+
rename = (0, import_util.promisify)(import_fs2.default.rename);
|
|
113
|
+
unlink = (0, import_util.promisify)(import_fs2.default.unlink);
|
|
114
|
+
CACHE_DIR = process.env.BOLTDOCS_CACHE_DIR || ".boltdocs";
|
|
115
|
+
ASSETS_DIR = "assets";
|
|
116
|
+
SHARDS_DIR = "shards";
|
|
117
|
+
DEFAULT_LRU_LIMIT = parseInt(
|
|
118
|
+
process.env.BOLTDOCS_CACHE_LRU_LIMIT || "2000",
|
|
119
|
+
10
|
|
120
|
+
);
|
|
121
|
+
DEFAULT_COMPRESS = process.env.BOLTDOCS_CACHE_COMPRESS !== "0";
|
|
122
|
+
LRUCache = class {
|
|
123
|
+
constructor(limit) {
|
|
124
|
+
this.limit = limit;
|
|
157
125
|
}
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
126
|
+
cache = /* @__PURE__ */ new Map();
|
|
127
|
+
get(key) {
|
|
128
|
+
const val = this.cache.get(key);
|
|
129
|
+
if (val !== void 0) {
|
|
130
|
+
this.cache.delete(key);
|
|
131
|
+
this.cache.set(key, val);
|
|
132
|
+
}
|
|
133
|
+
return val;
|
|
134
|
+
}
|
|
135
|
+
set(key, value) {
|
|
136
|
+
if (this.cache.has(key)) {
|
|
137
|
+
this.cache.delete(key);
|
|
138
|
+
} else if (this.cache.size >= this.limit) {
|
|
139
|
+
const firstKey = this.cache.keys().next().value;
|
|
140
|
+
if (firstKey !== void 0) {
|
|
141
|
+
this.cache.delete(firstKey);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
this.cache.set(key, value);
|
|
145
|
+
}
|
|
146
|
+
get size() {
|
|
147
|
+
return this.cache.size;
|
|
148
|
+
}
|
|
149
|
+
clear() {
|
|
150
|
+
this.cache.clear();
|
|
151
|
+
}
|
|
152
|
+
};
|
|
153
|
+
BackgroundQueue = class {
|
|
154
|
+
queue = Promise.resolve();
|
|
155
|
+
pendingCount = 0;
|
|
156
|
+
add(task) {
|
|
157
|
+
this.pendingCount++;
|
|
158
|
+
this.queue = this.queue.then(task).finally(() => {
|
|
159
|
+
this.pendingCount--;
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
async flush() {
|
|
163
|
+
await this.queue;
|
|
164
|
+
}
|
|
165
|
+
get pending() {
|
|
166
|
+
return this.pendingCount;
|
|
167
|
+
}
|
|
168
|
+
};
|
|
169
|
+
backgroundQueue = new BackgroundQueue();
|
|
170
|
+
FileCache = class {
|
|
171
|
+
entries = /* @__PURE__ */ new Map();
|
|
172
|
+
cachePath = null;
|
|
173
|
+
compress;
|
|
174
|
+
constructor(options = {}) {
|
|
175
|
+
this.compress = options.compress !== void 0 ? options.compress : DEFAULT_COMPRESS;
|
|
176
|
+
if (options.name) {
|
|
177
|
+
const root = options.root || process.cwd();
|
|
178
|
+
const ext = this.compress ? "json.gz" : "json";
|
|
179
|
+
this.cachePath = import_path.default.resolve(root, CACHE_DIR, `${options.name}.${ext}`);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Loads the cache. Synchronous for startup simplicity but uses fast I/O.
|
|
184
|
+
*/
|
|
185
|
+
load() {
|
|
186
|
+
if (process.env.BOLTDOCS_NO_CACHE === "1") return;
|
|
187
|
+
if (!this.cachePath || !import_fs2.default.existsSync(this.cachePath)) return;
|
|
188
|
+
try {
|
|
189
|
+
let raw = import_fs2.default.readFileSync(this.cachePath);
|
|
190
|
+
if (this.cachePath.endsWith(".gz")) {
|
|
191
|
+
raw = import_zlib.default.gunzipSync(raw);
|
|
192
|
+
}
|
|
193
|
+
const data = JSON.parse(raw.toString("utf-8"));
|
|
194
|
+
this.entries = new Map(Object.entries(data));
|
|
195
|
+
} catch (e) {
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Saves the cache in the background.
|
|
200
|
+
*/
|
|
201
|
+
save() {
|
|
202
|
+
if (process.env.BOLTDOCS_NO_CACHE === "1") return;
|
|
203
|
+
if (!this.cachePath) return;
|
|
204
|
+
const data = Object.fromEntries(this.entries);
|
|
205
|
+
const content = JSON.stringify(data);
|
|
206
|
+
const target = this.cachePath;
|
|
207
|
+
const useCompress = this.compress;
|
|
208
|
+
backgroundQueue.add(async () => {
|
|
209
|
+
try {
|
|
210
|
+
await mkdir(import_path.default.dirname(target), { recursive: true });
|
|
211
|
+
let buffer = Buffer.from(content);
|
|
212
|
+
if (useCompress) {
|
|
213
|
+
buffer = import_zlib.default.gzipSync(buffer);
|
|
214
|
+
}
|
|
215
|
+
const tempPath = `${target}.${import_crypto.default.randomBytes(4).toString("hex")}.tmp`;
|
|
216
|
+
await writeFile(tempPath, buffer);
|
|
217
|
+
await rename(tempPath, target);
|
|
218
|
+
} catch (e) {
|
|
219
|
+
}
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
get(filePath) {
|
|
223
|
+
const entry = this.entries.get(filePath);
|
|
224
|
+
if (!entry) return null;
|
|
225
|
+
if (getFileMtime(filePath) !== entry.mtime) return null;
|
|
226
|
+
return entry.data;
|
|
227
|
+
}
|
|
228
|
+
set(filePath, data) {
|
|
229
|
+
this.entries.set(filePath, {
|
|
230
|
+
data,
|
|
231
|
+
mtime: getFileMtime(filePath)
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
isValid(filePath) {
|
|
235
|
+
const entry = this.entries.get(filePath);
|
|
236
|
+
if (!entry) return false;
|
|
237
|
+
return getFileMtime(filePath) === entry.mtime;
|
|
238
|
+
}
|
|
239
|
+
invalidate(filePath) {
|
|
240
|
+
this.entries.delete(filePath);
|
|
241
|
+
}
|
|
242
|
+
invalidateAll() {
|
|
243
|
+
this.entries.clear();
|
|
244
|
+
}
|
|
245
|
+
pruneStale(currentFiles) {
|
|
246
|
+
for (const key of this.entries.keys()) {
|
|
247
|
+
if (!currentFiles.has(key)) {
|
|
248
|
+
this.entries.delete(key);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
get size() {
|
|
253
|
+
return this.entries.size;
|
|
254
|
+
}
|
|
255
|
+
async flush() {
|
|
256
|
+
await backgroundQueue.flush();
|
|
257
|
+
}
|
|
258
|
+
};
|
|
259
|
+
TransformCache = class {
|
|
260
|
+
index = /* @__PURE__ */ new Map();
|
|
261
|
+
// key -> hash
|
|
262
|
+
memoryCache = new LRUCache(DEFAULT_LRU_LIMIT);
|
|
263
|
+
baseDir;
|
|
264
|
+
shardsDir;
|
|
265
|
+
indexPath;
|
|
266
|
+
constructor(name, root = process.cwd()) {
|
|
267
|
+
this.baseDir = import_path.default.resolve(root, CACHE_DIR, `transform-${name}`);
|
|
268
|
+
this.shardsDir = import_path.default.resolve(this.baseDir, SHARDS_DIR);
|
|
269
|
+
this.indexPath = import_path.default.resolve(this.baseDir, "index.json");
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* Loads the index into memory.
|
|
273
|
+
*/
|
|
274
|
+
load() {
|
|
275
|
+
if (process.env.BOLTDOCS_NO_CACHE === "1") return;
|
|
276
|
+
if (!import_fs2.default.existsSync(this.indexPath)) return;
|
|
277
|
+
try {
|
|
278
|
+
const data = import_fs2.default.readFileSync(this.indexPath, "utf-8");
|
|
279
|
+
this.index = new Map(Object.entries(JSON.parse(data)));
|
|
280
|
+
} catch (e) {
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
/**
|
|
284
|
+
* Persists the index in background.
|
|
285
|
+
*/
|
|
286
|
+
save() {
|
|
287
|
+
if (process.env.BOLTDOCS_NO_CACHE === "1") return;
|
|
288
|
+
const data = JSON.stringify(Object.fromEntries(this.index));
|
|
289
|
+
const target = this.indexPath;
|
|
290
|
+
backgroundQueue.add(async () => {
|
|
291
|
+
await mkdir(import_path.default.dirname(target), { recursive: true });
|
|
292
|
+
await writeFile(target, data);
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
296
|
+
* Batch Read: Retrieves multiple transformation results concurrently.
|
|
297
|
+
*/
|
|
298
|
+
async getMany(keys) {
|
|
299
|
+
const results = /* @__PURE__ */ new Map();
|
|
300
|
+
const toLoad = [];
|
|
301
|
+
for (const key of keys) {
|
|
302
|
+
const mem = this.memoryCache.get(key);
|
|
303
|
+
if (mem) results.set(key, mem);
|
|
304
|
+
else if (this.index.has(key)) toLoad.push(key);
|
|
305
|
+
}
|
|
306
|
+
if (toLoad.length > 0) {
|
|
307
|
+
const shards = await Promise.all(
|
|
308
|
+
toLoad.map(async (key) => {
|
|
309
|
+
const hash = this.index.get(key);
|
|
310
|
+
const shardPath = import_path.default.resolve(this.shardsDir, `${hash}.gz`);
|
|
311
|
+
try {
|
|
312
|
+
const compressed = await readFile(shardPath);
|
|
313
|
+
const decompressed = import_zlib.default.gunzipSync(compressed).toString("utf-8");
|
|
314
|
+
this.memoryCache.set(key, decompressed);
|
|
315
|
+
return { key, val: decompressed };
|
|
316
|
+
} catch (e) {
|
|
317
|
+
return null;
|
|
318
|
+
}
|
|
319
|
+
})
|
|
320
|
+
);
|
|
321
|
+
for (const s of shards) {
|
|
322
|
+
if (s) results.set(s.key, s.val);
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
return results;
|
|
326
|
+
}
|
|
327
|
+
/**
|
|
328
|
+
* Retrieves a cached transformation. Fast lookup via index, lazy loading from disk.
|
|
329
|
+
*/
|
|
330
|
+
get(key) {
|
|
331
|
+
const mem = this.memoryCache.get(key);
|
|
332
|
+
if (mem) return mem;
|
|
333
|
+
const hash = this.index.get(key);
|
|
334
|
+
if (!hash) return null;
|
|
335
|
+
const shardPath = import_path.default.resolve(this.shardsDir, `${hash}.gz`);
|
|
336
|
+
if (!import_fs2.default.existsSync(shardPath)) return null;
|
|
337
|
+
try {
|
|
338
|
+
const compressed = import_fs2.default.readFileSync(shardPath);
|
|
339
|
+
const decompressed = import_zlib.default.gunzipSync(compressed).toString("utf-8");
|
|
340
|
+
this.memoryCache.set(key, decompressed);
|
|
341
|
+
return decompressed;
|
|
342
|
+
} catch (e) {
|
|
343
|
+
return null;
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
/**
|
|
347
|
+
* Stores a transformation result.
|
|
348
|
+
*/
|
|
349
|
+
set(key, result) {
|
|
350
|
+
const hash = import_crypto.default.createHash("md5").update(result).digest("hex");
|
|
351
|
+
this.index.set(key, hash);
|
|
352
|
+
this.memoryCache.set(key, result);
|
|
353
|
+
const shardPath = import_path.default.resolve(this.shardsDir, `${hash}.gz`);
|
|
354
|
+
backgroundQueue.add(async () => {
|
|
355
|
+
if (import_fs2.default.existsSync(shardPath)) return;
|
|
356
|
+
await mkdir(this.shardsDir, { recursive: true });
|
|
357
|
+
const compressed = import_zlib.default.gzipSync(Buffer.from(result));
|
|
358
|
+
const tempPath = `${shardPath}.${import_crypto.default.randomBytes(4).toString("hex")}.tmp`;
|
|
359
|
+
await writeFile(tempPath, compressed);
|
|
360
|
+
await rename(tempPath, shardPath);
|
|
361
|
+
});
|
|
362
|
+
}
|
|
363
|
+
get size() {
|
|
364
|
+
return this.index.size;
|
|
365
|
+
}
|
|
366
|
+
async flush() {
|
|
367
|
+
await backgroundQueue.flush();
|
|
368
|
+
}
|
|
369
|
+
};
|
|
370
|
+
AssetCache = class {
|
|
371
|
+
assetsDir;
|
|
372
|
+
constructor(root = process.cwd()) {
|
|
373
|
+
this.assetsDir = import_path.default.resolve(root, CACHE_DIR, ASSETS_DIR);
|
|
374
|
+
}
|
|
375
|
+
getFileHash(filePath) {
|
|
376
|
+
return import_crypto.default.createHash("md5").update(import_fs2.default.readFileSync(filePath)).digest("hex");
|
|
377
|
+
}
|
|
378
|
+
get(sourcePath, cacheKey) {
|
|
379
|
+
if (!import_fs2.default.existsSync(sourcePath)) return null;
|
|
380
|
+
const sourceHash = this.getFileHash(sourcePath);
|
|
381
|
+
const cachedPath = this.getCachedPath(
|
|
382
|
+
sourcePath,
|
|
383
|
+
`${cacheKey}-${sourceHash}`
|
|
384
|
+
);
|
|
385
|
+
return import_fs2.default.existsSync(cachedPath) ? cachedPath : null;
|
|
386
|
+
}
|
|
387
|
+
set(sourcePath, cacheKey, content) {
|
|
388
|
+
const sourceHash = this.getFileHash(sourcePath);
|
|
389
|
+
const cachedPath = this.getCachedPath(
|
|
390
|
+
sourcePath,
|
|
391
|
+
`${cacheKey}-${sourceHash}`
|
|
392
|
+
);
|
|
393
|
+
backgroundQueue.add(async () => {
|
|
394
|
+
await mkdir(this.assetsDir, { recursive: true });
|
|
395
|
+
const tempPath = `${cachedPath}.${import_crypto.default.randomBytes(4).toString("hex")}.tmp`;
|
|
396
|
+
await writeFile(tempPath, content);
|
|
397
|
+
await rename(tempPath, cachedPath);
|
|
398
|
+
});
|
|
399
|
+
}
|
|
400
|
+
getCachedPath(sourcePath, cacheKey) {
|
|
401
|
+
const ext = import_path.default.extname(sourcePath);
|
|
402
|
+
const name = import_path.default.basename(sourcePath, ext);
|
|
403
|
+
const safeKey = cacheKey.replace(/[^a-z0-9]/gi, "-").toLowerCase();
|
|
404
|
+
return import_path.default.join(this.assetsDir, `${name}.${safeKey}${ext}`);
|
|
405
|
+
}
|
|
406
|
+
clear() {
|
|
407
|
+
if (import_fs2.default.existsSync(this.assetsDir)) {
|
|
408
|
+
import_fs2.default.rmSync(this.assetsDir, { recursive: true, force: true });
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
async flush() {
|
|
412
|
+
await backgroundQueue.flush();
|
|
413
|
+
}
|
|
414
|
+
};
|
|
163
415
|
}
|
|
164
|
-
};
|
|
416
|
+
});
|
|
417
|
+
|
|
418
|
+
// src/node/index.ts
|
|
419
|
+
var node_exports = {};
|
|
420
|
+
__export(node_exports, {
|
|
421
|
+
default: () => boltdocs,
|
|
422
|
+
generateStaticPages: () => generateStaticPages
|
|
423
|
+
});
|
|
424
|
+
module.exports = __toCommonJS(node_exports);
|
|
425
|
+
|
|
426
|
+
// src/node/plugin/index.ts
|
|
427
|
+
var import_vite = require("vite");
|
|
428
|
+
|
|
429
|
+
// src/node/routes/index.ts
|
|
430
|
+
var import_fast_glob = __toESM(require("fast-glob"));
|
|
431
|
+
init_utils();
|
|
165
432
|
|
|
166
433
|
// src/node/routes/cache.ts
|
|
167
|
-
|
|
434
|
+
init_cache();
|
|
435
|
+
var docCache = new FileCache({ name: "routes" });
|
|
168
436
|
function invalidateRouteCache() {
|
|
169
437
|
docCache.invalidateAll();
|
|
170
438
|
}
|
|
@@ -173,11 +441,12 @@ function invalidateFile(filePath) {
|
|
|
173
441
|
}
|
|
174
442
|
|
|
175
443
|
// src/node/routes/parser.ts
|
|
176
|
-
var
|
|
444
|
+
var import_path2 = __toESM(require("path"));
|
|
177
445
|
var import_github_slugger = __toESM(require("github-slugger"));
|
|
446
|
+
init_utils();
|
|
178
447
|
function parseDocFile(file, docsDir, basePath, config) {
|
|
179
448
|
const { data, content } = parseFrontmatter(file);
|
|
180
|
-
const relativePath = normalizePath(
|
|
449
|
+
const relativePath = normalizePath(import_path2.default.relative(docsDir, file));
|
|
181
450
|
let parts = relativePath.split("/");
|
|
182
451
|
let locale;
|
|
183
452
|
let version;
|
|
@@ -209,7 +478,7 @@ function parseDocFile(file, docsDir, basePath, config) {
|
|
|
209
478
|
const rawFileName = parts[parts.length - 1];
|
|
210
479
|
const cleanFileName = stripNumberPrefix(rawFileName);
|
|
211
480
|
const inferredTitle = stripNumberPrefix(
|
|
212
|
-
|
|
481
|
+
import_path2.default.basename(file, import_path2.default.extname(file))
|
|
213
482
|
);
|
|
214
483
|
const sidebarPosition = data.sidebarPosition ?? extractNumberPrefix(rawFileName);
|
|
215
484
|
const rawDirName = parts.length >= 2 ? parts[0] : void 0;
|
|
@@ -277,6 +546,7 @@ function compareByGroupPosition(a, b) {
|
|
|
277
546
|
|
|
278
547
|
// src/node/routes/index.ts
|
|
279
548
|
async function generateRoutes(docsDir, config, basePath = "/docs") {
|
|
549
|
+
docCache.load();
|
|
280
550
|
const files = await (0, import_fast_glob.default)(["**/*.md", "**/*.mdx"], {
|
|
281
551
|
cwd: docsDir,
|
|
282
552
|
absolute: true
|
|
@@ -285,15 +555,25 @@ async function generateRoutes(docsDir, config, basePath = "/docs") {
|
|
|
285
555
|
if (config?.i18n) {
|
|
286
556
|
docCache.invalidateAll();
|
|
287
557
|
}
|
|
558
|
+
let cacheHits = 0;
|
|
288
559
|
const parsed = await Promise.all(
|
|
289
560
|
files.map(async (file) => {
|
|
290
561
|
const cached = docCache.get(file);
|
|
291
|
-
if (cached)
|
|
562
|
+
if (cached) {
|
|
563
|
+
cacheHits++;
|
|
564
|
+
return cached;
|
|
565
|
+
}
|
|
292
566
|
const result = parseDocFile(file, docsDir, basePath, config);
|
|
293
567
|
docCache.set(file, result);
|
|
294
568
|
return result;
|
|
295
569
|
})
|
|
296
570
|
);
|
|
571
|
+
if (files.length > 0) {
|
|
572
|
+
console.log(
|
|
573
|
+
`[boltdocs] Routes generated: ${files.length} files (${cacheHits} from cache, ${files.length - cacheHits} parsed)`
|
|
574
|
+
);
|
|
575
|
+
}
|
|
576
|
+
docCache.save();
|
|
297
577
|
const groupMeta = /* @__PURE__ */ new Map();
|
|
298
578
|
for (const p of parsed) {
|
|
299
579
|
if (p.relativeDir) {
|
|
@@ -371,9 +651,9 @@ async function generateRoutes(docsDir, config, basePath = "/docs") {
|
|
|
371
651
|
var import_vite_plugin_image_optimizer = require("vite-plugin-image-optimizer");
|
|
372
652
|
|
|
373
653
|
// src/node/config.ts
|
|
374
|
-
var
|
|
654
|
+
var import_path3 = __toESM(require("path"));
|
|
375
655
|
var import_url = require("url");
|
|
376
|
-
var
|
|
656
|
+
var import_fs3 = __toESM(require("fs"));
|
|
377
657
|
var CONFIG_FILES = [
|
|
378
658
|
"boltdocs.config.js",
|
|
379
659
|
"boltdocs.config.mjs",
|
|
@@ -382,7 +662,7 @@ var CONFIG_FILES = [
|
|
|
382
662
|
async function resolveConfig(docsDir) {
|
|
383
663
|
const projectRoot = process.cwd();
|
|
384
664
|
const defaults = {
|
|
385
|
-
docsDir:
|
|
665
|
+
docsDir: import_path3.default.resolve(docsDir),
|
|
386
666
|
themeConfig: {
|
|
387
667
|
title: "Boltdocs",
|
|
388
668
|
description: "A Vite documentation framework",
|
|
@@ -393,15 +673,15 @@ async function resolveConfig(docsDir) {
|
|
|
393
673
|
}
|
|
394
674
|
};
|
|
395
675
|
for (const filename of CONFIG_FILES) {
|
|
396
|
-
const configPath =
|
|
397
|
-
if (
|
|
676
|
+
const configPath = import_path3.default.resolve(projectRoot, filename);
|
|
677
|
+
if (import_fs3.default.existsSync(configPath)) {
|
|
398
678
|
try {
|
|
399
679
|
const fileUrl = (0, import_url.pathToFileURL)(configPath).href + "?t=" + Date.now();
|
|
400
680
|
const mod = await import(fileUrl);
|
|
401
681
|
const userConfig = mod.default || mod;
|
|
402
682
|
const userThemeConfig = userConfig.themeConfig || userConfig;
|
|
403
683
|
return {
|
|
404
|
-
docsDir:
|
|
684
|
+
docsDir: import_path3.default.resolve(docsDir),
|
|
405
685
|
themeConfig: {
|
|
406
686
|
...defaults.themeConfig,
|
|
407
687
|
...userThemeConfig
|
|
@@ -420,8 +700,9 @@ async function resolveConfig(docsDir) {
|
|
|
420
700
|
}
|
|
421
701
|
|
|
422
702
|
// src/node/ssg/index.ts
|
|
423
|
-
var
|
|
424
|
-
var
|
|
703
|
+
var import_fs4 = __toESM(require("fs"));
|
|
704
|
+
var import_path4 = __toESM(require("path"));
|
|
705
|
+
init_utils();
|
|
425
706
|
var import_url2 = require("url");
|
|
426
707
|
var import_module = require("module");
|
|
427
708
|
|
|
@@ -486,15 +767,15 @@ ${entries.map(
|
|
|
486
767
|
// src/node/ssg/index.ts
|
|
487
768
|
var import_meta2 = {};
|
|
488
769
|
var _filename = (0, import_url2.fileURLToPath)(import_meta2.url);
|
|
489
|
-
var _dirname =
|
|
770
|
+
var _dirname = import_path4.default.dirname(_filename);
|
|
490
771
|
var _require = (0, import_module.createRequire)(import_meta2.url);
|
|
491
772
|
async function generateStaticPages(options) {
|
|
492
773
|
const { docsDir, outDir, config } = options;
|
|
493
774
|
const routes = await generateRoutes(docsDir, config);
|
|
494
775
|
const siteTitle = config?.themeConfig?.title || "Boltdocs";
|
|
495
776
|
const siteDescription = config?.themeConfig?.description || "";
|
|
496
|
-
const ssrModulePath =
|
|
497
|
-
if (!
|
|
777
|
+
const ssrModulePath = import_path4.default.resolve(_dirname, "../client/ssr.js");
|
|
778
|
+
if (!import_fs4.default.existsSync(ssrModulePath)) {
|
|
498
779
|
console.error(
|
|
499
780
|
"[boltdocs] SSR module not found at",
|
|
500
781
|
ssrModulePath,
|
|
@@ -503,12 +784,12 @@ async function generateStaticPages(options) {
|
|
|
503
784
|
return;
|
|
504
785
|
}
|
|
505
786
|
const { render } = _require(ssrModulePath);
|
|
506
|
-
const templatePath =
|
|
507
|
-
if (!
|
|
787
|
+
const templatePath = import_path4.default.join(outDir, "index.html");
|
|
788
|
+
if (!import_fs4.default.existsSync(templatePath)) {
|
|
508
789
|
console.warn("[boltdocs] No index.html found in outDir, skipping SSG.");
|
|
509
790
|
return;
|
|
510
791
|
}
|
|
511
|
-
const template =
|
|
792
|
+
const template = import_fs4.default.readFileSync(templatePath, "utf-8");
|
|
512
793
|
let homePageComp;
|
|
513
794
|
if (config?._homePagePath) {
|
|
514
795
|
try {
|
|
@@ -534,10 +815,10 @@ async function generateStaticPages(options) {
|
|
|
534
815
|
title: escapeHtml(pageTitle),
|
|
535
816
|
description: escapeHtml(pageDescription)
|
|
536
817
|
}).replace("<!--app-html-->", appHtml).replace(`<div id="root"></div>`, `<div id="root">${appHtml}</div>`);
|
|
537
|
-
const routeDir =
|
|
538
|
-
await
|
|
539
|
-
await
|
|
540
|
-
|
|
818
|
+
const routeDir = import_path4.default.join(outDir, route.path);
|
|
819
|
+
await import_fs4.default.promises.mkdir(routeDir, { recursive: true });
|
|
820
|
+
await import_fs4.default.promises.writeFile(
|
|
821
|
+
import_path4.default.join(routeDir, "index.html"),
|
|
541
822
|
html,
|
|
542
823
|
"utf-8"
|
|
543
824
|
);
|
|
@@ -550,16 +831,20 @@ async function generateStaticPages(options) {
|
|
|
550
831
|
routes.map((r) => r.path),
|
|
551
832
|
config
|
|
552
833
|
);
|
|
553
|
-
|
|
834
|
+
import_fs4.default.writeFileSync(import_path4.default.join(outDir, "sitemap.xml"), sitemap, "utf-8");
|
|
554
835
|
console.log(
|
|
555
836
|
`[boltdocs] Generated ${routes.length} static pages + sitemap.xml`
|
|
556
837
|
);
|
|
838
|
+
const { flushCache: flushCache2 } = await Promise.resolve().then(() => (init_cache(), cache_exports));
|
|
839
|
+
await flushCache2();
|
|
557
840
|
}
|
|
558
841
|
|
|
559
842
|
// src/node/plugin/index.ts
|
|
560
|
-
|
|
843
|
+
init_utils();
|
|
844
|
+
var import_path5 = __toESM(require("path"));
|
|
561
845
|
|
|
562
846
|
// src/node/plugin/entry.ts
|
|
847
|
+
init_utils();
|
|
563
848
|
function generateEntryCode(options, config) {
|
|
564
849
|
const homeImport = options.homePage ? `import HomePage from '${normalizePath(options.homePage)}';` : "";
|
|
565
850
|
const homeOption = options.homePage ? "homePage: HomePage," : "";
|
|
@@ -568,8 +853,8 @@ function generateEntryCode(options, config) {
|
|
|
568
853
|
const componentImports = pluginComponents.map(
|
|
569
854
|
([
|
|
570
855
|
name,
|
|
571
|
-
|
|
572
|
-
]) => `import * as _comp_${name} from '${normalizePath(
|
|
856
|
+
path6
|
|
857
|
+
]) => `import * as _comp_${name} from '${normalizePath(path6)}';
|
|
573
858
|
const ${name} = _comp_${name}.default || _comp_${name}['${name}'] || _comp_${name};`
|
|
574
859
|
).join("\n");
|
|
575
860
|
const componentMap = pluginComponents.map(([name]) => name).join(", ");
|
|
@@ -639,7 +924,7 @@ ${themeScript} </head>`);
|
|
|
639
924
|
|
|
640
925
|
// src/node/plugin/index.ts
|
|
641
926
|
function boltdocsPlugin(options = {}, passedConfig) {
|
|
642
|
-
const docsDir =
|
|
927
|
+
const docsDir = import_path5.default.resolve(process.cwd(), options.docsDir || "docs");
|
|
643
928
|
const normalizedDocsDir = normalizePath(docsDir);
|
|
644
929
|
let config = passedConfig;
|
|
645
930
|
let viteConfig;
|
|
@@ -669,7 +954,7 @@ function boltdocsPlugin(options = {}, passedConfig) {
|
|
|
669
954
|
},
|
|
670
955
|
configureServer(server) {
|
|
671
956
|
const configPaths = CONFIG_FILES.map(
|
|
672
|
-
(c) =>
|
|
957
|
+
(c) => import_path5.default.resolve(process.cwd(), c)
|
|
673
958
|
);
|
|
674
959
|
server.watcher.add(configPaths);
|
|
675
960
|
const handleFileEvent = async (file, type) => {
|
|
@@ -732,8 +1017,10 @@ function boltdocsPlugin(options = {}, passedConfig) {
|
|
|
732
1017
|
},
|
|
733
1018
|
async closeBundle() {
|
|
734
1019
|
if (!isBuild) return;
|
|
735
|
-
const outDir = viteConfig?.build?.outDir ?
|
|
1020
|
+
const outDir = viteConfig?.build?.outDir ? import_path5.default.resolve(viteConfig.root, viteConfig.build.outDir) : import_path5.default.resolve(process.cwd(), "dist");
|
|
736
1021
|
await generateStaticPages({ docsDir, outDir, config });
|
|
1022
|
+
const { flushCache: flushCache2 } = await Promise.resolve().then(() => (init_cache(), cache_exports));
|
|
1023
|
+
await flushCache2();
|
|
737
1024
|
}
|
|
738
1025
|
},
|
|
739
1026
|
(0, import_vite_plugin_image_optimizer.ViteImageOptimizer)({
|
|
@@ -763,10 +1050,14 @@ var import_remark_gfm = __toESM(require("remark-gfm"));
|
|
|
763
1050
|
var import_remark_frontmatter = __toESM(require("remark-frontmatter"));
|
|
764
1051
|
var import_rehype_slug = __toESM(require("rehype-slug"));
|
|
765
1052
|
var import_rehype_pretty_code = __toESM(require("rehype-pretty-code"));
|
|
1053
|
+
var import_crypto2 = __toESM(require("crypto"));
|
|
1054
|
+
init_cache();
|
|
1055
|
+
var mdxCache = new TransformCache("mdx");
|
|
1056
|
+
var mdxCacheLoaded = false;
|
|
766
1057
|
function boltdocsMdxPlugin(config) {
|
|
767
1058
|
const extraRemarkPlugins = config?.plugins?.flatMap((p) => p.remarkPlugins || []) || [];
|
|
768
1059
|
const extraRehypePlugins = config?.plugins?.flatMap((p) => p.rehypePlugins || []) || [];
|
|
769
|
-
|
|
1060
|
+
const baseMdxPlugin = (0, import_rollup.default)({
|
|
770
1061
|
remarkPlugins: [import_remark_gfm.default, import_remark_frontmatter.default, ...extraRemarkPlugins],
|
|
771
1062
|
rehypePlugins: [
|
|
772
1063
|
import_rehype_slug.default,
|
|
@@ -774,16 +1065,64 @@ function boltdocsMdxPlugin(config) {
|
|
|
774
1065
|
[
|
|
775
1066
|
import_rehype_pretty_code.default,
|
|
776
1067
|
{
|
|
777
|
-
theme: "one-dark-pro",
|
|
1068
|
+
theme: config?.themeConfig?.codeTheme || "one-dark-pro",
|
|
778
1069
|
keepBackground: false
|
|
779
1070
|
}
|
|
780
1071
|
]
|
|
781
1072
|
],
|
|
782
|
-
// Provide React as default for JSX
|
|
783
1073
|
jsxRuntime: "automatic",
|
|
784
1074
|
providerImportSource: "@mdx-js/react"
|
|
785
1075
|
});
|
|
1076
|
+
return {
|
|
1077
|
+
...baseMdxPlugin,
|
|
1078
|
+
name: "vite-plugin-boltdocs-mdx",
|
|
1079
|
+
async buildStart() {
|
|
1080
|
+
hits = 0;
|
|
1081
|
+
total = 0;
|
|
1082
|
+
if (!mdxCacheLoaded) {
|
|
1083
|
+
mdxCache.load();
|
|
1084
|
+
mdxCacheLoaded = true;
|
|
1085
|
+
}
|
|
1086
|
+
if (baseMdxPlugin.buildStart) {
|
|
1087
|
+
await baseMdxPlugin.buildStart.call(this);
|
|
1088
|
+
}
|
|
1089
|
+
},
|
|
1090
|
+
async transform(code, id, options) {
|
|
1091
|
+
if (!id.endsWith(".md") && !id.endsWith(".mdx")) {
|
|
1092
|
+
return baseMdxPlugin.transform?.call(this, code, id, options);
|
|
1093
|
+
}
|
|
1094
|
+
total++;
|
|
1095
|
+
const contentHash = import_crypto2.default.createHash("md5").update(code).digest("hex");
|
|
1096
|
+
const cacheKey = `${id}:${contentHash}`;
|
|
1097
|
+
const cached = mdxCache.get(cacheKey);
|
|
1098
|
+
if (cached) {
|
|
1099
|
+
hits++;
|
|
1100
|
+
return { code: cached, map: null };
|
|
1101
|
+
}
|
|
1102
|
+
const result = await baseMdxPlugin.transform.call(
|
|
1103
|
+
this,
|
|
1104
|
+
code,
|
|
1105
|
+
id,
|
|
1106
|
+
options
|
|
1107
|
+
);
|
|
1108
|
+
if (result && typeof result === "object" && result.code) {
|
|
1109
|
+
mdxCache.set(cacheKey, result.code);
|
|
1110
|
+
} else if (typeof result === "string") {
|
|
1111
|
+
mdxCache.set(cacheKey, result);
|
|
1112
|
+
}
|
|
1113
|
+
return result;
|
|
1114
|
+
},
|
|
1115
|
+
async buildEnd() {
|
|
1116
|
+
mdxCache.save();
|
|
1117
|
+
await mdxCache.flush();
|
|
1118
|
+
if (baseMdxPlugin.buildEnd) {
|
|
1119
|
+
await baseMdxPlugin.buildEnd.call(this);
|
|
1120
|
+
}
|
|
1121
|
+
}
|
|
1122
|
+
};
|
|
786
1123
|
}
|
|
1124
|
+
var hits = 0;
|
|
1125
|
+
var total = 0;
|
|
787
1126
|
|
|
788
1127
|
// src/node/index.ts
|
|
789
1128
|
async function boltdocs(options) {
|