@abloatai/transaction 0.59.1 → 0.60.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 (166) hide show
  1. package/dist/auth/apiKey.d.ts +10 -11
  2. package/dist/auth/apiKey.d.ts.map +1 -1
  3. package/dist/auth/apiKey.js +15 -29
  4. package/dist/auth/apiKey.js.map +1 -1
  5. package/dist/auth/browserCredentialSafety.js +1 -1
  6. package/dist/auth/browserCredentialSafety.js.map +1 -1
  7. package/dist/auth/capabilityLifecycle.d.ts +1 -1
  8. package/dist/auth/capabilityLifecycle.d.ts.map +1 -1
  9. package/dist/auth/capabilityLifecycle.js +2 -1
  10. package/dist/auth/capabilityLifecycle.js.map +1 -1
  11. package/dist/auth/credentialEndpoint.js +1 -1
  12. package/dist/auth/credentialEndpoint.js.map +1 -1
  13. package/dist/auth/credentialResult.d.ts +2 -1
  14. package/dist/auth/credentialResult.d.ts.map +1 -1
  15. package/dist/auth/credentialResult.js.map +1 -1
  16. package/dist/claims/events.d.ts +1 -1
  17. package/dist/claims/events.d.ts.map +1 -1
  18. package/dist/client/ablo.d.ts +15 -11
  19. package/dist/client/ablo.d.ts.map +1 -1
  20. package/dist/client/ablo.js +5 -14
  21. package/dist/client/ablo.js.map +1 -1
  22. package/dist/client/resources/httpResources.d.ts +1 -169
  23. package/dist/client/resources/httpResources.d.ts.map +1 -1
  24. package/dist/client/resources/httpResources.js +1 -1
  25. package/dist/client/resources/httpResources.js.map +1 -1
  26. package/dist/client/resources/modelOperations.d.ts +0 -9
  27. package/dist/client/resources/modelOperations.d.ts.map +1 -1
  28. package/dist/client/surface.d.ts +2 -2
  29. package/dist/client/surface.d.ts.map +1 -1
  30. package/dist/client/surface.js +8 -3
  31. package/dist/client/surface.js.map +1 -1
  32. package/dist/commit/contract.d.ts +10 -10
  33. package/dist/commit/recordRuntime.d.ts +3 -2
  34. package/dist/commit/recordRuntime.d.ts.map +1 -1
  35. package/dist/commit/recordRuntime.js +1 -0
  36. package/dist/commit/recordRuntime.js.map +1 -1
  37. package/dist/coordination/index.d.ts +2 -2
  38. package/dist/coordination/index.d.ts.map +1 -1
  39. package/dist/coordination/index.js +3 -4
  40. package/dist/coordination/index.js.map +1 -1
  41. package/dist/coordination/schema.d.ts +3 -47
  42. package/dist/coordination/schema.d.ts.map +1 -1
  43. package/dist/coordination/schema.js +7 -69
  44. package/dist/coordination/schema.js.map +1 -1
  45. package/dist/errorCodes.d.ts +2 -2
  46. package/dist/errorCodes.d.ts.map +1 -1
  47. package/dist/errorCodes.js +5 -9
  48. package/dist/errorCodes.js.map +1 -1
  49. package/dist/errors.d.ts.map +1 -1
  50. package/dist/errors.js +16 -1
  51. package/dist/errors.js.map +1 -1
  52. package/dist/index.d.ts +1 -1
  53. package/dist/index.d.ts.map +1 -1
  54. package/dist/index.js.map +1 -1
  55. package/dist/sessions/client.d.ts +29 -0
  56. package/dist/sessions/client.d.ts.map +1 -0
  57. package/dist/sessions/client.js +69 -0
  58. package/dist/sessions/client.js.map +1 -0
  59. package/dist/sessions/contract.d.ts +97 -0
  60. package/dist/sessions/contract.d.ts.map +1 -0
  61. package/dist/sessions/contract.js +5 -0
  62. package/dist/sessions/contract.js.map +1 -0
  63. package/dist/{auth/sessionMint.d.ts → sessions/create.d.ts} +4 -4
  64. package/dist/sessions/create.d.ts.map +1 -0
  65. package/dist/{auth/sessionMint.js → sessions/create.js} +11 -10
  66. package/dist/sessions/create.js.map +1 -0
  67. package/dist/sessions/handler.d.ts +23 -0
  68. package/dist/sessions/handler.d.ts.map +1 -0
  69. package/dist/sessions/handler.js +55 -0
  70. package/dist/sessions/handler.js.map +1 -0
  71. package/dist/sessions/index.d.ts +14 -0
  72. package/dist/sessions/index.d.ts.map +1 -0
  73. package/dist/sessions/index.js +14 -0
  74. package/dist/sessions/index.js.map +1 -0
  75. package/dist/{transport/connection/credentialLifecycle.d.ts → sessions/lifecycle.d.ts} +6 -6
  76. package/dist/sessions/lifecycle.d.ts.map +1 -0
  77. package/dist/{transport/connection/credentialLifecycle.js → sessions/lifecycle.js} +5 -5
  78. package/dist/sessions/lifecycle.js.map +1 -0
  79. package/dist/sessions/source.d.ts +24 -0
  80. package/dist/sessions/source.d.ts.map +1 -0
  81. package/dist/sessions/source.js +56 -0
  82. package/dist/sessions/source.js.map +1 -0
  83. package/dist/transport/connection/index.d.ts +0 -1
  84. package/dist/transport/connection/index.d.ts.map +1 -1
  85. package/dist/transport/connection/index.js +0 -1
  86. package/dist/transport/connection/index.js.map +1 -1
  87. package/dist/transport/connection/manager.d.ts +1 -1
  88. package/dist/transport/connection/manager.d.ts.map +1 -1
  89. package/dist/transport/http/client.d.ts +44 -16
  90. package/dist/transport/http/client.d.ts.map +1 -1
  91. package/dist/transport/http/client.js +125 -12
  92. package/dist/transport/http/client.js.map +1 -1
  93. package/dist/transport/http/options.d.ts +4 -1
  94. package/dist/transport/http/options.d.ts.map +1 -1
  95. package/dist/transport/http/transport.d.ts +25 -10
  96. package/dist/transport/http/transport.d.ts.map +1 -1
  97. package/dist/transport/http/transport.js +102 -56
  98. package/dist/transport/http/transport.js.map +1 -1
  99. package/dist/transport/websocket/commitFrames.d.ts +5 -5
  100. package/dist/transport/websocket/commitFrames.d.ts.map +1 -1
  101. package/dist/transport/websocket/commitFrames.js +1 -0
  102. package/dist/transport/websocket/commitFrames.js.map +1 -1
  103. package/dist/transport/websocket/contextSubscription.d.ts +6 -0
  104. package/dist/transport/websocket/contextSubscription.d.ts.map +1 -0
  105. package/dist/transport/websocket/contextSubscription.js +45 -0
  106. package/dist/transport/websocket/contextSubscription.js.map +1 -0
  107. package/dist/transport/websocket/frameHandlers.d.ts +0 -14
  108. package/dist/transport/websocket/frameHandlers.d.ts.map +1 -1
  109. package/dist/transport/websocket/frameHandlers.js +1 -71
  110. package/dist/transport/websocket/frameHandlers.js.map +1 -1
  111. package/dist/transport/websocket/session.d.ts +4 -0
  112. package/dist/transport/websocket/session.d.ts.map +1 -0
  113. package/dist/transport/websocket/session.js +425 -0
  114. package/dist/transport/websocket/session.js.map +1 -0
  115. package/dist/transport/websocket/sessionContract.d.ts +78 -0
  116. package/dist/transport/websocket/sessionContract.d.ts.map +1 -0
  117. package/dist/transport/websocket/sessionContract.js +2 -0
  118. package/dist/transport/websocket/sessionContract.js.map +1 -0
  119. package/dist/transport/websocket/transport.d.ts +27 -42
  120. package/dist/transport/websocket/transport.d.ts.map +1 -1
  121. package/dist/transport/websocket/transport.js +77 -102
  122. package/dist/transport/websocket/transport.js.map +1 -1
  123. package/dist/wire/inboundFrames.d.ts +0 -10
  124. package/dist/wire/inboundFrames.d.ts.map +1 -1
  125. package/dist/wire/inboundFrames.js +1 -6
  126. package/dist/wire/inboundFrames.js.map +1 -1
  127. package/package.json +7 -1
  128. package/src/auth/apiKey.ts +25 -44
  129. package/src/auth/browserCredentialSafety.ts +1 -1
  130. package/src/auth/capabilityLifecycle.ts +3 -2
  131. package/src/auth/credentialEndpoint.ts +1 -1
  132. package/src/auth/credentialResult.ts +2 -0
  133. package/src/claims/events.ts +1 -2
  134. package/src/client/ablo.ts +23 -13
  135. package/src/client/resources/httpResources.ts +2 -174
  136. package/src/client/resources/modelOperations.ts +0 -10
  137. package/src/client/surface.ts +9 -4
  138. package/src/commit/recordRuntime.ts +4 -2
  139. package/src/coordination/index.ts +2 -9
  140. package/src/coordination/schema.ts +7 -81
  141. package/src/errorCodes.ts +8 -13
  142. package/src/errors.ts +18 -1
  143. package/src/index.ts +1 -0
  144. package/src/sessions/client.ts +121 -0
  145. package/src/sessions/contract.ts +116 -0
  146. package/src/{auth/sessionMint.ts → sessions/create.ts} +13 -12
  147. package/src/sessions/handler.ts +96 -0
  148. package/src/sessions/index.ts +13 -0
  149. package/src/{transport/connection/credentialLifecycle.ts → sessions/lifecycle.ts} +5 -5
  150. package/src/sessions/source.ts +94 -0
  151. package/src/transport/connection/index.ts +0 -1
  152. package/src/transport/connection/manager.ts +1 -1
  153. package/src/transport/http/client.ts +183 -26
  154. package/src/transport/http/options.ts +4 -1
  155. package/src/transport/http/transport.ts +140 -78
  156. package/src/transport/websocket/commitFrames.ts +5 -5
  157. package/src/transport/websocket/contextSubscription.ts +55 -0
  158. package/src/transport/websocket/frameHandlers.ts +0 -102
  159. package/src/transport/websocket/session.ts +522 -0
  160. package/src/transport/websocket/sessionContract.ts +106 -0
  161. package/src/transport/websocket/transport.ts +85 -137
  162. package/src/wire/inboundFrames.ts +0 -6
  163. package/dist/auth/sessionMint.d.ts.map +0 -1
  164. package/dist/auth/sessionMint.js.map +0 -1
  165. package/dist/transport/connection/credentialLifecycle.d.ts.map +0 -1
  166. package/dist/transport/connection/credentialLifecycle.js.map +0 -1
