Skip to content

Instantly share code, notes, and snippets.

@popuguytheparrot
Last active March 4, 2021 13:24
Show Gist options
  • Save popuguytheparrot/733f27ba79276d393b1196fadca39a70 to your computer and use it in GitHub Desktop.
Save popuguytheparrot/733f27ba79276d393b1196fadca39a70 to your computer and use it in GitHub Desktop.
ws store effector
import { createEffect, createEvent, createStore, merge } from 'effector';
import nanoid from 'nanoid';
import { request, parseObject } from 'jsonrpc-lite';
const wsURL = `ws://localhost:${process.env.WS_PORT}`;
let socket;
const awaitingMap = new Map();
function cleanSocket() {
socket.onopen = null;
socket.onclose = null;
socket.onerror = null;
socket.onmessage = null;
}
const open = createEvent('open');
const closed = createEvent('closed');
const error = createEvent('error');
const onMessage = createEvent('message');
onMessage
.map(({ data }) => JSON.parse(data))
.watch(payload => {
const {
payload: { id, result },
type
} = parseObject(payload);
const { resolve, reject } = awaitingMap.get(id);
if (type === 'error') {
reject(result);
}
awaitingMap.delete(id);
resolve(result);
});
export const fetch = createEffect('fetch', {
handler({ method, params }) {
const id = nanoid();
socket.send(request(id, method, params));
const promise = new Promise((resolve, reject) => {
awaitingMap.set(id, { resolve, reject });
});
return promise;
}
});
fetch.watch(payload => console.log(`Запрос`, payload));
fetch.done.watch(payload => console.log('Ответ на запрос', payload));
fetch.fail.watch(payload => console.log('Ошибка', payload));
export function disconnect() {
console.warn('websocket connection is disconnect');
socket.close();
}
export function connect() {
try {
console.info(`Try to connect on ${wsURL}`);
socket = new WebSocket(wsURL);
} catch (e) {
throw new Error(e.message);
}
socket.onopen = event => open(event);
socket.onclose = ({ wasClean, code, reason }) =>
closed({ wasClean, code, reason });
socket.onerror = err => error(err);
socket.onmessage = msg => onMessage(msg);
}
open.watch(() => {
console.info('connect ready');
});
closed.watch(({ code, reason }) => {
console.warn(`[close] Connection is closed, code=${code} reason=${reason}`);
});
error.watch(err => {
console.error(`[error] ${err.message}`);
});
merge([closed, error]).watch(() => cleanSocket());
const $status = createStore('closed')
.on(open, () => 'open')
.on(closed, () => 'closed')
.on(error, () => 'error');
$status.watch(state => console.log(`websocket is ${state}`));
@popuguytheparrot
Copy link
Author

import { fetch } from 'api/ws';

export const fetchDisplaysConfig = createEffect('get_displays', {
  handler(params = []) {
    return fetch({ method: 'get_displays', params });
  }
});

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment