@misiki/gocommerce-connector 0.13.0 → 0.14.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.
@@ -1197,14 +1197,17 @@ var CatalogService = class extends BaseService {
1197
1197
  const attr = Object.entries(q.attributes ?? {}).flatMap(
1198
1198
  ([handle, values]) => values.filter(Boolean).map((v) => `${handle}:${v}`)
1199
1199
  );
1200
- if (q.facets && !legacyListing.has(this.engineBase())) {
1200
+ const refined = attr.length > 0 || !!(q.tags?.length || q.vendors?.length || q.productTypes?.length);
1201
+ const triedIndex = !!search && !refined;
1202
+ const counted = q.facets && !legacyListing.has(this.engineBase());
1203
+ const facetListing = async (page2, limit2) => {
1201
1204
  const { currency } = await this.facts.ready();
1202
1205
  const minor = (n) => Number.isFinite(n) ? Math.max(0, toMinor(n, currency)) : void 0;
1203
- const env2 = await this.engine("/api/products", {
1206
+ return this.engine("/api/products", {
1204
1207
  query: {
1205
1208
  q: search,
1206
- page,
1207
- limit,
1209
+ page: page2,
1210
+ limit: limit2,
1208
1211
  channel: this.creds.channel,
1209
1212
  category: q.category,
1210
1213
  tag: q.tags,
@@ -1217,6 +1220,16 @@ var CatalogService = class extends BaseService {
1217
1220
  facets: 1
1218
1221
  }
1219
1222
  });
1223
+ };
1224
+ if (triedIndex && await this.facts.pluginOn("meilisearch")) {
1225
+ const [found, rail] = await Promise.all([
1226
+ this.fromIndex(q, { page, limit, search, sortKey, wantsRange, hierarchy }),
1227
+ counted ? facetListing(1, 1).catch(() => null) : null
1228
+ ]);
1229
+ if (found) return rail?.meta?.facets ? { ...found, facets: rail.meta.facets } : found;
1230
+ }
1231
+ if (counted) {
1232
+ const env2 = await facetListing(page, limit);
1220
1233
  if (env2.meta?.facets) {
1221
1234
  return {
1222
1235
  ...toPage(env2, (p) => toProduct(p)),
@@ -1227,39 +1240,9 @@ var CatalogService = class extends BaseService {
1227
1240
  }
1228
1241
  legacyListing.add(this.engineBase());
1229
1242
  }
1230
- if ((sortKey || wantsRange) && await this.facts.pluginOn("meilisearch")) {
1231
- const filters = [];
1232
- if (q.category) {
1233
- const names = (await this.facts.subtree(q.category).catch(() => [])).map(
1234
- (c) => quote(c.full_name)
1235
- );
1236
- if (!names.length) return { ...emptyCatalog(limit), categoryHierarchy: hierarchy, sorted: true };
1237
- filters.push(`category IN [${names.join(", ")}]`);
1238
- }
1239
- if (wantsRange) {
1240
- const { currency } = await this.facts.ready();
1241
- if (Number.isFinite(q.priceFrom)) filters.push(`price_minor >= ${toMinor(q.priceFrom, currency)}`);
1242
- if (Number.isFinite(q.priceTo)) filters.push(`price_minor <= ${toMinor(q.priceTo, currency)}`);
1243
- }
1244
- const res = await this.data("/x/meilisearch/search", {
1245
- query: {
1246
- q: search ?? "",
1247
- limit,
1248
- offset: (page - 1) * limit,
1249
- filter: filters.join(" AND ") || void 0,
1250
- sort: sortKey
1251
- }
1252
- });
1253
- const total = res.total ?? 0;
1254
- return {
1255
- data: (res.hits ?? []).map(fromSearchDoc),
1256
- count: total,
1257
- pageSize: limit,
1258
- noOfPage: Math.max(1, Math.ceil(total / limit)),
1259
- page,
1260
- categoryHierarchy: hierarchy,
1261
- sorted: true
1262
- };
1243
+ if (!triedIndex && (sortKey || wantsRange)) {
1244
+ const found = await this.fromIndex(q, { page, limit, search, sortKey, wantsRange, hierarchy });
1245
+ if (found) return found;
1263
1246
  }
1264
1247
  const sorted = !sortKey && !wantsRange;
1265
1248
  if (q.category && !search) {
@@ -1279,6 +1262,45 @@ var CatalogService = class extends BaseService {
1279
1262
  });
1280
1263
  return { ...toPage(env, (p) => toProduct(p)), categoryHierarchy: hierarchy, sorted };
1281
1264
  }
1265
+ /**
1266
+ * The shelf from the Meilisearch module, or null when the store has it off,
1267
+ * sells through a channel, finds nothing for the words, or it cannot answer (Meilisearch down: the engine says `unavailable`), so
1268
+ * the caller asks the database instead of showing the shopper an error.
1269
+ */
1270
+ async fromIndex(q, o) {
1271
+ if (this.creds.channel || !await this.facts.pluginOn("meilisearch")) return null;
1272
+ const filters = [];
1273
+ if (q.category) {
1274
+ const names = (await this.facts.subtree(q.category).catch(() => [])).map((c) => quote(c.full_name));
1275
+ if (!names.length) return { ...emptyCatalog(o.limit), categoryHierarchy: o.hierarchy, sorted: true };
1276
+ filters.push(`category IN [${names.join(", ")}]`);
1277
+ }
1278
+ if (o.wantsRange) {
1279
+ const { currency } = await this.facts.ready();
1280
+ if (Number.isFinite(q.priceFrom)) filters.push(`price_minor >= ${toMinor(q.priceFrom, currency)}`);
1281
+ if (Number.isFinite(q.priceTo)) filters.push(`price_minor <= ${toMinor(q.priceTo, currency)}`);
1282
+ }
1283
+ const res = await this.data("/x/meilisearch/search", {
1284
+ query: {
1285
+ q: o.search ?? "",
1286
+ limit: o.limit,
1287
+ offset: (o.page - 1) * o.limit,
1288
+ filter: filters.join(" AND ") || void 0,
1289
+ sort: o.sortKey
1290
+ }
1291
+ }).catch(() => null);
1292
+ if (!res || res.unavailable || o.search && !res.hits?.length) return null;
1293
+ const total = res.total ?? 0;
1294
+ return {
1295
+ data: (res.hits ?? []).map(fromSearchDoc),
1296
+ count: total,
1297
+ pageSize: o.limit,
1298
+ noOfPage: Math.max(1, Math.ceil(total / o.limit)),
1299
+ page: o.page,
1300
+ categoryHierarchy: o.hierarchy,
1301
+ sorted: true
1302
+ };
1303
+ }
1282
1304
  };
1283
1305
  function emptyCatalog(limit = PAGE_SIZE) {
1284
1306
  return { data: [], count: 0, pageSize: limit, noOfPage: 0, page: 1 };
@@ -1576,10 +1598,8 @@ var MeilisearchService = class extends CatalogService {
1576
1598
  async searchAutoComplete({ query, search, limit = 8 } = {}) {
1577
1599
  const q = (query ?? search ?? "").trim();
1578
1600
  if (!q) return { data: [] };
1579
- if (await this.facts.pluginOn("meilisearch")) {
1580
- const res = await this.data("/x/meilisearch/search", { query: { q, limit } });
1581
- return { data: (res.hits ?? []).map(fromSearchDoc) };
1582
- }
1601
+ const found = await this.fromIndex({}, { page: 1, limit, search: q, wantsRange: false, hierarchy: [] });
1602
+ if (found) return { data: found.data };
1583
1603
  const rows = await this.data("/api/products", { query: { q, limit, channel: this.creds.channel } }) ?? [];
1584
1604
  return { data: rows.map((p) => toProduct(p)) };
1585
1605
  }