@delali/narsil 0.3.1-next.69 → 0.3.1-next.71

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.
Files changed (46) hide show
  1. package/dist/{capabilities-B1wz2Zl0.d.ts → capabilities-Dt-7B4Wz.d.ts} +2 -2
  2. package/dist/{chunk-DD5X23E6.mjs → chunk-2STVUTNA.mjs} +1 -1
  3. package/dist/chunk-3JGWULDF.mjs +256 -0
  4. package/dist/{chunk-6TGZG2TV.mjs → chunk-653BNMAF.mjs} +190 -58
  5. package/dist/{chunk-YA52AC2V.mjs → chunk-FVLQ63B7.mjs} +203 -9
  6. package/dist/{chunk-5JLSTECC.mjs → chunk-GIVAGD3Q.mjs} +1 -1
  7. package/dist/{chunk-AV4IJKD2.mjs → chunk-HWQLTLNG.mjs} +18 -1
  8. package/dist/{chunk-6IT3MH5M.mjs → chunk-IOR2K26O.mjs} +178 -238
  9. package/dist/{chunk-4VU5TWCR.mjs → chunk-LMO5TJUS.mjs} +40 -35
  10. package/dist/{chunk-BEWOA4VV.mjs → chunk-M76V3OGJ.mjs} +508 -401
  11. package/dist/{chunk-YMZCMH5M.mjs → chunk-OI42GWLR.mjs} +17 -1
  12. package/dist/{chunk-2BDG2IWP.mjs → chunk-P4DSQ6M4.mjs} +16 -6
  13. package/dist/{chunk-THYRHHO2.mjs → chunk-YJDQ7NLA.mjs} +1 -1
  14. package/dist/{client-xVrOCYTW.d.ts → client-COek5GXK.d.ts} +3 -3
  15. package/dist/client.d.ts +8 -8
  16. package/dist/{config-CEeSV_Xo.d.ts → config-Dfanyqqt.d.ts} +2 -2
  17. package/dist/{config-CSvCVtB7.d.ts → config-rBpbgTw8.d.ts} +2 -2
  18. package/dist/direct-executor-GYJEKNV5.mjs +12 -0
  19. package/dist/distribution/coordinator/etcd.d.ts +2 -2
  20. package/dist/distribution/coordinator/etcd.mjs +1 -1
  21. package/dist/distribution/coordinator/in-memory.d.ts +2 -2
  22. package/dist/distribution/coordinator/in-memory.mjs +1 -1
  23. package/dist/distribution.d.ts +8 -8
  24. package/dist/distribution.mjs +109 -69
  25. package/dist/{engine-77ErLy8P.d.ts → engine-igk0aMpQ.d.ts} +109 -60
  26. package/dist/index.browser.mjs +1167 -749
  27. package/dist/index.d.ts +7 -7
  28. package/dist/index.mjs +10 -10
  29. package/dist/invalidation/filesystem.mjs +1 -1
  30. package/dist/{memory-CKF-9WLP.d.ts → memory-C7UMCMH3.d.ts} +35 -17
  31. package/dist/persistence/durability/checkpoint-worker.d.ts +2 -1
  32. package/dist/persistence/durability/checkpoint-worker.mjs +10 -10
  33. package/dist/react.d.ts +277 -182
  34. package/dist/react.mjs +189 -45
  35. package/dist/{schema-d5Afu03A.d.ts → schema-Bgzr4g7b.d.ts} +62 -10
  36. package/dist/server.d.ts +10 -10
  37. package/dist/server.mjs +11 -7
  38. package/dist/{tasks-BEiNxDRs.d.ts → tasks-BZt_zes6.d.ts} +3 -1
  39. package/dist/{thread-FLP45EUD.mjs → thread-JEVAYETR.mjs} +6 -6
  40. package/dist/{types-DAK7mnUZ.d.ts → types-gOUqhs2F.d.ts} +1 -1
  41. package/dist/vector/search-worker.d.ts +1 -1
  42. package/dist/vector/search-worker.mjs +2 -2
  43. package/dist/workers/entry.mjs +3 -3
  44. package/package.json +7 -7
  45. package/dist/chunk-VTPLKNWI.mjs +0 -135
  46. package/dist/direct-executor-3ZYXSGFX.mjs +0 -12
