content-query 0.1.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/README.md +29 -2
  2. package/dist/{build-C5ef0kkR.mjs → build-CI4s0oFP.mjs} +122 -30
  3. package/dist/build-jKnjDjQE.d.mts +48 -0
  4. package/dist/build.d.mts +2 -2
  5. package/dist/build.mjs +1 -2
  6. package/dist/cli.d.mts +1 -1
  7. package/dist/cli.mjs +3 -3
  8. package/dist/computed.d.mts +19 -13
  9. package/dist/computed.mjs +6 -5
  10. package/dist/{content-Dj2fQCJ5.mjs → content-N1gYshjg.mjs} +203 -77
  11. package/dist/{content-Crag1Uch.d.mts → content-lwPxE9Yu.d.mts} +40 -30
  12. package/dist/{descriptor-Xbo9u5eR.d.mts → descriptor-BUPT2J7X.d.mts} +1 -2
  13. package/dist/{diagnostics-Dol6ANtq.mjs → diagnostics-Cu94mZhl.mjs} +16 -15
  14. package/dist/{dist-BQGVLZyl.mjs → dist-C7_FOzY_.mjs} +21 -12
  15. package/dist/{glob-DJmebCMM.mjs → glob-Bv0dpvCQ.mjs} +3 -3
  16. package/dist/index.d.mts +35 -16
  17. package/dist/index.mjs +7 -4
  18. package/dist/internal/markdown.d.mts +3 -5
  19. package/dist/internal/markdown.mjs +1 -2
  20. package/dist/internal.d.mts +12 -12
  21. package/dist/internal.mjs +7 -7
  22. package/dist/loaders.d.mts +5 -6
  23. package/dist/loaders.mjs +6 -5
  24. package/dist/{markdown-CZBL4Ux_.mjs → markdown-CHvBBJNa.mjs} +2 -2
  25. package/dist/next.d.mts +3 -4
  26. package/dist/next.mjs +2 -2
  27. package/dist/{operators-BQpLfJlx.mjs → operators-UqWUhKQJ.mjs} +2 -2
  28. package/dist/query.d.mts +22 -23
  29. package/dist/query.mjs +1 -2
  30. package/dist/{relational-types-DLniKi5S.d.mts → relational-types-B45zM34W.d.mts} +62 -29
  31. package/dist/{chunk-CJs4Fogs.mjs → rolldown-runtime-Bg1v5YCA.mjs} +2 -2
  32. package/dist/runtime.d.mts +2 -2
  33. package/dist/runtime.mjs +3 -4
  34. package/dist/{schema-CnCbMosm.mjs → schema-C5Str-E8.mjs} +1 -1
  35. package/dist/schema.d.mts +0 -2
  36. package/dist/schema.mjs +1 -2
  37. package/dist/{types-BPh2cBPs.d.mts → types-BC8gVJ6u.d.mts} +27 -6
  38. package/dist/{types-hmDOw87q.d.mts → types-FmUJ3cH1.d.mts} +23 -6
  39. package/dist/{validation-BvvjSUFc.mjs → validation-D_XdE1pF.mjs} +2 -2
  40. package/dist/{values-B7lo_2_x.mjs → values-BbTV4QT-.mjs} +109 -108
  41. package/dist/vite.d.mts +14 -4
  42. package/dist/vite.mjs +28 -5
  43. package/package.json +7 -5
  44. package/dist/build-DSyoRxkZ.d.mts +0 -24
  45. /package/dist/{errors-C8lWyiy2.mjs → errors-C2iuBM0G.mjs} +0 -0
  46. /package/dist/{github-slugger-BCAkwEOL.mjs → github-slugger-BMgR_Q0I.mjs} +0 -0
  47. /package/dist/{server-only-CIE-FHx0.mjs → server-only-CIJUlyL-.mjs} +0 -0
  48. /package/dist/{types-DcvHRmxO.d.mts → types-Dh-Sydyw.d.mts} +0 -0
