@abloatai/humans 0.56.0 → 0.58.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.
Files changed (130) hide show
  1. package/dist/Ablo.d.ts +8 -18
  2. package/dist/client.d.ts +6 -19
  3. package/dist/core.d.ts +1 -1
  4. package/dist/core.js +1 -1
  5. package/dist/local/Database.d.ts +1 -1
  6. package/dist/local/Model.js +1 -1
  7. package/dist/local/SyncClient.d.ts +3 -34
  8. package/dist/local/SyncClient.js +6 -16
  9. package/dist/local/client/createInternalComponents.d.ts +1 -1
  10. package/dist/local/client/createInternalComponents.js +1 -1
  11. package/dist/local/client/{createModelProxy.d.ts → createModelOperations.d.ts} +22 -9
  12. package/dist/local/client/{createModelProxy.js → createModelOperations.js} +341 -335
  13. package/dist/local/client/options.d.ts +2 -2
  14. package/dist/local/client/reactiveEngine.js +38 -45
  15. package/dist/local/client/resourceTypes.d.ts +3 -3
  16. package/dist/local/client/resourceTypes.js +1 -1
  17. package/dist/local/client/wsMutationExecutor.d.ts +4 -4
  18. package/dist/local/client/wsMutationExecutor.js +4 -5
  19. package/dist/local/coordination/ClaimLog.d.ts +3 -3
  20. package/dist/local/coordination/ClaimLog.js +2 -2
  21. package/dist/local/interfaces/index.d.ts +5 -7
  22. package/dist/local/mutators/mutateActions.d.ts +3 -2
  23. package/dist/local/query/types.d.ts +2 -2
  24. package/dist/local/stores/syncAction.d.ts +1 -1
  25. package/dist/local/stores/syncAction.js +1 -1
  26. package/dist/local/sync/ConnectionManager.d.ts +1 -1
  27. package/dist/local/sync/ConnectionManager.js +1 -1
  28. package/dist/local/sync/OnDemandLoader.d.ts +1 -1
  29. package/dist/local/sync/OnDemandLoader.js +1 -1
  30. package/dist/local/sync/SyncWebSocket.d.ts +3 -3
  31. package/dist/local/sync/SyncWebSocket.js +2 -2
  32. package/dist/local/sync/commitFrames.d.ts +1 -1
  33. package/dist/local/sync/commitFrames.js +1 -1
  34. package/dist/local/sync/contextOnChange.d.ts +8 -0
  35. package/dist/local/sync/contextOnChange.js +65 -0
  36. package/dist/local/sync/createClaimStream.d.ts +1 -1
  37. package/dist/local/sync/createClaimStream.js +47 -28
  38. package/dist/local/sync/credentialLifecycle.d.ts +1 -1
  39. package/dist/local/sync/credentialLifecycle.js +1 -1
  40. package/dist/local/sync/participants.d.ts +1 -1
  41. package/dist/local/sync/schemas.d.ts +2 -2
  42. package/dist/local/sync/schemas.js +1 -1
  43. package/dist/local/sync/wsFrameHandlers.d.ts +1 -1
  44. package/dist/local/sync/wsFrameHandlers.js +1 -1
  45. package/dist/local/syncClientTypes.d.ts +41 -0
  46. package/dist/local/syncClientTypes.js +11 -0
  47. package/dist/local/transactions/databaseCommitOutbox.d.ts +2 -2
  48. package/dist/local/transactions/mutations/MutationQueue.d.ts +5 -18
  49. package/dist/local/transactions/mutations/MutationQueue.js +57 -137
  50. package/dist/local/transactions/mutations/batchProcessing.d.ts +2 -13
  51. package/dist/local/transactions/mutations/batchProcessing.js +0 -20
  52. package/dist/local/transactions/mutations/commitApi.d.ts +2 -3
  53. package/dist/local/transactions/mutations/commitApi.js +0 -4
  54. package/dist/local/transactions/mutations/commitLane.d.ts +6 -8
  55. package/dist/local/transactions/mutations/commitLane.js +12 -14
  56. package/dist/local/transactions/mutations/commitPayload.d.ts +2 -4
  57. package/dist/local/transactions/mutations/commitPayload.js +2 -6
  58. package/dist/local/transactions/mutations/commitTransport.d.ts +3 -4
  59. package/dist/local/transactions/mutations/commitTransport.js +2 -5
  60. package/dist/local/transactions/mutations/durableCommitRestore.d.ts +1 -1
  61. package/dist/local/transactions/mutations/durableCommitRestore.js +1 -4
  62. package/dist/local/transactions/mutations/durableWriteStore.d.ts +5 -5
  63. package/dist/local/transactions/mutations/durableWriteStore.js +3 -3
  64. package/dist/local/transactions/mutations/failurePolicy.d.ts +2 -2
  65. package/dist/local/transactions/mutations/mutationInput.d.ts +40 -0
  66. package/dist/local/transactions/mutations/mutationInput.js +53 -0
  67. package/dist/local/transactions/mutations/mutationPersistence.d.ts +1 -1
  68. package/dist/local/transactions/mutations/pendingDrain.d.ts +2 -2
  69. package/dist/local/transactions/mutations/replayValidation.d.ts +0 -20
  70. package/dist/local/transactions/mutations/replayValidation.js +1 -3
  71. package/dist/local/transactions/persistedTransaction.d.ts +0 -2
  72. package/dist/plugin.d.ts +2 -2
  73. package/dist/presenceStream.d.ts +1 -1
  74. package/dist/react/createAbloReact.d.ts +1 -1
  75. package/dist/react/useAblo.d.ts +2 -2
  76. package/dist/react/useAblo.js +1 -1
  77. package/dist/surface.d.ts +1 -1
  78. package/dist/surface.js +2 -2
  79. package/package.json +2 -2
  80. package/src/Ablo.ts +9 -27
  81. package/src/client.ts +6 -22
  82. package/src/core.ts +1 -1
  83. package/src/local/Database.ts +1 -2
  84. package/src/local/Model.ts +1 -1
  85. package/src/local/SyncClient.ts +17 -72
  86. package/src/local/client/createInternalComponents.ts +2 -2
  87. package/src/local/client/{createModelProxy.ts → createModelOperations.ts} +396 -320
  88. package/src/local/client/options.ts +2 -2
  89. package/src/local/client/reactiveEngine.ts +67 -55
  90. package/src/local/client/resourceTypes.ts +4 -4
  91. package/src/local/client/wsMutationExecutor.ts +4 -9
  92. package/src/local/coordination/ClaimLog.ts +3 -3
  93. package/src/local/interfaces/index.ts +5 -7
  94. package/src/local/mutators/mutateActions.ts +3 -2
  95. package/src/local/query/types.ts +2 -2
  96. package/src/local/stores/syncAction.ts +1 -1
  97. package/src/local/sync/ConnectionManager.ts +1 -1
  98. package/src/local/sync/OnDemandLoader.ts +1 -1
  99. package/src/local/sync/SyncWebSocket.ts +3 -3
  100. package/src/local/sync/commitFrames.ts +1 -2
  101. package/src/local/sync/contextOnChange.ts +92 -0
  102. package/src/local/sync/createClaimStream.ts +77 -39
  103. package/src/local/sync/credentialLifecycle.ts +1 -1
  104. package/src/local/sync/participants.ts +1 -1
  105. package/src/local/sync/schemas.ts +1 -1
  106. package/src/local/sync/wsFrameHandlers.ts +1 -1
  107. package/src/local/syncClientTypes.ts +59 -0
  108. package/src/local/transactions/databaseCommitOutbox.ts +2 -2
  109. package/src/local/transactions/mutations/MutationQueue.ts +69 -183
  110. package/src/local/transactions/mutations/batchProcessing.ts +2 -38
  111. package/src/local/transactions/mutations/commitApi.ts +3 -7
  112. package/src/local/transactions/mutations/commitLane.ts +24 -20
  113. package/src/local/transactions/mutations/commitPayload.ts +3 -11
  114. package/src/local/transactions/mutations/commitTransport.ts +3 -7
  115. package/src/local/transactions/mutations/durableCommitRestore.ts +2 -5
  116. package/src/local/transactions/mutations/durableWriteStore.ts +5 -5
  117. package/src/local/transactions/mutations/failurePolicy.ts +2 -2
  118. package/src/local/transactions/mutations/mutationInput.ts +69 -0
  119. package/src/local/transactions/mutations/mutationPersistence.ts +1 -1
  120. package/src/local/transactions/mutations/pendingDrain.ts +2 -2
  121. package/src/local/transactions/mutations/replayValidation.ts +1 -3
  122. package/src/local/transactions/persistedTransaction.ts +0 -3
  123. package/src/plugin.ts +2 -2
  124. package/src/presenceStream.ts +2 -2
  125. package/src/react/createAbloReact.ts +1 -1
  126. package/src/react/useAblo.ts +2 -2
  127. package/src/surface.ts +3 -3
  128. package/dist/local/sync/createSnapshot.d.ts +0 -29
  129. package/dist/local/sync/createSnapshot.js +0 -116
  130. package/src/local/sync/createSnapshot.ts +0 -160
