@seedprotocol/query 0.7.0 → 0.7.2-next.593.gd5bd4ea

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 (43) hide show
  1. package/README.md +14 -5
  2. package/dist/{FileCache-BZ2cHsU3.js → FileCache-CQuj0MeF.js} +21 -16
  3. package/dist/FileCache-CQuj0MeF.js.map +1 -0
  4. package/dist/api.d.ts +5 -0
  5. package/dist/api.d.ts.map +1 -1
  6. package/dist/assembleSeeds.d.ts +21 -0
  7. package/dist/assembleSeeds.d.ts.map +1 -1
  8. package/dist/cache/CacheManager.d.ts +12 -14
  9. package/dist/cache/CacheManager.d.ts.map +1 -1
  10. package/dist/cache/FileCache.d.ts +4 -2
  11. package/dist/cache/FileCache.d.ts.map +1 -1
  12. package/dist/cache/MemoryCache.d.ts +12 -6
  13. package/dist/cache/MemoryCache.d.ts.map +1 -1
  14. package/dist/cache/changes.d.ts +28 -0
  15. package/dist/cache/changes.d.ts.map +1 -0
  16. package/dist/cache/config.d.ts +9 -0
  17. package/dist/cache/config.d.ts.map +1 -1
  18. package/dist/cache/etag.d.ts +7 -4
  19. package/dist/cache/etag.d.ts.map +1 -1
  20. package/dist/cache/freeze.d.ts +7 -0
  21. package/dist/cache/freeze.d.ts.map +1 -0
  22. package/dist/cache/types.d.ts +34 -7
  23. package/dist/cache/types.d.ts.map +1 -1
  24. package/dist/hydrateArweaveRichText.d.ts +3 -0
  25. package/dist/hydrateArweaveRichText.d.ts.map +1 -1
  26. package/dist/index.d.ts +3 -3
  27. package/dist/index.d.ts.map +1 -1
  28. package/dist/index.js +2 -2
  29. package/dist/index.node.js +4 -4
  30. package/dist/index.node.js.map +1 -1
  31. package/dist/node.js +1 -1
  32. package/dist/source/remote.d.ts.map +1 -1
  33. package/dist/source/types.d.ts +19 -1
  34. package/dist/source/types.d.ts.map +1 -1
  35. package/dist/src-CBgjwvGT.js +1207 -0
  36. package/dist/src-CBgjwvGT.js.map +1 -0
  37. package/dist/types-DHRoT30t.js.map +1 -1
  38. package/dist/types.d.ts +30 -7
  39. package/dist/types.d.ts.map +1 -1
  40. package/package.json +9 -4
  41. package/dist/FileCache-BZ2cHsU3.js.map +0 -1
  42. package/dist/src-DOx4oUlk.js +0 -996
  43. package/dist/src-DOx4oUlk.js.map +0 -1
package/README.md CHANGED
@@ -43,8 +43,13 @@ const { items, limit, skip, etag } = await queryBySchema('post', {
43
43
  limit: 20,
44
44
  skip: 0,
45
45
  })
46
+
47
+ // Seeds whose UID starts with a prefix (e.g. the 8-hex-digit trunc in a URL), newest first
48
+ const { items: matches } = await queryBySchema('post', { uidPrefix: 'fd8c50ca', limit: 16 })
46
49
  ```
47
50
 
51
+ `uidPrefix` takes at least 4 hex digits, with or without `0x`, in any case (it is lowercased: EAS matches UIDs case-sensitively); anything else returns no items. It filters like a schema listing (schema name, not revoked, seeds whose versions were all revoked left out) in one EAS request, or a `LIKE` on the local source. It never reads or writes the collection cache; matched items are written through to the item cache. `normalizeUidPrefix` is exported for callers that want the same validation.
52
+
48
53
  `SeedRecord` shape:
49
54
 
50
55
  ```ts
@@ -124,17 +129,21 @@ Controlled by the same env vars as feed content cache (ops compatibility):
124
129
  | Variable | Default | Notes |
125
130
  |----------|---------|--------|
126
131
  | `CACHE_ENABLED` | on in prod; **off** when `NODE_ENV=development` | Set `true`/`false` to force |
127
- | `CACHE_TTL` | `3600` | Seconds for collection + item entries |
128
- | `CACHE_DIR` | `./cache` | Collections: `{schema}.json`; items: `items/{seedUid}-{opts}.json` |
132
+ | `CACHE_TTL` | `3600` | Seconds from an entry's last full assembly until it is rebuilt from scratch |
133
+ | `CACHE_DIR` | `./cache` | Collections: `collections/{schema}.{opts}.json`; items: `items/{seedUid}-{opts}.json` |
129
134
 
130
135
  Behavior:
131
136
 
132
- - **Collection cache** — only for **remote** `queryBySchema` with `skip === 0` (working set). Warm hits still fetch the page to detect newer `timeCreated`, then merge/dedupe.
133
- - **Item cache** — keyed by `seedUid` + options fingerprint (`expandRelations` / `hydrateStorage` / `include` / changelog filters). Default latest-only key remains `e1-h1`. Filled by remote `getSeed` and write-through from collection/month queries.
137
+ - **Change checks** — every cache hit asks EAS, in one request, for attestations created or revoked since the entry was last checked that touch what it was built from: the seed, its head Version, and the seeds it relates to (and their head Versions). New Versions, property edits on the same Version (the default `patch` publish), and revocations are all seen. Only changed seeds are assembled again; a cached seed that was revoked drops out. The TTL is a backstop for anything a check can't see (e.g. relations of related seeds).
138
+ - **Collection cache** — only for **remote** `queryBySchema` with `skip === 0`, per schema and options fingerprint. Each hit fetches the seed list (cheap; shows new and revoked seeds), checks cached seeds for changes, and assembles only new or changed ones.
139
+ - **Item cache** — keyed by `seedUid` + options fingerprint (`expandRelations` / `hydrateStorage` / `include` / changelog filters). Default latest-only key remains `e1-h1`. Filled by remote `getSeed` and write-through from collection/month queries; a `getSeed` hit is checked for changes first.
140
+ - **ETags** — from content, so they change with any edit (not only a new `versionUid`).
141
+ - **Arweave bodies** — cached in memory by transaction id (their content never changes), whether or not the query cache is enabled.
142
+ - **Read-only results** — records from a cached read are the cache's own objects, shared with every later caller, so `SeedRecord` is typed read-only (`data: SeedData`, `changelog: readonly ChangelogEntry[]`). Outside `NODE_ENV=production`, records are also deep-frozen as they enter the memory cache (stored, or loaded from disk), so a write throws a `TypeError` instead of silently changing what later callers see and leaving the ETag stale. Production skips the freeze. Copy before changing anything, nested values included (copy-on-write, as feed's `applyFeedDefaultsDeep` does). `queryBySchema`'s `items` array is the caller's own. Set `freezeRecords` on the cache config to override.
134
143
  - **`cache: false`** — skip all cache reads/writes for that call.
135
144
  - **`skip > 0`** — no collection cache; still write-through items when cache is enabled.
136
145
  - **Local source** — no query CacheManager (SQLite is authoritative).
137
- - Refresh lock — concurrent remote `queryBySchema` for the same schema share one in-flight refresh.
146
+ - Refresh lock — concurrent remote `queryBySchema` calls for the same schema, options and `limit` share one in-flight refresh.
138
147
 
139
148
  Feed still owns serialized RSS/Atom/JSON bodies, HTTP `ETag` / 304, and image-metadata probing.
140
149
 
@@ -24,24 +24,28 @@ var r = class {
24
24
  if (e.code !== "EEXIST") throw e;
25
25
  }
26
26
  }
