UNPKG

telegram-mtproto

Version:
317 lines (267 loc) 9.5 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _redux = require('redux'); var _reduxAct = require('redux-act'); var _ramda = require('ramda'); var _helpers = require('../helpers'); var _newtype = require('../../newtype.h'); var _action = require('../action'); var _keyStorage = require('../../util/key-storage'); var _keyStorage2 = _interopRequireDefault(_keyStorage); var _monadT = require('../../util/monad-t'); var _bin = require('../../bin'); var _netMessage = require('../../service/networker/net-message'); var _request = require('./request'); var _request2 = _interopRequireDefault(_request); var _request3 = require('../../service/main/request'); var _request4 = _interopRequireDefault(_request3); var _configProvider = require('../../config-provider'); var _configProvider2 = _interopRequireDefault(_configProvider); require('../../task/index.h'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /* eslint-disable object-shorthand */ var initial = {}; // import { Pure, liftF } from '@safareli/free' // import { of, Left, Right } from 'apropos' // import { Maybe } from 'folktale/maybe' function trimAction(action) { return (0, _helpers.trimType)(action.type); } var progress = (() => { var idle = (0, _reduxAct.createReducer)({}, []); var current = (0, _reduxAct.createReducer)({}, []); var done = (0, _reduxAct.createReducer)({}, []); var result = (0, _reduxAct.createReducer)({ //$off [_action.API.TASK.DONE]: (state, payload) => { var apiPL = onlyAPI(payload); var newState = apiPL.reduce(reduceResults, state); return newState; } }, _monadT.KeyValue.empty()); var reducer = (0, _redux.combineReducers)({ idle, current, done, result }); function reduceResults(acc, val) { var id = val.api.apiID; var data = val.body; var init = []; var list = acc.maybeGetK(id).fold(() => init, x => x.snd()); var saved = (0, _ramda.append)(data, list); var res = acc.push([[id, saved]]); return res; } var findReq = id => req => req.requestID === id; var onlyAPI = units => units.filter(p => p.flags.api && p.api.resolved); var getReqIDs = list => list.map(req => req.requestID); function unitReduce({ idle, current, done, result }, unit) { var id = unit.api.apiID; var newIdle = idle; var newCurrent = current; var newDone = done; var find = findReq(id); var inIdle = newIdle.findIndex(find); var inCurrent = newCurrent.findIndex(find); if (inIdle > -1) { var _req = newIdle[inIdle]; newIdle = (0, _ramda.remove)(inIdle, 1, newIdle); newDone = (0, _ramda.append)(_req, newDone); } if (inCurrent > -1) { var _req2 = newCurrent[inCurrent]; newCurrent = (0, _ramda.remove)(inCurrent, 1, newCurrent); newDone = (0, _ramda.append)(_req2, newDone); } return { idle: newIdle, current: newCurrent, done: newDone, result }; } return function watcher(currentState, action) { var state = reducer(currentState, action); var { idle, current, done, result } = state; switch (trimAction(action)) { case 'api/next': { if (idle.length === 0) return state; if (current.length > 0) return state; var newNext = (0, _ramda.head)(idle); /*:: || req */ var newState = { idle: (0, _ramda.tail)(idle), current: (0, _ramda.append)(newNext, current), done, result }; return newState; } case 'api/task new': { var ids = getReqIDs(idle).concat(getReqIDs(current)); var payload = action.payload; var update = payload.filter(req => !(0, _ramda.contains)(req.requestID, ids)); var newIdle = idle.concat(update); return { idle: newIdle, current, done, result }; } case 'api/task done': { var _payload = action.payload; var apiPL = onlyAPI(_payload); var _newState = apiPL.reduce(unitReduce, state); return _newState; } default: return state; } }; })(); var uid = (0, _reduxAct.createReducer)({ //$FlowIssue [_action.MAIN.INIT]: (state, payload) => payload.uid }, ''); var ackDefault = initial; var pendingAck = (0, _reduxAct.createReducer)({ //$off [_action.NET.ACK_ADD]: (state, { dc, ack }) => { var dcAcks = state[dc] || []; var updated = [...new Set([...dcAcks, ...ack])]; return Object.assign({}, state, { [dc | 0]: updated }); }, //$off [_action.NET.ACK_DELETE]: (state, { dc, ack }) => { var dcAcks = state[dc] || []; var updated = (0, _ramda.without)(ack, dcAcks); return Object.assign({}, state, { [dc | 0]: updated }); }, //$off [_action.MAIN.RECOVERY_MODE]: (state, { halt, recovery }) => Object.assign({}, state, { [halt]: [] }) }, ackDefault); var homeDc = (0, _reduxAct.createReducer)({ //$off [_action.MAIN.STORAGE_IMPORTED]: (state, { home }) => home, //$off [_action.MAIN.DC_DETECTED]: (state, { dc }) => dc, //$FlowIssue [_action.MAIN.DC_CHANGED]: (state, { newDC }) => newDC }, 2); var dcDetected = (0, _reduxAct.createReducer)({ //$off [_action.MAIN.DC_DETECTED]: () => true, //$off [_action.MAIN.DC_REJECTED]: () => false }, false); var lastMessages = (0, _reduxAct.createReducer)({ //$off [_action.API.TASK.DONE]: (state, payload) => (0, _ramda.pipe)((0, _ramda.map)(unit => /*:: toUID( */unit.id /*:: ) */), (0, _ramda.concat)(state), (0, _ramda.takeLast)(100))(payload) }, []); var authData = (() => { var salt = (0, _reduxAct.createReducer)({ //$off [_action.MAIN.AUTH.RESOLVE]: (state, payload) => state.set(payload.dc, payload.serverSalt), //$off [_action.MAIN.STORAGE_IMPORTED]: (state, { salt }) => state.merge(salt), '[01] action carrier': (state, payload) => state.merge(payload.summary.salt), //$off [_action.MAIN.RECOVERY_MODE]: (state, { halt, recovery }) => state.remove(halt) }, (0, _keyStorage2.default)()); var auth = (0, _reduxAct.createReducer)({ //$off [_action.MAIN.STORAGE_IMPORTED]: (state, { auth }) => state.merge(auth), '[01] action carrier': (state, payload) => state.merge(payload.summary.auth), //$off [_action.MAIN.AUTH.RESOLVE]: (state, payload) => state.set(payload.dc, payload.authKey), //$off [_action.MAIN.RECOVERY_MODE]: (state, { halt, recovery }) => state.remove(halt) }, (0, _keyStorage2.default)()); var authID = (0, _reduxAct.createReducer)({ //$off [_action.MAIN.STORAGE_IMPORTED]: (state, { auth }) => state.merge((0, _ramda.map)(makeAuthID, auth)), '[01] action carrier': (state, payload //$off ) => state.merge((0, _ramda.map)(makeAuthID, payload.summary.auth)), //$off [_action.MAIN.AUTH.RESOLVE]: (state, payload) => state.set(payload.dc, payload.authKeyID), //$off [_action.MAIN.RECOVERY_MODE]: (state, { halt, recovery }) => state.remove(halt) }, (0, _keyStorage2.default)()); var makeAuthID = auth => Array.isArray(auth) ? (0, _bin.sha1BytesSync)(auth).slice(-8) : false; return { auth, salt, authID }; })(); function commandReducer(state = _monadT.KeyValue.empty(), action) { switch ((0, _helpers.trimType)(action.type)) { case 'networker/sent add': { var payload = action.payload; var apiRequests = payload.filter(msg => msg.isAPI).map(({ msg_id, requestID }) => [msg_id, requestID || '']); return state.push(apiRequests); } case 'main/recovery mode': return state; default: return state; } } var clientRequest = (0, _reduxAct.createReducer)({ //$off [_action.API.REQUEST.NEW]: (state, { netReq }) => state.push([[netReq.requestID, netReq]]) }, _monadT.KeyValue.empty()); var client = (0, _redux.combineReducers)(Object.assign({ uid, homeDc, progress, command: commandReducer, request: clientRequest, lastMessages, dcDetected }, authData, { pendingAck, status: (0, _reduxAct.createReducer)({}, {}), homeStatus: (0, _reduxAct.createReducer)({}, false) })); function statusWatch(state) { var dcList = _configProvider2.default.dcList(state.uid); var singleStatus = dc => state.auth.has(dc) && state.authID.has(dc) && state.salt.has(dc); var kv = _monadT.KeyValue.empty(); return kv.push(dcList.map(dc => [dc, singleStatus(dc)])); } function decoratedClient(state, action) { var currentState = (0, _request2.default)(client(state, action), action); var status = statusWatch(currentState); var homeStatus = status.maybeGetK(currentState.homeDc).fold(() => false, x => x.snd()); return Object.assign({}, currentState, { status, homeStatus }); } var clientReducer = (state = { ids: [] }, action) => { if (typeof action.uid !== 'string') return state; var uid = action.uid; var oldValue = state[uid]; var newValue = decoratedClient(oldValue, action); if (oldValue === newValue) return state; return Object.assign({}, state, { [uid]: newValue, ids: idsReducer(state.ids, uid) }); }; function idsReducer(state, uid) { return (0, _ramda.contains)(uid, state) ? state : (0, _ramda.append)(uid, state); } var mainReducer = (0, _redux.combineReducers)({ client: clientReducer }); exports.default = mainReducer; //# sourceMappingURL=index.js.map