cantonjs 0.0.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/LICENSE +201 -0
- package/dist/cjs/admin/index.d.ts +5 -0
- package/dist/cjs/admin/index.d.ts.map +1 -0
- package/dist/cjs/admin/index.js +6 -0
- package/dist/cjs/admin/index.js.map +1 -0
- package/dist/cjs/chains/definitions.d.ts +20 -0
- package/dist/cjs/chains/definitions.d.ts.map +1 -0
- package/dist/cjs/chains/definitions.js +33 -0
- package/dist/cjs/chains/definitions.js.map +1 -0
- package/dist/cjs/chains/index.d.ts +2 -0
- package/dist/cjs/chains/index.d.ts.map +1 -0
- package/dist/cjs/chains/index.js +9 -0
- package/dist/cjs/chains/index.js.map +1 -0
- package/dist/cjs/clients/createAdminClient.d.ts +73 -0
- package/dist/cjs/clients/createAdminClient.d.ts.map +1 -0
- package/dist/cjs/clients/createAdminClient.js +205 -0
- package/dist/cjs/clients/createAdminClient.js.map +1 -0
- package/dist/cjs/clients/createLedgerClient.d.ts +83 -0
- package/dist/cjs/clients/createLedgerClient.d.ts.map +1 -0
- package/dist/cjs/clients/createLedgerClient.js +240 -0
- package/dist/cjs/clients/createLedgerClient.js.map +1 -0
- package/dist/cjs/clients/createTestClient.d.ts +27 -0
- package/dist/cjs/clients/createTestClient.d.ts.map +1 -0
- package/dist/cjs/clients/createTestClient.js +46 -0
- package/dist/cjs/clients/createTestClient.js.map +1 -0
- package/dist/cjs/clients/index.d.ts +4 -0
- package/dist/cjs/clients/index.d.ts.map +1 -0
- package/dist/cjs/clients/index.js +10 -0
- package/dist/cjs/clients/index.js.map +1 -0
- package/dist/cjs/codegen/index.d.ts +2 -0
- package/dist/cjs/codegen/index.d.ts.map +1 -0
- package/dist/cjs/codegen/index.js +3 -0
- package/dist/cjs/codegen/index.js.map +1 -0
- package/dist/cjs/codegen/types.d.ts +38 -0
- package/dist/cjs/codegen/types.d.ts.map +1 -0
- package/dist/cjs/codegen/types.js +9 -0
- package/dist/cjs/codegen/types.js.map +1 -0
- package/dist/cjs/errors/auth.d.ts +13 -0
- package/dist/cjs/errors/auth.d.ts.map +1 -0
- package/dist/cjs/errors/auth.js +36 -0
- package/dist/cjs/errors/auth.js.map +1 -0
- package/dist/cjs/errors/base.d.ts +35 -0
- package/dist/cjs/errors/base.d.ts.map +1 -0
- package/dist/cjs/errors/base.js +71 -0
- package/dist/cjs/errors/base.js.map +1 -0
- package/dist/cjs/errors/index.d.ts +6 -0
- package/dist/cjs/errors/index.d.ts.map +1 -0
- package/dist/cjs/errors/index.js +22 -0
- package/dist/cjs/errors/index.js.map +1 -0
- package/dist/cjs/errors/ledger.d.ts +22 -0
- package/dist/cjs/errors/ledger.d.ts.map +1 -0
- package/dist/cjs/errors/ledger.js +55 -0
- package/dist/cjs/errors/ledger.js.map +1 -0
- package/dist/cjs/errors/streaming.d.ts +20 -0
- package/dist/cjs/errors/streaming.d.ts.map +1 -0
- package/dist/cjs/errors/streaming.js +54 -0
- package/dist/cjs/errors/streaming.js.map +1 -0
- package/dist/cjs/errors/transport.d.ts +31 -0
- package/dist/cjs/errors/transport.d.ts.map +1 -0
- package/dist/cjs/errors/transport.js +63 -0
- package/dist/cjs/errors/transport.js.map +1 -0
- package/dist/cjs/index.d.ts +25 -0
- package/dist/cjs/index.d.ts.map +1 -0
- package/dist/cjs/index.js +48 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/ledger/index.d.ts +5 -0
- package/dist/cjs/ledger/index.d.ts.map +1 -0
- package/dist/cjs/ledger/index.js +6 -0
- package/dist/cjs/ledger/index.js.map +1 -0
- package/dist/cjs/package.json +1 -0
- package/dist/cjs/streaming/createStream.d.ts +55 -0
- package/dist/cjs/streaming/createStream.d.ts.map +1 -0
- package/dist/cjs/streaming/createStream.js +270 -0
- package/dist/cjs/streaming/createStream.js.map +1 -0
- package/dist/cjs/streaming/index.d.ts +8 -0
- package/dist/cjs/streaming/index.d.ts.map +1 -0
- package/dist/cjs/streaming/index.js +16 -0
- package/dist/cjs/streaming/index.js.map +1 -0
- package/dist/cjs/streaming/streamCompletions.d.ts +25 -0
- package/dist/cjs/streaming/streamCompletions.d.ts.map +1 -0
- package/dist/cjs/streaming/streamCompletions.js +47 -0
- package/dist/cjs/streaming/streamCompletions.js.map +1 -0
- package/dist/cjs/streaming/streamContracts.d.ts +42 -0
- package/dist/cjs/streaming/streamContracts.d.ts.map +1 -0
- package/dist/cjs/streaming/streamContracts.js +56 -0
- package/dist/cjs/streaming/streamContracts.js.map +1 -0
- package/dist/cjs/streaming/streamUpdates.d.ts +38 -0
- package/dist/cjs/streaming/streamUpdates.d.ts.map +1 -0
- package/dist/cjs/streaming/streamUpdates.js +66 -0
- package/dist/cjs/streaming/streamUpdates.js.map +1 -0
- package/dist/cjs/streaming/types.d.ts +111 -0
- package/dist/cjs/streaming/types.d.ts.map +1 -0
- package/dist/cjs/streaming/types.js +20 -0
- package/dist/cjs/streaming/types.js.map +1 -0
- package/dist/cjs/testing/index.d.ts +4 -0
- package/dist/cjs/testing/index.d.ts.map +1 -0
- package/dist/cjs/testing/index.js +11 -0
- package/dist/cjs/testing/index.js.map +1 -0
- package/dist/cjs/testing/mockTransport.d.ts +80 -0
- package/dist/cjs/testing/mockTransport.d.ts.map +1 -0
- package/dist/cjs/testing/mockTransport.js +97 -0
- package/dist/cjs/testing/mockTransport.js.map +1 -0
- package/dist/cjs/testing/setupSandbox.d.ts +62 -0
- package/dist/cjs/testing/setupSandbox.d.ts.map +1 -0
- package/dist/cjs/testing/setupSandbox.js +109 -0
- package/dist/cjs/testing/setupSandbox.js.map +1 -0
- package/dist/cjs/transport/fallback.d.ts +21 -0
- package/dist/cjs/transport/fallback.d.ts.map +1 -0
- package/dist/cjs/transport/fallback.js +48 -0
- package/dist/cjs/transport/fallback.js.map +1 -0
- package/dist/cjs/transport/grpc.d.ts +51 -0
- package/dist/cjs/transport/grpc.d.ts.map +1 -0
- package/dist/cjs/transport/grpc.js +90 -0
- package/dist/cjs/transport/grpc.js.map +1 -0
- package/dist/cjs/transport/index.d.ts +3 -0
- package/dist/cjs/transport/index.d.ts.map +1 -0
- package/dist/cjs/transport/index.js +6 -0
- package/dist/cjs/transport/index.js.map +1 -0
- package/dist/cjs/transport/json-api.d.ts +9 -0
- package/dist/cjs/transport/json-api.d.ts.map +1 -0
- package/dist/cjs/transport/json-api.js +69 -0
- package/dist/cjs/transport/json-api.js.map +1 -0
- package/dist/cjs/transport/types.d.ts +36 -0
- package/dist/cjs/transport/types.d.ts.map +1 -0
- package/dist/cjs/transport/types.js +10 -0
- package/dist/cjs/transport/types.js.map +1 -0
- package/dist/cjs/types/command.d.ts +127 -0
- package/dist/cjs/types/command.d.ts.map +1 -0
- package/dist/cjs/types/command.js +12 -0
- package/dist/cjs/types/command.js.map +1 -0
- package/dist/cjs/types/contract.d.ts +104 -0
- package/dist/cjs/types/contract.d.ts.map +1 -0
- package/dist/cjs/types/contract.js +12 -0
- package/dist/cjs/types/contract.js.map +1 -0
- package/dist/cjs/types/idp.d.ts +28 -0
- package/dist/cjs/types/idp.d.ts.map +1 -0
- package/dist/cjs/types/idp.js +9 -0
- package/dist/cjs/types/idp.js.map +1 -0
- package/dist/cjs/types/index.d.ts +10 -0
- package/dist/cjs/types/index.d.ts.map +1 -0
- package/dist/cjs/types/index.js +3 -0
- package/dist/cjs/types/index.js.map +1 -0
- package/dist/cjs/types/interactive.d.ts +47 -0
- package/dist/cjs/types/interactive.d.ts.map +1 -0
- package/dist/cjs/types/interactive.js +13 -0
- package/dist/cjs/types/interactive.js.map +1 -0
- package/dist/cjs/types/package.d.ts +15 -0
- package/dist/cjs/types/package.d.ts.map +1 -0
- package/dist/cjs/types/package.js +8 -0
- package/dist/cjs/types/package.js.map +1 -0
- package/dist/cjs/types/party.d.ts +32 -0
- package/dist/cjs/types/party.d.ts.map +1 -0
- package/dist/cjs/types/party.js +10 -0
- package/dist/cjs/types/party.js.map +1 -0
- package/dist/cjs/types/reassignment.d.ts +65 -0
- package/dist/cjs/types/reassignment.d.ts.map +1 -0
- package/dist/cjs/types/reassignment.js +10 -0
- package/dist/cjs/types/reassignment.js.map +1 -0
- package/dist/cjs/types/transaction.d.ts +59 -0
- package/dist/cjs/types/transaction.d.ts.map +1 -0
- package/dist/cjs/types/transaction.js +13 -0
- package/dist/cjs/types/transaction.js.map +1 -0
- package/dist/cjs/types/user.d.ts +64 -0
- package/dist/cjs/types/user.d.ts.map +1 -0
- package/dist/cjs/types/user.js +12 -0
- package/dist/cjs/types/user.js.map +1 -0
- package/dist/esm/admin/index.d.ts +5 -0
- package/dist/esm/admin/index.d.ts.map +1 -0
- package/dist/esm/admin/index.js +2 -0
- package/dist/esm/admin/index.js.map +1 -0
- package/dist/esm/chains/definitions.d.ts +20 -0
- package/dist/esm/chains/definitions.d.ts.map +1 -0
- package/dist/esm/chains/definitions.js +30 -0
- package/dist/esm/chains/definitions.js.map +1 -0
- package/dist/esm/chains/index.d.ts +2 -0
- package/dist/esm/chains/index.d.ts.map +1 -0
- package/dist/esm/chains/index.js +2 -0
- package/dist/esm/chains/index.js.map +1 -0
- package/dist/esm/clients/createAdminClient.d.ts +73 -0
- package/dist/esm/clients/createAdminClient.d.ts.map +1 -0
- package/dist/esm/clients/createAdminClient.js +202 -0
- package/dist/esm/clients/createAdminClient.js.map +1 -0
- package/dist/esm/clients/createLedgerClient.d.ts +83 -0
- package/dist/esm/clients/createLedgerClient.d.ts.map +1 -0
- package/dist/esm/clients/createLedgerClient.js +237 -0
- package/dist/esm/clients/createLedgerClient.js.map +1 -0
- package/dist/esm/clients/createTestClient.d.ts +27 -0
- package/dist/esm/clients/createTestClient.d.ts.map +1 -0
- package/dist/esm/clients/createTestClient.js +43 -0
- package/dist/esm/clients/createTestClient.js.map +1 -0
- package/dist/esm/clients/index.d.ts +4 -0
- package/dist/esm/clients/index.d.ts.map +1 -0
- package/dist/esm/clients/index.js +4 -0
- package/dist/esm/clients/index.js.map +1 -0
- package/dist/esm/codegen/index.d.ts +2 -0
- package/dist/esm/codegen/index.d.ts.map +1 -0
- package/dist/esm/codegen/index.js +2 -0
- package/dist/esm/codegen/index.js.map +1 -0
- package/dist/esm/codegen/types.d.ts +38 -0
- package/dist/esm/codegen/types.d.ts.map +1 -0
- package/dist/esm/codegen/types.js +8 -0
- package/dist/esm/codegen/types.js.map +1 -0
- package/dist/esm/errors/auth.d.ts +13 -0
- package/dist/esm/errors/auth.d.ts.map +1 -0
- package/dist/esm/errors/auth.js +31 -0
- package/dist/esm/errors/auth.js.map +1 -0
- package/dist/esm/errors/base.d.ts +35 -0
- package/dist/esm/errors/base.d.ts.map +1 -0
- package/dist/esm/errors/base.js +67 -0
- package/dist/esm/errors/base.js.map +1 -0
- package/dist/esm/errors/index.d.ts +6 -0
- package/dist/esm/errors/index.d.ts.map +1 -0
- package/dist/esm/errors/index.js +6 -0
- package/dist/esm/errors/index.js.map +1 -0
- package/dist/esm/errors/ledger.d.ts +22 -0
- package/dist/esm/errors/ledger.d.ts.map +1 -0
- package/dist/esm/errors/ledger.js +49 -0
- package/dist/esm/errors/ledger.js.map +1 -0
- package/dist/esm/errors/streaming.d.ts +20 -0
- package/dist/esm/errors/streaming.d.ts.map +1 -0
- package/dist/esm/errors/streaming.js +48 -0
- package/dist/esm/errors/streaming.js.map +1 -0
- package/dist/esm/errors/transport.d.ts +31 -0
- package/dist/esm/errors/transport.d.ts.map +1 -0
- package/dist/esm/errors/transport.js +56 -0
- package/dist/esm/errors/transport.js.map +1 -0
- package/dist/esm/index.d.ts +25 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +18 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/ledger/index.d.ts +5 -0
- package/dist/esm/ledger/index.d.ts.map +1 -0
- package/dist/esm/ledger/index.js +2 -0
- package/dist/esm/ledger/index.js.map +1 -0
- package/dist/esm/streaming/createStream.d.ts +55 -0
- package/dist/esm/streaming/createStream.d.ts.map +1 -0
- package/dist/esm/streaming/createStream.js +265 -0
- package/dist/esm/streaming/createStream.js.map +1 -0
- package/dist/esm/streaming/index.d.ts +8 -0
- package/dist/esm/streaming/index.d.ts.map +1 -0
- package/dist/esm/streaming/index.js +6 -0
- package/dist/esm/streaming/index.js.map +1 -0
- package/dist/esm/streaming/streamCompletions.d.ts +25 -0
- package/dist/esm/streaming/streamCompletions.d.ts.map +1 -0
- package/dist/esm/streaming/streamCompletions.js +44 -0
- package/dist/esm/streaming/streamCompletions.js.map +1 -0
- package/dist/esm/streaming/streamContracts.d.ts +42 -0
- package/dist/esm/streaming/streamContracts.d.ts.map +1 -0
- package/dist/esm/streaming/streamContracts.js +53 -0
- package/dist/esm/streaming/streamContracts.js.map +1 -0
- package/dist/esm/streaming/streamUpdates.d.ts +38 -0
- package/dist/esm/streaming/streamUpdates.d.ts.map +1 -0
- package/dist/esm/streaming/streamUpdates.js +63 -0
- package/dist/esm/streaming/streamUpdates.js.map +1 -0
- package/dist/esm/streaming/types.d.ts +111 -0
- package/dist/esm/streaming/types.d.ts.map +1 -0
- package/dist/esm/streaming/types.js +17 -0
- package/dist/esm/streaming/types.js.map +1 -0
- package/dist/esm/testing/index.d.ts +4 -0
- package/dist/esm/testing/index.d.ts.map +1 -0
- package/dist/esm/testing/index.js +4 -0
- package/dist/esm/testing/index.js.map +1 -0
- package/dist/esm/testing/mockTransport.d.ts +80 -0
- package/dist/esm/testing/mockTransport.d.ts.map +1 -0
- package/dist/esm/testing/mockTransport.js +93 -0
- package/dist/esm/testing/mockTransport.js.map +1 -0
- package/dist/esm/testing/setupSandbox.d.ts +62 -0
- package/dist/esm/testing/setupSandbox.d.ts.map +1 -0
- package/dist/esm/testing/setupSandbox.js +106 -0
- package/dist/esm/testing/setupSandbox.js.map +1 -0
- package/dist/esm/transport/fallback.d.ts +21 -0
- package/dist/esm/transport/fallback.d.ts.map +1 -0
- package/dist/esm/transport/fallback.js +45 -0
- package/dist/esm/transport/fallback.js.map +1 -0
- package/dist/esm/transport/grpc.d.ts +51 -0
- package/dist/esm/transport/grpc.d.ts.map +1 -0
- package/dist/esm/transport/grpc.js +87 -0
- package/dist/esm/transport/grpc.js.map +1 -0
- package/dist/esm/transport/index.d.ts +3 -0
- package/dist/esm/transport/index.d.ts.map +1 -0
- package/dist/esm/transport/index.js +2 -0
- package/dist/esm/transport/index.js.map +1 -0
- package/dist/esm/transport/json-api.d.ts +9 -0
- package/dist/esm/transport/json-api.d.ts.map +1 -0
- package/dist/esm/transport/json-api.js +66 -0
- package/dist/esm/transport/json-api.js.map +1 -0
- package/dist/esm/transport/types.d.ts +36 -0
- package/dist/esm/transport/types.d.ts.map +1 -0
- package/dist/esm/transport/types.js +9 -0
- package/dist/esm/transport/types.js.map +1 -0
- package/dist/esm/types/command.d.ts +127 -0
- package/dist/esm/types/command.d.ts.map +1 -0
- package/dist/esm/types/command.js +11 -0
- package/dist/esm/types/command.js.map +1 -0
- package/dist/esm/types/contract.d.ts +104 -0
- package/dist/esm/types/contract.d.ts.map +1 -0
- package/dist/esm/types/contract.js +11 -0
- package/dist/esm/types/contract.js.map +1 -0
- package/dist/esm/types/idp.d.ts +28 -0
- package/dist/esm/types/idp.d.ts.map +1 -0
- package/dist/esm/types/idp.js +8 -0
- package/dist/esm/types/idp.js.map +1 -0
- package/dist/esm/types/index.d.ts +10 -0
- package/dist/esm/types/index.d.ts.map +1 -0
- package/dist/esm/types/index.js +2 -0
- package/dist/esm/types/index.js.map +1 -0
- package/dist/esm/types/interactive.d.ts +47 -0
- package/dist/esm/types/interactive.d.ts.map +1 -0
- package/dist/esm/types/interactive.js +12 -0
- package/dist/esm/types/interactive.js.map +1 -0
- package/dist/esm/types/package.d.ts +15 -0
- package/dist/esm/types/package.d.ts.map +1 -0
- package/dist/esm/types/package.js +7 -0
- package/dist/esm/types/package.js.map +1 -0
- package/dist/esm/types/party.d.ts +32 -0
- package/dist/esm/types/party.d.ts.map +1 -0
- package/dist/esm/types/party.js +9 -0
- package/dist/esm/types/party.js.map +1 -0
- package/dist/esm/types/reassignment.d.ts +65 -0
- package/dist/esm/types/reassignment.d.ts.map +1 -0
- package/dist/esm/types/reassignment.js +9 -0
- package/dist/esm/types/reassignment.js.map +1 -0
- package/dist/esm/types/transaction.d.ts +59 -0
- package/dist/esm/types/transaction.d.ts.map +1 -0
- package/dist/esm/types/transaction.js +12 -0
- package/dist/esm/types/transaction.js.map +1 -0
- package/dist/esm/types/user.d.ts +64 -0
- package/dist/esm/types/user.d.ts.map +1 -0
- package/dist/esm/types/user.js +11 -0
- package/dist/esm/types/user.js.map +1 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -0
- package/dist/tsconfig.cjs.tsbuildinfo +1 -0
- package/package.json +140 -0
- package/src/admin/index.ts +9 -0
- package/src/chains/definitions.ts +43 -0
- package/src/chains/index.ts +1 -0
- package/src/clients/createAdminClient.ts +336 -0
- package/src/clients/createLedgerClient.ts +383 -0
- package/src/clients/createTestClient.ts +77 -0
- package/src/clients/index.ts +19 -0
- package/src/codegen/index.ts +6 -0
- package/src/codegen/types.ts +51 -0
- package/src/errors/auth.ts +33 -0
- package/src/errors/base.ts +83 -0
- package/src/errors/index.ts +5 -0
- package/src/errors/ledger.ts +53 -0
- package/src/errors/streaming.ts +51 -0
- package/src/errors/transport.ts +65 -0
- package/src/index.ts +122 -0
- package/src/ledger/index.ts +33 -0
- package/src/streaming/createStream.ts +321 -0
- package/src/streaming/index.ts +19 -0
- package/src/streaming/streamCompletions.ts +49 -0
- package/src/streaming/streamContracts.ts +64 -0
- package/src/streaming/streamUpdates.ts +67 -0
- package/src/streaming/types.ts +117 -0
- package/src/testing/index.ts +18 -0
- package/src/testing/mockTransport.ts +132 -0
- package/src/testing/setupSandbox.ts +163 -0
- package/src/transport/fallback.ts +57 -0
- package/src/transport/grpc.ts +130 -0
- package/src/transport/index.ts +2 -0
- package/src/transport/json-api.ts +83 -0
- package/src/transport/types.ts +39 -0
- package/src/types/command.ts +123 -0
- package/src/types/contract.ts +101 -0
- package/src/types/idp.ts +31 -0
- package/src/types/index.ts +66 -0
- package/src/types/interactive.ts +53 -0
- package/src/types/package.ts +16 -0
- package/src/types/party.ts +33 -0
- package/src/types/reassignment.ts +68 -0
- package/src/types/transaction.ts +57 -0
- package/src/types/user.ts +41 -0
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { CantonjsError, type ErrorCode } from './base.js'
|
|
2
|
+
|
|
3
|
+
/** Command was rejected by the ledger. */
|
|
4
|
+
export class CommandRejectedError extends CantonjsError {
|
|
5
|
+
readonly grpcStatusCode: number
|
|
6
|
+
readonly rejectionReason: string
|
|
7
|
+
|
|
8
|
+
constructor(rejectionReason: string, options?: { cause?: Error; grpcStatusCode?: number }) {
|
|
9
|
+
super(`Command rejected: ${rejectionReason}`, {
|
|
10
|
+
code: 'CJ3001' as ErrorCode,
|
|
11
|
+
cause: options?.cause,
|
|
12
|
+
metaMessages: [
|
|
13
|
+
'The ledger rejected this command. Check the rejection reason for details.',
|
|
14
|
+
'Common causes: authorization failure, contract not active, duplicate command.',
|
|
15
|
+
],
|
|
16
|
+
})
|
|
17
|
+
this.name = 'CommandRejectedError'
|
|
18
|
+
this.grpcStatusCode = options?.grpcStatusCode ?? 0
|
|
19
|
+
this.rejectionReason = rejectionReason
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/** Contract was not found on the ledger. */
|
|
24
|
+
export class ContractNotFoundError extends CantonjsError {
|
|
25
|
+
readonly contractId: string
|
|
26
|
+
|
|
27
|
+
constructor(contractId: string) {
|
|
28
|
+
super(`Contract not found: ${contractId}`, {
|
|
29
|
+
code: 'CJ3002' as ErrorCode,
|
|
30
|
+
metaMessages: [
|
|
31
|
+
'The contract may have been archived or may not be visible to the current party.',
|
|
32
|
+
`Contract ID: ${contractId}`,
|
|
33
|
+
],
|
|
34
|
+
})
|
|
35
|
+
this.name = 'ContractNotFoundError'
|
|
36
|
+
this.contractId = contractId
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/** Party is not authorized for the requested operation. */
|
|
41
|
+
export class AuthorizationError extends CantonjsError {
|
|
42
|
+
constructor(message: string, options?: { cause?: Error }) {
|
|
43
|
+
super(message, {
|
|
44
|
+
code: 'CJ3003' as ErrorCode,
|
|
45
|
+
cause: options?.cause,
|
|
46
|
+
metaMessages: [
|
|
47
|
+
'Ensure the party has the required rights (actAs or readAs) for this operation.',
|
|
48
|
+
'Check that the JWT token includes the correct party claims.',
|
|
49
|
+
],
|
|
50
|
+
})
|
|
51
|
+
this.name = 'AuthorizationError'
|
|
52
|
+
}
|
|
53
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { CantonjsError, type ErrorCode } from './base.js'
|
|
2
|
+
|
|
3
|
+
/** WebSocket connection to a Canton streaming endpoint failed. */
|
|
4
|
+
export class WebSocketError extends CantonjsError {
|
|
5
|
+
constructor(url: string, options?: { cause?: Error }) {
|
|
6
|
+
super(`WebSocket connection failed: ${url}`, {
|
|
7
|
+
code: 'CJ5001' as ErrorCode,
|
|
8
|
+
cause: options?.cause,
|
|
9
|
+
metaMessages: [
|
|
10
|
+
'Ensure the Canton node is running and WebSocket endpoint is accessible.',
|
|
11
|
+
`Attempted URL: ${url}`,
|
|
12
|
+
],
|
|
13
|
+
docsPath: 'https://github.com/merged-one/cantonjs#streaming',
|
|
14
|
+
})
|
|
15
|
+
this.name = 'WebSocketError'
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** Stream was closed unexpectedly by the server. */
|
|
20
|
+
export class StreamClosedError extends CantonjsError {
|
|
21
|
+
readonly code_: number
|
|
22
|
+
readonly reason: string
|
|
23
|
+
|
|
24
|
+
constructor(code: number, reason: string) {
|
|
25
|
+
super(`Stream closed unexpectedly: ${code} ${reason}`, {
|
|
26
|
+
code: 'CJ5002' as ErrorCode,
|
|
27
|
+
metaMessages: [
|
|
28
|
+
`WebSocket close code: ${code}`,
|
|
29
|
+
reason ? `Reason: ${reason}` : 'No reason provided by server.',
|
|
30
|
+
],
|
|
31
|
+
})
|
|
32
|
+
this.name = 'StreamClosedError'
|
|
33
|
+
this.code_ = code
|
|
34
|
+
this.reason = reason
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/** Reconnection attempts exhausted. */
|
|
39
|
+
export class ReconnectFailedError extends CantonjsError {
|
|
40
|
+
constructor(attempts: number, options?: { cause?: Error }) {
|
|
41
|
+
super(`Failed to reconnect after ${attempts} attempts`, {
|
|
42
|
+
code: 'CJ5003' as ErrorCode,
|
|
43
|
+
cause: options?.cause,
|
|
44
|
+
metaMessages: [
|
|
45
|
+
'The stream was unable to reconnect to the Canton node.',
|
|
46
|
+
'Check network connectivity and node availability.',
|
|
47
|
+
],
|
|
48
|
+
})
|
|
49
|
+
this.name = 'ReconnectFailedError'
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { CantonjsError, type ErrorCode } from './base.js'
|
|
2
|
+
|
|
3
|
+
/** Error connecting to a Canton node. */
|
|
4
|
+
export class ConnectionError extends CantonjsError {
|
|
5
|
+
constructor(url: string, options?: { cause?: Error }) {
|
|
6
|
+
super(`Failed to connect to Canton node at ${url}`, {
|
|
7
|
+
code: 'CJ1001' as ErrorCode,
|
|
8
|
+
cause: options?.cause,
|
|
9
|
+
metaMessages: [
|
|
10
|
+
'Ensure the Canton node is running and accessible.',
|
|
11
|
+
`Attempted URL: ${url}`,
|
|
12
|
+
],
|
|
13
|
+
docsPath: 'https://github.com/merged-one/cantonjs#connection',
|
|
14
|
+
})
|
|
15
|
+
this.name = 'ConnectionError'
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** HTTP error from the JSON Ledger API. */
|
|
20
|
+
export class HttpError extends CantonjsError {
|
|
21
|
+
readonly status: number
|
|
22
|
+
readonly headers?: Record<string, string>
|
|
23
|
+
|
|
24
|
+
constructor(
|
|
25
|
+
status: number,
|
|
26
|
+
statusText: string,
|
|
27
|
+
options?: { cause?: Error; headers?: Record<string, string>; body?: string },
|
|
28
|
+
) {
|
|
29
|
+
super(`HTTP ${status}: ${statusText}`, {
|
|
30
|
+
code: 'CJ1002' as ErrorCode,
|
|
31
|
+
cause: options?.cause,
|
|
32
|
+
metaMessages: options?.body ? [`Response body: ${options.body}`] : undefined,
|
|
33
|
+
})
|
|
34
|
+
this.name = 'HttpError'
|
|
35
|
+
this.status = status
|
|
36
|
+
this.headers = options?.headers
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/** gRPC error from the Ledger API. */
|
|
41
|
+
export class GrpcError extends CantonjsError {
|
|
42
|
+
readonly grpcCode: number
|
|
43
|
+
|
|
44
|
+
constructor(grpcCode: number, message: string, options?: { cause?: Error }) {
|
|
45
|
+
super(message, {
|
|
46
|
+
code: 'CJ1003' as ErrorCode,
|
|
47
|
+
cause: options?.cause,
|
|
48
|
+
metaMessages: [`gRPC status code: ${grpcCode}`],
|
|
49
|
+
})
|
|
50
|
+
this.name = 'GrpcError'
|
|
51
|
+
this.grpcCode = grpcCode
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/** Request timed out. */
|
|
56
|
+
export class TimeoutError extends CantonjsError {
|
|
57
|
+
constructor(timeoutMs: number, options?: { cause?: Error }) {
|
|
58
|
+
super(`Request timed out after ${timeoutMs}ms`, {
|
|
59
|
+
code: 'CJ1004' as ErrorCode,
|
|
60
|
+
cause: options?.cause,
|
|
61
|
+
metaMessages: ['Consider increasing the timeout or checking network conditions.'],
|
|
62
|
+
})
|
|
63
|
+
this.name = 'TimeoutError'
|
|
64
|
+
}
|
|
65
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
// Clients
|
|
2
|
+
export {
|
|
3
|
+
createLedgerClient,
|
|
4
|
+
type LedgerClient,
|
|
5
|
+
type LedgerClientConfig,
|
|
6
|
+
type CommandOptions,
|
|
7
|
+
type QueryOptions,
|
|
8
|
+
type ConnectedSynchronizer,
|
|
9
|
+
type PrunedOffsets,
|
|
10
|
+
} from './clients/createLedgerClient.js'
|
|
11
|
+
|
|
12
|
+
export {
|
|
13
|
+
createAdminClient,
|
|
14
|
+
type AdminClient,
|
|
15
|
+
type AdminClientConfig,
|
|
16
|
+
type PaginationOptions,
|
|
17
|
+
type PaginatedResult,
|
|
18
|
+
} from './clients/createAdminClient.js'
|
|
19
|
+
|
|
20
|
+
export {
|
|
21
|
+
createTestClient,
|
|
22
|
+
type TestClient,
|
|
23
|
+
type TestClientConfig,
|
|
24
|
+
} from './clients/createTestClient.js'
|
|
25
|
+
|
|
26
|
+
// Transport
|
|
27
|
+
export { jsonApi } from './transport/json-api.js'
|
|
28
|
+
export { grpc, type GrpcTransportConfig, type GrpcTransportLike } from './transport/grpc.js'
|
|
29
|
+
export { fallback, type FallbackTransportConfig } from './transport/fallback.js'
|
|
30
|
+
export type { Transport, TransportConfig, TransportRequest } from './transport/types.js'
|
|
31
|
+
|
|
32
|
+
// Errors
|
|
33
|
+
export {
|
|
34
|
+
CantonjsError,
|
|
35
|
+
ConnectionError,
|
|
36
|
+
HttpError,
|
|
37
|
+
GrpcError,
|
|
38
|
+
TimeoutError,
|
|
39
|
+
CommandRejectedError,
|
|
40
|
+
ContractNotFoundError,
|
|
41
|
+
AuthorizationError,
|
|
42
|
+
TokenExpiredError,
|
|
43
|
+
InvalidTokenError,
|
|
44
|
+
WebSocketError,
|
|
45
|
+
StreamClosedError,
|
|
46
|
+
ReconnectFailedError,
|
|
47
|
+
} from './errors/index.js'
|
|
48
|
+
export type { ErrorCode, CantonjsErrorOptions } from './errors/base.js'
|
|
49
|
+
|
|
50
|
+
// Chains
|
|
51
|
+
export { localNet, devNet, testNet, mainNet, type CantonChain } from './chains/definitions.js'
|
|
52
|
+
|
|
53
|
+
// Core types
|
|
54
|
+
export type {
|
|
55
|
+
ContractId,
|
|
56
|
+
TemplateId,
|
|
57
|
+
CreatedEvent,
|
|
58
|
+
ArchivedEvent,
|
|
59
|
+
ExercisedEvent,
|
|
60
|
+
TaggedEvent,
|
|
61
|
+
ActiveContract,
|
|
62
|
+
ContractEntry,
|
|
63
|
+
} from './types/contract.js'
|
|
64
|
+
|
|
65
|
+
export type { Party, ObjectMeta, PartyDetails, AllocatePartyRequest } from './types/party.js'
|
|
66
|
+
|
|
67
|
+
export type {
|
|
68
|
+
LedgerOffset,
|
|
69
|
+
TaggedCommand,
|
|
70
|
+
JsCommands,
|
|
71
|
+
TransactionShape,
|
|
72
|
+
EventFormat,
|
|
73
|
+
TransactionFormat,
|
|
74
|
+
} from './types/command.js'
|
|
75
|
+
|
|
76
|
+
export type {
|
|
77
|
+
JsTransaction,
|
|
78
|
+
TaggedUpdate,
|
|
79
|
+
UpdateFormat,
|
|
80
|
+
} from './types/transaction.js'
|
|
81
|
+
|
|
82
|
+
export type { User, Right, RightKind, CreateUserRequest } from './types/user.js'
|
|
83
|
+
export type { PackageStatus, PackageDetails } from './types/package.js'
|
|
84
|
+
export type {
|
|
85
|
+
IdentityProviderConfig,
|
|
86
|
+
CreateIdentityProviderRequest,
|
|
87
|
+
UpdateIdentityProviderRequest,
|
|
88
|
+
} from './types/idp.js'
|
|
89
|
+
|
|
90
|
+
export type {
|
|
91
|
+
Reassignment,
|
|
92
|
+
ReassignmentEvent,
|
|
93
|
+
AssignedEvent,
|
|
94
|
+
UnassignedEvent,
|
|
95
|
+
ReassignmentCommand,
|
|
96
|
+
UnassignCommand,
|
|
97
|
+
AssignCommand,
|
|
98
|
+
} from './types/reassignment.js'
|
|
99
|
+
|
|
100
|
+
export type {
|
|
101
|
+
PrepareSubmissionResponse,
|
|
102
|
+
ExecuteSubmissionRequest,
|
|
103
|
+
PartySignatures,
|
|
104
|
+
Signature,
|
|
105
|
+
SignatureFormat,
|
|
106
|
+
} from './types/interactive.js'
|
|
107
|
+
|
|
108
|
+
// Streaming
|
|
109
|
+
export { streamUpdates } from './streaming/streamUpdates.js'
|
|
110
|
+
export { streamContracts, type ActiveContractsResponse } from './streaming/streamContracts.js'
|
|
111
|
+
export { streamCompletions } from './streaming/streamCompletions.js'
|
|
112
|
+
export { toWebSocketUrl } from './streaming/createStream.js'
|
|
113
|
+
export type {
|
|
114
|
+
WebSocketConstructor,
|
|
115
|
+
WebSocketLike,
|
|
116
|
+
ReconnectConfig,
|
|
117
|
+
StreamOptions,
|
|
118
|
+
StreamUpdatesOptions,
|
|
119
|
+
StreamContractsOptions,
|
|
120
|
+
StreamCompletionsOptions,
|
|
121
|
+
CompletionEvent,
|
|
122
|
+
} from './streaming/types.js'
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export {
|
|
2
|
+
createLedgerClient,
|
|
3
|
+
type LedgerClient,
|
|
4
|
+
type LedgerClientConfig,
|
|
5
|
+
type CommandOptions,
|
|
6
|
+
type QueryOptions,
|
|
7
|
+
} from '../clients/createLedgerClient.js'
|
|
8
|
+
|
|
9
|
+
export type {
|
|
10
|
+
ContractId,
|
|
11
|
+
TemplateId,
|
|
12
|
+
CreatedEvent,
|
|
13
|
+
ArchivedEvent,
|
|
14
|
+
ExercisedEvent,
|
|
15
|
+
TaggedEvent,
|
|
16
|
+
ActiveContract,
|
|
17
|
+
ContractEntry,
|
|
18
|
+
} from '../types/contract.js'
|
|
19
|
+
|
|
20
|
+
export type {
|
|
21
|
+
JsTransaction,
|
|
22
|
+
TaggedUpdate,
|
|
23
|
+
UpdateFormat,
|
|
24
|
+
} from '../types/transaction.js'
|
|
25
|
+
|
|
26
|
+
export type {
|
|
27
|
+
LedgerOffset,
|
|
28
|
+
TaggedCommand,
|
|
29
|
+
JsCommands,
|
|
30
|
+
TransactionShape,
|
|
31
|
+
EventFormat,
|
|
32
|
+
TransactionFormat,
|
|
33
|
+
} from '../types/command.js'
|
|
@@ -0,0 +1,321 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core AsyncIterable stream factory for Canton WebSocket connections.
|
|
3
|
+
*
|
|
4
|
+
* Creates a stream that:
|
|
5
|
+
* - Opens a WebSocket connection with Canton subprotocol auth
|
|
6
|
+
* - Sends a subscription request on connection open
|
|
7
|
+
* - Yields parsed JSON messages as an AsyncIterable
|
|
8
|
+
* - Auto-reconnects with exponential backoff on disconnect
|
|
9
|
+
* - Tracks offsets for gap-free resumption
|
|
10
|
+
* - Supports AbortSignal cancellation
|
|
11
|
+
*
|
|
12
|
+
* @see ADR 0005 — Streaming Architecture
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import type {
|
|
16
|
+
WebSocketConstructor,
|
|
17
|
+
WebSocketLike,
|
|
18
|
+
ReconnectConfig,
|
|
19
|
+
} from './types.js'
|
|
20
|
+
import { WebSocketError, StreamClosedError, ReconnectFailedError } from '../errors/streaming.js'
|
|
21
|
+
|
|
22
|
+
/** Internal configuration for createStream. */
|
|
23
|
+
export type CreateStreamConfig = {
|
|
24
|
+
/** Full WebSocket URL (ws:// or wss://). */
|
|
25
|
+
readonly url: string
|
|
26
|
+
/** JWT token for authentication. */
|
|
27
|
+
readonly token?: string
|
|
28
|
+
/** WebSocket constructor. */
|
|
29
|
+
readonly WebSocket?: WebSocketConstructor
|
|
30
|
+
/** AbortSignal for cancellation. */
|
|
31
|
+
readonly signal?: AbortSignal
|
|
32
|
+
/** Reconnect config, or false to disable. */
|
|
33
|
+
readonly reconnect?: ReconnectConfig | false
|
|
34
|
+
/** Build the subscription request body. Called on each (re)connection. */
|
|
35
|
+
readonly buildRequest: (lastOffset: number | undefined) => unknown
|
|
36
|
+
/** Extract an offset from a received message, if present. */
|
|
37
|
+
readonly extractOffset: (message: unknown) => number | undefined
|
|
38
|
+
/** Whether this is a bounded stream that ends on server close. */
|
|
39
|
+
readonly bounded?: boolean
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const DEFAULT_RECONNECT: Required<ReconnectConfig> = {
|
|
43
|
+
initialDelay: 1000,
|
|
44
|
+
maxDelay: 30000,
|
|
45
|
+
factor: 2,
|
|
46
|
+
jitter: 0.25,
|
|
47
|
+
maxAttempts: Infinity,
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Convert an HTTP(S) URL to a WebSocket URL.
|
|
52
|
+
* http://host → ws://host, https://host → wss://host
|
|
53
|
+
* If already ws/wss, return as-is.
|
|
54
|
+
*/
|
|
55
|
+
export function toWebSocketUrl(baseUrl: string, path: string): string {
|
|
56
|
+
const url = new URL(path, baseUrl)
|
|
57
|
+
if (url.protocol === 'https:') {
|
|
58
|
+
url.protocol = 'wss:'
|
|
59
|
+
} else if (url.protocol === 'http:') {
|
|
60
|
+
url.protocol = 'ws:'
|
|
61
|
+
}
|
|
62
|
+
return url.toString()
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Calculate reconnect delay with exponential backoff and jitter.
|
|
67
|
+
*/
|
|
68
|
+
export function calculateDelay(attempt: number, config: Required<ReconnectConfig>): number {
|
|
69
|
+
const baseDelay = Math.min(
|
|
70
|
+
config.initialDelay * Math.pow(config.factor, attempt),
|
|
71
|
+
config.maxDelay,
|
|
72
|
+
)
|
|
73
|
+
const jitterRange = baseDelay * config.jitter
|
|
74
|
+
const jitter = (Math.random() * 2 - 1) * jitterRange
|
|
75
|
+
return Math.max(0, baseDelay + jitter)
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Create a Canton WebSocket stream as an AsyncIterable.
|
|
80
|
+
*
|
|
81
|
+
* Each iteration yields a parsed JSON message from the WebSocket.
|
|
82
|
+
* The stream auto-reconnects on disconnect unless:
|
|
83
|
+
* - The AbortSignal is aborted
|
|
84
|
+
* - reconnect is set to false
|
|
85
|
+
* - The stream is bounded and the server closed normally (code 1000)
|
|
86
|
+
* - Max reconnect attempts are exhausted
|
|
87
|
+
*/
|
|
88
|
+
export function createStream<T>(config: CreateStreamConfig): AsyncIterable<T> {
|
|
89
|
+
return {
|
|
90
|
+
[Symbol.asyncIterator](): AsyncIterator<T> {
|
|
91
|
+
return new StreamIterator<T>(config)
|
|
92
|
+
},
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Internal AsyncIterator implementation.
|
|
98
|
+
*
|
|
99
|
+
* Uses a message queue with promise-based signaling to bridge the
|
|
100
|
+
* event-driven WebSocket API to the pull-based AsyncIterator protocol.
|
|
101
|
+
*/
|
|
102
|
+
class StreamIterator<T> implements AsyncIterator<T> {
|
|
103
|
+
private readonly config: CreateStreamConfig
|
|
104
|
+
private readonly reconnectConfig: Required<ReconnectConfig> | false
|
|
105
|
+
private ws: WebSocketLike | null = null
|
|
106
|
+
private lastOffset: number | undefined = undefined
|
|
107
|
+
private reconnectAttempts = 0
|
|
108
|
+
private done = false
|
|
109
|
+
private abortHandler: (() => void) | null = null
|
|
110
|
+
|
|
111
|
+
// Message queue for buffering received messages
|
|
112
|
+
private queue: T[] = []
|
|
113
|
+
// Error stored when fail() is called before next()
|
|
114
|
+
private storedError: Error | null = null
|
|
115
|
+
// Pending resolve/reject for when consumer is waiting
|
|
116
|
+
private pendingResolve: ((result: IteratorResult<T>) => void) | null = null
|
|
117
|
+
private pendingReject: ((error: Error) => void) | null = null
|
|
118
|
+
|
|
119
|
+
constructor(config: CreateStreamConfig) {
|
|
120
|
+
this.config = config
|
|
121
|
+
|
|
122
|
+
if (config.reconnect === false) {
|
|
123
|
+
this.reconnectConfig = false
|
|
124
|
+
} else {
|
|
125
|
+
this.reconnectConfig = { ...DEFAULT_RECONNECT, ...config.reconnect }
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
if (config.signal?.aborted) {
|
|
129
|
+
this.done = true
|
|
130
|
+
} else {
|
|
131
|
+
this.setupAbortHandler()
|
|
132
|
+
this.connect()
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
async next(): Promise<IteratorResult<T>> {
|
|
137
|
+
// If an error was stored before next() was called, throw it now
|
|
138
|
+
if (this.storedError) {
|
|
139
|
+
const error = this.storedError
|
|
140
|
+
this.storedError = null
|
|
141
|
+
throw error
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
if (this.done && this.queue.length === 0) {
|
|
145
|
+
return { done: true, value: undefined }
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// If there are queued messages, return immediately
|
|
149
|
+
if (this.queue.length > 0) {
|
|
150
|
+
return { done: false, value: this.queue.shift()! }
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// Wait for the next message, error, or close
|
|
154
|
+
return new Promise<IteratorResult<T>>((resolve, reject) => {
|
|
155
|
+
this.pendingResolve = resolve
|
|
156
|
+
this.pendingReject = reject
|
|
157
|
+
})
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
async return(): Promise<IteratorResult<T>> {
|
|
161
|
+
this.cleanup()
|
|
162
|
+
return { done: true, value: undefined }
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
async throw(error?: Error): Promise<IteratorResult<T>> {
|
|
166
|
+
this.cleanup()
|
|
167
|
+
throw error
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
private setupAbortHandler(): void {
|
|
171
|
+
if (!this.config.signal) return
|
|
172
|
+
|
|
173
|
+
this.abortHandler = () => {
|
|
174
|
+
this.cleanup()
|
|
175
|
+
if (this.pendingResolve) {
|
|
176
|
+
this.pendingResolve({ done: true, value: undefined })
|
|
177
|
+
this.pendingResolve = null
|
|
178
|
+
this.pendingReject = null
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
this.config.signal.addEventListener('abort', this.abortHandler)
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
private connect(): void {
|
|
185
|
+
if (this.done) return
|
|
186
|
+
|
|
187
|
+
const WS = this.config.WebSocket ?? (globalThis as Record<string, unknown>).WebSocket as WebSocketConstructor | undefined
|
|
188
|
+
if (!WS) {
|
|
189
|
+
const error = new WebSocketError(this.config.url, {
|
|
190
|
+
cause: new Error('No WebSocket implementation available. Provide a WebSocket constructor.'),
|
|
191
|
+
})
|
|
192
|
+
this.fail(error)
|
|
193
|
+
return
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
const protocols = this.config.token
|
|
197
|
+
? ['daml.ws.auth', `jwt.token.${this.config.token}`]
|
|
198
|
+
: undefined
|
|
199
|
+
|
|
200
|
+
let ws: WebSocketLike
|
|
201
|
+
try {
|
|
202
|
+
ws = new WS(this.config.url, protocols) as WebSocketLike
|
|
203
|
+
} catch (err) {
|
|
204
|
+
const error = new WebSocketError(this.config.url, {
|
|
205
|
+
cause: err instanceof Error ? err : new Error(String(err)),
|
|
206
|
+
})
|
|
207
|
+
this.fail(error)
|
|
208
|
+
return
|
|
209
|
+
}
|
|
210
|
+
this.ws = ws
|
|
211
|
+
|
|
212
|
+
ws.onopen = () => {
|
|
213
|
+
this.reconnectAttempts = 0
|
|
214
|
+
const request = this.config.buildRequest(this.lastOffset)
|
|
215
|
+
ws.send(JSON.stringify(request))
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
ws.onmessage = (event: { data: unknown }) => {
|
|
219
|
+
let message: T
|
|
220
|
+
try {
|
|
221
|
+
message = JSON.parse(String(event.data)) as T
|
|
222
|
+
} catch {
|
|
223
|
+
return // Skip non-JSON messages
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// Track offset for resumption
|
|
227
|
+
const offset = this.config.extractOffset(message)
|
|
228
|
+
if (offset !== undefined) {
|
|
229
|
+
this.lastOffset = offset
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
this.enqueue(message)
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
ws.onerror = () => {
|
|
236
|
+
// onerror is always followed by onclose, so we handle reconnection there
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
ws.onclose = (event: { code: number; reason: string }) => {
|
|
240
|
+
this.ws = null
|
|
241
|
+
|
|
242
|
+
// Normal close on bounded stream = stream complete
|
|
243
|
+
if (this.config.bounded && event.code === 1000) {
|
|
244
|
+
this.cleanup()
|
|
245
|
+
if (this.pendingResolve) {
|
|
246
|
+
this.pendingResolve({ done: true, value: undefined })
|
|
247
|
+
this.pendingResolve = null
|
|
248
|
+
this.pendingReject = null
|
|
249
|
+
}
|
|
250
|
+
return
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
// If already done (abort, return), don't reconnect
|
|
254
|
+
if (this.done) return
|
|
255
|
+
|
|
256
|
+
// Try to reconnect
|
|
257
|
+
if (this.reconnectConfig === false) {
|
|
258
|
+
const error = new StreamClosedError(event.code, event.reason)
|
|
259
|
+
this.fail(error)
|
|
260
|
+
return
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
if (this.reconnectAttempts >= this.reconnectConfig.maxAttempts) {
|
|
264
|
+
const error = new ReconnectFailedError(this.reconnectAttempts)
|
|
265
|
+
this.fail(error)
|
|
266
|
+
return
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
const delay = calculateDelay(this.reconnectAttempts, this.reconnectConfig)
|
|
270
|
+
this.reconnectAttempts++
|
|
271
|
+
|
|
272
|
+
setTimeout(() => {
|
|
273
|
+
if (!this.done) {
|
|
274
|
+
this.connect()
|
|
275
|
+
}
|
|
276
|
+
}, delay)
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
private enqueue(message: T): void {
|
|
281
|
+
if (this.pendingResolve) {
|
|
282
|
+
const resolve = this.pendingResolve
|
|
283
|
+
this.pendingResolve = null
|
|
284
|
+
this.pendingReject = null
|
|
285
|
+
resolve({ done: false, value: message })
|
|
286
|
+
} else {
|
|
287
|
+
this.queue.push(message)
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
private fail(error: Error): void {
|
|
292
|
+
this.done = true
|
|
293
|
+
if (this.pendingReject) {
|
|
294
|
+
const reject = this.pendingReject
|
|
295
|
+
this.pendingResolve = null
|
|
296
|
+
this.pendingReject = null
|
|
297
|
+
reject(error)
|
|
298
|
+
} else {
|
|
299
|
+
this.storedError = error
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
private cleanup(): void {
|
|
304
|
+
this.done = true
|
|
305
|
+
|
|
306
|
+
if (this.config.signal && this.abortHandler) {
|
|
307
|
+
this.config.signal.removeEventListener('abort', this.abortHandler)
|
|
308
|
+
this.abortHandler = null
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
if (this.ws) {
|
|
312
|
+
// Clear handlers before closing to prevent reconnect
|
|
313
|
+
this.ws.onopen = null
|
|
314
|
+
this.ws.onmessage = null
|
|
315
|
+
this.ws.onerror = null
|
|
316
|
+
this.ws.onclose = null
|
|
317
|
+
this.ws.close()
|
|
318
|
+
this.ws = null
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export { createStream, toWebSocketUrl, calculateDelay } from './createStream.js'
|
|
2
|
+
export type { CreateStreamConfig } from './createStream.js'
|
|
3
|
+
|
|
4
|
+
export { streamUpdates } from './streamUpdates.js'
|
|
5
|
+
export { streamContracts, type ActiveContractsResponse } from './streamContracts.js'
|
|
6
|
+
export { streamCompletions } from './streamCompletions.js'
|
|
7
|
+
|
|
8
|
+
export type {
|
|
9
|
+
WebSocketConstructor,
|
|
10
|
+
WebSocketLike,
|
|
11
|
+
ReconnectConfig,
|
|
12
|
+
StreamOptions,
|
|
13
|
+
StreamUpdatesOptions,
|
|
14
|
+
StreamContractsOptions,
|
|
15
|
+
StreamCompletionsOptions,
|
|
16
|
+
CompletionEvent,
|
|
17
|
+
} from './types.js'
|
|
18
|
+
|
|
19
|
+
export { WS_READY_STATE } from './types.js'
|