@f0rbit/corpus 0.1.8 → 0.2.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.
@@ -0,0 +1,108 @@
1
+ /**
2
+ * @module Concurrency
3
+ * @description Utilities for controlling concurrent async operations.
4
+ */
5
+ /**
6
+ * Semaphore for controlling concurrent operations.
7
+ *
8
+ * Limits the number of concurrent async operations by requiring
9
+ * callers to acquire a permit before proceeding. When all permits
10
+ * are taken, subsequent acquires wait until a permit is released.
11
+ *
12
+ * @example
13
+ * ```ts
14
+ * const semaphore = new Semaphore(3) // Allow 3 concurrent operations
15
+ *
16
+ * async function rateLimitedFetch(url: string) {
17
+ * await semaphore.acquire()
18
+ * try {
19
+ * return await fetch(url)
20
+ * } finally {
21
+ * semaphore.release()
22
+ * }
23
+ * }
24
+ *
25
+ * // Only 3 fetches will run concurrently
26
+ * await Promise.all(urls.map(rateLimitedFetch))
27
+ * ```
28
+ */
29
+ export class Semaphore {
30
+ permits;
31
+ waiting = [];
32
+ constructor(permits) {
33
+ this.permits = permits;
34
+ }
35
+ /**
36
+ * Acquire a permit. Resolves immediately if available,
37
+ * otherwise waits until a permit is released.
38
+ */
39
+ async acquire() {
40
+ if (this.permits > 0) {
41
+ this.permits--;
42
+ return;
43
+ }
44
+ return new Promise(resolve => {
45
+ this.waiting.push(resolve);
46
+ });
47
+ }
48
+ /**
49
+ * Release a permit, allowing the next waiting operation to proceed.
50
+ */
51
+ release() {
52
+ const next = this.waiting.shift();
53
+ if (next) {
54
+ next();
55
+ }
56
+ else {
57
+ this.permits++;
58
+ }
59
+ }
60
+ }
61
+ /**
62
+ * Map over array with controlled concurrency.
63
+ *
64
+ * Unlike Promise.all which starts all operations at once, this limits
65
+ * concurrent operations. Results are returned in the same order as inputs.
66
+ *
67
+ * @param items - Array of items to process
68
+ * @param mapper - Async function to apply to each item
69
+ * @param concurrency - Maximum number of concurrent operations
70
+ * @returns Array of results in the same order as inputs
71
+ *
72
+ * @example
73
+ * ```ts
74
+ * // Process 100 items, but only 5 at a time
75
+ * const results = await parallel_map(
76
+ * urls,
77
+ * async (url, index) => {
78
+ * console.log(`Fetching ${index + 1}/${urls.length}`)
79
+ * return fetch(url).then(r => r.json())
80
+ * },
81
+ * 5
82
+ * )
83
+ * ```
84
+ *
85
+ * @example
86
+ * ```ts
87
+ * // Use with AI APIs that have rate limits
88
+ * const summaries = await parallel_map(
89
+ * documents,
90
+ * doc => summarize(doc),
91
+ * 3 // Only 3 concurrent API calls
92
+ * )
93
+ * ```
94
+ */
95
+ export const parallel_map = async (items, mapper, concurrency) => {
96
+ const semaphore = new Semaphore(concurrency);
97
+ const results = new Array(items.length);
98
+ await Promise.all(items.map(async (item, index) => {
99
+ await semaphore.acquire();
100
+ try {
101
+ results[index] = await mapper(item, index);
102
+ }
103
+ finally {
104
+ semaphore.release();
105
+ }
106
+ }));
107
+ return results;
108
+ };
package/dist/index.d.ts CHANGED
@@ -1,12 +1,14 @@
1
- export { create_corpus, create_store } from './corpus';
2
- export { create_memory_backend, type MemoryBackendOptions } from './backend/memory';
3
- export { create_file_backend, type FileBackendConfig } from './backend/file';
4
- export { create_cloudflare_backend, type CloudflareBackendConfig } from './backend/cloudflare';
5
- export { create_layered_backend, type LayeredBackendOptions } from './backend/layered';
6
- export { json_codec, text_codec, binary_codec, compute_hash, generate_version } from './utils';
7
- export { corpus_snapshots, type CorpusSnapshotRow, type CorpusSnapshotInsert } from './schema';
8
- export type { ContentType, ParentRef, SnapshotMeta, Snapshot, DataHandle, MetadataClient, DataClient, ListOpts, Backend, Codec, Store, StoreDefinition, DefineStoreOpts, DataKeyContext, PutOpts, CorpusBuilder, Corpus, CorpusError, Result, CorpusEvent, EventHandler, ObservationsClient, } from './types';
9
- export { ok, err, define_store } from './types';
10
- export * from './observations';
11
- export { createCorpusInfra, CORPUS_MIGRATION_SQL, type CorpusInfra, type CorpusInfraConfig } from './sst';
1
+ export { create_corpus, create_store } from "./corpus";
2
+ export { create_memory_backend, type MemoryBackendOptions } from "./backend/memory";
3
+ export { create_file_backend, type FileBackendConfig } from "./backend/file";
4
+ export { create_cloudflare_backend, type CloudflareBackendConfig } from "./backend/cloudflare";
5
+ export { create_layered_backend, type LayeredBackendOptions } from "./backend/layered";
6
+ export { json_codec, text_codec, binary_codec, compute_hash, generate_version } from "./utils";
7
+ export { corpus_snapshots, type CorpusSnapshotRow, type CorpusSnapshotInsert } from "./schema";
8
+ export type { ContentType, ParentRef, SnapshotMeta, Snapshot, DataHandle, MetadataClient, DataClient, ListOpts, Backend, Codec, Parser, Store, StoreDefinition, DefineStoreOpts, DataKeyContext, PutOpts, CorpusBuilder, Corpus, CorpusError, Result, CorpusEvent, EventHandler, ObservationsClient, } from "./types";
9
+ export { ok, err, define_store } from "./types";
10
+ export { match, unwrap_or, unwrap, unwrap_err, try_catch, try_catch_async, fetch_result, pipe, to_nullable, to_fallback, null_on, fallback_on, format_error, type FetchError, type Pipe, } from "./result";
11
+ export { Semaphore, parallel_map } from "./concurrency";
12
+ export * from "./observations";
13
+ export { createCorpusInfra, CORPUS_MIGRATION_SQL, type CorpusInfra, type CorpusInfraConfig } from "./sst";
12
14
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AAEtD,OAAO,EAAE,qBAAqB,EAAE,KAAK,oBAAoB,EAAE,MAAM,kBAAkB,CAAA;AACnF,OAAO,EAAE,mBAAmB,EAAE,KAAK,iBAAiB,EAAE,MAAM,gBAAgB,CAAA;AAC5E,OAAO,EAAE,yBAAyB,EAAE,KAAK,uBAAuB,EAAE,MAAM,sBAAsB,CAAA;AAC9F,OAAO,EAAE,sBAAsB,EAAE,KAAK,qBAAqB,EAAE,MAAM,mBAAmB,CAAA;AAEtF,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,YAAY,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAA;AAE9F,OAAO,EAAE,gBAAgB,EAAE,KAAK,iBAAiB,EAAE,KAAK,oBAAoB,EAAE,MAAM,UAAU,CAAA;AAE9F,YAAY,EACV,WAAW,EACX,SAAS,EACT,YAAY,EACZ,QAAQ,EACR,UAAU,EACV,cAAc,EACd,UAAU,EACV,QAAQ,EACR,OAAO,EACP,KAAK,EACL,KAAK,EACL,eAAe,EACf,eAAe,EACf,cAAc,EACd,OAAO,EACP,aAAa,EACb,MAAM,EACN,WAAW,EACX,MAAM,EACN,WAAW,EACX,YAAY,EACZ,kBAAkB,GACnB,MAAM,SAAS,CAAA;AAEhB,OAAO,EAAE,EAAE,EAAE,GAAG,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAE/C,cAAc,gBAAgB,CAAA;AAE9B,OAAO,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,KAAK,WAAW,EAAE,KAAK,iBAAiB,EAAE,MAAM,OAAO,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAEvD,OAAO,EAAE,qBAAqB,EAAE,KAAK,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AACpF,OAAO,EAAE,mBAAmB,EAAE,KAAK,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAC7E,OAAO,EAAE,yBAAyB,EAAE,KAAK,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAC/F,OAAO,EAAE,sBAAsB,EAAE,KAAK,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAEvF,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,YAAY,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAE/F,OAAO,EAAE,gBAAgB,EAAE,KAAK,iBAAiB,EAAE,KAAK,oBAAoB,EAAE,MAAM,UAAU,CAAC;AAE/F,YAAY,EACX,WAAW,EACX,SAAS,EACT,YAAY,EACZ,QAAQ,EACR,UAAU,EACV,cAAc,EACd,UAAU,EACV,QAAQ,EACR,OAAO,EACP,KAAK,EACL,MAAM,EACN,KAAK,EACL,eAAe,EACf,eAAe,EACf,cAAc,EACd,OAAO,EACP,aAAa,EACb,MAAM,EACN,WAAW,EACX,MAAM,EACN,WAAW,EACX,YAAY,EACZ,kBAAkB,GAClB,MAAM,SAAS,CAAC;AAEjB,OAAO,EAAE,EAAE,EAAE,GAAG,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAEhD,OAAO,EACN,KAAK,EACL,SAAS,EACT,MAAM,EACN,UAAU,EACV,SAAS,EACT,eAAe,EACf,YAAY,EACZ,IAAI,EACJ,WAAW,EACX,WAAW,EACX,OAAO,EACP,WAAW,EACX,YAAY,EACZ,KAAK,UAAU,EACf,KAAK,IAAI,GACT,MAAM,UAAU,CAAC;AAElB,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAExD,cAAc,gBAAgB,CAAC;AAE/B,OAAO,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,KAAK,WAAW,EAAE,KAAK,iBAAiB,EAAE,MAAM,OAAO,CAAC"}
package/dist/index.js CHANGED
@@ -1,10 +1,12 @@
1
- export { create_corpus, create_store } from './corpus';
2
- export { create_memory_backend } from './backend/memory';
3
- export { create_file_backend } from './backend/file';
4
- export { create_cloudflare_backend } from './backend/cloudflare';
5
- export { create_layered_backend } from './backend/layered';
6
- export { json_codec, text_codec, binary_codec, compute_hash, generate_version } from './utils';
7
- export { corpus_snapshots } from './schema';
8
- export { ok, err, define_store } from './types';
9
- export * from './observations';
10
- export { createCorpusInfra, CORPUS_MIGRATION_SQL } from './sst';
1
+ export { create_corpus, create_store } from "./corpus";
2
+ export { create_memory_backend } from "./backend/memory";
3
+ export { create_file_backend } from "./backend/file";
4
+ export { create_cloudflare_backend } from "./backend/cloudflare";
5
+ export { create_layered_backend } from "./backend/layered";
6
+ export { json_codec, text_codec, binary_codec, compute_hash, generate_version } from "./utils";
7
+ export { corpus_snapshots } from "./schema";
8
+ export { ok, err, define_store } from "./types";
9
+ export { match, unwrap_or, unwrap, unwrap_err, try_catch, try_catch_async, fetch_result, pipe, to_nullable, to_fallback, null_on, fallback_on, format_error, } from "./result";
10
+ export { Semaphore, parallel_map } from "./concurrency";
11
+ export * from "./observations";
12
+ export { createCorpusInfra, CORPUS_MIGRATION_SQL } from "./sst";
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../observations/client.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAuB,cAAc,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAExF,OAAO,KAAK,EAAE,mBAAmB,EAAoB,MAAM,WAAW,CAAC;AAuBvE;;;GAGG;AACH,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,mBAAmB,EAAE,QAAQ,EAAE,cAAc,GAAG,kBAAkB,CAmHrH"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../observations/client.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAuB,cAAc,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAExF,OAAO,KAAK,EAAE,mBAAmB,EAAoB,MAAM,WAAW,CAAC;AA6BvE;;;GAGG;AACH,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,mBAAmB,EAAE,QAAQ,EAAE,cAAc,GAAG,kBAAkB,CAiGrH"}
@@ -5,6 +5,13 @@
5
5
  import { row_to_observation, row_to_meta, create_observation_row } from "./storage";
