@b9g/platform-bun 0.1.4 → 0.1.6
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 +84 -0
- package/package.json +3 -12
- package/src/index.d.ts +55 -2
- package/src/index.js +241 -4
- package/src/platform.d.ts +0 -66
- package/src/platform.js +0 -191
package/README.md
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# @b9g/platform-bun
|
|
2
|
+
|
|
3
|
+
Bun platform adapter for Shovel. Runs ServiceWorker applications on Bun with native HTTP server integration and fast hot reloading.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
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
|
|
12
|
+
|
|
13
|
+
## Installation
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
bun install @b9g/platform-bun
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Usage
|
|
20
|
+
|
|
21
|
+
```javascript
|
|
22
|
+
import BunPlatform from '@b9g/platform-bun';
|
|
23
|
+
|
|
24
|
+
const platform = new BunPlatform({
|
|
25
|
+
cache: { type: 'memory' },
|
|
26
|
+
filesystem: { type: 'local', directory: './dist' }
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
const server = platform.createServer(async (request) => {
|
|
30
|
+
return new Response('Hello from Bun');
|
|
31
|
+
}, { port: 3000, host: 'localhost' });
|
|
32
|
+
|
|
33
|
+
await server.listen();
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Exports
|
|
37
|
+
|
|
38
|
+
### Classes
|
|
39
|
+
|
|
40
|
+
- `BunPlatform` - Bun platform implementation (extends BasePlatform)
|
|
41
|
+
|
|
42
|
+
### Types
|
|
43
|
+
|
|
44
|
+
- `BunPlatformOptions` - Configuration options for BunPlatform
|
|
45
|
+
|
|
46
|
+
### Re-exports from @b9g/platform
|
|
47
|
+
|
|
48
|
+
- `Platform`, `CacheConfig`, `StaticConfig`, `Handler`, `Server`, `ServerOptions`
|
|
49
|
+
|
|
50
|
+
### Default Export
|
|
51
|
+
|
|
52
|
+
- `BunPlatform` - The platform class
|
|
53
|
+
|
|
54
|
+
## API
|
|
55
|
+
|
|
56
|
+
### `new BunPlatform(options?)`
|
|
57
|
+
|
|
58
|
+
Creates a new Bun platform instance.
|
|
59
|
+
|
|
60
|
+
**Options:**
|
|
61
|
+
- `cache`: Cache configuration (memory, filesystem)
|
|
62
|
+
- `filesystem`: Filesystem configuration (local directory)
|
|
63
|
+
- `port`: Default port (default: 3000)
|
|
64
|
+
- `host`: Default host (default: localhost)
|
|
65
|
+
- `cwd`: Working directory for file resolution
|
|
66
|
+
|
|
67
|
+
### `platform.createServer(handler, options)`
|
|
68
|
+
|
|
69
|
+
Creates a Bun HTTP server with the given request handler.
|
|
70
|
+
|
|
71
|
+
**Options:**
|
|
72
|
+
- `port`: Port to listen on
|
|
73
|
+
- `host`: Host to bind to
|
|
74
|
+
|
|
75
|
+
Returns a Server instance with `listen()` and `close()` methods.
|
|
76
|
+
|
|
77
|
+
## Cache Backends
|
|
78
|
+
|
|
79
|
+
- `memory`: In-memory caching using MemoryCache
|
|
80
|
+
- `filesystem`: Filesystem-based caching using BunBucket
|
|
81
|
+
|
|
82
|
+
## License
|
|
83
|
+
|
|
84
|
+
MIT
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@b9g/platform-bun",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.6",
|
|
4
4
|
"description": "Bun platform adapter for Shovel with hot reloading and built-in TypeScript/JSX support",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"shovel",
|
|
@@ -12,9 +12,8 @@
|
|
|
12
12
|
"jsx"
|
|
13
13
|
],
|
|
14
14
|
"dependencies": {
|
|
15
|
-
"@b9g/platform": "^0.1.
|
|
16
|
-
"@b9g/
|
|
17
|
-
"@b9g/assets": "^0.1.4"
|
|
15
|
+
"@b9g/platform": "^0.1.6",
|
|
16
|
+
"@b9g/assets": "^0.1.6"
|
|
18
17
|
},
|
|
19
18
|
"devDependencies": {
|
|
20
19
|
"@b9g/libuild": "^0.1.11",
|
|
@@ -28,14 +27,6 @@
|
|
|
28
27
|
"types": "./src/index.d.ts",
|
|
29
28
|
"import": "./src/index.js"
|
|
30
29
|
},
|
|
31
|
-
"./platform": {
|
|
32
|
-
"types": "./src/platform.d.ts",
|
|
33
|
-
"import": "./src/platform.js"
|
|
34
|
-
},
|
|
35
|
-
"./platform.js": {
|
|
36
|
-
"types": "./src/platform.d.ts",
|
|
37
|
-
"import": "./src/platform.js"
|
|
38
|
-
},
|
|
39
30
|
"./package.json": "./package.json",
|
|
40
31
|
"./index": {
|
|
41
32
|
"types": "./src/index.d.ts",
|
package/src/index.d.ts
CHANGED
|
@@ -3,5 +3,58 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Provides built-in TypeScript/JSX support and simplified server setup for Bun environments.
|
|
5
5
|
*/
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
import { BasePlatform, PlatformConfig, Handler, Server, ServerOptions, ServiceWorkerOptions, ServiceWorkerInstance, ServiceWorkerPool } from "@b9g/platform";
|
|
7
|
+
import { CustomCacheStorage } from "@b9g/cache";
|
|
8
|
+
export type { Platform, Handler, Server, ServerOptions, ServiceWorkerOptions, ServiceWorkerInstance, } from "@b9g/platform";
|
|
9
|
+
export interface BunPlatformOptions extends PlatformConfig {
|
|
10
|
+
/** Port for development server (default: 3000) */
|
|
11
|
+
port?: number;
|
|
12
|
+
/** Host for development server (default: localhost) */
|
|
13
|
+
host?: string;
|
|
14
|
+
/** Working directory for file resolution */
|
|
15
|
+
cwd?: string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Bun platform implementation
|
|
19
|
+
* ServiceWorker entrypoint loader for Bun with native TypeScript/JSX support
|
|
20
|
+
*/
|
|
21
|
+
export declare class BunPlatform extends BasePlatform {
|
|
22
|
+
#private;
|
|
23
|
+
readonly name: string;
|
|
24
|
+
constructor(options?: BunPlatformOptions);
|
|
25
|
+
/**
|
|
26
|
+
* Get options for testing
|
|
27
|
+
*/
|
|
28
|
+
get options(): Required<BunPlatformOptions>;
|
|
29
|
+
/**
|
|
30
|
+
* Get/set worker pool for testing
|
|
31
|
+
*/
|
|
32
|
+
get workerPool(): ServiceWorkerPool | undefined;
|
|
33
|
+
set workerPool(pool: ServiceWorkerPool | undefined);
|
|
34
|
+
/**
|
|
35
|
+
* Create cache storage
|
|
36
|
+
* Uses config from package.json shovel field
|
|
37
|
+
*/
|
|
38
|
+
createCaches(): Promise<CustomCacheStorage>;
|
|
39
|
+
/**
|
|
40
|
+
* Create HTTP server using Bun.serve
|
|
41
|
+
*/
|
|
42
|
+
createServer(handler: Handler, options?: ServerOptions): Server;
|
|
43
|
+
/**
|
|
44
|
+
* Load and run a ServiceWorker-style entrypoint with Bun
|
|
45
|
+
* Uses native Web Workers with the common WorkerPool
|
|
46
|
+
*/
|
|
47
|
+
loadServiceWorker(entrypoint: string, options?: ServiceWorkerOptions): Promise<ServiceWorkerInstance>;
|
|
48
|
+
/**
|
|
49
|
+
* Reload workers for hot reloading (called by CLI)
|
|
50
|
+
*/
|
|
51
|
+
reloadWorkers(version?: number | string): Promise<void>;
|
|
52
|
+
/**
|
|
53
|
+
* Dispose of platform resources
|
|
54
|
+
*/
|
|
55
|
+
dispose(): Promise<void>;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Default export for easy importing
|
|
59
|
+
*/
|
|
60
|
+
export default BunPlatform;
|
package/src/index.js
CHANGED
|
@@ -1,10 +1,247 @@
|
|
|
1
1
|
/// <reference types="./index.d.ts" />
|
|
2
2
|
// src/index.ts
|
|
3
3
|
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
BasePlatform,
|
|
5
|
+
ServiceWorkerPool,
|
|
6
|
+
SingleThreadedRuntime,
|
|
7
|
+
loadConfig,
|
|
8
|
+
createCacheFactory
|
|
9
|
+
} from "@b9g/platform";
|
|
10
|
+
import { CustomCacheStorage } from "@b9g/cache";
|
|
11
|
+
import * as Path from "path";
|
|
12
|
+
import { getLogger } from "@logtape/logtape";
|
|
13
|
+
var logger = getLogger(["platform-bun"]);
|
|
14
|
+
var BunPlatform = class extends BasePlatform {
|
|
15
|
+
name;
|
|
16
|
+
#options;
|
|
17
|
+
#workerPool;
|
|
18
|
+
#singleThreadedRuntime;
|
|
19
|
+
#cacheStorage;
|
|
20
|
+
#config;
|
|
21
|
+
constructor(options = {}) {
|
|
22
|
+
super(options);
|
|
23
|
+
this.name = "bun";
|
|
24
|
+
const cwd = options.cwd || process.cwd();
|
|
25
|
+
this.#config = loadConfig(cwd);
|
|
26
|
+
this.#options = {
|
|
27
|
+
port: options.port ?? this.#config.port,
|
|
28
|
+
host: options.host ?? this.#config.host,
|
|
29
|
+
cwd,
|
|
30
|
+
...options
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Get options for testing
|
|
35
|
+
*/
|
|
36
|
+
get options() {
|
|
37
|
+
return this.#options;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Get/set worker pool for testing
|
|
41
|
+
*/
|
|
42
|
+
get workerPool() {
|
|
43
|
+
return this.#workerPool;
|
|
44
|
+
}
|
|
45
|
+
set workerPool(pool) {
|
|
46
|
+
this.#workerPool = pool;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Create cache storage
|
|
50
|
+
* Uses config from package.json shovel field
|
|
51
|
+
*/
|
|
52
|
+
async createCaches() {
|
|
53
|
+
return new CustomCacheStorage(createCacheFactory({ config: this.#config }));
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Create HTTP server using Bun.serve
|
|
57
|
+
*/
|
|
58
|
+
createServer(handler, options = {}) {
|
|
59
|
+
const port = options.port ?? this.#options.port;
|
|
60
|
+
const hostname = options.host ?? this.#options.host;
|
|
61
|
+
const server = Bun.serve({
|
|
62
|
+
port,
|
|
63
|
+
hostname,
|
|
64
|
+
async fetch(request) {
|
|
65
|
+
return handler(request);
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
return {
|
|
69
|
+
async listen() {
|
|
70
|
+
logger.info("Bun server running", { url: `http://${hostname}:${port}` });
|
|
71
|
+
},
|
|
72
|
+
async close() {
|
|
73
|
+
server.stop();
|
|
74
|
+
},
|
|
75
|
+
address: () => ({ port, host: hostname }),
|
|
76
|
+
get url() {
|
|
77
|
+
return `http://${hostname}:${port}`;
|
|
78
|
+
},
|
|
79
|
+
get ready() {
|
|
80
|
+
return true;
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Load and run a ServiceWorker-style entrypoint with Bun
|
|
86
|
+
* Uses native Web Workers with the common WorkerPool
|
|
87
|
+
*/
|
|
88
|
+
async loadServiceWorker(entrypoint, options = {}) {
|
|
89
|
+
const workerCount = options.workerCount ?? this.#config.workers ?? 1;
|
|
90
|
+
if (workerCount === 1 && !options.hotReload) {
|
|
91
|
+
return this.#loadServiceWorkerDirect(entrypoint, options);
|
|
92
|
+
}
|
|
93
|
+
return this.#loadServiceWorkerWithPool(entrypoint, options, workerCount);
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Load ServiceWorker directly in main thread (single-threaded mode)
|
|
97
|
+
* No postMessage overhead - maximum performance for production
|
|
98
|
+
*/
|
|
99
|
+
async #loadServiceWorkerDirect(entrypoint, _options) {
|
|
100
|
+
const entryPath = Path.resolve(this.#options.cwd, entrypoint);
|
|
101
|
+
const entryDir = Path.dirname(entryPath);
|
|
102
|
+
if (!this.#cacheStorage) {
|
|
103
|
+
this.#cacheStorage = await this.createCaches();
|
|
104
|
+
}
|
|
105
|
+
if (this.#singleThreadedRuntime) {
|
|
106
|
+
await this.#singleThreadedRuntime.terminate();
|
|
107
|
+
}
|
|
108
|
+
if (this.#workerPool) {
|
|
109
|
+
await this.#workerPool.terminate();
|
|
110
|
+
this.#workerPool = void 0;
|
|
111
|
+
}
|
|
112
|
+
logger.info("Creating single-threaded ServiceWorker runtime", { entryPath });
|
|
113
|
+
this.#singleThreadedRuntime = new SingleThreadedRuntime({
|
|
114
|
+
baseDir: entryDir,
|
|
115
|
+
cacheStorage: this.#cacheStorage,
|
|
116
|
+
config: this.#config
|
|
117
|
+
});
|
|
118
|
+
await this.#singleThreadedRuntime.init();
|
|
119
|
+
const version = Date.now();
|
|
120
|
+
await this.#singleThreadedRuntime.loadEntrypoint(entryPath, version);
|
|
121
|
+
const runtime = this.#singleThreadedRuntime;
|
|
122
|
+
const platform = this;
|
|
123
|
+
const instance = {
|
|
124
|
+
runtime,
|
|
125
|
+
handleRequest: async (request) => {
|
|
126
|
+
if (!platform.#singleThreadedRuntime) {
|
|
127
|
+
throw new Error("SingleThreadedRuntime not initialized");
|
|
128
|
+
}
|
|
129
|
+
return platform.#singleThreadedRuntime.handleRequest(request);
|
|
130
|
+
},
|
|
131
|
+
install: async () => {
|
|
132
|
+
logger.info("ServiceWorker installed", { method: "single_threaded" });
|
|
133
|
+
},
|
|
134
|
+
activate: async () => {
|
|
135
|
+
logger.info("ServiceWorker activated", { method: "single_threaded" });
|
|
136
|
+
},
|
|
137
|
+
get ready() {
|
|
138
|
+
return runtime?.ready ?? false;
|
|
139
|
+
},
|
|
140
|
+
dispose: async () => {
|
|
141
|
+
if (platform.#singleThreadedRuntime) {
|
|
142
|
+
await platform.#singleThreadedRuntime.terminate();
|
|
143
|
+
platform.#singleThreadedRuntime = void 0;
|
|
144
|
+
}
|
|
145
|
+
logger.info("ServiceWorker disposed", {});
|
|
146
|
+
}
|
|
147
|
+
};
|
|
148
|
+
logger.info("ServiceWorker loaded", {
|
|
149
|
+
features: ["single_threaded", "no_postmessage_overhead"]
|
|
150
|
+
});
|
|
151
|
+
return instance;
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Load ServiceWorker using worker pool (multi-threaded mode or dev mode)
|
|
155
|
+
*/
|
|
156
|
+
async #loadServiceWorkerWithPool(entrypoint, _options, workerCount) {
|
|
157
|
+
const entryPath = Path.resolve(this.#options.cwd, entrypoint);
|
|
158
|
+
if (!this.#cacheStorage) {
|
|
159
|
+
this.#cacheStorage = await this.createCaches();
|
|
160
|
+
}
|
|
161
|
+
if (this.#singleThreadedRuntime) {
|
|
162
|
+
await this.#singleThreadedRuntime.terminate();
|
|
163
|
+
this.#singleThreadedRuntime = void 0;
|
|
164
|
+
}
|
|
165
|
+
if (this.#workerPool) {
|
|
166
|
+
await this.#workerPool.terminate();
|
|
167
|
+
}
|
|
168
|
+
const poolOptions = {
|
|
169
|
+
workerCount,
|
|
170
|
+
requestTimeout: 3e4,
|
|
171
|
+
cwd: this.#options.cwd
|
|
172
|
+
};
|
|
173
|
+
logger.info("Creating ServiceWorker pool", { entryPath, workerCount });
|
|
174
|
+
this.#workerPool = new ServiceWorkerPool(
|
|
175
|
+
poolOptions,
|
|
176
|
+
entryPath,
|
|
177
|
+
this.#cacheStorage,
|
|
178
|
+
this.#config
|
|
179
|
+
);
|
|
180
|
+
await this.#workerPool.init();
|
|
181
|
+
const version = Date.now();
|
|
182
|
+
await this.#workerPool.reloadWorkers(version);
|
|
183
|
+
const workerPool = this.#workerPool;
|
|
184
|
+
const platform = this;
|
|
185
|
+
const instance = {
|
|
186
|
+
runtime: workerPool,
|
|
187
|
+
handleRequest: async (request) => {
|
|
188
|
+
if (!platform.#workerPool) {
|
|
189
|
+
throw new Error("WorkerPool not initialized");
|
|
190
|
+
}
|
|
191
|
+
return platform.#workerPool.handleRequest(request);
|
|
192
|
+
},
|
|
193
|
+
install: async () => {
|
|
194
|
+
logger.info("ServiceWorker installed", { method: "native_web_workers" });
|
|
195
|
+
},
|
|
196
|
+
activate: async () => {
|
|
197
|
+
logger.info("ServiceWorker activated", { method: "native_web_workers" });
|
|
198
|
+
},
|
|
199
|
+
get ready() {
|
|
200
|
+
return workerPool?.ready ?? false;
|
|
201
|
+
},
|
|
202
|
+
dispose: async () => {
|
|
203
|
+
if (platform.#workerPool) {
|
|
204
|
+
await platform.#workerPool.terminate();
|
|
205
|
+
platform.#workerPool = void 0;
|
|
206
|
+
}
|
|
207
|
+
logger.info("ServiceWorker disposed", {});
|
|
208
|
+
}
|
|
209
|
+
};
|
|
210
|
+
logger.info("ServiceWorker loaded", {
|
|
211
|
+
features: ["native_web_workers", "coordinated_caches"]
|
|
212
|
+
});
|
|
213
|
+
return instance;
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Reload workers for hot reloading (called by CLI)
|
|
217
|
+
*/
|
|
218
|
+
async reloadWorkers(version) {
|
|
219
|
+
if (this.#workerPool) {
|
|
220
|
+
await this.#workerPool.reloadWorkers(version);
|
|
221
|
+
} else if (this.#singleThreadedRuntime) {
|
|
222
|
+
await this.#singleThreadedRuntime.reloadWorkers(version);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Dispose of platform resources
|
|
227
|
+
*/
|
|
228
|
+
async dispose() {
|
|
229
|
+
if (this.#singleThreadedRuntime) {
|
|
230
|
+
await this.#singleThreadedRuntime.terminate();
|
|
231
|
+
this.#singleThreadedRuntime = void 0;
|
|
232
|
+
}
|
|
233
|
+
if (this.#workerPool) {
|
|
234
|
+
await this.#workerPool.terminate();
|
|
235
|
+
this.#workerPool = void 0;
|
|
236
|
+
}
|
|
237
|
+
if (this.#cacheStorage) {
|
|
238
|
+
await this.#cacheStorage.dispose();
|
|
239
|
+
this.#cacheStorage = void 0;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
};
|
|
243
|
+
var src_default = BunPlatform;
|
|
7
244
|
export {
|
|
8
245
|
BunPlatform,
|
|
9
|
-
|
|
246
|
+
src_default as default
|
|
10
247
|
};
|
package/src/platform.d.ts
DELETED
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Bun platform implementation - ServiceWorker entrypoint loader for Bun
|
|
3
|
-
*
|
|
4
|
-
* Bun has built-in TypeScript/JSX support, so this is much simpler than Node.js.
|
|
5
|
-
* Uses native imports instead of complex ESBuild VM system.
|
|
6
|
-
*/
|
|
7
|
-
import { BasePlatform, PlatformConfig, CacheConfig, Handler, Server, ServerOptions, ServiceWorkerOptions, ServiceWorkerInstance } from "@b9g/platform";
|
|
8
|
-
import { CustomCacheStorage } from "@b9g/cache";
|
|
9
|
-
export interface BunPlatformOptions extends PlatformConfig {
|
|
10
|
-
/** Enable hot reloading (default: true in development) */
|
|
11
|
-
hotReload?: boolean;
|
|
12
|
-
/** Port for development server (default: 3000) */
|
|
13
|
-
port?: number;
|
|
14
|
-
/** Host for development server (default: localhost) */
|
|
15
|
-
host?: string;
|
|
16
|
-
/** Working directory for file resolution */
|
|
17
|
-
cwd?: string;
|
|
18
|
-
}
|
|
19
|
-
/**
|
|
20
|
-
* Bun platform implementation
|
|
21
|
-
* ServiceWorker entrypoint loader for Bun with native TypeScript/JSX support
|
|
22
|
-
*/
|
|
23
|
-
export declare class BunPlatform extends BasePlatform {
|
|
24
|
-
readonly name = "bun";
|
|
25
|
-
private options;
|
|
26
|
-
private workerPool?;
|
|
27
|
-
private cacheStorage?;
|
|
28
|
-
constructor(options?: BunPlatformOptions);
|
|
29
|
-
/**
|
|
30
|
-
* Build artifacts filesystem (install-time only)
|
|
31
|
-
*/
|
|
32
|
-
getDirectoryHandle(name: string): Promise<FileSystemDirectoryHandle>;
|
|
33
|
-
/**
|
|
34
|
-
* Get platform-specific default cache configuration for Bun
|
|
35
|
-
*/
|
|
36
|
-
protected getDefaultCacheConfig(): CacheConfig;
|
|
37
|
-
/**
|
|
38
|
-
* Override cache creation to use appropriate cache type for Bun
|
|
39
|
-
*/
|
|
40
|
-
createCaches(config?: CacheConfig): Promise<CustomCacheStorage>;
|
|
41
|
-
/**
|
|
42
|
-
* Create HTTP server using Bun.serve
|
|
43
|
-
*/
|
|
44
|
-
createServer(handler: Handler, options?: ServerOptions): Server;
|
|
45
|
-
/**
|
|
46
|
-
* Load and run a ServiceWorker-style entrypoint with Bun
|
|
47
|
-
* Uses native Web Workers with the common WorkerPool
|
|
48
|
-
*/
|
|
49
|
-
loadServiceWorker(entrypoint: string, options?: ServiceWorkerOptions): Promise<ServiceWorkerInstance>;
|
|
50
|
-
/**
|
|
51
|
-
* Reload workers for hot reloading (called by CLI)
|
|
52
|
-
*/
|
|
53
|
-
reloadWorkers(version?: number | string): Promise<void>;
|
|
54
|
-
/**
|
|
55
|
-
* Dispose of platform resources
|
|
56
|
-
*/
|
|
57
|
-
dispose(): Promise<void>;
|
|
58
|
-
}
|
|
59
|
-
/**
|
|
60
|
-
* Create a Bun platform instance
|
|
61
|
-
*/
|
|
62
|
-
export declare function createBunPlatform(options?: BunPlatformOptions): BunPlatform;
|
|
63
|
-
/**
|
|
64
|
-
* Default export for easy importing
|
|
65
|
-
*/
|
|
66
|
-
export default createBunPlatform;
|
package/src/platform.js
DELETED
|
@@ -1,191 +0,0 @@
|
|
|
1
|
-
/// <reference types="./platform.d.ts" />
|
|
2
|
-
// src/platform.ts
|
|
3
|
-
import {
|
|
4
|
-
BasePlatform
|
|
5
|
-
} from "@b9g/platform";
|
|
6
|
-
import { WorkerPool } from "@b9g/platform/worker-pool";
|
|
7
|
-
import { CustomCacheStorage, PostMessageCache } from "@b9g/cache";
|
|
8
|
-
import { FileSystemRegistry, MemoryBucket, LocalBucket } from "@b9g/filesystem";
|
|
9
|
-
import * as Path from "path";
|
|
10
|
-
var BunPlatform = class extends BasePlatform {
|
|
11
|
-
name = "bun";
|
|
12
|
-
options;
|
|
13
|
-
workerPool;
|
|
14
|
-
cacheStorage;
|
|
15
|
-
constructor(options = {}) {
|
|
16
|
-
super(options);
|
|
17
|
-
this.options = {
|
|
18
|
-
hotReload: Bun.env.NODE_ENV !== "production",
|
|
19
|
-
port: 3e3,
|
|
20
|
-
host: "localhost",
|
|
21
|
-
cwd: process.cwd(),
|
|
22
|
-
...options
|
|
23
|
-
};
|
|
24
|
-
FileSystemRegistry.register("memory", new MemoryBucket());
|
|
25
|
-
FileSystemRegistry.register("node", new LocalBucket({
|
|
26
|
-
rootPath: Path.join(this.options.cwd, "dist")
|
|
27
|
-
}));
|
|
28
|
-
try {
|
|
29
|
-
FileSystemRegistry.register("bun-s3", new BunS3FileSystemAdapter(
|
|
30
|
-
// @ts-ignore - Bun's S3Client
|
|
31
|
-
new Bun.S3Client({})
|
|
32
|
-
));
|
|
33
|
-
} catch {
|
|
34
|
-
console.warn("[Bun] S3Client not available, using memory filesystem");
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
/**
|
|
38
|
-
* Build artifacts filesystem (install-time only)
|
|
39
|
-
*/
|
|
40
|
-
async getDirectoryHandle(name) {
|
|
41
|
-
const distPath = Path.resolve(this.options.cwd, "dist");
|
|
42
|
-
const adapter = new LocalBucket({ rootPath: distPath });
|
|
43
|
-
return await adapter.getDirectoryHandle(name);
|
|
44
|
-
}
|
|
45
|
-
/**
|
|
46
|
-
* Get platform-specific default cache configuration for Bun
|
|
47
|
-
*/
|
|
48
|
-
getDefaultCacheConfig() {
|
|
49
|
-
return {
|
|
50
|
-
pages: { type: "memory" },
|
|
51
|
-
// PostMessage cache for coordination
|
|
52
|
-
api: { type: "memory" },
|
|
53
|
-
static: { type: "memory" }
|
|
54
|
-
};
|
|
55
|
-
}
|
|
56
|
-
/**
|
|
57
|
-
* Override cache creation to use appropriate cache type for Bun
|
|
58
|
-
*/
|
|
59
|
-
async createCaches(config) {
|
|
60
|
-
const { MemoryCache } = await import("@b9g/cache");
|
|
61
|
-
const isWorkerThread = typeof self !== "undefined" && typeof window === "undefined";
|
|
62
|
-
return new CustomCacheStorage((name) => {
|
|
63
|
-
if (!isWorkerThread) {
|
|
64
|
-
return new MemoryCache(name, {
|
|
65
|
-
maxEntries: 1e3,
|
|
66
|
-
maxAge: 60 * 60 * 1e3
|
|
67
|
-
// 1 hour
|
|
68
|
-
});
|
|
69
|
-
} else {
|
|
70
|
-
return new PostMessageCache(name, {
|
|
71
|
-
maxEntries: 1e3,
|
|
72
|
-
maxAge: 60 * 60 * 1e3
|
|
73
|
-
// 1 hour
|
|
74
|
-
});
|
|
75
|
-
}
|
|
76
|
-
});
|
|
77
|
-
}
|
|
78
|
-
/**
|
|
79
|
-
* Create HTTP server using Bun.serve
|
|
80
|
-
*/
|
|
81
|
-
createServer(handler, options = {}) {
|
|
82
|
-
const port = options.port ?? this.options.port;
|
|
83
|
-
const hostname = options.host ?? this.options.host;
|
|
84
|
-
const server = Bun.serve({
|
|
85
|
-
port,
|
|
86
|
-
hostname,
|
|
87
|
-
async fetch(request) {
|
|
88
|
-
return handler(request);
|
|
89
|
-
},
|
|
90
|
-
development: this.options.hotReload
|
|
91
|
-
});
|
|
92
|
-
return {
|
|
93
|
-
async listen() {
|
|
94
|
-
console.info(`\u{1F956} Bun server running at http://${hostname}:${port}`);
|
|
95
|
-
},
|
|
96
|
-
async close() {
|
|
97
|
-
server.stop();
|
|
98
|
-
},
|
|
99
|
-
address: () => ({ port, host: hostname }),
|
|
100
|
-
get url() {
|
|
101
|
-
return `http://${hostname}:${port}`;
|
|
102
|
-
},
|
|
103
|
-
get ready() {
|
|
104
|
-
return true;
|
|
105
|
-
}
|
|
106
|
-
};
|
|
107
|
-
}
|
|
108
|
-
/**
|
|
109
|
-
* Load and run a ServiceWorker-style entrypoint with Bun
|
|
110
|
-
* Uses native Web Workers with the common WorkerPool
|
|
111
|
-
*/
|
|
112
|
-
async loadServiceWorker(entrypoint, options = {}) {
|
|
113
|
-
const entryPath = Path.resolve(this.options.cwd, entrypoint);
|
|
114
|
-
if (!this.cacheStorage) {
|
|
115
|
-
this.cacheStorage = await this.createCaches(options.caches);
|
|
116
|
-
}
|
|
117
|
-
if (this.workerPool) {
|
|
118
|
-
await this.workerPool.terminate();
|
|
119
|
-
}
|
|
120
|
-
const workerCount = options.workerCount || 1;
|
|
121
|
-
const poolOptions = {
|
|
122
|
-
workerCount,
|
|
123
|
-
requestTimeout: 3e4,
|
|
124
|
-
hotReload: this.options.hotReload,
|
|
125
|
-
cwd: this.options.cwd
|
|
126
|
-
};
|
|
127
|
-
this.workerPool = new WorkerPool(
|
|
128
|
-
this.cacheStorage,
|
|
129
|
-
poolOptions,
|
|
130
|
-
entryPath
|
|
131
|
-
);
|
|
132
|
-
await this.workerPool.init();
|
|
133
|
-
const version = Date.now();
|
|
134
|
-
await this.workerPool.reloadWorkers(version);
|
|
135
|
-
const instance = {
|
|
136
|
-
runtime: this.workerPool,
|
|
137
|
-
handleRequest: async (request) => {
|
|
138
|
-
if (!this.workerPool) {
|
|
139
|
-
throw new Error("WorkerPool not initialized");
|
|
140
|
-
}
|
|
141
|
-
return this.workerPool.handleRequest(request);
|
|
142
|
-
},
|
|
143
|
-
install: async () => {
|
|
144
|
-
console.info("[Bun] ServiceWorker installed via native Web Workers");
|
|
145
|
-
},
|
|
146
|
-
activate: async () => {
|
|
147
|
-
console.info("[Bun] ServiceWorker activated via native Web Workers");
|
|
148
|
-
},
|
|
149
|
-
collectStaticRoutes: async () => {
|
|
150
|
-
return [];
|
|
151
|
-
},
|
|
152
|
-
get ready() {
|
|
153
|
-
return this.workerPool?.ready ?? false;
|
|
154
|
-
},
|
|
155
|
-
dispose: async () => {
|
|
156
|
-
if (this.workerPool) {
|
|
157
|
-
await this.workerPool.terminate();
|
|
158
|
-
this.workerPool = void 0;
|
|
159
|
-
}
|
|
160
|
-
console.info("[Bun] ServiceWorker disposed");
|
|
161
|
-
}
|
|
162
|
-
};
|
|
163
|
-
return instance;
|
|
164
|
-
}
|
|
165
|
-
/**
|
|
166
|
-
* Reload workers for hot reloading (called by CLI)
|
|
167
|
-
*/
|
|
168
|
-
async reloadWorkers(version) {
|
|
169
|
-
if (this.workerPool) {
|
|
170
|
-
await this.workerPool.reloadWorkers(version);
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
/**
|
|
174
|
-
* Dispose of platform resources
|
|
175
|
-
*/
|
|
176
|
-
async dispose() {
|
|
177
|
-
if (this.workerPool) {
|
|
178
|
-
await this.workerPool.terminate();
|
|
179
|
-
this.workerPool = void 0;
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
};
|
|
183
|
-
function createBunPlatform(options) {
|
|
184
|
-
return new BunPlatform(options);
|
|
185
|
-
}
|
|
186
|
-
var platform_default = createBunPlatform;
|
|
187
|
-
export {
|
|
188
|
-
BunPlatform,
|
|
189
|
-
createBunPlatform,
|
|
190
|
-
platform_default as default
|
|
191
|
-
};
|