react-use-state-x
Version:
Complex state management and global store done in type-safe, high-performance way using react useState/useContext hooks.
876 lines (865 loc) • 34 kB
JavaScript
import React from 'react';
function extractValue(prevValue, value) {
if (typeof value === 'function') {
return value(prevValue);
}
return value;
}
function createArrayStateMutation(setValue) {
// All actions (except set) should crash if prevValue is null or undefined.
// It is intentional behavior.
// Although this situation is not allowed by type checking of the typescript,
// it is still possible to get null coming from ValueLink (see notes in the ValueLinkImpl)
return {
set: setValue,
merge: function (other) {
setValue(function (prevValue) {
var copy = prevValue.slice();
var source = extractValue(copy, other);
Object.keys(source).sort().forEach(function (i) {
var index = Number(i);
copy[index] = source[index];
});
return copy;
});
},
update: function (key, value) {
setValue(function (prevValue) {
var copy = prevValue.slice();
copy[key] = extractValue(copy[key], value);
return copy;
});
},
concat: function (other) {
if (other) {
setValue(function (prevValue) {
var copy = prevValue.slice();
return copy.concat(extractValue(copy, other));
});
}
},
push: function (elem) {
setValue(function (prevValue) {
var copy = prevValue.slice();
copy.push(elem);
return copy;
});
},
pop: function () {
setValue(function (prevValue) {
var copy = prevValue.slice();
copy.pop();
return copy;
});
},
insert: function (index, elem) {
setValue(function (prevValue) {
var copy = prevValue.slice();
copy.splice(index, 0, elem);
return copy;
});
},
remove: function (index) {
setValue(function (prevValue) {
var copy = prevValue.slice();
copy.splice(index, 1);
return copy;
});
},
swap: function (index1, index2) {
setValue(function (prevValue) {
var copy = prevValue.slice();
copy[index1] = prevValue[index2];
copy[index2] = prevValue[index1];
return copy;
});
}
};
}
function useStateArray(initialState) {
var _a = React.useState(initialState), value = _a[0], setValue = _a[1];
return [value, createArrayStateMutation(setValue)];
}
/*! *****************************************************************************
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.
***************************************************************************** */
/* global Reflect, Promise */
var extendStatics = function(d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b);
};
function __extends(d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
}
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 extractValue$1(prevValue, value) {
if (typeof value === 'function') {
return value(prevValue);
}
return value;
}
function createObjectStateMutation(setValue) {
// All actions (except set and merge with empty object) should crash
// if prevValue is null or undefined. It is intentional behavior.
// Although this situation is not allowed by type checking of the typescript,
// it is still possible to get null coming from ValueLink (see notes in the ValueLinkImpl)
var merge = function (value) {
setValue(function (prevValue) {
var extractedValue = extractValue$1(prevValue, value);
var keys = Object.keys(extractedValue);
if (keys.length === 0) {
// empty object to merge with
return prevValue;
}
// this causes the intended crash if merging with
// the prevously set to undefined | null value
// eslint-disable-next-line
var _unused = prevValue[keys[0]];
return __assign({}, (prevValue
// this causes the intended crash if merging with
// the prevously set to undefined | null value
// and the block with _unused variable is optimized out
// by a bundler like webpack, minify, etc.
|| Object.keys(prevValue)), extractedValue);
});
};
return {
set: setValue,
merge: merge,
update: function (key, value) { return merge(function (prevValue) {
var partialResult = {};
partialResult[key] = extractValue$1(
// this causes the intended crash if updating the property of
// the prevously set to undefined | null value
prevValue[key], value);
return partialResult;
}); }
};
}
function useStateObject(initialState) {
var _a = React.useState(initialState), value = _a[0], setValue = _a[1];
return [value, createObjectStateMutation(setValue)];
}
var ValidationSeverity;
(function (ValidationSeverity) {
ValidationSeverity[ValidationSeverity["WARNING"] = 1] = "WARNING";
ValidationSeverity[ValidationSeverity["ERROR"] = 2] = "ERROR";
})(ValidationSeverity || (ValidationSeverity = {}));
function defaultEqualityOperator(a, b) {
if (typeof b === 'object') {
// check reference equality first for speed
if (a === b) {
return true;
}
return JSON.stringify(a) === JSON.stringify(b);
}
return a === b;
}
// tslint:disable-next-line:no-any
var defaultProcessingHooks = {};
function resolveSettings(settings) {
return {
skipSettingEqual: (settings && settings.skipSettingEqual) || false,
globalHooks: (settings && settings.globalHooks) || defaultProcessingHooks,
targetHooks: (settings && settings.targetHooks) || defaultProcessingHooks
};
}
function extractValue$2(prevValue, newValue) {
if (typeof newValue === 'function') {
return newValue(prevValue);
}
return newValue;
}
var ReadonlyState = /** @class */ (function () {
// eslint-disable-next-line no-useless-constructor
function ReadonlyState(
// tslint:disable-next-line:no-any
_initial,
// tslint:disable-next-line:no-any
_current, _edition, _settings) {
this._initial = _initial;
this._current = _current;
this._edition = _edition;
this._settings = _settings;
}
ReadonlyState.prototype.getCurrent = function (path) {
var result = this._current;
path.forEach(function (p) {
result = result[p];
});
return result;
};
ReadonlyState.prototype.getInitial = function (path) {
var result = this._initial;
path.forEach(function (p) {
// in contrast to the current value,
// allow the initial may not exist
result = result && result[p];
});
return result;
};
Object.defineProperty(ReadonlyState.prototype, "edition", {
get: function () {
return this._edition;
},
enumerable: true,
configurable: true
});
Object.defineProperty(ReadonlyState.prototype, "settings", {
get: function () {
return this._settings;
},
enumerable: true,
configurable: true
});
ReadonlyState.prototype.globalHooks = function () {
return this._settings.globalHooks;
};
// tslint:disable-next-line:no-any
ReadonlyState.prototype.targetHooks = function (path) {
var result = this._settings.targetHooks;
path.forEach(function (p) {
result = result && (result[p] || (typeof p === 'number' && result['*']));
});
return result || defaultProcessingHooks;
};
return ReadonlyState;
}());
var State = /** @class */ (function (_super) {
__extends(State, _super);
// eslint-disable-next-line no-useless-constructor
function State(
// tslint:disable-next-line:no-any
_initial,
// tslint:disable-next-line:no-any
_current, _edition, _settings) {
return _super.call(this, _initial, _current, _edition, _settings) || this;
}
// tslint:disable-next-line:no-any
State.prototype.setCurrent = function (value) {
this._edition += 1;
this._current = value;
return this;
};
// tslint:disable-next-line:no-any
State.prototype.setInitial = function (value) {
// update edition on every mutation
// so consumers can invalidate their caches
this._edition += 1;
this._initial = value;
return this;
};
return State;
}(ReadonlyState));
var ValueLinkImpl = /** @class */ (function () {
// eslint-disable-next-line no-useless-constructor
function ValueLinkImpl(state, path, onSet) {
this.state = state;
this.path = path;
this.onSet = onSet;
this.inferredCache = undefined;
this.inferredCacheEdition = -1;
this.valueCacheEdition = -1;
this.initialValueCacheEdition = -1;
this.hooksCacheEdition = -1;
this.modifiedCacheEdition = -1;
this.errorsCacheEdition = -1;
}
Object.defineProperty(ValueLinkImpl.prototype, "value", {
get: function () {
if (this.valueCacheEdition < this.state.edition) {
this.valueCacheEdition = this.state.edition;
this.valueCache = this.state.getCurrent(this.path);
}
return this.valueCache;
},
enumerable: true,
configurable: true
});
Object.defineProperty(ValueLinkImpl.prototype, "initialValue", {
get: function () {
if (this.initialValueCacheEdition < this.state.edition) {
this.initialValueCacheEdition = this.state.edition;
this.initialValueCache = this.state.getInitial(this.path);
}
return this.initialValueCache;
},
enumerable: true,
configurable: true
});
Object.defineProperty(ValueLinkImpl.prototype, "hooks", {
get: function () {
if (this.hooksCacheEdition < this.state.edition) {
this.hooksCacheEdition = this.state.edition;
this.hooksCache = this.state.targetHooks(this.path);
}
return this.hooksCache;
},
enumerable: true,
configurable: true
});
ValueLinkImpl.prototype.set = function (newValue) {
// inferred() function checks for the nullability of the current value:
// If value is not null | undefined, it resolves to ArrayLink or ObjectLink
// which can not take null | undefined as a value.
// However, it is possible that a user of this ValueLink
// may call set(null | undefined).
// In this case this null will leak via setValue(prevValue => ...)
// to mutation actions for array or object,
// which breaks the guarantee of ArrayLink and ObjectLink to not link nullable value.
// Currently this causes a crash within ObjectLink or ArrayLink mutation actions.
// This behavior is left intentionally to make it equivivalent to the following:
// Example (plain JS):
// let myvar: { a: string, b: string } = { a: '', b: '' }
// myvar = undefined;
// myvar.a = '' // <-- crash here
// myvar = { a: '', b: '' } // <-- OK
// Example (using value links):
// let myvar = useStateLink({ a: '', b: '' } as { a: string, b: string } | undefined);
// let myvar_a = myvar.nested.a; // get value link to a property
// myvar.set(undefined);
// myvar_a.set('') // <-- crash here
// myvar.set({ a: '', b: '' }) // <-- OK
var extractedNewValue = extractValue$2(this.value, newValue);
var localPreset = this.hooks.__preset;
if (localPreset) {
extractedNewValue = localPreset(extractedNewValue, this);
}
var globalPreset = this.state.globalHooks().__preset;
if (globalPreset) {
extractedNewValue = globalPreset(extractedNewValue, this);
}
if (this.state.settings.skipSettingEqual &&
this.areValuesEqual(extractedNewValue, this.value)) {
return;
}
this.onSet(extractedNewValue);
};
ValueLinkImpl.prototype.areValuesEqual = function (newValue, oldValue) {
var localCompare = this.hooks.__compare;
if (localCompare) {
var localCompareResult = localCompare(newValue, oldValue, this);
if (localCompareResult !== undefined) {
return localCompareResult;
}
}
var globalCompare = this.state.globalHooks().__compare;
if (globalCompare) {
var globalCompareResult = globalCompare(newValue, oldValue, this);
if (globalCompareResult !== undefined) {
return globalCompareResult;
}
}
return defaultEqualityOperator(newValue, oldValue);
};
Object.defineProperty(ValueLinkImpl.prototype, "modified", {
get: function () {
if (this.modifiedCacheEdition < this.state.edition) {
this.modifiedCacheEdition = this.state.edition;
this.modifiedCache = !this.areValuesEqual(this.value, this.initialValue);
}
return this.modifiedCache;
},
enumerable: true,
configurable: true
});
Object.defineProperty(ValueLinkImpl.prototype, "unmodified", {
get: function () {
return !this.modified;
},
enumerable: true,
configurable: true
});
Object.defineProperty(ValueLinkImpl.prototype, "valid", {
get: function () {
return this.errors.length === 0;
},
enumerable: true,
configurable: true
});
Object.defineProperty(ValueLinkImpl.prototype, "invalid", {
get: function () {
return !this.valid;
},
enumerable: true,
configurable: true
});
ValueLinkImpl.prototype.validate = function (validator) {
var _this = this;
if (validator) {
var errors = validator(this.value, this);
if (errors !== undefined) {
if (Array.isArray(errors)) {
return errors.map(function (m) {
return typeof m === 'string' ? {
path: _this.path,
message: m,
severity: ValidationSeverity.ERROR
} : {
path: _this.path,
message: m.message,
severity: m.severity
};
});
}
else if (typeof errors === 'string') {
return [{
path: this.path,
message: errors,
severity: ValidationSeverity.ERROR
}];
}
else {
return [{
path: this.path,
message: errors.message,
severity: errors.severity
}];
}
}
}
return undefined;
};
Object.defineProperty(ValueLinkImpl.prototype, "errors", {
get: function () {
if (this.errorsCacheEdition < this.state.edition) {
this.errorsCacheEdition = this.state.edition;
var localHooks_1 = this.hooks;
var result_1 = this.validate(localHooks_1.__validate) ||
this.validate(this.state.globalHooks().__validate) ||
[];
var nestedHooks = Object.keys(localHooks_1).filter(function (i) { return typeof localHooks_1[i] !== 'function'; });
if (nestedHooks.length > 0 && this.nested) {
var nestedInst_1 = this.nested;
if (Array.isArray(nestedInst_1)) {
if (localHooks_1['*']) {
nestedInst_1.forEach(function (n, i) {
result_1 = result_1.concat(n.errors);
});
}
nestedHooks
// Validation rule exists,
// but the corresponding nested link may not be created,
// (because it may not be inferred automatically)
// because the original array value cas miss the corresponding index
// The design choice is to skip validation in this case.
// A client can define per array level validation rule,
// where existance of the index can be cheched.
.filter(function (k) { return typeof k === 'number' && nestedInst_1[k] !== undefined; })
.forEach(function (k) {
result_1 = result_1.concat(nestedInst_1[k].errors);
});
}
else if (nestedInst_1) {
nestedHooks
// Validation rule exists,
// but the corresponding nested link may not be created,
// (because it may not be inferred automatically)
// because the original object value can miss the corresponding key
// The design choice is to skip validation in this case.
// A client can define per object level validation rule,
// where existance of the property can be cheched.
.filter(function (k) { return nestedInst_1[k] !== undefined; })
.forEach(function (k) {
result_1 = result_1.concat(nestedInst_1[k].errors);
});
}
}
var first_1 = function (condition) {
return result_1.find(function (e) { return condition ? condition(e) : true; });
};
var firstPartial = function (condition) {
var r = first_1(condition);
if (r === undefined) {
return {};
}
return r;
};
Object.assign(result_1, {
first: first_1,
firstPartial: firstPartial
});
this.errorsCache = result_1;
}
return this.errorsCache;
},
enumerable: true,
configurable: true
});
Object.defineProperty(ValueLinkImpl.prototype, "inferred", {
get: function () {
if (this.inferredCacheEdition < this.state.edition) {
this.inferredCacheEdition = this.state.edition;
if (Array.isArray(this.value)) {
this.inferredCache = new ArrayLinkImpl(this);
}
else if (typeof this.value === 'object' && this.value !== null) {
this.inferredCache = new ObjectLinkImpl(this);
}
else {
this.inferredCache = undefined;
}
}
return this.inferredCache;
},
enumerable: true,
configurable: true
});
Object.defineProperty(ValueLinkImpl.prototype, "nested", {
get: function () {
var inferred = this.inferred;
if (inferred instanceof ArrayLinkImpl) {
return inferred.nestedImpl;
}
else if (inferred instanceof ObjectLinkImpl) {
return inferred.nestedImpl;
}
return undefined;
},
enumerable: true,
configurable: true
});
return ValueLinkImpl;
}());
var ProxyLink = /** @class */ (function () {
function ProxyLink(origin) {
this.origin = origin;
if (origin instanceof ProxyLink) {
origin = origin.origin;
}
}
Object.defineProperty(ProxyLink.prototype, "path", {
get: function () {
return this.origin.path;
},
enumerable: true,
configurable: true
});
Object.defineProperty(ProxyLink.prototype, "initialValue", {
get: function () {
return this.origin.initialValue;
},
enumerable: true,
configurable: true
});
Object.defineProperty(ProxyLink.prototype, "value", {
get: function () {
return this.origin.value;
},
enumerable: true,
configurable: true
});
Object.defineProperty(ProxyLink.prototype, "nested", {
get: function () {
return this.origin.nested;
},
enumerable: true,
configurable: true
});
Object.defineProperty(ProxyLink.prototype, "modified", {
get: function () {
return this.origin.modified;
},
enumerable: true,
configurable: true
});
Object.defineProperty(ProxyLink.prototype, "unmodified", {
get: function () {
return this.origin.unmodified;
},
enumerable: true,
configurable: true
});
Object.defineProperty(ProxyLink.prototype, "valid", {
get: function () {
return this.origin.valid;
},
enumerable: true,
configurable: true
});
Object.defineProperty(ProxyLink.prototype, "invalid", {
get: function () {
return this.origin.invalid;
},
enumerable: true,
configurable: true
});
Object.defineProperty(ProxyLink.prototype, "errors", {
get: function () {
return this.origin.errors;
},
enumerable: true,
configurable: true
});
Object.defineProperty(ProxyLink.prototype, "inferred", {
get: function () {
return this;
},
enumerable: true,
configurable: true
});
ProxyLink.prototype.set = function (newValue) {
this.origin.set(newValue);
};
return ProxyLink;
}());
var ArrayLinkImpl = /** @class */ (function (_super) {
__extends(ArrayLinkImpl, _super);
function ArrayLinkImpl(originImpl) {
var _this = _super.call(this, originImpl) || this;
_this.originImpl = originImpl;
_this.nestedCache = undefined;
_this.nestedCacheEdition = -1;
_this.arrayMutation = createArrayStateMutation(function (newValue) { return originImpl.set(newValue); });
return _this;
}
ArrayLinkImpl.prototype.set = function (newValue) {
this.arrayMutation.set(newValue);
};
ArrayLinkImpl.prototype.merge = function (other) {
this.arrayMutation.merge(other);
};
ArrayLinkImpl.prototype.update = function (key, value) {
this.arrayMutation.update(key, value);
};
ArrayLinkImpl.prototype.concat = function (other) {
this.arrayMutation.concat(other);
};
ArrayLinkImpl.prototype.push = function (elem) {
this.arrayMutation.push(elem);
};
ArrayLinkImpl.prototype.pop = function () {
this.arrayMutation.pop();
};
ArrayLinkImpl.prototype.insert = function (index, elem) {
this.arrayMutation.insert(index, elem);
};
ArrayLinkImpl.prototype.remove = function (index) {
this.arrayMutation.remove(index);
};
ArrayLinkImpl.prototype.swap = function (index1, index2) {
this.arrayMutation.swap(index1, index2);
};
Object.defineProperty(ArrayLinkImpl.prototype, "nestedImpl", {
get: function () {
var _this = this;
if (this.nestedCacheEdition < this.originImpl.state.edition) {
this.nestedCacheEdition = this.originImpl.state.edition;
var result_2 = [];
this.value.forEach(function (_, index) {
result_2[index] = _this.atImpl(index);
});
Object.assign(result_2, {
at: function (k) {
if (result_2[k] === undefined) {
result_2[k] = _this.atImpl(k);
}
return result_2[k];
}
});
this.nestedCache = result_2;
}
return this.nestedCache;
},
enumerable: true,
configurable: true
});
ArrayLinkImpl.prototype.atImpl = function (k) {
var _this = this;
return new ValueLinkImpl(this.originImpl.state, this.path.slice().concat(k), function (newValue) { return _this.arrayMutation.update(k, newValue); });
};
return ArrayLinkImpl;
}(ProxyLink));
var ObjectLinkImpl = /** @class */ (function (_super) {
__extends(ObjectLinkImpl, _super);
function ObjectLinkImpl(originImpl) {
var _this = _super.call(this, originImpl) || this;
_this.originImpl = originImpl;
_this.nestedCache = undefined;
_this.nestedCacheEdition = -1;
_this.objectMutation = createObjectStateMutation(function (newValue) { return originImpl.set(newValue); });
return _this;
}
ObjectLinkImpl.prototype.set = function (newValue) {
this.objectMutation.set(newValue);
};
ObjectLinkImpl.prototype.merge = function (newValue) {
this.objectMutation.merge(newValue);
};
ObjectLinkImpl.prototype.update = function (key, value) {
this.objectMutation.update(key, value);
};
Object.defineProperty(ObjectLinkImpl.prototype, "nestedImpl", {
get: function () {
var _this = this;
if (this.nestedCacheEdition < this.originImpl.state.edition) {
this.nestedCacheEdition = this.originImpl.state.edition;
var result_3 = {};
Object.keys(this.value).forEach(function (k) {
result_3[k] = _this.atImpl(k);
});
Object.assign(result_3, {
// tslint:disable-next-line:no-any
at: function (k) {
if (result_3[k] === undefined) {
result_3[k] = _this.atImpl(k);
}
return result_3[k];
}
});
this.nestedCache = result_3;
}
return this.nestedCache;
},
enumerable: true,
configurable: true
});
ObjectLinkImpl.prototype.atImpl = function (k) {
var _this = this;
return new ValueLinkImpl(this.originImpl.state, this.path.slice().concat(k.toString()), function (newValue) { return _this.objectMutation.update(k, newValue); });
};
return ObjectLinkImpl;
}(ProxyLink));
var StateLinkImpl = /** @class */ (function () {
function StateLinkImpl(initial, settings) {
var _this = this;
this.settings = settings;
this.context = undefined;
this.subscribers = [];
// tslint:disable-next-line:function-name
this.Observer = function (props) {
var _a = React.useState({
state: _this.state
}), value = _a[0], setState = _a[1];
React.useEffect(function () {
_this.subscribers.push(setState);
return function () {
_this.subscribers = _this.subscribers.filter(function (s) { return s !== setState; });
};
}, [setState]);
if (_this.context === undefined) {
_this.context = React.createContext(value);
}
// submit new value every time to trigger rerender for children
return React.createElement(_this.context.Provider, __assign({}, props, { value: value }));
};
var initialValue = initial;
if (typeof initial === 'function') {
initialValue = initial();
}
this.state = new State(initialValue, initialValue, 0, settings);
this.link = new ValueLinkImpl(this.state, [], function (newValue) {
_this.state.setCurrent(newValue);
var newRef = {
state: _this.state
};
_this.subscribers.forEach(function (s) { return s(newRef); });
});
}
return StateLinkImpl;
}());
function createStateLink(initial, settings) {
return new StateLinkImpl(initial, resolveSettings(settings));
}
function useProxyStateLink(originLink) {
var _a = React.useState({
state: new State(originLink.initialValue, originLink.value, 0, __assign({}, originLink.state.settings, { targetHooks: originLink.hooks })),
originInitEdition: originLink.state.edition,
}), value = _a[0], setValue = _a[1];
var isLocalStateStale = originLink.state.edition > value.originInitEdition;
if (isLocalStateStale) {
value.state = new State(originLink.initialValue, originLink.value, 0, __assign({}, originLink.state.settings, { targetHooks: originLink.hooks }));
}
var result = new ValueLinkImpl(value.state, [], function (newValue) { return setValue({
state: value.state.setCurrent(newValue),
originInitEdition: originLink.state.edition
}); });
React.useEffect(function () {
// set when the errors change, not just when validity status changes
if (!defaultEqualityOperator(result.errors, originLink.errors) ||
originLink.modified !== result.modified) {
originLink.set(result.value);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [
// eslint-disable-next-line react-hooks/exhaustive-deps
JSON.stringify(result.errors),
// eslint-disable-next-line react-hooks/exhaustive-deps
JSON.stringify(originLink.errors),
originLink.modified,
result.modified
]);
return result;
}
function useContextStateLink(stateLink) {
if (stateLink.context === undefined) {
// this allows to edit the global state
// whitout active observers
return stateLink.link;
}
// It is expected to be called within the provider scope,
// after the context has been initialized
// If not, the useContext will crash on undefined context.
// Note: useContext is need to trigger rerendering the component
// when state link changes its value.
// eslint-disable-next-line react-hooks/rules-of-hooks
React.useContext(stateLink.context);
return stateLink.link;
}
function useLocalStateLink(initialState, settings) {
var _a = React.useState(function () {
var initialValue = initialState;
if (typeof initialState === 'function') {
initialValue = initialState();
}
return {
state: new State(initialValue, initialValue, 0, resolveSettings(settings))
};
}), value = _a[0], setValue = _a[1];
return new ValueLinkImpl(value.state, [], function (newValue) {
setValue({
state: value.state.setCurrent(newValue)
});
});
}
function useStateLink(initialState, settings) {
if (initialState instanceof ValueLinkImpl) {
// eslint-disable-next-line react-hooks/rules-of-hooks
return useProxyStateLink(initialState);
}
if (initialState instanceof ProxyLink &&
initialState.origin instanceof ValueLinkImpl) {
// eslint-disable-next-line react-hooks/rules-of-hooks
return useProxyStateLink(initialState.origin);
}
if (initialState instanceof StateLinkImpl) {
// eslint-disable-next-line react-hooks/rules-of-hooks
return useContextStateLink(initialState);
}
// eslint-disable-next-line react-hooks/rules-of-hooks
return useLocalStateLink(initialState, settings);
}
export { ValidationSeverity, createArrayStateMutation, createObjectStateMutation, createStateLink, useStateArray, useStateLink, useStateObject };
//# sourceMappingURL=index.es.js.map