@cervello/react 5.0.0-beta.1 → 5.0.0-beta.11

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/README.md CHANGED
@@ -7,7 +7,7 @@
7
7
  <img src="https://github.com/chempogonzalez/cervello/blob/main/assets/emoji-logo.png" style="display:block;">
8
8
  </a>
9
9
 
10
- > 🤯 Simplest and truly reactive state manager for React _(just 1.5kb)_
10
+ > 🤯 Simple, reactive, tiny and performant state-management library for React _(just 1.5kb)_
11
11
 
12
12
  <br>
13
13
  <br>
@@ -22,10 +22,10 @@
22
22
 
23
23
  ## 🚀 **Features**
24
24
 
25
- - ⚛️ Truly reactive on store change like normal objects without functions **_(nested properties too 🚀!!)_**
26
- - ✅ Super simple and minimalistic API
27
- - 🐨 Listen properties lazily
28
- - 👌 No unnecessary re-renders
25
+ - ⚛️ Reactive with store object changes **_(nested properties too 🚀!!)_**
26
+ - ✅ Simple & minimalistic API
27
+ - 🚀 Batched updates and optimized re-renders
28
+ - 🐨 Lazy listen nested properties
29
29
  - 🔒 Immutable changes
30
30
  - 🔑 Typescript support
31
31
 
@@ -44,45 +44,46 @@ yarn add @cervello/react
44
44
 
45
45
  ## 💻 **Quick Usage**
46
46
 
47
- The `cervello` function allows you to create a new store in an easy way.
48
- Just set the initial value _`(the type will be inferred based on this value)`_ and you have it!
47
+ <!-- The `cervello` function allows you to create a new store in an easy way. -->
48
+ <!-- Just set the initial value _`(the type will be inferred based on this value)`_ and you have it! -->
49
+
50
+ It's **as simple as reassign a new value** to the store properties. <br/>It will notify all the components using `useStore` hook to re-render with the new value.
49
51
 
50
52
  ```ts
51
53
  // - store-example.ts
52
54
  import { cervello } from '@cervello/react'
53
55
 
54
56
  export const {
55
- store, // Reactive store object
56
- useStore, // Hook to listen for store changes
57
- useSelector, // Hook to listen for changes on parts of the store
57
+ store, // Object with reactive changes
58
+ useStore, // Hook to listen for store or partial store changes
58
59
  reset, // Function to reset the store to initial value
59
60
  } = cervello({
60
- count: 0,
61
- isModalOpen: false,
62
- /* ... */
61
+ fullName: 'Cervello Store',
62
+ address: {
63
+ city: 'Huelva',
64
+ /* ... */
65
+ },
63
66
  })
64
67
 
65
68
 
66
- // With the store object you can use it outside of React components
67
- const increment = () => { store.count++ }
69
+ // Change value from anywhere
70
+ store.address.city = 'Sevilla'
68
71
 
69
72
 
70
- const Button = () => {
71
- const { count } = useStore() // Listen for changes on the whole store
72
- return (
73
- <button onClick={increment}>
74
- {count}
75
- </button>
76
- )
73
+ // Listen for changes from components
74
+ function Address() {
75
+ const { address } = useStore()
76
+ return (<p>City: {address.city}</p>)
77
77
  }
78
78
 
79
- const ButtonWithSelector = () => {
80
- const { count } = useSelector(['count']) // Listen for changes just on 'count' property
81
- return (
82
- <button onClick={increment}>
83
- {count}
84
- </button>
85
- )
79
+
80
+ // Just listen for changes in the `city` property
81
+ const AddressWithSelector = () => {
82
+ const { address } = useStore({
83
+ select: ['address.city']
84
+ })
85
+
86
+ return (<p>City: {address.city}</p>)
86
87
  }
87
88
  ```
88
89
 
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 r(e)}):(Object.entries(e).forEach(function(e){n[e[0]]=r(e[1])}),Object.getOwnPropertySymbols(e).forEach(function(t){n[t]=r(e[t])})),n}var u=function(e){return null!==e&&"object"==typeof e&&!Array.isArray(e)};"hasOwn"in Object||(Object.hasOwn=Object.call.bind(Object.hasOwnProperty));var o=Symbol("value");function i(a,l,c){var f,s;void 0===c&&(c={});var h=null!=(f=c.nestedFieldPath)?f:"root",v=((s={})[o]=l,s),b="root"===h?Object.fromEntries(Object.entries(l).filter(function(e){return"function"==typeof e[1]})):{};return new Proxy(v,{get:function(t,l,f){if("_$fieldPath"===l)return h;var s=Object.hasOwn(t,o)?t[o]:t;if("toJSON"===l)return function(){return s};if("$value"===l)return r(s);var v,b=Reflect.get(s,l,f);if("symbol"==typeof l)return b;if("function"==typeof b)return b.bind(f);if(u(v=b)&&!e.isValidElement(v)&&!v[n]){var y,g=h+"."+l;if(b._$fieldPath===g)return b;var p=i(a,b,{nestedFieldPath:g,parentObjectToProxify:null!=(y=c.parentObjectToProxify)?y:s,beforeChange:c.beforeChange,afterChange:c.afterChange});return s[l]=p}return b},set:function(r,i,l,f){var s,v;if("symbol"==typeof i)return!0;var y=l,g=Object.hasOwn(r,o);if(g&&"$value"===i){var p=r[o];return y===p||JSON.stringify(y)===JSON.stringify(r[o])||("root"!==h?r[o]=y:(r[o]=t({},b,y),a.next({storeValue:r[o],change:{fieldPath:"root",newValue:y,previousValue:p}}))),!0}var O=g?r[o]:r,d=Reflect.get(O,i,f);if(d===y)return!0;u(y)&&!e.isValidElement(y)&&!y[n]&&d._$fieldPath?d.$value=y:Reflect.set(O,i,y,O);var P={storeValue:null!=(s=null==(v=c)?void 0:v.parentObjectToProxify)?s:O,change:{fieldPath:(h+"."+i).replace("root.",""),newValue:y,previousValue:d}};return a.next(P),null==c.afterChange||c.afterChange([P]),!0},has:function(e,n){return Reflect.has(e[o],n)},ownKeys:function(e){return Reflect.ownKeys(e[o])},getOwnPropertyDescriptor:function(e,n){return Reflect.getOwnPropertyDescriptor(e[o],n)}})}exports.cervello=function(n,t){var u=null!=t?t:{},o=u.beforeChange,a=u.afterChange,l=r(n),c=function(e,n){void 0===n&&(n=!1);var t=!1,r=[],u=[],o=e;return{getValue:function(){return o},next:function(e){o=e,r.push(e),t||(t=!0,Promise.resolve().then(function(){u.forEach(function(e){e.next(r)}),r=[],t=!1}))},subscribe:function(e){return n&&e.next(o),u.push(e),{unsubscribe:function(){u=u.filter(function(n){return n!==e})}}},unSubscribeAll:function(){u=[]}}}(l),f=i(c,l,{beforeChange:o,afterChange:a});return{store:f,reset:function(){f.$value=r(n)},useStore:function(n){var t,r,u=null==n||null==(t=n.initialValue)?void 0:t.apply(f,[f.$value]),o=e.useRef(!1);!o.current&&u&&u!==f&&(o.current=!0,f.$value=u);var i=e.useRef(null!=(r="function"==typeof(null==n?void 0:n.select)?null==n||null==n.select?void 0:n.select():null==n?void 0:n.select)?r:[]),a=e.useRef(i.current.filter(function(e){return e.includes(".*")}).map(function(e){return e.replace(".*","")}));return e.useLayoutEffect(function(){null!=n&&n.setValueOnMount&&n.setValueOnMount(f.$value).then(function(e){f.$value=e}).catch(function(e){console.error("Error setting initial value on mount",e)})},[]),e.useSyncExternalStore(function(e){var t=c.subscribe({next:function(t){var r=Array.isArray(t)?t:[t];if(null==n||!n.select)return e(),void(null==n||null==n.onChange||n.onChange(r));r.some(function(e){return"root"===e.change.fieldPath||i.current.includes(e.change.fieldPath)||a.current.find(function(n){return e.change.fieldPath.startsWith(n)})})&&(e(),null==n||null==n.onChange||n.onChange(r))}});return function(){t.unsubscribe()}},function(){return c.getValue()},function(){return c.getValue()}),f}}};
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)}var r=function(e){return null!==e&&"object"==typeof e&&!Array.isArray(e)};"hasOwn"in Object||(Object.hasOwn=Object.call.bind(Object.hasOwnProperty));var u=Symbol("value");function o(a,i,l){var c,f;void 0===l&&(l={});var s=null!=(c=l.nestedFieldPath)?c:"root",v=((f={})[u]=i,f),h="root"===s?Object.fromEntries(Object.entries(i).filter(function(e){return"function"==typeof e[1]})):{};return new Proxy(v,{get:function(t,i,c){if("_$fieldPath"===i)return s;var f=Object.hasOwn(t,u)?t[u]:t;if("toJSON"===i)return function(){return e=f,n=new WeakSet,function e(t){if(t&&"object"==typeof t){if(n.has(t))return null;if(n.add(t),Array.isArray(t))return t.map(e);var r={};for(var u in t)Object.prototype.hasOwnProperty.call(t,u)&&(r[u]=e(t[u]));return r}return t}(e);var e,n};if("$value"===i)return f;var v,h=Reflect.get(f,i,c);if("symbol"==typeof i)return h;if("function"==typeof h)return h.bind(c);if(r(v=h)&&!e.isValidElement(v)&&!v[n]&&h!==f){var b,p=s+"."+i;if(h._$fieldPath===p)return h;var y=o(a,h,{nestedFieldPath:p,parentObjectToProxify:null!=(b=l.parentObjectToProxify)?b:f,afterChange:l.afterChange});return f[i]=y}return h},set:function(o,i,c,f){var v,b;if("symbol"==typeof i)return!0;var p=c,y=Object.hasOwn(o,u);if(y&&"$$value"===i)return o[u]=p,!0;if(y&&"$value"===i){var O=o[u];return p===O||JSON.stringify(p)===JSON.stringify(o[u])||("root"!==s?o[u]=p:(o[u]=t({},h,p),a.next({storeValue:o[u],change:{fieldPath:"root",newValue:p,previousValue:O}}))),!0}var g=y?o[u]:o,d=Reflect.get(g,i,f);if(d===p)return!0;r(p)&&!e.isValidElement(p)&&!p[n]&&null!=d&&d._$fieldPath?d.$value=p:Reflect.set(g,i,p,g);var j={storeValue:null!=(v=null==(b=l)?void 0:b.parentObjectToProxify)?v:g,change:{fieldPath:(s+"."+i).replace("root.",""),newValue:p,previousValue:d}};return a.next(j),null==l.afterChange||l.afterChange([j]),!0},has:function(e,n){return Reflect.has(e[u],n)},ownKeys:function(e){return Reflect.ownKeys(e[u])},getOwnPropertyDescriptor:function(e,n){return Reflect.getOwnPropertyDescriptor(e[u],n)}})}exports.cervello=function(n,t){var r=(null!=t?t:{}).afterChange,u=n,a=function(e,n){void 0===n&&(n=!1);var t=!1,r=[],u=[],o=e;return{getValue:function(){return o},next:function(e){o=e,r.push(e),t||(t=!0,Promise.resolve().then(function(){u.forEach(function(e){e.next(r)}),r=[],t=!1}))},subscribe:function(e){return n&&e.next(o),u.push(e),{unsubscribe:function(){u=u.filter(function(n){return n!==e})}}},unSubscribeAll:function(){u=[]}}}(u),i=o(a,u,{afterChange:r});return{store:i,reset:function(){i.$value=function(e){var n=[],t=[],r=new Map;r.set(Date,function(e){return new Date(e)}),r.set(Map,function(e,n){return new Map(o(Array.from(e),n))}),r.set(Set,function(e,n){return new Set(o(Array.from(e),n))});var u=null;return function e(a){if("object"!=typeof a||null===a)return a;if(Array.isArray(a))return o(a,e);if(a.constructor!==Object&&(u=r.get(a.constructor)))return u(a,e);var i={};for(var l in n.push(a),t.push(i),Object.getOwnPropertySymbols(a).forEach(function(e){i[e]=a[e]}),a)if(Object.hasOwnProperty.call(a,l)){var c=a[l];if("object"!=typeof c||null===c)i[l]=c;else if(c.constructor!==Object&&(u=r.get(c.constructor)))i[l]=u(c,e);else{var f=n.indexOf(c);i[l]=-1!==f?t[f]:e(c)}}return n.pop(),t.pop(),i}(e);function o(e,o){for(var a=Object.keys(e),i=new Array(a.length),l=0;l<a.length;l++){var c=a[l],f=e[c];if("object"!=typeof f||null===f)i[c]=f;else if(f.constructor!==Object&&(u=r.get(f.constructor)))i[c]=u(f,o);else{var s=n.indexOf(f);i[c]=-1!==s?t[s]:o(f)}}return i}}(n)},useStore:function(n){var t,r=null==n||null==n.initialValue?void 0:n.initialValue(i.$value),u=e.useRef(!1);!u.current&&r&&r!==i&&(u.current=!0,i.$$value=r);var o=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:[]),l=e.useRef(o.current.filter(function(e){return e.includes(".*")}).map(function(e){return e.replace(".*","")}));return e.useLayoutEffect(function(){null!=n&&n.setValueOnMount&&n.setValueOnMount(i.$value).then(function(e){i.$value=e}).catch(function(e){console.error("Error setting initial value on mount",e)})},[]),e.useSyncExternalStore(function(e){var t=a.subscribe({next:function(t){var r=Array.isArray(t)?t:[t];if(null==n||!n.select)return e(),void(null==n||null==n.onChange||n.onChange(r));r.some(function(e){return"root"===e.change.fieldPath||o.current.includes(e.change.fieldPath)||l.current.find(function(n){return e.change.fieldPath.startsWith(n)})})&&(e(),null==n||null==n.onChange||n.onChange(r))}});return function(){t.unsubscribe()}},function(){return a.getValue()},function(){return a.getValue()}),i}}},exports.nonReactive=function(e){return Object.defineProperty(e,n,{value:!0,enumerable:!1,writable:!1,configurable:!1}),e};
2
2
  //# sourceMappingURL=cervello.cjs.map
