@medicine-wheel/storage-provider 0.6.0 → 0.6.2
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/interface.d.ts +10 -0
- package/dist/jsonl.d.ts +2 -0
- package/dist/jsonl.js +34 -0
- package/dist/neon.d.ts +2 -0
- package/dist/neon.js +8 -0
- package/package.json +2 -2
package/dist/interface.d.ts
CHANGED
|
@@ -291,6 +291,14 @@ export interface StorageProvider {
|
|
|
291
291
|
getNodesByType(type: NodeType): Promise<RelationalNode[]>;
|
|
292
292
|
getNodesByDirection(direction: DirectionName): Promise<RelationalNode[]>;
|
|
293
293
|
getAllNodes(limit?: number): Promise<RelationalNode[]>;
|
|
294
|
+
/**
|
|
295
|
+
* Cardinality of the whole node collection, never a page of it.
|
|
296
|
+
* `getAllNodes()` answers with a page (default 100), so its length is
|
|
297
|
+
* `min(actual, limit)` and cannot be used as a total. Implementations answer
|
|
298
|
+
* this without materialising the collection — a line count on jsonl, a
|
|
299
|
+
* `COUNT(*)` on Postgres.
|
|
300
|
+
*/
|
|
301
|
+
countNodes(): Promise<number>;
|
|
294
302
|
/** Throws NodeNotFoundError when the node does not exist. */
|
|
295
303
|
updateNode(id: string, patch: NodePatch): Promise<RelationalNode>;
|
|
296
304
|
/** Throws NodeNotFoundError or NodeHasRelationsError (refusal, never cascade). */
|
|
@@ -310,6 +318,8 @@ export interface StorageProvider {
|
|
|
310
318
|
getCeremoniesByDirection(direction: DirectionName): Promise<CeremonyLog[]>;
|
|
311
319
|
getCeremoniesByType(type: CeremonyType): Promise<CeremonyLog[]>;
|
|
312
320
|
getAllCeremonies(limit?: number): Promise<CeremonyLog[]>;
|
|
321
|
+
/** Cardinality of the whole ceremony collection — see `countNodes()`. */
|
|
322
|
+
countCeremonies(): Promise<number>;
|
|
313
323
|
registerInquiryWeave(record: WeaveRecord): Promise<void>;
|
|
314
324
|
getInquiryWeave(id: string): Promise<WeaveRecord | null>;
|
|
315
325
|
listInquiryWeaves(filters?: InquiryWeaveFilters): Promise<WeaveRecord[]>;
|
package/dist/jsonl.d.ts
CHANGED
|
@@ -19,6 +19,7 @@ export declare class JsonlProvider implements StorageProvider {
|
|
|
19
19
|
getNodesByType(type: NodeType): Promise<RelationalNode[]>;
|
|
20
20
|
getNodesByDirection(direction: DirectionName): Promise<RelationalNode[]>;
|
|
21
21
|
getAllNodes(limit?: number): Promise<RelationalNode[]>;
|
|
22
|
+
countNodes(): Promise<number>;
|
|
22
23
|
updateNode(id: string, patch: NodePatch): Promise<RelationalNode>;
|
|
23
24
|
deleteNode(id: string): Promise<void>;
|
|
24
25
|
createEdge(edge: RelationalEdge): Promise<void>;
|
|
@@ -34,6 +35,7 @@ export declare class JsonlProvider implements StorageProvider {
|
|
|
34
35
|
getCeremoniesByDirection(direction: DirectionName): Promise<CeremonyLog[]>;
|
|
35
36
|
getCeremoniesByType(type: CeremonyType): Promise<CeremonyLog[]>;
|
|
36
37
|
getAllCeremonies(limit?: number): Promise<CeremonyLog[]>;
|
|
38
|
+
countCeremonies(): Promise<number>;
|
|
37
39
|
registerInquiryWeave(record: WeaveRecord): Promise<void>;
|
|
38
40
|
getInquiryWeave(id: string): Promise<WeaveRecord | null>;
|
|
39
41
|
listInquiryWeaves(filters?: InquiryWeaveFilters): Promise<WeaveRecord[]>;
|
package/dist/jsonl.js
CHANGED
|
@@ -60,6 +60,9 @@ export class JsonlProvider {
|
|
|
60
60
|
.slice(0, limit)
|
|
61
61
|
.map((node) => this.parseNode(node));
|
|
62
62
|
}
|
|
63
|
+
async countNodes() {
|
|
64
|
+
return countJsonl(this.nodesFile);
|
|
65
|
+
}
|
|
63
66
|
async updateNode(id, patch) {
|
|
64
67
|
return withWriteLock(this.nodesFile, () => {
|
|
65
68
|
const nodes = this.readNodes();
|
|
@@ -202,6 +205,9 @@ export class JsonlProvider {
|
|
|
202
205
|
.slice(0, limit)
|
|
203
206
|
.map((ceremony) => this.parseCeremony(ceremony));
|
|
204
207
|
}
|
|
208
|
+
async countCeremonies() {
|
|
209
|
+
return countJsonl(this.ceremoniesFile);
|
|
210
|
+
}
|
|
205
211
|
async registerInquiryWeave(record) {
|
|
206
212
|
await this.upsertById(this.inquiryWeavesFile, record);
|
|
207
213
|
}
|
|
@@ -375,6 +381,34 @@ function readJsonl(filePath) {
|
|
|
375
381
|
}
|
|
376
382
|
return records;
|
|
377
383
|
}
|
|
384
|
+
/**
|
|
385
|
+
* How many records the file holds, without building them.
|
|
386
|
+
*
|
|
387
|
+
* Counts exactly what `readJsonl` would have returned — a malformed line is
|
|
388
|
+
* skipped by both, so a count can never disagree with a read — but retains no
|
|
389
|
+
* objects, sorts nothing, and parses no record into its domain shape. Skipping
|
|
390
|
+
* is silent here: `readJsonl` already warns about the same line, and counting
|
|
391
|
+
* must not double the noise.
|
|
392
|
+
*/
|
|
393
|
+
function countJsonl(filePath) {
|
|
394
|
+
if (!fs.existsSync(filePath))
|
|
395
|
+
return 0;
|
|
396
|
+
let count = 0;
|
|
397
|
+
const content = fs.readFileSync(filePath, 'utf-8');
|
|
398
|
+
for (const line of content.split('\n')) {
|
|
399
|
+
const trimmed = line.trim();
|
|
400
|
+
if (!trimmed)
|
|
401
|
+
continue;
|
|
402
|
+
try {
|
|
403
|
+
JSON.parse(trimmed);
|
|
404
|
+
count += 1;
|
|
405
|
+
}
|
|
406
|
+
catch {
|
|
407
|
+
// Same skip readJsonl performs; it owns the warning.
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
return count;
|
|
411
|
+
}
|
|
378
412
|
function writeJsonl(filePath, records) {
|
|
379
413
|
ensureDirectory(path.dirname(filePath));
|
|
380
414
|
const tmpPath = `${filePath}.tmp.${process.pid}`;
|
package/dist/neon.d.ts
CHANGED
|
@@ -14,6 +14,7 @@ export declare class NeonProvider implements StorageProvider {
|
|
|
14
14
|
getNodesByType(type: NodeType): Promise<RelationalNode[]>;
|
|
15
15
|
getNodesByDirection(direction: DirectionName): Promise<RelationalNode[]>;
|
|
16
16
|
getAllNodes(limit?: number): Promise<RelationalNode[]>;
|
|
17
|
+
countNodes(): Promise<number>;
|
|
17
18
|
updateNode(id: string, patch: NodePatch): Promise<RelationalNode>;
|
|
18
19
|
deleteNode(id: string): Promise<void>;
|
|
19
20
|
private parseNode;
|
|
@@ -31,6 +32,7 @@ export declare class NeonProvider implements StorageProvider {
|
|
|
31
32
|
getCeremoniesByDirection(direction: DirectionName): Promise<CeremonyLog[]>;
|
|
32
33
|
getCeremoniesByType(type: CeremonyType): Promise<CeremonyLog[]>;
|
|
33
34
|
getAllCeremonies(limit?: number): Promise<CeremonyLog[]>;
|
|
35
|
+
countCeremonies(): Promise<number>;
|
|
34
36
|
private parseCeremony;
|
|
35
37
|
registerInquiryWeave(record: WeaveRecord): Promise<void>;
|
|
36
38
|
getInquiryWeave(id: string): Promise<WeaveRecord | null>;
|
package/dist/neon.js
CHANGED
|
@@ -64,6 +64,10 @@ export class NeonProvider {
|
|
|
64
64
|
const rows = await this.db `SELECT * FROM nodes ORDER BY created_at DESC LIMIT ${limit}`;
|
|
65
65
|
return rows.map((row) => this.parseNode(row));
|
|
66
66
|
}
|
|
67
|
+
async countNodes() {
|
|
68
|
+
const counts = await this.db `SELECT COUNT(*)::int AS count FROM nodes`;
|
|
69
|
+
return Number(counts[0]?.count ?? 0);
|
|
70
|
+
}
|
|
67
71
|
async updateNode(id, patch) {
|
|
68
72
|
const existing = await this.getNode(id);
|
|
69
73
|
if (!existing)
|
|
@@ -245,6 +249,10 @@ export class NeonProvider {
|
|
|
245
249
|
async getAllCeremonies(limit = 100) {
|
|
246
250
|
return this.getCeremoniesTimeline(limit);
|
|
247
251
|
}
|
|
252
|
+
async countCeremonies() {
|
|
253
|
+
const counts = await this.db `SELECT COUNT(*)::int AS count FROM ceremonies`;
|
|
254
|
+
return Number(counts[0]?.count ?? 0);
|
|
255
|
+
}
|
|
248
256
|
parseCeremony(row) {
|
|
249
257
|
return {
|
|
250
258
|
id: row.id,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@medicine-wheel/storage-provider",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"dependencies": {
|
|
17
17
|
"@neondatabase/serverless": "^0.10.0",
|
|
18
18
|
"@upstash/redis": "^1.34.3",
|
|
19
|
-
"@medicine-wheel/ontology-core": "^0.6.
|
|
19
|
+
"@medicine-wheel/ontology-core": "^0.6.2"
|
|
20
20
|
},
|
|
21
21
|
"devDependencies": {
|
|
22
22
|
"typescript": "^5.7.0"
|