@based/db 0.0.19 → 0.0.21
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/basedDbNative.cjs +6 -2
- package/dist/lib/darwin_aarch64/include/selva/db.h +92 -9
- package/dist/lib/darwin_aarch64/include/selva/fast_memcmp.h +18 -0
- package/dist/lib/darwin_aarch64/include/selva/fields.h +31 -32
- package/dist/lib/darwin_aarch64/include/selva/types.h +0 -10
- package/dist/lib/darwin_aarch64/libdeflate.dylib +0 -0
- package/dist/lib/darwin_aarch64/libjemalloc_selva.2.dylib +0 -0
- package/dist/lib/darwin_aarch64/libnode-v20.node +0 -0
- package/dist/lib/darwin_aarch64/libnode-v21.node +0 -0
- package/dist/lib/darwin_aarch64/libnode-v22.node +0 -0
- package/dist/lib/darwin_aarch64/libnode-v23.node +0 -0
- package/dist/lib/darwin_aarch64/libselva.dylib +0 -0
- package/dist/lib/darwin_aarch64/libxxhash.dylib +0 -0
- package/dist/lib/linux_aarch64/include/selva/db.h +92 -9
- package/dist/lib/linux_aarch64/include/selva/fast_memcmp.h +18 -0
- package/dist/lib/linux_aarch64/include/selva/fields.h +31 -32
- package/dist/lib/linux_aarch64/include/selva/types.h +0 -10
- package/dist/lib/linux_aarch64/libnode-v20.node +0 -0
- package/dist/lib/linux_aarch64/libnode-v21.node +0 -0
- package/dist/lib/linux_aarch64/libnode-v22.node +0 -0
- package/dist/lib/linux_aarch64/libnode-v23.node +0 -0
- package/dist/lib/linux_aarch64/libselva.so +0 -0
- package/dist/lib/linux_x86_64/include/selva/db.h +92 -9
- package/dist/lib/linux_x86_64/include/selva/fast_memcmp.h +18 -0
- package/dist/lib/linux_x86_64/include/selva/fields.h +31 -32
- package/dist/lib/linux_x86_64/include/selva/types.h +0 -10
- package/dist/lib/linux_x86_64/libnode-v20.node +0 -0
- package/dist/lib/linux_x86_64/libnode-v21.node +0 -0
- package/dist/lib/linux_x86_64/libnode-v22.node +0 -0
- package/dist/lib/linux_x86_64/libnode-v23.node +0 -0
- package/dist/lib/linux_x86_64/libselva.so +0 -0
- package/dist/src/client/bitWise.js +0 -1
- package/dist/src/client/crc32.d.ts +1 -1
- package/dist/src/client/modify/alias.js +3 -3
- package/dist/src/client/modify/binary.d.ts +1 -1
- package/dist/src/client/modify/binary.js +7 -6
- package/dist/src/client/modify/cardinality.d.ts +3 -1
- package/dist/src/client/modify/cardinality.js +8 -4
- package/dist/src/client/modify/create.js +41 -5
- package/dist/src/client/modify/delete.js +9 -8
- package/dist/src/client/modify/expire.js +1 -1
- package/dist/src/client/modify/modify.js +3 -3
- package/dist/src/client/modify/references/edge.js +15 -1
- package/dist/src/client/modify/setCursor.js +0 -2
- package/dist/src/client/modify/string.d.ts +1 -1
- package/dist/src/client/modify/string.js +5 -3
- package/dist/src/client/modify/text.d.ts +1 -1
- package/dist/src/client/modify/text.js +52 -9
- package/dist/src/client/modify/types.d.ts +5 -1
- package/dist/src/client/modify/types.js +2 -1
- package/dist/src/client/modify/vector.js +4 -4
- package/dist/src/client/query/filter/convertFilter.js +3 -1
- package/dist/src/client/query/filter/createFixedFilterBuffer.js +1 -1
- package/dist/src/client/query/filter/createVariableFilterBuffer.js +10 -4
- package/dist/src/client/query/filter/parseFilterValue.js +13 -4
- package/dist/src/client/query/filter/primitiveFilter.js +13 -3
- package/dist/src/client/query/filter/toBuffer.js +13 -3
- package/dist/src/client/query/filter/types.d.ts +5 -3
- package/dist/src/client/query/filter/types.js +12 -0
- package/dist/src/client/query/read/read.js +7 -1
- package/dist/src/client/query/search/index.js +25 -19
- package/dist/src/client/query/serialize.d.ts +4 -0
- package/dist/src/client/query/serialize.js +26 -0
- package/dist/src/client/query/sort.d.ts +1 -1
- package/dist/src/client/query/sort.js +5 -5
- package/dist/src/client/query/subscription/run.js +1 -1
- package/dist/src/client/query/types.d.ts +6 -2
- package/dist/src/client/query/validation.js +14 -32
- package/dist/src/client/string.d.ts +2 -2
- package/dist/src/client/string.js +32 -29
- package/dist/src/client/tmpBuffer.d.ts +3 -0
- package/dist/src/client/tmpBuffer.js +20 -0
- package/dist/src/client/xxHash64.d.ts +1 -1
- package/dist/src/client/xxHash64.js +1 -1
- package/dist/src/index.d.ts +2 -0
- package/dist/src/index.js +2 -0
- package/dist/src/native.d.ts +14 -13
- package/dist/src/native.js +41 -25
- package/dist/src/server/csmt/draw-dot.js +2 -1
- package/dist/src/server/csmt/memebership-proof.d.ts +1 -1
- package/dist/src/server/csmt/tree.d.ts +2 -1
- package/dist/src/server/csmt/tree.js +10 -9
- package/dist/src/server/csmt/types.d.ts +4 -3
- package/dist/src/server/index.d.ts +5 -4
- package/dist/src/server/index.js +5 -6
- package/dist/src/server/save.js +4 -3
- package/dist/src/server/start.d.ts +1 -0
- package/dist/src/server/start.js +43 -16
- package/dist/src/server/tree.d.ts +1 -1
- package/dist/src/server/tree.js +17 -2
- package/dist/src/server/worker.js +2 -1
- package/dist/src/utils.d.ts +4 -0
- package/dist/src/utils.js +84 -0
- package/package.json +4 -4
- 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/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_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
|
@@ -2,4 +2,4 @@ import { LangCode } from '@based/schema';
|
|
|
2
2
|
import { ModifyCtx } from '../../index.js';
|
|
3
3
|
import { SchemaTypeDef, PropDef } from '@based/schema/def';
|
|
4
4
|
import { ModifyOp, ModifyErr } from './types.js';
|
|
5
|
-
export declare function writeString(lang: LangCode, value: string | null |
|
|
5
|
+
export declare function writeString(lang: LangCode, value: string | null | Uint8Array, ctx: ModifyCtx, def: SchemaTypeDef, t: PropDef, parentId: number, modifyOp: ModifyOp): ModifyErr;
|
|
@@ -6,14 +6,14 @@ import { write } from '../string.js';
|
|
|
6
6
|
// add compression handling for main buffer
|
|
7
7
|
// add compression handling for edge fields
|
|
8
8
|
export function writeString(lang, value, ctx, def, t, parentId, modifyOp) {
|
|
9
|
-
const isBuffer = value instanceof
|
|
9
|
+
const isBuffer = value instanceof Uint8Array;
|
|
10
10
|
if (typeof value !== 'string' && value !== null && !isBuffer) {
|
|
11
11
|
return new ModifyError(t, value);
|
|
12
12
|
}
|
|
13
13
|
const len = value?.length;
|
|
14
14
|
if (!len) {
|
|
15
15
|
if (modifyOp === UPDATE) {
|
|
16
|
-
if (ctx.len + 11 > ctx.max) {
|
|
16
|
+
if (ctx.len + 11 /* SIZE.DEFAULT_CURSOR */ + 1 > ctx.max) {
|
|
17
17
|
return RANGE_ERR;
|
|
18
18
|
}
|
|
19
19
|
setCursor(ctx, def, t.prop, t.typeIndex, parentId, modifyOp);
|
|
@@ -24,7 +24,9 @@ export function writeString(lang, value, ctx, def, t, parentId, modifyOp) {
|
|
|
24
24
|
let size = isBuffer
|
|
25
25
|
? value.byteLength
|
|
26
26
|
: Buffer.byteLength(value, 'utf8') + 6;
|
|
27
|
-
if (ctx.len +
|
|
27
|
+
if (ctx.len + 11 /* SIZE.DEFAULT_CURSOR */ + 11 + size > ctx.max) {
|
|
28
|
+
// +10 OR +11, teh original check was +20 but
|
|
29
|
+
// there are 10 addtional bytes in this scope
|
|
28
30
|
// 5 compression size
|
|
29
31
|
return RANGE_ERR;
|
|
30
32
|
}
|
|
@@ -5,4 +5,4 @@ import { writeString } from './string.js';
|
|
|
5
5
|
import { ModifyState } from './ModifyRes.js';
|
|
6
6
|
export declare function writeText(value: {
|
|
7
7
|
[k: string]: Parameters<typeof writeString>[1];
|
|
8
|
-
}, ctx: ModifyCtx, def: SchemaTypeDef, t: PropDef, res: ModifyState, modifyOp: ModifyOp): ModifyErr;
|
|
8
|
+
} | Parameters<typeof writeString>[1], ctx: ModifyCtx, def: SchemaTypeDef, t: PropDef, res: ModifyState, parentId: number, modifyOp: ModifyOp): ModifyErr;
|
|
@@ -1,24 +1,67 @@
|
|
|
1
1
|
import { langCodesMap } from '@based/schema';
|
|
2
|
-
import { CREATE } from './types.js';
|
|
2
|
+
import { CREATE, UPDATE, RANGE_ERR, DELETE, } from './types.js';
|
|
3
3
|
import { writeString } from './string.js';
|
|
4
|
-
|
|
4
|
+
import { ModifyError } from './ModifyRes.js';
|
|
5
|
+
import { setCursor } from './setCursor.js';
|
|
6
|
+
export function writeText(value, ctx, def, t, res, parentId, modifyOp) {
|
|
7
|
+
const isBuffer = value instanceof Uint8Array;
|
|
8
|
+
if (typeof value !== 'string' &&
|
|
9
|
+
value !== null &&
|
|
10
|
+
!isBuffer &&
|
|
11
|
+
value &&
|
|
12
|
+
typeof value !== 'object') {
|
|
13
|
+
return new ModifyError(t, value);
|
|
14
|
+
}
|
|
15
|
+
// const len = value?.length
|
|
16
|
+
// think about this
|
|
17
|
+
if (value === null && !res.locale) {
|
|
18
|
+
if (modifyOp === UPDATE) {
|
|
19
|
+
if (ctx.len + 11 /* SIZE.DEFAULT_CURSOR */ + 1 > ctx.max) {
|
|
20
|
+
return RANGE_ERR;
|
|
21
|
+
}
|
|
22
|
+
setCursor(ctx, def, t.prop, t.typeIndex, parentId, modifyOp);
|
|
23
|
+
ctx.buf[ctx.len++] = DELETE;
|
|
24
|
+
}
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
5
27
|
// todo proper fallback as well
|
|
6
|
-
if (value && typeof value !== 'object') {
|
|
7
|
-
const
|
|
28
|
+
if ((value && typeof value !== 'object') || value === null) {
|
|
29
|
+
const locale = res.locale ?? langCodesMap.get('en'); // TODO: Add def lang option...
|
|
30
|
+
if (value == null) {
|
|
31
|
+
// @ts-ignore
|
|
32
|
+
value = '';
|
|
33
|
+
}
|
|
34
|
+
// @ts-ignore
|
|
35
|
+
const err = writeString(res.locale, value, ctx, def, t, res.tmpId, modifyOp);
|
|
8
36
|
if (modifyOp === CREATE) {
|
|
9
|
-
|
|
10
|
-
|
|
37
|
+
const index = t.prop * (def.localeSize + 1);
|
|
38
|
+
const langIndex = def.seperateTextSort.localeToIndex.get(locale);
|
|
39
|
+
def.seperateTextSort.bufferTmp[index] -= 1;
|
|
40
|
+
def.seperateTextSort.bufferTmp[index + langIndex] = 0;
|
|
41
|
+
ctx.hasSortText += 1;
|
|
11
42
|
}
|
|
12
43
|
return err;
|
|
13
44
|
}
|
|
14
45
|
else {
|
|
46
|
+
// @ts-ignore
|
|
15
47
|
for (const lang in value) {
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
|
|
48
|
+
const langC = def.seperateTextSort.localeStringToIndex.get(lang);
|
|
49
|
+
if (!langC) {
|
|
50
|
+
return new ModifyError(t, lang, 'Invalid locale');
|
|
51
|
+
}
|
|
52
|
+
let s = value[lang];
|
|
53
|
+
if (s == null) {
|
|
54
|
+
// @ts-ignore
|
|
55
|
+
s = '';
|
|
56
|
+
}
|
|
57
|
+
const err = writeString(langC[1], s, ctx, def, t, res.tmpId, modifyOp);
|
|
19
58
|
if (err) {
|
|
20
59
|
return err;
|
|
21
60
|
}
|
|
61
|
+
const index = t.prop * (1 + def.localeSize);
|
|
62
|
+
def.seperateTextSort.bufferTmp[index] -= 1;
|
|
63
|
+
def.seperateTextSort.bufferTmp[index + langC[0]] = 0;
|
|
64
|
+
ctx.hasSortText += 1;
|
|
22
65
|
}
|
|
23
66
|
}
|
|
24
67
|
}
|
|
@@ -3,7 +3,8 @@ import { ModifyError } from './ModifyRes.js';
|
|
|
3
3
|
export declare const CREATE = 3;
|
|
4
4
|
export declare const UPDATE = 6;
|
|
5
5
|
export declare const DELETE = 11;
|
|
6
|
-
export declare const
|
|
6
|
+
export declare const DELETE_SORT_INDEX = 4;
|
|
7
|
+
export declare const DELETE_NODE = 10;
|
|
7
8
|
export declare const RANGE_ERR = 1;
|
|
8
9
|
export declare const INCREMENT = 12;
|
|
9
10
|
export declare const DECREMENT = 13;
|
|
@@ -14,6 +15,9 @@ export declare const SWITCH_TYPE = 2;
|
|
|
14
15
|
export declare const SWITCH_FIELD = 0;
|
|
15
16
|
export declare const SWITCH_ID_CREATE = 9;
|
|
16
17
|
export declare const SWITCH_ID_UPDATE = 1;
|
|
18
|
+
export declare const enum SIZE {
|
|
19
|
+
DEFAULT_CURSOR = 11
|
|
20
|
+
}
|
|
17
21
|
export type ModifyErr = typeof RANGE_ERR | ModifyError | void;
|
|
18
22
|
export type ModifyOp = typeof CREATE | typeof UPDATE | typeof INCREMENT | typeof EXPIRE;
|
|
19
23
|
export type ModifyOpts = {
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
export const CREATE = 3;
|
|
2
2
|
export const UPDATE = 6;
|
|
3
3
|
export const DELETE = 11;
|
|
4
|
-
export const
|
|
4
|
+
export const DELETE_SORT_INDEX = 4;
|
|
5
|
+
export const DELETE_NODE = 10;
|
|
5
6
|
export const RANGE_ERR = 1;
|
|
6
7
|
export const INCREMENT = 12;
|
|
7
8
|
export const DECREMENT = 13;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { UPDATE, RANGE_ERR, DELETE } from './types.js';
|
|
1
|
+
import { UPDATE, RANGE_ERR, DELETE, } from './types.js';
|
|
2
2
|
import { ModifyError } from './ModifyRes.js';
|
|
3
3
|
import { setCursor } from './setCursor.js';
|
|
4
4
|
function write(value, ctx, fieldSize) {
|
|
@@ -9,7 +9,7 @@ function write(value, ctx, fieldSize) {
|
|
|
9
9
|
ctx.buf[ctx.len++] = tmp >>>= 8;
|
|
10
10
|
ctx.buf[ctx.len++] = tmp >>>= 8;
|
|
11
11
|
ctx.buf[ctx.len++] = tmp >>>= 8;
|
|
12
|
-
|
|
12
|
+
ctx.buf.set(new Uint8Array(value.buffer).subarray(0, size), ctx.len);
|
|
13
13
|
ctx.len += size;
|
|
14
14
|
}
|
|
15
15
|
export function writeVector(value, ctx, schema, t, parentId, modifyOp) {
|
|
@@ -25,7 +25,7 @@ export function writeVector(value, ctx, schema, t, parentId, modifyOp) {
|
|
|
25
25
|
}
|
|
26
26
|
if (size === 0) {
|
|
27
27
|
if (modifyOp === UPDATE) {
|
|
28
|
-
if (ctx.len + 11 > ctx.max) {
|
|
28
|
+
if (ctx.len + 11 /* SIZE.DEFAULT_CURSOR */ + 1 > ctx.max) {
|
|
29
29
|
// TODO ???
|
|
30
30
|
return RANGE_ERR;
|
|
31
31
|
}
|
|
@@ -34,7 +34,7 @@ export function writeVector(value, ctx, schema, t, parentId, modifyOp) {
|
|
|
34
34
|
}
|
|
35
35
|
}
|
|
36
36
|
else {
|
|
37
|
-
if (ctx.len +
|
|
37
|
+
if (ctx.len + 11 /* SIZE.DEFAULT_CURSOR */ + 5 + size > ctx.max) {
|
|
38
38
|
// TODO ???
|
|
39
39
|
return RANGE_ERR;
|
|
40
40
|
}
|
|
@@ -15,7 +15,9 @@ export const convertFilter = (def, field, operator, value, opts) => {
|
|
|
15
15
|
value = operator;
|
|
16
16
|
operator = '=';
|
|
17
17
|
}
|
|
18
|
-
if (
|
|
18
|
+
if (!(operator === 'exists' || operator === '!exists') &&
|
|
19
|
+
(value === '' || value === undefined)) {
|
|
20
|
+
// not great...
|
|
19
21
|
return;
|
|
20
22
|
}
|
|
21
23
|
if (operator === '!..') {
|
|
@@ -20,7 +20,7 @@ export const writeFixed = (prop, buf, value, size, offset) => {
|
|
|
20
20
|
const size = buf.write(value, offset + 1, 'utf8');
|
|
21
21
|
buf[offset] = size;
|
|
22
22
|
}
|
|
23
|
-
else if (value instanceof
|
|
23
|
+
else if (value instanceof Uint8Array) {
|
|
24
24
|
buf.set(value, offset);
|
|
25
25
|
}
|
|
26
26
|
else {
|
|
@@ -2,7 +2,7 @@ import { ALIAS, TEXT, VECTOR } from '@based/schema/def';
|
|
|
2
2
|
import { EQUAL, EQUAL_CRC32, HAS, HAS_TO_LOWER_CASE, LIKE, MODE_DEFAULT_VAR, MODE_OR_VAR, getVectorFn, } from './types.js';
|
|
3
3
|
import { createFixedFilterBuffer } from './createFixedFilterBuffer.js';
|
|
4
4
|
import { crc32 } from '../../crc32.js';
|
|
5
|
-
const DEFAULT_SCORE =
|
|
5
|
+
const DEFAULT_SCORE = new Uint8Array(new Float32Array([0.5]).buffer);
|
|
6
6
|
const parseValue = (value, prop, ctx, lang) => {
|
|
7
7
|
let val = value;
|
|
8
8
|
if (ctx.operation === HAS_TO_LOWER_CASE && typeof val === 'string') {
|
|
@@ -12,11 +12,17 @@ const parseValue = (value, prop, ctx, lang) => {
|
|
|
12
12
|
if (!(val instanceof ArrayBuffer)) {
|
|
13
13
|
throw new Error('Vector should be an arrayBuffer');
|
|
14
14
|
}
|
|
15
|
-
|
|
15
|
+
const vector = new Uint8Array(val);
|
|
16
|
+
let fn = new Uint8Array([getVectorFn(ctx.opts.fn)]);
|
|
16
17
|
const score = ctx.opts.score
|
|
17
|
-
?
|
|
18
|
+
? new Uint8Array(new Float32Array([ctx.opts.score]).buffer)
|
|
18
19
|
: DEFAULT_SCORE;
|
|
19
|
-
|
|
20
|
+
const buf = new Uint8Array(vector.byteLength + fn.byteLength + score.byteLength);
|
|
21
|
+
let off = 0;
|
|
22
|
+
off += (buf.set(new Uint8Array(vector), off), vector.byteLength);
|
|
23
|
+
off += (buf.set(fn, off), fn.byteLength);
|
|
24
|
+
buf.set(score, off);
|
|
25
|
+
val = buf;
|
|
20
26
|
}
|
|
21
27
|
if (val instanceof Uint8Array ||
|
|
22
28
|
typeof value === 'string' ||
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { TIMESTAMP, CREATED, UPDATED, ENUM, BOOLEAN, STRING, BINARY, TEXT, } from '@based/schema/def';
|
|
2
2
|
import { crc32 } from '../../crc32.js';
|
|
3
3
|
import { convertToTimestamp } from '../../timestamp.js';
|
|
4
|
+
const ENCODER = new TextEncoder();
|
|
4
5
|
// -------------------------------------------
|
|
5
6
|
// conditions normal
|
|
6
7
|
// field, [size 2]
|
|
@@ -18,10 +19,18 @@ export const parseFilterValue = (prop, value) => {
|
|
|
18
19
|
if (prop.typeIndex === BINARY ||
|
|
19
20
|
prop.typeIndex === STRING ||
|
|
20
21
|
prop.typeIndex === TEXT) {
|
|
21
|
-
const b = value instanceof
|
|
22
|
-
const buf =
|
|
23
|
-
|
|
24
|
-
buf
|
|
22
|
+
const b = value instanceof Uint8Array ? value : ENCODER.encode(value);
|
|
23
|
+
const buf = new Uint8Array(8);
|
|
24
|
+
let crc = crc32(b);
|
|
25
|
+
buf[0] = crc;
|
|
26
|
+
buf[1] = crc >>>= 8;
|
|
27
|
+
buf[2] = crc >>>= 8;
|
|
28
|
+
buf[3] = crc >>>= 8;
|
|
29
|
+
let len = b.byteLength;
|
|
30
|
+
buf[4] = len;
|
|
31
|
+
buf[5] = len >>>= 8;
|
|
32
|
+
buf[6] = len >>>= 8;
|
|
33
|
+
buf[7] = len >>>= 8;
|
|
25
34
|
return buf;
|
|
26
35
|
}
|
|
27
36
|
else if (prop.typeIndex === BOOLEAN) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { CARDINALITY, REFERENCE, REFERENCES, REVERSE_SIZE_MAP, } from '@based/schema/def';
|
|
2
|
-
import { EQUAL, isNumerical } from './types.js';
|
|
2
|
+
import { EQUAL, EXISTS, isNumerical, TYPE_NEGATE } from './types.js';
|
|
3
3
|
import { createVariableFilterBuffer } from './createVariableFilterBuffer.js';
|
|
4
4
|
import { createFixedFilterBuffer } from './createFixedFilterBuffer.js';
|
|
5
5
|
import { createReferenceFilter } from './createReferenceFilter.js';
|
|
@@ -9,10 +9,20 @@ export const primitiveFilter = (def, prop, filter, conditions, lang) => {
|
|
|
9
9
|
return;
|
|
10
10
|
}
|
|
11
11
|
let [, ctx, value] = filter;
|
|
12
|
-
const fieldIndexChar = prop.prop;
|
|
13
12
|
let buf;
|
|
14
|
-
|
|
13
|
+
const fieldIndexChar = prop.prop;
|
|
15
14
|
const bufferMap = prop.__isEdge ? conditions.edges : conditions.conditions;
|
|
15
|
+
if (ctx.operation === EXISTS) {
|
|
16
|
+
if (!conditions.exists) {
|
|
17
|
+
conditions.exists = [];
|
|
18
|
+
}
|
|
19
|
+
conditions.exists.push({
|
|
20
|
+
prop: prop,
|
|
21
|
+
negate: filter[1].type === TYPE_NEGATE,
|
|
22
|
+
});
|
|
23
|
+
return 4;
|
|
24
|
+
}
|
|
25
|
+
let size = 0;
|
|
16
26
|
const isArray = Array.isArray(value);
|
|
17
27
|
if (isArray && value.length === 1) {
|
|
18
28
|
value = value[0];
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { META_EDGE, META_OR_BRANCH, META_REFERENCE } from './types.js';
|
|
1
|
+
import { META_EDGE, META_EXISTS, META_OR_BRANCH, META_REFERENCE, TYPE_DEFAULT, TYPE_NEGATE, } from './types.js';
|
|
2
2
|
// or
|
|
3
3
|
// [meta = 253] [size 2] [next 4]
|
|
4
4
|
// -------------------------------------------
|
|
@@ -17,7 +17,6 @@ import { META_EDGE, META_OR_BRANCH, META_REFERENCE } from './types.js';
|
|
|
17
17
|
const writeConditions = (result, k, offset, conditions) => {
|
|
18
18
|
let lastWritten = offset;
|
|
19
19
|
result[lastWritten] = k;
|
|
20
|
-
// result[lasWritten + 1] = typeIndex
|
|
21
20
|
lastWritten++;
|
|
22
21
|
const sizeIndex = lastWritten;
|
|
23
22
|
lastWritten += 2;
|
|
@@ -27,7 +26,6 @@ const writeConditions = (result, k, offset, conditions) => {
|
|
|
27
26
|
result.set(condition, lastWritten);
|
|
28
27
|
lastWritten += condition.byteLength;
|
|
29
28
|
}
|
|
30
|
-
// make this u32
|
|
31
29
|
result.writeUint16LE(conditionSize, sizeIndex);
|
|
32
30
|
return lastWritten - offset;
|
|
33
31
|
};
|
|
@@ -76,6 +74,18 @@ export const fillConditionsBuffer = (result, conditions, offset) => {
|
|
|
76
74
|
result.writeUint32LE(lastWritten, orJumpIndex + 2);
|
|
77
75
|
lastWritten += size;
|
|
78
76
|
}
|
|
77
|
+
if (conditions.exists) {
|
|
78
|
+
for (const exists of conditions.exists) {
|
|
79
|
+
result[lastWritten] = META_EXISTS;
|
|
80
|
+
lastWritten++;
|
|
81
|
+
result[lastWritten] = exists.prop.prop;
|
|
82
|
+
lastWritten++;
|
|
83
|
+
result[lastWritten] = exists.negate ? TYPE_NEGATE : TYPE_DEFAULT;
|
|
84
|
+
lastWritten++;
|
|
85
|
+
result[lastWritten] = exists.prop.typeIndex;
|
|
86
|
+
lastWritten++;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
79
89
|
return lastWritten - offset;
|
|
80
90
|
};
|
|
81
91
|
// TODO convert to UINT8ARRAY
|
|
@@ -4,7 +4,7 @@ export type Filter = [fieldStr: string, ctx: FilterCtx, value: any];
|
|
|
4
4
|
export type FilterBranchFn = (filterBranch: FilterBranch) => void;
|
|
5
5
|
export type FilterAst = (Filter | FilterAst)[];
|
|
6
6
|
export declare const IsFilter: (f: FilterAst) => f is Filter;
|
|
7
|
-
export type Operator = '=' | 'has' | '!has' | '<' | '>' | '!=' | 'like' | '>=' | '<=' | '..' | '!..' | 'like';
|
|
7
|
+
export type Operator = '=' | 'has' | '!has' | '<' | '>' | '!=' | 'like' | '>=' | '<=' | '..' | '!..' | 'like' | 'exists' | '!exists';
|
|
8
8
|
export declare const VECTOR_FNS: string[];
|
|
9
9
|
export type FilterOpts<O = Operator> = {
|
|
10
10
|
lowerCase?: boolean;
|
|
@@ -27,7 +27,8 @@ export declare const HAS_TO_LOWER_CASE = 13;
|
|
|
27
27
|
export declare const STARTS_WITH_LOWER_CASE = 14;
|
|
28
28
|
export declare const ENDS_WITH_LOWER_CASE = 15;
|
|
29
29
|
export declare const LIKE = 18;
|
|
30
|
-
export
|
|
30
|
+
export declare const EXISTS = 19;
|
|
31
|
+
export type OPERATOR = typeof EQUAL | typeof HAS | typeof ENDS_WITH | typeof STARTS_WITH | typeof GREATER_THAN | typeof SMALLER_THAN | typeof GREATER_THAN_INCLUSIVE | typeof SMALLER_THAN_INCLUSIVE | typeof RANGE | typeof RANGE_EXCLUDE | typeof EQUAL_LOWER_CASE | typeof HAS_TO_LOWER_CASE | typeof STARTS_WITH_LOWER_CASE | typeof ENDS_WITH_LOWER_CASE | typeof LIKE | typeof EQUAL_CRC32 | typeof EXISTS;
|
|
31
32
|
export declare const isNumerical: (op: OPERATOR) => boolean;
|
|
32
33
|
export declare const TYPE_NEGATE = 1;
|
|
33
34
|
export declare const TYPE_DEFAULT = 2;
|
|
@@ -39,10 +40,11 @@ export declare const MODE_AND_FIXED = 3;
|
|
|
39
40
|
export declare const MODE_DEFAULT_VAR = 4;
|
|
40
41
|
export declare const MODE_REFERENCE = 5;
|
|
41
42
|
export type FILTER_MODE = typeof MODE_DEFAULT | typeof MODE_OR_FIXED | typeof MODE_OR_VAR | typeof MODE_AND_FIXED | typeof MODE_DEFAULT_VAR | typeof MODE_REFERENCE;
|
|
43
|
+
export declare const META_EXISTS = 251;
|
|
42
44
|
export declare const META_EDGE = 252;
|
|
43
45
|
export declare const META_OR_BRANCH = 253;
|
|
44
46
|
export declare const META_REFERENCE = 254;
|
|
45
|
-
export type FILTER_META = typeof META_EDGE | typeof META_OR_BRANCH | typeof META_REFERENCE;
|
|
47
|
+
export type FILTER_META = typeof META_EDGE | typeof META_OR_BRANCH | typeof META_REFERENCE | typeof META_EXISTS;
|
|
46
48
|
export type FilterCtx = {
|
|
47
49
|
operation: OPERATOR;
|
|
48
50
|
type: FILTER_TYPE;
|
|
@@ -34,6 +34,9 @@ export const STARTS_WITH_LOWER_CASE = 14;
|
|
|
34
34
|
export const ENDS_WITH_LOWER_CASE = 15;
|
|
35
35
|
export const LIKE = 18;
|
|
36
36
|
// -------------------------------------------
|
|
37
|
+
// only valid for seperate fields
|
|
38
|
+
export const EXISTS = 19;
|
|
39
|
+
// -------------------------------------------
|
|
37
40
|
export const isNumerical = (op) => {
|
|
38
41
|
if (op === GREATER_THAN ||
|
|
39
42
|
op === SMALLER_THAN ||
|
|
@@ -59,6 +62,7 @@ export const MODE_DEFAULT_VAR = 4;
|
|
|
59
62
|
export const MODE_REFERENCE = 5;
|
|
60
63
|
// -------------------------------------------
|
|
61
64
|
// Meta
|
|
65
|
+
export const META_EXISTS = 251;
|
|
62
66
|
export const META_EDGE = 252;
|
|
63
67
|
export const META_OR_BRANCH = 253;
|
|
64
68
|
export const META_REFERENCE = 254;
|
|
@@ -88,6 +92,13 @@ export const toFilterCtx = (def, op, opts = {}) => {
|
|
|
88
92
|
opts,
|
|
89
93
|
};
|
|
90
94
|
}
|
|
95
|
+
if (op === 'exists' || op === '!exists') {
|
|
96
|
+
return {
|
|
97
|
+
operation: EXISTS,
|
|
98
|
+
type: op === '!exists' ? TYPE_NEGATE : TYPE_DEFAULT,
|
|
99
|
+
opts,
|
|
100
|
+
};
|
|
101
|
+
}
|
|
91
102
|
if (op === 'has' || op === '!has') {
|
|
92
103
|
return {
|
|
93
104
|
operation: opts.lowerCase ? HAS_TO_LOWER_CASE : HAS,
|
|
@@ -129,5 +140,6 @@ export const operatorReverseMap = {
|
|
|
129
140
|
[ENDS_WITH_LOWER_CASE]: 'endsWith (lowerCase)',
|
|
130
141
|
[LIKE]: 'like',
|
|
131
142
|
[EQUAL_CRC32]: '= (crc32)',
|
|
143
|
+
[EXISTS]: 'exists',
|
|
132
144
|
};
|
|
133
145
|
//# sourceMappingURL=types.js.map
|
|
@@ -234,6 +234,12 @@ export const readAllFields = (q, result, offset, end, item, id) => {
|
|
|
234
234
|
}
|
|
235
235
|
i += size + 4;
|
|
236
236
|
}
|
|
237
|
+
else if (t === CARDINALITY) {
|
|
238
|
+
i++;
|
|
239
|
+
const size = readUint32(result, i);
|
|
240
|
+
addField(edgeDef, readUint32(result, i + 4), item);
|
|
241
|
+
i += size + 4;
|
|
242
|
+
}
|
|
237
243
|
else {
|
|
238
244
|
i++;
|
|
239
245
|
readMainValue(edgeDef, result, i, item);
|
|
@@ -290,7 +296,7 @@ export const readAllFields = (q, result, offset, end, item, id) => {
|
|
|
290
296
|
else if (prop.typeIndex === JSON) {
|
|
291
297
|
q.include.propsRead[index] = id;
|
|
292
298
|
const size = readUint32(result, i);
|
|
293
|
-
addField(prop, global.JSON.parse(
|
|
299
|
+
addField(prop, global.JSON.parse(readUtf8(result, i + 6, size - 6)), item);
|
|
294
300
|
i += size + 4;
|
|
295
301
|
}
|
|
296
302
|
else if (prop.typeIndex === BINARY) {
|
|
@@ -2,16 +2,7 @@ import { langCodesMap } from '@based/schema';
|
|
|
2
2
|
import { STRING, TEXT, VECTOR } from '@based/schema/def';
|
|
3
3
|
import { getVectorFn } from '../filter/types.js';
|
|
4
4
|
import { searchDoesNotExist, searchIncorrecQueryValue, searchIncorrectType, } from '../validation.js';
|
|
5
|
-
const
|
|
6
|
-
if (u8) {
|
|
7
|
-
const size = Buffer.allocUnsafe(1);
|
|
8
|
-
size[0] = nr;
|
|
9
|
-
return size;
|
|
10
|
-
}
|
|
11
|
-
const size = Buffer.allocUnsafe(2);
|
|
12
|
-
size.writeUint16LE(nr);
|
|
13
|
-
return size;
|
|
14
|
-
};
|
|
5
|
+
const ENCODER = new TextEncoder();
|
|
15
6
|
// vector
|
|
16
7
|
export const vectorSearch = (def, q, field, opts) => {
|
|
17
8
|
let prop = def.props[field];
|
|
@@ -23,7 +14,7 @@ export const vectorSearch = (def, q, field, opts) => {
|
|
|
23
14
|
}
|
|
24
15
|
// [isVec] [q len] [q len] [field] [fn] [score] [score] [score] [score] [q..]
|
|
25
16
|
let size = 9;
|
|
26
|
-
const vec =
|
|
17
|
+
const vec = new Uint8Array(q.buffer, 0, q.byteLength);
|
|
27
18
|
size += vec.byteLength;
|
|
28
19
|
def.search = {
|
|
29
20
|
size: size,
|
|
@@ -33,23 +24,38 @@ export const vectorSearch = (def, q, field, opts) => {
|
|
|
33
24
|
opts,
|
|
34
25
|
};
|
|
35
26
|
};
|
|
27
|
+
function concatBufs(bufs, totalByteLength) {
|
|
28
|
+
const res = new Uint8Array(totalByteLength);
|
|
29
|
+
let off = 0;
|
|
30
|
+
for (let i = 0; i < bufs.length; i++) {
|
|
31
|
+
const buf = bufs[i];
|
|
32
|
+
res.set(buf, off);
|
|
33
|
+
off += buf.byteLength;
|
|
34
|
+
}
|
|
35
|
+
return res;
|
|
36
|
+
}
|
|
36
37
|
export const search = (def, q, s) => {
|
|
37
38
|
const bufs = [];
|
|
38
|
-
let
|
|
39
|
+
let nrBlocks = 0;
|
|
40
|
+
let totalByteLength = 1;
|
|
39
41
|
if (typeof q !== 'string') {
|
|
40
42
|
searchIncorrecQueryValue(def, q);
|
|
41
43
|
q = '';
|
|
42
44
|
}
|
|
43
|
-
const x = q.toLowerCase().trim().split(' ');
|
|
45
|
+
const x = q.toLowerCase().normalize('NFKD').trim().split(' ').map((s) => ` ${s}`);
|
|
44
46
|
for (const s of x) {
|
|
45
47
|
if (s) {
|
|
46
|
-
const
|
|
47
|
-
|
|
48
|
-
|
|
48
|
+
const buf = ENCODER.encode(s);
|
|
49
|
+
let len = buf.byteLength - 2;
|
|
50
|
+
buf[0] = len;
|
|
51
|
+
buf[1] = len >>> 8;
|
|
52
|
+
bufs.push(buf);
|
|
53
|
+
nrBlocks++;
|
|
54
|
+
totalByteLength += len + 2;
|
|
49
55
|
}
|
|
50
56
|
}
|
|
51
|
-
bufs.unshift(
|
|
52
|
-
const query =
|
|
57
|
+
bufs.unshift(Uint8Array.from([nrBlocks]));
|
|
58
|
+
const query = concatBufs(bufs, totalByteLength);
|
|
53
59
|
def.search = {
|
|
54
60
|
size: query.byteLength + 3,
|
|
55
61
|
query,
|
|
@@ -115,7 +121,7 @@ export const searchToBuffer = (search) => {
|
|
|
115
121
|
result.writeUint16LE(search.query.byteLength, 1);
|
|
116
122
|
result[3] = search.prop;
|
|
117
123
|
result[4] = getVectorFn(search.opts.fn);
|
|
118
|
-
result.set(
|
|
124
|
+
result.set(new Uint8Array(new Float32Array([search.opts.score ?? 0.5]).buffer), 5);
|
|
119
125
|
result.set(search.query, 9);
|
|
120
126
|
return result;
|
|
121
127
|
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
const walk = (q) => {
|
|
2
|
+
const obj = {};
|
|
3
|
+
for (const key in q) {
|
|
4
|
+
if (key === 'schema') {
|
|
5
|
+
obj[key] = q[key].type;
|
|
6
|
+
}
|
|
7
|
+
else {
|
|
8
|
+
// if PROPDEF
|
|
9
|
+
if (typeof q[key] === 'object') {
|
|
10
|
+
obj[key] = walk(q[key]);
|
|
11
|
+
}
|
|
12
|
+
else {
|
|
13
|
+
obj[key] = q[key];
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
return obj;
|
|
18
|
+
};
|
|
19
|
+
export const serialize = (q) => {
|
|
20
|
+
const obj = walk(q);
|
|
21
|
+
return JSON.stringify(obj);
|
|
22
|
+
};
|
|
23
|
+
export const parse = (str, parsedSchema) => {
|
|
24
|
+
//
|
|
25
|
+
};
|
|
26
|
+
//# sourceMappingURL=serialize.js.map
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { QueryDef, QueryDefSort } from './types.js';
|
|
2
|
-
export declare const createSortBuffer: (sort: QueryDefSort) =>
|
|
2
|
+
export declare const createSortBuffer: (sort: QueryDefSort) => Uint8Array;
|
|
3
3
|
export declare const sort: (def: QueryDef, field: string, order?: "asc" | "desc") => void;
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import { validateSort } from './validation.js';
|
|
2
2
|
export const createSortBuffer = (sort) => {
|
|
3
|
-
const buf =
|
|
3
|
+
const buf = new Uint8Array(8);
|
|
4
4
|
// [order] [propType] [start] [start] [len] [len] [lang]
|
|
5
5
|
buf[0] = sort.order;
|
|
6
6
|
buf[1] = sort.prop.prop;
|
|
7
7
|
buf[2] = sort.prop.typeIndex;
|
|
8
|
-
buf
|
|
9
|
-
buf
|
|
8
|
+
buf[3] = sort.prop.start;
|
|
9
|
+
buf[4] = sort.prop.start >>> 8;
|
|
10
|
+
buf[5] = sort.prop.len;
|
|
11
|
+
buf[6] = sort.prop.len >>> 8;
|
|
10
12
|
buf[7] = sort.lang;
|
|
11
|
-
// console.info({ sort, buf: new Uint8Array(buf) })
|
|
12
|
-
//[LANG]
|
|
13
13
|
return buf;
|
|
14
14
|
};
|
|
15
15
|
// NO REF / REFERENCES SUPPORT
|
|
@@ -16,7 +16,7 @@ export const resultsAreEqual = (a, b) => {
|
|
|
16
16
|
return false;
|
|
17
17
|
return true;
|
|
18
18
|
};
|
|
19
|
-
const EMPTY = new Uint8Array(
|
|
19
|
+
const EMPTY = new Uint8Array(4);
|
|
20
20
|
export const runSubscription = (subscription) => {
|
|
21
21
|
if (!subscription.inProgress) {
|
|
22
22
|
subscription.inProgress = true;
|
|
@@ -30,6 +30,10 @@ export declare const isRefDef: (def: QueryDef) => def is QueryDefRest;
|
|
|
30
30
|
export type QueryDefFilter = {
|
|
31
31
|
size: number;
|
|
32
32
|
conditions: Map<number, Buffer[]>;
|
|
33
|
+
exists?: {
|
|
34
|
+
prop: PropDef | PropDefEdge;
|
|
35
|
+
negate: boolean;
|
|
36
|
+
}[];
|
|
33
37
|
references?: Map<number, QueryDefFilter>;
|
|
34
38
|
fromRef?: PropDef;
|
|
35
39
|
schema?: SchemaTypeDef;
|
|
@@ -39,7 +43,7 @@ export type QueryDefFilter = {
|
|
|
39
43
|
};
|
|
40
44
|
export type QueryDefSearch = {
|
|
41
45
|
size: number;
|
|
42
|
-
query:
|
|
46
|
+
query: Uint8Array;
|
|
43
47
|
isVector: false;
|
|
44
48
|
fields: {
|
|
45
49
|
weight: number;
|
|
@@ -49,7 +53,7 @@ export type QueryDefSearch = {
|
|
|
49
53
|
}[];
|
|
50
54
|
} | {
|
|
51
55
|
size: number;
|
|
52
|
-
query:
|
|
56
|
+
query: Uint8Array;
|
|
53
57
|
prop: number;
|
|
54
58
|
isVector: true;
|
|
55
59
|
opts: FilterOpts;
|