ok
This commit is contained in:
20
node_modules/.pnpm/nanostores@1.0.1/node_modules/nanostores/LICENSE
generated
vendored
Normal file
20
node_modules/.pnpm/nanostores@1.0.1/node_modules/nanostores/LICENSE
generated
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright 2020 Andrey Sitnik <andrey@sitnik.ru>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
63
node_modules/.pnpm/nanostores@1.0.1/node_modules/nanostores/README.md
generated
vendored
Normal file
63
node_modules/.pnpm/nanostores@1.0.1/node_modules/nanostores/README.md
generated
vendored
Normal file
@ -0,0 +1,63 @@
|
||||
# Nano Stores
|
||||
|
||||
<img align="right" width="92" height="92" title="Nano Stores logo"
|
||||
src="https://nanostores.github.io/nanostores/logo.svg">
|
||||
|
||||
A tiny state manager for **React**, **React Native**, **Preact**, **Vue**,
|
||||
**Svelte**, **Solid**, **Lit**, **Angular**, and vanilla JS.
|
||||
It uses **many atomic stores** and direct manipulation.
|
||||
|
||||
* **Small.** Between 265 and 803 bytes (minified and brotlied).
|
||||
Zero dependencies. It uses [Size Limit] to control size.
|
||||
* **Fast.** With small atomic and derived stores, you do not need to call
|
||||
the selector function for all components on every store change.
|
||||
* **Tree Shakable.** A chunk contains only stores used by components
|
||||
in the chunk.
|
||||
* Designed to move logic from components to stores.
|
||||
* Good **TypeScript** support.
|
||||
|
||||
```ts
|
||||
// store/users.ts
|
||||
import { atom } from 'nanostores'
|
||||
|
||||
export const $users = atom<User[]>([])
|
||||
|
||||
export function addUser(user: User) {
|
||||
$users.set([...$users.get(), user]);
|
||||
}
|
||||
```
|
||||
|
||||
```ts
|
||||
// store/admins.ts
|
||||
import { computed } from 'nanostores'
|
||||
import { $users } from './users.js'
|
||||
|
||||
export const $admins = computed($users, users => users.filter(i => i.isAdmin))
|
||||
```
|
||||
|
||||
```tsx
|
||||
// components/admins.tsx
|
||||
import { useStore } from '@nanostores/react'
|
||||
import { $admins } from '../stores/admins.js'
|
||||
|
||||
export const Admins = () => {
|
||||
const admins = useStore($admins)
|
||||
return (
|
||||
<ul>
|
||||
{admins.map(user => <UserItem user={user} />)}
|
||||
</ul>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
<img src="https://cdn.evilmartians.com/badges/logo-no-label.svg" alt="" width="22" height="16" /> Made at <b><a href="https://evilmartians.com/devtools?utm_source=nanostores&utm_campaign=devtools-button&utm_medium=github">Evil Martians</a></b>, product consulting for <b>developer tools</b>.
|
||||
|
||||
---
|
||||
|
||||
[Size Limit]: https://github.com/ai/size-limit
|
||||
|
||||
|
||||
## Docs
|
||||
Read full docs **[here](https://github.com/nanostores/nanostores#readme)**.
|
||||
169
node_modules/.pnpm/nanostores@1.0.1/node_modules/nanostores/atom/index.d.ts
generated
vendored
Normal file
169
node_modules/.pnpm/nanostores@1.0.1/node_modules/nanostores/atom/index.d.ts
generated
vendored
Normal file
@ -0,0 +1,169 @@
|
||||
export type AllKeys<T> = T extends any ? keyof T : never
|
||||
|
||||
type Primitive = boolean | number | string
|
||||
|
||||
export type ReadonlyIfObject<Value> = Value extends undefined
|
||||
? Value
|
||||
: Value extends (...args: any) => any
|
||||
? Value
|
||||
: Value extends Primitive
|
||||
? Value
|
||||
: Value extends object
|
||||
? Readonly<Value>
|
||||
: Value
|
||||
|
||||
/**
|
||||
* Store object.
|
||||
*/
|
||||
export interface ReadableAtom<Value = any> {
|
||||
/**
|
||||
* Get store value.
|
||||
*
|
||||
* In contrast with {@link ReadableAtom#value} this value will be always
|
||||
* initialized even if store had no listeners.
|
||||
*
|
||||
* ```js
|
||||
* $store.get()
|
||||
* ```
|
||||
*
|
||||
* @returns Store value.
|
||||
*/
|
||||
get(): Value
|
||||
|
||||
/**
|
||||
* Listeners count.
|
||||
*/
|
||||
readonly lc: number
|
||||
|
||||
/**
|
||||
* Subscribe to store changes.
|
||||
*
|
||||
* In contrast with {@link Store#subscribe} it do not call listener
|
||||
* immediately.
|
||||
*
|
||||
* @param listener Callback with store value and old value.
|
||||
* @returns Function to remove listener.
|
||||
*/
|
||||
listen(
|
||||
listener: (
|
||||
value: ReadonlyIfObject<Value>,
|
||||
oldValue: ReadonlyIfObject<Value>
|
||||
) => void
|
||||
): () => void
|
||||
|
||||
/**
|
||||
* Low-level method to notify listeners about changes in the store.
|
||||
*
|
||||
* Can cause unexpected behaviour when combined with frontend frameworks
|
||||
* that perform equality checks for values, such as React.
|
||||
*/
|
||||
notify(oldValue?: ReadonlyIfObject<Value>): void
|
||||
|
||||
/**
|
||||
* Unbind all listeners.
|
||||
*/
|
||||
off(): void
|
||||
|
||||
/**
|
||||
* Subscribe to store changes and call listener immediately.
|
||||
*
|
||||
* ```
|
||||
* import { $router } from '../store'
|
||||
*
|
||||
* $router.subscribe(page => {
|
||||
* console.log(page)
|
||||
* })
|
||||
* ```
|
||||
*
|
||||
* @param listener Callback with store value and old value.
|
||||
* @returns Function to remove listener.
|
||||
*/
|
||||
subscribe(
|
||||
listener: (
|
||||
value: ReadonlyIfObject<Value>,
|
||||
oldValue?: ReadonlyIfObject<Value>
|
||||
) => void
|
||||
): () => void
|
||||
|
||||
/**
|
||||
* Low-level method to read store’s value without calling `onStart`.
|
||||
*
|
||||
* Try to use only {@link ReadableAtom#get}.
|
||||
* Without subscribers, value can be undefined.
|
||||
*/
|
||||
readonly value: undefined | Value
|
||||
}
|
||||
|
||||
/**
|
||||
* Store with a way to manually change the value.
|
||||
*/
|
||||
export interface WritableAtom<Value = any> extends ReadableAtom<Value> {
|
||||
/**
|
||||
* Change store value.
|
||||
*
|
||||
* ```js
|
||||
* $router.set({ path: location.pathname, page: parse(location.pathname) })
|
||||
* ```
|
||||
*
|
||||
* @param newValue New store value.
|
||||
*/
|
||||
set(newValue: Value): void
|
||||
}
|
||||
|
||||
export interface PreinitializedWritableAtom<Value> extends WritableAtom<Value> {
|
||||
readonly value: Value
|
||||
}
|
||||
|
||||
export type Atom<Value = any> = ReadableAtom<Value> | WritableAtom<Value>
|
||||
|
||||
export declare let notifyId: number
|
||||
/**
|
||||
* Create store with atomic value. It could be a string or an object, which you
|
||||
* will replace completely.
|
||||
*
|
||||
* If you want to change keys in the object inside store, use {@link map}.
|
||||
*
|
||||
* ```js
|
||||
* import { atom, onMount } from 'nanostores'
|
||||
*
|
||||
* // Initial value
|
||||
* export const $router = atom({ path: '', page: 'home' })
|
||||
*
|
||||
* function parse () {
|
||||
* $router.set({ path: location.pathname, page: parse(location.pathname) })
|
||||
* }
|
||||
*
|
||||
* // Listen for URL changes on first store’s listener.
|
||||
* onMount($router, () => {
|
||||
* parse()
|
||||
* window.addEventListener('popstate', parse)
|
||||
* return () => {
|
||||
* window.removeEventListener('popstate', parse)
|
||||
* }
|
||||
* })
|
||||
* ```
|
||||
*
|
||||
* @param initialValue Initial value of the store.
|
||||
* @returns The store object with methods to subscribe.
|
||||
*/
|
||||
export function atom<Value, StoreExt = object>(
|
||||
...args: undefined extends Value ? [] | [Value] : [Value]
|
||||
): PreinitializedWritableAtom<Value> & StoreExt
|
||||
|
||||
/**
|
||||
* Change store type for readonly for export.
|
||||
*
|
||||
* ```ts
|
||||
* import { readonlyType } from 'nanostores'
|
||||
*
|
||||
* const $storePrivate = atom(0)
|
||||
*
|
||||
* export const $store = readonlyType($storePrivate)
|
||||
* ```
|
||||
*
|
||||
* @param store The store to be exported.
|
||||
* @returns The readonly store.
|
||||
*/
|
||||
export function readonlyType<Value>(
|
||||
store: ReadableAtom<Value>
|
||||
): ReadableAtom<Value>
|
||||
92
node_modules/.pnpm/nanostores@1.0.1/node_modules/nanostores/atom/index.js
generated
vendored
Normal file
92
node_modules/.pnpm/nanostores@1.0.1/node_modules/nanostores/atom/index.js
generated
vendored
Normal file
@ -0,0 +1,92 @@
|
||||
import { clean } from '../clean-stores/index.js'
|
||||
|
||||
let listenerQueue = []
|
||||
let lqIndex = 0
|
||||
const QUEUE_ITEMS_PER_LISTENER = 4
|
||||
export let epoch = 0
|
||||
|
||||
export let atom = initialValue => {
|
||||
let listeners = []
|
||||
let $atom = {
|
||||
get() {
|
||||
if (!$atom.lc) {
|
||||
$atom.listen(() => {})()
|
||||
}
|
||||
return $atom.value
|
||||
},
|
||||
lc: 0,
|
||||
listen(listener) {
|
||||
$atom.lc = listeners.push(listener)
|
||||
|
||||
return () => {
|
||||
for (
|
||||
let i = lqIndex + QUEUE_ITEMS_PER_LISTENER;
|
||||
i < listenerQueue.length;
|
||||
|
||||
) {
|
||||
if (listenerQueue[i] === listener) {
|
||||
listenerQueue.splice(i, QUEUE_ITEMS_PER_LISTENER)
|
||||
} else {
|
||||
i += QUEUE_ITEMS_PER_LISTENER
|
||||
}
|
||||
}
|
||||
|
||||
let index = listeners.indexOf(listener)
|
||||
if (~index) {
|
||||
listeners.splice(index, 1)
|
||||
if (!--$atom.lc) $atom.off()
|
||||
}
|
||||
}
|
||||
},
|
||||
notify(oldValue, changedKey) {
|
||||
epoch++
|
||||
let runListenerQueue = !listenerQueue.length
|
||||
for (let listener of listeners) {
|
||||
listenerQueue.push(listener, $atom.value, oldValue, changedKey)
|
||||
}
|
||||
|
||||
if (runListenerQueue) {
|
||||
for (
|
||||
lqIndex = 0;
|
||||
lqIndex < listenerQueue.length;
|
||||
lqIndex += QUEUE_ITEMS_PER_LISTENER
|
||||
) {
|
||||
listenerQueue[lqIndex](
|
||||
listenerQueue[lqIndex + 1],
|
||||
listenerQueue[lqIndex + 2],
|
||||
listenerQueue[lqIndex + 3]
|
||||
)
|
||||
}
|
||||
listenerQueue.length = 0
|
||||
}
|
||||
},
|
||||
/* It will be called on last listener unsubscribing.
|
||||
We will redefine it in onMount and onStop. */
|
||||
off() {},
|
||||
set(newValue) {
|
||||
let oldValue = $atom.value
|
||||
if (oldValue !== newValue) {
|
||||
$atom.value = newValue
|
||||
$atom.notify(oldValue)
|
||||
}
|
||||
},
|
||||
subscribe(listener) {
|
||||
let unbind = $atom.listen(listener)
|
||||
listener($atom.value)
|
||||
return unbind
|
||||
},
|
||||
value: initialValue
|
||||
}
|
||||
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
$atom[clean] = () => {
|
||||
listeners = []
|
||||
$atom.lc = 0
|
||||
$atom.off()
|
||||
}
|
||||
}
|
||||
|
||||
return $atom
|
||||
}
|
||||
|
||||
export const readonlyType = store => store
|
||||
24
node_modules/.pnpm/nanostores@1.0.1/node_modules/nanostores/clean-stores/index.d.ts
generated
vendored
Normal file
24
node_modules/.pnpm/nanostores@1.0.1/node_modules/nanostores/clean-stores/index.d.ts
generated
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
import type { MapCreator } from '../map-creator/index.js'
|
||||
import type { Store } from '../map/index.js'
|
||||
|
||||
export const clean: unique symbol
|
||||
|
||||
/**
|
||||
* Destroys all cached stores and call
|
||||
*
|
||||
* It also reset all tasks by calling {@link cleanTasks}.
|
||||
*
|
||||
* ```js
|
||||
* import { cleanStores } from 'nanostores'
|
||||
*
|
||||
* afterEach(() => {
|
||||
* cleanStores($router, $settings)
|
||||
* })
|
||||
* ```
|
||||
*
|
||||
* @param stores Used store classes.
|
||||
* @return Promise for stores destroying.
|
||||
*/
|
||||
export function cleanStores(
|
||||
...stores: (MapCreator<any, any[]> | Store | undefined)[]
|
||||
): void
|
||||
18
node_modules/.pnpm/nanostores@1.0.1/node_modules/nanostores/clean-stores/index.js
generated
vendored
Normal file
18
node_modules/.pnpm/nanostores@1.0.1/node_modules/nanostores/clean-stores/index.js
generated
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
import { cleanTasks } from '../task/index.js'
|
||||
|
||||
export let clean = Symbol('clean')
|
||||
|
||||
export let cleanStores = (...stores) => {
|
||||
if (process.env.NODE_ENV === 'production') {
|
||||
throw new Error(
|
||||
'cleanStores() can be used only during development or tests'
|
||||
)
|
||||
}
|
||||
cleanTasks()
|
||||
for (let $store of stores) {
|
||||
if ($store) {
|
||||
if ($store.mocked) delete $store.mocked
|
||||
if ($store[clean]) $store[clean]()
|
||||
}
|
||||
}
|
||||
}
|
||||
86
node_modules/.pnpm/nanostores@1.0.1/node_modules/nanostores/computed/index.d.ts
generated
vendored
Normal file
86
node_modules/.pnpm/nanostores@1.0.1/node_modules/nanostores/computed/index.d.ts
generated
vendored
Normal file
@ -0,0 +1,86 @@
|
||||
import type { ReadableAtom } from '../atom/index.js'
|
||||
import type { AnyStore, Store, StoreValue } from '../map/index.js'
|
||||
import type { Task } from '../task/index.js'
|
||||
|
||||
export type StoreValues<Stores extends AnyStore[]> = {
|
||||
[Index in keyof Stores]: StoreValue<Stores[Index]>
|
||||
}
|
||||
|
||||
type A = ReadableAtom<number>
|
||||
type B = ReadableAtom<string>
|
||||
|
||||
type C = (...values: StoreValues<[A, B]>) => void
|
||||
|
||||
interface Computed {
|
||||
<Value, OriginStore extends Store>(
|
||||
stores: OriginStore,
|
||||
cb: (value: StoreValue<OriginStore>) => Task<Value>
|
||||
): ReadableAtom<undefined | Value>
|
||||
<Value, OriginStores extends AnyStore[]>(
|
||||
stores: [...OriginStores],
|
||||
cb: (...values: StoreValues<OriginStores>) => Task<Value>
|
||||
): ReadableAtom<undefined | Value>
|
||||
<Value, OriginStore extends Store>(
|
||||
stores: OriginStore,
|
||||
cb: (value: StoreValue<OriginStore>) => Value
|
||||
): ReadableAtom<Value>
|
||||
/**
|
||||
* Create derived store, which use generates value from another stores.
|
||||
*
|
||||
* ```js
|
||||
* import { computed } from 'nanostores'
|
||||
*
|
||||
* import { $users } from './users.js'
|
||||
*
|
||||
* export const $admins = computed($users, users => {
|
||||
* return users.filter(user => user.isAdmin)
|
||||
* })
|
||||
* ```
|
||||
*
|
||||
* An async function can be evaluated by using {@link task}.
|
||||
*
|
||||
* ```js
|
||||
* import { computed, task } from 'nanostores'
|
||||
*
|
||||
* import { $userId } from './users.js'
|
||||
*
|
||||
* export const $user = computed($userId, userId => task(async () => {
|
||||
* const response = await fetch(`https://my-api/users/${userId}`)
|
||||
* return response.json()
|
||||
* }))
|
||||
* ```
|
||||
*/
|
||||
<Value, OriginStores extends AnyStore[]>(
|
||||
stores: [...OriginStores],
|
||||
cb: (...values: StoreValues<OriginStores>) => Task<Value> | Value
|
||||
): ReadableAtom<Value>
|
||||
}
|
||||
|
||||
export const computed: Computed
|
||||
|
||||
interface Batched {
|
||||
<Value, OriginStore extends Store>(
|
||||
stores: OriginStore,
|
||||
cb: (value: StoreValue<OriginStore>) => Task<Value> | Value
|
||||
): ReadableAtom<Value>
|
||||
/**
|
||||
* Create derived store, which use generates value from another stores.
|
||||
*
|
||||
* ```js
|
||||
* import { batched } from 'nanostores'
|
||||
*
|
||||
* const $sortBy = atom('id')
|
||||
* const $category = atom('')
|
||||
*
|
||||
* export const $link = batched([$sortBy, $category], (sortBy, category) => {
|
||||
* return `/api/entities?sortBy=${sortBy}&category=${category}`
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
<Value, OriginStores extends AnyStore[]>(
|
||||
stores: [...OriginStores],
|
||||
cb: (...values: StoreValues<OriginStores>) => Task<Value> | Value
|
||||
): ReadableAtom<Value>
|
||||
}
|
||||
|
||||
export const batched: Batched
|
||||
56
node_modules/.pnpm/nanostores@1.0.1/node_modules/nanostores/computed/index.js
generated
vendored
Normal file
56
node_modules/.pnpm/nanostores@1.0.1/node_modules/nanostores/computed/index.js
generated
vendored
Normal file
@ -0,0 +1,56 @@
|
||||
import { atom, epoch } from '../atom/index.js'
|
||||
import { onMount } from '../lifecycle/index.js'
|
||||
|
||||
let computedStore = (stores, cb, batched) => {
|
||||
if (!Array.isArray(stores)) stores = [stores]
|
||||
|
||||
let previousArgs
|
||||
let currentEpoch
|
||||
let set = () => {
|
||||
if (currentEpoch === epoch) return
|
||||
currentEpoch = epoch
|
||||
let args = stores.map($store => $store.get())
|
||||
if (!previousArgs || args.some((arg, i) => arg !== previousArgs[i])) {
|
||||
previousArgs = args
|
||||
let value = cb(...args)
|
||||
if (value && value.then && value.t) {
|
||||
value.then(asyncValue => {
|
||||
if (previousArgs === args) {
|
||||
// Prevent a stale set
|
||||
$computed.set(asyncValue)
|
||||
}
|
||||
})
|
||||
} else {
|
||||
$computed.set(value)
|
||||
currentEpoch = epoch
|
||||
}
|
||||
}
|
||||
}
|
||||
let $computed = atom(undefined)
|
||||
let get = $computed.get
|
||||
$computed.get = () => {
|
||||
set()
|
||||
return get()
|
||||
}
|
||||
|
||||
let timer
|
||||
let run = batched
|
||||
? () => {
|
||||
clearTimeout(timer)
|
||||
timer = setTimeout(set)
|
||||
}
|
||||
: set
|
||||
|
||||
onMount($computed, () => {
|
||||
let unbinds = stores.map($store => $store.listen(run))
|
||||
set()
|
||||
return () => {
|
||||
for (let unbind of unbinds) unbind()
|
||||
}
|
||||
})
|
||||
|
||||
return $computed
|
||||
}
|
||||
|
||||
export let computed = (stores, fn) => computedStore(stores, fn)
|
||||
export let batched = (stores, fn) => computedStore(stores, fn, true)
|
||||
127
node_modules/.pnpm/nanostores@1.0.1/node_modules/nanostores/deep-map/index.d.ts
generated
vendored
Normal file
127
node_modules/.pnpm/nanostores@1.0.1/node_modules/nanostores/deep-map/index.d.ts
generated
vendored
Normal file
@ -0,0 +1,127 @@
|
||||
import type { WritableAtom } from '../atom/index.js'
|
||||
import type { AnyStore } from '../map/index.js'
|
||||
import type {
|
||||
AllPaths,
|
||||
BaseDeepMap,
|
||||
FromPath,
|
||||
FromPathWithIndexSignatureUndefined
|
||||
} from './path.js'
|
||||
|
||||
export {
|
||||
AllPaths,
|
||||
BaseDeepMap,
|
||||
FromPath,
|
||||
getPath,
|
||||
setByKey,
|
||||
setPath
|
||||
} from './path.js'
|
||||
|
||||
export type DeepMapStore<T extends BaseDeepMap> = {
|
||||
/**
|
||||
* Subscribe to store changes.
|
||||
*
|
||||
* In contrast with {@link Store#subscribe} it do not call listener
|
||||
* immediately.
|
||||
*
|
||||
* @param listener Callback with store value and old value.
|
||||
* @param changedKey Key that was changed. Will present only if `setKey`
|
||||
* has been used to change a store.
|
||||
* @returns Function to remove listener.
|
||||
*/
|
||||
listen(
|
||||
listener: (
|
||||
value: T,
|
||||
oldValue: T,
|
||||
changedKey: AllPaths<T> | undefined
|
||||
) => void
|
||||
): () => void
|
||||
|
||||
/**
|
||||
* Low-level method to notify listeners about changes in the store.
|
||||
*
|
||||
* Can cause unexpected behaviour when combined with frontend frameworks
|
||||
* doing equality checks for values, e.g. React.
|
||||
*/
|
||||
notify(oldValue?: T, changedKey?: AllPaths<T>): void
|
||||
|
||||
/**
|
||||
* Change key in store value. Copies are made at each level of `key` so that
|
||||
* no part of the original object is mutated (but it does not do a full deep
|
||||
* copy -- some sub-objects may still be shared between the old value and the
|
||||
* new one).
|
||||
*
|
||||
* ```js
|
||||
* $settings.setKey('visuals.theme', 'dark')
|
||||
* ```
|
||||
*
|
||||
* @param key The key name. Attributes can be split with a dot `.` and `[]`.
|
||||
* @param value New value.
|
||||
*/
|
||||
setKey: <K extends AllPaths<T>>(
|
||||
key: K,
|
||||
value: FromPathWithIndexSignatureUndefined<T, K>
|
||||
) => void
|
||||
|
||||
/**
|
||||
* Subscribe to store changes and call listener immediately.
|
||||
*
|
||||
* ```
|
||||
* import { $settings } from '../store'
|
||||
*
|
||||
* $settings.subscribe(settings => {
|
||||
* console.log(settings)
|
||||
* })
|
||||
* ```
|
||||
*
|
||||
* @param listener Callback with store value and old value.
|
||||
* @param changedKey Key that was changed. Will present only
|
||||
* if `setKey` has been used to change a store.
|
||||
* @returns Function to remove listener.
|
||||
*/
|
||||
subscribe(
|
||||
listener: (
|
||||
value: T,
|
||||
oldValue: T | undefined,
|
||||
changedKey: AllPaths<T> | undefined
|
||||
) => void
|
||||
): () => void
|
||||
} & Omit<WritableAtom<T>, 'listen' | 'notify' | 'setKey' | 'subscribe'>
|
||||
|
||||
/**
|
||||
* Create deep map store. Deep map store is a store with an object as store
|
||||
* value, that supports fine-grained reactivity for deeply nested properties.
|
||||
*
|
||||
* @param init Initialize store and return store destructor.
|
||||
* @returns The store object with methods to subscribe.
|
||||
*/
|
||||
export function deepMap<T extends BaseDeepMap>(init?: T): DeepMapStore<T>
|
||||
|
||||
/**
|
||||
* Get a value by key from a store with an object value.
|
||||
* Works with `map`, `deepMap`, and `atom`.
|
||||
*
|
||||
* ```js
|
||||
* import { getKey, map } from 'nanostores'
|
||||
*
|
||||
* const $user = map({ name: 'John', profile: { age: 30 } })
|
||||
*
|
||||
* // Simple key access
|
||||
* getKey($user, 'name') // Returns 'John'
|
||||
*
|
||||
* // Nested access with dot notation
|
||||
* getKey($user, 'profile.age') // Returns 30
|
||||
*
|
||||
* // Array access
|
||||
* const $items = map({ products: ['apple', 'banana'] })
|
||||
* getKey($items, 'products[1]') // Returns 'banana'
|
||||
* ```
|
||||
*
|
||||
* @param store The store to get the value from.
|
||||
* @param key The key to access. Can be a simple key or a path with dot notation.
|
||||
* @returns The value for this key
|
||||
*/
|
||||
|
||||
export function getKey<
|
||||
T extends Record<string, unknown>,
|
||||
K extends AllPaths<T>
|
||||
>(store: AnyStore<T>, key: K): FromPath<T, K>
|
||||
21
node_modules/.pnpm/nanostores@1.0.1/node_modules/nanostores/deep-map/index.js
generated
vendored
Normal file
21
node_modules/.pnpm/nanostores@1.0.1/node_modules/nanostores/deep-map/index.js
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
import { atom } from '../atom/index.js'
|
||||
import { getPath, setPath } from './path.js'
|
||||
|
||||
export { getPath, setByKey, setPath } from './path.js'
|
||||
|
||||
export function deepMap(initial = {}) {
|
||||
let $deepMap = atom(initial)
|
||||
$deepMap.setKey = (key, value) => {
|
||||
if (getPath($deepMap.value, key) !== value) {
|
||||
let oldValue = $deepMap.value
|
||||
$deepMap.value = setPath($deepMap.value, key, value)
|
||||
$deepMap.notify(oldValue, key)
|
||||
}
|
||||
}
|
||||
return $deepMap
|
||||
}
|
||||
|
||||
export function getKey(store, key) {
|
||||
let value = store.get()
|
||||
return getPath(value, key)
|
||||
}
|
||||
169
node_modules/.pnpm/nanostores@1.0.1/node_modules/nanostores/deep-map/path.d.ts
generated
vendored
Normal file
169
node_modules/.pnpm/nanostores@1.0.1/node_modules/nanostores/deep-map/path.d.ts
generated
vendored
Normal file
@ -0,0 +1,169 @@
|
||||
import type { ValueWithUndefinedForIndexSignatures } from '../map/index.js'
|
||||
|
||||
type ConcatPath<T extends string, P extends string> = T extends ''
|
||||
? P
|
||||
: `${T}.${P}`
|
||||
|
||||
type Length<T extends any[]> = T extends { length: infer L } ? L : never
|
||||
|
||||
type BuildTuple<L extends number, T extends any[] = []> = T extends {
|
||||
length: L
|
||||
}
|
||||
? T
|
||||
: BuildTuple<L, [...T, any]>
|
||||
|
||||
type Subtract<A extends number, B extends number> = BuildTuple<A> extends [
|
||||
...infer U,
|
||||
...BuildTuple<B>
|
||||
]
|
||||
? Length<U>
|
||||
: never
|
||||
|
||||
export type AllPaths<
|
||||
T,
|
||||
P extends string = '',
|
||||
MaxDepth extends number = 10
|
||||
> = T extends (infer U)[]
|
||||
?
|
||||
| `${P}[${number}]`
|
||||
| AllPaths<U, `${P}[${number}]`, Subtract<MaxDepth, 1>>
|
||||
| P
|
||||
: T extends BaseDeepMap
|
||||
? MaxDepth extends 0
|
||||
? never
|
||||
: {
|
||||
[K in keyof T]-?: K extends number | string
|
||||
?
|
||||
| AllPaths<T[K], ConcatPath<P, `${K}`>, Subtract<MaxDepth, 1>>
|
||||
| (P extends '' ? never : P)
|
||||
: never
|
||||
}[keyof T]
|
||||
: P
|
||||
|
||||
type IsNumber<T extends string> = T extends `${number}` ? true : false
|
||||
|
||||
type ElementType<T> = T extends (infer U)[] ? U : never
|
||||
|
||||
type Unwrap<T, P> = P extends `[${infer I}]${infer R}`
|
||||
? [ElementType<T>, IsNumber<I>] extends [infer Item, true]
|
||||
? R extends ''
|
||||
? Item
|
||||
: Unwrap<Item, R>
|
||||
: never
|
||||
: never
|
||||
|
||||
type NestedObjKey<T, P> = P extends `${infer A}.${infer B}`
|
||||
? A extends keyof T
|
||||
? FromPath<NonNullable<T[A]>, B>
|
||||
: never
|
||||
: never
|
||||
|
||||
type NestedObjKeyWithIndexSignatureUndefined<T, P> =
|
||||
P extends `${infer A}.${infer B}`
|
||||
? A extends keyof T
|
||||
? FromPathWithIndexSignatureUndefined<NonNullable<T[A]>, B>
|
||||
: never
|
||||
: never
|
||||
|
||||
type NestedArrKey<T, P> = P extends `${infer A}[${infer I}]${infer R}`
|
||||
? [A, NonNullable<T[Extract<A, keyof T>]>, IsNumber<I>] extends [
|
||||
keyof T,
|
||||
(infer Item)[],
|
||||
true
|
||||
]
|
||||
? R extends ''
|
||||
? Item
|
||||
: R extends `.${infer NewR}`
|
||||
? FromPath<Item, NewR>
|
||||
: R extends `${infer Indices}.${infer MoreR}`
|
||||
? FromPath<Unwrap<Item, Indices>, MoreR>
|
||||
: Unwrap<Item, R>
|
||||
: never
|
||||
: never
|
||||
|
||||
export type FromPath<T, P> = T extends unknown
|
||||
? NestedArrKey<T, P> extends never
|
||||
? NestedObjKey<T, P> extends never
|
||||
? P extends keyof T
|
||||
? T[P]
|
||||
: never
|
||||
: NestedObjKey<T, P>
|
||||
: NestedArrKey<T, P>
|
||||
: never
|
||||
|
||||
export type FromPathWithIndexSignatureUndefined<T, P> = T extends unknown
|
||||
? NestedArrKey<T, P> extends never
|
||||
? NestedObjKeyWithIndexSignatureUndefined<T, P> extends never
|
||||
? P extends keyof T
|
||||
? ValueWithUndefinedForIndexSignatures<T, P>
|
||||
: never
|
||||
: NestedObjKeyWithIndexSignatureUndefined<T, P>
|
||||
: NestedArrKey<T, P>
|
||||
: never
|
||||
|
||||
export type BaseDeepMap = Record<string, unknown>
|
||||
|
||||
/**
|
||||
* Get a value by object path. `undefined` if key is missing.
|
||||
*
|
||||
* ```
|
||||
* import { getPath } from 'nanostores'
|
||||
*
|
||||
* getPath({ a: { b: { c: ['hey', 'Hi!'] } } }, 'a.b.c[1]') // Returns 'Hi!'
|
||||
* ```
|
||||
*
|
||||
* @param obj Any object.
|
||||
* @param path Path splitted by dots and `[]`. Like: `props.arr[1].nested`.
|
||||
* @returns The value for this path. Undefined if key is missing.
|
||||
*/
|
||||
export function getPath<T extends BaseDeepMap, K extends AllPaths<T>>(
|
||||
obj: T,
|
||||
path: K
|
||||
): FromPath<T, K>
|
||||
|
||||
/**
|
||||
* Set a deep value by path. Copies are made at each level of `path` so that no
|
||||
* part of the original object is mutated (but it does not do a full deep copy
|
||||
* -- some sub-objects may still be shared between the old value and the new
|
||||
* one). Sparse arrays will be created if you set arbitrary length.
|
||||
*
|
||||
* ```
|
||||
* import { setPath } from 'nanostores'
|
||||
*
|
||||
* setPath({ a: { b: { c: [] } } }, 'a.b.c[1]', 'hey')
|
||||
* // Returns `{ a: { b: { c: [<empty>, 'hey'] } } }`
|
||||
* ```
|
||||
*
|
||||
* @param obj Any object.
|
||||
* @param path Path splitted by dots and `[]`. Like: `props.arr[1].nested`.
|
||||
* @returns The new object.
|
||||
*/
|
||||
export function setPath<T extends BaseDeepMap, K extends AllPaths<T>>(
|
||||
obj: T,
|
||||
path: K,
|
||||
value: FromPath<T, K>
|
||||
): T
|
||||
|
||||
/**
|
||||
* Set a deep value by key. Copies are made at each level of `path` so that no
|
||||
* part of the original object is mutated (but it does not do a full deep copy
|
||||
* -- some sub-objects may still be shared between the old value and the new
|
||||
* one). Sparse arrays will be created if you set arbitrary length.
|
||||
*
|
||||
* ```
|
||||
* import { setByKey } from 'nanostores'
|
||||
*
|
||||
* setByKey({ a: { b: { c: [] } } }, ['a', 'b', 'c', 1], 'hey')
|
||||
* // Returns `{ a: { b: { c: [<empty>, 'hey'] } } }`
|
||||
* ```
|
||||
*
|
||||
* @param obj Any object.
|
||||
* @param splittedKeys An array of keys representing the path to the value.
|
||||
* @param value New value.
|
||||
* @retunts The new object.
|
||||
*/
|
||||
export function setByKey<T extends BaseDeepMap>(
|
||||
obj: T,
|
||||
splittedKeys: PropertyKey[],
|
||||
value: unknown
|
||||
): T
|
||||
64
node_modules/.pnpm/nanostores@1.0.1/node_modules/nanostores/deep-map/path.js
generated
vendored
Normal file
64
node_modules/.pnpm/nanostores@1.0.1/node_modules/nanostores/deep-map/path.js
generated
vendored
Normal file
@ -0,0 +1,64 @@
|
||||
export function getPath(obj, path) {
|
||||
let allKeys = getAllKeysFromPath(path)
|
||||
let res = obj
|
||||
for (let key of allKeys) {
|
||||
if (res === undefined) {
|
||||
break
|
||||
}
|
||||
res = res[key]
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
export function setPath(obj, path, value) {
|
||||
return setByKey(obj != null ? obj : {}, getAllKeysFromPath(path), value)
|
||||
}
|
||||
|
||||
export function setByKey(obj, splittedKeys, value) {
|
||||
let key = splittedKeys[0]
|
||||
let copy = Array.isArray(obj) ? [...obj] : { ...obj }
|
||||
if (splittedKeys.length === 1) {
|
||||
if (value === undefined) {
|
||||
if (Array.isArray(copy)) {
|
||||
copy.splice(key, 1)
|
||||
} else {
|
||||
delete copy[key]
|
||||
}
|
||||
} else {
|
||||
copy[key] = value
|
||||
}
|
||||
return copy
|
||||
}
|
||||
ensureKey(copy, key, splittedKeys[1])
|
||||
copy[key] = setByKey(copy[key], splittedKeys.slice(1), value)
|
||||
return copy
|
||||
}
|
||||
|
||||
const ARRAY_INDEX = /(.*)\[(\d+)\]/
|
||||
|
||||
function getAllKeysFromPath(path) {
|
||||
return path.split('.').flatMap(key => getKeyAndIndicesFromKey(key))
|
||||
}
|
||||
|
||||
function getKeyAndIndicesFromKey(key) {
|
||||
if (ARRAY_INDEX.test(key)) {
|
||||
let [, keyPart, index] = key.match(ARRAY_INDEX)
|
||||
return [...getKeyAndIndicesFromKey(keyPart), index]
|
||||
}
|
||||
return [key]
|
||||
}
|
||||
|
||||
const IS_NUMBER = /^\d+$/
|
||||
function ensureKey(obj, key, nextKey) {
|
||||
if (key in obj) {
|
||||
return
|
||||
}
|
||||
|
||||
let isNum = IS_NUMBER.test(nextKey)
|
||||
|
||||
if (isNum) {
|
||||
obj[key] = Array(parseInt(nextKey, 10) + 1)
|
||||
} else {
|
||||
obj[key] = {}
|
||||
}
|
||||
}
|
||||
34
node_modules/.pnpm/nanostores@1.0.1/node_modules/nanostores/effect/index.d.ts
generated
vendored
Normal file
34
node_modules/.pnpm/nanostores@1.0.1/node_modules/nanostores/effect/index.d.ts
generated
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
import type { StoreValues } from '../computed/index.d.ts'
|
||||
import type { AnyStore, Store, StoreValue } from '../index.js'
|
||||
|
||||
interface Effect {
|
||||
<OriginStore extends Store>(
|
||||
stores: OriginStore,
|
||||
cb: (value: StoreValue<OriginStore>) => void | VoidFunction
|
||||
): VoidFunction
|
||||
/**
|
||||
* Subscribe for multiple stores. Also you can define cleanup function
|
||||
* to call on stores changes.
|
||||
*
|
||||
* ```js
|
||||
* const $enabled = atom(true)
|
||||
* const $interval = atom(1000)
|
||||
*
|
||||
* const cancelPing = effect([$enabled, $interval], (enabled, interval) => {
|
||||
* if (!enabled) return
|
||||
* const intervalId = setInterval(() => {
|
||||
* sendPing()
|
||||
* }, interval)
|
||||
* return () => {
|
||||
* clearInterval(intervalId)
|
||||
* }
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
<OriginStores extends AnyStore[]>(
|
||||
stores: [...OriginStores],
|
||||
cb: (...values: StoreValues<OriginStores>) => void | VoidFunction
|
||||
): VoidFunction
|
||||
}
|
||||
|
||||
export const effect: Effect
|
||||
21
node_modules/.pnpm/nanostores@1.0.1/node_modules/nanostores/effect/index.js
generated
vendored
Normal file
21
node_modules/.pnpm/nanostores@1.0.1/node_modules/nanostores/effect/index.js
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
export let effect = (stores, callback) => {
|
||||
if (!Array.isArray(stores)) stores = [stores]
|
||||
|
||||
let unbinds = []
|
||||
let lastRunUnbind
|
||||
|
||||
let run = () => {
|
||||
lastRunUnbind && lastRunUnbind()
|
||||
|
||||
let values = stores.map(store => store.get())
|
||||
lastRunUnbind = callback(...values)
|
||||
}
|
||||
|
||||
unbinds = stores.map(store => store.listen(run))
|
||||
run()
|
||||
|
||||
return () => {
|
||||
unbinds.forEach(unbind => unbind())
|
||||
lastRunUnbind && lastRunUnbind()
|
||||
}
|
||||
}
|
||||
44
node_modules/.pnpm/nanostores@1.0.1/node_modules/nanostores/index.d.ts
generated
vendored
Normal file
44
node_modules/.pnpm/nanostores@1.0.1/node_modules/nanostores/index.d.ts
generated
vendored
Normal file
@ -0,0 +1,44 @@
|
||||
export {
|
||||
atom,
|
||||
Atom,
|
||||
PreinitializedWritableAtom,
|
||||
ReadableAtom,
|
||||
readonlyType,
|
||||
WritableAtom
|
||||
} from './atom/index.js'
|
||||
export { clean, cleanStores } from './clean-stores/index.js'
|
||||
export { batched, computed } from './computed/index.js'
|
||||
export {
|
||||
AllPaths,
|
||||
BaseDeepMap,
|
||||
deepMap,
|
||||
DeepMapStore,
|
||||
FromPath,
|
||||
getKey,
|
||||
getPath,
|
||||
setByKey,
|
||||
setPath
|
||||
} from './deep-map/index.js'
|
||||
export { effect } from './effect/index.js'
|
||||
export { keepMount } from './keep-mount/index.js'
|
||||
export {
|
||||
onMount,
|
||||
onNotify,
|
||||
onSet,
|
||||
onStart,
|
||||
onStop,
|
||||
STORE_UNMOUNT_DELAY
|
||||
} from './lifecycle/index.js'
|
||||
export { listenKeys, subscribeKeys } from './listen-keys/index.js'
|
||||
export { mapCreator, MapCreator } from './map-creator/index.js'
|
||||
export {
|
||||
AnyStore,
|
||||
map,
|
||||
MapStore,
|
||||
MapStoreKeys,
|
||||
PreinitializedMapStore,
|
||||
Store,
|
||||
StoreValue,
|
||||
WritableStore
|
||||
} from './map/index.js'
|
||||
export { allTasks, cleanTasks, startTask, task, Task } from './task/index.js'
|
||||
24
node_modules/.pnpm/nanostores@1.0.1/node_modules/nanostores/index.js
generated
vendored
Normal file
24
node_modules/.pnpm/nanostores@1.0.1/node_modules/nanostores/index.js
generated
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
export { atom, readonlyType } from './atom/index.js'
|
||||
export { clean, cleanStores } from './clean-stores/index.js'
|
||||
export { batched, computed } from './computed/index.js'
|
||||
export {
|
||||
deepMap,
|
||||
getKey,
|
||||
getPath,
|
||||
setByKey,
|
||||
setPath
|
||||
} from './deep-map/index.js'
|
||||
export { effect } from './effect/index.js'
|
||||
export { keepMount } from './keep-mount/index.js'
|
||||
export {
|
||||
onMount,
|
||||
onNotify,
|
||||
onSet,
|
||||
onStart,
|
||||
onStop,
|
||||
STORE_UNMOUNT_DELAY
|
||||
} from './lifecycle/index.js'
|
||||
export { listenKeys, subscribeKeys } from './listen-keys/index.js'
|
||||
export { mapCreator } from './map-creator/index.js'
|
||||
export { map } from './map/index.js'
|
||||
export { allTasks, cleanTasks, startTask, task } from './task/index.js'
|
||||
17
node_modules/.pnpm/nanostores@1.0.1/node_modules/nanostores/keep-mount/index.d.ts
generated
vendored
Normal file
17
node_modules/.pnpm/nanostores@1.0.1/node_modules/nanostores/keep-mount/index.d.ts
generated
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
import type { MapCreator } from '../map-creator/index.js'
|
||||
import type { Store } from '../map/index.js'
|
||||
|
||||
/**
|
||||
* Prevent destructor call for the store.
|
||||
*
|
||||
* Together with {@link cleanStores} is useful tool for tests.
|
||||
*
|
||||
* ```js
|
||||
* import { keepMount } from 'nanostores'
|
||||
*
|
||||
* keepMount($store)
|
||||
* ```
|
||||
*
|
||||
* @param $store The store.
|
||||
*/
|
||||
export function keepMount($store: MapCreator | Store): void
|
||||
3
node_modules/.pnpm/nanostores@1.0.1/node_modules/nanostores/keep-mount/index.js
generated
vendored
Normal file
3
node_modules/.pnpm/nanostores@1.0.1/node_modules/nanostores/keep-mount/index.js
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
export let keepMount = $store => {
|
||||
$store.listen(() => {})
|
||||
}
|
||||
152
node_modules/.pnpm/nanostores@1.0.1/node_modules/nanostores/lifecycle/index.d.ts
generated
vendored
Normal file
152
node_modules/.pnpm/nanostores@1.0.1/node_modules/nanostores/lifecycle/index.d.ts
generated
vendored
Normal file
@ -0,0 +1,152 @@
|
||||
import type { MapStore, Store, StoreValue } from '../map/index.js'
|
||||
|
||||
type AtomSetPayload<Shared, SomeStore extends Store> = {
|
||||
abort(): void
|
||||
changed: undefined
|
||||
newValue: StoreValue<SomeStore>
|
||||
shared: Shared
|
||||
}
|
||||
|
||||
type MapSetPayload<Shared, SomeStore extends Store> =
|
||||
| {
|
||||
abort(): void
|
||||
changed: keyof StoreValue<SomeStore>
|
||||
newValue: StoreValue<SomeStore>
|
||||
shared: Shared
|
||||
}
|
||||
| AtomSetPayload<Shared, SomeStore>
|
||||
|
||||
type AtomNotifyPayload<Shared, SomeStore extends Store> = {
|
||||
abort(): void
|
||||
changed: undefined
|
||||
oldValue: StoreValue<SomeStore>
|
||||
shared: Shared
|
||||
}
|
||||
|
||||
type MapNotifyPayload<Shared, SomeStore extends Store> =
|
||||
| {
|
||||
abort(): void
|
||||
changed: keyof StoreValue<SomeStore>
|
||||
oldValue: StoreValue<SomeStore>
|
||||
shared: Shared
|
||||
}
|
||||
| AtomNotifyPayload<Shared, SomeStore>
|
||||
|
||||
/**
|
||||
* Add listener to store chagings.
|
||||
*
|
||||
* ```js
|
||||
* import { onSet } from 'nanostores'
|
||||
*
|
||||
* onSet($store, ({ newValue, abort }) => {
|
||||
* if (!validate(newValue)) {
|
||||
* abort()
|
||||
* }
|
||||
* })
|
||||
* ```
|
||||
*
|
||||
* You can communicate between listeners by `payload.shared`
|
||||
* or cancel changes by `payload.abort()`.
|
||||
*
|
||||
* New value of the all store will be `payload.newValue`.
|
||||
* On `MapStore#setKey()` call, changed value will be in `payload.changed`.
|
||||
*
|
||||
* @param $store The store to add listener.
|
||||
* @param listener Event callback.
|
||||
* @returns A function to remove listener.
|
||||
*/
|
||||
export function onSet<Shared = never, SomeStore extends Store = Store>(
|
||||
$store: SomeStore,
|
||||
listener: (
|
||||
payload: SomeStore extends MapStore
|
||||
? MapSetPayload<Shared, SomeStore>
|
||||
: AtomSetPayload<Shared, SomeStore>
|
||||
) => void
|
||||
): () => void
|
||||
|
||||
/**
|
||||
* Add listener to notifying about store changes.
|
||||
*
|
||||
* You can communicate between listeners by `payload.shared`
|
||||
* or cancel changes by `payload.abort()`.
|
||||
*
|
||||
* On `MapStore#setKey()` call, changed value will be in `payload.changed`.
|
||||
*
|
||||
* @param $store The store to add listener.
|
||||
* @param listener Event callback.
|
||||
* @returns A function to remove listener.
|
||||
*/
|
||||
export function onNotify<Shared = never, SomeStore extends Store = Store>(
|
||||
$store: SomeStore,
|
||||
listener: (
|
||||
payload: SomeStore extends MapStore
|
||||
? MapNotifyPayload<Shared, SomeStore>
|
||||
: AtomNotifyPayload<Shared, SomeStore>
|
||||
) => void
|
||||
): () => void
|
||||
|
||||
/**
|
||||
* Add listener on first store listener.
|
||||
*
|
||||
* We recommend to always use `onMount` instead to prevent flickering.
|
||||
* See {@link onMount} to add constructor and destructor for the store.
|
||||
*
|
||||
* You can communicate between listeners by `payload.shared`.
|
||||
*
|
||||
* @param $store The store to add listener.
|
||||
* @param listener Event callback.
|
||||
* @returns A function to remove listener.
|
||||
*/
|
||||
export function onStart<Shared = never>(
|
||||
$store: Store,
|
||||
listener: (payload: { shared: Shared }) => void
|
||||
): () => void
|
||||
|
||||
/**
|
||||
* Add listener on last store listener unsubscription.
|
||||
*
|
||||
* We recommend to always use `onMount` instead to prevent flickering.
|
||||
* See {@link onMount} to add constructor and destructor for the store.
|
||||
*
|
||||
* You can communicate between listeners by `payload.shared`.
|
||||
*
|
||||
* @param $store The store to add listener.
|
||||
* @param listener Event callback.
|
||||
* @returns A function to remove listener.
|
||||
*/
|
||||
export function onStop<Shared = never>(
|
||||
$store: Store,
|
||||
listener: (payload: { shared: Shared }) => void
|
||||
): () => void
|
||||
|
||||
export const STORE_UNMOUNT_DELAY: number
|
||||
|
||||
/**
|
||||
* Run constructor on first store’s listener and run destructor on last listener
|
||||
* unsubscription. It has a debounce to prevent flickering.
|
||||
*
|
||||
* A way to reduce memory and CPU usage when you do not need a store.
|
||||
*
|
||||
* You can communicate between listeners by `payload.shared`.
|
||||
*
|
||||
* ```js
|
||||
* import { onMount } from 'nanostores'
|
||||
*
|
||||
* // Listen for URL changes on first store’s listener.
|
||||
* onMount($router, () => {
|
||||
* parse()
|
||||
* window.addEventListener('popstate', parse)
|
||||
* return () => {
|
||||
* window.removeEventListener('popstate', parse)
|
||||
* }
|
||||
* })
|
||||
* ```
|
||||
*
|
||||
* @param $store Store to listen.
|
||||
* @param initialize Store constructor. Returns store destructor.
|
||||
* @return A function to remove constructor and destructor from store.
|
||||
*/
|
||||
export function onMount<Shared = never>(
|
||||
$store: Store,
|
||||
initialize?: (payload: { shared: Shared }) => (() => void) | void
|
||||
): () => void
|
||||
160
node_modules/.pnpm/nanostores@1.0.1/node_modules/nanostores/lifecycle/index.js
generated
vendored
Normal file
160
node_modules/.pnpm/nanostores@1.0.1/node_modules/nanostores/lifecycle/index.js
generated
vendored
Normal file
@ -0,0 +1,160 @@
|
||||
import { clean } from '../clean-stores/index.js'
|
||||
|
||||
const START = 0
|
||||
const STOP = 1
|
||||
const SET = 2
|
||||
const NOTIFY = 3
|
||||
const MOUNT = 5
|
||||
const UNMOUNT = 6
|
||||
const REVERT_MUTATION = 10
|
||||
|
||||
export let on = (object, listener, eventKey, mutateStore) => {
|
||||
object.events = object.events || {}
|
||||
if (!object.events[eventKey + REVERT_MUTATION]) {
|
||||
object.events[eventKey + REVERT_MUTATION] = mutateStore(eventProps => {
|
||||
// eslint-disable-next-line no-sequences
|
||||
object.events[eventKey].reduceRight((event, l) => (l(event), event), {
|
||||
shared: {},
|
||||
...eventProps
|
||||
})
|
||||
})
|
||||
}
|
||||
object.events[eventKey] = object.events[eventKey] || []
|
||||
object.events[eventKey].push(listener)
|
||||
return () => {
|
||||
let currentListeners = object.events[eventKey]
|
||||
let index = currentListeners.indexOf(listener)
|
||||
currentListeners.splice(index, 1)
|
||||
if (!currentListeners.length) {
|
||||
delete object.events[eventKey]
|
||||
object.events[eventKey + REVERT_MUTATION]()
|
||||
delete object.events[eventKey + REVERT_MUTATION]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export let onStart = ($store, listener) =>
|
||||
on($store, listener, START, runListeners => {
|
||||
let originListen = $store.listen
|
||||
$store.listen = arg => {
|
||||
if (!$store.lc && !$store.starting) {
|
||||
$store.starting = true
|
||||
runListeners()
|
||||
delete $store.starting
|
||||
}
|
||||
return originListen(arg)
|
||||
}
|
||||
return () => {
|
||||
$store.listen = originListen
|
||||
}
|
||||
})
|
||||
|
||||
export let onStop = ($store, listener) =>
|
||||
on($store, listener, STOP, runListeners => {
|
||||
let originOff = $store.off
|
||||
$store.off = () => {
|
||||
runListeners()
|
||||
originOff()
|
||||
}
|
||||
return () => {
|
||||
$store.off = originOff
|
||||
}
|
||||
})
|
||||
|
||||
export let onSet = ($store, listener) =>
|
||||
on($store, listener, SET, runListeners => {
|
||||
let originSet = $store.set
|
||||
let originSetKey = $store.setKey
|
||||
if ($store.setKey) {
|
||||
$store.setKey = (changed, changedValue) => {
|
||||
let isAborted
|
||||
let abort = () => {
|
||||
isAborted = true
|
||||
}
|
||||
|
||||
runListeners({
|
||||
abort,
|
||||
changed,
|
||||
newValue: { ...$store.value, [changed]: changedValue }
|
||||
})
|
||||
if (!isAborted) return originSetKey(changed, changedValue)
|
||||
}
|
||||
}
|
||||
$store.set = newValue => {
|
||||
let isAborted
|
||||
let abort = () => {
|
||||
isAborted = true
|
||||
}
|
||||
|
||||
runListeners({ abort, newValue })
|
||||
if (!isAborted) return originSet(newValue)
|
||||
}
|
||||
return () => {
|
||||
$store.set = originSet
|
||||
$store.setKey = originSetKey
|
||||
}
|
||||
})
|
||||
|
||||
export let onNotify = ($store, listener) =>
|
||||
on($store, listener, NOTIFY, runListeners => {
|
||||
let originNotify = $store.notify
|
||||
$store.notify = (oldValue, changed) => {
|
||||
let isAborted
|
||||
let abort = () => {
|
||||
isAborted = true
|
||||
}
|
||||
|
||||
runListeners({ abort, changed, oldValue })
|
||||
if (!isAborted) return originNotify(oldValue, changed)
|
||||
}
|
||||
return () => {
|
||||
$store.notify = originNotify
|
||||
}
|
||||
})
|
||||
|
||||
export let STORE_UNMOUNT_DELAY = 1000
|
||||
|
||||
export let onMount = ($store, initialize) => {
|
||||
let listener = payload => {
|
||||
let destroy = initialize(payload)
|
||||
if (destroy) $store.events[UNMOUNT].push(destroy)
|
||||
}
|
||||
return on($store, listener, MOUNT, runListeners => {
|
||||
let originListen = $store.listen
|
||||
$store.listen = (...args) => {
|
||||
if (!$store.lc && !$store.active) {
|
||||
$store.active = true
|
||||
runListeners()
|
||||
}
|
||||
return originListen(...args)
|
||||
}
|
||||
|
||||
let originOff = $store.off
|
||||
$store.events[UNMOUNT] = []
|
||||
$store.off = () => {
|
||||
originOff()
|
||||
setTimeout(() => {
|
||||
if ($store.active && !$store.lc) {
|
||||
$store.active = false
|
||||
for (let destroy of $store.events[UNMOUNT]) destroy()
|
||||
$store.events[UNMOUNT] = []
|
||||
}
|
||||
}, STORE_UNMOUNT_DELAY)
|
||||
}
|
||||
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
let originClean = $store[clean]
|
||||
$store[clean] = () => {
|
||||
for (let destroy of $store.events[UNMOUNT]) destroy()
|
||||
$store.events[UNMOUNT] = []
|
||||
$store.active = false
|
||||
originClean()
|
||||
}
|
||||
}
|
||||
|
||||
return () => {
|
||||
$store.listen = originListen
|
||||
$store.off = originOff
|
||||
}
|
||||
})
|
||||
}
|
||||
75
node_modules/.pnpm/nanostores@1.0.1/node_modules/nanostores/listen-keys/index.d.ts
generated
vendored
Normal file
75
node_modules/.pnpm/nanostores@1.0.1/node_modules/nanostores/listen-keys/index.d.ts
generated
vendored
Normal file
@ -0,0 +1,75 @@
|
||||
import type { StoreValue } from '../map/index.js'
|
||||
|
||||
/**
|
||||
* Listen for specific keys of the store.
|
||||
*
|
||||
* In contrast with {@link subscribeKeys} it do not call listener
|
||||
* immediately.
|
||||
* ```js
|
||||
* import { listenKeys } from 'nanostores'
|
||||
*
|
||||
* listenKeys($page, ['blocked'], (value, oldValue, changed) => {
|
||||
* if (value.blocked) {
|
||||
* console.log('You has no access')
|
||||
* }
|
||||
* })
|
||||
* ```
|
||||
*
|
||||
* @param $store The store to listen.
|
||||
* @param keys The keys to listen.
|
||||
* @param listener Standard listener.
|
||||
*/
|
||||
export function listenKeys<
|
||||
SomeStore extends { setKey: (key: any, value: any) => void }
|
||||
>(
|
||||
$store: SomeStore,
|
||||
keys: SomeStore extends { setKey: (key: infer Key, value: never) => unknown }
|
||||
? readonly Key[]
|
||||
: never,
|
||||
listener: (
|
||||
value: StoreValue<SomeStore>,
|
||||
oldValue: StoreValue<SomeStore>,
|
||||
changed: SomeStore extends {
|
||||
setKey: (key: infer Key, value: never) => unknown
|
||||
}
|
||||
? Key[]
|
||||
: never
|
||||
) => void
|
||||
): () => void
|
||||
|
||||
/**
|
||||
* Listen for specific keys of the store and call listener immediately.
|
||||
* Note that the oldValue and changed arguments in the listener are
|
||||
* undefined during the initial call.
|
||||
*
|
||||
* ```js
|
||||
* import { subscribeKeys } from 'nanostores'
|
||||
*
|
||||
* subscribeKeys($page, ['blocked'], (value, oldValue, changed) => {
|
||||
* if (value.blocked) {
|
||||
* console.log('You has no access')
|
||||
* }
|
||||
* })
|
||||
* ```
|
||||
*
|
||||
* @param $store The store to listen.
|
||||
* @param keys The keys to listen.
|
||||
* @param listener Standard listener.
|
||||
*/
|
||||
export function subscribeKeys<
|
||||
SomeStore extends { setKey: (key: any, value: any) => void }
|
||||
>(
|
||||
$store: SomeStore,
|
||||
keys: SomeStore extends { setKey: (key: infer Key, value: never) => unknown }
|
||||
? readonly Key[]
|
||||
: never,
|
||||
listener: (
|
||||
value: StoreValue<SomeStore>,
|
||||
oldValue: StoreValue<SomeStore>,
|
||||
changed: SomeStore extends {
|
||||
setKey: (key: infer Key, value: never) => unknown
|
||||
}
|
||||
? Key[]
|
||||
: never
|
||||
) => void
|
||||
): () => void
|
||||
14
node_modules/.pnpm/nanostores@1.0.1/node_modules/nanostores/listen-keys/index.js
generated
vendored
Normal file
14
node_modules/.pnpm/nanostores@1.0.1/node_modules/nanostores/listen-keys/index.js
generated
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
export function listenKeys($store, keys, listener) {
|
||||
let keysSet = new Set(keys).add(undefined)
|
||||
return $store.listen((value, oldValue, changed) => {
|
||||
if (keysSet.has(changed)) {
|
||||
listener(value, oldValue, changed)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export function subscribeKeys($store, keys, listener) {
|
||||
let unbind = listenKeys($store, keys, listener)
|
||||
listener($store.value)
|
||||
return unbind
|
||||
}
|
||||
29
node_modules/.pnpm/nanostores@1.0.1/node_modules/nanostores/map-creator/index.d.ts
generated
vendored
Normal file
29
node_modules/.pnpm/nanostores@1.0.1/node_modules/nanostores/map-creator/index.d.ts
generated
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
import type { MapStore } from '../map/index.js'
|
||||
|
||||
export interface MapCreator<
|
||||
Value extends object = any,
|
||||
Args extends any[] = []
|
||||
> {
|
||||
(id: string, ...args: Args): MapStore<Value>
|
||||
build(id: string, ...args: Args): MapStore<Value>
|
||||
cache: {
|
||||
[id: string]: MapStore<{ id: string } & Value>
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create function to create map stores. It will be like a class for store.
|
||||
*
|
||||
* @param init Store’s initializer. Returns store destructor.
|
||||
*/
|
||||
export function mapCreator<
|
||||
Value extends object,
|
||||
Args extends any[] = [],
|
||||
StoreExt = Record<number | string | symbol, any>
|
||||
>(
|
||||
init?: (
|
||||
store: MapStore<{ id: string } & Value> & StoreExt,
|
||||
id: string,
|
||||
...args: Args
|
||||
) => (() => void) | void
|
||||
): MapCreator<Value, Args>
|
||||
38
node_modules/.pnpm/nanostores@1.0.1/node_modules/nanostores/map-creator/index.js
generated
vendored
Normal file
38
node_modules/.pnpm/nanostores@1.0.1/node_modules/nanostores/map-creator/index.js
generated
vendored
Normal file
@ -0,0 +1,38 @@
|
||||
import { clean } from '../clean-stores/index.js'
|
||||
import { onMount } from '../lifecycle/index.js'
|
||||
import { map } from '../map/index.js'
|
||||
|
||||
export function mapCreator(init) {
|
||||
let Creator = (id, ...args) => {
|
||||
if (!Creator.cache[id]) {
|
||||
Creator.cache[id] = Creator.build(id, ...args)
|
||||
}
|
||||
return Creator.cache[id]
|
||||
}
|
||||
|
||||
Creator.build = (id, ...args) => {
|
||||
let store = map({ id })
|
||||
onMount(store, () => {
|
||||
let destroy
|
||||
if (init) destroy = init(store, id, ...args)
|
||||
return () => {
|
||||
delete Creator.cache[id]
|
||||
if (destroy) destroy()
|
||||
}
|
||||
})
|
||||
return store
|
||||
}
|
||||
|
||||
Creator.cache = {}
|
||||
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
Creator[clean] = () => {
|
||||
for (let id in Creator.cache) {
|
||||
Creator.cache[id][clean]()
|
||||
}
|
||||
Creator.cache = {}
|
||||
}
|
||||
}
|
||||
|
||||
return Creator
|
||||
}
|
||||
149
node_modules/.pnpm/nanostores@1.0.1/node_modules/nanostores/map/index.d.ts
generated
vendored
Normal file
149
node_modules/.pnpm/nanostores@1.0.1/node_modules/nanostores/map/index.d.ts
generated
vendored
Normal file
@ -0,0 +1,149 @@
|
||||
import type {
|
||||
AllKeys,
|
||||
ReadableAtom,
|
||||
ReadonlyIfObject,
|
||||
WritableAtom
|
||||
} from '../atom/index.js'
|
||||
|
||||
type KeyofBase = keyof any
|
||||
|
||||
type Get<T, K extends KeyofBase> = Extract<T, { [K1 in K]: any }>[K]
|
||||
|
||||
export type HasIndexSignature<T> = string extends keyof T ? true : false
|
||||
|
||||
export type ValueWithUndefinedForIndexSignatures<
|
||||
Value,
|
||||
Key extends keyof Value
|
||||
> = HasIndexSignature<Value> extends true ? undefined | Value[Key] : Value[Key]
|
||||
|
||||
export type WritableStore<Value = any> =
|
||||
| (Value extends object ? MapStore<Value> : never)
|
||||
| WritableAtom<Value>
|
||||
|
||||
export type Store<Value = any> = ReadableAtom<Value> | WritableStore<Value>
|
||||
|
||||
export type AnyStore<Value = any> = {
|
||||
get(): Value
|
||||
readonly value: undefined | Value
|
||||
}
|
||||
|
||||
export type StoreValue<SomeStore> = SomeStore extends {
|
||||
get(): infer Value
|
||||
}
|
||||
? Value
|
||||
: any
|
||||
|
||||
export type BaseMapStore<Value = any> = {
|
||||
setKey: (key: any, value: any) => any
|
||||
} & WritableAtom<Value>
|
||||
|
||||
export type MapStoreKeys<SomeStore> = SomeStore extends {
|
||||
setKey: (key: infer K, ...args: any[]) => any
|
||||
}
|
||||
? K
|
||||
: AllKeys<StoreValue<SomeStore>>
|
||||
|
||||
export interface MapStore<Value extends object = any>
|
||||
extends WritableAtom<Value> {
|
||||
/**
|
||||
* Subscribe to store changes.
|
||||
*
|
||||
* In contrast with {@link Store#subscribe} it do not call listener
|
||||
* immediately.
|
||||
*
|
||||
* @param listener Callback with store value and old value.
|
||||
* @param changedKey Key that was changed. Will present only if `setKey`
|
||||
* has been used to change a store.
|
||||
* @returns Function to remove listener.
|
||||
*/
|
||||
listen(
|
||||
listener: (
|
||||
value: ReadonlyIfObject<Value>,
|
||||
oldValue: ReadonlyIfObject<Value>,
|
||||
changedKey: AllKeys<Value>
|
||||
) => void
|
||||
): () => void
|
||||
|
||||
/**
|
||||
* Low-level method to notify listeners about changes in the store.
|
||||
*
|
||||
* Can cause unexpected behaviour when combined with frontend frameworks
|
||||
* that perform equality checks for values, such as React.
|
||||
*/
|
||||
notify(oldValue?: ReadonlyIfObject<Value>, changedKey?: AllKeys<Value>): void
|
||||
|
||||
/**
|
||||
* Change store value.
|
||||
*
|
||||
* ```js
|
||||
* $settings.set({ theme: 'dark' })
|
||||
* ```
|
||||
*
|
||||
* Operation is atomic, subscribers will be notified once with the new value.
|
||||
* `changedKey` will be undefined
|
||||
*
|
||||
* @param newValue New store value.
|
||||
*/
|
||||
set(newValue: Value): void
|
||||
|
||||
/**
|
||||
* Change key in store value.
|
||||
*
|
||||
* ```js
|
||||
* $settings.setKey('theme', 'dark')
|
||||
* ```
|
||||
*
|
||||
* To delete key set `undefined`.
|
||||
*
|
||||
* ```js
|
||||
* $settings.setKey('theme', undefined)
|
||||
* ```
|
||||
*
|
||||
* @param key The key name.
|
||||
* @param value New value.
|
||||
*/
|
||||
setKey<Key extends AllKeys<Value>>(
|
||||
key: Key,
|
||||
value: Get<Value, Key> | ValueWithUndefinedForIndexSignatures<Value, Key>
|
||||
): void
|
||||
|
||||
/**
|
||||
* Subscribe to store changes and call listener immediately.
|
||||
*
|
||||
* ```
|
||||
* import { $router } from '../store'
|
||||
*
|
||||
* $router.subscribe(page => {
|
||||
* console.log(page)
|
||||
* })
|
||||
* ```
|
||||
*
|
||||
* @param listener Callback with store value and old value.
|
||||
* @param changedKey Key that was changed. Will present only
|
||||
* if `setKey` has been used to change a store.
|
||||
* @returns Function to remove listener.
|
||||
*/
|
||||
subscribe(
|
||||
listener: (
|
||||
value: ReadonlyIfObject<Value>,
|
||||
oldValue: ReadonlyIfObject<Value> | undefined,
|
||||
changedKey: AllKeys<Value> | undefined
|
||||
) => void
|
||||
): () => void
|
||||
}
|
||||
|
||||
export interface PreinitializedMapStore<Value extends object = any>
|
||||
extends MapStore<Value> {
|
||||
readonly value: Value
|
||||
}
|
||||
|
||||
/**
|
||||
* Create map store. Map store is a store with key-value object
|
||||
* as a store value.
|
||||
*
|
||||
* @param init Initialize store and return store destructor.
|
||||
* @returns The store object with methods to subscribe.
|
||||
*/
|
||||
export function map<Value extends object, StoreExt extends object = object>(
|
||||
value?: Value
|
||||
): PreinitializedMapStore<Value> & StoreExt
|
||||
22
node_modules/.pnpm/nanostores@1.0.1/node_modules/nanostores/map/index.js
generated
vendored
Normal file
22
node_modules/.pnpm/nanostores@1.0.1/node_modules/nanostores/map/index.js
generated
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
import { atom } from '../atom/index.js'
|
||||
|
||||
export let map = (initial = {}) => {
|
||||
let $map = atom(initial)
|
||||
|
||||
$map.setKey = function (key, value) {
|
||||
let oldMap = $map.value
|
||||
if (typeof value === 'undefined' && key in $map.value) {
|
||||
$map.value = { ...$map.value }
|
||||
delete $map.value[key]
|
||||
$map.notify(oldMap, key)
|
||||
} else if ($map.value[key] !== value) {
|
||||
$map.value = {
|
||||
...$map.value,
|
||||
[key]: value
|
||||
}
|
||||
$map.notify(oldMap, key)
|
||||
}
|
||||
}
|
||||
|
||||
return $map
|
||||
}
|
||||
34
node_modules/.pnpm/nanostores@1.0.1/node_modules/nanostores/package.json
generated
vendored
Normal file
34
node_modules/.pnpm/nanostores@1.0.1/node_modules/nanostores/package.json
generated
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
{
|
||||
"name": "nanostores",
|
||||
"version": "1.0.1",
|
||||
"description": "A tiny (265 bytes) state manager for React/Preact/Vue/Svelte with many atomic tree-shakable stores",
|
||||
"keywords": [
|
||||
"store",
|
||||
"state",
|
||||
"state manager",
|
||||
"react",
|
||||
"react native",
|
||||
"preact",
|
||||
"vue",
|
||||
"svelte"
|
||||
],
|
||||
"author": "Andrey Sitnik <andrey@sitnik.ru>",
|
||||
"license": "MIT",
|
||||
"repository": "nanostores/nanostores",
|
||||
"sideEffects": false,
|
||||
"type": "module",
|
||||
"types": "./index.d.ts",
|
||||
"exports": {
|
||||
".": "./index.js",
|
||||
"./package.json": "./package.json"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^20.0.0 || >=22.0.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ai"
|
||||
}
|
||||
]
|
||||
}
|
||||
76
node_modules/.pnpm/nanostores@1.0.1/node_modules/nanostores/task/index.d.ts
generated
vendored
Normal file
76
node_modules/.pnpm/nanostores@1.0.1/node_modules/nanostores/task/index.d.ts
generated
vendored
Normal file
@ -0,0 +1,76 @@
|
||||
export interface Task<Value> extends Promise<Value> {
|
||||
t: true
|
||||
}
|
||||
|
||||
/**
|
||||
* Track store async task by start/end functions.
|
||||
* It is useful for test to wait end of the processing.
|
||||
*
|
||||
* It you use `async`/`await` in task, you can use {@link task}.
|
||||
*
|
||||
* ```ts
|
||||
* import { startTask } from 'nanostores'
|
||||
*
|
||||
* function saveUser () {
|
||||
* const endTask = startTask()
|
||||
* api.submit('/user', user.get(), () => {
|
||||
* $user.setKey('saved', true)
|
||||
* endTask()
|
||||
* })
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
export function startTask(): () => void
|
||||
|
||||
/**
|
||||
* Track store async task by wrapping promise callback.
|
||||
* It is useful for test to wait end of the processing.
|
||||
*
|
||||
* ```ts
|
||||
* import { task } from 'nanostores'
|
||||
*
|
||||
* async function saveUser () {
|
||||
* await task(async () => {
|
||||
* await api.submit('/user', user.get())
|
||||
* $user.setKey('saved', true)
|
||||
* })
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* @param cb Async callback with task.
|
||||
* @return Return value from callback.
|
||||
*/
|
||||
export function task<Return = never>(
|
||||
cb: () => Promise<Return> | Return
|
||||
): Task<Return>
|
||||
|
||||
/**
|
||||
* Return Promise until all current tasks (and tasks created while waiting).
|
||||
*
|
||||
* It is useful in tests to wait all async processes in the stores.
|
||||
*
|
||||
* ```ts
|
||||
* import { allTasks } from 'nanostores'
|
||||
*
|
||||
* it('saves user', async () => {
|
||||
* saveUser()
|
||||
* await allTasks()
|
||||
* expect($user.get().saved).toBe(true)
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
export function allTasks(): Promise<void>
|
||||
|
||||
/**
|
||||
* Forget all tracking tasks. Use it only for tests.
|
||||
* {@link cleanStores} cleans tasks automatically.
|
||||
*
|
||||
* ```js
|
||||
* import { cleanTasks } from 'nanostores'
|
||||
*
|
||||
* afterEach(() => {
|
||||
* cleanTasks()
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
export function cleanTasks(): void
|
||||
35
node_modules/.pnpm/nanostores@1.0.1/node_modules/nanostores/task/index.js
generated
vendored
Normal file
35
node_modules/.pnpm/nanostores@1.0.1/node_modules/nanostores/task/index.js
generated
vendored
Normal file
@ -0,0 +1,35 @@
|
||||
let tasks = 0
|
||||
let resolves = []
|
||||
|
||||
export function startTask() {
|
||||
tasks += 1
|
||||
return () => {
|
||||
tasks -= 1
|
||||
if (tasks === 0) {
|
||||
let prevResolves = resolves
|
||||
resolves = []
|
||||
for (let i of prevResolves) i()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function task(cb) {
|
||||
let endTask = startTask()
|
||||
let promise = cb().finally(endTask)
|
||||
promise.t = true
|
||||
return promise
|
||||
}
|
||||
|
||||
export function allTasks() {
|
||||
if (tasks === 0) {
|
||||
return Promise.resolve()
|
||||
} else {
|
||||
return new Promise(resolve => {
|
||||
resolves.push(resolve)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export function cleanTasks() {
|
||||
tasks = 0
|
||||
}
|
||||
Reference in New Issue
Block a user