@b9g/platform 0.1.12 → 0.1.14-beta.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/package.json CHANGED
@@ -1,28 +1,34 @@
1
1
  {
2
2
  "name": "@b9g/platform",
3
- "version": "0.1.12",
4
- "description": "ServiceWorker-first universal deployment platform. Write ServiceWorker apps once, deploy anywhere (Node/Bun/Cloudflare). Registry-based multi-app orchestration.",
3
+ "version": "0.1.14-beta.0",
4
+ "description": "The portable meta-framework built on web standards.",
5
5
  "keywords": [
6
- "serviceworker",
6
+ "service-worker",
7
7
  "universal",
8
8
  "deployment",
9
9
  "platform",
10
- "registry",
11
10
  "node",
12
11
  "bun",
13
12
  "cloudflare",
14
13
  "workers",
14
+ "cache",
15
+ "framework",
16
+ "meta-framework",
17
+ "esbuild",
15
18
  "shovel"
16
19
  ],
17
20
  "dependencies": {
18
- "@b9g/async-context": "^0.1.4",
19
- "@b9g/cache": "^0.1.5",
20
- "@b9g/filesystem": "^0.1.7",
21
+ "@b9g/async-context": "^0.2.0-beta.0",
22
+ "@b9g/cache": "^0.2.0-beta.0",
23
+ "@b9g/filesystem": "^0.1.8",
24
+ "@b9g/zen": "^0.1.6",
21
25
  "@logtape/logtape": "^1.2.0"
22
26
  },
23
27
  "devDependencies": {
24
- "@b9g/libuild": "^0.1.18",
25
- "bun-types": "latest"
28
+ "@b9g/libuild": "^0.1.20",
29
+ "@b9g/node-webworker": "^0.2.0-beta.1",
30
+ "@b9g/platform-bun": "^0.1.12-beta.0",
31
+ "@b9g/platform-node": "^0.1.14-beta.0"
26
32
  },
27
33
  "peerDependencies": {
28
34
  "@logtape/file": "^1.0.0",
@@ -65,14 +71,6 @@
65
71
  "types": "./src/runtime.d.ts",
66
72
  "import": "./src/runtime.js"
67
73
  },
68
- "./worker": {
69
- "types": "./src/worker.d.ts",
70
- "import": "./src/worker.js"
71
- },
72
- "./worker.js": {
73
- "types": "./src/worker.d.ts",
74
- "import": "./src/worker.js"
75
- },
76
74
  "./index": {
77
75
  "types": "./src/index.d.ts",
78
76
  "import": "./src/index.js"
@@ -80,6 +78,16 @@
80
78
  "./index.js": {
81
79
  "types": "./src/index.d.ts",
82
80
  "import": "./src/index.js"
81
+ },
82
+ "./globals.d.ts": "./src/globals.d.ts",
83
+ "./shovel-config.d.ts": "./src/shovel-config.d.ts",
84
+ "./config": {
85
+ "types": "./src/config.d.ts",
86
+ "import": "./src/config.js"
87
+ },
88
+ "./config.js": {
89
+ "types": "./src/config.d.ts",
90
+ "import": "./src/config.js"
83
91
  }
84
92
  }
85
93
  }