27
- collectionPath(e) {
28
- return n(this.cacheDir, `${e}.json`);
27
+ collectionsDir() {
28
+ return n(this.cacheDir, "collections");
29
+ }
30
+ collectionPath(t, r) {
31
+ return n(this.collectionsDir(), `${e(t)}.${r}.json`);
29
32
  }
30
33
  itemPath(t, r) {
31
34
  let i = e(t);
32
35
  return n(this.cacheDir, "items", `${i}-${r}.json`);
33
36
  }
34
- async getCollection(e) {
37
+ async getCollection(e, n) {
38
+ let r = this.collectionPath(e, n);
35
39
  try {
36
- let n = await t.readFile(this.collectionPath(e), "utf-8"), r = JSON.parse(n);
37
- return Math.floor(Date.now() / 1e3) - r.lastUpdated > this.config.ttl ? (await this.clearCollection(e), null) : r;
40
+ let e = await t.readFile(r, "utf-8"), n = JSON.parse(e);
41
+ return Math.floor(Date.now() / 1e3) - n.lastUpdated > this.config.ttl ? (await t.unlink(r).catch(() => {}), null) : n;
38
42
  } catch (t) {
39
43
  return t.code === "ENOENT" || console.error(`Error reading query collection cache for ${e}:`, t), null;
40
44
  }
41
45
  }
42
- async setCollection(e, n) {
46
+ async setCollection(e, n, r) {
43
47
  try {
44
- await this.ensureCacheDir(), await t.writeFile(this.collectionPath(e), JSON.stringify(n, null, 2), "utf-8");
48
+ await t.mkdir(this.collectionsDir(), { recursive: !0 }), await t.writeFile(this.collectionPath(e, n), JSON.stringify(r, null, 2), "utf-8");
45
49
  } catch (t) {
46
50
  console.error(`Error writing query collection cache for ${e}:`, t);
47
51
  }
@@ -61,11 +65,13 @@ var r = class {
61
65
  console.error(`Error writing query item cache for ${e.record.seedUid}:`, t);
62
66
  }
63
67
  }
64
- async clearCollection(e) {
68
+ async clearCollection(r) {
69
+ let i = `${e(r)}.`;
65
70
  try {
66
- await t.unlink(this.collectionPath(e));
67
- } catch (t) {
68
- t.code !== "ENOENT" && console.error(`Error clearing query collection cache for ${e}:`, t);
71
+ let e = await t.readdir(this.collectionsDir());
72
+ for (let r of e) r.startsWith(i) && r.endsWith(".json") && await t.unlink(n(this.collectionsDir(), r));
73
+ } catch (e) {
74
+ e.code !== "ENOENT" && console.error(`Error clearing query collection cache for ${r}:`, e);
69
75
  }
70
76
  }
71
77
  async clearItem(e, n) {
@@ -79,10 +85,9 @@ var r = class {
79
85
  try {
80
86
  let e = await t.readdir(this.cacheDir);
81
87
  for (let r of e) r.endsWith(".json") && await t.unlink(n(this.cacheDir, r));
82
- let r = n(this.cacheDir, "items");
83
- try {
84
- let e = await t.readdir(r);
85
- for (let i of e) i.endsWith(".json") && await t.unlink(n(r, i));
88
+ for (let e of [n(this.cacheDir, "items"), this.collectionsDir()]) try {
89
+ let r = await t.readdir(e);
90
+ for (let i of r) i.endsWith(".json") && await t.unlink(n(e, i));
86
91
  } catch {}
87
92
  } catch (e) {
88
93
  console.error("Error clearing all query caches:", e);
@@ -92,4 +97,4 @@ var r = class {
92
97
  //#endregion
93
98
  export { r as t };
94
99
 
95
- //# sourceMappingURL=FileCache-BZ2cHsU3.js.map
100
+ //# sourceMappingURL=FileCache-CQuj0MeF.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FileCache-CQuj0MeF.js","names":["fs","sanitizeSeedUidForPath","FileCache","config","err","promises","error","join","schemaName","optionsKey","safe","seedUid","path","data","cached","prefix","files","file","dir","dirFiles"],"sources":["../src/cache/FileCache.ts"],"sourcesContent":["import { promises as fs } from 'fs'\nimport { join } from 'path'\nimport type {\n CachedCollectionData,\n CachedItemData,\n QueryCacheConfig,\n} from './types.js'\nimport { sanitizeSeedUidForPath } from './types.js'\n\n/**\n * File-based persistent cache for collections and items (Node / best-effort).\n */\nexport class FileCache {\n private cacheDir: string\n private config: QueryCacheConfig\n\n constructor(config: QueryCacheConfig) {\n this.cacheDir = config.cacheDir\n this.config = config\n this.ensureCacheDir().catch((err) => {\n console.error('Failed to create query cache directory:', err)\n })\n }\n\n private async ensureCacheDir(): Promise<void> {\n try {\n await fs.mkdir(this.cacheDir, { recursive: true })\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'EEXIST') {\n throw error\n }\n }\n }\n\n private async ensureItemsDir(): Promise<void> {\n try {\n await fs.mkdir(join(this.cacheDir, 'items'), { recursive: true })\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'EEXIST') {\n throw error\n }\n }\n }\n\n private collectionsDir(): string {\n return join(this.cacheDir, 'collections')\n }\n\n /** Under `collections/`, so feed's own `{schema}-{format}.json` cleanup never matches it. */\n private collectionPath(schemaName: string, optionsKey: string): string {\n return join(this.collectionsDir(), `${sanitizeSeedUidForPath(schemaName)}.${optionsKey}.json`)\n }\n\n private itemPath(seedUid: string, optionsKey: string): string {\n const safe = sanitizeSeedUidForPath(seedUid)\n return join(this.cacheDir, 'items', `${safe}-${optionsKey}.json`)\n }\n\n async getCollection(\n schemaName: string,\n optionsKey: string,\n ): Promise<CachedCollectionData | null> {\n const path = this.collectionPath(schemaName, optionsKey)\n try {\n const data = await fs.readFile(path, 'utf-8')\n const cached: CachedCollectionData = JSON.parse(data)\n const now = Math.floor(Date.now() / 1000)\n if (now - cached.lastUpdated > this.config.ttl) {\n await fs.unlink(path).catch(() => {})\n return null\n }\n return cached\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n return null\n }\n console.error(\n `Error reading query collection cache for ${schemaName}:`,\n error,\n )\n return null\n }\n }\n\n async setCollection(\n schemaName: string,\n optionsKey: string,\n data: CachedCollectionData,\n ): Promise<void> {\n try {\n await fs.mkdir(this.collectionsDir(), { recursive: true })\n await fs.writeFile(\n this.collectionPath(schemaName, optionsKey),\n JSON.stringify(data, null, 2),\n 'utf-8',\n )\n } catch (error) {\n console.error(\n `Error writing query collection cache for ${schemaName}:`,\n error,\n )\n }\n }\n\n async getItem(\n seedUid: string,\n optionsKey: string,\n ): Promise<CachedItemData | null> {\n try {\n const data = await fs.readFile(\n this.itemPath(seedUid, optionsKey),\n 'utf-8',\n )\n const cached: CachedItemData = JSON.parse(data)\n const now = Math.floor(Date.now() / 1000)\n if (now - cached.lastUpdated > this.config.ttl) {\n await this.clearItem(seedUid, optionsKey)\n return null\n }\n return cached\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n return null\n }\n console.error(`Error reading query item cache for ${seedUid}:`, error)\n return null\n }\n }\n\n async setItem(data: CachedItemData): Promise<void> {\n try {\n await this.ensureItemsDir()\n await fs.writeFile(\n this.itemPath(data.record.seedUid, data.optionsKey),\n JSON.stringify(data, null, 2),\n 'utf-8',\n )\n } catch (error) {\n console.error(\n `Error writing query item cache for ${data.record.seedUid}:`,\n error,\n )\n }\n }\n\n async clearCollection(schemaName: string): Promise<void> {\n const prefix = `${sanitizeSeedUidForPath(schemaName)}.`\n try {\n const files = await fs.readdir(this.collectionsDir())\n for (const file of files) {\n if (file.startsWith(prefix) && file.endsWith('.json')) {\n await fs.unlink(join(this.collectionsDir(), file))\n }\n }\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT') {\n console.error(\n `Error clearing query collection cache for ${schemaName}:`,\n error,\n )\n }\n }\n }\n\n async clearItem(seedUid: string, optionsKey: string): Promise<void> {\n try {\n await fs.unlink(this.itemPath(seedUid, optionsKey))\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT') {\n console.error(\n `Error clearing query item cache for ${seedUid}:`,\n error,\n )\n }\n }\n }\n\n async clearAll(): Promise<void> {\n try {\n const files = await fs.readdir(this.cacheDir)\n for (const file of files) {\n if (file.endsWith('.json')) {\n await fs.unlink(join(this.cacheDir, file))\n }\n }\n for (const dir of [join(this.cacheDir, 'items'), this.collectionsDir()]) {\n try {\n const dirFiles = await fs.readdir(dir)\n for (const file of dirFiles) {\n if (file.endsWith('.json')) {\n await fs.unlink(join(dir, file))\n }\n }\n } catch {\n // dir may not exist\n }\n }\n } catch (error) {\n console.error('Error clearing all query caches:', error)\n }\n }\n}\n"],"mappings":"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"}
package/dist/api.d.ts CHANGED
@@ -1,4 +1,9 @@
1
1
  import type { AssembleOptions, GetSeedOptions, GetSeedResult, QueryBySchemaOptions, QueryBySchemaResult, SeedRecord } from './types.js';
2
+ /**
3
+ * `0x` + lowercase hex for a seed UID prefix given with or without `0x`, in any case (EAS indexes
4
+ * UIDs lowercase and matches prefixes case-sensitively). Null when it isn't 4–64 hex digits.
5
+ */
6
+ export declare function normalizeUidPrefix(prefix: string): string | null;
2
7
  export declare function queryBySchema(schemaName: string, options?: QueryBySchemaOptions): Promise<QueryBySchemaResult>;
3
8
  export declare function getSeed(seedUid: string, options?: GetSeedOptions): Promise<GetSeedResult | null>;
4
9
  /**
package/dist/api.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EACV,eAAe,EACf,cAAc,EACd,aAAa,EACb,oBAAoB,EACpB,mBAAmB,EACnB,UAAU,EACX,MAAM,YAAY,CAAA;AAyDnB,wBAAsB,aAAa,CACjC,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,mBAAmB,CAAC,CAyE9B;AAED,wBAAsB,OAAO,CAC3B,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAyF/B;AAED;;;GAGG;AACH,wBAAsB,qBAAqB,CACzC,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE,eAAe,GACxB,OAAO,CAAC,UAAU,EAAE,CAAC,CAuBvB"}
1
+ {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAuBA,OAAO,KAAK,EACV,eAAe,EACf,cAAc,EACd,aAAa,EACb,oBAAoB,EACpB,mBAAmB,EACnB,UAAU,EACX,MAAM,YAAY,CAAA;AAwKnB;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAKhE;AAED,wBAAsB,aAAa,CACjC,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,mBAAmB,CAAC,CA8C9B;AAmCD,wBAAsB,OAAO,CAC3B,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CA6G/B;AAED;;;GAGG;AACH,wBAAsB,qBAAqB,CACzC,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE,eAAe,GACxB,OAAO,CAAC,UAAU,EAAE,CAAC,CAuBvB"}
@@ -1,5 +1,26 @@
1
1
  import type { QueryDataSource } from './source/types.js';
2
2
  import type { AssembleOptions, AttestationLike, SeedRecord } from './types.js';
3
+ /**
4
+ * What an assembled record was built from, so a cache can tell when it changed: an attestation
5
+ * created or revoked later that references one of `refUIDs` (a new or revoked Version of the seed
6
+ * or of a seed it relates to, a property of one of their head Versions) or is one of `ids` (the
7
+ * seed or a related seed, revoked).
8
+ */
9
+ export type SeedDependencies = {
10
+ refUIDs: string[];
11
+ ids: string[];
12
+ };
13
+ /**
14
+ * Like assembleSeeds, plus each record's dependencies by seedUid (see SeedDependencies).
15
+ */
16
+ export declare function assembleSeedsWithDependencies(schemaName: string, seeds: AttestationLike[], options?: AssembleOptions, dataSource?: QueryDataSource,
17
+ /** Versions of `seeds` already fetched with `includeRevoked: true` (see getSeed). */
18
+ prefetched?: {
19
+ versions?: AttestationLike[];
20
+ }): Promise<{
21
+ records: SeedRecord[];
22
+ dependencies: Map<string, SeedDependencies>;
23
+ }>;
3
24
  /**
4
25
  * Assemble canonical SeedRecords from Seed attestations (latest Version + canonical properties).
5
26
  * Uses per-call state (safe for concurrent requests).
@@ -1 +1 @@
1
- {"version":3,"file":"assembleSeeds.d.ts","sourceRoot":"","sources":["../src/assembleSeeds.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAA;AACxD,OAAO,KAAK,EAAE,eAAe,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAyc9E;;;GAGG;AACH,wBAAsB,aAAa,CACjC,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,eAAe,EAAE,EACxB,OAAO,CAAC,EAAE,eAAe,EACzB,UAAU,GAAE,eAA4C,GACvD,OAAO,CAAC,UAAU,EAAE,CAAC,CA+BvB"}
1
+ {"version":3,"file":"assembleSeeds.d.ts","sourceRoot":"","sources":["../src/assembleSeeds.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAA;AACxD,OAAO,KAAK,EAAE,eAAe,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAqe9E;;;;;GAKG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC7B,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB,GAAG,EAAE,MAAM,EAAE,CAAA;CACd,CAAA;AAUD;;GAEG;AACH,wBAAsB,6BAA6B,CACjD,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,eAAe,EAAE,EACxB,OAAO,CAAC,EAAE,eAAe,EACzB,UAAU,GAAE,eAA4C;AACxD,qFAAqF;AACrF,UAAU,CAAC,EAAE;IAAE,QAAQ,CAAC,EAAE,eAAe,EAAE,CAAA;CAAE,GAC5C,OAAO,CAAC;IAAE,OAAO,EAAE,UAAU,EAAE,CAAC;IAAC,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAA;CAAE,CAAC,CA0CjF;AAED;;;GAGG;AACH,wBAAsB,aAAa,CACjC,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,eAAe,EAAE,EACxB,OAAO,CAAC,EAAE,eAAe,EACzB,UAAU,GAAE,eAA4C,GACvD,OAAO,CAAC,UAAU,EAAE,CAAC,CAEvB"}
@@ -1,4 +1,3 @@
1
- import type { GetSeedResult, SeedRecord } from '../types.js';
2
1
  import { MemoryCache } from './MemoryCache.js';
3
2
  import type { CachedCollectionData, CachedItemData, PersistentCache, QueryCacheConfig, QueryCacheStats } from './types.js';
4
3
  type PersistentCacheFactory = (config: QueryCacheConfig) => PersistentCache | null;
@@ -9,6 +8,7 @@ type PersistentCacheFactory = (config: QueryCacheConfig) => PersistentCache | nu
9
8
  export declare function configurePersistentCacheFactory(factory: PersistentCacheFactory): void;
10
9
  /**
11
10
  * Unified query cache: memory, with optional persistent (disk) layer.
11
+ * Collections are kept per schema and assemble-options key.
12
12
  */
13
13
  export declare class CacheManager {
14
14
  private memoryCache;
@@ -18,22 +18,20 @@ export declare class CacheManager {
18
18
  constructor(config: QueryCacheConfig, persistent?: PersistentCache | null);
19
19
  get enabled(): boolean;
20
20
  getConfig(): QueryCacheConfig;
21
- getCollection(schemaName: string): Promise<CachedCollectionData | null>;
22
- setCollection(schemaName: string, items: SeedRecord[]): Promise<CachedCollectionData | null>;
21
+ getCollection(schemaName: string, optionsKey: string): Promise<CachedCollectionData | null>;
22
+ /** Stores a collection; its ETag is derived from the records' content. */
23
+ setCollection(schemaName: string, optionsKey: string, data: Omit<CachedCollectionData, 'etag'>): Promise<CachedCollectionData | null>;
23
24
  getItem(seedUid: string, optionsKey: string): Promise<CachedItemData | null>;
24
- setItem(record: GetSeedResult, optionsKey: string): Promise<CachedItemData | null>;
25
- writeThroughItems(items: SeedRecord[], optionsKey: string): Promise<void>;
25
+ /** Stores an item; its ETag is derived from the record's content. */
26
+ setItem(data: Omit<CachedItemData, 'etag'>): Promise<CachedItemData | null>;
27
+ writeThroughItems(items: Array<Omit<CachedItemData, 'etag'>>): Promise<void>;
28
+ clearItem(seedUid: string, optionsKey: string): Promise<void>;
29
+ /** Every options variant of the schema's collection. */
26
30
  clearCollection(schemaName: string): Promise<void>;
27
31
  clearAll(): Promise<void>;
28
- withRefreshLock<T>(schemaName: string, fn: () => Promise<T>): Promise<T>;
29
- /**
30
- * Merge records by seedUid; new wins. Sort by timeCreated descending.
31
- */
32
- mergeRecords(cachedItems: SeedRecord[], newItems: SeedRecord[]): SeedRecord[];
33
- /**
34
- * Keep only records newer than lastProcessedTimestamp.
35
- */
36
- filterNewRecords(items: SeedRecord[], lastProcessedTimestamp: number): SeedRecord[];
32
+ withRefreshLock<T>(key: string, fn: () => Promise<T>): Promise<T>;
33
+ /** Counts a cache hit that was checked against changes and refreshed in part. */
34
+ recordRefresh(): void;
37
35
  updateConfig(config: Partial<QueryCacheConfig>): void;
38
36
  getStats(): QueryCacheStats & {
39
37
  memoryStats: ReturnType<MemoryCache['getStats']>;
@@ -1 +1 @@
1
- {"version":3,"file":"CacheManager.d.ts","sourceRoot":"","sources":["../../src/cache/CacheManager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAC5D,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAC9C,OAAO,KAAK,EACV,oBAAoB,EACpB,cAAc,EACd,eAAe,EACf,gBAAgB,EAChB,eAAe,EAChB,MAAM,YAAY,CAAA;AAEnB,KAAK,sBAAsB,GAAG,CAAC,MAAM,EAAE,gBAAgB,KAAK,eAAe,GAAG,IAAI,CAAA;AAIlF;;;GAGG;AACH,wBAAgB,+BAA+B,CAC7C,OAAO,EAAE,sBAAsB,GAC9B,IAAI,CAEN;AAED;;GAEG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,WAAW,CAAa;IAChC,OAAO,CAAC,UAAU,CAAwB;IAC1C,OAAO,CAAC,MAAM,CAAkB;IAChC,OAAO,CAAC,KAAK,CAKZ;gBAEW,MAAM,EAAE,gBAAgB,EAAE,UAAU,CAAC,EAAE,eAAe,GAAG,IAAI;IAUzE,IAAI,OAAO,IAAI,OAAO,CAErB;IAED,SAAS,IAAI,gBAAgB;IAIvB,aAAa,CACjB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC;IA6BjC,aAAa,CACjB,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,UAAU,EAAE,GAClB,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC;IAiBjC,OAAO,CACX,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IA0B3B,OAAO,CACX,MAAM,EAAE,aAAa,EACrB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IAiB3B,iBAAiB,CACrB,KAAK,EAAE,UAAU,EAAE,EACnB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,IAAI,CAAC;IAOV,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKlD,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAKzB,eAAe,CAAC,CAAC,EACrB,UAAU,EAAE,MAAM,EAClB,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GACnB,OAAO,CAAC,CAAC,CAAC;IAIb;;OAEG;IACH,YAAY,CACV,WAAW,EAAE,UAAU,EAAE,EACzB,QAAQ,EAAE,UAAU,EAAE,GACrB,UAAU,EAAE;IAmBf;;OAEG;IACH,gBAAgB,CACd,KAAK,EAAE,UAAU,EAAE,EACnB,sBAAsB,EAAE,MAAM,GAC7B,UAAU,EAAE;IAMf,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,gBAAgB,CAAC,GAAG,IAAI;IAKrD,QAAQ,IAAI,eAAe,GAAG;QAC5B,WAAW,EAAE,UAAU,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC,CAAA;KACjD;IAOD,UAAU,IAAI,IAAI;CAQnB"}
1
+ {"version":3,"file":"CacheManager.d.ts","sourceRoot":"","sources":["../../src/cache/CacheManager.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAC9C,OAAO,KAAK,EACV,oBAAoB,EACpB,cAAc,EACd,eAAe,EACf,gBAAgB,EAChB,eAAe,EAChB,MAAM,YAAY,CAAA;AAGnB,KAAK,sBAAsB,GAAG,CAAC,MAAM,EAAE,gBAAgB,KAAK,eAAe,GAAG,IAAI,CAAA;AAIlF;;;GAGG;AACH,wBAAgB,+BAA+B,CAC7C,OAAO,EAAE,sBAAsB,GAC9B,IAAI,CAEN;AA6BD;;;GAGG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,WAAW,CAAa;IAChC,OAAO,CAAC,UAAU,CAAwB;IAC1C,OAAO,CAAC,MAAM,CAAkB;IAChC,OAAO,CAAC,KAAK,CAKZ;gBAEW,MAAM,EAAE,gBAAgB,EAAE,UAAU,CAAC,EAAE,eAAe,GAAG,IAAI;IAUzE,IAAI,OAAO,IAAI,OAAO,CAErB;IAED,SAAS,IAAI,gBAAgB;IAIvB,aAAa,CACjB,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC;IA6BvC,0EAA0E;IACpE,aAAa,CACjB,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,IAAI,CAAC,oBAAoB,EAAE,MAAM,CAAC,GACvC,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC;IAwBjC,OAAO,CACX,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IA0BjC,qEAAqE;IAC/D,OAAO,CACX,IAAI,EAAE,IAAI,CAAC,cAAc,EAAE,MAAM,CAAC,GACjC,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IA2B3B,iBAAiB,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAO5E,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKnE,wDAAwD;IAClD,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKlD,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAKzB,eAAe,CAAC,CAAC,EACrB,GAAG,EAAE,MAAM,EACX,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GACnB,OAAO,CAAC,CAAC,CAAC;IAIb,iFAAiF;IACjF,aAAa,IAAI,IAAI;IAIrB,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,gBAAgB,CAAC,GAAG,IAAI;IAKrD,QAAQ,IAAI,eAAe,GAAG;QAC5B,WAAW,EAAE,UAAU,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC,CAAA;KACjD;IAOD,UAAU,IAAI,IAAI;CAQnB"}
@@ -8,10 +8,12 @@ export declare class FileCache {
8
8
  constructor(config: QueryCacheConfig);
9
9
  private ensureCacheDir;
10
10
  private ensureItemsDir;
11
+ private collectionsDir;
12
+ /** Under `collections/`, so feed's own `{schema}-{format}.json` cleanup never matches it. */
11
13
  private collectionPath;
12
14
  private itemPath;
13
- getCollection(schemaName: string): Promise<CachedCollectionData | null>;
14
- setCollection(schemaName: string, data: CachedCollectionData): Promise<void>;
15
+ getCollection(schemaName: string, optionsKey: string): Promise<CachedCollectionData | null>;
16
+ setCollection(schemaName: string, optionsKey: string, data: CachedCollectionData): Promise<void>;
15
17
  getItem(seedUid: string, optionsKey: string): Promise<CachedItemData | null>;
16
18
  setItem(data: CachedItemData): Promise<void>;
17
19
  clearCollection(schemaName: string): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"FileCache.d.ts","sourceRoot":"","sources":["../../src/cache/FileCache.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,oBAAoB,EACpB,cAAc,EACd,gBAAgB,EACjB,MAAM,YAAY,CAAA;AAGnB;;GAEG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,QAAQ,CAAQ;IACxB,OAAO,CAAC,MAAM,CAAkB;gBAEpB,MAAM,EAAE,gBAAgB;YAQtB,cAAc;YAUd,cAAc;IAU5B,OAAO,CAAC,cAAc;IAItB,OAAO,CAAC,QAAQ;IAKV,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC;IAsBvE,aAAa,CACjB,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,oBAAoB,GACzB,OAAO,CAAC,IAAI,CAAC;IAgBV,OAAO,CACX,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IAsB3B,OAAO,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAgB5C,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAalD,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAa7D,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;CAuBhC"}
1
+ {"version":3,"file":"FileCache.d.ts","sourceRoot":"","sources":["../../src/cache/FileCache.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,oBAAoB,EACpB,cAAc,EACd,gBAAgB,EACjB,MAAM,YAAY,CAAA;AAGnB;;GAEG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,QAAQ,CAAQ;IACxB,OAAO,CAAC,MAAM,CAAkB;gBAEpB,MAAM,EAAE,gBAAgB;YAQtB,cAAc;YAUd,cAAc;IAU5B,OAAO,CAAC,cAAc;IAItB,6FAA6F;IAC7F,OAAO,CAAC,cAAc;IAItB,OAAO,CAAC,QAAQ;IAKV,aAAa,CACjB,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC;IAuBjC,aAAa,CACjB,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,oBAAoB,GACzB,OAAO,CAAC,IAAI,CAAC;IAgBV,OAAO,CACX,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IAsB3B,OAAO,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAgB5C,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAmBlD,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAa7D,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;CAwBhC"}
@@ -1,7 +1,9 @@
1
- import type { GetSeedResult, SeedRecord } from '../types.js';
2
1
  import type { CachedCollectionData, CachedItemData, QueryCacheConfig } from './types.js';
3
2
  /**
4
3
  * In-memory collection + item cache with TTL and refresh locks.
4
+ * Entries expire `ttl` seconds after their `lastUpdated` (their last full assembly).
5
+ * Stored records are returned to callers by reference; with `freezeRecords` they are deep-frozen
6
+ * on the way in so a caller can't mutate them silently.
5
7
  */
6
8
  export declare class MemoryCache {
7
9
  private collectionCache;
@@ -9,18 +11,22 @@ export declare class MemoryCache {
9
11
  private config;
10
12
  private refreshLocks;
11
13
  constructor(config: QueryCacheConfig);
14
+ private collectionKey;
12
15
  private itemKey;
13
- getCollection(schemaName: string): CachedCollectionData | null;
14
- setCollection(schemaName: string, items: SeedRecord[]): CachedCollectionData;
16
+ private get freezeRecords();
17
+ private expired;
18
+ getCollection(schemaName: string, optionsKey: string): CachedCollectionData | null;
19
+ setCollection(schemaName: string, optionsKey: string, data: CachedCollectionData): void;
15
20
  getItem(seedUid: string, optionsKey: string): CachedItemData | null;
16
- setItem(record: GetSeedResult, optionsKey: string): CachedItemData;
21
+ setItem(data: CachedItemData): void;
22
+ /** Every options variant of the schema's collection. */
17
23
  clearCollection(schemaName: string): void;
18
24
  clearItem(seedUid: string, optionsKey?: string): void;
19
25
  clearAll(): void;
20
26
  /**
21
- * Single-flight: concurrent callers for the same schema share one in-flight promise.
27
+ * Single-flight: concurrent callers with the same key share one in-flight promise.
22
28
  */
23
- withRefreshLock<T>(schemaName: string, fn: () => Promise<T>): Promise<T>;
29
+ withRefreshLock<T>(key: string, fn: () => Promise<T>): Promise<T>;
24
30
  updateConfig(config: Partial<QueryCacheConfig>): void;
25
31
  getStats(): {
26
32
  collectionCount: number;
@@ -1 +1 @@
1
- {"version":3,"file":"MemoryCache.d.ts","sourceRoot":"","sources":["../../src/cache/MemoryCache.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAE5D,OAAO,KAAK,EACV,oBAAoB,EACpB,cAAc,EACd,gBAAgB,EACjB,MAAM,YAAY,CAAA;AAEnB;;GAEG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,eAAe,CAA+C;IACtE,OAAO,CAAC,SAAS,CAAyC;IAC1D,OAAO,CAAC,MAAM,CAAkB;IAChC,OAAO,CAAC,YAAY,CAA2C;gBAEnD,MAAM,EAAE,gBAAgB;IAIpC,OAAO,CAAC,OAAO;IAIf,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,oBAAoB,GAAG,IAAI;IAY9D,aAAa,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,GAAG,oBAAoB;IAgC5E,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI;IAYnE,OAAO,CACL,MAAM,EAAE,aAAa,EACrB,UAAU,EAAE,MAAM,GACjB,cAAc;IAyBjB,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAIzC,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI;IAYrD,QAAQ,IAAI,IAAI;IAKhB;;OAEG;IACG,eAAe,CAAC,CAAC,EACrB,UAAU,EAAE,MAAM,EAClB,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GACnB,OAAO,CAAC,CAAC,CAAC;IAkBb,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,gBAAgB,CAAC,GAAG,IAAI;IAIrD,QAAQ,IAAI;QACV,eAAe,EAAE,MAAM,CAAA;QACvB,SAAS,EAAE,MAAM,CAAA;QACjB,WAAW,EAAE,MAAM,CAAA;KACpB;CAOF"}
1
+ {"version":3,"file":"MemoryCache.d.ts","sourceRoot":"","sources":["../../src/cache/MemoryCache.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,oBAAoB,EACpB,cAAc,EACd,gBAAgB,EACjB,MAAM,YAAY,CAAA;AAInB;;;;;GAKG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,eAAe,CAA+C;IACtE,OAAO,CAAC,SAAS,CAAyC;IAC1D,OAAO,CAAC,MAAM,CAAkB;IAChC,OAAO,CAAC,YAAY,CAA2C;gBAEnD,MAAM,EAAE,gBAAgB;IAIpC,OAAO,CAAC,aAAa;IAIrB,OAAO,CAAC,OAAO;IAIf,OAAO,KAAK,aAAa,GAExB;IAED,OAAO,CAAC,OAAO;IAIf,aAAa,CAAC,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,oBAAoB,GAAG,IAAI;IAWlF,aAAa,CAAC,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,oBAAoB,GAAG,IAAI;IAKvF,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI;IAWnE,OAAO,CAAC,IAAI,EAAE,cAAc,GAAG,IAAI;IAKnC,wDAAwD;IACxD,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAMzC,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI;IAYrD,QAAQ,IAAI,IAAI;IAKhB;;OAEG;IACG,eAAe,CAAC,CAAC,EACrB,GAAG,EAAE,MAAM,EACX,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GACnB,OAAO,CAAC,CAAC,CAAC;IAkBb,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,gBAAgB,CAAC,GAAG,IAAI;IAIrD,QAAQ,IAAI;QACV,eAAe,EAAE,MAAM,CAAA;QACvB,SAAS,EAAE,MAAM,CAAA;QACjB,WAAW,EAAE,MAAM,CAAA;KACpB;CAOF"}
@@ -0,0 +1,28 @@
1
+ import type { SeedDependencies } from '../assembleSeeds.js';
2
+ import type { QueryDataSource } from '../source/types.js';
3
+ import type { ChangeCheck } from './types.js';
4
+ /**
5
+ * Each change check looks back this far before the previous check started, so an attestation
6
+ * the indexer lists late, or a clock between here and the chain that is off, is still seen.
7
+ * Changes inside the overlap that were already applied are skipped by their key.
8
+ */
9
+ export declare const CHANGE_CHECK_OVERLAP_SECONDS = 600;
10
+ export declare function nowSeconds(): number;
11
+ /** `checkedAt` for a check that started at `startedAt`. */
12
+ export declare function checkedAtFor(startedAt: number): number;
13
+ /**
14
+ * True when a check found nothing but its window has grown past twice the overlap, so it is worth
15
+ * storing the new `checkedAt` to keep later requests small. (Storing it is otherwise not needed:
16
+ * an unchanged entry's next check sees only changes it has already seen.)
17
+ */
18
+ export declare function checkWindowAged(check: ChangeCheck, startedAt: number): boolean;
19
+ /**
20
+ * Which of the cached seeds changed since `check.checkedAt`: a new or revoked Version of a seed
21
+ * it depends on, a new or revoked property on one of their head Versions, or one of those seeds
22
+ * revoked. Returns null when the data source can't list changes (treat everything as changed).
23
+ */
24
+ export declare function findChangedSeeds(dataSource: QueryDataSource, dependenciesBySeedUid: Map<string, SeedDependencies>, check: ChangeCheck): Promise<{
25
+ changed: Set<string>;
26
+ seenChangeKeys: string[];
27
+ } | null>;
28
+ //# sourceMappingURL=changes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"changes.d.ts","sourceRoot":"","sources":["../../src/cache/changes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAA;AAC3D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AAEzD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAE7C;;;;GAIG;AACH,eAAO,MAAM,4BAA4B,MAAM,CAAA;AAE/C,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AAED,2DAA2D;AAC3D,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAE9E;AAID;;;;GAIG;AACH,wBAAsB,gBAAgB,CACpC,UAAU,EAAE,eAAe,EAC3B,qBAAqB,EAAE,GAAG,CAAC,MAAM,EAAE,gBAAgB,CAAC,EACpD,KAAK,EAAE,WAAW,GACjB,OAAO,CAAC;IAAE,OAAO,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAAC,cAAc,EAAE,MAAM,EAAE,CAAA;CAAE,GAAG,IAAI,CAAC,CAgCpE"}
@@ -10,6 +10,15 @@ import type { QueryCacheConfig } from './types.js';
10
10
  *
11
11
  * In development (NODE_ENV=development), cache is disabled unless
12
12
  * CACHE_ENABLED is explicitly true.
13
+ *
14
+ * Records are deep-frozen as they enter the memory cache unless NODE_ENV=production
15
+ * (see {@link defaultFreezeRecords}).
16
+ */
17
+ /**
18
+ * Cached records are handed to callers by reference, so a caller that mutates one corrupts the
19
+ * cache. Outside production they are frozen when cached so such a write throws (in strict mode)
20
+ * instead; production skips the walk.
13
21
  */
22
+ export declare function defaultFreezeRecords(): boolean;
14
23
  export declare function loadQueryCacheConfig(): QueryCacheConfig;
15
24
  //# sourceMappingURL=config.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/cache/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAQlD;;;;;;;;;;;GAWG;AACH,wBAAgB,oBAAoB,IAAI,gBAAgB,CAqCvD"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/cache/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAQlD;;;;;;;;;;;;;;GAcG;AACH;;;;GAIG;AACH,wBAAgB,oBAAoB,IAAI,OAAO,CAE9C;AAED,wBAAgB,oBAAoB,IAAI,gBAAgB,CAsCvD"}
@@ -1,13 +1,16 @@
1
+ import type { GetSeedResult } from '../types.js';
1
2
  /**
2
3
  * Generate an ETag from a string value (SHA-256, first 16 hex chars, quoted).
3
4
  */
4
5
  export declare function generateETag(value: string): string;
5
6
  /**
6
- * Generate an ETag for a collection working set.
7
+ * Generate an ETag for a collection working set from its records' ETags (in order), so it
8
+ * changes whenever a record's content does.
7
9
  */
8
- export declare function generateCollectionETag(schemaName: string, lastProcessedTimestamp: number, itemCount: number): string;
10
+ export declare function generateCollectionETag(schemaName: string, optionsKey: string, itemETags: string[]): string;
9
11
  /**
10
- * Generate an ETag for a single SeedRecord.
12
+ * Generate an ETag for a single record from its content (a patch publish changes properties
13
+ * without a new versionUid, so ids alone don't identify the content).
11
14
  */
12
- export declare function generateItemETag(seedUid: string, versionUid: string, timeCreated: number, optionsKey: string): string;
15
+ export declare function generateItemETag(record: GetSeedResult, optionsKey: string): string;
13
16
  //# sourceMappingURL=etag.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"etag.d.ts","sourceRoot":"","sources":["../../src/cache/etag.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAGlD;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CACpC,UAAU,EAAE,MAAM,EAClB,sBAAsB,EAAE,MAAM,EAC9B,SAAS,EAAE,MAAM,GAChB,MAAM,CAIR;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,MAAM,GACjB,MAAM,CAIR"}
1
+ {"version":3,"file":"etag.d.ts","sourceRoot":"","sources":["../../src/cache/etag.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAEhD;;GAEG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAGlD;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CACpC,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EAAE,GAClB,MAAM,CAER;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAElF"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Freezes `value` and everything reachable from it, children before parents, so a frozen object's
3
+ * subtree is already frozen and is skipped (records share related-seed clones, and write-through
4
+ * freezes the same nested objects more than once). Typed arrays can't be frozen and are left as is.
5
+ */
6
+ export declare function deepFreeze<T>(value: T): T;
7
+ //# sourceMappingURL=freeze.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"freeze.d.ts","sourceRoot":"","sources":["../../src/cache/freeze.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,CAKzC"}
@@ -1,19 +1,39 @@
1
1
  import type { ChangelogInclude, GetSeedOptions, GetSeedResult, SeedRecord } from '../types.js';
2
+ import type { SeedDependencies } from '../assembleSeeds.js';
2
3
  /**
3
- * Cached collection working set for a schema (skip=0 page).
4
+ * How a cached entry is kept current: changes (see QueryDataSource.listChangesSince) after
5
+ * `checkedAt` have not been looked at yet. Each check's window overlaps the previous one, so a
6
+ * change already applied can be seen again; `seenChangeKeys` lists those to skip.
4
7
  */
5
- export type CachedCollectionData = {
8
+ export type ChangeCheck = {
9
+ /** Unix seconds. */
10
+ checkedAt: number;
11
+ seenChangeKeys: string[];
12
+ };
13
+ /** Per-record bookkeeping in a cached collection. */
14
+ export type CachedRecordMeta = {
15
+ dependencies: SeedDependencies;
16
+ /** Unix seconds when the record was assembled. */
17
+ builtAt: number;
18
+ };
19
+ /**
20
+ * Cached collection working set for a schema and assemble options (skip=0 page).
21
+ */
22
+ export type CachedCollectionData = ChangeCheck & {
6
23
  items: SeedRecord[];
7
- lastProcessedTimestamp: number;
8
- lastProcessedItemId: string;
24
+ /** By seedUid. */
25
+ meta: Record<string, CachedRecordMeta>;
26
+ /** Unix seconds of the last full assembly; the TTL counts from here. */
9
27
  lastUpdated: number;
10
28
  etag: string;
11
29
  };
12
30
  /**
13
31
  * Cached single-seed assembly result (may include changelog).
14
32
  */
15
- export type CachedItemData = {
33
+ export type CachedItemData = ChangeCheck & {
16
34
  record: GetSeedResult;
35
+ dependencies: SeedDependencies;
36
+ /** Unix seconds when the record was assembled; the TTL counts from here. */
17
37
  lastUpdated: number;
18
38
  etag: string;
19
39
  /** Fingerprint of assemble options used when caching. */
@@ -25,6 +45,11 @@ export type QueryCacheConfig = {
25
45
  enabled: boolean;
26
46
  backgroundRefresh: boolean;
27
47
  refreshInterval: number;
48
+ /**
49
+ * Deep-freeze records as they enter the memory cache (set, or loaded from the persistent layer).
50
+ * Default: on unless NODE_ENV=production.
51
+ */
52
+ freezeRecords?: boolean;
28
53
  };
29
54
  export type QueryCacheStats = {
30
55
  hits: number;
@@ -34,10 +59,12 @@ export type QueryCacheStats = {
34
59
  };
35
60
  /** Optional disk (or other) layer under CacheManager. Browser graphs omit this. */
36
61
  export type PersistentCache = {
37
- getCollection(schemaName: string): Promise<CachedCollectionData | null>;
38
- setCollection(schemaName: string, data: CachedCollectionData): Promise<void>;
62
+ getCollection(schemaName: string, optionsKey: string): Promise<CachedCollectionData | null>;
63
+ setCollection(schemaName: string, optionsKey: string, data: CachedCollectionData): Promise<void>;
39
64
  getItem(seedUid: string, optionsKey: string): Promise<CachedItemData | null>;
40
65
  setItem(data: CachedItemData): Promise<void>;
66
+ clearItem(seedUid: string, optionsKey: string): Promise<void>;
67
+ /** Every options variant of the schema's collection. */
41
68
  clearCollection(schemaName: string): Promise<void>;
42
69
  clearAll(): Promise<void>;
43
70
  };
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/cache/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,gBAAgB,EAChB,cAAc,EACd,aAAa,EACb,UAAU,EACX,MAAM,aAAa,CAAA;AAEpB;;GAEG;AACH,MAAM,MAAM,oBAAoB,GAAG;IACjC,KAAK,EAAE,UAAU,EAAE,CAAA;IACnB,sBAAsB,EAAE,MAAM,CAAA;IAC9B,mBAAmB,EAAE,MAAM,CAAA;IAC3B,WAAW,EAAE,MAAM,CAAA;IACnB,IAAI,EAAE,MAAM,CAAA;CACb,CAAA;AAED;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG;IAC3B,MAAM,EAAE,aAAa,CAAA;IACrB,WAAW,EAAE,MAAM,CAAA;IACnB,IAAI,EAAE,MAAM,CAAA;IACZ,yDAAyD;IACzD,UAAU,EAAE,MAAM,CAAA;CACnB,CAAA;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC7B,GAAG,EAAE,MAAM,CAAA;IACX,QAAQ,EAAE,MAAM,CAAA;IAChB,OAAO,EAAE,OAAO,CAAA;IAChB,iBAAiB,EAAE,OAAO,CAAA;IAC1B,eAAe,EAAE,MAAM,CAAA;CACxB,CAAA;AAED,MAAM,MAAM,eAAe,GAAG;IAC5B,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,EAAE,MAAM,CAAA;CACf,CAAA;AAED,mFAAmF;AACnF,MAAM,MAAM,eAAe,GAAG;IAC5B,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC,CAAA;IACvE,aAAa,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC5E,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAAA;IAC5E,OAAO,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC5C,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAClD,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;CAC1B,CAAA;AAQD;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,CAAC,EAAE;IAChD,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB,OAAO,CAAC,EAAE,gBAAgB,CAAA;IAC1B,SAAS,CAAC,EAAE,cAAc,CAAC,WAAW,CAAC,CAAA;CACxC,GAAG,MAAM,CAkBT;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAE9D"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/cache/types.ts"],"names":[],"mappings":"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"}
@@ -10,9 +10,12 @@ export type HydrateStorageOptions = {
10
10
  * True for a single-path gateway URL whose path looks like an Arweave transaction id.
11
11
  */
12
12
  export declare function isArweaveTransactionGatewayUrl(raw: string): boolean;
13
+ /** Clears the Arweave body cache. For tests. */
14
+ export declare function resetArweaveBodyCache(): void;
13
15
  /**
14
16
  * After relation URL resolution, Html/File fields may be gateway URLs (or local paths).
15
17
  * Replace those with the UTF-8 body when `hydrateStorage` is enabled.
18
+ * Up to HYDRATE_CONCURRENCY bodies are resolved at a time, across all items.
16
19
  */
17
20
  export declare function hydrateArweaveRichTextInItems(items: Record<string, unknown>[], options?: HydrateStorageOptions): Promise<void>;
18
21
  /** @deprecated Use {@link hydrateArweaveRichTextInItems} */
@@ -1 +1 @@
1
- {"version":3,"file":"hydrateArweaveRichText.d.ts","sourceRoot":"","sources":["../src/hydrateArweaveRichText.ts"],"names":[],"mappings":"AAaA,MAAM,MAAM,qBAAqB,GAAG;IAClC,iFAAiF;IACjF,eAAe,CAAC,EAAE,CAAC,GAAG,EAAE;QACtB,YAAY,EAAE,MAAM,CAAA;QACpB,KAAK,EAAE,OAAO,CAAA;QACd,aAAa,CAAC,EAAE,MAAM,CAAA;KACvB,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAA;CAC7B,CAAA;AAED;;GAEG;AACH,wBAAgB,8BAA8B,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAenE;AAkDD;;;GAGG;AACH,wBAAsB,6BAA6B,CACjD,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,EAChC,OAAO,CAAC,EAAE,qBAAqB,GAC9B,OAAO,CAAC,IAAI,CAAC,CA+Bf;AAED,4DAA4D;AAC5D,eAAO,MAAM,iCAAiC,sCAAgC,CAAA"}
1
+ {"version":3,"file":"hydrateArweaveRichText.d.ts","sourceRoot":"","sources":["../src/hydrateArweaveRichText.ts"],"names":[],"mappings":"AAaA,MAAM,MAAM,qBAAqB,GAAG;IAClC,iFAAiF;IACjF,eAAe,CAAC,EAAE,CAAC,GAAG,EAAE;QACtB,YAAY,EAAE,MAAM,CAAA;QACpB,KAAK,EAAE,OAAO,CAAA;QACd,aAAa,CAAC,EAAE,MAAM,CAAA;KACvB,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAA;CAC7B,CAAA;AAED;;GAEG;AACH,wBAAgB,8BAA8B,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAenE;AAiCD,gDAAgD;AAChD,wBAAgB,qBAAqB,IAAI,IAAI,CAI5C;AAuED;;;;GAIG;AACH,wBAAsB,6BAA6B,CACjD,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,EAChC,OAAO,CAAC,EAAE,qBAAqB,GAC9B,OAAO,CAAC,IAAI,CAAC,CAyCf;AAED,4DAA4D;AAC5D,eAAO,MAAM,iCAAiC,sCAAgC,CAAA"}
package/dist/index.d.ts CHANGED
@@ -2,11 +2,11 @@ export { initializeQueryPlatform, teardownQueryPlatform, isQueryPlatformInitiali
2
2
  export type { InitializeQueryPlatformOptions } from './bootstrap.js';
3
3
  export { assembleSeeds } from './assembleSeeds.js';
4
4
  export { assembleSeedChangelog } from './assembleChangelog.js';
5
- export { getSeed, queryBySchema, queryBySchemaForMonth } from './api.js';
5
+ export { getSeed, normalizeUidPrefix, queryBySchema, queryBySchemaForMonth } from './api.js';
6
6
  export { registerLocalQuerySource, clearLocalQuerySource, getRegisteredLocalQuerySource, hasLocalQuerySource, createRemoteQueryDataSource, getRemoteQueryDataSource, resolveQuerySource, normalizeSourceMode, } from './source/index.js';
7
7
  export type { QueryDataSource, ResolvedQuerySource } from './source/index.js';
8
8
  export { buildFlatSnapshotFromProperties, diffVersionSnapshots, diffPropertyAttestations, applyChangelogFilters, decodePropertyAttestation, changelogValuesEqual, } from './changelog.js';
9
- export type { SeedRecord, AssembleOptions, QuerySourceMode, GetSeedOptions, GetSeedResult, ChangelogInclude, ChangelogOptions, ChangelogEntry, VersionChangelogEntry, PropertyChangelogEntry, QueryBySchemaOptions, QueryBySchemaResult, AttestationLike, } from './types.js';
9
+ export type { SeedData, SeedRecord, AssembleOptions, QuerySourceMode, GetSeedOptions, GetSeedResult, ChangelogInclude, ChangelogOptions, ChangelogEntry, VersionChangelogEntry, PropertyChangelogEntry, QueryBySchemaOptions, QueryBySchemaResult, AttestationChange, AttestationLike, } from './types.js';
10
10
  export { getQueryCacheManager, resetQueryCacheManager, createQueryCacheManager, loadQueryCacheConfig, CacheManager, buildAssembleOptionsKey, } from './cache/index.js';
11
11
  export type { CachedCollectionData, CachedItemData, PersistentCache, QueryCacheConfig, QueryCacheStats, } from './cache/index.js';
12
12
  export { getArweaveUrlForTransaction } from './arweaveUrl.js';
@@ -18,6 +18,6 @@ export type { ParsedEasRelationPropertyName } from './parseEasRelationPropertyNa
18
18
  export { RICH_BODY_STORAGE_SCHEMAS, FEED_RICH_BODY_STORAGE_SCHEMAS, isRichBodyStorageSchema, isFeedRichBodyStorageSchema, richBodyModelPriority, feedRichBodyModelPriority, getFieldStorageModels, getFeedFieldStorageModels, getListElementStorageModels, getFeedListElementStorageModels, setFieldStorageModel, setFeedFieldStorageModel, setListElementStorageModels, setFeedListElementStorageModels, } from './fieldStorageModel.js';
19
19
  export type { FieldStorageModels, FeedFieldStorageModels, ListElementStorageModels, FeedListElementStorageModels, } from './fieldStorageModel.js';
20
20
  export { enrichImageSeedClone, enrichImageSeedCloneForFeed, } from './imageRelationEnrichment.js';
21
- export { hydrateArweaveRichTextInItems, hydrateArweaveRichTextInFeedItems, isArweaveTransactionGatewayUrl, } from './hydrateArweaveRichText.js';
21
+ export { hydrateArweaveRichTextInItems, hydrateArweaveRichTextInFeedItems, isArweaveTransactionGatewayUrl, resetArweaveBodyCache, } from './hydrateArweaveRichText.js';
22
22
  export type { HydrateStorageOptions } from './hydrateArweaveRichText.js';
23
23
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,uBAAuB,EACvB,qBAAqB,EACrB,0BAA0B,EAC1B,oBAAoB,GACrB,MAAM,gBAAgB,CAAA;AACvB,YAAY,EAAE,8BAA8B,EAAE,MAAM,gBAAgB,CAAA;AAEpE,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAClD,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAA;AAC9D,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAA;AAExE,OAAO,EACL,wBAAwB,EACxB,qBAAqB,EACrB,6BAA6B,EAC7B,mBAAmB,EACnB,2BAA2B,EAC3B,wBAAwB,EACxB,kBAAkB,EAClB,mBAAmB,GACpB,MAAM,mBAAmB,CAAA;AAC1B,YAAY,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAA;AAE7E,OAAO,EACL,+BAA+B,EAC/B,oBAAoB,EACpB,wBAAwB,EACxB,qBAAqB,EACrB,yBAAyB,EACzB,oBAAoB,GACrB,MAAM,gBAAgB,CAAA;AAEvB,YAAY,EACV,UAAU,EACV,eAAe,EACf,eAAe,EACf,cAAc,EACd,aAAa,EACb,gBAAgB,EAChB,gBAAgB,EAChB,cAAc,EACd,qBAAqB,EACrB,sBAAsB,EACtB,oBAAoB,EACpB,mBAAmB,EACnB,eAAe,GAChB,MAAM,YAAY,CAAA;AAEnB,OAAO,EACL,oBAAoB,EACpB,sBAAsB,EACtB,uBAAuB,EACvB,oBAAoB,EACpB,YAAY,EACZ,uBAAuB,GACxB,MAAM,kBAAkB,CAAA;AACzB,YAAY,EACV,oBAAoB,EACpB,cAAc,EACd,eAAe,EACf,gBAAgB,EAChB,eAAe,GAChB,MAAM,kBAAkB,CAAA;AAEzB,OAAO,EAAE,2BAA2B,EAAE,MAAM,iBAAiB,CAAA;AAE7D,OAAO,EACL,6BAA6B,EAC7B,2CAA2C,EAC3C,wBAAwB,GACzB,MAAM,sBAAsB,CAAA;AAE7B,OAAO,EACL,wBAAwB,EACxB,+BAA+B,GAChC,MAAM,+BAA+B,CAAA;AACtC,YAAY,EACV,mBAAmB,EACnB,0BAA0B,EAC1B,8BAA8B,EAC9B,qCAAqC,GACtC,MAAM,+BAA+B,CAAA;AAEtC,OAAO,EAAE,4BAA4B,EAAE,MAAM,mCAAmC,CAAA;AAChF,YAAY,EAAE,6BAA6B,EAAE,MAAM,mCAAmC,CAAA;AAEtF,OAAO,EACL,yBAAyB,EACzB,8BAA8B,EAC9B,uBAAuB,EACvB,2BAA2B,EAC3B,qBAAqB,EACrB,yBAAyB,EACzB,qBAAqB,EACrB,yBAAyB,EACzB,2BAA2B,EAC3B,+BAA+B,EAC/B,oBAAoB,EACpB,wBAAwB,EACxB,2BAA2B,EAC3B,+BAA+B,GAChC,MAAM,wBAAwB,CAAA;AAC/B,YAAY,EACV,kBAAkB,EAClB,sBAAsB,EACtB,wBAAwB,EACxB,4BAA4B,GAC7B,MAAM,wBAAwB,CAAA;AAE/B,OAAO,EACL,oBAAoB,EACpB,2BAA2B,GAC5B,MAAM,8BAA8B,CAAA;AAErC,OAAO,EACL,6BAA6B,EAC7B,iCAAiC,EACjC,8BAA8B,GAC/B,MAAM,6BAA6B,CAAA;AACpC,YAAY,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,uBAAuB,EACvB,qBAAqB,EACrB,0BAA0B,EAC1B,oBAAoB,GACrB,MAAM,gBAAgB,CAAA;AACvB,YAAY,EAAE,8BAA8B,EAAE,MAAM,gBAAgB,CAAA;AAEpE,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAClD,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAA;AAC9D,OAAO,EAAE,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAA;AAE5F,OAAO,EACL,wBAAwB,EACxB,qBAAqB,EACrB,6BAA6B,EAC7B,mBAAmB,EACnB,2BAA2B,EAC3B,wBAAwB,EACxB,kBAAkB,EAClB,mBAAmB,GACpB,MAAM,mBAAmB,CAAA;AAC1B,YAAY,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAA;AAE7E,OAAO,EACL,+BAA+B,EAC/B,oBAAoB,EACpB,wBAAwB,EACxB,qBAAqB,EACrB,yBAAyB,EACzB,oBAAoB,GACrB,MAAM,gBAAgB,CAAA;AAEvB,YAAY,EACV,QAAQ,EACR,UAAU,EACV,eAAe,EACf,eAAe,EACf,cAAc,EACd,aAAa,EACb,gBAAgB,EAChB,gBAAgB,EAChB,cAAc,EACd,qBAAqB,EACrB,sBAAsB,EACtB,oBAAoB,EACpB,mBAAmB,EACnB,iBAAiB,EACjB,eAAe,GAChB,MAAM,YAAY,CAAA;AAEnB,OAAO,EACL,oBAAoB,EACpB,sBAAsB,EACtB,uBAAuB,EACvB,oBAAoB,EACpB,YAAY,EACZ,uBAAuB,GACxB,MAAM,kBAAkB,CAAA;AACzB,YAAY,EACV,oBAAoB,EACpB,cAAc,EACd,eAAe,EACf,gBAAgB,EAChB,eAAe,GAChB,MAAM,kBAAkB,CAAA;AAEzB,OAAO,EAAE,2BAA2B,EAAE,MAAM,iBAAiB,CAAA;AAE7D,OAAO,EACL,6BAA6B,EAC7B,2CAA2C,EAC3C,wBAAwB,GACzB,MAAM,sBAAsB,CAAA;AAE7B,OAAO,EACL,wBAAwB,EACxB,+BAA+B,GAChC,MAAM,+BAA+B,CAAA;AACtC,YAAY,EACV,mBAAmB,EACnB,0BAA0B,EAC1B,8BAA8B,EAC9B,qCAAqC,GACtC,MAAM,+BAA+B,CAAA;AAEtC,OAAO,EAAE,4BAA4B,EAAE,MAAM,mCAAmC,CAAA;AAChF,YAAY,EAAE,6BAA6B,EAAE,MAAM,mCAAmC,CAAA;AAEtF,OAAO,EACL,yBAAyB,EACzB,8BAA8B,EAC9B,uBAAuB,EACvB,2BAA2B,EAC3B,qBAAqB,EACrB,yBAAyB,EACzB,qBAAqB,EACrB,yBAAyB,EACzB,2BAA2B,EAC3B,+BAA+B,EAC/B,oBAAoB,EACpB,wBAAwB,EACxB,2BAA2B,EAC3B,+BAA+B,GAChC,MAAM,wBAAwB,CAAA;AAC/B,YAAY,EACV,kBAAkB,EAClB,sBAAsB,EACtB,wBAAwB,EACxB,4BAA4B,GAC7B,MAAM,wBAAwB,CAAA;AAE/B,OAAO,EACL,oBAAoB,EACpB,2BAA2B,GAC5B,MAAM,8BAA8B,CAAA;AAErC,OAAO,EACL,6BAA6B,EAC7B,iCAAiC,EACjC,8BAA8B,EAC9B,qBAAqB,GACtB,MAAM,6BAA6B,CAAA;AACpC,YAAY,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAA"}
package/dist/index.js CHANGED
@@ -1,3 +1,3 @@
1
1
  import { a as e, i as t, o as n, r, t as i } from "./types-DHRoT30t.js";
2
- import { A as a, B as o, C as s, D as c, E as l, F as u, G as d, H as f, I as p, J as m, K as h, L as g, M as _, N as v, O as y, P as b, R as x, S, T as C, U as w, V as T, W as E, X as D, Y as O, Z as k, _ as A, a as j, b as M, c as N, d as P, f as F, g as I, i as L, j as R, k as z, l as B, m as V, n as H, o as U, p as W, q as G, r as K, s as q, t as J, u as Y, v as X, w as Z, x as Q, y as $, z as ee } from "./src-DOx4oUlk.js";
3
- export { V as CacheManager, r as DEFAULT_ARWEAVE_HOST, _ as FEED_RICH_BODY_STORAGE_SCHEMAS, v as RICH_BODY_STORAGE_SCHEMAS, A as applyChangelogFilters, I as assembleSeedChangelog, s as assembleSeeds, i as buildAssembleOptionsKey, X as buildFlatSnapshotFromProperties, $ as changelogValuesEqual, U as clearLocalQuerySource, Y as createQueryCacheManager, Z as createRemoteQueryDataSource, M as decodePropertyAttestation, Q as diffPropertyAttestations, S as diffVersionSnapshots, h as enrichImageSeedClone, G as enrichImageSeedCloneForFeed, b as feedRichBodyModelPriority, k as getArweaveUrlForTransaction, u as getFeedFieldStorageModels, p as getFeedListElementStorageModels, g as getFieldStorageModels, x as getListElementStorageModels, P as getQueryCacheManager, q as getRegisteredLocalQuerySource, C as getRemoteQueryDataSource, J as getSeed, N as hasLocalQuerySource, z as hydrateArweaveRichTextInFeedItems, a as hydrateArweaveRichTextInItems, t as initializeQueryPlatform, R as isArweaveTransactionGatewayUrl, ee as isFeedRichBodyStorageSchema, e as isQueryPlatformInitialized, o as isRichBodyStorageSchema, W as loadQueryCacheConfig, L as normalizeSourceMode, c as parseEasPropertyMetadata, y as parseEasPropertyMetadataForFeed, l as parseEasRelationPropertyName, m as publicListRelationPropertyKey, H as queryBySchema, K as queryBySchemaForMonth, B as registerLocalQuerySource, F as resetQueryCacheManager, j as resolveQuerySource, T as richBodyModelPriority, f as setFeedFieldStorageModel, w as setFeedListElementStorageModels, E as setFieldStorageModel, d as setListElementStorageModels, O as stripListRelationStorageAliasesForPublicKey, n as teardownQueryPlatform, D as tryCoerceJsonStringArray };
2
+ import { $ as a, A as o, B as s, C as c, D as l, E as u, F as d, G as f, H as p, I as m, J as h, K as g, L as _, M as v, N as y, O as b, P as x, Q as S, R as C, S as w, T, U as E, V as D, W as O, X as k, Y as A, Z as j, _ as M, a as N, b as P, c as F, d as I, f as L, g as R, i as z, j as B, k as V, l as H, m as U, n as W, o as G, p as K, q, r as J, s as Y, t as X, u as Z, v as Q, w as $, x as ee, y as te, z as ne } from "./src-CBgjwvGT.js";
3
+ export { U as CacheManager, r as DEFAULT_ARWEAVE_HOST, x as FEED_RICH_BODY_STORAGE_SCHEMAS, d as RICH_BODY_STORAGE_SCHEMAS, Q as applyChangelogFilters, M as assembleSeedChangelog, $ as assembleSeeds, i as buildAssembleOptionsKey, te as buildFlatSnapshotFromProperties, P as changelogValuesEqual, Y as clearLocalQuerySource, I as createQueryCacheManager, T as createRemoteQueryDataSource, ee as decodePropertyAttestation, w as diffPropertyAttestations, c as diffVersionSnapshots, h as enrichImageSeedClone, A as enrichImageSeedCloneForFeed, m as feedRichBodyModelPriority, a as getArweaveUrlForTransaction, _ as getFeedFieldStorageModels, C as getFeedListElementStorageModels, ne as getFieldStorageModels, s as getListElementStorageModels, L as getQueryCacheManager, F as getRegisteredLocalQuerySource, u as getRemoteQueryDataSource, X as getSeed, H as hasLocalQuerySource, o as hydrateArweaveRichTextInFeedItems, B as hydrateArweaveRichTextInItems, t as initializeQueryPlatform, v as isArweaveTransactionGatewayUrl, D as isFeedRichBodyStorageSchema, e as isQueryPlatformInitialized, p as isRichBodyStorageSchema, R as loadQueryCacheConfig, N as normalizeSourceMode, W as normalizeUidPrefix, b as parseEasPropertyMetadata, V as parseEasPropertyMetadataForFeed, l as parseEasRelationPropertyName, k as publicListRelationPropertyKey, J as queryBySchema, z as queryBySchemaForMonth, Z as registerLocalQuerySource, y as resetArweaveBodyCache, K as resetQueryCacheManager, G as resolveQuerySource, E as richBodyModelPriority, O as setFeedFieldStorageModel, f as setFeedListElementStorageModels, g as setFieldStorageModel, q as setListElementStorageModels, j as stripListRelationStorageAliasesForPublicKey, n as teardownQueryPlatform, S as tryCoerceJsonStringArray };