@based/db 0.2.5 → 0.2.7

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 (123) hide show
  1. package/dist/lib/darwin_aarch64/include/selva/db.h +1 -1
  2. package/dist/lib/darwin_aarch64/include/selva/fields.h +6 -3
  3. package/dist/lib/darwin_aarch64/include/selva/types.h +2 -1
  4. package/dist/lib/darwin_aarch64/libnode-v22.node +0 -0
  5. package/dist/lib/darwin_aarch64/libnode-v23.node +0 -0
  6. package/dist/lib/darwin_aarch64/libnode-v24.node +0 -0
  7. package/dist/lib/darwin_aarch64/libnode-v25.node +0 -0
  8. package/dist/lib/darwin_aarch64/libselva.dylib +0 -0
  9. package/dist/lib/linux_aarch64/include/cdefs.h +324 -0
  10. package/dist/lib/linux_aarch64/include/jemalloc.h +468 -0
  11. package/dist/lib/linux_aarch64/include/libdeflate.h +345 -0
  12. package/dist/lib/linux_aarch64/include/libdeflate_strings.h +35 -0
  13. package/dist/lib/linux_aarch64/include/linker_set.h +109 -0
  14. package/dist/lib/linux_aarch64/include/queue.h +627 -0
  15. package/dist/lib/linux_aarch64/include/selva/_export.h +7 -0
  16. package/dist/lib/linux_aarch64/include/selva/align.h +9 -0
  17. package/dist/lib/linux_aarch64/include/selva/backoff_timeout.h +29 -0
  18. package/dist/lib/linux_aarch64/include/selva/bitmap.h +95 -0
  19. package/dist/lib/linux_aarch64/include/selva/colvec.h +71 -0
  20. package/dist/lib/linux_aarch64/include/selva/crc32c.h +17 -0
  21. package/dist/lib/linux_aarch64/include/selva/ctime.h +135 -0
  22. package/dist/lib/linux_aarch64/include/selva/db.h +450 -0
  23. package/dist/lib/linux_aarch64/include/selva/endian.h +301 -0
  24. package/dist/lib/linux_aarch64/include/selva/fast_linear_search.h +27 -0
  25. package/dist/lib/linux_aarch64/include/selva/fast_memcmp.h +18 -0
  26. package/dist/lib/linux_aarch64/include/selva/fast_memmem.h +11 -0
  27. package/dist/lib/linux_aarch64/include/selva/fast_parsei.h +36 -0
  28. package/dist/lib/linux_aarch64/include/selva/fields.h +344 -0
  29. package/dist/lib/linux_aarch64/include/selva/gmtime.h +137 -0
  30. package/dist/lib/linux_aarch64/include/selva/hll.h +85 -0
  31. package/dist/lib/linux_aarch64/include/selva/lpf.h +28 -0
  32. package/dist/lib/linux_aarch64/include/selva/mblen.h +40 -0
  33. package/dist/lib/linux_aarch64/include/selva/membar.h +32 -0
  34. package/dist/lib/linux_aarch64/include/selva/node_id_set.h +43 -0
  35. package/dist/lib/linux_aarch64/include/selva/poptop.h +114 -0
  36. package/dist/lib/linux_aarch64/include/selva/selva_hash128.h +49 -0
  37. package/dist/lib/linux_aarch64/include/selva/selva_lang.h +112 -0
  38. package/dist/lib/linux_aarch64/include/selva/selva_math.h +37 -0
  39. package/dist/lib/linux_aarch64/include/selva/selva_string.h +683 -0
  40. package/dist/lib/linux_aarch64/include/selva/sort.h +140 -0
  41. package/dist/lib/linux_aarch64/include/selva/strsearch.h +43 -0
  42. package/dist/lib/linux_aarch64/include/selva/thread.h +37 -0
  43. package/dist/lib/linux_aarch64/include/selva/timestamp.h +25 -0
  44. package/dist/lib/linux_aarch64/include/selva/types.h +116 -0
  45. package/dist/lib/linux_aarch64/include/selva/vector.h +35 -0
  46. package/dist/lib/linux_aarch64/include/selva_error.h +140 -0
  47. package/dist/lib/linux_aarch64/include/selva_lang_code.h +160 -0
  48. package/dist/lib/linux_aarch64/include/tree.h +852 -0
  49. package/dist/lib/linux_aarch64/libdeflate.so +0 -0
  50. package/dist/lib/linux_aarch64/libjemalloc_selva.so.2 +0 -0
  51. package/dist/lib/linux_aarch64/libnode-v22.node +0 -0
  52. package/dist/lib/linux_aarch64/libnode-v23.node +0 -0
  53. package/dist/lib/linux_aarch64/libnode-v24.node +0 -0
  54. package/dist/lib/linux_aarch64/libnode-v25.node +0 -0
  55. package/dist/lib/linux_aarch64/libselva.so +0 -0
  56. package/dist/lib/linux_aarch64/libxxhash.so.0 +0 -0
  57. package/dist/lib/linux_x86_64/include/cdefs.h +324 -0
  58. package/dist/lib/linux_x86_64/include/jemalloc.h +468 -0
  59. package/dist/lib/linux_x86_64/include/libdeflate.h +345 -0
  60. package/dist/lib/linux_x86_64/include/libdeflate_strings.h +35 -0
  61. package/dist/lib/linux_x86_64/include/linker_set.h +109 -0
  62. package/dist/lib/linux_x86_64/include/queue.h +627 -0
  63. package/dist/lib/linux_x86_64/include/selva/_export.h +7 -0
  64. package/dist/lib/linux_x86_64/include/selva/align.h +9 -0
  65. package/dist/lib/linux_x86_64/include/selva/backoff_timeout.h +29 -0
  66. package/dist/lib/linux_x86_64/include/selva/bitmap.h +95 -0
  67. package/dist/lib/linux_x86_64/include/selva/colvec.h +71 -0
  68. package/dist/lib/linux_x86_64/include/selva/crc32c.h +17 -0
  69. package/dist/lib/linux_x86_64/include/selva/ctime.h +135 -0
  70. package/dist/lib/linux_x86_64/include/selva/db.h +450 -0
  71. package/dist/lib/linux_x86_64/include/selva/endian.h +301 -0
  72. package/dist/lib/linux_x86_64/include/selva/fast_linear_search.h +27 -0
  73. package/dist/lib/linux_x86_64/include/selva/fast_memcmp.h +18 -0
  74. package/dist/lib/linux_x86_64/include/selva/fast_memmem.h +11 -0
  75. package/dist/lib/linux_x86_64/include/selva/fast_parsei.h +36 -0
  76. package/dist/lib/linux_x86_64/include/selva/fields.h +344 -0
  77. package/dist/lib/linux_x86_64/include/selva/gmtime.h +137 -0
  78. package/dist/lib/linux_x86_64/include/selva/hll.h +85 -0
  79. package/dist/lib/linux_x86_64/include/selva/lpf.h +28 -0
  80. package/dist/lib/linux_x86_64/include/selva/mblen.h +40 -0
  81. package/dist/lib/linux_x86_64/include/selva/membar.h +32 -0
  82. package/dist/lib/linux_x86_64/include/selva/node_id_set.h +43 -0
  83. package/dist/lib/linux_x86_64/include/selva/poptop.h +114 -0
  84. package/dist/lib/linux_x86_64/include/selva/selva_hash128.h +49 -0
  85. package/dist/lib/linux_x86_64/include/selva/selva_lang.h +112 -0
  86. package/dist/lib/linux_x86_64/include/selva/selva_math.h +37 -0
  87. package/dist/lib/linux_x86_64/include/selva/selva_string.h +683 -0
  88. package/dist/lib/linux_x86_64/include/selva/sort.h +140 -0
  89. package/dist/lib/linux_x86_64/include/selva/strsearch.h +43 -0
  90. package/dist/lib/linux_x86_64/include/selva/thread.h +37 -0
  91. package/dist/lib/linux_x86_64/include/selva/timestamp.h +25 -0
  92. package/dist/lib/linux_x86_64/include/selva/types.h +116 -0
  93. package/dist/lib/linux_x86_64/include/selva/vector.h +35 -0
  94. package/dist/lib/linux_x86_64/include/selva_error.h +140 -0
  95. package/dist/lib/linux_x86_64/include/selva_lang_code.h +160 -0
  96. package/dist/lib/linux_x86_64/include/tree.h +852 -0
  97. package/dist/lib/linux_x86_64/libdeflate.so +0 -0
  98. package/dist/lib/linux_x86_64/libjemalloc_selva.so.2 +0 -0
  99. package/dist/lib/linux_x86_64/libnode-v22.node +0 -0
  100. package/dist/lib/linux_x86_64/libnode-v23.node +0 -0
  101. package/dist/lib/linux_x86_64/libnode-v24.node +0 -0
  102. package/dist/lib/linux_x86_64/libnode-v25.node +0 -0
  103. package/dist/lib/linux_x86_64/libselva.so +0 -0
  104. package/dist/lib/linux_x86_64/libxxhash.so.0 +0 -0
  105. package/dist/src/client/modify/props/fixed.js +1 -1
  106. package/dist/src/client/modify/types.d.ts +1 -0
  107. package/dist/src/client/modify/types.js +1 -0
  108. package/dist/src/client/query/BasedDbQuery.d.ts +1 -0
  109. package/dist/src/client/query/BasedDbQuery.js +14 -0
  110. package/dist/src/client/query/BasedQueryResponse.js +1 -1
  111. package/dist/src/client/query/filter/filter.js +26 -17
  112. package/dist/src/client/query/filter/toByteCode.js +18 -9
  113. package/dist/src/client/query/include/utils.d.ts +2 -2
  114. package/dist/src/client/query/include/utils.js +7 -6
  115. package/dist/src/client/query/include/walk.js +20 -2
  116. package/dist/src/client/query/queryDefToReadSchema.js +1 -1
  117. package/dist/src/client/query/subscription/index.js +6 -6
  118. package/dist/src/client/query/subscription/toByteCode.js +11 -6
  119. package/dist/src/client/query/types.d.ts +17 -1
  120. package/dist/src/client/query/types.js +23 -0
  121. package/dist/src/server/schemaSelvaBuffer.js +8 -11
  122. package/dist/src/server/subscription.js +0 -12
  123. package/package.json +7 -7