@@ -0,0 +1,24 @@
1
+ /// <reference path="./globals.d.ts" />
2
+ /// <reference path="./shovel-config.d.ts" />
3
+ /**
4
+ * Config Validation Utilities
5
+ *
6
+ * Helpers for validating config objects at runtime.
7
+ */
8
+ /**
9
+ * Error thrown when config validation fails
10
+ */
11
+ export declare class ConfigValidationError extends Error {
12
+ readonly path: string;
13
+ readonly issue: "undefined" | "NaN";
14
+ constructor(path: string, issue: "undefined" | "NaN");
15
+ }
16
+ /**
17
+ * Validate that a config object has no undefined or NaN values.
18
+ * Call this at runtime to fail fast on missing env vars.
19
+ *
20
+ * @param config - The config object to validate
21
+ * @param path - Current path for error messages (used in recursion)
22
+ * @throws ConfigValidationError if any value is undefined or NaN
23
+ */
24
+ export declare function validateConfig(config: Record<string, unknown>, path?: string): void;
package/src/config.js ADDED
@@ -0,0 +1,29 @@
1
+ /// <reference types="./config.d.ts" />
2
+ // src/config.ts
3
+ var ConfigValidationError = class extends Error {
4
+ constructor(path, issue) {
5
+ const message = issue === "undefined" ? `Config "${path}" is undefined. Ensure required environment variables are set.` : `Config "${path}" is NaN. Ensure the environment variable contains a valid number.`;
6
+ super(message);
7
+ this.path = path;
8
+ this.issue = issue;
9
+ this.name = "ConfigValidationError";
10
+ }
11
+ };
12
+ function validateConfig(config, path = "") {
13
+ for (const [key, value] of Object.entries(config)) {
14
+ const fullPath = path ? `${path}.${key}` : key;
15
+ if (value === void 0) {
16
+ throw new ConfigValidationError(fullPath, "undefined");
17
+ }
18
+ if (typeof value === "number" && Number.isNaN(value)) {
19
+ throw new ConfigValidationError(fullPath, "NaN");
20
+ }
21
+ if (value !== null && typeof value === "object" && !Array.isArray(value)) {
22
+ validateConfig(value, fullPath);
23
+ }
24
+ }
25
+ }
26
+ export {
27
+ ConfigValidationError,
28
+ validateConfig
29
+ };
@@ -0,0 +1,119 @@
1
+ /// <reference lib="webworker" />
2
+
3
+ /**
4
+ * Global type declarations for Shovel ServiceWorker environment.
5
+ *
6
+ * These types augment the global scope with Shovel-specific APIs
7
+ * that are installed by ServiceWorkerGlobals.
8
+ *
9
+ * Usage: Include this file in your tsconfig.json "include" array
10
+ * or reference it with /// <reference types="@b9g/platform/globals" />
11
+ */
12
+
13
+ import type {Logger} from "@logtape/logtape";
14
+ import type {DirectoryStorage} from "@b9g/filesystem";
15
+
16
+ declare global {
17
+ /**
18
+ * Logger storage API for accessing named loggers.
19
+ * @example const logger = self.loggers.get(["app"]);
20
+ * @example const dbLogger = self.loggers.get(["app", "db"]);
21
+ */
22
+ interface LoggerStorage {
23
+ get(categories: string[]): Logger;
24
+ }
25
+
26
+ /**
27
+ * Upgrade event passed to onUpgrade callback during database.open().
28
+ */
29
+ interface DatabaseUpgradeEvent {
30
+ /** The database being upgraded */
31
+ db: unknown;
32
+ /** Previous database version (0 if new) */
33
+ oldVersion: number;
34
+ /** Target version being opened */
35
+ newVersion: number;
36
+ /** Register a promise that must complete before open() resolves */
37
+ waitUntil(promise: Promise<unknown>): void;
38
+ }
39
+
40
+ /**
41
+ * Database storage API for accessing named database instances.
42
+ *
43
+ * @example
44
+ * // In activate - open with migrations
45
+ * await self.databases.open("main", 2, (e) => {
46
+ * e.waitUntil(runMigrations(e));
47
+ * });
48
+ *
49
+ * // In fetch - get opened database (sync)
50
+ * const db = self.databases.get("main");
51
+ */
52
+ interface DatabaseStorage {
53
+ /** Open a database at a specific version, running migrations if needed */
54
+ open(
55
+ name: string,
56
+ version: number,
57
+ onUpgrade?: (event: DatabaseUpgradeEvent) => void,
58
+ ): Promise<unknown>;
59
+ /** Get an already-opened database (throws if not opened) */
60
+ get(name: string): unknown;
61
+ /** Close a specific database */
62
+ close(name: string): Promise<void>;
63
+ /** Close all databases */
64
+ closeAll(): Promise<void>;
65
+ }
66
+
67
+ /**
68
+ * Directory storage API for accessing named directories.
69
+ * @example const uploads = await directories.open("uploads");
70
+ */
71
+ var directories: DirectoryStorage;
72
+
73
+ /**
74
+ * Logger storage API for accessing named loggers.
75
+ * @example const logger = self.loggers.get(["app"]);
76
+ * @example const dbLogger = self.loggers.get(["app", "db"]);
77
+ */
78
+ var loggers: LoggerStorage;
79
+
80
+ /**
81
+ * Database storage API for accessing named database instances.
82
+ * @example const db = self.databases.get("main");
83
+ */
84
+ var databases: DatabaseStorage;
85
+
86
+ /**
87
+ * Environment variables available via import.meta.env
88
+ * Works across all platforms (Node/Bun via esbuild shim, Cloudflare natively)
89
+ */
90
+ interface ImportMetaEnv {
91
+ readonly [key: string]: string | undefined;
92
+ }
93
+
94
+ interface ImportMeta {
95
+ readonly env: ImportMetaEnv;
96
+ }
97
+
98
+ /**
99
+ * Augment WorkerGlobalScopeEventMap with ServiceWorker events.
100
+ *
101
+ * TypeScript's lib.webworker.d.ts declares `self` as `WorkerGlobalScope`, not
102
+ * `ServiceWorkerGlobalScope`. This means `self.addEventListener("fetch", ...)`
103
+ * doesn't know about FetchEvent. See: https://github.com/microsoft/TypeScript/issues/14877
104
+ *
105
+ * Rather than trying to redeclare `self` (which causes conflicts), we augment
106
+ * the base WorkerGlobalScopeEventMap to include ServiceWorker-specific events.
107
+ * This allows `self.addEventListener("fetch", (event) => ...)` to correctly
108
+ * infer `event` as `FetchEvent`.
109
+ */
110
+ interface WorkerGlobalScopeEventMap {
111
+ fetch: FetchEvent;
112
+ install: ExtendableEvent;
113
+ activate: ExtendableEvent;
114
+ message: ExtendableMessageEvent;
115
+ messageerror: MessageEvent;
116
+ }
117
+ }
118
+
119
+ export {};
package/src/index.d.ts CHANGED
@@ -1,3 +1,5 @@
1
+ /// <reference path="./globals.d.ts" />
2
+ /// <reference path="./shovel-config.d.ts" />
1
3
  /**
2
4
  * @b9g/platform - Platform interface for ServiceWorker entrypoint loading
3
5
  *
@@ -6,11 +8,11 @@
6
8
  *
7
9
  * This module contains:
8
10
  * - Platform interface and base classes
9
- * - SingleThreadedRuntime for main-thread execution
10
11
  * - ServiceWorkerPool for multi-worker execution
11
12
  */
