@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
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @b9g/platform/single-threaded - Single-threaded ServiceWorker runtime
|
|
3
|
+
*
|
|
4
|
+
* Runs ServiceWorker code directly in the main thread without spawning workers.
|
|
5
|
+
* Used when workerCount === 1 for maximum performance (no postMessage overhead).
|
|
6
|
+
*/
|
|
7
|
+
import { CustomBucketStorage } from "@b9g/filesystem";
|
|
8
|
+
import { type ProcessedShovelConfig } from "./config.js";
|
|
9
|
+
export interface SingleThreadedRuntimeOptions {
|
|
10
|
+
/** Base directory for bucket path resolution (entrypoint directory) - REQUIRED */
|
|
11
|
+
baseDir: string;
|
|
12
|
+
/** Optional pre-created cache storage (for sharing across reloads) */
|
|
13
|
+
cacheStorage?: CacheStorage;
|
|
14
|
+
/** Optional pre-created bucket storage */
|
|
15
|
+
bucketStorage?: CustomBucketStorage;
|
|
16
|
+
/** Shovel configuration for bucket/cache settings */
|
|
17
|
+
config?: ProcessedShovelConfig;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Single-threaded ServiceWorker runtime
|
|
21
|
+
*
|
|
22
|
+
* Provides the same interface as ServiceWorkerPool but runs everything
|
|
23
|
+
* in the main thread for zero postMessage overhead.
|
|
24
|
+
*/
|
|
25
|
+
export declare class SingleThreadedRuntime {
|
|
26
|
+
#private;
|
|
27
|
+
constructor(options: SingleThreadedRuntimeOptions);
|
|
28
|
+
/**
|
|
29
|
+
* Initialize the runtime (install scope as globalThis.self)
|
|
30
|
+
*/
|
|
31
|
+
init(): Promise<void>;
|
|
32
|
+
/**
|
|
33
|
+
* Load and run a ServiceWorker entrypoint
|
|
34
|
+
*/
|
|
35
|
+
reloadWorkers(version?: number | string): Promise<void>;
|
|
36
|
+
/**
|
|
37
|
+
* Load a ServiceWorker entrypoint for the first time
|
|
38
|
+
*/
|
|
39
|
+
loadEntrypoint(entrypoint: string, version?: number | string): Promise<void>;
|
|
40
|
+
/**
|
|
41
|
+
* Handle an HTTP request
|
|
42
|
+
* This is the key method - direct call, no postMessage!
|
|
43
|
+
*/
|
|
44
|
+
handleRequest(request: Request): Promise<Response>;
|
|
45
|
+
/**
|
|
46
|
+
* Graceful shutdown
|
|
47
|
+
*/
|
|
48
|
+
terminate(): Promise<void>;
|
|
49
|
+
/**
|
|
50
|
+
* Get the number of workers (always 1 for single-threaded)
|
|
51
|
+
*/
|
|
52
|
+
get workerCount(): number;
|
|
53
|
+
/**
|
|
54
|
+
* Check if ready to handle requests
|
|
55
|
+
*/
|
|
56
|
+
get ready(): boolean;
|
|
57
|
+
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/// <reference types="./single-threaded.d.ts" />
|
|
2
|
+
// src/single-threaded.ts
|
|
3
|
+
import { getLogger } from "@logtape/logtape";
|
|
4
|
+
import { ShovelGlobalScope, ShovelServiceWorkerRegistration } from "./runtime.js";
|
|
5
|
+
import { CustomBucketStorage } from "@b9g/filesystem";
|
|
6
|
+
import { CustomCacheStorage } from "@b9g/cache";
|
|
7
|
+
import {
|
|
8
|
+
createBucketFactory,
|
|
9
|
+
createCacheFactory
|
|
10
|
+
} from "./config.js";
|
|
11
|
+
var logger = getLogger(["single-threaded"]);
|
|
12
|
+
var SingleThreadedRuntime = class {
|
|
13
|
+
#registration;
|
|
14
|
+
#scope;
|
|
15
|
+
#ready;
|
|
16
|
+
#entrypoint;
|
|
17
|
+
#config;
|
|
18
|
+
constructor(options) {
|
|
19
|
+
this.#ready = false;
|
|
20
|
+
this.#config = options.config;
|
|
21
|
+
const cacheStorage = options.cacheStorage || new CustomCacheStorage(createCacheFactory({ config: options.config }));
|
|
22
|
+
const bucketStorage = options.bucketStorage || new CustomBucketStorage(
|
|
23
|
+
createBucketFactory({ baseDir: options.baseDir, config: options.config })
|
|
24
|
+
);
|
|
25
|
+
this.#registration = new ShovelServiceWorkerRegistration();
|
|
26
|
+
this.#scope = new ShovelGlobalScope({
|
|
27
|
+
registration: this.#registration,
|
|
28
|
+
caches: cacheStorage,
|
|
29
|
+
buckets: bucketStorage
|
|
30
|
+
});
|
|
31
|
+
logger.info("SingleThreadedRuntime created", { baseDir: options.baseDir });
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Initialize the runtime (install scope as globalThis.self)
|
|
35
|
+
*/
|
|
36
|
+
async init() {
|
|
37
|
+
this.#scope.install();
|
|
38
|
+
logger.info("SingleThreadedRuntime initialized - scope installed");
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Load and run a ServiceWorker entrypoint
|
|
42
|
+
*/
|
|
43
|
+
async reloadWorkers(version) {
|
|
44
|
+
if (!this.#entrypoint) {
|
|
45
|
+
throw new Error("No entrypoint set - call loadEntrypoint first");
|
|
46
|
+
}
|
|
47
|
+
logger.info("Reloading ServiceWorker", {
|
|
48
|
+
version,
|
|
49
|
+
entrypoint: this.#entrypoint
|
|
50
|
+
});
|
|
51
|
+
const importPath = version ? `${this.#entrypoint}?v=${version}` : this.#entrypoint;
|
|
52
|
+
this.#registration._serviceWorker._setState("parsed");
|
|
53
|
+
this.#ready = false;
|
|
54
|
+
await import(importPath);
|
|
55
|
+
await this.#registration.install();
|
|
56
|
+
await this.#registration.activate();
|
|
57
|
+
this.#ready = true;
|
|
58
|
+
logger.info("ServiceWorker loaded and activated", { version });
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Load a ServiceWorker entrypoint for the first time
|
|
62
|
+
*/
|
|
63
|
+
async loadEntrypoint(entrypoint, version) {
|
|
64
|
+
this.#entrypoint = entrypoint;
|
|
65
|
+
logger.info("Loading ServiceWorker entrypoint", { entrypoint, version });
|
|
66
|
+
const importPath = version ? `${entrypoint}?v=${version}` : entrypoint;
|
|
67
|
+
await import(importPath);
|
|
68
|
+
await this.#registration.install();
|
|
69
|
+
await this.#registration.activate();
|
|
70
|
+
this.#ready = true;
|
|
71
|
+
logger.info("ServiceWorker loaded and activated", { entrypoint });
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Handle an HTTP request
|
|
75
|
+
* This is the key method - direct call, no postMessage!
|
|
76
|
+
*/
|
|
77
|
+
async handleRequest(request) {
|
|
78
|
+
if (!this.#ready) {
|
|
79
|
+
throw new Error(
|
|
80
|
+
"SingleThreadedRuntime not ready - ServiceWorker not loaded"
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
return this.#registration.handleRequest(request);
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Graceful shutdown
|
|
87
|
+
*/
|
|
88
|
+
async terminate() {
|
|
89
|
+
this.#ready = false;
|
|
90
|
+
logger.info("SingleThreadedRuntime terminated");
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Get the number of workers (always 1 for single-threaded)
|
|
94
|
+
*/
|
|
95
|
+
get workerCount() {
|
|
96
|
+
return 1;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Check if ready to handle requests
|
|
100
|
+
*/
|
|
101
|
+
get ready() {
|
|
102
|
+
return this.#ready;
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
export {
|
|
106
|
+
SingleThreadedRuntime
|
|
107
|
+
};
|
package/src/worker-pool.d.ts
CHANGED
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
2
|
+
* @b9g/platform/worker-pool - ServiceWorker pool implementation
|
|
3
|
+
*
|
|
4
|
+
* Manages a pool of workers that run the ServiceWorker runtime.
|
|
5
|
+
* Handles worker lifecycle, message passing, and request routing.
|
|
4
6
|
*/
|
|
5
|
-
import { CustomCacheStorage } from "@b9g/cache";
|
|
6
7
|
export interface WorkerPoolOptions {
|
|
7
8
|
/** Number of workers in the pool (default: 1) */
|
|
8
9
|
workerCount?: number;
|
|
9
10
|
/** Request timeout in milliseconds (default: 30000) */
|
|
10
11
|
requestTimeout?: number;
|
|
11
|
-
/** Enable hot reloading (default: true in development) */
|
|
12
|
-
hotReload?: boolean;
|
|
13
12
|
/** Working directory for file resolution */
|
|
14
13
|
cwd?: string;
|
|
15
14
|
}
|
|
@@ -23,9 +22,9 @@ export interface WorkerRequest extends WorkerMessage {
|
|
|
23
22
|
url: string;
|
|
24
23
|
method: string;
|
|
25
24
|
headers: Record<string, string>;
|
|
26
|
-
body?:
|
|
25
|
+
body?: ArrayBuffer | null;
|
|
27
26
|
};
|
|
28
|
-
|
|
27
|
+
requestID: number;
|
|
29
28
|
}
|
|
30
29
|
export interface WorkerResponse extends WorkerMessage {
|
|
31
30
|
type: "response";
|
|
@@ -33,9 +32,9 @@ export interface WorkerResponse extends WorkerMessage {
|
|
|
33
32
|
status: number;
|
|
34
33
|
statusText: string;
|
|
35
34
|
headers: Record<string, string>;
|
|
36
|
-
body:
|
|
35
|
+
body: ArrayBuffer;
|
|
37
36
|
};
|
|
38
|
-
|
|
37
|
+
requestID: number;
|
|
39
38
|
}
|
|
40
39
|
export interface WorkerLoadMessage extends WorkerMessage {
|
|
41
40
|
type: "load";
|
|
@@ -50,36 +49,27 @@ export interface WorkerErrorMessage extends WorkerMessage {
|
|
|
50
49
|
type: "error";
|
|
51
50
|
error: string;
|
|
52
51
|
stack?: string;
|
|
53
|
-
|
|
52
|
+
requestID?: number;
|
|
53
|
+
}
|
|
54
|
+
export interface WorkerInitMessage extends WorkerMessage {
|
|
55
|
+
type: "init";
|
|
56
|
+
config: any;
|
|
57
|
+
baseDir: string;
|
|
58
|
+
}
|
|
59
|
+
export interface WorkerInitializedMessage extends WorkerMessage {
|
|
60
|
+
type: "initialized";
|
|
54
61
|
}
|
|
55
62
|
/**
|
|
56
|
-
*
|
|
57
|
-
*
|
|
63
|
+
* ServiceWorkerPool - manages a pool of ServiceWorker instances
|
|
64
|
+
* Handles HTTP request/response routing, cache coordination, and hot reloading
|
|
58
65
|
*/
|
|
59
|
-
export declare class
|
|
60
|
-
private
|
|
61
|
-
|
|
62
|
-
private requestId;
|
|
63
|
-
private pendingRequests;
|
|
64
|
-
private options;
|
|
65
|
-
private cacheStorage;
|
|
66
|
-
private appEntrypoint?;
|
|
67
|
-
constructor(cacheStorage: CustomCacheStorage, options?: WorkerPoolOptions, appEntrypoint?: string);
|
|
66
|
+
export declare class ServiceWorkerPool {
|
|
67
|
+
#private;
|
|
68
|
+
constructor(options?: WorkerPoolOptions, appEntrypoint?: string, cacheStorage?: CacheStorage, config?: any);
|
|
68
69
|
/**
|
|
69
70
|
* Initialize workers (must be called after construction)
|
|
70
71
|
*/
|
|
71
72
|
init(): Promise<void>;
|
|
72
|
-
private initWorkers;
|
|
73
|
-
private createWorker;
|
|
74
|
-
private handleWorkerMessage;
|
|
75
|
-
private handleResponse;
|
|
76
|
-
private handleError;
|
|
77
|
-
private handleReady;
|
|
78
|
-
/**
|
|
79
|
-
* Platform-specific cache message handling
|
|
80
|
-
* Override this method in platform implementations for custom cache coordination
|
|
81
|
-
*/
|
|
82
|
-
protected handleCacheMessage(message: WorkerMessage): void;
|
|
83
73
|
/**
|
|
84
74
|
* Handle HTTP request using round-robin worker selection
|
|
85
75
|
*/
|