@cervello/react 0.9.2 → 0.9.5

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,12 +1,16 @@
1
1
  # Cervello
2
- > (Beta version) - Working on it to be have SSR integration (hydration) and better documentation
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
- #### `746 Bytes of bundle size for now!! `
5
- Simplest and truly reactive state manager for React
5
+ > (Beta version) - Working on SSR,persist options and documentation page
6
+
7
+
8
+
9
+
10
+ 🤯 Simplest and truly reactive state manager for React
6
11
 
7
12
 
8
13
  ## 🚀 **Features**
9
- - ⚡️ Optimized and super performant
10
14
  - ⚛️ Truly reactive on item change
11
15
  - ✅ Super simple and minimalistic API
12
16
  - 🐨 Listen to attributes or items lazily
@@ -14,126 +18,138 @@ Simplest and truly reactive state manager for React
14
18
  - 🔑 Typescript support
15
19
 
16
20
  ## 📦 **Install**
17
- ```zsh
18
- # NPM install as a dependency
19
- npm install cervello
21
+ ```bash
22
+ # NPM
23
+ npm install @cervello/react
24
+
25
+ # YARN
26
+ yarn add @cervello/react
20
27
 
21
- # YARN install as a dependency
22
- yarn add cervello
28
+ # PNPM
29
+ pnpm add @cervello/react
23
30
  ```
24
31
 
25
32
 
26
33
  ## 💻 **Usage**
27
34
  The `cervello` function allows you to create a new store in an easy way.
28
- 1. Define the store name
29
- 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
30
36
 
31
37
  ```ts
32
38
  // - store-example.ts
33
- import { cervello } from 'cervello'
39
+ import { cervello } from '@cervello/react'
34
40
 
35
41
 
36
42
  /** Export it with the names you prefer to be used/imported */
37
43
  /**
38
- * The cervello function returns a store with the given name and 2 hooks
39
- * to be reactive and change the store value
44
+ * The cervello function returns a reactive store and 2 hooks
45
+ * to be reactive and change the store value inside react components
46
+ *
40
47
  *
41
- * Object returned => { storeNameProvided, useStore, useSelect }
48
+ * Object returned => { store, useStore, useSelector }
42
49
  */
43
50
  export const {
44
- exampleStore, // The store object
45
- useStore: useExampleStore, // The hook to use the store
46
- useSelect: useExampleSelect // The hook to use the selectors (part of the store)
47
- } = cervello(
48
- 'exampleStore', /* store name */
49
- { count: 0 } /* initial value */
51
+ store: exampleStore, // The store object
52
+ useStore: useExampleStore, // The hook to use the store
53
+ useSelector: useExampleSelect // The hook to use the selectors (part of the store)
54
+ } = cervello({ count: 0 })
55
+ ```
56
+
57
+
58
+ ### 🟢 `store`
59
+ 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
60
+
61
+ ```tsx
62
+ import { store } from './store-example'
63
+
64
+ /**
65
+ * It can be used outside the react components
66
+ * It will notify all the components listening for changes
67
+ */
68
+ const increment = () => { store.count++}
69
+
70
+ const CounterButton = () => (
71
+ /**
72
+ * This makes all the components using the store (i.e.: CounterLabel)
73
+ * to be reactive and re-renders with the new value
74
+ */
75
+ <button onClick={increment}>
76
+ Increment
77
+ </button>
50
78
  )
51
79
  ```
52
80
 
81
+ ### 🟢 `useStore`
53
82
 
54
- Use it in your components. They don't need to know about each other. They can be in different pages or locations:
83
+ React hook that allows you to have a reactive store which re-renders when a new value was set
55
84
  ```tsx
56
- import { useExampleStore } from './store-example'
85
+ import { useStore } from './store-example'
57
86
 
58
87
  const CounterLabel = () => {
59
- const { count } = useExampleStore()
88
+ const { count } = useStore()
60
89
 
61
90
  return (<span>{ count }</span>)
62
91
  }
63
92
  ```
64
93
 
94
+ ### 🟢 `useSelector`
65
95
 
96
+ React hook that allows you to have a reactive store which re-renders when a new value was set on properties you specified
66
97
  ```tsx
67
- import { exampleStore } from './store-example'
98
+ import { useSelector } from './store-example'
68
99
 
