UNPKG

@cervello/react

Version:

🤯 Simple, reactive, tiny and performant state-management library

1 lines • 32.5 kB
{"version":3,"file":"cervello.cjs","sources":["../src/types/shared.ts","../src/lib/utils/object.ts","../src/lib/helpers/new-proxify-store.ts","../src/lib/store/new-index.ts","../src/lib/utils/subject.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/ban-types */\nexport type WithoutType<T, V, WithNever = {\n [K in keyof T]: Exclude<T[K], undefined> extends V\n ? never\n : (T[K] extends Record<string, unknown>\n ? WithoutType<T[K], V>\n : T[K])\n}> = Pick<WithNever, {\n [K in keyof WithNever]: WithNever[K] extends never ? never : K\n}[keyof WithNever]>\n\n\n\nexport type ObjectFromAttributes<T, Attributes extends Array< keyof WithoutType<T, Function> > > = {\n [k in Attributes[number]]: T[k]\n}\n\nexport type Maybe<T> = T | undefined\n\n\n\nexport type UseSelector<T> = <Attributes extends Array< Exclude<keyof WithoutType<T, Function>, '$value'> >>(\n selectors: Attributes,\n isEqualFunction?: (previousState: ObjectFromAttributes<T, Attributes>, currentState: ObjectFromAttributes<T, Attributes>) => boolean,\n) => T\n\nexport type FieldPath<T extends Record<string, any>> = {\n [K in keyof Required<T>]: T[K] extends Record<string, any>\n ? K extends string\n\n ? T[K] extends Function\n ? never\n : T[K] extends Array<any>\n ? K\n : `${K}.*` | `${K}.${FieldPath<T[K]>}`\n : never\n : K extends string\n ? K\n : never\n}[keyof T]\n\nexport const nonReactiveObjectSymbol = Symbol('nonReactiveObject')\nexport type StoreChange<T extends Record<string, any>> = {\n change: {\n fieldPath: FieldPath<T>\n newValue: any\n previousValue: any\n }\n storeValue: T\n}\n","/* eslint-disable no-cond-assign */\n\nimport { nonReactiveObjectSymbol } from '../../types/shared'\nimport { INTERNAL_VALUE_PROP } from '../helpers/constants'\n\n\n/**\n * Clones all the provided object and nested properties and it also\n * iterates nested arrays to deepClone them\n *\n * @param obj - base object to be cloned\n * @returns new cloned object with new reference\n */\nexport function deepClone <T> (obj: T): T {\n if (!obj || typeof obj !== 'object')\n return obj\n\n let newObj = {} as any\n\n if (Array.isArray(obj)) {\n newObj = obj.map(item => deepClone(item))\n } else if (!isReactObjectLikeNode(obj)) {\n Object.entries(obj).forEach(([key, value]) => {\n newObj[key] = deepClone(value)\n })\n Object.getOwnPropertySymbols(obj).forEach((symbol) => {\n newObj[symbol] = (obj as any)[symbol]\n })\n } else {\n newObj = obj\n }\n\n return newObj as T\n}\n\n// function copyBuffer (cur: ArrayBufferView) {\n// if (cur instanceof Buffer)\n// return Buffer.from(cur)\n//\n//\n// return new cur.constructor(cur.buffer.slice(), cur.byteOffset, cur.length)\n// }\n\n\n// INFO: From `rfdc` (really-fast-deep-clone) package for faster cloning taking care of circular references\nexport function deepClone2 <T> (obj: T): T {\n const refs: Array<any> = []\n const refsNew: Array<any> = []\n\n const constructorHandlers = new Map()\n\n constructorHandlers.set(Date, (o: string | number | Date) => new Date(o))\n constructorHandlers.set(Map, (o: Iterable<unknown> | ArrayLike<unknown>, fn: any) => new Map(cloneArray(Array.from(o), fn)))\n constructorHandlers.set(Set, (o: Iterable<unknown> | ArrayLike<unknown>, fn: any) => new Set(cloneArray(Array.from(o), fn)))\n\n let handler = null\n\n return clone(obj)\n\n function cloneArray (a: any, fn: any): any {\n const keys = Object.keys(a)\n const a2 = new Array(keys.length) as any\n\n for (let i = 0; i < keys.length; i++) {\n const k = keys[i]\n const cur = a[k]\n\n if (typeof cur !== 'object' || cur === null) {\n a2[k] = cur\n } else if (cur.constructor !== Object && (handler = constructorHandlers.get(cur.constructor))) {\n a2[k] = handler(cur, fn)\n // } else if (ArrayBuffer.isView(cur)) {\n // a2[k] = copyBuffer(cur)\n } else {\n const index = refs.indexOf(cur)\n\n if (index !== -1)\n a2[k] = refsNew[index]\n else\n a2[k] = fn(cur)\n }\n }\n\n return a2\n }\n\n function clone (o: any): any {\n if (typeof o !== 'object' || o === null) return o\n if (Array.isArray(o)) return cloneArray(o, clone)\n if (o.constructor !== Object && (handler = constructorHandlers.get(o.constructor)))\n return handler(o, clone)\n\n const o2 = {} as any\n\n refs.push(o)\n refsNew.push(o2)\n\n\n Object.getOwnPropertySymbols(o).forEach((symbol) => {\n o2[symbol] = (o)[symbol]\n })\n\n for (const k in o) {\n if (!Object.hasOwnProperty.call(o, k)) continue\n const cur = o[k]\n\n\n if (typeof cur !== 'object' || cur === null) {\n o2[k] = cur\n } else if (cur.constructor !== Object && (handler = constructorHandlers.get(cur.constructor))) {\n o2[k] = handler(cur, clone)\n // } else if (ArrayBuffer.isView(cur)) {\n // o2[k] = copyBuffer(cur)\n } else {\n const i = refs.indexOf(cur)\n\n if (i !== -1)\n o2[k] = refsNew[i]\n else\n o2[k] = clone(cur)\n }\n }\n refs.pop()\n refsNew.pop()\n\n\n return o2\n }\n}\n\n/**\n * Guard to check is variable is an object\n * @param obj - variable to be checked\n * @returns boolean\n */\nexport const isObject = (obj: unknown): obj is Record<string | symbol, unknown> => (\n obj !== null\n && typeof obj === 'object'\n && !Array.isArray(obj)\n)\n\n\nexport const isReactElement = (obj: unknown): boolean => {\n if (!isObject(obj)) return false\n\n return !!(obj.$$typeof)\n}\n\n\nexport function isReactObjectLikeNode (obj: unknown): boolean {\n if (!isObject(obj)) return false\n if (isReactElement(obj)) return true\n\n const objKeys = Object.keys(obj)\n const isReactObjNode = (objKeys.includes('tag') && objKeys.includes('containerInfo'))\n || objKeys.some(k => k.startsWith('__reactContainer'))\n || (objKeys.includes('tag') && objKeys.includes('stateNode'))\n\n return isReactObjNode\n}\n\n\nexport function isValidReactiveObject <T extends Record<string, any>> (value: T): boolean {\n return isObject(value) && !isReactElement(value) && !(value as any)[nonReactiveObjectSymbol]\n}\n\n\n\n/**\n * Returns the actual target value instead of root\n * object with internals props like $$value$$\n *\n * @param target - object from subscription or proxy\n * @returns actual value\n */\nexport const okTarget = (target: any): any => target[INTERNAL_VALUE_PROP] ?? target\n\n\n\n\n/**\n * Gets an object with just the properties requested\n * instead of the full object\n *\n * @param properties - object properties\n * @param obj - target to get the properties\n * @returns New object with just the requested properties\n */\nexport function getPartialObjectFromProperties<T> (properties: Array<keyof T>, obj: T): any {\n return properties.reduce<any>((acc, curr) => {\n acc[curr] = obj[curr]\n\n return acc\n }, {})\n}\n\n\n\nconst stringify = (obj: any): string => JSON.stringify(obj)\n\n/**\n * Compare 2 provided objects by stringing them\n * @param a - first object\n * @param b - second object\n * @returns boolean\n */\nexport const contentComparer = (a: any, b: any): boolean => stringify(a) === stringify(b)\n\n\n\n\nexport function safeToJson (obj: any): Record<string, any> {\n const o: Record<string, any> = {}\n\n if (typeof obj !== 'object' || obj == null)\n return obj\n\n if (Array.isArray(obj))\n return obj.map(item => safeToJson(item))\n\n if (isReactElement(obj))\n return { props: safeToJson(obj.props), type: typeof obj.type === 'string' ? obj.type : '' }\n\n if (globalThis?.HTMLElement && obj instanceof globalThis.HTMLElement) return { type: '[HTMLElement]', content: obj.innerHTML }\n\n Object.entries(obj).forEach(([key, v]) => {\n o[key] = safeToJson(v)\n })\n\n return o\n}\n","\nimport { deepClone, isValidReactiveObject, safeToJson } from '../utils/object'\n\nimport type { StoreChange } from '../../types/shared'\nimport type { CacheableSubject } from '../utils/subject'\n\n\n\n// @ts-expect-error - Object.hasOwn is not defined in older Safari's browsers\n('hasOwn' in Object) || (Object.hasOwn = Object.call.bind(Object.hasOwnProperty))\n\nconst ROOT_VALUE = Symbol('value')\n\n\nexport function proxifyStore <T extends Record<string | symbol, any>> (\n store$$: CacheableSubject<StoreChange<T>>,\n objectToProxify: T,\n opts: {\n nestedFieldPath?: string\n parentObjectToProxify?: any\n // beforeChange?: (storeChange: StoreChange<T>) => any\n afterChange?: (storeChange: Array<StoreChange<T>>) => void\n } = {},\n): T {\n const fieldPath = opts.nestedFieldPath ?? 'root'\n\n const objectWithRootValue = {\n [ROOT_VALUE]: objectToProxify,\n } as unknown as T\n\n const rootFunctions = fieldPath === 'root'\n ? Object.fromEntries(Object.entries(objectToProxify).filter(([,v]) => typeof v === 'function'))\n : {}\n\n return new Proxy(objectWithRootValue, {\n get (targetObject, propName, receiver) {\n // INFO: !Internal only.\n // Used to get the fieldPath of the object (it means it's a proxified object)\n if (propName === '_$fieldPath') return fieldPath\n\n const isRootTarget = Object.hasOwn(targetObject, ROOT_VALUE)\n const target = isRootTarget ? targetObject[ROOT_VALUE] : targetObject\n\n\n // Called when the object is converted to JSON or string (i.e. JSON.stringify)\n if (propName === 'toJSON') {\n return () => {\n // Remove react-elements with circular which have circular references\n // before stringifying to prevent JSON.stringify(storeProxy) from failing\n return safeToJson(target)\n // return removeCircularReferences(target)\n }\n }\n\n // Get the whole store value without proxies\n if (propName === '$value')\n return deepClone(target)\n // return target\n\n\n\n const propertyValue = Reflect.get(target, propName, receiver)\n\n if (typeof propName === 'symbol') return propertyValue\n\n if (typeof propertyValue === 'function')\n return (propertyValue as () => any).bind(receiver)\n\n\n // Check if it's correct to be a reactive object\n // & is not a circular reference or the same object\n if (isValidReactiveObject(propertyValue) && propertyValue !== target) {\n // const newNestedFieldPath = `${fieldPath}.${propName}`\n\n // If it's already a proxified object, return it\n // if (propertyValue._$fieldPath === newNestedFieldPath) return propertyValue\n if (propertyValue._$fieldPath) return propertyValue\n\n // Create a new proxified object\n const proxiedNestedObject = proxifyStore(\n store$$ as any,\n propertyValue,\n {\n nestedFieldPath: `${fieldPath}.${propName}`,\n parentObjectToProxify: opts.parentObjectToProxify ?? target,\n // beforeChange: opts.beforeChange,\n afterChange: opts.afterChange,\n },\n )\n\n return target[propName] = proxiedNestedObject\n }\n\n return propertyValue\n },\n\n\n set (parentObject, key, newValue, receiver) {\n if (typeof key === 'symbol') return true\n\n const value = newValue\n const isRootTarget = Object.hasOwn(parentObject, ROOT_VALUE)\n\n // INFO: !Internal only.\n // Used to set the value of the store without notifying the store\n if (isRootTarget && key === '$$value') {\n const previousValue = parentObject[ROOT_VALUE];\n\n (parentObject as any)[ROOT_VALUE] = value.newValue\n\n store$$.next({\n storeValue: value.newValue,\n change: {\n fieldPath: 'root' as any,\n newValue: value.newValue,\n previousValue,\n },\n }, value.id)\n\n return true\n }\n\n if (isRootTarget && key === '$value') {\n const previousValue = parentObject[ROOT_VALUE]\n\n if (value === previousValue) return true\n\n if (JSON.stringify(safeToJson(value)) === JSON.stringify(safeToJson(previousValue))) return true\n // if (safeStringify(value) === safeStringify(previousValue)) return true\n\n if (fieldPath !== 'root') {\n (parentObject as any)[ROOT_VALUE] = value\n } else {\n (parentObject as any)[ROOT_VALUE] = {\n ...rootFunctions,\n ...value,\n }\n store$$.next({\n // To be disabled for performance and send same store reference\n // storeValue: JSON.parse(JSON.stringify(targetObject[ROOT_VALUE])),\n storeValue: parentObject[ROOT_VALUE],\n change: {\n fieldPath: 'root' as any,\n newValue: value,\n previousValue,\n },\n })\n }\n\n return true\n }\n\n const realInnerObject = isRootTarget ? parentObject[ROOT_VALUE] : parentObject\n const previousValue = Reflect.get(realInnerObject, key, receiver)\n\n\n if (previousValue === value) return true\n\n\n // New object values, check if the field has already a proxy created to use it instead of reacreating a new instance\n if (isValidReactiveObject(value) && previousValue?._$fieldPath)\n previousValue.$value = value\n else\n Reflect.set(realInnerObject, key, value, realInnerObject)\n\n\n const nextStoreChange = {\n // To be disabled for performance and send same store reference\n // storeValue: JSON.parse(JSON.stringify(opts?.parentObjectToProxify ?? target)),\n storeValue: opts?.parentObjectToProxify ?? realInnerObject,\n change: {\n fieldPath: `${fieldPath}.${key}`.replace('root.', '') as any,\n newValue: value,\n previousValue,\n },\n }\n\n store$$.next(nextStoreChange)\n opts.afterChange?.([nextStoreChange])\n\n return true\n },\n\n has (t, p) {\n return Reflect.has(t[ROOT_VALUE], p)\n },\n\n ownKeys (t) {\n return Reflect.ownKeys(t[ROOT_VALUE])\n },\n\n getOwnPropertyDescriptor (t, p) {\n return Reflect.getOwnPropertyDescriptor(t[ROOT_VALUE], p)\n },\n\n })\n}\n\n\n// function getDeepUnproxiedObject (obj: any): any {\n// if (obj && typeof obj === 'object' && !Array.isArray(obj)) {\n// if (obj[ROOT_VALUE]?.[ROOT_VALUE]) {\n// console.warn('Circular reference detected in getDeepUnproxiedObject')\n//\n// return '[Circular reference]'\n// }\n//\n//\n// const r = Object.fromEntries(\n// Object.entries(obj).map(([key, value]) => {\n// // console.log('____________________getDeepUnproxiedObject', key, value, value.constructor.name)\n// if (value && typeof value === 'object' && !Array.isArray(value)) {\n// if (key === 'links') console.log('getDeepUnproxiedObject', key, value)\n//\n// // If it's a proxied object, get the unproxied value\n// return [key, getDeepUnproxiedObject(value)]\n// }\n//\n// return [key, value]\n// }),\n// )\n//\n//\n// return r\n// }\n//\n// return obj\n// }\n\n// function safeStringify (obj: any): string {\n// // use removeCircularReferences to avoid circular references\n// // const cleanedObj = removeCircularReferences(obj)\n// return JSON.stringify(safeToJson(obj))\n// //\n// // return JSON.stringify(\n// // obj,\n// // (_key, value) => {\n// // if (Array.isArray(value)) return value.map(i => safeStringify(i))\n// //\n// // if (isReactElement(value)) {\n// // // console.log('React element detected', value)\n// //\n// // return { props: safeStringify(value.props), type: typeof value.type === 'string' ? value.type : '' }\n// // }\n// //\n// // if (globalThis?.HTMLElement && value instanceof globalThis.HTMLElement) return { type: '[HTMLElement]', content: value.innerHTML }\n// //\n// // // console.log('Value', value)\n// //\n// // return value\n// // })\n// }\n\n\n\n\n// function removeCircularReferences (obj: any): any {\n// const seen = new WeakSet()\n//\n// function traverse (value: any): any {\n// if (value && typeof value === 'object') {\n// // If the object has already been seen, it's a circular reference\n// if (seen.has(value))\n// return null\n//\n// seen.add(value)\n//\n// if (Array.isArray(value))\n// return value.map(traverse)\n//\n//\n// const result: any = {}\n//\n// for (const key in value) {\n// if (Object.prototype.hasOwnProperty.call(value, key)) {\n// if (key === '_owner' && value.$$typeof) continue\n//\n// result[key] = traverse(value[key])\n// }\n// }\n//\n// return result\n// }\n//\n// // Return primitive values as-is\n// return value\n// }\n//\n// return traverse(obj)\n// }\n","\nimport { useEffect, useId, useRef, useState } from 'react'\n\nimport { nonReactiveObjectSymbol } from '../../types/shared'\nimport { proxifyStore } from '../helpers/new-proxify-store'\nimport { deepClone, safeToJson } from '../utils/object'\nimport { createCacheableSubject } from '../utils/subject'\n\nimport type { FieldPath, StoreChange } from '../../types/shared'\n\n\n\n\n// export type CervelloOptions<StoreValue extends Record<string, any>> = {\n// beforeChange?: (storeChange: StoreChange<StoreValue>) => unknown | undefined\n// afterChange?: (storeChange: Array<StoreChange<StoreValue>>) => void\n// }\n\nexport type CervelloOptions<StoreValue extends Record<string, any>> = {\n afterChange?: (storeChange: Array<StoreChange<StoreValue>>) => void\n}\n\nexport type CervelloUseStoreOptions<StoreValue extends Record<string, any>> = {\n initialValue?: (currentStore: StoreValue) => StoreValue | null,\n setValueOnMount?: (currentStore: StoreValue) => Promise<StoreValue>,\n select?:\n | Array<FieldPath<StoreValue>>\n | (() => Array<FieldPath<StoreValue>>)\n onChange?: (storeChange: Array<StoreChange<StoreValue>>) => void\n}\n\ntype MutableStoreValue<T extends Record<string, any>> = {\n $value: T\n} & T\n\n\n\n\n\n\n\n\nexport function nonReactive <T extends Record<string, any>> (initialValue: T): T {\n Object.defineProperty(initialValue, nonReactiveObjectSymbol, {\n value: true,\n enumerable: false,\n writable: false,\n configurable: false,\n })\n\n return initialValue\n}\n\n\nexport function cervello <StoreValue extends Record<PropertyKey, any>> (\n initialValue: StoreValue,\n options?: CervelloOptions<StoreValue>,\n): {\n store: MutableStoreValue<StoreValue>,\n reset: () => void,\n useStore: (options?: CervelloUseStoreOptions<StoreValue>) => MutableStoreValue<StoreValue>\n } {\n const {\n // beforeChange,\n afterChange,\n } = options ?? {}\n\n // const store$$ = createCacheableSubject<StoreChange<StoreValue>>(clonedInitialValue as any)\n const clonedInitialValue = deepClone(initialValue)\n\n const store$$ = createCacheableSubject<StoreChange<StoreValue>>()\n\n const proxiedStore = proxifyStore(\n store$$ as any,\n clonedInitialValue,\n // { beforeChange, afterChange },\n { afterChange },\n ) as MutableStoreValue<StoreValue>\n\n\n return {\n store: proxiedStore,\n reset: () => {\n proxiedStore.$value = deepClone(initialValue)\n },\n useStore: (options) => {\n const subscriberId = useId()\n const initialValue = options?.initialValue?.(proxiedStore.$value)\n const isInitialValueSet = useRef(false)\n const [, setRenderCount] = useState(0)\n\n if (!isInitialValueSet.current\n && initialValue\n && JSON.stringify(safeToJson(initialValue)) !== JSON.stringify(safeToJson(proxiedStore.$value))\n ) {\n isInitialValueSet.current = true;\n (proxiedStore as any).$$value = { id: subscriberId, newValue: initialValue }\n }\n\n const selectFieldPaths = useRef(\n (typeof options?.select === 'function'\n ? options?.select?.()\n : options?.select)\n ?? [],\n )\n\n\n const selectedFieldPathsForNestedObjects = useRef(\n selectFieldPaths.current\n .filter(fp => fp.includes('.*'))\n .map(fp => fp.replace('.*', '')),\n )\n\n const reRender = (): void => {\n setRenderCount(p => p + 1)\n }\n\n\n useEffect(() => {\n if (options?.setValueOnMount) {\n void options.setValueOnMount(proxiedStore.$value).then((value) => {\n proxiedStore.$value = value\n }).catch((err) => {\n console.error('Error setting initial value on mount', err)\n })\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [])\n\n\n // Same implementation as useSyncExternalStore but with useEffect\n useEffect(() => {\n const subscription = store$$.subscribe({\n id: subscriberId,\n next: (sc) => {\n const storeChanges = Array.isArray(sc)\n ? sc as Array<StoreChange<StoreValue>>\n : [sc]\n\n if (!options?.select) {\n reRender()\n options?.onChange?.(storeChanges)\n\n return\n }\n\n if (storeChanges.some(nextChange => (\n nextChange.change.fieldPath === 'root'\n || selectFieldPaths.current.includes(nextChange.change.fieldPath))\n || selectedFieldPathsForNestedObjects.current.find(fp => nextChange.change.fieldPath.startsWith(fp)),\n )) {\n reRender()\n options?.onChange?.(storeChanges)\n }\n },\n })\n\n return () => {\n subscription.unsubscribe()\n }\n\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [options?.select, options?.onChange])\n\n return proxiedStore\n },\n }\n}\n\n","\ntype Noop = () => void\n\n\ntype Observer<T> = {\n id: string\n next: (value: T, subscriberId?: string) => void\n}\n\ntype Subscription = {\n unsubscribe: Noop\n}\n\nexport type CacheableSubject<T> = {\n // getValue: () => T\n subscribe: (value: Observer<T>) => Subscription\n // unSubscribeAll: Noop\n} & Omit<Observer<T>, 'id'>\n\n\n\nexport function createCacheableSubject<T> (/* defaultValue: T/*, getValueOnSubscribe = false */): CacheableSubject<T> {\n let isFlushing = false\n let itemsToFlush: Array<{ newValue: T, subscriberId?: string }> = []\n\n let observerList: Array<Observer<T>> = []\n // let value = defaultValue\n\n // const getValue = (): T => value\n\n const next = (newValue: T, subscriberId?: string): void => {\n // value = newValue\n\n itemsToFlush.push({ newValue, subscriberId })\n\n if (!isFlushing) {\n isFlushing = true\n\n void Promise.resolve().then(() => {\n observerList.forEach((o) => {\n // Filter changes that were sent by the same subscriberId (initialValue function call)\n const nonInitiallySentBySubscriber = itemsToFlush.filter(item => item.subscriberId !== o.id)\n\n if (!nonInitiallySentBySubscriber.length) return\n\n o.next(nonInitiallySentBySubscriber.map(i => i.newValue) as T)\n })\n itemsToFlush = []\n isFlushing = false\n })\n\n // void Promise.resolve(subscriberId).then((subscriberId) => {\n // console.log('//// promise.resolve then', { subscriberId: s.id })\n // observerList.forEach((o) => {\n // console.log('//// CacheableSubject (forEach) flushing', { observerId: o.id, subscriberId: s.id })\n // if (o.id === subscriberId) return\n //\n // o.next(itemsToFlush as T)\n // })\n // itemsToFlush = []\n // isFlushing = false\n // })\n\n // void Promise.resolve().then(() => {\n // console.log('//// promise.resolve then')\n // observerList.forEach((o) => {\n // const nonInitiallySentBySubscriber = itemsToFlush.filter(item => item.subscriberId !== o.id)\n //\n // if (nonInitiallySentBySubscriber.length === 0) return\n //\n // o.next(nonInitiallySentBySubscriber.map(i => i.newValue) as T)\n // })\n // itemsToFlush = []\n // isFlushing = false\n // })\n }\n }\n\n const subscribe = (observer: Observer<T>): Subscription => {\n // Push cached value on subscribe\n // if (getValueOnSubscribe) observer.next(value)\n\n // Store the observer to be notified\n observerList.push(observer)\n\n return {\n unsubscribe: () => {\n observerList = observerList.filter(o => o.id !== observer.id)\n },\n }\n }\n\n // const unSubscribeAll = (): void => {\n // observerList = []\n // }\n\n return {\n // getValue,\n next,\n subscribe,\n // unSubscribeAll,\n }\n}\n"],"names":["nonReactiveObjectSymbol","Symbol","deepClone","obj","newObj","Array","isArray","map","item","isReactObjectLikeNode","isObject","isReactElement","objKeys","Object","keys","includes","some","k","startsWith","entries","forEach","_ref","getOwnPropertySymbols","symbol","$$typeof","isValidReactiveObject","value","safeToJson","o","props","type","globalThis","HTMLElement","content","innerHTML","_ref2","v","hasOwn","call","bind","hasOwnProperty","ROOT_VALUE","proxifyStore","store$$","objectToProxify","opts","_opts$nestedFieldPath","_objectWithRootValue","nestedFieldPath","objectWithRootValue","rootFunctions","fieldPath","fromEntries","filter","Proxy","get","targetObject","propName","receiver","target","propertyValue","Reflect","_opts$parentObjectToP","_$fieldPath","proxiedNestedObject","parentObjectToProxify","afterChange","set","parentObject","key","newValue","_opts$parentObjectToP2","_opts","isRootTarget","previousValue","next","storeValue","change","id","JSON","stringify","_extends","realInnerObject","$value","nextStoreChange","replace","has","t","p","ownKeys","getOwnPropertyDescriptor","initialValue","options","isFlushing","itemsToFlush","clonedInitialValue","subscriberId","push","resolve","then","observerList","nonInitiallySentBySubscriber","length","i","subscribe","observer","unsubscribe","proxiedStore","store","reset","useStore","useId","isInitialValueSet","useRef","setRenderCount","useState","current","$$value","selectFieldPaths","select","selectedFieldPathsForNestedObjects","fp","reRender","useEffect","setValueOnMount","err","console","error","subscription","sc","storeChanges","onChange","nextChange","find","defineProperty","enumerable","writable","configurable"],"mappings":"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"}