@b9g/platform 0.1.0
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 +109 -0
- package/src/adapter-registry.d.ts +53 -0
- package/src/adapter-registry.js +71 -0
- package/src/base-platform.d.ts +50 -0
- package/src/base-platform.js +114 -0
- package/src/detection.d.ts +36 -0
- package/src/detection.js +126 -0
- package/src/directory-storage.d.ts +41 -0
- package/src/directory-storage.js +78 -0
- package/src/filesystem.d.ts +8 -0
- package/src/filesystem.js +10 -0
- package/src/index.d.ts +14 -0
- package/src/index.js +62 -0
- package/src/registry.d.ts +31 -0
- package/src/registry.js +74 -0
- package/src/service-worker.d.ts +149 -0
- package/src/service-worker.js +183 -0
- package/src/types.d.ts +239 -0
- package/src/types.js +36 -0
- package/src/utils.d.ts +33 -0
- package/src/utils.js +139 -0
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/// <reference types="./filesystem.d.ts" />
|
|
2
|
+
// src/filesystem.ts
|
|
3
|
+
import { getPlatformAsync } from "./registry.js";
|
|
4
|
+
async function getFileSystemRoot(name) {
|
|
5
|
+
const platform = await getPlatformAsync();
|
|
6
|
+
return await platform.getFileSystemRoot(name);
|
|
7
|
+
}
|
|
8
|
+
export {
|
|
9
|
+
getFileSystemRoot
|
|
10
|
+
};
|
package/src/index.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @b9g/platform - Platform interface for ServiceWorker entrypoint loading
|
|
3
|
+
*
|
|
4
|
+
* Platform = "ServiceWorker entrypoint loader for JavaScript runtimes"
|
|
5
|
+
* Core responsibility: Take a ServiceWorker-style app file and make it run in this environment.
|
|
6
|
+
*/
|
|
7
|
+
export type { Platform, CacheConfig, CacheBackendConfig, ServerOptions, CorsConfig, Handler, Server, ServiceWorkerOptions, ServiceWorkerInstance, PlatformDetection, PlatformRegistry, } from "./types.js";
|
|
8
|
+
export { BasePlatform } from "./types.js";
|
|
9
|
+
export { ServiceWorkerRuntime, createServiceWorkerGlobals, type ShovelFetchEvent, type ShovelInstallEvent, type ShovelActivateEvent, type ShovelStaticEvent, type DirectoryStorage, } from "./service-worker.js";
|
|
10
|
+
export { PlatformDirectoryStorage, createDirectoryStorage, } from "./directory-storage.js";
|
|
11
|
+
export { platformRegistry, detectPlatform, getPlatform, getPlatformAsync, } from "./registry.js";
|
|
12
|
+
export { detectRuntime, detectDevelopmentPlatform, detectPlatforms, getBestPlatformDetection, resolvePlatform, createPlatform, displayPlatformInfo, } from "./detection.js";
|
|
13
|
+
export { parseTTL, mergeCacheConfig, validateCacheConfig, createCorsHeaders, mergeHeaders, isPreflightRequest, createPreflightResponse, } from "./utils.js";
|
|
14
|
+
export { getFileSystemRoot } from "./filesystem.js";
|
package/src/index.js
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/// <reference types="./index.d.ts" />
|
|
2
|
+
// src/index.ts
|
|
3
|
+
import { BasePlatform } from "./types.js";
|
|
4
|
+
import {
|
|
5
|
+
ServiceWorkerRuntime,
|
|
6
|
+
createServiceWorkerGlobals
|
|
7
|
+
} from "./service-worker.js";
|
|
8
|
+
import {
|
|
9
|
+
PlatformDirectoryStorage,
|
|
10
|
+
createDirectoryStorage
|
|
11
|
+
} from "./directory-storage.js";
|
|
12
|
+
import {
|
|
13
|
+
platformRegistry,
|
|
14
|
+
detectPlatform,
|
|
15
|
+
getPlatform,
|
|
16
|
+
getPlatformAsync
|
|
17
|
+
} from "./registry.js";
|
|
18
|
+
import {
|
|
19
|
+
detectRuntime,
|
|
20
|
+
detectDevelopmentPlatform,
|
|
21
|
+
detectPlatforms,
|
|
22
|
+
getBestPlatformDetection,
|
|
23
|
+
resolvePlatform,
|
|
24
|
+
createPlatform,
|
|
25
|
+
displayPlatformInfo
|
|
26
|
+
} from "./detection.js";
|
|
27
|
+
import {
|
|
28
|
+
parseTTL,
|
|
29
|
+
mergeCacheConfig,
|
|
30
|
+
validateCacheConfig,
|
|
31
|
+
createCorsHeaders,
|
|
32
|
+
mergeHeaders,
|
|
33
|
+
isPreflightRequest,
|
|
34
|
+
createPreflightResponse
|
|
35
|
+
} from "./utils.js";
|
|
36
|
+
import { getFileSystemRoot } from "./filesystem.js";
|
|
37
|
+
export {
|
|
38
|
+
BasePlatform,
|
|
39
|
+
PlatformDirectoryStorage,
|
|
40
|
+
ServiceWorkerRuntime,
|
|
41
|
+
createCorsHeaders,
|
|
42
|
+
createDirectoryStorage,
|
|
43
|
+
createPlatform,
|
|
44
|
+
createPreflightResponse,
|
|
45
|
+
createServiceWorkerGlobals,
|
|
46
|
+
detectDevelopmentPlatform,
|
|
47
|
+
detectPlatform,
|
|
48
|
+
detectPlatforms,
|
|
49
|
+
detectRuntime,
|
|
50
|
+
displayPlatformInfo,
|
|
51
|
+
getBestPlatformDetection,
|
|
52
|
+
getFileSystemRoot,
|
|
53
|
+
getPlatform,
|
|
54
|
+
getPlatformAsync,
|
|
55
|
+
isPreflightRequest,
|
|
56
|
+
mergeCacheConfig,
|
|
57
|
+
mergeHeaders,
|
|
58
|
+
parseTTL,
|
|
59
|
+
platformRegistry,
|
|
60
|
+
resolvePlatform,
|
|
61
|
+
validateCacheConfig
|
|
62
|
+
};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Platform registry for auto-detection and management
|
|
3
|
+
*/
|
|
4
|
+
import type { Platform, PlatformDetection, PlatformRegistry } from "./types.js";
|
|
5
|
+
/**
|
|
6
|
+
* Global platform registry
|
|
7
|
+
*/
|
|
8
|
+
declare class DefaultPlatformRegistry implements PlatformRegistry {
|
|
9
|
+
private platforms;
|
|
10
|
+
register(name: string, platform: Platform): void;
|
|
11
|
+
get(name: string): Platform | undefined;
|
|
12
|
+
detect(): PlatformDetection;
|
|
13
|
+
list(): string[];
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Global platform registry instance
|
|
17
|
+
*/
|
|
18
|
+
export declare const platformRegistry: DefaultPlatformRegistry;
|
|
19
|
+
/**
|
|
20
|
+
* Auto-detect and return the appropriate platform
|
|
21
|
+
*/
|
|
22
|
+
export declare function detectPlatform(): Platform | null;
|
|
23
|
+
/**
|
|
24
|
+
* Get platform by name with error handling
|
|
25
|
+
*/
|
|
26
|
+
export declare function getPlatform(name?: string): Platform;
|
|
27
|
+
/**
|
|
28
|
+
* Get platform with async auto-registration fallback
|
|
29
|
+
*/
|
|
30
|
+
export declare function getPlatformAsync(name?: string): Promise<Platform>;
|
|
31
|
+
export {};
|
package/src/registry.js
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/// <reference types="./registry.d.ts" />
|
|
2
|
+
// src/registry.ts
|
|
3
|
+
import { getBestPlatformDetection } from "./detection.js";
|
|
4
|
+
var DefaultPlatformRegistry = class {
|
|
5
|
+
platforms = /* @__PURE__ */ new Map();
|
|
6
|
+
register(name, platform) {
|
|
7
|
+
this.platforms.set(name, platform);
|
|
8
|
+
}
|
|
9
|
+
get(name) {
|
|
10
|
+
return this.platforms.get(name);
|
|
11
|
+
}
|
|
12
|
+
detect() {
|
|
13
|
+
return getBestPlatformDetection();
|
|
14
|
+
}
|
|
15
|
+
list() {
|
|
16
|
+
return Array.from(this.platforms.keys());
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
var platformRegistry = new DefaultPlatformRegistry();
|
|
20
|
+
function detectPlatform() {
|
|
21
|
+
const detection = platformRegistry.detect();
|
|
22
|
+
if (detection.confidence > 0.5) {
|
|
23
|
+
const platform = platformRegistry.get(detection.platform);
|
|
24
|
+
if (platform) {
|
|
25
|
+
return platform;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
function getPlatform(name) {
|
|
31
|
+
if (name) {
|
|
32
|
+
const platform = platformRegistry.get(name);
|
|
33
|
+
if (!platform) {
|
|
34
|
+
const available = platformRegistry.list();
|
|
35
|
+
throw new Error(
|
|
36
|
+
`Platform '${name}' not found. Available platforms: ${available.join(", ")}`
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
return platform;
|
|
40
|
+
}
|
|
41
|
+
const detected = detectPlatform();
|
|
42
|
+
if (!detected) {
|
|
43
|
+
throw new Error(
|
|
44
|
+
"No platform could be auto-detected. Please register a platform manually or specify a platform name."
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
return detected;
|
|
48
|
+
}
|
|
49
|
+
async function getPlatformAsync(name) {
|
|
50
|
+
if (name) {
|
|
51
|
+
const platform = platformRegistry.get(name);
|
|
52
|
+
if (!platform) {
|
|
53
|
+
const available = platformRegistry.list();
|
|
54
|
+
throw new Error(
|
|
55
|
+
`Platform '${name}' not found. Available platforms: ${available.join(", ")}`
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
return platform;
|
|
59
|
+
}
|
|
60
|
+
const detected = detectPlatform();
|
|
61
|
+
if (!detected) {
|
|
62
|
+
const { createNodePlatform } = await import("@b9g/platform-node");
|
|
63
|
+
const nodePlatform = createNodePlatform();
|
|
64
|
+
platformRegistry.register("node", nodePlatform);
|
|
65
|
+
return nodePlatform;
|
|
66
|
+
}
|
|
67
|
+
return detected;
|
|
68
|
+
}
|
|
69
|
+
export {
|
|
70
|
+
detectPlatform,
|
|
71
|
+
getPlatform,
|
|
72
|
+
getPlatformAsync,
|
|
73
|
+
platformRegistry
|
|
74
|
+
};
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ServiceWorker runtime environment for Shovel entrypoints
|
|
3
|
+
*
|
|
4
|
+
* Provides ServiceWorker APIs (self, addEventListener, etc.) in any JavaScript runtime
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* ServiceWorker-style fetch event
|
|
8
|
+
*/
|
|
9
|
+
export interface ShovelFetchEvent extends Event {
|
|
10
|
+
readonly type: "fetch";
|
|
11
|
+
readonly request: Request;
|
|
12
|
+
respondWith(response: Response | Promise<Response>): void;
|
|
13
|
+
waitUntil(promise: Promise<any>): void;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* ServiceWorker-style install event
|
|
17
|
+
*/
|
|
18
|
+
export interface ShovelInstallEvent extends Event {
|
|
19
|
+
readonly type: "install";
|
|
20
|
+
waitUntil(promise: Promise<any>): void;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* ServiceWorker-style activate event
|
|
24
|
+
*/
|
|
25
|
+
export interface ShovelActivateEvent extends Event {
|
|
26
|
+
readonly type: "activate";
|
|
27
|
+
waitUntil(promise: Promise<any>): void;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Static generation event for collecting routes
|
|
31
|
+
*/
|
|
32
|
+
export interface ShovelStaticEvent extends Event {
|
|
33
|
+
readonly type: "static";
|
|
34
|
+
readonly detail: {
|
|
35
|
+
outDir: string;
|
|
36
|
+
baseUrl?: string;
|
|
37
|
+
};
|
|
38
|
+
waitUntil(promise: Promise<string[]>): void;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* ServiceWorker runtime that can be embedded in any platform
|
|
42
|
+
*/
|
|
43
|
+
export declare class ServiceWorkerRuntime extends EventTarget {
|
|
44
|
+
private pendingPromises;
|
|
45
|
+
private isInstalled;
|
|
46
|
+
private isActivated;
|
|
47
|
+
constructor();
|
|
48
|
+
/**
|
|
49
|
+
* Create a fetch event and dispatch it
|
|
50
|
+
*/
|
|
51
|
+
handleRequest(request: Request): Promise<Response>;
|
|
52
|
+
/**
|
|
53
|
+
* Install the ServiceWorker
|
|
54
|
+
*/
|
|
55
|
+
install(): Promise<void>;
|
|
56
|
+
/**
|
|
57
|
+
* Activate the ServiceWorker
|
|
58
|
+
*/
|
|
59
|
+
activate(): Promise<void>;
|
|
60
|
+
/**
|
|
61
|
+
* Collect static routes for pre-rendering
|
|
62
|
+
*/
|
|
63
|
+
collectStaticRoutes(outDir: string, baseUrl?: string): Promise<string[]>;
|
|
64
|
+
/**
|
|
65
|
+
* Check if ready to handle requests
|
|
66
|
+
*/
|
|
67
|
+
get ready(): boolean;
|
|
68
|
+
/**
|
|
69
|
+
* Wait for all pending promises to resolve
|
|
70
|
+
*/
|
|
71
|
+
waitForPending(): Promise<void>;
|
|
72
|
+
/**
|
|
73
|
+
* Reset the ServiceWorker state (for hot reloading)
|
|
74
|
+
*/
|
|
75
|
+
reset(): void;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Directory storage interface - parallels CacheStorage for filesystem access
|
|
79
|
+
* This could become a future web standard
|
|
80
|
+
*/
|
|
81
|
+
export interface DirectoryStorage {
|
|
82
|
+
/**
|
|
83
|
+
* Open a named directory - returns FileSystemDirectoryHandle
|
|
84
|
+
* Well-known names: 'assets', 'static', 'server', 'client'
|
|
85
|
+
*/
|
|
86
|
+
open(name: string): Promise<FileSystemDirectoryHandle>;
|
|
87
|
+
/**
|
|
88
|
+
* Check if a named directory exists
|
|
89
|
+
*/
|
|
90
|
+
has(name: string): Promise<boolean>;
|
|
91
|
+
/**
|
|
92
|
+
* Delete a named directory and all its contents
|
|
93
|
+
*/
|
|
94
|
+
delete(name: string): Promise<boolean>;
|
|
95
|
+
/**
|
|
96
|
+
* List all available directory names
|
|
97
|
+
*/
|
|
98
|
+
keys(): Promise<string[]>;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Create ServiceWorker globals for a module context
|
|
102
|
+
*/
|
|
103
|
+
export declare function createServiceWorkerGlobals(runtime: ServiceWorkerRuntime, options?: {
|
|
104
|
+
caches?: any;
|
|
105
|
+
dirs?: DirectoryStorage;
|
|
106
|
+
}): {
|
|
107
|
+
self: ServiceWorkerRuntime;
|
|
108
|
+
addEventListener: any;
|
|
109
|
+
removeEventListener: any;
|
|
110
|
+
dispatchEvent: any;
|
|
111
|
+
skipWaiting: () => Promise<void>;
|
|
112
|
+
clients: {
|
|
113
|
+
claim: () => Promise<void>;
|
|
114
|
+
matchAll: () => Promise<any[]>;
|
|
115
|
+
};
|
|
116
|
+
console: Console;
|
|
117
|
+
setTimeout: typeof setTimeout;
|
|
118
|
+
clearTimeout: typeof clearTimeout;
|
|
119
|
+
setInterval: typeof setInterval;
|
|
120
|
+
clearInterval: typeof clearInterval;
|
|
121
|
+
fetch: typeof fetch;
|
|
122
|
+
Request: {
|
|
123
|
+
new (input: RequestInfo | URL, init?: RequestInit): Request;
|
|
124
|
+
prototype: Request;
|
|
125
|
+
};
|
|
126
|
+
Response: {
|
|
127
|
+
new (body?: BodyInit | null, init?: ResponseInit): Response;
|
|
128
|
+
prototype: Response;
|
|
129
|
+
error(): Response;
|
|
130
|
+
json(data: any, init?: ResponseInit): Response;
|
|
131
|
+
redirect(url: string | URL, status?: number): Response;
|
|
132
|
+
};
|
|
133
|
+
Headers: {
|
|
134
|
+
new (init?: HeadersInit): Headers;
|
|
135
|
+
prototype: Headers;
|
|
136
|
+
};
|
|
137
|
+
URL: {
|
|
138
|
+
new (url: string | URL, base?: string | URL): URL;
|
|
139
|
+
prototype: URL;
|
|
140
|
+
canParse(url: string | URL, base?: string | URL): boolean;
|
|
141
|
+
createObjectURL(obj: Blob | MediaSource): string;
|
|
142
|
+
parse(url: string | URL, base?: string | URL): URL | null;
|
|
143
|
+
revokeObjectURL(url: string): void;
|
|
144
|
+
};
|
|
145
|
+
URLSearchParams: {
|
|
146
|
+
new (init?: string[][] | Record<string, string> | string | URLSearchParams): URLSearchParams;
|
|
147
|
+
prototype: URLSearchParams;
|
|
148
|
+
};
|
|
149
|
+
};
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
/// <reference types="./service-worker.d.ts" />
|
|
2
|
+
// src/service-worker.ts
|
|
3
|
+
var ServiceWorkerRuntime = class extends EventTarget {
|
|
4
|
+
pendingPromises = /* @__PURE__ */ new Set();
|
|
5
|
+
isInstalled = false;
|
|
6
|
+
isActivated = false;
|
|
7
|
+
constructor() {
|
|
8
|
+
super();
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Create a fetch event and dispatch it
|
|
12
|
+
*/
|
|
13
|
+
async handleRequest(request) {
|
|
14
|
+
if (!this.isActivated) {
|
|
15
|
+
throw new Error("ServiceWorker not activated");
|
|
16
|
+
}
|
|
17
|
+
return new Promise((resolve, reject) => {
|
|
18
|
+
let responded = false;
|
|
19
|
+
const promises = [];
|
|
20
|
+
const event = Object.assign(new Event("fetch"), {
|
|
21
|
+
request,
|
|
22
|
+
respondWith: (response) => {
|
|
23
|
+
if (responded) {
|
|
24
|
+
throw new Error("respondWith() already called");
|
|
25
|
+
}
|
|
26
|
+
responded = true;
|
|
27
|
+
Promise.resolve(response).then(resolve).catch(reject);
|
|
28
|
+
},
|
|
29
|
+
waitUntil: (promise) => {
|
|
30
|
+
promises.push(promise);
|
|
31
|
+
this.pendingPromises.add(promise);
|
|
32
|
+
promise.finally(() => this.pendingPromises.delete(promise));
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
this.dispatchEvent(event);
|
|
36
|
+
if (!responded) {
|
|
37
|
+
reject(new Error("No response provided for fetch event"));
|
|
38
|
+
}
|
|
39
|
+
Promise.allSettled(promises).catch(console.error);
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Install the ServiceWorker
|
|
44
|
+
*/
|
|
45
|
+
async install() {
|
|
46
|
+
if (this.isInstalled)
|
|
47
|
+
return;
|
|
48
|
+
return new Promise((resolve, reject) => {
|
|
49
|
+
const promises = [];
|
|
50
|
+
let installCancelled = false;
|
|
51
|
+
const event = Object.assign(new Event("install"), {
|
|
52
|
+
waitUntil: (promise) => {
|
|
53
|
+
promises.push(promise);
|
|
54
|
+
this.pendingPromises.add(promise);
|
|
55
|
+
promise.finally(() => this.pendingPromises.delete(promise));
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
this.dispatchEvent(event);
|
|
59
|
+
Promise.allSettled(promises).then(() => {
|
|
60
|
+
if (!installCancelled) {
|
|
61
|
+
this.isInstalled = true;
|
|
62
|
+
resolve();
|
|
63
|
+
}
|
|
64
|
+
}).catch(reject);
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Activate the ServiceWorker
|
|
69
|
+
*/
|
|
70
|
+
async activate() {
|
|
71
|
+
if (!this.isInstalled) {
|
|
72
|
+
throw new Error("ServiceWorker must be installed before activation");
|
|
73
|
+
}
|
|
74
|
+
if (this.isActivated)
|
|
75
|
+
return;
|
|
76
|
+
return new Promise((resolve, reject) => {
|
|
77
|
+
const promises = [];
|
|
78
|
+
const event = Object.assign(new Event("activate"), {
|
|
79
|
+
waitUntil: (promise) => {
|
|
80
|
+
promises.push(promise);
|
|
81
|
+
this.pendingPromises.add(promise);
|
|
82
|
+
promise.finally(() => this.pendingPromises.delete(promise));
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
this.dispatchEvent(event);
|
|
86
|
+
Promise.allSettled(promises).then(() => {
|
|
87
|
+
this.isActivated = true;
|
|
88
|
+
resolve();
|
|
89
|
+
}).catch(reject);
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Collect static routes for pre-rendering
|
|
94
|
+
*/
|
|
95
|
+
async collectStaticRoutes(outDir, baseUrl) {
|
|
96
|
+
return new Promise((resolve, reject) => {
|
|
97
|
+
let routes = [];
|
|
98
|
+
const promises = [];
|
|
99
|
+
const event = Object.assign(new Event("static"), {
|
|
100
|
+
detail: { outDir, baseUrl },
|
|
101
|
+
waitUntil: (promise) => {
|
|
102
|
+
promises.push(
|
|
103
|
+
promise.then((routeList) => {
|
|
104
|
+
routes = routes.concat(routeList);
|
|
105
|
+
})
|
|
106
|
+
);
|
|
107
|
+
this.pendingPromises.add(promise);
|
|
108
|
+
promise.finally(() => this.pendingPromises.delete(promise));
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
this.dispatchEvent(event);
|
|
112
|
+
if (promises.length === 0) {
|
|
113
|
+
resolve([]);
|
|
114
|
+
} else {
|
|
115
|
+
Promise.allSettled(promises).then(() => resolve([...new Set(routes)])).catch(reject);
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Check if ready to handle requests
|
|
121
|
+
*/
|
|
122
|
+
get ready() {
|
|
123
|
+
return this.isInstalled && this.isActivated;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Wait for all pending promises to resolve
|
|
127
|
+
*/
|
|
128
|
+
async waitForPending() {
|
|
129
|
+
if (this.pendingPromises.size > 0) {
|
|
130
|
+
await Promise.allSettled([...this.pendingPromises]);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Reset the ServiceWorker state (for hot reloading)
|
|
135
|
+
*/
|
|
136
|
+
reset() {
|
|
137
|
+
this.isInstalled = false;
|
|
138
|
+
this.isActivated = false;
|
|
139
|
+
this.pendingPromises.clear();
|
|
140
|
+
const listeners = this._listeners;
|
|
141
|
+
if (listeners) {
|
|
142
|
+
for (const type in listeners) {
|
|
143
|
+
delete listeners[type];
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
};
|
|
148
|
+
function createServiceWorkerGlobals(runtime, options = {}) {
|
|
149
|
+
if (options.caches) {
|
|
150
|
+
runtime.caches = options.caches;
|
|
151
|
+
}
|
|
152
|
+
if (options.dirs) {
|
|
153
|
+
runtime.dirs = options.dirs;
|
|
154
|
+
}
|
|
155
|
+
return {
|
|
156
|
+
self: runtime,
|
|
157
|
+
addEventListener: runtime.addEventListener.bind(runtime),
|
|
158
|
+
removeEventListener: runtime.removeEventListener.bind(runtime),
|
|
159
|
+
dispatchEvent: runtime.dispatchEvent.bind(runtime),
|
|
160
|
+
// ServiceWorker-specific globals that might be useful
|
|
161
|
+
skipWaiting: () => Promise.resolve(),
|
|
162
|
+
clients: {
|
|
163
|
+
claim: () => Promise.resolve(),
|
|
164
|
+
matchAll: () => Promise.resolve([])
|
|
165
|
+
},
|
|
166
|
+
// Standard globals
|
|
167
|
+
console,
|
|
168
|
+
setTimeout,
|
|
169
|
+
clearTimeout,
|
|
170
|
+
setInterval,
|
|
171
|
+
clearInterval,
|
|
172
|
+
fetch,
|
|
173
|
+
Request,
|
|
174
|
+
Response,
|
|
175
|
+
Headers,
|
|
176
|
+
URL,
|
|
177
|
+
URLSearchParams
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
export {
|
|
181
|
+
ServiceWorkerRuntime,
|
|
182
|
+
createServiceWorkerGlobals
|
|
183
|
+
};
|