69
- const CounterButton = () => (
70
- // This makes all the components using the store (i.e.: CounterLabel)
71
- // to be reactive and re-renders with the new value
72
- <button onClick={e => exampleStore.count += 1}>
73
- Increment
74
- </button>
75
- )
76
- ```
77
-
78
-
79
- #### 🔖 Changing the store
80
- ```ts
81
100
  const CounterLabel = () => {
82
101
  /**
83
- * If you want to just listen for changes, then you can destructure the value but...
84
- *
85
- * IMPORTANT!: In order to change reactively any store attribute, you must use
86
- * the object returned from the `useStore` hook without destructuring
87
- * */
88
- const exampleStore = useExampleStore()
89
-
90
- // Destructured just to be listened if changes
91
- const { count } = exampleStore
92
-
93
- // In order to be reactive, you MUST use the object when you change a value
94
- const increment = () => exampleStore.count += 1
95
-
96
- return (
97
- <div>
98
- <span>{ count }</span>
99
- <button onClick={increment}> Increment </button>
100
- </div>
101
- )
102
- }
102
+ * This will re-render just only when the property `count` changes
103
+ */
104
+ const { count } = useSelector(['count'])
103
105
 
106
+ return (<span>{ count }</span>)
107
+ }
104
108
  ```
105
-
106
- ## USE FUNCTION
107
- The use function allows you to implement side effects due to a change in a the store
109
+ ----
110
+ ### 🟣 The `Use` function
111
+ The use function allows you to implement side effects due to a store change
112
+ #### 🔽 Example
108
113
  ```ts
109
114
  import type { UseFunction } from '@cervello/react'
110
115
 
111
- const logger: UseFunction<'testStore', typeof testStore> = ({ $onChange }): void => {
116
+ const logger: UseFunction<typeof store> = ({ $onChange }): void => {
112
117
  $onChange((store) => {
113
- console.log('Store changed to :>>', store)
118
+ console.log('[Store-changed] to ==>', store)
114
119
  })
115
120
  }
116
121
 
117
122
 
118
- const { testStore } =
119
- cervello('testStore', { test: 'test', count: -1 })
120
- .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 */)
121
125
 
122
126
  ```
123
127
 
124
- #### Use function callback object
128
+ #### 🗳️ Use function callback object
125
129
  ```ts
126
130
  import type { UseFunction } from '@cervello/react'
127
131
 
