@based/db 0.1.3-alpha.1 → 0.1.3

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 (161) hide show
  1. package/dist/basedDbNative.cjs +23 -0
  2. package/dist/lib/darwin_aarch64/include/cdefs.h +4 -1
  3. package/dist/lib/darwin_aarch64/include/selva/db.h +28 -5
  4. package/dist/lib/darwin_aarch64/include/selva/fast_linear_search.h +2 -2
  5. package/dist/lib/darwin_aarch64/include/selva/fields.h +13 -41
  6. package/dist/lib/darwin_aarch64/include/selva/selva_string.h +4 -0
  7. package/dist/lib/darwin_aarch64/include/selva/types.h +1 -11
  8. package/dist/lib/darwin_aarch64/libdeflate.dylib +0 -0
  9. package/dist/lib/darwin_aarch64/libjemalloc_selva.2.dylib +0 -0
  10. package/dist/lib/darwin_aarch64/libnode-v22.node +0 -0
  11. package/dist/lib/darwin_aarch64/libselva.dylib +0 -0
  12. package/dist/lib/darwin_aarch64/libxxhash.dylib +0 -0
  13. package/dist/src/client/index.d.ts +2 -0
  14. package/dist/src/client/index.js +11 -2
  15. package/dist/src/client/modify/Ctx.d.ts +3 -5
  16. package/dist/src/client/modify/Ctx.js +0 -3
  17. package/dist/src/client/modify/Tmp.d.ts +2 -2
  18. package/dist/src/client/modify/Tmp.js +27 -23
  19. package/dist/src/client/modify/create/index.js +36 -25
  20. package/dist/src/client/modify/cursor.d.ts +0 -1
  21. package/dist/src/client/modify/cursor.js +10 -26
  22. package/dist/src/client/modify/delete/index.js +6 -6
  23. package/dist/src/client/modify/drain.js +20 -23
  24. package/dist/src/client/modify/edges/references.js +3 -2
  25. package/dist/src/client/modify/error.d.ts +2 -1
  26. package/dist/src/client/modify/error.js +2 -2
  27. package/dist/src/client/modify/expire/index.js +5 -6
  28. package/dist/src/client/modify/props/object.js +3 -2
  29. package/dist/src/client/modify/props/reference.js +3 -3
  30. package/dist/src/client/modify/props/references.js +2 -1
  31. package/dist/src/client/modify/types.d.ts +4 -1
  32. package/dist/src/client/modify/types.js +4 -0
  33. package/dist/src/client/modify/update/index.d.ts +3 -0
  34. package/dist/src/client/modify/update/index.js +33 -20
  35. package/dist/src/client/modify/upsert/index.d.ts +2 -1
  36. package/dist/src/client/modify/upsert/index.js +67 -44
  37. package/dist/src/client/query/BasedDbQuery.js +12 -7
  38. package/dist/src/client/query/aggregates/aggregation.d.ts +1 -1
  39. package/dist/src/client/query/aggregates/aggregation.js +24 -3
  40. package/dist/src/client/query/filter/convertFilter.js +16 -3
  41. package/dist/src/client/query/filter/types.d.ts +1 -1
  42. package/dist/src/client/query/include/include.js +2 -5
  43. package/dist/src/client/query/queryDefToReadSchema.js +20 -1
  44. package/dist/src/client/query/search/index.js +9 -1
  45. package/dist/src/client/string.d.ts +1 -1
  46. package/dist/src/client/string.js +1 -1
  47. package/dist/src/hooks.d.ts +3 -6
  48. package/dist/src/hooks.js +5 -12
  49. package/dist/src/index.d.ts +3 -3
  50. package/dist/src/index.js +5 -3
  51. package/dist/src/native.d.ts +4 -3
  52. package/dist/src/native.js +11 -10
  53. package/dist/src/server/blocks.js +1 -1
  54. package/dist/src/server/index.d.ts +3 -2
  55. package/dist/src/server/index.js +23 -47
  56. package/dist/src/server/migrate/index.js +4 -0
  57. package/dist/src/server/resizeModifyDirtyRanges.js +1 -1
  58. package/dist/src/server/save.d.ts +0 -1
  59. package/dist/src/server/save.js +2 -2
  60. package/dist/src/server/schema.js +6 -1
  61. package/dist/src/server/start.js +0 -2
  62. package/dist/src/shared/Emitter.d.ts +1 -1
  63. package/dist/src/utils.d.ts +0 -2
  64. package/dist/src/utils.js +1 -3
  65. package/package.json +17 -7
  66. package/dist/lib/darwin_aarch64/libnode-v23.node +0 -0
  67. package/dist/lib/darwin_aarch64/libnode-v24.node +0 -0
  68. package/dist/lib/linux_aarch64/include/cdefs.h +0 -317
  69. package/dist/lib/linux_aarch64/include/jemalloc.h +0 -468
  70. package/dist/lib/linux_aarch64/include/libdeflate.h +0 -345
  71. package/dist/lib/linux_aarch64/include/libdeflate_strings.h +0 -35
  72. package/dist/lib/linux_aarch64/include/linker_set.h +0 -109
  73. package/dist/lib/linux_aarch64/include/queue.h +0 -627
  74. package/dist/lib/linux_aarch64/include/selva/_export.h +0 -7
  75. package/dist/lib/linux_aarch64/include/selva/align.h +0 -9
  76. package/dist/lib/linux_aarch64/include/selva/backoff_timeout.h +0 -29
  77. package/dist/lib/linux_aarch64/include/selva/bitmap.h +0 -95
  78. package/dist/lib/linux_aarch64/include/selva/colvec.h +0 -71
  79. package/dist/lib/linux_aarch64/include/selva/crc32c.h +0 -17
  80. package/dist/lib/linux_aarch64/include/selva/ctime.h +0 -135
  81. package/dist/lib/linux_aarch64/include/selva/db.h +0 -407
  82. package/dist/lib/linux_aarch64/include/selva/endian.h +0 -301
  83. package/dist/lib/linux_aarch64/include/selva/fast_linear_search.h +0 -27
  84. package/dist/lib/linux_aarch64/include/selva/fast_memcmp.h +0 -18
  85. package/dist/lib/linux_aarch64/include/selva/fast_memmem.h +0 -11
  86. package/dist/lib/linux_aarch64/include/selva/fast_parsei.h +0 -36
  87. package/dist/lib/linux_aarch64/include/selva/fields.h +0 -407
  88. package/dist/lib/linux_aarch64/include/selva/gmtime.h +0 -137
  89. package/dist/lib/linux_aarch64/include/selva/hll.h +0 -85
  90. package/dist/lib/linux_aarch64/include/selva/lpf.h +0 -28
  91. package/dist/lib/linux_aarch64/include/selva/mblen.h +0 -40
  92. package/dist/lib/linux_aarch64/include/selva/membar.h +0 -32
  93. package/dist/lib/linux_aarch64/include/selva/node_id_set.h +0 -43
  94. package/dist/lib/linux_aarch64/include/selva/poptop.h +0 -114
  95. package/dist/lib/linux_aarch64/include/selva/selva_hash128.h +0 -49
  96. package/dist/lib/linux_aarch64/include/selva/selva_lang.h +0 -105
  97. package/dist/lib/linux_aarch64/include/selva/selva_math.h +0 -37
  98. package/dist/lib/linux_aarch64/include/selva/selva_string.h +0 -679
  99. package/dist/lib/linux_aarch64/include/selva/sort.h +0 -140
  100. package/dist/lib/linux_aarch64/include/selva/strsearch.h +0 -43
  101. package/dist/lib/linux_aarch64/include/selva/thread.h +0 -37
  102. package/dist/lib/linux_aarch64/include/selva/timestamp.h +0 -25
  103. package/dist/lib/linux_aarch64/include/selva/types.h +0 -129
  104. package/dist/lib/linux_aarch64/include/selva/vector.h +0 -35
  105. package/dist/lib/linux_aarch64/include/selva_error.h +0 -140
  106. package/dist/lib/linux_aarch64/include/selva_lang_code.h +0 -160
  107. package/dist/lib/linux_aarch64/include/tree.h +0 -852
  108. package/dist/lib/linux_aarch64/libdeflate.so +0 -0
  109. package/dist/lib/linux_aarch64/libjemalloc_selva.so.2 +0 -0
  110. package/dist/lib/linux_aarch64/libnode-v22.node +0 -0
  111. package/dist/lib/linux_aarch64/libnode-v23.node +0 -0
  112. package/dist/lib/linux_aarch64/libnode-v24.node +0 -0
  113. package/dist/lib/linux_aarch64/libselva.so +0 -0
  114. package/dist/lib/linux_aarch64/libxxhash.so.0 +0 -0
  115. package/dist/lib/linux_x86_64/include/cdefs.h +0 -317
  116. package/dist/lib/linux_x86_64/include/jemalloc.h +0 -468
  117. package/dist/lib/linux_x86_64/include/libdeflate.h +0 -345
  118. package/dist/lib/linux_x86_64/include/libdeflate_strings.h +0 -35
  119. package/dist/lib/linux_x86_64/include/linker_set.h +0 -109
  120. package/dist/lib/linux_x86_64/include/queue.h +0 -627
  121. package/dist/lib/linux_x86_64/include/selva/_export.h +0 -7
  122. package/dist/lib/linux_x86_64/include/selva/align.h +0 -9
  123. package/dist/lib/linux_x86_64/include/selva/backoff_timeout.h +0 -29
  124. package/dist/lib/linux_x86_64/include/selva/bitmap.h +0 -95
  125. package/dist/lib/linux_x86_64/include/selva/colvec.h +0 -71
  126. package/dist/lib/linux_x86_64/include/selva/crc32c.h +0 -17
  127. package/dist/lib/linux_x86_64/include/selva/ctime.h +0 -135
  128. package/dist/lib/linux_x86_64/include/selva/db.h +0 -407
  129. package/dist/lib/linux_x86_64/include/selva/endian.h +0 -301
  130. package/dist/lib/linux_x86_64/include/selva/fast_linear_search.h +0 -27
  131. package/dist/lib/linux_x86_64/include/selva/fast_memcmp.h +0 -18
  132. package/dist/lib/linux_x86_64/include/selva/fast_memmem.h +0 -11
  133. package/dist/lib/linux_x86_64/include/selva/fast_parsei.h +0 -36
  134. package/dist/lib/linux_x86_64/include/selva/fields.h +0 -407
  135. package/dist/lib/linux_x86_64/include/selva/gmtime.h +0 -137
  136. package/dist/lib/linux_x86_64/include/selva/hll.h +0 -85
  137. package/dist/lib/linux_x86_64/include/selva/lpf.h +0 -28
  138. package/dist/lib/linux_x86_64/include/selva/mblen.h +0 -40
  139. package/dist/lib/linux_x86_64/include/selva/membar.h +0 -32
  140. package/dist/lib/linux_x86_64/include/selva/node_id_set.h +0 -43
  141. package/dist/lib/linux_x86_64/include/selva/poptop.h +0 -114
  142. package/dist/lib/linux_x86_64/include/selva/selva_hash128.h +0 -49
  143. package/dist/lib/linux_x86_64/include/selva/selva_lang.h +0 -105
  144. package/dist/lib/linux_x86_64/include/selva/selva_math.h +0 -37
  145. package/dist/lib/linux_x86_64/include/selva/selva_string.h +0 -679
  146. package/dist/lib/linux_x86_64/include/selva/sort.h +0 -140
  147. package/dist/lib/linux_x86_64/include/selva/strsearch.h +0 -43
  148. package/dist/lib/linux_x86_64/include/selva/thread.h +0 -37
  149. package/dist/lib/linux_x86_64/include/selva/timestamp.h +0 -25
  150. package/dist/lib/linux_x86_64/include/selva/types.h +0 -129
  151. package/dist/lib/linux_x86_64/include/selva/vector.h +0 -35
  152. package/dist/lib/linux_x86_64/include/selva_error.h +0 -140
  153. package/dist/lib/linux_x86_64/include/selva_lang_code.h +0 -160
  154. package/dist/lib/linux_x86_64/include/tree.h +0 -852
  155. package/dist/lib/linux_x86_64/libdeflate.so +0 -0
  156. package/dist/lib/linux_x86_64/libjemalloc_selva.so.2 +0 -0
  157. package/dist/lib/linux_x86_64/libnode-v22.node +0 -0
  158. package/dist/lib/linux_x86_64/libnode-v23.node +0 -0
  159. package/dist/lib/linux_x86_64/libnode-v24.node +0 -0
  160. package/dist/lib/linux_x86_64/libselva.so +0 -0
  161. package/dist/lib/linux_x86_64/libxxhash.so.0 +0 -0
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ const os = require('os');
3
+ const path = require('path');
4
+ const process = require('process');
5
+ const platform = os.platform();
6
+ const arch = os.arch();
7
+ const nodeMajorVersion = parseInt(process.version.match(/^v?(\d+)/)[1], 10);
8
+ const baseDir = path.join(__dirname, 'dist/lib');
9
+ let platformDir;
10
+ switch (platform) {
11
+ case 'darwin':
12
+ platformDir = arch === 'arm64' ? 'darwin_aarch64' : 'darwin_x86_64';
13
+ break;
14
+ case 'linux':
15
+ platformDir = arch === 'arm64' ? 'linux_aarch64' : 'linux_x86_64';
16
+ break;
17
+ default:
18
+ throw new Error(`Unsupported platform: ${platform}`);
19
+ }
20
+ const libPath = path.join(baseDir, platformDir, `libnode-v${nodeMajorVersion}.node`);
21
+ const addon = require(libPath);
22
+ module.exports = addon;
23
+ //# sourceMappingURL=basedDbNative.cjs.map
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright (c) 2020-2024 SAULX
2
+ * Copyright (c) 2020-2025 SAULX
3
3
  * SPDX-License-Identifier: BSD-2-Clause