12
13
  import type { DirectoryStorage } from "@b9g/filesystem";
13
14
  import { CustomLoggerStorage, type LoggerStorage } from "./runtime.js";
15
+ export { validateConfig, ConfigValidationError } from "./config.js";
14
16
  /**
15
17
  * Platform configuration
16
18
  * Extended by platform-specific implementations (NodePlatformOptions, etc.)
@@ -25,13 +27,8 @@ export interface ServerOptions {
25
27
  port?: number;
26
28
  /** Host to bind to */
27
29
  host?: string;
28
- /** Development mode settings */
29
- development?: {
30
- /** Source maps support */
31
- sourceMaps?: boolean;
32
- /** Verbose logging */
33
- verbose?: boolean;
34
- };
30
+ /** Enable SO_REUSEPORT for multi-worker deployments (Bun only) */
31
+ reusePort?: boolean;
35
32
  }
36
33
  /**
37
34
  * Request handler function (Web Fetch API compatible)
@@ -84,15 +81,18 @@ export interface ServiceWorkerInstance {
84
81
  dispose(): Promise<void>;
85
82
  }
86
83
  /**
87
- * Options for getEntryWrapper()
88
- * Reserved for future platform-specific options.
84
+ * Production entry points returned by getProductionEntryPoints().
85
+ * Each key is the output filename (without .js), value is the code.
86
+ *
87
+ * Examples:
88
+ * - Cloudflare: { "worker": "<code>" } - single worker file
89
+ * - Node/Bun: { "index": "<supervisor>", "worker": "<worker>" } - two files
89
90
  */
