@gonvex/client 0.1.31 → 0.3.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/README.md +119 -95
- package/dist/control.d.ts +416 -0
- package/dist/control.js +210 -0
- package/dist/control.js.map +1 -0
- package/dist/error-reporter.d.ts +20 -6
- package/dist/error-reporter.js +55 -27
- package/dist/error-reporter.js.map +1 -1
- package/dist/index.d.ts +170 -132
- package/dist/index.js +1123 -1138
- package/dist/index.js.map +1 -1
- package/dist/indexeddb-replica.d.ts +20 -0
- package/dist/indexeddb-replica.js +193 -0
- package/dist/indexeddb-replica.js.map +1 -0
- package/dist/kv-stores.d.ts +15 -0
- package/dist/kv-stores.js +60 -0
- package/dist/kv-stores.js.map +1 -0
- package/dist/local-replica.d.ts +240 -0
- package/dist/local-replica.js +590 -0
- package/dist/local-replica.js.map +1 -0
- package/dist/optimistic.d.ts +34 -55
- package/dist/optimistic.js +70 -269
- package/dist/optimistic.js.map +1 -1
- package/dist/outbox.d.ts +74 -16
- package/dist/outbox.js +194 -14
- package/dist/outbox.js.map +1 -1
- package/dist/query-expression.d.ts +58 -0
- package/dist/query-expression.js +164 -0
- package/dist/query-expression.js.map +1 -0
- package/dist/replica-integrity.d.ts +5 -0
- package/dist/replica-integrity.js +58 -0
- package/dist/replica-integrity.js.map +1 -0
- package/package.json +4 -4
- package/dist/browser-cache-client.d.ts +0 -77
- package/dist/browser-cache-client.js +0 -156
- package/dist/browser-cache-client.js.map +0 -1
- package/dist/browser-cache-shared-worker.d.ts +0 -35
- package/dist/browser-cache-shared-worker.js +0 -118
- package/dist/browser-cache-shared-worker.js.map +0 -1
- package/dist/browser-cache.d.ts +0 -43
- package/dist/browser-cache.js +0 -67
- package/dist/browser-cache.js.map +0 -1
- package/dist/browser-capabilities.d.ts +0 -21
- package/dist/browser-capabilities.js +0 -31
- package/dist/browser-capabilities.js.map +0 -1
- package/dist/cache-coordinator.d.ts +0 -37
- package/dist/cache-coordinator.js +0 -109
- package/dist/cache-coordinator.js.map +0 -1
- package/dist/cache.d.ts +0 -74
- package/dist/cache.js +0 -120
- package/dist/cache.js.map +0 -1
- package/dist/persistent-cache.d.ts +0 -41
- package/dist/persistent-cache.js +0 -103
- package/dist/persistent-cache.js.map +0 -1
- package/dist/query-cache.d.ts +0 -88
- package/dist/query-cache.js +0 -346
- package/dist/query-cache.js.map +0 -1
- package/dist/sync-store.d.ts +0 -96
- package/dist/sync-store.js +0 -500
- package/dist/sync-store.js.map +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gonvex/client",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"types": "./dist/index.d.ts",
|
|
15
15
|
"dependencies": {
|
|
16
16
|
"dexie": "^4.4.4",
|
|
17
|
-
"@gonvex/protocol": "0.
|
|
17
|
+
"@gonvex/protocol": "0.3.0"
|
|
18
18
|
},
|
|
19
19
|
"devDependencies": {
|
|
20
20
|
"fake-indexeddb": "^6.2.4",
|
|
@@ -27,9 +27,9 @@
|
|
|
27
27
|
"README.md"
|
|
28
28
|
],
|
|
29
29
|
"scripts": {
|
|
30
|
-
"build": "tsc -p tsconfig.json",
|
|
30
|
+
"build": "rm -rf dist && tsc -p tsconfig.json",
|
|
31
31
|
"dev": "tsc -p tsconfig.json --watch --preserveWatchOutput",
|
|
32
|
-
"test": "vitest run",
|
|
32
|
+
"test": "pnpm build && vitest run",
|
|
33
33
|
"typecheck": "tsc -p tsconfig.json --noEmit"
|
|
34
34
|
}
|
|
35
35
|
}
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
import { BrowserCacheCoordinatorHarness, type LocalDBRequest, type LocalDBResponse } from "./browser-cache.js";
|
|
2
|
-
import type { CacheDBHealth } from "./cache.js";
|
|
3
|
-
import type { CacheCoordinatorSnapshot, CacheTab } from "./cache-coordinator.js";
|
|
4
|
-
import { type BrowserCacheCapabilities } from "./browser-capabilities.js";
|
|
5
|
-
export type BrowserCacheClient = {
|
|
6
|
-
requestLocalRead<T>(request: Omit<LocalDBRequest<T>, "operation">): Promise<LocalDBResponse<T>>;
|
|
7
|
-
requestLocalWrite<T>(request: Omit<LocalDBRequest<T>, "operation">): Promise<LocalDBResponse<T>>;
|
|
8
|
-
getCacheHealth(): Promise<BrowserCacheHealth>;
|
|
9
|
-
};
|
|
10
|
-
export type BrowserCacheHealth = {
|
|
11
|
-
dbHealth: CacheDBHealth;
|
|
12
|
-
coordinator: CacheCoordinatorSnapshot;
|
|
13
|
-
};
|
|
14
|
-
export type BrowserCacheClientOptions = {
|
|
15
|
-
tabId: string;
|
|
16
|
-
harness?: BrowserCacheCoordinatorHarness;
|
|
17
|
-
};
|
|
18
|
-
export type SharedWorkerCacheClientOptions = {
|
|
19
|
-
tabId: string;
|
|
20
|
-
workerUrl: string | URL;
|
|
21
|
-
capabilities?: BrowserCacheCapabilities;
|
|
22
|
-
globalValue?: {
|
|
23
|
-
SharedWorker?: new (url: string | URL, options?: {
|
|
24
|
-
name?: string;
|
|
25
|
-
type?: "classic" | "module";
|
|
26
|
-
}) => {
|
|
27
|
-
port: WorkerLikePort;
|
|
28
|
-
};
|
|
29
|
-
};
|
|
30
|
-
};
|
|
31
|
-
type WorkerLikePort = {
|
|
32
|
-
postMessage(message: unknown): void;
|
|
33
|
-
start?: () => void;
|
|
34
|
-
addEventListener?: (type: "message", listener: (event: {
|
|
35
|
-
data: unknown;
|
|
36
|
-
}) => void) => void;
|
|
37
|
-
removeEventListener?: (type: "message", listener: (event: {
|
|
38
|
-
data: unknown;
|
|
39
|
-
}) => void) => void;
|
|
40
|
-
onmessage?: ((event: {
|
|
41
|
-
data: unknown;
|
|
42
|
-
}) => void) | null;
|
|
43
|
-
};
|
|
44
|
-
export declare class HarnessBrowserCacheClient implements BrowserCacheClient {
|
|
45
|
-
private dbHealth;
|
|
46
|
-
private readonly tabId;
|
|
47
|
-
private readonly harness;
|
|
48
|
-
constructor(options: BrowserCacheClientOptions);
|
|
49
|
-
registerTab(tab: Omit<CacheTab, "id">): void;
|
|
50
|
-
setDBHealth(health: CacheDBHealth): void;
|
|
51
|
-
requestLocalRead<T>(request: Omit<LocalDBRequest<T>, "operation">): Promise<LocalDBResponse<T>>;
|
|
52
|
-
requestLocalWrite<T>(request: Omit<LocalDBRequest<T>, "operation">): Promise<LocalDBResponse<T>>;
|
|
53
|
-
getCacheHealth(): Promise<BrowserCacheHealth>;
|
|
54
|
-
}
|
|
55
|
-
export declare function createHarnessBrowserCacheClient(options: BrowserCacheClientOptions): HarnessBrowserCacheClient;
|
|
56
|
-
export declare class DisabledBrowserCacheClient implements BrowserCacheClient {
|
|
57
|
-
private readonly reason;
|
|
58
|
-
constructor(reason: string);
|
|
59
|
-
requestLocalRead<T>(): Promise<LocalDBResponse<T>>;
|
|
60
|
-
requestLocalWrite<T>(): Promise<LocalDBResponse<T>>;
|
|
61
|
-
getCacheHealth(): Promise<BrowserCacheHealth>;
|
|
62
|
-
}
|
|
63
|
-
export declare class SharedWorkerBrowserCacheClient implements BrowserCacheClient {
|
|
64
|
-
private readonly options;
|
|
65
|
-
private readonly port;
|
|
66
|
-
private readonly pending;
|
|
67
|
-
constructor(options: SharedWorkerCacheClientOptions);
|
|
68
|
-
requestLocalRead<T>(request: Omit<LocalDBRequest<T>, "operation">): Promise<LocalDBResponse<T>>;
|
|
69
|
-
requestLocalWrite<T>(request: Omit<LocalDBRequest<T>, "operation">): Promise<LocalDBResponse<T>>;
|
|
70
|
-
getCacheHealth(): Promise<BrowserCacheHealth>;
|
|
71
|
-
private request;
|
|
72
|
-
private rpc;
|
|
73
|
-
private listen;
|
|
74
|
-
private resolve;
|
|
75
|
-
}
|
|
76
|
-
export declare function createBrowserCacheClient(options: SharedWorkerCacheClientOptions): BrowserCacheClient;
|
|
77
|
-
export {};
|
|
@@ -1,156 +0,0 @@
|
|
|
1
|
-
import { BrowserCacheCoordinatorHarness, } from "./browser-cache.js";
|
|
2
|
-
import { detectBrowserCacheCapabilities } from "./browser-capabilities.js";
|
|
3
|
-
export class HarnessBrowserCacheClient {
|
|
4
|
-
dbHealth = "initializing";
|
|
5
|
-
tabId;
|
|
6
|
-
harness;
|
|
7
|
-
constructor(options) {
|
|
8
|
-
this.tabId = options.tabId;
|
|
9
|
-
this.harness = options.harness ?? new BrowserCacheCoordinatorHarness();
|
|
10
|
-
}
|
|
11
|
-
registerTab(tab) {
|
|
12
|
-
this.harness.registerTab({ id: this.tabId, ...tab });
|
|
13
|
-
}
|
|
14
|
-
setDBHealth(health) {
|
|
15
|
-
this.dbHealth = health;
|
|
16
|
-
}
|
|
17
|
-
async requestLocalRead(request) {
|
|
18
|
-
if (this.dbHealth !== "healthy") {
|
|
19
|
-
return serverResponse("db-not-healthy");
|
|
20
|
-
}
|
|
21
|
-
return this.harness.request(this.tabId, { ...request, operation: "read" });
|
|
22
|
-
}
|
|
23
|
-
async requestLocalWrite(request) {
|
|
24
|
-
if (this.dbHealth !== "healthy") {
|
|
25
|
-
return serverResponse("db-not-healthy");
|
|
26
|
-
}
|
|
27
|
-
return this.harness.request(this.tabId, { ...request, operation: "write" });
|
|
28
|
-
}
|
|
29
|
-
async getCacheHealth() {
|
|
30
|
-
return {
|
|
31
|
-
dbHealth: this.dbHealth,
|
|
32
|
-
coordinator: this.harness.coordinator.snapshot(),
|
|
33
|
-
};
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
export function createHarnessBrowserCacheClient(options) {
|
|
37
|
-
return new HarnessBrowserCacheClient(options);
|
|
38
|
-
}
|
|
39
|
-
export class DisabledBrowserCacheClient {
|
|
40
|
-
reason;
|
|
41
|
-
constructor(reason) {
|
|
42
|
-
this.reason = reason;
|
|
43
|
-
}
|
|
44
|
-
async requestLocalRead() {
|
|
45
|
-
return serverResponse(this.reason);
|
|
46
|
-
}
|
|
47
|
-
async requestLocalWrite() {
|
|
48
|
-
return serverResponse(this.reason);
|
|
49
|
-
}
|
|
50
|
-
async getCacheHealth() {
|
|
51
|
-
return {
|
|
52
|
-
dbHealth: "unavailable",
|
|
53
|
-
coordinator: { status: "unsafe_fallback_disabled", tabs: [] },
|
|
54
|
-
};
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
export class SharedWorkerBrowserCacheClient {
|
|
58
|
-
options;
|
|
59
|
-
port;
|
|
60
|
-
pending = new Map();
|
|
61
|
-
constructor(options) {
|
|
62
|
-
this.options = options;
|
|
63
|
-
const capabilities = options.capabilities ?? detectBrowserCacheCapabilities();
|
|
64
|
-
if (!capabilities.supported) {
|
|
65
|
-
throw new Error(capabilities.disableReason ?? "browser-cache-unsupported");
|
|
66
|
-
}
|
|
67
|
-
const globalValue = options.globalValue ?? globalThis;
|
|
68
|
-
if (typeof globalValue.SharedWorker !== "function") {
|
|
69
|
-
throw new Error("shared-worker-unavailable");
|
|
70
|
-
}
|
|
71
|
-
this.port = new globalValue.SharedWorker(options.workerUrl, {
|
|
72
|
-
name: "gonvex-cache-coordinator",
|
|
73
|
-
type: "module",
|
|
74
|
-
}).port;
|
|
75
|
-
this.port.start?.();
|
|
76
|
-
this.listen((message) => this.resolve(message));
|
|
77
|
-
this.port.postMessage({ type: "gonvex.cache.register", tabId: options.tabId });
|
|
78
|
-
}
|
|
79
|
-
requestLocalRead(request) {
|
|
80
|
-
return this.request({ ...request, operation: "read" });
|
|
81
|
-
}
|
|
82
|
-
requestLocalWrite(request) {
|
|
83
|
-
return this.request({ ...request, operation: "write" });
|
|
84
|
-
}
|
|
85
|
-
async getCacheHealth() {
|
|
86
|
-
const message = await this.rpc("gonvex.cache.health", {});
|
|
87
|
-
if (message.type !== "gonvex.cache.health.result") {
|
|
88
|
-
throw new Error("unexpected cache worker health response");
|
|
89
|
-
}
|
|
90
|
-
return message.health;
|
|
91
|
-
}
|
|
92
|
-
async request(request) {
|
|
93
|
-
const message = await this.rpc("gonvex.cache.request", {
|
|
94
|
-
request: {
|
|
95
|
-
id: request.id,
|
|
96
|
-
operation: request.operation,
|
|
97
|
-
sql: request.sql,
|
|
98
|
-
params: request.params,
|
|
99
|
-
},
|
|
100
|
-
});
|
|
101
|
-
if (message.type !== "gonvex.cache.response") {
|
|
102
|
-
throw new Error("unexpected cache worker response");
|
|
103
|
-
}
|
|
104
|
-
return message.response;
|
|
105
|
-
}
|
|
106
|
-
rpc(type, payload) {
|
|
107
|
-
const id = randomID();
|
|
108
|
-
return new Promise((resolve) => {
|
|
109
|
-
this.pending.set(id, resolve);
|
|
110
|
-
this.port.postMessage({ ...payload, type, id, tabId: this.options.tabId });
|
|
111
|
-
});
|
|
112
|
-
}
|
|
113
|
-
listen(listener) {
|
|
114
|
-
if (this.port.addEventListener) {
|
|
115
|
-
this.port.addEventListener("message", (event) => {
|
|
116
|
-
if (isCacheWorkerMessage(event.data)) {
|
|
117
|
-
listener(event.data);
|
|
118
|
-
}
|
|
119
|
-
});
|
|
120
|
-
return;
|
|
121
|
-
}
|
|
122
|
-
this.port.onmessage = (event) => {
|
|
123
|
-
if (isCacheWorkerMessage(event.data)) {
|
|
124
|
-
listener(event.data);
|
|
125
|
-
}
|
|
126
|
-
};
|
|
127
|
-
}
|
|
128
|
-
resolve(message) {
|
|
129
|
-
const resolver = this.pending.get(message.id);
|
|
130
|
-
if (!resolver) {
|
|
131
|
-
return;
|
|
132
|
-
}
|
|
133
|
-
this.pending.delete(message.id);
|
|
134
|
-
resolver(message);
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
export function createBrowserCacheClient(options) {
|
|
138
|
-
const capabilities = options.capabilities ?? detectBrowserCacheCapabilities();
|
|
139
|
-
if (!capabilities.supported) {
|
|
140
|
-
return new DisabledBrowserCacheClient(capabilities.disableReason ?? "browser-cache-unsupported");
|
|
141
|
-
}
|
|
142
|
-
return new SharedWorkerBrowserCacheClient({ ...options, capabilities });
|
|
143
|
-
}
|
|
144
|
-
function serverResponse(reason) {
|
|
145
|
-
return { ok: false, route: "server", reason };
|
|
146
|
-
}
|
|
147
|
-
function isCacheWorkerMessage(value) {
|
|
148
|
-
return typeof value === "object" && value !== null && "type" in value && "id" in value;
|
|
149
|
-
}
|
|
150
|
-
function randomID() {
|
|
151
|
-
const randomUUID = globalThis.crypto?.randomUUID;
|
|
152
|
-
if (randomUUID)
|
|
153
|
-
return randomUUID.call(globalThis.crypto);
|
|
154
|
-
return `gonvex_cache_${Date.now().toString(36)}_${Math.random().toString(36).slice(2)}`;
|
|
155
|
-
}
|
|
156
|
-
//# sourceMappingURL=browser-cache-client.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"browser-cache-client.js","sourceRoot":"","sources":["../src/browser-cache-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import { BrowserCacheCoordinatorHarness, type LocalDBOperation } from "./browser-cache.js";
|
|
2
|
-
import type { CacheDBHealth } from "./cache.js";
|
|
3
|
-
import { CacheCoordinatorModel } from "./cache-coordinator.js";
|
|
4
|
-
export type SharedWorkerPortLike = {
|
|
5
|
-
postMessage(message: unknown): void;
|
|
6
|
-
addEventListener?: (type: "message", listener: (event: {
|
|
7
|
-
data: unknown;
|
|
8
|
-
}) => void) => void;
|
|
9
|
-
start?: () => void;
|
|
10
|
-
};
|
|
11
|
-
export type CacheOwnerExecutor = {
|
|
12
|
-
execute<T>(request: RoutedCacheRequest): Promise<T>;
|
|
13
|
-
reset?: () => Promise<void>;
|
|
14
|
-
};
|
|
15
|
-
export type RoutedCacheRequest = {
|
|
16
|
-
id: string;
|
|
17
|
-
operation: LocalDBOperation;
|
|
18
|
-
sql: string;
|
|
19
|
-
params?: unknown[];
|
|
20
|
-
};
|
|
21
|
-
export declare class SharedWorkerCacheCoordinator {
|
|
22
|
-
private readonly harness?;
|
|
23
|
-
readonly coordinator: CacheCoordinatorModel;
|
|
24
|
-
private readonly ports;
|
|
25
|
-
private dbHealth;
|
|
26
|
-
private ownerExecutor;
|
|
27
|
-
constructor(harness?: BrowserCacheCoordinatorHarness | undefined);
|
|
28
|
-
attach(port: SharedWorkerPortLike): void;
|
|
29
|
-
setDBHealth(health: CacheDBHealth): void;
|
|
30
|
-
setOwnerExecutor(executor: CacheOwnerExecutor | undefined): void;
|
|
31
|
-
handle(port: SharedWorkerPortLike, raw: unknown): Promise<void>;
|
|
32
|
-
private handleRequest;
|
|
33
|
-
private replyHealth;
|
|
34
|
-
private reply;
|
|
35
|
-
}
|
|
@@ -1,118 +0,0 @@
|
|
|
1
|
-
import { CacheCoordinatorModel } from "./cache-coordinator.js";
|
|
2
|
-
export class SharedWorkerCacheCoordinator {
|
|
3
|
-
harness;
|
|
4
|
-
coordinator = new CacheCoordinatorModel();
|
|
5
|
-
ports = new Map();
|
|
6
|
-
dbHealth = "initializing";
|
|
7
|
-
ownerExecutor;
|
|
8
|
-
constructor(harness) {
|
|
9
|
-
this.harness = harness;
|
|
10
|
-
}
|
|
11
|
-
attach(port) {
|
|
12
|
-
port.addEventListener?.("message", (event) => {
|
|
13
|
-
void this.handle(port, event.data);
|
|
14
|
-
});
|
|
15
|
-
port.start?.();
|
|
16
|
-
}
|
|
17
|
-
setDBHealth(health) {
|
|
18
|
-
this.dbHealth = health;
|
|
19
|
-
}
|
|
20
|
-
setOwnerExecutor(executor) {
|
|
21
|
-
this.ownerExecutor = executor;
|
|
22
|
-
}
|
|
23
|
-
async handle(port, raw) {
|
|
24
|
-
if (!isInboundMessage(raw)) {
|
|
25
|
-
return;
|
|
26
|
-
}
|
|
27
|
-
if ("tabId" in raw) {
|
|
28
|
-
this.ports.set(raw.tabId, port);
|
|
29
|
-
}
|
|
30
|
-
switch (raw.type) {
|
|
31
|
-
case "gonvex.cache.register":
|
|
32
|
-
this.coordinator.registerTab({
|
|
33
|
-
id: raw.tabId,
|
|
34
|
-
hasLivenessLock: false,
|
|
35
|
-
dedicatedWorkerReady: false,
|
|
36
|
-
storageReady: false,
|
|
37
|
-
integrityVerified: false,
|
|
38
|
-
});
|
|
39
|
-
this.replyHealth(port, "");
|
|
40
|
-
return;
|
|
41
|
-
case "gonvex.cache.tab":
|
|
42
|
-
this.coordinator.updateTab(raw.tabId, raw.tab);
|
|
43
|
-
return;
|
|
44
|
-
case "gonvex.cache.owner.ready":
|
|
45
|
-
this.coordinator.markActiveOwnerReady();
|
|
46
|
-
this.dbHealth = "healthy";
|
|
47
|
-
return;
|
|
48
|
-
case "gonvex.cache.owner.lost":
|
|
49
|
-
this.coordinator.closeTab(raw.tabId);
|
|
50
|
-
this.dbHealth = "initializing";
|
|
51
|
-
return;
|
|
52
|
-
case "gonvex.cache.health":
|
|
53
|
-
this.replyHealth(port, raw.id);
|
|
54
|
-
return;
|
|
55
|
-
case "gonvex.cache.request":
|
|
56
|
-
await this.handleRequest(port, raw.id, raw.request);
|
|
57
|
-
return;
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
async handleRequest(port, id, request) {
|
|
61
|
-
if (this.dbHealth !== "healthy") {
|
|
62
|
-
this.reply(port, { type: "gonvex.cache.response", id, response: serverResponse("db-not-healthy") });
|
|
63
|
-
return;
|
|
64
|
-
}
|
|
65
|
-
const route = this.coordinator.routeRequest();
|
|
66
|
-
if (route.route === "server") {
|
|
67
|
-
this.reply(port, { type: "gonvex.cache.response", id, response: serverResponse(route.reason) });
|
|
68
|
-
return;
|
|
69
|
-
}
|
|
70
|
-
const ownerExecutor = this.ownerExecutor;
|
|
71
|
-
if (!this.harness && !ownerExecutor) {
|
|
72
|
-
this.reply(port, { type: "gonvex.cache.response", id, response: serverResponse("owner-executor-unavailable") });
|
|
73
|
-
return;
|
|
74
|
-
}
|
|
75
|
-
try {
|
|
76
|
-
if (this.harness) {
|
|
77
|
-
const value = await this.harness.request(route.activeTabId, { ...request, execute: () => undefined });
|
|
78
|
-
this.reply(port, { type: "gonvex.cache.response", id, response: value });
|
|
79
|
-
return;
|
|
80
|
-
}
|
|
81
|
-
if (!ownerExecutor) {
|
|
82
|
-
this.reply(port, { type: "gonvex.cache.response", id, response: serverResponse("owner-executor-unavailable") });
|
|
83
|
-
return;
|
|
84
|
-
}
|
|
85
|
-
const value = await ownerExecutor.execute(request);
|
|
86
|
-
this.reply(port, {
|
|
87
|
-
type: "gonvex.cache.response",
|
|
88
|
-
id,
|
|
89
|
-
response: { ok: true, ownerTabId: route.activeTabId, value },
|
|
90
|
-
});
|
|
91
|
-
}
|
|
92
|
-
catch (error) {
|
|
93
|
-
this.dbHealth = "corrupt";
|
|
94
|
-
await this.ownerExecutor?.reset?.();
|
|
95
|
-
this.reply(port, { type: "gonvex.cache.response", id, response: serverResponse(error instanceof Error ? error.message : "cache-request-failed") });
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
replyHealth(port, id) {
|
|
99
|
-
this.reply(port, {
|
|
100
|
-
type: "gonvex.cache.health.result",
|
|
101
|
-
id,
|
|
102
|
-
health: {
|
|
103
|
-
dbHealth: this.dbHealth,
|
|
104
|
-
coordinator: this.coordinator.snapshot(),
|
|
105
|
-
},
|
|
106
|
-
});
|
|
107
|
-
}
|
|
108
|
-
reply(port, message) {
|
|
109
|
-
port.postMessage(message);
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
function isInboundMessage(value) {
|
|
113
|
-
return typeof value === "object" && value !== null && "type" in value;
|
|
114
|
-
}
|
|
115
|
-
function serverResponse(reason) {
|
|
116
|
-
return { ok: false, route: "server", reason };
|
|
117
|
-
}
|
|
118
|
-
//# sourceMappingURL=browser-cache-shared-worker.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"browser-cache-shared-worker.js","sourceRoot":"","sources":["../src/browser-cache-shared-worker.ts"],"names":[],"mappings":"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"}
|
package/dist/browser-cache.d.ts
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import { type CacheFailureAction } from "./cache.js";
|
|
2
|
-
import { CacheCoordinatorModel, type CacheTab } from "./cache-coordinator.js";
|
|
3
|
-
export type LocalDBOperation = "read" | "write";
|
|
4
|
-
export type LocalDBRequest<T = unknown> = {
|
|
5
|
-
id: string;
|
|
6
|
-
operation: LocalDBOperation;
|
|
7
|
-
sql: string;
|
|
8
|
-
params?: unknown[];
|
|
9
|
-
execute: (state: Map<string, unknown>) => T | Promise<T>;
|
|
10
|
-
};
|
|
11
|
-
export type LocalDBResponse<T = unknown> = {
|
|
12
|
-
ok: true;
|
|
13
|
-
ownerTabId: string;
|
|
14
|
-
value: T;
|
|
15
|
-
} | {
|
|
16
|
-
ok: false;
|
|
17
|
-
route: "server";
|
|
18
|
-
reason: string;
|
|
19
|
-
failure?: CacheFailureAction;
|
|
20
|
-
};
|
|
21
|
-
export declare class FakeTabWorker {
|
|
22
|
-
readonly tabId: string;
|
|
23
|
-
readonly state: Map<string, unknown>;
|
|
24
|
-
openCount: number;
|
|
25
|
-
writeCount: number;
|
|
26
|
-
constructor(tabId: string);
|
|
27
|
-
boot(): Promise<void>;
|
|
28
|
-
execute<T>(request: LocalDBRequest<T>): Promise<T>;
|
|
29
|
-
}
|
|
30
|
-
export declare class BrowserCacheCoordinatorHarness {
|
|
31
|
-
readonly coordinator: CacheCoordinatorModel;
|
|
32
|
-
readonly workers: Map<string, FakeTabWorker>;
|
|
33
|
-
readonly requestLog: Array<{
|
|
34
|
-
requestingTabId: string;
|
|
35
|
-
ownerTabId?: string;
|
|
36
|
-
operation: LocalDBOperation;
|
|
37
|
-
}>;
|
|
38
|
-
registerTab(tab: CacheTab): void;
|
|
39
|
-
bootActiveOwner(): Promise<void>;
|
|
40
|
-
closeTab(tabId: string): void;
|
|
41
|
-
request<T>(requestingTabId: string, request: LocalDBRequest<T>): Promise<LocalDBResponse<T>>;
|
|
42
|
-
activeWriters(): string[];
|
|
43
|
-
}
|
package/dist/browser-cache.js
DELETED
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
import { cacheFailureAction } from "./cache.js";
|
|
2
|
-
import { CacheCoordinatorModel } from "./cache-coordinator.js";
|
|
3
|
-
export class FakeTabWorker {
|
|
4
|
-
tabId;
|
|
5
|
-
state = new Map();
|
|
6
|
-
openCount = 0;
|
|
7
|
-
writeCount = 0;
|
|
8
|
-
constructor(tabId) {
|
|
9
|
-
this.tabId = tabId;
|
|
10
|
-
}
|
|
11
|
-
async boot() {
|
|
12
|
-
this.openCount += 1;
|
|
13
|
-
}
|
|
14
|
-
async execute(request) {
|
|
15
|
-
if (request.operation === "write") {
|
|
16
|
-
this.writeCount += 1;
|
|
17
|
-
}
|
|
18
|
-
return request.execute(this.state);
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
export class BrowserCacheCoordinatorHarness {
|
|
22
|
-
coordinator = new CacheCoordinatorModel();
|
|
23
|
-
workers = new Map();
|
|
24
|
-
requestLog = [];
|
|
25
|
-
registerTab(tab) {
|
|
26
|
-
this.coordinator.registerTab(tab);
|
|
27
|
-
this.workers.set(tab.id, new FakeTabWorker(tab.id));
|
|
28
|
-
}
|
|
29
|
-
async bootActiveOwner() {
|
|
30
|
-
const activeTabId = this.coordinator.snapshot().activeTabId;
|
|
31
|
-
if (!activeTabId) {
|
|
32
|
-
return;
|
|
33
|
-
}
|
|
34
|
-
const worker = this.workers.get(activeTabId);
|
|
35
|
-
if (!worker) {
|
|
36
|
-
return;
|
|
37
|
-
}
|
|
38
|
-
await worker.boot();
|
|
39
|
-
this.coordinator.markActiveOwnerReady();
|
|
40
|
-
}
|
|
41
|
-
closeTab(tabId) {
|
|
42
|
-
this.coordinator.closeTab(tabId);
|
|
43
|
-
}
|
|
44
|
-
async request(requestingTabId, request) {
|
|
45
|
-
const route = this.coordinator.routeRequest();
|
|
46
|
-
if (route.route === "server") {
|
|
47
|
-
this.requestLog.push({ requestingTabId, operation: request.operation });
|
|
48
|
-
return { ok: false, route: "server", reason: route.reason };
|
|
49
|
-
}
|
|
50
|
-
const owner = this.workers.get(route.activeTabId);
|
|
51
|
-
if (!owner) {
|
|
52
|
-
return { ok: false, route: "server", reason: "active-worker-missing" };
|
|
53
|
-
}
|
|
54
|
-
this.requestLog.push({ requestingTabId, ownerTabId: route.activeTabId, operation: request.operation });
|
|
55
|
-
try {
|
|
56
|
-
const value = await owner.execute(request);
|
|
57
|
-
return { ok: true, ownerTabId: route.activeTabId, value };
|
|
58
|
-
}
|
|
59
|
-
catch (error) {
|
|
60
|
-
return { ok: false, route: "server", reason: "local-db-error", failure: cacheFailureAction(error) };
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
activeWriters() {
|
|
64
|
-
return [...this.workers.values()].filter((worker) => worker.writeCount > 0).map((worker) => worker.tabId);
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
//# sourceMappingURL=browser-cache.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"browser-cache.js","sourceRoot":"","sources":["../src/browser-cache.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
export type BrowserCacheDisableReason = "shared-worker-unavailable" | "web-locks-unavailable" | "dedicated-worker-unavailable" | "persistent-storage-unavailable";
|
|
2
|
-
export type BrowserCacheCapabilities = {
|
|
3
|
-
sharedWorker: boolean;
|
|
4
|
-
webLocks: boolean;
|
|
5
|
-
dedicatedWorker: boolean;
|
|
6
|
-
opfs: boolean;
|
|
7
|
-
supported: boolean;
|
|
8
|
-
disableReason?: BrowserCacheDisableReason;
|
|
9
|
-
};
|
|
10
|
-
type CapabilityGlobal = {
|
|
11
|
-
SharedWorker?: unknown;
|
|
12
|
-
Worker?: unknown;
|
|
13
|
-
navigator?: {
|
|
14
|
-
locks?: unknown;
|
|
15
|
-
storage?: {
|
|
16
|
-
getDirectory?: unknown;
|
|
17
|
-
};
|
|
18
|
-
};
|
|
19
|
-
};
|
|
20
|
-
export declare function detectBrowserCacheCapabilities(globalValue?: CapabilityGlobal): BrowserCacheCapabilities;
|
|
21
|
-
export {};
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
export function detectBrowserCacheCapabilities(globalValue = globalThis) {
|
|
2
|
-
const sharedWorker = typeof globalValue.SharedWorker === "function";
|
|
3
|
-
const webLocks = typeof globalValue.navigator?.locks === "object" && globalValue.navigator?.locks !== null;
|
|
4
|
-
const dedicatedWorker = typeof globalValue.Worker === "function";
|
|
5
|
-
const opfs = typeof globalValue.navigator?.storage?.getDirectory === "function";
|
|
6
|
-
const disableReason = firstDisableReason({ sharedWorker, webLocks, dedicatedWorker, opfs });
|
|
7
|
-
return {
|
|
8
|
-
sharedWorker,
|
|
9
|
-
webLocks,
|
|
10
|
-
dedicatedWorker,
|
|
11
|
-
opfs,
|
|
12
|
-
supported: disableReason === undefined,
|
|
13
|
-
disableReason,
|
|
14
|
-
};
|
|
15
|
-
}
|
|
16
|
-
function firstDisableReason(capabilities) {
|
|
17
|
-
if (!capabilities.sharedWorker) {
|
|
18
|
-
return "shared-worker-unavailable";
|
|
19
|
-
}
|
|
20
|
-
if (!capabilities.webLocks) {
|
|
21
|
-
return "web-locks-unavailable";
|
|
22
|
-
}
|
|
23
|
-
if (!capabilities.dedicatedWorker) {
|
|
24
|
-
return "dedicated-worker-unavailable";
|
|
25
|
-
}
|
|
26
|
-
if (!capabilities.opfs) {
|
|
27
|
-
return "persistent-storage-unavailable";
|
|
28
|
-
}
|
|
29
|
-
return undefined;
|
|
30
|
-
}
|
|
31
|
-
//# sourceMappingURL=browser-capabilities.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"browser-capabilities.js","sourceRoot":"","sources":["../src/browser-capabilities.ts"],"names":[],"mappings":"AA0BA,MAAM,UAAU,8BAA8B,CAAC,cAAgC,UAAU;IACvF,MAAM,YAAY,GAAG,OAAO,WAAW,CAAC,YAAY,KAAK,UAAU,CAAC;IACpE,MAAM,QAAQ,GAAG,OAAO,WAAW,CAAC,SAAS,EAAE,KAAK,KAAK,QAAQ,IAAI,WAAW,CAAC,SAAS,EAAE,KAAK,KAAK,IAAI,CAAC;IAC3G,MAAM,eAAe,GAAG,OAAO,WAAW,CAAC,MAAM,KAAK,UAAU,CAAC;IACjE,MAAM,IAAI,GAAG,OAAO,WAAW,CAAC,SAAS,EAAE,OAAO,EAAE,YAAY,KAAK,UAAU,CAAC;IAChF,MAAM,aAAa,GAAG,kBAAkB,CAAC,EAAE,YAAY,EAAE,QAAQ,EAAE,eAAe,EAAE,IAAI,EAAE,CAAC,CAAC;IAE5F,OAAO;QACL,YAAY;QACZ,QAAQ;QACR,eAAe;QACf,IAAI;QACJ,SAAS,EAAE,aAAa,KAAK,SAAS;QACtC,aAAa;KACd,CAAC;AACJ,CAAC;AAED,SAAS,kBAAkB,CACzB,YAAsG;IAEtG,IAAI,CAAC,YAAY,CAAC,YAAY,EAAE,CAAC;QAC/B,OAAO,2BAA2B,CAAC;IACrC,CAAC;IACD,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE,CAAC;QAC3B,OAAO,uBAAuB,CAAC;IACjC,CAAC;IACD,IAAI,CAAC,YAAY,CAAC,eAAe,EAAE,CAAC;QAClC,OAAO,8BAA8B,CAAC;IACxC,CAAC;IACD,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC;QACvB,OAAO,gCAAgC,CAAC;IAC1C,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC"}
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
export type CacheOwnerStatus = "no_owner" | "electing" | "active_owner_ready" | "owner_lost" | "unsafe_fallback_disabled";
|
|
2
|
-
export type CacheTab = {
|
|
3
|
-
id: string;
|
|
4
|
-
hasLivenessLock: boolean;
|
|
5
|
-
dedicatedWorkerReady: boolean;
|
|
6
|
-
storageReady?: boolean;
|
|
7
|
-
integrityVerified?: boolean;
|
|
8
|
-
};
|
|
9
|
-
export type CacheCoordinatorSnapshot = {
|
|
10
|
-
status: CacheOwnerStatus;
|
|
11
|
-
activeTabId?: string;
|
|
12
|
-
tabs: CacheTab[];
|
|
13
|
-
};
|
|
14
|
-
export type DBRequestRoute = {
|
|
15
|
-
route: "active-worker";
|
|
16
|
-
activeTabId: string;
|
|
17
|
-
} | {
|
|
18
|
-
route: "server";
|
|
19
|
-
reason: "no-active-owner" | "owner-not-ready" | "unsafe-fallback-disabled";
|
|
20
|
-
};
|
|
21
|
-
export declare class CacheCoordinatorModel {
|
|
22
|
-
private tabs;
|
|
23
|
-
private activeTabId;
|
|
24
|
-
private status;
|
|
25
|
-
registerTab(tab: CacheTab): void;
|
|
26
|
-
updateTab(tabId: string, patch: Partial<Omit<CacheTab, "id">>): void;
|
|
27
|
-
closeTab(tabId: string): void;
|
|
28
|
-
disableUnsafeFallback(): void;
|
|
29
|
-
verifyActiveOwnerIntegrity(): void;
|
|
30
|
-
markActiveOwnerStorageReady(): void;
|
|
31
|
-
markActiveOwnerReady(): void;
|
|
32
|
-
routeRequest(): DBRequestRoute;
|
|
33
|
-
snapshot(): CacheCoordinatorSnapshot;
|
|
34
|
-
private electIfNeeded;
|
|
35
|
-
private canOwn;
|
|
36
|
-
private ownerReady;
|
|
37
|
-
}
|