4
4
  */
5
5
 
@@ -51,6 +51,9 @@
51
51
  #define __constfn
52
52
  #endif
53
53
 
54
+ /**
55
+ * The last argument to a function is expected to be nullptr.
56
+ */
54
57
  #define __sentinel __attribute__((sentinel))
55
58
 
56
59
  #if __has_c_attribute(noreturn)
@@ -5,6 +5,7 @@
5
5
  #pragma once
6
6
 
7
7
  #include <assert.h>
8
+ #include <stddef.h>
8
9
  #include <stdint.h>
9
10
  #include <sys/types.h>
10
11
  #include "selva/_export.h"
@@ -16,6 +17,20 @@
16
17
  */
17
18
  struct XXH3_state_s;
18
19
 
20
+ struct selva_dump_common_data {
21
+ /**
22
+ * Pointer to data returned here when loading; Data read from here when saving.
23
+ */
24
+ const void *meta_data __pcounted_by(meta_len);
25
+ size_t meta_len;
26
+
27
+ /**
28
+ * Can be nullptr. Also set errlog_size to 0.
29
+ */
30
+ char *errlog_buf __pcounted_by(errlog_size);
31
+ size_t errlog_size;
32
+ };
33
+
19
34
  /**
20
35
  * Create a new DB instance.
21
36
  */
