@dotdo/postgres 0.1.2 → 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.
- package/README.md +73 -1
- package/dist/client/index.d.ts +47 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +47 -0
- package/dist/client/index.js.map +1 -0
- package/dist/client/postgres-client.d.ts +273 -0
- package/dist/client/postgres-client.d.ts.map +1 -0
- package/dist/client/postgres-client.js +389 -0
- package/dist/client/postgres-client.js.map +1 -0
- package/dist/client/types.d.ts +167 -0
- package/dist/client/types.d.ts.map +1 -0
- package/dist/client/types.js +7 -0
- package/dist/client/types.js.map +1 -0
- package/dist/do/index.d.ts +18 -0
- package/dist/do/index.d.ts.map +1 -0
- package/dist/do/index.js +18 -0
- package/dist/do/index.js.map +1 -0
- package/dist/do/postgres.d.ts +110 -0
- package/dist/do/postgres.d.ts.map +1 -0
- package/dist/do/postgres.js +266 -0
- package/dist/do/postgres.js.map +1 -0
- package/dist/do/sql.d.ts +92 -0
- package/dist/do/sql.d.ts.map +1 -0
- package/dist/do/sql.js +204 -0
- package/dist/do/sql.js.map +1 -0
- package/dist/index.d.ts +25 -30
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +29 -30
- package/dist/index.js.map +1 -1
- package/dist/mcp/binding.d.ts +47 -0
- package/dist/mcp/binding.d.ts.map +1 -0
- package/dist/mcp/binding.js +183 -0
- package/dist/mcp/binding.js.map +1 -0
- package/dist/mcp/index.d.ts +92 -0
- package/dist/mcp/index.d.ts.map +1 -0
- package/dist/mcp/index.js +91 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/server.d.ts +62 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +278 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/tools.d.ts +58 -0
- package/dist/mcp/tools.d.ts.map +1 -0
- package/dist/mcp/tools.js +356 -0
- package/dist/mcp/tools.js.map +1 -0
- package/dist/mcp/types.d.ts +139 -0
- package/dist/mcp/types.d.ts.map +1 -0
- package/dist/mcp/types.js +7 -0
- package/dist/mcp/types.js.map +1 -0
- package/dist/pglite/workers-pglite.d.ts +13 -4
- package/dist/pglite/workers-pglite.d.ts.map +1 -1
- package/dist/pglite/workers-pglite.js +110 -5
- package/dist/pglite/workers-pglite.js.map +1 -1
- package/dist/pglite-assets/pglite.data +0 -0
- package/dist/pglite-assets/pglite.wasm +0 -0
- package/dist/worker/background-pglite-manager.d.ts +243 -0
- package/dist/worker/background-pglite-manager.d.ts.map +1 -0
- package/dist/worker/background-pglite-manager.js +528 -0
- package/dist/worker/background-pglite-manager.js.map +1 -0
- package/dist/worker/do-pglite-manager.d.ts +77 -0
- package/dist/worker/do-pglite-manager.d.ts.map +1 -1
- package/dist/worker/do-pglite-manager.js +189 -12
- package/dist/worker/do-pglite-manager.js.map +1 -1
- package/dist/worker/index.d.ts +7 -1
- package/dist/worker/index.d.ts.map +1 -1
- package/dist/worker/index.js +19 -1
- package/dist/worker/index.js.map +1 -1
- package/dist/worker/lazy-pglite-manager.d.ts +242 -0
- package/dist/worker/lazy-pglite-manager.d.ts.map +1 -0
- package/dist/worker/lazy-pglite-manager.js +463 -0
- package/dist/worker/lazy-pglite-manager.js.map +1 -0
- package/package.json +16 -3
- package/src/client/index.ts +61 -0
- package/src/client/postgres-client.ts +442 -0
- package/src/client/types.ts +211 -0
- package/src/do/index.ts +18 -0
- package/src/do/postgres.ts +367 -0
- package/src/do/sql.ts +280 -0
- package/src/index.ts +50 -30
- package/src/mcp/binding.ts +236 -0
- package/src/mcp/index.ts +122 -0
- package/src/mcp/server.ts +361 -0
- package/src/mcp/tools.ts +464 -0
- package/src/mcp/types.ts +148 -0
- package/src/pglite/workers-pglite.ts +141 -12
- package/src/pglite-assets/pglite.data +0 -0
- package/src/pglite-assets/pglite.wasm +0 -0
- package/src/worker/background-pglite-manager.ts +680 -0
- package/src/worker/do-pglite-manager.ts +235 -19
- package/src/worker/index.ts +71 -1
- package/src/worker/lazy-pglite-manager.ts +595 -0
- package/dist/iceberg/duckdb-wasm.d.ts +0 -447
- package/dist/iceberg/duckdb-wasm.d.ts.map +0 -1
- package/dist/iceberg/duckdb-wasm.js +0 -600
- package/dist/iceberg/duckdb-wasm.js.map +0 -1
- package/dist/iceberg/test-fixtures.d.ts +0 -151
- package/dist/iceberg/test-fixtures.d.ts.map +0 -1
- package/dist/iceberg/test-fixtures.js +0 -446
- package/dist/iceberg/test-fixtures.js.map +0 -1
- package/dist/worker/__mocks__/cloudflare-workers.d.ts +0 -31
- package/dist/worker/__mocks__/cloudflare-workers.d.ts.map +0 -1
- package/dist/worker/__mocks__/cloudflare-workers.js +0 -33
- package/dist/worker/__mocks__/cloudflare-workers.js.map +0 -1
|
@@ -0,0 +1,528 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Background PGLite Manager for PostgresDO
|
|
3
|
+
*
|
|
4
|
+
* This module implements a "eager-but-non-blocking" loading pattern:
|
|
5
|
+
* - WASM loading starts immediately on initialize() but doesn't block
|
|
6
|
+
* - Non-query endpoints respond instantly while WASM loads in background
|
|
7
|
+
* - Queries wait for WASM if not ready, but loading already started
|
|
8
|
+
* - Uses ctx.waitUntil() to keep DO alive during background loading
|
|
9
|
+
*
|
|
10
|
+
* ## Why This is Better Than Pure Lazy Loading
|
|
11
|
+
*
|
|
12
|
+
* Pure lazy loading just kicks the can down the road:
|
|
13
|
+
* - First query still pays full ~1200ms WASM load time
|
|
14
|
+
*
|
|
15
|
+
* Background loading gives us the best of both worlds:
|
|
16
|
+
* - Non-query endpoints respond instantly
|
|
17
|
+
* - WASM starts loading immediately
|
|
18
|
+
* - First query only waits for remaining load time (often near-zero)
|
|
19
|
+
* - If query arrives before WASM ready, it waits but loading is already in progress
|
|
20
|
+
*
|
|
21
|
+
* ## Usage with Durable Objects
|
|
22
|
+
*
|
|
23
|
+
* ```typescript
|
|
24
|
+
* export class MyDO extends DurableObject {
|
|
25
|
+
* private manager: BackgroundPGLiteManager
|
|
26
|
+
*
|
|
27
|
+
* constructor(ctx: DurableObjectState, env: Env) {
|
|
28
|
+
* super(ctx, env)
|
|
29
|
+
* this.manager = new BackgroundPGLiteManager({
|
|
30
|
+
* database: 'mydb',
|
|
31
|
+
* waitUntil: (p) => ctx.waitUntil(p), // Keep DO alive during load
|
|
32
|
+
* })
|
|
33
|
+
* }
|
|
34
|
+
*
|
|
35
|
+
* async init() {
|
|
36
|
+
* // Starts WASM loading in background, returns immediately
|
|
37
|
+
* await this.manager.initialize()
|
|
38
|
+
* }
|
|
39
|
+
*
|
|
40
|
+
* // Health check - responds instantly, triggers background load if needed
|
|
41
|
+
* async ping() {
|
|
42
|
+
* return { ok: true, wasmLoading: this.manager.isLoading() }
|
|
43
|
+
* }
|
|
44
|
+
*
|
|
45
|
+
* // Query - waits for WASM if not ready
|
|
46
|
+
* async query(sql: string) {
|
|
47
|
+
* return this.manager.query(sql)
|
|
48
|
+
* }
|
|
49
|
+
* }
|
|
50
|
+
* ```
|
|
51
|
+
*
|
|
52
|
+
* @module worker/background-pglite-manager
|
|
53
|
+
*/
|
|
54
|
+
import { PluginManager } from './plugin-manager';
|
|
55
|
+
// Import WASM module and data bundle for Workers
|
|
56
|
+
import pgliteWasm from '../pglite-assets/pglite.wasm';
|
|
57
|
+
import pgliteData from '../pglite-assets/pglite.data';
|
|
58
|
+
// Import Workers-compatible PGLite wrapper
|
|
59
|
+
import { createWorkersPGLite } from '../pglite/workers-pglite';
|
|
60
|
+
// =============================================================================
|
|
61
|
+
// Module-Level WASM State (for hoisting across DO reinstantiation)
|
|
62
|
+
// =============================================================================
|
|
63
|
+
/**
|
|
64
|
+
* Hoisted PGLite instance - survives DO class reinstantiation within same isolate.
|
|
65
|
+
*/
|
|
66
|
+
let bgHoistedPglite = null;
|
|
67
|
+
/**
|
|
68
|
+
* Promise for in-progress PGLite initialization.
|
|
69
|
+
* Shared across all manager instances for deduplication.
|
|
70
|
+
*/
|
|
71
|
+
let bgHoistedPglitePromise = null;
|
|
72
|
+
/**
|
|
73
|
+
* Timestamp when WASM loading started
|
|
74
|
+
*/
|
|
75
|
+
let wasmLoadStartedAt = null;
|
|
76
|
+
/**
|
|
77
|
+
* Timestamp when WASM was loaded
|
|
78
|
+
*/
|
|
79
|
+
let wasmLoadedAt = null;
|
|
80
|
+
/**
|
|
81
|
+
* Unique identifier for this module instance
|
|
82
|
+
*/
|
|
83
|
+
const BG_MODULE_INSTANCE_ID = Math.random().toString(36).slice(2, 10);
|
|
84
|
+
/**
|
|
85
|
+
* Check if the hoisted PGLite instance exists.
|
|
86
|
+
*/
|
|
87
|
+
export function hasBgHoistedPglite() {
|
|
88
|
+
return bgHoistedPglite !== null;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Check if WASM loading is in progress.
|
|
92
|
+
*/
|
|
93
|
+
export function isBgWasmLoading() {
|
|
94
|
+
return bgHoistedPglitePromise !== null && bgHoistedPglite === null;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Get diagnostics about the background hoisted WASM state.
|
|
98
|
+
*/
|
|
99
|
+
export function getBgHoistedPgliteDiagnostics() {
|
|
100
|
+
const now = Date.now();
|
|
101
|
+
return {
|
|
102
|
+
hasInstance: bgHoistedPglite !== null,
|
|
103
|
+
isLoading: bgHoistedPglitePromise !== null && bgHoistedPglite === null,
|
|
104
|
+
moduleInstanceId: BG_MODULE_INSTANCE_ID,
|
|
105
|
+
wasmLoadStartedAt,
|
|
106
|
+
wasmLoadedAt,
|
|
107
|
+
loadDurationMs: wasmLoadStartedAt && wasmLoadedAt ? wasmLoadedAt - wasmLoadStartedAt : null,
|
|
108
|
+
timeSinceLoadMs: wasmLoadedAt !== null ? now - wasmLoadedAt : null,
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Reset the hoisted PGLite instance.
|
|
113
|
+
* WARNING: This should only be used in tests.
|
|
114
|
+
* @internal
|
|
115
|
+
*/
|
|
116
|
+
export function resetBgHoistedPglite() {
|
|
117
|
+
bgHoistedPglite = null;
|
|
118
|
+
bgHoistedPglitePromise = null;
|
|
119
|
+
wasmLoadStartedAt = null;
|
|
120
|
+
wasmLoadedAt = null;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Start WASM loading and return the promise.
|
|
124
|
+
* This is called by initialize() but not awaited.
|
|
125
|
+
*/
|
|
126
|
+
function startWasmLoading(options) {
|
|
127
|
+
// Fast path: already initialized
|
|
128
|
+
if (bgHoistedPglite) {
|
|
129
|
+
return Promise.resolve(bgHoistedPglite);
|
|
130
|
+
}
|
|
131
|
+
// Deduplication: return existing promise if loading in progress
|
|
132
|
+
if (bgHoistedPglitePromise) {
|
|
133
|
+
return bgHoistedPglitePromise;
|
|
134
|
+
}
|
|
135
|
+
wasmLoadStartedAt = Date.now();
|
|
136
|
+
console.log(`[BackgroundPGLiteManager] Starting WASM load in background - instance: ${BG_MODULE_INSTANCE_ID}`);
|
|
137
|
+
// Start initialization
|
|
138
|
+
bgHoistedPglitePromise = createWorkersPGLite({
|
|
139
|
+
wasmModule: pgliteWasm,
|
|
140
|
+
fsBundle: pgliteData,
|
|
141
|
+
database: options.database ?? 'postgres',
|
|
142
|
+
debug: options.debug ?? 0,
|
|
143
|
+
}).then((pglite) => {
|
|
144
|
+
bgHoistedPglite = pglite;
|
|
145
|
+
wasmLoadedAt = Date.now();
|
|
146
|
+
const loadDuration = wasmLoadedAt - (wasmLoadStartedAt ?? wasmLoadedAt);
|
|
147
|
+
console.log(`[BackgroundPGLiteManager] WASM LOADED - took ${loadDuration}ms, instance: ${BG_MODULE_INSTANCE_ID}`);
|
|
148
|
+
return pglite;
|
|
149
|
+
}).catch((error) => {
|
|
150
|
+
console.error(`[BackgroundPGLiteManager] WASM load failed:`, error);
|
|
151
|
+
// Clear the promise so we can retry
|
|
152
|
+
bgHoistedPglitePromise = null;
|
|
153
|
+
throw error;
|
|
154
|
+
});
|
|
155
|
+
return bgHoistedPglitePromise;
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Get the hoisted instance, waiting for loading if in progress.
|
|
159
|
+
*/
|
|
160
|
+
async function getOrAwaitHoistedPglite(options) {
|
|
161
|
+
// Fast path: already loaded
|
|
162
|
+
if (bgHoistedPglite) {
|
|
163
|
+
return bgHoistedPglite;
|
|
164
|
+
}
|
|
165
|
+
// Loading in progress - wait for it
|
|
166
|
+
if (bgHoistedPglitePromise) {
|
|
167
|
+
return bgHoistedPglitePromise;
|
|
168
|
+
}
|
|
169
|
+
// Not started yet - start now (shouldn't happen if initialize() was called)
|
|
170
|
+
return startWasmLoading(options);
|
|
171
|
+
}
|
|
172
|
+
// =============================================================================
|
|
173
|
+
// BackgroundPGLiteManager Class
|
|
174
|
+
// =============================================================================
|
|
175
|
+
/**
|
|
176
|
+
* BackgroundPGLiteManager starts WASM loading immediately but doesn't block.
|
|
177
|
+
*
|
|
178
|
+
* This gives the best of both worlds:
|
|
179
|
+
* - Non-query endpoints respond instantly
|
|
180
|
+
* - WASM starts loading on first init
|
|
181
|
+
* - Queries wait only for remaining load time (often zero if loaded)
|
|
182
|
+
* - Uses ctx.waitUntil() to keep DO alive during background loading
|
|
183
|
+
*/
|
|
184
|
+
export class BackgroundPGLiteManager {
|
|
185
|
+
pglite = null;
|
|
186
|
+
initialized = false;
|
|
187
|
+
loadingState = 'not_started';
|
|
188
|
+
loadError = null;
|
|
189
|
+
config;
|
|
190
|
+
pluginManager;
|
|
191
|
+
usingHoistedInstance = false;
|
|
192
|
+
loadPromise = null;
|
|
193
|
+
/** Timing metrics for diagnostics */
|
|
194
|
+
metrics = {
|
|
195
|
+
initializeCalledAt: null,
|
|
196
|
+
wasmLoadStartAt: null,
|
|
197
|
+
wasmLoadEndAt: null,
|
|
198
|
+
firstQueryAt: null,
|
|
199
|
+
firstQueryWaitedMs: null,
|
|
200
|
+
};
|
|
201
|
+
constructor(config = {}) {
|
|
202
|
+
this.config = {
|
|
203
|
+
database: config.database ?? 'postgres',
|
|
204
|
+
debug: config.debug ?? false,
|
|
205
|
+
...config,
|
|
206
|
+
};
|
|
207
|
+
const pluginManagerConfig = {};
|
|
208
|
+
if (config.plugins !== undefined) {
|
|
209
|
+
pluginManagerConfig.plugins = config.plugins;
|
|
210
|
+
}
|
|
211
|
+
if (config.debug !== undefined) {
|
|
212
|
+
pluginManagerConfig.debug = config.debug;
|
|
213
|
+
}
|
|
214
|
+
this.pluginManager = new PluginManager(pluginManagerConfig);
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Initialize the manager.
|
|
218
|
+
*
|
|
219
|
+
* This starts WASM loading in the background but returns immediately.
|
|
220
|
+
* Non-query operations can proceed while WASM loads.
|
|
221
|
+
*
|
|
222
|
+
* If waitUntil is provided, it's used to keep the DO alive during loading.
|
|
223
|
+
*/
|
|
224
|
+
async initialize() {
|
|
225
|
+
if (this.initialized) {
|
|
226
|
+
return;
|
|
227
|
+
}
|
|
228
|
+
this.metrics.initializeCalledAt = Date.now();
|
|
229
|
+
this.initialized = true;
|
|
230
|
+
// If custom factory provided, use it (for testing)
|
|
231
|
+
if (this.config.createPGLite) {
|
|
232
|
+
this.loadingState = 'loading';
|
|
233
|
+
this.loadPromise = this.config.createPGLite();
|
|
234
|
+
this.loadPromise.then((pg) => {
|
|
235
|
+
this.pglite = pg;
|
|
236
|
+
this.loadingState = 'loaded';
|
|
237
|
+
this.metrics.wasmLoadEndAt = Date.now();
|
|
238
|
+
}).catch((err) => {
|
|
239
|
+
this.loadingState = 'error';
|
|
240
|
+
this.loadError = err;
|
|
241
|
+
});
|
|
242
|
+
if (this.config.waitUntil) {
|
|
243
|
+
this.config.waitUntil(this.loadPromise.catch(() => { }));
|
|
244
|
+
}
|
|
245
|
+
console.log(`[BackgroundPGLiteManager] Initialized (custom factory, loading in background)`);
|
|
246
|
+
return;
|
|
247
|
+
}
|
|
248
|
+
// If hoisting is disabled, start loading but don't hoist
|
|
249
|
+
if (this.config.disableHoisting) {
|
|
250
|
+
this.loadingState = 'loading';
|
|
251
|
+
this.metrics.wasmLoadStartAt = Date.now();
|
|
252
|
+
this.loadPromise = createWorkersPGLite({
|
|
253
|
+
wasmModule: pgliteWasm,
|
|
254
|
+
fsBundle: pgliteData,
|
|
255
|
+
database: this.config.database ?? 'postgres',
|
|
256
|
+
debug: this.config.debug ? 1 : 0,
|
|
257
|
+
});
|
|
258
|
+
this.loadPromise.then((pg) => {
|
|
259
|
+
this.pglite = pg;
|
|
260
|
+
this.loadingState = 'loaded';
|
|
261
|
+
this.metrics.wasmLoadEndAt = Date.now();
|
|
262
|
+
console.log(`[BackgroundPGLiteManager] WASM LOADED (non-hoisted) - took ${this.metrics.wasmLoadEndAt - (this.metrics.wasmLoadStartAt ?? 0)}ms`);
|
|
263
|
+
}).catch((err) => {
|
|
264
|
+
this.loadingState = 'error';
|
|
265
|
+
this.loadError = err;
|
|
266
|
+
console.error(`[BackgroundPGLiteManager] WASM load failed:`, err);
|
|
267
|
+
});
|
|
268
|
+
if (this.config.waitUntil) {
|
|
269
|
+
this.config.waitUntil(this.loadPromise.catch(() => { }));
|
|
270
|
+
}
|
|
271
|
+
console.log(`[BackgroundPGLiteManager] Initialized (hoisting disabled, loading in background)`);
|
|
272
|
+
return;
|
|
273
|
+
}
|
|
274
|
+
// Use hoisted instance
|
|
275
|
+
this.usingHoistedInstance = true;
|
|
276
|
+
// Check if already loaded
|
|
277
|
+
if (bgHoistedPglite) {
|
|
278
|
+
this.pglite = bgHoistedPglite;
|
|
279
|
+
this.loadingState = 'loaded';
|
|
280
|
+
console.log(`[BackgroundPGLiteManager] Initialized (WASM already loaded, reusing hoisted instance)`);
|
|
281
|
+
return;
|
|
282
|
+
}
|
|
283
|
+
// Start loading in background
|
|
284
|
+
this.loadingState = 'loading';
|
|
285
|
+
this.metrics.wasmLoadStartAt = Date.now();
|
|
286
|
+
const loadPromise = startWasmLoading({
|
|
287
|
+
database: this.config.database,
|
|
288
|
+
debug: this.config.debug ? 1 : 0,
|
|
289
|
+
});
|
|
290
|
+
// Track when loading completes for this manager
|
|
291
|
+
loadPromise.then((pg) => {
|
|
292
|
+
this.pglite = pg;
|
|
293
|
+
this.loadingState = 'loaded';
|
|
294
|
+
this.metrics.wasmLoadEndAt = Date.now();
|
|
295
|
+
}).catch((err) => {
|
|
296
|
+
this.loadingState = 'error';
|
|
297
|
+
this.loadError = err;
|
|
298
|
+
});
|
|
299
|
+
// Use waitUntil to keep DO alive during loading
|
|
300
|
+
if (this.config.waitUntil) {
|
|
301
|
+
this.config.waitUntil(loadPromise.catch(() => { }));
|
|
302
|
+
}
|
|
303
|
+
console.log(`[BackgroundPGLiteManager] Initialized (starting WASM load in background)`);
|
|
304
|
+
}
|
|
305
|
+
/**
|
|
306
|
+
* Check if WASM is fully loaded and ready for queries.
|
|
307
|
+
*/
|
|
308
|
+
isWASMLoaded() {
|
|
309
|
+
return this.loadingState === 'loaded' && this.pglite !== null;
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* Check if WASM is currently loading.
|
|
313
|
+
*/
|
|
314
|
+
isLoading() {
|
|
315
|
+
return this.loadingState === 'loading';
|
|
316
|
+
}
|
|
317
|
+
/**
|
|
318
|
+
* Get the current loading state.
|
|
319
|
+
*/
|
|
320
|
+
getLoadingState() {
|
|
321
|
+
return this.loadingState;
|
|
322
|
+
}
|
|
323
|
+
/**
|
|
324
|
+
* Get the PGLite instance, waiting for loading to complete if needed.
|
|
325
|
+
* This is called internally by query methods.
|
|
326
|
+
*/
|
|
327
|
+
async getPglite() {
|
|
328
|
+
// Already loaded
|
|
329
|
+
if (this.pglite) {
|
|
330
|
+
return this.pglite;
|
|
331
|
+
}
|
|
332
|
+
// Using hoisted instance
|
|
333
|
+
if (this.usingHoistedInstance && !this.config.createPGLite) {
|
|
334
|
+
const waitStart = performance.now();
|
|
335
|
+
const pg = await getOrAwaitHoistedPglite({
|
|
336
|
+
database: this.config.database,
|
|
337
|
+
debug: this.config.debug ? 1 : 0,
|
|
338
|
+
});
|
|
339
|
+
this.pglite = pg;
|
|
340
|
+
this.loadingState = 'loaded';
|
|
341
|
+
const waitMs = performance.now() - waitStart;
|
|
342
|
+
if (waitMs > 1) {
|
|
343
|
+
console.log(`[BackgroundPGLiteManager] Query waited ${waitMs.toFixed(2)}ms for WASM to finish loading`);
|
|
344
|
+
}
|
|
345
|
+
return pg;
|
|
346
|
+
}
|
|
347
|
+
// Using custom factory or non-hoisted
|
|
348
|
+
if (this.loadPromise) {
|
|
349
|
+
const waitStart = performance.now();
|
|
350
|
+
const pg = await this.loadPromise;
|
|
351
|
+
const waitMs = performance.now() - waitStart;
|
|
352
|
+
if (waitMs > 1) {
|
|
353
|
+
console.log(`[BackgroundPGLiteManager] Query waited ${waitMs.toFixed(2)}ms for WASM to finish loading`);
|
|
354
|
+
}
|
|
355
|
+
return pg;
|
|
356
|
+
}
|
|
357
|
+
throw new Error('PGLite not initialized - call initialize() first');
|
|
358
|
+
}
|
|
359
|
+
/**
|
|
360
|
+
* Execute a query.
|
|
361
|
+
*
|
|
362
|
+
* If WASM is not loaded yet, this will wait for loading to complete.
|
|
363
|
+
* If WASM is already loaded, this returns immediately after query execution.
|
|
364
|
+
*/
|
|
365
|
+
async query(sql, params) {
|
|
366
|
+
if (!this.initialized) {
|
|
367
|
+
throw new Error('Manager not initialized - call initialize() first');
|
|
368
|
+
}
|
|
369
|
+
if (this.loadingState === 'error') {
|
|
370
|
+
throw this.loadError ?? new Error('WASM loading failed');
|
|
371
|
+
}
|
|
372
|
+
// Track first query timing
|
|
373
|
+
if (this.metrics.firstQueryAt === null) {
|
|
374
|
+
this.metrics.firstQueryAt = Date.now();
|
|
375
|
+
}
|
|
376
|
+
const pg = await this.getPglite();
|
|
377
|
+
return pg.query(sql, params);
|
|
378
|
+
}
|
|
379
|
+
/**
|
|
380
|
+
* Execute a SQL statement without returning rows.
|
|
381
|
+
*/
|
|
382
|
+
async exec(sql) {
|
|
383
|
+
const pg = await this.getPglite();
|
|
384
|
+
if (pg.exec) {
|
|
385
|
+
await pg.exec(sql);
|
|
386
|
+
}
|
|
387
|
+
else {
|
|
388
|
+
await pg.query(sql);
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
/**
|
|
392
|
+
* Check if the manager is initialized (not the same as WASM loaded).
|
|
393
|
+
*/
|
|
394
|
+
isInitialized() {
|
|
395
|
+
return this.initialized;
|
|
396
|
+
}
|
|
397
|
+
/**
|
|
398
|
+
* Get the PGLite instance if loaded, null otherwise.
|
|
399
|
+
* Does NOT wait for loading - use for checking readiness.
|
|
400
|
+
*/
|
|
401
|
+
getInstanceOrNull() {
|
|
402
|
+
return this.pglite;
|
|
403
|
+
}
|
|
404
|
+
/**
|
|
405
|
+
* Get the PGLite instance (throws if not loaded).
|
|
406
|
+
* Use query() instead to automatically wait for loading.
|
|
407
|
+
*/
|
|
408
|
+
getInstance() {
|
|
409
|
+
if (!this.pglite) {
|
|
410
|
+
throw new Error('PGLite not loaded yet');
|
|
411
|
+
}
|
|
412
|
+
return this.pglite;
|
|
413
|
+
}
|
|
414
|
+
/**
|
|
415
|
+
* Wait for WASM to be loaded.
|
|
416
|
+
* Call this if you want to ensure WASM is ready before proceeding.
|
|
417
|
+
*/
|
|
418
|
+
async ensureWASMLoaded() {
|
|
419
|
+
await this.getPglite();
|
|
420
|
+
}
|
|
421
|
+
/**
|
|
422
|
+
* Check if PGLite is responsive.
|
|
423
|
+
*/
|
|
424
|
+
async checkLiveness() {
|
|
425
|
+
if (!this.isWASMLoaded()) {
|
|
426
|
+
return false;
|
|
427
|
+
}
|
|
428
|
+
try {
|
|
429
|
+
const result = await this.pglite.query('SELECT 1 as alive');
|
|
430
|
+
return result.rows.length > 0;
|
|
431
|
+
}
|
|
432
|
+
catch {
|
|
433
|
+
return false;
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
/**
|
|
437
|
+
* Get timing metrics for diagnostics.
|
|
438
|
+
*/
|
|
439
|
+
getMetrics() {
|
|
440
|
+
const loadDuration = this.metrics.wasmLoadStartAt && this.metrics.wasmLoadEndAt
|
|
441
|
+
? this.metrics.wasmLoadEndAt - this.metrics.wasmLoadStartAt
|
|
442
|
+
: null;
|
|
443
|
+
const initToFirstQuery = this.metrics.initializeCalledAt && this.metrics.firstQueryAt
|
|
444
|
+
? this.metrics.firstQueryAt - this.metrics.initializeCalledAt
|
|
445
|
+
: null;
|
|
446
|
+
return {
|
|
447
|
+
...this.metrics,
|
|
448
|
+
wasmLoadDurationMs: loadDuration,
|
|
449
|
+
timeFromInitToFirstQueryMs: initToFirstQuery,
|
|
450
|
+
isUsingHoistedInstance: this.usingHoistedInstance,
|
|
451
|
+
};
|
|
452
|
+
}
|
|
453
|
+
/**
|
|
454
|
+
* Get comprehensive diagnostics.
|
|
455
|
+
*/
|
|
456
|
+
getDiagnostics() {
|
|
457
|
+
return {
|
|
458
|
+
manager: {
|
|
459
|
+
initialized: this.initialized,
|
|
460
|
+
loadingState: this.loadingState,
|
|
461
|
+
hasInstance: this.pglite !== null,
|
|
462
|
+
usingHoistedInstance: this.usingHoistedInstance,
|
|
463
|
+
error: this.loadError?.message ?? null,
|
|
464
|
+
},
|
|
465
|
+
module: getBgHoistedPgliteDiagnostics(),
|
|
466
|
+
metrics: this.getMetrics(),
|
|
467
|
+
};
|
|
468
|
+
}
|
|
469
|
+
/**
|
|
470
|
+
* Close the manager.
|
|
471
|
+
* Note: Does NOT close hoisted instances (they're reused across DO reinstantiations).
|
|
472
|
+
*/
|
|
473
|
+
async close(timeoutMs = 5000) {
|
|
474
|
+
// Don't close hoisted instances
|
|
475
|
+
if (this.usingHoistedInstance) {
|
|
476
|
+
console.log(`[BackgroundPGLiteManager] Skipping close of hoisted WASM instance (will be reused)`);
|
|
477
|
+
this.pglite = null;
|
|
478
|
+
this.initialized = false;
|
|
479
|
+
return;
|
|
480
|
+
}
|
|
481
|
+
// Close non-hoisted instance
|
|
482
|
+
if (this.pglite?.close) {
|
|
483
|
+
try {
|
|
484
|
+
await Promise.race([
|
|
485
|
+
this.pglite.close(),
|
|
486
|
+
new Promise((_, reject) => setTimeout(() => reject(new Error('Close timeout')), timeoutMs)),
|
|
487
|
+
]);
|
|
488
|
+
}
|
|
489
|
+
catch (error) {
|
|
490
|
+
console.error('[BackgroundPGLiteManager] Error closing PGLite:', error);
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
this.pglite = null;
|
|
494
|
+
this.initialized = false;
|
|
495
|
+
this.loadingState = 'not_started';
|
|
496
|
+
}
|
|
497
|
+
/**
|
|
498
|
+
* Reset the manager state.
|
|
499
|
+
*/
|
|
500
|
+
reset() {
|
|
501
|
+
this.pglite = null;
|
|
502
|
+
this.initialized = false;
|
|
503
|
+
this.loadingState = 'not_started';
|
|
504
|
+
this.loadError = null;
|
|
505
|
+
this.loadPromise = null;
|
|
506
|
+
this.usingHoistedInstance = false;
|
|
507
|
+
this.metrics = {
|
|
508
|
+
initializeCalledAt: null,
|
|
509
|
+
wasmLoadStartAt: null,
|
|
510
|
+
wasmLoadEndAt: null,
|
|
511
|
+
firstQueryAt: null,
|
|
512
|
+
firstQueryWaitedMs: null,
|
|
513
|
+
};
|
|
514
|
+
}
|
|
515
|
+
/**
|
|
516
|
+
* Get the plugin manager.
|
|
517
|
+
*/
|
|
518
|
+
getPluginManager() {
|
|
519
|
+
return this.pluginManager;
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
/**
|
|
523
|
+
* Factory function to create a BackgroundPGLiteManager.
|
|
524
|
+
*/
|
|
525
|
+
export function createBackgroundPGLiteManager(config = {}) {
|
|
526
|
+
return new BackgroundPGLiteManager(config);
|
|
527
|
+
}
|
|
528
|
+
//# sourceMappingURL=background-pglite-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"background-pglite-manager.js","sourceRoot":"","sources":["../../src/worker/background-pglite-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,10 +4,45 @@
|
|
|
4
4
|
* Handles PGLite instance creation, initialization, and lifecycle.
|
|
5
5
|
* Extracted from PostgresDO to reduce class size and separate concerns.
|
|
6
6
|
*
|
|
7
|
+
* ## WASM Hoisting Pattern
|
|
8
|
+
*
|
|
9
|
+
* This module implements WASM hoisting to reduce "warm start" time from ~1200ms to ~30ms.
|
|
10
|
+
*
|
|
11
|
+
* The problem: In Cloudflare Workers, when a DO class is recreated (but the isolate stays alive),
|
|
12
|
+
* the PGLite WASM needs to be reloaded. WASM initialization takes ~1200ms.
|
|
13
|
+
*
|
|
14
|
+
* The solution: Cache the PGLite instance at module level. The module loads once per isolate,
|
|
15
|
+
* so the PGLite instance survives DO class reinstantiation. This means:
|
|
16
|
+
* - Cold start: ~1200ms (full WASM initialization)
|
|
17
|
+
* - Warm start (isolate alive, DO recreated): ~30ms (reuse cached WASM)
|
|
18
|
+
*
|
|
7
19
|
* @module worker/do-pglite-manager
|
|
8
20
|
*/
|
|
9
21
|
import type { PostgresConfig } from './types';
|
|
10
22
|
import { PluginManager, type PluginQueryExecutor } from './plugin-manager';
|
|
23
|
+
/**
|
|
24
|
+
* Check if the hoisted PGLite instance exists.
|
|
25
|
+
* Useful for diagnostics and testing.
|
|
26
|
+
*/
|
|
27
|
+
export declare function hasHoistedPglite(): boolean;
|
|
28
|
+
/**
|
|
29
|
+
* Get diagnostics about the hoisted WASM state.
|
|
30
|
+
* Useful for debugging warm start performance.
|
|
31
|
+
*/
|
|
32
|
+
export declare function getHoistedPgliteDiagnostics(): {
|
|
33
|
+
hasInstance: boolean;
|
|
34
|
+
hasPendingPromise: boolean;
|
|
35
|
+
moduleInstanceId: string;
|
|
36
|
+
moduleLoadTime: number;
|
|
37
|
+
moduleAgeMs: number;
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* Reset the hoisted PGLite instance.
|
|
41
|
+
* WARNING: This should only be used in tests. In production, the hoisted
|
|
42
|
+
* instance should persist for the lifetime of the isolate.
|
|
43
|
+
* @internal
|
|
44
|
+
*/
|
|
45
|
+
export declare function resetHoistedPglite(): void;
|
|
11
46
|
/**
|
|
12
47
|
* PGlite-like interface
|
|
13
48
|
* This interface is implemented by WorkersPGLite for Cloudflare Workers compatibility
|
|
@@ -39,6 +74,14 @@ export interface PGLiteManagerConfig {
|
|
|
39
74
|
plugins?: PostgresConfig['plugins'];
|
|
40
75
|
/** Custom PGLite factory for testing */
|
|
41
76
|
createPGLite?: () => Promise<PGliteLike>;
|
|
77
|
+
/**
|
|
78
|
+
* Disable WASM hoisting optimization.
|
|
79
|
+
* When false (default), the PGLite WASM instance is cached at module level
|
|
80
|
+
* and survives DO class reinstantiation for optimal warm start performance.
|
|
81
|
+
* Set to true to create a new WASM instance for each PGLiteManager.
|
|
82
|
+
* @default false
|
|
83
|
+
*/
|
|
84
|
+
disableHoisting?: boolean;
|
|
42
85
|
}
|
|
43
86
|
/**
|
|
44
87
|
* PGLiteManager handles PGLite instance lifecycle.
|
|
@@ -72,6 +115,8 @@ export declare class PGLiteManager {
|
|
|
72
115
|
private initialized;
|
|
73
116
|
private config;
|
|
74
117
|
private pluginManager;
|
|
118
|
+
/** Track whether this manager is using the hoisted instance */
|
|
119
|
+
private usingHoistedInstance;
|
|
75
120
|
constructor(config?: PGLiteManagerConfig);
|
|
76
121
|
/**
|
|
77
122
|
* Check if PGLite is initialized
|
|
@@ -104,6 +149,10 @@ export declare class PGLiteManager {
|
|
|
104
149
|
/**
|
|
105
150
|
* Create the PGLite instance
|
|
106
151
|
* Can be overridden for testing
|
|
152
|
+
*
|
|
153
|
+
* By default, uses the module-level hoisted PGLite instance for optimal
|
|
154
|
+
* warm start performance. The hoisted instance survives DO class
|
|
155
|
+
* reinstantiation within the same isolate.
|
|
107
156
|
*/
|
|
108
157
|
protected createPGLiteInstance(): Promise<PGliteLike>;
|
|
109
158
|
/**
|
|
@@ -122,6 +171,15 @@ export declare class PGLiteManager {
|
|
|
122
171
|
/**
|
|
123
172
|
* Close PGLite instance
|
|
124
173
|
*
|
|
174
|
+
* Note: When using the hoisted WASM instance (default), this method does NOT
|
|
175
|
+
* close the underlying PGLite instance, as it's shared across DO instances.
|
|
176
|
+
* It only clears the local reference. The hoisted instance persists for the
|
|
177
|
+
* lifetime of the isolate for optimal warm start performance.
|
|
178
|
+
*
|
|
179
|
+
* To actually close the hoisted instance, use resetHoistedPglite() followed
|
|
180
|
+
* by close() on the next manager that initializes. This should only be done
|
|
181
|
+
* in tests or when the isolate is shutting down.
|
|
182
|
+
*
|
|
125
183
|
* @param timeoutMs - Maximum time to wait for close (default: 5000ms)
|
|
126
184
|
*/
|
|
127
185
|
close(timeoutMs?: number): Promise<void>;
|
|
@@ -129,6 +187,25 @@ export declare class PGLiteManager {
|
|
|
129
187
|
* Reset manager state (for testing or hibernation recovery)
|
|
130
188
|
*/
|
|
131
189
|
reset(): void;
|
|
190
|
+
/**
|
|
191
|
+
* Check if this manager is using the hoisted WASM instance
|
|
192
|
+
*/
|
|
193
|
+
isUsingHoistedInstance(): boolean;
|
|
194
|
+
/**
|
|
195
|
+
* Get diagnostics about WASM hoisting and initialization state.
|
|
196
|
+
* Useful for debugging warm start performance.
|
|
197
|
+
*/
|
|
198
|
+
getDiagnostics(): {
|
|
199
|
+
initialized: boolean;
|
|
200
|
+
usingHoistedInstance: boolean;
|
|
201
|
+
hoisted: {
|
|
202
|
+
hasInstance: boolean;
|
|
203
|
+
hasPendingPromise: boolean;
|
|
204
|
+
moduleInstanceId: string;
|
|
205
|
+
moduleLoadTime: number;
|
|
206
|
+
moduleAgeMs: number;
|
|
207
|
+
};
|
|
208
|
+
};
|
|
132
209
|
}
|
|
133
210
|
/**
|
|
134
211
|
* Create a PGLite manager instance
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"do-pglite-manager.d.ts","sourceRoot":"","sources":["../../src/worker/do-pglite-manager.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"do-pglite-manager.d.ts","sourceRoot":"","sources":["../../src/worker/do-pglite-manager.ts"],"names":[],"mappings":"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"}
|