@gonvex/client 0.1.32 → 0.3.1
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 +125 -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 +176 -133
- package/dist/index.js +1177 -1140
- 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 +2 -48
- package/dist/kv-stores.js +24 -411
- package/dist/kv-stores.js.map +1 -1
- 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 +25 -25
- package/dist/outbox.js +27 -27
- 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
|
@@ -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":"AAAA,OAAO,EAAE,kBAAkB,EAA2B,MAAM,YAAY,CAAC;AACzE,OAAO,EAAE,qBAAqB,EAAiB,MAAM,wBAAwB,CAAC;AAgB9E,MAAM,OAAO,aAAa;IAKH;IAJZ,KAAK,GAAG,IAAI,GAAG,EAAmB,CAAC;IAC5C,SAAS,GAAG,CAAC,CAAC;IACd,UAAU,GAAG,CAAC,CAAC;IAEf,YAAqB,KAAa;QAAb,UAAK,GAAL,KAAK,CAAQ;IAAG,CAAC;IAEtC,KAAK,CAAC,IAAI;QACR,IAAI,CAAC,SAAS,IAAI,CAAC,CAAC;IACtB,CAAC;IAED,KAAK,CAAC,OAAO,CAAI,OAA0B;QACzC,IAAI,OAAO,CAAC,SAAS,KAAK,OAAO,EAAE,CAAC;YAClC,IAAI,CAAC,UAAU,IAAI,CAAC,CAAC;QACvB,CAAC;QACD,OAAO,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACrC,CAAC;CACF;AAED,MAAM,OAAO,8BAA8B;IAChC,WAAW,GAAG,IAAI,qBAAqB,EAAE,CAAC;IAC1C,OAAO,GAAG,IAAI,GAAG,EAAyB,CAAC;IAC3C,UAAU,GAAyF,EAAE,CAAC;IAE/G,WAAW,CAAC,GAAa;QACvB,IAAI,CAAC,WAAW,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;QAClC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,aAAa,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;IACtD,CAAC;IAED,KAAK,CAAC,eAAe;QACnB,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC,QAAQ,EAAE,CAAC,WAAW,CAAC;QAC5D,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,OAAO;QACT,CAAC;QACD,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QAC7C,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO;QACT,CAAC;QACD,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;QACpB,IAAI,CAAC,WAAW,CAAC,oBAAoB,EAAE,CAAC;IAC1C,CAAC;IAED,QAAQ,CAAC,KAAa;QACpB,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IACnC,CAAC;IAED,KAAK,CAAC,OAAO,CAAI,eAAuB,EAAE,OAA0B;QAClE,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,CAAC,YAAY,EAAE,CAAC;QAC9C,IAAI,KAAK,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC7B,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,eAAe,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;YACxE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC;QAC9D,CAAC;QAED,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;QAClD,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,uBAAuB,EAAE,CAAC;QACzE,CAAC;QAED,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,eAAe,EAAE,UAAU,EAAE,KAAK,CAAC,WAAW,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;QACvG,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,MAAM,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;YAC3C,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,CAAC,WAAW,EAAE,KAAK,EAAE,CAAC;QAC5D,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,gBAAgB,EAAE,OAAO,EAAE,kBAAkB,CAAC,KAAK,CAAC,EAAE,CAAC;QACtG,CAAC;IACH,CAAC;IAED,aAAa;QACX,OAAO,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC5G,CAAC;CACF"}
|
|
@@ -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
|
-
}
|
|
@@ -1,109 +0,0 @@
|
|
|
1
|
-
export class CacheCoordinatorModel {
|
|
2
|
-
tabs = new Map();
|
|
3
|
-
activeTabId;
|
|
4
|
-
status = "no_owner";
|
|
5
|
-
registerTab(tab) {
|
|
6
|
-
this.tabs.set(tab.id, normalizeTab(tab));
|
|
7
|
-
this.electIfNeeded();
|
|
8
|
-
}
|
|
9
|
-
updateTab(tabId, patch) {
|
|
10
|
-
const current = this.tabs.get(tabId);
|
|
11
|
-
if (!current) {
|
|
12
|
-
return;
|
|
13
|
-
}
|
|
14
|
-
this.tabs.set(tabId, normalizeTab({ ...current, ...patch }));
|
|
15
|
-
if (tabId === this.activeTabId && !this.canOwn(this.tabs.get(tabId))) {
|
|
16
|
-
this.activeTabId = undefined;
|
|
17
|
-
this.status = "owner_lost";
|
|
18
|
-
}
|
|
19
|
-
this.electIfNeeded();
|
|
20
|
-
}
|
|
21
|
-
closeTab(tabId) {
|
|
22
|
-
this.tabs.delete(tabId);
|
|
23
|
-
if (this.activeTabId === tabId) {
|
|
24
|
-
this.activeTabId = undefined;
|
|
25
|
-
this.status = "owner_lost";
|
|
26
|
-
}
|
|
27
|
-
this.electIfNeeded();
|
|
28
|
-
}
|
|
29
|
-
disableUnsafeFallback() {
|
|
30
|
-
this.activeTabId = undefined;
|
|
31
|
-
this.status = "unsafe_fallback_disabled";
|
|
32
|
-
}
|
|
33
|
-
verifyActiveOwnerIntegrity() {
|
|
34
|
-
if (!this.activeTabId || this.status === "unsafe_fallback_disabled") {
|
|
35
|
-
return;
|
|
36
|
-
}
|
|
37
|
-
this.updateTab(this.activeTabId, { integrityVerified: true });
|
|
38
|
-
}
|
|
39
|
-
markActiveOwnerStorageReady() {
|
|
40
|
-
if (!this.activeTabId || this.status === "unsafe_fallback_disabled") {
|
|
41
|
-
return;
|
|
42
|
-
}
|
|
43
|
-
this.updateTab(this.activeTabId, { storageReady: true });
|
|
44
|
-
}
|
|
45
|
-
markActiveOwnerReady() {
|
|
46
|
-
if (!this.activeTabId || this.status === "unsafe_fallback_disabled") {
|
|
47
|
-
return;
|
|
48
|
-
}
|
|
49
|
-
this.updateTab(this.activeTabId, {
|
|
50
|
-
dedicatedWorkerReady: true,
|
|
51
|
-
storageReady: true,
|
|
52
|
-
integrityVerified: true,
|
|
53
|
-
});
|
|
54
|
-
this.electIfNeeded();
|
|
55
|
-
}
|
|
56
|
-
routeRequest() {
|
|
57
|
-
if (this.status === "unsafe_fallback_disabled") {
|
|
58
|
-
return { route: "server", reason: "unsafe-fallback-disabled" };
|
|
59
|
-
}
|
|
60
|
-
if (!this.activeTabId) {
|
|
61
|
-
return { route: "server", reason: "no-active-owner" };
|
|
62
|
-
}
|
|
63
|
-
const active = this.tabs.get(this.activeTabId);
|
|
64
|
-
if (!this.canOwn(active) || !this.ownerReady(active) || this.status !== "active_owner_ready") {
|
|
65
|
-
return { route: "server", reason: "owner-not-ready" };
|
|
66
|
-
}
|
|
67
|
-
return { route: "active-worker", activeTabId: this.activeTabId };
|
|
68
|
-
}
|
|
69
|
-
snapshot() {
|
|
70
|
-
return {
|
|
71
|
-
status: this.status,
|
|
72
|
-
activeTabId: this.activeTabId,
|
|
73
|
-
tabs: [...this.tabs.values()].map((tab) => ({ ...tab })),
|
|
74
|
-
};
|
|
75
|
-
}
|
|
76
|
-
electIfNeeded() {
|
|
77
|
-
if (this.status === "unsafe_fallback_disabled") {
|
|
78
|
-
return;
|
|
79
|
-
}
|
|
80
|
-
if (this.activeTabId && this.canOwn(this.tabs.get(this.activeTabId))) {
|
|
81
|
-
this.status = this.ownerReady(this.tabs.get(this.activeTabId)) ? "active_owner_ready" : "electing";
|
|
82
|
-
return;
|
|
83
|
-
}
|
|
84
|
-
const nextOwner = [...this.tabs.values()]
|
|
85
|
-
.filter((tab) => this.canOwn(tab))
|
|
86
|
-
.sort((left, right) => left.id.localeCompare(right.id))[0];
|
|
87
|
-
if (!nextOwner) {
|
|
88
|
-
this.activeTabId = undefined;
|
|
89
|
-
this.status = this.tabs.size > 0 ? "electing" : "no_owner";
|
|
90
|
-
return;
|
|
91
|
-
}
|
|
92
|
-
this.activeTabId = nextOwner.id;
|
|
93
|
-
this.status = this.ownerReady(nextOwner) ? "active_owner_ready" : "electing";
|
|
94
|
-
}
|
|
95
|
-
canOwn(tab) {
|
|
96
|
-
return Boolean(tab?.hasLivenessLock);
|
|
97
|
-
}
|
|
98
|
-
ownerReady(tab) {
|
|
99
|
-
return Boolean(tab?.dedicatedWorkerReady && tab.storageReady && tab.integrityVerified);
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
function normalizeTab(tab) {
|
|
103
|
-
return {
|
|
104
|
-
...tab,
|
|
105
|
-
storageReady: tab.storageReady ?? false,
|
|
106
|
-
integrityVerified: tab.integrityVerified ?? false,
|
|
107
|
-
};
|
|
108
|
-
}
|
|
109
|
-
//# sourceMappingURL=cache-coordinator.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"cache-coordinator.js","sourceRoot":"","sources":["../src/cache-coordinator.ts"],"names":[],"mappings":"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"}
|