@voltro/plugin-search 0.84.0 → 0.86.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.
@@ -1,11 +1,11 @@
1
1
  # Third-Party Notices — @voltro/plugin-search
2
2
 
3
- This package depends on the open-source software listed below. Each is the
3
+ This package uses the open-source software listed below. Each is the
4
4
  property of its respective copyright holders and is used under the terms of
5
5
  its license. This file is provided for attribution; it grants no rights in
6
6
  @voltro/plugin-search itself, which is proprietary (see LICENSE).
7
7
 
8
- Generated from the resolved runtime dependency closure (59 packages).
8
+ Generated from the resolved runtime dependency closure (56 packages).
9
9
 
10
10
  ---
11
11
 
@@ -401,62 +401,6 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
401
401
  SOFTWARE.
402
402
  ```
403
403
 
404
- ## @effect/experimental@0.61.1
405
-
406
- License: MIT
407
-
408
- ```
409
- MIT License
410
-
411
- Copyright (c) 2023-present The Contributors
412
-
413
- Permission is hereby granted, free of charge, to any person obtaining a copy
414
- of this software and associated documentation files (the "Software"), to deal
415
- in the Software without restriction, including without limitation the rights
416
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
417
- copies of the Software, and to permit persons to whom the Software is
418
- furnished to do so, subject to the following conditions:
419
-
420
- The above copyright notice and this permission notice shall be included in all
421
- copies or substantial portions of the Software.
422
-
423
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
424
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
425
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
426
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
427
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
428
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
429
- SOFTWARE.
430
- ```
431
-
432
- ## @effect/sql@0.52.1
433
-
434
- License: MIT
435
-
436
- ```
437
- MIT License
438
-
439
- Copyright (c) 2023-present The Contributors
440
-
441
- Permission is hereby granted, free of charge, to any person obtaining a copy
442
- of this software and associated documentation files (the "Software"), to deal
443
- in the Software without restriction, including without limitation the rights
444
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
445
- copies of the Software, and to permit persons to whom the Software is
446
- furnished to do so, subject to the following conditions:
447
-
448
- The above copyright notice and this permission notice shall be included in all
449
- copies or substantial portions of the Software.
450
-
451
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
452
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
453
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
454
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
455
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
456
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
457
- SOFTWARE.
458
- ```
459
-
460
404
  ## @tanstack/devtools-event-client@0.4.4
461
405
 
462
406
  License: MIT
@@ -919,7 +863,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
919
863
  SOFTWARE.
920
864
  ```
921
865
 
922
- ## follow-redirects@1.16.0
866
+ ## follow-redirects@1.16.1
923
867
 
924
868
  License: MIT
925
869
 
@@ -1198,34 +1142,6 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
1198
1142
  SOFTWARE.
1199
1143
  ```
1200
1144
 
1201
- ## layerr@3.0.0
1202
-
1203
- License: MIT
1204
-
1205
- ```
1206
- MIT License
1207
-
1208
- Copyright (c) 2020 Perry Mitchell
1209
-
1210
- Permission is hereby granted, free of charge, to any person obtaining a copy
1211
- of this software and associated documentation files (the "Software"), to deal
1212
- in the Software without restriction, including without limitation the rights
1213
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
1214
- copies of the Software, and to permit persons to whom the Software is
1215
- furnished to do so, subject to the following conditions:
1216
-
1217
- The above copyright notice and this permission notice shall be included in all
1218
- copies or substantial portions of the Software.
1219
-
1220
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1221
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1222
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
1223
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1224
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
1225
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
1226
- SOFTWARE.
1227
- ```
1228
-
1229
1145
  ## loglevel@1.9.2
1230
1146
 
1231
1147
  License: MIT
@@ -1838,14 +1754,14 @@ Apache License
1838
1754
  limitations under the License.
1839
1755
  ```
1840
1756
 
1841
- ## ulidx@2.4.1
1757
+ ## ulid@3.0.2
1842
1758
 
1843
1759
  License: MIT
1844
1760
 
