UNPKG

1.58 kBJavaScriptView Raw
1import global from 'global';
2import { Channel } from '@storybook/channels';
3import { logger } from '@storybook/client-logger';
4import { isJSON, parse, stringify } from 'telejson';
5const {
6 WebSocket
7} = global;
8export class WebsocketTransport {
9 constructor({
10 url,
11 onError
12 }) {
13 this.socket = void 0;
14 this.handler = void 0;
15 this.buffer = [];
16 this.isReady = false;
17 this.connect(url, onError);
18 }
19
20 setHandler(handler) {
21 this.handler = handler;
22 }
23
24 send(event) {
25 if (!this.isReady) {
26 this.sendLater(event);
27 } else {
28 this.sendNow(event);
29 }
30 }
31
32 sendLater(event) {
33 this.buffer.push(event);
34 }
35
36 sendNow(event) {
37 const data = stringify(event, {
38 maxDepth: 15,
39 allowFunction: true
40 });
41 this.socket.send(data);
42 }
43
44 flush() {
45 const {
46 buffer
47 } = this;
48 this.buffer = [];
49 buffer.forEach(event => this.send(event));
50 }
51
52 connect(url, onError) {
53 this.socket = new WebSocket(url);
54
55 this.socket.onopen = () => {
56 this.isReady = true;
57 this.flush();
58 };
59
60 this.socket.onmessage = ({
61 data
62 }) => {
63 const event = typeof data === 'string' && isJSON(data) ? parse(data) : data;
64 this.handler(event);
65 };
66
67 this.socket.onerror = e => {
68 if (onError) {
69 onError(e);
70 }
71 };
72 }
73
74}
75export default function createChannel({
76 url,
77 async = false,
78 onError = err => logger.warn(err)
79}) {
80 const transport = new WebsocketTransport({
81 url,
82 onError
83 });
84 return new Channel({
85 transport,
86 async
87 });
88}
\No newline at end of file