@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.
Files changed (161) hide show
  1. package/dist/basedDbNative.cjs +23 -0
  2. package/dist/lib/darwin_aarch64/include/cdefs.h +4 -1
  3. package/dist/lib/darwin_aarch64/include/selva/db.h +28 -5
  4. package/dist/lib/darwin_aarch64/include/selva/fast_linear_search.h +2 -2
  5. package/dist/lib/darwin_aarch64/include/selva/fields.h +13 -41
  6. package/dist/lib/darwin_aarch64/include/selva/selva_string.h +4 -0
  7. package/dist/lib/darwin_aarch64/include/selva/types.h +1 -11
  8. package/dist/lib/darwin_aarch64/libdeflate.dylib +0 -0
  9. package/dist/lib/darwin_aarch64/libjemalloc_selva.2.dylib +0 -0
  10. package/dist/lib/darwin_aarch64/libnode-v22.node +0 -0
  11. package/dist/lib/darwin_aarch64/libselva.dylib +0 -0
  12. package/dist/lib/darwin_aarch64/libxxhash.dylib +0 -0
  13. package/dist/src/client/index.d.ts +2 -0
  14. package/dist/src/client/index.js +11 -2
  15. package/dist/src/client/modify/Ctx.d.ts +3 -5
  16. package/dist/src/client/modify/Ctx.js +0 -3
  17. package/dist/src/client/modify/Tmp.d.ts +2 -2
  18. package/dist/src/client/modify/Tmp.js +27 -23
  19. package/dist/src/client/modify/create/index.js +36 -25
  20. package/dist/src/client/modify/cursor.d.ts +0 -1
  21. package/dist/src/client/modify/cursor.js +10 -26
  22. package/dist/src/client/modify/delete/index.js +6 -6
  23. package/dist/src/client/modify/drain.js +20 -23
  24. package/dist/src/client/modify/edges/references.js +3 -2
  25. package/dist/src/client/modify/error.d.ts +2 -1
  26. package/dist/src/client/modify/error.js +2 -2
  27. package/dist/src/client/modify/expire/index.js +5 -6
  28. package/dist/src/client/modify/props/object.js +3 -2
  29. package/dist/src/client/modify/props/reference.js +3 -3
  30. package/dist/src/client/modify/props/references.js +2 -1
  31. package/dist/src/client/modify/types.d.ts +4 -1
  32. package/dist/src/client/modify/types.js +4 -0
  33. package/dist/src/client/modify/update/index.d.ts +3 -0
  34. package/dist/src/client/modify/update/index.js +33 -20
  35. package/dist/src/client/modify/upsert/index.d.ts +2 -1
  36. package/dist/src/client/modify/upsert/index.js +67 -44
  37. package/dist/src/client/query/BasedDbQuery.js +12 -7
  38. package/dist/src/client/query/aggregates/aggregation.d.ts +1 -1
  39. package/dist/src/client/query/aggregates/aggregation.js +24 -3
  40. package/dist/src/client/query/filter/convertFilter.js +16 -3
  41. package/dist/src/client/query/filter/types.d.ts +1 -1
  42. package/dist/src/client/query/include/include.js +2 -5
  43. package/dist/src/client/query/queryDefToReadSchema.js +20 -1
  44. package/dist/src/client/query/search/index.js +9 -1
  45. package/dist/src/client/string.d.ts +1 -1
  46. package/dist/src/client/string.js +1 -1
  47. package/dist/src/hooks.d.ts +3 -6
  48. package/dist/src/hooks.js +5 -12
  49. package/dist/src/index.d.ts +3 -3
  50. package/dist/src/index.js +5 -3
  51. package/dist/src/native.d.ts +4 -3
  52. package/dist/src/native.js +11 -10
  53. package/dist/src/server/blocks.js +1 -1
  54. package/dist/src/server/index.d.ts +3 -2
  55. package/dist/src/server/index.js +23 -47
  56. package/dist/src/server/migrate/index.js +4 -0
  57. package/dist/src/server/resizeModifyDirtyRanges.js +1 -1
  58. package/dist/src/server/save.d.ts +0 -1
  59. package/dist/src/server/save.js +2 -2
  60. package/dist/src/server/schema.js +6 -1
  61. package/dist/src/server/start.js +0 -2
  62. package/dist/src/shared/Emitter.d.ts +1 -1
  63. package/dist/src/utils.d.ts +0 -2
  64. package/dist/src/utils.js +1 -3
  65. package/package.json +17 -7
  66. package/dist/lib/darwin_aarch64/libnode-v23.node +0 -0
  67. package/dist/lib/darwin_aarch64/libnode-v24.node +0 -0
  68. package/dist/lib/linux_aarch64/include/cdefs.h +0 -317
  69. package/dist/lib/linux_aarch64/include/jemalloc.h +0 -468
  70. package/dist/lib/linux_aarch64/include/libdeflate.h +0 -345
  71. package/dist/lib/linux_aarch64/include/libdeflate_strings.h +0 -35
  72. package/dist/lib/linux_aarch64/include/linker_set.h +0 -109
  73. package/dist/lib/linux_aarch64/include/queue.h +0 -627
  74. package/dist/lib/linux_aarch64/include/selva/_export.h +0 -7
  75. package/dist/lib/linux_aarch64/include/selva/align.h +0 -9
  76. package/dist/lib/linux_aarch64/include/selva/backoff_timeout.h +0 -29
  77. package/dist/lib/linux_aarch64/include/selva/bitmap.h +0 -95
  78. package/dist/lib/linux_aarch64/include/selva/colvec.h +0 -71
  79. package/dist/lib/linux_aarch64/include/selva/crc32c.h +0 -17
  80. package/dist/lib/linux_aarch64/include/selva/ctime.h +0 -135
  81. package/dist/lib/linux_aarch64/include/selva/db.h +0 -407
  82. package/dist/lib/linux_aarch64/include/selva/endian.h +0 -301
  83. package/dist/lib/linux_aarch64/include/selva/fast_linear_search.h +0 -27
  84. package/dist/lib/linux_aarch64/include/selva/fast_memcmp.h +0 -18
  85. package/dist/lib/linux_aarch64/include/selva/fast_memmem.h +0 -11
  86. package/dist/lib/linux_aarch64/include/selva/fast_parsei.h +0 -36
  87. package/dist/lib/linux_aarch64/include/selva/fields.h +0 -407
  88. package/dist/lib/linux_aarch64/include/selva/gmtime.h +0 -137
  89. package/dist/lib/linux_aarch64/include/selva/hll.h +0 -85
  90. package/dist/lib/linux_aarch64/include/selva/lpf.h +0 -28
  91. package/dist/lib/linux_aarch64/include/selva/mblen.h +0 -40
  92. package/dist/lib/linux_aarch64/include/selva/membar.h +0 -32
  93. package/dist/lib/linux_aarch64/include/selva/node_id_set.h +0 -43
  94. package/dist/lib/linux_aarch64/include/selva/poptop.h +0 -114
  95. package/dist/lib/linux_aarch64/include/selva/selva_hash128.h +0 -49
  96. package/dist/lib/linux_aarch64/include/selva/selva_lang.h +0 -105
  97. package/dist/lib/linux_aarch64/include/selva/selva_math.h +0 -37
  98. package/dist/lib/linux_aarch64/include/selva/selva_string.h +0 -679
  99. package/dist/lib/linux_aarch64/include/selva/sort.h +0 -140
  100. package/dist/lib/linux_aarch64/include/selva/strsearch.h +0 -43
  101. package/dist/lib/linux_aarch64/include/selva/thread.h +0 -37
  102. package/dist/lib/linux_aarch64/include/selva/timestamp.h +0 -25
  103. package/dist/lib/linux_aarch64/include/selva/types.h +0 -129
  104. package/dist/lib/linux_aarch64/include/selva/vector.h +0 -35
  105. package/dist/lib/linux_aarch64/include/selva_error.h +0 -140
  106. package/dist/lib/linux_aarch64/include/selva_lang_code.h +0 -160
  107. package/dist/lib/linux_aarch64/include/tree.h +0 -852
  108. package/dist/lib/linux_aarch64/libdeflate.so +0 -0
  109. package/dist/lib/linux_aarch64/libjemalloc_selva.so.2 +0 -0
  110. package/dist/lib/linux_aarch64/libnode-v22.node +0 -0
  111. package/dist/lib/linux_aarch64/libnode-v23.node +0 -0
  112. package/dist/lib/linux_aarch64/libnode-v24.node +0 -0
  113. package/dist/lib/linux_aarch64/libselva.so +0 -0
  114. package/dist/lib/linux_aarch64/libxxhash.so.0 +0 -0
  115. package/dist/lib/linux_x86_64/include/cdefs.h +0 -317
  116. package/dist/lib/linux_x86_64/include/jemalloc.h +0 -468
  117. package/dist/lib/linux_x86_64/include/libdeflate.h +0 -345
  118. package/dist/lib/linux_x86_64/include/libdeflate_strings.h +0 -35
  119. package/dist/lib/linux_x86_64/include/linker_set.h +0 -109
  120. package/dist/lib/linux_x86_64/include/queue.h +0 -627
  121. package/dist/lib/linux_x86_64/include/selva/_export.h +0 -7
  122. package/dist/lib/linux_x86_64/include/selva/align.h +0 -9
  123. package/dist/lib/linux_x86_64/include/selva/backoff_timeout.h +0 -29
  124. package/dist/lib/linux_x86_64/include/selva/bitmap.h +0 -95
  125. package/dist/lib/linux_x86_64/include/selva/colvec.h +0 -71
  126. package/dist/lib/linux_x86_64/include/selva/crc32c.h +0 -17
  127. package/dist/lib/linux_x86_64/include/selva/ctime.h +0 -135
  128. package/dist/lib/linux_x86_64/include/selva/db.h +0 -407
  129. package/dist/lib/linux_x86_64/include/selva/endian.h +0 -301
  130. package/dist/lib/linux_x86_64/include/selva/fast_linear_search.h +0 -27
  131. package/dist/lib/linux_x86_64/include/selva/fast_memcmp.h +0 -18
  132. package/dist/lib/linux_x86_64/include/selva/fast_memmem.h +0 -11
  133. package/dist/lib/linux_x86_64/include/selva/fast_parsei.h +0 -36
  134. package/dist/lib/linux_x86_64/include/selva/fields.h +0 -407
  135. package/dist/lib/linux_x86_64/include/selva/gmtime.h +0 -137
  136. package/dist/lib/linux_x86_64/include/selva/hll.h +0 -85
  137. package/dist/lib/linux_x86_64/include/selva/lpf.h +0 -28
  138. package/dist/lib/linux_x86_64/include/selva/mblen.h +0 -40
  139. package/dist/lib/linux_x86_64/include/selva/membar.h +0 -32
  140. package/dist/lib/linux_x86_64/include/selva/node_id_set.h +0 -43
  141. package/dist/lib/linux_x86_64/include/selva/poptop.h +0 -114
  142. package/dist/lib/linux_x86_64/include/selva/selva_hash128.h +0 -49
  143. package/dist/lib/linux_x86_64/include/selva/selva_lang.h +0 -105
  144. package/dist/lib/linux_x86_64/include/selva/selva_math.h +0 -37
  145. package/dist/lib/linux_x86_64/include/selva/selva_string.h +0 -679
  146. package/dist/lib/linux_x86_64/include/selva/sort.h +0 -140
  147. package/dist/lib/linux_x86_64/include/selva/strsearch.h +0 -43
  148. package/dist/lib/linux_x86_64/include/selva/thread.h +0 -37
  149. package/dist/lib/linux_x86_64/include/selva/timestamp.h +0 -25
  150. package/dist/lib/linux_x86_64/include/selva/types.h +0 -129
  151. package/dist/lib/linux_x86_64/include/selva/vector.h +0 -35
  152. package/dist/lib/linux_x86_64/include/selva_error.h +0 -140
  153. package/dist/lib/linux_x86_64/include/selva_lang_code.h +0 -160
  154. package/dist/lib/linux_x86_64/include/tree.h +0 -852
  155. package/dist/lib/linux_x86_64/libdeflate.so +0 -0
  156. package/dist/lib/linux_x86_64/libjemalloc_selva.so.2 +0 -0
  157. package/dist/lib/linux_x86_64/libnode-v22.node +0 -0
  158. package/dist/lib/linux_x86_64/libnode-v23.node +0 -0
  159. package/dist/lib/linux_x86_64/libnode-v24.node +0 -0
  160. package/dist/lib/linux_x86_64/libselva.so +0 -0
  161. 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 = (def, field, StepInput) => {
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
- def.schema.hooks?.aggregate?.(def, new Set(fields));
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 filterHook = def.schema.hooks?.filter;
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
- def.schema.hooks.filter = null;
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
- def.schema.hooks.filter = filterHook;
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"]) => 0 | 1 | 3 | 2;
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[0] == '$'
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?.hooks?.read) {
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 compress: (str: string) => Uint8Array;
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 compress = (str) => {
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);
@@ -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
- offsets: Record<number, number>;
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
- try {
47
- const d = performance.now();
48
- const offsets = server.modify(buf);
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 Promise.resolve(server.getQueryBuf(buf));
53
+ return server.getQueryBuf(buf);
61
54
  },
62
55
  };
