swarm-mail 0.1.0 → 0.1.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.
Files changed (75) hide show
  1. package/README.md +28 -0
  2. package/dist/adapter.d.ts +36 -0
  3. package/dist/adapter.d.ts.map +1 -0
  4. package/dist/index.d.ts +22 -0
  5. package/dist/index.d.ts.map +1 -0
  6. package/dist/index.js +16710 -0
  7. package/{src/pglite.ts → dist/pglite.d.ts} +7 -93
  8. package/dist/pglite.d.ts.map +1 -0
  9. package/dist/streams/agent-mail.d.ts +139 -0
  10. package/dist/streams/agent-mail.d.ts.map +1 -0
  11. package/dist/streams/debug.d.ts +173 -0
  12. package/dist/streams/debug.d.ts.map +1 -0
  13. package/dist/streams/effect/ask.d.ts +124 -0
  14. package/dist/streams/effect/ask.d.ts.map +1 -0
  15. package/dist/streams/effect/cursor.d.ts +87 -0
  16. package/dist/streams/effect/cursor.d.ts.map +1 -0
  17. package/dist/streams/effect/deferred.d.ts +108 -0
  18. package/dist/streams/effect/deferred.d.ts.map +1 -0
  19. package/{src/streams/effect/index.ts → dist/streams/effect/index.d.ts} +1 -0
  20. package/dist/streams/effect/index.d.ts.map +1 -0
  21. package/{src/streams/effect/layers.ts → dist/streams/effect/layers.d.ts} +8 -33
  22. package/dist/streams/effect/layers.d.ts.map +1 -0
  23. package/dist/streams/effect/lock.d.ts +137 -0
  24. package/dist/streams/effect/lock.d.ts.map +1 -0
  25. package/dist/streams/effect/mailbox.d.ts +98 -0
  26. package/dist/streams/effect/mailbox.d.ts.map +1 -0
  27. package/dist/streams/events.d.ts +487 -0
  28. package/dist/streams/events.d.ts.map +1 -0
  29. package/dist/streams/index.d.ts +106 -0
  30. package/dist/streams/index.d.ts.map +1 -0
  31. package/dist/streams/migrations.d.ts +102 -0
  32. package/dist/streams/migrations.d.ts.map +1 -0
  33. package/dist/streams/projections.d.ts +173 -0
  34. package/dist/streams/projections.d.ts.map +1 -0
  35. package/dist/streams/store.d.ts +171 -0
  36. package/dist/streams/store.d.ts.map +1 -0
  37. package/dist/streams/swarm-mail.d.ts +153 -0
  38. package/dist/streams/swarm-mail.d.ts.map +1 -0
  39. package/dist/types/adapter.d.ts +267 -0
  40. package/dist/types/adapter.d.ts.map +1 -0
  41. package/dist/types/database.d.ts +117 -0
  42. package/dist/types/database.d.ts.map +1 -0
  43. package/{src/types/index.ts → dist/types/index.d.ts} +2 -15
  44. package/dist/types/index.d.ts.map +1 -0
  45. package/package.json +21 -5
  46. package/src/adapter.ts +0 -306
  47. package/src/index.ts +0 -57
  48. package/src/streams/agent-mail.test.ts +0 -777
  49. package/src/streams/agent-mail.ts +0 -535
  50. package/src/streams/debug.test.ts +0 -500
  51. package/src/streams/debug.ts +0 -727
  52. package/src/streams/effect/ask.integration.test.ts +0 -314
  53. package/src/streams/effect/ask.ts +0 -202
  54. package/src/streams/effect/cursor.integration.test.ts +0 -418
  55. package/src/streams/effect/cursor.ts +0 -288
  56. package/src/streams/effect/deferred.test.ts +0 -357
  57. package/src/streams/effect/deferred.ts +0 -445
  58. package/src/streams/effect/lock.test.ts +0 -385
  59. package/src/streams/effect/lock.ts +0 -399
  60. package/src/streams/effect/mailbox.test.ts +0 -260
  61. package/src/streams/effect/mailbox.ts +0 -318
  62. package/src/streams/events.test.ts +0 -924
  63. package/src/streams/events.ts +0 -329
  64. package/src/streams/index.test.ts +0 -229
  65. package/src/streams/index.ts +0 -578
  66. package/src/streams/migrations.test.ts +0 -359
  67. package/src/streams/migrations.ts +0 -362
  68. package/src/streams/projections.test.ts +0 -611
  69. package/src/streams/projections.ts +0 -564
  70. package/src/streams/store.integration.test.ts +0 -658
  71. package/src/streams/store.ts +0 -1129
  72. package/src/streams/swarm-mail.ts +0 -552
  73. package/src/types/adapter.ts +0 -392
  74. package/src/types/database.ts +0 -127
  75. package/tsconfig.json +0 -22
