@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,16 +1,12 @@
1
1
  import { REFERENCE, REFERENCES, REVERSE_SIZE_MAP, } from '../../../server/schema/types.js';
2
- import { isNumerical, operationToByte } from './operators.js';
2
+ import { EQUAL, isNumerical } from './types.js';
3
3
  import { createVariableFilterBuffer } from './createVariableFilterBuffer.js';
4
4
  import { createFixedFilterBuffer } from './createFixedFilterBuffer.js';
5
5
  import { createReferenceFilter } from './createReferenceFilter.js';
6
- import { checkOperator, checkValue } from '../validation.js';
7
6
  export const primitiveFilter = (prop, filter, conditions, lang) => {
8
- let [, operator, value] = filter;
9
- checkOperator(operator);
10
- checkValue(value, operator);
7
+ let [, ctx, value] = filter;
11
8
  const fieldIndexChar = prop.prop;
12
9
  let buf;
13
- const op = operationToByte(operator);
14
10
  let size = 0;
15
11
  const bufferMap = prop.__isEdge ? conditions.edges : conditions.conditions;
16
12
  const isArray = Array.isArray(value);
@@ -19,19 +15,19 @@ export const primitiveFilter = (prop, filter, conditions, lang) => {
19
15
  }
20
16
  const propSize = REVERSE_SIZE_MAP[prop.typeIndex];
21
17
  if (prop.typeIndex === REFERENCE) {
22
- buf = createReferenceFilter(prop, op, value);
18
+ buf = createReferenceFilter(prop, ctx, value);
23
19
  }
24
20
  else if (prop.typeIndex === REFERENCES) {
25
- if (op === 1 && !isArray) {
21
+ if (ctx.operation === EQUAL && !isArray) {
26
22
  value = [value];
27
23
  }
28
- buf = createFixedFilterBuffer(prop, 4, op, value, !isNumerical(op));
24
+ buf = createFixedFilterBuffer(prop, 4, ctx, value, !isNumerical(ctx.operation));
29
25
  }
30
26
  else if (propSize) {
31
- buf = createFixedFilterBuffer(prop, propSize, op, value, false);
27
+ buf = createFixedFilterBuffer(prop, propSize, ctx, value, false);
32
28
  }
33
29
  else {
34
- buf = createVariableFilterBuffer(value, prop, op, lang);
30
+ buf = createVariableFilterBuffer(value, prop, ctx, lang);
35
31
  }
36
32
  // ADD OR if array for value
37
33
  let arr = bufferMap.get(fieldIndexChar);
@@ -1,7 +1,4 @@
1
- // -------------------------------------------
2
- // and
3
- // [meta = 255] [size 2]
4
- // -------------------------------------------
1
+ import { META_EDGE, META_OR_BRANCH, META_REFERENCE } from './types.js';
5
2
  // or
6
3
  // [meta = 253] [size 2] [next 4]
7
4
  // -------------------------------------------
@@ -43,7 +40,7 @@ export const fillConditionsBuffer = (result, conditions, offset) => {
43
40
  let lastWritten = offset;
44
41
  let orJumpIndex = 0;
45
42
  if (conditions.or) {
46
- result[lastWritten] = 253;
43
+ result[lastWritten] = META_OR_BRANCH;
47
44
  lastWritten++;
48
45
  orJumpIndex = lastWritten;
49
46
  lastWritten += 2;
@@ -54,7 +51,7 @@ export const fillConditionsBuffer = (result, conditions, offset) => {
54
51
  });
55
52
  if (conditions.references) {
56
53
  for (const [refField, refConditions] of conditions.references) {
57
- result[lastWritten] = 254;
54
+ result[lastWritten] = META_REFERENCE;
58
55
  lastWritten++;
59
56
  result[lastWritten] = refField;
60
57
  lastWritten++;
@@ -69,7 +66,7 @@ export const fillConditionsBuffer = (result, conditions, offset) => {
69
66
  }
70
67
  if (conditions.edges) {
71
68
  conditions.edges.forEach((v, k) => {
72
- result[lastWritten] = 252;
69
+ result[lastWritten] = META_EDGE;
73
70
  lastWritten++;
74
71
  let sizeIndex = lastWritten;
75
72
  lastWritten += 2;
@@ -86,6 +83,7 @@ export const fillConditionsBuffer = (result, conditions, offset) => {
86
83
  }
87
84
  return lastWritten - offset;
88
85
  };
86
+ // TODO convert to UINT8ARRAY
89
87
  export const filterToBuffer = (conditions) => {
90
88
  let result;
91
89
  if (conditions.size > 0) {
@@ -1,6 +1,55 @@
1
- import { Operator } from './operators.js';
2
1
  import { FilterBranch } from './FilterBranch.js';
3
- export type Filter = [fieldStr: string, operator: Operator, value: any];
2
+ export type Filter = [fieldStr: string, ctx: FilterCtx, value: any];
4
3
  export type FilterBranchFn = (filterBranch: FilterBranch) => void;
5
4
  export type FilterAst = (Filter | FilterAst)[];
6
5
  export declare const IsFilter: (f: FilterAst) => f is Filter;
6
+ export declare const validOperators: readonly ["=", "has", "!has", "<", ">", "!=", "like", ">=", "<=", "..", "!.."];
7
+ export type Operator = '=' | 'has' | '!has' | '<' | '>' | '!=' | 'like' | '>=' | '<=' | '..' | '!..' | 'like';
8
+ export type FilterOpts<O = Operator> = {
9
+ lowerCase?: boolean;
10
+ fn?: 'dotProduct' | 'manhattanDistance' | 'cosineSimilarity' | 'euclideanDistance';
11
+ score?: number;
12
+ };
13
+ export declare const EQUAL = 1;
14
+ export declare const HAS = 2;
15
+ export declare const ENDS_WITH = 4;
16
+ export declare const STARTS_WITH = 5;
17
+ export declare const EQUAL_CRC32 = 17;
18
+ export declare const GREATER_THAN = 6;
19
+ export declare const SMALLER_THAN = 7;
20
+ export declare const GREATER_THAN_INCLUSIVE = 8;
21
+ export declare const SMALLER_THAN_INCLUSIVE = 9;
22
+ export declare const RANGE = 10;
23
+ export declare const RANGE_EXCLUDE = 11;
24
+ export declare const EQUAL_LOWER_CASE = 12;
25
+ export declare const HAS_TO_LOWER_CASE = 13;
26
+ export declare const STARTS_WITH_LOWER_CASE = 14;
27
+ export declare const ENDS_WITH_LOWER_CASE = 15;
28
+ export declare const LIKE = 18;
29
+ export type OPERATOR = typeof EQUAL | typeof HAS | typeof ENDS_WITH | typeof STARTS_WITH | typeof GREATER_THAN | typeof SMALLER_THAN | typeof GREATER_THAN_INCLUSIVE | typeof SMALLER_THAN_INCLUSIVE | typeof RANGE | typeof RANGE_EXCLUDE | typeof EQUAL_LOWER_CASE | typeof HAS_TO_LOWER_CASE | typeof STARTS_WITH_LOWER_CASE | typeof ENDS_WITH_LOWER_CASE | typeof LIKE | typeof EQUAL_CRC32;
30
+ export declare const isNumerical: (op: OPERATOR) => boolean;
31
+ export declare const TYPE_NEGATE = 1;
32
+ export declare const TYPE_DEFAULT = 2;
33
+ export type FILTER_TYPE = typeof TYPE_NEGATE | typeof TYPE_DEFAULT;
34
+ export declare const MODE_DEFAULT = 0;
35
+ export declare const MODE_OR_FIXED = 1;
36
+ export declare const MODE_OR_VAR = 2;
37
+ export declare const MODE_AND_FIXED = 3;
38
+ export declare const MODE_DEFAULT_VAR = 4;
39
+ export declare const MODE_REFERENCE = 5;
40
+ export type FILTER_MODE = typeof MODE_DEFAULT | typeof MODE_OR_FIXED | typeof MODE_OR_VAR | typeof MODE_AND_FIXED | typeof MODE_DEFAULT_VAR | typeof MODE_REFERENCE;
41
+ export declare const META_EDGE = 252;
42
+ export declare const META_OR_BRANCH = 253;
43
+ export declare const META_REFERENCE = 254;
44
+ export type FILTER_META = typeof META_EDGE | typeof META_OR_BRANCH | typeof META_REFERENCE;
45
+ export type FilterCtx = {
46
+ operation: OPERATOR;
47
+ type: FILTER_TYPE;
48
+ opts: FilterOpts;
49
+ };
50
+ export declare const VECTOR_DOT_PRODUCT = 0;
51
+ export declare const VECTOR_MANHATTAN_DIST = 1;
52
+ export declare const VECTOR_COSTINE_SIMILARITY = 2;
53
+ export declare const VECTOR_EUCLIDEAN_DIST = 3;
54
+ export declare const getVectorFn: (optsFn?: FilterOpts["fn"]) => 1 | 2 | 3 | 0;
55
+ export declare const toFilterCtx: (op: Operator, opts?: FilterOpts) => FilterCtx;
@@ -4,4 +4,118 @@ export const IsFilter = (f) => {
4
4
  }
5
5
  return false;
6
6
  };
7
+ export const validOperators = [
8
+ '=',
9
+ 'has',
10
+ '!has',
11
+ '<',
12
+ '>',
13
+ '!=',
14
+ 'like',
15
+ '>=',
16
+ '<=',
17
+ '..',
18
+ '!..',
19
+ ];
20
+ // -------------------------------------------
21
+ // operations shared
22
+ export const EQUAL = 1;
23
+ export const HAS = 2;
24
+ export const ENDS_WITH = 4;
25
+ export const STARTS_WITH = 5;
26
+ export const EQUAL_CRC32 = 17;
27
+ // -------------------------------------------
28
+ // operations numbers
29
+ export const GREATER_THAN = 6;
30
+ export const SMALLER_THAN = 7;
31
+ export const GREATER_THAN_INCLUSIVE = 8;
32
+ export const SMALLER_THAN_INCLUSIVE = 9;
33
+ export const RANGE = 10;
34
+ export const RANGE_EXCLUDE = 11;
35
+ // -------------------------------------------
36
+ // operations strings
37
+ export const EQUAL_LOWER_CASE = 12;
38
+ export const HAS_TO_LOWER_CASE = 13;
39
+ export const STARTS_WITH_LOWER_CASE = 14;
40
+ export const ENDS_WITH_LOWER_CASE = 15;
41
+ export const LIKE = 18;
42
+ // -------------------------------------------
43
+ export const isNumerical = (op) => {
44
+ if (op === GREATER_THAN ||
45
+ op === SMALLER_THAN ||
46
+ op === SMALLER_THAN_INCLUSIVE ||
47
+ op === GREATER_THAN_INCLUSIVE ||
48
+ op === RANGE ||
49
+ op === RANGE_EXCLUDE) {
50
+ return true;
51
+ }
52
+ return false;
53
+ };
54
+ // -------------------------------------------
55
+ // Types
56
+ export const TYPE_NEGATE = 1;
57
+ export const TYPE_DEFAULT = 2;
58
+ // -------------------------------------------
59
+ // Modes
60
+ export const MODE_DEFAULT = 0;
61
+ export const MODE_OR_FIXED = 1;
62
+ export const MODE_OR_VAR = 2;
63
+ export const MODE_AND_FIXED = 3;
64
+ export const MODE_DEFAULT_VAR = 4;
65
+ export const MODE_REFERENCE = 5;
66
+ // -------------------------------------------
67
+ // Meta
68
+ export const META_EDGE = 252;
69
+ export const META_OR_BRANCH = 253;
70
+ export const META_REFERENCE = 254;
71
+ export const VECTOR_DOT_PRODUCT = 0;
72
+ export const VECTOR_MANHATTAN_DIST = 1;
73
+ export const VECTOR_COSTINE_SIMILARITY = 2;
74
+ export const VECTOR_EUCLIDEAN_DIST = 3;
75
+ export const getVectorFn = (optsFn) => {
76
+ if (!optsFn) {
77
+ return VECTOR_COSTINE_SIMILARITY;
78
+ }
79
+ if (optsFn === 'dotProduct') {
80
+ return VECTOR_DOT_PRODUCT;
81
+ }
82
+ else if (optsFn === 'euclideanDistance') {
83
+ return VECTOR_EUCLIDEAN_DIST;
84
+ }
85
+ else if (optsFn === 'manhattanDistance') {
86
+ return VECTOR_MANHATTAN_DIST;
87
+ }
88
+ };
89
+ export const toFilterCtx = (op, opts = {}) => {
90
+ if (op === '=' || op === '!=') {
91
+ return {
92
+ operation: EQUAL,
93
+ type: op === '!=' ? TYPE_NEGATE : TYPE_DEFAULT,
94
+ opts,
95
+ };
96
+ }
97
+ if (op === 'has' || op === '!has') {
98
+ return {
99
+ operation: opts.lowerCase ? HAS_TO_LOWER_CASE : HAS,
100
+ type: op === '!has' ? TYPE_NEGATE : TYPE_DEFAULT,
101
+ opts,
102
+ };
103
+ }
104
+ if (op === '>') {
105
+ return { operation: GREATER_THAN, opts, type: TYPE_DEFAULT };
106
+ }
107
+ if (op === '<') {
108
+ return { operation: SMALLER_THAN, opts, type: TYPE_DEFAULT };
109
+ }
110
+ if (op === '>=') {
111
+ return { operation: GREATER_THAN_INCLUSIVE, opts, type: TYPE_DEFAULT };
112
+ }
113
+ if (op === '<=') {
114
+ return { operation: SMALLER_THAN_INCLUSIVE, opts, type: TYPE_DEFAULT };
115
+ }
116
+ if (op === 'like') {
117
+ return { operation: LIKE, opts, type: TYPE_DEFAULT };
118
+ }
119
+ throw new Error('Invalid filter operator');
120
+ };
7
121
  //# sourceMappingURL=types.js.map
@@ -1,6 +1,8 @@
1
1
  import { PropDef, PropDefEdge } from '../../../server/schema/types.js';
2
2
  import { QueryDef } from '../types.js';
3
3
  export declare const getAll: (props: QueryDef["props"]) => string[];
4
+ export declare const getAllRefs: (props: QueryDef["props"], affix?: string) => string[];
5
+ export declare const includeField: (def: QueryDef, field: string) => void;
4
6
  export declare const includeFields: (def: QueryDef, fields: string[]) => void;
5
7
  export declare const includeAllProps: (def: QueryDef) => void;
6
8
  export declare const includeProp: (def: QueryDef, prop: PropDef | PropDefEdge) => boolean;
@@ -9,14 +9,33 @@ export const getAll = (props) => {
9
9
  }
10
10
  return fields;
11
11
  };
12
+ export const getAllRefs = (props, affix = '') => {
13
+ const fields = [];
14
+ for (const key in props) {
15
+ const prop = props[key];
16
+ if (prop.typeIndex === REFERENCE || prop.typeIndex === REFERENCES) {
17
+ fields.push(prop.path.join('.') + affix);
18
+ }
19
+ }
20
+ return fields;
21
+ };
22
+ export const includeField = (def, field) => {
23
+ if (field === '*') {
24
+ includeFields(def, getAll(def.props));
25
+ }
26
+ else if (field === '**') {
27
+ includeFields(def, getAllRefs(def.props));
28
+ }
29
+ else if (field.startsWith('**.')) {
30
+ includeFields(def, getAllRefs(def.props, field.substring(2)));
31
+ }
32
+ else {
33
+ def.include.stringFields.add(field);
34
+ }
35
+ };
12
36
  export const includeFields = (def, fields) => {
13
37
  for (const field of fields) {
14
- if (field === '*') {
15
- includeFields(def, getAll(def.props));
16
- }
17
- else {
18
- def.include.stringFields.add(field);
19
- }
38
+ includeField(def, field);
20
39
  }
21
40
  };
22
41
  export const includeAllProps = (def) => {
@@ -5,7 +5,8 @@ export const includeToBuffer = (db, def) => {
5
5
  if (!def.include.stringFields.size &&
6
6
  !def.include.props.size &&
7
7
  !def.references.size &&
8
- !def.include.main.len) {
8
+ !def.include.main.len &&
9
+ !def.include.langTextFields.size) {
9
10
  return result;
10
11
  }
11
12
  let mainBuffer;
@@ -46,6 +47,25 @@ export const includeToBuffer = (db, def) => {
46
47
  }
47
48
  }
48
49
  }
50
+ if (def.include.langTextFields.size) {
51
+ for (const [prop, langCode] of def.include.langTextFields.entries()) {
52
+ def.include.propsRead[prop] = 0;
53
+ if (langCode.has(0)) {
54
+ const b = Buffer.allocUnsafe(2);
55
+ b[0] = prop;
56
+ b[1] = 0;
57
+ result.push(b);
58
+ }
59
+ else {
60
+ for (const code of langCode) {
61
+ const b = Buffer.allocUnsafe(2);
62
+ b[0] = prop;
63
+ b[1] = code;
64
+ result.push(b);
65
+ }
66
+ }
67
+ }
68
+ }
49
69
  const propSize = def.include.props.size ?? 0;
50
70
  if (mainBuffer) {
51
71
  len = mainBuffer.byteLength + 3 + propSize;
@@ -1,8 +1,9 @@
1
- import { isPropDef, REFERENCE, REFERENCES, } from '../../../server/schema/types.js';
1
+ import { isPropDef, REFERENCE, REFERENCES, TEXT, } from '../../../server/schema/types.js';
2
2
  import { createQueryDef } from '../queryDef.js';
3
3
  import { isRefDef, QueryDefType } from '../types.js';
4
4
  import { getAllFieldFromObject, createOrGetRefQueryDef } from './utils.js';
5
5
  import { includeFields, includeProp, includeAllProps } from './props.js';
6
+ import { langCodesMap } from '@based/schema';
6
7
  export const walkDefs = (db, def, f) => {
7
8
  const prop = def.props[f];
8
9
  const path = f.split('.');
@@ -41,7 +42,15 @@ export const walkDefs = (db, def, f) => {
41
42
  if (!t) {
42
43
  return;
43
44
  }
44
- if (isPropDef(t) &&
45
+ if (isPropDef(t) && t.typeIndex === TEXT) {
46
+ const langCode = langCodesMap.get(path[path.length - 1]);
47
+ if (!def.include.langTextFields.has(t.prop)) {
48
+ def.include.langTextFields.set(t.prop, new Set());
49
+ }
50
+ def.include.langTextFields.get(t.prop).add(langCode);
51
+ return;
52
+ }
53
+ else if (isPropDef(t) &&
45
54
  (t.typeIndex === REFERENCE || t.typeIndex === REFERENCES)) {
46
55
  const refDef = createOrGetRefQueryDef(db, def, t);
47
56
  const f = path.slice(i + 1).join('.');
@@ -64,6 +73,12 @@ export const walkDefs = (db, def, f) => {
64
73
  includeAllProps(refDef);
65
74
  return;
66
75
  }
76
+ else if (prop.typeIndex === TEXT) {
77
+ if (!def.include.langTextFields.has(prop.prop)) {
78
+ def.include.langTextFields.set(prop.prop, new Set());
79
+ }
80
+ def.include.langTextFields.get(prop.prop).add(def.lang ?? 0);
81
+ }
67
82
  else {
68
83
  includeProp(def, prop);
69
84
  }
@@ -7,6 +7,7 @@ const createEmptySharedDef = () => {
7
7
  range: { offset: 0, limit: 0 },
8
8
  lang: langCodesMap.get('none'),
9
9
  include: {
10
+ langTextFields: new Map(),
10
11
  stringFields: new Set(),
11
12
  props: new Set(),
12
13
  propsRead: {},
@@ -1,7 +1,7 @@
1
- import { ALIAS, ALIASES, BINARY, BOOLEAN, ENUM, INT16, INT32, INT8, NUMBER, STRING, TEXT, TIMESTAMP, UINT16, UINT32, UINT8, VECTOR, } from '../../../server/schema/types.js';
1
+ import { ALIAS, ALIASES, BINARY, BOOLEAN, ENUM, INT16, INT32, INT8, NUMBER, STRING, TEXT, TIMESTAMP, UINT16, UINT32, UINT8, VECTOR, JSON, } from '../../../server/schema/types.js';
2
2
  import { read, readUtf8 } from '../../string.js';
3
3
  import { readDoubleLE, readFloatLE, readInt16, readInt32, readUint16, readUint32, } from '../../bitWise.js';
4
- import { inverseLangMap, langCodesMap } from '@based/schema';
4
+ import { inverseLangMap } from '@based/schema';
5
5
  const addField = (p, value, item, defaultOnly = false, lang = 0) => {
6
6
  let i = p.__isEdge === true ? 1 : 0;
7
7
  // TODO OPTMIZE
@@ -28,6 +28,35 @@ const addField = (p, value, item, defaultOnly = false, lang = 0) => {
28
28
  }
29
29
  }
30
30
  };
31
+ const getEmptyField = (p, item) => {
32
+ let i = p.__isEdge === true ? 1 : 0;
33
+ const path = p.path;
34
+ const len = path.length;
35
+ let select = item;
36
+ if (len - i === 1) {
37
+ const field = path[i];
38
+ if (!(field in item)) {
39
+ select = item[field] = {};
40
+ }
41
+ else {
42
+ return item[field];
43
+ }
44
+ }
45
+ else {
46
+ for (; i < len; i++) {
47
+ const field = path[i];
48
+ if (i === len - 1) {
49
+ if (!(field in select)) {
50
+ select = select[field] = {};
51
+ }
52
+ }
53
+ else {
54
+ select = select[field] ?? (select[field] = {});
55
+ }
56
+ }
57
+ }
58
+ return select;
59
+ };
31
60
  const readMainValue = (prop, result, index, item) => {
32
61
  // 1: timestamp, 4: number
33
62
  if (prop.typeIndex === TIMESTAMP || prop.typeIndex === NUMBER) {
@@ -52,7 +81,7 @@ const readMainValue = (prop, result, index, item) => {
52
81
  }
53
82
  // 11: string
54
83
  else if (prop.typeIndex === STRING) {
55
- // Also remove this default then (same as other string)
84
+ // Also delete this default then (same as other string)
56
85
  const len = result[index];
57
86
  if (len !== 0) {
58
87
  const str = readUtf8(result, index + 1, len);
@@ -62,6 +91,10 @@ const readMainValue = (prop, result, index, item) => {
62
91
  addField(prop, '', item);
63
92
  }
64
93
  }
94
+ // ?: json
95
+ else if (prop.typeIndex === JSON) {
96
+ addField(prop, global.JSON.parse(Buffer.from(result.subarray(index + 1, index + 1 + result[index])).toString()), item);
97
+ }
65
98
  // 25: binary
66
99
  else if (prop.typeIndex === BINARY) {
67
100
  addField(prop, result.subarray(index + 1, index + 1 + result[index]), item);
@@ -109,7 +142,29 @@ const readMain = (q, result, offset, item) => {
109
142
  const handleUndefinedProps = (id, q, item) => {
110
143
  for (const k in q.include.propsRead) {
111
144
  if (q.include.propsRead[k] !== id) {
112
- addField(q.schema.reverseProps[k], '', item);
145
+ const prop = q.schema.reverseProps[k];
146
+ if (prop.typeIndex === TEXT && q.lang == 0) {
147
+ const lan = getEmptyField(prop, item);
148
+ const lang = q.include.langTextFields.get(prop.prop);
149
+ if (lang.has(0)) {
150
+ for (const locale in q.schema.locales) {
151
+ if (!lan[locale]) {
152
+ lan[locale] = '';
153
+ }
154
+ }
155
+ }
156
+ else {
157
+ for (const code of lang) {
158
+ const locale = inverseLangMap.get(code);
159
+ if (!lan[locale]) {
160
+ lan[locale] = '';
161
+ }
162
+ }
163
+ }
164
+ }
165
+ else {
166
+ addField(prop, prop.typeIndex === JSON ? null : '', item);
167
+ }
113
168
  }
114
169
  }
115
170
  };
@@ -118,12 +173,15 @@ export const readAllFields = (q, result, offset, end, item, id) => {
118
173
  while (i < end) {
119
174
  const index = result[i];
120
175
  i++;
176
+ // index:255 id
121
177
  if (index === 255) {
122
178
  handleUndefinedProps(id, q, item);
123
179
  return i - offset;
124
180
  }
181
+ // index:252 edge
125
182
  if (index === 252) {
126
183
  let prop = result[i];
184
+ // index:254 ref
127
185
  if (prop === 254) {
128
186
  i++;
129
187
  const field = result[i];
@@ -148,6 +206,7 @@ export const readAllFields = (q, result, offset, end, item, id) => {
148
206
  addField(ref.target.propDef, refItem, item);
149
207
  i += size - 5;
150
208
  }
209
+ // index:253 refs
151
210
  }
152
211
  else if (prop === 253) {
153
212
  i++;
@@ -165,7 +224,13 @@ export const readAllFields = (q, result, offset, end, item, id) => {
165
224
  else {
166
225
  const edgeDef = q.edges.reverseProps[prop];
167
226
  const t = edgeDef.typeIndex;
168
- if (t === BINARY) {
227
+ if (t === JSON) {
228
+ i++;
229
+ const size = readUint32(result, i);
230
+ addField(edgeDef, global.JSON.parse(Buffer.from(result.subarray(i + 6, size + i)).toString()), item);
231
+ i += size + 4;
232
+ }
233
+ else if (t === BINARY) {
169
234
  i++;
170
235
  const size = readUint32(result, i);
171
236
  addField(edgeDef, result.subarray(i + 6, size + i), item);
@@ -188,6 +253,7 @@ export const readAllFields = (q, result, offset, end, item, id) => {
188
253
  i += edgeDef.len;
189
254
  }
190
255
  }
256
+ // index:254 ref
191
257
  }
192
258
  else if (index === 254) {
193
259
  const field = result[i];
@@ -212,6 +278,7 @@ export const readAllFields = (q, result, offset, end, item, id) => {
212
278
  addField(ref.target.propDef, refItem, item);
213
279
  i += size - 5;
214
280
  }
281
+ // index:253 refs
215
282
  }
216
283
  else if (index === 253) {
217
284
  const field = result[i];
@@ -229,7 +296,13 @@ export const readAllFields = (q, result, offset, end, item, id) => {
229
296
  }
230
297
  else {
231
298
  const prop = q.schema.reverseProps[index];
232
- if (prop.typeIndex === BINARY) {
299
+ if (prop.typeIndex === JSON) {
300
+ q.include.propsRead[index] = id;
301
+ const size = readUint32(result, i);
302
+ addField(prop, global.JSON.parse(Buffer.from(result.subarray(i + 6, i + size)).toString()), item);
303
+ i += size + 4;
304
+ }
305
+ else if (prop.typeIndex === BINARY) {
233
306
  q.include.propsRead[index] = id;
234
307
  const size = readUint32(result, i);
235
308
  addField(prop, result.subarray(i + 6, i + size), item);
@@ -247,29 +320,20 @@ export const readAllFields = (q, result, offset, end, item, id) => {
247
320
  i += size + 4;
248
321
  }
249
322
  else if (prop.typeIndex == TEXT) {
250
- q.include.propsRead[index] = id;
251
323
  const size = readUint32(result, i);
252
- // if queryDef.LANG do different
253
324
  if (size === 0) {
254
- // LATER
255
- // addField(prop, '', item)
256
325
  }
257
326
  else {
258
- if (q.lang != langCodesMap.get('none')) {
327
+ if (q.lang != 0) {
328
+ q.include.propsRead[index] = id;
259
329
  addField(prop, read(result, i + 4, size), item);
260
330
  }
261
331
  else {
332
+ // q.include.propsRead[index] = id
262
333
  addField(prop, read(result, i + 4, size), item, false, result[i + 4]);
263
334
  }
264
335
  }
265
- const lan =
266
- // TODO Read text
267
- //if (size === 0) {
268
- // addField(prop, '', item)
269
- //} else {
270
- // addField(prop, read(result, i + 4, size), item)
271
- //}
272
- (i += size + 4);
336
+ i += size + 4;
273
337
  }
274
338
  else if (prop.typeIndex === ALIAS) {
275
339
  q.include.propsRead[index] = id;
@@ -314,8 +378,8 @@ export const resultToObject = (q, result, end, offset = 0) => {
314
378
  id,
315
379
  };
316
380
  if (q.search) {
317
- item.$searchScore = result[i];
318
- i += 1;
381
+ item.$searchScore = readFloatLE(result, i);
382
+ i += 4;
319
383
  }
320
384
  const l = readAllFields(q, result, i, end, item, id);
321
385
  i += l;
@@ -1,6 +1,8 @@
1
1
  import { QueryDefSearch, QueryDef } from '../types.js';
2
+ import { FilterOpts } from '../filter/types.js';
2
3
  export type Search = string[] | {
3
4
  [field: string]: number;
4
5
  } | string;
6
+ export declare const vectorSearch: (def: QueryDef, q: ArrayBufferView, field: string, opts: Omit<FilterOpts, "lowerCase">) => void;
5
7
  export declare const search: (def: QueryDef, q: string, s?: Search) => void;
6
8
  export declare const searchToBuffer: (search: QueryDefSearch) => Buffer;