mobx-keystone
Version:
A MobX powered state management solution based on data trees with first class support for TypeScript, snapshots, patches and much more
1,623 lines (1,622 loc) • 1.23 MB
JavaScript
var __defProp = Object.defineProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
import * as mobx from "mobx";
import { isObservableMap, isObservableSet, isObservableArray, isObservableObject, createAtom, runInAction, action, computed, isAction, set, reaction, isObservable, toJS, remove, observable, intercept, observe, when, untracked, transaction as transaction$1, values, get, has, keys, entries } from "mobx";
const dataModelActionRegistry = /* @__PURE__ */ new Map();
function getDataModelAction(fullActionName) {
return dataModelActionRegistry.get(fullActionName);
}
function setDataModelAction(fullActionName, modelClass2, fnName) {
dataModelActionRegistry.set(fullActionName, {
modelClass: modelClass2,
fnName
});
}
var BuiltInAction = /* @__PURE__ */ ((BuiltInAction2) => {
BuiltInAction2["ApplyPatches"] = "$$applyPatches";
BuiltInAction2["ApplySnapshot"] = "$$applySnapshot";
BuiltInAction2["Detach"] = "$$detach";
BuiltInAction2["ApplySet"] = "$$applySet";
BuiltInAction2["ApplyDelete"] = "$$applyDelete";
BuiltInAction2["ApplyMethodCall"] = "$$applyMethodCall";
return BuiltInAction2;
})(BuiltInAction || {});
const builtInActionValues = new Set(Object.values(BuiltInAction));
function isBuiltInAction(actionName) {
return builtInActionValues.has(actionName);
}
var ActionContextActionType = /* @__PURE__ */ ((ActionContextActionType2) => {
ActionContextActionType2["Sync"] = "sync";
ActionContextActionType2["Async"] = "async";
return ActionContextActionType2;
})(ActionContextActionType || {});
var ActionContextAsyncStepType = /* @__PURE__ */ ((ActionContextAsyncStepType2) => {
ActionContextAsyncStepType2["Spawn"] = "spawn";
ActionContextAsyncStepType2["Return"] = "return";
ActionContextAsyncStepType2["Resume"] = "resume";
ActionContextAsyncStepType2["ResumeError"] = "resumeError";
ActionContextAsyncStepType2["Throw"] = "throw";
return ActionContextAsyncStepType2;
})(ActionContextAsyncStepType || {});
let currentActionContext;
function getCurrentActionContext() {
return currentActionContext;
}
function setCurrentActionContext(ctx) {
currentActionContext = ctx;
}
const modelActionSymbol = Symbol("modelAction");
function isModelAction(fn) {
return typeof fn === "function" && modelActionSymbol in fn;
}
const modelTypeKey = "$modelType";
const modelIdKey = "$modelId";
function isReservedModelKey(key) {
return key === modelTypeKey;
}
class MobxKeystoneError extends Error {
constructor(msg) {
super(msg);
Object.setPrototypeOf(this, MobxKeystoneError.prototype);
}
}
function failure(msg) {
return new MobxKeystoneError(msg);
}
const writableHiddenPropDescriptor = {
enumerable: false,
writable: true,
configurable: false,
value: void 0
};
function addHiddenProp(object, propName, value, writable = true) {
if (writable) {
Object.defineProperty(object, propName, writableHiddenPropDescriptor);
object[propName] = value;
} else {
Object.defineProperty(object, propName, {
enumerable: false,
writable,
configurable: true,
value
});
}
}
function makePropReadonly(object, propName, enumerable) {
const propDesc = Object.getOwnPropertyDescriptor(object, propName);
if (propDesc) {
propDesc.enumerable = enumerable;
if (propDesc.get) {
delete propDesc.set;
} else {
propDesc.writable = false;
}
Object.defineProperty(object, propName, propDesc);
}
}
function isPlainObject(value) {
if (!isObject(value)) {
return false;
}
const proto = Object.getPrototypeOf(value);
return proto === Object.prototype || proto === null;
}
function isObject(value) {
return value !== null && typeof value === "object";
}
function isPrimitive(value) {
switch (typeof value) {
case "number":
case "string":
case "boolean":
case "undefined":
case "bigint":
return true;
default:
return value === null;
}
}
function isJSONPrimitive(value) {
switch (typeof value) {
case "number":
return Number.isFinite(value);
case "string":
case "boolean":
return true;
default:
return value === null;
}
}
function deleteFromArray(array, value) {
const index = array.indexOf(value);
if (index >= 0) {
array.splice(index, 1);
return true;
}
return false;
}
function isMap(val) {
return val instanceof Map || isObservableMap(val);
}
function isSet(val) {
return val instanceof Set || isObservableSet(val);
}
function isArray(val) {
return Array.isArray(val) || isObservableArray(val);
}
const inDevMode = process.env.NODE_ENV !== "production";
function assertIsObject(value, argName) {
if (!isObject(value)) {
throw failure(`${argName} must be an object`);
}
}
function assertIsPlainObject(value, argName) {
if (!isPlainObject(value)) {
throw failure(`${argName} must be a plain object`);
}
}
function assertIsObservableObject(value, argName) {
if (!isObservableObject(value)) {
throw failure(`${argName} must be an observable object`);
}
}
function assertIsObservableArray(value, argName) {
if (!isObservableArray(value)) {
throw failure(`${argName} must be an observable array`);
}
}
function assertIsMap(value, argName) {
if (!isMap(value)) {
throw failure(`${argName} must be a map`);
}
}
function assertIsSet(value, argName) {
if (!isSet(value)) {
throw failure(`${argName} must be a set`);
}
}
function assertIsFunction(value, argName) {
if (typeof value !== "function") {
throw failure(`${argName} must be a function`);
}
}
function assertIsPrimitive(value, argName) {
if (!isPrimitive(value)) {
throw failure(`${argName} must be a primitive`);
}
}
function assertIsString(value, argName) {
if (typeof value !== "string") {
throw failure(`${argName} must be a string`);
}
}
const runAfterNewSymbol = Symbol("runAfterNew");
const runBeforeOnInitSymbol = Symbol("runBeforeOnInit");
function addLateInitializationFunction(target, symbol, fn) {
let array = target[symbol];
if (!(array && Object.prototype.hasOwnProperty.call(target, symbol))) {
array = array ? array.slice() : [];
addHiddenProp(target, symbol, array);
}
array.push(fn);
}
function runLateInitializationFunctions(target, symbol) {
const fns = target[symbol];
if (fns) {
for (const fn of fns) {
fn(target);
}
}
}
const warningsAlreadyDisplayed = /* @__PURE__ */ new Set();
function logWarning(type, msg, uniqueKey) {
if (uniqueKey) {
if (warningsAlreadyDisplayed.has(uniqueKey)) {
return;
}
warningsAlreadyDisplayed.add(uniqueKey);
}
msg = "[mobx-keystone] " + msg;
switch (type) {
case "warn":
console.warn(msg);
break;
case "error":
console.error(msg);
break;
default:
throw failure(`unknown log type - ${type}`);
}
}
function lazy(getter) {
let memoizedValue;
let memoized = false;
return (...args) => {
if (!memoized) {
memoizedValue = getter(...args);
memoized = true;
}
return memoizedValue;
};
}
const identityFn = (x) => x;
const mobx6 = {
makeObservable: mobx[
// just to ensure import * is kept properly
String.fromCharCode("l".charCodeAt(0) + 1) + "akeObservable"
]
};
function propNameToSetterName(propName) {
return `set${propName[0].toUpperCase()}${propName.slice(1)}`;
}
function getMobxVersion() {
if (mobx6.makeObservable) {
return 6;
} else {
return 5;
}
}
const namespace$2 = "mobx-keystone";
const propsTypeSymbol = Symbol("propsType");
const fromSnapshotOverrideTypeSymbol = Symbol("fromSnapshotOverrideType");
const toSnapshotOverrideTypeSymbol = Symbol("toSnapshotOverrideType");
const modelInitializedSymbol = Symbol("modelInitialized");
function modelClass(type) {
return type;
}
const modelInfoByName = {};
const modelInfoByClass = /* @__PURE__ */ new WeakMap();
function getModelInfoForName(name) {
return modelInfoByName[name];
}
function getOrCreate(map, key, create) {
let value = map.get(key);
if (value === void 0) {
value = create();
map.set(key, value);
}
return value;
}
const objectParents = /* @__PURE__ */ new WeakMap();
const objectParentsAtoms = /* @__PURE__ */ new WeakMap();
function parentPathEquals(parentPath1, parentPath2) {
if (!(parentPath1 || parentPath2)) {
return true;
}
if (!(parentPath1 && parentPath2)) {
return false;
}
return parentPath1.parent === parentPath2.parent && parentPath1.path === parentPath2.path;
}
function createParentPathAtom() {
return createAtom("parentAtom");
}
function reportParentPathObserved(node) {
getOrCreate(objectParentsAtoms, node, createParentPathAtom).reportObserved();
}
function reportParentPathChanged(node) {
var _a2;
(_a2 = objectParentsAtoms.get(node)) == null ? void 0 : _a2.reportChanged();
}
const dataObjectParent = /* @__PURE__ */ new WeakMap();
function dataToModelNode(node) {
const modelNode = dataObjectParent.get(node);
return modelNode != null ? modelNode : node;
}
function modelToDataNode(node) {
return isModel(node) ? node.$ : node;
}
const tweakedObjects = /* @__PURE__ */ new WeakMap();
function isTweakedObject(value, canBeDataObject) {
if (!canBeDataObject && dataObjectParent.has(value)) {
return false;
}
return tweakedObjects.has(value);
}
function isTreeNode(value) {
return !isPrimitive(value) && isTweakedObject(value, false);
}
function assertTweakedObject(treeNode, argName, canBeDataObject = false) {
if (!canBeDataObject && dataObjectParent.has(treeNode)) {
throw failure(`${argName} must be the model object instance instead of the '$' sub-object`);
}
if (isPrimitive(treeNode) || !isTweakedObject(treeNode, true)) {
throw failure(
`${argName} must be a tree node (usually a model or a shallow / deep child part of a model 'data' object)`
);
}
}
function assertIsTreeNode(value, argName = "argument") {
assertTweakedObject(value, argName, false);
}
let runningWithoutSnapshotOrPatches = false;
function runWithoutSnapshotOrPatches(fn) {
const old = runningWithoutSnapshotOrPatches;
runningWithoutSnapshotOrPatches = true;
try {
runInAction(() => {
fn();
});
} finally {
runningWithoutSnapshotOrPatches = old;
}
}
const modelMetadataSymbol = Symbol("modelMetadata");
const modelUnwrappedClassSymbol = Symbol("modelUnwrappedClass");
const runAfterModelDecoratorSymbol = Symbol("runAfterModelDecorator");
const modelPropertiesSymbol = Symbol("modelProperties");
function getInternalModelClassPropsInfo(modelClass2) {
return modelClass2[modelPropertiesSymbol];
}
function setInternalModelClassPropsInfo(modelClass2, props) {
modelClass2[modelPropertiesSymbol] = props;
}
const noDefaultValue = Symbol("noDefaultValue");
const idProp = {
_setter: false,
_isId: true,
withSetter(mode) {
const obj = Object.create(this);
obj._setter = mode != null ? mode : true;
return obj;
},
typedAs() {
return idProp;
}
};
const baseProp = {
...{},
_defaultFn: noDefaultValue,
_defaultValue: noDefaultValue,
_typeChecker: void 0,
_setter: false,
_isId: false,
_transform: void 0,
_fromSnapshotProcessor: void 0,
_toSnapshotProcessor: void 0,
withSetter(mode) {
const obj = Object.create(this);
obj._setter = mode != null ? mode : true;
return obj;
},
withTransform(transform) {
const obj = Object.create(this);
obj._transform = toFullTransform(transform);
return obj;
},
withSnapshotProcessor({ fromSnapshot: fromSnapshot2, toSnapshot }) {
let newFromSnapshot;
if (this._fromSnapshotProcessor && fromSnapshot2) {
const oldFn = this._fromSnapshotProcessor;
const newFn = fromSnapshot2;
newFromSnapshot = (sn) => oldFn(newFn(sn));
} else if (fromSnapshot2) {
newFromSnapshot = fromSnapshot2;
} else {
newFromSnapshot = this._fromSnapshotProcessor;
}
let newToSnapshot;
if (this._toSnapshotProcessor && toSnapshot) {
const oldFn = this._toSnapshotProcessor;
const newFn = toSnapshot;
newToSnapshot = (sn) => newFn(oldFn(sn));
} else if (toSnapshot) {
newToSnapshot = toSnapshot;
} else {
newToSnapshot = this._toSnapshotProcessor;
}
const obj = Object.create(this);
obj._fromSnapshotProcessor = newFromSnapshot;
obj._toSnapshotProcessor = newToSnapshot;
return obj;
}
};
function prop(def) {
const hasDefaultValue = arguments.length > 0;
if (!hasDefaultValue) {
return baseProp;
}
let p = propCache.get(def);
if (!p) {
p = Object.create(baseProp);
if (typeof def === "function") {
p._defaultFn = def;
} else {
p._defaultValue = def;
}
propCache.set(def, p);
}
return p;
}
const propCache = /* @__PURE__ */ new Map();
let cacheTransformResult = false;
const cacheTransformedValueFn = () => {
cacheTransformResult = true;
};
function toFullTransform(transformObject) {
const cache = /* @__PURE__ */ new WeakMap();
const transform = (params) => params.originalValue == null ? params.originalValue : transformObject.transform(params);
const untransform = (params) => params.transformedValue == null ? params.transformedValue : transformObject.untransform(params);
return {
transform(originalValue, model2, propName, setOriginalValue) {
const modelCache = getOrCreate(cache, model2, () => /* @__PURE__ */ new Map());
let propCache2 = modelCache.get(propName);
if ((propCache2 == null ? void 0 : propCache2.originalValue) !== originalValue) {
modelCache.delete(propName);
propCache2 = void 0;
}
const transformedValue = transform({
originalValue,
cachedTransformedValue: propCache2 == null ? void 0 : propCache2.transformedValue,
setOriginalValue
});
modelCache.set(propName, {
originalValue,
transformedValue
});
return transformedValue;
},
untransform(transformedValue, model2, propName) {
const modelCache = getOrCreate(cache, model2, () => /* @__PURE__ */ new Map());
cacheTransformResult = false;
const originalValue = untransform({
transformedValue,
cacheTransformedValue: cacheTransformedValueFn
});
if (cacheTransformResult) {
modelCache.set(propName, { originalValue, transformedValue });
} else {
modelCache.delete(propName);
}
return originalValue;
}
};
}
function getModelPropDefaultValue(propData) {
if (propData._defaultFn !== noDefaultValue) {
return propData._defaultFn();
}
if (propData._defaultValue !== noDefaultValue) {
return propData._defaultValue;
}
return noDefaultValue;
}
let urlAlphabet = "useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict";
let nanoid = (size = 21) => {
let id = "";
let i = size | 0;
while (i--) {
id += urlAlphabet[Math.random() * 64 | 0];
}
return id;
};
var ModelAutoTypeCheckingMode = /* @__PURE__ */ ((ModelAutoTypeCheckingMode2) => {
ModelAutoTypeCheckingMode2["DevModeOnly"] = "devModeOnly";
ModelAutoTypeCheckingMode2["AlwaysOn"] = "alwaysOn";
ModelAutoTypeCheckingMode2["AlwaysOff"] = "alwaysOff";
return ModelAutoTypeCheckingMode2;
})(ModelAutoTypeCheckingMode || {});
let localId = 0;
const localBaseId = nanoid();
function defaultModelIdGenerator() {
const id = localId.toString(36) + "-" + localBaseId;
localId++;
return id;
}
let globalConfig = {
modelAutoTypeChecking: "devModeOnly",
modelIdGenerator: defaultModelIdGenerator,
allowUndefinedArrayElements: false,
showDuplicateModelNameWarnings: true
};
function setGlobalConfig(config) {
globalConfig = Object.freeze({
...globalConfig,
...config
});
}
function getGlobalConfig() {
return globalConfig;
}
function isModelAutoTypeCheckingEnabled() {
switch (getGlobalConfig().modelAutoTypeChecking) {
case "devModeOnly":
return inDevMode;
case "alwaysOff":
return false;
case "alwaysOn":
return true;
default:
throw failure(
`invalid 'modelAutoTypeChecking' config value - ${globalConfig.modelAutoTypeChecking}`
);
}
}
const objectChildren = /* @__PURE__ */ new WeakMap();
function getObjectChildrenObject(node) {
let obj = objectChildren.get(node);
if (!obj) {
obj = {
shallow: /* @__PURE__ */ new Set(),
shallowAtom: void 0,
// will be created when first observed
deep: /* @__PURE__ */ new Set(),
deepDirty: true,
deepAtom: void 0,
// will be created when first observed
extensionsData: initExtensionsData()
};
objectChildren.set(node, obj);
}
return obj;
}
function getObjectChildren(node) {
const obj = getObjectChildrenObject(node);
if (!obj.shallowAtom) {
obj.shallowAtom = createAtom("shallowChildrenAtom");
}
obj.shallowAtom.reportObserved();
return obj.shallow;
}
function getDeepObjectChildren(node) {
const obj = getObjectChildrenObject(node);
if (obj.deepDirty) {
updateDeepObjectChildren(node);
}
if (!obj.deepAtom) {
obj.deepAtom = createAtom("deepChildrenAtom");
}
obj.deepAtom.reportObserved();
return obj;
}
function addNodeToDeepLists(node, data) {
data.deep.add(node);
extensions.forEach((extension, dataSymbol) => {
extension.addNode(node, data.extensionsData.get(dataSymbol));
});
}
const updateDeepObjectChildren = action((node) => {
var _a2;
const obj = getObjectChildrenObject(node);
if (!obj.deepDirty) {
return obj;
}
obj.deep = /* @__PURE__ */ new Set();
obj.extensionsData = initExtensionsData();
const childrenIterator = obj.shallow.values();
let childrenIteratorResult = childrenIterator.next();
while (!childrenIteratorResult.done) {
addNodeToDeepLists(childrenIteratorResult.value, obj);
const childDeepChildren = updateDeepObjectChildren(childrenIteratorResult.value).deep;
const childDeepChildrenIterator = childDeepChildren.values();
let childDeepChildrenIteratorResult = childDeepChildrenIterator.next();
while (!childDeepChildrenIteratorResult.done) {
addNodeToDeepLists(childDeepChildrenIteratorResult.value, obj);
childDeepChildrenIteratorResult = childDeepChildrenIterator.next();
}
childrenIteratorResult = childrenIterator.next();
}
obj.deepDirty = false;
(_a2 = obj.deepAtom) == null ? void 0 : _a2.reportChanged();
return obj;
});
const addObjectChild = action((node, child) => {
var _a2;
const obj = getObjectChildrenObject(node);
obj.shallow.add(child);
(_a2 = obj.shallowAtom) == null ? void 0 : _a2.reportChanged();
invalidateDeepChildren(node, obj);
});
const removeObjectChild = action((node, child) => {
var _a2;
const obj = getObjectChildrenObject(node);
obj.shallow.delete(child);
(_a2 = obj.shallowAtom) == null ? void 0 : _a2.reportChanged();
invalidateDeepChildren(node, obj);
});
function invalidateDeepChildren(node, obj) {
var _a2;
let currentNode = node;
let currentObj = obj;
while (currentNode) {
currentObj.deepDirty = true;
(_a2 = currentObj.deepAtom) == null ? void 0 : _a2.reportChanged();
currentNode = fastGetParent(currentNode, false);
if (currentNode) {
currentObj = getObjectChildrenObject(currentNode);
}
}
}
const extensions = /* @__PURE__ */ new Map();
function registerDeepObjectChildrenExtension(extension) {
const dataSymbol = {};
extensions.set(dataSymbol, extension);
return (data) => {
return data.extensionsData.get(dataSymbol);
};
}
function initExtensionsData() {
const extensionsData = /* @__PURE__ */ new WeakMap();
extensions.forEach((extension, dataSymbol) => {
extensionsData.set(dataSymbol, extension.initData());
});
return extensionsData;
}
function canWrite() {
return !getActionProtection() || !!getCurrentActionContext();
}
function assertCanWrite() {
if (!canWrite()) {
throw failure("data changes must be performed inside model actions");
}
}
let actionProtection = true;
function getActionProtection() {
return actionProtection;
}
function setActionProtection(protection) {
actionProtection = protection;
}
const pendingActions = [];
function isActionRunning() {
return !getActionProtection() || !!getCurrentActionContext();
}
function enqueuePendingAction(action2) {
if (isActionRunning()) {
pendingActions.push(action2);
} else {
action2();
}
}
let pendingActionsRunning = false;
function tryRunPendingActions() {
if (isActionRunning() || pendingActionsRunning) {
return;
}
pendingActionsRunning = true;
try {
while (pendingActions.length > 0) {
const nextAction = pendingActions.shift();
nextAction();
}
} finally {
pendingActionsRunning = false;
}
}
function getModelMetadata(modelClassOrInstance) {
if (isModel(modelClassOrInstance)) {
return modelClassOrInstance.constructor[modelMetadataSymbol];
} else if (isModelClass(modelClassOrInstance)) {
return modelClassOrInstance[modelMetadataSymbol];
} else {
throw failure(`modelClassOrInstance must be a model class or instance`);
}
}
const modelIdPropertyNameCache = /* @__PURE__ */ new WeakMap();
function getModelIdPropertyName(modelClass2) {
return getOrCreate(
modelIdPropertyNameCache,
modelClass2,
() => getModelMetadata(modelClass2).modelIdProperty
);
}
var HookAction = /* @__PURE__ */ ((HookAction2) => {
HookAction2["OnInit"] = "$$onInit";
HookAction2["OnLazyInit"] = "$$onLazyInit";
HookAction2["OnAttachedToRootStore"] = "$$onAttachedToRootStore";
HookAction2["OnAttachedToRootStoreDisposer"] = "$$onAttachedToRootStoreDisposer";
return HookAction2;
})(HookAction || {});
const hookActionValues = new Set(Object.values(HookAction));
function isHookAction(actionName) {
return hookActionValues.has(actionName);
}
var WalkTreeMode = /* @__PURE__ */ ((WalkTreeMode2) => {
WalkTreeMode2["ParentFirst"] = "parentFirst";
WalkTreeMode2["ChildrenFirst"] = "childrenFirst";
return WalkTreeMode2;
})(WalkTreeMode || {});
function walkTree(root, visit, mode) {
assertTweakedObject(root, "root");
if (mode === "parentFirst") {
return walkTreeParentFirst(root, visit);
} else {
return walkTreeChildrenFirst(root, visit);
}
}
function walkTreeParentFirst(root, visit) {
const stack = [root];
while (stack.length > 0) {
const node = stack.pop();
const ret = visit(node);
if (ret !== void 0) {
return ret;
}
const children = getObjectChildren(node);
stack.length += children.size;
let i = stack.length - 1;
const childrenIter = children.values();
let ch = childrenIter.next();
while (!ch.done) {
stack[i--] = ch.value;
ch = childrenIter.next();
}
}
return void 0;
}
function walkTreeChildrenFirst(root, visit) {
const childrenIter = getObjectChildren(root).values();
let ch = childrenIter.next();
while (!ch.done) {
const ret2 = walkTreeChildrenFirst(ch.value, visit);
if (ret2 !== void 0) {
return ret2;
}
ch = childrenIter.next();
}
const ret = visit(root);
if (ret !== void 0) {
return ret;
}
return void 0;
}
function getComputedTreeResult(computedFns, visit, tree) {
let cmpted = computedFns.get(tree);
if (!cmpted) {
cmpted = computed(() => {
return walkTreeAggregate(tree, visit, (ch) => getComputedTreeResult(computedFns, visit, ch));
});
computedFns.set(tree, cmpted);
}
return cmpted.get();
}
function computedWalkTreeAggregate(visit) {
const computedFns = /* @__PURE__ */ new WeakMap();
return {
walk: (n) => getComputedTreeResult(computedFns, visit, n)
};
}
function walkTreeAggregate(target, visit, recurse) {
let map;
const rootVal = visit(target);
const childrenMap = getObjectChildren(target);
const childrenIter = childrenMap.values();
let ch = childrenIter.next();
if (rootVal === void 0 && childrenMap.size === 1) {
return recurse(ch.value);
}
while (!ch.done) {
const childMap = recurse(ch.value);
if (childMap) {
if (!map) {
map = /* @__PURE__ */ new Map();
}
const mapIter = childMap.keys();
let mapCur = mapIter.next();
while (!mapCur.done) {
const key = mapCur.value;
const val = childMap.get(key);
map.set(key, val);
mapCur = mapIter.next();
}
}
ch = childrenIter.next();
}
if (rootVal !== void 0) {
if (!map) {
map = /* @__PURE__ */ new Map();
}
map.set(rootVal, target);
}
return map;
}
const onAttachedDisposers = /* @__PURE__ */ new WeakMap();
const attachedToRootStore = /* @__PURE__ */ new WeakSet();
const attachToRootStore = action(
"attachToRootStore",
(rootStore, child) => {
const childrenToCall = [];
walkTree(
child,
(ch) => {
if (attachedToRootStore.has(ch)) {
return;
}
attachedToRootStore.add(ch);
if (ch instanceof BaseModel && ch.onAttachedToRootStore) {
wrapModelMethodInActionIfNeeded(
ch,
"onAttachedToRootStore",
HookAction.OnAttachedToRootStore
);
childrenToCall.push(ch);
}
},
WalkTreeMode.ParentFirst
);
const childrenToCallLen = childrenToCall.length;
for (let i = 0; i < childrenToCallLen; i++) {
const ch = childrenToCall[i];
const disposer = ch.onAttachedToRootStore(rootStore);
if (disposer) {
onAttachedDisposers.set(ch, disposer);
}
}
}
);
const detachFromRootStore = action("detachFromRootStore", (child) => {
const disposersToCall = [];
walkTree(
child,
(ch) => {
if (!attachedToRootStore.delete(ch)) {
return;
}
const disposer = onAttachedDisposers.get(ch);
if (disposer) {
const disposerAction = wrapInAction({
nameOrNameFn: HookAction.OnAttachedToRootStoreDisposer,
fn: disposer,
actionType: ActionContextActionType.Sync
}).bind(ch);
onAttachedDisposers.delete(ch);
disposersToCall.push(disposerAction);
}
},
WalkTreeMode.ChildrenFirst
);
const disposersToCallLen = disposersToCall.length;
for (let i = 0; i < disposersToCallLen; i++) {
disposersToCall[i]();
}
});
const rootStoreRegistry = /* @__PURE__ */ new WeakMap();
function createRootStoreEntry() {
return {
atom: void 0,
// will be created when first observed
is: false
};
}
const getOrCreateRootStoreEntry = (node) => getOrCreate(rootStoreRegistry, node, createRootStoreEntry);
const registerRootStore = action(
"registerRootStore",
(node) => {
var _a2;
assertTweakedObject(node, "node");
const entry = getOrCreateRootStoreEntry(node);
if (entry.is) {
throw failure("object already registered as root store");
}
if (!isRoot(node)) {
throw failure("a root store must not have a parent");
}
entry.is = true;
attachToRootStore(node, node);
(_a2 = entry.atom) == null ? void 0 : _a2.reportChanged();
return node;
}
);
const unregisterRootStore = action("unregisterRootStore", (node) => {
var _a2;
if (!isRootStore(node)) {
throw failure("not a root store");
}
const entry = getOrCreateRootStoreEntry(node);
entry.is = false;
detachFromRootStore(node);
(_a2 = entry.atom) == null ? void 0 : _a2.reportChanged();
});
function isRootStore(node) {
assertTweakedObject(node, "node");
const entry = getOrCreateRootStoreEntry(node);
if (!entry.atom) {
entry.atom = createAtom("rootStore");
}
entry.atom.reportObserved();
return entry.is;
}
function fastIsRootStoreNoAtom(node) {
var _a2;
return !!((_a2 = rootStoreRegistry.get(node)) == null ? void 0 : _a2.is);
}
function getRootStore(node) {
assertTweakedObject(node, "node");
const root = fastGetRoot(node, true);
return isRootStore(root) ? root : void 0;
}
class TypeCheckError {
/**
* Creates an instance of TypeError.
* @param path Sub-path (where the root is the value being type checked) where the error occured.
* @param expectedTypeName Name of the expected type.
* @param actualValue Actual value.
* @param typeCheckedValue The value where the type check was invoked.
*/
constructor(path, expectedTypeName, actualValue, typeCheckedValue) {
/**
* The type check error message.
*/
__publicField(this, "message");
this.path = path;
this.expectedTypeName = expectedTypeName;
this.actualValue = actualValue;
this.typeCheckedValue = typeCheckedValue;
let rootPath = [];
if (this.typeCheckedValue && isTweakedObject(this.typeCheckedValue, true)) {
rootPath = fastGetRootPath(this.typeCheckedValue, false).path;
}
const actualValueSnapshot = isTweakedObject(this.actualValue, true) ? getSnapshot(this.actualValue) : this.actualValue;
this.message = `TypeCheckError: [/${[...rootPath, ...this.path].join(
"/"
)}] Expected a value of type <${this.expectedTypeName}> but got the value <${JSON.stringify(
actualValueSnapshot
)}> instead`;
}
/**
* Throws the type check error as an actual error.
*/
throw() {
throw failure(this.message);
}
}
const emptyPath = [];
const typeCheckersWithCachedResultsOfObject = /* @__PURE__ */ new WeakMap();
var TypeCheckerBaseType = /* @__PURE__ */ ((TypeCheckerBaseType2) => {
TypeCheckerBaseType2["Object"] = "object";
TypeCheckerBaseType2["Array"] = "array";
TypeCheckerBaseType2["Primitive"] = "primitive";
TypeCheckerBaseType2["Any"] = "any";
return TypeCheckerBaseType2;
})(TypeCheckerBaseType || {});
function getTypeCheckerBaseTypeFromValue(value) {
if (isArray(value)) {
return "array";
}
if (isObject(value)) {
return "object";
}
if (isPrimitive(value)) {
return "primitive";
}
return "any";
}
function invalidateCachedTypeCheckerResult(obj) {
let current = obj;
while (current) {
const set2 = typeCheckersWithCachedResultsOfObject.get(current);
if (set2) {
typeCheckersWithCachedResultsOfObject.delete(current);
set2.forEach((typeChecker) => {
typeChecker.invalidateCachedResult(current);
});
}
current = fastGetParentIncludingDataObjects(current, false);
}
}
const typeCheckersWithCachedSnapshotProcessorResultsOfObject = /* @__PURE__ */ new WeakMap();
function invalidateCachedToSnapshotProcessorResult(obj) {
const set2 = typeCheckersWithCachedSnapshotProcessorResultsOfObject.get(obj);
if (set2) {
set2.forEach((typeChecker) => {
typeChecker.invalidateSnapshotProcessorCachedResult(obj);
});
typeCheckersWithCachedSnapshotProcessorResultsOfObject.delete(obj);
}
}
class TypeChecker {
constructor(baseType, _check, getTypeName, typeInfoGen, snapshotType, _fromSnapshotProcessor, _toSnapshotProcessor) {
__publicField(this, "checkResultCache");
__publicField(this, "unchecked");
__publicField(this, "_cachedTypeInfoGen");
__publicField(this, "fromSnapshotProcessor", (sn) => {
return this._fromSnapshotProcessor(sn);
});
__publicField(this, "_toSnapshotProcessorCache", /* @__PURE__ */ new WeakMap());
__publicField(this, "toSnapshotProcessor", (sn) => {
if (typeof sn !== "object" || sn === null) {
return this._toSnapshotProcessor(sn);
}
if (this._toSnapshotProcessorCache.has(sn)) {
return this._toSnapshotProcessorCache.get(sn);
}
const val = this._toSnapshotProcessor(sn);
this._toSnapshotProcessorCache.set(sn, val);
const typeCheckerSet = getOrCreate(
typeCheckersWithCachedSnapshotProcessorResultsOfObject,
sn,
() => /* @__PURE__ */ new Set()
);
typeCheckerSet.add(this);
return val;
});
this.baseType = baseType;
this._check = _check;
this.getTypeName = getTypeName;
this.typeInfoGen = typeInfoGen;
this.snapshotType = snapshotType;
this._fromSnapshotProcessor = _fromSnapshotProcessor;
this._toSnapshotProcessor = _toSnapshotProcessor;
this.unchecked = !_check;
this._cachedTypeInfoGen = lazy(typeInfoGen);
}
createCacheIfNeeded() {
if (!this.checkResultCache) {
this.checkResultCache = /* @__PURE__ */ new WeakMap();
}
return this.checkResultCache;
}
setCachedResult(obj, newCacheValue) {
this.createCacheIfNeeded().set(obj, newCacheValue);
const typeCheckerSet = getOrCreate(typeCheckersWithCachedResultsOfObject, obj, () => /* @__PURE__ */ new Set());
typeCheckerSet.add(this);
}
invalidateCachedResult(obj) {
var _a2;
(_a2 = this.checkResultCache) == null ? void 0 : _a2.delete(obj);
}
getCachedResult(obj) {
var _a2;
return (_a2 = this.checkResultCache) == null ? void 0 : _a2.get(obj);
}
check(value, path, typeCheckedValue) {
if (this.unchecked) {
return null;
}
if (!isTweakedObject(value, true)) {
return this._check(value, path, typeCheckedValue);
}
let cachedResult = this.getCachedResult(value);
if (cachedResult === void 0) {
cachedResult = this._check(value, emptyPath, void 0);
this.setCachedResult(value, cachedResult);
}
if (cachedResult) {
return new TypeCheckError(
[...path, ...cachedResult.path],
cachedResult.expectedTypeName,
cachedResult.actualValue,
typeCheckedValue
);
} else {
return null;
}
}
get typeInfo() {
return this._cachedTypeInfoGen(this);
}
invalidateSnapshotProcessorCachedResult(obj) {
this._toSnapshotProcessorCache.delete(obj);
}
}
const lateTypeCheckerSymbol = Symbol("lateTypeCheker");
function lateTypeChecker(fn, typeInfoGen) {
let cached;
const ltc = () => {
if (cached) {
return cached;
}
cached = fn();
return cached;
};
ltc[lateTypeCheckerSymbol] = true;
const cachedTypeInfoGen = lazy(typeInfoGen);
Object.defineProperty(ltc, "typeInfo", {
enumerable: true,
configurable: false,
get() {
return cachedTypeInfoGen(ltc);
}
});
return ltc;
}
function isLateTypeChecker(ltc) {
return typeof ltc === "function" && lateTypeCheckerSymbol in ltc;
}
class TypeInfo {
constructor(thisType) {
this.thisType = thisType;
}
}
const snapshots = /* @__PURE__ */ new WeakMap();
const frozenState = /* @__PURE__ */ new WeakMap();
function getInternalSnapshot(value) {
return snapshots.get(value);
}
function getInternalSnapshotParent(sn, parentPath) {
if (!(parentPath && sn)) {
return void 0;
}
const parentSn = getInternalSnapshot(parentPath.parent);
if (!parentSn) {
return void 0;
}
return {
parentSnapshot: parentSn,
parentPath
};
}
const unsetInternalSnapshot = action("unsetInternalSnapshot", (value) => {
var _a2;
const oldSn = getInternalSnapshot(value);
if (oldSn) {
snapshots.delete(value);
(_a2 = oldSn.atom) == null ? void 0 : _a2.reportChanged();
}
});
const setNewInternalSnapshot = action(
"setNewInternalSnapshot",
(value, untransformed, transformFn, markAsFrozen = false) => {
var _a2;
const transformed = transformFn ? transformFn(untransformed) : untransformed;
const sn = {
untransformed,
transformFn,
transformed,
atom: void 0
// will be created when first observed
};
frozenState.set(untransformed, markAsFrozen);
if (transformed !== void 0 && transformed !== untransformed) {
frozenState.set(transformed, markAsFrozen);
}
snapshots.set(value, sn);
(_a2 = sn.atom) == null ? void 0 : _a2.reportChanged();
}
);
const updateInternalSnapshot = action(
"updateInternalSnapshot",
(value, mutate) => {
var _a2;
const sn = getInternalSnapshot(value);
let untransformed = sn.untransformed;
const snFrozen = frozenState.get(untransformed);
if (snFrozen) {
if (Array.isArray(untransformed)) {
untransformed = untransformed.slice();
} else {
untransformed = Object.assign({}, untransformed);
}
} else {
invalidateCachedToSnapshotProcessorResult(untransformed);
}
mutate(untransformed);
sn.untransformed = untransformed;
sn.transformed = sn.transformFn ? sn.transformFn(untransformed) : untransformed;
frozenState.set(sn.untransformed, false);
if (sn.transformed !== void 0) {
frozenState.set(sn.transformed, false);
}
(_a2 = sn.atom) == null ? void 0 : _a2.reportChanged();
const parent = getInternalSnapshotParent(sn, fastGetParentPath(value, false));
if (parent) {
const { parentSnapshot, parentPath } = parent;
if (parentSnapshot) {
const path = parentPath.path;
updateInternalSnapshot(parentPath.parent, (objOrArray) => {
objOrArray[path] = sn.transformed;
});
}
}
}
);
function reportInternalSnapshotObserved(sn) {
if (!sn.atom) {
sn.atom = createAtom("snapshot");
}
sn.atom.reportObserved();
}
function freezeInternalSnapshot(data) {
if (isPrimitive(data)) {
return data;
}
const isFrozen = frozenState.get(data);
if (isFrozen === void 0 || isFrozen) {
return data;
}
if (Array.isArray(data)) {
for (let i = 0; i < data.length; i++) {
freezeInternalSnapshot(data[i]);
}
} else {
const keys2 = Object.keys(data);
for (let i = 0; i < keys2.length; i++) {
freezeInternalSnapshot(data[keys2[i]]);
}
}
frozenState.set(data, true);
return data;
}
const emptyPatchArray = [];
class InternalPatchRecorder {
constructor() {
__publicField(this, "patches", emptyPatchArray);
__publicField(this, "invPatches", emptyPatchArray);
}
reset() {
this.patches = emptyPatchArray;
this.invPatches = emptyPatchArray;
}
record(patches, invPatches) {
this.patches = patches;
this.invPatches = invPatches;
}
emit(obj) {
emitPatches(obj, this.patches, this.invPatches);
this.reset();
}
}
function emitPatches(obj, patches, invPatches) {
if (patches.length > 0 || invPatches.length > 0) {
emitGlobalPatch(obj, patches, invPatches);
emitPatch(obj, patches, invPatches);
}
}
const patchListeners = /* @__PURE__ */ new WeakMap();
const globalPatchListeners = [];
function onPatches(subtreeRoot, listener) {
assertTweakedObject(subtreeRoot, "subtreeRoot");
assertIsFunction(listener, "listener");
if (!isAction(listener)) {
listener = action(listener.name || "onPatchesListener", listener);
}
let listenersForObject = patchListeners.get(subtreeRoot);
if (!listenersForObject) {
listenersForObject = [];
patchListeners.set(subtreeRoot, listenersForObject);
}
listenersForObject.push(listener);
return () => {
deleteFromArray(listenersForObject, listener);
};
}
function onGlobalPatches(listener) {
assertIsFunction(listener, "listener");
if (!isAction(listener)) {
listener = action(listener.name || "onGlobalPatchesListener", listener);
}
globalPatchListeners.push(listener);
return () => {
deleteFromArray(globalPatchListeners, listener);
};
}
function emitGlobalPatch(obj, patches, inversePatches) {
for (let i = 0; i < globalPatchListeners.length; i++) {
const listener = globalPatchListeners[i];
listener(obj, patches, inversePatches);
}
}
function emitPatchForTarget(obj, patches, inversePatches, pathPrefix) {
const listenersForObject = patchListeners.get(obj);
if (!listenersForObject || listenersForObject.length === 0) {
return;
}
const fixPath = (patchesArray) => pathPrefix.length > 0 ? patchesArray.map((p) => addPathToPatch(p, pathPrefix)) : patchesArray;
const patchesWithPathPrefix = fixPath(patches);
const invPatchesWithPathPrefix = fixPath(inversePatches);
for (let i = 0; i < listenersForObject.length; i++) {
const listener = listenersForObject[i];
listener(patchesWithPathPrefix, invPatchesWithPathPrefix);
}
}
function emitPatch(obj, patches, inversePatches) {
const pathPrefix = [];
emitPatchForTarget(obj, patches, inversePatches, pathPrefix);
let parentPath = fastGetParentPath(obj, false);
while (parentPath) {
pathPrefix.unshift(parentPath.path);
emitPatchForTarget(parentPath.parent, patches, inversePatches, pathPrefix);
parentPath = fastGetParentPath(parentPath.parent, false);
}
}
function addPathToPatch(patch, pathPrefix) {
return {
...patch,
path: [...pathPrefix, ...patch.path]
};
}
const getValueSnapshotForPatch = (v) => {
if (isPrimitive(v)) {
return v;
}
const internalSnapshot = getInternalSnapshot(v);
if (!internalSnapshot) {
return v;
}
return freezeInternalSnapshot(internalSnapshot.transformed);
};
function createPatchForObjectValueChange(path, oldValue, newValue) {
return newValue === void 0 ? { op: "remove", path } : oldValue === void 0 ? {
op: "add",
path,
value: getValueSnapshotForPatch(newValue)
} : {
op: "replace",
path,
value: getValueSnapshotForPatch(newValue)
};
}
function setIfDifferent(target, key, value) {
if (target[key] !== value || !(key in target)) {
set(target, key, value);
}
}
function setIfDifferentWithReturn(target, key, value) {
if (target[key] !== value || !(key in target)) {
set(target, key, value);
return true;
}
return false;
}
var TweakerPriority = /* @__PURE__ */ ((TweakerPriority2) => {
TweakerPriority2[TweakerPriority2["Model"] = 0] = "Model";
TweakerPriority2[TweakerPriority2["Array"] = 1] = "Array";
TweakerPriority2[TweakerPriority2["PlainObject"] = 2] = "PlainObject";
TweakerPriority2[TweakerPriority2["Frozen"] = 3] = "Frozen";
return TweakerPriority2;
})(TweakerPriority || {});
function findParent(child, predicate, maxDepth = 0) {
const foundParentPath = findParentPath(child, predicate, maxDepth);
return foundParentPath ? foundParentPath.parent : void 0;
}
function findParentPath(child, predicate, maxDepth = 0) {
assertTweakedObject(child, "child");
const path = [];
let current = child;
let depth = 0;
let parentPath;
while (parentPath = fastGetParentPath(current, true)) {
path.unshift(parentPath.path);
current = parentPath.parent;
if (predicate(current)) {
return {
parent: current,
path
};
}
depth++;
if (maxDepth > 0 && depth === maxDepth) {
break;
}
}
return void 0;
}
function getChildrenObjects(node, options) {
assertTweakedObject(node, "node");
if (options == null ? void 0 : options.deep) {
return getDeepObjectChildren(node).deep;
} else {
return getObjectChildren(node);
}
}
function findChildren(root, predicate, options) {
const children = getChildrenObjects(root, options);
const set2 = /* @__PURE__ */ new Set();
const iter = children.values();
let cur = iter.next();
while (!cur.done) {
if (predicate(cur.value)) {
set2.add(cur.value);
}
cur = iter.next();
}
return set2;
}
function onChildAttachedTo(target, fn, options) {
assertIsFunction(target, "target");
assertIsFunction(fn, "fn");
const opts = {
deep: false,
fireForCurrentChildren: true,
...options
};
const detachDisposers = /* @__PURE__ */ new WeakMap();
const runDetachDisposer = (n) => {
const detachDisposer = detachDisposers.get(n);
if (detachDisposer) {
detachDisposers.delete(n);
detachDisposer();
}
};
const addDetachDisposer = (n, disposer2) => {
if (disposer2) {
detachDisposers.set(n, action(disposer2));
}
};
const getChildrenObjectOpts = { deep: opts.deep };
const getCurrentChildren = () => {
const t = target();
assertTweakedObject(t, "target()");
const children = getChildrenObjects(t, getChildrenObjectOpts);
const set2 = /* @__PURE__ */ new Set();
const iter = children.values();
let cur = iter.next();
while (!cur.done) {
set2.add(cur.value);
cur = iter.next();
}
return set2;
};
const currentChildren = opts.fireForCurrentChildren ? /* @__PURE__ */ new Set() : getCurrentChildren();
const disposer = reaction(
() => getCurrentChildren(),
(newChildren) => {
const disposersToRun = [];
const currentChildrenIter = currentChildren.values();
let currentChildrenCur = currentChildrenIter.next();
while (!currentChildrenCur.done) {
const n = currentChildrenCur.value;
if (!newChildren.has(n)) {
currentChildren.delete(n);
disposersToRun.push(n);
}
currentChildrenCur = currentChildrenIter.next();
}
if (disposersToRun.length > 0) {
for (let i = disposersToRun.length - 1; i >= 0; i--) {
runDetachDisposer(disposersToRun[i]);
}
}
const newChildrenIter = newChildren.values();
let newChildrenCur = newChildrenIter.next();
while (!newChildrenCur.done) {
const n = newChildrenCur.value;
if (!currentChildren.has(n)) {
currentChildren.add(n);
const detachAction = runInAction(() => fn(n));
addDetachDisposer(n, detachAction);
}
newChildrenCur = newChildrenIter.next();
}
},
{
fireImmediately: true
}
);
return (runDetachDisposers) => {
disposer();
if (runDetachDisposers) {
const currentChildrenIter = currentChildren.values();
let currentChildrenCur = currentChildrenIter.next();
while (!currentChildrenCur.done) {
const n = currentChildrenCur.value;
runDetachDisposer(n);
currentChildrenCur = currentChildrenIter.next();
}
}
currentChildren.clear();
};
}
function isChildOfParent(child, parent) {
assertTweakedObject(child, "child");
assertTweakedObject(parent, "parent");
let currentParent = fastGetParent(child, true);
while (currentParent) {
if (currentParent === parent) {
return true;
}
currentParent = fastGetParent(currentParent, true);
}
return false;
}
function isParentOfChild(parent, child) {
return isChildOfParent(child, parent);
}
let typeCheckingAllowed = true;
function withoutTypeChecking(fn) {
const oldTypeCheckingAllowed = typeCheckingAllowed;
typeCheckingAllowed = false;
try {
fn();
} finally {
typeCheckingAllowed = oldTypeCheckingAllowed;
}
}
function isTypeCheckingAllowed() {
return typeCheckingAllowed;
}
var SnapshotterAndReconcilerPriority = /* @__PURE__ */ ((SnapshotterAndReconcilerPriority2) => {
SnapshotterAndReconcilerPriority2[SnapshotterAndReconcilerPriority2["Array"] = 0] = "Array";
SnapshotterAndReconcilerPriority2[SnapshotterAndReconcilerPriority2["Frozen"] = 1] = "Frozen";
SnapshotterAndReconcilerPriority2[SnapshotterAndReconcilerPriority2["Model"] = 2] = "Model";
SnapshotterAndReconcilerPriority2[SnapshotterAndReconcilerPriority2["PlainObject"] = 3] = "PlainObject";
return SnapshotterAndReconcilerPriority2;
})(SnapshotterAndReconcilerPriority || {});
function reconcileArraySnapshot(value, sn, modelPool) {
if (!isArray(value)) {
return fromSnapshot(sn);
}
const snapshotBeforeChanges = getSnapshot(value);
withoutTypeChecking(() => {
if (value.length > sn.length) {
value.splice(sn.length, value.length - sn.length);
}
for (let i = 0; i < value.length; i++) {
const oldValue = value[i];
const newValue = reconcileSnapshot(oldValue, sn[i], modelPool, value);
detachIfNeeded(newValue, oldValue, modelPool);
setIfDifferent(value, i, newValue);
}
for (let i = value.length; i < sn.length; i++) {
const newValue = reconcileSnapshot(void 0, sn[i], modelPool, value);
detachIfNeeded(newValue, void 0, modelPool);
value.push(newValue);
}
});
runTypeCheckingAfterChange(value, void 0, snapshotBeforeChanges);
return value;
}
function registerArraySnapshotReconciler() {
registerReconciler(SnapshotterAndReconcilerPriority.Array, (value, sn, modelPool) => {
if (isArray(sn)) {
return reconcileArraySnapshot(value, sn, modelPool);
}
return void 0;
});
}
var FrozenCheckMode = /* @__PURE__ */ ((FrozenCheckMode2) => {
FrozenCheckMode2["DevModeOnly"] = "devModeOnly";
FrozenCheckMode2["On"] = "on";
FrozenCheckMode2["Off"] = "off";
return FrozenCheckMode2;
})(FrozenCheckMode || {});
const frozenKey = "$frozen";
class Frozen {
/**
* Creates an instance of Frozen.
* Do not use directly, use `frozen` instead.
*
* @param dataToFreeze
* @param checkMode
*/
constructor(dataToFreeze, checkMode = "devModeOnly") {
/**
* Frozen data, deeply immutable.
*/
__publicField(this, "data");
if (isObservable(dataToFreeze)) {
dataToFreeze = toJS(dataToFreeze);
}
const check = checkMode === "on" || inDevMode && checkMode === "devModeOnly";
if (check) {
checkDataIsSerializableAndFreeze(dataToFreeze);
}
this.data = dataToFreeze;
if (check) {
Object.freeze(this.data);
}
tweak(this, void 0);
}
}
function frozen(data, checkMode = "devModeOnly") {
return new Frozen(data, checkMode);
}
function checkDataIsSerializableAndFreeze(data) {
if (isPrimitive(data)) {
return;
}
if (Array.isArray(data)) {
const arrLen = data.length;
for (let i = 0; i < arrLen; i++) {
const v = data[i];
if (v === void 0 && !getGlobalConfig().allowUndefinedArrayElements) {
throw failure(
"undefined is not supported inside arrays since it is not serializable in JSON, consider using null instead"
);
}
checkDataIsSerializableAndFreeze(v);
}
Object.freeze(data);
return;
}
if (isPlainObject(data)) {
const dataKeys = Object.keys(data);
const dataKeysLen = dataKeys.length;
for (let i = 0; i < dataKeysLen; i++) {
const k = dataKeys[i];
const v = data[k];
checkDataIsSerializableAndFreeze(k);
checkDataIsSerializableAndFreeze(v);
}