UNPKG

react-torch

Version:

A lib to server-side render with react.

248 lines (247 loc) 11.3 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __generator = (this && this.__generator) || function (thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (_) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; var __read = (this && this.__read) || function (o, n) { var m = typeof Symbol === "function" && o[Symbol.iterator]; if (!m) return o; var i = m.call(o), r, ar = [], e; try { while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); } catch (error) { e = { error: error }; } finally { try { if (r && !r.done && (m = i["return"])) m.call(i); } finally { if (e) throw e.error; } } return ar; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.createReactModel = void 0; var react_1 = __importStar(require("react")); var core_1 = require("../core"); var useIsomorphicLayoutEffect = // tslint:disable-next-line: strict-type-predicates typeof window !== 'undefined' && // tslint:disable-next-line: strict-type-predicates typeof window.document !== 'undefined' && // tslint:disable-next-line: deprecation & strict-type-predicates typeof window.document.createElement !== 'undefined' ? react_1.useLayoutEffect : react_1.useEffect; var DefaultValue = Symbol('default-value'); var createReactModel = function (initilizer) { var ReactContext = react_1.default.createContext(null); var useState = function (selector, compare) { if (selector === void 0) { selector = core_1.identity; } if (compare === void 0) { compare = core_1.shallowEqual; } var ctx = (0, react_1.useContext)(ReactContext); if (ctx === null) { throw new Error("You may forget to attach Provider to component tree before calling Model.useState()"); } var store = ctx.store; // modified from react-redux useSelector var _a = __read((0, react_1.useReducer)(function (s) { return s + 1; }, 0), 2), _ = _a[0], forceRender = _a[1]; var latestSubscriptionCallbackError = (0, react_1.useRef)(null); var latestSelector = (0, react_1.useRef)(null); var latestStoreState = (0, react_1.useRef)(DefaultValue); var latestSelectedState = (0, react_1.useRef)(DefaultValue); var storeState = store.getState(); var selectedState = DefaultValue; try { if (selector !== latestSelector.current || storeState !== latestStoreState.current || latestSubscriptionCallbackError.current) { selectedState = selector(storeState); } else { selectedState = latestSelectedState.current; } } catch (err) { if (latestSubscriptionCallbackError.current && err instanceof Error) { err.message += "\nThe error may be correlated with this previous error:\n" + latestSubscriptionCallbackError.current.stack + "\n\n"; } throw err; } useIsomorphicLayoutEffect(function () { latestSelector.current = selector; latestStoreState.current = storeState; latestSelectedState.current = selectedState; latestSubscriptionCallbackError.current = null; }); useIsomorphicLayoutEffect(function () { var isUnmounted = false; var checkForUpdates = function () { if (!latestSelector.current) return; if (isUnmounted) return; if (latestSelectedState.current === DefaultValue) { throw new Error("latestSelectedState should not be default value"); } try { var storeState_1 = store.getState(); var newSelectedState = latestSelector.current(storeState_1); if (compare(newSelectedState, latestSelectedState.current)) { return; } latestSelectedState.current = newSelectedState; latestStoreState.current = storeState_1; } catch (err) { // we ignore all errors here, since when the component // is re-rendered, the selectors are called again, and // will throw again, if neither props nor store state // changed if (err instanceof Error) { latestSubscriptionCallbackError.current = err; } else { throw err; } } forceRender(); }; var unsubscribe = store.subscribe(checkForUpdates); return function () { isUnmounted = true; unsubscribe(); }; }, [store]); if (selectedState === DefaultValue) { throw new Error("selectedState should not be default value"); } return selectedState; }; var useActions = function () { var ctx = (0, react_1.useContext)(ReactContext); if (ctx === null) { throw new Error("You may forget to attach Provider to component tree before calling Model.useActions()"); } return ctx.actions; }; var Provider = function (props) { var children = props.children, preloadedState = props.preloadedState; var model = (0, react_1.useMemo)(function () { if (props.model) return props.model; var options = { preloadedState: preloadedState }; return (0, core_1.createPureModel)(initilizer, options); }, []); var value = (0, react_1.useMemo)(function () { return { store: model.store, actions: model.actions, }; }, [model]); var _a = __read((0, react_1.useState)(function () { return model.preload.hasRun(); }), 2), isReady = _a[0], setReady = _a[1]; useIsomorphicLayoutEffect(function () { var isUnmounted = false; if (!model.preload.hasRun()) { // tslint:disable-next-line: no-floating-promises model.preload.run().then(function () { if (isUnmounted) return; setReady(true); model.start.run(); }); } else if (!model.start.hasRun()) { model.start.run(); } return function () { isUnmounted = true; if (model.start.hasRun()) { model.finish.run(); } }; }, []); if (!isReady) return null; return (react_1.default.createElement(ReactContext.Provider, { value: value }, children)); }; var preload = function (preloadedState) { return __awaiter(void 0, void 0, void 0, function () { var model, state, PreloadedProvider; return __generator(this, function (_a) { switch (_a.label) { case 0: model = (0, core_1.createPureModel)(initilizer, { preloadedState: preloadedState }); return [4 /*yield*/, model.preload.run()]; case 1: _a.sent(); state = model.store.getState(); PreloadedProvider = function (_a) { var children = _a.children; return react_1.default.createElement(Provider, { model: model }, children); }; return [2 /*return*/, { Provider: PreloadedProvider, state: state, model: model }]; } }); }); }; return { isReactModel: true, useState: useState, useActions: useActions, Provider: Provider, preload: preload, create: initilizer, }; }; exports.createReactModel = createReactModel;