@based/db 0.0.47 → 0.0.49

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 (48) hide show
  1. package/dist/lib/darwin_aarch64/libnode-v20.node +0 -0
  2. package/dist/lib/darwin_aarch64/libnode-v21.node +0 -0
  3. package/dist/lib/darwin_aarch64/libnode-v22.node +0 -0
  4. package/dist/lib/darwin_aarch64/libnode-v23.node +0 -0
  5. package/dist/lib/darwin_aarch64/libnode-v24.node +0 -0
  6. package/dist/lib/darwin_aarch64/libselva.dylib +0 -0
  7. package/dist/lib/linux_aarch64/libnode-v20.node +0 -0
  8. package/dist/lib/linux_aarch64/libnode-v21.node +0 -0
  9. package/dist/lib/linux_aarch64/libnode-v22.node +0 -0
  10. package/dist/lib/linux_aarch64/libnode-v23.node +0 -0
  11. package/dist/lib/linux_aarch64/libnode-v24.node +0 -0
  12. package/dist/lib/linux_aarch64/libselva.so +0 -0
  13. package/dist/lib/linux_x86_64/libnode-v20.node +0 -0
  14. package/dist/lib/linux_x86_64/libnode-v21.node +0 -0
  15. package/dist/lib/linux_x86_64/libnode-v22.node +0 -0
  16. package/dist/lib/linux_x86_64/libnode-v23.node +0 -0
  17. package/dist/lib/linux_x86_64/libnode-v24.node +0 -0
  18. package/dist/lib/linux_x86_64/libselva.so +0 -0
  19. package/dist/src/client/index.js +4 -2
  20. package/dist/src/client/query/BasedDbQuery.js +4 -0
  21. package/dist/src/client/query/display.d.ts +1 -0
  22. package/dist/src/client/query/display.js +10 -4
  23. package/dist/src/client/query/filter/toBuffer.d.ts +1 -0
  24. package/dist/src/client/query/filter/toBuffer.js +11 -0
  25. package/dist/src/client/query/query.d.ts +1 -1
  26. package/dist/src/client/query/query.js +1 -1
  27. package/dist/src/client/query/registerQuery.js +1 -1
  28. package/dist/src/client/query/toByteCode/default.d.ts +2 -0
  29. package/dist/src/client/query/toByteCode/default.js +40 -0
  30. package/dist/src/client/query/toByteCode/toBuffer.d.ts +3 -0
  31. package/dist/src/client/query/{toBuffer.js → toByteCode/toBuffer.js} +10 -34
  32. package/dist/src/hooks.d.ts +16 -0
  33. package/dist/src/hooks.js +47 -0
  34. package/dist/src/index.d.ts +2 -0
  35. package/dist/src/index.js +3 -1
  36. package/dist/src/schema.d.ts +3 -0
  37. package/dist/src/schema.js +94 -0
  38. package/dist/src/server/index.js +16 -49
  39. package/dist/src/server/migrate/index.d.ts +0 -1
  40. package/dist/src/server/migrate/index.js +1 -1
  41. package/dist/src/server/migrate/worker.js +4 -1
  42. package/dist/src/server/start.d.ts +0 -1
  43. package/dist/src/server/start.js +0 -1
  44. package/dist/src/server/worker.js +5 -2
  45. package/dist/src/utils.d.ts +0 -16
  46. package/dist/src/utils.js +0 -93
  47. package/package.json +1 -1
  48. package/dist/src/client/query/toBuffer.d.ts +0 -3
Binary file
Binary file
@@ -10,7 +10,8 @@ import { deleteFn } from './modify/delete.js';
10
10
  import { wait } from '@saulx/utils';
11
11
  import { hash } from '@saulx/hash';
12
12
  import { expire } from './modify/expire.js';
