tinbase 0.1.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/LICENSE +21 -0
- package/README.md +185 -0
- package/assets/logo.svg +18 -0
- package/dist/auth/handler.d.ts +43 -0
- package/dist/auth/handler.js +291 -0
- package/dist/auth/handler.js.map +1 -0
- package/dist/auth/password.d.ts +3 -0
- package/dist/auth/password.js +40 -0
- package/dist/auth/password.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +181 -0
- package/dist/cli.js.map +1 -0
- package/dist/db/bootstrap.d.ts +6 -0
- package/dist/db/bootstrap.js +213 -0
- package/dist/db/bootstrap.js.map +1 -0
- package/dist/db/database.d.ts +83 -0
- package/dist/db/database.js +270 -0
- package/dist/db/database.js.map +1 -0
- package/dist/db/engine.d.ts +30 -0
- package/dist/db/engine.js +28 -0
- package/dist/db/engine.js.map +1 -0
- package/dist/db/pglite-engine.d.ts +3 -0
- package/dist/db/pglite-engine.js +39 -0
- package/dist/db/pglite-engine.js.map +1 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.js +145 -0
- package/dist/index.js.map +1 -0
- package/dist/jwt.d.ts +20 -0
- package/dist/jwt.js +72 -0
- package/dist/jwt.js.map +1 -0
- package/dist/node/bun-server.d.ts +8 -0
- package/dist/node/bun-server.js +41 -0
- package/dist/node/bun-server.js.map +1 -0
- package/dist/node/fs-driver.d.ts +11 -0
- package/dist/node/fs-driver.js +39 -0
- package/dist/node/fs-driver.js.map +1 -0
- package/dist/node/index.d.ts +7 -0
- package/dist/node/index.js +8 -0
- package/dist/node/index.js.map +1 -0
- package/dist/node/native/engine.d.ts +13 -0
- package/dist/node/native/engine.js +186 -0
- package/dist/node/native/engine.js.map +1 -0
- package/dist/node/native/wire.d.ts +38 -0
- package/dist/node/native/wire.js +345 -0
- package/dist/node/native/wire.js.map +1 -0
- package/dist/node/project.d.ts +6 -0
- package/dist/node/project.js +29 -0
- package/dist/node/project.js.map +1 -0
- package/dist/node/server-shared.d.ts +6 -0
- package/dist/node/server-shared.js +2 -0
- package/dist/node/server-shared.js.map +1 -0
- package/dist/node/server.d.ts +14 -0
- package/dist/node/server.js +83 -0
- package/dist/node/server.js.map +1 -0
- package/dist/node/ws.d.ts +8 -0
- package/dist/node/ws.js +165 -0
- package/dist/node/ws.js.map +1 -0
- package/dist/realtime/engine.d.ts +53 -0
- package/dist/realtime/engine.js +437 -0
- package/dist/realtime/engine.js.map +1 -0
- package/dist/rest/build.d.ts +53 -0
- package/dist/rest/build.js +505 -0
- package/dist/rest/build.js.map +1 -0
- package/dist/rest/errors.d.ts +2 -0
- package/dist/rest/errors.js +48 -0
- package/dist/rest/errors.js.map +1 -0
- package/dist/rest/handler.d.ts +11 -0
- package/dist/rest/handler.js +332 -0
- package/dist/rest/handler.js.map +1 -0
- package/dist/rest/parse.d.ts +69 -0
- package/dist/rest/parse.js +261 -0
- package/dist/rest/parse.js.map +1 -0
- package/dist/storage/driver.d.ts +9 -0
- package/dist/storage/driver.js +18 -0
- package/dist/storage/driver.js.map +1 -0
- package/dist/storage/handler.d.ts +49 -0
- package/dist/storage/handler.js +534 -0
- package/dist/storage/handler.js.map +1 -0
- package/dist/types.d.ts +51 -0
- package/dist/types.js +11 -0
- package/dist/types.js.map +1 -0
- package/package.json +59 -0
package/dist/jwt.js
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal HS256 JWT implementation on WebCrypto.
|
|
3
|
+
* Works in Node (>=18) and browsers — no dependencies.
|
|
4
|
+
*/
|
|
5
|
+
const encoder = new TextEncoder();
|
|
6
|
+
const decoder = new TextDecoder();
|
|
7
|
+
function bytesToBase64Url(bytes) {
|
|
8
|
+
let binary = '';
|
|
9
|
+
const chunk = 0x8000;
|
|
10
|
+
for (let i = 0; i < bytes.length; i += chunk) {
|
|
11
|
+
binary += String.fromCharCode(...bytes.subarray(i, i + chunk));
|
|
12
|
+
}
|
|
13
|
+
return btoa(binary).replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
|
|
14
|
+
}
|
|
15
|
+
function base64UrlToBytes(str) {
|
|
16
|
+
const base64 = str.replace(/-/g, '+').replace(/_/g, '/');
|
|
17
|
+
const padded = base64 + '='.repeat((4 - (base64.length % 4)) % 4);
|
|
18
|
+
const binary = atob(padded);
|
|
19
|
+
const bytes = new Uint8Array(binary.length);
|
|
20
|
+
for (let i = 0; i < binary.length; i++)
|
|
21
|
+
bytes[i] = binary.charCodeAt(i);
|
|
22
|
+
return bytes;
|
|
23
|
+
}
|
|
24
|
+
async function hmacKey(secret, usage) {
|
|
25
|
+
return crypto.subtle.importKey('raw', encoder.encode(secret), { name: 'HMAC', hash: 'SHA-256' }, false, [usage]);
|
|
26
|
+
}
|
|
27
|
+
export async function signJwt(claims, secret) {
|
|
28
|
+
const header = bytesToBase64Url(encoder.encode(JSON.stringify({ alg: 'HS256', typ: 'JWT' })));
|
|
29
|
+
const payload = bytesToBase64Url(encoder.encode(JSON.stringify(claims)));
|
|
30
|
+
const data = `${header}.${payload}`;
|
|
31
|
+
const key = await hmacKey(secret, 'sign');
|
|
32
|
+
const sig = await crypto.subtle.sign('HMAC', key, encoder.encode(data));
|
|
33
|
+
return `${data}.${bytesToBase64Url(new Uint8Array(sig))}`;
|
|
34
|
+
}
|
|
35
|
+
/** Verifies signature and expiry. Returns claims, or null when invalid. */
|
|
36
|
+
export async function verifyJwt(token, secret) {
|
|
37
|
+
const parts = token.split('.');
|
|
38
|
+
if (parts.length !== 3)
|
|
39
|
+
return null;
|
|
40
|
+
const [header, payload, signature] = parts;
|
|
41
|
+
try {
|
|
42
|
+
const key = await hmacKey(secret, 'verify');
|
|
43
|
+
const valid = await crypto.subtle.verify('HMAC', key, base64UrlToBytes(signature), encoder.encode(`${header}.${payload}`));
|
|
44
|
+
if (!valid)
|
|
45
|
+
return null;
|
|
46
|
+
const claims = JSON.parse(decoder.decode(base64UrlToBytes(payload)));
|
|
47
|
+
if (typeof claims.exp === 'number' && claims.exp * 1000 < Date.now())
|
|
48
|
+
return null;
|
|
49
|
+
return claims;
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
/** Decode without verification (for introspection/debugging only). */
|
|
56
|
+
export function decodeJwt(token) {
|
|
57
|
+
const parts = token.split('.');
|
|
58
|
+
if (parts.length !== 3)
|
|
59
|
+
return null;
|
|
60
|
+
try {
|
|
61
|
+
return JSON.parse(decoder.decode(base64UrlToBytes(parts[1])));
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
export function randomToken(bytes = 32) {
|
|
68
|
+
const buf = new Uint8Array(bytes);
|
|
69
|
+
crypto.getRandomValues(buf);
|
|
70
|
+
return bytesToBase64Url(buf);
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=jwt.js.map
|
package/dist/jwt.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jwt.js","sourceRoot":"","sources":["../src/jwt.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bun-native server: Bun.serve with first-class WebSockets. Used automatically
|
|
3
|
+
* when the CLI runs under Bun (including single-binary builds) — same backend,
|
|
4
|
+
* same RealtimeSocketLike contract as the node:http path.
|
|
5
|
+
*/
|
|
6
|
+
import type { SupaliteBackendShape } from './server-shared.js';
|
|
7
|
+
import type { RunningServer, ServeOptions } from './server.js';
|
|
8
|
+
export declare function serveBun(backend: SupaliteBackendShape, opts?: ServeOptions): Promise<RunningServer>;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
export async function serveBun(backend, opts = {}) {
|
|
2
|
+
const host = opts.host ?? '127.0.0.1';
|
|
3
|
+
const server = Bun.serve({
|
|
4
|
+
port: opts.port ?? 54321,
|
|
5
|
+
hostname: host,
|
|
6
|
+
async fetch(req, srv) {
|
|
7
|
+
const url = new URL(req.url);
|
|
8
|
+
if (url.pathname.startsWith('/realtime/v1') && req.headers.get('upgrade')?.toLowerCase() === 'websocket') {
|
|
9
|
+
const ok = srv.upgrade(req, { data: { vsn: url.searchParams.get('vsn') ?? '1.0.0' } });
|
|
10
|
+
if (ok)
|
|
11
|
+
return undefined;
|
|
12
|
+
return new Response('upgrade failed', { status: 400 });
|
|
13
|
+
}
|
|
14
|
+
return backend.fetch(req);
|
|
15
|
+
},
|
|
16
|
+
websocket: {
|
|
17
|
+
open(ws) {
|
|
18
|
+
const session = backend.realtime.connect({
|
|
19
|
+
send: (data) => ws.send(data),
|
|
20
|
+
close: (code, reason) => ws.close(code, reason),
|
|
21
|
+
}, { vsn: ws.data.vsn });
|
|
22
|
+
ws.data.session = session;
|
|
23
|
+
},
|
|
24
|
+
message(ws, message) {
|
|
25
|
+
ws.data.session?.onMessage(typeof message === 'string' ? message : new Uint8Array(message));
|
|
26
|
+
},
|
|
27
|
+
close(ws) {
|
|
28
|
+
ws.data.session?.onClose();
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
});
|
|
32
|
+
return {
|
|
33
|
+
server: server,
|
|
34
|
+
port: server.port,
|
|
35
|
+
url: `http://${host}:${server.port}`,
|
|
36
|
+
close: async () => {
|
|
37
|
+
server.stop(true);
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=bun-server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bun-server.js","sourceRoot":"","sources":["../../src/node/bun-server.ts"],"names":[],"mappings":"AAeA,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,OAA6B,EAAE,OAAqB,EAAE;IACnF,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,WAAW,CAAA;IAErC,MAAM,MAAM,GAAG,GAAG,CAAC,KAAK,CAAC;QACvB,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,KAAK;QACxB,QAAQ,EAAE,IAAI;QACd,KAAK,CAAC,KAAK,CAAC,GAAY,EAAE,GAAQ;YAChC,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;YAC5B,IAAI,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,cAAc,CAAC,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,WAAW,EAAE,KAAK,WAAW,EAAE,CAAC;gBACzG,MAAM,EAAE,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,EAAE,GAAG,EAAE,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,OAAO,EAAE,EAAE,CAAC,CAAA;gBACtF,IAAI,EAAE;oBAAE,OAAO,SAAS,CAAA;gBACxB,OAAO,IAAI,QAAQ,CAAC,gBAAgB,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAA;YACxD,CAAC;YACD,OAAO,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;QAC3B,CAAC;QACD,SAAS,EAAE;YACT,IAAI,CAAC,EAA6F;gBAChG,MAAM,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,OAAO,CACtC;oBACE,IAAI,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC;oBAC7B,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC;iBAChD,EACD,EAAE,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,CACrB,CAAA;gBACD,EAAE,CAAC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAA;YAC3B,CAAC;YACD,OAAO,CAAC,EAAoB,EAAE,OAA4B;gBACxD,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,CAAC,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,UAAU,CAAC,OAAO,CAAC,CAAC,CAAA;YAC7F,CAAC;YACD,KAAK,CAAC,EAAoB;gBACxB,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,CAAA;YAC5B,CAAC;SACF;KACF,CAAC,CAAA;IAEF,OAAO;QACL,MAAM,EAAE,MAAe;QACvB,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,GAAG,EAAE,UAAU,IAAI,IAAI,MAAM,CAAC,IAAI,EAAE;QACpC,KAAK,EAAE,KAAK,IAAI,EAAE;YAChB,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QACnB,CAAC;KACF,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { StorageDriver } from '../types.js';
|
|
2
|
+
/** Node-only driver — object bytes live under a root directory. */
|
|
3
|
+
export declare class FsStorageDriver implements StorageDriver {
|
|
4
|
+
private root;
|
|
5
|
+
constructor(root: string);
|
|
6
|
+
private resolve;
|
|
7
|
+
put(key: string, data: Uint8Array): Promise<void>;
|
|
8
|
+
get(key: string): Promise<Uint8Array | null>;
|
|
9
|
+
delete(key: string): Promise<void>;
|
|
10
|
+
deleteMany(keys: string[]): Promise<void>;
|
|
11
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { mkdir, readFile, rm, writeFile } from 'node:fs/promises';
|
|
2
|
+
import { dirname, join, normalize, sep } from 'node:path';
|
|
3
|
+
/** Node-only driver — object bytes live under a root directory. */
|
|
4
|
+
export class FsStorageDriver {
|
|
5
|
+
root;
|
|
6
|
+
constructor(root) {
|
|
7
|
+
this.root = root;
|
|
8
|
+
}
|
|
9
|
+
resolve(key) {
|
|
10
|
+
const path = normalize(join(this.root, key));
|
|
11
|
+
if (!path.startsWith(normalize(this.root) + sep)) {
|
|
12
|
+
throw new Error(`invalid storage key: ${key}`);
|
|
13
|
+
}
|
|
14
|
+
return path;
|
|
15
|
+
}
|
|
16
|
+
async put(key, data) {
|
|
17
|
+
const path = this.resolve(key);
|
|
18
|
+
await mkdir(dirname(path), { recursive: true });
|
|
19
|
+
await writeFile(path, data);
|
|
20
|
+
}
|
|
21
|
+
async get(key) {
|
|
22
|
+
try {
|
|
23
|
+
return new Uint8Array(await readFile(this.resolve(key)));
|
|
24
|
+
}
|
|
25
|
+
catch (e) {
|
|
26
|
+
if (e.code === 'ENOENT')
|
|
27
|
+
return null;
|
|
28
|
+
throw e;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
async delete(key) {
|
|
32
|
+
await rm(this.resolve(key), { force: true });
|
|
33
|
+
}
|
|
34
|
+
async deleteMany(keys) {
|
|
35
|
+
for (const k of keys)
|
|
36
|
+
await this.delete(k);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=fs-driver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fs-driver.js","sourceRoot":"","sources":["../../src/node/fs-driver.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AACjE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,WAAW,CAAA;AAGzD,mEAAmE;AACnE,MAAM,OAAO,eAAe;IACN;IAApB,YAAoB,IAAY;QAAZ,SAAI,GAAJ,IAAI,CAAQ;IAAG,CAAC;IAE5B,OAAO,CAAC,GAAW;QACzB,MAAM,IAAI,GAAG,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAA;QAC5C,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,EAAE,CAAC;YACjD,MAAM,IAAI,KAAK,CAAC,wBAAwB,GAAG,EAAE,CAAC,CAAA;QAChD,CAAC;QACD,OAAO,IAAI,CAAA;IACb,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,GAAW,EAAE,IAAgB;QACrC,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;QAC9B,MAAM,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;QAC/C,MAAM,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;IAC7B,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,GAAW;QACnB,IAAI,CAAC;YACH,OAAO,IAAI,UAAU,CAAC,MAAM,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAA;QAC1D,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,IAAK,CAA2B,CAAC,IAAI,KAAK,QAAQ;gBAAE,OAAO,IAAI,CAAA;YAC/D,MAAM,CAAC,CAAA;QACT,CAAC;IACH,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,GAAW;QACtB,MAAM,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAA;IAC9C,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,IAAc;QAC7B,KAAK,MAAM,CAAC,IAAI,IAAI;YAAE,MAAM,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAA;IAC5C,CAAC;CACF"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/** Node-only entrypoints (HTTP server, fs storage, project loading). */
|
|
2
|
+
export { serve, type ServeOptions, type RunningServer } from './server.js';
|
|
3
|
+
export { FsStorageDriver } from './fs-driver.js';
|
|
4
|
+
export { loadSupabaseProject, type SupabaseProject } from './project.js';
|
|
5
|
+
export { acceptWebSocket, type WsConnection } from './ws.js';
|
|
6
|
+
export { createNativeEngine, ensurePostgres, type NativeEngineOptions } from './native/engine.js';
|
|
7
|
+
export { PgWireClient, PgWireError } from './native/wire.js';
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/** Node-only entrypoints (HTTP server, fs storage, project loading). */
|
|
2
|
+
export { serve } from './server.js';
|
|
3
|
+
export { FsStorageDriver } from './fs-driver.js';
|
|
4
|
+
export { loadSupabaseProject } from './project.js';
|
|
5
|
+
export { acceptWebSocket } from './ws.js';
|
|
6
|
+
export { createNativeEngine, ensurePostgres } from './native/engine.js';
|
|
7
|
+
export { PgWireClient, PgWireError } from './native/wire.js';
|
|
8
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/node/index.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,OAAO,EAAE,KAAK,EAAyC,MAAM,aAAa,CAAA;AAC1E,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAChD,OAAO,EAAE,mBAAmB,EAAwB,MAAM,cAAc,CAAA;AACxE,OAAO,EAAE,eAAe,EAAqB,MAAM,SAAS,CAAA;AAC5D,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAA4B,MAAM,oBAAoB,CAAA;AACjG,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { DbEngine } from '../../db/engine.js';
|
|
2
|
+
export interface NativeEngineOptions {
|
|
3
|
+
/** Postgres data directory (created + initdb'd if missing). */
|
|
4
|
+
dataDir: string;
|
|
5
|
+
/** Postgres version tag from theseus-rs/postgresql-binaries. */
|
|
6
|
+
version?: string;
|
|
7
|
+
/** Where downloaded binaries are cached. Default ~/.cache/tinbase */
|
|
8
|
+
cacheDir?: string;
|
|
9
|
+
log?: (msg: string) => void;
|
|
10
|
+
}
|
|
11
|
+
/** Download + unpack Postgres binaries if not already cached. Returns the install dir. */
|
|
12
|
+
export declare function ensurePostgres(version?: string, cacheDir?: string, log?: (m: string) => void): Promise<string>;
|
|
13
|
+
export declare function createNativeEngine(opts: NativeEngineOptions): Promise<DbEngine>;
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Native embedded Postgres engine — PocketBase-class footprint with real
|
|
3
|
+
* Postgres semantics. Downloads platform binaries once (~12 MB from
|
|
4
|
+
* theseus-rs/postgresql-binaries), runs initdb with memory-lean settings,
|
|
5
|
+
* and manages the postgres child process. Trust auth over a private unix
|
|
6
|
+
* socket directory (0700), never TCP.
|
|
7
|
+
*/
|
|
8
|
+
import { execFileSync, spawn } from 'node:child_process';
|
|
9
|
+
import { chmodSync, existsSync, mkdirSync, mkdtempSync, rmSync, appendFileSync } from 'node:fs';
|
|
10
|
+
import { writeFile } from 'node:fs/promises';
|
|
11
|
+
import { homedir, tmpdir } from 'node:os';
|
|
12
|
+
import { join } from 'node:path';
|
|
13
|
+
import { Mutex } from '../../db/engine.js';
|
|
14
|
+
import { PgWireClient } from './wire.js';
|
|
15
|
+
const DEFAULT_PG_VERSION = '17.7.0';
|
|
16
|
+
function target() {
|
|
17
|
+
const arch = process.arch === 'arm64' ? 'aarch64' : process.arch === 'x64' ? 'x86_64' : null;
|
|
18
|
+
if (!arch)
|
|
19
|
+
throw new Error(`unsupported architecture for native engine: ${process.arch}`);
|
|
20
|
+
if (process.platform === 'darwin')
|
|
21
|
+
return `${arch}-apple-darwin`;
|
|
22
|
+
if (process.platform === 'linux')
|
|
23
|
+
return `${arch}-unknown-linux-gnu`;
|
|
24
|
+
throw new Error(`unsupported platform for native engine: ${process.platform} (use the default PGlite engine)`);
|
|
25
|
+
}
|
|
26
|
+
/** Download + unpack Postgres binaries if not already cached. Returns the install dir. */
|
|
27
|
+
export async function ensurePostgres(version = DEFAULT_PG_VERSION, cacheDir, log) {
|
|
28
|
+
const t = target();
|
|
29
|
+
const root = cacheDir ?? join(homedir(), '.cache', 'tinbase');
|
|
30
|
+
const dir = join(root, `postgresql-${version}-${t}`);
|
|
31
|
+
if (existsSync(join(dir, 'bin', 'postgres')))
|
|
32
|
+
return dir;
|
|
33
|
+
const url = `https://github.com/theseus-rs/postgresql-binaries/releases/download/${version}/postgresql-${version}-${t}.tar.gz`;
|
|
34
|
+
log?.(`downloading postgres ${version} (${t})…`);
|
|
35
|
+
const res = await fetch(url);
|
|
36
|
+
if (!res.ok)
|
|
37
|
+
throw new Error(`failed to download ${url}: HTTP ${res.status}`);
|
|
38
|
+
mkdirSync(dir, { recursive: true });
|
|
39
|
+
const tarball = join(root, `pg-${version}.tar.gz`);
|
|
40
|
+
await writeFile(tarball, Buffer.from(await res.arrayBuffer()));
|
|
41
|
+
execFileSync('tar', ['xzf', tarball, '-C', dir, '--strip-components=1']);
|
|
42
|
+
rmSync(tarball, { force: true });
|
|
43
|
+
log?.(`postgres installed to ${dir}`);
|
|
44
|
+
return dir;
|
|
45
|
+
}
|
|
46
|
+
const TUNED_CONF = `
|
|
47
|
+
# tinbase: memory-lean settings for an embedded, single-app Postgres
|
|
48
|
+
listen_addresses = ''
|
|
49
|
+
shared_buffers = 16MB
|
|
50
|
+
dynamic_shared_memory_type = posix
|
|
51
|
+
max_connections = 10
|
|
52
|
+
wal_level = minimal
|
|
53
|
+
max_wal_senders = 0
|
|
54
|
+
synchronous_commit = off
|
|
55
|
+
logging_collector = off
|
|
56
|
+
`;
|
|
57
|
+
export async function createNativeEngine(opts) {
|
|
58
|
+
const installDir = await ensurePostgres(opts.version, opts.cacheDir, opts.log);
|
|
59
|
+
const bin = (name) => join(installDir, 'bin', name);
|
|
60
|
+
// initdb on first boot
|
|
61
|
+
if (!existsSync(join(opts.dataDir, 'PG_VERSION'))) {
|
|
62
|
+
mkdirSync(opts.dataDir, { recursive: true });
|
|
63
|
+
execFileSync(bin('initdb'), ['-U', 'postgres', '-A', 'trust', '-E', 'UTF8', '-D', opts.dataDir], {
|
|
64
|
+
stdio: 'ignore',
|
|
65
|
+
});
|
|
66
|
+
appendFileSync(join(opts.dataDir, 'postgresql.conf'), TUNED_CONF);
|
|
67
|
+
}
|
|
68
|
+
// private socket dir — trust auth is safe because only this user can reach it
|
|
69
|
+
const sockDir = mkdtempSync(join(tmpdir(), 'tinbase-pg-'));
|
|
70
|
+
chmodSync(sockDir, 0o700);
|
|
71
|
+
const child = spawn(bin('postgres'), ['-D', opts.dataDir, '-k', sockDir], {
|
|
72
|
+
stdio: 'ignore',
|
|
73
|
+
detached: false,
|
|
74
|
+
});
|
|
75
|
+
let childExited = false;
|
|
76
|
+
child.on('exit', () => (childExited = true));
|
|
77
|
+
const socketPath = join(sockDir, '.s.PGSQL.5432');
|
|
78
|
+
const connect = async () => {
|
|
79
|
+
const deadline = Date.now() + 20_000;
|
|
80
|
+
for (;;) {
|
|
81
|
+
try {
|
|
82
|
+
return await PgWireClient.connect({ socketPath, user: 'postgres', database: 'postgres' });
|
|
83
|
+
}
|
|
84
|
+
catch (e) {
|
|
85
|
+
if (childExited)
|
|
86
|
+
throw new Error('postgres exited during startup');
|
|
87
|
+
if (Date.now() > deadline)
|
|
88
|
+
throw e;
|
|
89
|
+
await new Promise((r) => setTimeout(r, 150));
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
const main = await connect();
|
|
94
|
+
const listener = await connect();
|
|
95
|
+
const mutex = new Mutex();
|
|
96
|
+
const listeners = new Map();
|
|
97
|
+
listener.onNotification = (channel, payload) => {
|
|
98
|
+
for (const cb of listeners.get(channel) ?? [])
|
|
99
|
+
cb(payload);
|
|
100
|
+
};
|
|
101
|
+
const tx = {
|
|
102
|
+
async query(sql, params) {
|
|
103
|
+
const res = await main.query(sql, normalizeParams(params));
|
|
104
|
+
return { rows: res.rows, affectedRows: res.affectedRows };
|
|
105
|
+
},
|
|
106
|
+
async exec(sql) {
|
|
107
|
+
await main.exec(sql);
|
|
108
|
+
},
|
|
109
|
+
};
|
|
110
|
+
return {
|
|
111
|
+
query(sql, params) {
|
|
112
|
+
return mutex.run(() => tx.query(sql, params));
|
|
113
|
+
},
|
|
114
|
+
exec(sql) {
|
|
115
|
+
return mutex.run(() => tx.exec(sql));
|
|
116
|
+
},
|
|
117
|
+
transaction(fn) {
|
|
118
|
+
return mutex.run(async () => {
|
|
119
|
+
await main.exec('begin');
|
|
120
|
+
try {
|
|
121
|
+
const result = await fn(tx);
|
|
122
|
+
await main.exec('commit');
|
|
123
|
+
return result;
|
|
124
|
+
}
|
|
125
|
+
catch (e) {
|
|
126
|
+
await main.exec('rollback').catch(() => { });
|
|
127
|
+
throw e;
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
},
|
|
131
|
+
async listen(channel, cb) {
|
|
132
|
+
if (!listeners.has(channel)) {
|
|
133
|
+
listeners.set(channel, new Set());
|
|
134
|
+
await listener.exec(`listen "${channel.replaceAll('"', '""')}"`);
|
|
135
|
+
}
|
|
136
|
+
listeners.get(channel).add(cb);
|
|
137
|
+
return () => listeners.get(channel)?.delete(cb);
|
|
138
|
+
},
|
|
139
|
+
async close() {
|
|
140
|
+
await main.close().catch(() => { });
|
|
141
|
+
await listener.close().catch(() => { });
|
|
142
|
+
if (!childExited) {
|
|
143
|
+
child.kill('SIGINT'); // fast shutdown
|
|
144
|
+
await new Promise((resolve) => {
|
|
145
|
+
const t = setTimeout(() => {
|
|
146
|
+
child.kill('SIGKILL');
|
|
147
|
+
resolve();
|
|
148
|
+
}, 5000);
|
|
149
|
+
child.on('exit', () => {
|
|
150
|
+
clearTimeout(t);
|
|
151
|
+
resolve();
|
|
152
|
+
});
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
rmSync(sockDir, { recursive: true, force: true });
|
|
156
|
+
},
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
/** Match PGlite's param serialization: arrays → pg literals, objects → JSON. */
|
|
160
|
+
function normalizeParams(params) {
|
|
161
|
+
return params?.map((p) => {
|
|
162
|
+
if (p === null || p === undefined)
|
|
163
|
+
return null;
|
|
164
|
+
if (Array.isArray(p))
|
|
165
|
+
return toPgArrayLiteral(p);
|
|
166
|
+
if (p instanceof Date)
|
|
167
|
+
return p.toISOString();
|
|
168
|
+
if (typeof p === 'object')
|
|
169
|
+
return JSON.stringify(p);
|
|
170
|
+
return p;
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
function toPgArrayLiteral(arr) {
|
|
174
|
+
const items = arr.map((el) => {
|
|
175
|
+
if (el === null || el === undefined)
|
|
176
|
+
return 'NULL';
|
|
177
|
+
if (Array.isArray(el))
|
|
178
|
+
return toPgArrayLiteral(el);
|
|
179
|
+
if (typeof el === 'number' || typeof el === 'boolean')
|
|
180
|
+
return String(el);
|
|
181
|
+
const s = typeof el === 'object' ? JSON.stringify(el) : String(el);
|
|
182
|
+
return `"${s.replaceAll('\\', '\\\\').replaceAll('"', '\\"')}"`;
|
|
183
|
+
});
|
|
184
|
+
return `{${items.join(',')}}`;
|
|
185
|
+
}
|
|
186
|
+
//# sourceMappingURL=engine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engine.js","sourceRoot":"","sources":["../../../src/node/native/engine.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
export interface WireResults<T = any> {
|
|
2
|
+
rows: T[];
|
|
3
|
+
affectedRows?: number;
|
|
4
|
+
}
|
|
5
|
+
export declare class PgWireError extends Error {
|
|
6
|
+
code?: string;
|
|
7
|
+
detail?: string;
|
|
8
|
+
hint?: string;
|
|
9
|
+
severity?: string;
|
|
10
|
+
constructor(fields: Map<string, string>);
|
|
11
|
+
}
|
|
12
|
+
export declare class PgWireClient {
|
|
13
|
+
private socket;
|
|
14
|
+
private buffer;
|
|
15
|
+
private pending;
|
|
16
|
+
private queue;
|
|
17
|
+
private closed;
|
|
18
|
+
onNotification: ((channel: string, payload: string) => void) | null;
|
|
19
|
+
static connect(opts: {
|
|
20
|
+
socketPath?: string;
|
|
21
|
+
host?: string;
|
|
22
|
+
port?: number;
|
|
23
|
+
user: string;
|
|
24
|
+
database: string;
|
|
25
|
+
}): Promise<PgWireClient>;
|
|
26
|
+
private open;
|
|
27
|
+
/** One protocol op at a time; queued to be safe under concurrency. */
|
|
28
|
+
private run;
|
|
29
|
+
/** Simple query protocol — supports multiple statements. */
|
|
30
|
+
exec(sql: string): Promise<WireResults[]>;
|
|
31
|
+
/** Extended query protocol with text-format params. */
|
|
32
|
+
query<T = any>(sql: string, params?: unknown[]): Promise<WireResults<T>>;
|
|
33
|
+
close(): Promise<void>;
|
|
34
|
+
private nextMessage;
|
|
35
|
+
private processMessages;
|
|
36
|
+
}
|
|
37
|
+
/** Parse a one-dimensional Postgres array literal: {a,"b c",NULL} */
|
|
38
|
+
export declare function parsePgArray(text: string): (string | null)[];
|