@@ -0,0 +1,267 @@
1
+ /**
2
+ * SwarmMailAdapter - High-level interface for swarm-mail operations
3
+ *
4
+ * This interface abstracts all swarm-mail operations (events, messaging,
5
+ * reservations, locks) to enable different storage backends.
6
+ *
7
+ * ## Design Goals
8
+ * - Database-agnostic (works with PGLite, SQLite, PostgreSQL, etc.)
9
+ * - Matches existing swarm-mail API surface
10
+ * - No implementation details leak through interface
11
+ *
12
+ * ## Layering
13
+ * - DatabaseAdapter: Low-level SQL execution
14
+ * - SwarmMailAdapter: High-level swarm-mail operations (uses DatabaseAdapter internally)
15
+ * - Plugin tools: Type-safe Zod-validated wrappers (use SwarmMailAdapter)
16
+ */
17
+ import type { AgentEvent, AgentRegisteredEvent, FileReservedEvent, MessageSentEvent } from "../streams/events";
18
+ import type { DatabaseAdapter } from "./database";
19
+ export interface ReadEventsOptions {
20
+ projectKey?: string;
21
+ types?: AgentEvent["type"][];
22
+ since?: number;
23
+ until?: number;
24
+ afterSequence?: number;
25
+ limit?: number;
26
+ offset?: number;
27
+ }
28
+ export interface EventStoreAdapter {
29
+ /**
30
+ * Append a single event to the log
31
+ *
32
+ * Updates materialized views automatically.
33
+ */
34
+ appendEvent(event: AgentEvent, projectPath?: string): Promise<AgentEvent & {
35
+ id: number;
36
+ sequence: number;
37
+ }>;
38
+ /**
39
+ * Append multiple events in a transaction
40
+ *
41
+ * Atomic - all events succeed or all fail.
42
+ */
43
+ appendEvents(events: AgentEvent[], projectPath?: string): Promise<Array<AgentEvent & {
44
+ id: number;
45
+ sequence: number;
46
+ }>>;
47
+ /**
48
+ * Read events with filters
49
+ */
50
+ readEvents(options?: ReadEventsOptions, projectPath?: string): Promise<Array<AgentEvent & {
51
+ id: number;
52
+ sequence: number;
53
+ }>>;
54
+ /**
55
+ * Get the latest sequence number for a project
56
+ */
57
+ getLatestSequence(projectKey?: string, projectPath?: string): Promise<number>;
58
+ /**
59
+ * Replay events to rebuild materialized views
60
+ */
61
+ replayEvents(options?: {
62
+ projectKey?: string;
63
+ fromSequence?: number;
64
+ clearViews?: boolean;
65
+ }, projectPath?: string): Promise<{
66
+ eventsReplayed: number;
67
+ duration: number;
68
+ }>;
69
+ }
70
+ export interface AgentAdapter {
71
+ /**
72
+ * Register an agent for a project
73
+ */
74
+ registerAgent(projectKey: string, agentName: string, options?: {
75
+ program?: string;
76
+ model?: string;
77
+ taskDescription?: string;
78
+ }, projectPath?: string): Promise<AgentRegisteredEvent & {
79
+ id: number;
80
+ sequence: number;
81
+ }>;
82
+ /**
83
+ * Get all agents for a project
84
+ */
85
+ getAgents(projectKey: string, projectPath?: string): Promise<Array<{
86
+ id: number;
87
+ name: string;
88
+ program: string;
89
+ model: string;
90
+ task_description: string | null;
91
+ registered_at: number;
92
+ last_active_at: number;
93
+ }>>;
94
+ /**
95
+ * Get a specific agent by name
96
+ */
97
+ getAgent(projectKey: string, agentName: string, projectPath?: string): Promise<{
98
+ id: number;
99
+ name: string;
100
+ program: string;
101
+ model: string;
102
+ task_description: string | null;
103
+ registered_at: number;
104
+ last_active_at: number;
105
+ } | null>;
106
+ }
107
+ export interface InboxOptions {
108
+ limit?: number;
109
+ urgentOnly?: boolean;
110
+ unreadOnly?: boolean;
111
+ includeBodies?: boolean;
112
+ sinceTs?: string;
113
+ }
114
+ export interface Message {
115
+ id: number;
116
+ from_agent: string;
117
+ subject: string;
118
+ body?: string;
119
+ thread_id: string | null;
120
+ importance: string;
121
+ ack_required: boolean;
122
+ created_at: number;
123
+ read_at?: number | null;
124
+ acked_at?: number | null;
125
+ }
126
+ export interface MessagingAdapter {
127
+ /**
128
+ * Send a message to other agents
129
+ */
130
+ sendMessage(projectKey: string, fromAgent: string, toAgents: string[], subject: string, body: string, options?: {
131
+ threadId?: string;
132
+ importance?: "low" | "normal" | "high" | "urgent";
133
+ ackRequired?: boolean;
134
+ }, projectPath?: string): Promise<MessageSentEvent & {
135
+ id: number;
136
+ sequence: number;
137
+ }>;
138
+ /**
139
+ * Get inbox messages for an agent
140
+ */
141
+ getInbox(projectKey: string, agentName: string, options?: InboxOptions, projectPath?: string): Promise<Message[]>;
142
+ /**
143
+ * Get a single message by ID
144
+ */
145
+ getMessage(projectKey: string, messageId: number, projectPath?: string): Promise<Message | null>;
146
+ /**
147
+ * Get all messages in a thread
148
+ */
149
+ getThreadMessages(projectKey: string, threadId: string, projectPath?: string): Promise<Message[]>;
150
+ /**
151
+ * Mark a message as read
152
+ */
153
+ markMessageAsRead(projectKey: string, messageId: number, agentName: string, projectPath?: string): Promise<void>;
154
+ /**
155
+ * Acknowledge a message
156
+ */
157
+ acknowledgeMessage(projectKey: string, messageId: number, agentName: string, projectPath?: string): Promise<void>;
158
+ }
159
+ export interface Reservation {
160
+ id: number;
161
+ agent_name: string;
162
+ path_pattern: string;
163
+ exclusive: boolean;
164
+ reason: string | null;
165
+ created_at: number;
166
+ expires_at: number;
167
+ }
168
+ export interface Conflict {
169
+ path: string;
170
+ holder: string;
171
+ pattern: string;
172
+ exclusive: boolean;
173
+ }
174
+ export interface ReservationAdapter {
175
+ /**
176
+ * Reserve files for exclusive editing
177
+ */
178
+ reserveFiles(projectKey: string, agentName: string, paths: string[], options?: {
179
+ reason?: string;
180
+ exclusive?: boolean;
181
+ ttlSeconds?: number;
182
+ }, projectPath?: string): Promise<FileReservedEvent & {
183
+ id: number;
184
+ sequence: number;
185
+ }>;
186
+ /**
187
+ * Release file reservations
188
+ */
189
+ releaseFiles(projectKey: string, agentName: string, options?: {
190
+ paths?: string[];
191
+ reservationIds?: number[];
192
+ }, projectPath?: string): Promise<void>;
193
+ /**
194
+ * Get active reservations for a project
195
+ */
196
+ getActiveReservations(projectKey: string, projectPath?: string, agentName?: string): Promise<Reservation[]>;
197
+ /**
198
+ * Check for conflicts with existing reservations
199
+ */
200
+ checkConflicts(projectKey: string, agentName: string, paths: string[], projectPath?: string): Promise<Conflict[]>;
201
+ }
202
+ export interface SchemaAdapter {
203
+ /**
204
+ * Run database migrations
205
+ *
206
+ * Initializes tables, indexes, and constraints.
207
+ */
208
+ runMigrations(projectPath?: string): Promise<void>;
209
+ /**
210
+ * Check if database is healthy
211
+ */
212
+ healthCheck(projectPath?: string): Promise<boolean>;
213
+ /**
214
+ * Get database statistics
215
+ */
216
+ getDatabaseStats(projectPath?: string): Promise<{
217
+ events: number;
218
+ agents: number;
219
+ messages: number;
220
+ reservations: number;
221
+ }>;
222
+ /**
223
+ * Reset database for testing
224
+ *
225
+ * Clears all data but keeps schema.
226
+ */
227
+ resetDatabase(projectPath?: string): Promise<void>;
228
+ }
229
+ /**
230
+ * SwarmMailAdapter - Complete interface for swarm-mail operations
231
+ *
232
+ * Combines all sub-adapters into a single interface.
233
+ * Implementations provide a DatabaseAdapter and implement all operations.
234
+ */
235
+ export interface SwarmMailAdapter extends EventStoreAdapter, AgentAdapter, MessagingAdapter, ReservationAdapter, SchemaAdapter {
236
+ /**
237
+ * Get the underlying database adapter
238
+ */
239
+ getDatabase(projectPath?: string): Promise<DatabaseAdapter>;
240
+ /**
241
+ * Close the database connection
242
+ */
243
+ close(projectPath?: string): Promise<void>;
244
+ /**
245
+ * Close all database connections
246
+ */
247
+ closeAll(): Promise<void>;
248
+ }
249
+ /**
250
+ * SwarmMailAdapterFactory - Function that creates a SwarmMailAdapter instance
251
+ *
252
+ * Adapters export a factory function with this signature.
253
+ *
254
+ * @example
255
+ * ```typescript
256
+ * import { createPGLiteAdapter } from '@opencode/swarm-mail/adapters/pglite';
257
+ * import { createSQLiteAdapter } from '@opencode/swarm-mail/adapters/sqlite';
258
+ *
259
+ * const adapter = createPGLiteAdapter({ path: './streams.db' });
260
+ * const adapter2 = createSQLiteAdapter({ path: './streams.db' });
261
+ * ```
262
+ */
263
+ export type SwarmMailAdapterFactory = (config: {
264
+ path?: string;
265
+ timeout?: number;
266
+ }) => SwarmMailAdapter;
267
+ //# sourceMappingURL=adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../src/types/adapter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,117 @@
1
+ /**
2
+ * DatabaseAdapter - Database-agnostic interface for swarm-mail
3
+ *
4
+ * Abstracts PGLite-specific operations to support multiple database backends.
5
+ * Based on coursebuilder's adapter-drizzle pattern.
6
+ *
7
+ * ## Design Goals
8
+ * - Zero PGLite types in this interface
9
+ * - Support for PGLite, better-sqlite3, libsql, PostgreSQL
10
+ * - Transaction support optional (some adapters may not support it)
11
+ *
12
+ * ## Implementation Strategy
13
+ * - Accept database instance via dependency injection
14
+ * - Adapters implement this interface for their specific database
15
+ * - Query results use plain objects (no driver-specific types)
16
+ */
17
+ /**
18
+ * Query result with rows array
19
+ *
20
+ * All database adapters return results in this shape.
21
+ */
22
+ export interface QueryResult<T = unknown> {
23
+ /** Array of result rows */
24
+ rows: T[];
25
+ }
26
+ /**
27
+ * DatabaseAdapter interface
28
+ *
29
+ * Minimal interface for executing SQL queries and managing transactions.
30
+ * Adapters implement this for PGLite, SQLite, PostgreSQL, etc.
31
+ */
32
+ export interface DatabaseAdapter {
33
+ /**
34
+ * Execute a query and return results
35
+ *
36
+ * @param sql - SQL query string (parameterized)
37
+ * @param params - Query parameters ($1, $2, etc.)
38
+ * @returns Query result with rows array
39
+ *
40
+ * @example
41
+ * ```typescript
42
+ * const result = await db.query<{ id: number }>(
43
+ * "SELECT id FROM agents WHERE name = $1",
44
+ * ["BlueLake"]
45
+ * );
46
+ * const id = result.rows[0]?.id;
47
+ * ```
48
+ */
49
+ query<T = unknown>(sql: string, params?: unknown[]): Promise<QueryResult<T>>;
50
+ /**
51
+ * Execute a SQL statement without returning results
52
+ *
53
+ * Used for DDL (CREATE TABLE, etc.), DML (INSERT/UPDATE/DELETE), and transactions.
54
+ *
55
+ * @param sql - SQL statement(s) to execute
56
+ *
57
+ * @example
58
+ * ```typescript
59
+ * await db.exec("BEGIN");
60
+ * await db.exec("COMMIT");
61
+ * await db.exec("CREATE TABLE users (id SERIAL PRIMARY KEY)");
62
+ * ```
63
+ */
64
+ exec(sql: string): Promise<void>;
65
+ /**
66
+ * Execute a function within a transaction (optional)
67
+ *
68
+ * If the adapter doesn't support transactions, it can omit this method
69
+ * or throw an error. The swarm-mail layer will handle transaction
70
+ * fallback (using manual BEGIN/COMMIT/ROLLBACK).
71
+ *
72
+ * @param fn - Function to execute within transaction context
73
+ * @returns Result of the function
74
+ *
75
+ * @example
76
+ * ```typescript
77
+ * const result = await db.transaction?.(async (tx) => {
78
+ * await tx.query("INSERT INTO events ...", [...]);
79
+ * await tx.query("UPDATE agents ...", [...]);
80
+ * return { success: true };
81
+ * });
82
+ * ```
83
+ */
84
+ transaction?<T>(fn: (tx: DatabaseAdapter) => Promise<T>): Promise<T>;
85
+ /**
86
+ * Close the database connection (optional)
87
+ *
88
+ * Some adapters (like PGLite) need explicit cleanup.
89
+ * If not provided, swarm-mail assumes connection is managed externally.
90
+ */
91
+ close?(): Promise<void>;
92
+ }
93
+ /**
94
+ * Database configuration options
95
+ *
96
+ * Passed to adapter factory functions to create DatabaseAdapter instances.
97
+ */
98
+ export interface DatabaseConfig {
99
+ /** Path to database file or connection string */
100
+ path: string;
101
+ /** Optional timeout in milliseconds for queries */
102
+ timeout?: number;
103
+ /** Optional flags for database initialization */
104
+ flags?: {
105
+ /** Create database if it doesn't exist */
106
+ create?: boolean;
107
+ /** Enable foreign key constraints */
108
+ foreignKeys?: boolean;
109
+ /** Enable WAL mode (SQLite) */
110
+ wal?: boolean;
111
+ };
112
+ }
113
+ /**
114
+ * Type guard to check if adapter supports transactions
115
+ */
116
+ export declare function supportsTransactions(adapter: DatabaseAdapter): adapter is Required<Pick<DatabaseAdapter, "transaction">> & DatabaseAdapter;
117
+ //# sourceMappingURL=database.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../src/types/database.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH;;;;GAIG;AACH,MAAM,WAAW,WAAW,CAAC,CAAC,GAAG,OAAO;IACvC,2BAA2B;IAC3B,IAAI,EAAE,CAAC,EAAE,CAAC;CACV;AAED;;;;;GAKG;AACH,MAAM,WAAW,eAAe;IAC/B;;;;;;;;;;;;;;;OAeG;IACH,KAAK,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;IAE7E;;;;;;;;;;;;;OAaG;IACH,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEjC;;;;;;;;;;;;;;;;;;OAkBG;IACH,WAAW,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,eAAe,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAErE;;;;;OAKG;IACH,KAAK,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAC9B,iDAAiD;IACjD,IAAI,EAAE,MAAM,CAAC;IACb,mDAAmD;IACnD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iDAAiD;IACjD,KAAK,CAAC,EAAE;QACP,0CAA0C;QAC1C,MAAM,CAAC,EAAE,OAAO,CAAC;QACjB,qCAAqC;QACrC,WAAW,CAAC,EAAE,OAAO,CAAC;QACtB,+BAA+B;QAC/B,GAAG,CAAC,EAAE,OAAO,CAAC;KACd,CAAC;CACF;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CACnC,OAAO,EAAE,eAAe,GACtB,OAAO,IAAI,QAAQ,CAAC,IAAI,CAAC,eAAe,EAAE,aAAa,CAAC,CAAC,GAAG,eAAe,CAE7E"}
@@ -7,20 +7,7 @@
7
7
  * import type { DatabaseAdapter, SwarmMailAdapter } from '@opencode/swarm-mail/types';
