@based/db 0.0.28 → 0.0.30

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 (115) hide show
  1. package/README.md +1 -399
  2. package/dist/lib/darwin_aarch64/include/selva/db.h +8 -4
  3. package/dist/lib/darwin_aarch64/include/selva/fields.h +10 -2
  4. package/dist/lib/darwin_aarch64/include/selva/selva_hash128.h +17 -7
  5. package/dist/lib/darwin_aarch64/include/selva/sort.h +21 -14
  6. package/dist/lib/darwin_aarch64/libdeflate.dylib +0 -0
  7. package/dist/lib/darwin_aarch64/libjemalloc_selva.2.dylib +0 -0
  8. package/dist/lib/darwin_aarch64/libnode-v20.node +0 -0
  9. package/dist/lib/darwin_aarch64/libnode-v21.node +0 -0
  10. package/dist/lib/darwin_aarch64/libnode-v22.node +0 -0
  11. package/dist/lib/darwin_aarch64/libnode-v23.node +0 -0
  12. package/dist/lib/darwin_aarch64/libselva.dylib +0 -0
  13. package/dist/lib/darwin_aarch64/libxxhash.dylib +0 -0
  14. package/dist/lib/linux_aarch64/include/selva/db.h +8 -4
  15. package/dist/lib/linux_aarch64/include/selva/fields.h +10 -2
  16. package/dist/lib/linux_aarch64/include/selva/selva_hash128.h +17 -7
  17. package/dist/lib/linux_aarch64/include/selva/sort.h +21 -14
  18. package/dist/lib/linux_aarch64/libdeflate.so +0 -0
  19. package/dist/lib/linux_aarch64/libjemalloc_selva.so.2 +0 -0
  20. package/dist/lib/linux_aarch64/libnode-v20.node +0 -0
  21. package/dist/lib/linux_aarch64/libnode-v21.node +0 -0
  22. package/dist/lib/linux_aarch64/libnode-v22.node +0 -0
  23. package/dist/lib/linux_aarch64/libnode-v23.node +0 -0
  24. package/dist/lib/linux_aarch64/libselva.so +0 -0
  25. package/dist/lib/linux_x86_64/include/selva/db.h +8 -4
  26. package/dist/lib/linux_x86_64/include/selva/fields.h +10 -2
  27. package/dist/lib/linux_x86_64/include/selva/selva_hash128.h +17 -7
  28. package/dist/lib/linux_x86_64/include/selva/sort.h +21 -14
  29. package/dist/lib/linux_x86_64/libjemalloc_selva.so.2 +0 -0
  30. package/dist/lib/linux_x86_64/libnode-v20.node +0 -0
  31. package/dist/lib/linux_x86_64/libnode-v21.node +0 -0
  32. package/dist/lib/linux_x86_64/libnode-v22.node +0 -0
  33. package/dist/lib/linux_x86_64/libnode-v23.node +0 -0
  34. package/dist/lib/linux_x86_64/libselva.so +0 -0
  35. package/dist/src/client/flushModify.d.ts +1 -1
  36. package/dist/src/client/flushModify.js +15 -19
  37. package/dist/src/client/index.d.ts +8 -10
  38. package/dist/src/client/index.js +19 -8
  39. package/dist/src/client/modify/ModifyRes.d.ts +2 -4
  40. package/dist/src/client/modify/ModifyRes.js +15 -21
  41. package/dist/src/client/modify/create.js +1 -2
  42. package/dist/src/client/modify/delete.js +1 -2
  43. package/dist/src/client/modify/fixed.js +43 -8
  44. package/dist/src/client/modify/modify.js +0 -5
  45. package/dist/src/client/modify/references/{appendRefs.d.ts → appendEdgeRefs.d.ts} +1 -1
  46. package/dist/src/client/modify/references/{appendRefs.js → appendEdgeRefs.js} +5 -2
  47. package/dist/src/client/modify/references/edge.js +182 -175
  48. package/dist/src/client/modify/references/reference.js +4 -8
  49. package/dist/src/client/modify/references/references.js +18 -14
  50. package/dist/src/client/modify/setCursor.js +1 -1
  51. package/dist/src/client/modify/string.js +0 -3
  52. package/dist/src/client/modify/text.js +11 -3
  53. package/dist/src/client/modify/types.d.ts +11 -0
  54. package/dist/src/client/modify/types.js +10 -0
  55. package/dist/src/client/modify/update.js +5 -3
  56. package/dist/src/client/modify/vector.js +13 -4
  57. package/dist/src/client/query/BasedDbQuery.d.ts +1 -1
  58. package/dist/src/client/query/BasedDbQuery.js +2 -2
  59. package/dist/src/client/query/BasedIterable.d.ts +1 -1
  60. package/dist/src/client/query/BasedIterable.js +7 -2
  61. package/dist/src/client/query/filter/createFixedFilterBuffer.d.ts +2 -1
  62. package/dist/src/client/query/filter/createFixedFilterBuffer.js +11 -28
  63. package/dist/src/client/query/filter/createReferenceFilter.d.ts +2 -1
  64. package/dist/src/client/query/filter/createReferenceFilter.js +10 -9
  65. package/dist/src/client/query/filter/createVariableFilterBuffer.d.ts +2 -1
  66. package/dist/src/client/query/filter/createVariableFilterBuffer.js +8 -10
  67. package/dist/src/client/query/filter/parseFilterValue.js +1 -1
  68. package/dist/src/client/query/filter/primitiveFilter.js +9 -9
  69. package/dist/src/client/query/filter/toBuffer.js +0 -15
  70. package/dist/src/client/query/filter/types.d.ts +1 -0
  71. package/dist/src/client/query/filter/types.js +1 -0
  72. package/dist/src/client/query/include/walk.js +0 -1
  73. package/dist/src/client/query/read/read.js +16 -7
  74. package/dist/src/client/query/search/index.js +11 -15
  75. package/dist/src/client/query/subscription/index.d.ts +1 -2
  76. package/dist/src/client/query/subscription/index.js +3 -50
  77. package/dist/src/client/query/subscription/markers.js +1 -2
  78. package/dist/src/client/query/subscription/run.js +0 -2
  79. package/dist/src/client/query/subscription/types.d.ts +1 -29
  80. package/dist/src/client/query/subscription/types.js +8 -1
  81. package/dist/src/client/query/thresholds.d.ts +0 -2
  82. package/dist/src/client/query/thresholds.js +0 -2
  83. package/dist/src/client/query/toBuffer.js +16 -42
  84. package/dist/src/client/query/types.d.ts +3 -2
  85. package/dist/src/client/query/validation.d.ts +1 -3
  86. package/dist/src/client/query/validation.js +6 -18
  87. package/dist/src/client/string.d.ts +2 -0
  88. package/dist/src/client/string.js +10 -14
  89. package/dist/src/index.d.ts +1 -1
  90. package/dist/src/index.js +11 -15
  91. package/dist/src/native.d.ts +3 -3
  92. package/dist/src/native.js +6 -4
  93. package/dist/src/server/csmt/draw-dot.js +2 -2
  94. package/dist/src/server/csmt/tree.js +57 -6
  95. package/dist/src/server/csmt/types.d.ts +5 -0
  96. package/dist/src/server/index.d.ts +4 -3
  97. package/dist/src/server/index.js +44 -44
  98. package/dist/src/server/migrate/index.js +47 -29
  99. package/dist/src/server/migrate/worker.js +2 -2
  100. package/dist/src/server/save.js +40 -28
  101. package/dist/src/server/start.js +7 -19
  102. package/dist/src/server/tree.d.ts +2 -0
  103. package/dist/src/server/tree.js +34 -2
  104. package/dist/src/server/worker.js +3 -3
  105. package/dist/src/utils.d.ts +3 -1
  106. package/dist/src/utils.js +43 -19
  107. package/package.json +9 -3
  108. package/dist/lib/darwin_aarch64/include/selva/base64.h +0 -59
  109. package/dist/lib/darwin_aarch64/include/selva/base64url.h +0 -59
  110. package/dist/lib/linux_aarch64/include/selva/base64.h +0 -59
  111. package/dist/lib/linux_aarch64/include/selva/base64url.h +0 -59
  112. package/dist/lib/linux_x86_64/include/selva/base64.h +0 -59
  113. package/dist/lib/linux_x86_64/include/selva/base64url.h +0 -59
  114. package/dist/src/client/timestamp.d.ts +0 -1
  115. package/dist/src/client/timestamp.js +0 -68
