tigerbeetle-node 0.16.78 → 0.17.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.
package/src/translate.zig CHANGED
@@ -10,7 +10,9 @@ pub fn register_function(
10
10
  ) !void {
11
11
  var napi_function: c.napi_value = undefined;
12
12
  if (c.napi_create_function(env, null, 0, function, null, &napi_function) != c.napi_ok) {
13
- return throw(env, "Failed to create function " ++ name ++ "().");
13
+ return throw(env, .{
14
+ .message = "Failed to create function " ++ name ++ "().",
15
+ });
14
16
  }
15
17
 
16
18
  if (c.napi_set_named_property(
@@ -19,25 +21,87 @@ pub fn register_function(
19
21
  @as([*c]const u8, @ptrCast(name)),
20
22
  napi_function,
21
23
  ) != c.napi_ok) {
22
- return throw(env, "Failed to add " ++ name ++ "() to exports.");
24
+ return throw(env, .{
25
+ .message = "Failed to add " ++ name ++ "() to exports.",
26
+ });
23
27
  }
24
28
  }
25
29
 
26
- const TranslationError = error{ExceptionThrown};
27
- pub fn throw(env: c.napi_env, comptime message: [:0]const u8) TranslationError {
28
- const result = c.napi_throw_error(env, null, @as([*c]const u8, @ptrCast(message)));
30
+ pub const Error = error{ExceptionThrown};
31
+ pub fn throw(env: c.napi_env, comptime options: struct {
32
+ message: [:0]const u8,
33
+ }) Error {
34
+ const result = c.napi_throw_error(
35
+ env,
36
+ null,
37
+ options.message,
38
+ );
29
39
  switch (result) {
30
40
  c.napi_ok, c.napi_pending_exception => {},
31
41
  else => unreachable,
32
42
  }
33
43
 
34
- return TranslationError.ExceptionThrown;
44
+ return Error.ExceptionThrown;
45
+ }
46
+
47
+ pub fn throw_typed_error(
48
+ env: c.napi_env,
49
+ ctor_ref: c.napi_ref,
50
+ code: [:0]const u8,
51
+ ) Error {
52
+ var string: c.napi_value = undefined;
53
+ var ctor: c.napi_value = undefined;
54
+ var exception: c.napi_value = undefined;
55
+ if (c.napi_get_reference_value(
56
+ env,
57
+ ctor_ref,
58
+ &ctor,
59
+ ) != c.napi_ok) {
60
+ return throw(env, .{ .message = "Failed to get the constructor reference." });
61
+ }
62
+ assert(ctor != null);
63
+
64
+ if (c.napi_create_string_utf8(
65
+ env,
66
+ code,
67
+ code.len,
68
+ &string,
69
+ ) != c.napi_ok) {
70
+ return throw(env, .{ .message = "Failed to create string utf8." });
71
+ }
72
+ if (c.napi_new_instance(
73
+ env,
74
+ ctor,
75
+ 1,
76
+ &[_]c.napi_value{string},
77
+ &exception,
78
+ ) != c.napi_ok) {
79
+ return throw(env, .{ .message = "Failed to create new instance." });
80
+ }
81
+
82
+ // Asserting the exception got the right type.
83
+ var is_instance_of: bool = false;
84
+ assert(c.napi_instanceof(
85
+ env,
86
+ exception,
87
+ ctor,
88
+ &is_instance_of,
89
+ ) == c.napi_ok);
90
+ assert(is_instance_of);
91
+
92
+ if (c.napi_throw(env, exception) != c.napi_ok) {
93
+ return throw(env, .{ .message = "Failed to throw typed error" });
94
+ }
95
+
96
+ return Error.ExceptionThrown;
35
97
  }
36
98
 
37
99
  pub fn capture_null(env: c.napi_env) !c.napi_value {
38
100
  var result: c.napi_value = undefined;
39
101
  if (c.napi_get_null(env, &result) != c.napi_ok) {
40
- return throw(env, "Failed to capture the value of \"null\".");
102
+ return throw(env, .{
103
+ .message = "Failed to capture the value of \"null\".",
104
+ });
41
105
  }
42
106
 
43
107
  return result;
@@ -50,20 +114,21 @@ pub fn extract_args(env: c.napi_env, info: c.napi_callback_info, comptime args:
50
114
  var argc = args.count;
51
115
  var argv: [args.count]c.napi_value = undefined;
52
116
  if (c.napi_get_cb_info(env, info, &argc, &argv, null, null) != c.napi_ok) {
53
- return throw(
54
- env,
55
- std.fmt.comptimePrint("Failed to get args for {s}()\x00", .{args.function}),
56
- );
117
+ return throw(env, .{
118
+ .message = std.fmt.comptimePrint("Failed to get args for {s}()\x00", .{args.function}),
119
+ });
57
120
  }
58
121
 
59
122
  if (argc != args.count) {
60
- return throw(
61
- env,
62
- std.fmt.comptimePrint("Function {s}() requires exactly {} arguments.\x00", .{
63
- args.function,
64
- args.count,
65
- }),
66
- );
123
+ return throw(env, .{
124
+ .message = std.fmt.comptimePrint(
125
+ "Function {s}() requires exactly {} arguments.\x00",
126
+ .{
127
+ args.function,
128
+ args.count,
129
+ },
130
+ ),
131
+ });
67
132
  }
68
133
 
69
134
  return argv;
@@ -72,7 +137,9 @@ pub fn extract_args(env: c.napi_env, info: c.napi_callback_info, comptime args:
72
137
  pub fn create_external(env: c.napi_env, context: *anyopaque) !c.napi_value {
73
138
  var result: c.napi_value = null;
74
139
  if (c.napi_create_external(env, context, null, null, &result) != c.napi_ok) {
75
- return throw(env, "Failed to create external for client context.");
140
+ return throw(env, .{
141
+ .message = "Failed to create external for client context.",
142
+ });
76
143
  }
77
144
 
78
145
  return result;
@@ -85,7 +152,7 @@ pub fn value_external(
85
152
  ) !?*anyopaque {
86
153
  var result: ?*anyopaque = undefined;
87
154
  if (c.napi_get_value_external(env, value, &result) != c.napi_ok) {
88
- return throw(env, error_message);
155
+ return throw(env, .{ .message = error_message });
89
156
  }
90
157
 
91
158
  return result;
@@ -98,12 +165,28 @@ pub fn slice_from_object(
98
165
  ) ![]const u8 {
99
166
  var property: c.napi_value = undefined;
100
167
  if (c.napi_get_named_property(env, object, key, &property) != c.napi_ok) {
101
- return throw(env, key ++ " must be defined");
168
+ return throw(env, .{
169
+ .message = key ++ " must be defined",
170
+ });
102
171
  }
103
172
 
104
173
  return slice_from_value(env, property, key);
105
174
  }
106
175
 
176
+ pub fn get_object_property(
177
+ env: c.napi_env,
178
+ object: c.napi_value,
179
+ comptime key: [:0]const u8,
180
+ ) !c.napi_value {
181
+ var result: c.napi_value = undefined;
182
+ if (c.napi_get_named_property(env, object, key, &result) != c.napi_ok) {
183
+ return throw(env, .{
184
+ .message = key ++ " must be defined",
185
+ });
186
+ }
187
+ return result;
188
+ }
189
+
107
190
  pub fn slice_from_value(
108
191
  env: c.napi_env,
109
192
  value: c.napi_value,
@@ -112,13 +195,17 @@ pub fn slice_from_value(
112
195
  var is_buffer: bool = undefined;
113
196
  assert(c.napi_is_buffer(env, value, &is_buffer) == c.napi_ok);
114
197
 
115
- if (!is_buffer) return throw(env, key ++ " must be a buffer");
198
+ if (!is_buffer) return throw(env, .{
199
+ .message = key ++ " must be a buffer",
200
+ });
116
201
 
117
202
  var data: ?*anyopaque = null;
118
203
  var data_length: usize = undefined;
119
204
  assert(c.napi_get_buffer_info(env, value, &data, &data_length) == c.napi_ok);
120
205
 
121
- if (data_length < 1) return throw(env, key ++ " must not be empty");
206
+ if (data_length < 1) return throw(env, .{
207
+ .message = key ++ " must not be empty",
208
+ });
122
209
 
123
210
  return @as([*]u8, @ptrCast(data.?))[0..data_length];
124
211
  }
@@ -126,7 +213,9 @@ pub fn slice_from_value(
126
213
  pub fn u128_from_object(env: c.napi_env, object: c.napi_value, comptime key: [:0]const u8) !u128 {
127
214
  var property: c.napi_value = undefined;
128
215
  if (c.napi_get_named_property(env, object, key, &property) != c.napi_ok) {
129
- return throw(env, key ++ " must be defined");
216
+ return throw(env, .{
217
+ .message = key ++ " must be defined",
218
+ });
130
219
  }
131
220
 
132
221
  return u128_from_value(env, property, key);
@@ -135,7 +224,9 @@ pub fn u128_from_object(env: c.napi_env, object: c.napi_value, comptime key: [:0
135
224
  pub fn u64_from_object(env: c.napi_env, object: c.napi_value, comptime key: [:0]const u8) !u64 {
136
225
  var property: c.napi_value = undefined;
137
226
  if (c.napi_get_named_property(env, object, key, &property) != c.napi_ok) {
138
- return throw(env, key ++ " must be defined");
227
+ return throw(env, .{
228
+ .message = key ++ " must be defined",
229
+ });
139
230
  }
140
231
 
141
232
  return u64_from_value(env, property, key);
@@ -144,7 +235,9 @@ pub fn u64_from_object(env: c.napi_env, object: c.napi_value, comptime key: [:0]
144
235
  pub fn u32_from_object(env: c.napi_env, object: c.napi_value, comptime key: [:0]const u8) !u32 {
145
236
  var property: c.napi_value = undefined;
146
237
  if (c.napi_get_named_property(env, object, key, &property) != c.napi_ok) {
147
- return throw(env, key ++ " must be defined");
238
+ return throw(env, .{
239
+ .message = key ++ " must be defined",
240
+ });
148
241
  }
149
242
 
150
243
  return u32_from_value(env, property, key);
@@ -153,7 +246,9 @@ pub fn u32_from_object(env: c.napi_env, object: c.napi_value, comptime key: [:0]
153
246
  pub fn u16_from_object(env: c.napi_env, object: c.napi_value, comptime key: [:0]const u8) !u16 {
154
247
  const result = try u32_from_object(env, object, key);
155
248
  if (result > std.math.maxInt(u16)) {
156
- return throw(env, key ++ " must be a u16.");
249
+ return throw(env, .{
250
+ .message = key ++ " must be a u16.",
251
+ });
157
252
  }
158
253
 
159
254
  return @as(u16, @intCast(result));
@@ -171,11 +266,17 @@ pub fn u128_from_value(env: c.napi_env, value: c.napi_value, comptime name: [:0]
171
266
  var word_count: usize = 2;
172
267
  switch (c.napi_get_value_bigint_words(env, value, &sign_bit, &word_count, words)) {
173
268
  c.napi_ok => {},
174
- c.napi_bigint_expected => return throw(env, name ++ " must be a BigInt"),
269
+ c.napi_bigint_expected => return throw(env, .{
270
+ .message = name ++ " must be a BigInt",
271
+ }),
175
272
  else => unreachable,
176
273
  }
177
- if (sign_bit != 0) return throw(env, name ++ " must be positive");
178
- if (word_count > 2) return throw(env, name ++ " must fit in 128 bits");
274
+ if (sign_bit != 0) return throw(env, .{
275
+ .message = name ++ " must be positive",
276
+ });
277
+ if (word_count > 2) return throw(env, .{
278
+ .message = name ++ " must fit in 128 bits",
279
+ });
179
280
 
180
281
  return result;
181
282
  }
@@ -185,10 +286,14 @@ pub fn u64_from_value(env: c.napi_env, value: c.napi_value, comptime name: [:0]c
185
286
  var lossless: bool = undefined;
186
287
  switch (c.napi_get_value_bigint_uint64(env, value, &result, &lossless)) {
187
288
  c.napi_ok => {},
188
- c.napi_bigint_expected => return throw(env, name ++ " must be an unsigned 64-bit BigInt"),
289
+ c.napi_bigint_expected => return throw(env, .{
290
+ .message = name ++ " must be an unsigned 64-bit BigInt",
291
+ }),
189
292
  else => unreachable,
190
293
  }
191
- if (!lossless) return throw(env, name ++ " conversion was lossy");
294
+ if (!lossless) return throw(env, .{
295
+ .message = name ++ " conversion was lossy",
296
+ });
192
297
 
193
298
  return result;
194
299
  }
@@ -200,7 +305,9 @@ pub fn u32_from_value(env: c.napi_env, value: c.napi_value, comptime name: [:0]c
200
305
  // We want to make sure this is: unsigned, and an integer.
201
306
  switch (c.napi_get_value_uint32(env, value, &result)) {
202
307
  c.napi_ok => {},
203
- c.napi_number_expected => return throw(env, name ++ " must be a number"),
308
+ c.napi_number_expected => return throw(env, .{
309
+ .message = name ++ " must be a number",
310
+ }),
204
311
  else => unreachable,
205
312
  }
206
313
  return result;
@@ -226,7 +333,7 @@ pub fn u128_into_object(
226
333
  @as(*const [2]u64, @ptrCast(&value)),
227
334
  &bigint,
228
335
  ) != c.napi_ok) {
229
- return throw(env, error_message);
336
+ return throw(env, .{ .message = error_message });
230
337
  }
231
338
 
232
339
  if (c.napi_set_named_property(
@@ -235,7 +342,7 @@ pub fn u128_into_object(
235
342
  @ptrCast(key),
236
343
  bigint,
237
344
  ) != c.napi_ok) {
238
- return throw(env, error_message);
345
+ return throw(env, .{ .message = error_message });
239
346
  }
240
347
  }
241
348
 
@@ -248,7 +355,7 @@ pub fn u64_into_object(
248
355
  ) !void {
249
356
  var result: c.napi_value = undefined;
250
357
  if (c.napi_create_bigint_uint64(env, value, &result) != c.napi_ok) {
251
- return throw(env, error_message);
358
+ return throw(env, .{ .message = error_message });
252
359
  }
253
360
 
254
361
  if (c.napi_set_named_property(
@@ -257,7 +364,7 @@ pub fn u64_into_object(
257
364
  @ptrCast(key),
258
365
  result,
259
366
  ) != c.napi_ok) {
260
- return throw(env, error_message);
367
+ return throw(env, .{ .message = error_message });
261
368
  }
262
369
  }
263
370
 
@@ -270,11 +377,11 @@ pub fn u32_into_object(
270
377
  ) !void {
271
378
  var result: c.napi_value = undefined;
272
379
  if (c.napi_create_uint32(env, value, &result) != c.napi_ok) {
273
- return throw(env, error_message);
380
+ return throw(env, .{ .message = error_message });
274
381
  }
275
382
 
276
383
  if (c.napi_set_named_property(env, object, @ptrCast(key), result) != c.napi_ok) {
277
- return throw(env, error_message);
384
+ return throw(env, .{ .message = error_message });
278
385
  }
279
386
  }
280
387
 
@@ -291,7 +398,7 @@ pub fn u16_into_object(
291
398
  pub fn create_object(env: c.napi_env, comptime error_message: [:0]const u8) !c.napi_value {
292
399
  var result: c.napi_value = undefined;
293
400
  if (c.napi_create_object(env, &result) != c.napi_ok) {
294
- return throw(env, error_message);
401
+ return throw(env, .{ .message = error_message });
295
402
  }
296
403
 
297
404
  return result;
@@ -304,7 +411,7 @@ pub fn create_array(
304
411
  ) !c.napi_value {
305
412
  var result: c.napi_value = undefined;
306
413
  if (c.napi_create_array_with_length(env, length, &result) != c.napi_ok) {
307
- return throw(env, error_message);
414
+ return throw(env, .{ .message = error_message });
308
415
  }
309
416
 
310
417
  return result;
@@ -318,14 +425,14 @@ pub fn set_array_element(
318
425
  comptime error_message: [:0]const u8,
319
426
  ) !void {
320
427
  if (c.napi_set_element(env, array, index, value) != c.napi_ok) {
321
- return throw(env, error_message);
428
+ return throw(env, .{ .message = error_message });
322
429
  }
323
430
  }
324
431
 
325
432
  pub fn array_element(env: c.napi_env, array: c.napi_value, index: u32) !c.napi_value {
326
433
  var element: c.napi_value = undefined;
327
434
  if (c.napi_get_element(env, array, index, &element) != c.napi_ok) {
328
- return throw(env, "Failed to get array element.");
435
+ return throw(env, .{ .message = "Failed to get array element." });
329
436
  }
330
437
 
331
438
  return element;
@@ -334,7 +441,9 @@ pub fn array_element(env: c.napi_env, array: c.napi_value, index: u32) !c.napi_v
334
441
  pub fn array_length(env: c.napi_env, array: c.napi_value) !u32 {
335
442
  var is_array: bool = undefined;
336
443
  assert(c.napi_is_array(env, array, &is_array) == c.napi_ok);
337
- if (!is_array) return throw(env, "Batch must be an Array.");
444
+ if (!is_array) return throw(env, .{
445
+ .message = "Batch must be an Array.",
446
+ });
338
447
 
339
448
  var length: u32 = undefined;
340
449
  assert(c.napi_get_array_length(env, array, &length) == c.napi_ok);
@@ -342,9 +451,32 @@ pub fn array_length(env: c.napi_env, array: c.napi_value) !u32 {
342
451
  return length;
343
452
  }
344
453
 
454
+ pub fn create_reference(
455
+ env: c.napi_env,
456
+ object: c.napi_value,
457
+ reference_type: enum { strong, weak },
458
+ reference_out: *c.napi_ref,
459
+ comptime error_message: [:0]const u8,
460
+ ) !void {
461
+ const initial_ref_count: u32 = switch (reference_type) {
462
+ .weak => 0,
463
+ .strong => 1,
464
+ };
465
+ if (c.napi_create_reference(
466
+ env,
467
+ object,
468
+ initial_ref_count,
469
+ reference_out,
470
+ ) != c.napi_ok) {
471
+ return throw(env, .{ .message = error_message });
472
+ }
473
+ }
474
+
345
475
  pub fn delete_reference(env: c.napi_env, reference: c.napi_ref) !void {
346
476
  if (c.napi_delete_reference(env, reference) != c.napi_ok) {
347
- return throw(env, "Failed to delete callback reference.");
477
+ return throw(env, .{
478
+ .message = "Failed to delete callback reference.",
479
+ });
348
480
  }
349
481
  }
350
482
 
@@ -360,7 +492,9 @@ pub fn call_function(
360
492
  // the user's callback may throw a JS exception or call other functions that do so. We
361
493
  // therefore don't throw another error.
362
494
  c.napi_pending_exception => {},
363
- else => return throw(env, "Failed to invoke results callback."),
495
+ else => return throw(env, .{
496
+ .message = "Failed to invoke results callback.",
497
+ }),
364
498
  }
365
499
  return result;
366
500
  }
@@ -372,7 +506,7 @@ pub fn reference_value(
372
506
  ) !c.napi_value {
373
507
  var result: c.napi_value = undefined;
374
508
  if (c.napi_get_reference_value(env, callback_reference, &result) != c.napi_ok) {
375
- return throw(env, error_message);
509
+ return throw(env, .{ .message = error_message });
376
510
  }
377
511
 
378
512
  return result;