@based/db 0.0.21 → 0.0.23

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 (113) hide show
  1. package/README.md +10 -10
  2. package/dist/lib/darwin_aarch64/include/selva/types.h +9 -18
  3. package/dist/lib/darwin_aarch64/libnode-v20.node +0 -0
  4. package/dist/lib/darwin_aarch64/libnode-v21.node +0 -0
  5. package/dist/lib/darwin_aarch64/libnode-v22.node +0 -0
  6. package/dist/lib/darwin_aarch64/libnode-v23.node +0 -0
  7. package/dist/lib/darwin_aarch64/libselva.dylib +0 -0
  8. package/dist/lib/linux_aarch64/include/selva/types.h +9 -18
  9. package/dist/lib/linux_aarch64/libjemalloc_selva.so.2 +0 -0
  10. package/dist/lib/linux_aarch64/libnode-v20.node +0 -0
  11. package/dist/lib/linux_aarch64/libnode-v21.node +0 -0
  12. package/dist/lib/linux_aarch64/libnode-v22.node +0 -0
  13. package/dist/lib/linux_aarch64/libnode-v23.node +0 -0
  14. package/dist/lib/linux_aarch64/libselva.so +0 -0
  15. package/dist/lib/linux_x86_64/include/selva/types.h +9 -18
  16. package/dist/lib/linux_x86_64/libjemalloc_selva.so.2 +0 -0
  17. package/dist/lib/linux_x86_64/libnode-v20.node +0 -0
  18. package/dist/lib/linux_x86_64/libnode-v21.node +0 -0
  19. package/dist/lib/linux_x86_64/libnode-v22.node +0 -0
  20. package/dist/lib/linux_x86_64/libnode-v23.node +0 -0
  21. package/dist/lib/linux_x86_64/libselva.so +0 -0
  22. package/dist/src/client/bitWise.d.ts +0 -1
  23. package/dist/src/client/bitWise.js +0 -10
  24. package/dist/src/client/{operations.d.ts → flushModify.d.ts} +4 -4
  25. package/dist/src/client/{operations.js → flushModify.js} +39 -15
  26. package/dist/src/client/index.d.ts +10 -6
  27. package/dist/src/client/index.js +12 -4
  28. package/dist/src/client/modify/ModifyRes.d.ts +2 -8
  29. package/dist/src/client/modify/ModifyRes.js +23 -29
  30. package/dist/src/client/modify/alias.d.ts +1 -1
  31. package/dist/src/client/modify/alias.js +5 -2
  32. package/dist/src/client/modify/binary.d.ts +1 -1
  33. package/dist/src/client/modify/binary.js +1 -1
  34. package/dist/src/client/modify/cardinality.d.ts +2 -2
  35. package/dist/src/client/modify/cardinality.js +7 -5
  36. package/dist/src/client/modify/create.js +10 -5
  37. package/dist/src/client/modify/delete.d.ts +3 -1
  38. package/dist/src/client/modify/delete.js +12 -5
  39. package/dist/src/client/modify/expire.js +1 -1
  40. package/dist/src/client/modify/fixed.js +11 -4
  41. package/dist/src/client/modify/references/appendRefs.d.ts +4 -0
  42. package/dist/src/client/modify/references/appendRefs.js +27 -0
  43. package/dist/src/client/modify/references/edge.d.ts +0 -1
  44. package/dist/src/client/modify/references/edge.js +191 -71
  45. package/dist/src/client/modify/references/getEdgeSize.d.ts +3 -0
  46. package/dist/src/client/modify/references/getEdgeSize.js +27 -0
  47. package/dist/src/client/modify/references/reference.js +40 -26
  48. package/dist/src/client/modify/references/references.js +18 -6
  49. package/dist/src/client/modify/string.js +2 -1
  50. package/dist/src/client/modify/types.d.ts +1 -0
  51. package/dist/src/client/modify/types.js +1 -0
  52. package/dist/src/client/modify/update.js +3 -4
  53. package/dist/src/client/modify/upsert.js +1 -0
  54. package/dist/src/client/modify/vector.js +0 -2
  55. package/dist/src/client/query/BasedDbQuery.d.ts +4 -3
  56. package/dist/src/client/query/BasedDbQuery.js +12 -3
  57. package/dist/src/client/query/aggregationFn.d.ts +3 -0
  58. package/dist/src/client/query/aggregationFn.js +9 -0
  59. package/dist/src/client/query/debug.js +2 -6
  60. package/dist/src/client/query/display.js +5 -2
  61. package/dist/src/client/query/filter/createFixedFilterBuffer.d.ts +2 -2
  62. package/dist/src/client/query/filter/createFixedFilterBuffer.js +34 -26
  63. package/dist/src/client/query/filter/createReferenceFilter.d.ts +1 -1
  64. package/dist/src/client/query/filter/createReferenceFilter.js +17 -7
  65. package/dist/src/client/query/filter/createVariableFilterBuffer.d.ts +1 -1
  66. package/dist/src/client/query/filter/createVariableFilterBuffer.js +45 -22
  67. package/dist/src/client/query/filter/filter.d.ts +1 -1
  68. package/dist/src/client/query/filter/filter.js +5 -0
  69. package/dist/src/client/query/filter/parseFilterValue.js +1 -1
  70. package/dist/src/client/query/filter/toBuffer.d.ts +2 -2
  71. package/dist/src/client/query/filter/toBuffer.js +16 -9
  72. package/dist/src/client/query/include/props.js +18 -1
  73. package/dist/src/client/query/include/toBuffer.d.ts +1 -1
  74. package/dist/src/client/query/include/toBuffer.js +22 -12
  75. package/dist/src/client/query/include/walk.js +2 -1
  76. package/dist/src/client/query/query.d.ts +1 -0
  77. package/dist/src/client/query/query.js +1 -0
  78. package/dist/src/client/query/queryDef.js +2 -1
  79. package/dist/src/client/query/read/read.d.ts +2 -1
  80. package/dist/src/client/query/read/read.js +95 -62
  81. package/dist/src/client/query/registerQuery.d.ts +1 -1
  82. package/dist/src/client/query/registerQuery.js +2 -1
  83. package/dist/src/client/query/search/index.d.ts +1 -1
  84. package/dist/src/client/query/search/index.js +56 -24
  85. package/dist/src/client/query/subscription/markers.js +2 -1
  86. package/dist/src/client/query/toBuffer.d.ts +1 -1
  87. package/dist/src/client/query/toBuffer.js +80 -32
  88. package/dist/src/client/query/types.d.ts +25 -3
  89. package/dist/src/client/query/types.js +6 -0
  90. package/dist/src/client/query/validation.js +1 -1
  91. package/dist/src/client/string.d.ts +1 -1
  92. package/dist/src/client/string.js +1 -2
  93. package/dist/src/client/xxHash64.d.ts +1 -1
  94. package/dist/src/index.d.ts +4 -3
  95. package/dist/src/index.js +20 -11
  96. package/dist/src/native.d.ts +8 -13
  97. package/dist/src/native.js +9 -31
  98. package/dist/src/server/dbHash.d.ts +5 -0
  99. package/dist/src/server/dbHash.js +27 -0
  100. package/dist/src/server/index.d.ts +10 -10
  101. package/dist/src/server/index.js +54 -35
  102. package/dist/src/server/migrate/index.js +1 -1
  103. package/dist/src/server/migrate/worker.js +2 -2
  104. package/dist/src/server/save.d.ts +1 -1
  105. package/dist/src/server/save.js +10 -10
  106. package/dist/src/server/start.js +4 -2
  107. package/dist/src/server/tree.d.ts +1 -1
  108. package/dist/src/server/tree.js +1 -1
  109. package/dist/src/utils.d.ts +3 -0
  110. package/dist/src/utils.js +23 -5
  111. package/package.json +3 -2
  112. package/dist/src/client/query/read/types.d.ts +0 -4
  113. package/dist/src/client/query/read/types.js +0 -5
