@cervello/react 5.4.0 → 5.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cervello.cjs +1 -1
- package/dist/cervello.cjs.map +1 -1
- package/dist/cervello.esm.js +1 -1
- package/dist/cervello.esm.js.map +1 -1
- package/dist/cervello.umd.js +1 -1
- package/dist/cervello.umd.js.map +1 -1
- package/package.json +1 -1
- package/types/lib/utils/object.d.ts +1 -1
- package/types/lib/utils/subject.d.ts +2 -3
- package/types/test/lib/proxify-store.test.d.ts +1 -0
- package/types/test/lib/store.test.d.ts +1 -0
- package/types/test/lib/subject.test.d.ts +1 -0
- package/types/test/lib/utils.test.d.ts +1 -0
- package/types/lib/helpers/create-store-selector-hook.d.ts +0 -3
- package/types/lib/helpers/index.d.ts +0 -2
- package/types/lib/helpers/proxify-store.d.ts +0 -2
- package/types/lib/store/index.d.ts +0 -58
package/dist/cervello.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var e=require("react"),n=Symbol("nonReactiveObject");function t(){return t=Object.assign?Object.assign.bind():function(e){for(var n=1;n<arguments.length;n++){var t=arguments[n];for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(e[r]=t[r])}return e},t.apply(this,arguments)}function r(e){if(!e||"object"!=typeof e)return e;var n={};return Array.isArray(e)?n=e.map(function(e){return
|
|
1
|
+
var e=require("react"),n=Symbol("nonReactiveObject");function t(){return t=Object.assign?Object.assign.bind():function(e){for(var n=1;n<arguments.length;n++){var t=arguments[n];for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(e[r]=t[r])}return e},t.apply(this,arguments)}function r(e,n){(null==n||n>e.length)&&(n=e.length);for(var t=0,r=new Array(n);t<n;t++)r[t]=e[t];return r}function u(e,n){var t="undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(t)return(t=t.call(e)).next.bind(t);if(Array.isArray(e)||(t=function(e,n){if(e){if("string"==typeof e)return r(e,n);var t=Object.prototype.toString.call(e).slice(8,-1);return"Object"===t&&e.constructor&&(t=e.constructor.name),"Map"===t||"Set"===t?Array.from(e):"Arguments"===t||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t)?r(e,n):void 0}}(e))||n&&e&&"number"==typeof e.length){t&&(e=t);var u=0;return function(){return u>=e.length?{done:!0}:{done:!1,value:e[u++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function i(e){if(!e||"object"!=typeof e)return e;var n={};return Array.isArray(e)?n=e.map(function(e){return i(e)}):function(e){if(!o(e))return!1;if(a(e))return!0;var n=Object.keys(e);return n.includes("tag")&&n.includes("containerInfo")||n.some(function(e){return e.startsWith("__reactContainer")})||n.includes("tag")&&n.includes("stateNode")}(e)?n=e:(Object.entries(e).forEach(function(e){n[e[0]]=i(e[1])}),Object.getOwnPropertySymbols(e).forEach(function(t){n[t]=e[t]})),n}var o=function(e){return null!==e&&"object"==typeof e&&!Array.isArray(e)},a=function(e){return!!o(e)&&!!e.$$typeof};function l(e){return o(e)&&!a(e)&&!e[n]}function c(e){var n={};if("object"!=typeof e||null==e)return e;if(Array.isArray(e))return e.map(function(e){return c(e)});if(a(e))return{props:c(e.props),type:"string"==typeof e.type?e.type:""};if(null!=globalThis&&globalThis.HTMLElement&&e instanceof globalThis.HTMLElement)return{type:"[HTMLElement]",content:e.innerHTML};for(var t=0,r=Object.entries(e);t<r.length;t++){var u=r[t];n[u[0]]=c(u[1])}return n}"hasOwn"in Object||(Object.hasOwn=Object.call.bind(Object.hasOwnProperty));var f=Symbol("value");function s(e,n,r){var u,o;void 0===r&&(r={});var a=null!=(u=r.nestedFieldPath)?u:"root",v=((o={})[f]=n,o),b="root"===a?Object.fromEntries(Object.entries(n).filter(function(e){return"function"==typeof e[1]})):{};return new Proxy(v,{get:function(n,t,u){if("_$fieldPath"===t)return a;var o=Object.hasOwn(n,f)?n[f]:n;if("toJSON"===t)return function(){return c(o)};if("$value"===t)return i(o);var v=Reflect.get(o,t,u);if("symbol"==typeof t)return v;if("function"==typeof v)return v.bind(u);if(l(v)&&v!==o){var b;if(v._$fieldPath)return v;var y=s(e,v,{nestedFieldPath:a+"."+t,parentObjectToProxify:null!=(b=r.parentObjectToProxify)?b:o,afterChange:r.afterChange});return o[t]=y}return v},set:function(n,u,i,o){var s,v;if("symbol"==typeof u)return!0;var y=i,h=Object.hasOwn(n,f);if(h&&"$$value"===u){var p=n[f];return n[f]=y.newValue,e.next({storeValue:y.newValue,change:{fieldPath:"root",newValue:y.newValue,previousValue:p}},y.id),!0}if(h&&"$value"===u){var d=n[f];return y===d||JSON.stringify(c(y))===JSON.stringify(c(d))||("root"!==a?n[f]=y:(n[f]=t({},b,y),e.next({storeValue:n[f],change:{fieldPath:"root",newValue:y,previousValue:d}}))),!0}var g=h?n[f]:n,O=Reflect.get(g,u,o);if(O===y)return!0;l(y)&&null!=O&&O._$fieldPath?O.$value=y:Reflect.set(g,u,y,g);var m={storeValue:null!=(s=null==(v=r)?void 0:v.parentObjectToProxify)?s:g,change:{fieldPath:(a+"."+u).replace("root.",""),newValue:y,previousValue:O}};return e.next(m),null==r.afterChange||r.afterChange([m]),!0},has:function(e,n){return Reflect.has(e[f],n)},ownKeys:function(e){return Reflect.ownKeys(e[f])},getOwnPropertyDescriptor:function(e,n){return Reflect.getOwnPropertyDescriptor(e[f],n)}})}function v(){var e=!1,n=!1,t=0,r=[],i=new Map,o=function t(){e||n||(e=!0,queueMicrotask(function(){if(e=!1,!n&&0!==i.size){n=!0;var o=new Map(i);i.clear();for(var a,l=u(r);!(a=l()).done;){for(var c,f=a.value,s=[],v=u(o.values());!(c=v()).done;){var b=c.value;b.subscriberId!==f.id&&s.push(b)}s.length>0&&f.next(s.map(function(e){return e.newValue}))}n=!1,i.size>0&&t()}}))};return{next:function(r,u){var a=(null!=u?u:"g")+"-"+ ++t;i.set(a,{newValue:r,subscriberId:u}),e||n||o()},subscribe:function(e){return r.push(e),{unsubscribe:function(){var n=r.indexOf(e);-1!==n&&r.splice(n,1)}}}}}exports.cervello=function(n,t){var r=(null!=t?t:{}).afterChange,u=i(n),o=v(),a=s(o,u,{afterChange:r});return{store:a,reset:function(){a.$value=i(n)},useStore:function(n){var t,r=e.useId(),u=null==n||null==n.initialValue?void 0:n.initialValue(a.$value),i=e.useRef(!1),l=e.useState(0)[1];!i.current&&u&&JSON.stringify(c(u))!==JSON.stringify(c(a.$value))&&(i.current=!0,a.$$value={id:r,newValue:u});var f=e.useRef(null!=(t="function"==typeof(null==n?void 0:n.select)?null==n||null==n.select?void 0:n.select():null==n?void 0:n.select)?t:[]),s=e.useRef(f.current.filter(function(e){return e.includes(".*")}).map(function(e){return e.replace(".*","")})),v=function(){l(function(e){return e+1})};return e.useEffect(function(){null!=n&&n.setValueOnMount&&n.setValueOnMount(a.$value).then(function(e){a.$value=e}).catch(function(e){console.error("Error setting initial value on mount",e)})},[]),e.useEffect(function(){var e=o.subscribe({id:r,next:function(e){var t=Array.isArray(e)?e:[e];if(null==n||!n.select)return v(),void(null==n||null==n.onChange||n.onChange(t));t.some(function(e){return"root"===e.change.fieldPath||f.current.includes(e.change.fieldPath)||s.current.find(function(n){return e.change.fieldPath.startsWith(n)})})&&(v(),null==n||null==n.onChange||n.onChange(t))}});return function(){e.unsubscribe()}},[null==n?void 0:n.select,null==n?void 0:n.onChange]),a}}},exports.nonReactive=function(e){return Object.defineProperty(e,n,{value:!0,enumerable:!1,writable:!1,configurable:!1}),e};
|
|
2
2
|
//# sourceMappingURL=cervello.cjs.map
|
package/dist/cervello.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"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","\nimport { deepClone, isReactElement, isValidReactiveObject } 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\nfunction 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\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 } 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 && initialValue && initialValue !== proxiedStore) {\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","\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 !== observer)\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","obj","newObj","Array","isArray","map","item","deepClone","isReactObjectLikeNode","isObject","isReactElement","objKeys","Object","keys","includes","some","k","startsWith","entries","forEach","_ref","getOwnPropertySymbols","symbol","$$typeof","isValidReactiveObject","value","hasOwn","call","bind","hasOwnProperty","store$$","objectToProxify","opts","fieldPath","_opts$nestedFieldPath","nestedFieldPath","objectWithRootValue","_objectWithRootValue","ROOT_VALUE","rootFunctions","fromEntries","filter","Proxy","get","targetObject","propName","receiver","target","propertyValue","Reflect","_$fieldPath","proxiedNestedObject","proxifyStore","parentObjectToProxify","afterChange","set","parentObject","key","newValue","_opts$parentObjectToP2","_opts","isRootTarget","previousValue","next","storeValue","change","id","_previousValue2","JSON","stringify","safeToJson","realInnerObject","$value","nextStoreChange","replace","has","t","p","ownKeys","getOwnPropertyDescriptor","o","props","type","globalThis","HTMLElement","content","innerHTML","_ref2","cervello","initialValue","options","isFlushing","itemsToFlush","observerList","clonedInitialValue","subscriberId","push","Promise","resolve","then","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","nonReactive","defineProperty","enumerable","writable","configurable"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"cervello.cjs","sources":["../src/types/shared.ts","../src/lib/utils/object.ts","../src/lib/helpers/new-proxify-store.ts","../src/lib/utils/subject.ts","../src/lib/store/new-index.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","\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\n// export 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 for (const [key, v] of Object.entries(obj))\n o[key] = safeToJson(v)\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 current subscriber (value.id)\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 recreating 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","\ntype Observer<T> = {\n id: string\n next: (value: T, subscriberId?: string) => void\n}\n\ntype Subscription = {\n unsubscribe: () => void\n}\n\ntype FlushItem<T> = {\n newValue: T\n subscriberId?: string\n}\n\nexport type CacheableSubject<T> = {\n subscribe: (observer: Observer<T>) => Subscription\n} & Omit<Observer<T>, 'id'>\n\nexport function createCacheableSubject<T> (): CacheableSubject<T> {\n let isScheduled = false\n let isFlushing = false\n let tick = 0\n const observerList: Array<Observer<T>> = []\n const updateList = new Map<string, FlushItem<T>>()\n\n const scheduleFlush = (): void => {\n if (isScheduled || isFlushing) return\n isScheduled = true\n\n queueMicrotask(() => {\n isScheduled = false\n\n if (isFlushing || updateList.size === 0) return\n\n isFlushing = true\n const updatesSnapshot = new Map(updateList)\n\n updateList.clear()\n\n for (const observer of observerList) {\n const filtered: Array<FlushItem<T>> = []\n\n for (const item of updatesSnapshot.values()) {\n if (item.subscriberId !== observer.id)\n filtered.push(item)\n }\n\n if (filtered.length > 0)\n observer.next(filtered.map(f => f.newValue) as T)\n }\n\n isFlushing = false\n\n if (updateList.size > 0)\n scheduleFlush()\n })\n }\n\n const next = (newValue: T, subscriberId?: string): void => {\n const key = `${subscriberId ?? 'g'}-${++tick}`\n\n updateList.set(key, { newValue, subscriberId })\n\n if (!isScheduled && !isFlushing)\n scheduleFlush()\n }\n\n const subscribe = (observer: Observer<T>): Subscription => {\n observerList.push(observer)\n\n return {\n unsubscribe: () => {\n const idx = observerList.indexOf(observer)\n\n if (idx !== -1)\n observerList.splice(idx, 1)\n },\n }\n }\n\n\n return { next, subscribe }\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 afterChange,\n } = options ?? {}\n\n const clonedInitialValue = deepClone(initialValue)\n\n const store$$ = createCacheableSubject<StoreChange<StoreValue>>()\n\n const proxiedStore = proxifyStore(\n store$$ as any,\n clonedInitialValue,\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"],"names":["nonReactiveObjectSymbol","Symbol","deepClone","obj","newObj","Array","isArray","map","item","isObject","isReactElement","objKeys","Object","keys","includes","some","k","startsWith","isReactObjectLikeNode","entries","forEach","_ref","getOwnPropertySymbols","symbol","$$typeof","isValidReactiveObject","value","safeToJson","o","props","type","globalThis","HTMLElement","content","innerHTML","_i","_Object$entries","length","_Object$entries$_i","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","createCacheableSubject","isScheduled","isFlushing","tick","observerList","updateList","Map","scheduleFlush","queueMicrotask","size","updatesSnapshot","clear","_step","_iterator","done","_step2","observer","filtered","_iterator2","_createForOfIteratorHelperLoose","values","subscriberId","push","f","subscribe","unsubscribe","indexOf","idx","splice","initialValue","options","clonedInitialValue","proxiedStore","store","reset","useStore","_ref2","useId","isInitialValueSet","useRef","setRenderCount","useState","current","$$value","selectFieldPaths","select","selectedFieldPathsForNestedObjects","fp","reRender","useEffect","setValueOnMount","then","err","console","error","subscription","sc","storeChanges","onChange","nextChange","find","defineProperty","enumerable","writable","configurable"],"mappings":"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"}
|
package/dist/cervello.esm.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{useId as e,useRef as n,useState as t,useEffect as r}from"react";var u=Symbol("nonReactiveObject");function i(){return i=Object.assign?Object.assign.bind():function(e){for(var n=1;n<arguments.length;n++){var t=arguments[n];for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(e[r]=t[r])}return e},i.apply(this,arguments)}function o(e){if(!e||"object"!=typeof e)return e;var n={};return Array.isArray(e)?n=e.map(function(e){return
|
|
1
|
+
import{useId as e,useRef as n,useState as t,useEffect as r}from"react";var u=Symbol("nonReactiveObject");function i(){return i=Object.assign?Object.assign.bind():function(e){for(var n=1;n<arguments.length;n++){var t=arguments[n];for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(e[r]=t[r])}return e},i.apply(this,arguments)}function o(e,n){(null==n||n>e.length)&&(n=e.length);for(var t=0,r=new Array(n);t<n;t++)r[t]=e[t];return r}function a(e,n){var t="undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(t)return(t=t.call(e)).next.bind(t);if(Array.isArray(e)||(t=function(e,n){if(e){if("string"==typeof e)return o(e,n);var t=Object.prototype.toString.call(e).slice(8,-1);return"Object"===t&&e.constructor&&(t=e.constructor.name),"Map"===t||"Set"===t?Array.from(e):"Arguments"===t||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t)?o(e,n):void 0}}(e))||n&&e&&"number"==typeof e.length){t&&(e=t);var r=0;return function(){return r>=e.length?{done:!0}:{done:!1,value:e[r++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function l(e){if(!e||"object"!=typeof e)return e;var n={};return Array.isArray(e)?n=e.map(function(e){return l(e)}):function(e){if(!c(e))return!1;if(f(e))return!0;var n=Object.keys(e);return n.includes("tag")&&n.includes("containerInfo")||n.some(function(e){return e.startsWith("__reactContainer")})||n.includes("tag")&&n.includes("stateNode")}(e)?n=e:(Object.entries(e).forEach(function(e){n[e[0]]=l(e[1])}),Object.getOwnPropertySymbols(e).forEach(function(t){n[t]=e[t]})),n}var c=function(e){return null!==e&&"object"==typeof e&&!Array.isArray(e)},f=function(e){return!!c(e)&&!!e.$$typeof};function s(e){return c(e)&&!f(e)&&!e[u]}function v(e){var n={};if("object"!=typeof e||null==e)return e;if(Array.isArray(e))return e.map(function(e){return v(e)});if(f(e))return{props:v(e.props),type:"string"==typeof e.type?e.type:""};if(null!=globalThis&&globalThis.HTMLElement&&e instanceof globalThis.HTMLElement)return{type:"[HTMLElement]",content:e.innerHTML};for(var t=0,r=Object.entries(e);t<r.length;t++){var u=r[t];n[u[0]]=v(u[1])}return n}"hasOwn"in Object||(Object.hasOwn=Object.call.bind(Object.hasOwnProperty));var b=Symbol("value");function y(e,n,t){var r,u;void 0===t&&(t={});var o=null!=(r=t.nestedFieldPath)?r:"root",a=((u={})[b]=n,u),c="root"===o?Object.fromEntries(Object.entries(n).filter(function(e){return"function"==typeof e[1]})):{};return new Proxy(a,{get:function(n,r,u){if("_$fieldPath"===r)return o;var i=Object.hasOwn(n,b)?n[b]:n;if("toJSON"===r)return function(){return v(i)};if("$value"===r)return l(i);var a=Reflect.get(i,r,u);if("symbol"==typeof r)return a;if("function"==typeof a)return a.bind(u);if(s(a)&&a!==i){var c;if(a._$fieldPath)return a;var f=y(e,a,{nestedFieldPath:o+"."+r,parentObjectToProxify:null!=(c=t.parentObjectToProxify)?c:i,afterChange:t.afterChange});return i[r]=f}return a},set:function(n,r,u,a){var l,f;if("symbol"==typeof r)return!0;var y=u,h=Object.hasOwn(n,b);if(h&&"$$value"===r){var p=n[b];return n[b]=y.newValue,e.next({storeValue:y.newValue,change:{fieldPath:"root",newValue:y.newValue,previousValue:p}},y.id),!0}if(h&&"$value"===r){var d=n[b];return y===d||JSON.stringify(v(y))===JSON.stringify(v(d))||("root"!==o?n[b]=y:(n[b]=i({},c,y),e.next({storeValue:n[b],change:{fieldPath:"root",newValue:y,previousValue:d}}))),!0}var g=h?n[b]:n,O=Reflect.get(g,r,a);if(O===y)return!0;s(y)&&null!=O&&O._$fieldPath?O.$value=y:Reflect.set(g,r,y,g);var m={storeValue:null!=(l=null==(f=t)?void 0:f.parentObjectToProxify)?l:g,change:{fieldPath:(o+"."+r).replace("root.",""),newValue:y,previousValue:O}};return e.next(m),null==t.afterChange||t.afterChange([m]),!0},has:function(e,n){return Reflect.has(e[b],n)},ownKeys:function(e){return Reflect.ownKeys(e[b])},getOwnPropertyDescriptor:function(e,n){return Reflect.getOwnPropertyDescriptor(e[b],n)}})}function h(){var e=!1,n=!1,t=0,r=[],u=new Map,i=function t(){e||n||(e=!0,queueMicrotask(function(){if(e=!1,!n&&0!==u.size){n=!0;var i=new Map(u);u.clear();for(var o,l=a(r);!(o=l()).done;){for(var c,f=o.value,s=[],v=a(i.values());!(c=v()).done;){var b=c.value;b.subscriberId!==f.id&&s.push(b)}s.length>0&&f.next(s.map(function(e){return e.newValue}))}n=!1,u.size>0&&t()}}))};return{next:function(r,o){var a=(null!=o?o:"g")+"-"+ ++t;u.set(a,{newValue:r,subscriberId:o}),e||n||i()},subscribe:function(e){return r.push(e),{unsubscribe:function(){var n=r.indexOf(e);-1!==n&&r.splice(n,1)}}}}}function p(e){return Object.defineProperty(e,u,{value:!0,enumerable:!1,writable:!1,configurable:!1}),e}function d(u,i){var o=(null!=i?i:{}).afterChange,a=l(u),c=h(),f=y(c,a,{afterChange:o});return{store:f,reset:function(){f.$value=l(u)},useStore:function(u){var i,o=e(),a=null==u||null==u.initialValue?void 0:u.initialValue(f.$value),l=n(!1),s=t(0)[1];!l.current&&a&&JSON.stringify(v(a))!==JSON.stringify(v(f.$value))&&(l.current=!0,f.$$value={id:o,newValue:a});var b=n(null!=(i="function"==typeof(null==u?void 0:u.select)?null==u||null==u.select?void 0:u.select():null==u?void 0:u.select)?i:[]),y=n(b.current.filter(function(e){return e.includes(".*")}).map(function(e){return e.replace(".*","")})),h=function(){s(function(e){return e+1})};return r(function(){null!=u&&u.setValueOnMount&&u.setValueOnMount(f.$value).then(function(e){f.$value=e}).catch(function(e){console.error("Error setting initial value on mount",e)})},[]),r(function(){var e=c.subscribe({id:o,next:function(e){var n=Array.isArray(e)?e:[e];if(null==u||!u.select)return h(),void(null==u||null==u.onChange||u.onChange(n));n.some(function(e){return"root"===e.change.fieldPath||b.current.includes(e.change.fieldPath)||y.current.find(function(n){return e.change.fieldPath.startsWith(n)})})&&(h(),null==u||null==u.onChange||u.onChange(n))}});return function(){e.unsubscribe()}},[null==u?void 0:u.select,null==u?void 0:u.onChange]),f}}}export{d as cervello,p as nonReactive};
|
|
2
2
|
//# sourceMappingURL=cervello.esm.js.map
|
package/dist/cervello.esm.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cervello.esm.js","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","\nimport { deepClone, isReactElement, isValidReactiveObject } 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\nfunction 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\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 } 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 && initialValue && initialValue !== proxiedStore) {\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","\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 !== observer)\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","obj","newObj","Array","isArray","map","item","deepClone","isReactObjectLikeNode","isObject","isReactElement","objKeys","Object","keys","includes","some","k","startsWith","entries","forEach","_ref","getOwnPropertySymbols","symbol","$$typeof","isValidReactiveObject","value","hasOwn","call","bind","hasOwnProperty","store$$","objectToProxify","opts","fieldPath","_opts$nestedFieldPath","nestedFieldPath","objectWithRootValue","_objectWithRootValue","ROOT_VALUE","rootFunctions","fromEntries","filter","Proxy","get","targetObject","propName","receiver","target","propertyValue","Reflect","_$fieldPath","proxiedNestedObject","proxifyStore","parentObjectToProxify","afterChange","set","parentObject","key","newValue","_opts$parentObjectToP2","_opts","isRootTarget","previousValue","next","storeValue","change","id","_previousValue2","JSON","stringify","safeToJson","realInnerObject","$value","nextStoreChange","replace","has","t","p","ownKeys","getOwnPropertyDescriptor","o","props","type","globalThis","HTMLElement","content","innerHTML","_ref2","nonReactive","initialValue","defineProperty","enumerable","writable","configurable","cervello","options","isFlushing","itemsToFlush","observerList","clonedInitialValue","subscriberId","push","Promise","resolve","then","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"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"cervello.esm.js","sources":["../src/types/shared.ts","../src/lib/utils/object.ts","../src/lib/helpers/new-proxify-store.ts","../src/lib/utils/subject.ts","../src/lib/store/new-index.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","\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\n// export 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 for (const [key, v] of Object.entries(obj))\n o[key] = safeToJson(v)\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 current subscriber (value.id)\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 recreating 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","\ntype Observer<T> = {\n id: string\n next: (value: T, subscriberId?: string) => void\n}\n\ntype Subscription = {\n unsubscribe: () => void\n}\n\ntype FlushItem<T> = {\n newValue: T\n subscriberId?: string\n}\n\nexport type CacheableSubject<T> = {\n subscribe: (observer: Observer<T>) => Subscription\n} & Omit<Observer<T>, 'id'>\n\nexport function createCacheableSubject<T> (): CacheableSubject<T> {\n let isScheduled = false\n let isFlushing = false\n let tick = 0\n const observerList: Array<Observer<T>> = []\n const updateList = new Map<string, FlushItem<T>>()\n\n const scheduleFlush = (): void => {\n if (isScheduled || isFlushing) return\n isScheduled = true\n\n queueMicrotask(() => {\n isScheduled = false\n\n if (isFlushing || updateList.size === 0) return\n\n isFlushing = true\n const updatesSnapshot = new Map(updateList)\n\n updateList.clear()\n\n for (const observer of observerList) {\n const filtered: Array<FlushItem<T>> = []\n\n for (const item of updatesSnapshot.values()) {\n if (item.subscriberId !== observer.id)\n filtered.push(item)\n }\n\n if (filtered.length > 0)\n observer.next(filtered.map(f => f.newValue) as T)\n }\n\n isFlushing = false\n\n if (updateList.size > 0)\n scheduleFlush()\n })\n }\n\n const next = (newValue: T, subscriberId?: string): void => {\n const key = `${subscriberId ?? 'g'}-${++tick}`\n\n updateList.set(key, { newValue, subscriberId })\n\n if (!isScheduled && !isFlushing)\n scheduleFlush()\n }\n\n const subscribe = (observer: Observer<T>): Subscription => {\n observerList.push(observer)\n\n return {\n unsubscribe: () => {\n const idx = observerList.indexOf(observer)\n\n if (idx !== -1)\n observerList.splice(idx, 1)\n },\n }\n }\n\n\n return { next, subscribe }\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 afterChange,\n } = options ?? {}\n\n const clonedInitialValue = deepClone(initialValue)\n\n const store$$ = createCacheableSubject<StoreChange<StoreValue>>()\n\n const proxiedStore = proxifyStore(\n store$$ as any,\n clonedInitialValue,\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"],"names":["nonReactiveObjectSymbol","Symbol","deepClone","obj","newObj","Array","isArray","map","item","isObject","isReactElement","objKeys","Object","keys","includes","some","k","startsWith","isReactObjectLikeNode","entries","forEach","_ref","getOwnPropertySymbols","symbol","$$typeof","isValidReactiveObject","value","safeToJson","o","props","type","globalThis","HTMLElement","content","innerHTML","_i","_Object$entries","length","_Object$entries$_i","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","createCacheableSubject","isScheduled","isFlushing","tick","observerList","updateList","Map","scheduleFlush","queueMicrotask","size","updatesSnapshot","clear","_step","_iterator","done","_step2","observer","filtered","_iterator2","_createForOfIteratorHelperLoose","values","subscriberId","push","f","subscribe","unsubscribe","indexOf","idx","splice","nonReactive","initialValue","defineProperty","enumerable","writable","configurable","cervello","options","clonedInitialValue","proxiedStore","store","reset","useStore","_ref2","useId","isInitialValueSet","useRef","setRenderCount","useState","current","$$value","selectFieldPaths","select","selectedFieldPathsForNestedObjects","fp","reRender","useEffect","setValueOnMount","then","err","console","error","subscription","sc","storeChanges","onChange","nextChange","find"],"mappings":"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"}
|
package/dist/cervello.umd.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports,require("react")):"function"==typeof define&&define.amd?define(["exports","react"],n):n((e||self).react={},e.react)}(this,function(e,n){var t=Symbol("nonReactiveObject");function r(){return r=Object.assign?Object.assign.bind():function(e){for(var n=1;n<arguments.length;n++){var t=arguments[n];for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(e[r]=t[r])}return e},r.apply(this,arguments)}function u(e){if(!e||"object"!=typeof e)return e;var n={};return Array.isArray(e)?n=e.map(function(e){return
|
|
1
|
+
!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports,require("react")):"function"==typeof define&&define.amd?define(["exports","react"],n):n((e||self).react={},e.react)}(this,function(e,n){var t=Symbol("nonReactiveObject");function r(){return r=Object.assign?Object.assign.bind():function(e){for(var n=1;n<arguments.length;n++){var t=arguments[n];for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(e[r]=t[r])}return e},r.apply(this,arguments)}function u(e,n){(null==n||n>e.length)&&(n=e.length);for(var t=0,r=new Array(n);t<n;t++)r[t]=e[t];return r}function o(e,n){var t="undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(t)return(t=t.call(e)).next.bind(t);if(Array.isArray(e)||(t=function(e,n){if(e){if("string"==typeof e)return u(e,n);var t=Object.prototype.toString.call(e).slice(8,-1);return"Object"===t&&e.constructor&&(t=e.constructor.name),"Map"===t||"Set"===t?Array.from(e):"Arguments"===t||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t)?u(e,n):void 0}}(e))||n&&e&&"number"==typeof e.length){t&&(e=t);var r=0;return function(){return r>=e.length?{done:!0}:{done:!1,value:e[r++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function i(e){if(!e||"object"!=typeof e)return e;var n={};return Array.isArray(e)?n=e.map(function(e){return i(e)}):function(e){if(!a(e))return!1;if(l(e))return!0;var n=Object.keys(e);return n.includes("tag")&&n.includes("containerInfo")||n.some(function(e){return e.startsWith("__reactContainer")})||n.includes("tag")&&n.includes("stateNode")}(e)?n=e:(Object.entries(e).forEach(function(e){n[e[0]]=i(e[1])}),Object.getOwnPropertySymbols(e).forEach(function(t){n[t]=e[t]})),n}var a=function(e){return null!==e&&"object"==typeof e&&!Array.isArray(e)},l=function(e){return!!a(e)&&!!e.$$typeof};function f(e){return a(e)&&!l(e)&&!e[t]}function c(e){var n={};if("object"!=typeof e||null==e)return e;if(Array.isArray(e))return e.map(function(e){return c(e)});if(l(e))return{props:c(e.props),type:"string"==typeof e.type?e.type:""};if(null!=globalThis&&globalThis.HTMLElement&&e instanceof globalThis.HTMLElement)return{type:"[HTMLElement]",content:e.innerHTML};for(var t=0,r=Object.entries(e);t<r.length;t++){var u=r[t];n[u[0]]=c(u[1])}return n}"hasOwn"in Object||(Object.hasOwn=Object.call.bind(Object.hasOwnProperty));var s=Symbol("value");function v(e,n,t){var u,o;void 0===t&&(t={});var a=null!=(u=t.nestedFieldPath)?u:"root",l=((o={})[s]=n,o),y="root"===a?Object.fromEntries(Object.entries(n).filter(function(e){return"function"==typeof e[1]})):{};return new Proxy(l,{get:function(n,r,u){if("_$fieldPath"===r)return a;var o=Object.hasOwn(n,s)?n[s]:n;if("toJSON"===r)return function(){return c(o)};if("$value"===r)return i(o);var l=Reflect.get(o,r,u);if("symbol"==typeof r)return l;if("function"==typeof l)return l.bind(u);if(f(l)&&l!==o){var y;if(l._$fieldPath)return l;var b=v(e,l,{nestedFieldPath:a+"."+r,parentObjectToProxify:null!=(y=t.parentObjectToProxify)?y:o,afterChange:t.afterChange});return o[r]=b}return l},set:function(n,u,o,i){var l,v;if("symbol"==typeof u)return!0;var b=o,d=Object.hasOwn(n,s);if(d&&"$$value"===u){var p=n[s];return n[s]=b.newValue,e.next({storeValue:b.newValue,change:{fieldPath:"root",newValue:b.newValue,previousValue:p}},b.id),!0}if(d&&"$value"===u){var h=n[s];return b===h||JSON.stringify(c(b))===JSON.stringify(c(h))||("root"!==a?n[s]=b:(n[s]=r({},y,b),e.next({storeValue:n[s],change:{fieldPath:"root",newValue:b,previousValue:h}}))),!0}var g=d?n[s]:n,O=Reflect.get(g,u,i);if(O===b)return!0;f(b)&&null!=O&&O._$fieldPath?O.$value=b:Reflect.set(g,u,b,g);var m={storeValue:null!=(l=null==(v=t)?void 0:v.parentObjectToProxify)?l:g,change:{fieldPath:(a+"."+u).replace("root.",""),newValue:b,previousValue:O}};return e.next(m),null==t.afterChange||t.afterChange([m]),!0},has:function(e,n){return Reflect.has(e[s],n)},ownKeys:function(e){return Reflect.ownKeys(e[s])},getOwnPropertyDescriptor:function(e,n){return Reflect.getOwnPropertyDescriptor(e[s],n)}})}function y(){var e=!1,n=!1,t=0,r=[],u=new Map,i=function t(){e||n||(e=!0,queueMicrotask(function(){if(e=!1,!n&&0!==u.size){n=!0;var i=new Map(u);u.clear();for(var a,l=o(r);!(a=l()).done;){for(var f,c=a.value,s=[],v=o(i.values());!(f=v()).done;){var y=f.value;y.subscriberId!==c.id&&s.push(y)}s.length>0&&c.next(s.map(function(e){return e.newValue}))}n=!1,u.size>0&&t()}}))};return{next:function(r,o){var a=(null!=o?o:"g")+"-"+ ++t;u.set(a,{newValue:r,subscriberId:o}),e||n||i()},subscribe:function(e){return r.push(e),{unsubscribe:function(){var n=r.indexOf(e);-1!==n&&r.splice(n,1)}}}}}e.cervello=function(e,t){var r=(null!=t?t:{}).afterChange,u=i(e),o=y(),a=v(o,u,{afterChange:r});return{store:a,reset:function(){a.$value=i(e)},useStore:function(e){var t,r=n.useId(),u=null==e||null==e.initialValue?void 0:e.initialValue(a.$value),i=n.useRef(!1),l=n.useState(0)[1];!i.current&&u&&JSON.stringify(c(u))!==JSON.stringify(c(a.$value))&&(i.current=!0,a.$$value={id:r,newValue:u});var f=n.useRef(null!=(t="function"==typeof(null==e?void 0:e.select)?null==e||null==e.select?void 0:e.select():null==e?void 0:e.select)?t:[]),s=n.useRef(f.current.filter(function(e){return e.includes(".*")}).map(function(e){return e.replace(".*","")})),v=function(){l(function(e){return e+1})};return n.useEffect(function(){null!=e&&e.setValueOnMount&&e.setValueOnMount(a.$value).then(function(e){a.$value=e}).catch(function(e){console.error("Error setting initial value on mount",e)})},[]),n.useEffect(function(){var n=o.subscribe({id:r,next:function(n){var t=Array.isArray(n)?n:[n];if(null==e||!e.select)return v(),void(null==e||null==e.onChange||e.onChange(t));t.some(function(e){return"root"===e.change.fieldPath||f.current.includes(e.change.fieldPath)||s.current.find(function(n){return e.change.fieldPath.startsWith(n)})})&&(v(),null==e||null==e.onChange||e.onChange(t))}});return function(){n.unsubscribe()}},[null==e?void 0:e.select,null==e?void 0:e.onChange]),a}}},e.nonReactive=function(e){return Object.defineProperty(e,t,{value:!0,enumerable:!1,writable:!1,configurable:!1}),e}});
|
|
2
2
|
//# sourceMappingURL=cervello.umd.js.map
|
package/dist/cervello.umd.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cervello.umd.js","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","\nimport { deepClone, isReactElement, isValidReactiveObject } 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\nfunction 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\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 } 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 && initialValue && initialValue !== proxiedStore) {\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","\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 !== observer)\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","obj","newObj","Array","isArray","map","item","deepClone","isReactObjectLikeNode","isObject","isReactElement","objKeys","Object","keys","includes","some","k","startsWith","entries","forEach","_ref","getOwnPropertySymbols","symbol","$$typeof","isValidReactiveObject","value","hasOwn","call","bind","hasOwnProperty","store$$","objectToProxify","opts","fieldPath","_opts$nestedFieldPath","nestedFieldPath","objectWithRootValue","_objectWithRootValue","ROOT_VALUE","rootFunctions","fromEntries","filter","Proxy","get","targetObject","propName","receiver","target","propertyValue","Reflect","_$fieldPath","proxiedNestedObject","proxifyStore","parentObjectToProxify","afterChange","set","parentObject","key","newValue","_opts$parentObjectToP2","_opts","isRootTarget","previousValue","next","storeValue","change","id","_previousValue2","JSON","stringify","safeToJson","realInnerObject","$value","nextStoreChange","replace","has","t","p","ownKeys","getOwnPropertyDescriptor","o","props","type","globalThis","HTMLElement","content","innerHTML","_ref2","cervello","initialValue","options","isFlushing","itemsToFlush","observerList","clonedInitialValue","subscriberId","push","Promise","resolve","then","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","nonReactive","defineProperty","enumerable","writable","configurable"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"cervello.umd.js","sources":["../src/types/shared.ts","../src/lib/utils/object.ts","../src/lib/helpers/new-proxify-store.ts","../src/lib/utils/subject.ts","../src/lib/store/new-index.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","\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\n// export 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 for (const [key, v] of Object.entries(obj))\n o[key] = safeToJson(v)\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 current subscriber (value.id)\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 recreating 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","\ntype Observer<T> = {\n id: string\n next: (value: T, subscriberId?: string) => void\n}\n\ntype Subscription = {\n unsubscribe: () => void\n}\n\ntype FlushItem<T> = {\n newValue: T\n subscriberId?: string\n}\n\nexport type CacheableSubject<T> = {\n subscribe: (observer: Observer<T>) => Subscription\n} & Omit<Observer<T>, 'id'>\n\nexport function createCacheableSubject<T> (): CacheableSubject<T> {\n let isScheduled = false\n let isFlushing = false\n let tick = 0\n const observerList: Array<Observer<T>> = []\n const updateList = new Map<string, FlushItem<T>>()\n\n const scheduleFlush = (): void => {\n if (isScheduled || isFlushing) return\n isScheduled = true\n\n queueMicrotask(() => {\n isScheduled = false\n\n if (isFlushing || updateList.size === 0) return\n\n isFlushing = true\n const updatesSnapshot = new Map(updateList)\n\n updateList.clear()\n\n for (const observer of observerList) {\n const filtered: Array<FlushItem<T>> = []\n\n for (const item of updatesSnapshot.values()) {\n if (item.subscriberId !== observer.id)\n filtered.push(item)\n }\n\n if (filtered.length > 0)\n observer.next(filtered.map(f => f.newValue) as T)\n }\n\n isFlushing = false\n\n if (updateList.size > 0)\n scheduleFlush()\n })\n }\n\n const next = (newValue: T, subscriberId?: string): void => {\n const key = `${subscriberId ?? 'g'}-${++tick}`\n\n updateList.set(key, { newValue, subscriberId })\n\n if (!isScheduled && !isFlushing)\n scheduleFlush()\n }\n\n const subscribe = (observer: Observer<T>): Subscription => {\n observerList.push(observer)\n\n return {\n unsubscribe: () => {\n const idx = observerList.indexOf(observer)\n\n if (idx !== -1)\n observerList.splice(idx, 1)\n },\n }\n }\n\n\n return { next, subscribe }\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 afterChange,\n } = options ?? {}\n\n const clonedInitialValue = deepClone(initialValue)\n\n const store$$ = createCacheableSubject<StoreChange<StoreValue>>()\n\n const proxiedStore = proxifyStore(\n store$$ as any,\n clonedInitialValue,\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"],"names":["nonReactiveObjectSymbol","Symbol","deepClone","obj","newObj","Array","isArray","map","item","isObject","isReactElement","objKeys","Object","keys","includes","some","k","startsWith","isReactObjectLikeNode","entries","forEach","_ref","getOwnPropertySymbols","symbol","$$typeof","isValidReactiveObject","value","safeToJson","o","props","type","globalThis","HTMLElement","content","innerHTML","_i","_Object$entries","length","_Object$entries$_i","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","createCacheableSubject","isScheduled","isFlushing","tick","observerList","updateList","Map","scheduleFlush","queueMicrotask","size","updatesSnapshot","clear","_step","_iterator","done","_step2","observer","filtered","_iterator2","_createForOfIteratorHelperLoose","values","subscriberId","push","f","subscribe","unsubscribe","indexOf","idx","splice","initialValue","options","clonedInitialValue","proxiedStore","store","reset","useStore","_ref2","useId","isInitialValueSet","useRef","setRenderCount","useState","current","$$value","selectFieldPaths","select","selectedFieldPathsForNestedObjects","fp","reRender","useEffect","setValueOnMount","then","err","console","error","subscription","sc","storeChanges","onChange","nextChange","find","defineProperty","enumerable","writable","configurable"],"mappings":"sQAyCoCA,EAAGC,OAAO,+iCC7B9BC,SAAAA,EAAeC,GAC7B,IAAKA,GAAsB,iBAARA,EACjB,OAAUA,EAEZ,IAAIC,EAAS,CAAA,EAeb,OAbIC,MAAMC,QAAQH,GAChBC,EAASD,EAAII,IAAI,SAAAC,GAAI,OAAaN,EAACM,EAAK,GAiItC,SAAiCL,GACrC,IAAKM,EAASN,GAAM,OAAY,EAChC,GAAIO,EAAeP,GAAM,OAAO,EAEhC,IAAaQ,EAAGC,OAAOC,KAAKV,GAK5B,OAJwBQ,EAAQG,SAAS,QAAUH,EAAQG,SAAS,kBAC3DH,EAAQI,KAAK,SAAAC,GAAKA,OAAAA,EAAEC,WAAW,mBAAmB,IACjDN,EAAQG,SAAS,QAAUH,EAAQG,SAAS,YAGxD,CA1IcI,CAAsBf,GAQhCC,EAASD,GAPTS,OAAOO,QAAQhB,GAAKiB,QAAQ,SAAiBC,GAC3CjB,EAD+BiB,EAAA,IACjBnB,EADwBmB,EAAA,GAExC,GACAT,OAAOU,sBAAsBnB,GAAKiB,QAAQ,SAACG,GACzCnB,EAAOmB,GAAWpB,EAAYoB,EAChC,IAKKnB,CACT,CAsGaK,IAAAA,EAAW,SAACN,GAAY,OAC3B,OAALA,GACe,iBAARA,IACNE,MAAMC,QAAQH,EAAI,EAIGO,EAAG,SAACP,GAC7B,QAAKM,EAASN,MAEJA,EAAIqB,QAChB,EAgBgBC,SAAAA,EAAuDC,GACrE,OAAOjB,EAASiB,KAAWhB,EAAegB,KAAYA,EAAc1B,EACtE,CA+CgB2B,SAAAA,EAAYxB,GAC1B,IAAMyB,EAAyB,CAAA,EAE/B,GAAmB,iBAALzB,GAAwB,MAAPA,EAC7B,OAAOA,EAET,GAAIE,MAAMC,QAAQH,GAChB,OAAUA,EAACI,IAAI,SAAAC,GAAQmB,OAAAA,EAAWnB,EAAK,GAEzC,GAAIE,EAAeP,GACjB,MAAO,CAAE0B,MAAOF,EAAWxB,EAAI0B,OAAQC,KAA0B,iBAAV3B,EAAC2B,KAAoB3B,EAAI2B,KAAO,IAEzF,GAAc,MAAVC,YAAAA,WAAYC,aAAe7B,aAAyB4B,WAACC,YAAa,MAAO,CAAEF,KAAM,gBAAiBG,QAAS9B,EAAI+B,WAEnH,IAAA,IAAAC,EAAA,EAAAC,EAAuBxB,OAAOO,QAAQhB,GAAjCgC,EAAAC,EAAAC,OAAAF,IAAA,CAAA,IAAAG,EAAAF,EAAAD,GACHP,EADaU,EAAA,IACJX,EADOW,EAAA,GACM,CAExB,OACFV,CAAA,CC3NC,oBAAwBhB,OAAO2B,OAAS3B,OAAO4B,KAAKC,KAAK7B,OAAO8B,iBAEjE,IAAgBC,EAAG1C,OAAO,kBAGE2C,EAC1BC,EACAC,EACAC,GAKM,IAAAC,EAAAC,OALNF,IAAAA,IAAAA,EAKI,IAEJ,MAAsC,OAApBA,EAAAA,EAAKG,iBAAeF,EAAI,OAEjBG,IAAAF,EAAA,CAAA,GACtBN,GAAaG,EACCG,GAEXG,EAA8B,SAAdC,EAClBzC,OAAO0C,YAAY1C,OAAOO,QAAQ2B,GAAiBS,OAAO,SAAAlC,GAAI,MAAmB,mBAAnBA,EAAA,EAA6B,IAC3F,CAAE,EAEN,WAAgBmC,MAACL,EAAqB,CACpCM,IAAG,SAAEC,EAAcC,EAAUC,GAG3B,GAAiB,gBAAbD,EAA4B,SAEhC,IACME,EADejD,OAAO2B,OAAOmB,EAAcf,GACnBe,EAAaf,GAAce,EAIzD,GAAiB,WAAbC,EACF,OAAY,WAGV,OAAiBhC,EAACkC,EAEpB,EAIF,GAAiB,WAAbF,EACF,SAAiBE,GAKnB,IAAmBC,EAAGC,QAAQN,IAAII,EAAQF,EAAUC,GAEpD,GAAwB,mBAAU,SAElC,GAA6B,mBAALE,EACtB,OAAmCA,EAACrB,KAAKmB,GAK3C,GAAInC,EAAsBqC,IAAkBA,IAAkBD,EAAQ,CAAA,IAAAG,EAKpE,GAAIF,EAAcG,YAAa,OAAoBH,EAGnD,IAAyBI,EAAGtB,EAC1BC,EACAiB,EACA,CACEZ,gBAAoBG,EAAS,IAAIM,EACjCQ,sBAAiD,OAA1BpB,EAAAA,EAAKoB,uBAAqBH,EAAIH,EAErDO,YAAarB,EAAKqB,cAItB,OAAaP,EAACF,GAAYO,CAC5B,CAEA,OACFJ,CAAA,EAGAO,aAAKC,EAAcC,EAAKC,EAAUZ,GAChC,IAAAa,EAAAC,EAAA,GAAmB,iBAALH,EAAe,OAAW,EAExC,IAAM7C,EAAQ8C,EACRG,EAAe/D,OAAO2B,OAAO+B,EAAc3B,GAIjD,GAAIgC,GAAwB,YAARJ,EAAmB,CACrC,IAAMK,EAAgBN,EAAa3B,GAanC,OAXC2B,EAAqB3B,GAAcjB,EAAM8C,SAE1C3B,EAAQgC,KAAK,CACXC,WAAYpD,EAAM8C,SAClBO,OAAQ,CACN1B,UAAW,OACXmB,SAAU9C,EAAM8C,SAChBI,cAAAA,IAEDlD,EAAMsD,KAGX,CAAA,CAEA,GAAIL,GAAwB,WAARJ,EAAkB,CACpC,IAAMK,EAAgBN,EAAa3B,GAEnC,OAAIjB,IAAUkD,GAEVK,KAAKC,UAAUvD,EAAWD,MAAYuD,KAAKC,UAAUvD,EAAWiD,MAGlD,SAAdvB,EACDiB,EAAqB3B,GAAcjB,GAEnC4C,EAAqB3B,GAAWwC,EAAA,CAAA,EAC5B/B,EACA1B,GAELmB,EAAQgC,KAAK,CAGXC,WAAYR,EAAa3B,GACzBoC,OAAQ,CACN1B,UAAW,OACXmB,SAAU9C,EACVkD,cAAAA,QAnB8B,CAyBtC,CAEA,MAAwBD,EAAeL,EAAa3B,GAAc2B,EAC/CM,EAAGb,QAAQN,IAAI2B,EAAiBb,EAAKX,GAGxD,GAAIgB,IAAkBlD,EAAO,OAAO,EAIhCD,EAAsBC,IAAuB,MAAbkD,GAAAA,EAAeX,YACjDW,EAAcS,OAAS3D,EAEvBqC,QAAQM,IAAIe,EAAiBb,EAAK7C,EAAO0D,GAG3C,IAAME,EAAkB,CAGtBR,WAA2CM,OAA/BrC,EAAA,OAAAA,EAAAA,QAAA,EAAA2B,EAAMP,uBAAyBiB,EAAAA,EAC3CL,OAAQ,CACN1B,WAAcA,MAAakB,GAAMgB,QAAQ,QAAS,IAClDf,SAAU9C,EACVkD,cAAAA,IAOJ,OAHA/B,EAAQgC,KAAKS,GACbvC,MAAAA,EAAKqB,aAALrB,EAAKqB,YAAc,CAACkB,KAGtB,CAAA,EAEAE,IAAG,SAAEC,EAAGC,GACN,OAAO3B,QAAQyB,IAAIC,EAAE9C,GAAa+C,EACpC,EAEAC,QAAO,SAAEF,GACP,OAAO1B,QAAQ4B,QAAQF,EAAE9C,GAC3B,EAEAiD,yBAA0BH,SAAAA,EAAGC,GAC3B,OAAO3B,QAAQ6B,yBAAyBH,EAAE9C,GAAa+C,EACzD,GAGJ,CCjLgBG,SAAAA,IACd,IAAIC,GAAc,EACJC,GAAG,EACTC,EAAG,EACLC,EAAmC,GACzBC,EAAG,IAAIC,IAEjBC,EAAgB,SAAHA,IACbN,GAAeC,IACnBD,GAAc,EAEdO,eAAe,WAGb,GAFAP,GAAc,GAEVC,GAAkC,IAApBG,EAAWI,KAA7B,CAEAP,GAAa,EACb,IAAqBQ,EAAG,IAAIJ,IAAID,GAEhCA,EAAWM,QAEX,IAAuBP,IAAcQ,EAAdR,EAAAA,EAAAA,KAAcQ,EAAAC,KAAAC,MAAA,CAGnC,IAHmC,IAGQC,EAH1BC,EAAAJ,EAAA/E,MACXoF,EAAgC,GAEtCC,EAAAC,EAAmBT,EAAgBU,YAAQL,EAAAG,KAAAJ,MAAE,CAAlCnG,IAAAA,EACToG,EAAAlF,MAAIlB,EAAK0G,eAAiBL,EAAS7B,IACjC8B,EAASK,KAAK3G,EAClB,CAEIsG,EAASzE,OAAS,GACpBwE,EAAShC,KAAKiC,EAASvG,IAAI,SAAA6G,GAAC,OAAKA,EAAC5C,QAAQ,GAC9C,CAEAuB,GAAa,EAETG,EAAWI,KAAO,GACpBF,GApBFL,CAqBF,GACF,EAyBA,MAAO,CAAElB,KAvBI,SAACL,EAAa0C,GACzB,IAAM3C,GAAS2C,MAAAA,EAAAA,EAAgB,KAAO,OAAElB,EAExCE,EAAW7B,IAAIE,EAAK,CAAEC,SAAAA,EAAU0C,aAAAA,IAE3BpB,GAAgBC,GACnBK,GACJ,EAgBeiB,UAdG,SAACR,GAGjB,OAFAZ,EAAakB,KAAKN,GAEX,CACLS,YAAa,WACX,MAAYrB,EAAasB,QAAQV,IAEpB,IAATW,GACFvB,EAAawB,OAAOD,EAAK,EAC7B,EAEJ,EAIF,YC7BgB,SACdE,EACAC,GAMA,IACEvD,GACS,MAAPuD,EAAAA,EAAW,CAAA,GADbvD,YAGIwD,EAAqB1H,EAAUwH,GAExB7E,EAAGgD,IAEEgC,EAAGjF,EACnBC,EACA+E,EACA,CAAExD,YAAAA,IAIJ,MAAO,CACL0D,MAAOD,EACPE,MAAO,WACLF,EAAaxC,OAASnF,EAAUwH,EAClC,EACAM,SAAU,SAACL,GAAW,IAAAM,EACdf,EAAegB,EAAAA,QACHR,EAAU,MAAPC,GAAqB,MAArBA,EAASD,kBAAF,EAAPC,EAASD,aAAeG,EAAaxC,QACpD8C,EAAoBC,EAAAA,QAAO,GACxBC,EAAkBC,EAAAA,SAAS,GAEpC,IAAKH,EAAkBI,SAClBb,GACAzC,KAAKC,UAAUvD,EAAW+F,MAAmBzC,KAAKC,UAAUvD,EAAWkG,EAAaxC,WAEvF8C,EAAkBI,SAAU,EAC3BV,EAAqBW,QAAU,CAAExD,GAAIkC,EAAc1C,SAAUkD,IAGhE,IAAMe,EAAmBL,EAAAA,OAIlB,OAHJH,EAA2B,mBAAb,MAAPN,OAAO,EAAPA,EAASe,QACN,MAAPf,GAAAA,MAAAA,EAASe,YAAF,EAAPf,EAASe,SACTf,MAAAA,OAAAA,EAAAA,EAASe,QACRT,EAAA,IAIiCU,EAAGP,EAAAA,OACzCK,EAAiBF,QACdhF,OAAO,SAAAqF,GAAMA,OAAAA,EAAG9H,SAAS,KAAK,GAC9BP,IAAI,SAAAqI,GAAMA,OAAAA,EAAGrD,QAAQ,KAAM,GAAG,IAGrBsD,EAAG,WACfR,EAAe,SAAA3C,GAAKA,OAAAA,EAAI,CAAC,EAC3B,EAiDA,OA9CAoD,EAASA,UAAC,WACG,MAAPnB,GAAAA,EAASoB,mBACEA,gBAAgBlB,EAAaxC,QAAQ2D,KAAK,SAACtH,GACtDmG,EAAaxC,OAAS3D,CACxB,GAAQ,MAAC,SAACuH,GACRC,QAAQC,MAAM,uCAAwCF,EACxD,EAGJ,EAAG,IAIHH,EAASA,UAAC,WACR,IAAkBM,EAAGvG,EAAQwE,UAAU,CACrCrC,GAAIkC,EACJrC,KAAM,SAACwE,GACL,IAAkBC,EAAGjJ,MAAMC,QAAQ+I,GAC/BA,EACA,CAACA,GAEL,GAAY,MAAP1B,IAAAA,EAASe,OAIZ,OAHAG,SACAlB,MAAAA,GAAAA,MAAAA,EAAS4B,UAAT5B,EAAS4B,SAAWD,IAKlBA,EAAavI,KAAK,SAAAyI,GACpBA,MAAgC,SAAhCA,EAAWzE,OAAO1B,WACboF,EAAiBF,QAAQzH,SAAS0I,EAAWzE,OAAO1B,YACpDsF,EAAmCJ,QAAQkB,KAAK,SAAAb,GAAE,OAAcY,EAACzE,OAAO1B,UAAUpC,WAAW2H,EAAG,EAAC,KAEtGC,IACAlB,MAAAA,GAAAA,MAAAA,EAAS4B,UAAT5B,EAAS4B,SAAWD,GAExB,IAGF,OAAY,WACVF,EAAa9B,aACf,CAGF,EAAG,CAACK,MAAAA,OAAAA,EAAAA,EAASe,aAAQf,SAAAA,EAAS4B,WAEvB1B,CACT,EAEJ,gBA1HM,SAAuDH,GAQ3D,OAPA9G,OAAO8I,eAAehC,EAAc1H,EAAyB,CAC3D0B,OAAO,EACPiI,YAAY,EACZC,UAAU,EACVC,cAAc,IAIlBnC,CAAA"}
|
package/package.json
CHANGED
|
@@ -6,7 +6,6 @@
|
|
|
6
6
|
* @returns new cloned object with new reference
|
|
7
7
|
*/
|
|
8
8
|
export declare function deepClone<T>(obj: T): T;
|
|
9
|
-
export declare function deepClone2<T>(obj: T): T;
|
|
10
9
|
/**
|
|
11
10
|
* Guard to check is variable is an object
|
|
12
11
|
* @param obj - variable to be checked
|
|
@@ -40,3 +39,4 @@ export declare function getPartialObjectFromProperties<T>(properties: Array<keyo
|
|
|
40
39
|
* @returns boolean
|
|
41
40
|
*/
|
|
42
41
|
export declare const contentComparer: (a: any, b: any) => boolean;
|
|
42
|
+
export declare function safeToJson(obj: any): Record<string, any>;
|
|
@@ -1,13 +1,12 @@
|
|
|
1
|
-
type Noop = () => void;
|
|
2
1
|
type Observer<T> = {
|
|
3
2
|
id: string;
|
|
4
3
|
next: (value: T, subscriberId?: string) => void;
|
|
5
4
|
};
|
|
6
5
|
type Subscription = {
|
|
7
|
-
unsubscribe:
|
|
6
|
+
unsubscribe: () => void;
|
|
8
7
|
};
|
|
9
8
|
export type CacheableSubject<T> = {
|
|
10
|
-
subscribe: (
|
|
9
|
+
subscribe: (observer: Observer<T>) => Subscription;
|
|
11
10
|
} & Omit<Observer<T>, 'id'>;
|
|
12
11
|
export declare function createCacheableSubject<T>(): CacheableSubject<T>;
|
|
13
12
|
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
import type { Maybe, UseSelector, WithoutType } from '../../types/shared';
|
|
2
|
-
type CervelloStoreUseParam<StoreType> = {
|
|
3
|
-
onChange: (cb: (store: StoreType) => void) => void;
|
|
4
|
-
onPartialChange: <Attributes extends keyof WithoutType<StoreType, Function>, R extends Exclude<Attributes, '$value'>, ArrayOfAttributes extends Array<R>>(selectors: ArrayOfAttributes, cb: (store: StoreType) => void) => void;
|
|
5
|
-
};
|
|
6
|
-
/**
|
|
7
|
-
* Use function which allows you to listen for changes in the store.
|
|
8
|
-
*/
|
|
9
|
-
export type CervelloUseFunction<StoreType> = (param: CervelloStoreUseParam<StoreType>) => void;
|
|
10
|
-
declare type Prettify<T> = {} & {
|
|
11
|
-
[K in keyof T]: T[K];
|
|
12
|
-
};
|
|
13
|
-
type CervelloStore<StoreType, StoreName extends string | undefined = undefined> = StoreName extends string ? Prettify<{
|
|
14
|
-
[K in `${StoreName}Store`]: StoreType;
|
|
15
|
-
} & {
|
|
16
|
-
[K in `use${Capitalize<StoreName>}Store`]: () => StoreType;
|
|
17
|
-
} & {
|
|
18
|
-
[K in `use${Capitalize<StoreName>}Selector`]: UseSelector<StoreType>;
|
|
19
|
-
} & {
|
|
20
|
-
[K in `reset${Capitalize<StoreName>}Store`]: () => void;
|
|
21
|
-
} & {
|
|
22
|
-
/** Functions to be attached to changes in a general way (tracking, loggers, ... etc) */
|
|
23
|
-
use: (...functions: Array<(useObj: CervelloStoreUseParam<StoreType>) => void>) => CervelloStore<StoreType, StoreName>;
|
|
24
|
-
}> : {
|
|
25
|
-
/** Reactive store */
|
|
26
|
-
store: StoreType;
|
|
27
|
-
/** Hook to react to all changes done to 'store' */
|
|
28
|
-
useStore: () => StoreType;
|
|
29
|
-
/** Hook to react to changes done to 'store' in all the attributes provided */
|
|
30
|
-
useSelector: UseSelector<StoreType>;
|
|
31
|
-
/** Resets the value to the initial value passed in */
|
|
32
|
-
reset: () => void;
|
|
33
|
-
/** Functions to be attached to changes in a general way (tracking, loggers, ... etc) */
|
|
34
|
-
use: (...functions: Array<(useObj: CervelloStoreUseParam<StoreType>) => void>) => CervelloStore<StoreType, StoreName>;
|
|
35
|
-
};
|
|
36
|
-
export type CervelloOptions<StoreName extends string | undefined = undefined> = {
|
|
37
|
-
name?: StoreName;
|
|
38
|
-
reactiveNestedObjects?: boolean;
|
|
39
|
-
};
|
|
40
|
-
/**
|
|
41
|
-
* Creates a store that is reactive and can be used inside and outside of React components.
|
|
42
|
-
* @param initialValue - Function which returns the default values for the store
|
|
43
|
-
*
|
|
44
|
-
* @returns \{ store, useStore, useSelector \} or `{ exampleStore, useExampleStore, useExampleSelector }` if name is provided in options with 'example' value
|
|
45
|
-
*/
|
|
46
|
-
export declare function cervello<T, StoreName extends string | undefined = undefined>(initialValue: () => T, options?: CervelloOptions<StoreName>): Prettify<CervelloStore<Prettify<T & {
|
|
47
|
-
$value: Maybe<T>;
|
|
48
|
-
}>, StoreName>>;
|
|
49
|
-
/**
|
|
50
|
-
* Creates a store that is reactive and can be used inside and outside of React components.
|
|
51
|
-
* @param initialValue - Object with the default values for the store
|
|
52
|
-
*
|
|
53
|
-
* @returns - \{ store, useStore, useSelector \} or `{ exampleStore, useExampleStore, useExampleSelector }` if name is provided in options with 'example' value
|
|
54
|
-
*/
|
|
55
|
-
export declare function cervello<T extends Record<string, unknown>, StoreName extends string | undefined = undefined>(initialValue: T, options?: CervelloOptions<StoreName>): Prettify<CervelloStore<Prettify<T & {
|
|
56
|
-
$value: Maybe<T>;
|
|
57
|
-
}>, StoreName>>;
|
|
58
|
-
export {};
|