@based/db 0.0.28 → 0.0.29
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -399
- package/dist/lib/darwin_aarch64/include/selva/db.h +8 -4
- package/dist/lib/darwin_aarch64/include/selva/selva_hash128.h +17 -7
- package/dist/lib/darwin_aarch64/include/selva/sort.h +21 -14
- 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 +8 -4
- package/dist/lib/linux_aarch64/include/selva/selva_hash128.h +17 -7
- package/dist/lib/linux_aarch64/include/selva/sort.h +21 -14
- package/dist/lib/linux_aarch64/libdeflate.so +0 -0
- package/dist/lib/linux_aarch64/libjemalloc_selva.so.2 +0 -0
- 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 +8 -4
- package/dist/lib/linux_x86_64/include/selva/selva_hash128.h +17 -7
- package/dist/lib/linux_x86_64/include/selva/sort.h +21 -14
- package/dist/lib/linux_x86_64/libjemalloc_selva.so.2 +0 -0
- 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/flushModify.d.ts +1 -1
- package/dist/src/client/flushModify.js +12 -17
- package/dist/src/client/index.d.ts +6 -4
- package/dist/src/client/index.js +19 -2
- package/dist/src/client/modify/ModifyRes.d.ts +1 -1
- package/dist/src/client/modify/ModifyRes.js +14 -18
- package/dist/src/client/modify/fixed.js +43 -8
- package/dist/src/client/modify/modify.js +0 -1
- package/dist/src/client/modify/references/{appendRefs.d.ts → appendEdgeRefs.d.ts} +1 -1
- package/dist/src/client/modify/references/{appendRefs.js → appendEdgeRefs.js} +5 -2
- package/dist/src/client/modify/references/edge.js +182 -175
- package/dist/src/client/modify/references/reference.js +4 -8
- package/dist/src/client/modify/references/references.js +18 -14
- package/dist/src/client/modify/string.js +0 -3
- package/dist/src/client/modify/text.js +11 -3
- package/dist/src/client/modify/types.d.ts +11 -0
- package/dist/src/client/modify/types.js +10 -0
- package/dist/src/client/modify/update.js +4 -1
- package/dist/src/client/modify/vector.js +13 -4
- package/dist/src/client/query/BasedDbQuery.d.ts +1 -1
- package/dist/src/client/query/BasedDbQuery.js +2 -2
- package/dist/src/client/query/BasedIterable.d.ts +1 -1
- package/dist/src/client/query/BasedIterable.js +7 -2
- package/dist/src/client/query/filter/createFixedFilterBuffer.d.ts +2 -1
- package/dist/src/client/query/filter/createFixedFilterBuffer.js +11 -28
- package/dist/src/client/query/filter/createReferenceFilter.d.ts +2 -1
- package/dist/src/client/query/filter/createReferenceFilter.js +10 -9
- package/dist/src/client/query/filter/createVariableFilterBuffer.d.ts +2 -1
- package/dist/src/client/query/filter/createVariableFilterBuffer.js +8 -10
- package/dist/src/client/query/filter/parseFilterValue.js +1 -1
- package/dist/src/client/query/filter/primitiveFilter.js +9 -9
- package/dist/src/client/query/filter/toBuffer.js +0 -15
- package/dist/src/client/query/filter/types.d.ts +1 -0
- package/dist/src/client/query/filter/types.js +1 -0
- package/dist/src/client/query/include/walk.js +0 -1
- package/dist/src/client/query/read/read.js +4 -4
- package/dist/src/client/query/search/index.js +11 -15
- package/dist/src/client/query/subscription/markers.js +1 -2
- package/dist/src/client/query/subscription/run.js +0 -2
- package/dist/src/client/query/thresholds.d.ts +0 -2
- package/dist/src/client/query/thresholds.js +0 -2
- package/dist/src/client/query/toBuffer.js +16 -42
- package/dist/src/client/query/types.d.ts +3 -2
- package/dist/src/client/query/validation.d.ts +1 -3
- package/dist/src/client/query/validation.js +6 -18
- package/dist/src/client/string.d.ts +2 -0
- package/dist/src/client/string.js +9 -13
- package/dist/src/index.d.ts +1 -1
- package/dist/src/index.js +7 -15
- package/dist/src/native.d.ts +1 -1
- package/dist/src/native.js +3 -3
- package/dist/src/server/csmt/draw-dot.js +2 -2
- package/dist/src/server/csmt/tree.js +57 -6
- package/dist/src/server/csmt/types.d.ts +5 -0
- package/dist/src/server/index.d.ts +4 -3
- package/dist/src/server/index.js +44 -44
- package/dist/src/server/migrate/index.js +47 -29
- package/dist/src/server/migrate/worker.js +2 -2
- package/dist/src/server/save.js +40 -28
- package/dist/src/server/start.js +7 -19
- package/dist/src/server/tree.d.ts +2 -0
- package/dist/src/server/tree.js +34 -2
- package/dist/src/server/worker.js +3 -3
- package/dist/src/utils.d.ts +3 -1
- package/dist/src/utils.js +43 -19
- package/package.json +9 -3
- package/dist/lib/darwin_aarch64/include/selva/base64.h +0 -59
- package/dist/lib/darwin_aarch64/include/selva/base64url.h +0 -59
- package/dist/lib/linux_aarch64/include/selva/base64.h +0 -59
- package/dist/lib/linux_aarch64/include/selva/base64url.h +0 -59
- package/dist/lib/linux_x86_64/include/selva/base64.h +0 -59
- package/dist/lib/linux_x86_64/include/selva/base64url.h +0 -59
- package/dist/src/client/timestamp.d.ts +0 -1
- package/dist/src/client/timestamp.js +0 -68
|
@@ -13,6 +13,7 @@ const byteSize = (arr) => {
|
|
|
13
13
|
export function defToBuffer(db, def) {
|
|
14
14
|
const result = [];
|
|
15
15
|
const include = includeToBuffer(db, def);
|
|
16
|
+
// ---------------------------------------
|
|
16
17
|
def.references.forEach((ref) => {
|
|
17
18
|
include.push(...defToBuffer(db, ref));
|
|
18
19
|
if (ref.errors) {
|
|
@@ -32,27 +33,21 @@ export function defToBuffer(db, def) {
|
|
|
32
33
|
edgesSize = byteSize(edges);
|
|
33
34
|
}
|
|
34
35
|
const size = (edges ? edgesSize + 3 : 0) + byteSize(include);
|
|
36
|
+
// ---------------------------------------
|
|
37
|
+
// move down and will handle size after store the size Var
|
|
38
|
+
// only for references | edges
|
|
35
39
|
if (def.type === QueryDefType.Root) {
|
|
36
|
-
let filter;
|
|
37
|
-
let filterSize = 0;
|
|
38
40
|
let search;
|
|
39
41
|
let searchSize = 0;
|
|
42
|
+
const filterSize = def.filter.size || 0;
|
|
40
43
|
if (def.search) {
|
|
41
44
|
search = searchToBuffer(def.search);
|
|
42
45
|
searchSize = def.search.size;
|
|
43
46
|
}
|
|
44
|
-
if (def.filter.size) {
|
|
45
|
-
filter = filterToBuffer(def.filter);
|
|
46
|
-
filterSize = filter.byteLength;
|
|
47
|
-
}
|
|
48
|
-
// [type,type]
|
|
49
|
-
// [q type] 0 == id, 1 === ids, 2 === type only
|
|
50
47
|
if (def.target.resolvedAlias) {
|
|
51
|
-
// put this somehwere else at some point
|
|
52
48
|
const alias = def.target.resolvedAlias;
|
|
53
49
|
const aliasStr = ENCODER.encode(alias.value);
|
|
54
50
|
const aliasLen = aliasStr.byteLength;
|
|
55
|
-
// filter is nice for things like access
|
|
56
51
|
const buf = new Uint8Array(8 + filterSize + aliasLen);
|
|
57
52
|
buf[0] = 3;
|
|
58
53
|
buf[1] = def.schema.idUint8[0];
|
|
@@ -64,14 +59,11 @@ export function defToBuffer(db, def) {
|
|
|
64
59
|
buf[6 + aliasLen] = filterSize;
|
|
65
60
|
buf[7 + aliasLen] = filterSize >>> 8;
|
|
66
61
|
if (filterSize) {
|
|
67
|
-
buf.set(filter, 8 + aliasLen);
|
|
62
|
+
buf.set(filterToBuffer(def.filter), 8 + aliasLen);
|
|
68
63
|
}
|
|
69
64
|
result.push(buf);
|
|
70
65
|
}
|
|
71
66
|
else if (def.target.id) {
|
|
72
|
-
// type 0
|
|
73
|
-
// 0: 4 [id]
|
|
74
|
-
// 0: 2 [filterSize]
|
|
75
67
|
const buf = new Uint8Array(9 + filterSize);
|
|
76
68
|
buf[0] = 0;
|
|
77
69
|
buf[1] = def.schema.idUint8[0];
|
|
@@ -83,7 +75,7 @@ export function defToBuffer(db, def) {
|
|
|
83
75
|
buf[7] = filterSize;
|
|
84
76
|
buf[8] = filterSize >>> 8;
|
|
85
77
|
if (filterSize) {
|
|
86
|
-
buf.set(filter, 9);
|
|
78
|
+
buf.set(filterToBuffer(def.filter), 9);
|
|
87
79
|
}
|
|
88
80
|
result.push(buf);
|
|
89
81
|
}
|
|
@@ -95,15 +87,10 @@ export function defToBuffer(db, def) {
|
|
|
95
87
|
sortSize = sort.byteLength;
|
|
96
88
|
}
|
|
97
89
|
let aggregation;
|
|
98
|
-
|
|
90
|
+
if (def.aggregation) {
|
|
91
|
+
aggregation = createAggFlagBuffer(def.aggregation);
|
|
92
|
+
}
|
|
99
93
|
if (def.target.ids) {
|
|
100
|
-
// type 1
|
|
101
|
-
// 1: 4 + ids * 4 [ids len] [id,id,id]
|
|
102
|
-
// 1: 8 [offset, limit]
|
|
103
|
-
// 1: 2 [filter size]
|
|
104
|
-
// ?filter
|
|
105
|
-
// 1: 2 [sort size]
|
|
106
|
-
// ?sort
|
|
107
94
|
if (!sortSize &&
|
|
108
95
|
(def.range.offset || def.range.limit < def.target.ids.length)) {
|
|
109
96
|
def.target.ids = def.target.ids.slice(def.range.offset, def.range.offset + def.range.limit);
|
|
@@ -129,7 +116,8 @@ export function defToBuffer(db, def) {
|
|
|
129
116
|
buf[idsSize + 15] = filterSize;
|
|
130
117
|
buf[idsSize + 16] = filterSize >>> 8;
|
|
131
118
|
if (filterSize) {
|
|
132
|
-
|
|
119
|
+
// just write it here dont do set
|
|
120
|
+
buf.set(filterToBuffer(def.filter), idsSize + 17);
|
|
133
121
|
}
|
|
134
122
|
buf[17 + filterSize + idsSize] = sortSize;
|
|
135
123
|
buf[18 + filterSize + idsSize] = sortSize >>> 8;
|
|
@@ -145,13 +133,6 @@ export function defToBuffer(db, def) {
|
|
|
145
133
|
result.push(buf);
|
|
146
134
|
}
|
|
147
135
|
else {
|
|
148
|
-
// type 2
|
|
149
|
-
// 2: 0
|
|
150
|
-
// 2: 8 [offset, limit]
|
|
151
|
-
// 2: 2 [filter size]
|
|
152
|
-
// ?filter
|
|
153
|
-
// 2: 2 [sort size]
|
|
154
|
-
// ?sort
|
|
155
136
|
const buf = new Uint8Array(18 + filterSize + sortSize + searchSize);
|
|
156
137
|
buf[0] = 2;
|
|
157
138
|
buf[1] = def.schema.idUint8[0];
|
|
@@ -167,7 +148,7 @@ export function defToBuffer(db, def) {
|
|
|
167
148
|
buf[11] = filterSize;
|
|
168
149
|
buf[12] = filterSize >>> 8;
|
|
169
150
|
if (filterSize) {
|
|
170
|
-
buf.set(filter, 13);
|
|
151
|
+
buf.set(filterToBuffer(def.filter), 13);
|
|
171
152
|
}
|
|
172
153
|
buf[13 + filterSize] = sortSize;
|
|
173
154
|
buf[14 + filterSize] = sortSize >>> 8;
|
|
@@ -187,19 +168,12 @@ export function defToBuffer(db, def) {
|
|
|
187
168
|
}
|
|
188
169
|
}
|
|
189
170
|
else if (def.type === QueryDefType.References) {
|
|
190
|
-
|
|
191
|
-
let filter;
|
|
192
|
-
if (def.filter.size) {
|
|
193
|
-
filter = filterToBuffer(def.filter);
|
|
194
|
-
}
|
|
171
|
+
const filterSize = def.filter.size || 0;
|
|
195
172
|
let sort;
|
|
196
173
|
if (def.sort) {
|
|
197
174
|
sort = createSortBuffer(def.sort);
|
|
198
175
|
}
|
|
199
|
-
// ADD IT
|
|
200
|
-
// TODO: ADD RANGE [offset,limit] (8 bytes)
|
|
201
176
|
const sortSize = sort?.byteLength ?? 0;
|
|
202
|
-
const filterSize = filter?.byteLength ?? 0;
|
|
203
177
|
const modsSize = filterSize + sortSize;
|
|
204
178
|
const meta = new Uint8Array(modsSize + 10 + 8);
|
|
205
179
|
const sz = size + 7 + modsSize + 8;
|
|
@@ -218,8 +192,8 @@ export function defToBuffer(db, def) {
|
|
|
218
192
|
meta[12] = def.range.limit >>> 8;
|
|
219
193
|
meta[13] = def.range.limit >>> 16;
|
|
220
194
|
meta[14] = def.range.limit >>> 24;
|
|
221
|
-
if (
|
|
222
|
-
meta.set(filter, 15);
|
|
195
|
+
if (filterSize) {
|
|
196
|
+
meta.set(filterToBuffer(def.filter), 15);
|
|
223
197
|
}
|
|
224
198
|
if (sort) {
|
|
225
199
|
meta.set(sort, 15 + filterSize);
|
|
@@ -27,9 +27,10 @@ export type Target = {
|
|
|
27
27
|
};
|
|
28
28
|
};
|
|
29
29
|
export declare const isRefDef: (def: QueryDef) => def is QueryDefRest;
|
|
30
|
+
export type FilterCondition = Uint8Array;
|
|
30
31
|
export type QueryDefFilter = {
|
|
31
32
|
size: number;
|
|
32
|
-
conditions: Map<number,
|
|
33
|
+
conditions: Map<number, FilterCondition[]>;
|
|
33
34
|
exists?: {
|
|
34
35
|
prop: PropDef | PropDefEdge;
|
|
35
36
|
negate: boolean;
|
|
@@ -37,7 +38,7 @@ export type QueryDefFilter = {
|
|
|
37
38
|
references?: Map<number, QueryDefFilter>;
|
|
38
39
|
fromRef?: PropDef;
|
|
39
40
|
schema?: SchemaTypeDef;
|
|
40
|
-
edges?: Map<number,
|
|
41
|
+
edges?: Map<number, FilterCondition[]>;
|
|
41
42
|
or?: QueryDefFilter;
|
|
42
43
|
and?: QueryDefFilter;
|
|
43
44
|
};
|
|
@@ -61,9 +61,7 @@ export declare const searchIncorrecQueryValue: (def: QueryDef, payload: any) =>
|
|
|
61
61
|
export declare const searchIncorrectType: (def: QueryDef, payload: PropDef | PropDefEdge) => void;
|
|
62
62
|
export declare const searchDoesNotExist: (def: QueryDef, field: string, isVector: boolean) => PropDef;
|
|
63
63
|
export declare const validateRange: (def: QueryDef, offset: number, limit: number) => boolean;
|
|
64
|
-
export declare const
|
|
65
|
-
export declare const isValidString: (v: any) => boolean;
|
|
66
|
-
export declare const validateVal: (def: QueryDef, f: Filter, validate: (v: any) => boolean) => boolean;
|
|
64
|
+
export declare const validateVal: (def: QueryDef, f: Filter, validate: (v: any, p: PropDef | PropDefEdge) => boolean) => boolean;
|
|
67
65
|
export declare const validateFilter: (def: QueryDef, prop: PropDef | PropDefEdge, f: Filter) => boolean;
|
|
68
66
|
export declare const validateType: (db: DbClient, def: QueryDef, type: string) => SchemaTypeDef;
|
|
69
67
|
export declare const filterOperatorDoesNotExist: (def: QueryDef, field: string) => void;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import picocolors from 'picocolors';
|
|
2
2
|
import { ALIAS, BINARY, BOOLEAN, REFERENCE, REFERENCES, REVERSE_TYPE_INDEX_MAP, STRING, TEXT, TIMESTAMP, VECTOR, propIsNumerical, createEmptyDef, DEFAULT_MAP, } from '@based/schema/def';
|
|
3
3
|
import { EQUAL, EXISTS, HAS, isNumerical, LIKE, operatorReverseMap, VECTOR_FNS, } from './filter/types.js';
|
|
4
|
-
import {
|
|
4
|
+
import { MAX_IDS_PER_QUERY } from './thresholds.js';
|
|
5
5
|
import { displayTarget, safeStringify } from './display.js';
|
|
6
|
-
import { langCodesMap } from '@based/schema';
|
|
6
|
+
import { isValidId, isValidString, langCodesMap, MAX_ID, } from '@based/schema';
|
|
7
7
|
export const ERR_TARGET_INVAL_TYPE = 1;
|
|
8
8
|
export const ERR_TARGET_INVAL_ALIAS = 2;
|
|
9
9
|
export const ERR_TARGET_EXCEED_MAX_IDS = 3;
|
|
@@ -85,18 +85,6 @@ export const validateRange = (def, offset, limit) => {
|
|
|
85
85
|
}
|
|
86
86
|
return r;
|
|
87
87
|
};
|
|
88
|
-
export const isValidId = (id) => {
|
|
89
|
-
if (typeof id != 'number' || id < MIN_ID_VALUE || id > MAX_ID_VALUE) {
|
|
90
|
-
return false;
|
|
91
|
-
}
|
|
92
|
-
return true;
|
|
93
|
-
};
|
|
94
|
-
export const isValidString = (v) => {
|
|
95
|
-
const isVal = typeof v === 'string' ||
|
|
96
|
-
v instanceof Uint8Array ||
|
|
97
|
-
ArrayBuffer.isView(v);
|
|
98
|
-
return isVal;
|
|
99
|
-
};
|
|
100
88
|
export const validateVal = (def, f, validate) => {
|
|
101
89
|
if (def.skipValidation) {
|
|
102
90
|
return false;
|
|
@@ -104,13 +92,13 @@ export const validateVal = (def, f, validate) => {
|
|
|
104
92
|
const value = f[2];
|
|
105
93
|
if (Array.isArray(value)) {
|
|
106
94
|
for (const v of value) {
|
|
107
|
-
if (!validate(v)) {
|
|
95
|
+
if (!validate(v, f[2])) {
|
|
108
96
|
def.errors.push({ code: ERR_FILTER_INVALID_VAL, payload: f });
|
|
109
97
|
return true;
|
|
110
98
|
}
|
|
111
99
|
}
|
|
112
100
|
}
|
|
113
|
-
else if (!validate(value)) {
|
|
101
|
+
else if (!validate(value, f[2])) {
|
|
114
102
|
def.errors.push({
|
|
115
103
|
code: ERR_FILTER_INVALID_VAL,
|
|
116
104
|
payload: f,
|
|
@@ -147,7 +135,7 @@ export const validateFilter = (def, prop, f) => {
|
|
|
147
135
|
});
|
|
148
136
|
return true;
|
|
149
137
|
}
|
|
150
|
-
if (validateVal(def, f,
|
|
138
|
+
if (validateVal(def, f, prop.validation)) {
|
|
151
139
|
return true;
|
|
152
140
|
}
|
|
153
141
|
}
|
|
@@ -287,7 +275,7 @@ export const validateSort = (def, field, orderInput) => {
|
|
|
287
275
|
}
|
|
288
276
|
}
|
|
289
277
|
const type = propDef.typeIndex;
|
|
290
|
-
if (type === REFERENCES || type === REFERENCE) {
|
|
278
|
+
if (type === REFERENCES || type === REFERENCE || type === VECTOR) {
|
|
291
279
|
def.errors.push({
|
|
292
280
|
code: ERR_SORT_TYPE,
|
|
293
281
|
payload: propDef,
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { LangCode } from '@based/schema';
|
|
2
|
+
export declare const COMPRESSED = 1;
|
|
3
|
+
export declare const NOT_COMPRESSED = 0;
|
|
2
4
|
export declare const write: (buf: Uint8Array, value: string, offset: number, noCompression: boolean, lang?: LangCode) => number;
|
|
3
5
|
export declare const compress: (str: string) => Uint8Array;
|
|
4
6
|
export declare const decompress: (val: Uint8Array) => string;
|
|
@@ -3,12 +3,8 @@ import { readUint32 } from './../utils.js';
|
|
|
3
3
|
import makeTmpBuffer from './tmpBuffer.js';
|
|
4
4
|
import { DECODER, ENCODER } from '../utils.js';
|
|
5
5
|
const { getUint8Array: getTmpBuffer } = makeTmpBuffer(4096); // the usual page size?
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
// var cnt = 0
|
|
9
|
-
// var bytesSaved = 0
|
|
10
|
-
// make this into a package
|
|
11
|
-
// write the type Byte
|
|
6
|
+
export const COMPRESSED = 1;
|
|
7
|
+
export const NOT_COMPRESSED = 0;
|
|
12
8
|
export const write = (buf, value, offset, noCompression, lang) => {
|
|
13
9
|
value = value.normalize('NFKD');
|
|
14
10
|
buf[offset] = lang || 0;
|
|
@@ -19,7 +15,7 @@ export const write = (buf, value, offset, noCompression, lang) => {
|
|
|
19
15
|
buf.copyWithin(offset + 6 + l, offset + 2, offset + 2 + l);
|
|
20
16
|
const size = native.compress(buf, offset + 6, l);
|
|
21
17
|
if (size === 0) {
|
|
22
|
-
buf[offset + 1] =
|
|
18
|
+
buf[offset + 1] = NOT_COMPRESSED;
|
|
23
19
|
ENCODER.encodeInto(value, buf.subarray(offset + 2));
|
|
24
20
|
buf[offset + l + 2] = crc;
|
|
25
21
|
buf[offset + l + 3] = crc >>>= 8;
|
|
@@ -29,7 +25,7 @@ export const write = (buf, value, offset, noCompression, lang) => {
|
|
|
29
25
|
}
|
|
30
26
|
else {
|
|
31
27
|
let len = l;
|
|
32
|
-
buf[offset + 1] =
|
|
28
|
+
buf[offset + 1] = COMPRESSED;
|
|
33
29
|
buf[offset + 2] = len;
|
|
34
30
|
buf[offset + 3] = len >>>= 8;
|
|
35
31
|
buf[offset + 4] = len >>>= 8;
|
|
@@ -38,11 +34,11 @@ export const write = (buf, value, offset, noCompression, lang) => {
|
|
|
38
34
|
buf[offset + size + 7] = crc >>>= 8;
|
|
39
35
|
buf[offset + size + 8] = crc >>>= 8;
|
|
40
36
|
buf[offset + size + 9] = crc >>>= 8;
|
|
41
|
-
return size + 10;
|
|
37
|
+
return size + 10;
|
|
42
38
|
}
|
|
43
39
|
}
|
|
44
40
|
else {
|
|
45
|
-
buf[offset + 1] =
|
|
41
|
+
buf[offset + 1] = NOT_COMPRESSED;
|
|
46
42
|
buf[offset + l + 2] = crc;
|
|
47
43
|
buf[offset + l + 3] = crc >>>= 8;
|
|
48
44
|
buf[offset + l + 4] = crc >>>= 8;
|
|
@@ -63,14 +59,14 @@ export const decompress = (val) => {
|
|
|
63
59
|
};
|
|
64
60
|
export const read = (val, offset, len) => {
|
|
65
61
|
const type = val[offset + 1];
|
|
66
|
-
if (type ==
|
|
62
|
+
if (type == COMPRESSED) {
|
|
67
63
|
const origSize = readUint32(val, offset + 2);
|
|
68
64
|
const newBuffer = getTmpBuffer(origSize);
|
|
69
|
-
//
|
|
65
|
+
// Browser fallback required for this
|
|
70
66
|
native.decompress(val, newBuffer, offset + 6, len - 6);
|
|
71
67
|
return DECODER.decode(newBuffer);
|
|
72
68
|
}
|
|
73
|
-
else if (type ==
|
|
69
|
+
else if (type == NOT_COMPRESSED) {
|
|
74
70
|
return DECODER.decode(val.subarray(offset + 2, len + offset - 4));
|
|
75
71
|
}
|
|
76
72
|
return '';
|
package/dist/src/index.d.ts
CHANGED
package/dist/src/index.js
CHANGED
|
@@ -2,8 +2,8 @@ import { compress, decompress } from './client/string.js';
|
|
|
2
2
|
import { ModifyCtx } from './client/flushModify.js';
|
|
3
3
|
import { DbServer } from './server/index.js';
|
|
4
4
|
import { DbClient } from './client/index.js';
|
|
5
|
-
import picocolors from 'picocolors';
|
|
6
5
|
import { wait } from '@saulx/utils';
|
|
6
|
+
import { debugMode, debugServer } from './utils.js';
|
|
7
7
|
export * from './client/modify/modify.js';
|
|
8
8
|
export { compress, decompress };
|
|
9
9
|
export { ModifyCtx }; // TODO move this somewhere
|
|
@@ -23,16 +23,11 @@ export class BasedDb {
|
|
|
23
23
|
constructor(opts) {
|
|
24
24
|
this.#init(opts);
|
|
25
25
|
if (opts.debug) {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
const str = [`[${key}]`, ...arguments].join(' ');
|
|
32
|
-
console.info(picocolors.dim(str));
|
|
33
|
-
return fn.apply(this, arguments);
|
|
34
|
-
};
|
|
35
|
-
}
|
|
26
|
+
if (opts.debug === 'server') {
|
|
27
|
+
debugServer(this.server);
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
debugMode(this);
|
|
36
31
|
}
|
|
37
32
|
}
|
|
38
33
|
}
|
|
@@ -49,7 +44,6 @@ export class BasedDb {
|
|
|
49
44
|
const client = new DbClient({
|
|
50
45
|
maxModifySize,
|
|
51
46
|
hooks: {
|
|
52
|
-
flushTime: 0,
|
|
53
47
|
setSchema(schema, fromStart) {
|
|
54
48
|
return Promise.resolve(server.setSchema(schema, fromStart));
|
|
55
49
|
},
|
|
@@ -59,8 +53,6 @@ export class BasedDb {
|
|
|
59
53
|
offsets,
|
|
60
54
|
});
|
|
61
55
|
},
|
|
62
|
-
flushReady: () => { },
|
|
63
|
-
flushIsReady: new Promise(() => { }),
|
|
64
56
|
getQueryBuf(buf) {
|
|
65
57
|
return Promise.resolve(server.getQueryBuf(buf));
|
|
66
58
|
},
|
|
@@ -127,7 +119,7 @@ export class BasedDb {
|
|
|
127
119
|
await this.isModified();
|
|
128
120
|
// Tmp fix: Gives node time to GC existing buffers else it can incorrectly re-asign to mem
|
|
129
121
|
// Todo: clear all active queries, queues ETC
|
|
130
|
-
await wait(Math.max(this.client.
|
|
122
|
+
await wait(Math.max(this.client.flushTime + 10, 10));
|
|
131
123
|
this.client.destroy();
|
|
132
124
|
await this.server.destroy();
|
|
133
125
|
}
|
package/dist/src/native.d.ts
CHANGED
|
@@ -21,7 +21,7 @@ declare const _default: {
|
|
|
21
21
|
createSortIndex: (buf: Uint8Array, dbCtx: any) => any;
|
|
22
22
|
destroySortIndex: (buf: Uint8Array, dbCtx: any) => any;
|
|
23
23
|
xxHash64: (buf: Uint8Array, target: Uint8Array, index: number) => any;
|
|
24
|
-
base64encode: (dst: Uint8Array, src: Uint8Array, lineMax: number) => Uint8Array;
|
|
25
24
|
equals: (a: Uint8Array, b: Uint8Array) => boolean;
|
|
25
|
+
expire: (dbCtx: any) => void;
|
|
26
26
|
};
|
|
27
27
|
export default _default;
|
package/dist/src/native.js
CHANGED
|
@@ -90,11 +90,11 @@ export default {
|
|
|
90
90
|
xxHash64: (buf, target, index) => {
|
|
91
91
|
return db.xxHash64(buf, target, index);
|
|
92
92
|
},
|
|
93
|
-
base64encode: (dst, src, lineMax) => {
|
|
94
|
-
return db.base64encode(dst, src, lineMax);
|
|
95
|
-
},
|
|
96
93
|
equals: (a, b) => {
|
|
97
94
|
return !!db.equals(a, b);
|
|
98
95
|
},
|
|
96
|
+
expire: (dbCtx) => {
|
|
97
|
+
db.expire(dbCtx);
|
|
98
|
+
},
|
|
99
99
|
};
|
|
100
100
|
//# sourceMappingURL=native.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { encodeBase64 } from '@saulx/utils';
|
|
2
2
|
function makeLabel(node) {
|
|
3
|
-
return `${node.key}\n${
|
|
3
|
+
return `${node.key}\n${encodeBase64(node.hash).substring(0, 5)}`;
|
|
4
4
|
}
|
|
5
5
|
export default function draw(csmt) {
|
|
6
6
|
const root = csmt.getRoot();
|
|
@@ -12,9 +12,7 @@ export function createTree(createHash) {
|
|
|
12
12
|
return createHash().update(lHash).update(rHash).digest();
|
|
13
13
|
}
|
|
14
14
|
function createNode(left, right) {
|
|
15
|
-
const hash = left && right
|
|
16
|
-
? genNodeHash(left.hash, right.hash)
|
|
17
|
-
: emptyHash;
|
|
15
|
+
const hash = left && right ? genNodeHash(left.hash, right.hash) : emptyHash;
|
|
18
16
|
return {
|
|
19
17
|
hash,
|
|
20
18
|
key: max(left, right),
|
|
@@ -56,7 +54,7 @@ export function createTree(createHash) {
|
|
|
56
54
|
return createNode(newLeaf, node);
|
|
57
55
|
}
|
|
58
56
|
else {
|
|
59
|
-
throw new Error(
|
|
57
|
+
throw new Error(`k=${k} exists`);
|
|
60
58
|
}
|
|
61
59
|
}
|
|
62
60
|
const lDist = distance(k, (left && left.key) || TreeKeyNil);
|
|
@@ -120,6 +118,47 @@ export function createTree(createHash) {
|
|
|
120
118
|
}
|
|
121
119
|
}
|
|
122
120
|
}
|
|
121
|
+
function updateNodeHash(node) {
|
|
122
|
+
if (node.left && node.right) {
|
|
123
|
+
node.hash = genNodeHash(node.left.hash, node.right.hash);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
function updateHash(node, k, hash) {
|
|
127
|
+
if (!node)
|
|
128
|
+
return;
|
|
129
|
+
const { left, right } = node;
|
|
130
|
+
if (k === node.key && !left && !right) {
|
|
131
|
+
node.hash = hash;
|
|
132
|
+
}
|
|
133
|
+
else {
|
|
134
|
+
if (left && left.key === k) {
|
|
135
|
+
updateHash(left, k, hash);
|
|
136
|
+
updateNodeHash(left);
|
|
137
|
+
updateNodeHash(node);
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
if (right && right.key === k) {
|
|
141
|
+
updateHash(right, k, hash);
|
|
142
|
+
updateNodeHash(right);
|
|
143
|
+
updateNodeHash(node);
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
const lDist = distance(k, (left && left.key) || TreeKeyNil);
|
|
147
|
+
const rDist = distance(k, (right && right.key) || TreeKeyNil);
|
|
148
|
+
if (left && lDist <= rDist) {
|
|
149
|
+
updateHash(left, k, hash);
|
|
150
|
+
updateNodeHash(left);
|
|
151
|
+
updateNodeHash(node);
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
if (right && rDist <= lDist) {
|
|
155
|
+
updateHash(right, k, hash);
|
|
156
|
+
updateNodeHash(right);
|
|
157
|
+
updateNodeHash(node);
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
123
162
|
function diffAB(diffA, diffB, nodeA, nodeB) {
|
|
124
163
|
if (nodeA &&
|
|
125
164
|
nodeB &&
|
|
@@ -190,13 +229,20 @@ export function createTree(createHash) {
|
|
|
190
229
|
if (!node || (k === node.key && !node.left && !node.right))
|
|
191
230
|
return node;
|
|
192
231
|
const { left, right } = node;
|
|
193
|
-
if (left &&
|
|
232
|
+
if (left && left.key === k)
|
|
233
|
+
return search(left, k);
|
|
234
|
+
if (right && right.key === k)
|
|
235
|
+
return search(right, k);
|
|
236
|
+
const lDist = distance(k, (left && left.key) || TreeKeyNil);
|
|
237
|
+
const rDist = distance(k, (right && right.key) || TreeKeyNil);
|
|
238
|
+
if (left && lDist <= rDist)
|
|
194
239
|
return search(left, k);
|
|
195
|
-
if (right &&
|
|
240
|
+
if (right && rDist <= lDist)
|
|
196
241
|
return search(right, k);
|
|
197
242
|
return null;
|
|
198
243
|
}
|
|
199
244
|
return {
|
|
245
|
+
emptyHash,
|
|
200
246
|
getRoot: () => root,
|
|
201
247
|
insert: (k, h, data = null) => {
|
|
202
248
|
if (!(h instanceof Uint8Array)) {
|
|
@@ -205,6 +251,11 @@ export function createTree(createHash) {
|
|
|
205
251
|
const newLeaf = createLeaf(k, h, data);
|
|
206
252
|
root = root ? insert(root, newLeaf) : newLeaf;
|
|
207
253
|
},
|
|
254
|
+
update: (k, h) => {
|
|
255
|
+
if (root) {
|
|
256
|
+
updateHash(root, k, h);
|
|
257
|
+
}
|
|
258
|
+
},
|
|
208
259
|
delete: (k) => {
|
|
209
260
|
if (root) {
|
|
210
261
|
root = deleteNode(root, k);
|
|
@@ -15,6 +15,7 @@ export interface TreeDiff {
|
|
|
15
15
|
right: KeyHashPair[];
|
|
16
16
|
}
|
|
17
17
|
export interface Csmt {
|
|
18
|
+
emptyHash: Uint8Array;
|
|
18
19
|
/**
|
|
19
20
|
* Get the root node.
|
|
20
21
|
*/
|
|
@@ -27,6 +28,10 @@ export interface Csmt {
|
|
|
27
28
|
* Delete a key-hash pair from the tree.
|
|
28
29
|
*/
|
|
29
30
|
delete: (k: TreeKey) => void;
|
|
31
|
+
/**
|
|
32
|
+
* Update node hash.
|
|
33
|
+
*/
|
|
34
|
+
update: (k: TreeKey, h: Hash) => void;
|
|
30
35
|
/**
|
|
31
36
|
* Compute the diff between this and a given tree.
|
|
32
37
|
*/
|
|
@@ -50,10 +50,11 @@ export declare class DbServer {
|
|
|
50
50
|
stopped: boolean;
|
|
51
51
|
onSchemaChange: OnSchemaChange;
|
|
52
52
|
unlistenExit: ReturnType<typeof exitHook>;
|
|
53
|
-
constructor({ path, maxModifySize, onSchemaChange, }: {
|
|
53
|
+
constructor({ path, maxModifySize, onSchemaChange, debug, }: {
|
|
54
54
|
path: string;
|
|
55
55
|
maxModifySize?: number;
|
|
56
56
|
onSchemaChange?: OnSchemaChange;
|
|
57
|
+
debug?: boolean;
|
|
57
58
|
});
|
|
58
59
|
start(opts?: {
|
|
59
60
|
clean?: boolean;
|
|
@@ -85,14 +86,14 @@ export declare class DbServer {
|
|
|
85
86
|
lastId: number;
|
|
86
87
|
}>;
|
|
87
88
|
createSortIndexBuffer(typeId: number, field: number, start: number, lang: number): SortIndex;
|
|
88
|
-
updateMerkleTree(): void;
|
|
89
89
|
setSchema(strictSchema: StrictSchema, fromStart?: boolean, transformFns?: TransformFns): (StrictSchema & {
|
|
90
90
|
lastId: number;
|
|
91
91
|
}) | Promise<StrictSchema & {
|
|
92
92
|
lastId: number;
|
|
93
93
|
}>;
|
|
94
94
|
modify(buf: Uint8Array): Record<number, number>;
|
|
95
|
-
|
|
95
|
+
addToQueryQueue(resolve: any, buf: any): void;
|
|
96
|
+
getQueryBuf(buf: Uint8Array, fromQueue?: boolean): Promise<Uint8Array>;
|
|
96
97
|
onQueryEnd(): void;
|
|
97
98
|
stop(noSave?: boolean): Promise<void>;
|
|
98
99
|
destroy(): Promise<void>;
|