mezzanine
Version:
Fantasy land union types with pattern matching
241 lines (156 loc) • 4.87 kB
JavaScript
import { values } from 'ramda';
import toFastProps from '../to-fast-props';
import { isMezzanine } from './fixtures';
import { typeMark } from '../config';
import { createBuilder, createPred, transformInput } from './descriptor';
import './descriptor';
import './index.h';
import { injector } from '../utils/props';
import { getInitialValue, applyStack } from '../virtual-stack';
import { instanceInjectableProps, fantasyInstance, fantasyOnClass } from './properties';
function isType(pred, uniqMark, isMono, stack) {
var needTransform = stack.length !== 0;
return function checkIsType(obj) {
var val = obj;
if (needTransform === true) {
var initial = getInitialValue(stack, val);
if (initial.succ === false) return false;
val = initial.val;
}
var data = transformInput(val, isMono);
if (data == null) return false;
if (isMono && isMezzanine(data.value) && data.value.ಠ_ಠ === uniqMark)
return true;
return pred(data);
};
}
var newUniqMark = name => Symbol(name);
var generalInjectableProps = {
clone: (_, Static) => () => {
var { name, typeName, desc, func, stack } = Static;
return makeContainer(name, typeName, desc, func, stack);
},
//$FlowIssue
[typeMark]: {
get: () => true,
enumerable: false } };
var staticInjectableProps = {
//$FlowIssue
[Symbol.hasInstance]: Static => val => Static.is(val),
stackUpdate: Static =>
newStack => {
var { name, typeName, desc, func } = Static;
return makeContainer(name, typeName, desc, func, newStack);
} };
var fullStaticProps = injector([
generalInjectableProps,
staticInjectableProps,
fantasyOnClass]);
var fullInstanceProps = injector([
generalInjectableProps,
instanceInjectableProps,
fantasyInstance]);
function makeContainer(
name,
typeName,
descriptor,
func,
stack = []
//$FlowIssue
) {
var desc =
typeof descriptor !== 'object' ||
descriptor == null ?
{ value: descriptor } :
descriptor;
var keys = Object.keys(desc);
var pred = createPred(desc);
var isMono = keys.length === 1 && keys[0] === 'value';
var uniqMark = newUniqMark(name);
var checkIs = isType(pred, uniqMark, isMono, stack);
function RecordFn(arg) {
//$FlowIssue
if (new.target == null)
return new RecordFn(arg);
var obj = applyStack(stack, arg);
var data = transformInput(obj, isMono);
if (data == null) {
throw new TypeError(`${name}{isMono: ${isMono.toString()}}: No value recieved`);
}
if (isMono && isMezzanine(data.value) && data.value.ಠ_ಠ === uniqMark) return data.value;
if (!pred(data)) {
var mono = isMono.toString();
var keysList = Object.keys(data).toString();
var valuesList = values(data).toString();
var message = `${name}{isMono: ${mono}}: Unsafe pattern mismatch\nKeys: ${keysList}\nValues: ${valuesList}`;
throw new TypeError(message);
}
var dataResult = createBuilder(desc, data);
// console.log(data, obj, dataResult)
for (var _iterator = keys, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {var _ref;if (_isArray) {if (_i >= _iterator.length) break;_ref = _iterator[_i++];} else {_i = _iterator.next();if (_i.done) break;_ref = _i.value;}var key = _ref;
this[key] = dataResult[key];
// console.log(this[key])
}
fullInnerInstProps(this, RecordFn);
fullInstanceProps(this, RecordFn);
toFastProps(this);
}
var generalProps = {
ಠ_ಠ: {
value: uniqMark,
enumerable: false },
type: {
value: name,
enumerable: true },
keys: {
value: keys,
enumerable: false },
isMono: {
get: () => isMono,
enumerable: false },
is: {
value: checkIs,
enumerable: true } };
var staticProps = {
name: {
value: name,
enumerable: false },
typeName: {
value: typeName,
enumerable: false },
desc: {
value: descriptor,
enumerable: false },
func: {
value: func,
enumerable: false },
stack: {
value: stack,
enumerable: false } };
var instProps = {
typeName: {
value: typeName,
enumerable: true } };
var fullInnerStaticProps = injector([
generalProps,
staticProps]);
var userMeth = getUserMethods(func);
var fullInnerInstProps = injector([
generalProps,
instProps,
userMeth]);
fullInnerStaticProps(RecordFn, RecordFn);
fullStaticProps(RecordFn, RecordFn);
return RecordFn;
}
var getUserMethods = func =>
Object.getOwnPropertyNames(func)
//$FlowIssue
.concat(Object.getOwnPropertySymbols(func)).
map(key => [key, {
value: func[key],
enumerable: true,
writable: true,
inject: true }]);
export default makeContainer;
//# sourceMappingURL=type-container.js.map