@usearete/sdk 0.22.4 → 0.23.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/dist/index.d.ts CHANGED
@@ -1041,9 +1041,26 @@ type ProgramReadDescriptors<TPrograms extends Record<string, ProgramSdkDefinitio
1041
1041
  type ProgramReadOverrides<TPrograms extends Record<string, ProgramSdkDefinition> | undefined> = TPrograms extends Record<string, ProgramSdkDefinition> ? {
1042
1042
  readonly [K in keyof TPrograms]?: ProgramReadOverride;
1043
1043
  } : Record<string, never>;
1044
+ /**
1045
+ * The exact served version a generated stack definition was built for: one
1046
+ * live alias of one StackManifest.
1047
+ */
1048
+ interface StackRelease {
1049
+ /** `arete:h1:stack-manifest:sha256:<64 hex>` */
1050
+ readonly stackManifestHash: string;
1051
+ /** The StackManifest live alias this definition serves. */
1052
+ readonly liveAlias: string;
1053
+ }
1044
1054
  interface StackDefinition<TPrograms extends Record<string, ProgramSdkDefinition> = Record<string, ProgramSdkDefinition>> {
1045
1055
  readonly name: string;
1046
1056
  readonly endpoints: StackEndpoints;
1057
+ /**
1058
+ * Served version this definition was generated for. Present only on
1059
+ * definitions generated from a hosted StackManifest; it is sent with the
1060
+ * WebSocket session request for `endpoints.ws` so the session endpoint can
1061
+ * route the client to that version.
1062
+ */
1063
+ readonly release?: StackRelease;
1047
1064
  readonly views: Record<string, ViewGroup>;
1048
1065
  readonly schemas?: Record<string, Schema<unknown>>;
1049
1066
  readonly patchSchemas?: Record<string, Schema<unknown>>;
@@ -1168,6 +1185,14 @@ type AuthTokenRequest = {
1168
1185
  readonly targetKind?: never;
1169
1186
  readonly targetId?: never;
1170
1187
  readonly programReleaseHash?: never;
1188
+ /**
1189
+ * Served version of the stack this session is for, when its stack
1190
+ * definition carries one. A custom `getToken` provider can forward it
1191
+ * to the session endpoint as `stackManifestHash`.
1192
+ */
1193
+ readonly stackManifestHash?: string;
1194
+ /** Live alias paired with `stackManifestHash`, forwarded as `liveAlias`. */
1195
+ readonly liveAlias?: string;
1171
1196
  } | ({
1172
1197
  readonly scopes: readonly string[];
1173
1198
  } & ProgramReadBindingAuthTarget) | ({
@@ -1210,6 +1235,11 @@ interface AreteConfig {
1210
1235
  auth?: AuthConfig;
1211
1236
  /** Fetch implementation used for authentication token requests. */
1212
1237
  fetch?: typeof fetch;
1238
+ /**
1239
+ * Served stack version to name in WebSocket session requests. Omitted
1240
+ * requests are exactly what older clients send.
1241
+ */
1242
+ release?: StackRelease;
1213
1243
  }
1214
1244
  interface SocketIssue {
1215
1245
  error: string;
@@ -1228,7 +1258,24 @@ declare const DEFAULT_CONFIG: Required<Pick<AreteConfig, 'autoReconnect' | 'reco
1228
1258
  *
1229
1259
  * These codes match the Rust AuthErrorCode enum for cross-platform consistency.
1230
1260
  */
1231
- type AuthErrorCode = 'TOKEN_MISSING' | 'TOKEN_EXPIRED' | 'TOKEN_INVALID_SIGNATURE' | 'TOKEN_INVALID_FORMAT' | 'TOKEN_INVALID_ISSUER' | 'TOKEN_INVALID_AUDIENCE' | 'TOKEN_MISSING_CLAIM' | 'TOKEN_KEY_NOT_FOUND' | 'ORIGIN_MISMATCH' | 'ORIGIN_REQUIRED' | 'ORIGIN_NOT_ALLOWED' | 'AUTH_REQUIRED' | 'MISSING_AUTHORIZATION_HEADER' | 'INVALID_AUTHORIZATION_FORMAT' | 'INVALID_API_KEY' | 'EXPIRED_API_KEY' | 'USER_NOT_FOUND' | 'SECRET_KEY_REQUIRED' | 'DEPLOYMENT_ACCESS_DENIED' | 'RATE_LIMIT_EXCEEDED' | 'WEBSOCKET_SESSION_RATE_LIMIT_EXCEEDED' | 'CONNECTION_LIMIT_EXCEEDED' | 'SUBSCRIPTION_LIMIT_EXCEEDED' | 'SNAPSHOT_LIMIT_EXCEEDED' | 'EGRESS_LIMIT_EXCEEDED' | 'QUOTA_EXCEEDED' | 'INVALID_STATIC_TOKEN' | 'INTERNAL_ERROR';
1261
+ type AuthErrorCode = 'TOKEN_MISSING' | 'TOKEN_EXPIRED' | 'TOKEN_INVALID_SIGNATURE' | 'TOKEN_INVALID_FORMAT' | 'TOKEN_INVALID_ISSUER' | 'TOKEN_INVALID_AUDIENCE' | 'TOKEN_MISSING_CLAIM' | 'TOKEN_KEY_NOT_FOUND' | 'ORIGIN_MISMATCH' | 'ORIGIN_REQUIRED' | 'ORIGIN_NOT_ALLOWED' | 'AUTH_REQUIRED' | 'MISSING_AUTHORIZATION_HEADER' | 'INVALID_AUTHORIZATION_FORMAT' | 'INVALID_API_KEY' | 'EXPIRED_API_KEY' | 'USER_NOT_FOUND' | 'SECRET_KEY_REQUIRED' | 'DEPLOYMENT_ACCESS_DENIED' | 'RATE_LIMIT_EXCEEDED' | 'WEBSOCKET_SESSION_RATE_LIMIT_EXCEEDED' | 'CONNECTION_LIMIT_EXCEEDED' | 'SUBSCRIPTION_LIMIT_EXCEEDED' | 'SNAPSHOT_LIMIT_EXCEEDED' | 'EGRESS_LIMIT_EXCEEDED' | 'QUOTA_EXCEEDED' | 'INVALID_STATIC_TOKEN' | 'STACK_VERSION_RETIRED' | 'STACK_VERSION_UNKNOWN' | 'INTERNAL_ERROR';
1262
+ /**
1263
+ * Structured fields of a `STACK_VERSION_RETIRED` / `STACK_VERSION_UNKNOWN`
1264
+ * session refusal, carried on {@link AreteError.details} alongside `status`,
1265
+ * `wireErrorCode` and `responseBody`.
1266
+ */
1267
+ interface StackVersionRefusal {
1268
+ readonly replacement?: {
1269
+ readonly version?: string;
1270
+ readonly stackManifestHash?: string;
1271
+ };
1272
+ /** Command that installs the replacement, e.g. `a4 install stack ore@1.3.0`. */
1273
+ readonly upgradeCommand?: string;
1274
+ /** RFC 3339 time the version was retired. */
1275
+ readonly retiredAt?: string;
1276
+ }
1277
+ /** True for the session refusals that no retry or reconnect can resolve. */
1278
+ declare function isStackVersionRefusalCode(code: string): boolean;
1232
1279
  /**
1233
1280
  * Refusals of a replay cursor. Each has a distinct recovery, so they reach the
1234
1281
  * consumer as the wire code rather than being folded into a generic failure.
@@ -1347,8 +1394,15 @@ interface ErrorFrame {
1347
1394
  code: string;
1348
1395
  retryable?: boolean;
1349
1396
  fatal: boolean;
1397
+ /** Seconds to wait before retrying, as the server sends it. */
1398
+ retryAfter?: number;
1399
+ suggestedAction?: string;
1400
+ docsUrl?: string;
1401
+ /** @deprecated The server sends `retryAfter`; kept for older servers. */
1350
1402
  retry_after?: number;
1403
+ /** @deprecated The server sends `suggestedAction`; kept for older servers. */
1351
1404
  suggested_action?: string;
1405
+ /** @deprecated The server sends `docsUrl`; kept for older servers. */
1352
1406
  docs_url?: string;
1353
1407
  /** Present on cursor refusals: what the view can still serve. */
1354
1408
  replayWindow?: ReplayWindow;
@@ -1419,7 +1473,10 @@ declare class ConnectionManager {
1419
1473
  private tokenScopes;
1420
1474
  private requestedScopes;
1421
1475
  private readonly hostedAreteUrl;
1476
+ private readonly release?;
1422
1477
  private reconnectForTokenRefresh;
1478
+ /** Most recent reason the socket was lost, reported while reconnecting. */
1479
+ private lastDisconnectReason?;
1423
1480
  constructor(config: AreteConfig);
1424
1481
  private getTokenEndpoint;
1425
1482
  private getAuthStrategy;
@@ -1474,7 +1531,14 @@ declare class ConnectionManager {
1474
1531
  private addQueuedSubscription;
1475
1532
  private updateState;
1476
1533
  private notifyFrameHandlers;
1534
+ /**
1535
+ * @param reason Why the connection was lost, when known. It is reported
1536
+ * with the `reconnecting` state and kept for the terminal error if the
1537
+ * attempts run out, so a server's close reason is never dropped.
1538
+ */
1477
1539
  private handleReconnect;
1540
+ /** Schedule the next attempt after a failed reconnect, unless nothing can succeed. */
1541
+ private recoverFromFailedConnect;
1478
1542
  private clearReconnectTimeout;
1479
1543
  private startPingInterval;
1480
1544
  private stopPingInterval;
@@ -2660,5 +2724,5 @@ declare const Arete: typeof Arete$1 & {
2660
2724
  session: typeof createSession;
2661
2725
  };
2662
2726
 
2663
- export { ASSOCIATED_TOKEN_PROGRAM_ADDRESS, Arete, AreteError, ConnectionManager, DEFAULT_CONFIG, DEFAULT_MAX_ENTRIES_PER_VIEW, FrameProcessor, InstructionError, MemoryAdapter, OPERATION_KIND, OperationCallbackError, OperationExecutionError, PROGRAM_OPERATION_EXTENSIONS, ProcessedSlotTimeoutError, QueryStore, ReadRequestError, SPL_TOKEN_PROGRAM_ADDRESS, STACK_RUNTIME_EXTENSIONS, SYSTEM_PROGRAM_ADDRESS, StreamGapError, SubscriptionRegistry, TOKEN_2022_PROGRAM_ADDRESS, TRANSACTION_RESOURCE_OPTION_KEYS, TransactionExecutionError, TransactionOptionsError, TransactionTransportError, account, appendFlowTransactions, appendTransactionInstructions, applyConnectedStackExtensions, arg, buildInstruction, bytes, canonicalQueryKey, chainAccountLoader, createChainClient, createEntityStream, createHostedSolanaGatewayTransports, createInstructionExecutor, createInstructionHandler, createPreparedFlow, createPreparedInstruction, createPreparedTransaction, createPreparedTransactionBody, createProgramPdas, createPublicKeySeed, createRichUpdateStream, createSeed, createSession, createSignerRegistry, createSubscriptionId, createTransactionTransport, createTypedListView, createTypedStateView, createTypedViews, createUpdateStream, decodeBase58, defineProgramExtensions, defineStackExtensions, deriveAssociatedTokenAccount, deriveHttpEndpoint, findProgramAddress as derivePda, describePreparedOperation, encodeBase58, executeInstruction, executePreparedOperation, extendProgram, extendPrograms, extendStack, findProgramAddress, findProgramAddressSync, flowOperation, formatPreparedOperation, formatProgramError, formatRawToUi, getMintDecimals, getOperationKind, getProgramRuntimeExtensions, getStackRuntimeExtensions, getTransactionFailureOutcome, hostedWebsocketSuffixes, inspectPreparedOperation, instructionOperation, isEntityFrame, isErrorFrame, isHostedAreteEndpoint, isReplayErrorCode, isSnapshotFrame, isSubscribedFrame, isUnsubscribedFrame, isValidFrame, literal, normalizeSubscription, normalizeSubscriptionQuery, normalizeSubscriptionRequest, normalizeTransactionError, parseFrame, parseFrameFromBlob, parseInstructionError, parseUiAmountToRaw, pda, prependFlowTransactionInstructions, prependTransactionInstructions, programAccountRead, programQuery, resolveAccounts, resolveAmount, resolveAmountToRaw, resolveAmountsToRaw, resolveTokenProgramAddress, resolveTransactionBuildOptions, safeToRawAmount, serializeInstructionData, serializeViewKey, setHostedWebsocketSuffixes, stackQuery, stringifyBigints, toJsonValue, toRawAmount, toWireResourceOptions, transactionOperation, unwrapOperationExecutionError, validateAccountResolution, validateProgramReadDescriptor, validateSubscriptionId, withProgramRead, withPrograms };
2664
- export type { AccountCategory, AccountLoader, AccountMeta, AccountResolutionOptions, AccountResolutionResult, AmountInput, AnyOperation, AreteConfig, AreteOptions, AreteOptionsWithStorage, ArgSchema, ArgType, AuthConfig, AuthTokenRequest, AuthTokenResult, AuthTokenTarget, BuildOptions, BuiltAccountMeta, BuiltInstruction, ChainClient, ChainClock, ChainFailedTransactionOutcome, CompositionSessionOptions, ConfirmationLevel, ConfirmedTransactionOutcome, ConnectOptions, ConnectedArete, ConnectedStackClient, ConnectionState, ConnectionStateCallback, ContextSlotOptions, CreatePreparedFlowInput, CreatePreparedInstructionInput, CreatePreparedTransactionInput, DefaultViewKey, EntityFrame, ErrorFrame, ErrorMetadata, ExecuteOptions, ExecutionResult, ExtendedProgramDefinition, ExtendedStackDefinition, FlowOperation, FlowOperationNamespace, FlowOperationReceipt, Frame, FrameMode, FrameOp, FrameProcessorConfig, FrameValidationDiagnostic, HostedSolanaGatewayBindings, HostedSolanaGatewayCapabilityBinding, HostedSolanaGatewayTransportOptions, HostedSolanaGatewayTransports, HttpAuthMetadata, InstructionExecutor, InstructionHandler, InstructionHandlerConfig, InstructionOperation, InstructionOperationNamespace, JsonObject, JsonPrimitive, JsonValue, LatestBlockhashResult, MergeProgramMaps, MintAccountInfo, NativeBalanceInfo, NonEmptyReadonlyArray, NotSubmittedTransactionOutcome, OperationCallbackPhase, OperationExecutionEvent, OperationExecutionHost, OperationExecutionOptions, OperationExecutionSuccessEvent, OperationInspection, OperationInspectionOptions, OperationKind, OperationKindBrand, OperationNamespace, OperationPlan, OperationReceiptFor, OperationTransactionReceipt, PdaConfig, PdaDeriveContext, PdaFactory, PdaProgram, PdaProgramSelector, PdaSeed, PreparedFlow, PreparedInstruction, PreparedOperation, PreparedOperationDescription, PreparedTransaction, PreparedTransactionBody, PreparedTransactionInstruction, PreparedTransactionOperation, ProgramAccountBatchItem, ProgramAccountBatchResult, ProgramAccountReadDefinition, ProgramError, ProgramExtensionInput, ProgramInterface, ProgramOperationContext, ProgramOperations, ProgramOperationsOf, ProgramPdas, ProgramQueryDefinition, ProgramReadBinding, ProgramReadBindingAuthTarget, ProgramReadDescriptor, ProgramReadDescriptors, ProgramReadOf, ProgramReadOverride, ProgramReadOverrides, ProgramReadRequest, ProgramReadTransport, ProgramReleaseReference, ProgramRuntimeExtensionCarrier, ProgramRuntimeExtensions, ProgramSdkDefinition, ProgramsInterface, QueriesInterface, QueryLease, QuerySnapshot, RawAccountInfo, RawInstructionsInterface, RawProgramsInterface, ReadArgumentCount, ReadArgumentCounts, ReadTransportMethod, ReplayErrorCode, ReplayWindow, ResolvedAccount, ResolvedAccounts, ResolvedTransactionBuildOptions, ResolvedTransactionResourceOptions, ResourceLamports, ResourceUnits, RichUpdate, RichUpdateCallback, Schema, SchemaResult, SeedDef, SendOptions, SendResult, Session, SessionDefinition, SessionMemberOptions, SessionOptions, SignerRegistry, SingleTransactionOperationReceipt, SnapshotEntity, SnapshotFrame, SocketIssue, SocketIssueCallback, SolanaGatewayAuthMetadata, SolanaGatewayAuthScope, SolanaGatewayBindingAuthTarget, SortConfig, SortOrder, StackConnectedExtensions, StackDefinition, StackEndpoints, StackExtensionClient, StackExtensionInput, StackQueryDefinition, StackRuntimeExtensionCarrier, StackRuntimeExtensions, StackWithAttachedPrograms, StorageAdapter, StorageAdapterConfig, StringifiedBigints, SubmittedUnknownTransactionOutcome, SubscribeCallback, SubscribedFrame, Subscription, SubscriptionIdentity, SubscriptionOptions, SubscriptionQuery, SubscriptionRequest, SubscriptionSnapshotOptions, TokenAccountInfo, TokenBalanceInfo, TokenBalanceInput, TransactionBuildCapability, TransactionBuildOptions, TransactionCommitment, TransactionFailureOutcome, TransactionFailurePhase, TransactionFailureStatus, TransactionFeeResult, TransactionInspectionOptions, TransactionInspectionResult, TransactionOperation, TransactionOperationNamespace, TransactionOptions, TransactionOptionsErrorCode, TransactionOutcome, TransactionRequestContext, TransactionResourceOptionKey, TransactionResourceOptions, TransactionSendOptions, TransactionSendResult, TransactionSignatureStatus, TransactionSimulationOptions, TransactionSimulationResult, TransactionTransport, TransactionTransportErrorBody, TransactionVersion, TypedAccountReader, TypedInstruction, TypedListView, TypedQueryExecutor, TypedStateView, TypedViewGroup, TypedViews, UnsubscribeFn, UnsubscribedFrame, Update, UpdateCallback, ViewDef, ViewGroup, ViewKeyFields, ViewKeyValue, ViewSortConfig, WaitForProcessedSlotOptions, WalletAdapter, WalletConnectOptions, WalletExecutionContext, WalletState, WatchOptions, WebSocketFactoryInit };
2727
+ export { ASSOCIATED_TOKEN_PROGRAM_ADDRESS, Arete, AreteError, ConnectionManager, DEFAULT_CONFIG, DEFAULT_MAX_ENTRIES_PER_VIEW, FrameProcessor, InstructionError, MemoryAdapter, OPERATION_KIND, OperationCallbackError, OperationExecutionError, PROGRAM_OPERATION_EXTENSIONS, ProcessedSlotTimeoutError, QueryStore, ReadRequestError, SPL_TOKEN_PROGRAM_ADDRESS, STACK_RUNTIME_EXTENSIONS, SYSTEM_PROGRAM_ADDRESS, StreamGapError, SubscriptionRegistry, TOKEN_2022_PROGRAM_ADDRESS, TRANSACTION_RESOURCE_OPTION_KEYS, TransactionExecutionError, TransactionOptionsError, TransactionTransportError, account, appendFlowTransactions, appendTransactionInstructions, applyConnectedStackExtensions, arg, buildInstruction, bytes, canonicalQueryKey, chainAccountLoader, createChainClient, createEntityStream, createHostedSolanaGatewayTransports, createInstructionExecutor, createInstructionHandler, createPreparedFlow, createPreparedInstruction, createPreparedTransaction, createPreparedTransactionBody, createProgramPdas, createPublicKeySeed, createRichUpdateStream, createSeed, createSession, createSignerRegistry, createSubscriptionId, createTransactionTransport, createTypedListView, createTypedStateView, createTypedViews, createUpdateStream, decodeBase58, defineProgramExtensions, defineStackExtensions, deriveAssociatedTokenAccount, deriveHttpEndpoint, findProgramAddress as derivePda, describePreparedOperation, encodeBase58, executeInstruction, executePreparedOperation, extendProgram, extendPrograms, extendStack, findProgramAddress, findProgramAddressSync, flowOperation, formatPreparedOperation, formatProgramError, formatRawToUi, getMintDecimals, getOperationKind, getProgramRuntimeExtensions, getStackRuntimeExtensions, getTransactionFailureOutcome, hostedWebsocketSuffixes, inspectPreparedOperation, instructionOperation, isEntityFrame, isErrorFrame, isHostedAreteEndpoint, isReplayErrorCode, isSnapshotFrame, isStackVersionRefusalCode, isSubscribedFrame, isUnsubscribedFrame, isValidFrame, literal, normalizeSubscription, normalizeSubscriptionQuery, normalizeSubscriptionRequest, normalizeTransactionError, parseFrame, parseFrameFromBlob, parseInstructionError, parseUiAmountToRaw, pda, prependFlowTransactionInstructions, prependTransactionInstructions, programAccountRead, programQuery, resolveAccounts, resolveAmount, resolveAmountToRaw, resolveAmountsToRaw, resolveTokenProgramAddress, resolveTransactionBuildOptions, safeToRawAmount, serializeInstructionData, serializeViewKey, setHostedWebsocketSuffixes, stackQuery, stringifyBigints, toJsonValue, toRawAmount, toWireResourceOptions, transactionOperation, unwrapOperationExecutionError, validateAccountResolution, validateProgramReadDescriptor, validateSubscriptionId, withProgramRead, withPrograms };
2728
+ export type { AccountCategory, AccountLoader, AccountMeta, AccountResolutionOptions, AccountResolutionResult, AmountInput, AnyOperation, AreteConfig, AreteOptions, AreteOptionsWithStorage, ArgSchema, ArgType, AuthConfig, AuthTokenRequest, AuthTokenResult, AuthTokenTarget, BuildOptions, BuiltAccountMeta, BuiltInstruction, ChainClient, ChainClock, ChainFailedTransactionOutcome, CompositionSessionOptions, ConfirmationLevel, ConfirmedTransactionOutcome, ConnectOptions, ConnectedArete, ConnectedStackClient, ConnectionState, ConnectionStateCallback, ContextSlotOptions, CreatePreparedFlowInput, CreatePreparedInstructionInput, CreatePreparedTransactionInput, DefaultViewKey, EntityFrame, ErrorFrame, ErrorMetadata, ExecuteOptions, ExecutionResult, ExtendedProgramDefinition, ExtendedStackDefinition, FlowOperation, FlowOperationNamespace, FlowOperationReceipt, Frame, FrameMode, FrameOp, FrameProcessorConfig, FrameValidationDiagnostic, HostedSolanaGatewayBindings, HostedSolanaGatewayCapabilityBinding, HostedSolanaGatewayTransportOptions, HostedSolanaGatewayTransports, HttpAuthMetadata, InstructionExecutor, InstructionHandler, InstructionHandlerConfig, InstructionOperation, InstructionOperationNamespace, JsonObject, JsonPrimitive, JsonValue, LatestBlockhashResult, MergeProgramMaps, MintAccountInfo, NativeBalanceInfo, NonEmptyReadonlyArray, NotSubmittedTransactionOutcome, OperationCallbackPhase, OperationExecutionEvent, OperationExecutionHost, OperationExecutionOptions, OperationExecutionSuccessEvent, OperationInspection, OperationInspectionOptions, OperationKind, OperationKindBrand, OperationNamespace, OperationPlan, OperationReceiptFor, OperationTransactionReceipt, PdaConfig, PdaDeriveContext, PdaFactory, PdaProgram, PdaProgramSelector, PdaSeed, PreparedFlow, PreparedInstruction, PreparedOperation, PreparedOperationDescription, PreparedTransaction, PreparedTransactionBody, PreparedTransactionInstruction, PreparedTransactionOperation, ProgramAccountBatchItem, ProgramAccountBatchResult, ProgramAccountReadDefinition, ProgramError, ProgramExtensionInput, ProgramInterface, ProgramOperationContext, ProgramOperations, ProgramOperationsOf, ProgramPdas, ProgramQueryDefinition, ProgramReadBinding, ProgramReadBindingAuthTarget, ProgramReadDescriptor, ProgramReadDescriptors, ProgramReadOf, ProgramReadOverride, ProgramReadOverrides, ProgramReadRequest, ProgramReadTransport, ProgramReleaseReference, ProgramRuntimeExtensionCarrier, ProgramRuntimeExtensions, ProgramSdkDefinition, ProgramsInterface, QueriesInterface, QueryLease, QuerySnapshot, RawAccountInfo, RawInstructionsInterface, RawProgramsInterface, ReadArgumentCount, ReadArgumentCounts, ReadTransportMethod, ReplayErrorCode, ReplayWindow, ResolvedAccount, ResolvedAccounts, ResolvedTransactionBuildOptions, ResolvedTransactionResourceOptions, ResourceLamports, ResourceUnits, RichUpdate, RichUpdateCallback, Schema, SchemaResult, SeedDef, SendOptions, SendResult, Session, SessionDefinition, SessionMemberOptions, SessionOptions, SignerRegistry, SingleTransactionOperationReceipt, SnapshotEntity, SnapshotFrame, SocketIssue, SocketIssueCallback, SolanaGatewayAuthMetadata, SolanaGatewayAuthScope, SolanaGatewayBindingAuthTarget, SortConfig, SortOrder, StackConnectedExtensions, StackDefinition, StackEndpoints, StackExtensionClient, StackExtensionInput, StackQueryDefinition, StackRelease, StackRuntimeExtensionCarrier, StackRuntimeExtensions, StackVersionRefusal, StackWithAttachedPrograms, StorageAdapter, StorageAdapterConfig, StringifiedBigints, SubmittedUnknownTransactionOutcome, SubscribeCallback, SubscribedFrame, Subscription, SubscriptionIdentity, SubscriptionOptions, SubscriptionQuery, SubscriptionRequest, SubscriptionSnapshotOptions, TokenAccountInfo, TokenBalanceInfo, TokenBalanceInput, TransactionBuildCapability, TransactionBuildOptions, TransactionCommitment, TransactionFailureOutcome, TransactionFailurePhase, TransactionFailureStatus, TransactionFeeResult, TransactionInspectionOptions, TransactionInspectionResult, TransactionOperation, TransactionOperationNamespace, TransactionOptions, TransactionOptionsErrorCode, TransactionOutcome, TransactionRequestContext, TransactionResourceOptionKey, TransactionResourceOptions, TransactionSendOptions, TransactionSendResult, TransactionSignatureStatus, TransactionSimulationOptions, TransactionSimulationResult, TransactionTransport, TransactionTransportErrorBody, TransactionVersion, TypedAccountReader, TypedInstruction, TypedListView, TypedQueryExecutor, TypedStateView, TypedViewGroup, TypedViews, UnsubscribeFn, UnsubscribedFrame, Update, UpdateCallback, ViewDef, ViewGroup, ViewKeyFields, ViewKeyValue, ViewSortConfig, WaitForProcessedSlotOptions, WalletAdapter, WalletConnectOptions, WalletExecutionContext, WalletState, WatchOptions, WebSocketFactoryInit };
package/dist/index.esm.js CHANGED
@@ -8,6 +8,10 @@ const DEFAULT_CONFIG = {
8
8
  maxReconnectAttempts: 5,
9
9
  maxEntriesPerView: DEFAULT_MAX_ENTRIES_PER_VIEW,
10
10
  };
11
+ /** True for the session refusals that no retry or reconnect can resolve. */
12
+ function isStackVersionRefusalCode(code) {
13
+ return code === 'STACK_VERSION_RETIRED' || code === 'STACK_VERSION_UNKNOWN';
14
+ }
11
15
  const REPLAY_ERROR_CODES = {
12
16
  'cursor-expired': true,
13
17
  'cursor-epoch-changed': true,
@@ -46,41 +50,66 @@ class AreteError extends Error {
46
50
  * collapsing them into a generic failure would destroy the only distinction.
47
51
  */
48
52
  function parseErrorCode(errorCode) {
49
- const codeMap = {
50
- 'token-missing': 'TOKEN_MISSING',
51
- 'token-expired': 'TOKEN_EXPIRED',
52
- 'token-invalid-signature': 'TOKEN_INVALID_SIGNATURE',
53
- 'token-invalid-format': 'TOKEN_INVALID_FORMAT',
54
- 'token-invalid-issuer': 'TOKEN_INVALID_ISSUER',
55
- 'token-invalid-audience': 'TOKEN_INVALID_AUDIENCE',
56
- 'token-missing-claim': 'TOKEN_MISSING_CLAIM',
57
- 'token-key-not-found': 'TOKEN_KEY_NOT_FOUND',
58
- 'origin-mismatch': 'ORIGIN_MISMATCH',
59
- 'origin-required': 'ORIGIN_REQUIRED',
60
- 'origin-not-allowed': 'ORIGIN_NOT_ALLOWED',
61
- 'rate-limit-exceeded': 'RATE_LIMIT_EXCEEDED',
62
- 'websocket-session-rate-limit-exceeded': 'WEBSOCKET_SESSION_RATE_LIMIT_EXCEEDED',
63
- 'connection-limit-exceeded': 'CONNECTION_LIMIT_EXCEEDED',
64
- 'subscription-limit-exceeded': 'SUBSCRIPTION_LIMIT_EXCEEDED',
65
- 'snapshot-limit-exceeded': 'SNAPSHOT_LIMIT_EXCEEDED',
66
- 'egress-limit-exceeded': 'EGRESS_LIMIT_EXCEEDED',
67
- 'invalid-static-token': 'INVALID_STATIC_TOKEN',
68
- 'internal-error': 'INTERNAL_ERROR',
69
- 'auth-required': 'AUTH_REQUIRED',
70
- 'missing-authorization-header': 'MISSING_AUTHORIZATION_HEADER',
71
- 'invalid-authorization-format': 'INVALID_AUTHORIZATION_FORMAT',
72
- 'invalid-api-key': 'INVALID_API_KEY',
73
- 'expired-api-key': 'EXPIRED_API_KEY',
74
- 'user-not-found': 'USER_NOT_FOUND',
75
- 'secret-key-required': 'SECRET_KEY_REQUIRED',
76
- 'deployment-access-denied': 'DEPLOYMENT_ACCESS_DENIED',
77
- 'quota-exceeded': 'QUOTA_EXCEEDED',
78
- };
79
53
  const normalized = errorCode.toLowerCase();
80
54
  if (isReplayErrorCode(normalized))
81
55
  return normalized;
82
- return codeMap[normalized] || 'INTERNAL_ERROR';
56
+ return authErrorCodeFromWire(normalized) ?? 'INTERNAL_ERROR';
83
57
  }
58
+ /**
59
+ * Resolve a wire error code the way {@link parseErrorCode} does, except that a
60
+ * code this SDK does not know is returned as sent instead of being collapsed
61
+ * into `INTERNAL_ERROR`. A newer server's refusal then still reaches the
62
+ * consumer under its own name.
63
+ */
64
+ /** Whether `code` is a wire error code this SDK knows. */
65
+ function isKnownWireErrorCode(code) {
66
+ const normalized = code.trim().toLowerCase();
67
+ return isReplayErrorCode(normalized) || authErrorCodeFromWire(normalized) !== undefined;
68
+ }
69
+ function parseWireErrorCode(errorCode) {
70
+ const trimmed = errorCode.trim();
71
+ const normalized = trimmed.toLowerCase();
72
+ if (isReplayErrorCode(normalized))
73
+ return normalized;
74
+ return authErrorCodeFromWire(normalized) ?? trimmed;
75
+ }
76
+ function authErrorCodeFromWire(normalized) {
77
+ return Object.prototype.hasOwnProperty.call(AUTH_ERROR_CODES_BY_WIRE, normalized)
78
+ ? AUTH_ERROR_CODES_BY_WIRE[normalized]
79
+ : undefined;
80
+ }
81
+ const AUTH_ERROR_CODES_BY_WIRE = {
82
+ 'token-missing': 'TOKEN_MISSING',
83
+ 'token-expired': 'TOKEN_EXPIRED',
84
+ 'token-invalid-signature': 'TOKEN_INVALID_SIGNATURE',
85
+ 'token-invalid-format': 'TOKEN_INVALID_FORMAT',
86
+ 'token-invalid-issuer': 'TOKEN_INVALID_ISSUER',
87
+ 'token-invalid-audience': 'TOKEN_INVALID_AUDIENCE',
88
+ 'token-missing-claim': 'TOKEN_MISSING_CLAIM',
89
+ 'token-key-not-found': 'TOKEN_KEY_NOT_FOUND',
90
+ 'origin-mismatch': 'ORIGIN_MISMATCH',
91
+ 'origin-required': 'ORIGIN_REQUIRED',
92
+ 'origin-not-allowed': 'ORIGIN_NOT_ALLOWED',
93
+ 'rate-limit-exceeded': 'RATE_LIMIT_EXCEEDED',
94
+ 'websocket-session-rate-limit-exceeded': 'WEBSOCKET_SESSION_RATE_LIMIT_EXCEEDED',
95
+ 'connection-limit-exceeded': 'CONNECTION_LIMIT_EXCEEDED',
96
+ 'subscription-limit-exceeded': 'SUBSCRIPTION_LIMIT_EXCEEDED',
97
+ 'snapshot-limit-exceeded': 'SNAPSHOT_LIMIT_EXCEEDED',
98
+ 'egress-limit-exceeded': 'EGRESS_LIMIT_EXCEEDED',
99
+ 'invalid-static-token': 'INVALID_STATIC_TOKEN',
100
+ 'internal-error': 'INTERNAL_ERROR',
101
+ 'auth-required': 'AUTH_REQUIRED',
102
+ 'missing-authorization-header': 'MISSING_AUTHORIZATION_HEADER',
103
+ 'invalid-authorization-format': 'INVALID_AUTHORIZATION_FORMAT',
104
+ 'invalid-api-key': 'INVALID_API_KEY',
105
+ 'expired-api-key': 'EXPIRED_API_KEY',
106
+ 'user-not-found': 'USER_NOT_FOUND',
107
+ 'secret-key-required': 'SECRET_KEY_REQUIRED',
108
+ 'deployment-access-denied': 'DEPLOYMENT_ACCESS_DENIED',
109
+ 'quota-exceeded': 'QUOTA_EXCEEDED',
110
+ 'stack-version-retired': 'STACK_VERSION_RETIRED',
111
+ 'stack-version-unknown': 'STACK_VERSION_UNKNOWN',
112
+ };
84
113
 
85
114
  const GZIP_MAGIC_0 = 0x1f;
86
115
  const GZIP_MAGIC_1 = 0x8b;
@@ -623,6 +652,73 @@ function hostedWebsocketSuffixes() {
623
652
  return [HOSTED_WEBSOCKET_SUFFIX, ...extraHostedSuffixes];
624
653
  }
625
654
  const MAX_HTTP_AUTH_TOKEN_STATES = 32;
655
+ function optionalString(value) {
656
+ return typeof value === 'string' && value.length > 0 ? value : undefined;
657
+ }
658
+ /** The structured fields of a stack version refusal, dropping malformed ones. */
659
+ function parseStackVersionRefusal(body) {
660
+ const replacementBody = typeof body?.replacement === 'object' && body.replacement !== null
661
+ ? body.replacement
662
+ : undefined;
663
+ const version = optionalString(replacementBody?.['version']);
664
+ const stackManifestHash = optionalString(replacementBody?.['stackManifestHash']);
665
+ const upgradeCommand = optionalString(body?.upgradeCommand);
666
+ const retiredAt = optionalString(body?.retiredAt);
667
+ return {
668
+ ...(version !== undefined || stackManifestHash !== undefined
669
+ ? {
670
+ replacement: {
671
+ ...(version !== undefined ? { version } : {}),
672
+ ...(stackManifestHash !== undefined ? { stackManifestHash } : {}),
673
+ },
674
+ }
675
+ : {}),
676
+ ...(upgradeCommand !== undefined ? { upgradeCommand } : {}),
677
+ ...(retiredAt !== undefined ? { retiredAt } : {}),
678
+ };
679
+ }
680
+ /** The server's message, followed by the replacement and how to install it. */
681
+ function describeStackVersionRefusal(message, refusal) {
682
+ const guidance = [];
683
+ const replacement = refusal.replacement?.version ?? refusal.replacement?.stackManifestHash;
684
+ if (replacement !== undefined)
685
+ guidance.push(`Replacement: ${replacement}.`);
686
+ if (refusal.upgradeCommand !== undefined)
687
+ guidance.push(`Upgrade with: ${refusal.upgradeCommand}`);
688
+ if (guidance.length === 0)
689
+ return message;
690
+ const trimmed = message.trimEnd();
691
+ return `${trimmed}${/[.!?]$/.test(trimmed) ? '' : '.'} ${guidance.join(' ')}`;
692
+ }
693
+ /**
694
+ * The wire code a close reason carries: the `code` of `code: message`, or the
695
+ * whole reason when it is exactly a known wire code. A free-form reason
696
+ * carries none.
697
+ */
698
+ function closeReasonWireCode(reason) {
699
+ if (!reason)
700
+ return undefined;
701
+ const prefixed = reason.match(/^([\w-]+):/)?.[1];
702
+ if (prefixed !== undefined)
703
+ return prefixed;
704
+ const bare = reason.trim();
705
+ return isKnownWireErrorCode(bare) ? bare : undefined;
706
+ }
707
+ /** A stack version refusal ends the connection: no retry or reconnect can fix it. */
708
+ function isTerminalRefusal(error) {
709
+ return error instanceof AreteError && isStackVersionRefusalCode(error.code);
710
+ }
711
+ function normalizeStackRelease(release) {
712
+ if (release === undefined)
713
+ return undefined;
714
+ if (typeof release.stackManifestHash !== 'string'
715
+ || release.stackManifestHash.length === 0
716
+ || typeof release.liveAlias !== 'string'
717
+ || release.liveAlias.length === 0) {
718
+ throw new AreteError('Stack release requires a non-empty stackManifestHash and liveAlias', 'INVALID_CONFIG');
719
+ }
720
+ return { stackManifestHash: release.stackManifestHash, liveAlias: release.liveAlias };
721
+ }
626
722
  function normalizeTokenResult(result) {
627
723
  if (typeof result === 'string') {
628
724
  return { token: result };
@@ -799,6 +895,7 @@ class ConnectionManager {
799
895
  this.maxReconnectAttempts =
800
896
  config.maxReconnectAttempts ?? DEFAULT_CONFIG.maxReconnectAttempts;
801
897
  this.authConfig = config.auth;
898
+ this.release = normalizeStackRelease(config.release);
802
899
  this.authFetch = config.fetch ?? ((input, init) => {
803
900
  if (typeof globalThis.fetch !== 'function') {
804
901
  throw new AreteError('A fetch implementation is required for authentication token requests', 'INVALID_CONFIG');
@@ -901,7 +998,15 @@ class ConnectionManager {
901
998
  }
902
999
  }
903
1000
  async fetchAuthToken(scopes, isCurrent) {
904
- const request = { scopes: normalizeScopes(scopes) };
1001
+ const request = {
1002
+ scopes: normalizeScopes(scopes),
1003
+ ...(this.release
1004
+ ? {
1005
+ stackManifestHash: this.release.stackManifestHash,
1006
+ liveAlias: this.release.liveAlias,
1007
+ }
1008
+ : {}),
1009
+ };
905
1010
  const result = await this.requestAuthToken(request, isCurrent);
906
1011
  return result === undefined ? undefined : this.updateTokenState(result, request.scopes);
907
1012
  }
@@ -1030,9 +1135,14 @@ class ConnectionManager {
1030
1135
  ? { ...target, programReleaseHash: request.programReleaseHash }
1031
1136
  : target;
1032
1137
  }
1138
+ // Session requests from a stack definition without a release stay
1139
+ // byte-for-byte what older clients send.
1033
1140
  return {
1034
1141
  websocket_url: this.websocketUrl ?? '',
1035
1142
  scopes: request.scopes,
1143
+ ...(request.stackManifestHash !== undefined && request.liveAlias !== undefined
1144
+ ? { stackManifestHash: request.stackManifestHash, liveAlias: request.liveAlias }
1145
+ : {}),
1036
1146
  };
1037
1147
  }
1038
1148
  async fetchTokenFromEndpoint(tokenEndpoint, request) {
@@ -1069,6 +1179,15 @@ class ConnectionManager {
1069
1179
  const errorMessage = typeof parsedError?.error === 'string' && parsedError.error.length > 0
1070
1180
  ? parsedError.error
1071
1181
  : rawError || response.statusText || 'Authentication request failed';
1182
+ if (isStackVersionRefusalCode(errorCode)) {
1183
+ const refusal = parseStackVersionRefusal(parsedError);
1184
+ throw new AreteError(describeStackVersionRefusal(`Token endpoint returned ${response.status}: ${errorMessage}`, refusal), errorCode, {
1185
+ status: response.status,
1186
+ wireErrorCode,
1187
+ responseBody: rawError || null,
1188
+ ...refusal,
1189
+ });
1190
+ }
1072
1191
  throw new AreteError(`Token endpoint returned ${response.status}: ${errorMessage}`, errorCode, {
1073
1192
  status: response.status,
1074
1193
  wireErrorCode,
@@ -1134,8 +1253,10 @@ class ConnectionManager {
1134
1253
  this.scheduleTokenRefresh();
1135
1254
  }
1136
1255
  }
1137
- catch {
1138
- if (this.tokenRefreshInFlight === refresh) {
1256
+ catch (error) {
1257
+ // A stack version refusal will not change on retry. Stop refreshing;
1258
+ // the next connect after this session ends reports it.
1259
+ if (this.tokenRefreshInFlight === refresh && !isTerminalRefusal(error)) {
1139
1260
  this.scheduleTokenRefresh();
1140
1261
  }
1141
1262
  }
@@ -1328,11 +1449,11 @@ class ConnectionManager {
1328
1449
  const issue = {
1329
1450
  error: message.error ?? message.code,
1330
1451
  message: message.message ?? message.error ?? message.code,
1331
- code: parseErrorCode(message.code),
1452
+ code: parseWireErrorCode(message.code),
1332
1453
  retryable: message.retryable ?? false,
1333
- retryAfter: message.retry_after,
1334
- suggestedAction: message.suggested_action,
1335
- docsUrl: message.docs_url,
1454
+ retryAfter: message.retryAfter ?? message.retry_after,
1455
+ suggestedAction: message.suggestedAction ?? message.suggested_action,
1456
+ docsUrl: message.docsUrl ?? message.docs_url,
1336
1457
  fatal: message.fatal,
1337
1458
  subscriptionId: message.subscriptionId,
1338
1459
  };
@@ -1368,7 +1489,7 @@ class ConnectionManager {
1368
1489
  this.pendingConnect = null;
1369
1490
  }
1370
1491
  if (generation === this.socketGeneration) {
1371
- this.updateState(recovering ? 'reconnecting' : 'error', error instanceof Error ? error.message : 'Failed to get token');
1492
+ this.updateState(recovering && !isTerminalRefusal(error) ? 'reconnecting' : 'error', error instanceof Error ? error.message : 'Failed to get token');
1372
1493
  }
1373
1494
  throw error;
1374
1495
  }
@@ -1396,6 +1517,7 @@ class ConnectionManager {
1396
1517
  if (!isCurrentSocket())
1397
1518
  return;
1398
1519
  this.reconnectAttempts = 0;
1520
+ this.lastDisconnectReason = undefined;
1399
1521
  this.updateState('connected');
1400
1522
  this.startPingInterval();
1401
1523
  this.scheduleTokenRefresh();
@@ -1469,8 +1591,19 @@ class ConnectionManager {
1469
1591
  ? `${event.code}: ${event.reason}`
1470
1592
  : `code ${event.code}`;
1471
1593
  const errorMessage = `WebSocket closed before open (${detail})`;
1472
- this.updateState(recovering ? 'reconnecting' : 'error', errorMessage);
1473
- finish(() => reject(new AreteError(errorMessage, 'CONNECTION_ERROR')));
1594
+ const reasonCode = closeReasonWireCode(event.reason);
1595
+ const wireErrorCode = reasonCode === undefined
1596
+ ? undefined
1597
+ : parseWireErrorCode(reasonCode);
1598
+ // A stack version refusal is terminal even mid-reconnect: carry it
1599
+ // as the error code, so recovery stops instead of retrying.
1600
+ const refused = wireErrorCode !== undefined && isStackVersionRefusalCode(wireErrorCode);
1601
+ this.updateState(recovering && !refused ? 'reconnecting' : 'error', errorMessage);
1602
+ finish(() => reject(new AreteError(errorMessage, refused ? wireErrorCode : 'CONNECTION_ERROR', {
1603
+ closeCode: event.code,
1604
+ closeReason: event.reason || undefined,
1605
+ wireErrorCode,
1606
+ })));
1474
1607
  return;
1475
1608
  }
1476
1609
  if (this.reconnectForTokenRefresh) {
@@ -1479,15 +1612,19 @@ class ConnectionManager {
1479
1612
  this.updateState('error', 'WebSocket closed for token refresh and automatic reconnection is disabled');
1480
1613
  return;
1481
1614
  }
1482
- void this.connect(true).catch(() => {
1483
- this.handleReconnect();
1615
+ void this.connect(true).catch((error) => {
1616
+ this.recoverFromFailedConnect(error);
1484
1617
  });
1485
1618
  return;
1486
1619
  }
1487
1620
  // Parse close reason for error codes (e.g., "token-expired: Token has expired")
1488
1621
  const closeReason = event.reason || '';
1489
- const errorCodeMatch = closeReason.match(/^([\w-]+):/);
1490
- const errorCode = errorCodeMatch ? parseErrorCode(errorCodeMatch[1]) : null;
1622
+ const reasonCode = closeReasonWireCode(closeReason);
1623
+ const errorCode = reasonCode === undefined ? null : parseWireErrorCode(reasonCode);
1624
+ if (errorCode !== null && isStackVersionRefusalCode(errorCode)) {
1625
+ this.updateState('error', `WebSocket closed (${event.code}: ${closeReason})`);
1626
+ return;
1627
+ }
1491
1628
  // Check for auth errors that require token refresh
1492
1629
  if (event.code === 1008 || errorCode) {
1493
1630
  const isAuthError = errorCode
@@ -1500,8 +1637,8 @@ class ConnectionManager {
1500
1637
  return;
1501
1638
  }
1502
1639
  // Try to reconnect immediately with a fresh token
1503
- void this.connect(true).catch(() => {
1504
- this.handleReconnect();
1640
+ void this.connect(true).catch((error) => {
1641
+ this.recoverFromFailedConnect(error);
1505
1642
  });
1506
1643
  return;
1507
1644
  }
@@ -1516,13 +1653,13 @@ class ConnectionManager {
1516
1653
  }
1517
1654
  }
1518
1655
  if (this.currentState !== 'disconnected') {
1656
+ const detail = event.reason
1657
+ ? `${event.code}: ${event.reason}`
1658
+ : `code ${event.code}`;
1519
1659
  if (this.autoReconnect) {
1520
- this.handleReconnect();
1660
+ this.handleReconnect(`WebSocket closed (${detail})`);
1521
1661
  }
1522
1662
  else {
1523
- const detail = event.reason
1524
- ? `${event.code}: ${event.reason}`
1525
- : `code ${event.code}`;
1526
1663
  this.updateState('error', `WebSocket closed (${detail}) and automatic reconnection is disabled`);
1527
1664
  }
1528
1665
  }
@@ -1541,6 +1678,7 @@ class ConnectionManager {
1541
1678
  this.stopPingInterval();
1542
1679
  this.clearTokenRefreshTimeout();
1543
1680
  this.reconnectForTokenRefresh = false;
1681
+ this.lastDisconnectReason = undefined;
1544
1682
  const pendingConnect = this.pendingConnect;
1545
1683
  this.pendingConnect = null;
1546
1684
  this.tokenRequestInFlight = null;
@@ -1670,29 +1808,47 @@ class ConnectionManager {
1670
1808
  handler(frame);
1671
1809
  }
1672
1810
  }
1673
- handleReconnect() {
1811
+ /**
1812
+ * @param reason Why the connection was lost, when known. It is reported
1813
+ * with the `reconnecting` state and kept for the terminal error if the
1814
+ * attempts run out, so a server's close reason is never dropped.
1815
+ */
1816
+ handleReconnect(reason) {
1817
+ if (reason !== undefined) {
1818
+ this.lastDisconnectReason = reason;
1819
+ }
1674
1820
  if (!this.autoReconnect) {
1675
1821
  this.updateState('error', 'Automatic reconnection is disabled');
1676
1822
  return;
1677
1823
  }
1678
1824
  if (this.reconnectAttempts >= this.maxReconnectAttempts) {
1679
- this.updateState('error', `Max reconnection attempts (${this.reconnectAttempts}) reached`);
1825
+ const lastReason = this.lastDisconnectReason;
1826
+ this.updateState('error', `Max reconnection attempts (${this.reconnectAttempts}) reached`
1827
+ + (lastReason ? `; last disconnect: ${lastReason}` : ''));
1680
1828
  return;
1681
1829
  }
1682
- this.updateState('reconnecting');
1830
+ this.updateState('reconnecting', this.lastDisconnectReason);
1683
1831
  const attemptIndex = Math.min(this.reconnectAttempts, this.reconnectIntervals.length - 1);
1684
1832
  const delay = this.reconnectIntervals[attemptIndex] ?? 1000;
1685
1833
  this.reconnectAttempts++;
1686
1834
  this.reconnectTimeout = setTimeout(() => {
1687
- this.connect(true).catch(() => {
1835
+ this.connect(true).catch((error) => {
1688
1836
  // Once a socket exists, its close event owns the next retry. Token
1689
1837
  // acquisition and socket construction can fail before that point.
1690
1838
  if (this.ws === null && this.currentState !== 'disconnected') {
1691
- this.handleReconnect();
1839
+ this.recoverFromFailedConnect(error);
1692
1840
  }
1693
1841
  });
1694
1842
  }, delay);
1695
1843
  }
1844
+ /** Schedule the next attempt after a failed reconnect, unless nothing can succeed. */
1845
+ recoverFromFailedConnect(error) {
1846
+ if (isTerminalRefusal(error)) {
1847
+ // connect() already reported the refusal as the terminal error state.
1848
+ return;
1849
+ }
1850
+ this.handleReconnect(error instanceof Error ? error.message : undefined);
1851
+ }
1696
1852
  clearReconnectTimeout() {
1697
1853
  if (this.reconnectTimeout) {
1698
1854
  clearTimeout(this.reconnectTimeout);
@@ -7030,6 +7186,9 @@ let Arete$1 = class Arete {
7030
7186
  maxReconnectAttempts: options.maxReconnectAttempts,
7031
7187
  auth: options.auth,
7032
7188
  fetch: this.fetchImpl,
7189
+ // The release names the version served at the generated endpoint. A
7190
+ // different `url` points somewhere the generator knew nothing about.
7191
+ release: url !== null && url === this.stack.endpoints.ws ? this.stack.release : undefined,
7033
7192
  });
7034
7193
  this.processor.useCursorTracker(this.connection.cursors);
7035
7194
  this.subscriptionRegistry = new SubscriptionRegistry(this.connection, this.queryStore);
@@ -7923,5 +8082,5 @@ function stringifyBigints(value) {
7923
8082
 
7924
8083
  const Arete = Object.assign(Arete$1, { session: createSession });
7925
8084
 
7926
- export { ASSOCIATED_TOKEN_PROGRAM_ADDRESS, Arete, AreteError, ConnectionManager, DEFAULT_CONFIG, DEFAULT_MAX_ENTRIES_PER_VIEW, FrameProcessor, InstructionError, MemoryAdapter, OPERATION_KIND, OperationCallbackError, OperationExecutionError, PROGRAM_OPERATION_EXTENSIONS, ProcessedSlotTimeoutError, QueryStore, ReadRequestError, SPL_TOKEN_PROGRAM_ADDRESS, STACK_RUNTIME_EXTENSIONS, SYSTEM_PROGRAM_ADDRESS, StreamGapError, SubscriptionRegistry, TOKEN_2022_PROGRAM_ADDRESS, TRANSACTION_RESOURCE_OPTION_KEYS, TransactionExecutionError, TransactionOptionsError, TransactionTransportError, account, appendFlowTransactions, appendTransactionInstructions, applyConnectedStackExtensions, arg, buildInstruction, bytes, canonicalQueryKey, chainAccountLoader, createChainClient, createEntityStream, createHostedSolanaGatewayTransports, createInstructionExecutor, createInstructionHandler, createPreparedFlow, createPreparedInstruction, createPreparedTransaction, createPreparedTransactionBody, createProgramPdas, createPublicKeySeed, createRichUpdateStream, createSeed, createSession, createSignerRegistry, createSubscriptionId, createTransactionTransport, createTypedListView, createTypedStateView, createTypedViews, createUpdateStream, decodeBase58, defineProgramExtensions, defineStackExtensions, deriveAssociatedTokenAccount, deriveHttpEndpoint, findProgramAddress as derivePda, describePreparedOperation, encodeBase58, executeInstruction, executePreparedOperation, extendProgram, extendPrograms, extendStack, findProgramAddress, findProgramAddressSync, flowOperation, formatPreparedOperation, formatProgramError, formatRawToUi, getMintDecimals, getOperationKind, getProgramRuntimeExtensions, getStackRuntimeExtensions, getTransactionFailureOutcome, hostedWebsocketSuffixes, inspectPreparedOperation, instructionOperation, isEntityFrame, isErrorFrame, isHostedAreteEndpoint, isReplayErrorCode, isSnapshotFrame, isSubscribedFrame, isUnsubscribedFrame, isValidFrame, literal, normalizeSubscription, normalizeSubscriptionQuery, normalizeSubscriptionRequest, normalizeTransactionError, parseFrame, parseFrameFromBlob, parseInstructionError, parseUiAmountToRaw, pda, prependFlowTransactionInstructions, prependTransactionInstructions, programAccountRead, programQuery, resolveAccounts, resolveAmount, resolveAmountToRaw, resolveAmountsToRaw, resolveTokenProgramAddress, resolveTransactionBuildOptions, safeToRawAmount, serializeInstructionData, serializeViewKey, setHostedWebsocketSuffixes, stackQuery, stringifyBigints, toJsonValue, toRawAmount, toWireResourceOptions, transactionOperation, unwrapOperationExecutionError, validateAccountResolution, validateProgramReadDescriptor, validateSubscriptionId, withProgramRead, withPrograms };
8085
+ export { ASSOCIATED_TOKEN_PROGRAM_ADDRESS, Arete, AreteError, ConnectionManager, DEFAULT_CONFIG, DEFAULT_MAX_ENTRIES_PER_VIEW, FrameProcessor, InstructionError, MemoryAdapter, OPERATION_KIND, OperationCallbackError, OperationExecutionError, PROGRAM_OPERATION_EXTENSIONS, ProcessedSlotTimeoutError, QueryStore, ReadRequestError, SPL_TOKEN_PROGRAM_ADDRESS, STACK_RUNTIME_EXTENSIONS, SYSTEM_PROGRAM_ADDRESS, StreamGapError, SubscriptionRegistry, TOKEN_2022_PROGRAM_ADDRESS, TRANSACTION_RESOURCE_OPTION_KEYS, TransactionExecutionError, TransactionOptionsError, TransactionTransportError, account, appendFlowTransactions, appendTransactionInstructions, applyConnectedStackExtensions, arg, buildInstruction, bytes, canonicalQueryKey, chainAccountLoader, createChainClient, createEntityStream, createHostedSolanaGatewayTransports, createInstructionExecutor, createInstructionHandler, createPreparedFlow, createPreparedInstruction, createPreparedTransaction, createPreparedTransactionBody, createProgramPdas, createPublicKeySeed, createRichUpdateStream, createSeed, createSession, createSignerRegistry, createSubscriptionId, createTransactionTransport, createTypedListView, createTypedStateView, createTypedViews, createUpdateStream, decodeBase58, defineProgramExtensions, defineStackExtensions, deriveAssociatedTokenAccount, deriveHttpEndpoint, findProgramAddress as derivePda, describePreparedOperation, encodeBase58, executeInstruction, executePreparedOperation, extendProgram, extendPrograms, extendStack, findProgramAddress, findProgramAddressSync, flowOperation, formatPreparedOperation, formatProgramError, formatRawToUi, getMintDecimals, getOperationKind, getProgramRuntimeExtensions, getStackRuntimeExtensions, getTransactionFailureOutcome, hostedWebsocketSuffixes, inspectPreparedOperation, instructionOperation, isEntityFrame, isErrorFrame, isHostedAreteEndpoint, isReplayErrorCode, isSnapshotFrame, isStackVersionRefusalCode, isSubscribedFrame, isUnsubscribedFrame, isValidFrame, literal, normalizeSubscription, normalizeSubscriptionQuery, normalizeSubscriptionRequest, normalizeTransactionError, parseFrame, parseFrameFromBlob, parseInstructionError, parseUiAmountToRaw, pda, prependFlowTransactionInstructions, prependTransactionInstructions, programAccountRead, programQuery, resolveAccounts, resolveAmount, resolveAmountToRaw, resolveAmountsToRaw, resolveTokenProgramAddress, resolveTransactionBuildOptions, safeToRawAmount, serializeInstructionData, serializeViewKey, setHostedWebsocketSuffixes, stackQuery, stringifyBigints, toJsonValue, toRawAmount, toWireResourceOptions, transactionOperation, unwrapOperationExecutionError, validateAccountResolution, validateProgramReadDescriptor, validateSubscriptionId, withProgramRead, withPrograms };
7927
8086
  //# sourceMappingURL=index.esm.js.map