content-query 0.0.1 → 0.1.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 (48) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +70 -0
  3. package/dist/build-C5ef0kkR.mjs +1401 -0
  4. package/dist/build-DSyoRxkZ.d.mts +24 -0
  5. package/dist/build.d.mts +2 -0
  6. package/dist/build.mjs +2 -0
  7. package/dist/chunk-CJs4Fogs.mjs +34 -0
  8. package/dist/cli.d.mts +1 -0
  9. package/dist/cli.mjs +97 -0
  10. package/dist/computed.d.mts +37 -0
  11. package/dist/computed.mjs +138 -0
  12. package/dist/content-Crag1Uch.d.mts +99 -0
  13. package/dist/content-Dj2fQCJ5.mjs +902 -0
  14. package/dist/descriptor-Xbo9u5eR.d.mts +19 -0
  15. package/dist/diagnostics-Dol6ANtq.mjs +79 -0
  16. package/dist/dist-BQGVLZyl.mjs +5396 -0
  17. package/dist/errors-C8lWyiy2.mjs +72 -0
  18. package/dist/github-slugger-BCAkwEOL.mjs +72 -0
  19. package/dist/glob-DJmebCMM.mjs +159 -0
  20. package/dist/index.d.mts +60 -0
  21. package/dist/index.mjs +43 -0
  22. package/dist/internal/markdown.d.mts +7 -0
  23. package/dist/internal/markdown.mjs +2 -0
  24. package/dist/internal.d.mts +54 -0
  25. package/dist/internal.mjs +89 -0
  26. package/dist/loaders.d.mts +12 -0
  27. package/dist/loaders.mjs +85 -0
  28. package/dist/markdown-CZBL4Ux_.mjs +54 -0
  29. package/dist/next.d.mts +21 -0
  30. package/dist/next.mjs +142 -0
  31. package/dist/operators-BQpLfJlx.mjs +173 -0
  32. package/dist/query.d.mts +45 -0
  33. package/dist/query.mjs +2 -0
  34. package/dist/relational-types-DLniKi5S.d.mts +245 -0
  35. package/dist/runtime.d.mts +3 -0
  36. package/dist/runtime.mjs +6 -0
  37. package/dist/schema-CnCbMosm.mjs +20 -0
  38. package/dist/schema.d.mts +13 -0
  39. package/dist/schema.mjs +2 -0
  40. package/dist/server-only-CIE-FHx0.mjs +7 -0
  41. package/dist/types-BPh2cBPs.d.mts +48 -0
  42. package/dist/types-DcvHRmxO.d.mts +20 -0
  43. package/dist/types-hmDOw87q.d.mts +135 -0
  44. package/dist/validation-BvvjSUFc.mjs +84 -0
  45. package/dist/values-B7lo_2_x.mjs +900 -0
  46. package/dist/vite.d.mts +8 -0
  47. package/dist/vite.mjs +296 -0
  48. package/package.json +90 -10
