Skip to content
Source
Sign inSign up

assetImageSource.ts

53 lines1.8 KB

1import { sourceControlClients } from "@t3tools/client-runtime/source-control-clients";
2import {
3 SOURCE_CONTROL_MEDIA_ASSET,
4 type AssetResource,
5 type EnvironmentId,
6} from "@t3tools/contracts";
7import type { ImageSource } from "expo-image";
8​
9/**
10 * Signed URLs change on each mint and reconnect, so a URL-keyed cache misses every time.
11 * Content that cannot change caches under its identity, and host files under the revision the
12 * server read. Anything else stays keyed by URL.
13 */
14export function assetImageCacheKey(
15 environmentId: EnvironmentId,
16 resource: AssetResource,
17 fileRevision?: string,
18): string | undefined {
19 switch (resource._tag) {
20 case "attachment":
21 return `t3-attachment:${JSON.stringify([environmentId, resource.attachmentId])}`;
22 case SOURCE_CONTROL_MEDIA_ASSET: {
23 const media = sourceControlClients.mediaUrl(resource.url);
24 return media?.immutable
25 ? `t3-media:${JSON.stringify([environmentId, media.fetchUrl])}`
26 : undefined;
27 }
28 case "media-file":
29 case "workspace-file":
30 case "draft-workspace-file":
31 return fileRevision === undefined
32 ? undefined
33 : `t3-file:${JSON.stringify([
34 environmentId,
35 resource._tag === "draft-workspace-file" ? resource.cwd : resource.threadId,
36 resource.path,
37 fileRevision,
38 ])}`;
39 // A tool can replace the image at its index, and nothing cheap identifies its bytes.
40 default:
41 return undefined;
42 }
44​
45export function assetImageSource(
46 environmentId: EnvironmentId,
47 resource: AssetResource,
48 uri: string,
49 fileRevision?: string,
50): ImageSource {
51 const cacheKey = assetImageCacheKey(environmentId, resource, fileRevision);
52 return cacheKey === undefined ? { uri } : { uri, cacheKey };