@cervello/react 0.9.1 → 0.9.4
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 +85 -69
- package/dist/cervello.cjs +1 -1
- package/dist/cervello.cjs.map +1 -1
- package/dist/cervello.esm.js +1 -1
- package/dist/cervello.esm.js.map +1 -1
- package/dist/cervello.modern.js +1 -1
- package/dist/cervello.modern.js.map +1 -1
- package/dist/cervello.umd.js +1 -1
- package/dist/cervello.umd.js.map +1 -1
- package/package.json +10 -10
- package/types/lib/helpers/create-use-selector.d.ts +5 -0
- package/types/lib/helpers/index.d.ts +1 -1
- package/types/lib/store/index.d.ts +35 -14
- package/types/lib/utils/subscribe-for-react.d.ts +2 -0
- package/types/types/shared.d.ts +6 -2
- package/types/lib/helpers/create-use-select.d.ts +0 -4
- package/types/lib/index.d.ts +0 -1
package/README.md
CHANGED
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
# Cervello
|
|
2
|
-
|
|
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
|
-
|
|
5
|
-
|
|
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
|
-
```
|
|
18
|
-
# NPM
|
|
19
|
-
npm install cervello
|
|
21
|
+
```bash
|
|
22
|
+
# NPM
|
|
23
|
+
npm install @cervello/react
|
|
24
|
+
|
|
25
|
+
# YARN
|
|
26
|
+
yarn add @cervello/react
|
|
20
27
|
|
|
21
|
-
#
|
|
22
|
-
|
|
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
|
-
|
|
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
|
|
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 => {
|
|
48
|
+
* Object returned => { store, useStore, useSelector }
|
|
42
49
|
*/
|
|
43
50
|
export const {
|
|
44
|
-
exampleStore,
|
|
45
|
-
useStore:
|
|
46
|
-
|
|
47
|
-
} = cervello(
|
|
48
|
-
|
|
49
|
-
|
|
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
|
-
|
|
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 {
|
|
85
|
+
import { useStore } from './store-example'
|
|
57
86
|
|
|
58
87
|
const CounterLabel = () => {
|
|
59
|
-
const { count } =
|
|
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 {
|
|
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
|
-
*
|
|
84
|
-
|
|
85
|
-
|
|
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
|
-
|
|
107
|
-
The use function allows you to implement side effects due to a change
|
|
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<
|
|
116
|
+
const logger: UseFunction<typeof store> = ({ $onChange }): void => {
|
|
112
117
|
$onChange((store) => {
|
|
113
|
-
console.log('Store
|
|
118
|
+
console.log('[Store-changed] to ==>', store)
|
|
114
119
|
})
|
|
115
120
|
}
|
|
116
121
|
|
|
117
122
|
|
|
118
|
-
const {
|
|
119
|
-
|
|
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<
|
|
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(['
|
|
136
|
-
|
|
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("
|
|
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
|
package/dist/cervello.cjs.map
CHANGED
|
@@ -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":"4VAIA,MACoBA,OADa,2BAGjBC,SAAAA,EAAuDC,EAA6BC,GAClG,GAA2B,iBAAvBA,EAAiC,MAAUC,IAAAA,MAAM,2BAErD,OAAWC,IAAAA,MACTF,EACA,CACEG,IAAK,SAAUC,EAAWC,GACxB,IAYgHC,EAAAC,EAZ9FC,EAAGJ,EAIrB,OAAIC,KAAJG,EACoC,mBAAvBA,EAAaH,GACHG,EAACH,GAAMI,KAAKX,EAAaC,EAASS,IAMrB,iBAAXA,EAACH,IAAuBK,MAAMC,QAAQH,EAAaH,KAA0B,iBAATA,EAUxEG,EAACH,GARXP,EACLC,EADiBa,EAAA,CAAA,EAGZJ,EAAaH,WACfQ,GAJc,IAAA,OAAAP,EAAA,MAIIF,OAJJ,EAIIA,EAASS,IAJbP,EAI8B,IAAKD,EAJnCE,aAWRJ,IAAIC,EAAQC,EAC5B,EACDS,IAAK,SAAUV,EAAWC,EAAuBU,GAE/CC,QAAQC,IAAI,MAAO,CAAEb,OAAAA,EAAQC,KAAAA,EAAMU,MAAAA,IACnC,IAAkBP,EAAGT,EAAQmB,WAEvBC,EAAcC,OAAOC,OAAO,CAAd,EAAkBb,GAKtC,OAJAW,EAAYd,GAAQU,EAEpBhB,EAAQuB,KAAKH,GAECI,QAACT,IAAIV,EAAQC,EAAMU,EAClC,GAGN,KCnDiCS,EAAG,SAAIzB,GAOvC,OANkB,SAAC0B,GACjB,IAAMC,EAAe3B,EAAQ4B,UAAUF,GACvC,OAAY,WACVC,EAAaE,aACd,CACF,CAEF,ECFK,SAAAC,EAA8B9B,GAClC,MAAkByB,EAAsBzB,GAC1BmB,EAAGnB,EAAQmB,SAAST,KAAKV,GAWvC,OAPiB,WACf,IAAM+B,EAAQC,EAAoBA,qBAACJ,EAAWT,EAAUA,GAExD,OAAOpB,EAAaC,EAAS+B,EAC9B,CAIF,UCAKE,EAAiCjC,GACrC,IAAM4B,EAAYH,EAAsBzB,KACvBA,EAAQmB,SAAST,KAAKV,GAoDvC,OAlBoB,SAClBkC,EACAC,GAEA,IAAMJ,EAAQK,EAAgCA,iCAC5CR,EACAT,EACAA,EACA,SAACY,GAAD,OAxDUM,SAAoCC,EAA4BP,GAC9E,OAAiBO,EAACC,OAAY,SAACC,EAAKC,GAElC,OADAD,EAAIC,GAAQV,EAAMU,GAEnBD,CAAA,EAAE,CAAA,EACJ,CAmD8CH,CAACH,EAAWH,EAArD,EACA,SAACW,EAAMD,GAASN,OAAAA,EACZA,EAAgBO,EAAMD,GACtBE,KAAKC,UAAUF,KAAUC,KAAKC,UAAUH,EAF5C,GAMF,OAAO1C,EAAaC,EAAgB+B,EACrC,CAGF,kBCVe,SAAcc,EAA6BC,GACzD,IAAMC,EAAwC,mBAAxBF,EAAsCA,IAAyBA,EAC/E7C,EAAU,sBAAuB+C,GAEjCC,EAAejD,EAAgBC,EAAJa,EAAA,CAAA,EAAkBkC,IAE7CE,EAAgB,CACpBlB,MAAOiB,EAGPE,SAAUpB,EAAkB9B,GAC5BmD,YAAalB,EAAqBjC,GAGlCoD,IAAyB,WAiCvB,MAhCA,GAAaC,MAAAA,KAAAA,WAAAA,QAAQ,SAACC,GACpBA,EAAK,CACHvB,MAAOiB,EACPO,UAFG,SAEQC,GACTxD,EAAQyD,KACNC,EAAAA,WACAC,EAAAA,UAAU,SAAEC,GAAAA,IAAUC,EAAeD,EAAAA,GAAAA,OAAfC,EAAAA,KAA4BA,EAAWC,EAAAA,GAAGD,GAAYE,EAAlEA,KAAA,IACVnC,UAAU,SAACoC,GAAD,OAASR,EAACR,EAAV,EACb,EACDiB,iBAAkBC,SAAAA,EAAuBV,GACvCxD,EAAQyD,KACNC,EAAAA,WACAC,EAAAA,UAAU,SAAAQ,GAAA,IAAYN,EAAZM,EAAA,GAAA,OAAAA,EAAA,KAAwCN,EAAWC,EAAAA,GAAGD,GAAYE,EAAAA,KAAlE,GACVK,EAAoBA,qBAAC,SAAC1B,EAAMD,GAC1B,IAAW4B,GAAG,EAYd,OAXAH,EAAMb,QAAQ,SAACiB,GACTD,GAAqC,iBAAf5B,EAAC6B,GACrB3B,KAAKC,UAAUF,EAAK4B,MAAe3B,KAAKC,UAAUH,EAAK6B,MACzDD,GAAU,GAGRA,GAAW3B,EAAK4B,KAAc7B,EAAK6B,KACrCD,GAAU,EAGf,GAEFA,CAAA,IACDzC,UAAU,SAACoC,GAAD,OAASR,EAACR,EAAV,EACb,GAEJ,GAEFuB,IAAA,GAKH,OACDtB,CAAA"}
|
package/dist/cervello.esm.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{
|
|
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
|
package/dist/cervello.esm.js.map
CHANGED
|
@@ -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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"}
|
package/dist/cervello.modern.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{
|
|
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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"}
|
package/dist/cervello.umd.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
!function(e,
|
|
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
|
package/dist/cervello.umd.js.map
CHANGED
|
@@ -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":"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"}
|
|
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,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cervello/react",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.4",
|
|
4
4
|
"description": "Simplest and truly reactive state manager for React",
|
|
5
5
|
"main": "./dist/cervello.cjs",
|
|
6
6
|
"module": "./dist/cervello.esm.js",
|
|
@@ -28,7 +28,8 @@
|
|
|
28
28
|
"types"
|
|
29
29
|
],
|
|
30
30
|
"scripts": {
|
|
31
|
-
"
|
|
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,16 +39,16 @@
|
|
|
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",
|
|
47
48
|
"local"
|
|
48
49
|
],
|
|
49
50
|
"author": "Chempo",
|
|
50
|
-
"license": "
|
|
51
|
+
"license": "MIT",
|
|
51
52
|
"bugs": {
|
|
52
53
|
"url": "https://github.com/chempogonzalez/cervello/issues"
|
|
53
54
|
},
|
|
@@ -57,16 +58,15 @@
|
|
|
57
58
|
"rxjs": ">= 7.4.0"
|
|
58
59
|
},
|
|
59
60
|
"dependencies": {
|
|
60
|
-
"
|
|
61
|
-
"use-sync-external-store": "^1.1.0"
|
|
61
|
+
"use-sync-external-store": "^1.2.0"
|
|
62
62
|
},
|
|
63
63
|
"devDependencies": {
|
|
64
64
|
"@chempo/ec-linter": "^1.0.10",
|
|
65
|
-
"@types/react": "18.0.
|
|
65
|
+
"@types/react": "18.0.15",
|
|
66
66
|
"@types/use-sync-external-store": "^0.0.3",
|
|
67
67
|
"microbundle": "0.15.0",
|
|
68
|
-
"react": "18.
|
|
69
|
-
"rxjs": "7.5.
|
|
70
|
-
"typescript": "4.7.
|
|
68
|
+
"react": "18.2.0",
|
|
69
|
+
"rxjs": "7.5.6",
|
|
70
|
+
"typescript": "4.7.4"
|
|
71
71
|
}
|
|
72
72
|
}
|
|
@@ -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,17 +1,38 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
|
|
3
|
-
|
|
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
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
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
|
-
|
|
14
|
-
use: (...functions: Array<(useObj: CervelloStoreUseParam<
|
|
15
|
-
}
|
|
16
|
-
|
|
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 {};
|
package/types/types/shared.d.ts
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
declare type
|
|
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>;
|
package/types/lib/index.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { cervello as c } from './core';
|