tigerbeetle-node 0.16.78 → 0.17.0

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/index.ts CHANGED
@@ -2,8 +2,8 @@ export * from './bindings'
2
2
  import {
3
3
  Account,
4
4
  Transfer,
5
- CreateAccountsError,
6
- CreateTransfersError,
5
+ CreateAccountResult,
6
+ CreateTransferResult,
7
7
  Operation,
8
8
  AccountFilter,
9
9
  AccountBalance,
@@ -57,14 +57,54 @@ export type Context = object // tb_client
57
57
  export type AccountID = bigint // u128
58
58
  export type TransferID = bigint // u128
59
59
  export type Event = Account | Transfer | AccountID | TransferID | AccountFilter | QueryFilter
60
- export type Result = CreateAccountsError | CreateTransfersError | Account | Transfer | AccountBalance
60
+ export type Result = CreateAccountResult | CreateTransferResult | Account | Transfer | AccountBalance
61
61
  export type ResultCallback = (error: Error | null, results: Result[] | null) => void
62
62
 
63
63
  export const amount_max: bigint = (2n ** 128n) - 1n
64
64
 
65
+ // Error codes returned by the client.
66
+ export const ErrorCodes = {
67
+ ERR_CLIENT_CLOSED: 'ERR_CLIENT_CLOSED',
68
+ ERR_CLIENT_EVICTED: 'ERR_CLIENT_EVICTED',
69
+ ERR_CLIENT_RELEASE_TOO_LOW: 'ERR_CLIENT_RELEASE_TOO_LOW',
70
+ ERR_CLIENT_RELEASE_TOO_HIGH: 'ERR_CLIENT_RELEASE_TOO_HIGH',
71
+ ERR_TOO_MUCH_DATA: 'ERR_TOO_MUCH_DATA',
72
+ } as const;
73
+
74
+ export type ErrorCodes = typeof ErrorCodes[keyof typeof ErrorCodes];
75
+
76
+ export class RequestError extends Error {
77
+ code: ErrorCodes;
78
+
79
+ constructor(code: ErrorCodes) {
80
+ super(RequestError.errorMessage(code));
81
+ this.name = 'RequestError';
82
+ this.code = code;
83
+ }
84
+
85
+ static errorMessage(code: ErrorCodes): string {
86
+ switch (code) {
87
+ case ErrorCodes.ERR_CLIENT_CLOSED:
88
+ return 'Client was closed.'
89
+ case ErrorCodes.ERR_CLIENT_EVICTED:
90
+ return 'Client was evicted.'
91
+ case ErrorCodes.ERR_CLIENT_RELEASE_TOO_LOW:
92
+ return 'Client was evicted: release too old.'
93
+ case ErrorCodes.ERR_CLIENT_RELEASE_TOO_HIGH:
94
+ return 'Client was evicted: release too new.'
95
+ case ErrorCodes.ERR_TOO_MUCH_DATA:
96
+ return 'Too much data was sent or requested in this batch.'
97
+ default:
98
+ throw new Error("Unknown error code.")
99
+ }
100
+ }
101
+
102
+ }
103
+
65
104
  interface BindingInitArgs {
66
105
  cluster_id: bigint, // u128
67
106
  replica_addresses: Buffer,
107
+ request_error_class: typeof RequestError,
68
108
  }
69
109
 
70
110
  interface Binding {
@@ -79,8 +119,8 @@ export interface ClientInitArgs {
79
119
  }
80
120
 
81
121
  export interface Client {
82
- createAccounts: (batch: Account[]) => Promise<CreateAccountsError[]>
83
- createTransfers: (batch: Transfer[]) => Promise<CreateTransfersError[]>
122
+ createAccounts: (batch: Account[]) => Promise<CreateAccountResult[]>
123
+ createTransfers: (batch: Transfer[]) => Promise<CreateTransferResult[]>
84
124
  lookupAccounts: (batch: AccountID[]) => Promise<Account[]>
85
125
  lookupTransfers: (batch: TransferID[]) => Promise<Transfer[]>
86
126
  getAccountTransfers: (filter: AccountFilter) => Promise<Transfer[]>
@@ -96,6 +136,7 @@ export function createClient (args: ClientInitArgs): Client {
96
136
  let context: Context | null = binding.init({
97
137
  cluster_id: args.cluster_id,
98
138
  replica_addresses: Buffer.from(args.replica_addresses.join(',')),
139
+ request_error_class: RequestError,
99
140
  })
100
141
 
101
142
  const destroy = () => {
@@ -106,7 +147,8 @@ export function createClient (args: ClientInitArgs): Client {
106
147
  const request = <T extends Result>(operation: Operation, batch: Event[]): Promise<T[]> => {
107
148
  return new Promise((resolve, reject) => {
108
149
  try {
109
- if (!context) throw new Error('Client was shutdown.');
150
+ if (!context) throw new RequestError(ErrorCodes.ERR_CLIENT_CLOSED);
151
+
110
152
  binding.submit(context, operation, batch, (error, result) => {
111
153
  if (error) {
112
154
  reject(error)
@@ -165,15 +207,20 @@ export function id(): bigint {
165
207
  // Increment the u80 in idLastBuffer using carry arithmetic on u32s (as JS doesn't have fast u64).
166
208
  const littleEndian = true
167
209
  const randomLo32 = idLastBuffer.getUint32(0, littleEndian) + 1
168
- const randomHi32 = idLastBuffer.getUint32(4, littleEndian) + (randomLo32 > 0xFFFFFFFF ? 1 : 0)
169
- const randomHi16 = idLastBuffer.getUint16(8, littleEndian) + (randomHi32 > 0xFFFFFFFF ? 1 : 0)
210
+ const randomHi32 = idLastBuffer.getUint32(4, littleEndian) + (randomLo32 > 0xFFFF_FFFF ? 1 : 0)
211
+ const randomHi16 = idLastBuffer.getUint16(8, littleEndian) + (randomHi32 > 0xFFFF_FFFF ? 1 : 0)
170
212
  if (randomHi16 > 0xFFFF) {
171
- throw new Error('random bits overflow on monotonic increment')
213
+ timestamp += 1
214
+ idLastTimestamp = timestamp
215
+
216
+ if (timestamp === 0x1_0000_0000_0000) {
217
+ throw new Error('timestamp overflow on monotonic increment')
218
+ }
172
219
  }
173
220
 
174
221
  // Store the incremented random monotonic and the timestamp into the buffer.
175
- idLastBuffer.setUint32(0, randomLo32 & 0xFFFFFFFF, littleEndian)
176
- idLastBuffer.setUint32(4, randomHi32 & 0xFFFFFFFF, littleEndian)
222
+ idLastBuffer.setUint32(0, randomLo32 & 0xFFFF_FFFF, littleEndian)
223
+ idLastBuffer.setUint32(4, randomHi32 & 0xFFFF_FFFF, littleEndian)
177
224
  idLastBuffer.setUint16(8, randomHi16, littleEndian) // No need to mask since checked above.
178
225
  idLastBuffer.setUint16(10, timestamp & 0xFFFF, littleEndian) // timestamp lo.
179
226
  idLastBuffer.setUint32(12, (timestamp / 0x10000) | 0, littleEndian) // timestamp hi.
package/src/test.ts CHANGED
@@ -4,8 +4,8 @@ import {
4
4
  Account,
5
5
  Transfer,
6
6
  TransferFlags,
7
- CreateAccountError,
8
- CreateTransferError,
7
+ CreateAccountStatus,
8
+ CreateTransferStatus,
9
9
  AccountFilter,
10
10
  AccountFilterFlags,
11
11
  AccountFlags,
@@ -13,6 +13,8 @@ import {
13
13
  id,
14
14
  QueryFilter,
15
15
  QueryFilterFlags,
16
+ ErrorCodes,
17
+ RequestError,
16
18
  } from '.'
17
19
 
18
20
  const client = createClient({
@@ -88,23 +90,27 @@ test('range check `code` on Account to be u16', async (): Promise<void> => {
88
90
  })
89
91
 
90
92
  test('can create accounts', async (): Promise<void> => {
91
- const errors = await client.createAccounts([accountA])
92
- assert.deepStrictEqual(errors, [])
93
+ const account_results = await client.createAccounts([accountA])
94
+ assert.deepStrictEqual(account_results.length, 1)
95
+ assert.ok(account_results[0].timestamp > 0)
96
+ assert.deepStrictEqual(account_results[0].status, CreateAccountStatus.created)
93
97
  })
94
98
 
95
99
  test('can return error on account', async (): Promise<void> => {
96
- const errors = await client.createAccounts([accountA, accountB])
97
-
98
- assert.strictEqual(errors.length, 1)
99
- assert.deepStrictEqual(errors[0], { index: 0, result: CreateAccountError.exists })
100
+ const account_results = await client.createAccounts([accountA, accountB])
101
+ assert.deepStrictEqual(account_results.length, 2)
102
+ assert.ok(account_results[0].timestamp > 0)
103
+ assert.deepStrictEqual(account_results[0].status, CreateAccountStatus.exists)
104
+ assert.ok(account_results[1].timestamp > 0)
105
+ assert.deepStrictEqual(account_results[1].status, CreateAccountStatus.created)
100
106
  })
101
107
 
102
108
  test('error if timestamp is not set to 0n on account', async (): Promise<void> => {
103
109
  const account = { ...accountA, timestamp: 2n, id: 3n }
104
- const errors = await client.createAccounts([account])
105
-
106
- assert.strictEqual(errors.length, 1)
107
- assert.deepStrictEqual(errors[0], { index: 0, result: CreateAccountError.timestamp_must_be_zero })
110
+ const account_results = await client.createAccounts([account])
111
+ assert.deepStrictEqual(account_results.length, 1)
112
+ assert.ok(account_results[0].timestamp > 0)
113
+ assert.deepStrictEqual(account_results[0].status, CreateAccountStatus.timestamp_must_be_zero)
108
114
  })
109
115
 
110
116
  test('batch max size', async (): Promise<void> => {
@@ -127,13 +133,11 @@ test('batch max size', async (): Promise<void> => {
127
133
  timestamp: 0n,
128
134
  });
129
135
  }
130
-
131
- try {
132
- const results = await client.createTransfers(transfers);
133
- assert.fail();
134
- } catch (error) {
135
- assert.strictEqual(error.message, "Too much data provided on this batch.");
136
- }
136
+ assert.rejects(async() => await client.createTransfers(transfers), (err) => {
137
+ assert.ok(err instanceof RequestError)
138
+ assert.strictEqual(err.code, ErrorCodes.ERR_TOO_MUCH_DATA)
139
+ return true
140
+ })
137
141
  })
138
142
 
139
143
  test('can lookup accounts', async (): Promise<void> => {
@@ -186,8 +190,10 @@ test('can create a transfer', async (): Promise<void> => {
186
190
  timestamp: 0n, // this will be set correctly by the TigerBeetle server
187
191
  }
188
192
 
189
- const errors = await client.createTransfers([transfer])
190
- assert.deepStrictEqual(errors, [])
193
+ const transfers_results = await client.createTransfers([transfer])
194
+ assert.deepStrictEqual(transfers_results.length, 1)
195
+ assert.ok(transfers_results[0].timestamp > 0)
196
+ assert.deepStrictEqual(transfers_results[0].status, CreateTransferStatus.created)
191
197
 
192
198
  const accounts = await client.lookupAccounts([accountA.id, accountB.id])
193
199
  assert.strictEqual(accounts.length, 2)
@@ -221,8 +227,10 @@ test('can create a two-phase transfer', async (): Promise<void> => {
221
227
  timestamp: 0n, // this will be set correctly by the TigerBeetle server
222
228
  }
223
229
 
224
- const errors = await client.createTransfers([transfer])
225
- assert.deepStrictEqual(errors, [])
230
+ const transfers_results = await client.createTransfers([transfer])
231
+ assert.deepStrictEqual(transfers_results.length, 1)
232
+ assert.ok(transfers_results[0].timestamp > 0)
233
+ assert.deepStrictEqual(transfers_results[0].status, CreateTransferStatus.created)
226
234
 
227
235
  const accounts = await client.lookupAccounts([accountA.id, accountB.id])
228
236
  assert.strictEqual(accounts.length, 2)
@@ -272,8 +280,10 @@ test('can post a two-phase transfer', async (): Promise<void> => {
272
280
  timestamp: 0n, // this will be set correctly by the TigerBeetle server
273
281
  }
274
282
 
275
- const errors = await client.createTransfers([commit])
276
- assert.deepStrictEqual(errors, [])
283
+ const transfers_results = await client.createTransfers([commit])
284
+ assert.deepStrictEqual(transfers_results.length, 1)
285
+ assert.ok(transfers_results[0].timestamp > 0)
286
+ assert.deepStrictEqual(transfers_results[0].status, CreateTransferStatus.created)
277
287
 
278
288
  const accounts = await client.lookupAccounts([accountA.id, accountB.id])
279
289
  assert.strictEqual(accounts.length, 2)
@@ -305,8 +315,10 @@ test('can reject a two-phase transfer', async (): Promise<void> => {
305
315
  flags: TransferFlags.pending,
306
316
  timestamp: 0n, // this will be set correctly by the TigerBeetle server
307
317
  }
308
- const transferErrors = await client.createTransfers([transfer])
309
- assert.deepStrictEqual(transferErrors, [])
318
+ let transfers_results = await client.createTransfers([transfer])
319
+ assert.deepStrictEqual(transfers_results.length, 1)
320
+ assert.ok(transfers_results[0].timestamp > 0)
321
+ assert.deepStrictEqual(transfers_results[0].status, CreateTransferStatus.created)
310
322
 
311
323
  // send in the reject
312
324
  const reject: Transfer = {
@@ -325,8 +337,10 @@ test('can reject a two-phase transfer', async (): Promise<void> => {
325
337
  timestamp: 0n, // this will be set correctly by the TigerBeetle server
326
338
  }
327
339
 
328
- const errors = await client.createTransfers([reject])
329
- assert.deepStrictEqual(errors, [])
340
+ transfers_results = await client.createTransfers([reject])
341
+ assert.deepStrictEqual(transfers_results.length, 1)
342
+ assert.ok(transfers_results[0].timestamp > 0)
343
+ assert.deepStrictEqual(transfers_results[0].status, CreateTransferStatus.created)
330
344
 
331
345
  const accounts = await client.lookupAccounts([accountA.id, accountB.id])
332
346
  assert.strictEqual(accounts.length, 2)
@@ -375,10 +389,12 @@ test('can link transfers', async (): Promise<void> => {
375
389
  timestamp: 0n, // will be set correctly by the TigerBeetle server
376
390
  }
377
391
 
378
- const errors = await client.createTransfers([transfer1, transfer2])
379
- assert.strictEqual(errors.length, 2)
380
- assert.deepStrictEqual(errors[0], { index: 0, result: CreateTransferError.linked_event_failed })
381
- assert.deepStrictEqual(errors[1], { index: 1, result: CreateTransferError.exists_with_different_flags })
392
+ const transfers_results = await client.createTransfers([transfer1, transfer2])
393
+ assert.deepStrictEqual(transfers_results.length, 2)
394
+ assert.ok(transfers_results[0].timestamp > 0)
395
+ assert.deepStrictEqual(transfers_results[0].status, CreateTransferStatus.linked_event_failed)
396
+ assert.ok(transfers_results[1].timestamp > 0)
397
+ assert.deepStrictEqual(transfers_results[1].status, CreateTransferStatus.exists_with_different_flags)
382
398
 
383
399
  const accounts = await client.lookupAccounts([accountA.id, accountB.id])
384
400
  assert.strictEqual(accounts.length, 2)
@@ -410,8 +426,10 @@ test('cannot void an expired transfer', async (): Promise<void> => {
410
426
  flags: TransferFlags.pending,
411
427
  timestamp: 0n, // this will be set correctly by the TigerBeetle server
412
428
  }
413
- const transferErrors = await client.createTransfers([transfer])
414
- assert.deepStrictEqual(transferErrors, [])
429
+ let transfers_results = await client.createTransfers([transfer])
430
+ assert.deepStrictEqual(transfers_results.length, 1)
431
+ assert.ok(transfers_results[0].timestamp > 0)
432
+ assert.deepStrictEqual(transfers_results[0].status, CreateTransferStatus.created)
415
433
 
416
434
  var accounts = await client.lookupAccounts([accountA.id, accountB.id])
417
435
  assert.strictEqual(accounts.length, 2)
@@ -462,9 +480,10 @@ test('cannot void an expired transfer', async (): Promise<void> => {
462
480
  timestamp: 0n, // this will be set correctly by the TigerBeetle server
463
481
  }
464
482
 
465
- const errors = await client.createTransfers([reject])
466
- assert.strictEqual(errors.length, 1)
467
- assert.deepStrictEqual(errors[0], { index: 0, result: CreateTransferError.pending_transfer_expired })
483
+ transfers_results = await client.createTransfers([reject])
484
+ assert.deepStrictEqual(transfers_results.length, 1)
485
+ assert.ok(transfers_results[0].timestamp > 0)
486
+ assert.deepStrictEqual(transfers_results[0].status, CreateTransferStatus.pending_transfer_expired)
468
487
  })
469
488
 
470
489
  test('can close accounts', async (): Promise<void> => {
@@ -483,8 +502,10 @@ test('can close accounts', async (): Promise<void> => {
483
502
  flags: TransferFlags.closing_debit | TransferFlags.closing_credit | TransferFlags.pending,
484
503
  timestamp: 0n, // will be set correctly by the TigerBeetle server
485
504
  }
486
- let errors = await client.createTransfers([closing_transfer])
487
- assert.strictEqual(errors.length, 0)
505
+ let transfers_results = await client.createTransfers([closing_transfer])
506
+ assert.deepStrictEqual(transfers_results.length, 1)
507
+ assert.ok(transfers_results[0].timestamp > 0)
508
+ assert.deepStrictEqual(transfers_results[0].status, CreateTransferStatus.created)
488
509
 
489
510
  let accounts = await client.lookupAccounts([accountA.id, accountB.id])
490
511
  assert.strictEqual(accounts.length, 2)
@@ -510,8 +531,10 @@ test('can close accounts', async (): Promise<void> => {
510
531
  timestamp: 0n, // will be set correctly by the TigerBeetle server
511
532
  }
512
533
 
513
- errors = await client.createTransfers([voiding_transfer])
514
- assert.strictEqual(errors.length, 0)
534
+ transfers_results = await client.createTransfers([voiding_transfer])
535
+ assert.deepStrictEqual(transfers_results.length, 1)
536
+ assert.ok(transfers_results[0].timestamp > 0)
537
+ assert.deepStrictEqual(transfers_results[0].status, CreateTransferStatus.created)
515
538
 
516
539
  accounts = await client.lookupAccounts([accountA.id, accountB.id])
517
540
  assert.strictEqual(accounts.length, 2)
@@ -538,8 +561,10 @@ test('can get account transfers', async (): Promise<void> => {
538
561
  flags: AccountFlags.history,
539
562
  timestamp: 0n
540
563
  }
541
- const account_errors = await client.createAccounts([accountC])
542
- assert.deepStrictEqual(account_errors, [])
564
+ const account_results = await client.createAccounts([accountC])
565
+ assert.deepStrictEqual(account_results.length, 1)
566
+ assert.ok(account_results[0].timestamp > 0)
567
+ assert.deepStrictEqual(account_results[0].status, CreateAccountStatus.created)
543
568
 
544
569
  var transfers_created : Transfer[] = [];
545
570
  // Create transfers where the new account is either the debit or credit account:
@@ -561,8 +586,12 @@ test('can get account transfers', async (): Promise<void> => {
561
586
  });
562
587
  }
563
588
 
564
- const transfers_created_result = await client.createTransfers(transfers_created)
565
- assert.deepStrictEqual(transfers_created_result, [])
589
+ const transfers_results = await client.createTransfers(transfers_created)
590
+ assert.deepStrictEqual(transfers_results.length, transfers_created.length)
591
+ for (const result of transfers_results) {
592
+ assert.ok(result.timestamp > 0)
593
+ assert.deepStrictEqual(result.status, CreateTransferStatus.created)
594
+ }
566
595
 
567
596
  // Query all transfers for accountC:
568
597
  var filter: AccountFilter = {
@@ -868,6 +897,29 @@ test('can get account transfers', async (): Promise<void> => {
868
897
  assert.deepStrictEqual((await client.getAccountTransfers(filter)), [])
869
898
  assert.deepStrictEqual((await client.getAccountBalances(filter)), [])
870
899
 
900
+ // TooMuchData
901
+ filter = {
902
+ account_id: accountC.id,
903
+ user_data_128: 0n,
904
+ user_data_64: 0n,
905
+ user_data_32: 0,
906
+ code: 0,
907
+ timestamp_min: 0n,
908
+ timestamp_max: 0n,
909
+ limit: 10_000,
910
+ flags: AccountFilterFlags.credits | AccountFilterFlags.debits,
911
+ }
912
+ assert.rejects(async() => await client.getAccountTransfers(filter), (err) => {
913
+ assert.ok(err instanceof RequestError)
914
+ assert.strictEqual(err.code, ErrorCodes.ERR_TOO_MUCH_DATA)
915
+ return true
916
+ })
917
+ assert.rejects(async() => await client.getAccountBalances(filter), (err) => {
918
+ assert.ok(err instanceof RequestError)
919
+ assert.strictEqual(err.code, ErrorCodes.ERR_TOO_MUCH_DATA)
920
+ return true
921
+ })
922
+
871
923
  // Empty flags:
872
924
  filter = {
873
925
  account_id: accountC.id,
@@ -922,8 +974,12 @@ test('can query accounts', async (): Promise<void> => {
922
974
  })
923
975
  }
924
976
 
925
- const create_accounts_result = await client.createAccounts(accounts)
926
- assert.deepStrictEqual(create_accounts_result, [])
977
+ const account_results = await client.createAccounts(accounts)
978
+ assert.deepStrictEqual(account_results.length, accounts.length)
979
+ for (const result of account_results) {
980
+ assert.ok(result.timestamp > 0)
981
+ assert.deepStrictEqual(result.status, CreateAccountStatus.created)
982
+ }
927
983
  }
928
984
 
929
985
  {
@@ -1094,8 +1150,10 @@ test('can query transfers', async (): Promise<void> => {
1094
1150
  flags: AccountFlags.none,
1095
1151
  timestamp: 0n
1096
1152
  }
1097
- const create_accounts_result = await client.createAccounts([account])
1098
- assert.deepStrictEqual(create_accounts_result, [])
1153
+ const account_results = await client.createAccounts([account])
1154
+ assert.deepStrictEqual(account_results.length, 1)
1155
+ assert.ok(account_results[0].timestamp > 0)
1156
+ assert.deepStrictEqual(account_results[0].status, CreateAccountStatus.created)
1099
1157
 
1100
1158
  var transfers_created : Transfer[] = [];
1101
1159
  // Create transfers:
@@ -1117,8 +1175,12 @@ test('can query transfers', async (): Promise<void> => {
1117
1175
  })
1118
1176
  }
1119
1177
 
1120
- const create_transfers_result = await client.createTransfers(transfers_created)
1121
- assert.deepStrictEqual(create_transfers_result, [])
1178
+ const transfers_results = await client.createTransfers(transfers_created)
1179
+ assert.deepStrictEqual(transfers_results.length, transfers_created.length)
1180
+ for (const result of transfers_results) {
1181
+ assert.ok(result.timestamp > 0)
1182
+ assert.deepStrictEqual(result.status, CreateTransferStatus.created)
1183
+ }
1122
1184
  }
1123
1185
 
1124
1186
  {
@@ -1333,6 +1395,29 @@ test('query with invalid filter', async (): Promise<void> => {
1333
1395
  assert.deepStrictEqual((await client.queryAccounts(filter)), [])
1334
1396
  assert.deepStrictEqual((await client.queryTransfers(filter)), [])
1335
1397
 
1398
+ // TooMuchData
1399
+ filter = {
1400
+ user_data_128: 0n,
1401
+ user_data_64: 0n,
1402
+ user_data_32: 0,
1403
+ ledger: 0,
1404
+ code: 0,
1405
+ timestamp_min: 0n,
1406
+ timestamp_max: 0n,
1407
+ limit: 10_000,
1408
+ flags: QueryFilterFlags.none,
1409
+ }
1410
+ assert.rejects(async() => await client.queryAccounts(filter), (err) => {
1411
+ assert.ok(err instanceof RequestError)
1412
+ assert.strictEqual(err.code, ErrorCodes.ERR_TOO_MUCH_DATA)
1413
+ return true
1414
+ })
1415
+ assert.rejects(async() => await client.queryTransfers(filter), (err) => {
1416
+ assert.ok(err instanceof RequestError)
1417
+ assert.strictEqual(err.code, ErrorCodes.ERR_TOO_MUCH_DATA)
1418
+ return true
1419
+ })
1420
+
1336
1421
  // Invalid flags:
1337
1422
  filter = {
1338
1423
  user_data_128: 0n,
@@ -1365,8 +1450,10 @@ test('can import accounts and transfers', async (): Promise<void> => {
1365
1450
  flags: 0,
1366
1451
  timestamp: 0n // this will be set correctly by the TigerBeetle server
1367
1452
  }
1368
- let accountsErrors = await client.createAccounts([accountTmp])
1369
- assert.deepStrictEqual(accountsErrors, [])
1453
+ let account_results = await client.createAccounts([accountTmp])
1454
+ assert.deepStrictEqual(account_results.length, 1)
1455
+ assert.ok(account_results[0].timestamp > 0)
1456
+ assert.deepStrictEqual(account_results[0].status, CreateAccountStatus.created)
1370
1457
 
1371
1458
  let accountLookup = await client.lookupAccounts([accountTmp.id])
1372
1459
  assert.strictEqual(accountLookup.length, 1)
@@ -1406,8 +1493,12 @@ test('can import accounts and transfers', async (): Promise<void> => {
1406
1493
  flags: AccountFlags.imported,
1407
1494
  timestamp: timestampMax + 2n // user-defined timestamp
1408
1495
  }
1409
- accountsErrors = await client.createAccounts([accountA, accountB])
1410
- assert.deepStrictEqual(accountsErrors, [])
1496
+ account_results = await client.createAccounts([accountA, accountB])
1497
+ assert.deepStrictEqual(account_results.length, 2)
1498
+ assert.ok(account_results[0].timestamp > 0)
1499
+ assert.deepStrictEqual(account_results[0].status, CreateAccountStatus.created)
1500
+ assert.ok(account_results[1].timestamp > 0)
1501
+ assert.deepStrictEqual(account_results[1].status, CreateAccountStatus.created)
1411
1502
 
1412
1503
  accountLookup = await client.lookupAccounts([accountA.id, accountB.id])
1413
1504
  assert.strictEqual(accountLookup.length, 2)
@@ -1430,8 +1521,10 @@ test('can import accounts and transfers', async (): Promise<void> => {
1430
1521
  timestamp: timestampMax + 3n, // user-defined timestamp.
1431
1522
  }
1432
1523
 
1433
- const errors = await client.createTransfers([transfer])
1434
- assert.deepStrictEqual(errors, [])
1524
+ const transfers_results = await client.createTransfers([transfer])
1525
+ assert.deepStrictEqual(transfers_results.length, 1)
1526
+ assert.ok(transfers_results[0].timestamp > 0)
1527
+ assert.deepStrictEqual(transfers_results[0].status, CreateTransferStatus.created)
1435
1528
 
1436
1529
  const transfers = await client.lookupTransfers([transfer.id])
1437
1530
  assert.strictEqual(transfers.length, 1)
@@ -1439,13 +1532,13 @@ test('can import accounts and transfers', async (): Promise<void> => {
1439
1532
  })
1440
1533
 
1441
1534
  test('accept zero-length create_accounts', async (): Promise<void> => {
1442
- const errors = await client.createAccounts([])
1443
- assert.deepStrictEqual(errors, [])
1535
+ const account_results = await client.createAccounts([])
1536
+ assert.deepStrictEqual(account_results.length, 0)
1444
1537
  })
1445
1538
 
1446
1539
  test('accept zero-length create_transfers', async (): Promise<void> => {
1447
- const errors = await client.createTransfers([])
1448
- assert.deepStrictEqual(errors, [])
1540
+ const transfers_results = await client.createTransfers([])
1541
+ assert.deepStrictEqual(transfers_results.length, 0)
1449
1542
  })
1450
1543
 
1451
1544
  test('accept zero-length lookup_accounts', async (): Promise<void> => {
@@ -1462,13 +1555,11 @@ test("destroy client in-flight", async (): Promise<void> => {
1462
1555
  // Non-existing cluster.
1463
1556
  const client = createClient({ cluster_id: 92n, replica_addresses: ["99"] });
1464
1557
  setTimeout(() => client.destroy(), 30);
1465
- try {
1466
- await client.lookupAccounts([0n]);
1467
- } catch (error) {
1468
- assert.strictEqual(error.message, "Client was shutdown.");
1469
- return;
1470
- }
1471
- throw "expected an error";
1558
+ assert.rejects(async () => await client.lookupAccounts([0n]), (err) => {
1559
+ assert.ok(err instanceof RequestError)
1560
+ assert.strictEqual(err.code, ErrorCodes.ERR_CLIENT_CLOSED)
1561
+ return true
1562
+ })
1472
1563
  });
1473
1564
 
1474
1565
  async function main () {