90
- export interface EntryWrapperOptions {
91
- }
91
+ export type ProductionEntryPoints = Record<string, string>;
92
92
  /**
93
- * Esbuild configuration subset that platforms can customize
93
+ * ESBuild configuration subset that platforms can customize
94
94
  */
95
- export interface PlatformEsbuildConfig {
95
+ export interface PlatformESBuildConfig {
96
96
  /** Target platform: "node" or "browser" */
97
97
  platform?: "node" | "browser" | "neutral";
98
98
  /** Export conditions for package.json resolution */
@@ -101,16 +101,42 @@ export interface PlatformEsbuildConfig {
101
101
  external?: string[];
102
102
  /** Compile-time defines */
103
103
  define?: Record<string, string>;
104
- /**
105
- * Whether the entry wrapper imports user code inline (bundled together)
106
- * or references it as a separate file (loaded at runtime).
107
- *
108
- * - true: User code is imported inline (e.g., Cloudflare: `import "user-entry"`)
109
- * - false: User code is loaded separately (e.g., Node/Bun: `loadServiceWorker("./server.js")`)
110
- *
111
- * Default: false (separate build)
112
- */
113
- bundlesUserCodeInline?: boolean;
104
+ }
105
+ /**
106
+ * Default resource configuration for a named resource (cache, directory, etc.)
107
+ * Used by platforms to define built-in defaults that get merged with user config.
108
+ */
109
+ export interface ResourceDefault {
110
+ /** Module path to import (e.g., "@b9g/cache/memory") */
111
+ module: string;
112
+ /** Named export to use (defaults to "default") */
113
+ export?: string;
114
+ /** Additional options (e.g., path for directories) */
115
+ [key: string]: unknown;
116
+ }
117
+ /**
118
+ * Platform-specific defaults for config generation.
119
+ * These are merged with user config at build time to provide
120
+ * sensible defaults for each platform.
121
+ */
122
+ export interface PlatformDefaults {
123
+ /** Default directory configurations (server, public, tmp, etc.) */
124
+ directories?: Record<string, ResourceDefault>;
125
+ /** Default cache configuration (e.g., memory cache) */
126
+ caches?: Record<string, ResourceDefault>;
127
+ }
128
+ /**
129
+ * Extended ServiceWorkerContainer with internal methods for hot reload
130
+ */
131
+ export interface ShovelServiceWorkerContainer extends ServiceWorkerContainer {
132
+ /** Internal: Get the worker pool for request handling */
133
+ readonly pool?: {
134
+ handleRequest(request: Request): Promise<Response>;
135
+ };
136
+ /** Internal: Terminate all workers */
137
+ terminate(): Promise<void>;
138
+ /** Internal: Reload workers (for hot reload) */
139
+ reloadWorkers(entrypoint: string): Promise<void>;
114
140
  }
115
141
  /**
116
142
  * Platform interface - ServiceWorker entrypoint loader for JavaScript runtimes
@@ -123,41 +149,77 @@ export interface Platform {
123
149
  */
124
150
  readonly name: string;
125
151
  /**
126
- * Load and run a ServiceWorker-style entrypoint
127
- * This is where all the platform-specific complexity lives
152
+ * ServiceWorkerContainer for managing registrations (Node/Bun only)
153
+ * Similar to navigator.serviceWorker in browsers
128
154
  */
129
- loadServiceWorker(entrypoint: string, options?: ServiceWorkerOptions): Promise<ServiceWorkerInstance>;
155
+ readonly serviceWorker: ShovelServiceWorkerContainer;
130
156
  /**
131
- * SUPPORTING UTILITY - Create cache storage
132
- * Returns empty CacheStorage - applications create caches on-demand via caches.open()
157
+ * Start HTTP server and route requests to ServiceWorker (Node/Bun only)
158
+ * Must call serviceWorker.register() first
133
159
  */
134
- createCaches(): Promise<CacheStorage>;
160
+ listen(): Promise<Server>;
161
+ /**
162
+ * Close server and terminate workers (Node/Bun only)
163
+ */
164
+ close(): Promise<void>;
135
165
  /**
136
166
  * SUPPORTING UTILITY - Create server instance for this platform
137
167
  */
138
168
  createServer(handler: Handler, options?: ServerOptions): Server;
139
169
  /**
140
- * BUILD SUPPORT - Get virtual entry wrapper template for user code
170
+ * BUILD SUPPORT - Get production entry points for bundling
171
+ *
172
+ * Returns a map of output filenames to their source code.
173
+ * The build system creates one output file per entry point.
141
174
  *
142
- * Returns a JavaScript/TypeScript string that:
143
- * 1. Initializes platform-specific runtime (polyfills, globals)
144
- * 2. Imports the user's entrypoint
145
- * 3. Exports any required handlers (e.g., ES module export for Cloudflare)
175
+ * Platform determines the structure:
176
+ * - Cloudflare: { "worker": "<code>" } - single worker file
177
+ * - Node/Bun: { "index": "<supervisor>", "worker": "<runtime + user code>" }
146
178
  *
147
- * The CLI uses this to create a virtual entry point for bundling.
148
- * Every platform must provide a wrapper - there is no "raw user code" mode.
179
+ * The user's entrypoint code is statically imported into the appropriate file.
149
180
  *
150
- * @param entryPath - Absolute path to user's entrypoint file
151
- * @param options - Additional options
181
+ * @param userEntryPath - Path to user's entrypoint (will be imported)
152
182
  */
153
- getEntryWrapper(entryPath: string, options?: EntryWrapperOptions): string;
183
+ getProductionEntryPoints(userEntryPath: string): ProductionEntryPoints;
154
184
  /**
155
185
  * BUILD SUPPORT - Get platform-specific esbuild configuration
156
186
  *
157
187
  * Returns partial esbuild config that the CLI merges with common settings.
158
188
  * Includes platform target, conditions, externals, and defines.
159
189
  */
160
- getEsbuildConfig(): PlatformEsbuildConfig;
190
+ getESBuildConfig(): PlatformESBuildConfig;
191
+ /**
192
+ * BUILD SUPPORT - Get platform-specific defaults for config generation
193
+ *
194
+ * Returns defaults for directories, caches, etc. that get merged with
195
+ * user config at build time. These are used by generateConfigModule()
196
+ * to create static imports for the default implementations.
197
+ */
198
+ getDefaults(): PlatformDefaults;
199
+ /**
200
+ * Create cache storage for this platform
201
+ * Uses platform-specific defaults, overridable via shovel.json config
202
+ */
203
+ createCaches(): Promise<CacheStorage>;
204
+ /**
205
+ * Create directory storage for this platform
206
+ * Uses platform-specific defaults, overridable via shovel.json config
207
+ */
208
+ createDirectories(): Promise<DirectoryStorage>;
209
+ /**
210
+ * Create logger storage for this platform
211
+ * Uses platform-specific defaults, overridable via shovel.json config
212
+ */
213
+ createLoggers(): Promise<LoggerStorage>;
214
+ /**
215
+ * Dispose of platform resources (worker pools, connections, etc.)
216
+ */
217
+ dispose(): Promise<void>;
218
+ /**
219
+ * HOT RELOAD - Reload workers with a new entrypoint (development only)
220
+ * Optional - only Node and Bun platforms implement this
221
+ */
222
+ reloadWorkers?(entrypoint: string): Promise<void>;
161
223
  }
162
224
  /**
163
225
  * Platform registry - internal implementation
@@ -206,7 +268,7 @@ export declare function resolvePlatform(options: {
206
268
  /**
207
269
  * Create platform instance based on name
208
270
  */
209
- export declare function createPlatform(platformName: string, options?: any): Promise<any>;
271
+ export declare function createPlatform(platformName: string, options?: any): Promise<Platform>;
210
272
  /**
211
273
  * Base platform class with shared adapter loading logic
212
274
  * Platform implementations extend this and provide platform-specific methods
@@ -215,24 +277,57 @@ export declare abstract class BasePlatform implements Platform {
215
277
  config: PlatformConfig;
216
278
  constructor(config?: PlatformConfig);
217
279
  abstract readonly name: string;
218
- abstract loadServiceWorker(entrypoint: string, options?: any): Promise<any>;
280
+ abstract readonly serviceWorker: ShovelServiceWorkerContainer;
281
+ abstract listen(): Promise<Server>;
282
+ abstract close(): Promise<void>;
219
283
  abstract createServer(handler: any, options?: any): any;
220
284
  /**
221
- * Create cache storage
222
- * Returns empty CacheStorage - applications create caches on-demand via caches.open()
285
+ * Get production entry points for bundling
286
+ * Subclasses must override to provide platform-specific entry points
223
287
  */
224
- createCaches(): Promise<CacheStorage>;
225
- /**
226
- * Get virtual entry wrapper template for user code
227
- * Subclasses must override to provide platform-specific wrappers
228
- */
229
- abstract getEntryWrapper(entryPath: string, options?: EntryWrapperOptions): string;
288
+ abstract getProductionEntryPoints(userEntryPath: string): ProductionEntryPoints;
230
289
  /**
231
290
  * Get platform-specific esbuild configuration
232
291
  * Subclasses should override to provide platform-specific config
233
292
  */
234
- abstract getEsbuildConfig(): PlatformEsbuildConfig;
293
+ abstract getESBuildConfig(): PlatformESBuildConfig;
294
+ /**
295
+ * Get platform-specific defaults for config generation
296
+ * Subclasses should override to provide platform-specific defaults
297
+ */
298
+ abstract getDefaults(): PlatformDefaults;
299
+ /**
300
+ * Create cache storage for this platform
301
+ * Subclasses must override to provide platform-specific implementation
302
+ */
303
+ abstract createCaches(): Promise<CacheStorage>;
304
+ /**
305
+ * Create directory storage for this platform
306
+ * Subclasses must override to provide platform-specific implementation
307
+ */
308
+ abstract createDirectories(): Promise<DirectoryStorage>;
309
+ /**
310
+ * Create logger storage for this platform
311
+ * Subclasses must override to provide platform-specific implementation
312
+ */
313
+ abstract createLoggers(): Promise<LoggerStorage>;
314
+ /**
315
+ * Dispose of platform resources
316
+ * Subclasses should override to clean up worker pools, connections, etc.
317
+ */
318
+ dispose(): Promise<void>;
235
319
  }
