@cervello/react 0.9.3 → 0.9.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,17 +1,16 @@
1
1
  # Cervello
2
- <img src="https://img.shields.io/npm/v/@cervello/react?color=red&style=flat-square">
2
+ <a href="https://bundlephobia.com/package/@cervello/react@latest"><img src="https://img.shields.io/bundlephobia/minzip/@cervello/react?color=red&label=BundlePhobia%20size&style=flat-square"></a>
3
+ <a href="https://www.npmjs.com/package/@cervello/react"><img src="https://img.shields.io/npm/v/@cervello/react?color=yellow&style=flat-square"></a>
3
4
 
4
- > (Beta version) - Working on it to be have SSR integration (hydration) and better documentation
5
+ > (Beta version) - Working on SSR,persist options and documentation page
5
6
 
6
- <img src="https://img.shields.io/bundlephobia/minzip/@cervello/react?color=red&label=BundlePhobia%20size&style=flat-square">
7
7
 
8
8
 
9
- #### `746 Bytes of bundle size for now (.br compressed)!! `
10
- Simplest and truly reactive state manager for React
9
+
10
+ 🤯 Simplest and truly reactive state manager for React
11
11
 
12
12
 
13
13
  ## 🚀 **Features**
14
- - ⚡️ Optimized and super performant
15
14
  - ⚛️ Truly reactive on item change
16
15
  - ✅ Super simple and minimalistic API
17
16
  - 🐨 Listen to attributes or items lazily
@@ -19,129 +18,138 @@ Simplest and truly reactive state manager for React
19
18
  - 🔑 Typescript support
20
19
 
21
20
  ## 📦 **Install**
22
- ```zsh
23
- # NPM install as a dependency
24
- npm install cervello
21
+ ```bash
22
+ # NPM
23
+ npm install @cervello/react
24
+
25
+ # YARN
26
+ yarn add @cervello/react
25
27
 
26
- # YARN install as a dependency
27
- yarn add cervello
28
+ # PNPM
29
+ pnpm add @cervello/react
28
30
  ```
29
31
 
30
32
 
31
33
  ## 💻 **Usage**
32
34
  The `cervello` function allows you to create a new store in an easy way.
33
- 1. Define the store name
34
- 2. Set the initial value _`(the type will be inferred based on this value)`_
35
+ Just set the initial value _`(the type will be inferred based on this value)`_ and you have it
35
36
 
36
37
  ```ts
37
38
  // - store-example.ts
38
39
  import { cervello } from '@cervello/react'
39
40
 
40
41
 
41
- /** Export it with the names you prefer to be used/imported */
42
42
  /**
43
- * The cervello function returns a store with the given name and 2 hooks
44
- * to be reactive and change the store value
45
- *
46
- * Object returned => { storeNameProvided, useStore, useSelect }
43
+ * The cervello function returns a reactive store and 2 hooks
44
+ * to be ready to changes inside react components
45
+ *
47
46
  */
48
47
  export const {
49
- exampleStore, // The store object
50
- useStore: useExampleStore, // The hook to use the store
51
- useSelect: useExampleSelect // The hook to use the selectors (part of the store)
52
- } = cervello(
53
- 'exampleStore', /* store name */
54
- { count: 0 } /* initial value */
48
+ store, // The store object
49
+ useStore, // The hook to use the store
50
+ useSelector, // The hook to use the selectors (part of the store)
51
+ } = cervello({ count: 0 })
52
+ ```
53
+
54
+
55
+ ### 🟢 `store`
56
+ The store object that you can use `inside or outside react components` to modify the store. It will automatically notify all the components listening for changes
57
+
58
+ ```tsx
59
+ import { store } from './store-example'
60
+
61
+ /**
62
+ * It can be used outside the react components
63
+ * It will notify all the components listening for changes
64
+ */
65
+ const increment = () => { store.count++}
66
+
67
+ const CounterButton = () => (
68
+ /**
69
+ * This makes all the components using the store (i.e.: CounterLabel)
70
+ * to be reactive and re-renders with the new value
71
+ */
72
+ <button onClick={increment}>
73
+ Increment
74
+ </button>
55
75
  )
56
76
  ```
57
77
 
78
+ ### 🟢 `useStore`
58
79
 
59
- Use it in your components. They don't need to know about each other. They can be in different pages or locations:
80
+ React hook that allows you to have a reactive store which re-renders when a new value was set
60
81
  ```tsx
61
- import { useExampleStore } from './store-example'
82
+ import { useStore } from './store-example'
62
83
 
63
84
  const CounterLabel = () => {
64
- const { count } = useExampleStore()
85
+ const { count } = useStore()
65
86
 
66
87
  return (<span>{ count }</span>)
67
88
  }
68
89
  ```
69
90
 
91
+ ### 🟢 `useSelector`
70
92
 
93
+ React hook that allows you to have a reactive store which re-renders when a new value was set on properties you specified
94
+ - _Parameters_:
95
+ - `selectors`: an array of store properties to be watched
96
+ - `isEqualFunction`: a custom function to compare the new value with the old one
71
97
  ```tsx
72
- import { exampleStore } from './store-example'
98
+ import { useSelector } from './store-example'
73
99
 
74
- const CounterButton = () => (
75
- // This makes all the components using the store (i.e.: CounterLabel)
76
- // to be reactive and re-renders with the new value
77
- <button onClick={e => exampleStore.count += 1}>
78
- Increment
79
- </button>
80
- )
81
- ```
82
-
83
-
84
- ### 🔖 Changing the store
85
- ```ts
86
100
  const CounterLabel = () => {
87
101
  /**
88
- * If you want to just listen for changes, then you
89
- * can destructure the value but...
90
- *
91
- * IMPORTANT!:
92
- * In order to change reactively any store attribute, you
93
- * must use the object returned from the `useStore` hook
94
- * without destructuring
95
- * */
96
- const exampleStore = useExampleStore()
97
-
98
- // Destructured just to be listened if changes
99
- const { count } = exampleStore
100
-
101
- // In order to be reactive, you MUST use the object when you change a value
102
- const increment = () => exampleStore.count += 1
103
-
104
- return (
105
- <div>
106
- <span>{ count }</span>
107
- <button onClick={increment}> Increment </button>
108
- </div>
109
- )
110
- }
102
+ * This will re-render just only when the property `count` changes
103
+ */
104
+ const { count } = useSelector(['count'])
111
105
 
106
+ return (<span>{ count }</span>)
107
+ }
112
108
  ```
113
-
114
- ### ⤵️ The `Use` function
115
- The use function allows you to implement side effects due to a change in happened in the store
109
+ ----
110
+ ### 🟣 The `Use` function
111
+ The use function allows you to implement side effects due to a store change
112
+ #### 🔽 Example
116
113
  ```ts
117
114
  import type { UseFunction } from '@cervello/react'
118
115
 
