tigerbeetle-node 0.14.178 → 0.14.180
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 +33 -4
- package/dist/bin/aarch64-linux-gnu/client.node +0 -0
- package/dist/bin/aarch64-linux-musl/client.node +0 -0
- package/dist/bin/aarch64-macos/client.node +0 -0
- package/dist/bin/x86_64-linux-gnu/client.node +0 -0
- package/dist/bin/x86_64-linux-musl/client.node +0 -0
- package/dist/bin/x86_64-macos/client.node +0 -0
- package/dist/bin/x86_64-windows/client.node +0 -0
- package/dist/bindings.d.ts +13 -4
- package/dist/bindings.js +10 -8
- package/dist/bindings.js.map +1 -1
- package/dist/index.d.ts +6 -4
- package/dist/index.js +31 -1
- package/dist/index.js.map +1 -1
- package/dist/test.js +106 -42
- package/dist/test.js.map +1 -1
- package/package.json +1 -1
- package/src/bindings.ts +50 -12
- package/src/index.ts +50 -4
- package/src/node.zig +17 -12
- package/src/test.ts +139 -48
package/src/bindings.ts
CHANGED
|
@@ -24,6 +24,11 @@ export enum AccountFlags {
|
|
|
24
24
|
* See [credits_must_not_exceed_debits](https://docs.tigerbeetle.com/reference/accounts#flagscredits_must_not_exceed_debits)
|
|
25
25
|
*/
|
|
26
26
|
credits_must_not_exceed_debits = (1 << 2),
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* See [history](https://docs.tigerbeetle.com/reference/accounts#flagshistory)
|
|
30
|
+
*/
|
|
31
|
+
history = (1 << 3),
|
|
27
32
|
}
|
|
28
33
|
|
|
29
34
|
|
|
@@ -66,23 +71,23 @@ export enum TransferFlags {
|
|
|
66
71
|
|
|
67
72
|
|
|
68
73
|
/**
|
|
69
|
-
* See [
|
|
74
|
+
* See [AccountFilterFlags](https://docs.tigerbeetle.com/reference/account_filter#flags)
|
|
70
75
|
*/
|
|
71
|
-
export enum
|
|
76
|
+
export enum AccountFilterFlags {
|
|
72
77
|
none = 0,
|
|
73
78
|
|
|
74
79
|
/**
|
|
75
|
-
* See [debits](https://docs.tigerbeetle.com/reference/
|
|
80
|
+
* See [debits](https://docs.tigerbeetle.com/reference/account_filter#flagsdebits)
|
|
76
81
|
*/
|
|
77
82
|
debits = (1 << 0),
|
|
78
83
|
|
|
79
84
|
/**
|
|
80
|
-
* See [credits](https://docs.tigerbeetle.com/reference/
|
|
85
|
+
* See [credits](https://docs.tigerbeetle.com/reference/account_filter#flagscredits)
|
|
81
86
|
*/
|
|
82
87
|
credits = (1 << 1),
|
|
83
88
|
|
|
84
89
|
/**
|
|
85
|
-
* See [reversed](https://docs.tigerbeetle.com/reference/
|
|
90
|
+
* See [reversed](https://docs.tigerbeetle.com/reference/account_filter#flagsreversed)
|
|
86
91
|
*/
|
|
87
92
|
reversed = (1 << 2),
|
|
88
93
|
}
|
|
@@ -647,41 +652,74 @@ export type CreateTransfersError = {
|
|
|
647
652
|
|
|
648
653
|
|
|
649
654
|
/**
|
|
650
|
-
* See [
|
|
655
|
+
* See [AccountFilter](https://docs.tigerbeetle.com/reference/account_filter#)
|
|
651
656
|
*/
|
|
652
|
-
export type
|
|
657
|
+
export type AccountFilter = {
|
|
653
658
|
|
|
654
659
|
/**
|
|
655
|
-
* See [account_id](https://docs.tigerbeetle.com/reference/
|
|
660
|
+
* See [account_id](https://docs.tigerbeetle.com/reference/account_filter#account_id)
|
|
656
661
|
*/
|
|
657
662
|
account_id: bigint
|
|
658
663
|
|
|
659
664
|
/**
|
|
660
|
-
* See [timestamp_min](https://docs.tigerbeetle.com/reference/
|
|
665
|
+
* See [timestamp_min](https://docs.tigerbeetle.com/reference/account_filter#timestamp_min)
|
|
661
666
|
*/
|
|
662
667
|
timestamp_min: bigint
|
|
663
668
|
|
|
664
669
|
/**
|
|
665
|
-
* See [timestamp_max](https://docs.tigerbeetle.com/reference/
|
|
670
|
+
* See [timestamp_max](https://docs.tigerbeetle.com/reference/account_filter#timestamp_max)
|
|
666
671
|
*/
|
|
667
672
|
timestamp_max: bigint
|
|
668
673
|
|
|
669
674
|
/**
|
|
670
|
-
* See [limit](https://docs.tigerbeetle.com/reference/
|
|
675
|
+
* See [limit](https://docs.tigerbeetle.com/reference/account_filter#limit)
|
|
671
676
|
*/
|
|
672
677
|
limit: number
|
|
673
678
|
|
|
674
679
|
/**
|
|
675
|
-
* See [flags](https://docs.tigerbeetle.com/reference/
|
|
680
|
+
* See [flags](https://docs.tigerbeetle.com/reference/account_filter#flags)
|
|
676
681
|
*/
|
|
677
682
|
flags: number
|
|
678
683
|
}
|
|
679
684
|
|
|
685
|
+
|
|
686
|
+
/**
|
|
687
|
+
* See [AccountBalance](https://docs.tigerbeetle.com/reference/account_balances#)
|
|
688
|
+
*/
|
|
689
|
+
export type AccountBalance = {
|
|
690
|
+
|
|
691
|
+
/**
|
|
692
|
+
* See [debits_pending](https://docs.tigerbeetle.com/reference/account_balances#debits_pending)
|
|
693
|
+
*/
|
|
694
|
+
debits_pending: bigint
|
|
695
|
+
|
|
696
|
+
/**
|
|
697
|
+
* See [debits_posted](https://docs.tigerbeetle.com/reference/account_balances#debits_posted)
|
|
698
|
+
*/
|
|
699
|
+
debits_posted: bigint
|
|
700
|
+
|
|
701
|
+
/**
|
|
702
|
+
* See [credits_pending](https://docs.tigerbeetle.com/reference/account_balances#credits_pending)
|
|
703
|
+
*/
|
|
704
|
+
credits_pending: bigint
|
|
705
|
+
|
|
706
|
+
/**
|
|
707
|
+
* See [credits_posted](https://docs.tigerbeetle.com/reference/account_balances#credits_posted)
|
|
708
|
+
*/
|
|
709
|
+
credits_posted: bigint
|
|
710
|
+
|
|
711
|
+
/**
|
|
712
|
+
* See [timestamp](https://docs.tigerbeetle.com/reference/account_balances#timestamp)
|
|
713
|
+
*/
|
|
714
|
+
timestamp: bigint
|
|
715
|
+
}
|
|
716
|
+
|
|
680
717
|
export enum Operation {
|
|
681
718
|
create_accounts = 128,
|
|
682
719
|
create_transfers = 129,
|
|
683
720
|
lookup_accounts = 130,
|
|
684
721
|
lookup_transfers = 131,
|
|
685
722
|
get_account_transfers = 132,
|
|
723
|
+
get_account_history = 133,
|
|
686
724
|
}
|
|
687
725
|
|
package/src/index.ts
CHANGED
|
@@ -5,8 +5,10 @@ import {
|
|
|
5
5
|
CreateAccountsError,
|
|
6
6
|
CreateTransfersError,
|
|
7
7
|
Operation,
|
|
8
|
-
|
|
8
|
+
AccountFilter,
|
|
9
|
+
AccountBalance,
|
|
9
10
|
} from './bindings'
|
|
11
|
+
import { randomFillSync } from 'node:crypto'
|
|
10
12
|
|
|
11
13
|
const binding: Binding = (() => {
|
|
12
14
|
const { arch, platform } = process
|
|
@@ -66,8 +68,8 @@ const binding: Binding = (() => {
|
|
|
66
68
|
export type Context = object // tb_client
|
|
67
69
|
export type AccountID = bigint // u128
|
|
68
70
|
export type TransferID = bigint // u128
|
|
69
|
-
export type Event = Account | Transfer | AccountID | TransferID |
|
|
70
|
-
export type Result = CreateAccountsError | CreateTransfersError | Account | Transfer
|
|
71
|
+
export type Event = Account | Transfer | AccountID | TransferID | AccountFilter
|
|
72
|
+
export type Result = CreateAccountsError | CreateTransfersError | Account | Transfer | AccountBalance
|
|
71
73
|
export type ResultCallback = (error: Error | null, results: Result[] | null) => void
|
|
72
74
|
|
|
73
75
|
interface BindingInitArgs {
|
|
@@ -93,7 +95,8 @@ export interface Client {
|
|
|
93
95
|
createTransfers: (batch: Transfer[]) => Promise<CreateTransfersError[]>
|
|
94
96
|
lookupAccounts: (batch: AccountID[]) => Promise<Account[]>
|
|
95
97
|
lookupTransfers: (batch: TransferID[]) => Promise<Transfer[]>
|
|
96
|
-
getAccountTransfers: (filter:
|
|
98
|
+
getAccountTransfers: (filter: AccountFilter) => Promise<Transfer[]>
|
|
99
|
+
getAccountHistory: (filter: AccountFilter) => Promise<AccountBalance[]>
|
|
97
100
|
destroy: () => void
|
|
98
101
|
}
|
|
99
102
|
|
|
@@ -129,6 +132,49 @@ export function createClient (args: ClientInitArgs): Client {
|
|
|
129
132
|
lookupAccounts(batch) { return request(Operation.lookup_accounts, batch) },
|
|
130
133
|
lookupTransfers(batch) { return request(Operation.lookup_transfers, batch) },
|
|
131
134
|
getAccountTransfers(filter) { return request(Operation.get_account_transfers, [filter]) },
|
|
135
|
+
getAccountHistory(filter) { return request(Operation.get_account_history, [filter]) },
|
|
132
136
|
destroy() { binding.deinit(context) },
|
|
133
137
|
}
|
|
134
138
|
}
|
|
139
|
+
|
|
140
|
+
let idLastTimestamp = 0;
|
|
141
|
+
let idLastBuffer = new DataView(new ArrayBuffer(16));
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Generates a Universally Unique and Sortable Identifier as a u128 bigint.
|
|
145
|
+
*
|
|
146
|
+
* @remarks
|
|
147
|
+
* Based on {@link https://github.com/ulid/spec}, IDs returned are guaranteed to be monotonically
|
|
148
|
+
* increasing.
|
|
149
|
+
*/
|
|
150
|
+
export function id(): bigint {
|
|
151
|
+
// Ensure timestamp monotonically increases and generate a new random on each new timestamp.
|
|
152
|
+
let timestamp = Date.now()
|
|
153
|
+
if (timestamp <= idLastTimestamp) {
|
|
154
|
+
timestamp = idLastTimestamp
|
|
155
|
+
} else {
|
|
156
|
+
idLastTimestamp = timestamp
|
|
157
|
+
randomFillSync(idLastBuffer)
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// Increment the u80 in idLastBuffer using carry arithmetic on u32s (as JS doesn't have fast u64).
|
|
161
|
+
const littleEndian = true
|
|
162
|
+
const randomLo32 = idLastBuffer.getUint32(0, littleEndian) + 1
|
|
163
|
+
const randomHi32 = idLastBuffer.getUint32(4, littleEndian) + (randomLo32 > 0xFFFFFFFF ? 1 : 0)
|
|
164
|
+
const randomHi16 = idLastBuffer.getUint16(8, littleEndian) + (randomHi32 > 0xFFFFFFFF ? 1 : 0)
|
|
165
|
+
if (randomHi16 > 0xFFFF) {
|
|
166
|
+
throw new Error('random bits overflow on monotonic increment')
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// Store the incremented random monotonic and the timestamp into the buffer.
|
|
170
|
+
idLastBuffer.setUint32(0, randomLo32 & 0xFFFFFFFF, littleEndian)
|
|
171
|
+
idLastBuffer.setUint32(4, randomHi32 & 0xFFFFFFFF, littleEndian)
|
|
172
|
+
idLastBuffer.setUint16(8, randomHi16, littleEndian) // No need to mask since checked above.
|
|
173
|
+
idLastBuffer.setUint16(10, timestamp & 0xFFFF, littleEndian) // timestamp lo.
|
|
174
|
+
idLastBuffer.setUint32(12, (timestamp >>> 16) & 0xFFFFFFFF, littleEndian) // timestamp hi.
|
|
175
|
+
|
|
176
|
+
// Then return the buffer's contents as a little-endian u128 bigint.
|
|
177
|
+
const lo = idLastBuffer.getBigUint64(0, littleEndian)
|
|
178
|
+
const hi = idLastBuffer.getBigUint64(8, littleEndian)
|
|
179
|
+
return (hi << 64n) | lo
|
|
180
|
+
}
|
package/src/node.zig
CHANGED
|
@@ -15,8 +15,9 @@ const Transfer = tb.Transfer;
|
|
|
15
15
|
const TransferFlags = tb.TransferFlags;
|
|
16
16
|
const CreateAccountsResult = tb.CreateAccountsResult;
|
|
17
17
|
const CreateTransfersResult = tb.CreateTransfersResult;
|
|
18
|
-
const
|
|
19
|
-
const
|
|
18
|
+
const AccountFilter = tb.AccountFilter;
|
|
19
|
+
const AccountFilterFlags = tb.AccountFilterFlags;
|
|
20
|
+
const AccountBalance = tb.AccountBalance;
|
|
20
21
|
|
|
21
22
|
const Storage = @import("../../../storage.zig").Storage;
|
|
22
23
|
const StateMachine = @import("../../../state_machine.zig").StateMachineType(Storage, constants.state_machine_config);
|
|
@@ -367,7 +368,7 @@ fn decode_array(comptime Event: type, env: c.napi_env, array: c.napi_value, even
|
|
|
367
368
|
for (events, 0..) |*event, i| {
|
|
368
369
|
const object = try translate.array_element(env, array, @intCast(i));
|
|
369
370
|
switch (Event) {
|
|
370
|
-
Account, Transfer,
|
|
371
|
+
Account, Transfer, AccountFilter, AccountBalance => {
|
|
371
372
|
inline for (std.meta.fields(Event)) |field| {
|
|
372
373
|
const value: field.type = switch (@typeInfo(field.type)) {
|
|
373
374
|
.Struct => |info| @bitCast(try @field(
|
|
@@ -419,6 +420,8 @@ fn encode_array(comptime Result: type, env: c.napi_env, results: []const Result)
|
|
|
419
420
|
const FieldInt = switch (@typeInfo(field.type)) {
|
|
420
421
|
.Struct => |info| info.backing_integer.?,
|
|
421
422
|
.Enum => |info| info.tag_type,
|
|
423
|
+
// Arrays are only used for padding/reserved fields.
|
|
424
|
+
.Array => continue,
|
|
422
425
|
else => field.type,
|
|
423
426
|
};
|
|
424
427
|
|
|
@@ -474,9 +477,7 @@ fn BufferType(comptime op: Operation) type {
|
|
|
474
477
|
// Allocate enough bytes to hold memory for the Events and the Results.
|
|
475
478
|
const max_bytes = @max(
|
|
476
479
|
@sizeOf(Event) * count,
|
|
477
|
-
@sizeOf(Result) *
|
|
478
|
-
// Ad-hoc hack, event and result sizes are not the same size.
|
|
479
|
-
if (op == .get_account_transfers) 8190 else count,
|
|
480
|
+
@sizeOf(Result) * event_count(op, count),
|
|
480
481
|
);
|
|
481
482
|
if (@sizeOf(vsr.Header) + max_bytes > constants.message_size_max) {
|
|
482
483
|
return translate.throw(env, "Batch is larger than the maximum message size.");
|
|
@@ -496,9 +497,7 @@ fn BufferType(comptime op: Operation) type {
|
|
|
496
497
|
fn free(buffer: Buffer) void {
|
|
497
498
|
const max_bytes = @max(
|
|
498
499
|
@sizeOf(Event) * buffer.count,
|
|
499
|
-
@sizeOf(Result) *
|
|
500
|
-
//TODO(batiati): Refine the way we handle events with asymmetric results.
|
|
501
|
-
if (op == .get_account_transfers) 8190 else buffer.count,
|
|
500
|
+
@sizeOf(Result) * event_count(op, buffer.count),
|
|
502
501
|
);
|
|
503
502
|
const bytes: []align(max_align) u8 = @alignCast(buffer.ptr[0..max_bytes]);
|
|
504
503
|
allocator.free(bytes);
|
|
@@ -510,10 +509,16 @@ fn BufferType(comptime op: Operation) type {
|
|
|
510
509
|
}
|
|
511
510
|
|
|
512
511
|
fn results(buffer: Buffer) []Result {
|
|
513
|
-
const result_bytes = buffer.ptr[0 .. @sizeOf(Result) *
|
|
514
|
-
// Ad-hoc hack, event and result sizes are not the same size.
|
|
515
|
-
if (op == .get_account_transfers) 8190 else buffer.count];
|
|
512
|
+
const result_bytes = buffer.ptr[0 .. @sizeOf(Result) * event_count(op, buffer.count)];
|
|
516
513
|
return @alignCast(std.mem.bytesAsSlice(Result, result_bytes));
|
|
517
514
|
}
|
|
515
|
+
|
|
516
|
+
fn event_count(operation: Operation, count: usize) usize {
|
|
517
|
+
// TODO(batiati): Refine the way we handle events with asymmetric results.
|
|
518
|
+
return switch (operation) {
|
|
519
|
+
.get_account_transfers, .get_account_history => 8190,
|
|
520
|
+
else => count,
|
|
521
|
+
};
|
|
522
|
+
}
|
|
518
523
|
};
|
|
519
524
|
}
|