@based/db 0.1.3-alpha.1 → 0.1.3
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/basedDbNative.cjs +23 -0
- package/dist/lib/darwin_aarch64/include/cdefs.h +4 -1
- package/dist/lib/darwin_aarch64/include/selva/db.h +28 -5
- package/dist/lib/darwin_aarch64/include/selva/fast_linear_search.h +2 -2
- package/dist/lib/darwin_aarch64/include/selva/fields.h +13 -41
- package/dist/lib/darwin_aarch64/include/selva/selva_string.h +4 -0
- package/dist/lib/darwin_aarch64/include/selva/types.h +1 -11
- 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-v22.node +0 -0
- package/dist/lib/darwin_aarch64/libselva.dylib +0 -0
- package/dist/lib/darwin_aarch64/libxxhash.dylib +0 -0
- package/dist/src/client/index.d.ts +2 -0
- package/dist/src/client/index.js +11 -2
- package/dist/src/client/modify/Ctx.d.ts +3 -5
- package/dist/src/client/modify/Ctx.js +0 -3
- package/dist/src/client/modify/Tmp.d.ts +2 -2
- package/dist/src/client/modify/Tmp.js +27 -23
- package/dist/src/client/modify/create/index.js +36 -25
- package/dist/src/client/modify/cursor.d.ts +0 -1
- package/dist/src/client/modify/cursor.js +10 -26
- package/dist/src/client/modify/delete/index.js +6 -6
- package/dist/src/client/modify/drain.js +20 -23
- package/dist/src/client/modify/edges/references.js +3 -2
- package/dist/src/client/modify/error.d.ts +2 -1
- package/dist/src/client/modify/error.js +2 -2
- package/dist/src/client/modify/expire/index.js +5 -6
- package/dist/src/client/modify/props/object.js +3 -2
- package/dist/src/client/modify/props/reference.js +3 -3
- package/dist/src/client/modify/props/references.js +2 -1
- package/dist/src/client/modify/types.d.ts +4 -1
- package/dist/src/client/modify/types.js +4 -0
- package/dist/src/client/modify/update/index.d.ts +3 -0
- package/dist/src/client/modify/update/index.js +33 -20
- package/dist/src/client/modify/upsert/index.d.ts +2 -1
- package/dist/src/client/modify/upsert/index.js +67 -44
- package/dist/src/client/query/BasedDbQuery.js +12 -7
- package/dist/src/client/query/aggregates/aggregation.d.ts +1 -1
- package/dist/src/client/query/aggregates/aggregation.js +24 -3
- package/dist/src/client/query/filter/convertFilter.js +16 -3
- package/dist/src/client/query/filter/types.d.ts +1 -1
- package/dist/src/client/query/include/include.js +2 -5
- package/dist/src/client/query/queryDefToReadSchema.js +20 -1
- package/dist/src/client/query/search/index.js +9 -1
- package/dist/src/client/string.d.ts +1 -1
- package/dist/src/client/string.js +1 -1
- package/dist/src/hooks.d.ts +3 -6
- package/dist/src/hooks.js +5 -12
- package/dist/src/index.d.ts +3 -3
- package/dist/src/index.js +5 -3
- package/dist/src/native.d.ts +4 -3
- package/dist/src/native.js +11 -10
- package/dist/src/server/blocks.js +1 -1
- package/dist/src/server/index.d.ts +3 -2
- package/dist/src/server/index.js +23 -47
- package/dist/src/server/migrate/index.js +4 -0
- package/dist/src/server/resizeModifyDirtyRanges.js +1 -1
- package/dist/src/server/save.d.ts +0 -1
- package/dist/src/server/save.js +2 -2
- package/dist/src/server/schema.js +6 -1
- package/dist/src/server/start.js +0 -2
- package/dist/src/shared/Emitter.d.ts +1 -1
- package/dist/src/utils.d.ts +0 -2
- package/dist/src/utils.js +1 -3
- package/package.json +17 -7
- package/dist/lib/darwin_aarch64/libnode-v23.node +0 -0
- package/dist/lib/darwin_aarch64/libnode-v24.node +0 -0
- package/dist/lib/linux_aarch64/include/cdefs.h +0 -317
- package/dist/lib/linux_aarch64/include/jemalloc.h +0 -468
- package/dist/lib/linux_aarch64/include/libdeflate.h +0 -345
- package/dist/lib/linux_aarch64/include/libdeflate_strings.h +0 -35
- package/dist/lib/linux_aarch64/include/linker_set.h +0 -109
- package/dist/lib/linux_aarch64/include/queue.h +0 -627
- package/dist/lib/linux_aarch64/include/selva/_export.h +0 -7
- package/dist/lib/linux_aarch64/include/selva/align.h +0 -9
- package/dist/lib/linux_aarch64/include/selva/backoff_timeout.h +0 -29
- package/dist/lib/linux_aarch64/include/selva/bitmap.h +0 -95
- package/dist/lib/linux_aarch64/include/selva/colvec.h +0 -71
- package/dist/lib/linux_aarch64/include/selva/crc32c.h +0 -17
- package/dist/lib/linux_aarch64/include/selva/ctime.h +0 -135
- package/dist/lib/linux_aarch64/include/selva/db.h +0 -407
- package/dist/lib/linux_aarch64/include/selva/endian.h +0 -301
- package/dist/lib/linux_aarch64/include/selva/fast_linear_search.h +0 -27
- package/dist/lib/linux_aarch64/include/selva/fast_memcmp.h +0 -18
- package/dist/lib/linux_aarch64/include/selva/fast_memmem.h +0 -11
- package/dist/lib/linux_aarch64/include/selva/fast_parsei.h +0 -36
- package/dist/lib/linux_aarch64/include/selva/fields.h +0 -407
- package/dist/lib/linux_aarch64/include/selva/gmtime.h +0 -137
- package/dist/lib/linux_aarch64/include/selva/hll.h +0 -85
- package/dist/lib/linux_aarch64/include/selva/lpf.h +0 -28
- package/dist/lib/linux_aarch64/include/selva/mblen.h +0 -40
- package/dist/lib/linux_aarch64/include/selva/membar.h +0 -32
- package/dist/lib/linux_aarch64/include/selva/node_id_set.h +0 -43
- package/dist/lib/linux_aarch64/include/selva/poptop.h +0 -114
- package/dist/lib/linux_aarch64/include/selva/selva_hash128.h +0 -49
- package/dist/lib/linux_aarch64/include/selva/selva_lang.h +0 -105
- package/dist/lib/linux_aarch64/include/selva/selva_math.h +0 -37
- package/dist/lib/linux_aarch64/include/selva/selva_string.h +0 -679
- package/dist/lib/linux_aarch64/include/selva/sort.h +0 -140
- package/dist/lib/linux_aarch64/include/selva/strsearch.h +0 -43
- package/dist/lib/linux_aarch64/include/selva/thread.h +0 -37
- package/dist/lib/linux_aarch64/include/selva/timestamp.h +0 -25
- package/dist/lib/linux_aarch64/include/selva/types.h +0 -129
- package/dist/lib/linux_aarch64/include/selva/vector.h +0 -35
- package/dist/lib/linux_aarch64/include/selva_error.h +0 -140
- package/dist/lib/linux_aarch64/include/selva_lang_code.h +0 -160
- package/dist/lib/linux_aarch64/include/tree.h +0 -852
- 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-v22.node +0 -0
- package/dist/lib/linux_aarch64/libnode-v23.node +0 -0
- package/dist/lib/linux_aarch64/libnode-v24.node +0 -0
- package/dist/lib/linux_aarch64/libselva.so +0 -0
- package/dist/lib/linux_aarch64/libxxhash.so.0 +0 -0
- package/dist/lib/linux_x86_64/include/cdefs.h +0 -317
- package/dist/lib/linux_x86_64/include/jemalloc.h +0 -468
- package/dist/lib/linux_x86_64/include/libdeflate.h +0 -345
- package/dist/lib/linux_x86_64/include/libdeflate_strings.h +0 -35
- package/dist/lib/linux_x86_64/include/linker_set.h +0 -109
- package/dist/lib/linux_x86_64/include/queue.h +0 -627
- package/dist/lib/linux_x86_64/include/selva/_export.h +0 -7
- package/dist/lib/linux_x86_64/include/selva/align.h +0 -9
- package/dist/lib/linux_x86_64/include/selva/backoff_timeout.h +0 -29
- package/dist/lib/linux_x86_64/include/selva/bitmap.h +0 -95
- package/dist/lib/linux_x86_64/include/selva/colvec.h +0 -71
- package/dist/lib/linux_x86_64/include/selva/crc32c.h +0 -17
- package/dist/lib/linux_x86_64/include/selva/ctime.h +0 -135
- package/dist/lib/linux_x86_64/include/selva/db.h +0 -407
- package/dist/lib/linux_x86_64/include/selva/endian.h +0 -301
- package/dist/lib/linux_x86_64/include/selva/fast_linear_search.h +0 -27
- package/dist/lib/linux_x86_64/include/selva/fast_memcmp.h +0 -18
- package/dist/lib/linux_x86_64/include/selva/fast_memmem.h +0 -11
- package/dist/lib/linux_x86_64/include/selva/fast_parsei.h +0 -36
- package/dist/lib/linux_x86_64/include/selva/fields.h +0 -407
- package/dist/lib/linux_x86_64/include/selva/gmtime.h +0 -137
- package/dist/lib/linux_x86_64/include/selva/hll.h +0 -85
- package/dist/lib/linux_x86_64/include/selva/lpf.h +0 -28
- package/dist/lib/linux_x86_64/include/selva/mblen.h +0 -40
- package/dist/lib/linux_x86_64/include/selva/membar.h +0 -32
- package/dist/lib/linux_x86_64/include/selva/node_id_set.h +0 -43
- package/dist/lib/linux_x86_64/include/selva/poptop.h +0 -114
- package/dist/lib/linux_x86_64/include/selva/selva_hash128.h +0 -49
- package/dist/lib/linux_x86_64/include/selva/selva_lang.h +0 -105
- package/dist/lib/linux_x86_64/include/selva/selva_math.h +0 -37
- package/dist/lib/linux_x86_64/include/selva/selva_string.h +0 -679
- package/dist/lib/linux_x86_64/include/selva/sort.h +0 -140
- package/dist/lib/linux_x86_64/include/selva/strsearch.h +0 -43
- package/dist/lib/linux_x86_64/include/selva/thread.h +0 -37
- package/dist/lib/linux_x86_64/include/selva/timestamp.h +0 -25
- package/dist/lib/linux_x86_64/include/selva/types.h +0 -129
- package/dist/lib/linux_x86_64/include/selva/vector.h +0 -35
- package/dist/lib/linux_x86_64/include/selva_error.h +0 -140
- package/dist/lib/linux_x86_64/include/selva_lang_code.h +0 -160
- package/dist/lib/linux_x86_64/include/tree.h +0 -852
- package/dist/lib/linux_x86_64/libdeflate.so +0 -0
- package/dist/lib/linux_x86_64/libjemalloc_selva.so.2 +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/libnode-v24.node +0 -0
- package/dist/lib/linux_x86_64/libselva.so +0 -0
- package/dist/lib/linux_x86_64/libxxhash.so.0 +0 -0
|
@@ -70,11 +70,24 @@ const ensureAggregate = (def) => {
|
|
|
70
70
|
};
|
|
71
71
|
}
|
|
72
72
|
};
|
|
73
|
-
export const groupBy = (
|
|
73
|
+
export const groupBy = (q, field, StepInput) => {
|
|
74
|
+
const def = q.def;
|
|
74
75
|
const fieldDef = def.schema.props[field];
|
|
75
76
|
if (!fieldDef) {
|
|
76
77
|
aggregationFieldDoesNotExist(def, field);
|
|
77
78
|
}
|
|
79
|
+
const groupByPropHook = fieldDef.hooks?.groupBy;
|
|
80
|
+
if (groupByPropHook) {
|
|
81
|
+
fieldDef.hooks.groupBy = null;
|
|
82
|
+
groupByPropHook(q, field);
|
|
83
|
+
fieldDef.hooks.groupBy = groupByPropHook;
|
|
84
|
+
}
|
|
85
|
+
const groupByHook = def.schema.hooks?.groupBy;
|
|
86
|
+
if (groupByHook) {
|
|
87
|
+
def.schema.hooks.groupBy = null;
|
|
88
|
+
groupByHook(q, field);
|
|
89
|
+
def.schema.hooks.groupBy = groupByHook;
|
|
90
|
+
}
|
|
78
91
|
ensureAggregate(def);
|
|
79
92
|
if (!def.aggregate.groupBy) {
|
|
80
93
|
def.aggregate.size += 12;
|
|
@@ -113,10 +126,11 @@ export const groupBy = (def, field, StepInput) => {
|
|
|
113
126
|
};
|
|
114
127
|
export const addAggregate = (query, type, fields, option) => {
|
|
115
128
|
const def = query.def;
|
|
116
|
-
|
|
129
|
+
let hookFields;
|
|
117
130
|
ensureAggregate(def);
|
|
118
|
-
if (option?.mode)
|
|
131
|
+
if (option?.mode) {
|
|
119
132
|
def.aggregate.option = option;
|
|
133
|
+
}
|
|
120
134
|
const aggregates = def.aggregate.aggregates;
|
|
121
135
|
for (const field of fields) {
|
|
122
136
|
const fieldDef = type === AggregateType.COUNT
|
|
@@ -135,6 +149,10 @@ export const addAggregate = (query, type, fields, option) => {
|
|
|
135
149
|
if (!fieldDef) {
|
|
136
150
|
aggregationFieldDoesNotExist(def, field);
|
|
137
151
|
}
|
|
152
|
+
if (fieldDef.hooks?.aggregate) {
|
|
153
|
+
hookFields ??= new Set(fields);
|
|
154
|
+
fieldDef.hooks.aggregate(query, hookFields);
|
|
155
|
+
}
|
|
138
156
|
if (!aggregates.get(fieldDef.prop)) {
|
|
139
157
|
aggregates.set(fieldDef.prop, []);
|
|
140
158
|
def.aggregate.size += 3;
|
|
@@ -158,6 +176,9 @@ export const addAggregate = (query, type, fields, option) => {
|
|
|
158
176
|
// needs to add an extra field WRITE TO
|
|
159
177
|
def.aggregate.size += 8;
|
|
160
178
|
}
|
|
179
|
+
if (def.schema.hooks?.aggregate) {
|
|
180
|
+
def.schema.hooks.aggregate(query, hookFields || new Set(fields));
|
|
181
|
+
}
|
|
161
182
|
};
|
|
162
183
|
export const isRootCountOnly = (def, filterSize) => {
|
|
163
184
|
if (filterSize != 0) {
|
|
@@ -8,16 +8,29 @@ const normalizeNeedle = (s) => {
|
|
|
8
8
|
};
|
|
9
9
|
export const convertFilter = (query, field, operator, value, opts) => {
|
|
10
10
|
const def = query.def;
|
|
11
|
-
const
|
|
11
|
+
const propHooks = def.schema.props[field]?.hooks;
|
|
12
|
+
const hooks = def.schema.hooks;
|
|
13
|
+
const propFilterHook = propHooks?.filter;
|
|
14
|
+
const filterHook = hooks?.filter;
|
|
15
|
+
if (propFilterHook) {
|
|
16
|
+
propHooks.filter = null;
|
|
17
|
+
if (typeof operator === 'boolean') {
|
|
18
|
+
propFilterHook(query, field, '=', operator);
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
propFilterHook(query, field, operator, value);
|
|
22
|
+
}
|
|
23
|
+
propHooks.filter = propFilterHook;
|
|
24
|
+
}
|
|
12
25
|
if (filterHook) {
|
|
13
|
-
|
|
26
|
+
hooks.filter = null;
|
|
14
27
|
if (typeof operator === 'boolean') {
|
|
15
28
|
filterHook(query, field, '=', operator);
|
|
16
29
|
}
|
|
17
30
|
else {
|
|
18
31
|
filterHook(query, field, operator, value);
|
|
19
32
|
}
|
|
20
|
-
|
|
33
|
+
hooks.filter = filterHook;
|
|
21
34
|
}
|
|
22
35
|
if (operator === undefined) {
|
|
23
36
|
operator = '=';
|
|
@@ -54,7 +54,7 @@ export declare const VECTOR_DOT_PRODUCT = 0;
|
|
|
54
54
|
export declare const VECTOR_MANHATTAN_DIST = 1;
|
|
55
55
|
export declare const VECTOR_COSTINE_SIMILARITY = 2;
|
|
56
56
|
export declare const VECTOR_EUCLIDEAN_DIST = 3;
|
|
57
|
-
export declare const getVectorFn: (optsFn?: FilterOpts["fn"]) =>
|
|
57
|
+
export declare const getVectorFn: (optsFn?: FilterOpts["fn"]) => 1 | 0 | 3 | 2;
|
|
58
58
|
export declare const toFilterCtx: (def: QueryDef, op: Operator, opts?: FilterOpts) => FilterCtx;
|
|
59
59
|
export declare const operatorReverseMap: Record<OPERATOR, string>;
|
|
60
60
|
export declare const ALIGNMENT_NOT_SET = 255;
|
|
@@ -16,7 +16,7 @@ export const include = (query, fields) => {
|
|
|
16
16
|
}
|
|
17
17
|
else if (typeof f === 'function') {
|
|
18
18
|
f((field) => {
|
|
19
|
-
if (field[0]
|
|
19
|
+
if (field[0] === '$') {
|
|
20
20
|
// @ts-ignore
|
|
21
21
|
const prop = query.def.target?.propDef?.edges[field];
|
|
22
22
|
if (prop &&
|
|
@@ -28,10 +28,7 @@ export const include = (query, fields) => {
|
|
|
28
28
|
throw new Error(`No edge reference or edge references field named "${field}"`);
|
|
29
29
|
}
|
|
30
30
|
else {
|
|
31
|
-
const prop = field
|
|
32
|
-
? // @ts-ignore
|
|
33
|
-
query.def.target?.propDef?.edges[field]
|
|
34
|
-
: query.def.props[field];
|
|
31
|
+
const prop = query.def.props[field];
|
|
35
32
|
if (prop &&
|
|
36
33
|
(prop.typeIndex === REFERENCE || prop.typeIndex === REFERENCES)) {
|
|
37
34
|
const refDef = createOrGetRefQueryDef(query.db, query.def, prop);
|
|
@@ -41,6 +41,13 @@ const createReaderPropDef = (p, locales, opts) => {
|
|
|
41
41
|
}
|
|
42
42
|
return readerPropDef;
|
|
43
43
|
};
|
|
44
|
+
const normalizeHookFn = (fn) => {
|
|
45
|
+
let src = fn.toString();
|
|
46
|
+
if (/^[a-zA-Z0-9_$]+\s*\(/.test(src)) {
|
|
47
|
+
src = 'function ' + src;
|
|
48
|
+
}
|
|
49
|
+
return src;
|
|
50
|
+
};
|
|
44
51
|
export const convertToReaderSchema = (q, locales) => {
|
|
45
52
|
if (!locales) {
|
|
46
53
|
locales = {};
|
|
@@ -100,7 +107,19 @@ export const convertToReaderSchema = (q, locales) => {
|
|
|
100
107
|
}
|
|
101
108
|
}
|
|
102
109
|
else {
|
|
103
|
-
if (q.schema?.
|
|
110
|
+
if (q.schema?.propHooks?.read) {
|
|
111
|
+
let body = '';
|
|
112
|
+
for (const def of q.schema.propHooks.read) {
|
|
113
|
+
const target = `r.${def.path.join('.')}`;
|
|
114
|
+
body += `if(r.${def.path.join('?.')}!=null)${target}=(${normalizeHookFn(def.hooks.read)})(${target},r);`;
|
|
115
|
+
}
|
|
116
|
+
if (q.schema?.hooks?.read) {
|
|
117
|
+
body += `r=(${normalizeHookFn(q.schema.hooks.read)})(r);`;
|
|
118
|
+
}
|
|
119
|
+
body += `return r;`;
|
|
120
|
+
readerSchema.hook = new Function('r', body);
|
|
121
|
+
}
|
|
122
|
+
else if (q.schema?.hooks?.read) {
|
|
104
123
|
readerSchema.hook = q.schema.hooks.read;
|
|
105
124
|
}
|
|
106
125
|
if (isRoot && q.search) {
|
|
@@ -73,6 +73,7 @@ export const search = (queryBranch, q, s) => {
|
|
|
73
73
|
}
|
|
74
74
|
s = x;
|
|
75
75
|
}
|
|
76
|
+
let hookFields;
|
|
76
77
|
for (const key in s) {
|
|
77
78
|
let prop = def.props[key];
|
|
78
79
|
let lang = def.lang.lang;
|
|
@@ -110,11 +111,18 @@ export const search = (queryBranch, q, s) => {
|
|
|
110
111
|
field: prop.prop,
|
|
111
112
|
start: prop.start ?? 0, // also need lang ofc if you have start
|
|
112
113
|
});
|
|
114
|
+
const searchHook = prop.hooks?.search;
|
|
115
|
+
if (searchHook) {
|
|
116
|
+
hookFields ??= new Set(Object.keys(s));
|
|
117
|
+
prop.hooks.search = null;
|
|
118
|
+
searchHook(queryBranch, hookFields);
|
|
119
|
+
prop.hooks.search = searchHook;
|
|
120
|
+
}
|
|
113
121
|
}
|
|
114
122
|
const searchHook = def.schema.hooks?.search;
|
|
115
123
|
if (searchHook) {
|
|
116
124
|
def.schema.hooks.search = null;
|
|
117
|
-
searchHook(queryBranch, new Set(Object.keys(s)));
|
|
125
|
+
searchHook(queryBranch, hookFields || new Set(Object.keys(s)));
|
|
118
126
|
def.schema.hooks.search = searchHook;
|
|
119
127
|
}
|
|
120
128
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { LangCode } from '@based/schema';
|
|
2
2
|
import { Ctx } from './modify/Ctx.js';
|
|
3
3
|
export declare const write: (ctx: Ctx, value: string, offset: number, noCompression: boolean, lang?: LangCode) => number | null;
|
|
4
|
-
export declare const
|
|
4
|
+
export declare const stringCompress: (str: string) => Uint8Array;
|
|
@@ -40,7 +40,7 @@ export const write = (ctx, value, offset, noCompression, lang) => {
|
|
|
40
40
|
return l + 6;
|
|
41
41
|
}
|
|
42
42
|
};
|
|
43
|
-
export const
|
|
43
|
+
export const stringCompress = (str) => {
|
|
44
44
|
const len = ENCODER.encode(str).byteLength;
|
|
45
45
|
const tmpCompressBlock = getTmpBuffer(len * 3);
|
|
46
46
|
const l = write({ array: tmpCompressBlock }, str, 0, false);
|
package/dist/src/hooks.d.ts
CHANGED
|
@@ -1,14 +1,11 @@
|
|
|
1
1
|
import { StrictSchema, MigrateFns, DbSchema, SchemaChecksum } from '@based/schema';
|
|
2
|
-
import { BasedDbQuery } from './client/query/BasedDbQuery.js';
|
|
2
|
+
import type { BasedDbQuery } from './client/query/BasedDbQuery.js';
|
|
3
3
|
import { OnClose, OnData, OnError } from './client/query/subscription/types.js';
|
|
4
4
|
import { DbServer } from './server/index.js';
|
|
5
5
|
export type DbClientHooks = {
|
|
6
6
|
setSchema(schema: StrictSchema, transformFns?: MigrateFns): Promise<SchemaChecksum>;
|
|
7
|
-
flushModify(buf: Uint8Array): Promise<
|
|
8
|
-
|
|
9
|
-
dbWriteTime?: number;
|
|
10
|
-
}>;
|
|
11
|
-
getQueryBuf(buf: Uint8Array): Promise<Uint8Array>;
|
|
7
|
+
flushModify(buf: Uint8Array): Promise<Uint8Array | null>;
|
|
8
|
+
getQueryBuf(buf: Uint8Array): ReturnType<DbServer['getQueryBuf']>;
|
|
12
9
|
subscribe(q: BasedDbQuery, onData: (buf: Uint8Array) => ReturnType<OnData>, onError?: OnError): OnClose;
|
|
13
10
|
subscribeSchema(cb: (schema: DbSchema) => void): void;
|
|
14
11
|
};
|
package/dist/src/hooks.js
CHANGED
|
@@ -43,21 +43,14 @@ export const getDefaultHooks = (server, subInterval = 200) => {
|
|
|
43
43
|
});
|
|
44
44
|
},
|
|
45
45
|
flushModify(buf) {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
const dbWriteTime = performance.now() - d;
|
|
50
|
-
return Promise.resolve({
|
|
51
|
-
offsets,
|
|
52
|
-
dbWriteTime,
|
|
53
|
-
});
|
|
54
|
-
}
|
|
55
|
-
catch (e) {
|
|
56
|
-
return Promise.reject(e);
|
|
46
|
+
const res = server.modify(buf);
|
|
47
|
+
if (res instanceof Promise) {
|
|
48
|
+
return res.then((res) => res && new Uint8Array(res));
|
|
57
49
|
}
|
|
50
|
+
return Promise.resolve(res && new Uint8Array(res));
|
|
58
51
|
},
|
|
59
52
|
getQueryBuf(buf) {
|
|
60
|
-
return
|
|
53
|
+
return server.getQueryBuf(buf);
|
|
61
54
|
},
|
|
62
55
|
};
|
|
63
56
|
};
|
package/dist/src/index.d.ts
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { stringCompress } from './client/string.js';
|
|
2
2
|
import { DbServer } from './server/index.js';
|
|
3
3
|
import { DbClient } from './client/index.js';
|
|
4
4
|
import { getDefaultHooks } from './hooks.js';
|
|
5
5
|
import { Emitter } from './shared/Emitter.js';
|
|
6
6
|
import { BasedDbOpts } from './types.js';
|
|
7
|
-
|
|
8
|
-
export { compress, decompress };
|
|
7
|
+
export { stringCompress };
|
|
9
8
|
export { DbClient, DbServer };
|
|
10
9
|
export { xxHash64 } from './client/xxHash64.js';
|
|
11
10
|
export { crc32 } from './client/crc32.js';
|
|
@@ -27,6 +26,7 @@ export declare class BasedDb extends Emitter {
|
|
|
27
26
|
copy: DbClient['copy'];
|
|
28
27
|
update: DbClient['update'];
|
|
29
28
|
upsert: DbClient['upsert'];
|
|
29
|
+
insert: DbClient['insert'];
|
|
30
30
|
delete: DbClient['delete'];
|
|
31
31
|
expire: DbClient['expire'];
|
|
32
32
|
query: DbClient['query'];
|
package/dist/src/index.js
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { stringCompress } from './client/string.js';
|
|
2
2
|
import { DbServer } from './server/index.js';
|
|
3
3
|
import { DbClient } from './client/index.js';
|
|
4
4
|
import { wait } from '@based/utils';
|
|
5
5
|
import { debugMode, debugServer } from './utils.js';
|
|
6
6
|
import { getDefaultHooks } from './hooks.js';
|
|
7
7
|
import { Emitter } from './shared/Emitter.js';
|
|
8
|
-
|
|
9
|
-
export { compress, decompress };
|
|
8
|
+
export { stringCompress };
|
|
10
9
|
export { DbClient, DbServer };
|
|
11
10
|
export { xxHash64 } from './client/xxHash64.js';
|
|
12
11
|
export { crc32 } from './client/crc32.js';
|
|
@@ -61,6 +60,9 @@ export class BasedDb extends Emitter {
|
|
|
61
60
|
upsert = function () {
|
|
62
61
|
return this.client.upsert.apply(this.client, arguments);
|
|
63
62
|
};
|
|
63
|
+
insert = function () {
|
|
64
|
+
return this.client.insert.apply(this.client, arguments);
|
|
65
|
+
};
|
|
64
66
|
delete = function () {
|
|
65
67
|
return this.client.delete.apply(this.client, arguments);
|
|
66
68
|
};
|
package/dist/src/native.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ declare const native: {
|
|
|
4
4
|
destroyThreadCtx: (dbCtx: any, threadId: BigInt) => void;
|
|
5
5
|
externalFromInt(address: BigInt): any;
|
|
6
6
|
intFromExternal(external: any): BigInt;
|
|
7
|
-
modify: (data: Uint8Array,
|
|
7
|
+
modify: (data: Uint8Array, dbCtx: any, dirtyBlocksOut: Float64Array) => number | null;
|
|
8
8
|
getQueryBuf: (q: Uint8Array, dbCtx: any) => ArrayBuffer | null;
|
|
9
9
|
start: () => any;
|
|
10
10
|
stop: (dbCtx: any) => any;
|
|
@@ -13,8 +13,9 @@ declare const native: {
|
|
|
13
13
|
loadCommon: (path: string, dbCtx: any) => void;
|
|
14
14
|
loadBlock: (path: string, dbCtx: any) => void;
|
|
15
15
|
delBlock: (dbCtx: any, typeId: number, block: number) => void;
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
setSchemaType: (prefix: number, buf: Uint8Array, dbCtx: any) => any;
|
|
17
|
+
setSchemaIds: (ids: Uint32Array, dbCtx: any) => any;
|
|
18
|
+
getSchemaIds: (dbCtx: any) => Uint32Array;
|
|
18
19
|
getNodeRangeHash: (typeId: number, start: number, end: number, bufOut: Uint8Array, dbCtx: any) => any;
|
|
19
20
|
createCompressor(): any;
|
|
20
21
|
compressRaw: (compressor: any, buf: Uint8Array, offset: number, stringSize: number) => any;
|
package/dist/src/native.js
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
// @ts-ignore
|
|
2
|
-
import db from '
|
|
3
|
-
|
|
4
|
-
const DECODER = new TextDecoder('utf-8');
|
|
5
|
-
const ENCODER = new TextEncoder();
|
|
2
|
+
import db from '@based/db/native';
|
|
3
|
+
import { DECODER, ENCODER } from '@based/utils';
|
|
6
4
|
const selvaIoErrlog = new Uint8Array(256);
|
|
7
5
|
var compressor = db.createCompressor();
|
|
8
6
|
var decompressor = db.createDecompressor();
|
|
@@ -27,8 +25,8 @@ const native = {
|
|
|
27
25
|
intFromExternal(external) {
|
|
28
26
|
return db.intFromExternal(external);
|
|
29
27
|
},
|
|
30
|
-
modify: (data,
|
|
31
|
-
db.modify(data,
|
|
28
|
+
modify: (data, dbCtx, dirtyBlocksOut) => {
|
|
29
|
+
return db.modify(data, dbCtx, dirtyBlocksOut);
|
|
32
30
|
},
|
|
33
31
|
getQueryBuf: (q, dbCtx) => {
|
|
34
32
|
const x = db.getQueryBuf(dbCtx, q);
|
|
@@ -65,11 +63,14 @@ const native = {
|
|
|
65
63
|
delBlock: (dbCtx, typeId, block) => {
|
|
66
64
|
db.delBlock(dbCtx, typeId, block);
|
|
67
65
|
},
|
|
68
|
-
|
|
69
|
-
return db.
|
|
66
|
+
setSchemaType: (prefix, buf, dbCtx) => {
|
|
67
|
+
return db.setSchemaType(prefix, buf, dbCtx);
|
|
70
68
|
},
|
|
71
|
-
|
|
72
|
-
return db.
|
|
69
|
+
setSchemaIds: (ids, dbCtx) => {
|
|
70
|
+
return db.setSchemaIds(ids, dbCtx);
|
|
71
|
+
},
|
|
72
|
+
getSchemaIds: (dbCtx) => {
|
|
73
|
+
return new Uint32Array(db.getSchemaIds(dbCtx));
|
|
73
74
|
},
|
|
74
75
|
getNodeRangeHash: (typeId, start, end, bufOut, dbCtx) => {
|
|
75
76
|
return db.getNodeRangeHash(typeId, start, end, bufOut, dbCtx);
|
|
@@ -106,7 +106,7 @@ export async function unloadBlock(db, def, start) {
|
|
|
106
106
|
*/
|
|
107
107
|
export function foreachBlock(db, def, cb, includeEmptyBlocks = false) {
|
|
108
108
|
const step = def.blockCapacity;
|
|
109
|
-
const lastId =
|
|
109
|
+
const lastId = db.ids[def.id - 1];
|
|
110
110
|
for (let start = 1; start <= lastId; start += step) {
|
|
111
111
|
const end = start + step - 1;
|
|
112
112
|
const hash = new Uint8Array(16);
|
|
@@ -24,13 +24,14 @@ export declare class DbServer extends DbShared {
|
|
|
24
24
|
workers: QueryWorker[];
|
|
25
25
|
availableWorkerIndex: number;
|
|
26
26
|
activeReaders: number;
|
|
27
|
-
modifyQueue: Uint8Array
|
|
27
|
+
modifyQueue: Map<Function, Uint8Array>;
|
|
28
28
|
queryQueue: Map<Function, Uint8Array>;
|
|
29
29
|
stopped: boolean;
|
|
30
30
|
unlistenExit: ReturnType<typeof exitHook>;
|
|
31
31
|
saveIntervalInSeconds?: number;
|
|
32
32
|
saveInterval?: NodeJS.Timeout;
|
|
33
33
|
delayInMs?: number;
|
|
34
|
+
ids: Uint32Array;
|
|
34
35
|
constructor({ path, debug, saveIntervalInSeconds, }: {
|
|
35
36
|
path: string;
|
|
36
37
|
debug?: boolean;
|
|
@@ -58,7 +59,7 @@ export declare class DbServer extends DbShared {
|
|
|
58
59
|
getSortIndex(typeId: number, field: number, start: number, lang: number): SortIndex;
|
|
59
60
|
createSortIndexBuffer(typeId: number, field: number, start: number, lang: number): SortIndex;
|
|
60
61
|
setSchema(strictSchema: StrictSchema, transformFns?: MigrateFns): Promise<SchemaChecksum>;
|
|
61
|
-
modify(payload: Uint8Array
|
|
62
|
+
modify(payload: Uint8Array): Uint8Array | null | Promise<Uint8Array | null>;
|
|
62
63
|
addToQueryQueue(resolve: any, buf: any): Promise<Uint8Array<ArrayBuffer>>;
|
|
63
64
|
getQueryBuf(buf: Uint8Array, fromQueue?: boolean): Promise<Uint8Array>;
|
|
64
65
|
onQueryEnd(): void;
|
package/dist/src/server/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import native from '../native.js';
|
|
2
2
|
import { rm } from 'node:fs/promises';
|
|
3
|
-
import { langCodesMap, strictSchemaToDbSchema } from '@based/schema';
|
|
3
|
+
import { langCodesMap, strictSchemaToDbSchema, } from '@based/schema';
|
|
4
4
|
import { ID_FIELD_DEF } from '@based/schema/def';
|
|
5
5
|
import { start } from './start.js';
|
|
6
6
|
import { destructureTreeKey, makeTreeKeyFromNodeId } from './tree.js';
|
|
@@ -8,7 +8,7 @@ import { save } from './save.js';
|
|
|
8
8
|
import { setTimeout } from 'node:timers/promises';
|
|
9
9
|
import { migrate } from './migrate/index.js';
|
|
10
10
|
import { debugServer } from '../utils.js';
|
|
11
|
-
import { readUint16,
|
|
11
|
+
import { readUint16, readUint64 } from '@based/utils';
|
|
12
12
|
import { QueryType } from '../client/query/types.js';
|
|
13
13
|
import { DbShared } from '../shared/DbBase.js';
|
|
14
14
|
import { setNativeSchema, setSchemaOnServer, writeSchemaFile, } from './schema.js';
|
|
@@ -36,13 +36,14 @@ export class DbServer extends DbShared {
|
|
|
36
36
|
workers = [];
|
|
37
37
|
availableWorkerIndex = -1;
|
|
38
38
|
activeReaders = 0; // processing queries or other DB reads
|
|
39
|
-
modifyQueue =
|
|
39
|
+
modifyQueue = new Map();
|
|
40
40
|
queryQueue = new Map();
|
|
41
41
|
stopped; // = true does not work
|
|
42
42
|
unlistenExit;
|
|
43
43
|
saveIntervalInSeconds;
|
|
44
44
|
saveInterval;
|
|
45
45
|
delayInMs;
|
|
46
|
+
ids;
|
|
46
47
|
constructor({ path, debug, saveIntervalInSeconds, }) {
|
|
47
48
|
super();
|
|
48
49
|
this.fileSystemPath = path;
|
|
@@ -269,56 +270,31 @@ export class DbServer extends DbShared {
|
|
|
269
270
|
});
|
|
270
271
|
return schema.hash;
|
|
271
272
|
}
|
|
272
|
-
modify(payload
|
|
273
|
+
modify(payload) {
|
|
273
274
|
const hash = readUint64(payload, 0);
|
|
274
|
-
const contentEnd = readUint32(payload, payload.byteLength - 4);
|
|
275
|
-
let result;
|
|
276
275
|
if (this.schema?.hash !== hash) {
|
|
277
276
|
this.emit('info', 'Schema mismatch in write');
|
|
278
277
|
return null;
|
|
279
278
|
}
|
|
280
|
-
if (!skipParse) {
|
|
281
|
-
result = {};
|
|
282
|
-
let i = payload.byteLength - 4;
|
|
283
|
-
while (i > contentEnd) {
|
|
284
|
-
const typeId = readUint16(payload, i - 6);
|
|
285
|
-
const count = readUint32(payload, i - 4);
|
|
286
|
-
const typeDef = this.schemaTypesParsedById[typeId];
|
|
287
|
-
if (!typeDef) {
|
|
288
|
-
console.error('Missing typeDef, cancel write', { typeId, count });
|
|
289
|
-
this.emit('info', 'Missing typeDef, cancel write');
|
|
290
|
-
return null;
|
|
291
|
-
}
|
|
292
|
-
const lastId = typeDef.lastId ||
|
|
293
|
-
native.getTypeInfo(typeDef.id, this.dbCtxExternal)[1];
|
|
294
|
-
// TODO replace this with Ctx.created
|
|
295
|
-
const offset = lastId;
|
|
296
|
-
// write the offset into payload for zig to use
|
|
297
|
-
writeUint32(payload, offset, i - 4);
|
|
298
|
-
result[typeId] = offset;
|
|
299
|
-
typeDef.lastId = lastId + count;
|
|
300
|
-
i -= 6;
|
|
301
|
-
}
|
|
302
|
-
}
|
|
303
|
-
const content = payload.subarray(8, contentEnd);
|
|
304
|
-
const offsets = payload.subarray(contentEnd, payload.byteLength - 4);
|
|
305
279
|
if (this.activeReaders) {
|
|
306
|
-
|
|
280
|
+
return new Promise((resolve) => {
|
|
281
|
+
this.modifyQueue.set(resolve, new Uint8Array(payload));
|
|
282
|
+
});
|
|
307
283
|
}
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
this.dirtyRanges.add(key);
|
|
284
|
+
resizeModifyDirtyRanges(this);
|
|
285
|
+
const content = payload.subarray(8);
|
|
286
|
+
const len = native.modify(content, this.dbCtxExternal, this.modifyDirtyRanges);
|
|
287
|
+
for (const key of this.modifyDirtyRanges) {
|
|
288
|
+
if (key === 0) {
|
|
289
|
+
break;
|
|
315
290
|
}
|
|
291
|
+
this.dirtyRanges.add(key);
|
|
316
292
|
}
|
|
317
|
-
return
|
|
293
|
+
return content.subarray(0, len);
|
|
318
294
|
}
|
|
319
295
|
#expire() {
|
|
320
296
|
resizeModifyDirtyRanges(this);
|
|
321
|
-
native.modify(emptyUint8Array,
|
|
297
|
+
native.modify(emptyUint8Array, this.dbCtxExternal, this.modifyDirtyRanges);
|
|
322
298
|
for (const key of this.modifyDirtyRanges) {
|
|
323
299
|
if (key === 0)
|
|
324
300
|
break;
|
|
@@ -326,7 +302,7 @@ export class DbServer extends DbShared {
|
|
|
326
302
|
}
|
|
327
303
|
}
|
|
328
304
|
addToQueryQueue(resolve, buf) {
|
|
329
|
-
if (this.queryQueue.size ===
|
|
305
|
+
if (this.queryQueue.size === 16_777_216) {
|
|
330
306
|
resolve(new Error('Query queue exceeded'));
|
|
331
307
|
return;
|
|
332
308
|
}
|
|
@@ -341,7 +317,7 @@ export class DbServer extends DbShared {
|
|
|
341
317
|
console.error('Db is stopped - trying to query', buf.byteLength);
|
|
342
318
|
return Promise.resolve(new Uint8Array(8));
|
|
343
319
|
}
|
|
344
|
-
if (this.modifyQueue.
|
|
320
|
+
if (this.modifyQueue.size) {
|
|
345
321
|
return new Promise((resolve) => {
|
|
346
322
|
this.addToQueryQueue(resolve, buf);
|
|
347
323
|
});
|
|
@@ -385,11 +361,11 @@ export class DbServer extends DbShared {
|
|
|
385
361
|
}
|
|
386
362
|
onQueryEnd() {
|
|
387
363
|
if (this.activeReaders === 0) {
|
|
388
|
-
if (this.modifyQueue.
|
|
364
|
+
if (this.modifyQueue.size) {
|
|
389
365
|
const modifyQueue = this.modifyQueue;
|
|
390
|
-
this.modifyQueue =
|
|
391
|
-
for (const payload of modifyQueue) {
|
|
392
|
-
this.modify(payload
|
|
366
|
+
this.modifyQueue = new Map();
|
|
367
|
+
for (const [resolve, payload] of modifyQueue) {
|
|
368
|
+
resolve(this.modify(payload));
|
|
393
369
|
}
|
|
394
370
|
}
|
|
395
371
|
if (this.queryQueue.size) {
|
|
@@ -65,6 +65,10 @@ export const migrate = async (server, fromSchema, toSchema, transform) => {
|
|
|
65
65
|
}
|
|
66
66
|
let killed = false;
|
|
67
67
|
const abort = () => {
|
|
68
|
+
if (server.stopped) {
|
|
69
|
+
console.info(`server stopped during migration ${migrationId}`);
|
|
70
|
+
return true;
|
|
71
|
+
}
|
|
68
72
|
if (killed) {
|
|
69
73
|
server.emit('info', `migration killed something went wrong ${migrationId}`);
|
|
70
74
|
return true;
|
|
@@ -2,7 +2,7 @@ export const resizeModifyDirtyRanges = (server) => {
|
|
|
2
2
|
let maxNrChanges = 0;
|
|
3
3
|
for (const typeId in server.schemaTypesParsedById) {
|
|
4
4
|
const def = server.schemaTypesParsedById[typeId];
|
|
5
|
-
const lastId = def.
|
|
5
|
+
const lastId = server.ids[def.id - 1];
|
|
6
6
|
const blockCapacity = def.blockCapacity;
|
|
7
7
|
const tmp = lastId - +!(lastId % def.blockCapacity);
|
|
8
8
|
const lastBlock = Math.ceil((((tmp / blockCapacity) | 0) * blockCapacity + 1) / blockCapacity);
|
package/dist/src/server/save.js
CHANGED
|
@@ -38,8 +38,8 @@ function makeWritelog(db, ts) {
|
|
|
38
38
|
const types = {};
|
|
39
39
|
const rangeDumps = {};
|
|
40
40
|
for (const key in db.schemaTypesParsed) {
|
|
41
|
-
const { id,
|
|
42
|
-
types[id] = {
|
|
41
|
+
const { id, blockCapacity } = db.schemaTypesParsed[key];
|
|
42
|
+
types[id] = { blockCapacity };
|
|
43
43
|
rangeDumps[id] = [];
|
|
44
44
|
}
|
|
45
45
|
db.verifTree.foreachBlock((block) => {
|
|
@@ -13,6 +13,7 @@ export const setSchemaOnServer = (server, schema) => {
|
|
|
13
13
|
server.schema = schema;
|
|
14
14
|
server.schemaTypesParsed = schemaTypesParsed;
|
|
15
15
|
server.schemaTypesParsedById = schemaTypesParsedById;
|
|
16
|
+
server.ids = native.getSchemaIds(server.dbCtxExternal);
|
|
16
17
|
};
|
|
17
18
|
export const writeSchemaFile = async (server, schema) => {
|
|
18
19
|
if (server.fileSystemPath) {
|
|
@@ -34,15 +35,19 @@ export const writeSchemaFile = async (server, schema) => {
|
|
|
34
35
|
export const setNativeSchema = (server, schema) => {
|
|
35
36
|
const types = Object.keys(server.schemaTypesParsed);
|
|
36
37
|
const s = schemaToSelvaBuffer(server.schemaTypesParsed);
|
|
38
|
+
let maxTid = 0;
|
|
37
39
|
for (let i = 0; i < s.length; i++) {
|
|
38
40
|
const type = server.schemaTypesParsed[types[i]];
|
|
41
|
+
maxTid = Math.max(maxTid, type.id);
|
|
39
42
|
try {
|
|
40
|
-
native.
|
|
43
|
+
native.setSchemaType(type.id, new Uint8Array(s[i]), server.dbCtxExternal);
|
|
41
44
|
}
|
|
42
45
|
catch (err) {
|
|
43
46
|
throw new Error(`Cannot update schema on selva (native) ${type.type} ${err.message}`);
|
|
44
47
|
}
|
|
45
48
|
}
|
|
49
|
+
// Init the last ids
|
|
50
|
+
native.setSchemaIds(new Uint32Array(maxTid), server.dbCtxExternal);
|
|
46
51
|
// Insert a root node
|
|
47
52
|
if (schema.types._root) {
|
|
48
53
|
const tmpArr = new Uint8Array(new ArrayBuffer(1e3, { maxByteLength: 10e3 }));
|
package/dist/src/server/start.js
CHANGED
|
@@ -93,8 +93,6 @@ export async function start(db, opts) {
|
|
|
93
93
|
db.verifTree = new VerifTree(db.schemaTypesParsed);
|
|
94
94
|
for (const { typeId } of db.verifTree.types()) {
|
|
95
95
|
const def = db.schemaTypesParsedById[typeId];
|
|
96
|
-
const [total, lastId] = native.getTypeInfo(def.id, db.dbCtxExternal);
|
|
97
|
-
def.lastId = writelog?.types[def.id]?.lastId || lastId;
|
|
98
96
|
def.blockCapacity =
|
|
99
97
|
writelog?.types[def.id]?.blockCapacity ||
|
|
100
98
|
def.blockCapacity ||
|
package/dist/src/utils.d.ts
CHANGED
package/dist/src/utils.js
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import { inspect } from 'node:util';
|
|
2
2
|
import picocolors from 'picocolors';
|
|
3
|
-
export const DECODER = new TextDecoder('utf-8');
|
|
4
|
-
export const ENCODER = new TextEncoder();
|
|
5
3
|
export const debugMode = (target, getInfo = null) => {
|
|
6
4
|
const opts = { showHidden: false, depth: null, colors: true };
|
|
7
5
|
const info = (v) => (typeof v === 'object' ? inspect(v, opts) : v);
|
|
@@ -42,5 +40,5 @@ export const debugMode = (target, getInfo = null) => {
|
|
|
42
40
|
}
|
|
43
41
|
}
|
|
44
42
|
};
|
|
45
|
-
export const debugServer = (server) => debugMode(server, () => `p: ${server.activeReaders} m: ${server.modifyQueue.
|
|
43
|
+
export const debugServer = (server) => debugMode(server, () => `p: ${server.activeReaders} m: ${server.modifyQueue.size} q: ${server.queryQueue.size}`);
|
|
46
44
|
//# sourceMappingURL=utils.js.map
|