320
+ /**
321
+ * Merge platform defaults with user config
322
+ *
323
+ * Deep merges each entry so user can override specific options without
324
+ * losing the platform's default implementation class.
325
+ *
326
+ * @param defaults - Platform's runtime defaults (with actual class refs)
327
+ * @param userConfig - User's config from shovel.json (may be partial)
328
+ * @returns Merged config with all entries
329
+ */
330
+ export declare function mergeConfigWithDefaults(defaults: Record<string, Record<string, unknown>>, userConfig: Record<string, Record<string, unknown>> | undefined): Record<string, Record<string, unknown>>;
236
331
  /**
237
332
  * Global platform registry
238
333
  */
@@ -266,50 +361,6 @@ export interface ServiceWorkerRuntime {
266
361
  readonly workerCount: number;
267
362
  readonly ready: boolean;
268
363
  }
269
- export interface SingleThreadedRuntimeOptions {
270
- /** Cache storage for the runtime */
271
- caches: CacheStorage;
272
- /** Directory storage for the runtime */
273
- directories: DirectoryStorage;
274
- /** Logger storage for the runtime */
275
- loggers: LoggerStorage;
276
- }
277
- /**
278
- * Single-threaded ServiceWorker runtime
279
- *
280
- * Runs ServiceWorker code directly in the main thread.
281
- * Implements ServiceWorkerRuntime interface for interchangeability with ServiceWorkerPool.
282
- */
283
- export declare class SingleThreadedRuntime implements ServiceWorkerRuntime {
284
- #private;
285
- constructor(options: SingleThreadedRuntimeOptions);
286
- /**
287
- * Initialize the runtime (install ServiceWorker globals)
288
- */
289
- init(): Promise<void>;
290
- /**
291
- * Load (or reload) a ServiceWorker entrypoint
292
- * @param entrypoint - Path to the entrypoint file (content-hashed filename)
293
- */
294
- load(entrypoint: string): Promise<void>;
295
- /**
296
- * Handle an HTTP request
297
- * This is the key method - direct call, no postMessage!
298
- */
299
- handleRequest(request: Request): Promise<Response>;
300
- /**
301
- * Graceful shutdown
302
- */
303
- terminate(): Promise<void>;
304
- /**
305
- * Get the number of workers (always 1 for single-threaded)
306
- */
307
- get workerCount(): number;
308
- /**
309
- * Check if ready to handle requests
310
- */
311
- get ready(): boolean;
312
- }
313
364
  /**
314
365
  * Worker pool options
315
366
  */
