@sqldoc/db-pglite 0.0.10

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 (2) hide show
  1. package/package.json +25 -0
  2. package/src/index.ts +61 -0
package/package.json ADDED
@@ -0,0 +1,25 @@
1
+ {
2
+ "type": "module",
3
+ "name": "@sqldoc/db-pglite",
4
+ "version": "0.0.10",
5
+ "description": "PGlite embedded PostgreSQL adapter for sqldoc (zero-config, in-memory)",
6
+ "exports": {
7
+ ".": {
8
+ "types": "./src/index.ts",
9
+ "import": "./src/index.ts",
10
+ "default": "./src/index.ts"
11
+ }
12
+ },
13
+ "main": "./src/index.ts",
14
+ "types": "./src/index.ts",
15
+ "files": [
16
+ "src",
17
+ "package.json"
18
+ ],
19
+ "dependencies": {
20
+ "@electric-sql/pglite": "^0.4.0"
21
+ },
22
+ "devDependencies": {
23
+ "@sqldoc/db": "0.0.10"
24
+ }
25
+ }
package/src/index.ts ADDED
@@ -0,0 +1,61 @@
1
+ import { PGlite } from '@electric-sql/pglite'
2
+ import type { AdapterPluginContext, DatabaseAdapter, DatabaseAdapterPlugin, ExecResult, QueryResult } from '@sqldoc/db'
3
+ import { normalizeValue } from '@sqldoc/db'
4
+
5
+ async function loadExtension(name: string): Promise<any | null> {
6
+ // PGlite module names use underscores (e.g. uuid_ossp) while SQL uses hyphens (uuid-ossp)
7
+ const moduleName = name.replace(/-/g, '_')
8
+ try {
9
+ const mod = await import(`@electric-sql/pglite/contrib/${moduleName}`)
10
+ return mod.default ?? mod[moduleName] ?? mod
11
+ } catch {}
12
+ try {
13
+ const mod = await import(`@electric-sql/pglite/${moduleName}`)
14
+ return mod.default ?? mod[moduleName] ?? mod
15
+ } catch {}
16
+ return null
17
+ }
18
+
19
+ const plugin: DatabaseAdapterPlugin = {
20
+ apiVersion: 1,
21
+ name: 'pglite',
22
+ schemes: ['pglite'],
23
+ dialects: ['postgres'],
24
+ runtime: 'any',
25
+
26
+ async createAdapter(_devUrl: string, context: AdapterPluginContext): Promise<DatabaseAdapter> {
27
+ const extModules: Record<string, any> = {}
28
+ for (const ext of context.extensions) {
29
+ const mod = await loadExtension(ext)
30
+ if (mod) extModules[ext.replace(/-/g, '_')] = mod
31
+ }
32
+
33
+ const db = await PGlite.create({
34
+ extensions: Object.keys(extModules).length > 0 ? extModules : undefined,
35
+ })
36
+
37
+ return {
38
+ async query(sql: string, args?: unknown[]): Promise<QueryResult> {
39
+ const result = await db.query(sql, args, { rowMode: 'array' })
40
+ return {
41
+ columns: result.fields.map((f: { name: string }) => f.name),
42
+ rows: (result.rows as unknown[][]).map((row) => row.map((v) => normalizeValue(v))),
43
+ }
44
+ },
45
+ async exec(sql: string, args?: unknown[]): Promise<ExecResult> {
46
+ if (args && args.length > 0) {
47
+ const result = await db.query(sql, args)
48
+ return { rowsAffected: result.affectedRows ?? 0 }
49
+ }
50
+ const result = await db.exec(sql)
51
+ const last = result[result.length - 1]
52
+ return { rowsAffected: last?.affectedRows ?? 0 }
53
+ },
54
+ async close(): Promise<void> {
55
+ await db.close()
56
+ },
57
+ }
58
+ },
59
+ }
60
+
61
+ export default plugin