@bemedev/app-solid
Version:
Middleware between @bemedev/app-ts and solidjs
189 lines (185 loc) • 5.99 kB
JavaScript
'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