@based/db 0.2.0 → 0.2.2

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 (28) hide show
  1. package/dist/lib/darwin_aarch64/libnode-v22.node +0 -0
  2. package/dist/lib/darwin_aarch64/libnode-v23.node +0 -0
  3. package/dist/lib/darwin_aarch64/libnode-v24.node +0 -0
  4. package/dist/lib/darwin_aarch64/libnode-v25.node +0 -0
  5. package/dist/lib/darwin_aarch64/libselva.dylib +0 -0
  6. package/dist/lib/linux_aarch64/libnode-v22.node +0 -0
  7. package/dist/lib/linux_aarch64/libnode-v23.node +0 -0
  8. package/dist/lib/linux_aarch64/libnode-v24.node +0 -0
  9. package/dist/lib/linux_aarch64/libnode-v25.node +0 -0
  10. package/dist/lib/linux_aarch64/libselva.so +0 -0
  11. package/dist/lib/linux_x86_64/libnode-v22.node +0 -0
  12. package/dist/lib/linux_x86_64/libnode-v23.node +0 -0
  13. package/dist/lib/linux_x86_64/libnode-v24.node +0 -0
  14. package/dist/lib/linux_x86_64/libnode-v25.node +0 -0
  15. package/dist/lib/linux_x86_64/libselva.so +0 -0
  16. package/dist/src/client/query/filter/convertFilter.js +4 -0
  17. package/dist/src/client/query/filter/createFixedFilterBuffer.js +3 -2
  18. package/dist/src/client/query/filter/createReferenceFilter.js +1 -1
  19. package/dist/src/client/query/filter/createVariableFilterBuffer.js +9 -2
  20. package/dist/src/client/query/include/props.js +1 -1
  21. package/dist/src/client/query/include/toByteCode.js +13 -20
  22. package/dist/src/client/query/queryDef.js +1 -1
  23. package/dist/src/client/query/queryDefToReadSchema.js +1 -2
  24. package/dist/src/client/query/subscription/toByteCode.d.ts +7 -2
  25. package/dist/src/client/query/subscription/toByteCode.js +41 -22
  26. package/dist/src/client/query/types.d.ts +2 -3
  27. package/dist/src/server/subscription.js +23 -9
  28. package/package.json +3 -3
Binary file
Binary file
@@ -42,6 +42,10 @@ export const convertFilter = (query, field, operator, value, opts) => {
42
42
  }
43
43
  if (!(operator === 'exists' || operator === '!exists') &&
44
44
  (value === '' || value === undefined)) {
45
+ if (value === '' && operator === '=') {
46
+ return [[field, toFilterCtx(def, '!exists', opts), undefined]];
47
+ }
48
+ // console.log('DERP!??xxx')
45
49
  // not great...
46
50
  return;
47
51
  }
@@ -59,7 +59,7 @@ export const createFixedFilterBuffer = (prop, size, ctx, value, sort) => {
59
59
  const len = value.length;
60
60
  // Add 8 extra bytes for alignment
61
61
  const buffer = new Uint8Array(18 + len * size);
62
- const result = { buffer };
62
+ const result = { buffer, propDef: prop };
63
63
  buffer[0] = ctx.type;
64
64
  buffer[1] =
65
65
  prop.typeIndex === REFERENCES && ctx.operation === EQUAL
@@ -108,13 +108,14 @@ export const createFixedFilterBuffer = (prop, size, ctx, value, sort) => {
108
108
  if (isNowQuery(prop, value, ctx)) {
109
109
  return {
110
110
  buffer,
111
+ propDef: prop,
111
112
  subscriptionMeta: {
112
113
  now: [createNowMeta(prop, parsedValue, ctx)],
113
114
  },
114
115
  };
115
116
  }
116
117
  else {
117
- return { buffer };
118
+ return { buffer, propDef: prop };
118
119
  }
119
120
  }
120
121
  };
@@ -21,6 +21,6 @@ export const createReferenceFilter = (prop, ctx, value) => {
21
21
  else {
22
22
  writeUint32(buffer, value, 11);
23
23
  }
24
- return { buffer };
24
+ return { buffer, propDef: prop };
25
25
  };
26
26
  //# sourceMappingURL=createReferenceFilter.js.map
