PageSourceSearch

https://www.tweetbinder.com/public/js/socketWorker.js

js tweetbinder.com collected 2026-10-01 11:56:49 UTC 4,476 bytes, 165 lines download raw bytes

1/* NOTE:
2  This file must be in /public App folder to use Socket with
3  a Shared Worker.
4  //https://developer.mozilla.org/en-US/docs/Web/API/SharedWorker
5 */
6
7/**
8  * Logs messages
9  * @param {String} level  - Log level (uses consoles[level])
10  * @param  {...any} args - Arguments to log
11  */
12const logger = (level, ...args) => {
13  /* eslint-disable-next-line no-console */
14  const key = console[level] ? level : 'info';
15  /* eslint-disable-next-line no-console */
16  console[key]('%ctb-ui:SocketWorker', 'color: blue', ...args);
17};
18
19/**
20 * Generates a random string
21 */
22const randomString = () => Math.random().toString(36).substring(7);
23
24const defaultClientId = randomString();
25
26/**
27 * Generates a new Socket IO
28 * @param {String} token - Auth token
29 * @param {String} url -Socket URL
30 * @param {Array.<String>} rooms - Socket client rooms
31 * @param {String?} clientId -Socket clientId
32 * @param {function} handler - Function to handle socket messages
33 */
34const newSocket = (token, url, rooms = '', clientId = defaultClientId, handler) => {
35  if (!url) {
36    return null;
37  }
38
39  try {
40    logger('info', 'new-socket-rooms ', url, rooms);
41    // eslint-disable-next-line no-undef
42    importScripts(`${url}/socket.io/socket.io.js`);
43    const query = {
44      clientId,
45      ...(rooms ? { clientRooms: rooms } : {}),
46      ...(token ? { authToken: token } : {}),
47    };
48    logger('info', 'query is', query);
49
50    // eslint-disable-next-line no-undef
51    return io(url, {
52      query,
53      transports: ['websocket'],
54      reconnection: true,
55      rejectUnauthorized: false,
56    }).on('message', handler);
57  } catch (e) {
58    logger('error', e);
59    return null;
60  }
61};
62
63let socket;
64let token;
65let url;
66let clientId;
67let rooms;
68let socketPorts = []; // Connected tabs
69let socketTimeout;
70
71const end = () => {
72  if (socket) {
73    socket.close();
74  }
75  this.close();
76};
77
78const closePort = (closingPortId) => {
79  logger('info', 'close-port', closingPortId);
80  socketPorts = socketPorts.filter(({ id }) => id !== closingPortId);
81  if (!socketPorts.length) {
82    end();
83  }
84};
85
86const onmessage = (e) => {
87  const { data: tabMessage } = e;
88  logger('info', 'on-message', tabMessage);
89  let updateSocket = false;
90
91  if (tabMessage.action === 'closing') {
92    const { data: { id: closingPortId } } = tabMessage;
93    closePort(closingPortId);
94  }
95
96  // Handle message actions
97  if (tabMessage.action === 'new-options' && token !== tabMessage.data.token) {
98    // eslint-disable-next-line prefer-destructuring
99    token = tabMessage.data.token;
100    updateSocket = true;
101  }
102
103  if (tabMessage.action === 'new-options' && url !== tabMessage.data.url) {
104    // eslint-disable-next-line prefer-destructuring
105    url = tabMessage.data.url;
106    updateSocket = true;
107  }
108
109  if (tabMessage.action === 'new-options' && rooms !== tabMessage.data.rooms) {
110    // eslint-disable-next-line prefer-destructuring
111    rooms = tabMessage.data.rooms;
112    updateSocket = true;
113  }
114
115  if (tabMessage.action === 'new-options' && rooms !== tabMessage.data.clientId) {
116    // eslint-disable-next-line prefer-destructuring
117    clientId = tabMessage.data.clientId;
118    updateSocket = true;
119  }
120
121  // If socket config has changed re-connect
122  if (updateSocket) {
123    // AWAIT 0.5 secs for new messages before create socket
124    if (socketTimeout) {
125      clearTimeout(socketTimeout);
126    }
127
128    socketTimeout = setTimeout(() => {
129      if (socket) {
130        logger('info', 'close-socket');
131        socket.close();
132      }
133      logger('info', 'create-socket');
134      socket = newSocket(token, url, rooms, clientId, (message) => {
135        logger('info', 'receive-message', message);
136        socketPorts.forEach(({ port }) => port.postMessage({ action: 'message', data: message }));
137      });
138      if (!socket) {
139        return;
140      }
141
142      socket.on('connect', () => logger('info', ('connected')));
143      socket.on('error', err => logger('info', ('socket-error', err)));
144    }, 0.5 * 1000);
145  }
146};
147
148// eslint-disable-next-line no-undef
149onconnect = ({ ports }) => {
150  ports.forEach((newPort) => {
151    const portId = randomString();
152    logger('info', 'register-worker', portId);
153    logger('info', 'ports-length', socketPorts.length);
154    newPort.postMessage({
155      action: 'connected',
156      data: {
157        id: portId,
158      },
159    });
160
161    socketPorts.push({ port: newPort, id: portId });
162  });
163  // eslint-disable-next-line no-param-reassign
164  ports.forEach((port) => { port.onmessage = onmessage; });
165};

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.