@@ -25,7 +25,7 @@
25
25
  import type {
26
26
  WsTransport,
27
27
  PresenceUpdate,
28
- } from '@abloatai/transaction/transport/wsTransport';
28
+ } from '@abloatai/transaction/transport/websocket';
29
29
  import type {
30
30
  ClaimOptions,
31
31
  ClaimTarget,
@@ -52,10 +52,15 @@ import {
52
52
  streamTarget,
53
53
  wireTarget,
54
54
  type ClaimTargetDetails,
55
- } from '@abloatai/transaction/coordination/locator';
56
- import { declaredMeta } from '@abloatai/transaction/coordination/claimMeta';
55
+ } from '@abloatai/transaction/claims';
56
+ import {
57
+ bindClaimLifetime,
58
+ createClaimLifetime,
59
+ type ClaimLifetime,
60
+ } from '@abloatai/transaction/claims/lifetime';
61
+ import { declaredMeta } from '@abloatai/transaction/claims';
57
62
  import { AbloClaimedError, AbloConnectionError } from '@abloatai/transaction/errors';
58
- import { resolveHeartbeatOptions } from '@abloatai/transaction/coordination/claimHeartbeatLoop';
63
+ import { resolveHeartbeatOptions } from '@abloatai/transaction/claims';
59
64
  import { noopLogger, type Logger } from '@abloatai/transaction/logger';
