@langgraph-js/pure-graph 3.2.2 → 3.2.3
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/adapter/fetch/index.js +3 -7
- package/dist/adapter/fetch/index.js.map +1 -1
- package/dist/adapter/nextjs/index.js +1 -1
- package/dist/{checkpoint-CY59Lr2q.js → checkpoint-Due32543.js} +69 -39
- package/dist/checkpoint-Due32543.js.map +1 -0
- package/dist/{createEndpoint-vMmFiMSz.js → createEndpoint-CTPbz_D8.js} +2 -2
- package/dist/{createEndpoint-vMmFiMSz.js.map → createEndpoint-CTPbz_D8.js.map} +1 -1
- package/dist/index.js +2 -2
- package/dist/{queue-CUe5TDP1.js → queue-DPHwOl26.js} +2 -2
- package/dist/{queue-CUe5TDP1.js.map → queue-DPHwOl26.js.map} +1 -1
- package/dist/remote/index.js +1 -1
- package/dist/{shallow-checkpoint-ImbLxYNR.js → shallow-checkpoint-CHYRdSct.js} +76 -46
- package/dist/shallow-checkpoint-CHYRdSct.js.map +1 -0
- package/dist/{stream-jYlUzTZO.js → stream-Zt8tbgEj.js} +6 -9
- package/dist/{stream-jYlUzTZO.js.map → stream-Zt8tbgEj.js.map} +1 -1
- package/package.json +1 -1
- package/dist/checkpoint-CY59Lr2q.js.map +0 -1
- package/dist/shallow-checkpoint-ImbLxYNR.js.map +0 -1
|
@@ -4,9 +4,27 @@ import { BaseCheckpointSaver, TASKS, copyCheckpoint, maxChannelVersion } from '@
|
|
|
4
4
|
const SQLITE_RETRY_CONFIG = {
|
|
5
5
|
maxRetries: 3,
|
|
6
6
|
baseDelayMs: 100,
|
|
7
|
+
// 不可重试的错误模式
|
|
8
|
+
nonRetryablePatterns: [
|
|
9
|
+
"database disk image is malformed",
|
|
10
|
+
// 数据库文件损坏
|
|
11
|
+
"database is malformed",
|
|
12
|
+
// 数据库损坏(短形式)
|
|
13
|
+
"cannot rollback",
|
|
14
|
+
// 事务状态错误
|
|
15
|
+
"no transaction is active",
|
|
16
|
+
// 无活动事务
|
|
17
|
+
"database or disk is full"
|
|
18
|
+
// 磁盘空间不足
|
|
19
|
+
],
|
|
7
20
|
isRetryableError: (error) => {
|
|
8
21
|
const msg = error?.message?.toLowerCase() || "";
|
|
9
|
-
|
|
22
|
+
for (const pattern of SQLITE_RETRY_CONFIG.nonRetryablePatterns) {
|
|
23
|
+
if (msg.includes(pattern.toLowerCase())) {
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return msg.includes("sqlite_busy") || msg.includes("database is locked") || msg === "sqlite_busy" || msg === "database is locked";
|
|
10
28
|
}
|
|
11
29
|
};
|
|
12
30
|
async function withRetry(operation, context) {
|
|
@@ -16,7 +34,28 @@ async function withRetry(operation, context) {
|
|
|
16
34
|
return await operation();
|
|
17
35
|
} catch (error) {
|
|
18
36
|
lastError = error;
|
|
37
|
+
const msg = error?.message?.toLowerCase() || "";
|
|
19
38
|
if (!SQLITE_RETRY_CONFIG.isRetryableError(error)) {
|
|
39
|
+
if (msg.includes("malformed")) {
|
|
40
|
+
const enhancedError = new Error(
|
|
41
|
+
`SQLite database is corrupted: ${error.message}
|
|
42
|
+
|
|
43
|
+
Context: ${context || "unknown"}
|
|
44
|
+
|
|
45
|
+
Possible causes:
|
|
46
|
+
1. Database file was manually deleted or modified
|
|
47
|
+
2. Disk I/O errors during write operations
|
|
48
|
+
3. Concurrent access without proper locking
|
|
49
|
+
|
|
50
|
+
Recovery options:
|
|
51
|
+
- Delete the database file to start fresh (data will be lost)
|
|
52
|
+
- Use SQLite recovery tools: sqlite3 <db> ".recover" > recover.sql
|
|
53
|
+
- Switch to PostgreSQL/Redis for production use`
|
|
54
|
+
);
|
|
55
|
+
enhancedError.name = "SQLiteCorruptError";
|
|
56
|
+
enhancedError.cause = error;
|
|
57
|
+
throw enhancedError;
|
|
58
|
+
}
|
|
20
59
|
throw error;
|
|
21
60
|
}
|
|
22
61
|
if (attempt < SQLITE_RETRY_CONFIG.maxRetries - 1) {
|
|
@@ -320,27 +359,24 @@ CREATE TABLE IF NOT EXISTS writes (
|
|
|
320
359
|
if (type1 !== type2) {
|
|
321
360
|
throw new Error("Failed to serialized checkpoint and metadata to the same type.");
|
|
322
361
|
}
|
|
323
|
-
await withRetry(
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
362
|
+
await withRetry(async () => {
|
|
363
|
+
await this.db.insertInto("checkpoints").values({
|
|
364
|
+
thread_id,
|
|
365
|
+
checkpoint_ns,
|
|
366
|
+
checkpoint_id: checkpoint.id,
|
|
367
|
+
parent_checkpoint_id: parent_checkpoint_id ?? null,
|
|
368
|
+
type: type1,
|
|
369
|
+
checkpoint: new Uint8Array(Buffer.from(serializedCheckpoint)),
|
|
370
|
+
metadata: new Uint8Array(Buffer.from(serializedMetadata))
|
|
371
|
+
}).onConflict(
|
|
372
|
+
(oc) => oc.columns(["thread_id", "checkpoint_ns", "checkpoint_id"]).doUpdateSet({
|
|
329
373
|
parent_checkpoint_id: parent_checkpoint_id ?? null,
|
|
330
374
|
type: type1,
|
|
331
375
|
checkpoint: new Uint8Array(Buffer.from(serializedCheckpoint)),
|
|
332
376
|
metadata: new Uint8Array(Buffer.from(serializedMetadata))
|
|
333
|
-
})
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
type: type1,
|
|
337
|
-
checkpoint: new Uint8Array(Buffer.from(serializedCheckpoint)),
|
|
338
|
-
metadata: new Uint8Array(Buffer.from(serializedMetadata))
|
|
339
|
-
})
|
|
340
|
-
).execute();
|
|
341
|
-
},
|
|
342
|
-
`put(${thread_id}/${checkpoint.id})`
|
|
343
|
-
);
|
|
377
|
+
})
|
|
378
|
+
).execute();
|
|
379
|
+
}, `put(${thread_id}/${checkpoint.id})`);
|
|
344
380
|
return {
|
|
345
381
|
configurable: {
|
|
346
382
|
thread_id,
|
|
@@ -378,28 +414,22 @@ CREATE TABLE IF NOT EXISTS writes (
|
|
|
378
414
|
if (values.length === 0) return;
|
|
379
415
|
const threadId = config.configurable.thread_id;
|
|
380
416
|
const checkpointId = config.configurable.checkpoint_id;
|
|
381
|
-
await withRetry(
|
|
382
|
-
async () => {
|
|
383
|
-
await
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
},
|
|
390
|
-
`putWrites(${threadId}/${checkpointId}/${taskId})`
|
|
391
|
-
);
|
|
417
|
+
await withRetry(async () => {
|
|
418
|
+
await this.db.transaction().execute(async (trx) => {
|
|
419
|
+
await trx.deleteFrom("writes").where("thread_id", "=", threadId).where("checkpoint_ns", "=", values[0].checkpoint_ns).where("checkpoint_id", "=", checkpointId).where("task_id", "=", taskId).execute();
|
|
420
|
+
for (const value of values) {
|
|
421
|
+
await trx.insertInto("writes").values(value).execute();
|
|
422
|
+
}
|
|
423
|
+
});
|
|
424
|
+
}, `putWrites(${threadId}/${checkpointId}/${taskId})`);
|
|
392
425
|
}
|
|
393
426
|
async deleteThread(threadId) {
|
|
394
|
-
await withRetry(
|
|
395
|
-
async () => {
|
|
396
|
-
await
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
},
|
|
401
|
-
`deleteThread(${threadId})`
|
|
402
|
-
);
|
|
427
|
+
await withRetry(async () => {
|
|
428
|
+
await this.db.transaction().execute(async (trx) => {
|
|
429
|
+
await trx.deleteFrom("checkpoints").where("thread_id", "=", threadId).execute();
|
|
430
|
+
await trx.deleteFrom("writes").where("thread_id", "=", threadId).execute();
|
|
431
|
+
});
|
|
432
|
+
}, `deleteThread(${threadId})`);
|
|
403
433
|
}
|
|
404
434
|
async migratePendingSends(checkpoint, threadId, parentCheckpointId) {
|
|
405
435
|
const result = await this.db.selectFrom("writes as ps").select([
|
|
@@ -424,4 +454,4 @@ CREATE TABLE IF NOT EXISTS writes (
|
|
|
424
454
|
}
|
|
425
455
|
|
|
426
456
|
export { SqliteSaver };
|
|
427
|
-
//# sourceMappingURL=checkpoint-
|
|
457
|
+
//# sourceMappingURL=checkpoint-Due32543.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"checkpoint-Due32543.js","sources":["../src/storage/sqlite/checkpoint.ts"],"sourcesContent":["import { Dialect, Kysely, SqliteDialect, sql } from 'kysely';\nimport type { RunnableConfig } from '@langchain/core/runnables';\n\nimport {\n BaseCheckpointSaver,\n type Checkpoint,\n type CheckpointListOptions,\n type CheckpointTuple,\n type SerializerProtocol,\n type PendingWrite,\n type CheckpointMetadata,\n TASKS,\n copyCheckpoint,\n maxChannelVersion,\n} from '@langchain/langgraph-checkpoint';\n\n/**\n * SQLite 重试配置\n */\nconst SQLITE_RETRY_CONFIG = {\n maxRetries: 3,\n baseDelayMs: 100,\n // 不可重试的错误模式\n nonRetryablePatterns: [\n 'database disk image is malformed', // 数据库文件损坏\n 'database is malformed', // 数据库损坏(短形式)\n 'cannot rollback', // 事务状态错误\n 'no transaction is active', // 无活动事务\n 'database or disk is full', // 磁盘空间不足\n ],\n isRetryableError: (error: any): boolean => {\n const msg = error?.message?.toLowerCase() || '';\n\n // 检查是否为不可重试的错误\n for (const pattern of SQLITE_RETRY_CONFIG.nonRetryablePatterns) {\n if (msg.includes(pattern.toLowerCase())) {\n return false;\n }\n }\n\n // 只重试锁相关的错误\n return (\n msg.includes('sqlite_busy') ||\n msg.includes('database is locked') ||\n msg === 'sqlite_busy' ||\n msg === 'database is locked'\n );\n },\n};\n\n/**\n * 带重试的数据库操作包装器\n */\nasync function withRetry<T>(operation: () => Promise<T>, context?: string): Promise<T> {\n let lastError: Error | null = null;\n\n for (let attempt = 0; attempt < SQLITE_RETRY_CONFIG.maxRetries; attempt++) {\n try {\n return await operation();\n } catch (error: any) {\n lastError = error;\n const msg = error?.message?.toLowerCase() || '';\n\n // 检查是否为严重错误(不可重试)\n if (!SQLITE_RETRY_CONFIG.isRetryableError(error)) {\n // 为数据库损坏错误提供额外的诊断信息\n if (msg.includes('malformed')) {\n const enhancedError = new Error(\n `SQLite database is corrupted: ${error.message}\\n\\n` +\n `Context: ${context || 'unknown'}\\n\\n` +\n `Possible causes:\\n` +\n `1. Database file was manually deleted or modified\\n` +\n `2. Disk I/O errors during write operations\\n` +\n `3. Concurrent access without proper locking\\n\\n` +\n `Recovery options:\\n` +\n `- Delete the database file to start fresh (data will be lost)\\n` +\n `- Use SQLite recovery tools: sqlite3 <db> \".recover\" > recover.sql\\n` +\n `- Switch to PostgreSQL/Redis for production use`,\n );\n enhancedError.name = 'SQLiteCorruptError';\n /** @ts-ignore */\n enhancedError.cause = error;\n throw enhancedError;\n }\n\n // 其他不可重试错误直接抛出\n throw error;\n }\n\n if (attempt < SQLITE_RETRY_CONFIG.maxRetries - 1) {\n const delay = SQLITE_RETRY_CONFIG.baseDelayMs * Math.pow(2, attempt);\n console.warn(\n `SQLite lock detected${context ? ` (${context})` : ''}, retrying in ${delay}ms (attempt ${\n attempt + 1\n }/${SQLITE_RETRY_CONFIG.maxRetries})`,\n );\n await new Promise((resolve) => setTimeout(resolve, delay));\n }\n }\n }\n\n throw lastError;\n}\n\n// Kysely 数据库表类型定义\ninterface CheckpointsTable {\n thread_id: string;\n checkpoint_ns: string;\n checkpoint_id: string;\n parent_checkpoint_id: string | null;\n type: string | null;\n checkpoint: Uint8Array;\n metadata: Uint8Array;\n}\n\ninterface WritesTable {\n thread_id: string;\n checkpoint_ns: string;\n checkpoint_id: string;\n task_id: string;\n idx: number;\n channel: string;\n type: string | null;\n value: Uint8Array | null;\n}\n\ninterface CheckpointDatabase {\n checkpoints: CheckpointsTable;\n writes: WritesTable;\n}\n\ninterface CheckpointRow {\n checkpoint: string;\n metadata: string;\n parent_checkpoint_id?: string;\n thread_id: string;\n checkpoint_id: string;\n checkpoint_ns?: string;\n type?: string;\n pending_writes: string;\n}\n\ninterface PendingWriteColumn {\n task_id: string;\n channel: string;\n type: string;\n value: string;\n}\n\ninterface PendingSendColumn {\n type: string;\n value: string;\n}\n\n// In the `SqliteSaver.list` method, we need to sanitize the `options.filter` argument to ensure it only contains keys\n// that are part of the `CheckpointMetadata` type. The lines below ensure that we get compile-time errors if the list\n// of keys that we use is out of sync with the `CheckpointMetadata` type.\nconst checkpointMetadataKeys = ['source', 'step', 'parents'] as const;\n\ntype CheckKeys<T, K extends readonly (keyof T)[]> = [K[number]] extends [keyof T]\n ? [keyof T] extends [K[number]]\n ? K\n : never\n : never;\n\nfunction validateKeys<T, K extends readonly (keyof T)[]>(keys: CheckKeys<T, K>): K {\n return keys;\n}\n\n// If this line fails to compile, the list of keys that we use in the `SqliteSaver.list` method is out of sync with the\n// `CheckpointMetadata` type. In that case, just update `checkpointMetadataKeys` to contain all the keys in\n// `CheckpointMetadata`\nconst validCheckpointMetadataKeys = validateKeys<CheckpointMetadata, typeof checkpointMetadataKeys>(\n checkpointMetadataKeys,\n);\n\nexport class SqliteSaver extends BaseCheckpointSaver {\n db: Kysely<CheckpointDatabase>;\n\n protected isSetup: boolean;\n\n constructor(dialect: Dialect, serde?: SerializerProtocol) {\n super(serde);\n this.db = new Kysely<CheckpointDatabase>({\n dialect,\n });\n this.isSetup = false;\n }\n\n static async fromConnStringAsync(connStringOrLocalPath: string): Promise<SqliteSaver> {\n let saver: SqliteSaver;\n /** @ts-ignore */\n if (globalThis.Bun) {\n console.log('LG | Using BunWorkerDialect ' + connStringOrLocalPath);\n const { BunSqliteDialect } = await import('kysely-bun-worker/normal');\n // 使用 BunSqliteDialect(非 Worker 模式)避免 Worker 事务状态同步问题\n // BunWorkerDialect 在高并发下可能出现 \"cannot rollback - no transaction is active\"\n saver = new SqliteSaver(new BunSqliteDialect({ url: connStringOrLocalPath }));\n } else {\n /** @ts-ignore */\n console.log('LG | Using NodeWasmDialect');\n const { default: SqliteDatabase } = await import('node-sqlite3-wasm');\n const { NodeWasmDialect } = await import('kysely-wasm');\n console.log(connStringOrLocalPath);\n const wasm = new NodeWasmDialect({\n database: new SqliteDatabase.Database(connStringOrLocalPath),\n });\n saver = new SqliteSaver(wasm);\n }\n await saver.setup();\n return saver;\n }\n\n protected async setup(): Promise<void> {\n if (this.isSetup) {\n return;\n }\n\n // 锁等待超时 5 秒,避免立即返回 SQLITE_BUSY\n await sql`PRAGMA busy_timeout = 5000`.execute(this.db);\n\n // WAL 模式 - 允许读写并发\n await sql`PRAGMA journal_mode = WAL`.execute(this.db);\n\n // NORMAL 模式 - 平衡数据安全与性能\n await sql`PRAGMA synchronous = NORMAL`.execute(this.db);\n\n // WAL 自动检查点 - 每 1000 页执行一次,避免 WAL 文件无限增长\n await sql`PRAGMA wal_autocheckpoint = 1000`.execute(this.db);\n\n await sql`\nCREATE TABLE IF NOT EXISTS checkpoints (\n thread_id TEXT NOT NULL,\n checkpoint_ns TEXT NOT NULL DEFAULT '',\n checkpoint_id TEXT NOT NULL,\n parent_checkpoint_id TEXT,\n type TEXT,\n checkpoint BLOB,\n metadata BLOB,\n PRIMARY KEY (thread_id, checkpoint_ns, checkpoint_id)\n)`.execute(this.db);\n\n await sql`\nCREATE TABLE IF NOT EXISTS writes (\n thread_id TEXT NOT NULL,\n checkpoint_ns TEXT NOT NULL DEFAULT '',\n checkpoint_id TEXT NOT NULL,\n task_id TEXT NOT NULL,\n idx INTEGER NOT NULL,\n channel TEXT NOT NULL,\n type TEXT,\n value BLOB,\n PRIMARY KEY (thread_id, checkpoint_ns, checkpoint_id, task_id, idx)\n)`.execute(this.db);\n this.isSetup = true;\n }\n\n async getTuple(config: RunnableConfig): Promise<CheckpointTuple | undefined> {\n await this.setup();\n const { thread_id, checkpoint_ns = '', checkpoint_id } = config.configurable ?? {};\n\n let query = this.db\n .selectFrom('checkpoints')\n .select([\n 'thread_id',\n 'checkpoint_ns',\n 'checkpoint_id',\n 'parent_checkpoint_id',\n 'type',\n 'checkpoint',\n 'metadata',\n sql<string>`(\n SELECT json_group_array(\n json_object(\n 'task_id', pw.task_id,\n 'channel', pw.channel,\n 'type', pw.type,\n 'value', CAST(pw.value AS TEXT)\n )\n )\n FROM writes as pw\n WHERE pw.thread_id = checkpoints.thread_id\n AND pw.checkpoint_ns = checkpoints.checkpoint_ns\n AND pw.checkpoint_id = checkpoints.checkpoint_id\n )`.as('pending_writes'),\n sql<string>`(\n SELECT json_group_array(\n json_object(\n 'type', ps.type,\n 'value', CAST(ps.value AS TEXT)\n )\n )\n FROM writes as ps\n WHERE ps.thread_id = checkpoints.thread_id\n AND ps.checkpoint_ns = checkpoints.checkpoint_ns\n AND ps.checkpoint_id = checkpoints.parent_checkpoint_id\n AND ps.channel = ${TASKS}\n ORDER BY ps.idx\n )`.as('pending_sends'),\n ])\n .where('thread_id', '=', thread_id)\n .where('checkpoint_ns', '=', checkpoint_ns);\n\n if (checkpoint_id) {\n query = query.where('checkpoint_id', '=', checkpoint_id);\n } else {\n query = query.orderBy('checkpoint_id', 'desc').limit(1);\n }\n\n const row = await query.executeTakeFirst();\n if (!row) return undefined;\n\n let finalConfig = config;\n\n if (!checkpoint_id) {\n finalConfig = {\n configurable: {\n thread_id: row.thread_id,\n checkpoint_ns,\n checkpoint_id: row.checkpoint_id,\n },\n };\n }\n\n if (\n finalConfig.configurable?.thread_id === undefined ||\n finalConfig.configurable?.checkpoint_id === undefined\n ) {\n throw new Error('Missing thread_id or checkpoint_id');\n }\n\n const pendingWrites = await Promise.all(\n (JSON.parse(row.pending_writes) as PendingWriteColumn[]).map(async (write) => {\n return [\n write.task_id,\n write.channel,\n await this.serde.loadsTyped(write.type ?? 'json', write.value ?? ''),\n ] as [string, string, unknown];\n }),\n );\n\n const checkpoint = (await this.serde.loadsTyped(\n row.type ?? 'json',\n new TextDecoder().decode(row.checkpoint),\n )) as Checkpoint;\n\n if (checkpoint.v < 4 && row.parent_checkpoint_id != null) {\n await this.migratePendingSends(checkpoint, row.thread_id, row.parent_checkpoint_id);\n }\n\n return {\n checkpoint,\n config: finalConfig,\n metadata: (await this.serde.loadsTyped(\n row.type ?? 'json',\n new TextDecoder().decode(row.metadata),\n )) as CheckpointMetadata,\n parentConfig: row.parent_checkpoint_id\n ? {\n configurable: {\n thread_id: row.thread_id,\n checkpoint_ns,\n checkpoint_id: row.parent_checkpoint_id,\n },\n }\n : undefined,\n pendingWrites,\n };\n }\n\n async *list(config: RunnableConfig, options?: CheckpointListOptions): AsyncGenerator<CheckpointTuple> {\n const { limit, before, filter } = options ?? {};\n await this.setup();\n const thread_id = config.configurable?.thread_id;\n const checkpoint_ns = config.configurable?.checkpoint_ns;\n\n let query = this.db.selectFrom('checkpoints').select([\n 'thread_id',\n 'checkpoint_ns',\n 'checkpoint_id',\n 'parent_checkpoint_id',\n 'type',\n 'checkpoint',\n 'metadata',\n sql<string>`(\n SELECT json_group_array(\n json_object(\n 'task_id', pw.task_id,\n 'channel', pw.channel,\n 'type', pw.type,\n 'value', CAST(pw.value AS TEXT)\n )\n )\n FROM writes as pw\n WHERE pw.thread_id = checkpoints.thread_id\n AND pw.checkpoint_ns = checkpoints.checkpoint_ns\n AND pw.checkpoint_id = checkpoints.checkpoint_id\n )`.as('pending_writes'),\n sql<string>`(\n SELECT json_group_array(\n json_object(\n 'type', ps.type,\n 'value', CAST(ps.value AS TEXT)\n )\n )\n FROM writes as ps\n WHERE ps.thread_id = checkpoints.thread_id\n AND ps.checkpoint_ns = checkpoints.checkpoint_ns\n AND ps.checkpoint_id = checkpoints.parent_checkpoint_id\n AND ps.channel = ${TASKS}\n ORDER BY ps.idx\n )`.as('pending_sends'),\n ]);\n\n if (thread_id) {\n query = query.where('thread_id', '=', thread_id);\n }\n\n if (checkpoint_ns !== undefined && checkpoint_ns !== null) {\n query = query.where('checkpoint_ns', '=', checkpoint_ns);\n }\n\n if (before?.configurable?.checkpoint_id !== undefined) {\n query = query.where('checkpoint_id', '<', before.configurable.checkpoint_id);\n }\n\n const sanitizedFilter = Object.fromEntries(\n Object.entries(filter ?? {}).filter(\n ([key, value]) =>\n value !== undefined && validCheckpointMetadataKeys.includes(key as keyof CheckpointMetadata),\n ),\n );\n\n for (const [key, value] of Object.entries(sanitizedFilter)) {\n query = query.where(\n sql`json_extract(CAST(metadata AS TEXT), ${sql.lit('$.' + key)})`,\n '=',\n sql.lit(JSON.stringify(value)),\n );\n }\n\n query = query.orderBy('checkpoint_id', 'desc');\n\n if (limit) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n query = query.limit(parseInt(limit as any, 10));\n }\n\n const rows = await query.execute();\n\n for (const row of rows) {\n const pendingWrites = await Promise.all(\n (JSON.parse(row.pending_writes) as PendingWriteColumn[]).map(async (write) => {\n return [\n write.task_id,\n write.channel,\n await this.serde.loadsTyped(write.type ?? 'json', write.value ?? ''),\n ] as [string, string, unknown];\n }),\n );\n\n const checkpoint = (await this.serde.loadsTyped(\n row.type ?? 'json',\n new TextDecoder().decode(row.checkpoint),\n )) as Checkpoint;\n\n if (checkpoint.v < 4 && row.parent_checkpoint_id != null) {\n await this.migratePendingSends(checkpoint, row.thread_id, row.parent_checkpoint_id);\n }\n\n yield {\n config: {\n configurable: {\n thread_id: row.thread_id,\n checkpoint_ns: row.checkpoint_ns,\n checkpoint_id: row.checkpoint_id,\n },\n },\n checkpoint,\n metadata: (await this.serde.loadsTyped(\n row.type ?? 'json',\n new TextDecoder().decode(row.metadata),\n )) as CheckpointMetadata,\n parentConfig: row.parent_checkpoint_id\n ? {\n configurable: {\n thread_id: row.thread_id,\n checkpoint_ns: row.checkpoint_ns,\n checkpoint_id: row.parent_checkpoint_id,\n },\n }\n : undefined,\n pendingWrites,\n };\n }\n }\n\n async put(config: RunnableConfig, checkpoint: Checkpoint, metadata: CheckpointMetadata): Promise<RunnableConfig> {\n await this.setup();\n\n if (!config.configurable) {\n throw new Error('Empty configuration supplied.');\n }\n\n const thread_id = config.configurable?.thread_id;\n const checkpoint_ns = config.configurable?.checkpoint_ns ?? '';\n const parent_checkpoint_id = config.configurable?.checkpoint_id;\n\n if (!thread_id) {\n throw new Error(`Missing \"thread_id\" field in passed \"config.configurable\".`);\n }\n\n const preparedCheckpoint: Partial<Checkpoint> = copyCheckpoint(checkpoint);\n\n // 序列化在事务外完成\n const [[type1, serializedCheckpoint], [type2, serializedMetadata]] = await Promise.all([\n this.serde.dumpsTyped(preparedCheckpoint),\n this.serde.dumpsTyped(metadata),\n ]);\n\n if (type1 !== type2) {\n throw new Error('Failed to serialized checkpoint and metadata to the same type.');\n }\n\n // 带重试的数据库操作\n await withRetry(async () => {\n await this.db\n .insertInto('checkpoints')\n .values({\n thread_id,\n checkpoint_ns,\n checkpoint_id: checkpoint.id,\n parent_checkpoint_id: parent_checkpoint_id ?? null,\n type: type1,\n checkpoint: new Uint8Array(Buffer.from(serializedCheckpoint)),\n metadata: new Uint8Array(Buffer.from(serializedMetadata)),\n })\n .onConflict((oc) =>\n oc.columns(['thread_id', 'checkpoint_ns', 'checkpoint_id']).doUpdateSet({\n parent_checkpoint_id: parent_checkpoint_id ?? null,\n type: type1,\n checkpoint: new Uint8Array(Buffer.from(serializedCheckpoint)),\n metadata: new Uint8Array(Buffer.from(serializedMetadata)),\n }),\n )\n .execute();\n }, `put(${thread_id}/${checkpoint.id})`);\n\n return {\n configurable: {\n thread_id,\n checkpoint_ns,\n checkpoint_id: checkpoint.id,\n },\n };\n }\n\n async putWrites(config: RunnableConfig, writes: PendingWrite[], taskId: string): Promise<void> {\n await this.setup();\n\n if (!config.configurable) {\n throw new Error('Empty configuration supplied.');\n }\n\n if (!config.configurable?.thread_id) {\n throw new Error('Missing thread_id field in config.configurable.');\n }\n\n if (!config.configurable?.checkpoint_id) {\n throw new Error('Missing checkpoint_id field in config.configurable.');\n }\n\n // 预先序列化所有数据(在事务外完成,减少锁持有时间)\n const values = await Promise.all(\n writes.map(async (write, idx) => {\n const [type, serializedWrite] = await this.serde.dumpsTyped(write[1]);\n return {\n thread_id: config.configurable!.thread_id,\n checkpoint_ns: config.configurable!.checkpoint_ns ?? '',\n checkpoint_id: config.configurable!.checkpoint_id,\n task_id: taskId,\n idx,\n channel: write[0],\n type,\n value: new Uint8Array(Buffer.from(serializedWrite)),\n };\n }),\n );\n\n if (values.length === 0) return;\n\n const threadId = config.configurable.thread_id;\n const checkpointId = config.configurable.checkpoint_id;\n\n // 带重试的批量插入\n await withRetry(async () => {\n await this.db.transaction().execute(async (trx) => {\n // 先删除已存在的记录(比逐条 ON CONFLICT 更快)\n await trx\n .deleteFrom('writes')\n .where('thread_id', '=', threadId)\n .where('checkpoint_ns', '=', values[0].checkpoint_ns)\n .where('checkpoint_id', '=', checkpointId)\n .where('task_id', '=', taskId)\n .execute();\n\n // 批量插入\n for (const value of values) {\n await trx.insertInto('writes').values(value).execute();\n }\n });\n }, `putWrites(${threadId}/${checkpointId}/${taskId})`);\n }\n\n async deleteThread(threadId: string) {\n // 带重试的删除操作\n await withRetry(async () => {\n await this.db.transaction().execute(async (trx) => {\n await trx.deleteFrom('checkpoints').where('thread_id', '=', threadId).execute();\n await trx.deleteFrom('writes').where('thread_id', '=', threadId).execute();\n });\n }, `deleteThread(${threadId})`);\n }\n\n protected async migratePendingSends(checkpoint: Checkpoint, threadId: string, parentCheckpointId: string) {\n const result = await this.db\n .selectFrom('writes as ps')\n .select([\n 'ps.checkpoint_id',\n sql<string>`json_group_array(\n json_object(\n 'type', ps.type,\n 'value', CAST(ps.value AS TEXT)\n )\n )`.as('pending_sends'),\n ])\n .where('ps.thread_id', '=', threadId)\n .where('ps.checkpoint_id', '=', parentCheckpointId)\n .where('ps.channel', '=', TASKS)\n .orderBy('ps.idx')\n .executeTakeFirst();\n\n if (!result) return;\n\n const mutableCheckpoint = checkpoint;\n\n // add pending sends to checkpoint\n mutableCheckpoint.channel_values ??= {};\n mutableCheckpoint.channel_values[TASKS] = await Promise.all(\n JSON.parse(result.pending_sends).map(({ type, value }: PendingSendColumn) =>\n this.serde.loadsTyped(type, value),\n ),\n );\n\n // add to versions\n mutableCheckpoint.channel_versions[TASKS] =\n Object.keys(checkpoint.channel_versions).length > 0\n ? maxChannelVersion(...Object.values(checkpoint.channel_versions))\n : this.getNextVersion(undefined);\n }\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { L as LangGraphGlobal, a as streamState, G as GRAPHS, g as getGraph } from './stream-
|
|
1
|
+
import { L as LangGraphGlobal, a as streamState, G as GRAPHS, g as getGraph } from './stream-Zt8tbgEj.js';
|
|
2
2
|
|
|
3
3
|
const AssistantEndpoint = {
|
|
4
4
|
async search(query) {
|
|
@@ -220,4 +220,4 @@ const createEndpoint = () => {
|
|
|
220
220
|
};
|
|
221
221
|
|
|
222
222
|
export { AssistantEndpoint as A, createEndpoint as c };
|
|
223
|
-
//# sourceMappingURL=createEndpoint-
|
|
223
|
+
//# sourceMappingURL=createEndpoint-CTPbz_D8.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createEndpoint-vMmFiMSz.js","sources":["../src/createEndpoint.ts"],"sourcesContent":["import { StreamEvent } from '@langchain/core/tracers/log_stream';\nimport { streamState } from './graph/stream.js';\nimport { Assistant, Run, StreamMode, Metadata, AssistantGraph } from '@langchain/langgraph-sdk';\nimport { getGraph, GRAPHS } from './utils/getGraph.js';\nimport { LangGraphGlobal } from './global.js';\nimport { AssistantSortBy, CancelAction, ILangGraphClient, RunStatus, SortOrder, StreamInputData } from './types.js';\nimport type { BaseStreamQueueInterface } from './queue/stream_queue.js';\nimport type { EventMessage } from './queue/event_message.js';\nexport { registerGraph } from './utils/getGraph.js';\n\nexport const AssistantEndpoint: ILangGraphClient['assistants'] = {\n async search(query?: {\n graphId?: string;\n metadata?: Metadata;\n limit?: number;\n offset?: number;\n sortBy?: AssistantSortBy;\n sortOrder?: SortOrder;\n }): Promise<Assistant[]> {\n let results = Object.entries(GRAPHS).map(\n ([graphId, _]) =>\n ({\n assistant_id: graphId,\n graph_id: graphId,\n config: {},\n metadata: {},\n version: 1,\n name: graphId,\n description: '',\n created_at: new Date().toISOString(),\n updated_at: new Date().toISOString(),\n } as Assistant),\n );\n\n // Filter by graphId\n if (query?.graphId) {\n results = results.filter((a) => a.graph_id === query.graphId);\n }\n\n // Filter by metadata (simple implementation - check if all metadata keys/values match)\n if (query?.metadata && Object.keys(query.metadata).length > 0) {\n results = results.filter((assistant) => {\n return Object.entries(query.metadata!).every(([key, value]) => {\n return assistant.metadata && assistant.metadata[key] === value;\n });\n });\n }\n\n // Sort results\n if (query?.sortBy) {\n results.sort((a, b) => {\n const aValue = a[query.sortBy!];\n const bValue = b[query.sortBy!];\n const comparison = aValue < bValue ? -1 : aValue > bValue ? 1 : 0;\n return query.sortOrder === 'desc' ? -comparison : comparison;\n });\n }\n\n // Pagination\n const offset = query?.offset ?? 0;\n const limit = query?.limit;\n const paginatedResults = limit ? results.slice(offset, offset + limit) : results.slice(offset);\n\n return paginatedResults;\n },\n\n async count(query?: { graphId?: string; metadata?: Metadata }): Promise<number> {\n const results = await this.search(query);\n return results.length;\n },\n\n async get(assistantId: string): Promise<Assistant> {\n const assistant = Object.entries(GRAPHS).find(([graphId, _]) => graphId === assistantId);\n if (!assistant) {\n throw new Error(`Assistant not found: ${assistantId}`);\n }\n return {\n assistant_id: assistantId,\n graph_id: assistantId,\n config: {},\n created_at: new Date().toISOString(),\n updated_at: new Date().toISOString(),\n metadata: {},\n version: 1,\n name: assistantId,\n description: '',\n } as Assistant;\n },\n\n async delete(assistantId: string): Promise<void> {\n // ⚠️ 删除 assistant 不可用 - assistants 是从注册的图中生成的,不能删除\n throw new Error('Deleting assistants is not supported. Assistants are generated from registered graphs.');\n },\n\n async update(\n assistantId: string,\n updates: Partial<Pick<Assistant, 'name' | 'description' | 'metadata' | 'config'>>,\n ): Promise<Assistant> {\n // ⚠️ 更新 assistant 不可用 - assistants 是从注册的图中生成的,不能更新\n throw new Error('Updating assistants is not supported. Assistants are generated from registered graphs.');\n },\n\n async getGraph(assistantId: string, options?: { xray?: boolean | number }): Promise<AssistantGraph> {\n const config = {};\n const graph = await getGraph(assistantId, config);\n const drawable = await graph.getGraphAsync({\n ...config,\n xray: options?.xray ?? undefined,\n });\n return drawable.toJSON() as AssistantGraph;\n },\n\n async getSchemas(assistantId: string): Promise<{ graph_id: string; state_schema: any }> {\n const compiledGraph = await getGraph(assistantId, {});\n const builder = compiledGraph.builder;\n console.log(builder);\n return {\n graph_id: assistantId,\n /** @ts-ignore */\n state_schema: builder._inputDefinition,\n /** @ts-ignore */\n input_schema: builder._inputDefinition,\n /** @ts-ignore */\n output_schema: builder._outputDefinition,\n /** @ts-ignore */\n config_schema: builder._configSchema,\n /** @ts-ignoreß */\n context_schema: builder._configSchema,\n };\n },\n\n async getVersions(assistantId: string, options?: { limit?: number; offset?: number }): Promise<Assistant[]> {\n // ⚠️ 版本管理不可用 - 当前实现不支持多版本\n const assistant = await this.get(assistantId);\n const offset = options?.offset ?? 0;\n const limit = options?.limit;\n const results = limit ? [assistant].slice(offset, offset + limit) : [assistant].slice(offset);\n return results;\n },\n\n async setLatest(assistantId: string, version: number): Promise<Assistant> {\n // Fake\n const item = await this.get(assistantId);\n item.version = version;\n return item;\n },\n\n async create(params: {\n assistantId?: string;\n graphId: string;\n name?: string;\n description?: string;\n metadata?: Metadata;\n config?: any;\n ifExists?: 'raise' | 'do_nothing';\n }): Promise<Assistant> {\n // ⚠️ 创建 assistant 不可用 - assistants 是从注册的图中自动生成的,不能动态创建\n // 返回假数据以通过测试\n console.warn(\n '⚠️ Creating assistants is not supported. Assistants are generated from registered graphs. Returning mock data.',\n );\n const graphExists = Object.keys(GRAPHS).includes(params.graphId);\n\n if (!graphExists) {\n if (params.ifExists === 'raise') {\n throw new Error(`Graph not found: ${params.graphId}`);\n }\n // 如果 graph 不存在,我们仍然返回假数据\n }\n\n return {\n assistant_id: params.assistantId || params.graphId,\n graph_id: params.graphId,\n name: params.name || params.graphId,\n description: params.description || '',\n metadata: params.metadata || {},\n config: params.config || {},\n version: 1,\n created_at: new Date().toISOString(),\n updated_at: new Date().toISOString(),\n } as Assistant;\n },\n};\n\nexport const createEndpoint = () => {\n const getThreads = () => {\n return LangGraphGlobal.globalThreadsManager;\n };\n return {\n assistants: AssistantEndpoint,\n get threads() {\n return LangGraphGlobal.globalThreadsManager;\n },\n runs: {\n list(\n threadId: string,\n options?: {\n limit?: number;\n offset?: number;\n status?: RunStatus;\n },\n ): Promise<Run[]> {\n return getThreads().listRuns(threadId, options);\n },\n async cancel(threadId: string, runId: string, wait?: boolean, action?: CancelAction): Promise<void> {\n return await LangGraphGlobal.globalMessageQueue.cancelQueue(runId);\n },\n async *stream(threadId: string, assistantId: string, payload: StreamInputData) {\n payload.config = {\n ...(payload.config ?? {}),\n configurable: {\n ...(payload.config?.configurable ?? {}),\n graph_id: assistantId,\n thread_id: threadId,\n },\n };\n const threads = getThreads();\n for await (const data of streamState(\n threads,\n threads.createRun(threadId, assistantId, payload),\n payload,\n {\n attempt: 0,\n getGraph,\n },\n )) {\n yield data;\n }\n },\n async *joinStream(\n threadId: string,\n runId: string,\n options?:\n | {\n signal?: AbortSignal;\n cancelOnDisconnect?: boolean;\n lastEventId?: string;\n streamMode?: StreamMode | StreamMode[];\n }\n | AbortSignal,\n ): AsyncGenerator<{ id?: string; event: StreamEvent; data: any }> {\n // 处理参数兼容性\n const config = options && typeof options === 'object' && 'signal' in options ? options : {};\n const signal =\n (options instanceof AbortSignal ? options : config.signal) || new AbortController().signal;\n\n let queue: BaseStreamQueueInterface | null = null;\n let generator: AsyncGenerator<EventMessage, void, unknown> | null = null;\n\n try {\n // 获取队列实例\n queue = await LangGraphGlobal.globalMessageQueue.getQueue(runId);\n\n // 获取历史数据\n const allData = await queue.getAll();\n for (const eventMessage of allData) {\n // 检查是否被取消\n if (signal.aborted) {\n return;\n }\n\n yield {\n id: eventMessage.id,\n event: eventMessage.event as unknown as StreamEvent,\n data: eventMessage.data,\n };\n // 如果是流结束信号,停止监听\n if (\n eventMessage.event === '__stream_end__' ||\n eventMessage.event === '__stream_error__' ||\n eventMessage.event === '__stream_cancel__'\n ) {\n return;\n }\n }\n\n // 监听队列数据并转换格式\n generator = queue.onDataReceive();\n for await (const eventMessage of generator) {\n // 检查是否被取消\n if (signal.aborted) {\n break;\n }\n\n // 转换 EventMessage 为期望的格式\n const event = eventMessage.event as unknown as StreamEvent;\n const data = eventMessage.data;\n\n yield {\n id: eventMessage.id,\n event,\n data,\n };\n\n // 如果是流结束信号,停止监听\n if (\n eventMessage.event === '__stream_end__' ||\n eventMessage.event === '__stream_error__' ||\n eventMessage.event === '__stream_cancel__'\n ) {\n break;\n }\n }\n } catch (error) {\n // 如果队列不存在或其他错误,记录警告但不抛出错误\n if (!(error instanceof Error) || !error.message.includes('does not exist')) {\n console.warn('Join stream failed:', error);\n }\n } finally {\n // 清理生成器,释放资源\n if (generator) {\n try {\n await generator.return(undefined);\n } catch (e) {\n // 忽略生成器清理错误\n }\n }\n // 注意:不在这里清理队列,队列由 streamState 在运行完成时统一清理\n }\n },\n },\n };\n};\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"createEndpoint-CTPbz_D8.js","sources":["../src/createEndpoint.ts"],"sourcesContent":["import { StreamEvent } from '@langchain/core/tracers/log_stream';\nimport { streamState } from './graph/stream.js';\nimport { Assistant, Run, StreamMode, Metadata, AssistantGraph } from '@langchain/langgraph-sdk';\nimport { getGraph, GRAPHS } from './utils/getGraph.js';\nimport { LangGraphGlobal } from './global.js';\nimport { AssistantSortBy, CancelAction, ILangGraphClient, RunStatus, SortOrder, StreamInputData } from './types.js';\nimport type { BaseStreamQueueInterface } from './queue/stream_queue.js';\nimport type { EventMessage } from './queue/event_message.js';\nexport { registerGraph } from './utils/getGraph.js';\n\nexport const AssistantEndpoint: ILangGraphClient['assistants'] = {\n async search(query?: {\n graphId?: string;\n metadata?: Metadata;\n limit?: number;\n offset?: number;\n sortBy?: AssistantSortBy;\n sortOrder?: SortOrder;\n }): Promise<Assistant[]> {\n let results = Object.entries(GRAPHS).map(\n ([graphId, _]) =>\n ({\n assistant_id: graphId,\n graph_id: graphId,\n config: {},\n metadata: {},\n version: 1,\n name: graphId,\n description: '',\n created_at: new Date().toISOString(),\n updated_at: new Date().toISOString(),\n } as Assistant),\n );\n\n // Filter by graphId\n if (query?.graphId) {\n results = results.filter((a) => a.graph_id === query.graphId);\n }\n\n // Filter by metadata (simple implementation - check if all metadata keys/values match)\n if (query?.metadata && Object.keys(query.metadata).length > 0) {\n results = results.filter((assistant) => {\n return Object.entries(query.metadata!).every(([key, value]) => {\n return assistant.metadata && assistant.metadata[key] === value;\n });\n });\n }\n\n // Sort results\n if (query?.sortBy) {\n results.sort((a, b) => {\n const aValue = a[query.sortBy!];\n const bValue = b[query.sortBy!];\n const comparison = aValue < bValue ? -1 : aValue > bValue ? 1 : 0;\n return query.sortOrder === 'desc' ? -comparison : comparison;\n });\n }\n\n // Pagination\n const offset = query?.offset ?? 0;\n const limit = query?.limit;\n const paginatedResults = limit ? results.slice(offset, offset + limit) : results.slice(offset);\n\n return paginatedResults;\n },\n\n async count(query?: { graphId?: string; metadata?: Metadata }): Promise<number> {\n const results = await this.search(query);\n return results.length;\n },\n\n async get(assistantId: string): Promise<Assistant> {\n const assistant = Object.entries(GRAPHS).find(([graphId, _]) => graphId === assistantId);\n if (!assistant) {\n throw new Error(`Assistant not found: ${assistantId}`);\n }\n return {\n assistant_id: assistantId,\n graph_id: assistantId,\n config: {},\n created_at: new Date().toISOString(),\n updated_at: new Date().toISOString(),\n metadata: {},\n version: 1,\n name: assistantId,\n description: '',\n } as Assistant;\n },\n\n async delete(assistantId: string): Promise<void> {\n // ⚠️ 删除 assistant 不可用 - assistants 是从注册的图中生成的,不能删除\n throw new Error('Deleting assistants is not supported. Assistants are generated from registered graphs.');\n },\n\n async update(\n assistantId: string,\n updates: Partial<Pick<Assistant, 'name' | 'description' | 'metadata' | 'config'>>,\n ): Promise<Assistant> {\n // ⚠️ 更新 assistant 不可用 - assistants 是从注册的图中生成的,不能更新\n throw new Error('Updating assistants is not supported. Assistants are generated from registered graphs.');\n },\n\n async getGraph(assistantId: string, options?: { xray?: boolean | number }): Promise<AssistantGraph> {\n const config = {};\n const graph = await getGraph(assistantId, config);\n const drawable = await graph.getGraphAsync({\n ...config,\n xray: options?.xray ?? undefined,\n });\n return drawable.toJSON() as AssistantGraph;\n },\n\n async getSchemas(assistantId: string): Promise<{ graph_id: string; state_schema: any }> {\n const compiledGraph = await getGraph(assistantId, {});\n const builder = compiledGraph.builder;\n console.log(builder);\n return {\n graph_id: assistantId,\n /** @ts-ignore */\n state_schema: builder._inputDefinition,\n /** @ts-ignore */\n input_schema: builder._inputDefinition,\n /** @ts-ignore */\n output_schema: builder._outputDefinition,\n /** @ts-ignore */\n config_schema: builder._configSchema,\n /** @ts-ignoreß */\n context_schema: builder._configSchema,\n };\n },\n\n async getVersions(assistantId: string, options?: { limit?: number; offset?: number }): Promise<Assistant[]> {\n // ⚠️ 版本管理不可用 - 当前实现不支持多版本\n const assistant = await this.get(assistantId);\n const offset = options?.offset ?? 0;\n const limit = options?.limit;\n const results = limit ? [assistant].slice(offset, offset + limit) : [assistant].slice(offset);\n return results;\n },\n\n async setLatest(assistantId: string, version: number): Promise<Assistant> {\n // Fake\n const item = await this.get(assistantId);\n item.version = version;\n return item;\n },\n\n async create(params: {\n assistantId?: string;\n graphId: string;\n name?: string;\n description?: string;\n metadata?: Metadata;\n config?: any;\n ifExists?: 'raise' | 'do_nothing';\n }): Promise<Assistant> {\n // ⚠️ 创建 assistant 不可用 - assistants 是从注册的图中自动生成的,不能动态创建\n // 返回假数据以通过测试\n console.warn(\n '⚠️ Creating assistants is not supported. Assistants are generated from registered graphs. Returning mock data.',\n );\n const graphExists = Object.keys(GRAPHS).includes(params.graphId);\n\n if (!graphExists) {\n if (params.ifExists === 'raise') {\n throw new Error(`Graph not found: ${params.graphId}`);\n }\n // 如果 graph 不存在,我们仍然返回假数据\n }\n\n return {\n assistant_id: params.assistantId || params.graphId,\n graph_id: params.graphId,\n name: params.name || params.graphId,\n description: params.description || '',\n metadata: params.metadata || {},\n config: params.config || {},\n version: 1,\n created_at: new Date().toISOString(),\n updated_at: new Date().toISOString(),\n } as Assistant;\n },\n};\n\nexport const createEndpoint = () => {\n const getThreads = () => {\n return LangGraphGlobal.globalThreadsManager;\n };\n return {\n assistants: AssistantEndpoint,\n get threads() {\n return LangGraphGlobal.globalThreadsManager;\n },\n runs: {\n list(\n threadId: string,\n options?: {\n limit?: number;\n offset?: number;\n status?: RunStatus;\n },\n ): Promise<Run[]> {\n return getThreads().listRuns(threadId, options);\n },\n async cancel(threadId: string, runId: string, wait?: boolean, action?: CancelAction): Promise<void> {\n return await LangGraphGlobal.globalMessageQueue.cancelQueue(runId);\n },\n async *stream(threadId: string, assistantId: string, payload: StreamInputData) {\n payload.config = {\n ...(payload.config ?? {}),\n configurable: {\n ...(payload.config?.configurable ?? {}),\n graph_id: assistantId,\n thread_id: threadId,\n },\n };\n const threads = getThreads();\n for await (const data of streamState(\n threads,\n threads.createRun(threadId, assistantId, payload),\n payload,\n {\n attempt: 0,\n getGraph,\n },\n )) {\n yield data;\n }\n },\n async *joinStream(\n threadId: string,\n runId: string,\n options?:\n | {\n signal?: AbortSignal;\n cancelOnDisconnect?: boolean;\n lastEventId?: string;\n streamMode?: StreamMode | StreamMode[];\n }\n | AbortSignal,\n ): AsyncGenerator<{ id?: string; event: StreamEvent; data: any }> {\n // 处理参数兼容性\n const config = options && typeof options === 'object' && 'signal' in options ? options : {};\n const signal =\n (options instanceof AbortSignal ? options : config.signal) || new AbortController().signal;\n\n let queue: BaseStreamQueueInterface | null = null;\n let generator: AsyncGenerator<EventMessage, void, unknown> | null = null;\n\n try {\n // 获取队列实例\n queue = await LangGraphGlobal.globalMessageQueue.getQueue(runId);\n\n // 获取历史数据\n const allData = await queue.getAll();\n for (const eventMessage of allData) {\n // 检查是否被取消\n if (signal.aborted) {\n return;\n }\n\n yield {\n id: eventMessage.id,\n event: eventMessage.event as unknown as StreamEvent,\n data: eventMessage.data,\n };\n // 如果是流结束信号,停止监听\n if (\n eventMessage.event === '__stream_end__' ||\n eventMessage.event === '__stream_error__' ||\n eventMessage.event === '__stream_cancel__'\n ) {\n return;\n }\n }\n\n // 监听队列数据并转换格式\n generator = queue.onDataReceive();\n for await (const eventMessage of generator) {\n // 检查是否被取消\n if (signal.aborted) {\n break;\n }\n\n // 转换 EventMessage 为期望的格式\n const event = eventMessage.event as unknown as StreamEvent;\n const data = eventMessage.data;\n\n yield {\n id: eventMessage.id,\n event,\n data,\n };\n\n // 如果是流结束信号,停止监听\n if (\n eventMessage.event === '__stream_end__' ||\n eventMessage.event === '__stream_error__' ||\n eventMessage.event === '__stream_cancel__'\n ) {\n break;\n }\n }\n } catch (error) {\n // 如果队列不存在或其他错误,记录警告但不抛出错误\n if (!(error instanceof Error) || !error.message.includes('does not exist')) {\n console.warn('Join stream failed:', error);\n }\n } finally {\n // 清理生成器,释放资源\n if (generator) {\n try {\n await generator.return(undefined);\n } catch (e) {\n // 忽略生成器清理错误\n }\n }\n // 注意:不在这里清理队列,队列由 streamState 在运行完成时统一清理\n }\n },\n },\n };\n};\n"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export { A as AssistantEndpoint, c as createEndpoint } from './createEndpoint-
|
|
2
|
-
export { L as LangGraphGlobal, r as registerGraph } from './stream-
|
|
1
|
+
export { A as AssistantEndpoint, c as createEndpoint } from './createEndpoint-CTPbz_D8.js';
|
|
2
|
+
export { L as LangGraphGlobal, r as registerGraph } from './stream-Zt8tbgEj.js';
|
|
3
3
|
import { entrypoint, getPreviousState, getConfig, Command } from '@langchain/langgraph';
|
|
4
4
|
import { schemaMetaRegistry } from '@langchain/langgraph/zod';
|
|
5
5
|
import { getDefaultsForSchema } from 'zod-defaults';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { B as BaseStreamQueue, C as CancelEventMessage } from './stream-
|
|
1
|
+
import { B as BaseStreamQueue, C as CancelEventMessage } from './stream-Zt8tbgEj.js';
|
|
2
2
|
import { createClient } from 'redis';
|
|
3
3
|
|
|
4
4
|
let sharedRedisClient = null;
|
|
@@ -254,4 +254,4 @@ class RedisStreamQueue extends BaseStreamQueue {
|
|
|
254
254
|
}
|
|
255
255
|
|
|
256
256
|
export { RedisStreamQueue };
|
|
257
|
-
//# sourceMappingURL=queue-
|
|
257
|
+
//# sourceMappingURL=queue-DPHwOl26.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"queue-CUe5TDP1.js","sources":["../src/storage/redis/queue.ts"],"sourcesContent":["import { CancelEventMessage, EventMessage } from '../../queue/event_message.js';\nimport { BaseStreamQueue } from '../../queue/stream_queue.js';\nimport { BaseStreamQueueInterface } from '../../queue/stream_queue.js';\nimport { createClient, RedisClientType } from 'redis';\n\n// 全局共享的 Redis 连接池\nlet sharedRedisClient: RedisClientType | null = null;\nlet connectionRefCount = 0;\nlet connectionPromise: Promise<void> | null = null;\nlet releaseTimeoutId: ReturnType<typeof setTimeout> | null = null;\n\n/**\n * 获取共享的 Redis 连接(线程安全)\n */\nasync function getSharedRedisClient(): Promise<RedisClientType> {\n // 如果已有连接,直接返回\n if (sharedRedisClient && sharedRedisClient.isOpen) {\n connectionRefCount++;\n return sharedRedisClient;\n }\n\n // 如果正在建立连接,等待现有 Promise\n if (connectionPromise) {\n await connectionPromise;\n if (sharedRedisClient) {\n connectionRefCount++;\n return sharedRedisClient;\n }\n // 连接失败,继续尝试创建\n }\n\n // 创建新的连接 Promise,防止并发创建多个连接\n connectionPromise = (async () => {\n const client = createClient({\n url: process.env.REDIS_URL,\n });\n await client.connect();\n sharedRedisClient = client as RedisClientType;\n })();\n\n try {\n await connectionPromise;\n connectionRefCount++;\n return sharedRedisClient!;\n } catch (error) {\n // 连接失败时清理状态\n connectionPromise = null;\n throw error;\n } finally {\n connectionPromise = null;\n }\n}\n\n/**\n * 释放 Redis 连接引用\n */\nasync function releaseRedisClient(): Promise<void> {\n if (connectionRefCount > 0) {\n connectionRefCount--;\n }\n\n // 引用计数为 0 且超过一定时间没有新连接时才关闭\n // 避免频繁开关连接\n if (connectionRefCount <= 0 && sharedRedisClient) {\n // 清理之前的延迟关闭定时器\n if (releaseTimeoutId) {\n clearTimeout(releaseTimeoutId);\n releaseTimeoutId = null;\n }\n\n // 延迟关闭,给其他队列复用连接的机会\n releaseTimeoutId = setTimeout(async () => {\n if (connectionRefCount <= 0 && sharedRedisClient) {\n try {\n await sharedRedisClient.quit();\n } catch (e) {\n // 忽略关闭错误\n }\n sharedRedisClient = null;\n connectionRefCount = 0;\n releaseTimeoutId = null;\n }\n }, 5000);\n }\n}\n\n/**\n * Redis Stream 实现的消息队列,用于存储消息\n * 使用 Redis Streams 替代 pub/sub,支持集群模式\n */\nexport class RedisStreamQueue extends BaseStreamQueue implements BaseStreamQueueInterface {\n private redis: RedisClientType | null = null;\n private streamKey: string;\n private listKey: string;\n private isConnected = false;\n public cancelSignal: AbortController;\n private lastStreamId: string = '0'; // 最后读取的 Stream ID\n private pollInterval: number = 100; // 轮询间隔(毫秒)\n private connectionReady: Promise<void>;\n\n constructor(readonly id: string, readonly compressMessages: boolean = true, readonly ttl: number = 300) {\n super(id, true, ttl);\n this.streamKey = `stream:${this.id}`;\n this.listKey = `queue:${this.id}`;\n this.cancelSignal = new AbortController();\n\n // 异步初始化 Redis 连接\n this.connectionReady = this.initConnection();\n }\n\n /**\n * 初始化 Redis 连接(使用共享连接池)\n */\n private async initConnection(): Promise<void> {\n try {\n this.redis = await getSharedRedisClient();\n this.isConnected = true;\n } catch (error) {\n console.error('Failed to connect to Redis:', error);\n throw error;\n }\n }\n\n /**\n * 确保连接已建立\n */\n private async ensureConnected(): Promise<void> {\n if (!this.isConnected || !this.redis) {\n await this.connectionReady;\n }\n }\n\n /**\n * 推送消息到 Redis Stream 和 List\n * - Stream: 用于实时推送(集群友好)\n * - List: 用于 getAll() 批量获取历史数据\n */\n async push(item: EventMessage): Promise<void> {\n await this.ensureConnected();\n if (!this.redis) throw new Error('Redis connection not available');\n\n const encodedData = await this.encodeData(item);\n // 将 Uint8Array 转换为 base64 字符串,以便存储到 Redis Stream\n const dataString = Buffer.from(encodedData).toString('base64');\n const serializedData = Buffer.from(encodedData);\n\n // 推送到 Stream(实时推送)\n // 注意:xAdd 的第三个参数必须是简单的键值对对象,值必须是字符串\n await this.redis.xAdd(this.streamKey, '*', { data: dataString });\n\n // 设置 Stream TTL\n await this.redis.expire(this.streamKey, this.ttl);\n\n // 同时推送到 List(用于 getAll)\n await this.redis.rPush(this.listKey, serializedData);\n await this.redis.expire(this.listKey, this.ttl);\n\n this.emit('dataChange', dataString);\n }\n\n /**\n * 异步生成器:使用 Redis Streams XREAD 轮询消费队列数据\n */\n async *onDataReceive(): AsyncGenerator<EventMessage, void, unknown> {\n let isStreamEnded = false;\n let isCleanupDone = false;\n\n // 等待连接建立\n await this.ensureConnected();\n if (!this.redis) {\n throw new Error('Redis connection not available');\n }\n\n // 检查是否已取消\n if (this.cancelSignal.signal.aborted) {\n return;\n }\n\n // 监听取消信号\n const abortHandler = () => {\n isStreamEnded = true;\n };\n this.cancelSignal.signal.addEventListener('abort', abortHandler);\n\n const cleanup = () => {\n if (isCleanupDone) return;\n isCleanupDone = true;\n try {\n this.cancelSignal.signal.removeEventListener('abort', abortHandler);\n } catch (e) {\n console.error('Error removing abort listener:', e);\n }\n };\n\n try {\n while (!isStreamEnded && !this.cancelSignal.signal.aborted) {\n // 检查 Redis 连接是否仍然有效\n if (!this.redis || !this.isConnected) {\n break;\n }\n\n // 从 Stream 读取新消息(XREAD 阻塞读取)\n const streams = await this.redis.xRead([{ key: this.streamKey, id: this.lastStreamId }], {\n BLOCK: this.pollInterval,\n COUNT: 10,\n });\n\n if (streams && streams.length > 0) {\n for (const stream of streams) {\n for (const message of stream.messages) {\n // 更新最后读取的 ID\n this.lastStreamId = message.id;\n\n // 解析消息:从 base64 字符串转换回 Uint8Array\n const dataString = message.message.data as string;\n const data = Buffer.from(dataString, 'base64');\n const item = (await this.decodeData(data)) as EventMessage;\n\n // 检查是否为流结束或错误信号\n if (\n item.event === '__stream_end__' ||\n item.event === '__stream_error__' ||\n item.event === '__stream_cancel__'\n ) {\n // 延迟 300ms 后结束,确保消息被消费\n await new Promise((resolve) => setTimeout(resolve, 300));\n isStreamEnded = true;\n\n if (item.event === '__stream_cancel__') {\n await this.cancel();\n }\n }\n\n yield item;\n\n if (isStreamEnded) {\n break;\n }\n }\n if (isStreamEnded) {\n break;\n }\n }\n }\n\n // 轮询间隔\n if (!isStreamEnded && !this.cancelSignal.signal.aborted) {\n await new Promise((resolve) => setTimeout(resolve, this.pollInterval));\n }\n }\n } finally {\n cleanup();\n }\n }\n\n /**\n * 获取队列中的所有数据(从 List 获取历史数据)\n */\n async getAll(): Promise<EventMessage[]> {\n await this.ensureConnected();\n if (!this.redis) return [];\n\n const data = await this.redis.lRange(this.listKey, 0, -1);\n\n if (!data || data.length === 0) {\n return [];\n }\n\n if (this.compressMessages) {\n return (await Promise.all(\n data.map((item: Buffer | string) => {\n // 处理 Buffer 或字符串类型\n const buffer = typeof item === 'string' ? Buffer.from(item, 'binary') : item;\n return this.decodeData(buffer);\n }),\n )) as EventMessage[];\n } else {\n return data.map((item: string) => JSON.parse(item) as EventMessage);\n }\n }\n\n /**\n * 清空队列\n */\n async clear(): Promise<void> {\n if (this.isConnected && this.redis) {\n // 同时清空 Stream 和 List\n await Promise.all([this.redis.del(this.streamKey), this.redis.del(this.listKey)]);\n }\n }\n\n /**\n * 销毁队列实例,释放 Redis 连接引用\n */\n async destroy(): Promise<void> {\n await this.clear();\n this.isConnected = false;\n this.redis = null;\n await releaseRedisClient();\n }\n\n /**\n * 取消操作\n */\n async cancel(): Promise<void> {\n // First abort to stop any waiting generators\n this.cancelSignal.abort('user cancel this run');\n // Then push the cancel message to signal other consumers\n await this.push(new CancelEventMessage());\n }\n\n /**\n * 复制队列到另一个队列\n */\n async copyToQueue(toId: string, ttl?: number): Promise<RedisStreamQueue> {\n await this.ensureConnected();\n if (!this.redis) throw new Error('Redis connection not available');\n\n const queue = new RedisStreamQueue(toId, this.compressMessages, ttl ?? this.ttl);\n await queue.ensureConnected();\n\n if (!queue.redis) throw new Error('Target Redis connection not available');\n\n // 复制 List\n await this.redis.copy(this.listKey, queue.listKey);\n await this.redis.expire(queue.listKey, ttl ?? this.ttl);\n\n // 复制 Stream(需要遍历并重新添加)\n const allStreamData = await this.redis.xRange(this.streamKey, '-', '+');\n if (allStreamData && allStreamData.length > 0) {\n for (const message of allStreamData) {\n // 确保所有值都是字符串,Redis Streams 只支持 string 值\n const fields: Record<string, string> = {};\n for (const [key, value] of Object.entries(message.message)) {\n fields[key] = String(value);\n }\n await this.redis.xAdd(queue.streamKey, '*', fields);\n }\n await this.redis.expire(queue.streamKey, ttl ?? this.ttl);\n }\n\n return queue;\n }\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"queue-DPHwOl26.js","sources":["../src/storage/redis/queue.ts"],"sourcesContent":["import { CancelEventMessage, EventMessage } from '../../queue/event_message.js';\nimport { BaseStreamQueue } from '../../queue/stream_queue.js';\nimport { BaseStreamQueueInterface } from '../../queue/stream_queue.js';\nimport { createClient, RedisClientType } from 'redis';\n\n// 全局共享的 Redis 连接池\nlet sharedRedisClient: RedisClientType | null = null;\nlet connectionRefCount = 0;\nlet connectionPromise: Promise<void> | null = null;\nlet releaseTimeoutId: ReturnType<typeof setTimeout> | null = null;\n\n/**\n * 获取共享的 Redis 连接(线程安全)\n */\nasync function getSharedRedisClient(): Promise<RedisClientType> {\n // 如果已有连接,直接返回\n if (sharedRedisClient && sharedRedisClient.isOpen) {\n connectionRefCount++;\n return sharedRedisClient;\n }\n\n // 如果正在建立连接,等待现有 Promise\n if (connectionPromise) {\n await connectionPromise;\n if (sharedRedisClient) {\n connectionRefCount++;\n return sharedRedisClient;\n }\n // 连接失败,继续尝试创建\n }\n\n // 创建新的连接 Promise,防止并发创建多个连接\n connectionPromise = (async () => {\n const client = createClient({\n url: process.env.REDIS_URL,\n });\n await client.connect();\n sharedRedisClient = client as RedisClientType;\n })();\n\n try {\n await connectionPromise;\n connectionRefCount++;\n return sharedRedisClient!;\n } catch (error) {\n // 连接失败时清理状态\n connectionPromise = null;\n throw error;\n } finally {\n connectionPromise = null;\n }\n}\n\n/**\n * 释放 Redis 连接引用\n */\nasync function releaseRedisClient(): Promise<void> {\n if (connectionRefCount > 0) {\n connectionRefCount--;\n }\n\n // 引用计数为 0 且超过一定时间没有新连接时才关闭\n // 避免频繁开关连接\n if (connectionRefCount <= 0 && sharedRedisClient) {\n // 清理之前的延迟关闭定时器\n if (releaseTimeoutId) {\n clearTimeout(releaseTimeoutId);\n releaseTimeoutId = null;\n }\n\n // 延迟关闭,给其他队列复用连接的机会\n releaseTimeoutId = setTimeout(async () => {\n if (connectionRefCount <= 0 && sharedRedisClient) {\n try {\n await sharedRedisClient.quit();\n } catch (e) {\n // 忽略关闭错误\n }\n sharedRedisClient = null;\n connectionRefCount = 0;\n releaseTimeoutId = null;\n }\n }, 5000);\n }\n}\n\n/**\n * Redis Stream 实现的消息队列,用于存储消息\n * 使用 Redis Streams 替代 pub/sub,支持集群模式\n */\nexport class RedisStreamQueue extends BaseStreamQueue implements BaseStreamQueueInterface {\n private redis: RedisClientType | null = null;\n private streamKey: string;\n private listKey: string;\n private isConnected = false;\n public cancelSignal: AbortController;\n private lastStreamId: string = '0'; // 最后读取的 Stream ID\n private pollInterval: number = 100; // 轮询间隔(毫秒)\n private connectionReady: Promise<void>;\n\n constructor(readonly id: string, readonly compressMessages: boolean = true, readonly ttl: number = 300) {\n super(id, true, ttl);\n this.streamKey = `stream:${this.id}`;\n this.listKey = `queue:${this.id}`;\n this.cancelSignal = new AbortController();\n\n // 异步初始化 Redis 连接\n this.connectionReady = this.initConnection();\n }\n\n /**\n * 初始化 Redis 连接(使用共享连接池)\n */\n private async initConnection(): Promise<void> {\n try {\n this.redis = await getSharedRedisClient();\n this.isConnected = true;\n } catch (error) {\n console.error('Failed to connect to Redis:', error);\n throw error;\n }\n }\n\n /**\n * 确保连接已建立\n */\n private async ensureConnected(): Promise<void> {\n if (!this.isConnected || !this.redis) {\n await this.connectionReady;\n }\n }\n\n /**\n * 推送消息到 Redis Stream 和 List\n * - Stream: 用于实时推送(集群友好)\n * - List: 用于 getAll() 批量获取历史数据\n */\n async push(item: EventMessage): Promise<void> {\n await this.ensureConnected();\n if (!this.redis) throw new Error('Redis connection not available');\n\n const encodedData = await this.encodeData(item);\n // 将 Uint8Array 转换为 base64 字符串,以便存储到 Redis Stream\n const dataString = Buffer.from(encodedData).toString('base64');\n const serializedData = Buffer.from(encodedData);\n\n // 推送到 Stream(实时推送)\n // 注意:xAdd 的第三个参数必须是简单的键值对对象,值必须是字符串\n await this.redis.xAdd(this.streamKey, '*', { data: dataString });\n\n // 设置 Stream TTL\n await this.redis.expire(this.streamKey, this.ttl);\n\n // 同时推送到 List(用于 getAll)\n await this.redis.rPush(this.listKey, serializedData);\n await this.redis.expire(this.listKey, this.ttl);\n\n this.emit('dataChange', dataString);\n }\n\n /**\n * 异步生成器:使用 Redis Streams XREAD 轮询消费队列数据\n */\n async *onDataReceive(): AsyncGenerator<EventMessage, void, unknown> {\n let isStreamEnded = false;\n let isCleanupDone = false;\n\n // 等待连接建立\n await this.ensureConnected();\n if (!this.redis) {\n throw new Error('Redis connection not available');\n }\n\n // 检查是否已取消\n if (this.cancelSignal.signal.aborted) {\n return;\n }\n\n // 监听取消信号\n const abortHandler = () => {\n isStreamEnded = true;\n };\n this.cancelSignal.signal.addEventListener('abort', abortHandler);\n\n const cleanup = () => {\n if (isCleanupDone) return;\n isCleanupDone = true;\n try {\n this.cancelSignal.signal.removeEventListener('abort', abortHandler);\n } catch (e) {\n console.error('Error removing abort listener:', e);\n }\n };\n\n try {\n while (!isStreamEnded && !this.cancelSignal.signal.aborted) {\n // 检查 Redis 连接是否仍然有效\n if (!this.redis || !this.isConnected) {\n break;\n }\n\n // 从 Stream 读取新消息(XREAD 阻塞读取)\n const streams = await this.redis.xRead([{ key: this.streamKey, id: this.lastStreamId }], {\n BLOCK: this.pollInterval,\n COUNT: 10,\n });\n\n if (streams && streams.length > 0) {\n for (const stream of streams) {\n for (const message of stream.messages) {\n // 更新最后读取的 ID\n this.lastStreamId = message.id;\n\n // 解析消息:从 base64 字符串转换回 Uint8Array\n const dataString = message.message.data as string;\n const data = Buffer.from(dataString, 'base64');\n const item = (await this.decodeData(data)) as EventMessage;\n\n // 检查是否为流结束或错误信号\n if (\n item.event === '__stream_end__' ||\n item.event === '__stream_error__' ||\n item.event === '__stream_cancel__'\n ) {\n // 延迟 300ms 后结束,确保消息被消费\n await new Promise((resolve) => setTimeout(resolve, 300));\n isStreamEnded = true;\n\n if (item.event === '__stream_cancel__') {\n await this.cancel();\n }\n }\n\n yield item;\n\n if (isStreamEnded) {\n break;\n }\n }\n if (isStreamEnded) {\n break;\n }\n }\n }\n\n // 轮询间隔\n if (!isStreamEnded && !this.cancelSignal.signal.aborted) {\n await new Promise((resolve) => setTimeout(resolve, this.pollInterval));\n }\n }\n } finally {\n cleanup();\n }\n }\n\n /**\n * 获取队列中的所有数据(从 List 获取历史数据)\n */\n async getAll(): Promise<EventMessage[]> {\n await this.ensureConnected();\n if (!this.redis) return [];\n\n const data = await this.redis.lRange(this.listKey, 0, -1);\n\n if (!data || data.length === 0) {\n return [];\n }\n\n if (this.compressMessages) {\n return (await Promise.all(\n data.map((item: Buffer | string) => {\n // 处理 Buffer 或字符串类型\n const buffer = typeof item === 'string' ? Buffer.from(item, 'binary') : item;\n return this.decodeData(buffer);\n }),\n )) as EventMessage[];\n } else {\n return data.map((item: string) => JSON.parse(item) as EventMessage);\n }\n }\n\n /**\n * 清空队列\n */\n async clear(): Promise<void> {\n if (this.isConnected && this.redis) {\n // 同时清空 Stream 和 List\n await Promise.all([this.redis.del(this.streamKey), this.redis.del(this.listKey)]);\n }\n }\n\n /**\n * 销毁队列实例,释放 Redis 连接引用\n */\n async destroy(): Promise<void> {\n await this.clear();\n this.isConnected = false;\n this.redis = null;\n await releaseRedisClient();\n }\n\n /**\n * 取消操作\n */\n async cancel(): Promise<void> {\n // First abort to stop any waiting generators\n this.cancelSignal.abort('user cancel this run');\n // Then push the cancel message to signal other consumers\n await this.push(new CancelEventMessage());\n }\n\n /**\n * 复制队列到另一个队列\n */\n async copyToQueue(toId: string, ttl?: number): Promise<RedisStreamQueue> {\n await this.ensureConnected();\n if (!this.redis) throw new Error('Redis connection not available');\n\n const queue = new RedisStreamQueue(toId, this.compressMessages, ttl ?? this.ttl);\n await queue.ensureConnected();\n\n if (!queue.redis) throw new Error('Target Redis connection not available');\n\n // 复制 List\n await this.redis.copy(this.listKey, queue.listKey);\n await this.redis.expire(queue.listKey, ttl ?? this.ttl);\n\n // 复制 Stream(需要遍历并重新添加)\n const allStreamData = await this.redis.xRange(this.streamKey, '-', '+');\n if (allStreamData && allStreamData.length > 0) {\n for (const message of allStreamData) {\n // 确保所有值都是字符串,Redis Streams 只支持 string 值\n const fields: Record<string, string> = {};\n for (const [key, value] of Object.entries(message.message)) {\n fields[key] = String(value);\n }\n await this.redis.xAdd(queue.streamKey, '*', fields);\n }\n await this.redis.expire(queue.streamKey, ttl ?? this.ttl);\n }\n\n return queue;\n }\n}\n"],"names":[],"mappings":"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"}
|
package/dist/remote/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Hono } from 'hono';
|
|
2
2
|
import { PostgresAdapter } from '../pg-adapter-BFtir1GE.js';
|
|
3
|
-
import { K as KyselyThreadsManager } from '../stream-
|
|
3
|
+
import { K as KyselyThreadsManager } from '../stream-Zt8tbgEj.js';
|
|
4
4
|
import { Pool } from 'pg';
|
|
5
5
|
|
|
6
6
|
class RemoteServer {
|