UNPKG

@prodo/core

Version:

Core package for [Prodo](https://prodo.dev). See [documentation](https://docs.prodo.dev) for more info.

227 lines 10 kB
"use strict"; var __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; return extendStatics(d, b); }; return function (d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); var __assign = (this && this.__assign) || function () { __assign = Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; var __spreadArrays = (this && this.__spreadArrays) || function () { for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length; for (var r = Array(s), k = 0, i = 0; i < il; i++) for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) r[k] = a[j]; return r; }; Object.defineProperty(exports, "__esModule", { value: true }); var React = require("react"); var logger_1 = require("./logger"); var utils_1 = require("./utils"); var watch_1 = require("./watch"); exports.ProdoContext = React.createContext(null); var pathSymbol = Symbol("path"); exports.createUniverseWatcher = function (universePath) { var readProxy = function (path) { return new Proxy({}, { get: function (_target, key) { return key === pathSymbol ? path : readProxy(path.concat([key.toString()])); }, }); }; return readProxy([universePath]); }; var getValue = function (path, obj) { return path.reduce(function (x, y) { return x && x[y]; }, obj); }; var valueExtractor = function (store, watched) { return function (x) { var path = x[pathSymbol]; var pathKey = utils_1.joinPath(path); var value = getValue(path, store.universe); watched[pathKey] = value; return value; }; }; exports.shallowEqual = function (objA, objB) { if (Object.is(objA, objB)) { return true; } if (typeof objA !== "object" || objA === null || typeof objB !== "object" || objB === null) { return false; } var keysA = Object.keys(objA); var keysB = Object.keys(objB); if (keysA.length !== keysB.length) { return false; } // Test for A's keys different from B. // tslint:disable-next-line:prefer-for-of for (var i = 0; i < keysA.length; i++) { if (!Object.prototype.hasOwnProperty.call(objB, keysA[i]) || !Object.is(objA[keysA[i]], objB[keysA[i]])) { return false; } } return true; }; var _compIdCnt = 1; exports.connect = function (func, name) { if (name === void 0) { name = "(anonymous)"; } var _a; return _a = /** @class */ (function (_super) { __extends(ConnectComponent, _super); function ConnectComponent(props) { var _this = _super.call(this, props) || this; _this.state = {}; _this.watched = {}; _this.prevWatched = {}; _this.pathNodes = {}; _this.compId = _compIdCnt++; _this.name = name + "." + _this.compId; _this.store = _this.context; var setState = _this.setState.bind(_this); _this.status = { unmounted: false }; _this.comp = { name: _this.name, compId: _this.compId, }; _this.eventIdCnt = 0; _this.subscribe = function (path, unsubscribe) { var pathKey = utils_1.joinPath(path); var node = _this.pathNodes[pathKey] || __assign({ pathKey: pathKey, status: _this.status, setState: setState, unsubscribe: unsubscribe }, _this.comp); _this.pathNodes[pathKey] = node; watch_1.subscribe(_this.store, path, node); }; _this.unsubscribe = function (path) { var pathKey = utils_1.joinPath(path); var node = _this.pathNodes[pathKey]; if (node != null) { watch_1.unsubscribe(_this.store, path, node); delete _this.pathNodes[pathKey]; } }; _this._watch = function (x) { return x; }; _this._dispatch = function (func) { return function () { var _a; var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } return (_a = _this.store).exec.apply(_a, __spreadArrays([{ id: _this.comp.name + "/event." + _this.eventIdCnt++, parentId: _this.comp.name, }, func], args)); }; }; _this._renderFunc = function (props) { return func(_this._viewCtx)(props); }; logger_1.default.info("[constructing] " + _this.name); return _this; } ConnectComponent.prototype.componentDidMount = function () { var _this = this; logger_1.default.info("[did mount] " + this.name); Object.keys(this.watched).forEach(function (pathKey) { logger_1.default.info("[start watching] " + _this.name + ": < " + pathKey + " >"); _this.subscribe(utils_1.splitPath(pathKey)); }); logger_1.default.debug("store", this.store); this.prevWatched = __assign({}, this.watched); this.setState(this.watched); this.watched = {}; }; ConnectComponent.prototype.shouldComponentUpdate = function (nextProps, nextState) { var test = !exports.shallowEqual(this.props, nextProps) || !exports.shallowEqual(this.state, nextState); logger_1.default.info("[should update] " + this.name, test); return test; }; ConnectComponent.prototype.componentDidUpdate = function () { var _this = this; logger_1.default.info("[did update] " + this.name); Object.keys(this.watched).forEach(function (pathKey) { var keyExisted = _this.prevWatched.hasOwnProperty(pathKey); if (!keyExisted) { logger_1.default.info("[update] " + _this.name + ": now watching < " + pathKey + " >"); _this.subscribe(utils_1.splitPath(pathKey)); } }); Object.keys(this.prevWatched).forEach(function (pathKey) { var keyDeleted = !_this.watched.hasOwnProperty(pathKey); if (keyDeleted) { logger_1.default.info("[update] " + _this.name + ": stop watching < " + pathKey + " >"); _this.unsubscribe(utils_1.splitPath(pathKey)); } }); this.prevWatched = __assign({}, this.watched); this.watched = {}; }; ConnectComponent.prototype.componentWillUnmount = function () { var _this = this; logger_1.default.info("[will unmount]: " + this.name, this.state); Object.keys(this.state).forEach(function (pathKey) { logger_1.default.info("[unmount] " + _this.name + ": stop watching < " + pathKey + " >"); _this.unsubscribe(utils_1.splitPath(pathKey)); }); logger_1.default.debug("store", this.store); this.status.unmounted = true; }; ConnectComponent.prototype.render = function () { this.createViewCtx(); var Comp = this._renderFunc; return React.createElement(Comp, __assign({}, this.props)); }; ConnectComponent.prototype.createViewCtx = function () { var _this = this; this.store = this.context; this._state = exports.createUniverseWatcher("state"); this._watch = valueExtractor(this.store, this.watched); var subscribe = function (path, unsubscribe) { var pathKey = utils_1.joinPath(path); _this.watched[pathKey] = getValue(path, _this.store.universe); _this.subscribe(path, unsubscribe); }; var ctx = { dispatch: this._dispatch, state: this._state, watch: this._watch, subscribe: subscribe, }; this.store.plugins.forEach(function (p) { if (p._internals.viewCtx) { ctx.dispatch = _this._dispatch; p._internals.viewCtx({ ctx: ctx, universe: _this.store.universe, comp: _this.comp, }, _this.store.config); } }); this._viewCtx = ctx; }; return ConnectComponent; }(React.Component)), _a.contextType = exports.ProdoContext, _a; }; //# sourceMappingURL=connect.js.map