univo 0.3.2 → 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/dist/cli.mjs +2 -2
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.mjs +451 -384
- package/dist/proxy.d.mts +20 -0
- package/dist/proxy.d.ts +20 -0
- package/dist/proxy.mjs +90 -0
- package/dist/realtime.d.mts +2 -3
- package/dist/realtime.d.ts +2 -3
- package/dist/realtime.mjs +20 -3
- package/dist/rpc.d.mts +3 -326
- package/dist/rpc.d.ts +3 -326
- package/dist/shared/univo.C0flyVee.mjs +21 -0
- package/dist/shared/univo.CEA4vY0E.d.ts +354 -0
- package/dist/shared/univo.DYd1g40o.d.mts +354 -0
- package/dist/shared/{univo.vwk4Xrn3.mjs → univo.mlthZw0m.mjs} +2 -6
- package/dist/transport.d.mts +1 -39
- package/dist/transport.d.ts +1 -39
- package/dist/transport.mjs +215 -4
- package/package.json +5 -1
- package/dist/shared/univo.j1HWrILH.mjs +0 -238
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "univo",
|
|
3
3
|
"license": "MIT",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"version": "0.
|
|
5
|
+
"version": "0.4.0",
|
|
6
6
|
"sideEffects": false,
|
|
7
7
|
"module": "./dist/index.mjs",
|
|
8
8
|
"types": "./dist/index.d.ts",
|
|
@@ -18,6 +18,10 @@
|
|
|
18
18
|
"types": "./dist/rpc.d.ts",
|
|
19
19
|
"import": "./dist/rpc.mjs"
|
|
20
20
|
},
|
|
21
|
+
"./proxy": {
|
|
22
|
+
"types": "./dist/proxy.d.ts",
|
|
23
|
+
"import": "./dist/proxy.mjs"
|
|
24
|
+
},
|
|
21
25
|
"./transport": {
|
|
22
26
|
"types": "./dist/transport.d.ts",
|
|
23
27
|
"import": "./dist/transport.mjs"
|
|
@@ -1,238 +0,0 @@
|
|
|
1
|
-
import ws from 'ws';
|
|
2
|
-
import { WebSocket } from 'partysocket';
|
|
3
|
-
import { f as compress, g as raise, c as createLogger, m as mutex } from './univo.vwk4Xrn3.mjs';
|
|
4
|
-
|
|
5
|
-
function createException(message) {
|
|
6
|
-
return `univo:${message}`;
|
|
7
|
-
}
|
|
8
|
-
function catchException(unknown, exception) {
|
|
9
|
-
if (unknown instanceof Error) {
|
|
10
|
-
if (unknown.message === exception) {
|
|
11
|
-
return true;
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
return false;
|
|
15
|
-
}
|
|
16
|
-
function getException(unknown) {
|
|
17
|
-
if (unknown instanceof Error) {
|
|
18
|
-
if (unknown.message.startsWith("univo")) {
|
|
19
|
-
const [_, message] = unknown.message.split(":");
|
|
20
|
-
if (message) return message;
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
const DEFAULT_TIMEOUT_MS = 60 * 1e3;
|
|
26
|
-
const UnknownMethodError = createException("The requested RPC method does not exist on the provided implementation");
|
|
27
|
-
function local(rpc) {
|
|
28
|
-
const request = async (opts) => {
|
|
29
|
-
const method = rpc.request[opts.method];
|
|
30
|
-
if (method === void 0) {
|
|
31
|
-
throw new Error(UnknownMethodError);
|
|
32
|
-
}
|
|
33
|
-
return await method(...opts.params);
|
|
34
|
-
};
|
|
35
|
-
const subscribe = async () => {
|
|
36
|
-
throw new Error("Unable to `subscribe` on `local` transport");
|
|
37
|
-
};
|
|
38
|
-
return { protocol: "local", request, subscribe };
|
|
39
|
-
}
|
|
40
|
-
function createSocket(url, opts) {
|
|
41
|
-
const socket = new WebSocket(url, [], { WebSocket: ws });
|
|
42
|
-
socket.binaryType = "arraybuffer";
|
|
43
|
-
if (opts.onOpen) socket.onopen = opts.onOpen;
|
|
44
|
-
if (opts.onError) socket.onerror = opts.onError;
|
|
45
|
-
if (opts.onClose) socket.onclose = opts.onClose;
|
|
46
|
-
if (opts.onMessage) socket.onmessage = opts.onMessage;
|
|
47
|
-
return socket;
|
|
48
|
-
}
|
|
49
|
-
function wss(url, opts = {}) {
|
|
50
|
-
if (!url.startsWith("wss://")) {
|
|
51
|
-
throw new Error("Websocket connections must start with `wss://`");
|
|
52
|
-
}
|
|
53
|
-
const log = createLogger({ quiet: opts.quiet ?? false });
|
|
54
|
-
let id = 0;
|
|
55
|
-
const requests = /* @__PURE__ */ new Map();
|
|
56
|
-
const subscriptions = /* @__PURE__ */ new Map();
|
|
57
|
-
const params = /* @__PURE__ */ new Map();
|
|
58
|
-
const socket = createSocket(url, {
|
|
59
|
-
async onError(cause) {
|
|
60
|
-
log.error(`Socket error: ${cause.message}`);
|
|
61
|
-
},
|
|
62
|
-
async onOpen() {
|
|
63
|
-
if (subscriptions.size === 0) {
|
|
64
|
-
return;
|
|
65
|
-
}
|
|
66
|
-
const params2 = [];
|
|
67
|
-
for (const [id2, subscription] of subscriptions) {
|
|
68
|
-
params2.push(subscription.param);
|
|
69
|
-
request({ method: "eth_unsubscribe", params: [id2] }).catch(() => {
|
|
70
|
-
log.warn("Failed to cancel old susbcription");
|
|
71
|
-
});
|
|
72
|
-
subscriptions.delete(id2);
|
|
73
|
-
}
|
|
74
|
-
for (const param of params2) {
|
|
75
|
-
request({ method: "eth_subscribe", params: [param] }).then((id2) => {
|
|
76
|
-
subscriptions.set(id2, { param, latest: Date.now() });
|
|
77
|
-
});
|
|
78
|
-
}
|
|
79
|
-
},
|
|
80
|
-
async onClose() {
|
|
81
|
-
log.debug("Socket closed");
|
|
82
|
-
},
|
|
83
|
-
async onMessage(event) {
|
|
84
|
-
const data = JSON.parse(event.data);
|
|
85
|
-
if (data.method === "eth_subscription") {
|
|
86
|
-
const subscription = subscriptions.get(data.params.subscription);
|
|
87
|
-
if (subscription === void 0) {
|
|
88
|
-
return await request({ method: "eth_unsubscribe", params: [data.params.subscription] }).catch(() => {
|
|
89
|
-
log.warn("Failed to unsubscribe stale subscription");
|
|
90
|
-
});
|
|
91
|
-
}
|
|
92
|
-
const handlers = params.get(subscription.param);
|
|
93
|
-
if (handlers === void 0) {
|
|
94
|
-
return await request({ method: "eth_unsubscribe", params: [data.params.subscription] }).catch(() => {
|
|
95
|
-
log.warn("Failed to unsubscribe stale subscription");
|
|
96
|
-
});
|
|
97
|
-
}
|
|
98
|
-
for (const handler2 of handlers) {
|
|
99
|
-
try {
|
|
100
|
-
handler2(data.params.result);
|
|
101
|
-
} catch (cause) {
|
|
102
|
-
log.error(new Error("Handler error", { cause }));
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
subscription.latest = Date.now();
|
|
106
|
-
return;
|
|
107
|
-
}
|
|
108
|
-
const handler = requests.get(data.id);
|
|
109
|
-
if (handler === void 0) {
|
|
110
|
-
return log.warn(`Received unknown response for request id ${data.id}...`);
|
|
111
|
-
}
|
|
112
|
-
return handler(data.result);
|
|
113
|
-
}
|
|
114
|
-
});
|
|
115
|
-
const request = async (opts2) => {
|
|
116
|
-
return await new Promise((resolve, reject) => {
|
|
117
|
-
const signal = opts2.signal ?? AbortSignal.timeout(DEFAULT_TIMEOUT_MS);
|
|
118
|
-
const body = {
|
|
119
|
-
id: id++,
|
|
120
|
-
method: opts2.method,
|
|
121
|
-
params: opts2.params
|
|
122
|
-
};
|
|
123
|
-
function cleanup() {
|
|
124
|
-
requests.delete(body.id);
|
|
125
|
-
signal.removeEventListener("abort", abort);
|
|
126
|
-
}
|
|
127
|
-
function abort() {
|
|
128
|
-
cleanup();
|
|
129
|
-
reject(signal.reason);
|
|
130
|
-
}
|
|
131
|
-
if (signal.aborted) {
|
|
132
|
-
return abort();
|
|
133
|
-
}
|
|
134
|
-
signal.addEventListener("abort", abort, { once: true });
|
|
135
|
-
requests.set(body.id, (data) => {
|
|
136
|
-
cleanup();
|
|
137
|
-
resolve(data);
|
|
138
|
-
});
|
|
139
|
-
try {
|
|
140
|
-
socket.send(JSON.stringify(body));
|
|
141
|
-
} catch (cause) {
|
|
142
|
-
cleanup();
|
|
143
|
-
reject(new Error(ClientConnectionError, { cause }));
|
|
144
|
-
}
|
|
145
|
-
});
|
|
146
|
-
};
|
|
147
|
-
const subscribe = async (param, handler) => {
|
|
148
|
-
const handlers = params.get(param);
|
|
149
|
-
if (handlers === void 0) {
|
|
150
|
-
const handlers2 = (/* @__PURE__ */ new Set()).add(handler);
|
|
151
|
-
params.set(param, handlers2);
|
|
152
|
-
const id2 = await request({ method: "eth_subscribe", params: [param] }).catch((cause) => {
|
|
153
|
-
throw new Error(`Failed to initialise subscription for param ${param}`, { cause });
|
|
154
|
-
});
|
|
155
|
-
subscriptions.set(id2, { param, latest: Date.now() });
|
|
156
|
-
} else {
|
|
157
|
-
handlers.add(handler);
|
|
158
|
-
}
|
|
159
|
-
return async function unsubscribe() {
|
|
160
|
-
const handlers2 = params.get(param);
|
|
161
|
-
if (handlers2 === void 0) {
|
|
162
|
-
return log.warn("Param already unsubscribed...");
|
|
163
|
-
}
|
|
164
|
-
handlers2.delete(handler);
|
|
165
|
-
if (handlers2.size === 0) {
|
|
166
|
-
await request({ method: "eth_unsubscribe", params: [id] }).catch(() => {
|
|
167
|
-
log.warn("Failed to unsubscribe unused subscription");
|
|
168
|
-
});
|
|
169
|
-
}
|
|
170
|
-
};
|
|
171
|
-
};
|
|
172
|
-
function healthcheck() {
|
|
173
|
-
try {
|
|
174
|
-
const failed = Object.values(subscriptions).some((subscription) => {
|
|
175
|
-
return Date.now() - subscription.latest > 60 * 1e3;
|
|
176
|
-
});
|
|
177
|
-
if (!failed) {
|
|
178
|
-
return;
|
|
179
|
-
}
|
|
180
|
-
log.warn("Health check failed. Reinitialising socket...");
|
|
181
|
-
socket.reconnect();
|
|
182
|
-
} catch (error) {
|
|
183
|
-
if (error instanceof Error) {
|
|
184
|
-
log.debug(`Failed healthcheck: ${error.message}`);
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
setInterval(mutex(healthcheck), 60 * 1e3);
|
|
189
|
-
return { protocol: "wss", request, subscribe };
|
|
190
|
-
}
|
|
191
|
-
function http(url, opts = {}) {
|
|
192
|
-
let id = 0;
|
|
193
|
-
const request = async (options) => {
|
|
194
|
-
let body = JSON.stringify({
|
|
195
|
-
id: id++,
|
|
196
|
-
jsonrpc: "2.0",
|
|
197
|
-
method: options.method,
|
|
198
|
-
params: options.params
|
|
199
|
-
});
|
|
200
|
-
const headers = new Headers();
|
|
201
|
-
headers.set("Content-Type", "application/json");
|
|
202
|
-
if (options.method.startsWith("private_")) {
|
|
203
|
-
if (opts.signingKey === void 0) {
|
|
204
|
-
throw new Error(ClientUnauthorizedError);
|
|
205
|
-
}
|
|
206
|
-
body = await compress(body).catch((cause) => raise(ClientCompressionError, { cause }));
|
|
207
|
-
headers.set("Content-Encoding", "gzip");
|
|
208
|
-
headers.set("Authorization", `Bearer ${opts.signingKey}`);
|
|
209
|
-
}
|
|
210
|
-
const signal = options.signal ?? AbortSignal.timeout(DEFAULT_TIMEOUT_MS);
|
|
211
|
-
const res = await fetch(url, { headers, body, method: "POST", signal }).catch((cause) => {
|
|
212
|
-
if (signal.aborted) {
|
|
213
|
-
throw signal.reason;
|
|
214
|
-
}
|
|
215
|
-
throw new Error(ClientConnectionError, { cause });
|
|
216
|
-
});
|
|
217
|
-
if (!res.ok || res.status < 200 || res.status >= 300) {
|
|
218
|
-
throw new Error(ClientConnectionError);
|
|
219
|
-
}
|
|
220
|
-
const json = await res.json().catch((cause) => {
|
|
221
|
-
throw new Error(ClientResponseError, { cause });
|
|
222
|
-
});
|
|
223
|
-
if (json.error) {
|
|
224
|
-
throw new Error(json.error.message);
|
|
225
|
-
}
|
|
226
|
-
return json.result;
|
|
227
|
-
};
|
|
228
|
-
const subscribe = async () => {
|
|
229
|
-
throw new Error("Unable to `subscribe` on `http` transport");
|
|
230
|
-
};
|
|
231
|
-
return { protocol: "http", request, subscribe };
|
|
232
|
-
}
|
|
233
|
-
const ClientCompressionError = createException("An error occurred when compressing the request");
|
|
234
|
-
const ClientConnectionError = createException("An errored occurred when connecting to the server");
|
|
235
|
-
const ClientResponseError = createException("An error occurred when reading the servers response");
|
|
236
|
-
const ClientUnauthorizedError = createException("Attempted to execute a private method without providing a request signing key");
|
|
237
|
-
|
|
238
|
-
export { catchException as a, createException as c, getException as g, http as h, local as l, wss as w };
|