@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.
Files changed (102) hide show
  1. package/README.md +4 -3
  2. package/dist/document.d.ts +36 -1
  3. package/dist/document.d.ts.map +1 -1
  4. package/dist/document.js +54 -3
  5. package/dist/document.js.map +1 -1
  6. package/dist/internal/core/mdx/imports.d.ts +21 -0
  7. package/dist/internal/core/mdx/imports.d.ts.map +1 -0
  8. package/dist/internal/core/mdx/imports.js +80 -0
  9. package/dist/internal/core/mdx/imports.js.map +1 -0
  10. package/dist/internal/core/mdx/index.d.ts +1 -0
  11. package/dist/internal/core/mdx/index.d.ts.map +1 -1
  12. package/dist/internal/core/mdx/index.js +1 -0
  13. package/dist/internal/core/mdx/index.js.map +1 -1
  14. package/dist/internal/core/query/sections.d.ts +6 -0
  15. package/dist/internal/core/query/sections.d.ts.map +1 -1
  16. package/dist/internal/core/query/sections.js +8 -2
  17. package/dist/internal/core/query/sections.js.map +1 -1
  18. package/dist/internal/transforms/table-column-layout/create-table.d.ts.map +1 -1
  19. package/dist/internal/transforms/table-column-layout/create-table.js +40 -17
  20. package/dist/internal/transforms/table-column-layout/create-table.js.map +1 -1
  21. package/dist/internal/transforms/table-column-layout/index.d.ts +32 -0
  22. package/dist/internal/transforms/table-column-layout/index.d.ts.map +1 -1
  23. package/dist/internal/transforms/table-column-layout/index.js +66 -0
  24. package/dist/internal/transforms/table-column-layout/index.js.map +1 -1
  25. package/dist/markdown.d.ts +8 -0
  26. package/dist/markdown.d.ts.map +1 -1
  27. package/dist/markdown.js +9 -1
  28. package/dist/markdown.js.map +1 -1
  29. package/dist/node/check.d.ts +12 -6
  30. package/dist/node/check.d.ts.map +1 -1
  31. package/dist/node/check.js +460 -79
  32. package/dist/node/check.js.map +1 -1
  33. package/dist/node/cli.js +2 -56
  34. package/dist/node/cli.js.map +1 -1
  35. package/dist/node/collect.d.ts +41 -0
  36. package/dist/node/collect.d.ts.map +1 -0
  37. package/dist/node/collect.js +351 -0
  38. package/dist/node/collect.js.map +1 -0
  39. package/dist/node/command.d.ts +23 -0
  40. package/dist/node/command.d.ts.map +1 -0
  41. package/dist/node/command.js +116 -0
  42. package/dist/node/command.js.map +1 -0
  43. package/dist/node/dataset.d.ts +14 -1
  44. package/dist/node/dataset.d.ts.map +1 -1
  45. package/dist/node/dataset.js +44 -5
  46. package/dist/node/dataset.js.map +1 -1
  47. package/dist/node/glob.d.ts +21 -0
  48. package/dist/node/glob.d.ts.map +1 -0
  49. package/dist/node/glob.js +61 -0
  50. package/dist/node/glob.js.map +1 -0
  51. package/dist/node/library.d.ts +76 -6
  52. package/dist/node/library.d.ts.map +1 -1
  53. package/dist/node/library.js +63 -137
  54. package/dist/node/library.js.map +1 -1
  55. package/dist/node/load-ast.d.ts.map +1 -1
  56. package/dist/node/load-ast.js +4 -1
  57. package/dist/node/load-ast.js.map +1 -1
  58. package/dist/node/local-target.d.ts +39 -8
  59. package/dist/node/local-target.d.ts.map +1 -1
  60. package/dist/node/local-target.js +94 -13
  61. package/dist/node/local-target.js.map +1 -1
  62. package/dist/node/prepare-embeds.d.ts +52 -3
  63. package/dist/node/prepare-embeds.d.ts.map +1 -1
  64. package/dist/node/prepare-embeds.js +134 -8
  65. package/dist/node/prepare-embeds.js.map +1 -1
  66. package/dist/node/references.d.ts +39 -0
  67. package/dist/node/references.d.ts.map +1 -0
  68. package/dist/node/references.js +101 -0
  69. package/dist/node/references.js.map +1 -0
  70. package/dist/node/replace.d.ts +65 -0
  71. package/dist/node/replace.d.ts.map +1 -0
  72. package/dist/node/replace.js +285 -0
  73. package/dist/node/replace.js.map +1 -0
  74. package/dist/node/resolve-embed.d.ts +79 -1
  75. package/dist/node/resolve-embed.d.ts.map +1 -1
  76. package/dist/node/resolve-embed.js +480 -143
  77. package/dist/node/resolve-embed.js.map +1 -1
  78. package/dist/node/roots.d.ts +78 -0
  79. package/dist/node/roots.d.ts.map +1 -0
  80. package/dist/node/roots.js +170 -0
  81. package/dist/node/roots.js.map +1 -0
  82. package/dist/node/storage.d.ts +21 -3
  83. package/dist/node/storage.d.ts.map +1 -1
  84. package/dist/node/storage.js +242 -20
  85. package/dist/node/storage.js.map +1 -1
  86. package/dist/node/watch.d.ts +86 -0
  87. package/dist/node/watch.d.ts.map +1 -0
  88. package/dist/node/watch.js +174 -0
  89. package/dist/node/watch.js.map +1 -0
  90. package/dist/paged.d.ts +34 -0
  91. package/dist/paged.d.ts.map +1 -0
  92. package/dist/paged.js +44 -0
  93. package/dist/paged.js.map +1 -0
  94. package/dist/render.d.ts +1 -1
  95. package/dist/render.d.ts.map +1 -1
  96. package/dist/render.js +14 -0
  97. package/dist/render.js.map +1 -1
  98. package/dist/sections.d.ts.map +1 -1
  99. package/dist/sections.js +7 -3
  100. package/dist/sections.js.map +1 -1
  101. package/package.json +29 -16
  102. package/styles.css +5 -2
