@elizaos/plugin-sql 2.0.3-beta.2 → 2.0.3-beta.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/package.json +3 -3
- package/src/dist/base.d.ts +1169 -0
- package/src/dist/browser/index.browser.d.ts +2 -0
- package/src/dist/browser/index.browser.js +31167 -0
- package/src/dist/browser/index.browser.js.map +76 -0
- package/src/dist/browser/index.d.ts +2 -0
- package/src/dist/cjs/index.d.ts +2 -0
- package/src/dist/cjs/index.node.cjs +13565 -0
- package/src/dist/cjs/index.node.cjs.map +75 -0
- package/src/dist/cjs/index.node.d.cts +2 -0
- package/src/dist/connector-credential-store.d.ts +48 -0
- package/src/dist/drizzle/index.d.ts +1 -0
- package/src/dist/drizzle/index.js +1 -0
- package/src/dist/index.d.ts +4 -0
- package/src/dist/index.js +2 -0
- package/src/dist/index.node.d.ts +53 -0
- package/src/dist/migration-service.d.ts +17 -0
- package/src/dist/migrations.d.ts +15 -0
- package/src/dist/node/index.d.ts +2 -0
- package/src/dist/node/index.node.d.ts +2 -0
- package/src/dist/node/index.node.js +13588 -0
- package/src/dist/node/index.node.js.map +75 -0
- package/src/dist/pg/adapter.d.ts +42 -0
- package/src/dist/pg/manager.d.ts +17 -0
- package/src/dist/pg/sslmode.d.ts +6 -0
- package/src/dist/pglite/adapter.d.ts +63 -0
- package/src/dist/pglite/errors.d.ts +20 -0
- package/src/dist/pglite/manager.d.ts +213 -0
- package/src/dist/rls.d.ts +13 -0
- package/src/dist/runtime-migrator/crypto-utils.d.ts +25 -0
- package/src/dist/runtime-migrator/drizzle-adapters/database-introspector.d.ts +58 -0
- package/src/dist/runtime-migrator/drizzle-adapters/diff-calculator.d.ts +77 -0
- package/src/dist/runtime-migrator/drizzle-adapters/snapshot-generator.d.ts +21 -0
- package/src/dist/runtime-migrator/drizzle-adapters/sql-generator.d.ts +38 -0
- package/src/dist/runtime-migrator/extension-manager.d.ts +6 -0
- package/src/dist/runtime-migrator/index.d.ts +8 -0
- package/src/dist/runtime-migrator/runtime-migrator.d.ts +95 -0
- package/src/dist/runtime-migrator/schema-transformer.d.ts +18 -0
- package/src/dist/runtime-migrator/storage/journal-storage.d.ts +10 -0
- package/src/dist/runtime-migrator/storage/migration-tracker.d.ts +13 -0
- package/src/dist/runtime-migrator/storage/snapshot-storage.d.ts +9 -0
- package/src/dist/runtime-migrator/types.d.ts +157 -0
- package/src/dist/schema/agent.d.ts +344 -0
- package/src/dist/schema/approvalRequests.d.ts +277 -0
- package/src/dist/schema/authAuditEvent.d.ts +153 -0
- package/src/dist/schema/authBootstrapJti.d.ts +49 -0
- package/src/dist/schema/authIdentity.d.ts +121 -0
- package/src/dist/schema/authOwnerBinding.d.ts +168 -0
- package/src/dist/schema/authOwnerLoginToken.d.ts +122 -0
- package/src/dist/schema/authSession.d.ts +225 -0
- package/src/dist/schema/cache.d.ts +97 -0
- package/src/dist/schema/channel.d.ts +177 -0
- package/src/dist/schema/channelParticipant.d.ts +41 -0
- package/src/dist/schema/component.d.ts +163 -0
- package/src/dist/schema/connectorAccounts.d.ts +981 -0
- package/src/dist/schema/embedding.d.ts +225 -0
- package/src/dist/schema/entity.d.ts +125 -0
- package/src/dist/schema/entityIdentity.d.ts +577 -0
- package/src/dist/schema/index.d.ts +35 -0
- package/src/dist/schema/index.js +1 -0
- package/src/dist/schema/log.d.ts +114 -0
- package/src/dist/schema/longTermMemories.d.ts +254 -0
- package/src/dist/schema/memory.d.ts +185 -0
- package/src/dist/schema/memoryAccessLogs.d.ts +109 -0
- package/src/dist/schema/message.d.ts +194 -0
- package/src/dist/schema/messageServer.d.ts +126 -0
- package/src/dist/schema/messageServerAgent.d.ts +41 -0
- package/src/dist/schema/pairingAllowlist.d.ts +113 -0
- package/src/dist/schema/pairingRequest.d.ts +147 -0
- package/src/dist/schema/participant.d.ts +114 -0
- package/src/dist/schema/relationship.d.ts +156 -0
- package/src/dist/schema/room.d.ts +195 -0
- package/src/dist/schema/server.d.ts +64 -0
- package/src/dist/schema/sessionSummaries.d.ts +273 -0
- package/src/dist/schema/tasks.d.ts +225 -0
- package/src/dist/schema/types.d.ts +68 -0
- package/src/dist/schema/world.d.ts +114 -0
- package/src/dist/services/advanced-memory-storage.d.ts +36 -0
- package/src/dist/stores/connectorAccount.store.d.ts +64 -0
- package/src/dist/stores/types.d.ts +25 -0
- package/src/dist/types.d.ts +13 -0
- package/src/dist/utils/string-to-uuid.d.ts +2 -0
- package/src/dist/utils.d.ts +4 -0
- package/src/dist/utils.node.d.ts +4 -0
- package/src/dist/write-back/index.d.ts +56 -0
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { type Agent, type Component, type Entity, type Memory, type UUID } from "@elizaos/core";
|
|
2
|
+
import type { NodePgDatabase } from "drizzle-orm/node-postgres";
|
|
3
|
+
import type { Pool } from "pg";
|
|
4
|
+
import { BaseDrizzleAdapter } from "../base.js";
|
|
5
|
+
import { type EmbeddingDimensionColumn } from "../schema/embedding.js";
|
|
6
|
+
import type { PostgresConnectionManager } from "./manager.js";
|
|
7
|
+
export declare class PgDatabaseAdapter extends BaseDrizzleAdapter {
|
|
8
|
+
protected embeddingDimension: EmbeddingDimensionColumn;
|
|
9
|
+
private manager;
|
|
10
|
+
constructor(agentId: UUID, manager: PostgresConnectionManager, _schema?: Record<string, unknown>);
|
|
11
|
+
getManager(): PostgresConnectionManager;
|
|
12
|
+
withEntityContext<T>(entityId: UUID | null, callback: (tx: NodePgDatabase) => Promise<T>): Promise<T>;
|
|
13
|
+
getEntityByIds(entityIds: UUID[]): Promise<Entity[] | null>;
|
|
14
|
+
getMemoriesByServerId(params: {
|
|
15
|
+
serverId: UUID;
|
|
16
|
+
count?: number;
|
|
17
|
+
}): Promise<Memory[]>;
|
|
18
|
+
ensureAgentExists(agent: Partial<Agent>): Promise<Agent>;
|
|
19
|
+
protected withDatabase<T>(operation: () => Promise<T>): Promise<T>;
|
|
20
|
+
init(): Promise<void>;
|
|
21
|
+
isReady(): Promise<boolean>;
|
|
22
|
+
close(): Promise<void>;
|
|
23
|
+
getConnection(): Promise<NodePgDatabase>;
|
|
24
|
+
getRawConnection(): Pool;
|
|
25
|
+
createAgent(agent: Agent): Promise<boolean>;
|
|
26
|
+
getAgent(agentId: UUID): Promise<Agent | null>;
|
|
27
|
+
updateAgent(agentId: UUID, agent: Partial<Agent>): Promise<boolean>;
|
|
28
|
+
deleteAgent(agentId: UUID): Promise<boolean>;
|
|
29
|
+
createEntities(entities: Entity[]): Promise<UUID[]>;
|
|
30
|
+
getEntitiesByIds(entityIds: UUID[]): Promise<Entity[]>;
|
|
31
|
+
updateEntity(entity: Entity): Promise<void>;
|
|
32
|
+
createMemory(memory: Memory, tableName: string): Promise<UUID>;
|
|
33
|
+
getMemoryById(memoryId: UUID): Promise<Memory | null>;
|
|
34
|
+
updateMemory(memory: Partial<Memory> & {
|
|
35
|
+
id: UUID;
|
|
36
|
+
}): Promise<boolean>;
|
|
37
|
+
deleteMemory(memoryId: UUID): Promise<void>;
|
|
38
|
+
createComponent(component: Component): Promise<boolean>;
|
|
39
|
+
getComponent(entityId: UUID, type: string, worldId?: UUID, sourceEntityId?: UUID): Promise<Component | null>;
|
|
40
|
+
updateComponent(component: Component): Promise<void>;
|
|
41
|
+
deleteComponent(componentId: UUID): Promise<void>;
|
|
42
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type UUID } from "@elizaos/core";
|
|
2
|
+
import { type NodePgDatabase } from "drizzle-orm/node-postgres";
|
|
3
|
+
import { Pool, type PoolClient } from "pg";
|
|
4
|
+
export declare class PostgresConnectionManager {
|
|
5
|
+
private pool;
|
|
6
|
+
private db;
|
|
7
|
+
private closePromise;
|
|
8
|
+
private shuttingDown;
|
|
9
|
+
constructor(connectionString: string, rlsServerId?: string);
|
|
10
|
+
getDatabase(): NodePgDatabase;
|
|
11
|
+
getConnection(): Pool;
|
|
12
|
+
isShuttingDown(): boolean;
|
|
13
|
+
getClient(): Promise<PoolClient>;
|
|
14
|
+
testConnection(): Promise<boolean>;
|
|
15
|
+
withEntityContext<T>(entityId: UUID | null, callback: (tx: NodePgDatabase) => Promise<T>): Promise<T>;
|
|
16
|
+
close(): Promise<void>;
|
|
17
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* pg-connection-string currently treats these sslmode values like verify-full,
|
|
3
|
+
* but warns that its next major version will switch them to libpq semantics.
|
|
4
|
+
* Make the current strict TLS behavior explicit before node-postgres parses it.
|
|
5
|
+
*/
|
|
6
|
+
export declare function normalizePgSslMode(connectionString: string): string;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import type { PGlite } from "@electric-sql/pglite";
|
|
2
|
+
import { type Agent, type Entity, type Memory, type MemoryMetadata, type Relationship, type Room, type Task, type UUID, type World } from "@elizaos/core";
|
|
3
|
+
import { type PgliteDatabase } from "drizzle-orm/pglite";
|
|
4
|
+
import { BaseDrizzleAdapter } from "../base.js";
|
|
5
|
+
import { type EmbeddingDimensionColumn } from "../schema/embedding.js";
|
|
6
|
+
import type { PGliteClientManager } from "./manager.js";
|
|
7
|
+
export declare class PgliteDatabaseAdapter extends BaseDrizzleAdapter {
|
|
8
|
+
private manager;
|
|
9
|
+
protected embeddingDimension: EmbeddingDimensionColumn;
|
|
10
|
+
constructor(agentId: UUID, manager: PGliteClientManager);
|
|
11
|
+
withEntityContext<T>(_entityId: UUID | null, callback: (tx: PgliteDatabase) => Promise<T>): Promise<T>;
|
|
12
|
+
getEntityByIds(entityIds: UUID[]): Promise<Entity[] | null>;
|
|
13
|
+
getMemoriesByServerId(params: {
|
|
14
|
+
serverId: UUID;
|
|
15
|
+
count?: number;
|
|
16
|
+
}): Promise<Memory[]>;
|
|
17
|
+
ensureAgentExists(agent: Partial<Agent>): Promise<Agent>;
|
|
18
|
+
protected withDatabase<T>(operation: () => Promise<T>): Promise<T>;
|
|
19
|
+
init(): Promise<void>;
|
|
20
|
+
isReady(): Promise<boolean>;
|
|
21
|
+
close(): Promise<void>;
|
|
22
|
+
getConnection(): Promise<PgliteDatabase>;
|
|
23
|
+
getRawConnection(): PGlite;
|
|
24
|
+
createAgent(agent: Agent): Promise<boolean>;
|
|
25
|
+
updateAgent(agentId: UUID, agent: Partial<Agent>): Promise<boolean>;
|
|
26
|
+
deleteAgent(agentId: UUID): Promise<boolean>;
|
|
27
|
+
deleteAgents(agentIds: UUID[]): Promise<boolean>;
|
|
28
|
+
createEntities(entities: Entity[]): Promise<UUID[]>;
|
|
29
|
+
updateEntity(entity: Entity): Promise<void>;
|
|
30
|
+
deleteEntity(entityId: UUID): Promise<void>;
|
|
31
|
+
createWorld(world: World): Promise<UUID>;
|
|
32
|
+
updateWorld(world: World): Promise<void>;
|
|
33
|
+
removeWorld(id: UUID): Promise<void>;
|
|
34
|
+
createRooms(rooms: Room[]): Promise<UUID[]>;
|
|
35
|
+
updateRoom(room: Room): Promise<void>;
|
|
36
|
+
deleteRoom(roomId: UUID): Promise<void>;
|
|
37
|
+
addParticipant(entityId: UUID, roomId: UUID): Promise<boolean>;
|
|
38
|
+
removeParticipant(entityId: UUID, roomId: UUID): Promise<boolean>;
|
|
39
|
+
createMemory(memory: Memory & {
|
|
40
|
+
metadata?: MemoryMetadata;
|
|
41
|
+
}, tableName: string): Promise<UUID>;
|
|
42
|
+
updateMemory(memory: Partial<Memory> & {
|
|
43
|
+
id: UUID;
|
|
44
|
+
metadata?: MemoryMetadata;
|
|
45
|
+
}): Promise<boolean>;
|
|
46
|
+
deleteMemory(memoryId: UUID): Promise<void>;
|
|
47
|
+
deleteManyMemories(memoryIds: UUID[]): Promise<void>;
|
|
48
|
+
deleteAllMemories(roomIds: UUID[], tableName: string): Promise<void>;
|
|
49
|
+
deleteAllMemories(roomId: UUID, tableName: string): Promise<void>;
|
|
50
|
+
createRelationship(params: {
|
|
51
|
+
sourceEntityId: UUID;
|
|
52
|
+
targetEntityId: UUID;
|
|
53
|
+
tags?: string[];
|
|
54
|
+
metadata?: {
|
|
55
|
+
[key: string]: unknown;
|
|
56
|
+
};
|
|
57
|
+
}): Promise<boolean>;
|
|
58
|
+
updateRelationship(relationship: Relationship): Promise<void>;
|
|
59
|
+
deleteRelationships(relationshipIds: UUID[]): Promise<void>;
|
|
60
|
+
createTask(task: Task): Promise<UUID>;
|
|
61
|
+
updateTask(id: UUID, task: Partial<Task>): Promise<void>;
|
|
62
|
+
deleteTask(id: UUID): Promise<void>;
|
|
63
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export declare const PGLITE_ERROR_CODES: {
|
|
2
|
+
readonly ACTIVE_LOCK: "ELIZA_PGLITE_DATA_DIR_IN_USE";
|
|
3
|
+
readonly CORRUPT_DATA: "ELIZA_PGLITE_CORRUPT_DATA";
|
|
4
|
+
readonly MANUAL_RESET_REQUIRED: "ELIZA_PGLITE_MANUAL_RESET_REQUIRED";
|
|
5
|
+
};
|
|
6
|
+
export type PgliteErrorCode = (typeof PGLITE_ERROR_CODES)[keyof typeof PGLITE_ERROR_CODES];
|
|
7
|
+
export declare class PgliteInitError extends Error {
|
|
8
|
+
readonly code: PgliteErrorCode;
|
|
9
|
+
readonly dataDir?: string;
|
|
10
|
+
constructor(code: PgliteErrorCode, message: string, options?: {
|
|
11
|
+
cause?: unknown;
|
|
12
|
+
dataDir?: string;
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
export declare function createPgliteInitError(code: PgliteErrorCode, message: string, options?: {
|
|
16
|
+
cause?: unknown;
|
|
17
|
+
dataDir?: string;
|
|
18
|
+
}): PgliteInitError;
|
|
19
|
+
export declare function getPgliteErrorCode(err: unknown): PgliteErrorCode | null;
|
|
20
|
+
export declare function isFatalPgliteErrorCode(code: unknown): code is PgliteErrorCode;
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
import { PGlite, type PGliteOptions } from "@electric-sql/pglite";
|
|
2
|
+
import type { IDatabaseClientManager } from "../types.js";
|
|
3
|
+
import { WriteBackService } from "../write-back/index.js";
|
|
4
|
+
/**
|
|
5
|
+
* Canonical list of table names synced via Electric and tracked by the
|
|
6
|
+
* write-back service. Used by both syncShapesToTables (read path) and
|
|
7
|
+
* PgliteDatabaseAdapter (write path) so the two stay in sync.
|
|
8
|
+
*/
|
|
9
|
+
export declare const SYNCED_TABLE_NAMES: readonly ["agents", "entities", "worlds", "rooms", "participants", "memories", "relationships", "tasks"];
|
|
10
|
+
/**
|
|
11
|
+
* Runtime sync status of the Electric Sync client wired into PGlite.
|
|
12
|
+
* - syncing: the sync stream is connecting or catching up with the source.
|
|
13
|
+
* - synced: the local PGlite is up-to-date with the Electric source.
|
|
14
|
+
* - error: the sync stream encountered a non-recoverable error.
|
|
15
|
+
* - disabled: no ELIZA_ELECTRIC_SYNC_URL was configured at boot.
|
|
16
|
+
*/
|
|
17
|
+
export type PgliteSyncStatus = "syncing" | "synced" | "error" | "disabled";
|
|
18
|
+
/** Per-table sync state. */
|
|
19
|
+
export type PgliteSyncTableState = "pending" | "synced" | "error";
|
|
20
|
+
/** Per-table status map exposed by getSyncStatus(). */
|
|
21
|
+
export type PgliteSyncTableStatus = Record<string, {
|
|
22
|
+
state: PgliteSyncTableState;
|
|
23
|
+
error?: string;
|
|
24
|
+
}>;
|
|
25
|
+
/**
|
|
26
|
+
* Result row type for live queries. Matches the shape returned by
|
|
27
|
+
* {@link https://pglite.dev/docs/live-queries | pg.live.query()}.
|
|
28
|
+
*/
|
|
29
|
+
export interface LiveQueryResult<T = Record<string, unknown>> {
|
|
30
|
+
rows: T[];
|
|
31
|
+
fields: {
|
|
32
|
+
name: string;
|
|
33
|
+
dataTypeID: number;
|
|
34
|
+
}[];
|
|
35
|
+
affectedRows?: number;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Return value from {@link https://pglite.dev/docs/live-queries | pg.live.query()}.
|
|
39
|
+
*/
|
|
40
|
+
export interface LiveQueryReturn<T = Record<string, unknown>> {
|
|
41
|
+
initialResults: LiveQueryResult<T>;
|
|
42
|
+
unsubscribe: () => Promise<void>;
|
|
43
|
+
refresh: (options?: {
|
|
44
|
+
offset?: number;
|
|
45
|
+
limit?: number;
|
|
46
|
+
}) => Promise<void>;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* The `pg.live` namespace added by the `@electric-sql/pglite/live` extension.
|
|
50
|
+
*/
|
|
51
|
+
export interface LiveNamespace {
|
|
52
|
+
query<T = Record<string, unknown>>(sql: string, params: unknown[] | undefined, callback: (result: LiveQueryResult<T>) => void): Promise<LiveQueryReturn<T>>;
|
|
53
|
+
incrementalQuery<T = Record<string, unknown>>(sql: string, params: unknown[] | undefined, key: string, callback: (result: LiveQueryResult<T>) => void): Promise<LiveQueryReturn<T>>;
|
|
54
|
+
changes<T = Record<string, unknown>>(sql: string, params: unknown[] | undefined, key: string, callback: (changes: unknown[]) => void): Promise<LiveQueryReturn<T>>;
|
|
55
|
+
}
|
|
56
|
+
export declare class PGliteClientManager implements IDatabaseClientManager<PGlite> {
|
|
57
|
+
private static readonly LOCK_STALE_MS;
|
|
58
|
+
private client;
|
|
59
|
+
private options;
|
|
60
|
+
private shuttingDown;
|
|
61
|
+
private initialized;
|
|
62
|
+
private initializePromise;
|
|
63
|
+
private lockFd;
|
|
64
|
+
private lockPath;
|
|
65
|
+
private syncUrl;
|
|
66
|
+
private agentId;
|
|
67
|
+
private syncStatus;
|
|
68
|
+
private syncError;
|
|
69
|
+
private syncUnsubscribe;
|
|
70
|
+
private syncTableStates;
|
|
71
|
+
private syncedTables;
|
|
72
|
+
private startSyncMutex;
|
|
73
|
+
private forceResyncMutex;
|
|
74
|
+
private writeBack;
|
|
75
|
+
constructor(options: PGliteOptions & {
|
|
76
|
+
syncUrl?: string;
|
|
77
|
+
agentId?: string;
|
|
78
|
+
writeBackBaseUrl?: string;
|
|
79
|
+
serviceKey?: string;
|
|
80
|
+
});
|
|
81
|
+
getConnection(): PGlite;
|
|
82
|
+
/**
|
|
83
|
+
* Access the write-back service for forwarding local writes to the
|
|
84
|
+
* cloud API. Returns null when write-back is not configured.
|
|
85
|
+
*/
|
|
86
|
+
getWriteBack(): WriteBackService | null;
|
|
87
|
+
/**
|
|
88
|
+
* Notify the write-back service of a local write to a sync table.
|
|
89
|
+
* Called by the adapter after a successful write operation.
|
|
90
|
+
* No-op when write-back is not configured.
|
|
91
|
+
*/
|
|
92
|
+
notifyWrite(table: string, operation: "insert" | "upsert" | "delete", row: Record<string, unknown>): void;
|
|
93
|
+
/**
|
|
94
|
+
* Current Electric Sync status.
|
|
95
|
+
* - "disabled": no ELIZA_ELECTRIC_SYNC_URL was configured.
|
|
96
|
+
* - "syncing": sync client is connecting or catching up.
|
|
97
|
+
* - "synced": local PGlite is up-to-date with the Electric source.
|
|
98
|
+
* - "error": sync encountered an error (see syncError).
|
|
99
|
+
*
|
|
100
|
+
* Also returns per-table state so operators can see which specific
|
|
101
|
+
* tables are healthy vs errored vs still pending.
|
|
102
|
+
*/
|
|
103
|
+
getSyncStatus(): {
|
|
104
|
+
status: PgliteSyncStatus;
|
|
105
|
+
error: string | null;
|
|
106
|
+
tables: PgliteSyncTableStatus;
|
|
107
|
+
synced: string[];
|
|
108
|
+
};
|
|
109
|
+
isShuttingDown(): boolean;
|
|
110
|
+
isInitialized(): boolean;
|
|
111
|
+
initialize(): Promise<void>;
|
|
112
|
+
close(): Promise<void>;
|
|
113
|
+
private setupShutdownHandlers;
|
|
114
|
+
private createClient;
|
|
115
|
+
private getDataDir;
|
|
116
|
+
private isFileBackedDataDir;
|
|
117
|
+
private getDataDirLockPath;
|
|
118
|
+
private getLockInfo;
|
|
119
|
+
/**
|
|
120
|
+
* Decide whether an existing lock should be honored as held by a live owner.
|
|
121
|
+
*
|
|
122
|
+
* Single-writer safety comes first: a *confirmed-running* PID is always
|
|
123
|
+
* honored, regardless of how old its `createdAt` is. A long-running agent
|
|
124
|
+
* (days or weeks of uptime) must never have its live lock reclaimed by a
|
|
125
|
+
* second manager — that would open a dual-writer window, which is
|
|
126
|
+
* unrecoverable, whereas a falsely-bricked boot is recoverable by removing
|
|
127
|
+
* the lock file. This matches the sibling `reconcilePglitePidFile`, which
|
|
128
|
+
* also treats a live PID as "active".
|
|
129
|
+
*
|
|
130
|
+
* The staleness window only rescues the *unconfirmable* case. A bare
|
|
131
|
+
* `process.kill(pid, 0)` is vulnerable to PID reuse, and a recycled
|
|
132
|
+
* cross-user PID surfaces as `EPERM` (or another non-`ESRCH` error) rather
|
|
133
|
+
* than a clean success. For those we cannot prove the PID belongs to a live
|
|
134
|
+
* Eliza process, so we fall back to `createdAt`: a recent lock is still
|
|
135
|
+
* respected, but one older than `LOCK_STALE_MS` (or with no usable timestamp)
|
|
136
|
+
* is treated as stale and reclaimed so an aliased PID cannot brick boot
|
|
137
|
+
* forever. `ESRCH` is unambiguous — the process is gone and the lock is stale.
|
|
138
|
+
*/
|
|
139
|
+
private isLockActive;
|
|
140
|
+
private acquireDataDirLockIfNeeded;
|
|
141
|
+
private releaseDataDirLock;
|
|
142
|
+
private getErrorText;
|
|
143
|
+
private reconcilePglitePidFile;
|
|
144
|
+
private createActiveLockError;
|
|
145
|
+
private createManualResetRequiredError;
|
|
146
|
+
private queryMigrationsSchema;
|
|
147
|
+
/**
|
|
148
|
+
* Ensure the Electric Sync stream is started. Idempotent — safe to call
|
|
149
|
+
* on every database operation. The first call after PGlite is initialized
|
|
150
|
+
* and after migrations have created the target tables will start the sync
|
|
151
|
+
* stream; subsequent calls are no-ops.
|
|
152
|
+
*
|
|
153
|
+
* This is deliberately separate from {@link initialize} because the Drizzle
|
|
154
|
+
* migrations that create the target tables run AFTER plugin init completes.
|
|
155
|
+
* Starting sync during init would try to insert into non-existent tables.
|
|
156
|
+
*/
|
|
157
|
+
ensureSync(): Promise<void>;
|
|
158
|
+
/**
|
|
159
|
+
* Access the PGlite live query namespace for reactive queries that
|
|
160
|
+
* push updated results whenever the underlying tables change. Useful
|
|
161
|
+
* for dashboard health endpoints and real-time monitoring.
|
|
162
|
+
*
|
|
163
|
+
* Returns the {@link https://pglite.dev/docs/live-queries | pg.live}
|
|
164
|
+
* namespace, which provides:
|
|
165
|
+
* - `live.query(sql, params, callback)` — simple live query
|
|
166
|
+
* - `live.incrementalQuery(sql, params, key, callback)` — diff-based
|
|
167
|
+
* - `live.changes(sql, params, key, callback)` — raw change stream
|
|
168
|
+
*
|
|
169
|
+
* Returns null when PGlite extensions are disabled.
|
|
170
|
+
*/
|
|
171
|
+
liveQuery(): LiveNamespace | null;
|
|
172
|
+
/**
|
|
173
|
+
* Force-reset the Electric Sync stream: unsubscribe, drop all internal
|
|
174
|
+
* sync state from the `electric` schema, and restart from scratch.
|
|
175
|
+
*
|
|
176
|
+
* Use this when operators diagnose a split-brain scenario (local PGlite
|
|
177
|
+
* has diverged from the source Postgres) or when the sync stream is
|
|
178
|
+
* stuck in an unrecoverable error state. The local data in the synced
|
|
179
|
+
* tables is preserved — only the Electric metadata tables are dropped,
|
|
180
|
+
* forcing a full re-sync that reconstructs state from the source.
|
|
181
|
+
*
|
|
182
|
+
* Returns the sync status after the reset. When sync is not configured
|
|
183
|
+
* (no ELIZA_ELECTRIC_SYNC_URL), returns null.
|
|
184
|
+
*/
|
|
185
|
+
forceResync(): Promise<{
|
|
186
|
+
status: PgliteSyncStatus;
|
|
187
|
+
error: string | null;
|
|
188
|
+
tables: PgliteSyncTableStatus;
|
|
189
|
+
synced: string[];
|
|
190
|
+
} | null>;
|
|
191
|
+
private forceResyncInternal;
|
|
192
|
+
/**
|
|
193
|
+
* Start the Electric Sync stream after PGlite is initialized.
|
|
194
|
+
* Uses the official multi-table {@link https://pglite.dev/docs/sync#multi-table-sync | syncShapesToTables}
|
|
195
|
+
* API so all shape updates that happened in a single Postgres transaction
|
|
196
|
+
* are applied in a single PGlite transaction, preserving consistency
|
|
197
|
+
* across all runtime tables.
|
|
198
|
+
*
|
|
199
|
+
* Each shape is filtered by agent_id so that in a shared-Neon deployment
|
|
200
|
+
* an agent only syncs its own data — preserving per-agent physical isolation
|
|
201
|
+
* even though the source Postgres is multi-tenant.
|
|
202
|
+
*
|
|
203
|
+
* Sync failures are non-fatal: the agent runs on its local PGlite
|
|
204
|
+
* regardless of sync health. Per-table error state is tracked so
|
|
205
|
+
* operators can diagnose individual table issues without assuming
|
|
206
|
+
* the entire sync is broken.
|
|
207
|
+
*/
|
|
208
|
+
private startSync;
|
|
209
|
+
/** Internal body of startSync, extracted so the mutex wraps only the
|
|
210
|
+
* syncShapesToTables call, not the early-return guards. */
|
|
211
|
+
private startSyncInternal;
|
|
212
|
+
private initializeInternal;
|
|
213
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type IDatabaseAdapter } from "@elizaos/core";
|
|
2
|
+
export declare function installRLSFunctions(adapter: IDatabaseAdapter): Promise<void>;
|
|
3
|
+
export declare function getOrCreateRlsServer(adapter: IDatabaseAdapter, serverId: string): Promise<string>;
|
|
4
|
+
export declare function setServerContext(adapter: IDatabaseAdapter, serverId: string): Promise<void>;
|
|
5
|
+
export declare function assignAgentToServer(adapter: IDatabaseAdapter, agentId: string, serverId: string): Promise<void>;
|
|
6
|
+
/**
|
|
7
|
+
* Apply RLS to all tables by calling PostgreSQL function
|
|
8
|
+
*/
|
|
9
|
+
export declare function applyRLSToNewTables(adapter: IDatabaseAdapter): Promise<void>;
|
|
10
|
+
export declare function uninstallRLS(adapter: IDatabaseAdapter): Promise<void>;
|
|
11
|
+
export declare function installEntityRLS(adapter: IDatabaseAdapter): Promise<void>;
|
|
12
|
+
export declare function applyEntityRLSToAllTables(adapter: IDatabaseAdapter): Promise<void>;
|
|
13
|
+
export declare function uninstallEntityRLS(adapter: IDatabaseAdapter): Promise<void>;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Browser-compatible crypto utilities
|
|
3
|
+
* Uses the Web Crypto API which is available in both browsers and Node.js
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Simple synchronous hash function for change detection
|
|
7
|
+
* This is NOT cryptographic - it's just for comparing snapshots
|
|
8
|
+
* Uses djb2 hash algorithm for speed and simplicity
|
|
9
|
+
*/
|
|
10
|
+
export declare function simpleHash(str: string): string;
|
|
11
|
+
/**
|
|
12
|
+
* Create a longer hash by combining multiple passes
|
|
13
|
+
* This provides better distribution for larger inputs
|
|
14
|
+
*/
|
|
15
|
+
export declare function extendedHash(str: string): string;
|
|
16
|
+
/**
|
|
17
|
+
* Async SHA-256 hash using Web Crypto API
|
|
18
|
+
* Works in both browsers and Node.js (v15+)
|
|
19
|
+
*/
|
|
20
|
+
export declare function sha256Async(data: string): Promise<string>;
|
|
21
|
+
/**
|
|
22
|
+
* Generate a stable bigint from a string for advisory lock IDs
|
|
23
|
+
* Uses a simple hash that produces consistent results across runs
|
|
24
|
+
*/
|
|
25
|
+
export declare function stringToBigInt(str: string): bigint;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { DrizzleDB, SchemaSnapshot } from "../types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Introspect the current database state and generate a snapshot
|
|
4
|
+
* This is used when no previous snapshot exists for a plugin
|
|
5
|
+
* to capture the existing database state before migrations
|
|
6
|
+
*/
|
|
7
|
+
export declare class DatabaseIntrospector {
|
|
8
|
+
private db;
|
|
9
|
+
constructor(db: DrizzleDB);
|
|
10
|
+
/**
|
|
11
|
+
* Introspect all tables in the database and generate a snapshot
|
|
12
|
+
* @param schemaName - Schema to introspect (default: 'public')
|
|
13
|
+
* @returns Schema snapshot of current database state
|
|
14
|
+
*/
|
|
15
|
+
introspectSchema(schemaName?: string): Promise<SchemaSnapshot>;
|
|
16
|
+
/**
|
|
17
|
+
* Get all tables in a schema
|
|
18
|
+
*/
|
|
19
|
+
private getTables;
|
|
20
|
+
/**
|
|
21
|
+
* Get columns for a table
|
|
22
|
+
*/
|
|
23
|
+
private getColumns;
|
|
24
|
+
/**
|
|
25
|
+
* Get indexes for a table
|
|
26
|
+
*/
|
|
27
|
+
private getIndexes;
|
|
28
|
+
/**
|
|
29
|
+
* Get foreign keys for a table
|
|
30
|
+
*/
|
|
31
|
+
private getForeignKeys;
|
|
32
|
+
/**
|
|
33
|
+
* Get primary keys for a table
|
|
34
|
+
*/
|
|
35
|
+
private getPrimaryKeys;
|
|
36
|
+
/**
|
|
37
|
+
* Get unique constraints for a table
|
|
38
|
+
*/
|
|
39
|
+
private getUniqueConstraints;
|
|
40
|
+
/**
|
|
41
|
+
* Get check constraints for a table
|
|
42
|
+
*/
|
|
43
|
+
private getCheckConstraints;
|
|
44
|
+
/**
|
|
45
|
+
* Get enums in a schema
|
|
46
|
+
*/
|
|
47
|
+
private getEnums;
|
|
48
|
+
/**
|
|
49
|
+
* Parse default value for a column
|
|
50
|
+
*/
|
|
51
|
+
private parseDefault;
|
|
52
|
+
/**
|
|
53
|
+
* Check if tables exist for a plugin by checking if any tables exist in its schema
|
|
54
|
+
* @param pluginName - Name of the plugin
|
|
55
|
+
* @returns True if tables exist, false otherwise
|
|
56
|
+
*/
|
|
57
|
+
hasExistingTables(pluginName: string): Promise<boolean>;
|
|
58
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import type { SchemaCheckConstraint, SchemaColumn, SchemaForeignKey, SchemaIndex, SchemaSnapshot, SchemaUniqueConstraint } from "../types.js";
|
|
2
|
+
export interface ColumnChanges {
|
|
3
|
+
typeChanged?: boolean;
|
|
4
|
+
prevType?: string;
|
|
5
|
+
newType?: string;
|
|
6
|
+
nullabilityChanged?: boolean;
|
|
7
|
+
wasNullable?: boolean;
|
|
8
|
+
isNullable?: boolean;
|
|
9
|
+
defaultChanged?: boolean;
|
|
10
|
+
prevDefault?: string | number | boolean;
|
|
11
|
+
newDefault?: string | number | boolean;
|
|
12
|
+
from?: SchemaColumn;
|
|
13
|
+
to?: SchemaColumn;
|
|
14
|
+
}
|
|
15
|
+
export interface TableChanges {
|
|
16
|
+
columnsAdded: string[];
|
|
17
|
+
columnsDeleted: string[];
|
|
18
|
+
columnsModified: string[];
|
|
19
|
+
}
|
|
20
|
+
export interface SchemaDiff {
|
|
21
|
+
tables: {
|
|
22
|
+
created: string[];
|
|
23
|
+
deleted: string[];
|
|
24
|
+
modified: Array<{
|
|
25
|
+
name: string;
|
|
26
|
+
changes: TableChanges;
|
|
27
|
+
}>;
|
|
28
|
+
};
|
|
29
|
+
columns: {
|
|
30
|
+
added: Array<{
|
|
31
|
+
table: string;
|
|
32
|
+
column: string;
|
|
33
|
+
definition: SchemaColumn;
|
|
34
|
+
}>;
|
|
35
|
+
deleted: Array<{
|
|
36
|
+
table: string;
|
|
37
|
+
column: string;
|
|
38
|
+
}>;
|
|
39
|
+
modified: Array<{
|
|
40
|
+
table: string;
|
|
41
|
+
column: string;
|
|
42
|
+
changes: ColumnChanges;
|
|
43
|
+
}>;
|
|
44
|
+
};
|
|
45
|
+
indexes: {
|
|
46
|
+
created: SchemaIndex[];
|
|
47
|
+
deleted: SchemaIndex[];
|
|
48
|
+
altered: Array<{
|
|
49
|
+
old: SchemaIndex;
|
|
50
|
+
new: SchemaIndex;
|
|
51
|
+
}>;
|
|
52
|
+
};
|
|
53
|
+
foreignKeys: {
|
|
54
|
+
created: SchemaForeignKey[];
|
|
55
|
+
deleted: SchemaForeignKey[];
|
|
56
|
+
altered: Array<{
|
|
57
|
+
old: SchemaForeignKey;
|
|
58
|
+
new: SchemaForeignKey;
|
|
59
|
+
}>;
|
|
60
|
+
};
|
|
61
|
+
uniqueConstraints: {
|
|
62
|
+
created: SchemaUniqueConstraint[];
|
|
63
|
+
deleted: SchemaUniqueConstraint[];
|
|
64
|
+
};
|
|
65
|
+
checkConstraints: {
|
|
66
|
+
created: SchemaCheckConstraint[];
|
|
67
|
+
deleted: SchemaCheckConstraint[];
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Calculate the difference between two snapshots
|
|
72
|
+
*/
|
|
73
|
+
export declare function calculateDiff(previousSnapshot: SchemaSnapshot | null, currentSnapshot: SchemaSnapshot): Promise<SchemaDiff>;
|
|
74
|
+
/**
|
|
75
|
+
* Check if a diff has any changes
|
|
76
|
+
*/
|
|
77
|
+
export declare function hasDiffChanges(diff: SchemaDiff): boolean;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { SchemaSnapshot } from "../types.js";
|
|
2
|
+
type DrizzleSchema = Record<string, unknown>;
|
|
3
|
+
/**
|
|
4
|
+
* Generate a snapshot from a Drizzle schema
|
|
5
|
+
* This is a port of Drizzle's pgSerializer.generatePgSnapshot
|
|
6
|
+
*/
|
|
7
|
+
export declare function generateSnapshot(schema: DrizzleSchema): Promise<SchemaSnapshot>;
|
|
8
|
+
/**
|
|
9
|
+
* Calculate hash of a snapshot for change detection
|
|
10
|
+
* Uses a browser-compatible hash function
|
|
11
|
+
*/
|
|
12
|
+
export declare function hashSnapshot(snapshot: SchemaSnapshot): string;
|
|
13
|
+
/**
|
|
14
|
+
* Create an empty snapshot for initial migration
|
|
15
|
+
*/
|
|
16
|
+
export declare function createEmptySnapshot(): SchemaSnapshot;
|
|
17
|
+
/**
|
|
18
|
+
* Compare two snapshots and detect if there are changes
|
|
19
|
+
*/
|
|
20
|
+
export declare function hasChanges(previousSnapshot: SchemaSnapshot | null, currentSnapshot: SchemaSnapshot): boolean;
|
|
21
|
+
export {};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { SchemaSnapshot } from "../types.js";
|
|
2
|
+
import type { SchemaDiff } from "./diff-calculator.js";
|
|
3
|
+
/**
|
|
4
|
+
* Data loss detection result
|
|
5
|
+
* Based on Drizzle's pgPushUtils approach
|
|
6
|
+
*/
|
|
7
|
+
export interface DataLossCheck {
|
|
8
|
+
hasDataLoss: boolean;
|
|
9
|
+
tablesToRemove: string[];
|
|
10
|
+
columnsToRemove: string[];
|
|
11
|
+
tablesToTruncate: string[];
|
|
12
|
+
typeChanges: Array<{
|
|
13
|
+
table: string;
|
|
14
|
+
column: string;
|
|
15
|
+
from: string;
|
|
16
|
+
to: string;
|
|
17
|
+
}>;
|
|
18
|
+
warnings: string[];
|
|
19
|
+
requiresConfirmation: boolean;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Check for potential data loss in schema changes
|
|
23
|
+
* Based on Drizzle's pgSuggestions function
|
|
24
|
+
*/
|
|
25
|
+
export declare function checkForDataLoss(diff: SchemaDiff): DataLossCheck;
|
|
26
|
+
/**
|
|
27
|
+
* Generate SQL statements from a schema diff
|
|
28
|
+
* This follows Drizzle's approach: create all tables first, then add foreign keys
|
|
29
|
+
*/
|
|
30
|
+
export declare function generateMigrationSQL(previousSnapshot: SchemaSnapshot | null, currentSnapshot: SchemaSnapshot, diff?: SchemaDiff): Promise<string[]>;
|
|
31
|
+
/**
|
|
32
|
+
* Generate SQL for renaming a table
|
|
33
|
+
*/
|
|
34
|
+
export declare function generateRenameTableSQL(oldName: string, newName: string): string;
|
|
35
|
+
/**
|
|
36
|
+
* Generate SQL for renaming a column
|
|
37
|
+
*/
|
|
38
|
+
export declare function generateRenameColumnSQL(table: string, oldName: string, newName: string): string;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { calculateDiff, hasDiffChanges, type SchemaDiff, } from "./drizzle-adapters/diff-calculator.js";
|
|
2
|
+
export { createEmptySnapshot, generateSnapshot, hasChanges, hashSnapshot, } from "./drizzle-adapters/snapshot-generator.js";
|
|
3
|
+
export { generateMigrationSQL, generateRenameColumnSQL, generateRenameTableSQL, } from "./drizzle-adapters/sql-generator.js";
|
|
4
|
+
export { RuntimeMigrator } from "./runtime-migrator.js";
|
|
5
|
+
export { JournalStorage } from "./storage/journal-storage.js";
|
|
6
|
+
export { MigrationTracker } from "./storage/migration-tracker.js";
|
|
7
|
+
export { SnapshotStorage } from "./storage/snapshot-storage.js";
|
|
8
|
+
export * from "./types.js";
|