@@ -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","import { 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 if (Array.isArray(obj)) {\n newObj = obj.map(item => deepClone(item))\n } else {\n Object.entries(obj).forEach(([key, value]) => {\n newObj[key] = deepClone(value)\n })\n Object.getOwnPropertySymbols(obj).forEach(symbol => {\n newObj[symbol] = deepClone((obj as any)[symbol])\n })\n }\n return newObj as T\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\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 return acc\n }, {})\n}\n\n\n\nconst stringify = (obj: any): string => JSON.stringify(obj)\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","import { isValidElement } from 'react'\n\nimport { nonReactiveObjectSymbol } from '../../types/shared'\nimport { deepClone, isObject } 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// const FIELD_PATH = Symbol('field-path')\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 const objectWithRootValue = {\n [ROOT_VALUE]: objectToProxify,\n // [FIELD_PATH]: fieldPath,\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\n // console.log(' - value proxify -> () >', { fieldPath, objectToProxify, objectWithRootValue })\n\n return new Proxy(objectWithRootValue, {\n get (targetObject, propName, receiver) {\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 // console.log(' - value get -> () >', { propName, targetObject, target })\n\n if (propName === 'toJSON') return () => target\n\n if (propName === '$value') return deepClone(target)\n\n const propertyValue = Reflect.get(target, propName, receiver)\n\n if (typeof propName === 'symbol') return propertyValue\n\n\n if (typeof propertyValue === 'function')\n return (propertyValue as () => any).bind(receiver)\n\n\n if (isRactiveValidObject(propertyValue)) {\n const newNestedFieldPath = `${fieldPath}.${propName}`\n\n\n if (propertyValue._$fieldPath === newNestedFieldPath) return propertyValue\n\n const proxiedNestedObject = proxifyStore(\n store$$ as any,\n propertyValue,\n {\n nestedFieldPath: newNestedFieldPath,\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 value = opts.beforeChange\n // ? opts.beforeChange({\n // change: {\n // fieldPath: `${fieldPath}.${propName}`,\n // newValue,\n // previousValue: Reflect.get(receiver, propName, receiver),\n // },\n // storeValue: targetObject[ROOT_VALUE],\n // }) ?? newValue\n // : newValue\n\n // console.log(' - value set -> () >', { propName, value, targetObject })\n const isRootTarget = Object.hasOwn(parentObject, ROOT_VALUE)\n\n if (isRootTarget && key === '$value') {\n const previousValue = parentObject[ROOT_VALUE]\n\n if (value === previousValue) return true\n if (JSON.stringify(value) === JSON.stringify(parentObject[ROOT_VALUE])) 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)\n 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 (isObject(value) && !isValidElement(value) && !value[nonReactiveObjectSymbol] && 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\nfunction isRactiveValidObject <T extends Record<string, any>> (value: T): boolean {\n return isObject(value) && !isValidElement(value) && !(value as any)[nonReactiveObjectSymbol]\n}\n","\nimport { useLayoutEffect, useRef, useSyncExternalStore } 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\nexport 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 CervelloUseStoreOptions<StoreValue extends Record<string, any>> = {\n initialValue?: (currentStore: StoreValue) => StoreValue,\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 StoreValueMutable<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: StoreValueMutable<StoreValue>,\n reset: () => void,\n useStore: (options?: CervelloUseStoreOptions<StoreValue>) => StoreValueMutable<StoreValue>\n } {\n const {\n beforeChange,\n afterChange,\n } = options ?? {}\n\n const clonedInitialValue = deepClone(initialValue)\n const store$$ = createCacheableSubject<StoreChange<StoreValue>>(clonedInitialValue as any)\n\n const proxiedStore = proxifyStore(\n store$$ as any,\n clonedInitialValue,\n { beforeChange, afterChange },\n ) as StoreValueMutable<StoreValue>\n\n\n return {\n store: proxiedStore,\n reset: () => {\n proxiedStore.$value = deepClone(initialValue)\n },\n useStore: (options) => {\n const initialValue = options?.initialValue?.apply(proxiedStore, [proxiedStore.$value])\n const initialValueSet = useRef(false)\n\n if (!initialValueSet.current && initialValue && initialValue !== proxiedStore) {\n initialValueSet.current = true\n proxiedStore.$value = initialValue\n }\n\n const selectFieldPaths = useRef(\n (typeof options?.select === 'function'\n ? options?.select?.() // .map(fp => `root.${fp}`)\n : options?.select) // ?.map(fp => `root.${fp}`))\n ?? [],\n )\n\n const selectedFieldPathsForNestedObjects = useRef(\n selectFieldPaths.current\n .filter(fp => fp.includes('.*'))\n .map(fp => fp.replace('.*', '')),\n )\n\n\n useLayoutEffect(() => {\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 useSyncExternalStore(\n (onStoreChange) => {\n const subscription = store$$.subscribe({\n next: (sc) => {\n const storeChanges = Array.isArray(sc)\n ? sc as Array<StoreChange<StoreValue>>\n : [sc]\n\n if (!options?.select) {\n onStoreChange()\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\n .find(fp => nextChange.change.fieldPath.startsWith(fp)),\n )) {\n onStoreChange()\n options?.onChange?.(storeChanges)\n }\n },\n })\n\n return () => {\n subscription.unsubscribe()\n }\n },\n () => store$$.getValue(),\n () => store$$.getValue(),\n )\n\n return proxiedStore\n },\n }\n}\n","\nexport type Noop = () => void\n\n\nexport type Observer<T> = {\n next: (value: T) => void\n}\n\nexport type Subscription = {\n unsubscribe: Noop\n}\n\nexport type CacheableSubject<T> = {\n getValue: () => T\n subscribe: (value: Observer<T>) => Subscription\n unSubscribeAll: Noop\n} & Observer<T>\n\n\nconst WITH_FLUSHING = true\n\nexport function createCacheableSubject<T> (defaultValue: T, getValueOnSubscribe = false): CacheableSubject<T> {\n let isFlushing = false\n let itemsToFlush: Array<T> = []\n\n let observerList: Array<Observer<T>> = []\n let value = defaultValue\n\n const getValue = (): T => value\n\n const next = (newValue: T): void => {\n value = newValue\n\n if (!WITH_FLUSHING) {\n observerList.forEach((o) => { o.next(newValue) })\n\n return\n }\n\n itemsToFlush.push(newValue)\n // observerList.forEach((o) => { o.next(newValue) })\n\n if (!isFlushing) {\n isFlushing = true\n void Promise.resolve().then(() => {\n observerList.forEach((o) => { o.next(itemsToFlush as T) })\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 // 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\n"],"names":["nonReactiveObjectSymbol","Symbol","deepClone","obj","newObj","Array","isArray","map","item","Object","entries","forEach","_ref","getOwnPropertySymbols","symbol","isObject","hasOwn","call","bind","hasOwnProperty","ROOT_VALUE","store$$","objectToProxify","opts","fieldPath","nestedFieldPath","_opts$nestedFieldPath","objectWithRootValue","_objectWithRootValue","rootFunctions","fromEntries","filter","Proxy","get","targetObject","propName","receiver","target","value","propertyValue","Reflect","isValidElement","_opts$parentObjectToP","_$fieldPath","newNestedFieldPath","proxiedNestedObject","proxifyStore","parentObjectToProxify","beforeChange","afterChange","set","parentObject","key","newValue","_opts$parentObjectToP2","_opts","isRootTarget","previousValue","JSON","stringify","next","storeValue","change","realInnerObject","$value","nextStoreChange","replace","has","t","p","ownKeys","getOwnPropertyDescriptor","initialValue","options","clonedInitialValue","createCacheableSubject","defaultValue","getValueOnSubscribe","isFlushing","observerList","getValue","itemsToFlush","push","resolve","then","o","subscribe","observer","unsubscribe","unSubscribeAll","proxiedStore","store","reset","useStore","_options$initialValue","_ref2","apply","initialValueSet","useRef","current","selectFieldPaths","select","selectedFieldPathsForNestedObjects","fp","includes","useLayoutEffect","setValueOnMount","err","console","error","useSyncExternalStore","onStoreChange","subscription","sc","storeChanges","onChange","some","nextChange","find","startsWith"],"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/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 { 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 deepClone2 <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 // eslint-disable-next-line no-prototype-builtins\n } else if (!obj.hasOwnProperty('$$typeof')) {\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 deepClone <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\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","import { isValidElement } from 'react'\n\nimport { nonReactiveObjectSymbol } from '../../types/shared'\nimport { isObject } 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 if (propName === '_$fieldPath') return fieldPath\n\n const isRootTarget = Object.hasOwn(targetObject, ROOT_VALUE)\n const target = isRootTarget ? targetObject[ROOT_VALUE] : targetObject\n\n if (propName === 'toJSON') {\n return () => {\n // Remove circular references before stringifying\n // to prevent JSON.stringify from failing\n return removeCircularReferences(target)\n }\n }\n\n if (propName === '$value') {\n // return deepClone(target)\n // return getUnproxiedObject(target)\n return target\n }\n\n const propertyValue = Reflect.get(target, propName, receiver)\n\n if (typeof propName === 'symbol') return propertyValue\n\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\n if (propertyValue._$fieldPath === newNestedFieldPath) return propertyValue\n\n const proxiedNestedObject = proxifyStore(\n store$$ as any,\n propertyValue,\n {\n nestedFieldPath: newNestedFieldPath,\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 // This is used to set the value of the store without notifying the store\n if (isRootTarget && key === '$$value') {\n (parentObject as any)[ROOT_VALUE] = value\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(value) === JSON.stringify(parentObject[ROOT_VALUE])) 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 (isObject(value) && !isValidElement(value) && !value[nonReactiveObjectSymbol] && 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 getUnproxiedObject (obj: any): any {\n// if (obj && typeof obj === 'object') {\n// if (obj[ROOT_VALUE]?.[ROOT_VALUE]) return '[Circular reference]'\n//\n// // Check if the object is a proxy\n// if (obj[ROOT_VALUE])\n// return getUnproxiedObject(obj[ROOT_VALUE])\n//\n//\n// // If it's not a proxy, return the object itself\n// return obj\n// }\n//\n// // If it's not an object, return it as is\n// return obj\n// }\n\n\n\nfunction isValidReactiveObject <T extends Record<string, any>> (value: T): boolean {\n return isObject(value) && !isValidElement(value) && !(value as any)[nonReactiveObjectSymbol]\n}\n\n\nfunction 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 result[key] = traverse(value[key])\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 { useLayoutEffect, useRef, useSyncExternalStore } 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,\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 clonedInitialValue = (initialValue)\n const store$$ = createCacheableSubject<StoreChange<StoreValue>>(clonedInitialValue as any)\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 initialValue = options?.initialValue?.(proxiedStore.$value)\n const isInitialValueSet = useRef(false)\n\n if (!isInitialValueSet.current && initialValue && initialValue !== proxiedStore) {\n isInitialValueSet.current = true;\n (proxiedStore as any).$$value = initialValue\n }\n\n const selectFieldPaths = useRef(\n (typeof options?.select === 'function'\n ? options?.select?.()\n : options?.select)\n ?? [],\n )\n\n const selectedFieldPathsForNestedObjects = useRef(\n selectFieldPaths.current\n .filter(fp => fp.includes('.*'))\n .map(fp => fp.replace('.*', '')),\n )\n\n\n useLayoutEffect(() => {\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 useSyncExternalStore(\n (onStoreChange) => {\n const subscription = store$$.subscribe({\n next: (sc) => {\n const storeChanges = Array.isArray(sc)\n ? sc as Array<StoreChange<StoreValue>>\n : [sc]\n\n if (!options?.select) {\n onStoreChange()\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 onStoreChange()\n options?.onChange?.(storeChanges)\n }\n },\n })\n\n return () => {\n subscription.unsubscribe()\n }\n },\n () => store$$.getValue(),\n () => store$$.getValue(),\n )\n\n return proxiedStore\n },\n }\n}\n","\nexport type Noop = () => void\n\n\nexport type Observer<T> = {\n next: (value: T) => void\n}\n\nexport type Subscription = {\n unsubscribe: Noop\n}\n\nexport type CacheableSubject<T> = {\n getValue: () => T\n subscribe: (value: Observer<T>) => Subscription\n unSubscribeAll: Noop\n} & Observer<T>\n\n\nconst WITH_FLUSHING = true\n\nexport function createCacheableSubject<T> (defaultValue: T, getValueOnSubscribe = false): CacheableSubject<T> {\n let isFlushing = false\n let itemsToFlush: Array<T> = []\n\n let observerList: Array<Observer<T>> = []\n let value = defaultValue\n\n const getValue = (): T => value\n\n const next = (newValue: T): void => {\n value = newValue\n\n if (!WITH_FLUSHING) {\n observerList.forEach((o) => { o.next(newValue) })\n\n return\n }\n\n itemsToFlush.push(newValue)\n // observerList.forEach((o) => { o.next(newValue) })\n\n if (!isFlushing) {\n isFlushing = true\n void Promise.resolve().then(() => {\n observerList.forEach((o) => { o.next(itemsToFlush as T) })\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 // 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\n"],"names":["nonReactiveObjectSymbol","Symbol","obj","Array","isArray","Object","hasOwn","call","bind","hasOwnProperty","ROOT_VALUE","proxifyStore","store$$","objectToProxify","opts","_opts$nestedFieldPath","_objectWithRootValue","fieldPath","nestedFieldPath","objectWithRootValue","rootFunctions","fromEntries","entries","filter","v","Proxy","get","targetObject","propName","receiver","target","WeakSet","traverse","value","seen","has","add","map","result","prototype","key","propertyValue","Reflect","isObject","isValidElement","_opts$parentObjectToP","newNestedFieldPath","_$fieldPath","proxiedNestedObject","parentObjectToProxify","afterChange","set","parentObject","newValue","isRootTarget","previousValue","JSON","stringify","next","storeValue","change","realInnerObject","$value","_opts","replace","nextStoreChange","t","p","ownKeys","getOwnPropertyDescriptor","initialValue","options","clonedInitialValue","createCacheableSubject","defaultValue","getValueOnSubscribe","isFlushing","observerList","getValue","itemsToFlush","push","resolve","then","forEach","o","subscribe","observer","unsubscribe","unSubscribeAll","proxiedStore","store","reset","deepClone","refs","refsNew","constructorHandlers","Map","Date","fn","cloneArray","from","Set","clone","constructor","handler","o2","getOwnPropertySymbols","symbol","k","cur","i","indexOf","pop","a","keys","length","a2","index","useStore","_ref2","isInitialValueSet","useRef","current","$$value","selectFieldPaths","select","selectedFieldPathsForNestedObjects","fp","includes","useLayoutEffect","setValueOnMount","err","console","error","useSyncExternalStore","onStoreChange","subscription","sc","storeChanges","onChange","some","nextChange","find","startsWith","nonReactive","defineProperty","enumerable","writable","configurable"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import{isValidElement as e,useRef as n,useLayoutEffect as t,useSyncExternalStore as r}from"react";var u=Symbol("nonReactiveObject");function o(){return o=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},o.apply(this,arguments)}function i(e){if(!e||"object"!=typeof e)return e;var n={};return Array.isArray(e)?n=e.map(function(e){return i(e)}):(Object.entries(e).forEach(function(e){n[e[0]]=i(e[1])}),Object.getOwnPropertySymbols(e).forEach(function(t){n[t]=i(e[t])})),n}var a=function(e){return null!==e&&"object"==typeof e&&!Array.isArray(e)};"hasOwn"in Object||(Object.hasOwn=Object.call.bind(Object.hasOwnProperty));var l=Symbol("value");function c(n,t,r){var f,s;void 0===r&&(r={});var h=null!=(f=r.nestedFieldPath)?f:"root",v=((s={})[l]=t,s),b="root"===h?Object.fromEntries(Object.entries(t).filter(function(e){return"function"==typeof e[1]})):{};return new Proxy(v,{get:function(t,o,f){if("_$fieldPath"===o)return h;var s=Object.hasOwn(t,l)?t[l]:t;if("toJSON"===o)return function(){return s};if("$value"===o)return i(s);var v,b=Reflect.get(s,o,f);if("symbol"==typeof o)return b;if("function"==typeof b)return b.bind(f);if(a(v=b)&&!e(v)&&!v[u]){var g,y=h+"."+o;if(b._$fieldPath===y)return b;var p=c(n,b,{nestedFieldPath:y,parentObjectToProxify:null!=(g=r.parentObjectToProxify)?g:s,beforeChange:r.beforeChange,afterChange:r.afterChange});return s[o]=p}return b},set:function(t,i,c,f){var s,v;if("symbol"==typeof i)return!0;var g=c,y=Object.hasOwn(t,l);if(y&&"$value"===i){var p=t[l];return g===p||JSON.stringify(g)===JSON.stringify(t[l])||("root"!==h?t[l]=g:(t[l]=o({},b,g),n.next({storeValue:t[l],change:{fieldPath:"root",newValue:g,previousValue:p}}))),!0}var O=y?t[l]:t,d=Reflect.get(O,i,f);if(d===g)return!0;a(g)&&!e(g)&&!g[u]&&d._$fieldPath?d.$value=g:Reflect.set(O,i,g,O);var P={storeValue:null!=(s=null==(v=r)?void 0:v.parentObjectToProxify)?s:O,change:{fieldPath:(h+"."+i).replace("root.",""),newValue:g,previousValue:d}};return n.next(P),null==r.afterChange||r.afterChange([P]),!0},has:function(e,n){return Reflect.has(e[l],n)},ownKeys:function(e){return Reflect.ownKeys(e[l])},getOwnPropertyDescriptor:function(e,n){return Reflect.getOwnPropertyDescriptor(e[l],n)}})}function f(e,u){var o=null!=u?u:{},a=o.beforeChange,l=o.afterChange,f=i(e),s=function(e,n){void 0===n&&(n=!1);var t=!1,r=[],u=[],o=e;return{getValue:function(){return o},next:function(e){o=e,r.push(e),t||(t=!0,Promise.resolve().then(function(){u.forEach(function(e){e.next(r)}),r=[],t=!1}))},subscribe:function(e){return n&&e.next(o),u.push(e),{unsubscribe:function(){u=u.filter(function(n){return n!==e})}}},unSubscribeAll:function(){u=[]}}}(f),h=c(s,f,{beforeChange:a,afterChange:l});return{store:h,reset:function(){h.$value=i(e)},useStore:function(e){var u,o,i=null==e||null==(u=e.initialValue)?void 0:u.apply(h,[h.$value]),a=n(!1);!a.current&&i&&i!==h&&(a.current=!0,h.$value=i);var l=n(null!=(o="function"==typeof(null==e?void 0:e.select)?null==e||null==e.select?void 0:e.select():null==e?void 0:e.select)?o:[]),c=n(l.current.filter(function(e){return e.includes(".*")}).map(function(e){return e.replace(".*","")}));return t(function(){null!=e&&e.setValueOnMount&&e.setValueOnMount(h.$value).then(function(e){h.$value=e}).catch(function(e){console.error("Error setting initial value on mount",e)})},[]),r(function(n){var t=s.subscribe({next:function(t){var r=Array.isArray(t)?t:[t];if(null==e||!e.select)return n(),void(null==e||null==e.onChange||e.onChange(r));r.some(function(e){return"root"===e.change.fieldPath||l.current.includes(e.change.fieldPath)||c.current.find(function(n){return e.change.fieldPath.startsWith(n)})})&&(n(),null==e||null==e.onChange||e.onChange(r))}});return function(){t.unsubscribe()}},function(){return s.getValue()},function(){return s.getValue()}),h}}}export{f as cervello};
1
+ import{isValidElement as e,useRef as n,useLayoutEffect as t,useSyncExternalStore as r}from"react";var u=Symbol("nonReactiveObject");function o(){return o=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},o.apply(this,arguments)}var a=function(e){return null!==e&&"object"==typeof e&&!Array.isArray(e)};"hasOwn"in Object||(Object.hasOwn=Object.call.bind(Object.hasOwnProperty));var i=Symbol("value");function l(n,t,r){var c,f;void 0===r&&(r={});var s=null!=(c=r.nestedFieldPath)?c:"root",v=((f={})[i]=t,f),h="root"===s?Object.fromEntries(Object.entries(t).filter(function(e){return"function"==typeof e[1]})):{};return new Proxy(v,{get:function(t,o,c){if("_$fieldPath"===o)return s;var f=Object.hasOwn(t,i)?t[i]:t;if("toJSON"===o)return function(){return e=f,n=new WeakSet,function e(t){if(t&&"object"==typeof t){if(n.has(t))return null;if(n.add(t),Array.isArray(t))return t.map(e);var r={};for(var u in t)Object.prototype.hasOwnProperty.call(t,u)&&(r[u]=e(t[u]));return r}return t}(e);var e,n};if("$value"===o)return f;var v,h=Reflect.get(f,o,c);if("symbol"==typeof o)return h;if("function"==typeof h)return h.bind(c);if(a(v=h)&&!e(v)&&!v[u]&&h!==f){var b,p=s+"."+o;if(h._$fieldPath===p)return h;var y=l(n,h,{nestedFieldPath:p,parentObjectToProxify:null!=(b=r.parentObjectToProxify)?b:f,afterChange:r.afterChange});return f[o]=y}return h},set:function(t,l,c,f){var v,b;if("symbol"==typeof l)return!0;var p=c,y=Object.hasOwn(t,i);if(y&&"$$value"===l)return t[i]=p,!0;if(y&&"$value"===l){var O=t[i];return p===O||JSON.stringify(p)===JSON.stringify(t[i])||("root"!==s?t[i]=p:(t[i]=o({},h,p),n.next({storeValue:t[i],change:{fieldPath:"root",newValue:p,previousValue:O}}))),!0}var g=y?t[i]:t,d=Reflect.get(g,l,f);if(d===p)return!0;a(p)&&!e(p)&&!p[u]&&null!=d&&d._$fieldPath?d.$value=p:Reflect.set(g,l,p,g);var j={storeValue:null!=(v=null==(b=r)?void 0:b.parentObjectToProxify)?v:g,change:{fieldPath:(s+"."+l).replace("root.",""),newValue:p,previousValue:d}};return n.next(j),null==r.afterChange||r.afterChange([j]),!0},has:function(e,n){return Reflect.has(e[i],n)},ownKeys:function(e){return Reflect.ownKeys(e[i])},getOwnPropertyDescriptor:function(e,n){return Reflect.getOwnPropertyDescriptor(e[i],n)}})}function c(e){return Object.defineProperty(e,u,{value:!0,enumerable:!1,writable:!1,configurable:!1}),e}function f(e,u){var o=(null!=u?u:{}).afterChange,a=e,i=function(e,n){void 0===n&&(n=!1);var t=!1,r=[],u=[],o=e;return{getValue:function(){return o},next:function(e){o=e,r.push(e),t||(t=!0,Promise.resolve().then(function(){u.forEach(function(e){e.next(r)}),r=[],t=!1}))},subscribe:function(e){return n&&e.next(o),u.push(e),{unsubscribe:function(){u=u.filter(function(n){return n!==e})}}},unSubscribeAll:function(){u=[]}}}(a),c=l(i,a,{afterChange:o});return{store:c,reset:function(){c.$value=function(e){var n=[],t=[],r=new Map;r.set(Date,function(e){return new Date(e)}),r.set(Map,function(e,n){return new Map(o(Array.from(e),n))}),r.set(Set,function(e,n){return new Set(o(Array.from(e),n))});var u=null;return function e(a){if("object"!=typeof a||null===a)return a;if(Array.isArray(a))return o(a,e);if(a.constructor!==Object&&(u=r.get(a.constructor)))return u(a,e);var i={};for(var l in n.push(a),t.push(i),Object.getOwnPropertySymbols(a).forEach(function(e){i[e]=a[e]}),a)if(Object.hasOwnProperty.call(a,l)){var c=a[l];if("object"!=typeof c||null===c)i[l]=c;else if(c.constructor!==Object&&(u=r.get(c.constructor)))i[l]=u(c,e);else{var f=n.indexOf(c);i[l]=-1!==f?t[f]:e(c)}}return n.pop(),t.pop(),i}(e);function o(e,o){for(var a=Object.keys(e),i=new Array(a.length),l=0;l<a.length;l++){var c=a[l],f=e[c];if("object"!=typeof f||null===f)i[c]=f;else if(f.constructor!==Object&&(u=r.get(f.constructor)))i[c]=u(f,o);else{var s=n.indexOf(f);i[c]=-1!==s?t[s]:o(f)}}return i}}(e)},useStore:function(e){var u,o=null==e||null==e.initialValue?void 0:e.initialValue(c.$value),a=n(!1);!a.current&&o&&o!==c&&(a.current=!0,c.$$value=o);var l=n(null!=(u="function"==typeof(null==e?void 0:e.select)?null==e||null==e.select?void 0:e.select():null==e?void 0:e.select)?u:[]),f=n(l.current.filter(function(e){return e.includes(".*")}).map(function(e){return e.replace(".*","")}));return t(function(){null!=e&&e.setValueOnMount&&e.setValueOnMount(c.$value).then(function(e){c.$value=e}).catch(function(e){console.error("Error setting initial value on mount",e)})},[]),r(function(n){var t=i.subscribe({next:function(t){var r=Array.isArray(t)?t:[t];if(null==e||!e.select)return n(),void(null==e||null==e.onChange||e.onChange(r));r.some(function(e){return"root"===e.change.fieldPath||l.current.includes(e.change.fieldPath)||f.current.find(function(n){return e.change.fieldPath.startsWith(n)})})&&(n(),null==e||null==e.onChange||e.onChange(r))}});return function(){t.unsubscribe()}},function(){return i.getValue()},function(){return i.getValue()}),c}}}export{f as cervello,c as nonReactive};
2
2
  //# sourceMappingURL=cervello.esm.js.map
