UNPKG

@airma/react-state

Version:

the purpose of this project is make useReducer more simplify

755 lines (732 loc) 25.4 kB
"use strict"; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/index.ts var index_exports = {}; __export(index_exports, { ConfigProvider: () => ConfigProvider, Provider: () => Provider, createKey: () => createKey, createStore: () => createStore, model: () => model, provide: () => provide, shallowEqual: () => shallowEqual2, useActProcess: () => useActProcess, useControlledModel: () => useControlledModel, useModel: () => useModel, useSelector: () => useSelector, useSignal: () => useSignal, validations: () => import_as_model6.validations }); module.exports = __toCommonJS(index_exports); var import_as_model7 = require("as-model"); // ../../../node_modules/@swc/helpers/esm/_array_with_holes.js function _array_with_holes(arr) { if (Array.isArray(arr)) return arr; } // ../../../node_modules/@swc/helpers/esm/_iterable_to_array_limit.js function _iterable_to_array_limit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } // ../../../node_modules/@swc/helpers/esm/_non_iterable_rest.js function _non_iterable_rest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } // ../../../node_modules/@swc/helpers/esm/_array_like_to_array.js function _array_like_to_array(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; } // ../../../node_modules/@swc/helpers/esm/_unsupported_iterable_to_array.js function _unsupported_iterable_to_array(o, minLen) { if (!o) return; if (typeof o === "string") return _array_like_to_array(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(n); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen); } // ../../../node_modules/@swc/helpers/esm/_sliced_to_array.js function _sliced_to_array(arr, i) { return _array_with_holes(arr) || _iterable_to_array_limit(arr, i) || _unsupported_iterable_to_array(arr, i) || _non_iterable_rest(); } // src/model.ts var import_react_hooks_core2 = require("@airma/react-hooks-core"); var import_react4 = require("react"); // src/initialize.ts var import_react2 = require("react"); var import_as_model2 = require("as-model"); // ../../../node_modules/@swc/helpers/esm/_array_without_holes.js function _array_without_holes(arr) { if (Array.isArray(arr)) return _array_like_to_array(arr); } // ../../../node_modules/@swc/helpers/esm/_iterable_to_array.js function _iterable_to_array(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) { return Array.from(iter); } } // ../../../node_modules/@swc/helpers/esm/_non_iterable_spread.js function _non_iterable_spread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } // ../../../node_modules/@swc/helpers/esm/_to_consumable_array.js function _to_consumable_array(arr) { return _array_without_holes(arr) || _iterable_to_array(arr) || _unsupported_iterable_to_array(arr) || _non_iterable_spread(); } // src/provider.ts var import_react = require("react"); var import_as_model = require("as-model"); var createStores = (0, import_as_model.config)({}).createStores; var ModelStoresContext = (0, import_react.createContext)(void 0); var ConfigContext = (0, import_react.createContext)(void 0); function ifModelKeyOrStoreIndex(data) { return import_as_model.validations.isModelKey(data) || !!data && import_as_model.validations.isModelKey(data.key); } function parseKeySetToKeys(keySets) { var keySetArray = Array.isArray(keySets) ? keySets : [ keySets ]; return keySetArray.reduce(function(re, cur) { if (ifModelKeyOrStoreIndex(cur)) { return _to_consumable_array(re).concat([ cur ]); } if (!cur) { return re; } var data = Object.values(cur).filter(ifModelKeyOrStoreIndex); return _to_consumable_array(re).concat(_to_consumable_array(data)); }, []); } var Provider = function RequiredModelProvider(param) { var value = param.value, children = param.children; var storeKeys = (function extractCreators() { return parseKeySetToKeys(value); })(); if (storeKeys == null) { throw new Error("You need to provide keys to `Provider`"); } var parent = (0, import_react.useContext)(ModelStoresContext); var _useState = _sliced_to_array((0, import_react.useState)(function() { var collections = createStores.apply(void 0, _to_consumable_array(storeKeys)); return { collections, parent }; }), 2), stores = _useState[0], setStores = _useState[1]; (0, import_react.useEffect)(function() { var _stores_collections; if ((0, import_as_model.shallowEqual)(stores.collections.keys(), _to_consumable_array(storeKeys).map(function(d) { return import_as_model.validations.isModelKey(d) ? d : d.key; })) && stores.parent === parent) { return; } (_stores_collections = stores.collections).update.apply(_stores_collections, _to_consumable_array(storeKeys)); setStores({ collections: stores.collections, parent }); }, [ stores, storeKeys, parent ]); (0, import_react.useEffect)(function() { return function() { stores.collections.destroy(); stores.parent = void 0; }; }, []); return (0, import_react.createElement)(ModelStoresContext.Provider, { value: stores }, children); }; function provide() { for (var _len = arguments.length, keys = new Array(_len), _key = 0; _key < _len; _key++) { keys[_key] = arguments[_key]; } var connect = function connect2(Comp) { return function WithModelProviderComponent(props) { return (0, import_react.createElement)(Provider, { value: keys }, (0, import_react.createElement)(Comp, props)); }; }; connect.to = function to(Comp) { return function WithModelProviderComponent(props) { return (0, import_react.createElement)(Provider, { value: keys }, (0, import_react.createElement)(Comp, props)); }; }; return connect; } var ConfigProvider = function ConfigProvider2(props) { var value = props.value, children = props.children; return (0, import_react.createElement)(ConfigContext.Provider, { value }, children); }; function useStores() { return (0, import_react.useContext)(ModelStoresContext); } function useConfiguration() { var optimizeConfig = (0, import_react.useContext)(ConfigContext); var _ref = optimizeConfig || {}, batchUpdate = _ref.batchUpdate, supports = _ref.supports; return (0, import_react.useMemo)(function() { return { batchUpdate, supports }; }, [ batchUpdate, supports ]); } function useActProcess() { var optimizeConfig = (0, import_react.useContext)(ConfigContext); var test = (optimizeConfig || {}).test; return { act: function act(callback) { if (!test || typeof process === "undefined" || process == null || process.env == null || true) { return callback(); } var result; test.act(function() { result = callback(); }); return result; } }; } // src/initialize.ts function useInitialize(callback) { var ref = (0, import_react2.useRef)(null); if (ref.current == null) { ref.current = { result: callback() }; return ref.current.result; } return ref.current.result; } function findStore(stores, storeIndex) { if (stores == null) { return void 0; } var found = stores.collections.find(storeIndex); if (!found) { return findStore(stores.parent, storeIndex); } return found; } function useModelInitialize(model3, opt) { var _opt_hasDefaultState; var hasDefaultState = (_opt_hasDefaultState = opt === null || opt === void 0 ? void 0 : opt.hasDefaultState) !== null && _opt_hasDefaultState !== void 0 ? _opt_hasDefaultState : false; var state = opt === null || opt === void 0 ? void 0 : opt.state; var controlled = opt === null || opt === void 0 ? void 0 : opt.controlled; var ifModelIsModelOrModelUsage = !import_as_model2.validations.isModelStore(model3) && !import_as_model2.validations.isModelKey(model3); var stores = ifModelIsModelOrModelUsage ? void 0 : useStores(); var optimize = useConfiguration(); var initializedStore = useInitialize(function() { var store = (function findOrCreateStore() { if (import_as_model2.validations.isModelStore(model3)) { var foundStore = findStore(stores, model3); return foundStore !== null && foundStore !== void 0 ? foundStore : model3; } if (import_as_model2.validations.isModelKey(model3)) { var foundStore1 = findStore(stores, model3); if (foundStore1 == null) { throw new Error("Can not find the store of template model key."); } return foundStore1; } if (controlled) { return (0, import_as_model2.config)({ controlled }).model(model3).createStore(); } if (import_as_model2.validations.isModelUsage(model3)) { return model3.createStore(); } var createStore3 = (0, import_as_model2.config)((optimize === null || optimize === void 0 ? void 0 : optimize.batchUpdate) ? { notify: function notify(notifier, action) { var _optimize_batchUpdate; optimize === null || optimize === void 0 ? void 0 : (_optimize_batchUpdate = optimize.batchUpdate) === null || _optimize_batchUpdate === void 0 ? void 0 : _optimize_batchUpdate.call(optimize, function() { var errors = notifier(action).errors; if (!errors || !errors.length) { return; } errors.forEach(function(err) { Promise.reject(err); }); }); } } : {}).model(model3).createStore; return createStore3(); })(); if (hasDefaultState) { store.update({ initialState: state }); } return store; }); (0, import_react2.useEffect)(function() { return function() { if (ifModelIsModelOrModelUsage) { initializedStore.destroy(); } }; }, []); if (ifModelIsModelOrModelUsage) { initializedStore.update(controlled ? { model: model3, state } : { model: model3, silence: true }); } if (import_as_model2.validations.isInstanceFromNoStateModel(initializedStore.getStoreInstance())) { throw new Error("The model store is not initialized."); } return initializedStore; } // src/enhance.ts var import_react_hooks_core = require("@airma/react-hooks-core"); var import_react3 = require("react"); function useRenderProtectDispatch(dispatch) { var configuration = useConfiguration(); var supports = (configuration !== null && configuration !== void 0 ? configuration : {}).supports; var renderAction = (supports !== null && supports !== void 0 ? supports : {}).renderAction; var renderingRef = (0, import_react3.useRef)(renderAction ? [] : null); renderingRef.current = renderAction ? [] : null; var unmountedRef = (0, import_react3.useRef)(false); var dispatcher = (0, import_react_hooks_core.usePersistFn)(function(action) { if (unmountedRef.current) { return; } if (renderingRef.current) { renderingRef.current.push(action); return; } dispatch(action); }); (0, import_react3.useLayoutEffect)(function() { var renderingPhaseActions = renderingRef.current; renderingRef.current = null; if (!(renderingPhaseActions === null || renderingPhaseActions === void 0 ? void 0 : renderingPhaseActions.length)) { return; } renderingPhaseActions.forEach(function(action) { dispatch(action); }); }); (0, import_react3.useEffect)(function() { return function() { unmountedRef.current = true; }; }, []); return dispatcher; } // src/model.ts function useControlledModel(modelLike, state, onChange) { var store = useModelInitialize(modelLike, { hasDefaultState: true, state, controlled: true }); var dispatch = (0, import_react_hooks_core2.usePersistFn)(function(action) { if (action.state === state) { return; } onChange(action.state); }); var subscription = useRenderProtectDispatch(function(action) { dispatch(action); }); (0, import_react4.useEffect)(function() { return store.subscribe(subscription); }, []); return store.getInstance(); } function useModel(modelLike, state) { var hasDefaultState = arguments.length > 1; var store = useModelInitialize(modelLike, { hasDefaultState, state }); var _useState = _sliced_to_array((0, import_react4.useState)(function() { var ins = store.getInstance(); var token = store.getToken(); return { instance: ins, token }; }), 2), data = _useState[0], setData = _useState[1]; var subscription = useRenderProtectDispatch(function() { var token = store.getToken(); if (!data.token.isDifferent(token)) { return; } setData({ instance: store.getInstance(), token }); }); (0, import_react4.useEffect)(function() { return store.subscribe(subscription); }, []); return data.instance; } // src/signal.ts var import_as_model3 = require("as-model"); var import_react5 = require("react"); function useSignalSubscribeConnection(signal, subscription) { var actionsCollectionRef = (0, import_react5.useRef)(null); var changesCollectionRef = (0, import_react5.useRef)({ collector: null, collections: null }); var destroyRef = (0, import_react5.useRef)(null); var protectedDispatch = useRenderProtectDispatch(function(action) { var actionsCollector = actionsCollectionRef.current; var _changesCollectionRef_current = changesCollectionRef.current, changesCollector = _changesCollectionRef_current.collector, changesCollections = _changesCollectionRef_current.collections; var method = action.method; var instance = signal.store.getStoreInstance(); var isActionMethodMatched = (function matchMethod() { if (!actionsCollector) { return true; } var methods = actionsCollector(instance); return Array.isArray(methods) && methods.some(function(m) { return typeof m === "function" && m === method; }); })(); var isChangesMatched = (function matchChanges() { if (changesCollector == null) { return true; } var currentChanges = changesCollector(instance); changesCollectionRef.current.collections = currentChanges; return !(0, import_as_model3.shallowEqual)(changesCollections, currentChanges); })(); if (method != null && (!isActionMethodMatched || !isChangesMatched)) { return; } var prevDestroy = destroyRef.current; if (prevDestroy) { prevDestroy(); } var destroy = subscription(instance, action); destroyRef.current = destroy !== null && destroy !== void 0 ? destroy : null; }); (0, import_react5.useEffect)(function() { var unsubscribe = signal.subscribe(protectedDispatch); return function() { unsubscribe(); var destroy = destroyRef.current; if (destroy) { destroy(); } }; }, []); var res = { onActions: function onActions(collector) { actionsCollectionRef.current = collector; }, onChanges: function onChanges(collector) { changesCollectionRef.current.collector = collector; } }; return { getActionCollector: function getActionCollector() { return actionsCollectionRef.current; }, onActions: function onActions(collector) { res.onActions(collector); return { onChanges: res.onChanges }; }, onChanges: function onChanges(collector) { res.onChanges(collector); return { onActions: res.onActions }; } }; } function getSignalSubscribe(signal) { var useWatch = function useWatch2(subscription) { return useSignalSubscribeConnection(signal, function(ins, act) { if ((act === null || act === void 0 ? void 0 : act.method) == null) { return void 0; } return subscription(ins, act); }); }; var useEffective = function useEffective2(subscription) { var _useState = _sliced_to_array((0, import_react5.useState)({ action: null, instance: signal.store.getStoreInstance() }), 2), wrap = _useState[0], setWrap = _useState[1]; var filter = useSignalSubscribeConnection(signal, function(ins, act) { if ((act === null || act === void 0 ? void 0 : act.method) == null) { return void 0; } setWrap({ action: act, instance: ins }); }); (0, import_react5.useEffect)(function() { if (filter.getActionCollector() != null && wrap.action == null) { return function() { }; } return subscription(wrap.instance, wrap.action); }, [ wrap ]); return filter; }; return { useWatch, useEffect: useEffective }; } function useSignal(modelLike, state) { var hasDefaultState = arguments.length > 1; var store = useModelInitialize(modelLike, { hasDefaultState, state }); var signalStore = useInitialize(function() { return (0, import_as_model3.createSignal)(store); }); var _useState = _sliced_to_array((0, import_react5.useState)(signalStore.getToken()), 2), token = _useState[0], setToken = _useState[1]; var signal = signalStore.getSignal(); signal.startStatistics(); (0, import_react5.useLayoutEffect)(function() { signal.stopStatistics(); }); var subscription = useRenderProtectDispatch(function() { var currentToken = signalStore.getToken(); if (!token.isDifferent(currentToken)) { return; } setToken(currentToken); }); (0, import_react5.useEffect)(function() { return signalStore.subscribe(subscription); }, []); return (0, import_react5.useMemo)(function() { var handler = getSignalSubscribe(signal); var signalCallback = function signalCallback2(opts) { return signal(opts); }; signalCallback.useWatch = handler.useWatch; signalCallback.useEffect = handler.useEffect; signalCallback.store = signal.store; return signalCallback; }, [ token ]); } // src/selector.ts var import_as_model4 = require("as-model"); var import_react_hooks_core3 = require("@airma/react-hooks-core"); var import_react6 = require("react"); function useSelector(modelLike, selector, equalFn) { var equalityFunction = equalFn; var selectorFunction = selector; var equality = (0, import_react_hooks_core3.usePersistFn)(function(a, b) { return equalityFunction ? equalityFunction(a, b) : a === b; }); var store = useModelInitialize(modelLike); var selectStore = useInitialize(function() { return (0, import_as_model4.createSelector)(store, equalFn ? { equality } : {}); }); var computeResult = function computeResult2() { var token = selectStore.getToken(); var selected = selectStore.select(function(i) { return selectorFunction(i()); }); return { token, selected }; }; var _useState = _sliced_to_array((0, import_react6.useState)(computeResult), 2), result = _useState[0], setResult = _useState[1]; var subscription = useRenderProtectDispatch(function() { var newResult = computeResult(); if (!newResult.token.isDifferent(result.token)) { return; } if (result.selected === newResult.selected) { return; } setResult(newResult); }); (0, import_react6.useEffect)(function() { return selectStore.subscribe(subscription); }, []); return result.selected; } // src/entry.ts var import_as_model5 = require("as-model"); var model = function model2(modelLike) { var wrapper = import_as_model5.validations.isModelUsage(modelLike) ? modelLike.wrapper : void 0; var modelUsage = wrapper ? (0, import_as_model5.config)({}).model(modelLike, wrapper) : (0, import_as_model5.config)({}).model(modelLike); var originalCreateKey = modelUsage.createKey, originalCreateStore = modelUsage.createStore, originalProduce = modelUsage.produce; function produce(callback) { var newUsage = originalProduce(callback); return model2(newUsage); } var createUsageKey = function createUsageKey2(defaultState) { var hasDefaultState = arguments.length > 0; var key = hasDefaultState ? originalCreateKey(defaultState) : originalCreateKey(); var useKeyModel = function useKeyModel2(defaultModelState) { var parameters = arguments.length > 0 ? [ key, defaultModelState ] : [ key ]; return useModel.apply(void 0, _to_consumable_array(parameters)); }; var useKeySignal = function useKeySignal2(defaultModelState) { var parameters = arguments.length > 0 ? [ key, defaultModelState ] : [ key ]; return useSignal.apply(void 0, _to_consumable_array(parameters)); }; function useKeySelector(callback, equality) { return useSelector(key, callback, equality); } return key.extends({ useModel: useKeyModel, useSignal: useKeySignal, useSelector: useKeySelector }); }; var createUsageStore = function createUsageStore2(defaultState) { var hasDefaultState = arguments.length > 0; var store = hasDefaultState ? originalCreateStore(defaultState) : originalCreateStore(); var useStoreModel = function useStoreModel2(defaultModelState) { var parameters = arguments.length > 0 ? [ store, defaultModelState ] : [ store ]; return useModel.apply(void 0, _to_consumable_array(parameters)); }; var useStoreSignal = function useStoreSignal2(defaultModelState) { var parameters = arguments.length > 0 ? [ store, defaultModelState ] : [ store ]; return useSignal.apply(void 0, _to_consumable_array(parameters)); }; function useStoreSelector(callback, equality) { return useSelector(store, callback, equality); } return store.extends({ useModel: useStoreModel, useSignal: useStoreSignal, useSelector: useStoreSelector, instance: function instance(initialState) { var hasInitialState = arguments.length > 0; if (hasInitialState) { store.update({ initialState }); } return store.getInstance(); } }); }; var useUsageModel = function useUsageModel2(defaultModelState) { return useModel(modelLike, defaultModelState); }; var useUsageSignal = function useUsageSignal2(defaultModelState) { return useSignal(modelLike, defaultModelState); }; function useUsageControlledModel(state, onChange) { return useControlledModel(modelUsage, state, onChange); } modelUsage.extends({ produce, createKey: createUsageKey, createStore: createUsageStore, useControlledModel: useUsageControlledModel, useModel: useUsageModel, useSignal: useUsageSignal }); return modelUsage; }; var asModel = (0, import_as_model5.config)({}).model; model.create = model; model.createField = asModel.createField; model.createMethod = asModel.createMethod; // src/validations.ts var import_as_model6 = require("as-model"); // src/index.ts var shallowEqual2 = import_as_model7.shallowEqual; var createKey = function createKey2(modelFn, defaultState) { var hasDefaultState = arguments.length > 1; return hasDefaultState ? (0, import_as_model7.config)({}).createKey(modelFn, defaultState) : (0, import_as_model7.config)({}).createKey(modelFn); }; var createStore = function createStore2(modelFn, defaultState) { var hasDefaultState = arguments.length > 1; return hasDefaultState ? (0, import_as_model7.config)({}).createStore(modelFn, defaultState) : (0, import_as_model7.config)({}).createStore(modelFn); };