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/README.md +69 -70
- package/dist/benchmark.js +4 -4
- package/dist/benchmark.js.map +1 -1
- 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 -13
- package/dist/bindings.js +104 -104
- package/dist/bindings.js.map +1 -1
- package/dist/index.d.ts +17 -4
- package/dist/index.js +43 -7
- package/dist/index.js.map +1 -1
- package/dist/test.js +152 -66
- package/dist/test.js.map +1 -1
- package/package.json +1 -1
- package/src/benchmark.ts +4 -4
- package/src/bindings.ts +16 -16
- package/src/index.ts +58 -11
- package/src/test.ts +160 -69
- package/src/translate.zig +181 -47
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["export * from './bindings'\nimport {\n Account,\n Transfer,\n CreateAccountsError,\n CreateTransfersError,\n Operation,\n AccountFilter,\n AccountBalance,\n QueryFilter,\n} from './bindings'\nimport { randomFillSync } from 'node:crypto'\n\nconst binding: Binding = (() => {\n const { arch, platform } = process\n\n const archMap = {\n \"arm64\": \"aarch64\",\n \"x64\": \"x86_64\"\n }\n\n const platformMap = {\n \"linux\": \"linux\",\n \"darwin\": \"macos\",\n \"win32\" : \"windows\",\n }\n\n if (! (arch in archMap)) {\n throw new Error(`Unsupported arch: ${arch}`)\n }\n\n if (! (platform in platformMap)) {\n throw new Error(`Unsupported platform: ${platform}`)\n }\n\n let linuxABI = ''\n\n /**\n * We need to detect during runtime which libc we're running on to load the correct NAPI.\n * binary.\n */\n if (platform === 'linux') {\n const glibcVersionRuntime = (process.report.getReport() as any).header.glibcVersionRuntime\n if (glibcVersionRuntime) {\n linuxABI = '-gnu'\n } else {\n linuxABI = '-musl'\n }\n }\n\n const filename = `./bin/${archMap[arch as keyof typeof archMap]}-` +\n `${platformMap[platform as keyof typeof platformMap]}${linuxABI}/client.node`\n return require(filename)\n})()\n\nexport type Context = object // tb_client\nexport type AccountID = bigint // u128\nexport type TransferID = bigint // u128\nexport type Event = Account | Transfer | AccountID | TransferID | AccountFilter | QueryFilter\nexport type Result = CreateAccountsError | CreateTransfersError | Account | Transfer | AccountBalance\nexport type ResultCallback = (error: Error | null, results: Result[] | null) => void\n\nexport const amount_max: bigint = (2n ** 128n) - 1n\n\ninterface BindingInitArgs {\n cluster_id: bigint, // u128\n replica_addresses: Buffer,\n}\n\ninterface Binding {\n init: (args: BindingInitArgs) => Context\n submit: (context: Context, operation: Operation, batch: Event[], callback: ResultCallback) => void\n deinit: (context: Context) => void,\n}\n\nexport interface ClientInitArgs {\n cluster_id: bigint, // u128\n replica_addresses: Array<string | number>,\n}\n\nexport interface Client {\n createAccounts: (batch: Account[]) => Promise<CreateAccountsError[]>\n createTransfers: (batch: Transfer[]) => Promise<CreateTransfersError[]>\n lookupAccounts: (batch: AccountID[]) => Promise<Account[]>\n lookupTransfers: (batch: TransferID[]) => Promise<Transfer[]>\n getAccountTransfers: (filter: AccountFilter) => Promise<Transfer[]>\n getAccountBalances: (filter: AccountFilter) => Promise<AccountBalance[]>\n queryAccounts: (filter: QueryFilter) => Promise<Account[]>\n queryTransfers: (filter: QueryFilter) => Promise<Transfer[]>\n destroy: () => void\n}\n\nexport function createClient (args: ClientInitArgs): Client {\n // Context becomes null when `destroy` is called. After that point, further `request` Promises\n // throw a shutdown Error. This prevents tb_client calls from happening after tb_client_deinit().\n let context: Context | null = binding.init({\n cluster_id: args.cluster_id,\n replica_addresses: Buffer.from(args.replica_addresses.join(',')),\n })\n\n const destroy = () => {\n if (context) binding.deinit(context)\n context = null;\n }\n\n const request = <T extends Result>(operation: Operation, batch: Event[]): Promise<T[]> => {\n return new Promise((resolve, reject) => {\n try {\n if (!context) throw new Error('Client was shutdown.');\n binding.submit(context, operation, batch, (error, result) => {\n if (error) {\n reject(error)\n } else if (result) {\n resolve(result as T[])\n } else {\n throw new Error(\"UB: Binding invoked callback without error or result\")\n }\n })\n } catch (err) {\n reject(err)\n }\n })\n }\n\n return {\n createAccounts(batch) { return request(Operation.create_accounts, batch) },\n createTransfers(batch) { return request(Operation.create_transfers, batch) },\n lookupAccounts(batch) { return request(Operation.lookup_accounts, batch) },\n lookupTransfers(batch) { return request(Operation.lookup_transfers, batch) },\n getAccountTransfers(filter) { return request(Operation.get_account_transfers, [filter]) },\n getAccountBalances(filter) { return request(Operation.get_account_balances, [filter]) },\n queryAccounts(filter) { return request(Operation.query_accounts, [filter]) },\n queryTransfers(filter) { return request(Operation.query_transfers, [filter]) },\n destroy,\n }\n}\n\nlet idLastTimestamp = 0;\n\n// These are two references to the same buffer.\n// We only need the `Uint8Array` because in Node.js 24, but not earlier, `crypto.randomFillSync`\n// rejects `DataView` typed arguments.\nconst idLastBuffer = new DataView(new ArrayBuffer(16));\nconst idLastBufferArray = new Uint8Array(\n idLastBuffer.buffer, idLastBuffer.byteOffset, idLastBuffer.byteLength\n);\n\n/**\n * Generates a Universally Unique and Sortable Identifier as a u128 bigint.\n *\n * @remarks\n * Based on {@link https://github.com/ulid/spec}, IDs returned are guaranteed to be monotonically\n * increasing.\n */\nexport function id(): bigint {\n // Ensure timestamp monotonically increases and generate a new random on each new timestamp.\n let timestamp = Date.now()\n if (timestamp <= idLastTimestamp) {\n timestamp = idLastTimestamp\n } else {\n idLastTimestamp = timestamp\n randomFillSync(idLastBufferArray)\n }\n\n // Increment the u80 in idLastBuffer using carry arithmetic on u32s (as JS doesn't have fast u64).\n const littleEndian = true\n const randomLo32 = idLastBuffer.getUint32(0, littleEndian) + 1\n const randomHi32 = idLastBuffer.getUint32(4, littleEndian) + (randomLo32 > 0xFFFFFFFF ? 1 : 0)\n const randomHi16 = idLastBuffer.getUint16(8, littleEndian) + (randomHi32 > 0xFFFFFFFF ? 1 : 0)\n if (randomHi16 > 0xFFFF) {\n throw new Error('random bits overflow on monotonic increment')\n }\n\n // Store the incremented random monotonic and the timestamp into the buffer.\n idLastBuffer.setUint32(0, randomLo32 & 0xFFFFFFFF, littleEndian)\n idLastBuffer.setUint32(4, randomHi32 & 0xFFFFFFFF, littleEndian)\n idLastBuffer.setUint16(8, randomHi16, littleEndian) // No need to mask since checked above.\n idLastBuffer.setUint16(10, timestamp & 0xFFFF, littleEndian) // timestamp lo.\n idLastBuffer.setUint32(12, (timestamp / 0x10000) | 0, littleEndian) // timestamp hi.\n\n // Then return the buffer's contents as a little-endian u128 bigint.\n const lo = idLastBuffer.getBigUint64(0, littleEndian)\n const hi = idLastBuffer.getBigUint64(8, littleEndian)\n return (hi << 64n) | lo\n}\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["export * from './bindings'\nimport {\n Account,\n Transfer,\n CreateAccountResult,\n CreateTransferResult,\n Operation,\n AccountFilter,\n AccountBalance,\n QueryFilter,\n} from './bindings'\nimport { randomFillSync } from 'node:crypto'\n\nconst binding: Binding = (() => {\n const { arch, platform } = process\n\n const archMap = {\n \"arm64\": \"aarch64\",\n \"x64\": \"x86_64\"\n }\n\n const platformMap = {\n \"linux\": \"linux\",\n \"darwin\": \"macos\",\n \"win32\" : \"windows\",\n }\n\n if (! (arch in archMap)) {\n throw new Error(`Unsupported arch: ${arch}`)\n }\n\n if (! (platform in platformMap)) {\n throw new Error(`Unsupported platform: ${platform}`)\n }\n\n let linuxABI = ''\n\n /**\n * We need to detect during runtime which libc we're running on to load the correct NAPI.\n * binary.\n */\n if (platform === 'linux') {\n const glibcVersionRuntime = (process.report.getReport() as any).header.glibcVersionRuntime\n if (glibcVersionRuntime) {\n linuxABI = '-gnu'\n } else {\n linuxABI = '-musl'\n }\n }\n\n const filename = `./bin/${archMap[arch as keyof typeof archMap]}-` +\n `${platformMap[platform as keyof typeof platformMap]}${linuxABI}/client.node`\n return require(filename)\n})()\n\nexport type Context = object // tb_client\nexport type AccountID = bigint // u128\nexport type TransferID = bigint // u128\nexport type Event = Account | Transfer | AccountID | TransferID | AccountFilter | QueryFilter\nexport type Result = CreateAccountResult | CreateTransferResult | Account | Transfer | AccountBalance\nexport type ResultCallback = (error: Error | null, results: Result[] | null) => void\n\nexport const amount_max: bigint = (2n ** 128n) - 1n\n\n// Error codes returned by the client.\nexport const ErrorCodes = {\n ERR_CLIENT_CLOSED: 'ERR_CLIENT_CLOSED',\n ERR_CLIENT_EVICTED: 'ERR_CLIENT_EVICTED',\n ERR_CLIENT_RELEASE_TOO_LOW: 'ERR_CLIENT_RELEASE_TOO_LOW',\n ERR_CLIENT_RELEASE_TOO_HIGH: 'ERR_CLIENT_RELEASE_TOO_HIGH',\n ERR_TOO_MUCH_DATA: 'ERR_TOO_MUCH_DATA',\n} as const;\n\nexport type ErrorCodes = typeof ErrorCodes[keyof typeof ErrorCodes];\n\nexport class RequestError extends Error {\n code: ErrorCodes;\n\n constructor(code: ErrorCodes) {\n super(RequestError.errorMessage(code));\n this.name = 'RequestError';\n this.code = code;\n }\n\n static errorMessage(code: ErrorCodes): string {\n switch (code) {\n case ErrorCodes.ERR_CLIENT_CLOSED:\n return 'Client was closed.'\n case ErrorCodes.ERR_CLIENT_EVICTED:\n return 'Client was evicted.'\n case ErrorCodes.ERR_CLIENT_RELEASE_TOO_LOW:\n return 'Client was evicted: release too old.'\n case ErrorCodes.ERR_CLIENT_RELEASE_TOO_HIGH:\n return 'Client was evicted: release too new.'\n case ErrorCodes.ERR_TOO_MUCH_DATA:\n return 'Too much data was sent or requested in this batch.'\n default:\n throw new Error(\"Unknown error code.\")\n }\n }\n\n}\n\ninterface BindingInitArgs {\n cluster_id: bigint, // u128\n replica_addresses: Buffer,\n request_error_class: typeof RequestError,\n}\n\ninterface Binding {\n init: (args: BindingInitArgs) => Context\n submit: (context: Context, operation: Operation, batch: Event[], callback: ResultCallback) => void\n deinit: (context: Context) => void,\n}\n\nexport interface ClientInitArgs {\n cluster_id: bigint, // u128\n replica_addresses: Array<string | number>,\n}\n\nexport interface Client {\n createAccounts: (batch: Account[]) => Promise<CreateAccountResult[]>\n createTransfers: (batch: Transfer[]) => Promise<CreateTransferResult[]>\n lookupAccounts: (batch: AccountID[]) => Promise<Account[]>\n lookupTransfers: (batch: TransferID[]) => Promise<Transfer[]>\n getAccountTransfers: (filter: AccountFilter) => Promise<Transfer[]>\n getAccountBalances: (filter: AccountFilter) => Promise<AccountBalance[]>\n queryAccounts: (filter: QueryFilter) => Promise<Account[]>\n queryTransfers: (filter: QueryFilter) => Promise<Transfer[]>\n destroy: () => void\n}\n\nexport function createClient (args: ClientInitArgs): Client {\n // Context becomes null when `destroy` is called. After that point, further `request` Promises\n // throw a shutdown Error. This prevents tb_client calls from happening after tb_client_deinit().\n let context: Context | null = binding.init({\n cluster_id: args.cluster_id,\n replica_addresses: Buffer.from(args.replica_addresses.join(',')),\n request_error_class: RequestError,\n })\n\n const destroy = () => {\n if (context) binding.deinit(context)\n context = null;\n }\n\n const request = <T extends Result>(operation: Operation, batch: Event[]): Promise<T[]> => {\n return new Promise((resolve, reject) => {\n try {\n if (!context) throw new RequestError(ErrorCodes.ERR_CLIENT_CLOSED);\n\n binding.submit(context, operation, batch, (error, result) => {\n if (error) {\n reject(error)\n } else if (result) {\n resolve(result as T[])\n } else {\n throw new Error(\"UB: Binding invoked callback without error or result\")\n }\n })\n } catch (err) {\n reject(err)\n }\n })\n }\n\n return {\n createAccounts(batch) { return request(Operation.create_accounts, batch) },\n createTransfers(batch) { return request(Operation.create_transfers, batch) },\n lookupAccounts(batch) { return request(Operation.lookup_accounts, batch) },\n lookupTransfers(batch) { return request(Operation.lookup_transfers, batch) },\n getAccountTransfers(filter) { return request(Operation.get_account_transfers, [filter]) },\n getAccountBalances(filter) { return request(Operation.get_account_balances, [filter]) },\n queryAccounts(filter) { return request(Operation.query_accounts, [filter]) },\n queryTransfers(filter) { return request(Operation.query_transfers, [filter]) },\n destroy,\n }\n}\n\nlet idLastTimestamp = 0;\n\n// These are two references to the same buffer.\n// We only need the `Uint8Array` because in Node.js 24, but not earlier, `crypto.randomFillSync`\n// rejects `DataView` typed arguments.\nconst idLastBuffer = new DataView(new ArrayBuffer(16));\nconst idLastBufferArray = new Uint8Array(\n idLastBuffer.buffer, idLastBuffer.byteOffset, idLastBuffer.byteLength\n);\n\n/**\n * Generates a Universally Unique and Sortable Identifier as a u128 bigint.\n *\n * @remarks\n * Based on {@link https://github.com/ulid/spec}, IDs returned are guaranteed to be monotonically\n * increasing.\n */\nexport function id(): bigint {\n // Ensure timestamp monotonically increases and generate a new random on each new timestamp.\n let timestamp = Date.now()\n if (timestamp <= idLastTimestamp) {\n timestamp = idLastTimestamp\n } else {\n idLastTimestamp = timestamp\n randomFillSync(idLastBufferArray)\n }\n\n // Increment the u80 in idLastBuffer using carry arithmetic on u32s (as JS doesn't have fast u64).\n const littleEndian = true\n const randomLo32 = idLastBuffer.getUint32(0, littleEndian) + 1\n const randomHi32 = idLastBuffer.getUint32(4, littleEndian) + (randomLo32 > 0xFFFF_FFFF ? 1 : 0)\n const randomHi16 = idLastBuffer.getUint16(8, littleEndian) + (randomHi32 > 0xFFFF_FFFF ? 1 : 0)\n if (randomHi16 > 0xFFFF) {\n timestamp += 1\n idLastTimestamp = timestamp\n\n if (timestamp === 0x1_0000_0000_0000) {\n throw new Error('timestamp overflow on monotonic increment')\n }\n }\n\n // Store the incremented random monotonic and the timestamp into the buffer.\n idLastBuffer.setUint32(0, randomLo32 & 0xFFFF_FFFF, littleEndian)\n idLastBuffer.setUint32(4, randomHi32 & 0xFFFF_FFFF, littleEndian)\n idLastBuffer.setUint16(8, randomHi16, littleEndian) // No need to mask since checked above.\n idLastBuffer.setUint16(10, timestamp & 0xFFFF, littleEndian) // timestamp lo.\n idLastBuffer.setUint32(12, (timestamp / 0x10000) | 0, littleEndian) // timestamp hi.\n\n // Then return the buffer's contents as a little-endian u128 bigint.\n const lo = idLastBuffer.getBigUint64(0, littleEndian)\n const hi = idLastBuffer.getBigUint64(8, littleEndian)\n return (hi << 64n) | lo\n}\n"]}
|
package/dist/test.js
CHANGED
|
@@ -67,19 +67,25 @@ test('range check `code` on Account to be u16', async () => {
|
|
|
67
67
|
assert_1.default.deepStrictEqual(accounts, []);
|
|
68
68
|
});
|
|
69
69
|
test('can create accounts', async () => {
|
|
70
|
-
const
|
|
71
|
-
assert_1.default.deepStrictEqual(
|
|
70
|
+
const account_results = await client.createAccounts([accountA]);
|
|
71
|
+
assert_1.default.deepStrictEqual(account_results.length, 1);
|
|
72
|
+
assert_1.default.ok(account_results[0].timestamp > 0);
|
|
73
|
+
assert_1.default.deepStrictEqual(account_results[0].status, _1.CreateAccountStatus.created);
|
|
72
74
|
});
|
|
73
75
|
test('can return error on account', async () => {
|
|
74
|
-
const
|
|
75
|
-
assert_1.default.
|
|
76
|
-
assert_1.default.
|
|
76
|
+
const account_results = await client.createAccounts([accountA, accountB]);
|
|
77
|
+
assert_1.default.deepStrictEqual(account_results.length, 2);
|
|
78
|
+
assert_1.default.ok(account_results[0].timestamp > 0);
|
|
79
|
+
assert_1.default.deepStrictEqual(account_results[0].status, _1.CreateAccountStatus.exists);
|
|
80
|
+
assert_1.default.ok(account_results[1].timestamp > 0);
|
|
81
|
+
assert_1.default.deepStrictEqual(account_results[1].status, _1.CreateAccountStatus.created);
|
|
77
82
|
});
|
|
78
83
|
test('error if timestamp is not set to 0n on account', async () => {
|
|
79
84
|
const account = { ...accountA, timestamp: 2n, id: 3n };
|
|
80
|
-
const
|
|
81
|
-
assert_1.default.
|
|
82
|
-
assert_1.default.
|
|
85
|
+
const account_results = await client.createAccounts([account]);
|
|
86
|
+
assert_1.default.deepStrictEqual(account_results.length, 1);
|
|
87
|
+
assert_1.default.ok(account_results[0].timestamp > 0);
|
|
88
|
+
assert_1.default.deepStrictEqual(account_results[0].status, _1.CreateAccountStatus.timestamp_must_be_zero);
|
|
83
89
|
});
|
|
84
90
|
test('batch max size', async () => {
|
|
85
91
|
const BATCH_SIZE = 10000;
|
|
@@ -101,13 +107,11 @@ test('batch max size', async () => {
|
|
|
101
107
|
timestamp: 0n,
|
|
102
108
|
});
|
|
103
109
|
}
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
assert_1.default.
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
assert_1.default.strictEqual(error.message, "Too much data provided on this batch.");
|
|
110
|
-
}
|
|
110
|
+
assert_1.default.rejects(async () => await client.createTransfers(transfers), (err) => {
|
|
111
|
+
assert_1.default.ok(err instanceof _1.RequestError);
|
|
112
|
+
assert_1.default.strictEqual(err.code, _1.ErrorCodes.ERR_TOO_MUCH_DATA);
|
|
113
|
+
return true;
|
|
114
|
+
});
|
|
111
115
|
});
|
|
112
116
|
test('can lookup accounts', async () => {
|
|
113
117
|
const accounts = await client.lookupAccounts([accountA.id, accountB.id]);
|
|
@@ -155,8 +159,10 @@ test('can create a transfer', async () => {
|
|
|
155
159
|
flags: 0,
|
|
156
160
|
timestamp: 0n,
|
|
157
161
|
};
|
|
158
|
-
const
|
|
159
|
-
assert_1.default.deepStrictEqual(
|
|
162
|
+
const transfers_results = await client.createTransfers([transfer]);
|
|
163
|
+
assert_1.default.deepStrictEqual(transfers_results.length, 1);
|
|
164
|
+
assert_1.default.ok(transfers_results[0].timestamp > 0);
|
|
165
|
+
assert_1.default.deepStrictEqual(transfers_results[0].status, _1.CreateTransferStatus.created);
|
|
160
166
|
const accounts = await client.lookupAccounts([accountA.id, accountB.id]);
|
|
161
167
|
assert_1.default.strictEqual(accounts.length, 2);
|
|
162
168
|
assert_1.default.strictEqual(accounts[0].credits_posted, 100n);
|
|
@@ -186,8 +192,10 @@ test('can create a two-phase transfer', async () => {
|
|
|
186
192
|
flags,
|
|
187
193
|
timestamp: 0n,
|
|
188
194
|
};
|
|
189
|
-
const
|
|
190
|
-
assert_1.default.deepStrictEqual(
|
|
195
|
+
const transfers_results = await client.createTransfers([transfer]);
|
|
196
|
+
assert_1.default.deepStrictEqual(transfers_results.length, 1);
|
|
197
|
+
assert_1.default.ok(transfers_results[0].timestamp > 0);
|
|
198
|
+
assert_1.default.deepStrictEqual(transfers_results[0].status, _1.CreateTransferStatus.created);
|
|
191
199
|
const accounts = await client.lookupAccounts([accountA.id, accountB.id]);
|
|
192
200
|
assert_1.default.strictEqual(accounts.length, 2);
|
|
193
201
|
assert_1.default.strictEqual(accounts[0].credits_posted, 100n);
|
|
@@ -230,8 +238,10 @@ test('can post a two-phase transfer', async () => {
|
|
|
230
238
|
flags: flags,
|
|
231
239
|
timestamp: 0n,
|
|
232
240
|
};
|
|
233
|
-
const
|
|
234
|
-
assert_1.default.deepStrictEqual(
|
|
241
|
+
const transfers_results = await client.createTransfers([commit]);
|
|
242
|
+
assert_1.default.deepStrictEqual(transfers_results.length, 1);
|
|
243
|
+
assert_1.default.ok(transfers_results[0].timestamp > 0);
|
|
244
|
+
assert_1.default.deepStrictEqual(transfers_results[0].status, _1.CreateTransferStatus.created);
|
|
235
245
|
const accounts = await client.lookupAccounts([accountA.id, accountB.id]);
|
|
236
246
|
assert_1.default.strictEqual(accounts.length, 2);
|
|
237
247
|
assert_1.default.strictEqual(accounts[0].credits_posted, 150n);
|
|
@@ -259,8 +269,10 @@ test('can reject a two-phase transfer', async () => {
|
|
|
259
269
|
flags: _1.TransferFlags.pending,
|
|
260
270
|
timestamp: 0n,
|
|
261
271
|
};
|
|
262
|
-
|
|
263
|
-
assert_1.default.deepStrictEqual(
|
|
272
|
+
let transfers_results = await client.createTransfers([transfer]);
|
|
273
|
+
assert_1.default.deepStrictEqual(transfers_results.length, 1);
|
|
274
|
+
assert_1.default.ok(transfers_results[0].timestamp > 0);
|
|
275
|
+
assert_1.default.deepStrictEqual(transfers_results[0].status, _1.CreateTransferStatus.created);
|
|
264
276
|
const reject = {
|
|
265
277
|
id: 5n,
|
|
266
278
|
debit_account_id: BigInt(0),
|
|
@@ -276,8 +288,10 @@ test('can reject a two-phase transfer', async () => {
|
|
|
276
288
|
flags: _1.TransferFlags.void_pending_transfer,
|
|
277
289
|
timestamp: 0n,
|
|
278
290
|
};
|
|
279
|
-
|
|
280
|
-
assert_1.default.deepStrictEqual(
|
|
291
|
+
transfers_results = await client.createTransfers([reject]);
|
|
292
|
+
assert_1.default.deepStrictEqual(transfers_results.length, 1);
|
|
293
|
+
assert_1.default.ok(transfers_results[0].timestamp > 0);
|
|
294
|
+
assert_1.default.deepStrictEqual(transfers_results[0].status, _1.CreateTransferStatus.created);
|
|
281
295
|
const accounts = await client.lookupAccounts([accountA.id, accountB.id]);
|
|
282
296
|
assert_1.default.strictEqual(accounts.length, 2);
|
|
283
297
|
assert_1.default.strictEqual(accounts[0].credits_posted, 150n);
|
|
@@ -320,10 +334,12 @@ test('can link transfers', async () => {
|
|
|
320
334
|
flags: 0,
|
|
321
335
|
timestamp: 0n,
|
|
322
336
|
};
|
|
323
|
-
const
|
|
324
|
-
assert_1.default.
|
|
325
|
-
assert_1.default.
|
|
326
|
-
assert_1.default.deepStrictEqual(
|
|
337
|
+
const transfers_results = await client.createTransfers([transfer1, transfer2]);
|
|
338
|
+
assert_1.default.deepStrictEqual(transfers_results.length, 2);
|
|
339
|
+
assert_1.default.ok(transfers_results[0].timestamp > 0);
|
|
340
|
+
assert_1.default.deepStrictEqual(transfers_results[0].status, _1.CreateTransferStatus.linked_event_failed);
|
|
341
|
+
assert_1.default.ok(transfers_results[1].timestamp > 0);
|
|
342
|
+
assert_1.default.deepStrictEqual(transfers_results[1].status, _1.CreateTransferStatus.exists_with_different_flags);
|
|
327
343
|
const accounts = await client.lookupAccounts([accountA.id, accountB.id]);
|
|
328
344
|
assert_1.default.strictEqual(accounts.length, 2);
|
|
329
345
|
assert_1.default.strictEqual(accounts[0].credits_posted, 150n);
|
|
@@ -351,8 +367,10 @@ test('cannot void an expired transfer', async () => {
|
|
|
351
367
|
flags: _1.TransferFlags.pending,
|
|
352
368
|
timestamp: 0n,
|
|
353
369
|
};
|
|
354
|
-
|
|
355
|
-
assert_1.default.deepStrictEqual(
|
|
370
|
+
let transfers_results = await client.createTransfers([transfer]);
|
|
371
|
+
assert_1.default.deepStrictEqual(transfers_results.length, 1);
|
|
372
|
+
assert_1.default.ok(transfers_results[0].timestamp > 0);
|
|
373
|
+
assert_1.default.deepStrictEqual(transfers_results[0].status, _1.CreateTransferStatus.created);
|
|
356
374
|
var accounts = await client.lookupAccounts([accountA.id, accountB.id]);
|
|
357
375
|
assert_1.default.strictEqual(accounts.length, 2);
|
|
358
376
|
assert_1.default.strictEqual(accounts[0].credits_posted, 150n);
|
|
@@ -390,9 +408,10 @@ test('cannot void an expired transfer', async () => {
|
|
|
390
408
|
flags: _1.TransferFlags.void_pending_transfer,
|
|
391
409
|
timestamp: 0n,
|
|
392
410
|
};
|
|
393
|
-
|
|
394
|
-
assert_1.default.
|
|
395
|
-
assert_1.default.
|
|
411
|
+
transfers_results = await client.createTransfers([reject]);
|
|
412
|
+
assert_1.default.deepStrictEqual(transfers_results.length, 1);
|
|
413
|
+
assert_1.default.ok(transfers_results[0].timestamp > 0);
|
|
414
|
+
assert_1.default.deepStrictEqual(transfers_results[0].status, _1.CreateTransferStatus.pending_transfer_expired);
|
|
396
415
|
});
|
|
397
416
|
test('can close accounts', async () => {
|
|
398
417
|
const closing_transfer = {
|
|
@@ -410,8 +429,10 @@ test('can close accounts', async () => {
|
|
|
410
429
|
flags: _1.TransferFlags.closing_debit | _1.TransferFlags.closing_credit | _1.TransferFlags.pending,
|
|
411
430
|
timestamp: 0n,
|
|
412
431
|
};
|
|
413
|
-
let
|
|
414
|
-
assert_1.default.
|
|
432
|
+
let transfers_results = await client.createTransfers([closing_transfer]);
|
|
433
|
+
assert_1.default.deepStrictEqual(transfers_results.length, 1);
|
|
434
|
+
assert_1.default.ok(transfers_results[0].timestamp > 0);
|
|
435
|
+
assert_1.default.deepStrictEqual(transfers_results[0].status, _1.CreateTransferStatus.created);
|
|
415
436
|
let accounts = await client.lookupAccounts([accountA.id, accountB.id]);
|
|
416
437
|
assert_1.default.strictEqual(accounts.length, 2);
|
|
417
438
|
assert_1.default.ok(accountA.flags != accounts[0].flags);
|
|
@@ -433,8 +454,10 @@ test('can close accounts', async () => {
|
|
|
433
454
|
pending_id: closing_transfer.id,
|
|
434
455
|
timestamp: 0n,
|
|
435
456
|
};
|
|
436
|
-
|
|
437
|
-
assert_1.default.
|
|
457
|
+
transfers_results = await client.createTransfers([voiding_transfer]);
|
|
458
|
+
assert_1.default.deepStrictEqual(transfers_results.length, 1);
|
|
459
|
+
assert_1.default.ok(transfers_results[0].timestamp > 0);
|
|
460
|
+
assert_1.default.deepStrictEqual(transfers_results[0].status, _1.CreateTransferStatus.created);
|
|
438
461
|
accounts = await client.lookupAccounts([accountA.id, accountB.id]);
|
|
439
462
|
assert_1.default.strictEqual(accounts.length, 2);
|
|
440
463
|
assert_1.default.strictEqual(accountA.flags, accounts[0].flags);
|
|
@@ -458,8 +481,10 @@ test('can get account transfers', async () => {
|
|
|
458
481
|
flags: _1.AccountFlags.history,
|
|
459
482
|
timestamp: 0n
|
|
460
483
|
};
|
|
461
|
-
const
|
|
462
|
-
assert_1.default.deepStrictEqual(
|
|
484
|
+
const account_results = await client.createAccounts([accountC]);
|
|
485
|
+
assert_1.default.deepStrictEqual(account_results.length, 1);
|
|
486
|
+
assert_1.default.ok(account_results[0].timestamp > 0);
|
|
487
|
+
assert_1.default.deepStrictEqual(account_results[0].status, _1.CreateAccountStatus.created);
|
|
463
488
|
var transfers_created = [];
|
|
464
489
|
for (var i = 0; i < 10; i++) {
|
|
465
490
|
transfers_created.push({
|
|
@@ -478,8 +503,12 @@ test('can get account transfers', async () => {
|
|
|
478
503
|
timestamp: 0n,
|
|
479
504
|
});
|
|
480
505
|
}
|
|
481
|
-
const
|
|
482
|
-
assert_1.default.deepStrictEqual(
|
|
506
|
+
const transfers_results = await client.createTransfers(transfers_created);
|
|
507
|
+
assert_1.default.deepStrictEqual(transfers_results.length, transfers_created.length);
|
|
508
|
+
for (const result of transfers_results) {
|
|
509
|
+
assert_1.default.ok(result.timestamp > 0);
|
|
510
|
+
assert_1.default.deepStrictEqual(result.status, _1.CreateTransferStatus.created);
|
|
511
|
+
}
|
|
483
512
|
var filter = {
|
|
484
513
|
account_id: accountC.id,
|
|
485
514
|
user_data_128: 0n,
|
|
@@ -734,6 +763,27 @@ test('can get account transfers', async () => {
|
|
|
734
763
|
};
|
|
735
764
|
assert_1.default.deepStrictEqual((await client.getAccountTransfers(filter)), []);
|
|
736
765
|
assert_1.default.deepStrictEqual((await client.getAccountBalances(filter)), []);
|
|
766
|
+
filter = {
|
|
767
|
+
account_id: accountC.id,
|
|
768
|
+
user_data_128: 0n,
|
|
769
|
+
user_data_64: 0n,
|
|
770
|
+
user_data_32: 0,
|
|
771
|
+
code: 0,
|
|
772
|
+
timestamp_min: 0n,
|
|
773
|
+
timestamp_max: 0n,
|
|
774
|
+
limit: 10000,
|
|
775
|
+
flags: _1.AccountFilterFlags.credits | _1.AccountFilterFlags.debits,
|
|
776
|
+
};
|
|
777
|
+
assert_1.default.rejects(async () => await client.getAccountTransfers(filter), (err) => {
|
|
778
|
+
assert_1.default.ok(err instanceof _1.RequestError);
|
|
779
|
+
assert_1.default.strictEqual(err.code, _1.ErrorCodes.ERR_TOO_MUCH_DATA);
|
|
780
|
+
return true;
|
|
781
|
+
});
|
|
782
|
+
assert_1.default.rejects(async () => await client.getAccountBalances(filter), (err) => {
|
|
783
|
+
assert_1.default.ok(err instanceof _1.RequestError);
|
|
784
|
+
assert_1.default.strictEqual(err.code, _1.ErrorCodes.ERR_TOO_MUCH_DATA);
|
|
785
|
+
return true;
|
|
786
|
+
});
|
|
737
787
|
filter = {
|
|
738
788
|
account_id: accountC.id,
|
|
739
789
|
user_data_128: 0n,
|
|
@@ -781,8 +831,12 @@ test('can query accounts', async () => {
|
|
|
781
831
|
timestamp: 0n,
|
|
782
832
|
});
|
|
783
833
|
}
|
|
784
|
-
const
|
|
785
|
-
assert_1.default.deepStrictEqual(
|
|
834
|
+
const account_results = await client.createAccounts(accounts);
|
|
835
|
+
assert_1.default.deepStrictEqual(account_results.length, accounts.length);
|
|
836
|
+
for (const result of account_results) {
|
|
837
|
+
assert_1.default.ok(result.timestamp > 0);
|
|
838
|
+
assert_1.default.deepStrictEqual(result.status, _1.CreateAccountStatus.created);
|
|
839
|
+
}
|
|
786
840
|
}
|
|
787
841
|
{
|
|
788
842
|
var filter = {
|
|
@@ -920,8 +974,10 @@ test('can query transfers', async () => {
|
|
|
920
974
|
flags: _1.AccountFlags.none,
|
|
921
975
|
timestamp: 0n
|
|
922
976
|
};
|
|
923
|
-
const
|
|
924
|
-
assert_1.default.deepStrictEqual(
|
|
977
|
+
const account_results = await client.createAccounts([account]);
|
|
978
|
+
assert_1.default.deepStrictEqual(account_results.length, 1);
|
|
979
|
+
assert_1.default.ok(account_results[0].timestamp > 0);
|
|
980
|
+
assert_1.default.deepStrictEqual(account_results[0].status, _1.CreateAccountStatus.created);
|
|
925
981
|
var transfers_created = [];
|
|
926
982
|
for (var i = 0; i < 10; i++) {
|
|
927
983
|
transfers_created.push({
|
|
@@ -940,8 +996,12 @@ test('can query transfers', async () => {
|
|
|
940
996
|
timestamp: 0n,
|
|
941
997
|
});
|
|
942
998
|
}
|
|
943
|
-
const
|
|
944
|
-
assert_1.default.deepStrictEqual(
|
|
999
|
+
const transfers_results = await client.createTransfers(transfers_created);
|
|
1000
|
+
assert_1.default.deepStrictEqual(transfers_results.length, transfers_created.length);
|
|
1001
|
+
for (const result of transfers_results) {
|
|
1002
|
+
assert_1.default.ok(result.timestamp > 0);
|
|
1003
|
+
assert_1.default.deepStrictEqual(result.status, _1.CreateTransferStatus.created);
|
|
1004
|
+
}
|
|
945
1005
|
}
|
|
946
1006
|
{
|
|
947
1007
|
var filter = {
|
|
@@ -1115,6 +1175,27 @@ test('query with invalid filter', async () => {
|
|
|
1115
1175
|
};
|
|
1116
1176
|
assert_1.default.deepStrictEqual((await client.queryAccounts(filter)), []);
|
|
1117
1177
|
assert_1.default.deepStrictEqual((await client.queryTransfers(filter)), []);
|
|
1178
|
+
filter = {
|
|
1179
|
+
user_data_128: 0n,
|
|
1180
|
+
user_data_64: 0n,
|
|
1181
|
+
user_data_32: 0,
|
|
1182
|
+
ledger: 0,
|
|
1183
|
+
code: 0,
|
|
1184
|
+
timestamp_min: 0n,
|
|
1185
|
+
timestamp_max: 0n,
|
|
1186
|
+
limit: 10000,
|
|
1187
|
+
flags: _1.QueryFilterFlags.none,
|
|
1188
|
+
};
|
|
1189
|
+
assert_1.default.rejects(async () => await client.queryAccounts(filter), (err) => {
|
|
1190
|
+
assert_1.default.ok(err instanceof _1.RequestError);
|
|
1191
|
+
assert_1.default.strictEqual(err.code, _1.ErrorCodes.ERR_TOO_MUCH_DATA);
|
|
1192
|
+
return true;
|
|
1193
|
+
});
|
|
1194
|
+
assert_1.default.rejects(async () => await client.queryTransfers(filter), (err) => {
|
|
1195
|
+
assert_1.default.ok(err instanceof _1.RequestError);
|
|
1196
|
+
assert_1.default.strictEqual(err.code, _1.ErrorCodes.ERR_TOO_MUCH_DATA);
|
|
1197
|
+
return true;
|
|
1198
|
+
});
|
|
1118
1199
|
filter = {
|
|
1119
1200
|
user_data_128: 0n,
|
|
1120
1201
|
user_data_64: 0n,
|
|
@@ -1145,8 +1226,10 @@ test('can import accounts and transfers', async () => {
|
|
|
1145
1226
|
flags: 0,
|
|
1146
1227
|
timestamp: 0n
|
|
1147
1228
|
};
|
|
1148
|
-
let
|
|
1149
|
-
assert_1.default.deepStrictEqual(
|
|
1229
|
+
let account_results = await client.createAccounts([accountTmp]);
|
|
1230
|
+
assert_1.default.deepStrictEqual(account_results.length, 1);
|
|
1231
|
+
assert_1.default.ok(account_results[0].timestamp > 0);
|
|
1232
|
+
assert_1.default.deepStrictEqual(account_results[0].status, _1.CreateAccountStatus.created);
|
|
1150
1233
|
let accountLookup = await client.lookupAccounts([accountTmp.id]);
|
|
1151
1234
|
assert_1.default.strictEqual(accountLookup.length, 1);
|
|
1152
1235
|
const timestampMax = accountLookup[0].timestamp;
|
|
@@ -1181,8 +1264,12 @@ test('can import accounts and transfers', async () => {
|
|
|
1181
1264
|
flags: _1.AccountFlags.imported,
|
|
1182
1265
|
timestamp: timestampMax + 2n
|
|
1183
1266
|
};
|
|
1184
|
-
|
|
1185
|
-
assert_1.default.deepStrictEqual(
|
|
1267
|
+
account_results = await client.createAccounts([accountA, accountB]);
|
|
1268
|
+
assert_1.default.deepStrictEqual(account_results.length, 2);
|
|
1269
|
+
assert_1.default.ok(account_results[0].timestamp > 0);
|
|
1270
|
+
assert_1.default.deepStrictEqual(account_results[0].status, _1.CreateAccountStatus.created);
|
|
1271
|
+
assert_1.default.ok(account_results[1].timestamp > 0);
|
|
1272
|
+
assert_1.default.deepStrictEqual(account_results[1].status, _1.CreateAccountStatus.created);
|
|
1186
1273
|
accountLookup = await client.lookupAccounts([accountA.id, accountB.id]);
|
|
1187
1274
|
assert_1.default.strictEqual(accountLookup.length, 2);
|
|
1188
1275
|
assert_1.default.strictEqual(accountLookup[0].timestamp, accountA.timestamp);
|
|
@@ -1202,19 +1289,21 @@ test('can import accounts and transfers', async () => {
|
|
|
1202
1289
|
flags: _1.TransferFlags.imported,
|
|
1203
1290
|
timestamp: timestampMax + 3n,
|
|
1204
1291
|
};
|
|
1205
|
-
const
|
|
1206
|
-
assert_1.default.deepStrictEqual(
|
|
1292
|
+
const transfers_results = await client.createTransfers([transfer]);
|
|
1293
|
+
assert_1.default.deepStrictEqual(transfers_results.length, 1);
|
|
1294
|
+
assert_1.default.ok(transfers_results[0].timestamp > 0);
|
|
1295
|
+
assert_1.default.deepStrictEqual(transfers_results[0].status, _1.CreateTransferStatus.created);
|
|
1207
1296
|
const transfers = await client.lookupTransfers([transfer.id]);
|
|
1208
1297
|
assert_1.default.strictEqual(transfers.length, 1);
|
|
1209
1298
|
assert_1.default.strictEqual(transfers[0].timestamp, timestampMax + 3n);
|
|
1210
1299
|
});
|
|
1211
1300
|
test('accept zero-length create_accounts', async () => {
|
|
1212
|
-
const
|
|
1213
|
-
assert_1.default.deepStrictEqual(
|
|
1301
|
+
const account_results = await client.createAccounts([]);
|
|
1302
|
+
assert_1.default.deepStrictEqual(account_results.length, 0);
|
|
1214
1303
|
});
|
|
1215
1304
|
test('accept zero-length create_transfers', async () => {
|
|
1216
|
-
const
|
|
1217
|
-
assert_1.default.deepStrictEqual(
|
|
1305
|
+
const transfers_results = await client.createTransfers([]);
|
|
1306
|
+
assert_1.default.deepStrictEqual(transfers_results.length, 0);
|
|
1218
1307
|
});
|
|
1219
1308
|
test('accept zero-length lookup_accounts', async () => {
|
|
1220
1309
|
const accounts = await client.lookupAccounts([]);
|
|
@@ -1227,14 +1316,11 @@ test('accept zero-length lookup_transfers', async () => {
|
|
|
1227
1316
|
test("destroy client in-flight", async () => {
|
|
1228
1317
|
const client = (0, _1.createClient)({ cluster_id: 92n, replica_addresses: ["99"] });
|
|
1229
1318
|
setTimeout(() => client.destroy(), 30);
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
return;
|
|
1236
|
-
}
|
|
1237
|
-
throw "expected an error";
|
|
1319
|
+
assert_1.default.rejects(async () => await client.lookupAccounts([0n]), (err) => {
|
|
1320
|
+
assert_1.default.ok(err instanceof _1.RequestError);
|
|
1321
|
+
assert_1.default.strictEqual(err.code, _1.ErrorCodes.ERR_CLIENT_CLOSED);
|
|
1322
|
+
return true;
|
|
1323
|
+
});
|
|
1238
1324
|
});
|
|
1239
1325
|
async function main() {
|
|
1240
1326
|
const start = new Date().getTime();
|