@verdaccio/search 7.0.0-next.0 → 7.0.0-next.1
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 +6 -0
- package/build/dist.js +190 -82
- package/build/indexer.d.ts +5 -3
- package/package.json +3 -3
- package/src/indexer.ts +26 -11
- package/test/index.spec.ts +47 -0
package/CHANGELOG.md
CHANGED
package/build/dist.js
CHANGED
|
@@ -786,7 +786,7 @@ __export(src_exports, {
|
|
|
786
786
|
SearchMemoryIndexer: () => indexer_default
|
|
787
787
|
});
|
|
788
788
|
|
|
789
|
-
// ../../node_modules/.pnpm/@orama+orama@1.
|
|
789
|
+
// ../../node_modules/.pnpm/@orama+orama@1.2.1/node_modules/@orama/orama/dist/components/tokenizer/languages.js
|
|
790
790
|
var STEMMERS = {
|
|
791
791
|
arabic: "ar",
|
|
792
792
|
armenian: "am",
|
|
@@ -849,7 +849,7 @@ var SPLITTERS = {
|
|
|
849
849
|
};
|
|
850
850
|
var SUPPORTED_LANGUAGES = Object.keys(STEMMERS);
|
|
851
851
|
|
|
852
|
-
// ../../node_modules/.pnpm/@orama+orama@1.
|
|
852
|
+
// ../../node_modules/.pnpm/@orama+orama@1.2.1/node_modules/@orama/orama/dist/utils.js
|
|
853
853
|
var baseId = Date.now().toString().slice(5);
|
|
854
854
|
var lastId = 0;
|
|
855
855
|
var nano = BigInt(1e3);
|
|
@@ -983,7 +983,7 @@ async function getNested(obj, path) {
|
|
|
983
983
|
return props[path];
|
|
984
984
|
}
|
|
985
985
|
|
|
986
|
-
// ../../node_modules/.pnpm/@orama+orama@1.
|
|
986
|
+
// ../../node_modules/.pnpm/@orama+orama@1.2.1/node_modules/@orama/orama/dist/errors.js
|
|
987
987
|
var allLanguages = SUPPORTED_LANGUAGES.join("\n - ");
|
|
988
988
|
var errors = {
|
|
989
989
|
NO_LANGUAGE_WITH_CUSTOM_TOKENIZER: "Do not pass the language option to create when using a custom tokenizer.",
|
|
@@ -1012,7 +1012,11 @@ Supported languages are:
|
|
|
1012
1012
|
SORT_DISABLED: `Sort is disabled. Please read the documentation at https://docs.oramasearch for more information.`,
|
|
1013
1013
|
UNKNOWN_GROUP_BY_PROPERTY: `Unknown groupBy property "%s".`,
|
|
1014
1014
|
INVALID_GROUP_BY_PROPERTY: `Invalid groupBy property "%s". Allowed types: "%s", but given "%s".`,
|
|
1015
|
-
UNKNOWN_FILTER_PROPERTY: `Unknown filter property "%s"
|
|
1015
|
+
UNKNOWN_FILTER_PROPERTY: `Unknown filter property "%s".`,
|
|
1016
|
+
INVALID_VECTOR_SIZE: `Vector size must be a number greater than 0. Got "%s" instead.`,
|
|
1017
|
+
INVALID_VECTOR_VALUE: `Vector value must be a number greater than 0. Got "%s" instead.`,
|
|
1018
|
+
INVALID_INPUT_VECTOR: `Property "%s" was declared as a %s-dimentional vector, but got a %s-dimentional vector instead.
|
|
1019
|
+
Input vectors must be of the size declared in the schema, as calculating similarity between vectors of different sizes can lead to unexpected results.`
|
|
1016
1020
|
};
|
|
1017
1021
|
function createError(code, ...args) {
|
|
1018
1022
|
var _a2;
|
|
@@ -1024,7 +1028,7 @@ function createError(code, ...args) {
|
|
|
1024
1028
|
return error;
|
|
1025
1029
|
}
|
|
1026
1030
|
|
|
1027
|
-
// ../../node_modules/.pnpm/@orama+orama@1.
|
|
1031
|
+
// ../../node_modules/.pnpm/@orama+orama@1.2.1/node_modules/@orama/orama/dist/components/defaults.js
|
|
1028
1032
|
async function formatElapsedTime(n) {
|
|
1029
1033
|
return {
|
|
1030
1034
|
raw: Number(n),
|
|
@@ -1048,6 +1052,13 @@ async function validateSchema(doc, schema) {
|
|
|
1048
1052
|
continue;
|
|
1049
1053
|
}
|
|
1050
1054
|
const typeOfType = typeof type;
|
|
1055
|
+
if (isVectorType(type)) {
|
|
1056
|
+
const vectorSize = getVectorSize(type);
|
|
1057
|
+
if (!Array.isArray(value) || value.length !== vectorSize) {
|
|
1058
|
+
throw createError("INVALID_INPUT_VECTOR", prop, vectorSize, value.length);
|
|
1059
|
+
}
|
|
1060
|
+
continue;
|
|
1061
|
+
}
|
|
1051
1062
|
if (typeOfType === "string" && isArrayType(type)) {
|
|
1052
1063
|
if (!Array.isArray(value)) {
|
|
1053
1064
|
return prop;
|
|
@@ -1090,14 +1101,28 @@ var INNER_TYPE = {
|
|
|
1090
1101
|
"number[]": "number",
|
|
1091
1102
|
"boolean[]": "boolean"
|
|
1092
1103
|
};
|
|
1104
|
+
function isVectorType(type) {
|
|
1105
|
+
return /^vector\[\d+\]$/.test(type);
|
|
1106
|
+
}
|
|
1093
1107
|
function isArrayType(type) {
|
|
1094
1108
|
return IS_ARRAY_TYPE[type];
|
|
1095
1109
|
}
|
|
1096
1110
|
function getInnerType(type) {
|
|
1097
1111
|
return INNER_TYPE[type];
|
|
1098
1112
|
}
|
|
1113
|
+
function getVectorSize(type) {
|
|
1114
|
+
const size = Number(type.slice(7, -1));
|
|
1115
|
+
switch (true) {
|
|
1116
|
+
case isNaN(size):
|
|
1117
|
+
throw createError("INVALID_VECTOR_VALUE", type);
|
|
1118
|
+
case size <= 0:
|
|
1119
|
+
throw createError("INVALID_VECTOR_SIZE", type);
|
|
1120
|
+
default:
|
|
1121
|
+
return size;
|
|
1122
|
+
}
|
|
1123
|
+
}
|
|
1099
1124
|
|
|
1100
|
-
// ../../node_modules/.pnpm/@orama+orama@1.
|
|
1125
|
+
// ../../node_modules/.pnpm/@orama+orama@1.2.1/node_modules/@orama/orama/dist/components/internal-document-id-store.js
|
|
1101
1126
|
function createInternalDocumentIDStore() {
|
|
1102
1127
|
return {
|
|
1103
1128
|
idToInternalId: /* @__PURE__ */ new Map(),
|
|
@@ -1143,7 +1168,7 @@ function getDocumentIdFromInternalId(store2, internalId) {
|
|
|
1143
1168
|
return store2.internalIdToId[internalId - 1];
|
|
1144
1169
|
}
|
|
1145
1170
|
|
|
1146
|
-
// ../../node_modules/.pnpm/@orama+orama@1.
|
|
1171
|
+
// ../../node_modules/.pnpm/@orama+orama@1.2.1/node_modules/@orama/orama/dist/components/documents-store.js
|
|
1147
1172
|
async function create(_, sharedInternalDocumentStore) {
|
|
1148
1173
|
return {
|
|
1149
1174
|
sharedInternalDocumentStore,
|
|
@@ -1217,7 +1242,7 @@ async function createDocumentsStore() {
|
|
|
1217
1242
|
};
|
|
1218
1243
|
}
|
|
1219
1244
|
|
|
1220
|
-
// ../../node_modules/.pnpm/@orama+orama@1.
|
|
1245
|
+
// ../../node_modules/.pnpm/@orama+orama@1.2.1/node_modules/@orama/orama/dist/components/hooks.js
|
|
1221
1246
|
var OBJECT_COMPONENTS = [
|
|
1222
1247
|
"tokenizer",
|
|
1223
1248
|
"index",
|
|
@@ -1258,7 +1283,7 @@ async function runAfterSearch(hooks, db, params, language, results) {
|
|
|
1258
1283
|
}
|
|
1259
1284
|
}
|
|
1260
1285
|
|
|
1261
|
-
// ../../node_modules/.pnpm/@orama+orama@1.
|
|
1286
|
+
// ../../node_modules/.pnpm/@orama+orama@1.2.1/node_modules/@orama/orama/dist/trees/avl.js
|
|
1262
1287
|
var BALANCE_STATE = {
|
|
1263
1288
|
UNBALANCED_RIGHT: -2,
|
|
1264
1289
|
SLIGHTLY_UNBALANCED_RIGHT: -1,
|
|
@@ -1498,7 +1523,7 @@ function removeDocument(root, id, key) {
|
|
|
1498
1523
|
node.value.splice(node.value.indexOf(id), 1);
|
|
1499
1524
|
}
|
|
1500
1525
|
|
|
1501
|
-
// ../../node_modules/.pnpm/@orama+orama@1.
|
|
1526
|
+
// ../../node_modules/.pnpm/@orama+orama@1.2.1/node_modules/@orama/orama/dist/components/levenshtein.js
|
|
1502
1527
|
function _boundedLevenshtein(a, b, tolerance) {
|
|
1503
1528
|
if (a === b) {
|
|
1504
1529
|
return 0;
|
|
@@ -1587,7 +1612,7 @@ function syncBoundedLevenshtein(a, b, tolerance) {
|
|
|
1587
1612
|
};
|
|
1588
1613
|
}
|
|
1589
1614
|
|
|
1590
|
-
// ../../node_modules/.pnpm/@orama+orama@1.
|
|
1615
|
+
// ../../node_modules/.pnpm/@orama+orama@1.2.1/node_modules/@orama/orama/dist/trees/radix.js
|
|
1591
1616
|
var Node = class {
|
|
1592
1617
|
constructor(key, subWord, end) {
|
|
1593
1618
|
this.key = key;
|
|
@@ -1765,7 +1790,7 @@ function removeDocumentByWord(root, term, docID, exact = true) {
|
|
|
1765
1790
|
return true;
|
|
1766
1791
|
}
|
|
1767
1792
|
|
|
1768
|
-
// ../../node_modules/.pnpm/@orama+orama@1.
|
|
1793
|
+
// ../../node_modules/.pnpm/@orama+orama@1.2.1/node_modules/@orama/orama/dist/components/algorithms.js
|
|
1769
1794
|
function prioritizeTokenScores(arrays, boost, threshold = 1, keywordsCount) {
|
|
1770
1795
|
if (boost === 0) {
|
|
1771
1796
|
throw createError("INVALID_BOOST_VALUE");
|
|
@@ -1829,7 +1854,16 @@ function BM25(tf, matchingCount, docsCount, fieldLength, averageFieldLength, BM2
|
|
|
1829
1854
|
return idf * (d + tf * (k + 1)) / (tf + k * (1 - b + b * fieldLength / averageFieldLength));
|
|
1830
1855
|
}
|
|
1831
1856
|
|
|
1832
|
-
// ../../node_modules/.pnpm/@orama+orama@1.
|
|
1857
|
+
// ../../node_modules/.pnpm/@orama+orama@1.2.1/node_modules/@orama/orama/dist/components/cosine-similarity.js
|
|
1858
|
+
function getMagnitude(vector, vectorLength) {
|
|
1859
|
+
let magnitude = 0;
|
|
1860
|
+
for (let i = 0; i < vectorLength; i++) {
|
|
1861
|
+
magnitude += vector[i] * vector[i];
|
|
1862
|
+
}
|
|
1863
|
+
return Math.sqrt(magnitude);
|
|
1864
|
+
}
|
|
1865
|
+
|
|
1866
|
+
// ../../node_modules/.pnpm/@orama+orama@1.2.1/node_modules/@orama/orama/dist/components/index.js
|
|
1833
1867
|
async function insertDocumentScoreParameters(index, prop, id, tokens, docsCount) {
|
|
1834
1868
|
var _a2;
|
|
1835
1869
|
const internalId = getInternalDocumentId(index.sharedInternalDocumentStore, id);
|
|
@@ -1889,6 +1923,7 @@ async function create4(orama, sharedInternalDocumentStore, schema, index, prefix
|
|
|
1889
1923
|
index = {
|
|
1890
1924
|
sharedInternalDocumentStore,
|
|
1891
1925
|
indexes: {},
|
|
1926
|
+
vectorIndexes: {},
|
|
1892
1927
|
searchableProperties: [],
|
|
1893
1928
|
searchablePropertiesWithTypes: {},
|
|
1894
1929
|
frequencies: {},
|
|
@@ -1904,31 +1939,40 @@ async function create4(orama, sharedInternalDocumentStore, schema, index, prefix
|
|
|
1904
1939
|
create4(orama, sharedInternalDocumentStore, type, index, path);
|
|
1905
1940
|
continue;
|
|
1906
1941
|
}
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
1942
|
+
if (isVectorType(type)) {
|
|
1943
|
+
index.searchableProperties.push(path);
|
|
1944
|
+
index.searchablePropertiesWithTypes[path] = type;
|
|
1945
|
+
index.vectorIndexes[path] = {
|
|
1946
|
+
size: getVectorSize(type),
|
|
1947
|
+
vectors: {}
|
|
1948
|
+
};
|
|
1949
|
+
} else {
|
|
1950
|
+
switch (type) {
|
|
1951
|
+
case "boolean":
|
|
1952
|
+
case "boolean[]":
|
|
1953
|
+
index.indexes[path] = {
|
|
1954
|
+
true: [],
|
|
1955
|
+
false: []
|
|
1956
|
+
};
|
|
1957
|
+
break;
|
|
1958
|
+
case "number":
|
|
1959
|
+
case "number[]":
|
|
1960
|
+
index.indexes[path] = create2(0, []);
|
|
1961
|
+
break;
|
|
1962
|
+
case "string":
|
|
1963
|
+
case "string[]":
|
|
1964
|
+
index.indexes[path] = create3();
|
|
1965
|
+
index.avgFieldLength[path] = 0;
|
|
1966
|
+
index.frequencies[path] = {};
|
|
1967
|
+
index.tokenOccurrences[path] = {};
|
|
1968
|
+
index.fieldLengths[path] = {};
|
|
1969
|
+
break;
|
|
1970
|
+
default:
|
|
1971
|
+
throw createError("INVALID_SCHEMA_TYPE", Array.isArray(type) ? "array" : type, path);
|
|
1972
|
+
}
|
|
1973
|
+
index.searchableProperties.push(path);
|
|
1974
|
+
index.searchablePropertiesWithTypes[path] = type;
|
|
1929
1975
|
}
|
|
1930
|
-
index.searchableProperties.push(path);
|
|
1931
|
-
index.searchablePropertiesWithTypes[path] = type;
|
|
1932
1976
|
}
|
|
1933
1977
|
return index;
|
|
1934
1978
|
}
|
|
@@ -1957,6 +2001,9 @@ async function insertScalar(implementation, index, prop, id, value, schemaType,
|
|
|
1957
2001
|
}
|
|
1958
2002
|
}
|
|
1959
2003
|
async function insert3(implementation, index, prop, id, value, schemaType, language, tokenizer, docsCount) {
|
|
2004
|
+
if (isVectorType(schemaType)) {
|
|
2005
|
+
return insertVector(index, prop, value, id);
|
|
2006
|
+
}
|
|
1960
2007
|
if (!isArrayType(schemaType)) {
|
|
1961
2008
|
return insertScalar(implementation, index, prop, id, value, schemaType, language, tokenizer, docsCount);
|
|
1962
2009
|
}
|
|
@@ -1967,6 +2014,17 @@ async function insert3(implementation, index, prop, id, value, schemaType, langu
|
|
|
1967
2014
|
await insertScalar(implementation, index, prop, id, elements[i], innerSchemaType, language, tokenizer, docsCount);
|
|
1968
2015
|
}
|
|
1969
2016
|
}
|
|
2017
|
+
function insertVector(index, prop, value, id) {
|
|
2018
|
+
if (!(value instanceof Float32Array)) {
|
|
2019
|
+
value = new Float32Array(value);
|
|
2020
|
+
}
|
|
2021
|
+
const size = index.vectorIndexes[prop].size;
|
|
2022
|
+
const magnitude = getMagnitude(value, size);
|
|
2023
|
+
index.vectorIndexes[prop].vectors[id] = [
|
|
2024
|
+
magnitude,
|
|
2025
|
+
value
|
|
2026
|
+
];
|
|
2027
|
+
}
|
|
1970
2028
|
async function removeScalar(implementation, index, prop, id, value, schemaType, language, tokenizer, docsCount) {
|
|
1971
2029
|
const internalId = getInternalDocumentId(index.sharedInternalDocumentStore, id);
|
|
1972
2030
|
switch (schemaType) {
|
|
@@ -2118,8 +2176,9 @@ function loadNode(node) {
|
|
|
2118
2176
|
return convertedNode;
|
|
2119
2177
|
}
|
|
2120
2178
|
async function load3(sharedInternalDocumentStore, raw) {
|
|
2121
|
-
const { indexes: rawIndexes, searchableProperties, searchablePropertiesWithTypes, frequencies, tokenOccurrences, avgFieldLength, fieldLengths } = raw;
|
|
2179
|
+
const { indexes: rawIndexes, vectorIndexes: rawVectorIndexes, searchableProperties, searchablePropertiesWithTypes, frequencies, tokenOccurrences, avgFieldLength, fieldLengths } = raw;
|
|
2122
2180
|
const indexes = {};
|
|
2181
|
+
const vectorIndexes = {};
|
|
2123
2182
|
for (const prop of Object.keys(rawIndexes)) {
|
|
2124
2183
|
const value = rawIndexes[prop];
|
|
2125
2184
|
if (!("word" in value)) {
|
|
@@ -2128,9 +2187,23 @@ async function load3(sharedInternalDocumentStore, raw) {
|
|
|
2128
2187
|
}
|
|
2129
2188
|
indexes[prop] = loadNode(value);
|
|
2130
2189
|
}
|
|
2190
|
+
for (const idx of Object.keys(rawVectorIndexes)) {
|
|
2191
|
+
const vectors = rawVectorIndexes[idx].vectors;
|
|
2192
|
+
for (const vec in vectors) {
|
|
2193
|
+
vectors[vec] = [
|
|
2194
|
+
vectors[vec][0],
|
|
2195
|
+
new Float32Array(vectors[vec][1])
|
|
2196
|
+
];
|
|
2197
|
+
}
|
|
2198
|
+
vectorIndexes[idx] = {
|
|
2199
|
+
size: rawVectorIndexes[idx].size,
|
|
2200
|
+
vectors
|
|
2201
|
+
};
|
|
2202
|
+
}
|
|
2131
2203
|
return {
|
|
2132
2204
|
sharedInternalDocumentStore,
|
|
2133
2205
|
indexes,
|
|
2206
|
+
vectorIndexes,
|
|
2134
2207
|
searchableProperties,
|
|
2135
2208
|
searchablePropertiesWithTypes,
|
|
2136
2209
|
frequencies,
|
|
@@ -2140,9 +2213,24 @@ async function load3(sharedInternalDocumentStore, raw) {
|
|
|
2140
2213
|
};
|
|
2141
2214
|
}
|
|
2142
2215
|
async function save3(index) {
|
|
2143
|
-
const { indexes, searchableProperties, searchablePropertiesWithTypes, frequencies, tokenOccurrences, avgFieldLength, fieldLengths } = index;
|
|
2216
|
+
const { indexes, vectorIndexes, searchableProperties, searchablePropertiesWithTypes, frequencies, tokenOccurrences, avgFieldLength, fieldLengths } = index;
|
|
2217
|
+
const vectorIndexesAsArrays = {};
|
|
2218
|
+
for (const idx of Object.keys(vectorIndexes)) {
|
|
2219
|
+
const vectors = vectorIndexes[idx].vectors;
|
|
2220
|
+
for (const vec in vectors) {
|
|
2221
|
+
vectors[vec] = [
|
|
2222
|
+
vectors[vec][0],
|
|
2223
|
+
Array.from(vectors[vec][1])
|
|
2224
|
+
];
|
|
2225
|
+
}
|
|
2226
|
+
vectorIndexesAsArrays[idx] = {
|
|
2227
|
+
size: vectorIndexes[idx].size,
|
|
2228
|
+
vectors
|
|
2229
|
+
};
|
|
2230
|
+
}
|
|
2144
2231
|
return {
|
|
2145
2232
|
indexes,
|
|
2233
|
+
vectorIndexes: vectorIndexesAsArrays,
|
|
2146
2234
|
searchableProperties,
|
|
2147
2235
|
searchablePropertiesWithTypes,
|
|
2148
2236
|
frequencies,
|
|
@@ -2170,7 +2258,7 @@ async function createIndex() {
|
|
|
2170
2258
|
};
|
|
2171
2259
|
}
|
|
2172
2260
|
|
|
2173
|
-
// ../../node_modules/.pnpm/@orama+orama@1.
|
|
2261
|
+
// ../../node_modules/.pnpm/@orama+orama@1.2.1/node_modules/@orama/orama/dist/components/tokenizer/diacritics.js
|
|
2174
2262
|
var DIACRITICS_CHARCODE_START = 192;
|
|
2175
2263
|
var DIACRITICS_CHARCODE_END = 383;
|
|
2176
2264
|
var CHARCODE_REPLACE_MAPPING = [
|
|
@@ -2380,7 +2468,7 @@ function replaceDiacritics(str) {
|
|
|
2380
2468
|
return String.fromCharCode(...stringCharCode);
|
|
2381
2469
|
}
|
|
2382
2470
|
|
|
2383
|
-
// ../../node_modules/.pnpm/@orama+orama@1.
|
|
2471
|
+
// ../../node_modules/.pnpm/@orama+orama@1.2.1/node_modules/@orama/orama/dist/components/tokenizer/english-stemmer.js
|
|
2384
2472
|
var step2List = {
|
|
2385
2473
|
ational: "ate",
|
|
2386
2474
|
tional: "tion",
|
|
@@ -2540,7 +2628,7 @@ function stemmer(w) {
|
|
|
2540
2628
|
return w;
|
|
2541
2629
|
}
|
|
2542
2630
|
|
|
2543
|
-
// ../../node_modules/.pnpm/@orama+orama@1.
|
|
2631
|
+
// ../../node_modules/.pnpm/@orama+orama@1.2.1/node_modules/@orama/orama/dist/components/tokenizer/index.js
|
|
2544
2632
|
function normalizeToken(prop, token) {
|
|
2545
2633
|
var _this_stopWords;
|
|
2546
2634
|
const key = `${this.language}:${prop}:${token}`;
|
|
@@ -2641,7 +2729,7 @@ async function createTokenizer(config = {}) {
|
|
|
2641
2729
|
return tokenizer;
|
|
2642
2730
|
}
|
|
2643
2731
|
|
|
2644
|
-
// ../../node_modules/.pnpm/@orama+orama@1.
|
|
2732
|
+
// ../../node_modules/.pnpm/@orama+orama@1.2.1/node_modules/@orama/orama/dist/components/sorter.js
|
|
2645
2733
|
function innerCreate(orama, sharedInternalDocumentStore, schema, sortableDeniedProperties, prefix) {
|
|
2646
2734
|
const sorter = {
|
|
2647
2735
|
language: orama.tokenizer.language,
|
|
@@ -2665,25 +2753,27 @@ function innerCreate(orama, sharedInternalDocumentStore, schema, sortableDeniedP
|
|
|
2665
2753
|
sorter.sortablePropertiesWithTypes = __spreadValues(__spreadValues({}, sorter.sortablePropertiesWithTypes), ret.sortablePropertiesWithTypes);
|
|
2666
2754
|
continue;
|
|
2667
2755
|
}
|
|
2668
|
-
|
|
2669
|
-
|
|
2670
|
-
|
|
2671
|
-
|
|
2672
|
-
|
|
2673
|
-
|
|
2674
|
-
|
|
2675
|
-
|
|
2676
|
-
|
|
2677
|
-
|
|
2678
|
-
|
|
2679
|
-
|
|
2680
|
-
|
|
2681
|
-
|
|
2682
|
-
|
|
2683
|
-
|
|
2684
|
-
|
|
2685
|
-
|
|
2686
|
-
|
|
2756
|
+
if (!isVectorType(type)) {
|
|
2757
|
+
switch (type) {
|
|
2758
|
+
case "boolean":
|
|
2759
|
+
case "number":
|
|
2760
|
+
case "string":
|
|
2761
|
+
sorter.sortableProperties.push(path);
|
|
2762
|
+
sorter.sortablePropertiesWithTypes[path] = type;
|
|
2763
|
+
sorter.sorts[path] = {
|
|
2764
|
+
docs: /* @__PURE__ */ new Map(),
|
|
2765
|
+
orderedDocsToRemove: /* @__PURE__ */ new Map(),
|
|
2766
|
+
orderedDocs: [],
|
|
2767
|
+
type
|
|
2768
|
+
};
|
|
2769
|
+
break;
|
|
2770
|
+
case "boolean[]":
|
|
2771
|
+
case "number[]":
|
|
2772
|
+
case "string[]":
|
|
2773
|
+
continue;
|
|
2774
|
+
default:
|
|
2775
|
+
throw createError("INVALID_SORT_SCHEMA_TYPE", Array.isArray(type) ? "array" : type, path);
|
|
2776
|
+
}
|
|
2687
2777
|
}
|
|
2688
2778
|
}
|
|
2689
2779
|
return sorter;
|
|
@@ -2889,7 +2979,7 @@ async function createSorter() {
|
|
|
2889
2979
|
};
|
|
2890
2980
|
}
|
|
2891
2981
|
|
|
2892
|
-
// ../../node_modules/.pnpm/@orama+orama@1.
|
|
2982
|
+
// ../../node_modules/.pnpm/@orama+orama@1.2.1/node_modules/@orama/orama/dist/methods/create.js
|
|
2893
2983
|
function validateComponents(components) {
|
|
2894
2984
|
const defaultComponents = {
|
|
2895
2985
|
formatElapsedTime,
|
|
@@ -2992,11 +3082,11 @@ async function create6({ schema, sort, language, components, id }) {
|
|
|
2992
3082
|
return orama;
|
|
2993
3083
|
}
|
|
2994
3084
|
|
|
2995
|
-
// ../../node_modules/.pnpm/@orama+orama@1.
|
|
3085
|
+
// ../../node_modules/.pnpm/@orama+orama@1.2.1/node_modules/@orama/orama/dist/types.js
|
|
2996
3086
|
var kInsertions = Symbol("orama.insertions");
|
|
2997
3087
|
var kRemovals = Symbol("orama.removals");
|
|
2998
3088
|
|
|
2999
|
-
// ../../node_modules/.pnpm/@orama+orama@1.
|
|
3089
|
+
// ../../node_modules/.pnpm/@orama+orama@1.2.1/node_modules/@orama/orama/dist/components/sync-blocking-checker.js
|
|
3000
3090
|
var _globalThis_process;
|
|
3001
3091
|
var _a;
|
|
3002
3092
|
var warn = (_a = (_globalThis_process = globalThis.process) === null || _globalThis_process === void 0 ? void 0 : _globalThis_process.emitWarning) != null ? _a : function emitWarning(message, options) {
|
|
@@ -3035,7 +3125,7 @@ function trackRemoval(orama) {
|
|
|
3035
3125
|
}
|
|
3036
3126
|
}
|
|
3037
3127
|
|
|
3038
|
-
// ../../node_modules/.pnpm/@orama+orama@1.
|
|
3128
|
+
// ../../node_modules/.pnpm/@orama+orama@1.2.1/node_modules/@orama/orama/dist/methods/insert.js
|
|
3039
3129
|
async function insert5(orama, doc, language, skipHooks) {
|
|
3040
3130
|
const errorProperty = await orama.validateSchema(doc, orama.schema);
|
|
3041
3131
|
if (errorProperty) {
|
|
@@ -3065,6 +3155,9 @@ async function innerInsert(orama, doc, language, skipHooks) {
|
|
|
3065
3155
|
}
|
|
3066
3156
|
const actualType = typeof value;
|
|
3067
3157
|
const expectedType = indexablePropertiesWithTypes[key];
|
|
3158
|
+
if (isVectorType(expectedType) && Array.isArray(value)) {
|
|
3159
|
+
continue;
|
|
3160
|
+
}
|
|
3068
3161
|
if (isArrayType(expectedType) && Array.isArray(value)) {
|
|
3069
3162
|
continue;
|
|
3070
3163
|
}
|
|
@@ -3101,7 +3194,7 @@ async function innerInsert(orama, doc, language, skipHooks) {
|
|
|
3101
3194
|
return id;
|
|
3102
3195
|
}
|
|
3103
3196
|
|
|
3104
|
-
// ../../node_modules/.pnpm/@orama+orama@1.
|
|
3197
|
+
// ../../node_modules/.pnpm/@orama+orama@1.2.1/node_modules/@orama/orama/dist/methods/remove.js
|
|
3105
3198
|
async function remove5(orama, id, language, skipHooks) {
|
|
3106
3199
|
let result = true;
|
|
3107
3200
|
const { index, docs } = orama.data;
|
|
@@ -3146,7 +3239,7 @@ async function remove5(orama, id, language, skipHooks) {
|
|
|
3146
3239
|
return result;
|
|
3147
3240
|
}
|
|
3148
3241
|
|
|
3149
|
-
// ../../node_modules/.pnpm/@orama+orama@1.
|
|
3242
|
+
// ../../node_modules/.pnpm/@orama+orama@1.2.1/node_modules/@orama/orama/dist/components/facets.js
|
|
3150
3243
|
function sortingPredicate(order = "desc", a, b) {
|
|
3151
3244
|
if (order.toLowerCase() === "asc") {
|
|
3152
3245
|
return a[1] - b[1];
|
|
@@ -3255,7 +3348,7 @@ function calculateBooleanOrStringFacet(values, facetValue, propertyType, already
|
|
|
3255
3348
|
}
|
|
3256
3349
|
}
|
|
3257
3350
|
|
|
3258
|
-
// ../../node_modules/.pnpm/@orama+orama@1.
|
|
3351
|
+
// ../../node_modules/.pnpm/@orama+orama@1.2.1/node_modules/@orama/orama/dist/components/filters.js
|
|
3259
3352
|
function intersectFilteredIDs(filtered, lookedUp) {
|
|
3260
3353
|
const map = /* @__PURE__ */ new Map();
|
|
3261
3354
|
const result = [];
|
|
@@ -3274,7 +3367,7 @@ function intersectFilteredIDs(filtered, lookedUp) {
|
|
|
3274
3367
|
return result;
|
|
3275
3368
|
}
|
|
3276
3369
|
|
|
3277
|
-
// ../../node_modules/.pnpm/@orama+orama@1.
|
|
3370
|
+
// ../../node_modules/.pnpm/@orama+orama@1.2.1/node_modules/@orama/orama/dist/components/groups.js
|
|
3278
3371
|
var DEFAULT_REDUCE = {
|
|
3279
3372
|
reducer: (_, acc, res, index) => {
|
|
3280
3373
|
acc[index] = res;
|
|
@@ -3404,7 +3497,7 @@ function calculateCombination(arrs, index = 0) {
|
|
|
3404
3497
|
return combinations;
|
|
3405
3498
|
}
|
|
3406
3499
|
|
|
3407
|
-
// ../../node_modules/.pnpm/@orama+orama@1.
|
|
3500
|
+
// ../../node_modules/.pnpm/@orama+orama@1.2.1/node_modules/@orama/orama/dist/methods/search.js
|
|
3408
3501
|
var defaultBM25Params = {
|
|
3409
3502
|
k: 1.2,
|
|
3410
3503
|
b: 0.75,
|
|
@@ -3628,6 +3721,7 @@ var debug = (0, import_debug.default)("verdaccio:search:indexer");
|
|
|
3628
3721
|
var SearchMemoryIndexer = class {
|
|
3629
3722
|
database;
|
|
3630
3723
|
storage;
|
|
3724
|
+
logger;
|
|
3631
3725
|
configureStorage(storage) {
|
|
3632
3726
|
this.storage = storage;
|
|
3633
3727
|
}
|
|
@@ -3635,24 +3729,32 @@ var SearchMemoryIndexer = class {
|
|
|
3635
3729
|
if (this.database) {
|
|
3636
3730
|
debug("searching %s at indexer", term);
|
|
3637
3731
|
const searchResult = await search2(this.database, {
|
|
3638
|
-
term
|
|
3639
|
-
properties: "*"
|
|
3732
|
+
term
|
|
3640
3733
|
});
|
|
3641
3734
|
return searchResult;
|
|
3642
3735
|
}
|
|
3643
3736
|
}
|
|
3737
|
+
prepareKeywords(keywords) {
|
|
3738
|
+
if (typeof keywords === "undefined") {
|
|
3739
|
+
return "";
|
|
3740
|
+
} else if (typeof keywords === "string") {
|
|
3741
|
+
return keywords;
|
|
3742
|
+
}
|
|
3743
|
+
return keywords.join(",");
|
|
3744
|
+
}
|
|
3644
3745
|
async add(pkg) {
|
|
3645
3746
|
if (this.database) {
|
|
3646
3747
|
const name = pkg.name;
|
|
3647
3748
|
debug("adding item %s to the indexer", name);
|
|
3648
|
-
|
|
3749
|
+
const item = {
|
|
3649
3750
|
id: name,
|
|
3650
3751
|
name,
|
|
3651
3752
|
description: pkg.description,
|
|
3652
|
-
version:
|
|
3653
|
-
keywords: pkg.keywords,
|
|
3654
|
-
author: pkg._npmUser ? pkg._npmUser.name : "
|
|
3655
|
-
}
|
|
3753
|
+
version: pkg.version,
|
|
3754
|
+
keywords: this.prepareKeywords(pkg.keywords),
|
|
3755
|
+
author: pkg._npmUser ? pkg._npmUser.name : ""
|
|
3756
|
+
};
|
|
3757
|
+
await insert5(this.database, item);
|
|
3656
3758
|
}
|
|
3657
3759
|
}
|
|
3658
3760
|
async remove(name) {
|
|
@@ -3661,10 +3763,11 @@ var SearchMemoryIndexer = class {
|
|
|
3661
3763
|
await remove5(this.database, name);
|
|
3662
3764
|
}
|
|
3663
3765
|
}
|
|
3664
|
-
reindex() {
|
|
3766
|
+
async reindex() {
|
|
3665
3767
|
var _a2;
|
|
3666
3768
|
debug("reindexing search indexer");
|
|
3667
|
-
(_a2 = this.storage) == null ? void 0 : _a2.getLocalDatabase((error, packages) => {
|
|
3769
|
+
(_a2 = this.storage) == null ? void 0 : _a2.getLocalDatabase(async (error, packages) => {
|
|
3770
|
+
var _a3;
|
|
3668
3771
|
if (error) {
|
|
3669
3772
|
throw error;
|
|
3670
3773
|
}
|
|
@@ -3675,12 +3778,17 @@ var SearchMemoryIndexer = class {
|
|
|
3675
3778
|
while (i--) {
|
|
3676
3779
|
const pkg = packages[i];
|
|
3677
3780
|
debug("indexing package %s", pkg == null ? void 0 : pkg.name);
|
|
3678
|
-
|
|
3781
|
+
try {
|
|
3782
|
+
await this.add(pkg);
|
|
3783
|
+
} catch (err) {
|
|
3784
|
+
(_a3 = this.logger) == null ? void 0 : _a3.error({ err: err.message }, "error @{err} indexing package");
|
|
3785
|
+
}
|
|
3679
3786
|
}
|
|
3680
3787
|
debug("reindexed search indexer");
|
|
3681
3788
|
});
|
|
3682
3789
|
}
|
|
3683
|
-
async init() {
|
|
3790
|
+
async init(logger) {
|
|
3791
|
+
this.logger = logger;
|
|
3684
3792
|
this.database = await create6({
|
|
3685
3793
|
schema: {
|
|
3686
3794
|
id: "string",
|
package/build/indexer.d.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { Version } from '@verdaccio/types';
|
|
1
|
+
import { Logger, Version } from '@verdaccio/types';
|
|
2
2
|
type Results = any;
|
|
3
3
|
declare class SearchMemoryIndexer {
|
|
4
4
|
private database;
|
|
5
5
|
private storage;
|
|
6
|
+
private logger;
|
|
6
7
|
/**
|
|
7
8
|
* Set up the {Storage}
|
|
8
9
|
* @param {*} storage An storage reference.
|
|
@@ -16,6 +17,7 @@ declare class SearchMemoryIndexer {
|
|
|
16
17
|
* @return {Array} list of results.
|
|
17
18
|
*/
|
|
18
19
|
query(term: string): Promise<Results | void>;
|
|
20
|
+
private prepareKeywords;
|
|
19
21
|
/**
|
|
20
22
|
* Add a new element to index
|
|
21
23
|
* @param {*} pkg the package
|
|
@@ -29,8 +31,8 @@ declare class SearchMemoryIndexer {
|
|
|
29
31
|
/**
|
|
30
32
|
* Force a re-index.
|
|
31
33
|
*/
|
|
32
|
-
reindex(): void
|
|
33
|
-
init(): Promise<void>;
|
|
34
|
+
reindex(): Promise<void>;
|
|
35
|
+
init(logger: Logger): Promise<void>;
|
|
34
36
|
}
|
|
35
37
|
declare const _default: SearchMemoryIndexer;
|
|
36
38
|
export default _default;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@verdaccio/search",
|
|
3
|
-
"version": "7.0.0-next.
|
|
3
|
+
"version": "7.0.0-next.1",
|
|
4
4
|
"description": "verdaccio search utitlity tools",
|
|
5
5
|
"main": "./build/dist.js",
|
|
6
6
|
"types": "build/index.d.ts",
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
},
|
|
32
32
|
"devDependencies": {
|
|
33
33
|
"@verdaccio/types": "12.0.0-next.0",
|
|
34
|
-
"@orama/orama": "1.
|
|
34
|
+
"@orama/orama": "1.2.1",
|
|
35
35
|
"debug": "4.3.4",
|
|
36
36
|
"esbuild": "0.14.10"
|
|
37
37
|
},
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
},
|
|
42
42
|
"scripts": {
|
|
43
43
|
"clean": "rimraf ./build",
|
|
44
|
-
"test": "
|
|
44
|
+
"test": "vitest run",
|
|
45
45
|
"type-check": "tsc --noEmit -p tsconfig.build.json",
|
|
46
46
|
"build:types": "tsc --emitDeclarationOnly -p tsconfig.build.json",
|
|
47
47
|
"build:js": "babel src/ --out-dir build/ --copy-files --extensions \".ts,.tsx\" --source-maps",
|
package/src/indexer.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { create, insert, remove, search } from '@orama/orama';
|
|
2
2
|
import buildDebug from 'debug';
|
|
3
3
|
|
|
4
|
-
import { Version } from '@verdaccio/types';
|
|
4
|
+
import { Logger, Version } from '@verdaccio/types';
|
|
5
5
|
|
|
6
6
|
const debug = buildDebug('verdaccio:search:indexer');
|
|
7
7
|
|
|
@@ -10,6 +10,7 @@ type Results = any;
|
|
|
10
10
|
class SearchMemoryIndexer {
|
|
11
11
|
private database: any | undefined;
|
|
12
12
|
private storage: any;
|
|
13
|
+
private logger: Logger | undefined;
|
|
13
14
|
|
|
14
15
|
/**
|
|
15
16
|
* Set up the {Storage}
|
|
@@ -31,13 +32,21 @@ class SearchMemoryIndexer {
|
|
|
31
32
|
debug('searching %s at indexer', term);
|
|
32
33
|
const searchResult = await search(this.database, {
|
|
33
34
|
term,
|
|
34
|
-
properties: '*',
|
|
35
35
|
});
|
|
36
36
|
|
|
37
37
|
return searchResult;
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
+
private prepareKeywords(keywords?: string[] | string): string {
|
|
42
|
+
if (typeof keywords === 'undefined') {
|
|
43
|
+
return '';
|
|
44
|
+
} else if (typeof keywords === 'string') {
|
|
45
|
+
return keywords;
|
|
46
|
+
}
|
|
47
|
+
return keywords.join(',');
|
|
48
|
+
}
|
|
49
|
+
|
|
41
50
|
/**
|
|
42
51
|
* Add a new element to index
|
|
43
52
|
* @param {*} pkg the package
|
|
@@ -46,14 +55,15 @@ class SearchMemoryIndexer {
|
|
|
46
55
|
if (this.database) {
|
|
47
56
|
const name = pkg.name;
|
|
48
57
|
debug('adding item %s to the indexer', name);
|
|
49
|
-
|
|
58
|
+
const item = {
|
|
50
59
|
id: name,
|
|
51
60
|
name: name,
|
|
52
61
|
description: pkg.description,
|
|
53
|
-
version:
|
|
54
|
-
keywords: pkg.keywords,
|
|
55
|
-
author: pkg._npmUser ? pkg._npmUser.name : '
|
|
56
|
-
}
|
|
62
|
+
version: pkg.version,
|
|
63
|
+
keywords: this.prepareKeywords(pkg.keywords),
|
|
64
|
+
author: pkg._npmUser ? pkg._npmUser.name : '',
|
|
65
|
+
};
|
|
66
|
+
await insert(this.database, item);
|
|
57
67
|
}
|
|
58
68
|
}
|
|
59
69
|
|
|
@@ -71,9 +81,9 @@ class SearchMemoryIndexer {
|
|
|
71
81
|
/**
|
|
72
82
|
* Force a re-index.
|
|
73
83
|
*/
|
|
74
|
-
public reindex(): void {
|
|
84
|
+
public async reindex(): Promise<void> {
|
|
75
85
|
debug('reindexing search indexer');
|
|
76
|
-
this.storage?.getLocalDatabase((error, packages): void => {
|
|
86
|
+
this.storage?.getLocalDatabase(async (error, packages): Promise<void> => {
|
|
77
87
|
if (error) {
|
|
78
88
|
// that function shouldn't produce any
|
|
79
89
|
throw error;
|
|
@@ -86,13 +96,18 @@ class SearchMemoryIndexer {
|
|
|
86
96
|
while (i--) {
|
|
87
97
|
const pkg = packages[i];
|
|
88
98
|
debug('indexing package %s', pkg?.name);
|
|
89
|
-
|
|
99
|
+
try {
|
|
100
|
+
await this.add(pkg);
|
|
101
|
+
} catch (err: any) {
|
|
102
|
+
this.logger?.error({ err: err.message }, 'error @{err} indexing package');
|
|
103
|
+
}
|
|
90
104
|
}
|
|
91
105
|
debug('reindexed search indexer');
|
|
92
106
|
});
|
|
93
107
|
}
|
|
94
108
|
|
|
95
|
-
public async init() {
|
|
109
|
+
public async init(logger: Logger) {
|
|
110
|
+
this.logger = logger;
|
|
96
111
|
this.database = await create({
|
|
97
112
|
schema: {
|
|
98
113
|
id: 'string',
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { expect, test } from 'vitest';
|
|
2
|
+
|
|
3
|
+
import { Logger } from '@verdaccio/types';
|
|
4
|
+
|
|
5
|
+
import { SearchMemoryIndexer } from '../src';
|
|
6
|
+
|
|
7
|
+
class MockStore {
|
|
8
|
+
getLocalDatabase(cb) {
|
|
9
|
+
return cb(null, [
|
|
10
|
+
{
|
|
11
|
+
name: 'verdaccio-search',
|
|
12
|
+
version: '1.0.0',
|
|
13
|
+
readme: 'foo',
|
|
14
|
+
description: 'foo',
|
|
15
|
+
keywords: ['foo', 'bar'],
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
name: 'verdaccio-utils',
|
|
19
|
+
version: '2.0.0',
|
|
20
|
+
readme: 'foo',
|
|
21
|
+
description: 'foo',
|
|
22
|
+
keywords: 'some',
|
|
23
|
+
},
|
|
24
|
+
]);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const logger = {
|
|
29
|
+
// eslint-disable-next-line no-console
|
|
30
|
+
error: (...arg) => console.error(...arg),
|
|
31
|
+
} as Logger;
|
|
32
|
+
|
|
33
|
+
test('should search', async () => {
|
|
34
|
+
const store = new MockStore();
|
|
35
|
+
|
|
36
|
+
SearchMemoryIndexer.configureStorage(store);
|
|
37
|
+
await SearchMemoryIndexer.init(logger);
|
|
38
|
+
// @ts-expect-error
|
|
39
|
+
await SearchMemoryIndexer.add({
|
|
40
|
+
name: 'verdaccio',
|
|
41
|
+
version: '2.0.0',
|
|
42
|
+
readme: 'foo',
|
|
43
|
+
description: '',
|
|
44
|
+
});
|
|
45
|
+
const query = await SearchMemoryIndexer.query('verdaccio');
|
|
46
|
+
expect(query.hits.map((item) => item.id)).toEqual(['verdaccio', 'verdaccio-utils']);
|
|
47
|
+
});
|