@@ -22,28 +22,22 @@ import { EventEmitter } from 'events';
22
22
  import type { ParticipantKind } from '../../types/participant.js';
23
23
  import {
24
24
  AbloConnectionError,
25
- AbloError,
26
25
  AbloSessionError,
27
26
  AbloValidationError,
28
27
  toAbloError,
29
28
  } from '../../errors.js';
30
- import {
31
- participantClaimPayloadSchema,
32
- updateSubscriptionPayloadSchema,
33
- } from '../../coordination/schema.js';
29
+ import { updateSubscriptionPayloadSchema } from '../../coordination/schema.js';
34
30
  import type { BootstrapReason } from '../../wire/bootstrapReason.js';
35
31
  import type { ClientSyncDelta } from '../../observation/contract.js';
36
32
  import type {
37
33
  ClaimAcquired,
38
34
  PresenceUpdate,
39
- ClaimExpired,
40
35
  ClaimGranted,
41
36
  ClaimHeartbeatAckPayload,
42
37
  ClaimLost,
43
38
  ClaimQueue,
44
39
  ClaimQueued,
45
40
  ClaimRejection,
46
- ParticipantClaimPayload,
47
41
  ReadDependency,
48
42
  WireClaim,
49
43
  } from '../../coordination/schema.js';