@@ -39,7 +54,7 @@ int selva_db_create_type(struct SelvaDb *db, node_type_t type, const uint8_t *sc
39
54
  * Save the common/shared data of the database.
40
55
  */
41
56
  SELVA_EXPORT
42
- int selva_dump_save_common(struct SelvaDb *db, const char *filename) __attribute__((nonnull));
57
+ int selva_dump_save_common(struct SelvaDb *db, struct selva_dump_common_data *com, const char *filename) __attribute__((nonnull));
43
58
 
44
59
  /**
45
60
  * Save a nodes block starting from start.
@@ -56,7 +71,7 @@ int selva_dump_save_block(struct SelvaDb *db, struct SelvaTypeEntry *te, const c
56
71
  * ```
57
72
  */
58
73
  SELVA_EXPORT
59
- int selva_dump_load_common(struct SelvaDb *db, const char *filename, char *errlog_buf, size_t errlog_size) __attribute__((nonnull));
74
+ int selva_dump_load_common(struct SelvaDb *db, struct selva_dump_common_data *com, const char *filename) __attribute__((nonnull));
60
75
 
61
76
  SELVA_EXPORT
62
77
  int selva_dump_load_block(struct SelvaDb *db, const char *filename, char *errlog_buf, size_t errlog_size) __attribute__((nonnull));
@@ -124,11 +139,10 @@ inline const struct SelvaNodeSchema *selva_get_ns_by_te(const struct SelvaTypeEn
124
139
  #endif
125
140
 
126
141
  SELVA_EXPORT
127
- __attribute__((nonnull, pure))
128
142
  inline const struct SelvaFieldSchema *get_fs_by_fields_schema_field(const struct SelvaFieldsSchema *fields_schema, field_t field)
129
143
  #ifndef __zig
130
144
  {
131
- if (field >= fields_schema->nr_fields) {
145
+ if (!fields_schema || field >= fields_schema->nr_fields) {
132
146
  return nullptr;
133
147
  }
134
148
 
@@ -223,7 +237,16 @@ inline const struct EdgeFieldConstraint *selva_get_edge_field_constraint(const s
223
237
  #endif
224
238
 
225
239
  SELVA_EXPORT
226
- const struct SelvaFieldsSchema *selva_get_edge_field_fields_schema(struct SelvaDb *db, const struct EdgeFieldConstraint *efc);
240
+ inline const struct SelvaFieldsSchema *selva_get_edge_field_fields_schema(struct SelvaDb *db, const struct EdgeFieldConstraint *efc)
241
+ #ifndef __zig
242
+ {
243
+ struct SelvaTypeEntry *te = selva_get_type_by_index(db, efc->meta_node_type);
244
+
245
+ return (te) ? &selva_get_ns_by_te(te)->fields_schema : nullptr;
246
+ }
247
+ #else
248
+ ;
249
+ #endif
227
250
 
228
251
  SELVA_EXPORT
229
252
  void selva_expire_node(struct SelvaDb *db, node_type_t type, node_id_t node_id, int64_t ts);
@@ -21,7 +21,7 @@ SELVA_EXPORT
21
21
  ssize_t fast_linear_search_node(const struct SelvaNode *arr[], size_t len, const struct SelvaNode *x);
22
22
 
23
23
  SELVA_EXPORT
24
- ssize_t fast_linear_search_references_small(const struct SelvaNodeSmallReference *arr, size_t len, const struct SelvaNode *x);
24
+ ssize_t fast_linear_search_references_small(const struct SelvaNodeSmallReference *arr, size_t len, node_id_t x);
25
25
 
26
26
  SELVA_EXPORT
27
- ssize_t fast_linear_search_references_large(const struct SelvaNodeLargeReference *arr, size_t len, const struct SelvaNode *x);
27
+ ssize_t fast_linear_search_references_large(const struct SelvaNodeLargeReference *arr, size_t len, node_id_t x);
@@ -25,12 +25,12 @@ struct SelvaTextField {
25
25
  #endif
26
26
 
27
27
  struct SelvaNodeSmallReference {
28
- struct SelvaNode *dst;
28
+ node_id_t dst;
29
29
  };
30
30
 
31
31
  struct SelvaNodeLargeReference {
32
- struct SelvaNode *dst;
33
- struct SelvaFields *meta;
32
+ node_id_t dst;
33
+ node_id_t meta;
34
34
  };
35
35
 
36
36
  enum SelvaNodeReferenceType {
@@ -116,12 +116,14 @@ void *selva_fields_nfo2p(struct SelvaFields *fields, const struct SelvaFieldInfo
116
116
  SELVA_EXPORT
117
117
  struct SelvaFields *selva_fields_node2fields(struct SelvaNode *node);
118
118
 
119
- void selva_fields_ensure_ref_meta(
119
+ SELVA_EXPORT
120
+ struct SelvaNode *selva_fields_ensure_ref_meta(
120
121
  struct SelvaDb *db,
121
122
  struct SelvaNode *node,
123
+ const struct EdgeFieldConstraint *efc,
122
124
  struct SelvaNodeLargeReference *ref,
123
- const struct EdgeFieldConstraint *efc)
124
- __attribute__((nonnull));
125
+ node_id_t meta_id,
126
+ selva_dirty_node_cb_t dirty_cb, void *dirty_ctx);
125
127
 
126
128
  SELVA_EXPORT
127
129
  int selva_fields_get_mutable_string(
@@ -143,15 +145,6 @@ struct selva_string *selva_fields_ensure_string(
143
145
  const struct SelvaFieldSchema *fs,
144
146
  size_t initial_len);
145
147
 
146
- SELVA_EXPORT
147
- struct selva_string *selva_fields_ensure_string2(
148
- struct SelvaDb *db,
149
- struct SelvaNode *node,
150
- const struct EdgeFieldConstraint *efc,
151
- struct SelvaNodeLargeReference *ref,
152
- const struct SelvaFieldSchema *fs,
153
- size_t initial_len);
154
-
155
148
  /**
156
149
  * Set reference to fields.
157
150
  */
@@ -179,7 +172,8 @@ int selva_fields_references_insert(
179
172
  bool reorder,
180
173
  struct SelvaTypeEntry *te_dst,
181
174
  struct SelvaNode * restrict dst,
182
- struct SelvaNodeReferenceAny *ref_out)
175
+ struct SelvaNodeReferenceAny *ref_out,
176
+ selva_dirty_node_cb_t dirty_cb, void *dirty_ctx, bool ignore_src_dependent)
183
177
  __attribute__((access(write_only, 8)));
184
178
 
185
179
  /**
@@ -196,7 +190,8 @@ int selva_fields_references_insert_tail_wupsert(
196
190
  const struct SelvaFieldSchema *fs,
197
191
  struct SelvaTypeEntry *te_dst,
198
192
  const node_id_t ids[],
199
- size_t nr_ids)
193
+ size_t nr_ids,
194
+ selva_dirty_node_cb_t dirty_cb, void *dirty_ctx)
200
195
  __attribute__((access(read_only, 5, 6)));
201
196
 
202
197
  /**
@@ -223,25 +218,6 @@ int selva_fields_references_swap(
223
218
  size_t index_a,
224
219
  size_t index_b);
225
220
 
226
- SELVA_EXPORT
227
- int selva_fields_set_reference_meta(
228
- struct SelvaDb *db,
229
- struct SelvaNode *node,
230
- struct SelvaNodeLargeReference *ref,
231
- const struct EdgeFieldConstraint *efc,
232
- const struct SelvaFieldSchema *efs,
233
- const void *value, size_t len);
234
-
235
- SELVA_EXPORT
236
- int selva_fields_get_reference_meta_mutable_string(
237
- struct SelvaDb *db,
238
- struct SelvaNode *node,
239
- struct SelvaNodeLargeReference *ref,
240
- const struct EdgeFieldConstraint *efc,
241
- const struct SelvaFieldSchema *efs,
242
- size_t len,
243
- struct selva_string **s);
244
-
245
221
  /**
246
222
  * Set string field.
247
223
  *
@@ -339,10 +315,6 @@ struct SelvaNode *selva_fields_resolve_weak_reference(
339
315
  const struct SelvaNodeWeakReference *weak_ref)
340
316
  __attribute__((nonnull));
341
317
 
342
- SELVA_EXPORT
343
- struct selva_string *selva_fields_get_selva_string3(struct SelvaDb *db, struct SelvaNodeLargeReference *ref, const struct SelvaFieldSchema *fs)
344
- __attribute__((nonnull));
345
-
346
318
  SELVA_EXPORT
347
319
  struct selva_string *selva_fields_get_selva_string2(struct SelvaFields *fields, const struct SelvaFieldSchema *fs)
348
320
  __attribute__((nonnull));
@@ -374,7 +346,7 @@ int selva_fields_del(struct SelvaDb *db, struct SelvaNode *node, const struct Se
374
346
  * Delete an edge from a references field.
375
347
  */
376
348
  SELVA_EXPORT
377
- int selva_fields_del_ref(struct SelvaDb *db, struct SelvaNode *node, const struct SelvaFieldSchema *fs, node_id_t dst_node_id);
349
+ int selva_fields_del_ref(struct SelvaDb *db, struct SelvaNode *node, const struct SelvaFieldSchema *fs, node_id_t dst_node_id, selva_dirty_node_cb_t dirty_cb, void *dirty_ctx);
378
350
 
379
351
  /**
380
352
  * Clear a references field but don't free it.
@@ -244,7 +244,11 @@ typedef union {
244
244
  * @param s is a pointer to a selva_string.
245
245
  */
246
246
  SELVA_EXPORT
247
+ #ifdef __zig
248
+ void selva_string_free(struct selva_string *s);
249
+ #else
247
250
  void selva_string_free(_selva_string_ptr_t s);
251
+ #endif
248
252
 
249
253
  /**
250
254
  * Add a selva_string to the given finalizer.
@@ -48,26 +48,16 @@ enum SelvaFieldType {
48
48
  struct EdgeFieldConstraint {
49
49
  enum EdgeFieldConstraintFlag {
50
50
  EDGE_FIELD_CONSTRAINT_FLAG_DEPENDENT = 0x01,
51
- /**
52
- * _fields_schema is referenced from the opposite efc and shouldn't be freed.
53
- */
54
- EDGE_FIELD_CONSTRAINT_FLAG_SCHEMA_REF_CACHED = 0x40,
55
51
  /**
56
52
  * Skip saving this field while dumping.
57
53
  * If the field is of type SELVA_FIELD_TYPE_REFERENCES it's saved
58
54
  * regardless of this flag to preserve the original order of references.
59
- * However, the meta is only save from one side, i.e. the side that's
60
- * not skipped.
61
55
  */
62
56
  EDGE_FIELD_CONSTRAINT_FLAG_SKIP_DUMP = 0x80,
63
57
  } __packed flags;
64
58
  field_t inverse_field;
65
59
  node_type_t dst_node_type;
66
- /**
67
- * Don't use directly!
68
- * Use: `selva_get_edge_field_fields_schema()`
69
- */
70
- struct SelvaFieldsSchema *_fields_schema;
60
+ node_type_t meta_node_type;
71
61
  };
72
62
 
73
63
  struct SelvaFieldSchema {
@@ -14,6 +14,7 @@ type DbClientOpts = {
14
14
  export declare class DbClient extends DbShared {
15
15
  constructor({ hooks, maxModifySize, flushTime, debug, }: DbClientOpts);
16
16
  subs: Map<BasedDbQuery, SubStore>;
17
+ stopped: boolean;
17
18
  hooks: DbClientHooks;
18
19
  flushTime: number;
19
20
  writeTime: number;
@@ -36,6 +37,7 @@ export declare class DbClient extends DbShared {
36
37
  }, opts?: ModifyOpts): Promise<number>;
37
38
  update(value: Record<string, any>, opts?: ModifyOpts): Promise<number>;
38
39
  upsert(type: string, obj: Record<string, any>, opts?: ModifyOpts): Promise<number>;
40
+ insert(type: string, obj: Record<string, any>, opts?: ModifyOpts): Promise<number>;
39
41
  delete(type: string, id: number | Promise<number>): any;
40
42
  expire(type: string, id: number, seconds: number): Promise<number>;
41
43
  destroy(): void;
@@ -1,4 +1,4 @@
1
- import { parse } from '@based/schema';
1
+ import { parse, } from '@based/schema';
2
2
  import { BasedDbQuery } from './query/BasedDbQuery.js';
3
3
  import { debugMode } from '../utils.js';
4
4
  import { DbShared } from '../shared/DbBase.js';
@@ -9,7 +9,7 @@ import { update } from './modify/update/index.js';
9
9
  import { del } from './modify/delete/index.js';
10
10
  import { expire } from './modify/expire/index.js';
11
11
  import { cancel, drain, schedule } from './modify/drain.js';
12
- import { upsert } from './modify/upsert/index.js';
12
+ import { insert, upsert } from './modify/upsert/index.js';
13
13
  export class DbClient extends DbShared {
14
14
  constructor({ hooks, maxModifySize = 100 * 1e3 * 1e3, flushTime = 0, debug, }) {
15
15
  super();
@@ -27,6 +27,7 @@ export class DbClient extends DbShared {
27
27
  });
28
28
  }
29
29
  subs = new Map();
30
+ stopped;
30
31
  hooks;
31
32
  // modify
32
33
  flushTime;
@@ -44,6 +45,9 @@ export class DbClient extends DbShared {
44
45
  const strictSchema = parse(schema).schema;
45
46
  await this.drain();
46
47
  const schemaChecksum = await this.hooks.setSchema(strictSchema, transformFns);
48
+ if (this.stopped) {
49
+ return this.schema.hash;
50
+ }
47
51
  if (schemaChecksum !== this.schema?.hash) {
48
52
  await this.once('schema');
49
53
  return this.schema.hash;
@@ -119,6 +123,9 @@ export class DbClient extends DbShared {
119
123
  upsert(type, obj, opts) {
120
124
  return upsert(this, type, obj, opts);
121
125
  }
126
+ insert(type, obj, opts) {
127
+ return insert(this, type, obj, opts);
128
+ }
122
129
  delete(type, id) {
123
130
  if (typeof id === 'object' &&
124
131
  id !== null &&
@@ -130,6 +137,7 @@ export class DbClient extends DbShared {
130
137
  id = id.id;
131
138
  }
132
139
  else {
140
+ // @ts-ignore
133
141
  return id.then((id) => this.delete(type, id));
134
142
  }
135
143
  }
@@ -144,6 +152,7 @@ export class DbClient extends DbShared {
144
152
  delete this.listeners;
145
153
  }
146
154
  stop() {
155
+ this.stopped = true;
147
156
  for (const [, { onClose }] of this.subs) {
148
157
  onClose();
149
158
  }
@@ -4,7 +4,6 @@ import { type ModifyOp } from './types.js';
4
4
  import type { Tmp } from './Tmp.js';
5
5
  export declare class Ctx {
6
6
  constructor(schemaChecksum: number, array: Uint8Array<ArrayBufferLike>);
7
- id: number;
8
7
  start: number;
9
8
  index: number;
10
9
  schema: SchemaTypeDef;
@@ -12,26 +11,25 @@ export declare class Ctx {
12
11
  max: number;
13
12
  size: number;
14
13
  unsafe?: boolean;
15
- overwrite?: boolean;
16
14
  operation: ModifyOp;
17
15
  main: Map<PropDef, any>;
18
16
  draining: Promise<void>;
19
17
  scheduled: Promise<void>;
20
- created: Record<number, number>;
21
18
  locale: LangCode;
22
19
  sort: number;
23
20
  sortText: number;
24
21
  defaults: number;
25
22
  cursor: {
26
- id?: number;
27
23
  type?: number;
28
24
  prop?: number;
29
25
  main?: number;
30
26
  operation?: ModifyOp;
27
+ upserting?: boolean;
31
28
  };
32
29
  batch: {
30
+ count?: number;
33
31
  promises?: Tmp[];
34
- offsets?: Record<number, number>;
32
+ res?: Uint8Array;
35
33
  ready?: boolean;
36
34
  error?: Error;
37
35
  };
@@ -6,7 +6,6 @@ export class Ctx {
6
6
  this.size = array.buffer.byteLength - 4;
7
7
  writeUint64(array, schemaChecksum, 0);
8
8
  }
9
- id;
10
9
  start;
11
10
  index = 8;
12
11
  schema;
@@ -14,12 +13,10 @@ export class Ctx {
14
13
  max;
15
14
  size;
16
15
  unsafe;
17
- overwrite;
18
16
  operation;
19
17
  main = new Map();
20
18
  draining;
21
19
  scheduled;
22
- created = {}; // <typeId, count
23
20
  locale;
24
21
  sort = 0;
25
22
  sortText = 0;
@@ -3,8 +3,8 @@ export declare const resolveTmp: (tmp: Tmp) => void;
3
3
  export declare const rejectTmp: (tmp: Tmp) => void;
4
4
  export declare class Tmp implements Promise<number> {
5
5
  #private;
6
- constructor(ctx: Ctx, id?: number);
7
- get [Symbol.toStringTag](): string;
6
+ constructor(ctx: Ctx);
7
+ [Symbol.toStringTag]: 'ModifyPromise';
8
8
  get error(): Error;
9
9
  get id(): number;
10
10
  type: number;
@@ -1,8 +1,14 @@
1
+ import { readUint32 } from '@based/utils';
1
2
  const promisify = (tmp) => {
2
3
  if (!tmp.promise) {
3
- const id = tmp.id;
4
- if (id) {
5
- tmp.promise = Promise.resolve(id);
4
+ if (tmp.batch.ready) {
5
+ const id = tmp.id;
6
+ if (id) {
7
+ tmp.promise = Promise.resolve(id);
8
+ }
9
+ else {
10
+ tmp.promise = Promise.reject(tmp.error);
11
+ }
6
12
  }
7
13
  else {
8
14
  tmp.promise = new Promise((resolve, reject) => {
@@ -16,37 +22,35 @@ const promisify = (tmp) => {
16
22
  return tmp.promise;
17
23
  };
18
24
  export const resolveTmp = (tmp) => {
19
- tmp.resolve(tmp.id);
25
+ const id = tmp.id;
26
+ if (id) {
27
+ return tmp.resolve(tmp.id);
28
+ }
29
+ return tmp.reject(tmp.error);
30
+ };
31
+ export const rejectTmp = (tmp) => {
32
+ return tmp.reject(tmp.error);
20
33
  };
21
- export const rejectTmp = (tmp) => tmp.reject(tmp.error);
22
34
  export class Tmp {
23
- constructor(ctx, id) {
35
+ constructor(ctx) {
36
+ ctx.batch.count ??= 0;
24
37
  this.type = ctx.cursor.type;
25
- this.tmpId = ctx.id;
26
38
  this.batch = ctx.batch;
27
- this.#id = id;
28
- }
29
- get [Symbol.toStringTag]() {
30
- return 'ModifyPromise';
39
+ this.tmpId = ctx.batch.count++;
31
40
  }
41
+ [Symbol.toStringTag];
32
42
  #id;
33
43
  get error() {
34
- if (!this.batch.ready) {
35
- return;
44
+ if (this.batch.ready) {
45
+ // TODO: also handle individual errors here
46
+ return this.batch.error;
36
47
  }
37
- return this.batch.error;
38
48
  }
39
49
  get id() {
40
- if (!this.batch.ready) {
41
- return;
42
- }
43
- if (!this.#id) {
44
- if (this.batch.offsets) {
45
- const offset = this.batch.offsets[this.type];
46
- this.#id = this.tmpId + offset;
47
- }
50
+ if (this.batch.ready) {
51
+ this.#id ??= this.batch.res && readUint32(this.batch.res, this.tmpId * 5);
52
+ return this.#id;
48
53
  }
49
- return this.#id;
50
54
  }
51
55
  type;
52
56
  tmpId;
@@ -1,19 +1,19 @@
1
1
  import { TEXT } from '@based/schema/def';
2
2
  import { writeObject } from '../props/object.js';
3
3
  import { reserve } from '../resize.js';
4
- import { FULL_CURSOR_SIZE, PROP_CURSOR_SIZE, writeMainCursor, writeNodeCursor, writeTypeCursor, } from '../cursor.js';
4
+ import { FULL_CURSOR_SIZE, PROP_CURSOR_SIZE, writeMainCursor, writeTypeCursor, } from '../cursor.js';
5
5
  import { getByPath, writeUint16 } from '@based/utils';
6
6
  import { writeMainBuffer, writeMainValue } from '../props/main.js';
7
7
  import { Tmp } from '../Tmp.js';
8
8
  import { schedule } from '../drain.js';
9
- import { ADD_EMPTY_SORT, ADD_EMPTY_SORT_TEXT, CREATE, } from '../types.js';
9
+ import { ADD_EMPTY_SORT, ADD_EMPTY_SORT_TEXT, CREATE, PADDING, SWITCH_ID_CREATE, SWITCH_ID_CREATE_UNSAFE, } from '../types.js';
10
10
  import { inverseLangMap, langCodesMap } from '@based/schema';
11
11
  import { writeSeparate } from '../props/separate.js';
12
12
  import { writeString } from '../props/string.js';
13
- import { writeU8 } from '../uint.js';
13
+ import { writeU32, writeU8 } from '../uint.js';
14
14
  import { getValidSchema, validatePayload } from '../validate.js';
15
15
  import { handleError } from '../error.js';
16
- const writeDefaults = (ctx, payload) => {
16
+ const writeDefaults = (ctx) => {
17
17
  if (!ctx.schema.hasSeperateDefaults) {
18
18
  return;
19
19
  }
@@ -119,23 +119,22 @@ const writeCreateTs = (ctx, payload) => {
119
119
  };
120
120
  export const writeCreate = (ctx, schema, payload, opts) => {
121
121
  validatePayload(payload);
122
- validatePayload(schema);
123
- if (schema.hooks?.create) {
124
- payload = schema.hooks.create(payload) || payload;
125
- }
126
- if (payload.id) {
127
- if (!opts?.unsafe) {
128
- throw 'Invalid payload. "id" not allowed';
122
+ if (schema.propHooks?.create) {
123
+ for (const def of schema.propHooks.create) {
124
+ let val = payload;
125
+ let obj;
126
+ let key;
127
+ for (key of def.path) {
128
+ obj = val;
129
+ val = val?.[key];
130
+ }
131
+ if (val !== undefined) {
132
+ obj[key] = def.hooks.create(val, obj);
133
+ }
129
134
  }
130
- ctx.id = payload.id;
131
135
  }
132
- else {
133
- if (!(schema.id in ctx.created)) {
134
- ctx.created[schema.id] = 0;
135
- ctx.max -= 6;
136
- ctx.size -= 6;
137
- }
138
- ctx.id = ctx.created[schema.id] + 1;
136
+ if (schema.hooks?.create) {
137
+ payload = schema.hooks.create(payload) || payload;
139
138
  }
140
139
  if (ctx.defaults) {
141
140
  ctx.defaults = 0;
@@ -151,13 +150,24 @@ export const writeCreate = (ctx, schema, payload, opts) => {
151
150
  }
152
151
  ctx.schema = schema;
153
152
  ctx.operation = CREATE;
154
- ctx.overwrite = true;
155
153
  ctx.unsafe = opts?.unsafe;
156
154
  ctx.locale = opts?.locale && langCodesMap.get(opts.locale);
157
- ctx.start = ctx.index;
155
+ // TODO: can we remove this (and just init main buffer here?)
156
+ ctx.cursor.main = null;
158
157
  reserve(ctx, FULL_CURSOR_SIZE);
159
158
  writeTypeCursor(ctx);
160
- writeNodeCursor(ctx);
159
+ if (payload.id) {
160
+ if (ctx.unsafe) {
161
+ writeU8(ctx, SWITCH_ID_CREATE_UNSAFE);
162
+ writeU32(ctx, payload.id);
163
+ }
164
+ else {
165
+ throw 'Invalid payload. "id" not allowed';
166
+ }
167
+ }
168
+ else {
169
+ writeU8(ctx, SWITCH_ID_CREATE);
170
+ }
161
171
  const index = ctx.index;
162
172
  writeObject(ctx, ctx.schema.tree, payload);
163
173
  if (ctx.index === index || ctx.schema.mainLen === 0) {
@@ -168,16 +178,17 @@ export const writeCreate = (ctx, schema, payload, opts) => {
168
178
  if (!ctx.cursor.main && !ctx.schema.mainEmptyAllZeroes) {
169
179
  writeMainBuffer(ctx);
170
180
  }
171
- writeDefaults(ctx, payload);
181
+ writeDefaults(ctx);
172
182
  writeSortable(ctx);
173
183
  writeSortableText(ctx);
174
- if (schema.id in ctx.created) {
175
- ctx.created[schema.id]++;
184
+ while (ctx.index < ctx.start + 5) {
185
+ writeU8(ctx, PADDING);
176
186
  }
177
187
  };
178
188
  export function create(db, type, payload, opts) {
179
189
  const schema = getValidSchema(db, type);
180
190
  const ctx = db.modifyCtx;
191
+ ctx.start = ctx.index;
181
192
  try {
182
193
  writeCreate(ctx, schema, payload, opts);
183
194
  const tmp = new Tmp(ctx);
@@ -7,4 +7,3 @@ export declare const FULL_CURSOR_SIZE: number;
7
7
  export declare const writeTypeCursor: (ctx: Ctx) => void;
8
8
  export declare const writePropCursor: (ctx: Ctx, def: PropDef, typeIndex?: import("@based/schema/prop-types").TypeIndex) => void;
9
9
  export declare const writeMainCursor: (ctx: Ctx) => void;
10
- export declare const writeNodeCursor: (ctx: Ctx) => void;