@@ -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","import { 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 if (Array.isArray(obj)) {\n newObj = obj.map(item => deepClone(item))\n } else {\n Object.entries(obj).forEach(([key, value]) => {\n newObj[key] = deepClone(value)\n })\n Object.getOwnPropertySymbols(obj).forEach(symbol => {\n newObj[symbol] = deepClone((obj as any)[symbol])\n })\n }\n return newObj as T\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\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 return acc\n }, {})\n}\n\n\n\nconst stringify = (obj: any): string => JSON.stringify(obj)\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","import { isValidElement } from 'react'\n\nimport { nonReactiveObjectSymbol } from '../../types/shared'\nimport { deepClone, isObject } 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// const FIELD_PATH = Symbol('field-path')\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 const objectWithRootValue = {\n [ROOT_VALUE]: objectToProxify,\n // [FIELD_PATH]: fieldPath,\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\n // console.log(' - value proxify -> () >', { fieldPath, objectToProxify, objectWithRootValue })\n\n return new Proxy(objectWithRootValue, {\n get (targetObject, propName, receiver) {\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 // console.log(' - value get -> () >', { propName, targetObject, target })\n\n if (propName === 'toJSON') return () => target\n\n if (propName === '$value') return deepClone(target)\n\n const propertyValue = Reflect.get(target, propName, receiver)\n\n if (typeof propName === 'symbol') return propertyValue\n\n\n if (typeof propertyValue === 'function')\n return (propertyValue as () => any).bind(receiver)\n\n\n if (isRactiveValidObject(propertyValue)) {\n const newNestedFieldPath = `${fieldPath}.${propName}`\n\n\n if (propertyValue._$fieldPath === newNestedFieldPath) return propertyValue\n\n const proxiedNestedObject = proxifyStore(\n store$$ as any,\n propertyValue,\n {\n nestedFieldPath: newNestedFieldPath,\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 value = opts.beforeChange\n // ? opts.beforeChange({\n // change: {\n // fieldPath: `${fieldPath}.${propName}`,\n // newValue,\n // previousValue: Reflect.get(receiver, propName, receiver),\n // },\n // storeValue: targetObject[ROOT_VALUE],\n // }) ?? newValue\n // : newValue\n\n // console.log(' - value set -> () >', { propName, value, targetObject })\n const isRootTarget = Object.hasOwn(parentObject, ROOT_VALUE)\n\n if (isRootTarget && key === '$value') {\n const previousValue = parentObject[ROOT_VALUE]\n\n if (value === previousValue) return true\n if (JSON.stringify(value) === JSON.stringify(parentObject[ROOT_VALUE])) 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)\n 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 (isObject(value) && !isValidElement(value) && !value[nonReactiveObjectSymbol] && 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\nfunction isRactiveValidObject <T extends Record<string, any>> (value: T): boolean {\n return isObject(value) && !isValidElement(value) && !(value as any)[nonReactiveObjectSymbol]\n}\n","\nimport { useLayoutEffect, useRef, useSyncExternalStore } 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\nexport 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 CervelloUseStoreOptions<StoreValue extends Record<string, any>> = {\n initialValue?: (currentStore: StoreValue) => StoreValue,\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 StoreValueMutable<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: StoreValueMutable<StoreValue>,\n reset: () => void,\n useStore: (options?: CervelloUseStoreOptions<StoreValue>) => StoreValueMutable<StoreValue>\n } {\n const {\n beforeChange,\n afterChange,\n } = options ?? {}\n\n const clonedInitialValue = deepClone(initialValue)\n const store$$ = createCacheableSubject<StoreChange<StoreValue>>(clonedInitialValue as any)\n\n const proxiedStore = proxifyStore(\n store$$ as any,\n clonedInitialValue,\n { beforeChange, afterChange },\n ) as StoreValueMutable<StoreValue>\n\n\n return {\n store: proxiedStore,\n reset: () => {\n proxiedStore.$value = deepClone(initialValue)\n },\n useStore: (options) => {\n const initialValue = options?.initialValue?.apply(proxiedStore, [proxiedStore.$value])\n const initialValueSet = useRef(false)\n\n if (!initialValueSet.current && initialValue && initialValue !== proxiedStore) {\n initialValueSet.current = true\n proxiedStore.$value = initialValue\n }\n\n const selectFieldPaths = useRef(\n (typeof options?.select === 'function'\n ? options?.select?.() // .map(fp => `root.${fp}`)\n : options?.select) // ?.map(fp => `root.${fp}`))\n ?? [],\n )\n\n const selectedFieldPathsForNestedObjects = useRef(\n selectFieldPaths.current\n .filter(fp => fp.includes('.*'))\n .map(fp => fp.replace('.*', '')),\n )\n\n\n useLayoutEffect(() => {\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 useSyncExternalStore(\n (onStoreChange) => {\n const subscription = store$$.subscribe({\n next: (sc) => {\n const storeChanges = Array.isArray(sc)\n ? sc as Array<StoreChange<StoreValue>>\n : [sc]\n\n if (!options?.select) {\n onStoreChange()\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\n .find(fp => nextChange.change.fieldPath.startsWith(fp)),\n )) {\n onStoreChange()\n options?.onChange?.(storeChanges)\n }\n },\n })\n\n return () => {\n subscription.unsubscribe()\n }\n },\n () => store$$.getValue(),\n () => store$$.getValue(),\n )\n\n return proxiedStore\n },\n }\n}\n","\nexport type Noop = () => void\n\n\nexport type Observer<T> = {\n next: (value: T) => void\n}\n\nexport type Subscription = {\n unsubscribe: Noop\n}\n\nexport type CacheableSubject<T> = {\n getValue: () => T\n subscribe: (value: Observer<T>) => Subscription\n unSubscribeAll: Noop\n} & Observer<T>\n\n\nconst WITH_FLUSHING = true\n\nexport function createCacheableSubject<T> (defaultValue: T, getValueOnSubscribe = false): CacheableSubject<T> {\n let isFlushing = false\n let itemsToFlush: Array<T> = []\n\n let observerList: Array<Observer<T>> = []\n let value = defaultValue\n\n const getValue = (): T => value\n\n const next = (newValue: T): void => {\n value = newValue\n\n if (!WITH_FLUSHING) {\n observerList.forEach((o) => { o.next(newValue) })\n\n return\n }\n\n itemsToFlush.push(newValue)\n // observerList.forEach((o) => { o.next(newValue) })\n\n if (!isFlushing) {\n isFlushing = true\n void Promise.resolve().then(() => {\n observerList.forEach((o) => { o.next(itemsToFlush as T) })\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 // 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\n"],"names":["nonReactiveObjectSymbol","Symbol","deepClone","obj","newObj","Array","isArray","map","item","Object","entries","forEach","_ref","getOwnPropertySymbols","symbol","isObject","hasOwn","call","bind","hasOwnProperty","ROOT_VALUE","store$$","objectToProxify","opts","fieldPath","nestedFieldPath","_opts$nestedFieldPath","objectWithRootValue","_objectWithRootValue","rootFunctions","fromEntries","filter","Proxy","get","targetObject","propName","receiver","target","value","propertyValue","Reflect","isValidElement","_opts$parentObjectToP","_$fieldPath","newNestedFieldPath","proxiedNestedObject","proxifyStore","parentObjectToProxify","beforeChange","afterChange","set","parentObject","key","newValue","_opts$parentObjectToP2","_opts","isRootTarget","previousValue","JSON","stringify","next","storeValue","change","realInnerObject","$value","nextStoreChange","replace","has","t","p","ownKeys","getOwnPropertyDescriptor","cervello","initialValue","options","clonedInitialValue","createCacheableSubject","defaultValue","getValueOnSubscribe","isFlushing","observerList","getValue","itemsToFlush","push","resolve","then","o","subscribe","observer","unsubscribe","unSubscribeAll","proxiedStore","store","reset","useStore","_options$initialValue","_ref2","apply","initialValueSet","useRef","current","selectFieldPaths","select","selectedFieldPathsForNestedObjects","fp","includes","useLayoutEffect","setValueOnMount","err","console","error","useSyncExternalStore","onStoreChange","subscription","sc","storeChanges","onChange","some","nextChange","find","startsWith"],"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/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 { 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 deepClone2 <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 // eslint-disable-next-line no-prototype-builtins\n } else if (!obj.hasOwnProperty('$$typeof')) {\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 deepClone <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\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","import { isValidElement } from 'react'\n\nimport { nonReactiveObjectSymbol } from '../../types/shared'\nimport { isObject } 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 if (propName === '_$fieldPath') return fieldPath\n\n const isRootTarget = Object.hasOwn(targetObject, ROOT_VALUE)\n const target = isRootTarget ? targetObject[ROOT_VALUE] : targetObject\n\n if (propName === 'toJSON') {\n return () => {\n // Remove circular references before stringifying\n // to prevent JSON.stringify from failing\n return removeCircularReferences(target)\n }\n }\n\n if (propName === '$value') {\n // return deepClone(target)\n // return getUnproxiedObject(target)\n return target\n }\n\n const propertyValue = Reflect.get(target, propName, receiver)\n\n if (typeof propName === 'symbol') return propertyValue\n\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\n if (propertyValue._$fieldPath === newNestedFieldPath) return propertyValue\n\n const proxiedNestedObject = proxifyStore(\n store$$ as any,\n propertyValue,\n {\n nestedFieldPath: newNestedFieldPath,\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 // This is used to set the value of the store without notifying the store\n if (isRootTarget && key === '$$value') {\n (parentObject as any)[ROOT_VALUE] = value\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(value) === JSON.stringify(parentObject[ROOT_VALUE])) 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 (isObject(value) && !isValidElement(value) && !value[nonReactiveObjectSymbol] && 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 getUnproxiedObject (obj: any): any {\n// if (obj && typeof obj === 'object') {\n// if (obj[ROOT_VALUE]?.[ROOT_VALUE]) return '[Circular reference]'\n//\n// // Check if the object is a proxy\n// if (obj[ROOT_VALUE])\n// return getUnproxiedObject(obj[ROOT_VALUE])\n//\n//\n// // If it's not a proxy, return the object itself\n// return obj\n// }\n//\n// // If it's not an object, return it as is\n// return obj\n// }\n\n\n\nfunction isValidReactiveObject <T extends Record<string, any>> (value: T): boolean {\n return isObject(value) && !isValidElement(value) && !(value as any)[nonReactiveObjectSymbol]\n}\n\n\nfunction 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 result[key] = traverse(value[key])\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 { useLayoutEffect, useRef, useSyncExternalStore } 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,\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 clonedInitialValue = (initialValue)\n const store$$ = createCacheableSubject<StoreChange<StoreValue>>(clonedInitialValue as any)\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 initialValue = options?.initialValue?.(proxiedStore.$value)\n const isInitialValueSet = useRef(false)\n\n if (!isInitialValueSet.current && initialValue && initialValue !== proxiedStore) {\n isInitialValueSet.current = true;\n (proxiedStore as any).$$value = initialValue\n }\n\n const selectFieldPaths = useRef(\n (typeof options?.select === 'function'\n ? options?.select?.()\n : options?.select)\n ?? [],\n )\n\n const selectedFieldPathsForNestedObjects = useRef(\n selectFieldPaths.current\n .filter(fp => fp.includes('.*'))\n .map(fp => fp.replace('.*', '')),\n )\n\n\n useLayoutEffect(() => {\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 useSyncExternalStore(\n (onStoreChange) => {\n const subscription = store$$.subscribe({\n next: (sc) => {\n const storeChanges = Array.isArray(sc)\n ? sc as Array<StoreChange<StoreValue>>\n : [sc]\n\n if (!options?.select) {\n onStoreChange()\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 onStoreChange()\n options?.onChange?.(storeChanges)\n }\n },\n })\n\n return () => {\n subscription.unsubscribe()\n }\n },\n () => store$$.getValue(),\n () => store$$.getValue(),\n )\n\n return proxiedStore\n },\n }\n}\n","\nexport type Noop = () => void\n\n\nexport type Observer<T> = {\n next: (value: T) => void\n}\n\nexport type Subscription = {\n unsubscribe: Noop\n}\n\nexport type CacheableSubject<T> = {\n getValue: () => T\n subscribe: (value: Observer<T>) => Subscription\n unSubscribeAll: Noop\n} & Observer<T>\n\n\nconst WITH_FLUSHING = true\n\nexport function createCacheableSubject<T> (defaultValue: T, getValueOnSubscribe = false): CacheableSubject<T> {\n let isFlushing = false\n let itemsToFlush: Array<T> = []\n\n let observerList: Array<Observer<T>> = []\n let value = defaultValue\n\n const getValue = (): T => value\n\n const next = (newValue: T): void => {\n value = newValue\n\n if (!WITH_FLUSHING) {\n observerList.forEach((o) => { o.next(newValue) })\n\n return\n }\n\n itemsToFlush.push(newValue)\n // observerList.forEach((o) => { o.next(newValue) })\n\n if (!isFlushing) {\n isFlushing = true\n void Promise.resolve().then(() => {\n observerList.forEach((o) => { o.next(itemsToFlush as T) })\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 // 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\n"],"names":["nonReactiveObjectSymbol","Symbol","obj","Array","isArray","Object","hasOwn","call","bind","hasOwnProperty","ROOT_VALUE","proxifyStore","store$$","objectToProxify","opts","_opts$nestedFieldPath","_objectWithRootValue","fieldPath","nestedFieldPath","objectWithRootValue","rootFunctions","fromEntries","entries","filter","v","Proxy","get","targetObject","propName","receiver","target","WeakSet","traverse","value","seen","has","add","map","result","prototype","key","propertyValue","Reflect","isObject","isValidElement","_opts$parentObjectToP","newNestedFieldPath","_$fieldPath","proxiedNestedObject","parentObjectToProxify","afterChange","set","parentObject","newValue","isRootTarget","previousValue","JSON","stringify","next","storeValue","change","realInnerObject","$value","_opts","replace","nextStoreChange","t","p","ownKeys","getOwnPropertyDescriptor","nonReactive","initialValue","defineProperty","enumerable","writable","configurable","cervello","options","clonedInitialValue","createCacheableSubject","defaultValue","getValueOnSubscribe","isFlushing","observerList","getValue","itemsToFlush","push","resolve","then","forEach","o","subscribe","observer","unsubscribe","unSubscribeAll","proxiedStore","store","reset","deepClone","refs","refsNew","constructorHandlers","Map","Date","fn","cloneArray","from","Set","clone","constructor","handler","o2","getOwnPropertySymbols","symbol","k","cur","i","indexOf","pop","a","keys","length","a2","index","useStore","_ref2","isInitialValueSet","useRef","current","$$value","selectFieldPaths","select","selectedFieldPathsForNestedObjects","fp","includes","useLayoutEffect","setValueOnMount","err","console","error","useSyncExternalStore","onStoreChange","subscription","sc","storeChanges","onChange","some","nextChange","find","startsWith"],"mappings":"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"}
@@ -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 u(e)}):(Object.entries(e).forEach(function(e){n[e[0]]=u(e[1])}),Object.getOwnPropertySymbols(e).forEach(function(t){n[t]=u(e[t])})),n}var o=function(e){return null!==e&&"object"==typeof e&&!Array.isArray(e)};"hasOwn"in Object||(Object.hasOwn=Object.call.bind(Object.hasOwnProperty));var i=Symbol("value");function a(e,l,f){var c,s;void 0===f&&(f={});var h=null!=(c=f.nestedFieldPath)?c:"root",v=((s={})[i]=l,s),b="root"===h?Object.fromEntries(Object.entries(l).filter(function(e){return"function"==typeof e[1]})):{};return new Proxy(v,{get:function(r,l,c){if("_$fieldPath"===l)return h;var s=Object.hasOwn(r,i)?r[i]:r;if("toJSON"===l)return function(){return s};if("$value"===l)return u(s);var v,b=Reflect.get(s,l,c);if("symbol"==typeof l)return b;if("function"==typeof b)return b.bind(c);if(o(v=b)&&!n.isValidElement(v)&&!v[t]){var y,p=h+"."+l;if(b._$fieldPath===p)return b;var d=a(e,b,{nestedFieldPath:p,parentObjectToProxify:null!=(y=f.parentObjectToProxify)?y:s,beforeChange:f.beforeChange,afterChange:f.afterChange});return s[l]=d}return b},set:function(u,a,l,c){var s,v;if("symbol"==typeof a)return!0;var y=l,p=Object.hasOwn(u,i);if(p&&"$value"===a){var d=u[i];return y===d||JSON.stringify(y)===JSON.stringify(u[i])||("root"!==h?u[i]=y:(u[i]=r({},b,y),e.next({storeValue:u[i],change:{fieldPath:"root",newValue:y,previousValue:d}}))),!0}var g=p?u[i]:u,O=Reflect.get(g,a,c);if(O===y)return!0;o(y)&&!n.isValidElement(y)&&!y[t]&&O._$fieldPath?O.$value=y:Reflect.set(g,a,y,g);var j={storeValue:null!=(s=null==(v=f)?void 0:v.parentObjectToProxify)?s:g,change:{fieldPath:(h+"."+a).replace("root.",""),newValue:y,previousValue:O}};return e.next(j),null==f.afterChange||f.afterChange([j]),!0},has:function(e,n){return Reflect.has(e[i],n)},ownKeys:function(e){return Reflect.ownKeys(e[i])},getOwnPropertyDescriptor:function(e,n){return Reflect.getOwnPropertyDescriptor(e[i],n)}})}e.cervello=function(e,t){var r=null!=t?t:{},o=r.beforeChange,i=r.afterChange,l=u(e),f=function(e,n){void 0===n&&(n=!1);var t=!1,r=[],u=[],o=e;return{getValue:function(){return o},next:function(e){o=e,r.push(e),t||(t=!0,Promise.resolve().then(function(){u.forEach(function(e){e.next(r)}),r=[],t=!1}))},subscribe:function(e){return n&&e.next(o),u.push(e),{unsubscribe:function(){u=u.filter(function(n){return n!==e})}}},unSubscribeAll:function(){u=[]}}}(l),c=a(f,l,{beforeChange:o,afterChange:i});return{store:c,reset:function(){c.$value=u(e)},useStore:function(e){var t,r,u=null==e||null==(t=e.initialValue)?void 0:t.apply(c,[c.$value]),o=n.useRef(!1);!o.current&&u&&u!==c&&(o.current=!0,c.$value=u);var i=n.useRef(null!=(r="function"==typeof(null==e?void 0:e.select)?null==e||null==e.select?void 0:e.select():null==e?void 0:e.select)?r:[]),a=n.useRef(i.current.filter(function(e){return e.includes(".*")}).map(function(e){return e.replace(".*","")}));return n.useLayoutEffect(function(){null!=e&&e.setValueOnMount&&e.setValueOnMount(c.$value).then(function(e){c.$value=e}).catch(function(e){console.error("Error setting initial value on mount",e)})},[]),n.useSyncExternalStore(function(n){var t=f.subscribe({next:function(t){var r=Array.isArray(t)?t:[t];if(null==e||!e.select)return n(),void(null==e||null==e.onChange||e.onChange(r));r.some(function(e){return"root"===e.change.fieldPath||i.current.includes(e.change.fieldPath)||a.current.find(function(n){return e.change.fieldPath.startsWith(n)})})&&(n(),null==e||null==e.onChange||e.onChange(r))}});return function(){t.unsubscribe()}},function(){return f.getValue()},function(){return f.getValue()}),c}}}});
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)}var u=function(e){return null!==e&&"object"==typeof e&&!Array.isArray(e)};"hasOwn"in Object||(Object.hasOwn=Object.call.bind(Object.hasOwnProperty));var o=Symbol("value");function i(e,a,l){var c,f;void 0===l&&(l={});var s=null!=(c=l.nestedFieldPath)?c:"root",v=((f={})[o]=a,f),h="root"===s?Object.fromEntries(Object.entries(a).filter(function(e){return"function"==typeof e[1]})):{};return new Proxy(v,{get:function(r,a,c){if("_$fieldPath"===a)return s;var f=Object.hasOwn(r,o)?r[o]:r;if("toJSON"===a)return function(){return e=f,n=new WeakSet,function e(t){if(t&&"object"==typeof t){if(n.has(t))return null;if(n.add(t),Array.isArray(t))return t.map(e);var r={};for(var u in t)Object.prototype.hasOwnProperty.call(t,u)&&(r[u]=e(t[u]));return r}return t}(e);var e,n};if("$value"===a)return f;var v,h=Reflect.get(f,a,c);if("symbol"==typeof a)return h;if("function"==typeof h)return h.bind(c);if(u(v=h)&&!n.isValidElement(v)&&!v[t]&&h!==f){var p,b=s+"."+a;if(h._$fieldPath===b)return h;var y=i(e,h,{nestedFieldPath:b,parentObjectToProxify:null!=(p=l.parentObjectToProxify)?p:f,afterChange:l.afterChange});return f[a]=y}return h},set:function(i,a,c,f){var v,p;if("symbol"==typeof a)return!0;var b=c,y=Object.hasOwn(i,o);if(y&&"$$value"===a)return i[o]=b,!0;if(y&&"$value"===a){var d=i[o];return b===d||JSON.stringify(b)===JSON.stringify(i[o])||("root"!==s?i[o]=b:(i[o]=r({},h,b),e.next({storeValue:i[o],change:{fieldPath:"root",newValue:b,previousValue:d}}))),!0}var O=y?i[o]:i,g=Reflect.get(O,a,f);if(g===b)return!0;u(b)&&!n.isValidElement(b)&&!b[t]&&null!=g&&g._$fieldPath?g.$value=b:Reflect.set(O,a,b,O);var j={storeValue:null!=(v=null==(p=l)?void 0:p.parentObjectToProxify)?v:O,change:{fieldPath:(s+"."+a).replace("root.",""),newValue:b,previousValue:g}};return e.next(j),null==l.afterChange||l.afterChange([j]),!0},has:function(e,n){return Reflect.has(e[o],n)},ownKeys:function(e){return Reflect.ownKeys(e[o])},getOwnPropertyDescriptor:function(e,n){return Reflect.getOwnPropertyDescriptor(e[o],n)}})}e.cervello=function(e,t){var r=(null!=t?t:{}).afterChange,u=e,o=function(e,n){void 0===n&&(n=!1);var t=!1,r=[],u=[],o=e;return{getValue:function(){return o},next:function(e){o=e,r.push(e),t||(t=!0,Promise.resolve().then(function(){u.forEach(function(e){e.next(r)}),r=[],t=!1}))},subscribe:function(e){return n&&e.next(o),u.push(e),{unsubscribe:function(){u=u.filter(function(n){return n!==e})}}},unSubscribeAll:function(){u=[]}}}(u),a=i(o,u,{afterChange:r});return{store:a,reset:function(){a.$value=function(e){var n=[],t=[],r=new Map;r.set(Date,function(e){return new Date(e)}),r.set(Map,function(e,n){return new Map(o(Array.from(e),n))}),r.set(Set,function(e,n){return new Set(o(Array.from(e),n))});var u=null;return function e(i){if("object"!=typeof i||null===i)return i;if(Array.isArray(i))return o(i,e);if(i.constructor!==Object&&(u=r.get(i.constructor)))return u(i,e);var a={};for(var l in n.push(i),t.push(a),Object.getOwnPropertySymbols(i).forEach(function(e){a[e]=i[e]}),i)if(Object.hasOwnProperty.call(i,l)){var c=i[l];if("object"!=typeof c||null===c)a[l]=c;else if(c.constructor!==Object&&(u=r.get(c.constructor)))a[l]=u(c,e);else{var f=n.indexOf(c);a[l]=-1!==f?t[f]:e(c)}}return n.pop(),t.pop(),a}(e);function o(e,o){for(var i=Object.keys(e),a=new Array(i.length),l=0;l<i.length;l++){var c=i[l],f=e[c];if("object"!=typeof f||null===f)a[c]=f;else if(f.constructor!==Object&&(u=r.get(f.constructor)))a[c]=u(f,o);else{var s=n.indexOf(f);a[c]=-1!==s?t[s]:o(f)}}return a}}(e)},useStore:function(e){var t,r=null==e||null==e.initialValue?void 0:e.initialValue(a.$value),u=n.useRef(!1);!u.current&&r&&r!==a&&(u.current=!0,a.$$value=r);var i=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:[]),l=n.useRef(i.current.filter(function(e){return e.includes(".*")}).map(function(e){return e.replace(".*","")}));return n.useLayoutEffect(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.useSyncExternalStore(function(n){var t=o.subscribe({next:function(t){var r=Array.isArray(t)?t:[t];if(null==e||!e.select)return n(),void(null==e||null==e.onChange||e.onChange(r));r.some(function(e){return"root"===e.change.fieldPath||i.current.includes(e.change.fieldPath)||l.current.find(function(n){return e.change.fieldPath.startsWith(n)})})&&(n(),null==e||null==e.onChange||e.onChange(r))}});return function(){t.unsubscribe()}},function(){return o.getValue()},function(){return o.getValue()}),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
@@ -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","import { 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 if (Array.isArray(obj)) {\n newObj = obj.map(item => deepClone(item))\n } else {\n Object.entries(obj).forEach(([key, value]) => {\n newObj[key] = deepClone(value)\n })\n Object.getOwnPropertySymbols(obj).forEach(symbol => {\n newObj[symbol] = deepClone((obj as any)[symbol])\n })\n }\n return newObj as T\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\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 return acc\n }, {})\n}\n\n\n\nconst stringify = (obj: any): string => JSON.stringify(obj)\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","import { isValidElement } from 'react'\n\nimport { nonReactiveObjectSymbol } from '../../types/shared'\nimport { deepClone, isObject } 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// const FIELD_PATH = Symbol('field-path')\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 const objectWithRootValue = {\n [ROOT_VALUE]: objectToProxify,\n // [FIELD_PATH]: fieldPath,\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\n // console.log(' - value proxify -> () >', { fieldPath, objectToProxify, objectWithRootValue })\n\n return new Proxy(objectWithRootValue, {\n get (targetObject, propName, receiver) {\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 // console.log(' - value get -> () >', { propName, targetObject, target })\n\n if (propName === 'toJSON') return () => target\n\n if (propName === '$value') return deepClone(target)\n\n const propertyValue = Reflect.get(target, propName, receiver)\n\n if (typeof propName === 'symbol') return propertyValue\n\n\n if (typeof propertyValue === 'function')\n return (propertyValue as () => any).bind(receiver)\n\n\n if (isRactiveValidObject(propertyValue)) {\n const newNestedFieldPath = `${fieldPath}.${propName}`\n\n\n if (propertyValue._$fieldPath === newNestedFieldPath) return propertyValue\n\n const proxiedNestedObject = proxifyStore(\n store$$ as any,\n propertyValue,\n {\n nestedFieldPath: newNestedFieldPath,\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 value = opts.beforeChange\n // ? opts.beforeChange({\n // change: {\n // fieldPath: `${fieldPath}.${propName}`,\n // newValue,\n // previousValue: Reflect.get(receiver, propName, receiver),\n // },\n // storeValue: targetObject[ROOT_VALUE],\n // }) ?? newValue\n // : newValue\n\n // console.log(' - value set -> () >', { propName, value, targetObject })\n const isRootTarget = Object.hasOwn(parentObject, ROOT_VALUE)\n\n if (isRootTarget && key === '$value') {\n const previousValue = parentObject[ROOT_VALUE]\n\n if (value === previousValue) return true\n if (JSON.stringify(value) === JSON.stringify(parentObject[ROOT_VALUE])) 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)\n 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 (isObject(value) && !isValidElement(value) && !value[nonReactiveObjectSymbol] && 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\nfunction isRactiveValidObject <T extends Record<string, any>> (value: T): boolean {\n return isObject(value) && !isValidElement(value) && !(value as any)[nonReactiveObjectSymbol]\n}\n","\nimport { useLayoutEffect, useRef, useSyncExternalStore } 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\nexport 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 CervelloUseStoreOptions<StoreValue extends Record<string, any>> = {\n initialValue?: (currentStore: StoreValue) => StoreValue,\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 StoreValueMutable<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: StoreValueMutable<StoreValue>,\n reset: () => void,\n useStore: (options?: CervelloUseStoreOptions<StoreValue>) => StoreValueMutable<StoreValue>\n } {\n const {\n beforeChange,\n afterChange,\n } = options ?? {}\n\n const clonedInitialValue = deepClone(initialValue)\n const store$$ = createCacheableSubject<StoreChange<StoreValue>>(clonedInitialValue as any)\n\n const proxiedStore = proxifyStore(\n store$$ as any,\n clonedInitialValue,\n { beforeChange, afterChange },\n ) as StoreValueMutable<StoreValue>\n\n\n return {\n store: proxiedStore,\n reset: () => {\n proxiedStore.$value = deepClone(initialValue)\n },\n useStore: (options) => {\n const initialValue = options?.initialValue?.apply(proxiedStore, [proxiedStore.$value])\n const initialValueSet = useRef(false)\n\n if (!initialValueSet.current && initialValue && initialValue !== proxiedStore) {\n initialValueSet.current = true\n proxiedStore.$value = initialValue\n }\n\n const selectFieldPaths = useRef(\n (typeof options?.select === 'function'\n ? options?.select?.() // .map(fp => `root.${fp}`)\n : options?.select) // ?.map(fp => `root.${fp}`))\n ?? [],\n )\n\n const selectedFieldPathsForNestedObjects = useRef(\n selectFieldPaths.current\n .filter(fp => fp.includes('.*'))\n .map(fp => fp.replace('.*', '')),\n )\n\n\n useLayoutEffect(() => {\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 useSyncExternalStore(\n (onStoreChange) => {\n const subscription = store$$.subscribe({\n next: (sc) => {\n const storeChanges = Array.isArray(sc)\n ? sc as Array<StoreChange<StoreValue>>\n : [sc]\n\n if (!options?.select) {\n onStoreChange()\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\n .find(fp => nextChange.change.fieldPath.startsWith(fp)),\n )) {\n onStoreChange()\n options?.onChange?.(storeChanges)\n }\n },\n })\n\n return () => {\n subscription.unsubscribe()\n }\n },\n () => store$$.getValue(),\n () => store$$.getValue(),\n )\n\n return proxiedStore\n },\n }\n}\n","\nexport type Noop = () => void\n\n\nexport type Observer<T> = {\n next: (value: T) => void\n}\n\nexport type Subscription = {\n unsubscribe: Noop\n}\n\nexport type CacheableSubject<T> = {\n getValue: () => T\n subscribe: (value: Observer<T>) => Subscription\n unSubscribeAll: Noop\n} & Observer<T>\n\n\nconst WITH_FLUSHING = true\n\nexport function createCacheableSubject<T> (defaultValue: T, getValueOnSubscribe = false): CacheableSubject<T> {\n let isFlushing = false\n let itemsToFlush: Array<T> = []\n\n let observerList: Array<Observer<T>> = []\n let value = defaultValue\n\n const getValue = (): T => value\n\n const next = (newValue: T): void => {\n value = newValue\n\n if (!WITH_FLUSHING) {\n observerList.forEach((o) => { o.next(newValue) })\n\n return\n }\n\n itemsToFlush.push(newValue)\n // observerList.forEach((o) => { o.next(newValue) })\n\n if (!isFlushing) {\n isFlushing = true\n void Promise.resolve().then(() => {\n observerList.forEach((o) => { o.next(itemsToFlush as T) })\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 // 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\n"],"names":["nonReactiveObjectSymbol","Symbol","deepClone","obj","newObj","Array","isArray","map","item","Object","entries","forEach","_ref","getOwnPropertySymbols","symbol","isObject","hasOwn","call","bind","hasOwnProperty","ROOT_VALUE","store$$","objectToProxify","opts","fieldPath","nestedFieldPath","_opts$nestedFieldPath","objectWithRootValue","_objectWithRootValue","rootFunctions","fromEntries","filter","Proxy","get","targetObject","propName","receiver","target","value","propertyValue","Reflect","isValidElement","_opts$parentObjectToP","_$fieldPath","newNestedFieldPath","proxiedNestedObject","proxifyStore","parentObjectToProxify","beforeChange","afterChange","set","parentObject","key","newValue","_opts$parentObjectToP2","_opts","isRootTarget","previousValue","JSON","stringify","next","storeValue","change","realInnerObject","$value","nextStoreChange","replace","has","t","p","ownKeys","getOwnPropertyDescriptor","initialValue","options","clonedInitialValue","createCacheableSubject","defaultValue","getValueOnSubscribe","isFlushing","observerList","getValue","itemsToFlush","push","resolve","then","o","subscribe","observer","unsubscribe","unSubscribeAll","proxiedStore","store","reset","useStore","_options$initialValue","_ref2","apply","initialValueSet","useRef","current","selectFieldPaths","select","selectedFieldPathsForNestedObjects","fp","includes","useLayoutEffect","setValueOnMount","err","console","error","useSyncExternalStore","onStoreChange","subscription","sc","storeChanges","onChange","some","nextChange","find","startsWith"],"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/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 { 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 deepClone2 <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 // eslint-disable-next-line no-prototype-builtins\n } else if (!obj.hasOwnProperty('$$typeof')) {\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 deepClone <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\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","import { isValidElement } from 'react'\n\nimport { nonReactiveObjectSymbol } from '../../types/shared'\nimport { isObject } 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 if (propName === '_$fieldPath') return fieldPath\n\n const isRootTarget = Object.hasOwn(targetObject, ROOT_VALUE)\n const target = isRootTarget ? targetObject[ROOT_VALUE] : targetObject\n\n if (propName === 'toJSON') {\n return () => {\n // Remove circular references before stringifying\n // to prevent JSON.stringify from failing\n return removeCircularReferences(target)\n }\n }\n\n if (propName === '$value') {\n // return deepClone(target)\n // return getUnproxiedObject(target)\n return target\n }\n\n const propertyValue = Reflect.get(target, propName, receiver)\n\n if (typeof propName === 'symbol') return propertyValue\n\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\n if (propertyValue._$fieldPath === newNestedFieldPath) return propertyValue\n\n const proxiedNestedObject = proxifyStore(\n store$$ as any,\n propertyValue,\n {\n nestedFieldPath: newNestedFieldPath,\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 // This is used to set the value of the store without notifying the store\n if (isRootTarget && key === '$$value') {\n (parentObject as any)[ROOT_VALUE] = value\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(value) === JSON.stringify(parentObject[ROOT_VALUE])) 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 (isObject(value) && !isValidElement(value) && !value[nonReactiveObjectSymbol] && 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 getUnproxiedObject (obj: any): any {\n// if (obj && typeof obj === 'object') {\n// if (obj[ROOT_VALUE]?.[ROOT_VALUE]) return '[Circular reference]'\n//\n// // Check if the object is a proxy\n// if (obj[ROOT_VALUE])\n// return getUnproxiedObject(obj[ROOT_VALUE])\n//\n//\n// // If it's not a proxy, return the object itself\n// return obj\n// }\n//\n// // If it's not an object, return it as is\n// return obj\n// }\n\n\n\nfunction isValidReactiveObject <T extends Record<string, any>> (value: T): boolean {\n return isObject(value) && !isValidElement(value) && !(value as any)[nonReactiveObjectSymbol]\n}\n\n\nfunction 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 result[key] = traverse(value[key])\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 { useLayoutEffect, useRef, useSyncExternalStore } 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,\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 clonedInitialValue = (initialValue)\n const store$$ = createCacheableSubject<StoreChange<StoreValue>>(clonedInitialValue as any)\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 initialValue = options?.initialValue?.(proxiedStore.$value)\n const isInitialValueSet = useRef(false)\n\n if (!isInitialValueSet.current && initialValue && initialValue !== proxiedStore) {\n isInitialValueSet.current = true;\n (proxiedStore as any).$$value = initialValue\n }\n\n const selectFieldPaths = useRef(\n (typeof options?.select === 'function'\n ? options?.select?.()\n : options?.select)\n ?? [],\n )\n\n const selectedFieldPathsForNestedObjects = useRef(\n selectFieldPaths.current\n .filter(fp => fp.includes('.*'))\n .map(fp => fp.replace('.*', '')),\n )\n\n\n useLayoutEffect(() => {\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 useSyncExternalStore(\n (onStoreChange) => {\n const subscription = store$$.subscribe({\n next: (sc) => {\n const storeChanges = Array.isArray(sc)\n ? sc as Array<StoreChange<StoreValue>>\n : [sc]\n\n if (!options?.select) {\n onStoreChange()\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 onStoreChange()\n options?.onChange?.(storeChanges)\n }\n },\n })\n\n return () => {\n subscription.unsubscribe()\n }\n },\n () => store$$.getValue(),\n () => store$$.getValue(),\n )\n\n return proxiedStore\n },\n }\n}\n","\nexport type Noop = () => void\n\n\nexport type Observer<T> = {\n next: (value: T) => void\n}\n\nexport type Subscription = {\n unsubscribe: Noop\n}\n\nexport type CacheableSubject<T> = {\n getValue: () => T\n subscribe: (value: Observer<T>) => Subscription\n unSubscribeAll: Noop\n} & Observer<T>\n\n\nconst WITH_FLUSHING = true\n\nexport function createCacheableSubject<T> (defaultValue: T, getValueOnSubscribe = false): CacheableSubject<T> {\n let isFlushing = false\n let itemsToFlush: Array<T> = []\n\n let observerList: Array<Observer<T>> = []\n let value = defaultValue\n\n const getValue = (): T => value\n\n const next = (newValue: T): void => {\n value = newValue\n\n if (!WITH_FLUSHING) {\n observerList.forEach((o) => { o.next(newValue) })\n\n return\n }\n\n itemsToFlush.push(newValue)\n // observerList.forEach((o) => { o.next(newValue) })\n\n if (!isFlushing) {\n isFlushing = true\n void Promise.resolve().then(() => {\n observerList.forEach((o) => { o.next(itemsToFlush as T) })\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 // 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\n"],"names":["nonReactiveObjectSymbol","Symbol","obj","Array","isArray","Object","hasOwn","call","bind","hasOwnProperty","ROOT_VALUE","proxifyStore","store$$","objectToProxify","opts","_opts$nestedFieldPath","_objectWithRootValue","fieldPath","nestedFieldPath","objectWithRootValue","rootFunctions","fromEntries","entries","filter","v","Proxy","get","targetObject","propName","receiver","target","WeakSet","traverse","value","seen","has","add","map","result","prototype","key","propertyValue","Reflect","isObject","isValidElement","_opts$parentObjectToP","newNestedFieldPath","_$fieldPath","proxiedNestedObject","parentObjectToProxify","afterChange","set","parentObject","newValue","isRootTarget","previousValue","JSON","stringify","next","storeValue","change","realInnerObject","$value","_opts","replace","nextStoreChange","t","p","ownKeys","getOwnPropertyDescriptor","initialValue","options","clonedInitialValue","createCacheableSubject","defaultValue","getValueOnSubscribe","isFlushing","observerList","getValue","itemsToFlush","push","resolve","then","forEach","o","subscribe","observer","unsubscribe","unSubscribeAll","proxiedStore","store","reset","deepClone","refs","refsNew","constructorHandlers","Map","Date","fn","cloneArray","from","Set","clone","constructor","handler","o2","getOwnPropertySymbols","symbol","k","cur","i","indexOf","pop","a","keys","length","a2","index","useStore","_ref2","isInitialValueSet","useRef","current","$$value","selectFieldPaths","select","selectedFieldPathsForNestedObjects","fp","includes","useLayoutEffect","setValueOnMount","err","console","error","useSyncExternalStore","onStoreChange","subscription","sc","storeChanges","onChange","some","nextChange","find","startsWith","nonReactive","defineProperty","enumerable","writable","configurable"],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@cervello/react",
3
3
  "type": "module",
4
- "version": "5.0.0-beta.1",
4
+ "version": "5.0.0-beta.11",
5
5
  "description": "🤯 Simple, reactive, tiny and performant state-management library",
6
6
  "author": "Chempo",
7
7
  "license": "MIT",
@@ -54,6 +54,7 @@
54
54
  ],