@@ -1,5 +1,5 @@
1
- import { isTextFieldType, flattenSchema, SORTABLE_TEXT_FIELD_TYPE, isGeopointOrVectorType, MAX_SORT_FIELDS, MAX_SORT_FIELD_NAME_LENGTH, MAX_CURSOR_LENGTH, RESULT_WINDOW, DEFAULT_FUZZY_PREFIX_LENGTH, DEFAULT_PAGE_SIZE, PROTOTYPE_POLLUTION_KEYS, PREFIX_MAX_EXPANSIONS, MAX_CURSOR_ANCHOR_CODE_POINTS } from './chunk-6TGZG2TV.mjs';
2
- import { compareCodePoints, sortModeOf, defaultSortMode, toReducedSortValue, readSortField, compareComparableKeys, toComparableSortValue, isSortMode, SORT_MODES, SORT_VALUE_MAX_CODE_POINTS, compareSortValues } from './chunk-YMZCMH5M.mjs';
1
+ import { isWordIndexedBase, flattenSchema, parsedTypeOf, isStringValuedBase, withSortableOption, isGeopointOrVectorType, MAX_SORT_FIELDS, MAX_SORT_FIELD_NAME_LENGTH, MAX_CURSOR_LENGTH, MAX_CURSOR_ANCHOR_CODE_POINTS, RESULT_WINDOW, DEFAULT_FUZZY_PREFIX_LENGTH, DEFAULT_PAGE_SIZE, PROTOTYPE_POLLUTION_KEYS, isWordIndexedFieldType, PREFIX_MAX_EXPANSIONS } from './chunk-653BNMAF.mjs';
2
+ import { compareCodePoints, sortModeOf, defaultSortMode, SORT_VALUE_MAX_CODE_POINTS, toReducedSortValue, readSortField, compareComparableKeys, toComparableSortValue, exceedsCodePoints, isSortMode, SORT_MODES, compareSortValues } from './chunk-OI42GWLR.mjs';
3
3
  import { createNarsilError, ErrorCodes, NarsilError } from './chunk-USKFU7J5.mjs';
4
4
 
5
5
  // src/core/tokenizer/constants.ts
@@ -762,12 +762,12 @@ function stringArraysEqual(a, b) {
762
762
  }
763
763
  return true;
764
764
  }
