@based/db 0.1.5 → 0.2.1

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 (118) hide show
  1. package/dist/lib/darwin_aarch64/include/cdefs.h +4 -0
  2. package/dist/lib/darwin_aarch64/include/selva/db.h +25 -5
  3. package/dist/lib/darwin_aarch64/include/selva/fields.h +34 -72
  4. package/dist/lib/darwin_aarch64/include/selva/selva_lang.h +7 -0
  5. package/dist/lib/darwin_aarch64/include/selva/types.h +9 -13
  6. package/dist/lib/darwin_aarch64/libnode-v22.node +0 -0
  7. package/dist/lib/darwin_aarch64/libnode-v23.node +0 -0
  8. package/dist/lib/darwin_aarch64/libnode-v24.node +0 -0
  9. package/dist/lib/darwin_aarch64/libnode-v25.node +0 -0
  10. package/dist/lib/darwin_aarch64/libselva.dylib +0 -0
  11. package/dist/lib/linux_aarch64/include/cdefs.h +4 -0
  12. package/dist/lib/linux_aarch64/include/selva/db.h +25 -5
  13. package/dist/lib/linux_aarch64/include/selva/fields.h +34 -72
  14. package/dist/lib/linux_aarch64/include/selva/selva_lang.h +7 -0
  15. package/dist/lib/linux_aarch64/include/selva/types.h +9 -13
  16. package/dist/lib/linux_aarch64/libdeflate.so +0 -0
  17. package/dist/lib/linux_aarch64/libnode-v22.node +0 -0
  18. package/dist/lib/linux_aarch64/libnode-v23.node +0 -0
  19. package/dist/lib/linux_aarch64/libnode-v24.node +0 -0
  20. package/dist/lib/linux_aarch64/libnode-v25.node +0 -0
  21. package/dist/lib/linux_aarch64/libselva.so +0 -0
  22. package/dist/lib/linux_x86_64/include/cdefs.h +4 -0
  23. package/dist/lib/linux_x86_64/include/selva/db.h +25 -5
  24. package/dist/lib/linux_x86_64/include/selva/fields.h +34 -72
  25. package/dist/lib/linux_x86_64/include/selva/selva_lang.h +7 -0
  26. package/dist/lib/linux_x86_64/include/selva/types.h +9 -13
  27. package/dist/lib/linux_x86_64/libdeflate.so +0 -0
  28. package/dist/lib/linux_x86_64/libnode-v22.node +0 -0
  29. package/dist/lib/linux_x86_64/libnode-v23.node +0 -0
  30. package/dist/lib/linux_x86_64/libnode-v24.node +0 -0
  31. package/dist/lib/linux_x86_64/libnode-v25.node +0 -0
  32. package/dist/lib/linux_x86_64/libselva.so +0 -0
  33. package/dist/src/client/modify/Tmp.d.ts +0 -1
  34. package/dist/src/client/modify/Tmp.js +14 -9
  35. package/dist/src/client/modify/create/index.js +6 -5
  36. package/dist/src/client/modify/drain.js +6 -2
  37. package/dist/src/client/modify/edges/binary.js +3 -2
  38. package/dist/src/client/modify/edges/reference.js +2 -3
  39. package/dist/src/client/modify/edges/references.js +2 -3
  40. package/dist/src/client/modify/edges/separate.js +4 -1
  41. package/dist/src/client/modify/edges/string.js +2 -3
  42. package/dist/src/client/modify/error.d.ts +29 -0
  43. package/dist/src/client/modify/error.js +10 -0
  44. package/dist/src/client/modify/props/alias.js +1 -1
  45. package/dist/src/client/modify/props/binary.js +1 -1
  46. package/dist/src/client/modify/props/cardinality.js +1 -1
  47. package/dist/src/client/modify/props/fixed.js +13 -14
  48. package/dist/src/client/modify/props/reference.js +2 -2
  49. package/dist/src/client/modify/props/references.js +7 -7
  50. package/dist/src/client/modify/props/string.js +1 -1
  51. package/dist/src/client/modify/props/vector.js +1 -11
  52. package/dist/src/client/modify/types.d.ts +1 -0
  53. package/dist/src/client/modify/types.js +1 -0
  54. package/dist/src/client/modify/validate.d.ts +1 -1
  55. package/dist/src/client/modify/validate.js +4 -3
  56. package/dist/src/client/query/BasedDbQuery.d.ts +4 -4
  57. package/dist/src/client/query/BasedDbQuery.js +23 -12
  58. package/dist/src/client/query/BasedQueryResponse.d.ts +0 -1
  59. package/dist/src/client/query/BasedQueryResponse.js +0 -3
  60. package/dist/src/client/query/aggregates/aggregation.d.ts +1 -1
  61. package/dist/src/client/query/aggregates/aggregation.js +123 -51
  62. package/dist/src/client/query/display.js +14 -8
  63. package/dist/src/client/query/filter/createFixedFilterBuffer.js +59 -22
  64. package/dist/src/client/query/filter/createReferenceFilter.js +13 -13
  65. package/dist/src/client/query/filter/createVariableFilterBuffer.js +6 -3
  66. package/dist/src/client/query/filter/filter.js +8 -0
  67. package/dist/src/client/query/filter/primitiveFilter.js +4 -1
  68. package/dist/src/client/query/filter/{toBuffer.d.ts → toByteCode.d.ts} +3 -2
  69. package/dist/src/client/query/filter/{toBuffer.js → toByteCode.js} +46 -12
  70. package/dist/src/client/query/filter/types.d.ts +2 -1
  71. package/dist/src/client/query/filter/types.js +33 -5
  72. package/dist/src/client/query/include/toByteCode.d.ts +2 -2
  73. package/dist/src/client/query/include/toByteCode.js +1 -1
  74. package/dist/src/client/query/query.d.ts +1 -1
  75. package/dist/src/client/query/query.js +1 -1
  76. package/dist/src/client/query/queryDef.js +6 -2
  77. package/dist/src/client/query/registerQuery.js +5 -9
  78. package/dist/src/client/query/subscription/index.js +5 -0
  79. package/dist/src/client/query/subscription/toByteCode.d.ts +6 -0
  80. package/dist/src/client/query/subscription/toByteCode.js +139 -0
  81. package/dist/src/client/query/subscription/types.d.ts +6 -0
  82. package/dist/src/client/query/subscription/types.js +7 -9
  83. package/dist/src/client/query/toByteCode/aggregates.d.ts +2 -0
  84. package/dist/src/client/query/toByteCode/aggregates.js +60 -0
  85. package/dist/src/client/query/toByteCode/alias.d.ts +2 -0
  86. package/dist/src/client/query/toByteCode/alias.js +24 -0
  87. package/dist/src/client/query/toByteCode/default.d.ts +2 -2
  88. package/dist/src/client/query/toByteCode/default.js +21 -24
  89. package/dist/src/client/query/toByteCode/id.d.ts +2 -0
  90. package/dist/src/client/query/toByteCode/id.js +17 -0
  91. package/dist/src/client/query/toByteCode/ids.d.ts +2 -0
  92. package/dist/src/client/query/toByteCode/ids.js +52 -0
  93. package/dist/src/client/query/toByteCode/offsets.d.ts +35 -0
  94. package/dist/src/client/query/toByteCode/offsets.js +36 -0
  95. package/dist/src/client/query/toByteCode/reference.d.ts +2 -0
  96. package/dist/src/client/query/toByteCode/reference.js +12 -0
  97. package/dist/src/client/query/toByteCode/references.d.ts +2 -0
  98. package/dist/src/client/query/toByteCode/references.js +35 -0
  99. package/dist/src/client/query/toByteCode/toByteCode.d.ts +4 -2
  100. package/dist/src/client/query/toByteCode/toByteCode.js +62 -189
  101. package/dist/src/client/query/types.d.ts +24 -5
  102. package/dist/src/client/query/validation.d.ts +5 -1
  103. package/dist/src/client/query/validation.js +15 -3
  104. package/dist/src/client/string.js +1 -1
  105. package/dist/src/hooks.js +2 -29
  106. package/dist/src/index.d.ts +1 -0
  107. package/dist/src/index.js +1 -0
  108. package/dist/src/native.d.ts +8 -1
  109. package/dist/src/native.js +23 -2
  110. package/dist/src/server/index.d.ts +2 -0
  111. package/dist/src/server/index.js +11 -2
  112. package/dist/src/server/schema.js +3 -2
  113. package/dist/src/server/schemaSelvaBuffer.d.ts +4 -0
  114. package/dist/src/server/schemaSelvaBuffer.js +182 -0
  115. package/dist/src/server/subscription.d.ts +32 -0
  116. package/dist/src/server/subscription.js +288 -0
  117. package/dist/src/utils.js +2 -3
  118. package/package.json +5 -6
