@b9g/platform 0.1.3 → 0.1.5
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 +94 -28
- package/package.json +45 -87
- package/src/config.d.ts +105 -0
- package/src/config.js +463 -0
- package/src/cookie-store.d.ts +80 -0
- package/src/cookie-store.js +231 -0
- package/src/index.d.ts +189 -9
- package/src/index.js +242 -49
- package/src/runtime.d.ts +426 -0
- package/src/runtime.js +997 -0
- package/src/single-threaded.d.ts +57 -0
- package/src/single-threaded.js +107 -0
- package/src/worker-pool.d.ts +22 -32
- package/src/worker-pool.js +214 -100
- package/src/adapter-registry.d.ts +0 -53
- package/src/adapter-registry.js +0 -71
- package/src/base-platform.d.ts +0 -49
- package/src/base-platform.js +0 -114
- package/src/detection.d.ts +0 -36
- package/src/detection.js +0 -126
- package/src/directory-storage.d.ts +0 -41
- package/src/directory-storage.js +0 -53
- package/src/filesystem.d.ts +0 -16
- package/src/filesystem.js +0 -20
- package/src/registry.d.ts +0 -31
- package/src/registry.js +0 -74
- package/src/service-worker.d.ts +0 -175
- package/src/service-worker.js +0 -245
- package/src/types.d.ts +0 -246
- package/src/types.js +0 -36
- package/src/utils.d.ts +0 -33
- package/src/utils.js +0 -139
- package/src/worker-web.js +0 -119
package/src/worker-pool.js
CHANGED
|
@@ -9,6 +9,9 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
|
|
|
9
9
|
|
|
10
10
|
// src/worker-pool.ts
|
|
11
11
|
import * as Path from "path";
|
|
12
|
+
import { existsSync } from "fs";
|
|
13
|
+
import { getLogger } from "@logtape/logtape";
|
|
14
|
+
var logger = getLogger(["worker"]);
|
|
12
15
|
function resolveWorkerScript(entrypoint) {
|
|
13
16
|
if (entrypoint) {
|
|
14
17
|
const entryDir = Path.dirname(entrypoint);
|
|
@@ -17,13 +20,12 @@ function resolveWorkerScript(entrypoint) {
|
|
|
17
20
|
if (typeof Bun !== "undefined") {
|
|
18
21
|
const file = Bun.file(bundledWorker);
|
|
19
22
|
if (file.size > 0) {
|
|
20
|
-
|
|
23
|
+
logger.info("Using bundled worker", { bundledWorker });
|
|
21
24
|
return bundledWorker;
|
|
22
25
|
}
|
|
23
26
|
} else if (typeof __require !== "undefined") {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
console.debug(`[WorkerPool] Using bundled worker: ${bundledWorker}`);
|
|
27
|
+
if (existsSync(bundledWorker)) {
|
|
28
|
+
logger.info("Using bundled worker", { bundledWorker });
|
|
27
29
|
return bundledWorker;
|
|
28
30
|
}
|
|
29
31
|
}
|
|
@@ -31,19 +33,19 @@ function resolveWorkerScript(entrypoint) {
|
|
|
31
33
|
}
|
|
32
34
|
}
|
|
33
35
|
try {
|
|
34
|
-
const
|
|
36
|
+
const workerURL = import.meta.resolve("@b9g/platform/runtime.js");
|
|
35
37
|
let workerScript;
|
|
36
|
-
if (
|
|
37
|
-
workerScript =
|
|
38
|
+
if (workerURL.startsWith("file://")) {
|
|
39
|
+
workerScript = workerURL.slice(7);
|
|
38
40
|
} else {
|
|
39
|
-
workerScript =
|
|
41
|
+
workerScript = workerURL;
|
|
40
42
|
}
|
|
41
|
-
|
|
43
|
+
logger.info("Using worker runtime script", { workerScript });
|
|
42
44
|
return workerScript;
|
|
43
45
|
} catch (error) {
|
|
44
|
-
const bundledPath = entrypoint ? Path.join(Path.dirname(entrypoint), "
|
|
46
|
+
const bundledPath = entrypoint ? Path.join(Path.dirname(entrypoint), "runtime.js") : "runtime.js";
|
|
45
47
|
throw new Error(
|
|
46
|
-
`Could not resolve
|
|
48
|
+
`Could not resolve runtime.js. Checked bundled path: ${bundledPath} and package: @b9g/platform/runtime.js. Error: ${error instanceof Error ? error.message : String(error)}`
|
|
47
49
|
);
|
|
48
50
|
}
|
|
49
51
|
}
|
|
@@ -55,13 +57,18 @@ async function createWebWorker(workerScript) {
|
|
|
55
57
|
if (isNodeJs) {
|
|
56
58
|
try {
|
|
57
59
|
const { Worker: NodeWebWorker } = await import("@b9g/node-webworker");
|
|
58
|
-
|
|
59
|
-
return new NodeWebWorker(workerScript, {
|
|
60
|
+
logger.info("Using @b9g/node-webworker shim for Node.js", {});
|
|
61
|
+
return new NodeWebWorker(workerScript, {
|
|
62
|
+
type: "module"
|
|
63
|
+
});
|
|
60
64
|
} catch (shimError) {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
+
logger.error(
|
|
66
|
+
"MISSING WEB STANDARD: Node.js lacks native Web Worker support",
|
|
67
|
+
{
|
|
68
|
+
canonicalIssue: "https://github.com/nodejs/node/issues/43583",
|
|
69
|
+
message: "This is a basic web standard from 2009 - help push for implementation!"
|
|
70
|
+
}
|
|
71
|
+
);
|
|
65
72
|
throw new Error(`\u274C Web Worker not available on Node.js
|
|
66
73
|
|
|
67
74
|
\u{1F517} Node.js doesn't implement the Web Worker standard yet.
|
|
@@ -85,22 +92,30 @@ Please check your runtime version and configuration.
|
|
|
85
92
|
|
|
86
93
|
\u{1F4DA} Web Worker standard: https://developer.mozilla.org/en-US/docs/Web/API/Worker`);
|
|
87
94
|
}
|
|
88
|
-
var
|
|
89
|
-
workers
|
|
90
|
-
currentWorker
|
|
91
|
-
|
|
92
|
-
pendingRequests
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
appEntrypoint;
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
95
|
+
var ServiceWorkerPool = class {
|
|
96
|
+
#workers;
|
|
97
|
+
#currentWorker;
|
|
98
|
+
#requestID;
|
|
99
|
+
#pendingRequests;
|
|
100
|
+
#pendingWorkerInit;
|
|
101
|
+
#options;
|
|
102
|
+
#appEntrypoint;
|
|
103
|
+
#cacheStorage;
|
|
104
|
+
// CustomCacheStorage for cache coordination
|
|
105
|
+
#config;
|
|
106
|
+
// ShovelConfig from config.ts
|
|
107
|
+
constructor(options = {}, appEntrypoint, cacheStorage, config) {
|
|
108
|
+
this.#workers = [];
|
|
109
|
+
this.#currentWorker = 0;
|
|
110
|
+
this.#requestID = 0;
|
|
111
|
+
this.#pendingRequests = /* @__PURE__ */ new Map();
|
|
112
|
+
this.#pendingWorkerInit = /* @__PURE__ */ new Map();
|
|
113
|
+
this.#appEntrypoint = appEntrypoint;
|
|
114
|
+
this.#cacheStorage = cacheStorage;
|
|
115
|
+
this.#config = config || {};
|
|
116
|
+
this.#options = {
|
|
100
117
|
workerCount: 1,
|
|
101
118
|
requestTimeout: 3e4,
|
|
102
|
-
hotReload: process.env.NODE_ENV !== "production",
|
|
103
|
-
cwd: process.cwd(),
|
|
104
119
|
...options
|
|
105
120
|
};
|
|
106
121
|
}
|
|
@@ -108,47 +123,106 @@ var WorkerPool = class {
|
|
|
108
123
|
* Initialize workers (must be called after construction)
|
|
109
124
|
*/
|
|
110
125
|
async init() {
|
|
111
|
-
await this
|
|
126
|
+
await this.#initWorkers();
|
|
112
127
|
}
|
|
113
|
-
async initWorkers() {
|
|
114
|
-
for (let i = 0; i < this
|
|
115
|
-
await this
|
|
128
|
+
async #initWorkers() {
|
|
129
|
+
for (let i = 0; i < this.#options.workerCount; i++) {
|
|
130
|
+
await this.#createWorker();
|
|
116
131
|
}
|
|
117
132
|
}
|
|
118
|
-
async createWorker() {
|
|
119
|
-
const workerScript = resolveWorkerScript(this
|
|
133
|
+
async #createWorker() {
|
|
134
|
+
const workerScript = resolveWorkerScript(this.#appEntrypoint);
|
|
120
135
|
const worker = await createWebWorker(workerScript);
|
|
136
|
+
const workerReadyPromise = new Promise((resolve) => {
|
|
137
|
+
this.#pendingWorkerInit.set(worker, {
|
|
138
|
+
workerReady: resolve
|
|
139
|
+
});
|
|
140
|
+
});
|
|
121
141
|
worker.addEventListener("message", (event) => {
|
|
122
|
-
this
|
|
142
|
+
this.#handleWorkerMessage(worker, event.data || event);
|
|
123
143
|
});
|
|
124
|
-
worker.addEventListener("error", (
|
|
125
|
-
|
|
144
|
+
worker.addEventListener("error", (event) => {
|
|
145
|
+
logger.error("Worker error", {
|
|
146
|
+
message: event.message || event.error?.message,
|
|
147
|
+
filename: event.filename,
|
|
148
|
+
lineno: event.lineno,
|
|
149
|
+
colno: event.colno,
|
|
150
|
+
error: event.error,
|
|
151
|
+
stack: event.error?.stack
|
|
152
|
+
});
|
|
153
|
+
});
|
|
154
|
+
this.#workers.push(worker);
|
|
155
|
+
logger.info("Waiting for worker-ready signal");
|
|
156
|
+
await workerReadyPromise;
|
|
157
|
+
logger.info("Received worker-ready signal");
|
|
158
|
+
const initializedPromise = new Promise((resolve) => {
|
|
159
|
+
const pending = this.#pendingWorkerInit.get(worker) || {};
|
|
160
|
+
pending.initialized = resolve;
|
|
161
|
+
this.#pendingWorkerInit.set(worker, pending);
|
|
126
162
|
});
|
|
127
|
-
this
|
|
163
|
+
if (!this.#appEntrypoint) {
|
|
164
|
+
throw new Error(
|
|
165
|
+
"ServiceWorkerPool requires an entrypoint to derive baseDir"
|
|
166
|
+
);
|
|
167
|
+
}
|
|
168
|
+
const baseDir = Path.dirname(this.#appEntrypoint);
|
|
169
|
+
const initMessage = {
|
|
170
|
+
type: "init",
|
|
171
|
+
config: this.#config,
|
|
172
|
+
baseDir
|
|
173
|
+
};
|
|
174
|
+
logger.info("Sending init message", { config: this.#config, baseDir });
|
|
175
|
+
worker.postMessage(initMessage);
|
|
176
|
+
logger.info("Sent init message, waiting for initialized response");
|
|
177
|
+
await initializedPromise;
|
|
178
|
+
logger.info("Received initialized response");
|
|
179
|
+
this.#pendingWorkerInit.delete(worker);
|
|
128
180
|
return worker;
|
|
129
181
|
}
|
|
130
|
-
handleWorkerMessage(message) {
|
|
131
|
-
|
|
132
|
-
|
|
182
|
+
#handleWorkerMessage(worker, message) {
|
|
183
|
+
logger.debug("Worker message received", { type: message.type });
|
|
184
|
+
const pending = this.#pendingWorkerInit.get(worker);
|
|
185
|
+
if (message.type === "worker-ready" && pending?.workerReady) {
|
|
186
|
+
pending.workerReady();
|
|
187
|
+
} else if (message.type === "initialized" && pending?.initialized) {
|
|
188
|
+
pending.initialized();
|
|
133
189
|
return;
|
|
134
190
|
}
|
|
135
191
|
switch (message.type) {
|
|
136
192
|
case "response":
|
|
137
|
-
this
|
|
193
|
+
this.#handleResponse(message);
|
|
138
194
|
break;
|
|
139
195
|
case "error":
|
|
140
|
-
this
|
|
196
|
+
this.#handleError(message);
|
|
141
197
|
break;
|
|
142
198
|
case "ready":
|
|
143
199
|
case "worker-ready":
|
|
144
|
-
this
|
|
200
|
+
this.#handleReady(message);
|
|
201
|
+
break;
|
|
202
|
+
case "initialized":
|
|
145
203
|
break;
|
|
146
204
|
default:
|
|
147
|
-
|
|
205
|
+
if (message.type?.startsWith("cache:")) {
|
|
206
|
+
logger.debug("Cache message detected", {
|
|
207
|
+
type: message.type,
|
|
208
|
+
hasStorage: !!this.#cacheStorage
|
|
209
|
+
});
|
|
210
|
+
if (this.#cacheStorage) {
|
|
211
|
+
const handleMessage = this.#cacheStorage.handleMessage;
|
|
212
|
+
logger.debug("handleMessage check", {
|
|
213
|
+
hasMethod: typeof handleMessage === "function"
|
|
214
|
+
});
|
|
215
|
+
if (typeof handleMessage === "function") {
|
|
216
|
+
logger.debug("Calling handleMessage");
|
|
217
|
+
void handleMessage.call(this.#cacheStorage, worker, message);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
break;
|
|
148
222
|
}
|
|
149
223
|
}
|
|
150
|
-
handleResponse(message) {
|
|
151
|
-
const pending = this
|
|
224
|
+
#handleResponse(message) {
|
|
225
|
+
const pending = this.#pendingRequests.get(message.requestID);
|
|
152
226
|
if (pending) {
|
|
153
227
|
const response = new Response(message.response.body, {
|
|
154
228
|
status: message.response.status,
|
|
@@ -156,116 +230,156 @@ var WorkerPool = class {
|
|
|
156
230
|
headers: message.response.headers
|
|
157
231
|
});
|
|
158
232
|
pending.resolve(response);
|
|
159
|
-
this
|
|
233
|
+
this.#pendingRequests.delete(message.requestID);
|
|
160
234
|
}
|
|
161
235
|
}
|
|
162
|
-
handleError(message) {
|
|
163
|
-
|
|
164
|
-
|
|
236
|
+
#handleError(message) {
|
|
237
|
+
logger.error("Worker error message received", {
|
|
238
|
+
error: message.error,
|
|
239
|
+
stack: message.stack,
|
|
240
|
+
requestID: message.requestID
|
|
241
|
+
});
|
|
242
|
+
if (message.requestID) {
|
|
243
|
+
const pending = this.#pendingRequests.get(message.requestID);
|
|
165
244
|
if (pending) {
|
|
166
245
|
pending.reject(new Error(message.error));
|
|
167
|
-
this
|
|
246
|
+
this.#pendingRequests.delete(message.requestID);
|
|
168
247
|
}
|
|
169
248
|
} else {
|
|
170
|
-
|
|
249
|
+
logger.error("Worker error", { error: message.error });
|
|
171
250
|
}
|
|
172
251
|
}
|
|
173
|
-
handleReady(message) {
|
|
252
|
+
#handleReady(message) {
|
|
174
253
|
if (message.type === "ready") {
|
|
175
|
-
|
|
254
|
+
logger.info("ServiceWorker ready", { version: message.version });
|
|
176
255
|
} else if (message.type === "worker-ready") {
|
|
177
|
-
|
|
256
|
+
logger.info("Worker initialized", {});
|
|
178
257
|
}
|
|
179
258
|
}
|
|
180
|
-
/**
|
|
181
|
-
* Platform-specific cache message handling
|
|
182
|
-
* Override this method in platform implementations for custom cache coordination
|
|
183
|
-
*/
|
|
184
|
-
handleCacheMessage(message) {
|
|
185
|
-
}
|
|
186
259
|
/**
|
|
187
260
|
* Handle HTTP request using round-robin worker selection
|
|
188
261
|
*/
|
|
189
262
|
async handleRequest(request) {
|
|
190
|
-
const worker = this
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
263
|
+
const worker = this.#workers[this.#currentWorker];
|
|
264
|
+
logger.info("Dispatching to worker", {
|
|
265
|
+
workerIndex: this.#currentWorker + 1,
|
|
266
|
+
totalWorkers: this.#workers.length
|
|
267
|
+
});
|
|
268
|
+
this.#currentWorker = (this.#currentWorker + 1) % this.#workers.length;
|
|
269
|
+
const requestID = ++this.#requestID;
|
|
196
270
|
return new Promise((resolve, reject) => {
|
|
197
|
-
this
|
|
198
|
-
|
|
199
|
-
type: "request",
|
|
200
|
-
request: {
|
|
201
|
-
url: request.url,
|
|
202
|
-
method: request.method,
|
|
203
|
-
headers: Object.fromEntries(request.headers.entries()),
|
|
204
|
-
body: request.body
|
|
205
|
-
},
|
|
206
|
-
requestId
|
|
207
|
-
};
|
|
208
|
-
worker.postMessage(workerRequest);
|
|
271
|
+
this.#pendingRequests.set(requestID, { resolve, reject });
|
|
272
|
+
this.#sendRequest(worker, request, requestID).catch(reject);
|
|
209
273
|
setTimeout(() => {
|
|
210
|
-
if (this
|
|
211
|
-
this
|
|
274
|
+
if (this.#pendingRequests.has(requestID)) {
|
|
275
|
+
this.#pendingRequests.delete(requestID);
|
|
212
276
|
reject(new Error("Request timeout"));
|
|
213
277
|
}
|
|
214
|
-
}, this
|
|
278
|
+
}, this.#options.requestTimeout);
|
|
215
279
|
});
|
|
216
280
|
}
|
|
281
|
+
/**
|
|
282
|
+
* Send request to worker (async helper to avoid async promise executor)
|
|
283
|
+
*/
|
|
284
|
+
async #sendRequest(worker, request, requestID) {
|
|
285
|
+
let body = null;
|
|
286
|
+
if (request.body) {
|
|
287
|
+
body = await request.arrayBuffer();
|
|
288
|
+
}
|
|
289
|
+
const workerRequest = {
|
|
290
|
+
type: "request",
|
|
291
|
+
request: {
|
|
292
|
+
url: request.url,
|
|
293
|
+
method: request.method,
|
|
294
|
+
headers: Object.fromEntries(request.headers.entries()),
|
|
295
|
+
body
|
|
296
|
+
},
|
|
297
|
+
requestID
|
|
298
|
+
};
|
|
299
|
+
if (body) {
|
|
300
|
+
worker.postMessage(workerRequest, [body]);
|
|
301
|
+
} else {
|
|
302
|
+
worker.postMessage(workerRequest);
|
|
303
|
+
}
|
|
304
|
+
}
|
|
217
305
|
/**
|
|
218
306
|
* Reload ServiceWorker with new version (hot reload simulation)
|
|
219
307
|
*/
|
|
220
308
|
async reloadWorkers(version = Date.now()) {
|
|
221
|
-
|
|
222
|
-
const loadPromises = this
|
|
223
|
-
return new Promise((resolve) => {
|
|
309
|
+
logger.info("Reloading ServiceWorker", { version });
|
|
310
|
+
const loadPromises = this.#workers.map((worker) => {
|
|
311
|
+
return new Promise((resolve, reject) => {
|
|
312
|
+
let timeoutId;
|
|
313
|
+
const cleanup = () => {
|
|
314
|
+
worker.removeEventListener("message", handleReady);
|
|
315
|
+
worker.removeEventListener("error", handleError);
|
|
316
|
+
if (timeoutId) {
|
|
317
|
+
clearTimeout(timeoutId);
|
|
318
|
+
}
|
|
319
|
+
};
|
|
224
320
|
const handleReady = (event) => {
|
|
225
321
|
const message = event.data || event;
|
|
226
322
|
if (message.type === "ready" && message.version === version) {
|
|
227
|
-
|
|
323
|
+
cleanup();
|
|
228
324
|
resolve();
|
|
229
325
|
}
|
|
230
326
|
};
|
|
231
|
-
|
|
327
|
+
const handleError = (error) => {
|
|
328
|
+
cleanup();
|
|
329
|
+
const errorMsg = error?.error?.message || error?.message || JSON.stringify(error);
|
|
330
|
+
reject(new Error(`Worker failed to load ServiceWorker: ${errorMsg}`));
|
|
331
|
+
};
|
|
332
|
+
timeoutId = setTimeout(() => {
|
|
333
|
+
cleanup();
|
|
334
|
+
reject(
|
|
335
|
+
new Error(
|
|
336
|
+
`Worker failed to load ServiceWorker within 30000ms (version ${version})`
|
|
337
|
+
)
|
|
338
|
+
);
|
|
339
|
+
}, 3e4);
|
|
340
|
+
logger.info("Sending load message", {
|
|
232
341
|
version,
|
|
233
|
-
entrypoint: this
|
|
342
|
+
entrypoint: this.#appEntrypoint
|
|
234
343
|
});
|
|
235
344
|
worker.addEventListener("message", handleReady);
|
|
345
|
+
worker.addEventListener("error", handleError);
|
|
236
346
|
const loadMessage = {
|
|
237
347
|
type: "load",
|
|
238
348
|
version,
|
|
239
|
-
entrypoint: this
|
|
349
|
+
entrypoint: this.#appEntrypoint
|
|
240
350
|
};
|
|
351
|
+
logger.debug("[WorkerPool] Sending load message", {
|
|
352
|
+
entrypoint: this.#appEntrypoint,
|
|
353
|
+
version
|
|
354
|
+
});
|
|
241
355
|
worker.postMessage(loadMessage);
|
|
242
356
|
});
|
|
243
357
|
});
|
|
244
358
|
await Promise.all(loadPromises);
|
|
245
|
-
|
|
359
|
+
logger.info("All workers reloaded", { version });
|
|
246
360
|
}
|
|
247
361
|
/**
|
|
248
362
|
* Graceful shutdown of all workers
|
|
249
363
|
*/
|
|
250
364
|
async terminate() {
|
|
251
|
-
const terminatePromises = this
|
|
365
|
+
const terminatePromises = this.#workers.map((worker) => worker.terminate());
|
|
252
366
|
await Promise.allSettled(terminatePromises);
|
|
253
|
-
this
|
|
254
|
-
this
|
|
367
|
+
this.#workers = [];
|
|
368
|
+
this.#pendingRequests.clear();
|
|
255
369
|
}
|
|
256
370
|
/**
|
|
257
371
|
* Get the number of active workers
|
|
258
372
|
*/
|
|
259
373
|
get workerCount() {
|
|
260
|
-
return this
|
|
374
|
+
return this.#workers.length;
|
|
261
375
|
}
|
|
262
376
|
/**
|
|
263
377
|
* Check if the pool is ready to handle requests
|
|
264
378
|
*/
|
|
265
379
|
get ready() {
|
|
266
|
-
return this
|
|
380
|
+
return this.#workers.length > 0;
|
|
267
381
|
}
|
|
268
382
|
};
|
|
269
383
|
export {
|
|
270
|
-
|
|
384
|
+
ServiceWorkerPool
|
|
271
385
|
};
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Blessed alias registry for official Shovel adapters
|
|
3
|
-
* Maps short names to full package names for CLI convenience
|
|
4
|
-
*/
|
|
5
|
-
export interface AdapterModule {
|
|
6
|
-
createCache?: (config: any) => any;
|
|
7
|
-
createFileSystem?: (config: any) => any;
|
|
8
|
-
}
|
|
9
|
-
/**
|
|
10
|
-
* Official blessed aliases for cache adapters
|
|
11
|
-
*/
|
|
12
|
-
export declare const CACHE_ALIASES: {
|
|
13
|
-
readonly memory: "@b9g/cache";
|
|
14
|
-
readonly redis: "@b9g/cache-redis";
|
|
15
|
-
readonly kv: "@b9g/cache-kv";
|
|
16
|
-
readonly cloudflare: "@b9g/cache/cloudflare";
|
|
17
|
-
};
|
|
18
|
-
/**
|
|
19
|
-
* Official blessed aliases for filesystem adapters
|
|
20
|
-
*/
|
|
21
|
-
export declare const FILESYSTEM_ALIASES: {
|
|
22
|
-
readonly memory: "@b9g/filesystem";
|
|
23
|
-
readonly fs: "@b9g/filesystem/node";
|
|
24
|
-
readonly "bun-s3": "@b9g/filesystem/bun-s3";
|
|
25
|
-
readonly s3: "@b9g/filesystem-s3";
|
|
26
|
-
readonly r2: "@b9g/filesystem-r2";
|
|
27
|
-
};
|
|
28
|
-
/**
|
|
29
|
-
* Resolve a cache adapter name to a package name
|
|
30
|
-
* @param name - Blessed alias (memory, redis) or full package name (@custom/cache)
|
|
31
|
-
* @returns Full package name
|
|
32
|
-
*/
|
|
33
|
-
export declare function resolveCacheAdapter(name: string): string;
|
|
34
|
-
/**
|
|
35
|
-
* Resolve a filesystem adapter name to a package name
|
|
36
|
-
* @param name - Blessed alias (memory, s3) or full package name (@custom/filesystem)
|
|
37
|
-
* @returns Full package name
|
|
38
|
-
*/
|
|
39
|
-
export declare function resolveFilesystemAdapter(name: string): string;
|
|
40
|
-
/**
|
|
41
|
-
* Dynamically load a cache adapter
|
|
42
|
-
* @param name - Adapter name (blessed alias or package name)
|
|
43
|
-
* @param config - Adapter configuration
|
|
44
|
-
* @returns Cache instance
|
|
45
|
-
*/
|
|
46
|
-
export declare function loadCacheAdapter(name: string, config?: any): Promise<any>;
|
|
47
|
-
/**
|
|
48
|
-
* Dynamically load a filesystem adapter
|
|
49
|
-
* @param name - Adapter name (blessed alias or package name)
|
|
50
|
-
* @param config - Adapter configuration
|
|
51
|
-
* @returns Filesystem adapter instance
|
|
52
|
-
*/
|
|
53
|
-
export declare function loadFilesystemAdapter(name: string, config?: any): Promise<any>;
|
package/src/adapter-registry.js
DELETED
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
/// <reference types="./adapter-registry.d.ts" />
|
|
2
|
-
// src/adapter-registry.ts
|
|
3
|
-
var CACHE_ALIASES = {
|
|
4
|
-
memory: "@b9g/cache",
|
|
5
|
-
redis: "@b9g/cache-redis",
|
|
6
|
-
kv: "@b9g/cache-kv",
|
|
7
|
-
cloudflare: "@b9g/cache/cloudflare"
|
|
8
|
-
};
|
|
9
|
-
var FILESYSTEM_ALIASES = {
|
|
10
|
-
memory: "@b9g/filesystem",
|
|
11
|
-
fs: "@b9g/filesystem/node",
|
|
12
|
-
"bun-s3": "@b9g/filesystem/bun-s3",
|
|
13
|
-
s3: "@b9g/filesystem-s3",
|
|
14
|
-
r2: "@b9g/filesystem-r2"
|
|
15
|
-
};
|
|
16
|
-
function resolveCacheAdapter(name) {
|
|
17
|
-
if (name.startsWith("@")) {
|
|
18
|
-
return name;
|
|
19
|
-
}
|
|
20
|
-
if (name in CACHE_ALIASES) {
|
|
21
|
-
return CACHE_ALIASES[name];
|
|
22
|
-
}
|
|
23
|
-
throw new Error(`Unknown cache adapter: ${name}. Available aliases: ${Object.keys(CACHE_ALIASES).join(", ")} or use full package name like @custom/cache`);
|
|
24
|
-
}
|
|
25
|
-
function resolveFilesystemAdapter(name) {
|
|
26
|
-
if (name.startsWith("@")) {
|
|
27
|
-
return name;
|
|
28
|
-
}
|
|
29
|
-
if (name in FILESYSTEM_ALIASES) {
|
|
30
|
-
return FILESYSTEM_ALIASES[name];
|
|
31
|
-
}
|
|
32
|
-
throw new Error(`Unknown filesystem adapter: ${name}. Available aliases: ${Object.keys(FILESYSTEM_ALIASES).join(", ")} or use full package name like @custom/filesystem`);
|
|
33
|
-
}
|
|
34
|
-
async function loadCacheAdapter(name, config = {}) {
|
|
35
|
-
const packageName = resolveCacheAdapter(name);
|
|
36
|
-
try {
|
|
37
|
-
const module = await import(packageName);
|
|
38
|
-
if (!module.createCache) {
|
|
39
|
-
throw new Error(`Package ${packageName} does not export a createCache function`);
|
|
40
|
-
}
|
|
41
|
-
return module.createCache(config);
|
|
42
|
-
} catch (error) {
|
|
43
|
-
if (error instanceof Error && error.message.includes("Cannot resolve module")) {
|
|
44
|
-
throw new Error(`Cache adapter '${name}' requires: npm install ${packageName}`);
|
|
45
|
-
}
|
|
46
|
-
throw error;
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
async function loadFilesystemAdapter(name, config = {}) {
|
|
50
|
-
const packageName = resolveFilesystemAdapter(name);
|
|
51
|
-
try {
|
|
52
|
-
const module = await import(packageName);
|
|
53
|
-
if (!module.createFileSystem) {
|
|
54
|
-
throw new Error(`Package ${packageName} does not export a createFileSystem function`);
|
|
55
|
-
}
|
|
56
|
-
return module.createFileSystem(config);
|
|
57
|
-
} catch (error) {
|
|
58
|
-
if (error instanceof Error && error.message.includes("Cannot resolve module")) {
|
|
59
|
-
throw new Error(`Filesystem adapter '${name}' requires: npm install ${packageName}`);
|
|
60
|
-
}
|
|
61
|
-
throw error;
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
export {
|
|
65
|
-
CACHE_ALIASES,
|
|
66
|
-
FILESYSTEM_ALIASES,
|
|
67
|
-
loadCacheAdapter,
|
|
68
|
-
loadFilesystemAdapter,
|
|
69
|
-
resolveCacheAdapter,
|
|
70
|
-
resolveFilesystemAdapter
|
|
71
|
-
};
|
package/src/base-platform.d.ts
DELETED
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Base platform implementation with dynamic adapter loading
|
|
3
|
-
* Provides common functionality for all platform implementations
|
|
4
|
-
*/
|
|
5
|
-
import type { Platform, PlatformConfig, CacheConfig, CacheBackendConfig, FilesystemConfig } from "./types.js";
|
|
6
|
-
import type { CacheStorage } from "@b9g/cache/cache-storage";
|
|
7
|
-
/**
|
|
8
|
-
* Base platform class with shared adapter loading logic
|
|
9
|
-
* Platform implementations extend this and provide platform-specific methods
|
|
10
|
-
*/
|
|
11
|
-
export declare abstract class BasePlatform implements Platform {
|
|
12
|
-
protected config: PlatformConfig;
|
|
13
|
-
constructor(config?: PlatformConfig);
|
|
14
|
-
abstract readonly name: string;
|
|
15
|
-
abstract loadServiceWorker(entrypoint: string, options?: any): Promise<any>;
|
|
16
|
-
abstract createServer(handler: any, options?: any): any;
|
|
17
|
-
abstract getDirectoryHandle(name: string): Promise<FileSystemDirectoryHandle>;
|
|
18
|
-
/**
|
|
19
|
-
* Create cache storage with dynamic adapter loading
|
|
20
|
-
* Uses platform defaults when specific cache types aren't configured
|
|
21
|
-
*/
|
|
22
|
-
createCaches(config?: CacheConfig): Promise<CacheStorage>;
|
|
23
|
-
/**
|
|
24
|
-
* Get platform-specific default cache configuration
|
|
25
|
-
* Subclasses override this to provide optimal defaults for their runtime
|
|
26
|
-
*/
|
|
27
|
-
protected getDefaultCacheConfig(): CacheConfig;
|
|
28
|
-
/**
|
|
29
|
-
* Merge user config with platform defaults
|
|
30
|
-
*/
|
|
31
|
-
protected mergeCacheConfig(userConfig?: CacheConfig): CacheConfig;
|
|
32
|
-
/**
|
|
33
|
-
* Build CacheStorage instance with dynamic adapter loading
|
|
34
|
-
*/
|
|
35
|
-
protected buildCacheStorage(config: CacheConfig): Promise<CacheStorage>;
|
|
36
|
-
/**
|
|
37
|
-
* Load a single cache instance using dynamic import
|
|
38
|
-
*/
|
|
39
|
-
protected loadCacheInstance(config: CacheBackendConfig): Promise<any>;
|
|
40
|
-
/**
|
|
41
|
-
* Load filesystem adapter using dynamic import
|
|
42
|
-
*/
|
|
43
|
-
protected loadFilesystemAdapter(config?: FilesystemConfig): Promise<any>;
|
|
44
|
-
/**
|
|
45
|
-
* Get platform-specific default filesystem configuration
|
|
46
|
-
* Subclasses override this to provide optimal defaults for their runtime
|
|
47
|
-
*/
|
|
48
|
-
protected getDefaultFilesystemConfig(): FilesystemConfig;
|
|
49
|
-
}
|