@@ -0,0 +1,24 @@
1
+ import { n as CollectionRegistry } from "./types-BPh2cBPs.mjs";
2
+ import { s as InvalidRelationships, t as Content } from "./content-Crag1Uch.mjs";
3
+
4
+ //#region src/preparation/session.d.ts
5
+ type ContentSession<Registry extends CollectionRegistry = {}> = {
6
+ content: Content<Registry>;
7
+ dispose(): Promise<void>;
8
+ };
9
+ //#endregion
10
+ //#region src/preparation/build.d.ts
11
+ /** Options shared by standalone content builds and host integrations. */
12
+ type BuildContentOptions = {
13
+ /** Exact config path; omission discovers one content-query.config.{ts,mts,cts,js,mjs,cjs} file. */config?: string;
14
+ backend?: "in-memory" | "generated"; /** Generated backend output directory, relative to the application root; defaults to ./.content-query. */
15
+ outDir?: string;
16
+ watch?: boolean;
17
+ };
18
+ /**
19
+ * Builds content independently of a bundler; bind the registry through an erased type import.
20
+ * Generated watch sessions prune previous-run artifacts after their first successful publication.
21
+ */
22
+ declare function buildContent<Registry extends CollectionRegistry = {}>(...arguments_: InvalidRelationships<Registry> extends never ? [options?: BuildContentOptions] : [invalidRegistry: never]): Promise<ContentSession<Registry>>;
23
+ //#endregion
24
+ export { buildContent as n, ContentSession as r, BuildContentOptions as t };
@@ -0,0 +1,2 @@
1
+ import { n as buildContent, r as ContentSession, t as BuildContentOptions } from "./build-DSyoRxkZ.mjs";
2
+ export { type BuildContentOptions, type ContentSession, buildContent };
package/dist/build.mjs ADDED
@@ -0,0 +1,2 @@
1
+ import { n as buildContent } from "./build-C5ef0kkR.mjs";
2
+ export { buildContent };
@@ -0,0 +1,34 @@
1
+ import "node:module";
2
+ //#region \0rolldown/runtime.js
3
+ var __create = Object.create;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getProtoOf = Object.getPrototypeOf;
8
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __commonJSMin = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
10
+ var __exportAll = (all, no_symbols) => {
11
+ let target = {};
12
+ for (var name in all) __defProp(target, name, {
13
+ get: all[name],
14
+ enumerable: true
15
+ });
16
+ if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
17
+ return target;
18
+ };
19
+ var __copyProps = (to, from, except, desc) => {
20
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
21
+ key = keys[i];
22
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
23
+ get: ((k) => from[k]).bind(null, key),
24
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
25
+ });
26
+ }
27
+ return to;
28
+ };
29
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
30
+ value: mod,
31
+ enumerable: true
32
+ }) : target, mod));
33
+ //#endregion
34
+ export { __exportAll as n, __toESM as r, __commonJSMin as t };
package/dist/cli.d.mts ADDED
@@ -0,0 +1 @@
1
+ export { };
package/dist/cli.mjs ADDED
@@ -0,0 +1,97 @@
1
+ #!/usr/bin/env node
2
+ import { t as ContentError } from "./errors-C8lWyiy2.mjs";
3
+ import { t as buildAtRoot } from "./build-C5ef0kkR.mjs";
4
+ import { cac } from "cac";
5
+ //#region package.json
6
+ var version = "0.1.0";
7
+ //#endregion
8
+ //#region src/integrations/cli/arguments.ts
9
+ /** Validates one path option after CAC's automatic numeric conversion. */
10
+ function pathOption(value, flag) {
11
+ if (typeof value !== "string" && typeof value !== "number" || value === "") throw new Error(`Invalid value for ${flag}; expected a path.`);
12
+ return String(value);
13
+ }
14
+ /** Rejects repeated build options, including aliases that CAC otherwise collapses. */
15
+ function assertSingleOptions(command, arguments_) {
16
+ const used = /* @__PURE__ */ new Set();
17
+ for (const argument of arguments_) {
18
+ const name = argument.split("=", 1)[0];
19
+ const flags = name.startsWith("--") ? [name.slice(2).replace(/^no-/, "")] : name.startsWith("-") ? name.slice(1).split("") : [];
20
+ for (const flag of flags) {
21
+ const option = command.hasOption(flag);
22
+ if (option) {
23
+ if (used.has(option.name)) throw new Error(`Repeated option: --${option.name}`);
24
+ used.add(option.name);
25
+ }
26
+ }
27
+ }
28
+ }
29
+ /** Applies ContentQuery's scalar option and backend contracts to CAC's parsed values. */
30
+ function buildOptions(options) {
31
+ if (Array.isArray(options["--"]) && options["--"].length > 0) throw new Error("Unexpected arguments after --.");
32
+ const { config, backend, outDir, watch } = options;
33
+ if (backend !== void 0 && backend !== "generated" && backend !== "in-memory") throw new Error(`Invalid backend: ${JSON.stringify(backend)}`);
34
+ if (watch !== void 0 && typeof watch !== "boolean") throw new Error("Invalid value for --watch; expected a boolean.");
35
+ return {
36
+ ...config === void 0 ? {} : { config: pathOption(config, "--config") },
37
+ ...backend === void 0 ? {} : { backend },
38
+ ...outDir === void 0 ? {} : { outDir: pathOption(outDir, "--out-dir") },
39
+ ...watch === void 0 ? {} : { watch }
40
+ };
41
+ }
42
+ /** Parses build options with CAC, or prints help/version and returns no build request. */
43
+ function parseArguments(arguments_) {
44
+ const cli = cac("content-query");
45
+ let options;
46
+ const command = cli.command("build", "Build content collections for server-side queries");
47
+ command.option("-c, --config <file>", "Use an exact configuration file").option("--backend <name>", "Storage backend: generated (default) or in-memory").option("-o, --out-dir <directory>", "Output directory (default: .content-query)").option("-w, --watch", "Watch sources and rebuild after changes").action((parsed) => {
48
+ assertSingleOptions(command, arguments_);
49
+ options = buildOptions(parsed);
50
+ });
51
+ cli.help().version(version);
52
+ cli.parse([
53
+ process.execPath,
54
+ "content-query",
55
+ ...arguments_
56
+ ], { run: false });
57
+ if (cli.options.version && cli.matchedCommand) cli.outputVersion();
58
+ if (cli.options.help || cli.options.version) return;
59
+ if (!cli.matchedCommand) throw new Error("Usage: content-query build [options]. Run content-query --help for details.");
60
+ cli.runMatchedCommand();
61
+ return options;
62
+ }
63
+ //#endregion
64
+ //#region src/integrations/cli/report.ts
65
+ /** Prints structured contextual diagnostics without depending on a framework display. */
66
+ function report(cause) {
67
+ if (cause instanceof ContentError) for (const diagnostic of cause.diagnostics) console.error(`[content-query:${diagnostic.code}] ${[
68
+ diagnostic.collection,
69
+ diagnostic.id,
70
+ diagnostic.source
71
+ ].filter(Boolean).join(" ")}: ${diagnostic.message}`);
72
+ else console.error(cause instanceof Error ? cause.message : cause);
73
+ }
74
+ //#endregion
75
+ //#region src/cli.ts
76
+ try {
77
+ const options = parseArguments(process.argv.slice(2));
78
+ if (options) {
79
+ const session = await buildAtRoot(process.cwd(), options, options.watch ? (state) => {
80
+ if (state.error) report(state.error);
81
+ else console.log("[content-query] Content ready.");
82
+ } : void 0);
83
+ if (options.watch) {
84
+ process.once("SIGINT", () => {
85
+ session.dispose();
86
+ });
87
+ process.once("SIGTERM", () => {
88
+ session.dispose();
89
+ });
90
+ } else await session.dispose();
91
+ }
92
+ } catch (cause) {
93
+ report(cause);
94
+ process.exitCode = 1;
95
+ }
96
+ //#endregion
97
+ export {};
@@ -0,0 +1,37 @@
1
+ import { f as MaybePromise } from "./types-hmDOw87q.mjs";
2
+ import { r as ComputedContext } from "./types-BPh2cBPs.mjs";
3
+ import { StandardSchemaV1 } from "@standard-schema/spec";
4
+
5
+ //#region src/computed/text.d.ts
6
+ /** The syntax removed before computing text-derived fields; literal text preserves all characters. */
7
+ type TextFormat = "markdown" | "text" | "html";
8
+ /** Selects text from validated entry data or loader metadata instead of the captured body. */
9
+ type TextOptions<Data = Record<string, unknown>, Source = unknown> = {
10
+ /** Defaults to readBody(); undefined text is treated as an empty string. Async selectors are supported. */from?: (context: ComputedContext<Data, Source>) => MaybePromise<string | undefined>; /** Input syntax, defaulting to markdown. */
11
+ format?: TextFormat;
12
+ };
13
+ /** Controls the reading-speed estimate in addition to selecting its input text. */
14
+ type ReadingTimeOptions<Data = Record<string, unknown>, Source = unknown> = TextOptions<Data, Source> & {
15
+ /** A finite positive reading speed, defaulting to 200 words per minute. */wordsPerMinute?: number;
16
+ };
17
+ /** Controls the maximum excerpt size in addition to selecting its input text. */
18
+ type ExcerptOptions<Data = Record<string, unknown>, Source = unknown> = TextOptions<Data, Source> & {
19
+ /** A positive integer, defaulting to 160. Counts graphemes and includes the trailing ellipsis. */maxLength?: number;
20
+ };
21
+ /** Creates a numeric computed field counting normalized text with reading-time's word boundaries. */
22
+ declare function wordCount<Data = Record<string, unknown>, Source = unknown>(options?: TextOptions<Data, Source>): {
23
+ schema: StandardSchemaV1<unknown, number>; /** Resolves selected text during preparation and honors cancellation around asynchronous input. */
24
+ resolve(context: ComputedContext<Data, Source>): Promise<number>;
25
+ };
26
+ /** Creates a numeric computed field estimating whole reading minutes, rounded up; empty text returns zero. */
27
+ declare function readingTime<Data = Record<string, unknown>, Source = unknown>(options?: ReadingTimeOptions<Data, Source>): {
28
+ schema: StandardSchemaV1<unknown, number>; /** Resolves selected text during preparation and honors cancellation around asynchronous input. */
29
+ resolve(context: ComputedContext<Data, Source>): Promise<number>;
30
+ };
31
+ /** Creates a string computed field containing a normalized plain-text excerpt with a bounded length. */
32
+ declare function excerpt<Data = Record<string, unknown>, Source = unknown>(options?: ExcerptOptions<Data, Source>): {
33
+ schema: StandardSchemaV1<unknown, string>; /** Resolves selected text during preparation and honors cancellation around asynchronous input. */
34
+ resolve(context: ComputedContext<Data, Source>): Promise<string>;
35
+ };
36
+ //#endregion
37
+ export { type ExcerptOptions, type ReadingTimeOptions, type TextFormat, type TextOptions, excerpt, readingTime, wordCount };
@@ -0,0 +1,138 @@
1
+ import { t as assertServerOnly } from "./server-only-CIE-FHx0.mjs";
2
+ import { n as number, r as string } from "./schema-CnCbMosm.mjs";
3
+ import { t as src_default } from "./dist-BQGVLZyl.mjs";
4
+ import getReadingTime from "reading-time";
5
+ import { Parser } from "htmlparser2";
6
+ //#region src/computed/plain-text.ts
7
+ const markdown = new src_default({ html: true });
8
+ const ignoredElements = new Set([
9
+ "head",
10
+ "script",
11
+ "style",
12
+ "template",
13
+ "noscript"
14
+ ]);
15
+ const blockElements = new Set([
16
+ "address",
17
+ "article",
18
+ "aside",
19
+ "blockquote",
20
+ "br",
21
+ "caption",
22
+ "dd",
23
+ "details",
24
+ "dialog",
25
+ "div",
26
+ "dl",
27
+ "dt",
28
+ "fieldset",
29
+ "figcaption",
30
+ "figure",
31
+ "footer",
32
+ "form",
33
+ "h1",
34
+ "h2",
35
+ "h3",
36
+ "h4",
37
+ "h5",
38
+ "h6",
39
+ "header",
40
+ "hr",
41
+ "li",
42
+ "main",
43
+ "nav",
44
+ "ol",
45
+ "p",
46
+ "pre",
47
+ "section",
48
+ "summary",
49
+ "table",
50
+ "tbody",
51
+ "td",
52
+ "tfoot",
53
+ "th",
54
+ "thead",
55
+ "tr",
56
+ "ul"
57
+ ]);
58
+ /** Extracts HTML text and image alternatives without executing markup or retaining hidden code. */
59
+ function htmlText(html) {
60
+ const parts = [];
61
+ let ignoredDepth = 0;
62
+ new Parser({
63
+ onopentag(name, attributes) {
64
+ if (ignoredDepth || ignoredElements.has(name) || Object.hasOwn(attributes, "hidden")) {
65
+ ignoredDepth++;
66
+ return;
67
+ }
68
+ if (blockElements.has(name)) parts.push(" ");
69
+ if (name === "img" && attributes.alt) parts.push(" ", attributes.alt, " ");
70
+ },
71
+ ontext(text) {
72
+ if (!ignoredDepth) parts.push(text);
73
+ },
74
+ onclosetag(name) {
75
+ if (ignoredDepth) ignoredDepth--;
76
+ else if (blockElements.has(name)) parts.push(" ");
77
+ }
78
+ }).end(html);
79
+ return parts.join("");
80
+ }
81
+ /** Normalizes captured Markdown, HTML, or literal text to whitespace-separated plain text. */
82
+ function plainText(input, format) {
83
+ return (format === "text" ? input : htmlText(format === "markdown" ? markdown.render(input) : input)).replace(/\s+/gu, " ").trim();
84
+ }
85
+ //#endregion
86
+ //#region src/computed/text.ts
87
+ assertServerOnly();
88
+ /** Binds a typed result schema and text operation to the existing computed-field resolver contract. */
89
+ function textField(schema, options, compute) {
90
+ const { from, format = "markdown" } = options;
91
+ if (![
92
+ "markdown",
93
+ "text",
94
+ "html"
95
+ ].includes(format)) throw new TypeError("Text format must be \"markdown\", \"text\", or \"html\".");
96
+ if (from !== void 0 && typeof from !== "function") throw new TypeError("Text from must be a function.");
97
+ return {
98
+ schema,
99
+ async resolve(context) {
100
+ context.signal.throwIfAborted();
101
+ const input = await (from ? from(context) : context.readBody());
102
+ context.signal.throwIfAborted();
103
+ if (input !== void 0 && typeof input !== "string") throw new TypeError("Computed text input must be a string or undefined.");
104
+ return compute(plainText(input ?? "", format));
105
+ }
106
+ };
107
+ }
108
+ /** Creates a numeric computed field counting normalized text with reading-time's word boundaries. */
109
+ function wordCount(options = {}) {
110
+ return textField(number().int().nonnegative(), options, (text) => getReadingTime(text).words);
111
+ }
112
+ /** Creates a numeric computed field estimating whole reading minutes, rounded up; empty text returns zero. */
113
+ function readingTime(options = {}) {
114
+ const { wordsPerMinute = 200 } = options;
115
+ if (!Number.isFinite(wordsPerMinute) || wordsPerMinute <= 0) throw new TypeError("wordsPerMinute must be a finite positive number.");
116
+ return textField(number().int().nonnegative(), options, (text) => Math.ceil(getReadingTime(text, { wordsPerMinute }).minutes));
117
+ }
118
+ const graphemes = new Intl.Segmenter("en", { granularity: "grapheme" });
119
+ /** Truncates at a word boundary where possible, preserving complete Unicode graphemes and the hard limit. */
120
+ function truncate(text, maxLength) {
121
+ const characters = [];
122
+ for (const { segment } of graphemes.segment(text)) {
123
+ characters.push(segment);
124
+ if (characters.length > maxLength) break;
125
+ }
126
+ if (characters.length <= maxLength) return text;
127
+ const prefix = characters.slice(0, maxLength - 1).join("").trimEnd();
128
+ const boundary = prefix.lastIndexOf(" ");
129
+ return `${characters[maxLength - 1] === " " || boundary < 0 ? prefix : prefix.slice(0, boundary)}…`;
130
+ }
131
+ /** Creates a string computed field containing a normalized plain-text excerpt with a bounded length. */
132
+ function excerpt(options = {}) {
133
+ const { maxLength = 160 } = options;
134
+ if (!Number.isSafeInteger(maxLength) || maxLength <= 0) throw new TypeError("maxLength must be a positive safe integer.");
135
+ return textField(string(), options, (text) => truncate(text, maxLength));
136
+ }
137
+ //#endregion
138
+ export { excerpt, readingTime, wordCount };
@@ -0,0 +1,99 @@
1
+ import { n as ContentRenderResult } from "./types-DcvHRmxO.mjs";
2
+ import { a as Relationship, i as QueryData, n as CollectionRegistry, o as RelationshipsOf } from "./types-BPh2cBPs.mjs";
3
+ import { _ as QueryPlan, n as RelationalQueries, t as RelationalCountOptions, u as Query, v as QueryRegistry } from "./relational-types-DLniKi5S.mjs";
4
+
5
+ //#region src/collection/registry-types.d.ts
6
+ type Scalar = string | number | bigint | boolean | Date;
7
+ type Element<Value> = NonNullable<Value> extends readonly (infer Item)[] ? NonNullable<Item> : NonNullable<Value>;
8
+ type Compatible<Left, Right> = NonNullable<Left> extends readonly unknown[] ? NonNullable<Right> extends readonly unknown[] ? false : ScalarCompatible<Left, Right> : ScalarCompatible<Left, Right>;
9
+ type ScalarCompatible<Left, Right> = [Element<Left> | Element<Right>] extends [Scalar] ? [Element<Left>] extends [never] ? true : [Element<Right>] extends [never] ? true : [Extract<Element<Left>, Element<Right>> | Extract<Element<Right>, Element<Left>>] extends [never] ? false : true : false;
10
+ type CheckRelation<Registry extends CollectionRegistry, Name extends keyof Registry, Link extends Relationship> = Link["collection"] extends keyof Registry ? Link["from"] extends keyof QueryData<Registry[Name]> ? Link["to"] extends keyof QueryData<Registry[Link["collection"]]> ? Compatible<QueryData<Registry[Name]>[Link["from"]], QueryData<Registry[Link["collection"]]>[Link["to"]]> extends true ? never : "incompatible-relationship-fields" : "unknown-target-field" : "unknown-source-field" : "unknown-target-collection";
11
+ /** Registry-level relationship checks require the complete inferred collection map. */
12
+ type InvalidRelationships<Registry extends CollectionRegistry> = { [Name in keyof Registry]: { [Link in keyof RelationshipsOf<Registry[Name]>]: RelationshipsOf<Registry[Name]>[Link] extends Relationship ? CheckRelation<Registry, Name, RelationshipsOf<Registry[Name]>[Link]> : "invalid-relationship" }[keyof RelationshipsOf<Registry[Name]>] }[keyof Registry];
13
+ //#endregion
14
+ //#region src/query/select.d.ts
15
+ /** A selection whose collection and selected result are inferred when from() is supplied. */
16
+ type SelectFrom<Registry extends CollectionRegistry, Keys extends readonly string[]> = {
17
+ /** Binds the collection and rejects selected keys that are absent from its prepared data type. */from<Name extends keyof Registry & string>(collection: Name & (Exclude<Keys[number], keyof QueryData<Registry[NoInfer<Name>]>> extends never ? unknown : never)): Query<Registry, Name, Keys extends readonly [] ? QueryData<Registry[Name]> : { [Key in Keys[number]]-?: Key extends keyof QueryData<Registry[Name]> ? QueryData<Registry[Name]>[Key] : never }, true>;
18
+ };
19
+ //#endregion
20
+ //#region src/shared/errors.d.ts
21
+ type ContentErrorCode = "entry-not-found" | "not-renderable" | "source-error" | "validation-error" | "duplicate-id" | "invalid-reference" | "invalid-query" | "artifact-error" | "render-error";
22
+ type ContentDiagnostic = {
23
+ code: ContentErrorCode;
24
+ message: string;
25
+ operation?: string;
26
+ collection?: string;
27
+ id?: string;
28
+ source?: string;
29
+ path?: readonly PropertyKey[];
30
+ issues?: readonly unknown[];
31
+ cause?: unknown;
32
+ };
33
+ /** A contextual library failure; inspect code and diagnostics instead of message text. */
34
+ declare class ContentError extends Error {
35
+ /** Recognizes contextual errors across preparation and separately bundled loader modules. */
36
+ static [Symbol.hasInstance](value: unknown): boolean;
37
+ readonly code: ContentErrorCode;
38
+ readonly operation?: string;
39
+ readonly collection?: string;
40
+ readonly id?: string;
41
+ readonly source?: string;
42
+ readonly path?: readonly PropertyKey[];
43
+ readonly issues?: readonly unknown[];
44
+ readonly diagnostics: readonly ContentDiagnostic[];
45
+ /** Creates one failure or a grouped report preserving individual causes and issues. */
46
+ constructor(options: ContentDiagnostic & {
47
+ diagnostics?: readonly ContentDiagnostic[];
48
+ });
49
+ }
50
+ //#endregion
51
+ //#region src/runtime/revision.d.ts
52
+ type QueryRecord = Record<string, unknown> & {
53
+ id: string;
54
+ };
55
+ type ItemPayload = {
56
+ body?: string;
57
+ rendered?: ContentRenderResult;
58
+ markdown?: string;
59
+ };
60
+ type PreparedCollection = {
61
+ records: readonly QueryRecord[];
62
+ relationships: Record<string, Relationship>;
63
+ payloads: ReadonlyMap<string, () => Promise<ItemPayload>>;
64
+ sources?: ReadonlyMap<string, string | undefined>;
65
+ };
66
+ type PreparedRevision = {
67
+ registry: QueryRegistry;
68
+ collections: Record<string, PreparedCollection>;
69
+ relations: Map<string, Map<string, readonly QueryRecord[]>>;
70
+ active: number;
71
+ payloadCache: Map<string, Promise<ItemPayload>>;
72
+ renderCache: Map<string, Promise<ContentRenderResult>>;
73
+ renderMarkdown?: (body: string) => Promise<ContentRenderResult>;
74
+ execute?: (plan: QueryPlan, terminal: "all" | "first" | "count") => Promise<unknown>;
75
+ };
76
+ type ContentState = {
77
+ revision?: PreparedRevision;
78
+ registry?: QueryRegistry;
79
+ error?: ContentError;
80
+ };
81
+ //#endregion
82
+ //#region src/runtime/content.d.ts
83
+ type ContentMethods<Registry extends CollectionRegistry = {}> = {
84
+ /** Starts a SQL-ordered fluent query; field names are checked against the collection in from(). */select<const Keys extends readonly string[]>(...fields: Keys): SelectFrom<Registry, Keys>; /** Collection-scoped relational queries with typed columns, relationships, and object filters. */
85
+ readonly query: RelationalQueries<Registry>; /** Counts matching entries before pagination, like the fluent count terminal. */
86
+ count<Name extends keyof Registry & string>(collection: Name, options?: RelationalCountOptions<Registry, Name>): Promise<number>; /** Reads retained raw text separately from prepared metadata; missing entries reject. */
87
+ readBody(collection: keyof Registry & string, id: string): Promise<string | undefined>; /** Loads supplied output or renders captured Markdown, returning detached HTML and headings. */
88
+ render(collection: keyof Registry & string, id: string): Promise<ContentRenderResult>;
89
+ };
90
+ type Content<Registry extends CollectionRegistry = {}> = InvalidRelationships<Registry> extends never ? ContentMethods<Registry> : {
91
+ readonly invalidRelationships: InvalidRelationships<Registry>;
92
+ };
93
+ /** Keeps dev builders live across host-delivered revisions while pinning active operations. */
94
+ declare function createLiveRuntime(initial: ContentState): {
95
+ content: ContentMethods<CollectionRegistry>;
96
+ update(next: ContentState): void;
97
+ };
98
+ //#endregion
99
+ export { ContentError as a, ContentDiagnostic as i, createLiveRuntime as n, ContentErrorCode as o, PreparedRevision as r, InvalidRelationships as s, Content as t };