Last active
March 4, 2021 13:24
-
-
Save popuguytheparrot/733f27ba79276d393b1196fadca39a70 to your computer and use it in GitHub Desktop.
ws store effector
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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}`)); |
Author
popuguytheparrot
commented
Jun 5, 2020
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment