@usearete/sdk 0.22.3 → 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.cjs +216 -56
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +67 -3
- package/dist/index.esm.js +216 -57
- package/dist/index.esm.js.map +1 -1
- package/package.json +1 -1
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
|
|
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 = {
|
|
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
|
-
|
|
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:
|
|
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
|
-
|
|
1473
|
-
|
|
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.
|
|
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
|
|
1490
|
-
const errorCode =
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
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
|