128
- const logger: UseFunction<'testStore', typeof testStore> = ({ testStore, $onPartialChange, $onChange }): void => {
132
+ const logger: UseFunction<typeof store> = ({ $onChange, $onPartialChange }): void => {
129
133
  // Listen to all the changes happened in the store
130
134
  $onChange((store) => {
131
135
  console.log('Store changed to :>>', store)
132
136
  });
133
137
 
134
138
  // Listen to the changes happened in the store's attributes provided
135
- $onPartialChange(['test', 'count'], (store) => {
136
- store.count += 1
139
+ $onPartialChange(['name'], (store) => {
140
+ console.log('Name has changed to:', store.name)
137
141
  })
138
142
  }
139
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"),e=require("use-sync-external-store/shim/with-selector");function r(){return r=Object.assign?Object.assign.bind():function(n){for(var t=1;t<arguments.length;t++){var e=arguments[t];for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&(n[r]=e[r])}return n},r.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,e){var o,c,s=t;return e in s?"function"==typeof s[e]?s[e].bind(u(n,s)):"object"!=typeof s[e]||Array.isArray(s[e])||"symbol"==typeof e?s[e]:u(n,r({},s[e],((c={})[i]=""+(null!=(o=null==t?void 0:t[i])?o:"")+e,c))):Reflect.get(t,e)},set:function(t,e,r){console.log("set",{target:t,prop:e,value:r});var i=n.getValue(),u=Object.assign({},i);return u[e]=r,n.next(u),Reflect.set(t,e,r)}})}var o=function(n){return function(t){var e=n.subscribe(t);return function(){e.unsubscribe()}}};function c(n){var e=o(n),r=n.getValue.bind(n);return function(){var i=t.useSyncExternalStore(e,r,r);return u(n,i)}}function s(n){var t=o(n),r=n.getValue.bind(n);return function(i,o){var c=e.useSyncExternalStoreWithSelector(t,r,r,function(n){return function(n,t){return n.reduce(function(n,e){return n[e]=t[e],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,e){var i="function"==typeof t?t():t,o=new n.BehaviorSubject(i),a=u(o,r({},i)),f={store:a,useStore:c(o),useSelector:s(o),use:function(){return[].slice.call(arguments).forEach(function(t){t({store:a,$onChange:function(t){o.pipe(n.pairwise(),n.switchMap(function(t){var e=t[1];return t[0]!==e?n.of(e):n.NEVER})).subscribe(function(n){return t(a)})},$onPartialChange:function(t,e){o.pipe(n.pairwise(),n.switchMap(function(t){var e=t[1];return t[0]!==e?n.of(e):n.NEVER}),n.distinctUntilChanged(function(n,e){var r=!0;return t.forEach(function(t){r&&"object"==typeof e[t]?JSON.stringify(n[t])!==JSON.stringify(e[t])&&(r=!1):r&&n[t]!==e[t]&&(r=!1)}),r})).subscribe(function(n){return e(a)})}})}),this}};return f};
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 store: 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 store: StoreType\n useStore: () => StoreType\n useSelector: UseSelector<StoreType>\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 store: 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 (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":["Symbol","proxifyStore","store$$","storeObject","Error","Proxy","get","target","prop","_target$nestedAttrs","_extends2","currentStore","bind","Array","isArray","_extends","nestedAttrs","set","value","console","log","getValue","clonedStore","Object","assign","next","Reflect","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","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 o,distinctUntilChanged as u}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,o,u=t;return r in u?"function"==typeof u[r]?u[r].bind(a(n,u)):"object"!=typeof u[r]||Array.isArray(u[r])||"symbol"==typeof r?u[r]:a(n,f({},u[r],((o={})[s]=""+(null!=(e=null==t?void 0:t[s])?e:"")+r,o))):Reflect.get(t,r)},set:function(t,r,e){console.log("set",{target:t,prop:r,value:e});var o=n.getValue(),u=Object.assign({},o);return u[r]=e,n.next(u),Reflect.set(t,r,e)}})}var l=function(n){return function(t){var r=n.subscribe(t);return function(){r.unsubscribe()}}};function b(n){var t=l(n),r=n.getValue.bind(n);return function(){var e=i(t,r,r);return a(n,e)}}function p(n){var t=l(n),r=n.getValue.bind(n);return function(e,o){var u=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 o?o(n,t):JSON.stringify(n)===JSON.stringify(t)});return a(n,u)}}function y(i,c){var s="function"==typeof i?i():i,l=new n(s),y=a(l,f({},s)),v={store:y,useStore:b(l),useSelector:p(l),use:function(){return[].slice.call(arguments).forEach(function(n){n({store:y,$onChange:function(n){l.pipe(t(),r(function(n){var t=n[1];return n[0]!==t?e(t):o})).subscribe(function(t){return n(y)})},$onPartialChange:function(n,i){l.pipe(t(),r(function(n){var t=n[1];return n[0]!==t?e(t):o}),u(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(y)})}})}),this}};return v}export{y 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":"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"}
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 store: 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 store: StoreType\n useStore: () => StoreType\n useSelector: UseSelector<StoreType>\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 store: 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 (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":["Symbol","proxifyStore","store$$","storeObject","Error","Proxy","get","target","prop","_target$nestedAttrs","_extends2","currentStore","bind","Array","isArray","_extends","nestedAttrs","set","value","console","log","getValue","clonedStore","Object","assign","next","Reflect","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","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){console.log("set",{target:e,prop:n,value: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 p(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 y(i,c){const f="function"==typeof i?i():i,b=new t(f),y=a(b,u({},f));return{store:y,useStore:l(b),useSelector:p(b),use(...t){return t.forEach(t=>{t({store:y,$onChange(t){b.pipe(e(),n(([t,e])=>t!==e?r(e):o)).subscribe(e=>t(y))},$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(y))}})}),this}}}export{y 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 store: 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 store: StoreType\n useStore: () => StoreType\n useSelector: UseSelector<StoreType>\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 store: 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 (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":["Symbol","proxifyStore","store$$","storeObject","Error","Proxy","get","target","prop","currentStore","_target$nestedAttrs","bind","Array","isArray","nestedAttrs","Reflect","set","value","console","log","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","_extends","useStore","useSelector","use","functionList","forEach","func","$onChange","cb","pipe","pairwise","switchMap","oldValue","newValue","of","NEVER","_","$onPartialChange","attrs","distinctUntilChanged","isEqual","selector","this"],"mappings":"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"}
@@ -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,t){"object"==typeof exports&&"undefined"!=typeof module?t(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"],t):t((e||self).react={},e.rxjs,e.shim,e.withSelector)}(this,function(e,t,n,r){function i(){return i=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},i.apply(this,arguments)}var o=Symbol("___nested-attributes___");function u(e,t){if("object"!=typeof t)throw new Error("Store must be an object");return new Proxy(t,{get:function(t,n){var r,s,c=t;return n in c?"function"==typeof c[n]?c[n].bind(u(e,c)):"object"!=typeof c[n]||Array.isArray(c[n])||"symbol"==typeof n?c[n]:u(e,i({},c[n],((s={})[o]=""+(null!=(r=null==t?void 0:t[o])?r:"")+n,s))):Reflect.get(t,n)},set:function(t,n,r){console.log("set",{target:t,prop:n,value:r});var i=e.getValue(),o=Object.assign({},i);return o[n]=r,e.next(o),Reflect.set(t,n,r)}})}var s=function(e){return function(t){var n=e.subscribe(t);return function(){n.unsubscribe()}}};function c(e){var t=s(e),r=e.getValue.bind(e);return function(){var i=n.useSyncExternalStore(t,r,r);return u(e,i)}}function f(e){var t=s(e),n=e.getValue.bind(e);return function(i,o){var s=r.useSyncExternalStoreWithSelector(t,n,n,function(e){return function(e,t){return e.reduce(function(e,n){return e[n]=t[n],e},{})}(i,e)},function(e,t){return o?o(e,t):JSON.stringify(e)===JSON.stringify(t)});return u(e,s)}}e.cervello=function(e,n){var r="function"==typeof e?e():e,o=new t.BehaviorSubject(r),s=u(o,i({},r)),a={store:s,useStore:c(o),useSelector:f(o),use:function(){return[].slice.call(arguments).forEach(function(e){e({store:s,$onChange:function(e){o.pipe(t.pairwise(),t.switchMap(function(e){var n=e[1];return e[0]!==n?t.of(n):t.NEVER})).subscribe(function(t){return e(s)})},$onPartialChange:function(e,n){o.pipe(t.pairwise(),t.switchMap(function(e){var n=e[1];return e[0]!==n?t.of(n):t.NEVER}),t.distinctUntilChanged(function(t,n){var r=!0;return e.forEach(function(e){r&&"object"==typeof n[e]?JSON.stringify(t[e])!==JSON.stringify(n[e])&&(r=!1):r&&t[e]!==n[e]&&(r=!1)}),r})).subscribe(function(e){return n(s)})}})}),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 store: 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 store: StoreType\n useStore: () => StoreType\n useSelector: UseSelector<StoreType>\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 store: 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 (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":["Symbol","proxifyStore","store$$","storeObject","Error","Proxy","get","target","prop","_target$nestedAttrs","_extends2","currentStore","bind","Array","isArray","_extends","nestedAttrs","set","value","console","log","getValue","clonedStore","Object","assign","next","Reflect","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","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.2",
4
- "description": "Simplest and truly reactive state manager for React",
3
+ "version": "0.9.5",
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,38 @@
1
- import type { ObjectFromAttributes } from '../../types/shared';
2
- declare type CervelloStoreUseParam<StoreName extends string, StoreType> = {
3
- [k in StoreName]: StoreType;
4
- } & {
1
+ import type { WithoutType } from '../../types/shared';
2
+ import type { UseSelector } from '../helpers';
3
+ interface CervelloStoreUseParam<StoreType> {
4
+ store: StoreType;
5
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
- } & {
6
+ $onPartialChange: <Attributes extends Array<keyof WithoutType<StoreType, Function>>>(selectors: Attributes, cb: (store: StoreType) => void) => void;
7
+ }
8
+ /**
9
+ * Use function which allows you to listen for changes in the store.
10
+ */
11
+ export declare type CervelloUseFunction<StoreType> = (param: CervelloStoreUseParam<StoreType>) => void;
12
+ interface CervelloStore<StoreType> {
13
+ store: StoreType;
12
14
  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>;
15
+ useSelector: UseSelector<StoreType>;
16
+ use: (...functions: Array<(useObj: CervelloStoreUseParam<StoreType>) => void>) => CervelloStore<StoreType>;
17
+ }
18
+ /**
19
+ * @note Currently not working
20
+ */
21
+ export interface CervelloOptions {
22
+ persist?: boolean;
23
+ }
24
+ /**
25
+ * Creates a store that is reactive and can be used inside and outside of React components.
26
+ * @param initialValue Object with the default values for the store
27
+ *
28
+ * @returns - { store, useStore, useSelector }
29
+ */
30
+ export declare function cervello<T extends Record<any, unknown>>(initialValue: T, options?: CervelloOptions): CervelloStore<T>;
31
+ /**
32
+ * Creates a store that is reactive and can be used inside and outside of React components.
33
+ * @param initialValue Function which returns the default values for the store
34
+ *
35
+ * @returns - { store, useStore, useSelector }
36
+ */
37
+ export declare function cervello<T>(initialValue: () => T, options?: CervelloOptions): CervelloStore<T>;
17
38
  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';