@vibes.diy/base 14.3.45 → 14.3.47

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.
Files changed (61) hide show
  1. package/components/FilesPanelView.d.ts +19 -1
  2. package/components/FilesPanelView.js +52 -2
  3. package/components/FilesPanelView.js.map +1 -1
  4. package/components/HandlePickerMenu.d.ts +1 -0
  5. package/components/HandlePickerMenu.js.map +1 -1
  6. package/components/ImgGen.d.ts +5 -1
  7. package/components/ImgGen.js +23 -5
  8. package/components/ImgGen.js.map +1 -1
  9. package/components/NotificationDetailView.d.ts +15 -0
  10. package/components/NotificationDetailView.js +41 -3
  11. package/components/NotificationDetailView.js.map +1 -1
  12. package/components/ViewerTagView.d.ts +5 -1
  13. package/components/ViewerTagView.js +58 -12
  14. package/components/ViewerTagView.js.map +1 -1
  15. package/components/vibe-menu/cards/ShareAppDrill.d.ts +21 -0
  16. package/components/vibe-menu/cards/ShareAppDrill.js +162 -0
  17. package/components/vibe-menu/cards/ShareAppDrill.js.map +1 -0
  18. package/components/vibe-menu/cards/ShareCard.js +4 -4
  19. package/components/vibe-menu/cards/ShareCard.js.map +1 -1
  20. package/components/vibe-menu/cards/ShareDrills.d.ts +2 -2
  21. package/components/vibe-menu/cards/ShareDrills.js +5 -0
  22. package/components/vibe-menu/cards/ShareDrills.js.map +1 -1
  23. package/components/vibe-menu/cards/ShareLinkRows.d.ts +3 -2
  24. package/components/vibe-menu/cards/ShareLinkRows.js +5 -3
  25. package/components/vibe-menu/cards/ShareLinkRows.js.map +1 -1
  26. package/components/vibe-menu/cards/share-card.styles.d.ts +1 -1
  27. package/components/vibe-menu/cards/share-card.styles.js +22 -0
  28. package/components/vibe-menu/cards/share-card.styles.js.map +1 -1
  29. package/components/vibe-menu/cards/share-copy.d.ts +5 -3
  30. package/components/vibe-menu/cards/share-copy.js +7 -6
  31. package/components/vibe-menu/cards/share-copy.js.map +1 -1
  32. package/components/vibe-menu/index.d.ts +2 -0
  33. package/components/vibe-menu/index.js +2 -0
  34. package/components/vibe-menu/index.js.map +1 -1
  35. package/components/vibe-menu/menu-state.d.ts +1 -1
  36. package/components/vibe-menu/menu-state.js +1 -0
  37. package/components/vibe-menu/menu-state.js.map +1 -1
  38. package/components/vibe-menu/parts/Glyph.d.ts +1 -1
  39. package/components/vibe-menu/parts/Glyph.js +5 -1
  40. package/components/vibe-menu/parts/Glyph.js.map +1 -1
  41. package/components/vibe-menu/share-fixtures.d.ts +3 -1
  42. package/components/vibe-menu/share-fixtures.js +11 -0
  43. package/components/vibe-menu/share-fixtures.js.map +1 -1
  44. package/components/vibe-menu/share-image.d.ts +17 -0
  45. package/components/vibe-menu/share-image.js +194 -0
  46. package/components/vibe-menu/share-image.js.map +1 -0
  47. package/components/vibe-menu/slices.d.ts +11 -0
  48. package/components/vibe-menu/slices.js.map +1 -1
  49. package/hooks/img-gen/local-pictures.d.ts +10 -0
  50. package/hooks/img-gen/local-pictures.js +31 -0
  51. package/hooks/img-gen/local-pictures.js.map +1 -0
  52. package/hooks/img-gen/picture-bytes.d.ts +54 -0
  53. package/hooks/img-gen/picture-bytes.js +312 -0
  54. package/hooks/img-gen/picture-bytes.js.map +1 -0
  55. package/hooks/img-gen/use-img-gen.d.ts +9 -1
  56. package/hooks/img-gen/use-img-gen.js +109 -8
  57. package/hooks/img-gen/use-img-gen.js.map +1 -1
  58. package/hooks/img-gen/use-picture-src.d.ts +13 -0
  59. package/hooks/img-gen/use-picture-src.js +94 -0
  60. package/hooks/img-gen/use-picture-src.js.map +1 -0
  61. package/package.json +5 -4
