lestad's notebooks

  • parseBigInt - /lestad/parsebigint
    Last edited 4 years ago
    require("effector") function parseBigInt(value, radix = 10) { let chars = value.split(""); for (let char of chars) { } return result } function expect(input, expected) { if (input !== expected) { throw new Error(`input "${input}" is not equal "${expected}"`) } } expect(parseBigInt("10", 36), BigInt(parseInt("10", 36)))
  • redux thunk promise middleware - /lestad/redux-thunk-promise-middleware
    Last edited 7 years ago
    const { createStore, applyMiddleware } = require("redux") const createThunkPromiseMiddleware = extra => ({ dispatch, getState }) => next => action => { if (typeof action === 'function') { const result = action(dispatch, getState(), extra) if (typeof result.then === 'function') { return result.then(data => { if (data && typeof data.type === 'string') { next(data) } }) } if (result && typeof result.type === 'string') { return next(result) } } return next(action) } const extra = { demo(data) { return new Promise(resolve => setTimeout(resolve, 300, data)) } } // ------ const getData = () => async (dispatch, state, { demo }) => { dispatch({ type: 'loading/1' }) const data = await demo(1) return ({ type: 'loaded/1', data }) } const promised = (data) => (dispatch, state, { demo }) => { dispatch({ type: 'loading/2' }) return demo(data) .then(result => ({ type: 'loaded/2', data: result })) } const reducer = (store, action) => { console.log(action) return store } const store = createStore(reducer, {}, applyMiddleware(createThunkPromiseMiddleware(extra))) store.dispatch(getData()) store.dispatch(promised(2)) 'sync finished';
  • Untitled - /lestad/telemessage
    Last edited 7 years ago
    const Future = require('fluture') class Sequencer { constructor(fut) { this._fut = fut } get future() { return this._fut } promise() { return this.future.promise() } } class Message extends Sequencer { static of(data) { return new Message(Future.of(data)) } // static chain(fut) { // return new Message(fut.chain(Future.of)) // } wrap(fut) { return new Message(fut) } finish(logFn) { if (logFn) { this.future.fork(logFn, logFn) } else { this.future.value(() => {}) } } catch(fn) { return this.wrap(this.future.chain(fn)) } // ===== adminRequired() { return this.wrap(this.future.map(ctx => { if (ctx.from.id !== 0) { return new Error('Restricted') } })) } reply(text) { return this.wrap(this.future.map(ctx => { ctx.reply(text) return ctx })) } /** * Resolves with Future with [result, ctx] */ then(fut) { return this.wrap( this.future.chain(ctx => fut.map(res => [res, ctx]) ) ) } map(fn) { return this.wrap( this.future.map(fn) ) } chain(fn) { return this.wrap( this.future.chain(fn) ) } chainRej(fn) { return this.wrap( this.future.chainRej(fn) ) } } class Photo { constructor(id) { this._id = id } static fetch(id) { return Future.node(done => { setTimeout(done, 300, new Photo(id)) }) } } class TelegrafDemo { constructor() { this._commands = [] } /** * @param {string} cmd * @param {ctx => void} resolver */ command(cmd, resolver) { this._commands.push({ cmd, resolver, }) } startPolling() { this._commands.forEach(({ cmd, resolver }) => { const ctx = { from: { id: 1, }, chat: { id: 12, }, reply(text) { console.log('REPLY:', text, { to: ctx.from }) } } resolver(ctx) }) } } // ===== App code ===== / const debug = (...args) => console.log('DEBUG:', ...args) const bot = new TelegrafDemo() bot.command('/foo', (ctx) => { Message.of(ctx) .adminRequired() .catch(reason => Message.of(ctx).reply(`Not allowed: ${reason.message}`).future ) .then(Photo.fetch(123)) .chainRej((ctx) => { console.log('sdsd', ctx) return Future.of(null) }) .finish(debug) }) bot.startPolling()