@@ -2,5 +2,5 @@ import { ModifyCtx } from '../../index.js';
2
2
  import { SchemaTypeDef, PropDef } from '@based/schema/def';
3
3
  import { ModifyOp, ModifyErr } from './types.js';
4
4
  import { ModifyError } from './ModifyRes.js';
5
- export declare function writeHll(value: string | null | Buffer | Uint8Array | Array<string | Buffer | Uint8Array>, ctx: ModifyCtx, def: SchemaTypeDef, t: PropDef, parentId: number, modifyOp: ModifyOp): ModifyErr;
6
- export declare function writeHllBuf(value: (string | Buffer | Uint8Array)[], ctx: ModifyCtx, t: PropDef, len: number): ModifyError;
5
+ export declare function writeHll(value: string | null | Uint8Array | Array<string | Uint8Array>, ctx: ModifyCtx, def: SchemaTypeDef, t: PropDef, parentId: number, modifyOp: ModifyOp): ModifyErr;
6
+ export declare function writeHllBuf(value: (string | Uint8Array)[], ctx: ModifyCtx, t: PropDef, len: number): ModifyError;
@@ -2,6 +2,7 @@ import { RANGE_ERR, CREATE } from './types.js';
2
2
  import { ModifyError } from './ModifyRes.js';
