UNPKG

@bemedev/app-solid

Version:

Middleware between @bemedev/app-ts and solidjs

189 lines (185 loc) 5.99 kB
'use strict'; var appTs = require('@bemedev/app-ts'); var strings_js = require('@bemedev/app-ts/lib/constants/strings.js'); var constants_js = require('@bemedev/app-ts/lib/events/constants.js'); var merge_js = require('@bemedev/app-ts/lib/utils/merge.js'); var solidJs = require('solid-js'); var _default = require('./default.cjs'); var helpers = require('./helpers.cjs'); class Interpreter { #status = 'idle'; #machine; #service; #mainState; #options; interpreterOptions; get #setState() { return this.#mainState[1]; } get #state() { return this.#mainState[0]; } get #canPerform() { return this.#status === 'started' || this.#status === 'working'; } get __stateSignal() { return undefined; } #setUI = () => { this.#setState(state => { const out = { ...this.#initialState, ...state, uiThread: Object.entries({ ...this.#options?.uiThread, }).reduce((acc, [key, value]) => { acc[key] = value?.[0](); return acc; }, {}), }; return out; }); }; constructor({ machine, options: interpreterOptions, uiThread, }) { this.#machine = machine; this.interpreterOptions = interpreterOptions; this.#service = appTs.interpret(this.#machine, this.interpreterOptions); this.subscribe(next => { this.#setState(prev => merge_js.merge(prev, next)); }); if (uiThread) { if (!this.#options) this.#options = {}; this.#options.uiThread = Object.entries(uiThread).reduce((acc, [key, value]) => { acc[key] = solidJs.createSignal(value); return acc; }, {}); } const _ui = this.#options?.uiThread; this.#initialState = { context: this.#service.context, status: 'idle', value: this.#service.initialValue, event: constants_js.INIT_EVENT, uiThread: _ui ? Object.entries(_ui) .map(([key, [signal]]) => [key, signal()]) .reduce((acc, [key, value]) => { acc[key] = value; return acc; }, {}) : undefined, }; this.#mainState = solidJs.createSignal(this.#initialState); this.#setUI(); } get start() { this.#status = 'started'; return this.#service.start; } get pause() { return this.#service.pause; } get resume() { return this.#service.resume; } stop = () => { this.#status = 'stopped'; this.#service.stop(); solidJs.untrack(this.#mainState[0]); }; get subscribe() { return this.#service.subscribe; } #initialState; get send() { return this.#service.send; } sendUI = event => { if (!this.#canPerform) return; const fn = this.#options?.uiThread?.[event.type]?.[1]; const out = fn(event.payload); this.#setUI(); return out; }; state = (accessor = _default.defaultSelector, equals) => { return solidJs.createMemo(() => { const value = this.#state(); return accessor(value); }, this.#initialState, { equals }); }; watcher = (accessor) => { return (equals) => { return this.state(accessor, equals); }; }; reducer = (accessor) => { return (_accessor = _default.defaultSelector, equals) => { return this.state(state => { const step1 = accessor(state); const step2 = _accessor(step1); return step2; }, equals); }; }; context = this.reducer(state => state.context); value = this.watcher(state => state.value); status = this.watcher(state => state.status); tags = this.watcher(state => state.tags ?? []); ui = this.reducer(state => state.uiThread); hasTags = (...tags) => { const currentTags = this.state(({ tags }) => tags)(); if (!currentTags) return false; return tags.every(tag => currentTags.includes(tag)); }; /** * @deprecated * Only for testing purposes */ get __isUsedUi() { const state = this.#options?.uiThread; return !!state && Object.keys(state).length > 0; } dps = this.watcher(({ value }) => appTs.decomposeSV .low(value) .map(entry => entry.replaceAll('.', strings_js.DEFAULT_DELIMITER))); matches = (...values) => { const dps = this.dps()(); return solidJs.createMemo(() => values.every(value => dps.includes(value))); }; contains = (...values) => { const dps = this.dps()(); return solidJs.createMemo(() => values.some(value => dps.includes(value))); }; addOptions = option => { this.#options = merge_js.merge(this.#options, this.#service.addOptions(option)); this.#setUI(); return this.#options; }; provideOptions = (option) => { const instance = new Interpreter({ machine: this.#machine, options: this.interpreterOptions, }); instance.addOptions(option); return instance; }; dispose = () => { this.stop(); this.#service.dispose(); this.#options = undefined; this.#mainState = undefined; this.interpreterOptions = undefined; }; [Symbol.dispose] = this.dispose; [Symbol.asyncDispose] = helpers.asyncify(this.dispose); } const createInterpreter = args => { return new Interpreter(args); }; const interpret = createInterpreter; exports.createInterpreter = createInterpreter; exports.interpret = interpret; //# sourceMappingURL=interpreter.cjs.map