@absolutejs/sync 0.4.0 → 0.5.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/README.md CHANGED
@@ -33,9 +33,9 @@ top-N ordering are maintained incrementally through a composable operator graph
33
33
  > write-behind cache), Tier 2 (Drizzle + Prisma topic adapters, `createLiveQuery`),
34
34
  > and Tier 3 (sync engine: collections, WebSocket diff transport, optimistic
35
35
  > mutations + offline queue, a local-first client cache, declarative row-level
36
- > permissions, CDC for Postgres/MySQL/SQLite, incremental aggregations + joins,
37
- > and a declarative operator graph) are in place.
38
- > Everything ships as subpaths of this one package.
36
+ > permissions, live full-text + vector search, CDC for Postgres/MySQL/SQLite,
37
+ > incremental aggregations + joins, and a declarative operator graph) are in
38
+ > place. Everything ships as subpaths of this one package.
39
39
 
40
40
  ## Install
41
41
 
@@ -249,6 +249,37 @@ await orders.mutate({
249
249
  });
250
250
  ```
251
251
 
252
+ - **Live search.** A `defineSearchCollection` is a full-text or vector index kept
253
+ live from a table's change feed. The subscription's `params` are the query (a
254
+ string for keyword search, an embedding for similarity); the ranked top-K stream
255
+ back as an ordinary collection and re-rank as rows change. Read permissions on
256
+ the source table still scope a caller's hits. Standalone, `createTextIndex` and
257
+ `createVectorIndex` are reusable (e.g. RAG retrieval with `@absolutejs/rag`).
258
+
259
+ ```ts
260
+ // server
261
+ engine.registerSearch(
262
+ defineSearchCollection<Doc>({
263
+ name: 'docSearch',
264
+ table: 'docs',
265
+ index: () =>
266
+ createTextIndex({
267
+ key: (d) => d.id,
268
+ fields: ['title', 'body']
269
+ }),
270
+ source: () => db.select().from(docs), // the corpus to index
271
+ key: (d) => d.id
272
+ })
273
+ );
274
+
275
+ // client — params are the query; each result row carries `_score`
276
+ const results = createSyncCollection<Doc>({
277
+ url,
278
+ collection: 'docSearch',
279
+ params: 'quick brown fox' // a vector for createVectorIndex
280
+ });
281
+ ```
282
+
252
283
  ## Write-behind cache — keep a remote store off your hot path
253
284
 
254
285
  ```ts
