import { Actual, ConstructorType, MaybeMessage, Message, Of, Once, } from "silentium"; import { Record } from "../structures"; /** * Modify the object structure * with the ability to create new fields based on * existing ones in the object * * @url https://silentium.pw/article/transformed/view */ export function Transformed>( _base: MaybeMessage, transformRules: Record]>>, ) { const $base = Actual(_base); return Message(function TransformedImpl(resolve) { $base.then(function transformedBaseSub(v) { const existedKeysMap: Record = {}; const sourceObject = Object.fromEntries( Object.entries(v).map(function transformedBaseEntries(entry) { if (transformRules[entry[0]]) { existedKeysMap[entry[0]] = 1; return [entry[0], transformRules[entry[0]](v)]; } return [entry[0], Of(entry[1])]; }), ); Object.keys(transformRules).forEach(function transformedRulesKeys(key) { if (!existedKeysMap[key]) { sourceObject[key] = transformRules[key](v); } }); const record = Once(Record(sourceObject)); record.then(resolve); }); }); }