@based/db 0.0.28 → 0.0.30
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/fields.h +10 -2
- 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/fields.h +10 -2
- 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/fields.h +10 -2
- 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 +15 -19
- package/dist/src/client/index.d.ts +8 -10
- package/dist/src/client/index.js +19 -8
- package/dist/src/client/modify/ModifyRes.d.ts +2 -4
- package/dist/src/client/modify/ModifyRes.js +15 -21
- package/dist/src/client/modify/create.js +1 -2
- package/dist/src/client/modify/delete.js +1 -2
- package/dist/src/client/modify/fixed.js +43 -8
- package/dist/src/client/modify/modify.js +0 -5
- 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/setCursor.js +1 -1
- 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 +5 -3
- 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 +16 -7
- package/dist/src/client/query/search/index.js +11 -15
- package/dist/src/client/query/subscription/index.d.ts +1 -2
- package/dist/src/client/query/subscription/index.js +3 -50
- 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/subscription/types.d.ts +1 -29
- package/dist/src/client/query/subscription/types.js +8 -1
- 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 +10 -14
- package/dist/src/index.d.ts +1 -1
- package/dist/src/index.js +11 -15
- package/dist/src/native.d.ts +3 -3
- package/dist/src/native.js +6 -4
- 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
package/dist/src/server/save.js
CHANGED
|
@@ -2,18 +2,21 @@ import native from '../native.js';
|
|
|
2
2
|
import { isMainThread } from 'node:worker_threads';
|
|
3
3
|
import { writeFile } from 'node:fs/promises';
|
|
4
4
|
import { join } from 'node:path';
|
|
5
|
-
import { destructureCsmtKey, foreachBlock, foreachDirtyBlock, makeCsmtKey, } from './tree.js';
|
|
5
|
+
import { destructureCsmtKey, foreachBlock, foreachDirtyBlock, initCsmt, makeCsmtKey, specialBlock, } from './tree.js';
|
|
6
6
|
import { WRITELOG_FILE } from './index.js';
|
|
7
7
|
import { writeFileSync } from 'node:fs';
|
|
8
8
|
import { bufToHex } from '../utils.js';
|
|
9
|
-
import { createTree } from './csmt/tree.js';
|
|
10
9
|
const COMMON_SDB_FILE = 'common.sdb';
|
|
11
10
|
const block_sdb_file = (typeId, start, end) => `${typeId}_${start}_${end}.sdb`;
|
|
12
11
|
function saveRange(db, typeId, start, end, hashOut) {
|
|
13
12
|
const file = block_sdb_file(typeId, start, end);
|
|
14
13
|
const path = join(db.fileSystemPath, file);
|
|
15
14
|
const err = native.saveRange(path, typeId, start, end, db.dbCtxExternal, hashOut);
|
|
16
|
-
if (err) {
|
|
15
|
+
if (err == -8) {
|
|
16
|
+
// TODO ENOENT
|
|
17
|
+
return '';
|
|
18
|
+
}
|
|
19
|
+
else if (err) {
|
|
17
20
|
// TODO print the error string
|
|
18
21
|
console.error(`Save ${typeId}:${start}-${end} failed: ${err}`);
|
|
19
22
|
return null;
|
|
@@ -32,51 +35,58 @@ export function save(db, sync = false, forceFullDump = false) {
|
|
|
32
35
|
}
|
|
33
36
|
if (forceFullDump) {
|
|
34
37
|
// We just rebuild the whole tree
|
|
35
|
-
|
|
38
|
+
initCsmt(db);
|
|
36
39
|
for (const key in db.schemaTypesParsed) {
|
|
37
40
|
const def = db.schemaTypesParsed[key];
|
|
38
41
|
foreachBlock(db, def, (start, end, _hash) => {
|
|
39
42
|
const typeId = def.id;
|
|
43
|
+
const mtKey = makeCsmtKey(typeId, start);
|
|
40
44
|
const hash = new Uint8Array(16);
|
|
41
45
|
const file = saveRange(db, typeId, start, end, hash);
|
|
42
|
-
if (
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
+
if (file === null) {
|
|
47
|
+
throw new Error('full dump failed');
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
const data = {
|
|
51
|
+
file,
|
|
52
|
+
typeId,
|
|
53
|
+
start,
|
|
54
|
+
end,
|
|
55
|
+
};
|
|
56
|
+
db.merkleTree.insert(mtKey, hash, data);
|
|
46
57
|
}
|
|
47
|
-
const mtKey = makeCsmtKey(typeId, start);
|
|
48
|
-
const data = {
|
|
49
|
-
file,
|
|
50
|
-
typeId,
|
|
51
|
-
start,
|
|
52
|
-
end,
|
|
53
|
-
};
|
|
54
|
-
db.merkleTree.insert(mtKey, hash, data);
|
|
55
58
|
});
|
|
56
59
|
}
|
|
57
60
|
}
|
|
58
61
|
else {
|
|
59
62
|
foreachDirtyBlock(db, (mtKey, typeId, start, end) => {
|
|
60
63
|
const hash = new Uint8Array(16);
|
|
64
|
+
// TODO Don't save if empty
|
|
61
65
|
const file = saveRange(db, typeId, start, end, hash);
|
|
62
|
-
if (
|
|
66
|
+
if (file === null) {
|
|
63
67
|
// The previous state should remain in the merkle tree for
|
|
64
68
|
// load and sync purposes.
|
|
65
69
|
return;
|
|
66
70
|
}
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
typeId,
|
|
70
|
-
start,
|
|
71
|
-
end,
|
|
72
|
-
};
|
|
73
|
-
try {
|
|
74
|
-
db.merkleTree.delete(mtKey);
|
|
71
|
+
else if (file.length === 0) {
|
|
72
|
+
// The range is empty
|
|
75
73
|
}
|
|
76
|
-
|
|
77
|
-
|
|
74
|
+
else {
|
|
75
|
+
const oldLeaf = db.merkleTree.search(mtKey);
|
|
76
|
+
if (oldLeaf) {
|
|
77
|
+
oldLeaf.data.file = file;
|
|
78
|
+
db.merkleTree.update(mtKey, hash);
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
const data = {
|
|
82
|
+
file,
|
|
83
|
+
typeId,
|
|
84
|
+
start,
|
|
85
|
+
end,
|
|
86
|
+
};
|
|
87
|
+
db.merkleTree.insert(mtKey, hash, data);
|
|
88
|
+
}
|
|
78
89
|
}
|
|
79
|
-
db.merkleTree.insert(mtKey, hash, data);
|
|
80
90
|
});
|
|
81
91
|
}
|
|
82
92
|
db.dirtyRanges.clear();
|
|
@@ -89,6 +99,8 @@ export function save(db, sync = false, forceFullDump = false) {
|
|
|
89
99
|
}
|
|
90
100
|
db.merkleTree.visitLeafNodes((leaf) => {
|
|
91
101
|
const [typeId, start] = destructureCsmtKey(leaf.key);
|
|
102
|
+
if (start == specialBlock)
|
|
103
|
+
return; // skip the type specialBlock
|
|
92
104
|
const data = leaf.data;
|
|
93
105
|
if (start != data.start) {
|
|
94
106
|
console.error(`csmtKey start and range start mismatch: ${start} != ${data.start}`);
|
package/dist/src/server/start.js
CHANGED
|
@@ -3,8 +3,8 @@ import { DbWorker, SCHEMA_FILE, WRITELOG_FILE } from './index.js';
|
|
|
3
3
|
import native from '../native.js';
|
|
4
4
|
import { rm, mkdir, readFile } from 'node:fs/promises';
|
|
5
5
|
import { join } from 'node:path';
|
|
6
|
-
import {
|
|
7
|
-
import { foreachBlock, makeCsmtKey } from './tree.js';
|
|
6
|
+
import { hashEq } from './csmt/index.js';
|
|
7
|
+
import { foreachBlock, initCsmt, makeCsmtKey } from './tree.js';
|
|
8
8
|
import { availableParallelism } from 'node:os';
|
|
9
9
|
import exitHook from 'exit-hook';
|
|
10
10
|
import './worker.js';
|
|
@@ -28,7 +28,7 @@ export async function start(db, opts) {
|
|
|
28
28
|
native.loadCommon(join(path, writelog.commonDump), db.dbCtxExternal);
|
|
29
29
|
}
|
|
30
30
|
catch (e) {
|
|
31
|
-
console.
|
|
31
|
+
console.error(e.message);
|
|
32
32
|
throw e;
|
|
33
33
|
}
|
|
34
34
|
// Load all range dumps
|
|
@@ -40,7 +40,7 @@ export async function start(db, opts) {
|
|
|
40
40
|
native.loadRange(join(path, fname), db.dbCtxExternal);
|
|
41
41
|
}
|
|
42
42
|
catch (e) {
|
|
43
|
-
console.
|
|
43
|
+
console.error(e.message);
|
|
44
44
|
}
|
|
45
45
|
}
|
|
46
46
|
}
|
|
@@ -53,21 +53,9 @@ export async function start(db, opts) {
|
|
|
53
53
|
catch (err) {
|
|
54
54
|
// TODO In some cases we really should give up!
|
|
55
55
|
}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
}
|
|
60
|
-
// FDN-791 CSMT is unstable (not history independent)
|
|
61
|
-
// For now we just sort the types to ensure that we always
|
|
62
|
-
// load in the same order.
|
|
63
|
-
const types = Object.keys(db.schemaTypesParsed)
|
|
64
|
-
.sort((a, b) => db.schemaTypesParsed[a].id - db.schemaTypesParsed[b].id)
|
|
65
|
-
.reduce((obj, key) => {
|
|
66
|
-
obj[key] = db.schemaTypesParsed[key];
|
|
67
|
-
return obj;
|
|
68
|
-
}, {});
|
|
69
|
-
for (const key in types) {
|
|
70
|
-
const def = types[key];
|
|
56
|
+
const csmtTypes = initCsmt(db);
|
|
57
|
+
for (const key in csmtTypes) {
|
|
58
|
+
const def = csmtTypes[key];
|
|
71
59
|
const [total, lastId] = native.getTypeInfo(def.id, db.dbCtxExternal);
|
|
72
60
|
def.total = total;
|
|
73
61
|
def.lastId = writelog?.types[def.id]?.lastId || lastId;
|
|
@@ -6,8 +6,10 @@ export type CsmtNodeRange = {
|
|
|
6
6
|
start: number;
|
|
7
7
|
end: number;
|
|
8
8
|
};
|
|
9
|
+
export declare const specialBlock = 2147483647;
|
|
9
10
|
export declare const destructureCsmtKey: (key: number) => number[];
|
|
10
11
|
export declare const makeCsmtKey: (typeId: number, start: number) => number;
|
|
11
12
|
export declare const makeCsmtKeyFromNodeId: (typeId: number, blockCapacity: number, nodeId: number) => number;
|
|
13
|
+
export declare function initCsmt(db: DbServer): {};
|
|
12
14
|
export declare function foreachBlock(db: DbServer, def: SchemaTypeDef, cb: (start: number, end: number, hash: Uint8Array) => void): void;
|
|
13
15
|
export declare function foreachDirtyBlock(db: DbServer, cb: (mtKey: number, typeId: number, start: number, end: number) => void): Promise<void>;
|
package/dist/src/server/tree.js
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
import native from '../native.js';
|
|
2
|
+
import { createTree } from './csmt/tree.js';
|
|
3
|
+
// This is a special start id set for every type to somewhat lock the order of the csmt.
|
|
4
|
+
// While the id is valid, it's never a true start id of a block.
|
|
5
|
+
export const specialBlock = 2147483647;
|
|
2
6
|
export const destructureCsmtKey = (key) => [
|
|
3
7
|
(key / 4294967296) | 0, // typeId
|
|
4
8
|
(key >>> 31) * 2147483648 + (key & 0x7fffffff), // start_node_id
|
|
@@ -8,13 +12,41 @@ export const makeCsmtKeyFromNodeId = (typeId, blockCapacity, nodeId) => {
|
|
|
8
12
|
const tmp = nodeId - +!(nodeId % blockCapacity);
|
|
9
13
|
return typeId * 4294967296 + ((tmp / blockCapacity) | 0) * blockCapacity + 1;
|
|
10
14
|
};
|
|
15
|
+
export function initCsmt(db) {
|
|
16
|
+
const types = Object.keys(db.schemaTypesParsed)
|
|
17
|
+
.sort((a, b) => db.schemaTypesParsed[a].id - db.schemaTypesParsed[b].id)
|
|
18
|
+
.reduce((obj, key) => {
|
|
19
|
+
obj[key] = db.schemaTypesParsed[key];
|
|
20
|
+
return obj;
|
|
21
|
+
}, {});
|
|
22
|
+
db.merkleTree = createTree(db.createCsmtHashFun);
|
|
23
|
+
// Insert specialBlocks for types.
|
|
24
|
+
// This should ensure that the insertion order of the actual node ranges is
|
|
25
|
+
// always deterministic.
|
|
26
|
+
for (const key in types) {
|
|
27
|
+
const { id: typeId } = types[key];
|
|
28
|
+
const data = {
|
|
29
|
+
file: '',
|
|
30
|
+
typeId: typeId,
|
|
31
|
+
start: 0,
|
|
32
|
+
end: 0,
|
|
33
|
+
};
|
|
34
|
+
try {
|
|
35
|
+
db.merkleTree.insert(makeCsmtKey(typeId, specialBlock), db.merkleTree.emptyHash, data);
|
|
36
|
+
}
|
|
37
|
+
catch (_) { }
|
|
38
|
+
}
|
|
39
|
+
return types;
|
|
40
|
+
}
|
|
11
41
|
export function foreachBlock(db, def, cb) {
|
|
12
42
|
const step = def.blockCapacity;
|
|
13
43
|
for (let start = 1; start <= def.lastId; start += step) {
|
|
14
44
|
const end = start + step - 1;
|
|
15
45
|
const hash = new Uint8Array(16);
|
|
16
|
-
native.getNodeRangeHash(def.id, start, end, hash, db.dbCtxExternal);
|
|
17
|
-
|
|
46
|
+
const res = native.getNodeRangeHash(def.id, start, end, hash, db.dbCtxExternal);
|
|
47
|
+
if (res) {
|
|
48
|
+
cb(start, end, hash);
|
|
49
|
+
}
|
|
18
50
|
}
|
|
19
51
|
}
|
|
20
52
|
export async function foreachDirtyBlock(db, cb) {
|
|
@@ -8,7 +8,7 @@ else {
|
|
|
8
8
|
let { address, channel } = workerData;
|
|
9
9
|
let dbCtx = native.externalFromInt(address);
|
|
10
10
|
workerCtx = native.workerCtxInit();
|
|
11
|
-
const transferList = new Array(1)
|
|
11
|
+
// const transferList = new Array(1)
|
|
12
12
|
const handleMsg = (msg) => {
|
|
13
13
|
try {
|
|
14
14
|
if (typeof msg === 'bigint') {
|
|
@@ -19,8 +19,8 @@ else {
|
|
|
19
19
|
}
|
|
20
20
|
else {
|
|
21
21
|
const arrayBuf = native.getQueryBuf(msg, dbCtx);
|
|
22
|
-
transferList[0] = arrayBuf
|
|
23
|
-
channel.postMessage(arrayBuf,
|
|
22
|
+
// transferList[0] = arrayBuf
|
|
23
|
+
channel.postMessage(arrayBuf, [arrayBuf]);
|
|
24
24
|
}
|
|
25
25
|
}
|
|
26
26
|
catch (e) {
|
package/dist/src/utils.d.ts
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
|
+
import { DbServer } from './server/index.js';
|
|
1
2
|
export declare const DECODER: TextDecoder;
|
|
2
3
|
export declare const ENCODER: TextEncoder;
|
|
4
|
+
export declare const debugMode: (target: any, getInfo?: any) => void;
|
|
5
|
+
export declare const debugServer: (server: DbServer) => void;
|
|
3
6
|
export declare const equals: (aB: Uint8Array, bB: Uint8Array) => boolean;
|
|
4
7
|
export declare function concatUint8Arr(bufs: Uint8Array[], totalByteLength?: number): Uint8Array;
|
|
5
8
|
export declare const bufToHex: (a: Uint8Array) => string;
|
|
6
9
|
export declare const hexToBuf: (s: string) => Uint8Array;
|
|
7
|
-
export declare const base64encode: (a: Uint8Array, lineMax?: number) => string;
|
|
8
10
|
export declare const readDoubleLE: (val: Uint8Array, offset: number) => number;
|
|
9
11
|
export declare const readFloatLE: (val: Uint8Array, offset: number) => number;
|
|
10
12
|
export declare const readUint32: (val: Uint8Array, offset: number) => number;
|
package/dist/src/utils.js
CHANGED
|
@@ -1,7 +1,49 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { inspect } from 'node:util';
|
|
2
|
+
import picocolors from 'picocolors';
|
|
2
3
|
const native = typeof window === 'undefined' ? (await import('./native.js')).default : null;
|
|
3
4
|
export const DECODER = new TextDecoder('utf-8');
|
|
4
5
|
export const ENCODER = new TextEncoder();
|
|
6
|
+
export const debugMode = (target, getInfo = null) => {
|
|
7
|
+
const opts = { showHidden: false, depth: null, colors: true };
|
|
8
|
+
const info = (v) => (typeof v === 'object' ? inspect(v, opts) : v);
|
|
9
|
+
const proto = target.constructor.prototype;
|
|
10
|
+
const keys = new Set([
|
|
11
|
+
...Object.keys(Object.getOwnPropertyDescriptors(proto)),
|
|
12
|
+
...Object.keys(target),
|
|
13
|
+
]);
|
|
14
|
+
const colors = [
|
|
15
|
+
'red',
|
|
16
|
+
'green',
|
|
17
|
+
'yellow',
|
|
18
|
+
'blue',
|
|
19
|
+
'magenta',
|
|
20
|
+
'cyan',
|
|
21
|
+
'redBright',
|
|
22
|
+
'greenBright',
|
|
23
|
+
'yellowBright',
|
|
24
|
+
'blueBright',
|
|
25
|
+
'magentaBright',
|
|
26
|
+
'cyanBright',
|
|
27
|
+
];
|
|
28
|
+
let colorKey = 0;
|
|
29
|
+
for (const key of keys) {
|
|
30
|
+
const fn = target[key];
|
|
31
|
+
if (typeof fn === 'function') {
|
|
32
|
+
let cnt = 0;
|
|
33
|
+
const color = colors[colorKey++ % colors.length];
|
|
34
|
+
target[key] = function () {
|
|
35
|
+
const arr = [picocolors[color](`[${key}:${++cnt}]`)];
|
|
36
|
+
const add = getInfo?.(key);
|
|
37
|
+
if (add)
|
|
38
|
+
arr.push(add);
|
|
39
|
+
arr.push(...arguments);
|
|
40
|
+
console.info(arr.map(info).join(' '));
|
|
41
|
+
return fn.apply(target, arguments);
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
export const debugServer = (server) => debugMode(server, () => `p: ${server.processingQueries} m: ${server.modifyQueue.length} q: ${server.queryQueue.size}`);
|
|
5
47
|
export const equals = (aB, bB) => {
|
|
6
48
|
const len = aB.byteLength;
|
|
7
49
|
if (len != bB.byteLength) {
|
|
@@ -82,24 +124,6 @@ export const hexToBuf = (s) => {
|
|
|
82
124
|
}
|
|
83
125
|
return buf;
|
|
84
126
|
};
|
|
85
|
-
function base64OutLen(n, lineMax) {
|
|
86
|
-
let olen;
|
|
87
|
-
/* This version would be with padding but we don't pad */
|
|
88
|
-
//olen = n * 4 / 3 + 4; /* 3-byte blocks to 4-byte */
|
|
89
|
-
olen = ((4 * n) / 3 + 3) & ~3;
|
|
90
|
-
olen += lineMax > 0 ? olen / lineMax : 0; // line feeds
|
|
91
|
-
return olen;
|
|
92
|
-
}
|
|
93
|
-
export const base64encode = (a, lineMax = 72) => {
|
|
94
|
-
// TODO Could fallback to @saulx/utils if native is not available
|
|
95
|
-
const tmp = new Uint8Array(base64OutLen(a.byteLength, lineMax));
|
|
96
|
-
if ((a.length < 10 && lineMax === 72) || !native) {
|
|
97
|
-
return encodeBase64(a);
|
|
98
|
-
}
|
|
99
|
-
else {
|
|
100
|
-
return DECODER.decode(native.base64encode(tmp, a, lineMax));
|
|
101
|
-
}
|
|
102
|
-
};
|
|
103
127
|
export const readDoubleLE = (val, offset) => {
|
|
104
128
|
const low = (val[offset] |
|
|
105
129
|
(val[offset + 1] << 8) |
|
package/package.json
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@based/db",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.30",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/src/index.js",
|
|
7
7
|
"scripts": {
|
|
8
8
|
"build": "make -C clibs && npm run build-zig && tsc",
|
|
9
|
+
"build-ts": "tsc",
|
|
9
10
|
"build-zig": "npx tsx scripts/zig_cross_compile.ts",
|
|
11
|
+
"build-linux_aarch64": "(cd clibs && podman run --rm -v \"$PWD/../../..:/usr/src/based-db\" based-db-clibs-build-linux_aarch64)",
|
|
12
|
+
"build-release-debug": "(cd clibs && ./build-release.sh) && npm run build-zig -- release debug && tsc",
|
|
10
13
|
"build-release": "(cd clibs && ./build-release.sh) && npm run build-zig -- release && tsc",
|
|
11
14
|
"watch": "npx tsc --watch",
|
|
12
15
|
"clean-selva": "make -C clibs clean",
|
|
@@ -18,7 +21,10 @@
|
|
|
18
21
|
"test-gdb": "npm run build && LOCPATH=../locale/locale-x86_64-gnu/locale gdb -ex run --args node ./scripts/test.js",
|
|
19
22
|
"test-fast": "LOCPATH=../locale/locale-x86_64-gnu/locale node ./scripts/test.js",
|
|
20
23
|
"test-fast-linux_aarch64": "podman run --rm -v \"$PWD/../..:/usr/src/based-db\" based-db-clibs-build-linux_aarch64 sh -c '\\. \"/usr/local/nvm/nvm.sh\"; cd /usr/src/based-db/packages/db; npm run test-fast'",
|
|
24
|
+
"test-fast-linux_aarch64-gdb": "podman run --rm -v \"$PWD/../..:/usr/src/based-db\" based-db-clibs-build-linux_aarch64 sh -c '\\. \"/usr/local/nvm/nvm.sh\"; cd /usr/src/based-db/packages/db; LOCPATH=../locale/locale-x86_64-gnu/locale gdb -ex run --args node ./scripts/test.js'",
|
|
25
|
+
"test-fast-linux_aarch64-valgrind": "podman run --rm -v \"$PWD/../..:/usr/src/based-db\" based-db-clibs-build-linux_aarch64 sh -c '\\. \"/usr/local/nvm/nvm.sh\"; cd /usr/src/based-db/packages/db; LOCPATH=../locale/locale-aarch64-gnu/locale valgrind --leak-check=full node ./scripts/test.js references:update2'",
|
|
21
26
|
"test-zig": "npm run build-zig -- debug && tsc && npm run test-fast",
|
|
27
|
+
"test-zig-debug": "npm run build-zig -- debug && tsc && LOCPATH=../locale/locale-x86_64-gnu/locale ./scripts/lldb-node ./scripts/test.js",
|
|
22
28
|
"test-ts": "tsc && node ./scripts/test.js",
|
|
23
29
|
"perf": "npm run build && node benchmarks/references.js && node benchmarks/transfermarkt/transfermarkt-based.js"
|
|
24
30
|
},
|
|
@@ -32,9 +38,9 @@
|
|
|
32
38
|
"basedDbNative.cjs"
|
|
33
39
|
],
|
|
34
40
|
"dependencies": {
|
|
35
|
-
"@based/schema": "5.0.0-alpha.
|
|
41
|
+
"@based/schema": "5.0.0-alpha.10",
|
|
36
42
|
"@saulx/hash": "^3.0.0",
|
|
37
|
-
"@saulx/utils": "^6.
|
|
43
|
+
"@saulx/utils": "^6.4.0",
|
|
38
44
|
"exit-hook": "^4.0.0",
|
|
39
45
|
"picocolors": "^1.1.0",
|
|
40
46
|
"@based/crc32c": "^1.0.0"
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Base64 encoding/decoding (RFC1341)
|
|
3
|
-
* Copyright (c) 2021-2025 SAULX
|
|
4
|
-
* Copyright (c) 2005-2011, Jouni Malinen <j@w1.fi>
|
|
5
|
-
* SPDX-License-Identifier: BSD-3-Clause
|
|
6
|
-
*/
|
|
7
|
-
#pragma once
|
|
8
|
-
|
|
9
|
-
#include "selva/_export.h"
|
|
10
|
-
|
|
11
|
-
SELVA_EXPORT
|
|
12
|
-
size_t base64_encode_s(char *out, const char *str_in, size_t len, size_t line_max)
|
|
13
|
-
__attribute__((access(write_only, 1), access(read_only, 2, 3)));
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* base64_encode - Base64 encode
|
|
17
|
-
* Caller is responsible for freeing the returned buffer. Returned buffer is
|
|
18
|
-
* nul terminated to make it easier to use as a C string. The nul terminator is
|
|
19
|
-
* not included in out_len.
|
|
20
|
-
* @parma str_in Data to be encoded
|
|
21
|
-
* @param len Length of the data to be encoded
|
|
22
|
-
* @param out_len Pointer to output length variable, or NULL if not used
|
|
23
|
-
* @returns Allocated buffer of out_len bytes of encoded data,
|
|
24
|
-
* or %NULL on failure
|
|
25
|
-
*/
|
|
26
|
-
[[nodiscard]]
|
|
27
|
-
SELVA_EXPORT
|
|
28
|
-
char * base64_encode(const char *str_in, size_t len, size_t *out_len)
|
|
29
|
-
__attribute__((access(read_only, 1, 2), access(read_only, 3)));
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Base64 decode.
|
|
33
|
-
* Caller is responsible for freeing the returned buffer.
|
|
34
|
-
* @param str_in Data to be decoded
|
|
35
|
-
* @param len Length of the data to be decoded
|
|
36
|
-
* @param out_len Pointer to output length variable
|
|
37
|
-
* @returns Allocated buffer of out_len bytes of decoded data, or NULL on failure
|
|
38
|
-
*/
|
|
39
|
-
[[nodiscard]]
|
|
40
|
-
SELVA_EXPORT
|
|
41
|
-
char * base64_decode(const char *str_in, size_t len, size_t *out_len)
|
|
42
|
-
__attribute__((access(read_only, 1, 2), access(write_only, 3)));
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Calculate the required buffer size of a string of n bytes.
|
|
46
|
-
* @param line_max is the max line length. 0 = no limit; 72 = typical.
|
|
47
|
-
*/
|
|
48
|
-
static inline size_t base64_out_len(size_t n, size_t line_max) {
|
|
49
|
-
size_t olen;
|
|
50
|
-
|
|
51
|
-
/* This version would be with padding but we don't pad */
|
|
52
|
-
#if 0
|
|
53
|
-
olen = n * 4 / 3 + 4; /* 3-byte blocks to 4-byte */
|
|
54
|
-
#endif
|
|
55
|
-
olen = ((4 * n / 3) + 3) & ~3;
|
|
56
|
-
olen += line_max > 0 ? olen / line_max : 0; /* line feeds */
|
|
57
|
-
|
|
58
|
-
return olen;
|
|
59
|
-
}
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Base64url encoding/decoding (RFC4648)
|
|
3
|
-
* Copyright (c) 2021-2025 SAULX
|
|
4
|
-
* Copyright (c) 2005-2011, Jouni Malinen <j@w1.fi>
|
|
5
|
-
* SPDX-License-Identifier: BSD-3-Clause
|
|
6
|
-
*/
|
|
7
|
-
#pragma once
|
|
8
|
-
|
|
9
|
-
#include "selva/_export.h"
|
|
10
|
-
|
|
11
|
-
SELVA_EXPORT
|
|
12
|
-
size_t base64url_encode_s(char *out, const char *str_in, size_t len, size_t line_max)
|
|
13
|
-
__attribute__((access(write_only, 1), access(read_only, 2, 3)));
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* base64url_encode - Base64url encode
|
|
17
|
-
* Caller is responsible for freeing the returned buffer. Returned buffer is
|
|
18
|
-
* nul terminated to make it easier to use as a C string. The nul terminator is
|
|
19
|
-
* not included in out_len.
|
|
20
|
-
* @parma str_in Data to be encoded
|
|
21
|
-
* @param len Length of the data to be encoded
|
|
22
|
-
* @param out_len Pointer to output length variable, or NULL if not used
|
|
23
|
-
* @returns Allocated buffer of out_len bytes of encoded data,
|
|
24
|
-
* or %NULL on failure
|
|
25
|
-
*/
|
|
26
|
-
[[nodiscard]]
|
|
27
|
-
SELVA_EXPORT
|
|
28
|
-
char * base64url_encode(const char *str_in, size_t len, size_t *out_len)
|
|
29
|
-
__attribute__((access(read_only, 1, 2), access(read_only, 3)));
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Base64url decode.
|
|
33
|
-
* Caller is responsible for freeing the returned buffer.
|
|
34
|
-
* @param str_in Data to be decoded
|
|
35
|
-
* @param len Length of the data to be decoded
|
|
36
|
-
* @param out_len Pointer to output length variable
|
|
37
|
-
* @returns Allocated buffer of out_len bytes of decoded data, or NULL on failure
|
|
38
|
-
*/
|
|
39
|
-
[[nodiscard]]
|
|
40
|
-
SELVA_EXPORT
|
|
41
|
-
char * base64url_decode(const char *str_in, size_t len, size_t *out_len)
|
|
42
|
-
__attribute__((access(read_only, 1, 2), access(write_only, 3)));
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Calculate the required buffer size of a string of n bytes.
|
|
46
|
-
* @param line_max is the max line length. 0 = no limit; 72 = typical.
|
|
47
|
-
*/
|
|
48
|
-
static inline size_t base64url_out_len(size_t n, size_t line_max) {
|
|
49
|
-
size_t olen;
|
|
50
|
-
|
|
51
|
-
/* This version would be with padding but we don't pad */
|
|
52
|
-
#if 0
|
|
53
|
-
olen = n * 4 / 3 + 4; /* 3-byte blocks to 4-byte */
|
|
54
|
-
#endif
|
|
55
|
-
olen = ((4 * n / 3) + 3) & ~3;
|
|
56
|
-
olen += line_max > 0 ? olen / line_max : 0; /* line feeds */
|
|
57
|
-
|
|
58
|
-
return olen;
|
|
59
|
-
}
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Base64 encoding/decoding (RFC1341)
|
|
3
|
-
* Copyright (c) 2021-2025 SAULX
|
|
4
|
-
* Copyright (c) 2005-2011, Jouni Malinen <j@w1.fi>
|
|
5
|
-
* SPDX-License-Identifier: BSD-3-Clause
|
|
6
|
-
*/
|
|
7
|
-
#pragma once
|
|
8
|
-
|
|
9
|
-
#include "selva/_export.h"
|
|
10
|
-
|
|
11
|
-
SELVA_EXPORT
|
|
12
|
-
size_t base64_encode_s(char *out, const char *str_in, size_t len, size_t line_max)
|
|
13
|
-
__attribute__((access(write_only, 1), access(read_only, 2, 3)));
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* base64_encode - Base64 encode
|
|
17
|
-
* Caller is responsible for freeing the returned buffer. Returned buffer is
|
|
18
|
-
* nul terminated to make it easier to use as a C string. The nul terminator is
|
|
19
|
-
* not included in out_len.
|
|
20
|
-
* @parma str_in Data to be encoded
|
|
21
|
-
* @param len Length of the data to be encoded
|
|
22
|
-
* @param out_len Pointer to output length variable, or NULL if not used
|
|
23
|
-
* @returns Allocated buffer of out_len bytes of encoded data,
|
|
24
|
-
* or %NULL on failure
|
|
25
|
-
*/
|
|
26
|
-
[[nodiscard]]
|
|
27
|
-
SELVA_EXPORT
|
|
28
|
-
char * base64_encode(const char *str_in, size_t len, size_t *out_len)
|
|
29
|
-
__attribute__((access(read_only, 1, 2), access(read_only, 3)));
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Base64 decode.
|
|
33
|
-
* Caller is responsible for freeing the returned buffer.
|
|
34
|
-
* @param str_in Data to be decoded
|
|
35
|
-
* @param len Length of the data to be decoded
|
|
36
|
-
* @param out_len Pointer to output length variable
|
|
37
|
-
* @returns Allocated buffer of out_len bytes of decoded data, or NULL on failure
|
|
38
|
-
*/
|
|
39
|
-
[[nodiscard]]
|
|
40
|
-
SELVA_EXPORT
|
|
41
|
-
char * base64_decode(const char *str_in, size_t len, size_t *out_len)
|
|
42
|
-
__attribute__((access(read_only, 1, 2), access(write_only, 3)));
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Calculate the required buffer size of a string of n bytes.
|
|
46
|
-
* @param line_max is the max line length. 0 = no limit; 72 = typical.
|
|
47
|
-
*/
|
|
48
|
-
static inline size_t base64_out_len(size_t n, size_t line_max) {
|
|
49
|
-
size_t olen;
|
|
50
|
-
|
|
51
|
-
/* This version would be with padding but we don't pad */
|
|
52
|
-
#if 0
|
|
53
|
-
olen = n * 4 / 3 + 4; /* 3-byte blocks to 4-byte */
|
|
54
|
-
#endif
|
|
55
|
-
olen = ((4 * n / 3) + 3) & ~3;
|
|
56
|
-
olen += line_max > 0 ? olen / line_max : 0; /* line feeds */
|
|
57
|
-
|
|
58
|
-
return olen;
|
|
59
|
-
}
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Base64url encoding/decoding (RFC4648)
|
|
3
|
-
* Copyright (c) 2021-2025 SAULX
|
|
4
|
-
* Copyright (c) 2005-2011, Jouni Malinen <j@w1.fi>
|
|
5
|
-
* SPDX-License-Identifier: BSD-3-Clause
|
|
6
|
-
*/
|
|
7
|
-
#pragma once
|
|
8
|
-
|
|
9
|
-
#include "selva/_export.h"
|
|
10
|
-
|
|
11
|
-
SELVA_EXPORT
|
|
12
|
-
size_t base64url_encode_s(char *out, const char *str_in, size_t len, size_t line_max)
|
|
13
|
-
__attribute__((access(write_only, 1), access(read_only, 2, 3)));
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* base64url_encode - Base64url encode
|
|
17
|
-
* Caller is responsible for freeing the returned buffer. Returned buffer is
|
|
18
|
-
* nul terminated to make it easier to use as a C string. The nul terminator is
|
|
19
|
-
* not included in out_len.
|
|
20
|
-
* @parma str_in Data to be encoded
|
|
21
|
-
* @param len Length of the data to be encoded
|
|
22
|
-
* @param out_len Pointer to output length variable, or NULL if not used
|
|
23
|
-
* @returns Allocated buffer of out_len bytes of encoded data,
|
|
24
|
-
* or %NULL on failure
|
|
25
|
-
*/
|
|
26
|
-
[[nodiscard]]
|
|
27
|
-
SELVA_EXPORT
|
|
28
|
-
char * base64url_encode(const char *str_in, size_t len, size_t *out_len)
|
|
29
|
-
__attribute__((access(read_only, 1, 2), access(read_only, 3)));
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Base64url decode.
|
|
33
|
-
* Caller is responsible for freeing the returned buffer.
|
|
34
|
-
* @param str_in Data to be decoded
|
|
35
|
-
* @param len Length of the data to be decoded
|
|
36
|
-
* @param out_len Pointer to output length variable
|
|
37
|
-
* @returns Allocated buffer of out_len bytes of decoded data, or NULL on failure
|
|
38
|
-
*/
|
|
39
|
-
[[nodiscard]]
|
|
40
|
-
SELVA_EXPORT
|
|
41
|
-
char * base64url_decode(const char *str_in, size_t len, size_t *out_len)
|
|
42
|
-
__attribute__((access(read_only, 1, 2), access(write_only, 3)));
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Calculate the required buffer size of a string of n bytes.
|
|
46
|
-
* @param line_max is the max line length. 0 = no limit; 72 = typical.
|
|
47
|
-
*/
|
|
48
|
-
static inline size_t base64url_out_len(size_t n, size_t line_max) {
|
|
49
|
-
size_t olen;
|
|
50
|
-
|
|
51
|
-
/* This version would be with padding but we don't pad */
|
|
52
|
-
#if 0
|
|
53
|
-
olen = n * 4 / 3 + 4; /* 3-byte blocks to 4-byte */
|
|
54
|
-
#endif
|
|
55
|
-
olen = ((4 * n / 3) + 3) & ~3;
|
|
56
|
-
olen += line_max > 0 ? olen / line_max : 0; /* line feeds */
|
|
57
|
-
|
|
58
|
-
return olen;
|
|
59
|
-
}
|