@@ -38,8 +38,8 @@ enum SelvaFieldType {
38
38
  SELVA_FIELD_TYPE_TEXT = 3,
39
39
  SELVA_FIELD_TYPE_REFERENCE = 4,
40
40
  SELVA_FIELD_TYPE_REFERENCES = 5,
41
- SELVA_FIELD_TYPE_WEAK_REFERENCE = 6,
42
- SELVA_FIELD_TYPE_WEAK_REFERENCES = 7,
41
+ SELVA_FIELD_TYPE_WEAK_REFERENCE __attribute__((deprecated)) = 6,
42
+ SELVA_FIELD_TYPE_WEAK_REFERENCES __attribute__((deprecated)) = 7,
43
43
  SELVA_FIELD_TYPE_ALIAS = 8,
44
44
  SELVA_FIELD_TYPE_ALIASES = 9,
45
45
  SELVA_FIELD_TYPE_COLVEC = 10,
@@ -48,12 +48,6 @@ enum SelvaFieldType {
48
48
  struct EdgeFieldConstraint {
49
49
  enum EdgeFieldConstraintFlag {
50
50
  EDGE_FIELD_CONSTRAINT_FLAG_DEPENDENT = 0x01,
51
- /**
52
- * Skip saving this field while dumping.
53
- * If the field is of type SELVA_FIELD_TYPE_REFERENCES it's saved
54
- * regardless of this flag to preserve the original order of references.
55
- */
56
- EDGE_FIELD_CONSTRAINT_FLAG_SKIP_DUMP = 0x80,
57
51
  } __packed flags;
58
52
  field_t inverse_field;
59
53
  node_type_t dst_node_type;
@@ -69,7 +63,8 @@ struct SelvaFieldSchema {
69
63
  } string; /*!< SELVA_FIELD_TYPE_STRING */
70
64
  struct EdgeFieldConstraint edge_constraint; /*!< SELVA_FIELD_TYPE_REFERENCE, SELVA_FIELD_TYPE_REFERENCES, SELVA_FIELD_TYPE_WEAK_REFERENCE, and SELVA_FIELD_TYPE_WEAK_REFERENCES. */
71
65
  struct {
72
- uint16_t len;
66
+ uint16_t len; /*!< Size of the smb. */
67
+ uint32_t default_off; /*!< Offset to the default in the raw schema buffer. */
73
68
  } smb; /*!< SELVA_FIELD_TYPE_MICRO_BUFFER */
74
69
  size_t alias_index; /*!< Index in aliases for SELVA_FIELD_TYPE_ALIAS and SELVA_FIELD_TYPE_ALIASES. */
75
70
  struct {
@@ -88,10 +83,11 @@ struct SelvaFieldsSchema {
88
83
  * Template for fields->fields_map.
89
84
  */
90
85
  struct {
91
- void *buf;
92
- size_t len;
93
- size_t fixed_data_size;
94
- } field_map_template;
86
+ void *field_map_buf;
87
+ size_t field_map_len;
88
+ void *fixed_data_buf;
89
+ size_t fixed_data_len;
90
+ } template;
95
91
  struct SelvaFieldSchema field_schemas[SELVA_FIELDS_MAX];
96
92
  };
97
93
 
Binary file
@@ -242,6 +242,10 @@
242
242
  #define speculation_safe_value(x) x
243
243
  #endif
244
244
 
245
+ #ifndef assume
246
+ #define assume(expr) __attribute__((assume(expr)))
247
+ #endif
248
+
245
249
  #define same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b))
246
250
 
247
251
  /**
@@ -227,9 +227,7 @@ inline const struct EdgeFieldConstraint *selva_get_edge_field_constraint(const s
227
227
  #ifndef __zig
228
228
  {
229
229
  assert(fs->type == SELVA_FIELD_TYPE_REFERENCE ||
230
- fs->type == SELVA_FIELD_TYPE_REFERENCES ||
231
- fs->type == SELVA_FIELD_TYPE_WEAK_REFERENCE ||
232
- fs->type == SELVA_FIELD_TYPE_WEAK_REFERENCES);
230
+ fs->type == SELVA_FIELD_TYPE_REFERENCES);
233
231
  return &fs->edge_constraint;
234
232
  }
235
233
  #else
@@ -248,8 +246,27 @@ inline const struct SelvaFieldsSchema *selva_get_edge_field_fields_schema(struct
248
246
  ;
249
247
  #endif
250
248
 
249
+ /**
250
+ * Strategy for adding new node expires.
251
+ */
252
+ enum selva_expire_node_strategy {
253
+ /**
254
+ * Ignore any existing expire and just add a new one.
255
+ */
256
+ SELVA_EXPIRE_NODE_STRATEGY_IGNORE = 0,
257
+ /**
258
+ * Cancel adding an expire if one already exists.
259
+ */
260
+ SELVA_EXPIRE_NODE_STRATEGY_CANCEL = 1,
261
+ /**
262
+ * Cancel the previous expire before adding a new one.
263
+ * TODO This will currently only cancel one previous hit.
264
+ */
265
+ SELVA_EXPIRE_NODE_STRATEGY_CANCEL_OLD = 2,
266
+ };
267
+
251
268
  SELVA_EXPORT
252
- void selva_expire_node(struct SelvaDb *db, node_type_t type, node_id_t node_id, int64_t ts);
269
+ void selva_expire_node(struct SelvaDb *db, node_type_t type, node_id_t node_id, int64_t ts, enum selva_expire_node_strategy stg);
253
270
 
254
271
  SELVA_EXPORT
255
272
  void selva_expire_node_cancel(struct SelvaDb *db, node_type_t type, node_id_t node_id);
@@ -264,6 +281,9 @@ void selva_db_expire_tick(struct SelvaDb *db, selva_dirty_node_cb_t dirty_cb, vo
264
281
  SELVA_EXPORT
265
282
  void selva_del_node(struct SelvaDb *db, struct SelvaTypeEntry *type, struct SelvaNode *node, selva_dirty_node_cb_t dirty_cb, void *dirty_ctx) __attribute__((nonnull(1, 2, 3)));
266
283
 
284
+ SELVA_EXPORT
285
+ void selva_flush_node(struct SelvaDb *db, struct SelvaTypeEntry *type, struct SelvaNode *node, selva_dirty_node_cb_t dirty_cb, void *dirty_ctx);
286
+
267
287
  SELVA_EXPORT
268
288
  void selva_del_block(struct SelvaDb *db, struct SelvaTypeEntry *te, node_id_t start);
269
289
 
@@ -283,7 +303,7 @@ struct SelvaNode *selva_nfind_node(struct SelvaTypeEntry *type, node_id_t node_i
283
303
  * Get or create a node by id.
284
304
  */
285
305
  SELVA_EXPORT
286
- struct SelvaNode *selva_upsert_node(struct SelvaTypeEntry *type, node_id_t node_id) __attribute__((nonnull));
306
+ struct SelvaNode *selva_upsert_node(struct SelvaDb *db, struct SelvaTypeEntry *type, node_id_t node_id) __attribute__((nonnull));
287
307
 
288
308
  /**
289
309
  * **Example**
@@ -70,20 +70,6 @@ static_assert(offsetof(struct SelvaNodeReferences, any) == offsetof(struct Selva
70
70
  static_assert(offsetof(struct SelvaNodeReferences, any) == offsetof(struct SelvaNodeReferences, large));
71
71
  static_assert(offsetof(struct SelvaNodeReferences, small) == offsetof(struct SelvaNodeReferences, large));
72
72
 
73
- struct SelvaNodeWeakReference {
74
- /* The type can be found from the schema. */
75
- #if 0
76
- node_type_t dst_type;
77
- #endif
78
- node_id_t dst_id;
79
- };
80
-
81
- struct SelvaNodeWeakReferences {
82
- uint32_t nr_refs;
83
- uint32_t offset;
84
- struct SelvaNodeWeakReference *refs __pcounted_by(nr_refs);
85
- };
86
-
87
73
  struct SelvaFieldsPointer {
88
74
  uint8_t *ptr;
89
75
  size_t off;
@@ -107,14 +93,14 @@ __purefn
107
93
  #endif
108
94
  size_t selva_fields_get_data_size(const struct SelvaFieldSchema *fs);
109
95
 
110
- SELVA_EXPORT
111
96
  #if __has_c_attribute(reproducible)
112
97
  [[reproducible]]
113
98
  #endif
114
99
  void *selva_fields_nfo2p(struct SelvaFields *fields, const struct SelvaFieldInfo *nfo);
115
100
 
116
- SELVA_EXPORT
117
- struct SelvaFields *selva_fields_node2fields(struct SelvaNode *node);
101
+ struct SelvaNodeLargeReference *selva_fields_ensure_reference(
102
+ struct SelvaNode *node,
103
+ const struct SelvaFieldSchema *fs);
118
104
 
119
105
  SELVA_EXPORT
120
106
  struct SelvaNode *selva_fields_ensure_ref_meta(
@@ -125,6 +111,9 @@ struct SelvaNode *selva_fields_ensure_ref_meta(
125
111
  node_id_t meta_id,
126
112
  selva_dirty_node_cb_t dirty_cb, void *dirty_ctx);
127
113
 
114
+ SELVA_EXPORT
115
+ void selva_faux_dirty_cb(void *, node_type_t, node_id_t);
116
+
128
117
  SELVA_EXPORT
129
118
  int selva_fields_get_mutable_string(
130
119
  struct SelvaNode *node,
@@ -134,7 +123,7 @@ int selva_fields_get_mutable_string(
134
123
  __attribute__((access(write_only, 4)));
135
124
 
136
125
  SELVA_EXPORT
137
- struct SelvaFieldInfo *selva_fields_ensure(struct SelvaFields *fields, const struct SelvaFieldSchema *fs);
126
+ void *selva_fields_ensure_micro_buffer(struct SelvaNode *node, const struct SelvaFieldSchema *fs);
138
127
 
139
128
  /*
140
129
  * TODO Document diff to get_mutable_string
@@ -157,7 +146,15 @@ int selva_fields_reference_set(
157
146
  struct SelvaNodeReferenceAny *ref_out,
158
147
  selva_dirty_node_cb_t dirty_cb,
159
148
  void *dirty_ctx);
160
- // __attribute__((access(write_only, 5), access(write_only, 6)));
149
+
150
+ enum selva_fields_references_insert_flags {
151
+ /**
152
+ * Reorder existing reference to the new index.
153
+ * The reference is either inserted or moved to the given index.
154
+ */
155
+ SELVA_FIELDS_REFERENCES_INSERT_FLAGS_REORDER = 0x01,
156
+ SELVA_FIELDS_REFERENCES_INSERT_FLAGS_IGNORE_SRC_DEPENDENT = 0x02,
157
+ };
161
158
 
162
159
  /**
163
160
  * @param index 0 = first; -1 = last.
@@ -169,11 +166,11 @@ int selva_fields_references_insert(
169
166
  struct SelvaNode * restrict node,
170
167
  const struct SelvaFieldSchema *fs,
171
168
  ssize_t index,
172
- bool reorder,
169
+ enum selva_fields_references_insert_flags flags,
173
170
  struct SelvaTypeEntry *te_dst,
174
171
  struct SelvaNode * restrict dst,
175
172
  struct SelvaNodeReferenceAny *ref_out,
176
- selva_dirty_node_cb_t dirty_cb, void *dirty_ctx, bool ignore_src_dependent)
173
+ selva_dirty_node_cb_t dirty_cb, void *dirty_ctx)
177
174
  __attribute__((access(write_only, 8)));
178
175
 
179
176
  /**
@@ -184,7 +181,7 @@ SELVA_EXPORT
184
181
  size_t selva_fields_prealloc_refs(struct SelvaDb *db, struct SelvaNode *node, const struct SelvaFieldSchema *fs, size_t nr_refs_min);
185
182
 
186
183
  SELVA_EXPORT
187
- int selva_fields_references_insert_tail_wupsert(
184
+ int selva_fields_references_insert_tail(
188
185
  struct SelvaDb *db,
189
186
  struct SelvaNode * restrict node,
190
187
  const struct SelvaFieldSchema *fs,
@@ -275,61 +272,20 @@ int selva_fields_get_text(
275
272
  size_t *len);
276
273
 
277
274
  SELVA_EXPORT
278
- int selva_fields_set_micro_buffer(struct SelvaFields *fields, const struct SelvaFieldSchema *fs, const void *value, size_t len);
279
-
280
- SELVA_EXPORT
281
- int selva_fields_set_micro_buffer2(struct SelvaNode *node, const struct SelvaFieldSchema *fs, const void *value, size_t len);
282
-
283
- SELVA_EXPORT
284
- int selva_fields_set_weak_reference(struct SelvaNode *node, const struct SelvaFieldSchema *fs, node_id_t dst);
285
-
286
- SELVA_EXPORT
287
- int selva_fields_set_weak_reference2(struct SelvaFields *fields, const struct SelvaFieldSchema *fs, node_id_t dst);
288
-
289
- SELVA_EXPORT
290
- int selva_fields_set_weak_references2(struct SelvaFields *fields, const struct SelvaFieldSchema *fs, node_id_t dst[], size_t nr_dsts);
275
+ int selva_fields_set_micro_buffer(struct SelvaNode *node, const struct SelvaFieldSchema *fs, const void *value, size_t len);
291
276
 
292
277
  SELVA_EXPORT
293
- int selva_fields_set_weak_references(struct SelvaNode *node, const struct SelvaFieldSchema *fs, node_id_t dst[], size_t nr_dsts);
294
-
295
- SELVA_EXPORT
296
- struct SelvaNodeLargeReference *selva_fields_get_reference(struct SelvaDb *db, struct SelvaNode *node, const struct SelvaFieldSchema *fs)
278
+ struct SelvaNodeLargeReference *selva_fields_get_reference(struct SelvaNode *node, const struct SelvaFieldSchema *fs)
297
279
  __attribute__((nonnull));
298
280
 
299
281
  SELVA_EXPORT
300
- struct SelvaNodeReferences *selva_fields_get_references(struct SelvaDb *db, struct SelvaNode *node, const struct SelvaFieldSchema *fs)
301
- __attribute__((nonnull));
302
-
303
- SELVA_EXPORT
304
- struct SelvaNodeWeakReference selva_fields_get_weak_reference(struct SelvaFields *fields, field_t field)
305
- __attribute__((nonnull));
306
-
307
- SELVA_EXPORT
308
- struct SelvaNodeWeakReferences selva_fields_get_weak_references(struct SelvaFields *fields, field_t field)
309
- __attribute__((nonnull));
310
-
311
- SELVA_EXPORT
312
- struct SelvaNode *selva_fields_resolve_weak_reference(
313
- const struct SelvaDb *db,
314
- const struct SelvaFieldSchema *fs,
315
- const struct SelvaNodeWeakReference *weak_ref)
316
- __attribute__((nonnull));
317
-
318
- SELVA_EXPORT
319
- struct selva_string *selva_fields_get_selva_string2(struct SelvaFields *fields, const struct SelvaFieldSchema *fs)
282
+ struct SelvaNodeReferences *selva_fields_get_references(struct SelvaNode *node, const struct SelvaFieldSchema *fs)
320
283
  __attribute__((nonnull));
321
284
 
322
285
  SELVA_EXPORT
323
286
  struct selva_string *selva_fields_get_selva_string(struct SelvaNode *node, const struct SelvaFieldSchema *fs)
324
287
  __attribute__((nonnull));
325
288
 
326
- SELVA_EXPORT
327
- struct SelvaFieldInfo *selva_field_get_nfo(struct SelvaFields *fields, const struct SelvaFieldSchema *fs);
328
-
329
- SELVA_EXPORT
330
- struct SelvaFieldsPointer selva_fields_get_raw2(struct SelvaFields *fields, const struct SelvaFieldSchema *fs)
331
- __attribute__((nonnull));
332
-
333
289
  SELVA_EXPORT
334
290
  struct SelvaFieldsPointer selva_fields_get_raw(struct SelvaNode *node, const struct SelvaFieldSchema *fs)
335
291
  __attribute__((nonnull));
@@ -358,12 +314,10 @@ void selva_fields_clear_references(struct SelvaDb *db, struct SelvaNode *node, c
358
314
  /**
359
315
  * Init the fields struct of a node or edge.
360
316
  */
361
- SELVA_EXPORT
362
- void selva_fields_init(const struct SelvaFieldsSchema *schema, struct SelvaFields *fields)
317
+ void selva_fields_init_node(struct SelvaDb *db, struct SelvaTypeEntry *te, struct SelvaNode *node)
363
318
  __attribute__((nonnull));
364
319
 
365
- void selva_fields_init_node(struct SelvaTypeEntry *te, struct SelvaNode *node)
366
- __attribute__((nonnull));
320
+ void selva_fields_flush(struct SelvaDb *db, struct SelvaNode *node, selva_dirty_node_cb_t dirty_cb, void *dirty_ctx);
367
321
 
368
322
  /**
369
323
  * Destroy all fields of a node.
@@ -372,8 +326,16 @@ SELVA_EXPORT
372
326
  void selva_fields_destroy(struct SelvaDb *db, struct SelvaNode *node, selva_dirty_node_cb_t dirty_cb, void *dirty_ctx)
373
327
  __attribute__((nonnull(1, 2)));
374
328
 
329
+ /**
330
+ * Unload node fields.
331
+ * Same as selva_fields_destroy() but only clears references from one side.
332
+ */
333
+ SELVA_EXPORT
334
+ void selva_fields_unload(struct SelvaDb *db, struct SelvaNode *node)
335
+ __attribute__((nonnull));
336
+
375
337
  SELVA_EXPORT
376
- void selva_fields_hash_update(struct XXH3_state_s *hash_state, struct SelvaDb *db, const struct SelvaFieldsSchema *schema, const struct SelvaFields *fields);
338
+ void selva_fields_hash_update(struct XXH3_state_s *hash_state, struct SelvaDb *db, const struct SelvaFieldsSchema *schema, const struct SelvaNode *node);
377
339
 
378
340
  SELVA_EXPORT
379
- selva_hash128_t selva_fields_hash(struct SelvaDb *db, const struct SelvaFieldsSchema *schema, const struct SelvaFields *fields);
341
+ selva_hash128_t selva_fields_hash(struct SelvaDb *db, const struct SelvaFieldsSchema *schema, const struct SelvaNode *node);
@@ -4,6 +4,7 @@
4
4
  */
5
5
  #pragma once
6
6
 
7
+ #include <stddef.h>
7
8
  #if defined(__APPLE__) && __MACH__
8
9
  #include <xlocale.h>
9
10
  #endif
@@ -18,6 +19,12 @@
18
19
  struct libdeflate_decompressor;
19
20
  struct libdeflate_block_state;
20
21
 
22
+ SELVA_EXPORT
23
+ extern const char selva_lang_all_str[];
24
+
25
+ SELVA_EXPORT
26
+ extern const size_t selva_lang_all_len;
27
+
21
28
  int selva_lang_set_fallback(const char *lang_str, size_t lang_len);
22
29
 
23
30
  /**
@@ -38,8 +38,8 @@ enum SelvaFieldType {
38
38
  SELVA_FIELD_TYPE_TEXT = 3,
39
39
  SELVA_FIELD_TYPE_REFERENCE = 4,
40
40
  SELVA_FIELD_TYPE_REFERENCES = 5,
41
- SELVA_FIELD_TYPE_WEAK_REFERENCE = 6,
42
- SELVA_FIELD_TYPE_WEAK_REFERENCES = 7,
41
+ SELVA_FIELD_TYPE_WEAK_REFERENCE __attribute__((deprecated)) = 6,
42
+ SELVA_FIELD_TYPE_WEAK_REFERENCES __attribute__((deprecated)) = 7,
43
43
  SELVA_FIELD_TYPE_ALIAS = 8,
44
44
  SELVA_FIELD_TYPE_ALIASES = 9,
45
45
  SELVA_FIELD_TYPE_COLVEC = 10,
@@ -48,12 +48,6 @@ enum SelvaFieldType {
48
48
  struct EdgeFieldConstraint {
49
49
  enum EdgeFieldConstraintFlag {
50
50
  EDGE_FIELD_CONSTRAINT_FLAG_DEPENDENT = 0x01,
51
- /**
52
- * Skip saving this field while dumping.
53
- * If the field is of type SELVA_FIELD_TYPE_REFERENCES it's saved
54
- * regardless of this flag to preserve the original order of references.
55
- */
56
- EDGE_FIELD_CONSTRAINT_FLAG_SKIP_DUMP = 0x80,
57
51
  } __packed flags;
58
52
  field_t inverse_field;
59
53
  node_type_t dst_node_type;
@@ -69,7 +63,8 @@ struct SelvaFieldSchema {
69
63
  } string; /*!< SELVA_FIELD_TYPE_STRING */
70
64
  struct EdgeFieldConstraint edge_constraint; /*!< SELVA_FIELD_TYPE_REFERENCE, SELVA_FIELD_TYPE_REFERENCES, SELVA_FIELD_TYPE_WEAK_REFERENCE, and SELVA_FIELD_TYPE_WEAK_REFERENCES. */
71
65
  struct {
72
- uint16_t len;
66
+ uint16_t len; /*!< Size of the smb. */
67
+ uint32_t default_off; /*!< Offset to the default in the raw schema buffer. */
73
68
  } smb; /*!< SELVA_FIELD_TYPE_MICRO_BUFFER */
74
69
  size_t alias_index; /*!< Index in aliases for SELVA_FIELD_TYPE_ALIAS and SELVA_FIELD_TYPE_ALIASES. */
75
70
  struct {
@@ -88,10 +83,11 @@ struct SelvaFieldsSchema {
88
83
  * Template for fields->fields_map.
89
84
  */
90
85
  struct {
91
- void *buf;
92
- size_t len;
93
- size_t fixed_data_size;
94
- } field_map_template;
86
+ void *field_map_buf;
87
+ size_t field_map_len;
88
+ void *fixed_data_buf;
89
+ size_t fixed_data_len;
90
+ } template;
95
91
  struct SelvaFieldSchema field_schemas[SELVA_FIELDS_MAX];
96
92
  };
97
93
 
Binary file
Binary file
@@ -7,7 +7,6 @@ export declare class Tmp implements Promise<number> {
7
7
  [Symbol.toStringTag]: 'ModifyPromise';
8
8
  get error(): Error;
9
9
  get id(): number;
10
- type: number;
11
10
  tmpId: number;
12
11
  batch: Ctx['batch'];
13
12
  promise?: Promise<number>;
@@ -1,4 +1,5 @@
1
1
  import { readUint32 } from '@based/utils';
2
+ import { errorMap } from './error.js';
2
3
  const promisify = (tmp) => {
3
4
  if (!tmp.promise) {
4
5
  if (tmp.batch.ready) {
@@ -26,7 +27,7 @@ export const resolveTmp = (tmp) => {
26
27
  if (id) {
27
28
  return tmp.resolve(tmp.id);
28
29
  }
29
- return tmp.reject(tmp.error);
30
+ return rejectTmp(tmp);
30
31
  };
31
32
  export const rejectTmp = (tmp) => {
32
33
  return tmp.reject(tmp.error);
@@ -34,25 +35,29 @@ export const rejectTmp = (tmp) => {
34
35
  export class Tmp {
35
36
  constructor(ctx) {
36
37
  ctx.batch.count ??= 0;
37
- this.type = ctx.cursor.type;
38
+ this.#schema = ctx.schema;
38
39
  this.batch = ctx.batch;
39
40
  this.tmpId = ctx.batch.count++;
40
41
  }
41
42
  [Symbol.toStringTag];
43
+ #schema;
42
44
  #id;
45
+ #err;
43
46
  get error() {
44
- if (this.batch.ready) {
45
- // TODO: also handle individual errors here
46
- return this.batch.error;
47
+ if (this.batch.ready && !this.id) {
48
+ if (this.#err in errorMap) {
49
+ return new errorMap[this.#err](this.#id, this.#schema);
50
+ }
51
+ return this.batch.error || Error('Modify error');
47
52
  }
48
53
  }
49
54
  get id() {
50
- if (this.batch.ready) {
51
- this.#id ??= this.batch.res && readUint32(this.batch.res, this.tmpId * 5);
52
- return this.#id;
55
+ if (this.batch.res) {
56
+ this.#err ??= this.batch.res[this.tmpId * 5 + 4];
57
+ this.#id ??= readUint32(this.batch.res, this.tmpId * 5);
58
+ return this.#err ? 0 : this.#id;
53
59
  }
54
60
  }
55
- type;
56
61
  tmpId;
57
62
  batch;
58
63
  promise;
@@ -3,10 +3,10 @@ import { writeObject } from '../props/object.js';
3
3
  import { reserve } from '../resize.js';
4
4
  import { FULL_CURSOR_SIZE, PROP_CURSOR_SIZE, writeMainCursor, writeTypeCursor, } from '../cursor.js';
5
5
  import { getByPath, writeUint16 } from '@based/utils';
6
- import { writeMainBuffer, writeMainValue } from '../props/main.js';
6
+ import { 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, PADDING, SWITCH_ID_CREATE, SWITCH_ID_CREATE_UNSAFE, } from '../types.js';
9
+ import { ADD_EMPTY_SORT, ADD_EMPTY_SORT_TEXT, CREATE, PADDING, SWITCH_ID_CREATE, SWITCH_ID_CREATE_RING, 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';
@@ -165,6 +165,10 @@ export const writeCreate = (ctx, schema, payload, opts) => {
165
165
  throw 'Invalid payload. "id" not allowed';
166
166
  }
167
167
  }
168
+ else if (schema.capped) {
169
+ writeU8(ctx, SWITCH_ID_CREATE_RING);
170
+ writeU32(ctx, schema.capped);
171
+ }
168
172
  else {
169
173
  writeU8(ctx, SWITCH_ID_CREATE);
170
174
  }
@@ -175,9 +179,6 @@ export const writeCreate = (ctx, schema, payload, opts) => {
175
179
  writeMainCursor(ctx);
176
180
  }
177
181
  writeCreateTs(ctx, payload);
178
- if (!ctx.cursor.main && !ctx.schema.mainEmptyAllZeroes) {
179
- writeMainBuffer(ctx);
180
- }
181
182
  writeDefaults(ctx);
182
183
  writeSortable(ctx);
183
184
  writeSortableText(ctx);
@@ -25,7 +25,7 @@ export const drain = (db, ctx) => {
25
25
  const { batch } = ctx;
26
26
  const payload = consume(ctx);
27
27
  let start;
28
- ctx.draining = db.hooks
28
+ const current = db.hooks
29
29
  .flushModify(payload)
30
30
  .then((res) => {
31
31
  if (res === null) {
@@ -46,9 +46,13 @@ export const drain = (db, ctx) => {
46
46
  })
47
47
  .then(() => {
48
48
  if (start && start !== ctx.index) {
49
- return drain(db, ctx);
49
+ const next = drain(db, ctx);
50
+ if (next !== current) {
51
+ return next;
52
+ }
50
53
  }
51
54
  });
55
+ ctx.draining = current;
52
56
  }
53
57
  return ctx.draining;
54
58
  };
@@ -4,13 +4,14 @@ import { getBuffer, writeBinaryRaw } from '../props/binary.js';
4
4
  import { writeU32 } from '../uint.js';
5
5
  import { writeEdgeHeader } from './header.js';
6
6
  import { PROP_CURSOR_SIZE } from '../cursor.js';
7
+ import { validate } from '../validate.js';
7
8
  export const writeBinaryEdge = (ctx, edge, val) => {
8
9
  let size = 0;
9
10
  if (val !== null) {
10
11
  const buf = getBuffer(val);
11
- if (!buf || !edge.validation(buf, edge)) {
12
+ if (!buf)
12
13
  throw [edge, val];
13
- }
14
+ validate(buf, edge);
14
15
  size = buf.byteLength;
15
16
  val = buf;
16
17
  }
@@ -2,6 +2,7 @@ import { REFERENCE } from '@based/schema/def';
2
2
  import { reserve } from '../resize.js';
3
3
  import { writeU32 } from '../uint.js';
4
4
  import { writeEdgeHeader } from './header.js';
5
+ import { validate } from '../validate.js';
5
6
  export const writeReferenceEdge = (ctx, edge, val) => {
6
7
  if (val === null) {
7
8
  reserve(ctx, 3 + 4);
@@ -18,9 +19,7 @@ export const writeReferenceEdge = (ctx, edge, val) => {
18
19
  }
19
20
  }
20
21
  if (typeof val === 'number') {
21
- if (!edge.validation(val, edge)) {
22
- throw [edge, val];
23
- }
22
+ validate(val, edge);
24
23
  reserve(ctx, 3 + 4);
25
24
  writeEdgeHeader(ctx, edge, REFERENCE);
26
25
  writeU32(ctx, val);
@@ -2,6 +2,7 @@ import { REFERENCES } from '@based/schema/def';
2
2
  import { reserve } from '../resize.js';
3
3
  import { writePadding, writeU32 } from '../uint.js';
4
4
  import { writeEdgeHeader } from './header.js';
5
+ import { validate } from '../validate.js';
5
6
  export const writeReferencesEdge = (ctx, edge, vals) => {
6
7
  if (vals === null) {
7
8
  reserve(ctx, 3 + 4);
@@ -26,9 +27,7 @@ export const writeReferencesEdge = (ctx, edge, vals) => {
26
27
  }
27
28
  }
28
29
  if (typeof val === 'number') {
29
- if (!edge.validation(val, edge)) {
30
- throw [edge, vals];
31
- }
30
+ validate(val, edge);
32
31
  writeU32(ctx, val);
33
32
  continue;
34
33
  }
@@ -1,4 +1,4 @@
1
- import { BINARY, STRING, REFERENCE, REFERENCES, CARDINALITY, } from '@based/schema/def';
1
+ import { BINARY, STRING, REFERENCE, REFERENCES, CARDINALITY, JSON as JSONProp, } from '@based/schema/def';
2
2
  import { writeBinaryEdge } from './binary.js';
3
3
  import { writeStringEdge } from './string.js';
4
4
  import { writeReferenceEdge } from './reference.js';
@@ -8,6 +8,9 @@ export const writeSeparateEdge = (ctx, edge, val) => {
8
8
  if (edge.typeIndex === BINARY) {
9
9
  writeBinaryEdge(ctx, edge, val);
10
10
  }
11
+ else if (edge.typeIndex == JSONProp) {
12
+ writeBinaryEdge(ctx, edge, val === null ? null : JSON.stringify(val));
13
+ }
11
14
  else if (edge.typeIndex === STRING) {
12
15
  writeStringEdge(ctx, edge, val);
13
16
  }
@@ -5,6 +5,7 @@ import { reserve } from '../resize.js';
5
5
  import { RANGE_ERR } from '../types.js';
6
6
  import { writeU32 } from '../uint.js';
7
7
  import { writeEdgeHeader } from './header.js';
8
+ import { validate } from '../validate.js';
8
9
  export const writeStringEdge = (ctx, edge, val) => {
9
10
  if (val === null) {
10
11
  reserve(ctx, 3 + 4);
@@ -12,9 +13,7 @@ export const writeStringEdge = (ctx, edge, val) => {
12
13
  writeU32(ctx, 0);
13
14
  return;
14
15
  }
15
- if (!edge.validation(val, edge)) {
16
- throw [val, edge];
17
- }
16
+ validate(val, edge);
18
17
  const maxSize = val instanceof Uint8Array
19
18
  ? val.byteLength
20
19
  : ENCODER.encode(val).byteLength + 6;
@@ -1,3 +1,4 @@
1
+ import { SchemaTypeDef } from '@based/schema/def';
1
2
  import { DbClient } from '../../index.js';
2
3
  import { create } from './create/index.js';
3
4
  import { Ctx } from './Ctx.js';
@@ -6,3 +7,31 @@ import { expire } from './expire/index.js';
6
7
  import { update } from './update/index.js';
7
8
  import { upsert } from './upsert/index.js';
8
9
  export declare const handleError: (db: DbClient, ctx: Ctx, fn: typeof create | typeof update | typeof del | typeof expire | typeof upsert, args: IArguments, e: any) => Promise<number>;
10
+ export declare const errors: {
11
+ readonly NotExists: {
12
+ new (id: number, schema: SchemaTypeDef): {
13
+ name: string;
14
+ message: string;
15
+ stack?: string;
16
+ cause?: unknown;
17
+ };
18
+ isError(error: unknown): error is Error;
19
+ captureStackTrace(targetObject: object, constructorOpt?: Function): void;
20
+ prepareStackTrace(err: Error, stackTraces: NodeJS.CallSite[]): any;
21
+ stackTraceLimit: number;
22
+ };
23
+ };
24
+ export declare const errorMap: {
25
+ 1: {
26
+ new (id: number, schema: SchemaTypeDef): {
27
+ name: string;
28
+ message: string;
29
+ stack?: string;
30
+ cause?: unknown;
31
+ };
32
+ isError(error: unknown): error is Error;
33
+ captureStackTrace(targetObject: object, constructorOpt?: Function): void;
34
+ prepareStackTrace(err: Error, stackTraces: NodeJS.CallSite[]): any;
35
+ stackTraceLimit: number;
36
+ };
37
+ };