@airma/react-state
Version:
the purpose of this project is make useReducer more simplify
755 lines (732 loc) • 25.4 kB
JavaScript
;
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);
};