@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
@@ -10,9 +10,8 @@
10
10
  */
11
11
  import type { RuntimeContext } from '../../RuntimeContext.js';
12
12
  import { MutationOperationType } from '@abloatai/transaction/types';
13
- import type { OnStaleMode } from '@abloatai/transaction/coordination/schema';
14
13
  import type { MutationOptions, WriteOptions } from '../../interfaces/index.js';
15
- import type { CommitEnvelopeMember } from '@abloatai/transaction/transactions/confirmation/commitEnvelope';
14
+ import type { CommitEnvelopeMember } from '@abloatai/transaction/commit';
16
15
  export interface UserContext {
17
16
  userId: string;
18
17
  organizationId: string;
@@ -128,14 +127,13 @@ export declare function hasStaleWriteOptions(options?: WriteOptions): boolean;
128
127
  export declare function hasCommitCoalescingBarrier(options?: WriteOptions): boolean;
129
128
  export interface WriteOperationFields {
130
129
  readAt?: number | null;
131
- onStale?: OnStaleMode | null;
132
130
  fenceToken?: number | null;
133
131
  claimId?: string;
134
132
  options?: Pick<MutationOptions, 'idempotencyKey' | 'label'>;
135
133
  }
136
134
  /**
137
135
  * Copies a transaction's `writeOptions` onto the wire operation. The
138
- * stale-context guards (`readAt` and `onStale`) sit at the operation's root,
136
+ * stale-context guard (`readAt`) sits at the operation's root,
139
137
  * while `idempotencyKey` and `label` go in its `options` slot — the
140
138
  * `mutation_log` cache key and audit tag. This is the one place caller-supplied
141
139
  * write options cross onto the wire.
@@ -104,8 +104,7 @@ export const TX_TYPE_TO_MUTATION_OP = {
104
104
  unarchive: MutationOperationType.UNARCHIVE,
105
105
  };
106
106
  export function hasStaleWriteOptions(options) {
107
- return (options?.readAt !== undefined ||
108
- options?.onStale !== undefined);
107
+ return options?.readAt !== undefined;
109
108
  }
110
109
  /** Options whose identity/audit semantics forbid merging two caller writes. */
111
110
  export function hasCommitCoalescingBarrier(options) {
@@ -117,7 +116,7 @@ export function hasCommitCoalescingBarrier(options) {
117
116
  }
118
117
  /**
119
118
  * Copies a transaction's `writeOptions` onto the wire operation. The
120
- * stale-context guards (`readAt` and `onStale`) sit at the operation's root,
119
+ * stale-context guard (`readAt`) sits at the operation's root,
121
120
  * while `idempotencyKey` and `label` go in its `options` slot — the
122
121
  * `mutation_log` cache key and audit tag. This is the one place caller-supplied
123
122
  * write options cross onto the wire.
@@ -130,9 +129,6 @@ export function applyWriteOptions(op, transaction) {
130
129
  if (writeOptions.readAt !== undefined) {
131
130
  operation.readAt = writeOptions.readAt;
132
131
  }
133
- if (writeOptions.onStale !== undefined) {
134
- operation.onStale = writeOptions.onStale;
135
- }
136
132
  if (writeOptions.fenceToken !== undefined) {
137
133
  operation.fenceToken = writeOptions.fenceToken;
138
134
  }
@@ -1,8 +1,8 @@
1
1
  import type { RuntimeContext } from '../../RuntimeContext.js';
2
2
  import type { MutationExecutor } from '../../interfaces/index.js';
3
- import type { ReadDependency, TrackDependency } from '@abloatai/transaction/coordination/schema';
4
- import { type MutationCommitResult } from '@abloatai/transaction/wire/commit';
5
- import { type CommitOutboxScope, type DurableCommitEnvelope, type DurableCommitOperation } from '@abloatai/transaction/transactions/confirmation/commitEnvelope';
3
+ import type { ReadDependency } from '@abloatai/transaction/coordination/schema';
4
+ import { type MutationCommitResult } from '@abloatai/transaction/commit';
5
+ import { type CommitOutboxScope, type DurableCommitEnvelope, type DurableCommitOperation } from '@abloatai/transaction/commit';
6
6
  import type { DurableWriteStore } from './durableWriteStore.js';
7
7
  export interface CommitTransportContext {
8
8
  readonly runtime: RuntimeContext;
@@ -22,7 +22,6 @@ export interface SealDurableCommitInput {
22
22
  sourceMutationIds?: string[];
23
23
  commitOptions?: {
24
24
  reads?: readonly ReadDependency[] | null;
25
- track?: readonly TrackDependency[] | null;
26
25
  };
27
26
  createdAt: number;
28
27
  sealedAt: number;
@@ -1,6 +1,6 @@
1
1
  import { AbloConnectionError, AbloError, AbloIdempotencyError, } from '@abloatai/transaction/errors';
2
- import { mutationCommitResultSchema, } from '@abloatai/transaction/wire/commit';
3
- import { createDurableCommitEnvelope, commitEnvelopeRecordId, durableCommitEnvelopeSchema, } from '@abloatai/transaction/transactions/confirmation/commitEnvelope';
2
+ import { mutationCommitResultSchema, } from '@abloatai/transaction/commit';
3
+ import { createDurableCommitEnvelope, commitEnvelopeRecordId, durableCommitEnvelopeSchema, } from '@abloatai/transaction/commit';
4
4
  export async function sealDurableCommit(ctx, input, pendingMutationRecordId) {
5
5
  const sourceMutationIds = [...new Set(input.sourceMutationIds ?? [])];
6
6
  const envelope = createDurableCommitEnvelope({
@@ -12,9 +12,6 @@ export async function sealDurableCommit(ctx, input, pendingMutationRecordId) {
12
12
  ...(input.commitOptions?.reads !== undefined
13
13
  ? { reads: input.commitOptions.reads === null ? null : [...input.commitOptions.reads] }
14
14
  : {}),
15
- ...(input.commitOptions?.track !== undefined
16
- ? { track: input.commitOptions.track === null ? null : [...input.commitOptions.track] }
17
- : {}),
18
15
  },
19
16
  ...(ctx.commitOutboxScope ? { scope: ctx.commitOutboxScope } : {}),
20
17
  createdAt: input.createdAt,
@@ -1,6 +1,6 @@
1
1
  import type { RuntimeContext } from '../../RuntimeContext.js';
2
2
  import type { CommitTransaction } from './commitLane.js';
3
- import type { CommitOutboxScope } from '@abloatai/transaction/transactions/confirmation/commitEnvelope';
3
+ import type { CommitOutboxScope } from '@abloatai/transaction/commit';
4
4
  import type { DurableWriteStore } from './durableWriteStore.js';
5
5
  export interface DurableCommitRestoreContext {
6
6
  readonly config: {
@@ -1,5 +1,5 @@
1
1
  import { AbloIdempotencyError, AbloValidationError } from '@abloatai/transaction/errors';
2
- import { durableCommitEnvelopeSchema } from '@abloatai/transaction/transactions/confirmation/commitEnvelope';
2
+ import { durableCommitEnvelopeSchema } from '@abloatai/transaction/commit';
3
3
  export async function restoreDurableCommits(ctx) {
4
4
  if (!ctx.config.enablePersistence)
5
5
  return new Set();
@@ -61,9 +61,6 @@ export async function restoreDurableCommits(ctx) {
61
61
  ...(envelope.commitOptions.reads
62
62
  ? { reads: [...envelope.commitOptions.reads] }
63
63
  : {}),
64
- ...(envelope.commitOptions.track
65
- ? { track: [...envelope.commitOptions.track] }
66
- : {}),
67
64
  status: 'pending',
68
65
  createdAt: envelope.createdAt,
69
66
  sealedAt: envelope.sealedAt,
@@ -6,9 +6,9 @@
6
6
  *
7
7
  * The port and its config live in the core's `durableWrites` module (a behavior
8
8
  * contract, not a persisted shape); the records that cross it are owned by
9
- * `transactions/confirmation/pendingWrite`.
9
+ * `commit/confirmation/pendingWrite`.
10
10
  */
11
- export { durableWriteStoreSchema, durableWritesConfigSchema, } from '@abloatai/transaction/durableWrites';
12
- export type { DurableWriteStore, DurableWritesConfig, } from '@abloatai/transaction/durableWrites';
13
- export { pendingWriteSchema } from '@abloatai/transaction/transactions/confirmation/pendingWrite';
14
- export type { PendingWrite } from '@abloatai/transaction/transactions/confirmation/pendingWrite';
11
+ export { durableWriteStoreSchema, durableWritesConfigSchema, } from '@abloatai/transaction/commit';
12
+ export type { DurableWriteStore, DurableWritesConfig, } from '@abloatai/transaction/commit';
13
+ export { pendingWriteSchema } from '@abloatai/transaction/commit';
14
+ export type { PendingWrite } from '@abloatai/transaction/commit';
@@ -6,7 +6,7 @@
6
6
  *
7
7
  * The port and its config live in the core's `durableWrites` module (a behavior
8
8
  * contract, not a persisted shape); the records that cross it are owned by
9
- * `transactions/confirmation/pendingWrite`.
9
+ * `commit/confirmation/pendingWrite`.
10
10
  */
11
- export { durableWriteStoreSchema, durableWritesConfigSchema, } from '@abloatai/transaction/durableWrites';
12
- export { pendingWriteSchema } from '@abloatai/transaction/transactions/confirmation/pendingWrite';
11
+ export { durableWriteStoreSchema, durableWritesConfigSchema, } from '@abloatai/transaction/commit';
12
+ export { pendingWriteSchema } from '@abloatai/transaction/commit';
@@ -3,11 +3,11 @@ import type { MutationQueueConfig } from './MutationQueue.js';
3
3
  import type { MutationStore } from './MutationStore.js';
4
4
  export declare function isPermanentError(error: Error): boolean;
5
5
  export declare function isDefinitiveRejection(error: Error): boolean;
6
- export interface ConflictPolicyContext {
6
+ export interface ConflictResolutionContext {
7
7
  readonly config: Pick<MutationQueueConfig, 'conflictResolution'>;
8
8
  readonly store: MutationStore;
9
9
  readonly rollbackOptimistic: (transaction: QueuedMutation, reason: string) => Promise<void>;
10
10
  readonly mergeData: (local: MutationInput | undefined, remote: MutationInput) => MutationInput;
11
11
  readonly enqueue: (transaction: QueuedMutation) => void;
12
12
  }
13
- export declare function handleConflict(ctx: ConflictPolicyContext, transaction: QueuedMutation, serverData: MutationInput): Promise<void>;
13
+ export declare function handleConflict(ctx: ConflictResolutionContext, transaction: QueuedMutation, serverData: MutationInput): Promise<void>;
@@ -0,0 +1,40 @@
1
+ /**
2
+ * The input a queued mutation carries, derived from a local model.
3
+ *
4
+ * Six small rules that answer one question: given a model and what changed on
5
+ * it, what does the commit actually send? They sat as private methods on
6
+ * `MutationQueue` because that is where they were called, which is how a queue
7
+ * ends up also owning the payload vocabulary.
8
+ *
9
+ * The before-image rule is the one worth reading twice, and it is stated in
10
+ * `previousDataFor` rather than here.
11
+ */
12
+ import type { LocalModel } from '../../localModelContract.js';
13
+ import type { RuntimeContext } from '../../RuntimeContext.js';
14
+ import { type MutationInput } from './commitPayload.js';
15
+ /** A queued transaction's local identity, unique per process and monotonic enough to sort. */
16
+ export declare function generateTransactionId(): string;
17
+ /** Local values win: they are the edit the caller made, remote is the base. */
18
+ export declare function mergeMutationData(local: MutationInput | undefined, remote: MutationInput | undefined): MutationInput;
19
+ /** A create sends the whole row, `undefined` included, so absence is explicit. */
20
+ export declare function createDataFor(model: LocalModel, runtime?: RuntimeContext): MutationInput;
21
+ /** An arbitrary change set, projected the way an update is. */
22
+ export declare function changesToInput(modelName: string, changes: Record<string, unknown>, runtime?: RuntimeContext): MutationInput;
23
+ /** An update sends only what changed. */
24
+ export declare function updateDataFor(model: LocalModel, runtime?: RuntimeContext): MutationInput;
25
+ /**
26
+ * The before-image an undo reverts to.
27
+ *
28
+ * When the update's written keys are known, capture a before-image for exactly
29
+ * those keys, so the recorded undo inverse reverts them and nothing else — a
30
+ * full-row inverse would clobber concurrent edits to unrelated fields.
31
+ * `fallbackToLive: false` makes `Model.capturePreviousValues` omit any key it
32
+ * cannot resolve, and `buildUndoOps` then drops an un-revertible inverse rather
33
+ * than inventing one. With no `updateInput` (a full extract) it falls back to
34
+ * every tracked field.
35
+ *
36
+ * Model-specific special cases do not belong here: a model that needs to
37
+ * surface previous state beyond `modifiedProperties` should expose a typed
38
+ * `getPreviousData()` accessor for this to call.
39
+ */
40
+ export declare function previousDataFor(model: LocalModel, updateInput?: MutationInput): MutationInput;
@@ -0,0 +1,53 @@
1
+ /**
2
+ * The input a queued mutation carries, derived from a local model.
3
+ *
4
+ * Six small rules that answer one question: given a model and what changed on
5
+ * it, what does the commit actually send? They sat as private methods on
6
+ * `MutationQueue` because that is where they were called, which is how a queue
7
+ * ends up also owning the payload vocabulary.
8
+ *
9
+ * The before-image rule is the one worth reading twice, and it is stated in
10
+ * `previousDataFor` rather than here.
11
+ */
12
+ import { projectCommitPayload } from './commitPayload.js';
13
+ /** A queued transaction's local identity, unique per process and monotonic enough to sort. */
14
+ export function generateTransactionId() {
15
+ return `tx_${Date.now()}_${Math.random().toString(36).substring(2, 11)}`;
16
+ }
17
+ /** Local values win: they are the edit the caller made, remote is the base. */
18
+ export function mergeMutationData(local, remote) {
19
+ return { ...(remote ?? {}), ...(local ?? {}) };
20
+ }
21
+ /** A create sends the whole row, `undefined` included, so absence is explicit. */
22
+ export function createDataFor(model, runtime) {
23
+ return projectCommitPayload(model.getModelName(), model.toJSON(), { dropUndefined: false }, runtime);
24
+ }
25
+ /** An arbitrary change set, projected the way an update is. */
26
+ export function changesToInput(modelName, changes, runtime) {
27
+ return projectCommitPayload(modelName, changes, { dropUndefined: true }, runtime);
28
+ }
29
+ /** An update sends only what changed. */
30
+ export function updateDataFor(model, runtime) {
31
+ return projectCommitPayload(model.getModelName(), model.getChanges(), { dropUndefined: true }, runtime);
32
+ }
33
+ /**
34
+ * The before-image an undo reverts to.
35
+ *
36
+ * When the update's written keys are known, capture a before-image for exactly
37
+ * those keys, so the recorded undo inverse reverts them and nothing else — a
38
+ * full-row inverse would clobber concurrent edits to unrelated fields.
39
+ * `fallbackToLive: false` makes `Model.capturePreviousValues` omit any key it
40
+ * cannot resolve, and `buildUndoOps` then drops an un-revertible inverse rather
41
+ * than inventing one. With no `updateInput` (a full extract) it falls back to
42
+ * every tracked field.
43
+ *
44
+ * Model-specific special cases do not belong here: a model that needs to
45
+ * surface previous state beyond `modifiedProperties` should expose a typed
46
+ * `getPreviousData()` accessor for this to call.
47
+ */
48
+ export function previousDataFor(model, updateInput) {
49
+ const keys = updateInput
50
+ ? Object.keys(updateInput)
51
+ : [...(model.modifiedProperties instanceof Map ? model.modifiedProperties.keys() : [])];
52
+ return { id: model.id, ...model.capturePreviousValues(keys, { fallbackToLive: false }) };
53
+ }
@@ -1,7 +1,7 @@
1
1
  import type { RuntimeContext } from '../../RuntimeContext.js';
2
2
  import type { MutationPersistencePort } from '../../mutationPersistence.js';
3
3
  import type { MutationQueueConfig } from './MutationQueue.js';
4
- import type { CommitOutboxScope } from '@abloatai/transaction/transactions/confirmation/commitEnvelope';
4
+ import type { CommitOutboxScope } from '@abloatai/transaction/commit';
5
5
  import type { QueuedMutation } from './commitPayload.js';
6
6
  import { MutationStore } from './MutationStore.js';
7
7
  import { deserializePersistedTransaction } from './replayValidation.js';
@@ -2,8 +2,8 @@ import type { RuntimeContext } from '../../RuntimeContext.js';
2
2
  import type { QueuedMutation } from './commitPayload.js';
3
3
  import type { MutationStore } from './MutationStore.js';
4
4
  import type { OptimisticUpdateEntry } from './localMutation.js';
5
- import type { MutationCommitResult } from '@abloatai/transaction/wire/commit';
6
- import type { DurableCommitEnvelope } from '@abloatai/transaction/transactions/confirmation/commitEnvelope';
5
+ import type { MutationCommitResult } from '@abloatai/transaction/commit';
6
+ import type { DurableCommitEnvelope } from '@abloatai/transaction/commit';
7
7
  export interface PendingDrainContext {
8
8
  readonly runtime: RuntimeContext;
9
9
  readonly config: {
@@ -56,11 +56,6 @@ export declare const persistedTransactionSchema: z.ZodObject<{
56
56
  sourceMutationIds: z.ZodOptional<z.ZodArray<z.ZodString>>;
57
57
  writeOptions: z.ZodOptional<z.ZodObject<{
58
58
  readAt: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
59
- onStale: z.ZodOptional<z.ZodNullable<z.ZodEnum<{
60
- reject: "reject";
61
- overwrite: "overwrite";
62
- notify: "notify";
63
- }>>>;
64
59
  idempotencyKey: z.ZodOptional<z.ZodString>;
65
60
  label: z.ZodOptional<z.ZodString>;
66
61
  fenceToken: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
@@ -102,11 +97,6 @@ export declare const persistedMutationSchema: z.ZodObject<{
102
97
  capturedChanges: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
103
98
  writeOptions: z.ZodOptional<z.ZodObject<{
104
99
  readAt: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
105
- onStale: z.ZodOptional<z.ZodNullable<z.ZodEnum<{
106
- reject: "reject";
107
- overwrite: "overwrite";
108
- notify: "notify";
109
- }>>>;
110
100
  idempotencyKey: z.ZodOptional<z.ZodString>;
111
101
  label: z.ZodOptional<z.ZodString>;
112
102
  fenceToken: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
@@ -141,11 +131,6 @@ export declare const legacyPendingMutationRecordSchema: z.ZodObject<{
141
131
  capturedChanges: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
142
132
  writeOptions: z.ZodOptional<z.ZodObject<{
143
133
  readAt: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
144
- onStale: z.ZodOptional<z.ZodNullable<z.ZodEnum<{
145
- reject: "reject";
146
- overwrite: "overwrite";
147
- notify: "notify";
148
- }>>>;
149
134
  idempotencyKey: z.ZodOptional<z.ZodString>;
150
135
  label: z.ZodOptional<z.ZodString>;
151
136
  fenceToken: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
@@ -179,11 +164,6 @@ export declare const pendingMutationRecordSchema: z.ZodObject<{
179
164
  capturedChanges: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
180
165
  writeOptions: z.ZodOptional<z.ZodObject<{
181
166
  readAt: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
182
- onStale: z.ZodOptional<z.ZodNullable<z.ZodEnum<{
183
- reject: "reject";
184
- overwrite: "overwrite";
185
- notify: "notify";
186
- }>>>;
187
167
  idempotencyKey: z.ZodOptional<z.ZodString>;
188
168
  label: z.ZodOptional<z.ZodString>;
189
169
  fenceToken: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
@@ -17,13 +17,11 @@
17
17
  import { z } from 'zod';
18
18
  import { computePriorityScore, normalizeModelKey } from './commitPayload.js';
19
19
  import { globalRuntime } from '../../context.js';
20
- import { commitEnvelopeMemberSchema, commitOutboxScopeSchema, } from '@abloatai/transaction/transactions/confirmation/commitEnvelope';
21
- import { onStaleModeSchema } from '@abloatai/transaction/coordination/schema';
20
+ import { commitEnvelopeMemberSchema, commitOutboxScopeSchema, } from '@abloatai/transaction/commit';
22
21
  /** The subset of a write's options that is stored with each transaction or queued mutation. */
23
22
  const persistedWriteOptionsSchema = z
24
23
  .object({
25
24
  readAt: z.number().nullable().optional(),
26
- onStale: onStaleModeSchema.nullable().optional(),
27
25
  idempotencyKey: z.string().optional(),
28
26
  label: z.string().optional(),
29
27
  // Aligned with the `WriteOptions` type: a claimed write persisted locally
@@ -1,4 +1,3 @@
1
- import type { OnStaleMode } from '@abloatai/transaction/coordination/schema';
2
1
  type ModelData = Record<string, unknown>;
3
2
  /** One mutation retained in the durable local transaction journal. */
4
3
  interface PersistedMutation {
@@ -8,7 +7,6 @@ interface PersistedMutation {
8
7
  timestamp: string;
9
8
  writeOptions?: {
10
9
  readAt?: number | null;
11
- onStale?: OnStaleMode | null;
12
10
  };
13
11
  }
14
12
  /**
package/dist/plugin.d.ts CHANGED
@@ -17,9 +17,9 @@ import type { ParticipantKind } from '@abloatai/transaction/types/participant';
17
17
  import type { ErrorCodeSpec } from '@abloatai/transaction/errorCodes';
18
18
  import type { Logger } from '@abloatai/transaction/logger';
19
19
  import type { CoordinationObservability } from '@abloatai/transaction/observability';
20
- import type { WsTransport } from '@abloatai/transaction/transport/wsTransport';
20
+ import type { WsTransport } from '@abloatai/transaction/transport/websocket';
21
21
  import type { AuthCredentialSource } from '@abloatai/transaction/auth/credentialSource';
22
- import type { SyncDeltaWireCore } from '@abloatai/transaction/wire/delta';
22
+ import type { SyncDeltaWireCore } from '@abloatai/transaction/observation';
23
23
  import type { ModelData } from '@abloatai/transaction/types/modelData';
24
24
  /**
25
25
  * A string type that keeps literal inference alive: `id: 'humans'` stays the
@@ -22,7 +22,7 @@
22
22
  * • Inbound — the same frame, with `kind` one of `enter`, `update`, or
23
23
  * `leave`.
24
24
  */
25
- import type { WsTransport } from '@abloatai/transaction/transport/wsTransport';
25
+ import type { WsTransport } from '@abloatai/transaction/transport/websocket';
26
26
  import type { PresenceStream } from '@abloatai/transaction/types/streams';
27
27
  import type { ParticipantKind } from '@abloatai/transaction/types/participant';
28
28
  /**
@@ -23,7 +23,7 @@ import { type ReactElement } from 'react';
23
23
  import { type AbloProviderProps } from './AbloProvider.js';
24
24
  import { type AbloSelector, type ModelClientSelector, type UseAbloHydratedModelResult, type UseAbloModelOptions, type UseAbloModelResult } from './useAblo.js';
25
25
  import type { AbloClient as Ablo } from '../client.js';
26
- import type { ModelOperations } from '../local/client/createModelProxy.js';
26
+ import type { ModelOperations } from '../local/client/createModelOperations.js';
27
27
  import type { Schema, SchemaRecord } from '@abloatai/transaction/schema/schema';
28
28
  /** What a binding returns: the provider and the hook, with `S` fixed. */
29
29
  export interface AbloReactBinding<S extends SchemaRecord> {
@@ -1,6 +1,6 @@
1
1
  import type { AbloClient as Ablo, AbloReads } from '../client.js';
2
2
  import type { ModelClaim } from '@abloatai/transaction/coordination';
3
- import { type ModelOperations } from '../local/client/createModelProxy.js';
3
+ import { type ModelOperations } from '../local/client/createModelOperations.js';
4
4
  import type { SchemaRecord } from '@abloatai/transaction/schema/schema';
5
5
  import type { ResolveSchema } from '@abloatai/transaction/types/global';
6
6
  /**
@@ -54,7 +54,7 @@ export type UseAbloHydratedModelResult<T> = Omit<UseAbloModelResult<T>, 'data'>
54
54
  * // With the Register augmentation (recommended):
55
55
  * const ablo = useAblo();
56
56
  * if (!ablo) return <Loading />;
57
- * const doc = await ablo.records.get({ id }); // async server read
57
+ * const doc = await ablo.records.get({ id }); // observational async server read
58
58
  *
59
59
  * // Reactive selector (a synchronous local snapshot). The selector's reads
60
60
  * // are typed as snapshot rows — data fields + computeds, no relation
@@ -1,7 +1,7 @@
1
1
  'use client';
2
2
  import { useContext, useEffect, useState } from 'react';
3
3
  import { AbloInternalContext } from './internalContext.js';
4
- import { getModelClientMeta, } from '../local/client/createModelProxy.js';
4
+ import { getModelClientMeta, } from '../local/client/createModelOperations.js';
5
5
  import { Model } from '../local/Model.js';
6
6
  import { useReactive } from '../useReactive.js';
7
7
  const EMPTY_CLAIMS = Object.freeze([]);
package/dist/surface.d.ts CHANGED
@@ -19,7 +19,7 @@
19
19
  * tuple, so it is the one list of model-verb names a generated summary can
20
20
  * describe.
21
21
  */
22
- export declare const PUBLIC_MODEL_VERBS: readonly ["get", "retrieve", "list", "local", "create", "update", "delete", "claim", "track", "join", "onChange"];
22
+ export declare const PUBLIC_MODEL_VERBS: readonly ["get", "read", "list", "listAll", "local", "create", "update", "delete", "claim", "join", "onChange"];
23
23
  /**
24
24
  * The option keys accepted by `local.list` and `onChange`, matching the
25
25
  * keys of {@link LocalReadOptions}. Note that the lifecycle filter is named
package/dist/surface.js CHANGED
@@ -22,14 +22,14 @@
22
22
  */
23
23
  export const PUBLIC_MODEL_VERBS = [
24
24
  'get',
25
- 'retrieve',
25
+ 'read',
26
26
  'list',
27
+ 'listAll',
27
28
  'local',
28
29
  'create',
29
30
  'update',
30
31
  'delete',
31
32
  'claim',
32
- 'track',
33
33
  'join',
34
34
  'onChange',
35
35
  ];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abloatai/humans",
3
- "version": "0.56.0",
3
+ "version": "0.58.0",
4
4
  "description": "The optional human-facing local-state package for Ablo: presence, live queries, and React bindings.",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
@@ -84,7 +84,7 @@
84
84
  "directory": "packages/humans"
85
85
  },
86
86
  "dependencies": {
87
- "@abloatai/transaction": "^0.56.0",
87
+ "@abloatai/transaction": "^0.58.0",
88
88
  "mobx": "^6.13.7",
89
89
  "uuid": "^11.1.0",
90
90
  "zod": "^4.4.3"
package/src/Ablo.ts CHANGED
@@ -224,7 +224,7 @@ export function Ablo<const S extends SchemaRecord>(
224
224
  //
225
225
  // One default import, with types hung underneath via namespace dots:
226
226
  // `import { Ablo } from "@abloatai/humans"` gets the factory, its return type, and
227
- // every type a typical consumer references (`Ablo.Peer`, `Ablo.Snapshot<S, K>`,
227
+ // every type a typical consumer references (`Ablo.Peer`,
228
228
  // and so on) — all purely type-level, with zero runtime cost.
229
229
  //
230
230
  // The types still live in their canonical homes (`types/streams`, `principal`,
@@ -233,7 +233,6 @@ export function Ablo<const S extends SchemaRecord>(
233
233
 
234
234
  import type * as _Streams from '@abloatai/transaction/types/streams';
235
235
  import type * as _Participants from './local/sync/participants.js';
236
- import type * as _Policy from '@abloatai/transaction/policy/types';
237
236
  import type * as _Mutators from './local/mutators/defineMutators.js';
238
237
  import type * as _Tx from './local/mutators/Transaction.js';
239
238
  import type * as _Undo from './local/mutators/UndoManager.js';
@@ -292,12 +291,6 @@ export namespace Ablo {
292
291
  export type ClaimHeartbeat = _Streams.ClaimHeartbeat;
293
292
  export type ClaimHeartbeatOptions = _Streams.ClaimHeartbeatOptions;
294
293
 
295
- // ── Singletons (flat — no cohort) ─────────────────────────────────
296
- export type Snapshot<
297
- TSchema extends _SchemaTypes.Schema = _SchemaTypes.Schema,
298
- K extends keyof TSchema['models'] = keyof TSchema['models'],
299
- > = _Streams.Snapshot<TSchema, K>;
300
-
301
294
  // ── Auth (sub-namespace — actor attribution) ──────────────────────
302
295
  // eslint-disable-next-line @typescript-eslint/no-namespace
303
296
  export namespace Auth {
@@ -359,17 +352,6 @@ export namespace Ablo {
359
352
  export type InferModelNames<S extends _SchemaTypes.Schema> = _SchemaTypes.InferModelNames<S>;
360
353
  }
361
354
 
362
- // ── Conflict (type + sub-namespace via declaration merge) ─────────
363
- export type Conflict = _Policy.Conflict;
364
- // eslint-disable-next-line @typescript-eslint/no-namespace
365
- export namespace Conflict {
366
- export type Kind = _Policy.ConflictKind;
367
- export type Operation = _Policy.ConflictOperation;
368
- export type Decision = _Policy.ConflictDecision;
369
- export type Policy = _Policy.ConflictPolicy;
370
- export type Axis = _Policy.ConflictAxis;
371
- }
372
-
373
355
  // ── Commit (sub-namespace — write-side cohort) ────────────────────
374
356
  // eslint-disable-next-line @typescript-eslint/no-namespace
375
357
  export namespace Commit {
@@ -389,11 +371,11 @@ export namespace Ablo {
389
371
  export type CreateOptions = import('./local/client/resourceTypes.js').ClaimCreateOptions;
390
372
  export type WaitOptions = import('./local/client/resourceTypes.js').ClaimWaitOptions;
391
373
  export type ContentionOptions =
392
- import('@abloatai/transaction/resources/modelOperations').ClaimContentionOptions;
374
+ import('@abloatai/transaction/client/resources/modelOperations').ClaimContentionOptions;
393
375
  export type AttemptEvent =
394
- import('@abloatai/transaction/resources/modelOperations').ClaimAttemptEvent;
376
+ import('@abloatai/transaction/client/resources/modelOperations').ClaimAttemptEvent;
395
377
  export type QueueView =
396
- import('@abloatai/transaction/resources/modelOperations').ClaimQueueView;
378
+ import('@abloatai/transaction/client/resources/modelOperations').ClaimQueueView;
397
379
  export type Client = import('./local/client/resourceTypes.js').ClaimResource;
398
380
  }
399
381
 
@@ -402,18 +384,18 @@ export namespace Ablo {
402
384
  export namespace Model {
403
385
  export type Target = import('./local/client/resourceTypes.js').ModelTarget;
404
386
  export type Claim = import('./local/client/resourceTypes.js').ModelClaim;
405
- export type Operations<T, CreateInput = T> = import('./local/client/createModelProxy.js').ModelOperations<
387
+ export type Operations<T, CreateInput = T> = import('./local/client/createModelOperations.js').ModelOperations<
406
388
  T,
407
389
  CreateInput
408
390
  >;
409
391
  export type ClaimOptions<T = Record<string, unknown>> =
410
- import('./local/client/createModelProxy.js').ClaimOptions<T>;
392
+ import('./local/client/createModelOperations.js').ClaimOptions<T>;
411
393
  export type ClaimParams<T = Record<string, unknown>> =
412
- import('./local/client/createModelProxy.js').ClaimParams<T>;
394
+ import('./local/client/createModelOperations.js').ClaimParams<T>;
413
395
  export type ClaimLookupParams<T = Record<string, unknown>> =
414
- import('./local/client/createModelProxy.js').ClaimLookupParams<T>;
396
+ import('./local/client/createModelOperations.js').ClaimLookupParams<T>;
415
397
  export type ClaimReorderParams<T = Record<string, unknown>> =
416
- import('./local/client/createModelProxy.js').ClaimReorderParams<T>;
398
+ import('./local/client/createModelOperations.js').ClaimReorderParams<T>;
417
399
  export type MutationOptions = import('./local/client/resourceTypes.js').ModelMutationOptions;
418
400
  }
419
401
 
package/src/client.ts CHANGED
@@ -18,19 +18,21 @@ import type {
18
18
  InferCreate,
19
19
  InferRow,
20
20
  } from '@abloatai/transaction/schema/schema';
21
- import type { PresenceStream, Snapshot } from '@abloatai/transaction/types/streams';
21
+ import type { PresenceStream } from '@abloatai/transaction/types/streams';
22
22
  import type { InstanceCache } from './local/InstanceCache.js';
23
23
  import type { SyncStoreContract } from './react/context.js';
24
24
  import type { SyncWebSocket, CoreSyncEventMap } from './local/sync/SyncWebSocket.js';
25
25
  import type { SyncStatus } from './local/BaseSyncedStore.js';
26
- import type { ModelOperations } from './local/client/createModelProxy.js';
26
+ import type { ModelOperations } from './local/client/createModelOperations.js';
27
27
  import type {
28
28
  ClaimResource,
29
29
  CommitResource,
30
30
  CreateAgentClientParams,
31
31
  SessionResource,
32
- } from '@abloatai/transaction/resources/httpResources';
32
+ } from '@abloatai/transaction/client/resources/httpResources';
33
33
  import type { EffectiveAuthority } from '@abloatai/transaction/auth';
34
+ import type { ReadDependency } from '@abloatai/transaction/coordination';
35
+ import type { CapturedRow } from '@abloatai/transaction/transport/http';
34
36
  export type { LocalReadOptions } from './local/client/resourceTypes.js';
35
37
 
36
38
  /** The typed sync engine client — one property per model in the schema */
@@ -310,25 +312,7 @@ export type AbloClient<S extends SchemaRecord> = {
310
312
  * Canonical low-level mutation API. Every untyped model write compiles
311
313
  * down to `commits.create(...)`.
312
314
  */
313
- readonly commits: CommitResource;
314
-
315
- /**
316
- * Capture a context-staleness watermark over a set of entities.
317
- * Returns a flat snapshot with `stamp` (thread into writes as
318
- * `readAt`), `signal` (aborts on any captured-entity delta), and
319
- * `onChange` (callback form). Reads from the engine's InstanceCache;
320
- * subscription is on the engine's existing transport.
321
- *
322
- * Use before an LLM call to prevent the model from completing
323
- * against now-stale data:
324
- * ```ts
325
- * const snap = engine.snapshot({ sections: report.sectionIds });
326
- * await streamText({ messages, signal: snap.signal });
327
- * ```
328
- */
329
- snapshot<ModelName extends keyof S & string>(
330
- entities: Readonly<Record<ModelName, string | readonly string[]>>,
331
- ): Snapshot<Schema<S>, ModelName>;
315
+ readonly commits: CommitResource<ReadDependency | CapturedRow>;
332
316
 
333
317
  /**
334
318
  * Subscribe to pushed frames — deltas, presence updates, claim grants and
package/src/core.ts CHANGED
@@ -92,7 +92,7 @@ export {
92
92
  export {
93
93
  awaitClaimGrant,
94
94
  type GrantTransport,
95
- } from '@abloatai/transaction/coordination/awaitClaimGrant';
95
+ } from '@abloatai/transaction/claims';
96
96
 
97
97
  // An enum naming the strategies for loading a model's data. Referenced when
98
98
  // registering models in extension code.