@b9g/platform 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 +94 -28
- package/package.json +46 -86
- package/src/config.d.ts +125 -0
- package/src/config.js +517 -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/service-worker.js
DELETED
|
@@ -1,245 +0,0 @@
|
|
|
1
|
-
/// <reference types="./service-worker.d.ts" />
|
|
2
|
-
// src/service-worker.ts
|
|
3
|
-
var ExtendableEvent = class extends Event {
|
|
4
|
-
promises = [];
|
|
5
|
-
pendingPromises;
|
|
6
|
-
constructor(type, pendingPromises) {
|
|
7
|
-
super(type);
|
|
8
|
-
this.pendingPromises = pendingPromises;
|
|
9
|
-
}
|
|
10
|
-
waitUntil(promise) {
|
|
11
|
-
this.promises.push(promise);
|
|
12
|
-
this.pendingPromises.add(promise);
|
|
13
|
-
promise.finally(() => this.pendingPromises.delete(promise));
|
|
14
|
-
}
|
|
15
|
-
getPromises() {
|
|
16
|
-
return [...this.promises];
|
|
17
|
-
}
|
|
18
|
-
};
|
|
19
|
-
var FetchEvent = class extends ExtendableEvent {
|
|
20
|
-
request;
|
|
21
|
-
responsePromise = null;
|
|
22
|
-
responded = false;
|
|
23
|
-
constructor(request, pendingPromises) {
|
|
24
|
-
super("fetch", pendingPromises);
|
|
25
|
-
this.request = request;
|
|
26
|
-
}
|
|
27
|
-
respondWith(response) {
|
|
28
|
-
if (this.responded) {
|
|
29
|
-
throw new Error("respondWith() already called");
|
|
30
|
-
}
|
|
31
|
-
this.responded = true;
|
|
32
|
-
this.responsePromise = Promise.resolve(response);
|
|
33
|
-
}
|
|
34
|
-
getResponse() {
|
|
35
|
-
return this.responsePromise;
|
|
36
|
-
}
|
|
37
|
-
hasResponded() {
|
|
38
|
-
return this.responded;
|
|
39
|
-
}
|
|
40
|
-
};
|
|
41
|
-
var InstallEvent = class extends ExtendableEvent {
|
|
42
|
-
constructor(pendingPromises) {
|
|
43
|
-
super("install", pendingPromises);
|
|
44
|
-
}
|
|
45
|
-
};
|
|
46
|
-
var ActivateEvent = class extends ExtendableEvent {
|
|
47
|
-
constructor(pendingPromises) {
|
|
48
|
-
super("activate", pendingPromises);
|
|
49
|
-
}
|
|
50
|
-
};
|
|
51
|
-
var ServiceWorkerRuntime = class extends EventTarget {
|
|
52
|
-
pendingPromises = /* @__PURE__ */ new Set();
|
|
53
|
-
isInstalled = false;
|
|
54
|
-
isActivated = false;
|
|
55
|
-
eventListeners = /* @__PURE__ */ new Map();
|
|
56
|
-
constructor() {
|
|
57
|
-
super();
|
|
58
|
-
}
|
|
59
|
-
addEventListener(type, listener) {
|
|
60
|
-
super.addEventListener(type, listener);
|
|
61
|
-
if (!this.eventListeners.has(type)) {
|
|
62
|
-
this.eventListeners.set(type, []);
|
|
63
|
-
}
|
|
64
|
-
this.eventListeners.get(type).push(listener);
|
|
65
|
-
}
|
|
66
|
-
removeEventListener(type, listener) {
|
|
67
|
-
super.removeEventListener(type, listener);
|
|
68
|
-
if (this.eventListeners.has(type)) {
|
|
69
|
-
const listeners = this.eventListeners.get(type);
|
|
70
|
-
const index = listeners.indexOf(listener);
|
|
71
|
-
if (index > -1) {
|
|
72
|
-
listeners.splice(index, 1);
|
|
73
|
-
if (listeners.length === 0) {
|
|
74
|
-
this.eventListeners.delete(type);
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
/**
|
|
80
|
-
* Create a fetch event and dispatch it
|
|
81
|
-
*/
|
|
82
|
-
async handleRequest(request) {
|
|
83
|
-
if (!this.isActivated) {
|
|
84
|
-
throw new Error("ServiceWorker not activated");
|
|
85
|
-
}
|
|
86
|
-
return new Promise((resolve, reject) => {
|
|
87
|
-
const event = new FetchEvent(request, this.pendingPromises);
|
|
88
|
-
process.nextTick(() => {
|
|
89
|
-
this.dispatchEvent(event);
|
|
90
|
-
const promises = event.getPromises();
|
|
91
|
-
if (promises.length > 0) {
|
|
92
|
-
Promise.allSettled(promises).catch(console.error);
|
|
93
|
-
}
|
|
94
|
-
});
|
|
95
|
-
setTimeout(() => {
|
|
96
|
-
if (event.hasResponded()) {
|
|
97
|
-
const responsePromise = event.getResponse();
|
|
98
|
-
responsePromise.then(resolve).catch(reject);
|
|
99
|
-
} else {
|
|
100
|
-
reject(new Error("No response provided for fetch event"));
|
|
101
|
-
}
|
|
102
|
-
}, 0);
|
|
103
|
-
});
|
|
104
|
-
}
|
|
105
|
-
/**
|
|
106
|
-
* Install the ServiceWorker
|
|
107
|
-
*/
|
|
108
|
-
async install() {
|
|
109
|
-
if (this.isInstalled)
|
|
110
|
-
return;
|
|
111
|
-
return new Promise((resolve, reject) => {
|
|
112
|
-
const event = new InstallEvent(this.pendingPromises);
|
|
113
|
-
process.nextTick(() => {
|
|
114
|
-
this.dispatchEvent(event);
|
|
115
|
-
const promises = event.getPromises();
|
|
116
|
-
if (promises.length === 0) {
|
|
117
|
-
this.isInstalled = true;
|
|
118
|
-
resolve();
|
|
119
|
-
} else {
|
|
120
|
-
Promise.all(promises).then(() => {
|
|
121
|
-
this.isInstalled = true;
|
|
122
|
-
resolve();
|
|
123
|
-
}).catch(reject);
|
|
124
|
-
}
|
|
125
|
-
});
|
|
126
|
-
});
|
|
127
|
-
}
|
|
128
|
-
/**
|
|
129
|
-
* Activate the ServiceWorker
|
|
130
|
-
*/
|
|
131
|
-
async activate() {
|
|
132
|
-
if (!this.isInstalled) {
|
|
133
|
-
throw new Error("ServiceWorker must be installed before activation");
|
|
134
|
-
}
|
|
135
|
-
if (this.isActivated)
|
|
136
|
-
return;
|
|
137
|
-
return new Promise((resolve, reject) => {
|
|
138
|
-
const event = new ActivateEvent(this.pendingPromises);
|
|
139
|
-
process.nextTick(() => {
|
|
140
|
-
this.dispatchEvent(event);
|
|
141
|
-
const promises = event.getPromises();
|
|
142
|
-
if (promises.length === 0) {
|
|
143
|
-
this.isActivated = true;
|
|
144
|
-
resolve();
|
|
145
|
-
} else {
|
|
146
|
-
Promise.all(promises).then(() => {
|
|
147
|
-
this.isActivated = true;
|
|
148
|
-
resolve();
|
|
149
|
-
}).catch(reject);
|
|
150
|
-
}
|
|
151
|
-
});
|
|
152
|
-
});
|
|
153
|
-
}
|
|
154
|
-
/**
|
|
155
|
-
* Check if ready to handle requests
|
|
156
|
-
*/
|
|
157
|
-
get ready() {
|
|
158
|
-
return this.isInstalled && this.isActivated;
|
|
159
|
-
}
|
|
160
|
-
/**
|
|
161
|
-
* Wait for all pending promises to resolve
|
|
162
|
-
*/
|
|
163
|
-
async waitForPending() {
|
|
164
|
-
if (this.pendingPromises.size > 0) {
|
|
165
|
-
await Promise.allSettled([...this.pendingPromises]);
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
/**
|
|
169
|
-
* Reset the ServiceWorker state (for hot reloading)
|
|
170
|
-
*/
|
|
171
|
-
reset() {
|
|
172
|
-
this.isInstalled = false;
|
|
173
|
-
this.isActivated = false;
|
|
174
|
-
this.pendingPromises.clear();
|
|
175
|
-
for (const [type, listeners] of this.eventListeners) {
|
|
176
|
-
for (const listener of listeners) {
|
|
177
|
-
super.removeEventListener(type, listener);
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
this.eventListeners.clear();
|
|
181
|
-
}
|
|
182
|
-
};
|
|
183
|
-
function createServiceWorkerGlobals(runtime, options = {}) {
|
|
184
|
-
if (options.caches) {
|
|
185
|
-
runtime.caches = options.caches;
|
|
186
|
-
}
|
|
187
|
-
if (options.buckets) {
|
|
188
|
-
runtime.buckets = options.buckets;
|
|
189
|
-
}
|
|
190
|
-
const skipWaiting = async () => {
|
|
191
|
-
if (options.isDevelopment && options.hotReload) {
|
|
192
|
-
console.info("[ServiceWorker] skipWaiting() - triggering hot reload");
|
|
193
|
-
await options.hotReload();
|
|
194
|
-
} else if (!options.isDevelopment) {
|
|
195
|
-
console.info("[ServiceWorker] skipWaiting() - production graceful restart not implemented");
|
|
196
|
-
}
|
|
197
|
-
};
|
|
198
|
-
const clients = {
|
|
199
|
-
async claim() {
|
|
200
|
-
},
|
|
201
|
-
async get(id) {
|
|
202
|
-
return void 0;
|
|
203
|
-
},
|
|
204
|
-
async matchAll(options2) {
|
|
205
|
-
return [];
|
|
206
|
-
},
|
|
207
|
-
async openWindow(url) {
|
|
208
|
-
return null;
|
|
209
|
-
}
|
|
210
|
-
};
|
|
211
|
-
const globals = {
|
|
212
|
-
self: runtime,
|
|
213
|
-
addEventListener: runtime.addEventListener.bind(runtime),
|
|
214
|
-
removeEventListener: runtime.removeEventListener.bind(runtime),
|
|
215
|
-
dispatchEvent: runtime.dispatchEvent.bind(runtime),
|
|
216
|
-
// ServiceWorker-specific globals with proper implementations
|
|
217
|
-
skipWaiting,
|
|
218
|
-
clients,
|
|
219
|
-
// Platform resources
|
|
220
|
-
...options.buckets && { buckets: options.buckets },
|
|
221
|
-
...options.caches && { caches: options.caches },
|
|
222
|
-
// Standard globals
|
|
223
|
-
console,
|
|
224
|
-
setTimeout,
|
|
225
|
-
clearTimeout,
|
|
226
|
-
setInterval,
|
|
227
|
-
clearInterval,
|
|
228
|
-
fetch,
|
|
229
|
-
Request,
|
|
230
|
-
Response,
|
|
231
|
-
Headers,
|
|
232
|
-
URL,
|
|
233
|
-
URLSearchParams
|
|
234
|
-
};
|
|
235
|
-
Object.assign(globalThis, globals);
|
|
236
|
-
return globals;
|
|
237
|
-
}
|
|
238
|
-
export {
|
|
239
|
-
ActivateEvent,
|
|
240
|
-
ExtendableEvent,
|
|
241
|
-
FetchEvent,
|
|
242
|
-
InstallEvent,
|
|
243
|
-
ServiceWorkerRuntime,
|
|
244
|
-
createServiceWorkerGlobals
|
|
245
|
-
};
|
package/src/types.d.ts
DELETED
|
@@ -1,246 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Core Platform interface and configuration types for Shovel deployment adapters
|
|
3
|
-
*/
|
|
4
|
-
import type { CacheStorage } from "@b9g/cache/cache-storage";
|
|
5
|
-
export { loadCacheAdapter, loadFilesystemAdapter, resolveCacheAdapter, resolveFilesystemAdapter, CACHE_ALIASES, FILESYSTEM_ALIASES, } from "./adapter-registry.js";
|
|
6
|
-
export { BasePlatform } from "./base-platform.js";
|
|
7
|
-
export { detectRuntime, detectDevelopmentPlatform, detectPlatforms, getBestPlatformDetection, resolvePlatform, createPlatform, displayPlatformInfo, } from "./detection.js";
|
|
8
|
-
/**
|
|
9
|
-
* Cache backend configuration
|
|
10
|
-
* Type can be a blessed alias or full package name
|
|
11
|
-
*/
|
|
12
|
-
export interface CacheBackendConfig {
|
|
13
|
-
/** Cache backend type - blessed alias (memory, redis, kv) or package name (@custom/cache) */
|
|
14
|
-
type?: string;
|
|
15
|
-
/** Maximum number of entries (for memory/LRU caches) */
|
|
16
|
-
maxEntries?: number;
|
|
17
|
-
/** Time-to-live in milliseconds or string format (e.g., '5m', '1h') */
|
|
18
|
-
ttl?: number | string;
|
|
19
|
-
/** Directory for filesystem cache */
|
|
20
|
-
dir?: string;
|
|
21
|
-
/** Redis connection string */
|
|
22
|
-
url?: string;
|
|
23
|
-
/** Custom cache factory function */
|
|
24
|
-
factory?: () => any;
|
|
25
|
-
}
|
|
26
|
-
/**
|
|
27
|
-
* Cache configuration for different cache types
|
|
28
|
-
*/
|
|
29
|
-
export interface CacheConfig {
|
|
30
|
-
/** Page/HTML cache configuration */
|
|
31
|
-
pages?: CacheBackendConfig;
|
|
32
|
-
/** API response cache configuration */
|
|
33
|
-
api?: CacheBackendConfig;
|
|
34
|
-
/** Static file cache configuration */
|
|
35
|
-
static?: CacheBackendConfig;
|
|
36
|
-
/** Custom named caches */
|
|
37
|
-
[name: string]: CacheBackendConfig | undefined;
|
|
38
|
-
}
|
|
39
|
-
/**
|
|
40
|
-
* Static file serving configuration
|
|
41
|
-
*/
|
|
42
|
-
export interface StaticConfig {
|
|
43
|
-
/** Public URL path prefix */
|
|
44
|
-
publicPath?: string;
|
|
45
|
-
/** Output directory for built assets */
|
|
46
|
-
outputDir?: string;
|
|
47
|
-
/** Asset manifest file path */
|
|
48
|
-
manifest?: string;
|
|
49
|
-
/** Development mode (serve from source) */
|
|
50
|
-
dev?: boolean;
|
|
51
|
-
/** Source directory for development */
|
|
52
|
-
sourceDir?: string;
|
|
53
|
-
/** Cache configuration for static files */
|
|
54
|
-
cache?: {
|
|
55
|
-
name?: string;
|
|
56
|
-
ttl?: string | number;
|
|
57
|
-
};
|
|
58
|
-
}
|
|
59
|
-
/**
|
|
60
|
-
* CORS configuration
|
|
61
|
-
*/
|
|
62
|
-
export interface CorsConfig {
|
|
63
|
-
/** Allowed origins */
|
|
64
|
-
origin?: boolean | string | string[] | RegExp | ((origin: string) => boolean);
|
|
65
|
-
/** Allowed methods */
|
|
66
|
-
methods?: string[];
|
|
67
|
-
/** Allowed headers */
|
|
68
|
-
allowedHeaders?: string[];
|
|
69
|
-
/** Exposed headers */
|
|
70
|
-
exposedHeaders?: string[];
|
|
71
|
-
/** Allow credentials */
|
|
72
|
-
credentials?: boolean;
|
|
73
|
-
/** Preflight cache duration */
|
|
74
|
-
maxAge?: number;
|
|
75
|
-
}
|
|
76
|
-
/**
|
|
77
|
-
* Filesystem adapter configuration
|
|
78
|
-
*/
|
|
79
|
-
export interface FilesystemConfig {
|
|
80
|
-
/** Filesystem adapter type - blessed alias (memory, s3, r2) or package name (@custom/fs) */
|
|
81
|
-
type?: string;
|
|
82
|
-
/** Region for cloud storage */
|
|
83
|
-
region?: string;
|
|
84
|
-
/** Access credentials */
|
|
85
|
-
credentials?: {
|
|
86
|
-
accessKeyId?: string;
|
|
87
|
-
secretAccessKey?: string;
|
|
88
|
-
token?: string;
|
|
89
|
-
};
|
|
90
|
-
/** Factory function for creating directory storage */
|
|
91
|
-
factory?: any;
|
|
92
|
-
/** Additional adapter-specific options */
|
|
93
|
-
[key: string]: any;
|
|
94
|
-
}
|
|
95
|
-
/**
|
|
96
|
-
* Platform configuration from CLI flags
|
|
97
|
-
*/
|
|
98
|
-
export interface PlatformConfig {
|
|
99
|
-
/** Cache configuration */
|
|
100
|
-
caches?: CacheConfig;
|
|
101
|
-
/** Filesystem adapter configuration */
|
|
102
|
-
filesystem?: FilesystemConfig;
|
|
103
|
-
}
|
|
104
|
-
/**
|
|
105
|
-
* Server options for platform implementations
|
|
106
|
-
*/
|
|
107
|
-
export interface ServerOptions {
|
|
108
|
-
/** Port to listen on */
|
|
109
|
-
port?: number;
|
|
110
|
-
/** Host to bind to */
|
|
111
|
-
host?: string;
|
|
112
|
-
/** Hostname for URL generation */
|
|
113
|
-
hostname?: string;
|
|
114
|
-
/** Enable compression */
|
|
115
|
-
compression?: boolean;
|
|
116
|
-
/** CORS configuration */
|
|
117
|
-
cors?: CorsConfig;
|
|
118
|
-
/** Custom headers to add to all responses */
|
|
119
|
-
headers?: Record<string, string>;
|
|
120
|
-
/** Request timeout in milliseconds */
|
|
121
|
-
timeout?: number;
|
|
122
|
-
/** Development mode settings */
|
|
123
|
-
development?: {
|
|
124
|
-
/** Enable hot reloading */
|
|
125
|
-
hotReload?: boolean;
|
|
126
|
-
/** Source maps support */
|
|
127
|
-
sourceMaps?: boolean;
|
|
128
|
-
/** Verbose logging */
|
|
129
|
-
verbose?: boolean;
|
|
130
|
-
};
|
|
131
|
-
}
|
|
132
|
-
/**
|
|
133
|
-
* Request handler function (Web Fetch API compatible)
|
|
134
|
-
*/
|
|
135
|
-
export type Handler = (request: Request, context?: any) => Promise<Response> | Response;
|
|
136
|
-
/**
|
|
137
|
-
* ServiceWorker entrypoint options
|
|
138
|
-
*/
|
|
139
|
-
export interface ServiceWorkerOptions {
|
|
140
|
-
/** Enable hot reloading */
|
|
141
|
-
hotReload?: boolean;
|
|
142
|
-
/** Cache configuration to pass to platform event */
|
|
143
|
-
caches?: CacheConfig;
|
|
144
|
-
/** Additional context to provide */
|
|
145
|
-
context?: any;
|
|
146
|
-
}
|
|
147
|
-
/**
|
|
148
|
-
* ServiceWorker instance returned by platform
|
|
149
|
-
*/
|
|
150
|
-
export interface ServiceWorkerInstance {
|
|
151
|
-
/** The ServiceWorker runtime */
|
|
152
|
-
runtime: any;
|
|
153
|
-
/** Handle HTTP request */
|
|
154
|
-
handleRequest(request: Request): Promise<Response>;
|
|
155
|
-
/** Install the ServiceWorker */
|
|
156
|
-
install(): Promise<void>;
|
|
157
|
-
/** Activate the ServiceWorker */
|
|
158
|
-
activate(): Promise<void>;
|
|
159
|
-
/** Collect routes for static generation */
|
|
160
|
-
collectStaticRoutes(outDir: string, baseUrl?: string): Promise<string[]>;
|
|
161
|
-
/** Check if ready to handle requests */
|
|
162
|
-
readonly ready: boolean;
|
|
163
|
-
/** Dispose of resources */
|
|
164
|
-
dispose(): Promise<void>;
|
|
165
|
-
}
|
|
166
|
-
/**
|
|
167
|
-
* Server instance returned by platform.createServer()
|
|
168
|
-
*/
|
|
169
|
-
export interface Server {
|
|
170
|
-
/** Start listening for requests */
|
|
171
|
-
listen(): Promise<void>;
|
|
172
|
-
/** Stop the server */
|
|
173
|
-
close(): Promise<void>;
|
|
174
|
-
/** Get server address information */
|
|
175
|
-
address(): {
|
|
176
|
-
port: number;
|
|
177
|
-
host: string;
|
|
178
|
-
};
|
|
179
|
-
/** Get server URL */
|
|
180
|
-
readonly url: string;
|
|
181
|
-
/** Whether server is ready to accept requests */
|
|
182
|
-
readonly ready: boolean;
|
|
183
|
-
}
|
|
184
|
-
/**
|
|
185
|
-
* Platform interface - ServiceWorker entrypoint loader for JavaScript runtimes
|
|
186
|
-
*
|
|
187
|
-
* The core responsibility: "Take a ServiceWorker-style app file and make it run in this environment"
|
|
188
|
-
*/
|
|
189
|
-
export interface Platform {
|
|
190
|
-
/**
|
|
191
|
-
* Platform name for identification
|
|
192
|
-
*/
|
|
193
|
-
readonly name: string;
|
|
194
|
-
/**
|
|
195
|
-
* THE MAIN JOB - Load and run a ServiceWorker-style entrypoint
|
|
196
|
-
* This is where all the platform-specific complexity lives
|
|
197
|
-
*/
|
|
198
|
-
loadServiceWorker(entrypoint: string, options?: ServiceWorkerOptions): Promise<ServiceWorkerInstance>;
|
|
199
|
-
/**
|
|
200
|
-
* SUPPORTING UTILITY - Create cache storage with platform-optimized backends
|
|
201
|
-
* Automatically selects optimal cache types when not specified:
|
|
202
|
-
* - Node.js: filesystem for persistence, memory for API
|
|
203
|
-
* - Cloudflare: KV for persistence, memory for fast access
|
|
204
|
-
* - Bun: filesystem with optimized writes
|
|
205
|
-
*/
|
|
206
|
-
createCaches(config?: CacheConfig): Promise<CacheStorage>;
|
|
207
|
-
/**
|
|
208
|
-
* SUPPORTING UTILITY - Create bucket storage with platform-optimized backends
|
|
209
|
-
* Uses factory pattern to route bucket names to different filesystem adapters
|
|
210
|
-
*/
|
|
211
|
-
createBuckets(config?: FilesystemConfig): Promise<any>;
|
|
212
|
-
/**
|
|
213
|
-
* SUPPORTING UTILITY - Create server instance for this platform
|
|
214
|
-
*/
|
|
215
|
-
createServer(handler: Handler, options?: ServerOptions): Server;
|
|
216
|
-
/**
|
|
217
|
-
* SUPPORTING UTILITY - Get filesystem directory handle
|
|
218
|
-
* Maps directly to cloud storage buckets (S3, R2) or local directories
|
|
219
|
-
* @param name - Directory name. Use "" for root directory
|
|
220
|
-
*/
|
|
221
|
-
getDirectoryHandle(name: string): Promise<FileSystemDirectoryHandle>;
|
|
222
|
-
}
|
|
223
|
-
/**
|
|
224
|
-
* Platform detection result
|
|
225
|
-
*/
|
|
226
|
-
export interface PlatformDetection {
|
|
227
|
-
/** Detected platform name */
|
|
228
|
-
platform: string;
|
|
229
|
-
/** Confidence level (0-1) */
|
|
230
|
-
confidence: number;
|
|
231
|
-
/** Detection reasons */
|
|
232
|
-
reasons: string[];
|
|
233
|
-
}
|
|
234
|
-
/**
|
|
235
|
-
* Platform registry for auto-detection
|
|
236
|
-
*/
|
|
237
|
-
export interface PlatformRegistry {
|
|
238
|
-
/** Register a platform implementation */
|
|
239
|
-
register(name: string, platform: Platform): void;
|
|
240
|
-
/** Get platform by name */
|
|
241
|
-
get(name: string): Platform | undefined;
|
|
242
|
-
/** Detect current platform */
|
|
243
|
-
detect(): PlatformDetection;
|
|
244
|
-
/** Get all registered platforms */
|
|
245
|
-
list(): string[];
|
|
246
|
-
}
|
package/src/types.js
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
/// <reference types="./types.d.ts" />
|
|
2
|
-
// src/types.ts
|
|
3
|
-
import {
|
|
4
|
-
loadCacheAdapter,
|
|
5
|
-
loadFilesystemAdapter,
|
|
6
|
-
resolveCacheAdapter,
|
|
7
|
-
resolveFilesystemAdapter,
|
|
8
|
-
CACHE_ALIASES,
|
|
9
|
-
FILESYSTEM_ALIASES
|
|
10
|
-
} from "./adapter-registry.js";
|
|
11
|
-
import { BasePlatform } from "./base-platform.js";
|
|
12
|
-
import {
|
|
13
|
-
detectRuntime,
|
|
14
|
-
detectDevelopmentPlatform,
|
|
15
|
-
detectPlatforms,
|
|
16
|
-
getBestPlatformDetection,
|
|
17
|
-
resolvePlatform,
|
|
18
|
-
createPlatform,
|
|
19
|
-
displayPlatformInfo
|
|
20
|
-
} from "./detection.js";
|
|
21
|
-
export {
|
|
22
|
-
BasePlatform,
|
|
23
|
-
CACHE_ALIASES,
|
|
24
|
-
FILESYSTEM_ALIASES,
|
|
25
|
-
createPlatform,
|
|
26
|
-
detectDevelopmentPlatform,
|
|
27
|
-
detectPlatforms,
|
|
28
|
-
detectRuntime,
|
|
29
|
-
displayPlatformInfo,
|
|
30
|
-
getBestPlatformDetection,
|
|
31
|
-
loadCacheAdapter,
|
|
32
|
-
loadFilesystemAdapter,
|
|
33
|
-
resolveCacheAdapter,
|
|
34
|
-
resolveFilesystemAdapter,
|
|
35
|
-
resolvePlatform
|
|
36
|
-
};
|
package/src/utils.d.ts
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Utility functions for platform implementations
|
|
3
|
-
*/
|
|
4
|
-
import type { CacheBackendConfig } from "./types.js";
|
|
5
|
-
/**
|
|
6
|
-
* Parse TTL string to milliseconds
|
|
7
|
-
*/
|
|
8
|
-
export declare function parseTTL(ttl: string | number | undefined): number | undefined;
|
|
9
|
-
/**
|
|
10
|
-
* Merge cache configurations with defaults
|
|
11
|
-
*/
|
|
12
|
-
export declare function mergeCacheConfig(userConfig: CacheBackendConfig | undefined, defaults: Partial<CacheBackendConfig>): CacheBackendConfig;
|
|
13
|
-
/**
|
|
14
|
-
* Validate cache backend configuration
|
|
15
|
-
*/
|
|
16
|
-
export declare function validateCacheConfig(config: CacheBackendConfig): void;
|
|
17
|
-
/**
|
|
18
|
-
* Create CORS headers from configuration
|
|
19
|
-
*/
|
|
20
|
-
export declare function createCorsHeaders(corsConfig: any, // CorsConfig but avoiding circular import
|
|
21
|
-
request: Request): Headers;
|
|
22
|
-
/**
|
|
23
|
-
* Merge headers from multiple sources
|
|
24
|
-
*/
|
|
25
|
-
export declare function mergeHeaders(...headerSources: (Headers | Record<string, string> | undefined)[]): Headers;
|
|
26
|
-
/**
|
|
27
|
-
* Check if request is a preflight CORS request
|
|
28
|
-
*/
|
|
29
|
-
export declare function isPreflightRequest(request: Request): boolean;
|
|
30
|
-
/**
|
|
31
|
-
* Create a preflight response
|
|
32
|
-
*/
|
|
33
|
-
export declare function createPreflightResponse(corsConfig: any, request: Request): Response;
|
package/src/utils.js
DELETED
|
@@ -1,139 +0,0 @@
|
|
|
1
|
-
/// <reference types="./utils.d.ts" />
|
|
2
|
-
// src/utils.ts
|
|
3
|
-
function parseTTL(ttl) {
|
|
4
|
-
if (typeof ttl === "number") {
|
|
5
|
-
return ttl;
|
|
6
|
-
}
|
|
7
|
-
if (typeof ttl !== "string") {
|
|
8
|
-
return void 0;
|
|
9
|
-
}
|
|
10
|
-
const match = ttl.match(/^(\d+)\s*(ms|s|m|h|d)?$/);
|
|
11
|
-
if (!match) {
|
|
12
|
-
throw new Error(
|
|
13
|
-
`Invalid TTL format: ${ttl}. Use format like '5m', '1h', '30s'`
|
|
14
|
-
);
|
|
15
|
-
}
|
|
16
|
-
const value = parseInt(match[1], 10);
|
|
17
|
-
const unit = match[2] || "ms";
|
|
18
|
-
const multipliers = {
|
|
19
|
-
ms: 1,
|
|
20
|
-
s: 1e3,
|
|
21
|
-
m: 60 * 1e3,
|
|
22
|
-
h: 60 * 60 * 1e3,
|
|
23
|
-
d: 24 * 60 * 60 * 1e3
|
|
24
|
-
};
|
|
25
|
-
return value * multipliers[unit];
|
|
26
|
-
}
|
|
27
|
-
function mergeCacheConfig(userConfig, defaults) {
|
|
28
|
-
return {
|
|
29
|
-
type: "memory",
|
|
30
|
-
...defaults,
|
|
31
|
-
...userConfig
|
|
32
|
-
};
|
|
33
|
-
}
|
|
34
|
-
function validateCacheConfig(config) {
|
|
35
|
-
const validTypes = ["memory", "filesystem", "redis", "kv", "custom"];
|
|
36
|
-
if (!validTypes.includes(config.type)) {
|
|
37
|
-
throw new Error(
|
|
38
|
-
`Invalid cache type '${config.type}'. Must be one of: ${validTypes.join(", ")}`
|
|
39
|
-
);
|
|
40
|
-
}
|
|
41
|
-
if (config.type === "filesystem" && !config.dir) {
|
|
42
|
-
throw new Error("Filesystem cache requires a directory (dir) option");
|
|
43
|
-
}
|
|
44
|
-
if (config.type === "redis" && !config.url) {
|
|
45
|
-
throw new Error("Redis cache requires a connection URL (url) option");
|
|
46
|
-
}
|
|
47
|
-
if (config.type === "custom" && !config.factory) {
|
|
48
|
-
throw new Error("Custom cache requires a factory function");
|
|
49
|
-
}
|
|
50
|
-
if (config.maxEntries !== void 0 && config.maxEntries <= 0) {
|
|
51
|
-
throw new Error("maxEntries must be a positive number");
|
|
52
|
-
}
|
|
53
|
-
if (config.ttl !== void 0) {
|
|
54
|
-
try {
|
|
55
|
-
parseTTL(config.ttl);
|
|
56
|
-
} catch (error) {
|
|
57
|
-
throw new Error(`Invalid TTL configuration: ${error.message}`);
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
function createCorsHeaders(corsConfig, request) {
|
|
62
|
-
const headers = new Headers();
|
|
63
|
-
if (!corsConfig) {
|
|
64
|
-
return headers;
|
|
65
|
-
}
|
|
66
|
-
const origin = request.headers.get("origin");
|
|
67
|
-
if (corsConfig.origin === true) {
|
|
68
|
-
headers.set("Access-Control-Allow-Origin", "*");
|
|
69
|
-
} else if (typeof corsConfig.origin === "string") {
|
|
70
|
-
headers.set("Access-Control-Allow-Origin", corsConfig.origin);
|
|
71
|
-
} else if (Array.isArray(corsConfig.origin)) {
|
|
72
|
-
if (origin && corsConfig.origin.includes(origin)) {
|
|
73
|
-
headers.set("Access-Control-Allow-Origin", origin);
|
|
74
|
-
}
|
|
75
|
-
} else if (corsConfig.origin instanceof RegExp) {
|
|
76
|
-
if (origin && corsConfig.origin.test(origin)) {
|
|
77
|
-
headers.set("Access-Control-Allow-Origin", origin);
|
|
78
|
-
}
|
|
79
|
-
} else if (typeof corsConfig.origin === "function") {
|
|
80
|
-
if (origin && corsConfig.origin(origin)) {
|
|
81
|
-
headers.set("Access-Control-Allow-Origin", origin);
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
if (corsConfig.methods) {
|
|
85
|
-
headers.set("Access-Control-Allow-Methods", corsConfig.methods.join(", "));
|
|
86
|
-
}
|
|
87
|
-
if (corsConfig.allowedHeaders) {
|
|
88
|
-
headers.set(
|
|
89
|
-
"Access-Control-Allow-Headers",
|
|
90
|
-
corsConfig.allowedHeaders.join(", ")
|
|
91
|
-
);
|
|
92
|
-
}
|
|
93
|
-
if (corsConfig.exposedHeaders) {
|
|
94
|
-
headers.set(
|
|
95
|
-
"Access-Control-Expose-Headers",
|
|
96
|
-
corsConfig.exposedHeaders.join(", ")
|
|
97
|
-
);
|
|
98
|
-
}
|
|
99
|
-
if (corsConfig.credentials) {
|
|
100
|
-
headers.set("Access-Control-Allow-Credentials", "true");
|
|
101
|
-
}
|
|
102
|
-
if (corsConfig.maxAge !== void 0) {
|
|
103
|
-
headers.set("Access-Control-Max-Age", corsConfig.maxAge.toString());
|
|
104
|
-
}
|
|
105
|
-
return headers;
|
|
106
|
-
}
|
|
107
|
-
function mergeHeaders(...headerSources) {
|
|
108
|
-
const result = new Headers();
|
|
109
|
-
for (const source of headerSources) {
|
|
110
|
-
if (!source)
|
|
111
|
-
continue;
|
|
112
|
-
if (source instanceof Headers) {
|
|
113
|
-
for (const [key, value] of source.entries()) {
|
|
114
|
-
result.set(key, value);
|
|
115
|
-
}
|
|
116
|
-
} else {
|
|
117
|
-
for (const [key, value] of Object.entries(source)) {
|
|
118
|
-
result.set(key, value);
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
return result;
|
|
123
|
-
}
|
|
124
|
-
function isPreflightRequest(request) {
|
|
125
|
-
return request.method === "OPTIONS" && request.headers.has("access-control-request-method");
|
|
126
|
-
}
|
|
127
|
-
function createPreflightResponse(corsConfig, request) {
|
|
128
|
-
const headers = createCorsHeaders(corsConfig, request);
|
|
129
|
-
return new Response(null, { status: 204, headers });
|
|
130
|
-
}
|
|
131
|
-
export {
|
|
132
|
-
createCorsHeaders,
|
|
133
|
-
createPreflightResponse,
|
|
134
|
-
isPreflightRequest,
|
|
135
|
-
mergeCacheConfig,
|
|
136
|
-
mergeHeaders,
|
|
137
|
-
parseTTL,
|
|
138
|
-
validateCacheConfig
|
|
139
|
-
};
|