agent-world 0.11.1 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +17 -7
- package/dist/cli/commands.d.ts +109 -0
- package/dist/cli/commands.js +2024 -0
- package/dist/cli/display.d.ts +124 -0
- package/dist/cli/display.js +381 -0
- package/dist/cli/hitl.d.ts +33 -0
- package/dist/cli/hitl.js +81 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/stream.d.ts +41 -0
- package/dist/cli/stream.js +222 -0
- package/dist/core/activity-tracker.d.ts +16 -0
- package/dist/core/activity-tracker.d.ts.map +1 -0
- package/dist/core/activity-tracker.js +91 -0
- package/dist/core/activity-tracker.js.map +1 -0
- package/dist/core/ai-commands.d.ts +16 -0
- package/dist/core/ai-commands.d.ts.map +1 -0
- package/dist/core/ai-commands.js +24 -0
- package/dist/core/ai-commands.js.map +1 -0
- package/dist/core/ai-sdk-patch.d.ts +24 -0
- package/dist/core/ai-sdk-patch.d.ts.map +1 -0
- package/dist/core/ai-sdk-patch.js +169 -0
- package/dist/core/ai-sdk-patch.js.map +1 -0
- package/dist/core/anthropic-direct.d.ts +52 -0
- package/dist/core/anthropic-direct.d.ts.map +1 -0
- package/dist/core/anthropic-direct.js +301 -0
- package/dist/core/anthropic-direct.js.map +1 -0
- package/dist/core/approval-cache.d.ts +104 -0
- package/dist/core/approval-cache.d.ts.map +1 -0
- package/dist/core/approval-cache.js +150 -0
- package/dist/core/approval-cache.js.map +1 -0
- package/dist/core/chat-constants.d.ts +20 -0
- package/dist/core/chat-constants.d.ts.map +1 -0
- package/dist/core/chat-constants.js +22 -0
- package/dist/core/chat-constants.js.map +1 -0
- package/dist/core/create-agent-tool.d.ts +66 -0
- package/dist/core/create-agent-tool.d.ts.map +1 -0
- package/dist/core/create-agent-tool.js +212 -0
- package/dist/core/create-agent-tool.js.map +1 -0
- package/dist/core/events/approval-checker.d.ts +61 -0
- package/dist/core/events/approval-checker.d.ts.map +1 -0
- package/dist/core/events/approval-checker.js +226 -0
- package/dist/core/events/approval-checker.js.map +1 -0
- package/dist/core/events/index.d.ts +25 -0
- package/dist/core/events/index.d.ts.map +1 -0
- package/dist/core/events/index.js +30 -0
- package/dist/core/events/index.js.map +1 -0
- package/dist/core/events/memory-manager.d.ts +73 -0
- package/dist/core/events/memory-manager.d.ts.map +1 -0
- package/dist/core/events/memory-manager.js +1218 -0
- package/dist/core/events/memory-manager.js.map +1 -0
- package/dist/core/events/mention-logic.d.ts +39 -0
- package/dist/core/events/mention-logic.d.ts.map +1 -0
- package/dist/core/events/mention-logic.js +163 -0
- package/dist/core/events/mention-logic.js.map +1 -0
- package/dist/core/events/orchestrator.d.ts +69 -0
- package/dist/core/events/orchestrator.d.ts.map +1 -0
- package/dist/core/events/orchestrator.js +883 -0
- package/dist/core/events/orchestrator.js.map +1 -0
- package/dist/core/events/persistence.d.ts +41 -0
- package/dist/core/events/persistence.d.ts.map +1 -0
- package/dist/core/events/persistence.js +296 -0
- package/dist/core/events/persistence.js.map +1 -0
- package/dist/core/events/publishers.d.ts +81 -0
- package/dist/core/events/publishers.d.ts.map +1 -0
- package/dist/core/events/publishers.js +272 -0
- package/dist/core/events/publishers.js.map +1 -0
- package/dist/core/events/subscribers.d.ts +45 -0
- package/dist/core/events/subscribers.d.ts.map +1 -0
- package/dist/core/events/subscribers.js +288 -0
- package/dist/core/events/subscribers.js.map +1 -0
- package/dist/core/events/tool-bridge-logging.d.ts +28 -0
- package/dist/core/events/tool-bridge-logging.d.ts.map +1 -0
- package/dist/core/events/tool-bridge-logging.js +94 -0
- package/dist/core/events/tool-bridge-logging.js.map +1 -0
- package/dist/core/events-metadata.d.ts +72 -0
- package/dist/core/events-metadata.d.ts.map +1 -0
- package/dist/core/events-metadata.js +167 -0
- package/dist/core/events-metadata.js.map +1 -0
- package/dist/core/events.d.ts +186 -0
- package/dist/core/events.d.ts.map +1 -0
- package/dist/core/events.js +1248 -0
- package/dist/core/events.js.map +1 -0
- package/dist/core/export.d.ts +106 -0
- package/dist/core/export.d.ts.map +1 -0
- package/dist/core/export.js +705 -0
- package/dist/core/export.js.map +1 -0
- package/dist/core/file-tools.d.ts +114 -0
- package/dist/core/file-tools.d.ts.map +1 -0
- package/dist/core/file-tools.js +370 -0
- package/dist/core/file-tools.js.map +1 -0
- package/dist/core/google-direct.d.ts +58 -0
- package/dist/core/google-direct.d.ts.map +1 -0
- package/dist/core/google-direct.js +298 -0
- package/dist/core/google-direct.js.map +1 -0
- package/dist/core/hitl.d.ts +54 -0
- package/dist/core/hitl.d.ts.map +1 -0
- package/dist/core/hitl.js +153 -0
- package/dist/core/hitl.js.map +1 -0
- package/dist/core/index.d.ts +59 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +70 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/llm-config.d.ts +128 -0
- package/dist/core/llm-config.d.ts.map +1 -0
- package/dist/core/llm-config.js +164 -0
- package/dist/core/llm-config.js.map +1 -0
- package/dist/core/llm-manager.d.ts +163 -0
- package/dist/core/llm-manager.d.ts.map +1 -0
- package/dist/core/llm-manager.js +669 -0
- package/dist/core/llm-manager.js.map +1 -0
- package/dist/core/load-skill-tool.d.ts +55 -0
- package/dist/core/load-skill-tool.d.ts.map +1 -0
- package/dist/core/load-skill-tool.js +468 -0
- package/dist/core/load-skill-tool.js.map +1 -0
- package/dist/core/logger.d.ts +88 -0
- package/dist/core/logger.d.ts.map +1 -0
- package/dist/core/logger.js +358 -0
- package/dist/core/logger.js.map +1 -0
- package/dist/core/managers.d.ts +131 -0
- package/dist/core/managers.d.ts.map +1 -0
- package/dist/core/managers.js +1223 -0
- package/dist/core/managers.js.map +1 -0
- package/dist/core/mcp-server-registry.d.ts +304 -0
- package/dist/core/mcp-server-registry.d.ts.map +1 -0
- package/dist/core/mcp-server-registry.js +1769 -0
- package/dist/core/mcp-server-registry.js.map +1 -0
- package/dist/core/mcp-tools.d.ts +56 -0
- package/dist/core/mcp-tools.d.ts.map +1 -0
- package/dist/core/mcp-tools.js +186 -0
- package/dist/core/mcp-tools.js.map +1 -0
- package/dist/core/message-prep.d.ts +81 -0
- package/dist/core/message-prep.d.ts.map +1 -0
- package/dist/core/message-prep.js +223 -0
- package/dist/core/message-prep.js.map +1 -0
- package/dist/core/message-processing-control.d.ts +54 -0
- package/dist/core/message-processing-control.d.ts.map +1 -0
- package/dist/core/message-processing-control.js +139 -0
- package/dist/core/message-processing-control.js.map +1 -0
- package/dist/core/openai-direct.d.ts +80 -0
- package/dist/core/openai-direct.d.ts.map +1 -0
- package/dist/core/openai-direct.js +374 -0
- package/dist/core/openai-direct.js.map +1 -0
- package/dist/core/shell-cmd-tool.d.ts +235 -0
- package/dist/core/shell-cmd-tool.d.ts.map +1 -0
- package/dist/core/shell-cmd-tool.js +1157 -0
- package/dist/core/shell-cmd-tool.js.map +1 -0
- package/dist/core/shell-process-registry.d.ts +88 -0
- package/dist/core/shell-process-registry.d.ts.map +1 -0
- package/dist/core/shell-process-registry.js +309 -0
- package/dist/core/shell-process-registry.js.map +1 -0
- package/dist/core/skill-registry.d.ts +75 -0
- package/dist/core/skill-registry.d.ts.map +1 -0
- package/dist/core/skill-registry.js +369 -0
- package/dist/core/skill-registry.js.map +1 -0
- package/dist/core/skill-script-runner.d.ts +89 -0
- package/dist/core/skill-script-runner.d.ts.map +1 -0
- package/dist/core/skill-script-runner.js +274 -0
- package/dist/core/skill-script-runner.js.map +1 -0
- package/dist/core/skill-selector.d.ts +65 -0
- package/dist/core/skill-selector.d.ts.map +1 -0
- package/dist/core/skill-selector.js +190 -0
- package/dist/core/skill-selector.js.map +1 -0
- package/dist/core/skill-settings.d.ts +20 -0
- package/dist/core/skill-settings.d.ts.map +1 -0
- package/dist/core/skill-settings.js +40 -0
- package/dist/core/skill-settings.js.map +1 -0
- package/dist/core/storage/agent-storage.d.ts +134 -0
- package/dist/core/storage/agent-storage.d.ts.map +1 -0
- package/dist/core/storage/agent-storage.js +498 -0
- package/dist/core/storage/agent-storage.js.map +1 -0
- package/dist/core/storage/eventStorage/fileEventStorage.d.ts +100 -0
- package/dist/core/storage/eventStorage/fileEventStorage.d.ts.map +1 -0
- package/dist/core/storage/eventStorage/fileEventStorage.js +494 -0
- package/dist/core/storage/eventStorage/fileEventStorage.js.map +1 -0
- package/dist/core/storage/eventStorage/index.d.ts +31 -0
- package/dist/core/storage/eventStorage/index.d.ts.map +1 -0
- package/dist/core/storage/eventStorage/index.js +31 -0
- package/dist/core/storage/eventStorage/index.js.map +1 -0
- package/dist/core/storage/eventStorage/memoryEventStorage.d.ts +87 -0
- package/dist/core/storage/eventStorage/memoryEventStorage.d.ts.map +1 -0
- package/dist/core/storage/eventStorage/memoryEventStorage.js +244 -0
- package/dist/core/storage/eventStorage/memoryEventStorage.js.map +1 -0
- package/dist/core/storage/eventStorage/sqliteEventStorage.d.ts +45 -0
- package/dist/core/storage/eventStorage/sqliteEventStorage.d.ts.map +1 -0
- package/dist/core/storage/eventStorage/sqliteEventStorage.js +301 -0
- package/dist/core/storage/eventStorage/sqliteEventStorage.js.map +1 -0
- package/dist/core/storage/eventStorage/types.d.ts +142 -0
- package/dist/core/storage/eventStorage/types.d.ts.map +1 -0
- package/dist/core/storage/eventStorage/types.js +43 -0
- package/dist/core/storage/eventStorage/types.js.map +1 -0
- package/dist/core/storage/eventStorage/validation.d.ts +30 -0
- package/dist/core/storage/eventStorage/validation.d.ts.map +1 -0
- package/dist/core/storage/eventStorage/validation.js +68 -0
- package/dist/core/storage/eventStorage/validation.js.map +1 -0
- package/dist/core/storage/legacy-migrations.d.ts +45 -0
- package/dist/core/storage/legacy-migrations.d.ts.map +1 -0
- package/dist/core/storage/legacy-migrations.js +295 -0
- package/dist/core/storage/legacy-migrations.js.map +1 -0
- package/dist/core/storage/memory-storage.d.ts +105 -0
- package/dist/core/storage/memory-storage.d.ts.map +1 -0
- package/dist/core/storage/memory-storage.js +415 -0
- package/dist/core/storage/memory-storage.js.map +1 -0
- package/dist/core/storage/migration-runner.d.ts +96 -0
- package/dist/core/storage/migration-runner.d.ts.map +1 -0
- package/dist/core/storage/migration-runner.js +306 -0
- package/dist/core/storage/migration-runner.js.map +1 -0
- package/dist/core/storage/queue-storage.d.ts +147 -0
- package/dist/core/storage/queue-storage.d.ts.map +1 -0
- package/dist/core/storage/queue-storage.js +290 -0
- package/dist/core/storage/queue-storage.js.map +1 -0
- package/dist/core/storage/skill-storage.d.ts +136 -0
- package/dist/core/storage/skill-storage.d.ts.map +1 -0
- package/dist/core/storage/skill-storage.js +474 -0
- package/dist/core/storage/skill-storage.js.map +1 -0
- package/dist/core/storage/sqlite-schema.d.ts +95 -0
- package/dist/core/storage/sqlite-schema.d.ts.map +1 -0
- package/dist/core/storage/sqlite-schema.js +156 -0
- package/dist/core/storage/sqlite-schema.js.map +1 -0
- package/dist/core/storage/sqlite-storage.d.ts +146 -0
- package/dist/core/storage/sqlite-storage.d.ts.map +1 -0
- package/dist/core/storage/sqlite-storage.js +709 -0
- package/dist/core/storage/sqlite-storage.js.map +1 -0
- package/dist/core/storage/storage-factory.d.ts +61 -0
- package/dist/core/storage/storage-factory.d.ts.map +1 -0
- package/dist/core/storage/storage-factory.js +794 -0
- package/dist/core/storage/storage-factory.js.map +1 -0
- package/dist/core/storage/validation.d.ts +36 -0
- package/dist/core/storage/validation.d.ts.map +1 -0
- package/dist/core/storage/validation.js +79 -0
- package/dist/core/storage/validation.js.map +1 -0
- package/dist/core/storage/world-storage.d.ts +114 -0
- package/dist/core/storage/world-storage.d.ts.map +1 -0
- package/dist/core/storage/world-storage.js +378 -0
- package/dist/core/storage/world-storage.js.map +1 -0
- package/dist/core/subscription.d.ts +43 -0
- package/dist/core/subscription.d.ts.map +1 -0
- package/dist/core/subscription.js +227 -0
- package/dist/core/subscription.js.map +1 -0
- package/dist/core/tool-utils.d.ts +80 -0
- package/dist/core/tool-utils.d.ts.map +1 -0
- package/dist/core/tool-utils.js +273 -0
- package/dist/core/tool-utils.js.map +1 -0
- package/dist/core/types.d.ts +595 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +158 -0
- package/dist/core/types.js.map +1 -0
- package/dist/core/utils.d.ts +138 -0
- package/dist/core/utils.d.ts.map +1 -0
- package/dist/core/utils.js +478 -0
- package/dist/core/utils.js.map +1 -0
- package/dist/core/world-class.d.ts +43 -0
- package/dist/core/world-class.d.ts.map +1 -0
- package/dist/core/world-class.js +90 -0
- package/dist/core/world-class.js.map +1 -0
- package/dist/index.d.ts +18 -0
- package/dist/public/assets/agent-sprites-DJFgj-zP.png +0 -0
- package/dist/public/assets/border-KHK37r8y.svg +83 -0
- package/dist/public/assets/index-C9kPXL6G.css +1 -0
- package/dist/public/assets/index-DOQEHGWt.js +96 -0
- package/dist/public/index.html +21 -0
- package/dist/server/api.d.ts +2 -0
- package/dist/server/api.js +1124 -0
- package/dist/server/index.d.ts +29 -0
- package/dist/server/sse-handler.d.ts +62 -0
- package/dist/server/sse-handler.js +234 -0
- package/package.json +15 -3
- package/scripts/launch-electron.js +0 -58
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SQL File-Based Migration Runner
|
|
3
|
+
*
|
|
4
|
+
* Purpose: Manages database schema migrations using SQL files
|
|
5
|
+
*
|
|
6
|
+
* Features:
|
|
7
|
+
* - Executes SQL migration files in order
|
|
8
|
+
* - Tracks migration versions in database
|
|
9
|
+
* - Supports both TypeScript and SQL file migrations
|
|
10
|
+
* - Prevents concurrent migrations with locks
|
|
11
|
+
* - Provides rollback support (future enhancement)
|
|
12
|
+
* - Better error handling and logging
|
|
13
|
+
*
|
|
14
|
+
* Migration File Naming Convention:
|
|
15
|
+
* - {version}_{description}.sql (e.g., 0001_create_events_table.sql)
|
|
16
|
+
* - Version numbers must be sequential
|
|
17
|
+
* - Files are executed in numeric order
|
|
18
|
+
*
|
|
19
|
+
* Implementation:
|
|
20
|
+
* - 2025-11-02: Initial implementation replacing inline TypeScript migrations
|
|
21
|
+
*/
|
|
22
|
+
import { promisify } from 'util';
|
|
23
|
+
import * as fs from 'fs';
|
|
24
|
+
import * as path from 'path';
|
|
25
|
+
import { createCategoryLogger } from '../logger.js';
|
|
26
|
+
const logger = createCategoryLogger('storage.migration');
|
|
27
|
+
/**
|
|
28
|
+
* Get current schema version from database
|
|
29
|
+
*/
|
|
30
|
+
export async function getCurrentVersion(db) {
|
|
31
|
+
const get = promisify(db.get.bind(db));
|
|
32
|
+
try {
|
|
33
|
+
const result = await get("PRAGMA user_version");
|
|
34
|
+
return result.user_version;
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
return 0;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Set schema version in database
|
|
42
|
+
*/
|
|
43
|
+
export async function setVersion(db, version) {
|
|
44
|
+
// Ensure version is an integer
|
|
45
|
+
const intVersion = Math.floor(version);
|
|
46
|
+
// PRAGMA statements work with db.run but need to be handled in serialize mode
|
|
47
|
+
await new Promise((resolve, reject) => {
|
|
48
|
+
db.serialize(() => {
|
|
49
|
+
db.run(`PRAGMA user_version = ${intVersion}`, (err) => {
|
|
50
|
+
if (err)
|
|
51
|
+
reject(err);
|
|
52
|
+
else
|
|
53
|
+
resolve();
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
logger.info('Schema version updated', { version: intVersion });
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Create migration tracking table if it doesn't exist
|
|
61
|
+
* This provides better migration history than just PRAGMA user_version
|
|
62
|
+
*/
|
|
63
|
+
export async function ensureMigrationTable(db) {
|
|
64
|
+
return new Promise((resolve, reject) => {
|
|
65
|
+
db.run(`
|
|
66
|
+
CREATE TABLE IF NOT EXISTS schema_migrations (
|
|
67
|
+
version INTEGER PRIMARY KEY,
|
|
68
|
+
name TEXT NOT NULL,
|
|
69
|
+
applied_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
70
|
+
)
|
|
71
|
+
`, (err) => {
|
|
72
|
+
if (err)
|
|
73
|
+
reject(err);
|
|
74
|
+
else
|
|
75
|
+
resolve();
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Get list of applied migrations from tracking table
|
|
81
|
+
*/
|
|
82
|
+
export async function getAppliedMigrations(db) {
|
|
83
|
+
const all = promisify(db.all.bind(db));
|
|
84
|
+
try {
|
|
85
|
+
// Ensure table exists before querying
|
|
86
|
+
await ensureMigrationTable(db);
|
|
87
|
+
const rows = await all("SELECT version, name, applied_at FROM schema_migrations ORDER BY version");
|
|
88
|
+
return rows || [];
|
|
89
|
+
}
|
|
90
|
+
catch {
|
|
91
|
+
return [];
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Record a migration in the tracking table
|
|
96
|
+
*/
|
|
97
|
+
export async function recordMigration(db, version, name) {
|
|
98
|
+
// Ensure table exists before inserting
|
|
99
|
+
await ensureMigrationTable(db);
|
|
100
|
+
const run = (sql, params) => {
|
|
101
|
+
return new Promise((resolve, reject) => {
|
|
102
|
+
db.run(sql, params || [], (err) => {
|
|
103
|
+
if (err)
|
|
104
|
+
reject(err);
|
|
105
|
+
else
|
|
106
|
+
resolve();
|
|
107
|
+
});
|
|
108
|
+
});
|
|
109
|
+
};
|
|
110
|
+
await run("INSERT INTO schema_migrations (version, name) VALUES (?, ?)", [version, name]);
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Discover all SQL migration files in the migrations directory
|
|
114
|
+
*/
|
|
115
|
+
export function discoverMigrations(migrationsDir) {
|
|
116
|
+
if (!fs.existsSync(migrationsDir)) {
|
|
117
|
+
logger.warn('Migrations directory not found', { dir: migrationsDir });
|
|
118
|
+
return [];
|
|
119
|
+
}
|
|
120
|
+
const files = fs.readdirSync(migrationsDir)
|
|
121
|
+
.filter(f => f.endsWith('.sql'))
|
|
122
|
+
.map(filename => {
|
|
123
|
+
const match = filename.match(/^(\d+)_(.+)\.sql$/);
|
|
124
|
+
if (!match) {
|
|
125
|
+
logger.warn('Invalid migration filename format', { filename });
|
|
126
|
+
return null;
|
|
127
|
+
}
|
|
128
|
+
return {
|
|
129
|
+
version: parseInt(match[1], 10),
|
|
130
|
+
name: match[2],
|
|
131
|
+
filePath: path.join(migrationsDir, filename)
|
|
132
|
+
};
|
|
133
|
+
})
|
|
134
|
+
.filter((m) => m !== null)
|
|
135
|
+
.sort((a, b) => a.version - b.version);
|
|
136
|
+
return files;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Read and parse SQL migration file
|
|
140
|
+
*/
|
|
141
|
+
export function readMigrationFile(filePath) {
|
|
142
|
+
if (!fs.existsSync(filePath)) {
|
|
143
|
+
throw new Error(`Migration file not found: ${filePath}`);
|
|
144
|
+
}
|
|
145
|
+
return fs.readFileSync(filePath, 'utf-8');
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Execute a single migration file
|
|
149
|
+
*/
|
|
150
|
+
export async function executeMigration(db, migration) {
|
|
151
|
+
// Split SQL by semicolons and execute each statement
|
|
152
|
+
const run = promisify(db.run.bind(db));
|
|
153
|
+
logger.info('Executing migration', {
|
|
154
|
+
version: migration.version,
|
|
155
|
+
name: migration.name
|
|
156
|
+
});
|
|
157
|
+
const sql = readMigrationFile(migration.filePath);
|
|
158
|
+
try {
|
|
159
|
+
// Split SQL into statements and execute each one
|
|
160
|
+
const statements = sql
|
|
161
|
+
.split(';')
|
|
162
|
+
.map(s => s.trim())
|
|
163
|
+
.filter(s => s.length > 0);
|
|
164
|
+
for (const statement of statements) {
|
|
165
|
+
await run(statement);
|
|
166
|
+
}
|
|
167
|
+
await recordMigration(db, migration.version, migration.name);
|
|
168
|
+
await setVersion(db, migration.version);
|
|
169
|
+
logger.info('Migration completed successfully', {
|
|
170
|
+
version: migration.version,
|
|
171
|
+
name: migration.name
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
catch (error) {
|
|
175
|
+
logger.error('Migration failed', {
|
|
176
|
+
version: migration.version,
|
|
177
|
+
name: migration.name,
|
|
178
|
+
error: error instanceof Error ? error.message : String(error)
|
|
179
|
+
});
|
|
180
|
+
throw error;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Check if migrations are needed
|
|
185
|
+
*/
|
|
186
|
+
export async function needsMigration(db, migrationsDir) {
|
|
187
|
+
const currentVersion = await getCurrentVersion(db);
|
|
188
|
+
const migrations = discoverMigrations(migrationsDir);
|
|
189
|
+
if (migrations.length === 0) {
|
|
190
|
+
return false;
|
|
191
|
+
}
|
|
192
|
+
const latestVersion = Math.max(...migrations.map(m => m.version));
|
|
193
|
+
return currentVersion < latestVersion;
|
|
194
|
+
}
|
|
195
|
+
// Global migration locks to prevent concurrent migrations
|
|
196
|
+
const migrationLocks = new Map();
|
|
197
|
+
/**
|
|
198
|
+
* Run all pending migrations
|
|
199
|
+
*/
|
|
200
|
+
export async function runMigrations(ctx) {
|
|
201
|
+
const dbPath = ctx.db.filename || 'memory';
|
|
202
|
+
// Check if there's already a migration in progress for this database
|
|
203
|
+
if (migrationLocks.has(dbPath)) {
|
|
204
|
+
logger.info('Waiting for existing migration to complete', { dbPath });
|
|
205
|
+
await migrationLocks.get(dbPath);
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
208
|
+
const migrationPromise = performMigrations(ctx);
|
|
209
|
+
migrationLocks.set(dbPath, migrationPromise);
|
|
210
|
+
try {
|
|
211
|
+
await migrationPromise;
|
|
212
|
+
}
|
|
213
|
+
finally {
|
|
214
|
+
migrationLocks.delete(dbPath);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Internal function to perform migrations
|
|
219
|
+
*/
|
|
220
|
+
async function performMigrations(ctx) {
|
|
221
|
+
const { db, migrationsDir } = ctx;
|
|
222
|
+
// Ensure migration tracking table exists
|
|
223
|
+
await ensureMigrationTable(db);
|
|
224
|
+
const currentVersion = await getCurrentVersion(db);
|
|
225
|
+
const migrations = discoverMigrations(migrationsDir);
|
|
226
|
+
if (migrations.length === 0) {
|
|
227
|
+
logger.info('No migration files found', { dir: migrationsDir });
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
// For completely fresh databases at v0, include migration 0000
|
|
231
|
+
// For all other cases, only include migrations with version > currentVersion
|
|
232
|
+
const pendingMigrations = currentVersion === 0
|
|
233
|
+
? migrations.filter(m => m.version >= 0)
|
|
234
|
+
: migrations.filter(m => m.version > currentVersion);
|
|
235
|
+
if (pendingMigrations.length === 0) {
|
|
236
|
+
logger.info('Database is up to date', { currentVersion });
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
logger.info('Starting migrations', {
|
|
240
|
+
currentVersion,
|
|
241
|
+
pendingCount: pendingMigrations.length,
|
|
242
|
+
targetVersion: Math.max(...pendingMigrations.map(m => m.version))
|
|
243
|
+
});
|
|
244
|
+
// Execute each pending migration in order
|
|
245
|
+
for (const migration of pendingMigrations) {
|
|
246
|
+
await executeMigration(db, migration);
|
|
247
|
+
}
|
|
248
|
+
const finalVersion = await getCurrentVersion(db);
|
|
249
|
+
logger.info('Migrations completed', {
|
|
250
|
+
fromVersion: currentVersion,
|
|
251
|
+
toVersion: finalVersion
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Get migration status and history
|
|
256
|
+
*/
|
|
257
|
+
export async function getMigrationStatus(ctx) {
|
|
258
|
+
const { db, migrationsDir } = ctx;
|
|
259
|
+
const currentVersion = await getCurrentVersion(db);
|
|
260
|
+
const availableMigrations = discoverMigrations(migrationsDir);
|
|
261
|
+
let appliedMigrations = [];
|
|
262
|
+
try {
|
|
263
|
+
appliedMigrations = await getAppliedMigrations(db);
|
|
264
|
+
}
|
|
265
|
+
catch {
|
|
266
|
+
// Migration table might not exist yet
|
|
267
|
+
}
|
|
268
|
+
const pendingMigrations = availableMigrations.filter(m => m.version > currentVersion);
|
|
269
|
+
return {
|
|
270
|
+
currentVersion,
|
|
271
|
+
availableMigrations,
|
|
272
|
+
appliedMigrations,
|
|
273
|
+
pendingMigrations
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* Validate migration file sequence
|
|
278
|
+
* Ensures no gaps or duplicates in version numbers
|
|
279
|
+
*/
|
|
280
|
+
export function validateMigrationSequence(migrations) {
|
|
281
|
+
const errors = [];
|
|
282
|
+
if (migrations.length === 0) {
|
|
283
|
+
return { isValid: true, errors };
|
|
284
|
+
}
|
|
285
|
+
// Check for duplicates
|
|
286
|
+
const versions = migrations.map(m => m.version);
|
|
287
|
+
const uniqueVersions = new Set(versions);
|
|
288
|
+
if (versions.length !== uniqueVersions.size) {
|
|
289
|
+
errors.push('Duplicate migration versions found');
|
|
290
|
+
}
|
|
291
|
+
// Check for gaps (optional - might want to allow gaps)
|
|
292
|
+
for (let i = 1; i < migrations.length; i++) {
|
|
293
|
+
const expectedVersion = migrations[i - 1].version + 1;
|
|
294
|
+
if (migrations[i].version !== expectedVersion) {
|
|
295
|
+
logger.warn('Gap in migration sequence', {
|
|
296
|
+
expected: expectedVersion,
|
|
297
|
+
actual: migrations[i].version
|
|
298
|
+
});
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
return {
|
|
302
|
+
isValid: errors.length === 0,
|
|
303
|
+
errors
|
|
304
|
+
};
|
|
305
|
+
}
|
|
306
|
+
//# sourceMappingURL=migration-runner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migration-runner.js","sourceRoot":"","sources":["../../../core/storage/migration-runner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAGH,OAAO,EAAE,SAAS,EAAE,MAAM,MAAM,CAAC;AACjC,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAEpD,MAAM,MAAM,GAAG,oBAAoB,CAAC,mBAAmB,CAAC,CAAC;AAmBzD;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,EAAY;IAClD,MAAM,GAAG,GAAG,SAAS,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;IACvC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,qBAAqB,CAA6B,CAAC;QAC5E,OAAO,MAAM,CAAC,YAAY,CAAC;IAC7B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,CAAC;IACX,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,EAAY,EAAE,OAAe;IAC5D,+BAA+B;IAC/B,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAEvC,8EAA8E;IAC9E,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QAC1C,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE;YAChB,EAAE,CAAC,GAAG,CAAC,yBAAyB,UAAU,EAAE,EAAE,CAAC,GAAG,EAAE,EAAE;gBACpD,IAAI,GAAG;oBAAE,MAAM,CAAC,GAAG,CAAC,CAAC;;oBAChB,OAAO,EAAE,CAAC;YACjB,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,IAAI,CAAC,wBAAwB,EAAE,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC,CAAC;AACjE,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,EAAY;IACrD,OAAO,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QAC3C,EAAE,CAAC,GAAG,CAAC;;;;;;KAMN,EAAE,CAAC,GAAG,EAAE,EAAE;YACT,IAAI,GAAG;gBAAE,MAAM,CAAC,GAAG,CAAC,CAAC;;gBAChB,OAAO,EAAE,CAAC;QACjB,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,EAAY;IACrD,MAAM,GAAG,GAAG,SAAS,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;IACvC,IAAI,CAAC;QACH,sCAAsC;QACtC,MAAM,oBAAoB,CAAC,EAAE,CAAC,CAAC;QAC/B,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,0EAA0E,CAAsB,CAAC;QACxH,OAAO,IAAI,IAAI,EAAE,CAAC;IACpB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,EAAY,EAAE,OAAe,EAAE,IAAY;IAC/E,uCAAuC;IACvC,MAAM,oBAAoB,CAAC,EAAE,CAAC,CAAC;IAE/B,MAAM,GAAG,GAAG,CAAC,GAAW,EAAE,MAAc,EAAiB,EAAE;QACzD,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACrC,EAAE,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,IAAI,EAAE,EAAE,CAAC,GAAG,EAAE,EAAE;gBAChC,IAAI,GAAG;oBAAE,MAAM,CAAC,GAAG,CAAC,CAAC;;oBAChB,OAAO,EAAE,CAAC;YACjB,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,CAAC;IACF,MAAM,GAAG,CACP,6DAA6D,EAC7D,CAAC,OAAO,EAAE,IAAI,CAAC,CAChB,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAAC,aAAqB;IACtD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC;QAClC,MAAM,CAAC,IAAI,CAAC,gCAAgC,EAAE,EAAE,GAAG,EAAE,aAAa,EAAE,CAAC,CAAC;QACtE,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,KAAK,GAAG,EAAE,CAAC,WAAW,CAAC,aAAa,CAAC;SACxC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;SAC/B,GAAG,CAAC,QAAQ,CAAC,EAAE;QACd,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC;QAClD,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,MAAM,CAAC,IAAI,CAAC,mCAAmC,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC;YAC/D,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO;YACL,OAAO,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;YAC/B,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC;YACd,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,QAAQ,CAAC;SAC7C,CAAC;IACJ,CAAC,CAAC;SACD,MAAM,CAAC,CAAC,CAAC,EAAsB,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC;SAC7C,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC;IAEzC,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAAC,QAAgB;IAChD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CAAC,6BAA6B,QAAQ,EAAE,CAAC,CAAC;IAC3D,CAAC;IACD,OAAO,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;AAC5C,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,EAAY,EAAE,SAAwB;IAC3E,qDAAqD;IACrD,MAAM,GAAG,GAAG,SAAS,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;IAEvC,MAAM,CAAC,IAAI,CAAC,qBAAqB,EAAE;QACjC,OAAO,EAAE,SAAS,CAAC,OAAO;QAC1B,IAAI,EAAE,SAAS,CAAC,IAAI;KACrB,CAAC,CAAC;IAEH,MAAM,GAAG,GAAG,iBAAiB,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;IAElD,IAAI,CAAC;QACH,iDAAiD;QACjD,MAAM,UAAU,GAAG,GAAG;aACnB,KAAK,CAAC,GAAG,CAAC;aACV,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;aAClB,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QAE7B,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;YACnC,MAAM,GAAG,CAAC,SAAS,CAAC,CAAC;QACvB,CAAC;QAED,MAAM,eAAe,CAAC,EAAE,EAAE,SAAS,CAAC,OAAO,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC;QAC7D,MAAM,UAAU,CAAC,EAAE,EAAE,SAAS,CAAC,OAAO,CAAC,CAAC;QAExC,MAAM,CAAC,IAAI,CAAC,kCAAkC,EAAE;YAC9C,OAAO,EAAE,SAAS,CAAC,OAAO;YAC1B,IAAI,EAAE,SAAS,CAAC,IAAI;SACrB,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,CAAC,KAAK,CAAC,kBAAkB,EAAE;YAC/B,OAAO,EAAE,SAAS,CAAC,OAAO;YAC1B,IAAI,EAAE,SAAS,CAAC,IAAI;YACpB,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;SAC9D,CAAC,CAAC;QACH,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,EAAY,EAAE,aAAqB;IACtE,MAAM,cAAc,GAAG,MAAM,iBAAiB,CAAC,EAAE,CAAC,CAAC;IACnD,MAAM,UAAU,GAAG,kBAAkB,CAAC,aAAa,CAAC,CAAC;IAErD,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5B,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,aAAa,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;IAClE,OAAO,cAAc,GAAG,aAAa,CAAC;AACxC,CAAC;AAED,0DAA0D;AAC1D,MAAM,cAAc,GAAG,IAAI,GAAG,EAAyB,CAAC;AAExD;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,GAAqB;IACvD,MAAM,MAAM,GAAI,GAAG,CAAC,EAAU,CAAC,QAAQ,IAAI,QAAQ,CAAC;IAEpD,qEAAqE;IACrE,IAAI,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;QAC/B,MAAM,CAAC,IAAI,CAAC,4CAA4C,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;QACtE,MAAM,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACjC,OAAO;IACT,CAAC;IAED,MAAM,gBAAgB,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAC;IAChD,cAAc,CAAC,GAAG,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IAE7C,IAAI,CAAC;QACH,MAAM,gBAAgB,CAAC;IACzB,CAAC;YAAS,CAAC;QACT,cAAc,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAChC,CAAC;AACH,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,iBAAiB,CAAC,GAAqB;IACpD,MAAM,EAAE,EAAE,EAAE,aAAa,EAAE,GAAG,GAAG,CAAC;IAElC,yCAAyC;IACzC,MAAM,oBAAoB,CAAC,EAAE,CAAC,CAAC;IAE/B,MAAM,cAAc,GAAG,MAAM,iBAAiB,CAAC,EAAE,CAAC,CAAC;IACnD,MAAM,UAAU,GAAG,kBAAkB,CAAC,aAAa,CAAC,CAAC;IAErD,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5B,MAAM,CAAC,IAAI,CAAC,0BAA0B,EAAE,EAAE,GAAG,EAAE,aAAa,EAAE,CAAC,CAAC;QAChE,OAAO;IACT,CAAC;IAED,+DAA+D;IAC/D,6EAA6E;IAC7E,MAAM,iBAAiB,GAAG,cAAc,KAAK,CAAC;QAC5C,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC;QACxC,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,GAAG,cAAc,CAAC,CAAC;IAEvD,IAAI,iBAAiB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACnC,MAAM,CAAC,IAAI,CAAC,wBAAwB,EAAE,EAAE,cAAc,EAAE,CAAC,CAAC;QAC1D,OAAO;IACT,CAAC;IAED,MAAM,CAAC,IAAI,CAAC,qBAAqB,EAAE;QACjC,cAAc;QACd,YAAY,EAAE,iBAAiB,CAAC,MAAM;QACtC,aAAa,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;KAClE,CAAC,CAAC;IAEH,0CAA0C;IAC1C,KAAK,MAAM,SAAS,IAAI,iBAAiB,EAAE,CAAC;QAC1C,MAAM,gBAAgB,CAAC,EAAE,EAAE,SAAS,CAAC,CAAC;IACxC,CAAC;IAED,MAAM,YAAY,GAAG,MAAM,iBAAiB,CAAC,EAAE,CAAC,CAAC;IACjD,MAAM,CAAC,IAAI,CAAC,sBAAsB,EAAE;QAClC,WAAW,EAAE,cAAc;QAC3B,SAAS,EAAE,YAAY;KACxB,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,GAAqB;IAM5D,MAAM,EAAE,EAAE,EAAE,aAAa,EAAE,GAAG,GAAG,CAAC;IAElC,MAAM,cAAc,GAAG,MAAM,iBAAiB,CAAC,EAAE,CAAC,CAAC;IACnD,MAAM,mBAAmB,GAAG,kBAAkB,CAAC,aAAa,CAAC,CAAC;IAE9D,IAAI,iBAAiB,GAAsB,EAAE,CAAC;IAC9C,IAAI,CAAC;QACH,iBAAiB,GAAG,MAAM,oBAAoB,CAAC,EAAE,CAAC,CAAC;IACrD,CAAC;IAAC,MAAM,CAAC;QACP,sCAAsC;IACxC,CAAC;IAED,MAAM,iBAAiB,GAAG,mBAAmB,CAAC,MAAM,CAClD,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,GAAG,cAAc,CAChC,CAAC;IAEF,OAAO;QACL,cAAc;QACd,mBAAmB;QACnB,iBAAiB;QACjB,iBAAiB;KAClB,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,yBAAyB,CAAC,UAA2B;IAInE,MAAM,MAAM,GAAa,EAAE,CAAC;IAE5B,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5B,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IACnC,CAAC;IAED,uBAAuB;IACvB,MAAM,QAAQ,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;IAChD,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC;IACzC,IAAI,QAAQ,CAAC,MAAM,KAAK,cAAc,CAAC,IAAI,EAAE,CAAC;QAC5C,MAAM,CAAC,IAAI,CAAC,oCAAoC,CAAC,CAAC;IACpD,CAAC;IAED,uDAAuD;IACvD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC3C,MAAM,eAAe,GAAG,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC;QACtD,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC,OAAO,KAAK,eAAe,EAAE,CAAC;YAC9C,MAAM,CAAC,IAAI,CAAC,2BAA2B,EAAE;gBACvC,QAAQ,EAAE,eAAe;gBACzB,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,OAAO;aAC9B,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO;QACL,OAAO,EAAE,MAAM,CAAC,MAAM,KAAK,CAAC;QAC5B,MAAM;KACP,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Queue Storage - In-Memory Message Queue Implementation
|
|
3
|
+
*
|
|
4
|
+
* Purpose: Simple in-memory message queue for async processing
|
|
5
|
+
*
|
|
6
|
+
* Features:
|
|
7
|
+
* - FIFO per-world message queuing
|
|
8
|
+
* - Per-world locking (one message processing at a time)
|
|
9
|
+
* - Automatic retry on failure
|
|
10
|
+
* - Basic statistics tracking
|
|
11
|
+
*
|
|
12
|
+
* Implementation:
|
|
13
|
+
* - In-memory queues with Map-based storage
|
|
14
|
+
* - Simple locking via processing state tracking
|
|
15
|
+
* - Auto-retry when marking failed (up to maxRetries)
|
|
16
|
+
*
|
|
17
|
+
* Queue Message Lifecycle:
|
|
18
|
+
* 1. pending: Message enqueued, waiting in queue
|
|
19
|
+
* 2. processing: Message dequeued and being processed
|
|
20
|
+
* 3. completed: Processing finished successfully
|
|
21
|
+
* 4. failed: Processing failed after max retries
|
|
22
|
+
*
|
|
23
|
+
* Note: Data is NOT persisted - queue cleared on restart
|
|
24
|
+
* For production with persistence, use external MQ system (Redis, RabbitMQ, etc)
|
|
25
|
+
*
|
|
26
|
+
* Changes:
|
|
27
|
+
* - 2025-11-01: Replace SQL implementation with in-memory version
|
|
28
|
+
* - Reduced from 716 lines to 453 lines (242 lines of actual code)
|
|
29
|
+
* - Removed: SQL transactions, heartbeat monitoring, stuck detection, priority ordering
|
|
30
|
+
* - Kept: Core queue operations, per-world locking, auto-retry, statistics
|
|
31
|
+
* - All 31 unit tests pass with in-memory implementation
|
|
32
|
+
*/
|
|
33
|
+
/**
|
|
34
|
+
* Queue message status
|
|
35
|
+
*/
|
|
36
|
+
export type QueueStatus = 'pending' | 'processing' | 'completed' | 'failed';
|
|
37
|
+
/**
|
|
38
|
+
* Queue message structure
|
|
39
|
+
*/
|
|
40
|
+
export interface QueueMessage {
|
|
41
|
+
id: string;
|
|
42
|
+
worldId: string;
|
|
43
|
+
messageId: string;
|
|
44
|
+
content: string;
|
|
45
|
+
sender: string;
|
|
46
|
+
chatId: string | null;
|
|
47
|
+
status: QueueStatus;
|
|
48
|
+
priority: number;
|
|
49
|
+
createdAt: Date;
|
|
50
|
+
processedAt?: Date;
|
|
51
|
+
heartbeatAt?: Date;
|
|
52
|
+
completedAt?: Date;
|
|
53
|
+
error?: string;
|
|
54
|
+
retryCount: number;
|
|
55
|
+
maxRetries: number;
|
|
56
|
+
timeoutSeconds: number;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Queue statistics
|
|
60
|
+
*/
|
|
61
|
+
export interface QueueStats {
|
|
62
|
+
pending: number;
|
|
63
|
+
processing: number;
|
|
64
|
+
completed: number;
|
|
65
|
+
failed: number;
|
|
66
|
+
oldestPending?: Date;
|
|
67
|
+
avgProcessingTime?: number;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Per-world queue statistics
|
|
71
|
+
*/
|
|
72
|
+
export interface WorldQueueStats extends QueueStats {
|
|
73
|
+
worldId: string;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Input type for enqueuing a new message
|
|
77
|
+
* Makes chatId optional since it's nullable
|
|
78
|
+
*/
|
|
79
|
+
export type EnqueueMessageInput = Omit<QueueMessage, 'id' | 'status' | 'createdAt' | 'retryCount' | 'processedAt' | 'completedAt' | 'heartbeatAt' | 'error' | 'chatId'> & {
|
|
80
|
+
chatId?: string | null;
|
|
81
|
+
};
|
|
82
|
+
/**
|
|
83
|
+
* Message queue storage interface
|
|
84
|
+
*/
|
|
85
|
+
export interface QueueStorage {
|
|
86
|
+
/**
|
|
87
|
+
* Enqueue a message for processing
|
|
88
|
+
* Returns the created queue message with generated ID
|
|
89
|
+
*/
|
|
90
|
+
enqueue(message: EnqueueMessageInput): Promise<QueueMessage>;
|
|
91
|
+
/**
|
|
92
|
+
* Dequeue the next pending message for a specific world
|
|
93
|
+
* Atomically marks message as 'processing' and returns it
|
|
94
|
+
* Returns null if no pending messages or world already processing
|
|
95
|
+
*/
|
|
96
|
+
dequeue(worldId: string): Promise<QueueMessage | null>;
|
|
97
|
+
/**
|
|
98
|
+
* Update heartbeat timestamp for a message
|
|
99
|
+
* Used to signal the message is still actively processing
|
|
100
|
+
*/
|
|
101
|
+
updateHeartbeat(messageId: string): Promise<void>;
|
|
102
|
+
/**
|
|
103
|
+
* Mark a message as completed successfully
|
|
104
|
+
*/
|
|
105
|
+
markCompleted(messageId: string): Promise<void>;
|
|
106
|
+
/**
|
|
107
|
+
* Mark a message as failed with error details
|
|
108
|
+
* Automatically retries if retryCount < maxRetries
|
|
109
|
+
*/
|
|
110
|
+
markFailed(messageId: string, error: string): Promise<void>;
|
|
111
|
+
/**
|
|
112
|
+
* Retry a failed message (reset to pending)
|
|
113
|
+
* Only works if retryCount < maxRetries
|
|
114
|
+
*/
|
|
115
|
+
retryMessage(messageId: string): Promise<boolean>;
|
|
116
|
+
/**
|
|
117
|
+
* Get queue depth (number of pending messages) for a world
|
|
118
|
+
*/
|
|
119
|
+
getQueueDepth(worldId: string): Promise<number>;
|
|
120
|
+
/**
|
|
121
|
+
* Get queue statistics for a specific world or all worlds
|
|
122
|
+
*/
|
|
123
|
+
getQueueStats(worldId?: string): Promise<WorldQueueStats[]>;
|
|
124
|
+
/**
|
|
125
|
+
* Detect and reset stuck messages (stale heartbeat)
|
|
126
|
+
* Returns number of messages reset
|
|
127
|
+
*/
|
|
128
|
+
detectStuckMessages(): Promise<number>;
|
|
129
|
+
/**
|
|
130
|
+
* Cleanup old completed/failed messages
|
|
131
|
+
* Returns number of messages deleted
|
|
132
|
+
*/
|
|
133
|
+
cleanup(olderThan: Date): Promise<number>;
|
|
134
|
+
/**
|
|
135
|
+
* Get message by ID (for debugging/monitoring)
|
|
136
|
+
*/
|
|
137
|
+
getMessage(messageId: string): Promise<QueueMessage | null>;
|
|
138
|
+
/**
|
|
139
|
+
* Close/cleanup storage resources
|
|
140
|
+
*/
|
|
141
|
+
close?(): Promise<void>;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* In-Memory Queue Storage Implementation
|
|
145
|
+
*/
|
|
146
|
+
export declare function createMemoryQueueStorage(): QueueStorage;
|
|
147
|
+
//# sourceMappingURL=queue-storage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queue-storage.d.ts","sourceRoot":"","sources":["../../../core/storage/queue-storage.ts"],"names":[],"mappings":"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"}
|