@polyester/sdk 0.3.1 → 0.4.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/CHANGELOG.md +38 -0
- package/README.md +63 -17
- package/dist/_virtual/_rolldown/runtime.js +15 -1
- package/dist/account-signer/types.d.ts.map +1 -1
- package/dist/account-signer/types.js +6 -3
- package/dist/account-signer/types.js.map +1 -1
- package/dist/browser-client.d.ts +4 -2
- package/dist/browser-client.d.ts.map +1 -1
- package/dist/browser-client.js +3 -4
- package/dist/browser-client.js.map +1 -1
- package/dist/catalogs/client-catalog.d.ts.map +1 -1
- package/dist/catalogs/client-catalog.js +11 -4
- package/dist/catalogs/client-catalog.js.map +1 -1
- package/dist/catalogs/index.js +1 -1
- package/dist/catalogs/readers.d.ts.map +1 -1
- package/dist/catalogs/readers.js +3 -1
- package/dist/catalogs/readers.js.map +1 -1
- package/dist/catalogs/snapshot-validation.js +132 -0
- package/dist/catalogs/snapshot-validation.js.map +1 -0
- package/dist/catalogs/snapshot.d.ts.map +1 -1
- package/dist/catalogs/snapshot.js +16 -7
- package/dist/catalogs/snapshot.js.map +1 -1
- package/dist/catalogs/zipper-supply.d.ts.map +1 -1
- package/dist/catalogs/zipper-supply.js +10 -7
- package/dist/catalogs/zipper-supply.js.map +1 -1
- package/dist/core-client.d.ts +24 -17
- package/dist/core-client.d.ts.map +1 -1
- package/dist/core-client.js +21 -3
- package/dist/core-client.js.map +1 -1
- package/dist/environment.d.ts.map +1 -1
- package/dist/environment.js +32 -1
- package/dist/environment.js.map +1 -1
- package/dist/index.js +3 -3
- package/dist/realtime/client.js +13 -2
- package/dist/realtime/client.js.map +1 -1
- package/dist/realtime/snapshot-then-stream.js +1 -1
- package/dist/realtime/snapshot-then-stream.js.map +1 -1
- package/dist/realtime/types.d.ts +2 -0
- package/dist/realtime/types.d.ts.map +1 -1
- package/dist/server-client.d.ts +17 -8
- package/dist/server-client.d.ts.map +1 -1
- package/dist/server-client.js +8 -11
- package/dist/server-client.js.map +1 -1
- package/dist/services/accounts/accounts.js +3 -3
- package/dist/services/accounts/accounts.js.map +1 -1
- package/dist/services/accounts/accounts.schemas.d.ts +13 -13
- package/dist/services/accounts/accounts.schemas.d.ts.map +1 -1
- package/dist/services/accounts/accounts.schemas.js +11 -11
- package/dist/services/accounts/accounts.schemas.js.map +1 -1
- package/dist/services/address-book/address-book.js +28 -28
- package/dist/services/address-book/address-book.js.map +1 -1
- package/dist/services/address-book/address-book.schemas.d.ts +751 -751
- package/dist/services/address-book/address-book.schemas.d.ts.map +1 -1
- package/dist/services/address-book/address-book.schemas.js +160 -160
- package/dist/services/address-book/address-book.schemas.js.map +1 -1
- package/dist/services/api-keys/api-keys.d.ts +6 -6
- package/dist/services/api-keys/api-keys.d.ts.map +1 -1
- package/dist/services/api-keys/api-keys.js +12 -12
- package/dist/services/api-keys/api-keys.js.map +1 -1
- package/dist/services/api-keys/api-keys.schemas.d.ts +62 -62
- package/dist/services/api-keys/api-keys.schemas.d.ts.map +1 -1
- package/dist/services/api-keys/api-keys.schemas.js +34 -34
- package/dist/services/api-keys/api-keys.schemas.js.map +1 -1
- package/dist/services/auth/auth.d.ts +46 -40
- package/dist/services/auth/auth.d.ts.map +1 -1
- package/dist/services/auth/auth.js +28 -25
- package/dist/services/auth/auth.js.map +1 -1
- package/dist/services/auth/profile/profile.d.ts +2 -2
- package/dist/services/auth/profile/profile.d.ts.map +1 -1
- package/dist/services/auth/profile/profile.js +7 -7
- package/dist/services/auth/profile/profile.js.map +1 -1
- package/dist/services/auth/profile/profile.schemas.d.ts +41 -41
- package/dist/services/auth/profile/profile.schemas.d.ts.map +1 -1
- package/dist/services/auth/profile/profile.schemas.js +27 -27
- package/dist/services/auth/profile/profile.schemas.js.map +1 -1
- package/dist/services/auth/session.d.ts +1 -1
- package/dist/services/auth/session.d.ts.map +1 -1
- package/dist/services/auth/session.js +6 -2
- package/dist/services/auth/session.js.map +1 -1
- package/dist/services/auth/session.schemas.js +17 -17
- package/dist/services/auth/session.schemas.js.map +1 -1
- package/dist/services/auth/session.types.d.ts +3 -2
- package/dist/services/auth/session.types.d.ts.map +1 -1
- package/dist/services/balances/balances.d.ts +1 -1
- package/dist/services/balances/balances.js +9 -9
- package/dist/services/balances/balances.js.map +1 -1
- package/dist/services/balances/balances.schemas.d.ts +95 -95
- package/dist/services/balances/balances.schemas.d.ts.map +1 -1
- package/dist/services/balances/balances.schemas.js +61 -61
- package/dist/services/balances/balances.schemas.js.map +1 -1
- package/dist/services/candles/candles.js +12 -12
- package/dist/services/candles/candles.js.map +1 -1
- package/dist/services/candles/candles.schemas.d.ts +70 -70
- package/dist/services/candles/candles.schemas.d.ts.map +1 -1
- package/dist/services/candles/candles.schemas.js +47 -48
- package/dist/services/candles/candles.schemas.js.map +1 -1
- package/dist/services/chain-analytics/chain-analytics.js +7 -7
- package/dist/services/chain-analytics/chain-analytics.js.map +1 -1
- package/dist/services/chain-analytics/chain-analytics.schemas.d.ts +68 -68
- package/dist/services/chain-analytics/chain-analytics.schemas.d.ts.map +1 -1
- package/dist/services/chain-analytics/chain-analytics.schemas.js +29 -29
- package/dist/services/chain-analytics/chain-analytics.schemas.js.map +1 -1
- package/dist/services/deposit/deposit.js +5 -5
- package/dist/services/deposit/deposit.js.map +1 -1
- package/dist/services/deposit/deposit.schemas.d.ts +17 -17
- package/dist/services/deposit/deposit.schemas.d.ts.map +1 -1
- package/dist/services/deposit/deposit.schemas.js +11 -11
- package/dist/services/deposit/deposit.schemas.js.map +1 -1
- package/dist/services/guard-signer/guard-signer.js +13 -13
- package/dist/services/guard-signer/guard-signer.js.map +1 -1
- package/dist/services/guard-signer/guard-signer.schemas.d.ts +75 -75
- package/dist/services/guard-signer/guard-signer.schemas.d.ts.map +1 -1
- package/dist/services/guard-signer/guard-signer.schemas.js +42 -42
- package/dist/services/guard-signer/guard-signer.schemas.js.map +1 -1
- package/dist/services/heatmap/heatmap.js +9 -9
- package/dist/services/heatmap/heatmap.js.map +1 -1
- package/dist/services/heatmap/heatmap.schemas.d.ts +144 -144
- package/dist/services/heatmap/heatmap.schemas.d.ts.map +1 -1
- package/dist/services/heatmap/heatmap.schemas.js +47 -47
- package/dist/services/heatmap/heatmap.schemas.js.map +1 -1
- package/dist/services/internal-transfers/internal-transfers.js +3 -3
- package/dist/services/internal-transfers/internal-transfers.js.map +1 -1
- package/dist/services/internal-transfers/internal-transfers.schemas.d.ts +53 -53
- package/dist/services/internal-transfers/internal-transfers.schemas.d.ts.map +1 -1
- package/dist/services/internal-transfers/internal-transfers.schemas.js +27 -27
- package/dist/services/internal-transfers/internal-transfers.schemas.js.map +1 -1
- package/dist/services/lifecycle/lifecycle.js +10 -10
- package/dist/services/lifecycle/lifecycle.js.map +1 -1
- package/dist/services/lifecycle/lifecycle.schemas.d.ts +614 -614
- package/dist/services/lifecycle/lifecycle.schemas.d.ts.map +1 -1
- package/dist/services/lifecycle/lifecycle.schemas.js +146 -146
- package/dist/services/lifecycle/lifecycle.schemas.js.map +1 -1
- package/dist/services/market-data/market-data.js +6 -6
- package/dist/services/market-data/market-data.js.map +1 -1
- package/dist/services/market-data/market-data.schemas.d.ts +20 -20
- package/dist/services/market-data/market-data.schemas.d.ts.map +1 -1
- package/dist/services/market-data/market-data.schemas.js +51 -55
- package/dist/services/market-data/market-data.schemas.js.map +1 -1
- package/dist/services/market-overview/market-overview.js +4 -4
- package/dist/services/market-overview/market-overview.js.map +1 -1
- package/dist/services/market-overview/market-overview.schemas.d.ts +38 -38
- package/dist/services/market-overview/market-overview.schemas.d.ts.map +1 -1
- package/dist/services/market-overview/market-overview.schemas.js +33 -33
- package/dist/services/market-overview/market-overview.schemas.js.map +1 -1
- package/dist/services/mfa/mfa.js +27 -27
- package/dist/services/mfa/mfa.js.map +1 -1
- package/dist/services/mfa/mfa.schemas.d.ts +206 -206
- package/dist/services/mfa/mfa.schemas.d.ts.map +1 -1
- package/dist/services/mfa/mfa.schemas.js +83 -83
- package/dist/services/mfa/mfa.schemas.js.map +1 -1
- package/dist/services/orderbook/orderbook.d.ts +2 -2
- package/dist/services/orderbook/orderbook.d.ts.map +1 -1
- package/dist/services/orderbook/orderbook.js +5 -5
- package/dist/services/orderbook/orderbook.js.map +1 -1
- package/dist/services/orderbook/orderbook.schemas.d.ts +22 -22
- package/dist/services/orderbook/orderbook.schemas.d.ts.map +1 -1
- package/dist/services/orderbook/orderbook.schemas.js +15 -15
- package/dist/services/orderbook/orderbook.schemas.js.map +1 -1
- package/dist/services/orders/order-errors.schemas.d.ts +18 -18
- package/dist/services/orders/order-errors.schemas.d.ts.map +1 -1
- package/dist/services/orders/order-errors.schemas.js +8 -8
- package/dist/services/orders/order-errors.schemas.js.map +1 -1
- package/dist/services/orders/orders-batch.schemas.d.ts +492 -492
- package/dist/services/orders/orders-batch.schemas.d.ts.map +1 -1
- package/dist/services/orders/orders-batch.schemas.js +118 -118
- package/dist/services/orders/orders-batch.schemas.js.map +1 -1
- package/dist/services/orders/orders-identifiers.schemas.js +5 -5
- package/dist/services/orders/orders-identifiers.schemas.js.map +1 -1
- package/dist/services/orders/orders-input.schemas.d.ts +657 -648
- package/dist/services/orders/orders-input.schemas.d.ts.map +1 -1
- package/dist/services/orders/orders-input.schemas.js +100 -96
- package/dist/services/orders/orders-input.schemas.js.map +1 -1
- package/dist/services/orders/orders-modify.schemas.d.ts +370 -351
- package/dist/services/orders/orders-modify.schemas.d.ts.map +1 -1
- package/dist/services/orders/orders-modify.schemas.js +48 -44
- package/dist/services/orders/orders-modify.schemas.js.map +1 -1
- package/dist/services/orders/orders-output.schemas.d.ts +183 -183
- package/dist/services/orders/orders-output.schemas.d.ts.map +1 -1
- package/dist/services/orders/orders-output.schemas.js +49 -49
- package/dist/services/orders/orders-output.schemas.js.map +1 -1
- package/dist/services/orders/orders-risk.schemas.d.ts +226 -226
- package/dist/services/orders/orders-risk.schemas.d.ts.map +1 -1
- package/dist/services/orders/orders-risk.schemas.js +69 -69
- package/dist/services/orders/orders-risk.schemas.js.map +1 -1
- package/dist/services/orders/orders.d.ts +8 -8
- package/dist/services/orders/orders.d.ts.map +1 -1
- package/dist/services/orders/orders.js +44 -32
- package/dist/services/orders/orders.js.map +1 -1
- package/dist/services/policies/api-key-policies/api-key-policies.d.ts +6 -6
- package/dist/services/policies/api-key-policies/api-key-policies.d.ts.map +1 -1
- package/dist/services/policies/api-key-policies/api-key-policies.js +11 -11
- package/dist/services/policies/api-key-policies/api-key-policies.js.map +1 -1
- package/dist/services/policies/api-key-policies/api-key-policies.schemas.d.ts +105 -105
- package/dist/services/policies/api-key-policies/api-key-policies.schemas.d.ts.map +1 -1
- package/dist/services/policies/api-key-policies/api-key-policies.schemas.js +49 -49
- package/dist/services/policies/api-key-policies/api-key-policies.schemas.js.map +1 -1
- package/dist/services/policies/shared.d.ts +5 -5
- package/dist/services/policies/shared.d.ts.map +1 -1
- package/dist/services/policies/shared.js +10 -10
- package/dist/services/policies/shared.js.map +1 -1
- package/dist/services/policies/subaccount-policies/subaccount-policies.d.ts +6 -6
- package/dist/services/policies/subaccount-policies/subaccount-policies.d.ts.map +1 -1
- package/dist/services/policies/subaccount-policies/subaccount-policies.js +13 -13
- package/dist/services/policies/subaccount-policies/subaccount-policies.js.map +1 -1
- package/dist/services/policies/subaccount-policies/subaccount-policies.schemas.d.ts +124 -124
- package/dist/services/policies/subaccount-policies/subaccount-policies.schemas.d.ts.map +1 -1
- package/dist/services/policies/subaccount-policies/subaccount-policies.schemas.js +75 -75
- package/dist/services/policies/subaccount-policies/subaccount-policies.schemas.js.map +1 -1
- package/dist/services/shared.js +11 -11
- package/dist/services/shared.js.map +1 -1
- package/dist/services/social-verification/social-verification.d.ts +3 -3
- package/dist/services/social-verification/social-verification.d.ts.map +1 -1
- package/dist/services/social-verification/social-verification.js +7 -7
- package/dist/services/social-verification/social-verification.js.map +1 -1
- package/dist/services/social-verification/social-verification.schemas.d.ts +54 -54
- package/dist/services/social-verification/social-verification.schemas.d.ts.map +1 -1
- package/dist/services/social-verification/social-verification.schemas.js +28 -28
- package/dist/services/social-verification/social-verification.schemas.js.map +1 -1
- package/dist/services/subaccount-resolver.js +5 -3
- package/dist/services/subaccount-resolver.js.map +1 -1
- package/dist/services/subaccounts/subaccounts.d.ts +15 -15
- package/dist/services/subaccounts/subaccounts.d.ts.map +1 -1
- package/dist/services/subaccounts/subaccounts.js +35 -35
- package/dist/services/subaccounts/subaccounts.js.map +1 -1
- package/dist/services/subaccounts/subaccounts.schemas.d.ts +135 -135
- package/dist/services/subaccounts/subaccounts.schemas.d.ts.map +1 -1
- package/dist/services/subaccounts/subaccounts.schemas.js +72 -72
- package/dist/services/subaccounts/subaccounts.schemas.js.map +1 -1
- package/dist/services/trades/trades.d.ts +2 -2
- package/dist/services/trades/trades.d.ts.map +1 -1
- package/dist/services/trades/trades.js +5 -5
- package/dist/services/trades/trades.js.map +1 -1
- package/dist/services/trades/trades.schemas.d.ts +31 -31
- package/dist/services/trades/trades.schemas.d.ts.map +1 -1
- package/dist/services/trades/trades.schemas.js +24 -24
- package/dist/services/trades/trades.schemas.js.map +1 -1
- package/dist/services/trading-withdraws/trading-withdraws.js +8 -8
- package/dist/services/trading-withdraws/trading-withdraws.js.map +1 -1
- package/dist/services/trading-withdraws/trading-withdraws.schemas.d.ts +45 -45
- package/dist/services/trading-withdraws/trading-withdraws.schemas.d.ts.map +1 -1
- package/dist/services/trading-withdraws/trading-withdraws.schemas.js +36 -36
- package/dist/services/trading-withdraws/trading-withdraws.schemas.js.map +1 -1
- package/dist/services/transfers/transfers.d.ts +1 -1
- package/dist/services/transfers/transfers.d.ts.map +1 -1
- package/dist/services/transfers/transfers.js +5 -5
- package/dist/services/transfers/transfers.js.map +1 -1
- package/dist/services/transfers/transfers.schemas.d.ts +42 -42
- package/dist/services/transfers/transfers.schemas.d.ts.map +1 -1
- package/dist/services/transfers/transfers.schemas.js +30 -30
- package/dist/services/transfers/transfers.schemas.js.map +1 -1
- package/dist/services/triggers/trigger-child-order.schemas.js +23 -23
- package/dist/services/triggers/trigger-child-order.schemas.js.map +1 -1
- package/dist/services/triggers/trigger-input.schemas.d.ts +226 -226
- package/dist/services/triggers/trigger-input.schemas.d.ts.map +1 -1
- package/dist/services/triggers/trigger-input.schemas.js +53 -53
- package/dist/services/triggers/trigger-input.schemas.js.map +1 -1
- package/dist/services/triggers/triggers-output.schemas.d.ts +210 -210
- package/dist/services/triggers/triggers-output.schemas.d.ts.map +1 -1
- package/dist/services/triggers/triggers-output.schemas.js +152 -152
- package/dist/services/triggers/triggers-output.schemas.js.map +1 -1
- package/dist/services/triggers/triggers.js +21 -21
- package/dist/services/triggers/triggers.js.map +1 -1
- package/dist/services/whiteboard/whiteboard.js +15 -15
- package/dist/services/whiteboard/whiteboard.js.map +1 -1
- package/dist/services/whiteboard/whiteboard.schemas.d.ts +379 -379
- package/dist/services/whiteboard/whiteboard.schemas.d.ts.map +1 -1
- package/dist/services/whiteboard/whiteboard.schemas.js +71 -71
- package/dist/services/whiteboard/whiteboard.schemas.js.map +1 -1
- package/dist/services/zipper/zipper.js +3 -3
- package/dist/services/zipper/zipper.js.map +1 -1
- package/dist/services/zipper/zipper.schemas.d.ts +1 -1
- package/dist/services/zipper/zipper.schemas.js +54 -54
- package/dist/services/zipper/zipper.schemas.js.map +1 -1
- package/dist/shared/account-scope.d.ts +6 -6
- package/dist/shared/account-scope.d.ts.map +1 -1
- package/dist/shared/account-scope.js +3 -3
- package/dist/shared/account-scope.js.map +1 -1
- package/dist/shared/connect-error-mapping.d.ts +1 -1
- package/dist/shared/connect-error-mapping.js +29 -3
- package/dist/shared/connect-error-mapping.js.map +1 -1
- package/dist/shared/rate-limit.schemas.d.ts +12 -12
- package/dist/shared/rate-limit.schemas.d.ts.map +1 -1
- package/dist/shared/rate-limit.schemas.js +7 -7
- package/dist/shared/rate-limit.schemas.js.map +1 -1
- package/dist/shared/schemas.js +26 -26
- package/dist/shared/schemas.js.map +1 -1
- package/dist/shared/transports.js +7 -12
- package/dist/shared/transports.js.map +1 -1
- package/dist/shared/types.d.ts +12 -0
- package/dist/shared/types.d.ts.map +1 -1
- package/dist/shared/validation.d.ts +14 -0
- package/dist/shared/validation.d.ts.map +1 -0
- package/dist/shared/validation.js +24 -0
- package/dist/shared/validation.js.map +1 -0
- package/dist/utils/connect-order-errors.js +2 -2
- package/dist/utils/connect-order-errors.js.map +1 -1
- package/dist/utils/cookies.d.ts +8 -3
- package/dist/utils/cookies.d.ts.map +1 -1
- package/dist/utils/cookies.js +7 -1
- package/dist/utils/cookies.js.map +1 -1
- package/dist/utils/event-emitter.d.ts +1 -1
- package/dist/utils/event-emitter.d.ts.map +1 -1
- package/dist/utils/event-emitter.js +4 -2
- package/dist/utils/event-emitter.js.map +1 -1
- package/dist/utils/evm.js +2 -2
- package/dist/utils/evm.js.map +1 -1
- package/dist/utils/jwt.d.ts +2 -2
- package/dist/utils/jwt.d.ts.map +1 -1
- package/dist/utils/jwt.js +2 -2
- package/dist/utils/jwt.js.map +1 -1
- package/package.json +1 -1
package/dist/core-client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"core-client.js","names":["#environment","#authProvider","#realtimeConfig","#configRealtimeClient","#configCatalog","#configCatalogSnapshot","#configCatalogCell","#createAuth","#realtime","#catalog","#getScales","#scales","#resolverInitialized","#resolver","#auth","#accounts","#apiKeys","#getResolver","#subaccounts","#candles","#chainAnalytics","#marketData","#marketOverview","#orderbook","#heatmap","#lifecycle","#trades","#orders","#triggers","#balances","#transfers","#internalTransfers","#tradingWithdraws","#deposit","#addressBook","#guardSigner","#socialVerification","#whiteboard","#zipper","#mfa"],"sources":["../src/core-client.ts"],"sourcesContent":["import type { Interceptor } from \"@connectrpc/connect\";\nimport { ConfigurationError } from \"./shared/errors.js\";\nimport {\n createApiKeyEd25519AuthHeaders,\n createTransports,\n type Transports,\n type JwtAuthProvider,\n type ApiKeyEd25519AuthProvider,\n} from \"./shared/transports.js\";\nimport type { PolyesterEnvironment } from \"./environment.js\";\nimport { AccountsService } from \"./services/accounts/index.js\";\nimport { ApiKeysService } from \"./services/api-keys/index.js\";\nimport { AuthService, type AuthServiceTransports } from \"./services/auth/auth.js\";\nimport { SubaccountsService } from \"./services/subaccounts/index.js\";\nimport { CandlesService } from \"./services/candles/index.js\";\nimport { ChainAnalyticsService } from \"./services/chain-analytics/index.js\";\nimport { MarketDataService } from \"./services/market-data/index.js\";\nimport { MarketOverviewService } from \"./services/market-overview/index.js\";\nimport { OrderbookService } from \"./services/orderbook/index.js\";\nimport { HeatmapService } from \"./services/heatmap/index.js\";\nimport { LifecycleService } from \"./services/lifecycle/index.js\";\nimport { TradesService } from \"./services/trades/index.js\";\nimport { OrdersService } from \"./services/orders/index.js\";\nimport { TriggersService } from \"./services/triggers/index.js\";\nimport { BalancesService } from \"./services/balances/index.js\";\nimport { TransfersService } from \"./services/transfers/index.js\";\nimport { InternalTransfersService } from \"./services/internal-transfers/index.js\";\nimport { TradingWithdrawsService } from \"./services/trading-withdraws/index.js\";\nimport { DepositService } from \"./services/deposit/index.js\";\nimport { AddressBookService } from \"./services/address-book/index.js\";\nimport { GuardSignerService } from \"./services/guard-signer/index.js\";\nimport { SocialVerificationService } from \"./services/social-verification/index.js\";\nimport { WhiteboardService } from \"./services/whiteboard/index.js\";\nimport { ZipperService } from \"./services/zipper/index.js\";\nimport { MfaService } from \"./services/mfa/index.js\";\nimport type { SubaccountResolver } from \"./services/subaccount-resolver.js\";\nimport {\n createPolyesterCatalog,\n type CatalogSnapshot,\n type CatalogSnapshotCell,\n type ClientCatalog,\n} from \"./catalogs/index.js\";\nimport { createCatalogSdkScales, type SdkScales } from \"./shared/decimal-surface.js\";\nimport { RealtimeClient, type PolyesterRealtime, type RealtimeConfig } from \"./realtime/index.js\";\n\nfunction realtimeAuthFromProvider(\n auth: JwtAuthProvider | ApiKeyEd25519AuthProvider | undefined,\n): Pick<RealtimeConfig, \"getAuthHeaders\" | \"hasAuth\"> {\n if (!auth) return {};\n if (auth.kind === \"jwt\") {\n return {\n getAuthHeaders: async () => {\n const token = await auth.getToken();\n const headers: Record<string, string> = {};\n if (token) headers.authorization = `Bearer ${token}`;\n return headers;\n },\n hasAuth: () => {\n // Only token getters that resolve synchronously can be checked here;\n // async getters are assumed authenticated and fail at token fetch.\n const token = auth.getToken();\n if (token instanceof Promise) return true;\n return typeof token === \"string\" && token.length > 0;\n },\n };\n }\n return {\n getAuthHeaders: (request) =>\n createApiKeyEd25519AuthHeaders(auth, {\n url: request.url,\n method: request.method,\n }),\n hasAuth: () => true,\n };\n}\n\nexport type PolyesterRealtimeAuthConfig = Pick<RealtimeConfig, \"getAuthHeaders\" | \"hasAuth\">;\n\nexport interface PolyesterClientBaseConfig {\n environment: PolyesterEnvironment;\n interceptors?: Interceptor[];\n auth?: JwtAuthProvider | ApiKeyEd25519AuthProvider;\n realtime?: PolyesterRealtimeAuthConfig;\n /**\n * Connect wire format. Defaults to binary for production performance.\n * Use `json` for human-readable debugging.\n */\n wireFormat?: \"binary\" | \"json\";\n /**\n * Client-owned catalog store. Advanced callers can inject a fully managed catalog instance.\n */\n catalog?: ClientCatalog;\n /**\n * Explicit initial catalog snapshot, commonly hydrated from server-rendered data.\n * Combines with `catalogCell` as the cell's initial value (never clobbers a\n * pre-populated cell).\n */\n catalogSnapshot?: CatalogSnapshot;\n /**\n * External snapshot storage for the client-built catalog (mutually exclusive with\n * `catalog`). A cell backed by a reactive source makes every catalog read reactive.\n */\n catalogCell?: CatalogSnapshotCell;\n /**\n * Advanced: inject pre-built Connect transports (in-memory mocks, custom\n * stacks). When provided, the SDK does not build its own transports and the\n * built-in auth/error-mapping interceptors are NOT applied — the injected\n * transports own their full interceptor chain.\n */\n transports?: Transports;\n /**\n * Advanced: inject a realtime implementation (in-memory mocks, custom\n * stacks). When provided, the SDK skips constructing its Centrifuge-backed\n * realtime client and the `realtime` auth config is ignored.\n */\n realtimeClient?: PolyesterRealtime;\n}\n\nexport interface PolyesterClientConfig extends PolyesterClientBaseConfig {}\n\ninterface AuthServiceFactoryContext {\n transports: AuthServiceTransports;\n realtime: PolyesterRealtime;\n subaccounts: SubaccountsService;\n environment: PolyesterEnvironment;\n}\n\ninterface PolyesterClientRuntimeConfig {\n createAuth?: (context: AuthServiceFactoryContext) => AuthService;\n}\n\n/**\n * Base SDK client that wires transports, realtime, catalogs, and all public service clients for a Polyester environment.\n *\n * Services are constructed lazily on first property access (and memoized) so\n * that creating a client — which happens for every SSR request in server\n * hooks — only pays for the services the caller actually touches.\n */\nexport class PolyesterClient {\n protected readonly transports: Transports;\n\n readonly #environment: PolyesterEnvironment;\n readonly #authProvider: JwtAuthProvider | ApiKeyEd25519AuthProvider | undefined;\n readonly #realtimeConfig: PolyesterRealtimeAuthConfig | undefined;\n readonly #configRealtimeClient: PolyesterRealtime | undefined;\n readonly #configCatalog: ClientCatalog | undefined;\n readonly #configCatalogSnapshot: CatalogSnapshot | undefined;\n readonly #configCatalogCell: CatalogSnapshotCell | undefined;\n readonly #createAuth: PolyesterClientRuntimeConfig[\"createAuth\"];\n\n #realtime: PolyesterRealtime | undefined;\n #catalog: ClientCatalog | undefined;\n #scales: SdkScales | undefined;\n #resolver: SubaccountResolver | undefined;\n #resolverInitialized = false;\n\n #auth: AuthService | undefined;\n #accounts: AccountsService | undefined;\n #apiKeys: ApiKeysService | undefined;\n #subaccounts: SubaccountsService | undefined;\n #candles: CandlesService | undefined;\n #chainAnalytics: ChainAnalyticsService | undefined;\n #marketData: MarketDataService | undefined;\n #marketOverview: MarketOverviewService | undefined;\n #orderbook: OrderbookService | undefined;\n #heatmap: HeatmapService | undefined;\n #lifecycle: LifecycleService | undefined;\n #trades: TradesService | undefined;\n #orders: OrdersService | undefined;\n #triggers: TriggersService | undefined;\n #balances: BalancesService | undefined;\n #transfers: TransfersService | undefined;\n #internalTransfers: InternalTransfersService | undefined;\n #tradingWithdraws: TradingWithdrawsService | undefined;\n #deposit: DepositService | undefined;\n #addressBook: AddressBookService | undefined;\n #guardSigner: GuardSignerService | undefined;\n #socialVerification: SocialVerificationService | undefined;\n #whiteboard: WhiteboardService | undefined;\n #zipper: ZipperService | undefined;\n #mfa: MfaService | undefined;\n\n constructor(config: PolyesterClientConfig, runtime: PolyesterClientRuntimeConfig = {}) {\n const interceptors = config.interceptors ?? [];\n const { environment } = config;\n if (config.catalog && config.catalogSnapshot) {\n throw new ConfigurationError(\"Provide either catalog or catalogSnapshot, not both.\");\n }\n if (config.catalog && config.catalogCell) {\n throw new ConfigurationError(\"Provide either catalog or catalogCell, not both.\");\n }\n\n this.transports =\n config.transports ??\n createTransports({\n apiUrl: environment.apiUrl,\n interceptors,\n auth: config.auth,\n wireFormat: config.wireFormat,\n });\n\n this.#environment = environment;\n this.#authProvider = config.auth;\n this.#realtimeConfig = config.realtime;\n this.#configRealtimeClient = config.realtimeClient;\n this.#configCatalog = config.catalog;\n this.#configCatalogSnapshot = config.catalogSnapshot;\n this.#configCatalogCell = config.catalogCell;\n this.#createAuth = runtime.createAuth;\n }\n\n get realtime(): PolyesterRealtime {\n if (!this.#realtime) {\n if (this.#configRealtimeClient) {\n this.#realtime = this.#configRealtimeClient;\n } else {\n const environment = this.#environment;\n const realtimeAuth = realtimeAuthFromProvider(this.#authProvider);\n this.#realtime = new RealtimeClient({\n wsUrl: environment.websocketUrl,\n tokenEndpoint: `${environment.apiUrl}/v1/rt/token`,\n subscribeEndpoint: `${environment.apiUrl}/v1/rt/subscribe`,\n getAuthHeaders:\n this.#realtimeConfig?.getAuthHeaders ?? realtimeAuth.getAuthHeaders,\n hasAuth: this.#realtimeConfig?.hasAuth ?? realtimeAuth.hasAuth,\n });\n }\n }\n return this.#realtime;\n }\n\n get catalog(): ClientCatalog {\n if (!this.#catalog) {\n if (this.#configCatalog) {\n this.#catalog = this.#configCatalog;\n } else {\n const catalogRefreshMarketData = new MarketDataService(\n this.transports.publicApi,\n this.realtime,\n this.#getScales(),\n );\n const catalogRefreshZipper = new ZipperService(this.transports.publicApi);\n this.#catalog = createPolyesterCatalog({\n snapshot: this.#configCatalogSnapshot,\n cell: this.#configCatalogCell,\n refresh: {\n market: () => catalogRefreshMarketData.getSpotConfig(),\n zipper: () => catalogRefreshZipper.getDepositWithdrawConfig(),\n },\n });\n }\n }\n return this.#catalog;\n }\n\n #getScales(): SdkScales {\n // Lazy catalog binding: the resolver only dereferences `this.catalog` at\n // call time. getSpotConfig() (the catalog's own refresh source) never\n // awaits scale readiness.\n this.#scales ??= createCatalogSdkScales(() => this.catalog);\n return this.#scales;\n }\n\n #getResolver(): SubaccountResolver | undefined {\n if (!this.#resolverInitialized) {\n this.#resolverInitialized = true;\n this.#resolver = this.createSubaccountResolver();\n }\n return this.#resolver;\n }\n\n get auth(): AuthService {\n if (!this.#auth) {\n const { authApi, publicApi } = this.transports;\n this.#auth =\n this.#createAuth?.({\n transports: { publicApi, authApi },\n realtime: this.realtime,\n subaccounts: this.subaccounts,\n environment: this.#environment,\n }) ?? new AuthService({ publicApi, authApi }, this.realtime);\n }\n return this.#auth;\n }\n\n get accounts(): AccountsService {\n return (this.#accounts ??= new AccountsService(this.transports.authApi));\n }\n\n get apiKeys(): ApiKeysService {\n return (this.#apiKeys ??= new ApiKeysService(\n this.transports.authApi,\n this.realtime,\n this.#getResolver(),\n ));\n }\n\n get subaccounts(): SubaccountsService {\n return (this.#subaccounts ??= new SubaccountsService(\n this.transports.authApi,\n this.realtime,\n this.#getResolver(),\n ));\n }\n\n get candles(): CandlesService {\n return (this.#candles ??= new CandlesService(\n this.transports.publicApi,\n this.realtime,\n this.#getScales(),\n ));\n }\n\n get chainAnalytics(): ChainAnalyticsService {\n return (this.#chainAnalytics ??= new ChainAnalyticsService(\n this.transports.publicApi,\n this.#getScales(),\n ));\n }\n\n get marketData(): MarketDataService {\n return (this.#marketData ??= new MarketDataService(\n this.transports.publicApi,\n this.realtime,\n this.#getScales(),\n ));\n }\n\n get marketOverview(): MarketOverviewService {\n return (this.#marketOverview ??= new MarketOverviewService(\n this.transports.publicApi,\n this.realtime,\n this.#getScales(),\n ));\n }\n\n get orderbook(): OrderbookService {\n return (this.#orderbook ??= new OrderbookService(\n this.transports.publicApi,\n this.realtime,\n this.#getScales(),\n ));\n }\n\n get heatmap(): HeatmapService {\n return (this.#heatmap ??= new HeatmapService(\n this.transports.publicApi,\n this.realtime,\n this.#getScales(),\n ));\n }\n\n get lifecycle(): LifecycleService {\n return (this.#lifecycle ??= new LifecycleService(this.transports.publicApi, this.realtime));\n }\n\n get trades(): TradesService {\n return (this.#trades ??= new TradesService(\n this.transports.authApi,\n this.realtime,\n this.#getResolver(),\n this.#getScales(),\n ));\n }\n\n get orders(): OrdersService {\n return (this.#orders ??= new OrdersService(\n this.transports.authApi,\n this.realtime,\n this.#getResolver(),\n this.#getScales(),\n ));\n }\n\n get triggers(): TriggersService {\n return (this.#triggers ??= new TriggersService(\n this.transports.authApi,\n this.realtime,\n this.#getResolver(),\n this.#getScales(),\n ));\n }\n\n get balances(): BalancesService {\n return (this.#balances ??= new BalancesService(\n this.transports.authApi,\n this.realtime,\n this.#getResolver(),\n this.#getScales(),\n ));\n }\n\n get transfers(): TransfersService {\n return (this.#transfers ??= new TransfersService(\n this.transports.authApi,\n this.realtime,\n this.#getResolver(),\n this.#getScales(),\n ));\n }\n\n get internalTransfers(): InternalTransfersService {\n return (this.#internalTransfers ??= new InternalTransfersService(\n this.transports.authApi,\n this.#getResolver(),\n this.#getScales(),\n ));\n }\n\n get tradingWithdraws(): TradingWithdrawsService {\n return (this.#tradingWithdraws ??= new TradingWithdrawsService(\n this.transports.authApi,\n this.#getResolver(),\n {\n chainId: this.#environment.chain.id,\n tradingGatewayAddress: this.#environment.contracts.tradingGatewayAddress,\n },\n this.#getScales(),\n this.catalog,\n ));\n }\n\n get deposit(): DepositService {\n return (this.#deposit ??= new DepositService(this.transports.authApi, this.#getResolver()));\n }\n\n get addressBook(): AddressBookService {\n return (this.#addressBook ??= new AddressBookService(\n this.transports.authApi,\n this.realtime,\n this.#getResolver(),\n ));\n }\n\n get guardSigner(): GuardSignerService {\n return (this.#guardSigner ??= new GuardSignerService(\n this.transports.authApi,\n this.#getResolver(),\n ));\n }\n\n get socialVerification(): SocialVerificationService {\n return (this.#socialVerification ??= new SocialVerificationService(\n this.transports.authApi,\n ));\n }\n\n get whiteboard(): WhiteboardService {\n return (this.#whiteboard ??= new WhiteboardService(this.transports.authApi));\n }\n\n get zipper(): ZipperService {\n return (this.#zipper ??= new ZipperService(\n this.transports.publicApi,\n this.realtime,\n this.#getScales(),\n ));\n }\n\n get mfa(): MfaService {\n return (this.#mfa ??= new MfaService(this.transports.authApi));\n }\n\n /**\n * Override in subclasses to provide a subaccount resolver.\n * The resolver is called lazily when service methods are invoked.\n */\n protected createSubaccountResolver(): SubaccountResolver | undefined {\n return undefined;\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"core-client.js","names":["#environment","#authProvider","#realtimeConfig","#configRealtimeClient","#configCatalog","#configCatalogSnapshot","#configCatalogCell","#createAuth","#realtime","#catalog","#getScales","#scales","#resolverInitialized","#resolver","#auth","#accounts","#apiKeys","#getResolver","#subaccounts","#candles","#chainAnalytics","#marketData","#marketOverview","#orderbook","#heatmap","#lifecycle","#trades","#orders","#triggers","#balances","#transfers","#internalTransfers","#tradingWithdraws","#deposit","#addressBook","#guardSigner","#socialVerification","#whiteboard","#zipper","#mfa"],"sources":["../src/core-client.ts"],"sourcesContent":["import type { Interceptor } from \"@connectrpc/connect\";\nimport { ConfigurationError } from \"./shared/errors.js\";\nimport {\n createApiKeyEd25519AuthHeaders,\n createTransports,\n type Transports,\n type JwtAuthProvider,\n type ApiKeyEd25519AuthProvider,\n} from \"./shared/transports.js\";\nimport { parsePolyesterEnvironment, type PolyesterEnvironment } from \"./environment.js\";\nimport { AccountsService } from \"./services/accounts/index.js\";\nimport { ApiKeysService } from \"./services/api-keys/index.js\";\nimport { AuthService, type AuthServiceTransports } from \"./services/auth/auth.js\";\nimport { SubaccountsService } from \"./services/subaccounts/index.js\";\nimport { CandlesService } from \"./services/candles/index.js\";\nimport { ChainAnalyticsService } from \"./services/chain-analytics/index.js\";\nimport { MarketDataService } from \"./services/market-data/index.js\";\nimport { MarketOverviewService } from \"./services/market-overview/index.js\";\nimport { OrderbookService } from \"./services/orderbook/index.js\";\nimport { HeatmapService } from \"./services/heatmap/index.js\";\nimport { LifecycleService } from \"./services/lifecycle/index.js\";\nimport { TradesService } from \"./services/trades/index.js\";\nimport { OrdersService } from \"./services/orders/index.js\";\nimport { TriggersService } from \"./services/triggers/index.js\";\nimport { BalancesService } from \"./services/balances/index.js\";\nimport { TransfersService } from \"./services/transfers/index.js\";\nimport { InternalTransfersService } from \"./services/internal-transfers/index.js\";\nimport { TradingWithdrawsService } from \"./services/trading-withdraws/index.js\";\nimport { DepositService } from \"./services/deposit/index.js\";\nimport { AddressBookService } from \"./services/address-book/index.js\";\nimport { GuardSignerService } from \"./services/guard-signer/index.js\";\nimport { SocialVerificationService } from \"./services/social-verification/index.js\";\nimport { WhiteboardService } from \"./services/whiteboard/index.js\";\nimport { ZipperService } from \"./services/zipper/index.js\";\nimport { MfaService } from \"./services/mfa/index.js\";\nimport type { SubaccountResolver } from \"./services/subaccount-resolver.js\";\nimport {\n createPolyesterCatalog,\n type CatalogSnapshot,\n type CatalogSnapshotCell,\n type ClientCatalog,\n} from \"./catalogs/index.js\";\nimport { createCatalogSdkScales, type SdkScales } from \"./shared/decimal-surface.js\";\nimport { RealtimeClient, type PolyesterRealtime, type RealtimeConfig } from \"./realtime/index.js\";\n\nfunction realtimeAuthFromProvider(\n auth: JwtAuthProvider | ApiKeyEd25519AuthProvider | undefined,\n): Pick<RealtimeConfig, \"getAuthHeaders\" | \"hasAuth\"> {\n if (!auth) return {};\n if (auth.kind === \"jwt\") {\n return {\n getAuthHeaders: async () => {\n const token = await auth.getToken();\n const headers: Record<string, string> = {};\n if (token) headers.authorization = `Bearer ${token}`;\n return headers;\n },\n hasAuth: () => {\n // Only token getters that resolve synchronously can be checked here;\n // async getters are assumed authenticated and fail at token fetch.\n const token = auth.getToken();\n if (token instanceof Promise) return true;\n return typeof token === \"string\" && token.length > 0;\n },\n };\n }\n return {\n getAuthHeaders: (request) =>\n createApiKeyEd25519AuthHeaders(auth, {\n url: request.url,\n method: request.method,\n }),\n hasAuth: () => true,\n };\n}\n\nexport type PolyesterRealtimeAuthConfig = Pick<RealtimeConfig, \"getAuthHeaders\" | \"hasAuth\">;\n\ninterface PolyesterClientCommonConfig {\n environment: PolyesterEnvironment;\n interceptors?: Interceptor[];\n auth?: JwtAuthProvider | ApiKeyEd25519AuthProvider;\n realtime?: PolyesterRealtimeAuthConfig;\n /**\n * Connect wire format. Defaults to binary for production performance.\n * Use `json` for human-readable debugging.\n */\n wireFormat?: \"binary\" | \"json\";\n /**\n * Advanced: inject pre-built Connect transports (in-memory mocks, custom\n * stacks). When provided, the SDK does not build its own transports and the\n * built-in auth/error-mapping interceptors are NOT applied — the injected\n * transports own their full interceptor chain.\n */\n transports?: Transports;\n /**\n * Advanced: inject a realtime implementation (in-memory mocks, custom\n * stacks). When provided, the SDK skips constructing its Centrifuge-backed\n * realtime client and the `realtime` auth config is ignored.\n */\n realtimeClient?: PolyesterRealtime;\n}\n\ntype PolyesterCatalogConfig =\n | {\n /** Client-owned catalog store. */\n catalog: ClientCatalog;\n catalogSnapshot?: never;\n catalogCell?: never;\n }\n | {\n catalog?: never;\n /**\n * Explicit initial catalog snapshot, commonly hydrated from server-rendered data.\n * Combines with `catalogCell` as the cell's initial value without clobbering a\n * pre-populated cell.\n */\n catalogSnapshot?: CatalogSnapshot;\n /**\n * External snapshot storage for the client-built catalog. A cell backed by a\n * reactive source makes every catalog read reactive.\n */\n catalogCell?: CatalogSnapshotCell;\n };\n\n/** Configuration shared by every Polyester client. */\nexport type PolyesterClientBaseConfig = PolyesterClientCommonConfig & PolyesterCatalogConfig;\n\n/** Configuration for the base Polyester client. */\nexport type PolyesterClientConfig = PolyesterClientBaseConfig;\n\n/** Preserves the exclusive catalog configuration while projecting client config fields. */\nexport function pickPolyesterCatalogConfig(\n config: PolyesterClientBaseConfig,\n): PolyesterCatalogConfig {\n return config.catalog === undefined\n ? {\n catalogSnapshot: config.catalogSnapshot,\n catalogCell: config.catalogCell,\n }\n : { catalog: config.catalog };\n}\n\ninterface AuthServiceFactoryContext {\n transports: AuthServiceTransports;\n realtime: PolyesterRealtime;\n subaccounts: SubaccountsService;\n environment: PolyesterEnvironment;\n}\n\ninterface PolyesterClientRuntimeConfig {\n createAuth?: (context: AuthServiceFactoryContext) => AuthService;\n}\n\n/**\n * Parses the configuration shared by every public client constructor.\n */\nexport function parsePolyesterClientConfig<TConfig extends PolyesterClientBaseConfig>(\n config: TConfig,\n): TConfig {\n if (typeof config !== \"object\" || config === null || Array.isArray(config)) {\n throw new ConfigurationError(\"Client configuration must be an object.\");\n }\n const environment = parsePolyesterEnvironment(config.environment);\n if (\n config.wireFormat !== undefined &&\n config.wireFormat !== \"binary\" &&\n config.wireFormat !== \"json\"\n ) {\n throw new ConfigurationError('wireFormat must be either \"binary\" or \"json\".');\n }\n if (config.catalog && config.catalogSnapshot) {\n throw new ConfigurationError(\"Provide either catalog or catalogSnapshot, not both.\");\n }\n if (config.catalog && config.catalogCell) {\n throw new ConfigurationError(\"Provide either catalog or catalogCell, not both.\");\n }\n\n return Object.assign({}, config, { environment });\n}\n\n/**\n * Base SDK client that wires transports, realtime, catalogs, and all public service clients for a Polyester environment.\n *\n * Services are constructed lazily on first property access (and memoized) so\n * that creating a client — which happens for every SSR request in server\n * hooks — only pays for the services the caller actually touches.\n */\nexport class PolyesterClient {\n protected readonly transports: Transports;\n\n readonly #environment: PolyesterEnvironment;\n readonly #authProvider: JwtAuthProvider | ApiKeyEd25519AuthProvider | undefined;\n readonly #realtimeConfig: PolyesterRealtimeAuthConfig | undefined;\n readonly #configRealtimeClient: PolyesterRealtime | undefined;\n readonly #configCatalog: ClientCatalog | undefined;\n readonly #configCatalogSnapshot: CatalogSnapshot | undefined;\n readonly #configCatalogCell: CatalogSnapshotCell | undefined;\n readonly #createAuth: PolyesterClientRuntimeConfig[\"createAuth\"];\n\n #realtime: PolyesterRealtime | undefined;\n #catalog: ClientCatalog | undefined;\n #scales: SdkScales | undefined;\n #resolver: SubaccountResolver | undefined;\n #resolverInitialized = false;\n\n #auth: AuthService | undefined;\n #accounts: AccountsService | undefined;\n #apiKeys: ApiKeysService | undefined;\n #subaccounts: SubaccountsService | undefined;\n #candles: CandlesService | undefined;\n #chainAnalytics: ChainAnalyticsService | undefined;\n #marketData: MarketDataService | undefined;\n #marketOverview: MarketOverviewService | undefined;\n #orderbook: OrderbookService | undefined;\n #heatmap: HeatmapService | undefined;\n #lifecycle: LifecycleService | undefined;\n #trades: TradesService | undefined;\n #orders: OrdersService | undefined;\n #triggers: TriggersService | undefined;\n #balances: BalancesService | undefined;\n #transfers: TransfersService | undefined;\n #internalTransfers: InternalTransfersService | undefined;\n #tradingWithdraws: TradingWithdrawsService | undefined;\n #deposit: DepositService | undefined;\n #addressBook: AddressBookService | undefined;\n #guardSigner: GuardSignerService | undefined;\n #socialVerification: SocialVerificationService | undefined;\n #whiteboard: WhiteboardService | undefined;\n #zipper: ZipperService | undefined;\n #mfa: MfaService | undefined;\n\n constructor(config: PolyesterClientConfig, runtime: PolyesterClientRuntimeConfig = {}) {\n const parsedConfig = parsePolyesterClientConfig(config);\n config = parsedConfig;\n const interceptors = config.interceptors ?? [];\n const { environment } = config;\n\n this.transports =\n config.transports ??\n createTransports({\n apiUrl: environment.apiUrl,\n interceptors,\n auth: config.auth,\n wireFormat: config.wireFormat,\n });\n\n this.#environment = environment;\n this.#authProvider = config.auth;\n this.#realtimeConfig = config.realtime;\n this.#configRealtimeClient = config.realtimeClient;\n this.#configCatalog = config.catalog;\n this.#configCatalogSnapshot = config.catalogSnapshot;\n this.#configCatalogCell = config.catalogCell;\n this.#createAuth = runtime.createAuth;\n }\n\n get realtime(): PolyesterRealtime {\n if (!this.#realtime) {\n if (this.#configRealtimeClient) {\n this.#realtime = this.#configRealtimeClient;\n } else {\n const environment = this.#environment;\n const realtimeAuth = realtimeAuthFromProvider(this.#authProvider);\n this.#realtime = new RealtimeClient({\n wsUrl: environment.websocketUrl,\n tokenEndpoint: `${environment.apiUrl}/v1/rt/token`,\n subscribeEndpoint: `${environment.apiUrl}/v1/rt/subscribe`,\n getAuthHeaders:\n this.#realtimeConfig?.getAuthHeaders ?? realtimeAuth.getAuthHeaders,\n hasAuth: this.#realtimeConfig?.hasAuth ?? realtimeAuth.hasAuth,\n });\n }\n }\n return this.#realtime;\n }\n\n get catalog(): ClientCatalog {\n if (!this.#catalog) {\n if (this.#configCatalog) {\n this.#catalog = this.#configCatalog;\n } else {\n const catalogRefreshMarketData = new MarketDataService(\n this.transports.publicApi,\n this.realtime,\n this.#getScales(),\n );\n const catalogRefreshZipper = new ZipperService(this.transports.publicApi);\n this.#catalog = createPolyesterCatalog({\n snapshot: this.#configCatalogSnapshot,\n cell: this.#configCatalogCell,\n refresh: {\n market: () => catalogRefreshMarketData.getSpotConfig(),\n zipper: () => catalogRefreshZipper.getDepositWithdrawConfig(),\n },\n });\n }\n }\n return this.#catalog;\n }\n\n #getScales(): SdkScales {\n // Lazy catalog binding: the resolver only dereferences `this.catalog` at\n // call time. getSpotConfig() (the catalog's own refresh source) never\n // awaits scale readiness.\n this.#scales ??= createCatalogSdkScales(() => this.catalog);\n return this.#scales;\n }\n\n #getResolver(): SubaccountResolver | undefined {\n if (!this.#resolverInitialized) {\n this.#resolverInitialized = true;\n this.#resolver = this.createSubaccountResolver();\n }\n return this.#resolver;\n }\n\n get auth(): AuthService {\n if (!this.#auth) {\n const { authApi, publicApi } = this.transports;\n this.#auth =\n this.#createAuth?.({\n transports: { publicApi, authApi },\n realtime: this.realtime,\n subaccounts: this.subaccounts,\n environment: this.#environment,\n }) ?? new AuthService({ publicApi, authApi }, this.realtime);\n }\n return this.#auth;\n }\n\n get accounts(): AccountsService {\n return (this.#accounts ??= new AccountsService(this.transports.authApi));\n }\n\n get apiKeys(): ApiKeysService {\n return (this.#apiKeys ??= new ApiKeysService(\n this.transports.authApi,\n this.realtime,\n this.#getResolver(),\n ));\n }\n\n get subaccounts(): SubaccountsService {\n return (this.#subaccounts ??= new SubaccountsService(\n this.transports.authApi,\n this.realtime,\n this.#getResolver(),\n ));\n }\n\n get candles(): CandlesService {\n return (this.#candles ??= new CandlesService(\n this.transports.publicApi,\n this.realtime,\n this.#getScales(),\n ));\n }\n\n get chainAnalytics(): ChainAnalyticsService {\n return (this.#chainAnalytics ??= new ChainAnalyticsService(\n this.transports.publicApi,\n this.#getScales(),\n ));\n }\n\n get marketData(): MarketDataService {\n return (this.#marketData ??= new MarketDataService(\n this.transports.publicApi,\n this.realtime,\n this.#getScales(),\n ));\n }\n\n get marketOverview(): MarketOverviewService {\n return (this.#marketOverview ??= new MarketOverviewService(\n this.transports.publicApi,\n this.realtime,\n this.#getScales(),\n ));\n }\n\n get orderbook(): OrderbookService {\n return (this.#orderbook ??= new OrderbookService(\n this.transports.publicApi,\n this.realtime,\n this.#getScales(),\n ));\n }\n\n get heatmap(): HeatmapService {\n return (this.#heatmap ??= new HeatmapService(\n this.transports.publicApi,\n this.realtime,\n this.#getScales(),\n ));\n }\n\n get lifecycle(): LifecycleService {\n return (this.#lifecycle ??= new LifecycleService(this.transports.publicApi, this.realtime));\n }\n\n get trades(): TradesService {\n return (this.#trades ??= new TradesService(\n this.transports.authApi,\n this.realtime,\n this.#getResolver(),\n this.#getScales(),\n ));\n }\n\n get orders(): OrdersService {\n return (this.#orders ??= new OrdersService(\n this.transports.authApi,\n this.realtime,\n this.#getResolver(),\n this.#getScales(),\n ));\n }\n\n get triggers(): TriggersService {\n return (this.#triggers ??= new TriggersService(\n this.transports.authApi,\n this.realtime,\n this.#getResolver(),\n this.#getScales(),\n ));\n }\n\n get balances(): BalancesService {\n return (this.#balances ??= new BalancesService(\n this.transports.authApi,\n this.realtime,\n this.#getResolver(),\n this.#getScales(),\n ));\n }\n\n get transfers(): TransfersService {\n return (this.#transfers ??= new TransfersService(\n this.transports.authApi,\n this.realtime,\n this.#getResolver(),\n this.#getScales(),\n ));\n }\n\n get internalTransfers(): InternalTransfersService {\n return (this.#internalTransfers ??= new InternalTransfersService(\n this.transports.authApi,\n this.#getResolver(),\n this.#getScales(),\n ));\n }\n\n get tradingWithdraws(): TradingWithdrawsService {\n return (this.#tradingWithdraws ??= new TradingWithdrawsService(\n this.transports.authApi,\n this.#getResolver(),\n {\n chainId: this.#environment.chain.id,\n tradingGatewayAddress: this.#environment.contracts.tradingGatewayAddress,\n },\n this.#getScales(),\n this.catalog,\n ));\n }\n\n get deposit(): DepositService {\n return (this.#deposit ??= new DepositService(this.transports.authApi, this.#getResolver()));\n }\n\n get addressBook(): AddressBookService {\n return (this.#addressBook ??= new AddressBookService(\n this.transports.authApi,\n this.realtime,\n this.#getResolver(),\n ));\n }\n\n get guardSigner(): GuardSignerService {\n return (this.#guardSigner ??= new GuardSignerService(\n this.transports.authApi,\n this.#getResolver(),\n ));\n }\n\n get socialVerification(): SocialVerificationService {\n return (this.#socialVerification ??= new SocialVerificationService(\n this.transports.authApi,\n ));\n }\n\n get whiteboard(): WhiteboardService {\n return (this.#whiteboard ??= new WhiteboardService(this.transports.authApi));\n }\n\n get zipper(): ZipperService {\n return (this.#zipper ??= new ZipperService(\n this.transports.publicApi,\n this.realtime,\n this.#getScales(),\n ));\n }\n\n get mfa(): MfaService {\n return (this.#mfa ??= new MfaService(this.transports.authApi));\n }\n\n /**\n * Override in subclasses to provide a subaccount resolver.\n * The resolver is called lazily when service methods are invoked.\n */\n protected createSubaccountResolver(): SubaccountResolver | undefined {\n return undefined;\n }\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"environment.d.ts","names":[],"sources":["../src/environment.ts"],"mappings":";;;UAKiB;WACJ,SAAS;WACT;;UAGI;WACJ,SAAS;WACT,wBAAwB;WACxB,uBAAuB;WACvB,yBAAyB;WACzB,sBAAsB;WACtB,kBAAkB;WAClB,2BAA2B;;UAGvB;WACJ;WACA;WACA,YAAY;WACZ,MAAM;;UAGF;WACJ,uBAAuB;;UAGnB;WACJ;WACA;WACA;WACA;WACA;WACA,OAAO;WACP,oBAAoB;WACpB,WAAW;;UAGP;WACJ;WACA;WACA;WACA;WACA,OAAO;WACP;aACI;aACA;aACA,YAAY;aACZ,MAAM;;WAEV,WAAW;;;;;
|
|
1
|
+
{"version":3,"file":"environment.d.ts","names":[],"sources":["../src/environment.ts"],"mappings":";;;UAKiB;WACJ,SAAS;WACT;;UAGI;WACJ,SAAS;WACT,wBAAwB;WACxB,uBAAuB;WACvB,yBAAyB;WACzB,sBAAsB;WACtB,kBAAkB;WAClB,2BAA2B;;UAGvB;WACJ;WACA;WACA,YAAY;WACZ,MAAM;;UAGF;WACJ,uBAAuB;;UAGnB;WACJ;WACA;WACA;WACA;WACA;WACA,OAAO;WACP,oBAAoB;WACpB,WAAW;;UAGP;WACJ;WACA;WACA;WACA;WACA,OAAO;WACP;aACI;aACA;aACA,YAAY;aACZ,MAAM;;WAEV,WAAW;;;;;iBAmKR,2BACZ,QAAQ,mCACT;cAgEU,+BAA6B"}
|
package/dist/environment.js
CHANGED
|
@@ -7,6 +7,12 @@ const LOCAL_HOSTS = /* @__PURE__ */ new Set([
|
|
|
7
7
|
"::1",
|
|
8
8
|
"[::1]"
|
|
9
9
|
]);
|
|
10
|
+
function requireObject(value, label) {
|
|
11
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) throw new ConfigurationError(`${label} must be an object.`);
|
|
12
|
+
}
|
|
13
|
+
function requireNonEmptyString(value, label) {
|
|
14
|
+
if (typeof value !== "string" || value.trim().length === 0) throw new ConfigurationError(`${label} must be a non-empty string.`);
|
|
15
|
+
}
|
|
10
16
|
function isLocalHost(hostname) {
|
|
11
17
|
return LOCAL_HOSTS.has(hostname);
|
|
12
18
|
}
|
|
@@ -27,6 +33,7 @@ function normalizeAddress(value, label) {
|
|
|
27
33
|
return checksumEvmAddress(value);
|
|
28
34
|
}
|
|
29
35
|
function normalizeEntryPoint(entryPoint) {
|
|
36
|
+
requireObject(entryPoint, "accountAbstraction.entryPoint");
|
|
30
37
|
if (entryPoint.version !== "0.7") throw new ConfigurationError("accountAbstraction.entryPoint.version must be 0.7.");
|
|
31
38
|
return Object.freeze({
|
|
32
39
|
address: normalizeAddress(entryPoint.address, "accountAbstraction.entryPoint.address"),
|
|
@@ -34,6 +41,8 @@ function normalizeEntryPoint(entryPoint) {
|
|
|
34
41
|
});
|
|
35
42
|
}
|
|
36
43
|
function normalizeSafeConfig(safe) {
|
|
44
|
+
requireObject(safe, "accountAbstraction.safe");
|
|
45
|
+
if (safe.version !== "1.4.1" && safe.version !== "1.5.0") throw new ConfigurationError("accountAbstraction.safe.version must be either \"1.4.1\" or \"1.5.0\".");
|
|
37
46
|
return Object.freeze({
|
|
38
47
|
version: safe.version,
|
|
39
48
|
safeModuleSetupAddress: normalizeAddress(safe.safeModuleSetupAddress, "accountAbstraction.safe.safeModuleSetupAddress"),
|
|
@@ -45,7 +54,16 @@ function normalizeSafeConfig(safe) {
|
|
|
45
54
|
});
|
|
46
55
|
}
|
|
47
56
|
function normalizeChain(chain, rpcUrl) {
|
|
57
|
+
requireObject(chain, "chain");
|
|
48
58
|
if (!Number.isInteger(chain.id) || chain.id <= 0) throw new ConfigurationError("chain.id must be a positive integer.");
|
|
59
|
+
requireNonEmptyString(chain.name, "chain.name");
|
|
60
|
+
requireObject(chain.nativeCurrency, "chain.nativeCurrency");
|
|
61
|
+
if (!Number.isInteger(chain.nativeCurrency.decimals) || chain.nativeCurrency.decimals < 0) throw new ConfigurationError("chain.nativeCurrency.decimals must be a non-negative integer.");
|
|
62
|
+
requireNonEmptyString(chain.nativeCurrency.name, "chain.nativeCurrency.name");
|
|
63
|
+
requireNonEmptyString(chain.nativeCurrency.symbol, "chain.nativeCurrency.symbol");
|
|
64
|
+
requireObject(chain.rpcUrls, "chain.rpcUrls");
|
|
65
|
+
requireObject(chain.rpcUrls.default, "chain.rpcUrls.default");
|
|
66
|
+
if (!Array.isArray(chain.rpcUrls.default.http)) throw new ConfigurationError("chain.rpcUrls.default.http must be an array.");
|
|
49
67
|
return Object.freeze({
|
|
50
68
|
formatters: void 0,
|
|
51
69
|
fees: void 0,
|
|
@@ -77,6 +95,10 @@ function environmentFingerprint(input) {
|
|
|
77
95
|
* Creates a complete SDK environment configuration from entrypoint and contract settings.
|
|
78
96
|
*/
|
|
79
97
|
function createPolyesterEnvironment(params) {
|
|
98
|
+
requireObject(params, "Environment configuration");
|
|
99
|
+
requireNonEmptyString(params.name, "name");
|
|
100
|
+
requireObject(params.accountAbstraction, "accountAbstraction");
|
|
101
|
+
requireObject(params.contracts, "contracts");
|
|
80
102
|
const apiUrl = normalizeUrl(params.apiUrl, "apiUrl", ["https:", "http:"]);
|
|
81
103
|
const websocketUrl = normalizeUrl(params.websocketUrl, "websocketUrl", ["wss:", "ws:"]);
|
|
82
104
|
const rpcUrl = normalizeUrl(params.rpcUrl, "rpcUrl", ["https:", "http:"]);
|
|
@@ -109,6 +131,15 @@ function createPolyesterEnvironment(params) {
|
|
|
109
131
|
contracts
|
|
110
132
|
});
|
|
111
133
|
}
|
|
134
|
+
/**
|
|
135
|
+
* Parses a complete environment supplied to a public SDK client constructor.
|
|
136
|
+
*/
|
|
137
|
+
function parsePolyesterEnvironment(environment) {
|
|
138
|
+
requireObject(environment, "environment");
|
|
139
|
+
const parsed = createPolyesterEnvironment(environment);
|
|
140
|
+
if (environment.fingerprint !== parsed.fingerprint) throw new ConfigurationError("environment.fingerprint must match the environment configuration.");
|
|
141
|
+
return parsed;
|
|
142
|
+
}
|
|
112
143
|
const POLYESTER_TESTNET_ENVIRONMENT = createPolyesterEnvironment({
|
|
113
144
|
name: "polyester-testnet",
|
|
114
145
|
apiUrl: "https://api-devnet.polyester.ai",
|
|
@@ -148,6 +179,6 @@ const POLYESTER_TESTNET_ENVIRONMENT = createPolyesterEnvironment({
|
|
|
148
179
|
contracts: { tradingGatewayAddress: "0xD3fecf5D39131e23b6B0f872cA0a21c8A5a30932" }
|
|
149
180
|
});
|
|
150
181
|
//#endregion
|
|
151
|
-
export { POLYESTER_TESTNET_ENVIRONMENT, createPolyesterEnvironment };
|
|
182
|
+
export { POLYESTER_TESTNET_ENVIRONMENT, createPolyesterEnvironment, parsePolyesterEnvironment };
|
|
152
183
|
|
|
153
184
|
//# sourceMappingURL=environment.js.map
|
package/dist/environment.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"environment.js","names":[],"sources":["../src/environment.ts"],"sourcesContent":["import type { SafeVersion } from \"permissionless/accounts\";\nimport { ConfigurationError } from \"./shared/errors.js\";\nimport type { Address, Chain } from \"viem\";\nimport { checksumEvmAddress, evmUtf8ToBytes, isEvmAddress, keccak256Hex } from \"./utils/evm.js\";\n\nexport interface PolyesterEntryPointConfig {\n readonly address: Address;\n readonly version: \"0.7\";\n}\n\nexport interface PolyesterSafeDeploymentConfig {\n readonly version: SafeVersion;\n readonly safeModuleSetupAddress: Address;\n readonly safe4337ModuleAddress: Address;\n readonly safeProxyFactoryAddress: Address;\n readonly safeSingletonAddress: Address;\n readonly multiSendAddress: Address;\n readonly multiSendCallOnlyAddress?: Address;\n}\n\nexport interface PolyesterAccountAbstractionEnvironment {\n readonly bundlerUrl: string;\n readonly paymasterUrl: string;\n readonly entryPoint: PolyesterEntryPointConfig;\n readonly safe: PolyesterSafeDeploymentConfig;\n}\n\nexport interface PolyesterContractsEnvironment {\n readonly tradingGatewayAddress: Address;\n}\n\nexport interface PolyesterEnvironment {\n readonly name: string;\n readonly fingerprint: string;\n readonly apiUrl: string;\n readonly websocketUrl: string;\n readonly rpcUrl: string;\n readonly chain: Chain;\n readonly accountAbstraction: PolyesterAccountAbstractionEnvironment;\n readonly contracts: PolyesterContractsEnvironment;\n}\n\nexport interface CreatePolyesterEnvironmentParams {\n readonly name: string;\n readonly apiUrl: string;\n readonly websocketUrl: string;\n readonly rpcUrl: string;\n readonly chain: Chain;\n readonly accountAbstraction: {\n readonly bundlerUrl: string;\n readonly paymasterUrl: string;\n readonly entryPoint: PolyesterEntryPointConfig;\n readonly safe: PolyesterSafeDeploymentConfig;\n };\n readonly contracts: PolyesterContractsEnvironment;\n}\n\nconst LOCAL_HOSTS = new Set([\"localhost\", \"127.0.0.1\", \"::1\", \"[::1]\"]);\n\nfunction isLocalHost(hostname: string): boolean {\n return LOCAL_HOSTS.has(hostname);\n}\n\nfunction normalizeUrl(value: string, label: string, allowedProtocols: readonly string[]): string {\n let url: URL;\n try {\n url = new URL(value);\n } catch {\n throw new ConfigurationError(`${label} must be a valid URL.`);\n }\n\n if (!allowedProtocols.includes(url.protocol)) {\n throw new ConfigurationError(`${label} must use ${allowedProtocols.join(\" or \")}.`);\n }\n\n const insecureRemote =\n (url.protocol === \"http:\" || url.protocol === \"ws:\") && !isLocalHost(url.hostname);\n if (insecureRemote) {\n throw new ConfigurationError(`${label} must use a secure protocol for remote hosts.`);\n }\n\n url.hash = \"\";\n return url.toString().replace(/\\/+$/u, \"\");\n}\n\nfunction normalizeAddress(value: Address, label: string): Address {\n if (!isEvmAddress(value)) {\n throw new ConfigurationError(`${label} must be a valid address.`);\n }\n return checksumEvmAddress(value);\n}\n\nfunction normalizeEntryPoint(entryPoint: PolyesterEntryPointConfig): PolyesterEntryPointConfig {\n if (entryPoint.version !== \"0.7\") {\n throw new ConfigurationError(\"accountAbstraction.entryPoint.version must be 0.7.\");\n }\n return Object.freeze({\n address: normalizeAddress(entryPoint.address, \"accountAbstraction.entryPoint.address\"),\n version: entryPoint.version,\n });\n}\n\nfunction normalizeSafeConfig(safe: PolyesterSafeDeploymentConfig): PolyesterSafeDeploymentConfig {\n return Object.freeze({\n version: safe.version,\n safeModuleSetupAddress: normalizeAddress(\n safe.safeModuleSetupAddress,\n \"accountAbstraction.safe.safeModuleSetupAddress\",\n ),\n safe4337ModuleAddress: normalizeAddress(\n safe.safe4337ModuleAddress,\n \"accountAbstraction.safe.safe4337ModuleAddress\",\n ),\n safeProxyFactoryAddress: normalizeAddress(\n safe.safeProxyFactoryAddress,\n \"accountAbstraction.safe.safeProxyFactoryAddress\",\n ),\n safeSingletonAddress: normalizeAddress(\n safe.safeSingletonAddress,\n \"accountAbstraction.safe.safeSingletonAddress\",\n ),\n multiSendAddress: normalizeAddress(\n safe.multiSendAddress,\n \"accountAbstraction.safe.multiSendAddress\",\n ),\n multiSendCallOnlyAddress: safe.multiSendCallOnlyAddress\n ? normalizeAddress(\n safe.multiSendCallOnlyAddress,\n \"accountAbstraction.safe.multiSendCallOnlyAddress\",\n )\n : undefined,\n });\n}\n\nfunction normalizeChain(chain: Chain, rpcUrl: string): Chain {\n if (!Number.isInteger(chain.id) || chain.id <= 0) {\n throw new ConfigurationError(\"chain.id must be a positive integer.\");\n }\n\n // Shape parity with viem's defineChain: spread over undefined defaults.\n return Object.freeze({\n formatters: undefined,\n fees: undefined,\n serializers: undefined,\n ...chain,\n rpcUrls: {\n ...chain.rpcUrls,\n default: {\n ...chain.rpcUrls.default,\n http: [rpcUrl],\n },\n },\n });\n}\n\nfunction environmentFingerprint(input: {\n apiUrl: string;\n websocketUrl: string;\n rpcUrl: string;\n chainId: number;\n accountAbstraction: PolyesterAccountAbstractionEnvironment;\n contracts: PolyesterContractsEnvironment;\n}): string {\n return keccak256Hex(\n evmUtf8ToBytes(\n JSON.stringify({\n apiUrl: input.apiUrl,\n websocketUrl: input.websocketUrl,\n rpcUrl: input.rpcUrl,\n chainId: input.chainId,\n bundlerUrl: input.accountAbstraction.bundlerUrl,\n paymasterUrl: input.accountAbstraction.paymasterUrl,\n entryPoint: input.accountAbstraction.entryPoint,\n safe: input.accountAbstraction.safe,\n contracts: input.contracts,\n }),\n ),\n );\n}\n\n/**\n * Creates a complete SDK environment configuration from entrypoint and contract settings.\n */\nexport function createPolyesterEnvironment(\n params: CreatePolyesterEnvironmentParams,\n): PolyesterEnvironment {\n const apiUrl = normalizeUrl(params.apiUrl, \"apiUrl\", [\"https:\", \"http:\"]);\n const websocketUrl = normalizeUrl(params.websocketUrl, \"websocketUrl\", [\"wss:\", \"ws:\"]);\n const rpcUrl = normalizeUrl(params.rpcUrl, \"rpcUrl\", [\"https:\", \"http:\"]);\n const bundlerUrl = normalizeUrl(params.accountAbstraction.bundlerUrl, \"bundlerUrl\", [\n \"https:\",\n \"http:\",\n ]);\n const paymasterUrl = normalizeUrl(params.accountAbstraction.paymasterUrl, \"paymasterUrl\", [\n \"https:\",\n \"http:\",\n ]);\n const chain = normalizeChain(params.chain, rpcUrl);\n const accountAbstraction = Object.freeze({\n bundlerUrl,\n paymasterUrl,\n entryPoint: normalizeEntryPoint(params.accountAbstraction.entryPoint),\n safe: normalizeSafeConfig(params.accountAbstraction.safe),\n });\n const contracts = Object.freeze({\n tradingGatewayAddress: normalizeAddress(\n params.contracts.tradingGatewayAddress,\n \"contracts.tradingGatewayAddress\",\n ),\n });\n const fingerprint = environmentFingerprint({\n apiUrl,\n websocketUrl,\n rpcUrl,\n chainId: chain.id,\n accountAbstraction,\n contracts,\n });\n\n return Object.freeze({\n name: params.name,\n fingerprint,\n apiUrl,\n websocketUrl,\n rpcUrl,\n chain,\n accountAbstraction,\n contracts,\n });\n}\n\nexport const POLYESTER_TESTNET_ENVIRONMENT = createPolyesterEnvironment({\n name: \"polyester-testnet\",\n apiUrl: \"https://api-devnet.polyester.ai\",\n websocketUrl: \"wss://api-devnet.polyester.ai\",\n rpcUrl: \"https://rpc.polyester.tech\",\n chain: {\n id: 888168,\n name: \"Polyester Chain Testnet\",\n nativeCurrency: {\n decimals: 18,\n name: \"POL\",\n symbol: \"POL\",\n },\n rpcUrls: {\n default: {\n http: [\"https://rpc.polyester.tech\"],\n },\n },\n blockExplorers: {\n default: {\n name: \"Polyester Scan\",\n url: \"https://polyesterscan.com\",\n },\n },\n },\n accountAbstraction: {\n bundlerUrl: \"https://bundler.polyester.tech\",\n paymasterUrl: \"https://paymaster.polyester.tech\",\n entryPoint: {\n address: \"0x59a4B77766509c4507D79eFF8089474eC3daC174\",\n version: \"0.7\",\n },\n safe: {\n version: \"1.4.1\",\n safeModuleSetupAddress: \"0x80791683D9C079A37Debc67EaDdbFcBC6f0FF2bB\",\n safe4337ModuleAddress: \"0x0713FF3d4c1b4f177833a372b1e3cb977540EA11\",\n safeProxyFactoryAddress: \"0xF8F0F649Dd3bFa9095206691E9fb2356c26216dE\",\n safeSingletonAddress: \"0x92abEa238FEA8908c397cE65366ea9278f0AeC7A\",\n multiSendAddress: \"0x70C8a8CcB45a8E2589B0f019374fc923dA34E4c7\",\n multiSendCallOnlyAddress: \"0x375C86a08DA98d1944D7B3c736307A72186CcAf1\",\n },\n },\n contracts: {\n tradingGatewayAddress: \"0xD3fecf5D39131e23b6B0f872cA0a21c8A5a30932\",\n },\n});\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"environment.js","names":[],"sources":["../src/environment.ts"],"sourcesContent":["import type { SafeVersion } from \"permissionless/accounts\";\nimport { ConfigurationError } from \"./shared/errors.js\";\nimport type { Address, Chain } from \"viem\";\nimport { checksumEvmAddress, evmUtf8ToBytes, isEvmAddress, keccak256Hex } from \"./utils/evm.js\";\n\nexport interface PolyesterEntryPointConfig {\n readonly address: Address;\n readonly version: \"0.7\";\n}\n\nexport interface PolyesterSafeDeploymentConfig {\n readonly version: SafeVersion;\n readonly safeModuleSetupAddress: Address;\n readonly safe4337ModuleAddress: Address;\n readonly safeProxyFactoryAddress: Address;\n readonly safeSingletonAddress: Address;\n readonly multiSendAddress: Address;\n readonly multiSendCallOnlyAddress?: Address;\n}\n\nexport interface PolyesterAccountAbstractionEnvironment {\n readonly bundlerUrl: string;\n readonly paymasterUrl: string;\n readonly entryPoint: PolyesterEntryPointConfig;\n readonly safe: PolyesterSafeDeploymentConfig;\n}\n\nexport interface PolyesterContractsEnvironment {\n readonly tradingGatewayAddress: Address;\n}\n\nexport interface PolyesterEnvironment {\n readonly name: string;\n readonly fingerprint: string;\n readonly apiUrl: string;\n readonly websocketUrl: string;\n readonly rpcUrl: string;\n readonly chain: Chain;\n readonly accountAbstraction: PolyesterAccountAbstractionEnvironment;\n readonly contracts: PolyesterContractsEnvironment;\n}\n\nexport interface CreatePolyesterEnvironmentParams {\n readonly name: string;\n readonly apiUrl: string;\n readonly websocketUrl: string;\n readonly rpcUrl: string;\n readonly chain: Chain;\n readonly accountAbstraction: {\n readonly bundlerUrl: string;\n readonly paymasterUrl: string;\n readonly entryPoint: PolyesterEntryPointConfig;\n readonly safe: PolyesterSafeDeploymentConfig;\n };\n readonly contracts: PolyesterContractsEnvironment;\n}\n\nconst LOCAL_HOSTS = new Set([\"localhost\", \"127.0.0.1\", \"::1\", \"[::1]\"]);\n\nfunction requireObject(value: unknown, label: string): asserts value is Record<string, unknown> {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n throw new ConfigurationError(`${label} must be an object.`);\n }\n}\n\nfunction requireNonEmptyString(value: unknown, label: string): asserts value is string {\n if (typeof value !== \"string\" || value.trim().length === 0) {\n throw new ConfigurationError(`${label} must be a non-empty string.`);\n }\n}\n\nfunction isLocalHost(hostname: string): boolean {\n return LOCAL_HOSTS.has(hostname);\n}\n\nfunction normalizeUrl(value: string, label: string, allowedProtocols: readonly string[]): string {\n let url: URL;\n try {\n url = new URL(value);\n } catch {\n throw new ConfigurationError(`${label} must be a valid URL.`);\n }\n\n if (!allowedProtocols.includes(url.protocol)) {\n throw new ConfigurationError(`${label} must use ${allowedProtocols.join(\" or \")}.`);\n }\n\n const insecureRemote =\n (url.protocol === \"http:\" || url.protocol === \"ws:\") && !isLocalHost(url.hostname);\n if (insecureRemote) {\n throw new ConfigurationError(`${label} must use a secure protocol for remote hosts.`);\n }\n\n url.hash = \"\";\n return url.toString().replace(/\\/+$/u, \"\");\n}\n\nfunction normalizeAddress(value: Address, label: string): Address {\n if (!isEvmAddress(value)) {\n throw new ConfigurationError(`${label} must be a valid address.`);\n }\n return checksumEvmAddress(value);\n}\n\nfunction normalizeEntryPoint(entryPoint: PolyesterEntryPointConfig): PolyesterEntryPointConfig {\n requireObject(entryPoint, \"accountAbstraction.entryPoint\");\n if (entryPoint.version !== \"0.7\") {\n throw new ConfigurationError(\"accountAbstraction.entryPoint.version must be 0.7.\");\n }\n return Object.freeze({\n address: normalizeAddress(entryPoint.address, \"accountAbstraction.entryPoint.address\"),\n version: entryPoint.version,\n });\n}\n\nfunction normalizeSafeConfig(safe: PolyesterSafeDeploymentConfig): PolyesterSafeDeploymentConfig {\n requireObject(safe, \"accountAbstraction.safe\");\n if (safe.version !== \"1.4.1\" && safe.version !== \"1.5.0\") {\n throw new ConfigurationError(\n 'accountAbstraction.safe.version must be either \"1.4.1\" or \"1.5.0\".',\n );\n }\n return Object.freeze({\n version: safe.version,\n safeModuleSetupAddress: normalizeAddress(\n safe.safeModuleSetupAddress,\n \"accountAbstraction.safe.safeModuleSetupAddress\",\n ),\n safe4337ModuleAddress: normalizeAddress(\n safe.safe4337ModuleAddress,\n \"accountAbstraction.safe.safe4337ModuleAddress\",\n ),\n safeProxyFactoryAddress: normalizeAddress(\n safe.safeProxyFactoryAddress,\n \"accountAbstraction.safe.safeProxyFactoryAddress\",\n ),\n safeSingletonAddress: normalizeAddress(\n safe.safeSingletonAddress,\n \"accountAbstraction.safe.safeSingletonAddress\",\n ),\n multiSendAddress: normalizeAddress(\n safe.multiSendAddress,\n \"accountAbstraction.safe.multiSendAddress\",\n ),\n multiSendCallOnlyAddress: safe.multiSendCallOnlyAddress\n ? normalizeAddress(\n safe.multiSendCallOnlyAddress,\n \"accountAbstraction.safe.multiSendCallOnlyAddress\",\n )\n : undefined,\n });\n}\n\nfunction normalizeChain(chain: Chain, rpcUrl: string): Chain {\n requireObject(chain, \"chain\");\n if (!Number.isInteger(chain.id) || chain.id <= 0) {\n throw new ConfigurationError(\"chain.id must be a positive integer.\");\n }\n requireNonEmptyString(chain.name, \"chain.name\");\n requireObject(chain.nativeCurrency, \"chain.nativeCurrency\");\n if (!Number.isInteger(chain.nativeCurrency.decimals) || chain.nativeCurrency.decimals < 0) {\n throw new ConfigurationError(\n \"chain.nativeCurrency.decimals must be a non-negative integer.\",\n );\n }\n requireNonEmptyString(chain.nativeCurrency.name, \"chain.nativeCurrency.name\");\n requireNonEmptyString(chain.nativeCurrency.symbol, \"chain.nativeCurrency.symbol\");\n requireObject(chain.rpcUrls, \"chain.rpcUrls\");\n requireObject(chain.rpcUrls.default, \"chain.rpcUrls.default\");\n if (!Array.isArray(chain.rpcUrls.default.http)) {\n throw new ConfigurationError(\"chain.rpcUrls.default.http must be an array.\");\n }\n\n // Shape parity with viem's defineChain: spread over undefined defaults.\n return Object.freeze({\n formatters: undefined,\n fees: undefined,\n serializers: undefined,\n ...chain,\n rpcUrls: {\n ...chain.rpcUrls,\n default: {\n ...chain.rpcUrls.default,\n http: [rpcUrl],\n },\n },\n });\n}\n\nfunction environmentFingerprint(input: {\n apiUrl: string;\n websocketUrl: string;\n rpcUrl: string;\n chainId: number;\n accountAbstraction: PolyesterAccountAbstractionEnvironment;\n contracts: PolyesterContractsEnvironment;\n}): string {\n return keccak256Hex(\n evmUtf8ToBytes(\n JSON.stringify({\n apiUrl: input.apiUrl,\n websocketUrl: input.websocketUrl,\n rpcUrl: input.rpcUrl,\n chainId: input.chainId,\n bundlerUrl: input.accountAbstraction.bundlerUrl,\n paymasterUrl: input.accountAbstraction.paymasterUrl,\n entryPoint: input.accountAbstraction.entryPoint,\n safe: input.accountAbstraction.safe,\n contracts: input.contracts,\n }),\n ),\n );\n}\n\n/**\n * Creates a complete SDK environment configuration from entrypoint and contract settings.\n */\nexport function createPolyesterEnvironment(\n params: CreatePolyesterEnvironmentParams,\n): PolyesterEnvironment {\n requireObject(params, \"Environment configuration\");\n requireNonEmptyString(params.name, \"name\");\n requireObject(params.accountAbstraction, \"accountAbstraction\");\n requireObject(params.contracts, \"contracts\");\n const apiUrl = normalizeUrl(params.apiUrl, \"apiUrl\", [\"https:\", \"http:\"]);\n const websocketUrl = normalizeUrl(params.websocketUrl, \"websocketUrl\", [\"wss:\", \"ws:\"]);\n const rpcUrl = normalizeUrl(params.rpcUrl, \"rpcUrl\", [\"https:\", \"http:\"]);\n const bundlerUrl = normalizeUrl(params.accountAbstraction.bundlerUrl, \"bundlerUrl\", [\n \"https:\",\n \"http:\",\n ]);\n const paymasterUrl = normalizeUrl(params.accountAbstraction.paymasterUrl, \"paymasterUrl\", [\n \"https:\",\n \"http:\",\n ]);\n const chain = normalizeChain(params.chain, rpcUrl);\n const accountAbstraction = Object.freeze({\n bundlerUrl,\n paymasterUrl,\n entryPoint: normalizeEntryPoint(params.accountAbstraction.entryPoint),\n safe: normalizeSafeConfig(params.accountAbstraction.safe),\n });\n const contracts = Object.freeze({\n tradingGatewayAddress: normalizeAddress(\n params.contracts.tradingGatewayAddress,\n \"contracts.tradingGatewayAddress\",\n ),\n });\n const fingerprint = environmentFingerprint({\n apiUrl,\n websocketUrl,\n rpcUrl,\n chainId: chain.id,\n accountAbstraction,\n contracts,\n });\n\n return Object.freeze({\n name: params.name,\n fingerprint,\n apiUrl,\n websocketUrl,\n rpcUrl,\n chain,\n accountAbstraction,\n contracts,\n });\n}\n\n/**\n * Parses a complete environment supplied to a public SDK client constructor.\n */\nexport function parsePolyesterEnvironment(environment: PolyesterEnvironment): PolyesterEnvironment {\n requireObject(environment, \"environment\");\n const parsed = createPolyesterEnvironment(environment);\n if (environment.fingerprint !== parsed.fingerprint) {\n throw new ConfigurationError(\n \"environment.fingerprint must match the environment configuration.\",\n );\n }\n return parsed;\n}\n\nexport const POLYESTER_TESTNET_ENVIRONMENT = createPolyesterEnvironment({\n name: \"polyester-testnet\",\n apiUrl: \"https://api-devnet.polyester.ai\",\n websocketUrl: \"wss://api-devnet.polyester.ai\",\n rpcUrl: \"https://rpc.polyester.tech\",\n chain: {\n id: 888168,\n name: \"Polyester Chain Testnet\",\n nativeCurrency: {\n decimals: 18,\n name: \"POL\",\n symbol: \"POL\",\n },\n rpcUrls: {\n default: {\n http: [\"https://rpc.polyester.tech\"],\n },\n },\n blockExplorers: {\n default: {\n name: \"Polyester Scan\",\n url: \"https://polyesterscan.com\",\n },\n },\n },\n accountAbstraction: {\n bundlerUrl: \"https://bundler.polyester.tech\",\n paymasterUrl: \"https://paymaster.polyester.tech\",\n entryPoint: {\n address: \"0x59a4B77766509c4507D79eFF8089474eC3daC174\",\n version: \"0.7\",\n },\n safe: {\n version: \"1.4.1\",\n safeModuleSetupAddress: \"0x80791683D9C079A37Debc67EaDdbFcBC6f0FF2bB\",\n safe4337ModuleAddress: \"0x0713FF3d4c1b4f177833a372b1e3cb977540EA11\",\n safeProxyFactoryAddress: \"0xF8F0F649Dd3bFa9095206691E9fb2356c26216dE\",\n safeSingletonAddress: \"0x92abEa238FEA8908c397cE65366ea9278f0AeC7A\",\n multiSendAddress: \"0x70C8a8CcB45a8E2589B0f019374fc923dA34E4c7\",\n multiSendCallOnlyAddress: \"0x375C86a08DA98d1944D7B3c736307A72186CcAf1\",\n },\n },\n contracts: {\n tradingGatewayAddress: \"0xD3fecf5D39131e23b6B0f872cA0a21c8A5a30932\",\n },\n});\n"],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import { AlreadyExistsError, AuthenticationError, ConfigurationError, InternalServerError, MfaEnrollmentRequiredError, MfaLastFactorRequiredError, MfaRequiredError, MfaVerificationError, NetworkError, PermissionError, PolicyInUseError, PolicyLockedError, PolicyScopeMismatchError, PolyesterError, PreconditionFailedError, RateLimitError, RequestError, ResourceNotFoundError, RevisionConflictError, ServiceUnavailableError, SessionElevationRequiredError, StaleQuoteError, StepUpRequiredError, TimeoutError, TransientError, ValidationError, errorFromHttpStatus, isAbortError, normalizeErrorMessage } from "./shared/errors.js";
|
|
2
2
|
import { tsObjToNsString } from "./utils/time.js";
|
|
3
3
|
import { connectErrorToPolyesterError, createErrorMappingInterceptor, toPolyesterError } from "./shared/connect-error-mapping.js";
|
|
4
|
+
import { checksumEvmAddress, evmHexToBytes, evmUtf8ToBytes, evmUtf8ToHex, isEvmAddress, isEvmAddressStrict, keccak256Hex } from "./utils/evm.js";
|
|
5
|
+
import { POLYESTER_TESTNET_ENVIRONMENT, createPolyesterEnvironment } from "./environment.js";
|
|
4
6
|
import { formatConnectError, formatUserFacingError, isPolicyInUseError, isPolicyLockedError, isPolicyScopeMismatchError, isResourceNotFoundError, isRetryableError, isRevisionConflictError } from "./utils/errors.js";
|
|
7
|
+
import { getOrderErrorDetail, isStaleQuoteError } from "./utils/connect-order-errors.js";
|
|
5
8
|
import { compareUnsignedIntegerStrings, shouldApplyReconciliationUpdate } from "./shared/reconciliation.js";
|
|
6
9
|
import { mergeLedgerBalances } from "./services/balances/balances.merge.js";
|
|
7
|
-
import { checksumEvmAddress, evmHexToBytes, evmUtf8ToBytes, evmUtf8ToHex, isEvmAddress, isEvmAddressStrict, keccak256Hex } from "./utils/evm.js";
|
|
8
10
|
import { validateCreateAddressBookEntryInput } from "./services/address-book/address-book.schemas.js";
|
|
9
11
|
import { PolyesterClient } from "./core-client.js";
|
|
10
12
|
import { POLYESTER_AUTH_TOKEN_COOKIE_NAME, POLYESTER_SESSION_COOKIE_NAME } from "./services/auth/cookie-constants.js";
|
|
11
13
|
import { createCookieAuthTokenStorage, createMemoryAuthTokenStorage } from "./services/auth/token-storage.js";
|
|
12
14
|
import { PolyesterBrowserClient } from "./browser-client.js";
|
|
13
15
|
import { PolyesterServerClient, createPolyesterServerClientFromCookies, createPolyesterServerClientFromRequest } from "./server-client.js";
|
|
14
|
-
import { POLYESTER_TESTNET_ENVIRONMENT, createPolyesterEnvironment } from "./environment.js";
|
|
15
16
|
import { isFreshStepUpRequiredError, isMfaEnrollmentRequiredError, isMfaLastFactorRequiredError, isSessionElevationRequiredError } from "./utils/connect-mfa-errors.js";
|
|
16
|
-
import { getOrderErrorDetail, isStaleQuoteError } from "./utils/connect-order-errors.js";
|
|
17
17
|
import { columnarTimestampSecAt, expandColumnarTimestampsSec } from "./utils/columnar-time.js";
|
|
18
18
|
export { AlreadyExistsError, AuthenticationError, ConfigurationError, InternalServerError, MfaEnrollmentRequiredError, MfaLastFactorRequiredError, MfaRequiredError, MfaVerificationError, NetworkError, POLYESTER_AUTH_TOKEN_COOKIE_NAME, POLYESTER_SESSION_COOKIE_NAME, POLYESTER_TESTNET_ENVIRONMENT, PermissionError, PolicyInUseError, PolicyLockedError, PolicyScopeMismatchError, PolyesterBrowserClient, PolyesterClient, PolyesterError, PolyesterServerClient, PreconditionFailedError, RateLimitError, RequestError, ResourceNotFoundError, RevisionConflictError, ServiceUnavailableError, SessionElevationRequiredError, StaleQuoteError, StepUpRequiredError, TimeoutError, TransientError, ValidationError, checksumEvmAddress, columnarTimestampSecAt, compareUnsignedIntegerStrings, connectErrorToPolyesterError, createCookieAuthTokenStorage, createErrorMappingInterceptor, createMemoryAuthTokenStorage, createPolyesterEnvironment, createPolyesterServerClientFromCookies, createPolyesterServerClientFromRequest, errorFromHttpStatus, evmHexToBytes, evmUtf8ToBytes, evmUtf8ToHex, expandColumnarTimestampsSec, formatConnectError, formatUserFacingError, getOrderErrorDetail, isAbortError, isEvmAddress, isEvmAddressStrict, isFreshStepUpRequiredError, isMfaEnrollmentRequiredError, isMfaLastFactorRequiredError, isPolicyInUseError, isPolicyLockedError, isPolicyScopeMismatchError, isResourceNotFoundError, isRetryableError, isRevisionConflictError, isSessionElevationRequiredError, isStaleQuoteError, keccak256Hex, mergeLedgerBalances, normalizeErrorMessage, shouldApplyReconciliationUpdate, tsObjToNsString as timestampToNanoseconds, toPolyesterError, validateCreateAddressBookEntryInput };
|
package/dist/realtime/client.js
CHANGED
|
@@ -293,10 +293,21 @@ var RealtimeClient = class {
|
|
|
293
293
|
} catch {}
|
|
294
294
|
}
|
|
295
295
|
/**
|
|
296
|
-
* Subscribes to a realtime channel and returns an unsubscribe function.
|
|
296
|
+
* Subscribes to a realtime channel and returns an unsubscribe function. Missing
|
|
297
|
+
* authentication is reported to `onError`, or thrown synchronously when no error
|
|
298
|
+
* observer is provided.
|
|
297
299
|
*/
|
|
298
300
|
subscribe(channel, handlers) {
|
|
299
|
-
|
|
301
|
+
let shared;
|
|
302
|
+
try {
|
|
303
|
+
shared = this.#getOrCreateSubscription(channel);
|
|
304
|
+
} catch (error) {
|
|
305
|
+
if (!(error instanceof AuthenticationError)) throw error;
|
|
306
|
+
if (!handlers.onError) throw error;
|
|
307
|
+
const ctx = createSdkSubscriptionErrorContext(channel, "auth", error);
|
|
308
|
+
queueMicrotask(() => this.#callErrorHandler(handlers.onError, ctx));
|
|
309
|
+
return () => {};
|
|
310
|
+
}
|
|
300
311
|
shared.consumers++;
|
|
301
312
|
const publicationHandler = handlers.onPublication;
|
|
302
313
|
const errorHandler = handlers.onError;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","names":["#config","#getAuthHeaders","#sharedSubs","#channelKind","#emitSubscriptionError","#publicClient","#connectionHandlers","#privateClient","#emitConnectionTokenError","#createPublicClient","#hasAuth","#createPrivateClient","#assertChannelAuth","#ensurePrivateClient","#ensurePublicClient","#attachSubscriptionNow","#attachSubscriptionWhenLoaded","#ensureClientForChannel","#subscriptionOpts","#pendingTeardowns","#attachSubscription","#callErrorHandler","#disconnectClientIfIdle","#hasChannelsForKind","#teardownSubscription","#getOrCreateSubscription","#callConsumerHandler","#disconnect","#disconnectPrivate"],"sources":["../../src/realtime/client.ts"],"sourcesContent":["import { fromBinary, type DescMessage, type MessageShape } from \"@bufbuild/protobuf\";\nimport type {\n Centrifuge,\n SubscriptionErrorContext,\n PublicationContext,\n Subscription,\n} from \"centrifuge/build/protobuf\";\nimport type * as CentrifugeModule from \"centrifuge/build/protobuf\";\nimport {\n createSdkSubscriptionErrorContext,\n fromCentrifugeSubscriptionError,\n type SdkSubscriptionErrorContext,\n} from \"../shared/subscription-errors.js\";\nimport { AuthenticationError, errorFromHttpStatus, InternalServerError } from \"../shared/errors.js\";\nimport { makeFetch } from \"../shared/transports.js\";\nimport { decodeProtoFrame } from \"../utils/streams.js\";\nimport type { ConnectChannelParams, PolyesterRealtime, SubscribeHandlers } from \"./types.js\";\n\nconst realtimeFetch = makeFetch();\n\ntype CentrifugeCtor = typeof CentrifugeModule.Centrifuge;\n\n// Centrifuge's protobuf build embeds the protobuf.js runtime (~300 KB minified).\n// Loading it lazily keeps it out of the eager module graph on both the server\n// (Cloudflare isolate cold start — SSR never opens a websocket) and the client\n// app shell; it is only fetched when the first subscription attaches.\nlet centrifugeCtorPromise: Promise<CentrifugeCtor> | null = null;\nlet loadedCentrifugeCtor: CentrifugeCtor | null = null;\nexport function __setRealtimeCentrifugeForTests(Centrifuge: CentrifugeCtor | null): void {\n loadedCentrifugeCtor = Centrifuge;\n centrifugeCtorPromise = Centrifuge ? Promise.resolve(Centrifuge) : null;\n}\n\nfunction loadCentrifuge(): Promise<CentrifugeCtor> {\n if ((import.meta as { env?: { SSR?: boolean } }).env?.SSR) {\n return Promise.reject(new Error(\"Realtime subscriptions are browser-only during SSR.\"));\n }\n\n centrifugeCtorPromise ??= import(\"centrifuge/build/protobuf\").then((mod) => {\n loadedCentrifugeCtor = mod.Centrifuge;\n return mod.Centrifuge;\n });\n return centrifugeCtorPromise;\n}\n\nexport interface RealtimeAuthRequest {\n url: string | URL;\n method: string;\n}\n\nexport interface RealtimeConfig {\n wsUrl: string;\n tokenEndpoint: string;\n subscribeEndpoint: string;\n getAuthHeaders?: (request: RealtimeAuthRequest) => Promise<HeadersInit> | HeadersInit;\n hasAuth?: () => boolean;\n}\n\ntype ResolvedRealtimeConfig = Pick<\n RealtimeConfig,\n \"wsUrl\" | \"tokenEndpoint\" | \"subscribeEndpoint\"\n> & {\n getAuthHeaders: (request: RealtimeAuthRequest) => Promise<HeadersInit> | HeadersInit;\n hasAuth: () => boolean;\n};\n\nexport type { ConnectChannelParams, PolyesterRealtime, SubscribeHandlers } from \"./types.js\";\n\ntype ConnectionHandler = { onConnected?: () => void; onDisconnected?: () => void };\ntype PublicationHandler<T = unknown> = (data: T) => void;\ntype ErrorHandler = (ctx: SdkSubscriptionErrorContext) => void;\ntype RealtimeClientKind = \"public\" | \"private\";\n\ninterface SharedSubscription {\n channel: string;\n sub: Subscription | null;\n client: Centrifuge | null;\n attachmentEpoch: number;\n consumers: number;\n subscriptionEpoch: number;\n publicationHandlers: Set<PublicationHandler>;\n subscribedHandlers: Set<(epoch: number) => void>;\n unsubscribedHandlers: Set<() => void>;\n errorHandlers: Set<ErrorHandler>;\n}\n\n/**\n * Shared Centrifuge realtime client that multiplexes public and private protobuf subscriptions across SDK services.\n */\nexport class RealtimeClient implements PolyesterRealtime {\n #publicClient: Centrifuge | null = null;\n #privateClient: Centrifuge | null = null;\n #connectionHandlers = new Set<ConnectionHandler>();\n #sharedSubs = new Map<string, SharedSubscription>();\n #pendingTeardowns = new Map<string, SharedSubscription>();\n readonly #config: ResolvedRealtimeConfig;\n\n constructor(config: RealtimeConfig) {\n this.#config = {\n wsUrl: config.wsUrl,\n tokenEndpoint: config.tokenEndpoint,\n subscribeEndpoint: config.subscribeEndpoint,\n getAuthHeaders: config.getAuthHeaders ?? (() => ({})),\n hasAuth: config.hasAuth ?? (() => false),\n };\n }\n\n async #getAuthHeaders(request: RealtimeAuthRequest): Promise<HeadersInit> {\n return this.#config.getAuthHeaders(request);\n }\n\n #emitSubscriptionError(shared: SharedSubscription, type: string, error: unknown): void {\n const ctx = createSdkSubscriptionErrorContext(shared.channel, type, error);\n for (const handler of shared.errorHandlers) {\n handler(ctx);\n }\n }\n\n #emitConnectionTokenError(error: unknown): void {\n for (const shared of this.#sharedSubs.values()) {\n if (this.#channelKind(shared.channel) === \"private\") {\n this.#emitSubscriptionError(shared, \"connection_token\", error);\n }\n }\n }\n\n #subscriptionOpts(shared: SharedSubscription, attachmentEpoch: number) {\n if (this.#channelKind(shared.channel) !== \"private\") return undefined;\n return {\n getToken: async () => {\n try {\n const url = new URL(this.#config.subscribeEndpoint);\n url.searchParams.set(\"channel\", shared.channel);\n const headers = await this.#getAuthHeaders({ url, method: \"GET\" });\n const res = await realtimeFetch(url, { headers });\n if (!res.ok) {\n throw errorFromHttpStatus(\n res.status,\n `Failed to fetch subscription token: ${res.status}`,\n );\n }\n const json = (await res.json()) as { token?: string };\n if (!json?.token) {\n throw new InternalServerError(\"Subscription token response had no token\");\n }\n return json.token;\n } catch (error) {\n if (shared.attachmentEpoch === attachmentEpoch) {\n this.#emitSubscriptionError(shared, \"subscription_token\", error);\n }\n throw error;\n }\n },\n };\n }\n\n #hasAuth(): boolean {\n return this.#config.hasAuth();\n }\n\n #channelKind(channel: string): RealtimeClientKind {\n return channel.startsWith(\"private:\") ? \"private\" : \"public\";\n }\n\n #createPublicClient(Centrifuge: CentrifugeCtor): Centrifuge {\n const client = new Centrifuge(this.#config.wsUrl);\n this.#publicClient = client;\n\n client.on(\"connected\", () => {\n if (this.#publicClient !== client) return;\n for (const h of this.#connectionHandlers) h.onConnected?.();\n });\n client.on(\"disconnected\", () => {\n if (this.#publicClient !== client) return;\n for (const h of this.#connectionHandlers) h.onDisconnected?.();\n });\n\n client.connect();\n return client;\n }\n\n #createPrivateClient(Centrifuge: CentrifugeCtor): Centrifuge {\n let client: Centrifuge;\n const opts = {\n getToken: async () => {\n try {\n const headers = await this.#getAuthHeaders({\n url: this.#config.tokenEndpoint,\n method: \"GET\",\n });\n const res = await realtimeFetch(this.#config.tokenEndpoint, {\n headers,\n });\n if (!res.ok) {\n throw errorFromHttpStatus(\n res.status,\n `Failed to fetch connection token: ${res.status}`,\n );\n }\n const json = (await res.json()) as { token?: string };\n if (!json?.token) {\n throw new InternalServerError(\"Connection token response had no token\");\n }\n return json.token;\n } catch (error) {\n if (this.#privateClient === client) {\n this.#emitConnectionTokenError(error);\n }\n throw error;\n }\n },\n };\n\n client = new Centrifuge(this.#config.wsUrl, opts);\n this.#privateClient = client;\n\n client.on(\"connected\", () => {\n if (this.#privateClient !== client) return;\n for (const h of this.#connectionHandlers) h.onConnected?.();\n });\n client.on(\"disconnected\", () => {\n if (this.#privateClient !== client) return;\n for (const h of this.#connectionHandlers) h.onDisconnected?.();\n });\n\n client.connect();\n return client;\n }\n\n #ensurePublicClient(Centrifuge: CentrifugeCtor): Centrifuge {\n return this.#publicClient ?? this.#createPublicClient(Centrifuge);\n }\n\n #ensurePrivateClient(Centrifuge: CentrifugeCtor): Centrifuge {\n if (!this.#hasAuth()) {\n throw new AuthenticationError(\n \"Cannot create authenticated realtime client without authentication\",\n );\n }\n return this.#privateClient ?? this.#createPrivateClient(Centrifuge);\n }\n\n #assertChannelAuth(channel: string): void {\n if (this.#channelKind(channel) === \"private\" && !this.#hasAuth()) {\n throw new AuthenticationError(\n `Cannot subscribe to private channel \"${channel}\" without authentication`,\n );\n }\n }\n\n #ensureClientForChannel(Centrifuge: CentrifugeCtor, channel: string): Centrifuge {\n this.#assertChannelAuth(channel);\n if (this.#channelKind(channel) === \"private\") {\n return this.#ensurePrivateClient(Centrifuge);\n }\n\n return this.#ensurePublicClient(Centrifuge);\n }\n\n #attachSubscription(shared: SharedSubscription): void {\n if (shared.sub) return;\n\n // Auth failures must surface synchronously to subscribe() callers, as\n // they did when centrifuge was imported statically.\n this.#assertChannelAuth(shared.channel);\n\n const attachmentEpoch = shared.attachmentEpoch + 1;\n shared.attachmentEpoch = attachmentEpoch;\n\n // Once the transport module is loaded, attachment stays fully\n // synchronous — only the very first attach pays the dynamic import.\n if (loadedCentrifugeCtor) {\n this.#attachSubscriptionNow(loadedCentrifugeCtor, shared, attachmentEpoch);\n return;\n }\n void this.#attachSubscriptionWhenLoaded(shared, attachmentEpoch);\n }\n\n async #attachSubscriptionWhenLoaded(\n shared: SharedSubscription,\n attachmentEpoch: number,\n ): Promise<void> {\n let Centrifuge: CentrifugeCtor;\n try {\n Centrifuge = await loadCentrifuge();\n } catch (error) {\n if (shared.attachmentEpoch !== attachmentEpoch) return;\n if (this.#sharedSubs.get(shared.channel) === shared) {\n this.#sharedSubs.delete(shared.channel);\n }\n this.#emitSubscriptionError(shared, \"transport_load\", error);\n return;\n }\n\n // The subscription may have been torn down or re-attached while the\n // transport module was loading.\n if (shared.attachmentEpoch !== attachmentEpoch || shared.sub) return;\n if (this.#sharedSubs.get(shared.channel) !== shared) return;\n\n try {\n this.#attachSubscriptionNow(Centrifuge, shared, attachmentEpoch);\n } catch (error) {\n this.#sharedSubs.delete(shared.channel);\n this.#emitSubscriptionError(shared, \"auth\", error);\n }\n }\n\n #attachSubscriptionNow(\n Centrifuge: CentrifugeCtor,\n shared: SharedSubscription,\n attachmentEpoch: number,\n ): void {\n const client = this.#ensureClientForChannel(Centrifuge, shared.channel);\n\n const sub = client.newSubscription(\n shared.channel,\n this.#subscriptionOpts(shared, attachmentEpoch),\n );\n shared.sub = sub;\n shared.client = client;\n\n sub.on(\"publication\", (ctx: PublicationContext) => {\n if (shared.sub !== sub || shared.attachmentEpoch !== attachmentEpoch) return;\n for (const handler of shared.publicationHandlers) handler(ctx.data);\n });\n sub.on(\"subscribed\", () => {\n if (shared.sub !== sub || shared.attachmentEpoch !== attachmentEpoch) return;\n const subscriptionEpoch = ++shared.subscriptionEpoch;\n for (const handler of shared.subscribedHandlers) handler(subscriptionEpoch);\n });\n sub.on(\"unsubscribed\", () => {\n if (shared.sub !== sub || shared.attachmentEpoch !== attachmentEpoch) return;\n for (const handler of shared.unsubscribedHandlers) handler();\n });\n sub.on(\"error\", (ctx: SubscriptionErrorContext) => {\n if (shared.sub !== sub || shared.attachmentEpoch !== attachmentEpoch) return;\n const sdkCtx = fromCentrifugeSubscriptionError(ctx);\n for (const handler of shared.errorHandlers) handler(sdkCtx);\n });\n\n sub.subscribe();\n }\n\n #getOrCreateSubscription(channel: string): SharedSubscription {\n const existing = this.#sharedSubs.get(channel);\n if (existing) return existing;\n\n const pending = this.#pendingTeardowns.get(channel);\n if (pending) {\n this.#pendingTeardowns.delete(channel);\n this.#sharedSubs.set(channel, pending);\n if (!pending.sub) {\n this.#attachSubscription(pending);\n } else if (pending.sub.state !== \"subscribed\") {\n pending.sub.subscribe();\n }\n return pending;\n }\n\n const shared: SharedSubscription = {\n channel,\n sub: null,\n client: null,\n attachmentEpoch: 0,\n consumers: 0,\n subscriptionEpoch: 0,\n publicationHandlers: new Set(),\n subscribedHandlers: new Set(),\n unsubscribedHandlers: new Set(),\n errorHandlers: new Set(),\n };\n\n this.#sharedSubs.set(channel, shared);\n try {\n this.#attachSubscription(shared);\n } catch (error) {\n this.#sharedSubs.delete(channel);\n throw error;\n }\n return shared;\n }\n\n #callErrorHandler(handler: ErrorHandler | undefined, ctx: SdkSubscriptionErrorContext): void {\n if (!handler) return;\n\n try {\n handler(ctx);\n } catch {\n // Keep error reporting isolated from other subscription consumers.\n }\n }\n\n #callConsumerHandler(\n channel: string,\n type: string,\n handler: () => void,\n onError?: ErrorHandler,\n ): void {\n try {\n handler();\n } catch (error) {\n this.#callErrorHandler(\n onError,\n createSdkSubscriptionErrorContext(channel, type, error),\n );\n }\n }\n\n #teardownSubscription(shared: SharedSubscription): void {\n const sub = shared.sub;\n const client = shared.client;\n const kind = this.#channelKind(shared.channel);\n shared.sub = null;\n shared.client = null;\n shared.attachmentEpoch++;\n if (!sub) return;\n\n try {\n if (sub.state !== \"unsubscribed\") {\n sub.unsubscribe();\n }\n } catch {\n // noop\n }\n try {\n client?.removeSubscription?.(sub);\n } catch {\n // noop\n }\n this.#disconnectClientIfIdle(kind);\n }\n\n #hasChannelsForKind(kind: RealtimeClientKind): boolean {\n for (const shared of this.#sharedSubs.values()) {\n if (this.#channelKind(shared.channel) === kind) return true;\n }\n for (const shared of this.#pendingTeardowns.values()) {\n if (this.#channelKind(shared.channel) === kind) return true;\n }\n return false;\n }\n\n #disconnectClientIfIdle(kind: RealtimeClientKind): void {\n if (this.#hasChannelsForKind(kind)) return;\n\n const client = kind === \"private\" ? this.#privateClient : this.#publicClient;\n if (kind === \"private\") {\n this.#privateClient = null;\n } else {\n this.#publicClient = null;\n }\n\n try {\n client?.disconnect();\n } catch {\n // noop\n }\n }\n\n #disconnect(): void {\n const publicClient = this.#publicClient;\n const privateClient = this.#privateClient;\n\n this.#pendingTeardowns.clear();\n this.#sharedSubs.clear();\n this.#publicClient = null;\n this.#privateClient = null;\n\n try {\n publicClient?.disconnect();\n } catch {\n // noop\n }\n try {\n privateClient?.disconnect();\n } catch {\n // noop\n }\n this.#connectionHandlers.clear();\n }\n\n #disconnectPrivate(): void {\n const privateClient = this.#privateClient;\n this.#privateClient = null;\n\n for (const [channel, shared] of this.#sharedSubs) {\n if (this.#channelKind(channel) !== \"private\") continue;\n this.#sharedSubs.delete(channel);\n this.#teardownSubscription(shared);\n }\n for (const [channel, shared] of this.#pendingTeardowns) {\n if (this.#channelKind(channel) !== \"private\") continue;\n this.#pendingTeardowns.delete(channel);\n this.#teardownSubscription(shared);\n }\n\n try {\n privateClient?.disconnect();\n } catch {\n // noop\n }\n }\n\n /**\n * Subscribes to a realtime channel and returns an unsubscribe function.\n */\n subscribe<T>(channel: string, handlers: SubscribeHandlers<T>): () => void {\n const shared = this.#getOrCreateSubscription(channel);\n shared.consumers++;\n\n const publicationHandler = handlers.onPublication;\n const errorHandler = handlers.onError;\n const subscribedHandler = handlers.onSubscribed;\n const unsubscribedHandler = handlers.onUnsubscribed;\n\n const onError: ErrorHandler | undefined = errorHandler\n ? (ctx) => this.#callErrorHandler(errorHandler, ctx)\n : undefined;\n const onPub: PublicationHandler = (data) => {\n this.#callConsumerHandler(\n channel,\n \"publication_handler\",\n () => publicationHandler(data as T),\n onError,\n );\n };\n let lastSubscribedEpoch = -1;\n const onSubscribed = subscribedHandler\n ? (subscriptionEpoch: number) => {\n if (subscriptionEpoch <= lastSubscribedEpoch) return;\n lastSubscribedEpoch = subscriptionEpoch;\n this.#callConsumerHandler(\n channel,\n \"subscribed_handler\",\n subscribedHandler,\n onError,\n );\n }\n : undefined;\n const onUnsubscribed = unsubscribedHandler\n ? () =>\n this.#callConsumerHandler(\n channel,\n \"unsubscribed_handler\",\n unsubscribedHandler,\n onError,\n )\n : undefined;\n\n shared.publicationHandlers.add(onPub);\n\n if (onSubscribed) shared.subscribedHandlers.add(onSubscribed);\n if (onUnsubscribed) shared.unsubscribedHandlers.add(onUnsubscribed);\n if (onError) shared.errorHandlers.add(onError);\n\n let closed = false;\n if (onSubscribed && shared.sub?.state === \"subscribed\") {\n const subscriptionEpoch = shared.subscriptionEpoch;\n queueMicrotask(() => {\n if (closed || shared.sub?.state !== \"subscribed\") return;\n onSubscribed(subscriptionEpoch);\n });\n }\n\n return () => {\n if (closed) return;\n closed = true;\n\n shared.publicationHandlers.delete(onPub);\n if (onSubscribed) shared.subscribedHandlers.delete(onSubscribed);\n if (onUnsubscribed) shared.unsubscribedHandlers.delete(onUnsubscribed);\n if (onError) shared.errorHandlers.delete(onError);\n\n shared.consumers--;\n if (shared.consumers <= 0) {\n const currentShared = this.#sharedSubs.get(channel);\n if (currentShared !== shared) return;\n\n this.#sharedSubs.delete(channel);\n this.#pendingTeardowns.set(channel, shared);\n\n queueMicrotask(() => {\n if (this.#pendingTeardowns.get(channel) !== shared) return;\n this.#pendingTeardowns.delete(channel);\n\n this.#teardownSubscription(shared);\n\n if (this.#sharedSubs.size === 0 && this.#pendingTeardowns.size === 0) {\n this.#disconnect();\n }\n });\n }\n };\n }\n\n /**\n * Connects to a realtime channel with a custom message decoder.\n */\n connectChannel<T extends DescMessage>(params: ConnectChannelParams<T>): () => void {\n return this.subscribe<Uint8Array>(params.channel, {\n onPublication: (data) => {\n let decoded: MessageShape<T>;\n try {\n decoded = fromBinary(params.schema, data);\n } catch (error) {\n this.#callErrorHandler(\n params.onError,\n createSdkSubscriptionErrorContext(params.channel, \"decode\", error),\n );\n return;\n }\n params.onPublication(decoded);\n },\n onSubscribed: params.onConnected,\n onUnsubscribed: params.onDisconnected,\n onError: params.onError,\n });\n }\n\n /**\n * Connects to a realtime channel that emits protobuf messages.\n */\n connectProtoChannel<T extends DescMessage>(params: ConnectChannelParams<T>): () => void {\n return this.subscribe<Uint8Array | MessageShape<T>>(params.channel, {\n onPublication: (data) => {\n let msg: MessageShape<T> | null;\n try {\n msg = decodeProtoFrame(params.schema, data);\n } catch (error) {\n this.#callErrorHandler(\n params.onError,\n createSdkSubscriptionErrorContext(params.channel, \"decode\", error),\n );\n return;\n }\n if (!msg) {\n this.#callErrorHandler(\n params.onError,\n createSdkSubscriptionErrorContext(\n params.channel,\n \"decode\",\n \"Unable to decode protobuf frame\",\n ),\n );\n return;\n }\n params.onPublication(msg);\n },\n onSubscribed: params.onConnected,\n onUnsubscribed: params.onDisconnected,\n onError: params.onError,\n });\n }\n\n /**\n * Disconnects the realtime client from all active channels.\n */\n disconnect(): void {\n this.#disconnect();\n }\n\n /**\n * Disconnects authenticated realtime state without touching public channels.\n */\n disconnectPrivate(): void {\n this.#disconnectPrivate();\n }\n\n get isConnected(): boolean {\n return this.#publicClient !== null || this.#privateClient !== null;\n }\n\n get activeChannels(): number {\n return this.#sharedSubs.size;\n }\n\n get totalConsumers(): number {\n let total = 0;\n for (const shared of this.#sharedSubs.values()) {\n total += shared.consumers;\n }\n return total;\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"client.js","names":["#config","#getAuthHeaders","#sharedSubs","#channelKind","#emitSubscriptionError","#publicClient","#connectionHandlers","#privateClient","#emitConnectionTokenError","#createPublicClient","#hasAuth","#createPrivateClient","#assertChannelAuth","#ensurePrivateClient","#ensurePublicClient","#attachSubscriptionNow","#attachSubscriptionWhenLoaded","#ensureClientForChannel","#subscriptionOpts","#pendingTeardowns","#attachSubscription","#callErrorHandler","#disconnectClientIfIdle","#hasChannelsForKind","#teardownSubscription","#getOrCreateSubscription","#callConsumerHandler","#disconnect","#disconnectPrivate"],"sources":["../../src/realtime/client.ts"],"sourcesContent":["import { fromBinary, type DescMessage, type MessageShape } from \"@bufbuild/protobuf\";\nimport type {\n Centrifuge,\n SubscriptionErrorContext,\n PublicationContext,\n Subscription,\n} from \"centrifuge/build/protobuf\";\nimport type * as CentrifugeModule from \"centrifuge/build/protobuf\";\nimport {\n createSdkSubscriptionErrorContext,\n fromCentrifugeSubscriptionError,\n type SdkSubscriptionErrorContext,\n} from \"../shared/subscription-errors.js\";\nimport { AuthenticationError, errorFromHttpStatus, InternalServerError } from \"../shared/errors.js\";\nimport { makeFetch } from \"../shared/transports.js\";\nimport { decodeProtoFrame } from \"../utils/streams.js\";\nimport type { ConnectChannelParams, PolyesterRealtime, SubscribeHandlers } from \"./types.js\";\n\nconst realtimeFetch = makeFetch();\n\ntype CentrifugeCtor = typeof CentrifugeModule.Centrifuge;\n\n// Centrifuge's protobuf build embeds the protobuf.js runtime (~300 KB minified).\n// Loading it lazily keeps it out of the eager module graph on both the server\n// (Cloudflare isolate cold start — SSR never opens a websocket) and the client\n// app shell; it is only fetched when the first subscription attaches.\nlet centrifugeCtorPromise: Promise<CentrifugeCtor> | null = null;\nlet loadedCentrifugeCtor: CentrifugeCtor | null = null;\nexport function __setRealtimeCentrifugeForTests(Centrifuge: CentrifugeCtor | null): void {\n loadedCentrifugeCtor = Centrifuge;\n centrifugeCtorPromise = Centrifuge ? Promise.resolve(Centrifuge) : null;\n}\n\nfunction loadCentrifuge(): Promise<CentrifugeCtor> {\n if ((import.meta as { env?: { SSR?: boolean } }).env?.SSR) {\n return Promise.reject(new Error(\"Realtime subscriptions are browser-only during SSR.\"));\n }\n\n centrifugeCtorPromise ??= import(\"centrifuge/build/protobuf\").then((mod) => {\n loadedCentrifugeCtor = mod.Centrifuge;\n return mod.Centrifuge;\n });\n return centrifugeCtorPromise;\n}\n\nexport interface RealtimeAuthRequest {\n url: string | URL;\n method: string;\n}\n\nexport interface RealtimeConfig {\n wsUrl: string;\n tokenEndpoint: string;\n subscribeEndpoint: string;\n getAuthHeaders?: (request: RealtimeAuthRequest) => Promise<HeadersInit> | HeadersInit;\n hasAuth?: () => boolean;\n}\n\ntype ResolvedRealtimeConfig = Pick<\n RealtimeConfig,\n \"wsUrl\" | \"tokenEndpoint\" | \"subscribeEndpoint\"\n> & {\n getAuthHeaders: (request: RealtimeAuthRequest) => Promise<HeadersInit> | HeadersInit;\n hasAuth: () => boolean;\n};\n\nexport type { ConnectChannelParams, PolyesterRealtime, SubscribeHandlers } from \"./types.js\";\n\ntype ConnectionHandler = { onConnected?: () => void; onDisconnected?: () => void };\ntype PublicationHandler<T = unknown> = (data: T) => void;\ntype ErrorHandler = (ctx: SdkSubscriptionErrorContext) => void;\ntype RealtimeClientKind = \"public\" | \"private\";\n\ninterface SharedSubscription {\n channel: string;\n sub: Subscription | null;\n client: Centrifuge | null;\n attachmentEpoch: number;\n consumers: number;\n subscriptionEpoch: number;\n publicationHandlers: Set<PublicationHandler>;\n subscribedHandlers: Set<(epoch: number) => void>;\n unsubscribedHandlers: Set<() => void>;\n errorHandlers: Set<ErrorHandler>;\n}\n\n/**\n * Shared Centrifuge realtime client that multiplexes public and private protobuf subscriptions across SDK services.\n */\nexport class RealtimeClient implements PolyesterRealtime {\n #publicClient: Centrifuge | null = null;\n #privateClient: Centrifuge | null = null;\n #connectionHandlers = new Set<ConnectionHandler>();\n #sharedSubs = new Map<string, SharedSubscription>();\n #pendingTeardowns = new Map<string, SharedSubscription>();\n readonly #config: ResolvedRealtimeConfig;\n\n constructor(config: RealtimeConfig) {\n this.#config = {\n wsUrl: config.wsUrl,\n tokenEndpoint: config.tokenEndpoint,\n subscribeEndpoint: config.subscribeEndpoint,\n getAuthHeaders: config.getAuthHeaders ?? (() => ({})),\n hasAuth: config.hasAuth ?? (() => false),\n };\n }\n\n async #getAuthHeaders(request: RealtimeAuthRequest): Promise<HeadersInit> {\n return this.#config.getAuthHeaders(request);\n }\n\n #emitSubscriptionError(shared: SharedSubscription, type: string, error: unknown): void {\n const ctx = createSdkSubscriptionErrorContext(shared.channel, type, error);\n for (const handler of shared.errorHandlers) {\n handler(ctx);\n }\n }\n\n #emitConnectionTokenError(error: unknown): void {\n for (const shared of this.#sharedSubs.values()) {\n if (this.#channelKind(shared.channel) === \"private\") {\n this.#emitSubscriptionError(shared, \"connection_token\", error);\n }\n }\n }\n\n #subscriptionOpts(shared: SharedSubscription, attachmentEpoch: number) {\n if (this.#channelKind(shared.channel) !== \"private\") return undefined;\n return {\n getToken: async () => {\n try {\n const url = new URL(this.#config.subscribeEndpoint);\n url.searchParams.set(\"channel\", shared.channel);\n const headers = await this.#getAuthHeaders({ url, method: \"GET\" });\n const res = await realtimeFetch(url, { headers });\n if (!res.ok) {\n throw errorFromHttpStatus(\n res.status,\n `Failed to fetch subscription token: ${res.status}`,\n );\n }\n const json = (await res.json()) as { token?: string };\n if (!json?.token) {\n throw new InternalServerError(\"Subscription token response had no token\");\n }\n return json.token;\n } catch (error) {\n if (shared.attachmentEpoch === attachmentEpoch) {\n this.#emitSubscriptionError(shared, \"subscription_token\", error);\n }\n throw error;\n }\n },\n };\n }\n\n #hasAuth(): boolean {\n return this.#config.hasAuth();\n }\n\n #channelKind(channel: string): RealtimeClientKind {\n return channel.startsWith(\"private:\") ? \"private\" : \"public\";\n }\n\n #createPublicClient(Centrifuge: CentrifugeCtor): Centrifuge {\n const client = new Centrifuge(this.#config.wsUrl);\n this.#publicClient = client;\n\n client.on(\"connected\", () => {\n if (this.#publicClient !== client) return;\n for (const h of this.#connectionHandlers) h.onConnected?.();\n });\n client.on(\"disconnected\", () => {\n if (this.#publicClient !== client) return;\n for (const h of this.#connectionHandlers) h.onDisconnected?.();\n });\n\n client.connect();\n return client;\n }\n\n #createPrivateClient(Centrifuge: CentrifugeCtor): Centrifuge {\n let client: Centrifuge;\n const opts = {\n getToken: async () => {\n try {\n const headers = await this.#getAuthHeaders({\n url: this.#config.tokenEndpoint,\n method: \"GET\",\n });\n const res = await realtimeFetch(this.#config.tokenEndpoint, {\n headers,\n });\n if (!res.ok) {\n throw errorFromHttpStatus(\n res.status,\n `Failed to fetch connection token: ${res.status}`,\n );\n }\n const json = (await res.json()) as { token?: string };\n if (!json?.token) {\n throw new InternalServerError(\"Connection token response had no token\");\n }\n return json.token;\n } catch (error) {\n if (this.#privateClient === client) {\n this.#emitConnectionTokenError(error);\n }\n throw error;\n }\n },\n };\n\n client = new Centrifuge(this.#config.wsUrl, opts);\n this.#privateClient = client;\n\n client.on(\"connected\", () => {\n if (this.#privateClient !== client) return;\n for (const h of this.#connectionHandlers) h.onConnected?.();\n });\n client.on(\"disconnected\", () => {\n if (this.#privateClient !== client) return;\n for (const h of this.#connectionHandlers) h.onDisconnected?.();\n });\n\n client.connect();\n return client;\n }\n\n #ensurePublicClient(Centrifuge: CentrifugeCtor): Centrifuge {\n return this.#publicClient ?? this.#createPublicClient(Centrifuge);\n }\n\n #ensurePrivateClient(Centrifuge: CentrifugeCtor): Centrifuge {\n if (!this.#hasAuth()) {\n throw new AuthenticationError(\n \"Cannot create authenticated realtime client without authentication\",\n );\n }\n return this.#privateClient ?? this.#createPrivateClient(Centrifuge);\n }\n\n #assertChannelAuth(channel: string): void {\n if (this.#channelKind(channel) === \"private\" && !this.#hasAuth()) {\n throw new AuthenticationError(\n `Cannot subscribe to private channel \"${channel}\" without authentication`,\n );\n }\n }\n\n #ensureClientForChannel(Centrifuge: CentrifugeCtor, channel: string): Centrifuge {\n this.#assertChannelAuth(channel);\n if (this.#channelKind(channel) === \"private\") {\n return this.#ensurePrivateClient(Centrifuge);\n }\n\n return this.#ensurePublicClient(Centrifuge);\n }\n\n #attachSubscription(shared: SharedSubscription): void {\n if (shared.sub) return;\n\n // Auth failures must surface synchronously to subscribe() callers, as\n // they did when centrifuge was imported statically.\n this.#assertChannelAuth(shared.channel);\n\n const attachmentEpoch = shared.attachmentEpoch + 1;\n shared.attachmentEpoch = attachmentEpoch;\n\n // Once the transport module is loaded, attachment stays fully\n // synchronous — only the very first attach pays the dynamic import.\n if (loadedCentrifugeCtor) {\n this.#attachSubscriptionNow(loadedCentrifugeCtor, shared, attachmentEpoch);\n return;\n }\n void this.#attachSubscriptionWhenLoaded(shared, attachmentEpoch);\n }\n\n async #attachSubscriptionWhenLoaded(\n shared: SharedSubscription,\n attachmentEpoch: number,\n ): Promise<void> {\n let Centrifuge: CentrifugeCtor;\n try {\n Centrifuge = await loadCentrifuge();\n } catch (error) {\n if (shared.attachmentEpoch !== attachmentEpoch) return;\n if (this.#sharedSubs.get(shared.channel) === shared) {\n this.#sharedSubs.delete(shared.channel);\n }\n this.#emitSubscriptionError(shared, \"transport_load\", error);\n return;\n }\n\n // The subscription may have been torn down or re-attached while the\n // transport module was loading.\n if (shared.attachmentEpoch !== attachmentEpoch || shared.sub) return;\n if (this.#sharedSubs.get(shared.channel) !== shared) return;\n\n try {\n this.#attachSubscriptionNow(Centrifuge, shared, attachmentEpoch);\n } catch (error) {\n this.#sharedSubs.delete(shared.channel);\n this.#emitSubscriptionError(shared, \"auth\", error);\n }\n }\n\n #attachSubscriptionNow(\n Centrifuge: CentrifugeCtor,\n shared: SharedSubscription,\n attachmentEpoch: number,\n ): void {\n const client = this.#ensureClientForChannel(Centrifuge, shared.channel);\n\n const sub = client.newSubscription(\n shared.channel,\n this.#subscriptionOpts(shared, attachmentEpoch),\n );\n shared.sub = sub;\n shared.client = client;\n\n sub.on(\"publication\", (ctx: PublicationContext) => {\n if (shared.sub !== sub || shared.attachmentEpoch !== attachmentEpoch) return;\n for (const handler of shared.publicationHandlers) handler(ctx.data);\n });\n sub.on(\"subscribed\", () => {\n if (shared.sub !== sub || shared.attachmentEpoch !== attachmentEpoch) return;\n const subscriptionEpoch = ++shared.subscriptionEpoch;\n for (const handler of shared.subscribedHandlers) handler(subscriptionEpoch);\n });\n sub.on(\"unsubscribed\", () => {\n if (shared.sub !== sub || shared.attachmentEpoch !== attachmentEpoch) return;\n for (const handler of shared.unsubscribedHandlers) handler();\n });\n sub.on(\"error\", (ctx: SubscriptionErrorContext) => {\n if (shared.sub !== sub || shared.attachmentEpoch !== attachmentEpoch) return;\n const sdkCtx = fromCentrifugeSubscriptionError(ctx);\n for (const handler of shared.errorHandlers) handler(sdkCtx);\n });\n\n sub.subscribe();\n }\n\n #getOrCreateSubscription(channel: string): SharedSubscription {\n const existing = this.#sharedSubs.get(channel);\n if (existing) return existing;\n\n const pending = this.#pendingTeardowns.get(channel);\n if (pending) {\n this.#pendingTeardowns.delete(channel);\n this.#sharedSubs.set(channel, pending);\n if (!pending.sub) {\n this.#attachSubscription(pending);\n } else if (pending.sub.state !== \"subscribed\") {\n pending.sub.subscribe();\n }\n return pending;\n }\n\n const shared: SharedSubscription = {\n channel,\n sub: null,\n client: null,\n attachmentEpoch: 0,\n consumers: 0,\n subscriptionEpoch: 0,\n publicationHandlers: new Set(),\n subscribedHandlers: new Set(),\n unsubscribedHandlers: new Set(),\n errorHandlers: new Set(),\n };\n\n this.#sharedSubs.set(channel, shared);\n try {\n this.#attachSubscription(shared);\n } catch (error) {\n this.#sharedSubs.delete(channel);\n throw error;\n }\n return shared;\n }\n\n #callErrorHandler(handler: ErrorHandler | undefined, ctx: SdkSubscriptionErrorContext): void {\n if (!handler) return;\n\n try {\n handler(ctx);\n } catch {\n // Keep error reporting isolated from other subscription consumers.\n }\n }\n\n #callConsumerHandler(\n channel: string,\n type: string,\n handler: () => void,\n onError?: ErrorHandler,\n ): void {\n try {\n handler();\n } catch (error) {\n this.#callErrorHandler(\n onError,\n createSdkSubscriptionErrorContext(channel, type, error),\n );\n }\n }\n\n #teardownSubscription(shared: SharedSubscription): void {\n const sub = shared.sub;\n const client = shared.client;\n const kind = this.#channelKind(shared.channel);\n shared.sub = null;\n shared.client = null;\n shared.attachmentEpoch++;\n if (!sub) return;\n\n try {\n if (sub.state !== \"unsubscribed\") {\n sub.unsubscribe();\n }\n } catch {\n // noop\n }\n try {\n client?.removeSubscription?.(sub);\n } catch {\n // noop\n }\n this.#disconnectClientIfIdle(kind);\n }\n\n #hasChannelsForKind(kind: RealtimeClientKind): boolean {\n for (const shared of this.#sharedSubs.values()) {\n if (this.#channelKind(shared.channel) === kind) return true;\n }\n for (const shared of this.#pendingTeardowns.values()) {\n if (this.#channelKind(shared.channel) === kind) return true;\n }\n return false;\n }\n\n #disconnectClientIfIdle(kind: RealtimeClientKind): void {\n if (this.#hasChannelsForKind(kind)) return;\n\n const client = kind === \"private\" ? this.#privateClient : this.#publicClient;\n if (kind === \"private\") {\n this.#privateClient = null;\n } else {\n this.#publicClient = null;\n }\n\n try {\n client?.disconnect();\n } catch {\n // noop\n }\n }\n\n #disconnect(): void {\n const publicClient = this.#publicClient;\n const privateClient = this.#privateClient;\n\n this.#pendingTeardowns.clear();\n this.#sharedSubs.clear();\n this.#publicClient = null;\n this.#privateClient = null;\n\n try {\n publicClient?.disconnect();\n } catch {\n // noop\n }\n try {\n privateClient?.disconnect();\n } catch {\n // noop\n }\n this.#connectionHandlers.clear();\n }\n\n #disconnectPrivate(): void {\n const privateClient = this.#privateClient;\n this.#privateClient = null;\n\n for (const [channel, shared] of this.#sharedSubs) {\n if (this.#channelKind(channel) !== \"private\") continue;\n this.#sharedSubs.delete(channel);\n this.#teardownSubscription(shared);\n }\n for (const [channel, shared] of this.#pendingTeardowns) {\n if (this.#channelKind(channel) !== \"private\") continue;\n this.#pendingTeardowns.delete(channel);\n this.#teardownSubscription(shared);\n }\n\n try {\n privateClient?.disconnect();\n } catch {\n // noop\n }\n }\n\n /**\n * Subscribes to a realtime channel and returns an unsubscribe function. Missing\n * authentication is reported to `onError`, or thrown synchronously when no error\n * observer is provided.\n */\n subscribe<T>(channel: string, handlers: SubscribeHandlers<T>): () => void {\n let shared: SharedSubscription;\n try {\n shared = this.#getOrCreateSubscription(channel);\n } catch (error) {\n if (!(error instanceof AuthenticationError)) throw error;\n if (!handlers.onError) throw error;\n\n const ctx = createSdkSubscriptionErrorContext(channel, \"auth\", error);\n queueMicrotask(() => this.#callErrorHandler(handlers.onError, ctx));\n return () => {};\n }\n shared.consumers++;\n\n const publicationHandler = handlers.onPublication;\n const errorHandler = handlers.onError;\n const subscribedHandler = handlers.onSubscribed;\n const unsubscribedHandler = handlers.onUnsubscribed;\n\n const onError: ErrorHandler | undefined = errorHandler\n ? (ctx) => this.#callErrorHandler(errorHandler, ctx)\n : undefined;\n const onPub: PublicationHandler = (data) => {\n this.#callConsumerHandler(\n channel,\n \"publication_handler\",\n () => publicationHandler(data as T),\n onError,\n );\n };\n let lastSubscribedEpoch = -1;\n const onSubscribed = subscribedHandler\n ? (subscriptionEpoch: number) => {\n if (subscriptionEpoch <= lastSubscribedEpoch) return;\n lastSubscribedEpoch = subscriptionEpoch;\n this.#callConsumerHandler(\n channel,\n \"subscribed_handler\",\n subscribedHandler,\n onError,\n );\n }\n : undefined;\n const onUnsubscribed = unsubscribedHandler\n ? () =>\n this.#callConsumerHandler(\n channel,\n \"unsubscribed_handler\",\n unsubscribedHandler,\n onError,\n )\n : undefined;\n\n shared.publicationHandlers.add(onPub);\n\n if (onSubscribed) shared.subscribedHandlers.add(onSubscribed);\n if (onUnsubscribed) shared.unsubscribedHandlers.add(onUnsubscribed);\n if (onError) shared.errorHandlers.add(onError);\n\n let closed = false;\n if (onSubscribed && shared.sub?.state === \"subscribed\") {\n const subscriptionEpoch = shared.subscriptionEpoch;\n queueMicrotask(() => {\n if (closed || shared.sub?.state !== \"subscribed\") return;\n onSubscribed(subscriptionEpoch);\n });\n }\n\n return () => {\n if (closed) return;\n closed = true;\n\n shared.publicationHandlers.delete(onPub);\n if (onSubscribed) shared.subscribedHandlers.delete(onSubscribed);\n if (onUnsubscribed) shared.unsubscribedHandlers.delete(onUnsubscribed);\n if (onError) shared.errorHandlers.delete(onError);\n\n shared.consumers--;\n if (shared.consumers <= 0) {\n const currentShared = this.#sharedSubs.get(channel);\n if (currentShared !== shared) return;\n\n this.#sharedSubs.delete(channel);\n this.#pendingTeardowns.set(channel, shared);\n\n queueMicrotask(() => {\n if (this.#pendingTeardowns.get(channel) !== shared) return;\n this.#pendingTeardowns.delete(channel);\n\n this.#teardownSubscription(shared);\n\n if (this.#sharedSubs.size === 0 && this.#pendingTeardowns.size === 0) {\n this.#disconnect();\n }\n });\n }\n };\n }\n\n /**\n * Connects to a realtime channel with a custom message decoder.\n */\n connectChannel<T extends DescMessage>(params: ConnectChannelParams<T>): () => void {\n return this.subscribe<Uint8Array>(params.channel, {\n onPublication: (data) => {\n let decoded: MessageShape<T>;\n try {\n decoded = fromBinary(params.schema, data);\n } catch (error) {\n this.#callErrorHandler(\n params.onError,\n createSdkSubscriptionErrorContext(params.channel, \"decode\", error),\n );\n return;\n }\n params.onPublication(decoded);\n },\n onSubscribed: params.onConnected,\n onUnsubscribed: params.onDisconnected,\n onError: params.onError,\n });\n }\n\n /**\n * Connects to a realtime channel that emits protobuf messages.\n */\n connectProtoChannel<T extends DescMessage>(params: ConnectChannelParams<T>): () => void {\n return this.subscribe<Uint8Array | MessageShape<T>>(params.channel, {\n onPublication: (data) => {\n let msg: MessageShape<T> | null;\n try {\n msg = decodeProtoFrame(params.schema, data);\n } catch (error) {\n this.#callErrorHandler(\n params.onError,\n createSdkSubscriptionErrorContext(params.channel, \"decode\", error),\n );\n return;\n }\n if (!msg) {\n this.#callErrorHandler(\n params.onError,\n createSdkSubscriptionErrorContext(\n params.channel,\n \"decode\",\n \"Unable to decode protobuf frame\",\n ),\n );\n return;\n }\n params.onPublication(msg);\n },\n onSubscribed: params.onConnected,\n onUnsubscribed: params.onDisconnected,\n onError: params.onError,\n });\n }\n\n /**\n * Disconnects the realtime client from all active channels.\n */\n disconnect(): void {\n this.#disconnect();\n }\n\n /**\n * Disconnects authenticated realtime state without touching public channels.\n */\n disconnectPrivate(): void {\n this.#disconnectPrivate();\n }\n\n get isConnected(): boolean {\n return this.#publicClient !== null || this.#privateClient !== null;\n }\n\n get activeChannels(): number {\n return this.#sharedSubs.size;\n }\n\n get totalConsumers(): number {\n let total = 0;\n for (const shared of this.#sharedSubs.values()) {\n total += shared.consumers;\n }\n return total;\n }\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"snapshot-then-stream.js","names":[],"sources":["../../src/realtime/snapshot-then-stream.ts"],"sourcesContent":["import type { DescMessage, MessageShape } from \"@bufbuild/protobuf\";\nimport {\n createSdkSubscriptionErrorContext,\n type SdkSubscriptionErrorContext,\n} from \"../shared/subscription-errors.js\";\nimport type { PolyesterRealtime } from \"./types.js\";\nimport { formatConnectError } from \"../utils/errors.js\";\nimport { isDev } from \"../utils/is-dev.js\";\n\nexport interface SnapshotThenStreamSubscription {\n unsubscribe: () => void;\n refreshSnapshot: () => void;\n isReady: () => boolean;\n isDisposed: () => boolean;\n}\n\nexport interface SnapshotThenStreamInput<TSchema extends DescMessage, TSnapshot, TPublication> {\n realtime: PolyesterRealtime;\n channel: string;\n schema: TSchema;\n maxBufferedPublications?: number;\n bufferPublicationKey?: (publication: TPublication) => PropertyKey;\n snapshotRetry?: {\n maxAttempts: number;\n delayMs: number;\n };\n snapshotFailureMode?: \"wait\" | \"live\";\n snapshotErrorLog?: string;\n fetchSnapshot: () => Promise<TSnapshot>;\n readPublication: (message: MessageShape<TSchema>) => readonly TPublication[];\n applySnapshot: (snapshot: TSnapshot, bufferedPublications: readonly TPublication[]) => void;\n applyLivePublications: (publications: readonly TPublication[]) => void;\n onOpen?: () => void;\n onClose?: () => void;\n onError?: (ctx: SdkSubscriptionErrorContext) => void;\n}\n\n/**\n * Snapshot-then-stream for feed state. By default, the buffer caps at\n * `maxBufferedPublications` and drops the OLDEST publications, which is correct for\n * ephemeral feeds where a later publication supersedes earlier ones. Keyed state can\n * provide `bufferPublicationKey` to retain the latest value for every key without FIFO\n * loss. Entity transitions (orders, triggers, balances, trades) must NOT use this —\n * their ordering contract lives in the app-side `EntityStreamStore`, which buffers\n * unbounded and replays because dropping an event loses a row transition.\n */\nexport function snapshotThenStream<TSchema extends DescMessage, TSnapshot, TPublication>(\n params: SnapshotThenStreamInput<TSchema, TSnapshot, TPublication>,\n): SnapshotThenStreamSubscription {\n const maxBufferedPublications = params.maxBufferedPublications ?? 200;\n let droppedPublications = 0;\n\n let ready = false;\n let disposed = false;\n let refreshGeneration = 0;\n let pendingPublications: TPublication[] = [];\n let retryAttempts = 0;\n let retryTimer: ReturnType<typeof setTimeout> | null = null;\n\n function reportSnapshotError(error: unknown): void {\n if (isDev() && params.snapshotErrorLog) {\n console.error(params.snapshotErrorLog, error);\n }\n params.onError?.(\n createSdkSubscriptionErrorContext(\n params.channel,\n \"snapshot\",\n formatConnectError(error, \"snapshot failed\"),\n ),\n );\n }\n\n function takePendingPublications(): TPublication[] {\n const buffered = pendingPublications;\n pendingPublications = [];\n return buffered;\n }\n\n function applyBufferedAsLive(): void {\n const buffered = takePendingPublications();\n if (buffered.length === 0) return;\n params.applyLivePublications(buffered);\n }\n\n function bufferPublications(publications: readonly TPublication[]): void {\n if (params.bufferPublicationKey) {\n const byKey = new Map<PropertyKey, TPublication>();\n for (const publication of pendingPublications) {\n byKey.set(params.bufferPublicationKey(publication), publication);\n }\n for (const publication of publications) {\n byKey.set(params.bufferPublicationKey(publication), publication);\n }\n pendingPublications = Array.from(byKey.values());\n return;\n }\n\n const next = pendingPublications.concat(publications);\n if (next.length > maxBufferedPublications) {\n droppedPublications += next.length - maxBufferedPublications;\n if (isDev()) {\n console.warn(\n `[snapshot-then-stream] ${params.channel}: buffer cap dropped ${droppedPublications} publication(s) while snapshot in flight`,\n );\n }\n }\n pendingPublications = next.slice(-maxBufferedPublications);\n }\n\n function clearRetryTimer(): void {\n if (retryTimer === null) return;\n clearTimeout(retryTimer);\n retryTimer = null;\n }\n\n function reportBufferedPublicationError(error: unknown): void {\n params.onError?.(\n createSdkSubscriptionErrorContext(params.channel, \"publication_handler\", error),\n );\n }\n\n function scheduleSnapshotRetry(): void {\n const retry = params.snapshotRetry;\n if (!retry || retryAttempts >= retry.maxAttempts || disposed) return;\n\n const delayMs = retry.delayMs * 2 ** retryAttempts;\n retryAttempts++;\n retryTimer = setTimeout(() => {\n retryTimer = null;\n refreshSnapshot(false);\n }, delayMs);\n }\n\n function refreshSnapshot(resetRetries = true): void {\n if (disposed) return;\n clearRetryTimer();\n if (resetRetries) retryAttempts = 0;\n\n const generation = ++refreshGeneration;\n ready = false;\n\n Promise.resolve()\n .then(() => params.fetchSnapshot())\n .then((snapshot) => {\n if (disposed || generation !== refreshGeneration) return;\n\n const buffered = takePendingPublications();\n params.applySnapshot(snapshot, buffered);\n\n if (disposed || generation !== refreshGeneration) return;\n ready = true;\n retryAttempts = 0;\n })\n .catch((error: unknown) => {\n if (disposed || generation !== refreshGeneration) return;\n reportSnapshotError(error);\n if (params.snapshotFailureMode === \"live\") {\n ready = true;\n try {\n applyBufferedAsLive();\n } catch (publicationError) {\n reportBufferedPublicationError(publicationError);\n }\n }\n scheduleSnapshotRetry();\n });\n }\n\n const unsubscribeRealtime = params.realtime.connectProtoChannel({\n channel: params.channel,\n schema: params.schema,\n onPublication: (message) => {\n const publications = params.readPublication(message);\n if (publications.length === 0) return;\n\n if (!ready) {\n bufferPublications(publications);\n return;\n }\n\n params.applyLivePublications(publications);\n },\n onConnected: () => {\n if (disposed) return;\n pendingPublications = [];\n refreshSnapshot();\n params.onOpen?.();\n },\n onDisconnected: () => {\n if (disposed) return;\n clearRetryTimer();\n refreshGeneration++;\n ready = false;\n pendingPublications = [];\n params.onClose?.();\n },\n onError: (ctx) => params.onError?.(ctx),\n });\n\n function unsubscribe(): void {\n disposed = true;\n clearRetryTimer();\n refreshGeneration++;\n pendingPublications = [];\n try {\n unsubscribeRealtime();\n } catch {\n // noop\n }\n }\n\n return {\n unsubscribe,\n refreshSnapshot,\n isReady: () => ready,\n isDisposed: () => disposed,\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"snapshot-then-stream.js","names":[],"sources":["../../src/realtime/snapshot-then-stream.ts"],"sourcesContent":["import type { DescMessage, MessageShape } from \"@bufbuild/protobuf\";\nimport {\n createSdkSubscriptionErrorContext,\n type SdkSubscriptionErrorContext,\n} from \"../shared/subscription-errors.js\";\nimport type { PolyesterRealtime } from \"./types.js\";\nimport { formatConnectError } from \"../utils/errors.js\";\nimport { isDev } from \"../utils/is-dev.js\";\n\nexport interface SnapshotThenStreamSubscription {\n unsubscribe: () => void;\n refreshSnapshot: () => void;\n isReady: () => boolean;\n isDisposed: () => boolean;\n}\n\nexport interface SnapshotThenStreamInput<TSchema extends DescMessage, TSnapshot, TPublication> {\n realtime: PolyesterRealtime;\n channel: string;\n schema: TSchema;\n maxBufferedPublications?: number;\n bufferPublicationKey?: (publication: TPublication) => PropertyKey;\n snapshotRetry?: {\n maxAttempts: number;\n delayMs: number;\n };\n snapshotFailureMode?: \"wait\" | \"live\";\n snapshotErrorLog?: string;\n fetchSnapshot: () => Promise<TSnapshot>;\n readPublication: (message: MessageShape<TSchema>) => readonly TPublication[];\n applySnapshot: (snapshot: TSnapshot, bufferedPublications: readonly TPublication[]) => void;\n applyLivePublications: (publications: readonly TPublication[]) => void;\n onOpen?: () => void;\n onClose?: () => void;\n onError?: (ctx: SdkSubscriptionErrorContext) => void;\n}\n\n/**\n * Snapshot-then-stream for feed state. By default, the buffer caps at\n * `maxBufferedPublications` and drops the OLDEST publications, which is correct for\n * ephemeral feeds where a later publication supersedes earlier ones. Keyed state can\n * provide `bufferPublicationKey` to retain the latest value for every key without FIFO\n * loss. Entity transitions (orders, triggers, balances, trades) must NOT use this —\n * their ordering contract lives in the app-side `EntityStreamStore`, which buffers\n * unbounded and replays because dropping an event loses a row transition.\n */\nexport function snapshotThenStream<TSchema extends DescMessage, TSnapshot, TPublication>(\n params: SnapshotThenStreamInput<TSchema, TSnapshot, TPublication>,\n): SnapshotThenStreamSubscription {\n const maxBufferedPublications = params.maxBufferedPublications ?? 200;\n let droppedPublications = 0;\n\n let ready = false;\n let disposed = false;\n let refreshGeneration = 0;\n let pendingPublications: TPublication[] = [];\n let retryAttempts = 0;\n let retryTimer: ReturnType<typeof setTimeout> | null = null;\n\n function reportSnapshotError(error: unknown): void {\n if (isDev() && params.snapshotErrorLog) {\n console.error(params.snapshotErrorLog, error);\n }\n params.onError?.(\n createSdkSubscriptionErrorContext(\n params.channel,\n \"snapshot\",\n formatConnectError(error, \"snapshot failed\"),\n ),\n );\n }\n\n function takePendingPublications(): TPublication[] {\n const buffered = pendingPublications;\n pendingPublications = [];\n return buffered;\n }\n\n function applyBufferedAsLive(): void {\n const buffered = takePendingPublications();\n if (buffered.length === 0) return;\n params.applyLivePublications(buffered);\n }\n\n function bufferPublications(publications: readonly TPublication[]): void {\n if (params.bufferPublicationKey) {\n const byKey = new Map<PropertyKey, TPublication>();\n for (const publication of pendingPublications) {\n byKey.set(params.bufferPublicationKey(publication), publication);\n }\n for (const publication of publications) {\n byKey.set(params.bufferPublicationKey(publication), publication);\n }\n pendingPublications = Array.from(byKey.values());\n return;\n }\n\n const next = pendingPublications.concat(publications);\n if (next.length > maxBufferedPublications) {\n droppedPublications += next.length - maxBufferedPublications;\n if (isDev()) {\n console.warn(\n `[snapshot-then-stream] ${params.channel}: buffer cap dropped ${droppedPublications} publication(s) while snapshot in flight`,\n );\n }\n }\n pendingPublications = next.slice(-maxBufferedPublications);\n }\n\n function clearRetryTimer(): void {\n if (retryTimer === null) return;\n clearTimeout(retryTimer);\n retryTimer = null;\n }\n\n function reportBufferedPublicationError(error: unknown): void {\n params.onError?.(\n createSdkSubscriptionErrorContext(params.channel, \"publication_handler\", error),\n );\n }\n\n function scheduleSnapshotRetry(): void {\n const retry = params.snapshotRetry;\n if (!retry || retryAttempts >= retry.maxAttempts || disposed) return;\n\n const delayMs = retry.delayMs * 2 ** retryAttempts;\n retryAttempts++;\n retryTimer = setTimeout(() => {\n retryTimer = null;\n refreshSnapshot(false);\n }, delayMs);\n }\n\n function refreshSnapshot(resetRetries = true): void {\n if (disposed) return;\n clearRetryTimer();\n if (resetRetries) retryAttempts = 0;\n\n const generation = ++refreshGeneration;\n ready = false;\n\n Promise.resolve()\n .then(() => params.fetchSnapshot())\n .then((snapshot) => {\n if (disposed || generation !== refreshGeneration) return;\n\n const buffered = takePendingPublications();\n params.applySnapshot(snapshot, buffered);\n\n if (disposed || generation !== refreshGeneration) return;\n ready = true;\n retryAttempts = 0;\n })\n .catch((error: unknown) => {\n if (disposed || generation !== refreshGeneration) return;\n reportSnapshotError(error);\n if (params.snapshotFailureMode === \"live\") {\n ready = true;\n try {\n applyBufferedAsLive();\n } catch (publicationError) {\n reportBufferedPublicationError(publicationError);\n }\n }\n scheduleSnapshotRetry();\n });\n }\n\n const unsubscribeRealtime = params.realtime.connectProtoChannel({\n channel: params.channel,\n schema: params.schema,\n onPublication: (message) => {\n const publications = params.readPublication(message);\n if (publications.length === 0) return;\n\n if (!ready) {\n bufferPublications(publications);\n return;\n }\n\n params.applyLivePublications(publications);\n },\n onConnected: () => {\n if (disposed) return;\n pendingPublications = [];\n refreshSnapshot();\n params.onOpen?.();\n },\n onDisconnected: () => {\n if (disposed) return;\n clearRetryTimer();\n refreshGeneration++;\n ready = false;\n pendingPublications = [];\n params.onClose?.();\n },\n onError: params.onError,\n });\n\n function unsubscribe(): void {\n disposed = true;\n clearRetryTimer();\n refreshGeneration++;\n pendingPublications = [];\n try {\n unsubscribeRealtime();\n } catch {\n // noop\n }\n }\n\n return {\n unsubscribe,\n refreshSnapshot,\n isReady: () => ready,\n isDisposed: () => disposed,\n };\n}\n"],"mappings":"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"}
|
package/dist/realtime/types.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ interface SubscribeHandlers<T> {
|
|
|
5
5
|
onPublication: (data: T) => void;
|
|
6
6
|
onSubscribed?: () => void;
|
|
7
7
|
onUnsubscribed?: () => void;
|
|
8
|
+
/** Observes subscription failures. Missing authentication throws when omitted. */
|
|
8
9
|
onError?: (ctx: SdkSubscriptionErrorContext) => void;
|
|
9
10
|
}
|
|
10
11
|
interface ConnectChannelParams<T extends DescMessage> {
|
|
@@ -13,6 +14,7 @@ interface ConnectChannelParams<T extends DescMessage> {
|
|
|
13
14
|
onPublication: (data: MessageShape<T>) => void;
|
|
14
15
|
onConnected?: () => void;
|
|
15
16
|
onDisconnected?: () => void;
|
|
17
|
+
/** Observes subscription failures. Missing authentication throws when omitted. */
|
|
16
18
|
onError?: (ctx: SdkSubscriptionErrorContext) => void;
|
|
17
19
|
}
|
|
18
20
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","names":[],"sources":["../../src/realtime/types.ts"],"mappings":";;;UAGiB,kBAAkB;EAC/B,gBAAgB,MAAM;EACtB;EACA
|
|
1
|
+
{"version":3,"file":"types.d.ts","names":[],"sources":["../../src/realtime/types.ts"],"mappings":";;;UAGiB,kBAAkB;EAC/B,gBAAgB,MAAM;EACtB;EACA;;EAEA,WAAW,KAAK;;UAGH,qBAAqB,UAAU;EAC5C;EACA,QAAQ;EACR,gBAAgB,MAAM,aAAa;EACnC;EACA;;EAEA,WAAW,KAAK;;;;;;;;UASH;;EAEb,UAAU,GAAG,iBAAiB,UAAU,kBAAkB;;EAE1D,eAAe,UAAU,aAAa,QAAQ,qBAAqB;;EAEnE,oBAAoB,UAAU,aAAa,QAAQ,qBAAqB;;EAExE;;EAEA;WACS;WACA;WACA"}
|