@@ -103,7 +103,10 @@ export const createVariableFilterBuffer = (value, prop, ctx, lang) => {
103
103
  for (let i = 0; i < fbLen; i++) {
104
104
  v[v.byteLength - (i + 1)] = val[val.byteLength - (i + 1)];
105
105
  }
106
- parsedCondition = { buffer: writeVarFilter(mode, v, ctx, prop, 0, 0) };
106
+ parsedCondition = {
107
+ buffer: writeVarFilter(mode, v, ctx, prop, 0, 0),
108
+ propDef: prop,
109
+ };
107
110
  }
108
111
  else {
109
112
  parsedCondition = createFixedFilterBuffer(prop, 8, {
@@ -118,12 +121,16 @@ export const createVariableFilterBuffer = (value, prop, ctx, lang) => {
118
121
  if (val instanceof ArrayBuffer) {
119
122
  val = new Uint8Array(val);
120
123
  }
121
- parsedCondition = { buffer: writeVarFilter(mode, val, ctx, prop, 0, 0) };
124
+ parsedCondition = {
125
+ buffer: writeVarFilter(mode, val, ctx, prop, 0, 0),
126
+ propDef: prop,
127
+ };
122
128
  }
123
129
  }
124
130
  else {
125
131
  parsedCondition = {
126
132
  buffer: writeVarFilter(mode, val, ctx, prop, prop.start, prop.len),
133
+ propDef: prop,
127
134
  };
128
135
  }
129
136
  }
@@ -100,7 +100,7 @@ export const includeProp = (def, prop, opts) => {
100
100
  }
101
101
  else {
102
102
  def.include.main.len += prop.len;
103
- def.include.main.include[prop.start] = [0, prop, opts];
103
+ def.include.main.include.set(prop.start, [0, prop, opts]);
104
104
  return true;
105
105
  }
106
106
  }
@@ -2,7 +2,7 @@ import { MICRO_BUFFER, STRING, TEXT, JSON, BINARY } from '@based/schema/def';
2
2
  import { QueryDefType, } from '../types.js';
3
3
  import { walkDefs } from './walk.js';
4
4
  import { langCodesMap } from '@based/schema';
5
- import { writeUint32 } from '@based/utils';
5
+ import { writeUint16, writeUint32 } from '@based/utils';
6
6
  import { getEnd } from './utils.js';
7
7
  const EMPTY_BUFFER = new Uint8Array(0);