6
6
  import { generate_observation_id } from "./utils";
7
7
  import { ok, err } from "../types";
8
+ async function apply_version_filter(filter, store_id, version) {
9
+ if (typeof filter === "function")
10
+ return filter(store_id, version);
11
+ if (filter instanceof Set)
12
+ return filter.has(version);
13
+ return filter.includes(version);
14
+ }
8
15
  /**
9
16
  * Convert client query opts to storage query opts.
10
17
  * Handles Date -> ISO string conversion.
@@ -31,14 +38,6 @@ export function create_observations_client(storage, metadata) {
31
38
  const result = await metadata.get_latest(store_id);
32
39
  return result.ok ? result.value.version : null;
33
40
  }
34
- async function resolve_version(store_id, resolver) {
35
- if (resolver) {
36
- const resolved = await resolver(store_id);
37
- if (resolved !== null)
38
- return resolved;
39
- }
40
- return get_latest_version(store_id);
41
- }
42
41
  return {
43
42
  async put(type, opts) {
44
43
  const validation = type.schema.safeParse(opts.content);
@@ -81,15 +80,10 @@ export function create_observations_client(storage, metadata) {
81
80
  },
82
81
  async *query(opts = {}) {
83
82
  const storageOpts = to_storage_opts(opts);
84
- const version_cache = new Map();
85
83
  for await (const row of storage.query_rows(storageOpts)) {
86
- if (!opts.include_stale) {
87
- let canonical_version = version_cache.get(row.source_store_id);
88
- if (canonical_version === undefined) {
89
- canonical_version = await resolve_version(row.source_store_id, opts.version_resolver);
90
- version_cache.set(row.source_store_id, canonical_version);
91
- }
92
- if (canonical_version && row.source_version !== canonical_version)
84
+ if (opts.version_filter !== undefined) {
85
+ const included = await apply_version_filter(opts.version_filter, row.source_store_id, row.source_version);
86
+ if (!included)
93
87
  continue;
94
88
  }
95
89
  yield row_to_observation(row);
@@ -97,15 +91,10 @@ export function create_observations_client(storage, metadata) {
97
91
  },
98
92
  async *query_meta(opts = {}) {
99
93
  const storageOpts = to_storage_opts(opts);
100
- const version_cache = new Map();
101
94
  for await (const row of storage.query_rows(storageOpts)) {
102
- if (!opts.include_stale) {
103
- let canonical_version = version_cache.get(row.source_store_id);
104
- if (canonical_version === undefined) {
105
- canonical_version = await resolve_version(row.source_store_id, opts.version_resolver);
106
- version_cache.set(row.source_store_id, canonical_version);
107
- }
108
- if (canonical_version && row.source_version !== canonical_version)
95
+ if (opts.version_filter !== undefined) {
96
+ const included = await apply_version_filter(opts.version_filter, row.source_store_id, row.source_version);
97
+ if (!included)
109
98
  continue;
110
99
  }
111
100
  yield row_to_meta(row);
@@ -5,7 +5,7 @@
5
5
  export * from './types';
6
6
  export type { ObservationRow, ObservationInsert } from './schema';
7
7
  export { corpus_observations } from './schema';
8
- export type { ObservationsStorage, StorageQueryOpts, ObservationsCRUD } from './storage';
8
+ export type { ObservationsStorage, StorageQueryOpts, ObservationsCRUD, ObservationsAdapter, ObservationsCRUDBase, ObservationsCRUDOptimized } from './storage';
9
9
  export { row_to_observation, row_to_meta, create_observation_row, filter_observation_rows, create_observations_storage } from './storage';
10
10
  export { create_observations_client } from './client';
11
11
  export * from './utils';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../observations/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,cAAc,SAAS,CAAA;AACvB,YAAY,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAA;AACjE,OAAO,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAA;AAC9C,YAAY,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAA;AAGxF,OAAO,EAAE,kBAAkB,EAAE,WAAW,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,2BAA2B,EAAE,MAAM,WAAW,CAAA;AACzI,OAAO,EAAE,0BAA0B,EAAE,MAAM,UAAU,CAAA;AACrD,cAAc,SAAS,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../observations/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,cAAc,SAAS,CAAA;AACvB,YAAY,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAA;AACjE,OAAO,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAA;AAC9C,YAAY,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,yBAAyB,EAAE,MAAM,WAAW,CAAA;AAG9J,OAAO,EAAE,kBAAkB,EAAE,WAAW,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,2BAA2B,EAAE,MAAM,WAAW,CAAA;AACzI,OAAO,EAAE,0BAA0B,EAAE,MAAM,UAAU,CAAA;AACrD,cAAc,SAAS,CAAA"}
@@ -58,7 +58,31 @@ export declare function create_observation_row(id: string, type_name: string, so
58
58
  */