3
3
  import { setCursor } from './setCursor.js';
4
4
  import { xxHash64 } from '../xxHash64.js';
5
+ import { ENCODER } from '../../utils.js';
5
6
  export function writeHll(value, ctx, def, t, parentId, modifyOp) {
6
7
  if (!value) {
7
8
  return new ModifyError(t, value);
@@ -31,14 +32,15 @@ function addHll(value, ctx, def, t, parentId, modifyOp) {
31
32
  writeHllBuf(value, ctx, t, len);
32
33
  }
33
34
  export function writeHllBuf(value, ctx, t, len) {
34
- ctx.buf.writeUint32LE(len, ctx.len);
35
- ctx.len += 4;
35
+ ctx.buf[ctx.len++] = len;
36
+ ctx.buf[ctx.len++] = len >>> 8;
37
+ ctx.buf[ctx.len++] = len >>> 16;
38
+ ctx.buf[ctx.len++] = len >>> 24;
36
39
  for (let val of value) {
37
40
  if (typeof val === 'string') {
38
- xxHash64(new TextEncoder().encode(val), ctx.buf, ctx.len);
41
+ xxHash64(ENCODER.encode(val), ctx.buf, ctx.len);
39
42
  }
40
- else if ((val instanceof Buffer || val instanceof Uint8Array) &&
41
- val.byteLength === 8) {
43
+ else if ((val instanceof Uint8Array) && val.byteLength === 8) {
42
44
  ctx.buf.set(val, ctx.len);
43
45
  }
44
46
  else {
@@ -1,5 +1,5 @@
1
1
  import { MICRO_BUFFER } from '@based/schema/def';
2
- import { startDrain, flushBuffer } from '../operations.js';
2
+ import { startDrain, flushBuffer } from '../flushModify.js';
3
3
  import { setCursor } from './setCursor.js';
4
4
  import { modify } from './modify.js';
5
5
  import { ModifyState } from './ModifyRes.js';
@@ -102,7 +102,9 @@ const appendCreate = (ctx, def, obj, res, unsafe) => {
102
102
  export function create(db, type, obj, opts) {
103
103
  const def = db.schemaTypesParsed[type];
104
104
  if (!def) {
105
- throw new Error(`Unknown type: ${type}. Did you mean on of: ${Object.keys(db.schemaTypesParsed).join(', ')}`);
105
+ throw new Error(
106
+ // fix this with promise
107
+ `Unknown type: ${type}. Did you mean on of: ${Object.keys(db.schemaTypesParsed).join(', ')}`);
106
108
  }
107
109
  let id;
108
110
  if ('id' in obj) {
@@ -110,6 +112,7 @@ export function create(db, type, obj, opts) {
110
112
  id = obj.id;
111
113
  }
112
114
  else {
115
+ // fix this with promise
113
116
  throw Error('create with "id" is not allowed');
114
117
  }
115
118
  }
@@ -121,7 +124,7 @@ export function create(db, type, obj, opts) {
121
124
  const pos = ctx.len;
122
125
  const err = appendCreate(ctx, def, obj, res, opts?.unsafe);
123
126
  if (err) {
124
- ctx.prefix0 = -1; // force a new cursor
127
+ ctx.prefix0 = -1; // Force a new cursor
125
128
  ctx.len = pos;
126
129
  if (err === RANGE_ERR) {
127
130
  if (pos === 0) {
@@ -130,9 +133,11 @@ export function create(db, type, obj, opts) {
130
133
  flushBuffer(db);
131
134
  return db.create(type, obj, opts);
132
135
  }
133
- res.error = err;
136
+ // res.error = err
134
137
  // @ts-ignore
135
- return res;
138
+ // return Promise.reject(err)
139
+ // return res
140
+ throw err;
136
141
  }
137
142
  if (!db.isDraining) {
138
143
  startDrain(db);
@@ -1,2 +1,4 @@
1
1
  import { DbClient } from '../index.js';
2
- export declare const deleteFn: (db: DbClient, type: string, id: number) => boolean;
2
+ import { ModifyRes } from './ModifyRes.js';
3
+ import { ModifyOpts } from './types.js';
4
+ export declare const deleteFn: (db: DbClient, type: string, id: number, opts?: ModifyOpts) => ModifyRes;
@@ -1,12 +1,18 @@
1
- import { flushBuffer, startDrain } from '../operations.js';
1
+ import { flushBuffer, startDrain } from '../flushModify.js';
2
+ import { getSubscriptionMarkers } from '../query/subscription/markers.js';
3
+ import { ModifyState } from './ModifyRes.js';
2
4
  import { setCursor } from './setCursor.js';
3
- import { UPDATE, DELETE_SORT_INDEX, DELETE_NODE } from './types.js';
5
+ import { UPDATE, DELETE_SORT_INDEX, DELETE_NODE, } from './types.js';
4
6
  import { MICRO_BUFFER } from '@based/schema/def';
5
- export const deleteFn = (db, type, id) => {
7
+ export const deleteFn = (db, type, id, opts) => {
8
+ const def = db.schemaTypesParsed[type];
9
+ if (!def) {
10
+ throw new Error(`Unknown type: ${type}. Did you mean on of: ${Object.keys(db.schemaTypesParsed).join(', ')}`);
11
+ }
6
12
  const ctx = db.modifyCtx;
13
+ const res = new ModifyState(def.id, id, db, getSubscriptionMarkers(db, def.id, id, true), opts);
7
14
  const schema = db.schemaTypesParsed[type];
8
15
  const separate = schema.separate;
9
- // TODO: pretty slow actually
10
16
  if (separate) {
11
17
  const size = 11 /* SIZE.DEFAULT_CURSOR */ + 2 + separate.length * 12;
12
18
  if (ctx.len + size > ctx.max) {
@@ -33,6 +39,7 @@ export const deleteFn = (db, type, id) => {
33
39
  if (!db.isDraining) {
34
40
  startDrain(db);
35
41
  }
36
- return true;
42
+ // @ts-ignore
43
+ return res;
37
44
  };
38
45
  //# sourceMappingURL=delete.js.map
@@ -1,5 +1,5 @@
1
1
  import { MICRO_BUFFER } from '@based/schema/def';
2
- import { startDrain, flushBuffer } from '../operations.js';
2
+ import { startDrain, flushBuffer } from '../flushModify.js';
3
3
  import { setCursor } from './setCursor.js';
4
4
  import { EXPIRE } from './types.js';
5
5
  export function expire(db, type, id, seconds) {
@@ -1,3 +1,4 @@
1
+ import { ENCODER } from '../../index.js';
1
2
  import { BINARY, BOOLEAN, ENUM, INT16, INT32, INT8, NUMBER, STRING, TIMESTAMP, UINT16, UINT32, UINT8, } from '@based/schema/def';
2
3
  import { convertToTimestamp } from '../timestamp.js';
3
4
  import { getBuffer } from './binary.js';
@@ -24,7 +25,8 @@ map[STRING] = (ctx, val, def) => {
24
25
  }
25
26
  val = '';
26
27
  }
27
- const size = Buffer.byteLength(val, 'utf8');
28
+ const valBuf = ENCODER.encode(val);
29
+ const size = valBuf.byteLength;
28
30
  if (size + 1 > def.len) {
29
31
  return new ModifyError(def, val, `max length of ${def.len - 1},`);
30
32
  }
@@ -32,7 +34,8 @@ map[STRING] = (ctx, val, def) => {
32
34
  return RANGE_ERR;
33
35
  }
34
36
  ctx.buf[ctx.len++] = size;
35
- ctx.len += ctx.buf.write(val, ctx.len, 'utf8');
37
+ ctx.buf.set(valBuf, ctx.len);
38
+ ctx.len += size;
36
39
  };
37
40
  map[BOOLEAN] = (ctx, val, def) => {
38
41
  if (ctx.len + 1 > ctx.max) {
@@ -69,7 +72,9 @@ map[NUMBER] = (ctx, val, def) => {
69
72
  if (ctx.len + 8 > ctx.max) {
70
73
  return RANGE_ERR;
71
74
  }
72
- ctx.len = ctx.buf.writeDoubleLE(val, ctx.len);
75
+ const view = new DataView(ctx.buf.buffer, ctx.buf.byteOffset + ctx.len, 8);
76
+ ctx.len += 8;
77
+ view.setFloat64(0, val, true);
73
78
  };
74
79
  map[TIMESTAMP] = (ctx, val, def) => {
75
80
  const parsedValue = convertToTimestamp(val);
@@ -79,7 +84,9 @@ map[TIMESTAMP] = (ctx, val, def) => {
79
84
  if (ctx.len + 8 > ctx.max) {
80
85
  return RANGE_ERR;
81
86
  }
82
- ctx.len = ctx.buf.writeDoubleLE(parsedValue, ctx.len);
87
+ const view = new DataView(ctx.buf.buffer, ctx.buf.byteOffset + ctx.len, 8);
88
+ ctx.len += 8;
89
+ view.setFloat64(0, parsedValue, true);
83
90
  };
84
91
  map[UINT32] = (ctx, val, def) => {
85
92
  if (typeof val !== 'number') {
@@ -0,0 +1,4 @@
1
+ import { PropDefEdge } from '@based/schema/def';
2
+ import { ModifyCtx } from '../../flushModify.js';
3
+ import { ModifyErr } from '../types.js';
4
+ export declare function appendRefs(t: PropDefEdge, ctx: ModifyCtx, value: any[]): ModifyErr;
@@ -0,0 +1,27 @@
1
+ import { ModifyState, ModifyError } from '../ModifyRes.js';
2
+ export function appendRefs(t, ctx, value) {
3
+ for (let i = 0; i < value.length; i++) {
4
+ let id = value[i];
5
+ if (typeof id !== 'number') {
6
+ if (id instanceof ModifyState) {
7
+ if (id.error) {
8
+ return id.error;
9
+ }
10
+ id = id.tmpId;
11
+ }
12
+ else {
13
+ return new ModifyError(t, value);
14
+ }
15
+ }
16
+ if (id > 0) {
17
+ ctx.buf[ctx.len++] = id;
18
+ ctx.buf[ctx.len++] = id >>>= 8;
19
+ ctx.buf[ctx.len++] = id >>>= 8;
20
+ ctx.buf[ctx.len++] = id >>>= 8;
21
+ }
22
+ else {
23
+ return new ModifyError(t, value);
24
+ }
25
+ }
26
+ }
27
+ //# sourceMappingURL=appendRefs.js.map
@@ -2,5 +2,4 @@ import { ModifyCtx } from '../../../index.js';
2
2
  import { PropDef } from '@based/schema/def';
3
3
  import { ModifyErr } from '../types.js';
4
4
  import { RefModifyOpts } from './references.js';
5
- export declare function getEdgeSize(t: PropDef, ref: RefModifyOpts): number;
6
5
  export declare function writeEdges(t: PropDef, ref: RefModifyOpts, ctx: ModifyCtx): ModifyErr;
@@ -1,65 +1,50 @@
1
- import { BINARY, CARDINALITY, REFERENCE, REFERENCES, STRING, } from '@based/schema/def';
1
+ import { ENCODER } from '../../../index.js';
2
+ import { BINARY, MICRO_BUFFER, CARDINALITY, REFERENCE, REFERENCES, STRING, } from '@based/schema/def';
2
3
  import { write } from '../../string.js';
3
4
  import { writeHllBuf } from '../cardinality.js';
4
5
  import { getBuffer, writeBinaryRaw } from '../binary.js';
5
6
  import { ModifyError, ModifyState } from '../ModifyRes.js';
6
- import { DECREMENT, INCREMENT, RANGE_ERR } from '../types.js';
7
+ import { DECREMENT, INCREMENT, RANGE_ERR, UPDATE, UPDATE_PARTIAL, } from '../types.js';
7
8
  import { appendFixedValue } from '../fixed.js';
8
- export function getEdgeSize(t, ref) {
9
- let size = 0;
10
- for (const key in t.edges) {
11
- if (key in ref) {
12
- const edge = t.edges[key];
13
- const value = ref[key];
14
- if (edge.len === 0) {
15
- if (edge.typeIndex === STRING) {
16
- size += Buffer.byteLength(value) + 4;
17
- }
18
- else if (edge.typeIndex === REFERENCE) {
19
- size += 4;
20
- }
21
- else if (edge.typeIndex === REFERENCES) {
22
- size += value.length * 4 + 4;
23
- }
24
- }
25
- else {
26
- size += edge.len;
27
- }
28
- }
29
- }
30
- return size;
31
- }
32
- function appendRefs(t, ctx, value) {
33
- for (let i = 0; i < value.length; i++) {
34
- let id = value[i];
35
- if (typeof id !== 'number') {
36
- if (id instanceof ModifyState) {
37
- if (id.error) {
38
- return id.error;
39
- }
40
- id = id.tmpId;
41
- }
42
- else {
43
- return new ModifyError(t, value);
44
- }
45
- }
46
- if (id > 0) {
47
- ctx.buf[ctx.len++] = id;
48
- ctx.buf[ctx.len++] = id >>>= 8;
49
- ctx.buf[ctx.len++] = id >>>= 8;
50
- ctx.buf[ctx.len++] = id >>>= 8;
9
+ import { appendRefs } from './appendRefs.js';
10
+ function valueOperation(value) {
11
+ if (typeof value === 'object' && value !== null) {
12
+ if (value.increment > 0) {
13
+ return INCREMENT;
51
14
  }
52
- else {
53
- return new ModifyError(t, value);
15
+ else if (value.increment < 0) {
16
+ return DECREMENT;
54
17
  }
18
+ return 0;
55
19
  }
20
+ return UPDATE;
56
21
  }
22
+ const EDGE_HEADER_SIZE = 5;
57
23
  export function writeEdges(t, ref, ctx) {
24
+ let mainFields;
25
+ let mainSize = 0;
26
+ let hasIncr = false;
58
27
  for (const key in t.edges) {
59
28
  if (key in ref) {
60
29
  const edge = t.edges[key];
61
30
  let value = ref[key];
62
- if (edge.len === 0) {
31
+ if (edge.separate === true) {
32
+ if (ctx.len + 2 > ctx.max) {
33
+ return RANGE_ERR;
34
+ }
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
+ */
63
48
  if (edge.typeIndex === BINARY) {
64
49
  let size = 0;
65
50
  if (value === null) {
@@ -72,10 +57,9 @@ export function writeEdges(t, ref, ctx) {
72
57
  }
73
58
  size = buf.byteLength;
74
59
  }
75
- if (ctx.len + 6 + size > ctx.max) {
60
+ if (ctx.len + EDGE_HEADER_SIZE + size > ctx.max) {
76
61
  return RANGE_ERR;
77
62
  }
78
- ctx.buf[ctx.len++] = edge.prop;
79
63
  ctx.buf[ctx.len++] = STRING;
80
64
  if (size) {
81
65
  writeBinaryRaw(value, ctx);
@@ -91,10 +75,9 @@ export function writeEdges(t, ref, ctx) {
91
75
  if (typeof value !== 'string') {
92
76
  return new ModifyError(edge, value);
93
77
  }
94
- if (ctx.len + 6 + Buffer.byteLength(value) > ctx.max) {
78
+ if (ctx.len + EDGE_HEADER_SIZE + ENCODER.encode(value).byteLength > ctx.max) {
95
79
  return RANGE_ERR;
96
80
  }
97
- ctx.buf[ctx.len++] = edge.prop;
98
81
  ctx.buf[ctx.len++] = STRING;
99
82
  let size = write(ctx.buf, value, ctx.len + 4, edge.compression === 0);
100
83
  let sizeU32 = size;
@@ -114,7 +97,6 @@ export function writeEdges(t, ref, ctx) {
114
97
  }
115
98
  }
116
99
  if (value > 0) {
117
- ctx.buf[ctx.len++] = edge.prop;
118
100
  ctx.buf[ctx.len++] = REFERENCE;
119
101
  ctx.buf[ctx.len++] = value;
120
102
  ctx.buf[ctx.len++] = value >>>= 8;
@@ -130,10 +112,9 @@ export function writeEdges(t, ref, ctx) {
130
112
  return new ModifyError(edge, value);
131
113
  }
132
114
  let size = value.length * 4;
133
- if (ctx.len + 6 + size > ctx.max) {
115
+ if (ctx.len + EDGE_HEADER_SIZE + size > ctx.max) {
134
116
  return RANGE_ERR;
135
117
  }
136
- ctx.buf[ctx.len++] = edge.prop;
137
118
  ctx.buf[ctx.len++] = REFERENCES;
138
119
  ctx.buf[ctx.len++] = size;
139
120
  ctx.buf[ctx.len++] = size >>>= 8;
@@ -147,40 +128,179 @@ export function writeEdges(t, ref, ctx) {
147
128
  }
148
129
  const len = value.length;
149
130
  let size = 4 + len * 8;
150
- if (ctx.len + size + 11 > ctx.max) {
131
+ if (ctx.len + size + EDGE_HEADER_SIZE > ctx.max) {
151
132
  return RANGE_ERR;
152
133
  }
153
- ctx.buf[ctx.len++] = edge.prop;
154
134
  ctx.buf[ctx.len++] = CARDINALITY;
155
135
  writeHllBuf(value, ctx, t, size);
156
136
  }
157
137
  }
158
138
  else {
159
- if (ctx.len + 2 > ctx.max) {
160
- return RANGE_ERR;
139
+ const op = valueOperation(value);
140
+ if (op === 0) {
141
+ return new ModifyError(edge, value);
161
142
  }
162
- if (typeof value === 'object' && value !== null) {
163
- if (value.increment > 0) {
164
- ctx.buf[ctx.len++] = 0;
165
- ctx.buf[ctx.len++] = INCREMENT;
166
- value = value.increment;
143
+ if (op != UPDATE) {
144
+ hasIncr = true;
145
+ value = value.increment;
146
+ }
147
+ if (!hasIncr && t.edgeMainLen == edge.len) {
148
+ /*
149
+ Full main update:
150
+
151
+ | Offset | Field | Size (bytes)| Description |
152
+ |---------|-------------|-------------|---------------------------------------|
153
+ | 0 | modify op | 1 | Modify operation identifier |
154
+ | 1 | prop | 1 | Field identifier (0) |
155
+ | 2 | type | 1 | Indicates MICRO_BUFFER type |
156
+ | 3 | mainSize | 4 | Size of the main data in bytes |
157
+ | 7 | main buffer | Variable | Main data content |
158
+ */
159
+ if (ctx.len + 7 + edge.len > ctx.max) {
160
+ return RANGE_ERR;
167
161
  }
168
- else if (value.increment < 0) {
169
- ctx.buf[ctx.len++] = 0;
170
- ctx.buf[ctx.len++] = DECREMENT;
171
- value = -value.increment;
162
+ ctx.buf[ctx.len++] = UPDATE;
163
+ ctx.buf[ctx.len++] = 0;
164
+ ctx.buf[ctx.len++] = MICRO_BUFFER;
165
+ const size = edge.len;
166
+ let sizeU32 = size;
167
+ ctx.buf[ctx.len++] = sizeU32;
168
+ ctx.buf[ctx.len++] = sizeU32 >>>= 8;
169
+ ctx.buf[ctx.len++] = sizeU32 >>>= 8;
170
+ ctx.buf[ctx.len++] = sizeU32 >>>= 8;
171
+ const err = appendFixedValue(ctx, value, edge);
172
+ if (err) {
173
+ return err;
174
+ }
175
+ }
176
+ else {
177
+ mainSize += edge.len;
178
+ if (!mainFields) {
179
+ mainFields = [edge, value, op];
172
180
  }
173
181
  else {
174
- return new ModifyError(edge, value);
182
+ const len = mainFields.length;
183
+ for (let i = 0; i < len; i += 3) {
184
+ if (edge.start < mainFields[i].start) {
185
+ mainFields.splice(i, 0, edge, value, op);
186
+ break;
187
+ }
188
+ else if (mainFields[len - i - 3].start < edge.start) {
189
+ mainFields.splice(len - i, 0, edge, value, op);
190
+ break;
191
+ }
192
+ }
175
193
  }
176
194
  }
177
- ctx.buf[ctx.len++] = edge.prop;
178
- ctx.buf[ctx.len++] = edge.typeIndex;
195
+ }
196
+ }
197
+ }
198
+ if (mainFields) {
199
+ // Single field in main buffer can immediately setup the main buffer
200
+ if (!hasIncr && mainSize === t.edgeMainLen) {
201
+ /*
202
+ Full main update:
203
+
204
+ | Offset | Field | Size (bytes)| Description |
205
+ |---------|-------------|-------------|---------------------------------------|
206
+ | 0 | modify op | 1 | Modify operation identifier |
207
+ | 1 | prop | 1 | Field identifier (0) |
208
+ | 2 | type | 1 | Indicates MICRO_BUFFER type |
209
+ | 3 | mainSize | 4 | Size of the main data in bytes |
210
+ | 7 | main buffer | Variable | Main data content |
211
+ */
212
+ if (ctx.len + 7 + mainSize > ctx.max) {
213
+ return RANGE_ERR;
214
+ }
215
+ ctx.buf[ctx.len++] = UPDATE;
216
+ ctx.buf[ctx.len++] = 0;
217
+ ctx.buf[ctx.len++] = MICRO_BUFFER;
218
+ let sizeU32 = mainSize;
219
+ ctx.buf[ctx.len++] = sizeU32;
220
+ ctx.buf[ctx.len++] = sizeU32 >>>= 8;
221
+ ctx.buf[ctx.len++] = sizeU32 >>>= 8;
222
+ ctx.buf[ctx.len++] = sizeU32 >>>= 8;
223
+ for (let i = 0; i < mainFields.length; i += 3) {
224
+ const edge = mainFields[i];
225
+ const err = appendFixedValue(ctx, mainFields[i + 1], edge);
226
+ if (err) {
227
+ return err;
228
+ }
229
+ }
230
+ }
231
+ else {
232
+ /*
233
+ Partial main update:
234
+
235
+ | Offset | Field | Size (bytes)| Description |
236
+ |---------|-------------|-------------|--------------------------------------|
237
+ | 0 | modify op | 1 | Modify operation identifier |
238
+ | 1 | prop | 1 | Field identifier (0 in this case) |
239
+ | 2 | type | 1 | Indicates MICRO_BUFFER type |
240
+ | 3 | size | 4 | Total size of the payload |
241
+ | 7 | mainSize | 2 | Length of the main data block |
242
+ | 9 | start | 2 | Start position of first section |
243
+ | 11 | len | 2 | Length of first section |
244
+ | 12 | field op | 1 | Field operation type e.g. INCREMENT |
245
+ | 13 | propType | 1 | Prop typeIndex |
246
+ | ... | ... | ... | Additional (start, len) pairs |
247
+ | X | main | len | Actual main content |
248
+
249
+ ### Notes:
250
+ - The number of `(start, len, operation)` pairs is not explicitly stored
251
+ but **derived** from the structure.
252
+ - Parsing logic must determine the end of pairs by computing:
253
+ `Pairs End Offset = (size - mainSize)`
254
+ Sections are processed until the `MAIN` data block begins.
255
+ */
256
+ const mainFieldsStartSize = mainFields.length * 2;
257
+ if (ctx.len + 7 + mainSize + mainFieldsStartSize > ctx.max) {
258
+ return RANGE_ERR;
259
+ }
260
+ ctx.buf[ctx.len++] = UPDATE_PARTIAL;
261
+ ctx.buf[ctx.len++] = 0;
262
+ ctx.buf[ctx.len++] = MICRO_BUFFER;
263
+ let sizeU32 = mainFieldsStartSize + t.edgeMainLen;
264
+ ctx.buf[ctx.len++] = sizeU32;
265
+ ctx.buf[ctx.len++] = sizeU32 >>>= 8;
266
+ ctx.buf[ctx.len++] = sizeU32 >>>= 8;
267
+ ctx.buf[ctx.len++] = sizeU32 >>>= 8;
268
+ let mainTotal = t.edgeMainLen;
269
+ ctx.buf[ctx.len++] = mainTotal;
270
+ ctx.buf[ctx.len++] = mainTotal >>>= 8;
271
+ // Index of start of fields
272
+ const sIndex = ctx.len;
273
+ ctx.len += mainFieldsStartSize;
274
+ // Add zeroes
275
+ ctx.buf.fill(0, ctx.len, ctx.len + t.edgeMainLen);
276
+ // Keep track of written bytes from append fixed
277
+ let writtenFields = 0;
278
+ // do this different...
279
+ let startMain = ctx.len;
280
+ for (let i = 0; i < mainFields.length; i += 3) {
281
+ const edge = mainFields[i];
282
+ const value = mainFields[i + 1];
283
+ const op = mainFields[i + 2];
284
+ const sIndexI = i + sIndex;
285
+ let start = edge.start;
286
+ ctx.buf[sIndexI] = start;
287
+ ctx.buf[sIndexI + 1] = start >>>= 8;
288
+ let len = edge.len;
289
+ ctx.buf[sIndexI + 2] = len;
290
+ ctx.buf[sIndexI + 3] = len >>>= 8;
291
+ ctx.buf[sIndexI + 4] = op;
292
+ ctx.buf[sIndexI + 5] = edge.typeIndex;
293
+ ctx.len = startMain + edge.start;
294
+ if (edge.start + edge.len > writtenFields) {
295
+ writtenFields = edge.start + edge.len;
296
+ }
179
297
  const err = appendFixedValue(ctx, value, edge);
180
298
  if (err) {
181
299
  return err;
182
300
  }
183
301
  }
302
+ // Correction to reuse append fixed value
303
+ ctx.len += t.edgeMainLen - writtenFields;
184
304
  }
185
305
  }
186
306
  }
@@ -0,0 +1,3 @@
1
+ import { PropDef } from '@based/schema/def';
2
+ import { RefModifyOpts } from './references.js';
3
+ export declare function getEdgeSize(t: PropDef, ref: RefModifyOpts): number;
@@ -0,0 +1,27 @@
1
+ import { STRING, REFERENCE, REFERENCES } from '@based/schema/def';
2
+ import { ENCODER } from '../../../utils.js';
3
+ export function getEdgeSize(t, ref) {
4
+ let size = 0;
5
+ for (const key in t.edges) {
6
+ if (key in ref) {
7
+ const edge = t.edges[key];
8
+ const value = ref[key];
9
+ if (edge.len === 0) {
10
+ if (edge.typeIndex === STRING) {
11
+ size += ENCODER.encode(value).byteLength + 4;
12
+ }
13
+ else if (edge.typeIndex === REFERENCE) {
14
+ size += 4;
15
+ }
16
+ else if (edge.typeIndex === REFERENCES) {
17
+ size += value.length * 4 + 4;
18
+ }
19
+ }
20
+ else {
21
+ size += edge.len;
22
+ }
23
+ }
24
+ }
25
+ return size;
26
+ }
27
+ //# sourceMappingURL=getEdgeSize.js.map