@voltro/plugin-search 0.87.0 → 0.89.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 +272 -6
- package/THIRD-PARTY-NOTICES.md +72 -1361
- package/dist/backend.js +1 -2
- package/dist/drift.js +1 -2
- package/dist/errors.js +1 -2
- package/dist/index.js +1 -2
- package/dist/memoryGuard.js +2 -26
- package/dist/rpc.js +1 -2
- package/dist/sanitize.js +1 -2
- package/dist/statsBuffer.js +1 -2
- package/dist/statsStore.js +1 -2
- package/dist/web.js +1 -2
- package/package.json +7 -7
package/dist/backend.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { isSafeFieldName as e, sanitizeEngineParams as t } from "./sanitize.js";
|
|
2
2
|
import { Data as n } from "effect";
|
|
3
|
-
|
|
3
|
+
// src/backend.ts
|
|
4
4
|
var r = class extends n.TaggedError("SearchBackendError") {}, i = (e) => Array.isArray(e) ? e : [e], a = (e, t, n) => {
|
|
5
5
|
if (Math.abs(e.length - t.length) > n) return !1;
|
|
6
6
|
if (e === t) return !0;
|
|
@@ -394,5 +394,4 @@ var r = class extends n.TaggedError("SearchBackendError") {}, i = (e) => Array.i
|
|
|
394
394
|
}),
|
|
395
395
|
facets: e.facets ?? {}
|
|
396
396
|
});
|
|
397
|
-
//#endregion
|
|
398
397
|
export { r as SearchBackendError, x as algoliaBackend, a as editDistanceWithin, g as meilisearchBackend, s as memoryBackend, p as typesenseBackend };
|
package/dist/drift.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
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
|
-
|
|
2
|
+
// src/drift.ts
|
|
3
3
|
var c = "_voltro_search_drift", l = a(c, {
|
|
4
4
|
id: r({ prefix: "sdrft" }),
|
|
5
5
|
indexName: o().maxLength(191),
|
|
@@ -117,5 +117,4 @@ var c = "_voltro_search_drift", l = a(c, {
|
|
|
117
117
|
await r.deleteMany(c, { where: e(n("indexName", t), n("rowId", i)) });
|
|
118
118
|
}
|
|
119
119
|
}), _ = () => [l];
|
|
120
|
-
//#endregion
|
|
121
120
|
export { c as SEARCH_DRIFT_TABLE, g as dataStoreDriftLedger, u as driftSourceQuery, _ as driftTables, p as memoryDriftLedger, l as searchDriftTable };
|
package/dist/errors.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Schema as e } from "effect";
|
|
2
|
-
|
|
2
|
+
// src/errors.ts
|
|
3
3
|
var t = class extends e.TaggedError()("SearchIndexNotFound", { index: e.String }) {}, n = class extends e.TaggedError()("SearchFieldRejected", {
|
|
4
4
|
field: e.String,
|
|
5
5
|
where: e.Literals([
|
|
@@ -9,5 +9,4 @@ var t = class extends e.TaggedError()("SearchIndexNotFound", { index: e.String }
|
|
|
9
9
|
]),
|
|
10
10
|
reason: e.Literals(["not-an-identifier", "not-queryable"])
|
|
11
11
|
}) {};
|
|
12
|
-
//#endregion
|
|
13
12
|
export { n as SearchFieldRejected, t as SearchIndexNotFound };
|
package/dist/index.js
CHANGED
|
@@ -9,7 +9,7 @@ import { SEARCH_DRIFT_TABLE as E, dataStoreDriftLedger as D, driftSourceQuery as
|
|
|
9
9
|
import { Cause as ee, Duration as M, Effect as N, Exit as P, Option as F, Schedule as I, Stream as L } from "effect";
|
|
10
10
|
import { streamTable as te } from "@voltro/database";
|
|
11
11
|
import { definePlugin as ne, pluginInstanceName as re } from "@voltro/protocol";
|
|
12
|
-
|
|
12
|
+
// src/index.ts
|
|
13
13
|
var ie = (e, t) => {
|
|
14
14
|
if (e === void 0 || e === "memory") return p();
|
|
15
15
|
if (typeof e.query == "function") return e;
|
|
@@ -346,5 +346,4 @@ var ie = (e, t) => {
|
|
|
346
346
|
})
|
|
347
347
|
});
|
|
348
348
|
};
|
|
349
|
-
//#endregion
|
|
350
349
|
export { a as FIELD_NAME_PATTERN, E as SEARCH_DRIFT_TABLE, h as SEARCH_STATS_TABLE, B as SYNC_DEFAULTS, u as SearchBackendError, S as SearchBackendNotDurable, e as SearchFieldRejected, t as SearchIndexNotFound, d as algoliaBackend, o as allowedEngineParams, z as applyChange, H as asBackendError, C as auditMemoryBackend, w as backendKindOf, R as backfillIndex, D as dataStoreDriftLedger, g as dataStoreStatsStore, O as driftSourceQuery, k as driftTables, c as isSafeFieldName, b as makeSearchStatsBuffer, f as meilisearchBackend, p as memoryBackend, A as memoryDriftLedger, _ as memoryStatsStore, T as peerObservedWarning, V as resolveSyncOptions, l as sanitizeEngineParams, W as scopeSearchFilters, j as searchDriftTable, K as searchPlugin, v as searchStatsTable, y as searchTables, x as statsStoreFlush, U as syncRetrySchedule, m as typesenseBackend };
|
package/dist/memoryGuard.js
CHANGED
|
@@ -1,38 +1,14 @@
|
|
|
1
|
-
|
|
1
|
+
// src/memoryGuard.ts
|
|
2
2
|
var e = (e) => e === void 0 || e === "memory" ? "memory" : typeof e.query == "function" ? e.engineKind === "memory" ? "memory" : "custom" : "vendor", t = class extends Error {
|
|
3
3
|
_tag = "SearchBackendNotDurable";
|
|
4
4
|
constructor(e) {
|
|
5
5
|
super(e), this.name = "SearchBackendNotDurable";
|
|
6
6
|
}
|
|
7
|
-
}, n =
|
|
8
|
-
"plugin-search refuses to boot in production on the in-memory backend.",
|
|
9
|
-
"",
|
|
10
|
-
"The memory index lives in THIS process's heap. Two consequences, both silent:",
|
|
11
|
-
" • every replica holds a different index, so a result depends on which replica served you;",
|
|
12
|
-
" • the index starts EMPTY after every restart/deploy, and nothing re-seeds it automatically.",
|
|
13
|
-
"",
|
|
14
|
-
"Configure a durable engine in app.config.ts:",
|
|
15
|
-
" searchPlugin({ backend: { engine: 'typesense', url: …, apiKey: … }, indexes })",
|
|
16
|
-
" searchPlugin({ backend: { engine: 'meilisearch', url: …, apiKey: … }, indexes })",
|
|
17
|
-
" searchPlugin({ backend: { engine: 'algolia', appId: …, apiKey: … }, indexes })",
|
|
18
|
-
"or pass your own `SearchBackend` implementation.",
|
|
19
|
-
"",
|
|
20
|
-
"If this deployment really is ONE process that re-seeds its index at startup",
|
|
21
|
-
"(a `*.startup.tsx` calling `backfillIndex`), say so explicitly:",
|
|
22
|
-
" searchPlugin({ singleProcessMemoryIndex: true, indexes })",
|
|
23
|
-
"That is a claim about your topology, not a mute switch: if a second replica",
|
|
24
|
-
"ever announces itself, the plugin logs that the claim was contradicted."
|
|
25
|
-
].join("\n"), r = [
|
|
26
|
-
"plugin-search is running the in-memory backend in production under",
|
|
27
|
-
"`singleProcessMemoryIndex: true`. Holding you to the two conditions that makes true:",
|
|
28
|
-
"exactly ONE process serves search, and it re-seeds every index at startup",
|
|
29
|
-
"(`backfillIndex`) — the index is empty after each restart until it does."
|
|
30
|
-
].join(" "), i = (e) => e.backendKind !== "memory" || !e.production ? { level: "quiet" } : e.singleProcessDeclared ? {
|
|
7
|
+
}, n = "plugin-search refuses to boot in production on the in-memory backend.\n\nThe memory index lives in THIS process's heap. Two consequences, both silent:\n • every replica holds a different index, so a result depends on which replica served you;\n • the index starts EMPTY after every restart/deploy, and nothing re-seeds it automatically.\n\nConfigure a durable engine in app.config.ts:\n searchPlugin({ backend: { engine: 'typesense', url: …, apiKey: … }, indexes })\n searchPlugin({ backend: { engine: 'meilisearch', url: …, apiKey: … }, indexes })\n searchPlugin({ backend: { engine: 'algolia', appId: …, apiKey: … }, indexes })\nor pass your own `SearchBackend` implementation.\n\nIf this deployment really is ONE process that re-seeds its index at startup\n(a `*.startup.tsx` calling `backfillIndex`), say so explicitly:\n searchPlugin({ singleProcessMemoryIndex: true, indexes })\nThat is a claim about your topology, not a mute switch: if a second replica\never announces itself, the plugin logs that the claim was contradicted.", r = "plugin-search is running the in-memory backend in production under `singleProcessMemoryIndex: true`. Holding you to the two conditions that makes true: exactly ONE process serves search, and it re-seeds every index at startup (`backfillIndex`) — the index is empty after each restart until it does.", i = (e) => e.backendKind !== "memory" || !e.production ? { level: "quiet" } : e.singleProcessDeclared ? {
|
|
31
8
|
level: "note",
|
|
32
9
|
message: r
|
|
33
10
|
} : {
|
|
34
11
|
level: "refuse",
|
|
35
12
|
message: n
|
|
36
13
|
}, a = (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.`;
|
|
37
|
-
//#endregion
|
|
38
14
|
export { t as SearchBackendNotDurable, i as auditMemoryBackend, e as backendKindOf, a as peerObservedWarning };
|
package/dist/rpc.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { SearchFieldRejected as e, SearchIndexNotFound as t } from "./errors.js";
|
|
2
2
|
import { Schema as n } from "effect";
|
|
3
3
|
import { defineAction as r } from "@voltro/protocol";
|
|
4
|
-
|
|
4
|
+
// src/rpc.ts
|
|
5
5
|
var i = "@voltro/plugin-search", a = n.Union([
|
|
6
6
|
n.String,
|
|
7
7
|
n.Number,
|
|
@@ -53,5 +53,4 @@ var i = "@voltro/plugin-search", a = n.Union([
|
|
|
53
53
|
name: "queryDescriptor"
|
|
54
54
|
}
|
|
55
55
|
}];
|
|
56
|
-
//#endregion
|
|
57
56
|
export { i as BASE_NAME, o as SearchFilterSchema, l as queryDescriptor, u as searchRpcClientImports };
|
package/dist/sanitize.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
// src/sanitize.ts
|
|
2
2
|
var e = /^[A-Za-z_][A-Za-z0-9_.]*$/, t = (t) => e.test(t), n = (e, n) => {
|
|
3
3
|
let r = n ? new Set(n) : void 0;
|
|
4
4
|
for (let [n, i] of e) {
|
|
@@ -118,5 +118,4 @@ var e = /^[A-Za-z_][A-Za-z0-9_.]*$/, t = (t) => e.test(t), n = (e, n) => {
|
|
|
118
118
|
dropped: u
|
|
119
119
|
};
|
|
120
120
|
}, o = (e) => r[e];
|
|
121
|
-
//#endregion
|
|
122
121
|
export { e as FIELD_NAME_PATTERN, o as allowedEngineParams, n as firstRejectedField, t as isSafeFieldName, a as sanitizeEngineParams };
|
package/dist/statsBuffer.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
// src/statsBuffer.ts
|
|
2
2
|
var e = (e) => {
|
|
3
3
|
let t = /* @__PURE__ */ new Map(), n = 0, r = !1, i = async () => {
|
|
4
4
|
if (t.size === 0) return;
|
|
@@ -32,5 +32,4 @@ var e = (e) => {
|
|
|
32
32
|
pending: () => n
|
|
33
33
|
};
|
|
34
34
|
}, t = (e) => (t, n, r) => e().add(t, n, r);
|
|
35
|
-
//#endregion
|
|
36
35
|
export { e as makeSearchStatsBuffer, t as statsStoreFlush };
|
package/dist/statsStore.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { SearchBackendError as e } from "./backend.js";
|
|
2
2
|
import { and as t, eq as n, id as r, integer as i, table as a, text as o, timestamp as s } from "@voltro/database";
|
|
3
3
|
import { replicaId as c } from "@voltro/protocol/identity";
|
|
4
|
-
|
|
4
|
+
// src/statsStore.ts
|
|
5
5
|
var l = "_voltro_search_stats", u = () => ({
|
|
6
6
|
synced: 0,
|
|
7
7
|
removed: 0,
|
|
@@ -159,5 +159,4 @@ var l = "_voltro_search_stats", u = () => ({
|
|
|
159
159
|
})
|
|
160
160
|
};
|
|
161
161
|
};
|
|
162
|
-
//#endregion
|
|
163
162
|
export { l as SEARCH_STATS_TABLE, v as dataStoreStatsStore, p as memoryStatsStore, d as searchStatsTable, f as searchTables, u as zeroStats };
|
package/dist/web.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { BASE_NAME as e } from "./rpc.js";
|
|
2
2
|
import { pluginTag as t } from "@voltro/protocol";
|
|
3
3
|
import { useAction as n } from "@voltro/client";
|
|
4
|
-
|
|
4
|
+
// src/web.ts
|
|
5
5
|
var r = (n) => t(e, n), i = (e, t = "app") => {
|
|
6
6
|
let i = n(t, r("query")), a = i.lastResult;
|
|
7
7
|
return {
|
|
@@ -16,5 +16,4 @@ var r = (n) => t(e, n), i = (e, t = "app") => {
|
|
|
16
16
|
error: i.error
|
|
17
17
|
};
|
|
18
18
|
};
|
|
19
|
-
//#endregion
|
|
20
19
|
export { i as useSearch };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@voltro/plugin-search",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.89.0",
|
|
4
4
|
"description": "Keep an external search index (Typesense / Meilisearch / Algolia) in sync with framework tables via the post-commit ChangeEvent tap, then query it — tenant-scoped, with a backfill path and a useSearch() hook.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"voltro",
|
|
@@ -43,17 +43,17 @@
|
|
|
43
43
|
"node": ">=24.0.0"
|
|
44
44
|
},
|
|
45
45
|
"dependencies": {
|
|
46
|
-
"@voltro/client": "0.
|
|
47
|
-
"@voltro/database": "0.
|
|
48
|
-
"@voltro/protocol": "0.
|
|
46
|
+
"@voltro/client": "0.89.0",
|
|
47
|
+
"@voltro/database": "0.89.0",
|
|
48
|
+
"@voltro/protocol": "0.89.0"
|
|
49
49
|
},
|
|
50
50
|
"optionalDependencies": {
|
|
51
|
-
"algoliasearch": "^5.
|
|
51
|
+
"algoliasearch": "^5.60.0",
|
|
52
52
|
"meilisearch": "^0.62.0",
|
|
53
|
-
"typesense": "^3.0
|
|
53
|
+
"typesense": "^3.2.0"
|
|
54
54
|
},
|
|
55
55
|
"peerDependencies": {
|
|
56
|
-
"effect": "4.0
|
|
56
|
+
"effect": "4.1.0"
|
|
57
57
|
},
|
|
58
58
|
"publishConfig": {
|
|
59
59
|
"access": "public"
|