UNPKG

reactive-di

Version:
805 lines (616 loc) 19.7 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var urc = require('urc'); function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; subClass.__proto__ = superClass; } var rdiInst = Symbol('rdi_inst'); var rdiProp = Symbol('rdi_prop'); var depId = 0; var rdiId = Symbol('rdi_id'); var Alias = function Alias(dest) { dest[rdiId] = '' + ++depId; this.dest = dest; }; var Injector = /*#__PURE__*/ function () { function Injector(contextAliases, sheetManager, state, displayName, instance, cache, flags) { this.id = ''; this.props = undefined; this._sheet = undefined; this._resolved = false; this._listeners = undefined; this._state = state; this.instance = instance || 0; this.displayName = displayName || ''; if (Injector.parentContext === undefined) Injector.parentContext = this; if (sheetManager) { Injector.sheetManager = sheetManager; } this._flags = flags; var map = this._cache = cache || Object.create(null); if (contextAliases !== undefined) { for (var i = 0; i < contextAliases.length; i++) { var item = contextAliases[i]; if (item instanceof Array) { var src = item[0]; if (typeof src === 'string') { map[src] = item[1]; } else { if (src[rdiId] === undefined) { src[rdiId] = '' + ++depId; } var dest = item[1]; map[src[rdiId]] = typeof dest === 'function' && !(dest instanceof Alias) ? new Alias(dest) : dest; } } else { var _src = item.constructor; if (_src[rdiId] === undefined) { _src[rdiId] = '' + ++depId; } map[_src[rdiId]] = item; } } } } var _proto = Injector.prototype; _proto.getClassName = function getClassName(data, debugName) { var sheet = this._sheet; var flags = this._flags; if (sheet === undefined) { sheet = this._sheet = Injector.sheetManager.createSheet(this.displayName + (flags && flags.isDynamic ? '_' + this.instance : '')); } if (data._dynamic !== undefined && flags) { flags.isDynamic = true; } return sheet.addRule(data, debugName); }; _proto.toString = function toString() { return this.displayName + (this.instance ? '[' + this.instance + ']' : ''); }; _proto.toJSON = function toJSON() { return this._cache; }; _proto.value = function value(key) { var id = key[rdiId]; if (key[rdiId] === undefined) { id = key[rdiId] = '' + ++depId; } var value = this._cache[id]; if (value === undefined) { value = this._cache[id] = this.invoke(key); var depName = (key.displayName || key.name) + (this.instance > 0 ? '[' + this.instance + ']' : ''); value.displayName = this.displayName + "." + depName; value[rdiInst] = this; var state = this._state === undefined ? undefined : this._state[depName]; if (state && typeof state === 'object') { for (var prop in state) { value[prop] = state[prop]; } } } else if (value instanceof Alias) { value = this._cache[id] = this.value(value.dest); } return value; }; _proto.destructor = function destructor() { if (this._sheet) this._sheet.destructor(); this._sheet = undefined; this._cache = undefined; this._listeners = undefined; }; _proto.invoke = function invoke(key) { var isFn = false; var deps = key.deps; if (key._r !== undefined) { isFn = key._r[0] === 2; deps = deps || key._r[1]; } var a = this.resolve(deps); if (isFn) { switch (a.length) { case 0: return key(); case 1: return key(a[0]); case 2: return key(a[0], a[1]); case 3: return key(a[0], a[1], a[2]); case 4: return key(a[0], a[1], a[2], a[3]); case 5: return key(a[0], a[1], a[2], a[3], a[4]); case 6: return key(a[0], a[1], a[2], a[3], a[4], a[5]); default: return key.apply(void 0, a); } } switch (a.length) { case 0: return new key(); case 1: return new key(a[0]); case 2: return new key(a[0], a[1]); case 3: return new key(a[0], a[1], a[2]); case 4: return new key(a[0], a[1], a[2], a[3]); case 5: return new key(a[0], a[1], a[2], a[3], a[4]); case 6: return new key(a[0], a[1], a[2], a[3], a[4], a[5]); default: return new (Function.prototype.bind.apply(key, [null].concat(a)))(); } }; _proto.alias = function alias(key, rawId) { var id = rawId; if (id === undefined) { id = key[rdiId]; if (id === undefined) { id = key[rdiId] = '' + ++depId; } } var newKey = this._cache[id]; if (newKey instanceof Alias) return newKey.dest; if (newKey === undefined) return key; return newKey; }; _proto.getContext = function getContext(key, props) { var deps = key.deps || (key._r === undefined ? undefined : key._r[1]); if (deps === undefined) return undefined; var a = this.resolve(deps); var listeners = this._listeners; if (props !== undefined && listeners !== undefined) { for (var i = 0; i < listeners.length; i++) { var listener = listeners[i]; listener[listener.constructor[rdiProp]] = props; } } this._resolved = true; return a[0]; }; _proto.copy = function copy(flags) { return new Injector(flags.contextAliases, null, this._state, flags.displayName, flags.instance, Object.create(this._cache), flags); }; _proto.resolve = function resolve(argDeps) { var result = []; if (argDeps === undefined) return result; var listeners = this._listeners; var resolved = this._resolved; for (var i = 0, l = argDeps.length; i < l; i++) { var argDep = argDeps[i]; if (typeof argDep === 'object') { var obj = {}; for (var prop in argDep) { // eslint-disable-line var key = argDep[prop]; var dep = this.value(key); if (resolved === false && key[rdiProp] !== undefined) { if (listeners === undefined) { this._listeners = listeners = []; } listeners.push(dep); } obj[prop] = dep; } result.push(obj); } else { var _dep = this.value(argDep); if (resolved === false && argDep[rdiProp] !== undefined) { if (listeners === undefined) { this._listeners = listeners = []; } listeners.push(_dep); } result.push(_dep); } } return result; }; return Injector; }(); function createReactWrapper(BaseComponent, renderError, ReactAtom, rootInjector) { if (rootInjector === void 0) { rootInjector = new Injector(); } var names = new Map(); function normalizeClass(cls) { var prefix = names.get(cls.displayName); if (prefix !== undefined) { prefix++; names.set(cls.displayName, prefix); cls.displayName = cls.displayName + prefix; } else { names.set(cls.displayName, 0); } return cls; } var MixinComponent = /*#__PURE__*/ function (_CatchableComponent) { _inheritsLoose(MixinComponent, _CatchableComponent); function MixinComponent() { return _CatchableComponent.apply(this, arguments) || this; } var _proto = MixinComponent.prototype; _proto.componentWillMount = function componentWillMount() { _CatchableComponent.prototype.componentWillMount.call(this); var cns = this.constructor; if (cns.instance === undefined) { cns.instance = 0; cns.isDynamic = false; } cns.instance++; var injector = rootInjector; var props = this.props; if (props && props.__lom_ctx !== undefined) injector = props.__lom_ctx; this._injector = injector.copy(cns); this._injector.id = cns.displayName; this._injector.props = props; }; _proto.componentWillUnmount = function componentWillUnmount() { this.constructor.instance--; this._injector.destructor(); _CatchableComponent.prototype.componentWillUnmount.call(this); }; _proto.__value = function __value(isPropsChanged) { var oldInjector = Injector.parentContext; Injector.parentContext = this._injector; var value = _CatchableComponent.prototype.__value.call(this, isPropsChanged); Injector.parentContext = oldInjector; return value; }; _proto._getContext = function _getContext(key, propsChanged) { return this._injector.getContext(key, propsChanged ? this.props : undefined); }; return MixinComponent; }(urc.CatchableComponent); return urc.createConnect({ ReactAtom: ReactAtom, renderError: renderError, BaseComponent: BaseComponent, MixinComponent: MixinComponent, normalizeClass: normalizeClass }); } function createCreateElement(atomize, createElement, modifyId) { function lomCreateElement() { var args = arguments; var attrs = args[1]; var el = args[0]; var newEl; var isAtomic = typeof el === 'function' && el.constructor.render === undefined; var parentContext = Injector.parentContext; var props = parentContext.props; var id = undefined; if (attrs) { var pid = parentContext.id; id = attrs.rdi_id || attrs.id; var aClass = attrs.class; if (typeof aClass === 'object') { attrs.class = aClass = parentContext.getClassName(aClass, id); } if (attrs.rdi_theme === true) { attrs.rdi_theme = undefined; if (props) { var pClass = props.class; if (pClass !== undefined) { attrs.class = aClass === undefined ? pClass : aClass + " " + pClass; } var pStyle = props.style; if (pStyle !== undefined) { var aStyle = attrs.style; if (aStyle === undefined) { attrs.style = pStyle; } else { for (var _key in pStyle) { aStyle[_key] = pStyle[_key]; } } } } if (modifyId) attrs.id = pid; } else if (modifyId && pid !== '' && attrs.id !== undefined) { attrs.id = pid + '.' + attrs.id; } } if (isAtomic) { newEl = parentContext.alias(el, id); if (newEl === null) return null; if (newEl !== undefined) el = newEl; if (!attrs) { attrs = { __lom_ctx: parentContext }; } else { attrs.__lom_ctx = parentContext; } if (el.__lom === undefined) { el.__lom = atomize(el); } newEl = el.__lom; } else { if (id) { newEl = parentContext.alias(el, id); if (newEl === null) return null; if (newEl !== undefined) el = newEl; } newEl = el; } switch (args.length) { case 2: return createElement(newEl, attrs); case 3: return createElement(newEl, attrs, args[2]); case 4: return createElement(newEl, attrs, args[2], args[3]); case 5: return createElement(newEl, attrs, args[2], args[3], args[4]); case 6: return createElement(newEl, attrs, args[2], args[3], args[4], args[5]); case 7: return createElement(newEl, attrs, args[2], args[3], args[4], args[5], args[6]); case 8: return createElement(newEl, attrs, args[2], args[3], args[4], args[5], args[6], args[7]); case 9: return createElement(newEl, attrs, args[2], args[3], args[4], args[5], args[6], args[7], args[8]); default: if (isAtomic === false) { return createElement.apply(null, args); } else { var newArgs = [newEl, attrs]; for (var i = 2, l = args.length; i < l; i++) { newArgs.push(args[i]); } return createElement.apply(null, newArgs); } } } return lomCreateElement; } function dn(fn) { if (!fn) return 'null'; if (typeof fn === 'object') { var cons = fn.constructor; return cons.displayName || cons.name; } if (typeof fn === 'function') { return fn.displayName || fn.name; } return String(fn); } function provideMap(item) { return item instanceof Array ? "[" + dn(item[0]) + ", " + dn(item[1]) + "]" : dn(item); } function cloneComponent(fn, contextAliases, name) { var cloned = function cloned() { var a = arguments; switch (a.length) { case 1: return fn(a[0]); case 2: return fn(a[0], a[1]); case 3: return fn(a[0], a[1], a[2]); case 4: return fn(a[0], a[1], a[2], a[3]); case 5: return fn(a[0], a[1], a[2], a[3], a[4]); default: return fn.apply(null, a); } }; cloned.deps = fn.deps; cloned._r = fn._r; cloned.contextAliases = fn.contextAliases ? fn.contextAliases.concat(contextAliases) : contextAliases; cloned.displayName = name || "cloneComponent(" + dn(fn) + ", [" + contextAliases.map(provideMap).join(', ') + "])"; return cloned; } function props(proto, name, descr) { proto.constructor[rdiProp] = name; if (!descr.value && !descr.set) { descr.writable = true; } } var subRulesId = Symbol('rdi_sub_rules'); var nameId = Symbol('rdi_theme_name'); var ruleId = Symbol('rdi_rule_id'); var BAD_CLASS_SYMBOLS = new RegExp('[^\\w\\d\\-\\_]', 'g'); var KEYFRAMES = '@keyframes '; function replaceProps(obj, placeholder, replaceTo) { for (var _key in obj) { var val = obj[_key]; if (val && _key.indexOf('animation') === 0) { obj[_key] = typeof val === 'object' ? replaceProps(val, placeholder, replaceTo) : val.replace(placeholder, replaceTo); } } return obj; } var JssSheet = /*#__PURE__*/ function () { function JssSheet(jssSheet, owner, key) { this.usageCount = 0; this._scheduled = false; this._lastAttached = new Set(); this._toDelete = new Set(); this.jssSheet = jssSheet; this._owner = owner; this.key = key; } var _proto = JssSheet.prototype; _proto.addRule = function addRule(css, debugName) { var sheet = this.jssSheet; var id = css[ruleId]; var rule = undefined; if (id === undefined) { id = css[ruleId] = (css[nameId] || JSON.stringify(css)).replace(BAD_CLASS_SYMBOLS, ''); rule = sheet.getRule(id); if (rule && css._dynamic === true) { rule = undefined; } } else { rule = sheet.getRule(id); } if (!rule) { var prefix = sheet.options.classNamePrefix; var placeholder = '@.'; var newCss = {}; var subRules = undefined; for (var _key2 in css) { var item = css[_key2]; if (item === true) continue; // _dynamic if (_key2.indexOf(KEYFRAMES) === 0 && typeof item === 'object') { if (subRules === undefined) subRules = []; subRules.push(sheet.addRule(_key2.replace(placeholder, prefix), item)); } else { newCss[_key2] = item !== null && typeof item === 'object' ? replaceProps(item, placeholder, prefix) : _key2.indexOf('animation') === 0 ? item.replace(placeholder, prefix) : item; } } rule = sheet.addRule(id, newCss); if (subRules) rule[subRulesId] = subRules; if (!this._scheduled) this._owner.update(this); this._scheduled = true; } this._lastAttached.add(rule); this._toDelete.delete(rule); return sheet.classes[id]; }; _proto._deleteRule = function _deleteRule(rule) { var sheet = this.jssSheet; var subRules = rule[subRulesId]; if (subRules !== undefined) { for (var i = 0; i < subRules.length; i++) { sheet.deleteRule(subRules[i].key); } } sheet.deleteRule(rule.key); }; _proto.attach = function attach() { this._scheduled = false; this._toDelete.forEach(this._deleteRule, this); this._toDelete = this._lastAttached; this._lastAttached = new Set(); this.jssSheet.attach(); }; _proto.destructor = function destructor() { this.usageCount--; if (this.usageCount !== 0) return; this._toDelete = undefined; this._lastAttached = undefined; this._owner.update(this); }; return JssSheet; }(); function defaultSchedule(cb) { setTimeout(cb, 16); } var JssSheetManager = /*#__PURE__*/ function () { function JssSheetManager(jss, schedule) { if (schedule === void 0) { schedule = defaultSchedule; } _initialiseProps.call(this); this._jss = jss; this._schedule = schedule; } JssSheetManager.createGenerateClassName = function createGenerateClassName() { return function generateClassName(rule, sheet) { return "" + (sheet ? sheet.options.classNamePrefix : '') + (rule.key ? "-" + rule.key : ''); }; }; var _proto2 = JssSheetManager.prototype; _proto2.createSheet = function createSheet(sheetKey) { var sheet = this._cache.get(sheetKey); if (sheet === undefined) { var _meta = sheetKey.replace(this._badClassSymbols, ''); var _options = { meta: _meta, classNamePrefix: _meta }; sheet = new JssSheet(this._jss.createStyleSheet(undefined, _options), this, sheetKey); this._cache.set(sheetKey, sheet); } sheet.usageCount++; return sheet; }; _proto2.update = function update(sheet) { var scheduled = this._scheduled; if (scheduled.length === 0) { this._schedule(this._sync); } scheduled.push(sheet); }; return JssSheetManager; }(); var _initialiseProps = function _initialiseProps() { var _this = this; this._cache = new Map(); this._badClassSymbols = BAD_CLASS_SYMBOLS; this._scheduled = []; this._sync = function () { var scheduled = _this._scheduled, cache = _this._cache, jss = _this._jss; for (var i = 0; i < scheduled.length; i++) { var _sheet = scheduled[i]; if (_sheet.usageCount === 0) { cache.delete(_sheet.key); jss.removeStyleSheet(_sheet.jssSheet); } else { _sheet.attach(); } } _this._scheduled = []; }; }; function addDebugInfo(obj) { if (obj[nameId] === undefined) { for (var k in obj) { var prop = obj[k]; if (prop && typeof prop === 'object') { prop[nameId] = k; } } } return obj; } function themeProp(proto, name, descr) { var className = proto.constructor.displayName || proto.constructor.name; var getSheet = descr.get; var value = descr.value; if (getSheet === undefined && value === undefined) { throw new Error("Need " + className + " { @theme get " + name + "() }"); } if (getSheet) { proto[name + "#"] = getSheet; } return { enumerable: descr.enumerable, configurable: descr.configurable, get: function get() { var obj = value || this[name + "#"](); return addDebugInfo(obj); } }; } function theme(proto, name, descr) { return themeProp(proto, name, descr); } theme.fn = addDebugInfo; exports.createReactWrapper = createReactWrapper; exports.createCreateElement = createCreateElement; exports.Injector = Injector; exports.cloneComponent = cloneComponent; exports.props = props; exports.theme = theme; exports.JssSheetManager = JssSheetManager;