@restate/core
Version:
_Restate_ is a predictable, easy to use, easy to integrate, typesafe state container for [React](https://reactjs.org/).
97 lines (96 loc) • 3.47 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);
var create_next_hook_exports = {};
__export(create_next_hook_exports, {
createNextHook: () => createNextHook
});
module.exports = __toCommonJS(create_next_hook_exports);
var import_immer = require("immer");
var import_react = require("react");
var import_utils = require("./utils");
function createNextHook(provider, scope) {
function useNextHook(selector, trace) {
const store = (0, import_react.useContext)(provider);
const outerSelector = scope ? scope : (state) => state;
function updateNestedState(subState, nextValue) {
const proxy = getProxy({ subState, selector, outerSelector });
mutateNestedObject({ proxy, nextValue });
return subState;
}
function updateState(updateFunctionOrNextState) {
return store.next((currentState) => {
if ((0, import_utils.isFunction)(updateFunctionOrNextState)) {
const subState = selector(outerSelector(currentState));
return updateFunctionOrNextState(subState);
} else {
const nextValue = updateFunctionOrNextState;
return updateNestedState(currentState, nextValue);
}
}, trace);
}
return updateState;
}
return useNextHook;
}
function getProxy(props) {
const { subState, selector, outerSelector } = props;
const unfrozenSupState = Object.isFrozen(subState) ? Object.assign({}, (0, import_immer.current)(subState)) : subState;
let path = [];
const proxyAccess = (parent) => ({
get(target2, key) {
if (Array.isArray(target2) && isNaN(key)) {
return target2[key];
}
if (key === "___restate_parent___") {
return parent;
}
path.push({
parent,
target: target2,
key,
idx: Array.isArray(parent) ? parent.indexOf(target2) : -1
});
if (typeof target2[key] === "object" && target2[key] !== null) {
return new Proxy(target2[key], proxyAccess(target2));
} else if (Array.isArray(target2) && !isNaN(key)) {
return new Proxy(target2[key], proxyAccess(target2));
} else {
return target2[key];
}
}
});
const proxy = new Proxy(unfrozenSupState, proxyAccess(unfrozenSupState));
const target = selector(outerSelector(proxy));
if (Array.isArray(target.___restate_parent___)) {
return {
...path.at(-1),
isArray: true
};
}
return { ...path.at(-1), isArray: false, idx: -1 };
}
function mutateNestedObject(props) {
const { proxy, nextValue } = props;
const { target, key, isArray, idx, parent } = proxy;
if (isArray && typeof parent[idx] === typeof nextValue) {
parent[idx] = nextValue;
} else {
target[key] = nextValue;
}
}