8
8
  export const includeToBuffer = (db, def) => {
@@ -24,33 +24,27 @@ export const includeToBuffer = (db, def) => {
24
24
  ? def.target.ref.edgeMainLen
25
25
  : def.schema.mainLen;
26
26
  if (def.include.main.len === len) {
27
- // GET ALL MAIN FIELDS
27
+ // Get all main fields
28
28
  mainBuffer = EMPTY_BUFFER;
29
29
  let i = 2;
30
- for (const key in def.include.main.include) {
31
- const v = def.include.main.include[key];
32
- v[0] = v[1].start;
30
+ for (const value of def.include.main.include.values()) {
31
+ value[0] = value[1].start;
33
32
  i += 4;
34
33
  }
35
34
  }
36
35
  else {
37
- // GET SOME MAIN FIELDS
38
- const size = Object.keys(def.include.main.include).length;
36
+ const size = def.include.main.include.size;
39
37
  mainBuffer = new Uint8Array(size * 4 + 2);
40
- mainBuffer[0] = def.include.main.len;
41
- mainBuffer[1] = def.include.main.len >>> 8;
38
+ writeUint16(mainBuffer, def.include.main.len, 0);
42
39
  let i = 2;
43
40
  let m = 0;
44
- for (const key in def.include.main.include) {
45
- const v = def.include.main.include[key];
46
- mainBuffer[i] = v[1].start;
47
- mainBuffer[i + 1] = v[1].start >>> 8;
48
- const len = v[1].len;
49
- v[0] = m;
50
- mainBuffer[i + 2] = len;
51
- mainBuffer[i + 3] = len >>> 8;
41
+ for (const value of def.include.main.include.values()) {
42
+ const propDef = value[1];
43
+ writeUint16(mainBuffer, propDef.start, i);
44
+ writeUint16(mainBuffer, propDef.len, i + 2);
45
+ value[0] = m;
52
46
  i += 4;
53
- m += len;
47
+ m += propDef.len;
54
48
  }
55
49
  }
56
50
  }
@@ -61,8 +55,7 @@ export const includeToBuffer = (db, def) => {
61
55
  buf[0] = 7 /* includeOp.PARTIAL */;
62
56
  buf[1] = 0; // field name 0
63
57
  buf[2] = MICRO_BUFFER;
64
- buf[3] = mainBuffer.byteLength;
65
- buf[4] = mainBuffer.byteLength >>> 8;
58
+ writeUint16(buf, mainBuffer.byteLength, 3);
66
59
  result.push(buf, mainBuffer);
67
60
  }
68
61
  else {
@@ -17,7 +17,7 @@ const createEmptySharedDef = (skipValidation) => {
17
17
  props: new Map(),
18
18
  main: {
19
19
  len: 0,
20
- include: {},
20
+ include: new Map(),
21
21
  },
22
22
  },
23
23
  aggregate: null,
@@ -129,8 +129,7 @@ export const convertToReaderSchema = (q, locales) => {
129
129
  readerSchema.props[k] = createReaderPropDef(v.def, locales, v.opts);
130
130
  }
131
131
  readerSchema.main.len = q.include.main.len;
132
- for (const k in q.include.main.include) {
133
- const [start, p, opts] = q.include.main.include[k];
132
+ for (const [start, p, opts] of q.include.main.include.values()) {
134
133
  readerSchema.main.props[start] = createReaderPropDef(p, locales, opts);
135
134
  }
136
135
  for (const [k, v] of q.references.entries()) {
@@ -1,6 +1,11 @@
1
1
  import { BasedDbQuery } from '../BasedDbQuery.js';
2
2
  import { FilterMetaNow, QueryDef, QueryDefFilter } from '../types.js';
3
- export declare const collectFilters: (filter: QueryDefFilter, fields?: Set<number>, nowQueries?: FilterMetaNow[]) => FilterMetaNow[];
4
- export declare const collectFields: (def: QueryDef) => Set<number>;
3
+ type Fields = {
4
+ separate: Set<number>;
5
+ main: Set<number>;
6
+ };
7
+ export declare const collectFilters: (filter: QueryDefFilter, fields?: Fields, nowQueries?: FilterMetaNow[]) => FilterMetaNow[];
8
+ export declare const collectFields: (def: QueryDef) => Fields;
5
9
  export declare const collectTypes: (def: QueryDef | QueryDefFilter, types?: Set<number>) => Set<number>;
6
10
  export declare const registerSubscription: (query: BasedDbQuery) => void;
11
+ export {};
@@ -5,10 +5,7 @@ import { QueryType } from '../types.js';
5
5
  import { SubscriptionType } from './types.js';
6
6
  export const collectFilters = (filter, fields, nowQueries = []) => {
7
7
  if (filter.hasSubMeta) {
8
- for (const [prop, conditions] of filter.conditions) {
9
- if (fields) {
10
- fields.add(prop);
11
- }
8
+ for (const [, conditions] of filter.conditions) {
12
9
  for (const condition of conditions) {
13
10
  if (condition.subscriptionMeta) {
14
11
  if (condition.subscriptionMeta.now) {
@@ -18,10 +15,13 @@ export const collectFilters = (filter, fields, nowQueries = []) => {
18
15
  }
19
16
  }
20
17
  }
21
- else {
22
- for (const prop of filter.conditions.keys()) {
23
- if (fields) {
24
- fields.add(prop);
18
+ if (fields) {
19
+ for (const [prop, conditions] of filter.conditions) {
20
+ fields.separate.add(prop);
21
+ if (prop === 0) {
22
+ for (const condition of conditions) {
23
+ fields.main.add(condition.propDef.start);
24
+ }
25
25
  }
26
26
  }
27
27
  }
@@ -32,9 +32,9 @@ export const collectFilters = (filter, fields, nowQueries = []) => {
32
32
  collectFilters(filter.and, fields, nowQueries);
33
33
  }
34
34
  if (filter.references) {
35
- for (const [prop, ref] of filter.references) {
36
- if (fields) {
37
- fields.add(prop);
35
+ for (const ref of filter.references.values()) {
36
+ for (const prop of filter.conditions.keys()) {
37
+ fields.separate.add(prop);
38
38
  }
39
39
  collectFilters(ref, undefined, nowQueries);
40
40
  }
@@ -42,15 +42,22 @@ export const collectFilters = (filter, fields, nowQueries = []) => {
42
42
  return nowQueries;
43
43
  };
44
44
  export const collectFields = (def) => {
45
- const fields = new Set();
45
+ const fields = {
46
+ separate: new Set(),
47
+ main: new Set(),
48
+ };
46
49
  if (def.include.main.len > 0) {
47
- fields.add(0);
50
+ for (const [, propDef] of def.include.main.include.values()) {
51
+ fields.main.add(propDef.start);
52
+ }
53
+ // Add 0
54
+ fields.separate.add(0);
48
55
  }
49
56
  for (const prop of def.include.props.values()) {
50
- fields.add(prop.def.prop);
57
+ fields.separate.add(prop.def.prop);
51
58
  }
52
59
  for (const prop of def.references.keys()) {
53
- fields.add(prop);
60
+ fields.separate.add(prop);
54
61
  }
55
62
  return fields;
56
63
  };
@@ -77,22 +84,31 @@ export const registerSubscription = (query) => {
77
84
  const fields = collectFields(query.def);
78
85
  const typeId = query.def.schema.id;
79
86
  const subId = native.crc32(query.buffer.subarray(ID.id + 4, query.buffer.byteLength - 4));
80
- const headerLen = 16;
87
+ const headerLen = 18;
81
88
  const types = collectTypes(query.def);
82
89
  const nowQueries = collectFilters(query.def.filter, fields);
83
- const buffer = new Uint8Array(headerLen + fields.size + types.size * 2 + nowQueries.length * 16);
90
+ const buffer = new Uint8Array(headerLen +
91
+ fields.separate.size +
92
+ types.size * 2 +
93
+ nowQueries.length * 16 +
94
+ fields.main.size * 2);
84
95
  buffer[0] = SubscriptionType.singleId;
85
96
  writeUint32(buffer, subId, 1);
86
97
  writeUint16(buffer, typeId, 5);
87
98
  writeUint32(buffer, id, 7);
88
- buffer[11] = fields.size;
89
- writeUint16(buffer, types.size, 12);
90
- writeUint16(buffer, nowQueries.length, 14);
99
+ buffer[11] = fields.separate.size;
100
+ writeUint16(buffer, fields.main.size, 12);
101
+ writeUint16(buffer, types.size, 14);
102
+ writeUint16(buffer, nowQueries.length, 16);
91
103
  let i = headerLen;
92
- for (const field of fields) {
104
+ for (const field of fields.separate) {
93
105
  buffer[i] = field;
94
106
  i++;
95
107
  }
108
+ for (const offset of fields.main) {
109
+ writeUint16(buffer, offset, i);
110
+ i += 2;
111
+ }
96
112
  for (const type of types) {
97
113
  writeUint16(buffer, type, i);
98
114
  i += 2;
@@ -110,7 +126,10 @@ export const registerSubscription = (query) => {
110
126
  else {
111
127
  const typeId = query.def.schema.id;
112
128
  const types = collectTypes(query.def);
113
- const nowQueries = collectFilters(query.def.filter, new Set());
129
+ const nowQueries = collectFilters(query.def.filter, {
130
+ separate: new Set(),
131
+ main: new Set(),
132
+ });
114
133
  const typeLen = types.has(typeId) ? types.size - 1 : types.size;
115
134
  const headerLen = 8;
116
135
  const buffer = new Uint8Array(headerLen + typeLen * 2 + nowQueries.length * 16);
@@ -19,9 +19,7 @@ export type IncludeField = {
19
19
  field: string;
20
20
  opts?: IncludeOpts;
21
21
  };
22
- export type MainIncludes = {
23
- [start: string]: [number, PropDef, IncludeOpts];
24
- };
22
+ export type MainIncludes = Map<number, [number, PropDef, IncludeOpts]>;
25
23
  export type IncludeTreeArr = (string | PropDef | IncludeTreeArr)[];
26
24
  export declare enum QueryType {
27
25
  id = 0,
@@ -61,6 +59,7 @@ export type FilterMetaNow = {
61
59
  };
62
60
  export type FilterCondition = {
63
61
  buffer: Uint8Array;
62
+ propDef: PropDef | PropDefEdge;
64
63
  subscriptionMeta?: {
65
64
  now?: FilterMetaNow[];
66
65
  };
@@ -20,8 +20,8 @@ export const startUpdateHandler = (server) => {
20
20
  if (markedIdSubs) {
21
21
  const buffer = new Uint8Array(markedIdSubs);
22
22
  for (let i = 0; i < buffer.byteLength; i += 8) {
23
- const subId = readUint32(buffer, i);
24
- const id = readUint32(buffer, i + 4);
23
+ const id = readUint32(buffer, i);
24
+ const subId = readUint32(buffer, i + 4);
25
25
  const subContainer = server.subscriptions.ids.get(subId);
26
26
  const ids = subContainer.ids.get(id);
27
27
  if (ids) {
@@ -92,11 +92,21 @@ const replaceNowValues = (query, now) => {
92
92
  writeInt64(query, dateNow + offset, byteIndex);
93
93
  }
94
94
  };
95
+ // let total = 0
96
+ // let exectime = 0
97
+ // let int
95
98
  export const registerSubscription = (server, query, sub, onData, onError, subInterval) => {
96
99
  // this can change dynamicly
97
100
  if (subInterval) {
98
101
  server.subscriptions.subInterval = subInterval;
99
102
  }
103
+ // if (!int)
104
+ // int = setInterval(() => {
105
+ // console.log('EXECED', total, exectime / total, 'ms exec time')
106
+ // if (server.stopped) {
107
+ // clearInterval(int)
108
+ // }
109
+ // }, 1e3)
100
110
  let killed = false;
101
111
  // now maybe just once per second? (for now)
102
112
  if (server.subscriptions.active === 0) {
@@ -110,10 +120,13 @@ export const registerSubscription = (server, query, sub, onData, onError, subInt
110
120
  if (now) {
111
121
  replaceNowValues(query, now);
112
122
  }
123
+ let d = Date.now();
113
124
  server.getQueryBuf(query).then((res) => {
114
125
  if (killed) {
115
126
  return;
116
127
  }
128
+ // total++
129
+ // exectime += Date.now() - d
117
130
  if (res.byteLength >= 4) {
118
131
  onData(res);
119
132
  }
@@ -129,30 +142,31 @@ export const registerSubscription = (server, query, sub, onData, onError, subInt
129
142
  });
130
143
  }
131
144
  else {
132
- console.log('Allready fired block');
145
+ // console.log('Allready fired block')
133
146
  }
134
147
  };
135
148
  server.subscriptions.active++;
136
149
  if (sub[0] === SubscriptionType.singleId) {
137
150
  const subId = readUint32(sub, 1);
138
151
  const id = readUint32(sub, 7);
139
- const headerLen = 16;
152
+ const headerLen = 18;
140
153
  let subContainer;
141
154
  let listeners;
142
155
  if (!server.subscriptions.ids.get(subId)) {
143
156
  subContainer = { ids: new Map() };
144
157
  server.subscriptions.ids.set(subId, subContainer);
145
- const typesLen = readUint16(sub, 12);
146
- const nowLen = readUint16(sub, 14);
147
158
  const fLen = sub[11];
159
+ const mainLen = readUint16(sub, 12) * 2;
160
+ const typesLen = readUint16(sub, 14);
161
+ const nowLen = readUint16(sub, 16);
148
162
  if (typesLen != 0) {
149
163
  // double check if this is alignment correct with the byteOffset else copy
150
- const byteOffset = sub.byteOffset + headerLen + fLen;
164
+ const byteOffset = sub.byteOffset + headerLen + fLen + mainLen;
151
165
  if (byteOffset % 2 === 0) {
152
166
  subContainer.types = new Uint16Array(sub.buffer, byteOffset, typesLen);
153
167
  }
154
168
  else {
155
- subContainer.types = new Uint16Array(sub.slice(headerLen + fLen, headerLen + fLen + typesLen * 2));
169
+ subContainer.types = new Uint16Array(sub.slice(headerLen + fLen + mainLen, headerLen + fLen + mainLen + typesLen * 2));
156
170
  }
157
171
  subContainer.typesListener = () => {
158
172
  for (const set of subContainer.ids.values()) {
@@ -171,7 +185,7 @@ export const registerSubscription = (server, query, sub, onData, onError, subInt
171
185
  // and get the date allways (as a seperate query)
172
186
  // when getting the date mark next in line
173
187
  // have to make a copy (subArray is weak)
174
- now = sub.slice(headerLen + fLen + typesLen * 2);
188
+ now = sub.slice(headerLen + fLen + mainLen + typesLen * 2);
175
189
  subContainer.nowListener = () => {
176
190
  // per id want to have a last eval and needs next eval
177
191
  for (const set of subContainer.ids.values()) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@based/db",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
4
4
  "type": "module",
5
5
  "main": "./dist/src/index.js",
6
6
  "scripts": {
@@ -42,9 +42,9 @@
42
42
  ],
43
43
  "dependencies": {
44
44
  "@based/hash": "1.1.0",
45
- "@based/schema": "5.1.0",
45
+ "@based/schema": "5.1.2",
46
46
  "@based/utils": "1.2.0",
47
- "@based/protocol": "0.1.0",
47
+ "@based/protocol": "0.1.2",
48
48
  "exit-hook": "^4.0.0"
49
49
  },
50
50
  "optionalDependencies": {