@pezkuwi/rpc-provider 16.5.20 → 16.5.21

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.
Files changed (210) hide show
  1. package/package.json +9 -9
  2. package/build/LICENSE +0 -201
  3. package/build/README.md +0 -68
  4. package/build/bizinikiwi-connect/Health.js +0 -259
  5. package/build/bizinikiwi-connect/index.js +0 -319
  6. package/build/bizinikiwi-connect/types.js +0 -1
  7. package/build/bundle.js +0 -5
  8. package/build/cjs/bizinikiwi-connect/Health.d.ts +0 -7
  9. package/build/cjs/bizinikiwi-connect/Health.js +0 -264
  10. package/build/cjs/bizinikiwi-connect/index.d.ts +0 -22
  11. package/build/cjs/bizinikiwi-connect/index.js +0 -323
  12. package/build/cjs/bizinikiwi-connect/types.d.ts +0 -12
  13. package/build/cjs/bizinikiwi-connect/types.js +0 -2
  14. package/build/cjs/bundle.d.ts +0 -5
  15. package/build/cjs/bundle.js +0 -14
  16. package/build/cjs/coder/error.js +0 -53
  17. package/build/cjs/coder/index.js +0 -63
  18. package/build/cjs/defaults.js +0 -8
  19. package/build/cjs/http/index.js +0 -196
  20. package/build/cjs/http/types.js +0 -2
  21. package/build/cjs/index.js +0 -5
  22. package/build/cjs/lru.js +0 -150
  23. package/build/cjs/mock/index.js +0 -196
  24. package/build/cjs/mock/mockHttp.js +0 -17
  25. package/build/cjs/mock/mockWs.js +0 -47
  26. package/build/cjs/mock/types.js +0 -2
  27. package/build/cjs/packageInfo.js +0 -4
  28. package/build/cjs/types.js +0 -2
  29. package/build/cjs/ws/errors.js +0 -41
  30. package/build/cjs/ws/index.js +0 -529
  31. package/build/coder/error.d.ts +0 -29
  32. package/build/coder/error.js +0 -50
  33. package/build/coder/index.d.ts +0 -8
  34. package/build/coder/index.js +0 -58
  35. package/build/defaults.d.ts +0 -5
  36. package/build/defaults.js +0 -6
  37. package/build/http/index.d.ts +0 -81
  38. package/build/http/index.js +0 -191
  39. package/build/http/types.d.ts +0 -7
  40. package/build/http/types.js +0 -1
  41. package/build/index.d.ts +0 -2
  42. package/build/index.js +0 -2
  43. package/build/lru.d.ts +0 -15
  44. package/build/lru.js +0 -146
  45. package/build/mock/index.d.ts +0 -35
  46. package/build/mock/index.js +0 -191
  47. package/build/mock/mockHttp.d.ts +0 -9
  48. package/build/mock/mockHttp.js +0 -12
  49. package/build/mock/mockWs.d.ts +0 -26
  50. package/build/mock/mockWs.js +0 -43
  51. package/build/mock/types.d.ts +0 -23
  52. package/build/mock/types.js +0 -1
  53. package/build/package.json +0 -344
  54. package/build/packageDetect.d.ts +0 -1
  55. package/build/packageDetect.js +0 -4
  56. package/build/packageInfo.d.ts +0 -6
  57. package/build/packageInfo.js +0 -1
  58. package/build/types.d.ts +0 -85
  59. package/build/types.js +0 -1
  60. package/build/ws/errors.d.ts +0 -1
  61. package/build/ws/errors.js +0 -38
  62. package/build/ws/index.d.ts +0 -121
  63. package/build/ws/index.js +0 -524
  64. package/build-deno/README.md +0 -66
  65. package/build-deno/bizinikiwi-connect/Health.ts +0 -323
  66. package/build-deno/bizinikiwi-connect/index.ts +0 -417
  67. package/build-deno/bizinikiwi-connect/types.ts +0 -14
  68. package/build-deno/bundle.ts +0 -6
  69. package/build-deno/coder/error.ts +0 -64
  70. package/build-deno/coder/index.ts +0 -86
  71. package/build-deno/defaults.ts +0 -8
  72. package/build-deno/http/index.ts +0 -236
  73. package/build-deno/http/types.ts +0 -9
  74. package/build-deno/index.ts +0 -4
  75. package/build-deno/lru.ts +0 -189
  76. package/build-deno/mock/index.ts +0 -257
  77. package/build-deno/mock/mockHttp.ts +0 -33
  78. package/build-deno/mock/mockWs.ts +0 -87
  79. package/build-deno/mock/types.ts +0 -34
  80. package/build-deno/mod.ts +0 -2
  81. package/build-deno/packageDetect.ts +0 -8
  82. package/build-deno/packageInfo.ts +0 -3
  83. package/build-deno/types.ts +0 -99
  84. package/build-deno/ws/errors.ts +0 -38
  85. package/build-deno/ws/index.ts +0 -650
  86. package/build-tsc-cjs/packageDetect.js +0 -6
  87. package/src/bizinikiwi-connect/Health.ts +0 -325
  88. package/src/bizinikiwi-connect/index.spec.ts +0 -675
  89. package/src/bizinikiwi-connect/index.ts +0 -427
  90. package/src/bizinikiwi-connect/types.ts +0 -16
  91. package/src/bundle.ts +0 -8
  92. package/src/coder/decodeResponse.spec.ts +0 -70
  93. package/src/coder/encodeJson.spec.ts +0 -20
  94. package/src/coder/encodeObject.spec.ts +0 -25
  95. package/src/coder/error.spec.ts +0 -111
  96. package/src/coder/error.ts +0 -66
  97. package/src/coder/index.ts +0 -88
  98. package/src/defaults.ts +0 -10
  99. package/src/http/index.spec.ts +0 -72
  100. package/src/http/index.ts +0 -238
  101. package/src/http/send.spec.ts +0 -61
  102. package/src/http/types.ts +0 -11
  103. package/src/index.ts +0 -6
  104. package/src/lru.spec.ts +0 -74
  105. package/src/lru.ts +0 -197
  106. package/src/mock/index.ts +0 -259
  107. package/src/mock/mockHttp.ts +0 -35
  108. package/src/mock/mockWs.ts +0 -92
  109. package/src/mock/on.spec.ts +0 -43
  110. package/src/mock/send.spec.ts +0 -38
  111. package/src/mock/subscribe.spec.ts +0 -81
  112. package/src/mock/types.ts +0 -36
  113. package/src/mock/unsubscribe.spec.ts +0 -57
  114. package/src/mod.ts +0 -4
  115. package/src/packageDetect.ts +0 -12
  116. package/src/packageInfo.ts +0 -6
  117. package/src/types.ts +0 -101
  118. package/src/ws/connect.spec.ts +0 -167
  119. package/src/ws/errors.ts +0 -41
  120. package/src/ws/index.spec.ts +0 -97
  121. package/src/ws/index.ts +0 -652
  122. package/src/ws/send.spec.ts +0 -126
  123. package/src/ws/state.spec.ts +0 -20
  124. package/src/ws/subscribe.spec.ts +0 -68
  125. package/src/ws/unsubscribe.spec.ts +0 -100
  126. package/tsconfig.build.json +0 -17
  127. package/tsconfig.build.tsbuildinfo +0 -1
  128. package/tsconfig.spec.json +0 -18
  129. package/tsconfig.spec.tsbuildinfo +0 -1
  130. /package/{build-tsc/bizinikiwi-connect → bizinikiwi-connect}/Health.d.ts +0 -0
  131. /package/{build-tsc-esm/bizinikiwi-connect → bizinikiwi-connect}/Health.js +0 -0
  132. /package/{build-tsc/bizinikiwi-connect → bizinikiwi-connect}/index.d.ts +0 -0
  133. /package/{build-tsc-esm/bizinikiwi-connect → bizinikiwi-connect}/index.js +0 -0
  134. /package/{build-tsc/bizinikiwi-connect → bizinikiwi-connect}/types.d.ts +0 -0
  135. /package/{build-tsc-esm/bizinikiwi-connect → bizinikiwi-connect}/types.js +0 -0
  136. /package/{build-tsc/bundle.d.ts → bundle.d.ts} +0 -0
  137. /package/{build-tsc-esm/bundle.js → bundle.js} +0 -0
  138. /package/{build → cjs}/bizinikiwi-connect/Health.d.ts +0 -0
  139. /package/{build-tsc-cjs → cjs}/bizinikiwi-connect/Health.js +0 -0
  140. /package/{build → cjs}/bizinikiwi-connect/index.d.ts +0 -0
  141. /package/{build-tsc-cjs → cjs}/bizinikiwi-connect/index.js +0 -0
  142. /package/{build → cjs}/bizinikiwi-connect/types.d.ts +0 -0
  143. /package/{build-tsc-cjs → cjs}/bizinikiwi-connect/types.js +0 -0
  144. /package/{build → cjs}/bundle.d.ts +0 -0
  145. /package/{build-tsc-cjs → cjs}/bundle.js +0 -0
  146. /package/{build-tsc → cjs}/coder/error.d.ts +0 -0
  147. /package/{build-tsc-cjs → cjs}/coder/error.js +0 -0
  148. /package/{build-tsc → cjs}/coder/index.d.ts +0 -0
  149. /package/{build-tsc-cjs → cjs}/coder/index.js +0 -0
  150. /package/{build-tsc → cjs}/defaults.d.ts +0 -0
  151. /package/{build-tsc-cjs → cjs}/defaults.js +0 -0
  152. /package/{build-tsc → cjs}/http/index.d.ts +0 -0
  153. /package/{build-tsc-cjs → cjs}/http/index.js +0 -0
  154. /package/{build-tsc → cjs}/http/types.d.ts +0 -0
  155. /package/{build-tsc-cjs → cjs}/http/types.js +0 -0
  156. /package/{build-tsc → cjs}/index.d.ts +0 -0
  157. /package/{build-tsc-cjs → cjs}/index.js +0 -0
  158. /package/{build-tsc → cjs}/lru.d.ts +0 -0
  159. /package/{build-tsc-cjs → cjs}/lru.js +0 -0
  160. /package/{build-tsc → cjs}/mock/index.d.ts +0 -0
  161. /package/{build-tsc-cjs → cjs}/mock/index.js +0 -0
  162. /package/{build-tsc → cjs}/mock/mockHttp.d.ts +0 -0
  163. /package/{build-tsc-cjs → cjs}/mock/mockHttp.js +0 -0
  164. /package/{build-tsc → cjs}/mock/mockWs.d.ts +0 -0
  165. /package/{build-tsc-cjs → cjs}/mock/mockWs.js +0 -0
  166. /package/{build-tsc → cjs}/mock/types.d.ts +0 -0
  167. /package/{build-tsc-cjs → cjs}/mock/types.js +0 -0
  168. /package/{build/cjs → cjs}/package.json +0 -0
  169. /package/{build-tsc → cjs}/packageDetect.d.ts +0 -0
  170. /package/{build/cjs → cjs}/packageDetect.js +0 -0
  171. /package/{build-tsc → cjs}/packageInfo.d.ts +0 -0
  172. /package/{build-tsc-cjs → cjs}/packageInfo.js +0 -0
  173. /package/{build-tsc → cjs}/types.d.ts +0 -0
  174. /package/{build-tsc-cjs → cjs}/types.js +0 -0
  175. /package/{build-tsc → cjs}/ws/errors.d.ts +0 -0
  176. /package/{build-tsc-cjs → cjs}/ws/errors.js +0 -0
  177. /package/{build-tsc → cjs}/ws/index.d.ts +0 -0
  178. /package/{build-tsc-cjs → cjs}/ws/index.js +0 -0
  179. /package/{build/cjs/coder → coder}/error.d.ts +0 -0
  180. /package/{build-tsc-esm/coder → coder}/error.js +0 -0
  181. /package/{build/cjs/coder → coder}/index.d.ts +0 -0
  182. /package/{build-tsc-esm/coder → coder}/index.js +0 -0
  183. /package/{build/cjs/defaults.d.ts → defaults.d.ts} +0 -0
  184. /package/{build-tsc-esm/defaults.js → defaults.js} +0 -0
  185. /package/{build/cjs/http → http}/index.d.ts +0 -0
  186. /package/{build-tsc-esm/http → http}/index.js +0 -0
  187. /package/{build/cjs/http → http}/types.d.ts +0 -0
  188. /package/{build-tsc-esm/http → http}/types.js +0 -0
  189. /package/{build/cjs/index.d.ts → index.d.ts} +0 -0
  190. /package/{build-tsc-esm/index.js → index.js} +0 -0
  191. /package/{build/cjs/lru.d.ts → lru.d.ts} +0 -0
  192. /package/{build-tsc-esm/lru.js → lru.js} +0 -0
  193. /package/{build/cjs/mock → mock}/index.d.ts +0 -0
  194. /package/{build-tsc-esm/mock → mock}/index.js +0 -0
  195. /package/{build/cjs/mock → mock}/mockHttp.d.ts +0 -0
  196. /package/{build-tsc-esm/mock → mock}/mockHttp.js +0 -0
  197. /package/{build/cjs/mock → mock}/mockWs.d.ts +0 -0
  198. /package/{build-tsc-esm/mock → mock}/mockWs.js +0 -0
  199. /package/{build/cjs/mock → mock}/types.d.ts +0 -0
  200. /package/{build-tsc-esm/mock → mock}/types.js +0 -0
  201. /package/{build/cjs/packageDetect.d.ts → packageDetect.d.ts} +0 -0
  202. /package/{build-tsc-esm/packageDetect.js → packageDetect.js} +0 -0
  203. /package/{build/cjs/packageInfo.d.ts → packageInfo.d.ts} +0 -0
  204. /package/{build-tsc-esm/packageInfo.js → packageInfo.js} +0 -0
  205. /package/{build/cjs/types.d.ts → types.d.ts} +0 -0
  206. /package/{build-tsc-esm/types.js → types.js} +0 -0
  207. /package/{build/cjs/ws → ws}/errors.d.ts +0 -0
  208. /package/{build-tsc-esm/ws → ws}/errors.js +0 -0
  209. /package/{build/cjs/ws → ws}/index.d.ts +0 -0
  210. /package/{build-tsc-esm/ws → ws}/index.js +0 -0
