Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/toyobayashi/pinia-core
https://github.com/toyobayashi/pinia-core
Last synced: 2 days ago
JSON representation
- Host: GitHub
- URL: https://github.com/toyobayashi/pinia-core
- Owner: toyobayashi
- Created: 2023-11-07T15:22:22.000Z (about 1 year ago)
- Default Branch: main
- Last Pushed: 2024-08-21T10:41:16.000Z (3 months ago)
- Last Synced: 2024-10-11T20:58:36.976Z (27 days ago)
- Language: TypeScript
- Size: 71.3 KB
- Stars: 2
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# Use 🍍 in React
```bash
npm install @vue/runtime-core pinia-core
```Example:
```ts
import { useRef, useCallback, useSyncExternalStore } from 'react'
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
import type { Plugin, InjectionKey, App } from '@vue/runtime-core'
import { Store, createPinia, defineStore } from 'pinia-core'
import type { PiniaPlugin } from 'pinia-core'class SnapshotSaver {
private _store: S
private _selector?: (store: S) => unknown
public getSnapshot: () => unknown
public updateSnapshot: () => voidpublic constructor (store: S, selector?: (store: S) => unknown) {
this._store = store
this._selector = selectorlet snapshot: unknown
this.getSnapshot = () => snapshot
this.updateSnapshot = () => {
const { _store, _selector } = this
snapshot = _selector ? _selector(_store) : new Proxy(_store, {})
}this.updateSnapshot()
}public tryUpdate (store: S, selector: ((store: S) => unknown) | undefined) {
const prevStore = this._store
const prevSelector = this._selector
const newStore = !Object.is(store, prevStore)
const newSelector = !Object.is(selector, prevSelector)
if (newStore) this._store = store
if (newSelector) this._selector = selector
if (newStore || newSelector) {
this.updateSnapshot()
}
}
}function usePiniaStore<
S extends { $subscribe: (cb: (...args: unknown[]) => unknown) => () => void },
T = S
> (
store: S,
selector?: (store: S) => T
): T {
const snap = useRef>(null!)
if (!snap.current) {
snap.current = new SnapshotSaver(store, selector)
} else {
snap.current.tryUpdate(store, selector)
}const subscribe = useCallback((onStoreChange: () => void) => {
return store.$subscribe(() => {
snap.current.updateSnapshot()
onStoreChange()
})
}, [store])return useSyncExternalStore(subscribe, snap.current.getSnapshot as () => T)
}interface FakeApp {
config: {
globalProperties: Record
};
use(plugin: Plugin): this;
provide(key: InjectionKey | string, value: T): this;
}// for plugin
const fakeVueApp: FakeApp = {
provide () {
return this
},
config: {
globalProperties: {}
},
use (plugin) {
if (typeof plugin === 'function') {
plugin(this as App)
} else {
plugin.install(this as App)
}
return this
}
}const pinia = createPinia()
pinia.use(piniaPluginPersistedstate as unknown as PiniaPlugin)
fakeVueApp.use(pinia)declare module 'pinia-core' {
interface DefineStoreOptions<
Id extends string,
S extends StateTree,
G,
A
> extends DefineStoreOptionsBase> {
persist: boolean
}
}const mainStore = defineStore('main_store', {
persist: true,
state: () => {
return {
count: 0
}
},
actions: {
addCount () {
this.count++
}
}
})(pinia)export default function Component () {
// connect store
const store = usePiniaStore(mainStore)// with selector
const storeCount = usePiniaStore(mainStore, (state) => state.count)// ...
}
```