119
- const logger: UseFunction<'testStore', typeof testStore> = ({ $onChange }): void => {
120
- $onChange((store) => {
121
- console.log('Store changed to :>>', store)
116
+ const logger: UseFunction<typeof store> = ({ onChange }): void => {
117
+ onChange((store) => {
118
+ console.log('[Store-changed] to ==>', store)
122
119
  })
123
120
  }
124
121
 
125
122
 
126
- const { testStore } =
127
- cervello('testStore', { test: 'test', count: -1 })
128
- .use(logger, /* other use functions */) // Adds the logger to the store
123
+ const { store } = cervello({ name: 'chempo', surname: 'gonzalez' })
124
+ .use(logger, /* other use functions */)
129
125
 
130
126
  ```
131
127
 
132
- #### 🗳️ Use function callback object
128
+ #### 🗳️ Use function input parameters
133
129
  ```ts
134
130
  import type { UseFunction } from '@cervello/react'
135
131
 
136
- const logger: UseFunction<'testStore', typeof testStore> = ({ testStore, $onPartialChange, $onChange }): void => {
132
+ const logger: UseFunction<typeof store> = ({ onChange, onPartialChange }): void => {
137
133
  // Listen to all the changes happened in the store
138
- $onChange((store) => {
134
+ onChange((store) => {
139
135
  console.log('Store changed to :>>', store)
140
136
  });
141
137
 
142
138
  // Listen to the changes happened in the store's attributes provided
143
- $onPartialChange(['test', 'count'], (store) => {
144
- store.count += 1
139
+ onPartialChange(['name'], (store) => {
140
+ console.log('Name has changed to:', store.name)
145
141
  })
146
142
  }
147
143
  ```
144
+ ------
145
+ <br>
146
+
147
+
148
+ ## 🤓 Happy Code
149
+
150
+ > Created with Typescript! ⚡ and latin music 🎺🎵
151
+
152
+ ### This README.md file has been written keeping in mind
153
+
154
+ - [GitHub Markdown](https://guides.github.com/features/mastering-markdown/)
155
+ - [Emoji Cheat Sheet](https://www.webfx.com/tools/emoji-cheat-sheet/)
package/dist/cervello.cjs CHANGED
@@ -1,2 +1,2 @@
1
- var n=require("rxjs"),e=require("react");function r(){return r=Object.assign?Object.assign.bind():function(n){for(var e=1;e<arguments.length;e++){var r=arguments[e];for(var t in r)Object.prototype.hasOwnProperty.call(r,t)&&(n[t]=r[t])}return n},r.apply(this,arguments)}function t(n,e){if("object"!=typeof e)throw new Error("Store must be an object");return new Proxy(e,{get:function(e,r){var u=n.value;return r in u?"function"==typeof u[r]?u[r].bind(t(n,u)):u[r]:Reflect.get(e,r)},set:function(e,r,t){var u=Object.assign({},n.value);return u[r]=t,n.next(u),Reflect.set(e,r,t)}})}function u(n,e){return n.reduce(function(n,r){return n[r]=e[r],n},{})}exports.cervello=function(i,c){var o,f=new n.BehaviorSubject(c),s=t(f,r({},c)),a=((o={})[i]=s,o.useStore=function(r){return function(){var u=e.useState(t(r,r.value)),i=u[0],c=u[1],o=e.useRef(!0);return e.useEffect(function(){var e=r.pipe(n.observeOn(n.queueScheduler)).subscribe(function(n){o.current?o.current=!1:c(t(r,n))});return function(){return e.unsubscribe()}},[]),i}}(f),o.useSelect=function(r){return function(){var i=[].slice.call(arguments),c=e.useState(function(){var n=u(i,r.value);return t(r,n)}),o=c[0],f=c[1],s=e.useRef(!0);return e.useEffect(function(){var e=r.pipe(n.distinctUntilChanged(function(n,e){var r=!0;return i.forEach(function(t){"object"==typeof e[t]&&r?JSON.stringify(n[t])!==JSON.stringify(e[t])&&(r=!1):n[t]!==e[t]&&r&&(r=!1)}),r})).subscribe(function(n){if(s.current)s.current=!1;else{var e=u(i,n);f(t(r,e))}});return function(){return e.unsubscribe()}},[i.length]),o}}(f),o.use=function(){return[].slice.call(arguments).forEach(function(e){var r;e(((r={})[i]=s,r.$onChange=function(e){f.pipe(n.pairwise(),n.switchMap(function(e){var r=e[1];return e[0]!==r?n.of(r):n.NEVER})).subscribe(function(n){return e(s)})},r.$onPartialChange=function(e,r){f.pipe(n.pairwise(),n.switchMap(function(e){var r=e[1];return e[0]!==r?n.of(r):n.NEVER}),n.distinctUntilChanged(function(n,r){var t=!0;return e.forEach(function(e){"object"==typeof r[e]&&t?JSON.stringify(n[e])!==JSON.stringify(r[e])&&(t=!1):n[e]!==r[e]&&t&&(t=!1)}),t})).subscribe(function(n){return r(s)})},r))}),this},o);return a};
1
+ var n=require("rxjs"),t=require("use-sync-external-store/shim"),r=require("use-sync-external-store/shim/with-selector");function e(){return e=Object.assign?Object.assign.bind():function(n){for(var t=1;t<arguments.length;t++){var r=arguments[t];for(var e in r)Object.prototype.hasOwnProperty.call(r,e)&&(n[e]=r[e])}return n},e.apply(this,arguments)}var i=Symbol("___nested-attributes___");function u(n,t){if("object"!=typeof t)throw new Error("Store must be an object");return new Proxy(t,{get:function(t,r){var o,c,s=t;return r in s?"function"==typeof s[r]?s[r].bind(u(n,s)):"object"!=typeof s[r]||Array.isArray(s[r])||"symbol"==typeof r?s[r]:u(n,e({},s[r],((c={})[i]=""+(null!=(o=null==t?void 0:t[i])?o:"")+r,c))):Reflect.get(t,r)},set:function(t,r,e){var i=n.getValue(),u=Object.assign({},i);return u[r]=e,n.next(u),Reflect.set(t,r,e)}})}var o=function(n){return function(t){var r=n.subscribe(t);return function(){r.unsubscribe()}}};function c(n){var r=o(n),e=n.getValue.bind(n);return function(){var i=t.useSyncExternalStore(r,e,e);return u(n,i)}}function s(n){var t=o(n),e=n.getValue.bind(n);return function(i,o){var c=r.useSyncExternalStoreWithSelector(t,e,e,function(n){return function(n,t){return n.reduce(function(n,r){return n[r]=t[r],n},{})}(i,n)},function(n,t){return o?o(n,t):JSON.stringify(n)===JSON.stringify(t)});return u(n,c)}}exports.cervello=function(t,r){var i="function"==typeof t?t():t,o=new n.BehaviorSubject(i),f=u(o,e({},i)),a={store:f,useStore:c(o),useSelector:s(o),use:function(){return[].slice.call(arguments).forEach(function(t){t({onChange:function(t){o.pipe(n.pairwise(),n.switchMap(function(t){var r=t[1];return t[0]!==r?n.of(r):n.NEVER})).subscribe(function(n){return t(f)})},onPartialChange:function(t,r){o.pipe(n.pairwise(),n.switchMap(function(t){var r=t[1];return t[0]!==r?n.of(r):n.NEVER}),n.distinctUntilChanged(function(n,r){var e=!0;return t.forEach(function(t){e&&"object"==typeof r[t]?JSON.stringify(n[t])!==JSON.stringify(r[t])&&(e=!1):e&&n[t]!==r[t]&&(e=!1)}),e})).subscribe(function(n){return r(f)})}})}),this}};return a};
2
2
  //# sourceMappingURL=cervello.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"cervello.cjs","sources":["../src/lib/helpers/proxify-store.ts","../src/lib/helpers/create-use-select.ts","../src/lib/store/index.ts","../src/lib/helpers/create-use-store.ts"],"sourcesContent":["import type { BehaviorSubject } from 'rxjs'\n\n\n\nexport function proxifyStore <T extends Record<string | symbol, any>> (store$$: BehaviorSubject<T>, storeObject: T): T {\n if (typeof storeObject !== 'object') throw new Error('Store must be an object')\n\n return new Proxy<T>(\n storeObject,\n {\n get: function (target: T, prop: string | symbol): any {\n const currentStore = store$$.value as any\n\n if (prop in currentStore) {\n if (typeof currentStore[prop] === 'function') {\n return currentStore[prop].bind(proxifyStore(store$$, currentStore))\n }\n\n return currentStore[prop]\n }\n\n return Reflect.get(target, prop)\n },\n set: function (target: T, prop: string | symbol, value: any) {\n const currentStore = store$$.value as any\n\n const clonedStore = Object.assign({}, currentStore)\n clonedStore[prop] = value\n\n store$$.next(clonedStore)\n\n return Reflect.set(target, prop, value)\n },\n },\n )\n}\n","import { useEffect, useRef, useState } from 'react'\nimport { distinctUntilChanged } from 'rxjs'\n\nimport { proxifyStore } from './proxify-store'\n\nimport type { ObjectFromAttributes } from '../../types/shared'\nimport type { BehaviorSubject } from 'rxjs'\n\n\n\nexport function getPartialObjectFromAttributes <T> (attributes: Array<keyof T>, store: T): any {\n return attributes.reduce<any>((acc, curr) => {\n acc[curr] = store[curr]\n return acc\n }, {})\n}\n\n\nexport function createUseSelect <T> (store$$: BehaviorSubject<T>) {\n //\n return <Attributes extends Array<keyof T>>(...selectors: Attributes): ObjectFromAttributes<T, Attributes> => {\n const [store, setStore] = useState<any>(() => {\n const selectedStore = getPartialObjectFromAttributes(selectors, store$$.value)\n return proxifyStore(store$$, selectedStore)\n })\n const isFirstTime = useRef(true)\n\n\n useEffect(() => {\n const subscription = store$$.pipe(distinctUntilChanged((prev, curr) => {\n let isEqual = true\n selectors.forEach((selector) => {\n if (typeof curr[selector] === 'object' && isEqual) {\n if (JSON.stringify(prev[selector]) !== JSON.stringify(curr[selector])) {\n isEqual = false\n }\n } else {\n if (prev[selector] !== curr[selector] && isEqual) {\n isEqual = false\n }\n }\n })\n\n return isEqual\n })).subscribe((partialStore) => {\n if (isFirstTime.current) {\n isFirstTime.current = false\n } else {\n const selectedStore = getPartialObjectFromAttributes(selectors, partialStore)\n setStore(proxifyStore(store$$, selectedStore))\n }\n })\n\n\n return () => subscription.unsubscribe()\n }, [selectors.length])\n\n\n return store\n }\n}\n","import { BehaviorSubject, distinctUntilChanged, NEVER, of, pairwise, switchMap } from 'rxjs'\n\nimport { createUseSelect, createUseStore, proxifyStore } from '../helpers'\n\nimport type { ObjectFromAttributes } from '../../types/shared'\n\n\n\n// const STORE_SYMBOL = '__cervello-store__'\n\n\n\n\ntype CervelloStoreUseParam<StoreName extends string, StoreType> = {\n [k in StoreName]: StoreType\n} & {\n $onChange: (cb: (store: StoreType) => void) => void\n $onPartialChange: <\n Attributes extends Array<keyof StoreType>\n > (selectors: Attributes, cb: (store: StoreType) => void) => void\n}\n\n\nexport type CervelloUseFunction<StoreName extends string, StoreType> = (param: CervelloStoreUseParam<StoreName, StoreType>) => void\n\n\ntype CervelloStore<StoreName extends string, StoreType> = {\n [k in StoreName]: StoreType\n} & {\n useStore: () => StoreType\n useSelect: <Attributes extends Array<keyof StoreType>>(...selectors: Attributes) => ObjectFromAttributes<StoreType, Attributes>\n use: (...functions: Array<(useObj: CervelloStoreUseParam<StoreName, StoreType>) => void>) => CervelloStore<StoreName, StoreType>\n}\n\n\n\n\nexport function cervello <\n StoreName extends string,\n T\n> (storeName: StoreName, initialValue: T): CervelloStore<StoreName, T> {\n // Unique symbol to be used to keep a reference of the BehaviourSubject\n // const storeSymbol = Symbol(STORE_SYMBOL)\n\n\n const store$$ = new BehaviorSubject<T>(initialValue)\n\n const proxiedStore = proxifyStore(store$$, { ...initialValue })\n\n const cervelloStore = {\n [storeName]: proxiedStore,\n\n // TO BE SEPARATED IN cervello/react package ---------------------\n useStore: createUseStore<T>(store$$),\n useSelect: createUseSelect<T>(store$$),\n // ---------------------------------------------------------------\n\n use (...functionList: any) {\n functionList.forEach((func: any) => {\n func({\n [storeName]: proxiedStore,\n $onChange (cb: any) {\n store$$.pipe(\n pairwise(),\n switchMap(([oldValue, newValue]) => (oldValue !== newValue ? of(newValue) : NEVER)),\n ).subscribe((_) => cb(proxiedStore))\n },\n $onPartialChange (attrs: Array<keyof T>, cb: any) {\n store$$.pipe(\n pairwise(),\n switchMap(([oldValue, newValue]) => (oldValue !== newValue ? of(newValue) : NEVER)),\n distinctUntilChanged((prev, curr) => {\n let isEqual = true\n attrs.forEach((selector) => {\n if (typeof curr[selector] === 'object' && isEqual) {\n if (JSON.stringify(prev[selector]) !== JSON.stringify(curr[selector])) {\n isEqual = false\n }\n } else {\n if (prev[selector] !== curr[selector] && isEqual) {\n isEqual = false\n }\n }\n })\n return isEqual\n }),\n ).subscribe((_) => cb(proxiedStore))\n },\n })\n })\n return this\n },\n } as any\n\n\n\n return cervelloStore as CervelloStore<StoreName, T>\n}\n","import { useEffect, useRef, useState } from 'react'\nimport { observeOn, queueScheduler } from 'rxjs'\n\nimport { proxifyStore } from './proxify-store'\n\nimport type { BehaviorSubject } from 'rxjs'\n\n\n\nexport function createUseStore <T> (store$$: BehaviorSubject<T>): () => T {\n return () => {\n const [store, setStore] = useState<T>(proxifyStore(store$$, store$$.value))\n const isFirstTime = useRef(true)\n\n // TODO: Use new useSyncExternalStore API hook\n useEffect(() => {\n const subscription = store$$.pipe(observeOn(queueScheduler)).subscribe((n) => {\n if (isFirstTime.current) {\n isFirstTime.current = false\n } else {\n setStore(proxifyStore(store$$, n))\n }\n })\n\n return () => subscription.unsubscribe()\n }, [])\n\n\n return store\n }\n}\n"],"names":["proxifyStore","store$$","storeObject","Error","Proxy","get","target","prop","currentStore","value","bind","Reflect","set","clonedStore","Object","assign","next","getPartialObjectFromAttributes","attributes","store","reduce","acc","curr","storeName","initialValue","_cervelloStore","BehaviorSubject","proxiedStore","cervelloStore","useStore","_useState","useState","setStore","isFirstTime","useRef","useEffect","subscription","pipe","observeOn","queueScheduler","subscribe","n","current","unsubscribe","createUseStore","useSelect","createUseSelect","selectors","slice","call","arguments","selectedStore","distinctUntilChanged","prev","isEqual","forEach","selector","JSON","stringify","partialStore","length","use","func","_func","$onChange","cb","pairwise","switchMap","oldValue","newValue","of","NEVER","_","$onPartialChange","attrs","_ref2","this"],"mappings":"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"}
1
+ {"version":3,"file":"cervello.cjs","sources":["../src/lib/helpers/proxify-store.ts","../src/lib/utils/subscribe-for-react.ts","../src/lib/helpers/create-use-store.ts","../src/lib/helpers/create-use-selector.ts","../src/lib/store/index.ts"],"sourcesContent":["import type { BehaviorSubject } from 'rxjs'\n\n\n\nconst NESTED_ATTRIBUTES_SYMBOL = '___nested-attributes___'\nconst nestedAttrs = Symbol(NESTED_ATTRIBUTES_SYMBOL)\n\nexport function proxifyStore <T extends Record<string | symbol, any>> (store$$: BehaviorSubject<T>, storeObject: T): T {\n if (typeof storeObject !== 'object') throw new Error('Store must be an object')\n\n return new Proxy<T>(\n storeObject,\n {\n get: function (target: T, prop: string | symbol): any {\n const currentStore = target as any\n // console.log('get', { target, prop, in: prop in currentStore })\n\n // Problem with nested proxies because of currentStore is the root object\n if (prop in currentStore) {\n if (typeof currentStore[prop] === 'function') {\n return currentStore[prop].bind(proxifyStore(store$$, currentStore))\n }\n\n // console.log('------', prop, typeof currentStore[prop] === 'object', !Array.isArray(currentStore[prop]))\n // TODO: add pseudo identifier in order to return\n // TODO: the same object with a identifier of the level and the name of the property\n if (typeof currentStore[prop] === 'object' && !Array.isArray(currentStore[prop]) && typeof prop !== 'symbol') {\n // console.log('returning proxified object', prop)\n return proxifyStore(\n store$$,\n {\n ...currentStore[prop],\n [nestedAttrs]: `${(target?.[nestedAttrs]) ?? ''}${prop}`,\n })\n }\n\n return currentStore[prop]\n }\n\n return Reflect.get(target, prop)\n },\n set: function (target: T, prop: string | symbol, value: any) {\n // Write a merge deep nested objects function (as 'deepmerge lib')\n // console.log('set', { target, prop, value })\n const currentStore = store$$.getValue() as any\n\n const clonedStore = Object.assign({}, currentStore)\n clonedStore[prop] = value\n\n store$$.next(clonedStore)\n\n return Reflect.set(target, prop, value)\n },\n },\n )\n}\n","import type { BehaviorSubject } from 'rxjs'\n\n\n\nexport const subscribeForReactHook = <T>(store$$: BehaviorSubject<T>): typeof subscribe => {\n const subscribe = (onStoreChange: () => void): () => void => {\n const subscription = store$$.subscribe(onStoreChange)\n return () => {\n subscription.unsubscribe()\n }\n }\n return subscribe\n}\n","\nimport { useSyncExternalStore } from 'use-sync-external-store/shim'\n\nimport { subscribeForReactHook } from '../utils/subscribe-for-react'\nimport { proxifyStore } from './proxify-store'\n\nimport type { BehaviorSubject } from 'rxjs'\n\n\n\nexport function createUseStore <T> (store$$: BehaviorSubject<T>): () => T {\n const subscribe = subscribeForReactHook(store$$)\n const getValue = store$$.getValue.bind(store$$)\n\n\n // USE STORE HOOK -------------------------------------------------\n const useStore = (): T => {\n const store = useSyncExternalStore(subscribe, getValue, getValue)\n\n return proxifyStore(store$$, store)\n }\n\n\n return useStore\n}\n","\nimport { useSyncExternalStoreWithSelector } from 'use-sync-external-store/shim/with-selector'\n\n\nimport { subscribeForReactHook } from '../utils/subscribe-for-react'\nimport { proxifyStore } from './proxify-store'\n\nimport type { ObjectFromAttributes, WithoutType } from '../../types/shared'\nimport type { BehaviorSubject } from 'rxjs'\n\n\n\nexport function getPartialObjectFromAttributes <T> (attributes: Array<keyof T>, store: T): any {\n return attributes.reduce<any>((acc, curr) => {\n acc[curr] = store[curr]\n return acc\n }, {})\n}\n\nexport type UseSelector<T> = <Attributes extends Array< keyof WithoutType<T, Function> >>(\n selectors: Attributes,\n isEqualFunction?: (previousState: ObjectFromAttributes<T, Attributes>, currentState: ObjectFromAttributes<T, Attributes>) => boolean,\n ) => ObjectFromAttributes<T, Attributes>\n\nexport function createUseSelector <T> (store$$: BehaviorSubject<T>): UseSelector<T> {\n const subscribe = subscribeForReactHook(store$$)\n const getValue = store$$.getValue.bind(store$$)\n\n // const subscribeWithSelectors = (selectors: Array<keyof T>): (onStoreChange: () => void) => () => void => {\n // return (onStoreChange: () => void): (() => void) => {\n // const subscription = store$$.subscribe(onStoreChange)\n // // console.log('1- FUNCTION OF SUBSCRIBE')\n // // const subscription = store$$.pipe(distinctUntilChanged((prev, curr) => {\n // // let isEqual = true\n // // selectors.forEach((selector) => {\n // // if (typeof curr[selector] === 'object' && isEqual) {\n // // if (JSON.stringify(prev[selector]) !== JSON.stringify(curr[selector])) {\n // // isEqual = false\n // // }\n // // } else {\n // // if (prev[selector] !== curr[selector] && isEqual) {\n // // isEqual = false\n // // }\n // // }\n // // })\n // // console.log('1- FUNCTION OF distinctUntilChanged', { isEqual })\n\n // // return isEqual\n // // })).subscribe(onStoreChange)\n\n // return () => {\n // subscription.unsubscribe()\n // }\n // }\n // }\n\n\n\n\n // USE SELECTOR HOOK -------------------------------------------------\n const useSelector = <Attributes extends Array< keyof WithoutType<T, Function> >>(\n selectors: Attributes,\n isEqualFunction?: (previousState: ObjectFromAttributes<T, Attributes>, currentState: ObjectFromAttributes<T, Attributes>) => boolean,\n ): ObjectFromAttributes<T, Attributes> => {\n const store = useSyncExternalStoreWithSelector<T, ObjectFromAttributes<T, Attributes>>(\n subscribe,\n getValue,\n getValue,\n (store) => getPartialObjectFromAttributes(selectors, store),\n (prev, curr) => isEqualFunction\n ? isEqualFunction(prev, curr)\n : JSON.stringify(prev) === JSON.stringify(curr),\n\n )\n\n return proxifyStore(store$$ as any, store)\n }\n\n return useSelector\n}\n","import { BehaviorSubject, distinctUntilChanged, NEVER, of, pairwise, switchMap } from 'rxjs'\n\nimport { createUseSelector, createUseStore, proxifyStore } from '../helpers'\n\nimport type { WithoutType } from '../../types/shared'\nimport type { UseSelector } from '../helpers'\n\n\n\n// const STORE_SYMBOL = '__cervello-store__'\n\n\ninterface CervelloStoreUseParam<StoreType> {\n onChange: (cb: (store: StoreType) => void) => void\n onPartialChange: <\n Attributes extends Array< keyof WithoutType<StoreType, Function>>\n > (selectors: Attributes, cb: (store: StoreType) => void) => void\n}\n\n/**\n * Use function which allows you to listen for changes in the store.\n */\nexport type CervelloUseFunction<StoreType> = (param: CervelloStoreUseParam<StoreType>) => void\n\n\ninterface CervelloStore<StoreType> {\n /** Reactive store */\n store: StoreType\n /** Hook to react to all changes done to 'store' */\n useStore: () => StoreType\n /** Hook to react to changes done to 'store' in all the attributes provided */\n useSelector: UseSelector<StoreType>\n /** Functions to be attached to changes in a general way (tracking, loggers, ... etc) */\n use: (...functions: Array<(useObj: CervelloStoreUseParam<StoreType>) => void>) => CervelloStore<StoreType>\n}\n\n/**\n * @note Currently not working\n */\nexport interface CervelloOptions {\n persist?:\n | boolean\n // | {\n // getItem: (key: string) => any\n // }\n}\n\n\n/**\n * Creates a store that is reactive and can be used inside and outside of React components.\n * @param initialValue Object with the default values for the store\n *\n * @returns - { store, useStore, useSelector }\n */\nexport function cervello <T extends Record<any, unknown>> (initialValue: T, options?: CervelloOptions): CervelloStore<T>\n\n\n/**\n * Creates a store that is reactive and can be used inside and outside of React components.\n * @param initialValue Function which returns the default values for the store\n *\n * @returns - { store, useStore, useSelector }\n */\nexport function cervello <T> (initialValue: () => T, options?: CervelloOptions): CervelloStore<T>\n\n\n\n\n\n\n\n/** @internal */\nexport function cervello <T> (initialValue: T | (() => T), options?: CervelloOptions): CervelloStore<T> {\n const defaultValue = (typeof initialValue === 'function' ? (initialValue as any)() : initialValue) as T\n const store$$ = new BehaviorSubject<T>(defaultValue)\n\n const proxiedStore = proxifyStore<T>(store$$, { ...defaultValue })\n\n const cervelloStore = {\n store: proxiedStore,\n\n // TO BE SEPARATED IN cervello/react package ---------------------\n useStore: createUseStore<T>(store$$),\n useSelector: createUseSelector<T>(store$$),\n // ---------------------------------------------------------------\n\n use (...functionList: any) {\n functionList.forEach((func: any) => {\n func({\n onChange (cb: any) {\n store$$.pipe(\n pairwise(),\n switchMap(([oldValue, newValue]) => (oldValue !== newValue ? of(newValue) : NEVER)),\n ).subscribe((_) => cb(proxiedStore))\n },\n onPartialChange (attrs: Array<keyof T>, cb: any) {\n store$$.pipe(\n pairwise(),\n switchMap(([oldValue, newValue]) => (oldValue !== newValue ? of(newValue) : NEVER)),\n distinctUntilChanged((prev, curr) => {\n let isEqual = true\n attrs.forEach((selector) => {\n if (isEqual && typeof curr[selector] === 'object') {\n if (JSON.stringify(prev[selector]) !== JSON.stringify(curr[selector])) {\n isEqual = false\n }\n } else {\n if (isEqual && prev[selector] !== curr[selector]) {\n isEqual = false\n }\n }\n })\n return isEqual\n }),\n ).subscribe((_) => cb(proxiedStore))\n },\n })\n })\n return this\n },\n } as any\n\n\n\n return cervelloStore as CervelloStore<T>\n}\n"],"names":["nestedAttrs","Symbol","store$$","storeObject","Error","Proxy","get","target","prop","_target$nestedAttrs","_extends2","currentStore","bind","proxifyStore","Array","isArray","_extends","set","value","getValue","clonedStore","Object","assign","next","subscribeForReactHook","onStoreChange","subscription","subscribe","unsubscribe","createUseStore","store","useSyncExternalStore","createUseSelector","selectors","isEqualFunction","useSyncExternalStoreWithSelector","getPartialObjectFromAttributes","attributes","reduce","acc","curr","prev","JSON","stringify","initialValue","options","defaultValue","proxiedStore","cervelloStore","useStore","useSelector","use","slice","call","arguments","forEach","func","onChange","cb","pipe","pairwise","switchMap","oldValue","newValue","of","NEVER","_","onPartialChange","attrs","_ref2","distinctUntilChanged","isEqual","selector","this"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import{observeOn as n,queueScheduler as r,distinctUntilChanged as t,BehaviorSubject as e,pairwise as u,switchMap as i,of as c,NEVER as o}from"rxjs";import{useState as f,useRef as a,useEffect as s}from"react";function b(){return b=Object.assign?Object.assign.bind():function(n){for(var r=1;r<arguments.length;r++){var t=arguments[r];for(var e in t)Object.prototype.hasOwnProperty.call(t,e)&&(n[e]=t[e])}return n},b.apply(this,arguments)}function v(n,r){if("object"!=typeof r)throw new Error("Store must be an object");return new Proxy(r,{get:function(r,t){var e=n.value;return t in e?"function"==typeof e[t]?e[t].bind(v(n,e)):e[t]:Reflect.get(r,t)},set:function(r,t,e){var u=Object.assign({},n.value);return u[t]=e,n.next(u),Reflect.set(r,t,e)}})}function l(n,r){return n.reduce(function(n,t){return n[t]=r[t],n},{})}function p(p,g){var y,h=new e(g),j=v(h,b({},g)),O=((y={})[p]=j,y.useStore=function(t){return function(){var e=f(v(t,t.value)),u=e[0],i=e[1],c=a(!0);return s(function(){var e=t.pipe(n(r)).subscribe(function(n){c.current?c.current=!1:i(v(t,n))});return function(){return e.unsubscribe()}},[]),u}}(h),y.useSelect=function(n){return function(){var r=[].slice.call(arguments),e=f(function(){var t=l(r,n.value);return v(n,t)}),u=e[0],i=e[1],c=a(!0);return s(function(){var e=n.pipe(t(function(n,t){var e=!0;return r.forEach(function(r){"object"==typeof t[r]&&e?JSON.stringify(n[r])!==JSON.stringify(t[r])&&(e=!1):n[r]!==t[r]&&e&&(e=!1)}),e})).subscribe(function(t){if(c.current)c.current=!1;else{var e=l(r,t);i(v(n,e))}});return function(){return e.unsubscribe()}},[r.length]),u}}(h),y.use=function(){return[].slice.call(arguments).forEach(function(n){var r;n(((r={})[p]=j,r.$onChange=function(n){h.pipe(u(),i(function(n){var r=n[1];return n[0]!==r?c(r):o})).subscribe(function(r){return n(j)})},r.$onPartialChange=function(n,r){h.pipe(u(),i(function(n){var r=n[1];return n[0]!==r?c(r):o}),t(function(r,t){var e=!0;return n.forEach(function(n){"object"==typeof t[n]&&e?JSON.stringify(r[n])!==JSON.stringify(t[n])&&(e=!1):r[n]!==t[n]&&e&&(e=!1)}),e})).subscribe(function(n){return r(j)})},r))}),this},y);return O}export{p as cervello};
1
+ import{BehaviorSubject as n,pairwise as t,switchMap as r,of as e,NEVER as u,distinctUntilChanged as o}from"rxjs";import{useSyncExternalStore as i}from"use-sync-external-store/shim";import{useSyncExternalStoreWithSelector as c}from"use-sync-external-store/shim/with-selector";function f(){return f=Object.assign?Object.assign.bind():function(n){for(var t=1;t<arguments.length;t++){var r=arguments[t];for(var e in r)Object.prototype.hasOwnProperty.call(r,e)&&(n[e]=r[e])}return n},f.apply(this,arguments)}var s=Symbol("___nested-attributes___");function a(n,t){if("object"!=typeof t)throw new Error("Store must be an object");return new Proxy(t,{get:function(t,r){var e,u,o=t;return r in o?"function"==typeof o[r]?o[r].bind(a(n,o)):"object"!=typeof o[r]||Array.isArray(o[r])||"symbol"==typeof r?o[r]:a(n,f({},o[r],((u={})[s]=""+(null!=(e=null==t?void 0:t[s])?e:"")+r,u))):Reflect.get(t,r)},set:function(t,r,e){var u=n.getValue(),o=Object.assign({},u);return o[r]=e,n.next(o),Reflect.set(t,r,e)}})}var b=function(n){return function(t){var r=n.subscribe(t);return function(){r.unsubscribe()}}};function l(n){var t=b(n),r=n.getValue.bind(n);return function(){var e=i(t,r,r);return a(n,e)}}function y(n){var t=b(n),r=n.getValue.bind(n);return function(e,u){var o=c(t,r,r,function(n){return function(n,t){return n.reduce(function(n,r){return n[r]=t[r],n},{})}(e,n)},function(n,t){return u?u(n,t):JSON.stringify(n)===JSON.stringify(t)});return a(n,o)}}function p(i,c){var s="function"==typeof i?i():i,b=new n(s),p=a(b,f({},s)),v={store:p,useStore:l(b),useSelector:y(b),use:function(){return[].slice.call(arguments).forEach(function(n){n({onChange:function(n){b.pipe(t(),r(function(n){var t=n[1];return n[0]!==t?e(t):u})).subscribe(function(t){return n(p)})},onPartialChange:function(n,i){b.pipe(t(),r(function(n){var t=n[1];return n[0]!==t?e(t):u}),o(function(t,r){var e=!0;return n.forEach(function(n){e&&"object"==typeof r[n]?JSON.stringify(t[n])!==JSON.stringify(r[n])&&(e=!1):e&&t[n]!==r[n]&&(e=!1)}),e})).subscribe(function(n){return i(p)})}})}),this}};return v}export{p as cervello};
2
2
  //# sourceMappingURL=cervello.esm.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"cervello.esm.js","sources":["../src/lib/helpers/proxify-store.ts","../src/lib/helpers/create-use-select.ts","../src/lib/store/index.ts","../src/lib/helpers/create-use-store.ts"],"sourcesContent":["import type { BehaviorSubject } from 'rxjs'\n\n\n\nexport function proxifyStore <T extends Record<string | symbol, any>> (store$$: BehaviorSubject<T>, storeObject: T): T {\n if (typeof storeObject !== 'object') throw new Error('Store must be an object')\n\n return new Proxy<T>(\n storeObject,\n {\n get: function (target: T, prop: string | symbol): any {\n const currentStore = store$$.value as any\n\n if (prop in currentStore) {\n if (typeof currentStore[prop] === 'function') {\n return currentStore[prop].bind(proxifyStore(store$$, currentStore))\n }\n\n return currentStore[prop]\n }\n\n return Reflect.get(target, prop)\n },\n set: function (target: T, prop: string | symbol, value: any) {\n const currentStore = store$$.value as any\n\n const clonedStore = Object.assign({}, currentStore)\n clonedStore[prop] = value\n\n store$$.next(clonedStore)\n\n return Reflect.set(target, prop, value)\n },\n },\n )\n}\n","import { useEffect, useRef, useState } from 'react'\nimport { distinctUntilChanged } from 'rxjs'\n\nimport { proxifyStore } from './proxify-store'\n\nimport type { ObjectFromAttributes } from '../../types/shared'\nimport type { BehaviorSubject } from 'rxjs'\n\n\n\nexport function getPartialObjectFromAttributes <T> (attributes: Array<keyof T>, store: T): any {\n return attributes.reduce<any>((acc, curr) => {\n acc[curr] = store[curr]\n return acc\n }, {})\n}\n\n\nexport function createUseSelect <T> (store$$: BehaviorSubject<T>) {\n //\n return <Attributes extends Array<keyof T>>(...selectors: Attributes): ObjectFromAttributes<T, Attributes> => {\n const [store, setStore] = useState<any>(() => {\n const selectedStore = getPartialObjectFromAttributes(selectors, store$$.value)\n return proxifyStore(store$$, selectedStore)\n })\n const isFirstTime = useRef(true)\n\n\n useEffect(() => {\n const subscription = store$$.pipe(distinctUntilChanged((prev, curr) => {\n let isEqual = true\n selectors.forEach((selector) => {\n if (typeof curr[selector] === 'object' && isEqual) {\n if (JSON.stringify(prev[selector]) !== JSON.stringify(curr[selector])) {\n isEqual = false\n }\n } else {\n if (prev[selector] !== curr[selector] && isEqual) {\n isEqual = false\n }\n }\n })\n\n return isEqual\n })).subscribe((partialStore) => {\n if (isFirstTime.current) {\n isFirstTime.current = false\n } else {\n const selectedStore = getPartialObjectFromAttributes(selectors, partialStore)\n setStore(proxifyStore(store$$, selectedStore))\n }\n })\n\n\n return () => subscription.unsubscribe()\n }, [selectors.length])\n\n\n return store\n }\n}\n","import { BehaviorSubject, distinctUntilChanged, NEVER, of, pairwise, switchMap } from 'rxjs'\n\nimport { createUseSelect, createUseStore, proxifyStore } from '../helpers'\n\nimport type { ObjectFromAttributes } from '../../types/shared'\n\n\n\n// const STORE_SYMBOL = '__cervello-store__'\n\n\n\n\ntype CervelloStoreUseParam<StoreName extends string, StoreType> = {\n [k in StoreName]: StoreType\n} & {\n $onChange: (cb: (store: StoreType) => void) => void\n $onPartialChange: <\n Attributes extends Array<keyof StoreType>\n > (selectors: Attributes, cb: (store: StoreType) => void) => void\n}\n\n\nexport type CervelloUseFunction<StoreName extends string, StoreType> = (param: CervelloStoreUseParam<StoreName, StoreType>) => void\n\n\ntype CervelloStore<StoreName extends string, StoreType> = {\n [k in StoreName]: StoreType\n} & {\n useStore: () => StoreType\n useSelect: <Attributes extends Array<keyof StoreType>>(...selectors: Attributes) => ObjectFromAttributes<StoreType, Attributes>\n use: (...functions: Array<(useObj: CervelloStoreUseParam<StoreName, StoreType>) => void>) => CervelloStore<StoreName, StoreType>\n}\n\n\n\n\nexport function cervello <\n StoreName extends string,\n T\n> (storeName: StoreName, initialValue: T): CervelloStore<StoreName, T> {\n // Unique symbol to be used to keep a reference of the BehaviourSubject\n // const storeSymbol = Symbol(STORE_SYMBOL)\n\n\n const store$$ = new BehaviorSubject<T>(initialValue)\n\n const proxiedStore = proxifyStore(store$$, { ...initialValue })\n\n const cervelloStore = {\n [storeName]: proxiedStore,\n\n // TO BE SEPARATED IN cervello/react package ---------------------\n useStore: createUseStore<T>(store$$),\n useSelect: createUseSelect<T>(store$$),\n // ---------------------------------------------------------------\n\n use (...functionList: any) {\n functionList.forEach((func: any) => {\n func({\n [storeName]: proxiedStore,\n $onChange (cb: any) {\n store$$.pipe(\n pairwise(),\n switchMap(([oldValue, newValue]) => (oldValue !== newValue ? of(newValue) : NEVER)),\n ).subscribe((_) => cb(proxiedStore))\n },\n $onPartialChange (attrs: Array<keyof T>, cb: any) {\n store$$.pipe(\n pairwise(),\n switchMap(([oldValue, newValue]) => (oldValue !== newValue ? of(newValue) : NEVER)),\n distinctUntilChanged((prev, curr) => {\n let isEqual = true\n attrs.forEach((selector) => {\n if (typeof curr[selector] === 'object' && isEqual) {\n if (JSON.stringify(prev[selector]) !== JSON.stringify(curr[selector])) {\n isEqual = false\n }\n } else {\n if (prev[selector] !== curr[selector] && isEqual) {\n isEqual = false\n }\n }\n })\n return isEqual\n }),\n ).subscribe((_) => cb(proxiedStore))\n },\n })\n })\n return this\n },\n } as any\n\n\n\n return cervelloStore as CervelloStore<StoreName, T>\n}\n","import { useEffect, useRef, useState } from 'react'\nimport { observeOn, queueScheduler } from 'rxjs'\n\nimport { proxifyStore } from './proxify-store'\n\nimport type { BehaviorSubject } from 'rxjs'\n\n\n\nexport function createUseStore <T> (store$$: BehaviorSubject<T>): () => T {\n return () => {\n const [store, setStore] = useState<T>(proxifyStore(store$$, store$$.value))\n const isFirstTime = useRef(true)\n\n // TODO: Use new useSyncExternalStore API hook\n useEffect(() => {\n const subscription = store$$.pipe(observeOn(queueScheduler)).subscribe((n) => {\n if (isFirstTime.current) {\n isFirstTime.current = false\n } else {\n setStore(proxifyStore(store$$, n))\n }\n })\n\n return () => subscription.unsubscribe()\n }, [])\n\n\n return store\n }\n}\n"],"names":["proxifyStore","store$$","storeObject","Error","Proxy","get","target","prop","currentStore","value","bind","Reflect","set","clonedStore","Object","assign","next","getPartialObjectFromAttributes","attributes","store","reduce","acc","curr","cervello","storeName","initialValue","_cervelloStore","BehaviorSubject","proxiedStore","cervelloStore","useStore","_useState","useState","setStore","isFirstTime","useRef","useEffect","subscription","pipe","observeOn","queueScheduler","subscribe","n","current","unsubscribe","createUseStore","useSelect","createUseSelect","selectors","slice","call","arguments","selectedStore","distinctUntilChanged","prev","isEqual","forEach","selector","JSON","stringify","partialStore","length","use","func","_func","$onChange","cb","pairwise","switchMap","oldValue","newValue","of","NEVER","_","$onPartialChange","attrs","_ref2","this"],"mappings":"obAIgBA,SAAAA,EAAuDC,EAA6BC,GAClG,GAA2B,iBAAhBA,EAA0B,MAAM,IAAAC,MAAU,2BAErD,WAAOC,MACLF,EACA,CACEG,IAAK,SAAUC,EAAWC,GACxB,IAAkBC,EAAGP,EAAQQ,MAE7B,OAAIF,OACgC,qBAAVA,KACFA,GAAMG,KAAKV,EAAaC,EAASO,IAGhDA,EAAaD,GAGRI,QAACN,IAAIC,EAAQC,IAE7BK,IAAK,SAAUN,EAAWC,EAAuBE,GAC/C,IAEMI,EAAcC,OAAOC,OAAO,GAFbd,EAAQQ,OAO7B,OAJAI,EAAYN,GAAQE,EAEpBR,EAAQe,KAAKH,GAENF,QAAQC,IAAIN,EAAQC,EAAME,MCrBzB,SAAAQ,EAAoCC,EAA4BC,GAC9E,SAAkBC,OAAY,SAACC,EAAKC,GAElC,OADAD,EAAIC,GAAQH,EAAMG,GACXD,GACN,ICuBW,SAAAE,EAGbC,EAAsBC,GAAe,IAAAC,EAKhCzB,EAAU,IAAA0B,EAAuBF,GAErBG,EAAG5B,EAAaC,EAAcwB,EAAAA,GAAAA,IAE1CI,IACHL,EAAAA,IAAAA,GAAYI,EADIF,EAIjBI,SC5CE,SAA8B7B,GAClC,kBACE,IAAA8B,EAA0BC,EAAYhC,EAAaC,EAASA,EAAQQ,QAA7DU,EAAPY,EAAA,GAAcE,EAAdF,EAAA,GACMG,EAAcC,GAAO,GAgB3B,OAbAC,EAAU,WACR,IAAkBC,EAAGpC,EAAQqC,KAAKC,EAAUC,IAAiBC,UAAU,SAACC,GAClER,EAAYS,QACdT,EAAYS,SAAU,EAEtBV,EAASjC,EAAaC,EAASyC,MAInC,OAAO,WAAA,OAAkBL,EAACO,gBACzB,IAGIzB,GDyBG0B,CAAkB5C,KAC5B6C,UDpCYC,SAAqB9C,GAEnC,OAA4G,WAAA,IAAA+C,EAAA,GAAAC,MAAAC,KAAAC,WAChFnB,EAAAA,EAAc,WACtC,IAAmBoB,EAAGnC,EAA+B+B,EAAW/C,EAAQQ,OACxE,OAAmBT,EAACC,EAASmD,KAFxBjC,OAAOc,EAAdF,EAAA,GAIMG,EAAcC,GAAO,GAiC3B,OA9BAC,EAAU,WACR,IAAMC,EAAepC,EAAQqC,KAAKe,EAAqB,SAACC,EAAMhC,GAC5D,IAAIiC,GAAU,EAad,OAZAP,EAAUQ,QAAQ,SAACC,GACa,iBAAfnC,EAACmC,IAA0BF,EACpCG,KAAKC,UAAUL,EAAKG,MAAeC,KAAKC,UAAUrC,EAAKmC,MACzDF,GAAU,GAGRD,EAAKG,KAAcnC,EAAKmC,IAAaF,IACvCA,GAAU,KAKTA,KACLd,UAAU,SAACmB,GACb,GAAI1B,EAAYS,QACdT,EAAYS,SAAU,MACjB,CACL,IAAMS,EAAgBnC,EAA+B+B,EAAWY,GAChE3B,EAASjC,EAAaC,EAASmD,OAKnC,OAAaf,WAAAA,OAAAA,EAAaO,gBACzB,CAACI,EAAUa,YCDHd,CAAmB9C,GAG9B6D,EAAAA,IAAyB,WAiCvB,MAhCA,GAAaN,MAAAA,KAAAA,WAAAA,QAAQ,SAACO,SACpBA,IAAIC,EAAA,IACDxC,GAAYI,EADXoC,EAEFC,UAFE,SAESC,GACTjE,EAAQqC,KACN6B,IACAC,EAAU,SAAEC,GAAAA,IAAUC,EAAeD,EAAAA,GAAAA,OAAfC,EAAAA,KAA4BA,EAAWC,EAAGD,GAAYE,KAC5E/B,UAAU,SAACgC,GAAD,SAAU7C,MAExB8C,EAAAA,0BAAkBC,EAAuBT,GACvCjE,EAAQqC,KACN6B,IACAC,EAAU,SAAEC,GAAAA,IAAUC,EAAZM,EAAA,GAAA,cAAwCN,EAAWC,EAAGD,GAAYE,IAC5EnB,EAAqB,SAACC,EAAMhC,GAC1B,IAAWiC,GAAG,EAYd,OAXAoB,EAAMnB,QAAQ,SAACC,GACiB,iBAAnBnC,EAAKmC,IAA0BF,EACpCG,KAAKC,UAAUL,EAAKG,MAAeC,KAAKC,UAAUrC,EAAKmC,MACzDF,GAAU,GAGRD,EAAKG,KAAcnC,EAAKmC,IAAaF,IACvCA,GAAU,KAKjBA,KACDd,UAAU,SAACgC,GAAD,OAASP,EAACtC,MAG3BoC,MAEFa,MA1CHnD,GA+CA,OACDG"}
1
+ {"version":3,"file":"cervello.esm.js","sources":["../src/lib/helpers/proxify-store.ts","../src/lib/utils/subscribe-for-react.ts","../src/lib/helpers/create-use-store.ts","../src/lib/helpers/create-use-selector.ts","../src/lib/store/index.ts"],"sourcesContent":["import type { BehaviorSubject } from 'rxjs'\n\n\n\nconst NESTED_ATTRIBUTES_SYMBOL = '___nested-attributes___'\nconst nestedAttrs = Symbol(NESTED_ATTRIBUTES_SYMBOL)\n\nexport function proxifyStore <T extends Record<string | symbol, any>> (store$$: BehaviorSubject<T>, storeObject: T): T {\n if (typeof storeObject !== 'object') throw new Error('Store must be an object')\n\n return new Proxy<T>(\n storeObject,\n {\n get: function (target: T, prop: string | symbol): any {\n const currentStore = target as any\n // console.log('get', { target, prop, in: prop in currentStore })\n\n // Problem with nested proxies because of currentStore is the root object\n if (prop in currentStore) {\n if (typeof currentStore[prop] === 'function') {\n return currentStore[prop].bind(proxifyStore(store$$, currentStore))\n }\n\n // console.log('------', prop, typeof currentStore[prop] === 'object', !Array.isArray(currentStore[prop]))\n // TODO: add pseudo identifier in order to return\n // TODO: the same object with a identifier of the level and the name of the property\n if (typeof currentStore[prop] === 'object' && !Array.isArray(currentStore[prop]) && typeof prop !== 'symbol') {\n // console.log('returning proxified object', prop)\n return proxifyStore(\n store$$,\n {\n ...currentStore[prop],\n [nestedAttrs]: `${(target?.[nestedAttrs]) ?? ''}${prop}`,\n })\n }\n\n return currentStore[prop]\n }\n\n return Reflect.get(target, prop)\n },\n set: function (target: T, prop: string | symbol, value: any) {\n // Write a merge deep nested objects function (as 'deepmerge lib')\n // console.log('set', { target, prop, value })\n const currentStore = store$$.getValue() as any\n\n const clonedStore = Object.assign({}, currentStore)\n clonedStore[prop] = value\n\n store$$.next(clonedStore)\n\n return Reflect.set(target, prop, value)\n },\n },\n )\n}\n","import type { BehaviorSubject } from 'rxjs'\n\n\n\nexport const subscribeForReactHook = <T>(store$$: BehaviorSubject<T>): typeof subscribe => {\n const subscribe = (onStoreChange: () => void): () => void => {\n const subscription = store$$.subscribe(onStoreChange)\n return () => {\n subscription.unsubscribe()\n }\n }\n return subscribe\n}\n","\nimport { useSyncExternalStore } from 'use-sync-external-store/shim'\n\nimport { subscribeForReactHook } from '../utils/subscribe-for-react'\nimport { proxifyStore } from './proxify-store'\n\nimport type { BehaviorSubject } from 'rxjs'\n\n\n\nexport function createUseStore <T> (store$$: BehaviorSubject<T>): () => T {\n const subscribe = subscribeForReactHook(store$$)\n const getValue = store$$.getValue.bind(store$$)\n\n\n // USE STORE HOOK -------------------------------------------------\n const useStore = (): T => {\n const store = useSyncExternalStore(subscribe, getValue, getValue)\n\n return proxifyStore(store$$, store)\n }\n\n\n return useStore\n}\n","\nimport { useSyncExternalStoreWithSelector } from 'use-sync-external-store/shim/with-selector'\n\n\nimport { subscribeForReactHook } from '../utils/subscribe-for-react'\nimport { proxifyStore } from './proxify-store'\n\nimport type { ObjectFromAttributes, WithoutType } from '../../types/shared'\nimport type { BehaviorSubject } from 'rxjs'\n\n\n\nexport function getPartialObjectFromAttributes <T> (attributes: Array<keyof T>, store: T): any {\n return attributes.reduce<any>((acc, curr) => {\n acc[curr] = store[curr]\n return acc\n }, {})\n}\n\nexport type UseSelector<T> = <Attributes extends Array< keyof WithoutType<T, Function> >>(\n selectors: Attributes,\n isEqualFunction?: (previousState: ObjectFromAttributes<T, Attributes>, currentState: ObjectFromAttributes<T, Attributes>) => boolean,\n ) => ObjectFromAttributes<T, Attributes>\n\nexport function createUseSelector <T> (store$$: BehaviorSubject<T>): UseSelector<T> {\n const subscribe = subscribeForReactHook(store$$)\n const getValue = store$$.getValue.bind(store$$)\n\n // const subscribeWithSelectors = (selectors: Array<keyof T>): (onStoreChange: () => void) => () => void => {\n // return (onStoreChange: () => void): (() => void) => {\n // const subscription = store$$.subscribe(onStoreChange)\n // // console.log('1- FUNCTION OF SUBSCRIBE')\n // // const subscription = store$$.pipe(distinctUntilChanged((prev, curr) => {\n // // let isEqual = true\n // // selectors.forEach((selector) => {\n // // if (typeof curr[selector] === 'object' && isEqual) {\n // // if (JSON.stringify(prev[selector]) !== JSON.stringify(curr[selector])) {\n // // isEqual = false\n // // }\n // // } else {\n // // if (prev[selector] !== curr[selector] && isEqual) {\n // // isEqual = false\n // // }\n // // }\n // // })\n // // console.log('1- FUNCTION OF distinctUntilChanged', { isEqual })\n\n // // return isEqual\n // // })).subscribe(onStoreChange)\n\n // return () => {\n // subscription.unsubscribe()\n // }\n // }\n // }\n\n\n\n\n // USE SELECTOR HOOK -------------------------------------------------\n const useSelector = <Attributes extends Array< keyof WithoutType<T, Function> >>(\n selectors: Attributes,\n isEqualFunction?: (previousState: ObjectFromAttributes<T, Attributes>, currentState: ObjectFromAttributes<T, Attributes>) => boolean,\n ): ObjectFromAttributes<T, Attributes> => {\n const store = useSyncExternalStoreWithSelector<T, ObjectFromAttributes<T, Attributes>>(\n subscribe,\n getValue,\n getValue,\n (store) => getPartialObjectFromAttributes(selectors, store),\n (prev, curr) => isEqualFunction\n ? isEqualFunction(prev, curr)\n : JSON.stringify(prev) === JSON.stringify(curr),\n\n )\n\n return proxifyStore(store$$ as any, store)\n }\n\n return useSelector\n}\n","import { BehaviorSubject, distinctUntilChanged, NEVER, of, pairwise, switchMap } from 'rxjs'\n\nimport { createUseSelector, createUseStore, proxifyStore } from '../helpers'\n\nimport type { WithoutType } from '../../types/shared'\nimport type { UseSelector } from '../helpers'\n\n\n\n// const STORE_SYMBOL = '__cervello-store__'\n\n\ninterface CervelloStoreUseParam<StoreType> {\n onChange: (cb: (store: StoreType) => void) => void\n onPartialChange: <\n Attributes extends Array< keyof WithoutType<StoreType, Function>>\n > (selectors: Attributes, cb: (store: StoreType) => void) => void\n}\n\n/**\n * Use function which allows you to listen for changes in the store.\n */\nexport type CervelloUseFunction<StoreType> = (param: CervelloStoreUseParam<StoreType>) => void\n\n\ninterface CervelloStore<StoreType> {\n /** Reactive store */\n store: StoreType\n /** Hook to react to all changes done to 'store' */\n useStore: () => StoreType\n /** Hook to react to changes done to 'store' in all the attributes provided */\n useSelector: UseSelector<StoreType>\n /** Functions to be attached to changes in a general way (tracking, loggers, ... etc) */\n use: (...functions: Array<(useObj: CervelloStoreUseParam<StoreType>) => void>) => CervelloStore<StoreType>\n}\n\n/**\n * @note Currently not working\n */\nexport interface CervelloOptions {\n persist?:\n | boolean\n // | {\n // getItem: (key: string) => any\n // }\n}\n\n\n/**\n * Creates a store that is reactive and can be used inside and outside of React components.\n * @param initialValue Object with the default values for the store\n *\n * @returns - { store, useStore, useSelector }\n */\nexport function cervello <T extends Record<any, unknown>> (initialValue: T, options?: CervelloOptions): CervelloStore<T>\n\n\n/**\n * Creates a store that is reactive and can be used inside and outside of React components.\n * @param initialValue Function which returns the default values for the store\n *\n * @returns - { store, useStore, useSelector }\n */\nexport function cervello <T> (initialValue: () => T, options?: CervelloOptions): CervelloStore<T>\n\n\n\n\n\n\n\n/** @internal */\nexport function cervello <T> (initialValue: T | (() => T), options?: CervelloOptions): CervelloStore<T> {\n const defaultValue = (typeof initialValue === 'function' ? (initialValue as any)() : initialValue) as T\n const store$$ = new BehaviorSubject<T>(defaultValue)\n\n const proxiedStore = proxifyStore<T>(store$$, { ...defaultValue })\n\n const cervelloStore = {\n store: proxiedStore,\n\n // TO BE SEPARATED IN cervello/react package ---------------------\n useStore: createUseStore<T>(store$$),\n useSelector: createUseSelector<T>(store$$),\n // ---------------------------------------------------------------\n\n use (...functionList: any) {\n functionList.forEach((func: any) => {\n func({\n onChange (cb: any) {\n store$$.pipe(\n pairwise(),\n switchMap(([oldValue, newValue]) => (oldValue !== newValue ? of(newValue) : NEVER)),\n ).subscribe((_) => cb(proxiedStore))\n },\n onPartialChange (attrs: Array<keyof T>, cb: any) {\n store$$.pipe(\n pairwise(),\n switchMap(([oldValue, newValue]) => (oldValue !== newValue ? of(newValue) : NEVER)),\n distinctUntilChanged((prev, curr) => {\n let isEqual = true\n attrs.forEach((selector) => {\n if (isEqual && typeof curr[selector] === 'object') {\n if (JSON.stringify(prev[selector]) !== JSON.stringify(curr[selector])) {\n isEqual = false\n }\n } else {\n if (isEqual && prev[selector] !== curr[selector]) {\n isEqual = false\n }\n }\n })\n return isEqual\n }),\n ).subscribe((_) => cb(proxiedStore))\n },\n })\n })\n return this\n },\n } as any\n\n\n\n return cervelloStore as CervelloStore<T>\n}\n"],"names":["nestedAttrs","Symbol","store$$","storeObject","Error","Proxy","get","target","prop","_target$nestedAttrs","_extends2","currentStore","bind","proxifyStore","Array","isArray","_extends","set","value","getValue","clonedStore","Object","assign","next","subscribeForReactHook","onStoreChange","subscription","subscribe","unsubscribe","createUseStore","store","useSyncExternalStore","createUseSelector","selectors","isEqualFunction","useSyncExternalStoreWithSelector","getPartialObjectFromAttributes","attributes","reduce","acc","curr","prev","JSON","stringify","cervello","initialValue","options","defaultValue","proxiedStore","cervelloStore","useStore","useSelector","use","slice","call","arguments","forEach","func","onChange","cb","pipe","pairwise","switchMap","oldValue","newValue","of","NEVER","_","onPartialChange","attrs","_ref2","distinctUntilChanged","isEqual","selector","this"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import{observeOn as t,queueScheduler as e,distinctUntilChanged as r,BehaviorSubject as n,pairwise as u,switchMap as o,of as c,NEVER as i}from"rxjs";import{useState as s,useRef as f,useEffect as b}from"react";function a(){return a=Object.assign?Object.assign.bind():function(t){for(var e=1;e<arguments.length;e++){var r=arguments[e];for(var n in r)Object.prototype.hasOwnProperty.call(r,n)&&(t[n]=r[n])}return t},a.apply(this,arguments)}function p(t,e){if("object"!=typeof e)throw new Error("Store must be an object");return new Proxy(e,{get:function(e,r){const n=t.value;return r in n?"function"==typeof n[r]?n[r].bind(p(t,n)):n[r]:Reflect.get(e,r)},set:function(e,r,n){const u=Object.assign({},t.value);return u[r]=n,t.next(u),Reflect.set(e,r,n)}})}function l(r){return()=>{const[n,u]=s(p(r,r.value)),o=f(!0);return b(()=>{const n=r.pipe(t(e)).subscribe(t=>{o.current?o.current=!1:u(p(r,t))});return()=>n.unsubscribe()},[]),n}}function g(t,e){return t.reduce((t,r)=>(t[r]=e[r],t),{})}function y(t){return(...e)=>{const[n,u]=s(()=>{const r=g(e,t.value);return p(t,r)}),o=f(!0);return b(()=>{const n=t.pipe(r((t,r)=>{let n=!0;return e.forEach(e=>{"object"==typeof r[e]&&n?JSON.stringify(t[e])!==JSON.stringify(r[e])&&(n=!1):t[e]!==r[e]&&n&&(n=!1)}),n})).subscribe(r=>{if(o.current)o.current=!1;else{const n=g(e,r);u(p(t,n))}});return()=>n.unsubscribe()},[e.length]),n}}function h(t,e){const s=new n(e),f=p(s,a({},e));return{[t]:f,useStore:l(s),useSelect:y(s),use(...e){return e.forEach(e=>{e({[t]:f,$onChange(t){s.pipe(u(),o(([t,e])=>t!==e?c(e):i)).subscribe(e=>t(f))},$onPartialChange(t,e){s.pipe(u(),o(([t,e])=>t!==e?c(e):i),r((e,r)=>{let n=!0;return t.forEach(t=>{"object"==typeof r[t]&&n?JSON.stringify(e[t])!==JSON.stringify(r[t])&&(n=!1):e[t]!==r[t]&&n&&(n=!1)}),n})).subscribe(t=>e(f))}})}),this}}}export{h as cervello};
1
+ import{BehaviorSubject as t,pairwise as e,switchMap as n,of as r,NEVER as o,distinctUntilChanged as s}from"rxjs";import{useSyncExternalStore as i}from"use-sync-external-store/shim";import{useSyncExternalStoreWithSelector as c}from"use-sync-external-store/shim/with-selector";function u(){return u=Object.assign?Object.assign.bind():function(t){for(var e=1;e<arguments.length;e++){var n=arguments[e];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(t[r]=n[r])}return t},u.apply(this,arguments)}const f=Symbol("___nested-attributes___");function a(t,e){if("object"!=typeof e)throw new Error("Store must be an object");return new Proxy(e,{get:function(e,n){const r=e;var o;return n in r?"function"==typeof r[n]?r[n].bind(a(t,r)):"object"!=typeof r[n]||Array.isArray(r[n])||"symbol"==typeof n?r[n]:a(t,u({},r[n],{[f]:`${null!=(o=null==e?void 0:e[f])?o:""}${n}`})):Reflect.get(e,n)},set:function(e,n,r){const o=t.getValue(),s=Object.assign({},o);return s[n]=r,t.next(s),Reflect.set(e,n,r)}})}const b=t=>e=>{const n=t.subscribe(e);return()=>{n.unsubscribe()}};function l(t){const e=b(t),n=t.getValue.bind(t);return()=>{const r=i(e,n,n);return a(t,r)}}function y(t){const e=b(t),n=t.getValue.bind(t);return(r,o)=>{const s=c(e,n,n,t=>function(t,e){return t.reduce((t,n)=>(t[n]=e[n],t),{})}(r,t),(t,e)=>o?o(t,e):JSON.stringify(t)===JSON.stringify(e));return a(t,s)}}function p(i,c){const f="function"==typeof i?i():i,b=new t(f),p=a(b,u({},f));return{store:p,useStore:l(b),useSelector:y(b),use(...t){return t.forEach(t=>{t({onChange(t){b.pipe(e(),n(([t,e])=>t!==e?r(e):o)).subscribe(e=>t(p))},onPartialChange(t,i){b.pipe(e(),n(([t,e])=>t!==e?r(e):o),s((e,n)=>{let r=!0;return t.forEach(t=>{r&&"object"==typeof n[t]?JSON.stringify(e[t])!==JSON.stringify(n[t])&&(r=!1):r&&e[t]!==n[t]&&(r=!1)}),r})).subscribe(t=>i(p))}})}),this}}}export{p as cervello};
2
2
  //# sourceMappingURL=cervello.modern.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"cervello.modern.js","sources":["../src/lib/helpers/proxify-store.ts","../src/lib/helpers/create-use-store.ts","../src/lib/helpers/create-use-select.ts","../src/lib/store/index.ts"],"sourcesContent":["import type { BehaviorSubject } from 'rxjs'\n\n\n\nexport function proxifyStore <T extends Record<string | symbol, any>> (store$$: BehaviorSubject<T>, storeObject: T): T {\n if (typeof storeObject !== 'object') throw new Error('Store must be an object')\n\n return new Proxy<T>(\n storeObject,\n {\n get: function (target: T, prop: string | symbol): any {\n const currentStore = store$$.value as any\n\n if (prop in currentStore) {\n if (typeof currentStore[prop] === 'function') {\n return currentStore[prop].bind(proxifyStore(store$$, currentStore))\n }\n\n return currentStore[prop]\n }\n\n return Reflect.get(target, prop)\n },\n set: function (target: T, prop: string | symbol, value: any) {\n const currentStore = store$$.value as any\n\n const clonedStore = Object.assign({}, currentStore)\n clonedStore[prop] = value\n\n store$$.next(clonedStore)\n\n return Reflect.set(target, prop, value)\n },\n },\n )\n}\n","import { useEffect, useRef, useState } from 'react'\nimport { observeOn, queueScheduler } from 'rxjs'\n\nimport { proxifyStore } from './proxify-store'\n\nimport type { BehaviorSubject } from 'rxjs'\n\n\n\nexport function createUseStore <T> (store$$: BehaviorSubject<T>): () => T {\n return () => {\n const [store, setStore] = useState<T>(proxifyStore(store$$, store$$.value))\n const isFirstTime = useRef(true)\n\n // TODO: Use new useSyncExternalStore API hook\n useEffect(() => {\n const subscription = store$$.pipe(observeOn(queueScheduler)).subscribe((n) => {\n if (isFirstTime.current) {\n isFirstTime.current = false\n } else {\n setStore(proxifyStore(store$$, n))\n }\n })\n\n return () => subscription.unsubscribe()\n }, [])\n\n\n return store\n }\n}\n","import { useEffect, useRef, useState } from 'react'\nimport { distinctUntilChanged } from 'rxjs'\n\nimport { proxifyStore } from './proxify-store'\n\nimport type { ObjectFromAttributes } from '../../types/shared'\nimport type { BehaviorSubject } from 'rxjs'\n\n\n\nexport function getPartialObjectFromAttributes <T> (attributes: Array<keyof T>, store: T): any {\n return attributes.reduce<any>((acc, curr) => {\n acc[curr] = store[curr]\n return acc\n }, {})\n}\n\n\nexport function createUseSelect <T> (store$$: BehaviorSubject<T>) {\n //\n return <Attributes extends Array<keyof T>>(...selectors: Attributes): ObjectFromAttributes<T, Attributes> => {\n const [store, setStore] = useState<any>(() => {\n const selectedStore = getPartialObjectFromAttributes(selectors, store$$.value)\n return proxifyStore(store$$, selectedStore)\n })\n const isFirstTime = useRef(true)\n\n\n useEffect(() => {\n const subscription = store$$.pipe(distinctUntilChanged((prev, curr) => {\n let isEqual = true\n selectors.forEach((selector) => {\n if (typeof curr[selector] === 'object' && isEqual) {\n if (JSON.stringify(prev[selector]) !== JSON.stringify(curr[selector])) {\n isEqual = false\n }\n } else {\n if (prev[selector] !== curr[selector] && isEqual) {\n isEqual = false\n }\n }\n })\n\n return isEqual\n })).subscribe((partialStore) => {\n if (isFirstTime.current) {\n isFirstTime.current = false\n } else {\n const selectedStore = getPartialObjectFromAttributes(selectors, partialStore)\n setStore(proxifyStore(store$$, selectedStore))\n }\n })\n\n\n return () => subscription.unsubscribe()\n }, [selectors.length])\n\n\n return store\n }\n}\n","import { BehaviorSubject, distinctUntilChanged, NEVER, of, pairwise, switchMap } from 'rxjs'\n\nimport { createUseSelect, createUseStore, proxifyStore } from '../helpers'\n\nimport type { ObjectFromAttributes } from '../../types/shared'\n\n\n\n// const STORE_SYMBOL = '__cervello-store__'\n\n\n\n\ntype CervelloStoreUseParam<StoreName extends string, StoreType> = {\n [k in StoreName]: StoreType\n} & {\n $onChange: (cb: (store: StoreType) => void) => void\n $onPartialChange: <\n Attributes extends Array<keyof StoreType>\n > (selectors: Attributes, cb: (store: StoreType) => void) => void\n}\n\n\nexport type CervelloUseFunction<StoreName extends string, StoreType> = (param: CervelloStoreUseParam<StoreName, StoreType>) => void\n\n\ntype CervelloStore<StoreName extends string, StoreType> = {\n [k in StoreName]: StoreType\n} & {\n useStore: () => StoreType\n useSelect: <Attributes extends Array<keyof StoreType>>(...selectors: Attributes) => ObjectFromAttributes<StoreType, Attributes>\n use: (...functions: Array<(useObj: CervelloStoreUseParam<StoreName, StoreType>) => void>) => CervelloStore<StoreName, StoreType>\n}\n\n\n\n\nexport function cervello <\n StoreName extends string,\n T\n> (storeName: StoreName, initialValue: T): CervelloStore<StoreName, T> {\n // Unique symbol to be used to keep a reference of the BehaviourSubject\n // const storeSymbol = Symbol(STORE_SYMBOL)\n\n\n const store$$ = new BehaviorSubject<T>(initialValue)\n\n const proxiedStore = proxifyStore(store$$, { ...initialValue })\n\n const cervelloStore = {\n [storeName]: proxiedStore,\n\n // TO BE SEPARATED IN cervello/react package ---------------------\n useStore: createUseStore<T>(store$$),\n useSelect: createUseSelect<T>(store$$),\n // ---------------------------------------------------------------\n\n use (...functionList: any) {\n functionList.forEach((func: any) => {\n func({\n [storeName]: proxiedStore,\n $onChange (cb: any) {\n store$$.pipe(\n pairwise(),\n switchMap(([oldValue, newValue]) => (oldValue !== newValue ? of(newValue) : NEVER)),\n ).subscribe((_) => cb(proxiedStore))\n },\n $onPartialChange (attrs: Array<keyof T>, cb: any) {\n store$$.pipe(\n pairwise(),\n switchMap(([oldValue, newValue]) => (oldValue !== newValue ? of(newValue) : NEVER)),\n distinctUntilChanged((prev, curr) => {\n let isEqual = true\n attrs.forEach((selector) => {\n if (typeof curr[selector] === 'object' && isEqual) {\n if (JSON.stringify(prev[selector]) !== JSON.stringify(curr[selector])) {\n isEqual = false\n }\n } else {\n if (prev[selector] !== curr[selector] && isEqual) {\n isEqual = false\n }\n }\n })\n return isEqual\n }),\n ).subscribe((_) => cb(proxiedStore))\n },\n })\n })\n return this\n },\n } as any\n\n\n\n return cervelloStore as CervelloStore<StoreName, T>\n}\n"],"names":["proxifyStore","store$$","storeObject","Error","Proxy","get","target","prop","currentStore","value","bind","Reflect","set","clonedStore","Object","assign","next","createUseStore","store","setStore","useState","isFirstTime","useRef","useEffect","subscription","pipe","observeOn","queueScheduler","subscribe","n","current","unsubscribe","getPartialObjectFromAttributes","attributes","reduce","acc","curr","createUseSelect","selectors","selectedStore","distinctUntilChanged","prev","isEqual","forEach","selector","JSON","stringify","partialStore","length","cervello","storeName","initialValue","BehaviorSubject","proxiedStore","_extends","useStore","useSelect","use","functionList","func","$onChange","cb","pairwise","switchMap","oldValue","newValue","of","NEVER","_","$onPartialChange","attrs","this"],"mappings":"obAIgBA,SAAAA,EAAuDC,EAA6BC,GAClG,GAA2B,iBAAhBA,EAA0B,MAAM,IAAAC,MAAU,2BAErD,WAAOC,MACLF,EACA,CACEG,IAAK,SAAUC,EAAWC,GACxB,MAAkBC,EAAGP,EAAQQ,MAE7B,OAAIF,OACgC,qBAAVA,KACFA,GAAMG,KAAKV,EAAaC,EAASO,IAGhDA,EAAaD,GAGRI,QAACN,IAAIC,EAAQC,IAE7BK,IAAK,SAAUN,EAAWC,EAAuBE,GAC/C,MAEMI,EAAcC,OAAOC,OAAO,GAFbd,EAAQQ,OAO7B,OAJAI,EAAYN,GAAQE,EAEpBR,EAAQe,KAAKH,GAENF,QAAQC,IAAIN,EAAQC,EAAME,MCtBnC,SAAAQ,EAA8BhB,GAClC,MAAO,KACL,MAAOiB,EAAOC,GAAYC,EAAYpB,EAAaC,EAASA,EAAQQ,QAC9DY,EAAcC,GAAO,GAgB3B,OAbAC,EAAU,KACR,MAAkBC,EAAGvB,EAAQwB,KAAKC,EAAUC,IAAiBC,UAAWC,IAClER,EAAYS,QACdT,EAAYS,SAAU,EAEtBX,EAASnB,EAAaC,EAAS4B,MAInC,MAAO,IAAML,EAAaO,eACzB,IAGIb,GClBK,SAAAc,EAAoCC,EAA4Bf,GAC9E,SAAkBgB,OAAY,CAACC,EAAKC,KAClCD,EAAIC,GAAQlB,EAAMkB,GACXD,GACN,IAIWE,SAAAA,EAAqBpC,GAEnC,MAAO,IAAuCqC,KAC5C,MAAOpB,EAAOC,GAAYC,EAAc,KACtC,MAAmBmB,EAAGP,EAA+BM,EAAWrC,EAAQQ,OACxE,OAAmBT,EAACC,EAASsC,KAEzBlB,EAAcC,GAAO,GAiC3B,OA9BAC,EAAU,KACR,MAAkBC,EAAGvB,EAAQwB,KAAKe,EAAqB,CAACC,EAAML,KAC5D,IAAIM,GAAU,EAad,OAZAJ,EAAUK,QAASC,IACa,iBAAnBR,EAAKQ,IAA0BF,EACpCG,KAAKC,UAAUL,EAAKG,MAAeC,KAAKC,UAAUV,EAAKQ,MACzDF,GAAU,GAGRD,EAAKG,KAAcR,EAAKQ,IAAaF,IACvCA,GAAU,KAMjBA,KAAGd,UAAWmB,IACb,GAAI1B,EAAYS,QACdT,EAAYS,SAAU,MACjB,CACL,MAAmBS,EAAGP,EAA+BM,EAAWS,GAChE5B,EAASnB,EAAaC,EAASsC,OAKnC,MAAO,IAAMf,EAAaO,eACzB,CAACO,EAAUU,YClBFC,SAAAA,EAGbC,EAAsBC,GAKvB,MAAalD,EAAG,IAAImD,EAAmBD,GAErBE,EAAGrD,EAAaC,EAADqD,EAAA,GAAeH,IAiDhD,MA/CsB,CACpBD,CAACA,GAAYG,EAGbE,SAAUtC,EAAkBhB,GAC5BuD,UAAWnB,EAAmBpC,GAG9BwD,OAAQC,GAiCN,OAhCAA,EAAaf,QAASgB,IACpBA,EAAK,CACHT,CAACA,GAAYG,EACbO,UAAWC,GACT5D,EAAQwB,KACNqC,IACAC,EAAU,EAAEC,EAAUC,KAAeD,IAAaC,EAAWC,EAAGD,GAAYE,IAC5EvC,UAAWwC,GAAMP,EAAGR,KAExBgB,iBAAkBC,EAAuBT,GACvC5D,EAAQwB,KACNqC,IACAC,EAAU,EAAEC,EAAUC,KAAeD,IAAaC,EAAWC,EAAGD,GAAYE,GAC5E3B,EAAqB,CAACC,EAAML,KAC1B,IAAIM,GAAU,EAYd,OAXA4B,EAAM3B,QAASC,IACiB,iBAAnBR,EAAKQ,IAA0BF,EACpCG,KAAKC,UAAUL,EAAKG,MAAeC,KAAKC,UAAUV,EAAKQ,MACzDF,GAAU,GAGRD,EAAKG,KAAcR,EAAKQ,IAAaF,IACvCA,GAAU,KAITA,KAETd,UAAWwC,GAAMP,EAAGR,SAK7BkB"}
1
+ {"version":3,"file":"cervello.modern.js","sources":["../src/lib/helpers/proxify-store.ts","../src/lib/utils/subscribe-for-react.ts","../src/lib/helpers/create-use-store.ts","../src/lib/helpers/create-use-selector.ts","../src/lib/store/index.ts"],"sourcesContent":["import type { BehaviorSubject } from 'rxjs'\n\n\n\nconst NESTED_ATTRIBUTES_SYMBOL = '___nested-attributes___'\nconst nestedAttrs = Symbol(NESTED_ATTRIBUTES_SYMBOL)\n\nexport function proxifyStore <T extends Record<string | symbol, any>> (store$$: BehaviorSubject<T>, storeObject: T): T {\n if (typeof storeObject !== 'object') throw new Error('Store must be an object')\n\n return new Proxy<T>(\n storeObject,\n {\n get: function (target: T, prop: string | symbol): any {\n const currentStore = target as any\n // console.log('get', { target, prop, in: prop in currentStore })\n\n // Problem with nested proxies because of currentStore is the root object\n if (prop in currentStore) {\n if (typeof currentStore[prop] === 'function') {\n return currentStore[prop].bind(proxifyStore(store$$, currentStore))\n }\n\n // console.log('------', prop, typeof currentStore[prop] === 'object', !Array.isArray(currentStore[prop]))\n // TODO: add pseudo identifier in order to return\n // TODO: the same object with a identifier of the level and the name of the property\n if (typeof currentStore[prop] === 'object' && !Array.isArray(currentStore[prop]) && typeof prop !== 'symbol') {\n // console.log('returning proxified object', prop)\n return proxifyStore(\n store$$,\n {\n ...currentStore[prop],\n [nestedAttrs]: `${(target?.[nestedAttrs]) ?? ''}${prop}`,\n })\n }\n\n return currentStore[prop]\n }\n\n return Reflect.get(target, prop)\n },\n set: function (target: T, prop: string | symbol, value: any) {\n // Write a merge deep nested objects function (as 'deepmerge lib')\n // console.log('set', { target, prop, value })\n const currentStore = store$$.getValue() as any\n\n const clonedStore = Object.assign({}, currentStore)\n clonedStore[prop] = value\n\n store$$.next(clonedStore)\n\n return Reflect.set(target, prop, value)\n },\n },\n )\n}\n","import type { BehaviorSubject } from 'rxjs'\n\n\n\nexport const subscribeForReactHook = <T>(store$$: BehaviorSubject<T>): typeof subscribe => {\n const subscribe = (onStoreChange: () => void): () => void => {\n const subscription = store$$.subscribe(onStoreChange)\n return () => {\n subscription.unsubscribe()\n }\n }\n return subscribe\n}\n","\nimport { useSyncExternalStore } from 'use-sync-external-store/shim'\n\nimport { subscribeForReactHook } from '../utils/subscribe-for-react'\nimport { proxifyStore } from './proxify-store'\n\nimport type { BehaviorSubject } from 'rxjs'\n\n\n\nexport function createUseStore <T> (store$$: BehaviorSubject<T>): () => T {\n const subscribe = subscribeForReactHook(store$$)\n const getValue = store$$.getValue.bind(store$$)\n\n\n // USE STORE HOOK -------------------------------------------------\n const useStore = (): T => {\n const store = useSyncExternalStore(subscribe, getValue, getValue)\n\n return proxifyStore(store$$, store)\n }\n\n\n return useStore\n}\n","\nimport { useSyncExternalStoreWithSelector } from 'use-sync-external-store/shim/with-selector'\n\n\nimport { subscribeForReactHook } from '../utils/subscribe-for-react'\nimport { proxifyStore } from './proxify-store'\n\nimport type { ObjectFromAttributes, WithoutType } from '../../types/shared'\nimport type { BehaviorSubject } from 'rxjs'\n\n\n\nexport function getPartialObjectFromAttributes <T> (attributes: Array<keyof T>, store: T): any {\n return attributes.reduce<any>((acc, curr) => {\n acc[curr] = store[curr]\n return acc\n }, {})\n}\n\nexport type UseSelector<T> = <Attributes extends Array< keyof WithoutType<T, Function> >>(\n selectors: Attributes,\n isEqualFunction?: (previousState: ObjectFromAttributes<T, Attributes>, currentState: ObjectFromAttributes<T, Attributes>) => boolean,\n ) => ObjectFromAttributes<T, Attributes>\n\nexport function createUseSelector <T> (store$$: BehaviorSubject<T>): UseSelector<T> {\n const subscribe = subscribeForReactHook(store$$)\n const getValue = store$$.getValue.bind(store$$)\n\n // const subscribeWithSelectors = (selectors: Array<keyof T>): (onStoreChange: () => void) => () => void => {\n // return (onStoreChange: () => void): (() => void) => {\n // const subscription = store$$.subscribe(onStoreChange)\n // // console.log('1- FUNCTION OF SUBSCRIBE')\n // // const subscription = store$$.pipe(distinctUntilChanged((prev, curr) => {\n // // let isEqual = true\n // // selectors.forEach((selector) => {\n // // if (typeof curr[selector] === 'object' && isEqual) {\n // // if (JSON.stringify(prev[selector]) !== JSON.stringify(curr[selector])) {\n // // isEqual = false\n // // }\n // // } else {\n // // if (prev[selector] !== curr[selector] && isEqual) {\n // // isEqual = false\n // // }\n // // }\n // // })\n // // console.log('1- FUNCTION OF distinctUntilChanged', { isEqual })\n\n // // return isEqual\n // // })).subscribe(onStoreChange)\n\n // return () => {\n // subscription.unsubscribe()\n // }\n // }\n // }\n\n\n\n\n // USE SELECTOR HOOK -------------------------------------------------\n const useSelector = <Attributes extends Array< keyof WithoutType<T, Function> >>(\n selectors: Attributes,\n isEqualFunction?: (previousState: ObjectFromAttributes<T, Attributes>, currentState: ObjectFromAttributes<T, Attributes>) => boolean,\n ): ObjectFromAttributes<T, Attributes> => {\n const store = useSyncExternalStoreWithSelector<T, ObjectFromAttributes<T, Attributes>>(\n subscribe,\n getValue,\n getValue,\n (store) => getPartialObjectFromAttributes(selectors, store),\n (prev, curr) => isEqualFunction\n ? isEqualFunction(prev, curr)\n : JSON.stringify(prev) === JSON.stringify(curr),\n\n )\n\n return proxifyStore(store$$ as any, store)\n }\n\n return useSelector\n}\n","import { BehaviorSubject, distinctUntilChanged, NEVER, of, pairwise, switchMap } from 'rxjs'\n\nimport { createUseSelector, createUseStore, proxifyStore } from '../helpers'\n\nimport type { WithoutType } from '../../types/shared'\nimport type { UseSelector } from '../helpers'\n\n\n\n// const STORE_SYMBOL = '__cervello-store__'\n\n\ninterface CervelloStoreUseParam<StoreType> {\n onChange: (cb: (store: StoreType) => void) => void\n onPartialChange: <\n Attributes extends Array< keyof WithoutType<StoreType, Function>>\n > (selectors: Attributes, cb: (store: StoreType) => void) => void\n}\n\n/**\n * Use function which allows you to listen for changes in the store.\n */\nexport type CervelloUseFunction<StoreType> = (param: CervelloStoreUseParam<StoreType>) => void\n\n\ninterface CervelloStore<StoreType> {\n /** Reactive store */\n store: StoreType\n /** Hook to react to all changes done to 'store' */\n useStore: () => StoreType\n /** Hook to react to changes done to 'store' in all the attributes provided */\n useSelector: UseSelector<StoreType>\n /** Functions to be attached to changes in a general way (tracking, loggers, ... etc) */\n use: (...functions: Array<(useObj: CervelloStoreUseParam<StoreType>) => void>) => CervelloStore<StoreType>\n}\n\n/**\n * @note Currently not working\n */\nexport interface CervelloOptions {\n persist?:\n | boolean\n // | {\n // getItem: (key: string) => any\n // }\n}\n\n\n/**\n * Creates a store that is reactive and can be used inside and outside of React components.\n * @param initialValue Object with the default values for the store\n *\n * @returns - { store, useStore, useSelector }\n */\nexport function cervello <T extends Record<any, unknown>> (initialValue: T, options?: CervelloOptions): CervelloStore<T>\n\n\n/**\n * Creates a store that is reactive and can be used inside and outside of React components.\n * @param initialValue Function which returns the default values for the store\n *\n * @returns - { store, useStore, useSelector }\n */\nexport function cervello <T> (initialValue: () => T, options?: CervelloOptions): CervelloStore<T>\n\n\n\n\n\n\n\n/** @internal */\nexport function cervello <T> (initialValue: T | (() => T), options?: CervelloOptions): CervelloStore<T> {\n const defaultValue = (typeof initialValue === 'function' ? (initialValue as any)() : initialValue) as T\n const store$$ = new BehaviorSubject<T>(defaultValue)\n\n const proxiedStore = proxifyStore<T>(store$$, { ...defaultValue })\n\n const cervelloStore = {\n store: proxiedStore,\n\n // TO BE SEPARATED IN cervello/react package ---------------------\n useStore: createUseStore<T>(store$$),\n useSelector: createUseSelector<T>(store$$),\n // ---------------------------------------------------------------\n\n use (...functionList: any) {\n functionList.forEach((func: any) => {\n func({\n onChange (cb: any) {\n store$$.pipe(\n pairwise(),\n switchMap(([oldValue, newValue]) => (oldValue !== newValue ? of(newValue) : NEVER)),\n ).subscribe((_) => cb(proxiedStore))\n },\n onPartialChange (attrs: Array<keyof T>, cb: any) {\n store$$.pipe(\n pairwise(),\n switchMap(([oldValue, newValue]) => (oldValue !== newValue ? of(newValue) : NEVER)),\n distinctUntilChanged((prev, curr) => {\n let isEqual = true\n attrs.forEach((selector) => {\n if (isEqual && typeof curr[selector] === 'object') {\n if (JSON.stringify(prev[selector]) !== JSON.stringify(curr[selector])) {\n isEqual = false\n }\n } else {\n if (isEqual && prev[selector] !== curr[selector]) {\n isEqual = false\n }\n }\n })\n return isEqual\n }),\n ).subscribe((_) => cb(proxiedStore))\n },\n })\n })\n return this\n },\n } as any\n\n\n\n return cervelloStore as CervelloStore<T>\n}\n"],"names":["nestedAttrs","Symbol","proxifyStore","store$$","storeObject","Error","Proxy","get","target","prop","currentStore","_target$nestedAttrs","bind","Array","isArray","_extends","Reflect","set","value","getValue","clonedStore","Object","assign","next","subscribeForReactHook","onStoreChange","subscription","subscribe","unsubscribe","createUseStore","store","useSyncExternalStore","createUseSelector","selectors","isEqualFunction","useSyncExternalStoreWithSelector","attributes","reduce","acc","curr","getPartialObjectFromAttributes","prev","JSON","stringify","cervello","initialValue","options","defaultValue","proxiedStore","useStore","useSelector","use","functionList","forEach","func","onChange","cb","pipe","pairwise","switchMap","oldValue","newValue","of","NEVER","_","onPartialChange","attrs","distinctUntilChanged","isEqual","selector","this"],"mappings":"ufAIA,MACiBA,EAAGC,OADa,2BAGjB,SAAAC,EAAuDC,EAA6BC,GAClG,GAA2B,iBAAvBA,EAAiC,UAAMC,MAAU,2BAErD,OAAO,IAAAC,MACLF,EACA,CACEG,IAAK,SAAUC,EAAWC,GACxB,MAAkBC,EAAGF,EAY2F,IAAAG,EARhH,OAAIF,KAAQC,EACwB,mBAAvBA,EAAaD,GACfC,EAAaD,GAAMG,KAAKV,EAAaC,EAASO,IAMrB,iBAAXA,EAACD,IAAuBI,MAAMC,QAAQJ,EAAaD,KAA0B,iBAAhBA,EAU7EC,EAAaD,GARCP,EACjBC,EADiBY,EAAA,CAAA,EAGZL,EAAaD,GAHD,CAIfT,CAACA,GAAc,YAAA,MAAIQ,OAAJ,EAAIA,EAASR,MAAiB,KAAKS,OAO5CO,QAACT,IAAIC,EAAQC,EAC5B,EACDQ,IAAK,SAAUT,EAAWC,EAAuBS,GAG/C,MAAMR,EAAeP,EAAQgB,WAEZC,EAAGC,OAAOC,OAAO,CAAA,EAAIZ,GAKtC,OAJAU,EAAYX,GAAQS,EAEpBf,EAAQoB,KAAKH,WAEEH,IAAIT,EAAQC,EAAMS,EAClC,GAGN,CCnDYM,MAAAA,EAA4BrB,GACpBsB,IACjB,MAAMC,EAAevB,EAAQwB,UAAUF,GACvC,MAAO,KACLC,EAAaE,cACd,ECCC,SAAAC,EAA8B1B,GAClC,QAAkBqB,EAAsBrB,GAClCgB,EAAWhB,EAAQgB,SAASP,KAAKT,GAWvC,MAPiB,KACf,MAAW2B,EAAGC,EAAqBJ,EAAWR,EAAUA,GAExD,OAAmBjB,EAACC,EAAS2B,EAAV,CAKtB,CCAK,SAAAE,EAAiC7B,GACrC,QAAkBqB,EAAsBrB,GAC1BgB,EAAGhB,EAAQgB,SAASP,KAAKT,GAoDvC,MAlBoB,CAClB8B,EACAC,KAEA,MAAWJ,EAAGK,EACZR,EACAR,EACAA,EACCW,GAxDS,SAAoCM,EAA4BN,GAC9E,OAAOM,EAAWC,OAAY,CAACC,EAAKC,KAClCD,EAAIC,GAAQT,EAAMS,GACXD,GACN,CAAA,EACJ,CAmDgBE,CAA+BP,EAAWH,GACrD,CAACW,EAAMF,IAASL,EACZA,EAAgBO,EAAMF,GACtBG,KAAKC,UAAUF,KAAUC,KAAKC,UAAUJ,IAI9C,OAAOrC,EAAaC,EAAgB2B,EAAjB,CAItB,CCPe,SAAAc,EAAcC,EAA6BC,GACzD,MAAMC,EAAwC,mBAAxBF,EAAsCA,IAAyBA,EAC/E1C,EAAU,MAAuB4C,GAEjCC,EAAe9C,EAAgBC,EAAJY,EAAA,CAAA,EAAkBgC,IAgDnD,MA9CsB,CACpBjB,MAAOkB,EAGPC,SAAUpB,EAAkB1B,GAC5B+C,YAAalB,EAAqB7B,GAGlCgD,OAAQC,GAgCN,OA/BAA,EAAaC,QAASC,IACpBA,EAAK,CACHC,SAAUC,GACRrD,EAAQsD,KACNC,IACAC,EAAU,EAAEC,EAAUC,KAAeD,IAAaC,EAAWC,EAAGD,GAAYE,IAC5EpC,UAAWqC,GAAMR,EAAGR,GACvB,EACDiB,gBAAiBC,EAAuBV,GACtCrD,EAAQsD,KACNC,IACAC,EAAU,EAAEC,EAAUC,KAAeD,IAAaC,EAAWC,EAAGD,GAAYE,GAC5EI,EAAqB,CAAC1B,EAAMF,KAC1B,IAAW6B,GAAG,EAYd,OAXAF,EAAMb,QAASgB,IACTD,GAAqC,iBAAnB7B,EAAK8B,GACrB3B,KAAKC,UAAUF,EAAK4B,MAAe3B,KAAKC,UAAUJ,EAAK8B,MACzDD,GAAU,GAGRA,GAAW3B,EAAK4B,KAAc9B,EAAK8B,KACrCD,GAAU,EAEb,GAGJA,KACDzC,UAAWqC,GAAMR,EAAGR,GACvB,MAINsB,IAAA,EAMJ"}
@@ -1,2 +1,2 @@
1
- !function(e,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports,require("rxjs"),require("react")):"function"==typeof define&&define.amd?define(["exports","rxjs","react"],n):n((e||self).react={},e.rxjs,e.react)}(this,function(e,n,t){function r(){return r=Object.assign?Object.assign.bind():function(e){for(var n=1;n<arguments.length;n++){var t=arguments[n];for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(e[r]=t[r])}return e},r.apply(this,arguments)}function u(e,n){if("object"!=typeof n)throw new Error("Store must be an object");return new Proxy(n,{get:function(n,t){var r=e.value;return t in r?"function"==typeof r[t]?r[t].bind(u(e,r)):r[t]:Reflect.get(n,t)},set:function(n,t,r){var u=Object.assign({},e.value);return u[t]=r,e.next(u),Reflect.set(n,t,r)}})}function i(e,n){return e.reduce(function(e,t){return e[t]=n[t],e},{})}e.cervello=function(e,c){var o,f=new n.BehaviorSubject(c),s=u(f,r({},c)),a=((o={})[e]=s,o.useStore=function(e){return function(){var r=t.useState(u(e,e.value)),i=r[0],c=r[1],o=t.useRef(!0);return t.useEffect(function(){var t=e.pipe(n.observeOn(n.queueScheduler)).subscribe(function(n){o.current?o.current=!1:c(u(e,n))});return function(){return t.unsubscribe()}},[]),i}}(f),o.useSelect=function(e){return function(){var r=[].slice.call(arguments),c=t.useState(function(){var n=i(r,e.value);return u(e,n)}),o=c[0],f=c[1],s=t.useRef(!0);return t.useEffect(function(){var t=e.pipe(n.distinctUntilChanged(function(e,n){var t=!0;return r.forEach(function(r){"object"==typeof n[r]&&t?JSON.stringify(e[r])!==JSON.stringify(n[r])&&(t=!1):e[r]!==n[r]&&t&&(t=!1)}),t})).subscribe(function(n){if(s.current)s.current=!1;else{var t=i(r,n);f(u(e,t))}});return function(){return t.unsubscribe()}},[r.length]),o}}(f),o.use=function(){return[].slice.call(arguments).forEach(function(t){var r;t(((r={})[e]=s,r.$onChange=function(e){f.pipe(n.pairwise(),n.switchMap(function(e){var t=e[1];return e[0]!==t?n.of(t):n.NEVER})).subscribe(function(n){return e(s)})},r.$onPartialChange=function(e,t){f.pipe(n.pairwise(),n.switchMap(function(e){var t=e[1];return e[0]!==t?n.of(t):n.NEVER}),n.distinctUntilChanged(function(n,t){var r=!0;return e.forEach(function(e){"object"==typeof t[e]&&r?JSON.stringify(n[e])!==JSON.stringify(t[e])&&(r=!1):n[e]!==t[e]&&r&&(r=!1)}),r})).subscribe(function(e){return t(s)})},r))}),this},o);return a}});
1
+ !function(e,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports,require("rxjs"),require("use-sync-external-store/shim"),require("use-sync-external-store/shim/with-selector")):"function"==typeof define&&define.amd?define(["exports","rxjs","use-sync-external-store/shim","use-sync-external-store/shim/with-selector"],n):n((e||self).react={},e.rxjs,e.shim,e.withSelector)}(this,function(e,n,t,r){function i(){return i=Object.assign?Object.assign.bind():function(e){for(var n=1;n<arguments.length;n++){var t=arguments[n];for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(e[r]=t[r])}return e},i.apply(this,arguments)}var o=Symbol("___nested-attributes___");function u(e,n){if("object"!=typeof n)throw new Error("Store must be an object");return new Proxy(n,{get:function(n,t){var r,c,s=n;return t in s?"function"==typeof s[t]?s[t].bind(u(e,s)):"object"!=typeof s[t]||Array.isArray(s[t])||"symbol"==typeof t?s[t]:u(e,i({},s[t],((c={})[o]=""+(null!=(r=null==n?void 0:n[o])?r:"")+t,c))):Reflect.get(n,t)},set:function(n,t,r){var i=e.getValue(),o=Object.assign({},i);return o[t]=r,e.next(o),Reflect.set(n,t,r)}})}var c=function(e){return function(n){var t=e.subscribe(n);return function(){t.unsubscribe()}}};function s(e){var n=c(e),r=e.getValue.bind(e);return function(){var i=t.useSyncExternalStore(n,r,r);return u(e,i)}}function f(e){var n=c(e),t=e.getValue.bind(e);return function(i,o){var c=r.useSyncExternalStoreWithSelector(n,t,t,function(e){return function(e,n){return e.reduce(function(e,t){return e[t]=n[t],e},{})}(i,e)},function(e,n){return o?o(e,n):JSON.stringify(e)===JSON.stringify(n)});return u(e,c)}}e.cervello=function(e,t){var r="function"==typeof e?e():e,o=new n.BehaviorSubject(r),c=u(o,i({},r)),a={store:c,useStore:s(o),useSelector:f(o),use:function(){return[].slice.call(arguments).forEach(function(e){e({onChange:function(e){o.pipe(n.pairwise(),n.switchMap(function(e){var t=e[1];return e[0]!==t?n.of(t):n.NEVER})).subscribe(function(n){return e(c)})},onPartialChange:function(e,t){o.pipe(n.pairwise(),n.switchMap(function(e){var t=e[1];return e[0]!==t?n.of(t):n.NEVER}),n.distinctUntilChanged(function(n,t){var r=!0;return e.forEach(function(e){r&&"object"==typeof t[e]?JSON.stringify(n[e])!==JSON.stringify(t[e])&&(r=!1):r&&n[e]!==t[e]&&(r=!1)}),r})).subscribe(function(e){return t(c)})}})}),this}};return a}});
2
2
  //# sourceMappingURL=cervello.umd.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"cervello.umd.js","sources":["../src/lib/helpers/proxify-store.ts","../src/lib/helpers/create-use-select.ts","../src/lib/store/index.ts","../src/lib/helpers/create-use-store.ts"],"sourcesContent":["import type { BehaviorSubject } from 'rxjs'\n\n\n\nexport function proxifyStore <T extends Record<string | symbol, any>> (store$$: BehaviorSubject<T>, storeObject: T): T {\n if (typeof storeObject !== 'object') throw new Error('Store must be an object')\n\n return new Proxy<T>(\n storeObject,\n {\n get: function (target: T, prop: string | symbol): any {\n const currentStore = store$$.value as any\n\n if (prop in currentStore) {\n if (typeof currentStore[prop] === 'function') {\n return currentStore[prop].bind(proxifyStore(store$$, currentStore))\n }\n\n return currentStore[prop]\n }\n\n return Reflect.get(target, prop)\n },\n set: function (target: T, prop: string | symbol, value: any) {\n const currentStore = store$$.value as any\n\n const clonedStore = Object.assign({}, currentStore)\n clonedStore[prop] = value\n\n store$$.next(clonedStore)\n\n return Reflect.set(target, prop, value)\n },\n },\n )\n}\n","import { useEffect, useRef, useState } from 'react'\nimport { distinctUntilChanged } from 'rxjs'\n\nimport { proxifyStore } from './proxify-store'\n\nimport type { ObjectFromAttributes } from '../../types/shared'\nimport type { BehaviorSubject } from 'rxjs'\n\n\n\nexport function getPartialObjectFromAttributes <T> (attributes: Array<keyof T>, store: T): any {\n return attributes.reduce<any>((acc, curr) => {\n acc[curr] = store[curr]\n return acc\n }, {})\n}\n\n\nexport function createUseSelect <T> (store$$: BehaviorSubject<T>) {\n //\n return <Attributes extends Array<keyof T>>(...selectors: Attributes): ObjectFromAttributes<T, Attributes> => {\n const [store, setStore] = useState<any>(() => {\n const selectedStore = getPartialObjectFromAttributes(selectors, store$$.value)\n return proxifyStore(store$$, selectedStore)\n })\n const isFirstTime = useRef(true)\n\n\n useEffect(() => {\n const subscription = store$$.pipe(distinctUntilChanged((prev, curr) => {\n let isEqual = true\n selectors.forEach((selector) => {\n if (typeof curr[selector] === 'object' && isEqual) {\n if (JSON.stringify(prev[selector]) !== JSON.stringify(curr[selector])) {\n isEqual = false\n }\n } else {\n if (prev[selector] !== curr[selector] && isEqual) {\n isEqual = false\n }\n }\n })\n\n return isEqual\n })).subscribe((partialStore) => {\n if (isFirstTime.current) {\n isFirstTime.current = false\n } else {\n const selectedStore = getPartialObjectFromAttributes(selectors, partialStore)\n setStore(proxifyStore(store$$, selectedStore))\n }\n })\n\n\n return () => subscription.unsubscribe()\n }, [selectors.length])\n\n\n return store\n }\n}\n","import { BehaviorSubject, distinctUntilChanged, NEVER, of, pairwise, switchMap } from 'rxjs'\n\nimport { createUseSelect, createUseStore, proxifyStore } from '../helpers'\n\nimport type { ObjectFromAttributes } from '../../types/shared'\n\n\n\n// const STORE_SYMBOL = '__cervello-store__'\n\n\n\n\ntype CervelloStoreUseParam<StoreName extends string, StoreType> = {\n [k in StoreName]: StoreType\n} & {\n $onChange: (cb: (store: StoreType) => void) => void\n $onPartialChange: <\n Attributes extends Array<keyof StoreType>\n > (selectors: Attributes, cb: (store: StoreType) => void) => void\n}\n\n\nexport type CervelloUseFunction<StoreName extends string, StoreType> = (param: CervelloStoreUseParam<StoreName, StoreType>) => void\n\n\ntype CervelloStore<StoreName extends string, StoreType> = {\n [k in StoreName]: StoreType\n} & {\n useStore: () => StoreType\n useSelect: <Attributes extends Array<keyof StoreType>>(...selectors: Attributes) => ObjectFromAttributes<StoreType, Attributes>\n use: (...functions: Array<(useObj: CervelloStoreUseParam<StoreName, StoreType>) => void>) => CervelloStore<StoreName, StoreType>\n}\n\n\n\n\nexport function cervello <\n StoreName extends string,\n T\n> (storeName: StoreName, initialValue: T): CervelloStore<StoreName, T> {\n // Unique symbol to be used to keep a reference of the BehaviourSubject\n // const storeSymbol = Symbol(STORE_SYMBOL)\n\n\n const store$$ = new BehaviorSubject<T>(initialValue)\n\n const proxiedStore = proxifyStore(store$$, { ...initialValue })\n\n const cervelloStore = {\n [storeName]: proxiedStore,\n\n // TO BE SEPARATED IN cervello/react package ---------------------\n useStore: createUseStore<T>(store$$),\n useSelect: createUseSelect<T>(store$$),\n // ---------------------------------------------------------------\n\n use (...functionList: any) {\n functionList.forEach((func: any) => {\n func({\n [storeName]: proxiedStore,\n $onChange (cb: any) {\n store$$.pipe(\n pairwise(),\n switchMap(([oldValue, newValue]) => (oldValue !== newValue ? of(newValue) : NEVER)),\n ).subscribe((_) => cb(proxiedStore))\n },\n $onPartialChange (attrs: Array<keyof T>, cb: any) {\n store$$.pipe(\n pairwise(),\n switchMap(([oldValue, newValue]) => (oldValue !== newValue ? of(newValue) : NEVER)),\n distinctUntilChanged((prev, curr) => {\n let isEqual = true\n attrs.forEach((selector) => {\n if (typeof curr[selector] === 'object' && isEqual) {\n if (JSON.stringify(prev[selector]) !== JSON.stringify(curr[selector])) {\n isEqual = false\n }\n } else {\n if (prev[selector] !== curr[selector] && isEqual) {\n isEqual = false\n }\n }\n })\n return isEqual\n }),\n ).subscribe((_) => cb(proxiedStore))\n },\n })\n })\n return this\n },\n } as any\n\n\n\n return cervelloStore as CervelloStore<StoreName, T>\n}\n","import { useEffect, useRef, useState } from 'react'\nimport { observeOn, queueScheduler } from 'rxjs'\n\nimport { proxifyStore } from './proxify-store'\n\nimport type { BehaviorSubject } from 'rxjs'\n\n\n\nexport function createUseStore <T> (store$$: BehaviorSubject<T>): () => T {\n return () => {\n const [store, setStore] = useState<T>(proxifyStore(store$$, store$$.value))\n const isFirstTime = useRef(true)\n\n // TODO: Use new useSyncExternalStore API hook\n useEffect(() => {\n const subscription = store$$.pipe(observeOn(queueScheduler)).subscribe((n) => {\n if (isFirstTime.current) {\n isFirstTime.current = false\n } else {\n setStore(proxifyStore(store$$, n))\n }\n })\n\n return () => subscription.unsubscribe()\n }, [])\n\n\n return store\n }\n}\n"],"names":["proxifyStore","store$$","storeObject","Error","Proxy","get","target","prop","currentStore","value","bind","Reflect","set","clonedStore","Object","assign","next","getPartialObjectFromAttributes","attributes","store","reduce","acc","curr","storeName","initialValue","_cervelloStore","BehaviorSubject","proxiedStore","cervelloStore","useStore","_useState","useState","setStore","isFirstTime","useRef","useEffect","subscription","pipe","observeOn","queueScheduler","subscribe","n","current","unsubscribe","createUseStore","useSelect","createUseSelect","selectors","slice","call","arguments","selectedStore","distinctUntilChanged","prev","isEqual","forEach","selector","JSON","stringify","partialStore","length","use","func","_func","$onChange","cb","pairwise","switchMap","oldValue","newValue","of","NEVER","_","$onPartialChange","attrs","_ref2","this"],"mappings":"sgBAIgBA,SAAAA,EAAuDC,EAA6BC,GAClG,GAA2B,iBAAhBA,EAA0B,MAAM,IAAAC,MAAU,2BAErD,WAAOC,MACLF,EACA,CACEG,IAAK,SAAUC,EAAWC,GACxB,IAAkBC,EAAGP,EAAQQ,MAE7B,OAAIF,OACgC,qBAAVA,KACFA,GAAMG,KAAKV,EAAaC,EAASO,IAGhDA,EAAaD,GAGRI,QAACN,IAAIC,EAAQC,IAE7BK,IAAK,SAAUN,EAAWC,EAAuBE,GAC/C,IAEMI,EAAcC,OAAOC,OAAO,GAFbd,EAAQQ,OAO7B,OAJAI,EAAYN,GAAQE,EAEpBR,EAAQe,KAAKH,GAENF,QAAQC,IAAIN,EAAQC,EAAME,MCrBzB,SAAAQ,EAAoCC,EAA4BC,GAC9E,SAAkBC,OAAY,SAACC,EAAKC,GAElC,OADAD,EAAIC,GAAQH,EAAMG,GACXD,GACN,eCuBW,SAGbE,EAAsBC,GAAe,IAAAC,EAKhCxB,EAAU,IAAAyB,EAAAA,gBAAuBF,GAErBG,EAAG3B,EAAaC,EAAcuB,EAAAA,GAAAA,IAE1CI,IACHL,EAAAA,IAAAA,GAAYI,EADIF,EAIjBI,SC5CE,SAA8B5B,GAClC,kBACE,IAAA6B,EAA0BC,EAAAA,SAAY/B,EAAaC,EAASA,EAAQQ,QAA7DU,EAAPW,EAAA,GAAcE,EAAdF,EAAA,GACMG,EAAcC,UAAO,GAgB3B,OAbAC,EAASA,UAAC,WACR,IAAkBC,EAAGnC,EAAQoC,KAAKC,EAASA,UAACC,EAADA,iBAAkBC,UAAU,SAACC,GAClER,EAAYS,QACdT,EAAYS,SAAU,EAEtBV,EAAShC,EAAaC,EAASwC,MAInC,OAAO,WAAA,OAAkBL,EAACO,gBACzB,IAGIxB,GDyBGyB,CAAkB3C,KAC5B4C,UDpCYC,SAAqB7C,GAEnC,OAA4G,WAAA,IAAA8C,EAAA,GAAAC,MAAAC,KAAAC,WAChFnB,EAAAA,EAAQA,SAAM,WACtC,IAAmBoB,EAAGlC,EAA+B8B,EAAW9C,EAAQQ,OACxE,OAAmBT,EAACC,EAASkD,KAFxBhC,OAAOa,EAAdF,EAAA,GAIMG,EAAcC,EAAMA,QAAC,GAiC3B,OA9BAC,EAAAA,UAAU,WACR,IAAMC,EAAenC,EAAQoC,KAAKe,EAAAA,qBAAqB,SAACC,EAAM/B,GAC5D,IAAIgC,GAAU,EAad,OAZAP,EAAUQ,QAAQ,SAACC,GACa,iBAAflC,EAACkC,IAA0BF,EACpCG,KAAKC,UAAUL,EAAKG,MAAeC,KAAKC,UAAUpC,EAAKkC,MACzDF,GAAU,GAGRD,EAAKG,KAAclC,EAAKkC,IAAaF,IACvCA,GAAU,KAKTA,KACLd,UAAU,SAACmB,GACb,GAAI1B,EAAYS,QACdT,EAAYS,SAAU,MACjB,CACL,IAAMS,EAAgBlC,EAA+B8B,EAAWY,GAChE3B,EAAShC,EAAaC,EAASkD,OAKnC,OAAaf,WAAAA,OAAAA,EAAaO,gBACzB,CAACI,EAAUa,YCDHd,CAAmB7C,GAG9B4D,EAAAA,IAAyB,WAiCvB,MAhCA,GAAaN,MAAAA,KAAAA,WAAAA,QAAQ,SAACO,SACpBA,IAAIC,EAAA,IACDxC,GAAYI,EADXoC,EAEFC,UAFE,SAESC,GACThE,EAAQoC,KACN6B,aACAC,YAAU,SAAEC,GAAAA,IAAUC,EAAeD,EAAAA,GAAAA,OAAfC,EAAAA,KAA4BA,EAAWC,EAAEA,GAACD,GAAYE,EAAlEA,SACV/B,UAAU,SAACgC,GAAD,SAAU7C,MAExB8C,EAAAA,0BAAkBC,EAAuBT,GACvChE,EAAQoC,KACN6B,EAAAA,WACAC,EAAAA,UAAU,SAAEC,GAAAA,IAAUC,EAAZM,EAAA,GAAA,cAAwCN,EAAWC,EAAEA,GAACD,GAAYE,UAC5EnB,EAAAA,qBAAqB,SAACC,EAAM/B,GAC1B,IAAWgC,GAAG,EAYd,OAXAoB,EAAMnB,QAAQ,SAACC,GACiB,iBAAnBlC,EAAKkC,IAA0BF,EACpCG,KAAKC,UAAUL,EAAKG,MAAeC,KAAKC,UAAUpC,EAAKkC,MACzDF,GAAU,GAGRD,EAAKG,KAAclC,EAAKkC,IAAaF,IACvCA,GAAU,KAKjBA,KACDd,UAAU,SAACgC,GAAD,OAASP,EAACtC,MAG3BoC,MAEFa,MA1CHnD,GA+CA,OACDG"}
1
+ {"version":3,"file":"cervello.umd.js","sources":["../src/lib/helpers/proxify-store.ts","../src/lib/utils/subscribe-for-react.ts","../src/lib/helpers/create-use-store.ts","../src/lib/helpers/create-use-selector.ts","../src/lib/store/index.ts"],"sourcesContent":["import type { BehaviorSubject } from 'rxjs'\n\n\n\nconst NESTED_ATTRIBUTES_SYMBOL = '___nested-attributes___'\nconst nestedAttrs = Symbol(NESTED_ATTRIBUTES_SYMBOL)\n\nexport function proxifyStore <T extends Record<string | symbol, any>> (store$$: BehaviorSubject<T>, storeObject: T): T {\n if (typeof storeObject !== 'object') throw new Error('Store must be an object')\n\n return new Proxy<T>(\n storeObject,\n {\n get: function (target: T, prop: string | symbol): any {\n const currentStore = target as any\n // console.log('get', { target, prop, in: prop in currentStore })\n\n // Problem with nested proxies because of currentStore is the root object\n if (prop in currentStore) {\n if (typeof currentStore[prop] === 'function') {\n return currentStore[prop].bind(proxifyStore(store$$, currentStore))\n }\n\n // console.log('------', prop, typeof currentStore[prop] === 'object', !Array.isArray(currentStore[prop]))\n // TODO: add pseudo identifier in order to return\n // TODO: the same object with a identifier of the level and the name of the property\n if (typeof currentStore[prop] === 'object' && !Array.isArray(currentStore[prop]) && typeof prop !== 'symbol') {\n // console.log('returning proxified object', prop)\n return proxifyStore(\n store$$,\n {\n ...currentStore[prop],\n [nestedAttrs]: `${(target?.[nestedAttrs]) ?? ''}${prop}`,\n })\n }\n\n return currentStore[prop]\n }\n\n return Reflect.get(target, prop)\n },\n set: function (target: T, prop: string | symbol, value: any) {\n // Write a merge deep nested objects function (as 'deepmerge lib')\n // console.log('set', { target, prop, value })\n const currentStore = store$$.getValue() as any\n\n const clonedStore = Object.assign({}, currentStore)\n clonedStore[prop] = value\n\n store$$.next(clonedStore)\n\n return Reflect.set(target, prop, value)\n },\n },\n )\n}\n","import type { BehaviorSubject } from 'rxjs'\n\n\n\nexport const subscribeForReactHook = <T>(store$$: BehaviorSubject<T>): typeof subscribe => {\n const subscribe = (onStoreChange: () => void): () => void => {\n const subscription = store$$.subscribe(onStoreChange)\n return () => {\n subscription.unsubscribe()\n }\n }\n return subscribe\n}\n","\nimport { useSyncExternalStore } from 'use-sync-external-store/shim'\n\nimport { subscribeForReactHook } from '../utils/subscribe-for-react'\nimport { proxifyStore } from './proxify-store'\n\nimport type { BehaviorSubject } from 'rxjs'\n\n\n\nexport function createUseStore <T> (store$$: BehaviorSubject<T>): () => T {\n const subscribe = subscribeForReactHook(store$$)\n const getValue = store$$.getValue.bind(store$$)\n\n\n // USE STORE HOOK -------------------------------------------------\n const useStore = (): T => {\n const store = useSyncExternalStore(subscribe, getValue, getValue)\n\n return proxifyStore(store$$, store)\n }\n\n\n return useStore\n}\n","\nimport { useSyncExternalStoreWithSelector } from 'use-sync-external-store/shim/with-selector'\n\n\nimport { subscribeForReactHook } from '../utils/subscribe-for-react'\nimport { proxifyStore } from './proxify-store'\n\nimport type { ObjectFromAttributes, WithoutType } from '../../types/shared'\nimport type { BehaviorSubject } from 'rxjs'\n\n\n\nexport function getPartialObjectFromAttributes <T> (attributes: Array<keyof T>, store: T): any {\n return attributes.reduce<any>((acc, curr) => {\n acc[curr] = store[curr]\n return acc\n }, {})\n}\n\nexport type UseSelector<T> = <Attributes extends Array< keyof WithoutType<T, Function> >>(\n selectors: Attributes,\n isEqualFunction?: (previousState: ObjectFromAttributes<T, Attributes>, currentState: ObjectFromAttributes<T, Attributes>) => boolean,\n ) => ObjectFromAttributes<T, Attributes>\n\nexport function createUseSelector <T> (store$$: BehaviorSubject<T>): UseSelector<T> {\n const subscribe = subscribeForReactHook(store$$)\n const getValue = store$$.getValue.bind(store$$)\n\n // const subscribeWithSelectors = (selectors: Array<keyof T>): (onStoreChange: () => void) => () => void => {\n // return (onStoreChange: () => void): (() => void) => {\n // const subscription = store$$.subscribe(onStoreChange)\n // // console.log('1- FUNCTION OF SUBSCRIBE')\n // // const subscription = store$$.pipe(distinctUntilChanged((prev, curr) => {\n // // let isEqual = true\n // // selectors.forEach((selector) => {\n // // if (typeof curr[selector] === 'object' && isEqual) {\n // // if (JSON.stringify(prev[selector]) !== JSON.stringify(curr[selector])) {\n // // isEqual = false\n // // }\n // // } else {\n // // if (prev[selector] !== curr[selector] && isEqual) {\n // // isEqual = false\n // // }\n // // }\n // // })\n // // console.log('1- FUNCTION OF distinctUntilChanged', { isEqual })\n\n // // return isEqual\n // // })).subscribe(onStoreChange)\n\n // return () => {\n // subscription.unsubscribe()\n // }\n // }\n // }\n\n\n\n\n // USE SELECTOR HOOK -------------------------------------------------\n const useSelector = <Attributes extends Array< keyof WithoutType<T, Function> >>(\n selectors: Attributes,\n isEqualFunction?: (previousState: ObjectFromAttributes<T, Attributes>, currentState: ObjectFromAttributes<T, Attributes>) => boolean,\n ): ObjectFromAttributes<T, Attributes> => {\n const store = useSyncExternalStoreWithSelector<T, ObjectFromAttributes<T, Attributes>>(\n subscribe,\n getValue,\n getValue,\n (store) => getPartialObjectFromAttributes(selectors, store),\n (prev, curr) => isEqualFunction\n ? isEqualFunction(prev, curr)\n : JSON.stringify(prev) === JSON.stringify(curr),\n\n )\n\n return proxifyStore(store$$ as any, store)\n }\n\n return useSelector\n}\n","import { BehaviorSubject, distinctUntilChanged, NEVER, of, pairwise, switchMap } from 'rxjs'\n\nimport { createUseSelector, createUseStore, proxifyStore } from '../helpers'\n\nimport type { WithoutType } from '../../types/shared'\nimport type { UseSelector } from '../helpers'\n\n\n\n// const STORE_SYMBOL = '__cervello-store__'\n\n\ninterface CervelloStoreUseParam<StoreType> {\n onChange: (cb: (store: StoreType) => void) => void\n onPartialChange: <\n Attributes extends Array< keyof WithoutType<StoreType, Function>>\n > (selectors: Attributes, cb: (store: StoreType) => void) => void\n}\n\n/**\n * Use function which allows you to listen for changes in the store.\n */\nexport type CervelloUseFunction<StoreType> = (param: CervelloStoreUseParam<StoreType>) => void\n\n\ninterface CervelloStore<StoreType> {\n /** Reactive store */\n store: StoreType\n /** Hook to react to all changes done to 'store' */\n useStore: () => StoreType\n /** Hook to react to changes done to 'store' in all the attributes provided */\n useSelector: UseSelector<StoreType>\n /** Functions to be attached to changes in a general way (tracking, loggers, ... etc) */\n use: (...functions: Array<(useObj: CervelloStoreUseParam<StoreType>) => void>) => CervelloStore<StoreType>\n}\n\n/**\n * @note Currently not working\n */\nexport interface CervelloOptions {\n persist?:\n | boolean\n // | {\n // getItem: (key: string) => any\n // }\n}\n\n\n/**\n * Creates a store that is reactive and can be used inside and outside of React components.\n * @param initialValue Object with the default values for the store\n *\n * @returns - { store, useStore, useSelector }\n */\nexport function cervello <T extends Record<any, unknown>> (initialValue: T, options?: CervelloOptions): CervelloStore<T>\n\n\n/**\n * Creates a store that is reactive and can be used inside and outside of React components.\n * @param initialValue Function which returns the default values for the store\n *\n * @returns - { store, useStore, useSelector }\n */\nexport function cervello <T> (initialValue: () => T, options?: CervelloOptions): CervelloStore<T>\n\n\n\n\n\n\n\n/** @internal */\nexport function cervello <T> (initialValue: T | (() => T), options?: CervelloOptions): CervelloStore<T> {\n const defaultValue = (typeof initialValue === 'function' ? (initialValue as any)() : initialValue) as T\n const store$$ = new BehaviorSubject<T>(defaultValue)\n\n const proxiedStore = proxifyStore<T>(store$$, { ...defaultValue })\n\n const cervelloStore = {\n store: proxiedStore,\n\n // TO BE SEPARATED IN cervello/react package ---------------------\n useStore: createUseStore<T>(store$$),\n useSelector: createUseSelector<T>(store$$),\n // ---------------------------------------------------------------\n\n use (...functionList: any) {\n functionList.forEach((func: any) => {\n func({\n onChange (cb: any) {\n store$$.pipe(\n pairwise(),\n switchMap(([oldValue, newValue]) => (oldValue !== newValue ? of(newValue) : NEVER)),\n ).subscribe((_) => cb(proxiedStore))\n },\n onPartialChange (attrs: Array<keyof T>, cb: any) {\n store$$.pipe(\n pairwise(),\n switchMap(([oldValue, newValue]) => (oldValue !== newValue ? of(newValue) : NEVER)),\n distinctUntilChanged((prev, curr) => {\n let isEqual = true\n attrs.forEach((selector) => {\n if (isEqual && typeof curr[selector] === 'object') {\n if (JSON.stringify(prev[selector]) !== JSON.stringify(curr[selector])) {\n isEqual = false\n }\n } else {\n if (isEqual && prev[selector] !== curr[selector]) {\n isEqual = false\n }\n }\n })\n return isEqual\n }),\n ).subscribe((_) => cb(proxiedStore))\n },\n })\n })\n return this\n },\n } as any\n\n\n\n return cervelloStore as CervelloStore<T>\n}\n"],"names":["nestedAttrs","Symbol","store$$","storeObject","Error","Proxy","get","target","prop","_target$nestedAttrs","_extends2","currentStore","bind","proxifyStore","Array","isArray","_extends","set","value","getValue","clonedStore","Object","assign","next","subscribeForReactHook","onStoreChange","subscription","subscribe","unsubscribe","createUseStore","store","useSyncExternalStore","createUseSelector","selectors","isEqualFunction","useSyncExternalStoreWithSelector","getPartialObjectFromAttributes","attributes","reduce","acc","curr","prev","JSON","stringify","initialValue","options","defaultValue","proxiedStore","cervelloStore","useStore","useSelector","use","slice","call","arguments","forEach","func","onChange","cb","pipe","pairwise","switchMap","oldValue","newValue","of","NEVER","_","onPartialChange","attrs","_ref2","distinctUntilChanged","isEqual","selector","this"],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@cervello/react",
3
- "version": "0.9.3",
4
- "description": "Simplest and truly reactive state manager for React",
3
+ "version": "0.9.6",
4
+ "description": "🤯 Simplest and truly reactive state manager for React",
5
5
  "main": "./dist/cervello.cjs",
6
6
  "module": "./dist/cervello.esm.js",
7
7
  "unpkg": "./dist/cervello.umd.js",
@@ -28,7 +28,8 @@
28
28
  "types"
29
29
  ],
30
30
  "scripts": {
31
- "build": "(rm -rf types & rm -rf dist) && microbundle",
31
+ "prepublish": "npm run build",
32
+ "build": "(rm -rf types & rm -rf dist) && microbundle --alias @observable-lib=../observable-lib/src/index.ts",
32
33
  "dev": "microbundle watch"
33
34
  },
34
35
  "repository": {
@@ -38,9 +39,9 @@
38
39
  "sideEffects": false,
39
40
  "keywords": [
40
41
  "state",
42
+ "react",
41
43
  "manager",
42
44
  "reactive",
43
- "react",
44
45
  "immutable",
45
46
  "observable",
46
47
  "global",
@@ -0,0 +1,5 @@
1
+ import type { ObjectFromAttributes, WithoutType } from '../../types/shared';
2
+ import type { BehaviorSubject } from 'rxjs';
3
+ export declare function getPartialObjectFromAttributes<T>(attributes: Array<keyof T>, store: T): any;
4
+ export declare type UseSelector<T> = <Attributes extends Array<keyof WithoutType<T, Function>>>(selectors: Attributes, isEqualFunction?: (previousState: ObjectFromAttributes<T, Attributes>, currentState: ObjectFromAttributes<T, Attributes>) => boolean) => ObjectFromAttributes<T, Attributes>;
5
+ export declare function createUseSelector<T>(store$$: BehaviorSubject<T>): UseSelector<T>;
@@ -1,3 +1,3 @@
1
1
  export * from './proxify-store';
2
2
  export * from './create-use-store';
3
- export * from './create-use-select';
3
+ export * from './create-use-selector';
@@ -1,17 +1,41 @@
1
- import type { ObjectFromAttributes } from '../../types/shared';
2
- declare type CervelloStoreUseParam<StoreName extends string, StoreType> = {
3
- [k in StoreName]: StoreType;
4
- } & {
5
- $onChange: (cb: (store: StoreType) => void) => void;
6
- $onPartialChange: <Attributes extends Array<keyof StoreType>>(selectors: Attributes, cb: (store: StoreType) => void) => void;
7
- };
8
- export declare type CervelloUseFunction<StoreName extends string, StoreType> = (param: CervelloStoreUseParam<StoreName, StoreType>) => void;
9
- declare type CervelloStore<StoreName extends string, StoreType> = {
10
- [k in StoreName]: StoreType;
11
- } & {
1
+ import type { WithoutType } from '../../types/shared';
2
+ import type { UseSelector } from '../helpers';
3
+ interface CervelloStoreUseParam<StoreType> {
4
+ onChange: (cb: (store: StoreType) => void) => void;
5
+ onPartialChange: <Attributes extends Array<keyof WithoutType<StoreType, Function>>>(selectors: Attributes, cb: (store: StoreType) => void) => void;
6
+ }
7
+ /**
8
+ * Use function which allows you to listen for changes in the store.
9
+ */
10
+ export declare type CervelloUseFunction<StoreType> = (param: CervelloStoreUseParam<StoreType>) => void;
11
+ interface CervelloStore<StoreType> {
12
+ /** Reactive store */
13
+ store: StoreType;
14
+ /** Hook to react to all changes done to 'store' */
12
15
  useStore: () => StoreType;
13
- useSelect: <Attributes extends Array<keyof StoreType>>(...selectors: Attributes) => ObjectFromAttributes<StoreType, Attributes>;
14
- use: (...functions: Array<(useObj: CervelloStoreUseParam<StoreName, StoreType>) => void>) => CervelloStore<StoreName, StoreType>;
15
- };
16
- export declare function cervello<StoreName extends string, T>(storeName: StoreName, initialValue: T): CervelloStore<StoreName, T>;
16
+ /** Hook to react to changes done to 'store' in all the attributes provided */
17
+ useSelector: UseSelector<StoreType>;
18
+ /** Functions to be attached to changes in a general way (tracking, loggers, ... etc) */
19
+ use: (...functions: Array<(useObj: CervelloStoreUseParam<StoreType>) => void>) => CervelloStore<StoreType>;
20
+ }
21
+ /**
22
+ * @note Currently not working
23
+ */
24
+ export interface CervelloOptions {
25
+ persist?: boolean;
26
+ }
27
+ /**
28
+ * Creates a store that is reactive and can be used inside and outside of React components.
29
+ * @param initialValue Object with the default values for the store
30
+ *
31
+ * @returns - { store, useStore, useSelector }
32
+ */
33
+ export declare function cervello<T extends Record<any, unknown>>(initialValue: T, options?: CervelloOptions): CervelloStore<T>;
34
+ /**
35
+ * Creates a store that is reactive and can be used inside and outside of React components.
36
+ * @param initialValue Function which returns the default values for the store
37
+ *
38
+ * @returns - { store, useStore, useSelector }
39
+ */
40
+ export declare function cervello<T>(initialValue: () => T, options?: CervelloOptions): CervelloStore<T>;
17
41
  export {};
@@ -0,0 +1,2 @@
1
+ import type { BehaviorSubject } from 'rxjs';
2
+ export declare const subscribeForReactHook: <T>(store$$: BehaviorSubject<T>) => (onStoreChange: () => void) => () => void;
@@ -1,4 +1,8 @@
1
- declare type ObjectFromAttributes<T, Attributes extends Array<keyof T>> = {
1
+ export declare type WithoutType<T, V, WithNever = {
2
+ [K in keyof T]: Exclude<T[K], undefined> extends V ? never : (T[K] extends Record<string, unknown> ? WithoutType<T[K], V> : T[K]);
3
+ }> = Pick<WithNever, {
4
+ [K in keyof WithNever]: WithNever[K] extends never ? never : K;
5
+ }[keyof WithNever]>;
6
+ export declare type ObjectFromAttributes<T, Attributes extends Array<keyof WithoutType<T, Function>>> = {
2
7
  [k in Attributes[number]]: T[k];
3
8
  };
4
- export type { ObjectFromAttributes };
@@ -1,4 +0,0 @@
1
- import type { ObjectFromAttributes } from '../../types/shared';
2
- import type { BehaviorSubject } from 'rxjs';
3
- export declare function getPartialObjectFromAttributes<T>(attributes: Array<keyof T>, store: T): any;
4
- export declare function createUseSelect<T>(store$$: BehaviorSubject<T>): <Attributes extends (keyof T)[]>(...selectors: Attributes) => ObjectFromAttributes<T, Attributes>;
@@ -1 +0,0 @@
1
- export { cervello as c } from './core';