@@ -320,6 +371,8 @@ export interface WorkerPoolOptions {
320
371
  requestTimeout?: number;
321
372
  /** Working directory for file resolution */
322
373
  cwd?: string;
374
+ /** Custom worker factory (if not provided, uses createWebWorker) */
375
+ createWorker?: (entrypoint: string) => Worker | Promise<Worker>;
323
376
  }
324
377
  export interface WorkerMessage {
325
378
  type: string;
@@ -345,13 +398,8 @@ export interface WorkerResponse extends WorkerMessage {
345
398
  };
346
399
  requestID: number;
347
400
  }
348
- export interface WorkerLoadMessage extends WorkerMessage {
349
- type: "load";
350
- entrypoint: string;
351
- }
352
401
  export interface WorkerReadyMessage extends WorkerMessage {
353
- type: "ready" | "worker-ready";
354
- entrypoint?: string;
402
+ type: "ready";
355
403
  }
356
404
  export interface WorkerErrorMessage extends WorkerMessage {
357
405
  type: "error";
@@ -359,21 +407,21 @@ export interface WorkerErrorMessage extends WorkerMessage {
359
407
  stack?: string;
360
408
  requestID?: number;
361
409
  }
362
- export interface WorkerInitMessage extends WorkerMessage {
363
- type: "init";
364
- config: any;
365
- baseDir: string;
366
- }
367
- export interface WorkerInitializedMessage extends WorkerMessage {
368
- type: "initialized";
369
- }
370
410
  /**
371
411
  * ServiceWorkerPool - manages a pool of ServiceWorker instances
372
- * Handles HTTP request/response routing, cache coordination, and hot reloading
412
+ *
413
+ * With the unified build model, workers are self-contained bundles that:
414
+ * 1. Initialize their own runtime (via initWorkerRuntime)
415
+ * 2. Import user code
416
+ * 3. Run lifecycle events
417
+ * 4. Start message loop (via startWorkerMessageLoop)
418
+ *
419
+ * Hot reload is achieved by terminating old workers and creating new ones
420
+ * with the new bundle path.
373
421
  */
374
422
  export declare class ServiceWorkerPool {
375
423
  #private;
376
- constructor(options?: WorkerPoolOptions, appEntrypoint?: string, cacheStorage?: CacheStorage, config?: any);
424
+ constructor(options: WorkerPoolOptions, appEntrypoint: string, cacheStorage?: CacheStorage);
377
425
  /**
378
426
  * Initialize workers (must be called after construction)
379
427
  */
@@ -383,8 +431,12 @@ export declare class ServiceWorkerPool {
383
431
  */
384
432
  handleRequest(request: Request): Promise<Response>;
385
433
  /**
386
- * Reload ServiceWorker with new entrypoint (hot reload)
387
- * The entrypoint path contains a content hash for cache busting
434
+ * Reload workers with new entrypoint (hot reload)
435
+ *
436
+ * With unified builds, hot reload means:
437
+ * 1. Gracefully shutdown existing workers (close databases, etc.)
438
+ * 2. Terminate workers after resources are closed
439
+ * 3. Create new workers with the new bundle
388
440
  */
389
441
  reloadWorkers(entrypoint: string): Promise<void>;
390
442
  /**
@@ -402,3 +454,4 @@ export declare class ServiceWorkerPool {
402
454
  }
403
455
  export { CustomLoggerStorage, type LoggerStorage };
404
456
  export type { LoggerFactory } from "./runtime.js";
457
+ export { CustomDatabaseStorage, createDatabaseFactory, type DatabaseStorage, type DatabaseConfig, type DatabaseFactory, type DatabaseUpgradeEvent, } from "./runtime.js";