60
65
 
61
66
  /**
@@ -114,13 +119,11 @@ export interface AttachableClaimStream extends ClaimStream {
114
119
  }
115
120
 
116
121
  /**
117
- * What this participant needs to remember about a claim it holds, so it can
118
- * re-announce it after a reconnect.
122
+ * What this participant needs to remember about one open grant.
119
123
  *
120
124
  * The sub-entity locator is taken from {@link ClaimTargetDetails} rather than
121
- * listed again: a member this record forgot would be a member the re-announced
122
- * claim silently lost, which is a narrower claim than the one the holder
123
- * believes it has.
125
+ * listed again: a member this record forgot would be a member release or loss
126
+ * bookkeeping silently narrowed relative to the handle the caller holds.
124
127
  */
125
128
  type OwnClaim = ClaimTargetDetails & {
126
129
  readonly entityType: string;
@@ -133,6 +136,11 @@ type OwnClaim = ClaimTargetDetails & {
133
136
  readonly queue?: boolean;
134
137
  };
135
138
 
139
+ interface OwnGrant {
140
+ readonly claim: OwnClaim;
141
+ readonly lifetime: ClaimLifetime;
142
+ }
143
+
136
144
  export function createClaimStream(
137
145
  config: ClaimStreamConfig,
138
146
  transport: ClaimTransport | null = null,
@@ -146,8 +154,8 @@ export function createClaimStream(
146
154
  const activeByClaimId = new Map<string, Claim>();
147
155
  let claimsSnapshot: readonly Claim[] = Object.freeze([]);
148
156
 
149
- // ── State: our own open claims (for re-announce on reconnect) ───
150
- const ownClaims = new Map<string, OwnClaim>();
157
+ // ── State: our own open grants, keyed by the exact claim id ─────
158
+ const ownClaims = new Map<string, OwnGrant>();
151
159
 
152
160
  // ── State: per-entity wait queues, from `claim_queue` frames ────
153
161
  // Keyed `type:id`; the value is the FIFO line of queued claims. Powers
@@ -290,7 +298,8 @@ export function createClaimStream(
290
298
  unsubs.push(
291
299
  t.subscribe('claim_rejected', (rejection) => {
292
300
  if (!rejection.claimId) return;
293
- if (ownClaims.has(rejection.claimId)) {
301
+ const own = ownClaims.get(rejection.claimId);
302
+ if (own) {
294
303
  const tgt = rejection.target
295
304
  ? claimLabel(rejection.target.entityType, rejection.target.entityId, rejection.target.field)
296
305
  : rejection.claimId;
@@ -299,9 +308,17 @@ export function createClaimStream(
299
308
  { claimId: rejection.claimId, reason: rejection.reason },
300
309
  );
301
310
  }
302
- // Drop the rejected own-claim so reconnect doesn't re-announce
303
- // a claim the server already rejected (would just spam both
304
- // sides with conflicts).
311
+ own?.lifetime.end(
312
+ new AbloClaimedError(
313
+ rejection.message ?? `Claim ${rejection.claimId} was rejected.`,
314
+ {
315
+ code:
316
+ rejection.reason === 'conflict'
317
+ ? 'claim_conflict'
318
+ : 'claim_lease_unavailable',
319
+ },
320
+ ),
321
+ );
305
322
  ownClaims.delete(rejection.claimId);
306
323
  // A holder on another server may have claimed before this client joined
307
324
  // the row group, so its one-shot presence frame was missed. A conflict
@@ -336,15 +353,20 @@ export function createClaimStream(
336
353
  // The frame is validated by the transport's dispatcher against the same
337
354
  // schema this parameter's type comes from, so it arrives proven.
338
355
  t.subscribe('claim_lost', (lost) => {
339
- if (ownClaims.has(lost.claimId)) {
340
- const c = ownClaims.get(lost.claimId);
356
+ const own = ownClaims.get(lost.claimId);
357
+ if (own) {
358
+ const c = own.claim;
341
359
  logger.info(
342
- `claim: lost ${c ? claimLabel(c.entityType, c.entityId, c.field) : lost.claimId} (preempted or expired)`,
360
+ `claim: lost ${claimLabel(c.entityType, c.entityId, c.field)} (preempted or expired)`,
343
361
  { claimId: lost.claimId },
344
362
  );
345
363
  }
346
- // Drop the lost own-claim so reconnect doesn't re-announce a lease we
347
- // no longer hold.
364
+ own?.lifetime.end(
365
+ new AbloClaimedError(
366
+ `Claim ${lost.claimId} was lost because it ${lost.reason === 'expired' ? 'expired' : 'was preempted'}. Re-acquire it before continuing.`,
367
+ { code: 'claim_lost' },
368
+ ),
369
+ );
348
370
  ownClaims.delete(lost.claimId);
349
371
  for (const l of lostListeners) {
350
372
  try {
@@ -418,25 +440,35 @@ export function createClaimStream(
418
440
  });
419
441
  return;
420
442
  }
421
- const c = ownClaims.get(ack.claimId);
422
- reject(
423
- new AbloClaimedError(
424
- `The lease behind ${c ? claimLabel(c.entityType, c.entityId, c.field) : `claim ${ack.claimId}`} is no longer held — it expired or was granted onward while this participant was working. Re-acquire the claim and retry; a write attempted under the old lease is rejected by its \`readAt\` guard.`,
425
- { code: 'claim_lost' },
426
- ),
443
+ const own = ownClaims.get(ack.claimId);
444
+ const c = own?.claim;
445
+ const error = new AbloClaimedError(
446
+ `The lease behind ${c ? claimLabel(c.entityType, c.entityId, c.field) : `claim ${ack.claimId}`} is no longer held — it expired or was granted onward while this participant was working. Re-acquire the claim and retry; a write attempted under the old lease is rejected by its \`readAt\` guard.`,
447
+ { code: 'claim_lost' },
427
448
  );
449
+ own?.lifetime.end(error);
450
+ ownClaims.delete(ack.claimId);
451
+ reject(error);
428
452
  });
429
453
  }),
430
454
  );
431
455
 
432
- // (3) On reconnect, re-announce every open self-claim the
433
- // server's claim state is in-memory and is lost across
434
- // restarts. Without this, peers would see our claims vanish
435
- // whenever the connection blipped.
456
+ // (3) A granted handle belongs to this connection's exact grant. The server
457
+ // releases the participant's claims when its last socket leaves; trying
458
+ // to recreate them on `connected` silently swapped the lease beneath an
459
+ // old `data` / `readAt` / fenceToken tuple. End them instead. A caller
460
+ // reconnects, re-reads, and takes a fresh handle.
436
461
  unsubs.push(
437
- t.subscribe('connected', () => {
438
- for (const [claimId, claim] of ownClaims) {
439
- sendBegin(claimId, claim);
462
+ t.subscribe('disconnected', () => {
463
+ const error = new AbloConnectionError(
464
+ 'The connection holding this claim ended. Reconnect and acquire a fresh claim before continuing.',
465
+ );
466
+ for (const { lifetime } of ownClaims.values()) {
467
+ lifetime.end(error);
468
+ }
469
+ ownClaims.clear();
470
+ for (const claimId of [...pendingHeartbeats.keys()]) {
471
+ settleHeartbeat(claimId, ({ reject }) => reject(error));
440
472
  }
441
473
  }),
442
474
  );
@@ -480,8 +512,8 @@ export function createClaimStream(
480
512
 
481
513
  /**
482
514
  * Send one heartbeat and await its ack. Rejects with
483
- * {@link AbloConnectionError} (transient the auto-heartbeat loop retries
484
- * on its next tick) when the socket is down or the ack times out, and with
515
+ * {@link AbloConnectionError} when the socket is down or the ack times out,
516
+ * and with
485
517
  * {@link AbloClaimedError} (definitive) when the server answers that the
486
518
  * lease is no longer ours.
487
519
  */
@@ -493,7 +525,7 @@ export function createClaimStream(
493
525
  if (!attached?.isConnected()) {
494
526
  return Promise.reject(
495
527
  new AbloConnectionError(
496
- `The heartbeat for ${claimLabel(claim.entityType, claim.entityId, claim.field)} was skipped because the connection is down. The keepalive renews held leases automatically on reconnect; the next beat retries.`,
528
+ `The heartbeat for ${claimLabel(claim.entityType, claim.entityId, claim.field)} was skipped because the connection is down. This connection's grant has ended; reconnect and acquire a fresh claim.`,
497
529
  ),
498
530
  );
499
531
  }
@@ -567,7 +599,8 @@ export function createClaimStream(
567
599
  estimatedMs,
568
600
  queue: args.queue,
569
601
  };
570
- ownClaims.set(claimId, claim);
602
+ const lifetime = createClaimLifetime();
603
+ ownClaims.set(claimId, { claim, lifetime });
571
604
  sendBegin(claimId, claim);
572
605
  // Coordination trace (info): the creator can see their human/agent claims.
573
606
  logger.info(
@@ -580,6 +613,7 @@ export function createClaimStream(
580
613
  const revoke = () => {
581
614
  if (revoked) return;
582
615
  revoked = true;
616
+ lifetime.end();
583
617
  ownClaims.delete(claimId);
584
618
  sendAbandon(claimId, claim);
585
619
  logger.info(
@@ -588,7 +622,7 @@ export function createClaimStream(
588
622
  );
589
623
  };
590
624
 
591
- return {
625
+ return bindClaimLifetime({
592
626
  object: 'claim',
593
627
  id: claimId,
594
628
  status: 'active',
@@ -607,7 +641,7 @@ export function createClaimStream(
607
641
  [Symbol.asyncDispose]: async () => {
608
642
  revoke();
609
643
  },
610
- };
644
+ }, lifetime);
611
645
  }
612
646
 
613
647
  function resolveTarget(target: PresenceTarget): ClaimTarget {
@@ -686,6 +720,10 @@ export function createClaimStream(
686
720
  );
687
721
  });
688
722
  }
723
+ const error = new AbloConnectionError(
724
+ 'The claim stream was disposed. Acquire a fresh claim before continuing.',
725
+ );
726
+ for (const { lifetime } of ownClaims.values()) lifetime.end(error);
689
727
  listeners.clear();
690
728
  rejectionListeners.clear();
691
729
  lostListeners.clear();
@@ -15,4 +15,4 @@ export {
15
15
  type CredentialRefreshResult,
16
16
  type CredentialRefresher,
17
17
  type CredentialLifecycleContext,
18
- } from '@abloatai/transaction/transport/credentialLifecycle';
18
+ } from '@abloatai/transaction/transport/connection';
@@ -1,4 +1,4 @@
1
- import type { JoinOptions } from '@abloatai/transaction/resources/modelOperations';
1
+ import type { JoinOptions } from '@abloatai/transaction/client/resources/modelOperations';
2
2
  import type { SyncWebSocket } from './SyncWebSocket.js';
3
3
  import type { Schema, SchemaRecord } from '@abloatai/transaction/schema/schema';
4
4
  import { scopeKindOf, type ModelDef } from '@abloatai/transaction/schema/model';
@@ -10,7 +10,7 @@ import { z } from 'zod';
10
10
  import { globalRuntime } from "../context.js";
11
11
  import type { RuntimeContext } from "../RuntimeContext.js";
12
12
  import { AbloValidationError } from "@abloatai/transaction/errors";
13
- import { syncDeltaWireCoreSchema } from '@abloatai/transaction/wire/delta';
13
+ import { syncDeltaWireCoreSchema } from '@abloatai/transaction/observation';
14
14
 
15
15
  // ─── Server Delta Schema ─────────────────────────────────────────────────────
16
16
 
@@ -17,4 +17,4 @@ export {
17
17
  type WsInboundFrame,
18
18
  type WsSession,
19
19
  type WsFrameHandler,
20
- } from '@abloatai/transaction/transport/wsFrameHandlers';
20
+ } from '@abloatai/transaction/transport/websocket';
@@ -0,0 +1,59 @@
1
+ import type { Model } from './Model.js';
2
+ import type { BootstrapData } from './sync/BootstrapFetcher.js';
3
+ import type { QueuedMutation } from './transactions/mutations/MutationQueue.js';
4
+ import type { CommitTransaction } from './transactions/mutations/commitLane.js';
5
+
6
+ export interface SyncObserver {
7
+ onSync?: (event: SyncEvent) => void;
8
+ }
9
+
10
+ export interface SyncEvent {
11
+ type: 'create' | 'update' | 'delete' | 'archive' | 'rollback';
12
+ modelType: string;
13
+ model?: Model;
14
+ modelId?: string;
15
+ transactionType?: string;
16
+ }
17
+
18
+ export interface SyncState {
19
+ connectionState: 'connected' | 'disconnected' | 'connecting';
20
+ pendingMutations: number;
21
+ lastSyncAt?: Date;
22
+ error?: Error;
23
+ }
24
+
25
+ export interface RehydrationStats {
26
+ added: number;
27
+ updated: number;
28
+ removed: number;
29
+ skipped: number;
30
+ healed: number;
31
+ elapsedMs: number;
32
+ }
33
+
34
+ export type EventHandler = () => void;
35
+
36
+ /** The bootstrap fields applied to the local object pool. */
37
+ export type BootstrapSnapshot = Pick<BootstrapData, 'models' | 'failedModels'> &
38
+ Partial<Pick<BootstrapData, 'lastSyncId'>>;
39
+
40
+ /** A completed queued mutation or explicit commit. */
41
+ export type CompletedTransaction =
42
+ | (Pick<QueuedMutation, 'id' | 'modelId' | 'syncIdNeededForCompletion'> & {
43
+ lastSyncId?: undefined;
44
+ operations?: undefined;
45
+ })
46
+ | (Pick<CommitTransaction, 'id' | 'lastSyncId' | 'operations'> & {
47
+ modelId?: undefined;
48
+ syncIdNeededForCompletion?: undefined;
49
+ });
50
+
51
+ /** Normalize an untyped server timestamp for last-write-wins comparison. */
52
+ export function toEpochMs(value: unknown): number {
53
+ if (!value) return 0;
54
+ if (value instanceof Date) return value.getTime();
55
+ if (typeof value === 'string' || typeof value === 'number') {
56
+ return new Date(value).getTime();
57
+ }
58
+ return 0;
59
+ }
@@ -1,7 +1,7 @@
1
1
  import type {
2
2
  DurableWriteStore,
3
- } from '@abloatai/transaction/durableWrites';
4
- import type { PendingWrite } from '@abloatai/transaction/transactions/confirmation/pendingWrite';
3
+ } from '@abloatai/transaction/commit';
4
+ import type { PendingWrite } from '@abloatai/transaction/commit';
5
5
 
6
6
  export interface CommitOutboxDatabase {
7
7
  sealTransactionRecord(