@@ -0,0 +1,312 @@
1
+ import { exception2Result } from "@adviser/cement";
2
+ import { type } from "arktype";
3
+ import { FILES_ASSET_STATE_HEADER, FILES_UPLOAD_ID_HEADER, KEEPABLE_ASSET_STATES } from "@vibes.diy/vibe-types";
4
+ import { vibe } from "@vibes.diy/vibe-runtime";
5
+ function defaultWarn(event, fields) {
6
+ vibe.log("warn", event, fields);
7
+ }
8
+ const RASTER_IMAGE_TYPES = ["image/png", "image/jpeg", "image/webp", "image/gif", "image/avif", "image/bmp"];
9
+ export function isRasterImageType(mime) {
10
+ return RASTER_IMAGE_TYPES.includes(mime.split(";")[0].trim().toLowerCase());
11
+ }
12
+ const DEFAULT_MEMORY_BYTES = 48 * 1024 * 1024;
13
+ const DEFAULT_LOCAL_LOOKUP_MS = 1500;
14
+ class MemoryTier {
15
+ max;
16
+ entries = new Map();
17
+ total = 0;
18
+ constructor(max) {
19
+ this.max = max;
20
+ }
21
+ get(id) {
22
+ const b = this.entries.get(id);
23
+ if (b === undefined)
24
+ return undefined;
25
+ this.entries.delete(id);
26
+ this.entries.set(id, b);
27
+ return b;
28
+ }
29
+ delete(id) {
30
+ const b = this.entries.get(id);
31
+ if (b === undefined)
32
+ return;
33
+ this.entries.delete(id);
34
+ this.total -= b.size;
35
+ }
36
+ set(id, b) {
37
+ const prior = this.entries.get(id);
38
+ if (prior !== undefined) {
39
+ this.total -= prior.size;
40
+ this.entries.delete(id);
41
+ }
42
+ if (b.size > this.max)
43
+ return;
44
+ this.entries.set(id, b);
45
+ this.total += b.size;
46
+ for (const [oldId, old] of this.entries) {
47
+ if (this.total <= this.max)
48
+ break;
49
+ this.entries.delete(oldId);
50
+ this.total -= old.size;
51
+ }
52
+ }
53
+ }
54
+ const TIMED_OUT = Symbol("timed-out");
55
+ function withinMs(p, ms) {
56
+ return new Promise((resolve, reject) => {
57
+ const timer = setTimeout(() => resolve(TIMED_OUT), ms);
58
+ p.then((v) => {
59
+ clearTimeout(timer);
60
+ resolve(v);
61
+ }, (e) => {
62
+ clearTimeout(timer);
63
+ reject(e);
64
+ });
65
+ });
66
+ }
67
+ export function createPictureStore(opts) {
68
+ const fetcher = opts.fetcher ?? defaultFetch;
69
+ const warn = opts.warn ?? defaultWarn;
70
+ const memory = new MemoryTier(opts.memoryBytes ?? DEFAULT_MEMORY_BYTES);
71
+ const lookupMs = opts.localLookupMs ?? DEFAULT_LOCAL_LOOKUP_MS;
72
+ const filesPrefix = `${opts.assetOrigin}/_files/`;
73
+ const inFlight = new Map();
74
+ const notKeepable = new Map();
75
+ const unconfirmed = new Set();
76
+ const confirmInFlight = new Map();
77
+ async function keep(uploadId, blob) {
78
+ if (isRasterImageType(blob.type) === false) {
79
+ warn("picture-bytes-not-raster", { uploadId, type: blob.type });
80
+ return;
81
+ }
82
+ memory.set(uploadId, blob);
83
+ const rPut = await exception2Result(() => opts.bytes.put(uploadId, blob));
84
+ if (rPut.isErr())
85
+ warn("picture-bytes-put-failed", { uploadId, message: rPut.Err().message });
86
+ }
87
+ async function seed(uploadId, blob) {
88
+ if (isRasterImageType(blob.type) === false) {
89
+ warn("picture-bytes-not-raster", { uploadId, type: blob.type });
90
+ return;
91
+ }
92
+ memory.set(uploadId, blob);
93
+ unconfirmed.add(uploadId);
94
+ }
95
+ function dropUnconfirmed(uploadId) {
96
+ if (unconfirmed.delete(uploadId))
97
+ memory.delete(uploadId);
98
+ }
99
+ function judge(uploadId, res, type) {
100
+ const servedUpload = res.headers.get(FILES_UPLOAD_ID_HEADER);
101
+ const state = res.headers.get(FILES_ASSET_STATE_HEADER);
102
+ const named = servedUpload === uploadId;
103
+ const rasterOk = type === undefined ? true : isRasterImageType(type);
104
+ return { named, keepable: named && state !== null && KEEPABLE_ASSET_STATES.includes(state) && rasterOk };
105
+ }
106
+ async function headConfirm(uploadId, url) {
107
+ if (unconfirmed.has(uploadId) === false)
108
+ return "none";
109
+ if (url.startsWith(filesPrefix) === false)
110
+ return "unknown";
111
+ const rRes = await exception2Result(() => fetcher(url, { method: "HEAD", credentials: "include" }));
112
+ if (rRes.isErr()) {
113
+ warn("picture-bytes-confirm-failed", { uploadId, message: rRes.Err().message });
114
+ return "unknown";
115
+ }
116
+ const res = rRes.Ok();
117
+ if (res.ok === false)
118
+ return "unknown";
119
+ const seeded = memory.get(uploadId);
120
+ const verdict = judge(uploadId, res, seeded?.type);
121
+ if (verdict.keepable === false || seeded === undefined) {
122
+ dropUnconfirmed(uploadId);
123
+ return "dropped";
124
+ }
125
+ unconfirmed.delete(uploadId);
126
+ await keep(uploadId, seeded);
127
+ return "kept";
128
+ }
129
+ function confirm(ref) {
130
+ const pending = confirmInFlight.get(ref.uploadId);
131
+ if (pending !== undefined)
132
+ return pending;
133
+ const p = headConfirm(ref.uploadId, ref.url).finally(() => confirmInFlight.delete(ref.uploadId));
134
+ confirmInFlight.set(ref.uploadId, p);
135
+ return p;
136
+ }
137
+ async function lookup(uploadId) {
138
+ const hot = memory.get(uploadId);
139
+ if (hot !== undefined)
140
+ return hot;
141
+ const rStored = await exception2Result(() => withinMs(opts.bytes.get(uploadId), lookupMs));
142
+ if (rStored.isErr()) {
143
+ warn("picture-bytes-get-failed", { uploadId, message: rStored.Err().message });
144
+ return undefined;
145
+ }
146
+ const stored = rStored.Ok();
147
+ if (stored === TIMED_OUT) {
148
+ warn("picture-bytes-get-slow", { uploadId, ms: lookupMs });
149
+ return undefined;
150
+ }
151
+ if (stored === undefined)
152
+ return undefined;
153
+ if (isRasterImageType(stored.type) === false)
154
+ return undefined;
155
+ memory.set(uploadId, stored);
156
+ return stored;
157
+ }
158
+ async function download(uploadId, url) {
159
+ if (url.startsWith(filesPrefix) === false)
160
+ return { outcome: "unavailable" };
161
+ const rRes = await exception2Result(() => fetcher(url, { credentials: "include" }));
162
+ if (rRes.isErr()) {
163
+ warn("picture-bytes-fetch-failed", { uploadId, message: rRes.Err().message });
164
+ return { outcome: "unavailable" };
165
+ }
166
+ const res = rRes.Ok();
167
+ if (res.ok === false) {
168
+ warn("picture-bytes-fetch-status", { uploadId, status: res.status });
169
+ return { outcome: "unavailable" };
170
+ }
171
+ const servedUpload = res.headers.get(FILES_UPLOAD_ID_HEADER);
172
+ if (servedUpload !== null && servedUpload !== uploadId) {
173
+ warn("picture-bytes-other-upload", { uploadId, servedUpload });
174
+ dropUnconfirmed(uploadId);
175
+ return { outcome: "other-upload" };
176
+ }
177
+ const rBlob = await exception2Result(() => res.blob());
178
+ if (rBlob.isErr()) {
179
+ warn("picture-bytes-body-failed", { uploadId, message: rBlob.Err().message });
180
+ return { outcome: "unavailable" };
181
+ }
182
+ const blob = rBlob.Ok();
183
+ const verdict = judge(uploadId, res, blob.type);
184
+ if (verdict.keepable === false) {
185
+ notKeepable.set(uploadId, verdict.named);
186
+ dropUnconfirmed(uploadId);
187
+ return { outcome: "not-kept", blob, confirmed: verdict.named };
188
+ }
189
+ unconfirmed.delete(uploadId);
190
+ await keep(uploadId, blob);
191
+ return { outcome: "kept", blob };
192
+ }
193
+ function fill(ref) {
194
+ const pending = inFlight.get(ref.uploadId);
195
+ if (pending !== undefined)
196
+ return pending;
197
+ const known = notKeepable.get(ref.uploadId);
198
+ if (known !== undefined)
199
+ return Promise.resolve({ outcome: "known-not-keepable", confirmed: known });
200
+ const p = download(ref.uploadId, ref.url).finally(() => inFlight.delete(ref.uploadId));
201
+ inFlight.set(ref.uploadId, p);
202
+ return p;
203
+ }
204
+ return {
205
+ peek: (uploadId) => memory.get(uploadId),
206
+ lookup,
207
+ fill,
208
+ seed,
209
+ isUnconfirmed: (uploadId) => unconfirmed.has(uploadId),
210
+ confirm,
211
+ };
212
+ }
213
+ function defaultFetch(input, init) {
214
+ return fetch(input, init);
215
+ }
216
+ export const PICTURE_BYTES_DB = "vibes-picture-bytes";
217
+ const BYTES = "bytes";
218
+ const META = "meta";
219
+ const DEFAULT_MAX_BYTES = 160 * 1024 * 1024;
220
+ const bytesRow = type({ buf: type.instanceOf(ArrayBuffer), type: "string" });
221
+ const metaRow = type({ uploadId: "string", size: "number", lastUsed: "number" });
222
+ const metaRowId = type({ uploadId: "string" });
223
+ function req(r) {
224
+ return new Promise((resolve, reject) => {
225
+ r.onsuccess = () => resolve(r.result);
226
+ r.onerror = () => reject(r.error ?? new Error("indexeddb request failed"));
227
+ });
228
+ }
229
+ function done(tx) {
230
+ return new Promise((resolve, reject) => {
231
+ tx.oncomplete = () => resolve();
232
+ tx.onerror = () => reject(tx.error ?? new Error("indexeddb transaction failed"));
233
+ tx.onabort = () => reject(tx.error ?? new Error("indexeddb transaction aborted"));
234
+ });
235
+ }
236
+ export function idbPictureBytes(opts = {}) {
237
+ const factory = opts.indexedDB ?? (typeof indexedDB === "undefined" ? undefined : indexedDB);
238
+ const maxBytes = opts.maxBytes ?? DEFAULT_MAX_BYTES;
239
+ const now = opts.now ?? Date.now;
240
+ let dbp;
241
+ function open() {
242
+ if (factory === undefined)
243
+ return Promise.reject(new Error("indexedDB unavailable"));
244
+ if (dbp === undefined) {
245
+ const r = factory.open(opts.dbName ?? PICTURE_BYTES_DB, 1);
246
+ r.onupgradeneeded = () => {
247
+ const db = r.result;
248
+ if (db.objectStoreNames.contains(BYTES) === false)
249
+ db.createObjectStore(BYTES);
250
+ if (db.objectStoreNames.contains(META) === false)
251
+ db.createObjectStore(META, { keyPath: "uploadId" });
252
+ };
253
+ const opening = req(r);
254
+ dbp = opening;
255
+ opening.then(undefined, forgetFailedOpen);
256
+ }
257
+ return dbp;
258
+ }
259
+ function forgetFailedOpen() {
260
+ dbp = undefined;
261
+ }
262
+ async function get(uploadId) {
263
+ const db = await open();
264
+ const tx = db.transaction([BYTES, META], "readwrite");
265
+ const row = bytesRow(await req(tx.objectStore(BYTES).get(uploadId)));
266
+ if (row instanceof type.errors) {
267
+ await done(tx);
268
+ return undefined;
269
+ }
270
+ tx.objectStore(META).put({ uploadId, size: row.buf.byteLength, lastUsed: now() });
271
+ await done(tx);
272
+ return new Blob([row.buf], { type: row.type });
273
+ }
274
+ async function put(uploadId, blob) {
275
+ if (blob.size > maxBytes)
276
+ return;
277
+ const buf = await blob.arrayBuffer();
278
+ const db = await open();
279
+ const tx = db.transaction([BYTES, META], "readwrite");
280
+ const bytes = tx.objectStore(BYTES);
281
+ const meta = tx.objectStore(META);
282
+ bytes.put({ buf, type: blob.type }, uploadId);
283
+ meta.put({ uploadId, size: buf.byteLength, lastUsed: now() });
284
+ const rows = [];
285
+ for (const raw of await req(meta.getAll())) {
286
+ const m = metaRow(raw);
287
+ if (m instanceof type.errors) {
288
+ const id = metaRowId(raw);
289
+ if (id instanceof type.errors === false) {
290
+ bytes.delete(id.uploadId);
291
+ meta.delete(id.uploadId);
292
+ }
293
+ continue;
294
+ }
295
+ rows.push(m);
296
+ }
297
+ rows.sort((a, b) => a.lastUsed - b.lastUsed);
298
+ let total = rows.reduce((n, m) => n + m.size, 0);
299
+ for (const m of rows) {
300
+ if (total <= maxBytes)
301
+ break;
302
+ if (m.uploadId === uploadId)
303
+ continue;
304
+ bytes.delete(m.uploadId);
305
+ meta.delete(m.uploadId);
306
+ total -= m.size;
307
+ }
308
+ await done(tx);
309
+ }
310
+ return { get, put };
311
+ }
312
+ //# sourceMappingURL=picture-bytes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"picture-bytes.js","sourceRoot":"","sources":["../../../jsr/hooks/img-gen/picture-bytes.ts"],"names":[],"mappings":"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"}
@@ -3,6 +3,8 @@ export type UseFireproofHook = typeof useFireproof;
3
3
  export type UseVibeContextHook = typeof useVibeContext;
