@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 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../src/react/index.tsx"],"sourcesContent":["import {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useLayoutEffect,\n useMemo,\n useReducer,\n useRef,\n useState,\n useSyncExternalStore,\n type PropsWithChildren,\n} from \"react\";\nimport type {\n AssetKeyInput,\n FileStemMatch,\n MediaCacheBridge,\n MediaCacheErrors,\n MediaCachePhase,\n MediaCacheReadyState,\n MediaCacheStatus,\n PaginationInput,\n PaginationResult,\n MediaQuerySyncOptions,\n ResolvedMediaAsset,\n} from \"../shared/types.js\";\nimport \"../renderer/window-globals.js\";\nimport {\n type MediaAsyncState,\n type MediaCacheStatusController,\n MISSING_BRIDGE_ERROR,\n createMediaCacheStatusController,\n createMediaQueryWatcherInstance,\n deriveMediaCachePhase,\n} from \"../renderer/runtime.js\";\nimport { aggregateMediaCacheErrors, mediaCacheReadyFromStatus } from \"../renderer/helpers.js\";\n\ntype AsyncState<T> = MediaAsyncState<T>;\n\ninterface MediaCacheContextValue {\n bridge: MediaCacheBridge | null;\n statusController: MediaCacheStatusController | null;\n queryErrors: Error[];\n reportQueryError: (id: string, error: Error | null) => void;\n}\n\nexport interface UseMediaBridgeResult extends MediaCacheBridge {\n status: AsyncState<MediaCacheStatus>;\n phase: MediaCachePhase;\n errors: MediaCacheErrors;\n}\n\nexport interface UseMediaCacheStatusResult extends AsyncState<MediaCacheStatus> {\n phase: MediaCachePhase;\n}\n\nconst MediaCacheContext = createContext<MediaCacheContextValue | null>(null);\nlet nextQueryErrorId = 0;\n\nexport function MediaCacheProvider({\n bridge,\n children,\n}: PropsWithChildren<{ bridge?: MediaCacheBridge }>) {\n const valueBridge = useMemo(() => bridge ?? window.mediaCache ?? null, [bridge]);\n const statusController = useMemo(\n () => createMediaCacheStatusController(valueBridge, valueBridge !== null),\n [valueBridge],\n );\n\n useEffect(() => () => statusController.dispose(), [statusController]);\n\n const [queryErrorsById, setQueryErrorsById] = useState<Map<string, Error>>(() => new Map());\n\n const reportQueryError = useCallback((id: string, error: Error | null) => {\n setQueryErrorsById((previous: Map<string, Error>) => {\n if (error === null) {\n if (!previous.has(id)) {\n return previous;\n }\n const next = new Map(previous);\n next.delete(id);\n return next;\n }\n\n if (previous.get(id) === error) {\n return previous;\n }\n\n const next = new Map(previous);\n next.set(id, error);\n return next;\n });\n }, []);\n\n const queryErrors = useMemo(() => Array.from(queryErrorsById.values()), [queryErrorsById]);\n const value = useMemo(\n () => ({\n bridge: valueBridge,\n statusController,\n queryErrors,\n reportQueryError,\n }),\n [valueBridge, statusController, queryErrors, reportQueryError],\n );\n\n return <MediaCacheContext.Provider value={value}>{children}</MediaCacheContext.Provider>;\n}\n\nexport function useMediaBridge(): UseMediaBridgeResult {\n const { bridge, status, queryErrors } = useMediaCacheRuntime();\n const errors = useMemo(\n () => aggregateMediaCacheErrors(status, queryErrors),\n [status, queryErrors],\n );\n\n return useMemo(\n () => ({\n ...bridge,\n status,\n phase: deriveMediaCachePhase(status),\n errors,\n }),\n [bridge, status, errors],\n );\n}\n\nexport function useMediaCacheStatus(): UseMediaCacheStatusResult {\n const status = useMediaCacheRuntime().status;\n return useMemo(() => ({ ...status, phase: deriveMediaCachePhase(status) }), [status]);\n}\n\n/**\n * Fetches a single asset by key.\n *\n * @param key - The asset key to look up. A string or array of string segments.\n * @param options - Optional sync-triggered refetch behavior.\n */\nexport function useMediaAsset(\n key: AssetKeyInput,\n options?: MediaQuerySyncOptions,\n): AsyncState<ResolvedMediaAsset | null> {\n const { bridge, statusController } = useMediaCacheRuntime();\n const stableKey = typeof key === \"string\" ? key : key.join(\"\\0\");\n return useAsyncResource(() => bridge.getAsset(key), [bridge, stableKey], statusController, {\n refetchOnSyncComplete: options?.refetchOnSyncComplete,\n });\n}\n\n/**\n * Lists assets matching a secondary index value.\n *\n * @param indexName - The index to query (e.g. `\"mimeType\"`, a user-defined index name).\n * @param value - The index value to match.\n * @param options - Optional pagination and sync-triggered refetch behavior.\n */\nexport function useMediaByIndex(\n indexName: string,\n value: string,\n options?: PaginationInput & MediaQuerySyncOptions,\n): AsyncState<PaginationResult<ResolvedMediaAsset>> {\n const { bridge, statusController } = useMediaCacheRuntime();\n const cursor = options?.cursor;\n const limit = options?.limit;\n return useAsyncResource(\n () => bridge.listByIndex(indexName, value, { cursor, limit }),\n [bridge, indexName, value, cursor, limit],\n statusController,\n { refetchOnSyncComplete: options?.refetchOnSyncComplete },\n );\n}\n\n/**\n * Searches assets by normalized file stem (file name without extension).\n *\n * @param stem - Normalized file stem to search for.\n * @param options - Optional pagination and sync-triggered refetch behavior.\n */\nexport function useFileStemMatch(\n stem: string,\n options?: PaginationInput & MediaQuerySyncOptions,\n): AsyncState<PaginationResult<FileStemMatch>> {\n const { bridge, statusController } = useMediaCacheRuntime();\n const cursor = options?.cursor;\n const limit = options?.limit;\n return useAsyncResource(\n () => bridge.findByFileStem(stem, { cursor, limit }),\n [bridge, stem, cursor, limit],\n statusController,\n { refetchOnSyncComplete: options?.refetchOnSyncComplete },\n );\n}\n\nexport function useMediaCacheReady(): AsyncState<MediaCacheReadyState> {\n const status = useMediaCacheStatus();\n\n return {\n data: mediaCacheReadyFromStatus(status.data ?? undefined),\n loading: status.loading,\n error: status.error,\n refresh: status.refresh,\n };\n}\n\nexport function useMediaCacheErrors(): MediaCacheErrors {\n const { status, queryErrors } = useMediaCacheRuntime();\n return aggregateMediaCacheErrors(status, queryErrors);\n}\n\nfunction useAsyncResource<T>(\n loader: () => Promise<T>,\n refreshDeps: ReadonlyArray<unknown>,\n statusController: MediaCacheStatusController,\n options?: MediaQuerySyncOptions,\n): AsyncState<T> {\n const latestLoader = useRef(loader);\n latestLoader.current = loader;\n\n const watcherRef = useRef<ReturnType<typeof createMediaQueryWatcherInstance<T>> | null>(null);\n const [, forceRender] = useReducer((count: number) => count + 1, 0);\n\n useLayoutEffect(() => {\n const instance = createMediaQueryWatcherInstance({\n status: statusController,\n getLoader: () => latestLoader.current,\n refetchOnSyncComplete: options?.refetchOnSyncComplete ?? true,\n listener: () => forceRender(),\n });\n watcherRef.current = instance;\n instance.syncDeps(refreshDeps);\n forceRender();\n return () => {\n instance.dispose();\n watcherRef.current = null;\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps -- deps compared imperatively via syncDeps\n }, [statusController, options?.refetchOnSyncComplete]);\n\n useEffect(() => {\n watcherRef.current?.syncDeps(refreshDeps);\n });\n\n const snapshot =\n watcherRef.current?.getSnapshot() ??\n ({\n data: null,\n loading: true,\n error: null,\n refresh: async () => {\n await watcherRef.current?.refresh();\n },\n } as AsyncState<T>);\n\n useQueryErrorRegistration(snapshot.error);\n\n return snapshot;\n}\n\nfunction useMediaCacheRuntime(): {\n bridge: MediaCacheBridge;\n status: AsyncState<MediaCacheStatus>;\n statusController: MediaCacheStatusController;\n queryErrors: Error[];\n} {\n const runtime = useContext(MediaCacheContext);\n const bridge = runtime?.bridge;\n const statusController = runtime?.statusController;\n\n if (!bridge || !statusController) {\n throw new Error(MISSING_BRIDGE_ERROR);\n }\n\n const status = useSyncExternalStore(\n statusController.subscribe,\n statusController.getSnapshot,\n statusController.getSnapshot,\n );\n\n return {\n bridge,\n status,\n statusController,\n queryErrors: runtime.queryErrors,\n };\n}\n\nfunction useQueryErrorRegistration(error: Error | null): void {\n const runtime = useContext(MediaCacheContext);\n const queryErrorId = useRef<string | null>(null);\n\n if (queryErrorId.current === null) {\n queryErrorId.current = `query-error-${nextQueryErrorId++}`;\n }\n\n useEffect(() => {\n if (!runtime) {\n return;\n }\n\n runtime.reportQueryError(queryErrorId.current!, error);\n\n return () => {\n runtime.reportQueryError(queryErrorId.current!, null);\n };\n }, [runtime, error]);\n}\n\nexport type {\n AssetKeyInput,\n FileStemMatch,\n MediaCacheBridge,\n MediaCacheErrors,\n MediaCachePhase,\n MediaCacheReadyState,\n MediaCacheStatus,\n MediaQuerySyncOptions,\n ResolvedMediaAsset,\n} from \"../shared/types.js\";\n"],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
//#region src/renderer/helpers.ts
|
|
2
|
+
function toPrimaryError(syncError) {
|
|
3
|
+
if (!syncError) return null;
|
|
4
|
+
const error = new Error(syncError.message);
|
|
5
|
+
error.name = syncError.name;
|
|
6
|
+
return error;
|
|
7
|
+
}
|
|
8
|
+
/** Derive {@link MediaCacheReadyState} from a status snapshot, or `null` if status is missing. */
|
|
9
|
+
function mediaCacheReadyFromStatus(status) {
|
|
10
|
+
if (!status) return null;
|
|
11
|
+
return {
|
|
12
|
+
ready: status.phase === "ready",
|
|
13
|
+
syncing: status.phase === "syncing",
|
|
14
|
+
phase: status.phase,
|
|
15
|
+
activeGenerationId: status.activeGenerationId,
|
|
16
|
+
syncError: status.error
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
/** Combine status loading failures, sync errors, and query errors (same rules as `useMediaCacheErrors`). */
|
|
20
|
+
function aggregateMediaCacheErrors(statusState, queryErrors) {
|
|
21
|
+
const syncError = statusState.data?.error ?? null;
|
|
22
|
+
const statusError = statusState.error;
|
|
23
|
+
const primaryError = statusError ?? queryErrors[0] ?? toPrimaryError(syncError);
|
|
24
|
+
return {
|
|
25
|
+
syncError,
|
|
26
|
+
statusError,
|
|
27
|
+
queryErrors,
|
|
28
|
+
hasError: primaryError !== null,
|
|
29
|
+
primaryError
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
//#endregion
|
|
33
|
+
exports.aggregateMediaCacheErrors = aggregateMediaCacheErrors;
|
|
34
|
+
exports.mediaCacheReadyFromStatus = mediaCacheReadyFromStatus;
|
|
35
|
+
|
|
36
|
+
//# sourceMappingURL=helpers.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.cjs","names":[],"sources":["../../src/renderer/helpers.ts"],"sourcesContent":["import type { MediaCacheErrors, MediaCacheReadyState, MediaCacheStatus } from \"../shared/types.js\";\nimport type { MediaAsyncState } from \"./runtime.js\";\n\nfunction toPrimaryError(syncError: MediaCacheStatus[\"error\"]): Error | null {\n if (!syncError) {\n return null;\n }\n\n const error = new Error(syncError.message);\n error.name = syncError.name;\n return error;\n}\n\n/** Derive {@link MediaCacheReadyState} from a status snapshot, or `null` if status is missing. */\nexport function mediaCacheReadyFromStatus(\n status: MediaCacheStatus | null | undefined,\n): MediaCacheReadyState | null {\n if (!status) {\n return null;\n }\n\n return {\n ready: status.phase === \"ready\",\n syncing: status.phase === \"syncing\",\n phase: status.phase,\n activeGenerationId: status.activeGenerationId,\n syncError: status.error,\n };\n}\n\n/** Combine status loading failures, sync errors, and query errors (same rules as `useMediaCacheErrors`). */\nexport function aggregateMediaCacheErrors(\n statusState: MediaAsyncState<MediaCacheStatus>,\n queryErrors: Error[],\n): MediaCacheErrors {\n const syncError = statusState.data?.error ?? null;\n const statusError = statusState.error;\n const primaryError = statusError ?? queryErrors[0] ?? toPrimaryError(syncError);\n\n return {\n syncError,\n statusError,\n queryErrors,\n hasError: primaryError !== null,\n primaryError,\n };\n}\n"],"mappings":";AAGA,SAAS,eAAe,WAAoD;CAC1E,IAAI,CAAC,WACH,OAAO;CAGT,MAAM,QAAQ,IAAI,MAAM,UAAU,QAAQ;CAC1C,MAAM,OAAO,UAAU;CACvB,OAAO;;;AAIT,SAAgB,0BACd,QAC6B;CAC7B,IAAI,CAAC,QACH,OAAO;CAGT,OAAO;EACL,OAAO,OAAO,UAAU;EACxB,SAAS,OAAO,UAAU;EAC1B,OAAO,OAAO;EACd,oBAAoB,OAAO;EAC3B,WAAW,OAAO;EACnB;;;AAIH,SAAgB,0BACd,aACA,aACkB;CAClB,MAAM,YAAY,YAAY,MAAM,SAAS;CAC7C,MAAM,cAAc,YAAY;CAChC,MAAM,eAAe,eAAe,YAAY,MAAM,eAAe,UAAU;CAE/E,OAAO;EACL;EACA;EACA;EACA,UAAU,iBAAiB;EAC3B;EACD"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { MediaCacheErrors, MediaCacheReadyState, MediaCacheStatus } from "../shared/types.cjs";
|
|
2
|
+
import { MediaAsyncState } from "./runtime.cjs";
|
|
3
|
+
|
|
4
|
+
//#region src/renderer/helpers.d.ts
|
|
5
|
+
/** Derive {@link MediaCacheReadyState} from a status snapshot, or `null` if status is missing. */
|
|
6
|
+
declare function mediaCacheReadyFromStatus(status: MediaCacheStatus | null | undefined): MediaCacheReadyState | null;
|
|
7
|
+
/** Combine status loading failures, sync errors, and query errors (same rules as `useMediaCacheErrors`). */
|
|
8
|
+
declare function aggregateMediaCacheErrors(statusState: MediaAsyncState<MediaCacheStatus>, queryErrors: Error[]): MediaCacheErrors;
|
|
9
|
+
//#endregion
|
|
10
|
+
export { aggregateMediaCacheErrors, mediaCacheReadyFromStatus };
|
|
11
|
+
//# sourceMappingURL=helpers.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.d.cts","names":[],"sources":["../../src/renderer/helpers.ts"],"mappings":";;;;;iBAcgB,yBAAA,CACd,MAAA,EAAQ,gBAAA,sBACP,oBAAA;AAFH;AAAA,iBAiBgB,yBAAA,CACd,WAAA,EAAa,eAAA,CAAgB,gBAAA,GAC7B,WAAA,EAAa,KAAA,KACZ,gBAAA"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { MediaCacheErrors, MediaCacheReadyState, MediaCacheStatus } from "../shared/types.js";
|
|
2
|
+
import { MediaAsyncState } from "./runtime.js";
|
|
3
|
+
|
|
4
|
+
//#region src/renderer/helpers.d.ts
|
|
5
|
+
/** Derive {@link MediaCacheReadyState} from a status snapshot, or `null` if status is missing. */
|
|
6
|
+
declare function mediaCacheReadyFromStatus(status: MediaCacheStatus | null | undefined): MediaCacheReadyState | null;
|
|
7
|
+
/** Combine status loading failures, sync errors, and query errors (same rules as `useMediaCacheErrors`). */
|
|
8
|
+
declare function aggregateMediaCacheErrors(statusState: MediaAsyncState<MediaCacheStatus>, queryErrors: Error[]): MediaCacheErrors;
|
|
9
|
+
//#endregion
|
|
10
|
+
export { aggregateMediaCacheErrors, mediaCacheReadyFromStatus };
|
|
11
|
+
//# sourceMappingURL=helpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.d.ts","names":[],"sources":["../../src/renderer/helpers.ts"],"mappings":";;;;;iBAcgB,yBAAA,CACd,MAAA,EAAQ,gBAAA,sBACP,oBAAA;AAFH;AAAA,iBAiBgB,yBAAA,CACd,WAAA,EAAa,eAAA,CAAgB,gBAAA,GAC7B,WAAA,EAAa,KAAA,KACZ,gBAAA"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
//#region src/renderer/helpers.ts
|
|
2
|
+
function toPrimaryError(syncError) {
|
|
3
|
+
if (!syncError) return null;
|
|
4
|
+
const error = new Error(syncError.message);
|
|
5
|
+
error.name = syncError.name;
|
|
6
|
+
return error;
|
|
7
|
+
}
|
|
8
|
+
/** Derive {@link MediaCacheReadyState} from a status snapshot, or `null` if status is missing. */
|
|
9
|
+
function mediaCacheReadyFromStatus(status) {
|
|
10
|
+
if (!status) return null;
|
|
11
|
+
return {
|
|
12
|
+
ready: status.phase === "ready",
|
|
13
|
+
syncing: status.phase === "syncing",
|
|
14
|
+
phase: status.phase,
|
|
15
|
+
activeGenerationId: status.activeGenerationId,
|
|
16
|
+
syncError: status.error
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
/** Combine status loading failures, sync errors, and query errors (same rules as `useMediaCacheErrors`). */
|
|
20
|
+
function aggregateMediaCacheErrors(statusState, queryErrors) {
|
|
21
|
+
const syncError = statusState.data?.error ?? null;
|
|
22
|
+
const statusError = statusState.error;
|
|
23
|
+
const primaryError = statusError ?? queryErrors[0] ?? toPrimaryError(syncError);
|
|
24
|
+
return {
|
|
25
|
+
syncError,
|
|
26
|
+
statusError,
|
|
27
|
+
queryErrors,
|
|
28
|
+
hasError: primaryError !== null,
|
|
29
|
+
primaryError
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
//#endregion
|
|
33
|
+
export { aggregateMediaCacheErrors, mediaCacheReadyFromStatus };
|
|
34
|
+
|
|
35
|
+
//# sourceMappingURL=helpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.js","names":[],"sources":["../../src/renderer/helpers.ts"],"sourcesContent":["import type { MediaCacheErrors, MediaCacheReadyState, MediaCacheStatus } from \"../shared/types.js\";\nimport type { MediaAsyncState } from \"./runtime.js\";\n\nfunction toPrimaryError(syncError: MediaCacheStatus[\"error\"]): Error | null {\n if (!syncError) {\n return null;\n }\n\n const error = new Error(syncError.message);\n error.name = syncError.name;\n return error;\n}\n\n/** Derive {@link MediaCacheReadyState} from a status snapshot, or `null` if status is missing. */\nexport function mediaCacheReadyFromStatus(\n status: MediaCacheStatus | null | undefined,\n): MediaCacheReadyState | null {\n if (!status) {\n return null;\n }\n\n return {\n ready: status.phase === \"ready\",\n syncing: status.phase === \"syncing\",\n phase: status.phase,\n activeGenerationId: status.activeGenerationId,\n syncError: status.error,\n };\n}\n\n/** Combine status loading failures, sync errors, and query errors (same rules as `useMediaCacheErrors`). */\nexport function aggregateMediaCacheErrors(\n statusState: MediaAsyncState<MediaCacheStatus>,\n queryErrors: Error[],\n): MediaCacheErrors {\n const syncError = statusState.data?.error ?? null;\n const statusError = statusState.error;\n const primaryError = statusError ?? queryErrors[0] ?? toPrimaryError(syncError);\n\n return {\n syncError,\n statusError,\n queryErrors,\n hasError: primaryError !== null,\n primaryError,\n };\n}\n"],"mappings":";AAGA,SAAS,eAAe,WAAoD;CAC1E,IAAI,CAAC,WACH,OAAO;CAGT,MAAM,QAAQ,IAAI,MAAM,UAAU,QAAQ;CAC1C,MAAM,OAAO,UAAU;CACvB,OAAO;;;AAIT,SAAgB,0BACd,QAC6B;CAC7B,IAAI,CAAC,QACH,OAAO;CAGT,OAAO;EACL,OAAO,OAAO,UAAU;EACxB,SAAS,OAAO,UAAU;EAC1B,OAAO,OAAO;EACd,oBAAoB,OAAO;EAC3B,WAAW,OAAO;EACnB;;;AAIH,SAAgB,0BACd,aACA,aACkB;CAClB,MAAM,YAAY,YAAY,MAAM,SAAS;CAC7C,MAAM,cAAc,YAAY;CAChC,MAAM,eAAe,eAAe,YAAY,MAAM,eAAe,UAAU;CAE/E,OAAO;EACL;EACA;EACA;EACA,UAAU,iBAAiB;EAC3B;EACD"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_runtime = require("./runtime.cjs");
|
|
3
|
+
const require_helpers = require("./helpers.cjs");
|
|
4
|
+
//#region src/renderer/index.ts
|
|
5
|
+
/**
|
|
6
|
+
* Framework-agnostic entry: resolves the preload bridge, subscribes to cache status,
|
|
7
|
+
* and exposes watchers aligned with the React hooks’ async semantics.
|
|
8
|
+
*/
|
|
9
|
+
function createMediaCacheRenderer(options) {
|
|
10
|
+
return require_runtime.createMediaCacheRenderer(options);
|
|
11
|
+
}
|
|
12
|
+
//#endregion
|
|
13
|
+
exports.MISSING_BRIDGE_ERROR = require_runtime.MISSING_BRIDGE_ERROR;
|
|
14
|
+
exports.aggregateMediaCacheErrors = require_helpers.aggregateMediaCacheErrors;
|
|
15
|
+
exports.createMediaCacheRenderer = createMediaCacheRenderer;
|
|
16
|
+
exports.deriveMediaCachePhase = require_runtime.deriveMediaCachePhase;
|
|
17
|
+
exports.mediaCacheReadyFromStatus = require_helpers.mediaCacheReadyFromStatus;
|
|
18
|
+
exports.resolveMediaCacheBridge = require_runtime.resolveMediaCacheBridge;
|
|
19
|
+
|
|
20
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["createMediaCacheRendererImpl"],"sources":["../../src/renderer/index.ts"],"sourcesContent":["import \"./window-globals.js\";\nimport type { MediaAsyncState } from \"./runtime.js\";\nimport {\n type CreateMediaCacheRendererOptions,\n type MediaCacheRenderer,\n createMediaCacheRenderer as createMediaCacheRendererImpl,\n} from \"./runtime.js\";\n\nexport { aggregateMediaCacheErrors, mediaCacheReadyFromStatus } from \"./helpers.js\";\n\nexport type { MediaAsyncState };\nexport { MISSING_BRIDGE_ERROR, deriveMediaCachePhase, resolveMediaCacheBridge } from \"./runtime.js\";\n\nexport type CreateMediaCacheRendererInput = CreateMediaCacheRendererOptions;\n\n/**\n * Framework-agnostic entry: resolves the preload bridge, subscribes to cache status,\n * and exposes watchers aligned with the React hooks’ async semantics.\n */\nexport function createMediaCacheRenderer(\n options?: CreateMediaCacheRendererOptions,\n): MediaCacheRenderer {\n return createMediaCacheRendererImpl(options);\n}\n\nexport type {\n AssetKeyInput,\n FileStemMatch,\n MediaCacheBridge,\n MediaCacheErrors,\n MediaCachePhase,\n MediaCacheReadyState,\n MediaCacheStatus,\n MediaQuerySyncOptions,\n PaginationInput,\n PaginationResult,\n ResolvedMediaAsset,\n} from \"../shared/types.js\";\n"],"mappings":";;;;;;;;AAmBA,SAAgB,yBACd,SACoB;CACpB,OAAOA,gBAAAA,yBAA6B,QAAQ"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { AssetKeyInput, FileStemMatch, MediaCacheBridge, MediaCacheErrors, MediaCachePhase, MediaCacheReadyState, MediaCacheStatus, MediaQuerySyncOptions, PaginationInput, PaginationResult, ResolvedMediaAsset } from "../shared/types.cjs";
|
|
2
|
+
import { CreateMediaCacheRendererOptions, MISSING_BRIDGE_ERROR, MediaAsyncState, MediaCacheRenderer, deriveMediaCachePhase, resolveMediaCacheBridge } from "./runtime.cjs";
|
|
3
|
+
import { aggregateMediaCacheErrors, mediaCacheReadyFromStatus } from "./helpers.cjs";
|
|
4
|
+
|
|
5
|
+
//#region src/renderer/index.d.ts
|
|
6
|
+
type CreateMediaCacheRendererInput = CreateMediaCacheRendererOptions;
|
|
7
|
+
/**
|
|
8
|
+
* Framework-agnostic entry: resolves the preload bridge, subscribes to cache status,
|
|
9
|
+
* and exposes watchers aligned with the React hooks’ async semantics.
|
|
10
|
+
*/
|
|
11
|
+
declare function createMediaCacheRenderer(options?: CreateMediaCacheRendererOptions): MediaCacheRenderer;
|
|
12
|
+
//#endregion
|
|
13
|
+
export { type AssetKeyInput, CreateMediaCacheRendererInput, type FileStemMatch, MISSING_BRIDGE_ERROR, type MediaAsyncState, type MediaCacheBridge, type MediaCacheErrors, type MediaCachePhase, type MediaCacheReadyState, type MediaCacheStatus, type MediaQuerySyncOptions, type PaginationInput, type PaginationResult, type ResolvedMediaAsset, aggregateMediaCacheErrors, createMediaCacheRenderer, deriveMediaCachePhase, mediaCacheReadyFromStatus, resolveMediaCacheBridge };
|
|
14
|
+
//# sourceMappingURL=index.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.cts","names":[],"sources":["../../src/renderer/index.ts"],"mappings":";;;;;KAaY,6BAAA,GAAgC,+BAAA;;;;;iBAM5B,wBAAA,CACd,OAAA,GAAU,+BAAA,GACT,kBAAA"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { AssetKeyInput, FileStemMatch, MediaCacheBridge, MediaCacheErrors, MediaCachePhase, MediaCacheReadyState, MediaCacheStatus, MediaQuerySyncOptions, PaginationInput, PaginationResult, ResolvedMediaAsset } from "../shared/types.js";
|
|
2
|
+
import { CreateMediaCacheRendererOptions, MISSING_BRIDGE_ERROR, MediaAsyncState, MediaCacheRenderer, deriveMediaCachePhase, resolveMediaCacheBridge } from "./runtime.js";
|
|
3
|
+
import { aggregateMediaCacheErrors, mediaCacheReadyFromStatus } from "./helpers.js";
|
|
4
|
+
|
|
5
|
+
//#region src/renderer/index.d.ts
|
|
6
|
+
type CreateMediaCacheRendererInput = CreateMediaCacheRendererOptions;
|
|
7
|
+
/**
|
|
8
|
+
* Framework-agnostic entry: resolves the preload bridge, subscribes to cache status,
|
|
9
|
+
* and exposes watchers aligned with the React hooks’ async semantics.
|
|
10
|
+
*/
|
|
11
|
+
declare function createMediaCacheRenderer(options?: CreateMediaCacheRendererOptions): MediaCacheRenderer;
|
|
12
|
+
//#endregion
|
|
13
|
+
export { type AssetKeyInput, CreateMediaCacheRendererInput, type FileStemMatch, MISSING_BRIDGE_ERROR, type MediaAsyncState, type MediaCacheBridge, type MediaCacheErrors, type MediaCachePhase, type MediaCacheReadyState, type MediaCacheStatus, type MediaQuerySyncOptions, type PaginationInput, type PaginationResult, type ResolvedMediaAsset, aggregateMediaCacheErrors, createMediaCacheRenderer, deriveMediaCachePhase, mediaCacheReadyFromStatus, resolveMediaCacheBridge };
|
|
14
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../../src/renderer/index.ts"],"mappings":";;;;;KAaY,6BAAA,GAAgC,+BAAA;;;;;iBAM5B,wBAAA,CACd,OAAA,GAAU,+BAAA,GACT,kBAAA"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { MISSING_BRIDGE_ERROR, createMediaCacheRenderer as createMediaCacheRenderer$1, deriveMediaCachePhase, resolveMediaCacheBridge } from "./runtime.js";
|
|
2
|
+
import { aggregateMediaCacheErrors, mediaCacheReadyFromStatus } from "./helpers.js";
|
|
3
|
+
//#region src/renderer/index.ts
|
|
4
|
+
/**
|
|
5
|
+
* Framework-agnostic entry: resolves the preload bridge, subscribes to cache status,
|
|
6
|
+
* and exposes watchers aligned with the React hooks’ async semantics.
|
|
7
|
+
*/
|
|
8
|
+
function createMediaCacheRenderer(options) {
|
|
9
|
+
return createMediaCacheRenderer$1(options);
|
|
10
|
+
}
|
|
11
|
+
//#endregion
|
|
12
|
+
export { MISSING_BRIDGE_ERROR, aggregateMediaCacheErrors, createMediaCacheRenderer, deriveMediaCachePhase, mediaCacheReadyFromStatus, resolveMediaCacheBridge };
|
|
13
|
+
|
|
14
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":["createMediaCacheRendererImpl"],"sources":["../../src/renderer/index.ts"],"sourcesContent":["import \"./window-globals.js\";\nimport type { MediaAsyncState } from \"./runtime.js\";\nimport {\n type CreateMediaCacheRendererOptions,\n type MediaCacheRenderer,\n createMediaCacheRenderer as createMediaCacheRendererImpl,\n} from \"./runtime.js\";\n\nexport { aggregateMediaCacheErrors, mediaCacheReadyFromStatus } from \"./helpers.js\";\n\nexport type { MediaAsyncState };\nexport { MISSING_BRIDGE_ERROR, deriveMediaCachePhase, resolveMediaCacheBridge } from \"./runtime.js\";\n\nexport type CreateMediaCacheRendererInput = CreateMediaCacheRendererOptions;\n\n/**\n * Framework-agnostic entry: resolves the preload bridge, subscribes to cache status,\n * and exposes watchers aligned with the React hooks’ async semantics.\n */\nexport function createMediaCacheRenderer(\n options?: CreateMediaCacheRendererOptions,\n): MediaCacheRenderer {\n return createMediaCacheRendererImpl(options);\n}\n\nexport type {\n AssetKeyInput,\n FileStemMatch,\n MediaCacheBridge,\n MediaCacheErrors,\n MediaCachePhase,\n MediaCacheReadyState,\n MediaCacheStatus,\n MediaQuerySyncOptions,\n PaginationInput,\n PaginationResult,\n ResolvedMediaAsset,\n} from \"../shared/types.js\";\n"],"mappings":";;;;;;;AAmBA,SAAgB,yBACd,SACoB;CACpB,OAAOA,2BAA6B,QAAQ"}
|
|
@@ -0,0 +1,278 @@
|
|
|
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
|
+
exports.MISSING_BRIDGE_ERROR = MISSING_BRIDGE_ERROR;
|
|
272
|
+
exports.createMediaCacheRenderer = createMediaCacheRenderer;
|
|
273
|
+
exports.createMediaCacheStatusController = createMediaCacheStatusController;
|
|
274
|
+
exports.createMediaQueryWatcherInstance = createMediaQueryWatcherInstance;
|
|
275
|
+
exports.deriveMediaCachePhase = deriveMediaCachePhase;
|
|
276
|
+
exports.resolveMediaCacheBridge = resolveMediaCacheBridge;
|
|
277
|
+
|
|
278
|
+
//# sourceMappingURL=runtime.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime.cjs","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,35 @@
|
|
|
1
|
+
import { AssetKeyInput, FileStemMatch, MediaCacheBridge, MediaCachePhase, MediaCacheStatus, MediaQuerySyncOptions, PaginationInput, PaginationResult, ResolvedMediaAsset } from "../shared/types.cjs";
|
|
2
|
+
|
|
3
|
+
//#region src/renderer/runtime.d.ts
|
|
4
|
+
/** Async snapshot aligned with React hooks (`useMedia`, `useMediaCacheStatus`, etc.). */
|
|
5
|
+
interface MediaAsyncState<T> {
|
|
6
|
+
/** Latest resolved value, or `null` while loading/when unavailable. */
|
|
7
|
+
data: T | null;
|
|
8
|
+
/** `true` while an initial load or `refresh()` request is in flight. */
|
|
9
|
+
loading: boolean;
|
|
10
|
+
/** Last request error, or `null` when the latest request succeeded. */
|
|
11
|
+
error: Error | null;
|
|
12
|
+
/** Re-runs the underlying query and updates `data`/`error`. */
|
|
13
|
+
refresh: () => Promise<void>;
|
|
14
|
+
}
|
|
15
|
+
declare const MISSING_BRIDGE_ERROR = "MediaCache bridge is unavailable. Wrap your app in <MediaCacheProvider> or expose the preload bridge on window.mediaCache.";
|
|
16
|
+
declare function deriveMediaCachePhase(status: MediaAsyncState<MediaCacheStatus>): MediaCachePhase;
|
|
17
|
+
declare function resolveMediaCacheBridge(options?: {
|
|
18
|
+
bridge?: MediaCacheBridge;
|
|
19
|
+
windowKey?: string;
|
|
20
|
+
}): MediaCacheBridge;
|
|
21
|
+
interface CreateMediaCacheRendererOptions {
|
|
22
|
+
bridge?: MediaCacheBridge;
|
|
23
|
+
windowKey?: string;
|
|
24
|
+
}
|
|
25
|
+
interface MediaCacheRenderer {
|
|
26
|
+
bridge: MediaCacheBridge;
|
|
27
|
+
subscribeCacheStatus(listener: (state: MediaAsyncState<MediaCacheStatus>) => void): () => void;
|
|
28
|
+
watchMediaAsset(key: AssetKeyInput, options: MediaQuerySyncOptions | undefined, listener: (state: MediaAsyncState<ResolvedMediaAsset | null>) => void): () => void;
|
|
29
|
+
watchMediaByIndex(indexName: string, value: string, options: (PaginationInput & MediaQuerySyncOptions) | undefined, listener: (state: MediaAsyncState<PaginationResult<ResolvedMediaAsset>>) => void): () => void;
|
|
30
|
+
watchFileStemMatch(stem: string, options: (PaginationInput & MediaQuerySyncOptions) | undefined, listener: (state: MediaAsyncState<PaginationResult<FileStemMatch>>) => void): () => void;
|
|
31
|
+
dispose(): void;
|
|
32
|
+
}
|
|
33
|
+
//#endregion
|
|
34
|
+
export { CreateMediaCacheRendererOptions, MISSING_BRIDGE_ERROR, MediaAsyncState, MediaCacheRenderer, deriveMediaCachePhase, resolveMediaCacheBridge };
|
|
35
|
+
//# sourceMappingURL=runtime.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime.d.cts","names":[],"sources":["../../src/renderer/runtime.ts"],"mappings":";;;;UAaiB,eAAA;EAAA;EAEf,IAAA,EAAM,CAAA;EAFwB;EAI9B,OAAA;EAEO;EAAP,KAAA,EAAO,KAAA;EAEe;EAAtB,OAAA,QAAe,OAAA;AAAA;AAAA,cAGJ,oBAAA;AAAA,iBAOG,qBAAA,CAAsB,MAAA,EAAQ,eAAA,CAAgB,gBAAA,IAAoB,eAAA;AAAA,iBAIlE,uBAAA,CAAwB,OAAA;EACtC,MAAA,GAAS,gBAAA;EACT,SAAA;AAAA,IACE,gBAAA;AAAA,UA+Qa,+BAAA;EACf,MAAA,GAAS,gBAAA;EACT,SAAA;AAAA;AAAA,UAGe,kBAAA;EACf,MAAA,EAAQ,gBAAA;EACR,oBAAA,CAAqB,QAAA,GAAW,KAAA,EAAO,eAAA,CAAgB,gBAAA;EACvD,eAAA,CACE,GAAA,EAAK,aAAA,EACL,OAAA,EAAS,qBAAA,cACT,QAAA,GAAW,KAAA,EAAO,eAAA,CAAgB,kBAAA;EAEpC,iBAAA,CACE,SAAA,UACA,KAAA,UACA,OAAA,GAAU,eAAA,GAAkB,qBAAA,eAC5B,QAAA,GAAW,KAAA,EAAO,eAAA,CAAgB,gBAAA,CAAiB,kBAAA;EAErD,kBAAA,CACE,IAAA,UACA,OAAA,GAAU,eAAA,GAAkB,qBAAA,eAC5B,QAAA,GAAW,KAAA,EAAO,eAAA,CAAgB,gBAAA,CAAiB,aAAA;EAErD,OAAA;AAAA"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { AssetKeyInput, FileStemMatch, MediaCacheBridge, MediaCachePhase, MediaCacheStatus, MediaQuerySyncOptions, PaginationInput, PaginationResult, ResolvedMediaAsset } from "../shared/types.js";
|
|
2
|
+
|
|
3
|
+
//#region src/renderer/runtime.d.ts
|
|
4
|
+
/** Async snapshot aligned with React hooks (`useMedia`, `useMediaCacheStatus`, etc.). */
|
|
5
|
+
interface MediaAsyncState<T> {
|
|
6
|
+
/** Latest resolved value, or `null` while loading/when unavailable. */
|
|
7
|
+
data: T | null;
|
|
8
|
+
/** `true` while an initial load or `refresh()` request is in flight. */
|
|
9
|
+
loading: boolean;
|
|
10
|
+
/** Last request error, or `null` when the latest request succeeded. */
|
|
11
|
+
error: Error | null;
|
|
12
|
+
/** Re-runs the underlying query and updates `data`/`error`. */
|
|
13
|
+
refresh: () => Promise<void>;
|
|
14
|
+
}
|
|
15
|
+
declare const MISSING_BRIDGE_ERROR = "MediaCache bridge is unavailable. Wrap your app in <MediaCacheProvider> or expose the preload bridge on window.mediaCache.";
|
|
16
|
+
declare function deriveMediaCachePhase(status: MediaAsyncState<MediaCacheStatus>): MediaCachePhase;
|
|
17
|
+
declare function resolveMediaCacheBridge(options?: {
|
|
18
|
+
bridge?: MediaCacheBridge;
|
|
19
|
+
windowKey?: string;
|
|
20
|
+
}): MediaCacheBridge;
|
|
21
|
+
interface CreateMediaCacheRendererOptions {
|
|
22
|
+
bridge?: MediaCacheBridge;
|
|
23
|
+
windowKey?: string;
|
|
24
|
+
}
|
|
25
|
+
interface MediaCacheRenderer {
|
|
26
|
+
bridge: MediaCacheBridge;
|
|
27
|
+
subscribeCacheStatus(listener: (state: MediaAsyncState<MediaCacheStatus>) => void): () => void;
|
|
28
|
+
watchMediaAsset(key: AssetKeyInput, options: MediaQuerySyncOptions | undefined, listener: (state: MediaAsyncState<ResolvedMediaAsset | null>) => void): () => void;
|
|
29
|
+
watchMediaByIndex(indexName: string, value: string, options: (PaginationInput & MediaQuerySyncOptions) | undefined, listener: (state: MediaAsyncState<PaginationResult<ResolvedMediaAsset>>) => void): () => void;
|
|
30
|
+
watchFileStemMatch(stem: string, options: (PaginationInput & MediaQuerySyncOptions) | undefined, listener: (state: MediaAsyncState<PaginationResult<FileStemMatch>>) => void): () => void;
|
|
31
|
+
dispose(): void;
|
|
32
|
+
}
|
|
33
|
+
//#endregion
|
|
34
|
+
export { CreateMediaCacheRendererOptions, MISSING_BRIDGE_ERROR, MediaAsyncState, MediaCacheRenderer, deriveMediaCachePhase, resolveMediaCacheBridge };
|
|
35
|
+
//# sourceMappingURL=runtime.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime.d.ts","names":[],"sources":["../../src/renderer/runtime.ts"],"mappings":";;;;UAaiB,eAAA;EAAA;EAEf,IAAA,EAAM,CAAA;EAFwB;EAI9B,OAAA;EAEO;EAAP,KAAA,EAAO,KAAA;EAEe;EAAtB,OAAA,QAAe,OAAA;AAAA;AAAA,cAGJ,oBAAA;AAAA,iBAOG,qBAAA,CAAsB,MAAA,EAAQ,eAAA,CAAgB,gBAAA,IAAoB,eAAA;AAAA,iBAIlE,uBAAA,CAAwB,OAAA;EACtC,MAAA,GAAS,gBAAA;EACT,SAAA;AAAA,IACE,gBAAA;AAAA,UA+Qa,+BAAA;EACf,MAAA,GAAS,gBAAA;EACT,SAAA;AAAA;AAAA,UAGe,kBAAA;EACf,MAAA,EAAQ,gBAAA;EACR,oBAAA,CAAqB,QAAA,GAAW,KAAA,EAAO,eAAA,CAAgB,gBAAA;EACvD,eAAA,CACE,GAAA,EAAK,aAAA,EACL,OAAA,EAAS,qBAAA,cACT,QAAA,GAAW,KAAA,EAAO,eAAA,CAAgB,kBAAA;EAEpC,iBAAA,CACE,SAAA,UACA,KAAA,UACA,OAAA,GAAU,eAAA,GAAkB,qBAAA,eAC5B,QAAA,GAAW,KAAA,EAAO,eAAA,CAAgB,gBAAA,CAAiB,kBAAA;EAErD,kBAAA,CACE,IAAA,UACA,OAAA,GAAU,eAAA,GAAkB,qBAAA,eAC5B,QAAA,GAAW,KAAA,EAAO,eAAA,CAAgB,gBAAA,CAAiB,aAAA;EAErD,OAAA;AAAA"}
|