@cervello/react 5.4.1 β 6.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +12 -0
- package/dist/cervello.cjs +1 -1
- package/dist/cervello.cjs.map +1 -1
- package/dist/cervello.esm.js +1 -1
- package/dist/cervello.esm.js.map +1 -1
- package/package.json +14 -12
- package/types/index.d.ts +1 -0
- package/types/lib/helpers/new-proxify-store.d.ts +5 -1
- package/types/lib/utils/object.d.ts +22 -5
- package/types/lib/utils/subject.d.ts +9 -5
- package/types/test/bench/clone.bench.d.ts +1 -0
- package/types/test/bench/proxy.bench.d.ts +1 -0
- package/types/test/bench/subject.bench.d.ts +1 -0
- package/types/test/lib/proxify-store.test.d.ts +1 -0
- package/types/test/lib/store.test.d.ts +1 -0
- package/types/test/lib/subject.test.d.ts +1 -0
- package/types/test/lib/utils.test.d.ts +1 -0
- package/dist/cervello.umd.js +0 -2
- package/dist/cervello.umd.js.map +0 -1
- package/types/lib/helpers/create-store-selector-hook.d.ts +0 -3
- package/types/lib/helpers/index.d.ts +0 -2
- package/types/lib/helpers/proxify-store.d.ts +0 -2
- package/types/lib/store/index.d.ts +0 -58
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2021 Chempo GonzΓ‘lez
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -87,6 +87,18 @@ const AddressWithSelector = () => {
|
|
|
87
87
|
}
|
|
88
88
|
```
|
|
89
89
|
|
|
90
|
+
## π‘ **Good to know**
|
|
91
|
+
|
|
92
|
+
- **Batched changes**: mutations are coalesced and flushed once per microtask. `onChange`/`afterChange` receive the whole batch as an array (don't mutate it β it may be shared between subscribers).
|
|
93
|
+
- **No spurious updates**: assigning content-equal values (same primitive, or a plain object with the same content β key order doesn't matter) does not notify or re-render. Arrays, `nonReactive` objects and React elements always notify. A component that already rendered after a write (e.g. a handler that calls `setState` and then writes to the store) is not re-rendered again by that write.
|
|
94
|
+
- **Nested objects are live views**: `const { address } = useStore()` (or `const a = store.address`) keeps pointing at the store's current data even after `store.address = {...}`, `store.$value = {...}` or `reset()`, so writing through it always updates the store. If its path stops being an object (`store.address = null`), writes through the old handle are dropped.
|
|
95
|
+
- **`$value` is always a copy**: reading `store.$value` returns a deep clone, and `store.$value = obj` (like `cervello(obj)` and `reset()`) stores a deep clone of `obj` β mutating `obj` afterwards does not touch the store. Prefer `{ ...store.$value, x }` over `{ ...store, x }` when building a new value.
|
|
96
|
+
- **Hot components**: pass `select: ['path', 'nested.*']` to `useStore` so the component only re-renders for those paths; without it, it re-renders on every store change. Exact paths match their own writes; `'address.*'` also matches anything nested under `address`. When an **ancestor** is reassigned (`store.address = {...}`, `store.$value = {...}` or `reset()`), the selected slice is compared by content and the component only re-renders if it actually changed. Rule: a component must only **read** the paths it selects β a non-selected field read in render is never refreshed.
|
|
97
|
+
- **`afterChange` fires on every emission**: field writes, whole-store replacement (`store.$value = ...`, `reset()`) and `initialValue` seeds β content-equal writes never emit, so they never fire it either. For seeds it is deferred to a microtask (never inside a React render). A subscriber (`onChange`) that throws does not stop the other subscribers nor later updates: the error is re-thrown asynchronously.
|
|
98
|
+
- **StrictMode**: `initialValue` is render-phase code (double-invoked in dev β keep it idempotent) and `setValueOnMount` runs on each effect mount, per React's contract.
|
|
99
|
+
- **SSR**: the store is module-scoped. For per-request isolation, call `cervello()` per request and share it via context.
|
|
100
|
+
- **Complex values** (`Date`, `Map`, `Set`, class instances, circular refs): wrap them with `nonReactive(...)` β they are kept intact (and restored by `reset()`) but don't trigger reactivity.
|
|
101
|
+
|
|
90
102
|
<br>
|
|
91
103
|
<br>
|
|
92
104
|
|
package/dist/cervello.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var e=require("react"),n=Symbol("nonReactiveObject");function
|
|
1
|
+
var e=require("react"),n=Symbol("nonReactiveObject");function r(e,n){if(!e||"object"!=typeof e)return e;if(n.has(e))return n.get(e);if(e instanceof Date)return new Date(e.getTime());if(a(e))return e;if(Array.isArray(e)){var t=[];return n.set(e,t),e.forEach(function(e,u){t[u]=r(e,n)}),t}if(e instanceof Map){var u=new Map;return n.set(e,u),e.forEach(function(e,t){u.set(r(t,n),r(e,n))}),u}if(e instanceof Set){var o=new Set;return n.set(e,o),e.forEach(function(e){o.add(r(e,n))}),o}if(e.constructor&&e.constructor!==Object)return e;var i={};n.set(e,i);for(var l=Object.keys(e),f=0;f<l.length;f++)i[l[f]]=r(e[l[f]],n);for(var c=Object.getOwnPropertySymbols(e),s=0;s<c.length;s++)i[c[s]]=e[c[s]];return i}function t(e,u){if(void 0===u&&(u=new WeakSet),!e||"object"!=typeof e)return e;if(e[n]){var o=r(e,new WeakMap);return o[n]||(o[n]=!0),o}if(u.has(e))return null;if(Array.isArray(e)){u.add(e);var i=e.map(function(e){return t(e,u)});return u.delete(e),i}var l=Object.keys(e);if(a(e,l))return e;u.add(e);for(var f={},c=0;c<l.length;c++)f[l[c]]=t(e[l[c]],u);for(var s=Object.getOwnPropertySymbols(e),v=0;v<s.length;v++)f[s[v]]=e[s[v]];return u.delete(e),f}var u=function(e){return null!==e&&"object"==typeof e&&!Array.isArray(e)},o=function(e){return!!u(e)&&!!e.$$typeof};function a(e,n){if(!u(e))return!1;if(o(e))return!0;var r=null!=n?n:Object.keys(e);return r.includes("tag")&&r.includes("containerInfo")||r.some(function(e){return e.startsWith("__reactContainer")})||r.includes("tag")&&r.includes("stateNode")}function i(e){return u(e)&&!o(e)&&!e[n]}function l(e,n){for(var r=n.split("."),t=e,u=0;u<r.length;u++){if(null===t||"object"!=typeof t)return;t=t[r[u]]}return t}var f=function(e){return JSON.stringify(d(e))},c=function(e,n){return a(e,n)||!(null==globalThis||!globalThis.HTMLElement)&&e instanceof globalThis.HTMLElement};function s(e,n,r,t){if(e===n)return!0;if(Number.isNaN(e))return Number.isNaN(n);if(!e||!n||"object"!=typeof e||"object"!=typeof n)return!1;var u=!!r&&r.has(e),o=!!t&&t.has(n);if(u||o)return u&&o;var a=Array.isArray(e);if(a!==Array.isArray(n))return!1;var i=!1,l=!0;if(a){l=e.length===n.length;for(var v=0;l&&v<e.length;v++){var d,h,p=void 0===e[v]||"function"==typeof e[v]?null:e[v],y=void 0===n[v]||"function"==typeof n[v]?null:n[v];!i&&(p&&"object"==typeof p||y&&"object"==typeof y)&&(i=!0,r=null!=(d=r)?d:new WeakSet,t=null!=(h=t)?h:new WeakSet,r.add(e),t.add(n)),l=s(p,y,r,t)}}else{var g=Object.keys(e),b=Object.keys(n);if(c(e,g)||c(n,b))l=f(e)===f(n);else{for(var w=0,j=0;l&&j<g.length;j++){var m=e[g[j]];if(void 0!==m&&"function"!=typeof m){w++;var O,V,k=n[g[j]];void 0===k||"function"==typeof k?l=!1:(!i&&(m&&"object"==typeof m||k&&"object"==typeof k)&&(i=!0,r=null!=(O=r)?O:new WeakSet,t=null!=(V=t)?V:new WeakSet,r.add(e),t.add(n)),l=s(m,k,r,t))}}if(l){for(var M=0;M<b.length;M++){var S=n[b[M]];void 0!==S&&"function"!=typeof S&&w--}l=0===w}}}return i&&(r.delete(e),t.delete(n)),l}var v=function(e,n){return s(e,n,null,null)};function d(e,n){if(void 0===n&&(n=new WeakSet),"object"!=typeof e||null==e)return e;if(n.has(e))return null;if(Array.isArray(e)){n.add(e);var r=e.map(function(e){return d(e,n)});return n.delete(e),r}if(o(e)){n.add(e);var t={props:d(e.props,n),type:"string"==typeof e.type?e.type:""};return n.delete(e),t}if(null!=globalThis&&globalThis.HTMLElement&&e instanceof globalThis.HTMLElement)return{type:"[HTMLElement]",content:e.innerHTML};var u=Object.keys(e);if(a(e,u))return{type:"[ReactNode]"};var i={};n.add(e);for(var l=0;l<u.length;l++)i[u[l]]=d(e[u[l]],n);return n.delete(e),i}var h=Symbol("rawValue");function p(e,n,r){var u,o;void 0===r&&(r={});var a=null!=(u=r.nestedFieldPath)?u:"root",l=void 0===r.parent,f=r.key,c=l?"":a.slice(5)+".",s=new Map,y=n,g=!1,b=-1,w=function(){if(b=e.state.version,!l){var n=r.parent(),t=void 0===n?void 0:n[f];if(t!==y&&i(t)){var u=t[h];u&&(n[f]=t=u),y=t}g=t!==y}},j=function(){return e.state.version!==b&&w(),y},m=function(){var e=j();return g?void 0:e},O=null!=(o=r.rootRaw)?o:function(){return y},V=function(){return d(j())},k=new WeakMap,M=l?Object.fromEntries(Object.entries(n).filter(function(e){return"function"==typeof e[1]})):{},S=function(n){e.next(n),null==r.afterChange||r.afterChange([n])};return new Proxy({},{get:function(n,u,o){e.state.version!==b&&w();var l=y;if("symbol"==typeof u)return u===h?l:l[u];if("_$fieldPath"===u)return a;if("toJSON"===u)return V;if("$value"===u)return t(l);var f=l[u];if("function"==typeof f){var c=k.get(f);return c||(c=f.bind(o),k.set(f,c)),c}if(null!==f&&"object"==typeof f){var v=s.get(u);if(void 0!==v&&v.raw===f)return v.proxy;if(i(f)&&f!==l){var d=f[h];if(d&&(l[u]=f=d),void 0!==v)return v.raw=f,v.proxy;var g=p(e,f,{nestedFieldPath:a+"."+u,parent:m,parentProxy:o,key:u,rootRaw:O,afterChange:r.afterChange});return s.set(u,{proxy:g,raw:f}),g}}return f},set:function(n,u,o){var a;if("symbol"==typeof u)return!0;var s=null!==o&&"object"==typeof o&&null!=(a=o[h])?a:o;if("$$value"===u&&l){var d=y,p={storeValue:y=Object.assign({},M,t(s.newValue)),change:{fieldPath:"root",newValue:s.newValue,previousValue:d}};return e.next(p,s.id),r.afterChange&&queueMicrotask(function(){r.afterChange([p])}),!0}if("$value"===u){if(!l)return r.parentProxy[f]=s,!0;var g=y;return s===g||v(s,g)||(y=Object.assign({},M,t(s)),S({storeValue:y,change:{fieldPath:"root",newValue:s,previousValue:g}})),!0}var b=m();if(void 0===b)return!0;var w=b[u];return w===s||i(s)&&v(s,w)||(b[u]=s,S({storeValue:O(),change:{fieldPath:c+u,newValue:s,previousValue:w}})),!0},has:function(e,n){return Reflect.has(j(),n)},ownKeys:function(){return Reflect.ownKeys(j())},getOwnPropertyDescriptor:function(e,n){return Reflect.getOwnPropertyDescriptor(j(),n)}})}exports.cervello=function(n,r){var u=(null!=r?r:{}).afterChange,o=t(n),a=function(){var e=!1,n=!1,r={version:0},t=!1,u=[],o=[];function a(e,n){try{e.next(n)}catch(e){queueMicrotask(function(){throw e})}}function i(){if(e=!1,!n&&0!==o.length){n=!0;var r=o,i=t;o=[],t=!1;var f=u.slice();if(i)for(var c=0;c<f.length;c++){for(var s=f[c],v=[],d=0;d<r.length;d++)r[d].subscriberId!==s.id&&v.push(r[d].newValue);v.length>0&&a(s,v)}else{for(var h=[],p=0;p<r.length;p++)h.push(r[p].newValue);for(var y=0;y<f.length;y++)void 0!==f[y].id&&a(f[y],h)}n=!1,o.length>0&&l()}}function l(){e||n||0===o.length||(e=!0,queueMicrotask(i))}return{next:function(u,a){r.version++,void 0!==a&&(t=!0),o.push({newValue:u,subscriberId:a}),e||n||l()},subscribe:function(e){return u.push(e),{unsubscribe:function(){var n=u.indexOf(e);-1!==n&&u.splice(n,1)}}},version:function(){return r.version},state:r}}(),i=p(a,o,{afterChange:u});return{store:i,reset:function(){i.$value=n},useStore:function(n){var r=e.useId(),t=e.useRef(!1),u=e.useState(0)[1],o=e.useRef(n);if(o.current=n,!t.current){t.current=!0;var f=null==n||null==n.initialValue?void 0:n.initialValue(i.$value);f&&!v(f,i[h])&&(i.$$value={id:r,newValue:f})}var c=e.useRef(0);c.current=a.version();var s,d=e.useRef(null);null===d.current&&(d.current=null!=(s="function"==typeof(null==n?void 0:n.select)?n.select():null==n?void 0:n.select)?s:[]);var p=e.useRef(null);null===p.current&&(p.current=d.current.filter(function(e){return e.includes(".*")}).map(function(e){return e.replace("*","")}));var y=function(){u(function(e){return e+1})};return e.useEffect(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.useEffect(function(){var e,n,t=null!=(e=d.current)?e:[],u=null!=(n=p.current)?n:[],i=t.map(function(e){return e.replace(".*","")});a.version()!==c.current&&y();var f=a.subscribe({id:r,next:function(e){var n=o.current,r=a.version()!==c.current;if(null==n||!n.select)return r&&y(),void(null==n||null==n.onChange||n.onChange(e));e.some(function(e){var n=e.change.fieldPath,r=n+".";return!!t.includes(n)||!!u.some(function(e){return r.startsWith(e)})||i.some(function(t){if("root"!==n&&!t.startsWith(r))return!1;var u="root"===n?t:t.slice(r.length);return!v(l(e.change.previousValue,u),l(e.change.newValue,u))})})&&(r&&y(),null==n||null==n.onChange||n.onChange(e))}});return function(){f.unsubscribe()}},[]),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
|
package/dist/cervello.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cervello.cjs","sources":["../src/types/shared.ts","../src/lib/utils/object.ts","../src/lib/helpers/new-proxify-store.ts","../src/lib/store/new-index.ts","../src/lib/utils/subject.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/ban-types */\nexport type WithoutType<T, V, WithNever = {\n [K in keyof T]: Exclude<T[K], undefined> extends V\n ? never\n : (T[K] extends Record<string, unknown>\n ? WithoutType<T[K], V>\n : T[K])\n}> = Pick<WithNever, {\n [K in keyof WithNever]: WithNever[K] extends never ? never : K\n}[keyof WithNever]>\n\n\n\nexport type ObjectFromAttributes<T, Attributes extends Array< keyof WithoutType<T, Function> > > = {\n [k in Attributes[number]]: T[k]\n}\n\nexport type Maybe<T> = T | undefined\n\n\n\nexport type UseSelector<T> = <Attributes extends Array< Exclude<keyof WithoutType<T, Function>, '$value'> >>(\n selectors: Attributes,\n isEqualFunction?: (previousState: ObjectFromAttributes<T, Attributes>, currentState: ObjectFromAttributes<T, Attributes>) => boolean,\n) => T\n\nexport type FieldPath<T extends Record<string, any>> = {\n [K in keyof Required<T>]: T[K] extends Record<string, any>\n ? K extends string\n\n ? T[K] extends Function\n ? never\n : T[K] extends Array<any>\n ? K\n : `${K}.*` | `${K}.${FieldPath<T[K]>}`\n : never\n : K extends string\n ? K\n : never\n}[keyof T]\n\nexport const nonReactiveObjectSymbol = Symbol('nonReactiveObject')\nexport type StoreChange<T extends Record<string, any>> = {\n change: {\n fieldPath: FieldPath<T>\n newValue: any\n previousValue: any\n }\n storeValue: T\n}\n","/* eslint-disable no-cond-assign */\n\nimport { nonReactiveObjectSymbol } from '../../types/shared'\nimport { INTERNAL_VALUE_PROP } from '../helpers/constants'\n\n\n/**\n * Clones all the provided object and nested properties and it also\n * iterates nested arrays to deepClone them\n *\n * @param obj - base object to be cloned\n * @returns new cloned object with new reference\n */\nexport function deepClone <T> (obj: T): T {\n if (!obj || typeof obj !== 'object')\n return obj\n\n let newObj = {} as any\n\n if (Array.isArray(obj)) {\n newObj = obj.map(item => deepClone(item))\n } else if (!isReactObjectLikeNode(obj)) {\n Object.entries(obj).forEach(([key, value]) => {\n newObj[key] = deepClone(value)\n })\n Object.getOwnPropertySymbols(obj).forEach((symbol) => {\n newObj[symbol] = (obj as any)[symbol]\n })\n } else {\n newObj = obj\n }\n\n return newObj as T\n}\n\n// function copyBuffer (cur: ArrayBufferView) {\n// if (cur instanceof Buffer)\n// return Buffer.from(cur)\n//\n//\n// return new cur.constructor(cur.buffer.slice(), cur.byteOffset, cur.length)\n// }\n\n\n// INFO: From `rfdc` (really-fast-deep-clone) package for faster cloning taking care of circular references\nexport function deepClone2 <T> (obj: T): T {\n const refs: Array<any> = []\n const refsNew: Array<any> = []\n\n const constructorHandlers = new Map()\n\n constructorHandlers.set(Date, (o: string | number | Date) => new Date(o))\n constructorHandlers.set(Map, (o: Iterable<unknown> | ArrayLike<unknown>, fn: any) => new Map(cloneArray(Array.from(o), fn)))\n constructorHandlers.set(Set, (o: Iterable<unknown> | ArrayLike<unknown>, fn: any) => new Set(cloneArray(Array.from(o), fn)))\n\n let handler = null\n\n return clone(obj)\n\n function cloneArray (a: any, fn: any): any {\n const keys = Object.keys(a)\n const a2 = new Array(keys.length) as any\n\n for (let i = 0; i < keys.length; i++) {\n const k = keys[i]\n const cur = a[k]\n\n if (typeof cur !== 'object' || cur === null) {\n a2[k] = cur\n } else if (cur.constructor !== Object && (handler = constructorHandlers.get(cur.constructor))) {\n a2[k] = handler(cur, fn)\n // } else if (ArrayBuffer.isView(cur)) {\n // a2[k] = copyBuffer(cur)\n } else {\n const index = refs.indexOf(cur)\n\n if (index !== -1)\n a2[k] = refsNew[index]\n else\n a2[k] = fn(cur)\n }\n }\n\n return a2\n }\n\n function clone (o: any): any {\n if (typeof o !== 'object' || o === null) return o\n if (Array.isArray(o)) return cloneArray(o, clone)\n if (o.constructor !== Object && (handler = constructorHandlers.get(o.constructor)))\n return handler(o, clone)\n\n const o2 = {} as any\n\n refs.push(o)\n refsNew.push(o2)\n\n\n Object.getOwnPropertySymbols(o).forEach((symbol) => {\n o2[symbol] = (o)[symbol]\n })\n\n for (const k in o) {\n if (!Object.hasOwnProperty.call(o, k)) continue\n const cur = o[k]\n\n\n if (typeof cur !== 'object' || cur === null) {\n o2[k] = cur\n } else if (cur.constructor !== Object && (handler = constructorHandlers.get(cur.constructor))) {\n o2[k] = handler(cur, clone)\n // } else if (ArrayBuffer.isView(cur)) {\n // o2[k] = copyBuffer(cur)\n } else {\n const i = refs.indexOf(cur)\n\n if (i !== -1)\n o2[k] = refsNew[i]\n else\n o2[k] = clone(cur)\n }\n }\n refs.pop()\n refsNew.pop()\n\n\n return o2\n }\n}\n\n/**\n * Guard to check is variable is an object\n * @param obj - variable to be checked\n * @returns boolean\n */\nexport const isObject = (obj: unknown): obj is Record<string | symbol, unknown> => (\n obj !== null\n && typeof obj === 'object'\n && !Array.isArray(obj)\n)\n\n\nexport const isReactElement = (obj: unknown): boolean => {\n if (!isObject(obj)) return false\n\n return !!(obj.$$typeof)\n}\n\n\nexport function isReactObjectLikeNode (obj: unknown): boolean {\n if (!isObject(obj)) return false\n if (isReactElement(obj)) return true\n\n const objKeys = Object.keys(obj)\n const isReactObjNode = (objKeys.includes('tag') && objKeys.includes('containerInfo'))\n || objKeys.some(k => k.startsWith('__reactContainer'))\n || (objKeys.includes('tag') && objKeys.includes('stateNode'))\n\n return isReactObjNode\n}\n\n\nexport function isValidReactiveObject <T extends Record<string, any>> (value: T): boolean {\n return isObject(value) && !isReactElement(value) && !(value as any)[nonReactiveObjectSymbol]\n}\n\n\n\n/**\n * Returns the actual target value instead of root\n * object with internals props like $$value$$\n *\n * @param target - object from subscription or proxy\n * @returns actual value\n */\nexport const okTarget = (target: any): any => target[INTERNAL_VALUE_PROP] ?? target\n\n\n\n\n/**\n * Gets an object with just the properties requested\n * instead of the full object\n *\n * @param properties - object properties\n * @param obj - target to get the properties\n * @returns New object with just the requested properties\n */\nexport function getPartialObjectFromProperties<T> (properties: Array<keyof T>, obj: T): any {\n return properties.reduce<any>((acc, curr) => {\n acc[curr] = obj[curr]\n\n return acc\n }, {})\n}\n\n\n\nconst stringify = (obj: any): string => JSON.stringify(obj)\n\n/**\n * Compare 2 provided objects by stringing them\n * @param a - first object\n * @param b - second object\n * @returns boolean\n */\nexport const contentComparer = (a: any, b: any): boolean => stringify(a) === stringify(b)\n\n\n\n\nexport function safeToJson (obj: any): Record<string, any> {\n const o: Record<string, any> = {}\n\n if (typeof obj !== 'object' || obj == null)\n return obj\n\n if (Array.isArray(obj))\n return obj.map(item => safeToJson(item))\n\n if (isReactElement(obj))\n return { props: safeToJson(obj.props), type: typeof obj.type === 'string' ? obj.type : '' }\n\n if (globalThis?.HTMLElement && obj instanceof globalThis.HTMLElement) return { type: '[HTMLElement]', content: obj.innerHTML }\n\n Object.entries(obj).forEach(([key, v]) => {\n o[key] = safeToJson(v)\n })\n\n return o\n}\n","\nimport { deepClone, isValidReactiveObject, safeToJson } from '../utils/object'\n\nimport type { StoreChange } from '../../types/shared'\nimport type { CacheableSubject } from '../utils/subject'\n\n\n\n// @ts-expect-error - Object.hasOwn is not defined in older Safari's browsers\n('hasOwn' in Object) || (Object.hasOwn = Object.call.bind(Object.hasOwnProperty))\n\nconst ROOT_VALUE = Symbol('value')\n\n\nexport function proxifyStore <T extends Record<string | symbol, any>> (\n store$$: CacheableSubject<StoreChange<T>>,\n objectToProxify: T,\n opts: {\n nestedFieldPath?: string\n parentObjectToProxify?: any\n // beforeChange?: (storeChange: StoreChange<T>) => any\n afterChange?: (storeChange: Array<StoreChange<T>>) => void\n } = {},\n): T {\n const fieldPath = opts.nestedFieldPath ?? 'root'\n\n const objectWithRootValue = {\n [ROOT_VALUE]: objectToProxify,\n } as unknown as T\n\n const rootFunctions = fieldPath === 'root'\n ? Object.fromEntries(Object.entries(objectToProxify).filter(([,v]) => typeof v === 'function'))\n : {}\n\n return new Proxy(objectWithRootValue, {\n get (targetObject, propName, receiver) {\n // INFO: !Internal only.\n // Used to get the fieldPath of the object (it means it's a proxified object)\n if (propName === '_$fieldPath') return fieldPath\n\n const isRootTarget = Object.hasOwn(targetObject, ROOT_VALUE)\n const target = isRootTarget ? targetObject[ROOT_VALUE] : targetObject\n\n\n // Called when the object is converted to JSON or string (i.e. JSON.stringify)\n if (propName === 'toJSON') {\n return () => {\n // Remove react-elements with circular which have circular references\n // before stringifying to prevent JSON.stringify(storeProxy) from failing\n return safeToJson(target)\n // return removeCircularReferences(target)\n }\n }\n\n // Get the whole store value without proxies\n if (propName === '$value')\n return deepClone(target)\n // return target\n\n\n\n const propertyValue = Reflect.get(target, propName, receiver)\n\n if (typeof propName === 'symbol') return propertyValue\n\n if (typeof propertyValue === 'function')\n return (propertyValue as () => any).bind(receiver)\n\n\n // Check if it's correct to be a reactive object\n // & is not a circular reference or the same object\n if (isValidReactiveObject(propertyValue) && propertyValue !== target) {\n // const newNestedFieldPath = `${fieldPath}.${propName}`\n\n // If it's already a proxified object, return it\n // if (propertyValue._$fieldPath === newNestedFieldPath) return propertyValue\n if (propertyValue._$fieldPath) return propertyValue\n\n // Create a new proxified object\n const proxiedNestedObject = proxifyStore(\n store$$ as any,\n propertyValue,\n {\n nestedFieldPath: `${fieldPath}.${propName}`,\n parentObjectToProxify: opts.parentObjectToProxify ?? target,\n // beforeChange: opts.beforeChange,\n afterChange: opts.afterChange,\n },\n )\n\n return target[propName] = proxiedNestedObject\n }\n\n return propertyValue\n },\n\n\n set (parentObject, key, newValue, receiver) {\n if (typeof key === 'symbol') return true\n\n const value = newValue\n const isRootTarget = Object.hasOwn(parentObject, ROOT_VALUE)\n\n // INFO: !Internal only.\n // Used to set the value of the store without notifying the store\n if (isRootTarget && key === '$$value') {\n const previousValue = parentObject[ROOT_VALUE];\n\n (parentObject as any)[ROOT_VALUE] = value.newValue\n\n store$$.next({\n storeValue: value.newValue,\n change: {\n fieldPath: 'root' as any,\n newValue: value.newValue,\n previousValue,\n },\n }, value.id)\n\n return true\n }\n\n if (isRootTarget && key === '$value') {\n const previousValue = parentObject[ROOT_VALUE]\n\n if (value === previousValue) return true\n\n if (JSON.stringify(safeToJson(value)) === JSON.stringify(safeToJson(previousValue))) return true\n // if (safeStringify(value) === safeStringify(previousValue)) return true\n\n if (fieldPath !== 'root') {\n (parentObject as any)[ROOT_VALUE] = value\n } else {\n (parentObject as any)[ROOT_VALUE] = {\n ...rootFunctions,\n ...value,\n }\n store$$.next({\n // To be disabled for performance and send same store reference\n // storeValue: JSON.parse(JSON.stringify(targetObject[ROOT_VALUE])),\n storeValue: parentObject[ROOT_VALUE],\n change: {\n fieldPath: 'root' as any,\n newValue: value,\n previousValue,\n },\n })\n }\n\n return true\n }\n\n const realInnerObject = isRootTarget ? parentObject[ROOT_VALUE] : parentObject\n const previousValue = Reflect.get(realInnerObject, key, receiver)\n\n\n if (previousValue === value) return true\n\n\n // New object values, check if the field has already a proxy created to use it instead of reacreating a new instance\n if (isValidReactiveObject(value) && previousValue?._$fieldPath)\n previousValue.$value = value\n else\n Reflect.set(realInnerObject, key, value, realInnerObject)\n\n\n const nextStoreChange = {\n // To be disabled for performance and send same store reference\n // storeValue: JSON.parse(JSON.stringify(opts?.parentObjectToProxify ?? target)),\n storeValue: opts?.parentObjectToProxify ?? realInnerObject,\n change: {\n fieldPath: `${fieldPath}.${key}`.replace('root.', '') as any,\n newValue: value,\n previousValue,\n },\n }\n\n store$$.next(nextStoreChange)\n opts.afterChange?.([nextStoreChange])\n\n return true\n },\n\n has (t, p) {\n return Reflect.has(t[ROOT_VALUE], p)\n },\n\n ownKeys (t) {\n return Reflect.ownKeys(t[ROOT_VALUE])\n },\n\n getOwnPropertyDescriptor (t, p) {\n return Reflect.getOwnPropertyDescriptor(t[ROOT_VALUE], p)\n },\n\n })\n}\n\n\n// function getDeepUnproxiedObject (obj: any): any {\n// if (obj && typeof obj === 'object' && !Array.isArray(obj)) {\n// if (obj[ROOT_VALUE]?.[ROOT_VALUE]) {\n// console.warn('Circular reference detected in getDeepUnproxiedObject')\n//\n// return '[Circular reference]'\n// }\n//\n//\n// const r = Object.fromEntries(\n// Object.entries(obj).map(([key, value]) => {\n// // console.log('____________________getDeepUnproxiedObject', key, value, value.constructor.name)\n// if (value && typeof value === 'object' && !Array.isArray(value)) {\n// if (key === 'links') console.log('getDeepUnproxiedObject', key, value)\n//\n// // If it's a proxied object, get the unproxied value\n// return [key, getDeepUnproxiedObject(value)]\n// }\n//\n// return [key, value]\n// }),\n// )\n//\n//\n// return r\n// }\n//\n// return obj\n// }\n\n// function safeStringify (obj: any): string {\n// // use removeCircularReferences to avoid circular references\n// // const cleanedObj = removeCircularReferences(obj)\n// return JSON.stringify(safeToJson(obj))\n// //\n// // return JSON.stringify(\n// // obj,\n// // (_key, value) => {\n// // if (Array.isArray(value)) return value.map(i => safeStringify(i))\n// //\n// // if (isReactElement(value)) {\n// // // console.log('React element detected', value)\n// //\n// // return { props: safeStringify(value.props), type: typeof value.type === 'string' ? value.type : '' }\n// // }\n// //\n// // if (globalThis?.HTMLElement && value instanceof globalThis.HTMLElement) return { type: '[HTMLElement]', content: value.innerHTML }\n// //\n// // // console.log('Value', value)\n// //\n// // return value\n// // })\n// }\n\n\n\n\n// function removeCircularReferences (obj: any): any {\n// const seen = new WeakSet()\n//\n// function traverse (value: any): any {\n// if (value && typeof value === 'object') {\n// // If the object has already been seen, it's a circular reference\n// if (seen.has(value))\n// return null\n//\n// seen.add(value)\n//\n// if (Array.isArray(value))\n// return value.map(traverse)\n//\n//\n// const result: any = {}\n//\n// for (const key in value) {\n// if (Object.prototype.hasOwnProperty.call(value, key)) {\n// if (key === '_owner' && value.$$typeof) continue\n//\n// result[key] = traverse(value[key])\n// }\n// }\n//\n// return result\n// }\n//\n// // Return primitive values as-is\n// return value\n// }\n//\n// return traverse(obj)\n// }\n","\nimport { useEffect, useId, useRef, useState } from 'react'\n\nimport { nonReactiveObjectSymbol } from '../../types/shared'\nimport { proxifyStore } from '../helpers/new-proxify-store'\nimport { deepClone, safeToJson } from '../utils/object'\nimport { createCacheableSubject } from '../utils/subject'\n\nimport type { FieldPath, StoreChange } from '../../types/shared'\n\n\n\n\n// export type CervelloOptions<StoreValue extends Record<string, any>> = {\n// beforeChange?: (storeChange: StoreChange<StoreValue>) => unknown | undefined\n// afterChange?: (storeChange: Array<StoreChange<StoreValue>>) => void\n// }\n\nexport type CervelloOptions<StoreValue extends Record<string, any>> = {\n afterChange?: (storeChange: Array<StoreChange<StoreValue>>) => void\n}\n\nexport type CervelloUseStoreOptions<StoreValue extends Record<string, any>> = {\n initialValue?: (currentStore: StoreValue) => StoreValue | null,\n setValueOnMount?: (currentStore: StoreValue) => Promise<StoreValue>,\n select?:\n | Array<FieldPath<StoreValue>>\n | (() => Array<FieldPath<StoreValue>>)\n onChange?: (storeChange: Array<StoreChange<StoreValue>>) => void\n}\n\ntype MutableStoreValue<T extends Record<string, any>> = {\n $value: T\n} & T\n\n\n\n\n\n\n\n\nexport function nonReactive <T extends Record<string, any>> (initialValue: T): T {\n Object.defineProperty(initialValue, nonReactiveObjectSymbol, {\n value: true,\n enumerable: false,\n writable: false,\n configurable: false,\n })\n\n return initialValue\n}\n\n\nexport function cervello <StoreValue extends Record<PropertyKey, any>> (\n initialValue: StoreValue,\n options?: CervelloOptions<StoreValue>,\n): {\n store: MutableStoreValue<StoreValue>,\n reset: () => void,\n useStore: (options?: CervelloUseStoreOptions<StoreValue>) => MutableStoreValue<StoreValue>\n } {\n const {\n // beforeChange,\n afterChange,\n } = options ?? {}\n\n // const store$$ = createCacheableSubject<StoreChange<StoreValue>>(clonedInitialValue as any)\n const clonedInitialValue = deepClone(initialValue)\n\n const store$$ = createCacheableSubject<StoreChange<StoreValue>>()\n\n const proxiedStore = proxifyStore(\n store$$ as any,\n clonedInitialValue,\n // { beforeChange, afterChange },\n { afterChange },\n ) as MutableStoreValue<StoreValue>\n\n\n return {\n store: proxiedStore,\n reset: () => {\n proxiedStore.$value = deepClone(initialValue)\n },\n useStore: (options) => {\n const subscriberId = useId()\n const initialValue = options?.initialValue?.(proxiedStore.$value)\n const isInitialValueSet = useRef(false)\n const [, setRenderCount] = useState(0)\n\n if (!isInitialValueSet.current\n && initialValue\n && JSON.stringify(safeToJson(initialValue)) !== JSON.stringify(safeToJson(proxiedStore.$value))\n ) {\n isInitialValueSet.current = true;\n (proxiedStore as any).$$value = { id: subscriberId, newValue: initialValue }\n }\n\n const selectFieldPaths = useRef(\n (typeof options?.select === 'function'\n ? options?.select?.()\n : options?.select)\n ?? [],\n )\n\n\n const selectedFieldPathsForNestedObjects = useRef(\n selectFieldPaths.current\n .filter(fp => fp.includes('.*'))\n .map(fp => fp.replace('.*', '')),\n )\n\n const reRender = (): void => {\n setRenderCount(p => p + 1)\n }\n\n\n useEffect(() => {\n if (options?.setValueOnMount) {\n void options.setValueOnMount(proxiedStore.$value).then((value) => {\n proxiedStore.$value = value\n }).catch((err) => {\n console.error('Error setting initial value on mount', err)\n })\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [])\n\n\n // Same implementation as useSyncExternalStore but with useEffect\n useEffect(() => {\n const subscription = store$$.subscribe({\n id: subscriberId,\n next: (sc) => {\n const storeChanges = Array.isArray(sc)\n ? sc as Array<StoreChange<StoreValue>>\n : [sc]\n\n if (!options?.select) {\n reRender()\n options?.onChange?.(storeChanges)\n\n return\n }\n\n if (storeChanges.some(nextChange => (\n nextChange.change.fieldPath === 'root'\n || selectFieldPaths.current.includes(nextChange.change.fieldPath))\n || selectedFieldPathsForNestedObjects.current.find(fp => nextChange.change.fieldPath.startsWith(fp)),\n )) {\n reRender()\n options?.onChange?.(storeChanges)\n }\n },\n })\n\n return () => {\n subscription.unsubscribe()\n }\n\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [options?.select, options?.onChange])\n\n return proxiedStore\n },\n }\n}\n\n","\ntype Noop = () => void\n\n\ntype Observer<T> = {\n id: string\n next: (value: T, subscriberId?: string) => void\n}\n\ntype Subscription = {\n unsubscribe: Noop\n}\n\nexport type CacheableSubject<T> = {\n // getValue: () => T\n subscribe: (value: Observer<T>) => Subscription\n // unSubscribeAll: Noop\n} & Omit<Observer<T>, 'id'>\n\n\n\nexport function createCacheableSubject<T> (/* defaultValue: T/*, getValueOnSubscribe = false */): CacheableSubject<T> {\n let isFlushing = false\n let itemsToFlush: Array<{ newValue: T, subscriberId?: string }> = []\n\n let observerList: Array<Observer<T>> = []\n // let value = defaultValue\n\n // const getValue = (): T => value\n\n const next = (newValue: T, subscriberId?: string): void => {\n // value = newValue\n\n itemsToFlush.push({ newValue, subscriberId })\n\n if (!isFlushing) {\n isFlushing = true\n\n void Promise.resolve().then(() => {\n observerList.forEach((o) => {\n // Filter changes that were sent by the same subscriberId (initialValue function call)\n const nonInitiallySentBySubscriber = itemsToFlush.filter(item => item.subscriberId !== o.id)\n\n if (!nonInitiallySentBySubscriber.length) return\n\n o.next(nonInitiallySentBySubscriber.map(i => i.newValue) as T)\n })\n itemsToFlush = []\n isFlushing = false\n })\n\n // void Promise.resolve(subscriberId).then((subscriberId) => {\n // console.log('//// promise.resolve then', { subscriberId: s.id })\n // observerList.forEach((o) => {\n // console.log('//// CacheableSubject (forEach) flushing', { observerId: o.id, subscriberId: s.id })\n // if (o.id === subscriberId) return\n //\n // o.next(itemsToFlush as T)\n // })\n // itemsToFlush = []\n // isFlushing = false\n // })\n\n // void Promise.resolve().then(() => {\n // console.log('//// promise.resolve then')\n // observerList.forEach((o) => {\n // const nonInitiallySentBySubscriber = itemsToFlush.filter(item => item.subscriberId !== o.id)\n //\n // if (nonInitiallySentBySubscriber.length === 0) return\n //\n // o.next(nonInitiallySentBySubscriber.map(i => i.newValue) as T)\n // })\n // itemsToFlush = []\n // isFlushing = false\n // })\n }\n }\n\n const subscribe = (observer: Observer<T>): Subscription => {\n // Push cached value on subscribe\n // if (getValueOnSubscribe) observer.next(value)\n\n // Store the observer to be notified\n observerList.push(observer)\n\n return {\n unsubscribe: () => {\n observerList = observerList.filter(o => o.id !== observer.id)\n },\n }\n }\n\n // const unSubscribeAll = (): void => {\n // observerList = []\n // }\n\n return {\n // getValue,\n next,\n subscribe,\n // unSubscribeAll,\n }\n}\n"],"names":["nonReactiveObjectSymbol","Symbol","deepClone","obj","newObj","Array","isArray","map","item","isReactObjectLikeNode","isObject","isReactElement","objKeys","Object","keys","includes","some","k","startsWith","entries","forEach","_ref","getOwnPropertySymbols","symbol","$$typeof","isValidReactiveObject","value","safeToJson","o","props","type","globalThis","HTMLElement","content","innerHTML","_ref2","v","hasOwn","call","bind","hasOwnProperty","ROOT_VALUE","proxifyStore","store$$","objectToProxify","opts","_opts$nestedFieldPath","_objectWithRootValue","nestedFieldPath","objectWithRootValue","rootFunctions","fieldPath","fromEntries","filter","Proxy","get","targetObject","propName","receiver","target","propertyValue","Reflect","_opts$parentObjectToP","_$fieldPath","proxiedNestedObject","parentObjectToProxify","afterChange","set","parentObject","key","newValue","_opts$parentObjectToP2","_opts","isRootTarget","previousValue","next","storeValue","change","id","JSON","stringify","_extends","realInnerObject","$value","nextStoreChange","replace","has","t","p","ownKeys","getOwnPropertyDescriptor","initialValue","options","isFlushing","itemsToFlush","clonedInitialValue","subscriberId","push","resolve","then","observerList","nonInitiallySentBySubscriber","length","i","subscribe","observer","unsubscribe","proxiedStore","store","reset","useStore","useId","isInitialValueSet","useRef","setRenderCount","useState","current","$$value","selectFieldPaths","select","selectedFieldPathsForNestedObjects","fp","reRender","useEffect","setValueOnMount","err","console","error","subscription","sc","storeChanges","onChange","nextChange","find","defineProperty","enumerable","writable","configurable"],"mappings":"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"}
|
|
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","\nimport { nonReactiveObjectSymbol } from '../../types/shared'\nimport { INTERNAL_VALUE_PROP } from '../helpers/constants'\n\n\n/**\n * Structural clone for nonReactive() subtrees: preserves complex values\n * (Date, Map, Set) and keeps circular references/aliases intact by mapping\n * each source object to its clone. Functions, React nodes and any other\n * class instance (DOM elements included, via the constructor check) are\n * kept by reference β they cannot be cloned safely\n */\nfunction cloneNonReactive (obj: any, refs: WeakMap<object, any>): any {\n if (!obj || typeof obj !== 'object') return obj\n\n if (refs.has(obj)) return refs.get(obj)\n\n if (obj instanceof Date) return new Date(obj.getTime())\n\n if (isReactObjectLikeNode(obj)) return obj\n\n if (Array.isArray(obj)) {\n const arr: Array<any> = []\n\n refs.set(obj, arr)\n obj.forEach((item, idx) => { arr[idx] = cloneNonReactive(item, refs) })\n\n return arr\n }\n\n if (obj instanceof Map) {\n const map = new Map()\n\n refs.set(obj, map)\n obj.forEach((v, k) => { map.set(cloneNonReactive(k, refs), cloneNonReactive(v, refs)) })\n\n return map\n }\n\n if (obj instanceof Set) {\n const set = new Set()\n\n refs.set(obj, set)\n obj.forEach((v) => { set.add(cloneNonReactive(v, refs)) })\n\n return set\n }\n\n // Other class instances cannot be cloned generically: keep them by reference\n if (obj.constructor && obj.constructor !== Object) return obj\n\n const o: Record<PropertyKey, any> = {}\n\n refs.set(obj, o)\n\n // Indexed loops: no [key, value] tuple per property (Object.entries) nor\n // a closure per object (forEach)\n const keys = Object.keys(obj)\n\n for (let i = 0; i < keys.length; i++)\n o[keys[i]] = cloneNonReactive(obj[keys[i]], refs)\n\n const symbols = Object.getOwnPropertySymbols(obj)\n\n for (let i = 0; i < symbols.length; i++)\n o[symbols[i]] = obj[symbols[i]]\n\n return o\n}\n\n\n/**\n * Clones all the provided object and nested properties and it also\n * iterates nested arrays to deepClone them\n *\n * Circular references are considered invalid store values, so they are cut\n * to `null` instead of recursing forever. The exceptions are React\n * elements/nodes (kept by reference) and nonReactive()-wrapped objects,\n * which are cloned structurally so complex values (Date, Map, Set, circular\n * references...) survive intact β this keeps the store copy decoupled from\n * the caller's object and allows reset() to restore the initial state\n *\n * @param obj - base object to be cloned\n * @param ancestors - objects of the current traversal path, to detect cycles\n * @returns new cloned object with new reference\n */\nexport function deepClone <T> (obj: T, ancestors = new WeakSet<object>()): T {\n if (!obj || typeof obj !== 'object')\n return obj\n\n if ((obj as any)[nonReactiveObjectSymbol]) {\n const cloned = cloneNonReactive(obj, new WeakMap())\n\n // Keep the mark when the wrapper itself is an exotic object (Map, array...)\n // whose clone branch does not copy symbol properties\n if (!cloned[nonReactiveObjectSymbol]) cloned[nonReactiveObjectSymbol] = true\n\n return cloned\n }\n\n if (ancestors.has(obj))\n return null as T\n\n if (Array.isArray(obj)) {\n ancestors.add(obj)\n const clonedArray = obj.map(item => deepClone(item, ancestors))\n\n ancestors.delete(obj)\n\n return clonedArray as T\n }\n\n // Keys are computed once and shared with the react-node check, which had\n // to allocate its own Object.keys per visited object before\n const keys = Object.keys(obj)\n\n if (isReactObjectLikeNode(obj, keys)) return obj\n\n ancestors.add(obj)\n\n const newObj = {} as any\n\n // Indexed loops (keys and symbols): no [key, value] tuple per property\n // (Object.entries) nor a closure per object (forEach) in this hot path\n for (let i = 0; i < keys.length; i++)\n newObj[keys[i]] = deepClone((obj as any)[keys[i]], ancestors)\n\n const symbols = Object.getOwnPropertySymbols(obj)\n\n for (let i = 0; i < symbols.length; i++)\n newObj[symbols[i]] = (obj as any)[symbols[i]]\n\n ancestors.delete(obj)\n\n return newObj as T\n}\n\n// function copyBuffer (cur: ArrayBufferView) {\n// if (cur instanceof Buffer)\n// return Buffer.from(cur)\n//\n//\n// return new cur.constructor(cur.buffer.slice(), cur.byteOffset, cur.length)\n// }\n\n\n// INFO: From `rfdc` (really-fast-deep-clone) package for faster cloning taking care of circular references\n// export function deepClone2 <T> (obj: T): T {\n// const refs: Array<any> = []\n// const refsNew: Array<any> = []\n//\n// const constructorHandlers = new Map()\n//\n// constructorHandlers.set(Date, (o: string | number | Date) => new Date(o))\n// constructorHandlers.set(Map, (o: Iterable<unknown> | ArrayLike<unknown>, fn: any) => new Map(cloneArray(Array.from(o), fn)))\n// constructorHandlers.set(Set, (o: Iterable<unknown> | ArrayLike<unknown>, fn: any) => new Set(cloneArray(Array.from(o), fn)))\n//\n// let handler = null\n//\n// return clone(obj)\n//\n// function cloneArray (a: any, fn: any): any {\n// const keys = Object.keys(a)\n// const a2 = new Array(keys.length) as any\n//\n// for (let i = 0; i < keys.length; i++) {\n// const k = keys[i]\n// const cur = a[k]\n//\n// if (typeof cur !== 'object' || cur === null) {\n// a2[k] = cur\n// } else if (cur.constructor !== Object && (handler = constructorHandlers.get(cur.constructor))) {\n// a2[k] = handler(cur, fn)\n// // } else if (ArrayBuffer.isView(cur)) {\n// // a2[k] = copyBuffer(cur)\n// } else {\n// const index = refs.indexOf(cur)\n//\n// if (index !== -1)\n// a2[k] = refsNew[index]\n// else\n// a2[k] = fn(cur)\n// }\n// }\n//\n// return a2\n// }\n//\n// function clone (o: any): any {\n// if (typeof o !== 'object' || o === null) return o\n// if (Array.isArray(o)) return cloneArray(o, clone)\n// if (o.constructor !== Object && (handler = constructorHandlers.get(o.constructor)))\n// return handler(o, clone)\n//\n// const o2 = {} as any\n//\n// refs.push(o)\n// refsNew.push(o2)\n//\n//\n// Object.getOwnPropertySymbols(o).forEach((symbol) => {\n// o2[symbol] = (o)[symbol]\n// })\n//\n// for (const k in o) {\n// if (!Object.hasOwnProperty.call(o, k)) continue\n// const cur = o[k]\n//\n//\n// if (typeof cur !== 'object' || cur === null) {\n// o2[k] = cur\n// } else if (cur.constructor !== Object && (handler = constructorHandlers.get(cur.constructor))) {\n// o2[k] = handler(cur, clone)\n// // } else if (ArrayBuffer.isView(cur)) {\n// // o2[k] = copyBuffer(cur)\n// } else {\n// const i = refs.indexOf(cur)\n//\n// if (i !== -1)\n// o2[k] = refsNew[i]\n// else\n// o2[k] = clone(cur)\n// }\n// }\n// refs.pop()\n// refsNew.pop()\n//\n//\n// return o2\n// }\n// }\n\n/**\n * Guard to check is variable is an object\n * @param obj - variable to be checked\n * @returns boolean\n */\nexport const isObject = (obj: unknown): obj is Record<string | symbol, unknown> => (\n obj !== null\n && typeof obj === 'object'\n && !Array.isArray(obj)\n)\n\n\nexport const isReactElement = (obj: unknown): boolean => {\n if (!isObject(obj)) return false\n\n return !!(obj.$$typeof)\n}\n\n\nexport function isReactObjectLikeNode (obj: unknown, precomputedKeys?: Array<string>): boolean {\n if (!isObject(obj)) return false\n if (isReactElement(obj)) return true\n\n // Callers traversing the object can pass their own Object.keys() result to\n // avoid allocating the key array twice per visited object\n const objKeys = precomputedKeys ?? Object.keys(obj)\n const isReactObjNode = (objKeys.includes('tag') && objKeys.includes('containerInfo'))\n || objKeys.some(k => k.startsWith('__reactContainer'))\n || (objKeys.includes('tag') && objKeys.includes('stateNode'))\n\n return isReactObjNode\n}\n\n\nexport function isValidReactiveObject <T extends Record<string, any>> (value: T): boolean {\n return isObject(value) && !isReactElement(value) && !(value as any)[nonReactiveObjectSymbol]\n}\n\n\n\n/**\n * Returns the actual target value instead of root\n * object with internals props like $$value$$\n *\n * @param target - object from subscription or proxy\n * @returns actual value\n */\nexport const okTarget = (target: any): any => target[INTERNAL_VALUE_PROP] ?? target\n\n\n\n\n/**\n * Gets an object with just the properties requested\n * instead of the full object\n *\n * @param properties - object properties\n * @param obj - target to get the properties\n * @returns New object with just the requested properties\n */\nexport function getPartialObjectFromProperties<T> (properties: Array<keyof T>, obj: T): any {\n return properties.reduce<any>((acc, curr) => {\n acc[curr] = obj[curr]\n\n return acc\n }, {})\n}\n\n\n\n/**\n * Walks a dotted path ('address.city', 'meta.tags') inside an object.\n * Returns undefined when any segment is missing or an intermediate node\n * is not traversable (primitive/null)\n * @param obj - object to walk\n * @param path - dotted field path, relative to obj\n * @returns the value at the path, or undefined\n */\nexport function getValueAtPath (obj: any, path: string): any {\n const segments = path.split('.')\n\n let current = obj\n\n for (let i = 0; i < segments.length; i++) {\n if (current === null || typeof current !== 'object') return undefined\n current = current[segments[i]]\n }\n\n return current\n}\n\n\n\n\nconst stringify = (obj: any): string => JSON.stringify(safeToJson(obj))\n\n\n// Nodes the JSON projection treats specially (React elements, React\n// internals, DOM elements): compared through safeToJson instead of key-by-key\nconst isJsonExoticNode = (obj: any, keys: Array<string>): boolean => (\n isReactObjectLikeNode(obj, keys)\n || (!!globalThis?.HTMLElement && obj instanceof globalThis.HTMLElement)\n)\n\n\n/**\n * Structural equivalent of comparing the two safeToJson projections, with\n * early exit and zero string/tree allocations (this runs on every `$value`\n * set and nested-object reassignment): `undefined`/function-valued keys are\n * skipped (JSON drops them), such array elements compare as `null`, complex\n * leaves (Date, Map, Set...) are opaque and circular references only match\n * when both sides cycle. React/DOM nodes fall back to their safeToJson\n * projection. Key order is irrelevant and NaN equals NaN β both intended\n * divergences from the previous stringify-based comparison\n */\nfunction deepEqualJson (a: any, b: any, aSeen: WeakSet<object> | null, bSeen: WeakSet<object> | null): boolean {\n if (a === b) return true\n\n if (Number.isNaN(a)) return Number.isNaN(b)\n\n if (!a || !b || typeof a !== 'object' || typeof b !== 'object') return false\n\n // Circular reference (cut by the JSON traversal): equal only if both cycle\n const aCycles = !!aSeen && aSeen.has(a)\n const bCycles = !!bSeen && bSeen.has(b)\n\n if (aCycles || bCycles) return aCycles && bCycles\n\n const aIsArray = Array.isArray(a)\n\n if (aIsArray !== Array.isArray(b)) return false\n\n // Ancestor tracking is paid lazily, right before the first recursion into\n // an object-typed value: flat objects (the hot case) never touch a WeakSet\n let tracked = false\n\n let result = true\n\n if (aIsArray) {\n result = a.length === b.length\n\n for (let i = 0; result && i < a.length; i++) {\n const aItem = a[i] === undefined || typeof a[i] === 'function' ? null : a[i]\n const bItem = b[i] === undefined || typeof b[i] === 'function' ? null : b[i]\n\n if (!tracked && ((aItem && typeof aItem === 'object') || (bItem && typeof bItem === 'object'))) {\n tracked = true\n aSeen = aSeen ?? new WeakSet()\n bSeen = bSeen ?? new WeakSet()\n aSeen.add(a)\n bSeen.add(b)\n }\n\n result = deepEqualJson(aItem, bItem, aSeen, bSeen)\n }\n } else {\n const aKeys = Object.keys(a)\n const bKeys = Object.keys(b)\n\n if (isJsonExoticNode(a, aKeys) || isJsonExoticNode(b, bKeys)) {\n result = stringify(a) === stringify(b)\n } else {\n // Compare by key name (order-independent), skipping values JSON drops.\n // `serializableBalance` nets a's comparable keys against b's, so b\n // cannot hide extra keys behind matching ones\n let serializableBalance = 0\n\n for (let i = 0; result && i < aKeys.length; i++) {\n const aValue = a[aKeys[i]]\n\n if (aValue === undefined || typeof aValue === 'function') continue\n\n serializableBalance++\n const bValue = b[aKeys[i]]\n\n if (bValue === undefined || typeof bValue === 'function') {\n result = false\n } else {\n if (!tracked && ((aValue && typeof aValue === 'object') || (bValue && typeof bValue === 'object'))) {\n tracked = true\n aSeen = aSeen ?? new WeakSet()\n bSeen = bSeen ?? new WeakSet()\n aSeen.add(a)\n bSeen.add(b)\n }\n\n result = deepEqualJson(aValue, bValue, aSeen, bSeen)\n }\n }\n\n if (result) {\n for (let i = 0; i < bKeys.length; i++) {\n const bValue = b[bKeys[i]]\n\n if (bValue !== undefined && typeof bValue !== 'function') serializableBalance--\n }\n\n result = serializableBalance === 0\n }\n }\n }\n\n if (tracked) {\n (aSeen as WeakSet<object>).delete(a);\n (bSeen as WeakSet<object>).delete(b)\n }\n\n return result\n}\n\n\n/**\n * Compare 2 provided objects by content\n * (safe against circular references and React internals)\n * @param a - first object\n * @param b - second object\n * @returns boolean\n */\nexport const contentComparer = (a: any, b: any): boolean => deepEqualJson(a, b, null, null)\n\n\n\n\nexport function safeToJson (obj: any, ancestors = new WeakSet<object>()): Record<string, any> {\n if (typeof obj !== 'object' || obj == null)\n return obj\n\n // Circular reference: cut the cycle to keep the traversal finite\n if (ancestors.has(obj))\n return null as any\n\n if (Array.isArray(obj)) {\n ancestors.add(obj)\n const arr = obj.map(item => safeToJson(item, ancestors))\n\n ancestors.delete(obj)\n\n return arr\n }\n\n if (isReactElement(obj)) {\n ancestors.add(obj)\n const element = { props: safeToJson(obj.props, ancestors), type: typeof obj.type === 'string' ? obj.type : '' }\n\n ancestors.delete(obj)\n\n return element\n }\n\n if (globalThis?.HTMLElement && obj instanceof globalThis.HTMLElement) return { type: '[HTMLElement]', content: obj.innerHTML }\n\n // Keys computed once, shared between the react-node check and the copy\n // loop (no [key, value] tuple per property either β hot path)\n const keys = Object.keys(obj)\n\n // React internals (fibers, containers...) are huge and circular: treat them\n // as opaque values instead of traversing them (same rule as deepClone)\n if (isReactObjectLikeNode(obj, keys))\n return { type: '[ReactNode]' }\n\n const o: Record<string, any> = {}\n\n ancestors.add(obj)\n\n for (let i = 0; i < keys.length; i++)\n o[keys[i]] = safeToJson(obj[keys[i]], ancestors)\n\n ancestors.delete(obj)\n\n return o\n}\n","\nimport { contentComparer, deepClone, isValidReactiveObject, safeToJson } from '../utils/object'\n\nimport type { StoreChange } from '../../types/shared'\nimport type { CacheableSubject } from '../utils/subject'\n\n\n\n// INFO: !Internal only.\n// Read through a proxy of this store, returns the raw object it currently wraps\nexport const RAW_VALUE = Symbol('rawValue')\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 // Nested proxies only: the parent's `live` resolver, the parent proxy\n // itself and the key this proxy sits under\n parent?: () => any\n parentProxy?: any\n key?: PropertyKey\n // Live raw of the whole store (for `storeValue` in emitted changes)\n rootRaw?: () => any\n afterChange?: (storeChange: Array<StoreChange<T>>) => void\n } = {},\n): T {\n const fieldPath = opts.nestedFieldPath ?? 'root'\n const isRoot = opts.parent === undefined\n const key = opts.key as PropertyKey\n\n // Emitted paths are root-relative: precomputing the prefix (dropping the\n // leading 'root.') avoids a string scan + replace on every write\n const emitPrefix = isRoot ? '' : `${fieldPath.slice(5)}.`\n\n // The Proxy target is just a shell: the data lives in the `raw` closure\n const shell = {} as unknown as T\n\n // Child proxies are cached here (keyed by property name) instead of being\n // written back into the raw data, so the store data never holds Proxy\n // instances. Entries are never dropped: a child proxy is a live view of\n // `parent[key]` (see `resolveRaw`), so its identity survives reassigning the\n // field and even replacing the whole store. The raw the slot held when the\n // entry was last refreshed is kept for the read fast path\n const childProxies = new Map<PropertyKey, { proxy: any, raw: any }>()\n\n // Raw object this proxy currently wraps (the root's is the whole store)\n let raw: any = objectToProxify\n let isDetached = false\n // Store version a nested proxy last resolved its slot at\n // every store mutation bumps it, so while it is unchanged `raw` is still the live one\n // and reads pay a single property compare (no call)\n let seenVersion = -1\n\n // Cold path (nested proxies, after a store write)\n // re-read the slot on the parent's live raw.\n // When the field, an ancestor or the whole store\n // ($value / reset / initialValue seed) was reassigned, a captured handle\n // keeps reading and writing the live data instead of a disconnected\n // object. Proxies of this store injected as data (e.g.\n // `store.a = { ...store.a }` spreads child proxies) are healed on the way\n const revalidate = (): void => {\n // Set before walking\n // healing a proxy reads through its traps, which may\n // resolve back into this one (self or mutual injection) β the re-entry\n // then sees an up-to-date version and answers with the current raw\n seenVersion = store$$.state.version\n\n // The root IS the live data: nothing to walk (keeps the hot-path check\n // below free of an `isRoot` branch)\n if (isRoot) return\n\n const parent = opts.parent!()\n let liveValue = parent === undefined ? undefined : parent[key]\n\n if (liveValue !== raw && isValidReactiveObject(liveValue)) {\n const injected = liveValue[RAW_VALUE]\n\n if (injected) parent[key] = liveValue = injected\n\n raw = liveValue\n }\n\n // The slot no longer holds an object (null, primitive, array,\n // nonReactive, React element) or an ancestor is gone\n isDetached = liveValue !== raw\n }\n\n const resolveRaw = (): any => {\n if (store$$.state.version !== seenVersion) revalidate()\n\n return raw\n }\n\n // Same as `resolveRaw` but undefined when this path no longer exists in the store\n // writes through a detached proxy are dropped instead of emitting a\n // change that is not in the store\n const liveRawObject = (): any => {\n const value = resolveRaw()\n\n return isDetached ? undefined : value\n }\n\n const rootRaw = opts.rootRaw ?? ((): any => raw)\n\n // Created once per proxy (a fresh closure per read was allocated before)\n const toJson = (): any => safeToJson(resolveRaw())\n\n // Bound functions are cached per raw function so repeated reads return the\n // same reference (stable identity for React deps) instead of re-binding on\n // every access. Keyed by the raw function: reassigning the property to a\n // different function re-binds automatically\n const boundFunctions = new WeakMap<(...args: Array<any>) => any, (...args: Array<any>) => any>()\n\n const rootFunctions = isRoot\n ? Object.fromEntries(Object.entries(objectToProxify).filter(([,v]) => typeof v === 'function'))\n : {}\n\n const emit = (change: StoreChange<T>): void => {\n store$$.next(change)\n opts.afterChange?.([change])\n }\n\n return new Proxy(shell, {\n get (_, propName, receiver) {\n // Inlined `resolveRaw()`: this is the hottest path of the library\n if (store$$.state.version !== seenVersion) revalidate()\n\n const target = raw\n\n if (typeof propName === 'symbol') {\n if (propName === RAW_VALUE) return target\n\n return target[propName]\n }\n\n // INFO: !Internal only.\n // Used to get the fieldPath of the object (it means it's a proxified object)\n if (propName === '_$fieldPath') return fieldPath\n\n // Called when the object is converted to JSON or string (i.e. JSON.stringify).\n // safeToJson removes react-elements with circular references before\n // stringifying to prevent JSON.stringify(storeProxy) from failing\n if (propName === 'toJSON') return toJson\n\n // Get the whole store value without proxies\n if (propName === '$value')\n return deepClone(target)\n\n let propertyValue = target[propName]\n\n if (typeof propertyValue === 'function') {\n let boundFunction = boundFunctions.get(propertyValue)\n\n if (!boundFunction) {\n // Bound to the proxy (receiver), so `this.prop` inside store\n // functions keeps reading/writing through the traps (reactive)\n boundFunction = (propertyValue as () => any).bind(receiver)\n boundFunctions.set(propertyValue, boundFunction)\n }\n\n return boundFunction\n }\n\n if (propertyValue !== null && typeof propertyValue === 'object') {\n const entry = childProxies.get(propName)\n\n if (entry !== undefined && entry.raw === propertyValue) return entry.proxy\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 // Proxy of this store injected as data by the user: heal the slot\n // with the raw object it wraps, so the store data stays Proxy-free\n const injectedProxy = propertyValue[RAW_VALUE]\n\n if (injectedProxy) target[propName] = propertyValue = injectedProxy\n\n // Reassigned field: keep the child's identity (it resolves the new\n // raw on its own) and just refresh the fast-path key\n if (entry !== undefined) {\n entry.raw = propertyValue\n\n return entry.proxy\n }\n\n const child = proxifyStore(\n store$$ as any,\n propertyValue,\n {\n nestedFieldPath: `${fieldPath}.${propName}`,\n parent: liveRawObject,\n parentProxy: receiver,\n key: propName,\n rootRaw,\n afterChange: opts.afterChange,\n },\n )\n\n childProxies.set(propName, { proxy: child, raw: propertyValue })\n\n return child\n }\n }\n\n return propertyValue\n },\n\n\n set (_, propName, newValue) {\n if (typeof propName === 'symbol') return true\n\n // Keep raw data clean: if a proxy of this store is assigned as a value,\n // store the raw object it wraps instead of the Proxy instance (the\n // typeof guard lets primitive writes skip the symbol-prop lookup)\n const value = newValue !== null && typeof newValue === 'object'\n ? newValue[RAW_VALUE] ?? newValue\n : newValue\n\n // INFO: !Internal only.\n // Used to set the value of the store without notifying the current subscriber (value.id)\n if (propName === '$$value' && isRoot) {\n const previousValue = raw\n\n // Same merge as `$value`: top-level store functions are preserved when\n // the new value (e.g. from useStore's initialValue) does not include them\n raw = Object.assign({}, rootFunctions, deepClone(value.newValue))\n\n const seedChange = {\n storeValue: raw,\n change: {\n fieldPath: 'root' as any,\n newValue: value.newValue,\n previousValue,\n },\n }\n\n store$$.next(seedChange, value.id)\n\n // Seeds are render-phase writes (useStore's initialValue): the hook is\n // deferred so user code never runs inside a React render\n if (opts.afterChange) queueMicrotask(() => { opts.afterChange!([seedChange]) })\n\n return true\n }\n\n if (propName === '$value') {\n // Nested: replacing this object is a plain write into the parent\n if (!isRoot) {\n opts.parentProxy[key] = value\n\n return true\n }\n\n const previousValue = raw\n\n if (value === previousValue || contentComparer(value, previousValue)) return true\n\n // Cloned like the initial value: the store never aliases the caller's\n // object and any proxies spread into it (`{ ...store }`) are unwrapped.\n // Object.assign instead of spread: it avoids shipping Babel's\n // `_extends` helper in the bundle\n raw = Object.assign({}, rootFunctions, deepClone(value))\n\n emit({\n storeValue: raw,\n change: {\n fieldPath: 'root' as any,\n newValue: value,\n previousValue,\n },\n })\n\n return true\n }\n\n const validRawObject = liveRawObject()\n\n // Detached handle (its path is gone from the store): drop the write\n if (validRawObject === undefined) return true\n\n const previousValue = validRawObject[propName]\n\n if (previousValue === value) return true\n\n // Content-equal object writes are no-ops (arrays, nonReactive objects\n // and React elements always notify)\n if (isValidReactiveObject(value) && contentComparer(value, previousValue)) return true\n\n validRawObject[propName] = value\n\n emit({\n storeValue: rootRaw(),\n change: {\n fieldPath: (emitPrefix + propName) as any,\n newValue: value,\n previousValue,\n },\n })\n\n return true\n },\n\n has (_, p) {\n return Reflect.has(resolveRaw(), p)\n },\n\n ownKeys () {\n return Reflect.ownKeys(resolveRaw())\n },\n\n getOwnPropertyDescriptor (_, p) {\n return Reflect.getOwnPropertyDescriptor(resolveRaw(), p)\n },\n\n })\n}\n","\nimport { useEffect, useId, useRef, useState } from 'react'\n\nimport { nonReactiveObjectSymbol } from '../../types/shared'\nimport { proxifyStore, RAW_VALUE } from '../helpers/new-proxify-store'\nimport { contentComparer, deepClone, getValueAtPath } from '../utils/object'\nimport { createCacheableSubject } from '../utils/subject'\n\nimport type { FieldPath, StoreChange } from '../../types/shared'\n\n\n\n\n\nexport type CervelloOptions<StoreValue extends Record<string, any>> = {\n afterChange?: (storeChange: Array<StoreChange<StoreValue>>) => void\n}\n\nexport type CervelloUseStoreOptions<StoreValue extends Record<string, any>> = {\n initialValue?: (currentStore: StoreValue) => StoreValue | null,\n setValueOnMount?: (currentStore: StoreValue) => Promise<StoreValue>,\n select?:\n | Array<FieldPath<StoreValue>>\n | (() => Array<FieldPath<StoreValue>>)\n onChange?: (storeChange: Array<StoreChange<StoreValue>>) => void\n}\n\ntype MutableStoreValue<T extends Record<string, any>> = {\n $value: T\n} & T\n\n\n\n\n\n\n\n\nexport function nonReactive <T extends Record<string, any>> (initialValue: T): T {\n Object.defineProperty(initialValue, nonReactiveObjectSymbol, {\n value: true,\n enumerable: false,\n writable: false,\n configurable: false,\n })\n\n return initialValue\n}\n\n\nexport function cervello <StoreValue extends Record<PropertyKey, any>> (\n initialValue: StoreValue,\n options?: CervelloOptions<StoreValue>,\n): {\n store: MutableStoreValue<StoreValue>,\n reset: () => void,\n useStore: (options?: CervelloUseStoreOptions<StoreValue>) => MutableStoreValue<StoreValue>\n } {\n const {\n afterChange,\n } = options ?? {}\n\n const clonedInitialValue = deepClone(initialValue)\n\n const store$$ = createCacheableSubject<StoreChange<StoreValue>>()\n\n const proxiedStore = proxifyStore(\n store$$ as any,\n clonedInitialValue,\n { afterChange },\n ) as MutableStoreValue<StoreValue>\n\n\n return {\n store: proxiedStore,\n reset: () => {\n // The `$value` setter already stores a deep clone\n proxiedStore.$value = initialValue\n },\n useStore: (options) => {\n const subscriberId = useId()\n const isInitialValueSet = useRef(false)\n const [, setRenderCount] = useState(0)\n\n // Latest options are read through this ref by the subscription (created\n // once per mount), so callbacks like `onChange` are never stale closures\n const optionsRef = useRef(options)\n\n optionsRef.current = options\n\n // useState-like semantics: `initialValue` runs only on the first render\n // (SSR included), so the store traversals it needs (clone + compare)\n // are paid once per mount instead of on every re-render\n if (!isInitialValueSet.current) {\n isInitialValueSet.current = true\n\n const initialValue = options?.initialValue?.(proxiedStore.$value)\n\n // Compared against the raw value (not `$value`): contentComparer is\n // already cycle-safe, so this skips a second full deep clone per mount\n if (initialValue && !contentComparer(initialValue, (proxiedStore as any)[RAW_VALUE]))\n (proxiedStore as any).$$value = { id: subscriberId, newValue: initialValue }\n }\n\n // Version of the store this render is based on. Captured AFTER the\n // `initialValue` seed so the component's own seed does not re-trigger it\n const seenVersion = useRef(0)\n\n seenVersion.current = store$$.version()\n\n // `select` is frozen from the first render (computed lazily, once)\n const selectFieldPaths = useRef<Array<FieldPath<StoreValue>> | null>(null)\n\n if (selectFieldPaths.current === null) {\n selectFieldPaths.current = (\n typeof options?.select === 'function'\n ? options.select()\n : options?.select\n ) ?? []\n }\n\n const selectedFieldPathsForNestedObjects = useRef<Array<string> | null>(null)\n\n if (selectedFieldPathsForNestedObjects.current === null) {\n // The trailing dot is kept ('address.*' -> 'address.') so matching is\n // a single startsWith against the dotted changed path\n selectedFieldPathsForNestedObjects.current = selectFieldPaths.current\n .filter(fp => fp.includes('.*'))\n .map(fp => fp.replace('*', ''))\n }\n\n const reRender = (): void => {\n setRenderCount(p => p + 1)\n }\n\n\n useEffect(() => {\n if (options?.setValueOnMount) {\n void options.setValueOnMount(proxiedStore.$value).then((value) => {\n proxiedStore.$value = value\n }).catch((err) => {\n console.error('Error setting initial value on mount', err)\n })\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [])\n\n\n // Same implementation as useSyncExternalStore but with useEffect.\n // Subscribed once per mount: `select` is frozen from the first render\n // and the latest callbacks are read through `optionsRef`\n useEffect(() => {\n // All three lists are frozen from the first render, so they can be\n // captured once per subscription instead of on every notification\n const selectedPaths = selectFieldPaths.current ?? []\n const wildcardPrefixes = selectedFieldPathsForNestedObjects.current ?? []\n\n // Targets for ancestor-change comparison: exact paths as-is, wildcards\n // reduced to their base ('address.*' -> 'address')\n const compareTargets = selectedPaths.map(fp => fp.replace('.*', ''))\n\n // Changes flushed between the render and this effect (React yields\n // before the passive-effects task when a commit exceeds the frame\n // budget) were emitted before the subscription existed β recover them\n // with one re-render, since reads through the proxy are always live\n if (store$$.version() !== seenVersion.current) reRender()\n\n const subscription = store$$.subscribe({\n id: subscriberId,\n next: (storeChanges) => {\n const currentOptions = optionsRef.current\n\n // Already rendered after every write flushed so far (e.g. a\n // handler calls setState and then writes to the store: React\n // renders the SyncLane update before this microtask runs, and the\n // render reads the store live) β same check as\n // useSyncExternalStore's `checkIfSnapshotChanged`, so the render\n // is skipped while `onChange` still fires\n const needsRender = store$$.version() !== seenVersion.current\n\n if (!currentOptions?.select) {\n if (needsRender) reRender()\n currentOptions?.onChange?.(storeChanges)\n\n return\n }\n\n if (storeChanges.some((nextChange) => {\n const changedPath = nextChange.change.fieldPath\n const dottedPath = `${changedPath}.`\n\n // Path-level matches: the set trap already guaranteed the\n // written value changed content, so no re-comparison is needed.\n // Checked before the 'root' branch: `select` can only contain\n // 'root' for a top-level field literally named `root`, and\n // whole-store changes then over-render (safe) instead of being\n // refined against the field's value\n if (selectedPaths.includes(changedPath)) return true\n\n // 'address.*' (kept as 'address.') matches 'address' and\n // 'address.<nested>', but not a sibling field sharing the\n // prefix (e.g. 'addressLine')\n if (wildcardPrefixes.some(fp => dottedPath.startsWith(fp))) return true\n\n // Ancestor changes ('root', or 'address' for 'address.city'):\n // the selected slice may or may not have changed inside the\n // reassigned object, so re-render only if its content differs.\n // Compared at flush time: `newValue` is the live raw, so several\n // same-microtask writes are seen in their final (converged)\n // state β same guarantee the batch already gives for storeValue\n return compareTargets.some((target) => {\n if (changedPath !== 'root' && !target.startsWith(dottedPath)) return false\n\n const remainingPath = changedPath === 'root'\n ? target\n : target.slice(dottedPath.length)\n\n return !contentComparer(\n getValueAtPath(nextChange.change.previousValue, remainingPath),\n getValueAtPath(nextChange.change.newValue, remainingPath),\n )\n })\n })) {\n if (needsRender) reRender()\n currentOptions?.onChange?.(storeChanges)\n }\n },\n })\n\n return () => {\n subscription.unsubscribe()\n }\n\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [])\n\n return proxiedStore\n },\n }\n}\n","type Observer<T> = {\n id: string\n // Changes are always delivered in batches (one flush per microtask)\n next: (values: Array<T>) => void\n}\n\ntype Subscription = {\n unsubscribe: () => void\n}\n\ntype FlushItem<T> = {\n newValue: T\n subscriberId?: string\n}\n\nexport type CacheableSubject<T> = {\n subscribe: (observer: Observer<T>) => Subscription\n next: (value: T, subscriberId?: string) => void\n version: () => number\n // Same counter as `version()`, readable without a call (proxy hot path)\n state: { version: number }\n}\n\nexport function createCacheableSubject<T> (): CacheableSubject<T> {\n let isScheduled = false\n let isFlushing = false\n // Monotonic write counter, bumped at write time (not flush time) so a\n // subscriber can detect changes emitted before its subscription existed\n const state = { version: 0 }\n // True when any queued item carries a subscriberId (self-notification\n // exclusion needed): tracked at write time to pick the flush fast path\n let hasIds = false\n const observerList: Array<Observer<T>> = []\n let updateList: Array<FlushItem<T>> = []\n\n\n /** Pushes a new value to the subject and schedules a flush if not already scheduled or flushing.\n * `newValue`:\n * The new value to be emitted to subscribers.\n *\n * `subscriberId`: (Optional)\n * identifier for the subscriber that triggered the update, used to prevent self-notifications. (usage in initialValue)\n */\n function next (newValue: T, subscriberId?: string): void {\n state.version++\n\n if (subscriberId !== undefined) hasIds = true\n updateList.push({ newValue, subscriberId })\n\n if (!isScheduled && !isFlushing)\n scheduleFlush()\n }\n\n\n function subscribe (observer: Observer<T>): Subscription {\n observerList.push(observer)\n\n return {\n unsubscribe: () => {\n const idx = observerList.indexOf(observer)\n\n if (idx !== -1)\n observerList.splice(idx, 1)\n },\n }\n }\n\n\n\n // A subscriber that throws (typically a user `onChange`) must not break the\n // delivery loop nor leave `isFlushing` stuck: the error is re-thrown from\n // its own microtask (reaches window.onerror) and the flush carries on\n function deliver (observer: Observer<T>, values: Array<T>): void {\n try {\n observer.next(values)\n } catch (err) {\n queueMicrotask(() => { throw err })\n }\n }\n\n\n // Hoisted (instead of a fresh closure per scheduled flush) and reused by\n // every queueMicrotask call\n function flush (): void {\n isScheduled = false\n\n if (isFlushing || updateList.length === 0) return\n\n isFlushing = true\n\n // Snapshot by swap (no copy): new updates arriving while flushing are\n // collected into a fresh list\n const changesSnapshot = updateList\n const snapshotHasIds = hasIds\n\n updateList = []\n hasIds = false\n\n // Snapshot the observers too: a synchronous unsubscribe from inside a\n // callback must not shift the delivery loop and skip an observer\n const observersSnapshot = observerList.slice()\n\n // Plain indexed loops: for...of over arrays makes the build ship Babel's\n // iterator-interop helpers, which weigh more than this whole module\n if (!snapshotHasIds) {\n // Fast path (the common case): no self-notification exclusions, so all\n // observers with an id share ONE values array instead of allocating a\n // filtered copy each. Observers without id are excluded, exactly like\n // the filtered path does (undefined === undefined)\n const values: Array<T> = []\n\n for (let i = 0; i < changesSnapshot.length; i++)\n values.push(changesSnapshot[i].newValue)\n\n for (let i = 0; i < observersSnapshot.length; i++) {\n if (observersSnapshot[i].id !== undefined)\n deliver(observersSnapshot[i], values)\n }\n } else {\n for (let i = 0; i < observersSnapshot.length; i++) {\n const observer = observersSnapshot[i]\n const filtered: Array<T> = []\n\n for (let j = 0; j < changesSnapshot.length; j++) {\n if (changesSnapshot[j].subscriberId !== observer.id)\n filtered.push(changesSnapshot[j].newValue)\n }\n\n if (filtered.length > 0)\n deliver(observer, filtered)\n }\n }\n\n isFlushing = false\n\n // Re-check if there are new updates that came in during the flush\n if (updateList.length > 0)\n scheduleFlush()\n }\n\n\n function scheduleFlush (): void {\n if (isScheduled || isFlushing || updateList.length === 0) return\n isScheduled = true\n\n queueMicrotask(flush)\n }\n\n\n\n\n return { next, subscribe, version: () => state.version, state }\n}\n"],"names":["nonReactiveObjectSymbol","Symbol","cloneNonReactive","obj","refs","has","get","Date","getTime","isReactObjectLikeNode","Array","isArray","arr","set","forEach","item","idx","Map","map","v","k","Set","add","constructor","Object","o","keys","i","length","symbols","getOwnPropertySymbols","ancestors","WeakSet","WeakMap","cloned","clonedArray","deepClone","newObj","_i2","isObject","isReactElement","$$typeof","precomputedKeys","objKeys","includes","some","startsWith","isValidReactiveObject","value","getValueAtPath","path","segments","split","current","stringify","JSON","safeToJson","isJsonExoticNode","globalThis","HTMLElement","a","b","aSeen","bSeen","Number","isNaN","aCycles","bCycles","aIsArray","tracked","result","undefined","bItem","aItem","_aSeen","_bSeen","deepEqualJson","aKeys","bKeys","aValue","serializableBalance","_aSeen2","_bSeen2","bValue","_i4","contentComparer","element","props","type","content","innerHTML","RAW_VALUE","proxifyStore","store$$","objectToProxify","opts","fieldPath","nestedFieldPath","isRoot","parent","key","emitPrefix","slice","childProxies","raw","isDetached","seenVersion","revalidate","state","version","liveValue","injected","resolveRaw","liveRawObject","rootRaw","_opts$rootRaw","toJson","boundFunctions","rootFunctions","fromEntries","entries","filter","_ref","emit","change","next","afterChange","Proxy","_","propName","receiver","target","propertyValue","boundFunction","bind","entry","proxy","injectedProxy","parentProxy","child","newValue","_newValue$RAW_VALUE","_previousValue","seedChange","storeValue","assign","previousValue","id","queueMicrotask","_previousValue2","validRawObject","p","Reflect","ownKeys","getOwnPropertyDescriptor","cervello","initialValue","options","clonedInitialValue","isScheduled","isFlushing","hasIds","observerList","updateList","deliver","observer","values","err","changesSnapshot","observersSnapshot","snapshotHasIds","filtered","j","subscriberId","push","scheduleFlush","flush","subscribe","unsubscribe","indexOf","splice","createCacheableSubject","proxiedStore","store","reset","$value","useStore","useId","isInitialValueSet","useRef","setRenderCount","useState","optionsRef","$$value","selectFieldPaths","_ref2","select","selectedFieldPathsForNestedObjects","fp","replace","reRender","useEffect","setValueOnMount","then","console","error","selectedPaths","_selectFieldPaths$cur","wildcardPrefixes","_selectedFieldPathsFo","subscription","storeChanges","needsRender","currentOptions","onChange","nextChange","changedPath","dottedPath","compareTargets","remainingPath","defineProperty","enumerable","writable","configurable"],"mappings":"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"}
|
package/dist/cervello.esm.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{useId as e,useRef as n,useState as
|
|
1
|
+
import{useId as e,useRef as n,useState as r,useEffect as t}from"react";var u=Symbol("nonReactiveObject");function o(e,n){if(!e||"object"!=typeof e)return e;if(n.has(e))return n.get(e);if(e instanceof Date)return new Date(e.getTime());if(f(e))return e;if(Array.isArray(e)){var r=[];return n.set(e,r),e.forEach(function(e,t){r[t]=o(e,n)}),r}if(e instanceof Map){var t=new Map;return n.set(e,t),e.forEach(function(e,r){t.set(o(r,n),o(e,n))}),t}if(e instanceof Set){var u=new Set;return n.set(e,u),e.forEach(function(e){u.add(o(e,n))}),u}if(e.constructor&&e.constructor!==Object)return e;var a={};n.set(e,a);for(var i=Object.keys(e),l=0;l<i.length;l++)a[i[l]]=o(e[i[l]],n);for(var c=Object.getOwnPropertySymbols(e),s=0;s<c.length;s++)a[c[s]]=e[c[s]];return a}function a(e,n){if(void 0===n&&(n=new WeakSet),!e||"object"!=typeof e)return e;if(e[u]){var r=o(e,new WeakMap);return r[u]||(r[u]=!0),r}if(n.has(e))return null;if(Array.isArray(e)){n.add(e);var t=e.map(function(e){return a(e,n)});return n.delete(e),t}var i=Object.keys(e);if(f(e,i))return e;n.add(e);for(var l={},c=0;c<i.length;c++)l[i[c]]=a(e[i[c]],n);for(var s=Object.getOwnPropertySymbols(e),v=0;v<s.length;v++)l[s[v]]=e[s[v]];return n.delete(e),l}var i=function(e){return null!==e&&"object"==typeof e&&!Array.isArray(e)},l=function(e){return!!i(e)&&!!e.$$typeof};function f(e,n){if(!i(e))return!1;if(l(e))return!0;var r=null!=n?n:Object.keys(e);return r.includes("tag")&&r.includes("containerInfo")||r.some(function(e){return e.startsWith("__reactContainer")})||r.includes("tag")&&r.includes("stateNode")}function c(e){return i(e)&&!l(e)&&!e[u]}function s(e,n){for(var r=n.split("."),t=e,u=0;u<r.length;u++){if(null===t||"object"!=typeof t)return;t=t[r[u]]}return t}var v=function(e){return JSON.stringify(y(e))},d=function(e,n){return f(e,n)||!(null==globalThis||!globalThis.HTMLElement)&&e instanceof globalThis.HTMLElement};function h(e,n,r,t){if(e===n)return!0;if(Number.isNaN(e))return Number.isNaN(n);if(!e||!n||"object"!=typeof e||"object"!=typeof n)return!1;var u=!!r&&r.has(e),o=!!t&&t.has(n);if(u||o)return u&&o;var a=Array.isArray(e);if(a!==Array.isArray(n))return!1;var i=!1,l=!0;if(a){l=e.length===n.length;for(var f=0;l&&f<e.length;f++){var c,s,p=void 0===e[f]||"function"==typeof e[f]?null:e[f],y=void 0===n[f]||"function"==typeof n[f]?null:n[f];!i&&(p&&"object"==typeof p||y&&"object"==typeof y)&&(i=!0,r=null!=(c=r)?c:new WeakSet,t=null!=(s=t)?s:new WeakSet,r.add(e),t.add(n)),l=h(p,y,r,t)}}else{var g=Object.keys(e),b=Object.keys(n);if(d(e,g)||d(n,b))l=v(e)===v(n);else{for(var w=0,j=0;l&&j<g.length;j++){var m=e[g[j]];if(void 0!==m&&"function"!=typeof m){w++;var O,V,k=n[g[j]];void 0===k||"function"==typeof k?l=!1:(!i&&(m&&"object"==typeof m||k&&"object"==typeof k)&&(i=!0,r=null!=(O=r)?O:new WeakSet,t=null!=(V=t)?V:new WeakSet,r.add(e),t.add(n)),l=h(m,k,r,t))}}if(l){for(var M=0;M<b.length;M++){var P=n[b[M]];void 0!==P&&"function"!=typeof P&&w--}l=0===w}}}return i&&(r.delete(e),t.delete(n)),l}var p=function(e,n){return h(e,n,null,null)};function y(e,n){if(void 0===n&&(n=new WeakSet),"object"!=typeof e||null==e)return e;if(n.has(e))return null;if(Array.isArray(e)){n.add(e);var r=e.map(function(e){return y(e,n)});return n.delete(e),r}if(l(e)){n.add(e);var t={props:y(e.props,n),type:"string"==typeof e.type?e.type:""};return n.delete(e),t}if(null!=globalThis&&globalThis.HTMLElement&&e instanceof globalThis.HTMLElement)return{type:"[HTMLElement]",content:e.innerHTML};var u=Object.keys(e);if(f(e,u))return{type:"[ReactNode]"};var o={};n.add(e);for(var a=0;a<u.length;a++)o[u[a]]=y(e[u[a]],n);return n.delete(e),o}var g=Symbol("rawValue");function b(e,n,r){var t,u;void 0===r&&(r={});var o=null!=(t=r.nestedFieldPath)?t:"root",i=void 0===r.parent,l=r.key,f=i?"":o.slice(5)+".",s=new Map,v=n,d=!1,h=-1,w=function(){if(h=e.state.version,!i){var n=r.parent(),t=void 0===n?void 0:n[l];if(t!==v&&c(t)){var u=t[g];u&&(n[l]=t=u),v=t}d=t!==v}},j=function(){return e.state.version!==h&&w(),v},m=function(){var e=j();return d?void 0:e},O=null!=(u=r.rootRaw)?u:function(){return v},V=function(){return y(j())},k=new WeakMap,M=i?Object.fromEntries(Object.entries(n).filter(function(e){return"function"==typeof e[1]})):{},P=function(n){e.next(n),null==r.afterChange||r.afterChange([n])};return new Proxy({},{get:function(n,t,u){e.state.version!==h&&w();var i=v;if("symbol"==typeof t)return t===g?i:i[t];if("_$fieldPath"===t)return o;if("toJSON"===t)return V;if("$value"===t)return a(i);var l=i[t];if("function"==typeof l){var f=k.get(l);return f||(f=l.bind(u),k.set(l,f)),f}if(null!==l&&"object"==typeof l){var d=s.get(t);if(void 0!==d&&d.raw===l)return d.proxy;if(c(l)&&l!==i){var p=l[g];if(p&&(i[t]=l=p),void 0!==d)return d.raw=l,d.proxy;var y=b(e,l,{nestedFieldPath:o+"."+t,parent:m,parentProxy:u,key:t,rootRaw:O,afterChange:r.afterChange});return s.set(t,{proxy:y,raw:l}),y}}return l},set:function(n,t,u){var o;if("symbol"==typeof t)return!0;var s=null!==u&&"object"==typeof u&&null!=(o=u[g])?o:u;if("$$value"===t&&i){var d=v,h={storeValue:v=Object.assign({},M,a(s.newValue)),change:{fieldPath:"root",newValue:s.newValue,previousValue:d}};return e.next(h,s.id),r.afterChange&&queueMicrotask(function(){r.afterChange([h])}),!0}if("$value"===t){if(!i)return r.parentProxy[l]=s,!0;var y=v;return s===y||p(s,y)||(v=Object.assign({},M,a(s)),P({storeValue:v,change:{fieldPath:"root",newValue:s,previousValue:y}})),!0}var b=m();if(void 0===b)return!0;var w=b[t];return w===s||c(s)&&p(s,w)||(b[t]=s,P({storeValue:O(),change:{fieldPath:f+t,newValue:s,previousValue:w}})),!0},has:function(e,n){return Reflect.has(j(),n)},ownKeys:function(){return Reflect.ownKeys(j())},getOwnPropertyDescriptor:function(e,n){return Reflect.getOwnPropertyDescriptor(j(),n)}})}function w(e){return Object.defineProperty(e,u,{value:!0,enumerable:!1,writable:!1,configurable:!1}),e}function j(u,o){var i=(null!=o?o:{}).afterChange,l=a(u),f=function(){var e=!1,n=!1,r={version:0},t=!1,u=[],o=[];function a(e,n){try{e.next(n)}catch(e){queueMicrotask(function(){throw e})}}function i(){if(e=!1,!n&&0!==o.length){n=!0;var r=o,i=t;o=[],t=!1;var f=u.slice();if(i)for(var c=0;c<f.length;c++){for(var s=f[c],v=[],d=0;d<r.length;d++)r[d].subscriberId!==s.id&&v.push(r[d].newValue);v.length>0&&a(s,v)}else{for(var h=[],p=0;p<r.length;p++)h.push(r[p].newValue);for(var y=0;y<f.length;y++)void 0!==f[y].id&&a(f[y],h)}n=!1,o.length>0&&l()}}function l(){e||n||0===o.length||(e=!0,queueMicrotask(i))}return{next:function(u,a){r.version++,void 0!==a&&(t=!0),o.push({newValue:u,subscriberId:a}),e||n||l()},subscribe:function(e){return u.push(e),{unsubscribe:function(){var n=u.indexOf(e);-1!==n&&u.splice(n,1)}}},version:function(){return r.version},state:r}}(),c=b(f,l,{afterChange:i});return{store:c,reset:function(){c.$value=u},useStore:function(u){var o=e(),a=n(!1),i=r(0)[1],l=n(u);if(l.current=u,!a.current){a.current=!0;var v=null==u||null==u.initialValue?void 0:u.initialValue(c.$value);v&&!p(v,c[g])&&(c.$$value={id:o,newValue:v})}var d=n(0);d.current=f.version();var h,y=n(null);null===y.current&&(y.current=null!=(h="function"==typeof(null==u?void 0:u.select)?u.select():null==u?void 0:u.select)?h:[]);var b=n(null);null===b.current&&(b.current=y.current.filter(function(e){return e.includes(".*")}).map(function(e){return e.replace("*","")}));var w=function(){i(function(e){return e+1})};return t(function(){null!=u&&u.setValueOnMount&&u.setValueOnMount(c.$value).then(function(e){c.$value=e}).catch(function(e){console.error("Error setting initial value on mount",e)})},[]),t(function(){var e,n,r=null!=(e=y.current)?e:[],t=null!=(n=b.current)?n:[],u=r.map(function(e){return e.replace(".*","")});f.version()!==d.current&&w();var a=f.subscribe({id:o,next:function(e){var n=l.current,o=f.version()!==d.current;if(null==n||!n.select)return o&&w(),void(null==n||null==n.onChange||n.onChange(e));e.some(function(e){var n=e.change.fieldPath,o=n+".";return!!r.includes(n)||!!t.some(function(e){return o.startsWith(e)})||u.some(function(r){if("root"!==n&&!r.startsWith(o))return!1;var t="root"===n?r:r.slice(o.length);return!p(s(e.change.previousValue,t),s(e.change.newValue,t))})})&&(o&&w(),null==n||null==n.onChange||n.onChange(e))}});return function(){a.unsubscribe()}},[]),c}}}export{j as cervello,w as nonReactive};
|
|
2
2
|
//# sourceMappingURL=cervello.esm.js.map
|
package/dist/cervello.esm.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cervello.esm.js","sources":["../src/types/shared.ts","../src/lib/utils/object.ts","../src/lib/helpers/new-proxify-store.ts","../src/lib/store/new-index.ts","../src/lib/utils/subject.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/ban-types */\nexport type WithoutType<T, V, WithNever = {\n [K in keyof T]: Exclude<T[K], undefined> extends V\n ? never\n : (T[K] extends Record<string, unknown>\n ? WithoutType<T[K], V>\n : T[K])\n}> = Pick<WithNever, {\n [K in keyof WithNever]: WithNever[K] extends never ? never : K\n}[keyof WithNever]>\n\n\n\nexport type ObjectFromAttributes<T, Attributes extends Array< keyof WithoutType<T, Function> > > = {\n [k in Attributes[number]]: T[k]\n}\n\nexport type Maybe<T> = T | undefined\n\n\n\nexport type UseSelector<T> = <Attributes extends Array< Exclude<keyof WithoutType<T, Function>, '$value'> >>(\n selectors: Attributes,\n isEqualFunction?: (previousState: ObjectFromAttributes<T, Attributes>, currentState: ObjectFromAttributes<T, Attributes>) => boolean,\n) => T\n\nexport type FieldPath<T extends Record<string, any>> = {\n [K in keyof Required<T>]: T[K] extends Record<string, any>\n ? K extends string\n\n ? T[K] extends Function\n ? never\n : T[K] extends Array<any>\n ? K\n : `${K}.*` | `${K}.${FieldPath<T[K]>}`\n : never\n : K extends string\n ? K\n : never\n}[keyof T]\n\nexport const nonReactiveObjectSymbol = Symbol('nonReactiveObject')\nexport type StoreChange<T extends Record<string, any>> = {\n change: {\n fieldPath: FieldPath<T>\n newValue: any\n previousValue: any\n }\n storeValue: T\n}\n","/* eslint-disable no-cond-assign */\n\nimport { nonReactiveObjectSymbol } from '../../types/shared'\nimport { INTERNAL_VALUE_PROP } from '../helpers/constants'\n\n\n/**\n * Clones all the provided object and nested properties and it also\n * iterates nested arrays to deepClone them\n *\n * @param obj - base object to be cloned\n * @returns new cloned object with new reference\n */\nexport function deepClone <T> (obj: T): T {\n if (!obj || typeof obj !== 'object')\n return obj\n\n let newObj = {} as any\n\n if (Array.isArray(obj)) {\n newObj = obj.map(item => deepClone(item))\n } else if (!isReactObjectLikeNode(obj)) {\n Object.entries(obj).forEach(([key, value]) => {\n newObj[key] = deepClone(value)\n })\n Object.getOwnPropertySymbols(obj).forEach((symbol) => {\n newObj[symbol] = (obj as any)[symbol]\n })\n } else {\n newObj = obj\n }\n\n return newObj as T\n}\n\n// function copyBuffer (cur: ArrayBufferView) {\n// if (cur instanceof Buffer)\n// return Buffer.from(cur)\n//\n//\n// return new cur.constructor(cur.buffer.slice(), cur.byteOffset, cur.length)\n// }\n\n\n// INFO: From `rfdc` (really-fast-deep-clone) package for faster cloning taking care of circular references\nexport function deepClone2 <T> (obj: T): T {\n const refs: Array<any> = []\n const refsNew: Array<any> = []\n\n const constructorHandlers = new Map()\n\n constructorHandlers.set(Date, (o: string | number | Date) => new Date(o))\n constructorHandlers.set(Map, (o: Iterable<unknown> | ArrayLike<unknown>, fn: any) => new Map(cloneArray(Array.from(o), fn)))\n constructorHandlers.set(Set, (o: Iterable<unknown> | ArrayLike<unknown>, fn: any) => new Set(cloneArray(Array.from(o), fn)))\n\n let handler = null\n\n return clone(obj)\n\n function cloneArray (a: any, fn: any): any {\n const keys = Object.keys(a)\n const a2 = new Array(keys.length) as any\n\n for (let i = 0; i < keys.length; i++) {\n const k = keys[i]\n const cur = a[k]\n\n if (typeof cur !== 'object' || cur === null) {\n a2[k] = cur\n } else if (cur.constructor !== Object && (handler = constructorHandlers.get(cur.constructor))) {\n a2[k] = handler(cur, fn)\n // } else if (ArrayBuffer.isView(cur)) {\n // a2[k] = copyBuffer(cur)\n } else {\n const index = refs.indexOf(cur)\n\n if (index !== -1)\n a2[k] = refsNew[index]\n else\n a2[k] = fn(cur)\n }\n }\n\n return a2\n }\n\n function clone (o: any): any {\n if (typeof o !== 'object' || o === null) return o\n if (Array.isArray(o)) return cloneArray(o, clone)\n if (o.constructor !== Object && (handler = constructorHandlers.get(o.constructor)))\n return handler(o, clone)\n\n const o2 = {} as any\n\n refs.push(o)\n refsNew.push(o2)\n\n\n Object.getOwnPropertySymbols(o).forEach((symbol) => {\n o2[symbol] = (o)[symbol]\n })\n\n for (const k in o) {\n if (!Object.hasOwnProperty.call(o, k)) continue\n const cur = o[k]\n\n\n if (typeof cur !== 'object' || cur === null) {\n o2[k] = cur\n } else if (cur.constructor !== Object && (handler = constructorHandlers.get(cur.constructor))) {\n o2[k] = handler(cur, clone)\n // } else if (ArrayBuffer.isView(cur)) {\n // o2[k] = copyBuffer(cur)\n } else {\n const i = refs.indexOf(cur)\n\n if (i !== -1)\n o2[k] = refsNew[i]\n else\n o2[k] = clone(cur)\n }\n }\n refs.pop()\n refsNew.pop()\n\n\n return o2\n }\n}\n\n/**\n * Guard to check is variable is an object\n * @param obj - variable to be checked\n * @returns boolean\n */\nexport const isObject = (obj: unknown): obj is Record<string | symbol, unknown> => (\n obj !== null\n && typeof obj === 'object'\n && !Array.isArray(obj)\n)\n\n\nexport const isReactElement = (obj: unknown): boolean => {\n if (!isObject(obj)) return false\n\n return !!(obj.$$typeof)\n}\n\n\nexport function isReactObjectLikeNode (obj: unknown): boolean {\n if (!isObject(obj)) return false\n if (isReactElement(obj)) return true\n\n const objKeys = Object.keys(obj)\n const isReactObjNode = (objKeys.includes('tag') && objKeys.includes('containerInfo'))\n || objKeys.some(k => k.startsWith('__reactContainer'))\n || (objKeys.includes('tag') && objKeys.includes('stateNode'))\n\n return isReactObjNode\n}\n\n\nexport function isValidReactiveObject <T extends Record<string, any>> (value: T): boolean {\n return isObject(value) && !isReactElement(value) && !(value as any)[nonReactiveObjectSymbol]\n}\n\n\n\n/**\n * Returns the actual target value instead of root\n * object with internals props like $$value$$\n *\n * @param target - object from subscription or proxy\n * @returns actual value\n */\nexport const okTarget = (target: any): any => target[INTERNAL_VALUE_PROP] ?? target\n\n\n\n\n/**\n * Gets an object with just the properties requested\n * instead of the full object\n *\n * @param properties - object properties\n * @param obj - target to get the properties\n * @returns New object with just the requested properties\n */\nexport function getPartialObjectFromProperties<T> (properties: Array<keyof T>, obj: T): any {\n return properties.reduce<any>((acc, curr) => {\n acc[curr] = obj[curr]\n\n return acc\n }, {})\n}\n\n\n\nconst stringify = (obj: any): string => JSON.stringify(obj)\n\n/**\n * Compare 2 provided objects by stringing them\n * @param a - first object\n * @param b - second object\n * @returns boolean\n */\nexport const contentComparer = (a: any, b: any): boolean => stringify(a) === stringify(b)\n\n\n\n\nexport function safeToJson (obj: any): Record<string, any> {\n const o: Record<string, any> = {}\n\n if (typeof obj !== 'object' || obj == null)\n return obj\n\n if (Array.isArray(obj))\n return obj.map(item => safeToJson(item))\n\n if (isReactElement(obj))\n return { props: safeToJson(obj.props), type: typeof obj.type === 'string' ? obj.type : '' }\n\n if (globalThis?.HTMLElement && obj instanceof globalThis.HTMLElement) return { type: '[HTMLElement]', content: obj.innerHTML }\n\n Object.entries(obj).forEach(([key, v]) => {\n o[key] = safeToJson(v)\n })\n\n return o\n}\n","\nimport { deepClone, isValidReactiveObject, safeToJson } from '../utils/object'\n\nimport type { StoreChange } from '../../types/shared'\nimport type { CacheableSubject } from '../utils/subject'\n\n\n\n// @ts-expect-error - Object.hasOwn is not defined in older Safari's browsers\n('hasOwn' in Object) || (Object.hasOwn = Object.call.bind(Object.hasOwnProperty))\n\nconst ROOT_VALUE = Symbol('value')\n\n\nexport function proxifyStore <T extends Record<string | symbol, any>> (\n store$$: CacheableSubject<StoreChange<T>>,\n objectToProxify: T,\n opts: {\n nestedFieldPath?: string\n parentObjectToProxify?: any\n // beforeChange?: (storeChange: StoreChange<T>) => any\n afterChange?: (storeChange: Array<StoreChange<T>>) => void\n } = {},\n): T {\n const fieldPath = opts.nestedFieldPath ?? 'root'\n\n const objectWithRootValue = {\n [ROOT_VALUE]: objectToProxify,\n } as unknown as T\n\n const rootFunctions = fieldPath === 'root'\n ? Object.fromEntries(Object.entries(objectToProxify).filter(([,v]) => typeof v === 'function'))\n : {}\n\n return new Proxy(objectWithRootValue, {\n get (targetObject, propName, receiver) {\n // INFO: !Internal only.\n // Used to get the fieldPath of the object (it means it's a proxified object)\n if (propName === '_$fieldPath') return fieldPath\n\n const isRootTarget = Object.hasOwn(targetObject, ROOT_VALUE)\n const target = isRootTarget ? targetObject[ROOT_VALUE] : targetObject\n\n\n // Called when the object is converted to JSON or string (i.e. JSON.stringify)\n if (propName === 'toJSON') {\n return () => {\n // Remove react-elements with circular which have circular references\n // before stringifying to prevent JSON.stringify(storeProxy) from failing\n return safeToJson(target)\n // return removeCircularReferences(target)\n }\n }\n\n // Get the whole store value without proxies\n if (propName === '$value')\n return deepClone(target)\n // return target\n\n\n\n const propertyValue = Reflect.get(target, propName, receiver)\n\n if (typeof propName === 'symbol') return propertyValue\n\n if (typeof propertyValue === 'function')\n return (propertyValue as () => any).bind(receiver)\n\n\n // Check if it's correct to be a reactive object\n // & is not a circular reference or the same object\n if (isValidReactiveObject(propertyValue) && propertyValue !== target) {\n // const newNestedFieldPath = `${fieldPath}.${propName}`\n\n // If it's already a proxified object, return it\n // if (propertyValue._$fieldPath === newNestedFieldPath) return propertyValue\n if (propertyValue._$fieldPath) return propertyValue\n\n // Create a new proxified object\n const proxiedNestedObject = proxifyStore(\n store$$ as any,\n propertyValue,\n {\n nestedFieldPath: `${fieldPath}.${propName}`,\n parentObjectToProxify: opts.parentObjectToProxify ?? target,\n // beforeChange: opts.beforeChange,\n afterChange: opts.afterChange,\n },\n )\n\n return target[propName] = proxiedNestedObject\n }\n\n return propertyValue\n },\n\n\n set (parentObject, key, newValue, receiver) {\n if (typeof key === 'symbol') return true\n\n const value = newValue\n const isRootTarget = Object.hasOwn(parentObject, ROOT_VALUE)\n\n // INFO: !Internal only.\n // Used to set the value of the store without notifying the store\n if (isRootTarget && key === '$$value') {\n const previousValue = parentObject[ROOT_VALUE];\n\n (parentObject as any)[ROOT_VALUE] = value.newValue\n\n store$$.next({\n storeValue: value.newValue,\n change: {\n fieldPath: 'root' as any,\n newValue: value.newValue,\n previousValue,\n },\n }, value.id)\n\n return true\n }\n\n if (isRootTarget && key === '$value') {\n const previousValue = parentObject[ROOT_VALUE]\n\n if (value === previousValue) return true\n\n if (JSON.stringify(safeToJson(value)) === JSON.stringify(safeToJson(previousValue))) return true\n // if (safeStringify(value) === safeStringify(previousValue)) return true\n\n if (fieldPath !== 'root') {\n (parentObject as any)[ROOT_VALUE] = value\n } else {\n (parentObject as any)[ROOT_VALUE] = {\n ...rootFunctions,\n ...value,\n }\n store$$.next({\n // To be disabled for performance and send same store reference\n // storeValue: JSON.parse(JSON.stringify(targetObject[ROOT_VALUE])),\n storeValue: parentObject[ROOT_VALUE],\n change: {\n fieldPath: 'root' as any,\n newValue: value,\n previousValue,\n },\n })\n }\n\n return true\n }\n\n const realInnerObject = isRootTarget ? parentObject[ROOT_VALUE] : parentObject\n const previousValue = Reflect.get(realInnerObject, key, receiver)\n\n\n if (previousValue === value) return true\n\n\n // New object values, check if the field has already a proxy created to use it instead of reacreating a new instance\n if (isValidReactiveObject(value) && previousValue?._$fieldPath)\n previousValue.$value = value\n else\n Reflect.set(realInnerObject, key, value, realInnerObject)\n\n\n const nextStoreChange = {\n // To be disabled for performance and send same store reference\n // storeValue: JSON.parse(JSON.stringify(opts?.parentObjectToProxify ?? target)),\n storeValue: opts?.parentObjectToProxify ?? realInnerObject,\n change: {\n fieldPath: `${fieldPath}.${key}`.replace('root.', '') as any,\n newValue: value,\n previousValue,\n },\n }\n\n store$$.next(nextStoreChange)\n opts.afterChange?.([nextStoreChange])\n\n return true\n },\n\n has (t, p) {\n return Reflect.has(t[ROOT_VALUE], p)\n },\n\n ownKeys (t) {\n return Reflect.ownKeys(t[ROOT_VALUE])\n },\n\n getOwnPropertyDescriptor (t, p) {\n return Reflect.getOwnPropertyDescriptor(t[ROOT_VALUE], p)\n },\n\n })\n}\n\n\n// function getDeepUnproxiedObject (obj: any): any {\n// if (obj && typeof obj === 'object' && !Array.isArray(obj)) {\n// if (obj[ROOT_VALUE]?.[ROOT_VALUE]) {\n// console.warn('Circular reference detected in getDeepUnproxiedObject')\n//\n// return '[Circular reference]'\n// }\n//\n//\n// const r = Object.fromEntries(\n// Object.entries(obj).map(([key, value]) => {\n// // console.log('____________________getDeepUnproxiedObject', key, value, value.constructor.name)\n// if (value && typeof value === 'object' && !Array.isArray(value)) {\n// if (key === 'links') console.log('getDeepUnproxiedObject', key, value)\n//\n// // If it's a proxied object, get the unproxied value\n// return [key, getDeepUnproxiedObject(value)]\n// }\n//\n// return [key, value]\n// }),\n// )\n//\n//\n// return r\n// }\n//\n// return obj\n// }\n\n// function safeStringify (obj: any): string {\n// // use removeCircularReferences to avoid circular references\n// // const cleanedObj = removeCircularReferences(obj)\n// return JSON.stringify(safeToJson(obj))\n// //\n// // return JSON.stringify(\n// // obj,\n// // (_key, value) => {\n// // if (Array.isArray(value)) return value.map(i => safeStringify(i))\n// //\n// // if (isReactElement(value)) {\n// // // console.log('React element detected', value)\n// //\n// // return { props: safeStringify(value.props), type: typeof value.type === 'string' ? value.type : '' }\n// // }\n// //\n// // if (globalThis?.HTMLElement && value instanceof globalThis.HTMLElement) return { type: '[HTMLElement]', content: value.innerHTML }\n// //\n// // // console.log('Value', value)\n// //\n// // return value\n// // })\n// }\n\n\n\n\n// function removeCircularReferences (obj: any): any {\n// const seen = new WeakSet()\n//\n// function traverse (value: any): any {\n// if (value && typeof value === 'object') {\n// // If the object has already been seen, it's a circular reference\n// if (seen.has(value))\n// return null\n//\n// seen.add(value)\n//\n// if (Array.isArray(value))\n// return value.map(traverse)\n//\n//\n// const result: any = {}\n//\n// for (const key in value) {\n// if (Object.prototype.hasOwnProperty.call(value, key)) {\n// if (key === '_owner' && value.$$typeof) continue\n//\n// result[key] = traverse(value[key])\n// }\n// }\n//\n// return result\n// }\n//\n// // Return primitive values as-is\n// return value\n// }\n//\n// return traverse(obj)\n// }\n","\nimport { useEffect, useId, useRef, useState } from 'react'\n\nimport { nonReactiveObjectSymbol } from '../../types/shared'\nimport { proxifyStore } from '../helpers/new-proxify-store'\nimport { deepClone, safeToJson } from '../utils/object'\nimport { createCacheableSubject } from '../utils/subject'\n\nimport type { FieldPath, StoreChange } from '../../types/shared'\n\n\n\n\n// export type CervelloOptions<StoreValue extends Record<string, any>> = {\n// beforeChange?: (storeChange: StoreChange<StoreValue>) => unknown | undefined\n// afterChange?: (storeChange: Array<StoreChange<StoreValue>>) => void\n// }\n\nexport type CervelloOptions<StoreValue extends Record<string, any>> = {\n afterChange?: (storeChange: Array<StoreChange<StoreValue>>) => void\n}\n\nexport type CervelloUseStoreOptions<StoreValue extends Record<string, any>> = {\n initialValue?: (currentStore: StoreValue) => StoreValue | null,\n setValueOnMount?: (currentStore: StoreValue) => Promise<StoreValue>,\n select?:\n | Array<FieldPath<StoreValue>>\n | (() => Array<FieldPath<StoreValue>>)\n onChange?: (storeChange: Array<StoreChange<StoreValue>>) => void\n}\n\ntype MutableStoreValue<T extends Record<string, any>> = {\n $value: T\n} & T\n\n\n\n\n\n\n\n\nexport function nonReactive <T extends Record<string, any>> (initialValue: T): T {\n Object.defineProperty(initialValue, nonReactiveObjectSymbol, {\n value: true,\n enumerable: false,\n writable: false,\n configurable: false,\n })\n\n return initialValue\n}\n\n\nexport function cervello <StoreValue extends Record<PropertyKey, any>> (\n initialValue: StoreValue,\n options?: CervelloOptions<StoreValue>,\n): {\n store: MutableStoreValue<StoreValue>,\n reset: () => void,\n useStore: (options?: CervelloUseStoreOptions<StoreValue>) => MutableStoreValue<StoreValue>\n } {\n const {\n // beforeChange,\n afterChange,\n } = options ?? {}\n\n // const store$$ = createCacheableSubject<StoreChange<StoreValue>>(clonedInitialValue as any)\n const clonedInitialValue = deepClone(initialValue)\n\n const store$$ = createCacheableSubject<StoreChange<StoreValue>>()\n\n const proxiedStore = proxifyStore(\n store$$ as any,\n clonedInitialValue,\n // { beforeChange, afterChange },\n { afterChange },\n ) as MutableStoreValue<StoreValue>\n\n\n return {\n store: proxiedStore,\n reset: () => {\n proxiedStore.$value = deepClone(initialValue)\n },\n useStore: (options) => {\n const subscriberId = useId()\n const initialValue = options?.initialValue?.(proxiedStore.$value)\n const isInitialValueSet = useRef(false)\n const [, setRenderCount] = useState(0)\n\n if (!isInitialValueSet.current\n && initialValue\n && JSON.stringify(safeToJson(initialValue)) !== JSON.stringify(safeToJson(proxiedStore.$value))\n ) {\n isInitialValueSet.current = true;\n (proxiedStore as any).$$value = { id: subscriberId, newValue: initialValue }\n }\n\n const selectFieldPaths = useRef(\n (typeof options?.select === 'function'\n ? options?.select?.()\n : options?.select)\n ?? [],\n )\n\n\n const selectedFieldPathsForNestedObjects = useRef(\n selectFieldPaths.current\n .filter(fp => fp.includes('.*'))\n .map(fp => fp.replace('.*', '')),\n )\n\n const reRender = (): void => {\n setRenderCount(p => p + 1)\n }\n\n\n useEffect(() => {\n if (options?.setValueOnMount) {\n void options.setValueOnMount(proxiedStore.$value).then((value) => {\n proxiedStore.$value = value\n }).catch((err) => {\n console.error('Error setting initial value on mount', err)\n })\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [])\n\n\n // Same implementation as useSyncExternalStore but with useEffect\n useEffect(() => {\n const subscription = store$$.subscribe({\n id: subscriberId,\n next: (sc) => {\n const storeChanges = Array.isArray(sc)\n ? sc as Array<StoreChange<StoreValue>>\n : [sc]\n\n if (!options?.select) {\n reRender()\n options?.onChange?.(storeChanges)\n\n return\n }\n\n if (storeChanges.some(nextChange => (\n nextChange.change.fieldPath === 'root'\n || selectFieldPaths.current.includes(nextChange.change.fieldPath))\n || selectedFieldPathsForNestedObjects.current.find(fp => nextChange.change.fieldPath.startsWith(fp)),\n )) {\n reRender()\n options?.onChange?.(storeChanges)\n }\n },\n })\n\n return () => {\n subscription.unsubscribe()\n }\n\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [options?.select, options?.onChange])\n\n return proxiedStore\n },\n }\n}\n\n","\ntype Noop = () => void\n\n\ntype Observer<T> = {\n id: string\n next: (value: T, subscriberId?: string) => void\n}\n\ntype Subscription = {\n unsubscribe: Noop\n}\n\nexport type CacheableSubject<T> = {\n // getValue: () => T\n subscribe: (value: Observer<T>) => Subscription\n // unSubscribeAll: Noop\n} & Omit<Observer<T>, 'id'>\n\n\n\nexport function createCacheableSubject<T> (/* defaultValue: T/*, getValueOnSubscribe = false */): CacheableSubject<T> {\n let isFlushing = false\n let itemsToFlush: Array<{ newValue: T, subscriberId?: string }> = []\n\n let observerList: Array<Observer<T>> = []\n // let value = defaultValue\n\n // const getValue = (): T => value\n\n const next = (newValue: T, subscriberId?: string): void => {\n // value = newValue\n\n itemsToFlush.push({ newValue, subscriberId })\n\n if (!isFlushing) {\n isFlushing = true\n\n void Promise.resolve().then(() => {\n observerList.forEach((o) => {\n // Filter changes that were sent by the same subscriberId (initialValue function call)\n const nonInitiallySentBySubscriber = itemsToFlush.filter(item => item.subscriberId !== o.id)\n\n if (!nonInitiallySentBySubscriber.length) return\n\n o.next(nonInitiallySentBySubscriber.map(i => i.newValue) as T)\n })\n itemsToFlush = []\n isFlushing = false\n })\n\n // void Promise.resolve(subscriberId).then((subscriberId) => {\n // console.log('//// promise.resolve then', { subscriberId: s.id })\n // observerList.forEach((o) => {\n // console.log('//// CacheableSubject (forEach) flushing', { observerId: o.id, subscriberId: s.id })\n // if (o.id === subscriberId) return\n //\n // o.next(itemsToFlush as T)\n // })\n // itemsToFlush = []\n // isFlushing = false\n // })\n\n // void Promise.resolve().then(() => {\n // console.log('//// promise.resolve then')\n // observerList.forEach((o) => {\n // const nonInitiallySentBySubscriber = itemsToFlush.filter(item => item.subscriberId !== o.id)\n //\n // if (nonInitiallySentBySubscriber.length === 0) return\n //\n // o.next(nonInitiallySentBySubscriber.map(i => i.newValue) as T)\n // })\n // itemsToFlush = []\n // isFlushing = false\n // })\n }\n }\n\n const subscribe = (observer: Observer<T>): Subscription => {\n // Push cached value on subscribe\n // if (getValueOnSubscribe) observer.next(value)\n\n // Store the observer to be notified\n observerList.push(observer)\n\n return {\n unsubscribe: () => {\n observerList = observerList.filter(o => o.id !== observer.id)\n },\n }\n }\n\n // const unSubscribeAll = (): void => {\n // observerList = []\n // }\n\n return {\n // getValue,\n next,\n subscribe,\n // unSubscribeAll,\n }\n}\n"],"names":["nonReactiveObjectSymbol","Symbol","deepClone","obj","newObj","Array","isArray","map","item","isReactObjectLikeNode","isObject","isReactElement","objKeys","Object","keys","includes","some","k","startsWith","entries","forEach","_ref","getOwnPropertySymbols","symbol","$$typeof","isValidReactiveObject","value","safeToJson","o","props","type","globalThis","HTMLElement","content","innerHTML","_ref2","v","hasOwn","call","bind","hasOwnProperty","ROOT_VALUE","proxifyStore","store$$","objectToProxify","opts","_opts$nestedFieldPath","_objectWithRootValue","nestedFieldPath","objectWithRootValue","rootFunctions","fieldPath","fromEntries","filter","Proxy","get","targetObject","propName","receiver","target","propertyValue","Reflect","_opts$parentObjectToP","_$fieldPath","proxiedNestedObject","parentObjectToProxify","afterChange","set","parentObject","key","newValue","_opts$parentObjectToP2","_opts","isRootTarget","previousValue","next","storeValue","change","id","JSON","stringify","_extends","realInnerObject","$value","nextStoreChange","replace","has","t","p","ownKeys","getOwnPropertyDescriptor","nonReactive","initialValue","defineProperty","enumerable","writable","configurable","cervello","options","isFlushing","itemsToFlush","clonedInitialValue","subscriberId","push","resolve","then","observerList","nonInitiallySentBySubscriber","length","i","subscribe","observer","unsubscribe","proxiedStore","store","reset","useStore","useId","isInitialValueSet","useRef","setRenderCount","useState","current","$$value","selectFieldPaths","select","selectedFieldPathsForNestedObjects","fp","reRender","useEffect","setValueOnMount","err","console","error","subscription","sc","storeChanges","onChange","nextChange","find"],"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","\nimport { nonReactiveObjectSymbol } from '../../types/shared'\nimport { INTERNAL_VALUE_PROP } from '../helpers/constants'\n\n\n/**\n * Structural clone for nonReactive() subtrees: preserves complex values\n * (Date, Map, Set) and keeps circular references/aliases intact by mapping\n * each source object to its clone. Functions, React nodes and any other\n * class instance (DOM elements included, via the constructor check) are\n * kept by reference β they cannot be cloned safely\n */\nfunction cloneNonReactive (obj: any, refs: WeakMap<object, any>): any {\n if (!obj || typeof obj !== 'object') return obj\n\n if (refs.has(obj)) return refs.get(obj)\n\n if (obj instanceof Date) return new Date(obj.getTime())\n\n if (isReactObjectLikeNode(obj)) return obj\n\n if (Array.isArray(obj)) {\n const arr: Array<any> = []\n\n refs.set(obj, arr)\n obj.forEach((item, idx) => { arr[idx] = cloneNonReactive(item, refs) })\n\n return arr\n }\n\n if (obj instanceof Map) {\n const map = new Map()\n\n refs.set(obj, map)\n obj.forEach((v, k) => { map.set(cloneNonReactive(k, refs), cloneNonReactive(v, refs)) })\n\n return map\n }\n\n if (obj instanceof Set) {\n const set = new Set()\n\n refs.set(obj, set)\n obj.forEach((v) => { set.add(cloneNonReactive(v, refs)) })\n\n return set\n }\n\n // Other class instances cannot be cloned generically: keep them by reference\n if (obj.constructor && obj.constructor !== Object) return obj\n\n const o: Record<PropertyKey, any> = {}\n\n refs.set(obj, o)\n\n // Indexed loops: no [key, value] tuple per property (Object.entries) nor\n // a closure per object (forEach)\n const keys = Object.keys(obj)\n\n for (let i = 0; i < keys.length; i++)\n o[keys[i]] = cloneNonReactive(obj[keys[i]], refs)\n\n const symbols = Object.getOwnPropertySymbols(obj)\n\n for (let i = 0; i < symbols.length; i++)\n o[symbols[i]] = obj[symbols[i]]\n\n return o\n}\n\n\n/**\n * Clones all the provided object and nested properties and it also\n * iterates nested arrays to deepClone them\n *\n * Circular references are considered invalid store values, so they are cut\n * to `null` instead of recursing forever. The exceptions are React\n * elements/nodes (kept by reference) and nonReactive()-wrapped objects,\n * which are cloned structurally so complex values (Date, Map, Set, circular\n * references...) survive intact β this keeps the store copy decoupled from\n * the caller's object and allows reset() to restore the initial state\n *\n * @param obj - base object to be cloned\n * @param ancestors - objects of the current traversal path, to detect cycles\n * @returns new cloned object with new reference\n */\nexport function deepClone <T> (obj: T, ancestors = new WeakSet<object>()): T {\n if (!obj || typeof obj !== 'object')\n return obj\n\n if ((obj as any)[nonReactiveObjectSymbol]) {\n const cloned = cloneNonReactive(obj, new WeakMap())\n\n // Keep the mark when the wrapper itself is an exotic object (Map, array...)\n // whose clone branch does not copy symbol properties\n if (!cloned[nonReactiveObjectSymbol]) cloned[nonReactiveObjectSymbol] = true\n\n return cloned\n }\n\n if (ancestors.has(obj))\n return null as T\n\n if (Array.isArray(obj)) {\n ancestors.add(obj)\n const clonedArray = obj.map(item => deepClone(item, ancestors))\n\n ancestors.delete(obj)\n\n return clonedArray as T\n }\n\n // Keys are computed once and shared with the react-node check, which had\n // to allocate its own Object.keys per visited object before\n const keys = Object.keys(obj)\n\n if (isReactObjectLikeNode(obj, keys)) return obj\n\n ancestors.add(obj)\n\n const newObj = {} as any\n\n // Indexed loops (keys and symbols): no [key, value] tuple per property\n // (Object.entries) nor a closure per object (forEach) in this hot path\n for (let i = 0; i < keys.length; i++)\n newObj[keys[i]] = deepClone((obj as any)[keys[i]], ancestors)\n\n const symbols = Object.getOwnPropertySymbols(obj)\n\n for (let i = 0; i < symbols.length; i++)\n newObj[symbols[i]] = (obj as any)[symbols[i]]\n\n ancestors.delete(obj)\n\n return newObj as T\n}\n\n// function copyBuffer (cur: ArrayBufferView) {\n// if (cur instanceof Buffer)\n// return Buffer.from(cur)\n//\n//\n// return new cur.constructor(cur.buffer.slice(), cur.byteOffset, cur.length)\n// }\n\n\n// INFO: From `rfdc` (really-fast-deep-clone) package for faster cloning taking care of circular references\n// export function deepClone2 <T> (obj: T): T {\n// const refs: Array<any> = []\n// const refsNew: Array<any> = []\n//\n// const constructorHandlers = new Map()\n//\n// constructorHandlers.set(Date, (o: string | number | Date) => new Date(o))\n// constructorHandlers.set(Map, (o: Iterable<unknown> | ArrayLike<unknown>, fn: any) => new Map(cloneArray(Array.from(o), fn)))\n// constructorHandlers.set(Set, (o: Iterable<unknown> | ArrayLike<unknown>, fn: any) => new Set(cloneArray(Array.from(o), fn)))\n//\n// let handler = null\n//\n// return clone(obj)\n//\n// function cloneArray (a: any, fn: any): any {\n// const keys = Object.keys(a)\n// const a2 = new Array(keys.length) as any\n//\n// for (let i = 0; i < keys.length; i++) {\n// const k = keys[i]\n// const cur = a[k]\n//\n// if (typeof cur !== 'object' || cur === null) {\n// a2[k] = cur\n// } else if (cur.constructor !== Object && (handler = constructorHandlers.get(cur.constructor))) {\n// a2[k] = handler(cur, fn)\n// // } else if (ArrayBuffer.isView(cur)) {\n// // a2[k] = copyBuffer(cur)\n// } else {\n// const index = refs.indexOf(cur)\n//\n// if (index !== -1)\n// a2[k] = refsNew[index]\n// else\n// a2[k] = fn(cur)\n// }\n// }\n//\n// return a2\n// }\n//\n// function clone (o: any): any {\n// if (typeof o !== 'object' || o === null) return o\n// if (Array.isArray(o)) return cloneArray(o, clone)\n// if (o.constructor !== Object && (handler = constructorHandlers.get(o.constructor)))\n// return handler(o, clone)\n//\n// const o2 = {} as any\n//\n// refs.push(o)\n// refsNew.push(o2)\n//\n//\n// Object.getOwnPropertySymbols(o).forEach((symbol) => {\n// o2[symbol] = (o)[symbol]\n// })\n//\n// for (const k in o) {\n// if (!Object.hasOwnProperty.call(o, k)) continue\n// const cur = o[k]\n//\n//\n// if (typeof cur !== 'object' || cur === null) {\n// o2[k] = cur\n// } else if (cur.constructor !== Object && (handler = constructorHandlers.get(cur.constructor))) {\n// o2[k] = handler(cur, clone)\n// // } else if (ArrayBuffer.isView(cur)) {\n// // o2[k] = copyBuffer(cur)\n// } else {\n// const i = refs.indexOf(cur)\n//\n// if (i !== -1)\n// o2[k] = refsNew[i]\n// else\n// o2[k] = clone(cur)\n// }\n// }\n// refs.pop()\n// refsNew.pop()\n//\n//\n// return o2\n// }\n// }\n\n/**\n * Guard to check is variable is an object\n * @param obj - variable to be checked\n * @returns boolean\n */\nexport const isObject = (obj: unknown): obj is Record<string | symbol, unknown> => (\n obj !== null\n && typeof obj === 'object'\n && !Array.isArray(obj)\n)\n\n\nexport const isReactElement = (obj: unknown): boolean => {\n if (!isObject(obj)) return false\n\n return !!(obj.$$typeof)\n}\n\n\nexport function isReactObjectLikeNode (obj: unknown, precomputedKeys?: Array<string>): boolean {\n if (!isObject(obj)) return false\n if (isReactElement(obj)) return true\n\n // Callers traversing the object can pass their own Object.keys() result to\n // avoid allocating the key array twice per visited object\n const objKeys = precomputedKeys ?? Object.keys(obj)\n const isReactObjNode = (objKeys.includes('tag') && objKeys.includes('containerInfo'))\n || objKeys.some(k => k.startsWith('__reactContainer'))\n || (objKeys.includes('tag') && objKeys.includes('stateNode'))\n\n return isReactObjNode\n}\n\n\nexport function isValidReactiveObject <T extends Record<string, any>> (value: T): boolean {\n return isObject(value) && !isReactElement(value) && !(value as any)[nonReactiveObjectSymbol]\n}\n\n\n\n/**\n * Returns the actual target value instead of root\n * object with internals props like $$value$$\n *\n * @param target - object from subscription or proxy\n * @returns actual value\n */\nexport const okTarget = (target: any): any => target[INTERNAL_VALUE_PROP] ?? target\n\n\n\n\n/**\n * Gets an object with just the properties requested\n * instead of the full object\n *\n * @param properties - object properties\n * @param obj - target to get the properties\n * @returns New object with just the requested properties\n */\nexport function getPartialObjectFromProperties<T> (properties: Array<keyof T>, obj: T): any {\n return properties.reduce<any>((acc, curr) => {\n acc[curr] = obj[curr]\n\n return acc\n }, {})\n}\n\n\n\n/**\n * Walks a dotted path ('address.city', 'meta.tags') inside an object.\n * Returns undefined when any segment is missing or an intermediate node\n * is not traversable (primitive/null)\n * @param obj - object to walk\n * @param path - dotted field path, relative to obj\n * @returns the value at the path, or undefined\n */\nexport function getValueAtPath (obj: any, path: string): any {\n const segments = path.split('.')\n\n let current = obj\n\n for (let i = 0; i < segments.length; i++) {\n if (current === null || typeof current !== 'object') return undefined\n current = current[segments[i]]\n }\n\n return current\n}\n\n\n\n\nconst stringify = (obj: any): string => JSON.stringify(safeToJson(obj))\n\n\n// Nodes the JSON projection treats specially (React elements, React\n// internals, DOM elements): compared through safeToJson instead of key-by-key\nconst isJsonExoticNode = (obj: any, keys: Array<string>): boolean => (\n isReactObjectLikeNode(obj, keys)\n || (!!globalThis?.HTMLElement && obj instanceof globalThis.HTMLElement)\n)\n\n\n/**\n * Structural equivalent of comparing the two safeToJson projections, with\n * early exit and zero string/tree allocations (this runs on every `$value`\n * set and nested-object reassignment): `undefined`/function-valued keys are\n * skipped (JSON drops them), such array elements compare as `null`, complex\n * leaves (Date, Map, Set...) are opaque and circular references only match\n * when both sides cycle. React/DOM nodes fall back to their safeToJson\n * projection. Key order is irrelevant and NaN equals NaN β both intended\n * divergences from the previous stringify-based comparison\n */\nfunction deepEqualJson (a: any, b: any, aSeen: WeakSet<object> | null, bSeen: WeakSet<object> | null): boolean {\n if (a === b) return true\n\n if (Number.isNaN(a)) return Number.isNaN(b)\n\n if (!a || !b || typeof a !== 'object' || typeof b !== 'object') return false\n\n // Circular reference (cut by the JSON traversal): equal only if both cycle\n const aCycles = !!aSeen && aSeen.has(a)\n const bCycles = !!bSeen && bSeen.has(b)\n\n if (aCycles || bCycles) return aCycles && bCycles\n\n const aIsArray = Array.isArray(a)\n\n if (aIsArray !== Array.isArray(b)) return false\n\n // Ancestor tracking is paid lazily, right before the first recursion into\n // an object-typed value: flat objects (the hot case) never touch a WeakSet\n let tracked = false\n\n let result = true\n\n if (aIsArray) {\n result = a.length === b.length\n\n for (let i = 0; result && i < a.length; i++) {\n const aItem = a[i] === undefined || typeof a[i] === 'function' ? null : a[i]\n const bItem = b[i] === undefined || typeof b[i] === 'function' ? null : b[i]\n\n if (!tracked && ((aItem && typeof aItem === 'object') || (bItem && typeof bItem === 'object'))) {\n tracked = true\n aSeen = aSeen ?? new WeakSet()\n bSeen = bSeen ?? new WeakSet()\n aSeen.add(a)\n bSeen.add(b)\n }\n\n result = deepEqualJson(aItem, bItem, aSeen, bSeen)\n }\n } else {\n const aKeys = Object.keys(a)\n const bKeys = Object.keys(b)\n\n if (isJsonExoticNode(a, aKeys) || isJsonExoticNode(b, bKeys)) {\n result = stringify(a) === stringify(b)\n } else {\n // Compare by key name (order-independent), skipping values JSON drops.\n // `serializableBalance` nets a's comparable keys against b's, so b\n // cannot hide extra keys behind matching ones\n let serializableBalance = 0\n\n for (let i = 0; result && i < aKeys.length; i++) {\n const aValue = a[aKeys[i]]\n\n if (aValue === undefined || typeof aValue === 'function') continue\n\n serializableBalance++\n const bValue = b[aKeys[i]]\n\n if (bValue === undefined || typeof bValue === 'function') {\n result = false\n } else {\n if (!tracked && ((aValue && typeof aValue === 'object') || (bValue && typeof bValue === 'object'))) {\n tracked = true\n aSeen = aSeen ?? new WeakSet()\n bSeen = bSeen ?? new WeakSet()\n aSeen.add(a)\n bSeen.add(b)\n }\n\n result = deepEqualJson(aValue, bValue, aSeen, bSeen)\n }\n }\n\n if (result) {\n for (let i = 0; i < bKeys.length; i++) {\n const bValue = b[bKeys[i]]\n\n if (bValue !== undefined && typeof bValue !== 'function') serializableBalance--\n }\n\n result = serializableBalance === 0\n }\n }\n }\n\n if (tracked) {\n (aSeen as WeakSet<object>).delete(a);\n (bSeen as WeakSet<object>).delete(b)\n }\n\n return result\n}\n\n\n/**\n * Compare 2 provided objects by content\n * (safe against circular references and React internals)\n * @param a - first object\n * @param b - second object\n * @returns boolean\n */\nexport const contentComparer = (a: any, b: any): boolean => deepEqualJson(a, b, null, null)\n\n\n\n\nexport function safeToJson (obj: any, ancestors = new WeakSet<object>()): Record<string, any> {\n if (typeof obj !== 'object' || obj == null)\n return obj\n\n // Circular reference: cut the cycle to keep the traversal finite\n if (ancestors.has(obj))\n return null as any\n\n if (Array.isArray(obj)) {\n ancestors.add(obj)\n const arr = obj.map(item => safeToJson(item, ancestors))\n\n ancestors.delete(obj)\n\n return arr\n }\n\n if (isReactElement(obj)) {\n ancestors.add(obj)\n const element = { props: safeToJson(obj.props, ancestors), type: typeof obj.type === 'string' ? obj.type : '' }\n\n ancestors.delete(obj)\n\n return element\n }\n\n if (globalThis?.HTMLElement && obj instanceof globalThis.HTMLElement) return { type: '[HTMLElement]', content: obj.innerHTML }\n\n // Keys computed once, shared between the react-node check and the copy\n // loop (no [key, value] tuple per property either β hot path)\n const keys = Object.keys(obj)\n\n // React internals (fibers, containers...) are huge and circular: treat them\n // as opaque values instead of traversing them (same rule as deepClone)\n if (isReactObjectLikeNode(obj, keys))\n return { type: '[ReactNode]' }\n\n const o: Record<string, any> = {}\n\n ancestors.add(obj)\n\n for (let i = 0; i < keys.length; i++)\n o[keys[i]] = safeToJson(obj[keys[i]], ancestors)\n\n ancestors.delete(obj)\n\n return o\n}\n","\nimport { contentComparer, deepClone, isValidReactiveObject, safeToJson } from '../utils/object'\n\nimport type { StoreChange } from '../../types/shared'\nimport type { CacheableSubject } from '../utils/subject'\n\n\n\n// INFO: !Internal only.\n// Read through a proxy of this store, returns the raw object it currently wraps\nexport const RAW_VALUE = Symbol('rawValue')\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 // Nested proxies only: the parent's `live` resolver, the parent proxy\n // itself and the key this proxy sits under\n parent?: () => any\n parentProxy?: any\n key?: PropertyKey\n // Live raw of the whole store (for `storeValue` in emitted changes)\n rootRaw?: () => any\n afterChange?: (storeChange: Array<StoreChange<T>>) => void\n } = {},\n): T {\n const fieldPath = opts.nestedFieldPath ?? 'root'\n const isRoot = opts.parent === undefined\n const key = opts.key as PropertyKey\n\n // Emitted paths are root-relative: precomputing the prefix (dropping the\n // leading 'root.') avoids a string scan + replace on every write\n const emitPrefix = isRoot ? '' : `${fieldPath.slice(5)}.`\n\n // The Proxy target is just a shell: the data lives in the `raw` closure\n const shell = {} as unknown as T\n\n // Child proxies are cached here (keyed by property name) instead of being\n // written back into the raw data, so the store data never holds Proxy\n // instances. Entries are never dropped: a child proxy is a live view of\n // `parent[key]` (see `resolveRaw`), so its identity survives reassigning the\n // field and even replacing the whole store. The raw the slot held when the\n // entry was last refreshed is kept for the read fast path\n const childProxies = new Map<PropertyKey, { proxy: any, raw: any }>()\n\n // Raw object this proxy currently wraps (the root's is the whole store)\n let raw: any = objectToProxify\n let isDetached = false\n // Store version a nested proxy last resolved its slot at\n // every store mutation bumps it, so while it is unchanged `raw` is still the live one\n // and reads pay a single property compare (no call)\n let seenVersion = -1\n\n // Cold path (nested proxies, after a store write)\n // re-read the slot on the parent's live raw.\n // When the field, an ancestor or the whole store\n // ($value / reset / initialValue seed) was reassigned, a captured handle\n // keeps reading and writing the live data instead of a disconnected\n // object. Proxies of this store injected as data (e.g.\n // `store.a = { ...store.a }` spreads child proxies) are healed on the way\n const revalidate = (): void => {\n // Set before walking\n // healing a proxy reads through its traps, which may\n // resolve back into this one (self or mutual injection) β the re-entry\n // then sees an up-to-date version and answers with the current raw\n seenVersion = store$$.state.version\n\n // The root IS the live data: nothing to walk (keeps the hot-path check\n // below free of an `isRoot` branch)\n if (isRoot) return\n\n const parent = opts.parent!()\n let liveValue = parent === undefined ? undefined : parent[key]\n\n if (liveValue !== raw && isValidReactiveObject(liveValue)) {\n const injected = liveValue[RAW_VALUE]\n\n if (injected) parent[key] = liveValue = injected\n\n raw = liveValue\n }\n\n // The slot no longer holds an object (null, primitive, array,\n // nonReactive, React element) or an ancestor is gone\n isDetached = liveValue !== raw\n }\n\n const resolveRaw = (): any => {\n if (store$$.state.version !== seenVersion) revalidate()\n\n return raw\n }\n\n // Same as `resolveRaw` but undefined when this path no longer exists in the store\n // writes through a detached proxy are dropped instead of emitting a\n // change that is not in the store\n const liveRawObject = (): any => {\n const value = resolveRaw()\n\n return isDetached ? undefined : value\n }\n\n const rootRaw = opts.rootRaw ?? ((): any => raw)\n\n // Created once per proxy (a fresh closure per read was allocated before)\n const toJson = (): any => safeToJson(resolveRaw())\n\n // Bound functions are cached per raw function so repeated reads return the\n // same reference (stable identity for React deps) instead of re-binding on\n // every access. Keyed by the raw function: reassigning the property to a\n // different function re-binds automatically\n const boundFunctions = new WeakMap<(...args: Array<any>) => any, (...args: Array<any>) => any>()\n\n const rootFunctions = isRoot\n ? Object.fromEntries(Object.entries(objectToProxify).filter(([,v]) => typeof v === 'function'))\n : {}\n\n const emit = (change: StoreChange<T>): void => {\n store$$.next(change)\n opts.afterChange?.([change])\n }\n\n return new Proxy(shell, {\n get (_, propName, receiver) {\n // Inlined `resolveRaw()`: this is the hottest path of the library\n if (store$$.state.version !== seenVersion) revalidate()\n\n const target = raw\n\n if (typeof propName === 'symbol') {\n if (propName === RAW_VALUE) return target\n\n return target[propName]\n }\n\n // INFO: !Internal only.\n // Used to get the fieldPath of the object (it means it's a proxified object)\n if (propName === '_$fieldPath') return fieldPath\n\n // Called when the object is converted to JSON or string (i.e. JSON.stringify).\n // safeToJson removes react-elements with circular references before\n // stringifying to prevent JSON.stringify(storeProxy) from failing\n if (propName === 'toJSON') return toJson\n\n // Get the whole store value without proxies\n if (propName === '$value')\n return deepClone(target)\n\n let propertyValue = target[propName]\n\n if (typeof propertyValue === 'function') {\n let boundFunction = boundFunctions.get(propertyValue)\n\n if (!boundFunction) {\n // Bound to the proxy (receiver), so `this.prop` inside store\n // functions keeps reading/writing through the traps (reactive)\n boundFunction = (propertyValue as () => any).bind(receiver)\n boundFunctions.set(propertyValue, boundFunction)\n }\n\n return boundFunction\n }\n\n if (propertyValue !== null && typeof propertyValue === 'object') {\n const entry = childProxies.get(propName)\n\n if (entry !== undefined && entry.raw === propertyValue) return entry.proxy\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 // Proxy of this store injected as data by the user: heal the slot\n // with the raw object it wraps, so the store data stays Proxy-free\n const injectedProxy = propertyValue[RAW_VALUE]\n\n if (injectedProxy) target[propName] = propertyValue = injectedProxy\n\n // Reassigned field: keep the child's identity (it resolves the new\n // raw on its own) and just refresh the fast-path key\n if (entry !== undefined) {\n entry.raw = propertyValue\n\n return entry.proxy\n }\n\n const child = proxifyStore(\n store$$ as any,\n propertyValue,\n {\n nestedFieldPath: `${fieldPath}.${propName}`,\n parent: liveRawObject,\n parentProxy: receiver,\n key: propName,\n rootRaw,\n afterChange: opts.afterChange,\n },\n )\n\n childProxies.set(propName, { proxy: child, raw: propertyValue })\n\n return child\n }\n }\n\n return propertyValue\n },\n\n\n set (_, propName, newValue) {\n if (typeof propName === 'symbol') return true\n\n // Keep raw data clean: if a proxy of this store is assigned as a value,\n // store the raw object it wraps instead of the Proxy instance (the\n // typeof guard lets primitive writes skip the symbol-prop lookup)\n const value = newValue !== null && typeof newValue === 'object'\n ? newValue[RAW_VALUE] ?? newValue\n : newValue\n\n // INFO: !Internal only.\n // Used to set the value of the store without notifying the current subscriber (value.id)\n if (propName === '$$value' && isRoot) {\n const previousValue = raw\n\n // Same merge as `$value`: top-level store functions are preserved when\n // the new value (e.g. from useStore's initialValue) does not include them\n raw = Object.assign({}, rootFunctions, deepClone(value.newValue))\n\n const seedChange = {\n storeValue: raw,\n change: {\n fieldPath: 'root' as any,\n newValue: value.newValue,\n previousValue,\n },\n }\n\n store$$.next(seedChange, value.id)\n\n // Seeds are render-phase writes (useStore's initialValue): the hook is\n // deferred so user code never runs inside a React render\n if (opts.afterChange) queueMicrotask(() => { opts.afterChange!([seedChange]) })\n\n return true\n }\n\n if (propName === '$value') {\n // Nested: replacing this object is a plain write into the parent\n if (!isRoot) {\n opts.parentProxy[key] = value\n\n return true\n }\n\n const previousValue = raw\n\n if (value === previousValue || contentComparer(value, previousValue)) return true\n\n // Cloned like the initial value: the store never aliases the caller's\n // object and any proxies spread into it (`{ ...store }`) are unwrapped.\n // Object.assign instead of spread: it avoids shipping Babel's\n // `_extends` helper in the bundle\n raw = Object.assign({}, rootFunctions, deepClone(value))\n\n emit({\n storeValue: raw,\n change: {\n fieldPath: 'root' as any,\n newValue: value,\n previousValue,\n },\n })\n\n return true\n }\n\n const validRawObject = liveRawObject()\n\n // Detached handle (its path is gone from the store): drop the write\n if (validRawObject === undefined) return true\n\n const previousValue = validRawObject[propName]\n\n if (previousValue === value) return true\n\n // Content-equal object writes are no-ops (arrays, nonReactive objects\n // and React elements always notify)\n if (isValidReactiveObject(value) && contentComparer(value, previousValue)) return true\n\n validRawObject[propName] = value\n\n emit({\n storeValue: rootRaw(),\n change: {\n fieldPath: (emitPrefix + propName) as any,\n newValue: value,\n previousValue,\n },\n })\n\n return true\n },\n\n has (_, p) {\n return Reflect.has(resolveRaw(), p)\n },\n\n ownKeys () {\n return Reflect.ownKeys(resolveRaw())\n },\n\n getOwnPropertyDescriptor (_, p) {\n return Reflect.getOwnPropertyDescriptor(resolveRaw(), p)\n },\n\n })\n}\n","\nimport { useEffect, useId, useRef, useState } from 'react'\n\nimport { nonReactiveObjectSymbol } from '../../types/shared'\nimport { proxifyStore, RAW_VALUE } from '../helpers/new-proxify-store'\nimport { contentComparer, deepClone, getValueAtPath } from '../utils/object'\nimport { createCacheableSubject } from '../utils/subject'\n\nimport type { FieldPath, StoreChange } from '../../types/shared'\n\n\n\n\n\nexport type CervelloOptions<StoreValue extends Record<string, any>> = {\n afterChange?: (storeChange: Array<StoreChange<StoreValue>>) => void\n}\n\nexport type CervelloUseStoreOptions<StoreValue extends Record<string, any>> = {\n initialValue?: (currentStore: StoreValue) => StoreValue | null,\n setValueOnMount?: (currentStore: StoreValue) => Promise<StoreValue>,\n select?:\n | Array<FieldPath<StoreValue>>\n | (() => Array<FieldPath<StoreValue>>)\n onChange?: (storeChange: Array<StoreChange<StoreValue>>) => void\n}\n\ntype MutableStoreValue<T extends Record<string, any>> = {\n $value: T\n} & T\n\n\n\n\n\n\n\n\nexport function nonReactive <T extends Record<string, any>> (initialValue: T): T {\n Object.defineProperty(initialValue, nonReactiveObjectSymbol, {\n value: true,\n enumerable: false,\n writable: false,\n configurable: false,\n })\n\n return initialValue\n}\n\n\nexport function cervello <StoreValue extends Record<PropertyKey, any>> (\n initialValue: StoreValue,\n options?: CervelloOptions<StoreValue>,\n): {\n store: MutableStoreValue<StoreValue>,\n reset: () => void,\n useStore: (options?: CervelloUseStoreOptions<StoreValue>) => MutableStoreValue<StoreValue>\n } {\n const {\n afterChange,\n } = options ?? {}\n\n const clonedInitialValue = deepClone(initialValue)\n\n const store$$ = createCacheableSubject<StoreChange<StoreValue>>()\n\n const proxiedStore = proxifyStore(\n store$$ as any,\n clonedInitialValue,\n { afterChange },\n ) as MutableStoreValue<StoreValue>\n\n\n return {\n store: proxiedStore,\n reset: () => {\n // The `$value` setter already stores a deep clone\n proxiedStore.$value = initialValue\n },\n useStore: (options) => {\n const subscriberId = useId()\n const isInitialValueSet = useRef(false)\n const [, setRenderCount] = useState(0)\n\n // Latest options are read through this ref by the subscription (created\n // once per mount), so callbacks like `onChange` are never stale closures\n const optionsRef = useRef(options)\n\n optionsRef.current = options\n\n // useState-like semantics: `initialValue` runs only on the first render\n // (SSR included), so the store traversals it needs (clone + compare)\n // are paid once per mount instead of on every re-render\n if (!isInitialValueSet.current) {\n isInitialValueSet.current = true\n\n const initialValue = options?.initialValue?.(proxiedStore.$value)\n\n // Compared against the raw value (not `$value`): contentComparer is\n // already cycle-safe, so this skips a second full deep clone per mount\n if (initialValue && !contentComparer(initialValue, (proxiedStore as any)[RAW_VALUE]))\n (proxiedStore as any).$$value = { id: subscriberId, newValue: initialValue }\n }\n\n // Version of the store this render is based on. Captured AFTER the\n // `initialValue` seed so the component's own seed does not re-trigger it\n const seenVersion = useRef(0)\n\n seenVersion.current = store$$.version()\n\n // `select` is frozen from the first render (computed lazily, once)\n const selectFieldPaths = useRef<Array<FieldPath<StoreValue>> | null>(null)\n\n if (selectFieldPaths.current === null) {\n selectFieldPaths.current = (\n typeof options?.select === 'function'\n ? options.select()\n : options?.select\n ) ?? []\n }\n\n const selectedFieldPathsForNestedObjects = useRef<Array<string> | null>(null)\n\n if (selectedFieldPathsForNestedObjects.current === null) {\n // The trailing dot is kept ('address.*' -> 'address.') so matching is\n // a single startsWith against the dotted changed path\n selectedFieldPathsForNestedObjects.current = selectFieldPaths.current\n .filter(fp => fp.includes('.*'))\n .map(fp => fp.replace('*', ''))\n }\n\n const reRender = (): void => {\n setRenderCount(p => p + 1)\n }\n\n\n useEffect(() => {\n if (options?.setValueOnMount) {\n void options.setValueOnMount(proxiedStore.$value).then((value) => {\n proxiedStore.$value = value\n }).catch((err) => {\n console.error('Error setting initial value on mount', err)\n })\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [])\n\n\n // Same implementation as useSyncExternalStore but with useEffect.\n // Subscribed once per mount: `select` is frozen from the first render\n // and the latest callbacks are read through `optionsRef`\n useEffect(() => {\n // All three lists are frozen from the first render, so they can be\n // captured once per subscription instead of on every notification\n const selectedPaths = selectFieldPaths.current ?? []\n const wildcardPrefixes = selectedFieldPathsForNestedObjects.current ?? []\n\n // Targets for ancestor-change comparison: exact paths as-is, wildcards\n // reduced to their base ('address.*' -> 'address')\n const compareTargets = selectedPaths.map(fp => fp.replace('.*', ''))\n\n // Changes flushed between the render and this effect (React yields\n // before the passive-effects task when a commit exceeds the frame\n // budget) were emitted before the subscription existed β recover them\n // with one re-render, since reads through the proxy are always live\n if (store$$.version() !== seenVersion.current) reRender()\n\n const subscription = store$$.subscribe({\n id: subscriberId,\n next: (storeChanges) => {\n const currentOptions = optionsRef.current\n\n // Already rendered after every write flushed so far (e.g. a\n // handler calls setState and then writes to the store: React\n // renders the SyncLane update before this microtask runs, and the\n // render reads the store live) β same check as\n // useSyncExternalStore's `checkIfSnapshotChanged`, so the render\n // is skipped while `onChange` still fires\n const needsRender = store$$.version() !== seenVersion.current\n\n if (!currentOptions?.select) {\n if (needsRender) reRender()\n currentOptions?.onChange?.(storeChanges)\n\n return\n }\n\n if (storeChanges.some((nextChange) => {\n const changedPath = nextChange.change.fieldPath\n const dottedPath = `${changedPath}.`\n\n // Path-level matches: the set trap already guaranteed the\n // written value changed content, so no re-comparison is needed.\n // Checked before the 'root' branch: `select` can only contain\n // 'root' for a top-level field literally named `root`, and\n // whole-store changes then over-render (safe) instead of being\n // refined against the field's value\n if (selectedPaths.includes(changedPath)) return true\n\n // 'address.*' (kept as 'address.') matches 'address' and\n // 'address.<nested>', but not a sibling field sharing the\n // prefix (e.g. 'addressLine')\n if (wildcardPrefixes.some(fp => dottedPath.startsWith(fp))) return true\n\n // Ancestor changes ('root', or 'address' for 'address.city'):\n // the selected slice may or may not have changed inside the\n // reassigned object, so re-render only if its content differs.\n // Compared at flush time: `newValue` is the live raw, so several\n // same-microtask writes are seen in their final (converged)\n // state β same guarantee the batch already gives for storeValue\n return compareTargets.some((target) => {\n if (changedPath !== 'root' && !target.startsWith(dottedPath)) return false\n\n const remainingPath = changedPath === 'root'\n ? target\n : target.slice(dottedPath.length)\n\n return !contentComparer(\n getValueAtPath(nextChange.change.previousValue, remainingPath),\n getValueAtPath(nextChange.change.newValue, remainingPath),\n )\n })\n })) {\n if (needsRender) reRender()\n currentOptions?.onChange?.(storeChanges)\n }\n },\n })\n\n return () => {\n subscription.unsubscribe()\n }\n\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [])\n\n return proxiedStore\n },\n }\n}\n","type Observer<T> = {\n id: string\n // Changes are always delivered in batches (one flush per microtask)\n next: (values: Array<T>) => void\n}\n\ntype Subscription = {\n unsubscribe: () => void\n}\n\ntype FlushItem<T> = {\n newValue: T\n subscriberId?: string\n}\n\nexport type CacheableSubject<T> = {\n subscribe: (observer: Observer<T>) => Subscription\n next: (value: T, subscriberId?: string) => void\n version: () => number\n // Same counter as `version()`, readable without a call (proxy hot path)\n state: { version: number }\n}\n\nexport function createCacheableSubject<T> (): CacheableSubject<T> {\n let isScheduled = false\n let isFlushing = false\n // Monotonic write counter, bumped at write time (not flush time) so a\n // subscriber can detect changes emitted before its subscription existed\n const state = { version: 0 }\n // True when any queued item carries a subscriberId (self-notification\n // exclusion needed): tracked at write time to pick the flush fast path\n let hasIds = false\n const observerList: Array<Observer<T>> = []\n let updateList: Array<FlushItem<T>> = []\n\n\n /** Pushes a new value to the subject and schedules a flush if not already scheduled or flushing.\n * `newValue`:\n * The new value to be emitted to subscribers.\n *\n * `subscriberId`: (Optional)\n * identifier for the subscriber that triggered the update, used to prevent self-notifications. (usage in initialValue)\n */\n function next (newValue: T, subscriberId?: string): void {\n state.version++\n\n if (subscriberId !== undefined) hasIds = true\n updateList.push({ newValue, subscriberId })\n\n if (!isScheduled && !isFlushing)\n scheduleFlush()\n }\n\n\n function subscribe (observer: Observer<T>): Subscription {\n observerList.push(observer)\n\n return {\n unsubscribe: () => {\n const idx = observerList.indexOf(observer)\n\n if (idx !== -1)\n observerList.splice(idx, 1)\n },\n }\n }\n\n\n\n // A subscriber that throws (typically a user `onChange`) must not break the\n // delivery loop nor leave `isFlushing` stuck: the error is re-thrown from\n // its own microtask (reaches window.onerror) and the flush carries on\n function deliver (observer: Observer<T>, values: Array<T>): void {\n try {\n observer.next(values)\n } catch (err) {\n queueMicrotask(() => { throw err })\n }\n }\n\n\n // Hoisted (instead of a fresh closure per scheduled flush) and reused by\n // every queueMicrotask call\n function flush (): void {\n isScheduled = false\n\n if (isFlushing || updateList.length === 0) return\n\n isFlushing = true\n\n // Snapshot by swap (no copy): new updates arriving while flushing are\n // collected into a fresh list\n const changesSnapshot = updateList\n const snapshotHasIds = hasIds\n\n updateList = []\n hasIds = false\n\n // Snapshot the observers too: a synchronous unsubscribe from inside a\n // callback must not shift the delivery loop and skip an observer\n const observersSnapshot = observerList.slice()\n\n // Plain indexed loops: for...of over arrays makes the build ship Babel's\n // iterator-interop helpers, which weigh more than this whole module\n if (!snapshotHasIds) {\n // Fast path (the common case): no self-notification exclusions, so all\n // observers with an id share ONE values array instead of allocating a\n // filtered copy each. Observers without id are excluded, exactly like\n // the filtered path does (undefined === undefined)\n const values: Array<T> = []\n\n for (let i = 0; i < changesSnapshot.length; i++)\n values.push(changesSnapshot[i].newValue)\n\n for (let i = 0; i < observersSnapshot.length; i++) {\n if (observersSnapshot[i].id !== undefined)\n deliver(observersSnapshot[i], values)\n }\n } else {\n for (let i = 0; i < observersSnapshot.length; i++) {\n const observer = observersSnapshot[i]\n const filtered: Array<T> = []\n\n for (let j = 0; j < changesSnapshot.length; j++) {\n if (changesSnapshot[j].subscriberId !== observer.id)\n filtered.push(changesSnapshot[j].newValue)\n }\n\n if (filtered.length > 0)\n deliver(observer, filtered)\n }\n }\n\n isFlushing = false\n\n // Re-check if there are new updates that came in during the flush\n if (updateList.length > 0)\n scheduleFlush()\n }\n\n\n function scheduleFlush (): void {\n if (isScheduled || isFlushing || updateList.length === 0) return\n isScheduled = true\n\n queueMicrotask(flush)\n }\n\n\n\n\n return { next, subscribe, version: () => state.version, state }\n}\n"],"names":["nonReactiveObjectSymbol","Symbol","cloneNonReactive","obj","refs","has","get","Date","getTime","isReactObjectLikeNode","Array","isArray","arr","set","forEach","item","idx","Map","map","v","k","Set","add","constructor","Object","o","keys","i","length","symbols","getOwnPropertySymbols","ancestors","WeakSet","WeakMap","cloned","clonedArray","deepClone","newObj","_i2","isObject","isReactElement","$$typeof","precomputedKeys","objKeys","includes","some","startsWith","isValidReactiveObject","value","getValueAtPath","path","segments","split","current","stringify","JSON","safeToJson","isJsonExoticNode","globalThis","HTMLElement","a","b","aSeen","bSeen","Number","isNaN","aCycles","bCycles","aIsArray","tracked","result","undefined","bItem","aItem","_aSeen","_bSeen","deepEqualJson","aKeys","bKeys","aValue","serializableBalance","_aSeen2","_bSeen2","bValue","_i4","contentComparer","element","props","type","content","innerHTML","RAW_VALUE","proxifyStore","store$$","objectToProxify","opts","fieldPath","nestedFieldPath","isRoot","parent","key","emitPrefix","slice","childProxies","raw","isDetached","seenVersion","revalidate","state","version","liveValue","injected","resolveRaw","liveRawObject","rootRaw","_opts$rootRaw","toJson","boundFunctions","rootFunctions","fromEntries","entries","filter","_ref","emit","change","next","afterChange","Proxy","_","propName","receiver","target","propertyValue","boundFunction","bind","entry","proxy","injectedProxy","parentProxy","child","newValue","_newValue$RAW_VALUE","_previousValue","seedChange","storeValue","assign","previousValue","id","queueMicrotask","_previousValue2","validRawObject","p","Reflect","ownKeys","getOwnPropertyDescriptor","nonReactive","initialValue","defineProperty","enumerable","writable","configurable","cervello","options","clonedInitialValue","isScheduled","isFlushing","hasIds","observerList","updateList","deliver","observer","values","err","changesSnapshot","observersSnapshot","snapshotHasIds","filtered","j","subscriberId","push","scheduleFlush","flush","subscribe","unsubscribe","indexOf","splice","createCacheableSubject","proxiedStore","store","reset","$value","useStore","useId","isInitialValueSet","useRef","setRenderCount","useState","optionsRef","$$value","selectFieldPaths","_ref2","select","selectedFieldPathsForNestedObjects","fp","replace","reRender","useEffect","setValueOnMount","then","console","error","selectedPaths","_selectFieldPaths$cur","wildcardPrefixes","_selectedFieldPathsFo","subscription","storeChanges","needsRender","currentOptions","onChange","nextChange","changedPath","dottedPath","compareTargets","remainingPath"],"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": "
|
|
4
|
+
"version": "6.0.0",
|
|
5
5
|
"description": "π€― Simple, reactive, tiny and performant state-management library",
|
|
6
6
|
"author": "Chempo",
|
|
7
7
|
"license": "MIT",
|
|
@@ -52,16 +52,6 @@
|
|
|
52
52
|
"dist",
|
|
53
53
|
"types"
|
|
54
54
|
],
|
|
55
|
-
"scripts": {
|
|
56
|
-
"release": "pnpx bumpp --push=false && npm publish --access public",
|
|
57
|
-
"docs:dev": "pnpm run --filter @cervello/react docs:dev",
|
|
58
|
-
"publish:beta": "npm publish --tag beta",
|
|
59
|
-
"test": "vitest --watch",
|
|
60
|
-
"test:release": "vitest run",
|
|
61
|
-
"prepublishOnly": "pnpm build",
|
|
62
|
-
"build": "(rm -rf types & rm -rf dist) && microbundle",
|
|
63
|
-
"dev": "microbundle watch"
|
|
64
|
-
},
|
|
65
55
|
"peerDependencies": {
|
|
66
56
|
"react": ">= 18.2.0"
|
|
67
57
|
},
|
|
@@ -71,9 +61,21 @@
|
|
|
71
61
|
"@types/react": "18.2.33",
|
|
72
62
|
"microbundle": "0.15.1",
|
|
73
63
|
"react": "18.2.0",
|
|
64
|
+
"react-dom": "18.2.0",
|
|
74
65
|
"typescript": "5.6.2",
|
|
75
66
|
"vite": "4.5.0",
|
|
76
67
|
"vitest": "3.0.7",
|
|
77
68
|
"vitest-react": "0.9.5"
|
|
69
|
+
},
|
|
70
|
+
"scripts": {
|
|
71
|
+
"publish:release": "npm publish --registry=https://registry.npmjs.org/ --//registry.npmjs.org/:_authToken=XXX",
|
|
72
|
+
"release": "pnpx bumpp --push=false && npm publish --access public",
|
|
73
|
+
"docs:dev": "pnpm run --filter @cervello/react docs:dev",
|
|
74
|
+
"publish:beta": "npm publish --tag beta",
|
|
75
|
+
"test": "vitest --watch",
|
|
76
|
+
"test:release": "vitest run",
|
|
77
|
+
"bench": "vitest bench --run",
|
|
78
|
+
"build": "(rm -rf types & rm -rf dist) && microbundle -f esm,cjs",
|
|
79
|
+
"dev": "microbundle watch"
|
|
78
80
|
}
|
|
79
|
-
}
|
|
81
|
+
}
|
package/types/index.d.ts
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import type { StoreChange } from '../../types/shared';
|
|
2
2
|
import type { CacheableSubject } from '../utils/subject';
|
|
3
|
+
export declare const RAW_VALUE: unique symbol;
|
|
3
4
|
export declare function proxifyStore<T extends Record<string | symbol, any>>(store$$: CacheableSubject<StoreChange<T>>, objectToProxify: T, opts?: {
|
|
4
5
|
nestedFieldPath?: string;
|
|
5
|
-
|
|
6
|
+
parent?: () => any;
|
|
7
|
+
parentProxy?: any;
|
|
8
|
+
key?: PropertyKey;
|
|
9
|
+
rootRaw?: () => any;
|
|
6
10
|
afterChange?: (storeChange: Array<StoreChange<T>>) => void;
|
|
7
11
|
}): T;
|
|
@@ -2,11 +2,18 @@
|
|
|
2
2
|
* Clones all the provided object and nested properties and it also
|
|
3
3
|
* iterates nested arrays to deepClone them
|
|
4
4
|
*
|
|
5
|
+
* Circular references are considered invalid store values, so they are cut
|
|
6
|
+
* to `null` instead of recursing forever. The exceptions are React
|
|
7
|
+
* elements/nodes (kept by reference) and nonReactive()-wrapped objects,
|
|
8
|
+
* which are cloned structurally so complex values (Date, Map, Set, circular
|
|
9
|
+
* references...) survive intact β this keeps the store copy decoupled from
|
|
10
|
+
* the caller's object and allows reset() to restore the initial state
|
|
11
|
+
*
|
|
5
12
|
* @param obj - base object to be cloned
|
|
13
|
+
* @param ancestors - objects of the current traversal path, to detect cycles
|
|
6
14
|
* @returns new cloned object with new reference
|
|
7
15
|
*/
|
|
8
|
-
export declare function deepClone<T>(obj: T): T;
|
|
9
|
-
export declare function deepClone2<T>(obj: T): T;
|
|
16
|
+
export declare function deepClone<T>(obj: T, ancestors?: WeakSet<object>): T;
|
|
10
17
|
/**
|
|
11
18
|
* Guard to check is variable is an object
|
|
12
19
|
* @param obj - variable to be checked
|
|
@@ -14,7 +21,7 @@ export declare function deepClone2<T>(obj: T): T;
|
|
|
14
21
|
*/
|
|
15
22
|
export declare const isObject: (obj: unknown) => obj is Record<string | symbol, unknown>;
|
|
16
23
|
export declare const isReactElement: (obj: unknown) => boolean;
|
|
17
|
-
export declare function isReactObjectLikeNode(obj: unknown): boolean;
|
|
24
|
+
export declare function isReactObjectLikeNode(obj: unknown, precomputedKeys?: Array<string>): boolean;
|
|
18
25
|
export declare function isValidReactiveObject<T extends Record<string, any>>(value: T): boolean;
|
|
19
26
|
/**
|
|
20
27
|
* Returns the actual target value instead of root
|
|
@@ -34,10 +41,20 @@ export declare const okTarget: (target: any) => any;
|
|
|
34
41
|
*/
|
|
35
42
|
export declare function getPartialObjectFromProperties<T>(properties: Array<keyof T>, obj: T): any;
|
|
36
43
|
/**
|
|
37
|
-
*
|
|
44
|
+
* Walks a dotted path ('address.city', 'meta.tags') inside an object.
|
|
45
|
+
* Returns undefined when any segment is missing or an intermediate node
|
|
46
|
+
* is not traversable (primitive/null)
|
|
47
|
+
* @param obj - object to walk
|
|
48
|
+
* @param path - dotted field path, relative to obj
|
|
49
|
+
* @returns the value at the path, or undefined
|
|
50
|
+
*/
|
|
51
|
+
export declare function getValueAtPath(obj: any, path: string): any;
|
|
52
|
+
/**
|
|
53
|
+
* Compare 2 provided objects by content
|
|
54
|
+
* (safe against circular references and React internals)
|
|
38
55
|
* @param a - first object
|
|
39
56
|
* @param b - second object
|
|
40
57
|
* @returns boolean
|
|
41
58
|
*/
|
|
42
59
|
export declare const contentComparer: (a: any, b: any) => boolean;
|
|
43
|
-
export declare function safeToJson(obj: any): Record<string, any>;
|
|
60
|
+
export declare function safeToJson(obj: any, ancestors?: WeakSet<object>): Record<string, any>;
|
|
@@ -1,13 +1,17 @@
|
|
|
1
|
-
type Noop = () => void;
|
|
2
1
|
type Observer<T> = {
|
|
3
2
|
id: string;
|
|
4
|
-
next: (
|
|
3
|
+
next: (values: Array<T>) => void;
|
|
5
4
|
};
|
|
6
5
|
type Subscription = {
|
|
7
|
-
unsubscribe:
|
|
6
|
+
unsubscribe: () => void;
|
|
8
7
|
};
|
|
9
8
|
export type CacheableSubject<T> = {
|
|
10
|
-
subscribe: (
|
|
11
|
-
|
|
9
|
+
subscribe: (observer: Observer<T>) => Subscription;
|
|
10
|
+
next: (value: T, subscriberId?: string) => void;
|
|
11
|
+
version: () => number;
|
|
12
|
+
state: {
|
|
13
|
+
version: number;
|
|
14
|
+
};
|
|
15
|
+
};
|
|
12
16
|
export declare function createCacheableSubject<T>(): CacheableSubject<T>;
|
|
13
17
|
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/cervello.umd.js
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
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)}):function(e){if(!i(e))return!1;if(o(e))return!0;var n=Object.keys(e);return n.includes("tag")&&n.includes("containerInfo")||n.some(function(e){return e.startsWith("__reactContainer")})||n.includes("tag")&&n.includes("stateNode")}(e)?n=e:(Object.entries(e).forEach(function(e){n[e[0]]=u(e[1])}),Object.getOwnPropertySymbols(e).forEach(function(t){n[t]=e[t]})),n}var i=function(e){return null!==e&&"object"==typeof e&&!Array.isArray(e)},o=function(e){return!!i(e)&&!!e.$$typeof};function a(e){return i(e)&&!o(e)&&!e[t]}function l(e){var n={};return"object"!=typeof e||null==e?e:Array.isArray(e)?e.map(function(e){return l(e)}):o(e)?{props:l(e.props),type:"string"==typeof e.type?e.type:""}:null!=globalThis&&globalThis.HTMLElement&&e instanceof globalThis.HTMLElement?{type:"[HTMLElement]",content:e.innerHTML}:(Object.entries(e).forEach(function(e){n[e[0]]=l(e[1])}),n)}"hasOwn"in Object||(Object.hasOwn=Object.call.bind(Object.hasOwnProperty));var c=Symbol("value");function f(e,n,t){var i,o;void 0===t&&(t={});var s=null!=(i=t.nestedFieldPath)?i:"root",h=((o={})[c]=n,o),v="root"===s?Object.fromEntries(Object.entries(n).filter(function(e){return"function"==typeof e[1]})):{};return new Proxy(h,{get:function(n,r,i){if("_$fieldPath"===r)return s;var o=Object.hasOwn(n,c)?n[c]:n;if("toJSON"===r)return function(){return l(o)};if("$value"===r)return u(o);var h=Reflect.get(o,r,i);if("symbol"==typeof r)return h;if("function"==typeof h)return h.bind(i);if(a(h)&&h!==o){var v;if(h._$fieldPath)return h;var b=f(e,h,{nestedFieldPath:s+"."+r,parentObjectToProxify:null!=(v=t.parentObjectToProxify)?v:o,afterChange:t.afterChange});return o[r]=b}return h},set:function(n,u,i,o){var f,h;if("symbol"==typeof u)return!0;var b=i,d=Object.hasOwn(n,c);if(d&&"$$value"===u){var p=n[c];return n[c]=b.newValue,e.next({storeValue:b.newValue,change:{fieldPath:"root",newValue:b.newValue,previousValue:p}},b.id),!0}if(d&&"$value"===u){var y=n[c];return b===y||JSON.stringify(l(b))===JSON.stringify(l(y))||("root"!==s?n[c]=b:(n[c]=r({},v,b),e.next({storeValue:n[c],change:{fieldPath:"root",newValue:b,previousValue:y}}))),!0}var g=d?n[c]:n,O=Reflect.get(g,u,o);if(O===b)return!0;a(b)&&null!=O&&O._$fieldPath?O.$value=b:Reflect.set(g,u,b,g);var j={storeValue:null!=(f=null==(h=t)?void 0:h.parentObjectToProxify)?f:g,change:{fieldPath:(s+"."+u).replace("root.",""),newValue:b,previousValue:O}};return e.next(j),null==t.afterChange||t.afterChange([j]),!0},has:function(e,n){return Reflect.has(e[c],n)},ownKeys:function(e){return Reflect.ownKeys(e[c])},getOwnPropertyDescriptor:function(e,n){return Reflect.getOwnPropertyDescriptor(e[c],n)}})}e.cervello=function(e,t){var r,i,o,a=(null!=t?t:{}).afterChange,c=u(e),s=(r=!1,i=[],o=[],{next:function(e,n){i.push({newValue:e,subscriberId:n}),r||(r=!0,Promise.resolve().then(function(){o.forEach(function(e){var n=i.filter(function(n){return n.subscriberId!==e.id});n.length&&e.next(n.map(function(e){return e.newValue}))}),i=[],r=!1}))},subscribe:function(e){return o.push(e),{unsubscribe:function(){o=o.filter(function(n){return n.id!==e.id})}}}}),h=f(s,c,{afterChange:a});return{store:h,reset:function(){h.$value=u(e)},useStore:function(e){var t,r=n.useId(),u=null==e||null==e.initialValue?void 0:e.initialValue(h.$value),i=n.useRef(!1),o=n.useState(0)[1];!i.current&&u&&JSON.stringify(l(u))!==JSON.stringify(l(h.$value))&&(i.current=!0,h.$$value={id:r,newValue:u});var a=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:[]),c=n.useRef(a.current.filter(function(e){return e.includes(".*")}).map(function(e){return e.replace(".*","")})),f=function(){o(function(e){return e+1})};return n.useEffect(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)})},[]),n.useEffect(function(){var n=s.subscribe({id:r,next:function(n){var t=Array.isArray(n)?n:[n];if(null==e||!e.select)return f(),void(null==e||null==e.onChange||e.onChange(t));t.some(function(e){return"root"===e.change.fieldPath||a.current.includes(e.change.fieldPath)||c.current.find(function(n){return e.change.fieldPath.startsWith(n)})})&&(f(),null==e||null==e.onChange||e.onChange(t))}});return function(){n.unsubscribe()}},[null==e?void 0:e.select,null==e?void 0:e.onChange]),h}}},e.nonReactive=function(e){return Object.defineProperty(e,t,{value:!0,enumerable:!1,writable:!1,configurable:!1}),e}});
|
|
2
|
-
//# sourceMappingURL=cervello.umd.js.map
|
package/dist/cervello.umd.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"cervello.umd.js","sources":["../src/types/shared.ts","../src/lib/utils/object.ts","../src/lib/helpers/new-proxify-store.ts","../src/lib/store/new-index.ts","../src/lib/utils/subject.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/ban-types */\nexport type WithoutType<T, V, WithNever = {\n [K in keyof T]: Exclude<T[K], undefined> extends V\n ? never\n : (T[K] extends Record<string, unknown>\n ? WithoutType<T[K], V>\n : T[K])\n}> = Pick<WithNever, {\n [K in keyof WithNever]: WithNever[K] extends never ? never : K\n}[keyof WithNever]>\n\n\n\nexport type ObjectFromAttributes<T, Attributes extends Array< keyof WithoutType<T, Function> > > = {\n [k in Attributes[number]]: T[k]\n}\n\nexport type Maybe<T> = T | undefined\n\n\n\nexport type UseSelector<T> = <Attributes extends Array< Exclude<keyof WithoutType<T, Function>, '$value'> >>(\n selectors: Attributes,\n isEqualFunction?: (previousState: ObjectFromAttributes<T, Attributes>, currentState: ObjectFromAttributes<T, Attributes>) => boolean,\n) => T\n\nexport type FieldPath<T extends Record<string, any>> = {\n [K in keyof Required<T>]: T[K] extends Record<string, any>\n ? K extends string\n\n ? T[K] extends Function\n ? never\n : T[K] extends Array<any>\n ? K\n : `${K}.*` | `${K}.${FieldPath<T[K]>}`\n : never\n : K extends string\n ? K\n : never\n}[keyof T]\n\nexport const nonReactiveObjectSymbol = Symbol('nonReactiveObject')\nexport type StoreChange<T extends Record<string, any>> = {\n change: {\n fieldPath: FieldPath<T>\n newValue: any\n previousValue: any\n }\n storeValue: T\n}\n","/* eslint-disable no-cond-assign */\n\nimport { nonReactiveObjectSymbol } from '../../types/shared'\nimport { INTERNAL_VALUE_PROP } from '../helpers/constants'\n\n\n/**\n * Clones all the provided object and nested properties and it also\n * iterates nested arrays to deepClone them\n *\n * @param obj - base object to be cloned\n * @returns new cloned object with new reference\n */\nexport function deepClone <T> (obj: T): T {\n if (!obj || typeof obj !== 'object')\n return obj\n\n let newObj = {} as any\n\n if (Array.isArray(obj)) {\n newObj = obj.map(item => deepClone(item))\n } else if (!isReactObjectLikeNode(obj)) {\n Object.entries(obj).forEach(([key, value]) => {\n newObj[key] = deepClone(value)\n })\n Object.getOwnPropertySymbols(obj).forEach((symbol) => {\n newObj[symbol] = (obj as any)[symbol]\n })\n } else {\n newObj = obj\n }\n\n return newObj as T\n}\n\n// function copyBuffer (cur: ArrayBufferView) {\n// if (cur instanceof Buffer)\n// return Buffer.from(cur)\n//\n//\n// return new cur.constructor(cur.buffer.slice(), cur.byteOffset, cur.length)\n// }\n\n\n// INFO: From `rfdc` (really-fast-deep-clone) package for faster cloning taking care of circular references\nexport function deepClone2 <T> (obj: T): T {\n const refs: Array<any> = []\n const refsNew: Array<any> = []\n\n const constructorHandlers = new Map()\n\n constructorHandlers.set(Date, (o: string | number | Date) => new Date(o))\n constructorHandlers.set(Map, (o: Iterable<unknown> | ArrayLike<unknown>, fn: any) => new Map(cloneArray(Array.from(o), fn)))\n constructorHandlers.set(Set, (o: Iterable<unknown> | ArrayLike<unknown>, fn: any) => new Set(cloneArray(Array.from(o), fn)))\n\n let handler = null\n\n return clone(obj)\n\n function cloneArray (a: any, fn: any): any {\n const keys = Object.keys(a)\n const a2 = new Array(keys.length) as any\n\n for (let i = 0; i < keys.length; i++) {\n const k = keys[i]\n const cur = a[k]\n\n if (typeof cur !== 'object' || cur === null) {\n a2[k] = cur\n } else if (cur.constructor !== Object && (handler = constructorHandlers.get(cur.constructor))) {\n a2[k] = handler(cur, fn)\n // } else if (ArrayBuffer.isView(cur)) {\n // a2[k] = copyBuffer(cur)\n } else {\n const index = refs.indexOf(cur)\n\n if (index !== -1)\n a2[k] = refsNew[index]\n else\n a2[k] = fn(cur)\n }\n }\n\n return a2\n }\n\n function clone (o: any): any {\n if (typeof o !== 'object' || o === null) return o\n if (Array.isArray(o)) return cloneArray(o, clone)\n if (o.constructor !== Object && (handler = constructorHandlers.get(o.constructor)))\n return handler(o, clone)\n\n const o2 = {} as any\n\n refs.push(o)\n refsNew.push(o2)\n\n\n Object.getOwnPropertySymbols(o).forEach((symbol) => {\n o2[symbol] = (o)[symbol]\n })\n\n for (const k in o) {\n if (!Object.hasOwnProperty.call(o, k)) continue\n const cur = o[k]\n\n\n if (typeof cur !== 'object' || cur === null) {\n o2[k] = cur\n } else if (cur.constructor !== Object && (handler = constructorHandlers.get(cur.constructor))) {\n o2[k] = handler(cur, clone)\n // } else if (ArrayBuffer.isView(cur)) {\n // o2[k] = copyBuffer(cur)\n } else {\n const i = refs.indexOf(cur)\n\n if (i !== -1)\n o2[k] = refsNew[i]\n else\n o2[k] = clone(cur)\n }\n }\n refs.pop()\n refsNew.pop()\n\n\n return o2\n }\n}\n\n/**\n * Guard to check is variable is an object\n * @param obj - variable to be checked\n * @returns boolean\n */\nexport const isObject = (obj: unknown): obj is Record<string | symbol, unknown> => (\n obj !== null\n && typeof obj === 'object'\n && !Array.isArray(obj)\n)\n\n\nexport const isReactElement = (obj: unknown): boolean => {\n if (!isObject(obj)) return false\n\n return !!(obj.$$typeof)\n}\n\n\nexport function isReactObjectLikeNode (obj: unknown): boolean {\n if (!isObject(obj)) return false\n if (isReactElement(obj)) return true\n\n const objKeys = Object.keys(obj)\n const isReactObjNode = (objKeys.includes('tag') && objKeys.includes('containerInfo'))\n || objKeys.some(k => k.startsWith('__reactContainer'))\n || (objKeys.includes('tag') && objKeys.includes('stateNode'))\n\n return isReactObjNode\n}\n\n\nexport function isValidReactiveObject <T extends Record<string, any>> (value: T): boolean {\n return isObject(value) && !isReactElement(value) && !(value as any)[nonReactiveObjectSymbol]\n}\n\n\n\n/**\n * Returns the actual target value instead of root\n * object with internals props like $$value$$\n *\n * @param target - object from subscription or proxy\n * @returns actual value\n */\nexport const okTarget = (target: any): any => target[INTERNAL_VALUE_PROP] ?? target\n\n\n\n\n/**\n * Gets an object with just the properties requested\n * instead of the full object\n *\n * @param properties - object properties\n * @param obj - target to get the properties\n * @returns New object with just the requested properties\n */\nexport function getPartialObjectFromProperties<T> (properties: Array<keyof T>, obj: T): any {\n return properties.reduce<any>((acc, curr) => {\n acc[curr] = obj[curr]\n\n return acc\n }, {})\n}\n\n\n\nconst stringify = (obj: any): string => JSON.stringify(obj)\n\n/**\n * Compare 2 provided objects by stringing them\n * @param a - first object\n * @param b - second object\n * @returns boolean\n */\nexport const contentComparer = (a: any, b: any): boolean => stringify(a) === stringify(b)\n\n\n\n\nexport function safeToJson (obj: any): Record<string, any> {\n const o: Record<string, any> = {}\n\n if (typeof obj !== 'object' || obj == null)\n return obj\n\n if (Array.isArray(obj))\n return obj.map(item => safeToJson(item))\n\n if (isReactElement(obj))\n return { props: safeToJson(obj.props), type: typeof obj.type === 'string' ? obj.type : '' }\n\n if (globalThis?.HTMLElement && obj instanceof globalThis.HTMLElement) return { type: '[HTMLElement]', content: obj.innerHTML }\n\n Object.entries(obj).forEach(([key, v]) => {\n o[key] = safeToJson(v)\n })\n\n return o\n}\n","\nimport { deepClone, isValidReactiveObject, safeToJson } from '../utils/object'\n\nimport type { StoreChange } from '../../types/shared'\nimport type { CacheableSubject } from '../utils/subject'\n\n\n\n// @ts-expect-error - Object.hasOwn is not defined in older Safari's browsers\n('hasOwn' in Object) || (Object.hasOwn = Object.call.bind(Object.hasOwnProperty))\n\nconst ROOT_VALUE = Symbol('value')\n\n\nexport function proxifyStore <T extends Record<string | symbol, any>> (\n store$$: CacheableSubject<StoreChange<T>>,\n objectToProxify: T,\n opts: {\n nestedFieldPath?: string\n parentObjectToProxify?: any\n // beforeChange?: (storeChange: StoreChange<T>) => any\n afterChange?: (storeChange: Array<StoreChange<T>>) => void\n } = {},\n): T {\n const fieldPath = opts.nestedFieldPath ?? 'root'\n\n const objectWithRootValue = {\n [ROOT_VALUE]: objectToProxify,\n } as unknown as T\n\n const rootFunctions = fieldPath === 'root'\n ? Object.fromEntries(Object.entries(objectToProxify).filter(([,v]) => typeof v === 'function'))\n : {}\n\n return new Proxy(objectWithRootValue, {\n get (targetObject, propName, receiver) {\n // INFO: !Internal only.\n // Used to get the fieldPath of the object (it means it's a proxified object)\n if (propName === '_$fieldPath') return fieldPath\n\n const isRootTarget = Object.hasOwn(targetObject, ROOT_VALUE)\n const target = isRootTarget ? targetObject[ROOT_VALUE] : targetObject\n\n\n // Called when the object is converted to JSON or string (i.e. JSON.stringify)\n if (propName === 'toJSON') {\n return () => {\n // Remove react-elements with circular which have circular references\n // before stringifying to prevent JSON.stringify(storeProxy) from failing\n return safeToJson(target)\n // return removeCircularReferences(target)\n }\n }\n\n // Get the whole store value without proxies\n if (propName === '$value')\n return deepClone(target)\n // return target\n\n\n\n const propertyValue = Reflect.get(target, propName, receiver)\n\n if (typeof propName === 'symbol') return propertyValue\n\n if (typeof propertyValue === 'function')\n return (propertyValue as () => any).bind(receiver)\n\n\n // Check if it's correct to be a reactive object\n // & is not a circular reference or the same object\n if (isValidReactiveObject(propertyValue) && propertyValue !== target) {\n // const newNestedFieldPath = `${fieldPath}.${propName}`\n\n // If it's already a proxified object, return it\n // if (propertyValue._$fieldPath === newNestedFieldPath) return propertyValue\n if (propertyValue._$fieldPath) return propertyValue\n\n // Create a new proxified object\n const proxiedNestedObject = proxifyStore(\n store$$ as any,\n propertyValue,\n {\n nestedFieldPath: `${fieldPath}.${propName}`,\n parentObjectToProxify: opts.parentObjectToProxify ?? target,\n // beforeChange: opts.beforeChange,\n afterChange: opts.afterChange,\n },\n )\n\n return target[propName] = proxiedNestedObject\n }\n\n return propertyValue\n },\n\n\n set (parentObject, key, newValue, receiver) {\n if (typeof key === 'symbol') return true\n\n const value = newValue\n const isRootTarget = Object.hasOwn(parentObject, ROOT_VALUE)\n\n // INFO: !Internal only.\n // Used to set the value of the store without notifying the store\n if (isRootTarget && key === '$$value') {\n const previousValue = parentObject[ROOT_VALUE];\n\n (parentObject as any)[ROOT_VALUE] = value.newValue\n\n store$$.next({\n storeValue: value.newValue,\n change: {\n fieldPath: 'root' as any,\n newValue: value.newValue,\n previousValue,\n },\n }, value.id)\n\n return true\n }\n\n if (isRootTarget && key === '$value') {\n const previousValue = parentObject[ROOT_VALUE]\n\n if (value === previousValue) return true\n\n if (JSON.stringify(safeToJson(value)) === JSON.stringify(safeToJson(previousValue))) return true\n // if (safeStringify(value) === safeStringify(previousValue)) return true\n\n if (fieldPath !== 'root') {\n (parentObject as any)[ROOT_VALUE] = value\n } else {\n (parentObject as any)[ROOT_VALUE] = {\n ...rootFunctions,\n ...value,\n }\n store$$.next({\n // To be disabled for performance and send same store reference\n // storeValue: JSON.parse(JSON.stringify(targetObject[ROOT_VALUE])),\n storeValue: parentObject[ROOT_VALUE],\n change: {\n fieldPath: 'root' as any,\n newValue: value,\n previousValue,\n },\n })\n }\n\n return true\n }\n\n const realInnerObject = isRootTarget ? parentObject[ROOT_VALUE] : parentObject\n const previousValue = Reflect.get(realInnerObject, key, receiver)\n\n\n if (previousValue === value) return true\n\n\n // New object values, check if the field has already a proxy created to use it instead of reacreating a new instance\n if (isValidReactiveObject(value) && previousValue?._$fieldPath)\n previousValue.$value = value\n else\n Reflect.set(realInnerObject, key, value, realInnerObject)\n\n\n const nextStoreChange = {\n // To be disabled for performance and send same store reference\n // storeValue: JSON.parse(JSON.stringify(opts?.parentObjectToProxify ?? target)),\n storeValue: opts?.parentObjectToProxify ?? realInnerObject,\n change: {\n fieldPath: `${fieldPath}.${key}`.replace('root.', '') as any,\n newValue: value,\n previousValue,\n },\n }\n\n store$$.next(nextStoreChange)\n opts.afterChange?.([nextStoreChange])\n\n return true\n },\n\n has (t, p) {\n return Reflect.has(t[ROOT_VALUE], p)\n },\n\n ownKeys (t) {\n return Reflect.ownKeys(t[ROOT_VALUE])\n },\n\n getOwnPropertyDescriptor (t, p) {\n return Reflect.getOwnPropertyDescriptor(t[ROOT_VALUE], p)\n },\n\n })\n}\n\n\n// function getDeepUnproxiedObject (obj: any): any {\n// if (obj && typeof obj === 'object' && !Array.isArray(obj)) {\n// if (obj[ROOT_VALUE]?.[ROOT_VALUE]) {\n// console.warn('Circular reference detected in getDeepUnproxiedObject')\n//\n// return '[Circular reference]'\n// }\n//\n//\n// const r = Object.fromEntries(\n// Object.entries(obj).map(([key, value]) => {\n// // console.log('____________________getDeepUnproxiedObject', key, value, value.constructor.name)\n// if (value && typeof value === 'object' && !Array.isArray(value)) {\n// if (key === 'links') console.log('getDeepUnproxiedObject', key, value)\n//\n// // If it's a proxied object, get the unproxied value\n// return [key, getDeepUnproxiedObject(value)]\n// }\n//\n// return [key, value]\n// }),\n// )\n//\n//\n// return r\n// }\n//\n// return obj\n// }\n\n// function safeStringify (obj: any): string {\n// // use removeCircularReferences to avoid circular references\n// // const cleanedObj = removeCircularReferences(obj)\n// return JSON.stringify(safeToJson(obj))\n// //\n// // return JSON.stringify(\n// // obj,\n// // (_key, value) => {\n// // if (Array.isArray(value)) return value.map(i => safeStringify(i))\n// //\n// // if (isReactElement(value)) {\n// // // console.log('React element detected', value)\n// //\n// // return { props: safeStringify(value.props), type: typeof value.type === 'string' ? value.type : '' }\n// // }\n// //\n// // if (globalThis?.HTMLElement && value instanceof globalThis.HTMLElement) return { type: '[HTMLElement]', content: value.innerHTML }\n// //\n// // // console.log('Value', value)\n// //\n// // return value\n// // })\n// }\n\n\n\n\n// function removeCircularReferences (obj: any): any {\n// const seen = new WeakSet()\n//\n// function traverse (value: any): any {\n// if (value && typeof value === 'object') {\n// // If the object has already been seen, it's a circular reference\n// if (seen.has(value))\n// return null\n//\n// seen.add(value)\n//\n// if (Array.isArray(value))\n// return value.map(traverse)\n//\n//\n// const result: any = {}\n//\n// for (const key in value) {\n// if (Object.prototype.hasOwnProperty.call(value, key)) {\n// if (key === '_owner' && value.$$typeof) continue\n//\n// result[key] = traverse(value[key])\n// }\n// }\n//\n// return result\n// }\n//\n// // Return primitive values as-is\n// return value\n// }\n//\n// return traverse(obj)\n// }\n","\nimport { useEffect, useId, useRef, useState } from 'react'\n\nimport { nonReactiveObjectSymbol } from '../../types/shared'\nimport { proxifyStore } from '../helpers/new-proxify-store'\nimport { deepClone, safeToJson } from '../utils/object'\nimport { createCacheableSubject } from '../utils/subject'\n\nimport type { FieldPath, StoreChange } from '../../types/shared'\n\n\n\n\n// export type CervelloOptions<StoreValue extends Record<string, any>> = {\n// beforeChange?: (storeChange: StoreChange<StoreValue>) => unknown | undefined\n// afterChange?: (storeChange: Array<StoreChange<StoreValue>>) => void\n// }\n\nexport type CervelloOptions<StoreValue extends Record<string, any>> = {\n afterChange?: (storeChange: Array<StoreChange<StoreValue>>) => void\n}\n\nexport type CervelloUseStoreOptions<StoreValue extends Record<string, any>> = {\n initialValue?: (currentStore: StoreValue) => StoreValue | null,\n setValueOnMount?: (currentStore: StoreValue) => Promise<StoreValue>,\n select?:\n | Array<FieldPath<StoreValue>>\n | (() => Array<FieldPath<StoreValue>>)\n onChange?: (storeChange: Array<StoreChange<StoreValue>>) => void\n}\n\ntype MutableStoreValue<T extends Record<string, any>> = {\n $value: T\n} & T\n\n\n\n\n\n\n\n\nexport function nonReactive <T extends Record<string, any>> (initialValue: T): T {\n Object.defineProperty(initialValue, nonReactiveObjectSymbol, {\n value: true,\n enumerable: false,\n writable: false,\n configurable: false,\n })\n\n return initialValue\n}\n\n\nexport function cervello <StoreValue extends Record<PropertyKey, any>> (\n initialValue: StoreValue,\n options?: CervelloOptions<StoreValue>,\n): {\n store: MutableStoreValue<StoreValue>,\n reset: () => void,\n useStore: (options?: CervelloUseStoreOptions<StoreValue>) => MutableStoreValue<StoreValue>\n } {\n const {\n // beforeChange,\n afterChange,\n } = options ?? {}\n\n // const store$$ = createCacheableSubject<StoreChange<StoreValue>>(clonedInitialValue as any)\n const clonedInitialValue = deepClone(initialValue)\n\n const store$$ = createCacheableSubject<StoreChange<StoreValue>>()\n\n const proxiedStore = proxifyStore(\n store$$ as any,\n clonedInitialValue,\n // { beforeChange, afterChange },\n { afterChange },\n ) as MutableStoreValue<StoreValue>\n\n\n return {\n store: proxiedStore,\n reset: () => {\n proxiedStore.$value = deepClone(initialValue)\n },\n useStore: (options) => {\n const subscriberId = useId()\n const initialValue = options?.initialValue?.(proxiedStore.$value)\n const isInitialValueSet = useRef(false)\n const [, setRenderCount] = useState(0)\n\n if (!isInitialValueSet.current\n && initialValue\n && JSON.stringify(safeToJson(initialValue)) !== JSON.stringify(safeToJson(proxiedStore.$value))\n ) {\n isInitialValueSet.current = true;\n (proxiedStore as any).$$value = { id: subscriberId, newValue: initialValue }\n }\n\n const selectFieldPaths = useRef(\n (typeof options?.select === 'function'\n ? options?.select?.()\n : options?.select)\n ?? [],\n )\n\n\n const selectedFieldPathsForNestedObjects = useRef(\n selectFieldPaths.current\n .filter(fp => fp.includes('.*'))\n .map(fp => fp.replace('.*', '')),\n )\n\n const reRender = (): void => {\n setRenderCount(p => p + 1)\n }\n\n\n useEffect(() => {\n if (options?.setValueOnMount) {\n void options.setValueOnMount(proxiedStore.$value).then((value) => {\n proxiedStore.$value = value\n }).catch((err) => {\n console.error('Error setting initial value on mount', err)\n })\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [])\n\n\n // Same implementation as useSyncExternalStore but with useEffect\n useEffect(() => {\n const subscription = store$$.subscribe({\n id: subscriberId,\n next: (sc) => {\n const storeChanges = Array.isArray(sc)\n ? sc as Array<StoreChange<StoreValue>>\n : [sc]\n\n if (!options?.select) {\n reRender()\n options?.onChange?.(storeChanges)\n\n return\n }\n\n if (storeChanges.some(nextChange => (\n nextChange.change.fieldPath === 'root'\n || selectFieldPaths.current.includes(nextChange.change.fieldPath))\n || selectedFieldPathsForNestedObjects.current.find(fp => nextChange.change.fieldPath.startsWith(fp)),\n )) {\n reRender()\n options?.onChange?.(storeChanges)\n }\n },\n })\n\n return () => {\n subscription.unsubscribe()\n }\n\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [options?.select, options?.onChange])\n\n return proxiedStore\n },\n }\n}\n\n","\ntype Noop = () => void\n\n\ntype Observer<T> = {\n id: string\n next: (value: T, subscriberId?: string) => void\n}\n\ntype Subscription = {\n unsubscribe: Noop\n}\n\nexport type CacheableSubject<T> = {\n // getValue: () => T\n subscribe: (value: Observer<T>) => Subscription\n // unSubscribeAll: Noop\n} & Omit<Observer<T>, 'id'>\n\n\n\nexport function createCacheableSubject<T> (/* defaultValue: T/*, getValueOnSubscribe = false */): CacheableSubject<T> {\n let isFlushing = false\n let itemsToFlush: Array<{ newValue: T, subscriberId?: string }> = []\n\n let observerList: Array<Observer<T>> = []\n // let value = defaultValue\n\n // const getValue = (): T => value\n\n const next = (newValue: T, subscriberId?: string): void => {\n // value = newValue\n\n itemsToFlush.push({ newValue, subscriberId })\n\n if (!isFlushing) {\n isFlushing = true\n\n void Promise.resolve().then(() => {\n observerList.forEach((o) => {\n // Filter changes that were sent by the same subscriberId (initialValue function call)\n const nonInitiallySentBySubscriber = itemsToFlush.filter(item => item.subscriberId !== o.id)\n\n if (!nonInitiallySentBySubscriber.length) return\n\n o.next(nonInitiallySentBySubscriber.map(i => i.newValue) as T)\n })\n itemsToFlush = []\n isFlushing = false\n })\n\n // void Promise.resolve(subscriberId).then((subscriberId) => {\n // console.log('//// promise.resolve then', { subscriberId: s.id })\n // observerList.forEach((o) => {\n // console.log('//// CacheableSubject (forEach) flushing', { observerId: o.id, subscriberId: s.id })\n // if (o.id === subscriberId) return\n //\n // o.next(itemsToFlush as T)\n // })\n // itemsToFlush = []\n // isFlushing = false\n // })\n\n // void Promise.resolve().then(() => {\n // console.log('//// promise.resolve then')\n // observerList.forEach((o) => {\n // const nonInitiallySentBySubscriber = itemsToFlush.filter(item => item.subscriberId !== o.id)\n //\n // if (nonInitiallySentBySubscriber.length === 0) return\n //\n // o.next(nonInitiallySentBySubscriber.map(i => i.newValue) as T)\n // })\n // itemsToFlush = []\n // isFlushing = false\n // })\n }\n }\n\n const subscribe = (observer: Observer<T>): Subscription => {\n // Push cached value on subscribe\n // if (getValueOnSubscribe) observer.next(value)\n\n // Store the observer to be notified\n observerList.push(observer)\n\n return {\n unsubscribe: () => {\n observerList = observerList.filter(o => o.id !== observer.id)\n },\n }\n }\n\n // const unSubscribeAll = (): void => {\n // observerList = []\n // }\n\n return {\n // getValue,\n next,\n subscribe,\n // unSubscribeAll,\n }\n}\n"],"names":["nonReactiveObjectSymbol","Symbol","deepClone","obj","newObj","Array","isArray","map","item","isReactObjectLikeNode","isObject","isReactElement","objKeys","Object","keys","includes","some","k","startsWith","entries","forEach","_ref","getOwnPropertySymbols","symbol","$$typeof","isValidReactiveObject","value","safeToJson","o","props","type","globalThis","HTMLElement","content","innerHTML","_ref2","v","hasOwn","call","bind","hasOwnProperty","ROOT_VALUE","proxifyStore","store$$","objectToProxify","opts","_opts$nestedFieldPath","_objectWithRootValue","nestedFieldPath","objectWithRootValue","rootFunctions","fieldPath","fromEntries","filter","Proxy","get","targetObject","propName","receiver","target","propertyValue","Reflect","_opts$parentObjectToP","_$fieldPath","proxiedNestedObject","parentObjectToProxify","afterChange","set","parentObject","key","newValue","_opts$parentObjectToP2","_opts","isRootTarget","previousValue","next","storeValue","change","id","JSON","stringify","_extends","realInnerObject","$value","nextStoreChange","replace","has","t","p","ownKeys","getOwnPropertyDescriptor","initialValue","options","isFlushing","itemsToFlush","clonedInitialValue","subscriberId","push","resolve","then","observerList","nonInitiallySentBySubscriber","length","i","subscribe","observer","unsubscribe","proxiedStore","store","reset","useStore","useId","isInitialValueSet","useRef","setRenderCount","useState","current","$$value","selectFieldPaths","select","selectedFieldPathsForNestedObjects","fp","reRender","useEffect","setValueOnMount","err","console","error","subscription","sc","storeChanges","onChange","nextChange","find","defineProperty","enumerable","writable","configurable"],"mappings":"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"}
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
import type { Maybe, UseSelector, WithoutType } from '../../types/shared';
|
|
2
|
-
type CervelloStoreUseParam<StoreType> = {
|
|
3
|
-
onChange: (cb: (store: StoreType) => void) => void;
|
|
4
|
-
onPartialChange: <Attributes extends keyof WithoutType<StoreType, Function>, R extends Exclude<Attributes, '$value'>, ArrayOfAttributes extends Array<R>>(selectors: ArrayOfAttributes, cb: (store: StoreType) => void) => void;
|
|
5
|
-
};
|
|
6
|
-
/**
|
|
7
|
-
* Use function which allows you to listen for changes in the store.
|
|
8
|
-
*/
|
|
9
|
-
export type CervelloUseFunction<StoreType> = (param: CervelloStoreUseParam<StoreType>) => void;
|
|
10
|
-
declare type Prettify<T> = {} & {
|
|
11
|
-
[K in keyof T]: T[K];
|
|
12
|
-
};
|
|
13
|
-
type CervelloStore<StoreType, StoreName extends string | undefined = undefined> = StoreName extends string ? Prettify<{
|
|
14
|
-
[K in `${StoreName}Store`]: StoreType;
|
|
15
|
-
} & {
|
|
16
|
-
[K in `use${Capitalize<StoreName>}Store`]: () => StoreType;
|
|
17
|
-
} & {
|
|
18
|
-
[K in `use${Capitalize<StoreName>}Selector`]: UseSelector<StoreType>;
|
|
19
|
-
} & {
|
|
20
|
-
[K in `reset${Capitalize<StoreName>}Store`]: () => void;
|
|
21
|
-
} & {
|
|
22
|
-
/** Functions to be attached to changes in a general way (tracking, loggers, ... etc) */
|
|
23
|
-
use: (...functions: Array<(useObj: CervelloStoreUseParam<StoreType>) => void>) => CervelloStore<StoreType, StoreName>;
|
|
24
|
-
}> : {
|
|
25
|
-
/** Reactive store */
|
|
26
|
-
store: StoreType;
|
|
27
|
-
/** Hook to react to all changes done to 'store' */
|
|
28
|
-
useStore: () => StoreType;
|
|
29
|
-
/** Hook to react to changes done to 'store' in all the attributes provided */
|
|
30
|
-
useSelector: UseSelector<StoreType>;
|
|
31
|
-
/** Resets the value to the initial value passed in */
|
|
32
|
-
reset: () => void;
|
|
33
|
-
/** Functions to be attached to changes in a general way (tracking, loggers, ... etc) */
|
|
34
|
-
use: (...functions: Array<(useObj: CervelloStoreUseParam<StoreType>) => void>) => CervelloStore<StoreType, StoreName>;
|
|
35
|
-
};
|
|
36
|
-
export type CervelloOptions<StoreName extends string | undefined = undefined> = {
|
|
37
|
-
name?: StoreName;
|
|
38
|
-
reactiveNestedObjects?: boolean;
|
|
39
|
-
};
|
|
40
|
-
/**
|
|
41
|
-
* Creates a store that is reactive and can be used inside and outside of React components.
|
|
42
|
-
* @param initialValue - Function which returns the default values for the store
|
|
43
|
-
*
|
|
44
|
-
* @returns \{ store, useStore, useSelector \} or `{ exampleStore, useExampleStore, useExampleSelector }` if name is provided in options with 'example' value
|
|
45
|
-
*/
|
|
46
|
-
export declare function cervello<T, StoreName extends string | undefined = undefined>(initialValue: () => T, options?: CervelloOptions<StoreName>): Prettify<CervelloStore<Prettify<T & {
|
|
47
|
-
$value: Maybe<T>;
|
|
48
|
-
}>, StoreName>>;
|
|
49
|
-
/**
|
|
50
|
-
* Creates a store that is reactive and can be used inside and outside of React components.
|
|
51
|
-
* @param initialValue - Object with the default values for the store
|
|
52
|
-
*
|
|
53
|
-
* @returns - \{ store, useStore, useSelector \} or `{ exampleStore, useExampleStore, useExampleSelector }` if name is provided in options with 'example' value
|
|
54
|
-
*/
|
|
55
|
-
export declare function cervello<T extends Record<string, unknown>, StoreName extends string | undefined = undefined>(initialValue: T, options?: CervelloOptions<StoreName>): Prettify<CervelloStore<Prettify<T & {
|
|
56
|
-
$value: Maybe<T>;
|
|
57
|
-
}>, StoreName>>;
|
|
58
|
-
export {};
|