@based/db 0.0.7 → 0.0.9

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 (133) hide show
  1. package/README.md +425 -8
  2. package/dist/lib/darwin_aarch64/include/selva/db.h +12 -3
  3. package/dist/lib/darwin_aarch64/include/selva/fields.h +22 -11
  4. package/dist/lib/darwin_aarch64/include/selva/history.h +49 -0
  5. package/dist/lib/darwin_aarch64/include/selva/hll.h +21 -0
  6. package/dist/lib/darwin_aarch64/include/selva/sort.h +14 -0
  7. package/dist/lib/darwin_aarch64/include/selva/types.h +9 -2
  8. package/dist/lib/darwin_aarch64/include/selva/vector.h +22 -1
  9. package/dist/lib/darwin_aarch64/include/selva/xxhash64.h +23 -0
  10. package/dist/lib/darwin_aarch64/libnode-v20.11.1.node +0 -0
  11. package/dist/lib/darwin_aarch64/libnode-v20.18.1.node +0 -0
  12. package/dist/lib/darwin_aarch64/libnode-v22.13.0.node +0 -0
  13. package/dist/lib/darwin_aarch64/libnode-v22.8.0.node +0 -0
  14. package/dist/lib/darwin_aarch64/libselva.dylib +0 -0
  15. package/dist/lib/linux_aarch64/include/selva/db.h +12 -3
  16. package/dist/lib/linux_aarch64/include/selva/fields.h +22 -11
  17. package/dist/lib/linux_aarch64/include/selva/history.h +49 -0
  18. package/dist/lib/linux_aarch64/include/selva/hll.h +21 -0
  19. package/dist/lib/linux_aarch64/include/selva/sort.h +14 -0
  20. package/dist/lib/linux_aarch64/include/selva/types.h +9 -2
  21. package/dist/lib/linux_aarch64/include/selva/vector.h +22 -1
  22. package/dist/lib/linux_aarch64/include/selva/xxhash64.h +23 -0
  23. package/dist/lib/linux_aarch64/libnode-v20.11.1.node +0 -0
  24. package/dist/lib/linux_aarch64/libnode-v20.18.1.node +0 -0
  25. package/dist/lib/linux_aarch64/libnode-v22.13.0.node +0 -0
  26. package/dist/lib/linux_aarch64/libselva.so +0 -0
  27. package/dist/lib/linux_x86_64/include/selva/db.h +12 -3
  28. package/dist/lib/linux_x86_64/include/selva/fields.h +22 -11
  29. package/dist/lib/linux_x86_64/include/selva/history.h +49 -0
  30. package/dist/lib/linux_x86_64/include/selva/hll.h +21 -0
  31. package/dist/lib/linux_x86_64/include/selva/sort.h +14 -0
  32. package/dist/lib/linux_x86_64/include/selva/types.h +9 -2
  33. package/dist/lib/linux_x86_64/include/selva/vector.h +22 -1
  34. package/dist/lib/linux_x86_64/include/selva/xxhash64.h +23 -0
  35. package/dist/lib/linux_x86_64/libnode-v20.11.1.node +0 -0
  36. package/dist/lib/linux_x86_64/libnode-v20.18.1.node +0 -0
  37. package/dist/lib/linux_x86_64/libnode-v22.13.0.node +0 -0
  38. package/dist/lib/linux_x86_64/libselva.so +0 -0
  39. package/dist/src/client/bitWise.js +21 -1
  40. package/dist/src/client/index.d.ts +11 -5
  41. package/dist/src/client/index.js +57 -11
  42. package/dist/src/client/modify/ModifyRes.d.ts +4 -1
  43. package/dist/src/client/modify/ModifyRes.js +8 -1
  44. package/dist/src/client/modify/alias.js +3 -3
  45. package/dist/src/client/modify/binary.js +5 -2
  46. package/dist/src/client/modify/cardinality.d.ts +4 -0
  47. package/dist/src/client/modify/cardinality.js +50 -0
  48. package/dist/src/client/modify/create copy.d.ts +5 -0
  49. package/dist/src/client/modify/create copy.js +112 -0
  50. package/dist/src/client/modify/create.d.ts +2 -1
  51. package/dist/src/client/modify/create.js +11 -7
  52. package/dist/src/client/modify/delete.d.ts +2 -0
  53. package/dist/src/client/modify/delete.js +37 -0
  54. package/dist/src/client/modify/expire.d.ts +3 -0
  55. package/dist/src/client/modify/expire.js +25 -0
  56. package/dist/src/client/modify/fixed.js +11 -1
  57. package/dist/src/client/modify/index.d.ts +1 -1
  58. package/dist/src/client/modify/index.js +1 -1
  59. package/dist/src/client/modify/json.d.ts +4 -0
  60. package/dist/src/client/modify/json.js +5 -0
  61. package/dist/src/client/modify/modify.js +11 -7
  62. package/dist/src/client/modify/references/edge.js +21 -6
  63. package/dist/src/client/modify/references/reference.js +2 -2
  64. package/dist/src/client/modify/references/references.d.ts +0 -1
  65. package/dist/src/client/modify/references/references.js +4 -4
  66. package/dist/src/client/modify/remove.d.ts +1 -2
  67. package/dist/src/client/modify/remove.js +9 -6
  68. package/dist/src/client/modify/setCursor.d.ts +1 -1
  69. package/dist/src/client/modify/setCursor.js +4 -1
  70. package/dist/src/client/modify/string.js +2 -2
  71. package/dist/src/client/modify/text.d.ts +2 -1
  72. package/dist/src/client/modify/text.js +13 -7
  73. package/dist/src/client/modify/types.d.ts +8 -1
  74. package/dist/src/client/modify/types.js +1 -0
  75. package/dist/src/client/modify/update.d.ts +2 -1
  76. package/dist/src/client/modify/update.js +9 -5
  77. package/dist/src/client/modify/upsert.d.ts +2 -1
  78. package/dist/src/client/modify/upsert.js +3 -3
  79. package/dist/src/client/modify/vector copy.d.ts +4 -0
  80. package/dist/src/client/modify/vector copy.js +46 -0
  81. package/dist/src/client/modify/vector.js +6 -4
  82. package/dist/src/client/query/BasedDbQuery.d.ts +4 -3
  83. package/dist/src/client/query/BasedDbQuery.js +39 -16
  84. package/dist/src/client/query/BasedIterable.js +3 -3
  85. package/dist/src/client/query/filter/FilterBranch.d.ts +2 -2
  86. package/dist/src/client/query/filter/FilterBranch.js +2 -2
  87. package/dist/src/client/query/filter/createFixedFilterBuffer.d.ts +3 -2
  88. package/dist/src/client/query/filter/createFixedFilterBuffer.js +14 -11
  89. package/dist/src/client/query/filter/createReferenceFilter.d.ts +2 -1
  90. package/dist/src/client/query/filter/createReferenceFilter.js +6 -5
  91. package/dist/src/client/query/filter/createVariableFilterBuffer.d.ts +2 -1
  92. package/dist/src/client/query/filter/createVariableFilterBuffer.js +61 -30
  93. package/dist/src/client/query/filter/filter.d.ts +2 -2
  94. package/dist/src/client/query/filter/filter.js +27 -22
  95. package/dist/src/client/query/filter/parseFilterValue.js +9 -64
  96. package/dist/src/client/query/filter/primitiveFilter.js +7 -11
  97. package/dist/src/client/query/filter/toBuffer.js +5 -7
  98. package/dist/src/client/query/filter/types.d.ts +51 -2
  99. package/dist/src/client/query/filter/types.js +114 -0
  100. package/dist/src/client/query/include/props.d.ts +2 -0
  101. package/dist/src/client/query/include/props.js +25 -6
  102. package/dist/src/client/query/include/toBuffer.js +21 -1
  103. package/dist/src/client/query/include/walk.js +17 -2
  104. package/dist/src/client/query/queryDef.js +1 -0
  105. package/dist/src/client/query/read/read.js +85 -21
  106. package/dist/src/client/query/search/index.d.ts +2 -0
  107. package/dist/src/client/query/search/index.js +79 -23
  108. package/dist/src/client/query/subscription/index.js +2 -2
  109. package/dist/src/client/query/subscription/markers.d.ts +1 -1
  110. package/dist/src/client/query/subscription/markers.js +2 -2
  111. package/dist/src/client/query/toBuffer.js +0 -4
  112. package/dist/src/client/query/types.d.ts +10 -0
  113. package/dist/src/client/query/validation.d.ts +3 -2
  114. package/dist/src/client/query/validation.js +17 -2
  115. package/dist/src/client/timestamp.d.ts +1 -0
  116. package/dist/src/client/timestamp.js +68 -0
  117. package/dist/src/client/xxHash64.d.ts +1 -0
  118. package/dist/src/client/xxHash64.js +5 -0
  119. package/dist/src/index.d.ts +4 -1
  120. package/dist/src/index.js +13 -3
  121. package/dist/src/native.d.ts +1 -0
  122. package/dist/src/native.js +4 -1
  123. package/dist/src/server/csmt/tree.js +12 -2
  124. package/dist/src/server/index.d.ts +12 -4
  125. package/dist/src/server/index.js +63 -17
  126. package/dist/src/server/migrate/index.js +6 -2
  127. package/dist/src/server/migrate/worker.js +3 -3
  128. package/dist/src/server/schema/selvaBuffer.js +20 -11
  129. package/dist/src/server/schema/typeDef.d.ts +2 -2
  130. package/dist/src/server/schema/typeDef.js +14 -5
  131. package/dist/src/server/schema/types.d.ts +7 -2
  132. package/dist/src/server/schema/types.js +6 -3
  133. package/package.json +1 -1
