@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.
- package/dist/backend/base.d.ts +23 -0
- package/dist/backend/base.d.ts.map +1 -0
- package/dist/backend/base.js +100 -0
- package/dist/backend/file.d.ts.map +1 -1
- package/dist/backend/file.js +38 -76
- package/dist/backend/memory.d.ts.map +1 -1
- package/dist/backend/memory.js +18 -69
- package/dist/backends.d.ts +1 -0
- package/dist/backends.d.ts.map +1 -1
- package/dist/backends.js +1 -0
- package/dist/cloudflare.d.ts +1 -0
- package/dist/cloudflare.d.ts.map +1 -1
- package/dist/cloudflare.js +1 -0
- package/dist/concurrency.d.ts +78 -0
- package/dist/concurrency.d.ts.map +1 -0
- package/dist/concurrency.js +108 -0
- package/dist/index.d.ts +13 -11
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +12 -10
- package/dist/observations/client.d.ts.map +1 -1
- package/dist/observations/client.js +13 -24
- package/dist/observations/index.d.ts +1 -1
- package/dist/observations/index.d.ts.map +1 -1
- package/dist/observations/storage.d.ts +33 -4
- package/dist/observations/storage.d.ts.map +1 -1
- package/dist/observations/storage.js +63 -43
- package/dist/observations/types.d.ts +21 -15
- package/dist/observations/types.d.ts.map +1 -1
- package/dist/result.d.ts +280 -0
- package/dist/result.d.ts.map +1 -0
- package/dist/result.js +319 -0
- package/dist/types.d.ts +33 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/utils.d.ts +39 -6
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +47 -15
- package/package.json +1 -1
|
@@ -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
|
|
2
|
-
export { create_memory_backend, type MemoryBackendOptions } from
|
|
3
|
-
export { create_file_backend, type FileBackendConfig } from
|
|
4
|
-
export { create_cloudflare_backend, type CloudflareBackendConfig } from
|
|
5
|
-
export { create_layered_backend, type LayeredBackendOptions } from
|
|
6
|
-
export { json_codec, text_codec, binary_codec, compute_hash, generate_version } from
|
|
7
|
-
export { corpus_snapshots, type CorpusSnapshotRow, type CorpusSnapshotInsert } from
|
|
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
|
|
9
|
-
export { ok, err, define_store } from
|
|
10
|
-
export
|
|
11
|
-
export {
|
|
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
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,UAAU,
|
|
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
|
|
2
|
-
export { create_memory_backend } from
|
|
3
|
-
export { create_file_backend } from
|
|
4
|
-
export { create_cloudflare_backend } from
|
|
5
|
-
export { create_layered_backend } from
|
|
6
|
-
export { json_codec, text_codec, binary_codec, compute_hash, generate_version } from
|
|
7
|
-
export { corpus_snapshots } from
|
|
8
|
-
export { ok, err, define_store } from
|
|
9
|
-
export
|
|
10
|
-
export {
|
|
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;
|
|
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 (
|
|
87
|
-
|
|
88
|
-
if (
|
|
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 (
|
|
103
|
-
|
|
104
|
-
if (
|
|
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;
|
|
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
|
-
*
|
|
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
|
|
72
|
-
*
|
|
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(
|
|
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":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA;
|
|
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
|
-
|
|
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
|
|
105
|
-
*
|
|
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(
|
|
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
|
|
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
|
|
127
|
+
const row = await adapter.get_one(id);
|
|
115
128
|
return ok(row);
|
|
116
129
|
},
|
|
117
130
|
async *query_rows(opts = {}) {
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
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
|
-
|
|
125
|
-
return ok(deleted);
|
|
142
|
+
return wrap_remove_one(id);
|
|
126
143
|
},
|
|
127
144
|
async delete_by_source(store_id, version, path) {
|
|
128
|
-
|
|
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
|
|
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
|
-
*
|
|
124
|
-
*
|
|
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
|
-
*
|
|
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.
|
|
141
|
+
* where: eq(published_reports.version, version)
|
|
134
142
|
* });
|
|
135
|
-
* return published
|
|
143
|
+
* return published !== null;
|
|
136
144
|
* };
|
|
137
145
|
* ```
|
|
138
146
|
*/
|
|
139
|
-
export type
|
|
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
|
-
* //
|
|
164
|
+
* // Filter to only published versions
|
|
157
165
|
* const versionOpts: ObservationQueryOpts = {
|
|
158
166
|
* source_store: 'hansard',
|
|
159
|
-
*
|
|
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
|
-
*
|
|
178
|
-
* When provided
|
|
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
|
-
*
|
|
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
|
-
|
|
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
|
|
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"}
|