@voltro/plugin-search 0.83.1 → 0.85.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.
- package/CHANGELOG.md +1191 -0
- package/THIRD-PARTY-NOTICES.md +1 -57
- package/dist/index.d.ts +8 -12
- package/dist/index.js +250 -247
- package/dist/{rpc-CpryHBcM.js → rpc-CggQ77CG.js} +28 -26
- package/dist/rpc.d.ts +32 -35
- package/dist/rpc.js +1 -1
- package/dist/web.js +1 -1
- package/package.json +5 -5
package/dist/index.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import { a as e, i as t, o as n, r, t as i } from "./rpc-
|
|
2
|
-
import { Cause as a,
|
|
3
|
-
import { and as
|
|
4
|
-
import { definePlugin as
|
|
5
|
-
import { replicaId as
|
|
1
|
+
import { a as e, i as t, o as n, r, t as i } from "./rpc-CggQ77CG.js";
|
|
2
|
+
import { Cause as a, Data as o, Duration as s, Effect as c, Exit as l, Option as u, Schedule as d, Stream as f } from "effect";
|
|
3
|
+
import { and as p, count as m, eq as h, id as g, integer as _, streamTable as ee, table as v, text as y, timestamp as b } from "@voltro/database";
|
|
4
|
+
import { definePlugin as te, pluginInstanceName as ne } from "@voltro/protocol";
|
|
5
|
+
import { replicaId as re } from "@voltro/protocol/identity";
|
|
6
6
|
//#region src/sanitize.ts
|
|
7
|
-
var
|
|
7
|
+
var x = /^[A-Za-z_][A-Za-z0-9_.]*$/, S = (e) => x.test(e), ie = (e, t) => {
|
|
8
8
|
let n = t ? new Set(t) : void 0;
|
|
9
9
|
for (let [t, r] of e) {
|
|
10
|
-
if (!
|
|
10
|
+
if (!S(r)) return {
|
|
11
11
|
field: r,
|
|
12
12
|
where: t,
|
|
13
13
|
reason: "not-an-identifier"
|
|
@@ -18,7 +18,7 @@ var C = /^[A-Za-z_][A-Za-z0-9_.]*$/, w = (e) => C.test(e), re = (e, t) => {
|
|
|
18
18
|
reason: "not-queryable"
|
|
19
19
|
};
|
|
20
20
|
}
|
|
21
|
-
},
|
|
21
|
+
}, C = {
|
|
22
22
|
typesense: [
|
|
23
23
|
"per_page",
|
|
24
24
|
"page",
|
|
@@ -72,7 +72,7 @@ var C = /^[A-Za-z_][A-Za-z0-9_.]*$/, w = (e) => C.test(e), re = (e, t) => {
|
|
|
72
72
|
"highlightPreTag",
|
|
73
73
|
"highlightPostTag"
|
|
74
74
|
]
|
|
75
|
-
},
|
|
75
|
+
}, w = {
|
|
76
76
|
typesense: [
|
|
77
77
|
"filter_by",
|
|
78
78
|
"q",
|
|
@@ -109,36 +109,39 @@ var C = /^[A-Za-z_][A-Za-z0-9_.]*$/, w = (e) => C.test(e), re = (e, t) => {
|
|
|
109
109
|
"aroundLatLng",
|
|
110
110
|
"insideBoundingBox"
|
|
111
111
|
]
|
|
112
|
-
},
|
|
112
|
+
}, T = (e, t, n) => {
|
|
113
113
|
if (!t) return {
|
|
114
114
|
params: {},
|
|
115
115
|
appAllowed: {},
|
|
116
116
|
dropped: []
|
|
117
117
|
};
|
|
118
|
-
let r = new Set(
|
|
118
|
+
let r = new Set(w[e]), i = new Set(C[e]), a = new Set(n ?? []), o = {}, s = {}, c = [];
|
|
119
119
|
for (let [e, n] of Object.entries(t)) r.has(e) ? c.push(e) : i.has(e) ? o[e] = n : a.has(e) ? s[e] = n : c.push(e);
|
|
120
120
|
return {
|
|
121
121
|
params: o,
|
|
122
122
|
appAllowed: s,
|
|
123
123
|
dropped: c
|
|
124
124
|
};
|
|
125
|
-
},
|
|
125
|
+
}, E = (e) => C[e], D = class extends o.TaggedError("SearchBackendError") {}, O = (e) => Array.isArray(e) ? e : [e], k = (e, t, n) => {
|
|
126
126
|
if (Math.abs(e.length - t.length) > n) return !1;
|
|
127
127
|
if (e === t) return !0;
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
let
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
128
|
+
if (Number.isNaN(n)) return !1;
|
|
129
|
+
let r = t.length, i = Math.floor(n), a = Array(r + 1).fill(Infinity), o = Array(r + 1).fill(Infinity);
|
|
130
|
+
for (let e = 0; e <= Math.min(r, i); e++) a[e] = e;
|
|
131
|
+
for (let s = 1; s <= e.length; s++) {
|
|
132
|
+
let c = Math.max(1, s - i), l = Math.min(r, s + i);
|
|
133
|
+
o[0] = s, c > 1 && (o[c - 1] = Infinity), l < r && (o[l + 1] = Infinity);
|
|
134
|
+
let u = s, d = e.charCodeAt(s - 1);
|
|
135
|
+
for (let e = c; e <= l; e++) {
|
|
136
|
+
let n = d === t.charCodeAt(e - 1) ? 0 : 1, r = Math.min(a[e] + 1, o[e - 1] + 1, a[e - 1] + n);
|
|
137
|
+
o[e] = r, u = Math.min(u, r);
|
|
136
138
|
}
|
|
137
|
-
if (
|
|
138
|
-
|
|
139
|
+
if (u > n) return !1;
|
|
140
|
+
let f = a;
|
|
141
|
+
a = o, o = f;
|
|
139
142
|
}
|
|
140
|
-
return
|
|
141
|
-
},
|
|
143
|
+
return a[r] <= n;
|
|
144
|
+
}, A = (e) => e.length <= 4 ? 1 : 2, j = () => {
|
|
142
145
|
let e = /* @__PURE__ */ new Map(), t = (t) => {
|
|
143
146
|
let n = e.get(t);
|
|
144
147
|
return n || (n = /* @__PURE__ */ new Map(), e.set(t, n)), n;
|
|
@@ -147,13 +150,13 @@ var C = /^[A-Za-z_][A-Za-z0-9_.]*$/, w = (e) => C.test(e), re = (e, t) => {
|
|
|
147
150
|
switch (t.op) {
|
|
148
151
|
case "eq": return String(n) === String(t.value);
|
|
149
152
|
case "neq": return String(n) !== String(t.value);
|
|
150
|
-
case "in": return
|
|
151
|
-
case "nin": return
|
|
153
|
+
case "in": return O(t.value).some((e) => String(n) === String(e));
|
|
154
|
+
case "nin": return O(t.value).every((e) => String(n) !== String(e));
|
|
152
155
|
case "gt":
|
|
153
156
|
case "gte":
|
|
154
157
|
case "lt":
|
|
155
158
|
case "lte": {
|
|
156
|
-
let [e, r] = [
|
|
159
|
+
let [e, r] = [M(n), M(t.value)];
|
|
157
160
|
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;
|
|
158
161
|
}
|
|
159
162
|
}
|
|
@@ -163,8 +166,8 @@ var C = /^[A-Za-z_][A-Za-z0-9_.]*$/, w = (e) => C.test(e), re = (e, t) => {
|
|
|
163
166
|
let e = r.toLowerCase();
|
|
164
167
|
if (e.includes(t)) return !0;
|
|
165
168
|
if (n !== void 0 && n !== 0) {
|
|
166
|
-
let r = n === "auto" ?
|
|
167
|
-
for (let n of e.split(/\s+/)) if (
|
|
169
|
+
let r = n === "auto" ? A(t) : n;
|
|
170
|
+
for (let n of e.split(/\s+/)) if (k(n, t, r)) return !0;
|
|
168
171
|
}
|
|
169
172
|
}
|
|
170
173
|
return !1;
|
|
@@ -208,7 +211,7 @@ var C = /^[A-Za-z_][A-Za-z0-9_.]*$/, w = (e) => C.test(e), re = (e, t) => {
|
|
|
208
211
|
};
|
|
209
212
|
}
|
|
210
213
|
};
|
|
211
|
-
},
|
|
214
|
+
}, M = (e) => {
|
|
212
215
|
if (typeof e == "number") return e;
|
|
213
216
|
if (typeof e == "boolean") return +!!e;
|
|
214
217
|
if (typeof e == "string") {
|
|
@@ -217,19 +220,19 @@ var C = /^[A-Za-z_][A-Za-z0-9_.]*$/, w = (e) => C.test(e), re = (e, t) => {
|
|
|
217
220
|
let n = Date.parse(e);
|
|
218
221
|
return Number.isNaN(n) ? void 0 : n;
|
|
219
222
|
}
|
|
220
|
-
},
|
|
223
|
+
}, N = async (e, t, n) => {
|
|
221
224
|
try {
|
|
222
225
|
return await n();
|
|
223
226
|
} catch {
|
|
224
|
-
throw new
|
|
227
|
+
throw new D({
|
|
225
228
|
engine: t,
|
|
226
229
|
op: "query",
|
|
227
230
|
message: `the '${t}' search backend requires the '${e}' optional dependency. Install it to enable it (e.g. \`npm i ${e}\`).`,
|
|
228
231
|
transient: !1
|
|
229
232
|
});
|
|
230
233
|
}
|
|
231
|
-
},
|
|
232
|
-
let { params: r, appAllowed: i, dropped: a } =
|
|
234
|
+
}, P = (e, t) => (n) => {
|
|
235
|
+
let { params: r, appAllowed: i, dropped: a } = T(e, n, t.allowEngineParams);
|
|
233
236
|
return a.length > 0 && t.onWarn?.("search dropped disallowed engineParams", {
|
|
234
237
|
engine: e,
|
|
235
238
|
keys: a
|
|
@@ -237,16 +240,16 @@ var C = /^[A-Za-z_][A-Za-z0-9_.]*$/, w = (e) => C.test(e), re = (e, t) => {
|
|
|
237
240
|
before: r,
|
|
238
241
|
after: i
|
|
239
242
|
};
|
|
240
|
-
},
|
|
241
|
-
if (!
|
|
243
|
+
}, F = (e, t) => {
|
|
244
|
+
if (!S(t)) throw new D({
|
|
242
245
|
engine: e,
|
|
243
246
|
op: "query",
|
|
244
247
|
message: `filter field "${t}" is not a plain field path (^[A-Za-z_][A-Za-z0-9_.]*$)`,
|
|
245
248
|
transient: !1
|
|
246
249
|
});
|
|
247
250
|
return t;
|
|
248
|
-
},
|
|
249
|
-
let t = (e) => JSON.stringify(e), n =
|
|
251
|
+
}, ae = (e) => {
|
|
252
|
+
let t = (e) => JSON.stringify(e), n = F("typesense", e.field);
|
|
250
253
|
switch (e.op) {
|
|
251
254
|
case "eq": return `${n}:=${t(e.value)}`;
|
|
252
255
|
case "neq": return `${n}:!=${t(e.value)}`;
|
|
@@ -254,21 +257,21 @@ var C = /^[A-Za-z_][A-Za-z0-9_.]*$/, w = (e) => C.test(e), re = (e, t) => {
|
|
|
254
257
|
case "gte": return `${n}:>=${t(e.value)}`;
|
|
255
258
|
case "lt": return `${n}:<${t(e.value)}`;
|
|
256
259
|
case "lte": return `${n}:<=${t(e.value)}`;
|
|
257
|
-
case "in": return `${n}:[${
|
|
258
|
-
case "nin": return `${n}:!=[${
|
|
260
|
+
case "in": return `${n}:[${O(e.value).map(t).join(",")}]`;
|
|
261
|
+
case "nin": return `${n}:!=[${O(e.value).map(t).join(",")}]`;
|
|
259
262
|
}
|
|
260
|
-
},
|
|
261
|
-
let n =
|
|
263
|
+
}, oe = (e, t = {}) => {
|
|
264
|
+
let n = P("typesense", t), r, i = async () => (r ||= N("typesense", "typesense", () => import("typesense")).then((t) => {
|
|
262
265
|
let n = t.Client;
|
|
263
266
|
return new n({
|
|
264
267
|
nodes: [{ url: e.url ?? e.host ?? "http://localhost:8108" }],
|
|
265
268
|
apiKey: e.apiKey
|
|
266
269
|
});
|
|
267
|
-
}), r), a = (e) => e && e.length > 0 ? e.map(
|
|
270
|
+
}), r), a = (e) => e && e.length > 0 ? e.map(ae).join(" && ") : void 0, o = async (e, t) => {
|
|
268
271
|
try {
|
|
269
272
|
return await t();
|
|
270
273
|
} catch (t) {
|
|
271
|
-
throw t instanceof
|
|
274
|
+
throw t instanceof D ? t : new D({
|
|
272
275
|
engine: "typesense",
|
|
273
276
|
op: e,
|
|
274
277
|
message: String(t?.message ?? t),
|
|
@@ -300,10 +303,10 @@ var C = /^[A-Za-z_][A-Za-z0-9_.]*$/, w = (e) => C.test(e), re = (e, t) => {
|
|
|
300
303
|
...d !== void 0 && d !== "auto" ? { num_typos: Math.min(2, Math.max(0, d)) } : {},
|
|
301
304
|
...p.after
|
|
302
305
|
};
|
|
303
|
-
return
|
|
306
|
+
return se(await o.collections(e).documents().search(m));
|
|
304
307
|
})
|
|
305
308
|
};
|
|
306
|
-
},
|
|
309
|
+
}, se = (e) => {
|
|
307
310
|
let t = (e.hits ?? []).map((e) => {
|
|
308
311
|
let t = {};
|
|
309
312
|
for (let n of e.highlights ?? []) {
|
|
@@ -320,8 +323,8 @@ var C = /^[A-Za-z_][A-Za-z0-9_.]*$/, w = (e) => C.test(e), re = (e, t) => {
|
|
|
320
323
|
hits: t,
|
|
321
324
|
facets: n
|
|
322
325
|
};
|
|
323
|
-
},
|
|
324
|
-
let t = (e) => JSON.stringify(e), n =
|
|
326
|
+
}, ce = (e) => {
|
|
327
|
+
let t = (e) => JSON.stringify(e), n = F("meilisearch", e.field);
|
|
325
328
|
switch (e.op) {
|
|
326
329
|
case "eq": return `${n} = ${t(e.value)}`;
|
|
327
330
|
case "neq": return `${n} != ${t(e.value)}`;
|
|
@@ -329,18 +332,18 @@ var C = /^[A-Za-z_][A-Za-z0-9_.]*$/, w = (e) => C.test(e), re = (e, t) => {
|
|
|
329
332
|
case "gte": return `${n} >= ${t(e.value)}`;
|
|
330
333
|
case "lt": return `${n} < ${t(e.value)}`;
|
|
331
334
|
case "lte": return `${n} <= ${t(e.value)}`;
|
|
332
|
-
case "in": return `${n} IN [${
|
|
333
|
-
case "nin": return `${n} NOT IN [${
|
|
335
|
+
case "in": return `${n} IN [${O(e.value).map(t).join(", ")}]`;
|
|
336
|
+
case "nin": return `${n} NOT IN [${O(e.value).map(t).join(", ")}]`;
|
|
334
337
|
}
|
|
335
|
-
},
|
|
336
|
-
let n =
|
|
338
|
+
}, I = (e, t = {}) => {
|
|
339
|
+
let n = P("meilisearch", t), r, i = async () => (r ||= N("meilisearch", "meilisearch", () => import("meilisearch")).then((t) => new t.Meilisearch({
|
|
337
340
|
host: e.host ?? e.url ?? "http://localhost:7700",
|
|
338
341
|
apiKey: e.apiKey
|
|
339
|
-
})), r), a = (e) => e && e.length > 0 ? e.map(
|
|
342
|
+
})), r), a = (e) => e && e.length > 0 ? e.map(ce) : void 0, o = async (e, t) => {
|
|
340
343
|
try {
|
|
341
344
|
return await t();
|
|
342
345
|
} catch (t) {
|
|
343
|
-
throw t instanceof
|
|
346
|
+
throw t instanceof D ? t : new D({
|
|
344
347
|
engine: "meilisearch",
|
|
345
348
|
op: e,
|
|
346
349
|
message: String(t?.message ?? t),
|
|
@@ -352,7 +355,7 @@ var C = /^[A-Za-z_][A-Za-z0-9_.]*$/, w = (e) => C.test(e), re = (e, t) => {
|
|
|
352
355
|
timeout: 6e4,
|
|
353
356
|
interval: 50
|
|
354
357
|
});
|
|
355
|
-
if (n.status !== "succeeded") throw new
|
|
358
|
+
if (n.status !== "succeeded") throw new D({
|
|
356
359
|
engine: "meilisearch",
|
|
357
360
|
op: e,
|
|
358
361
|
message: n.error?.message ?? `Meilisearch task ${t.taskUid} ${n.status}`,
|
|
@@ -403,7 +406,7 @@ var C = /^[A-Za-z_][A-Za-z0-9_.]*$/, w = (e) => C.test(e), re = (e, t) => {
|
|
|
403
406
|
facets: e.facetDistribution ?? {}
|
|
404
407
|
}), ue = (e) => String(e).replace(/^-/, "\\-"), de = (e, t) => {
|
|
405
408
|
let n = typeof t == "boolean" ? +!!t : Number(t);
|
|
406
|
-
if (!Number.isFinite(n)) throw new
|
|
409
|
+
if (!Number.isFinite(n)) throw new D({
|
|
407
410
|
engine: "algolia",
|
|
408
411
|
op: "query",
|
|
409
412
|
message: `range filter on "${e}" needs a numeric value (got ${JSON.stringify(t)})`,
|
|
@@ -413,7 +416,7 @@ var C = /^[A-Za-z_][A-Za-z0-9_.]*$/, w = (e) => C.test(e), re = (e, t) => {
|
|
|
413
416
|
}, fe = (e) => {
|
|
414
417
|
let t = [], n = [];
|
|
415
418
|
for (let r of e ?? []) {
|
|
416
|
-
let e =
|
|
419
|
+
let e = F("algolia", r.field), i = (e) => ue(e), a = (t) => de(e, t);
|
|
417
420
|
switch (r.op) {
|
|
418
421
|
case "eq":
|
|
419
422
|
t.push(`${e}:${i(r.value)}`);
|
|
@@ -422,10 +425,10 @@ var C = /^[A-Za-z_][A-Za-z0-9_.]*$/, w = (e) => C.test(e), re = (e, t) => {
|
|
|
422
425
|
t.push(`${e}:-${i(r.value)}`);
|
|
423
426
|
break;
|
|
424
427
|
case "in":
|
|
425
|
-
t.push(
|
|
428
|
+
t.push(O(r.value).map((t) => `${e}:${i(t)}`));
|
|
426
429
|
break;
|
|
427
430
|
case "nin":
|
|
428
|
-
for (let n of
|
|
431
|
+
for (let n of O(r.value)) t.push(`${e}:-${i(n)}`);
|
|
429
432
|
break;
|
|
430
433
|
case "gt":
|
|
431
434
|
n.push(`${e} > ${a(r.value)}`);
|
|
@@ -443,12 +446,12 @@ var C = /^[A-Za-z_][A-Za-z0-9_.]*$/, w = (e) => C.test(e), re = (e, t) => {
|
|
|
443
446
|
facetFilters: t,
|
|
444
447
|
numericFilters: n
|
|
445
448
|
};
|
|
446
|
-
},
|
|
447
|
-
let n =
|
|
449
|
+
}, L = (e, t = {}) => {
|
|
450
|
+
let n = P("algolia", t), r, i = async () => (r ||= N("algoliasearch", "algolia", () => import("algoliasearch")).then((t) => t.algoliasearch(e.appId ?? "", e.apiKey)), r), a = async (e, t) => {
|
|
448
451
|
try {
|
|
449
452
|
return await t();
|
|
450
453
|
} catch (t) {
|
|
451
|
-
throw t instanceof
|
|
454
|
+
throw t instanceof D ? t : new D({
|
|
452
455
|
engine: "algolia",
|
|
453
456
|
op: e,
|
|
454
457
|
message: String(t?.message ?? t),
|
|
@@ -491,13 +494,13 @@ var C = /^[A-Za-z_][A-Za-z0-9_.]*$/, w = (e) => C.test(e), re = (e, t) => {
|
|
|
491
494
|
...u === 0 ? { typoTolerance: !1 } : {},
|
|
492
495
|
...m.after
|
|
493
496
|
};
|
|
494
|
-
return
|
|
497
|
+
return pe(await (await i()).searchSingleIndex({
|
|
495
498
|
indexName: e,
|
|
496
499
|
searchParams: h
|
|
497
500
|
}), l);
|
|
498
501
|
})
|
|
499
502
|
};
|
|
500
|
-
},
|
|
503
|
+
}, pe = (e, t) => ({
|
|
501
504
|
hits: e.hits.map((e) => {
|
|
502
505
|
let { _highlightResult: n, ...r } = e;
|
|
503
506
|
if (t && n) {
|
|
@@ -511,25 +514,25 @@ var C = /^[A-Za-z_][A-Za-z0-9_.]*$/, w = (e) => C.test(e), re = (e, t) => {
|
|
|
511
514
|
return { doc: r };
|
|
512
515
|
}),
|
|
513
516
|
facets: e.facets ?? {}
|
|
514
|
-
}), R = "_voltro_search_stats",
|
|
517
|
+
}), R = "_voltro_search_stats", z = () => ({
|
|
515
518
|
synced: 0,
|
|
516
519
|
removed: 0,
|
|
517
520
|
dropped: 0,
|
|
518
521
|
lastReindexAt: null,
|
|
519
522
|
lastReindexCount: 0
|
|
520
|
-
}),
|
|
521
|
-
id:
|
|
522
|
-
indexName:
|
|
523
|
-
replicaId:
|
|
524
|
-
synced:
|
|
525
|
-
removed:
|
|
526
|
-
dropped:
|
|
527
|
-
scope:
|
|
528
|
-
lastReindexAt:
|
|
529
|
-
lastReindexCount:
|
|
530
|
-
updatedAt:
|
|
531
|
-
}).unique("bySearchStatsIndexReplica", ["indexName", "replicaId"]).index("bySearchStatsIndex", ["indexName"]),
|
|
532
|
-
let e = /* @__PURE__ */ new Map(), t = (t) => e.get(t) ??
|
|
523
|
+
}), B = v(R, {
|
|
524
|
+
id: g({ prefix: "sstat" }),
|
|
525
|
+
indexName: y().maxLength(191),
|
|
526
|
+
replicaId: y().maxLength(191),
|
|
527
|
+
synced: _().default(0),
|
|
528
|
+
removed: _().default(0),
|
|
529
|
+
dropped: _().default(0),
|
|
530
|
+
scope: y().maxLength(8).default("local"),
|
|
531
|
+
lastReindexAt: b().nullable(),
|
|
532
|
+
lastReindexCount: _().default(0),
|
|
533
|
+
updatedAt: b()
|
|
534
|
+
}).unique("bySearchStatsIndexReplica", ["indexName", "replicaId"]).index("bySearchStatsIndex", ["indexName"]), V = () => [B], H = () => {
|
|
535
|
+
let e = /* @__PURE__ */ new Map(), t = (t) => e.get(t) ?? z();
|
|
533
536
|
return {
|
|
534
537
|
bump: async (n, r) => {
|
|
535
538
|
let i = t(n);
|
|
@@ -564,19 +567,19 @@ var C = /^[A-Za-z_][A-Za-z0-9_.]*$/, w = (e) => C.test(e), re = (e, t) => {
|
|
|
564
567
|
},
|
|
565
568
|
get: async (e) => t(e)
|
|
566
569
|
};
|
|
567
|
-
},
|
|
570
|
+
}, U = (e) => ({
|
|
568
571
|
table: R,
|
|
569
572
|
predicate: e,
|
|
570
573
|
order: [],
|
|
571
574
|
take: void 0,
|
|
572
575
|
skip: void 0,
|
|
573
576
|
projection: void 0
|
|
574
|
-
}),
|
|
575
|
-
let n = async (n) => (await e.query(
|
|
577
|
+
}), me = () => `sstat_${Math.random().toString(36).slice(2)}${Date.now().toString(36)}`, he = () => re(), W = 32, G = (e, t = he()) => {
|
|
578
|
+
let n = async (n) => (await e.query(U(p(h("indexName", n), h("replicaId", t)))))[0] ?? null, r = async (e) => {
|
|
576
579
|
try {
|
|
577
580
|
return await e();
|
|
578
581
|
} catch (e) {
|
|
579
|
-
throw e instanceof
|
|
582
|
+
throw e instanceof D ? e : new D({
|
|
580
583
|
engine: "stats",
|
|
581
584
|
op: "upsert",
|
|
582
585
|
message: String(e?.message ?? e),
|
|
@@ -584,7 +587,7 @@ var C = /^[A-Za-z_][A-Za-z0-9_.]*$/, w = (e) => C.test(e), re = (e, t) => {
|
|
|
584
587
|
});
|
|
585
588
|
}
|
|
586
589
|
}, i = (i, a, o, s) => r(async () => {
|
|
587
|
-
for (let r = 0; r <
|
|
590
|
+
for (let r = 0; r < W; r++) {
|
|
588
591
|
r > 0 && await new Promise((e) => setTimeout(e, r));
|
|
589
592
|
let c = await n(i);
|
|
590
593
|
if (c) {
|
|
@@ -599,9 +602,9 @@ var C = /^[A-Za-z_][A-Za-z0-9_.]*$/, w = (e) => C.test(e), re = (e, t) => {
|
|
|
599
602
|
...o(i),
|
|
600
603
|
...a ? { scope: a } : {},
|
|
601
604
|
updatedAt: /* @__PURE__ */ new Date()
|
|
602
|
-
}, { where:
|
|
605
|
+
}, { where: p(h("id", String(c.id)), h("synced", t), h("removed", n), h("dropped", r)) }) === 1) return;
|
|
603
606
|
} else {
|
|
604
|
-
let n =
|
|
607
|
+
let n = me(), r = await e.insertIgnore(R, {
|
|
605
608
|
id: n,
|
|
606
609
|
indexName: i,
|
|
607
610
|
replicaId: t,
|
|
@@ -617,10 +620,10 @@ var C = /^[A-Za-z_][A-Za-z0-9_.]*$/, w = (e) => C.test(e), re = (e, t) => {
|
|
|
617
620
|
if (String(r.id) === n) return;
|
|
618
621
|
}
|
|
619
622
|
}
|
|
620
|
-
throw new
|
|
623
|
+
throw new D({
|
|
621
624
|
engine: "stats",
|
|
622
625
|
op: "upsert",
|
|
623
|
-
message: `search stats: contention on (${i}, ${t}) exceeded ${
|
|
626
|
+
message: `search stats: contention on (${i}, ${t}) exceeded ${W} attempts`,
|
|
624
627
|
transient: !0
|
|
625
628
|
});
|
|
626
629
|
});
|
|
@@ -645,7 +648,7 @@ var C = /^[A-Za-z_][A-Za-z0-9_.]*$/, w = (e) => C.test(e), re = (e, t) => {
|
|
|
645
648
|
lastReindexCount: t
|
|
646
649
|
}),
|
|
647
650
|
get: (t) => r(async () => {
|
|
648
|
-
let n = await e.query(
|
|
651
|
+
let n = await e.query(U(h("indexName", t))), r = n.some((e) => e.scope === "fleet"), i = (e) => {
|
|
649
652
|
let t = 0;
|
|
650
653
|
for (let i of n) {
|
|
651
654
|
let n = Number(i[e] ?? 0);
|
|
@@ -658,7 +661,7 @@ var C = /^[A-Za-z_][A-Za-z0-9_.]*$/, w = (e) => C.test(e), re = (e, t) => {
|
|
|
658
661
|
t && (a === null || t > a) && (a = t, o = Number(e.lastReindexCount ?? 0));
|
|
659
662
|
}
|
|
660
663
|
return {
|
|
661
|
-
...
|
|
664
|
+
...z(),
|
|
662
665
|
synced: i("synced"),
|
|
663
666
|
removed: i("removed"),
|
|
664
667
|
dropped: i("dropped"),
|
|
@@ -667,7 +670,7 @@ var C = /^[A-Za-z_][A-Za-z0-9_.]*$/, w = (e) => C.test(e), re = (e, t) => {
|
|
|
667
670
|
};
|
|
668
671
|
})
|
|
669
672
|
};
|
|
670
|
-
},
|
|
673
|
+
}, K = (e) => {
|
|
671
674
|
let t = /* @__PURE__ */ new Map(), n = 0, r = !1, i = async () => {
|
|
672
675
|
if (t.size === 0) return;
|
|
673
676
|
let r = t;
|
|
@@ -699,12 +702,12 @@ var C = /^[A-Za-z_][A-Za-z0-9_.]*$/, w = (e) => C.test(e), re = (e, t) => {
|
|
|
699
702
|
},
|
|
700
703
|
pending: () => n
|
|
701
704
|
};
|
|
702
|
-
},
|
|
705
|
+
}, q = (e) => (t, n, r) => e().add(t, n, r), ge = (e) => e === void 0 || e === "memory" ? "memory" : typeof e.query == "function" ? e.engineKind === "memory" ? "memory" : "custom" : "vendor", _e = class extends Error {
|
|
703
706
|
_tag = "SearchBackendNotDurable";
|
|
704
707
|
constructor(e) {
|
|
705
708
|
super(e), this.name = "SearchBackendNotDurable";
|
|
706
709
|
}
|
|
707
|
-
},
|
|
710
|
+
}, ve = [
|
|
708
711
|
"plugin-search refuses to boot in production on the in-memory backend.",
|
|
709
712
|
"",
|
|
710
713
|
"The memory index lives in THIS process's heap. Two consequences, both silent:",
|
|
@@ -722,36 +725,36 @@ var C = /^[A-Za-z_][A-Za-z0-9_.]*$/, w = (e) => C.test(e), re = (e, t) => {
|
|
|
722
725
|
" searchPlugin({ singleProcessMemoryIndex: true, indexes })",
|
|
723
726
|
"That is a claim about your topology, not a mute switch: if a second replica",
|
|
724
727
|
"ever announces itself, the plugin logs that the claim was contradicted."
|
|
725
|
-
].join("\n"),
|
|
728
|
+
].join("\n"), ye = [
|
|
726
729
|
"plugin-search is running the in-memory backend in production under",
|
|
727
730
|
"`singleProcessMemoryIndex: true`. Holding you to the two conditions that makes true:",
|
|
728
731
|
"exactly ONE process serves search, and it re-seeds every index at startup",
|
|
729
732
|
"(`backfillIndex`) — the index is empty after each restart until it does."
|
|
730
|
-
].join(" "),
|
|
733
|
+
].join(" "), be = (e) => e.backendKind !== "memory" || !e.production ? { level: "quiet" } : e.singleProcessDeclared ? {
|
|
731
734
|
level: "note",
|
|
732
|
-
message:
|
|
735
|
+
message: ye
|
|
733
736
|
} : {
|
|
734
737
|
level: "refuse",
|
|
735
|
-
message:
|
|
736
|
-
}, xe = (e, t) => t ? `search: replica "${e}" joined, but this app declared \`singleProcessMemoryIndex: true\`. That declaration is now false: each replica has its own in-memory index, so search results depend on which one serves the request. Configure a durable backend (typesense / meilisearch / algolia) or run one process.` : `search: replica "${e}" joined while search is served from an in-memory index. Each replica indexes only its OWN writes, so results depend on which replica answers. Configure a durable backend (typesense / meilisearch / algolia) before relying on these results.`,
|
|
737
|
-
id:
|
|
738
|
-
indexName:
|
|
739
|
-
sourceTable:
|
|
740
|
-
rowId:
|
|
741
|
-
docId:
|
|
742
|
-
op:
|
|
743
|
-
attempts:
|
|
744
|
-
lastError:
|
|
745
|
-
firstFailedAt:
|
|
746
|
-
lastFailedAt:
|
|
738
|
+
message: ve
|
|
739
|
+
}, xe = (e, t) => t ? `search: replica "${e}" joined, but this app declared \`singleProcessMemoryIndex: true\`. That declaration is now false: each replica has its own in-memory index, so search results depend on which one serves the request. Configure a durable backend (typesense / meilisearch / algolia) or run one process.` : `search: replica "${e}" joined while search is served from an in-memory index. Each replica indexes only its OWN writes, so results depend on which replica answers. Configure a durable backend (typesense / meilisearch / algolia) before relying on these results.`, J = "_voltro_search_drift", Se = v(J, {
|
|
740
|
+
id: g({ prefix: "sdrft" }),
|
|
741
|
+
indexName: y().maxLength(191),
|
|
742
|
+
sourceTable: y().maxLength(191),
|
|
743
|
+
rowId: y().maxLength(191),
|
|
744
|
+
docId: y().maxLength(191),
|
|
745
|
+
op: y().maxLength(16),
|
|
746
|
+
attempts: _().default(0),
|
|
747
|
+
lastError: y().maxLength(1e3),
|
|
748
|
+
firstFailedAt: b(),
|
|
749
|
+
lastFailedAt: b()
|
|
747
750
|
}).unique("bySearchDriftIndexRow", ["indexName", "rowId"]).index("bySearchDriftIndex", ["indexName"]), Ce = (e, t) => ({
|
|
748
751
|
table: e,
|
|
749
|
-
predicate:
|
|
752
|
+
predicate: h("id", t),
|
|
750
753
|
order: [],
|
|
751
754
|
take: 1,
|
|
752
755
|
skip: void 0,
|
|
753
756
|
projection: void 0
|
|
754
|
-
}),
|
|
757
|
+
}), Y = (e) => e ? new Date(e).toISOString() : (/* @__PURE__ */ new Date(0)).toISOString(), we = (e) => ({
|
|
755
758
|
indexName: String(e.indexName),
|
|
756
759
|
sourceTable: String(e.sourceTable),
|
|
757
760
|
rowId: String(e.rowId),
|
|
@@ -759,8 +762,8 @@ var C = /^[A-Za-z_][A-Za-z0-9_.]*$/, w = (e) => C.test(e), re = (e, t) => {
|
|
|
759
762
|
op: e.op === "remove" ? "remove" : "upsert",
|
|
760
763
|
attempts: Number(e.attempts ?? 0),
|
|
761
764
|
lastError: String(e.lastError ?? ""),
|
|
762
|
-
firstFailedAt:
|
|
763
|
-
lastFailedAt:
|
|
765
|
+
firstFailedAt: Y(e.firstFailedAt),
|
|
766
|
+
lastFailedAt: Y(e.lastFailedAt)
|
|
764
767
|
}), Te = () => {
|
|
765
768
|
let e = /* @__PURE__ */ new Map(), t = (e, t) => `${e}\u0000${t}`;
|
|
766
769
|
return {
|
|
@@ -791,8 +794,8 @@ var C = /^[A-Za-z_][A-Za-z0-9_.]*$/, w = (e) => C.test(e), re = (e, t) => {
|
|
|
791
794
|
e.delete(t(n, r));
|
|
792
795
|
}
|
|
793
796
|
};
|
|
794
|
-
}, Ee = () => `sdrft_${Math.random().toString(36).slice(2)}${Date.now().toString(36)}`,
|
|
795
|
-
table:
|
|
797
|
+
}, Ee = () => `sdrft_${Math.random().toString(36).slice(2)}${Date.now().toString(36)}`, X = (e, t) => ({
|
|
798
|
+
table: J,
|
|
796
799
|
predicate: e,
|
|
797
800
|
order: [{
|
|
798
801
|
column: "firstFailedAt",
|
|
@@ -803,7 +806,7 @@ var C = /^[A-Za-z_][A-Za-z0-9_.]*$/, w = (e) => C.test(e), re = (e, t) => {
|
|
|
803
806
|
projection: void 0
|
|
804
807
|
}), De = (e) => ({
|
|
805
808
|
record: async (t) => {
|
|
806
|
-
let n = /* @__PURE__ */ new Date(), r = Ee(), i = await e.insertIgnore(
|
|
809
|
+
let n = /* @__PURE__ */ new Date(), r = Ee(), i = await e.insertIgnore(J, {
|
|
807
810
|
id: r,
|
|
808
811
|
indexName: t.indexName,
|
|
809
812
|
sourceTable: t.sourceTable,
|
|
@@ -815,27 +818,27 @@ var C = /^[A-Za-z_][A-Za-z0-9_.]*$/, w = (e) => C.test(e), re = (e, t) => {
|
|
|
815
818
|
firstFailedAt: n,
|
|
816
819
|
lastFailedAt: n
|
|
817
820
|
}, { conflictColumns: ["indexName", "rowId"] });
|
|
818
|
-
String(i.id) !== r && await e.updateMany(
|
|
821
|
+
String(i.id) !== r && await e.updateMany(J, {
|
|
819
822
|
attempts: Number(i.attempts ?? 0) + 1,
|
|
820
823
|
op: t.op,
|
|
821
824
|
docId: t.docId,
|
|
822
825
|
lastError: t.error.slice(0, 1e3),
|
|
823
826
|
lastFailedAt: n
|
|
824
|
-
}, { where:
|
|
827
|
+
}, { where: h("id", String(i.id)) });
|
|
825
828
|
},
|
|
826
|
-
list: async (t) => (await e.query(
|
|
829
|
+
list: async (t) => (await e.query(X(void 0, t))).map(we),
|
|
827
830
|
summary: async (t) => {
|
|
828
831
|
let n = (await e.query({
|
|
829
|
-
...
|
|
832
|
+
...X(h("indexName", t), void 0),
|
|
830
833
|
order: [],
|
|
831
|
-
aggregations: [
|
|
834
|
+
aggregations: [m("n")]
|
|
832
835
|
}))[0], r = Number(n?.n ?? n?.count ?? 0);
|
|
833
836
|
if (r === 0) return {
|
|
834
837
|
pending: 0,
|
|
835
838
|
lastFailedAt: null
|
|
836
839
|
};
|
|
837
840
|
let i = await e.query({
|
|
838
|
-
...
|
|
841
|
+
...X(h("indexName", t), 1),
|
|
839
842
|
order: [{
|
|
840
843
|
column: "lastFailedAt",
|
|
841
844
|
direction: "desc"
|
|
@@ -843,17 +846,17 @@ var C = /^[A-Za-z_][A-Za-z0-9_.]*$/, w = (e) => C.test(e), re = (e, t) => {
|
|
|
843
846
|
});
|
|
844
847
|
return {
|
|
845
848
|
pending: r,
|
|
846
|
-
lastFailedAt: i[0] ?
|
|
849
|
+
lastFailedAt: i[0] ? Y(i[0].lastFailedAt) : null
|
|
847
850
|
};
|
|
848
851
|
},
|
|
849
852
|
clear: async (t, n) => {
|
|
850
|
-
await e.deleteMany(
|
|
853
|
+
await e.deleteMany(J, { where: p(h("indexName", t), h("rowId", n)) });
|
|
851
854
|
}
|
|
852
855
|
}), Oe = () => [Se], ke = (e, t) => {
|
|
853
|
-
if (e === void 0 || e === "memory") return
|
|
856
|
+
if (e === void 0 || e === "memory") return j();
|
|
854
857
|
if (typeof e.query == "function") return e;
|
|
855
858
|
let n = e;
|
|
856
|
-
return n.engine === "typesense" ?
|
|
859
|
+
return n.engine === "typesense" ? oe(n, t) : n.engine === "meilisearch" ? I(n, t) : n.engine === "algolia" ? L(n, t) : j();
|
|
857
860
|
}, Ae = async (e, t, n) => {
|
|
858
861
|
let r = n.map((e) => t.map(e));
|
|
859
862
|
return r.length > 0 && await e.upsert(t.index, r), r.length;
|
|
@@ -864,7 +867,7 @@ var C = /^[A-Za-z_][A-Za-z0-9_.]*$/, w = (e) => C.test(e), re = (e, t) => {
|
|
|
864
867
|
return;
|
|
865
868
|
}
|
|
866
869
|
n.new && await e.upsert(t.index, [t.map(n.new)]);
|
|
867
|
-
},
|
|
870
|
+
}, Z = {
|
|
868
871
|
retries: 5,
|
|
869
872
|
retryBaseDelayMs: 200,
|
|
870
873
|
retryMaxDelayMs: 1e4,
|
|
@@ -873,21 +876,21 @@ var C = /^[A-Za-z_][A-Za-z0-9_.]*$/, w = (e) => C.test(e), re = (e, t) => {
|
|
|
873
876
|
reindexBatchSize: 1e3,
|
|
874
877
|
statsFlushIntervalMs: 5e3,
|
|
875
878
|
statsFlushMaxBuffered: 1e3
|
|
876
|
-
},
|
|
877
|
-
retries: Math.max(0, e?.retries ??
|
|
878
|
-
retryBaseDelayMs: Math.max(1, e?.retryBaseDelayMs ??
|
|
879
|
-
retryMaxDelayMs: Math.max(1, e?.retryMaxDelayMs ??
|
|
880
|
-
resyncIntervalMs: Math.max(0, e?.resyncIntervalMs ??
|
|
881
|
-
resyncBatchSize: Math.max(1, e?.resyncBatchSize ??
|
|
882
|
-
reindexBatchSize: Math.max(1, e?.reindexBatchSize ??
|
|
883
|
-
statsFlushIntervalMs: Math.max(0, e?.statsFlushIntervalMs ??
|
|
884
|
-
statsFlushMaxBuffered: Math.max(1, e?.statsFlushMaxBuffered ??
|
|
885
|
-
}),
|
|
879
|
+
}, Q = (e) => ({
|
|
880
|
+
retries: Math.max(0, e?.retries ?? Z.retries),
|
|
881
|
+
retryBaseDelayMs: Math.max(1, e?.retryBaseDelayMs ?? Z.retryBaseDelayMs),
|
|
882
|
+
retryMaxDelayMs: Math.max(1, e?.retryMaxDelayMs ?? Z.retryMaxDelayMs),
|
|
883
|
+
resyncIntervalMs: Math.max(0, e?.resyncIntervalMs ?? Z.resyncIntervalMs),
|
|
884
|
+
resyncBatchSize: Math.max(1, e?.resyncBatchSize ?? Z.resyncBatchSize),
|
|
885
|
+
reindexBatchSize: Math.max(1, e?.reindexBatchSize ?? Z.reindexBatchSize),
|
|
886
|
+
statsFlushIntervalMs: Math.max(0, e?.statsFlushIntervalMs ?? Z.statsFlushIntervalMs),
|
|
887
|
+
statsFlushMaxBuffered: Math.max(1, e?.statsFlushMaxBuffered ?? Z.statsFlushMaxBuffered)
|
|
888
|
+
}), Me = (e) => e instanceof D ? e : new D({
|
|
886
889
|
engine: "unknown",
|
|
887
890
|
op: "upsert",
|
|
888
891
|
message: String(e?.message ?? e),
|
|
889
892
|
transient: !1
|
|
890
|
-
}),
|
|
893
|
+
}), Ne = (e) => d.max([d.min([d.exponential(s.millis(e.retryBaseDelayMs), 2), d.spaced(s.millis(e.retryMaxDelayMs))]), d.recurs(e.retries)]).pipe(d.while(({ input: e }) => e.transient)), Pe = (e) => {
|
|
891
894
|
if (!e || e === "memory" || typeof e.query == "function") return;
|
|
892
895
|
let t = e;
|
|
893
896
|
try {
|
|
@@ -895,7 +898,7 @@ var C = /^[A-Za-z_][A-Za-z0-9_.]*$/, w = (e) => C.test(e), re = (e, t) => {
|
|
|
895
898
|
} catch {
|
|
896
899
|
return;
|
|
897
900
|
}
|
|
898
|
-
},
|
|
901
|
+
}, Fe = (e, t, n) => {
|
|
899
902
|
let r = n ?? [];
|
|
900
903
|
return e ? t == null ? null : [...r, {
|
|
901
904
|
field: e,
|
|
@@ -906,69 +909,69 @@ var C = /^[A-Za-z_][A-Za-z0-9_.]*$/, w = (e) => C.test(e), re = (e, t) => {
|
|
|
906
909
|
...(e.filters ?? []).map((e) => ["filter", e.field]),
|
|
907
910
|
...(e.facets ?? []).map((e) => ["facet", e]),
|
|
908
911
|
...(e.highlight?.fields ?? []).map((e) => ["highlight", e])
|
|
909
|
-
],
|
|
910
|
-
let
|
|
911
|
-
base:
|
|
912
|
+
], $ = i, Le = (i) => {
|
|
913
|
+
let o = ne({
|
|
914
|
+
base: $,
|
|
912
915
|
alias: i.alias,
|
|
913
916
|
instance: i.name
|
|
914
|
-
}),
|
|
917
|
+
}), s = () => void 0, d = () => void 0, p = Q(i.sync), m = Ne(p), h = ke(i.backend, {
|
|
915
918
|
...i.allowedEngineParams ? { allowEngineParams: i.allowedEngineParams } : {},
|
|
916
|
-
onWarn: (e, t) =>
|
|
917
|
-
}),
|
|
918
|
-
for (let e of Object.values(i.indexes))
|
|
919
|
-
let
|
|
919
|
+
onWarn: (e, t) => s(e, t)
|
|
920
|
+
}), g = /* @__PURE__ */ new Map();
|
|
921
|
+
for (let e of Object.values(i.indexes)) g.set(e.index, e);
|
|
922
|
+
let _ = ge(i.backend), v = i.singleProcessMemoryIndex === !0, y = !1, b, re = {
|
|
920
923
|
...r,
|
|
921
924
|
description: "Full-text search an index (facets/highlight/fuzzy/filters), auto-scoped to the caller tenant.",
|
|
922
925
|
execute: (t, r) => {
|
|
923
|
-
let { index: i, q: a, limit: o, offset: s, filters:
|
|
924
|
-
if (!m) return
|
|
925
|
-
let
|
|
926
|
-
...
|
|
926
|
+
let { index: i, q: a, limit: o, offset: s, filters: l, facets: u, highlight: d, fuzziness: f, engineParams: p } = t, m = g.get(i);
|
|
927
|
+
if (!m) return c.fail(new n({ index: i }));
|
|
928
|
+
let _ = ie(Ie({
|
|
929
|
+
...l ? { filters: l } : {},
|
|
927
930
|
...u ? { facets: u } : {},
|
|
928
931
|
...d ? { highlight: d } : {}
|
|
929
932
|
}), m.queryableFields);
|
|
930
|
-
if (
|
|
931
|
-
let
|
|
932
|
-
if (
|
|
933
|
+
if (_) return c.fail(new e(_));
|
|
934
|
+
let ee = r.request.subject.tenantId ?? null, v = Fe(m.tenantField, ee, l);
|
|
935
|
+
if (v === null) return c.succeed({
|
|
933
936
|
hits: [],
|
|
934
937
|
facets: {}
|
|
935
938
|
});
|
|
936
|
-
let
|
|
939
|
+
let y = {
|
|
937
940
|
q: a,
|
|
938
941
|
...o === void 0 ? {} : { limit: o },
|
|
939
942
|
...s === void 0 ? {} : { offset: s },
|
|
940
|
-
...
|
|
943
|
+
...v.length > 0 ? { filters: v } : {},
|
|
941
944
|
...u && u.length > 0 ? { facets: u } : {},
|
|
942
945
|
...d ? { highlight: d } : {},
|
|
943
946
|
...f === void 0 ? {} : { fuzziness: f },
|
|
944
947
|
...p ? { engineParams: p } : {}
|
|
945
948
|
};
|
|
946
|
-
return
|
|
949
|
+
return c.promise(() => h.query(i, y));
|
|
947
950
|
}
|
|
948
|
-
},
|
|
951
|
+
}, x = Pe(i.backend), S = [
|
|
949
952
|
"store:changes:read",
|
|
950
953
|
"store:write",
|
|
951
954
|
"inspect:read",
|
|
952
955
|
"inspect:write",
|
|
953
|
-
...
|
|
954
|
-
],
|
|
956
|
+
...x ? [`network:outbound:${x}`] : []
|
|
957
|
+
], C = H(), w = Te(), T, E, D, O, k = (e, t, n) => O === void 0 ? c.tryPromise(() => C.bump(e, t, n)).pipe(c.catch((n) => c.sync(() => s("search stats bump failed", {
|
|
955
958
|
index: e,
|
|
956
959
|
kind: t,
|
|
957
960
|
error: String(n)
|
|
958
|
-
})))) :
|
|
959
|
-
let t = await
|
|
961
|
+
})))) : c.sync(() => O.bump(e, t, n)), A = async (e) => {
|
|
962
|
+
let t = await w.list(e), n = 0, r = 0;
|
|
960
963
|
for (let e of t) {
|
|
961
|
-
let t =
|
|
964
|
+
let t = g.get(e.indexName);
|
|
962
965
|
if (!t) {
|
|
963
|
-
await
|
|
966
|
+
await w.clear(e.indexName, e.rowId);
|
|
964
967
|
continue;
|
|
965
968
|
}
|
|
966
969
|
try {
|
|
967
|
-
if (!
|
|
968
|
-
let r = (await
|
|
969
|
-
r ? await
|
|
970
|
+
if (!E) throw Error("data store not bound");
|
|
971
|
+
let r = (await E.query(Ce(e.sourceTable, e.rowId)))[0];
|
|
972
|
+
r ? await h.upsert(t.index, [t.map(r)]) : await h.remove(t.index, [e.docId]), await w.clear(e.indexName, e.rowId), n++;
|
|
970
973
|
} catch (t) {
|
|
971
|
-
r++, await
|
|
974
|
+
r++, await w.record({
|
|
972
975
|
...e,
|
|
973
976
|
error: String(t?.message ?? t)
|
|
974
977
|
}).catch(() => void 0);
|
|
@@ -979,20 +982,20 @@ var C = /^[A-Za-z_][A-Za-z0-9_.]*$/, w = (e) => C.test(e), re = (e, t) => {
|
|
|
979
982
|
repaired: n,
|
|
980
983
|
failed: r
|
|
981
984
|
};
|
|
982
|
-
},
|
|
985
|
+
}, j = (e) => ({
|
|
983
986
|
kind: "json",
|
|
984
987
|
data: e
|
|
985
|
-
}),
|
|
988
|
+
}), M = (e, t) => ({
|
|
986
989
|
kind: "json",
|
|
987
990
|
status: e,
|
|
988
991
|
data: { error: t }
|
|
989
992
|
});
|
|
990
|
-
return
|
|
991
|
-
name:
|
|
992
|
-
baseName:
|
|
993
|
+
return te({
|
|
994
|
+
name: o,
|
|
995
|
+
baseName: $,
|
|
993
996
|
description: "External search index sync (Typesense/Meilisearch/Algolia/memory) via the ChangeEvent tap + a tenant-scoped query route.",
|
|
994
|
-
permissions:
|
|
995
|
-
routes: [
|
|
997
|
+
permissions: S,
|
|
998
|
+
routes: [re],
|
|
996
999
|
rpcClientDescriptors: t,
|
|
997
1000
|
inspectEndpoints: [
|
|
998
1001
|
{
|
|
@@ -1000,10 +1003,10 @@ var C = /^[A-Za-z_][A-Za-z0-9_.]*$/, w = (e) => C.test(e), re = (e, t) => {
|
|
|
1000
1003
|
path: "/indexes",
|
|
1001
1004
|
scope: "process",
|
|
1002
1005
|
description: "Configured indexes + durable, cross-replica sync stats + current index drift.",
|
|
1003
|
-
handler: () =>
|
|
1004
|
-
await
|
|
1006
|
+
handler: () => c.promise(async () => {
|
|
1007
|
+
await O?.flushNow();
|
|
1005
1008
|
let e = await Promise.all(Object.entries(i.indexes).map(async ([e, t]) => {
|
|
1006
|
-
let n = await
|
|
1009
|
+
let n = await C.get(t.index), r = await w.summary(t.index);
|
|
1007
1010
|
return {
|
|
1008
1011
|
table: e,
|
|
1009
1012
|
index: t.index,
|
|
@@ -1014,15 +1017,15 @@ var C = /^[A-Za-z_][A-Za-z0-9_.]*$/, w = (e) => C.test(e), re = (e, t) => {
|
|
|
1014
1017
|
drifted: r.pending > 0
|
|
1015
1018
|
};
|
|
1016
1019
|
}));
|
|
1017
|
-
return
|
|
1020
|
+
return j({
|
|
1018
1021
|
indexes: e,
|
|
1019
1022
|
backend: typeof i.backend == "string" ? i.backend : i.backend ? "custom/vendor" : "memory",
|
|
1020
|
-
durable:
|
|
1021
|
-
singleProcessMemoryIndex:
|
|
1023
|
+
durable: _ !== "memory",
|
|
1024
|
+
singleProcessMemoryIndex: v,
|
|
1022
1025
|
pendingDrift: e.reduce((e, t) => e + t.pendingDrift, 0),
|
|
1023
1026
|
sync: {
|
|
1024
|
-
...
|
|
1025
|
-
resyncArmed:
|
|
1027
|
+
...p,
|
|
1028
|
+
resyncArmed: T !== void 0
|
|
1026
1029
|
}
|
|
1027
1030
|
});
|
|
1028
1031
|
})
|
|
@@ -1032,34 +1035,34 @@ var C = /^[A-Za-z_][A-Za-z0-9_.]*$/, w = (e) => C.test(e), re = (e, t) => {
|
|
|
1032
1035
|
path: "/drift",
|
|
1033
1036
|
scope: "process",
|
|
1034
1037
|
description: "The changes that did NOT reach the engine, oldest first (the repair queue).",
|
|
1035
|
-
handler: (e) =>
|
|
1036
|
-
let t = Number(new URL(e.url, "http://localhost").searchParams.get("limit") ?? 100), n = await
|
|
1037
|
-
return
|
|
1038
|
+
handler: (e) => c.promise(async () => {
|
|
1039
|
+
let t = Number(new URL(e.url, "http://localhost").searchParams.get("limit") ?? 100), n = await w.list(Number.isFinite(t) && t > 0 ? Math.min(t, 1e3) : 100);
|
|
1040
|
+
return j({ entries: n });
|
|
1038
1041
|
})
|
|
1039
1042
|
},
|
|
1040
1043
|
{
|
|
1041
1044
|
method: "POST",
|
|
1042
1045
|
path: "/resync",
|
|
1043
1046
|
description: "Repair drifted rows now — re-reads each from the DB and re-applies it.",
|
|
1044
|
-
handler: (e) =>
|
|
1047
|
+
handler: (e) => c.promise(async () => {
|
|
1045
1048
|
let t;
|
|
1046
1049
|
try {
|
|
1047
1050
|
t = JSON.parse(e.body || "{}");
|
|
1048
1051
|
} catch {
|
|
1049
|
-
return
|
|
1052
|
+
return M(400, "invalid JSON body");
|
|
1050
1053
|
}
|
|
1051
|
-
if (typeof t != "object" || !t || Array.isArray(t)) return
|
|
1052
|
-
let n = "limit" in t ? t.limit :
|
|
1053
|
-
if (typeof n != "number" || !Number.isSafeInteger(n) || n < 1) return
|
|
1054
|
-
if (!
|
|
1054
|
+
if (typeof t != "object" || !t || Array.isArray(t)) return M(400, "expected a JSON object");
|
|
1055
|
+
let n = "limit" in t ? t.limit : p.resyncBatchSize;
|
|
1056
|
+
if (typeof n != "number" || !Number.isSafeInteger(n) || n < 1) return M(400, "limit must be a positive integer");
|
|
1057
|
+
if (!E) return M(503, "data store not bound yet");
|
|
1055
1058
|
try {
|
|
1056
|
-
let e = await
|
|
1057
|
-
return
|
|
1059
|
+
let e = await A(Math.min(n, 1e3));
|
|
1060
|
+
return j({
|
|
1058
1061
|
ok: !0,
|
|
1059
1062
|
...e
|
|
1060
1063
|
});
|
|
1061
1064
|
} catch (e) {
|
|
1062
|
-
return
|
|
1065
|
+
return M(500, e.message);
|
|
1063
1066
|
}
|
|
1064
1067
|
})
|
|
1065
1068
|
},
|
|
@@ -1067,64 +1070,64 @@ var C = /^[A-Za-z_][A-Za-z0-9_.]*$/, w = (e) => C.test(e), re = (e, t) => {
|
|
|
1067
1070
|
method: "POST",
|
|
1068
1071
|
path: "/reindex",
|
|
1069
1072
|
description: "Re-seed an index from the table's current rows (streamed in bounded batches).",
|
|
1070
|
-
handler: (e) =>
|
|
1073
|
+
handler: (e) => c.promise(async () => {
|
|
1071
1074
|
let t;
|
|
1072
1075
|
try {
|
|
1073
1076
|
t = JSON.parse(e.body || "{}");
|
|
1074
1077
|
} catch {
|
|
1075
|
-
return
|
|
1078
|
+
return M(400, "invalid JSON body");
|
|
1076
1079
|
}
|
|
1077
|
-
if (typeof t != "object" || !t || Array.isArray(t)) return
|
|
1080
|
+
if (typeof t != "object" || !t || Array.isArray(t)) return M(400, "expected a JSON object");
|
|
1078
1081
|
let n = "table" in t ? t.table : void 0;
|
|
1079
|
-
if (typeof n != "string" || n.trim() === "") return
|
|
1082
|
+
if (typeof n != "string" || n.trim() === "") return M(400, "table must be a non-empty string");
|
|
1080
1083
|
let r = Object.hasOwn(i.indexes, n) ? i.indexes[n] : void 0;
|
|
1081
|
-
if (!r) return
|
|
1082
|
-
if (!
|
|
1083
|
-
let
|
|
1084
|
+
if (!r) return M(404, `no index configured for table "${n}"`);
|
|
1085
|
+
if (!D) return M(503, "data store not bound yet");
|
|
1086
|
+
let o = 0, s = await c.runPromiseExit(ee(D, {
|
|
1084
1087
|
table: n,
|
|
1085
|
-
chunkSize:
|
|
1086
|
-
}).pipe(
|
|
1087
|
-
|
|
1088
|
+
chunkSize: p.reindexBatchSize
|
|
1089
|
+
}).pipe(f.chunks, f.runForEach((e) => c.tryPromise(async () => {
|
|
1090
|
+
o += await Ae(h, r, e);
|
|
1088
1091
|
}))));
|
|
1089
|
-
if (
|
|
1090
|
-
let e = a.
|
|
1091
|
-
return
|
|
1092
|
+
if (l.isFailure(s)) {
|
|
1093
|
+
let e = a.findErrorOption(s.cause), t = u.isSome(e) ? e.value : s.cause, n = t.cause ?? t.error ?? t;
|
|
1094
|
+
return M(500, String(n?.message ?? n));
|
|
1092
1095
|
}
|
|
1093
1096
|
try {
|
|
1094
|
-
await
|
|
1097
|
+
await C.recordReindex(r.index, o, (/* @__PURE__ */ new Date()).toISOString());
|
|
1095
1098
|
} catch (e) {
|
|
1096
|
-
return
|
|
1099
|
+
return M(500, e.message);
|
|
1097
1100
|
}
|
|
1098
|
-
return
|
|
1101
|
+
return j({
|
|
1099
1102
|
ok: !0,
|
|
1100
1103
|
table: n,
|
|
1101
1104
|
index: r.index,
|
|
1102
|
-
count:
|
|
1105
|
+
count: o
|
|
1103
1106
|
});
|
|
1104
1107
|
})
|
|
1105
1108
|
}
|
|
1106
1109
|
],
|
|
1107
|
-
extendSchema: { tables: [...
|
|
1110
|
+
extendSchema: { tables: [...V(), ...Oe()] },
|
|
1108
1111
|
bindDataStore: (e, t) => {
|
|
1109
|
-
|
|
1110
|
-
e.kind === "left" ||
|
|
1112
|
+
E = e, D = e, C = G(e, ...t?.instanceId === void 0 ? [] : [t.instanceId]), w = De(e), _ === "memory" && t?.membership !== void 0 && (b = t.membership.onChange((e) => {
|
|
1113
|
+
e.kind === "left" || y || (t.instanceId === void 0 || e.instanceId !== t.instanceId) && (y = !0, s(xe(e.instanceId, v), {
|
|
1111
1114
|
instanceId: t.instanceId ?? null,
|
|
1112
1115
|
peer: e.instanceId,
|
|
1113
1116
|
indexes: Object.keys(i.indexes)
|
|
1114
1117
|
}));
|
|
1115
|
-
})), !(
|
|
1118
|
+
})), !(p.resyncIntervalMs <= 0 || t?.scheduleCoordinated === void 0) && (T = t.scheduleCoordinated("search.resync", p.resyncIntervalMs, async () => {
|
|
1116
1119
|
try {
|
|
1117
|
-
let e = await
|
|
1118
|
-
return (e.repaired > 0 || e.failed > 0) &&
|
|
1120
|
+
let e = await A(p.resyncBatchSize);
|
|
1121
|
+
return (e.repaired > 0 || e.failed > 0) && d("search: drift repair pass", e), { idle: e.scanned === 0 };
|
|
1119
1122
|
} catch (e) {
|
|
1120
|
-
return
|
|
1123
|
+
return s("search: drift repair pass failed", { error: String(e?.message ?? e) }), { idle: !1 };
|
|
1121
1124
|
}
|
|
1122
1125
|
}));
|
|
1123
1126
|
},
|
|
1124
1127
|
onChangeEvent: (e) => {
|
|
1125
1128
|
let t = i.indexes[e.table];
|
|
1126
|
-
if (!t) return
|
|
1127
|
-
let n = e.changeScope, r = e.changeScope === "fleet" || e.origin !== "injected", a = e.op === "delete" ? e.old : e.new, o = typeof a?.id == "string" ? a.id : "",
|
|
1129
|
+
if (!t) return c.void;
|
|
1130
|
+
let n = e.changeScope, r = e.changeScope === "fleet" || e.origin !== "injected", a = e.op === "delete" ? e.old : e.new, o = typeof a?.id == "string" ? a.id : "", l = e.op === "delete" ? "remove" : "upsert", u = () => {
|
|
1128
1131
|
if (e.op === "delete" || !e.new) return o;
|
|
1129
1132
|
try {
|
|
1130
1133
|
return String(t.map(e.new).id ?? o);
|
|
@@ -1132,11 +1135,11 @@ var C = /^[A-Za-z_][A-Za-z0-9_.]*$/, w = (e) => C.test(e), re = (e, t) => {
|
|
|
1132
1135
|
return o;
|
|
1133
1136
|
}
|
|
1134
1137
|
};
|
|
1135
|
-
return
|
|
1136
|
-
try: () => je(
|
|
1137
|
-
catch:
|
|
1138
|
-
}).pipe(
|
|
1139
|
-
onSuccess: () => r ?
|
|
1138
|
+
return c.tryPromise({
|
|
1139
|
+
try: () => je(h, t, e),
|
|
1140
|
+
catch: Me
|
|
1141
|
+
}).pipe(c.retry(m)).pipe(c.matchEffect({
|
|
1142
|
+
onSuccess: () => r ? k(t.index, e.op === "delete" ? "removed" : "synced", n) : c.void,
|
|
1140
1143
|
onFailure: (r) => {
|
|
1141
1144
|
let i = {
|
|
1142
1145
|
table: e.table,
|
|
@@ -1146,49 +1149,49 @@ var C = /^[A-Za-z_][A-Za-z0-9_.]*$/, w = (e) => C.test(e), re = (e, t) => {
|
|
|
1146
1149
|
transient: r.transient,
|
|
1147
1150
|
error: r.message
|
|
1148
1151
|
};
|
|
1149
|
-
return o === "" ?
|
|
1152
|
+
return o === "" ? c.sync(() => s("search: change not indexed and NOT recoverable (row has no id)", i)).pipe(c.andThen(c.fail(r))) : c.tryPromise(() => w.record({
|
|
1150
1153
|
indexName: t.index,
|
|
1151
1154
|
sourceTable: e.table,
|
|
1152
1155
|
rowId: o,
|
|
1153
1156
|
docId: u(),
|
|
1154
|
-
op:
|
|
1157
|
+
op: l,
|
|
1155
1158
|
error: r.message
|
|
1156
|
-
})).pipe(
|
|
1157
|
-
onSuccess: () =>
|
|
1158
|
-
onFailure: (e) =>
|
|
1159
|
+
})).pipe(c.matchEffect({
|
|
1160
|
+
onSuccess: () => k(t.index, "dropped", n).pipe(c.andThen(c.sync(() => s("search: index drift recorded — will be repaired from the database", i)))),
|
|
1161
|
+
onFailure: (e) => c.sync(() => s("search: change LOST — engine failed and the drift ledger could not record it", {
|
|
1159
1162
|
...i,
|
|
1160
1163
|
ledgerError: String(e)
|
|
1161
|
-
})).pipe(
|
|
1164
|
+
})).pipe(c.andThen(c.fail(r)))
|
|
1162
1165
|
}));
|
|
1163
1166
|
}
|
|
1164
1167
|
}));
|
|
1165
1168
|
},
|
|
1166
|
-
onActivate: (e) =>
|
|
1167
|
-
|
|
1168
|
-
let t =
|
|
1169
|
-
backendKind:
|
|
1169
|
+
onActivate: (e) => c.suspend(() => {
|
|
1170
|
+
s = (t, n) => e.logger.warn(t, n), d = (t, n) => e.logger.info(t, n);
|
|
1171
|
+
let t = be({
|
|
1172
|
+
backendKind: _,
|
|
1170
1173
|
production: (e.env?.NODE_ENV ?? process.env.NODE_ENV) === "production",
|
|
1171
|
-
singleProcessDeclared:
|
|
1174
|
+
singleProcessDeclared: v
|
|
1172
1175
|
});
|
|
1173
|
-
return t.level === "refuse" ?
|
|
1174
|
-
flush:
|
|
1175
|
-
intervalMs:
|
|
1176
|
-
maxBuffered:
|
|
1177
|
-
})),
|
|
1176
|
+
return t.level === "refuse" ? c.fail(new _e(t.message)) : (t.level === "note" && e.logger.info(t.message, { indexes: Object.keys(i.indexes) }), p.statsFlushIntervalMs > 0 && O === void 0 && (O = K({
|
|
1177
|
+
flush: q(() => C),
|
|
1178
|
+
intervalMs: p.statsFlushIntervalMs,
|
|
1179
|
+
maxBuffered: p.statsFlushMaxBuffered
|
|
1180
|
+
})), c.sync(() => {
|
|
1178
1181
|
e.logger.info("search active", {
|
|
1179
1182
|
indexes: Object.keys(i.indexes),
|
|
1180
1183
|
backend: typeof i.backend == "string" ? i.backend : "custom/vendor",
|
|
1181
|
-
durable:
|
|
1182
|
-
sync:
|
|
1184
|
+
durable: _ !== "memory",
|
|
1185
|
+
sync: p
|
|
1183
1186
|
});
|
|
1184
1187
|
}));
|
|
1185
1188
|
}),
|
|
1186
|
-
onDeactivate: () =>
|
|
1187
|
-
|
|
1188
|
-
let e =
|
|
1189
|
-
|
|
1189
|
+
onDeactivate: () => c.promise(async () => {
|
|
1190
|
+
T?.stop(), T = void 0, b?.(), b = void 0, y = !1;
|
|
1191
|
+
let e = O;
|
|
1192
|
+
O = void 0, await e?.shutdown();
|
|
1190
1193
|
})
|
|
1191
1194
|
});
|
|
1192
1195
|
};
|
|
1193
1196
|
//#endregion
|
|
1194
|
-
export {
|
|
1197
|
+
export { x as FIELD_NAME_PATTERN, J as SEARCH_DRIFT_TABLE, R as SEARCH_STATS_TABLE, Z as SYNC_DEFAULTS, D as SearchBackendError, _e as SearchBackendNotDurable, e as SearchFieldRejected, n as SearchIndexNotFound, L as algoliaBackend, E as allowedEngineParams, je as applyChange, Me as asBackendError, be as auditMemoryBackend, ge as backendKindOf, Ae as backfillIndex, De as dataStoreDriftLedger, G as dataStoreStatsStore, Ce as driftSourceQuery, Oe as driftTables, S as isSafeFieldName, K as makeSearchStatsBuffer, I as meilisearchBackend, j as memoryBackend, Te as memoryDriftLedger, H as memoryStatsStore, xe as peerObservedWarning, Q as resolveSyncOptions, T as sanitizeEngineParams, Fe as scopeSearchFilters, Se as searchDriftTable, Le as searchPlugin, B as searchStatsTable, V as searchTables, q as statsStoreFlush, Ne as syncRetrySchedule, oe as typesenseBackend };
|