Spaces:
Running
Running
fix: merge local products_url_added.json (synced from zalo-products-all) — newest products on top of modal list
Browse files- src/vaix-rag.js +58 -0
src/vaix-rag.js
CHANGED
|
@@ -63,6 +63,11 @@ const DETAIL_URL = "https://huggingface.co/datasets/bep40/grob-products-updated/
|
|
| 63 |
// products to the searchable catalog. Shape is the zalobot _scrape_product_url
|
| 64 |
// format: {n,l,i,p,pn,c,cs,ci,imgs,sum,desc,specs,feats,sku,vid,mod,brand,slug,...}
|
| 65 |
const ADDED_URL = "https://huggingface.co/datasets/bep40/grob-products-updated/resolve/main/products_url_added.json";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 66 |
// ── Persistent catalog cache (CacheStorage) ───────────────────────────────
|
| 67 |
// The index JSON is ~10 MB. Without a persistent cache every page load
|
| 68 |
// re-downloads + re-parses it (cold cache: the "danh sách sản phẩm load chậm"
|
|
@@ -1167,6 +1172,59 @@ async function load() {
|
|
| 1167 |
}
|
| 1168 |
}
|
| 1169 |
} catch (e) { console.warn("[VAIX] products_url_added merge skipped:", e && e.message); }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1170 |
loaded = true;
|
| 1171 |
console.log("[VAIX] Loaded " + allProducts.length + " products (" + source + ") in " + (Date.now() - _ls) + "ms");
|
| 1172 |
handleProductUrlParam();
|
|
|
|
| 63 |
// products to the searchable catalog. Shape is the zalobot _scrape_product_url
|
| 64 |
// format: {n,l,i,p,pn,c,cs,ci,imgs,sum,desc,specs,feats,sku,vid,mod,brand,slug,...}
|
| 65 |
const ADDED_URL = "https://huggingface.co/datasets/bep40/grob-products-updated/resolve/main/products_url_added.json";
|
| 66 |
+
// ── Zalo-sync products (synced from bep40/zalo-products-all by auto_sync_worker) ──
|
| 67 |
+
// The webhook space auto-sync worker prepends NEW products (model-based) to this
|
| 68 |
+
// file ON the vai-market space itself, so the floating product list modal always
|
| 69 |
+
// shows the most-recent products on top. Best-effort (fail → empty list).
|
| 70 |
+
const ADDED_LOCAL_URL = "/products_url_added.json";
|
| 71 |
// ── Persistent catalog cache (CacheStorage) ───────────────────────────────
|
| 72 |
// The index JSON is ~10 MB. Without a persistent cache every page load
|
| 73 |
// re-downloads + re-parses it (cold cache: the "danh sách sản phẩm load chậm"
|
|
|
|
| 1172 |
}
|
| 1173 |
}
|
| 1174 |
} catch (e) { console.warn("[VAIX] products_url_added merge skipped:", e && e.message); }
|
| 1175 |
+
// ── Merge ZALO-SYNC products (newest, synced from zalo-products-all) ──
|
| 1176 |
+
// These live ON the vai-market space itself (written by auto_sync_worker)
|
| 1177 |
+
// and must surface on TOP of the modal product list so the newest
|
| 1178 |
+
// products always appear first. Dedup against BOTH the base catalog and
|
| 1179 |
+
// the previously-merged grob-added products by sku/slug/link/name.
|
| 1180 |
+
try {
|
| 1181 |
+
const localResp = await fetch(ADDED_LOCAL_URL, { signal: AbortSignal.timeout(15000) });
|
| 1182 |
+
if (localResp.ok) {
|
| 1183 |
+
const localRaw = await localResp.json();
|
| 1184 |
+
if (Array.isArray(localRaw) && localRaw.length) {
|
| 1185 |
+
const localAdded = localRaw.map((p) => ({
|
| 1186 |
+
name: p.n || p.name || "", title_clean: p.n || p.name || "",
|
| 1187 |
+
brand: p.brand || "", price: p.p || p.price || "", priceNum: Number(p.pn || 0),
|
| 1188 |
+
listPn: Number(p.listPn || 0) || 0, salePn: Number(p.salePn || p.salePn || p.pn || 0) || 0, priceMode: p.priceMode || "sale",
|
| 1189 |
+
category: normalizeCategory(p.c || p.cat || "", p.n || p.name || ""), category_slug: p.cs || "", category_icon: p.ci || "fa-box",
|
| 1190 |
+
sku: p.sku || p.s || p.mod || "", model: p.mod || p.model || p.sku || "", slug: p.slug || p.sl || "",
|
| 1191 |
+
description: p.desc || p.d || "", summary: p.sum || p.summary || "",
|
| 1192 |
+
features: Array.isArray(p.feats) ? p.feats : (Array.isArray(p.f) ? p.f : []),
|
| 1193 |
+
specs: (p.specs && typeof p.specs === "object") ? p.specs : {},
|
| 1194 |
+
video: p.vid || "", image: p.i || p.image || "",
|
| 1195 |
+
images: Array.isArray(p.imgs) ? p.imgs : (Array.isArray(p.g) ? p.g : []), link: p.l || "",
|
| 1196 |
+
_addedBy: "zalo-products-all-autosync"
|
| 1197 |
+
}));
|
| 1198 |
+
const baseSkus2 = new Set(allProducts.map((p) => String(p.sku).toLowerCase()).filter(Boolean));
|
| 1199 |
+
const baseSlugs2 = new Set(allProducts.map((p) => String(p.slug || "").toLowerCase()).filter(Boolean));
|
| 1200 |
+
const seenKeys2 = new Set();
|
| 1201 |
+
const seenNames2 = new Set();
|
| 1202 |
+
const uniqueLocal = localAdded.filter((p) => {
|
| 1203 |
+
const sk = String(p.sku || "").toLowerCase();
|
| 1204 |
+
const sl = String(p.slug || "").toLowerCase();
|
| 1205 |
+
const lk = String(p.link || "").toLowerCase();
|
| 1206 |
+
const nm = String(p.title_clean || p.name || "").toLowerCase().replace(/\s+/g, " ").trim();
|
| 1207 |
+
if (sk && baseSkus2.has(sk)) return false;
|
| 1208 |
+
if (sl && baseSlugs2.has(sl)) return false;
|
| 1209 |
+
if (nm && seenNames2.has(nm)) return false;
|
| 1210 |
+
if (nm) seenNames2.add(nm);
|
| 1211 |
+
let key = "";
|
| 1212 |
+
if (sk) key = "sku:" + sk;
|
| 1213 |
+
else if (sl) key = "slug:" + sl;
|
| 1214 |
+
else if (lk) key = "link:" + lk;
|
| 1215 |
+
else if (nm) key = "name:" + nm;
|
| 1216 |
+
if (!key) return false;
|
| 1217 |
+
if (seenKeys2.has(key)) return false;
|
| 1218 |
+
seenKeys2.add(key);
|
| 1219 |
+
return true;
|
| 1220 |
+
});
|
| 1221 |
+
if (uniqueLocal.length) {
|
| 1222 |
+
allProducts = uniqueLocal.concat(allProducts);
|
| 1223 |
+
console.log("[VAIX] Merged " + uniqueLocal.length + " zalo-sync products (on top) from local products_url_added.json");
|
| 1224 |
+
}
|
| 1225 |
+
}
|
| 1226 |
+
}
|
| 1227 |
+
} catch (e) { console.warn("[VAIX] local products_url_added merge skipped:", e && e.message); }
|
| 1228 |
loaded = true;
|
| 1229 |
console.log("[VAIX] Loaded " + allProducts.length + " products (" + source + ") in " + (Date.now() - _ls) + "ms");
|
| 1230 |
handleProductUrlParam();
|