@@ -0,0 +1,116 @@
1
+ /**
2
+ * The `cudoc` command line as a function: arguments in, exit code out. The
3
+ * installed binary (`cli.ts`) runs it with the process's own streams; a test
4
+ * calls it directly. It is not a package entry point.
5
+ */
6
+ import fs from "node:fs";
7
+ import path from "node:path";
8
+ import { pathToFileURL } from "node:url";
9
+ import { loadLibrary } from "./library.js";
10
+ import { generateDataset } from "./dataset.js";
11
+ import { checkReferences } from "./check.js";
12
+ import { formatCheckResult } from "./report.js";
13
+ import { collectDocuments, watchDocuments } from "./watch.js";
14
+ export const USAGE = "Usage: cudoc <collect|check|dataset> --config config.mjs [--watch] [--format text|json] [--strict]";
15
+ /**
16
+ * What the process prints for a failure. cudoc's own errors describe the
17
+ * document and are printed as they read; anything else keeps its stack, since
18
+ * it is a fault rather than a finding.
19
+ */
20
+ export const describeError = (value) => {
21
+ if (!(value instanceof Error) ||
22
+ !(/^cudoc[\w-]*: /.test(value.message) || value.message === USAGE))
23
+ return value;
24
+ // A finding may wrap what caused it, a parser's message for instance. A
25
+ // cause the message already repeats, as a block's names its resolver's,
26
+ // adds nothing.
27
+ let text = value.message;
28
+ for (let cause = value.cause; cause !== undefined; cause = cause instanceof Error ? cause.cause : undefined) {
29
+ const reason = cause instanceof Error ? cause.message : String(cause);
30
+ if (!text.includes(reason.replace(/^cudoc[\w-]*: /, "")))
31
+ text += `\n caused by: ${reason}`;
32
+ }
33
+ return text;
34
+ };
35
+ const processOutput = {
36
+ out: (text) => console.log(text),
37
+ error: (value) => console.error(describeError(value)),
38
+ };
39
+ /**
40
+ * Runs one command. Resolves with the exit code; a `collect --watch` resolves
41
+ * after its first pass and keeps watching until the process is signalled.
42
+ */
43
+ export async function runCommand(argv, io = processOutput) {
44
+ try {
45
+ const [command] = argv;
46
+ const flags = new Set(argv.filter((value) => value.startsWith("--")));
47
+ const configIndex = argv.indexOf("--config");
48
+ const formatIndex = argv.indexOf("--format");
49
+ const format = formatIndex === -1 ? "text" : argv[formatIndex + 1];
50
+ if (!["collect", "check", "dataset"].includes(command ?? "") ||
51
+ configIndex === -1 ||
52
+ !argv[configIndex + 1] ||
53
+ (format !== "text" && format !== "json"))
54
+ throw new Error(USAGE);
55
+ const configPath = argv[configIndex + 1];
56
+ const config = configPath.endsWith(".json")
57
+ ? JSON.parse(fs.readFileSync(configPath, "utf8"))
58
+ : (await import(pathToFileURL(path.resolve(configPath)).href)).default;
59
+ if (command === "dataset") {
60
+ io.out(JSON.stringify(generateDataset(config)));
61
+ return 0;
62
+ }
63
+ if (command === "check") {
64
+ // Checking reads the library the last collection published, which is
65
+ // the one the host build renders from, and writes nothing. It needs no
66
+ // compiler: a host's collector script keeps that, not this config.
67
+ const outDir = config.outDir ?? ".cudoc/documents";
68
+ if (!fs.existsSync(path.join(outDir, "manifest.json")))
69
+ throw new Error(`cudoc: no collected library in ${outDir}; collect documents before checking them`);
70
+ const library = loadLibrary(outDir, undefined, config.roots ?? config.sourceRoot);
71
+ // A stored library keeps no functions: a table column that names an
72
+ // extractor is checked with the one the same configuration registers.
73
+ if (config.extractors)
74
+ library.extractors = config.extractors;
75
+ const result = checkReferences(library, config.check ?? {});
76
+ io.out(format === "json"
77
+ ? JSON.stringify(result, null, 2)
78
+ : formatCheckResult(result));
79
+ const blocking = result.issues.filter((issue) => issue.severity === "error" || flags.has("--strict"));
80
+ return blocking.length ? 1 : 0;
81
+ }
82
+ if (flags.has("--watch")) {
83
+ // The first pass starts from whatever the output directory holds, and
84
+ // every pass reports what it compiled; a failed pass is a message and
85
+ // the last good output stays in place.
86
+ const watcher = watchDocuments(config, {
87
+ onPass: ({ documentCount, compiled, reused, blocks, reusedBlocks, outDir, elapsed, }) => io.out(JSON.stringify({
88
+ documentCount,
89
+ compiled,
90
+ reused,
91
+ blocks,
92
+ reusedBlocks,
93
+ outDir,
94
+ elapsed,
95
+ })),
96
+ onError: (error) => io.error(error),
97
+ });
98
+ const stop = () => {
99
+ watcher.close();
100
+ process.exit(0);
101
+ };
102
+ process.on("SIGINT", stop);
103
+ process.on("SIGTERM", stop);
104
+ await watcher.ready;
105
+ return 0;
106
+ }
107
+ const { documentCount, outDir } = await collectDocuments(config);
108
+ io.out(JSON.stringify({ documentCount, outDir }));
109
+ return 0;
110
+ }
111
+ catch (error) {
112
+ io.error(error);
113
+ return 1;
114
+ }
115
+ }
116
+ //# sourceMappingURL=command.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"command.js","sourceRoot":"","sources":["../../src/node/command.ts"],"names":[],"mappings":"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"}
@@ -2,12 +2,25 @@ import { type ProjectionOptions } from "../dataset.js";
2
2
  export type DatasetOptions = ProjectionOptions & {
3
3
  inputDir: string;
4
4
  outDir: string;
5
+ /**
6
+ * The collected library the ASTs came from. Its roots tell the generator
7
+ * where a document's scope segment starts, and its private documents are
8
+ * left out. Without it, the scope is the first path segment and nothing is
9
+ * private.
10
+ */
11
+ library?: string;
5
12
  documents?: string[];
6
13
  scopes?: string[];
7
14
  projectionId?: string;
8
15
  requireVersion?: boolean;
9
16
  };