59
59
  export declare function filter_observation_rows(rows: ObservationRow[], opts?: StorageQueryOpts): ObservationRow[];
60
60
  /**
61
- * Simple CRUD interface for observation storage backends.
61
+ * Base CRUD operations for observation storage backends.
62
+ * All backends must implement at minimum these operations.
63
+ */
64
+ export type ObservationsCRUDBase = {
65
+ get_all: () => Promise<ObservationRow[]>;
66
+ set_all: (rows: ObservationRow[]) => Promise<void>;
67
+ get_one: (id: string) => Promise<ObservationRow | null>;
68
+ add_one: (row: ObservationRow) => Promise<Result<void, CorpusError>>;
69
+ remove_one: (id: string) => Promise<Result<boolean, CorpusError>>;
70
+ };
71
+ /**
72
+ * Optional optimized operations for backends with native query capabilities.
73
+ * When provided, these are used instead of loading all rows into memory.
74
+ */
75
+ export type ObservationsCRUDOptimized = {
76
+ query: (opts: StorageQueryOpts) => AsyncIterable<ObservationRow>;
77
+ delete_by_source: (store_id: string, version: string, path?: string) => Promise<Result<number, CorpusError>>;
78
+ };
79
+ /**
80
+ * Storage adapter interface for observation backends.
81
+ * Backends provide base CRUD operations and optionally optimized operations.
82
+ */
83
+ export type ObservationsAdapter = ObservationsCRUDBase & Partial<ObservationsCRUDOptimized>;
84
+ /**
85
+ * @deprecated Use ObservationsAdapter instead
62
86
  */
