viem 2.18.1 → 2.18.4
Sign up to get free protection for your applications and to get access to all the features.
- package/CHANGELOG.md +18 -0
- package/_cjs/chains/definitions/gravity.js +28 -0
- package/_cjs/chains/definitions/gravity.js.map +1 -0
- package/_cjs/chains/index.js +7 -5
- package/_cjs/chains/index.js.map +1 -1
- package/_cjs/clients/transports/webSocket.js +5 -2
- package/_cjs/clients/transports/webSocket.js.map +1 -1
- package/_cjs/errors/base.js +27 -27
- package/_cjs/errors/base.js.map +1 -1
- package/_cjs/errors/version.js +1 -1
- package/_cjs/utils/rpc/socket.js +27 -6
- package/_cjs/utils/rpc/socket.js.map +1 -1
- package/_cjs/utils/rpc/webSocket.js +22 -5
- package/_cjs/utils/rpc/webSocket.js.map +1 -1
- package/_esm/chains/definitions/gravity.js +25 -0
- package/_esm/chains/definitions/gravity.js.map +1 -0
- package/_esm/chains/index.js +1 -0
- package/_esm/chains/index.js.map +1 -1
- package/_esm/clients/transports/webSocket.js +5 -2
- package/_esm/clients/transports/webSocket.js.map +1 -1
- package/_esm/errors/base.js +27 -27
- package/_esm/errors/base.js.map +1 -1
- package/_esm/errors/version.js +1 -1
- package/_esm/utils/rpc/socket.js +29 -6
- package/_esm/utils/rpc/socket.js.map +1 -1
- package/_esm/utils/rpc/webSocket.js +22 -5
- package/_esm/utils/rpc/webSocket.js.map +1 -1
- package/_types/chains/definitions/gravity.d.ts +34 -0
- package/_types/chains/definitions/gravity.d.ts.map +1 -0
- package/_types/chains/index.d.ts +1 -0
- package/_types/chains/index.d.ts.map +1 -1
- package/_types/clients/transports/webSocket.d.ts +5 -0
- package/_types/clients/transports/webSocket.d.ts.map +1 -1
- package/_types/errors/base.d.ts +1 -1
- package/_types/errors/base.d.ts.map +1 -1
- package/_types/errors/version.d.ts +1 -1
- package/_types/utils/rpc/compat.d.ts +1 -0
- package/_types/utils/rpc/compat.d.ts.map +1 -1
- package/_types/utils/rpc/socket.d.ts +16 -2
- package/_types/utils/rpc/socket.d.ts.map +1 -1
- package/_types/utils/rpc/webSocket.d.ts +1 -1
- package/_types/utils/rpc/webSocket.d.ts.map +1 -1
- package/chains/definitions/gravity.ts +25 -0
- package/chains/index.ts +1 -0
- package/clients/transports/webSocket.ts +10 -1
- package/errors/base.ts +7 -6
- package/errors/version.ts +1 -1
- package/package.json +1 -1
- package/utils/rpc/socket.ts +59 -11
- package/utils/rpc/webSocket.ts +25 -6
package/errors/base.ts
CHANGED
@@ -15,13 +15,11 @@ export class BaseError extends Error {
|
|
15
15
|
docsPath?: string | undefined
|
16
16
|
metaMessages?: string[] | undefined
|
17
17
|
shortMessage: string
|
18
|
+
version: string
|
18
19
|
|
19
20
|
override name = 'ViemError'
|
20
|
-
version = getVersion()
|
21
21
|
|
22
22
|
constructor(shortMessage: string, args: BaseErrorParameters = {}) {
|
23
|
-
super()
|
24
|
-
|
25
23
|
const details =
|
26
24
|
args.cause instanceof BaseError
|
27
25
|
? args.cause.details
|
@@ -32,8 +30,9 @@ export class BaseError extends Error {
|
|
32
30
|
args.cause instanceof BaseError
|
33
31
|
? args.cause.docsPath || args.docsPath
|
34
32
|
: args.docsPath
|
33
|
+
const version = getVersion()
|
35
34
|
|
36
|
-
|
35
|
+
const message = [
|
37
36
|
shortMessage || 'An error occurred.',
|
38
37
|
'',
|
39
38
|
...(args.metaMessages ? [...args.metaMessages, ''] : []),
|
@@ -45,14 +44,16 @@ export class BaseError extends Error {
|
|
45
44
|
]
|
46
45
|
: []),
|
47
46
|
...(details ? [`Details: ${details}`] : []),
|
48
|
-
`Version: ${
|
47
|
+
`Version: ${version}`,
|
49
48
|
].join('\n')
|
50
49
|
|
51
|
-
|
50
|
+
super(message, args.cause ? { cause: args.cause } : undefined)
|
51
|
+
|
52
52
|
this.details = details
|
53
53
|
this.docsPath = docsPath
|
54
54
|
this.metaMessages = args.metaMessages
|
55
55
|
this.shortMessage = shortMessage
|
56
|
+
this.version = version
|
56
57
|
}
|
57
58
|
|
58
59
|
walk(): Error
|
package/errors/version.ts
CHANGED
@@ -1 +1 @@
|
|
1
|
-
export const version = '2.18.
|
1
|
+
export const version = '2.18.4'
|
package/package.json
CHANGED
package/utils/rpc/socket.ts
CHANGED
@@ -16,6 +16,7 @@ type CallbackFn = {
|
|
16
16
|
type CallbackMap = Map<Id, CallbackFn>
|
17
17
|
|
18
18
|
export type GetSocketParameters = {
|
19
|
+
onClose: () => void
|
19
20
|
onError: (error?: Error | Event | undefined) => void
|
20
21
|
onOpen: () => void
|
21
22
|
onResponse: (data: RpcResponse) => void
|
@@ -23,9 +24,8 @@ export type GetSocketParameters = {
|
|
23
24
|
|
24
25
|
export type Socket<socket extends {}> = socket & {
|
25
26
|
close(): void
|
26
|
-
|
27
|
-
|
28
|
-
}): void
|
27
|
+
ping?: (() => void) | undefined
|
28
|
+
request(params: { body: RpcRequest }): void
|
29
29
|
}
|
30
30
|
|
31
31
|
export type SocketRpcClient<socket extends {}> = {
|
@@ -47,9 +47,23 @@ export type SocketRpcClient<socket extends {}> = {
|
|
47
47
|
|
48
48
|
export type GetSocketRpcClientParameters<socket extends {} = {}> = {
|
49
49
|
getSocket(params: GetSocketParameters): Promise<Socket<socket>>
|
50
|
+
/**
|
51
|
+
* Whether or not to send keep-alive messages.
|
52
|
+
* @default true
|
53
|
+
*/
|
54
|
+
keepAlive?:
|
55
|
+
| boolean
|
56
|
+
| {
|
57
|
+
/**
|
58
|
+
* The interval (in ms) to send keep-alive messages.
|
59
|
+
* @default 30_000
|
60
|
+
*/
|
61
|
+
interval?: number | undefined
|
62
|
+
}
|
63
|
+
| undefined
|
50
64
|
key?: string
|
51
65
|
/**
|
52
|
-
* Whether or not to attempt to reconnect on socket failure.
|
66
|
+
* Whether or not to attempt to reconnect on socket failure or closure.
|
53
67
|
* @default true
|
54
68
|
*/
|
55
69
|
reconnect?:
|
@@ -80,9 +94,17 @@ export const socketClientCache = /*#__PURE__*/ new Map<
|
|
80
94
|
>()
|
81
95
|
|
82
96
|
export async function getSocketRpcClient<socket extends {}>(
|
83
|
-
|
97
|
+
parameters: GetSocketRpcClientParameters<socket>,
|
84
98
|
): Promise<SocketRpcClient<socket>> {
|
85
|
-
const {
|
99
|
+
const {
|
100
|
+
getSocket,
|
101
|
+
keepAlive = true,
|
102
|
+
key = 'socket',
|
103
|
+
reconnect = true,
|
104
|
+
url,
|
105
|
+
} = parameters
|
106
|
+
const { interval: keepAliveInterval = 30_000 } =
|
107
|
+
typeof keepAlive === 'object' ? keepAlive : {}
|
86
108
|
const { attempts = 5, delay = 2_000 } =
|
87
109
|
typeof reconnect === 'object' ? reconnect : {}
|
88
110
|
|
@@ -105,10 +127,24 @@ export async function getSocketRpcClient<socket extends {}>(
|
|
105
127
|
const subscriptions = new Map<Id, CallbackFn>()
|
106
128
|
|
107
129
|
let error: Error | Event | undefined
|
108
|
-
let socket: Socket<
|
130
|
+
let socket: Socket<{}>
|
131
|
+
let keepAliveTimer: Timer | undefined
|
132
|
+
|
109
133
|
// Set up socket implementation.
|
110
134
|
async function setup() {
|
111
|
-
|
135
|
+
const result = await getSocket({
|
136
|
+
onClose() {
|
137
|
+
// Clear all requests and subscriptions.
|
138
|
+
requests.clear()
|
139
|
+
subscriptions.clear()
|
140
|
+
|
141
|
+
// Attempt to reconnect.
|
142
|
+
if (reconnect && reconnectCount < attempts)
|
143
|
+
setTimeout(async () => {
|
144
|
+
reconnectCount++
|
145
|
+
await setup().catch(console.error)
|
146
|
+
}, delay)
|
147
|
+
},
|
112
148
|
onError(error_) {
|
113
149
|
error = error_
|
114
150
|
|
@@ -125,7 +161,7 @@ export async function getSocketRpcClient<socket extends {}>(
|
|
125
161
|
if (reconnect && reconnectCount < attempts)
|
126
162
|
setTimeout(async () => {
|
127
163
|
reconnectCount++
|
128
|
-
|
164
|
+
await setup().catch(console.error)
|
129
165
|
}, delay)
|
130
166
|
},
|
131
167
|
onOpen() {
|
@@ -141,17 +177,29 @@ export async function getSocketRpcClient<socket extends {}>(
|
|
141
177
|
if (!isSubscription) cache.delete(id)
|
142
178
|
},
|
143
179
|
})
|
180
|
+
|
181
|
+
socket = result
|
182
|
+
|
183
|
+
if (keepAlive) {
|
184
|
+
if (keepAliveTimer) clearInterval(keepAliveTimer)
|
185
|
+
keepAliveTimer = setInterval(() => socket.ping?.(), keepAliveInterval)
|
186
|
+
}
|
187
|
+
|
188
|
+
return result
|
144
189
|
}
|
145
|
-
|
190
|
+
await setup()
|
146
191
|
error = undefined
|
147
192
|
|
148
193
|
// Create a new socket instance.
|
149
194
|
socketClient = {
|
150
195
|
close() {
|
196
|
+
keepAliveTimer && clearInterval(keepAliveTimer)
|
151
197
|
socket.close()
|
152
198
|
socketClientCache.delete(`${key}:${url}`)
|
153
199
|
},
|
154
|
-
socket
|
200
|
+
get socket() {
|
201
|
+
return socket
|
202
|
+
},
|
155
203
|
request({ body, onError, onResponse }) {
|
156
204
|
if (error && onError) onError(error)
|
157
205
|
|
package/utils/rpc/webSocket.ts
CHANGED
@@ -10,22 +10,23 @@ import {
|
|
10
10
|
|
11
11
|
export type GetWebSocketRpcClientOptions = Pick<
|
12
12
|
GetSocketRpcClientParameters,
|
13
|
-
'reconnect'
|
13
|
+
'keepAlive' | 'reconnect'
|
14
14
|
>
|
15
15
|
|
16
16
|
export async function getWebSocketRpcClient(
|
17
17
|
url: string,
|
18
18
|
options: GetWebSocketRpcClientOptions | undefined = {},
|
19
19
|
): Promise<SocketRpcClient<WebSocket>> {
|
20
|
-
const { reconnect } = options
|
20
|
+
const { keepAlive, reconnect } = options
|
21
21
|
|
22
22
|
return getSocketRpcClient({
|
23
|
-
async getSocket({ onError, onOpen, onResponse }) {
|
23
|
+
async getSocket({ onClose, onError, onOpen, onResponse }) {
|
24
24
|
const WebSocket = await import('isows').then((module) => module.WebSocket)
|
25
25
|
const socket = new WebSocket(url)
|
26
26
|
|
27
|
-
function
|
28
|
-
|
27
|
+
function onClose_() {
|
28
|
+
onClose()
|
29
|
+
socket.removeEventListener('close', onClose_)
|
29
30
|
socket.removeEventListener('message', onMessage)
|
30
31
|
socket.removeEventListener('error', onError)
|
31
32
|
socket.removeEventListener('open', onOpen)
|
@@ -35,7 +36,7 @@ export async function getWebSocketRpcClient(
|
|
35
36
|
}
|
36
37
|
|
37
38
|
// Setup event listeners for RPC & subscription responses.
|
38
|
-
socket.addEventListener('close',
|
39
|
+
socket.addEventListener('close', onClose_)
|
39
40
|
socket.addEventListener('message', onMessage)
|
40
41
|
socket.addEventListener('error', onError)
|
41
42
|
socket.addEventListener('open', onOpen)
|
@@ -56,6 +57,23 @@ export async function getWebSocketRpcClient(
|
|
56
57
|
close_.bind(socket)()
|
57
58
|
onClose()
|
58
59
|
},
|
60
|
+
ping() {
|
61
|
+
try {
|
62
|
+
if (
|
63
|
+
socket.readyState === socket.CLOSED ||
|
64
|
+
socket.readyState === socket.CLOSING
|
65
|
+
)
|
66
|
+
throw new WebSocketRequestError({
|
67
|
+
body: {},
|
68
|
+
url: socket.url,
|
69
|
+
details: 'Socket is closed.',
|
70
|
+
})
|
71
|
+
|
72
|
+
socket.send('ping')
|
73
|
+
} catch (error) {
|
74
|
+
onError(error as Error)
|
75
|
+
}
|
76
|
+
},
|
59
77
|
request({ body }) {
|
60
78
|
if (
|
61
79
|
socket.readyState === socket.CLOSED ||
|
@@ -71,6 +89,7 @@ export async function getWebSocketRpcClient(
|
|
71
89
|
},
|
72
90
|
} as Socket<WebSocket>)
|
73
91
|
},
|
92
|
+
keepAlive,
|
74
93
|
reconnect,
|
75
94
|
url,
|
76
95
|
})
|