@stryke-xyz/premarket-sdk 1.2.2 → 1.2.4

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.
@@ -0,0 +1,225 @@
1
+ function _class_call_check(instance, Constructor) {
2
+ if (!(instance instanceof Constructor)) {
3
+ throw new TypeError("Cannot call a class as a function");
4
+ }
5
+ }
6
+ function _defineProperties(target, props) {
7
+ for(var i = 0; i < props.length; i++){
8
+ var descriptor = props[i];
9
+ descriptor.enumerable = descriptor.enumerable || false;
10
+ descriptor.configurable = true;
11
+ if ("value" in descriptor) descriptor.writable = true;
12
+ Object.defineProperty(target, descriptor.key, descriptor);
13
+ }
14
+ }
15
+ function _create_class(Constructor, protoProps, staticProps) {
16
+ if (protoProps) _defineProperties(Constructor.prototype, protoProps);
17
+ if (staticProps) _defineProperties(Constructor, staticProps);
18
+ return Constructor;
19
+ }
20
+ function _define_property(obj, key, value) {
21
+ if (key in obj) {
22
+ Object.defineProperty(obj, key, {
23
+ value: value,
24
+ enumerable: true,
25
+ configurable: true,
26
+ writable: true
27
+ });
28
+ } else {
29
+ obj[key] = value;
30
+ }
31
+ return obj;
32
+ }
33
+ function scheduleDeferred(callback) {
34
+ return setTimeout(callback, 1000);
35
+ }
36
+ export var RedisWsClient = /*#__PURE__*/ function() {
37
+ "use strict";
38
+ function RedisWsClient(url) {
39
+ _class_call_check(this, RedisWsClient);
40
+ _define_property(this, "url", void 0);
41
+ _define_property(this, "ws", void 0);
42
+ _define_property(this, "handlers", void 0);
43
+ _define_property(this, "heartbeat", void 0);
44
+ _define_property(this, "reconnectTimeout", void 0);
45
+ _define_property(this, "shouldReconnect", void 0);
46
+ this.url = url;
47
+ this.handlers = new Map();
48
+ this.reconnectTimeout = null;
49
+ this.shouldReconnect = true;
50
+ this.connect();
51
+ }
52
+ _create_class(RedisWsClient, [
53
+ {
54
+ key: "connect",
55
+ value: function connect() {
56
+ var _this = this;
57
+ if (!this.shouldReconnect) return;
58
+ this.ws = new WebSocket(this.url);
59
+ this.ws.onopen = function() {
60
+ _this.startHeartbeat();
61
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
62
+ try {
63
+ // Re-subscribe to all channels after reconnection
64
+ for(var _iterator = _this.handlers.keys()[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
65
+ var channel = _step.value;
66
+ _this.subscribeInternal(channel);
67
+ }
68
+ } catch (err) {
69
+ _didIteratorError = true;
70
+ _iteratorError = err;
71
+ } finally{
72
+ try {
73
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
74
+ _iterator.return();
75
+ }
76
+ } finally{
77
+ if (_didIteratorError) {
78
+ throw _iteratorError;
79
+ }
80
+ }
81
+ }
82
+ };
83
+ this.ws.onmessage = function(event) {
84
+ var message = event.data;
85
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
86
+ try {
87
+ // Redis messages come directly as strings from the bridge
88
+ // Since we subscribe to one channel per client instance in practice,
89
+ // we can call all handlers
90
+ for(var _iterator = _this.handlers.values()[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
91
+ var handlers = _step.value;
92
+ handlers.forEach(function(fn) {
93
+ return fn(message);
94
+ });
95
+ }
96
+ } catch (err) {
97
+ _didIteratorError = true;
98
+ _iteratorError = err;
99
+ } finally{
100
+ try {
101
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
102
+ _iterator.return();
103
+ }
104
+ } finally{
105
+ if (_didIteratorError) {
106
+ throw _iteratorError;
107
+ }
108
+ }
109
+ }
110
+ };
111
+ this.ws.onclose = function() {
112
+ return _this.reconnect();
113
+ };
114
+ this.ws.onerror = function() {
115
+ return _this.ws.close();
116
+ };
117
+ }
118
+ },
119
+ {
120
+ key: "reconnect",
121
+ value: function reconnect() {
122
+ var _this = this;
123
+ if (!this.shouldReconnect) return;
124
+ this.stopHeartbeat();
125
+ this.clearReconnectTimeout();
126
+ this.reconnectTimeout = scheduleDeferred(function() {
127
+ _this.reconnectTimeout = null;
128
+ _this.connect();
129
+ });
130
+ }
131
+ },
132
+ {
133
+ key: "startHeartbeat",
134
+ value: function startHeartbeat() {
135
+ var _this = this;
136
+ this.heartbeat = setInterval(function() {
137
+ if (_this.ws.readyState === WebSocket.OPEN) {
138
+ _this.ws.send(JSON.stringify({
139
+ type: "ping"
140
+ }));
141
+ }
142
+ }, 20000);
143
+ }
144
+ },
145
+ {
146
+ key: "stopHeartbeat",
147
+ value: function stopHeartbeat() {
148
+ if (this.heartbeat) clearInterval(this.heartbeat);
149
+ }
150
+ },
151
+ {
152
+ key: "clearReconnectTimeout",
153
+ value: function clearReconnectTimeout() {
154
+ if (this.reconnectTimeout) {
155
+ clearTimeout(this.reconnectTimeout);
156
+ this.reconnectTimeout = null;
157
+ }
158
+ }
159
+ },
160
+ {
161
+ key: "subscribe",
162
+ value: function subscribe(channel, handler) {
163
+ if (!this.handlers.has(channel)) {
164
+ this.handlers.set(channel, new Set());
165
+ this.subscribeInternal(channel);
166
+ }
167
+ this.handlers.get(channel).add(handler);
168
+ }
169
+ },
170
+ {
171
+ key: "unsubscribe",
172
+ value: function unsubscribe(channel, handler) {
173
+ var handlers = this.handlers.get(channel);
174
+ if (!handlers) return;
175
+ if (handler) {
176
+ handlers.delete(handler);
177
+ if (handlers.size === 0) {
178
+ this.handlers.delete(channel);
179
+ this.unsubscribeInternal(channel);
180
+ }
181
+ } else {
182
+ this.handlers.delete(channel);
183
+ this.unsubscribeInternal(channel);
184
+ }
185
+ }
186
+ },
187
+ {
188
+ key: "subscribeInternal",
189
+ value: function subscribeInternal(channel) {
190
+ if (this.ws.readyState === WebSocket.OPEN) {
191
+ this.ws.send(JSON.stringify({
192
+ type: "subscribe",
193
+ channel: channel
194
+ }));
195
+ }
196
+ }
197
+ },
198
+ {
199
+ key: "unsubscribeInternal",
200
+ value: function unsubscribeInternal(channel) {
201
+ if (this.ws.readyState === WebSocket.OPEN) {
202
+ this.ws.send(JSON.stringify({
203
+ type: "unsubscribe",
204
+ channel: channel
205
+ }));
206
+ }
207
+ }
208
+ },
209
+ {
210
+ key: "close",
211
+ value: function close() {
212
+ this.shouldReconnect = false;
213
+ this.stopHeartbeat();
214
+ this.clearReconnectTimeout();
215
+ if (this.ws) {
216
+ this.ws.onclose = null;
217
+ }
218
+ if (this.ws) {
219
+ this.ws.close();
220
+ }
221
+ }
222
+ }
223
+ ]);
224
+ return RedisWsClient;
225
+ }();
@@ -0,0 +1,89 @@
1
+ # Utilities Guide
2
+
3
+ The `utils` folder contains small reusable helpers that do not belong to one
4
+ domain module but are still part of the SDK's public surface.
5
+
6
+ ## Source map
7
+
8
+ - [`mul-div.ts`](./mul-div.ts) provides deterministic multiply-divide math with
9
+ optional rounding up
10
+ - [`rand-bigint.ts`](./rand-bigint.ts) provides secure random bigint generation
11
+ - [`orderUtils.ts`](./orderUtils.ts) provides token-pair helpers and a
12
+ signature-verification shortcut
13
+
14
+ ## `mulDiv` and `Rounding`
15
+
16
+ `mulDiv(a, b, x, rounding?)` performs integer multiplication and division in one
17
+ step using `bigint` arithmetic.
18
+
19
+ Public exports:
20
+
21
+ - `Rounding`
22
+ - `Ceil`
23
+ - `Floor`
24
+ - `mulDiv(a, b, x, rounding?)`
25
+
26
+ ```ts
27
+ import { Rounding, mulDiv } from "@stryke-xyz/premarket-sdk";
28
+
29
+ const floorValue = mulDiv(10n, 3n, 4n);
30
+ const ceilValue = mulDiv(10n, 3n, 4n, Rounding.Ceil);
31
+ ```
32
+
33
+ This helper is especially relevant to the [Vault guide](../vault/README.md),
34
+ where collateral previews need deterministic rounding behavior.
35
+
36
+ ## `randBigInt`
37
+
38
+ `randBigInt(max)` returns a cryptographically secure random bigint in the range
39
+ `[0, max]`.
40
+
41
+ ```ts
42
+ import { randBigInt } from "@stryke-xyz/premarket-sdk";
43
+
44
+ const salt = randBigInt((1n << 96n) - 1n);
45
+ ```
46
+
47
+ Implementation notes:
48
+
49
+ - it requires `globalThis.crypto.getRandomValues`
50
+ - it throws if no secure random source is available
51
+ - it is used by the exchange order builder for default salts
52
+
53
+ ## Order utility helpers
54
+
55
+ [`orderUtils.ts`](./orderUtils.ts) exports a few low-level helpers that are
56
+ useful when app code needs token-id normalization or direct signature recovery.
57
+
58
+ Public exports:
59
+
60
+ - `optionPrmToPrmTokenId(tokenId)`
61
+ - `prmToOptionPrmTokenId(prmTokenId)`
62
+ - `isComplementaryOptionTokenPair(tokenIdA, tokenIdB)`
63
+ - `verifyOrderSignature(order, signature, chainId, exchangeAddress)`
64
+
65
+ ```ts
66
+ import {
67
+ isComplementaryOptionTokenPair,
68
+ verifyOrderSignature,
69
+ } from "@stryke-xyz/premarket-sdk";
70
+
71
+ const complementary = isComplementaryOptionTokenPair(100n, 101n);
72
+ const signer = await verifyOrderSignature(
73
+ order,
74
+ signature,
75
+ 4326,
76
+ exchangeAddress,
77
+ );
78
+ ```
79
+
80
+ Relationship to the domain modules:
81
+
82
+ - the token-id helpers overlap conceptually with the [Vault guide](../vault/README.md)
83
+ and [Exchange guide](../exchange/README.md)
84
+ - `verifyOrderSignature` is a thin convenience wrapper around exchange
85
+ EIP-712 signer recovery
86
+
87
+ When you want the richer context and invariants, prefer the domain guides. When
88
+ you want the smallest possible helper for a utility task, this module is the
89
+ right place.
@@ -0,0 +1,268 @@
1
+ # Vault Guide
2
+
3
+ The `vault` module documents the SDK surface built around
4
+ `OptionMarketVault`. It covers token-id derivation, collateral and settlement
5
+ math, role constants, and transaction builders for mint, redeem, withdraw,
6
+ rollover, and related flows.
7
+
8
+ ## Source map
9
+
10
+ - [`index.ts`](./index.ts) re-exports the public vault surface
11
+ - [`types.ts`](./types.ts) defines vault-level structs used across helpers
12
+ - [`token-ids.ts`](./token-ids.ts) derives `PRM` and `oPRM` token ids
13
+ - [`collateral.ts`](./collateral.ts) mirrors collateral and payoff math
14
+ - [`transactions.ts`](./transactions.ts) builds calldata and transaction envelopes
15
+ - [`constants.ts`](./constants.ts) exports precision constants and role enums
16
+
17
+ ## What this module is for
18
+
19
+ In plain language:
20
+
21
+ - it tells integrators how option position tokens are identified
22
+ - it lets frontends and services estimate collateral, fees, and payouts without
23
+ re-implementing Solidity math
24
+ - it gives callers ABI-backed transaction builders for the public vault flows
25
+
26
+ ## Vault concepts
27
+
28
+ The vault mints paired ERC-6909 position ids:
29
+
30
+ - `PRM`
31
+ - the collateral-side position token
32
+ - always even
33
+ - `oPRM`
34
+ - the option claim token
35
+ - always odd
36
+
37
+ The pairing rule is simple and intentional:
38
+
39
+ - `oPrmTokenId = prmTokenId | 1`
40
+ - `optionPrmToPrm(tokenId)` clears the low bit and returns the canonical `PRM`
41
+ id whether the input is already `PRM` or `oPRM`
42
+
43
+ This convention is used throughout the SDK and should be treated as canonical.
44
+
45
+ ## Public types
46
+
47
+ The main type definitions live in [`types.ts`](./types.ts):
48
+
49
+ - `VaultInstrument`
50
+ - `{ marketId, tick, isCall }`
51
+ - used when minting or describing a strike-side instrument
52
+ - `VaultMarket`
53
+ - bigint-based market shape matching the vault and registry configuration
54
+ - `PrmInfo`
55
+ - metadata associated with a minted `PRM` family
56
+ - `TokenIdParams`
57
+ - the full parameter set needed to derive a token id
58
+
59
+ [`collateral.ts`](./collateral.ts) also exports calculation-specific types:
60
+
61
+ - `MarketParams`
62
+ - `InstrumentParams`
63
+ - `SpreadBounds`
64
+
65
+ These smaller helper types are useful when callers only need the math helpers
66
+ and not the full market struct.
67
+
68
+ ## Precision constants and roles
69
+
70
+ [`constants.ts`](./constants.ts) exposes the shared vault constants:
71
+
72
+ - `VAULT_TOKEN_PRECISION = 1e18`
73
+ - `FEE_BPS_PRECISION = 1e6`
74
+ - `PNL_PRECISION = 1e18`
75
+ - `Role`
76
+ - typed enum for vault role ids
77
+ - `ROLE_NAMES`
78
+ - a friendly lookup from numeric role to display label
79
+
80
+ Use these constants instead of hardcoding precision values in app code.
81
+
82
+ ## Token-id helpers
83
+
84
+ [`token-ids.ts`](./token-ids.ts) is the public source of truth for position-id
85
+ derivation.
86
+
87
+ Public helpers:
88
+
89
+ - `getPrmTokenId(params)`
90
+ - derives the even `PRM` token id from vault address, instrument, expiry, and
91
+ `chainId`
92
+ - `getOptionPrmTokenId(params)`
93
+ - derives the odd `oPRM` token id
94
+ - `prmToOptionTokenId(prmTokenId)`
95
+ - `optionPrmToPrm(oPrmTokenId)`
96
+ - `isPrmToken(tokenId)`
97
+ - `isOptionPrmToken(tokenId)`
98
+ - `getPositionId(tokenId, userAddress)`
99
+ - stable string key for app-side storage keyed by token and user
100
+
101
+ ```ts
102
+ import {
103
+ getOptionPrmTokenId,
104
+ optionPrmToPrm,
105
+ } from "@stryke-xyz/premarket-sdk";
106
+
107
+ const oPrmTokenId = getOptionPrmTokenId({
108
+ vaultAddress: "0xVault",
109
+ marketId: 12n,
110
+ tick: 1500n,
111
+ isCall: true,
112
+ expiry: 1_735_689_600n,
113
+ chainId: 4326,
114
+ });
115
+
116
+ const prmTokenId = optionPrmToPrm(oPrmTokenId);
117
+ ```
118
+
119
+ Implementation detail worth remembering:
120
+
121
+ - `getPrmTokenId` hashes the vault address, instrument fields, expiry, and
122
+ `chainId`, then left-shifts once to force even parity
123
+
124
+ ## Collateral and settlement math
125
+
126
+ [`collateral.ts`](./collateral.ts) mirrors the important deterministic math used
127
+ by the vault contract. This makes it safe to pre-compute values in the UI or a
128
+ backend without sacrificing contract parity.
129
+
130
+ Public helpers:
131
+
132
+ - `getSpreadWidth(market)`
133
+ - `getSpreadBounds(instrument, market)`
134
+ - `calculateCollateralAmount(prmAmount, instrument, market)`
135
+ - `calculatePrmAmount(collateralAmount, instrument, market)`
136
+ - `calculateSpreadProfit(instrument, market, finalTick, positionSize)`
137
+ - `calculateSpreadLoss(instrument, market, finalTick, positionSize)`
138
+ - `calculateWithdrawableCollateral(instrument, market, finalTick, positionSize)`
139
+ - `getCollateralPerPosition(instrument, market)`
140
+ - `calculateDepositFees(collateralAmount, depositFeeBps, feeBpsPrecision?)`
141
+ - `calculateRedeemFees(profitAmount, redeemFeeBps, feeBpsPrecision?)`
142
+ - `isInTheMoney(instrument, market, finalTick)`
143
+ - `calculateMoneyness(instrument, market, finalTick)`
144
+
145
+ ```ts
146
+ import {
147
+ calculateCollateralAmount,
148
+ calculateWithdrawableCollateral,
149
+ } from "@stryke-xyz/premarket-sdk";
150
+
151
+ const collateral = calculateCollateralAmount(
152
+ 1_000_000_000_000_000_000n,
153
+ { marketId: 1n, tick: 1500n, isCall: true },
154
+ {
155
+ tickSize: 100n,
156
+ tickSpacing: 100n,
157
+ tokensPerTickSize: 1_000_000n,
158
+ isCollateralScaled: false,
159
+ },
160
+ );
161
+
162
+ const withdrawable = calculateWithdrawableCollateral(
163
+ { marketId: 1n, tick: 1500n, isCall: true },
164
+ {
165
+ tickSize: 100n,
166
+ tickSpacing: 100n,
167
+ tokensPerTickSize: 1_000_000n,
168
+ isCollateralScaled: false,
169
+ },
170
+ 1_600n,
171
+ 1_000_000_000_000_000_000n,
172
+ );
173
+ ```
174
+
175
+ Important behavior captured by the SDK:
176
+
177
+ - spread width falls back to `1` when `tickSpacing <= tickSize`
178
+ - strike-scaled collateral uses `instrument.tick`
179
+ - collateral calculation rounds up when the final division is not exact
180
+ - inverse `PRM` previews use floor division
181
+ - payoff and withdraw math use deterministic `bigint` arithmetic throughout
182
+
183
+ ## Transaction builders
184
+
185
+ [`transactions.ts`](./transactions.ts) contains ABI-backed transaction builders.
186
+ These return a lightweight `TransactionCall`:
187
+
188
+ ```ts
189
+ export interface TransactionCall {
190
+ to: `0x${string}`;
191
+ value?: bigint;
192
+ data: Hex;
193
+ }
194
+ ```
195
+
196
+ ### User-facing lifecycle builders
197
+
198
+ - `buildMintTransaction(vaultAddress, instrument, amount)`
199
+ - `buildWithdrawTransaction(vaultAddress, prmTokenId, amount, receiver)`
200
+ - `buildRedeemTransaction(vaultAddress, oPrmTokenId, receiver)`
201
+ - `buildUnwindTransaction(vaultAddress, prmTokenId, amount, receiver)`
202
+ - `buildRolloverTransaction(vaultAddress, oldPrmTokenId)`
203
+ - `buildApproveTransaction(tokenAddress, spender, amount?)`
204
+ - `buildBatchedMintTransactions(collateralTokenAddress, vaultAddress, instrument, collateralAmount, prmAmount)`
205
+ - `buildSetOperatorTransaction(vaultAddress, operator, approved)`
206
+
207
+ ```ts
208
+ import {
209
+ buildApproveTransaction,
210
+ buildMintTransaction,
211
+ } from "@stryke-xyz/premarket-sdk";
212
+
213
+ const approve = buildApproveTransaction(collateralToken, vaultAddress);
214
+ const mint = buildMintTransaction(
215
+ vaultAddress,
216
+ { marketId: 12n, tick: 1500n, isCall: true },
217
+ 1_000_000_000_000_000_000n,
218
+ );
219
+ ```
220
+
221
+ ### Restricted and role-gated builders
222
+
223
+ These functions are exported because they are part of the SDK, but they belong
224
+ to operational or keeper-style flows rather than ordinary end-user integrations:
225
+
226
+ - `buildDelegateRedeemTransaction`
227
+ - `buildDelegateRolloverTransaction`
228
+ - `buildDelegateWithdrawTransaction`
229
+ - `buildFillMarketDeliveryTransaction`
230
+ - `buildSetRolloverEnabledTransaction`
231
+ - `buildSetRoleTransaction`
232
+ - `buildUpdateFinalTickTransaction`
233
+ - `buildUpdateMarketExpiryTransaction`
234
+ - `buildUpdateMarketExpiryFromMarketTransaction`
235
+
236
+ They should usually be used by privileged services, market operators, or
237
+ automation code that already understands the relevant role checks.
238
+
239
+ ## Typical integration patterns
240
+
241
+ ### 1. Preview before mint
242
+
243
+ Use the math helpers and token-id helpers together:
244
+
245
+ 1. derive the target `PRM` or `oPRM` id
246
+ 2. compute required collateral with `calculateCollateralAmount`
247
+ 3. build `approve` and `mint` calls
248
+
249
+ ### 2. Display settlement outcomes
250
+
251
+ Use:
252
+
253
+ - `isInTheMoney`
254
+ - `calculateSpreadProfit`
255
+ - `calculateRedeemFees`
256
+ - `calculateWithdrawableCollateral`
257
+
258
+ This gives UI code a contract-aligned preview for both option holders and
259
+ collateral providers.
260
+
261
+ ### 3. Build sponsored or batched flows
262
+
263
+ `buildBatchedMintTransactions` is especially helpful when a frontend or relayer
264
+ needs to bundle approval and minting into one user operation or multicall-like
265
+ flow.
266
+
267
+ For market configuration and market serialization, continue with the
268
+ [Registry guide](../registry/README.md).
File without changes
@@ -0,0 +1,56 @@
1
+ import type { SyncStatus } from "../types.js";
2
+ import { RedisWsClient } from "../redis-ws-client.js";
3
+ /**
4
+ * Base abstract class for sync clients
5
+ * @template TMessage - The message type (e.g., SequencedMessage, BalanceUpdateMessage)
6
+ * @template TChange - The change type (e.g., OrderChange, BalanceData[])
7
+ * @template TData - The data type stored in the map (e.g., StoredOrder, string)
8
+ * @template TConfig - The config type (must have redisUrl and channel)
9
+ */
10
+ export declare abstract class BaseSyncClient<TMessage extends {
11
+ seq: number;
12
+ previousSeq: number;
13
+ }, TChange, TData, TConfig extends {
14
+ redisUrl: string;
15
+ channel: string;
16
+ }> {
17
+ protected wsClient: RedisWsClient | null;
18
+ protected config: TConfig;
19
+ protected status: SyncStatus;
20
+ protected lastSeq: number;
21
+ protected incomingQueue: TMessage[];
22
+ protected isProcessing: boolean;
23
+ protected statusListeners: Set<(status: SyncStatus) => void>;
24
+ protected changeListeners: Set<(change: TChange) => void>;
25
+ protected dataMap: Map<string, TData>;
26
+ protected snapshotListeners: Set<(data: TData[]) => void>;
27
+ constructor(config: TConfig);
28
+ /** Opens the websocket subscription, fetches a fresh snapshot, and starts replaying queued messages. */
29
+ connect(): Promise<void>;
30
+ protected enqueueMessage(message: TMessage): void;
31
+ protected processQueue(): Promise<void>;
32
+ protected fullResync(): Promise<void>;
33
+ protected setStatus(status: SyncStatus): void;
34
+ /** Returns the current connection lifecycle state. */
35
+ getStatus(): SyncStatus;
36
+ /** Returns true once the client has finished its initial snapshot sync. */
37
+ isSynced(): boolean;
38
+ /** Returns the most recent successfully applied sequence id. */
39
+ getLastSequence(): number;
40
+ /** Returns the number of queued messages waiting to be processed. */
41
+ getBufferedCount(): number;
42
+ /** Registers a listener for connection status changes. */
43
+ onStatus(callback: (status: SyncStatus) => void): () => void;
44
+ /** Registers a listener for individual applied change events. */
45
+ onChange(callback: (change: TChange) => void): () => void;
46
+ /** Registers a listener for full snapshot updates. */
47
+ onSnapshot(callback: (data: TData[]) => void): () => void;
48
+ protected notifySnapshotListeners(data: TData[]): void;
49
+ /** Closes the websocket connection and clears queued messages. */
50
+ disconnect(): Promise<void>;
51
+ /**
52
+ * Abstract methods to be implemented by child classes
53
+ */
54
+ protected abstract fetchSnapshot(): Promise<void>;
55
+ protected abstract applyMessage(message: TMessage): Promise<void> | void;
56
+ }
@@ -0,0 +1,21 @@
1
+ type Handler<T = any> = (data: T) => void;
2
+ export declare class RedisWsClient {
3
+ private url;
4
+ private ws;
5
+ private handlers;
6
+ private heartbeat?;
7
+ private reconnectTimeout;
8
+ private shouldReconnect;
9
+ constructor(url: string);
10
+ private connect;
11
+ private reconnect;
12
+ private startHeartbeat;
13
+ private stopHeartbeat;
14
+ private clearReconnectTimeout;
15
+ subscribe<T>(channel: string, handler: Handler<T>): void;
16
+ unsubscribe(channel: string, handler?: Handler): void;
17
+ private subscribeInternal;
18
+ private unsubscribeInternal;
19
+ close(): void;
20
+ }
21
+ export {};