@based/db 0.1.4 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/darwin_aarch64/include/cdefs.h +4 -0
- package/dist/lib/darwin_aarch64/include/selva/db.h +25 -5
- package/dist/lib/darwin_aarch64/include/selva/fields.h +34 -72
- package/dist/lib/darwin_aarch64/include/selva/selva_lang.h +7 -0
- package/dist/lib/darwin_aarch64/include/selva/types.h +9 -13
- 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/libnode-v23.node +0 -0
- package/dist/lib/darwin_aarch64/libnode-v24.node +0 -0
- package/dist/lib/darwin_aarch64/libnode-v25.node +0 -0
- package/dist/lib/darwin_aarch64/libselva.dylib +0 -0
- package/dist/lib/linux_aarch64/include/cdefs.h +4 -0
- package/dist/lib/linux_aarch64/include/selva/db.h +25 -5
- package/dist/lib/linux_aarch64/include/selva/fields.h +34 -72
- package/dist/lib/linux_aarch64/include/selva/selva_lang.h +7 -0
- package/dist/lib/linux_aarch64/include/selva/types.h +9 -13
- package/dist/lib/linux_aarch64/libdeflate.so +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/libnode-v25.node +0 -0
- package/dist/lib/linux_aarch64/libselva.so +0 -0
- package/dist/lib/linux_x86_64/include/cdefs.h +4 -0
- package/dist/lib/linux_x86_64/include/selva/db.h +25 -5
- package/dist/lib/linux_x86_64/include/selva/fields.h +34 -72
- package/dist/lib/linux_x86_64/include/selva/selva_lang.h +7 -0
- package/dist/lib/linux_x86_64/include/selva/types.h +9 -13
- package/dist/lib/linux_x86_64/libdeflate.so +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/libnode-v25.node +0 -0
- package/dist/lib/linux_x86_64/libselva.so +0 -0
- package/dist/src/client/modify/Tmp.d.ts +0 -1
- package/dist/src/client/modify/Tmp.js +14 -9
- package/dist/src/client/modify/create/index.js +6 -5
- package/dist/src/client/modify/drain.js +6 -2
- package/dist/src/client/modify/edges/binary.js +3 -2
- package/dist/src/client/modify/edges/reference.js +2 -3
- package/dist/src/client/modify/edges/references.js +2 -3
- package/dist/src/client/modify/edges/separate.js +4 -1
- package/dist/src/client/modify/edges/string.js +2 -3
- package/dist/src/client/modify/error.d.ts +29 -0
- package/dist/src/client/modify/error.js +10 -0
- package/dist/src/client/modify/props/alias.js +1 -1
- package/dist/src/client/modify/props/binary.js +1 -1
- package/dist/src/client/modify/props/cardinality.js +1 -1
- package/dist/src/client/modify/props/fixed.js +13 -14
- package/dist/src/client/modify/props/reference.js +2 -2
- package/dist/src/client/modify/props/references.js +7 -7
- package/dist/src/client/modify/props/string.js +1 -1
- package/dist/src/client/modify/props/vector.js +1 -11
- package/dist/src/client/modify/types.d.ts +1 -0
- package/dist/src/client/modify/types.js +1 -0
- package/dist/src/client/modify/validate.d.ts +1 -1
- package/dist/src/client/modify/validate.js +4 -3
- package/dist/src/client/query/BasedDbQuery.d.ts +4 -4
- package/dist/src/client/query/BasedDbQuery.js +23 -12
- package/dist/src/client/query/BasedQueryResponse.d.ts +0 -1
- package/dist/src/client/query/BasedQueryResponse.js +0 -3
- package/dist/src/client/query/aggregates/aggregation.d.ts +1 -1
- package/dist/src/client/query/aggregates/aggregation.js +123 -51
- package/dist/src/client/query/display.js +14 -8
- package/dist/src/client/query/filter/createFixedFilterBuffer.js +59 -22
- package/dist/src/client/query/filter/createReferenceFilter.js +13 -13
- package/dist/src/client/query/filter/createVariableFilterBuffer.js +6 -3
- package/dist/src/client/query/filter/filter.js +8 -0
- package/dist/src/client/query/filter/primitiveFilter.js +4 -1
- package/dist/src/client/query/filter/{toBuffer.d.ts → toByteCode.d.ts} +3 -2
- package/dist/src/client/query/filter/{toBuffer.js → toByteCode.js} +46 -12
- package/dist/src/client/query/filter/types.d.ts +1 -0
- package/dist/src/client/query/filter/types.js +33 -5
- package/dist/src/client/query/include/toByteCode.d.ts +2 -2
- package/dist/src/client/query/include/toByteCode.js +1 -1
- package/dist/src/client/query/query.d.ts +1 -1
- package/dist/src/client/query/query.js +1 -1
- package/dist/src/client/query/queryDef.js +6 -2
- package/dist/src/client/query/registerQuery.js +5 -9
- package/dist/src/client/query/subscription/index.js +5 -0
- package/dist/src/client/query/subscription/toByteCode.d.ts +6 -0
- package/dist/src/client/query/subscription/toByteCode.js +139 -0
- package/dist/src/client/query/subscription/types.d.ts +6 -0
- package/dist/src/client/query/subscription/types.js +7 -9
- package/dist/src/client/query/toByteCode/aggregates.d.ts +2 -0
- package/dist/src/client/query/toByteCode/aggregates.js +60 -0
- package/dist/src/client/query/toByteCode/alias.d.ts +2 -0
- package/dist/src/client/query/toByteCode/alias.js +24 -0
- package/dist/src/client/query/toByteCode/default.d.ts +2 -2
- package/dist/src/client/query/toByteCode/default.js +21 -24
- package/dist/src/client/query/toByteCode/id.d.ts +2 -0
- package/dist/src/client/query/toByteCode/id.js +17 -0
- package/dist/src/client/query/toByteCode/ids.d.ts +2 -0
- package/dist/src/client/query/toByteCode/ids.js +52 -0
- package/dist/src/client/query/toByteCode/offsets.d.ts +35 -0
- package/dist/src/client/query/toByteCode/offsets.js +36 -0
- package/dist/src/client/query/toByteCode/reference.d.ts +2 -0
- package/dist/src/client/query/toByteCode/reference.js +12 -0
- package/dist/src/client/query/toByteCode/references.d.ts +2 -0
- package/dist/src/client/query/toByteCode/references.js +35 -0
- package/dist/src/client/query/toByteCode/toByteCode.d.ts +4 -2
- package/dist/src/client/query/toByteCode/toByteCode.js +62 -189
- package/dist/src/client/query/types.d.ts +24 -5
- package/dist/src/client/query/validation.d.ts +5 -1
- package/dist/src/client/query/validation.js +15 -3
- package/dist/src/client/string.js +1 -1
- package/dist/src/hooks.js +2 -29
- package/dist/src/index.d.ts +1 -0
- package/dist/src/index.js +1 -0
- package/dist/src/native.d.ts +8 -1
- package/dist/src/native.js +23 -2
- package/dist/src/server/index.d.ts +2 -0
- package/dist/src/server/index.js +11 -2
- package/dist/src/server/migrate/worker.js +87 -84
- package/dist/src/server/schema.js +3 -2
- package/dist/src/server/schemaSelvaBuffer.d.ts +4 -0
- package/dist/src/server/schemaSelvaBuffer.js +182 -0
- package/dist/src/server/subscription.d.ts +32 -0
- package/dist/src/server/subscription.js +275 -0
- package/dist/src/utils.js +2 -3
- package/package.json +5 -6
package/dist/src/server/index.js
CHANGED
|
@@ -5,7 +5,6 @@ import { ID_FIELD_DEF } from '@based/schema/def';
|
|
|
5
5
|
import { start } from './start.js';
|
|
6
6
|
import { destructureTreeKey, makeTreeKeyFromNodeId } from './tree.js';
|
|
7
7
|
import { save } from './save.js';
|
|
8
|
-
import { setTimeout } from 'node:timers/promises';
|
|
9
8
|
import { migrate } from './migrate/index.js';
|
|
10
9
|
import { debugServer } from '../utils.js';
|
|
11
10
|
import { readUint16, readUint64 } from '@based/utils';
|
|
@@ -27,6 +26,15 @@ class SortIndex {
|
|
|
27
26
|
export class DbServer extends DbShared {
|
|
28
27
|
modifyDirtyRanges;
|
|
29
28
|
dbCtxExternal; // pointer to zig dbCtx
|
|
29
|
+
subscriptions = {
|
|
30
|
+
subInterval: 200,
|
|
31
|
+
active: 0,
|
|
32
|
+
updateHandler: null,
|
|
33
|
+
ids: new Map(),
|
|
34
|
+
fullType: new Map(),
|
|
35
|
+
updateId: 1,
|
|
36
|
+
now: { listeners: new Set(), lastUpdated: 1 },
|
|
37
|
+
};
|
|
30
38
|
migrating = null;
|
|
31
39
|
saveInProgress = false;
|
|
32
40
|
fileSystemPath;
|
|
@@ -382,6 +390,8 @@ export class DbServer extends DbShared {
|
|
|
382
390
|
if (this.stopped) {
|
|
383
391
|
return;
|
|
384
392
|
}
|
|
393
|
+
clearTimeout(this.subscriptions.updateHandler);
|
|
394
|
+
this.subscriptions.updateHandler = null;
|
|
385
395
|
this.stopped = true;
|
|
386
396
|
this.unlistenExit();
|
|
387
397
|
if (this.cleanupTimer) {
|
|
@@ -402,7 +412,6 @@ export class DbServer extends DbShared {
|
|
|
402
412
|
this.workers = [];
|
|
403
413
|
native.stop(this.dbCtxExternal);
|
|
404
414
|
this.dbCtxExternal = null;
|
|
405
|
-
await setTimeout(100);
|
|
406
415
|
}
|
|
407
416
|
catch (e) {
|
|
408
417
|
this.stopped = false;
|
|
@@ -10,101 +10,104 @@ if (isMainThread) {
|
|
|
10
10
|
console.warn('running worker.ts in mainthread');
|
|
11
11
|
}
|
|
12
12
|
else if (workerData?.isDbMigrateWorker) {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
const
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
if (prop.
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
edge
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
13
|
+
;
|
|
14
|
+
(async () => {
|
|
15
|
+
const { from, to, fromSchema, toSchema, channel, workerState, transformFns, } = workerData;
|
|
16
|
+
const fromCtx = native.externalFromInt(from);
|
|
17
|
+
const toCtx = native.externalFromInt(to);
|
|
18
|
+
native.createThreadCtx(fromCtx, native.getThreadId());
|
|
19
|
+
native.createThreadCtx(toCtx, native.getThreadId());
|
|
20
|
+
const fromDb = new BasedDb({ path: null });
|
|
21
|
+
const toDb = new BasedDb({ path: null });
|
|
22
|
+
fromDb.server.dbCtxExternal = fromCtx;
|
|
23
|
+
toDb.server.dbCtxExternal = toCtx;
|
|
24
|
+
setSchemaOnServer(fromDb.server, deSerialize(fromSchema));
|
|
25
|
+
setSchemaOnServer(toDb.server, deSerialize(toSchema));
|
|
26
|
+
setLocalClientSchema(fromDb.client, fromDb.server.schema);
|
|
27
|
+
setLocalClientSchema(toDb.client, toDb.server.schema);
|
|
28
|
+
try {
|
|
29
|
+
const map = {};
|
|
30
|
+
for (const type in fromDb.server.schemaTypesParsed) {
|
|
31
|
+
const { id, props } = fromDb.server.schemaTypesParsed[type];
|
|
32
|
+
const include = [];
|
|
33
|
+
const includeRaw = [];
|
|
34
|
+
for (const path in props) {
|
|
35
|
+
const prop = props[path];
|
|
36
|
+
if (prop.typeIndex === REFERENCE || prop.typeIndex === REFERENCES) {
|
|
37
|
+
include.push(`${path}.id`);
|
|
38
|
+
if (prop.edges) {
|
|
39
|
+
for (const key in prop.edges) {
|
|
40
|
+
const edge = prop.edges[key];
|
|
41
|
+
if (edge.typeIndex === REFERENCE ||
|
|
42
|
+
edge.typeIndex === REFERENCES) {
|
|
43
|
+
include.push(`${path}.${key}.id`);
|
|
44
|
+
}
|
|
45
|
+
else if (edge.typeIndex === CARDINALITY) {
|
|
46
|
+
includeRaw.push(`${path}.${key}`);
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
include.push(`${path}.${key}`);
|
|
50
|
+
}
|
|
48
51
|
}
|
|
49
52
|
}
|
|
50
53
|
}
|
|
54
|
+
else if (prop.typeIndex === CARDINALITY) {
|
|
55
|
+
includeRaw.push(path);
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
include.push(path);
|
|
59
|
+
}
|
|
51
60
|
}
|
|
52
|
-
|
|
53
|
-
includeRaw.push(path);
|
|
54
|
-
}
|
|
55
|
-
else {
|
|
56
|
-
include.push(path);
|
|
57
|
-
}
|
|
61
|
+
map[id] = { type, include, includeRaw };
|
|
58
62
|
}
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
query.
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
toDb.create(type, res || node, { unsafe: true });
|
|
63
|
+
for (const type in transformFns) {
|
|
64
|
+
const fnOrNull = transformFns[type];
|
|
65
|
+
transformFns[type] = eval(`(${fnOrNull})`);
|
|
66
|
+
}
|
|
67
|
+
while (true) {
|
|
68
|
+
let msg;
|
|
69
|
+
while ((msg = receiveMessageOnPort(channel))) {
|
|
70
|
+
const leafData = msg.message;
|
|
71
|
+
const { type, include, includeRaw } = map[leafData.typeId];
|
|
72
|
+
const typeTransformFn = transformFns[type];
|
|
73
|
+
const query = fromDb
|
|
74
|
+
.query(type)
|
|
75
|
+
.range(leafData.start - 1, leafData.end)
|
|
76
|
+
.include(include);
|
|
77
|
+
for (const rawProp of includeRaw) {
|
|
78
|
+
query.include(rawProp, { raw: true });
|
|
79
|
+
}
|
|
80
|
+
const nodes = query._getSync(fromCtx);
|
|
81
|
+
if (typeTransformFn) {
|
|
82
|
+
for (const node of nodes) {
|
|
83
|
+
const res = typeTransformFn(node);
|
|
84
|
+
if (res === null) {
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
if (Array.isArray(res)) {
|
|
88
|
+
toDb.create(res[0], res[1] || node, { unsafe: true });
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
toDb.create(type, res || node, { unsafe: true });
|
|
92
|
+
}
|
|
90
93
|
}
|
|
91
94
|
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
95
|
+
else if (type in toDb.server.schemaTypesParsed) {
|
|
96
|
+
for (const node of nodes) {
|
|
97
|
+
toDb.create(type, node, { unsafe: true });
|
|
98
|
+
}
|
|
96
99
|
}
|
|
97
100
|
}
|
|
101
|
+
await toDb.drain();
|
|
102
|
+
native.membarSyncWrite();
|
|
103
|
+
setToSleep(workerState);
|
|
98
104
|
}
|
|
99
|
-
await toDb.drain();
|
|
100
|
-
native.membarSyncWrite();
|
|
101
|
-
setToSleep(workerState);
|
|
102
105
|
}
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
}
|
|
106
|
+
catch (e) {
|
|
107
|
+
console.error(e);
|
|
108
|
+
throw e;
|
|
109
|
+
}
|
|
110
|
+
})();
|
|
108
111
|
}
|
|
109
112
|
else {
|
|
110
113
|
console.info('incorrect worker db migrate');
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { updateTypeDefs } from '@based/schema/def';
|
|
2
2
|
import { serialize } from '@based/schema';
|
|
3
3
|
import { join } from 'node:path';
|
|
4
4
|
import { writeFile } from 'node:fs/promises';
|
|
@@ -8,6 +8,7 @@ import { saveSync } from './save.js';
|
|
|
8
8
|
import { writeCreate } from '../client/modify/create/index.js';
|
|
9
9
|
import { Ctx } from '../client/modify/Ctx.js';
|
|
10
10
|
import { consume } from '../client/modify/drain.js';
|
|
11
|
+
import { schemaToSelvaBuffer } from './schemaSelvaBuffer.js';
|
|
11
12
|
export const setSchemaOnServer = (server, schema) => {
|
|
12
13
|
const { schemaTypesParsed, schemaTypesParsedById } = updateTypeDefs(schema);
|
|
13
14
|
server.schema = schema;
|
|
@@ -40,7 +41,7 @@ export const setNativeSchema = (server, schema) => {
|
|
|
40
41
|
const type = server.schemaTypesParsed[types[i]];
|
|
41
42
|
maxTid = Math.max(maxTid, type.id);
|
|
42
43
|
try {
|
|
43
|
-
native.setSchemaType(type.id, new Uint8Array(s[i])
|
|
44
|
+
native.setSchemaType(server.dbCtxExternal, type.id, new Uint8Array(s[i]));
|
|
44
45
|
}
|
|
45
46
|
catch (err) {
|
|
46
47
|
throw new Error(`Cannot update schema on selva (native) ${type.type} ${err.message}`);
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import { ENCODER, writeDoubleLE, writeUint16, writeUint32, writeUint64 } from '@based/utils';
|
|
2
|
+
import { ALIAS, ALIASES, BINARY, EMPTY_MICRO_BUFFER, CARDINALITY, MICRO_BUFFER, REFERENCE, REFERENCES, STRING, TEXT, VECTOR, JSON, COLVEC, VECTOR_BASE_TYPE_SIZE_MAP, INT8, UINT8, BOOLEAN, INT16, UINT16, INT32, UINT32, NUMBER, TIMESTAMP, ENUM, } from '@based/schema/def';
|
|
3
|
+
import { NOT_COMPRESSED } from '@based/protocol';
|
|
4
|
+
import native from '../native.js';
|
|
5
|
+
const selvaFieldType = {
|
|
6
|
+
NULL: 0,
|
|
7
|
+
MICRO_BUFFER: 1,
|
|
8
|
+
STRING: 2,
|
|
9
|
+
TEXT: 3,
|
|
10
|
+
REFERENCE: 4,
|
|
11
|
+
REFERENCES: 5,
|
|
12
|
+
ALIAS: 8,
|
|
13
|
+
ALIASES: 9,
|
|
14
|
+
COLVEC: 10,
|
|
15
|
+
};
|
|
16
|
+
const selvaTypeMap = new Uint8Array(32); // 1.2x faster than JS array
|
|
17
|
+
selvaTypeMap[MICRO_BUFFER] = selvaFieldType.MICRO_BUFFER;
|
|
18
|
+
selvaTypeMap[VECTOR] = selvaFieldType.MICRO_BUFFER;
|
|
19
|
+
selvaTypeMap[BINARY] = selvaFieldType.STRING;
|
|
20
|
+
selvaTypeMap[CARDINALITY] = selvaFieldType.STRING;
|
|
21
|
+
selvaTypeMap[JSON] = selvaFieldType.STRING;
|
|
22
|
+
selvaTypeMap[STRING] = selvaFieldType.STRING;
|
|
23
|
+
selvaTypeMap[TEXT] = selvaFieldType.TEXT;
|
|
24
|
+
selvaTypeMap[REFERENCE] = selvaFieldType.REFERENCE;
|
|
25
|
+
selvaTypeMap[REFERENCES] = selvaFieldType.REFERENCES;
|
|
26
|
+
selvaTypeMap[ALIAS] = selvaFieldType.ALIAS;
|
|
27
|
+
selvaTypeMap[ALIASES] = selvaFieldType.ALIASES;
|
|
28
|
+
selvaTypeMap[COLVEC] = selvaFieldType.COLVEC;
|
|
29
|
+
const EDGE_FIELD_CONSTRAINT_FLAG_DEPENDENT = 0x01;
|
|
30
|
+
function blockCapacity(blockCapacity) {
|
|
31
|
+
const buf = new Uint8Array(Uint32Array.BYTES_PER_ELEMENT);
|
|
32
|
+
const view = new DataView(buf.buffer);
|
|
33
|
+
view.setUint32(0, blockCapacity, true);
|
|
34
|
+
return buf;
|
|
35
|
+
}
|
|
36
|
+
function sepPropCount(props) {
|
|
37
|
+
return props.filter((prop) => prop.separate).length;
|
|
38
|
+
}
|
|
39
|
+
function makeEdgeConstraintFlags(prop) {
|
|
40
|
+
let flags = 0;
|
|
41
|
+
flags |= prop.dependent ? EDGE_FIELD_CONSTRAINT_FLAG_DEPENDENT : 0x00;
|
|
42
|
+
return flags;
|
|
43
|
+
}
|
|
44
|
+
const propDefBuffer = (schema, prop) => {
|
|
45
|
+
const type = prop.typeIndex;
|
|
46
|
+
const selvaType = selvaTypeMap[type];
|
|
47
|
+
if (prop.len && (type === MICRO_BUFFER || type === VECTOR)) {
|
|
48
|
+
const buf = new Uint8Array(4);
|
|
49
|
+
const view = new DataView(buf.buffer);
|
|
50
|
+
buf[0] = selvaType;
|
|
51
|
+
view.setUint16(1, prop.len, true);
|
|
52
|
+
if (prop.default) {
|
|
53
|
+
buf[3] = 1; // has default
|
|
54
|
+
return [...buf, ...prop.default];
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
buf[3] = 0; // has default
|
|
58
|
+
return [...buf];
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
else if (prop.len && type === COLVEC) {
|
|
62
|
+
const buf = new Uint8Array(5);
|
|
63
|
+
const view = new DataView(buf.buffer);
|
|
64
|
+
buf[0] = selvaType;
|
|
65
|
+
const baseSize = VECTOR_BASE_TYPE_SIZE_MAP[prop.vectorBaseType];
|
|
66
|
+
view.setUint16(1, prop.len / baseSize, true); // elements
|
|
67
|
+
view.setUint16(3, baseSize, true); // element size
|
|
68
|
+
return [...buf];
|
|
69
|
+
}
|
|
70
|
+
else if (type === REFERENCE || type === REFERENCES) {
|
|
71
|
+
const buf = new Uint8Array(7);
|
|
72
|
+
const view = new DataView(buf.buffer);
|
|
73
|
+
const dstType = schema[prop.inverseTypeName];
|
|
74
|
+
buf[0] = selvaType; // field type
|
|
75
|
+
buf[1] = makeEdgeConstraintFlags(prop); // flags
|
|
76
|
+
view.setUint16(2, dstType.id, true); // dst_node_type
|
|
77
|
+
buf[4] = prop.inversePropNumber; // inverse_field
|
|
78
|
+
view.setUint16(5, prop.edgeNodeTypeId ?? 0, true); // meta_node_type
|
|
79
|
+
return [...buf];
|
|
80
|
+
}
|
|
81
|
+
else if (type === STRING ||
|
|
82
|
+
type === BINARY ||
|
|
83
|
+
type === CARDINALITY ||
|
|
84
|
+
type === JSON) {
|
|
85
|
+
return [selvaType, prop.len < 50 ? prop.len : 0];
|
|
86
|
+
}
|
|
87
|
+
{
|
|
88
|
+
return [selvaType];
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
// TODO rewrite
|
|
92
|
+
export function schemaToSelvaBuffer(schema) {
|
|
93
|
+
return Object.values(schema).map((t) => {
|
|
94
|
+
const props = Object.values(t.props);
|
|
95
|
+
const rest = [];
|
|
96
|
+
const nrFields = 1 + sepPropCount(props);
|
|
97
|
+
let refFields = 0;
|
|
98
|
+
let virtualFields = 0;
|
|
99
|
+
if (nrFields >= 250) {
|
|
100
|
+
throw new Error('Too many fields');
|
|
101
|
+
}
|
|
102
|
+
const main = {
|
|
103
|
+
...EMPTY_MICRO_BUFFER,
|
|
104
|
+
len: t.mainLen === 0 ? 1 : t.mainLen,
|
|
105
|
+
};
|
|
106
|
+
for (const f of props) {
|
|
107
|
+
if (f.separate) {
|
|
108
|
+
if (f.typeIndex === REFERENCE || f.typeIndex === REFERENCES) {
|
|
109
|
+
refFields++;
|
|
110
|
+
}
|
|
111
|
+
else if (f.typeIndex === ALIAS ||
|
|
112
|
+
f.typeIndex === ALIASES ||
|
|
113
|
+
f.typeIndex === COLVEC) {
|
|
114
|
+
// We assume that these are always the last props!
|
|
115
|
+
virtualFields++;
|
|
116
|
+
}
|
|
117
|
+
rest.push(f);
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
if (f.default) {
|
|
121
|
+
if (!main.default) {
|
|
122
|
+
main.default = new Uint8Array(main.len);
|
|
123
|
+
}
|
|
124
|
+
const buf = main.default;
|
|
125
|
+
switch (f.typeIndex) {
|
|
126
|
+
case INT8:
|
|
127
|
+
case UINT8:
|
|
128
|
+
case BOOLEAN:
|
|
129
|
+
case ENUM:
|
|
130
|
+
main.default[f.start] = f.default;
|
|
131
|
+
break;
|
|
132
|
+
case INT16:
|
|
133
|
+
case UINT16:
|
|
134
|
+
writeUint16(buf, f.default, f.start);
|
|
135
|
+
break;
|
|
136
|
+
case INT32:
|
|
137
|
+
case UINT32:
|
|
138
|
+
writeUint32(buf, f.default, f.start);
|
|
139
|
+
break;
|
|
140
|
+
case NUMBER:
|
|
141
|
+
writeDoubleLE(buf, f.default, f.start);
|
|
142
|
+
//const view = new DataView(
|
|
143
|
+
// buf.buffer,
|
|
144
|
+
// f.start,
|
|
145
|
+
// 8,
|
|
146
|
+
//)
|
|
147
|
+
//view.setFloat64(0, f.default, true)
|
|
148
|
+
break;
|
|
149
|
+
case TIMESTAMP:
|
|
150
|
+
writeUint64(buf, f.default, f.start);
|
|
151
|
+
break;
|
|
152
|
+
case BINARY:
|
|
153
|
+
case STRING:
|
|
154
|
+
if (f.default instanceof Uint8Array) {
|
|
155
|
+
buf.set(f.default, f.start);
|
|
156
|
+
}
|
|
157
|
+
else {
|
|
158
|
+
const value = f.default.normalize('NFKD');
|
|
159
|
+
buf[f.start] = 0; // lang
|
|
160
|
+
buf[f.start + 1] = NOT_COMPRESSED;
|
|
161
|
+
const { written: l } = ENCODER.encodeInto(value, buf.subarray(f.start + 2));
|
|
162
|
+
let crc = native.crc32(buf.subarray(f.start + 2, f.start + 2 + l));
|
|
163
|
+
writeUint32(buf, crc, f.start + 2 + l);
|
|
164
|
+
}
|
|
165
|
+
break;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
rest.sort((a, b) => a.prop - b.prop);
|
|
171
|
+
return Uint8Array.from([
|
|
172
|
+
...blockCapacity(t.blockCapacity), // u32 blockCapacity
|
|
173
|
+
nrFields, // u8 nrFields
|
|
174
|
+
1 + refFields, // u8 nrFixedFields
|
|
175
|
+
virtualFields, // u8 nrVirtualFields
|
|
176
|
+
6, // u8 version (generally follows the sdb version)
|
|
177
|
+
...propDefBuffer(schema, main),
|
|
178
|
+
...rest.map((f) => propDefBuffer(schema, f)).flat(1),
|
|
179
|
+
]).buffer;
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
//# sourceMappingURL=schemaSelvaBuffer.js.map
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { OnError } from '../client/query/subscription/types.js';
|
|
2
|
+
import { DbServer } from '../index.js';
|
|
3
|
+
type OnData = (res: Uint8Array) => void;
|
|
4
|
+
export type SubscriptionFullType = {
|
|
5
|
+
listeners: Set<() => void>;
|
|
6
|
+
};
|
|
7
|
+
export type SubscriptionNow = {
|
|
8
|
+
lastEval: number;
|
|
9
|
+
next: number;
|
|
10
|
+
listeners: Set<() => void>;
|
|
11
|
+
};
|
|
12
|
+
export type SubscriptionId = {
|
|
13
|
+
types?: Uint16Array;
|
|
14
|
+
ids: Map<number, Set<() => void>>;
|
|
15
|
+
typesListener?: () => void;
|
|
16
|
+
nowListener?: () => void;
|
|
17
|
+
};
|
|
18
|
+
export type Subscriptions = {
|
|
19
|
+
updateId: number;
|
|
20
|
+
active: number;
|
|
21
|
+
updateHandler: ReturnType<typeof setTimeout>;
|
|
22
|
+
ids: Map<number, SubscriptionId>;
|
|
23
|
+
fullType: Map<number, SubscriptionFullType>;
|
|
24
|
+
now: {
|
|
25
|
+
listeners: Set<() => void>;
|
|
26
|
+
lastUpdated: number;
|
|
27
|
+
};
|
|
28
|
+
subInterval: number;
|
|
29
|
+
};
|
|
30
|
+
export declare const startUpdateHandler: (server: DbServer) => void;
|
|
31
|
+
export declare const registerSubscription: (server: DbServer, query: Uint8Array, sub: Uint8Array, onData: OnData, onError: OnError, subInterval?: number) => () => void;
|
|
32
|
+
export {};
|