@@ -369,120 +369,121 @@ function unflatten(parsed, revivers, options) {
369
369
  if (index >= values.length) invalid();
370
370
  const value = values[index];
371
371
  if (!value || typeof value !== "object") hydrated[index] = ops.fromPrimitive(value);
372
- else if (Array.isArray(value)) if (typeof value[0] === "string") {
373
- const type = value[0];
374
- const reviver = revivers && Object.hasOwn(revivers, type) ? revivers[type] : void 0;
375
- if (reviver) {
376
- let i = value[1];
377
- if (typeof i !== "number") i = values.push(value[1]) - 1;
378
- if (Object.hasOwn(hydrated, i)) return hydrated[index] = reviver(hydrated[i]);
379
- hydrating ??= /* @__PURE__ */ new Set();
380
- if (hydrating.has(i)) throw new Error("Invalid circular reference");
381
- hydrating.add(i);
382
- hydrated[index] = reviver(hydrate(i));
383
- hydrating.delete(i);
384
- return hydrated[index];
385
- }
386
- switch (type) {
387
- case "Date":
388
- hydrated[index] = ops.fromISOString(value[1]);
389
- break;
390
- case "Set":
391
- const set = ops.createSet();
392
- hydrated[index] = set;
393
- for (let i = 1; i < value.length; i += 1) ops.addValue(set, hydrate(value[i]));
394
- break;
395
- case "Map":
396
- const map = ops.createMap();
397
- hydrated[index] = map;
398
- for (let i = 1; i < value.length; i += 2) ops.addEntry(map, hydrate(value[i]), hydrate(value[i + 1]));
399
- break;
400
- case "RegExp":
401
- hydrated[index] = ops.fromRegExpInfo(value[1], value[2]);
402
- break;
403
- case "Object": {
404
- const wrapped_index = value[1];
405
- if (!(wrapped_index === -3 || wrapped_index === -4 || wrapped_index === -5 || wrapped_index === -6)) {
406
- const wrapped = get_raw(wrapped_index);
407
- const is_bigint = Array.isArray(wrapped) && wrapped[0] === "BigInt";
408
- if ((wrapped === void 0 || typeof wrapped === "object") && !is_bigint) invalid();
409
- }
410
- hydrated[index] = ops.box(hydrate(wrapped_index));
411
- break;
372
+ else if (Array.isArray(value)) {
373
+ if (typeof value[0] === "string") {
374
+ const type = value[0];
375
+ const reviver = revivers && Object.hasOwn(revivers, type) ? revivers[type] : void 0;
376
+ if (reviver) {
377
+ let i = value[1];
378
+ if (typeof i !== "number") i = values.push(value[1]) - 1;
379
+ if (Object.hasOwn(hydrated, i)) return hydrated[index] = reviver(hydrated[i]);
380
+ hydrating ??= /* @__PURE__ */ new Set();
381
+ if (hydrating.has(i)) throw new Error("Invalid circular reference");
382
+ hydrating.add(i);
383
+ hydrated[index] = reviver(hydrate(i));
384
+ hydrating.delete(i);
385
+ return hydrated[index];
412
386
  }
413
- case "BigInt":
414
- hydrated[index] = ops.fromPrimitive(BigInt(value[1]));
415
- break;
416
- case "null":
417
- const obj = ops.createNullPrototypeObject();
418
- hydrated[index] = obj;
419
- for (let i = 1; i < value.length; i += 2) {
420
- const key = value[i];
421
- if (typeof key !== "string") throw new Error("Cannot parse an object with a non-string key");
422
- if (key === "__proto__") throw new Error("Cannot parse an object with a `__proto__` property");
423
- ops.set(obj, key, hydrate(value[i + 1]));
387
+ switch (type) {
388
+ case "Date":
389
+ hydrated[index] = ops.fromISOString(value[1]);
390
+ break;
391
+ case "Set":
392
+ const set = ops.createSet();
393
+ hydrated[index] = set;
394
+ for (let i = 1; i < value.length; i += 1) ops.addValue(set, hydrate(value[i]));
395
+ break;
396
+ case "Map":
397
+ const map = ops.createMap();
398
+ hydrated[index] = map;
399
+ for (let i = 1; i < value.length; i += 2) ops.addEntry(map, hydrate(value[i]), hydrate(value[i + 1]));
400
+ break;
401
+ case "RegExp":
402
+ hydrated[index] = ops.fromRegExpInfo(value[1], value[2]);
403
+ break;
404
+ case "Object": {
405
+ const wrapped_index = value[1];
406
+ if (!(wrapped_index === -3 || wrapped_index === -4 || wrapped_index === -5 || wrapped_index === -6)) {
407
+ const wrapped = get_raw(wrapped_index);
408
+ const is_bigint = Array.isArray(wrapped) && wrapped[0] === "BigInt";
409
+ if ((wrapped === void 0 || typeof wrapped === "object") && !is_bigint) invalid();
410
+ }
411
+ hydrated[index] = ops.box(hydrate(wrapped_index));
412
+ break;
424
413
  }
425
- break;
426
- case "Int8Array":
427
- case "Uint8Array":
428
- case "Uint8ClampedArray":
429
- case "Int16Array":
430
- case "Uint16Array":
431
- case "Float16Array":
432
- case "Int32Array":
433
- case "Uint32Array":
434
- case "Float32Array":
435
- case "Float64Array":
436
- case "BigInt64Array":
437
- case "BigUint64Array":
438
- case "DataView": {
439
- const buffer_index = value[1];
440
- const raw = get_raw(buffer_index);
441
- if (!Array.isArray(raw) || raw[0] !== "ArrayBuffer") invalid();
442
- const buffer = hydrate(buffer_index);
443
- hydrated[index] = ops.fromViewInfo(type, buffer, value[2], value[3]);
444
- break;
414
+ case "BigInt":
415
+ hydrated[index] = ops.fromPrimitive(BigInt(value[1]));
416
+ break;
417
+ case "null":
418
+ const obj = ops.createNullPrototypeObject();
419
+ hydrated[index] = obj;
420
+ for (let i = 1; i < value.length; i += 2) {
421
+ const key = value[i];
422
+ if (typeof key !== "string") throw new Error("Cannot parse an object with a non-string key");
423
+ if (key === "__proto__") throw new Error("Cannot parse an object with a `__proto__` property");
424
+ ops.set(obj, key, hydrate(value[i + 1]));
425
+ }
426
+ break;
427
+ case "Int8Array":
428
+ case "Uint8Array":
429
+ case "Uint8ClampedArray":
430
+ case "Int16Array":
431
+ case "Uint16Array":
432
+ case "Float16Array":
433
+ case "Int32Array":
434
+ case "Uint32Array":
435
+ case "Float32Array":
436
+ case "Float64Array":
437
+ case "BigInt64Array":
438
+ case "BigUint64Array":
439
+ case "DataView": {
440
+ const buffer_index = value[1];
441
+ const raw = get_raw(buffer_index);
442
+ if (!Array.isArray(raw) || raw[0] !== "ArrayBuffer") invalid();
443
+ const buffer = hydrate(buffer_index);
444
+ hydrated[index] = ops.fromViewInfo(type, buffer, value[2], value[3]);
445
+ break;
446
+ }
447
+ case "ArrayBuffer": {
448
+ const base64 = value[1];
449
+ if (typeof base64 !== "string") throw new Error("Invalid ArrayBuffer encoding");
450
+ hydrated[index] = ops.fromArrayBuffer(decode64(base64));
451
+ break;
452
+ }
453
+ case "URL":
454
+ case "URLSearchParams":
455
+ case "Temporal.Duration":
456
+ case "Temporal.Instant":
457
+ case "Temporal.PlainDate":
458
+ case "Temporal.PlainTime":
459
+ case "Temporal.PlainDateTime":
460
+ case "Temporal.PlainMonthDay":
461
+ case "Temporal.PlainYearMonth":
462
+ case "Temporal.ZonedDateTime":
463
+ hydrated[index] = ops.fromStringValue(type, value[1]);
464
+ break;
465
+ default: throw new Error(`Unknown type ${type}`);
445
466
  }
446
- case "ArrayBuffer": {
447
- const base64 = value[1];
448
- if (typeof base64 !== "string") throw new Error("Invalid ArrayBuffer encoding");
449
- hydrated[index] = ops.fromArrayBuffer(decode64(base64));
450
- break;
467
+ } else if (value[0] === -7) {
468
+ const len = value[1];
469
+ if (!is_valid_array_len(len)) invalid();
470
+ const array = ops.createSparseArray(len);
471
+ hydrated[index] = array;
472
+ for (let i = 2; i < value.length; i += 2) {
473
+ const idx = value[i];
474
+ if (!is_valid_array_index(idx) || idx >= len) invalid();
475
+ ops.set(array, idx, hydrate(value[i + 1]));
476
+ }
477
+ } else {
478
+ const array = ops.createArray(value.length);
479
+ hydrated[index] = array;
480
+ for (let i = 0; i < value.length; i += 1) {
481
+ const n = value[i];
482
+ if (n === -2) continue;
483
+ ops.set(array, i, hydrate(n));
451
484
  }
452
- case "URL":
453
- case "URLSearchParams":
454
- case "Temporal.Duration":
455
- case "Temporal.Instant":
456
- case "Temporal.PlainDate":
457
- case "Temporal.PlainTime":
458
- case "Temporal.PlainDateTime":
459
- case "Temporal.PlainMonthDay":
460
- case "Temporal.PlainYearMonth":
461
- case "Temporal.ZonedDateTime":
462
- hydrated[index] = ops.fromStringValue(type, value[1]);
463
- break;
464
- default: throw new Error(`Unknown type ${type}`);
465
- }
466
- } else if (value[0] === -7) {
467
- const len = value[1];
468
- if (!is_valid_array_len(len)) invalid();
469
- const array = ops.createSparseArray(len);
470
- hydrated[index] = array;
471
- for (let i = 2; i < value.length; i += 2) {
472
- const idx = value[i];
473
- if (!is_valid_array_index(idx) || idx >= len) invalid();
474
- ops.set(array, idx, hydrate(value[i + 1]));
475
485
  }
476
486
  } else {
477
- const array = ops.createArray(value.length);
478
- hydrated[index] = array;
479
- for (let i = 0; i < value.length; i += 1) {
480
- const n = value[i];
481
- if (n === -2) continue;
482
- ops.set(array, i, hydrate(n));
483
- }
484
- }
485
- else {
486
487
  const object = ops.createObject();
487
488
  hydrated[index] = object;
488
489
  for (const key of Object.keys(value)) {
package/dist/vite.d.mts CHANGED
@@ -1,8 +1,18 @@
1
- import { t as BuildContentOptions } from "./build-DSyoRxkZ.mjs";
1
+ import { a as ContentSourceEvent, o as ContentSourceSnapshot, t as BuildContentOptions } from "./build-jKnjDjQE.mjs";
2
2
  import { Plugin } from "vite";
3
-
4
3
  //#region src/integrations/vite/plugin.d.ts
4
+ /** Public, format-neutral hooks for integrations sharing this plugin's preparation session. */
5
+ type ContentQueryPluginApi = {
6
+ /** Prepares or awaits the shared session and returns its current source identities. */
7
+ prepare(): Promise<ContentSourceSnapshot>;
8
+ /** Observes subsequent source publications and errors without owning another watcher. */
9
+ subscribe(listener: (event: ContentSourceEvent) => void): () => void;
10
+ };
11
+ /** A normal Vite plugin with a typed source-integration API. */
12
+ interface ContentQueryPlugin extends Plugin<ContentQueryPluginApi> {
13
+ api: ContentQueryPluginApi;
14
+ }
5
15
  /** Integrates in-memory content with Vite; opt into generated storage for standalone artifacts. */
6
- declare function contentQuery(options?: Omit<BuildContentOptions, "watch">): Plugin;
16
+ export declare function contentQuery(options?: Omit<BuildContentOptions, "watch">): ContentQueryPlugin;
7
17
  //#endregion
8
- export { contentQuery };
18
+ export type { ContentQueryPlugin, ContentQueryPluginApi };
package/dist/vite.mjs CHANGED
@@ -1,5 +1,5 @@
1
- import { a as sessionInternals, i as resolveConfigPath, l as virtualDeclarations, o as withinDirectory, r as configCandidates, s as writeChanged, t as buildAtRoot, u as revisionModules } from "./build-C5ef0kkR.mjs";
2
- import { n as serializeContentError } from "./diagnostics-Dol6ANtq.mjs";
1
+ import { a as sessionInternals, i as resolveConfigPath, l as virtualDeclarations, o as withinDirectory, r as configCandidates, s as writeChanged, t as buildAtRoot, u as revisionModules } from "./build-CI4s0oFP.mjs";
2
+ import { n as serializeContentError } from "./diagnostics-Cu94mZhl.mjs";
3
3
  import { createRequire } from "node:module";
4
4
  import path from "node:path";
5
5
  import { randomUUID } from "node:crypto";
@@ -54,9 +54,9 @@ async function preparedModules(state) {
54
54
  let next;
55
55
  if (error) {
56
56
  const serialized = serializeContentError(error);
57
- next = new Map([["server.js", `import { restoreContentError } from "content-query/internal"; export const revision = undefined; export const registry = JSON.parse(${JSON.stringify(JSON.stringify(state.registry ?? {}))}); export const error = restoreContentError(${JSON.stringify(serialized)});`]]);
57
+ next = /* @__PURE__ */ new Map([["server.js", `import { restoreContentError } from "content-query/internal"; export const revision = undefined; export const registry = JSON.parse(${JSON.stringify(JSON.stringify(state.registry ?? {}))}); export const error = restoreContentError(${JSON.stringify(serialized)});`]]);
58
58
  } else {
59
- next = await revisionModules(revision, { payloadChunkBytes: 128 * 1024 });
59
+ next = await revisionModules(revision, { payloadChunkBytes: 131072 });
60
60
  next.set("server.js", next.get("server.js").replaceAll("createArtifactRuntime", "createArtifactRevision").replace("export const content =", "export const revision =") + "\nexport const registry = revision.registry; export const error = undefined;\n");
61
61
  }
62
62
  return next;
@@ -122,6 +122,7 @@ function contentQuery(options = {}) {
122
122
  let encoding;
123
123
  const bridgeKey = randomUUID();
124
124
  const refreshClients = /* @__PURE__ */ new WeakSet();
125
+ const sourceListeners = /* @__PURE__ */ new Set();
125
126
  /** Publishes type-only facade binding without importing configuration in executable code. */
126
127
  async function writeTypes(configPath) {
127
128
  const directory = path.join(config.root, ".content-query");
@@ -216,6 +217,14 @@ function contentQuery(options = {}) {
216
217
  if (config.command === "serve") changed(state).catch(deliveryFailed);
217
218
  });
218
219
  session = prepared;
220
+ prepared.subscribe((event) => {
221
+ const listeners = [...sourceListeners];
222
+ for (const listener of listeners) try {
223
+ listener(event);
224
+ } catch (cause) {
225
+ config.logger.error(`Content source subscriber failed: ${cause instanceof Error ? cause.message : String(cause)}`);
226
+ }
227
+ });
219
228
  try {
220
229
  if (config.command === "serve") {
221
230
  const global = globalThis;
@@ -235,6 +244,19 @@ function contentQuery(options = {}) {
235
244
  }
236
245
  return {
237
246
  name: "content-query",
247
+ api: {
248
+ async prepare() {
249
+ const prepared = await ensureSession();
250
+ await sessionInternals(prepared).idle();
251
+ return prepared.sources();
252
+ },
253
+ subscribe(listener) {
254
+ sourceListeners.add(listener);
255
+ return () => {
256
+ sourceListeners.delete(listener);
257
+ };
258
+ }
259
+ },
238
260
  enforce: "pre",
239
261
  configResolved(resolved) {
240
262
  config = resolved;
@@ -257,7 +279,7 @@ function contentQuery(options = {}) {
257
279
  async buildStart() {
258
280
  if (config.command === "build" && clientEnvironment(this, config)) return;
259
281
  const prepared = await ensureSession();
260
- if (config.command === "build") modules = await revisionModules(sessionInternals(prepared).state.revision, { payloadChunkBytes: 128 * 1024 });
282
+ if (config.command === "build") modules = await revisionModules(sessionInternals(prepared).state.revision, { payloadChunkBytes: 131072 });
261
283
  },
262
284
  resolveId(source, importer, resolveOptions) {
263
285
  if (clientEnvironment(this, config, resolveOptions.ssr) && forbidden(source, config, options, importer)) this.error(`[content-query] Server-only import "${source}" is reachable from a client module${importer ? `: ${importer}` : "."}`);
@@ -288,6 +310,7 @@ function contentQuery(options = {}) {
288
310
  server = void 0;
289
311
  await starting?.catch(() => void 0);
290
312
  await session?.dispose();
313
+ sourceListeners.clear();
291
314
  globalThis[bridgeSymbol]?.delete(bridgeKey);
292
315
  }
293
316
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "content-query",
3
- "version": "0.1.0",
3
+ "version": "0.3.0",
4
4
  "description": "Typed, framework-independent content collections, queries, and rendering.",
5
5
  "homepage": "https://github.com/yangshun/content-query#readme",
6
6
  "bugs": {
@@ -66,11 +66,12 @@
66
66
  "@types/picomatch": "^4.0.3",
67
67
  "astro": "7.4.0",
68
68
  "next": "16.4.2",
69
- "typescript": "^6.0.2",
70
- "vite-plus": "latest"
69
+ "tsrs": "0.18.0-ts7.1.0-dev.20260929",
70
+ "typescript": "npm:@typescript/typescript6@6.0.2",
71
+ "vite-plus": "1.3.0"
71
72
  },
72
73
  "peerDependencies": {
73
- "next": "^16.0.0",
74
+ "next": "^15.0.0 || ^16.0.0",
74
75
  "vite": "^8.0.0"
75
76
  },
76
77
  "peerDependenciesMeta": {
@@ -87,7 +88,8 @@
87
88
  "scripts": {
88
89
  "build": "vp pack",
89
90
  "dev": "vp pack --watch --no-clean",
90
- "check": "vp check",
91
+ "check": "vp check && vp run typecheck",
92
+ "typecheck": "tsrs --noEmit",
91
93
  "test": "vp test"
92
94
  }
93
95
  }
@@ -1,24 +0,0 @@
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 };