@vrplatform/kysely 1.2.28 → 1.2.30
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/build/.data.tar +0 -0
- package/build/main/index.d.ts +14 -4
- package/build/main/index.js +44 -12
- package/build/main/index.js.map +1 -1
- package/build/main/local/generate.d.ts +3 -0
- package/build/main/{local.js → local/generate.js} +10 -12
- package/build/main/local/generate.js.map +1 -0
- package/build/main/local/index.d.ts +5 -0
- package/build/main/local/index.js +36 -0
- package/build/main/local/index.js.map +1 -0
- package/build/main/tsconfig.main.tsbuildinfo +1 -1
- package/build/module/index.d.ts +14 -4
- package/build/module/index.js +44 -12
- package/build/module/index.js.map +1 -1
- package/build/module/local/generate.d.ts +3 -0
- package/build/module/{local.js → local/generate.js} +9 -11
- package/build/module/local/generate.js.map +1 -0
- package/build/module/local/index.d.ts +5 -0
- package/build/module/local/index.js +32 -0
- package/build/module/local/index.js.map +1 -0
- package/build/module/tsconfig.esm.tsbuildinfo +1 -1
- package/package.json +3 -3
- package/src/index.ts +58 -19
- package/src/{local.ts → local/generate.ts} +9 -11
- package/src/local/index.ts +40 -0
- package/build/main/local.d.ts +0 -3
- package/build/main/local.js.map +0 -1
- package/build/main/v0.generated.d.ts +0 -1996
- package/build/main/v0.generated.js +0 -7
- package/build/main/v0.generated.js.map +0 -1
- package/build/module/local.d.ts +0 -3
- package/build/module/local.js.map +0 -1
- package/build/module/v0.generated.d.ts +0 -1996
- package/build/module/v0.generated.js +0 -6
- package/build/module/v0.generated.js.map +0 -1
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { join } from 'node:path';
|
|
2
|
+
import { PGlite } from '@electric-sql/pglite';
|
|
3
|
+
import { CamelCasePlugin, Kysely } from 'kysely';
|
|
4
|
+
import { KyselyPGlite } from 'kysely-pglite';
|
|
5
|
+
export const root = join(__dirname, '../..');
|
|
6
|
+
export const dumpPath = join(root, '.data.tar');
|
|
7
|
+
export async function useLocalKysely() {
|
|
8
|
+
let isDestroyed = false;
|
|
9
|
+
const now = performance.now();
|
|
10
|
+
const dump = Bun.file(dumpPath);
|
|
11
|
+
const pglite = new PGlite({ loadDataDir: dump });
|
|
12
|
+
// warm up
|
|
13
|
+
await pglite.sql `SELECT 1`;
|
|
14
|
+
const { dialect } = new KyselyPGlite(pglite);
|
|
15
|
+
const kysely = new Kysely({
|
|
16
|
+
dialect,
|
|
17
|
+
plugins: [new CamelCasePlugin()],
|
|
18
|
+
});
|
|
19
|
+
const originalDestroy = kysely.destroy.bind(kysely);
|
|
20
|
+
kysely.destroy = async () => {
|
|
21
|
+
if (isDestroyed)
|
|
22
|
+
return;
|
|
23
|
+
isDestroyed = true;
|
|
24
|
+
const destroyTime = performance.now();
|
|
25
|
+
await originalDestroy().catch(() => undefined);
|
|
26
|
+
await pglite.close().catch(() => undefined);
|
|
27
|
+
console.log(`Database destroyed: ${Math.round(performance.now() - destroyTime)}ms`);
|
|
28
|
+
};
|
|
29
|
+
console.log(`Database initialized: ${Math.round(performance.now() - now)}ms`);
|
|
30
|
+
return kysely;
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"src/","sources":["local/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAG7C,MAAM,CAAC,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;AAC7C,MAAM,CAAC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;AAEhD,MAAM,CAAC,KAAK,UAAU,cAAc;IAClC,IAAI,WAAW,GAAG,KAAK,CAAC;IACxB,MAAM,GAAG,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;IAE9B,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAEhC,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC;IACjD,UAAU;IACV,MAAM,MAAM,CAAC,GAAG,CAAA,UAAU,CAAC;IAC3B,MAAM,EAAE,OAAO,EAAE,GAAG,IAAI,YAAY,CAAC,MAAM,CAAC,CAAC;IAC7C,MAAM,MAAM,GAAG,IAAI,MAAM,CAAK;QAC5B,OAAO;QACP,OAAO,EAAE,CAAC,IAAI,eAAe,EAAE,CAAC;KACjC,CAAC,CAAC;IAEH,MAAM,eAAe,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACpD,MAAM,CAAC,OAAO,GAAG,KAAK,IAAI,EAAE;QAC1B,IAAI,WAAW;YAAE,OAAO;QACxB,WAAW,GAAG,IAAI,CAAC;QACnB,MAAM,WAAW,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;QACtC,MAAM,eAAe,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;QAC/C,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;QAC5C,OAAO,CAAC,GAAG,CACT,uBAAuB,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,EAAE,GAAG,WAAW,CAAC,IAAI,CACvE,CAAC;IACJ,CAAC,CAAC;IAEF,OAAO,CAAC,GAAG,CAAC,yBAAyB,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,EAAE,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC;IAE9E,OAAO,MAAM,CAAC;AAChB,CAAC","sourcesContent":["import { join } from 'node:path';\nimport { PGlite } from '@electric-sql/pglite';\nimport { CamelCasePlugin, Kysely } from 'kysely';\nimport { KyselyPGlite } from 'kysely-pglite';\nimport type { DB } from '../v1.generated';\n\nexport const root = join(__dirname, '../..');\nexport const dumpPath = join(root, '.data.tar');\n\nexport async function useLocalKysely() {\n let isDestroyed = false;\n const now = performance.now();\n\n const dump = Bun.file(dumpPath);\n\n const pglite = new PGlite({ loadDataDir: dump });\n // warm up\n await pglite.sql`SELECT 1`;\n const { dialect } = new KyselyPGlite(pglite);\n const kysely = new Kysely<DB>({\n dialect,\n plugins: [new CamelCasePlugin()],\n });\n\n const originalDestroy = kysely.destroy.bind(kysely);\n kysely.destroy = async () => {\n if (isDestroyed) return;\n isDestroyed = true;\n const destroyTime = performance.now();\n await originalDestroy().catch(() => undefined);\n await pglite.close().catch(() => undefined);\n console.log(\n `Database destroyed: ${Math.round(performance.now() - destroyTime)}ms`\n );\n };\n\n console.log(`Database initialized: ${Math.round(performance.now() - now)}ms`);\n\n return kysely;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"root":["../../src/index.ts","../../src/
|
|
1
|
+
{"root":["../../src/index.ts","../../src/test.ts","../../src/v1.generated.ts","../../src/local/generate.ts","../../src/local/index.ts"],"version":"5.9.3"}
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"publishConfig": {
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
|
-
"version": "1.2.
|
|
6
|
+
"version": "1.2.30",
|
|
7
7
|
"description": "",
|
|
8
8
|
"main": "build/main/index.js",
|
|
9
9
|
"module": "build/module/index.js",
|
|
@@ -13,8 +13,8 @@
|
|
|
13
13
|
"require": "./build/main/index.js"
|
|
14
14
|
},
|
|
15
15
|
"./local": {
|
|
16
|
-
"import": "./build/module/local.js",
|
|
17
|
-
"require": "./build/main/local.js"
|
|
16
|
+
"import": "./build/module/local/index.js",
|
|
17
|
+
"require": "./build/main/local/index.js"
|
|
18
18
|
},
|
|
19
19
|
"./test": {
|
|
20
20
|
"import": "./build/module/test.js",
|
package/src/index.ts
CHANGED
|
@@ -25,38 +25,70 @@ import type { DB } from './v1.generated';
|
|
|
25
25
|
export type Transaction = T<DB>;
|
|
26
26
|
export { sql } from 'kysely';
|
|
27
27
|
|
|
28
|
+
type PgOpt = {
|
|
29
|
+
forceDisableSSL?: boolean;
|
|
30
|
+
retries?: false | number;
|
|
31
|
+
};
|
|
32
|
+
|
|
28
33
|
export type Kysely = K<DB>;
|
|
29
34
|
export type Postgres = Sql;
|
|
35
|
+
/**
|
|
36
|
+
* @deprecated This method is deprecated in favor of the useAsyncKysely method.
|
|
37
|
+
*/
|
|
30
38
|
export function useKysely(postgres: Sql, options: { log?: boolean } = {}) {
|
|
31
|
-
|
|
39
|
+
console.debug('Creating Kysely instance');
|
|
40
|
+
const kysely = new K<DB>({
|
|
32
41
|
dialect: new PostgresJSDialect({
|
|
33
42
|
postgres,
|
|
34
43
|
}),
|
|
35
44
|
plugins: [new CamelCasePlugin()],
|
|
36
45
|
log: options?.log ? ['query', 'error'] : undefined,
|
|
37
46
|
});
|
|
47
|
+
|
|
48
|
+
const destroy = kysely.destroy;
|
|
49
|
+
kysely.destroy = async () => {
|
|
50
|
+
console.debug('Closing Kysely connection');
|
|
51
|
+
return destroy();
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
return kysely;
|
|
38
55
|
}
|
|
39
56
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
retries =
|
|
44
|
-
|
|
45
|
-
|
|
57
|
+
const _connections: postgres.Sql[] = [];
|
|
58
|
+
export async function useAsyncPostgres(connectionString: string, opt?: PgOpt) {
|
|
59
|
+
const delayMs = 2500;
|
|
60
|
+
const retries = opt?.retries === false ? 0 : opt?.retries || 3;
|
|
61
|
+
const ssl = opt?.forceDisableSSL !== true;
|
|
62
|
+
|
|
63
|
+
console.debug(
|
|
64
|
+
`Creating Postgres connection with ${retries} retries and ssl=${ssl}`
|
|
65
|
+
);
|
|
66
|
+
if (_connections.length > 0) {
|
|
67
|
+
console.warn(`We already have ${_connections.length} Postgres connections`);
|
|
68
|
+
}
|
|
69
|
+
|
|
46
70
|
for (let attempt = 1; attempt <= retries; attempt++) {
|
|
47
71
|
try {
|
|
48
72
|
const sql = postgres(connectionString, {
|
|
49
73
|
ssl: ssl ? 'require' : false,
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
74
|
+
// connect_timeout: 10
|
|
75
|
+
// idle_timeout: 10
|
|
76
|
+
// disable prepare statements since we use pgbouncer
|
|
53
77
|
prepare: false,
|
|
78
|
+
connect_timeout: 10,
|
|
79
|
+
idle_timeout: 60,
|
|
54
80
|
});
|
|
55
81
|
|
|
56
82
|
await sql`select 1`;
|
|
83
|
+
try {
|
|
84
|
+
// connect 30s, idle 60s, max lifetime 45min, statement 60s, lock 10s, log_min_duration 20s, log_lock_waits off
|
|
85
|
+
await sql`set statement_timeout to '30s';`;
|
|
86
|
+
await sql`set lock_timeout to '10s';`;
|
|
87
|
+
} catch (e) {
|
|
88
|
+
console.warn('Failed to set statement timeout, continuing', e);
|
|
89
|
+
}
|
|
57
90
|
|
|
58
|
-
|
|
59
|
-
|
|
91
|
+
_connections.push(sql);
|
|
60
92
|
return sql;
|
|
61
93
|
} catch (err) {
|
|
62
94
|
if (attempt === retries) throw err;
|
|
@@ -70,27 +102,34 @@ export async function useAsyncPostgres(
|
|
|
70
102
|
throw new Error('Unable to connect to Postgres');
|
|
71
103
|
}
|
|
72
104
|
|
|
73
|
-
export async function useAsyncKysely(connectionString: string,
|
|
74
|
-
const sql = await useAsyncPostgres(connectionString,
|
|
105
|
+
export async function useAsyncKysely(connectionString: string, opt?: PgOpt) {
|
|
106
|
+
const sql = await useAsyncPostgres(connectionString, opt);
|
|
75
107
|
return useKysely(sql);
|
|
76
108
|
}
|
|
77
109
|
|
|
78
|
-
|
|
79
|
-
|
|
110
|
+
/**
|
|
111
|
+
* @deprecated This method is deprecated in favor of the useAsyncKysely method.
|
|
112
|
+
*/
|
|
113
|
+
export function usePostgres(
|
|
114
|
+
connectionString?: string,
|
|
115
|
+
opt?: Pick<PgOpt, 'forceDisableSSL'>
|
|
116
|
+
) {
|
|
80
117
|
if (!connectionString) throw new Error('No connection string');
|
|
118
|
+
const ssl = opt?.forceDisableSSL !== true;
|
|
81
119
|
const pg = postgres(connectionString, {
|
|
82
120
|
ssl: ssl ? 'require' : false,
|
|
83
121
|
});
|
|
84
|
-
|
|
122
|
+
_connections.push(pg);
|
|
85
123
|
return pg;
|
|
86
124
|
}
|
|
87
125
|
|
|
88
126
|
export async function forceCloseAllPostgres(timeoutMs = 5000) {
|
|
89
|
-
|
|
90
|
-
|
|
127
|
+
await Promise.all(
|
|
128
|
+
_connections.map((pg) =>
|
|
91
129
|
pg.end({ timeout: timeoutMs }).catch(() => undefined)
|
|
92
130
|
)
|
|
93
131
|
);
|
|
132
|
+
_connections.length = 0;
|
|
94
133
|
}
|
|
95
134
|
|
|
96
135
|
export class DatabaseError extends Error {
|
|
@@ -11,10 +11,9 @@ import {
|
|
|
11
11
|
} from 'kysely';
|
|
12
12
|
import codegen from 'kysely-codegen';
|
|
13
13
|
import { KyselyPGlite } from 'kysely-pglite';
|
|
14
|
-
import type { DB } from '
|
|
14
|
+
import type { DB } from '../v1.generated';
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
async function migrate(client: PGlite) {
|
|
16
|
+
async function migrate(root: string, client: PGlite) {
|
|
18
17
|
console.log('migrating pglite ....');
|
|
19
18
|
const glob = new Bun.Glob('initial/*.sql');
|
|
20
19
|
for await (const migration of glob.scan(root)) {
|
|
@@ -22,7 +21,7 @@ async function migrate(client: PGlite) {
|
|
|
22
21
|
}
|
|
23
22
|
}
|
|
24
23
|
|
|
25
|
-
async function migrateKysely(kysely: Kysely<any>) {
|
|
24
|
+
async function migrateKysely(root: string, kysely: Kysely<any>) {
|
|
26
25
|
console.log('init migrating kysely ....');
|
|
27
26
|
const migrator = new Migrator({
|
|
28
27
|
db: kysely,
|
|
@@ -58,13 +57,12 @@ async function migrateKysely(kysely: Kysely<any>) {
|
|
|
58
57
|
}
|
|
59
58
|
}
|
|
60
59
|
|
|
61
|
-
|
|
62
|
-
const dumpFile = (async () => {
|
|
60
|
+
async function generateDump(root: string, dumpPath: string) {
|
|
63
61
|
const dataExists = await exists(dumpPath).catch(() => false);
|
|
64
62
|
if (!dataExists) {
|
|
65
63
|
console.log('Creating initial dump');
|
|
66
64
|
const main = new PGlite();
|
|
67
|
-
await migrate(main).catch(async (err) => {
|
|
65
|
+
await migrate(root, main).catch(async (err) => {
|
|
68
66
|
console.error('failed to migrate initial dump');
|
|
69
67
|
await Bun.write(
|
|
70
68
|
'../logs/migrate-initial-dump.json',
|
|
@@ -77,7 +75,7 @@ const dumpFile = (async () => {
|
|
|
77
75
|
dialect,
|
|
78
76
|
plugins: [new CamelCasePlugin()],
|
|
79
77
|
});
|
|
80
|
-
await migrateKysely(kysely).catch(() => {
|
|
78
|
+
await migrateKysely(root, kysely).catch(() => {
|
|
81
79
|
console.error('failed to migrate kysely');
|
|
82
80
|
process.exit(1);
|
|
83
81
|
});
|
|
@@ -104,13 +102,13 @@ const dumpFile = (async () => {
|
|
|
104
102
|
return content;
|
|
105
103
|
}
|
|
106
104
|
return Bun.file(dumpPath);
|
|
107
|
-
}
|
|
105
|
+
}
|
|
108
106
|
|
|
109
|
-
export async function
|
|
107
|
+
export async function createLocalKysely(root: string, dumpPath: string) {
|
|
110
108
|
let isDestroyed = false;
|
|
111
109
|
const now = performance.now();
|
|
112
110
|
|
|
113
|
-
const dump = await
|
|
111
|
+
const dump = await generateDump(root, dumpPath);
|
|
114
112
|
|
|
115
113
|
const pglite = new PGlite({ loadDataDir: dump });
|
|
116
114
|
// warm up
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { join } from 'node:path';
|
|
2
|
+
import { PGlite } from '@electric-sql/pglite';
|
|
3
|
+
import { CamelCasePlugin, Kysely } from 'kysely';
|
|
4
|
+
import { KyselyPGlite } from 'kysely-pglite';
|
|
5
|
+
import type { DB } from '../v1.generated';
|
|
6
|
+
|
|
7
|
+
export const root = join(__dirname, '../..');
|
|
8
|
+
export const dumpPath = join(root, '.data.tar');
|
|
9
|
+
|
|
10
|
+
export async function useLocalKysely() {
|
|
11
|
+
let isDestroyed = false;
|
|
12
|
+
const now = performance.now();
|
|
13
|
+
|
|
14
|
+
const dump = Bun.file(dumpPath);
|
|
15
|
+
|
|
16
|
+
const pglite = new PGlite({ loadDataDir: dump });
|
|
17
|
+
// warm up
|
|
18
|
+
await pglite.sql`SELECT 1`;
|
|
19
|
+
const { dialect } = new KyselyPGlite(pglite);
|
|
20
|
+
const kysely = new Kysely<DB>({
|
|
21
|
+
dialect,
|
|
22
|
+
plugins: [new CamelCasePlugin()],
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
const originalDestroy = kysely.destroy.bind(kysely);
|
|
26
|
+
kysely.destroy = async () => {
|
|
27
|
+
if (isDestroyed) return;
|
|
28
|
+
isDestroyed = true;
|
|
29
|
+
const destroyTime = performance.now();
|
|
30
|
+
await originalDestroy().catch(() => undefined);
|
|
31
|
+
await pglite.close().catch(() => undefined);
|
|
32
|
+
console.log(
|
|
33
|
+
`Database destroyed: ${Math.round(performance.now() - destroyTime)}ms`
|
|
34
|
+
);
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
console.log(`Database initialized: ${Math.round(performance.now() - now)}ms`);
|
|
38
|
+
|
|
39
|
+
return kysely;
|
|
40
|
+
}
|
package/build/main/local.d.ts
DELETED
package/build/main/local.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"local.js","sourceRoot":"src/","sources":["local.ts"],"names":[],"mappings":"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","sourcesContent":["import { promises as fs } from 'node:fs';\nimport { exists } from 'node:fs/promises';\nimport * as path from 'node:path';\nimport { join } from 'node:path';\nimport { PGlite } from '@electric-sql/pglite';\nimport {\n CamelCasePlugin,\n FileMigrationProvider,\n Kysely,\n Migrator,\n} from 'kysely';\nimport codegen from 'kysely-codegen';\nimport { KyselyPGlite } from 'kysely-pglite';\nimport type { DB } from './v1.generated';\n\nconst root = join(__dirname, '..');\nasync function migrate(client: PGlite) {\n console.log('migrating pglite ....');\n const glob = new Bun.Glob('initial/*.sql');\n for await (const migration of glob.scan(root)) {\n await client.exec(await Bun.file(join(root, migration)).text());\n }\n}\n\nasync function migrateKysely(kysely: Kysely<any>) {\n console.log('init migrating kysely ....');\n const migrator = new Migrator({\n db: kysely,\n migrationTableSchema: 'core',\n migrationTableName: 'kysely_migration',\n migrationLockTableName: 'kysely_migration_lock',\n provider: new FileMigrationProvider({\n fs,\n path,\n // This needs to be an absolute path.\n migrationFolder: path.join(root, 'migrations'),\n }),\n });\n\n console.log('migrating kysely ....');\n const { error, results } = await migrator.migrateToLatest().catch(() => {\n console.error('failed to migrate');\n process.exit(1);\n });\n\n for (const it of results ?? []) {\n if (it.status === 'Success') {\n console.log(`migration \"${it.migrationName}\" was executed successfully`);\n } else if (it.status === 'Error') {\n console.error(`failed to execute migration \"${it.migrationName}\"`);\n }\n }\n\n if (error) {\n console.error('failed to migrate');\n console.error(error);\n process.exit(1);\n }\n}\n\nconst dumpPath = join(root, '.data.tar');\nconst dumpFile = (async () => {\n const dataExists = await exists(dumpPath).catch(() => false);\n if (!dataExists) {\n console.log('Creating initial dump');\n const main = new PGlite();\n await migrate(main).catch(async (err) => {\n console.error('failed to migrate initial dump');\n await Bun.write(\n '../logs/migrate-initial-dump.json',\n JSON.stringify(err as any, null, 2)\n );\n process.exit(1);\n });\n const { dialect } = new KyselyPGlite(main);\n const kysely = new Kysely<DB>({\n dialect,\n plugins: [new CamelCasePlugin()],\n });\n await migrateKysely(kysely).catch(() => {\n console.error('failed to migrate kysely');\n process.exit(1);\n });\n await codegen\n .generate({\n db: kysely,\n outFile: path.join(root, 'src/v1.generated.ts'),\n defaultSchemas: ['xxx'],\n camelCase: true,\n dialect: codegen.getDialect('postgres'),\n })\n .catch(() => {\n console.error('failed to generate kysely');\n process.exit(1);\n });\n const content = await main.dumpDataDir('none').catch(() => {\n console.error('failed to dump data');\n process.exit(1);\n });\n await Bun.write(dumpPath, content).catch(() => {\n console.error('failed to write dump');\n process.exit(1);\n });\n return content;\n }\n return Bun.file(dumpPath);\n})();\n\nexport async function useLocalKysely() {\n let isDestroyed = false;\n const now = performance.now();\n\n const dump = await dumpFile;\n\n const pglite = new PGlite({ loadDataDir: dump });\n // warm up\n await pglite.sql`SELECT 1`;\n const { dialect } = new KyselyPGlite(pglite);\n const kysely = new Kysely<DB>({\n dialect,\n plugins: [new CamelCasePlugin()],\n });\n\n const originalDestroy = kysely.destroy.bind(kysely);\n kysely.destroy = async () => {\n if (isDestroyed) return;\n isDestroyed = true;\n const destroyTime = performance.now();\n await originalDestroy().catch(() => undefined);\n await pglite.close().catch(() => undefined);\n console.log(\n `Database destroyed: ${Math.round(performance.now() - destroyTime)}ms`\n );\n };\n\n console.log(`Database initialized: ${Math.round(performance.now() - now)}ms`);\n\n return kysely;\n}\n"]}
|