@@ -60,7 +54,6 @@ import {
60
54
  readWsInboundFrame,
61
55
  type WsSession,
62
56
  type PendingCommit,
63
- type PendingClaim,
64
57
  type PendingSubscription,
65
58
  } from './frameHandlers.js';
66
59
  import { HeartbeatController } from './heartbeat.js';
@@ -203,6 +196,7 @@ export interface CoreSyncEventMap {
203
196
  presence_update: [PresenceUpdate];
204
197
  error: [Error];
205
198
  session_error: [Error];
199
+ protocol_mismatch: [CloseEvent];
206
200
  /**
207
201
  * The WebSocket `onclose` fired before `onopen` — the handshake itself
208
202
  * failed. The browser cannot expose the HTTP status (it shows as code
@@ -212,14 +206,6 @@ export interface CoreSyncEventMap {
212
206
  */
213
207
  handshake_failed: [CloseEvent];
214
208
  reconnect_failed: [{ attempts: number }];
215
- /**
216
- * Server-initiated notification that a previously-active claim's
217
- * TTL has expired. Consumers (e.g., the participant SDK) re-mint
218
- * a fresh capability and re-claim, OR accept the drop. The claim
219
- * is already inactive on the server side by the time this fires —
220
- * no client-side action needed unless re-claiming.
221
- */
222
- claim_expired: [ClaimExpired];
223
209
  /**
224
210
  * Server rejected an `claim_begin` because another participant
225
211
  * already holds an open claim on the same target (cooperative
@@ -369,6 +355,10 @@ export class WsTransport<
369
355
  * server rejected the upgrade" since browsers hide the HTTP status (e.g.
370
356
  * 401) behind the opaque 1006 close code. */
371
357
  private _everOpened = false;
358
+ /** True after any socket in this logical transport has opened. Unlike
359
+ * `_everOpened`, this survives socket replacement so a failed reconnect
360
+ * handshake is retried instead of being mistaken for a failed first login. */
361
+ private _hasConnected = false;
372
362
  /**
373
363
  * Diagnostic snapshot of the last connection lifecycle. Persisted across
374
364
  * the lifetime of the transport so that any subsequent "not connected"
@@ -404,14 +394,6 @@ export class WsTransport<
404
394
  */
405
395
  private pendingMutations = new Map<string, PendingCommit>();
406
396
 
407
- /**
408
- * In-flight `claim` requests keyed by claimId. Resolved when the matching
409
- * `claim_ack` arrives, or rejected on timeout or disconnect — the same
410
- * request/response pattern as `pendingMutations`, multiplexed over the one
411
- * connection.
412
- */
413
- private pendingClaims = new Map<string, PendingClaim>();
414
-
415
397
  /**
416
398
  * In-flight `update_subscription` frames awaiting `subscription_ack`.
417
399
  * A FIFO queue rather than a keyed Map because the wire ack carries no
@@ -482,7 +464,6 @@ export class WsTransport<
482
464
  logger: this.logger,
483
465
  observability: this.observability,
484
466
  pendingMutations: this.pendingMutations,
485
- pendingClaims: this.pendingClaims,
486
467
  shiftPendingSubscription: () => this.pendingSubscriptions.shift(),
487
468
  options: this.options,
488
469
  collaborationEventTypes: this.collaborationEventTypes,
@@ -730,6 +711,7 @@ export class WsTransport<
730
711
  this.isConnecting = false;
731
712
  this.reconnectAttempts = 0;
732
713
  this._everOpened = true;
714
+ this._hasConnected = true;
733
715
  this.lastOpenAt = Date.now();
734
716
  this.emit('connected');
735
717
 
@@ -860,22 +842,6 @@ export class WsTransport<
860
842
  this.pendingMutations.clear();
861
843
  }
862
844
 
863
- // Cancel in-flight claims — same rationale. Server-side
864
- // claims are bound to the connection; a reconnect will need
865
- // to re-claim. Higher-level retry belongs to whoever holds
866
- // the participant handle (typically the SDK's claim manager).
867
- if (this.pendingClaims.size > 0) {
868
- for (const pending of this.pendingClaims.values()) {
869
- clearTimeout(pending.timeout);
870
- pending.reject(
871
- new AbloConnectionError(
872
- `WebSocket closed while claim was in flight (code=${event.code})`,
873
- ),
874
- );
875
- }
876
- this.pendingClaims.clear();
877
- }
878
-
879
845
  // Cancel in-flight subscription updates — the reconnect handshake
880
846
  // re-sends `options.syncGroups` (the last acked interest) in the
881
847
  // upgrade URL, so a pending change that never acked is simply
@@ -945,7 +911,7 @@ export class WsTransport<
945
911
  // from a transient network issue and transition the UI accordingly.
946
912
  // Reconnecting blindly is what produced the infinite
947
913
  // "offline → reconnecting → offline" loop on stale cookies.
948
- if (!everOpened && !this.isManualClose) {
914
+ if (!everOpened && !this._hasConnected && !this.isManualClose) {
949
915
  this.observability.captureWebSocketError({
950
916
  context: 'handshake-failed-close',
951
917
  code: event.code,
@@ -998,6 +964,77 @@ export class WsTransport<
998
964
  }
999
965
  }
1000
966
 
967
+ /**
968
+ * Ask the server for every durable delta after the supplied position.
969
+ *
970
+ * This is deliberately part of the carrier rather than the reactive
971
+ * materialiser: browser stores and headless WebSocket clients resume the same
972
+ * ordered protocol. The owner decides when a received position is durable
973
+ * enough to acknowledge.
974
+ */
975
+ requestSync(position: {
976
+ readonly cursor?: string | null;
977
+ readonly lastSyncId: number;
978
+ }): void {
979
+ if (this.ws?.readyState !== WebSocket.OPEN) {
980
+ throw this.notConnectedError('sync_request');
981
+ }
982
+ const capabilities = Object.entries(this.options.capabilities)
983
+ .filter(([, enabled]) => enabled)
984
+ .map(([name]) => name);
985
+ this.send({
986
+ type: 'sync_request',
987
+ payload: {
988
+ cursor: position.cursor ?? null,
989
+ lastSyncId: position.lastSyncId,
990
+ capabilities,
991
+ protocolVersion: PROTOCOL_VERSION,
992
+ },
993
+ });
994
+ }
995
+
996
+ /** Persist the server-side resume position after the caller durably applied it. */
997
+ acknowledge(lastSyncId: number): void {
998
+ if (!Number.isSafeInteger(lastSyncId) || lastSyncId < 0) {
999
+ throw new AbloValidationError('acknowledge requires a non-negative safe integer.', {
1000
+ code: 'invalid_request',
1001
+ });
1002
+ }
1003
+ if (this.ws?.readyState !== WebSocket.OPEN) return;
1004
+ this.send({ type: 'ack', payload: { lastSyncId } });
1005
+ }
1006
+
1007
+ /** Announce this participant's current presence on the shared connection. */
1008
+ updatePresence(input: {
1009
+ readonly status?: 'online' | 'away' | 'offline';
1010
+ readonly customStatus?: string;
1011
+ readonly timezone?: string;
1012
+ readonly activity?: Record<string, unknown>;
1013
+ } = {}): void {
1014
+ if (this.ws?.readyState !== WebSocket.OPEN) {
1015
+ throw this.notConnectedError('presence_update');
1016
+ }
1017
+ let timezone = input.timezone;
1018
+ if (!timezone) {
1019
+ try {
1020
+ timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
1021
+ } catch {
1022
+ timezone = 'UTC';
1023
+ }
1024
+ }
1025
+ this.send({
1026
+ type: 'presence_update',
1027
+ payload: {
1028
+ status: input.status ?? 'online',
1029
+ timezone,
1030
+ ...(input.customStatus !== undefined
1031
+ ? { customStatus: input.customStatus }
1032
+ : {}),
1033
+ ...(input.activity !== undefined ? { activity: input.activity } : {}),
1034
+ },
1035
+ });
1036
+ }
1037
+
1001
1038
  /**
1002
1039
  * Sends a `commit` mutation request over the existing WebSocket and resolves
1003
1040
  * when the server's `mutation_result` frame comes back with the same
@@ -1100,100 +1137,6 @@ export class WsTransport<
1100
1137
  this.ws.send(JSON.stringify(frame));
1101
1138
  }
1102
1139
 
1103
- /**
1104
- * Activates a participant claim on this connection. One connection can hold
1105
- * several concurrent claims at once, each scoped to a different set of sync
1106
- * groups, so the SDK reuses the existing connection instead of opening a
1107
- * separate socket per scope.
1108
- *
1109
- * Returns a promise that resolves with the server-canonicalized `syncGroups`
1110
- * and effective `ttlSeconds` once `claim_ack` arrives, or rejects with a typed
1111
- * error on a failed ack, a timeout, or a disconnect.
1112
- */
1113
- sendClaim(
1114
- claimId: string,
1115
- syncGroups: readonly string[],
1116
- options?: Pick<ParticipantClaimPayload, 'capabilityToken' | 'ttlSeconds'> & {
1117
- timeoutMs?: number;
1118
- },
1119
- ): Promise<{ syncGroups: string[]; ttlSeconds?: number }> {
1120
- if (this.ws?.readyState !== WebSocket.OPEN) {
1121
- return Promise.reject(this.notConnectedError('claim'));
1122
- }
1123
- // Checked against the schema the server ingests it with, for the same
1124
- // reason `updateSubscription` below is: the two frames name their scopes
1125
- // identically, so a group that would be refused there is refused here, at
1126
- // the call that asked for it, rather than coming back as a failed ack a
1127
- // round trip later with nothing to point at.
1128
- const payload = participantClaimPayloadSchema.safeParse({
1129
- claimId,
1130
- syncGroups: [...syncGroups],
1131
- capabilityToken: options?.capabilityToken,
1132
- ttlSeconds: options?.ttlSeconds,
1133
- });
1134
- if (!payload.success) {
1135
- return Promise.reject(
1136
- new AbloValidationError(
1137
- `join was given a sync group the protocol does not accept: ${payload.error.issues[0]?.message ?? 'unreadable'}. A group is 'default' or 'kind:id'.`,
1138
- { code: 'malformed_claim' },
1139
- ),
1140
- );
1141
- }
1142
- const timeoutMs = options?.timeoutMs ?? 15_000;
1143
- return new Promise((resolve, reject) => {
1144
- const timeout = setTimeout(() => {
1145
- this.pendingClaims.delete(claimId);
1146
- reject(
1147
- new AbloConnectionError(`claim timed out after ${timeoutMs}ms (claimId=${claimId})`, {
1148
- code: 'wait_for_timeout',
1149
- }),
1150
- );
1151
- }, timeoutMs);
1152
- this.pendingClaims.set(claimId, { resolve, reject, timeout });
1153
- try {
1154
- this.ws!.send(JSON.stringify({ type: 'claim', payload: payload.data }));
1155
- } catch (error) {
1156
- clearTimeout(timeout);
1157
- this.pendingClaims.delete(claimId);
1158
- reject(toAbloError(error));
1159
- }
1160
- });
1161
- }
1162
-
1163
- /**
1164
- * Drop a previously-active claim. Idempotent — `release` is
1165
- * fire-and-forget per the wire contract; the server accepts
1166
- * unknown claimIds silently so disconnect-time release storms
1167
- * never error. No ack is expected.
1168
- *
1169
- * If a claim's send promise is still pending (no claim_ack yet),
1170
- * we reject it locally — the user explicitly chose to release.
1171
- */
1172
- sendRelease(claimId: string): void {
1173
- // Cancel any in-flight claim that hadn't acked yet — the user
1174
- // changed their mind. Without this the timer would eventually
1175
- // reject; doing it now matches the user's claim immediately.
1176
- const pending = this.pendingClaims.get(claimId);
1177
- if (pending) {
1178
- clearTimeout(pending.timeout);
1179
- this.pendingClaims.delete(claimId);
1180
- pending.reject(
1181
- new AbloError(`claim ${claimId} released before ack`, {
1182
- code: 'claim_wait_aborted',
1183
- httpStatus: 409,
1184
- }),
1185
- );
1186
- }
1187
- if (this.ws?.readyState !== WebSocket.OPEN) return;
1188
- try {
1189
- this.ws.send(
1190
- JSON.stringify({ type: 'release', payload: { claimId } }),
1191
- );
1192
- } catch {
1193
- // Idempotent contract — silent failure is acceptable here.
1194
- }
1195
- }
1196
-
1197
1140
  /**
1198
1141
  * Moves this connection's read interest — replaces the connection-level sync
1199
1142
  * groups mid-session as the user opens and closes entities. This is the
@@ -1371,8 +1314,13 @@ export class WsTransport<
1371
1314
  }
1372
1315
 
1373
1316
  if (this.ws) {
1374
- this.ws.close(1000, 'Manual disconnect');
1317
+ // Detach before close: Node/undici may synchronously fire `onerror` from
1318
+ // close(). The handler's stale-socket guard then suppresses that expected
1319
+ // manual-close error instead of emitting EventEmitter's fatal unhandled
1320
+ // `error` event. `onclose` deliberately accepts a null owner below.
1321
+ const socket = this.ws;
1375
1322
  this.ws = null;
1323
+ socket.close(1000, 'Manual disconnect');
1376
1324
  }
1377
1325
  }
1378
1326
 
@@ -28,7 +28,6 @@ import { commitReceiptSchema } from '../commit/contract.js';
28
28
  import { clientSyncDeltaSchema } from '../observation/contract.js';
29
29
  import {
30
30
  claimAcquiredSchema,
31
- claimExpiredSchema,
32
31
  claimGrantedSchema,
33
32
  claimHeartbeatAckPayloadSchema,
34
33
  claimLostSchema,
@@ -111,10 +110,6 @@ export const WS_INBOUND_FRAMES = {
111
110
  },
112
111
 
113
112
  // ── Requests we made ───────────────────────────────────────────────────
114
- claim_ack: {
115
- validation: 'handler',
116
- where: 'handleClaimAck narrows field by field, because a rejection carries a typed capability error it has to re-raise as CapabilityError',
117
- },
118
113
  subscription_ack: {
119
114
  validation: 'handler',
120
115
  // Not parsed at dispatch because the handler must first claim the oldest
@@ -126,7 +121,6 @@ export const WS_INBOUND_FRAMES = {
126
121
 
127
122
  // ── Coordination ───────────────────────────────────────────────────────
128
123
  presence_update: { validation: 'schema', payload: presenceUpdateSchema },
129
- claim_expired: { validation: 'schema', payload: claimExpiredSchema },
130
124
  claim_rejected: { validation: 'schema', payload: claimRejectionSchema },
131
125
  claim_acquired: { validation: 'schema', payload: claimAcquiredSchema },
132
126
  claim_queued: { validation: 'schema', payload: claimQueuedSchema },
@@ -1 +0,0 @@
1
- {"version":3,"file":"sessionMint.d.ts","sourceRoot":"","sources":["../../src/auth/sessionMint.ts"],"names":[],"mappings":"AAgCA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,KAAK,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,sCAAsC,CAAC;AAE7F;;;;GAIG;AACH,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;IAC9B;;;;;;;;OAQG;IACH,QAAQ,CAAC,cAAc,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CAC3D;AAED;;;;GAIG;AACH,wBAAsB,WAAW,CAAC,CAAC,SAAS,YAAY,EACtD,MAAM,EAAE,mBAAmB,CAAC,CAAC,CAAC,EAC9B,GAAG,EAAE,kBAAkB,GACtB,OAAO,CAAC,WAAW,CAAC,CAkEtB"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"sessionMint.js","sourceRoot":"","sources":["../../src/auth/sessionMint.ts"],"names":[],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"credentialLifecycle.d.ts","sourceRoot":"","sources":["../../../src/transport/connection/credentialLifecycle.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAAc,KAAK,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAC1D,OAAO,EAGL,KAAK,kBAAkB,EACvB,KAAK,wBAAwB,EAC9B,MAAM,gCAAgC,CAAC;AAExC;;;GAGG;AACH,MAAM,MAAM,wBAAwB,GAAG,WAAW,GAAG,eAAe,GAAG,eAAe,CAAC;AAEvF;;;;;;GAMG;AACH,MAAM,MAAM,yBAAyB,GAAG,OAAO,GAAG,MAAM,CAAC;AAEzD;;;;;;GAMG;AACH,MAAM,MAAM,uBAAuB,GAAG,wBAAwB,CAAC;AAE/D;0DAC0D;AAC1D,MAAM,MAAM,mBAAmB,GAAG,kBAAkB,CAAC;AAErD;;kDAEkD;AAClD,eAAO,MAAM,2BAA2B,QAAiB,CAAC;AAE1D,8EAA8E;AAC9E,eAAO,MAAM,oBAAoB,QAAY,CAAC;AAE9C;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAQvF;AAUD;;;;;GAKG;AACH,MAAM,WAAW,0BAA0B;IACzC;kEAC8D;IAC9D,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,0EAA0E;IAC1E,cAAc,IAAI,IAAI,CAAC;IACvB;gCAC4B;IAC5B,oBAAoB,IAAI,IAAI,CAAC;CAC9B;AAED,qBAAa,mBAAmB;IAoC5B,OAAO,CAAC,QAAQ,CAAC,GAAG;IACpB,OAAO,CAAC,QAAQ,CAAC,MAAM;IApCzB;;;;;;;;;;OAUG;IACH,OAAO,CAAC,mBAAmB,CAAoC;IAE/D;6EACyE;IACzE,OAAO,CAAC,yBAAyB,CAAkD;IAEnF;;wDAEoD;IACpD,OAAO,CAAC,2BAA2B,CAA6B;IAEhE;;;0BAGsB;IACtB,OAAO,CAAC,qBAAqB,CAAuB;IAEpD;;;mEAG+D;IAC/D,OAAO,CAAC,iBAAiB,CAA6B;gBAGnC,GAAG,EAAE,0BAA0B,EAC/B,MAAM,GAAE,MAAmB;IAG9C;;;;OAIG;IACH,YAAY,CAAC,SAAS,EAAE,mBAAmB,GAAG,IAAI,GAAG,IAAI;IAIzD,kFAAkF;IAClF,MAAM,CAAC,MAAM,EAAE,uBAAuB,GAAG,OAAO;IAShD;;;;;;;;;;;;;;;OAeG;IACG,OAAO,IAAI,OAAO,CAAC,wBAAwB,CAAC;IAkDlD;;;;;OAKG;IACH,OAAO,CAAC,mBAAmB;IAmB3B;;;;;;;;;;;;;;;OAeG;IACG,wBAAwB,CAAC,QAAQ,EAAE,aAAa,GAAG,OAAO,CAAC,yBAAyB,CAAC;IAY3F;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,KAAK,CAAC,QAAQ,EAAE,mBAAmB,EAAE,IAAI,CAAC,EAAE;QAAE,eAAe,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI;IAqFhF,iEAAiE;IACjE,IAAI,IAAI,IAAI;CAIb"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"credentialLifecycle.js","sourceRoot":"","sources":["../../../src/transport/connection/credentialLifecycle.ts"],"names":[],"mappings":"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"}