@@ -1,9 +1,9 @@
1
- import { createQueryDef, QueryDefType, includeFields, filter, sort, defToBuffer, getAll, filterOr, convertFilter, isAlias, } from './query.js';
1
+ import { createQueryDef, QueryDefType, includeFields, filter, sort, defToBuffer, filterOr, convertFilter, isAlias, includeField, } from './query.js';
2
2
  import { BasedQueryResponse } from './BasedIterable.js';
3
3
  import { createOrGetEdgeRefQueryDef, createOrGetRefQueryDef, } from './include/utils.js';
4
4
  import { FilterBranch } from './filter/FilterBranch.js';
5
- import { search } from './search/index.js';
6
- import { isValidId, checkMaxIdsPerQuery, checkTotalBufferSize, hasField, hasFields, } from './validation.js';
5
+ import { search, vectorSearch } from './search/index.js';
6
+ import { isValidId, checkMaxIdsPerQuery, checkTotalBufferSize, hasField, isValidAlias, } from './validation.js';
7
7
  import native from '../../native.js';
8
8
  import { REFERENCE, REFERENCES } from '../../server/schema/types.js';
9
9
  import { subscribe } from './subscription/index.js';
@@ -21,13 +21,39 @@ export class QueryBranch {
21
21
  // @ts-ignore
22
22
  return this;
23
23
  }
