devsess 0.0.0 → 0.2.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 +122 -0
- package/dist/async/define-cli.d.ts +22 -0
- package/dist/async/define-cli.d.ts.map +1 -0
- package/dist/async/dev-sessions.d.ts +21 -0
- package/dist/async/dev-sessions.d.ts.map +1 -0
- package/dist/async/index.d.ts +9 -0
- package/dist/async/index.d.ts.map +1 -0
- package/dist/async/index.js +141 -0
- package/dist/async/index.js.map +1 -0
- package/dist/async/platform.d.ts +41 -0
- package/dist/async/platform.d.ts.map +1 -0
- package/dist/async/run-dev-cli.d.ts +20 -0
- package/dist/async/run-dev-cli.d.ts.map +1 -0
- package/dist/async/run.d.ts +5 -0
- package/dist/async/run.d.ts.map +1 -0
- package/dist/async/session-state.d.ts +13 -0
- package/dist/async/session-state.d.ts.map +1 -0
- package/dist/async/session.d.ts +16 -0
- package/dist/async/session.d.ts.map +1 -0
- package/dist/chunk-AQGYVNYU.js +321 -0
- package/dist/chunk-AQGYVNYU.js.map +1 -0
- package/dist/current-session.d.ts +29 -0
- package/dist/current-session.d.ts.map +1 -0
- package/dist/dev/running-signal.d.ts +29 -0
- package/dist/dev/running-signal.d.ts.map +1 -0
- package/dist/dev/session-state.d.ts +23 -0
- package/dist/dev/session-state.d.ts.map +1 -0
- package/dist/dev/sticky-port.d.ts +4 -0
- package/dist/dev/sticky-port.d.ts.map +1 -0
- package/dist/dev/subprocess.d.ts +5 -0
- package/dist/dev/subprocess.d.ts.map +1 -0
- package/dist/dev-sessions.d.ts +60 -0
- package/dist/dev-sessions.d.ts.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +43 -0
- package/dist/index.js.map +1 -0
- package/dist/pglite/index.d.ts +50 -0
- package/dist/pglite/index.d.ts.map +1 -0
- package/dist/pglite/index.js +218 -0
- package/dist/pglite/index.js.map +1 -0
- package/package.json +86 -1
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { PGlite } from '@electric-sql/pglite';
|
|
2
|
+
import { Effect } from 'effect';
|
|
3
|
+
import { FileSystem } from 'effect/FileSystem';
|
|
4
|
+
import { Path } from 'effect/Path';
|
|
5
|
+
import type { DevSession } from '../dev-sessions';
|
|
6
|
+
declare const PgliteError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
|
|
7
|
+
readonly _tag: "PgliteError";
|
|
8
|
+
} & Readonly<A>;
|
|
9
|
+
export declare class PgliteError extends PgliteError_base<{
|
|
10
|
+
message: string;
|
|
11
|
+
cause?: unknown;
|
|
12
|
+
}> {
|
|
13
|
+
}
|
|
14
|
+
export type PgliteMigrations = {
|
|
15
|
+
migrationsFolder: string;
|
|
16
|
+
migrationsTable?: string;
|
|
17
|
+
migrationsSchema?: string;
|
|
18
|
+
};
|
|
19
|
+
export declare const createPgliteFromDump: (opts: {
|
|
20
|
+
dataDir?: string;
|
|
21
|
+
dumpPath: string;
|
|
22
|
+
}) => Effect.Effect<PGlite, PgliteError | import("effect/PlatformError").PlatformError, FileSystem>;
|
|
23
|
+
export declare const dumpPgliteToFile: (client: PGlite, dest: string) => Effect.Effect<void, PgliteError | import("effect/PlatformError").PlatformError, FileSystem | Path>;
|
|
24
|
+
export declare const migratePglite: (client: PGlite, migrations: PgliteMigrations) => Effect.Effect<void, PgliteError, never>;
|
|
25
|
+
export declare const getDbMigrationCount: (client: PGlite, migrations?: Pick<PgliteMigrations, 'migrationsTable' | 'migrationsSchema'>) => Effect.Effect<number, PgliteError, never>;
|
|
26
|
+
export declare const getExpectedMigrationCount: (migrationsFolder: string) => Effect.Effect<number, PgliteError | import("effect/PlatformError").PlatformError, FileSystem | Path>;
|
|
27
|
+
export declare const buildPgliteDump: (opts: PgliteMigrations & {
|
|
28
|
+
dumpPath: string;
|
|
29
|
+
}) => Effect.Effect<void, PgliteError | import("effect/PlatformError").PlatformError, FileSystem | Path>;
|
|
30
|
+
export declare const ensurePgliteDump: (opts: PgliteMigrations & {
|
|
31
|
+
dumpPath: string;
|
|
32
|
+
}) => Effect.Effect<void, PgliteError | import("effect/PlatformError").PlatformError, FileSystem | Path>;
|
|
33
|
+
export declare const openLitePglite: (opts: PgliteMigrations & {
|
|
34
|
+
dataDir: string;
|
|
35
|
+
dumpPath: string;
|
|
36
|
+
}) => Effect.Effect<PGlite, PgliteError | import("effect/PlatformError").PlatformError, FileSystem | Path>;
|
|
37
|
+
/**
|
|
38
|
+
* Prepares a PGlite database scoped to a dev session: the data dir lives at
|
|
39
|
+
* `<session>/pglite` and the migration dump at `<session>/pglite.dump`. Builds
|
|
40
|
+
* the dump from `migrationsFolder` if missing, hydrates the client, and runs
|
|
41
|
+
* pending migrations. Returns the open client plus the resolved paths so the
|
|
42
|
+
* caller can pass them to the app (e.g. as `DATABASE_LITE_PATH`).
|
|
43
|
+
*/
|
|
44
|
+
export declare const prepareSessionPglite: (session: DevSession, opts: PgliteMigrations) => Effect.Effect<{
|
|
45
|
+
client: PGlite;
|
|
46
|
+
dataDir: string;
|
|
47
|
+
dumpPath: string;
|
|
48
|
+
}, PgliteError | import("effect/PlatformError").PlatformError, FileSystem | Path>;
|
|
49
|
+
export {};
|
|
50
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/pglite/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAG9C,OAAO,EAAQ,MAAM,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AACnC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;;;;AAElD,qBAAa,WAAY,SAAQ,iBAAgC;IAChE,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,OAAO,CAAC;CAChB,CAAC;CAAG;AAQL,MAAM,MAAM,gBAAgB,GAAG;IAC9B,gBAAgB,EAAE,MAAM,CAAC;IACzB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC1B,CAAC;AAwBF,eAAO,MAAM,oBAAoB,SAAU;IAC1C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CACjB,kGAsBE,CAAC;AAeJ,eAAO,MAAM,gBAAgB,WAAY,MAAM,QAAQ,MAAM,uGAuB1D,CAAC;AAEJ,eAAO,MAAM,aAAa,WAAY,MAAM,cAAc,gBAAgB,4CAavE,CAAC;AAYJ,eAAO,MAAM,mBAAmB,WACvB,MAAM,eACD,IAAI,CAAC,gBAAgB,EAAE,iBAAiB,GAAG,kBAAkB,CAAC,8CA4DzE,CAAC;AAEJ,eAAO,MAAM,yBAAyB,qBAAsB,MAAM,yGA8B/D,CAAC;AAEJ,eAAO,MAAM,eAAe,SACrB,gBAAgB,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,uGAO3C,CAAC;AAEJ,eAAO,MAAM,gBAAgB,SACtB,gBAAgB,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,uGAQ3C,CAAC;AAEJ,eAAO,MAAM,cAAc,SACpB,gBAAgB,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,yGAwB5D,CAAC;AAEJ;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,YACvB,UAAU,QACb,gBAAgB;;;;iFAWpB,CAAC"}
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
// src/pglite/index.ts
|
|
2
|
+
import { PGlite } from "@electric-sql/pglite";
|
|
3
|
+
import { drizzle } from "drizzle-orm/pglite";
|
|
4
|
+
import { migrate } from "drizzle-orm/pglite/migrator";
|
|
5
|
+
import { Data, Effect } from "effect";
|
|
6
|
+
import { FileSystem } from "effect/FileSystem";
|
|
7
|
+
import { Path } from "effect/Path";
|
|
8
|
+
var PgliteError = class extends Data.TaggedError("PgliteError") {
|
|
9
|
+
};
|
|
10
|
+
var IN_MEMORY_DATA_DIR = "memory://";
|
|
11
|
+
var DEFAULT_MIGRATIONS_TABLE = "__drizzle_migrations";
|
|
12
|
+
var DEFAULT_MIGRATIONS_SCHEMA = "drizzle";
|
|
13
|
+
var quoteIdentifierPart = (part) => `"${part.replaceAll('"', '""')}"`;
|
|
14
|
+
var qualifiedMigrationsTable = (migrations) => `${quoteIdentifierPart(migrations.migrationsSchema ?? DEFAULT_MIGRATIONS_SCHEMA)}.${quoteIdentifierPart(migrations.migrationsTable ?? DEFAULT_MIGRATIONS_TABLE)}`;
|
|
15
|
+
var shouldReuseExistingDatabase = (dataDir) => Effect.gen(function* () {
|
|
16
|
+
if (!dataDir || dataDir === IN_MEMORY_DATA_DIR) {
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
const fs = yield* FileSystem;
|
|
20
|
+
return yield* fs.exists(dataDir);
|
|
21
|
+
});
|
|
22
|
+
var createPgliteFromDump = (opts) => Effect.gen(function* () {
|
|
23
|
+
const fs = yield* FileSystem;
|
|
24
|
+
if (yield* shouldReuseExistingDatabase(opts.dataDir)) {
|
|
25
|
+
return new PGlite(opts.dataDir);
|
|
26
|
+
}
|
|
27
|
+
if (!(yield* fs.exists(opts.dumpPath))) {
|
|
28
|
+
return yield* new PgliteError({
|
|
29
|
+
message: `Dump file not found at ${opts.dumpPath}`
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
const buffer = yield* fs.readFile(opts.dumpPath);
|
|
33
|
+
const file = new Blob([new Uint8Array(buffer)]);
|
|
34
|
+
const client = new PGlite(opts.dataDir, {
|
|
35
|
+
loadDataDir: file
|
|
36
|
+
});
|
|
37
|
+
return client;
|
|
38
|
+
});
|
|
39
|
+
var toUint8Array = (input) => Effect.gen(function* () {
|
|
40
|
+
const buf = yield* Effect.tryPromise({
|
|
41
|
+
try: () => input.arrayBuffer(),
|
|
42
|
+
catch: (error) => new PgliteError({
|
|
43
|
+
message: "Failed to convert dump to Uint8Array",
|
|
44
|
+
cause: error
|
|
45
|
+
})
|
|
46
|
+
});
|
|
47
|
+
return new Uint8Array(buf);
|
|
48
|
+
});
|
|
49
|
+
var dumpPgliteToFile = (client, dest) => Effect.gen(function* () {
|
|
50
|
+
const fs = yield* FileSystem;
|
|
51
|
+
const path = yield* Path;
|
|
52
|
+
const destDir = path.dirname(dest);
|
|
53
|
+
const dirExists = yield* fs.exists(destDir);
|
|
54
|
+
if (!dirExists) {
|
|
55
|
+
yield* fs.makeDirectory(destDir, { recursive: true });
|
|
56
|
+
}
|
|
57
|
+
const dump = yield* Effect.tryPromise({
|
|
58
|
+
try: () => client.dumpDataDir(),
|
|
59
|
+
catch: (error) => new PgliteError({
|
|
60
|
+
message: "Failed to dump PGlite database",
|
|
61
|
+
cause: error
|
|
62
|
+
})
|
|
63
|
+
});
|
|
64
|
+
const data = yield* toUint8Array(dump);
|
|
65
|
+
yield* fs.writeFile(dest, data);
|
|
66
|
+
});
|
|
67
|
+
var migratePglite = (client, migrations) => Effect.tryPromise({
|
|
68
|
+
try: () => migrate(drizzle(client), {
|
|
69
|
+
migrationsFolder: migrations.migrationsFolder,
|
|
70
|
+
migrationsTable: migrations.migrationsTable,
|
|
71
|
+
migrationsSchema: migrations.migrationsSchema
|
|
72
|
+
}),
|
|
73
|
+
catch: (error) => new PgliteError({
|
|
74
|
+
message: `Failed to migrate pglite from ${migrations.migrationsFolder}`,
|
|
75
|
+
cause: error
|
|
76
|
+
})
|
|
77
|
+
});
|
|
78
|
+
var closePglite = (client) => Effect.tryPromise({
|
|
79
|
+
try: () => client.close(),
|
|
80
|
+
catch: (error) => new PgliteError({
|
|
81
|
+
message: "Failed to close PGlite client",
|
|
82
|
+
cause: error
|
|
83
|
+
})
|
|
84
|
+
});
|
|
85
|
+
var getDbMigrationCount = (client, migrations) => Effect.gen(function* () {
|
|
86
|
+
const qualifiedTable = qualifiedMigrationsTable(migrations ?? {});
|
|
87
|
+
yield* Effect.tryPromise({
|
|
88
|
+
try: () => client.waitReady,
|
|
89
|
+
catch: (error) => new PgliteError({
|
|
90
|
+
message: "Failed to wait for PGlite ready",
|
|
91
|
+
cause: error
|
|
92
|
+
})
|
|
93
|
+
});
|
|
94
|
+
const existsResult = yield* Effect.tryPromise({
|
|
95
|
+
try: () => client.query(
|
|
96
|
+
'SELECT to_regclass($1) IS NOT NULL AS "exists"',
|
|
97
|
+
[qualifiedTable]
|
|
98
|
+
),
|
|
99
|
+
catch: (error) => new PgliteError({
|
|
100
|
+
message: "Failed to check drizzle migrations table",
|
|
101
|
+
cause: error
|
|
102
|
+
})
|
|
103
|
+
});
|
|
104
|
+
const existsRow = existsResult.rows[0];
|
|
105
|
+
if (!existsRow) {
|
|
106
|
+
return yield* Effect.fail(
|
|
107
|
+
new PgliteError({
|
|
108
|
+
message: "Missing row from drizzle migrations existence check"
|
|
109
|
+
})
|
|
110
|
+
);
|
|
111
|
+
}
|
|
112
|
+
if (!existsRow.exists) {
|
|
113
|
+
return 0;
|
|
114
|
+
}
|
|
115
|
+
const countResult = yield* Effect.tryPromise({
|
|
116
|
+
try: () => client.query(
|
|
117
|
+
`SELECT count(*)::int AS c FROM ${qualifiedTable}`
|
|
118
|
+
),
|
|
119
|
+
catch: (error) => new PgliteError({
|
|
120
|
+
message: "Failed to count drizzle migrations",
|
|
121
|
+
cause: error
|
|
122
|
+
})
|
|
123
|
+
});
|
|
124
|
+
const countRow = countResult.rows[0];
|
|
125
|
+
if (!countRow) {
|
|
126
|
+
return yield* Effect.fail(
|
|
127
|
+
new PgliteError({
|
|
128
|
+
message: "Missing row from drizzle migrations count query"
|
|
129
|
+
})
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
return countRow.c;
|
|
133
|
+
});
|
|
134
|
+
var getExpectedMigrationCount = (migrationsFolder) => Effect.gen(function* () {
|
|
135
|
+
const fs = yield* FileSystem;
|
|
136
|
+
const path = yield* Path;
|
|
137
|
+
const journalPath = path.join(migrationsFolder, "meta/_journal.json");
|
|
138
|
+
const journalExists = yield* fs.exists(journalPath);
|
|
139
|
+
if (!journalExists) {
|
|
140
|
+
return yield* Effect.fail(
|
|
141
|
+
new PgliteError({
|
|
142
|
+
message: `Migration journal not found at ${journalPath}`
|
|
143
|
+
})
|
|
144
|
+
);
|
|
145
|
+
}
|
|
146
|
+
const content = yield* fs.readFileString(journalPath);
|
|
147
|
+
const journal = yield* Effect.try({
|
|
148
|
+
try: () => JSON.parse(content),
|
|
149
|
+
catch: (cause) => new PgliteError({
|
|
150
|
+
message: `Failed to parse migration journal at ${journalPath}`,
|
|
151
|
+
cause
|
|
152
|
+
})
|
|
153
|
+
});
|
|
154
|
+
if (!Array.isArray(journal.entries)) {
|
|
155
|
+
return yield* Effect.fail(
|
|
156
|
+
new PgliteError({
|
|
157
|
+
message: `Migration journal at ${journalPath} is missing an "entries" array`
|
|
158
|
+
})
|
|
159
|
+
);
|
|
160
|
+
}
|
|
161
|
+
return journal.entries.length;
|
|
162
|
+
});
|
|
163
|
+
var buildPgliteDump = (opts) => Effect.gen(function* () {
|
|
164
|
+
const client = new PGlite(IN_MEMORY_DATA_DIR);
|
|
165
|
+
yield* migratePglite(client, opts);
|
|
166
|
+
yield* dumpPgliteToFile(client, opts.dumpPath);
|
|
167
|
+
yield* closePglite(client);
|
|
168
|
+
});
|
|
169
|
+
var ensurePgliteDump = (opts) => Effect.gen(function* () {
|
|
170
|
+
const fs = yield* FileSystem;
|
|
171
|
+
const dumpExists = yield* fs.exists(opts.dumpPath);
|
|
172
|
+
if (!dumpExists) {
|
|
173
|
+
yield* buildPgliteDump(opts);
|
|
174
|
+
}
|
|
175
|
+
});
|
|
176
|
+
var openLitePglite = (opts) => Effect.gen(function* () {
|
|
177
|
+
yield* ensurePgliteDump(opts);
|
|
178
|
+
const client = yield* createPgliteFromDump({
|
|
179
|
+
dataDir: opts.dataDir,
|
|
180
|
+
dumpPath: opts.dumpPath
|
|
181
|
+
});
|
|
182
|
+
const expected = yield* getExpectedMigrationCount(opts.migrationsFolder);
|
|
183
|
+
const actual = yield* getDbMigrationCount(client, opts);
|
|
184
|
+
const predatesMigrationJournal = expected > 0 && actual === 0;
|
|
185
|
+
if (predatesMigrationJournal) {
|
|
186
|
+
return yield* Effect.fail(
|
|
187
|
+
new PgliteError({
|
|
188
|
+
message: `Stale local pglite at ${opts.dataDir} (schema present, no migration journal) \u2014 it was built by an older scheme. Remove it and the dump, then restart:
|
|
189
|
+
rm -rf ${opts.dataDir} ${opts.dumpPath}`
|
|
190
|
+
})
|
|
191
|
+
);
|
|
192
|
+
}
|
|
193
|
+
yield* migratePglite(client, opts);
|
|
194
|
+
return client;
|
|
195
|
+
});
|
|
196
|
+
var prepareSessionPglite = (session, opts) => Effect.gen(function* () {
|
|
197
|
+
const dataDir = yield* session.path("pglite");
|
|
198
|
+
const dumpPath = yield* session.path("pglite.dump");
|
|
199
|
+
const client = yield* openLitePglite({
|
|
200
|
+
...opts,
|
|
201
|
+
dataDir,
|
|
202
|
+
dumpPath
|
|
203
|
+
});
|
|
204
|
+
return { client, dataDir, dumpPath };
|
|
205
|
+
});
|
|
206
|
+
export {
|
|
207
|
+
PgliteError,
|
|
208
|
+
buildPgliteDump,
|
|
209
|
+
createPgliteFromDump,
|
|
210
|
+
dumpPgliteToFile,
|
|
211
|
+
ensurePgliteDump,
|
|
212
|
+
getDbMigrationCount,
|
|
213
|
+
getExpectedMigrationCount,
|
|
214
|
+
migratePglite,
|
|
215
|
+
openLitePglite,
|
|
216
|
+
prepareSessionPglite
|
|
217
|
+
};
|
|
218
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/pglite/index.ts"],"sourcesContent":["import { PGlite } from '@electric-sql/pglite';\nimport { drizzle } from 'drizzle-orm/pglite';\nimport { migrate } from 'drizzle-orm/pglite/migrator';\nimport { Data, Effect } from 'effect';\nimport { FileSystem } from 'effect/FileSystem';\nimport { Path } from 'effect/Path';\nimport type { DevSession } from '../dev-sessions';\n\nexport class PgliteError extends Data.TaggedError('PgliteError')<{\n\tmessage: string;\n\tcause?: unknown;\n}> {}\n\nconst IN_MEMORY_DATA_DIR = 'memory://';\n\n/** Drizzle's own defaults, used whenever a caller doesn't override them. */\nconst DEFAULT_MIGRATIONS_TABLE = '__drizzle_migrations';\nconst DEFAULT_MIGRATIONS_SCHEMA = 'drizzle';\n\nexport type PgliteMigrations = {\n\tmigrationsFolder: string;\n\tmigrationsTable?: string;\n\tmigrationsSchema?: string;\n};\n\n/** Double-quotes an identifier part for safe interpolation into SQL. */\nconst quoteIdentifierPart = (part: string) => `\"${part.replaceAll('\"', '\"\"')}\"`;\n\nconst qualifiedMigrationsTable = (\n\tmigrations: Pick<PgliteMigrations, 'migrationsTable' | 'migrationsSchema'>,\n) =>\n\t`${quoteIdentifierPart(migrations.migrationsSchema ?? DEFAULT_MIGRATIONS_SCHEMA)}.${quoteIdentifierPart(migrations.migrationsTable ?? DEFAULT_MIGRATIONS_TABLE)}`;\n\n/**\n * A persisted data dir that already exists holds a hydrated database, so it is\n * opened as-is rather than re-seeded from the dump. In-memory clients have\n * nothing to reuse.\n */\nconst shouldReuseExistingDatabase = (dataDir: string | undefined) =>\n\tEffect.gen(function* () {\n\t\tif (!dataDir || dataDir === IN_MEMORY_DATA_DIR) {\n\t\t\treturn false;\n\t\t}\n\t\tconst fs = yield* FileSystem;\n\t\treturn yield* fs.exists(dataDir);\n\t});\n\nexport const createPgliteFromDump = (opts: {\n\tdataDir?: string;\n\tdumpPath: string;\n}) =>\n\tEffect.gen(function* () {\n\t\tconst fs = yield* FileSystem;\n\n\t\tif (yield* shouldReuseExistingDatabase(opts.dataDir)) {\n\t\t\treturn new PGlite(opts.dataDir);\n\t\t}\n\n\t\tif (!(yield* fs.exists(opts.dumpPath))) {\n\t\t\treturn yield* new PgliteError({\n\t\t\t\tmessage: `Dump file not found at ${opts.dumpPath}`,\n\t\t\t});\n\t\t}\n\n\t\tconst buffer = yield* fs.readFile(opts.dumpPath);\n\t\tconst file = new Blob([new Uint8Array(buffer)]);\n\n\t\tconst client = new PGlite(opts.dataDir, {\n\t\t\tloadDataDir: file,\n\t\t});\n\n\t\treturn client;\n\t});\n\nconst toUint8Array = (input: File | Blob) =>\n\tEffect.gen(function* () {\n\t\tconst buf = yield* Effect.tryPromise({\n\t\t\ttry: () => input.arrayBuffer(),\n\t\t\tcatch: (error) =>\n\t\t\t\tnew PgliteError({\n\t\t\t\t\tmessage: 'Failed to convert dump to Uint8Array',\n\t\t\t\t\tcause: error,\n\t\t\t\t}),\n\t\t});\n\t\treturn new Uint8Array(buf);\n\t});\n\nexport const dumpPgliteToFile = (client: PGlite, dest: string) =>\n\tEffect.gen(function* () {\n\t\tconst fs = yield* FileSystem;\n\t\tconst path = yield* Path;\n\n\t\tconst destDir = path.dirname(dest);\n\t\tconst dirExists = yield* fs.exists(destDir);\n\n\t\tif (!dirExists) {\n\t\t\tyield* fs.makeDirectory(destDir, { recursive: true });\n\t\t}\n\n\t\tconst dump = yield* Effect.tryPromise({\n\t\t\ttry: () => client.dumpDataDir(),\n\t\t\tcatch: (error) =>\n\t\t\t\tnew PgliteError({\n\t\t\t\t\tmessage: 'Failed to dump PGlite database',\n\t\t\t\t\tcause: error,\n\t\t\t\t}),\n\t\t});\n\n\t\tconst data = yield* toUint8Array(dump);\n\t\tyield* fs.writeFile(dest, data);\n\t});\n\nexport const migratePglite = (client: PGlite, migrations: PgliteMigrations) =>\n\tEffect.tryPromise({\n\t\ttry: () =>\n\t\t\tmigrate(drizzle(client), {\n\t\t\t\tmigrationsFolder: migrations.migrationsFolder,\n\t\t\t\tmigrationsTable: migrations.migrationsTable,\n\t\t\t\tmigrationsSchema: migrations.migrationsSchema,\n\t\t\t}),\n\t\tcatch: (error) =>\n\t\t\tnew PgliteError({\n\t\t\t\tmessage: `Failed to migrate pglite from ${migrations.migrationsFolder}`,\n\t\t\t\tcause: error,\n\t\t\t}),\n\t});\n\nconst closePglite = (client: PGlite) =>\n\tEffect.tryPromise({\n\t\ttry: () => client.close(),\n\t\tcatch: (error) =>\n\t\t\tnew PgliteError({\n\t\t\t\tmessage: 'Failed to close PGlite client',\n\t\t\t\tcause: error,\n\t\t\t}),\n\t});\n\nexport const getDbMigrationCount = (\n\tclient: PGlite,\n\tmigrations?: Pick<PgliteMigrations, 'migrationsTable' | 'migrationsSchema'>,\n) =>\n\tEffect.gen(function* () {\n\t\tconst qualifiedTable = qualifiedMigrationsTable(migrations ?? {});\n\n\t\tyield* Effect.tryPromise({\n\t\t\ttry: () => client.waitReady,\n\t\t\tcatch: (error) =>\n\t\t\t\tnew PgliteError({\n\t\t\t\t\tmessage: 'Failed to wait for PGlite ready',\n\t\t\t\t\tcause: error,\n\t\t\t\t}),\n\t\t});\n\n\t\tconst existsResult = yield* Effect.tryPromise({\n\t\t\ttry: () =>\n\t\t\t\tclient.query<{ exists: boolean }>(\n\t\t\t\t\t'SELECT to_regclass($1) IS NOT NULL AS \"exists\"',\n\t\t\t\t\t[qualifiedTable],\n\t\t\t\t),\n\t\t\tcatch: (error) =>\n\t\t\t\tnew PgliteError({\n\t\t\t\t\tmessage: 'Failed to check drizzle migrations table',\n\t\t\t\t\tcause: error,\n\t\t\t\t}),\n\t\t});\n\n\t\tconst existsRow = existsResult.rows[0];\n\t\tif (!existsRow) {\n\t\t\treturn yield* Effect.fail(\n\t\t\t\tnew PgliteError({\n\t\t\t\t\tmessage: 'Missing row from drizzle migrations existence check',\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\t\tif (!existsRow.exists) {\n\t\t\treturn 0;\n\t\t}\n\n\t\tconst countResult = yield* Effect.tryPromise({\n\t\t\ttry: () =>\n\t\t\t\tclient.query<{ c: number }>(\n\t\t\t\t\t`SELECT count(*)::int AS c FROM ${qualifiedTable}`,\n\t\t\t\t),\n\t\t\tcatch: (error) =>\n\t\t\t\tnew PgliteError({\n\t\t\t\t\tmessage: 'Failed to count drizzle migrations',\n\t\t\t\t\tcause: error,\n\t\t\t\t}),\n\t\t});\n\n\t\tconst countRow = countResult.rows[0];\n\t\tif (!countRow) {\n\t\t\treturn yield* Effect.fail(\n\t\t\t\tnew PgliteError({\n\t\t\t\t\tmessage: 'Missing row from drizzle migrations count query',\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\t\treturn countRow.c;\n\t});\n\nexport const getExpectedMigrationCount = (migrationsFolder: string) =>\n\tEffect.gen(function* () {\n\t\tconst fs = yield* FileSystem;\n\t\tconst path = yield* Path;\n\t\tconst journalPath = path.join(migrationsFolder, 'meta/_journal.json');\n\t\tconst journalExists = yield* fs.exists(journalPath);\n\t\tif (!journalExists) {\n\t\t\treturn yield* Effect.fail(\n\t\t\t\tnew PgliteError({\n\t\t\t\t\tmessage: `Migration journal not found at ${journalPath}`,\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\t\tconst content = yield* fs.readFileString(journalPath);\n\t\tconst journal = yield* Effect.try({\n\t\t\ttry: () => JSON.parse(content) as { entries: unknown[] },\n\t\t\tcatch: (cause) =>\n\t\t\t\tnew PgliteError({\n\t\t\t\t\tmessage: `Failed to parse migration journal at ${journalPath}`,\n\t\t\t\t\tcause,\n\t\t\t\t}),\n\t\t});\n\t\tif (!Array.isArray(journal.entries)) {\n\t\t\treturn yield* Effect.fail(\n\t\t\t\tnew PgliteError({\n\t\t\t\t\tmessage: `Migration journal at ${journalPath} is missing an \"entries\" array`,\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\t\treturn journal.entries.length;\n\t});\n\nexport const buildPgliteDump = (\n\topts: PgliteMigrations & { dumpPath: string },\n) =>\n\tEffect.gen(function* () {\n\t\tconst client = new PGlite(IN_MEMORY_DATA_DIR);\n\t\tyield* migratePglite(client, opts);\n\t\tyield* dumpPgliteToFile(client, opts.dumpPath);\n\t\tyield* closePglite(client);\n\t});\n\nexport const ensurePgliteDump = (\n\topts: PgliteMigrations & { dumpPath: string },\n) =>\n\tEffect.gen(function* () {\n\t\tconst fs = yield* FileSystem;\n\t\tconst dumpExists = yield* fs.exists(opts.dumpPath);\n\t\tif (!dumpExists) {\n\t\t\tyield* buildPgliteDump(opts);\n\t\t}\n\t});\n\nexport const openLitePglite = (\n\topts: PgliteMigrations & { dataDir: string; dumpPath: string },\n) =>\n\tEffect.gen(function* () {\n\t\tyield* ensurePgliteDump(opts);\n\t\tconst client = yield* createPgliteFromDump({\n\t\t\tdataDir: opts.dataDir,\n\t\t\tdumpPath: opts.dumpPath,\n\t\t});\n\t\tconst expected = yield* getExpectedMigrationCount(opts.migrationsFolder);\n\t\tconst actual = yield* getDbMigrationCount(client, opts);\n\t\t/** Schema is present but nothing is journaled — it predates journaled migrations. */\n\t\tconst predatesMigrationJournal = expected > 0 && actual === 0;\n\t\tif (predatesMigrationJournal) {\n\t\t\treturn yield* Effect.fail(\n\t\t\t\tnew PgliteError({\n\t\t\t\t\tmessage:\n\t\t\t\t\t\t`Stale local pglite at ${opts.dataDir} (schema present, no migration journal) — ` +\n\t\t\t\t\t\t'it was built by an older scheme. Remove it and the dump, then restart:\\n' +\n\t\t\t\t\t\t` rm -rf ${opts.dataDir} ${opts.dumpPath}`,\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\t\tyield* migratePglite(client, opts);\n\t\treturn client;\n\t});\n\n/**\n * Prepares a PGlite database scoped to a dev session: the data dir lives at\n * `<session>/pglite` and the migration dump at `<session>/pglite.dump`. Builds\n * the dump from `migrationsFolder` if missing, hydrates the client, and runs\n * pending migrations. Returns the open client plus the resolved paths so the\n * caller can pass them to the app (e.g. as `DATABASE_LITE_PATH`).\n */\nexport const prepareSessionPglite = (\n\tsession: DevSession,\n\topts: PgliteMigrations,\n) =>\n\tEffect.gen(function* () {\n\t\tconst dataDir = yield* session.path('pglite');\n\t\tconst dumpPath = yield* session.path('pglite.dump');\n\t\tconst client = yield* openLitePglite({\n\t\t\t...opts,\n\t\t\tdataDir,\n\t\t\tdumpPath,\n\t\t});\n\t\treturn { client, dataDir, dumpPath };\n\t});\n"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
|
@@ -1,4 +1,89 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "devsess",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Isolated, managed dev servers — each worktree gets its own session, with its own port and its own database",
|
|
5
|
+
"license": "Apache-2.0",
|
|
6
|
+
"homepage": "https://github.com/fdarian/devsess#readme",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/fdarian/devsess.git",
|
|
10
|
+
"directory": "packages/devsess"
|
|
11
|
+
},
|
|
12
|
+
"bugs": {
|
|
13
|
+
"url": "https://github.com/fdarian/devsess/issues"
|
|
14
|
+
},
|
|
15
|
+
"type": "module",
|
|
16
|
+
"keywords": [
|
|
17
|
+
"effect",
|
|
18
|
+
"dev",
|
|
19
|
+
"cli",
|
|
20
|
+
"dev-server",
|
|
21
|
+
"pglite",
|
|
22
|
+
"drizzle",
|
|
23
|
+
"sqlite",
|
|
24
|
+
"postgres"
|
|
25
|
+
],
|
|
26
|
+
"sideEffects": false,
|
|
27
|
+
"files": [
|
|
28
|
+
"dist",
|
|
29
|
+
"README.md"
|
|
30
|
+
],
|
|
31
|
+
"main": "./dist/index.js",
|
|
32
|
+
"module": "./dist/index.js",
|
|
33
|
+
"types": "./dist/index.d.ts",
|
|
34
|
+
"exports": {
|
|
35
|
+
".": {
|
|
36
|
+
"types": "./dist/index.d.ts",
|
|
37
|
+
"import": "./dist/index.js"
|
|
38
|
+
},
|
|
39
|
+
"./pglite": {
|
|
40
|
+
"types": "./dist/pglite/index.d.ts",
|
|
41
|
+
"import": "./dist/pglite/index.js"
|
|
42
|
+
},
|
|
43
|
+
"./async": {
|
|
44
|
+
"types": "./dist/async/index.d.ts",
|
|
45
|
+
"import": "./dist/async/index.js"
|
|
46
|
+
},
|
|
47
|
+
"./package.json": "./package.json"
|
|
48
|
+
},
|
|
49
|
+
"publishConfig": {
|
|
50
|
+
"access": "public",
|
|
51
|
+
"provenance": true
|
|
52
|
+
},
|
|
53
|
+
"scripts": {
|
|
54
|
+
"build": "tsup && tsc -p tsconfig.build.json",
|
|
55
|
+
"dev": "tsup --watch",
|
|
56
|
+
"check:type": "tsc --noEmit",
|
|
57
|
+
"check:lint": "biome check",
|
|
58
|
+
"test": "vitest run",
|
|
59
|
+
"prepack": "bun run build"
|
|
60
|
+
},
|
|
61
|
+
"dependencies": {
|
|
62
|
+
"get-port": "^7.2.0",
|
|
63
|
+
"random-word-slugs": "^0.1.7"
|
|
64
|
+
},
|
|
65
|
+
"peerDependencies": {
|
|
66
|
+
"@electric-sql/pglite": ">=0.2.0",
|
|
67
|
+
"drizzle-orm": ">=0.30.0",
|
|
68
|
+
"effect": "^4.0.0-beta.101"
|
|
69
|
+
},
|
|
70
|
+
"peerDependenciesMeta": {
|
|
71
|
+
"@electric-sql/pglite": {
|
|
72
|
+
"optional": true
|
|
73
|
+
},
|
|
74
|
+
"drizzle-orm": {
|
|
75
|
+
"optional": true
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
"devDependencies": {
|
|
79
|
+
"@devsess/config": "workspace:*",
|
|
80
|
+
"@effect/platform-node": "^4.0.0-beta.101",
|
|
81
|
+
"@effect/vitest": "^4.0.0-beta.101",
|
|
82
|
+
"@electric-sql/pglite": "^0.5.3",
|
|
83
|
+
"@types/node": "^22.0.0",
|
|
84
|
+
"drizzle-orm": "^0.45.2",
|
|
85
|
+
"effect": "^4.0.0-beta.101",
|
|
86
|
+
"tsup": "^8.5.1",
|
|
87
|
+
"vitest": "^4.1.10"
|
|
88
|
+
}
|
|
4
89
|
}
|