@sandbox-agent/persist-postgres 0.3.2 → 0.4.0-rc.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/README.md +5 -0
- package/dist/index.d.ts +1 -26
- package/dist/index.js +3 -240
- package/dist/index.js.map +1 -1
- package/package.json +4 -12
package/README.md
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
# @sandbox-agent/persist-postgres
|
|
2
|
+
|
|
3
|
+
> **Deprecated:** This package has been deprecated and removed.
|
|
4
|
+
|
|
5
|
+
Install `pg` directly and copy the driver source into your project. See the [full example](https://github.com/rivet-dev/sandbox-agent/tree/main/examples/persist-postgres) and the [session persistence docs](https://sandboxagent.dev/session-persistence) for guidance.
|
package/dist/index.d.ts
CHANGED
|
@@ -1,27 +1,2 @@
|
|
|
1
|
-
import { Pool, PoolConfig } from 'pg';
|
|
2
|
-
import { SessionPersistDriver, SessionRecord, ListPageRequest, ListPage, ListEventsRequest, SessionEvent } from 'sandbox-agent';
|
|
3
1
|
|
|
4
|
-
|
|
5
|
-
connectionString?: string;
|
|
6
|
-
pool?: Pool;
|
|
7
|
-
poolConfig?: PoolConfig;
|
|
8
|
-
schema?: string;
|
|
9
|
-
}
|
|
10
|
-
declare class PostgresSessionPersistDriver implements SessionPersistDriver {
|
|
11
|
-
private readonly pool;
|
|
12
|
-
private readonly ownsPool;
|
|
13
|
-
private readonly schema;
|
|
14
|
-
private readonly initialized;
|
|
15
|
-
constructor(options?: PostgresSessionPersistDriverOptions);
|
|
16
|
-
getSession(id: string): Promise<SessionRecord | null>;
|
|
17
|
-
listSessions(request?: ListPageRequest): Promise<ListPage<SessionRecord>>;
|
|
18
|
-
updateSession(session: SessionRecord): Promise<void>;
|
|
19
|
-
listEvents(request: ListEventsRequest): Promise<ListPage<SessionEvent>>;
|
|
20
|
-
insertEvent(event: SessionEvent): Promise<void>;
|
|
21
|
-
close(): Promise<void>;
|
|
22
|
-
private ready;
|
|
23
|
-
private table;
|
|
24
|
-
private initialize;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export { PostgresSessionPersistDriver, type PostgresSessionPersistDriverOptions };
|
|
2
|
+
export { }
|
package/dist/index.js
CHANGED
|
@@ -1,242 +1,5 @@
|
|
|
1
1
|
// src/index.ts
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
pool;
|
|
6
|
-
ownsPool;
|
|
7
|
-
schema;
|
|
8
|
-
initialized;
|
|
9
|
-
constructor(options = {}) {
|
|
10
|
-
this.schema = normalizeSchema(options.schema ?? "public");
|
|
11
|
-
if (options.pool) {
|
|
12
|
-
this.pool = options.pool;
|
|
13
|
-
this.ownsPool = false;
|
|
14
|
-
} else {
|
|
15
|
-
this.pool = new Pool({
|
|
16
|
-
connectionString: options.connectionString,
|
|
17
|
-
...options.poolConfig
|
|
18
|
-
});
|
|
19
|
-
this.ownsPool = true;
|
|
20
|
-
}
|
|
21
|
-
this.initialized = this.initialize();
|
|
22
|
-
}
|
|
23
|
-
async getSession(id) {
|
|
24
|
-
await this.ready();
|
|
25
|
-
const result = await this.pool.query(
|
|
26
|
-
`SELECT id, agent, agent_session_id, last_connection_id, created_at, destroyed_at, session_init_json
|
|
27
|
-
FROM ${this.table("sessions")}
|
|
28
|
-
WHERE id = $1`,
|
|
29
|
-
[id]
|
|
30
|
-
);
|
|
31
|
-
if (result.rows.length === 0) {
|
|
32
|
-
return null;
|
|
33
|
-
}
|
|
34
|
-
return decodeSessionRow(result.rows[0]);
|
|
35
|
-
}
|
|
36
|
-
async listSessions(request = {}) {
|
|
37
|
-
await this.ready();
|
|
38
|
-
const offset = parseCursor(request.cursor);
|
|
39
|
-
const limit = normalizeLimit(request.limit);
|
|
40
|
-
const rowsResult = await this.pool.query(
|
|
41
|
-
`SELECT id, agent, agent_session_id, last_connection_id, created_at, destroyed_at, session_init_json
|
|
42
|
-
FROM ${this.table("sessions")}
|
|
43
|
-
ORDER BY created_at ASC, id ASC
|
|
44
|
-
LIMIT $1 OFFSET $2`,
|
|
45
|
-
[limit, offset]
|
|
46
|
-
);
|
|
47
|
-
const countResult = await this.pool.query(`SELECT COUNT(*) AS count FROM ${this.table("sessions")}`);
|
|
48
|
-
const total = parseInteger(countResult.rows[0]?.count ?? "0");
|
|
49
|
-
const nextOffset = offset + rowsResult.rows.length;
|
|
50
|
-
return {
|
|
51
|
-
items: rowsResult.rows.map(decodeSessionRow),
|
|
52
|
-
nextCursor: nextOffset < total ? String(nextOffset) : void 0
|
|
53
|
-
};
|
|
54
|
-
}
|
|
55
|
-
async updateSession(session) {
|
|
56
|
-
await this.ready();
|
|
57
|
-
await this.pool.query(
|
|
58
|
-
`INSERT INTO ${this.table("sessions")} (
|
|
59
|
-
id, agent, agent_session_id, last_connection_id, created_at, destroyed_at, session_init_json
|
|
60
|
-
) VALUES ($1, $2, $3, $4, $5, $6, $7)
|
|
61
|
-
ON CONFLICT(id) DO UPDATE SET
|
|
62
|
-
agent = EXCLUDED.agent,
|
|
63
|
-
agent_session_id = EXCLUDED.agent_session_id,
|
|
64
|
-
last_connection_id = EXCLUDED.last_connection_id,
|
|
65
|
-
created_at = EXCLUDED.created_at,
|
|
66
|
-
destroyed_at = EXCLUDED.destroyed_at,
|
|
67
|
-
session_init_json = EXCLUDED.session_init_json`,
|
|
68
|
-
[
|
|
69
|
-
session.id,
|
|
70
|
-
session.agent,
|
|
71
|
-
session.agentSessionId,
|
|
72
|
-
session.lastConnectionId,
|
|
73
|
-
session.createdAt,
|
|
74
|
-
session.destroyedAt ?? null,
|
|
75
|
-
session.sessionInit ?? null
|
|
76
|
-
]
|
|
77
|
-
);
|
|
78
|
-
}
|
|
79
|
-
async listEvents(request) {
|
|
80
|
-
await this.ready();
|
|
81
|
-
const offset = parseCursor(request.cursor);
|
|
82
|
-
const limit = normalizeLimit(request.limit);
|
|
83
|
-
const rowsResult = await this.pool.query(
|
|
84
|
-
`SELECT id, event_index, session_id, created_at, connection_id, sender, payload_json
|
|
85
|
-
FROM ${this.table("events")}
|
|
86
|
-
WHERE session_id = $1
|
|
87
|
-
ORDER BY event_index ASC, id ASC
|
|
88
|
-
LIMIT $2 OFFSET $3`,
|
|
89
|
-
[request.sessionId, limit, offset]
|
|
90
|
-
);
|
|
91
|
-
const countResult = await this.pool.query(`SELECT COUNT(*) AS count FROM ${this.table("events")} WHERE session_id = $1`, [
|
|
92
|
-
request.sessionId
|
|
93
|
-
]);
|
|
94
|
-
const total = parseInteger(countResult.rows[0]?.count ?? "0");
|
|
95
|
-
const nextOffset = offset + rowsResult.rows.length;
|
|
96
|
-
return {
|
|
97
|
-
items: rowsResult.rows.map(decodeEventRow),
|
|
98
|
-
nextCursor: nextOffset < total ? String(nextOffset) : void 0
|
|
99
|
-
};
|
|
100
|
-
}
|
|
101
|
-
async insertEvent(event) {
|
|
102
|
-
await this.ready();
|
|
103
|
-
await this.pool.query(
|
|
104
|
-
`INSERT INTO ${this.table("events")} (
|
|
105
|
-
id, event_index, session_id, created_at, connection_id, sender, payload_json
|
|
106
|
-
) VALUES ($1, $2, $3, $4, $5, $6, $7)
|
|
107
|
-
ON CONFLICT(id) DO UPDATE SET
|
|
108
|
-
event_index = EXCLUDED.event_index,
|
|
109
|
-
session_id = EXCLUDED.session_id,
|
|
110
|
-
created_at = EXCLUDED.created_at,
|
|
111
|
-
connection_id = EXCLUDED.connection_id,
|
|
112
|
-
sender = EXCLUDED.sender,
|
|
113
|
-
payload_json = EXCLUDED.payload_json`,
|
|
114
|
-
[event.id, event.eventIndex, event.sessionId, event.createdAt, event.connectionId, event.sender, event.payload]
|
|
115
|
-
);
|
|
116
|
-
}
|
|
117
|
-
async close() {
|
|
118
|
-
if (!this.ownsPool) {
|
|
119
|
-
return;
|
|
120
|
-
}
|
|
121
|
-
await this.pool.end();
|
|
122
|
-
}
|
|
123
|
-
async ready() {
|
|
124
|
-
await this.initialized;
|
|
125
|
-
}
|
|
126
|
-
table(name) {
|
|
127
|
-
return `"${this.schema}"."${name}"`;
|
|
128
|
-
}
|
|
129
|
-
async initialize() {
|
|
130
|
-
await this.pool.query(`CREATE SCHEMA IF NOT EXISTS "${this.schema}"`);
|
|
131
|
-
await this.pool.query(`
|
|
132
|
-
CREATE TABLE IF NOT EXISTS ${this.table("sessions")} (
|
|
133
|
-
id TEXT PRIMARY KEY,
|
|
134
|
-
agent TEXT NOT NULL,
|
|
135
|
-
agent_session_id TEXT NOT NULL,
|
|
136
|
-
last_connection_id TEXT NOT NULL,
|
|
137
|
-
created_at BIGINT NOT NULL,
|
|
138
|
-
destroyed_at BIGINT,
|
|
139
|
-
session_init_json JSONB
|
|
140
|
-
)
|
|
141
|
-
`);
|
|
142
|
-
await this.pool.query(`
|
|
143
|
-
CREATE TABLE IF NOT EXISTS ${this.table("events")} (
|
|
144
|
-
id TEXT PRIMARY KEY,
|
|
145
|
-
event_index BIGINT NOT NULL,
|
|
146
|
-
session_id TEXT NOT NULL,
|
|
147
|
-
created_at BIGINT NOT NULL,
|
|
148
|
-
connection_id TEXT NOT NULL,
|
|
149
|
-
sender TEXT NOT NULL,
|
|
150
|
-
payload_json JSONB NOT NULL
|
|
151
|
-
)
|
|
152
|
-
`);
|
|
153
|
-
await this.pool.query(`
|
|
154
|
-
ALTER TABLE ${this.table("events")}
|
|
155
|
-
ALTER COLUMN id TYPE TEXT USING id::TEXT
|
|
156
|
-
`);
|
|
157
|
-
await this.pool.query(`
|
|
158
|
-
ALTER TABLE ${this.table("events")}
|
|
159
|
-
ADD COLUMN IF NOT EXISTS event_index BIGINT
|
|
160
|
-
`);
|
|
161
|
-
await this.pool.query(`
|
|
162
|
-
WITH ranked AS (
|
|
163
|
-
SELECT id, ROW_NUMBER() OVER (PARTITION BY session_id ORDER BY created_at ASC, id ASC) AS ranked_index
|
|
164
|
-
FROM ${this.table("events")}
|
|
165
|
-
)
|
|
166
|
-
UPDATE ${this.table("events")} AS current_events
|
|
167
|
-
SET event_index = ranked.ranked_index
|
|
168
|
-
FROM ranked
|
|
169
|
-
WHERE current_events.id = ranked.id
|
|
170
|
-
AND current_events.event_index IS NULL
|
|
171
|
-
`);
|
|
172
|
-
await this.pool.query(`
|
|
173
|
-
ALTER TABLE ${this.table("events")}
|
|
174
|
-
ALTER COLUMN event_index SET NOT NULL
|
|
175
|
-
`);
|
|
176
|
-
await this.pool.query(`
|
|
177
|
-
CREATE INDEX IF NOT EXISTS idx_events_session_order
|
|
178
|
-
ON ${this.table("events")}(session_id, event_index, id)
|
|
179
|
-
`);
|
|
180
|
-
}
|
|
181
|
-
};
|
|
182
|
-
function decodeSessionRow(row) {
|
|
183
|
-
return {
|
|
184
|
-
id: row.id,
|
|
185
|
-
agent: row.agent,
|
|
186
|
-
agentSessionId: row.agent_session_id,
|
|
187
|
-
lastConnectionId: row.last_connection_id,
|
|
188
|
-
createdAt: parseInteger(row.created_at),
|
|
189
|
-
destroyedAt: row.destroyed_at === null ? void 0 : parseInteger(row.destroyed_at),
|
|
190
|
-
sessionInit: row.session_init_json ? row.session_init_json : void 0
|
|
191
|
-
};
|
|
192
|
-
}
|
|
193
|
-
function decodeEventRow(row) {
|
|
194
|
-
return {
|
|
195
|
-
id: String(row.id),
|
|
196
|
-
eventIndex: parseInteger(row.event_index),
|
|
197
|
-
sessionId: row.session_id,
|
|
198
|
-
createdAt: parseInteger(row.created_at),
|
|
199
|
-
connectionId: row.connection_id,
|
|
200
|
-
sender: parseSender(row.sender),
|
|
201
|
-
payload: row.payload_json
|
|
202
|
-
};
|
|
203
|
-
}
|
|
204
|
-
function normalizeLimit(limit) {
|
|
205
|
-
if (!Number.isFinite(limit) || (limit ?? 0) < 1) {
|
|
206
|
-
return DEFAULT_LIST_LIMIT;
|
|
207
|
-
}
|
|
208
|
-
return Math.floor(limit);
|
|
209
|
-
}
|
|
210
|
-
function parseCursor(cursor) {
|
|
211
|
-
if (!cursor) {
|
|
212
|
-
return 0;
|
|
213
|
-
}
|
|
214
|
-
const parsed = Number.parseInt(cursor, 10);
|
|
215
|
-
if (!Number.isFinite(parsed) || parsed < 0) {
|
|
216
|
-
return 0;
|
|
217
|
-
}
|
|
218
|
-
return parsed;
|
|
219
|
-
}
|
|
220
|
-
function parseInteger(value) {
|
|
221
|
-
const parsed = typeof value === "number" ? value : Number.parseInt(value, 10);
|
|
222
|
-
if (!Number.isFinite(parsed)) {
|
|
223
|
-
throw new Error(`Invalid integer value returned by postgres: ${String(value)}`);
|
|
224
|
-
}
|
|
225
|
-
return parsed;
|
|
226
|
-
}
|
|
227
|
-
function parseSender(value) {
|
|
228
|
-
if (value === "agent" || value === "client") {
|
|
229
|
-
return value;
|
|
230
|
-
}
|
|
231
|
-
throw new Error(`Invalid sender value returned by postgres: ${value}`);
|
|
232
|
-
}
|
|
233
|
-
function normalizeSchema(schema) {
|
|
234
|
-
if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(schema)) {
|
|
235
|
-
throw new Error(`Invalid schema name '${schema}'. Use letters, numbers, and underscores only.`);
|
|
236
|
-
}
|
|
237
|
-
return schema;
|
|
238
|
-
}
|
|
239
|
-
export {
|
|
240
|
-
PostgresSessionPersistDriver
|
|
241
|
-
};
|
|
2
|
+
throw new Error(
|
|
3
|
+
"@sandbox-agent/persist-postgres has been deprecated and removed. Copy the reference implementation from examples/persist-postgres into your project instead. See https://github.com/rivet-dev/sandbox-agent/tree/main/examples/persist-postgres"
|
|
4
|
+
);
|
|
242
5
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { Pool, type PoolConfig } from \"pg\";\nimport type { ListEventsRequest, ListPage, ListPageRequest, SessionEvent, SessionPersistDriver, SessionRecord } from \"sandbox-agent\";\n\nconst DEFAULT_LIST_LIMIT = 100;\n\nexport interface PostgresSessionPersistDriverOptions {\n connectionString?: string;\n pool?: Pool;\n poolConfig?: PoolConfig;\n schema?: string;\n}\n\nexport class PostgresSessionPersistDriver implements SessionPersistDriver {\n private readonly pool: Pool;\n private readonly ownsPool: boolean;\n private readonly schema: string;\n private readonly initialized: Promise<void>;\n\n constructor(options: PostgresSessionPersistDriverOptions = {}) {\n this.schema = normalizeSchema(options.schema ?? \"public\");\n\n if (options.pool) {\n this.pool = options.pool;\n this.ownsPool = false;\n } else {\n this.pool = new Pool({\n connectionString: options.connectionString,\n ...options.poolConfig,\n });\n this.ownsPool = true;\n }\n\n this.initialized = this.initialize();\n }\n\n async getSession(id: string): Promise<SessionRecord | null> {\n await this.ready();\n\n const result = await this.pool.query<SessionRow>(\n `SELECT id, agent, agent_session_id, last_connection_id, created_at, destroyed_at, session_init_json\n FROM ${this.table(\"sessions\")}\n WHERE id = $1`,\n [id],\n );\n\n if (result.rows.length === 0) {\n return null;\n }\n\n return decodeSessionRow(result.rows[0]);\n }\n\n async listSessions(request: ListPageRequest = {}): Promise<ListPage<SessionRecord>> {\n await this.ready();\n\n const offset = parseCursor(request.cursor);\n const limit = normalizeLimit(request.limit);\n\n const rowsResult = await this.pool.query<SessionRow>(\n `SELECT id, agent, agent_session_id, last_connection_id, created_at, destroyed_at, session_init_json\n FROM ${this.table(\"sessions\")}\n ORDER BY created_at ASC, id ASC\n LIMIT $1 OFFSET $2`,\n [limit, offset],\n );\n\n const countResult = await this.pool.query<{ count: string }>(`SELECT COUNT(*) AS count FROM ${this.table(\"sessions\")}`);\n const total = parseInteger(countResult.rows[0]?.count ?? \"0\");\n const nextOffset = offset + rowsResult.rows.length;\n\n return {\n items: rowsResult.rows.map(decodeSessionRow),\n nextCursor: nextOffset < total ? String(nextOffset) : undefined,\n };\n }\n\n async updateSession(session: SessionRecord): Promise<void> {\n await this.ready();\n\n await this.pool.query(\n `INSERT INTO ${this.table(\"sessions\")} (\n id, agent, agent_session_id, last_connection_id, created_at, destroyed_at, session_init_json\n ) VALUES ($1, $2, $3, $4, $5, $6, $7)\n ON CONFLICT(id) DO UPDATE SET\n agent = EXCLUDED.agent,\n agent_session_id = EXCLUDED.agent_session_id,\n last_connection_id = EXCLUDED.last_connection_id,\n created_at = EXCLUDED.created_at,\n destroyed_at = EXCLUDED.destroyed_at,\n session_init_json = EXCLUDED.session_init_json`,\n [\n session.id,\n session.agent,\n session.agentSessionId,\n session.lastConnectionId,\n session.createdAt,\n session.destroyedAt ?? null,\n session.sessionInit ?? null,\n ],\n );\n }\n\n async listEvents(request: ListEventsRequest): Promise<ListPage<SessionEvent>> {\n await this.ready();\n\n const offset = parseCursor(request.cursor);\n const limit = normalizeLimit(request.limit);\n\n const rowsResult = await this.pool.query<EventRow>(\n `SELECT id, event_index, session_id, created_at, connection_id, sender, payload_json\n FROM ${this.table(\"events\")}\n WHERE session_id = $1\n ORDER BY event_index ASC, id ASC\n LIMIT $2 OFFSET $3`,\n [request.sessionId, limit, offset],\n );\n\n const countResult = await this.pool.query<{ count: string }>(`SELECT COUNT(*) AS count FROM ${this.table(\"events\")} WHERE session_id = $1`, [\n request.sessionId,\n ]);\n const total = parseInteger(countResult.rows[0]?.count ?? \"0\");\n const nextOffset = offset + rowsResult.rows.length;\n\n return {\n items: rowsResult.rows.map(decodeEventRow),\n nextCursor: nextOffset < total ? String(nextOffset) : undefined,\n };\n }\n\n async insertEvent(event: SessionEvent): Promise<void> {\n await this.ready();\n\n await this.pool.query(\n `INSERT INTO ${this.table(\"events\")} (\n id, event_index, session_id, created_at, connection_id, sender, payload_json\n ) VALUES ($1, $2, $3, $4, $5, $6, $7)\n ON CONFLICT(id) DO UPDATE SET\n event_index = EXCLUDED.event_index,\n session_id = EXCLUDED.session_id,\n created_at = EXCLUDED.created_at,\n connection_id = EXCLUDED.connection_id,\n sender = EXCLUDED.sender,\n payload_json = EXCLUDED.payload_json`,\n [event.id, event.eventIndex, event.sessionId, event.createdAt, event.connectionId, event.sender, event.payload],\n );\n }\n\n async close(): Promise<void> {\n if (!this.ownsPool) {\n return;\n }\n await this.pool.end();\n }\n\n private async ready(): Promise<void> {\n await this.initialized;\n }\n\n private table(name: \"sessions\" | \"events\"): string {\n return `\"${this.schema}\".\"${name}\"`;\n }\n\n private async initialize(): Promise<void> {\n await this.pool.query(`CREATE SCHEMA IF NOT EXISTS \"${this.schema}\"`);\n\n await this.pool.query(`\n CREATE TABLE IF NOT EXISTS ${this.table(\"sessions\")} (\n id TEXT PRIMARY KEY,\n agent TEXT NOT NULL,\n agent_session_id TEXT NOT NULL,\n last_connection_id TEXT NOT NULL,\n created_at BIGINT NOT NULL,\n destroyed_at BIGINT,\n session_init_json JSONB\n )\n `);\n\n await this.pool.query(`\n CREATE TABLE IF NOT EXISTS ${this.table(\"events\")} (\n id TEXT PRIMARY KEY,\n event_index BIGINT NOT NULL,\n session_id TEXT NOT NULL,\n created_at BIGINT NOT NULL,\n connection_id TEXT NOT NULL,\n sender TEXT NOT NULL,\n payload_json JSONB NOT NULL\n )\n `);\n\n await this.pool.query(`\n ALTER TABLE ${this.table(\"events\")}\n ALTER COLUMN id TYPE TEXT USING id::TEXT\n `);\n\n await this.pool.query(`\n ALTER TABLE ${this.table(\"events\")}\n ADD COLUMN IF NOT EXISTS event_index BIGINT\n `);\n\n await this.pool.query(`\n WITH ranked AS (\n SELECT id, ROW_NUMBER() OVER (PARTITION BY session_id ORDER BY created_at ASC, id ASC) AS ranked_index\n FROM ${this.table(\"events\")}\n )\n UPDATE ${this.table(\"events\")} AS current_events\n SET event_index = ranked.ranked_index\n FROM ranked\n WHERE current_events.id = ranked.id\n AND current_events.event_index IS NULL\n `);\n\n await this.pool.query(`\n ALTER TABLE ${this.table(\"events\")}\n ALTER COLUMN event_index SET NOT NULL\n `);\n\n await this.pool.query(`\n CREATE INDEX IF NOT EXISTS idx_events_session_order\n ON ${this.table(\"events\")}(session_id, event_index, id)\n `);\n }\n}\n\ntype SessionRow = {\n id: string;\n agent: string;\n agent_session_id: string;\n last_connection_id: string;\n created_at: string | number;\n destroyed_at: string | number | null;\n session_init_json: unknown | null;\n};\n\ntype EventRow = {\n id: string | number;\n event_index: string | number;\n session_id: string;\n created_at: string | number;\n connection_id: string;\n sender: string;\n payload_json: unknown;\n};\n\nfunction decodeSessionRow(row: SessionRow): SessionRecord {\n return {\n id: row.id,\n agent: row.agent,\n agentSessionId: row.agent_session_id,\n lastConnectionId: row.last_connection_id,\n createdAt: parseInteger(row.created_at),\n destroyedAt: row.destroyed_at === null ? undefined : parseInteger(row.destroyed_at),\n sessionInit: row.session_init_json ? (row.session_init_json as SessionRecord[\"sessionInit\"]) : undefined,\n };\n}\n\nfunction decodeEventRow(row: EventRow): SessionEvent {\n return {\n id: String(row.id),\n eventIndex: parseInteger(row.event_index),\n sessionId: row.session_id,\n createdAt: parseInteger(row.created_at),\n connectionId: row.connection_id,\n sender: parseSender(row.sender),\n payload: row.payload_json as SessionEvent[\"payload\"],\n };\n}\n\nfunction normalizeLimit(limit: number | undefined): number {\n if (!Number.isFinite(limit) || (limit ?? 0) < 1) {\n return DEFAULT_LIST_LIMIT;\n }\n return Math.floor(limit as number);\n}\n\nfunction parseCursor(cursor: string | undefined): number {\n if (!cursor) {\n return 0;\n }\n const parsed = Number.parseInt(cursor, 10);\n if (!Number.isFinite(parsed) || parsed < 0) {\n return 0;\n }\n return parsed;\n}\n\nfunction parseInteger(value: string | number): number {\n const parsed = typeof value === \"number\" ? value : Number.parseInt(value, 10);\n if (!Number.isFinite(parsed)) {\n throw new Error(`Invalid integer value returned by postgres: ${String(value)}`);\n }\n return parsed;\n}\n\nfunction parseSender(value: string): SessionEvent[\"sender\"] {\n if (value === \"agent\" || value === \"client\") {\n return value;\n }\n throw new Error(`Invalid sender value returned by postgres: ${value}`);\n}\n\nfunction normalizeSchema(schema: string): string {\n if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(schema)) {\n throw new Error(`Invalid schema name '${schema}'. Use letters, numbers, and underscores only.`);\n }\n return schema;\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["throw new Error(\n \"@sandbox-agent/persist-postgres has been deprecated and removed. \" +\n \"Copy the reference implementation from examples/persist-postgres into your project instead. \" +\n \"See https://github.com/rivet-dev/sandbox-agent/tree/main/examples/persist-postgres\",\n);\n"],"mappings":";AAAA,MAAM,IAAI;AAAA,EACR;AAGF;","names":[]}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sandbox-agent/persist-postgres",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "PostgreSQL persistence driver for the Sandbox Agent TypeScript SDK",
|
|
3
|
+
"version": "0.4.0-rc.2",
|
|
4
|
+
"description": "PostgreSQL persistence driver for the Sandbox Agent TypeScript SDK (DEPRECATED)",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -16,24 +16,16 @@
|
|
|
16
16
|
"import": "./dist/index.js"
|
|
17
17
|
}
|
|
18
18
|
},
|
|
19
|
-
"dependencies": {
|
|
20
|
-
"pg": "^8.16.3",
|
|
21
|
-
"sandbox-agent": "0.3.2"
|
|
22
|
-
},
|
|
23
19
|
"files": [
|
|
24
20
|
"dist"
|
|
25
21
|
],
|
|
26
22
|
"devDependencies": {
|
|
27
23
|
"@types/node": "^22.0.0",
|
|
28
|
-
"@types/pg": "^8.15.6",
|
|
29
24
|
"tsup": "^8.0.0",
|
|
30
|
-
"typescript": "^5.7.0"
|
|
31
|
-
"vitest": "^3.0.0"
|
|
25
|
+
"typescript": "^5.7.0"
|
|
32
26
|
},
|
|
33
27
|
"scripts": {
|
|
34
28
|
"build": "tsup",
|
|
35
|
-
"typecheck": "tsc --noEmit"
|
|
36
|
-
"test": "vitest run",
|
|
37
|
-
"test:watch": "vitest"
|
|
29
|
+
"typecheck": "tsc --noEmit"
|
|
38
30
|
}
|
|
39
31
|
}
|