55
55
  "scripts": {
56
56
  "release": "pnpx bumpp --push=false && npm publish --access public",
57
+ "docs:dev": "pnpm run --filter @cervello/react docs:dev",
57
58
  "publish:beta": "npm publish --tag beta",
58
59
  "test": "vitest --watch",
59
60
  "test:release": "vitest run",
package/types/index.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export { cervello } from './lib/store/new-index';
1
+ export { cervello, nonReactive } from './lib/store/new-index';
2
2
  export type { CervelloOptions, CervelloUseStoreOptions } from './lib/store/new-index';
@@ -3,6 +3,5 @@ import type { CacheableSubject } from '../utils/subject';
3
3
  export declare function proxifyStore<T extends Record<string | symbol, any>>(store$$: CacheableSubject<StoreChange<T>>, objectToProxify: T, opts?: {
4
4
  nestedFieldPath?: string;
5
5
  parentObjectToProxify?: any;
6
- beforeChange?: (storeChange: StoreChange<T>) => any;
7
6
  afterChange?: (storeChange: Array<StoreChange<T>>) => void;
8
7
  }): T;
@@ -1,6 +1,5 @@
1
1
  import type { FieldPath, StoreChange } from '../../types/shared';
2
2
  export type CervelloOptions<StoreValue extends Record<string, any>> = {
3
- beforeChange?: (storeChange: StoreChange<StoreValue>) => unknown | undefined;
4
3
  afterChange?: (storeChange: Array<StoreChange<StoreValue>>) => void;
5
4
  };
6
5
  export type CervelloUseStoreOptions<StoreValue extends Record<string, any>> = {
@@ -9,13 +8,13 @@ export type CervelloUseStoreOptions<StoreValue extends Record<string, any>> = {
9
8
  select?: Array<FieldPath<StoreValue>> | (() => Array<FieldPath<StoreValue>>);
10
9
  onChange?: (storeChange: Array<StoreChange<StoreValue>>) => void;
11
10
  };
12
- type StoreValueMutable<T extends Record<string, any>> = {
11
+ type MutableStoreValue<T extends Record<string, any>> = {
13
12
  $value: T;
14
13
  } & T;
15
14
  export declare function nonReactive<T extends Record<string, any>>(initialValue: T): T;
16
15
  export declare function cervello<StoreValue extends Record<PropertyKey, any>>(initialValue: StoreValue, options?: CervelloOptions<StoreValue>): {
17
- store: StoreValueMutable<StoreValue>;
16
+ store: MutableStoreValue<StoreValue>;
18
17
  reset: () => void;
19
- useStore: (options?: CervelloUseStoreOptions<StoreValue>) => StoreValueMutable<StoreValue>;
18
+ useStore: (options?: CervelloUseStoreOptions<StoreValue>) => MutableStoreValue<StoreValue>;
20
19
  };
21
20
  export {};
@@ -5,6 +5,7 @@
5
5
  * @param obj - base object to be cloned
6
6
  * @returns new cloned object with new reference
7
7
  */
8
+ export declare function deepClone2<T>(obj: T): T;
8
9
  export declare function deepClone<T>(obj: T): T;
9
10
  /**
10
11
  * Guard to check is variable is an object