@b9g/platform-bun 0.1.15 → 0.1.17

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 CHANGED
@@ -1,83 +1,124 @@
1
1
  # @b9g/platform-bun
2
2
 
3
- Bun platform adapter for Shovel. Runs ServiceWorker applications on Bun with native HTTP server integration and fast hot reloading.
3
+ Bun platform adapter for Shovel. Runs ServiceWorker applications on [Bun](https://bun.sh) with native HTTP server, WebSocket support, and OS-level load balancing via `reusePort`.
4
4
 
5
5
  ## Features
6
6
 
7
- - Bun HTTP server integration
8
- - Fast hot module reloading
9
- - Worker thread support for concurrency
10
- - Memory and filesystem cache backends
11
- - File System Access API implementation via BunBucket
7
+ - Native `Bun.serve()` HTTP + WebSocket server
8
+ - Built-in TypeScript/JSX support (no transpilation step)
9
+ - Worker threads with `reusePort` for zero-overhead load balancing
10
+ - Hot module reloading for development
11
+ - ServiceWorker lifecycle support (install, activate, fetch events)
12
+ - File System Access API via `@b9g/filesystem`
12
13
 
13
14
  ## Installation
14
15
 
15
16
  ```bash
16
- bun install @b9g/platform-bun
17
+ bun add @b9g/platform-bun
17
18
  ```
18
19
 
19
20
  ## Usage
20
21
 
21
- ```javascript
22
- import BunPlatform from '@b9g/platform-bun';
22
+ ### ServiceWorker Application
23
23
 
24
- const platform = new BunPlatform({
25
- cache: { type: 'memory' },
26
- filesystem: { type: 'local', directory: './dist' }
27
- });
24
+ ```typescript
25
+ import BunPlatform from "@b9g/platform-bun";
28
26
 
29
- const server = platform.createServer(async (request) => {
30
- return new Response('Hello from Bun');
31
- }, { port: 7777, host: 'localhost' });
27
+ const platform = new BunPlatform({port: 3000, workers: 4});
28
+ await platform.serviceWorker.register("./dist/server/worker.js");
29
+ await platform.serviceWorker.ready;
30
+ await platform.listen();
31
+ ```
32
+
33
+ ### Standalone Server
34
+
35
+ ```typescript
36
+ import BunPlatform from "@b9g/platform-bun";
32
37
 
38
+ const platform = new BunPlatform();
39
+ const server = platform.createServer(async (request) => {
40
+ return new Response("Hello from Bun");
41
+ });
33
42
  await server.listen();
34
43
  ```
35
44
 
36
45
  ## Exports
37
46
 
38
- ### Classes
47
+ - **`BunPlatform`** (default) -- Main platform class
48
+ - **`BunServiceWorkerContainer`** -- ServiceWorker container managing worker lifecycle
49
+ - **`BunPlatformOptions`** -- Constructor options type
50
+ - **`DefaultCache`** -- Re-exported `MemoryCache` for config references
39
51
 
40
- - `BunPlatform` - Bun platform implementation (extends BasePlatform)
52
+ ## API
41
53
 
42
- ### Types
54
+ ### `new BunPlatform(options?)`
43
55
 
44
- - `BunPlatformOptions` - Configuration options for BunPlatform
56
+ | Option | Type | Default | Description |
57
+ |--------|------|---------|-------------|
58
+ | `port` | `number` | `7777` | Server port |
59
+ | `host` | `string` | `"localhost"` | Server host |
60
+ | `cwd` | `string` | `process.cwd()` | Working directory |
61
+ | `workers` | `number` | `1` | Number of worker threads |
62
+ | `config` | `ShovelConfig` | -- | Shovel config (caches, directories) |
45
63
 
46
- ### Re-exports from @b9g/platform
64
+ ### `platform.createServer(handler, options?)`
47
65
 
48
- - `Platform`, `CacheConfig`, `StaticConfig`, `Handler`, `Server`, `ServerOptions`
66
+ Creates a Bun HTTP server with WebSocket upgrade support.
49
67
 
50
- ### Default Export
68
+ - **`handler`**: `(request: Request) => Promise<Response | HandleResult>`
69
+ - **`options.port`**: Override port
70
+ - **`options.host`**: Override host
71
+ - **`options.reusePort`**: Enable OS-level load balancing (used in multi-worker production)
51
72
 
52
- - `BunPlatform` - The platform class
73
+ Returns a `Server` with `listen()`, `close()`, `url`, `address()`, and `ready`.
53
74
 
54
- ## API
75
+ ### `platform.serviceWorker`
55
76
 
56
- ### `new BunPlatform(options?)`
77
+ `BunServiceWorkerContainer` implementing the standard `ServiceWorkerContainer` interface:
78
+
79
+ - **`register(scriptURL, options?)`** -- Register a ServiceWorker, spawns worker threads
80
+ - **`ready`** -- Promise resolving when registration is active
81
+ - **`getRegistration(scope?)`** / **`getRegistrations()`** -- Query registrations
82
+
83
+ ### `platform.getEntryPoints(userEntryPath, mode)`
84
+
85
+ Returns generated entry point code for bundling. Used by the build system.
86
+
87
+ - **Development**: `{worker}` -- Single worker with message loop
88
+ - **Production**: `{supervisor, worker}` -- Supervisor spawns workers with `reusePort`
57
89
 
58
- Creates a new Bun platform instance.
90
+ ### `platform.getESBuildConfig()`
59
91
 
60
- **Options:**
61
- - `cache`: Cache configuration (memory, filesystem)
62
- - `filesystem`: Filesystem configuration (local directory)
63
- - `port`: Default port (default: 7777)
64
- - `host`: Default host (default: localhost)
65
- - `cwd`: Working directory for file resolution
92
+ Returns Bun-specific esbuild configuration: `platform: "node"`, externals for `node:*`, `bun`, `bun:*`, and Node.js builtins.
66
93
 
67
- ### `platform.createServer(handler, options)`
94
+ ## Worker Architecture
68
95
 
69
- Creates a Bun HTTP server with the given request handler.
96
+ ### Development
70
97
 
71
- **Options:**
72
- - `port`: Port to listen on
73
- - `host`: Host to bind to
98
+ Single worker managed by the `shovel develop` CLI. The develop command owns the HTTP server; the worker handles requests via message loop.
99
+
100
+ ### Production
101
+
102
+ Each worker creates its own `Bun.serve()` with `reusePort`, letting the OS kernel load-balance connections. No message passing overhead between supervisor and workers.
103
+
104
+ ```
105
+ Supervisor (index.js)
106
+ ├── Worker 1 (worker.js) ── Bun.serve(:3000, reusePort)
107
+ ├── Worker 2 (worker.js) ── Bun.serve(:3000, reusePort)
108
+ └── Worker N (worker.js) ── Bun.serve(:3000, reusePort)
109
+ ```
74
110
 
75
- Returns a Server instance with `listen()` and `close()` methods.
111
+ The supervisor handles graceful shutdown (SIGINT/SIGTERM) and BroadcastChannel relay between workers.
76
112
 
77
- ## Cache Backends
113
+ ## How It Differs from @b9g/platform-node
78
114
 
79
- - `memory`: In-memory caching using MemoryCache
80
- - `filesystem`: Filesystem-based caching using BunBucket
115
+ | | Bun | Node.js |
116
+ |---|---|---|
117
+ | **HTTP** | `Bun.serve()` | `node:http` + `ws` |
118
+ | **WebSocket** | Built-in | Requires `ws` package |
119
+ | **Load balancing** | OS-level via `reusePort` | Round-robin message passing |
120
+ | **TypeScript** | Native support | VM module transpilation |
121
+ | **Multi-worker** | Each worker binds own port | Supervisor distributes requests |
81
122
 
82
123
  ## License
83
124
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@b9g/platform-bun",
3
- "version": "0.1.15",
3
+ "version": "0.1.17",
4
4
  "description": "Bun platform adapter for Shovel with hot reloading and built-in TypeScript/JSX support",
5
5
  "keywords": [
6
6
  "shovel",
@@ -13,15 +13,15 @@
13
13
  ],
14
14
  "repository": {
15
15
  "type": "git",
16
- "url": "https://github.com/bikeshaving/shovel.git",
16
+ "url": "git+https://github.com/bikeshaving/shovel.git",
17
17
  "directory": "packages/platform-bun"
18
18
  },
19
19
  "dependencies": {
20
20
  "@b9g/assets": "^0.2.1",
21
21
  "@b9g/cache": "^0.2.2",
22
22
  "@b9g/http-errors": "^0.2.1",
23
- "@b9g/platform": "^0.1.17",
24
- "@logtape/logtape": "^1.2.0"
23
+ "@b9g/platform": "^0.1.19",
24
+ "@logtape/logtape": "^2.0.0"
25
25
  },
26
26
  "devDependencies": {
27
27
  "@b9g/libuild": "^0.1.18"
package/src/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /// <reference types="./index.d.ts" />
2
- // src/index.ts
2
+ // packages/platform-bun/src/index.ts
3
3
  import { builtinModules } from "node:module";
4
4
  import { tmpdir } from "node:os";
5
5
  import * as Path from "node:path";
@@ -250,7 +250,7 @@ var BunPlatform = class {
250
250
  const prodWorkerCode = `// Bun Production Worker
251
251
  import BunPlatform from "@b9g/platform-bun";
252
252
  import {getLogger} from "@logtape/logtape";
253
- import {configureLogging, initWorkerRuntime, runLifecycle, dispatchRequest} from "@b9g/platform/runtime";
253
+ import {configureLogging, initWorkerRuntime, runLifecycle, dispatchRequest, setBroadcastChannelRelay, deliverBroadcastMessage} from "@b9g/platform/runtime";
254
254
  import {config} from "shovel:config";
255
255
 
256
256
  await configureLogging(config.logging);
@@ -260,13 +260,15 @@ const logger = getLogger(["shovel", "platform"]);
260
260
  let server;
261
261
  let databases;
262
262
 
263
- // Register shutdown handler before async startup
263
+ // Register message handler for shutdown and broadcast relay
264
264
  self.onmessage = async (event) => {
265
265
  if (event.data.type === "shutdown") {
266
266
  logger.info("Worker shutting down");
267
267
  if (server) await server.close();
268
268
  if (databases) await databases.closeAll();
269
269
  postMessage({type: "shutdown-complete"});
270
+ } else if (event.data.type === "broadcast:deliver") {
271
+ deliverBroadcastMessage(event.data.channel, event.data.data);
270
272
  }
271
273
  };
272
274
 
@@ -275,6 +277,11 @@ const result = await initWorkerRuntime({config, usePostMessage: false});
275
277
  const registration = result.registration;
276
278
  databases = result.databases;
277
279
 
280
+ // Set up broadcast relay (posts go to supervisor for fan-out to other workers)
281
+ setBroadcastChannelRelay((channelName, data) => {
282
+ postMessage({type: "broadcast:post", channel: channelName, data});
283
+ });
284
+
278
285
  // Import user code (registers event handlers)
279
286
  await import("${userEntryPath}");
280
287
 
package/src/platform.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /// <reference types="./platform.d.ts" />
2
- // src/platform.ts
2
+ // packages/platform-bun/src/platform.ts
3
3
  import { builtinModules } from "node:module";
4
4
  import { getLogger } from "@logtape/logtape";
5
5
  var logger = getLogger(["shovel", "platform"]);