1845
1761
  ```
1846
- MIT License
1762
+ The MIT License (MIT)
1847
1763
 
1848
- Copyright (c) 2021 Perry Mitchell
1764
+ Copyright (c) 2017 Alizain Feerasta
1849
1765
 
1850
1766
  Permission is hereby granted, free of charge, to any person obtaining a copy
1851
1767
  of this software and associated documentation files (the "Software"), to deal
@@ -0,0 +1,398 @@
1
+ import { isSafeFieldName as e, sanitizeEngineParams as t } from "./sanitize.js";
2
+ import { Data as n } from "effect";
3
+ //#region src/backend.ts
4
+ var r = class extends n.TaggedError("SearchBackendError") {}, i = (e) => Array.isArray(e) ? e : [e], a = (e, t, n) => {
5
+ if (Math.abs(e.length - t.length) > n) return !1;
6
+ if (e === t) return !0;
7
+ if (Number.isNaN(n)) return !1;
8
+ let r = t.length, i = Math.floor(n), a = Array(r + 1).fill(Infinity), o = Array(r + 1).fill(Infinity);
9
+ for (let e = 0; e <= Math.min(r, i); e++) a[e] = e;
10
+ for (let s = 1; s <= e.length; s++) {
11
+ let c = Math.max(1, s - i), l = Math.min(r, s + i);
12
+ o[0] = s, c > 1 && (o[c - 1] = Infinity), l < r && (o[l + 1] = Infinity);
13
+ let u = s, d = e.charCodeAt(s - 1);
14
+ for (let e = c; e <= l; e++) {
15
+ let n = d === t.charCodeAt(e - 1) ? 0 : 1, r = Math.min(a[e] + 1, o[e - 1] + 1, a[e - 1] + n);
16
+ o[e] = r, u = Math.min(u, r);
17
+ }
18
+ if (u > n) return !1;
19
+ let f = a;
20
+ a = o, o = f;
21
+ }
22
+ return a[r] <= n;
23
+ }, o = (e) => e.length <= 4 ? 1 : 2, s = () => {
24
+ let e = /* @__PURE__ */ new Map(), t = (t) => {
25
+ let n = e.get(t);
26
+ return n || (n = /* @__PURE__ */ new Map(), e.set(t, n)), n;
27
+ }, n = (e, t) => {
28
+ let n = e[t.field];
29
+ switch (t.op) {
30
+ case "eq": return String(n) === String(t.value);
31
+ case "neq": return String(n) !== String(t.value);
32
+ case "in": return i(t.value).some((e) => String(n) === String(e));
33
+ case "nin": return i(t.value).every((e) => String(n) !== String(e));
34
+ case "gt":
35
+ case "gte":
36
+ case "lt":
37
+ case "lte": {
38
+ let [e, r] = [c(n), c(t.value)];
39
+ return e === void 0 || r === void 0 ? !1 : t.op === "gt" ? e > r : t.op === "gte" ? e >= r : t.op === "lt" ? e < r : e <= r;
40
+ }
41
+ }
42
+ }, r = (e, t) => !t || t.every((t) => n(e, t)), s = (e) => Object.entries(e).filter(([e]) => e !== "id").map(([e, t]) => [e, String(t)]), l = (e, t, n) => {
43
+ if (t.length === 0) return !0;
44
+ for (let [, r] of s(e)) {
45
+ let e = r.toLowerCase();
46
+ if (e.includes(t)) return !0;
47
+ if (n !== void 0 && n !== 0) {
48
+ let r = n === "auto" ? o(t) : n;
49
+ for (let n of e.split(/\s+/)) if (a(n, t, r)) return !0;
50
+ }
51
+ }
52
+ return !1;
53
+ }, u = (e, t, n) => {
54
+ if (t.length === 0) return {};
55
+ let r = n.preTag ?? "<mark>", i = n.postTag ?? "</mark>", a = n.fields && n.fields.length > 0 ? new Set(n.fields) : null, o = {}, c = new RegExp(t.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), "gi");
56
+ for (let [n, l] of s(e)) (!a || a.has(n)) && l.toLowerCase().includes(t) && (o[n] = l.replace(c, (e) => `${r}${e}${i}`));
57
+ return o;
58
+ };
59
+ return {
60
+ engineKind: "memory",
61
+ upsert: async (e, n) => {
62
+ let r = t(e);
63
+ for (let e of n) r.set(e.id, e);
64
+ },
65
+ remove: async (e, n) => {
66
+ let r = t(e);
67
+ for (let e of n) r.delete(e);
68
+ },
69
+ query: async (e, { q: n, limit: i, offset: a, filters: o, facets: s, highlight: c, fuzziness: d }) => {
70
+ let f = n.trim().toLowerCase(), p = [];
71
+ for (let n of t(e).values()) r(n, o) && l(n, f, d) && p.push(n);
72
+ let m = {};
73
+ if (s) for (let e of s) {
74
+ let t = {};
75
+ for (let n of p) {
76
+ let r = n[e];
77
+ if (r == null) continue;
78
+ let i = String(r);
79
+ t[i] = (t[i] ?? 0) + 1;
80
+ }
81
+ m[e] = t;
82
+ }
83
+ let h = a ?? 0;
84
+ return {
85
+ hits: (i === void 0 ? p.slice(h) : p.slice(h, h + i)).map((e) => c ? {
86
+ doc: e,
87
+ highlights: u(e, f, c)
88
+ } : { doc: e }),
89
+ facets: m
90
+ };
91
+ }
92
+ };
93
+ }, c = (e) => {
94
+ if (typeof e == "number") return e;
95
+ if (typeof e == "boolean") return +!!e;
96
+ if (typeof e == "string") {
97
+ let t = Number(e);
98
+ if (!Number.isNaN(t) && e.trim() !== "") return t;
99
+ let n = Date.parse(e);
100
+ return Number.isNaN(n) ? void 0 : n;
101
+ }
102
+ }, l = async (e, t, n) => {
103
+ try {
104
+ return await n();
105
+ } catch {
106
+ throw new r({
107
+ engine: t,
108
+ op: "query",
109
+ message: `the '${t}' search backend requires the '${e}' optional dependency. Install it to enable it (e.g. \`npm i ${e}\`).`,
110
+ transient: !1
111
+ });
112
+ }
113
+ }, u = (e, n) => (r) => {
114
+ let { params: i, appAllowed: a, dropped: o } = t(e, r, n.allowEngineParams);
115
+ return o.length > 0 && n.onWarn?.("search dropped disallowed engineParams", {
116
+ engine: e,
117
+ keys: o
118
+ }), {
119
+ before: i,
120
+ after: a
121
+ };
122
+ }, d = (t, n) => {
123
+ if (!e(n)) throw new r({
124
+ engine: t,
125
+ op: "query",
126
+ message: `filter field "${n}" is not a plain field path (^[A-Za-z_][A-Za-z0-9_.]*$)`,
127
+ transient: !1
128
+ });
129
+ return n;
130
+ }, f = (e) => {
131
+ let t = (e) => JSON.stringify(e), n = d("typesense", e.field);
132
+ switch (e.op) {
133
+ case "eq": return `${n}:=${t(e.value)}`;
134
+ case "neq": return `${n}:!=${t(e.value)}`;
135
+ case "gt": return `${n}:>${t(e.value)}`;
136
+ case "gte": return `${n}:>=${t(e.value)}`;
137
+ case "lt": return `${n}:<${t(e.value)}`;
138
+ case "lte": return `${n}:<=${t(e.value)}`;
139
+ case "in": return `${n}:[${i(e.value).map(t).join(",")}]`;
140
+ case "nin": return `${n}:!=[${i(e.value).map(t).join(",")}]`;
141
+ }
142
+ }, p = (e, t = {}) => {
143
+ let n = u("typesense", t), i, a = async () => (i ||= l("typesense", "typesense", () => import("typesense")).then((t) => {
144
+ let n = t.Client;
145
+ return new n({
146
+ nodes: [{ url: e.url ?? e.host ?? "http://localhost:8108" }],
147
+ apiKey: e.apiKey
148
+ });
149
+ }), i), o = (e) => e && e.length > 0 ? e.map(f).join(" && ") : void 0, s = async (e, t) => {
150
+ try {
151
+ return await t();
152
+ } catch (t) {
153
+ throw t instanceof r ? t : new r({
154
+ engine: "typesense",
155
+ op: e,
156
+ message: String(t?.message ?? t),
157
+ transient: !0
158
+ });
159
+ }
160
+ };
161
+ return {
162
+ upsert: (e, t) => s("upsert", async () => {
163
+ await (await a()).collections(e).documents().import(t, { action: "upsert" });
164
+ }),
165
+ remove: (e, t) => s("remove", async () => {
166
+ await (await a()).collections(e).documents().delete({ filter_by: `id:[${t.map((e) => JSON.stringify(e)).join(",")}]` });
167
+ }),
168
+ query: (e, { q: t, limit: r, offset: i, filters: c, facets: l, highlight: u, fuzziness: d, engineParams: f }) => s("query", async () => {
169
+ let s = await a(), p = n(f), h = {
170
+ ...p.before,
171
+ q: t || "*",
172
+ query_by: "*",
173
+ per_page: r ?? 20,
174
+ ...i ? { offset: i } : {},
175
+ ...o(c) ? { filter_by: o(c) } : {},
176
+ ...l && l.length > 0 ? { facet_by: l.join(",") } : {},
177
+ ...u ? {
178
+ ...u.fields && u.fields.length > 0 ? { highlight_fields: u.fields.join(",") } : { highlight_full_fields: "*" },
179
+ ...u.preTag ? { highlight_start_tag: u.preTag } : {},
180
+ ...u.postTag ? { highlight_end_tag: u.postTag } : {}
181
+ } : {},
182
+ ...d !== void 0 && d !== "auto" ? { num_typos: Math.min(2, Math.max(0, d)) } : {},
183
+ ...p.after
184
+ };
185
+ return m(await s.collections(e).documents().search(h));
186
+ })
187
+ };
188
+ }, m = (e) => {
189
+ let t = (e.hits ?? []).map((e) => {
190
+ let t = {};
191
+ for (let n of e.highlights ?? []) {
192
+ let e = n.snippet ?? n.value;
193
+ e && (t[n.field] = e);
194
+ }
195
+ return Object.keys(t).length > 0 ? {
196
+ doc: e.document,
197
+ highlights: t
198
+ } : { doc: e.document };
199
+ }), n = {};
200
+ for (let t of e.facet_counts ?? []) n[t.field_name] = Object.fromEntries(t.counts.map((e) => [e.value, e.count]));
201
+ return {
202
+ hits: t,
203
+ facets: n
204
+ };
205
+ }, h = (e) => {
206
+ let t = (e) => JSON.stringify(e), n = d("meilisearch", e.field);
207
+ switch (e.op) {
208
+ case "eq": return `${n} = ${t(e.value)}`;
209
+ case "neq": return `${n} != ${t(e.value)}`;
210
+ case "gt": return `${n} > ${t(e.value)}`;
211
+ case "gte": return `${n} >= ${t(e.value)}`;
212
+ case "lt": return `${n} < ${t(e.value)}`;
213
+ case "lte": return `${n} <= ${t(e.value)}`;
214
+ case "in": return `${n} IN [${i(e.value).map(t).join(", ")}]`;
215
+ case "nin": return `${n} NOT IN [${i(e.value).map(t).join(", ")}]`;
216
+ }
217
+ }, g = (e, t = {}) => {
218
+ let n = u("meilisearch", t), i, a = async () => (i ||= l("meilisearch", "meilisearch", () => import("meilisearch")).then((t) => new t.Meilisearch({
219
+ host: e.host ?? e.url ?? "http://localhost:7700",
220
+ apiKey: e.apiKey
221
+ })), i), o = (e) => e && e.length > 0 ? e.map(h) : void 0, s = async (e, t) => {
222
+ try {
223
+ return await t();
224
+ } catch (t) {
225
+ throw t instanceof r ? t : new r({
226
+ engine: "meilisearch",
227
+ op: e,
228
+ message: String(t?.message ?? t),
229
+ transient: !0
230
+ });
231
+ }
232
+ }, c = async (e, t) => {
233
+ let n = await (await a()).tasks.waitForTask(t, {
234
+ timeout: 6e4,
235
+ interval: 50
236
+ });
237
+ if (n.status !== "succeeded") throw new r({
238
+ engine: "meilisearch",
239
+ op: e,
240
+ message: n.error?.message ?? `Meilisearch task ${t.taskUid} ${n.status}`,
241
+ transient: n.status === "canceled"
242
+ });
243
+ };
244
+ return {
245
+ upsert: (e, t) => s("upsert", async () => {
246
+ await c("upsert", await (await a()).index(e).addDocuments([...t]));
247
+ }),
248
+ remove: (e, t) => s("remove", async () => {
249
+ await c("remove", await (await a()).index(e).deleteDocuments([...t]));
250
+ }),
251
+ query: (e, { q: t, limit: r, offset: i, filters: c, facets: l, highlight: u, fuzziness: d, engineParams: f }) => s("query", async () => {
252
+ let s = n(f), p = {
253
+ ...s.before,
254
+ limit: r ?? 20,
255
+ ...i ? { offset: i } : {},
256
+ ...o(c) ? { filter: o(c) } : {},
257
+ ...l && l.length > 0 ? { facets: [...l] } : {},
258
+ ...u ? {
259
+ attributesToHighlight: u.fields && u.fields.length > 0 ? [...u.fields] : ["*"],
260
+ ...u.preTag ? { highlightPreTag: u.preTag } : {},
261
+ ...u.postTag ? { highlightPostTag: u.postTag } : {}
262
+ } : {},
263
+ ...d === 0 ? {
264
+ rankingScoreThreshold: void 0,
265
+ typoTolerance: { enabled: !1 }
266
+ } : {},
267
+ ...s.after
268
+ };
269
+ return _(await (await a()).index(e).search(t, p), u);
270
+ })
271
+ };
272
+ }, _ = (e, t) => ({
273
+ hits: e.hits.map((e) => {
274
+ let { _formatted: n, ...r } = e;
275
+ if (t && n) {
276
+ let e = {};
277
+ for (let [t, r] of Object.entries(n)) t !== "id" && (e[t] = String(r));
278
+ return Object.keys(e).length > 0 ? {
279
+ doc: r,
280
+ highlights: e
281
+ } : { doc: r };
282
+ }
283
+ return { doc: r };
284
+ }),
285
+ facets: e.facetDistribution ?? {}
286
+ }), v = (e) => String(e).replace(/^-/, "\\-"), y = (e, t) => {
287
+ let n = typeof t == "boolean" ? +!!t : Number(t);
288
+ if (!Number.isFinite(n)) throw new r({
289
+ engine: "algolia",
290
+ op: "query",
291
+ message: `range filter on "${e}" needs a numeric value (got ${JSON.stringify(t)})`,
292
+ transient: !1
293
+ });
294
+ return n;
295
+ }, b = (e) => {
296
+ let t = [], n = [];
297
+ for (let r of e ?? []) {
298
+ let e = d("algolia", r.field), a = (e) => v(e), o = (t) => y(e, t);
299
+ switch (r.op) {
300
+ case "eq":
301
+ t.push(`${e}:${a(r.value)}`);
302
+ break;
303
+ case "neq":
304
+ t.push(`${e}:-${a(r.value)}`);
305
+ break;
306
+ case "in":
307
+ t.push(i(r.value).map((t) => `${e}:${a(t)}`));
308
+ break;
309
+ case "nin":
310
+ for (let n of i(r.value)) t.push(`${e}:-${a(n)}`);
311
+ break;
312
+ case "gt":
313
+ n.push(`${e} > ${o(r.value)}`);
314
+ break;
315
+ case "gte":
316
+ n.push(`${e} >= ${o(r.value)}`);
317
+ break;
318
+ case "lt":
319
+ n.push(`${e} < ${o(r.value)}`);
320
+ break;
321
+ case "lte": n.push(`${e} <= ${o(r.value)}`);
322
+ }
323
+ }
324
+ return {
325
+ facetFilters: t,
326
+ numericFilters: n
327
+ };
328
+ }, x = (e, t = {}) => {
329
+ let n = u("algolia", t), i, a = async () => (i ||= l("algoliasearch", "algolia", () => import("algoliasearch")).then((t) => t.algoliasearch(e.appId ?? "", e.apiKey)), i), o = async (e, t) => {
330
+ try {
331
+ return await t();
332
+ } catch (t) {
333
+ throw t instanceof r ? t : new r({
334
+ engine: "algolia",
335
+ op: e,
336
+ message: String(t?.message ?? t),
337
+ transient: !0
338
+ });
339
+ }
340
+ };
341
+ return {
342
+ upsert: (e, t) => o("upsert", async () => {
343
+ await (await a()).saveObjects({
344
+ indexName: e,
345
+ objects: t.map((e) => ({
346
+ ...e,
347
+ objectID: e.id
348
+ }))
349
+ });
350
+ }),
351
+ remove: (e, t) => o("remove", async () => {
352
+ await (await a()).deleteObjects({
353
+ indexName: e,
354
+ objectIDs: [...t]
355
+ });
356
+ }),
357
+ query: (e, { q: t, limit: r, offset: i, filters: s, facets: c, highlight: l, fuzziness: u, engineParams: d }) => o("query", async () => {
358
+ let { facetFilters: o, numericFilters: f } = b(s), p = i ? {
359
+ offset: i,
360
+ length: r ?? 20
361
+ } : { hitsPerPage: r ?? 20 }, m = n(d), h = {
362
+ ...m.before,
363
+ query: t,
364
+ ...p,
365
+ ...o.length > 0 ? { facetFilters: o } : {},
366
+ ...f.length > 0 ? { numericFilters: f } : {},
367
+ ...c && c.length > 0 ? { facets: [...c] } : {},
368
+ ...l ? {
369
+ ...l.fields && l.fields.length > 0 ? { attributesToHighlight: [...l.fields] } : {},
370
+ ...l.preTag ? { highlightPreTag: l.preTag } : {},
371
+ ...l.postTag ? { highlightPostTag: l.postTag } : {}
372
+ } : {},
373
+ ...u === 0 ? { typoTolerance: !1 } : {},
374
+ ...m.after
375
+ };
376
+ return S(await (await a()).searchSingleIndex({
377
+ indexName: e,
378
+ searchParams: h
379
+ }), l);
380
+ })
381
+ };
382
+ }, S = (e, t) => ({
383
+ hits: e.hits.map((e) => {
384
+ let { _highlightResult: n, ...r } = e;
385
+ if (t && n) {
386
+ let e = {};
387
+ for (let [t, r] of Object.entries(n)) t !== "id" && r?.value && (e[t] = r.value);
388
+ return Object.keys(e).length > 0 ? {
389
+ doc: r,
390
+ highlights: e
391
+ } : { doc: r };
392
+ }
393
+ return { doc: r };
394
+ }),
395
+ facets: e.facets ?? {}
396
+ });
397
+ //#endregion
398
+ export { r as SearchBackendError, x as algoliaBackend, a as editDistanceWithin, g as meilisearchBackend, s as memoryBackend, p as typesenseBackend };
package/dist/drift.js ADDED
@@ -0,0 +1,121 @@
1
+ import { and as e, count as t, eq as n, id as r, integer as i, table as a, text as o, timestamp as s } from "@voltro/database";
2
+ //#region src/drift.ts
3
+ var c = "_voltro_search_drift", l = a(c, {
4
+ id: r({ prefix: "sdrft" }),
5
+ indexName: o().maxLength(191),
6
+ sourceTable: o().maxLength(191),
7
+ rowId: o().maxLength(191),
8
+ docId: o().maxLength(191),
9
+ op: o().maxLength(16),
10
+ attempts: i().default(0),
11
+ lastError: o().maxLength(1e3),
12
+ firstFailedAt: s(),
13
+ lastFailedAt: s()
14
+ }).unique("bySearchDriftIndexRow", ["indexName", "rowId"]).index("bySearchDriftIndex", ["indexName"]), u = (e, t) => ({
15
+ table: e,
16
+ predicate: n("id", t),
17
+ order: [],
18
+ take: 1,
19
+ skip: void 0,
20
+ projection: void 0
21
+ }), d = (e) => e ? new Date(e).toISOString() : (/* @__PURE__ */ new Date(0)).toISOString(), f = (e) => ({
22
+ indexName: String(e.indexName),
23
+ sourceTable: String(e.sourceTable),
24
+ rowId: String(e.rowId),
25
+ docId: String(e.docId),
26
+ op: e.op === "remove" ? "remove" : "upsert",
27
+ attempts: Number(e.attempts ?? 0),
28
+ lastError: String(e.lastError ?? ""),
29
+ firstFailedAt: d(e.firstFailedAt),
30
+ lastFailedAt: d(e.lastFailedAt)
31
+ }), p = () => {
32
+ let e = /* @__PURE__ */ new Map(), t = (e, t) => `${e}\u0000${t}`;
33
+ return {
34
+ record: async (n) => {
35
+ let r = (/* @__PURE__ */ new Date()).toISOString(), i = e.get(t(n.indexName, n.rowId));
36
+ e.set(t(n.indexName, n.rowId), {
37
+ indexName: n.indexName,
38
+ sourceTable: n.sourceTable,
39
+ rowId: n.rowId,
40
+ docId: n.docId,
41
+ op: n.op,
42
+ attempts: (i?.attempts ?? 0) + 1,
43
+ lastError: n.error,
44
+ firstFailedAt: i?.firstFailedAt ?? r,
45
+ lastFailedAt: r
46
+ });
47
+ },
48
+ list: async (t) => [...e.values()].sort((e, t) => e.firstFailedAt.localeCompare(t.firstFailedAt)).slice(0, t),
49
+ summary: async (t) => {
50
+ let n = [...e.values()].filter((e) => e.indexName === t), r = null;
51
+ for (let e of n) (r === null || e.lastFailedAt > r) && (r = e.lastFailedAt);
52
+ return {
53
+ pending: n.length,
54
+ lastFailedAt: r
55
+ };
56
+ },
57
+ clear: async (n, r) => {
58
+ e.delete(t(n, r));
59
+ }
60
+ };
61
+ }, m = () => `sdrft_${Math.random().toString(36).slice(2)}${Date.now().toString(36)}`, h = (e, t) => ({
62
+ table: c,
63
+ predicate: e,
64
+ order: [{
65
+ column: "firstFailedAt",
66
+ direction: "asc"
67
+ }],
68
+ take: t,
69
+ skip: void 0,
70
+ projection: void 0
71
+ }), g = (r) => ({
72
+ record: async (e) => {
73
+ let t = /* @__PURE__ */ new Date(), i = m(), a = await r.insertIgnore(c, {
74
+ id: i,
75
+ indexName: e.indexName,
76
+ sourceTable: e.sourceTable,
77
+ rowId: e.rowId,
78
+ docId: e.docId,
79
+ op: e.op,
80
+ attempts: 1,
81
+ lastError: e.error.slice(0, 1e3),
82
+ firstFailedAt: t,
83
+ lastFailedAt: t
84
+ }, { conflictColumns: ["indexName", "rowId"] });
85
+ String(a.id) !== i && await r.updateMany(c, {
86
+ attempts: Number(a.attempts ?? 0) + 1,
87
+ op: e.op,
88
+ docId: e.docId,
89
+ lastError: e.error.slice(0, 1e3),
90
+ lastFailedAt: t
91
+ }, { where: n("id", String(a.id)) });
92
+ },
93
+ list: async (e) => (await r.query(h(void 0, e))).map(f),
94
+ summary: async (e) => {
95
+ let i = (await r.query({
96
+ ...h(n("indexName", e), void 0),
97
+ order: [],
98
+ aggregations: [t("n")]
99
+ }))[0], a = Number(i?.n ?? i?.count ?? 0);
100
+ if (a === 0) return {
101
+ pending: 0,
102
+ lastFailedAt: null
103
+ };
104
+ let o = await r.query({
105
+ ...h(n("indexName", e), 1),
106
+ order: [{
107
+ column: "lastFailedAt",
108
+ direction: "desc"
109
+ }]
110
+ });
111
+ return {
112
+ pending: a,
113
+ lastFailedAt: o[0] ? d(o[0].lastFailedAt) : null
114
+ };
115
+ },
116
+ clear: async (t, i) => {
117
+ await r.deleteMany(c, { where: e(n("indexName", t), n("rowId", i)) });
118
+ }
119
+ }), _ = () => [l];
120
+ //#endregion
121
+ export { c as SEARCH_DRIFT_TABLE, g as dataStoreDriftLedger, u as driftSourceQuery, _ as driftTables, p as memoryDriftLedger, l as searchDriftTable };
package/dist/errors.js ADDED
@@ -0,0 +1,13 @@
1
+ import { Schema as e } from "effect";
2
+ //#region src/errors.ts
3
+ var t = class extends e.TaggedError()("SearchIndexNotFound", { index: e.String }) {}, n = class extends e.TaggedError()("SearchFieldRejected", {
4
+ field: e.String,
5
+ where: e.Literals([
6
+ "filter",
7
+ "facet",
8
+ "highlight"
9
+ ]),
10
+ reason: e.Literals(["not-an-identifier", "not-queryable"])
11
+ }) {};
12
+ //#endregion
13
+ export { n as SearchFieldRejected, t as SearchIndexNotFound };