@@ -1,236 +0,0 @@
1
-
2
- import type RpcError from '../coder/error.ts';
3
- import type { JsonRpcResponse, ProviderInterface, ProviderInterfaceCallback, ProviderInterfaceEmitCb, ProviderInterfaceEmitted, ProviderStats } from '../types.ts';
4
-
5
- import { logger, noop, stringify } from 'https://deno.land/x/pezkuwi/util/mod.ts';
6
- import { fetch } from 'https://deno.land/x/pezkuwi/x-fetch/mod.ts';
7
-
8
- import { RpcCoder } from '../coder/index.ts';
9
- import defaults from '../defaults.ts';
10
- import { DEFAULT_CAPACITY, DEFAULT_TTL, LRUCache } from '../lru.ts';
11
-
12
- const ERROR_SUBSCRIBE = 'HTTP Provider does not have subscriptions, use WebSockets instead';
13
-
14
- const l = logger('api-http');
15
-
16
- /**
17
- * # @pezkuwi/rpc-provider
18
- *
19
- * @name HttpProvider
20
- *
21
- * @description The HTTP Provider allows sending requests using HTTP to a HTTP RPC server TCP port. It does not support subscriptions so you won't be able to listen to events such as new blocks or balance changes. It is usually preferable using the [[WsProvider]].
22
- *
23
- * @example
24
- * <BR>
25
- *
26
- * ```javascript
27
- * import Api from 'https://deno.land/x/pezkuwi/api/promise/index.ts';
28
- * import { HttpProvider } from 'https://deno.land/x/pezkuwi/rpc-provider/mod.ts';
29
- *
30
- * const provider = new HttpProvider('http://127.0.0.1:9933');
31
- * const api = new Api(provider);
32
- * ```
33
- *
34
- * @see [[WsProvider]]
35
- */
36
- export class HttpProvider implements ProviderInterface {
37
- readonly #callCache: LRUCache;
38
- readonly #cacheCapacity: number;
39
- readonly #coder: RpcCoder;
40
- readonly #endpoint: string;
41
- readonly #headers: Record<string, string>;
42
- readonly #stats: ProviderStats;
43
- readonly #ttl: number | null | undefined;
44
-
45
- /**
46
- * @param {string} endpoint The endpoint url starting with http://
47
- * @param {Record<string, string>} headers The headers provided to the underlying Http Endpoint
48
- * @param {number} [cacheCapacity] Custom size of the HttpProvider LRUCache. Defaults to `DEFAULT_CAPACITY` (1024)
49
- * @param {number} [cacheTtl] Custom TTL of the HttpProvider LRUCache. Determines how long an object can live in the cache. Defaults to `DEFAULT_TTL` (30000)
50
- */
51
- constructor (endpoint: string = defaults.HTTP_URL, headers: Record<string, string> = {}, cacheCapacity?: number, cacheTtl?: number | null) {
52
- if (!/^(https|http):\/\//.test(endpoint)) {
53
- throw new Error(`Endpoint should start with 'http://' or 'https://', received '${endpoint}'`);
54
- }
55
-
56
- this.#coder = new RpcCoder();
57
- this.#endpoint = endpoint;
58
- this.#headers = headers;
59
- this.#cacheCapacity = cacheCapacity === 0 ? 0 : cacheCapacity || DEFAULT_CAPACITY;
60
-
61
- const ttl = cacheTtl === undefined ? DEFAULT_TTL : cacheTtl;
62
-
63
- this.#callCache = new LRUCache(cacheCapacity === 0 ? 0 : cacheCapacity || DEFAULT_CAPACITY, ttl);
64
- this.#ttl = cacheTtl;
65
-
66
- this.#stats = {
67
- active: { requests: 0, subscriptions: 0 },
68
- total: { bytesRecv: 0, bytesSent: 0, cached: 0, errors: 0, requests: 0, subscriptions: 0, timeout: 0 }
69
- };
70
- }
71
-
72
- /**
73
- * @summary `true` when this provider supports subscriptions
74
- */
75
- public get hasSubscriptions (): boolean {
76
- return !!false;
77
- }
78
-
79
- /**
80
- * @description Returns a clone of the object
81
- */
82
- public clone (): HttpProvider {
83
- return new HttpProvider(this.#endpoint, this.#headers);
84
- }
85
-
86
- /**
87
- * @description Manually connect from the connection
88
- */
89
- public async connect (): Promise<void> {
90
- // noop
91
- }
92
-
93
- /**
94
- * @description Manually disconnect from the connection
95
- */
96
- public async disconnect (): Promise<void> {
97
- // noop
98
- }
99
-
100
- /**
101
- * @description Returns the connection stats
102
- */
103
- public get stats (): ProviderStats {
104
- return this.#stats;
105
- }
106
-
107
- /**
108
- * @description Returns the connection stats
109
- */
110
- public get ttl (): number | null | undefined {
111
- return this.#ttl;
112
- }
113
-
114
- /**
115
- * @summary `true` when this provider supports clone()
116
- */
117
- public get isClonable (): boolean {
118
- return !!true;
119
- }
120
-
121
- /**
122
- * @summary Whether the node is connected or not.
123
- * @return {boolean} true if connected
124
- */
125
- public get isConnected (): boolean {
126
- return !!true;
127
- }
128
-
129
- /**
130
- * @summary Events are not supported with the HttpProvider, see [[WsProvider]].
131
- * @description HTTP Provider does not have 'on' emitters. WebSockets should be used instead.
132
- */
133
- public on (_type: ProviderInterfaceEmitted, _sub: ProviderInterfaceEmitCb): () => void {
134
- l.error('HTTP Provider does not have \'on\' emitters, use WebSockets instead');
135
-
136
- return noop;
137
- }
138
-
139
- /**
140
- * @summary Send HTTP POST Request with Body to configured HTTP Endpoint.
141
- */
142
- public async send <T> (method: string, params: unknown[], isCacheable?: boolean): Promise<T> {
143
- this.#stats.total.requests++;
144
-
145
- const [, body] = this.#coder.encodeJson(method, params);
146
-
147
- if (this.#cacheCapacity === 0) {
148
- return this.#send(body);
149
- }
150
-
151
- const cacheKey = isCacheable ? `${method}::${stringify(params)}` : '';
152
- let resultPromise: Promise<T> | null = isCacheable
153
- ? this.#callCache.get(cacheKey)
154
- : null;
155
-
156
- if (!resultPromise) {
157
- resultPromise = this.#send(body);
158
-
159
- if (isCacheable) {
160
- this.#callCache.set(cacheKey, resultPromise);
161
- }
162
- } else {
163
- this.#stats.total.cached++;
164
- }
165
-
166
- return resultPromise;
167
- }
168
-
169
- async #send <T> (body: string): Promise<T> {
170
- this.#stats.active.requests++;
171
- this.#stats.total.bytesSent += body.length;
172
-
173
- try {
174
- const response = await fetch(this.#endpoint, {
175
- body,
176
- headers: {
177
- Accept: 'application/json',
178
- 'Content-Length': `${body.length}`,
179
- 'Content-Type': 'application/json',
180
- ...this.#headers
181
- },
182
- method: 'POST'
183
- });
184
-
185
- if (!response.ok) {
186
- throw new Error(`[${response.status}]: ${response.statusText}`);
187
- }
188
-
189
- const result = await response.text();
190
-
191
- this.#stats.total.bytesRecv += result.length;
192
-
193
- const decoded = this.#coder.decodeResponse(JSON.parse(result) as JsonRpcResponse<T>);
194
-
195
- this.#stats.active.requests--;
196
-
197
- return decoded;
198
- } catch (e) {
199
- this.#stats.active.requests--;
200
- this.#stats.total.errors++;
201
-
202
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
203
- const { method, params } = JSON.parse(body);
204
-
205
- const rpcError: RpcError = e as RpcError;
206
-
207
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
208
- const failedRequest = `\nFailed HTTP Request: ${JSON.stringify({ method, params })}`;
209
-
210
- // Provide HTTP Request alongside the error
211
- rpcError.message = `${rpcError.message}${failedRequest}`;
212
-
213
- throw rpcError;
214
- }
215
- }
216
-
217
- /**
218
- * @summary Subscriptions are not supported with the HttpProvider, see [[WsProvider]].
219
- */
220
- // eslint-disable-next-line @typescript-eslint/require-await
221
- public async subscribe (_types: string, _method: string, _params: unknown[], _cb: ProviderInterfaceCallback): Promise<number> {
222
- l.error(ERROR_SUBSCRIBE);
223
-
224
- throw new Error(ERROR_SUBSCRIBE);
225
- }
226
-
227
- /**
228
- * @summary Subscriptions are not supported with the HttpProvider, see [[WsProvider]].
229
- */
230
- // eslint-disable-next-line @typescript-eslint/require-await
231
- public async unsubscribe (_type: string, _method: string, _id: number): Promise<boolean> {
232
- l.error(ERROR_SUBSCRIBE);
233
-
234
- throw new Error(ERROR_SUBSCRIBE);
235
- }
236
- }
@@ -1,9 +0,0 @@
1
-
2
- import type { Logger } from 'https://deno.land/x/pezkuwi/util/types.ts';
3
- import type { RpcCoder } from '../coder/index.ts';
4
-
5
- export interface HttpState {
6
- coder: RpcCoder;
7
- endpoint: string;
8
- l: Logger;
9
- }
@@ -1,4 +0,0 @@
1
-
2
- import './packageDetect.ts';
3
-
4
- export * from './bundle.ts';
package/build-deno/lru.ts DELETED
@@ -1,189 +0,0 @@
1
-
2
-
3
- export const DEFAULT_CAPACITY = 1024;
4
- export const DEFAULT_TTL = 30000; // 30 seconds
5
- const MAX_TTL = 1800_000; // 30 minutes
6
-
7
- const DISABLED_TTL = 31_536_000_000;
8
-
9
- class LRUNode {
10
- readonly key: string;
11
- #expires: number;
12
- #ttl: number;
13
- readonly createdAt: number;
14
-
15
- public next: LRUNode;
16
- public prev: LRUNode;
17
-
18
- constructor (key: string, ttl: number) {
19
- this.key = key;
20
- this.#ttl = ttl;
21
- this.#expires = Date.now() + ttl;
22
- this.createdAt = Date.now();
23
- this.next = this.prev = this;
24
- }
25
-
26
- public refresh (): void {
27
- this.#expires = Date.now() + this.#ttl;
28
- }
29
-
30
- public get expiry (): number {
31
- return this.#expires;
32
- }
33
- }
34
-
35
- export class LRUCache {
36
- readonly capacity: number;
37
-
38
- readonly #data = new Map<string, unknown>();
39
- readonly #refs = new Map<string, LRUNode>();
40
-
41
- #length = 0;
42
- #head: LRUNode;
43
- #tail: LRUNode;
44
-
45
- readonly #ttl: number;
46
-
47
- constructor (capacity = DEFAULT_CAPACITY, ttl: number | null = DEFAULT_TTL) {
48
- // Validate capacity
49
- if (!Number.isInteger(capacity) || capacity < 0) {
50
- throw new Error(`LRUCache initialization error: 'capacity' must be a non-negative integer. Received: ${capacity}`);
51
- }
52
-
53
- // Validate ttl
54
- if (ttl !== null && (!Number.isFinite(ttl) || ttl < 0 || ttl > MAX_TTL)) {
55
- throw new Error(`LRUCache initialization error: 'ttl' must be between 0 and ${MAX_TTL} ms or null to disable. Received: ${ttl}`);
56
- }
57
-
58
- this.capacity = capacity;
59
- ttl ? this.#ttl = ttl : this.#ttl = DISABLED_TTL;
60
- this.#head = this.#tail = new LRUNode('<empty>', this.#ttl);
61
- }
62
-
63
- get ttl (): number | null {
64
- return this.#ttl;
65
- }
66
-
67
- get length (): number {
68
- return this.#length;
69
- }
70
-
71
- get lengthData (): number {
72
- return this.#data.size;
73
- }
74
-
75
- get lengthRefs (): number {
76
- return this.#refs.size;
77
- }
78
-
79
- entries (): [string, unknown][] {
80
- const keys = this.keys();
81
- const count = keys.length;
82
- const entries = new Array<[string, unknown]>(count);
83
-
84
- for (let i = 0; i < count; i++) {
85
- const key = keys[i];
86
-
87
- entries[i] = [key, this.#data.get(key)];
88
- }
89
-
90
- return entries;
91
- }
92
-
93
- keys (): string[] {
94
- const keys: string[] = [];
95
-
96
- if (this.#length) {
97
- let curr = this.#head;
98
-
99
- while (curr !== this.#tail) {
100
- keys.push(curr.key);
101
- curr = curr.next;
102
- }
103
-
104
- keys.push(curr.key);
105
- }
106
-
107
- return keys;
108
- }
109
-
110
- get <T> (key: string): T | null {
111
- const data = this.#data.get(key);
112
-
113
- if (data) {
114
- this.#toHead(key);
115
-
116
- // Evict TTL once data is refreshed
117
- this.#evictTTL();
118
-
119
- return data as T;
120
- }
121
-
122
- this.#evictTTL();
123
-
124
- return null;
125
- }
126
-
127
- set <T> (key: string, value: T): void {
128
- if (this.#data.has(key)) {
129
- this.#toHead(key);
130
- } else {
131
- const node = new LRUNode(key, this.#ttl);
132
-
133
- this.#refs.set(node.key, node);
134
-
135
- if (this.length === 0) {
136
- this.#head = this.#tail = node;
137
- } else {
138
- this.#head.prev = node;
139
- node.next = this.#head;
140
- this.#head = node;
141
- }
142
-
143
- if (this.#length === this.capacity) {
144
- this.#data.delete(this.#tail.key);
145
- this.#refs.delete(this.#tail.key);
146
-
147
- this.#tail = this.#tail.prev;
148
- this.#tail.next = this.#head;
149
- } else {
150
- this.#length += 1;
151
- }
152
- }
153
-
154
- // Evict TTL once data is refreshed or added
155
- this.#evictTTL();
156
-
157
- this.#data.set(key, value);
158
- }
159
-
160
- #evictTTL () {
161
- // Find last node to keep
162
- // traverse map to find the expired nodes
163
- while (this.#tail.expiry && this.#tail.expiry < Date.now() && this.#length > 0) {
164
- this.#refs.delete(this.#tail.key);
165
- this.#data.delete(this.#tail.key);
166
- this.#length -= 1;
167
- this.#tail = this.#tail.prev;
168
- this.#tail.next = this.#head;
169
- }
170
-
171
- if (this.#length === 0) {
172
- this.#head = this.#tail = new LRUNode('<empty>', this.#ttl);
173
- }
174
- }
175
-
176
- #toHead (key: string): void {
177
- const ref = this.#refs.get(key);
178
-
179
- if (ref && ref !== this.#head) {
180
- ref.refresh();
181
- ref.prev.next = ref.next;
182
- ref.next.prev = ref.prev;
183
- ref.next = this.#head;
184
-
185
- this.#head.prev = ref;
186
- this.#head = ref;
187
- }
188
- }
189
- }
@@ -1,257 +0,0 @@
1
-
2
- /* eslint-disable camelcase */
3
-
4
- import type { Header } from 'https://deno.land/x/pezkuwi/types/interfaces/index.ts';
5
- import type { Codec, Registry } from 'https://deno.land/x/pezkuwi/types/types/index.ts';
6
- import type { ProviderInterface, ProviderInterfaceEmitCb, ProviderInterfaceEmitted } from '../types.ts';
7
- import type { MockStateDb, MockStateSubscriptionCallback, MockStateSubscriptions } from './types.ts';
8
-
9
- import { EventEmitter } from 'https://esm.sh/eventemitter3@5.0.1';
10
-
11
- import { createTestKeyring } from 'https://deno.land/x/pezkuwi/keyring/testing.ts';
12
- import { decorateStorage, Metadata } from 'https://deno.land/x/pezkuwi/types/mod.ts';
13
- import jsonrpc from 'https://deno.land/x/pezkuwi/types/interfaces/jsonrpc.ts';
14
- import rpcHeader from 'https://deno.land/x/pezkuwi/json/Header.004.json' with { type: 'json' };
15
- import rpcSignedBlock from 'https://deno.land/x/pezkuwi/json/SignedBlock.004.immortal.json' with { type: 'json' };
16
- import rpcMetadata from 'https://deno.land/x/pezkuwi/types-support/metadata/static-bizinikiwi.ts';
17
- import { BN, bnToU8a, logger, u8aToHex } from 'https://deno.land/x/pezkuwi/util/mod.ts';
18
- import { randomAsU8a } from 'https://deno.land/x/pezkuwi/util-crypto/mod.ts';
19
-
20
- const INTERVAL = 1000;
21
- const SUBSCRIPTIONS: string[] = Array.prototype.concat.apply(
22
- [],
23
- Object.values(jsonrpc).map((section): string[] =>
24
- Object
25
- .values(section)
26
- .filter(({ isSubscription }) => isSubscription)
27
- .map(({ jsonrpc }) => jsonrpc)
28
- .concat('chain_subscribeNewHead')
29
- )
30
- ) as string[];
31
-
32
- const keyring = createTestKeyring({ type: 'ed25519' });
33
- const l = logger('api-mock');
34
-
35
- /**
36
- * A mock provider mainly used for testing.
37
- * @return {ProviderInterface} The mock provider
38
- * @internal
39
- */
40
- export class MockProvider implements ProviderInterface {
41
- private db: MockStateDb = {};
42
-
43
- private emitter = new EventEmitter();
44
-
45
- private intervalId?: ReturnType<typeof setInterval> | null;
46
-
47
- public isUpdating = true;
48
-
49
- private registry: Registry;
50
-
51
- private prevNumber = new BN(-1);
52
-
53
- private requests: Record<string, (...params: any[]) => unknown> = {
54
- // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
55
- chain_getBlock: () => this.registry.createType('SignedBlock', rpcSignedBlock.result).toJSON(),
56
- chain_getBlockHash: () => '0x1234000000000000000000000000000000000000000000000000000000000000',
57
- // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
58
- chain_getFinalizedHead: () => this.registry.createType('Header', rpcHeader.result).hash,
59
- // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
60
- chain_getHeader: () => this.registry.createType('Header', rpcHeader.result).toJSON(),
61
- rpc_methods: () => this.registry.createType('RpcMethods').toJSON(),
62
- state_getKeys: () => [],
63
- state_getKeysPaged: () => [],
64
- state_getMetadata: () => rpcMetadata,
65
- state_getRuntimeVersion: () => this.registry.createType('RuntimeVersion').toHex(),
66
- state_getStorage: (storage: MockStateDb, [key]: string[]) => u8aToHex(storage[key]),
67
- system_chain: () => 'mockChain',
68
- system_health: () => ({}),
69
- system_name: () => 'mockClient',
70
- system_properties: () => ({ ss58Format: 42 }),
71
- system_upgradedToTripleRefCount: () => this.registry.createType('bool', true),
72
- system_version: () => '9.8.7',
73
- // eslint-disable-next-line @typescript-eslint/no-unsafe-return, sort-keys
74
- dev_echo: (_, params: any) => params
75
- };
76
-
77
- public subscriptions: MockStateSubscriptions = SUBSCRIPTIONS.reduce((subs, name): MockStateSubscriptions => {
78
- subs[name] = {
79
- callbacks: {},
80
- lastValue: null
81
- };
82
-
83
- return subs;
84
- }, ({} as MockStateSubscriptions));
85
-
86
- private subscriptionId = 0;
87
-
88
- private subscriptionMap: Record<number, string> = {};
89
-
90
- constructor (registry: Registry) {
91
- this.registry = registry;
92
-
93
- this.init();
94
- }
95
-
96
- public get hasSubscriptions (): boolean {
97
- return !!true;
98
- }
99
-
100
- public clone (): MockProvider {
101
- throw new Error('Unimplemented');
102
- }
103
-
104
- public async connect (): Promise<void> {
105
- // noop
106
- }
107
-
108
- // eslint-disable-next-line @typescript-eslint/require-await
109
- public async disconnect (): Promise<void> {
110
- if (this.intervalId) {
111
- clearInterval(this.intervalId);
112
- this.intervalId = null;
113
- }
114
- }
115
-
116
- public get isClonable (): boolean {
117
- return !!false;
118
- }
119
-
120
- public get isConnected (): boolean {
121
- return !!true;
122
- }
123
-
124
- public on (type: ProviderInterfaceEmitted, sub: ProviderInterfaceEmitCb): () => void {
125
- this.emitter.on(type, sub);
126
-
127
- return (): void => {
128
- this.emitter.removeListener(type, sub);
129
- };
130
- }
131
-
132
- // eslint-disable-next-line @typescript-eslint/require-await
133
- public async send <T = any> (method: string, params: unknown[]): Promise<T> {
134
- l.debug(() => ['send', method, params]);
135
-
136
- if (!this.requests[method]) {
137
- throw new Error(`provider.send: Invalid method '${method}'`);
138
- }
139
-
140
- return this.requests[method](this.db, params) as T;
141
- }
142
-
143
- // eslint-disable-next-line @typescript-eslint/require-await
144
- public async subscribe (_type: string, method: string, ...params: unknown[]): Promise<number> {
145
- l.debug(() => ['subscribe', method, params]);
146
-
147
- if (!this.subscriptions[method]) {
148
- throw new Error(`provider.subscribe: Invalid method '${method}'`);
149
- }
150
-
151
- const callback = params.pop() as MockStateSubscriptionCallback;
152
- const id = ++this.subscriptionId;
153
-
154
- this.subscriptions[method].callbacks[id] = callback;
155
- this.subscriptionMap[id] = method;
156
-
157
- if (this.subscriptions[method].lastValue !== null) {
158
- callback(null, this.subscriptions[method].lastValue);
159
- }
160
-
161
- return id;
162
- }
163
-
164
- // eslint-disable-next-line @typescript-eslint/require-await
165
- public async unsubscribe (_type: string, _method: string, id: number): Promise<boolean> {
166
- const sub = this.subscriptionMap[id];
167
-
168
- l.debug(() => ['unsubscribe', id, sub]);
169
-
170
- if (!sub) {
171
- throw new Error(`Unable to find subscription for ${id}`);
172
- }
173
-
174
- delete this.subscriptionMap[id];
175
- delete this.subscriptions[sub].callbacks[id];
176
-
177
- return true;
178
- }
179
-
180
- private init (): void {
181
- const emitEvents: ProviderInterfaceEmitted[] = ['connected', 'disconnected'];
182
- let emitIndex = 0;
183
- let newHead = this.makeBlockHeader();
184
- let counter = -1;
185
-
186
- const metadata = new Metadata(this.registry, rpcMetadata);
187
-
188
- this.registry.setMetadata(metadata);
189
-
190
- const query = decorateStorage(this.registry, metadata.asLatest, metadata.version);
191
-
192
- // Do something every 1 seconds
193
- this.intervalId = setInterval((): void => {
194
- if (!this.isUpdating) {
195
- return;
196
- }
197
-
198
- // create a new header (next block)
199
- newHead = this.makeBlockHeader();
200
-
201
- // increment the balances and nonce for each account
202
- keyring.getPairs().forEach(({ publicKey }, index): void => {
203
- this.setStateBn(query['system']['account'](publicKey), newHead.number.toBn().addn(index));
204
- });
205
-
206
- // set the timestamp for the current block
207
- this.setStateBn(query['timestamp']['now'](), Math.floor(Date.now() / 1000));
208
- this.updateSubs('chain_subscribeNewHead', newHead);
209
-
210
- // We emit connected/disconnected at intervals
211
- if (++counter % 2 === 1) {
212
- if (++emitIndex === emitEvents.length) {
213
- emitIndex = 0;
214
- }
215
-
216
- this.emitter.emit(emitEvents[emitIndex]);
217
- }
218
- }, INTERVAL);
219
- }
220
-
221
- private makeBlockHeader (): Header {
222
- const blockNumber = this.prevNumber.addn(1);
223
- const header = this.registry.createType('Header', {
224
- digest: {
225
- logs: []
226
- },
227
- extrinsicsRoot: randomAsU8a(),
228
- number: blockNumber,
229
- parentHash: blockNumber.isZero()
230
- ? new Uint8Array(32)
231
- : bnToU8a(this.prevNumber, { bitLength: 256, isLe: false }),
232
- stateRoot: bnToU8a(blockNumber, { bitLength: 256, isLe: false })
233
- });
234
-
235
- this.prevNumber = blockNumber;
236
-
237
- return header as unknown as Header;
238
- }
239
-
240
- private setStateBn (key: Uint8Array, value: BN | number): void {
241
- this.db[u8aToHex(key)] = bnToU8a(value, { bitLength: 64, isLe: true });
242
- }
243
-
244
- private updateSubs (method: string, value: Codec): void {
245
- this.subscriptions[method].lastValue = value;
246
-
247
- Object
248
- .values(this.subscriptions[method].callbacks)
249
- .forEach((cb): void => {
250
- try {
251
- cb(null, value.toJSON());
252
- } catch (error) {
253
- l.error(`Error on '${method}' subscription`, error);
254
- }
255
- });
256
- }
257
- }