@registrystack/client 0.31.0 → 0.33.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -34,7 +34,8 @@ const work = new casework.CaseworkClient({
34
34
  - `evidence`: Evidence Gateway, request and verify signed minimum-disclosure
35
35
  assertions.
36
36
  - `relay`: Registry Relay, scoped read-only APIs over existing sources.
37
- - `breg`: Base Registry Engine, records, contracts, writes, and lifecycle.
37
+ - `breg`: Base Registry Engine, records, contracts, writes, lifecycle, and typed
38
+ applied-request result navigation.
38
39
  - `casework`: Registry Casework, staff inbox, claims, drafts, decisions,
39
40
  recovery, history, holdings, and directory bootstrap.
40
41
 
package/breg/client.d.ts CHANGED
@@ -87,9 +87,47 @@ export class PrivateKeyJwt {
87
87
  bearerToken(): Promise<string>
88
88
  }
89
89
 
90
+ /** One immutable verified person or grant context. Reconstruct after host source facts change. */
91
+ export interface ExchangeContext {
92
+ issuer: string
93
+ subject: string
94
+ audience: string
95
+ generation: string
96
+ deadlineSeconds: SafeInteger
97
+ grantId?: string | null
98
+ }
99
+
100
+ export type ExchangePrivateKeyJwtConfig = PrivateKeyJwtConfig & {
101
+ resource: string
102
+ scopes: ReadonlyArray<string>
103
+ }
104
+
105
+ export interface FirstPartyExchangeSource {
106
+ key: PrivateJwk
107
+ /** Reviewed host attributes; registry_actor_kind must be human and grant claims are refused. */
108
+ attributes: Readonly<Record<string, JsonValue>>
109
+ }
110
+
111
+ export interface RemoteExchangeSource {
112
+ /** Exact assertion URL supplied by the authority client, such as Casework.taskAssertionEndpoint. */
113
+ endpoint: string
114
+ bootstrap: ExchangePrivateKeyJwtConfig
115
+ bootstrapResource: string
116
+ bootstrapScope: string
117
+ requestTimeoutMilliseconds?: SafeInteger | null
118
+ connectTimeoutMilliseconds?: SafeInteger | null
119
+ userAgent?: string | null
120
+ trustedRootCertificates?: string | null
121
+ }
122
+
123
+ export type ExchangeAuthorizationConfig =
124
+ | { client: ExchangePrivateKeyJwtConfig; context: ExchangeContext; firstParty: FirstPartyExchangeSource }
125
+ | { client: ExchangePrivateKeyJwtConfig; context: ExchangeContext; remote: RemoteExchangeSource }
126
+
90
127
  export type BaseRegistryAuthorization =
91
128
  | { static: string }
92
129
  | { privateKeyJwt: PrivateKeyJwtConfig }
130
+ | { exchange: ExchangeAuthorizationConfig }
93
131
 
94
132
  export interface BaseRegistryClientConfig {
95
133
  baseUrl: string
@@ -178,33 +216,54 @@ export interface RegistryRecord {
178
216
  readonly [member: string]: JsonValue | undefined
179
217
  }
180
218
 
181
- export type BRegRequestReviewStage = JsonObject & {
182
- readonly id: string
183
- readonly approvals: SafeInteger
184
- readonly excludeSubmitter: boolean
185
- readonly excludePreviousReviewers?: boolean
186
- }
187
- export type BRegRequestReviewState = JsonObject & {
188
- readonly stages: ReadonlyArray<BRegRequestReviewStage>
189
- readonly submittedAt: string
190
- readonly pendingStage: string | null
191
- readonly stageEnteredAt: string | null
192
- }
193
- export type BRegRequestReviewTiming = JsonObject & {
194
- readonly firstSubmittedAt: string
195
- readonly pausedMilliseconds: SafeInteger
196
- readonly pauseStartedAt: string | null
197
- readonly completedAt: string | null
198
- }
199
- export type BRegRequestDecision = JsonObject & {
200
- readonly stageId: string
201
- readonly kind: 'approve' | 'reject' | 'request_revision'
202
- readonly decidedAt: string
203
- readonly reasonPresent: boolean
204
- readonly reason?: string
205
- readonly actorReference?: string
206
- }
207
- export type BRegRequestState = 'draft' | 'submitted' | 'approved' | 'needs_changes' | 'rejected' | 'canceled' | 'applied'
219
+ export type BRegRequestResultReferenceData = JsonObject & {
220
+ readonly targetEntityId: string
221
+ readonly targetRecordId: string
222
+ /** Revision written by the application, not a current ETag or precondition. */
223
+ readonly targetRevision: SafeInteger
224
+ }
225
+ export type BRegRequestState = 'draft' | 'submitted' | 'cancelled' | 'applied' | 'superseded'
226
+ export type BRegRequestReviewRequirement =
227
+ | Readonly<{ mode: 'none' }>
228
+ | Readonly<{ authority: string; policyId: string }>
229
+ export type BRegExternalReviewStatus = Readonly<{
230
+ submission: Readonly<{
231
+ state: 'pending' | 'accepted' | 'uncertain' | 'cancelling' | 'cancelled' | 'failed'
232
+ authority: string
233
+ requestId?: string
234
+ submissionDigest?: string
235
+ /** Fixed recovery deadline for the durable submission. */
236
+ recoveryDeadline?: string
237
+ policy?: Readonly<{ id: string; version: string; digest: string }>
238
+ }>
239
+ result: Readonly<{
240
+ state: 'pending' | 'approved' | 'rejected' | 'changesRequested' | 'answered' | 'cancelled' | 'superseded'
241
+ resultId?: string
242
+ completedAt?: string
243
+ availableUntil?: string
244
+ }>
245
+ delivery: Readonly<{
246
+ state: 'polling' | 'received' | 'reconciled' | 'unmatched' | 'exhausted'
247
+ eventId?: string
248
+ receivedAt?: string
249
+ }>
250
+ application: Readonly<{
251
+ mode: 'manual' | 'automatic'
252
+ state: 'awaitingReview' | 'ready' | 'queued' | 'applying' | 'applied' | 'blocked'
253
+ executor?: string
254
+ applicationId?: string
255
+ /** Durable automatic-application attempts, from 0 through 1000. */
256
+ attempts?: SafeInteger
257
+ /** Present only while an automatic application is queued or applying. */
258
+ nextAttemptAt?: string
259
+ /** Present when the applied receipt was recovered from already-applied source state. */
260
+ receiptRecovered?: true
261
+ }>
262
+ recovery: Readonly<{
263
+ state: 'none' | 'operatorAttention'
264
+ code?: string
265
+ }>
266
+ }>
208
267
  export type BRegRetainedRequestProposal = JsonObject & {
209
268
  readonly requestEntityId: string
210
269
  readonly requestId: string
@@ -215,9 +274,9 @@ export type BRegRetainedRequestProposal = JsonObject & {
215
274
  readonly detailErased: boolean
216
275
  readonly applicationId: string | null
217
276
  readonly resultLinkCount: SafeInteger
218
- readonly resultLinks: ReadonlyArray<JsonObject>
277
+ readonly resultLinks: ReadonlyArray<BRegRequestResultReferenceData>
219
278
  readonly effectDigest?: string
220
- readonly decisions?: ReadonlyArray<BRegRequestDecision>
279
+ readonly proposal?: Readonly<{ review: BRegRequestReviewRequirement }>
221
280
  }
222
281
  export type BRegRetainedRequestHistory = JsonObject & {
223
282
  readonly proposals: ReadonlyArray<BRegRetainedRequestProposal>
@@ -227,17 +286,15 @@ export type BRegRequestMetadata = JsonObject & {
227
286
  readonly bregState: BRegRequestState
228
287
  readonly proposalVersion: SafeInteger
229
288
  readonly effectDigest?: string | null
230
- readonly proposal?: JsonObject | null
289
+ readonly proposal?: Readonly<{ review: BRegRequestReviewRequirement }> | null
231
290
  readonly editable: boolean
232
291
  readonly detailErased?: true
233
292
  readonly actions?: ReadonlyArray<JsonObject>
234
293
  readonly application?: JsonObject | null
235
- readonly history?: BRegRetainedRequestHistory
236
- readonly review?: BRegRequestReviewState
237
- readonly reviewTiming?: BRegRequestReviewTiming
294
+ readonly history?: BRegRetainedRequestHistory | null
295
+ readonly review?: BRegExternalReviewStatus
238
296
  readonly submitterReference?: string
239
297
  readonly applierReference?: string
240
- readonly decisions?: ReadonlyArray<BRegRequestDecision>
241
298
  }
242
299
 
243
300
  export interface RecordMetadata {
@@ -305,17 +362,6 @@ export interface RemovePatchOperation {
305
362
  field: string
306
363
  }
307
364
 
308
- export interface LifecycleReviewTarget {
309
- entityIdentifier: string
310
- recordIdentifier: string
311
- operation: 'create' | 'patch'
312
- baseRevision?: SafeInteger
313
- before?: Readonly<Record<string, JsonValue>>
314
- after: Readonly<Record<string, JsonValue>>
315
- }
316
-
317
- export interface LifecycleReview { targets: ReadonlyArray<LifecycleReviewTarget> }
318
-
319
365
  export type LifecycleReceipt = JsonObject & {
320
366
  readonly id: string
321
367
  readonly revision: SafeInteger
@@ -554,6 +600,132 @@ export interface BRegBatchReceipt {
554
600
  }>
555
601
  }
556
602
 
603
+ export type BRegIngestionOperation = 'create' | 'patch'
604
+ export type BRegIngestionRunStatus = 'open' | 'complete' | 'cancelled' | 'blocked'
605
+ export type BRegIngestionAttemptOutcome =
606
+ | 'committed'
607
+ | 'replayed'
608
+ | 'invalidItem'
609
+ | 'refused'
610
+ | 'bindingChanged'
611
+ | 'chunkMismatch'
612
+ | 'runNotOpen'
613
+ | 'unavailable'
614
+
615
+ /** The whole-input announcement that opens one durable ingestion run. */
616
+ export interface BRegIngestionRunInput {
617
+ operation: BRegIngestionOperation
618
+ profileId: string
619
+ packageRevision: string
620
+ schemaFingerprint: string
621
+ /** Lowercase SHA-256 of the complete raw source input. */
622
+ inputDigest: string
623
+ inputLength: SafeInteger
624
+ itemCount: SafeInteger
625
+ chunkCount: SafeInteger
626
+ /** The only accepted value is `greedy-canonical-http-batch-v1`. */
627
+ chunkAlgorithmVersion: string
628
+ }
629
+
630
+ export interface BRegIngestionRunListInput {
631
+ accessProfile?: string | null
632
+ limit?: SafeInteger | null
633
+ after?: string | null
634
+ status?: BRegIngestionRunStatus | null
635
+ inputDigest?: string | null
636
+ }
637
+
638
+ export interface BRegIngestionAttempt {
639
+ readonly outcome: BRegIngestionAttemptOutcome
640
+ readonly chunkIndex: SafeInteger | null
641
+ }
642
+
643
+ /** Value-free durable state of one ingestion run: no source rows, no record values. */
644
+ export interface BRegIngestionRun {
645
+ readonly runId: string
646
+ readonly status: BRegIngestionRunStatus
647
+ readonly blockedReason: string | null
648
+ readonly entityId: string
649
+ readonly operation: BRegIngestionOperation
650
+ readonly profileId: string
651
+ readonly packageRevision: string
652
+ readonly schemaFingerprint: string
653
+ readonly inputDigest: string
654
+ readonly inputLength: SafeInteger
655
+ readonly itemCount: SafeInteger
656
+ readonly chunkCount: SafeInteger
657
+ readonly chunkAlgorithmVersion: string
658
+ readonly maximumItems: SafeInteger
659
+ readonly maximumBytes: SafeInteger
660
+ readonly nextChunkIndex: SafeInteger
661
+ readonly committedItems: SafeInteger
662
+ readonly committedPrefixDigest: string
663
+ readonly lastAttempt: BRegIngestionAttempt | null
664
+ readonly createdAt: string
665
+ readonly updatedAt: string
666
+ readonly complete: boolean
667
+ }
668
+
669
+ export interface BRegIngestionRunPage {
670
+ readonly runs: ReadonlyArray<BRegIngestionRun>
671
+ readonly hasMore: boolean
672
+ readonly nextAfter: string | null
673
+ }
674
+
675
+ export interface BRegIngestionReceiptBatch {
676
+ readonly snapshot: string
677
+ readonly results: ReadonlyArray<JsonObject>
678
+ }
679
+
680
+ export interface BRegIngestionChunkReceipt {
681
+ readonly chunkIndex: SafeInteger
682
+ readonly digest: string
683
+ readonly replayed: boolean
684
+ readonly erased: boolean
685
+ readonly batch: BRegIngestionReceiptBatch
686
+ }
687
+
688
+ export interface BRegIngestionChunkSubmission {
689
+ readonly run: BRegIngestionRun
690
+ readonly receipt: BRegIngestionChunkReceipt
691
+ }
692
+
693
+ /**
694
+ * One bounded, digest-bound chunk of an ingestion run. The chunk digest is
695
+ * derived in Rust from the exact canonical batch body the items hash to.
696
+ */
697
+ export declare class BRegIngestionChunk {
698
+ private constructor()
699
+ private readonly __opaque: void
700
+ readonly chunkIndex: SafeInteger
701
+ readonly itemCount: SafeInteger
702
+ readonly digest: string
703
+ readonly prefixDigest: string
704
+ }
705
+
706
+ /**
707
+ * Accumulate the raw source bytes of one ingestion input and derive the
708
+ * rolling prefix digest the run binds: the lowercase SHA-256 of everything
709
+ * absorbed through the end of the current chunk. The digest of an empty
710
+ * accumulation is `e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855`.
711
+ */
712
+ export declare class BRegIngestionPrefixDigest {
713
+ constructor()
714
+ update(data: Buffer): void
715
+ digest(): string
716
+ }
717
+
718
+ /**
719
+ * Encode one ingestion chunk submission: derive its digest in Rust and bind
720
+ * the announced prefix digest into the exact wire body. `items` are the same
721
+ * batch items the entity's atomic batch route executes.
722
+ */
723
+ export declare function encodeIngestionChunk(
724
+ chunkIndex: SafeInteger,
725
+ items: ReadonlyArray<BRegBatchItem>,
726
+ prefixDigest: string,
727
+ ): BRegIngestionChunk
728
+
557
729
  export interface BRegChangeRequestCapability {
558
730
  readonly planner: {
559
731
  readonly kind: 'declarative' | 'rhai'
@@ -574,17 +746,13 @@ export interface BRegChangeRequestCapability {
574
746
  readonly possibleWriteCount: SafeInteger | null
575
747
  readonly possibleWriteOperations: ReadonlyArray<string>
576
748
  }
577
- readonly reviewMode: 'none' | 'staged'
578
- readonly stages: ReadonlyArray<{
579
- readonly id: string
580
- readonly approvals: SafeInteger
581
- readonly excludeSubmitter: boolean
582
- readonly excludePreviousReviewers: boolean
583
- }> | null
749
+ readonly review: BRegRequestReviewRequirement
750
+ readonly onApproved: {
751
+ readonly mode: 'manual' | 'automatic'
752
+ readonly executor: string | null
753
+ }
584
754
  readonly application: {
585
- readonly mode: 'manual' | 'automatic' | 'planner'
586
- readonly allowedDispositions: ReadonlyArray<'apply' | 'queue'>
587
- readonly queueReasons: ReadonlyArray<{ readonly code: string; readonly label: string }>
755
+ readonly preconditions: JsonValue | null
588
756
  }
589
757
  }
590
758
 
@@ -677,18 +845,54 @@ export declare class BRegLifecycleAuthority {
677
845
  private readonly __opaque: void
678
846
  }
679
847
 
848
+ /** Inert caller-visible target provenance. It grants no read authority. */
849
+ export declare class BRegRequestResultReference {
850
+ private constructor()
851
+ private readonly __opaque: void
852
+ readonly targetEntityIdentifier: string
853
+ readonly targetRecordIdentifier: string
854
+ /** Revision written by the application, not a current ETag or precondition. */
855
+ readonly targetRevision: SafeInteger
856
+ toString(): string
857
+ }
858
+
859
+ /** One exact retained proposal from an explicitly loaded history page. */
860
+ export declare class BRegRetainedRequestProposalView {
861
+ private constructor()
862
+ private readonly __opaque: void
863
+ readonly requestEntityIdentifier: string
864
+ readonly requestIdentifier: string
865
+ readonly proposalVersion: SafeInteger
866
+ readonly bregState: BRegRequestState
867
+ readonly current: boolean
868
+ readonly detailErased: boolean
869
+ readonly applicationIdentifier: string | null
870
+ /** Caller-visible count, never an undisclosed application total. */
871
+ readonly resultLinkCount: SafeInteger
872
+ readonly resultReferences: ReadonlyArray<BRegRequestResultReference>
873
+ toString(): string
874
+ }
875
+
876
+ /** One page only. Call getRecord with its cursor to load another page. */
877
+ export declare class BRegRetainedRequestHistoryPage {
878
+ private constructor()
879
+ private readonly __opaque: void
880
+ readonly proposals: ReadonlyArray<BRegRetainedRequestProposalView>
881
+ readonly nextAfterProposalVersion: SafeInteger | null
882
+ findProposal(requestEntityIdentifier: string, requestIdentifier: string, proposalVersion: SafeInteger): BRegRetainedRequestProposalView | null
883
+ findApplication(requestEntityIdentifier: string, requestIdentifier: string, proposalVersion: SafeInteger, applicationIdentifier: string): BRegRetainedRequestProposalView | null
884
+ toString(): string
885
+ }
886
+
680
887
  /** Opaque executable action promoted from a metadata authority and one record. */
681
888
  export declare class BRegLifecycleAction {
682
889
  withReason(reason: string): BRegLifecycleAction
683
890
  private constructor()
684
891
  private readonly __opaque: void
685
892
  readonly operation: string
686
- readonly stage: string | null
687
893
  readonly href: string
688
894
  readonly bodyJson: string
689
- readonly reviewJson: string | null
690
895
  readonly body: JsonObject
691
- readonly review: LifecycleReview | null
692
896
  }
693
897
 
694
898
  /** Inert bounded Create evidence. Persist these bytes with owner-only access. */
@@ -801,9 +1005,17 @@ export declare class BaseRegistryClient {
801
1005
  patchRecord(binding: BRegPatchBinding, recordIdentifier: string, etag: string, operations: ReadonlyArray<PatchOperation | RemovePatchOperation>, idempotencyKey: string, format?: RecordFormat | null): Promise<CompleteOutcome<RecordEnvelope>>
802
1006
  batchRecords(binding: BRegBatchBinding, request: BRegBatchInput, idempotencyKey: string): Promise<CompleteOutcome<BRegBatchReceipt>>
803
1007
  batchRecordsJson(binding: BRegBatchBinding, requestJson: string, idempotencyKey: string): Promise<JsonOutcome>
1008
+ createIngestionRun(entityRoute: string, request: BRegIngestionRunInput): Promise<CompleteOutcome<BRegIngestionRun>>
1009
+ listIngestionRuns(entityRoute: string, query?: BRegIngestionRunListInput | null): Promise<CompleteOutcome<BRegIngestionRunPage>>
1010
+ readIngestionRun(entityRoute: string, runId: string, accessProfile?: string | null): Promise<CompleteOutcome<BRegIngestionRun>>
1011
+ submitIngestionChunk(entityRoute: string, runId: string, chunk: BRegIngestionChunk, profileId: string): Promise<CompleteOutcome<BRegIngestionChunkSubmission>>
1012
+ cancelIngestionRun(entityRoute: string, runId: string, accessProfile?: string | null): Promise<CompleteOutcome<BRegIngestionRun>>
1013
+ ingestionChunkReceipt(entityRoute: string, runId: string, chunkIndex: SafeInteger, profileId: string): Promise<CompleteOutcome<BRegIngestionChunkReceipt>>
804
1014
  tombstoneRecord(binding: BRegTombstoneBinding, recordIdentifier: string, etag: string, idempotencyKey: string, format?: RecordFormat | null): Promise<CompleteOutcome<RecordEnvelope>>
805
1015
  tombstoneRecordJson(binding: BRegTombstoneBinding, recordIdentifier: string, etag: string, idempotencyKey: string, format?: RecordFormat | null): Promise<JsonOutcome>
806
1016
  lifecycleActions(authority: BRegLifecycleAuthority, record: RecordEnvelope, format?: RecordFormat | null): ReadonlyArray<BRegLifecycleAction>
1017
+ /** Pure typed projection of one already loaded page. Performs no I/O. */
1018
+ requestHistory(record: RecordEnvelope, format?: RecordFormat | null): BRegRetainedRequestHistoryPage | null
807
1019
  prepareLifecycleAction(authority: BRegLifecycleAuthority, record: RecordEnvelope, action: BRegLifecycleAction, idempotencyKey: string, format?: RecordFormat | null): BRegPreparedLifecycle
808
1020
  prepareLifecycleActionJson(authority: BRegLifecycleAuthority, recordJson: string, action: BRegLifecycleAction, idempotencyKey: string, format?: RecordFormat | null): BRegPreparedLifecycle
809
1021
  recoverLifecycleAction(authority: BRegLifecycleAuthority, prepared: BRegPreparedLifecycle): BRegRecoveredLifecycle
package/breg/client.js CHANGED
@@ -222,6 +222,8 @@ for (const [method, jsonIndexes, requiredIndexes] of [
222
222
  ['actionTargetConditionsJson'], ['invokeActionJson'], ['batchRecordsJson'], ['tombstoneRecordJson'],
223
223
  ['executeRecoveredCreateJson'], ['executeRecoveredLifecycleActionJson'],
224
224
  ['uploadAttachmentJson'], ['deleteAttachmentJson'],
225
+ ['createIngestionRun', [1], [1]], ['listIngestionRuns', [1]],
226
+ ['readIngestionRun'], ['submitIngestionChunk'], ['cancelIngestionRun'],
225
227
  ]) wrapAsync(method, jsonIndexes, requiredIndexes);
226
228
 
227
229
  for (const [method, jsonIndexes, requiredIndexes] of [
@@ -302,6 +304,32 @@ native.BaseRegistryClient.prototype.lifecycleActions = function (...args) {
302
304
  }
303
305
  };
304
306
 
307
+ const requestHistory = native.BaseRegistryClient.prototype.requestHistory;
308
+ native.BaseRegistryClient.prototype.requestHistory = function (...args) {
309
+ try {
310
+ const sanitized = sanitizeArguments(args, new Set([0]), new Set([0]));
311
+ return requestHistory.apply(this, sanitized);
312
+ } catch (error) {
313
+ throw normalize(error, 'invalid_request');
314
+ }
315
+ };
316
+
317
+ for (const name of ['findProposal', 'findApplication']) {
318
+ const original = native.RetainedRequestHistoryPage.prototype[name];
319
+ native.RetainedRequestHistoryPage.prototype[name] = function (...args) {
320
+ try {
321
+ const proposalVersion = args[2];
322
+ if (!Number.isSafeInteger(proposalVersion)
323
+ || proposalVersion < 1 || proposalVersion > 0xffff_ffff) {
324
+ throw inputError('invalid_request');
325
+ }
326
+ return original.apply(this, args);
327
+ } catch (error) {
328
+ throw normalize(error, 'invalid_request');
329
+ }
330
+ };
331
+ }
332
+
305
333
  const valueIn = native.BRegAttachmentSlot.prototype.valueIn;
306
334
  native.BRegAttachmentSlot.prototype.valueIn = function (...args) {
307
335
  try {
@@ -336,6 +364,42 @@ for (const name of [
336
364
  };
337
365
  }
338
366
 
367
+ function encodeIngestionChunk(chunkIndex, items, prefixDigest) {
368
+ try {
369
+ if (!Number.isSafeInteger(chunkIndex)) throw inputError('invalid_request');
370
+ const sanitized = sanitizeArguments(
371
+ [chunkIndex, items, prefixDigest], new Set([1]), new Set([1]),
372
+ );
373
+ return native.encodeIngestionChunk(...sanitized);
374
+ } catch (error) {
375
+ throw normalize(error, 'invalid_request');
376
+ }
377
+ }
378
+
379
+ // napi truncates a fractional JavaScript number into the i64 chunk index, so
380
+ // the exact chunk-bound protocol checks integrality before it reaches Rust.
381
+ const ingestionChunkReceipt = native.BaseRegistryClient.prototype.ingestionChunkReceipt;
382
+ native.BaseRegistryClient.prototype.ingestionChunkReceipt = function (...args) {
383
+ try {
384
+ if (!Number.isSafeInteger(args[2])) throw inputError('invalid_request');
385
+ return ingestionChunkReceipt.apply(this, args).catch((error) => { throw normalize(error); });
386
+ } catch (error) {
387
+ throw normalize(error, 'invalid_request');
388
+ }
389
+ };
390
+
391
+ const ingestionPrefixDigestUpdate = native.BRegIngestionPrefixDigest.prototype.update;
392
+ native.BRegIngestionPrefixDigest.prototype.update = function (data) {
393
+ try {
394
+ if (!Buffer.isBuffer(data) || isSharedArrayBuffer(data.buffer)) {
395
+ throw inputError('invalid_request');
396
+ }
397
+ return ingestionPrefixDigestUpdate.call(this, data);
398
+ } catch (error) {
399
+ throw normalize(error, 'invalid_request');
400
+ }
401
+ };
402
+
339
403
  class BaseRegistryClient extends native.BaseRegistryClient {
340
404
  constructor(config) {
341
405
  try {
@@ -372,6 +436,9 @@ module.exports = {
372
436
  BRegPatchBinding: native.BRegPatchBinding,
373
437
  BRegLifecycleAuthority: native.BRegLifecycleAuthority,
374
438
  BRegLifecycleAction: native.BRegLifecycleAction,
439
+ BRegRequestResultReference: native.RequestResultReference,
440
+ BRegRetainedRequestProposalView: native.RetainedRequestProposal,
441
+ BRegRetainedRequestHistoryPage: native.RetainedRequestHistoryPage,
375
442
  BRegAttachmentSlot: native.BRegAttachmentSlot,
376
443
  BRegAttachmentUpload: native.BRegAttachmentUpload,
377
444
  BRegImmediateActionBinding: native.BRegImmediateActionBinding,
@@ -382,4 +449,7 @@ module.exports = {
382
449
  BRegPreparedLifecycle,
383
450
  BRegRecoveredCreate: native.BRegRecoveredCreate,
384
451
  BRegRecoveredLifecycle: native.BRegRecoveredLifecycle,
452
+ BRegIngestionChunk: native.BRegIngestionChunk,
453
+ BRegIngestionPrefixDigest: native.BRegIngestionPrefixDigest,
454
+ encodeIngestionChunk,
385
455
  };
package/breg/index.d.ts CHANGED
@@ -41,6 +41,30 @@ export declare class BaseRegistryClient {
41
41
  patchRecord(binding: BRegPatchBinding, recordIdentifier: string, etag: string, operations: any, idempotencyKey: string, formatValue?: string | undefined | null): Promise<CompleteOutcome>
42
42
  /** Execute one metadata-selected atomic batch without automatic retry. */
43
43
  batchRecords(binding: BRegBatchBinding, request: any, idempotencyKey: string): Promise<CompleteOutcome>
44
+ /**
45
+ * Announce one whole input and open a durable ingestion run for it. The
46
+ * run request names the access profile, which the client selects for the
47
+ * exchange.
48
+ */
49
+ createIngestionRun(entityRoute: string, request: any): Promise<CompleteOutcome>
50
+ /** Read one bounded page of ingestion runs for one entity route. */
51
+ listIngestionRuns(entityRoute: string, query?: any | undefined | null): Promise<CompleteOutcome>
52
+ /** Read the current durable state of one ingestion run. */
53
+ readIngestionRun(entityRoute: string, runId: string, accessProfile?: string | undefined | null): Promise<CompleteOutcome>
54
+ /**
55
+ * Submit one bounded chunk of an open ingestion run under the run's
56
+ * access profile. A resubmitted chunk replays its retained receipt
57
+ * instead of executing twice.
58
+ */
59
+ submitIngestionChunk(entityRoute: string, runId: string, chunk: BRegIngestionChunk, profileId: string): Promise<CompleteOutcome>
60
+ /** Cancel an open ingestion run. Committed chunks stay committed. */
61
+ cancelIngestionRun(entityRoute: string, runId: string, accessProfile?: string | undefined | null): Promise<CompleteOutcome>
62
+ /**
63
+ * Read the retained receipt of one committed chunk under the run's
64
+ * access profile. An erased receipt answers with the
65
+ * `ingestion.receipt_erased` problem instead.
66
+ */
67
+ ingestionChunkReceipt(entityRoute: string, runId: string, chunkIndex: number, profileId: string): Promise<CompleteOutcome>
44
68
  /** Tombstone one record against its current strong ETag. */
45
69
  tombstoneRecord(binding: BRegTombstoneBinding, recordIdentifier: string, etag: string, idempotencyKey: string, formatValue?: string | undefined | null): Promise<CompleteOutcome>
46
70
  /**
@@ -53,6 +77,11 @@ export declare class BaseRegistryClient {
53
77
  /** Empty one governed attachment slot. */
54
78
  deleteAttachment(slot: BRegAttachmentSlot, recordIdentifier: string, etag: string, idempotencyKey: string, formatValue?: string | undefined | null): Promise<CompleteOutcome>
55
79
  lifecycleActions(authority: BRegLifecycleAuthority, record: any, formatValue?: string | undefined | null): Array<BRegLifecycleAction>
80
+ /**
81
+ * Decode one already loaded record's retained request-history page.
82
+ * This performs no I/O and does not advance the returned continuation.
83
+ */
84
+ requestHistory(record: any, formatValue?: string | undefined | null): RetainedRequestHistoryPage | null
56
85
  executeLifecycleAction(action: BRegLifecycleAction, idempotencyKey: string): Promise<CompleteOutcome>
57
86
  /** Prepare inert lifecycle evidence before any token acquisition or I/O. */
58
87
  prepareLifecycleAction(authority: BRegLifecycleAuthority, record: any, action: BRegLifecycleAction, idempotencyKey: string, formatValue?: string | undefined | null): BRegPreparedLifecycle
@@ -151,15 +180,42 @@ export declare class BRegImmediateActionBinding {
151
180
  }
152
181
  export type ImmediateActionBinding = BRegImmediateActionBinding
153
182
 
183
+ /**
184
+ * One bounded, digest-bound chunk of an ingestion run. The chunk digest is
185
+ * derived in Rust from the exact canonical batch body the items hash to.
186
+ */
187
+ export declare class BRegIngestionChunk {
188
+ get chunkIndex(): number
189
+ get itemCount(): number
190
+ /** The derived lowercase SHA-256 of the chunk's canonical batch body. */
191
+ get digest(): string
192
+ get prefixDigest(): string
193
+ }
194
+ export type IngestionChunk = BRegIngestionChunk
195
+
196
+ /**
197
+ * Accumulate the raw source bytes of one ingestion input and derive the
198
+ * prefix digest the run binds: the lowercase SHA-256 of everything absorbed
199
+ * through the end of the current chunk. The digest of an empty accumulation
200
+ * is `e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855`.
201
+ * The digest is never a chain over chunk digests: the server stores it as an
202
+ * opaque value and cannot re-derive the raw bytes.
203
+ */
204
+ export declare class BRegIngestionPrefixDigest {
205
+ constructor()
206
+ /** Absorb the next raw source bytes, typically one chunk's source extent. */
207
+ update(data: Buffer): void
208
+ /** The lowercase SHA-256 of every raw source byte absorbed so far. */
209
+ digest(): string
210
+ }
211
+ export type IngestionPrefixDigest = BRegIngestionPrefixDigest
212
+
154
213
  export declare class BRegLifecycleAction {
155
214
  withReason(reason: string): BRegLifecycleAction
156
215
  get bodyJson(): string
157
- get reviewJson(): string | null
158
216
  get operation(): string
159
- get stage(): string | null
160
217
  get href(): string
161
218
  get body(): any
162
- get review(): any | null
163
219
  }
164
220
  export type LifecycleAction = BRegLifecycleAction
165
221
 
@@ -252,6 +308,37 @@ export declare class PrivateKeyJwt {
252
308
  }
253
309
  export type PrivateKeyJwtBinding = PrivateKeyJwt
254
310
 
311
+ /** One inert caller-visible target written by an applied request. */
312
+ export declare class RequestResultReference {
313
+ get targetEntityIdentifier(): string
314
+ get targetRecordIdentifier(): string
315
+ get targetRevision(): number
316
+ toString(): string
317
+ }
318
+
319
+ /** One explicitly loaded retained request-history page. */
320
+ export declare class RetainedRequestHistoryPage {
321
+ get proposals(): Array<RetainedRequestProposal>
322
+ get nextAfterProposalVersion(): number | null
323
+ findProposal(requestEntityIdentifier: string, requestIdentifier: string, proposalVersion: number): RetainedRequestProposal | null
324
+ findApplication(requestEntityIdentifier: string, requestIdentifier: string, proposalVersion: number, applicationIdentifier: string): RetainedRequestProposal | null
325
+ toString(): string
326
+ }
327
+
328
+ /** One exact retained proposal in an explicitly loaded history page. */
329
+ export declare class RetainedRequestProposal {
330
+ get requestEntityIdentifier(): string
331
+ get requestIdentifier(): string
332
+ get proposalVersion(): number
333
+ get bregState(): string
334
+ get current(): boolean
335
+ get detailErased(): boolean
336
+ get applicationIdentifier(): string | null
337
+ get resultLinkCount(): number
338
+ get resultReferences(): Array<RequestResultReference>
339
+ toString(): string
340
+ }
341
+
255
342
  export interface CompleteOutcome {
256
343
  kind: string
257
344
  value: any
@@ -260,6 +347,15 @@ export interface CompleteOutcome {
260
347
  location?: string
261
348
  }
262
349
 
350
+ /**
351
+ * Encode one ingestion chunk submission: derive its digest in Rust and bind
352
+ * the announced prefix digest into the exact wire body. `items` are the same
353
+ * batch items the entity's atomic batch route executes; `prefixDigest` is the
354
+ * lowercase SHA-256 of the complete raw source input through the end of this
355
+ * chunk, which `BRegIngestionPrefixDigest` accumulates.
356
+ */
357
+ export declare function encodeIngestionChunk(chunkIndex: number, items: any, prefixDigest: string): BRegIngestionChunk
358
+
263
359
  /** Validated product result serialized before the JavaScript number boundary. */
264
360
  export interface JsonOutcome {
265
361
  kind: string