4
4
  import type { ImgGenRequestOptions, ImgGenResult, UseImgGenOptions, UseImgGenResult } from "@vibes.diy/vibe-types";
5
5
  import { Result } from "@adviser/cement";
6
+ import { type LocalFileUrl } from "./local-pictures.js";
7
+ import type { PictureStore } from "./picture-bytes.js";
6
8
  export declare function __setImgGenProbeDeadlineMsForTests(ms: number | undefined): void;
7
9
  export declare function __setImgGenCommitReprobeDelaysMsForTests(ms: readonly number[] | undefined): void;
8
10
  interface InjectedDeps {
@@ -10,7 +12,13 @@ interface InjectedDeps {
10
12
  imgGen?: (prompt: string, opts?: ImgGenRequestOptions) => Promise<Result<ImgGenResult>>;
11
13
  confirmedMediaProbe?: ConfirmedMediaProbe | null;
12
14
  useFireproof?: UseFireproofHook;
15
+ localFileUrl?: LocalFileUrl | null;
16
+ pictures?: PictureStore | null;
13
17
  useVibeContext?: UseVibeContextHook;
14
18
  }
15
- export declare function useImgGen(opts: Partial<UseImgGenOptions> & InjectedDeps): UseImgGenResult;
19
+ export interface UseImgGenDisplayResult extends UseImgGenResult {
20
+ readonly mintedUrls: ReadonlySet<string>;
21
+ readonly reportUnavailable: (uploadId: string) => void;
22
+ }
23
+ export declare function useImgGen(opts: Partial<UseImgGenOptions> & InjectedDeps): UseImgGenDisplayResult;
16
24
  export {};
@@ -1,7 +1,9 @@
1
- import { useState, useEffect, useMemo, useRef } from "react";
1
+ import { useState, useEffect, useMemo, useRef, useCallback } from "react";
2
2
  import { useFireproof, imgGen as defaultImgGen, confirmedMediaProbe as defaultConfirmedMediaProbe, useVibeContext, getRegisteredVibeApi, vibe, decorateFiles, IMG_GEN_SOURCE_UNUSABLE, } from "@vibes.diy/vibe-runtime";
3
3
  import { IMG_GEN_CANCELLED, IMG_GEN_NEEDS_TAP, IMG_GEN_UNREACHABLE, IMG_GEN_UNREACHABLE_MESSAGE, buildMediaPointerDoc, buildMediaVersionDoc, mediaDbName, mediaPointerDocId, mediaVersionDocId, } from "@vibes.diy/vibe-types";
4
4
  import { exception2Result, Result } from "@adviser/cement";
5
+ import { type } from "arktype";
6
+ import { registeredLocalFileUrl, registeredPictureStore } from "./local-pictures.js";
5
7
  const PROMPT_KEY = "p1";
6
8
  function isValidVersionDoc(d) {
7
9
  if (d.type !== "version")
@@ -40,6 +42,41 @@ function withLocalPreviews(doc, previews) {
40
42
  }
41
43
  return changed ? { ...doc, _files: files } : doc;
42
44
  }
45
+ function withLocalUrls(doc, localUrls) {
46
+ const minted = new Set();
47
+ if (doc === null || localUrls.size === 0 || doc._files === undefined)
48
+ return { doc, minted };
49
+ const files = {};
50
+ for (const [key, f] of Object.entries(doc._files)) {
51
+ const url = f.url === undefined && f.uploadId !== undefined ? localUrls.get(localUrlKey(key, f.uploadId)) : undefined;
52
+ if (url !== undefined) {
53
+ files[key] = { ...f, url };
54
+ minted.add(url);
55
+ }
56
+ else {
57
+ files[key] = f;
58
+ }
59
+ }
60
+ return minted.size > 0 ? { doc: decorateFiles({ ...doc, _files: files }), minted } : { doc, minted };
61
+ }
62
+ function localUrlKey(fileKey, uploadId) {
63
+ return `${fileKey}\u0000${uploadId}`;
64
+ }
65
+ const localRow = type({ _id: "string", _files: "Record<string, unknown>" });
66
+ const localFileEntry = type({ uploadId: "string > 0", "url?": "unknown" });
67
+ function noteLocalUrls(args) {
68
+ for (const raw of args.docs) {
69
+ const d = localRow(raw);
70
+ if (d instanceof type.errors)
71
+ continue;
72
+ for (const [key, rawEntry] of Object.entries(d._files)) {
73
+ const f = localFileEntry(rawEntry);
74
+ if (f instanceof type.errors || f.url !== undefined)
75
+ continue;
76
+ args.into.set(localUrlKey(key, f.uploadId), args.mint({ dbName: args.dbName, docId: d._id, key, uploadId: f.uploadId }));
77
+ }
78
+ }
79
+ }
43
80
  function synthesizeMediaDocument(hostDocId, versionDocs, pointer) {
44
81
  const versions = versionDocs.map((vd) => {
45
82
  const fileKey = Object.keys(vd._files)[0];
@@ -182,7 +219,9 @@ async function readBackFromServer(args) {
182
219
  const IMG_GEN_MAX_REKEEPS = 3;
183
220
  const IMG_GEN_UNKEPT_MESSAGE = "This picture wasn't saved — another device added a version at the same moment. Please try again.";
184
221
  export function useImgGen(opts) {
185
- const { prompt, _id, database = "ImgGen", skip = false, generationId, inputImage, model, imgGen = defaultImgGen, temporaryDraft = getRegisteredVibeApi()?.temporaryData === true, confirmedMediaProbe = defaultConfirmedMediaProbe, useFireproof: useFireproofImpl = useFireproof, useVibeContext: useVibeContextImpl = useVibeContext, tapGenerationId, } = opts;
222
+ const { prompt, _id, database = "ImgGen", skip = false, generationId, inputImage, model, imgGen = defaultImgGen, temporaryDraft = getRegisteredVibeApi()?.temporaryData === true, confirmedMediaProbe = defaultConfirmedMediaProbe, useFireproof: useFireproofImpl = useFireproof, useVibeContext: useVibeContextImpl = useVibeContext, tapGenerationId, localFileUrl: localFileUrlOpt = registeredLocalFileUrl(), pictures: picturesOpt = registeredPictureStore(), } = opts;
223
+ const mintLocal = temporaryDraft || localFileUrlOpt === null ? undefined : localFileUrlOpt;
224
+ const pictures = picturesOpt ?? undefined;
186
225
  const [loading, setLoading] = useState(false);
187
226
  const [progress, setProgress] = useState(0);
188
227
  const [error, setError] = useState(null);
@@ -222,6 +261,9 @@ export function useImgGen(opts) {
222
261
  unmountSignalRef.current = ac.signal;
223
262
  return () => ac.abort();
224
263
  }, []);
264
+ const localUrlsRef = useRef(new Map());
265
+ const retryDisplayReadBackRef = useRef(null);
266
+ const seededRef = useRef(new Set());
225
267
  const previewUrlsRef = useRef(new Map());
226
268
  useEffect(() => {
227
269
  const previews = previewUrlsRef.current;
@@ -282,6 +324,9 @@ export function useImgGen(opts) {
282
324
  const hostDocId = _id;
283
325
  async function loadMediaDocs() {
284
326
  const res = await mediaDb.query("hostDocId", { key: hostDocId });
327
+ if (mintLocal !== undefined) {
328
+ noteLocalUrls({ docs: res.docs, dbName: mediaDbName(dbName), mint: mintLocal, into: localUrlsRef.current });
329
+ }
285
330
  return res.docs;
286
331
  }
287
332
  let readStartedPending = false;
@@ -302,9 +347,14 @@ export function useImgGen(opts) {
302
347
  tapSpentRef.current = generationId;
303
348
  return;
304
349
  }
305
- await decide(rMediaDocs.Ok(), rLegacy.isOk() ? rLegacy.Ok() : null, false);
350
+ const localLegacy = rLegacy.isOk() ? rLegacy.Ok() : null;
351
+ if (mintLocal !== undefined && localLegacy !== null) {
352
+ noteLocalUrls({ docs: [localLegacy], dbName, mint: mintLocal, into: localUrlsRef.current });
353
+ }
354
+ await decide(rMediaDocs.Ok(), localLegacy, false);
306
355
  }
307
356
  async function readBackForDisplay(shown, fileKey, localDocs, legacyDoc) {
357
+ const ourVersionId = sortVersionDocs(localDocs).find((vd) => vd._files[fileKey]?.uploadId === shown._files?.[fileKey]?.uploadId)?._id;
308
358
  const uploadId = shown._files?.[fileKey]?.uploadId;
309
359
  if (confirmedMediaProbe === undefined || confirmedMediaProbe === null)
310
360
  return;
@@ -333,8 +383,17 @@ export function useImgGen(opts) {
333
383
  logEvent: "imggen-display-probe-failed",
334
384
  examine: (probedDocs, probedLegacy) => {
335
385
  const probedVersions = sortVersionDocs(probedDocs);
336
- if (holdsUpload(probedVersions, uploadId, true) === false)
386
+ if (holdsUpload(probedVersions, uploadId, true) === false) {
387
+ const taken = ourVersionId !== undefined &&
388
+ probedVersions.some((vd) => vd._id === ourVersionId && holdsUpload([vd], uploadId, false) === false);
389
+ if (taken) {
390
+ vibe.log("warn", "imggen-version-unkept", { docId: hostDocId, dbName, uploadId, lane: "display" });
391
+ setError(new Error(IMG_GEN_UNKEPT_MESSAGE));
392
+ setPending(false);
393
+ return { done: true, value: true };
394
+ }
337
395
  return { done: false };
396
+ }
338
397
  const composed = composeDocument({
339
398
  hostDocId,
340
399
  versionDocs: probedVersions,
@@ -389,12 +448,24 @@ export function useImgGen(opts) {
389
448
  currentVer?.id &&
390
449
  existingDoc._files?.[currentVer.id]) {
391
450
  const urlPending = existingDoc._files[currentVer.id]?.url === undefined;
392
- setPending(urlPending);
451
+ const currentUpload = existingDoc._files[currentVer.id]?.uploadId;
452
+ const shownLocally = urlPending && currentUpload !== undefined && localUrlsRef.current.has(localUrlKey(currentVer.id, currentUpload));
453
+ setPending(urlPending && shownLocally === false);
393
454
  setDocument(existingDoc);
394
455
  setNeedsTap(false);
395
456
  if (urlPending) {
396
457
  currentGenRef.current = null;
397
- await readBackForDisplay(existingDoc, currentVer.id, mediaDocs, legacyDoc);
458
+ if (shownLocally === false)
459
+ await readBackForDisplay(existingDoc, currentVer.id, mediaDocs, legacyDoc);
460
+ else if (currentUpload !== undefined) {
461
+ const fileKey = currentVer.id;
462
+ const restart = () => {
463
+ displayReadBackRef.current = null;
464
+ void readBackForDisplay(existingDoc, fileKey, mediaDocs, legacyDoc);
465
+ };
466
+ retryDisplayReadBackRef.current = { uploadId: currentUpload, run: restart };
467
+ void readBackForDisplay(existingDoc, fileKey, mediaDocs, legacyDoc);
468
+ }
398
469
  }
399
470
  else {
400
471
  const committed = committedGenRef.current;
@@ -513,7 +584,7 @@ export function useImgGen(opts) {
513
584
  if (earlyPreviewRef.current !== null)
514
585
  return;
515
586
  const url = URL.createObjectURL(blob);
516
- earlyPreviewRef.current = { genKey, url };
587
+ earlyPreviewRef.current = { genKey, url, blob };
517
588
  setPreviewUrl(url);
518
589
  },
519
590
  }));
@@ -561,6 +632,11 @@ export function useImgGen(opts) {
561
632
  else if (file.preview instanceof Blob && previewUrlsRef.current.has(file.uploadId) === false) {
562
633
  previewUrlsRef.current.set(file.uploadId, URL.createObjectURL(file.preview));
563
634
  }
635
+ const ownBytes = early?.blob ?? (file.preview instanceof Blob ? file.preview : undefined);
636
+ if (ownBytes !== undefined && pictures !== undefined) {
637
+ void pictures.seed(file.uploadId, ownBytes);
638
+ seededRef.current.add(file.uploadId);
639
+ }
564
640
  const rRun = await exception2Result(async () => {
565
641
  setProgress(90);
566
642
  const showCommitted = async (uploadId, clientWrite) => {
@@ -832,12 +908,35 @@ export function useImgGen(opts) {
832
908
  model,
833
909
  imgGen,
834
910
  confirmedMediaProbe,
911
+ mintLocal,
912
+ pictures,
835
913
  mediaFromCache,
836
914
  hostFromCache,
837
915
  deferTick,
838
916
  arrivalTick,
839
917
  ]);
840
- const displayed = useMemo(() => withLocalPreviews(document, previewUrlsRef.current), [document]);
918
+ const { doc: displayed, minted: mintedUrls } = useMemo(() => withLocalUrls(withLocalPreviews(document, previewUrlsRef.current), localUrlsRef.current), [document]);
919
+ useEffect(() => {
920
+ if (pictures === undefined || seededRef.current.size === 0 || document?._files === undefined)
921
+ return;
922
+ for (const [key, f] of Object.entries(document._files)) {
923
+ const uploadId = f.uploadId;
924
+ if (uploadId === undefined || seededRef.current.has(uploadId) === false)
925
+ continue;
926
+ const url = f.url ?? localUrlsRef.current.get(localUrlKey(key, uploadId));
927
+ if (url === undefined)
928
+ continue;
929
+ void pictures.confirm({ uploadId, url }).then((answer) => {
930
+ if (answer !== "unknown")
931
+ seededRef.current.delete(uploadId);
932
+ });
933
+ }
934
+ }, [document, pictures]);
935
+ const reportUnavailable = useCallback((uploadId) => {
936
+ const retry = retryDisplayReadBackRef.current;
937
+ if (retry !== null && retry.uploadId === uploadId)
938
+ retry.run();
939
+ }, []);
841
940
  const previewSettled = previewUrl !== undefined && (error !== null || Object.values(displayed?._files ?? {}).some((f) => f.url === previewUrl));
842
941
  useEffect(() => {
843
942
  if (previewSettled)
@@ -851,6 +950,8 @@ export function useImgGen(opts) {
851
950
  pending,
852
951
  needsTap,
853
952
  ...(previewUrl !== undefined ? { previewUrl } : {}),
953
+ mintedUrls,
954
+ reportUnavailable,
854
955
  };
855
956
  }
856
957
  //# sourceMappingURL=use-img-gen.js.map