@b9g/platform-bun 0.1.1 → 0.1.4

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,6 +1,6 @@
1
1
  {
2
2
  "name": "@b9g/platform-bun",
3
- "version": "0.1.1",
3
+ "version": "0.1.4",
4
4
  "description": "Bun platform adapter for Shovel with hot reloading and built-in TypeScript/JSX support",
5
5
  "keywords": [
6
6
  "shovel",
@@ -12,12 +12,12 @@
12
12
  "jsx"
13
13
  ],
14
14
  "dependencies": {
15
- "@b9g/platform": "^0.1.1",
16
- "@b9g/cache": "^0.1.1",
17
- "@b9g/assets": "^0.1.1"
15
+ "@b9g/platform": "^0.1.4",
16
+ "@b9g/cache": "^0.1.3",
17
+ "@b9g/assets": "^0.1.4"
18
18
  },
19
19
  "devDependencies": {
20
- "@b9g/libuild": "^0.1.10",
20
+ "@b9g/libuild": "^0.1.11",
21
21
  "bun-types": "latest"
22
22
  },
23
23
  "type": "module",
package/src/platform.d.ts CHANGED
@@ -23,18 +23,19 @@ export interface BunPlatformOptions extends PlatformConfig {
23
23
  export declare class BunPlatform extends BasePlatform {
24
24
  readonly name = "bun";
25
25
  private options;
26
- private _dist?;
26
+ private workerPool?;
27
+ private cacheStorage?;
27
28
  constructor(options?: BunPlatformOptions);
28
29
  /**
29
30
  * Build artifacts filesystem (install-time only)
30
31
  */
31
- get distDir(): FileSystemDirectoryHandle;
32
+ getDirectoryHandle(name: string): Promise<FileSystemDirectoryHandle>;
32
33
  /**
33
34
  * Get platform-specific default cache configuration for Bun
34
35
  */
35
36
  protected getDefaultCacheConfig(): CacheConfig;
36
37
  /**
37
- * Override cache creation to use PostMessage coordination for Bun
38
+ * Override cache creation to use appropriate cache type for Bun
38
39
  */
39
40
  createCaches(config?: CacheConfig): Promise<CustomCacheStorage>;
40
41
  /**
@@ -43,12 +44,13 @@ export declare class BunPlatform extends BasePlatform {
43
44
  createServer(handler: Handler, options?: ServerOptions): Server;
44
45
  /**
45
46
  * Load and run a ServiceWorker-style entrypoint with Bun
47
+ * Uses native Web Workers with the common WorkerPool
46
48
  */
47
49
  loadServiceWorker(entrypoint: string, options?: ServiceWorkerOptions): Promise<ServiceWorkerInstance>;
48
50
  /**
49
- * Get filesystem root for File System Access API
51
+ * Reload workers for hot reloading (called by CLI)
50
52
  */
51
- getFileSystemRoot(name?: string): Promise<FileSystemDirectoryHandle>;
53
+ reloadWorkers(version?: number | string): Promise<void>;
52
54
  /**
53
55
  * Dispose of platform resources
54
56
  */
package/src/platform.js CHANGED
@@ -1,18 +1,17 @@
1
1
  /// <reference types="./platform.d.ts" />
2
2
  // src/platform.ts
3
3
  import {
4
- BasePlatform,
5
- ServiceWorkerRuntime,
6
- createServiceWorkerGlobals,
7
- createDirectoryStorage
4
+ BasePlatform
8
5
  } from "@b9g/platform";
6
+ import { WorkerPool } from "@b9g/platform/worker-pool";
9
7
  import { CustomCacheStorage, PostMessageCache } from "@b9g/cache";
10
- import { FileSystemRegistry, getFileSystemRoot, MemoryFileSystemAdapter, NodeFileSystemAdapter, BunS3FileSystemAdapter } from "@b9g/filesystem";
8
+ import { FileSystemRegistry, MemoryBucket, LocalBucket } from "@b9g/filesystem";
11
9
  import * as Path from "path";
12
10
  var BunPlatform = class extends BasePlatform {
13
11
  name = "bun";
14
12
  options;
15
- _dist;
13
+ workerPool;
14
+ cacheStorage;
16
15
  constructor(options = {}) {
17
16
  super(options);
18
17
  this.options = {
@@ -22,8 +21,8 @@ var BunPlatform = class extends BasePlatform {
22
21
  cwd: process.cwd(),
23
22
  ...options
24
23
  };
25
- FileSystemRegistry.register("memory", new MemoryFileSystemAdapter());
26
- FileSystemRegistry.register("node", new NodeFileSystemAdapter({
24
+ FileSystemRegistry.register("memory", new MemoryBucket());
25
+ FileSystemRegistry.register("node", new LocalBucket({
27
26
  rootPath: Path.join(this.options.cwd, "dist")
28
27
  }));
29
28
  try {
@@ -38,12 +37,10 @@ var BunPlatform = class extends BasePlatform {
38
37
  /**
39
38
  * Build artifacts filesystem (install-time only)
40
39
  */
41
- get distDir() {
42
- if (!this._dist) {
43
- const distPath = Path.resolve(this.options.cwd, "dist");
44
- this._dist = new NodeFileSystemAdapter({ rootPath: distPath }).getFileSystemRoot("");
45
- }
46
- return this._dist;
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);
47
44
  }
48
45
  /**
49
46
  * Get platform-specific default cache configuration for Bun
@@ -57,15 +54,25 @@ var BunPlatform = class extends BasePlatform {
57
54
  };
58
55
  }
59
56
  /**
60
- * Override cache creation to use PostMessage coordination for Bun
57
+ * Override cache creation to use appropriate cache type for Bun
61
58
  */
62
59
  async createCaches(config) {
60
+ const { MemoryCache } = await import("@b9g/cache");
61
+ const isWorkerThread = typeof self !== "undefined" && typeof window === "undefined";
63
62
  return new CustomCacheStorage((name) => {
64
- return new PostMessageCache(name, {
65
- maxEntries: 1e3,
66
- maxSize: 50 * 1024 * 1024
67
- // 50MB
68
- });
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
+ }
69
76
  });
70
77
  }
71
78
  /**
@@ -83,80 +90,94 @@ var BunPlatform = class extends BasePlatform {
83
90
  development: this.options.hotReload
84
91
  });
85
92
  return {
86
- listen: () => {
93
+ async listen() {
87
94
  console.info(`\u{1F956} Bun server running at http://${hostname}:${port}`);
88
- return Promise.resolve();
89
95
  },
90
- close: () => {
96
+ async close() {
91
97
  server.stop();
92
- return Promise.resolve();
93
98
  },
94
- address: () => ({ port, host: hostname })
99
+ address: () => ({ port, host: hostname }),
100
+ get url() {
101
+ return `http://${hostname}:${port}`;
102
+ },
103
+ get ready() {
104
+ return true;
105
+ }
95
106
  };
96
107
  }
97
108
  /**
98
109
  * Load and run a ServiceWorker-style entrypoint with Bun
110
+ * Uses native Web Workers with the common WorkerPool
99
111
  */
100
112
  async loadServiceWorker(entrypoint, options = {}) {
101
- const runtime = new ServiceWorkerRuntime();
102
113
  const entryPath = Path.resolve(this.options.cwd, entrypoint);
103
- const caches = await this.createCaches(options.caches);
104
- const dirs = createDirectoryStorage(this.distDir);
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);
105
135
  const instance = {
106
- runtime,
107
- handleRequest: (request) => runtime.handleRequest(request),
108
- install: () => runtime.install(),
109
- activate: () => runtime.activate(),
110
- collectStaticRoutes: (outDir, baseUrl) => runtime.collectStaticRoutes(outDir, baseUrl),
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
+ },
111
152
  get ready() {
112
- return runtime.ready;
153
+ return this.workerPool?.ready ?? false;
113
154
  },
114
155
  dispose: async () => {
115
- runtime.reset();
156
+ if (this.workerPool) {
157
+ await this.workerPool.terminate();
158
+ this.workerPool = void 0;
159
+ }
160
+ console.info("[Bun] ServiceWorker disposed");
116
161
  }
117
162
  };
118
- if (this.options.hotReload && options.hotReload !== false) {
119
- console.info("[Bun] Hot reloading enabled - native TypeScript support");
120
- const loadModule = async () => {
121
- try {
122
- runtime.reset();
123
- createServiceWorkerGlobals(runtime, { caches, dirs });
124
- globalThis.self = runtime;
125
- globalThis.addEventListener = runtime.addEventListener.bind(runtime);
126
- globalThis.removeEventListener = runtime.removeEventListener.bind(runtime);
127
- globalThis.dispatchEvent = runtime.dispatchEvent.bind(runtime);
128
- const moduleUrl = `${entryPath}?t=${Date.now()}`;
129
- await import(moduleUrl);
130
- await runtime.install();
131
- await runtime.activate();
132
- console.info("[Bun] ServiceWorker loaded successfully");
133
- } catch (error) {
134
- console.error("[Bun] Failed to load ServiceWorker:", error);
135
- }
136
- };
137
- await loadModule();
138
- } else {
139
- createServiceWorkerGlobals(runtime, { caches, dirs });
140
- globalThis.self = runtime;
141
- globalThis.addEventListener = runtime.addEventListener.bind(runtime);
142
- globalThis.removeEventListener = runtime.removeEventListener.bind(runtime);
143
- globalThis.dispatchEvent = runtime.dispatchEvent.bind(runtime);
144
- await import(entryPath);
145
- await runtime.install();
146
- await runtime.activate();
147
- }
148
163
  return instance;
149
164
  }
150
165
  /**
151
- * Get filesystem root for File System Access API
166
+ * Reload workers for hot reloading (called by CLI)
152
167
  */
153
- async getFileSystemRoot(name = "default") {
154
- return await getFileSystemRoot(name);
168
+ async reloadWorkers(version) {
169
+ if (this.workerPool) {
170
+ await this.workerPool.reloadWorkers(version);
171
+ }
155
172
  }
156
173
  /**
157
174
  * Dispose of platform resources
158
175
  */
159
176
  async dispose() {
177
+ if (this.workerPool) {
178
+ await this.workerPool.terminate();
179
+ this.workerPool = void 0;
180
+ }
160
181
  }
161
182
  };
162
183
  function createBunPlatform(options) {