@@ -38,7 +38,7 @@ map[ENUM] = (ctx, val, def) => {
38
38
  validate(val, def);
39
39
  if (val === null) {
40
40
  reserve(ctx, 1);
41
- writeU8(ctx, def.default);
41
+ writeU8(ctx, def.reverseEnum[def.default] + 1);
42
42
  }
43
43
  else if (val in def.reverseEnum) {
44
44
  reserve(ctx, 1);
@@ -19,6 +19,7 @@ export declare const SWITCH_ID_CREATE = 9;
19
19
  export declare const SWITCH_ID_CREATE_RING = 19;
20
20
  export declare const SWITCH_ID_CREATE_UNSAFE = 8;
21
21
  export declare const SWITCH_ID_UPDATE = 1;
22
+ export declare const SWITCH_EDGE_ID = 20;
22
23
  export declare const UPSERT = 17;
23
24
  export declare const INSERT = 18;
24
25
  export type ModifyOp = typeof CREATE | typeof UPDATE | typeof INCREMENT | typeof EXPIRE;
@@ -18,6 +18,7 @@ export const SWITCH_ID_CREATE = 9;
18
18
  export const SWITCH_ID_CREATE_RING = 19;
19
19
  export const SWITCH_ID_CREATE_UNSAFE = 8;
20
20
  export const SWITCH_ID_UPDATE = 1;
21
+ export const SWITCH_EDGE_ID = 20;
21
22
  export const UPSERT = 17;
22
23
  export const INSERT = 18;
23
24
  export const MOD_OPS_TO_STRING = {
@@ -51,6 +51,7 @@ export declare class BasedDbQuery extends QueryBranch<BasedDbQuery> {
51
51
  target: QueryTarget;
52
52
  readSchema: ReaderSchema;
53
53
  constructor(db: DbClient, type: string, rawTarget?: QueryByAliasObj | number | Promise<number> | Uint32Array | (QueryByAliasObj | number)[], skipValidation?: boolean);
54
+ at(index: number): BasedDbQuery;
54
55
  reset(): void;
55
56
  get(): GetPromise;
56
57
  buffer?: Uint8Array;
@@ -419,6 +419,20 @@ export class BasedDbQuery extends QueryBranch {
419
419
  this.queryCommands = [];
420
420
  this.target = target;
421
421
  }
422
+ at(index) {
423
+ if (this.queryCommands) {
424
+ this.queryCommands.push({
425
+ method: 'at',
426
+ args: [index],
427
+ });
428
+ }
429
+ else {
430
+ this.def.selectFirstResult = true;
431
+ this.def.range.limit = 1;
432
+ this.def.range.offset = index;
433
+ }
434
+ return this;
435
+ }
422
436
  reset() {
423
437
  this.subscriptionBuffer = undefined;
424
438
  this.buffer = undefined;
@@ -26,7 +26,7 @@ export class BasedQueryResponse {
26
26
  return this.result.length;
27
27
  }
28
28
  [inspect.custom](depth) {
29
- const hasId = defHasId(this.def);
29
+ const hasId = defHasId(this.def) || this.def.selectFirstResult;
30
30
  const target = displayTarget(this.def);
31
31
  let str = '';
32
32
  str += '\n execTime: ' + time(this.execTime);
@@ -1,3 +1,4 @@
1
+ import { getReferenceSelect, ReferenceSelect, } from '../types.js';
1
2
  import { isPropDef, ID_FIELD_DEF, TEXT, REFERENCE, REFERENCES, } from '@based/schema/def';
2
3
  import { primitiveFilter } from './primitiveFilter.js';
3
4
  import { IsFilter } from './types.js';
@@ -8,11 +9,16 @@ const referencesFilter = (db, filter, schema, conditions, def) => {
8
9
  var size = 0;
9
10
  const path = fieldStr.split('.');
10
11
  let t = schema.tree;
12
+ let referencesSelect;
11
13
  for (let i = 0; i < path.length; i++) {
12
14
  const p = path[i];
13
15
  t = t[p];
14
16
  if (!t) {
15
- if (p[0] === '$') {
17
+ referencesSelect = getReferenceSelect(p, def);
18
+ if (referencesSelect) {
19
+ t = referencesSelect.prop;
20
+ }
21
+ else if (p[0] === '$') {
16
22
  let edges = conditions.fromRef && conditions.fromRef.edges;
17
23
  if (!edges && 'propDef' in def.target) {
18
24
  edges = def.target.propDef.edges;
@@ -34,31 +40,34 @@ const referencesFilter = (db, filter, schema, conditions, def) => {
34
40
  filterFieldDoesNotExist(def, fieldStr);
35
41
  return 0;
36
42
  }
37
- return size;
38
- }
39
- if (isPropDef(t) && t.typeIndex === REFERENCES) {
40
- console.info('REFERENCES NESTED NOT IMPLEMENTED');
41
- conditions.references ??= new Map();
42
- return 0;
43
+ if (!t) {
44
+ return size;
45
+ }
43
46
  }
44
- else if (isPropDef(t) && t.typeIndex === REFERENCE) {
47
+ if (isPropDef(t) &&
48
+ (t.typeIndex === REFERENCE || t.typeIndex === REFERENCES)) {
45
49
  conditions.references ??= new Map();
46
50
  let refConditions = conditions.references.get(t.prop);
47
51
  if (!refConditions) {
48
52
  const schema = db.schemaTypesParsed[t.inverseTypeName];
49
- size += 6;
53
+ size += t.typeIndex === REFERENCES ? 11 : 6;
50
54
  refConditions = {
51
- conditions: new Map(),
52
- fromRef: t,
53
- schema,
54
- size: 0,
55
- hasSubMeta: false,
55
+ conditions: {
56
+ conditions: new Map(),
57
+ fromRef: t,
58
+ schema,
59
+ size: 0,
60
+ hasSubMeta: false,
61
+ },
62
+ select: referencesSelect || {
63
+ type: ReferenceSelect.Any,
64
+ prop: t,
65
+ },
56
66
  };
57
67
  conditions.references.set(t.prop, refConditions);
58
68
  }
59
- // more nested
60
- size += filterRaw(db, [path.slice(i + 1).join('.'), ctx, value], refConditions.schema, refConditions, def);
61
- if (refConditions.hasSubMeta) {
69
+ size += filterRaw(db, [path.slice(i + 1).join('.'), ctx, value], refConditions.conditions.schema, refConditions.conditions, def);
70
+ if (refConditions.conditions.hasSubMeta) {
62
71
  conditions.hasSubMeta = true;
63
72
  }
64
73
  return size;
@@ -1,5 +1,6 @@
1
- import { writeUint16, writeUint32 } from '@based/utils';
2
- import { META_EDGE, META_EXISTS, META_OR_BRANCH, META_REFERENCE, TYPE_DEFAULT, TYPE_NEGATE, } from './types.js';
1
+ import { writeInt32, writeUint16, writeUint32 } from '@based/utils';
2
+ import { META_EDGE, META_EXISTS, META_OR_BRANCH, META_REFERENCE, META_REFERENCES, TYPE_DEFAULT, TYPE_NEGATE, } from './types.js';
3
+ import { REFERENCES } from '@based/schema/prop-types';
3
4
  const writeConditions = (result, k, offset, conditions, metaOffset) => {
4
5
  let lastWritten = offset;
5
6
  result[lastWritten] = k;
@@ -37,15 +38,23 @@ export const fillConditionsBuffer = (result, conditions, offset, metaOffset) =>
37
38
  });
38
39
  if (conditions.references) {
39
40
  for (const [refField, refConditions] of conditions.references) {
40
- result[lastWritten] = META_REFERENCE;
41
- lastWritten++;
41
+ const isReferences = refConditions.select.prop.typeIndex === REFERENCES;
42
+ result[lastWritten] = isReferences ? META_REFERENCES : META_REFERENCE;
43
+ lastWritten += 1;
42
44
  result[lastWritten] = refField;
43
- lastWritten++;
44
- writeUint16(result, refConditions.schema.id, lastWritten);
45
+ lastWritten += 1;
46
+ writeUint16(result, refConditions.conditions.schema.id, lastWritten);
45
47
  lastWritten += 2;
48
+ if (isReferences) {
49
+ result[lastWritten] = refConditions.select.type;
50
+ lastWritten += 1;
51
+ writeInt32(result, refConditions.select.index ?? 0, lastWritten);
52
+ lastWritten += 4;
53
+ // 13
54
+ }
46
55
  const sizeIndex = lastWritten;
47
56
  lastWritten += 2;
48
- const size = fillConditionsBuffer(result, refConditions, lastWritten, metaOffset);
57
+ const size = fillConditionsBuffer(result, refConditions.conditions, lastWritten, metaOffset);
49
58
  writeUint16(result, size, sizeIndex);
50
59
  lastWritten += size;
51
60
  }
@@ -53,7 +62,7 @@ export const fillConditionsBuffer = (result, conditions, offset, metaOffset) =>
53
62
  if (conditions.edges) {
54
63
  conditions.edges.forEach((v, k) => {
55
64
  result[lastWritten] = META_EDGE;
56
- lastWritten++;
65
+ lastWritten += 1;
57
66
  let sizeIndex = lastWritten;
58
67
  lastWritten += 2;
59
68
  const size = writeConditions(result, k, lastWritten, v, metaOffset);
@@ -127,7 +136,7 @@ export const resolveMetaIndexes = (defFilter, offset) => {
127
136
  }
128
137
  if (defFilter.references) {
129
138
  for (const ref of defFilter.references.values()) {
130
- resolveMetaIndexes(ref, offset);
139
+ resolveMetaIndexes(ref.conditions, offset);
131
140
  }
132
141
  }
133
142
  };
@@ -1,8 +1,8 @@
1
1
  import { PropDef, PropDefEdge, SchemaPropTree } from '@based/schema/def';
2
2
  import { DbClient } from '../../index.js';
3
- import { IncludeOpts, QueryDef } from '../types.js';
3
+ import { IncludeOpts, QueryDef, ReferenceSelectValue } from '../types.js';
4
4
  import { LangCode } from '@based/schema';
5
5
  export declare const getAllFieldFromObject: (tree: SchemaPropTree | PropDef, arr?: string[]) => string[];
6
- export declare const createOrGetRefQueryDef: (db: DbClient, def: QueryDef, t: PropDef | PropDefEdge) => QueryDef;
6
+ export declare const createOrGetRefQueryDef: (db: DbClient, def: QueryDef, t: PropDef | PropDefEdge, refSelect?: ReferenceSelectValue) => QueryDef;
7
7
  export declare const createOrGetEdgeRefQueryDef: (db: DbClient, def: QueryDef, t: PropDefEdge) => QueryDef;
8
8
  export declare const getEnd: (opts?: IncludeOpts, lang?: LangCode) => number;
@@ -1,6 +1,6 @@
1
1
  import { REFERENCE, } from '@based/schema/def';
2
2
  import { createQueryDef } from '../queryDef.js';
3
- import { QueryDefType } from '../types.js';
3
+ import { QueryDefType, } from '../types.js';
4
4
  import { inverseLangMap } from '@based/schema';
5
5
  export const getAllFieldFromObject = (tree, arr = []) => {
6
6
  for (const key in tree) {
@@ -14,7 +14,7 @@ export const getAllFieldFromObject = (tree, arr = []) => {
14
14
  }
15
15
  return arr;
16
16
  };
17
- const createRefQueryDef = (db, def, t) => {
17
+ const createRefQueryDef = (db, def, t, refSelect) => {
18
18
  const defRef = createQueryDef(db, t.typeIndex === REFERENCE
19
19
  ? QueryDefType.Reference
20
20
  : QueryDefType.References, {
@@ -25,11 +25,12 @@ const createRefQueryDef = (db, def, t) => {
25
25
  def.references.set(t.prop, defRef);
26
26
  return defRef;
27
27
  };
28
- export const createOrGetRefQueryDef = (db, def, t) => {
29
- if (!def.references.has(t.prop)) {
30
- return createRefQueryDef(db, def, t);
28
+ export const createOrGetRefQueryDef = (db, def, t, refSelect) => {
29
+ let refDef = def.references.get(t.prop);
30
+ if (!refDef) {
31
+ refDef = createRefQueryDef(db, def, t, refSelect);
31
32
  }
32
- return def.references.get(t.prop);
33
+ return refDef;
33
34
  };
34
35
  export const createOrGetEdgeRefQueryDef = (db, def, t) => {
35
36
  def.edges ??= createQueryDef(db, QueryDefType.Edge, {
@@ -1,6 +1,6 @@
1
1
  import { isPropDef, REFERENCE, REFERENCES, TEXT, } from '@based/schema/def';
2
2
  import { createQueryDef } from '../queryDef.js';
3
- import { isRefDef, QueryDefType } from '../types.js';
3
+ import { getReferenceSelect, isRefDef, QueryDefType, } from '../types.js';
4
4
  import { getAllFieldFromObject, createOrGetRefQueryDef } from './utils.js';
5
5
  import { includeProp, includeAllProps, includeField } from './props.js';
6
6
  import { langCodesMap } from '@based/schema';
@@ -8,11 +8,29 @@ import { includeDoesNotExist, includeLangDoesNotExist } from '../validation.js';
8
8
  export const walkDefs = (db, def, include) => {
9
9
  const prop = def.props[include.field];
10
10
  const path = include.field.split('.');
11
+ let referencesSelect;
11
12
  if (!prop) {
12
13
  let t = def.schema.tree;
13
14
  for (let i = 0; i < path.length; i++) {
14
15
  let p = path[i];
15
- if (isRefDef(def) && p[0] == '$') {
16
+ referencesSelect = getReferenceSelect(p, def);
17
+ if (referencesSelect) {
18
+ const refDef = createOrGetRefQueryDef(db, def, referencesSelect.prop);
19
+ if (referencesSelect.index > -1) {
20
+ refDef.range.limit = 1;
21
+ refDef.range.offset = referencesSelect.index;
22
+ }
23
+ // range at the end (start at end)
24
+ const f = path.slice(i + 1).join('.');
25
+ if (!f) {
26
+ includeAllProps(refDef, include.opts);
27
+ }
28
+ else if (!includeProp(refDef, refDef.props[f], include.opts)) {
29
+ includeField(refDef, { field: f, opts: include.opts });
30
+ }
31
+ return;
32
+ }
33
+ else if (isRefDef(def) && p[0] == '$') {
16
34
  if (!def.edges) {
17
35
  def.edges = createQueryDef(db, QueryDefType.Edge, {
18
36
  ref: def.target.propDef,
@@ -57,7 +57,7 @@ export const convertToReaderSchema = (q, locales) => {
57
57
  }
58
58
  const t = q.type;
59
59
  const isRoot = t === 4; // QueryDefType.Root (cant import type enum ofc)
60
- const isSingle = isRoot && ('id' in q.target || 'alias' in q.target);
60
+ const isSingle = (isRoot && ('id' in q.target || 'alias' in q.target)) || q.selectFirstResult;
61
61
  const isEdge = t === 1; // QueryDefType.Edge (cant import type enum ofc)
62
62
  const readerSchema = {
63
63
  readId: 0,
@@ -1,8 +1,6 @@
1
1
  import { BasedQueryResponse } from '../BasedQueryResponse.js';
2
2
  import { registerQuery } from '../registerQuery.js';
3
3
  import { registerSubscription } from './toByteCode.js';
4
- // exec
5
- // subscription thing
6
4
  export class SubStore {
7
5
  listeners;
8
6
  onClose;
@@ -88,10 +86,12 @@ export const subscribe = (q, onData, onError) => {
88
86
  }
89
87
  return () => {
90
88
  const store = q.db.subs.get(q);
91
- store.listeners.delete(onData);
92
- if (!store.listeners.size) {
93
- q.db.subs.delete(q);
94
- store.onClose();
89
+ if (store) {
90
+ store.listeners.delete(onData);
91
+ if (!store.listeners.size) {
92
+ q.db.subs.delete(q);
93
+ store.onClose();
94
+ }
95
95
  }
96
96
  };
97
97
  };
@@ -36,7 +36,7 @@ export const collectFilters = (filter, fields, nowQueries = []) => {
36
36
  for (const prop of filter.conditions.keys()) {
37
37
  fields.separate.add(prop);
38
38
  }
39
- collectFilters(ref, undefined, nowQueries);
39
+ collectFilters(ref.conditions, undefined, nowQueries);
40
40
  }
41
41
  }
42
42
  return nowQueries;
@@ -64,15 +64,20 @@ export const collectFields = (def) => {
64
64
  export const collectTypes = (def, types = new Set()) => {
65
65
  if ('references' in def) {
66
66
  for (const ref of def.references.values()) {
67
- types.add(ref.schema.id);
68
- // TODO Now queries here...
69
- collectTypes(ref, types);
67
+ if ('schema' in ref) {
68
+ types.add(ref.schema.id);
69
+ collectTypes(ref, types);
70
+ }
71
+ else {
72
+ types.add(ref.conditions.schema.id);
73
+ collectTypes(ref.conditions, types);
74
+ }
70
75
  }
71
76
  }
72
77
  if ('filter' in def && 'references' in def.filter) {
73
78
  for (const ref of def.filter.references.values()) {
74
- types.add(ref.schema.id);
75
- collectTypes(ref);
79
+ types.add(ref.conditions.schema.id);
80
+ collectTypes(ref.conditions);
76
81
  }
77
82
  }
78
83
  return types;
@@ -29,6 +29,18 @@ export declare enum QueryType {
29
29
  aggregates = 4,
30
30
  aggregatesCountType = 5
31
31
  }
32
+ export declare enum ReferenceSelect {
33
+ Index = 1,
34
+ Any = 2,
35
+ All = 3
36
+ }
37
+ export type ReferenceSelectValue = {
38
+ type: ReferenceSelect;
39
+ index?: number;
40
+ prop: PropDef | PropDefEdge;
41
+ };
42
+ export type ReferenceSelectOperator = '*' | '*?' | number;
43
+ export declare const getReferenceSelect: (p: string, def: QueryDef) => ReferenceSelectValue | void;
32
44
  declare enum QueryDefType {
33
45
  Edge = 1,
34
46
  Reference = 2,
@@ -71,7 +83,10 @@ export type QueryDefFilter = {
71
83
  prop: PropDef | PropDefEdge;
72
84
  negate: boolean;
73
85
  }[];
74
- references?: Map<number, QueryDefFilter>;
86
+ references?: Map<number, {
87
+ conditions: QueryDefFilter;
88
+ select: ReferenceSelectValue;
89
+ }>;
75
90
  fromRef?: PropDef;
76
91
  schema?: SchemaTypeDef;
77
92
  edges?: Map<number, FilterCondition[]>;
@@ -128,6 +143,7 @@ export interface aggPropDef extends PropDef {
128
143
  }
129
144
  export type LangFallback = LangName | false;
130
145
  export type QueryDefShared = {
146
+ selectFirstResult: boolean;
131
147
  queryType: QueryType;
132
148
  schemaChecksum?: number;
133
149
  errors: QueryError[];
@@ -7,6 +7,29 @@ export var QueryType;
7
7
  QueryType[QueryType["aggregates"] = 4] = "aggregates";
8
8
  QueryType[QueryType["aggregatesCountType"] = 5] = "aggregatesCountType";
9
9
  })(QueryType || (QueryType = {}));
10
+ export var ReferenceSelect;
11
+ (function (ReferenceSelect) {
12
+ ReferenceSelect[ReferenceSelect["Index"] = 1] = "Index";
13
+ ReferenceSelect[ReferenceSelect["Any"] = 2] = "Any";
14
+ ReferenceSelect[ReferenceSelect["All"] = 3] = "All";
15
+ })(ReferenceSelect || (ReferenceSelect = {}));
16
+ export const getReferenceSelect = (p, def) => {
17
+ if (p[p.length - 1] === ']') {
18
+ const [refsField, indexNotation] = p.split('[');
19
+ const index = indexNotation.slice(0, -1);
20
+ const ref = def.schema.props[refsField];
21
+ if (index === '*') {
22
+ return { type: ReferenceSelect.All, prop: ref };
23
+ }
24
+ if (index === '*?') {
25
+ return { type: ReferenceSelect.Any, prop: ref };
26
+ }
27
+ if (isNaN(Number(index))) {
28
+ return;
29
+ }
30
+ return { type: ReferenceSelect.Index, index: Number(index), prop: ref };
31
+ }
32
+ };
10
33
  var QueryDefType;
11
34
  (function (QueryDefType) {
12
35
  QueryDefType[QueryDefType["Edge"] = 1] = "Edge";
@@ -1,4 +1,4 @@
1
- import { ENCODER, writeDoubleLE, writeUint16, writeUint32, writeUint64 } from '@based/utils';
1
+ import { ENCODER, writeDoubleLE, writeUint16, writeUint32, writeUint64, } from '@based/utils';
2
2
  import { ALIAS, ALIASES, BINARY, EMPTY_MICRO_BUFFER, CARDINALITY, MICRO_BUFFER, REFERENCE, REFERENCES, STRING, TEXT, VECTOR, JSON, COLVEC, VECTOR_BASE_TYPE_SIZE_MAP, INT8, UINT8, BOOLEAN, INT16, UINT16, INT32, UINT32, NUMBER, TIMESTAMP, ENUM, } from '@based/schema/def';
3
3
  import { NOT_COMPRESSED } from '@based/protocol';
4
4
  import native from '../native.js';
@@ -68,14 +68,15 @@ const propDefBuffer = (schema, prop) => {
68
68
  return [...buf];
69
69
  }
70
70
  else if (type === REFERENCE || type === REFERENCES) {
71
- const buf = new Uint8Array(7);
71
+ const buf = new Uint8Array(11);
72
72
  const view = new DataView(buf.buffer);
73
73
  const dstType = schema[prop.inverseTypeName];
74
74
  buf[0] = selvaType; // field type
75
75
  buf[1] = makeEdgeConstraintFlags(prop); // flags
76
76
  view.setUint16(2, dstType.id, true); // dst_node_type
77
77
  buf[4] = prop.inversePropNumber; // inverse_field
78
- view.setUint16(5, prop.edgeNodeTypeId ?? 0, true); // meta_node_type
78
+ view.setUint16(5, prop.edgeNodeTypeId ?? 0, true); // edge_node_type
79
+ view.setUint32(7, prop.referencesCapped ?? 0, true);
79
80
  return [...buf];
80
81
  }
81
82
  else if (type === STRING ||
@@ -123,10 +124,12 @@ export function schemaToSelvaBuffer(schema) {
123
124
  }
124
125
  const buf = main.default;
125
126
  switch (f.typeIndex) {
127
+ case ENUM:
128
+ main.default[f.start] = f.reverseEnum[f.default] + 1;
129
+ break;
126
130
  case INT8:
127
131
  case UINT8:
128
132
  case BOOLEAN:
129
- case ENUM:
130
133
  main.default[f.start] = f.default;
131
134
  break;
132
135
  case INT16:
@@ -139,12 +142,6 @@ export function schemaToSelvaBuffer(schema) {
139
142
  break;
140
143
  case NUMBER:
141
144
  writeDoubleLE(buf, f.default, f.start);
142
- //const view = new DataView(
143
- // buf.buffer,
144
- // f.start,
145
- // 8,
146
- //)
147
- //view.setFloat64(0, f.default, true)
148
145
  break;
149
146
  case TIMESTAMP:
150
147
  writeUint64(buf, f.default, f.start);
@@ -173,7 +170,7 @@ export function schemaToSelvaBuffer(schema) {
173
170
  nrFields, // u8 nrFields
174
171
  1 + refFields, // u8 nrFixedFields
175
172
  virtualFields, // u8 nrVirtualFields
176
- 6, // u8 version (generally follows the sdb version)
173
+ 7, // u8 version (generally follows the sdb version)
177
174
  ...propDefBuffer(schema, main),
178
175
  ...rest.map((f) => propDefBuffer(schema, f)).flat(1),
179
176
  ]).buffer;
@@ -94,23 +94,11 @@ const replaceNowValues = (query, now) => {
94
94
  writeInt64(query, dateNow + offset, byteIndex);
95
95
  }
96
96
  };
97
- // let total = 0
98
- // let exectime = 0
99
- // let int
100
97
  export const registerSubscription = (server, query, sub, onData, onError, subInterval) => {
101
- // this can change dynamicly
102
98
  if (subInterval) {
103
99
  server.subscriptions.subInterval = subInterval;
104
100
  }
105
- // if (!int)
106
- // int = setInterval(() => {
107
- // console.log('EXECED', total, exectime / total, 'ms exec time')
108
- // if (server.stopped) {
109
- // clearInterval(int)
110
- // }
111
- // }, 1e3)
112
101
  let killed = false;
113
- // now maybe just once per second? (for now)
114
102
  if (server.subscriptions.active === 0) {
115
103
  startUpdateHandler(server);
116
104
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@based/db",
3
- "version": "0.2.5",
3
+ "version": "0.2.7",
4
4
  "type": "module",
5
5
  "main": "./dist/src/index.js",
6
6
  "scripts": {
@@ -19,10 +19,10 @@
19
19
  "test": "npm run build && LOCPATH=../locale/locale-x86_64-gnu/locale ./scripts/lldb-node ./scripts/test.js",
20
20
  "test-gdb": "npm run build && LOCPATH=../locale/locale-x86_64-gnu/locale gdb -ex run --args node ./scripts/test.js",
21
21
  "test-fast": "LOCPATH=../locale/locale-x86_64-gnu/locale node ./scripts/test.js",
22
- "test-fast-linux_aarch64-schema": "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 schemadebug'",
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'",
22
+ "test-fast-linux_aarch64-schema": "podman run -t --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 schemadebug'",
23
+ "test-fast-linux_aarch64": "podman run -t --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 -t --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 -t --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'",
26
26
  "test-vector": "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 -- mem.js'",
27
27
  "test-zig": "npm run build-zig && tsc && npm run test-fast",
28
28
  "test-zig-debug": "npm run build-zig -- debug && tsc && LOCPATH=../locale/locale-x86_64-gnu/locale ./scripts/lldb-node ./scripts/test.js",
@@ -42,9 +42,9 @@
42
42
  ],
43
43
  "dependencies": {
44
44
  "@based/hash": "1.1.0",
45
- "@based/schema": "5.1.3",
45
+ "@based/schema": "5.1.4",
46
46
  "@based/utils": "1.2.0",
47
- "@based/protocol": "0.1.3",
47
+ "@based/protocol": "0.1.4",
48
48
  "exit-hook": "^4.0.0"
49
49
  },
50
50
  "optionalDependencies": {