8
8
  * ```
9
9
  */
10
-
11
- export type {
12
- AgentAdapter,
13
- Conflict,
14
- EventStoreAdapter,
15
- InboxOptions,
16
- Message,
17
- MessagingAdapter,
18
- ReadEventsOptions,
19
- Reservation,
20
- ReservationAdapter,
21
- SchemaAdapter,
22
- SwarmMailAdapter,
23
- SwarmMailAdapterFactory,
24
- } from "./adapter";
10
+ export type { AgentAdapter, Conflict, EventStoreAdapter, InboxOptions, Message, MessagingAdapter, ReadEventsOptions, Reservation, ReservationAdapter, SchemaAdapter, SwarmMailAdapter, SwarmMailAdapterFactory, } from "./adapter";
25
11
  export type { DatabaseAdapter, DatabaseConfig, QueryResult } from "./database";
26
12
  export { supportsTransactions } from "./database";
13
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,YAAY,EACX,YAAY,EACZ,QAAQ,EACR,iBAAiB,EACjB,YAAY,EACZ,OAAO,EACP,gBAAgB,EAChB,iBAAiB,EACjB,WAAW,EACX,kBAAkB,EAClB,aAAa,EACb,gBAAgB,EAChB,uBAAuB,GACvB,MAAM,WAAW,CAAC;AACnB,YAAY,EAAE,eAAe,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC/E,OAAO,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC"}
package/package.json CHANGED
@@ -1,23 +1,39 @@
1
1
  {
2
2
  "name": "swarm-mail",
3
- "version": "0.1.0",
3
+ "version": "0.1.3",
4
+ "description": "Event sourcing primitives for multi-agent coordination. Local-first, no external servers.",
4
5
  "type": "module",
5
6
  "main": "./dist/index.js",
6
7
  "types": "./dist/index.d.ts",
8
+ "files": [
9
+ "dist",
10
+ "README.md"
11
+ ],
7
12
  "exports": {
8
13
  ".": {
9
14
  "import": "./dist/index.js",
10
15
  "types": "./dist/index.d.ts"
11
16
  }
12
17
  },
18
+ "repository": {
19
+ "type": "git",
20
+ "url": "https://github.com/joelhooks/opencode-swarm-plugin"
21
+ },
22
+ "author": "Joel Hooks",
23
+ "license": "MIT",
13
24
  "scripts": {
14
- "build": "bun build ./src/index.ts --outdir ./dist --target node && tsc",
15
- "test": "vitest run",
16
- "typecheck": "tsc --noEmit"
25
+ "build": "bun build ./src/index.ts --outdir ./dist --target node --external @electric-sql/pglite && tsc",
26
+ "test": "vitest run --exclude '**/*.integration.test.ts'",
27
+ "test:integration": "vitest run --include '**/*.integration.test.ts' --testTimeout 60000",
28
+ "test:all": "vitest run --testTimeout 60000",
29
+ "typecheck": "tsc --noEmit",
30
+ "publish:pkg": "npm publish --access public --provenance"
17
31
  },
18
32
  "dependencies": {
19
- "effect": "^3.19.12",
20
33
  "@electric-sql/pglite": "0.3.14",
34
+ "effect": "^3.19.12",
35
+ "minimatch": "^10.1.1",
36
+ "nanoid": "^5.1.6",
21
37
  "zod": "4.1.8"
22
38
  },
23
39
  "devDependencies": {