@@ -328,21 +359,24 @@ mutate({
328
359
 
329
360
  ### `@absolutejs/sync/engine`
330
361
 
331
- | Export | What it is |
332
- | --------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
333
- | `createSyncEngine()` | Registry + view syncer: `register`, `subscribe`, `applyChange`, `connectSource`, `registerMutation`, `registerWriter`, `runMutation`. |
334
- | `defineCollection({ name, hydrate, key?, match?, authorize?, tables? })` | Define a syncable collection. |
335
- | `defineMutation({ name, handler, authorize? })` | Define a server mutation. Its `handler` gets `actions.insert/update/delete` (write through a registered `TableWriter` → persists + emits in one step) plus `actions.change` (escape hatch). Changes commit atomically. |
336
- | `registerWriter(table, { insert, update, delete })` | Teach the engine how to persist a table (any ORM), so writes auto-emit — you can't write without going live. |
337
- | `createAggregate({ key, groupBy?, value? })` | Incremental count/sum/avg/min/max by group. |
338
- | `createMaterializedView({ key, match, equals? })` | The predicate-matching IVM primitive (`apply`/`reset` → diffs). |
339
- | `createPollingChangeSource({ poll, intervalMs?, startSeq?, onProcessed? })` | DB-agnostic CDC `ChangeSource` that tails a changelog (outbox) table. |
340
- | `engine.connectCluster(bus)` + `createInMemoryClusterBus()` | Horizontal scale: fan changes across server instances over a `ClusterBus` (BYO Redis/Postgres; in-memory bus for dev). |
341
- | `createPresenceHub()` + `syncSocket({ engine, presence })` | Ephemeral room-scoped presence (online / typing / cursors) over the same socket — not persisted, auto-cleaned on disconnect. |
342
- | `query(source).filter().map().join().leftJoin().groupBy().orderBy()` | Declarative incremental query builder (the operator graph). |
343
- | `defineGraphCollection({ name, query, key, authorize? })` | Run a `query` as a live collection. |
344
- | `defineReactiveQuery({ name, run, key })` + `registerReactive` / `registerReader` | Read-set-tracked query: `run(ctx)` reads via `ctx.db` (`all`/`get`/`where`) and re-runs only when the rows/ranges it read change — no `match`, no manual emit. |
345
- | `definePermissions({ [table]: { read?, insert?, update?, delete?, write? } })` | Declarative row-level access control. Pass as `createSyncEngine({ permissions })` or `registerPermissions(table, rules)`. Read rules filter every row emitted; write rules gate `actions.insert/update/delete`. |
362
+ | Export | What it is |
363
+ | ---------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
364
+ | `createSyncEngine()` | Registry + view syncer: `register`, `subscribe`, `applyChange`, `connectSource`, `registerMutation`, `registerWriter`, `runMutation`. |
365
+ | `defineCollection({ name, hydrate, key?, match?, authorize?, tables? })` | Define a syncable collection. |
366
+ | `defineMutation({ name, handler, authorize? })` | Define a server mutation. Its `handler` gets `actions.insert/update/delete` (write through a registered `TableWriter` → persists + emits in one step) plus `actions.change` (escape hatch). Changes commit atomically. |
367
+ | `registerWriter(table, { insert, update, delete })` | Teach the engine how to persist a table (any ORM), so writes auto-emit — you can't write without going live. |
368
+ | `createAggregate({ key, groupBy?, value? })` | Incremental count/sum/avg/min/max by group. |
369
+ | `createMaterializedView({ key, match, equals? })` | The predicate-matching IVM primitive (`apply`/`reset` → diffs). |
370
+ | `createPollingChangeSource({ poll, intervalMs?, startSeq?, onProcessed? })` | DB-agnostic CDC `ChangeSource` that tails a changelog (outbox) table. |
371
+ | `engine.connectCluster(bus)` + `createInMemoryClusterBus()` | Horizontal scale: fan changes across server instances over a `ClusterBus` (BYO Redis/Postgres; in-memory bus for dev). |
372
+ | `createPresenceHub()` + `syncSocket({ engine, presence })` | Ephemeral room-scoped presence (online / typing / cursors) over the same socket — not persisted, auto-cleaned on disconnect. |
373
+ | `query(source).filter().map().join().leftJoin().groupBy().orderBy()` | Declarative incremental query builder (the operator graph). |
374
+ | `defineGraphCollection({ name, query, key, authorize? })` | Run a `query` as a live collection. |
375
+ | `defineReactiveQuery({ name, run, key })` + `registerReactive` / `registerReader` | Read-set-tracked query: `run(ctx)` reads via `ctx.db` (`all`/`get`/`where`) and re-runs only when the rows/ranges it read change — no `match`, no manual emit. |
376
+ | `definePermissions({ [table]: { read?, insert?, update?, delete?, write? } })` | Declarative row-level access control. Pass as `createSyncEngine({ permissions })` or `registerPermissions(table, rules)`. Read rules filter every row emitted; write rules gate `actions.insert/update/delete`. |
377
+ | `defineSearchCollection({ name, table, index, source, key, limit? })` + `registerSearch` | Live search collection: the subscription's `params` are the query (string/vector), the ranked top-K stream back as a normal collection, re-ranked as rows change. Each row carries its score under `_score`. |
378
+ | `createTextIndex({ key, fields, tokenize?, stopwords?, k1?, b? })` | Incremental BM25 full-text index (keyword search). Implements `SearchIndex`; usable standalone or inside a search collection. |
379
+ | `createVectorIndex({ key, embedding, metric? })` | Incremental vector index (cosine/dot/euclidean exact k-NN) for semantic search — pairs with `@absolutejs/ai` / `@absolutejs/rag` for RAG retrieval on your own data. |
346
380
 
347
381
  ### `@absolutejs/sync/postgres`
348
382
 
@@ -32,6 +32,12 @@ export { defineGraphCollection, query } from './graph';
32
32
  export type { GraphCollectionDefinition, GraphInstance, GraphSource, GroupByOptions, JoinOptions, OrderByQueryOptions, Query } from './graph';
33
33
  export { definePermissions } from './permissions';
34
34
  export type { PermissionsDefinition, ReadRule, TablePermissions, WriteRule } from './permissions';
35
+ export { defineSearchCollection, SEARCH_SCORE_FIELD } from './search';
36
+ export type { SearchCollectionDefinition, SearchHit, SearchIndex } from './search';
37
+ export { createTextIndex } from './textIndex';
38
+ export type { TextIndexOptions } from './textIndex';
39
+ export { createVectorIndex } from './vectorIndex';
40
+ export type { VectorIndexOptions, VectorMetric } from './vectorIndex';
35
41
  export { defineMutation } from './mutation';
36
42
  export type { MutationActions, MutationDefinition, MutationHandler, TableWriter, TransactionRunner } from './mutation';
37
43
  export { createSyncEngine, UnauthorizedError } from './syncEngine';
@@ -885,6 +885,156 @@ var query = (source) => makeQuery(source, []);
885
885
  var defineGraphCollection = (definition) => ({ ...definition, kind: "graph" });
886
886
  // src/engine/permissions.ts
887
887
  var definePermissions = (permissions) => permissions;
888
+ // src/engine/search.ts
889
+ var SEARCH_SCORE_FIELD = "_score";
890
+ var defineSearchCollection = (definition) => ({
891
+ ...definition,
892
+ kind: "search"
893
+ });
894
+ // src/engine/textIndex.ts
895
+ var defaultTokenize = (text) => text.toLowerCase().match(/[a-z0-9]+/g) ?? [];
896
+ var createTextIndex = (options) => {
897
+ const { key, fields } = options;
898
+ const tokenize = options.tokenize ?? defaultTokenize;
899
+ const stopwords = new Set(options.stopwords ?? []);
900
+ const k1 = options.k1 ?? 1.5;
901
+ const b = options.b ?? 0.75;
902
+ const docs = new Map;
903
+ const postings = new Map;
904
+ let totalLen = 0;
905
+ const termsOf = (row) => {
906
+ const text = fields.map((field) => {
907
+ const value = row[field];
908
+ return value === undefined || value === null ? "" : String(value);
909
+ }).join(" ");
910
+ return tokenize(text).filter((term) => !stopwords.has(term));
911
+ };
912
+ const remove = (rowKey) => {
913
+ const doc = docs.get(rowKey);
914
+ if (doc === undefined) {
915
+ return;
916
+ }
917
+ for (const term of doc.tf.keys()) {
918
+ const set = postings.get(term);
919
+ if (set !== undefined) {
920
+ set.delete(rowKey);
921
+ if (set.size === 0) {
922
+ postings.delete(term);
923
+ }
924
+ }
925
+ }
926
+ totalLen -= doc.len;
927
+ docs.delete(rowKey);
928
+ };
929
+ const add = (row) => {
930
+ const rowKey = key(row);
931
+ remove(rowKey);
932
+ const terms = termsOf(row);
933
+ const tf = new Map;
934
+ for (const term of terms) {
935
+ tf.set(term, (tf.get(term) ?? 0) + 1);
936
+ }
937
+ for (const term of tf.keys()) {
938
+ let set = postings.get(term);
939
+ if (set === undefined) {
940
+ set = new Set;
941
+ postings.set(term, set);
942
+ }
943
+ set.add(rowKey);
944
+ }
945
+ docs.set(rowKey, { row, len: terms.length, tf });
946
+ totalLen += terms.length;
947
+ };
948
+ const search = (query2, limit) => {
949
+ const total = docs.size;
950
+ if (total === 0) {
951
+ return [];
952
+ }
953
+ const avgdl = totalLen / total;
954
+ const queryTerms = new Set(tokenize(query2).filter((term) => !stopwords.has(term)));
955
+ const scores = new Map;
956
+ for (const term of queryTerms) {
957
+ const set = postings.get(term);
958
+ if (set === undefined) {
959
+ continue;
960
+ }
961
+ const df = set.size;
962
+ const idf = Math.log(1 + (total - df + 0.5) / (df + 0.5));
963
+ for (const rowKey of set) {
964
+ const doc = docs.get(rowKey);
965
+ const freq = doc.tf.get(term) ?? 0;
966
+ const norm = freq * (k1 + 1) / (freq + k1 * (1 - b + b * doc.len / avgdl));
967
+ scores.set(rowKey, (scores.get(rowKey) ?? 0) + idf * norm);
968
+ }
969
+ }
970
+ return [...scores.entries()].map(([rowKey, score]) => ({ row: docs.get(rowKey).row, score })).sort((first, second) => second.score - first.score).slice(0, limit);
971
+ };
972
+ return {
973
+ add,
974
+ remove,
975
+ search,
976
+ size: () => docs.size,
977
+ clear: () => {
978
+ docs.clear();
979
+ postings.clear();
980
+ totalLen = 0;
981
+ }
982
+ };
983
+ };
984
+ // src/engine/vectorIndex.ts
985
+ var dot = (first, second) => {
986
+ const length = Math.min(first.length, second.length);
987
+ let sum = 0;
988
+ for (let index = 0;index < length; index += 1) {
989
+ sum += first[index] * second[index];
990
+ }
991
+ return sum;
992
+ };
993
+ var normOf = (vec) => Math.sqrt(dot(vec, vec));
994
+ var euclidean = (first, second) => {
995
+ const length = Math.max(first.length, second.length);
996
+ let sum = 0;
997
+ for (let index = 0;index < length; index += 1) {
998
+ const delta = (first[index] ?? 0) - (second[index] ?? 0);
999
+ sum += delta * delta;
1000
+ }
1001
+ return Math.sqrt(sum);
1002
+ };
1003
+ var createVectorIndex = (options) => {
1004
+ const { key, embedding } = options;
1005
+ const metric = options.metric ?? "cosine";
1006
+ const entries = new Map;
1007
+ const score = (query2, queryNorm, entry) => {
1008
+ if (metric === "dot") {
1009
+ return dot(query2, entry.vec);
1010
+ }
1011
+ if (metric === "euclidean") {
1012
+ return -euclidean(query2, entry.vec);
1013
+ }
1014
+ const denominator = queryNorm * entry.norm;
1015
+ return denominator === 0 ? 0 : dot(query2, entry.vec) / denominator;
1016
+ };
1017
+ return {
1018
+ add: (row) => {
1019
+ const vec = embedding(row);
1020
+ entries.set(key(row), { row, vec, norm: normOf(vec) });
1021
+ },
1022
+ remove: (rowKey) => {
1023
+ entries.delete(rowKey);
1024
+ },
1025
+ search: (query2, limit) => {
1026
+ const queryNorm = normOf(query2);
1027
+ return [...entries.values()].map((entry) => ({
1028
+ row: entry.row,
1029
+ score: score(query2, queryNorm, entry)
1030
+ })).sort((first, second) => second.score - first.score).slice(0, limit);
1031
+ },
1032
+ size: () => entries.size,
1033
+ clear: () => {
1034
+ entries.clear();
1035
+ }
1036
+ };
1037
+ };
888
1038
  // src/engine/mutation.ts
889
1039
  var defineMutation = (definition) => definition;
890
1040
  // src/engine/syncEngine.ts
@@ -906,6 +1056,15 @@ var shallowEqual4 = (a, b) => {
906
1056
  const bKeys = Object.keys(b);
907
1057
  return aKeys.length === bKeys.length && aKeys.every((k) => a[k] === b[k]);
908
1058
  };
1059
+ var equalsIgnoringScore = (a, b) => {
1060
+ if (typeof a !== "object" || typeof b !== "object" || a === null || b === null) {
1061
+ return a === b;
1062
+ }
1063
+ const strip = (value) => Object.keys(value).filter((k) => k !== SEARCH_SCORE_FIELD);
1064
+ const aKeys = strip(a);
1065
+ const bKeys = strip(b);
1066
+ return aKeys.length === bKeys.length && aKeys.every((k) => a[k] === b[k]);
1067
+ };
909
1068
  var createSyncEngine = (options = {}) => {
910
1069
  const registry = new Map;
911
1070
  const mutations = new Map;
@@ -921,6 +1080,8 @@ var createSyncEngine = (options = {}) => {
921
1080
  return rules?.[op] ?? rules?.write;
922
1081
  };
923
1082
  const reactiveSubs = new Set;
1083
+ const searchSubs = new Set;
1084
+ const searchIndexes = new Map;
924
1085
  const active = new Map;
925
1086
  const tableIndex = new Map;
926
1087
  const changeLogSize = options.changeLogSize ?? 1024;
@@ -973,6 +1134,9 @@ var createSyncEngine = (options = {}) => {
973
1134
  if (subscription.kind === "reactive") {
974
1135
  return EMPTY_DIFF;
975
1136
  }
1137
+ if (subscription.kind === "search") {
1138
+ return EMPTY_DIFF;
1139
+ }
976
1140
  if (subscription.incremental) {
977
1141
  try {
978
1142
  return subscription.view.apply(change);
@@ -1085,7 +1249,7 @@ var createSyncEngine = (options = {}) => {
1085
1249
  }
1086
1250
  };
1087
1251
  };
1088
- const diffRerun = (sub, rows) => {
1252
+ const diffRerun = (sub, rows, equals = shallowEqual4) => {
1089
1253
  const next = new Map;
1090
1254
  for (const row of rows) {
1091
1255
  next.set(sub.key(row), row);
@@ -1097,7 +1261,7 @@ var createSyncEngine = (options = {}) => {
1097
1261
  const previous = sub.current.get(rowKey);
1098
1262
  if (previous === undefined) {
1099
1263
  added.push(row);
1100
- } else if (!shallowEqual4(previous, row)) {
1264
+ } else if (!equals(previous, row)) {
1101
1265
  changed.push(row);
1102
1266
  }
1103
1267
  }
@@ -1128,6 +1292,47 @@ var createSyncEngine = (options = {}) => {
1128
1292
  }
1129
1293
  return pairs;
1130
1294
  };
1295
+ const ensureSearchIndex = async (definition) => {
1296
+ let entry = searchIndexes.get(definition.name);
1297
+ if (entry === undefined) {
1298
+ entry = { index: definition.index(), definition, hydrated: false };
1299
+ searchIndexes.set(definition.name, entry);
1300
+ }
1301
+ if (!entry.hydrated) {
1302
+ for (const row of await definition.source()) {
1303
+ entry.index.add(row);
1304
+ }
1305
+ entry.hydrated = true;
1306
+ }
1307
+ return entry;
1308
+ };
1309
+ const searchPairs = (changes) => {
1310
+ const touched = new Set;
1311
+ for (const { table, change } of changes) {
1312
+ for (const entry of searchIndexes.values()) {
1313
+ if (!entry.hydrated || entry.definition.table !== table) {
1314
+ continue;
1315
+ }
1316
+ if (change.op === "delete") {
1317
+ entry.index.remove(entry.definition.key(change.row));
1318
+ } else {
1319
+ entry.index.add(change.row);
1320
+ }
1321
+ touched.add(entry.definition.name);
1322
+ }
1323
+ }
1324
+ const pairs = [];
1325
+ for (const sub of searchSubs) {
1326
+ if (!touched.has(sub.collection)) {
1327
+ continue;
1328
+ }
1329
+ const diff = diffRerun(sub, sub.rerun(), equalsIgnoringScore);
1330
+ if (!isEmptyViewDiff(diff)) {
1331
+ pairs.push([sub, diff]);
1332
+ }
1333
+ }
1334
+ return pairs;
1335
+ };
1131
1336
  const logChange = (changeVersion, entry) => {
1132
1337
  changeLog.push(entry);
1133
1338
  if (changeLog.length > changeLogSize) {
@@ -1148,6 +1353,7 @@ var createSyncEngine = (options = {}) => {
1148
1353
  emissions.push(...await reactivePairs([
1149
1354
  { table, key: changedKeyFor(table, change), row: change.row }
1150
1355
  ]));
1356
+ emissions.push(...searchPairs([{ table, change }]));
1151
1357
  for (const [subscription, diff] of emissions) {
1152
1358
  subscription.onDiff(diff, changeVersion);
1153
1359
  }
@@ -1188,6 +1394,7 @@ var createSyncEngine = (options = {}) => {
1188
1394
  }
1189
1395
  }
1190
1396
  emissions.push(...await reactivePairs(reactiveChanges));
1397
+ emissions.push(...searchPairs(changes));
1191
1398
  for (const [subscription, diff] of emissions) {
1192
1399
  subscription.onDiff(diff, batchVersion);
1193
1400
  }
@@ -1330,6 +1537,50 @@ var createSyncEngine = (options = {}) => {
1330
1537
  }
1331
1538
  };
1332
1539
  };
1540
+ const subscribeSearch = async (collection, definition, params, ctx, onDiff, set) => {
1541
+ const query2 = params;
1542
+ if (definition.authorize !== undefined) {
1543
+ const allowed = await definition.authorize(query2, ctx);
1544
+ if (!allowed) {
1545
+ throw new UnauthorizedError(`subscribe to collection "${collection}"`);
1546
+ }
1547
+ }
1548
+ const entry = await ensureSearchIndex(definition);
1549
+ const limit = definition.limit ?? 20;
1550
+ const readRule = readRuleFor(definition.table);
1551
+ const rerun = () => {
1552
+ const candidates = entry.index.search(query2, readRule ? limit * 5 : limit);
1553
+ const visible = readRule ? candidates.filter((hit) => readRule(ctx, hit.row)) : candidates;
1554
+ return visible.slice(0, limit).map((hit) => ({
1555
+ ...hit.row,
1556
+ [SEARCH_SCORE_FIELD]: hit.score
1557
+ }));
1558
+ };
1559
+ const initial = rerun();
1560
+ const current = new Map;
1561
+ for (const row of initial) {
1562
+ current.set(definition.key(row), row);
1563
+ }
1564
+ const atVersion = version;
1565
+ const subscription = {
1566
+ kind: "search",
1567
+ collection,
1568
+ key: definition.key,
1569
+ rerun,
1570
+ current,
1571
+ onDiff
1572
+ };
1573
+ set.add(subscription);
1574
+ searchSubs.add(subscription);
1575
+ return {
1576
+ initial,
1577
+ version: atVersion,
1578
+ unsubscribe: () => {
1579
+ set.delete(subscription);
1580
+ searchSubs.delete(subscription);
1581
+ }
1582
+ };
1583
+ };
1333
1584
  return {
1334
1585
  register: (collection) => {
1335
1586
  registry.set(collection.name, collection);
@@ -1348,6 +1599,9 @@ var createSyncEngine = (options = {}) => {
1348
1599
  addTableIndex(table, collection.name);
1349
1600
  }
1350
1601
  },
1602
+ registerSearch: (collection) => {
1603
+ registry.set(collection.name, collection);
1604
+ },
1351
1605
  subscribe: async ({ collection, params, ctx, onDiff, since }) => {
1352
1606
  const registered = registry.get(collection);
1353
1607
  if (registered === undefined) {
@@ -1368,6 +1622,10 @@ var createSyncEngine = (options = {}) => {
1368
1622
  const reactived = await subscribeReactive(collection, registered, params, ctx, typedOnDiff, subscribeSet);
1369
1623
  return reactived;
1370
1624
  }
1625
+ if (registeredKind === "search") {
1626
+ const searched = await subscribeSearch(collection, registered, params, ctx, typedOnDiff, subscribeSet);
1627
+ return searched;
1628
+ }
1371
1629
  const definition = registered;
1372
1630
  if (definition.authorize !== undefined) {
1373
1631
  const allowed = await definition.authorize(params, ctx);
@@ -1801,12 +2059,15 @@ export {
1801
2059
  hydrateRoute,
1802
2060
  fromRowChange,
1803
2061
  filterOp,
2062
+ defineSearchCollection,
1804
2063
  defineReactiveQuery,
1805
2064
  definePermissions,
1806
2065
  defineMutation,
1807
2066
  defineJoinCollection,
1808
2067
  defineGraphCollection,
1809
2068
  defineCollection,
2069
+ createVectorIndex,
2070
+ createTextIndex,
1810
2071
  createSyncEngine,
1811
2072
  createSyncConnection,
1812
2073
  createPresenceHub,
@@ -1817,8 +2078,9 @@ export {
1817
2078
  createAggregate,
1818
2079
  chain,
1819
2080
  aggregateOp,
1820
- UnauthorizedError
2081
+ UnauthorizedError,
2082
+ SEARCH_SCORE_FIELD
1821
2083
  };
1822
2084
 
1823
- //# debugId=04C93A0AB37B69AD64756E2164756E21
2085
+ //# debugId=28E08370F43FEBAE64756E2164756E21
1824
2086
  //# sourceMappingURL=index.js.map