63
87
  export type ObservationsCRUD = {
64
88
  get_all: () => Promise<ObservationRow[]>;
@@ -68,8 +92,13 @@ export type ObservationsCRUD = {
68
92
  remove_one: (id: string) => Promise<boolean>;
69
93
  };
70
94
  /**
71
- * Create an ObservationsStorage from simple CRUD operations.
72
- * Used by memory and file backends.
95
+ * Create an ObservationsStorage from an adapter.
96
+ *
97
+ * Backends provide simple CRUD operations and optionally optimized query/delete operations.
98
+ * When optimized operations are not provided, falls back to loading all rows into memory.
99
+ *
100
+ * @param adapter - Storage adapter with base CRUD and optional optimized operations
101
+ * @returns ObservationsStorage interface for use with create_observations_client
73
102
  */
74
- export declare function create_observations_storage(crud: ObservationsCRUD): ObservationsStorage;
103
+ export declare function create_observations_storage(adapter: ObservationsAdapter | ObservationsCRUD): ObservationsStorage;
75
104
  //# sourceMappingURL=storage.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../observations/storage.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../observations/storage.ts"],"names":[],"mappings":"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"}
@@ -3,6 +3,7 @@
3
3
  * @description Raw storage interface and row conversion utilities for observations.
4
4
  */
5
5
  import { ok } from '../types';
6
+ import { create_filter_pipeline } from '../utils';
6
7
  /**
7
8
  * Extract common fields from an observation row (everything except content).
8
9
  * Used internally by row_to_observation and row_to_meta.
@@ -63,74 +64,93 @@ export function create_observation_row(id, type_name, source, content, opts) {
63
64
  derived_from: opts.derived_from ? JSON.stringify(opts.derived_from) : null
64
65
  };
65
66
  }
67
+ const observation_filter_pipeline = create_filter_pipeline({
68
+ filters: [
69
+ {
70
+ key: 'type',
71
+ predicate: (r, type) => {
72
+ const types = Array.isArray(type) ? type : [type];
73
+ return types.includes(r.type);
74
+ }
75
+ },
76
+ { key: 'source_store_id', predicate: (r, id) => r.source_store_id === id },
77
+ { key: 'source_version', predicate: (r, version) => r.source_version === version },
78
+ { key: 'source_prefix', predicate: (r, prefix) => r.source_version.startsWith(prefix) },
79
+ { key: 'created_after', predicate: (r, after) => r.created_at > after },
80
+ { key: 'created_before', predicate: (r, before) => r.created_at < before },
81
+ { key: 'observed_after', predicate: (r, after) => r.observed_at !== null && r.observed_at > after },
82
+ { key: 'observed_before', predicate: (r, before) => r.observed_at !== null && r.observed_at < before }
83
+ ],
84
+ sort: (a, b) => b.created_at.localeCompare(a.created_at)
85
+ });
66
86
  /**
67
87
  * Filter and sort observation rows based on query options.
68
88
  * Used by in-memory storage implementations (memory backend, file backend).
69
89
  */
70
90
  export function filter_observation_rows(rows, opts = {}) {
71
- let filtered = rows;
72
- if (opts.type) {
73
- const types = Array.isArray(opts.type) ? opts.type : [opts.type];
74
- filtered = filtered.filter(r => types.includes(r.type));
75
- }
76
- if (opts.source_store_id) {
77
- filtered = filtered.filter(r => r.source_store_id === opts.source_store_id);
78
- }
79
- if (opts.source_version) {
80
- filtered = filtered.filter(r => r.source_version === opts.source_version);
81
- }
82
- if (opts.source_prefix) {
83
- filtered = filtered.filter(r => r.source_version.startsWith(opts.source_prefix));
84
- }
85
- if (opts.created_after) {
86
- filtered = filtered.filter(r => r.created_at > opts.created_after);
87
- }
88
- if (opts.created_before) {
89
- filtered = filtered.filter(r => r.created_at < opts.created_before);
90
- }
91
- if (opts.observed_after) {
92
- filtered = filtered.filter(r => r.observed_at && r.observed_at > opts.observed_after);
93
- }
94
- if (opts.observed_before) {
95
- filtered = filtered.filter(r => r.observed_at && r.observed_at < opts.observed_before);
96
- }
97
- filtered.sort((a, b) => b.created_at.localeCompare(a.created_at));
98
- if (opts.limit) {
99
- filtered = filtered.slice(0, opts.limit);
100
- }
101
- return filtered;
91
+ return observation_filter_pipeline(rows, opts);
102
92
  }
103
93
  /**
104
- * Create an ObservationsStorage from simple CRUD operations.
105
- * Used by memory and file backends.
94
+ * Create an ObservationsStorage from an adapter.
95
+ *
96
+ * Backends provide simple CRUD operations and optionally optimized query/delete operations.
97
+ * When optimized operations are not provided, falls back to loading all rows into memory.
98
+ *
99
+ * @param adapter - Storage adapter with base CRUD and optional optimized operations
100
+ * @returns ObservationsStorage interface for use with create_observations_client
106
101
  */
107
- export function create_observations_storage(crud) {
102
+ export function create_observations_storage(adapter) {
103
+ const wrap_add_one = async (row) => {
104
+ const result = await adapter.add_one(row);
105
+ if (result === undefined || result === null)
106
+ return ok(undefined);
107
+ if (typeof result === 'object' && 'ok' in result)
108
+ return result;
109
+ return ok(undefined);
110
+ };
111
+ const wrap_remove_one = async (id) => {
112
+ const result = await adapter.remove_one(id);
113
+ if (typeof result === 'boolean')
114
+ return ok(result);
115
+ if (typeof result === 'object' && 'ok' in result)
116
+ return result;
117
+ return ok(false);
118
+ };
108
119
  return {
109
120
  async put_row(row) {
110
- await crud.add_one(row);
121
+ const result = await wrap_add_one(row);
122
+ if (!result.ok)
123
+ return result;
111
124
  return ok(row);
112
125
  },
113
126
  async get_row(id) {
114
- const row = await crud.get_one(id);
127
+ const row = await adapter.get_one(id);
115
128
  return ok(row);
116
129
  },
117
130
  async *query_rows(opts = {}) {
118
- const rows = filter_observation_rows(await crud.get_all(), opts);
119
- for (const row of rows) {
120
- yield row;
131
+ if (adapter.query) {
132
+ yield* adapter.query(opts);
133
+ }
134
+ else {
135
+ const rows = filter_observation_rows(await adapter.get_all(), opts);
136
+ for (const row of rows) {
137
+ yield row;
138
+ }
121
139
  }
122
140
  },
123
141
  async delete_row(id) {
124
- const deleted = await crud.remove_one(id);
125
- return ok(deleted);
142
+ return wrap_remove_one(id);
126
143
  },
127
144
  async delete_by_source(store_id, version, path) {
128
- const rows = await crud.get_all();
145
+ if (adapter.delete_by_source) {
146
+ return adapter.delete_by_source(store_id, version, path);
147
+ }
148
+ const rows = await adapter.get_all();
129
149
  const toKeep = rows.filter(r => !(r.source_store_id === store_id &&
130
150
  r.source_version === version &&
131
151
  (path === undefined || r.source_path === path)));
132
152
  const deleted = rows.length - toKeep.length;
133
- await crud.set_all(toKeep);
153
+ await adapter.set_all(toKeep);
134
154
  return ok(deleted);
135
155
  }
136
156
  };
@@ -120,23 +120,31 @@ export type ObservationPutOpts<T> = {
120
120
  derived_from?: SnapshotPointer[];
121
121
  };
122
122
  /**
123
- * Function that resolves which version is "canonical" for a given store.
124
- * Return null to fall back to default behavior (most recent by created_at).
123
+ * Filter for version-based observation filtering.
124
+ * - Set<string> or string[]: Include if version is in the collection
125
+ * - Function: Called with (store_id, version), return true to include
125
126
  *
126
127
  * @category Types
127
128
  * @group Observation Types
128
129
  *
129
130
  * @example
130
131
  * ```ts
131
- * const resolver: VersionResolver = async (store_id) => {
132
+ * // Filter to specific versions
133
+ * const filter: VersionFilter = new Set(['v1', 'v2', 'v3'])
134
+ *
135
+ * // Or use an array
136
+ * const filter: VersionFilter = ['v1', 'v2', 'v3']
137
+ *
138
+ * // Or use a function for dynamic filtering
139
+ * const filter: VersionFilter = async (store_id, version) => {
132
140
  * const published = await db.query.published_reports.findFirst({
133
- * where: eq(published_reports.store_id, store_id)
141
+ * where: eq(published_reports.version, version)
134
142
  * });
135
- * return published?.version ?? null;
143
+ * return published !== null;
136
144
  * };
137
145
  * ```
138
146
  */
139
- export type VersionResolver = (store_id: string) => Promise<string | null>;
147
+ export type VersionFilter = Set<string> | string[] | ((store_id: string, version: string) => boolean | Promise<boolean>);
140
148
  /**
141
149
  * Query options for filtering observations.
142
150
  *
@@ -153,11 +161,10 @@ export type VersionResolver = (store_id: string) => Promise<string | null>;
153
161
  * limit: 100
154
162
  * }
155
163
  *
156
- * // Find all observations for a specific version
164
+ * // Filter to only published versions
157
165
  * const versionOpts: ObservationQueryOpts = {
158
166
  * source_store: 'hansard',
159
- * source_version: 'AZJx4vM',
160
- * include_stale: true
167
+ * version_filter: new Set(['v1', 'v2'])
161
168
  * }
162
169
  * ```
163
170
  */
@@ -170,17 +177,16 @@ export type ObservationQueryOpts = {
170
177
  before?: Date;
171
178
  created_after?: Date;
172
179
  created_before?: Date;
173
- include_stale?: boolean;
174
180
  limit?: number;
175
181
  cursor?: string;
176
182
  /**
177
- * Custom function to resolve which version is "current" for a given store.
178
- * When provided and include_stale is false, this takes precedence over
179
- * the default "most recent by created_at" staleness logic.
183
+ * Filter observations by version.
184
+ * When provided, only observations whose source version passes the filter are included.
180
185
  *
181
- * If the resolver returns null for a store_id, falls back to default behavior.
186
+ * - Set<string> or string[]: Include if version is in the collection
187
+ * - Function: Called with (store_id, version), return true to include
182
188
  */
183
- version_resolver?: VersionResolver;
189
+ version_filter?: VersionFilter;
184
190
  };
185
191
  /**
186
192
  * Utility type to extract the content type from an ObservationTypeDef.
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../observations/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC;AAEnC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,MAAM,MAAM,eAAe,GAAG;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE;QACN,KAAK,EAAE,MAAM,CAAC;QACd,GAAG,EAAE,MAAM,CAAC;KACZ,CAAC;CACF,CAAC;AAEF;;;;;;;;GAQG;AACH,MAAM,MAAM,kBAAkB,CAAC,CAAC,IAAI;IACnC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;CAC5B,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,MAAM,MAAM,WAAW,CAAC,CAAC,GAAG,OAAO,IAAI;IACtC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,eAAe,CAAC;IACxB,OAAO,EAAE,CAAC,CAAC;IACX,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,IAAI,CAAC;IACnB,UAAU,EAAE,IAAI,CAAC;IACjB,YAAY,CAAC,EAAE,eAAe,EAAE,CAAC;CACjC,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,MAAM,eAAe,GAAG,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE,SAAS,CAAC,CAAC;AAElE;;;;;GAKG;AACH,MAAM,MAAM,kBAAkB,CAAC,CAAC,IAAI;IACnC,MAAM,EAAE,eAAe,CAAC;IACxB,OAAO,EAAE,CAAC,CAAC;IACX,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,IAAI,CAAC;IACnB,YAAY,CAAC,EAAE,eAAe,EAAE,CAAC;CACjC,CAAC;AAEF;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;AAE3E;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,MAAM,oBAAoB,GAAG;IAClC,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACzB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,KAAK,CAAC,EAAE,IAAI,CAAC;IACb,MAAM,CAAC,EAAE,IAAI,CAAC;IACd,aAAa,CAAC,EAAE,IAAI,CAAC;IACrB,cAAc,CAAC,EAAE,IAAI,CAAC;IACtB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;;;OAMG;IACH,gBAAgB,CAAC,EAAE,eAAe,CAAC;CACnC,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,uBAAuB,CAAC,CAAC,IAAI,CAAC,SAAS,kBAAkB,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;AAE3F;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,wBAAgB,uBAAuB,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,kBAAkB,CAAC,CAAC,CAAC,CAElG"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../observations/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC;AAEnC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,MAAM,MAAM,eAAe,GAAG;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE;QACN,KAAK,EAAE,MAAM,CAAC;QACd,GAAG,EAAE,MAAM,CAAC;KACZ,CAAC;CACF,CAAC;AAEF;;;;;;;;GAQG;AACH,MAAM,MAAM,kBAAkB,CAAC,CAAC,IAAI;IACnC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;CAC5B,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,MAAM,MAAM,WAAW,CAAC,CAAC,GAAG,OAAO,IAAI;IACtC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,eAAe,CAAC;IACxB,OAAO,EAAE,CAAC,CAAC;IACX,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,IAAI,CAAC;IACnB,UAAU,EAAE,IAAI,CAAC;IACjB,YAAY,CAAC,EAAE,eAAe,EAAE,CAAC;CACjC,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,MAAM,eAAe,GAAG,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE,SAAS,CAAC,CAAC;AAElE;;;;;GAKG;AACH,MAAM,MAAM,kBAAkB,CAAC,CAAC,IAAI;IACnC,MAAM,EAAE,eAAe,CAAC;IACxB,OAAO,EAAE,CAAC,CAAC;IACX,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,IAAI,CAAC;IACnB,YAAY,CAAC,EAAE,eAAe,EAAE,CAAC;CACjC,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,MAAM,aAAa,GAAG,GAAG,CAAC,MAAM,CAAC,GAAG,MAAM,EAAE,GAAG,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC;AAEzH;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,MAAM,oBAAoB,GAAG;IAClC,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACzB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,KAAK,CAAC,EAAE,IAAI,CAAC;IACb,MAAM,CAAC,EAAE,IAAI,CAAC;IACd,aAAa,CAAC,EAAE,IAAI,CAAC;IACrB,cAAc,CAAC,EAAE,IAAI,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;;;OAMG;IACH,cAAc,CAAC,EAAE,aAAa,CAAC;CAC/B,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,uBAAuB,CAAC,CAAC,IAAI,CAAC,SAAS,kBAAkB,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;AAE3F;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,wBAAgB,uBAAuB,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,kBAAkB,CAAC,CAAC,CAAC,CAElG"}