10
- export declare function generateDataset({ inputDir, outDir, documents, scopes, projectionId, requireVersion, ...projection }: DatasetOptions): {
17
+ /**
18
+ * The segment that names a document's scope: the first one after the longest
19
+ * root base that prefixes the id, so `docs/ko/guide` under base `docs` and
20
+ * `terms/ko/token` under base `terms` both belong to `ko`.
21
+ */
22
+ export declare const scopeOf: (id: string, bases: readonly string[]) => string;
23
+ export declare function generateDataset({ inputDir, outDir, library, documents, scopes, projectionId, requireVersion, ...projection }: DatasetOptions): {
11
24
  schemaVersion: string;
12
25
  documentCount: number;
13
26
  documents: {
@@ -1 +1 @@
1
- {"version":3,"file":"dataset.d.ts","sourceRoot":"","sources":["../../src/node/dataset.ts"],"names":[],"mappings":"AAIA,OAAO,EAAc,KAAK,iBAAiB,EAAE,MAAM,eAAe,CAAA;AAUlE,MAAM,MAAM,cAAc,GAAG,iBAAiB,GAAG;IAC/C,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,CAAC,EAAE,MAAM,EAAE,CAAA;IACpB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;IACjB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,cAAc,CAAC,EAAE,OAAO,CAAA;CACzB,CAAA;AACD,wBAAgB,eAAe,CAAC,EAC9B,QAAQ,EACR,MAAM,EACN,SAAS,EACT,MAAM,EACN,YAAuB,EACvB,cAAqB,EACrB,GAAG,UAAU,EACd,EAAE,cAAc;;;;YAiBK,MAAM;cAAQ,MAAM;oBAAc,MAAM;;EA+B7D"}
1
+ {"version":3,"file":"dataset.d.ts","sourceRoot":"","sources":["../../src/node/dataset.ts"],"names":[],"mappings":"AAIA,OAAO,EAAc,KAAK,iBAAiB,EAAE,MAAM,eAAe,CAAA;AAWlE,MAAM,MAAM,cAAc,GAAG,iBAAiB,GAAG;IAC/C,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;IACd;;;;;OAKG;IACH,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAA;IACpB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;IACjB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,cAAc,CAAC,EAAE,OAAO,CAAA;CACzB,CAAA;AAyBD;;;;GAIG;AACH,eAAO,MAAM,OAAO,GAAI,IAAI,MAAM,EAAE,OAAO,SAAS,MAAM,EAAE,KAAG,MAM9D,CAAA;AAED,wBAAgB,eAAe,CAAC,EAC9B,QAAQ,EACR,MAAM,EACN,OAAO,EACP,SAAS,EACT,MAAM,EACN,YAAuB,EACvB,cAAqB,EACrB,GAAG,UAAU,EACd,EAAE,cAAc;;;;YA8BK,MAAM;cAAQ,MAAM;oBAAc,MAAM;;EAiC7D"}
@@ -2,19 +2,56 @@ import fs from "node:fs";
2
2
  import path from "node:path";
3
3
  import { validateAstContract } from "../internal/core/ast/validate.js";
4
4
  import { projectAst } from "../dataset.js";
5
+ import { LIBRARY_SCHEMA_VERSION } from "./library.js";
5
6
  import { hash, sourceFiles, publishDirectory, safePath, posix, writeJson, } from "./storage.js";
6
- export function generateDataset({ inputDir, outDir, documents, scopes, projectionId = "custom", requireVersion = true, ...projection }) {
7
+ /** What the generator reads from a library manifest, when it is given one. */
8
+ const readLibraryFacts = (library) => {
9
+ const manifest = JSON.parse(fs.readFileSync(path.join(library, "manifest.json"), "utf8"));
10
+ if (manifest.schemaVersion !== LIBRARY_SCHEMA_VERSION ||
11
+ !Array.isArray(manifest.roots) ||
12
+ !Array.isArray(manifest.documents))
13
+ throw new Error("cudoc: incompatible document manifest; rebuild documents");
14
+ return {
15
+ bases: manifest.roots.map((root) => root.base),
16
+ privateIds: new Set(manifest.documents
17
+ .filter((doc) => doc.private)
18
+ .map((doc) => doc.id)),
19
+ };
20
+ };
21
+ /**
22
+ * The segment that names a document's scope: the first one after the longest
23
+ * root base that prefixes the id, so `docs/ko/guide` under base `docs` and
24
+ * `terms/ko/token` under base `terms` both belong to `ko`.
25
+ */
26
+ export const scopeOf = (id, bases) => {
27
+ const base = [...bases]
28
+ .filter((candidate) => !candidate || id.startsWith(`${candidate}/`))
29
+ .sort((a, b) => b.length - a.length)[0];
30
+ const rest = base ? id.slice(base.length + 1) : id;
31
+ return rest.split("/")[0];
32
+ };
33
+ export function generateDataset({ inputDir, outDir, library, documents, scopes, projectionId = "custom", requireVersion = true, ...projection }) {
34
+ const facts = library
35
+ ? readLibraryFacts(library)
36
+ : { bases: [""], privateIds: new Set() };
37
+ // A library's own `manifest.json`, or a `meta.json` beside the documents,
38
+ // sits at the top of the input; a document of that name deeper down is
39
+ // still a document.
7
40
  const entries = sourceFiles(inputDir, [".json"])
8
- .filter((file) => !["manifest.json", "meta.json"].includes(path.basename(file)))
41
+ .filter((file) => !["manifest.json", "meta.json"].includes(posix(path.relative(inputDir, file))))
9
42
  .map((file) => ({
10
43
  file,
11
44
  id: posix(path.relative(inputDir, file)).replace(/\.json$/, ""),
12
45
  }))
46
+ .filter((entry) => !facts.privateIds.has(entry.id))
13
47
  .filter((entry) => (!documents || documents.includes(entry.id)) &&
14
- (!scopes || scopes.includes(entry.id.split("/")[0])));
15
- for (const id of documents ?? [])
48
+ (!scopes || scopes.includes(scopeOf(entry.id, facts.bases))));
49
+ for (const id of documents ?? []) {
50
+ if (facts.privateIds.has(id))
51
+ throw new Error(`cudoc: dataset document is private: ${id}`);
16
52
  if (!entries.some((e) => e.id === id))
17
53
  throw new Error(`cudoc: dataset document missing: ${id}`);
54
+ }
18
55
  const inputs = [];
19
56
  publishDirectory(inputDir, outDir, (staging) => {
20
57
  for (const { file, id } of entries) {
@@ -38,7 +75,9 @@ export function generateDataset({ inputDir, outDir, documents, scopes, projectio
38
75
  projectionId,
39
76
  projection,
40
77
  documentCount: inputs.length,
41
- scopes: scopes ?? [...new Set(entries.map((e) => e.id.split("/")[0]))],
78
+ scopes: scopes ?? [
79
+ ...new Set(entries.map((e) => scopeOf(e.id, facts.bases))),
80
+ ],
42
81
  documents: inputs,
43
82
  });
44
83
  });
@@ -1 +1 @@
1
- {"version":3,"file":"dataset.js","sourceRoot":"","sources":["../../src/node/dataset.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"dataset.js","sourceRoot":"","sources":["../../src/node/dataset.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * The small glob dialect collection options use to name files.
3
+ *
4
+ * Patterns are matched against a document's library path — its root base
5
+ * followed by its path under the root directory, in POSIX form — so one
6
+ * vocabulary serves `exclude`, `private` and any later option that names
7
+ * documents. The dialect is deliberately small: `*` and `?` within a segment,
8
+ * `**` for any number of segments, and a pattern without `/` matching a file
9
+ * or directory name anywhere. There are no brace sets, character classes or
10
+ * negations, because a mistyped pattern that silently matches nothing is
11
+ * worse than a pattern an author has to spell out.
12
+ */
13
+ /**
14
+ * Compiles one pattern. A trailing `**` also matches the directory itself, so
15
+ * a walker can prune `drafts/**` at `drafts` instead of visiting every file
16
+ * beneath it.
17
+ */
18
+ export declare function globToRegExp(pattern: string): RegExp;
19
+ /** A predicate over library paths for a list of patterns; empty lists match nothing. */
20
+ export declare function globMatcher(patterns: readonly string[] | undefined, option: string): (libraryPath: string) => boolean;
21
+ //# sourceMappingURL=glob.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"glob.d.ts","sourceRoot":"","sources":["../../src/node/glob.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAOH;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CA2BpD;AAED,wFAAwF;AACxF,wBAAgB,WAAW,CACzB,QAAQ,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,EACvC,MAAM,EAAE,MAAM,GACb,CAAC,WAAW,EAAE,MAAM,KAAK,OAAO,CAUlC"}
@@ -0,0 +1,61 @@
1
+ /**
2
+ * The small glob dialect collection options use to name files.
3
+ *
4
+ * Patterns are matched against a document's library path — its root base
5
+ * followed by its path under the root directory, in POSIX form — so one
6
+ * vocabulary serves `exclude`, `private` and any later option that names
7
+ * documents. The dialect is deliberately small: `*` and `?` within a segment,
8
+ * `**` for any number of segments, and a pattern without `/` matching a file
9
+ * or directory name anywhere. There are no brace sets, character classes or
10
+ * negations, because a mistyped pattern that silently matches nothing is
11
+ * worse than a pattern an author has to spell out.
12
+ */
13
+ const escape = (value) => value.replace(/[.+^${}()|[\]\\]/g, "\\$&");
14
+ const segment = (value) => escape(value).replace(/\*/g, "[^/]*").replace(/\?/g, "[^/]");
15
+ /**
16
+ * Compiles one pattern. A trailing `**` also matches the directory itself, so
17
+ * a walker can prune `drafts/**` at `drafts` instead of visiting every file
18
+ * beneath it.
19
+ */
20
+ export function globToRegExp(pattern) {
21
+ if (typeof pattern !== "string" || !pattern.trim())
22
+ throw new Error("cudoc: a glob pattern must be a non-empty string");
23
+ const segments = pattern
24
+ .replace(/\\/g, "/")
25
+ .replace(/^\.?\//, "")
26
+ .split("/")
27
+ .filter((part) => part !== "" && part !== ".");
28
+ if (!segments.length || segments.includes(".."))
29
+ throw new Error(`cudoc: invalid glob pattern: ${pattern}`);
30
+ if (segments.length === 1 && segments[0] !== "**")
31
+ return new RegExp(`(?:^|/)${segment(segments[0])}$`);
32
+ let source = "^";
33
+ let separator = false;
34
+ segments.forEach((part, index) => {
35
+ const last = index === segments.length - 1;
36
+ if (part === "**") {
37
+ if (index === 0)
38
+ source += last ? ".*" : "(?:.*/)?";
39
+ else
40
+ source += last ? "(?:/.*)?" : "/(?:.*/)?";
41
+ separator = false;
42
+ return;
43
+ }
44
+ if (separator)
45
+ source += "/";
46
+ source += segment(part);
47
+ separator = true;
48
+ });
49
+ return new RegExp(`${source}$`);
50
+ }
51
+ /** A predicate over library paths for a list of patterns; empty lists match nothing. */
52
+ export function globMatcher(patterns, option) {
53
+ if (patterns === undefined)
54
+ return () => false;
55
+ if (!Array.isArray(patterns) ||
56
+ patterns.some((pattern) => typeof pattern !== "string"))
57
+ throw new Error(`cudoc: ${option} must be an array of glob patterns`);
58
+ const expressions = patterns.map(globToRegExp);
59
+ return (libraryPath) => expressions.some((expression) => expression.test(libraryPath));
60
+ }
61
+ //# sourceMappingURL=glob.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"glob.js","sourceRoot":"","sources":["../../src/node/glob.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,MAAM,MAAM,GAAG,CAAC,KAAa,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,mBAAmB,EAAE,MAAM,CAAC,CAAA;AAE5E,MAAM,OAAO,GAAG,CAAC,KAAa,EAAE,EAAE,CAChC,MAAM,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAA;AAE9D;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,OAAe;IAC1C,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE;QAChD,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAA;IACrE,MAAM,QAAQ,GAAG,OAAO;SACrB,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;SACnB,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC;SACrB,KAAK,CAAC,GAAG,CAAC;SACV,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,KAAK,EAAE,IAAI,IAAI,KAAK,GAAG,CAAC,CAAA;IAChD,IAAI,CAAC,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC;QAC7C,MAAM,IAAI,KAAK,CAAC,gCAAgC,OAAO,EAAE,CAAC,CAAA;IAC5D,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,IAAI,QAAQ,CAAC,CAAC,CAAC,KAAK,IAAI;QAC/C,OAAO,IAAI,MAAM,CAAC,UAAU,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAE,CAAC,GAAG,CAAC,CAAA;IACvD,IAAI,MAAM,GAAG,GAAG,CAAA;IAChB,IAAI,SAAS,GAAG,KAAK,CAAA;IACrB,QAAQ,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;QAC/B,MAAM,IAAI,GAAG,KAAK,KAAK,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAA;QAC1C,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;YAClB,IAAI,KAAK,KAAK,CAAC;gBAAE,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,UAAU,CAAA;;gBAC9C,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,WAAW,CAAA;YAC9C,SAAS,GAAG,KAAK,CAAA;YACjB,OAAM;QACR,CAAC;QACD,IAAI,SAAS;YAAE,MAAM,IAAI,GAAG,CAAA;QAC5B,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;QACvB,SAAS,GAAG,IAAI,CAAA;IAClB,CAAC,CAAC,CAAA;IACF,OAAO,IAAI,MAAM,CAAC,GAAG,MAAM,GAAG,CAAC,CAAA;AACjC,CAAC;AAED,wFAAwF;AACxF,MAAM,UAAU,WAAW,CACzB,QAAuC,EACvC,MAAc;IAEd,IAAI,QAAQ,KAAK,SAAS;QAAE,OAAO,GAAG,EAAE,CAAC,KAAK,CAAA;IAC9C,IACE,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC;QACxB,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,OAAO,KAAK,QAAQ,CAAC;QAEvD,MAAM,IAAI,KAAK,CAAC,UAAU,MAAM,oCAAoC,CAAC,CAAA;IACvE,MAAM,WAAW,GAAG,QAAQ,CAAC,GAAG,CAAC,YAAY,CAAC,CAAA;IAC9C,OAAO,CAAC,WAAW,EAAE,EAAE,CACrB,WAAW,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAA;AAClE,CAAC"}
@@ -1,6 +1,11 @@
1
1
  import type { Root } from "mdast";
2
- import { type CompiledDocument } from "../markdown.js";
2
+ import type { CompiledDocument } from "../markdown.js";
3
3
  import type { DocumentOptions } from "../document.js";
4
+ import type { TableExtractor } from "./resolve-embed.js";
5
+ import { type ResolvedRoot, type SourceRoot } from "./roots.js";
6
+ export type { SourceRoot, ResolvedRoot } from "./roots.js";
7
+ export { resolveRoots, documentIdOf, libraryPathOf, sourceFileOf, } from "./roots.js";
8
+ export { LIBRARY_SCHEMA_VERSION } from "./collect.js";
4
9
  export type SourceSnapshot = {
5
10
  text: string;
6
11
  hash: string;
@@ -14,11 +19,19 @@ export type SourceSnapshot = {
14
19
  };
15
20
  export type StoredDocument = {
16
21
  id: string;
22
+ /** The library path with its extension: the root base, then the path under the root. */
17
23
  sourcePath: string;
18
24
  route: string;
19
25
  tree: Root;
20
26
  source: SourceSnapshot;
21
27
  frontmatter: Record<string, unknown>;
28
+ /**
29
+ * Set when a `private` pattern matched the document. It is collected and
30
+ * checked like any other, and left out of exports and datasets.
31
+ */
32
+ private?: true;
33
+ /** Local names the document's own `import` statements bind, when it has any. */
34
+ imports?: string[];
22
35
  };
23
36
  export type DocumentCompiler = (source: string, context: {
24
37
  id: string;
@@ -30,12 +43,41 @@ export type Library = {
30
43
  documents: StoredDocument[];
31
44
  options: DocumentOptions;
32
45
  configuration: string;
33
- sourceRoot?: string;
46
+ /** Where the documents were read from. Runtime only; a loaded library has it when the caller supplies roots. */
47
+ roots?: ResolvedRoot[];
48
+ /** The base of every root, in root order, as the manifest records them. */
49
+ bases?: string[];
50
+ /** Cell extractors an embed table may name. Runtime only; their versions are in the configuration. */
51
+ extractors?: Record<string, TableExtractor>;
34
52
  compiler?: DocumentCompiler;
35
53
  asyncCompiler?: AsyncDocumentCompiler;
54
+ /** What an incremental build did. Runtime only; present when `previous` was given. */
55
+ incremental?: {
56
+ compiled: string[];
57
+ reused: string[];
58
+ };
36
59
  };
37
60
  export type BuildDocumentsOptions = DocumentOptions & {
38
- sourceRoot: string;
61
+ /** One directory at the top of the library: shorthand for `roots: [{ dir }]`. */
62
+ sourceRoot?: string;
63
+ /** Directories to collect, each under its own base. Exactly one of `sourceRoot` and `roots` is given. */
64
+ roots?: SourceRoot[];
65
+ /**
66
+ * Glob patterns, matched against library paths, for files and directories
67
+ * that are not documents at all: drafts, agent notes, work folders.
68
+ */
69
+ exclude?: string[];
70
+ /**
71
+ * Glob patterns, matched against library paths, for documents that are
72
+ * collected and checked but never exported or put in a dataset.
73
+ */
74
+ private?: string[];
75
+ /**
76
+ * Functions an embed table's `{ extractor }` column may name. Each carries
77
+ * a `version` that enters the library configuration, so prepared embeds go
78
+ * stale when an extractor's output changes.
79
+ */
80
+ extractors?: Record<string, TableExtractor>;
39
81
  outDir?: string;
40
82
  routeBase?: string;
41
83
  routeSuffix?: string;
@@ -45,12 +87,40 @@ export type BuildDocumentsOptions = DocumentOptions & {
45
87
  compiler?: DocumentCompiler;
46
88
  /** Identifies external compiler/plugins/configuration for persisted metadata. */
47
89
  compilerId?: string;
90
+ /**
91
+ * A library collected earlier. A document whose source text is unchanged
92
+ * is taken from it instead of compiled again, as long as the configuration
93
+ * hash is the same; a document that is new, changed or collected under a
94
+ * different configuration compiles as usual. The publication is complete
95
+ * either way.
96
+ */
97
+ previous?: Library;
48
98
  };
99
+ /**
100
+ * Compiles every document and publishes the library to `outDir`, replacing
101
+ * what was there in one step. Prepared embeds are not part of it: a separate
102
+ * `prepareEmbeds` adds `embeds.json`, and `collectDocuments` does both into
103
+ * one publication.
104
+ */
105
+ export declare function buildDocuments(options: BuildDocumentsOptions): Library;
49
106
  /** Collect async framework compilers before publishing or resolving any embeds. */
50
107
  export declare function buildDocumentsAsync(options: Omit<BuildDocumentsOptions, "compiler"> & {
51
108
  compiler: AsyncDocumentCompiler;
52
109
  }): Promise<Library>;
53
- export declare function snapshotSource(text: string, tree: Root, format: "md" | "mdx"): SourceSnapshot;
54
- export declare function buildDocuments({ sourceRoot, outDir, compiler, compilerId, routeBase, routeSuffix, routes, ...options }: BuildDocumentsOptions): Library;
55
- export declare function loadLibrary(outDir?: string, compiler?: DocumentCompiler, sourceRoot?: string): Library;
110
+ export type LoadLibraryOptions = {
111
+ /**
112
+ * Keep the loaded documents in memory and reuse them while `manifest.json`
113
+ * is byte-for-byte unchanged. For a server that renders from the library on
114
+ * every request; a one-off build has nothing to gain. The documents are
115
+ * shared between calls, so treat them as read-only.
116
+ */
117
+ cache?: boolean;
118
+ };
119
+ /**
120
+ * Reads a published library back. `roots` restores where the documents live
121
+ * on disk, which replacement and asset resolution need; a single directory is
122
+ * the shorthand for one root at the top. The bases given have to be the ones
123
+ * the library was collected with, because ids were derived from them.
124
+ */
125
+ export declare function loadLibrary(outDir?: string, compiler?: DocumentCompiler, roots?: string | SourceRoot[], options?: LoadLibraryOptions): Library;
56
126
  //# sourceMappingURL=library.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"library.d.ts","sourceRoot":"","sources":["../../src/node/library.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"library.d.ts","sourceRoot":"","sources":["../../src/node/library.ts"],"names":[],"mappings":"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"}