@ckb-ccc/core 0.0.16-alpha.1 → 0.0.16-alpha.3

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 CHANGED
@@ -1,5 +1,17 @@
1
1
  # @ckb-ccc/core
2
2
 
3
+ ## 0.0.16-alpha.3
4
+
5
+ ### Patch Changes
6
+
7
+ - [#72](https://github.com/ckb-ecofund/ccc/pull/72) [`a3d5359`](https://github.com/ckb-ecofund/ccc/commit/a3d53595f6dd11f2f59cdf0086b3d7ce558a2fdd) Thanks [@Hanssen0](https://github.com/Hanssen0)! - fix(core): reopen websocket
8
+
9
+ ## 0.0.16-alpha.2
10
+
11
+ ### Patch Changes
12
+
13
+ - [#70](https://github.com/ckb-ecofund/ccc/pull/70) [`acfc050`](https://github.com/ckb-ecofund/ccc/commit/acfc0502cd6beb48b9310dec8411dcd630507366) Thanks [@Hanssen0](https://github.com/Hanssen0)! - fix(core): websocket transport
14
+
3
15
  ## 0.0.16-alpha.1
4
16
 
5
17
  ### Patch Changes
@@ -4,6 +4,7 @@ export declare class TransportWebSocket implements Transport {
4
4
  private readonly timeout;
5
5
  private ongoing;
6
6
  private socket?;
7
+ private openSocket?;
7
8
  constructor(url: string, timeout?: number);
8
9
  request(data: JsonRpcPayload): Promise<unknown>;
9
10
  }
@@ -1 +1 @@
1
- {"version":3,"file":"webSocket.d.ts","sourceRoot":"","sources":["../../../src/client/transports/webSocket.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3D,qBAAa,kBAAmB,YAAW,SAAS;IAYhD,OAAO,CAAC,QAAQ,CAAC,GAAG;IACpB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAZ1B,OAAO,CAAC,OAAO,CAOD;IACd,OAAO,CAAC,MAAM,CAAC,CAAqB;gBAGjB,GAAG,EAAE,MAAM,EACX,OAAO,SAAQ;IAGlC,OAAO,CAAC,IAAI,EAAE,cAAc;CAmE7B"}
1
+ {"version":3,"file":"webSocket.d.ts","sourceRoot":"","sources":["../../../src/client/transports/webSocket.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3D,qBAAa,kBAAmB,YAAW,SAAS;IAahD,OAAO,CAAC,QAAQ,CAAC,GAAG;IACpB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAb1B,OAAO,CAAC,OAAO,CAOD;IACd,OAAO,CAAC,MAAM,CAAC,CAAY;IAC3B,OAAO,CAAC,UAAU,CAAC,CAAqB;gBAGrB,GAAG,EAAE,MAAM,EACX,OAAO,SAAQ;IAGlC,OAAO,CAAC,IAAI,EAAE,cAAc;CAkF7B"}
@@ -6,9 +6,12 @@ export class TransportWebSocket {
6
6
  this.ongoing = new Map();
7
7
  }
8
8
  request(data) {
9
- const socket = (this.socket ?? Promise.resolve(undefined)).then((existed) => {
10
- if (existed && existed.readyState === existed.OPEN) {
11
- return existed;
9
+ const socket = (() => {
10
+ if (this.socket &&
11
+ this.socket.readyState !== this.socket.CLOSING &&
12
+ this.socket.readyState !== this.socket.CLOSED &&
13
+ this.openSocket) {
14
+ return this.openSocket;
12
15
  }
13
16
  const socket = new WebSocket(this.url);
14
17
  const onMessage = ({ data }) => {
@@ -20,40 +23,50 @@ export class TransportWebSocket {
20
23
  if (!req) {
21
24
  return;
22
25
  }
23
- clearTimeout(req[2]);
26
+ const [resolve, _, timeout] = req;
27
+ clearTimeout(timeout);
24
28
  this.ongoing.delete(res.id);
25
- req[0](res);
29
+ resolve(res);
26
30
  };
27
31
  const onClose = () => {
28
- this.socket = undefined;
29
- this.ongoing.forEach(([_, onError]) => onError(new Error("Connection closed")));
32
+ this.ongoing.forEach(([_, reject, timeout]) => {
33
+ clearTimeout(timeout);
34
+ reject(new Error("Connection closed"));
35
+ });
30
36
  this.ongoing.clear();
31
37
  };
32
38
  socket.onclose = onClose;
33
39
  socket.onerror = onClose;
34
40
  socket.onmessage = onMessage;
35
- this.socket = new Promise((resolve) => {
41
+ this.socket = socket;
42
+ this.openSocket = new Promise((resolve) => {
36
43
  if (socket.readyState === socket.OPEN) {
37
- resolve(undefined);
44
+ resolve(socket);
38
45
  }
39
46
  else {
40
- socket.onopen = resolve;
47
+ socket.onopen = () => {
48
+ resolve(socket);
49
+ };
41
50
  }
42
- }).then(() => socket);
43
- return this.socket;
44
- });
51
+ });
52
+ return this.openSocket;
53
+ })();
45
54
  return new Promise((resolve, reject) => {
46
- this.ongoing.set(data.id, [
55
+ const req = [
47
56
  resolve,
48
57
  reject,
49
58
  setTimeout(() => {
59
+ this.ongoing.delete(data.id);
50
60
  socket.then((socket) => socket.close());
51
61
  reject(new Error("Request timeout"));
52
62
  }, this.timeout),
53
- ]);
63
+ ];
64
+ this.ongoing.set(data.id, req);
54
65
  socket.then((socket) => {
55
66
  if (socket.readyState === socket.CLOSED ||
56
67
  socket.readyState === socket.CLOSING) {
68
+ clearTimeout(req[2]);
69
+ this.ongoing.delete(data.id);
57
70
  reject(new Error("Connection closed"));
58
71
  }
59
72
  else {
@@ -4,6 +4,7 @@ export declare class TransportWebSocket implements Transport {
4
4
  private readonly timeout;
5
5
  private ongoing;
6
6
  private socket?;
7
+ private openSocket?;
7
8
  constructor(url: string, timeout?: number);
8
9
  request(data: JsonRpcPayload): Promise<unknown>;
9
10
  }
@@ -1 +1 @@
1
- {"version":3,"file":"webSocket.d.ts","sourceRoot":"","sources":["../../../src/client/transports/webSocket.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3D,qBAAa,kBAAmB,YAAW,SAAS;IAYhD,OAAO,CAAC,QAAQ,CAAC,GAAG;IACpB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAZ1B,OAAO,CAAC,OAAO,CAOD;IACd,OAAO,CAAC,MAAM,CAAC,CAAqB;gBAGjB,GAAG,EAAE,MAAM,EACX,OAAO,SAAQ;IAGlC,OAAO,CAAC,IAAI,EAAE,cAAc;CAmE7B"}
1
+ {"version":3,"file":"webSocket.d.ts","sourceRoot":"","sources":["../../../src/client/transports/webSocket.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3D,qBAAa,kBAAmB,YAAW,SAAS;IAahD,OAAO,CAAC,QAAQ,CAAC,GAAG;IACpB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAb1B,OAAO,CAAC,OAAO,CAOD;IACd,OAAO,CAAC,MAAM,CAAC,CAAY;IAC3B,OAAO,CAAC,UAAU,CAAC,CAAqB;gBAGrB,GAAG,EAAE,MAAM,EACX,OAAO,SAAQ;IAGlC,OAAO,CAAC,IAAI,EAAE,cAAc;CAkF7B"}
@@ -12,9 +12,12 @@ class TransportWebSocket {
12
12
  this.ongoing = new Map();
13
13
  }
14
14
  request(data) {
15
- const socket = (this.socket ?? Promise.resolve(undefined)).then((existed) => {
16
- if (existed && existed.readyState === existed.OPEN) {
17
- return existed;
15
+ const socket = (() => {
16
+ if (this.socket &&
17
+ this.socket.readyState !== this.socket.CLOSING &&
18
+ this.socket.readyState !== this.socket.CLOSED &&
19
+ this.openSocket) {
20
+ return this.openSocket;
18
21
  }
19
22
  const socket = new isomorphic_ws_1.default(this.url);
20
23
  const onMessage = ({ data }) => {
@@ -26,40 +29,50 @@ class TransportWebSocket {
26
29
  if (!req) {
27
30
  return;
28
31
  }
29
- clearTimeout(req[2]);
32
+ const [resolve, _, timeout] = req;
33
+ clearTimeout(timeout);
30
34
  this.ongoing.delete(res.id);
31
- req[0](res);
35
+ resolve(res);
32
36
  };
33
37
  const onClose = () => {
34
- this.socket = undefined;
35
- this.ongoing.forEach(([_, onError]) => onError(new Error("Connection closed")));
38
+ this.ongoing.forEach(([_, reject, timeout]) => {
39
+ clearTimeout(timeout);
40
+ reject(new Error("Connection closed"));
41
+ });
36
42
  this.ongoing.clear();
37
43
  };
38
44
  socket.onclose = onClose;
39
45
  socket.onerror = onClose;
40
46
  socket.onmessage = onMessage;
41
- this.socket = new Promise((resolve) => {
47
+ this.socket = socket;
48
+ this.openSocket = new Promise((resolve) => {
42
49
  if (socket.readyState === socket.OPEN) {
43
- resolve(undefined);
50
+ resolve(socket);
44
51
  }
45
52
  else {
46
- socket.onopen = resolve;
53
+ socket.onopen = () => {
54
+ resolve(socket);
55
+ };
47
56
  }
48
- }).then(() => socket);
49
- return this.socket;
50
- });
57
+ });
58
+ return this.openSocket;
59
+ })();
51
60
  return new Promise((resolve, reject) => {
52
- this.ongoing.set(data.id, [
61
+ const req = [
53
62
  resolve,
54
63
  reject,
55
64
  setTimeout(() => {
65
+ this.ongoing.delete(data.id);
56
66
  socket.then((socket) => socket.close());
57
67
  reject(new Error("Request timeout"));
58
68
  }, this.timeout),
59
- ]);
69
+ ];
70
+ this.ongoing.set(data.id, req);
60
71
  socket.then((socket) => {
61
72
  if (socket.readyState === socket.CLOSED ||
62
73
  socket.readyState === socket.CLOSING) {
74
+ clearTimeout(req[2]);
75
+ this.ongoing.delete(data.id);
63
76
  reject(new Error("Connection closed"));
64
77
  }
65
78
  else {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ckb-ccc/core",
3
- "version": "0.0.16-alpha.1",
3
+ "version": "0.0.16-alpha.3",
4
4
  "description": "Core of CCC - CKBer's Codebase",
5
5
  "author": "Hanssen0 <hanssen0@hanssen0.com>",
6
6
  "license": "MIT",
@@ -10,7 +10,8 @@ export class TransportWebSocket implements Transport {
10
10
  ReturnType<typeof setTimeout>,
11
11
  ]
12
12
  > = new Map();
13
- private socket?: Promise<WebSocket>;
13
+ private socket?: WebSocket;
14
+ private openSocket?: Promise<WebSocket>;
14
15
 
15
16
  constructor(
16
17
  private readonly url: string,
@@ -18,65 +19,80 @@ export class TransportWebSocket implements Transport {
18
19
  ) {}
19
20
 
20
21
  request(data: JsonRpcPayload) {
21
- const socket = (this.socket ?? Promise.resolve(undefined)).then(
22
- (existed) => {
23
- if (existed && existed.readyState === existed.OPEN) {
24
- return existed;
22
+ const socket = (() => {
23
+ if (
24
+ this.socket &&
25
+ this.socket.readyState !== this.socket.CLOSING &&
26
+ this.socket.readyState !== this.socket.CLOSED &&
27
+ this.openSocket
28
+ ) {
29
+ return this.openSocket;
30
+ }
31
+ const socket = new WebSocket(this.url);
32
+ const onMessage = ({ data }: { data: string }) => {
33
+ const res = JSON.parse(data);
34
+ if (typeof res !== "object" || res === null) {
35
+ throw new Error(`Unknown response ${data}`);
25
36
  }
26
37
 
27
- const socket = new WebSocket(this.url);
28
- const onMessage = ({ data }: { data: string }) => {
29
- const res = JSON.parse(data);
30
- if (typeof res !== "object" || res === null) {
31
- throw new Error(`Unknown response ${data}`);
32
- }
33
-
34
- const req = this.ongoing.get(res.id);
35
- if (!req) {
36
- return;
37
- }
38
- clearTimeout(req[2]);
39
- this.ongoing.delete(res.id);
38
+ const req = this.ongoing.get(res.id);
39
+ if (!req) {
40
+ return;
41
+ }
42
+ const [resolve, _, timeout] = req;
43
+ clearTimeout(timeout);
44
+ this.ongoing.delete(res.id);
40
45
 
41
- req[0](res);
42
- };
43
- const onClose = () => {
44
- this.socket = undefined;
45
- this.ongoing.forEach(([_, onError]) =>
46
- onError(new Error("Connection closed")),
47
- );
48
- this.ongoing.clear();
49
- };
46
+ resolve(res);
47
+ };
48
+ const onClose = () => {
49
+ this.ongoing.forEach(([_, reject, timeout]) => {
50
+ clearTimeout(timeout);
51
+ reject(new Error("Connection closed"));
52
+ });
53
+ this.ongoing.clear();
54
+ };
50
55
 
51
- socket.onclose = onClose;
52
- socket.onerror = onClose;
53
- socket.onmessage = onMessage;
56
+ socket.onclose = onClose;
57
+ socket.onerror = onClose;
58
+ socket.onmessage = onMessage;
54
59
 
55
- this.socket = new Promise((resolve) => {
56
- if (socket.readyState === socket.OPEN) {
57
- resolve(undefined);
58
- } else {
59
- socket.onopen = resolve;
60
- }
61
- }).then(() => socket);
62
- return this.socket;
63
- },
64
- );
60
+ this.socket = socket;
61
+ this.openSocket = new Promise<WebSocket>((resolve) => {
62
+ if (socket.readyState === socket.OPEN) {
63
+ resolve(socket);
64
+ } else {
65
+ socket.onopen = () => {
66
+ resolve(socket);
67
+ };
68
+ }
69
+ });
70
+ return this.openSocket;
71
+ })();
65
72
 
66
73
  return new Promise((resolve, reject) => {
67
- this.ongoing.set(data.id, [
74
+ const req: [
75
+ (res: unknown) => unknown,
76
+ (err: unknown) => unknown,
77
+ ReturnType<typeof setTimeout>,
78
+ ] = [
68
79
  resolve,
69
80
  reject,
70
81
  setTimeout(() => {
82
+ this.ongoing.delete(data.id);
71
83
  socket.then((socket) => socket.close());
72
84
  reject(new Error("Request timeout"));
73
85
  }, this.timeout),
74
- ]);
86
+ ];
87
+ this.ongoing.set(data.id, req);
88
+
75
89
  socket.then((socket) => {
76
90
  if (
77
91
  socket.readyState === socket.CLOSED ||
78
92
  socket.readyState === socket.CLOSING
79
93
  ) {
94
+ clearTimeout(req[2]);
95
+ this.ongoing.delete(data.id);
80
96
  reject(new Error("Connection closed"));
81
97
  } else {
82
98
  socket.send(JSON.stringify(data));