@cudoment/cudoc 0.5.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 +3 -2
- package/dist/document.d.ts +25 -0
- package/dist/document.d.ts.map +1 -1
- package/dist/document.js +21 -1
- package/dist/document.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/node/check.d.ts +7 -4
- package/dist/node/check.d.ts.map +1 -1
- package/dist/node/check.js +368 -65
- package/dist/node/check.js.map +1 -1
- package/dist/node/cli.js +2 -81
- 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.map +1 -1
- package/dist/node/dataset.js +4 -1
- package/dist/node/dataset.js.map +1 -1
- package/dist/node/library.d.ts +9 -5
- package/dist/node/library.d.ts.map +1 -1
- package/dist/node/library.js +15 -253
- 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 +11 -0
- package/dist/node/local-target.d.ts.map +1 -1
- package/dist/node/local-target.js +54 -2
- package/dist/node/local-target.js.map +1 -1
- package/dist/node/prepare-embeds.d.ts +36 -1
- package/dist/node/prepare-embeds.d.ts.map +1 -1
- package/dist/node/prepare-embeds.js +94 -4
- 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.map +1 -1
- package/dist/node/resolve-embed.js +232 -103
- package/dist/node/resolve-embed.js.map +1 -1
- package/dist/node/roots.d.ts +12 -1
- package/dist/node/roots.d.ts.map +1 -1
- package/dist/node/roots.js +47 -11
- package/dist/node/roots.js.map +1 -1
- package/dist/node/storage.d.ts.map +1 -1
- package/dist/node/storage.js +202 -9
- package/dist/node/storage.js.map +1 -1
- package/dist/node/watch.d.ts +9 -4
- package/dist/node/watch.d.ts.map +1 -1
- package/dist/node/watch.js +51 -17
- package/dist/node/watch.js.map +1 -1
- 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 +15 -15
package/dist/node/roots.js
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
*/
|
|
12
12
|
import fs from "node:fs";
|
|
13
13
|
import path from "node:path";
|
|
14
|
-
import { posix, safePath } from "./storage.js";
|
|
14
|
+
import { posix, realPath, safePath } from "./storage.js";
|
|
15
15
|
/** `/docs/` and `docs` are the same base; `..`, `?` and `#` never are one. */
|
|
16
16
|
export function normalizeBase(base) {
|
|
17
17
|
if (base === undefined)
|
|
@@ -45,11 +45,14 @@ export function resolveRoots(options) {
|
|
|
45
45
|
throw new Error("cudoc: a root dir must not be empty");
|
|
46
46
|
return { dir: path.resolve(root.dir), base: normalizeBase(root.base) };
|
|
47
47
|
});
|
|
48
|
+
// A directory named once as it is and once through a symlink is still one
|
|
49
|
+
// directory, and its files would otherwise have two ids.
|
|
48
50
|
const dirs = new Set();
|
|
49
51
|
for (const root of roots) {
|
|
50
|
-
|
|
52
|
+
const real = realPath(root.dir);
|
|
53
|
+
if (dirs.has(root.dir) || dirs.has(real))
|
|
51
54
|
throw new Error(`cudoc: root directory listed twice: ${root.dir}`);
|
|
52
|
-
dirs.add(root.dir);
|
|
55
|
+
dirs.add(root.dir).add(real);
|
|
53
56
|
}
|
|
54
57
|
return roots;
|
|
55
58
|
}
|
|
@@ -70,20 +73,47 @@ export const libraryPath = (root, relative) => root.base ? `${root.base}/${relat
|
|
|
70
73
|
*
|
|
71
74
|
* Nested root directories are allowed — a project may collect `docs/` and
|
|
72
75
|
* give `docs/api/` its own base — and the deeper one owns the file.
|
|
76
|
+
*
|
|
77
|
+
* Containment and depth are both measured on real paths. A host may hand over
|
|
78
|
+
* the real path of a file whose root was configured through a symlink — a
|
|
79
|
+
* linked workspace, or macOS's `/tmp` for `/private/tmp` — or the other way
|
|
80
|
+
* round, and a root reached through a symlink may sit inside another root's
|
|
81
|
+
* real directory. Comparing the spellings as given would let the outer root
|
|
82
|
+
* claim a file its nested root owns whenever the host spells it the other way.
|
|
73
83
|
*/
|
|
74
84
|
export function libraryPathOf(roots, file) {
|
|
75
|
-
const
|
|
85
|
+
const owner = ownerOf(roots, file);
|
|
86
|
+
return owner && libraryPath(owner.root, owner.relative);
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* A root's real directory. It is remembered once the directory exists, so
|
|
90
|
+
* looking up a link or an asset costs one resolution of the file alone.
|
|
91
|
+
*/
|
|
92
|
+
const realDirs = new WeakMap();
|
|
93
|
+
const realDirOf = (root) => {
|
|
94
|
+
const cached = realDirs.get(root);
|
|
95
|
+
if (cached !== undefined)
|
|
96
|
+
return cached;
|
|
97
|
+
const real = realPath(root.dir);
|
|
98
|
+
if (fs.existsSync(root.dir))
|
|
99
|
+
realDirs.set(root, real);
|
|
100
|
+
return real;
|
|
101
|
+
};
|
|
102
|
+
/** The innermost root holding a file, and the file's path under it. */
|
|
103
|
+
const ownerOf = (roots, file) => {
|
|
104
|
+
const target = realPath(file);
|
|
76
105
|
let best;
|
|
77
106
|
for (const root of roots) {
|
|
78
|
-
const
|
|
107
|
+
const dir = realDirOf(root);
|
|
108
|
+
const relative = under(dir, target);
|
|
79
109
|
if (relative === undefined)
|
|
80
110
|
continue;
|
|
81
|
-
const depth =
|
|
111
|
+
const depth = dir.split(path.sep).length;
|
|
82
112
|
if (!best || depth > best.depth)
|
|
83
|
-
best = { depth,
|
|
113
|
+
best = { depth, root, relative };
|
|
84
114
|
}
|
|
85
|
-
return best
|
|
86
|
-
}
|
|
115
|
+
return best;
|
|
116
|
+
};
|
|
87
117
|
/** The document id a file collects as: its library path without the extension. */
|
|
88
118
|
export const documentIdOf = (roots, file) => libraryPathOf(roots, file)?.replace(/\.mdx?$/i, "");
|
|
89
119
|
/** Whether `libraryPath` sits under the root's base. */
|
|
@@ -102,7 +132,11 @@ const inBase = (root, target) => {
|
|
|
102
132
|
* Two roots may share a base, and one base may extend another, so the answer
|
|
103
133
|
* is a list: the caller that wants the file that exists checks each, and the
|
|
104
134
|
* caller that wants to know whether the path could exist at all takes the
|
|
105
|
-
* first. A path that would escape a root's directory is left out
|
|
135
|
+
* first. A path that would escape a root's directory is left out, and so is a
|
|
136
|
+
* file another root owns: under a nested root with a base of its own, the
|
|
137
|
+
* outer root's spelling of a file names nothing. A file the root reaches
|
|
138
|
+
* through a symlink of its own, an asset under a dot directory say, stays
|
|
139
|
+
* that root's.
|
|
106
140
|
*/
|
|
107
141
|
export function candidateFiles(roots, target) {
|
|
108
142
|
return [...roots]
|
|
@@ -112,12 +146,14 @@ export function candidateFiles(roots, target) {
|
|
|
112
146
|
const relative = inBase(root, target);
|
|
113
147
|
if (relative === undefined)
|
|
114
148
|
return [];
|
|
149
|
+
let file;
|
|
115
150
|
try {
|
|
116
|
-
|
|
151
|
+
file = safePath(root.dir, relative);
|
|
117
152
|
}
|
|
118
153
|
catch {
|
|
119
154
|
return [];
|
|
120
155
|
}
|
|
156
|
+
return ownerOf(roots, file)?.root === root ? [file] : [];
|
|
121
157
|
});
|
|
122
158
|
}
|
|
123
159
|
/**
|
package/dist/node/roots.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"roots.js","sourceRoot":"","sources":["../../src/node/roots.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,MAAM,SAAS,CAAA;AACxB,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAA;
|
|
1
|
+
{"version":3,"file":"roots.js","sourceRoot":"","sources":["../../src/node/roots.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,MAAM,SAAS,CAAA;AACxB,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAA;AAiBxD,8EAA8E;AAC9E,MAAM,UAAU,aAAa,CAAC,IAAwB;IACpD,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,EAAE,CAAA;IACjC,IAAI,OAAO,IAAI,KAAK,QAAQ;QAC1B,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAA;IACxD,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,CAAA;IAChE,IAAI,CAAC,KAAK;QAAE,OAAO,EAAE,CAAA;IACrB,IACE,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,IAAI,IAAI,KAAK,GAAG,IAAI,IAAI,KAAK,IAAI,CAAC;QACvE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC;QAElB,MAAM,IAAI,KAAK,CAAC,6BAA6B,IAAI,EAAE,CAAC,CAAA;IACtD,OAAO,KAAK,CAAA;AACd,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,OAG5B;IACC,IAAI,OAAO,CAAC,UAAU,KAAK,SAAS,IAAI,OAAO,CAAC,KAAK,KAAK,SAAS;QACjE,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAA;IACrE,MAAM,KAAK,GACT,OAAO,CAAC,KAAK;QACb,CAAC,OAAO,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC,CAAA;IACzE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM;QACxC,MAAM,IAAI,KAAK,CAAC,yDAAyD,CAAC,CAAA;IAC5E,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;QAC/B,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,OAAO,IAAI,CAAC,GAAG,KAAK,QAAQ;YACnE,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAA;QACjD,IAAI,CAAC,IAAI,CAAC,GAAG;YAAE,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAA;QACrE,OAAO,EAAE,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAA;IACxE,CAAC,CAAC,CAAA;IACF,0EAA0E;IAC1E,yDAAyD;IACzD,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAA;IAC9B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;QAC/B,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC;YACtC,MAAM,IAAI,KAAK,CAAC,uCAAuC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAA;QACpE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;IAC9B,CAAC;IACD,OAAO,KAAK,CAAA;AACd,CAAC;AAED,mFAAmF;AACnF,MAAM,KAAK,GAAG,CAAC,GAAW,EAAE,IAAY,EAAsB,EAAE;IAC9D,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAC,CAAA;IACzC,IACE,CAAC,QAAQ;QACT,QAAQ,KAAK,IAAI;QACjB,QAAQ,CAAC,UAAU,CAAC,KAAK,IAAI,CAAC,GAAG,EAAE,CAAC;QACpC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC;QAEzB,OAAO,SAAS,CAAA;IAClB,OAAO,KAAK,CAAC,QAAQ,CAAC,CAAA;AACxB,CAAC,CAAA;AAED,iEAAiE;AACjE,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,IAAkB,EAAE,QAAgB,EAAU,EAAE,CAC1E,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,IAAI,QAAQ,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAA;AAEnD;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,aAAa,CAC3B,KAA8B,EAC9B,IAAY;IAEZ,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,CAAA;IAClC,OAAO,KAAK,IAAI,WAAW,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAA;AACzD,CAAC;AAED;;;GAGG;AACH,MAAM,QAAQ,GAAG,IAAI,OAAO,EAAwB,CAAA;AACpD,MAAM,SAAS,GAAG,CAAC,IAAkB,EAAU,EAAE;IAC/C,MAAM,MAAM,GAAG,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;IACjC,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO,MAAM,CAAA;IACvC,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IAC/B,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC;QAAE,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;IACrD,OAAO,IAAI,CAAA;AACb,CAAC,CAAA;AAED,uEAAuE;AACvE,MAAM,OAAO,GAAG,CACd,KAA8B,EAC9B,IAAY,EAC0C,EAAE;IACxD,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAA;IAC7B,IAAI,IAAyE,CAAA;IAC7E,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,GAAG,GAAG,SAAS,CAAC,IAAI,CAAC,CAAA;QAC3B,MAAM,QAAQ,GAAG,KAAK,CAAC,GAAG,EAAE,MAAM,CAAC,CAAA;QACnC,IAAI,QAAQ,KAAK,SAAS;YAAE,SAAQ;QACpC,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,CAAA;QACxC,IAAI,CAAC,IAAI,IAAI,KAAK,GAAG,IAAI,CAAC,KAAK;YAAE,IAAI,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAA;IACnE,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC,CAAA;AAED,kFAAkF;AAClF,MAAM,CAAC,MAAM,YAAY,GAAG,CAC1B,KAA8B,EAC9B,IAAY,EACQ,EAAE,CAAC,aAAa,CAAC,KAAK,EAAE,IAAI,CAAC,EAAE,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAA;AAE5E,wDAAwD;AACxD,MAAM,MAAM,GAAG,CAAC,IAAkB,EAAE,MAAc,EAAsB,EAAE;IACxE,IAAI,CAAC,IAAI,CAAC,IAAI;QAAE,OAAO,MAAM,CAAA;IAC7B,IAAI,MAAM,KAAK,IAAI,CAAC,IAAI;QAAE,OAAO,EAAE,CAAA;IACnC,OAAO,MAAM,CAAC,UAAU,CAAC,GAAG,IAAI,CAAC,IAAI,GAAG,CAAC;QACvC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;QACpC,CAAC,CAAC,SAAS,CAAA;AACf,CAAC,CAAA;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,cAAc,CAC5B,KAA8B,EAC9B,MAAc;IAEd,OAAO,CAAC,GAAG,KAAK,CAAC;SACd,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;SACvC,IAAI,CACH,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CACvE;SACA,OAAO,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE;QACpB,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,CAAA;QACrC,IAAI,QAAQ,KAAK,SAAS;YAAE,OAAO,EAAE,CAAA;QACrC,IAAI,IAAY,CAAA;QAChB,IAAI,CAAC;YACH,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAA;QACrC,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,EAAE,CAAA;QACX,CAAC;QACD,OAAO,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,EAAE,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;IAC1D,CAAC,CAAC,CAAA;AACN,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,YAAY,CAC1B,KAA8B,EAC9B,MAAc;IAEd,MAAM,UAAU,GAAG,cAAc,CAAC,KAAK,EAAE,MAAM,CAAC,CAAA;IAChD,OAAO,UAAU,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,IAAI,UAAU,CAAC,CAAC,CAAC,CAAA;AACxE,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../src/node/storage.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,IAAI,GAAI,OAAO,MAAM,WACuB,CAAA;AACzD,eAAO,MAAM,KAAK,GAAI,OAAO,MAAM,WAAoC,CAAA;AACvE,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAQ/D;AACD,wBAAgB,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAI/C;AACD,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAQ/D;AACD;;;;;GAKG;AACH,wBAAgB,WAAW,CACzB,IAAI,EAAE,MAAM,EACZ,UAAU,WAAkB,EAC5B,OAAO,GAAE;IAAE,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAA;CAAO,GACxD,MAAM,EAAE,CAmBV;AACD,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,QAGrD;
|
|
1
|
+
{"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../src/node/storage.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,IAAI,GAAI,OAAO,MAAM,WACuB,CAAA;AACzD,eAAO,MAAM,KAAK,GAAI,OAAO,MAAM,WAAoC,CAAA;AACvE,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAQ/D;AACD,wBAAgB,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAI/C;AACD,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAQ/D;AACD;;;;;GAKG;AACH,wBAAgB,WAAW,CACzB,IAAI,EAAE,MAAM,EACZ,UAAU,WAAkB,EAC5B,OAAO,GAAE;IAAE,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAA;CAAO,GACxD,MAAM,EAAE,CAmBV;AACD,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,QAGrD;AA8LD;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAC9B,UAAU,EAAE,MAAM,GAAG,MAAM,EAAE,EAC7B,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,GAC/B,IAAI,CAAA;AACP,wBAAgB,gBAAgB,CAC9B,UAAU,EAAE,MAAM,GAAG,MAAM,EAAE,EAC7B,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,GACxC,OAAO,CAAC,IAAI,CAAC,CAAA"}
|
package/dist/node/storage.js
CHANGED
|
@@ -54,6 +54,195 @@ export function writeJson(file, value) {
|
|
|
54
54
|
fs.mkdirSync(path.dirname(file), { recursive: true });
|
|
55
55
|
fs.writeFileSync(file, JSON.stringify(value));
|
|
56
56
|
}
|
|
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
|
+
}
|
|
57
246
|
export function publishDirectory(inputRoots, outputRoot, build) {
|
|
58
247
|
if (fs.existsSync(outputRoot) && fs.lstatSync(outputRoot).isSymbolicLink())
|
|
59
248
|
throw new Error("cudoc: output directory must not be a symlink");
|
|
@@ -64,13 +253,18 @@ export function publishDirectory(inputRoots, outputRoot, build) {
|
|
|
64
253
|
throw new Error("cudoc: input and output directories overlap");
|
|
65
254
|
}
|
|
66
255
|
fs.mkdirSync(path.dirname(output), { recursive: true });
|
|
67
|
-
|
|
68
|
-
if (fs.existsSync(output) &&
|
|
69
|
-
(!fs.existsSync(owner) || fs.readFileSync(owner, "utf8") !== "cudoc\n"))
|
|
256
|
+
if (fs.existsSync(output) && !ownedDirectory(output))
|
|
70
257
|
throw new Error(`cudoc: refusing to replace unowned directory: ${output}`);
|
|
71
258
|
const lock = `${output}.lock`;
|
|
72
|
-
|
|
73
|
-
|
|
259
|
+
acquireLock(lock, output);
|
|
260
|
+
let staging;
|
|
261
|
+
try {
|
|
262
|
+
staging = fs.mkdtempSync(`${output}${STAGING}`);
|
|
263
|
+
}
|
|
264
|
+
catch (error) {
|
|
265
|
+
fs.unlinkSync(lock);
|
|
266
|
+
throw error;
|
|
267
|
+
}
|
|
74
268
|
const backup = `${output}.previous-${crypto.randomUUID()}`;
|
|
75
269
|
const commit = () => {
|
|
76
270
|
if (fs.existsSync(output))
|
|
@@ -83,16 +277,15 @@ export function publishDirectory(inputRoots, outputRoot, build) {
|
|
|
83
277
|
fs.renameSync(backup, output);
|
|
84
278
|
throw error;
|
|
85
279
|
}
|
|
86
|
-
|
|
280
|
+
removeOwned(backup);
|
|
87
281
|
};
|
|
88
282
|
const cleanup = () => {
|
|
89
|
-
|
|
90
|
-
fs.closeSync(fd);
|
|
283
|
+
removeOwned(staging);
|
|
91
284
|
fs.unlinkSync(lock);
|
|
92
285
|
};
|
|
93
286
|
let result;
|
|
94
287
|
try {
|
|
95
|
-
fs.writeFileSync(path.join(staging,
|
|
288
|
+
fs.writeFileSync(path.join(staging, OWNER_MARKER), OWNER_TEXT);
|
|
96
289
|
result = build(staging);
|
|
97
290
|
}
|
|
98
291
|
catch (error) {
|
package/dist/node/storage.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storage.js","sourceRoot":"","sources":["../../src/node/storage.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"storage.js","sourceRoot":"","sources":["../../src/node/storage.ts"],"names":[],"mappings":"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"}
|
package/dist/node/watch.d.ts
CHANGED
|
@@ -47,9 +47,11 @@ export type CollectionState = {
|
|
|
47
47
|
*/
|
|
48
48
|
export declare function previousCollection(outDir?: string): CollectionState;
|
|
49
49
|
/**
|
|
50
|
-
* One pass: collect, then prepare
|
|
51
|
-
*
|
|
52
|
-
* are complete either way.
|
|
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.
|
|
53
55
|
*/
|
|
54
56
|
export declare function collectDocuments(config: CollectConfig, previous?: CollectionState): Promise<CollectionPass>;
|
|
55
57
|
export type WatchOptions = {
|
|
@@ -57,7 +59,10 @@ export type WatchOptions = {
|
|
|
57
59
|
debounce?: number;
|
|
58
60
|
/** The result of every pass, the first included. */
|
|
59
61
|
onPass?: (pass: CollectionPass) => void;
|
|
60
|
-
/**
|
|
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
|
+
*/
|
|
61
66
|
onError?: (error: unknown) => void;
|
|
62
67
|
/**
|
|
63
68
|
* Whether the first pass may start from what `outDir` already holds.
|
package/dist/node/watch.d.ts.map
CHANGED
|
@@ -1 +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,
|
|
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"}
|
package/dist/node/watch.js
CHANGED
|
@@ -12,8 +12,10 @@
|
|
|
12
12
|
*/
|
|
13
13
|
import fs from "node:fs";
|
|
14
14
|
import path from "node:path";
|
|
15
|
-
import {
|
|
15
|
+
import { loadLibrary, resolveRoots, } from "./library.js";
|
|
16
|
+
import { collectLibrary, collectLibraryAsync } from "./collect.js";
|
|
16
17
|
import { prepareEmbeds } from "./prepare-embeds.js";
|
|
18
|
+
import { publishDirectory } from "./storage.js";
|
|
17
19
|
/**
|
|
18
20
|
* The library and preparation already in `outDir`, when they load and are
|
|
19
21
|
* worth reusing, so a watcher's first pass compiles only what changed since
|
|
@@ -42,23 +44,30 @@ export function previousCollection(outDir = ".cudoc/documents") {
|
|
|
42
44
|
return state;
|
|
43
45
|
}
|
|
44
46
|
/**
|
|
45
|
-
* One pass: collect, then prepare
|
|
46
|
-
*
|
|
47
|
-
* are complete either way.
|
|
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.
|
|
48
52
|
*/
|
|
49
53
|
export async function collectDocuments(config, previous = {}) {
|
|
50
54
|
const started = Date.now();
|
|
51
|
-
const outDir = config.outDir ?? ".cudoc/documents";
|
|
52
55
|
const { compiler, ...rest } = config;
|
|
53
56
|
const options = { ...rest, previous: previous.library };
|
|
54
|
-
const
|
|
55
|
-
? await
|
|
57
|
+
const collection = compiler
|
|
58
|
+
? await collectLibraryAsync({
|
|
56
59
|
...options,
|
|
57
60
|
compiler: async (...parameters) => compiler(...parameters),
|
|
58
61
|
})
|
|
59
|
-
:
|
|
60
|
-
const
|
|
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
|
+
});
|
|
62
71
|
});
|
|
63
72
|
const keys = Object.keys(prepared.blocks);
|
|
64
73
|
return {
|
|
@@ -74,9 +83,28 @@ export async function collectDocuments(config, previous = {}) {
|
|
|
74
83
|
elapsed: Date.now() - started,
|
|
75
84
|
};
|
|
76
85
|
}
|
|
77
|
-
/**
|
|
78
|
-
|
|
79
|
-
|
|
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
|
+
};
|
|
80
108
|
/**
|
|
81
109
|
* Collects once, then again whenever a `.md` or `.mdx` file under any root is
|
|
82
110
|
* created, changed, renamed or deleted. Changes that arrive while a pass runs
|
|
@@ -85,6 +113,7 @@ const isSource = (filename) => filename === null ||
|
|
|
85
113
|
*/
|
|
86
114
|
export function watchDocuments(config, options = {}) {
|
|
87
115
|
const debounce = options.debounce ?? 150;
|
|
116
|
+
const report = options.onError ?? ((error) => console.error(error));
|
|
88
117
|
const roots = resolveRoots(config);
|
|
89
118
|
let state = options.reuseOutput === false ? {} : previousCollection(config.outDir);
|
|
90
119
|
let running;
|
|
@@ -98,7 +127,7 @@ export function watchDocuments(config, options = {}) {
|
|
|
98
127
|
options.onPass?.(result);
|
|
99
128
|
}
|
|
100
129
|
catch (error) {
|
|
101
|
-
|
|
130
|
+
report(error);
|
|
102
131
|
}
|
|
103
132
|
};
|
|
104
133
|
const run = () => {
|
|
@@ -115,8 +144,8 @@ export function watchDocuments(config, options = {}) {
|
|
|
115
144
|
});
|
|
116
145
|
return running;
|
|
117
146
|
};
|
|
118
|
-
const schedule = (
|
|
119
|
-
if (closed || !isSource(filename))
|
|
147
|
+
const schedule = (root, filename) => {
|
|
148
|
+
if (closed || !isSource(root, filename))
|
|
120
149
|
return;
|
|
121
150
|
if (timer)
|
|
122
151
|
clearTimeout(timer);
|
|
@@ -125,7 +154,12 @@ export function watchDocuments(config, options = {}) {
|
|
|
125
154
|
void run();
|
|
126
155
|
}, debounce);
|
|
127
156
|
};
|
|
128
|
-
const watchers = roots.map((root) =>
|
|
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)));
|
|
129
163
|
return {
|
|
130
164
|
ready: run(),
|
|
131
165
|
close() {
|
package/dist/node/watch.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"watch.js","sourceRoot":"","sources":["../../src/node/watch.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,MAAM,SAAS,CAAA;AACxB,OAAO,IAAI,MAAM,WAAW,CAAA;AAE5B,OAAO,EACL,
|
|
1
|
+
{"version":3,"file":"watch.js","sourceRoot":"","sources":["../../src/node/watch.ts"],"names":[],"mappings":"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"}
|
package/dist/render.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Root } from "mdast";
|
|
2
2
|
import type { Root as HastRoot } from "hast";
|
|
3
|
-
import type
|
|
3
|
+
import { type DocumentNode } from "./document.js";
|
|
4
4
|
export type RenderOptions = {
|
|
5
5
|
highlight?: (code: string, language?: string) => string;
|
|
6
6
|
/** Explicit renderer for authored custom components. The callback returns HTML. */
|
package/dist/render.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../src/render.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,OAAO,CAAA;AACjC,OAAO,KAAK,EAAE,IAAI,IAAI,QAAQ,EAAkB,MAAM,MAAM,CAAA;AAI5D,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../src/render.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,OAAO,CAAA;AACjC,OAAO,KAAK,EAAE,IAAI,IAAI,QAAQ,EAAkB,MAAM,MAAM,CAAA;AAI5D,OAAO,EAAiB,KAAK,YAAY,EAAE,MAAM,eAAe,CAAA;AAEhE,MAAM,MAAM,aAAa,GAAG;IAC1B,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,KAAK,MAAM,CAAA;IACvD,mFAAmF;IACnF,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,MAAM,CAAC,CAAA;CAC5D,CAAA;AACD,wBAAgB,cAAc,CAC5B,IAAI,EAAE,IAAI,EACV,OAAO,GAAE,aAAkB,GAC1B,QAAQ,CA2EV;AACD,eAAO,MAAM,cAAc,GACzB,MAAM,IAAI,EACV,UAAS,aAAkB,KAC1B,MAA6E,CAAA"}
|