13
- import { debugMode, schemaLooseEqual } from '../utils.js';
13
+ import { debugMode } from '../utils.js';
14
+ import { parseSchema, schemaLooseEqual } from '../schema.js';
14
15
  const makeFlushIsReady = (dbClient) => {
15
16
  dbClient.flushIsReady = new Promise((resolve) => {
16
17
  dbClient.flushReady = () => {
@@ -48,8 +49,9 @@ export class DbClient {
48
49
  schemaPromise;
49
50
  async setSchema(schema, fromStart, transformFns) {
50
51
  const strictSchema = fromStart ? schema : parse(schema).schema;
52
+ const parsedSchema = parseSchema(strictSchema);
51
53
  // this one excludes all the ids
52
- if (schemaLooseEqual(strictSchema, this.schema)) {
54
+ if (schemaLooseEqual(parsedSchema, this.schema)) {
53
55
  return this.schema;
54
56
  }
55
57
  // drain current things
@@ -325,6 +325,10 @@ export class BasedDbQuery extends QueryBranch {
325
325
  const res = await this.db.hooks.getQueryBuf(buf);
326
326
  if (res.byteLength === 1) {
327
327
  if (res[0] === 0) {
328
+ if (this.db.schema?.hash !== this.def.schemaChecksum) {
329
+ this.reBuildQuery();
330
+ return this.#getInternal(resolve, reject);
331
+ }
328
332
  reject(new Error('schema mismatch'));
329
333
  }
330
334
  else {
@@ -3,6 +3,7 @@ import { TypeIndex } from '@based/schema/def';
3
3
  import { BasedQueryResponse } from './BasedIterable.js';
4
4
  export declare const size: (size: number) => string;
5
5
  export declare const time: (time: number) => string;
6
+ export declare const printNumber: (nr: number) => string;
6
7
  export declare const prettyPrintVal: (v: any, type: TypeIndex) => string;
7
8
  export declare const parseUint8Array: (p: any) => any;
8
9
  export declare const safeStringify: (p: any, nr?: number) => string;
@@ -35,6 +35,12 @@ export const time = (time) => {
35
35
  return picocolors.green(str);
36
36
  }
37
37
  };
38
+ export const printNumber = (nr) => {
39
+ if (nr > 1000) {
40
+ return picocolors.blue(nr.toLocaleString());
41
+ }
42
+ return picocolors.blue(nr);
43
+ };
38
44
  export const prettyPrintVal = (v, type) => {
39
45
  if (type === BINARY) {
40
46
  const nr = 12;
@@ -151,12 +157,12 @@ const inspectObject = (object, q, path, level, isLast, isFirst, isObject, depth)
151
157
  else if (!def) {
152
158
  if (typeof v === 'number') {
153
159
  if (q.aggregate) {
154
- str += picocolors.blue(v);
160
+ str += printNumber(v);
155
161
  str += picocolors.italic(picocolors.dim(` ${key.indexOf('count') >= 0 ? ' count' : ' sum'}`));
156
162
  str += ',\n';
157
163
  }
158
164
  else {
159
- str += picocolors.blue(v) + '\n';
165
+ str += printNumber(v) + '\n';
160
166
  }
161
167
  }
162
168
  else {
@@ -212,11 +218,11 @@ const inspectObject = (object, q, path, level, isLast, isFirst, isObject, depth)
212
218
  else {
213
219
  if (typeof v === 'number') {
214
220
  if (q.aggregate) {
215
- str += picocolors.blue(v);
221
+ str += printNumber(v);
216
222
  str += picocolors.italic(picocolors.dim(` ${key.indexOf('count') >= 0 ? ' count' : ' sum'}`));
217
223
  }
218
224
  else {
219
- str += picocolors.blue(v);
225
+ str += printNumber(v);
220
226
  }
221
227
  }
222
228
  else if (typeof v === 'object' && v) {
@@ -1,3 +1,4 @@
1
1
  import { QueryDefFilter } from '../types.js';
2
2
  export declare const fillConditionsBuffer: (result: Uint8Array, conditions: QueryDefFilter, offset: number) => number;
3
+ export declare const isSimpleMainFilter: (conditions: QueryDefFilter) => boolean;
3
4
  export declare const filterToBuffer: (conditions: QueryDefFilter) => Uint8Array;
@@ -81,7 +81,18 @@ export const fillConditionsBuffer = (result, conditions, offset) => {
81
81
  }
82
82
  return lastWritten - offset;
83
83
  };
84
+ export const isSimpleMainFilter = (conditions) => {
85
+ if (!conditions.references &&
86
+ !conditions.edges &&
87
+ conditions.conditions.size === 1 &&
88
+ conditions.conditions.has(0) &&
89
+ !conditions.or) {
90
+ return true;
91
+ }
92
+ return false;
93
+ };
84
94
  export const filterToBuffer = (conditions) => {
95
+ // add extra byte IS SINGLE CONDITION
85
96
  let result;
86
97
  if (conditions.size > 0) {
87
98
  result = new Uint8Array(conditions.size);
@@ -2,7 +2,7 @@ export * from './queryDef.js';
2
2
  export * from './types.js';
3
3
  export * from './include/props.js';
4
4
  export * from './include/toBuffer.js';
5
- export * from './toBuffer.js';
5
+ export * from './toByteCode/toBuffer.js';
6
6
  export * from './filter/filter.js';
7
7
  export * from './filter/toBuffer.js';
8
8
  export * from './sort.js';
@@ -2,7 +2,7 @@ export * from './queryDef.js';
2
2
  export * from './types.js';
3
3
  export * from './include/props.js';
4
4
  export * from './include/toBuffer.js';
5
- export * from './toBuffer.js';
5
+ export * from './toByteCode/toBuffer.js';
6
6
  export * from './filter/filter.js';
7
7
  export * from './filter/toBuffer.js';
8
8
  export * from './sort.js';
@@ -1,6 +1,6 @@
1
1
  import native from '../../native.js';
2
2
  import { concatUint8Arr } from '@saulx/utils';
3
- import { defToBuffer } from './toBuffer.js';
3
+ import { defToBuffer } from './toByteCode/toBuffer.js';
4
4
  import { handleErrors } from './validation.js';
5
5
  export const registerQuery = (q) => {
6
6
  if (!q.id) {
@@ -0,0 +1,2 @@
1
+ import { QueryDef } from '../types.js';
2
+ export declare const defaultQuery: (def: QueryDef, filterSize: number, sortSize: number, searchSize: number, sort: Uint8Array, search: Uint8Array) => Uint8Array;
@@ -0,0 +1,40 @@
1
+ import { filterToBuffer, isSimpleMainFilter } from '../query.js';
2
+ import { QueryType } from '../types.js';
3
+ export const defaultQuery = (def, filterSize, sortSize, searchSize, sort, search) => {
4
+ const buf = new Uint8Array(18 + filterSize + sortSize + searchSize);
5
+ let index = 0;
6
+ buf[index++] = QueryType.default;
7
+ buf[index++] = def.schema.idUint8[0];
8
+ buf[index++] = def.schema.idUint8[1];
9
+ buf[index++] = def.range.offset;
10
+ buf[index++] = def.range.offset >>> 8;
11
+ buf[index++] = def.range.offset >>> 16;
12
+ buf[index++] = def.range.offset >>> 24;
13
+ buf[index++] = def.range.limit;
14
+ buf[index++] = def.range.limit >>> 8;
15
+ buf[index++] = def.range.limit >>> 16;
16
+ buf[index++] = def.range.limit >>> 24;
17
+ buf[index++] = filterSize;
18
+ buf[index++] = filterSize >>> 8;
19
+ buf[index++] = filterSize && isSimpleMainFilter(def.filter) ? 1 : 0;
20
+ // if (filterSize && isSimpleMainFilter(def.filter)) {
21
+ // console.log('SIMPLE FILTER!')
22
+ if (filterSize) {
23
+ buf.set(filterToBuffer(def.filter), index);
24
+ index += filterSize;
25
+ }
26
+ buf[index++] = sortSize;
27
+ buf[index++] = sortSize >>> 8;
28
+ if (sortSize) {
29
+ buf.set(sort, index);
30
+ index += sortSize;
31
+ }
32
+ buf[index++] = searchSize;
33
+ buf[index++] = searchSize >>> 8;
34
+ if (searchSize) {
35
+ buf.set(search, index);
36
+ index += searchSize;
37
+ }
38
+ return buf;
39
+ };
40
+ //# sourceMappingURL=default.js.map
@@ -0,0 +1,3 @@
1
+ import { QueryDef } from '../types.js';
2
+ import { DbClient } from '../../index.js';
3
+ export declare function defToBuffer(db: DbClient, def: QueryDef): Uint8Array[];
@@ -1,10 +1,11 @@
1
- import { createSortBuffer } from './sort.js';
2
- import { QueryDefType, QueryType } from './types.js';
3
- import { includeToBuffer } from './include/toBuffer.js';
4
- import { filterToBuffer } from './query.js';
5
- import { searchToBuffer } from './search/index.js';
1
+ import { createSortBuffer } from '../sort.js';
2
+ import { QueryDefType, QueryType } from '../types.js';
3
+ import { includeToBuffer } from '../include/toBuffer.js';
4
+ import { filterToBuffer } from '../query.js';
5
+ import { searchToBuffer } from '../search/index.js';
6
6
  import { ENCODER, writeUint64 } from '@saulx/utils';
7
- import { aggregateToBuffer, isRootCountOnly } from './aggregates/aggregation.js';
7
+ import { aggregateToBuffer, isRootCountOnly, } from '../aggregates/aggregation.js';
8
+ import { defaultQuery } from './default.js';
8
9
  const byteSize = (arr) => {
9
10
  return arr.reduce((a, b) => {
10
11
  return a + b.byteLength;
@@ -173,6 +174,8 @@ export function defToBuffer(db, def) {
173
174
  buf[idsSize + 12] = def.range.limit >>> 8;
174
175
  buf[idsSize + 13] = def.range.limit >>> 16;
175
176
  buf[idsSize + 14] = def.range.limit >>> 24;
177
+ // if (filterSize && isSimpleMainFilter(def.filter)) {
178
+ // console.log('SIMPLE FILTER!')
176
179
  buf[idsSize + 15] = filterSize;
177
180
  buf[idsSize + 16] = filterSize >>> 8;
178
181
  if (filterSize) {
@@ -193,34 +196,7 @@ export function defToBuffer(db, def) {
193
196
  result.push(buf);
194
197
  }
195
198
  else {
196
- const buf = new Uint8Array(17 + filterSize + sortSize + searchSize);
197
- buf[0] = QueryType.default;
198
- buf[1] = def.schema.idUint8[0];
199
- buf[2] = def.schema.idUint8[1];
200
- buf[3] = def.range.offset;
201
- buf[4] = def.range.offset >>> 8;
202
- buf[5] = def.range.offset >>> 16;
203
- buf[6] = def.range.offset >>> 24;
204
- buf[7] = def.range.limit;
205
- buf[8] = def.range.limit >>> 8;
206
- buf[9] = def.range.limit >>> 16;
207
- buf[10] = def.range.limit >>> 24;
208
- buf[11] = filterSize;
209
- buf[12] = filterSize >>> 8;
210
- if (filterSize) {
211
- buf.set(filterToBuffer(def.filter), 13);
212
- }
213
- buf[13 + filterSize] = sortSize;
214
- buf[14 + filterSize] = sortSize >>> 8;
215
- if (sortSize) {
216
- buf.set(sort, 15 + filterSize);
217
- }
218
- buf[15 + filterSize + sortSize] = searchSize;
219
- buf[16 + filterSize + sortSize] = searchSize >>> 8;
220
- if (searchSize) {
221
- buf.set(search, 17 + filterSize + sortSize);
222
- }
223
- result.push(buf);
199
+ result.push(defaultQuery(def, filterSize, sortSize, searchSize, sort, search));
224
200
  }
225
201
  }
226
202
  }
@@ -0,0 +1,16 @@
1
+ import { StrictSchema } from '@based/schema';
2
+ import { BasedDbQuery } from './client/query/BasedDbQuery.js';
3
+ import { OnError } from './client/query/subscription/types.js';
4
+ import { DbServer } from './server/index.js';
5
+ export declare const getDefaultHooks: (server: DbServer, subInterval?: number) => {
6
+ subscribe(q: BasedDbQuery, onData: (res: Uint8Array) => void, onError: OnError): () => void;
7
+ setSchema(schema: StrictSchema, fromStart: boolean): Promise<StrictSchema & {
8
+ lastId: number;
9
+ hash?: number;
10
+ }>;
11
+ flushModify(buf: Uint8Array): Promise<{
12
+ offsets: Record<number, number>;
13
+ dbWriteTime: number;
14
+ }>;
15
+ getQueryBuf(buf: Uint8Array): Promise<Uint8Array>;
16
+ };
@@ -0,0 +1,47 @@
1
+ export const getDefaultHooks = (server, subInterval = 200) => {
2
+ return {
3
+ subscribe(q, onData, onError) {
4
+ let timer;
5
+ let killed = false;
6
+ const poll = async () => {
7
+ const res = await server.getQueryBuf(q.buffer);
8
+ if (killed) {
9
+ return;
10
+ }
11
+ if (res.byteLength >= 8) {
12
+ onData(res);
13
+ }
14
+ else if (res.byteLength === 1 && res[0] === 0) {
15
+ console.info('schema mismatch, should resolve after update');
16
+ // ignore update and stop polling
17
+ return;
18
+ }
19
+ else {
20
+ onError(new Error('unexpected error'));
21
+ }
22
+ timer = setTimeout(poll, subInterval);
23
+ };
24
+ poll();
25
+ return () => {
26
+ clearTimeout(timer);
27
+ killed = true;
28
+ };
29
+ },
30
+ setSchema(schema, fromStart) {
31
+ return Promise.resolve(server.setSchema(schema, fromStart));
32
+ },
33
+ flushModify(buf) {
34
+ const d = performance.now();
35
+ const offsets = server.modify(buf);
36
+ const dbWriteTime = performance.now() - d;
37
+ return Promise.resolve({
38
+ offsets,
39
+ dbWriteTime,
40
+ });
41
+ },
42
+ getQueryBuf(buf) {
43
+ return Promise.resolve(server.getQueryBuf(buf));
44
+ },
45
+ };
46
+ };
47
+ //# sourceMappingURL=hooks.js.map
@@ -2,6 +2,7 @@ import { compress, decompress } from './client/string.js';
2
2
  import { ModifyCtx } from './client/flushModify.js';
3
3
  import { DbServer } from './server/index.js';
4
4
  import { DbClient } from './client/index.js';
5
+ import { getDefaultHooks } from './hooks.js';
5
6
  export * from './client/modify/modify.js';
6
7
  export { compress, decompress };
7
8
  export { ModifyCtx };
@@ -15,6 +16,7 @@ export * from './client/query/query.js';
15
16
  export * from './client/query/BasedDbQuery.js';
16
17
  export * from './client/query/BasedIterable.js';
17
18
  export * from './server/save.js';
19
+ export { getDefaultHooks };
18
20
  export declare class BasedDb {
19
21
  #private;
20
22
  client: DbClient;
package/dist/src/index.js CHANGED
@@ -3,7 +3,8 @@ import { ModifyCtx } from './client/flushModify.js';
3
3
  import { DbServer } from './server/index.js';
4
4
  import { DbClient } from './client/index.js';
5
5
  import { wait } from '@saulx/utils';
6
- import { debugMode, debugServer, getDefaultHooks } from './utils.js';
6
+ import { debugMode, debugServer } from './utils.js';
7
+ import { getDefaultHooks } from './hooks.js';
7
8
  export * from './client/modify/modify.js';
8
9
  export { compress, decompress };
9
10
  export { ModifyCtx }; // TODO move this somewhere
@@ -17,6 +18,7 @@ export * from './client/query/query.js';
17
18
  export * from './client/query/BasedDbQuery.js';
18
19
  export * from './client/query/BasedIterable.js';
19
20
  export * from './server/save.js';
21
+ export { getDefaultHooks };
20
22
  export class BasedDb {
21
23
  client;
22
24
  server;
@@ -0,0 +1,3 @@
1
+ import { StrictSchema } from '@based/schema';
2
+ export declare const schemaLooseEqual: (a: any, b: any, key?: string) => boolean;
3
+ export declare const parseSchema: (strictSchema: StrictSchema) => StrictSchema;
@@ -0,0 +1,94 @@
1
+ import { getPropType } from '@based/schema';
2
+ const exclude = new Set(['id', 'lastId', 'hash']);
3
+ export const schemaLooseEqual = (a, b, key) => {
4
+ if (a === b) {
5
+ return true;
6
+ }
7
+ const typeofA = typeof a;
8
+ if (typeofA !== 'object') {
9
+ return exclude.has(key);
10
+ }
11
+ const typeofB = typeof b;
12
+ if (typeofA !== typeofB) {
13
+ return exclude.has(key);
14
+ }
15
+ if (a === null || b === null) {
16
+ return false;
17
+ }
18
+ if (a.constructor !== b.constructor) {
19
+ return false;
20
+ }
21
+ if (Array.isArray(a)) {
22
+ let i = a.length;
23
+ if (i !== b.length) {
24
+ return false;
25
+ }
26
+ while (i--) {
27
+ if (!schemaLooseEqual(a[i], b[i])) {
28
+ return false;
29
+ }
30
+ }
31
+ }
32
+ else {
33
+ for (const k in a) {
34
+ if (!schemaLooseEqual(a[k], b[k], k)) {
35
+ return false;
36
+ }
37
+ }
38
+ for (const k in b) {
39
+ if (k in a) {
40
+ continue;
41
+ }
42
+ if (!schemaLooseEqual(a[k], b[k], k)) {
43
+ return false;
44
+ }
45
+ }
46
+ }
47
+ return true;
48
+ };
49
+ export const parseSchema = (strictSchema) => {
50
+ let parsedSchema = strictSchema;
51
+ if (strictSchema.props) {
52
+ parsedSchema = {
53
+ ...strictSchema,
54
+ types: { ...parsedSchema.types },
55
+ };
56
+ const props = { ...strictSchema.props };
57
+ for (const key in props) {
58
+ const prop = props[key];
59
+ const propType = getPropType(prop);
60
+ let refProp;
61
+ if (propType === 'reference') {
62
+ refProp = prop;
63
+ }
64
+ else if (propType === 'references') {
65
+ refProp = prop.items;
66
+ }
67
+ if (refProp) {
68
+ const type = parsedSchema.types[refProp.ref];
69
+ const inverseKey = '_' + key;
70
+ parsedSchema.types[refProp.ref] = {
71
+ ...type,
72
+ props: {
73
+ ...type.props,
74
+ [inverseKey]: {
75
+ items: {
76
+ ref: '_root',
77
+ prop: key,
78
+ },
79
+ },
80
+ },
81
+ };
82
+ refProp.prop = inverseKey;
83
+ }
84
+ }
85
+ // @ts-ignore This creates an internal type to use for root props
86
+ parsedSchema.types._root = {
87
+ id: 1,
88
+ props,
89
+ };
90
+ delete parsedSchema.props;
91
+ }
92
+ return parsedSchema;
93
+ };
94
+ //# sourceMappingURL=schema.js.map
@@ -2,7 +2,7 @@ import native from '../native.js';
2
2
  import createDbHash from './dbHash.js';
3
3
  import { rm, writeFile } from 'node:fs/promises';
4
4
  import { dirname, join } from 'node:path';
5
- import { getPropType, langCodesMap, } from '@based/schema';
5
+ import { langCodesMap } from '@based/schema';
6
6
  import { updateTypeDefs, schemaToSelvaBuffer, } from '@based/schema/def';
7
7
  import { start } from './start.js';
8
8
  import { initCsmt, makeCsmtKey, makeCsmtKeyFromNodeId, } from './tree.js';
@@ -11,8 +11,10 @@ import { Worker, MessageChannel } from 'node:worker_threads';
11
11
  import { fileURLToPath } from 'node:url';
12
12
  import { setTimeout } from 'node:timers/promises';
13
13
  import { migrate } from './migrate/index.js';
14
- import { debugServer, schemaLooseEqual } from '../utils.js';
14
+ import { debugServer } from '../utils.js';
15
15
  import { readUint16, readUint32, readUint64, writeUint64 } from '@saulx/utils';
16
+ import { QueryType } from '../client/query/types.js';
17
+ import { parseSchema, schemaLooseEqual } from '../schema.js';
16
18
  import { hash } from '@saulx/hash';
17
19
  export const SCHEMA_FILE = 'schema.json';
18
20
  export const WRITELOG_FILE = 'writelog.json';
@@ -36,6 +38,7 @@ export class DbWorker {
36
38
  this.channel = port1;
37
39
  this.worker = new Worker(workerPath, {
38
40
  workerData: {
41
+ isDbWorker: true,
39
42
  channel: port2,
40
43
  address,
41
44
  },
@@ -279,64 +282,26 @@ export class DbServer {
279
282
  return sortIndex;
280
283
  }
281
284
  setSchema(strictSchema, fromStart = false, transformFns) {
285
+ const parsedSchema = parseSchema(strictSchema);
282
286
  if (!fromStart && Object.keys(this.schema.types).length > 0) {
283
- if (schemaLooseEqual(strictSchema, this.schema)) {
287
+ if (schemaLooseEqual(parsedSchema, this.schema)) {
284
288
  return this.schema;
285
289
  }
286
290
  return this.migrateSchema(strictSchema, transformFns);
287
291
  }
288
- const { lastId } = this.schema;
289
292
  this.schema = {
290
- lastId,
291
- ...strictSchema,
293
+ lastId: this.schema.lastId,
294
+ ...parsedSchema,
292
295
  };
293
- if (strictSchema.props) {
294
- this.schema.types ??= {};
295
- const props = { ...strictSchema.props };
296
- for (const key in props) {
297
- const prop = props[key];
298
- const propType = getPropType(prop);
299
- let refProp;
300
- if (propType === 'reference') {
301
- refProp = prop;
302
- }
303
- else if (propType === 'references') {
304
- refProp = prop.items;
305
- }
306
- if (refProp) {
307
- const type = this.schema.types[refProp.ref];
308
- const inverseKey = '_' + key;
309
- this.schema.types[refProp.ref] = {
310
- ...type,
311
- props: {
312
- ...type.props,
313
- [inverseKey]: {
314
- items: {
315
- ref: '_root',
316
- prop: key,
317
- },
318
- },
319
- },
320
- };
321
- refProp.prop = inverseKey;
322
- }
323
- }
324
- // @ts-ignore This creates an internal type to use for root props
325
- this.schema.types._root = {
326
- id: 1,
327
- props,
328
- };
329
- delete this.schema.props;
330
- }
331
296
  for (const field in this.schema.types) {
332
297
  if (!('id' in this.schema.types[field])) {
333
298
  this.schema.lastId++;
334
299
  this.schema.types[field].id = this.schema.lastId;
335
300
  }
336
301
  }
302
+ const { hash: _, ...rest } = this.schema;
303
+ this.schema.hash = hash(rest);
337
304
  updateTypeDefs(this.schema, this.schemaTypesParsed, this.schemaTypesParsedById);
338
- const { hash: _, ...schemaWithoutHash } = this.schema;
339
- this.schema.hash = hash(schemaWithoutHash);
340
305
  if (!fromStart) {
341
306
  writeFile(join(this.fileSystemPath, SCHEMA_FILE), JSON.stringify(this.schema)).catch((err) => console.error('!!!', SCHEMA_FILE, err));
342
307
  let types = Object.keys(this.schemaTypesParsed);
@@ -352,7 +317,7 @@ export class DbServer {
352
317
  console.error('Cannot update schema on selva', type.type, err, s[i]);
353
318
  }
354
319
  }
355
- if (strictSchema.props) {
320
+ if (strictSchema.props || strictSchema.types?._root) {
356
321
  // insert a root node
357
322
  // TODO fix this add it in schema at least
358
323
  const data = [2, 1, 0, 0, 0, 1, 9, 1, 0, 0, 0, 7, 1, 0, 1];
@@ -480,10 +445,12 @@ export class DbServer {
480
445
  }
481
446
  else {
482
447
  const queryType = buf[0];
483
- if (queryType == 2) {
484
- const s = 13 + readUint16(buf, 11);
448
+ if (queryType == QueryType.default) {
449
+ // TODO: make a function for this!
450
+ const s = 14 + readUint16(buf, 11);
485
451
  const sortLen = readUint16(buf, s);
486
452
  if (sortLen) {
453
+ // make function for this
487
454
  const typeId = readUint16(buf, 1);
488
455
  const sort = buf.slice(s + 2, s + 2 + sortLen);
489
456
  const field = sort[1];
@@ -1,5 +1,4 @@
1
1
  import { StrictSchema } from '@based/schema';
2
- import './worker.js';
3
2
  import { DbServer } from '../index.js';
4
3
  type TransformFn = (node: Record<string, any>) => Record<string, any> | [string, Record<string, any>];
5
4
  export type TransformFns = Record<string, TransformFn>;
@@ -3,7 +3,6 @@ import { dirname, join } from 'path';
3
3
  import { tmpdir } from 'os';
4
4
  import { Worker, MessageChannel, receiveMessageOnPort, } from 'node:worker_threads';
5
5
  import native from '../../native.js';
6
- import './worker.js';
7
6
  import { destructureCsmtKey, foreachDirtyBlock, specialBlock } from '../tree.js';
8
7
  import { SCHEMA_FILE } from '../index.js';
9
8
  import { fileURLToPath } from 'url';
@@ -58,6 +57,7 @@ export const migrate = async (fromDbServer, toSchema, transform) => {
58
57
  atomics[0] = 1;
59
58
  const worker = new Worker(workerPath, {
60
59
  workerData: {
60
+ isDbMigrateWorker: true,
61
61
  from: fromAddress,
62
62
  to: toAddress,
63
63
  fromSchema,
@@ -6,7 +6,7 @@ import { isTypedArray } from 'node:util/types';
6
6
  if (isMainThread) {
7
7
  console.warn('running worker.ts in mainthread');
8
8
  }
9
- else {
9
+ else if (workerData?.isDbMigrateWorker) {
10
10
  const { from, to, fromSchema, toSchema, channel, atomics, transformFns } = workerData;
11
11
  const fromCtx = native.externalFromInt(from);
12
12
  const toCtx = native.externalFromInt(to);
@@ -114,4 +114,7 @@ else {
114
114
  Atomics.wait(atomics, 0, 0);
115
115
  }
116
116
  }
117
+ else {
118
+ console.info('incorrect worker db migrate');
119
+ }
117
120
  //# sourceMappingURL=worker.js.map
@@ -1,5 +1,4 @@
1
1
  import { DbServer } from './index.js';
2
- import './worker.js';
3
2
  export declare function start(db: DbServer, opts: {
4
3
  clean?: boolean;
5
4
  hosted?: boolean;
@@ -6,7 +6,6 @@ import { hashEq } from './csmt/index.js';
6
6
  import { foreachBlock, initCsmt, makeCsmtKey } from './tree.js';
7
7
  import { availableParallelism } from 'node:os';
8
8
  import exitHook from 'exit-hook';
9
- import './worker.js';
10
9
  import { save } from './save.js';
11
10
  import { DEFAULT_BLOCK_CAPACITY } from '@based/schema/def';
12
11
  import { bufToHex, hexToBuf } from '@saulx/utils';
@@ -1,9 +1,9 @@
1
1
  import { isMainThread, receiveMessageOnPort, workerData, } from 'node:worker_threads';
2
2
  import native from '../native.js';
3
3
  if (isMainThread) {
4
- console.warn('running query worker.ts in mainthread');
4
+ console.warn('running query worker.ts in mainthread - incorrect');
5
5
  }
6
- else {
6
+ else if (workerData?.isDbWorker) {
7
7
  let { address, channel } = workerData;
8
8
  let dbCtx = native.externalFromInt(address);
9
9
  native.workerCtxInit();
@@ -32,4 +32,7 @@ else {
32
32
  handleMsg(msg.message);
33
33
  }
34
34
  }
35
+ else {
36
+ console.info('incorrect worker db query');
37
+ }
35
38
  //# sourceMappingURL=worker.js.map
@@ -1,21 +1,5 @@
1
1
  import { DbServer } from './server/index.js';
2
- import { BasedDbQuery } from './client/query/BasedDbQuery.js';
3
- import { OnError } from './client/query/subscription/types.js';
4
- import { StrictSchema } from '@based/schema';
5
2
  export declare const DECODER: TextDecoder;
6
3
  export declare const ENCODER: TextEncoder;
7
4
  export declare const debugMode: (target: any, getInfo?: any) => void;
8
5
  export declare const debugServer: (server: DbServer) => void;
9
- export declare const schemaLooseEqual: (a: any, b: any, key?: string) => boolean;
10
- export declare const getDefaultHooks: (server: DbServer, subInterval?: number) => {
11
- subscribe(q: BasedDbQuery, onData: (res: Uint8Array) => void, onError: OnError): () => void;
12
- setSchema(schema: StrictSchema, fromStart: boolean): Promise<StrictSchema & {
13
- lastId: number;
14
- hash?: number;
15
- }>;
16
- flushModify(buf: Uint8Array): Promise<{
17
- offsets: Record<number, number>;
18
- dbWriteTime: number;
19
- }>;
20
- getQueryBuf(buf: Uint8Array): Promise<Uint8Array>;
21
- };
package/dist/src/utils.js CHANGED
@@ -43,97 +43,4 @@ export const debugMode = (target, getInfo = null) => {
43
43
  }
44
44
  };
45
45
  export const debugServer = (server) => debugMode(server, () => `p: ${server.processingQueries} m: ${server.modifyQueue.length} q: ${server.queryQueue.size}`);
46
- const exclude = new Set(['id', 'lastId', 'hash']);
47
- export const schemaLooseEqual = (a, b, key) => {
48
- if (a === b) {
49
- return true;
50
- }
51
- const typeofA = typeof a;
52
- if (typeofA !== 'object') {
53
- return exclude.has(key);
54
- }
55
- const typeofB = typeof b;
56
- if (typeofA !== typeofB) {
57
- return exclude.has(key);
58
- }
59
- if (a === null || b === null) {
60
- return false;
61
- }
62
- if (a.constructor !== b.constructor) {
63
- return false;
64
- }
65
- if (Array.isArray(a)) {
66
- let i = a.length;
67
- if (i !== b.length) {
68
- return false;
69
- }
70
- while (i--) {
71
- if (!schemaLooseEqual(a[i], b[i])) {
72
- return false;
73
- }
74
- }
75
- }
76
- else {
77
- for (const k in a) {
78
- if (!schemaLooseEqual(a[k], b[k], k)) {
79
- return false;
80
- }
81
- }
82
- for (const k in b) {
83
- if (k in a) {
84
- continue;
85
- }
86
- if (!schemaLooseEqual(a[k], b[k], k)) {
87
- return false;
88
- }
89
- }
90
- }
91
- return true;
92
- };
93
- export const getDefaultHooks = (server, subInterval = 200) => {
94
- return {
95
- subscribe(q, onData, onError) {
96
- let timer;
97
- let killed = false;
98
- const poll = async () => {
99
- const res = await server.getQueryBuf(q.buffer);
100
- if (killed) {
101
- return;
102
- }
103
- if (res.byteLength >= 8) {
104
- onData(res);
105
- }
106
- else if (res.byteLength === 1 && res[0] === 0) {
107
- console.info('schema mismatch, should resolve after update');
108
- // ignore update and stop polling
109
- return;
110
- }
111
- else {
112
- onError(new Error('unexpected error'));
113
- }
114
- timer = setTimeout(poll, subInterval);
115
- };
116
- poll();
117
- return () => {
118
- clearTimeout(timer);
119
- killed = true;
120
- };
121
- },
122
- setSchema(schema, fromStart) {
123
- return Promise.resolve(server.setSchema(schema, fromStart));
124
- },
125
- flushModify(buf) {
126
- const d = performance.now();
127
- const offsets = server.modify(buf);
128
- const dbWriteTime = performance.now() - d;
129
- return Promise.resolve({
130
- offsets,
131
- dbWriteTime,
132
- });
133
- },
134
- getQueryBuf(buf) {
135
- return Promise.resolve(server.getQueryBuf(buf));
136
- },
137
- };
138
- };
139
46
  //# sourceMappingURL=utils.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@based/db",
3
- "version": "0.0.47",
3
+ "version": "0.0.49",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "main": "./dist/src/index.js",
@@ -1,3 +0,0 @@
1
- import { QueryDef } from './types.js';
2
- import { DbClient } from '../index.js';
3
- export declare function defToBuffer(db: DbClient, def: QueryDef): Uint8Array[];