@cudoment/cudoc 0.4.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -3
- package/dist/document.d.ts +36 -1
- package/dist/document.d.ts.map +1 -1
- package/dist/document.js +54 -3
- package/dist/document.js.map +1 -1
- package/dist/internal/core/mdx/imports.d.ts +21 -0
- package/dist/internal/core/mdx/imports.d.ts.map +1 -0
- package/dist/internal/core/mdx/imports.js +80 -0
- package/dist/internal/core/mdx/imports.js.map +1 -0
- package/dist/internal/core/mdx/index.d.ts +1 -0
- package/dist/internal/core/mdx/index.d.ts.map +1 -1
- package/dist/internal/core/mdx/index.js +1 -0
- package/dist/internal/core/mdx/index.js.map +1 -1
- package/dist/internal/core/query/sections.d.ts +6 -0
- package/dist/internal/core/query/sections.d.ts.map +1 -1
- package/dist/internal/core/query/sections.js +8 -2
- package/dist/internal/core/query/sections.js.map +1 -1
- package/dist/internal/transforms/table-column-layout/create-table.d.ts.map +1 -1
- package/dist/internal/transforms/table-column-layout/create-table.js +40 -17
- package/dist/internal/transforms/table-column-layout/create-table.js.map +1 -1
- package/dist/internal/transforms/table-column-layout/index.d.ts +32 -0
- package/dist/internal/transforms/table-column-layout/index.d.ts.map +1 -1
- package/dist/internal/transforms/table-column-layout/index.js +66 -0
- package/dist/internal/transforms/table-column-layout/index.js.map +1 -1
- package/dist/markdown.d.ts +8 -0
- package/dist/markdown.d.ts.map +1 -1
- package/dist/markdown.js +9 -1
- package/dist/markdown.js.map +1 -1
- package/dist/node/check.d.ts +12 -6
- package/dist/node/check.d.ts.map +1 -1
- package/dist/node/check.js +460 -79
- package/dist/node/check.js.map +1 -1
- package/dist/node/cli.js +2 -56
- package/dist/node/cli.js.map +1 -1
- package/dist/node/collect.d.ts +41 -0
- package/dist/node/collect.d.ts.map +1 -0
- package/dist/node/collect.js +351 -0
- package/dist/node/collect.js.map +1 -0
- package/dist/node/command.d.ts +23 -0
- package/dist/node/command.d.ts.map +1 -0
- package/dist/node/command.js +116 -0
- package/dist/node/command.js.map +1 -0
- package/dist/node/dataset.d.ts +14 -1
- package/dist/node/dataset.d.ts.map +1 -1
- package/dist/node/dataset.js +44 -5
- package/dist/node/dataset.js.map +1 -1
- package/dist/node/glob.d.ts +21 -0
- package/dist/node/glob.d.ts.map +1 -0
- package/dist/node/glob.js +61 -0
- package/dist/node/glob.js.map +1 -0
- package/dist/node/library.d.ts +76 -6
- package/dist/node/library.d.ts.map +1 -1
- package/dist/node/library.js +63 -137
- package/dist/node/library.js.map +1 -1
- package/dist/node/load-ast.d.ts.map +1 -1
- package/dist/node/load-ast.js +4 -1
- package/dist/node/load-ast.js.map +1 -1
- package/dist/node/local-target.d.ts +39 -8
- package/dist/node/local-target.d.ts.map +1 -1
- package/dist/node/local-target.js +94 -13
- package/dist/node/local-target.js.map +1 -1
- package/dist/node/prepare-embeds.d.ts +52 -3
- package/dist/node/prepare-embeds.d.ts.map +1 -1
- package/dist/node/prepare-embeds.js +134 -8
- package/dist/node/prepare-embeds.js.map +1 -1
- package/dist/node/references.d.ts +39 -0
- package/dist/node/references.d.ts.map +1 -0
- package/dist/node/references.js +101 -0
- package/dist/node/references.js.map +1 -0
- package/dist/node/replace.d.ts +65 -0
- package/dist/node/replace.d.ts.map +1 -0
- package/dist/node/replace.js +285 -0
- package/dist/node/replace.js.map +1 -0
- package/dist/node/resolve-embed.d.ts +79 -1
- package/dist/node/resolve-embed.d.ts.map +1 -1
- package/dist/node/resolve-embed.js +480 -143
- package/dist/node/resolve-embed.js.map +1 -1
- package/dist/node/roots.d.ts +78 -0
- package/dist/node/roots.d.ts.map +1 -0
- package/dist/node/roots.js +170 -0
- package/dist/node/roots.js.map +1 -0
- package/dist/node/storage.d.ts +21 -3
- package/dist/node/storage.d.ts.map +1 -1
- package/dist/node/storage.js +242 -20
- package/dist/node/storage.js.map +1 -1
- package/dist/node/watch.d.ts +86 -0
- package/dist/node/watch.d.ts.map +1 -0
- package/dist/node/watch.js +174 -0
- package/dist/node/watch.js.map +1 -0
- package/dist/paged.d.ts +34 -0
- package/dist/paged.d.ts.map +1 -0
- package/dist/paged.js +44 -0
- package/dist/paged.js.map +1 -0
- package/dist/render.d.ts +1 -1
- package/dist/render.d.ts.map +1 -1
- package/dist/render.js +14 -0
- package/dist/render.js.map +1 -1
- package/dist/sections.d.ts.map +1 -1
- package/dist/sections.js +7 -3
- package/dist/sections.js.map +1 -1
- package/package.json +29 -16
- package/styles.css +5 -2
package/dist/node/storage.js
CHANGED
|
@@ -23,7 +23,14 @@ export function safePath(root, relative) {
|
|
|
23
23
|
throw new Error(`cudoc: path escapes document root: ${relative}`);
|
|
24
24
|
return target;
|
|
25
25
|
}
|
|
26
|
-
|
|
26
|
+
/**
|
|
27
|
+
* Every file under `root` with one of the extensions, sorted, as absolute
|
|
28
|
+
* paths. Dot entries and `node_modules` are always skipped; `exclude` is asked
|
|
29
|
+
* about each remaining entry's POSIX path relative to `root`, and a directory
|
|
30
|
+
* it excludes is not entered, so a symlink inside one is never seen.
|
|
31
|
+
*/
|
|
32
|
+
export function sourceFiles(root, extensions = [".md", ".mdx"], options = {}) {
|
|
33
|
+
const base = path.resolve(root);
|
|
27
34
|
const walk = (dir) => fs
|
|
28
35
|
.readdirSync(dir, { withFileTypes: true })
|
|
29
36
|
.sort((a, b) => a.name.localeCompare(b.name, "en"))
|
|
@@ -31,6 +38,8 @@ export function sourceFiles(root, extensions = [".md", ".mdx"]) {
|
|
|
31
38
|
if (entry.name.startsWith(".") || entry.name === "node_modules")
|
|
32
39
|
return [];
|
|
33
40
|
const file = path.join(dir, entry.name);
|
|
41
|
+
if (options.exclude?.(posix(path.relative(base, file))))
|
|
42
|
+
return [];
|
|
34
43
|
if (entry.isSymbolicLink())
|
|
35
44
|
throw new Error(`cudoc: symlink in source tree: ${file}`);
|
|
36
45
|
if (entry.isDirectory())
|
|
@@ -39,31 +48,225 @@ export function sourceFiles(root, extensions = [".md", ".mdx"]) {
|
|
|
39
48
|
? [file]
|
|
40
49
|
: [];
|
|
41
50
|
});
|
|
42
|
-
return walk(
|
|
51
|
+
return walk(base);
|
|
43
52
|
}
|
|
44
53
|
export function writeJson(file, value) {
|
|
45
54
|
fs.mkdirSync(path.dirname(file), { recursive: true });
|
|
46
55
|
fs.writeFileSync(file, JSON.stringify(value));
|
|
47
56
|
}
|
|
48
|
-
/**
|
|
49
|
-
|
|
57
|
+
/**
|
|
58
|
+
* Creates the lock already holding this process's id, or fails with `EEXIST`.
|
|
59
|
+
*
|
|
60
|
+
* The id is written to a file of this process's own and linked into place:
|
|
61
|
+
* `link` fails when the lock exists, as an exclusive open does, and no other
|
|
62
|
+
* process ever reads the lock before the id is in it. A file system without
|
|
63
|
+
* hard links gets the exclusive open instead, and the id right after it.
|
|
64
|
+
*/
|
|
65
|
+
function createLock(lock) {
|
|
66
|
+
const pending = `${lock}.${process.pid}-${crypto.randomUUID()}`;
|
|
67
|
+
fs.writeFileSync(pending, String(process.pid));
|
|
68
|
+
try {
|
|
69
|
+
fs.linkSync(pending, lock);
|
|
70
|
+
}
|
|
71
|
+
catch (error) {
|
|
72
|
+
if (error.code === "EEXIST")
|
|
73
|
+
throw error;
|
|
74
|
+
const fd = fs.openSync(lock, "wx");
|
|
75
|
+
try {
|
|
76
|
+
fs.writeSync(fd, String(process.pid));
|
|
77
|
+
}
|
|
78
|
+
finally {
|
|
79
|
+
fs.closeSync(fd);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
finally {
|
|
83
|
+
fs.rmSync(pending, { force: true });
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
/** The process id a lock file names, or `NaN` when it names none. */
|
|
87
|
+
const holderOf = (lock) => {
|
|
88
|
+
try {
|
|
89
|
+
return Number.parseInt(fs.readFileSync(lock, "utf8"), 10);
|
|
90
|
+
}
|
|
91
|
+
catch {
|
|
92
|
+
return Number.NaN;
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
const busy = (output, holder) => new Error(`cudoc: ${output} is being written by process ${holder}; wait for it to finish`);
|
|
96
|
+
/**
|
|
97
|
+
* Takes the lock beside an output directory, holding this process's id, and
|
|
98
|
+
* then recovers what a killed build left there.
|
|
99
|
+
*
|
|
100
|
+
* A lock whose process is gone was left by a build that was killed. A lock
|
|
101
|
+
* held by a live process is a build still running, which is reported by name
|
|
102
|
+
* rather than as `EEXIST`. A stale lock is claimed by renaming it, which only
|
|
103
|
+
* one process can do to that file, and the lock is then taken again before
|
|
104
|
+
* anything else is touched. A process that found the same stale lock but
|
|
105
|
+
* renames after another has already taken the lock over finds a live id in
|
|
106
|
+
* what it moved, puts it back and reports that build instead of taking the
|
|
107
|
+
* lock from it; one that finds the stale lock already gone tries the lock
|
|
108
|
+
* again, and gets either the lock or the name of the process that did.
|
|
109
|
+
*
|
|
110
|
+
* The staging directory and the backup a killed build was working with are
|
|
111
|
+
* recovered only by the process holding the lock. A running build's own
|
|
112
|
+
* directories exist only while it holds the lock, so whatever recovery finds
|
|
113
|
+
* belongs to no build, and a process that lost the lock cannot remove the
|
|
114
|
+
* staging directory of the one that won it. The one window left is between
|
|
115
|
+
* reading a dead id and renaming: a rename that moves a lock another process
|
|
116
|
+
* took over in that moment is put back, but a third process can create the
|
|
117
|
+
* lock while it is away. Closing that would need a rename conditioned on the
|
|
118
|
+
* file's identity, which the file system does not offer.
|
|
119
|
+
*/
|
|
120
|
+
function acquireLock(lock, output) {
|
|
121
|
+
for (;;) {
|
|
122
|
+
try {
|
|
123
|
+
createLock(lock);
|
|
124
|
+
break;
|
|
125
|
+
}
|
|
126
|
+
catch (error) {
|
|
127
|
+
if (error.code !== "EEXIST")
|
|
128
|
+
throw error;
|
|
129
|
+
}
|
|
130
|
+
const holder = holderOf(lock);
|
|
131
|
+
if (Number.isInteger(holder) && holder > 0 && processAlive(holder))
|
|
132
|
+
throw busy(output, holder);
|
|
133
|
+
const claimed = `${lock}.stale-${process.pid}-${crypto.randomUUID()}`;
|
|
134
|
+
try {
|
|
135
|
+
fs.renameSync(lock, claimed);
|
|
136
|
+
}
|
|
137
|
+
catch (error) {
|
|
138
|
+
if (error.code !== "ENOENT")
|
|
139
|
+
throw error;
|
|
140
|
+
// Another process claimed the stale lock first. Whoever takes the lock
|
|
141
|
+
// next recovers the leftovers; this one touches nothing until then.
|
|
142
|
+
continue;
|
|
143
|
+
}
|
|
144
|
+
const moved = holderOf(claimed);
|
|
145
|
+
if (moved !== holder &&
|
|
146
|
+
Number.isInteger(moved) &&
|
|
147
|
+
moved > 0 &&
|
|
148
|
+
processAlive(moved)) {
|
|
149
|
+
try {
|
|
150
|
+
fs.linkSync(claimed, lock);
|
|
151
|
+
}
|
|
152
|
+
catch {
|
|
153
|
+
// A lock is back in place already; the one moved here is not needed.
|
|
154
|
+
}
|
|
155
|
+
fs.rmSync(claimed, { force: true });
|
|
156
|
+
throw busy(output, moved);
|
|
157
|
+
}
|
|
158
|
+
fs.rmSync(claimed, { force: true });
|
|
159
|
+
}
|
|
160
|
+
// A leftover that cannot be moved or removed ends this publication, and
|
|
161
|
+
// the lock goes with it, so the next one in this process can try again.
|
|
162
|
+
try {
|
|
163
|
+
recoverLeftovers(output);
|
|
164
|
+
}
|
|
165
|
+
catch (error) {
|
|
166
|
+
fs.rmSync(lock, { force: true });
|
|
167
|
+
throw error;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
const OWNER_MARKER = ".cudoc-output";
|
|
171
|
+
const OWNER_TEXT = "cudoc\n";
|
|
172
|
+
/**
|
|
173
|
+
* Whether `dir` is a directory cudoc wrote: a real directory, not a link to
|
|
174
|
+
* one, holding the ownership marker with exactly cudoc's text. Replacing an
|
|
175
|
+
* output and recovering a killed build's leftovers both ask this, so nothing
|
|
176
|
+
* is moved or removed on a weaker test than the one that guards the output.
|
|
177
|
+
*/
|
|
178
|
+
function ownedDirectory(dir) {
|
|
179
|
+
try {
|
|
180
|
+
if (!fs.lstatSync(dir).isDirectory())
|
|
181
|
+
return false;
|
|
182
|
+
const marker = path.join(dir, OWNER_MARKER);
|
|
183
|
+
return (fs.lstatSync(marker).isFile() &&
|
|
184
|
+
fs.readFileSync(marker, "utf8") === OWNER_TEXT);
|
|
185
|
+
}
|
|
186
|
+
catch {
|
|
187
|
+
return false;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Removes a directory `ownedDirectory` accepts, its marker last. A removal
|
|
192
|
+
* that stops partway, a process killed or a file that cannot go, leaves a
|
|
193
|
+
* directory that is still owned, which the next recovery finishes.
|
|
194
|
+
*/
|
|
195
|
+
function removeOwned(dir) {
|
|
196
|
+
if (!fs.existsSync(dir))
|
|
197
|
+
return;
|
|
198
|
+
for (const entry of fs.readdirSync(dir))
|
|
199
|
+
if (entry !== OWNER_MARKER)
|
|
200
|
+
fs.rmSync(path.join(dir, entry), { recursive: true, force: true });
|
|
201
|
+
fs.rmSync(dir, { recursive: true, force: true });
|
|
202
|
+
}
|
|
203
|
+
const UUID = "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}";
|
|
204
|
+
const escape = (text) => text.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
205
|
+
/** The staging prefix; `mkdtempSync` appends six letters or digits to it. */
|
|
206
|
+
const STAGING = ".cudoc-staging-";
|
|
207
|
+
/**
|
|
208
|
+
* Puts back the backup and removes the staging directory a killed build left
|
|
209
|
+
* beside `output`. Called only with the lock held, so nothing found here is a
|
|
210
|
+
* running build's.
|
|
211
|
+
*
|
|
212
|
+
* Only the names this module gives are considered, `<output>.previous-<uuid>`
|
|
213
|
+
* for a backup and `<output>.cudoc-staging-` and the six letters or digits
|
|
214
|
+
* `mkdtemp` appends for a staging directory, and only when the directory is
|
|
215
|
+
* owned, so a copy of an output someone made by hand under another name is
|
|
216
|
+
* never touched.
|
|
217
|
+
*/
|
|
218
|
+
function recoverLeftovers(output) {
|
|
219
|
+
const dir = path.dirname(output);
|
|
220
|
+
const name = escape(path.basename(output));
|
|
221
|
+
const backup = new RegExp(`^${name}\\.previous-${UUID}$`);
|
|
222
|
+
const staging = new RegExp(`^${name}${escape(STAGING)}[A-Za-z0-9]{6}$`);
|
|
223
|
+
for (const entry of fs.readdirSync(dir)) {
|
|
224
|
+
const leftover = path.join(dir, entry);
|
|
225
|
+
if (backup.test(entry) && ownedDirectory(leftover)) {
|
|
226
|
+
if (!fs.existsSync(output))
|
|
227
|
+
fs.renameSync(leftover, output);
|
|
228
|
+
else
|
|
229
|
+
removeOwned(leftover);
|
|
230
|
+
}
|
|
231
|
+
else if (staging.test(entry) && ownedDirectory(leftover))
|
|
232
|
+
removeOwned(leftover);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
/** Whether a process id names a running process this user can see. */
|
|
236
|
+
function processAlive(pid) {
|
|
237
|
+
try {
|
|
238
|
+
process.kill(pid, 0);
|
|
239
|
+
return true;
|
|
240
|
+
}
|
|
241
|
+
catch (error) {
|
|
242
|
+
// EPERM: it exists but belongs to someone else, which still means running.
|
|
243
|
+
return error.code === "EPERM";
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
export function publishDirectory(inputRoots, outputRoot, build) {
|
|
50
247
|
if (fs.existsSync(outputRoot) && fs.lstatSync(outputRoot).isSymbolicLink())
|
|
51
248
|
throw new Error("cudoc: output directory must not be a symlink");
|
|
52
|
-
const
|
|
53
|
-
|
|
54
|
-
|
|
249
|
+
const output = realPath(outputRoot);
|
|
250
|
+
for (const inputRoot of [inputRoots].flat()) {
|
|
251
|
+
const input = realPath(inputRoot);
|
|
252
|
+
if (contained(input, output) || contained(output, input))
|
|
253
|
+
throw new Error("cudoc: input and output directories overlap");
|
|
254
|
+
}
|
|
55
255
|
fs.mkdirSync(path.dirname(output), { recursive: true });
|
|
56
|
-
|
|
57
|
-
if (fs.existsSync(output) &&
|
|
58
|
-
(!fs.existsSync(owner) || fs.readFileSync(owner, "utf8") !== "cudoc\n"))
|
|
256
|
+
if (fs.existsSync(output) && !ownedDirectory(output))
|
|
59
257
|
throw new Error(`cudoc: refusing to replace unowned directory: ${output}`);
|
|
60
258
|
const lock = `${output}.lock`;
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
const backup = `${output}.previous-${crypto.randomUUID()}`;
|
|
259
|
+
acquireLock(lock, output);
|
|
260
|
+
let staging;
|
|
64
261
|
try {
|
|
65
|
-
fs.
|
|
66
|
-
|
|
262
|
+
staging = fs.mkdtempSync(`${output}${STAGING}`);
|
|
263
|
+
}
|
|
264
|
+
catch (error) {
|
|
265
|
+
fs.unlinkSync(lock);
|
|
266
|
+
throw error;
|
|
267
|
+
}
|
|
268
|
+
const backup = `${output}.previous-${crypto.randomUUID()}`;
|
|
269
|
+
const commit = () => {
|
|
67
270
|
if (fs.existsSync(output))
|
|
68
271
|
fs.renameSync(output, backup);
|
|
69
272
|
try {
|
|
@@ -74,12 +277,31 @@ export function publishDirectory(inputRoot, outputRoot, build) {
|
|
|
74
277
|
fs.renameSync(backup, output);
|
|
75
278
|
throw error;
|
|
76
279
|
}
|
|
77
|
-
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
fs.closeSync(fd);
|
|
280
|
+
removeOwned(backup);
|
|
281
|
+
};
|
|
282
|
+
const cleanup = () => {
|
|
283
|
+
removeOwned(staging);
|
|
82
284
|
fs.unlinkSync(lock);
|
|
285
|
+
};
|
|
286
|
+
let result;
|
|
287
|
+
try {
|
|
288
|
+
fs.writeFileSync(path.join(staging, OWNER_MARKER), OWNER_TEXT);
|
|
289
|
+
result = build(staging);
|
|
290
|
+
}
|
|
291
|
+
catch (error) {
|
|
292
|
+
cleanup();
|
|
293
|
+
throw error;
|
|
294
|
+
}
|
|
295
|
+
const pending = result;
|
|
296
|
+
if (typeof pending?.then !== "function") {
|
|
297
|
+
try {
|
|
298
|
+
commit();
|
|
299
|
+
}
|
|
300
|
+
finally {
|
|
301
|
+
cleanup();
|
|
302
|
+
}
|
|
303
|
+
return;
|
|
83
304
|
}
|
|
305
|
+
return pending.then(commit).finally(cleanup);
|
|
84
306
|
}
|
|
85
307
|
//# sourceMappingURL=storage.js.map
|
package/dist/node/storage.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storage.js","sourceRoot":"","sources":["../../src/node/storage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAA;AACxB,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,MAAM,MAAM,aAAa,CAAA;AAEhC,MAAM,CAAC,MAAM,IAAI,GAAG,CAAC,KAAa,EAAE,EAAE,CACpC,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;AACzD,MAAM,CAAC,MAAM,KAAK,GAAG,CAAC,KAAa,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;AACvE,MAAM,UAAU,SAAS,CAAC,IAAY,EAAE,MAAc;IACpD,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAA;IAC5C,OAAO,CACL,QAAQ,KAAK,EAAE;QACf,CAAC,QAAQ,KAAK,IAAI;YAChB,CAAC,QAAQ,CAAC,UAAU,CAAC,KAAK,IAAI,CAAC,GAAG,EAAE,CAAC;YACrC,CAAC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAC9B,CAAA;AACH,CAAC;AACD,MAAM,UAAU,QAAQ,CAAC,MAAc;IACrC,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;IACrC,IAAI,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC;QAAE,OAAO,EAAE,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAA;IAC7D,OAAO,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAA;AAC7E,CAAC;AACD,MAAM,UAAU,QAAQ,CAAC,IAAY,EAAE,QAAgB;IACrD,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAA;IAC3C,IACE,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;QAC5C,MAAM,KAAK,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC;QAE7B,MAAM,IAAI,KAAK,CAAC,sCAAsC,QAAQ,EAAE,CAAC,CAAA;IACnE,OAAO,MAAM,CAAA;AACf,CAAC;AACD,MAAM,UAAU,WAAW,CACzB,IAAY,EACZ,UAAU,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"storage.js","sourceRoot":"","sources":["../../src/node/storage.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Collection that repeats as sources change.
|
|
3
|
+
*
|
|
4
|
+
* A pass is what the CLI's `collect` does once: build the library, then
|
|
5
|
+
* prepare the embeds. Here every pass after the first hands the previous
|
|
6
|
+
* library and the previous preparation back in, so only the documents whose
|
|
7
|
+
* text changed compile again and only the blocks that read a changed document
|
|
8
|
+
* resolve again. The watcher runs a pass when a file under any root changes,
|
|
9
|
+
* after a short quiet period, and keeps the last good result when a pass
|
|
10
|
+
* fails, so a half-typed document is an error message rather than a broken
|
|
11
|
+
* library.
|
|
12
|
+
*/
|
|
13
|
+
import type { CompiledDocument } from "../markdown.js";
|
|
14
|
+
import { type BuildDocumentsOptions, type Library } from "./library.js";
|
|
15
|
+
import { type PreparedEmbeds } from "./prepare-embeds.js";
|
|
16
|
+
/**
|
|
17
|
+
* A collection configuration as a config file exports it: the build options,
|
|
18
|
+
* where the compiler may return its result synchronously or as a promise.
|
|
19
|
+
*/
|
|
20
|
+
export type CollectConfig = Omit<BuildDocumentsOptions, "compiler"> & {
|
|
21
|
+
compiler?: (...parameters: Parameters<NonNullable<BuildDocumentsOptions["compiler"]>>) => CompiledDocument | Promise<CompiledDocument>;
|
|
22
|
+
};
|
|
23
|
+
/** What one pass produced and how much of it was new. */
|
|
24
|
+
export type CollectionPass = {
|
|
25
|
+
library: Library;
|
|
26
|
+
prepared: PreparedEmbeds;
|
|
27
|
+
documentCount: number;
|
|
28
|
+
/** Ids of the documents this pass compiled. Every document on a full pass. */
|
|
29
|
+
compiled: string[];
|
|
30
|
+
/** Documents taken from the previous library unchanged. */
|
|
31
|
+
reused: number;
|
|
32
|
+
/** Embed blocks in the library, and how many were taken from the previous preparation. */
|
|
33
|
+
blocks: number;
|
|
34
|
+
reusedBlocks: number;
|
|
35
|
+
outDir: string;
|
|
36
|
+
/** Wall-clock milliseconds the pass took. */
|
|
37
|
+
elapsed: number;
|
|
38
|
+
};
|
|
39
|
+
export type CollectionState = {
|
|
40
|
+
library?: Library;
|
|
41
|
+
prepared?: PreparedEmbeds;
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* The library and preparation already in `outDir`, when they load and are
|
|
45
|
+
* worth reusing, so a watcher's first pass compiles only what changed since
|
|
46
|
+
* the last run. Anything unreadable or incompatible means starting fresh.
|
|
47
|
+
*/
|
|
48
|
+
export declare function previousCollection(outDir?: string): CollectionState;
|
|
49
|
+
/**
|
|
50
|
+
* One pass: collect, then prepare, then publish both at once. With
|
|
51
|
+
* `previous`, an unchanged document is not compiled and an unaffected block
|
|
52
|
+
* is not resolved; the published files are complete either way. Nothing is
|
|
53
|
+
* written until every embed has resolved, so a pass that fails leaves the
|
|
54
|
+
* previous library and its prepared embeds in place, still matching.
|
|
55
|
+
*/
|
|
56
|
+
export declare function collectDocuments(config: CollectConfig, previous?: CollectionState): Promise<CollectionPass>;
|
|
57
|
+
export type WatchOptions = {
|
|
58
|
+
/** Quiet time after the last change before a pass starts, in milliseconds. Default 150. */
|
|
59
|
+
debounce?: number;
|
|
60
|
+
/** The result of every pass, the first included. */
|
|
61
|
+
onPass?: (pass: CollectionPass) => void;
|
|
62
|
+
/**
|
|
63
|
+
* A failed pass, or a watcher the system stopped. The watcher keeps the last
|
|
64
|
+
* good result and keeps running. Default: print the error to stderr.
|
|
65
|
+
*/
|
|
66
|
+
onError?: (error: unknown) => void;
|
|
67
|
+
/**
|
|
68
|
+
* Whether the first pass may start from what `outDir` already holds.
|
|
69
|
+
* Default true.
|
|
70
|
+
*/
|
|
71
|
+
reuseOutput?: boolean;
|
|
72
|
+
};
|
|
73
|
+
export type CollectionWatcher = {
|
|
74
|
+
/** Resolves when the first pass has finished, whether it succeeded or failed. */
|
|
75
|
+
ready: Promise<void>;
|
|
76
|
+
/** Stops watching. A pass in progress finishes. */
|
|
77
|
+
close(): void;
|
|
78
|
+
};
|
|
79
|
+
/**
|
|
80
|
+
* Collects once, then again whenever a `.md` or `.mdx` file under any root is
|
|
81
|
+
* created, changed, renamed or deleted. Changes that arrive while a pass runs
|
|
82
|
+
* start another pass when it finishes, so the output always reflects the
|
|
83
|
+
* latest files.
|
|
84
|
+
*/
|
|
85
|
+
export declare function watchDocuments(config: CollectConfig, options?: WatchOptions): CollectionWatcher;
|
|
86
|
+
//# sourceMappingURL=watch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"watch.d.ts","sourceRoot":"","sources":["../../src/node/watch.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAA;AACtD,OAAO,EAGL,KAAK,qBAAqB,EAC1B,KAAK,OAAO,EACb,MAAM,cAAc,CAAA;AAErB,OAAO,EAAiB,KAAK,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAGxE;;;GAGG;AACH,MAAM,MAAM,aAAa,GAAG,IAAI,CAAC,qBAAqB,EAAE,UAAU,CAAC,GAAG;IACpE,QAAQ,CAAC,EAAE,CACT,GAAG,UAAU,EAAE,UAAU,CAAC,WAAW,CAAC,qBAAqB,CAAC,UAAU,CAAC,CAAC,CAAC,KACtE,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAA;CAClD,CAAA;AAED,yDAAyD;AACzD,MAAM,MAAM,cAAc,GAAG;IAC3B,OAAO,EAAE,OAAO,CAAA;IAChB,QAAQ,EAAE,cAAc,CAAA;IACxB,aAAa,EAAE,MAAM,CAAA;IACrB,8EAA8E;IAC9E,QAAQ,EAAE,MAAM,EAAE,CAAA;IAClB,2DAA2D;IAC3D,MAAM,EAAE,MAAM,CAAA;IACd,0FAA0F;IAC1F,MAAM,EAAE,MAAM,CAAA;IACd,YAAY,EAAE,MAAM,CAAA;IACpB,MAAM,EAAE,MAAM,CAAA;IACd,6CAA6C;IAC7C,OAAO,EAAE,MAAM,CAAA;CAChB,CAAA;AAED,MAAM,MAAM,eAAe,GAAG;IAC5B,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,QAAQ,CAAC,EAAE,cAAc,CAAA;CAC1B,CAAA;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,SAAqB,GAC1B,eAAe,CAkBjB;AAED;;;;;;GAMG;AACH,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,aAAa,EACrB,QAAQ,GAAE,eAAoB,GAC7B,OAAO,CAAC,cAAc,CAAC,CAmCzB;AAED,MAAM,MAAM,YAAY,GAAG;IACzB,2FAA2F;IAC3F,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,oDAAoD;IACpD,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,cAAc,KAAK,IAAI,CAAA;IACvC;;;OAGG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAA;IAClC;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,CAAA;CACtB,CAAA;AAED,MAAM,MAAM,iBAAiB,GAAG;IAC9B,iFAAiF;IACjF,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,CAAA;IACpB,mDAAmD;IACnD,KAAK,IAAI,IAAI,CAAA;CACd,CAAA;AA0BD;;;;;GAKG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,aAAa,EACrB,OAAO,GAAE,YAAiB,GACzB,iBAAiB,CA2DnB"}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Collection that repeats as sources change.
|
|
3
|
+
*
|
|
4
|
+
* A pass is what the CLI's `collect` does once: build the library, then
|
|
5
|
+
* prepare the embeds. Here every pass after the first hands the previous
|
|
6
|
+
* library and the previous preparation back in, so only the documents whose
|
|
7
|
+
* text changed compile again and only the blocks that read a changed document
|
|
8
|
+
* resolve again. The watcher runs a pass when a file under any root changes,
|
|
9
|
+
* after a short quiet period, and keeps the last good result when a pass
|
|
10
|
+
* fails, so a half-typed document is an error message rather than a broken
|
|
11
|
+
* library.
|
|
12
|
+
*/
|
|
13
|
+
import fs from "node:fs";
|
|
14
|
+
import path from "node:path";
|
|
15
|
+
import { loadLibrary, resolveRoots, } from "./library.js";
|
|
16
|
+
import { collectLibrary, collectLibraryAsync } from "./collect.js";
|
|
17
|
+
import { prepareEmbeds } from "./prepare-embeds.js";
|
|
18
|
+
import { publishDirectory } from "./storage.js";
|
|
19
|
+
/**
|
|
20
|
+
* The library and preparation already in `outDir`, when they load and are
|
|
21
|
+
* worth reusing, so a watcher's first pass compiles only what changed since
|
|
22
|
+
* the last run. Anything unreadable or incompatible means starting fresh.
|
|
23
|
+
*/
|
|
24
|
+
export function previousCollection(outDir = ".cudoc/documents") {
|
|
25
|
+
const state = {};
|
|
26
|
+
try {
|
|
27
|
+
if (fs.existsSync(path.join(outDir, "manifest.json")))
|
|
28
|
+
state.library = loadLibrary(outDir);
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
return {};
|
|
32
|
+
}
|
|
33
|
+
try {
|
|
34
|
+
const file = path.join(outDir, "embeds.json");
|
|
35
|
+
if (state.library && fs.existsSync(file)) {
|
|
36
|
+
const prepared = JSON.parse(fs.readFileSync(file, "utf8"));
|
|
37
|
+
if (prepared?.schemaVersion === 2)
|
|
38
|
+
state.prepared = prepared;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
delete state.prepared;
|
|
43
|
+
}
|
|
44
|
+
return state;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* One pass: collect, then prepare, then publish both at once. With
|
|
48
|
+
* `previous`, an unchanged document is not compiled and an unaffected block
|
|
49
|
+
* is not resolved; the published files are complete either way. Nothing is
|
|
50
|
+
* written until every embed has resolved, so a pass that fails leaves the
|
|
51
|
+
* previous library and its prepared embeds in place, still matching.
|
|
52
|
+
*/
|
|
53
|
+
export async function collectDocuments(config, previous = {}) {
|
|
54
|
+
const started = Date.now();
|
|
55
|
+
const { compiler, ...rest } = config;
|
|
56
|
+
const options = { ...rest, previous: previous.library };
|
|
57
|
+
const collection = compiler
|
|
58
|
+
? await collectLibraryAsync({
|
|
59
|
+
...options,
|
|
60
|
+
compiler: async (...parameters) => compiler(...parameters),
|
|
61
|
+
})
|
|
62
|
+
: collectLibrary(options);
|
|
63
|
+
const { library, outDir } = collection;
|
|
64
|
+
// Assigned by the publication below, which throws if preparation fails.
|
|
65
|
+
let prepared;
|
|
66
|
+
await publishDirectory(collection.inputs, outDir, async (staging) => {
|
|
67
|
+
collection.write(staging);
|
|
68
|
+
prepared = await prepareEmbeds(library, staging, {
|
|
69
|
+
previous: previous.prepared,
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
const keys = Object.keys(prepared.blocks);
|
|
73
|
+
return {
|
|
74
|
+
library,
|
|
75
|
+
prepared,
|
|
76
|
+
documentCount: library.documents.length,
|
|
77
|
+
compiled: library.incremental?.compiled ??
|
|
78
|
+
library.documents.map((document) => document.id),
|
|
79
|
+
reused: library.incremental?.reused.length ?? 0,
|
|
80
|
+
blocks: keys.length,
|
|
81
|
+
reusedBlocks: keys.filter((key) => previous.prepared?.blocks[key] === prepared.blocks[key]).length,
|
|
82
|
+
outDir,
|
|
83
|
+
elapsed: Date.now() - started,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Whether a change may alter what collection reads: a Markdown file, a
|
|
88
|
+
* directory, or an entry that is gone, which may have been a directory
|
|
89
|
+
* renamed, moved or deleted with its documents inside. A name alone cannot
|
|
90
|
+
* tell `v1.5/` from a file, so what is still there is looked at. Dot entries
|
|
91
|
+
* and `node_modules` are never collected, so changes under them are ignored.
|
|
92
|
+
*/
|
|
93
|
+
const isSource = (root, filename) => {
|
|
94
|
+
if (filename === null)
|
|
95
|
+
return true;
|
|
96
|
+
const segments = String(filename).split(/[\\/]/);
|
|
97
|
+
if (segments.some((segment) => segment.startsWith(".") || segment === "node_modules"))
|
|
98
|
+
return false;
|
|
99
|
+
if (/\.mdx?$/i.test(segments[segments.length - 1] ?? ""))
|
|
100
|
+
return true;
|
|
101
|
+
try {
|
|
102
|
+
return fs.statSync(path.join(root, String(filename))).isDirectory();
|
|
103
|
+
}
|
|
104
|
+
catch {
|
|
105
|
+
return true;
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
/**
|
|
109
|
+
* Collects once, then again whenever a `.md` or `.mdx` file under any root is
|
|
110
|
+
* created, changed, renamed or deleted. Changes that arrive while a pass runs
|
|
111
|
+
* start another pass when it finishes, so the output always reflects the
|
|
112
|
+
* latest files.
|
|
113
|
+
*/
|
|
114
|
+
export function watchDocuments(config, options = {}) {
|
|
115
|
+
const debounce = options.debounce ?? 150;
|
|
116
|
+
const report = options.onError ?? ((error) => console.error(error));
|
|
117
|
+
const roots = resolveRoots(config);
|
|
118
|
+
let state = options.reuseOutput === false ? {} : previousCollection(config.outDir);
|
|
119
|
+
let running;
|
|
120
|
+
let pending = false;
|
|
121
|
+
let timer;
|
|
122
|
+
let closed = false;
|
|
123
|
+
const pass = async () => {
|
|
124
|
+
try {
|
|
125
|
+
const result = await collectDocuments(config, state);
|
|
126
|
+
state = { library: result.library, prepared: result.prepared };
|
|
127
|
+
options.onPass?.(result);
|
|
128
|
+
}
|
|
129
|
+
catch (error) {
|
|
130
|
+
report(error);
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
const run = () => {
|
|
134
|
+
if (running) {
|
|
135
|
+
pending = true;
|
|
136
|
+
return running;
|
|
137
|
+
}
|
|
138
|
+
running = pass().then(async () => {
|
|
139
|
+
running = undefined;
|
|
140
|
+
if (pending && !closed) {
|
|
141
|
+
pending = false;
|
|
142
|
+
await run();
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
return running;
|
|
146
|
+
};
|
|
147
|
+
const schedule = (root, filename) => {
|
|
148
|
+
if (closed || !isSource(root, filename))
|
|
149
|
+
return;
|
|
150
|
+
if (timer)
|
|
151
|
+
clearTimeout(timer);
|
|
152
|
+
timer = setTimeout(() => {
|
|
153
|
+
timer = undefined;
|
|
154
|
+
void run();
|
|
155
|
+
}, debounce);
|
|
156
|
+
};
|
|
157
|
+
const watchers = roots.map((root) =>
|
|
158
|
+
// A watcher the system gives up on — too many watched files, a root
|
|
159
|
+
// deleted — emits an error; without a listener that ends the process.
|
|
160
|
+
fs
|
|
161
|
+
.watch(root.dir, { recursive: true }, (_event, filename) => schedule(root.dir, filename))
|
|
162
|
+
.on("error", (error) => report(error)));
|
|
163
|
+
return {
|
|
164
|
+
ready: run(),
|
|
165
|
+
close() {
|
|
166
|
+
closed = true;
|
|
167
|
+
if (timer)
|
|
168
|
+
clearTimeout(timer);
|
|
169
|
+
for (const watcher of watchers)
|
|
170
|
+
watcher.close();
|
|
171
|
+
},
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
//# sourceMappingURL=watch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"watch.js","sourceRoot":"","sources":["../../src/node/watch.ts"],"names":[],"mappings":"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"}
|
package/dist/paged.d.ts
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What the paginated output formats have to agree on.
|
|
3
|
+
*
|
|
4
|
+
* A PDF is printed by a browser and a `.docx` is assembled by a writer that
|
|
5
|
+
* never sees CSS, so the only thing keeping the two in step is a shared
|
|
6
|
+
* definition rather than two implementations that happen to match. This module
|
|
7
|
+
* is browser-safe and holds no I/O.
|
|
8
|
+
*/
|
|
9
|
+
import type { Position } from "unist";
|
|
10
|
+
import type { DocumentNode } from "./document.js";
|
|
11
|
+
/** The info string an author writes on a fence to force a page break. */
|
|
12
|
+
export declare const PAGE_BREAK_FENCE = "cudoc-pagebreak";
|
|
13
|
+
/** `data.cudoc.kind` on the node the fence normalizes to. */
|
|
14
|
+
export declare const PAGE_BREAK_KIND = "pageBreak";
|
|
15
|
+
/** The class the printed stylesheets key their `break-after` rule off. */
|
|
16
|
+
export declare const PAGE_BREAK_CLASS = "cudoc-page-break";
|
|
17
|
+
/**
|
|
18
|
+
* Whether a node is an authored page break.
|
|
19
|
+
*
|
|
20
|
+
* A writer must test this **before** any generic `thematicBreak` handling: the
|
|
21
|
+
* break is carried on a `thematicBreak` because that is a childless flow node
|
|
22
|
+
* which can never swallow content, so a handler that dispatches on `type` alone
|
|
23
|
+
* turns an authored page break into a horizontal rule.
|
|
24
|
+
*/
|
|
25
|
+
export declare const isPageBreak: (node: DocumentNode) => boolean;
|
|
26
|
+
/**
|
|
27
|
+
* The node an authored break becomes.
|
|
28
|
+
*
|
|
29
|
+
* `hidden` gives it the user agent's `display: none`, so a host stylesheet
|
|
30
|
+
* cudoc does not own cannot give the empty element a margin on the primary
|
|
31
|
+
* site. The printed stylesheet turns it back on and breaks after it.
|
|
32
|
+
*/
|
|
33
|
+
export declare const pageBreakNode: (position?: Position) => DocumentNode;
|
|
34
|
+
//# sourceMappingURL=paged.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paged.d.ts","sourceRoot":"","sources":["../src/paged.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AACrC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAEjD,yEAAyE;AACzE,eAAO,MAAM,gBAAgB,oBAAoB,CAAA;AAEjD,6DAA6D;AAC7D,eAAO,MAAM,eAAe,cAAc,CAAA;AAE1C,0EAA0E;AAC1E,eAAO,MAAM,gBAAgB,qBAAqB,CAAA;AAElD;;;;;;;GAOG;AACH,eAAO,MAAM,WAAW,GAAI,MAAM,YAAY,KAAG,OACL,CAAA;AAE5C;;;;;;GAMG;AACH,eAAO,MAAM,aAAa,GAAI,WAAW,QAAQ,KAAG,YAYlD,CAAA"}
|