@yesod/observer 0.0.1
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/index.cjs +128 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +46 -0
- package/dist/index.d.ts +46 -0
- package/dist/index.js +88 -0
- package/dist/index.js.map +1 -0
- package/package.json +39 -0
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/index.ts
|
|
31
|
+
var index_exports = {};
|
|
32
|
+
__export(index_exports, {
|
|
33
|
+
CostAggregator: () => CostAggregator,
|
|
34
|
+
EventLogger: () => EventLogger,
|
|
35
|
+
ReplayEngine: () => ReplayEngine,
|
|
36
|
+
SQLiteStorageAdapter: () => SQLiteStorageAdapter
|
|
37
|
+
});
|
|
38
|
+
module.exports = __toCommonJS(index_exports);
|
|
39
|
+
|
|
40
|
+
// src/logger.ts
|
|
41
|
+
var EventLogger = class {
|
|
42
|
+
constructor(storage) {
|
|
43
|
+
this.storage = storage;
|
|
44
|
+
}
|
|
45
|
+
storage;
|
|
46
|
+
async log(event) {
|
|
47
|
+
await this.storage.put(`event:${event.id}`, event);
|
|
48
|
+
}
|
|
49
|
+
async getEvent(eventId) {
|
|
50
|
+
return await this.storage.get(`event:${eventId}`);
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
// src/cost.ts
|
|
55
|
+
var CostAggregator = class {
|
|
56
|
+
entries = [];
|
|
57
|
+
record(entry) {
|
|
58
|
+
this.entries.push(entry);
|
|
59
|
+
}
|
|
60
|
+
getSessionCost(sessionId) {
|
|
61
|
+
return this.entries.filter((e) => e.sessionId === sessionId).reduce((sum, e) => sum + e.cost, 0);
|
|
62
|
+
}
|
|
63
|
+
getOrchestrationCost(orchestrationId) {
|
|
64
|
+
return this.entries.filter((e) => e.orchestrationId === orchestrationId).reduce((sum, e) => sum + e.cost, 0);
|
|
65
|
+
}
|
|
66
|
+
getTotalTokens(sessionId) {
|
|
67
|
+
const sessionEntries = this.entries.filter(
|
|
68
|
+
(e) => e.sessionId === sessionId
|
|
69
|
+
);
|
|
70
|
+
return {
|
|
71
|
+
input: sessionEntries.reduce((sum, e) => sum + e.inputTokens, 0),
|
|
72
|
+
output: sessionEntries.reduce((sum, e) => sum + e.outputTokens, 0)
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
// src/replay.ts
|
|
78
|
+
var ReplayEngine = class {
|
|
79
|
+
constructor(storage) {
|
|
80
|
+
this.storage = storage;
|
|
81
|
+
}
|
|
82
|
+
storage;
|
|
83
|
+
/** Replay events for a given orchestration from stored events */
|
|
84
|
+
async replay(_orchestrationId, _onEvent) {
|
|
85
|
+
return [];
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
// src/sqlite-adapter.ts
|
|
90
|
+
var import_better_sqlite3 = __toESM(require("better-sqlite3"), 1);
|
|
91
|
+
var SQLiteStorageAdapter = class {
|
|
92
|
+
db;
|
|
93
|
+
constructor(dbPath) {
|
|
94
|
+
this.db = new import_better_sqlite3.default(dbPath);
|
|
95
|
+
this.db.exec(`
|
|
96
|
+
CREATE TABLE IF NOT EXISTS kv (
|
|
97
|
+
key TEXT PRIMARY KEY,
|
|
98
|
+
value TEXT NOT NULL
|
|
99
|
+
)
|
|
100
|
+
`);
|
|
101
|
+
}
|
|
102
|
+
async get(key) {
|
|
103
|
+
const row = this.db.prepare("SELECT value FROM kv WHERE key = ?").get(key);
|
|
104
|
+
return row ? JSON.parse(row.value) : void 0;
|
|
105
|
+
}
|
|
106
|
+
async put(key, value) {
|
|
107
|
+
this.db.prepare("INSERT OR REPLACE INTO kv (key, value) VALUES (?, ?)").run(key, JSON.stringify(value));
|
|
108
|
+
}
|
|
109
|
+
async query(_query) {
|
|
110
|
+
const rows = this.db.prepare("SELECT value FROM kv").all();
|
|
111
|
+
return rows.map((r) => JSON.parse(r.value));
|
|
112
|
+
}
|
|
113
|
+
async delete(key) {
|
|
114
|
+
const result = this.db.prepare("DELETE FROM kv WHERE key = ?").run(key);
|
|
115
|
+
return result.changes > 0;
|
|
116
|
+
}
|
|
117
|
+
close() {
|
|
118
|
+
this.db.close();
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
122
|
+
0 && (module.exports = {
|
|
123
|
+
CostAggregator,
|
|
124
|
+
EventLogger,
|
|
125
|
+
ReplayEngine,
|
|
126
|
+
SQLiteStorageAdapter
|
|
127
|
+
});
|
|
128
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/logger.ts","../src/cost.ts","../src/replay.ts","../src/sqlite-adapter.ts"],"sourcesContent":["export { EventLogger } from \"./logger.js\";\nexport { CostAggregator } from \"./cost.js\";\nexport type { CostEntry } from \"./cost.js\";\nexport { ReplayEngine } from \"./replay.js\";\nexport { SQLiteStorageAdapter } from \"./sqlite-adapter.js\";\n","import type { YesodEvent } from \"@yesod/core\";\nimport type { StorageAdapter } from \"@yesod/core\";\n\nexport class EventLogger {\n constructor(private storage: StorageAdapter) {}\n\n async log(event: YesodEvent): Promise<void> {\n await this.storage.put(`event:${event.id}`, event);\n }\n\n async getEvent(eventId: string): Promise<YesodEvent | undefined> {\n return (await this.storage.get(`event:${eventId}`)) as\n | YesodEvent\n | undefined;\n }\n}\n","export interface CostEntry {\n sessionId: string;\n orchestrationId: string;\n inputTokens: number;\n outputTokens: number;\n cost: number;\n timestamp: string;\n}\n\nexport class CostAggregator {\n private entries: CostEntry[] = [];\n\n record(entry: CostEntry): void {\n this.entries.push(entry);\n }\n\n getSessionCost(sessionId: string): number {\n return this.entries\n .filter((e) => e.sessionId === sessionId)\n .reduce((sum, e) => sum + e.cost, 0);\n }\n\n getOrchestrationCost(orchestrationId: string): number {\n return this.entries\n .filter((e) => e.orchestrationId === orchestrationId)\n .reduce((sum, e) => sum + e.cost, 0);\n }\n\n getTotalTokens(sessionId: string): {\n input: number;\n output: number;\n } {\n const sessionEntries = this.entries.filter(\n (e) => e.sessionId === sessionId,\n );\n return {\n input: sessionEntries.reduce((sum, e) => sum + e.inputTokens, 0),\n output: sessionEntries.reduce((sum, e) => sum + e.outputTokens, 0),\n };\n }\n}\n","import type { YesodEvent, StorageAdapter } from \"@yesod/core\";\n\nexport class ReplayEngine {\n constructor(private storage: StorageAdapter) {}\n\n /** Replay events for a given orchestration from stored events */\n async replay(\n _orchestrationId: string,\n _onEvent?: (event: YesodEvent) => void,\n ): Promise<YesodEvent[]> {\n // Stub — will query storage for events and replay them in order\n return [];\n }\n}\n","import type { StorageAdapter, StorageQuery } from \"@yesod/core\";\nimport Database from \"better-sqlite3\";\n\nexport class SQLiteStorageAdapter implements StorageAdapter {\n private db: Database.Database;\n\n constructor(dbPath: string) {\n this.db = new Database(dbPath);\n this.db.exec(`\n CREATE TABLE IF NOT EXISTS kv (\n key TEXT PRIMARY KEY,\n value TEXT NOT NULL\n )\n `);\n }\n\n async get(key: string): Promise<unknown | undefined> {\n const row = this.db\n .prepare(\"SELECT value FROM kv WHERE key = ?\")\n .get(key) as { value: string } | undefined;\n return row ? JSON.parse(row.value) : undefined;\n }\n\n async put(key: string, value: unknown): Promise<void> {\n this.db\n .prepare(\"INSERT OR REPLACE INTO kv (key, value) VALUES (?, ?)\")\n .run(key, JSON.stringify(value));\n }\n\n async query(_query: StorageQuery): Promise<unknown[]> {\n // Stub — will implement filtered queries over stored events\n const rows = this.db.prepare(\"SELECT value FROM kv\").all() as {\n value: string;\n }[];\n return rows.map((r) => JSON.parse(r.value));\n }\n\n async delete(key: string): Promise<boolean> {\n const result = this.db.prepare(\"DELETE FROM kv WHERE key = ?\").run(key);\n return result.changes > 0;\n }\n\n close(): void {\n this.db.close();\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACGO,IAAM,cAAN,MAAkB;AAAA,EACvB,YAAoB,SAAyB;AAAzB;AAAA,EAA0B;AAAA,EAA1B;AAAA,EAEpB,MAAM,IAAI,OAAkC;AAC1C,UAAM,KAAK,QAAQ,IAAI,SAAS,MAAM,EAAE,IAAI,KAAK;AAAA,EACnD;AAAA,EAEA,MAAM,SAAS,SAAkD;AAC/D,WAAQ,MAAM,KAAK,QAAQ,IAAI,SAAS,OAAO,EAAE;AAAA,EAGnD;AACF;;;ACNO,IAAM,iBAAN,MAAqB;AAAA,EAClB,UAAuB,CAAC;AAAA,EAEhC,OAAO,OAAwB;AAC7B,SAAK,QAAQ,KAAK,KAAK;AAAA,EACzB;AAAA,EAEA,eAAe,WAA2B;AACxC,WAAO,KAAK,QACT,OAAO,CAAC,MAAM,EAAE,cAAc,SAAS,EACvC,OAAO,CAAC,KAAK,MAAM,MAAM,EAAE,MAAM,CAAC;AAAA,EACvC;AAAA,EAEA,qBAAqB,iBAAiC;AACpD,WAAO,KAAK,QACT,OAAO,CAAC,MAAM,EAAE,oBAAoB,eAAe,EACnD,OAAO,CAAC,KAAK,MAAM,MAAM,EAAE,MAAM,CAAC;AAAA,EACvC;AAAA,EAEA,eAAe,WAGb;AACA,UAAM,iBAAiB,KAAK,QAAQ;AAAA,MAClC,CAAC,MAAM,EAAE,cAAc;AAAA,IACzB;AACA,WAAO;AAAA,MACL,OAAO,eAAe,OAAO,CAAC,KAAK,MAAM,MAAM,EAAE,aAAa,CAAC;AAAA,MAC/D,QAAQ,eAAe,OAAO,CAAC,KAAK,MAAM,MAAM,EAAE,cAAc,CAAC;AAAA,IACnE;AAAA,EACF;AACF;;;ACtCO,IAAM,eAAN,MAAmB;AAAA,EACxB,YAAoB,SAAyB;AAAzB;AAAA,EAA0B;AAAA,EAA1B;AAAA;AAAA,EAGpB,MAAM,OACJ,kBACA,UACuB;AAEvB,WAAO,CAAC;AAAA,EACV;AACF;;;ACZA,4BAAqB;AAEd,IAAM,uBAAN,MAAqD;AAAA,EAClD;AAAA,EAER,YAAY,QAAgB;AAC1B,SAAK,KAAK,IAAI,sBAAAA,QAAS,MAAM;AAC7B,SAAK,GAAG,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA,KAKZ;AAAA,EACH;AAAA,EAEA,MAAM,IAAI,KAA2C;AACnD,UAAM,MAAM,KAAK,GACd,QAAQ,oCAAoC,EAC5C,IAAI,GAAG;AACV,WAAO,MAAM,KAAK,MAAM,IAAI,KAAK,IAAI;AAAA,EACvC;AAAA,EAEA,MAAM,IAAI,KAAa,OAA+B;AACpD,SAAK,GACF,QAAQ,sDAAsD,EAC9D,IAAI,KAAK,KAAK,UAAU,KAAK,CAAC;AAAA,EACnC;AAAA,EAEA,MAAM,MAAM,QAA0C;AAEpD,UAAM,OAAO,KAAK,GAAG,QAAQ,sBAAsB,EAAE,IAAI;AAGzD,WAAO,KAAK,IAAI,CAAC,MAAM,KAAK,MAAM,EAAE,KAAK,CAAC;AAAA,EAC5C;AAAA,EAEA,MAAM,OAAO,KAA+B;AAC1C,UAAM,SAAS,KAAK,GAAG,QAAQ,8BAA8B,EAAE,IAAI,GAAG;AACtE,WAAO,OAAO,UAAU;AAAA,EAC1B;AAAA,EAEA,QAAc;AACZ,SAAK,GAAG,MAAM;AAAA,EAChB;AACF;","names":["Database"]}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { StorageAdapter, YesodEvent, StorageQuery } from '@yesod/core';
|
|
2
|
+
|
|
3
|
+
declare class EventLogger {
|
|
4
|
+
private storage;
|
|
5
|
+
constructor(storage: StorageAdapter);
|
|
6
|
+
log(event: YesodEvent): Promise<void>;
|
|
7
|
+
getEvent(eventId: string): Promise<YesodEvent | undefined>;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
interface CostEntry {
|
|
11
|
+
sessionId: string;
|
|
12
|
+
orchestrationId: string;
|
|
13
|
+
inputTokens: number;
|
|
14
|
+
outputTokens: number;
|
|
15
|
+
cost: number;
|
|
16
|
+
timestamp: string;
|
|
17
|
+
}
|
|
18
|
+
declare class CostAggregator {
|
|
19
|
+
private entries;
|
|
20
|
+
record(entry: CostEntry): void;
|
|
21
|
+
getSessionCost(sessionId: string): number;
|
|
22
|
+
getOrchestrationCost(orchestrationId: string): number;
|
|
23
|
+
getTotalTokens(sessionId: string): {
|
|
24
|
+
input: number;
|
|
25
|
+
output: number;
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
declare class ReplayEngine {
|
|
30
|
+
private storage;
|
|
31
|
+
constructor(storage: StorageAdapter);
|
|
32
|
+
/** Replay events for a given orchestration from stored events */
|
|
33
|
+
replay(_orchestrationId: string, _onEvent?: (event: YesodEvent) => void): Promise<YesodEvent[]>;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
declare class SQLiteStorageAdapter implements StorageAdapter {
|
|
37
|
+
private db;
|
|
38
|
+
constructor(dbPath: string);
|
|
39
|
+
get(key: string): Promise<unknown | undefined>;
|
|
40
|
+
put(key: string, value: unknown): Promise<void>;
|
|
41
|
+
query(_query: StorageQuery): Promise<unknown[]>;
|
|
42
|
+
delete(key: string): Promise<boolean>;
|
|
43
|
+
close(): void;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export { CostAggregator, type CostEntry, EventLogger, ReplayEngine, SQLiteStorageAdapter };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { StorageAdapter, YesodEvent, StorageQuery } from '@yesod/core';
|
|
2
|
+
|
|
3
|
+
declare class EventLogger {
|
|
4
|
+
private storage;
|
|
5
|
+
constructor(storage: StorageAdapter);
|
|
6
|
+
log(event: YesodEvent): Promise<void>;
|
|
7
|
+
getEvent(eventId: string): Promise<YesodEvent | undefined>;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
interface CostEntry {
|
|
11
|
+
sessionId: string;
|
|
12
|
+
orchestrationId: string;
|
|
13
|
+
inputTokens: number;
|
|
14
|
+
outputTokens: number;
|
|
15
|
+
cost: number;
|
|
16
|
+
timestamp: string;
|
|
17
|
+
}
|
|
18
|
+
declare class CostAggregator {
|
|
19
|
+
private entries;
|
|
20
|
+
record(entry: CostEntry): void;
|
|
21
|
+
getSessionCost(sessionId: string): number;
|
|
22
|
+
getOrchestrationCost(orchestrationId: string): number;
|
|
23
|
+
getTotalTokens(sessionId: string): {
|
|
24
|
+
input: number;
|
|
25
|
+
output: number;
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
declare class ReplayEngine {
|
|
30
|
+
private storage;
|
|
31
|
+
constructor(storage: StorageAdapter);
|
|
32
|
+
/** Replay events for a given orchestration from stored events */
|
|
33
|
+
replay(_orchestrationId: string, _onEvent?: (event: YesodEvent) => void): Promise<YesodEvent[]>;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
declare class SQLiteStorageAdapter implements StorageAdapter {
|
|
37
|
+
private db;
|
|
38
|
+
constructor(dbPath: string);
|
|
39
|
+
get(key: string): Promise<unknown | undefined>;
|
|
40
|
+
put(key: string, value: unknown): Promise<void>;
|
|
41
|
+
query(_query: StorageQuery): Promise<unknown[]>;
|
|
42
|
+
delete(key: string): Promise<boolean>;
|
|
43
|
+
close(): void;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export { CostAggregator, type CostEntry, EventLogger, ReplayEngine, SQLiteStorageAdapter };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
// src/logger.ts
|
|
2
|
+
var EventLogger = class {
|
|
3
|
+
constructor(storage) {
|
|
4
|
+
this.storage = storage;
|
|
5
|
+
}
|
|
6
|
+
storage;
|
|
7
|
+
async log(event) {
|
|
8
|
+
await this.storage.put(`event:${event.id}`, event);
|
|
9
|
+
}
|
|
10
|
+
async getEvent(eventId) {
|
|
11
|
+
return await this.storage.get(`event:${eventId}`);
|
|
12
|
+
}
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
// src/cost.ts
|
|
16
|
+
var CostAggregator = class {
|
|
17
|
+
entries = [];
|
|
18
|
+
record(entry) {
|
|
19
|
+
this.entries.push(entry);
|
|
20
|
+
}
|
|
21
|
+
getSessionCost(sessionId) {
|
|
22
|
+
return this.entries.filter((e) => e.sessionId === sessionId).reduce((sum, e) => sum + e.cost, 0);
|
|
23
|
+
}
|
|
24
|
+
getOrchestrationCost(orchestrationId) {
|
|
25
|
+
return this.entries.filter((e) => e.orchestrationId === orchestrationId).reduce((sum, e) => sum + e.cost, 0);
|
|
26
|
+
}
|
|
27
|
+
getTotalTokens(sessionId) {
|
|
28
|
+
const sessionEntries = this.entries.filter(
|
|
29
|
+
(e) => e.sessionId === sessionId
|
|
30
|
+
);
|
|
31
|
+
return {
|
|
32
|
+
input: sessionEntries.reduce((sum, e) => sum + e.inputTokens, 0),
|
|
33
|
+
output: sessionEntries.reduce((sum, e) => sum + e.outputTokens, 0)
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
// src/replay.ts
|
|
39
|
+
var ReplayEngine = class {
|
|
40
|
+
constructor(storage) {
|
|
41
|
+
this.storage = storage;
|
|
42
|
+
}
|
|
43
|
+
storage;
|
|
44
|
+
/** Replay events for a given orchestration from stored events */
|
|
45
|
+
async replay(_orchestrationId, _onEvent) {
|
|
46
|
+
return [];
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
// src/sqlite-adapter.ts
|
|
51
|
+
import Database from "better-sqlite3";
|
|
52
|
+
var SQLiteStorageAdapter = class {
|
|
53
|
+
db;
|
|
54
|
+
constructor(dbPath) {
|
|
55
|
+
this.db = new Database(dbPath);
|
|
56
|
+
this.db.exec(`
|
|
57
|
+
CREATE TABLE IF NOT EXISTS kv (
|
|
58
|
+
key TEXT PRIMARY KEY,
|
|
59
|
+
value TEXT NOT NULL
|
|
60
|
+
)
|
|
61
|
+
`);
|
|
62
|
+
}
|
|
63
|
+
async get(key) {
|
|
64
|
+
const row = this.db.prepare("SELECT value FROM kv WHERE key = ?").get(key);
|
|
65
|
+
return row ? JSON.parse(row.value) : void 0;
|
|
66
|
+
}
|
|
67
|
+
async put(key, value) {
|
|
68
|
+
this.db.prepare("INSERT OR REPLACE INTO kv (key, value) VALUES (?, ?)").run(key, JSON.stringify(value));
|
|
69
|
+
}
|
|
70
|
+
async query(_query) {
|
|
71
|
+
const rows = this.db.prepare("SELECT value FROM kv").all();
|
|
72
|
+
return rows.map((r) => JSON.parse(r.value));
|
|
73
|
+
}
|
|
74
|
+
async delete(key) {
|
|
75
|
+
const result = this.db.prepare("DELETE FROM kv WHERE key = ?").run(key);
|
|
76
|
+
return result.changes > 0;
|
|
77
|
+
}
|
|
78
|
+
close() {
|
|
79
|
+
this.db.close();
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
export {
|
|
83
|
+
CostAggregator,
|
|
84
|
+
EventLogger,
|
|
85
|
+
ReplayEngine,
|
|
86
|
+
SQLiteStorageAdapter
|
|
87
|
+
};
|
|
88
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/logger.ts","../src/cost.ts","../src/replay.ts","../src/sqlite-adapter.ts"],"sourcesContent":["import type { YesodEvent } from \"@yesod/core\";\nimport type { StorageAdapter } from \"@yesod/core\";\n\nexport class EventLogger {\n constructor(private storage: StorageAdapter) {}\n\n async log(event: YesodEvent): Promise<void> {\n await this.storage.put(`event:${event.id}`, event);\n }\n\n async getEvent(eventId: string): Promise<YesodEvent | undefined> {\n return (await this.storage.get(`event:${eventId}`)) as\n | YesodEvent\n | undefined;\n }\n}\n","export interface CostEntry {\n sessionId: string;\n orchestrationId: string;\n inputTokens: number;\n outputTokens: number;\n cost: number;\n timestamp: string;\n}\n\nexport class CostAggregator {\n private entries: CostEntry[] = [];\n\n record(entry: CostEntry): void {\n this.entries.push(entry);\n }\n\n getSessionCost(sessionId: string): number {\n return this.entries\n .filter((e) => e.sessionId === sessionId)\n .reduce((sum, e) => sum + e.cost, 0);\n }\n\n getOrchestrationCost(orchestrationId: string): number {\n return this.entries\n .filter((e) => e.orchestrationId === orchestrationId)\n .reduce((sum, e) => sum + e.cost, 0);\n }\n\n getTotalTokens(sessionId: string): {\n input: number;\n output: number;\n } {\n const sessionEntries = this.entries.filter(\n (e) => e.sessionId === sessionId,\n );\n return {\n input: sessionEntries.reduce((sum, e) => sum + e.inputTokens, 0),\n output: sessionEntries.reduce((sum, e) => sum + e.outputTokens, 0),\n };\n }\n}\n","import type { YesodEvent, StorageAdapter } from \"@yesod/core\";\n\nexport class ReplayEngine {\n constructor(private storage: StorageAdapter) {}\n\n /** Replay events for a given orchestration from stored events */\n async replay(\n _orchestrationId: string,\n _onEvent?: (event: YesodEvent) => void,\n ): Promise<YesodEvent[]> {\n // Stub — will query storage for events and replay them in order\n return [];\n }\n}\n","import type { StorageAdapter, StorageQuery } from \"@yesod/core\";\nimport Database from \"better-sqlite3\";\n\nexport class SQLiteStorageAdapter implements StorageAdapter {\n private db: Database.Database;\n\n constructor(dbPath: string) {\n this.db = new Database(dbPath);\n this.db.exec(`\n CREATE TABLE IF NOT EXISTS kv (\n key TEXT PRIMARY KEY,\n value TEXT NOT NULL\n )\n `);\n }\n\n async get(key: string): Promise<unknown | undefined> {\n const row = this.db\n .prepare(\"SELECT value FROM kv WHERE key = ?\")\n .get(key) as { value: string } | undefined;\n return row ? JSON.parse(row.value) : undefined;\n }\n\n async put(key: string, value: unknown): Promise<void> {\n this.db\n .prepare(\"INSERT OR REPLACE INTO kv (key, value) VALUES (?, ?)\")\n .run(key, JSON.stringify(value));\n }\n\n async query(_query: StorageQuery): Promise<unknown[]> {\n // Stub — will implement filtered queries over stored events\n const rows = this.db.prepare(\"SELECT value FROM kv\").all() as {\n value: string;\n }[];\n return rows.map((r) => JSON.parse(r.value));\n }\n\n async delete(key: string): Promise<boolean> {\n const result = this.db.prepare(\"DELETE FROM kv WHERE key = ?\").run(key);\n return result.changes > 0;\n }\n\n close(): void {\n this.db.close();\n }\n}\n"],"mappings":";AAGO,IAAM,cAAN,MAAkB;AAAA,EACvB,YAAoB,SAAyB;AAAzB;AAAA,EAA0B;AAAA,EAA1B;AAAA,EAEpB,MAAM,IAAI,OAAkC;AAC1C,UAAM,KAAK,QAAQ,IAAI,SAAS,MAAM,EAAE,IAAI,KAAK;AAAA,EACnD;AAAA,EAEA,MAAM,SAAS,SAAkD;AAC/D,WAAQ,MAAM,KAAK,QAAQ,IAAI,SAAS,OAAO,EAAE;AAAA,EAGnD;AACF;;;ACNO,IAAM,iBAAN,MAAqB;AAAA,EAClB,UAAuB,CAAC;AAAA,EAEhC,OAAO,OAAwB;AAC7B,SAAK,QAAQ,KAAK,KAAK;AAAA,EACzB;AAAA,EAEA,eAAe,WAA2B;AACxC,WAAO,KAAK,QACT,OAAO,CAAC,MAAM,EAAE,cAAc,SAAS,EACvC,OAAO,CAAC,KAAK,MAAM,MAAM,EAAE,MAAM,CAAC;AAAA,EACvC;AAAA,EAEA,qBAAqB,iBAAiC;AACpD,WAAO,KAAK,QACT,OAAO,CAAC,MAAM,EAAE,oBAAoB,eAAe,EACnD,OAAO,CAAC,KAAK,MAAM,MAAM,EAAE,MAAM,CAAC;AAAA,EACvC;AAAA,EAEA,eAAe,WAGb;AACA,UAAM,iBAAiB,KAAK,QAAQ;AAAA,MAClC,CAAC,MAAM,EAAE,cAAc;AAAA,IACzB;AACA,WAAO;AAAA,MACL,OAAO,eAAe,OAAO,CAAC,KAAK,MAAM,MAAM,EAAE,aAAa,CAAC;AAAA,MAC/D,QAAQ,eAAe,OAAO,CAAC,KAAK,MAAM,MAAM,EAAE,cAAc,CAAC;AAAA,IACnE;AAAA,EACF;AACF;;;ACtCO,IAAM,eAAN,MAAmB;AAAA,EACxB,YAAoB,SAAyB;AAAzB;AAAA,EAA0B;AAAA,EAA1B;AAAA;AAAA,EAGpB,MAAM,OACJ,kBACA,UACuB;AAEvB,WAAO,CAAC;AAAA,EACV;AACF;;;ACZA,OAAO,cAAc;AAEd,IAAM,uBAAN,MAAqD;AAAA,EAClD;AAAA,EAER,YAAY,QAAgB;AAC1B,SAAK,KAAK,IAAI,SAAS,MAAM;AAC7B,SAAK,GAAG,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA,KAKZ;AAAA,EACH;AAAA,EAEA,MAAM,IAAI,KAA2C;AACnD,UAAM,MAAM,KAAK,GACd,QAAQ,oCAAoC,EAC5C,IAAI,GAAG;AACV,WAAO,MAAM,KAAK,MAAM,IAAI,KAAK,IAAI;AAAA,EACvC;AAAA,EAEA,MAAM,IAAI,KAAa,OAA+B;AACpD,SAAK,GACF,QAAQ,sDAAsD,EAC9D,IAAI,KAAK,KAAK,UAAU,KAAK,CAAC;AAAA,EACnC;AAAA,EAEA,MAAM,MAAM,QAA0C;AAEpD,UAAM,OAAO,KAAK,GAAG,QAAQ,sBAAsB,EAAE,IAAI;AAGzD,WAAO,KAAK,IAAI,CAAC,MAAM,KAAK,MAAM,EAAE,KAAK,CAAC;AAAA,EAC5C;AAAA,EAEA,MAAM,OAAO,KAA+B;AAC1C,UAAM,SAAS,KAAK,GAAG,QAAQ,8BAA8B,EAAE,IAAI,GAAG;AACtE,WAAO,OAAO,UAAU;AAAA,EAC1B;AAAA,EAEA,QAAc;AACZ,SAAK,GAAG,MAAM;AAAA,EAChB;AACF;","names":[]}
|
package/package.json
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@yesod/observer",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"repository": {
|
|
5
|
+
"type": "git",
|
|
6
|
+
"url": "https://github.com/eryv-ai/yesod.git",
|
|
7
|
+
"directory": "packages/observer"
|
|
8
|
+
},
|
|
9
|
+
"type": "module",
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"import": "./dist/index.js",
|
|
13
|
+
"require": "./dist/index.cjs"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"main": "./dist/index.cjs",
|
|
17
|
+
"module": "./dist/index.js",
|
|
18
|
+
"types": "./dist/index.d.ts",
|
|
19
|
+
"files": ["dist"],
|
|
20
|
+
"publishConfig": {
|
|
21
|
+
"access": "public"
|
|
22
|
+
},
|
|
23
|
+
"scripts": {
|
|
24
|
+
"build": "tsup",
|
|
25
|
+
"dev": "tsup --watch",
|
|
26
|
+
"test": "vitest run",
|
|
27
|
+
"clean": "rm -rf dist"
|
|
28
|
+
},
|
|
29
|
+
"dependencies": {
|
|
30
|
+
"@yesod/core": "workspace:*",
|
|
31
|
+
"better-sqlite3": "^11.8.0"
|
|
32
|
+
},
|
|
33
|
+
"devDependencies": {
|
|
34
|
+
"@types/better-sqlite3": "^7.6.12",
|
|
35
|
+
"tsup": "^8.4.0",
|
|
36
|
+
"typescript": "^5.8.0",
|
|
37
|
+
"vitest": "^3.1.0"
|
|
38
|
+
}
|
|
39
|
+
}
|