@based/db 0.0.16 → 0.0.17
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/dist/lib/darwin_aarch64/include/selva/db.h +3 -0
- package/dist/lib/darwin_aarch64/include/selva/fields.h +1 -2
- package/dist/lib/darwin_aarch64/include/selva/history.h +16 -1
- package/dist/lib/darwin_aarch64/include/selva/types.h +4 -0
- package/dist/lib/darwin_aarch64/libnode-v20.11.1.node +0 -0
- package/dist/lib/darwin_aarch64/libnode-v20.18.1.node +0 -0
- package/dist/lib/darwin_aarch64/libnode-v22.13.0.node +0 -0
- package/dist/lib/darwin_aarch64/libselva.dylib +0 -0
- package/dist/lib/linux_aarch64/include/selva/db.h +3 -0
- package/dist/lib/linux_aarch64/include/selva/fields.h +1 -2
- package/dist/lib/linux_aarch64/include/selva/history.h +16 -1
- package/dist/lib/linux_aarch64/include/selva/types.h +4 -0
- package/dist/lib/linux_aarch64/libnode-v20.11.1.node +0 -0
- package/dist/lib/linux_aarch64/libnode-v20.18.1.node +0 -0
- package/dist/lib/linux_aarch64/libnode-v22.13.0.node +0 -0
- package/dist/lib/linux_aarch64/libselva.so +0 -0
- package/dist/lib/linux_x86_64/include/selva/db.h +3 -0
- package/dist/lib/linux_x86_64/include/selva/fields.h +1 -2
- package/dist/lib/linux_x86_64/include/selva/history.h +16 -1
- package/dist/lib/linux_x86_64/include/selva/types.h +4 -0
- package/dist/lib/linux_x86_64/libnode-v20.11.1.node +0 -0
- package/dist/lib/linux_x86_64/libnode-v20.18.1.node +0 -0
- package/dist/lib/linux_x86_64/libnode-v22.13.0.node +0 -0
- package/dist/lib/linux_x86_64/libselva.so +0 -0
- package/dist/src/client/crc32.js +0 -276
- package/dist/src/client/modify/ModifyRes.d.ts +4 -2
- package/dist/src/client/modify/ModifyRes.js +11 -6
- package/dist/src/client/modify/alias.js +2 -2
- package/dist/src/client/modify/cardinality.js +6 -1
- package/dist/src/client/modify/create.js +8 -9
- package/dist/src/client/modify/references/reference.js +14 -7
- package/dist/src/client/modify/references/references.js +10 -4
- package/dist/src/client/modify/string.js +2 -2
- package/dist/src/client/modify/text.js +1 -1
- package/dist/src/client/modify/types.d.ts +3 -1
- package/dist/src/client/modify/types.js +2 -0
- package/dist/src/client/modify/update.js +1 -1
- package/dist/src/client/operations.d.ts +2 -2
- package/dist/src/client/operations.js +19 -3
- package/dist/src/client/query/BasedDbQuery.d.ts +4 -3
- package/dist/src/client/query/BasedDbQuery.js +14 -6
- package/dist/src/client/query/BasedIterable.js +3 -10
- package/dist/src/client/query/display.d.ts +6 -0
- package/dist/src/client/query/display.js +52 -1
- package/dist/src/client/query/filter/createFixedFilterBuffer.js +9 -8
- package/dist/src/client/query/filter/createReferenceFilter.js +5 -4
- package/dist/src/client/query/filter/createVariableFilterBuffer.js +6 -10
- package/dist/src/client/query/filter/toBuffer.js +1 -6
- package/dist/src/client/query/include/props.js +14 -6
- package/dist/src/client/query/include/utils.js +2 -2
- package/dist/src/client/query/include/walk.js +1 -7
- package/dist/src/client/query/queryDef.d.ts +1 -1
- package/dist/src/client/query/queryDef.js +4 -3
- package/dist/src/client/query/registerQuery.js +1 -0
- package/dist/src/client/query/search/index.js +12 -6
- package/dist/src/client/query/sort.js +7 -6
- package/dist/src/client/query/thresholds.d.ts +0 -1
- package/dist/src/client/query/thresholds.js +0 -8
- package/dist/src/client/query/toBuffer.js +0 -3
- package/dist/src/client/query/types.d.ts +2 -0
- package/dist/src/client/query/validation.d.ts +32 -0
- package/dist/src/client/query/validation.js +237 -114
- package/dist/src/index.d.ts +3 -1
- package/dist/src/index.js +17 -2
- package/dist/src/native.d.ts +2 -0
- package/dist/src/native.js +6 -0
- package/dist/src/server/index.d.ts +8 -6
- package/dist/src/server/index.js +56 -30
- package/dist/src/server/migrate/index.js +10 -2
- package/dist/src/server/migrate/worker.js +1 -1
- package/dist/src/server/schema/typeDef.js +35 -25
- package/dist/src/server/schema/types.d.ts +10 -5
- package/dist/src/server/schema/types.js +1 -1
- package/package.json +5 -3
|
@@ -1,7 +1,10 @@
|
|
|
1
|
-
import
|
|
1
|
+
import picocolors from 'picocolors';
|
|
2
|
+
import { ALIAS, BINARY, BOOLEAN, REFERENCE, REFERENCES, REVERSE_TYPE_INDEX_MAP, STRING, TEXT, TIMESTAMP, VECTOR, } from '../../server/schema/types.js';
|
|
2
3
|
import { propIsNumerical } from '../../server/schema/utils.js';
|
|
3
4
|
import { EQUAL, HAS, isNumerical, LIKE, operatorReverseMap, VECTOR_FNS, } from './filter/types.js';
|
|
4
5
|
import { MAX_ID, MAX_ID_VALUE, MAX_IDS_PER_QUERY, MIN_ID_VALUE, } from './thresholds.js';
|
|
6
|
+
import { displayTarget, safeStringify } from './display.js';
|
|
7
|
+
import { langCodesMap } from '@based/schema';
|
|
5
8
|
export const ERR_TARGET_INVAL_TYPE = 1;
|
|
6
9
|
export const ERR_TARGET_INVAL_ALIAS = 2;
|
|
7
10
|
export const ERR_TARGET_EXCEED_MAX_IDS = 3;
|
|
@@ -15,23 +18,24 @@ export const ERR_FILTER_INVALID_VAL = 10;
|
|
|
15
18
|
export const ERR_FILTER_INVALID_OPTS = 11;
|
|
16
19
|
export const ERR_FILTER_INVALID_LANG = 12;
|
|
17
20
|
export const ERR_INCLUDE_INVALID_LANG = 13;
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
21
|
+
export const ERR_SORT_ENOENT = 14;
|
|
22
|
+
export const ERR_SORT_TYPE = 15;
|
|
23
|
+
export const ERR_SORT_ORDER = 16;
|
|
24
|
+
export const ERR_SORT_WRONG_TARGET = 17;
|
|
25
|
+
export const ERR_RANGE_INVALID_OFFSET = 18;
|
|
26
|
+
export const ERR_RANGE_INVALID_LIMIT = 19;
|
|
27
|
+
export const ERR_INVALID_LANG = 20;
|
|
28
|
+
export const ERR_SEARCH_ENOENT = 21;
|
|
29
|
+
export const ERR_SEARCH_TYPE = 22;
|
|
30
|
+
export const ERR_SEARCH_INCORRECT_VALUE = 23;
|
|
31
|
+
export const ERR_SORT_LANG = 24;
|
|
28
32
|
const messages = {
|
|
29
33
|
[ERR_TARGET_INVAL_TYPE]: (p) => `Type "${p}" does not exist`,
|
|
30
34
|
[ERR_TARGET_INVAL_ALIAS]: (p) => {
|
|
31
|
-
return `Invalid alias prodived to query
|
|
35
|
+
return `Invalid alias prodived to query\n ${picocolors.italic(safeStringify(p, 100))}`;
|
|
32
36
|
},
|
|
33
37
|
[ERR_TARGET_EXCEED_MAX_IDS]: (p) => `Exceeds max ids ${~~(p.length / 1e3)}k (max ${MAX_IDS_PER_QUERY / 1e3}k)`,
|
|
34
|
-
[ERR_TARGET_INVAL_IDS]: (p) => `Ids should be of type array or Uint32Array with valid ids`,
|
|
38
|
+
[ERR_TARGET_INVAL_IDS]: (p) => `Ids should be of type array or Uint32Array with valid ids \n ${picocolors.italic(safeStringify(p, 100))}`,
|
|
35
39
|
[ERR_TARGET_INVAL_ID]: (p) => `Invalid id should be a number larger then 0 "${p}"`,
|
|
36
40
|
[ERR_INCLUDE_ENOENT]: (p) => `Include: field does not exist "${p}"`,
|
|
37
41
|
[ERR_INCLUDE_INVALID_LANG]: (p) => `Include: invalid lang "${p}"`,
|
|
@@ -45,108 +49,144 @@ const messages = {
|
|
|
45
49
|
[ERR_FILTER_INVALID_VAL]: (p) => {
|
|
46
50
|
return `Filter: Invalid value ${p[0]} ${operatorReverseMap[p[1].operation]} "${safeStringify(p[2])}"`;
|
|
47
51
|
},
|
|
52
|
+
[ERR_SORT_ENOENT]: (p) => `Sort: field does not exist "${p}"`,
|
|
53
|
+
[ERR_SORT_WRONG_TARGET]: (p) => `Sort: incorrect qeury target "${displayTarget(p)}"`,
|
|
54
|
+
[ERR_SORT_ORDER]: (p) => `Sort: incorrect order option "${safeStringify(p.order)}" passed to sort "${p.field}"`,
|
|
55
|
+
[ERR_SORT_TYPE]: (p) => `Sort: cannot sort on type "${REVERSE_TYPE_INDEX_MAP[p.typeIndex]}" on field "${p.path.join('.')}"`,
|
|
56
|
+
[ERR_RANGE_INVALID_OFFSET]: (p) => `Range: incorrect offset "${safeStringify(p)}"`,
|
|
57
|
+
[ERR_RANGE_INVALID_LIMIT]: (p) => `Range: incorrect limit "${safeStringify(p)}"`,
|
|
58
|
+
[ERR_INVALID_LANG]: (p) => `Invalid locale "${p}"`,
|
|
59
|
+
[ERR_SEARCH_ENOENT]: (p) => `Search: field does not exist "${p}"`,
|
|
60
|
+
[ERR_SEARCH_TYPE]: (p) => `Search: incorrect type "${p.path.join('.')}"`,
|
|
61
|
+
[ERR_SEARCH_INCORRECT_VALUE]: (p) => `Search: incorrect query on field "${safeStringify(p)}"`,
|
|
62
|
+
[ERR_SORT_LANG]: (p) => `Sort: invalid lang`,
|
|
63
|
+
};
|
|
64
|
+
export const searchIncorrecQueryValue = (def, payload) => {
|
|
65
|
+
def.errors.push({ code: ERR_SEARCH_INCORRECT_VALUE, payload });
|
|
66
|
+
};
|
|
67
|
+
export const searchIncorrectType = (def, payload) => {
|
|
68
|
+
def.errors.push({ code: ERR_SEARCH_TYPE, payload });
|
|
69
|
+
};
|
|
70
|
+
export const searchDoesNotExist = (def, field, isVector) => {
|
|
71
|
+
def.errors.push({ code: ERR_SEARCH_ENOENT, payload: field });
|
|
72
|
+
if (isVector) {
|
|
73
|
+
return ERROR_VECTOR;
|
|
74
|
+
}
|
|
75
|
+
return ERROR_STRING;
|
|
76
|
+
};
|
|
77
|
+
export const validateRange = (def, offset, limit) => {
|
|
78
|
+
var r = false;
|
|
79
|
+
if (typeof offset !== 'number' || offset > MAX_ID || offset < 0) {
|
|
80
|
+
def.errors.push({ code: ERR_RANGE_INVALID_OFFSET, payload: offset });
|
|
81
|
+
r = true;
|
|
82
|
+
}
|
|
83
|
+
if (typeof limit !== 'number' || limit > MAX_ID || limit < 1) {
|
|
84
|
+
def.errors.push({ code: ERR_RANGE_INVALID_LIMIT, payload: limit });
|
|
85
|
+
r = true;
|
|
86
|
+
}
|
|
87
|
+
return r;
|
|
48
88
|
};
|
|
49
89
|
export const isValidId = (id) => {
|
|
50
|
-
if (typeof id != 'number') {
|
|
90
|
+
if (typeof id != 'number' || id < MIN_ID_VALUE || id > MAX_ID_VALUE) {
|
|
51
91
|
return false;
|
|
52
92
|
}
|
|
53
|
-
|
|
93
|
+
return true;
|
|
94
|
+
};
|
|
95
|
+
export const isValidString = (v) => {
|
|
96
|
+
const isVal = typeof v === 'string' ||
|
|
97
|
+
v instanceof Buffer ||
|
|
98
|
+
ArrayBuffer.isView(v);
|
|
99
|
+
return isVal;
|
|
100
|
+
};
|
|
101
|
+
export const validateVal = (def, f, validate) => {
|
|
102
|
+
if (def.skipValidation) {
|
|
54
103
|
return false;
|
|
55
104
|
}
|
|
56
|
-
|
|
105
|
+
const value = f[2];
|
|
106
|
+
if (Array.isArray(value)) {
|
|
107
|
+
for (const v of value) {
|
|
108
|
+
if (!validate(v)) {
|
|
109
|
+
def.errors.push({ code: ERR_FILTER_INVALID_VAL, payload: f });
|
|
110
|
+
return true;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
else if (!validate(value)) {
|
|
115
|
+
def.errors.push({
|
|
116
|
+
code: ERR_FILTER_INVALID_VAL,
|
|
117
|
+
payload: f,
|
|
118
|
+
});
|
|
119
|
+
return true;
|
|
120
|
+
}
|
|
121
|
+
return false;
|
|
57
122
|
};
|
|
58
123
|
export const validateFilter = (def, prop, f) => {
|
|
124
|
+
if (def.skipValidation) {
|
|
125
|
+
return false;
|
|
126
|
+
}
|
|
59
127
|
const t = prop.typeIndex;
|
|
60
128
|
const op = f[1].operation;
|
|
61
|
-
|
|
62
|
-
if (t === REFERENCES) {
|
|
129
|
+
if (t === REFERENCES || t === REFERENCE) {
|
|
63
130
|
if (op == LIKE) {
|
|
64
|
-
def.errors.push({
|
|
65
|
-
code: ERR_FILTER_OP_FIELD,
|
|
66
|
-
payload: f,
|
|
67
|
-
});
|
|
131
|
+
def.errors.push({ code: ERR_FILTER_OP_FIELD, payload: f });
|
|
68
132
|
return true;
|
|
69
133
|
}
|
|
70
|
-
|
|
71
|
-
else if (t === REFERENCE) {
|
|
72
|
-
if (op != EQUAL) {
|
|
134
|
+
if (t === REFERENCE && op != EQUAL) {
|
|
73
135
|
def.errors.push({
|
|
74
136
|
code: ERR_FILTER_OP_FIELD,
|
|
75
137
|
payload: f,
|
|
76
138
|
});
|
|
77
139
|
return true;
|
|
78
140
|
}
|
|
79
|
-
if (
|
|
80
|
-
for (const v of value) {
|
|
81
|
-
if (!isValidId(v)) {
|
|
82
|
-
def.errors.push({
|
|
83
|
-
code: ERR_FILTER_INVALID_VAL,
|
|
84
|
-
payload: f,
|
|
85
|
-
});
|
|
86
|
-
return true;
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
else if (!isValidId(value)) {
|
|
91
|
-
def.errors.push({
|
|
92
|
-
code: ERR_FILTER_INVALID_VAL,
|
|
93
|
-
payload: f,
|
|
94
|
-
});
|
|
141
|
+
if (validateVal(def, f, isValidId)) {
|
|
95
142
|
return true;
|
|
96
143
|
}
|
|
97
144
|
}
|
|
98
145
|
else if (t === VECTOR) {
|
|
99
146
|
if (isNumerical(op) || op === HAS) {
|
|
100
|
-
def.errors.push({
|
|
101
|
-
code: ERR_FILTER_OP_FIELD,
|
|
102
|
-
payload: f,
|
|
103
|
-
});
|
|
147
|
+
def.errors.push({ code: ERR_FILTER_OP_FIELD, payload: f });
|
|
104
148
|
return true;
|
|
105
149
|
}
|
|
106
150
|
if (op === LIKE) {
|
|
107
151
|
const opts = f[1].opts;
|
|
108
152
|
if ((opts.fn && !VECTOR_FNS.includes(opts.fn)) ||
|
|
109
153
|
(opts.score != undefined && typeof opts.score !== 'number')) {
|
|
110
|
-
def.errors.push({
|
|
111
|
-
code: ERR_FILTER_INVALID_OPTS,
|
|
112
|
-
payload: f,
|
|
113
|
-
});
|
|
154
|
+
def.errors.push({ code: ERR_FILTER_INVALID_OPTS, payload: f });
|
|
114
155
|
return true;
|
|
115
156
|
}
|
|
116
157
|
}
|
|
158
|
+
if (validateVal(def, f, (v) => ArrayBuffer.isView(v) || v instanceof ArrayBuffer)) {
|
|
159
|
+
return true;
|
|
160
|
+
}
|
|
117
161
|
}
|
|
118
|
-
else if (t === TEXT || t === STRING) {
|
|
162
|
+
else if (t === TEXT || t === STRING || t === BINARY) {
|
|
119
163
|
if (isNumerical(op)) {
|
|
120
|
-
def.errors.push({
|
|
121
|
-
code: ERR_FILTER_OP_FIELD,
|
|
122
|
-
payload: f,
|
|
123
|
-
});
|
|
164
|
+
def.errors.push({ code: ERR_FILTER_OP_FIELD, payload: f });
|
|
124
165
|
return true;
|
|
125
166
|
}
|
|
126
167
|
if (op === LIKE) {
|
|
127
168
|
const opts = f[1].opts;
|
|
128
169
|
if (opts.score &&
|
|
129
170
|
(typeof opts.score !== 'number' || opts.score < 0 || opts.score > 255)) {
|
|
130
|
-
def.errors.push({
|
|
131
|
-
code: ERR_FILTER_INVALID_OPTS,
|
|
132
|
-
payload: f,
|
|
133
|
-
});
|
|
171
|
+
def.errors.push({ code: ERR_FILTER_INVALID_OPTS, payload: f });
|
|
134
172
|
return true;
|
|
135
173
|
}
|
|
136
174
|
}
|
|
175
|
+
if (validateVal(def, f, isValidString)) {
|
|
176
|
+
return true;
|
|
177
|
+
}
|
|
137
178
|
}
|
|
138
|
-
else if (propIsNumerical(prop)
|
|
139
|
-
|
|
140
|
-
code: ERR_FILTER_OP_FIELD,
|
|
141
|
-
|
|
142
|
-
}
|
|
143
|
-
|
|
179
|
+
else if (propIsNumerical(prop)) {
|
|
180
|
+
if (op !== EQUAL && !isNumerical(op)) {
|
|
181
|
+
def.errors.push({ code: ERR_FILTER_OP_FIELD, payload: f });
|
|
182
|
+
return true;
|
|
183
|
+
}
|
|
184
|
+
if (validateVal(def, f, (v) => t == TIMESTAMP || typeof v === 'number')) {
|
|
185
|
+
return true;
|
|
186
|
+
}
|
|
144
187
|
}
|
|
145
188
|
else if (t === BOOLEAN && op !== EQUAL) {
|
|
146
|
-
def.errors.push({
|
|
147
|
-
code: ERR_FILTER_OP_FIELD,
|
|
148
|
-
payload: f,
|
|
149
|
-
});
|
|
189
|
+
def.errors.push({ code: ERR_FILTER_OP_FIELD, payload: f });
|
|
150
190
|
return true;
|
|
151
191
|
}
|
|
152
192
|
return false;
|
|
@@ -193,6 +233,81 @@ export const includeLangDoesNotExist = (def, field) => {
|
|
|
193
233
|
payload: field,
|
|
194
234
|
});
|
|
195
235
|
};
|
|
236
|
+
export const validateLocale = (def, lang) => {
|
|
237
|
+
const schema = def.schema;
|
|
238
|
+
if (!(lang in schema.locales)) {
|
|
239
|
+
def.errors.push({
|
|
240
|
+
code: ERR_INVALID_LANG,
|
|
241
|
+
payload: lang,
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
};
|
|
245
|
+
export const validateSort = (def, field, orderInput) => {
|
|
246
|
+
let propDef = def.props[field];
|
|
247
|
+
if (orderInput && orderInput !== 'asc' && orderInput !== 'desc') {
|
|
248
|
+
def.errors.push({
|
|
249
|
+
code: ERR_SORT_ORDER,
|
|
250
|
+
payload: { order: orderInput, field },
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
const order = orderInput === 'asc' || orderInput === undefined ? 0 : 1;
|
|
254
|
+
// IF ! FIX
|
|
255
|
+
let lang = 0;
|
|
256
|
+
if (!propDef) {
|
|
257
|
+
let isText = false;
|
|
258
|
+
if (field.includes('.')) {
|
|
259
|
+
const path = field.split('.');
|
|
260
|
+
const x = path.slice(0, -1).join('.');
|
|
261
|
+
propDef = def.props[x];
|
|
262
|
+
if (propDef && propDef.typeIndex === TEXT) {
|
|
263
|
+
const k = path[path.length - 1];
|
|
264
|
+
lang = langCodesMap.get(k);
|
|
265
|
+
isText = true;
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
if (!isText) {
|
|
269
|
+
def.errors.push({
|
|
270
|
+
code: ERR_SORT_ENOENT,
|
|
271
|
+
payload: field,
|
|
272
|
+
});
|
|
273
|
+
return {
|
|
274
|
+
prop: EMPTY_ALIAS_PROP_DEF,
|
|
275
|
+
order,
|
|
276
|
+
lang: def.lang,
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
const type = propDef.typeIndex;
|
|
281
|
+
if (type === REFERENCES || type === REFERENCE) {
|
|
282
|
+
def.errors.push({
|
|
283
|
+
code: ERR_SORT_TYPE,
|
|
284
|
+
payload: propDef,
|
|
285
|
+
});
|
|
286
|
+
}
|
|
287
|
+
else if (type === TEXT) {
|
|
288
|
+
if (lang === 0) {
|
|
289
|
+
lang = def.lang ?? 0;
|
|
290
|
+
if (lang === 0) {
|
|
291
|
+
def.errors.push({
|
|
292
|
+
code: ERR_SORT_LANG,
|
|
293
|
+
payload: propDef,
|
|
294
|
+
});
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
// add propDef LANG
|
|
299
|
+
if ('id' in def.target || 'alias' in def.target) {
|
|
300
|
+
def.errors.push({
|
|
301
|
+
code: ERR_SORT_WRONG_TARGET,
|
|
302
|
+
payload: def,
|
|
303
|
+
});
|
|
304
|
+
}
|
|
305
|
+
return {
|
|
306
|
+
prop: propDef,
|
|
307
|
+
order,
|
|
308
|
+
lang,
|
|
309
|
+
};
|
|
310
|
+
};
|
|
196
311
|
export const validateAlias = (alias, path, def) => {
|
|
197
312
|
const schema = def.schema;
|
|
198
313
|
for (const k in alias) {
|
|
@@ -217,7 +332,10 @@ export const validateAlias = (alias, path, def) => {
|
|
|
217
332
|
return { value: '', def: EMPTY_ALIAS_PROP_DEF };
|
|
218
333
|
};
|
|
219
334
|
export const validateId = (def, id) => {
|
|
220
|
-
if (
|
|
335
|
+
if (def.skipValidation) {
|
|
336
|
+
return id;
|
|
337
|
+
}
|
|
338
|
+
if (!isValidId(id)) {
|
|
221
339
|
def.errors.push({
|
|
222
340
|
code: ERR_TARGET_INVAL_ID,
|
|
223
341
|
payload: id,
|
|
@@ -227,17 +345,18 @@ export const validateId = (def, id) => {
|
|
|
227
345
|
return id;
|
|
228
346
|
};
|
|
229
347
|
export const validateIds = (def, ids) => {
|
|
348
|
+
const origIds = ids;
|
|
230
349
|
if (!Array.isArray(ids) && !(ids instanceof Uint32Array)) {
|
|
231
350
|
def.errors.push({
|
|
232
351
|
code: ERR_TARGET_INVAL_IDS,
|
|
233
|
-
payload:
|
|
352
|
+
payload: origIds,
|
|
234
353
|
});
|
|
235
354
|
return new Uint32Array([]);
|
|
236
355
|
}
|
|
237
356
|
if (ids.length > MAX_IDS_PER_QUERY) {
|
|
238
357
|
def.errors.push({
|
|
239
358
|
code: ERR_TARGET_EXCEED_MAX_IDS,
|
|
240
|
-
payload:
|
|
359
|
+
payload: origIds,
|
|
241
360
|
});
|
|
242
361
|
return new Uint32Array([]);
|
|
243
362
|
}
|
|
@@ -249,17 +368,20 @@ export const validateIds = (def, ids) => {
|
|
|
249
368
|
catch (err) {
|
|
250
369
|
def.errors.push({
|
|
251
370
|
code: ERR_TARGET_INVAL_IDS,
|
|
252
|
-
payload:
|
|
371
|
+
payload: origIds,
|
|
253
372
|
});
|
|
254
373
|
return new Uint32Array([]);
|
|
255
374
|
}
|
|
256
375
|
}
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
376
|
+
if (def.skipValidation) {
|
|
377
|
+
return ids;
|
|
378
|
+
}
|
|
379
|
+
for (let i = 0; i < ids.length; i++) {
|
|
380
|
+
const id = ids[i];
|
|
381
|
+
if (typeof id !== 'number' || id == 0 || id > MAX_ID) {
|
|
260
382
|
def.errors.push({
|
|
261
383
|
code: ERR_TARGET_INVAL_IDS,
|
|
262
|
-
payload:
|
|
384
|
+
payload: origIds,
|
|
263
385
|
});
|
|
264
386
|
return new Uint32Array([]);
|
|
265
387
|
}
|
|
@@ -268,9 +390,14 @@ export const validateIds = (def, ids) => {
|
|
|
268
390
|
};
|
|
269
391
|
export const handleErrors = (def) => {
|
|
270
392
|
if (def.errors.length) {
|
|
271
|
-
let name = `
|
|
393
|
+
let name = picocolors.red(`QueryError[${displayTarget(def)}]\n`);
|
|
272
394
|
for (const err of def.errors) {
|
|
273
|
-
|
|
395
|
+
try {
|
|
396
|
+
name += ` ${messages[err.code](err.payload)}\n`;
|
|
397
|
+
}
|
|
398
|
+
catch (e) {
|
|
399
|
+
name += ` Cannot parse error:${err.code}\n`;
|
|
400
|
+
}
|
|
274
401
|
}
|
|
275
402
|
const err = new Error(`Query\n`);
|
|
276
403
|
err.stack = name;
|
|
@@ -286,6 +413,24 @@ export const EMPTY_ALIAS_PROP_DEF = {
|
|
|
286
413
|
start: 0,
|
|
287
414
|
path: ['ERROR_ALIAS'],
|
|
288
415
|
};
|
|
416
|
+
export const ERROR_STRING = {
|
|
417
|
+
prop: 1,
|
|
418
|
+
typeIndex: STRING,
|
|
419
|
+
__isPropDef: true,
|
|
420
|
+
separate: true,
|
|
421
|
+
len: 0,
|
|
422
|
+
start: 0,
|
|
423
|
+
path: ['ERROR_STRING'],
|
|
424
|
+
};
|
|
425
|
+
export const ERROR_VECTOR = {
|
|
426
|
+
prop: 1,
|
|
427
|
+
typeIndex: VECTOR,
|
|
428
|
+
__isPropDef: true,
|
|
429
|
+
separate: true,
|
|
430
|
+
len: 0,
|
|
431
|
+
start: 0,
|
|
432
|
+
path: ['ERROR_VECTOR'],
|
|
433
|
+
};
|
|
289
434
|
export const EMPTY_SCHEMA_DEF = {
|
|
290
435
|
type: '_error',
|
|
291
436
|
cnt: 0,
|
|
@@ -304,41 +449,19 @@ export const EMPTY_SCHEMA_DEF = {
|
|
|
304
449
|
main: {},
|
|
305
450
|
separate: [],
|
|
306
451
|
tree: {},
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
452
|
+
hasSeperateSort: false,
|
|
453
|
+
seperateSort: {
|
|
454
|
+
size: 0,
|
|
455
|
+
buffer: Buffer.from([]),
|
|
456
|
+
bufferTmp: Buffer.from([]),
|
|
457
|
+
props: [],
|
|
458
|
+
},
|
|
459
|
+
hasSeperateTextSort: false,
|
|
460
|
+
seperateTextSort: {
|
|
461
|
+
size: 0,
|
|
462
|
+
buffer: Buffer.from([]),
|
|
463
|
+
bufferTmp: Buffer.from([]),
|
|
464
|
+
props: [],
|
|
465
|
+
},
|
|
312
466
|
};
|
|
313
|
-
// export const checkMaxIdsPerQuery = (
|
|
314
|
-
// ids: (number | QueryByAliasObj)[],
|
|
315
|
-
// ): void => {
|
|
316
|
-
// if (ids.length > MAX_IDS_PER_QUERY) {
|
|
317
|
-
// throw new Error(`The number of IDs cannot exceed ${MAX_IDS_PER_QUERY}.`)
|
|
318
|
-
// }
|
|
319
|
-
// }
|
|
320
|
-
// export const checkMaxBufferSize = (buf: Buffer): void => {
|
|
321
|
-
// if (buf.byteLength > MAX_BUFFER_SIZE) {
|
|
322
|
-
// throw new Error(
|
|
323
|
-
// `The buffer size exceeds the maximum threshold of ${MAX_BUFFER_SIZE} bytes.` +
|
|
324
|
-
// `Crrent size is ${buf.byteLength} bytes.`,
|
|
325
|
-
// )
|
|
326
|
-
// }
|
|
327
|
-
// }
|
|
328
|
-
// export const checkTotalBufferSize = (bufers: Buffer[]): void => {
|
|
329
|
-
// let totalSize = 0
|
|
330
|
-
// for (const buffer of bufers) {
|
|
331
|
-
// totalSize += buffer.byteLength
|
|
332
|
-
// if (totalSize > MAX_BUFFER_SIZE) {
|
|
333
|
-
// throw new Error(
|
|
334
|
-
// `The total buffer size exceeds the maximum threshold of ${MAX_BUFFER_SIZE} bytes.` +
|
|
335
|
-
// `Crrent size is ${totalSize} bytes.`,
|
|
336
|
-
// )
|
|
337
|
-
// }
|
|
338
|
-
// }
|
|
339
|
-
// }
|
|
340
|
-
// // ------------------------------
|
|
341
|
-
// export const includeDoesNotExist = (def: QueryDef, field: string) => {
|
|
342
|
-
// throw new Error(`Incorrect include field provided to query "${field}")`)
|
|
343
|
-
// }
|
|
344
467
|
//# sourceMappingURL=validation.js.map
|
package/dist/src/index.d.ts
CHANGED
|
@@ -8,15 +8,17 @@ export { compress, decompress };
|
|
|
8
8
|
export { ModifyCtx };
|
|
9
9
|
export { DbClient, DbServer };
|
|
10
10
|
export { xxHash64 } from './client/xxHash64.js';
|
|
11
|
+
export { crc32 } from './client/crc32.js';
|
|
11
12
|
export declare class BasedDb {
|
|
12
13
|
#private;
|
|
13
14
|
client: DbClient;
|
|
14
15
|
server: DbServer;
|
|
15
16
|
fileSystemPath: string;
|
|
16
17
|
maxModifySize: number;
|
|
17
|
-
constructor(
|
|
18
|
+
constructor(opts: {
|
|
18
19
|
path: string;
|
|
19
20
|
maxModifySize?: number;
|
|
21
|
+
debug?: boolean;
|
|
20
22
|
});
|
|
21
23
|
create: DbClient['create'];
|
|
22
24
|
copy: DbClient['copy'];
|
package/dist/src/index.js
CHANGED
|
@@ -2,19 +2,34 @@ import { compress, decompress } from './client/string.js';
|
|
|
2
2
|
import { ModifyCtx } from './client/operations.js';
|
|
3
3
|
import { DbServer } from './server/index.js';
|
|
4
4
|
import { DbClient } from './client/index.js';
|
|
5
|
+
import picocolors from 'picocolors';
|
|
5
6
|
export * from './server/schema/typeDef.js';
|
|
6
7
|
export * from './client/modify/modify.js';
|
|
7
8
|
export { compress, decompress };
|
|
8
9
|
export { ModifyCtx }; // TODO move this somewhere
|
|
9
10
|
export { DbClient, DbServer };
|
|
10
11
|
export { xxHash64 } from './client/xxHash64.js';
|
|
12
|
+
export { crc32 } from './client/crc32.js';
|
|
11
13
|
export class BasedDb {
|
|
12
14
|
client;
|
|
13
15
|
server;
|
|
14
16
|
fileSystemPath;
|
|
15
17
|
maxModifySize;
|
|
16
|
-
constructor(
|
|
17
|
-
this.#init(
|
|
18
|
+
constructor(opts) {
|
|
19
|
+
this.#init(opts);
|
|
20
|
+
if (opts.debug) {
|
|
21
|
+
for (const key in this) {
|
|
22
|
+
const fn = this[key];
|
|
23
|
+
if (typeof fn === 'function') {
|
|
24
|
+
// @ts-ignore
|
|
25
|
+
this[key] = function () {
|
|
26
|
+
const str = [`[${key}]`, ...arguments].join(' ');
|
|
27
|
+
console.info(picocolors.dim(str));
|
|
28
|
+
return fn.apply(this, arguments);
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
18
33
|
}
|
|
19
34
|
#init({ path, maxModifySize }) {
|
|
20
35
|
this.fileSystemPath = path;
|
package/dist/src/native.d.ts
CHANGED
package/dist/src/native.js
CHANGED
|
@@ -3,6 +3,12 @@ import db from '../../basedDbNative.cjs';
|
|
|
3
3
|
var compressor = null;
|
|
4
4
|
var decompressor = null;
|
|
5
5
|
export default {
|
|
6
|
+
historyAppend(history, typeId, nodeId) {
|
|
7
|
+
return db.historyCreate(history, typeId, nodeId);
|
|
8
|
+
},
|
|
9
|
+
historyCreate(pathname, mainLen) {
|
|
10
|
+
return db.historyCreate(Buffer.from(pathname), mainLen + 16 - (mainLen % 16));
|
|
11
|
+
},
|
|
6
12
|
workerCtxInit: () => {
|
|
7
13
|
return db.workerCtxInit();
|
|
8
14
|
},
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { StrictSchema } from '@based/schema';
|
|
1
|
+
import { LangName, StrictSchema } from '@based/schema';
|
|
2
2
|
import { SchemaTypeDef } from './schema/types.js';
|
|
3
3
|
import { createTree } from './csmt/index.js';
|
|
4
4
|
import { Worker, MessagePort } from 'node:worker_threads';
|
|
@@ -67,19 +67,21 @@ export declare class DbServer {
|
|
|
67
67
|
sortIndexes: {
|
|
68
68
|
[type: number]: {
|
|
69
69
|
[field: number]: {
|
|
70
|
-
[start: number]:
|
|
70
|
+
[start: number]: {
|
|
71
|
+
[lang: number]: SortIndex;
|
|
72
|
+
};
|
|
71
73
|
};
|
|
72
74
|
};
|
|
73
75
|
};
|
|
74
76
|
cleanupTimer: NodeJS.Timeout;
|
|
75
77
|
cleanup(): void;
|
|
76
|
-
createSortIndex(type: string, field: string): SortIndex;
|
|
77
|
-
destroySortIndex(type: string, field: string): any;
|
|
78
|
-
getSortIndex(typeId: number, field: number, start: number): SortIndex;
|
|
78
|
+
createSortIndex(type: string, field: string, lang?: LangName): SortIndex;
|
|
79
|
+
destroySortIndex(type: string, field: string, lang?: LangName): any;
|
|
80
|
+
getSortIndex(typeId: number, field: number, start: number, lang: number): SortIndex;
|
|
79
81
|
migrateSchema(schema: StrictSchema, transform?: Record<string, (node: Record<string, any>) => Record<string, any> | [string, Record<string, any>]>): Promise<StrictSchema & {
|
|
80
82
|
lastId: number;
|
|
81
83
|
}>;
|
|
82
|
-
createSortIndexBuffer(typeId: number, field: number, start: number): SortIndex;
|
|
84
|
+
createSortIndexBuffer(typeId: number, field: number, start: number, lang: number): SortIndex;
|
|
83
85
|
updateMerkleTree(): void;
|
|
84
86
|
putSchema(strictSchema: StrictSchema, fromStart?: boolean, transformFns?: TransformFns): (StrictSchema & {
|
|
85
87
|
lastId: number;
|