@primestyleai/tryon 5.10.121 → 5.10.123

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.
@@ -116,6 +116,11 @@ export interface HistoryEntry {
116
116
  * IndexedDB rather than in this localStorage object to avoid the ~5–10 MB
117
117
  * quota. Old entries without a photo set this false/undefined. */
118
118
  hasPhoto?: boolean;
119
+ /** True when the try-on RESULT image is stored as a Blob in IndexedDB
120
+ * (key = `result-<entry.id>`). Restored as an object URL on history
121
+ * click so the result survives even if the original URL (Cloudinary
122
+ * / data:) expired or was lost. */
123
+ hasResult?: boolean;
119
124
  /** What the user actually selected when they ran the try-on (per section). */
120
125
  selectedSizes?: Array<{
121
126
  sectionName: string;
@@ -15,5 +15,11 @@ export declare function savePhoto(id: string, blob: Blob): Promise<boolean>;
15
15
  export declare function getPhoto(id: string): Promise<Blob | null>;
16
16
  /** Delete a photo by historyEntryId. */
17
17
  export declare function deletePhoto(id: string): Promise<boolean>;
18
- /** Garbage-collect: keep only photos whose id is in `keepIds`. */
18
+ /** Save a try-on result Blob keyed by historyEntryId. Replaces if exists. */
19
+ export declare function saveResult(id: string, blob: Blob): Promise<boolean>;
20
+ /** Load a try-on result Blob by historyEntryId, or null if not stored. */
21
+ export declare function getResult(id: string): Promise<Blob | null>;
22
+ /** Garbage-collect: keep only photos (and results) whose id is in `keepIds`.
23
+ * Uses a value cursor (openCursor) so records can be deleted during
24
+ * iteration — openKeyCursor's cursor.delete() throws InvalidStateError. */
19
25
  export declare function pruneToIds(keepIds: Set<string>): Promise<void>;
@@ -9624,6 +9624,7 @@ function openDb() {
9624
9624
  });
9625
9625
  return _dbPromise;
9626
9626
  }
9627
+ const RESULT_PREFIX = "result-";
9627
9628
  async function savePhoto(id2, blob) {
9628
9629
  const db2 = await openDb();
9629
9630
  if (!db2) return false;
@@ -9653,19 +9654,30 @@ async function getPhoto(id2) {
9653
9654
  }
9654
9655
  });
9655
9656
  }
9657
+ async function saveResult(id2, blob) {
9658
+ return savePhoto(RESULT_PREFIX + id2, blob);
9659
+ }
9660
+ async function getResult(id2) {
9661
+ return getPhoto(RESULT_PREFIX + id2);
9662
+ }
9656
9663
  async function pruneToIds(keepIds) {
9657
9664
  const db2 = await openDb();
9658
9665
  if (!db2) return;
9666
+ const expected = /* @__PURE__ */ new Set();
9667
+ for (const id2 of keepIds) {
9668
+ expected.add(id2);
9669
+ expected.add(RESULT_PREFIX + id2);
9670
+ }
9659
9671
  return new Promise((resolve) => {
9660
9672
  try {
9661
9673
  const tx = db2.transaction(STORE, "readwrite");
9662
9674
  const store = tx.objectStore(STORE);
9663
- const cursorReq = store.openKeyCursor();
9675
+ const cursorReq = store.openCursor();
9664
9676
  cursorReq.onsuccess = () => {
9665
9677
  const cursor = cursorReq.result;
9666
9678
  if (!cursor) return;
9667
9679
  const key = String(cursor.key);
9668
- if (!keepIds.has(key)) cursor.delete();
9680
+ if (!expected.has(key)) cursor.delete();
9669
9681
  cursor.continue();
9670
9682
  };
9671
9683
  tx.oncomplete = () => resolve();
@@ -11391,7 +11403,7 @@ const STYLES$1 = `
11391
11403
  padding: 0.1vw 0.5vw;
11392
11404
  }
11393
11405
  .ps-tryon-sr-card-v2-rec-pill {
11394
- align-self: flex-start;
11406
+ align-self: center;
11395
11407
  font-size: 0.55vw; font-weight: 700; color: var(--ps-accent);
11396
11408
  text-transform: uppercase; letter-spacing: 0.08em;
11397
11409
  background: rgba(33, 84, 239, 0.10);
@@ -29201,15 +29213,30 @@ function PrimeStyleTryonInner({
29201
29213
  displayLabel: o.displayLabel,
29202
29214
  isOverride: !!recommended && o.selectedSize !== recommended
29203
29215
  }));
29216
+ let entryId = null;
29204
29217
  setHistory((prev) => {
29205
29218
  if (prev.length === 0) return prev;
29219
+ entryId = prev[0].id;
29206
29220
  const updated = {
29207
29221
  ...prev[0],
29208
29222
  resultImageUrl,
29223
+ hasResult: true,
29209
29224
  ...selectedSizes.length ? { selectedSizes } : {}
29210
29225
  };
29211
29226
  return [updated, ...prev.slice(1)];
29212
29227
  });
29228
+ if (entryId) {
29229
+ const id2 = entryId;
29230
+ void (async () => {
29231
+ try {
29232
+ const res = await fetch(resultImageUrl);
29233
+ if (!res.ok) return;
29234
+ const blob = await res.blob();
29235
+ await saveResult(id2, blob);
29236
+ } catch {
29237
+ }
29238
+ })();
29239
+ }
29213
29240
  } else if (view === "result" && resultImageUrl && !historySavedRef.current) {
29214
29241
  historySavedRef.current = true;
29215
29242
  saveHistoryEntry().catch(() => {
@@ -29239,6 +29266,13 @@ function PrimeStyleTryonInner({
29239
29266
  setSizeGuideFetching(false);
29240
29267
  }
29241
29268
  setResultImageUrl(entry.resultImageUrl || null);
29269
+ if (entry.hasResult || entry.resultImageUrl) {
29270
+ void getResult(entry.id).then((blob) => {
29271
+ if (!blob) return;
29272
+ const url = URL.createObjectURL(blob);
29273
+ setResultImageUrl(url);
29274
+ });
29275
+ }
29242
29276
  if (entry.hasPhoto) {
29243
29277
  void getPhoto(entry.id).then((blob) => {
29244
29278
  if (!blob) return;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@primestyleai/tryon",
3
- "version": "5.10.121",
3
+ "version": "5.10.123",
4
4
  "description": "PrimeStyle Virtual Try-On SDK — React component & Web Component",
5
5
  "type": "module",
6
6
  "main": "dist/primestyle-tryon.js",