tigerbeetle-node 0.4.2 → 0.5.2
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/README.md +19 -5
- package/dist/benchmark.js.map +1 -1
- package/dist/index.d.ts +18 -16
- package/dist/index.js +35 -13
- package/dist/index.js.map +1 -1
- package/dist/test.js +12 -0
- package/dist/test.js.map +1 -1
- package/package.json +2 -2
- package/scripts/postinstall.sh +2 -2
- package/src/benchmark.ts +2 -2
- package/src/index.ts +29 -4
- package/src/node.zig +120 -17
- package/src/test.ts +14 -0
- package/src/tigerbeetle/scripts/install.sh +1 -1
- package/src/tigerbeetle/scripts/install_zig.bat +109 -0
- package/src/tigerbeetle/scripts/install_zig.sh +4 -2
- package/src/tigerbeetle/scripts/lint.zig +8 -2
- package/src/tigerbeetle/scripts/vopr.bat +48 -0
- package/src/tigerbeetle/src/benchmark.zig +10 -8
- package/src/tigerbeetle/src/cli.zig +6 -4
- package/src/tigerbeetle/src/config.zig +2 -2
- package/src/tigerbeetle/src/demo.zig +119 -89
- package/src/tigerbeetle/src/demo_01_create_accounts.zig +5 -3
- package/src/tigerbeetle/src/demo_02_lookup_accounts.zig +2 -3
- package/src/tigerbeetle/src/demo_03_create_transfers.zig +5 -3
- package/src/tigerbeetle/src/demo_04_create_transfers_two_phase_commit.zig +5 -3
- package/src/tigerbeetle/src/demo_05_accept_transfers.zig +5 -3
- package/src/tigerbeetle/src/demo_06_reject_transfers.zig +5 -3
- package/src/tigerbeetle/src/demo_07_lookup_transfers.zig +7 -0
- package/src/tigerbeetle/src/io/benchmark.zig +238 -0
- package/src/tigerbeetle/src/{io_darwin.zig → io/darwin.zig} +89 -124
- package/src/tigerbeetle/src/io/linux.zig +933 -0
- package/src/tigerbeetle/src/io/test.zig +621 -0
- package/src/tigerbeetle/src/io.zig +7 -1328
- package/src/tigerbeetle/src/main.zig +18 -10
- package/src/tigerbeetle/src/message_bus.zig +43 -60
- package/src/tigerbeetle/src/message_pool.zig +3 -2
- package/src/tigerbeetle/src/ring_buffer.zig +135 -68
- package/src/tigerbeetle/src/simulator.zig +41 -37
- package/src/tigerbeetle/src/state_machine.zig +851 -26
- package/src/tigerbeetle/src/storage.zig +49 -46
- package/src/tigerbeetle/src/test/cluster.zig +2 -2
- package/src/tigerbeetle/src/test/message_bus.zig +6 -6
- package/src/tigerbeetle/src/test/network.zig +3 -3
- package/src/tigerbeetle/src/test/packet_simulator.zig +32 -29
- package/src/tigerbeetle/src/test/state_checker.zig +2 -2
- package/src/tigerbeetle/src/test/state_machine.zig +4 -0
- package/src/tigerbeetle/src/test/storage.zig +39 -19
- package/src/tigerbeetle/src/test/time.zig +2 -2
- package/src/tigerbeetle/src/tigerbeetle.zig +6 -129
- package/src/tigerbeetle/src/time.zig +6 -5
- package/src/tigerbeetle/src/vsr/client.zig +11 -11
- package/src/tigerbeetle/src/vsr/clock.zig +26 -43
- package/src/tigerbeetle/src/vsr/journal.zig +7 -6
- package/src/tigerbeetle/src/vsr/marzullo.zig +6 -3
- package/src/tigerbeetle/src/vsr/replica.zig +51 -48
- package/src/tigerbeetle/src/vsr.zig +24 -20
- package/src/translate.zig +55 -55
|
@@ -16,7 +16,7 @@ pub const Clock = @import("vsr/clock.zig").Clock;
|
|
|
16
16
|
pub const Journal = @import("vsr/journal.zig").Journal;
|
|
17
17
|
|
|
18
18
|
/// Viewstamped Replication protocol commands:
|
|
19
|
-
pub const Command =
|
|
19
|
+
pub const Command = enum(u8) {
|
|
20
20
|
reserved,
|
|
21
21
|
|
|
22
22
|
ping,
|
|
@@ -387,14 +387,14 @@ pub const Timeout = struct {
|
|
|
387
387
|
/// Allows the attempts counter to wrap from time to time.
|
|
388
388
|
/// The overflow period is kept short to surface any related bugs sooner rather than later.
|
|
389
389
|
/// We do not saturate the counter as this would cause round-robin retries to get stuck.
|
|
390
|
-
pub fn backoff(self: *Timeout,
|
|
390
|
+
pub fn backoff(self: *Timeout, random: std.rand.Random) void {
|
|
391
391
|
assert(self.ticking);
|
|
392
392
|
|
|
393
393
|
self.ticks = 0;
|
|
394
394
|
self.attempts +%= 1;
|
|
395
395
|
|
|
396
396
|
log.debug("{}: {s} backing off", .{ self.id, self.name });
|
|
397
|
-
self.set_after_for_rtt_and_attempts(
|
|
397
|
+
self.set_after_for_rtt_and_attempts(random);
|
|
398
398
|
}
|
|
399
399
|
|
|
400
400
|
/// It's important to check that when fired() is acted on that the timeout is stopped/started,
|
|
@@ -403,7 +403,7 @@ pub const Timeout = struct {
|
|
|
403
403
|
if (self.ticking and self.ticks >= self.after) {
|
|
404
404
|
log.debug("{}: {s} fired", .{ self.id, self.name });
|
|
405
405
|
if (self.ticks > self.after) {
|
|
406
|
-
log.
|
|
406
|
+
log.err("{}: {s} is firing every tick", .{ self.id, self.name });
|
|
407
407
|
@panic("timeout was not reset correctly");
|
|
408
408
|
}
|
|
409
409
|
return true;
|
|
@@ -423,13 +423,13 @@ pub const Timeout = struct {
|
|
|
423
423
|
/// Sets the value of `after` as a function of `rtt` and `attempts`.
|
|
424
424
|
/// Adds exponential backoff and jitter.
|
|
425
425
|
/// May be called only after a timeout has been stopped or reset, to prevent backward jumps.
|
|
426
|
-
pub fn set_after_for_rtt_and_attempts(self: *Timeout,
|
|
426
|
+
pub fn set_after_for_rtt_and_attempts(self: *Timeout, random: std.rand.Random) void {
|
|
427
427
|
// If `after` is reduced by this function to less than `ticks`, then `fired()` will panic:
|
|
428
428
|
assert(self.ticks == 0);
|
|
429
429
|
assert(self.rtt > 0);
|
|
430
430
|
|
|
431
431
|
const after = (self.rtt * self.rtt_multiple) + exponential_backoff_with_jitter(
|
|
432
|
-
|
|
432
|
+
random,
|
|
433
433
|
config.backoff_min_ticks,
|
|
434
434
|
config.backoff_max_ticks,
|
|
435
435
|
self.attempts,
|
|
@@ -488,7 +488,7 @@ pub const Timeout = struct {
|
|
|
488
488
|
|
|
489
489
|
/// Calculates exponential backoff with jitter to prevent cascading failure due to thundering herds.
|
|
490
490
|
pub fn exponential_backoff_with_jitter(
|
|
491
|
-
|
|
491
|
+
random: std.rand.Random,
|
|
492
492
|
min: u64,
|
|
493
493
|
max: u64,
|
|
494
494
|
attempt: u64,
|
|
@@ -504,35 +504,39 @@ pub fn exponential_backoff_with_jitter(
|
|
|
504
504
|
// 1<<0 = 1, 1<<1 = 2, 1<<2 = 4, 1<<3 = 8
|
|
505
505
|
const power = std.math.shlExact(u128, 1, exponent) catch unreachable; // Do not truncate.
|
|
506
506
|
|
|
507
|
+
// Ensure that `backoff` is calculated correctly when min is 0, taking `std.math.max(1, min)`.
|
|
508
|
+
// Otherwise, the final result will always be 0. This was an actual bug we encountered.
|
|
509
|
+
const min_non_zero = std.math.max(1, min);
|
|
510
|
+
assert(min_non_zero > 0);
|
|
511
|
+
assert(power > 0);
|
|
512
|
+
|
|
507
513
|
// Calculate the capped exponential backoff component, `min(range, min * 2 ^ attempt)`:
|
|
508
|
-
const backoff = std.math.min(range,
|
|
509
|
-
const jitter =
|
|
514
|
+
const backoff = std.math.min(range, min_non_zero * power);
|
|
515
|
+
const jitter = random.uintAtMostBiased(u64, backoff);
|
|
510
516
|
|
|
511
517
|
const result = @intCast(u64, min + jitter);
|
|
512
518
|
assert(result >= min);
|
|
513
519
|
assert(result <= max);
|
|
520
|
+
|
|
514
521
|
return result;
|
|
515
522
|
}
|
|
516
523
|
|
|
517
524
|
test "exponential_backoff_with_jitter" {
|
|
518
525
|
const testing = std.testing;
|
|
519
526
|
|
|
520
|
-
const attempts = 1000;
|
|
521
527
|
var prng = std.rand.DefaultPrng.init(0);
|
|
528
|
+
const random = prng.random();
|
|
529
|
+
|
|
530
|
+
const attempts = 1000;
|
|
522
531
|
const max: u64 = std.math.maxInt(u64);
|
|
523
532
|
const min = max - attempts;
|
|
533
|
+
|
|
524
534
|
var attempt = max - attempts;
|
|
525
535
|
while (attempt < max) : (attempt += 1) {
|
|
526
|
-
const ebwj = exponential_backoff_with_jitter(
|
|
536
|
+
const ebwj = exponential_backoff_with_jitter(random, min, max, attempt);
|
|
527
537
|
try testing.expect(ebwj >= min);
|
|
528
538
|
try testing.expect(ebwj <= max);
|
|
529
539
|
}
|
|
530
|
-
|
|
531
|
-
// Check that `backoff` is calculated correctly when min is 0 by taking `std.math.max(1, min)`.
|
|
532
|
-
// Otherwise, the final result will always be 0. This was an actual bug we encountered.
|
|
533
|
-
// If the PRNG ever changes, then there is a small chance that we may collide for 0,
|
|
534
|
-
// but this is outweighed by the probability that we refactor and fail to take the max.
|
|
535
|
-
try testing.expect(exponential_backoff_with_jitter(&prng, 0, max, 0) > 0);
|
|
536
540
|
}
|
|
537
541
|
|
|
538
542
|
/// Returns An array containing the remote or local addresses of each of the 2f + 1 replicas:
|
|
@@ -544,17 +548,17 @@ test "exponential_backoff_with_jitter" {
|
|
|
544
548
|
/// The caller owns the memory of the returned slice of addresses.
|
|
545
549
|
/// TODO Unit tests.
|
|
546
550
|
/// TODO Integrate into `src/cli.zig`.
|
|
547
|
-
pub fn parse_addresses(allocator:
|
|
551
|
+
pub fn parse_addresses(allocator: std.mem.Allocator, raw: []const u8) ![]std.net.Address {
|
|
548
552
|
var addresses = try allocator.alloc(std.net.Address, config.replicas_max);
|
|
549
553
|
errdefer allocator.free(addresses);
|
|
550
554
|
|
|
551
555
|
var index: usize = 0;
|
|
552
|
-
var comma_iterator = std.mem.split(raw, ",");
|
|
556
|
+
var comma_iterator = std.mem.split(u8, raw, ",");
|
|
553
557
|
while (comma_iterator.next()) |raw_address| : (index += 1) {
|
|
554
558
|
if (raw_address.len == 0) return error.AddressHasTrailingComma;
|
|
555
559
|
if (index == config.replicas_max) return error.AddressLimitExceeded;
|
|
556
560
|
|
|
557
|
-
var colon_iterator = std.mem.split(raw_address, ":");
|
|
561
|
+
var colon_iterator = std.mem.split(u8, raw_address, ":");
|
|
558
562
|
// The split iterator will always return non-null once, even if the delimiter is not found:
|
|
559
563
|
const raw_ipv4 = colon_iterator.next().?;
|
|
560
564
|
|
package/src/translate.zig
CHANGED
|
@@ -9,11 +9,11 @@ pub fn register_function(
|
|
|
9
9
|
function: fn (env: c.napi_env, info: c.napi_callback_info) callconv(.C) c.napi_value,
|
|
10
10
|
) !void {
|
|
11
11
|
var napi_function: c.napi_value = undefined;
|
|
12
|
-
if (c.napi_create_function(env, null, 0, function, null, &napi_function) != .napi_ok) {
|
|
12
|
+
if (c.napi_create_function(env, null, 0, function, null, &napi_function) != c.napi_ok) {
|
|
13
13
|
return throw(env, "Failed to create function " ++ name ++ "().");
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
if (c.napi_set_named_property(env, exports, name, napi_function) != .napi_ok) {
|
|
16
|
+
if (c.napi_set_named_property(env, exports, name, napi_function) != c.napi_ok) {
|
|
17
17
|
return throw(env, "Failed to add " ++ name ++ "() to exports.");
|
|
18
18
|
}
|
|
19
19
|
}
|
|
@@ -22,7 +22,7 @@ const TranslationError = error{ExceptionThrown};
|
|
|
22
22
|
pub fn throw(env: c.napi_env, comptime message: [:0]const u8) TranslationError {
|
|
23
23
|
var result = c.napi_throw_error(env, null, message);
|
|
24
24
|
switch (result) {
|
|
25
|
-
.napi_ok, .napi_pending_exception => {},
|
|
25
|
+
c.napi_ok, c.napi_pending_exception => {},
|
|
26
26
|
else => unreachable,
|
|
27
27
|
}
|
|
28
28
|
|
|
@@ -31,7 +31,7 @@ pub fn throw(env: c.napi_env, comptime message: [:0]const u8) TranslationError {
|
|
|
31
31
|
|
|
32
32
|
pub fn capture_undefined(env: c.napi_env) !c.napi_value {
|
|
33
33
|
var result: c.napi_value = undefined;
|
|
34
|
-
if (c.napi_get_undefined(env, &result) != .napi_ok) {
|
|
34
|
+
if (c.napi_get_undefined(env, &result) != c.napi_ok) {
|
|
35
35
|
return throw(env, "Failed to capture the value of \"undefined\".");
|
|
36
36
|
}
|
|
37
37
|
|
|
@@ -40,17 +40,17 @@ pub fn capture_undefined(env: c.napi_env) !c.napi_value {
|
|
|
40
40
|
|
|
41
41
|
pub fn set_instance_data(
|
|
42
42
|
env: c.napi_env,
|
|
43
|
-
data: *
|
|
44
|
-
finalize_callback: fn (env: c.napi_env, data: ?*
|
|
43
|
+
data: *anyopaque,
|
|
44
|
+
finalize_callback: fn (env: c.napi_env, data: ?*anyopaque, hint: ?*anyopaque) callconv(.C) void,
|
|
45
45
|
) !void {
|
|
46
|
-
if (c.napi_set_instance_data(env, data, finalize_callback, null) != .napi_ok) {
|
|
46
|
+
if (c.napi_set_instance_data(env, data, finalize_callback, null) != c.napi_ok) {
|
|
47
47
|
return throw(env, "Failed to initialize environment.");
|
|
48
48
|
}
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
-
pub fn create_external(env: c.napi_env, context: *
|
|
51
|
+
pub fn create_external(env: c.napi_env, context: *anyopaque) !c.napi_value {
|
|
52
52
|
var result: c.napi_value = null;
|
|
53
|
-
if (c.napi_create_external(env, context, null, null, &result) != .napi_ok) {
|
|
53
|
+
if (c.napi_create_external(env, context, null, null, &result) != c.napi_ok) {
|
|
54
54
|
return throw(env, "Failed to create external for client context.");
|
|
55
55
|
}
|
|
56
56
|
|
|
@@ -61,9 +61,9 @@ pub fn value_external(
|
|
|
61
61
|
env: c.napi_env,
|
|
62
62
|
value: c.napi_value,
|
|
63
63
|
comptime error_message: [:0]const u8,
|
|
64
|
-
) !?*
|
|
65
|
-
var result: ?*
|
|
66
|
-
if (c.napi_get_value_external(env, value, &result) != .napi_ok) {
|
|
64
|
+
) !?*anyopaque {
|
|
65
|
+
var result: ?*anyopaque = undefined;
|
|
66
|
+
if (c.napi_get_value_external(env, value, &result) != c.napi_ok) {
|
|
67
67
|
return throw(env, error_message);
|
|
68
68
|
}
|
|
69
69
|
|
|
@@ -79,13 +79,13 @@ pub const UserData = packed struct {
|
|
|
79
79
|
/// This reference will be destroyed when we return the server response to JS.
|
|
80
80
|
pub fn user_data_from_value(env: c.napi_env, value: c.napi_value) !UserData {
|
|
81
81
|
var callback_type: c.napi_valuetype = undefined;
|
|
82
|
-
if (c.napi_typeof(env, value, &callback_type) != .napi_ok) {
|
|
82
|
+
if (c.napi_typeof(env, value, &callback_type) != c.napi_ok) {
|
|
83
83
|
return throw(env, "Failed to check callback type.");
|
|
84
84
|
}
|
|
85
|
-
if (callback_type != .napi_function) return throw(env, "Callback must be a Function.");
|
|
85
|
+
if (callback_type != c.napi_function) return throw(env, "Callback must be a Function.");
|
|
86
86
|
|
|
87
87
|
var callback_reference: c.napi_ref = undefined;
|
|
88
|
-
if (c.napi_create_reference(env, value, 1, &callback_reference) != .napi_ok) {
|
|
88
|
+
if (c.napi_create_reference(env, value, 1, &callback_reference) != c.napi_ok) {
|
|
89
89
|
return throw(env, "Failed to create reference to callback.");
|
|
90
90
|
}
|
|
91
91
|
|
|
@@ -95,9 +95,9 @@ pub fn user_data_from_value(env: c.napi_env, value: c.napi_value) !UserData {
|
|
|
95
95
|
};
|
|
96
96
|
}
|
|
97
97
|
|
|
98
|
-
pub fn globals(env: c.napi_env) !?*
|
|
99
|
-
var data: ?*
|
|
100
|
-
if (c.napi_get_instance_data(env, &data) != .napi_ok) {
|
|
98
|
+
pub fn globals(env: c.napi_env) !?*anyopaque {
|
|
99
|
+
var data: ?*anyopaque = null;
|
|
100
|
+
if (c.napi_get_instance_data(env, &data) != c.napi_ok) {
|
|
101
101
|
return throw(env, "Failed to decode globals.");
|
|
102
102
|
}
|
|
103
103
|
|
|
@@ -110,7 +110,7 @@ pub fn slice_from_object(
|
|
|
110
110
|
comptime key: [:0]const u8,
|
|
111
111
|
) ![]const u8 {
|
|
112
112
|
var property: c.napi_value = undefined;
|
|
113
|
-
if (c.napi_get_named_property(env, object, key, &property) != .napi_ok) {
|
|
113
|
+
if (c.napi_get_named_property(env, object, key, &property) != c.napi_ok) {
|
|
114
114
|
return throw(env, key ++ " must be defined");
|
|
115
115
|
}
|
|
116
116
|
|
|
@@ -123,13 +123,13 @@ pub fn slice_from_value(
|
|
|
123
123
|
comptime key: [:0]const u8,
|
|
124
124
|
) ![]u8 {
|
|
125
125
|
var is_buffer: bool = undefined;
|
|
126
|
-
assert(c.napi_is_buffer(env, value, &is_buffer) == .napi_ok);
|
|
126
|
+
assert(c.napi_is_buffer(env, value, &is_buffer) == c.napi_ok);
|
|
127
127
|
|
|
128
128
|
if (!is_buffer) return throw(env, key ++ " must be a buffer");
|
|
129
129
|
|
|
130
|
-
var data: ?*
|
|
130
|
+
var data: ?*anyopaque = null;
|
|
131
131
|
var data_length: usize = undefined;
|
|
132
|
-
assert(c.napi_get_buffer_info(env, value, &data, &data_length) == .napi_ok);
|
|
132
|
+
assert(c.napi_get_buffer_info(env, value, &data, &data_length) == c.napi_ok);
|
|
133
133
|
|
|
134
134
|
if (data_length < 1) return throw(env, key ++ " must not be empty");
|
|
135
135
|
|
|
@@ -143,7 +143,7 @@ pub fn bytes_from_object(
|
|
|
143
143
|
comptime key: [:0]const u8,
|
|
144
144
|
) ![length]u8 {
|
|
145
145
|
var property: c.napi_value = undefined;
|
|
146
|
-
if (c.napi_get_named_property(env, object, key, &property) != .napi_ok) {
|
|
146
|
+
if (c.napi_get_named_property(env, object, key, &property) != c.napi_ok) {
|
|
147
147
|
return throw(env, key ++ " must be defined");
|
|
148
148
|
}
|
|
149
149
|
|
|
@@ -181,7 +181,7 @@ pub fn bytes_from_buffer(
|
|
|
181
181
|
|
|
182
182
|
pub fn u128_from_object(env: c.napi_env, object: c.napi_value, comptime key: [:0]const u8) !u128 {
|
|
183
183
|
var property: c.napi_value = undefined;
|
|
184
|
-
if (c.napi_get_named_property(env, object, key, &property) != .napi_ok) {
|
|
184
|
+
if (c.napi_get_named_property(env, object, key, &property) != c.napi_ok) {
|
|
185
185
|
return throw(env, key ++ " must be defined");
|
|
186
186
|
}
|
|
187
187
|
|
|
@@ -190,7 +190,7 @@ pub fn u128_from_object(env: c.napi_env, object: c.napi_value, comptime key: [:0
|
|
|
190
190
|
|
|
191
191
|
pub fn u64_from_object(env: c.napi_env, object: c.napi_value, comptime key: [:0]const u8) !u64 {
|
|
192
192
|
var property: c.napi_value = undefined;
|
|
193
|
-
if (c.napi_get_named_property(env, object, key, &property) != .napi_ok) {
|
|
193
|
+
if (c.napi_get_named_property(env, object, key, &property) != c.napi_ok) {
|
|
194
194
|
return throw(env, key ++ " must be defined");
|
|
195
195
|
}
|
|
196
196
|
|
|
@@ -199,7 +199,7 @@ pub fn u64_from_object(env: c.napi_env, object: c.napi_value, comptime key: [:0]
|
|
|
199
199
|
|
|
200
200
|
pub fn u32_from_object(env: c.napi_env, object: c.napi_value, comptime key: [:0]const u8) !u32 {
|
|
201
201
|
var property: c.napi_value = undefined;
|
|
202
|
-
if (c.napi_get_named_property(env, object, key, &property) != .napi_ok) {
|
|
202
|
+
if (c.napi_get_named_property(env, object, key, &property) != c.napi_ok) {
|
|
203
203
|
return throw(env, key ++ " must be defined");
|
|
204
204
|
}
|
|
205
205
|
|
|
@@ -225,8 +225,8 @@ pub fn u128_from_value(env: c.napi_env, value: c.napi_value, comptime name: [:0]
|
|
|
225
225
|
const words = @ptrCast(*[2]u64, &result);
|
|
226
226
|
var word_count: usize = 2;
|
|
227
227
|
switch (c.napi_get_value_bigint_words(env, value, &sign_bit, &word_count, words)) {
|
|
228
|
-
.napi_ok => {},
|
|
229
|
-
.napi_bigint_expected => return throw(env, name ++ " must be a BigInt"),
|
|
228
|
+
c.napi_ok => {},
|
|
229
|
+
c.napi_bigint_expected => return throw(env, name ++ " must be a BigInt"),
|
|
230
230
|
else => unreachable,
|
|
231
231
|
}
|
|
232
232
|
if (sign_bit != 0) return throw(env, name ++ " must be positive");
|
|
@@ -239,8 +239,8 @@ pub fn u64_from_value(env: c.napi_env, value: c.napi_value, comptime name: [:0]c
|
|
|
239
239
|
var result: u64 = undefined;
|
|
240
240
|
var lossless: bool = undefined;
|
|
241
241
|
switch (c.napi_get_value_bigint_uint64(env, value, &result, &lossless)) {
|
|
242
|
-
.napi_ok => {},
|
|
243
|
-
.napi_bigint_expected => return throw(env, name ++ " must be an unsigned 64-bit BigInt"),
|
|
242
|
+
c.napi_ok => {},
|
|
243
|
+
c.napi_bigint_expected => return throw(env, name ++ " must be an unsigned 64-bit BigInt"),
|
|
244
244
|
else => unreachable,
|
|
245
245
|
}
|
|
246
246
|
if (!lossless) return throw(env, name ++ " conversion was lossy");
|
|
@@ -254,8 +254,8 @@ pub fn u32_from_value(env: c.napi_env, value: c.napi_value, comptime name: [:0]c
|
|
|
254
254
|
// In that case we need to use the appropriate napi method to do more type checking here.
|
|
255
255
|
// We want to make sure this is: unsigned, and an integer.
|
|
256
256
|
switch (c.napi_get_value_uint32(env, value, &result)) {
|
|
257
|
-
.napi_ok => {},
|
|
258
|
-
.napi_number_expected => return throw(env, name ++ " must be a number"),
|
|
257
|
+
c.napi_ok => {},
|
|
258
|
+
c.napi_number_expected => return throw(env, name ++ " must be a number"),
|
|
259
259
|
else => unreachable,
|
|
260
260
|
}
|
|
261
261
|
return result;
|
|
@@ -270,11 +270,11 @@ pub fn byte_slice_into_object(
|
|
|
270
270
|
) !void {
|
|
271
271
|
var result: c.napi_value = undefined;
|
|
272
272
|
// create a copy that is managed by V8.
|
|
273
|
-
if (c.napi_create_buffer_copy(env, value.len, value.ptr, null, &result) != .napi_ok) {
|
|
273
|
+
if (c.napi_create_buffer_copy(env, value.len, value.ptr, null, &result) != c.napi_ok) {
|
|
274
274
|
return throw(env, error_message ++ " Failed to allocate Buffer in V8.");
|
|
275
275
|
}
|
|
276
276
|
|
|
277
|
-
if (c.napi_set_named_property(env, object, key, result) != .napi_ok) {
|
|
277
|
+
if (c.napi_set_named_property(env, object, key, result) != c.napi_ok) {
|
|
278
278
|
return throw(env, error_message);
|
|
279
279
|
}
|
|
280
280
|
}
|
|
@@ -297,11 +297,11 @@ pub fn u128_into_object(
|
|
|
297
297
|
2,
|
|
298
298
|
@ptrCast(*const [2]u64, &value),
|
|
299
299
|
&bigint,
|
|
300
|
-
) != .napi_ok) {
|
|
300
|
+
) != c.napi_ok) {
|
|
301
301
|
return throw(env, error_message);
|
|
302
302
|
}
|
|
303
303
|
|
|
304
|
-
if (c.napi_set_named_property(env, object, key, bigint) != .napi_ok) {
|
|
304
|
+
if (c.napi_set_named_property(env, object, key, bigint) != c.napi_ok) {
|
|
305
305
|
return throw(env, error_message);
|
|
306
306
|
}
|
|
307
307
|
}
|
|
@@ -314,11 +314,11 @@ pub fn u64_into_object(
|
|
|
314
314
|
comptime error_message: [:0]const u8,
|
|
315
315
|
) !void {
|
|
316
316
|
var result: c.napi_value = undefined;
|
|
317
|
-
if (c.napi_create_bigint_uint64(env, value, &result) != .napi_ok) {
|
|
317
|
+
if (c.napi_create_bigint_uint64(env, value, &result) != c.napi_ok) {
|
|
318
318
|
return throw(env, error_message);
|
|
319
319
|
}
|
|
320
320
|
|
|
321
|
-
if (c.napi_set_named_property(env, object, key, result) != .napi_ok) {
|
|
321
|
+
if (c.napi_set_named_property(env, object, key, result) != c.napi_ok) {
|
|
322
322
|
return throw(env, error_message);
|
|
323
323
|
}
|
|
324
324
|
}
|
|
@@ -331,18 +331,18 @@ pub fn u32_into_object(
|
|
|
331
331
|
comptime error_message: [:0]const u8,
|
|
332
332
|
) !void {
|
|
333
333
|
var result: c.napi_value = undefined;
|
|
334
|
-
if (c.napi_create_uint32(env, value, &result) != .napi_ok) {
|
|
334
|
+
if (c.napi_create_uint32(env, value, &result) != c.napi_ok) {
|
|
335
335
|
return throw(env, error_message);
|
|
336
336
|
}
|
|
337
337
|
|
|
338
|
-
if (c.napi_set_named_property(env, object, key, result) != .napi_ok) {
|
|
338
|
+
if (c.napi_set_named_property(env, object, key, result) != c.napi_ok) {
|
|
339
339
|
return throw(env, error_message);
|
|
340
340
|
}
|
|
341
341
|
}
|
|
342
342
|
|
|
343
343
|
pub fn create_object(env: c.napi_env, comptime error_message: [:0]const u8) !c.napi_value {
|
|
344
344
|
var result: c.napi_value = undefined;
|
|
345
|
-
if (c.napi_create_object(env, &result) != .napi_ok) {
|
|
345
|
+
if (c.napi_create_object(env, &result) != c.napi_ok) {
|
|
346
346
|
return throw(env, error_message);
|
|
347
347
|
}
|
|
348
348
|
|
|
@@ -354,9 +354,9 @@ fn create_buffer(
|
|
|
354
354
|
value: []const u8,
|
|
355
355
|
comptime error_message: [:0]const u8,
|
|
356
356
|
) !c.napi_value {
|
|
357
|
-
var data: ?*
|
|
357
|
+
var data: ?*anyopaque = undefined;
|
|
358
358
|
var result: c.napi_value = undefined;
|
|
359
|
-
if (c.napi_create_buffer(env, value.len, &data, &result) != .napi_ok) {
|
|
359
|
+
if (c.napi_create_buffer(env, value.len, &data, &result) != c.napi_ok) {
|
|
360
360
|
return throw(env, error_message);
|
|
361
361
|
}
|
|
362
362
|
|
|
@@ -371,7 +371,7 @@ pub fn create_array(
|
|
|
371
371
|
comptime error_message: [:0]const u8,
|
|
372
372
|
) !c.napi_value {
|
|
373
373
|
var result: c.napi_value = undefined;
|
|
374
|
-
if (c.napi_create_array_with_length(env, length, &result) != .napi_ok) {
|
|
374
|
+
if (c.napi_create_array_with_length(env, length, &result) != c.napi_ok) {
|
|
375
375
|
return throw(env, error_message);
|
|
376
376
|
}
|
|
377
377
|
|
|
@@ -385,14 +385,14 @@ pub fn set_array_element(
|
|
|
385
385
|
value: c.napi_value,
|
|
386
386
|
comptime error_message: [:0]const u8,
|
|
387
387
|
) !void {
|
|
388
|
-
if (c.napi_set_element(env, array, index, value) != .napi_ok) {
|
|
388
|
+
if (c.napi_set_element(env, array, index, value) != c.napi_ok) {
|
|
389
389
|
return throw(env, error_message);
|
|
390
390
|
}
|
|
391
391
|
}
|
|
392
392
|
|
|
393
393
|
pub fn array_element(env: c.napi_env, array: c.napi_value, index: u32) !c.napi_value {
|
|
394
394
|
var element: c.napi_value = undefined;
|
|
395
|
-
if (c.napi_get_element(env, array, index, &element) != .napi_ok) {
|
|
395
|
+
if (c.napi_get_element(env, array, index, &element) != c.napi_ok) {
|
|
396
396
|
return throw(env, "Failed to get array element.");
|
|
397
397
|
}
|
|
398
398
|
|
|
@@ -401,17 +401,17 @@ pub fn array_element(env: c.napi_env, array: c.napi_value, index: u32) !c.napi_v
|
|
|
401
401
|
|
|
402
402
|
pub fn array_length(env: c.napi_env, array: c.napi_value) !u32 {
|
|
403
403
|
var is_array: bool = undefined;
|
|
404
|
-
assert(c.napi_is_array(env, array, &is_array) == .napi_ok);
|
|
404
|
+
assert(c.napi_is_array(env, array, &is_array) == c.napi_ok);
|
|
405
405
|
if (!is_array) return throw(env, "Batch must be an Array.");
|
|
406
406
|
|
|
407
407
|
var length: u32 = undefined;
|
|
408
|
-
assert(c.napi_get_array_length(env, array, &length) == .napi_ok);
|
|
408
|
+
assert(c.napi_get_array_length(env, array, &length) == c.napi_ok);
|
|
409
409
|
|
|
410
410
|
return length;
|
|
411
411
|
}
|
|
412
412
|
|
|
413
413
|
pub fn delete_reference(env: c.napi_env, reference: c.napi_ref) !void {
|
|
414
|
-
if (c.napi_delete_reference(env, reference) != .napi_ok) {
|
|
414
|
+
if (c.napi_delete_reference(env, reference) != c.napi_ok) {
|
|
415
415
|
return throw(env, "Failed to delete callback reference.");
|
|
416
416
|
}
|
|
417
417
|
}
|
|
@@ -421,12 +421,12 @@ pub fn create_error(
|
|
|
421
421
|
comptime message: [:0]const u8,
|
|
422
422
|
) TranslationError!c.napi_value {
|
|
423
423
|
var napi_string: c.napi_value = undefined;
|
|
424
|
-
if (c.napi_create_string_utf8(env, message, std.mem.len(message), &napi_string) != .napi_ok) {
|
|
424
|
+
if (c.napi_create_string_utf8(env, message, std.mem.len(message), &napi_string) != c.napi_ok) {
|
|
425
425
|
return TranslationError.ExceptionThrown;
|
|
426
426
|
}
|
|
427
427
|
|
|
428
428
|
var napi_error: c.napi_value = undefined;
|
|
429
|
-
if (c.napi_create_error(env, null, napi_string, &napi_error) != .napi_ok) {
|
|
429
|
+
if (c.napi_create_error(env, null, napi_string, &napi_error) != c.napi_ok) {
|
|
430
430
|
return TranslationError.ExceptionThrown;
|
|
431
431
|
}
|
|
432
432
|
|
|
@@ -442,17 +442,17 @@ pub fn call_function(
|
|
|
442
442
|
) !void {
|
|
443
443
|
const result = c.napi_call_function(env, this, callback, argc, argv, null);
|
|
444
444
|
switch (result) {
|
|
445
|
-
.napi_ok => {},
|
|
445
|
+
c.napi_ok => {},
|
|
446
446
|
// the user's callback may throw a JS exception or call other functions that do so. We
|
|
447
447
|
// therefore don't throw another error.
|
|
448
|
-
.napi_pending_exception => {},
|
|
448
|
+
c.napi_pending_exception => {},
|
|
449
449
|
else => return throw(env, "Failed to invoke results callback."),
|
|
450
450
|
}
|
|
451
451
|
}
|
|
452
452
|
|
|
453
453
|
pub fn scope(env: c.napi_env, comptime error_message: [:0]const u8) !c.napi_value {
|
|
454
454
|
var result: c.napi_value = undefined;
|
|
455
|
-
if (c.napi_get_global(env, &result) != .napi_ok) {
|
|
455
|
+
if (c.napi_get_global(env, &result) != c.napi_ok) {
|
|
456
456
|
return throw(env, error_message);
|
|
457
457
|
}
|
|
458
458
|
|
|
@@ -465,7 +465,7 @@ pub fn reference_value(
|
|
|
465
465
|
comptime error_message: [:0]const u8,
|
|
466
466
|
) !c.napi_value {
|
|
467
467
|
var result: c.napi_value = undefined;
|
|
468
|
-
if (c.napi_get_reference_value(env, callback_reference, &result) != .napi_ok) {
|
|
468
|
+
if (c.napi_get_reference_value(env, callback_reference, &result) != c.napi_ok) {
|
|
469
469
|
return throw(env, error_message);
|
|
470
470
|
}
|
|
471
471
|
|