@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.
Files changed (115) hide show
  1. package/README.md +1 -399
  2. package/dist/lib/darwin_aarch64/include/selva/db.h +8 -4
  3. package/dist/lib/darwin_aarch64/include/selva/fields.h +10 -2
  4. package/dist/lib/darwin_aarch64/include/selva/selva_hash128.h +17 -7
  5. package/dist/lib/darwin_aarch64/include/selva/sort.h +21 -14
  6. package/dist/lib/darwin_aarch64/libdeflate.dylib +0 -0
  7. package/dist/lib/darwin_aarch64/libjemalloc_selva.2.dylib +0 -0
  8. package/dist/lib/darwin_aarch64/libnode-v20.node +0 -0
  9. package/dist/lib/darwin_aarch64/libnode-v21.node +0 -0
  10. package/dist/lib/darwin_aarch64/libnode-v22.node +0 -0
  11. package/dist/lib/darwin_aarch64/libnode-v23.node +0 -0
  12. package/dist/lib/darwin_aarch64/libselva.dylib +0 -0
  13. package/dist/lib/darwin_aarch64/libxxhash.dylib +0 -0
  14. package/dist/lib/linux_aarch64/include/selva/db.h +8 -4
  15. package/dist/lib/linux_aarch64/include/selva/fields.h +10 -2
  16. package/dist/lib/linux_aarch64/include/selva/selva_hash128.h +17 -7
  17. package/dist/lib/linux_aarch64/include/selva/sort.h +21 -14
  18. package/dist/lib/linux_aarch64/libdeflate.so +0 -0
  19. package/dist/lib/linux_aarch64/libjemalloc_selva.so.2 +0 -0
  20. package/dist/lib/linux_aarch64/libnode-v20.node +0 -0
  21. package/dist/lib/linux_aarch64/libnode-v21.node +0 -0
  22. package/dist/lib/linux_aarch64/libnode-v22.node +0 -0
  23. package/dist/lib/linux_aarch64/libnode-v23.node +0 -0
  24. package/dist/lib/linux_aarch64/libselva.so +0 -0
  25. package/dist/lib/linux_x86_64/include/selva/db.h +8 -4
  26. package/dist/lib/linux_x86_64/include/selva/fields.h +10 -2
  27. package/dist/lib/linux_x86_64/include/selva/selva_hash128.h +17 -7
  28. package/dist/lib/linux_x86_64/include/selva/sort.h +21 -14
  29. package/dist/lib/linux_x86_64/libjemalloc_selva.so.2 +0 -0
  30. package/dist/lib/linux_x86_64/libnode-v20.node +0 -0
  31. package/dist/lib/linux_x86_64/libnode-v21.node +0 -0
  32. package/dist/lib/linux_x86_64/libnode-v22.node +0 -0
  33. package/dist/lib/linux_x86_64/libnode-v23.node +0 -0
  34. package/dist/lib/linux_x86_64/libselva.so +0 -0
  35. package/dist/src/client/flushModify.d.ts +1 -1
  36. package/dist/src/client/flushModify.js +15 -19
  37. package/dist/src/client/index.d.ts +8 -10
  38. package/dist/src/client/index.js +19 -8
  39. package/dist/src/client/modify/ModifyRes.d.ts +2 -4
  40. package/dist/src/client/modify/ModifyRes.js +15 -21
  41. package/dist/src/client/modify/create.js +1 -2
  42. package/dist/src/client/modify/delete.js +1 -2
  43. package/dist/src/client/modify/fixed.js +43 -8
  44. package/dist/src/client/modify/modify.js +0 -5
  45. package/dist/src/client/modify/references/{appendRefs.d.ts → appendEdgeRefs.d.ts} +1 -1
  46. package/dist/src/client/modify/references/{appendRefs.js → appendEdgeRefs.js} +5 -2
  47. package/dist/src/client/modify/references/edge.js +182 -175
  48. package/dist/src/client/modify/references/reference.js +4 -8
  49. package/dist/src/client/modify/references/references.js +18 -14
  50. package/dist/src/client/modify/setCursor.js +1 -1
  51. package/dist/src/client/modify/string.js +0 -3
  52. package/dist/src/client/modify/text.js +11 -3
  53. package/dist/src/client/modify/types.d.ts +11 -0
  54. package/dist/src/client/modify/types.js +10 -0
  55. package/dist/src/client/modify/update.js +5 -3
  56. package/dist/src/client/modify/vector.js +13 -4
  57. package/dist/src/client/query/BasedDbQuery.d.ts +1 -1
  58. package/dist/src/client/query/BasedDbQuery.js +2 -2
  59. package/dist/src/client/query/BasedIterable.d.ts +1 -1
  60. package/dist/src/client/query/BasedIterable.js +7 -2
  61. package/dist/src/client/query/filter/createFixedFilterBuffer.d.ts +2 -1
  62. package/dist/src/client/query/filter/createFixedFilterBuffer.js +11 -28
  63. package/dist/src/client/query/filter/createReferenceFilter.d.ts +2 -1
  64. package/dist/src/client/query/filter/createReferenceFilter.js +10 -9
  65. package/dist/src/client/query/filter/createVariableFilterBuffer.d.ts +2 -1
  66. package/dist/src/client/query/filter/createVariableFilterBuffer.js +8 -10
  67. package/dist/src/client/query/filter/parseFilterValue.js +1 -1
  68. package/dist/src/client/query/filter/primitiveFilter.js +9 -9
  69. package/dist/src/client/query/filter/toBuffer.js +0 -15
  70. package/dist/src/client/query/filter/types.d.ts +1 -0
  71. package/dist/src/client/query/filter/types.js +1 -0
  72. package/dist/src/client/query/include/walk.js +0 -1
  73. package/dist/src/client/query/read/read.js +16 -7
  74. package/dist/src/client/query/search/index.js +11 -15
  75. package/dist/src/client/query/subscription/index.d.ts +1 -2
  76. package/dist/src/client/query/subscription/index.js +3 -50
  77. package/dist/src/client/query/subscription/markers.js +1 -2
  78. package/dist/src/client/query/subscription/run.js +0 -2
  79. package/dist/src/client/query/subscription/types.d.ts +1 -29
  80. package/dist/src/client/query/subscription/types.js +8 -1
  81. package/dist/src/client/query/thresholds.d.ts +0 -2
  82. package/dist/src/client/query/thresholds.js +0 -2
  83. package/dist/src/client/query/toBuffer.js +16 -42
  84. package/dist/src/client/query/types.d.ts +3 -2
  85. package/dist/src/client/query/validation.d.ts +1 -3
  86. package/dist/src/client/query/validation.js +6 -18
  87. package/dist/src/client/string.d.ts +2 -0
  88. package/dist/src/client/string.js +10 -14
  89. package/dist/src/index.d.ts +1 -1
  90. package/dist/src/index.js +11 -15
  91. package/dist/src/native.d.ts +3 -3
  92. package/dist/src/native.js +6 -4
  93. package/dist/src/server/csmt/draw-dot.js +2 -2
  94. package/dist/src/server/csmt/tree.js +57 -6
  95. package/dist/src/server/csmt/types.d.ts +5 -0
  96. package/dist/src/server/index.d.ts +4 -3
  97. package/dist/src/server/index.js +44 -44
  98. package/dist/src/server/migrate/index.js +47 -29
  99. package/dist/src/server/migrate/worker.js +2 -2
  100. package/dist/src/server/save.js +40 -28
  101. package/dist/src/server/start.js +7 -19
  102. package/dist/src/server/tree.d.ts +2 -0
  103. package/dist/src/server/tree.js +34 -2
  104. package/dist/src/server/worker.js +3 -3
  105. package/dist/src/utils.d.ts +3 -1
  106. package/dist/src/utils.js +43 -19
  107. package/package.json +9 -3
  108. package/dist/lib/darwin_aarch64/include/selva/base64.h +0 -59
  109. package/dist/lib/darwin_aarch64/include/selva/base64url.h +0 -59
  110. package/dist/lib/linux_aarch64/include/selva/base64.h +0 -59
  111. package/dist/lib/linux_aarch64/include/selva/base64url.h +0 -59
  112. package/dist/lib/linux_x86_64/include/selva/base64.h +0 -59
  113. package/dist/lib/linux_x86_64/include/selva/base64url.h +0 -59
  114. package/dist/src/client/timestamp.d.ts +0 -1
  115. package/dist/src/client/timestamp.js +0 -68
@@ -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
- db.merkleTree = createTree(db.createCsmtHashFun); // TODO This could be somewhere else.
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 (!file) {
43
- // The previous state should remain in the merkle tree for
44
- // load and sync purposes.
45
- return;
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 (!file) {
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
- const data = {
68
- file,
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
- catch (err) {
77
- // console.error({ err })
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}`);
@@ -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 { createTree, hashEq } from './csmt/index.js';
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.log(e.message);
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.log(e.message);
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
- // The merkle tree should be empty at start.
57
- if (!db.merkleTree || db.merkleTree.getRoot()) {
58
- db.merkleTree = createTree(db.createCsmtHashFun);
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>;
@@ -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
- cb(start, end, hash);
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, transferList);
22
+ // transferList[0] = arrayBuf
23
+ channel.postMessage(arrayBuf, [arrayBuf]);
24
24
  }
25
25
  }
26
26
  catch (e) {
@@ -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 { encodeBase64 } from '@saulx/utils';
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.28",
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.9",
41
+ "@based/schema": "5.0.0-alpha.10",
36
42
  "@saulx/hash": "^3.0.0",
37
- "@saulx/utils": "^6.1.1",
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
- }