@distrohelena/canton-typescript-sdk 0.1.35 → 0.1.36
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
CHANGED
|
@@ -132,30 +132,63 @@ npm run example:topology:party-hosting
|
|
|
132
132
|
|
|
133
133
|
### Workflow examples
|
|
134
134
|
|
|
135
|
-
The
|
|
136
|
-
or verifies the fixture DAR, resolves a party, reads the
|
|
137
|
-
and creates its own run-scoped data. First make a Canton
|
|
138
|
-
and verify the source with `npm run examples:check`; the
|
|
139
|
-
authentication environment variables are documented below.
|
|
140
|
-
|
|
135
|
+
The seven workflow examples are standalone proofs, not a sequence:
|
|
136
|
+
each uploads or verifies the fixture DAR, resolves a party, reads the
|
|
137
|
+
participant status, and creates its own run-scoped data. First make a Canton
|
|
138
|
+
participant available and verify the source with `npm run examples:check`; the
|
|
139
|
+
default endpoints and authentication environment variables are documented below.
|
|
140
|
+
The pruning preflight is a separate read-only operator check and does none of
|
|
141
|
+
those setup or mutation steps. Run any example independently:
|
|
141
142
|
|
|
142
143
|
```bash
|
|
143
144
|
npm run example:workflow:atomic
|
|
144
145
|
npm run example:workflow:retry
|
|
145
146
|
npm run example:workflow:resume
|
|
146
147
|
npm run example:workflow:stale-contract
|
|
148
|
+
npm run example:workflow:command-completion
|
|
149
|
+
npm run example:workflow:contract-lifecycle-audit
|
|
150
|
+
npm run example:workflow:update-lookup-reconciliation
|
|
151
|
+
npm run example:workflow:pruning-preflight
|
|
147
152
|
```
|
|
148
153
|
|
|
149
|
-
|
|
154
|
+
Those seven established stateful workflows intentionally leave durable state behind. A missing `SDK_EXAMPLE_PARTY`
|
|
150
155
|
causes fallback party allocation, which creates durable topology state; every
|
|
151
|
-
|
|
152
|
-
party to rerun
|
|
153
|
-
fixture DAR remains installed after a run.
|
|
154
|
-
|
|
155
|
-
|
|
156
|
+
one also creates durable contracts. Set `SDK_EXAMPLE_PARTY` to an existing
|
|
157
|
+
party to rerun the established workflows against that party and avoid fallback
|
|
158
|
+
allocation. The fixture DAR remains installed after a run.
|
|
159
|
+
|
|
160
|
+
The completion-correlation workflow (`npm run example:workflow:command-completion`)
|
|
161
|
+
is a standalone successful proof that creates durable Message state. It uses the
|
|
162
|
+
same normal `SDK_EXAMPLE_*` configuration: `SDK_EXAMPLE_LEDGER_ENDPOINT`,
|
|
163
|
+
`SDK_EXAMPLE_LEDGER_ADMIN_ENDPOINT`, `SDK_EXAMPLE_PARTICIPANT_ADMIN_ENDPOINT`,
|
|
164
|
+
`SDK_EXAMPLE_BEARER_TOKEN`, `SDK_EXAMPLE_LEDGER_BEARER_TOKEN`,
|
|
165
|
+
`SDK_EXAMPLE_LEDGER_ADMIN_BEARER_TOKEN`,
|
|
166
|
+
`SDK_EXAMPLE_PARTICIPANT_ADMIN_BEARER_TOKEN`,
|
|
167
|
+
`SDK_EXAMPLE_TLS_ROOT_CERTIFICATE`, `SDK_EXAMPLE_PARTY`,
|
|
168
|
+
`SDK_EXAMPLE_PARTY_PREFIX`, and `SDK_EXAMPLE_TIMEOUT_MS`.
|
|
169
|
+
`SDK_EXAMPLE_USER_ID` is mandatory: absent or blank input is rejected, while
|
|
170
|
+
every nonblank value is preserved untrimmed and exactly submitted and exactly
|
|
171
|
+
matched in the completion. With bearer authentication, the configured declared
|
|
172
|
+
user must equal the token's Ledger API user/subject; the example does not inspect
|
|
173
|
+
the token. It keeps the ledger end as its saved exclusive offset and begins the
|
|
174
|
+
first stream read before submission.
|
|
175
|
+
No public wait-for-command-completion helper or API is introduced; the
|
|
176
|
+
correlation helper remains example-only.
|
|
177
|
+
The completion-correlation example asserts successful correlation only; it does
|
|
178
|
+
not assert rejected-command correlation. On both participant observations, the
|
|
179
|
+
stream-first rejected-command probes observed no exact completion before their
|
|
180
|
+
bounded stream transport errors.
|
|
181
|
+
|
|
182
|
+
The contract-lifecycle audit workflow (`npm run example:workflow:contract-lifecycle-audit`) is a standalone gRPC-only proof. It uses the normal `SDK_EXAMPLE_*` endpoint, authentication, party, and timeout configuration: `SDK_EXAMPLE_LEDGER_ENDPOINT`, `SDK_EXAMPLE_LEDGER_ADMIN_ENDPOINT`, `SDK_EXAMPLE_PARTICIPANT_ADMIN_ENDPOINT`, `SDK_EXAMPLE_BEARER_TOKEN`, `SDK_EXAMPLE_LEDGER_BEARER_TOKEN`, `SDK_EXAMPLE_LEDGER_ADMIN_BEARER_TOKEN`, `SDK_EXAMPLE_PARTICIPANT_ADMIN_BEARER_TOKEN`, `SDK_EXAMPLE_PARTY`, `SDK_EXAMPLE_PARTY_PREFIX`, and `SDK_EXAMPLE_TIMEOUT_MS`. An explicit `SDK_EXAMPLE_PARTY` is reused; otherwise fallback allocation creates durable topology. The fixture upload leaves a durable DAR, and the workflow leaves durable contracts. It uses the alpha ContractService to prove the original active Message before replacement and the replacement active Message afterward, then uses EventQuery for the original contract's create/archive history. It makes no post-archive ContractService claim for the original.
|
|
183
|
+
|
|
184
|
+
The update-lookup reconciliation workflow (`npm run example:workflow:update-lookup-reconciliation`) is a standalone gRPC-only proof that observes one exact self-party Message transaction from `UpdateService.GetUpdates`, then immediately reconciles it through `getUpdateById` and `getUpdateByOffset`. It uses the normal `SDK_EXAMPLE_*` endpoint, authentication, party, and timeout configuration, including `SDK_EXAMPLE_PARTY` and `SDK_EXAMPLE_TIMEOUT_MS`; first run `npm run examples:check` and make an authenticated participant available. An explicit party is reused, while fallback allocation creates durable topology; the fixture upload leaves a durable DAR and the workflow leaves durable contracts. The same unchanged implementation is tested against authenticated Participant 3.5.7 and the isolated Participant 3.5.8 sidecar, in default-party and explicit-party modes.
|
|
185
|
+
|
|
186
|
+
The pruning-preflight workflow (`npm run example:workflow:pruning-preflight`) is a standalone gRPC-only, read-only operator check. It requires `SDK_EXAMPLE_OFFSET` to be a canonical positive decimal integer and uses the normal endpoint, authentication, and timeout variables: `SDK_EXAMPLE_LEDGER_ENDPOINT`, `SDK_EXAMPLE_LEDGER_ADMIN_ENDPOINT`, `SDK_EXAMPLE_PARTICIPANT_ADMIN_ENDPOINT`, `SDK_EXAMPLE_BEARER_TOKEN`, `SDK_EXAMPLE_LEDGER_BEARER_TOKEN`, `SDK_EXAMPLE_LEDGER_ADMIN_BEARER_TOKEN`, `SDK_EXAMPLE_PARTICIPANT_ADMIN_BEARER_TOKEN`, and `SDK_EXAMPLE_TIMEOUT_MS`. The participant-admin credential is required for the schedule and safe-pruning context reads. Its safe-pruning context request sends the saved ledger end and a validated current timestamp encoded in `beforeOrAt`; it leaves commitment-state absent. It does not mutate the participant or create durable state: no party, DAR, command, update query, schedule change, or pruning request is made. The later participant watermark classifies the supplied offset as `alreadyPruned`, `beyondLedgerEnd`, or `notObservedPruned`; all-divulged watermarks and schedule/safe-pruning context are reported separately and do not alter that result. `notObservedPruned` is not proven queryable, because pruning can race after the later observation and other query preconditions can still fail. The unchanged implementation is supported on Participant 3.5.7 and the isolated Participant 3.5.8 sidecar.
|
|
187
|
+
|
|
188
|
+
Each of the seven established stateful workflows prints its actor plus the full participant version returned by the
|
|
156
189
|
authenticated status API, its parsed release core, and its selected path:
|
|
157
190
|
`Participant version:`, `Release core:`, and `Compatibility path:`. The current
|
|
158
|
-
implementation uses one common-code path for release cores 3.5.7 and 3.5.8. It
|
|
191
|
+
stateful-workflow implementation uses one common-code path for release cores 3.5.7 and 3.5.8. It
|
|
159
192
|
adds a version-specific behavioral difference only after live evidence proves
|
|
160
193
|
one; it does not infer compatibility from a container tag or endpoint.
|
|
161
194
|
|
|
@@ -179,15 +212,15 @@ request and is not a retry proof. The resume example treats the saved offset as
|
|
|
179
212
|
exclusive, so its resumed stream must observe only updates after the saved
|
|
180
213
|
ledger end.
|
|
181
214
|
|
|
182
|
-
The workflow
|
|
183
|
-
authenticated Participant 3.5.7 and the isolated
|
|
184
|
-
final-tree matrices selected the same unchanged implementation and common
|
|
215
|
+
The seven established stateful workflow sources and unit contracts were developed
|
|
216
|
+
and live-tested against authenticated Participant 3.5.7 and the isolated
|
|
217
|
+
Participant 3.5.8. Both final-tree matrices selected the same unchanged implementation and common
|
|
185
218
|
compatibility path. The normalized outcome comparison is identical: atomic
|
|
186
219
|
reports `invalidChoice` before its replacement proof, retry reports
|
|
187
220
|
`duplicateCommand` with one active contract, resume reports `idle-timeout` and
|
|
188
221
|
a post-offset update, and stale-contract reports `staleContract`.
|
|
189
222
|
|
|
190
|
-
|
|
223
|
+
For those seven established stateful workflows, the best multi-version path reads the authenticated full version, parses its
|
|
191
224
|
release core, and uses data-only structured compatibility for observed
|
|
192
225
|
outcomes. A behavioral difference is introduced only after live proof; it is
|
|
193
226
|
never inferred from a container tag, endpoint, or prose error message. For the
|
|
@@ -555,7 +588,11 @@ const contracts = await client.stateService.getActiveContractsPageAsync(
|
|
|
555
588
|
);
|
|
556
589
|
```
|
|
557
590
|
|
|
558
|
-
`stateService.getActiveContractsPageAsync(...)` accepts the generated Ledger API request
|
|
591
|
+
`stateService.getActiveContractsPageAsync(...)` is gRPC-only and accepts the generated Ledger API request, including its `eventFormat`, `activeAtOffset`, `maxPageSize`, and `pageToken` fields. Build party, template, and interface filters in `eventFormat`.
|
|
592
|
+
|
|
593
|
+
`stateService.getActiveContractsPagesAsync(...)` is the gRPC-only lazy, raw, bounded traversal API. It starts from the same generated request and yields raw `GetActiveContractsPageResponse` values one page at a time. The caller selects the shared `OperationDeadline`, maximum pages, and maximum contracts with `ActiveContractsTraversalOptions`; there is no collect-all wrapper. Transport errors from dispatched RPCs propagate unchanged. Traversal safety, invariant, and bound failures use `ActiveContractsTraversalError` codes, such as an inconsistent offset, repeated page token, or exceeded bound.
|
|
594
|
+
|
|
595
|
+
JSON does not implement either paginated gRPC API. Its existing `stateService.getActiveContractsAsync(...)` behavior remains the distinct JSON streaming read.
|
|
559
596
|
|
|
560
597
|
For interface views, do not use `contractService.getContractAsync(...)`. That contract lookup surface cannot return interface views; use `stateService` or `updateService` instead.
|
|
561
598
|
|
|
@@ -703,11 +740,12 @@ unsupported query features reject with `QueryCapabilityError`.
|
|
|
703
740
|
- `commandService.submitAndWaitAsync(...)`: `json`, `grpc`
|
|
704
741
|
- `commandSubmissionService.submitAsync(...)`: reserved, currently unsupported
|
|
705
742
|
- `stateService.getActiveContractsPageAsync(...)`: `grpc` only
|
|
706
|
-
- `stateService.
|
|
743
|
+
- `stateService.getActiveContractsPagesAsync(...)`: `grpc` only, lazy raw bounded traversal
|
|
744
|
+
- `stateService.getActiveContractsAsync(...)`: `json` only, existing distinct streaming read
|
|
707
745
|
- `updateService.getUpdatesAsync(...)`: `grpc` only
|
|
708
|
-
- `commandCompletionService`:
|
|
709
|
-
- `eventQueryService`:
|
|
710
|
-
- `contractService`:
|
|
746
|
+
- `commandCompletionService.getCompletionsAsync(...)`: `grpc` only, existing streaming API
|
|
747
|
+
- `eventQueryService.getEventsByContractIdAsync(...)`: `grpc` only; JSON rejects this request
|
|
748
|
+
- `contractService.getContractAsync(...)`: `grpc` only; JSON rejects this request
|
|
711
749
|
|
|
712
750
|
- Ledger Admin endpoint:
|
|
713
751
|
- `partyManagementService.allocatePartyAsync(...)`: `json`, `grpc`
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.StateServiceClient = void 0;
|
|
4
|
+
const active_contracts_traversal_error_js_1 = require("../../core/errors/active-contracts-traversal-error.js");
|
|
5
|
+
const validation_error_js_1 = require("../../core/errors/validation-error.js");
|
|
4
6
|
class StateServiceClient {
|
|
5
7
|
transport;
|
|
6
8
|
constructor(transport) {
|
|
@@ -11,6 +13,10 @@ class StateServiceClient {
|
|
|
11
13
|
getActiveContractsPageAsync(request, options) {
|
|
12
14
|
return this.transport.getActiveContractsPageAsync(request, options);
|
|
13
15
|
}
|
|
16
|
+
/** Reads active-contract pages lazily. Supported on gRPC; JSON rejects it. */
|
|
17
|
+
getActiveContractsPagesAsync(request, options) {
|
|
18
|
+
return this.getActiveContractsPagesLazy(request, options);
|
|
19
|
+
}
|
|
14
20
|
/** Reads active contracts as a stream. JSON-backed; gRPC currently rejects it. */
|
|
15
21
|
getActiveContractsAsync(request, observer, options) {
|
|
16
22
|
return this.transport.getActiveContractsAsync(request, observer, options);
|
|
@@ -27,5 +33,55 @@ class StateServiceClient {
|
|
|
27
33
|
getLatestPrunedOffsetsAsync(request, options) {
|
|
28
34
|
return this.transport.getLatestPrunedOffsetsAsync(request, options);
|
|
29
35
|
}
|
|
36
|
+
async *getActiveContractsPagesLazy(request, options) {
|
|
37
|
+
if (request.pageToken && request.pageToken.length > 0) {
|
|
38
|
+
throw new validation_error_js_1.ValidationError("active contracts traversal must not start with a page token");
|
|
39
|
+
}
|
|
40
|
+
let pageRequest = request;
|
|
41
|
+
let pagesRead = 0;
|
|
42
|
+
let contractsRead = 0;
|
|
43
|
+
let activeAtOffset;
|
|
44
|
+
const observedPageTokens = new Set();
|
|
45
|
+
while (true) {
|
|
46
|
+
if (pagesRead >= options.maxPages) {
|
|
47
|
+
throw new active_contracts_traversal_error_js_1.ActiveContractsTraversalError("max-pages-exceeded", "active contracts traversal exceeded maxPages");
|
|
48
|
+
}
|
|
49
|
+
const response = await this.transport.getActiveContractsPageAsync(pageRequest, options.deadline.createRequestOptions());
|
|
50
|
+
pagesRead += 1;
|
|
51
|
+
if (typeof response.activeAtOffset !== "string" ||
|
|
52
|
+
response.activeAtOffset.trim().length === 0) {
|
|
53
|
+
throw new active_contracts_traversal_error_js_1.ActiveContractsTraversalError("missing-active-at-offset", "active contracts response is missing activeAtOffset");
|
|
54
|
+
}
|
|
55
|
+
else if (activeAtOffset === undefined) {
|
|
56
|
+
if (request.activeAtOffset !== undefined &&
|
|
57
|
+
request.activeAtOffset !== response.activeAtOffset) {
|
|
58
|
+
throw new active_contracts_traversal_error_js_1.ActiveContractsTraversalError("active-at-offset-mismatch", "active contracts response activeAtOffset does not match the request");
|
|
59
|
+
}
|
|
60
|
+
activeAtOffset = response.activeAtOffset;
|
|
61
|
+
}
|
|
62
|
+
else if (activeAtOffset !== response.activeAtOffset) {
|
|
63
|
+
throw new active_contracts_traversal_error_js_1.ActiveContractsTraversalError("active-at-offset-mismatch", "active contracts response activeAtOffset changed during traversal");
|
|
64
|
+
}
|
|
65
|
+
contractsRead += response.activeContracts.length;
|
|
66
|
+
if (contractsRead > options.maxContracts) {
|
|
67
|
+
throw new active_contracts_traversal_error_js_1.ActiveContractsTraversalError("max-contracts-exceeded", "active contracts traversal exceeded maxContracts");
|
|
68
|
+
}
|
|
69
|
+
yield response;
|
|
70
|
+
if (!response.nextPageToken || response.nextPageToken.length === 0) {
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
const pageTokenKey = Array.from(response.nextPageToken).join(",");
|
|
74
|
+
if (observedPageTokens.has(pageTokenKey)) {
|
|
75
|
+
throw new active_contracts_traversal_error_js_1.ActiveContractsTraversalError("repeated-page-token", "active contracts traversal received a repeated page token");
|
|
76
|
+
}
|
|
77
|
+
observedPageTokens.add(pageTokenKey);
|
|
78
|
+
pageRequest = {
|
|
79
|
+
activeAtOffset,
|
|
80
|
+
eventFormat: request.eventFormat,
|
|
81
|
+
maxPageSize: request.maxPageSize,
|
|
82
|
+
pageToken: response.nextPageToken,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
}
|
|
30
86
|
}
|
|
31
87
|
exports.StateServiceClient = StateServiceClient;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ITransport } from "../../core/transports/transport.interface.js";
|
|
2
|
+
import { ActiveContractsTraversalOptions } from "../../core/types/active-contracts-traversal-options.js";
|
|
2
3
|
import { RequestOptions } from "../../core/types/request-options.js";
|
|
3
4
|
import { GetActiveContractsRequest } from "../../core/types/requests/get-active-contracts-request.js";
|
|
4
5
|
import type { GetActiveContractsPageRequest, GetActiveContractsPageResponse, GetConnectedSynchronizersRequest, GetConnectedSynchronizersResponse, GetLedgerEndRequest, GetLedgerEndResponse, GetLatestPrunedOffsetsRequest, GetLatestPrunedOffsetsResponse } from "../../transports/grpc/generated/canton/com/daml/ledger/api/v2/state_service.js";
|
|
@@ -8,6 +9,8 @@ export declare class StateServiceClient {
|
|
|
8
9
|
constructor(transport: ITransport);
|
|
9
10
|
/** Reads a page of active contracts. Supported on gRPC; JSON rejects it. */
|
|
10
11
|
getActiveContractsPageAsync(request: GetActiveContractsPageRequest, options?: RequestOptions): Promise<GetActiveContractsPageResponse>;
|
|
12
|
+
/** Reads active-contract pages lazily. Supported on gRPC; JSON rejects it. */
|
|
13
|
+
getActiveContractsPagesAsync(request: GetActiveContractsPageRequest, options: ActiveContractsTraversalOptions): AsyncIterable<GetActiveContractsPageResponse>;
|
|
11
14
|
/** Reads active contracts as a stream. JSON-backed; gRPC currently rejects it. */
|
|
12
15
|
getActiveContractsAsync(request: GetActiveContractsRequest, observer: ContractObserver, options?: RequestOptions): Promise<void>;
|
|
13
16
|
/** Reads connected synchronizers. Supported on gRPC; JSON rejects it. */
|
|
@@ -16,4 +19,5 @@ export declare class StateServiceClient {
|
|
|
16
19
|
getLedgerEndAsync(request: GetLedgerEndRequest, options?: RequestOptions): Promise<GetLedgerEndResponse>;
|
|
17
20
|
/** Reads the latest participant pruning offsets. Supported on gRPC; JSON rejects it. */
|
|
18
21
|
getLatestPrunedOffsetsAsync(request: GetLatestPrunedOffsetsRequest, options?: RequestOptions): Promise<GetLatestPrunedOffsetsResponse>;
|
|
22
|
+
private getActiveContractsPagesLazy;
|
|
19
23
|
}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { ActiveContractsTraversalError } from "../../core/errors/active-contracts-traversal-error.js";
|
|
2
|
+
import { ValidationError } from "../../core/errors/validation-error.js";
|
|
1
3
|
export class StateServiceClient {
|
|
2
4
|
transport;
|
|
3
5
|
constructor(transport) {
|
|
@@ -8,6 +10,10 @@ export class StateServiceClient {
|
|
|
8
10
|
getActiveContractsPageAsync(request, options) {
|
|
9
11
|
return this.transport.getActiveContractsPageAsync(request, options);
|
|
10
12
|
}
|
|
13
|
+
/** Reads active-contract pages lazily. Supported on gRPC; JSON rejects it. */
|
|
14
|
+
getActiveContractsPagesAsync(request, options) {
|
|
15
|
+
return this.getActiveContractsPagesLazy(request, options);
|
|
16
|
+
}
|
|
11
17
|
/** Reads active contracts as a stream. JSON-backed; gRPC currently rejects it. */
|
|
12
18
|
getActiveContractsAsync(request, observer, options) {
|
|
13
19
|
return this.transport.getActiveContractsAsync(request, observer, options);
|
|
@@ -24,4 +30,54 @@ export class StateServiceClient {
|
|
|
24
30
|
getLatestPrunedOffsetsAsync(request, options) {
|
|
25
31
|
return this.transport.getLatestPrunedOffsetsAsync(request, options);
|
|
26
32
|
}
|
|
33
|
+
async *getActiveContractsPagesLazy(request, options) {
|
|
34
|
+
if (request.pageToken && request.pageToken.length > 0) {
|
|
35
|
+
throw new ValidationError("active contracts traversal must not start with a page token");
|
|
36
|
+
}
|
|
37
|
+
let pageRequest = request;
|
|
38
|
+
let pagesRead = 0;
|
|
39
|
+
let contractsRead = 0;
|
|
40
|
+
let activeAtOffset;
|
|
41
|
+
const observedPageTokens = new Set();
|
|
42
|
+
while (true) {
|
|
43
|
+
if (pagesRead >= options.maxPages) {
|
|
44
|
+
throw new ActiveContractsTraversalError("max-pages-exceeded", "active contracts traversal exceeded maxPages");
|
|
45
|
+
}
|
|
46
|
+
const response = await this.transport.getActiveContractsPageAsync(pageRequest, options.deadline.createRequestOptions());
|
|
47
|
+
pagesRead += 1;
|
|
48
|
+
if (typeof response.activeAtOffset !== "string" ||
|
|
49
|
+
response.activeAtOffset.trim().length === 0) {
|
|
50
|
+
throw new ActiveContractsTraversalError("missing-active-at-offset", "active contracts response is missing activeAtOffset");
|
|
51
|
+
}
|
|
52
|
+
else if (activeAtOffset === undefined) {
|
|
53
|
+
if (request.activeAtOffset !== undefined &&
|
|
54
|
+
request.activeAtOffset !== response.activeAtOffset) {
|
|
55
|
+
throw new ActiveContractsTraversalError("active-at-offset-mismatch", "active contracts response activeAtOffset does not match the request");
|
|
56
|
+
}
|
|
57
|
+
activeAtOffset = response.activeAtOffset;
|
|
58
|
+
}
|
|
59
|
+
else if (activeAtOffset !== response.activeAtOffset) {
|
|
60
|
+
throw new ActiveContractsTraversalError("active-at-offset-mismatch", "active contracts response activeAtOffset changed during traversal");
|
|
61
|
+
}
|
|
62
|
+
contractsRead += response.activeContracts.length;
|
|
63
|
+
if (contractsRead > options.maxContracts) {
|
|
64
|
+
throw new ActiveContractsTraversalError("max-contracts-exceeded", "active contracts traversal exceeded maxContracts");
|
|
65
|
+
}
|
|
66
|
+
yield response;
|
|
67
|
+
if (!response.nextPageToken || response.nextPageToken.length === 0) {
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
const pageTokenKey = Array.from(response.nextPageToken).join(",");
|
|
71
|
+
if (observedPageTokens.has(pageTokenKey)) {
|
|
72
|
+
throw new ActiveContractsTraversalError("repeated-page-token", "active contracts traversal received a repeated page token");
|
|
73
|
+
}
|
|
74
|
+
observedPageTokens.add(pageTokenKey);
|
|
75
|
+
pageRequest = {
|
|
76
|
+
activeAtOffset,
|
|
77
|
+
eventFormat: request.eventFormat,
|
|
78
|
+
maxPageSize: request.maxPageSize,
|
|
79
|
+
pageToken: response.nextPageToken,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
}
|
|
27
83
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@distrohelena/canton-typescript-sdk",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.36",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -98,6 +98,10 @@
|
|
|
98
98
|
"example:workflow:retry": "npm run build && node --loader ts-node/esm examples/91-idempotent-command-retry.ts",
|
|
99
99
|
"example:workflow:resume": "npm run build && node --loader ts-node/esm examples/92-resume-update-stream.ts",
|
|
100
100
|
"example:workflow:stale-contract": "npm run build && node --loader ts-node/esm examples/93-archive-and-stale-contract.ts",
|
|
101
|
+
"example:workflow:command-completion": "npm run build && node --loader ts-node/esm examples/94-command-completion-correlation.ts",
|
|
102
|
+
"example:workflow:contract-lifecycle-audit": "npm run build && node --loader ts-node/esm examples/95-contract-lifecycle-audit.ts",
|
|
103
|
+
"example:workflow:update-lookup-reconciliation": "npm run build && node --loader ts-node/esm examples/96-update-lookup-reconciliation.ts",
|
|
104
|
+
"example:workflow:pruning-preflight": "npm run build && node --loader ts-node/esm examples/97-pruning-preflight.ts",
|
|
101
105
|
"lint": "eslint . --max-warnings=0",
|
|
102
106
|
"lint:fix": "eslint . --fix --max-warnings=0",
|
|
103
107
|
"start:local-ledger": "bash node/start-local.sh",
|