@@ -1,6 +1,6 @@
1
1
  import { ENCODER } from '../../index.js';
2
2
  import { BINARY, BOOLEAN, ENUM, INT16, INT32, INT8, NUMBER, STRING, TIMESTAMP, UINT16, UINT32, UINT8, } from '@based/schema/def';
3
- import { convertToTimestamp } from '../timestamp.js';
3
+ import { convertToTimestamp } from '@saulx/utils';
4
4
  import { getBuffer } from './binary.js';
5
5
  import { ModifyError } from './ModifyRes.js';
6
6
  import { RANGE_ERR } from './types.js';
@@ -10,6 +10,9 @@ map[BINARY] = (ctx, val, def) => {
10
10
  if (buf === undefined) {
11
11
  return new ModifyError(def, val);
12
12
  }
13
+ if (!def.validation(val, def)) {
14
+ return new ModifyError(def, val);
15
+ }
13
16
  const size = buf.byteLength;
14
17
  if (ctx.len + size + 1 > ctx.max) {
15
18
  return RANGE_ERR;
@@ -24,17 +27,27 @@ map[STRING] = (ctx, val, def) => {
24
27
  if (size + 1 > def.len) {
25
28
  return new ModifyError(def, val, `max length of ${def.len - 1},`);
26
29
  }
30
+ if (!def.validation(val, def)) {
31
+ return new ModifyError(def, val);
32
+ }
27
33
  if (ctx.len + size + 1 > ctx.max) {
28
34
  return RANGE_ERR;
29
35
  }
30
36
  ctx.buf[ctx.len++] = size;
31
37
  ctx.buf.set(valBuf, ctx.len);
32
- ctx.len += size;
38
+ const fullSize = def.len - 1;
39
+ ctx.len += fullSize;
40
+ if (fullSize !== size) {
41
+ ctx.buf.fill(0, ctx.len - (fullSize - size), ctx.len);
42
+ }
33
43
  };
34
44
  map[BOOLEAN] = (ctx, val, def) => {
35
45
  if (ctx.len + 1 > ctx.max) {
36
46
  return RANGE_ERR;
37
47
  }
48
+ if (!def.validation(val, def)) {
49
+ return new ModifyError(def, val);
50
+ }
38
51
  if (val === null) {
39
52
  ctx.buf[ctx.len++] = 0;
40
53
  }
@@ -49,6 +62,9 @@ map[ENUM] = (ctx, val, def) => {
49
62
  if (ctx.len + 1 > ctx.max) {
50
63
  return RANGE_ERR;
51
64
  }
65
+ if (!def.validation(val, def)) {
66
+ return new ModifyError(def, val);
67
+ }
52
68
  if (val === null) {
53
69
  ctx.buf[ctx.len++] = 0;
54
70
  }
@@ -63,6 +79,9 @@ map[NUMBER] = (ctx, val, def) => {
63
79
  if (ctx.len + 8 > ctx.max) {
64
80
  return RANGE_ERR;
65
81
  }
82
+ if (!def.validation(val, def)) {
83
+ return new ModifyError(def, val);
84
+ }
66
85
  const view = new DataView(ctx.buf.buffer, ctx.buf.byteOffset + ctx.len, 8);
67
86
  ctx.len += 8;
68
87
  view.setFloat64(0, val, true);
@@ -72,14 +91,21 @@ map[TIMESTAMP] = (ctx, val, def) => {
72
91
  if (ctx.len + 8 > ctx.max) {
73
92
  return RANGE_ERR;
74
93
  }
94
+ if (!def.validation(parsedValue, def)) {
95
+ return new ModifyError(def, val);
96
+ }
75
97
  const view = new DataView(ctx.buf.buffer, ctx.buf.byteOffset + ctx.len, 8);
76
98
  ctx.len += 8;
77
99
  view.setFloat64(0, parsedValue, true);
100
+ const ts = view.getFloat64(0);
78
101
  };
79
102
  map[UINT32] = (ctx, val, def) => {
80
103
  if (ctx.len + 4 > ctx.max) {
81
104
  return RANGE_ERR;
82
105
  }
106
+ if (!def.validation(val, def)) {
107
+ return new ModifyError(def, val);
108
+ }
83
109
  ctx.buf[ctx.len++] = val;
84
110
  ctx.buf[ctx.len++] = val >>>= 8;
85
111
  ctx.buf[ctx.len++] = val >>>= 8;
@@ -89,6 +115,9 @@ map[UINT16] = (ctx, val, def) => {
89
115
  if (ctx.len + 2 > ctx.max) {
90
116
  return RANGE_ERR;
91
117
  }
118
+ if (!def.validation(val, def)) {
119
+ return new ModifyError(def, val);
120
+ }
92
121
  ctx.buf[ctx.len++] = val;
93
122
  ctx.buf[ctx.len++] = val >>>= 8;
94
123
  };
@@ -96,12 +125,18 @@ map[UINT8] = (ctx, val, def) => {
96
125
  if (ctx.len + 1 > ctx.max) {
97
126
  return RANGE_ERR;
98
127
  }
128
+ if (!def.validation(val, def)) {
129
+ return new ModifyError(def, val);
130
+ }
99
131
  ctx.buf[ctx.len++] = val;
100
132
  };
101
133
  map[INT32] = (ctx, val, def) => {
102
134
  if (ctx.len + 4 > ctx.max) {
103
135
  return RANGE_ERR;
104
136
  }
137
+ if (!def.validation(val, def)) {
138
+ return new ModifyError(def, val);
139
+ }
105
140
  ctx.buf[ctx.len++] = val;
106
141
  ctx.buf[ctx.len++] = val >>>= 8;
107
142
  ctx.buf[ctx.len++] = val >>>= 8;
@@ -111,6 +146,9 @@ map[INT16] = (ctx, val, def) => {
111
146
  if (ctx.len + 2 > ctx.max) {
112
147
  return RANGE_ERR;
113
148
  }
149
+ if (!def.validation(val, def)) {
150
+ return new ModifyError(def, val);
151
+ }
114
152
  ctx.buf[ctx.len++] = val;
115
153
  ctx.buf[ctx.len++] = val >>>= 8;
116
154
  };
@@ -118,12 +156,12 @@ map[INT8] = (ctx, val, def) => {
118
156
  if (ctx.len + 1 > ctx.max) {
119
157
  return RANGE_ERR;
120
158
  }
121
- ctx.buf[ctx.len++] = val;
122
- };
123
- export const writeFixedValue = (ctx, val, def, pos) => {
124
159
  if (!def.validation(val, def)) {
125
160
  return new ModifyError(def, val);
126
161
  }
162
+ ctx.buf[ctx.len++] = val;
163
+ };
164
+ export const writeFixedValue = (ctx, val, def, pos) => {
127
165
  const len = ctx.len;
128
166
  ctx.len = pos;
129
167
  const res = map[def.typeIndex](ctx, val, def);
@@ -131,9 +169,6 @@ export const writeFixedValue = (ctx, val, def, pos) => {
131
169
  return res;
132
170
  };
133
171
  export const appendFixedValue = (ctx, val, def) => {
134
- if (!def.validation(val, def)) {
135
- return new ModifyError(def, val);
136
- }
137
172
  return map[def.typeIndex](ctx, val, def);
138
173
  };
139
174
  //# sourceMappingURL=fixed.js.map
@@ -11,7 +11,6 @@ import { appendFixedValue, writeFixedValue } from './fixed.js';
11
11
  import { writeAlias } from './alias.js';
12
12
  import { writeHll } from './cardinality.js';
13
13
  import { writeVector } from './vector.js';
14
- import { checkSubscriptionMarkers } from '../query/subscription/index.js';
15
14
  import { writeJson } from './json.js';
16
15
  function _modify(ctx, res, obj, schema, mod, tree, overwrite, unsafe) {
17
16
  for (const key in obj) {
@@ -28,9 +27,6 @@ function _modify(ctx, res, obj, schema, mod, tree, overwrite, unsafe) {
28
27
  if (val === undefined) {
29
28
  continue;
30
29
  }
31
- if (res.subMarkers) {
32
- checkSubscriptionMarkers(ctx.db, res.subMarkers, def);
33
- }
34
30
  const type = def.typeIndex;
35
31
  if (def.separate) {
36
32
  if (type === STRING) {
@@ -77,7 +73,6 @@ function _modify(ctx, res, obj, schema, mod, tree, overwrite, unsafe) {
77
73
  ctx.lastMain = ctx.len;
78
74
  ctx.buf.set(schema.mainEmpty, ctx.len);
79
75
  ctx.len += schema.mainLen;
80
- // ctx.buf.fill(0, ctx.len, (ctx.len += schema.mainLen))
81
76
  }
82
77
  if (typeof val === 'object' && val !== null && 'increment' in val) {
83
78
  err = writeFixedValue(ctx, val.increment, def, ctx.lastMain + def.start);
@@ -1,4 +1,4 @@
1
1
  import { PropDefEdge } from '@based/schema/def';
2
2
  import { ModifyCtx } from '../../flushModify.js';
3
3
  import { ModifyErr } from '../types.js';
4
- export declare function appendRefs(t: PropDefEdge, ctx: ModifyCtx, value: any[]): ModifyErr;
4
+ export declare function appendEdgeRefs(t: PropDefEdge, ctx: ModifyCtx, value: any[]): ModifyErr;
@@ -1,5 +1,5 @@
1
1
  import { ModifyState, ModifyError } from '../ModifyRes.js';
2
- export function appendRefs(t, ctx, value) {
2
+ export function appendEdgeRefs(t, ctx, value) {
3
3
  for (let i = 0; i < value.length; i++) {
4
4
  let id = value[i];
5
5
  if (typeof id !== 'number') {
@@ -13,6 +13,9 @@ export function appendRefs(t, ctx, value) {
13
13
  return new ModifyError(t, value);
14
14
  }
15
15
  }
16
+ if (!t.validation(id, t)) {
17
+ return new ModifyError(t, value);
18
+ }
16
19
  if (id > 0) {
17
20
  ctx.buf[ctx.len++] = id;
18
21
  ctx.buf[ctx.len++] = id >>>= 8;
@@ -24,4 +27,4 @@ export function appendRefs(t, ctx, value) {
24
27
  }
25
28
  }
26
29
  }
27
- //# sourceMappingURL=appendRefs.js.map
30
+ //# sourceMappingURL=appendEdgeRefs.js.map
@@ -6,7 +6,7 @@ import { getBuffer, writeBinaryRaw } from '../binary.js';
6
6
  import { ModifyError, ModifyState } from '../ModifyRes.js';
7
7
  import { DECREMENT, INCREMENT, RANGE_ERR, UPDATE, UPDATE_PARTIAL, } from '../types.js';
8
8
  import { appendFixedValue } from '../fixed.js';
9
- import { appendRefs } from './appendRefs.js';
9
+ import { appendEdgeRefs } from './appendEdgeRefs.js';
10
10
  function valueOperation(value) {
11
11
  if (typeof value === 'object' && value !== null) {
12
12
  if (value.increment > 0) {
@@ -24,172 +24,194 @@ export function writeEdges(t, ref, ctx) {
24
24
  let mainFields;
25
25
  let mainSize = 0;
26
26
  let hasIncr = false;
27
- for (const key in t.edges) {
28
- if (key in ref) {
29
- const edge = t.edges[key];
30
- let value = ref[key];
31
- if (edge.separate === true) {
32
- if (ctx.len + 2 > ctx.max) {
33
- return RANGE_ERR;
27
+ for (const key in ref) {
28
+ if (key === 'id' || key === '$index') {
29
+ continue;
30
+ }
31
+ const edge = t.edges?.[key];
32
+ if (!edge) {
33
+ return new ModifyError(t, key, `Does not exist`);
34
+ }
35
+ let value = ref[key];
36
+ if (edge.separate === true) {
37
+ if (ctx.len + 2 > ctx.max) {
38
+ return RANGE_ERR;
39
+ }
40
+ ctx.buf[ctx.len++] = UPDATE;
41
+ ctx.buf[ctx.len++] = edge.prop;
42
+ /*
43
+ Seperate fields:
44
+
45
+ | Offset | Field | Size (bytes)| Description |
46
+ |---------|-------------|-------------|---------------------------------------|
47
+ | 0 | modify op | 1 | Modify operation identifier |
48
+ | 1 | prop | 1 | Field identifier |
49
+ | 2 | type | 1 | Indicates MICRO_BUFFER type |
50
+ | 3 | size | 4 | Size of the data in bytes |
51
+ | 7 | data | Variable | Content |
52
+ */
53
+ if (edge.typeIndex === BINARY) {
54
+ let size = 0;
55
+ // add null
56
+ if (value === null) {
57
+ size = 0;
34
58
  }
35
- ctx.buf[ctx.len++] = UPDATE;
36
- ctx.buf[ctx.len++] = edge.prop;
37
- /*
38
- Seperate fields:
39
-
40
- | Offset | Field | Size (bytes)| Description |
41
- |---------|-------------|-------------|---------------------------------------|
42
- | 0 | modify op | 1 | Modify operation identifier |
43
- | 1 | prop | 1 | Field identifier |
44
- | 2 | type | 1 | Indicates MICRO_BUFFER type |
45
- | 3 | size | 4 | Size of the data in bytes |
46
- | 7 | data | Variable | Content |
47
- */
48
- if (edge.typeIndex === BINARY) {
49
- let size = 0;
50
- if (value === null) {
51
- size = 0;
52
- }
53
- else {
54
- const buf = getBuffer(value);
55
- if (!buf) {
56
- return new ModifyError(edge, value);
57
- }
58
- size = buf.byteLength;
59
- }
60
- if (ctx.len + EDGE_HEADER_SIZE + size > ctx.max) {
61
- return RANGE_ERR;
62
- }
63
- ctx.buf[ctx.len++] = STRING;
64
- if (size) {
65
- writeBinaryRaw(value, ctx);
66
- }
67
- else {
68
- ctx.buf[ctx.len++] = 0;
69
- ctx.buf[ctx.len++] = 0;
70
- ctx.buf[ctx.len++] = 0;
71
- ctx.buf[ctx.len++] = 0;
59
+ else {
60
+ const buf = getBuffer(value);
61
+ if (!buf || !edge.validation(buf, edge)) {
62
+ return new ModifyError(edge, value);
72
63
  }
64
+ size = buf.byteLength;
65
+ value = buf;
66
+ }
67
+ if (ctx.len + EDGE_HEADER_SIZE + size > ctx.max) {
68
+ return RANGE_ERR;
69
+ }
70
+ ctx.buf[ctx.len++] = STRING;
71
+ if (size) {
72
+ writeBinaryRaw(value, ctx);
73
+ }
74
+ else {
75
+ ctx.buf[ctx.len++] = 0;
76
+ ctx.buf[ctx.len++] = 0;
77
+ ctx.buf[ctx.len++] = 0;
78
+ ctx.buf[ctx.len++] = 0;
73
79
  }
74
- else if (edge.typeIndex === STRING) {
75
- if (typeof value !== 'string') {
80
+ }
81
+ else if (edge.typeIndex === STRING) {
82
+ let size = 0;
83
+ // add null
84
+ if (value !== null) {
85
+ if (!edge.validation(value, edge)) {
76
86
  return new ModifyError(edge, value);
77
87
  }
78
- if (ctx.len + EDGE_HEADER_SIZE + ENCODER.encode(value).byteLength >
79
- ctx.max) {
88
+ const isBuffer = value instanceof Uint8Array;
89
+ size = isBuffer
90
+ ? value.byteLength
91
+ : ENCODER.encode(value).byteLength + 6;
92
+ if (ctx.len + EDGE_HEADER_SIZE + size > ctx.max) {
80
93
  return RANGE_ERR;
81
94
  }
82
95
  ctx.buf[ctx.len++] = STRING;
83
- let size = write(ctx.buf, value, ctx.len + 4, edge.compression === 0);
84
- let sizeU32 = size;
85
- ctx.buf[ctx.len++] = sizeU32;
86
- ctx.buf[ctx.len++] = sizeU32 >>>= 8;
87
- ctx.buf[ctx.len++] = sizeU32 >>>= 8;
88
- ctx.buf[ctx.len++] = sizeU32 >>>= 8;
89
- ctx.len += size;
96
+ size = write(ctx.buf, value, ctx.len + 4, edge.compression === 0);
90
97
  }
91
- else if (edge.typeIndex === REFERENCE) {
92
- if (typeof value !== 'number') {
93
- if (value instanceof ModifyState) {
94
- value = value.tmpId;
95
- }
96
- else {
97
- return new ModifyError(edge, value);
98
- }
99
- }
100
- if (value > 0) {
101
- ctx.buf[ctx.len++] = REFERENCE;
102
- ctx.buf[ctx.len++] = value;
103
- ctx.buf[ctx.len++] = value >>>= 8;
104
- ctx.buf[ctx.len++] = value >>>= 8;
105
- ctx.buf[ctx.len++] = value >>>= 8;
98
+ let sizeU32 = size;
99
+ ctx.buf[ctx.len++] = sizeU32;
100
+ ctx.buf[ctx.len++] = sizeU32 >>>= 8;
101
+ ctx.buf[ctx.len++] = sizeU32 >>>= 8;
102
+ ctx.buf[ctx.len++] = sizeU32 >>>= 8;
103
+ ctx.len += size;
104
+ }
105
+ else if (edge.typeIndex === REFERENCE) {
106
+ // add null
107
+ if (typeof value !== 'number') {
108
+ if (value instanceof ModifyState) {
109
+ value = value.tmpId;
106
110
  }
107
111
  else {
108
112
  return new ModifyError(edge, value);
109
113
  }
110
114
  }
111
- else if (edge.typeIndex === REFERENCES) {
112
- if (!Array.isArray(value)) {
113
- return new ModifyError(edge, value);
114
- }
115
- let size = value.length * 4;
116
- if (ctx.len + EDGE_HEADER_SIZE + size > ctx.max) {
117
- return RANGE_ERR;
118
- }
119
- ctx.buf[ctx.len++] = REFERENCES;
120
- ctx.buf[ctx.len++] = size;
121
- ctx.buf[ctx.len++] = size >>>= 8;
122
- ctx.buf[ctx.len++] = size >>>= 8;
123
- ctx.buf[ctx.len++] = size >>>= 8;
124
- appendRefs(edge, ctx, value);
115
+ if (!edge.validation(value, edge)) {
116
+ return new ModifyError(edge, value);
125
117
  }
126
- else if (edge.typeIndex === CARDINALITY) {
127
- if (!Array.isArray(value)) {
128
- value = [value];
129
- }
130
- const len = value.length;
131
- let size = 4 + len * 8;
132
- if (ctx.len + size + EDGE_HEADER_SIZE > ctx.max) {
133
- return RANGE_ERR;
134
- }
135
- ctx.buf[ctx.len++] = CARDINALITY;
136
- writeHllBuf(value, ctx, edge, size);
118
+ if (value > 0) {
119
+ ctx.buf[ctx.len++] = REFERENCE;
120
+ ctx.buf[ctx.len++] = value;
121
+ ctx.buf[ctx.len++] = value >>>= 8;
122
+ ctx.buf[ctx.len++] = value >>>= 8;
123
+ ctx.buf[ctx.len++] = value >>>= 8;
124
+ }
125
+ else {
126
+ return new ModifyError(edge, value);
137
127
  }
138
128
  }
139
- else {
140
- const op = valueOperation(value);
141
- if (op === 0) {
129
+ else if (edge.typeIndex === REFERENCES) {
130
+ // add null
131
+ if (!Array.isArray(value)) {
142
132
  return new ModifyError(edge, value);
143
133
  }
144
- if (op != UPDATE) {
145
- hasIncr = true;
146
- value = value.increment;
134
+ let size = value.length * 4;
135
+ if (ctx.len + EDGE_HEADER_SIZE + size > ctx.max) {
136
+ return RANGE_ERR;
147
137
  }
148
- if (!hasIncr && t.edgeMainLen == edge.len) {
149
- /*
150
- Full main update:
151
-
152
- | Offset | Field | Size (bytes)| Description |
153
- |---------|-------------|-------------|---------------------------------------|
154
- | 0 | modify op | 1 | Modify operation identifier |
155
- | 1 | prop | 1 | Field identifier (0) |
156
- | 2 | type | 1 | Indicates MICRO_BUFFER type |
157
- | 3 | mainSize | 4 | Size of the main data in bytes |
158
- | 7 | main buffer | Variable | Main data content |
159
- */
160
- if (ctx.len + 7 + edge.len > ctx.max) {
161
- return RANGE_ERR;
162
- }
163
- ctx.buf[ctx.len++] = UPDATE;
164
- ctx.buf[ctx.len++] = 0;
165
- ctx.buf[ctx.len++] = MICRO_BUFFER;
166
- const size = edge.len;
167
- let sizeU32 = size;
168
- ctx.buf[ctx.len++] = sizeU32;
169
- ctx.buf[ctx.len++] = sizeU32 >>>= 8;
170
- ctx.buf[ctx.len++] = sizeU32 >>>= 8;
171
- ctx.buf[ctx.len++] = sizeU32 >>>= 8;
172
- const err = appendFixedValue(ctx, value, edge);
173
- if (err) {
174
- return err;
175
- }
138
+ ctx.buf[ctx.len++] = REFERENCES;
139
+ ctx.buf[ctx.len++] = size;
140
+ ctx.buf[ctx.len++] = size >>>= 8;
141
+ ctx.buf[ctx.len++] = size >>>= 8;
142
+ ctx.buf[ctx.len++] = size >>>= 8;
143
+ const err = appendEdgeRefs(edge, ctx, value);
144
+ if (err) {
145
+ return err;
146
+ }
147
+ }
148
+ else if (edge.typeIndex === CARDINALITY) {
149
+ // add null
150
+ if (!Array.isArray(value)) {
151
+ value = [value];
152
+ }
153
+ const len = value.length;
154
+ let size = 4 + len * 8;
155
+ if (ctx.len + size + EDGE_HEADER_SIZE > ctx.max) {
156
+ return RANGE_ERR;
157
+ }
158
+ ctx.buf[ctx.len++] = CARDINALITY;
159
+ writeHllBuf(value, ctx, edge, size);
160
+ }
161
+ }
162
+ else {
163
+ const op = valueOperation(value);
164
+ if (op === 0) {
165
+ return new ModifyError(edge, value);
166
+ }
167
+ if (op != UPDATE) {
168
+ hasIncr = true;
169
+ value = value.increment;
170
+ }
171
+ if (!hasIncr && t.edgeMainLen == edge.len) {
172
+ /*
173
+ Full main update:
174
+
175
+ | Offset | Field | Size (bytes)| Description |
176
+ |---------|-------------|-------------|---------------------------------------|
177
+ | 0 | modify op | 1 | Modify operation identifier |
178
+ | 1 | prop | 1 | Field identifier (0) |
179
+ | 2 | type | 1 | Indicates MICRO_BUFFER type |
180
+ | 3 | mainSize | 4 | Size of the main data in bytes |
181
+ | 7 | main buffer | Variable | Main data content |
182
+ */
183
+ if (ctx.len + 7 + edge.len > ctx.max) {
184
+ return RANGE_ERR;
185
+ }
186
+ ctx.buf[ctx.len++] = UPDATE;
187
+ ctx.buf[ctx.len++] = 0;
188
+ ctx.buf[ctx.len++] = MICRO_BUFFER;
189
+ const size = edge.len;
190
+ let sizeU32 = size;
191
+ ctx.buf[ctx.len++] = sizeU32;
192
+ ctx.buf[ctx.len++] = sizeU32 >>>= 8;
193
+ ctx.buf[ctx.len++] = sizeU32 >>>= 8;
194
+ ctx.buf[ctx.len++] = sizeU32 >>>= 8;
195
+ const err = appendFixedValue(ctx, value, edge);
196
+ if (err) {
197
+ return err;
198
+ }
199
+ }
200
+ else {
201
+ mainSize += edge.len;
202
+ if (!mainFields) {
203
+ mainFields = [edge, value, op];
176
204
  }
177
205
  else {
178
- mainSize += edge.len;
179
- if (!mainFields) {
180
- mainFields = [edge, value, op];
181
- }
182
- else {
183
- const len = mainFields.length;
184
- for (let i = 0; i < len; i += 3) {
185
- if (edge.start < mainFields[i].start) {
186
- mainFields.splice(i, 0, edge, value, op);
187
- break;
188
- }
189
- else if (mainFields[len - i - 3].start < edge.start) {
190
- mainFields.splice(len - i, 0, edge, value, op);
191
- break;
192
- }
206
+ const len = mainFields.length;
207
+ for (let i = 0; i < len; i += 3) {
208
+ if (edge.start < mainFields[i].start) {
209
+ mainFields.splice(i, 0, edge, value, op);
210
+ break;
211
+ }
212
+ else if (mainFields[len - i - 3].start < edge.start) {
213
+ mainFields.splice(len - i, 0, edge, value, op);
214
+ break;
193
215
  }
194
216
  }
195
217
  }
@@ -246,13 +268,6 @@ export function writeEdges(t, ref, ctx) {
246
268
  | 13 | propType | 1 | Prop typeIndex |
247
269
  | ... | ... | ... | Additional (start, len) pairs |
248
270
  | X | main | len | Actual main content |
249
-
250
- ### Notes:
251
- - The number of `(start, len, operation)` pairs is not explicitly stored
252
- but **derived** from the structure.
253
- - Parsing logic must determine the end of pairs by computing:
254
- `Pairs End Offset = (size - mainSize)`
255
- Sections are processed until the `MAIN` data block begins.
256
271
  */
257
272
  const mainFieldsStartSize = mainFields.length * 2;
258
273
  if (ctx.len + 7 + mainSize + mainFieldsStartSize > ctx.max) {
@@ -261,48 +276,40 @@ export function writeEdges(t, ref, ctx) {
261
276
  ctx.buf[ctx.len++] = UPDATE_PARTIAL;
262
277
  ctx.buf[ctx.len++] = 0;
263
278
  ctx.buf[ctx.len++] = MICRO_BUFFER;
264
- let sizeU32 = mainFieldsStartSize + t.edgeMainLen;
265
- ctx.buf[ctx.len++] = sizeU32;
266
- ctx.buf[ctx.len++] = sizeU32 >>>= 8;
267
- ctx.buf[ctx.len++] = sizeU32 >>>= 8;
268
- ctx.buf[ctx.len++] = sizeU32 >>>= 8;
269
- let mainTotal = t.edgeMainLen;
270
- ctx.buf[ctx.len++] = mainTotal;
271
- ctx.buf[ctx.len++] = mainTotal >>>= 8;
279
+ const size = mainFieldsStartSize + t.edgeMainLen;
280
+ ctx.buf[ctx.len++] = size;
281
+ ctx.buf[ctx.len++] = size >>> 8;
282
+ ctx.buf[ctx.len++] = size >>> 16;
283
+ ctx.buf[ctx.len++] = size >>> 24;
284
+ ctx.buf[ctx.len++] = t.edgeMainLen;
285
+ ctx.buf[ctx.len++] = t.edgeMainLen >>> 8;
272
286
  // Index of start of fields
273
287
  const sIndex = ctx.len;
274
288
  ctx.len += mainFieldsStartSize;
275
- // this has to be replaced
276
289
  // Add zeroes
277
290
  ctx.buf.fill(0, ctx.len, ctx.len + t.edgeMainLen);
278
291
  // Keep track of written bytes from append fixed
279
- let writtenFields = 0;
280
- // do this different...
281
292
  let startMain = ctx.len;
282
293
  for (let i = 0; i < mainFields.length; i += 3) {
283
294
  const edge = mainFields[i];
284
295
  const value = mainFields[i + 1];
285
296
  const op = mainFields[i + 2];
286
- const sIndexI = i + sIndex;
287
- let start = edge.start;
288
- ctx.buf[sIndexI] = start;
289
- ctx.buf[sIndexI + 1] = start >>>= 8;
290
- let len = edge.len;
291
- ctx.buf[sIndexI + 2] = len;
292
- ctx.buf[sIndexI + 3] = len >>>= 8;
297
+ const sIndexI = i * 2 + sIndex;
298
+ ctx.buf[sIndexI] = edge.start;
299
+ ctx.buf[sIndexI + 1] = edge.start >>> 8;
300
+ ctx.buf[sIndexI + 2] = edge.len;
301
+ ctx.buf[sIndexI + 3] = edge.len >>> 8;
293
302
  ctx.buf[sIndexI + 4] = op;
294
303
  ctx.buf[sIndexI + 5] = edge.typeIndex;
295
304
  ctx.len = startMain + edge.start;
296
- if (edge.start + edge.len > writtenFields) {
297
- writtenFields = edge.start + edge.len;
298
- }
305
+ // Add null support (defaults)
299
306
  const err = appendFixedValue(ctx, value, edge);
300
307
  if (err) {
301
308
  return err;
302
309
  }
303
310
  }
304
- // Correction to reuse append fixed value
305
- ctx.len += t.edgeMainLen - writtenFields;
311
+ // Correction append fixed value writes the len
312
+ ctx.len = startMain + t.edgeMainLen;
306
313
  }
307
314
  }
308
315
  }