@rockhall/electron-offline-content 0.4.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/CHANGELOG.md +384 -0
- package/LICENSE +21 -0
- package/README.md +794 -0
- package/dist/internal/asset-file-name.cjs +13 -0
- package/dist/internal/asset-file-name.cjs.map +1 -0
- package/dist/internal/asset-file-name.d.cts +6 -0
- package/dist/internal/asset-file-name.d.cts.map +1 -0
- package/dist/internal/asset-file-name.d.ts +6 -0
- package/dist/internal/asset-file-name.d.ts.map +1 -0
- package/dist/internal/asset-file-name.js +12 -0
- package/dist/internal/asset-file-name.js.map +1 -0
- package/dist/internal/asset-key.cjs +30 -0
- package/dist/internal/asset-key.cjs.map +1 -0
- package/dist/internal/asset-key.d.cts +19 -0
- package/dist/internal/asset-key.d.cts.map +1 -0
- package/dist/internal/asset-key.d.ts +19 -0
- package/dist/internal/asset-key.d.ts.map +1 -0
- package/dist/internal/asset-key.js +27 -0
- package/dist/internal/asset-key.js.map +1 -0
- package/dist/internal/log-format.cjs +98 -0
- package/dist/internal/log-format.cjs.map +1 -0
- package/dist/internal/log-format.d.cts +10 -0
- package/dist/internal/log-format.d.cts.map +1 -0
- package/dist/internal/log-format.d.ts +10 -0
- package/dist/internal/log-format.d.ts.map +1 -0
- package/dist/internal/log-format.js +97 -0
- package/dist/internal/log-format.js.map +1 -0
- package/dist/internal/media-kind.cjs +46 -0
- package/dist/internal/media-kind.cjs.map +1 -0
- package/dist/internal/media-kind.d.cts +20 -0
- package/dist/internal/media-kind.d.cts.map +1 -0
- package/dist/internal/media-kind.d.ts +20 -0
- package/dist/internal/media-kind.d.ts.map +1 -0
- package/dist/internal/media-kind.js +45 -0
- package/dist/internal/media-kind.js.map +1 -0
- package/dist/internal/url-warn.cjs +14 -0
- package/dist/internal/url-warn.cjs.map +1 -0
- package/dist/internal/url-warn.d.cts +10 -0
- package/dist/internal/url-warn.d.cts.map +1 -0
- package/dist/internal/url-warn.d.ts +10 -0
- package/dist/internal/url-warn.d.ts.map +1 -0
- package/dist/internal/url-warn.js +13 -0
- package/dist/internal/url-warn.js.map +1 -0
- package/dist/internal/validation.cjs +222 -0
- package/dist/internal/validation.cjs.map +1 -0
- package/dist/internal/validation.d.cts +78 -0
- package/dist/internal/validation.d.cts.map +1 -0
- package/dist/internal/validation.d.ts +78 -0
- package/dist/internal/validation.d.ts.map +1 -0
- package/dist/internal/validation.js +196 -0
- package/dist/internal/validation.js.map +1 -0
- package/dist/main/asset-download.cjs +265 -0
- package/dist/main/asset-download.cjs.map +1 -0
- package/dist/main/asset-download.d.cts +12 -0
- package/dist/main/asset-download.d.cts.map +1 -0
- package/dist/main/asset-download.d.ts +12 -0
- package/dist/main/asset-download.d.ts.map +1 -0
- package/dist/main/asset-download.js +263 -0
- package/dist/main/asset-download.js.map +1 -0
- package/dist/main/database.cjs +473 -0
- package/dist/main/database.cjs.map +1 -0
- package/dist/main/database.d.cts +81 -0
- package/dist/main/database.d.cts.map +1 -0
- package/dist/main/database.d.ts +81 -0
- package/dist/main/database.d.ts.map +1 -0
- package/dist/main/database.js +472 -0
- package/dist/main/database.js.map +1 -0
- package/dist/main/index.cjs +22 -0
- package/dist/main/index.d.cts +7 -0
- package/dist/main/index.d.ts +7 -0
- package/dist/main/index.js +7 -0
- package/dist/main/media-cache.cjs +862 -0
- package/dist/main/media-cache.cjs.map +1 -0
- package/dist/main/media-cache.d.cts +134 -0
- package/dist/main/media-cache.d.cts.map +1 -0
- package/dist/main/media-cache.d.ts +134 -0
- package/dist/main/media-cache.d.ts.map +1 -0
- package/dist/main/media-cache.js +854 -0
- package/dist/main/media-cache.js.map +1 -0
- package/dist/main/storage-root-lock.cjs +124 -0
- package/dist/main/storage-root-lock.cjs.map +1 -0
- package/dist/main/storage-root-lock.d.cts +11 -0
- package/dist/main/storage-root-lock.d.cts.map +1 -0
- package/dist/main/storage-root-lock.d.ts +11 -0
- package/dist/main/storage-root-lock.d.ts.map +1 -0
- package/dist/main/storage-root-lock.js +120 -0
- package/dist/main/storage-root-lock.js.map +1 -0
- package/dist/main/store.cjs +197 -0
- package/dist/main/store.cjs.map +1 -0
- package/dist/main/store.d.cts +83 -0
- package/dist/main/store.d.cts.map +1 -0
- package/dist/main/store.d.ts +83 -0
- package/dist/main/store.d.ts.map +1 -0
- package/dist/main/store.js +195 -0
- package/dist/main/store.js.map +1 -0
- package/dist/preload/index.cjs +36 -0
- package/dist/preload/index.cjs.map +1 -0
- package/dist/preload/index.d.cts +14 -0
- package/dist/preload/index.d.cts.map +1 -0
- package/dist/preload/index.d.ts +14 -0
- package/dist/preload/index.d.ts.map +1 -0
- package/dist/preload/index.js +34 -0
- package/dist/preload/index.js.map +1 -0
- package/dist/react/index.cjs +199 -0
- package/dist/react/index.cjs.map +1 -0
- package/dist/react/index.d.cts +50 -0
- package/dist/react/index.d.cts.map +1 -0
- package/dist/react/index.d.ts +50 -0
- package/dist/react/index.d.ts.map +1 -0
- package/dist/react/index.js +191 -0
- package/dist/react/index.js.map +1 -0
- package/dist/renderer/helpers.cjs +36 -0
- package/dist/renderer/helpers.cjs.map +1 -0
- package/dist/renderer/helpers.d.cts +11 -0
- package/dist/renderer/helpers.d.cts.map +1 -0
- package/dist/renderer/helpers.d.ts +11 -0
- package/dist/renderer/helpers.d.ts.map +1 -0
- package/dist/renderer/helpers.js +35 -0
- package/dist/renderer/helpers.js.map +1 -0
- package/dist/renderer/index.cjs +20 -0
- package/dist/renderer/index.cjs.map +1 -0
- package/dist/renderer/index.d.cts +14 -0
- package/dist/renderer/index.d.cts.map +1 -0
- package/dist/renderer/index.d.ts +14 -0
- package/dist/renderer/index.d.ts.map +1 -0
- package/dist/renderer/index.js +14 -0
- package/dist/renderer/index.js.map +1 -0
- package/dist/renderer/runtime.cjs +278 -0
- package/dist/renderer/runtime.cjs.map +1 -0
- package/dist/renderer/runtime.d.cts +35 -0
- package/dist/renderer/runtime.d.cts.map +1 -0
- package/dist/renderer/runtime.d.ts +35 -0
- package/dist/renderer/runtime.d.ts.map +1 -0
- package/dist/renderer/runtime.js +273 -0
- package/dist/renderer/runtime.js.map +1 -0
- package/dist/renderer/window-globals.d.cts +9 -0
- package/dist/renderer/window-globals.d.cts.map +1 -0
- package/dist/renderer/window-globals.d.ts +9 -0
- package/dist/renderer/window-globals.d.ts.map +1 -0
- package/dist/shared/errors.cjs +102 -0
- package/dist/shared/errors.cjs.map +1 -0
- package/dist/shared/errors.d.cts +45 -0
- package/dist/shared/errors.d.cts.map +1 -0
- package/dist/shared/errors.d.ts +45 -0
- package/dist/shared/errors.d.ts.map +1 -0
- package/dist/shared/errors.js +93 -0
- package/dist/shared/errors.js.map +1 -0
- package/dist/shared/ipc.cjs +14 -0
- package/dist/shared/ipc.cjs.map +1 -0
- package/dist/shared/ipc.d.cts +12 -0
- package/dist/shared/ipc.d.cts.map +1 -0
- package/dist/shared/ipc.d.ts +12 -0
- package/dist/shared/ipc.d.ts.map +1 -0
- package/dist/shared/ipc.js +13 -0
- package/dist/shared/ipc.js.map +1 -0
- package/dist/shared/normalize.cjs +19 -0
- package/dist/shared/normalize.cjs.map +1 -0
- package/dist/shared/normalize.d.cts +11 -0
- package/dist/shared/normalize.d.cts.map +1 -0
- package/dist/shared/normalize.d.ts +11 -0
- package/dist/shared/normalize.d.ts.map +1 -0
- package/dist/shared/normalize.js +18 -0
- package/dist/shared/normalize.js.map +1 -0
- package/dist/shared/pagination.cjs +32 -0
- package/dist/shared/pagination.cjs.map +1 -0
- package/dist/shared/pagination.d.cts +14 -0
- package/dist/shared/pagination.d.cts.map +1 -0
- package/dist/shared/pagination.d.ts +14 -0
- package/dist/shared/pagination.d.ts.map +1 -0
- package/dist/shared/pagination.js +28 -0
- package/dist/shared/pagination.js.map +1 -0
- package/dist/shared/stem.cjs +16 -0
- package/dist/shared/stem.cjs.map +1 -0
- package/dist/shared/stem.d.cts +6 -0
- package/dist/shared/stem.d.cts.map +1 -0
- package/dist/shared/stem.d.ts +6 -0
- package/dist/shared/stem.d.ts.map +1 -0
- package/dist/shared/stem.js +14 -0
- package/dist/shared/stem.js.map +1 -0
- package/dist/shared/types.cjs +15 -0
- package/dist/shared/types.cjs.map +1 -0
- package/dist/shared/types.d.cts +234 -0
- package/dist/shared/types.d.cts.map +1 -0
- package/dist/shared/types.d.ts +234 -0
- package/dist/shared/types.d.ts.map +1 -0
- package/dist/shared/types.js +14 -0
- package/dist/shared/types.js.map +1 -0
- package/package.json +120 -0
- package/skills/authenticated-downloads/SKILL.md +203 -0
- package/skills/cache-configuration/SKILL.md +357 -0
- package/skills/cache-configuration/references/options.md +356 -0
- package/skills/getting-started/SKILL.md +407 -0
- package/skills/production-checklist/SKILL.md +397 -0
- package/skills/react-rendering/SKILL.md +424 -0
- package/skills/react-rendering/references/hooks.md +443 -0
- package/skills/store-authoring/SKILL.md +369 -0
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
//#region src/renderer/runtime.ts
|
|
2
|
+
const MISSING_BRIDGE_ERROR = "MediaCache bridge is unavailable. Wrap your app in <MediaCacheProvider> or expose the preload bridge on window.mediaCache.";
|
|
3
|
+
function toError(error) {
|
|
4
|
+
return error instanceof Error ? error : new Error(String(error));
|
|
5
|
+
}
|
|
6
|
+
function deriveMediaCachePhase(status) {
|
|
7
|
+
return status.data?.phase ?? (status.loading ? "loading" : "idle");
|
|
8
|
+
}
|
|
9
|
+
function resolveMediaCacheBridge(options) {
|
|
10
|
+
const key = options?.windowKey ?? "mediaCache";
|
|
11
|
+
const fromWindow = typeof window !== "undefined" ? window[key] : void 0;
|
|
12
|
+
const bridge = options?.bridge ?? fromWindow;
|
|
13
|
+
if (!bridge || typeof bridge.getStatus !== "function" || typeof bridge.subscribeStatus !== "function" || typeof bridge.syncNow !== "function" || typeof bridge.getAsset !== "function" || typeof bridge.listByIndex !== "function" || typeof bridge.findByFileStem !== "function") throw new Error(MISSING_BRIDGE_ERROR);
|
|
14
|
+
return bridge;
|
|
15
|
+
}
|
|
16
|
+
const EMPTY_DISABLED_STATUS_SNAPSHOT = {
|
|
17
|
+
data: null,
|
|
18
|
+
loading: false,
|
|
19
|
+
error: null,
|
|
20
|
+
refresh: async () => void 0
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Owns status fetch + `subscribeStatus` wiring; same behavior as the former
|
|
24
|
+
* `useMediaCacheStatusState` hook.
|
|
25
|
+
*/
|
|
26
|
+
function createMediaCacheStatusController(bridge, enabled) {
|
|
27
|
+
if (!enabled || !bridge) return {
|
|
28
|
+
getSnapshot: () => EMPTY_DISABLED_STATUS_SNAPSHOT,
|
|
29
|
+
subscribe: () => () => void 0,
|
|
30
|
+
refresh: async () => void 0,
|
|
31
|
+
dispose: () => void 0
|
|
32
|
+
};
|
|
33
|
+
const activeBridge = bridge;
|
|
34
|
+
let data = null;
|
|
35
|
+
let loading = true;
|
|
36
|
+
let error = null;
|
|
37
|
+
let requestSequence = 0;
|
|
38
|
+
const listeners = /* @__PURE__ */ new Set();
|
|
39
|
+
let unsubscribeBridge = null;
|
|
40
|
+
let disposed = false;
|
|
41
|
+
function emit() {
|
|
42
|
+
for (const listener of listeners) listener();
|
|
43
|
+
}
|
|
44
|
+
async function refresh() {
|
|
45
|
+
const requestId = ++requestSequence;
|
|
46
|
+
loading = true;
|
|
47
|
+
emit();
|
|
48
|
+
try {
|
|
49
|
+
const nextStatus = await activeBridge.getStatus();
|
|
50
|
+
if (requestId === requestSequence) {
|
|
51
|
+
data = nextStatus;
|
|
52
|
+
error = null;
|
|
53
|
+
}
|
|
54
|
+
} catch (caught) {
|
|
55
|
+
if (requestId === requestSequence) error = toError(caught);
|
|
56
|
+
} finally {
|
|
57
|
+
if (requestId === requestSequence) {
|
|
58
|
+
loading = false;
|
|
59
|
+
emit();
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
let cachedSnapshot = null;
|
|
64
|
+
function getSnapshot() {
|
|
65
|
+
if (cachedSnapshot && cachedSnapshot.data === data && cachedSnapshot.loading === loading && cachedSnapshot.error === error) return cachedSnapshot;
|
|
66
|
+
cachedSnapshot = {
|
|
67
|
+
data,
|
|
68
|
+
loading,
|
|
69
|
+
error,
|
|
70
|
+
refresh
|
|
71
|
+
};
|
|
72
|
+
return cachedSnapshot;
|
|
73
|
+
}
|
|
74
|
+
function subscribe(listener) {
|
|
75
|
+
listeners.add(listener);
|
|
76
|
+
return () => {
|
|
77
|
+
listeners.delete(listener);
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
function dispose() {
|
|
81
|
+
if (disposed) return;
|
|
82
|
+
disposed = true;
|
|
83
|
+
if (unsubscribeBridge) {
|
|
84
|
+
unsubscribeBridge();
|
|
85
|
+
unsubscribeBridge = null;
|
|
86
|
+
}
|
|
87
|
+
requestSequence += 1;
|
|
88
|
+
listeners.clear();
|
|
89
|
+
}
|
|
90
|
+
refresh();
|
|
91
|
+
unsubscribeBridge = activeBridge.subscribeStatus((status) => {
|
|
92
|
+
requestSequence += 1;
|
|
93
|
+
if (!disposed) {
|
|
94
|
+
data = status;
|
|
95
|
+
loading = false;
|
|
96
|
+
error = null;
|
|
97
|
+
emit();
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
return {
|
|
101
|
+
getSnapshot,
|
|
102
|
+
subscribe,
|
|
103
|
+
refresh,
|
|
104
|
+
dispose
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Shared query lifecycle: dependency-based refresh + optional refetch when
|
|
109
|
+
* `phase === "ready"` and `activeGenerationId` changes.
|
|
110
|
+
*/
|
|
111
|
+
function createMediaQueryWatcherInstance(options) {
|
|
112
|
+
const { status, getLoader, refetchOnSyncComplete, listener } = options;
|
|
113
|
+
let data = null;
|
|
114
|
+
let loading = true;
|
|
115
|
+
let error = null;
|
|
116
|
+
let requestSequence = 0;
|
|
117
|
+
let previousDeps = null;
|
|
118
|
+
let previousReadyGenerationId = null;
|
|
119
|
+
let disposed = false;
|
|
120
|
+
let cachedQuerySnapshot = null;
|
|
121
|
+
function notify() {
|
|
122
|
+
if (!disposed) listener(getSnapshot());
|
|
123
|
+
}
|
|
124
|
+
async function refresh() {
|
|
125
|
+
const requestId = ++requestSequence;
|
|
126
|
+
loading = true;
|
|
127
|
+
notify();
|
|
128
|
+
try {
|
|
129
|
+
const result = await getLoader()();
|
|
130
|
+
if (requestId === requestSequence) {
|
|
131
|
+
data = result;
|
|
132
|
+
error = null;
|
|
133
|
+
}
|
|
134
|
+
} catch (caught) {
|
|
135
|
+
if (requestId === requestSequence) error = toError(caught);
|
|
136
|
+
} finally {
|
|
137
|
+
if (requestId === requestSequence) loading = false;
|
|
138
|
+
notify();
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
function getSnapshot() {
|
|
142
|
+
if (cachedQuerySnapshot && cachedQuerySnapshot.data === data && cachedQuerySnapshot.loading === loading && cachedQuerySnapshot.error === error) return cachedQuerySnapshot;
|
|
143
|
+
cachedQuerySnapshot = {
|
|
144
|
+
data,
|
|
145
|
+
loading,
|
|
146
|
+
error,
|
|
147
|
+
refresh
|
|
148
|
+
};
|
|
149
|
+
return cachedQuerySnapshot;
|
|
150
|
+
}
|
|
151
|
+
function onStatusTick() {
|
|
152
|
+
const st = status.getSnapshot();
|
|
153
|
+
const phase = st.data?.phase;
|
|
154
|
+
const activeGenerationId = st.data?.activeGenerationId ?? null;
|
|
155
|
+
if (!refetchOnSyncComplete || phase !== "ready" || activeGenerationId === null) return;
|
|
156
|
+
if (previousReadyGenerationId !== activeGenerationId) {
|
|
157
|
+
previousReadyGenerationId = activeGenerationId;
|
|
158
|
+
refresh();
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
function syncDeps(refreshDeps) {
|
|
162
|
+
if (!(previousDeps === null || previousDeps.length !== refreshDeps.length || refreshDeps.some((dependency, index) => !Object.is(dependency, previousDeps[index])))) return;
|
|
163
|
+
previousDeps = refreshDeps;
|
|
164
|
+
refresh();
|
|
165
|
+
}
|
|
166
|
+
const unsubStatus = status.subscribe(() => {
|
|
167
|
+
onStatusTick();
|
|
168
|
+
});
|
|
169
|
+
onStatusTick();
|
|
170
|
+
return {
|
|
171
|
+
syncDeps,
|
|
172
|
+
onStatusTick,
|
|
173
|
+
getSnapshot,
|
|
174
|
+
refresh,
|
|
175
|
+
dispose() {
|
|
176
|
+
if (disposed) return;
|
|
177
|
+
disposed = true;
|
|
178
|
+
unsubStatus();
|
|
179
|
+
requestSequence += 1;
|
|
180
|
+
}
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
/** Framework-agnostic renderer client: shared status subscription and query watchers. */
|
|
184
|
+
function createMediaCacheRenderer(options) {
|
|
185
|
+
const bridge = resolveMediaCacheBridge(options);
|
|
186
|
+
const status = createMediaCacheStatusController(bridge, true);
|
|
187
|
+
const queryWatchers = /* @__PURE__ */ new Set();
|
|
188
|
+
function addQueryWatcher(instance) {
|
|
189
|
+
queryWatchers.add(instance);
|
|
190
|
+
return () => {
|
|
191
|
+
queryWatchers.delete(instance);
|
|
192
|
+
instance.dispose();
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
function subscribeCacheStatus(listener) {
|
|
196
|
+
listener(status.getSnapshot());
|
|
197
|
+
return status.subscribe(() => {
|
|
198
|
+
listener(status.getSnapshot());
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
return {
|
|
202
|
+
bridge,
|
|
203
|
+
subscribeCacheStatus,
|
|
204
|
+
watchMediaAsset(key, queryOptions, listener) {
|
|
205
|
+
const refetch = queryOptions?.refetchOnSyncComplete ?? true;
|
|
206
|
+
const stableKey = typeof key === "string" ? key : key.join("\0");
|
|
207
|
+
const instance = createMediaQueryWatcherInstance({
|
|
208
|
+
status,
|
|
209
|
+
getLoader: () => () => bridge.getAsset(key),
|
|
210
|
+
refetchOnSyncComplete: refetch,
|
|
211
|
+
listener
|
|
212
|
+
});
|
|
213
|
+
instance.syncDeps([
|
|
214
|
+
bridge,
|
|
215
|
+
"asset",
|
|
216
|
+
stableKey
|
|
217
|
+
]);
|
|
218
|
+
return addQueryWatcher(instance);
|
|
219
|
+
},
|
|
220
|
+
watchMediaByIndex(indexName, value, listOptions, listener) {
|
|
221
|
+
const cursor = listOptions?.cursor;
|
|
222
|
+
const limit = listOptions?.limit;
|
|
223
|
+
const instance = createMediaQueryWatcherInstance({
|
|
224
|
+
status,
|
|
225
|
+
getLoader: () => () => bridge.listByIndex(indexName, value, {
|
|
226
|
+
cursor,
|
|
227
|
+
limit
|
|
228
|
+
}),
|
|
229
|
+
refetchOnSyncComplete: listOptions?.refetchOnSyncComplete ?? true,
|
|
230
|
+
listener
|
|
231
|
+
});
|
|
232
|
+
instance.syncDeps([
|
|
233
|
+
bridge,
|
|
234
|
+
"index",
|
|
235
|
+
indexName,
|
|
236
|
+
value,
|
|
237
|
+
cursor,
|
|
238
|
+
limit
|
|
239
|
+
]);
|
|
240
|
+
return addQueryWatcher(instance);
|
|
241
|
+
},
|
|
242
|
+
watchFileStemMatch(stem, stemOptions, listener) {
|
|
243
|
+
const cursor = stemOptions?.cursor;
|
|
244
|
+
const limit = stemOptions?.limit;
|
|
245
|
+
const instance = createMediaQueryWatcherInstance({
|
|
246
|
+
status,
|
|
247
|
+
getLoader: () => () => bridge.findByFileStem(stem, {
|
|
248
|
+
cursor,
|
|
249
|
+
limit
|
|
250
|
+
}),
|
|
251
|
+
refetchOnSyncComplete: stemOptions?.refetchOnSyncComplete ?? true,
|
|
252
|
+
listener
|
|
253
|
+
});
|
|
254
|
+
instance.syncDeps([
|
|
255
|
+
bridge,
|
|
256
|
+
"fileStem",
|
|
257
|
+
stem,
|
|
258
|
+
cursor,
|
|
259
|
+
limit
|
|
260
|
+
]);
|
|
261
|
+
return addQueryWatcher(instance);
|
|
262
|
+
},
|
|
263
|
+
dispose() {
|
|
264
|
+
for (const watcher of queryWatchers) watcher.dispose();
|
|
265
|
+
queryWatchers.clear();
|
|
266
|
+
status.dispose();
|
|
267
|
+
}
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
//#endregion
|
|
271
|
+
export { MISSING_BRIDGE_ERROR, createMediaCacheRenderer, createMediaCacheStatusController, createMediaQueryWatcherInstance, deriveMediaCachePhase, resolveMediaCacheBridge };
|
|
272
|
+
|
|
273
|
+
//# sourceMappingURL=runtime.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime.js","names":[],"sources":["../../src/renderer/runtime.ts"],"sourcesContent":["import type {\n AssetKeyInput,\n FileStemMatch,\n MediaCacheBridge,\n MediaCachePhase,\n MediaCacheStatus,\n MediaQuerySyncOptions,\n PaginationInput,\n PaginationResult,\n ResolvedMediaAsset,\n} from \"../shared/types.js\";\n\n/** Async snapshot aligned with React hooks (`useMedia`, `useMediaCacheStatus`, etc.). */\nexport interface MediaAsyncState<T> {\n /** Latest resolved value, or `null` while loading/when unavailable. */\n data: T | null;\n /** `true` while an initial load or `refresh()` request is in flight. */\n loading: boolean;\n /** Last request error, or `null` when the latest request succeeded. */\n error: Error | null;\n /** Re-runs the underlying query and updates `data`/`error`. */\n refresh: () => Promise<void>;\n}\n\nexport const MISSING_BRIDGE_ERROR =\n \"MediaCache bridge is unavailable. Wrap your app in <MediaCacheProvider> or expose the preload bridge on window.mediaCache.\";\n\nexport function toError(error: unknown): Error {\n return error instanceof Error ? error : new Error(String(error));\n}\n\nexport function deriveMediaCachePhase(status: MediaAsyncState<MediaCacheStatus>): MediaCachePhase {\n return status.data?.phase ?? (status.loading ? \"loading\" : \"idle\");\n}\n\nexport function resolveMediaCacheBridge(options?: {\n bridge?: MediaCacheBridge;\n windowKey?: string;\n}): MediaCacheBridge {\n const key = options?.windowKey ?? \"mediaCache\";\n const fromWindow =\n typeof window !== \"undefined\" ? (window as unknown as Record<string, unknown>)[key] : undefined;\n\n const bridge = options?.bridge ?? (fromWindow as MediaCacheBridge | undefined);\n\n if (\n !bridge ||\n typeof bridge.getStatus !== \"function\" ||\n typeof bridge.subscribeStatus !== \"function\" ||\n typeof bridge.syncNow !== \"function\" ||\n typeof bridge.getAsset !== \"function\" ||\n typeof bridge.listByIndex !== \"function\" ||\n typeof bridge.findByFileStem !== \"function\"\n ) {\n throw new Error(MISSING_BRIDGE_ERROR);\n }\n\n return bridge;\n}\n\nconst EMPTY_DISABLED_STATUS_SNAPSHOT: MediaAsyncState<MediaCacheStatus> = {\n data: null,\n loading: false,\n error: null,\n refresh: async () => undefined,\n};\n\nexport interface MediaCacheStatusController {\n getSnapshot(): MediaAsyncState<MediaCacheStatus>;\n subscribe(listener: () => void): () => void;\n refresh(): Promise<void>;\n dispose(): void;\n}\n\n/**\n * Owns status fetch + `subscribeStatus` wiring; same behavior as the former\n * `useMediaCacheStatusState` hook.\n */\nexport function createMediaCacheStatusController(\n bridge: MediaCacheBridge | null,\n enabled: boolean,\n): MediaCacheStatusController {\n if (!enabled || !bridge) {\n return {\n getSnapshot: () => EMPTY_DISABLED_STATUS_SNAPSHOT,\n subscribe: () => () => undefined,\n refresh: async () => undefined,\n dispose: () => undefined,\n };\n }\n\n const activeBridge = bridge;\n\n let data: MediaCacheStatus | null = null;\n let loading = true;\n let error: Error | null = null;\n let requestSequence = 0;\n const listeners = new Set<() => void>();\n\n let unsubscribeBridge: (() => void) | null = null;\n let disposed = false;\n\n function emit(): void {\n for (const listener of listeners) {\n listener();\n }\n }\n\n async function refresh(): Promise<void> {\n const requestId = ++requestSequence;\n loading = true;\n emit();\n try {\n const nextStatus = await activeBridge.getStatus();\n if (requestId === requestSequence) {\n data = nextStatus;\n error = null;\n }\n } catch (caught) {\n if (requestId === requestSequence) {\n error = toError(caught);\n }\n } finally {\n if (requestId === requestSequence) {\n loading = false;\n emit();\n }\n }\n }\n\n let cachedSnapshot: MediaAsyncState<MediaCacheStatus> | null = null;\n\n function getSnapshot(): MediaAsyncState<MediaCacheStatus> {\n if (\n cachedSnapshot &&\n cachedSnapshot.data === data &&\n cachedSnapshot.loading === loading &&\n cachedSnapshot.error === error\n ) {\n return cachedSnapshot;\n }\n cachedSnapshot = { data, loading, error, refresh };\n return cachedSnapshot;\n }\n\n function subscribe(listener: () => void): () => void {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n }\n\n function dispose(): void {\n if (disposed) {\n return;\n }\n disposed = true;\n if (unsubscribeBridge) {\n unsubscribeBridge();\n unsubscribeBridge = null;\n }\n requestSequence += 1;\n listeners.clear();\n }\n\n void refresh();\n unsubscribeBridge = activeBridge.subscribeStatus((status) => {\n requestSequence += 1;\n if (!disposed) {\n data = status;\n loading = false;\n error = null;\n emit();\n }\n });\n\n return {\n getSnapshot,\n subscribe,\n refresh,\n dispose,\n };\n}\n\nexport interface MediaQueryWatcherInstance<T> {\n /** Compare deps to the previous call; refetches when the tuple changes. */\n syncDeps(deps: ReadonlyArray<unknown>): void;\n /** Run ready-generation refetch logic (also invoked on status updates). */\n onStatusTick(): void;\n getSnapshot(): MediaAsyncState<T>;\n /** Same as snapshot `refresh` — exposed for hosts that subscribe before first snapshot. */\n refresh(): Promise<void>;\n dispose(): void;\n}\n\n/**\n * Shared query lifecycle: dependency-based refresh + optional refetch when\n * `phase === \"ready\"` and `activeGenerationId` changes.\n */\nexport function createMediaQueryWatcherInstance<T>(options: {\n status: MediaCacheStatusController;\n /** Called on each load so callers can close over fresh arguments (React ref pattern). */\n getLoader: () => () => Promise<T>;\n refetchOnSyncComplete: boolean;\n listener: (state: MediaAsyncState<T>) => void;\n}): MediaQueryWatcherInstance<T> {\n const { status, getLoader, refetchOnSyncComplete, listener } = options;\n\n let data: T | null = null;\n let loading = true;\n let error: Error | null = null;\n let requestSequence = 0;\n let previousDeps: ReadonlyArray<unknown> | null = null;\n let previousReadyGenerationId: number | null = null;\n let disposed = false;\n let cachedQuerySnapshot: MediaAsyncState<T> | null = null;\n\n function notify(): void {\n if (!disposed) {\n listener(getSnapshot());\n }\n }\n\n async function refresh(): Promise<void> {\n const requestId = ++requestSequence;\n loading = true;\n notify();\n try {\n const result = await getLoader()();\n if (requestId === requestSequence) {\n data = result;\n error = null;\n }\n } catch (caught) {\n if (requestId === requestSequence) {\n error = toError(caught);\n }\n } finally {\n if (requestId === requestSequence) {\n loading = false;\n }\n notify();\n }\n }\n\n function getSnapshot(): MediaAsyncState<T> {\n if (\n cachedQuerySnapshot &&\n cachedQuerySnapshot.data === data &&\n cachedQuerySnapshot.loading === loading &&\n cachedQuerySnapshot.error === error\n ) {\n return cachedQuerySnapshot;\n }\n cachedQuerySnapshot = { data, loading, error, refresh };\n return cachedQuerySnapshot;\n }\n\n function onStatusTick(): void {\n const st = status.getSnapshot();\n const phase = st.data?.phase;\n const activeGenerationId = st.data?.activeGenerationId ?? null;\n\n if (!refetchOnSyncComplete || phase !== \"ready\" || activeGenerationId === null) {\n return;\n }\n\n if (previousReadyGenerationId !== activeGenerationId) {\n previousReadyGenerationId = activeGenerationId;\n void refresh();\n }\n }\n\n function syncDeps(refreshDeps: ReadonlyArray<unknown>): void {\n const shouldRefresh =\n previousDeps === null ||\n previousDeps.length !== refreshDeps.length ||\n refreshDeps.some((dependency, index) => !Object.is(dependency, previousDeps![index]));\n\n if (!shouldRefresh) {\n return;\n }\n\n previousDeps = refreshDeps;\n void refresh();\n }\n\n const unsubStatus = status.subscribe(() => {\n onStatusTick();\n });\n\n onStatusTick();\n\n return {\n syncDeps,\n onStatusTick,\n getSnapshot,\n refresh,\n dispose() {\n if (disposed) {\n return;\n }\n disposed = true;\n unsubStatus();\n requestSequence += 1;\n },\n };\n}\n\nexport interface CreateMediaCacheRendererOptions {\n bridge?: MediaCacheBridge;\n windowKey?: string;\n}\n\nexport interface MediaCacheRenderer {\n bridge: MediaCacheBridge;\n subscribeCacheStatus(listener: (state: MediaAsyncState<MediaCacheStatus>) => void): () => void;\n watchMediaAsset(\n key: AssetKeyInput,\n options: MediaQuerySyncOptions | undefined,\n listener: (state: MediaAsyncState<ResolvedMediaAsset | null>) => void,\n ): () => void;\n watchMediaByIndex(\n indexName: string,\n value: string,\n options: (PaginationInput & MediaQuerySyncOptions) | undefined,\n listener: (state: MediaAsyncState<PaginationResult<ResolvedMediaAsset>>) => void,\n ): () => void;\n watchFileStemMatch(\n stem: string,\n options: (PaginationInput & MediaQuerySyncOptions) | undefined,\n listener: (state: MediaAsyncState<PaginationResult<FileStemMatch>>) => void,\n ): () => void;\n dispose(): void;\n}\n\n/** Framework-agnostic renderer client: shared status subscription and query watchers. */\nexport function createMediaCacheRenderer(\n options?: CreateMediaCacheRendererOptions,\n): MediaCacheRenderer {\n const bridge = resolveMediaCacheBridge(options);\n const status = createMediaCacheStatusController(bridge, true);\n const queryWatchers = new Set<MediaQueryWatcherInstance<unknown>>();\n\n function addQueryWatcher<T>(instance: MediaQueryWatcherInstance<T>): () => void {\n queryWatchers.add(instance as MediaQueryWatcherInstance<unknown>);\n return () => {\n queryWatchers.delete(instance as MediaQueryWatcherInstance<unknown>);\n instance.dispose();\n };\n }\n\n function subscribeCacheStatus(\n listener: (state: MediaAsyncState<MediaCacheStatus>) => void,\n ): () => void {\n listener(status.getSnapshot());\n return status.subscribe(() => {\n listener(status.getSnapshot());\n });\n }\n\n return {\n bridge,\n subscribeCacheStatus,\n watchMediaAsset(key, queryOptions, listener) {\n const refetch = queryOptions?.refetchOnSyncComplete ?? true;\n const stableKey = typeof key === \"string\" ? key : key.join(\"\\0\");\n const instance = createMediaQueryWatcherInstance({\n status,\n getLoader: () => () => bridge.getAsset(key),\n refetchOnSyncComplete: refetch,\n listener,\n });\n instance.syncDeps([bridge, \"asset\", stableKey]);\n return addQueryWatcher(instance);\n },\n watchMediaByIndex(indexName, value, listOptions, listener) {\n const cursor = listOptions?.cursor;\n const limit = listOptions?.limit;\n const refetchOnSyncComplete = listOptions?.refetchOnSyncComplete;\n const refetch = refetchOnSyncComplete ?? true;\n const instance = createMediaQueryWatcherInstance({\n status,\n getLoader: () => () => bridge.listByIndex(indexName, value, { cursor, limit }),\n refetchOnSyncComplete: refetch,\n listener,\n });\n instance.syncDeps([bridge, \"index\", indexName, value, cursor, limit]);\n return addQueryWatcher(instance);\n },\n watchFileStemMatch(stem, stemOptions, listener) {\n const cursor = stemOptions?.cursor;\n const limit = stemOptions?.limit;\n const refetch = stemOptions?.refetchOnSyncComplete ?? true;\n const instance = createMediaQueryWatcherInstance({\n status,\n getLoader: () => () => bridge.findByFileStem(stem, { cursor, limit }),\n refetchOnSyncComplete: refetch,\n listener,\n });\n instance.syncDeps([bridge, \"fileStem\", stem, cursor, limit]);\n return addQueryWatcher(instance);\n },\n dispose() {\n for (const watcher of queryWatchers) {\n watcher.dispose();\n }\n queryWatchers.clear();\n status.dispose();\n },\n };\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"window-globals.d.cts","names":[],"sources":["../../src/renderer/window-globals.ts"],"mappings":";;;QAEQ,MAAA;EAAA,UACI,MAAA;IACR,UAAA,GAAa,gBAAA;EAAA;AAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"window-globals.d.ts","names":[],"sources":["../../src/renderer/window-globals.ts"],"mappings":";;;QAEQ,MAAA;EAAA,UACI,MAAA;IACR,UAAA,GAAa,gBAAA;EAAA;AAAA"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
//#region src/shared/errors.ts
|
|
3
|
+
/**
|
|
4
|
+
* Base class for cache errors; use `code` for stable programmatic handling.
|
|
5
|
+
* @param message - Human-readable error description.
|
|
6
|
+
* @param code - Machine-readable error code for branching (for example `SYNC_FAILURE`).
|
|
7
|
+
* @param options - Standard `ErrorOptions` (e.g. `{ cause }`).
|
|
8
|
+
*/
|
|
9
|
+
var MediaCacheError = class extends Error {
|
|
10
|
+
code;
|
|
11
|
+
constructor(message, code, options) {
|
|
12
|
+
super(message, options);
|
|
13
|
+
this.code = code;
|
|
14
|
+
this.name = "MediaCacheError";
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
/** Store from `resolveStore` is missing or inconsistent (indexes, assets, or structure). */
|
|
18
|
+
var StoreValidationError = class extends MediaCacheError {
|
|
19
|
+
constructor(message) {
|
|
20
|
+
super(message, "STORE_VALIDATION_ERROR");
|
|
21
|
+
this.name = "StoreValidationError";
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
/** Store-derived URLs have passed their declared expiration time and must not be downloaded. */
|
|
25
|
+
var StoreExpiredError = class extends MediaCacheError {
|
|
26
|
+
constructor(message, options) {
|
|
27
|
+
super(message, "STORE_EXPIRED", options);
|
|
28
|
+
this.name = "StoreExpiredError";
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
/** Another process or cache instance already owns the configured storage root. */
|
|
32
|
+
var StorageOwnershipError = class extends MediaCacheError {
|
|
33
|
+
constructor(message, options) {
|
|
34
|
+
super(message, "STORAGE_OWNERSHIP_ERROR", options);
|
|
35
|
+
this.name = "StorageOwnershipError";
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* Cache would exceed `maxCacheBytes`, violate `reserveFreeBytes`, disk is full (`ENOSPC`), or a
|
|
40
|
+
* commit would leave insufficient free space.
|
|
41
|
+
*/
|
|
42
|
+
var StorageLimitError = class extends MediaCacheError {
|
|
43
|
+
constructor(message, options) {
|
|
44
|
+
super(message, "STORAGE_LIMIT_ERROR", options);
|
|
45
|
+
this.name = "StorageLimitError";
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
/** Persisted state on disk fails validation (for example a corrupt status snapshot). */
|
|
49
|
+
var DataValidationError = class extends MediaCacheError {
|
|
50
|
+
constructor(message, options) {
|
|
51
|
+
super(message, "DATA_VALIDATION_ERROR", options);
|
|
52
|
+
this.name = "DataValidationError";
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
/** Network or HTTP failure while downloading an asset during sync (may be retryable internally). */
|
|
56
|
+
var SyncFailureError = class extends MediaCacheError {
|
|
57
|
+
constructor(message, options) {
|
|
58
|
+
super(message, "SYNC_FAILURE", options);
|
|
59
|
+
this.name = "SyncFailureError";
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
function toSerializedError(error) {
|
|
63
|
+
if (error instanceof MediaCacheError) return {
|
|
64
|
+
name: error.name,
|
|
65
|
+
code: error.code,
|
|
66
|
+
message: error.message
|
|
67
|
+
};
|
|
68
|
+
if (error instanceof Error) return {
|
|
69
|
+
name: error.name,
|
|
70
|
+
code: "UNKNOWN_ERROR",
|
|
71
|
+
message: error.message
|
|
72
|
+
};
|
|
73
|
+
return {
|
|
74
|
+
name: "UnknownError",
|
|
75
|
+
code: "UNKNOWN_ERROR",
|
|
76
|
+
message: String(error)
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
function isNoSpaceError(error) {
|
|
80
|
+
return error instanceof Error && collectErrorChain(error).some((entry) => "code" in entry && entry.code === "ENOSPC");
|
|
81
|
+
}
|
|
82
|
+
function collectErrorChain(error) {
|
|
83
|
+
const chain = [];
|
|
84
|
+
let current = error;
|
|
85
|
+
while (current instanceof Error && !chain.includes(current)) {
|
|
86
|
+
chain.push(current);
|
|
87
|
+
current = current.cause;
|
|
88
|
+
}
|
|
89
|
+
return chain;
|
|
90
|
+
}
|
|
91
|
+
//#endregion
|
|
92
|
+
exports.DataValidationError = DataValidationError;
|
|
93
|
+
exports.MediaCacheError = MediaCacheError;
|
|
94
|
+
exports.StorageLimitError = StorageLimitError;
|
|
95
|
+
exports.StorageOwnershipError = StorageOwnershipError;
|
|
96
|
+
exports.StoreExpiredError = StoreExpiredError;
|
|
97
|
+
exports.StoreValidationError = StoreValidationError;
|
|
98
|
+
exports.SyncFailureError = SyncFailureError;
|
|
99
|
+
exports.isNoSpaceError = isNoSpaceError;
|
|
100
|
+
exports.toSerializedError = toSerializedError;
|
|
101
|
+
|
|
102
|
+
//# sourceMappingURL=errors.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.cjs","names":[],"sources":["../../src/shared/errors.ts"],"sourcesContent":["import type { SerializedMediaCacheError } from \"./types.js\";\n\n/**\n * Base class for cache errors; use `code` for stable programmatic handling.\n * @param message - Human-readable error description.\n * @param code - Machine-readable error code for branching (for example `SYNC_FAILURE`).\n * @param options - Standard `ErrorOptions` (e.g. `{ cause }`).\n */\nexport class MediaCacheError extends Error {\n constructor(\n message: string,\n public readonly code: string,\n options?: ErrorOptions,\n ) {\n super(message, options);\n this.name = \"MediaCacheError\";\n }\n}\n\n/** Store from `resolveStore` is missing or inconsistent (indexes, assets, or structure). */\nexport class StoreValidationError extends MediaCacheError {\n constructor(message: string) {\n super(message, \"STORE_VALIDATION_ERROR\");\n this.name = \"StoreValidationError\";\n }\n}\n\n/** Store-derived URLs have passed their declared expiration time and must not be downloaded. */\nexport class StoreExpiredError extends MediaCacheError {\n constructor(message: string, options?: ErrorOptions) {\n super(message, \"STORE_EXPIRED\", options);\n this.name = \"StoreExpiredError\";\n }\n}\n\n/** Another process or cache instance already owns the configured storage root. */\nexport class StorageOwnershipError extends MediaCacheError {\n constructor(message: string, options?: ErrorOptions) {\n super(message, \"STORAGE_OWNERSHIP_ERROR\", options);\n this.name = \"StorageOwnershipError\";\n }\n}\n\n/**\n * Cache would exceed `maxCacheBytes`, violate `reserveFreeBytes`, disk is full (`ENOSPC`), or a\n * commit would leave insufficient free space.\n */\nexport class StorageLimitError extends MediaCacheError {\n constructor(message: string, options?: ErrorOptions) {\n super(message, \"STORAGE_LIMIT_ERROR\", options);\n this.name = \"StorageLimitError\";\n }\n}\n\n/** Persisted state on disk fails validation (for example a corrupt status snapshot). */\nexport class DataValidationError extends MediaCacheError {\n constructor(message: string, options?: ErrorOptions) {\n super(message, \"DATA_VALIDATION_ERROR\", options);\n this.name = \"DataValidationError\";\n }\n}\n\n/** Network or HTTP failure while downloading an asset during sync (may be retryable internally). */\nexport class SyncFailureError extends MediaCacheError {\n constructor(message: string, options?: ErrorOptions) {\n super(message, \"SYNC_FAILURE\", options);\n this.name = \"SyncFailureError\";\n }\n}\n\nexport function toSerializedError(error: unknown): SerializedMediaCacheError {\n if (error instanceof MediaCacheError) {\n return {\n name: error.name,\n code: error.code,\n message: error.message,\n };\n }\n\n if (error instanceof Error) {\n return {\n name: error.name,\n code: \"UNKNOWN_ERROR\",\n message: error.message,\n };\n }\n\n return {\n name: \"UnknownError\",\n code: \"UNKNOWN_ERROR\",\n message: String(error),\n };\n}\n\nexport function isNoSpaceError(error: unknown): boolean {\n return (\n error instanceof Error &&\n collectErrorChain(error).some(\n (entry) => \"code\" in entry && (entry as NodeJS.ErrnoException).code === \"ENOSPC\",\n )\n );\n}\n\nfunction collectErrorChain(error: Error): Error[] {\n const chain: Error[] = [];\n let current: unknown = error;\n\n while (current instanceof Error && !chain.includes(current)) {\n chain.push(current);\n current = current.cause;\n }\n\n return chain;\n}\n"],"mappings":";;;;;;;;AAQA,IAAa,kBAAb,cAAqC,MAAM;CAGvB;CAFlB,YACE,SACA,MACA,SACA;EACA,MAAM,SAAS,QAAQ;EAHP,KAAA,OAAA;EAIhB,KAAK,OAAO;;;;AAKhB,IAAa,uBAAb,cAA0C,gBAAgB;CACxD,YAAY,SAAiB;EAC3B,MAAM,SAAS,yBAAyB;EACxC,KAAK,OAAO;;;;AAKhB,IAAa,oBAAb,cAAuC,gBAAgB;CACrD,YAAY,SAAiB,SAAwB;EACnD,MAAM,SAAS,iBAAiB,QAAQ;EACxC,KAAK,OAAO;;;;AAKhB,IAAa,wBAAb,cAA2C,gBAAgB;CACzD,YAAY,SAAiB,SAAwB;EACnD,MAAM,SAAS,2BAA2B,QAAQ;EAClD,KAAK,OAAO;;;;;;;AAQhB,IAAa,oBAAb,cAAuC,gBAAgB;CACrD,YAAY,SAAiB,SAAwB;EACnD,MAAM,SAAS,uBAAuB,QAAQ;EAC9C,KAAK,OAAO;;;;AAKhB,IAAa,sBAAb,cAAyC,gBAAgB;CACvD,YAAY,SAAiB,SAAwB;EACnD,MAAM,SAAS,yBAAyB,QAAQ;EAChD,KAAK,OAAO;;;;AAKhB,IAAa,mBAAb,cAAsC,gBAAgB;CACpD,YAAY,SAAiB,SAAwB;EACnD,MAAM,SAAS,gBAAgB,QAAQ;EACvC,KAAK,OAAO;;;AAIhB,SAAgB,kBAAkB,OAA2C;CAC3E,IAAI,iBAAiB,iBACnB,OAAO;EACL,MAAM,MAAM;EACZ,MAAM,MAAM;EACZ,SAAS,MAAM;EAChB;CAGH,IAAI,iBAAiB,OACnB,OAAO;EACL,MAAM,MAAM;EACZ,MAAM;EACN,SAAS,MAAM;EAChB;CAGH,OAAO;EACL,MAAM;EACN,MAAM;EACN,SAAS,OAAO,MAAM;EACvB;;AAGH,SAAgB,eAAe,OAAyB;CACtD,OACE,iBAAiB,SACjB,kBAAkB,MAAM,CAAC,MACtB,UAAU,UAAU,SAAU,MAAgC,SAAS,SACzE;;AAIL,SAAS,kBAAkB,OAAuB;CAChD,MAAM,QAAiB,EAAE;CACzB,IAAI,UAAmB;CAEvB,OAAO,mBAAmB,SAAS,CAAC,MAAM,SAAS,QAAQ,EAAE;EAC3D,MAAM,KAAK,QAAQ;EACnB,UAAU,QAAQ;;CAGpB,OAAO"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { SerializedMediaCacheError } from "./types.cjs";
|
|
2
|
+
|
|
3
|
+
//#region src/shared/errors.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Base class for cache errors; use `code` for stable programmatic handling.
|
|
6
|
+
* @param message - Human-readable error description.
|
|
7
|
+
* @param code - Machine-readable error code for branching (for example `SYNC_FAILURE`).
|
|
8
|
+
* @param options - Standard `ErrorOptions` (e.g. `{ cause }`).
|
|
9
|
+
*/
|
|
10
|
+
declare class MediaCacheError extends Error {
|
|
11
|
+
readonly code: string;
|
|
12
|
+
constructor(message: string, code: string, options?: ErrorOptions);
|
|
13
|
+
}
|
|
14
|
+
/** Store from `resolveStore` is missing or inconsistent (indexes, assets, or structure). */
|
|
15
|
+
declare class StoreValidationError extends MediaCacheError {
|
|
16
|
+
constructor(message: string);
|
|
17
|
+
}
|
|
18
|
+
/** Store-derived URLs have passed their declared expiration time and must not be downloaded. */
|
|
19
|
+
declare class StoreExpiredError extends MediaCacheError {
|
|
20
|
+
constructor(message: string, options?: ErrorOptions);
|
|
21
|
+
}
|
|
22
|
+
/** Another process or cache instance already owns the configured storage root. */
|
|
23
|
+
declare class StorageOwnershipError extends MediaCacheError {
|
|
24
|
+
constructor(message: string, options?: ErrorOptions);
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Cache would exceed `maxCacheBytes`, violate `reserveFreeBytes`, disk is full (`ENOSPC`), or a
|
|
28
|
+
* commit would leave insufficient free space.
|
|
29
|
+
*/
|
|
30
|
+
declare class StorageLimitError extends MediaCacheError {
|
|
31
|
+
constructor(message: string, options?: ErrorOptions);
|
|
32
|
+
}
|
|
33
|
+
/** Persisted state on disk fails validation (for example a corrupt status snapshot). */
|
|
34
|
+
declare class DataValidationError extends MediaCacheError {
|
|
35
|
+
constructor(message: string, options?: ErrorOptions);
|
|
36
|
+
}
|
|
37
|
+
/** Network or HTTP failure while downloading an asset during sync (may be retryable internally). */
|
|
38
|
+
declare class SyncFailureError extends MediaCacheError {
|
|
39
|
+
constructor(message: string, options?: ErrorOptions);
|
|
40
|
+
}
|
|
41
|
+
declare function toSerializedError(error: unknown): SerializedMediaCacheError;
|
|
42
|
+
declare function isNoSpaceError(error: unknown): boolean;
|
|
43
|
+
//#endregion
|
|
44
|
+
export { DataValidationError, MediaCacheError, StorageLimitError, StorageOwnershipError, StoreExpiredError, StoreValidationError, SyncFailureError, isNoSpaceError, toSerializedError };
|
|
45
|
+
//# sourceMappingURL=errors.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.cts","names":[],"sources":["../../src/shared/errors.ts"],"mappings":";;;;;AAQA;;;;cAAa,eAAA,SAAwB,KAAA;EAAA,SAGjB,IAAA;cADhB,OAAA,UACgB,IAAA,UAChB,OAAA,GAAU,YAAA;AAAA;;cAQD,oBAAA,SAA6B,eAAA;cAC5B,OAAA;AAAA;;cAOD,iBAAA,SAA0B,eAAA;cACzB,OAAA,UAAiB,OAAA,GAAU,YAAA;AAAA;;cAO5B,qBAAA,SAA8B,eAAA;cAC7B,OAAA,UAAiB,OAAA,GAAU,YAAA;AAAA;;;AATzC;;cAmBa,iBAAA,SAA0B,eAAA;cACzB,OAAA,UAAiB,OAAA,GAAU,YAAA;AAAA;;cAO5B,mBAAA,SAA4B,eAAA;cAC3B,OAAA,UAAiB,OAAA,GAAU,YAAA;AAAA;;cAO5B,gBAAA,SAAyB,eAAA;cACxB,OAAA,UAAiB,OAAA,GAAU,YAAA;AAAA;AAAA,iBAMzB,iBAAA,CAAkB,KAAA,YAAiB,yBAAA;AAAA,iBAwBnC,cAAA,CAAe,KAAA"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { SerializedMediaCacheError } from "./types.js";
|
|
2
|
+
|
|
3
|
+
//#region src/shared/errors.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Base class for cache errors; use `code` for stable programmatic handling.
|
|
6
|
+
* @param message - Human-readable error description.
|
|
7
|
+
* @param code - Machine-readable error code for branching (for example `SYNC_FAILURE`).
|
|
8
|
+
* @param options - Standard `ErrorOptions` (e.g. `{ cause }`).
|
|
9
|
+
*/
|
|
10
|
+
declare class MediaCacheError extends Error {
|
|
11
|
+
readonly code: string;
|
|
12
|
+
constructor(message: string, code: string, options?: ErrorOptions);
|
|
13
|
+
}
|
|
14
|
+
/** Store from `resolveStore` is missing or inconsistent (indexes, assets, or structure). */
|
|
15
|
+
declare class StoreValidationError extends MediaCacheError {
|
|
16
|
+
constructor(message: string);
|
|
17
|
+
}
|
|
18
|
+
/** Store-derived URLs have passed their declared expiration time and must not be downloaded. */
|
|
19
|
+
declare class StoreExpiredError extends MediaCacheError {
|
|
20
|
+
constructor(message: string, options?: ErrorOptions);
|
|
21
|
+
}
|
|
22
|
+
/** Another process or cache instance already owns the configured storage root. */
|
|
23
|
+
declare class StorageOwnershipError extends MediaCacheError {
|
|
24
|
+
constructor(message: string, options?: ErrorOptions);
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Cache would exceed `maxCacheBytes`, violate `reserveFreeBytes`, disk is full (`ENOSPC`), or a
|
|
28
|
+
* commit would leave insufficient free space.
|
|
29
|
+
*/
|
|
30
|
+
declare class StorageLimitError extends MediaCacheError {
|
|
31
|
+
constructor(message: string, options?: ErrorOptions);
|
|
32
|
+
}
|
|
33
|
+
/** Persisted state on disk fails validation (for example a corrupt status snapshot). */
|
|
34
|
+
declare class DataValidationError extends MediaCacheError {
|
|
35
|
+
constructor(message: string, options?: ErrorOptions);
|
|
36
|
+
}
|
|
37
|
+
/** Network or HTTP failure while downloading an asset during sync (may be retryable internally). */
|
|
38
|
+
declare class SyncFailureError extends MediaCacheError {
|
|
39
|
+
constructor(message: string, options?: ErrorOptions);
|
|
40
|
+
}
|
|
41
|
+
declare function toSerializedError(error: unknown): SerializedMediaCacheError;
|
|
42
|
+
declare function isNoSpaceError(error: unknown): boolean;
|
|
43
|
+
//#endregion
|
|
44
|
+
export { DataValidationError, MediaCacheError, StorageLimitError, StorageOwnershipError, StoreExpiredError, StoreValidationError, SyncFailureError, isNoSpaceError, toSerializedError };
|
|
45
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","names":[],"sources":["../../src/shared/errors.ts"],"mappings":";;;;;AAQA;;;;cAAa,eAAA,SAAwB,KAAA;EAAA,SAGjB,IAAA;cADhB,OAAA,UACgB,IAAA,UAChB,OAAA,GAAU,YAAA;AAAA;;cAQD,oBAAA,SAA6B,eAAA;cAC5B,OAAA;AAAA;;cAOD,iBAAA,SAA0B,eAAA;cACzB,OAAA,UAAiB,OAAA,GAAU,YAAA;AAAA;;cAO5B,qBAAA,SAA8B,eAAA;cAC7B,OAAA,UAAiB,OAAA,GAAU,YAAA;AAAA;;;AATzC;;cAmBa,iBAAA,SAA0B,eAAA;cACzB,OAAA,UAAiB,OAAA,GAAU,YAAA;AAAA;;cAO5B,mBAAA,SAA4B,eAAA;cAC3B,OAAA,UAAiB,OAAA,GAAU,YAAA;AAAA;;cAO5B,gBAAA,SAAyB,eAAA;cACxB,OAAA,UAAiB,OAAA,GAAU,YAAA;AAAA;AAAA,iBAMzB,iBAAA,CAAkB,KAAA,YAAiB,yBAAA;AAAA,iBAwBnC,cAAA,CAAe,KAAA"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
//#region src/shared/errors.ts
|
|
2
|
+
/**
|
|
3
|
+
* Base class for cache errors; use `code` for stable programmatic handling.
|
|
4
|
+
* @param message - Human-readable error description.
|
|
5
|
+
* @param code - Machine-readable error code for branching (for example `SYNC_FAILURE`).
|
|
6
|
+
* @param options - Standard `ErrorOptions` (e.g. `{ cause }`).
|
|
7
|
+
*/
|
|
8
|
+
var MediaCacheError = class extends Error {
|
|
9
|
+
code;
|
|
10
|
+
constructor(message, code, options) {
|
|
11
|
+
super(message, options);
|
|
12
|
+
this.code = code;
|
|
13
|
+
this.name = "MediaCacheError";
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
/** Store from `resolveStore` is missing or inconsistent (indexes, assets, or structure). */
|
|
17
|
+
var StoreValidationError = class extends MediaCacheError {
|
|
18
|
+
constructor(message) {
|
|
19
|
+
super(message, "STORE_VALIDATION_ERROR");
|
|
20
|
+
this.name = "StoreValidationError";
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
/** Store-derived URLs have passed their declared expiration time and must not be downloaded. */
|
|
24
|
+
var StoreExpiredError = class extends MediaCacheError {
|
|
25
|
+
constructor(message, options) {
|
|
26
|
+
super(message, "STORE_EXPIRED", options);
|
|
27
|
+
this.name = "StoreExpiredError";
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
/** Another process or cache instance already owns the configured storage root. */
|
|
31
|
+
var StorageOwnershipError = class extends MediaCacheError {
|
|
32
|
+
constructor(message, options) {
|
|
33
|
+
super(message, "STORAGE_OWNERSHIP_ERROR", options);
|
|
34
|
+
this.name = "StorageOwnershipError";
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* Cache would exceed `maxCacheBytes`, violate `reserveFreeBytes`, disk is full (`ENOSPC`), or a
|
|
39
|
+
* commit would leave insufficient free space.
|
|
40
|
+
*/
|
|
41
|
+
var StorageLimitError = class extends MediaCacheError {
|
|
42
|
+
constructor(message, options) {
|
|
43
|
+
super(message, "STORAGE_LIMIT_ERROR", options);
|
|
44
|
+
this.name = "StorageLimitError";
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
/** Persisted state on disk fails validation (for example a corrupt status snapshot). */
|
|
48
|
+
var DataValidationError = class extends MediaCacheError {
|
|
49
|
+
constructor(message, options) {
|
|
50
|
+
super(message, "DATA_VALIDATION_ERROR", options);
|
|
51
|
+
this.name = "DataValidationError";
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
/** Network or HTTP failure while downloading an asset during sync (may be retryable internally). */
|
|
55
|
+
var SyncFailureError = class extends MediaCacheError {
|
|
56
|
+
constructor(message, options) {
|
|
57
|
+
super(message, "SYNC_FAILURE", options);
|
|
58
|
+
this.name = "SyncFailureError";
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
function toSerializedError(error) {
|
|
62
|
+
if (error instanceof MediaCacheError) return {
|
|
63
|
+
name: error.name,
|
|
64
|
+
code: error.code,
|
|
65
|
+
message: error.message
|
|
66
|
+
};
|
|
67
|
+
if (error instanceof Error) return {
|
|
68
|
+
name: error.name,
|
|
69
|
+
code: "UNKNOWN_ERROR",
|
|
70
|
+
message: error.message
|
|
71
|
+
};
|
|
72
|
+
return {
|
|
73
|
+
name: "UnknownError",
|
|
74
|
+
code: "UNKNOWN_ERROR",
|
|
75
|
+
message: String(error)
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
function isNoSpaceError(error) {
|
|
79
|
+
return error instanceof Error && collectErrorChain(error).some((entry) => "code" in entry && entry.code === "ENOSPC");
|
|
80
|
+
}
|
|
81
|
+
function collectErrorChain(error) {
|
|
82
|
+
const chain = [];
|
|
83
|
+
let current = error;
|
|
84
|
+
while (current instanceof Error && !chain.includes(current)) {
|
|
85
|
+
chain.push(current);
|
|
86
|
+
current = current.cause;
|
|
87
|
+
}
|
|
88
|
+
return chain;
|
|
89
|
+
}
|
|
90
|
+
//#endregion
|
|
91
|
+
export { DataValidationError, MediaCacheError, StorageLimitError, StorageOwnershipError, StoreExpiredError, StoreValidationError, SyncFailureError, isNoSpaceError, toSerializedError };
|
|
92
|
+
|
|
93
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","names":[],"sources":["../../src/shared/errors.ts"],"sourcesContent":["import type { SerializedMediaCacheError } from \"./types.js\";\n\n/**\n * Base class for cache errors; use `code` for stable programmatic handling.\n * @param message - Human-readable error description.\n * @param code - Machine-readable error code for branching (for example `SYNC_FAILURE`).\n * @param options - Standard `ErrorOptions` (e.g. `{ cause }`).\n */\nexport class MediaCacheError extends Error {\n constructor(\n message: string,\n public readonly code: string,\n options?: ErrorOptions,\n ) {\n super(message, options);\n this.name = \"MediaCacheError\";\n }\n}\n\n/** Store from `resolveStore` is missing or inconsistent (indexes, assets, or structure). */\nexport class StoreValidationError extends MediaCacheError {\n constructor(message: string) {\n super(message, \"STORE_VALIDATION_ERROR\");\n this.name = \"StoreValidationError\";\n }\n}\n\n/** Store-derived URLs have passed their declared expiration time and must not be downloaded. */\nexport class StoreExpiredError extends MediaCacheError {\n constructor(message: string, options?: ErrorOptions) {\n super(message, \"STORE_EXPIRED\", options);\n this.name = \"StoreExpiredError\";\n }\n}\n\n/** Another process or cache instance already owns the configured storage root. */\nexport class StorageOwnershipError extends MediaCacheError {\n constructor(message: string, options?: ErrorOptions) {\n super(message, \"STORAGE_OWNERSHIP_ERROR\", options);\n this.name = \"StorageOwnershipError\";\n }\n}\n\n/**\n * Cache would exceed `maxCacheBytes`, violate `reserveFreeBytes`, disk is full (`ENOSPC`), or a\n * commit would leave insufficient free space.\n */\nexport class StorageLimitError extends MediaCacheError {\n constructor(message: string, options?: ErrorOptions) {\n super(message, \"STORAGE_LIMIT_ERROR\", options);\n this.name = \"StorageLimitError\";\n }\n}\n\n/** Persisted state on disk fails validation (for example a corrupt status snapshot). */\nexport class DataValidationError extends MediaCacheError {\n constructor(message: string, options?: ErrorOptions) {\n super(message, \"DATA_VALIDATION_ERROR\", options);\n this.name = \"DataValidationError\";\n }\n}\n\n/** Network or HTTP failure while downloading an asset during sync (may be retryable internally). */\nexport class SyncFailureError extends MediaCacheError {\n constructor(message: string, options?: ErrorOptions) {\n super(message, \"SYNC_FAILURE\", options);\n this.name = \"SyncFailureError\";\n }\n}\n\nexport function toSerializedError(error: unknown): SerializedMediaCacheError {\n if (error instanceof MediaCacheError) {\n return {\n name: error.name,\n code: error.code,\n message: error.message,\n };\n }\n\n if (error instanceof Error) {\n return {\n name: error.name,\n code: \"UNKNOWN_ERROR\",\n message: error.message,\n };\n }\n\n return {\n name: \"UnknownError\",\n code: \"UNKNOWN_ERROR\",\n message: String(error),\n };\n}\n\nexport function isNoSpaceError(error: unknown): boolean {\n return (\n error instanceof Error &&\n collectErrorChain(error).some(\n (entry) => \"code\" in entry && (entry as NodeJS.ErrnoException).code === \"ENOSPC\",\n )\n );\n}\n\nfunction collectErrorChain(error: Error): Error[] {\n const chain: Error[] = [];\n let current: unknown = error;\n\n while (current instanceof Error && !chain.includes(current)) {\n chain.push(current);\n current = current.cause;\n }\n\n return chain;\n}\n"],"mappings":";;;;;;;AAQA,IAAa,kBAAb,cAAqC,MAAM;CAGvB;CAFlB,YACE,SACA,MACA,SACA;EACA,MAAM,SAAS,QAAQ;EAHP,KAAA,OAAA;EAIhB,KAAK,OAAO;;;;AAKhB,IAAa,uBAAb,cAA0C,gBAAgB;CACxD,YAAY,SAAiB;EAC3B,MAAM,SAAS,yBAAyB;EACxC,KAAK,OAAO;;;;AAKhB,IAAa,oBAAb,cAAuC,gBAAgB;CACrD,YAAY,SAAiB,SAAwB;EACnD,MAAM,SAAS,iBAAiB,QAAQ;EACxC,KAAK,OAAO;;;;AAKhB,IAAa,wBAAb,cAA2C,gBAAgB;CACzD,YAAY,SAAiB,SAAwB;EACnD,MAAM,SAAS,2BAA2B,QAAQ;EAClD,KAAK,OAAO;;;;;;;AAQhB,IAAa,oBAAb,cAAuC,gBAAgB;CACrD,YAAY,SAAiB,SAAwB;EACnD,MAAM,SAAS,uBAAuB,QAAQ;EAC9C,KAAK,OAAO;;;;AAKhB,IAAa,sBAAb,cAAyC,gBAAgB;CACvD,YAAY,SAAiB,SAAwB;EACnD,MAAM,SAAS,yBAAyB,QAAQ;EAChD,KAAK,OAAO;;;;AAKhB,IAAa,mBAAb,cAAsC,gBAAgB;CACpD,YAAY,SAAiB,SAAwB;EACnD,MAAM,SAAS,gBAAgB,QAAQ;EACvC,KAAK,OAAO;;;AAIhB,SAAgB,kBAAkB,OAA2C;CAC3E,IAAI,iBAAiB,iBACnB,OAAO;EACL,MAAM,MAAM;EACZ,MAAM,MAAM;EACZ,SAAS,MAAM;EAChB;CAGH,IAAI,iBAAiB,OACnB,OAAO;EACL,MAAM,MAAM;EACZ,MAAM;EACN,SAAS,MAAM;EAChB;CAGH,OAAO;EACL,MAAM;EACN,MAAM;EACN,SAAS,OAAO,MAAM;EACvB;;AAGH,SAAgB,eAAe,OAAyB;CACtD,OACE,iBAAiB,SACjB,kBAAkB,MAAM,CAAC,MACtB,UAAU,UAAU,SAAU,MAAgC,SAAS,SACzE;;AAIL,SAAS,kBAAkB,OAAuB;CAChD,MAAM,QAAiB,EAAE;CACzB,IAAI,UAAmB;CAEvB,OAAO,mBAAmB,SAAS,CAAC,MAAM,SAAS,QAAQ,EAAE;EAC3D,MAAM,KAAK,QAAQ;EACnB,UAAU,QAAQ;;CAGpB,OAAO"}
|