765
- function textFieldsChanged(oldDoc, newDoc, flatSchema) {
766
- for (const [path, fieldType] of Object.entries(flatSchema)) {
767
- if (!isTextFieldType(fieldType) && fieldType !== "string[]") continue;
765
+ function textFieldsChanged(oldDoc, newDoc, fields) {
766
+ for (const { path, base } of fields) {
767
+ if (!isWordIndexedBase(base)) continue;
768
768
  const oldVal = getNestedValue(oldDoc, path);
769
769
  const newVal = getNestedValue(newDoc, path);
770
- if (fieldType !== "string[]") {
770
+ if (base === "string") {
771
771
  if (oldVal !== newVal) return true;
772
772
  } else {
773
773
  if (!stringArraysEqual(oldVal, newVal)) return true;
@@ -1192,6 +1192,16 @@ function requireFieldKind(fieldPath, operator, type, accepted) {
1192
1192
  operator
1193
1193
  );
1194
1194
  }
1195
+ function requireTextRangeField(fieldPath, operator, type) {
1196
+ const parsed = parsedTypeOf(type);
1197
+ if (parsed?.sortable && (parsed.base === "string" || parsed.base === "verbatim")) return;
1198
+ const declared = type === void 0 ? `the schema has no field "${fieldPath}"` : `field "${fieldPath}" has type "${type}"`;
1199
+ invalid(
1200
+ `The engine applies "${operator}" with a text bound to a "string" or "verbatim" field whose type includes "sortable", but ${declared}`,
1201
+ fieldPath,
1202
+ operator
1203
+ );
1204
+ }
1195
1205
  function requireRadius(fieldPath, radius) {
1196
1206
  const circle = radius;
1197
1207
  if (circle === null || typeof circle !== "object") {
@@ -1252,22 +1262,32 @@ function requireValidFilter(expression, fieldTypes, declaredOnly = false) {
1252
1262
  }
1253
1263
  function requireValidOperands(fieldPath, filter, type) {
1254
1264
  for (const operator of RANGE_OPERATORS) {
1255
- if (filter[operator] === void 0) continue;
1256
- if (!isFiniteNumber(filter[operator])) {
1257
- invalid(`"${operator}" on field "${fieldPath}" must be a finite number`, fieldPath, operator);
1265
+ const bound = filter[operator];
1266
+ if (bound === void 0) continue;
1267
+ if (typeof bound === "string") {
1268
+ requireTextRangeField(fieldPath, operator, type);
1269
+ continue;
1270
+ }
1271
+ if (!isFiniteNumber(bound)) {
1272
+ invalid(`"${operator}" on field "${fieldPath}" must be a finite number or a string`, fieldPath, operator);
1258
1273
  }
1259
1274
  requireFieldKind(fieldPath, operator, type, ["number"]);
1260
1275
  }
1261
1276
  if (filter.between !== void 0) {
1262
1277
  const bounds = filter.between;
1263
- if (!Array.isArray(bounds) || bounds.length !== 2 || !isFiniteNumber(bounds[0]) || !isFiniteNumber(bounds[1])) {
1264
- invalid(
1265
- `"between" on field "${fieldPath}" must be two finite numbers, the lower bound first`,
1266
- fieldPath,
1267
- "between"
1268
- );
1278
+ const isPair = Array.isArray(bounds) && bounds.length === 2;
1279
+ if (isPair && typeof bounds[0] === "string" && typeof bounds[1] === "string") {
1280
+ requireTextRangeField(fieldPath, "between", type);
1281
+ } else {
1282
+ if (!isPair || !isFiniteNumber(bounds[0]) || !isFiniteNumber(bounds[1])) {
1283
+ invalid(
1284
+ `"between" on field "${fieldPath}" must be two finite numbers or two strings, the lower bound first`,
1285
+ fieldPath,
1286
+ "between"
1287
+ );
1288
+ }
1289
+ requireFieldKind(fieldPath, "between", type, ["number"]);
1269
1290
  }
1270
- requireFieldKind(fieldPath, "between", type, ["number"]);
1271
1291
  }
1272
1292
  for (const operator of TEXT_OPERATORS) {
1273
1293
  if (filter[operator] === void 0) continue;
@@ -1365,10 +1385,11 @@ function requireSortableFields(sort, schema, strict = false) {
1365
1385
  );
1366
1386
  }
1367
1387
  requireSortMode(entry, fieldType);
1368
- if (fieldType === "string") {
1388
+ const parsed = parsedTypeOf(fieldType);
1389
+ if (parsed !== void 0 && isStringValuedBase(parsed.base) && !parsed.sortable) {
1369
1390
  throw new NarsilError(
1370
1391
  ErrorCodes.SEARCH_INVALID_FIELD,
1371
- `The engine sorts by text field "${entry.field}" only where the schema declares it "${SORTABLE_TEXT_FIELD_TYPE}", because ordering text takes far more memory per document than ordering a number`,
1392
+ `The engine sorts by text field "${entry.field}" only where its type includes "sortable", as in "${withSortableOption(parsed)}", because it keeps up to the first ${SORT_VALUE_MAX_CODE_POINTS} code points of every document's value in memory to sort by a text field`,
1372
1393
  { field: entry.field, fieldType }
1373
1394
  );
1374
1395
  }
@@ -1406,22 +1427,6 @@ function invalidCursor(cursor, reason) {
1406
1427
  const shown = cursor.length > 100 ? `${cursor.slice(0, 100)}...` : cursor;
1407
1428
  return new NarsilError(ErrorCodes.SEARCH_INVALID_CURSOR, `Failed to decode cursor: ${reason}`, { cursor: shown });
1408
1429
  }
1409
- function exceedsCodePoints(value, maximum) {
1410
- if (value.length <= maximum) return false;
1411
- let counted = 0;
1412
- let i = 0;
1413
- while (i < value.length) {
1414
- const unit = value.charCodeAt(i);
1415
- if (unit >= 55296 && unit < 56320 && i + 1 < value.length) {
1416
- const low = value.charCodeAt(i + 1);
1417
- if (low >= 56320 && low < 57344) i++;
1418
- }
1419
- i++;
1420
- counted++;
1421
- if (counted > maximum) return true;
1422
- }
1423
- return false;
1424
- }
1425
1430
  function sortSignatureOf(sort) {
1426
1431
  const fields = normalizeSort(sort);
1427
1432
  if (fields.length === 0) return null;
@@ -1750,7 +1755,7 @@ function validateSearchFields(fields, flatSchema) {
1750
1755
  if (!fieldType) {
1751
1756
  throw new NarsilError(ErrorCodes.SEARCH_INVALID_FIELD, `Field "${field}" does not exist in the schema`, { field });
1752
1757
  }
1753
- if (!isTextFieldType(fieldType) && fieldType !== "string[]") {
1758
+ if (!isWordIndexedFieldType(fieldType)) {
1754
1759
  throw new NarsilError(
1755
1760
  ErrorCodes.SEARCH_INVALID_FIELD,
1756
1761
  `Field "${field}" has type "${fieldType}" which cannot be used for full-text search`,