63
56
  };
@@ -1,11 +1,10 @@
1
- import { compress } from './client/string.js';
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
- import { decompress } from '@based/protocol/db-read';
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 { compress } from './client/string.js';
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
- import { decompress } from '@based/protocol/db-read';
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
  };
@@ -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, types: Uint8Array, dbCtx: any, dirtyBlocksOut: Float64Array) => any;
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
- updateSchemaType: (prefix: number, buf: Uint8Array, dbCtx: any) => any;
17
- getTypeInfo: (typeId: number, dbCtx: any) => any;
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;
@@ -1,8 +1,6 @@
1
1
  // @ts-ignore
2
- import db from '../../basedDbNative.cjs';
3
- // Can't import these from utils or it would be a cyclic import.
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, types, dbCtx, dirtyBlocksOut) => {
31
- db.modify(data, types, dbCtx, dirtyBlocksOut);
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
- updateSchemaType: (prefix, buf, dbCtx) => {
69
- return db.updateSchema(prefix, buf, dbCtx);
66
+ setSchemaType: (prefix, buf, dbCtx) => {
67
+ return db.setSchemaType(prefix, buf, dbCtx);
70
68
  },
71
- getTypeInfo: (typeId, dbCtx) => {
72
- return db.getTypeInfo(typeId, dbCtx);
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 = def.lastId || native.getTypeInfo(def.id, db.dbCtxExternal)[1];
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, skipParse?: boolean): Record<number, number> | null;
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;
@@ -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, readUint32, readUint64, writeUint32 } from '@based/utils';
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, skipParse) {
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
- this.modifyQueue.push(new Uint8Array(payload));
280
+ return new Promise((resolve) => {
281
+ this.modifyQueue.set(resolve, new Uint8Array(payload));
282
+ });
307
283
  }