24
- filter(field, operator, value) {
25
- const f = convertFilter(field, operator, value);
24
+ filter(field, operator, value, opts) {
25
+ const f = convertFilter(field, operator, value, opts);
26
26
  filter(this.db, this.def, f, this.def.filter);
27
27
  // @ts-ignore
28
28
  return this;
29
29
  }
30
- search(query, ...fields) {
30
+ search(query, field, opts, ...fields) {
31
+ if (ArrayBuffer.isView(query)) {
32
+ // @ts-ignore
33
+ vectorSearch(this.def, query, field, opts ?? {});
34
+ // @ts-ignore
35
+ return this;
36
+ }
37
+ if (field) {
38
+ if (!fields) {
39
+ // @ts-ignore
40
+ fields = [field];
41
+ }
42
+ else {
43
+ // @ts-ignore
44
+ fields.unshift(field);
45
+ }
46
+ }
47
+ if (opts) {
48
+ if (!fields) {
49
+ // @ts-ignore
50
+ fields = [opts];
51
+ }
52
+ else {
53
+ // @ts-ignore
54
+ fields.unshift(opts);
55
+ }
56
+ }
31
57
  if (fields.length) {
32
58
  if (fields.length === 1) {
33
59
  search(this.def, query, fields[0]);
@@ -61,14 +87,14 @@ export class QueryBranch {
61
87
  // @ts-ignore
62
88
  return this;
63
89
  }
64
- or(field, operator, value) {
90
+ or(field, operator, value, opts) {
65
91
  if (typeof field === 'function') {
66
92
  const f = new FilterBranch(this.db, filterOr(this.db, this.def, [], this.def.filter), this.def);
67
93
  field(f);
68
94
  this.def.filter.size += f.filterBranch.size;
69
95
  }
70
96
  else {
71
- const f = convertFilter(field, operator, value);
97
+ const f = convertFilter(field, operator, value, opts);
72
98
  filterOr(this.db, this.def, f, this.def.filter);
73
99
  }
74
100
  // @ts-ignore
@@ -83,13 +109,7 @@ export class QueryBranch {
83
109
  include(...fields) {
84
110
  for (const f of fields) {
85
111
  if (typeof f === 'string') {
86
- if (f === '*') {
87
- hasFields(this.def.props);
88
- includeFields(this.def, getAll(this.def.props));
89
- }
90
- else {
91
- this.def.include.stringFields.add(f);
92
- }
112
+ includeField(this.def, f);
93
113
  }
94
114
  else if (typeof f === 'function') {
95
115
  f((field) => {
@@ -122,8 +142,8 @@ export class QueryBranch {
122
142
  else if (Array.isArray(f)) {
123
143
  for (const field of f) {
124
144
  hasField(field);
145
+ includeField(this.def, field);
125
146
  }
126
- includeFields(this.def, f);
127
147
  }
128
148
  else if (f !== undefined) {
129
149
  throw new Error('Invalid include statement: expected props, refs and edges (string or array) or function');
@@ -181,6 +201,9 @@ export class BasedDbQuery extends QueryBranch {
181
201
  }
182
202
  }
183
203
  const def = createQueryDef(db, QueryDefType.Root, target);
204
+ if (isAlias(id)) {
205
+ isValidAlias(def, id);
206
+ }
184
207
  super(db, def);
185
208
  }
186
209
  #getInternal = async (resolve, reject) => {
@@ -2,7 +2,7 @@ import { inspect } from 'node:util';
2
2
  import picocolors from 'picocolors';
3
3
  import { debug, resultToObject, readAllFields } from './query.js';
4
4
  import { size, time, inspectData } from './display.js';
5
- import { readUint32 } from '../bitWise.js';
5
+ import { readFloatLE, readUint32 } from '../bitWise.js';
6
6
  export { time, size, inspectData };
7
7
  export class BasedQueryResponse {
8
8
  result;
@@ -70,8 +70,8 @@ export class BasedQueryResponse {
70
70
  id,
71
71
  };
72
72
  if (this.def.search) {
73
- item.$searchScore = result[i];
74
- i += 1;
73
+ item.$searchScore = readFloatLE(result, i);
74
+ i += 4;
75
75
  }
76
76
  const l = readAllFields(this.def, result, i, result.byteLength - 4, item, id);
77
77
  i += l;
@@ -1,6 +1,6 @@
1
1
  import { DbClient } from '../../index.js';
2
2
  import { QueryDefFilter, QueryDef } from '../types.js';
3
- import { Operator } from './operators.js';
3
+ import { FilterOpts, Operator } from './types.js';
4
4
  import { FilterBranchFn } from './types.js';
5
5
  export declare class FilterBranch {
6
6
  constructor(db: DbClient, filterBranch: QueryDefFilter, def: QueryDef);
@@ -8,6 +8,6 @@ export declare class FilterBranch {
8
8
  filterBranch: QueryDefFilter;
9
9
  def: QueryDef;
10
10
  or(fn: FilterBranchFn): FilterBranch;
11
- or(field: string, operator?: Operator | boolean, value?: any): FilterBranch;
11
+ or(field: string, operator?: Operator | boolean, value?: any, opts?: FilterOpts): FilterBranch;
12
12
  filter(field: string, operator?: Operator | boolean, value?: any): this;
13
13
  }
@@ -8,14 +8,14 @@ export class FilterBranch {
8
8
  db;
9
9
  filterBranch;
10
10
  def;
11
- or(field, operator, value) {
11
+ or(field, operator, value, opts) {
12
12
  if (typeof field === 'function') {
13
13
  const f = new FilterBranch(this.db, filterOr(this.db, this.def, [], this.filterBranch), this.def);
14
14
  field(f);
15
15
  this.def.filter.size += f.filterBranch.size;
16
16
  }
17
17
  else {
18
- const f = convertFilter(field, operator, value);
18
+ const f = convertFilter(field, operator, value, opts);
19
19
  filterOr(this.db, this.def, f, this.filterBranch);
20
20
  }
21
21
  return this;
@@ -1,3 +1,4 @@
1
1
  import { PropDef, PropDefEdge } from '../../../server/schema/types.js';
2
- export declare const writeFixed: (prop: PropDef | PropDefEdge, buf: Buffer, value: any, size: number, offset: number, op: number) => void;
3
- export declare const createFixedFilterBuffer: (prop: PropDef | PropDefEdge, size: number, op: number, value: any, sort: boolean) => Buffer;
2
+ import { FilterCtx } from './types.js';
3
+ export declare const writeFixed: (prop: PropDef | PropDefEdge, buf: Buffer, value: any, size: number, offset: number) => void;
4
+ export declare const createFixedFilterBuffer: (prop: PropDef | PropDefEdge, size: number, ctx: FilterCtx, value: any, sort: boolean) => Buffer;
@@ -1,6 +1,6 @@
1
1
  import { BINARY, STRING, REFERENCES, } from '../../../server/schema/types.js';
2
2
  import { propIsSigned } from '../../../server/schema/utils.js';
3
- import { negateType, stripNegation } from './operators.js';
3
+ import { EQUAL, MODE_AND_FIXED, MODE_DEFAULT, MODE_OR_FIXED, } from './types.js';
4
4
  import { parseFilterValue } from './parseFilterValue.js';
5
5
  // -------------------------------------------
6
6
  // conditions normal
@@ -15,7 +15,7 @@ import { parseFilterValue } from './parseFilterValue.js';
15
15
  // field, [size 2]
16
16
  // [or = 2] [size 2] [start 2], [op], [size 2], value[size], [size 2], value[size]
17
17
  // -------------------------------------------
18
- export const writeFixed = (prop, buf, value, size, offset, op) => {
18
+ export const writeFixed = (prop, buf, value, size, offset) => {
19
19
  if (prop.typeIndex === BINARY || prop.typeIndex === STRING) {
20
20
  if (typeof value === 'string') {
21
21
  const size = buf.write(value, offset + 1, 'utf8');
@@ -58,18 +58,21 @@ export const writeFixed = (prop, buf, value, size, offset, op) => {
58
58
  // default = 0,
59
59
  // orFixed = 1,
60
60
  // orVar = 2,
61
- export const createFixedFilterBuffer = (prop, size, op, value, sort) => {
61
+ export const createFixedFilterBuffer = (prop, size, ctx, value, sort) => {
62
62
  let buf;
63
63
  const start = prop.start;
64
64
  if (Array.isArray(value)) {
65
65
  // [or = 1] [size 2] [start 2] [op], [repeat 2], value[size] value[size] value[size]
66
66
  const len = value.length;
67
67
  buf = Buffer.allocUnsafe(10 + len * size);
68
- buf[0] = negateType(op);
69
- buf[1] = prop.typeIndex === REFERENCES && op === 1 ? 3 : 1;
68
+ buf[0] = ctx.type;
69
+ buf[1] =
70
+ prop.typeIndex === REFERENCES && ctx.operation === EQUAL
71
+ ? MODE_AND_FIXED
72
+ : MODE_OR_FIXED;
70
73
  buf.writeUInt16LE(size, 2);
71
74
  buf.writeUInt16LE(start, 4);
72
- buf[6] = stripNegation(op);
75
+ buf[6] = ctx.operation;
73
76
  buf[7] = prop.typeIndex;
74
77
  buf.writeUInt16LE(len, 8);
75
78
  if (sort) {
@@ -81,20 +84,20 @@ export const createFixedFilterBuffer = (prop, size, op, value, sort) => {
81
84
  }
82
85
  else {
83
86
  for (let i = 0; i < len; i++) {
84
- writeFixed(prop, buf, parseFilterValue(prop, value[i]), size, 10 + i * size, op);
87
+ writeFixed(prop, buf, parseFilterValue(prop, value[i]), size, 10 + i * size);
85
88
  }
86
89
  }
87
90
  }
88
91
  else {
89
92
  // [or = 0] [size 2] [start 2], [op], value[size]
90
93
  buf = Buffer.allocUnsafe(8 + size);
91
- buf[0] = negateType(op);
92
- buf[1] = 0;
94
+ buf[0] = ctx.type;
95
+ buf[1] = MODE_DEFAULT;
93
96
  buf.writeUInt16LE(size, 2);
94
97
  buf.writeUInt16LE(start, 4);
95
- buf[6] = stripNegation(op);
98
+ buf[6] = ctx.operation;
96
99
  buf[7] = prop.typeIndex;
97
- writeFixed(prop, buf, parseFilterValue(prop, value), size, 8, op);
100
+ writeFixed(prop, buf, parseFilterValue(prop, value), size, 8);
98
101
  }
99
102
  return buf;
100
103
  };
@@ -1,2 +1,3 @@
1
1
  import { PropDef, PropDefEdge } from '../../../server/schema/types.js';
2
- export declare const createReferenceFilter: (prop: PropDef | PropDefEdge, op: number, value: any) => Buffer;
2
+ import { FilterCtx } from './types.js';
3
+ export declare const createReferenceFilter: (prop: PropDef | PropDefEdge, ctx: FilterCtx, value: any) => Buffer;
@@ -1,14 +1,15 @@
1
- import { negateType, stripNegation } from './operators.js';
2
- export const createReferenceFilter = (prop, op, value) => {
1
+ import { MODE_REFERENCE } from './types.js';
2
+ export const createReferenceFilter = (prop, ctx, value) => {
3
3
  let buf;
4
4
  const len = Array.isArray(value) ? value.length : 1;
5
5
  buf = Buffer.allocUnsafe(11 + len * 8);
6
- buf[0] = negateType(op);
7
- buf[1] = 5;
6
+ buf[0] = ctx.type;
7
+ buf[1] = MODE_REFERENCE;
8
8
  buf.writeUInt16LE(8, 2);
9
9
  buf.writeUInt16LE(len, 4);
10
- buf[6] = stripNegation(op);
10
+ buf[6] = ctx.operation;
11
11
  buf[7] = prop.typeIndex;
12
+ // REF TYPE (only 1 exists now...)
12
13
  buf[8] = 0;
13
14
  buf.writeUInt16LE(prop.inverseTypeId, 9);
14
15
  if (Array.isArray(value)) {
@@ -1,3 +1,4 @@
1
1
  import { PropDef, PropDefEdge } from '../../../server/schema/types.js';
2
+ import { FilterCtx } from './types.js';
2
3
  import { LangCode } from '@based/schema';
3
- export declare const createVariableFilterBuffer: (value: any, prop: PropDef | PropDefEdge, op: number, lang: LangCode) => Buffer;
4
+ export declare const createVariableFilterBuffer: (value: any, prop: PropDef | PropDefEdge, ctx: FilterCtx, lang: LangCode) => Buffer;
@@ -1,15 +1,27 @@
1
- import { ALIAS, TEXT, } from '../../../server/schema/types.js';
2
- import { negateType, stripNegation } from './operators.js';
1
+ import { ALIAS, TEXT, VECTOR, } from '../../../server/schema/types.js';
2
+ import { EQUAL, EQUAL_CRC32, HAS, HAS_TO_LOWER_CASE, LIKE, MODE_DEFAULT_VAR, MODE_OR_VAR, getVectorFn, } from './types.js';
3
3
  import { createFixedFilterBuffer } from './createFixedFilterBuffer.js';
4
- const parseValue = (value, prop, op, lang) => {
4
+ import { crc32 } from '../../crc32.js';
5
+ const DEFAULT_SCORE = Buffer.from(new Float32Array([0.5]).buffer);
6
+ const parseValue = (value, prop, ctx, lang) => {
5
7
  let val = value;
6
- if (op === 19 && typeof val === 'string') {
8
+ if (ctx.operation === HAS_TO_LOWER_CASE && typeof val === 'string') {
7
9
  val = val.toLowerCase();
8
10
  }
11
+ if (ctx.operation === LIKE && prop.typeIndex === VECTOR) {
12
+ if (!(val instanceof ArrayBuffer)) {
13
+ throw new Error('Vector should be an arrayBuffer');
14
+ }
15
+ let fn = getVectorFn(ctx.opts.fn);
16
+ const score = ctx.opts.score
17
+ ? Buffer.from(new Float32Array([ctx.opts.score]).buffer)
18
+ : DEFAULT_SCORE;
19
+ val = Buffer.concat([Buffer.from(val), Buffer.from([fn]), score]);
20
+ }
9
21
  if (val instanceof Uint8Array ||
10
22
  typeof value === 'string' ||
11
23
  !prop.separate ||
12
- op !== 1) {
24
+ ctx.operation !== EQUAL) {
13
25
  if (prop.typeIndex === TEXT) {
14
26
  // can be optmized replace when using uint8array
15
27
  val = Buffer.concat([Buffer.from(val), Buffer.from([lang])]);
@@ -18,21 +30,29 @@ const parseValue = (value, prop, op, lang) => {
18
30
  val = Buffer.from(val);
19
31
  }
20
32
  }
21
- if (!(val instanceof Buffer)) {
22
- throw new Error('Incorrect value for filter ' + prop.path);
33
+ if (val?.BYTES_PER_ELEMENT > 1) {
34
+ val = val.buffer;
35
+ }
36
+ if (!(val instanceof Buffer || val instanceof ArrayBuffer)) {
37
+ throw new Error(`Incorrect value for filter: ${prop.path}`);
38
+ }
39
+ if (ctx.operation === LIKE && prop.typeIndex !== VECTOR) {
40
+ // @ts-ignore
41
+ val = Buffer.concat([val, Buffer.from([ctx.opts.score ?? 2])]);
23
42
  }
43
+ // @ts-ignore TODO FDN-576
24
44
  return val;
25
45
  };
26
- export const createVariableFilterBuffer = (value, prop, op, lang) => {
27
- let isOr = 4;
46
+ export const createVariableFilterBuffer = (value, prop, ctx, lang) => {
47
+ let mode = MODE_DEFAULT_VAR;
28
48
  let val;
29
49
  let buf;
30
50
  if (Array.isArray(value)) {
31
- if (op !== 1 || !prop.separate) {
32
- isOr = 2;
51
+ if (ctx.operation !== EQUAL || !prop.separate) {
52
+ mode = MODE_OR_VAR;
33
53
  const x = [];
34
54
  for (const v of value) {
35
- const a = parseValue(v, prop, op, lang);
55
+ const a = parseValue(v, prop, ctx, lang);
36
56
  const size = Buffer.allocUnsafe(2);
37
57
  size.writeUint16LE(a.byteLength);
38
58
  x.push(size, a);
@@ -42,49 +62,60 @@ export const createVariableFilterBuffer = (value, prop, op, lang) => {
42
62
  else {
43
63
  const x = [];
44
64
  for (const v of value) {
45
- x.push(parseValue(v, prop, op, lang));
65
+ x.push(parseValue(v, prop, ctx, lang));
46
66
  }
47
67
  val = x;
48
68
  }
49
69
  }
50
70
  else {
51
- val = parseValue(value, prop, op, lang);
71
+ val = parseValue(value, prop, ctx, lang);
52
72
  }
53
- // --------------------
54
- if (op === 3 || op === 1 || op === 2 || op === 16 || op === 18 || op === 19) {
73
+ // -------------------- PUT VARIABLES HERE
74
+ if (ctx.operation === EQUAL ||
75
+ ctx.operation === HAS ||
76
+ ctx.operation === LIKE ||
77
+ ctx.operation === HAS_TO_LOWER_CASE) {
55
78
  if (prop.separate) {
56
- if (op === 1 && prop.typeIndex !== ALIAS) {
57
- // console.log('STRICT EQUAL FOR TEXT ALSO!')
58
- // 17 crc32 check
59
- buf = createFixedFilterBuffer(prop, 8, 17, val, false);
79
+ if (ctx.operation === EQUAL &&
80
+ prop.typeIndex !== ALIAS &&
81
+ prop.typeIndex !== VECTOR) {
82
+ if (prop.typeIndex === TEXT) {
83
+ buf = writeVarFilter(mode, Buffer.concat([
84
+ Buffer.from(new Uint32Array([crc32(val.slice(0, -1)), val.byteLength - 1])
85
+ .buffer),
86
+ Buffer.from(new Uint8Array([val[val.length - 1]]).buffer),
87
+ ]), ctx, prop, 0, 0);
88
+ }
89
+ else {
90
+ buf = createFixedFilterBuffer(prop, 8, { operation: EQUAL_CRC32, type: ctx.type, opts: ctx.opts }, val, false);
91
+ }
60
92
  }
61
93
  else {
62
- buf = writeVarFilter(isOr, val, buf, op, prop, 0, 0);
94
+ buf = writeVarFilter(mode, val, ctx, prop, 0, 0);
63
95
  }
64
96
  }
65
97
  else {
66
- // HANDLE EQUAL
67
- buf = writeVarFilter(isOr, val, buf, op, prop, prop.start, prop.len);
98
+ buf = writeVarFilter(mode, val, ctx, prop, prop.start, prop.len);
68
99
  }
69
100
  }
70
101
  else {
71
- console.log('OP NOT SUPPORTED YET =>', op);
102
+ console.log('OP NOT SUPPORTED YET =>', ctx);
72
103
  }
73
104
  return buf;
74
105
  };
75
- function writeVarFilter(isOr, val, buf, op, prop, start, len) {
106
+ function writeVarFilter(mode, val, ctx, prop, start, len) {
76
107
  const size = val.byteLength;
77
- buf = Buffer.allocUnsafe(12 + size);
78
- buf[0] = negateType(op);
79
- buf[1] = isOr;
108
+ const buf = Buffer.allocUnsafe(12 + size);
109
+ buf[0] = ctx.type;
110
+ buf[1] = mode;
80
111
  buf.writeUInt16LE(start, 2);
81
112
  buf.writeUint16LE(len, 4);
82
113
  buf.writeUint32LE(size, 6);
83
- buf[10] = stripNegation(op);
114
+ buf[10] = ctx.operation;
84
115
  buf[11] = prop.typeIndex;
85
116
  // need to pas LANG FROM QUERY
86
117
  // need to set on 12 if TEXT
87
- buf.set(val, 12);
118
+ buf.set(Buffer.from(val), 12);
88
119
  return buf;
89
120
  }
90
121
  //# sourceMappingURL=createVariableFilterBuffer.js.map
@@ -1,10 +1,10 @@
1
1
  import { QueryDef, QueryDefFilter } from '../types.js';
2
2
  import { SchemaTypeDef } from '../../../server/schema/schema.js';
3
- import { Operator } from './operators.js';
3
+ import { FilterOpts, Operator } from './types.js';
4
4
  import { Filter, FilterAst } from './types.js';
5
5
  import { DbClient } from '../../index.js';
6
6
  export { Operator, Filter };
7
7
  export declare const filterRaw: (db: DbClient, filter: Filter, schema: SchemaTypeDef, conditions: QueryDefFilter, def: QueryDef) => number;
8
8
  export declare const filter: (db: DbClient, def: QueryDef, filterAst: FilterAst, conditions: QueryDefFilter) => void;
9
9
  export declare const filterOr: (db: DbClient, def: QueryDef, filterAst: FilterAst[], conditions: QueryDefFilter) => QueryDefFilter;
10
- export declare const convertFilter: (field: string, operator?: Operator | boolean, value?: any) => FilterAst;
10
+ export declare const convertFilter: (field: string, operator?: Operator | boolean, value?: any, opts?: FilterOpts) => FilterAst;
@@ -1,16 +1,14 @@
1
1
  import { isPropDef, ID_FIELD_DEF, TEXT, } from '../../../server/schema/schema.js';
2
2
  import { primitiveFilter } from './primitiveFilter.js';
3
+ import { toFilterCtx } from './types.js';
3
4
  import { IsFilter } from './types.js';
4
5
  import { hasField, checkOperator, checkValue } from '../validation.js';
5
6
  import { langCodesMap } from '@based/schema';
6
7
  const referencesFilter = (db, filter, schema, conditions, def) => {
7
- const [fieldStr, operator, value] = filter;
8
+ const [fieldStr, ctx, value] = filter;
8
9
  var size = 0;
9
10
  const path = fieldStr.split('.');
10
11
  let t = schema.tree;
11
- hasField(fieldStr);
12
- checkOperator(operator);
13
- checkValue(value, operator);
14
12
  for (let i = 0; i < path.length; i++) {
15
13
  const p = path[i];
16
14
  t = t[p];
@@ -45,18 +43,14 @@ const referencesFilter = (db, filter, schema, conditions, def) => {
45
43
  conditions.references.set(t.prop, refConditions);
46
44
  }
47
45
  // more nested
48
- size += filterRaw(db, [path.slice(i + 1).join('.'), operator, value], refConditions.schema, refConditions, def);
46
+ size += filterRaw(db, [path.slice(i + 1).join('.'), ctx, value], refConditions.schema, refConditions, def);
49
47
  return size;
50
48
  }
51
49
  }
52
- console.error(`Querty: field "${fieldStr}" does not exist on type ${schema.type}`);
53
- return size;
50
+ throw new Error(`Query: field "${fieldStr}" does not exist on type ${schema.type}`);
54
51
  };
55
52
  export const filterRaw = (db, filter, schema, conditions, def) => {
56
- const [field, operator, value] = filter;
57
- hasField(field); // Validates if the field is a non-empty string
58
- checkOperator(operator); // Validates if the operator is valid
59
- checkValue(value, operator); // Validates the value based on the operator
53
+ const field = filter[0];
60
54
  let fieldDef = schema.props[field];
61
55
  if (!fieldDef) {
62
56
  const s = field.split('.');
@@ -101,14 +95,14 @@ export const filterOr = (db, def, filterAst, conditions) => {
101
95
  conditions.size += conditions.or.size;
102
96
  return conditions.or;
103
97
  };
104
- function normalizeNeedle(s) {
98
+ const normalizeNeedle = (s) => {
105
99
  return s
106
100
  .normalize('NFKD')
107
101
  .split('')
108
102
  .filter((ch) => ch.charCodeAt(0) <= 127)
109
103
  .join('');
110
- }
111
- export const convertFilter = (field, operator, value) => {
104
+ };
105
+ export const convertFilter = (field, operator, value, opts) => {
112
106
  if (operator === undefined) {
113
107
  operator = '=';
114
108
  value = true;
@@ -122,26 +116,37 @@ export const convertFilter = (field, operator, value) => {
122
116
  checkValue(value, operator);
123
117
  if (operator === '!..') {
124
118
  return [
125
- [field, '>', value[1]],
126
- [field, '<', value[0]],
119
+ [field, toFilterCtx('>', opts), value[1]],
120
+ [field, toFilterCtx('<', opts), value[0]],
127
121
  ];
128
122
  }
129
123
  else if (operator === '..') {
130
124
  return [
131
- [field, '>', value[0]],
132
- [field, '<', value[1]],
125
+ [field, toFilterCtx('>', opts), value[0]],
126
+ [field, toFilterCtx('<', opts), value[1]],
133
127
  ];
134
128
  }
135
129
  else {
136
130
  if (operator == 'like') {
137
- if (value.normalize) {
131
+ if (value == null) {
132
+ throw new Error('Value is required');
133
+ }
134
+ if (value?.normalize) {
138
135
  value = normalizeNeedle(value);
139
136
  }
140
- else {
141
- value = value.map(normalizeNeedle);
137
+ else if (Array.isArray(value)) {
138
+ if (value[0]?.normalize) {
139
+ value = value.map(normalizeNeedle);
140
+ }
141
+ else if (value[0]?.BYTES_PER_ELEMENT > 1) {
142
+ value = value.map((v) => v.buffer);
143
+ }
144
+ }
145
+ else if (value?.BYTES_PER_ELEMENT > 1) {
146
+ value = value.buffer;
142
147
  }
143
148
  }
144
- return [[field, operator, value]];
149
+ return [[field, toFilterCtx(operator, opts), value]];
145
150
  }
146
151
  };
147
152
  //# sourceMappingURL=filter.js.map
@@ -1,5 +1,6 @@
1
- import { TIMESTAMP, CREATED, UPDATED, ENUM, BOOLEAN, STRING, BINARY, } from '../../../server/schema/types.js';
1
+ import { TIMESTAMP, CREATED, UPDATED, ENUM, BOOLEAN, STRING, BINARY, TEXT, } from '../../../server/schema/types.js';
2
2
  import { crc32 } from '../../crc32.js';
3
+ import { convertToTimestamp } from '../../timestamp.js';
3
4
  // -------------------------------------------
4
5
  // conditions normal
5
6
  // field, [size 2]
@@ -13,26 +14,10 @@ import { crc32 } from '../../crc32.js';
13
14
  // field, [size 2]
14
15
  // [or = 2] [size 2] [start 2], [op], [size 2], value[size], [size 2], value[size]
15
16
  // -------------------------------------------
16
- const timeToNumber = (ex) => {
17
- if (ex === 's') {
18
- return 1000;
19
- }
20
- if (ex === 'm') {
21
- return 1000 * 60;
22
- }
23
- if (ex === 'h') {
24
- return 1000 * 60 * 60;
25
- }
26
- if (ex === 'd') {
27
- return 1000 * 60 * 60 * 24;
28
- }
29
- if (ex === 'y') {
30
- return 31556952000;
31
- }
32
- return 1;
33
- };
34
17
  export const parseFilterValue = (prop, value) => {
35
- if (prop.typeIndex === BINARY || prop.typeIndex === STRING) {
18
+ if (prop.typeIndex === BINARY ||
19
+ prop.typeIndex === STRING ||
20
+ prop.typeIndex === TEXT) {
36
21
  const b = value instanceof Buffer ? value : Buffer.from(value);
37
22
  const buf = Buffer.allocUnsafe(8);
38
23
  buf.writeUint32LE(crc32(b), 0);
@@ -48,51 +33,11 @@ export const parseFilterValue = (prop, value) => {
48
33
  else if (prop.typeIndex === TIMESTAMP ||
49
34
  prop.typeIndex === CREATED ||
50
35
  prop.typeIndex === UPDATED) {
51
- if (value instanceof Date) {
52
- return value.valueOf();
53
- }
54
- if (typeof value === 'string') {
55
- if (value === 'now') {
56
- return Date.now();
57
- }
58
- const y = value.replace(/([+-])/g, ' $1 ');
59
- const arr = y.split(/ +/);
60
- let newValue = 0;
61
- let now;
62
- let op = 1;
63
- for (const seg of arr) {
64
- if (seg === '-') {
65
- op = -1;
66
- }
67
- else if (seg === '+') {
68
- op = 1;
69
- }
70
- else {
71
- var v = 0;
72
- if (seg === 'now') {
73
- if (!now) {
74
- now = Date.now();
75
- }
76
- v = now;
77
- }
78
- else if (/[smhdy]$/.test(seg)) {
79
- const ex = seg[seg.length - 1];
80
- const number = parseInt(seg, 10);
81
- v = number * timeToNumber(ex);
82
- }
83
- else if (seg) {
84
- v = new Date(seg).valueOf();
85
- }
86
- if (op === -1) {
87
- newValue -= v;
88
- }
89
- else {
90
- newValue += v;
91
- }
92
- }
93
- }
94
- return newValue;
36
+ const v = convertToTimestamp(value);
37
+ if (typeof v !== 'number') {
38
+ throw new Error(`Incorrect value for timestamp ${prop.path.join('.')}`);
95
39
  }
40
+ return v;
96
41
  }
97
42
  return value;
98
43
  };