UNPKG

@rxreact/context

Version:

Dependency-inject an RxJS signal graph into your React components

121 lines (109 loc) 5.82 kB
(function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('rxjs'), require('rxjs/operators'), require('react'), require('@rxreact/core')) : typeof define === 'function' && define.amd ? define(['exports', 'rxjs', 'rxjs/operators', 'react', '@rxreact/core'], factory) : (global = global || self, factory(global.context = {}, global.rxjs, global.operators, global.React, global.core)); }(this, (function (exports, rxjs, operators, React, core) { 'use strict'; var getAccessor = function (externalValue$) { var setValue$ = new rxjs.Subject(); var value$ = rxjs.merge(setValue$, externalValue$); return [value$, setValue$]; }; /** * An operator to extract a property from an observable of an object. * Useful for pulling a specific prop from an observable of React props. * @param prop - The name of the object property * @returns - An observable of the object's property */ function getProp(prop) { return function (props$, compare) { return props$.pipe(operators.map(function (props) { return props[prop]; }), operators.distinctUntilChanged(compare)); }; } function reducer(pairs, startWith) { var xs = pairs.map(function (_a, index) { var observable = _a[0], _mapper = _a[1]; return observable.pipe(operators.map(function (value) { return ({ index: index, payload: value }); })); }); return rxjs.merge.apply(void 0, xs).pipe(operators.scan(function (state, _a) { var index = _a.index, payload = _a.payload; var _b = pairs[index], f = _b[1]; return f(state, payload); }, startWith), operators.shareReplay(1)); } /*! ***************************************************************************** Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT. See the Apache Version 2.0 License for specific language governing permissions and limitations under the License. ***************************************************************************** */ var __assign = function() { __assign = Object.assign || function __assign(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); }; function connect(context, viewModelFactory) { return function connectWithComponent(Component) { // The final component takes all the props of `component`, // _except_ the ones passed in from the Signal Graph. var Connected = function (props) { // The Child component to render var _a = React.useState({ Child: null }), Child = _a[0].Child, setChild = _a[1]; var _b = React.useState(null), localSubscriptions = _b[0], setLocalSubscriptions = _b[1]; var signalGraph = React.useContext(context); // Wrap the child with `withViewModel`, but only do this once. React.useEffect(function () { var child = core.withViewModel(function (ownProps) { var _a = viewModelFactory(signalGraph, ownProps), inputs = _a.inputs, outputs = _a.outputs, unsubscribe = _a.unsubscribe; // Store the unsubscribes for cleanup. setLocalSubscriptions(unsubscribe || null); return { inputs: inputs, outputs: outputs }; })(Component); // Wrap the child in an object, because `setChild` when passed a // function (like a component) will actually call the function. setChild({ Child: child }); }, [signalGraph]); // On destroy, perform cleanup React.useEffect(function () { return function () { if (localSubscriptions) { localSubscriptions.map(function (subscription) { return subscription.unsubscribe(); }); } }; }, [localSubscriptions]); return Child ? React.createElement(Child, __assign({}, props)) : null; }; return Connected; }; } /** * Generate a SignalGraph context and provider to serve connected components. * @param createSignalGraph - A function to generate the signal graph */ function createSignalGraphContext(createSignalGraph) { var signalGraph = createSignalGraph(); var SignalGraphContext = React.createContext(signalGraph); var SignalGraphProvider = function (_a) { var children = _a.children; return (React.createElement(SignalGraphContext.Provider, { value: signalGraph }, children)); }; return [SignalGraphContext, SignalGraphProvider]; } exports.connect = connect; exports.createSignalGraphContext = createSignalGraphContext; exports.getAccessor = getAccessor; exports.getProp = getProp; exports.reducer = reducer; Object.defineProperty(exports, '__esModule', { value: true }); }))); //# sourceMappingURL=context.umd.js.map