308
- else {
309
- resizeModifyDirtyRanges(this);
310
- native.modify(content, offsets, this.dbCtxExternal, this.modifyDirtyRanges);
311
- for (const key of this.modifyDirtyRanges) {
312
- if (key === 0)
313
- break;
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 result;
293
+ return content.subarray(0, len);
318
294
  }
319
295
  #expire() {
320
296
  resizeModifyDirtyRanges(this);
321
- native.modify(emptyUint8Array, emptyUint8Array, this.dbCtxExternal, this.modifyDirtyRanges);
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 === 16777216) {
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.length) {
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.length) {
364
+ if (this.modifyQueue.size) {
389
365
  const modifyQueue = this.modifyQueue;
390
- this.modifyQueue = [];
391
- for (const payload of modifyQueue) {
392
- this.modify(payload, true);
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.lastId;
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);
@@ -9,7 +9,6 @@ export type Writelog = {
9
9
  ts: number;
10
10
  types: {
11
11
  [t: number]: {
12
- lastId: number;
13
12
  blockCapacity: number;
14
13
  };
15
14
  };
@@ -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, lastId, blockCapacity } = db.schemaTypesParsed[key];
42
- types[id] = { lastId, blockCapacity };
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.updateSchemaType(type.id, new Uint8Array(s[i]), server.dbCtxExternal);
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 }));
@@ -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 ||
@@ -1,4 +1,4 @@
1
- import { DbSchema } from "@based/schema";
1
+ import { DbSchema } from '@based/schema';
2
2
  export type EventMap = {
3
3
  schema: DbSchema;
4
4
  info: string;
@@ -1,5 +1,3 @@
1
1
  import { DbServer } from './server/index.js';
2
- export declare const DECODER: TextDecoder;
3
- export declare const ENCODER: TextEncoder;
4
2
  export declare const debugMode: (target: any, getInfo?: any) => void;
5
3
  export declare const debugServer: (server: DbServer) => void;
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.length} q: ${server.queryQueue.size}`);
43
+ export const debugServer = (server) => debugMode(server, () => `p: ${server.activeReaders} m: ${server.modifyQueue.size} q: ${server.queryQueue.size}`);
46
44
  //# sourceMappingURL=utils.js.map