@kdeveloper/kvark 0.6.9 → 0.8.0
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 +154 -12
- package/dist/{atom-BC8W-H22.d.ts → atom-DfZiw6GT.d.ts} +2 -2
- package/dist/{atom-BC8W-H22.d.ts.map → atom-DfZiw6GT.d.ts.map} +1 -1
- package/dist/family.d.ts +4 -4
- package/dist/family.d.ts.map +1 -1
- package/dist/family.js +2 -2
- package/dist/index.d.ts +3 -3
- package/dist/index.js +2 -2
- package/dist/preact/index.d.ts +42 -0
- package/dist/preact/index.d.ts.map +1 -0
- package/dist/preact/index.js +116 -0
- package/dist/preact/index.js.map +1 -0
- package/dist/react/index.d.ts +5 -2
- package/dist/react/index.d.ts.map +1 -1
- package/dist/react/index.js +7 -1
- package/dist/react/index.js.map +1 -1
- package/dist/{store-Cng0OzIQ.d.ts → store-DLoedZQo.d.ts} +19 -3
- package/dist/store-DLoedZQo.d.ts.map +1 -0
- package/dist/{store-DuKg4_ng.js → store-DvSUP7R9.js} +60 -3
- package/dist/store-DvSUP7R9.js.map +1 -0
- package/dist/types-B2mzc3A5.js.map +1 -1
- package/dist/vue/index.d.ts +5 -2
- package/dist/vue/index.d.ts.map +1 -1
- package/dist/vue/index.js +7 -1
- package/dist/vue/index.js.map +1 -1
- package/package.json +11 -1
- package/dist/store-Cng0OzIQ.d.ts.map +0 -1
- package/dist/store-DuKg4_ng.js.map +0 -1
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/@kdeveloper/kvark)
|
|
4
4
|
|
|
5
|
-
Atomic state management for **React** and **Vue 3** with **explicit dependency graphs**, stale-while-revalidate, and first-class external invalidation.
|
|
5
|
+
Atomic state management for **React**, **Preact**, and **Vue 3** with **explicit dependency graphs**, stale-while-revalidate, and first-class external invalidation.
|
|
6
6
|
|
|
7
7
|
Inspired by Jotai, but built around a key difference: dependencies are declared upfront rather than inferred at runtime. This makes the data graph statically analysable, enables parallel loading, and allows invalidation from anywhere — WebSocket handlers, SSE streams, timers, Service Workers — without framework hooks.
|
|
8
8
|
|
|
@@ -23,7 +23,7 @@ Inspired by Jotai, but built around a key difference: dependencies are declared
|
|
|
23
23
|
|
|
24
24
|
```bash
|
|
25
25
|
pnpm add @kdeveloper/kvark
|
|
26
|
-
# optional peers: react >=18 and/or vue >=3.4
|
|
26
|
+
# optional peers: react >=18, preact >=10, and/or vue >=3.4
|
|
27
27
|
```
|
|
28
28
|
|
|
29
29
|
## Quick Start
|
|
@@ -70,6 +70,16 @@ function UserCard() {
|
|
|
70
70
|
}
|
|
71
71
|
```
|
|
72
72
|
|
|
73
|
+
### Preact
|
|
74
|
+
|
|
75
|
+
The same atoms and store work with `@kdeveloper/kvark/preact` — the API is identical to the React integration. Replace the React import with the Preact one:
|
|
76
|
+
|
|
77
|
+
```tsx
|
|
78
|
+
import { Provider, useAtomValue, useSetAtom } from "@kdeveloper/kvark/preact";
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Hooks use only `preact` and `preact/hooks` internally — no `preact/compat` aliases required.
|
|
82
|
+
|
|
73
83
|
### Vue 3
|
|
74
84
|
|
|
75
85
|
The same atoms and store work with `@kdeveloper/kvark/vue`. Composables mirror the React hooks; `useAtomValue` returns an **awaitable** [`shallowRef`](https://vuejs.org/api/reactivity-advanced.html#shallowref) — use `.value` in `<script setup>` (templates unwrap refs automatically). Until the first `get` resolves, that ref’s value is `undefined`; TypeScript types it as `V | undefined` (`ThenableShallowRef<V>`). After `await useAtomValue(atom)` you get `Readonly<ShallowRef<V>>` with a defined `.value`. The ref also implements `PromiseLike`, so awaiting it in an async `setup` suspends until the first `get` resolves — see [Suspense (Vue 3)](#suspense-vue-3).
|
|
@@ -192,6 +202,8 @@ The `ctx` passed to `set` provides:
|
|
|
192
202
|
- **`ctx.get(key)`** — read any declared dependency (same as in `get`).
|
|
193
203
|
- **`ctx.signal`** — an `AbortSignal` tied to the atom's lifecycle, useful for cancelling in-flight requests.
|
|
194
204
|
- **`ctx.setOptimisticValue(value)`** — synchronously update the atom's cached value before the async work completes (see below). Also accepts a mutator `(prev) => next`.
|
|
205
|
+
- **`ctx.writeOptimistic(atom, value)`** — synchronously write into another atom's cache with automatic rollback on error (see [Dependent mutations](#dependent-mutations)). Also accepts a mutator.
|
|
206
|
+
- **`ctx.invalidate(atom)`** / **`ctx.invalidateMany(atoms)`** — mark unrelated atoms as stale so they refetch (see [Dependent mutations](#dependent-mutations)).
|
|
195
207
|
|
|
196
208
|
#### Optimistic updates
|
|
197
209
|
|
|
@@ -226,6 +238,112 @@ set: async (ctx) => {
|
|
|
226
238
|
|
|
227
239
|
If the `PUT` fails, the atom reverts to whatever value `get` had loaded before the optimistic update — no manual rollback needed.
|
|
228
240
|
|
|
241
|
+
#### Dependent mutations
|
|
242
|
+
|
|
243
|
+
The `ctx` inside `set` also provides methods for cross-atom side-effects:
|
|
244
|
+
|
|
245
|
+
- **`ctx.invalidate(atom)`** — mark another atom as `stale` and schedule a refetch. Does **not** participate in rollback; best called after the async work succeeds.
|
|
246
|
+
- **`ctx.invalidateMany(atoms)`** — same as `invalidate`, but for multiple atoms at once.
|
|
247
|
+
- **`ctx.writeOptimistic(atom, value | mutator)`** — synchronously write a value into another atom's cache (same semantics as `store.write`). If the mutation throws, the store rolls back **all** atoms touched by `writeOptimistic` together with the primary atom's `setOptimisticValue`.
|
|
248
|
+
|
|
249
|
+
A common pattern is a list atom alongside per-item atoms managed by `atomFamily`. Mutating an item should optimistically patch the list and then invalidate it after the request succeeds:
|
|
250
|
+
|
|
251
|
+
```ts
|
|
252
|
+
const todosListAtom = atom({
|
|
253
|
+
debugLabel: "todosList",
|
|
254
|
+
get: async () => {
|
|
255
|
+
const res = await fetch("/api/todos");
|
|
256
|
+
return res.json() as Promise<Todo[]>;
|
|
257
|
+
},
|
|
258
|
+
});
|
|
259
|
+
|
|
260
|
+
const todoAtom = atomFamily({
|
|
261
|
+
debugLabel: "todo",
|
|
262
|
+
get: (id: number) => async () => {
|
|
263
|
+
const res = await fetch(`/api/todos/${id}`);
|
|
264
|
+
return res.json() as Promise<Todo>;
|
|
265
|
+
},
|
|
266
|
+
set: (id: number) => async (ctx, patch: Partial<Todo>) => {
|
|
267
|
+
ctx.setOptimisticValue((prev) => ({ ...prev!, ...patch }));
|
|
268
|
+
ctx.writeOptimistic(todosListAtom, (list) =>
|
|
269
|
+
list?.map((t) => (t.id === id ? { ...t, ...patch } : t)),
|
|
270
|
+
);
|
|
271
|
+
await fetch(`/api/todos/${id}`, {
|
|
272
|
+
method: "PATCH",
|
|
273
|
+
body: JSON.stringify(patch),
|
|
274
|
+
signal: ctx.signal,
|
|
275
|
+
});
|
|
276
|
+
ctx.invalidate(todosListAtom);
|
|
277
|
+
},
|
|
278
|
+
});
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
If the `PATCH` fails, both the item and the list revert to their pre-optimistic state. After success, `invalidate(todosListAtom)` triggers a background refetch to reconcile with the server.
|
|
282
|
+
|
|
283
|
+
#### Standalone mutations (`mutation`)
|
|
284
|
+
|
|
285
|
+
Sometimes a server action updates **several** atoms at once, and there is no single writable atom that should own the mutation. Use **`mutation(fn)`** to define that work once, then run it with **`store.mutate(m, ...args)`** or **`useMutation(m)`** in components.
|
|
286
|
+
|
|
287
|
+
The callback receives a **`MutationContext`** (the same optimistic and invalidation helpers as in `set`, but **without** `setOptimisticValue`, `ctx.get`, or `ctx.signal` — pass server inputs as mutation arguments, and use `store.get` / `client.get` beforehand if you need current values):
|
|
288
|
+
|
|
289
|
+
- **`ctx.writeOptimistic(atom, value | mutator)`** — same semantics as inside `set`. On throw, every atom touched by `writeOptimistic` rolls back to its state before the first optimistic write in this run.
|
|
290
|
+
- **`ctx.invalidate` / `ctx.invalidateMany`** — mark atoms stale (not rolled back on error).
|
|
291
|
+
|
|
292
|
+
Unlike **`set`**, a successful **`mutate` does not invalidate any atom automatically**. Call `ctx.invalidate` / `ctx.invalidateMany` when you want stale-while-revalidate after the request completes.
|
|
293
|
+
|
|
294
|
+
```ts
|
|
295
|
+
import { atom, mutation, createStore } from "@kdeveloper/kvark";
|
|
296
|
+
|
|
297
|
+
const listAtom = atom({
|
|
298
|
+
debugLabel: "list",
|
|
299
|
+
get: async () => {
|
|
300
|
+
const res = await fetch("/api/items");
|
|
301
|
+
return res.json() as Promise<string[]>;
|
|
302
|
+
},
|
|
303
|
+
});
|
|
304
|
+
|
|
305
|
+
const countAtom = atom({
|
|
306
|
+
debugLabel: "count",
|
|
307
|
+
get: async () => {
|
|
308
|
+
const res = await fetch("/api/count");
|
|
309
|
+
return (await res.json()) as { n: number };
|
|
310
|
+
},
|
|
311
|
+
});
|
|
312
|
+
|
|
313
|
+
const addItem = mutation(async (ctx, label: string) => {
|
|
314
|
+
ctx.writeOptimistic(listAtom, (prev) => [...(prev ?? []), label]);
|
|
315
|
+
ctx.writeOptimistic(countAtom, (prev) => ({ n: (prev?.n ?? 0) + 1 }));
|
|
316
|
+
await fetch("/api/items", {
|
|
317
|
+
method: "POST",
|
|
318
|
+
body: JSON.stringify({ label }),
|
|
319
|
+
});
|
|
320
|
+
ctx.invalidateMany([listAtom, countAtom]);
|
|
321
|
+
});
|
|
322
|
+
|
|
323
|
+
const store = createStore();
|
|
324
|
+
await store.mutate(addItem, "new row");
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
**React / Preact / Vue**
|
|
328
|
+
|
|
329
|
+
```tsx
|
|
330
|
+
import { useMutation } from "@kdeveloper/kvark/react"; // or "@kdeveloper/kvark/preact"
|
|
331
|
+
|
|
332
|
+
const runAddItem = useMutation(addItem);
|
|
333
|
+
|
|
334
|
+
await runAddItem("new row");
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
```vue
|
|
338
|
+
<script setup lang="ts">
|
|
339
|
+
import { useMutation } from "@kdeveloper/kvark/vue";
|
|
340
|
+
|
|
341
|
+
const runAddItem = useMutation(addItem);
|
|
342
|
+
</script>
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
`useMutation` returns a stable function (React/Preact: `useCallback` over `store.mutate`) with the same argument tuple as your mutation.
|
|
346
|
+
|
|
229
347
|
#### Writable atoms vs `onMount`
|
|
230
348
|
|
|
231
349
|
Both can update an atom's cached value, but they serve different purposes:
|
|
@@ -393,6 +511,15 @@ const setCount = useSetAtom(countAtom);
|
|
|
393
511
|
await setCount(42);
|
|
394
512
|
```
|
|
395
513
|
|
|
514
|
+
### `useMutation`
|
|
515
|
+
|
|
516
|
+
Returns a function that runs a **`mutation(...)`** descriptor against the store, with the same `...args` as the mutation callback (after `ctx`). Does not subscribe to any atom.
|
|
517
|
+
|
|
518
|
+
```tsx
|
|
519
|
+
const runReorder = useMutation(reorderMutation);
|
|
520
|
+
await runReorder(itemId, newIndex);
|
|
521
|
+
```
|
|
522
|
+
|
|
396
523
|
### `useAtom`
|
|
397
524
|
|
|
398
525
|
Combines `useAtomValue` and `useSetAtom` into a `[value, setter]` tuple.
|
|
@@ -414,9 +541,15 @@ const readBalance = useAtomContext(async (client) => {
|
|
|
414
541
|
const balance = await readBalance();
|
|
415
542
|
```
|
|
416
543
|
|
|
544
|
+
## Preact (`@kdeveloper/kvark/preact`)
|
|
545
|
+
|
|
546
|
+
Same hook names, signatures, and behaviour as the React integration: `Provider`, `useStore`, `useAtomValue`, `useSetAtom`, `useMutation`, `useAtom`, `useAtomContext`. All hooks must be used inside a `<Provider>`.
|
|
547
|
+
|
|
548
|
+
Internally the entry imports only from `preact` and `preact/hooks` — there is **no dependency on `preact/compat`**, so your app does not need any React compatibility aliases.
|
|
549
|
+
|
|
417
550
|
## Vue 3 (`@kdeveloper/kvark/vue`)
|
|
418
551
|
|
|
419
|
-
Same composable names and behaviour as React: `Provider`, `useStore`, `useAtomValue`, `useSetAtom`, `useAtom`, `useAtomContext`. Wrap your app (or subtree) with `Provider` and pass `:store="store"`.
|
|
552
|
+
Same composable names and behaviour as React: `Provider`, `useStore`, `useAtomValue`, `useSetAtom`, `useMutation`, `useAtom`, `useAtomContext`. Wrap your app (or subtree) with `Provider` and pass `:store="store"`.
|
|
420
553
|
|
|
421
554
|
Exported types: **`ThenableShallowRef<V>`** (default `useAtomValue`), **`ThenableObservedShallowRef<V>`** and **`ObservedValue<V>`** (with `{ observe: true }`). They encode pending vs resolved ref shapes for TypeScript.
|
|
422
555
|
|
|
@@ -546,10 +679,15 @@ client.write(counterAtom, (prev) => (prev ?? 0) + 1);
|
|
|
546
679
|
|
|
547
680
|
### `StoreClient` interface
|
|
548
681
|
|
|
682
|
+
The concrete `Store` class exposes the same surface as `getClient()` — e.g. `store.mutate(m, ...args)` and `client.mutate(m, ...args)`.
|
|
683
|
+
|
|
549
684
|
```ts
|
|
685
|
+
import type { Atom, WritableAtom, AtomState, Mutation } from "@kdeveloper/kvark";
|
|
686
|
+
|
|
550
687
|
interface StoreClient {
|
|
551
688
|
get<V>(atom: Atom<V>): Promise<V>;
|
|
552
689
|
set<V, A extends readonly unknown[]>(atom: WritableAtom<V, A>, ...args: A): Promise<void>;
|
|
690
|
+
mutate<Args extends readonly unknown[]>(mutation: Mutation<Args>, ...args: Args): Promise<void>;
|
|
553
691
|
write<V>(atom: Atom<V>, value: V): void;
|
|
554
692
|
write<V>(atom: Atom<V>, mutate: (prev: V | undefined) => V): void;
|
|
555
693
|
invalidate(atom: Atom<unknown>): void;
|
|
@@ -560,7 +698,7 @@ interface StoreClient {
|
|
|
560
698
|
|
|
561
699
|
## Provider and Store Setup
|
|
562
700
|
|
|
563
|
-
**React**
|
|
701
|
+
**React / Preact**
|
|
564
702
|
|
|
565
703
|
```tsx
|
|
566
704
|
// store.ts
|
|
@@ -568,7 +706,7 @@ import { createStore } from "@kdeveloper/kvark";
|
|
|
568
706
|
export const store = createStore();
|
|
569
707
|
|
|
570
708
|
// App.tsx
|
|
571
|
-
import { Provider } from "@kdeveloper/kvark/react";
|
|
709
|
+
import { Provider } from "@kdeveloper/kvark/react"; // or "@kdeveloper/kvark/preact"
|
|
572
710
|
import { store } from "./store";
|
|
573
711
|
|
|
574
712
|
export function App() {
|
|
@@ -607,16 +745,19 @@ type PostArgs = AtomArgs<typeof postAtom>; // → [postId: number]
|
|
|
607
745
|
type Writable = IsWritable<typeof countAtom>; // → true | false
|
|
608
746
|
```
|
|
609
747
|
|
|
748
|
+
`WritableAtomContext` extends `MutationContext` — the same `writeOptimistic` / `invalidate` / `invalidateMany` helpers appear on both standalone mutations and writable `set` callbacks.
|
|
749
|
+
|
|
610
750
|
## Package Structure
|
|
611
751
|
|
|
612
|
-
| Import | Contents
|
|
613
|
-
| -------------------------- |
|
|
614
|
-
| `@kdeveloper/kvark` | `atom`, `createStore`, all types
|
|
615
|
-
| `@kdeveloper/kvark/react`
|
|
616
|
-
| `@kdeveloper/kvark/
|
|
617
|
-
| `@kdeveloper/kvark/
|
|
752
|
+
| Import | Contents |
|
|
753
|
+
| -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
754
|
+
| `@kdeveloper/kvark` | `atom`, `mutation`, `createStore`, all types (including `Mutation`, `MutationContext`) |
|
|
755
|
+
| `@kdeveloper/kvark/react` | `Provider`, `useStore`, `useAtomValue`, `useSetAtom`, `useMutation`, `useAtom`, `useAtomContext` |
|
|
756
|
+
| `@kdeveloper/kvark/preact` | `Provider`, `useStore`, `useAtomValue`, `useSetAtom`, `useMutation`, `useAtom`, `useAtomContext` |
|
|
757
|
+
| `@kdeveloper/kvark/vue` | `Provider`, `useStore`, `useAtomValue`, `useSetAtom`, `useMutation`, `useAtom`, `useAtomContext`; types `ThenableShallowRef`, `ThenableObservedShallowRef`, `ObservedValue` |
|
|
758
|
+
| `@kdeveloper/kvark/family` | `atomFamily`, `stableFamilyKey`, re-exports `atom`, `mutation`, `createStore`; types include `AtomFamily`, `Mutation`, `MutationContext`, and core atom types |
|
|
618
759
|
|
|
619
|
-
The core (`@kdeveloper/kvark`) has **zero runtime dependencies**. **React** and **Vue** are optional peer dependencies — install the framework you use and import from `/react
|
|
760
|
+
The core (`@kdeveloper/kvark`) has **zero runtime dependencies**. **React**, **Preact**, and **Vue** are optional peer dependencies — install the framework you use and import from `/react`, `/preact`, or `/vue`.
|
|
620
761
|
|
|
621
762
|
The published package is **ESM-only** (`import`); there is no CommonJS `require` entry.
|
|
622
763
|
|
|
@@ -639,6 +780,7 @@ Useful variants: `pnpm test:watch`, `pnpm lint:fix`, `pnpm fmt:check`, `pnpm lin
|
|
|
639
780
|
- **Node.js** ≥ 20
|
|
640
781
|
- **TypeScript** ≥ 6 (strict mode recommended)
|
|
641
782
|
- **React** ≥ 18 (optional peer, for `@kdeveloper/kvark/react`)
|
|
783
|
+
- **Preact** ≥ 10 (optional peer, for `@kdeveloper/kvark/preact`)
|
|
642
784
|
- **Vue** ≥ 3.4 (optional peer, for `@kdeveloper/kvark/vue`)
|
|
643
785
|
|
|
644
786
|
## License
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { c as AtomConfig, g as WritableAtomContext, h as WritableAtom, o as Atom } from "./store-DLoedZQo.js";
|
|
2
2
|
|
|
3
3
|
//#region src/internal/atom.d.ts
|
|
4
4
|
type WritableConfig<Value, Deps extends Record<string, Atom<unknown>>, Args extends readonly unknown[]> = AtomConfig<Value, Deps, Args> & {
|
|
@@ -9,4 +9,4 @@ declare function atom<Value, Deps extends Record<string, Atom<unknown>> = Record
|
|
|
9
9
|
declare function atom<Value, Deps extends Record<string, Atom<unknown>> = Record<never, never>>(config: ReadonlyConfig<Value, Deps>): Atom<Value>;
|
|
10
10
|
//#endregion
|
|
11
11
|
export { atom as t };
|
|
12
|
-
//# sourceMappingURL=atom-
|
|
12
|
+
//# sourceMappingURL=atom-DfZiw6GT.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"atom-
|
|
1
|
+
{"version":3,"file":"atom-DfZiw6GT.d.ts","names":[],"sources":["../src/internal/atom.ts"],"mappings":";;;KASK,cAAA,qBAEU,MAAA,SAAe,IAAA,+CAE1B,UAAA,CAAW,KAAA,EAAO,IAAA,EAAM,IAAA;EAC1B,GAAA,GAAM,GAAA,EAAK,mBAAA,CAAoB,IAAA,EAAM,KAAA,MAAW,IAAA,EAAM,IAAA,KAAS,OAAA;AAAA;AAAA,KAG5D,cAAA,qBAAmC,MAAA,SAAe,IAAA,cAAkB,IAAA,CACvE,UAAA,CAAW,KAAA,EAAO,IAAA;AAAA,iBAIJ,IAAA,qBAED,MAAA,SAAe,IAAA,aAAiB,MAAA,8DAAA,CAE7C,MAAA,EAAQ,cAAA,CAAe,KAAA,EAAO,IAAA,EAAM,IAAA,IAAQ,YAAA,CAAa,KAAA,EAAO,IAAA;AAAA,iBAElD,IAAA,qBAAyB,MAAA,SAAe,IAAA,aAAiB,MAAA,eAAA,CACvE,MAAA,EAAQ,cAAA,CAAe,KAAA,EAAO,IAAA,IAC7B,IAAA,CAAK,KAAA"}
|
package/dist/family.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { c as
|
|
2
|
-
import { t as atom } from "./atom-
|
|
1
|
+
import { a as mutation, c as AtomConfig, d as AtomValue, g as WritableAtomContext, h as WritableAtom, i as Mutation, l as AtomContext, m as StalePolicy, o as Atom, p as MutationContext, r as createStore, u as AtomState } from "./store-DLoedZQo.js";
|
|
2
|
+
import { t as atom } from "./atom-DfZiw6GT.js";
|
|
3
3
|
|
|
4
4
|
//#region src/internal/family.d.ts
|
|
5
5
|
type AtomFamilyOptions<Param, Value, Deps extends Record<string, Atom<unknown>>, Args extends readonly unknown[], Key = Param> = {
|
|
@@ -20,7 +20,7 @@ type AtomFamilyOptions<Param, Value, Deps extends Record<string, Atom<unknown>>,
|
|
|
20
20
|
*/
|
|
21
21
|
paramKey?: (param: Param) => Key;
|
|
22
22
|
get: (param: Param) => (ctx: AtomContext<Deps>) => Promise<Value>;
|
|
23
|
-
set?: (param: Param) => (ctx:
|
|
23
|
+
set?: (param: Param) => (ctx: WritableAtomContext<Deps, Value>, ...args: Args) => Promise<void>;
|
|
24
24
|
};
|
|
25
25
|
interface AtomFamily<Param, Value, Key = Param> {
|
|
26
26
|
(param: Param): Atom<Value>;
|
|
@@ -45,5 +45,5 @@ declare function atomFamily<Param, Value, Deps extends Record<string, Atom<unkno
|
|
|
45
45
|
*/
|
|
46
46
|
declare function stableFamilyKey(value: unknown): string;
|
|
47
47
|
//#endregion
|
|
48
|
-
export { type Atom, type AtomConfig, type AtomContext, type AtomFamily, type AtomFamilyOptions, type AtomState, type AtomValue, type StalePolicy, type WritableAtom, atom, atomFamily, createStore, stableFamilyKey };
|
|
48
|
+
export { type Atom, type AtomConfig, type AtomContext, type AtomFamily, type AtomFamilyOptions, type AtomState, type AtomValue, type Mutation, type MutationContext, type StalePolicy, type WritableAtom, atom, atomFamily, createStore, mutation, stableFamilyKey };
|
|
49
49
|
//# sourceMappingURL=family.d.ts.map
|
package/dist/family.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"family.d.ts","names":[],"sources":["../src/internal/family.ts","../src/internal/stable-family-key.ts"],"mappings":";;;;KAKY,iBAAA,4BAGG,MAAA,SAAe,IAAA,mDAEtB,KAAA;EAEN,YAAA,IAAgB,KAAA,EAAO,KAAA,KAAU,IAAA;EACjC,WAAA,GAAc,WAAA;EACd,WAAA;EACA,OAAA;EACA,UAAA;EAR4B;;;;;;;;;;EAmB5B,QAAA,IAAY,KAAA,EAAO,KAAA,KAAU,GAAA;EAC7B,GAAA,GAAM,KAAA,EAAO,KAAA,MAAW,GAAA,EAAK,WAAA,CAAY,IAAA,MAAU,OAAA,CAAQ,KAAA;EAC3D,GAAA,IAAO,KAAA,EAAO,KAAA,MAAW,GAAA,EAAK,
|
|
1
|
+
{"version":3,"file":"family.d.ts","names":[],"sources":["../src/internal/family.ts","../src/internal/stable-family-key.ts"],"mappings":";;;;KAKY,iBAAA,4BAGG,MAAA,SAAe,IAAA,mDAEtB,KAAA;EAEN,YAAA,IAAgB,KAAA,EAAO,KAAA,KAAU,IAAA;EACjC,WAAA,GAAc,WAAA;EACd,WAAA;EACA,OAAA;EACA,UAAA;EAR4B;;;;;;;;;;EAmB5B,QAAA,IAAY,KAAA,EAAO,KAAA,KAAU,GAAA;EAC7B,GAAA,GAAM,KAAA,EAAO,KAAA,MAAW,GAAA,EAAK,WAAA,CAAY,IAAA,MAAU,OAAA,CAAQ,KAAA;EAC3D,GAAA,IAAO,KAAA,EAAO,KAAA,MAAW,GAAA,EAAK,mBAAA,CAAoB,IAAA,EAAM,KAAA,MAAW,IAAA,EAAM,IAAA,KAAS,OAAA;AAAA;AAAA,UAGnE,UAAA,qBAA+B,KAAA;EAAA,CAC7C,KAAA,EAAO,KAAA,GAAQ,IAAA,CAAK,KAAA;EACrB,UAAA,CAAW,KAAA,EAAO,KAAA;EAClB,aAAA;EACA,MAAA,CAAO,KAAA,EAAO,KAAA;EACd,QAAA,IAAY,WAAA,CAAY,GAAA,EAAK,IAAA,CAAK,KAAA;AAAA;AAAA,iBAYpB,UAAA,4BAGD,MAAA,SAAe,IAAA,aAAiB,MAAA,qEAEvC,KAAA,CAAA,CACN,OAAA,EAAS,iBAAA,CAAkB,KAAA,EAAO,KAAA,EAAO,IAAA,EAAM,IAAA,EAAM,GAAA,IAAO,UAAA,CAAW,KAAA,EAAO,KAAA,EAAO,GAAA;;;;;;;AAlDvF;;;;;;;iBC0BgB,eAAA,CAAgB,KAAA"}
|
package/dist/family.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as
|
|
1
|
+
import { i as atom, n as mutation, r as atomFamily, t as createStore } from "./store-DvSUP7R9.js";
|
|
2
2
|
//#region src/internal/stable-family-key.ts
|
|
3
3
|
/**
|
|
4
4
|
* Produces a deterministic string key for plain-object/array/primitive values.
|
|
@@ -54,6 +54,6 @@ function serializeValue(value) {
|
|
|
54
54
|
}).join(",")}}`;
|
|
55
55
|
}
|
|
56
56
|
//#endregion
|
|
57
|
-
export { atom, atomFamily, createStore, stableFamilyKey };
|
|
57
|
+
export { atom, atomFamily, createStore, mutation, stableFamilyKey };
|
|
58
58
|
|
|
59
59
|
//# sourceMappingURL=family.js.map
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { a as
|
|
2
|
-
import { t as atom } from "./atom-
|
|
3
|
-
export { type Atom, type AtomArgs, type AtomConfig, type AtomContext, type AtomState, type AtomValue, type IsWritable, type StalePolicy, type StoreClient, type WritableAtom, type WritableAtomContext, atom, createStore };
|
|
1
|
+
import { a as mutation, c as AtomConfig, d as AtomValue, f as IsWritable, g as WritableAtomContext, h as WritableAtom, i as Mutation, l as AtomContext, m as StalePolicy, n as StoreClient, o as Atom, p as MutationContext, r as createStore, s as AtomArgs, u as AtomState } from "./store-DLoedZQo.js";
|
|
2
|
+
import { t as atom } from "./atom-DfZiw6GT.js";
|
|
3
|
+
export { type Atom, type AtomArgs, type AtomConfig, type AtomContext, type AtomState, type AtomValue, type IsWritable, type Mutation, type MutationContext, type StalePolicy, type StoreClient, type WritableAtom, type WritableAtomContext, atom, createStore, mutation };
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export { atom, createStore };
|
|
1
|
+
import { i as atom, n as mutation, t as createStore } from "./store-DvSUP7R9.js";
|
|
2
|
+
export { atom, createStore, mutation };
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { h as WritableAtom, i as Mutation, n as StoreClient, o as Atom, t as Store } from "../store-DLoedZQo.js";
|
|
2
|
+
import { ComponentChildren, VNode } from "preact";
|
|
3
|
+
|
|
4
|
+
//#region src/preact/provider.d.ts
|
|
5
|
+
type ProviderProps = {
|
|
6
|
+
store: Store;
|
|
7
|
+
children: ComponentChildren;
|
|
8
|
+
};
|
|
9
|
+
declare function Provider({
|
|
10
|
+
store,
|
|
11
|
+
children
|
|
12
|
+
}: ProviderProps): VNode;
|
|
13
|
+
declare function useStore(): Store;
|
|
14
|
+
//#endregion
|
|
15
|
+
//#region src/preact/use-atom-value.d.ts
|
|
16
|
+
type ObservedValue<V> = {
|
|
17
|
+
value: V;
|
|
18
|
+
isStale: boolean;
|
|
19
|
+
error: unknown;
|
|
20
|
+
};
|
|
21
|
+
declare function useAtomValue<V>(atom: Atom<V>): V;
|
|
22
|
+
declare function useAtomValue<V>(atom: Atom<V>, opts: {
|
|
23
|
+
observe: true;
|
|
24
|
+
}): ObservedValue<V>;
|
|
25
|
+
//#endregion
|
|
26
|
+
//#region src/preact/use-set-atom.d.ts
|
|
27
|
+
declare function useSetAtom<V, A extends readonly unknown[]>(atom: WritableAtom<V, A>): (...args: A) => Promise<void>;
|
|
28
|
+
//#endregion
|
|
29
|
+
//#region src/preact/use-mutation.d.ts
|
|
30
|
+
declare function useMutation<Args extends readonly unknown[]>(mutation: Mutation<Args>): (...args: Args) => Promise<void>;
|
|
31
|
+
//#endregion
|
|
32
|
+
//#region src/preact/use-atom.d.ts
|
|
33
|
+
declare function useAtom<V, A extends readonly unknown[]>(atom: WritableAtom<V, A>): readonly [V, (...args: A) => Promise<void>];
|
|
34
|
+
//#endregion
|
|
35
|
+
//#region src/preact/use-atom-context.d.ts
|
|
36
|
+
declare function useAtomContext<R>(callback: (ctx: StoreClient) => Promise<R>): () => Promise<R>;
|
|
37
|
+
//#endregion
|
|
38
|
+
//#region src/preact/use-stable-fn.d.ts
|
|
39
|
+
declare function useStableFn<Args extends unknown[], R>(fn: (...args: Args) => R): (...args: Args) => R;
|
|
40
|
+
//#endregion
|
|
41
|
+
export { Provider, useAtom, useAtomContext, useAtomValue, useMutation, useSetAtom, useStableFn, useStore };
|
|
42
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../../src/preact/provider.tsx","../../src/preact/use-atom-value.ts","../../src/preact/use-set-atom.ts","../../src/preact/use-mutation.ts","../../src/preact/use-atom.ts","../../src/preact/use-atom-context.ts","../../src/preact/use-stable-fn.ts"],"mappings":";;;;KAOY,aAAA;EACV,KAAA,EAAO,KAAA;EACP,QAAA,EAAU,iBAAA;AAAA;AAAA,iBAGI,QAAA,CAAA;EAAW,KAAA;EAAO;AAAA,GAAY,aAAA,GAAgB,KAAA;AAAA,iBAI9C,QAAA,CAAA,GAAY,KAAA;;;KCVvB,aAAA;EACH,KAAA,EAAO,CAAA;EACP,OAAA;EACA,KAAA;AAAA;AAAA,iBAGc,YAAA,GAAA,CAAgB,IAAA,EAAM,IAAA,CAAK,CAAA,IAAK,CAAA;AAAA,iBAChC,YAAA,GAAA,CAAgB,IAAA,EAAM,IAAA,CAAK,CAAA,GAAI,IAAA;EAAQ,OAAA;AAAA,IAAkB,aAAA,CAAc,CAAA;;;iBCTvE,UAAA,iCAAA,CACd,IAAA,EAAM,YAAA,CAAa,CAAA,EAAG,CAAA,QACjB,IAAA,EAAM,CAAA,KAAM,OAAA;;;iBCFH,WAAA,iCAAA,CACd,QAAA,EAAU,QAAA,CAAS,IAAA,QACd,IAAA,EAAM,IAAA,KAAS,OAAA;;;iBCFN,OAAA,iCAAA,CACd,IAAA,EAAM,YAAA,CAAa,CAAA,EAAG,CAAA,cACX,CAAA,MAAO,IAAA,EAAM,CAAA,KAAM,OAAA;;;iBCFhB,cAAA,GAAA,CAAkB,QAAA,GAAW,GAAA,EAAK,WAAA,KAAgB,OAAA,CAAQ,CAAA,UAAW,OAAA,CAAQ,CAAA;;;iBCF7E,WAAA,2BAAA,CACd,EAAA,MAAQ,IAAA,EAAM,IAAA,KAAS,CAAA,OAClB,IAAA,EAAM,IAAA,KAAS,CAAA"}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { t as CONFIG } from "../types-B2mzc3A5.js";
|
|
2
|
+
import { createContext } from "preact";
|
|
3
|
+
import { useCallback, useContext, useEffect, useLayoutEffect, useRef, useState } from "preact/hooks";
|
|
4
|
+
import { jsx } from "preact/jsx-runtime";
|
|
5
|
+
//#region src/preact/provider.tsx
|
|
6
|
+
/** @jsxImportSource preact */
|
|
7
|
+
const StoreContext = createContext(null);
|
|
8
|
+
function Provider({ store, children }) {
|
|
9
|
+
return /* @__PURE__ */ jsx(StoreContext.Provider, {
|
|
10
|
+
value: store,
|
|
11
|
+
children
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
function useStore() {
|
|
15
|
+
const store = useContext(StoreContext);
|
|
16
|
+
if (store == null) throw new Error("useStore must be used within a <Provider>");
|
|
17
|
+
return store;
|
|
18
|
+
}
|
|
19
|
+
//#endregion
|
|
20
|
+
//#region src/preact/use-sync-external-store.ts
|
|
21
|
+
function didSnapshotChange(inst) {
|
|
22
|
+
try {
|
|
23
|
+
return !Object.is(inst._value, inst._getSnapshot());
|
|
24
|
+
} catch {
|
|
25
|
+
return true;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
function useSyncExternalStore(subscribe, getSnapshot) {
|
|
29
|
+
const value = getSnapshot();
|
|
30
|
+
const [{ _instance }, forceUpdate] = useState(() => ({ _instance: {
|
|
31
|
+
_value: value,
|
|
32
|
+
_getSnapshot: getSnapshot
|
|
33
|
+
} }));
|
|
34
|
+
useLayoutEffect(() => {
|
|
35
|
+
_instance._value = value;
|
|
36
|
+
_instance._getSnapshot = getSnapshot;
|
|
37
|
+
if (didSnapshotChange(_instance)) forceUpdate({ _instance });
|
|
38
|
+
}, [
|
|
39
|
+
subscribe,
|
|
40
|
+
value,
|
|
41
|
+
getSnapshot
|
|
42
|
+
]);
|
|
43
|
+
useEffect(() => {
|
|
44
|
+
if (didSnapshotChange(_instance)) forceUpdate({ _instance });
|
|
45
|
+
return subscribe(() => {
|
|
46
|
+
if (didSnapshotChange(_instance)) forceUpdate({ _instance });
|
|
47
|
+
});
|
|
48
|
+
}, [subscribe]);
|
|
49
|
+
return value;
|
|
50
|
+
}
|
|
51
|
+
//#endregion
|
|
52
|
+
//#region src/preact/use-stable-fn.ts
|
|
53
|
+
function useStableFn(fn) {
|
|
54
|
+
const ref = useRef(fn);
|
|
55
|
+
ref.current = fn;
|
|
56
|
+
return useCallback((...args) => ref.current(...args), []);
|
|
57
|
+
}
|
|
58
|
+
//#endregion
|
|
59
|
+
//#region src/preact/use-atom-value.ts
|
|
60
|
+
function useAtomValue(atom, opts) {
|
|
61
|
+
const store = useStore();
|
|
62
|
+
const snapshot = useSyncExternalStore(useStableFn((notify) => store.subscribe(atom, notify)), useStableFn(() => store.getSnapshot(atom)));
|
|
63
|
+
const stalePolicy = atom[CONFIG].stalePolicy ?? "keep";
|
|
64
|
+
if (snapshot.status === "pending") throw store.resolve(atom);
|
|
65
|
+
if (snapshot.status === "stale") {
|
|
66
|
+
if (stalePolicy === "suspend") throw store.resolve(atom);
|
|
67
|
+
store.resolve(atom);
|
|
68
|
+
if (opts?.observe === true) return {
|
|
69
|
+
value: snapshot.value,
|
|
70
|
+
isStale: true,
|
|
71
|
+
error: void 0
|
|
72
|
+
};
|
|
73
|
+
return snapshot.value;
|
|
74
|
+
}
|
|
75
|
+
if (snapshot.status === "error") {
|
|
76
|
+
if (opts?.observe === true && snapshot.value !== void 0) return {
|
|
77
|
+
value: snapshot.value,
|
|
78
|
+
isStale: false,
|
|
79
|
+
error: snapshot.error
|
|
80
|
+
};
|
|
81
|
+
throw snapshot.error;
|
|
82
|
+
}
|
|
83
|
+
if (opts?.observe === true) return {
|
|
84
|
+
value: snapshot.value,
|
|
85
|
+
isStale: false,
|
|
86
|
+
error: void 0
|
|
87
|
+
};
|
|
88
|
+
return snapshot.value;
|
|
89
|
+
}
|
|
90
|
+
//#endregion
|
|
91
|
+
//#region src/preact/use-set-atom.ts
|
|
92
|
+
function useSetAtom(atom) {
|
|
93
|
+
const store = useStore();
|
|
94
|
+
return useCallback((...args) => store.set(atom, ...args), [store, atom]);
|
|
95
|
+
}
|
|
96
|
+
//#endregion
|
|
97
|
+
//#region src/preact/use-mutation.ts
|
|
98
|
+
function useMutation(mutation) {
|
|
99
|
+
const store = useStore();
|
|
100
|
+
return useCallback((...args) => store.mutate(mutation, ...args), [store, mutation]);
|
|
101
|
+
}
|
|
102
|
+
//#endregion
|
|
103
|
+
//#region src/preact/use-atom.ts
|
|
104
|
+
function useAtom(atom) {
|
|
105
|
+
return [useAtomValue(atom), useSetAtom(atom)];
|
|
106
|
+
}
|
|
107
|
+
//#endregion
|
|
108
|
+
//#region src/preact/use-atom-context.ts
|
|
109
|
+
function useAtomContext(callback) {
|
|
110
|
+
const store = useStore();
|
|
111
|
+
return useCallback(() => callback(store.getClient()), [store, callback]);
|
|
112
|
+
}
|
|
113
|
+
//#endregion
|
|
114
|
+
export { Provider, useAtom, useAtomContext, useAtomValue, useMutation, useSetAtom, useStableFn, useStore };
|
|
115
|
+
|
|
116
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../src/preact/provider.tsx","../../src/preact/use-sync-external-store.ts","../../src/preact/use-stable-fn.ts","../../src/preact/use-atom-value.ts","../../src/preact/use-set-atom.ts","../../src/preact/use-mutation.ts","../../src/preact/use-atom.ts","../../src/preact/use-atom-context.ts"],"sourcesContent":["/** @jsxImportSource preact */\nimport { createContext, type ComponentChildren, type VNode } from \"preact\";\nimport { useContext } from \"preact/hooks\";\nimport type { Store } from \"@/internal/store.js\";\n\nconst StoreContext = createContext<Store | null>(null);\n\nexport type ProviderProps = {\n store: Store;\n children: ComponentChildren;\n};\n\nexport function Provider({ store, children }: ProviderProps): VNode {\n return <StoreContext.Provider value={store}>{children}</StoreContext.Provider>;\n}\n\nexport function useStore(): Store {\n const store = useContext(StoreContext);\n if (store == null) {\n throw new Error(\"useStore must be used within a <Provider>\");\n }\n return store;\n}\n","import { useState, useLayoutEffect, useEffect } from \"preact/hooks\";\n\n// Typed shim for useSyncExternalStore using only preact/hooks,\n// based on React's client shim that Preact ships in preact/compat.\n\ntype StoreInstance<T> = { _value: T; _getSnapshot: () => T };\n\nfunction didSnapshotChange<T>(inst: StoreInstance<T>): boolean {\n try {\n return !Object.is(inst._value, inst._getSnapshot());\n } catch {\n return true;\n }\n}\n\nexport function useSyncExternalStore<T>(\n subscribe: (onStoreChange: () => void) => () => void,\n getSnapshot: () => T,\n): T {\n const value = getSnapshot();\n\n const [{ _instance }, forceUpdate] = useState(() => ({\n _instance: { _value: value, _getSnapshot: getSnapshot } as StoreInstance<T>,\n }));\n\n useLayoutEffect(() => {\n _instance._value = value;\n _instance._getSnapshot = getSnapshot;\n\n if (didSnapshotChange(_instance)) {\n forceUpdate({ _instance });\n }\n }, [subscribe, value, getSnapshot]);\n\n useEffect(() => {\n if (didSnapshotChange(_instance)) {\n forceUpdate({ _instance });\n }\n\n return subscribe(() => {\n if (didSnapshotChange(_instance)) {\n forceUpdate({ _instance });\n }\n });\n }, [subscribe]);\n\n return value;\n}\n","import { useCallback, useRef } from \"preact/hooks\";\n\nexport function useStableFn<Args extends unknown[], R>(\n fn: (...args: Args) => R,\n): (...args: Args) => R {\n const ref = useRef(fn);\n ref.current = fn;\n\n return useCallback((...args: Args) => ref.current(...args), []);\n}\n","import { useSyncExternalStore } from \"@/preact/use-sync-external-store.js\";\nimport type { Atom, AtomState, StalePolicy } from \"@/internal/types.js\";\nimport { CONFIG } from \"@/internal/types.js\";\nimport { useStore } from \"@/preact/provider.js\";\nimport { useStableFn } from \"@/preact/use-stable-fn.js\";\n\ntype ObservedValue<V> = {\n value: V;\n isStale: boolean;\n error: unknown;\n};\n\nexport function useAtomValue<V>(atom: Atom<V>): V;\nexport function useAtomValue<V>(atom: Atom<V>, opts: { observe: true }): ObservedValue<V>;\nexport function useAtomValue<V>(atom: Atom<V>, opts?: { observe: true }): V | ObservedValue<V> {\n const store = useStore();\n\n const subscribe = useStableFn((notify: () => void) => store.subscribe(atom, notify));\n const getSnapshot = useStableFn(() => store.getSnapshot(atom));\n\n const snapshot: AtomState<V> = useSyncExternalStore(subscribe, getSnapshot);\n\n const stalePolicy: StalePolicy = atom[CONFIG].stalePolicy ?? \"keep\";\n\n if (snapshot.status === \"pending\") {\n throw store.resolve(atom);\n }\n\n if (snapshot.status === \"stale\") {\n if (stalePolicy === \"suspend\") {\n throw store.resolve(atom);\n }\n // \"keep\" or \"reset\" while stale: trigger background revalidation\n void store.resolve(atom);\n\n if (opts?.observe === true) {\n return { value: snapshot.value, isStale: true, error: undefined };\n }\n return snapshot.value;\n }\n\n if (snapshot.status === \"error\") {\n if (opts?.observe === true && snapshot.value !== undefined) {\n return {\n value: snapshot.value as V,\n isStale: false,\n error: snapshot.error,\n };\n }\n throw snapshot.error;\n }\n\n // status === \"fresh\"\n if (opts?.observe === true) {\n return { value: snapshot.value, isStale: false, error: undefined };\n }\n return snapshot.value;\n}\n","import { useCallback } from \"preact/hooks\";\nimport type { WritableAtom } from \"@/internal/types.js\";\nimport { useStore } from \"@/preact/provider.js\";\n\nexport function useSetAtom<V, A extends readonly unknown[]>(\n atom: WritableAtom<V, A>,\n): (...args: A) => Promise<void> {\n const store = useStore();\n return useCallback((...args: A): Promise<void> => store.set(atom, ...args), [store, atom]);\n}\n","import { useCallback } from \"preact/hooks\";\nimport type { Mutation } from \"@/internal/mutation.js\";\nimport { useStore } from \"@/preact/provider.js\";\n\nexport function useMutation<Args extends readonly unknown[]>(\n mutation: Mutation<Args>,\n): (...args: Args) => Promise<void> {\n const store = useStore();\n return useCallback(\n (...args: Args): Promise<void> => store.mutate(mutation, ...args),\n [store, mutation],\n );\n}\n","import type { WritableAtom } from \"@/internal/types.js\";\nimport { useAtomValue } from \"@/preact/use-atom-value.js\";\nimport { useSetAtom } from \"@/preact/use-set-atom.js\";\n\nexport function useAtom<V, A extends readonly unknown[]>(\n atom: WritableAtom<V, A>,\n): readonly [V, (...args: A) => Promise<void>] {\n const value = useAtomValue(atom);\n const setter = useSetAtom(atom);\n return [value, setter] as const;\n}\n","import { useCallback } from \"preact/hooks\";\nimport type { StoreClient } from \"@/internal/store.js\";\nimport { useStore } from \"@/preact/provider.js\";\n\nexport function useAtomContext<R>(callback: (ctx: StoreClient) => Promise<R>): () => Promise<R> {\n const store = useStore();\n return useCallback((): Promise<R> => callback(store.getClient()), [store, callback]);\n}\n"],"mappings":";;;;;;AAKA,MAAM,eAAe,cAA4B,KAAK;AAOtD,SAAgB,SAAS,EAAE,OAAO,YAAkC;AAClE,QAAO,oBAAC,aAAa,UAAd;EAAuB,OAAO;EAAQ;EAAiC,CAAA;;AAGhF,SAAgB,WAAkB;CAChC,MAAM,QAAQ,WAAW,aAAa;AACtC,KAAI,SAAS,KACX,OAAM,IAAI,MAAM,4CAA4C;AAE9D,QAAO;;;;ACdT,SAAS,kBAAqB,MAAiC;AAC7D,KAAI;AACF,SAAO,CAAC,OAAO,GAAG,KAAK,QAAQ,KAAK,cAAc,CAAC;SAC7C;AACN,SAAO;;;AAIX,SAAgB,qBACd,WACA,aACG;CACH,MAAM,QAAQ,aAAa;CAE3B,MAAM,CAAC,EAAE,aAAa,eAAe,gBAAgB,EACnD,WAAW;EAAE,QAAQ;EAAO,cAAc;EAAa,EACxD,EAAE;AAEH,uBAAsB;AACpB,YAAU,SAAS;AACnB,YAAU,eAAe;AAEzB,MAAI,kBAAkB,UAAU,CAC9B,aAAY,EAAE,WAAW,CAAC;IAE3B;EAAC;EAAW;EAAO;EAAY,CAAC;AAEnC,iBAAgB;AACd,MAAI,kBAAkB,UAAU,CAC9B,aAAY,EAAE,WAAW,CAAC;AAG5B,SAAO,gBAAgB;AACrB,OAAI,kBAAkB,UAAU,CAC9B,aAAY,EAAE,WAAW,CAAC;IAE5B;IACD,CAAC,UAAU,CAAC;AAEf,QAAO;;;;AC5CT,SAAgB,YACd,IACsB;CACtB,MAAM,MAAM,OAAO,GAAG;AACtB,KAAI,UAAU;AAEd,QAAO,aAAa,GAAG,SAAe,IAAI,QAAQ,GAAG,KAAK,EAAE,EAAE,CAAC;;;;ACMjE,SAAgB,aAAgB,MAAe,MAAgD;CAC7F,MAAM,QAAQ,UAAU;CAKxB,MAAM,WAAyB,qBAHb,aAAa,WAAuB,MAAM,UAAU,MAAM,OAAO,CAAC,EAChE,kBAAkB,MAAM,YAAY,KAAK,CAAC,CAEa;CAE3E,MAAM,cAA2B,KAAK,QAAQ,eAAe;AAE7D,KAAI,SAAS,WAAW,UACtB,OAAM,MAAM,QAAQ,KAAK;AAG3B,KAAI,SAAS,WAAW,SAAS;AAC/B,MAAI,gBAAgB,UAClB,OAAM,MAAM,QAAQ,KAAK;AAGtB,QAAM,QAAQ,KAAK;AAExB,MAAI,MAAM,YAAY,KACpB,QAAO;GAAE,OAAO,SAAS;GAAO,SAAS;GAAM,OAAO,KAAA;GAAW;AAEnE,SAAO,SAAS;;AAGlB,KAAI,SAAS,WAAW,SAAS;AAC/B,MAAI,MAAM,YAAY,QAAQ,SAAS,UAAU,KAAA,EAC/C,QAAO;GACL,OAAO,SAAS;GAChB,SAAS;GACT,OAAO,SAAS;GACjB;AAEH,QAAM,SAAS;;AAIjB,KAAI,MAAM,YAAY,KACpB,QAAO;EAAE,OAAO,SAAS;EAAO,SAAS;EAAO,OAAO,KAAA;EAAW;AAEpE,QAAO,SAAS;;;;ACpDlB,SAAgB,WACd,MAC+B;CAC/B,MAAM,QAAQ,UAAU;AACxB,QAAO,aAAa,GAAG,SAA2B,MAAM,IAAI,MAAM,GAAG,KAAK,EAAE,CAAC,OAAO,KAAK,CAAC;;;;ACJ5F,SAAgB,YACd,UACkC;CAClC,MAAM,QAAQ,UAAU;AACxB,QAAO,aACJ,GAAG,SAA8B,MAAM,OAAO,UAAU,GAAG,KAAK,EACjE,CAAC,OAAO,SAAS,CAClB;;;;ACPH,SAAgB,QACd,MAC6C;AAG7C,QAAO,CAFO,aAAa,KAAK,EACjB,WAAW,KAAK,CACT;;;;ACLxB,SAAgB,eAAkB,UAA8D;CAC9F,MAAM,QAAQ,UAAU;AACxB,QAAO,kBAA8B,SAAS,MAAM,WAAW,CAAC,EAAE,CAAC,OAAO,SAAS,CAAC"}
|
package/dist/react/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { h as WritableAtom, i as Mutation, n as StoreClient, o as Atom, t as Store } from "../store-DLoedZQo.js";
|
|
2
2
|
import { ReactNode } from "react";
|
|
3
3
|
|
|
4
4
|
//#region src/react/provider.d.ts
|
|
@@ -26,6 +26,9 @@ declare function useAtomValue<V>(atom: Atom<V>, opts: {
|
|
|
26
26
|
//#region src/react/use-set-atom.d.ts
|
|
27
27
|
declare function useSetAtom<V, A extends readonly unknown[]>(atom: WritableAtom<V, A>): (...args: A) => Promise<void>;
|
|
28
28
|
//#endregion
|
|
29
|
+
//#region src/react/use-mutation.d.ts
|
|
30
|
+
declare function useMutation<Args extends readonly unknown[]>(mutation: Mutation<Args>): (...args: Args) => Promise<void>;
|
|
31
|
+
//#endregion
|
|
29
32
|
//#region src/react/use-atom.d.ts
|
|
30
33
|
declare function useAtom<V, A extends readonly unknown[]>(atom: WritableAtom<V, A>): readonly [V, (...args: A) => Promise<void>];
|
|
31
34
|
//#endregion
|
|
@@ -35,5 +38,5 @@ declare function useAtomContext<R>(callback: (ctx: StoreClient) => Promise<R>):
|
|
|
35
38
|
//#region src/react/use-stable-fn.d.ts
|
|
36
39
|
declare function useStableFn<Args extends unknown[], R>(fn: (...args: Args) => R): (...args: Args) => R;
|
|
37
40
|
//#endregion
|
|
38
|
-
export { Provider, useAtom, useAtomContext, useAtomValue, useSetAtom, useStableFn, useStore };
|
|
41
|
+
export { Provider, useAtom, useAtomContext, useAtomValue, useMutation, useSetAtom, useStableFn, useStore };
|
|
39
42
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../../src/react/provider.tsx","../../src/react/use-atom-value.ts","../../src/react/use-set-atom.ts","../../src/react/use-atom.ts","../../src/react/use-atom-context.ts","../../src/react/use-stable-fn.ts"],"mappings":";;;;KAKY,aAAA;EACV,KAAA,EAAO,KAAA;EACP,QAAA,EAAU,SAAA;AAAA;AAAA,iBAGI,QAAA,CAAA;EAAW,KAAA;EAAO;AAAA,GAAY,aAAA,GAAgB,SAAA;AAAA,iBAI9C,QAAA,CAAA,GAAY,KAAA;;;KCRvB,aAAA;EACH,KAAA,EAAO,CAAA;EACP,OAAA;EACA,KAAA;AAAA;AAAA,iBAGc,YAAA,GAAA,CAAgB,IAAA,EAAM,IAAA,CAAK,CAAA,IAAK,CAAA;AAAA,iBAChC,YAAA,GAAA,CAAgB,IAAA,EAAM,IAAA,CAAK,CAAA,GAAI,IAAA;EAAQ,OAAA;AAAA,IAAkB,aAAA,CAAc,CAAA;;;iBCTvE,UAAA,iCAAA,CACd,IAAA,EAAM,YAAA,CAAa,CAAA,EAAG,CAAA,QACjB,IAAA,EAAM,CAAA,KAAM,OAAA;;;iBCFH,OAAA,iCAAA,CACd,IAAA,EAAM,YAAA,CAAa,CAAA,EAAG,CAAA,cACX,CAAA,MAAO,IAAA,EAAM,CAAA,KAAM,OAAA;;;iBCFhB,cAAA,GAAA,CAAkB,QAAA,GAAW,GAAA,EAAK,WAAA,KAAgB,OAAA,CAAQ,CAAA,UAAW,OAAA,CAAQ,CAAA;;;iBCF7E,WAAA,2BAAA,CACd,EAAA,MAAQ,IAAA,EAAM,IAAA,KAAS,CAAA,OAClB,IAAA,EAAM,IAAA,KAAS,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../../src/react/provider.tsx","../../src/react/use-atom-value.ts","../../src/react/use-set-atom.ts","../../src/react/use-mutation.ts","../../src/react/use-atom.ts","../../src/react/use-atom-context.ts","../../src/react/use-stable-fn.ts"],"mappings":";;;;KAKY,aAAA;EACV,KAAA,EAAO,KAAA;EACP,QAAA,EAAU,SAAA;AAAA;AAAA,iBAGI,QAAA,CAAA;EAAW,KAAA;EAAO;AAAA,GAAY,aAAA,GAAgB,SAAA;AAAA,iBAI9C,QAAA,CAAA,GAAY,KAAA;;;KCRvB,aAAA;EACH,KAAA,EAAO,CAAA;EACP,OAAA;EACA,KAAA;AAAA;AAAA,iBAGc,YAAA,GAAA,CAAgB,IAAA,EAAM,IAAA,CAAK,CAAA,IAAK,CAAA;AAAA,iBAChC,YAAA,GAAA,CAAgB,IAAA,EAAM,IAAA,CAAK,CAAA,GAAI,IAAA;EAAQ,OAAA;AAAA,IAAkB,aAAA,CAAc,CAAA;;;iBCTvE,UAAA,iCAAA,CACd,IAAA,EAAM,YAAA,CAAa,CAAA,EAAG,CAAA,QACjB,IAAA,EAAM,CAAA,KAAM,OAAA;;;iBCFH,WAAA,iCAAA,CACd,QAAA,EAAU,QAAA,CAAS,IAAA,QACd,IAAA,EAAM,IAAA,KAAS,OAAA;;;iBCFN,OAAA,iCAAA,CACd,IAAA,EAAM,YAAA,CAAa,CAAA,EAAG,CAAA,cACX,CAAA,MAAO,IAAA,EAAM,CAAA,KAAM,OAAA;;;iBCFhB,cAAA,GAAA,CAAkB,QAAA,GAAW,GAAA,EAAK,WAAA,KAAgB,OAAA,CAAQ,CAAA,UAAW,OAAA,CAAQ,CAAA;;;iBCF7E,WAAA,2BAAA,CACd,EAAA,MAAQ,IAAA,EAAM,IAAA,KAAS,CAAA,OAClB,IAAA,EAAM,IAAA,KAAS,CAAA"}
|
package/dist/react/index.js
CHANGED
|
@@ -60,6 +60,12 @@ function useSetAtom(atom) {
|
|
|
60
60
|
return useCallback((...args) => store.set(atom, ...args), [store, atom]);
|
|
61
61
|
}
|
|
62
62
|
//#endregion
|
|
63
|
+
//#region src/react/use-mutation.ts
|
|
64
|
+
function useMutation(mutation) {
|
|
65
|
+
const store = useStore();
|
|
66
|
+
return useCallback((...args) => store.mutate(mutation, ...args), [store, mutation]);
|
|
67
|
+
}
|
|
68
|
+
//#endregion
|
|
63
69
|
//#region src/react/use-atom.ts
|
|
64
70
|
function useAtom(atom) {
|
|
65
71
|
return [useAtomValue(atom), useSetAtom(atom)];
|
|
@@ -71,6 +77,6 @@ function useAtomContext(callback) {
|
|
|
71
77
|
return useCallback(() => callback(store.getClient()), [store, callback]);
|
|
72
78
|
}
|
|
73
79
|
//#endregion
|
|
74
|
-
export { Provider, useAtom, useAtomContext, useAtomValue, useSetAtom, useStableFn, useStore };
|
|
80
|
+
export { Provider, useAtom, useAtomContext, useAtomValue, useMutation, useSetAtom, useStableFn, useStore };
|
|
75
81
|
|
|
76
82
|
//# sourceMappingURL=index.js.map
|
package/dist/react/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../src/react/provider.tsx","../../src/react/use-stable-fn.ts","../../src/react/use-atom-value.ts","../../src/react/use-set-atom.ts","../../src/react/use-atom.ts","../../src/react/use-atom-context.ts"],"sourcesContent":["import { createContext, useContext, type ReactNode } from \"react\";\nimport type { Store } from \"@/internal/store.js\";\n\nconst StoreContext = createContext<Store | null>(null);\n\nexport type ProviderProps = {\n store: Store;\n children: ReactNode;\n};\n\nexport function Provider({ store, children }: ProviderProps): ReactNode {\n return <StoreContext.Provider value={store}>{children}</StoreContext.Provider>;\n}\n\nexport function useStore(): Store {\n const store = useContext(StoreContext);\n if (store == null) {\n throw new Error(\"useStore must be used within a <Provider>\");\n }\n return store;\n}\n","import { useCallback, useRef } from \"react\";\n\nexport function useStableFn<Args extends unknown[], R>(\n fn: (...args: Args) => R,\n): (...args: Args) => R {\n const ref = useRef(fn);\n ref.current = fn;\n\n return useCallback((...args: Args) => ref.current(...args), []);\n}\n","import { useSyncExternalStore } from \"react\";\nimport type { Atom, AtomState, StalePolicy } from \"@/internal/types.js\";\nimport { CONFIG } from \"@/internal/types.js\";\nimport { useStore } from \"@/react/provider.js\";\nimport { useStableFn } from \"@/react/use-stable-fn.js\";\n\ntype ObservedValue<V> = {\n value: V;\n isStale: boolean;\n error: unknown;\n};\n\nexport function useAtomValue<V>(atom: Atom<V>): V;\nexport function useAtomValue<V>(atom: Atom<V>, opts: { observe: true }): ObservedValue<V>;\nexport function useAtomValue<V>(atom: Atom<V>, opts?: { observe: true }): V | ObservedValue<V> {\n const store = useStore();\n\n const subscribe = useStableFn((notify: () => void) => store.subscribe(atom, notify));\n const getSnapshot = useStableFn(() => store.getSnapshot(atom));\n const getServerSnapshot = useStableFn(() => store.getServerSnapshot(atom));\n\n const snapshot: AtomState<V> = useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);\n\n const stalePolicy: StalePolicy = atom[CONFIG].stalePolicy ?? \"keep\";\n\n if (snapshot.status === \"pending\") {\n throw store.resolve(atom);\n }\n\n if (snapshot.status === \"stale\") {\n if (stalePolicy === \"suspend\") {\n throw store.resolve(atom);\n }\n // \"keep\" or \"reset\" while stale: trigger background revalidation\n void store.resolve(atom);\n\n if (opts?.observe === true) {\n return { value: snapshot.value, isStale: true, error: undefined };\n }\n return snapshot.value;\n }\n\n if (snapshot.status === \"error\") {\n if (opts?.observe === true && snapshot.value !== undefined) {\n return {\n value: snapshot.value as V,\n isStale: false,\n error: snapshot.error,\n };\n }\n throw snapshot.error;\n }\n\n // status === \"fresh\"\n if (opts?.observe === true) {\n return { value: snapshot.value, isStale: false, error: undefined };\n }\n return snapshot.value;\n}\n","import { useCallback } from \"react\";\nimport type { WritableAtom } from \"@/internal/types.js\";\nimport { useStore } from \"@/react/provider.js\";\n\nexport function useSetAtom<V, A extends readonly unknown[]>(\n atom: WritableAtom<V, A>,\n): (...args: A) => Promise<void> {\n const store = useStore();\n return useCallback((...args: A): Promise<void> => store.set(atom, ...args), [store, atom]);\n}\n","import type { WritableAtom } from \"@/internal/types.js\";\nimport { useAtomValue } from \"@/react/use-atom-value.js\";\nimport { useSetAtom } from \"@/react/use-set-atom.js\";\n\nexport function useAtom<V, A extends readonly unknown[]>(\n atom: WritableAtom<V, A>,\n): readonly [V, (...args: A) => Promise<void>] {\n const value = useAtomValue(atom);\n const setter = useSetAtom(atom);\n return [value, setter] as const;\n}\n","import { useCallback } from \"react\";\nimport type { StoreClient } from \"@/internal/store.js\";\nimport { useStore } from \"@/react/provider.js\";\n\nexport function useAtomContext<R>(callback: (ctx: StoreClient) => Promise<R>): () => Promise<R> {\n const store = useStore();\n return useCallback((): Promise<R> => callback(store.getClient()), [store, callback]);\n}\n"],"mappings":";;;;AAGA,MAAM,eAAe,cAA4B,KAAK;AAOtD,SAAgB,SAAS,EAAE,OAAO,YAAsC;AACtE,QAAO,oBAAC,aAAa,UAAd;EAAuB,OAAO;EAAQ;EAAiC,CAAA;;AAGhF,SAAgB,WAAkB;CAChC,MAAM,QAAQ,WAAW,aAAa;AACtC,KAAI,SAAS,KACX,OAAM,IAAI,MAAM,4CAA4C;AAE9D,QAAO;;;;ACjBT,SAAgB,YACd,IACsB;CACtB,MAAM,MAAM,OAAO,GAAG;AACtB,KAAI,UAAU;AAEd,QAAO,aAAa,GAAG,SAAe,IAAI,QAAQ,GAAG,KAAK,EAAE,EAAE,CAAC;;;;ACMjE,SAAgB,aAAgB,MAAe,MAAgD;CAC7F,MAAM,QAAQ,UAAU;CAMxB,MAAM,WAAyB,qBAJb,aAAa,WAAuB,MAAM,UAAU,MAAM,OAAO,CAAC,EAChE,kBAAkB,MAAM,YAAY,KAAK,CAAC,EACpC,kBAAkB,MAAM,kBAAkB,KAAK,CAAC,CAEoB;CAE9F,MAAM,cAA2B,KAAK,QAAQ,eAAe;AAE7D,KAAI,SAAS,WAAW,UACtB,OAAM,MAAM,QAAQ,KAAK;AAG3B,KAAI,SAAS,WAAW,SAAS;AAC/B,MAAI,gBAAgB,UAClB,OAAM,MAAM,QAAQ,KAAK;AAGtB,QAAM,QAAQ,KAAK;AAExB,MAAI,MAAM,YAAY,KACpB,QAAO;GAAE,OAAO,SAAS;GAAO,SAAS;GAAM,OAAO,KAAA;GAAW;AAEnE,SAAO,SAAS;;AAGlB,KAAI,SAAS,WAAW,SAAS;AAC/B,MAAI,MAAM,YAAY,QAAQ,SAAS,UAAU,KAAA,EAC/C,QAAO;GACL,OAAO,SAAS;GAChB,SAAS;GACT,OAAO,SAAS;GACjB;AAEH,QAAM,SAAS;;AAIjB,KAAI,MAAM,YAAY,KACpB,QAAO;EAAE,OAAO,SAAS;EAAO,SAAS;EAAO,OAAO,KAAA;EAAW;AAEpE,QAAO,SAAS;;;;ACrDlB,SAAgB,WACd,MAC+B;CAC/B,MAAM,QAAQ,UAAU;AACxB,QAAO,aAAa,GAAG,SAA2B,MAAM,IAAI,MAAM,GAAG,KAAK,EAAE,CAAC,OAAO,KAAK,CAAC;;;;ACJ5F,SAAgB,QACd,MAC6C;AAG7C,QAAO,CAFO,aAAa,KAAK,EACjB,WAAW,KAAK,CACT;;;;ACLxB,SAAgB,eAAkB,UAA8D;CAC9F,MAAM,QAAQ,UAAU;AACxB,QAAO,kBAA8B,SAAS,MAAM,WAAW,CAAC,EAAE,CAAC,OAAO,SAAS,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../src/react/provider.tsx","../../src/react/use-stable-fn.ts","../../src/react/use-atom-value.ts","../../src/react/use-set-atom.ts","../../src/react/use-mutation.ts","../../src/react/use-atom.ts","../../src/react/use-atom-context.ts"],"sourcesContent":["import { createContext, useContext, type ReactNode } from \"react\";\nimport type { Store } from \"@/internal/store.js\";\n\nconst StoreContext = createContext<Store | null>(null);\n\nexport type ProviderProps = {\n store: Store;\n children: ReactNode;\n};\n\nexport function Provider({ store, children }: ProviderProps): ReactNode {\n return <StoreContext.Provider value={store}>{children}</StoreContext.Provider>;\n}\n\nexport function useStore(): Store {\n const store = useContext(StoreContext);\n if (store == null) {\n throw new Error(\"useStore must be used within a <Provider>\");\n }\n return store;\n}\n","import { useCallback, useRef } from \"react\";\n\nexport function useStableFn<Args extends unknown[], R>(\n fn: (...args: Args) => R,\n): (...args: Args) => R {\n const ref = useRef(fn);\n ref.current = fn;\n\n return useCallback((...args: Args) => ref.current(...args), []);\n}\n","import { useSyncExternalStore } from \"react\";\nimport type { Atom, AtomState, StalePolicy } from \"@/internal/types.js\";\nimport { CONFIG } from \"@/internal/types.js\";\nimport { useStore } from \"@/react/provider.js\";\nimport { useStableFn } from \"@/react/use-stable-fn.js\";\n\ntype ObservedValue<V> = {\n value: V;\n isStale: boolean;\n error: unknown;\n};\n\nexport function useAtomValue<V>(atom: Atom<V>): V;\nexport function useAtomValue<V>(atom: Atom<V>, opts: { observe: true }): ObservedValue<V>;\nexport function useAtomValue<V>(atom: Atom<V>, opts?: { observe: true }): V | ObservedValue<V> {\n const store = useStore();\n\n const subscribe = useStableFn((notify: () => void) => store.subscribe(atom, notify));\n const getSnapshot = useStableFn(() => store.getSnapshot(atom));\n const getServerSnapshot = useStableFn(() => store.getServerSnapshot(atom));\n\n const snapshot: AtomState<V> = useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);\n\n const stalePolicy: StalePolicy = atom[CONFIG].stalePolicy ?? \"keep\";\n\n if (snapshot.status === \"pending\") {\n throw store.resolve(atom);\n }\n\n if (snapshot.status === \"stale\") {\n if (stalePolicy === \"suspend\") {\n throw store.resolve(atom);\n }\n // \"keep\" or \"reset\" while stale: trigger background revalidation\n void store.resolve(atom);\n\n if (opts?.observe === true) {\n return { value: snapshot.value, isStale: true, error: undefined };\n }\n return snapshot.value;\n }\n\n if (snapshot.status === \"error\") {\n if (opts?.observe === true && snapshot.value !== undefined) {\n return {\n value: snapshot.value as V,\n isStale: false,\n error: snapshot.error,\n };\n }\n throw snapshot.error;\n }\n\n // status === \"fresh\"\n if (opts?.observe === true) {\n return { value: snapshot.value, isStale: false, error: undefined };\n }\n return snapshot.value;\n}\n","import { useCallback } from \"react\";\nimport type { WritableAtom } from \"@/internal/types.js\";\nimport { useStore } from \"@/react/provider.js\";\n\nexport function useSetAtom<V, A extends readonly unknown[]>(\n atom: WritableAtom<V, A>,\n): (...args: A) => Promise<void> {\n const store = useStore();\n return useCallback((...args: A): Promise<void> => store.set(atom, ...args), [store, atom]);\n}\n","import { useCallback } from \"react\";\nimport type { Mutation } from \"@/internal/mutation.js\";\nimport { useStore } from \"@/react/provider.js\";\n\nexport function useMutation<Args extends readonly unknown[]>(\n mutation: Mutation<Args>,\n): (...args: Args) => Promise<void> {\n const store = useStore();\n return useCallback(\n (...args: Args): Promise<void> => store.mutate(mutation, ...args),\n [store, mutation],\n );\n}\n","import type { WritableAtom } from \"@/internal/types.js\";\nimport { useAtomValue } from \"@/react/use-atom-value.js\";\nimport { useSetAtom } from \"@/react/use-set-atom.js\";\n\nexport function useAtom<V, A extends readonly unknown[]>(\n atom: WritableAtom<V, A>,\n): readonly [V, (...args: A) => Promise<void>] {\n const value = useAtomValue(atom);\n const setter = useSetAtom(atom);\n return [value, setter] as const;\n}\n","import { useCallback } from \"react\";\nimport type { StoreClient } from \"@/internal/store.js\";\nimport { useStore } from \"@/react/provider.js\";\n\nexport function useAtomContext<R>(callback: (ctx: StoreClient) => Promise<R>): () => Promise<R> {\n const store = useStore();\n return useCallback((): Promise<R> => callback(store.getClient()), [store, callback]);\n}\n"],"mappings":";;;;AAGA,MAAM,eAAe,cAA4B,KAAK;AAOtD,SAAgB,SAAS,EAAE,OAAO,YAAsC;AACtE,QAAO,oBAAC,aAAa,UAAd;EAAuB,OAAO;EAAQ;EAAiC,CAAA;;AAGhF,SAAgB,WAAkB;CAChC,MAAM,QAAQ,WAAW,aAAa;AACtC,KAAI,SAAS,KACX,OAAM,IAAI,MAAM,4CAA4C;AAE9D,QAAO;;;;ACjBT,SAAgB,YACd,IACsB;CACtB,MAAM,MAAM,OAAO,GAAG;AACtB,KAAI,UAAU;AAEd,QAAO,aAAa,GAAG,SAAe,IAAI,QAAQ,GAAG,KAAK,EAAE,EAAE,CAAC;;;;ACMjE,SAAgB,aAAgB,MAAe,MAAgD;CAC7F,MAAM,QAAQ,UAAU;CAMxB,MAAM,WAAyB,qBAJb,aAAa,WAAuB,MAAM,UAAU,MAAM,OAAO,CAAC,EAChE,kBAAkB,MAAM,YAAY,KAAK,CAAC,EACpC,kBAAkB,MAAM,kBAAkB,KAAK,CAAC,CAEoB;CAE9F,MAAM,cAA2B,KAAK,QAAQ,eAAe;AAE7D,KAAI,SAAS,WAAW,UACtB,OAAM,MAAM,QAAQ,KAAK;AAG3B,KAAI,SAAS,WAAW,SAAS;AAC/B,MAAI,gBAAgB,UAClB,OAAM,MAAM,QAAQ,KAAK;AAGtB,QAAM,QAAQ,KAAK;AAExB,MAAI,MAAM,YAAY,KACpB,QAAO;GAAE,OAAO,SAAS;GAAO,SAAS;GAAM,OAAO,KAAA;GAAW;AAEnE,SAAO,SAAS;;AAGlB,KAAI,SAAS,WAAW,SAAS;AAC/B,MAAI,MAAM,YAAY,QAAQ,SAAS,UAAU,KAAA,EAC/C,QAAO;GACL,OAAO,SAAS;GAChB,SAAS;GACT,OAAO,SAAS;GACjB;AAEH,QAAM,SAAS;;AAIjB,KAAI,MAAM,YAAY,KACpB,QAAO;EAAE,OAAO,SAAS;EAAO,SAAS;EAAO,OAAO,KAAA;EAAW;AAEpE,QAAO,SAAS;;;;ACrDlB,SAAgB,WACd,MAC+B;CAC/B,MAAM,QAAQ,UAAU;AACxB,QAAO,aAAa,GAAG,SAA2B,MAAM,IAAI,MAAM,GAAG,KAAK,EAAE,CAAC,OAAO,KAAK,CAAC;;;;ACJ5F,SAAgB,YACd,UACkC;CAClC,MAAM,QAAQ,UAAU;AACxB,QAAO,aACJ,GAAG,SAA8B,MAAM,OAAO,UAAU,GAAG,KAAK,EACjE,CAAC,OAAO,SAAS,CAClB;;;;ACPH,SAAgB,QACd,MAC6C;AAG7C,QAAO,CAFO,aAAa,KAAK,EACjB,WAAW,KAAK,CACT;;;;ACLxB,SAAgB,eAAkB,UAA8D;CAC9F,MAAM,QAAQ,UAAU;AACxB,QAAO,kBAA8B,SAAS,MAAM,WAAW,CAAC,EAAE,CAAC,OAAO,SAAS,CAAC"}
|
|
@@ -23,7 +23,14 @@ type AtomContext<Deps extends Record<string, Atom<unknown>>> = {
|
|
|
23
23
|
get: <K extends keyof Deps>(key: K) => Promise<AtomValue<Deps[K]>>;
|
|
24
24
|
signal: AbortSignal;
|
|
25
25
|
};
|
|
26
|
-
|
|
26
|
+
/** Context for standalone mutations: optimistic writes and invalidation (no primary atom). */
|
|
27
|
+
type MutationContext = {
|
|
28
|
+
writeOptimistic<U>(atom: Atom<U>, value: U): void;
|
|
29
|
+
writeOptimistic<U>(atom: Atom<U>, mutate: (prev: U | undefined) => U): void;
|
|
30
|
+
invalidate(atom: Atom<unknown>): void;
|
|
31
|
+
invalidateMany(atoms: ReadonlyArray<Atom<unknown>>): void;
|
|
32
|
+
};
|
|
33
|
+
interface WritableAtomContext<Deps extends Record<string, Atom<unknown>>, Value> extends AtomContext<Deps>, MutationContext {
|
|
27
34
|
setOptimisticValue(value: Value): void;
|
|
28
35
|
setOptimisticValue(mutate: (prev: Value | undefined) => Value): void;
|
|
29
36
|
}
|
|
@@ -54,10 +61,18 @@ type AtomValue<A> = A extends Atom<infer V> ? V : never;
|
|
|
54
61
|
type IsWritable<A> = A extends WritableAtom<unknown, readonly unknown[]> ? true : false;
|
|
55
62
|
type AtomArgs<A> = A extends WritableAtom<unknown, infer Args> ? Args : never;
|
|
56
63
|
//#endregion
|
|
64
|
+
//#region src/internal/mutation.d.ts
|
|
65
|
+
declare const MUTATION_RUN: unique symbol;
|
|
66
|
+
type Mutation<in out Args extends readonly unknown[]> = {
|
|
67
|
+
readonly [MUTATION_RUN]: (ctx: MutationContext, ...args: Args) => Promise<void>;
|
|
68
|
+
};
|
|
69
|
+
declare function mutation<const Args extends readonly unknown[]>(fn: (ctx: MutationContext, ...args: Args) => Promise<void>): Mutation<Args>;
|
|
70
|
+
//#endregion
|
|
57
71
|
//#region src/internal/store.d.ts
|
|
58
72
|
interface StoreClient {
|
|
59
73
|
get<V>(atom: Atom<V>): Promise<V>;
|
|
60
74
|
set<V, A extends readonly unknown[]>(atom: WritableAtom<V, A>, ...args: A): Promise<void>;
|
|
75
|
+
mutate<Args extends readonly unknown[]>(mutation: Mutation<Args>, ...args: Args): Promise<void>;
|
|
61
76
|
write<V>(atom: Atom<V>, value: V): void;
|
|
62
77
|
write<V>(atom: Atom<V>, mutate: (prev: V | undefined) => V): void;
|
|
63
78
|
invalidate(atom: Atom<unknown>): void;
|
|
@@ -73,11 +88,12 @@ declare class Store {
|
|
|
73
88
|
getSnapshot<V>(atom: Atom<V>): AtomState<V>;
|
|
74
89
|
getServerSnapshot<V>(atom: Atom<V>): AtomState<V>;
|
|
75
90
|
set<V, A extends readonly unknown[]>(atom: WritableAtom<V, A>, ...args: A): Promise<void>;
|
|
91
|
+
mutate<Args extends readonly unknown[]>(mutation: Mutation<Args>, ...args: Args): Promise<void>;
|
|
76
92
|
write<V>(atom: Atom<V>, value: V): void;
|
|
77
93
|
write<V>(atom: Atom<V>, mutate: (prev: V | undefined) => V): void;
|
|
78
94
|
getClient(): StoreClient;
|
|
79
95
|
}
|
|
80
96
|
declare function createStore(): Store;
|
|
81
97
|
//#endregion
|
|
82
|
-
export {
|
|
83
|
-
//# sourceMappingURL=store-
|
|
98
|
+
export { mutation as a, AtomConfig as c, AtomValue as d, IsWritable as f, WritableAtomContext as g, WritableAtom as h, Mutation as i, AtomContext as l, StalePolicy as m, StoreClient as n, Atom as o, MutationContext as p, createStore as r, AtomArgs as s, Store as t, AtomState as u };
|
|
99
|
+
//# sourceMappingURL=store-DLoedZQo.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store-DLoedZQo.d.ts","names":[],"sources":["../src/internal/types.ts","../src/internal/mutation.ts","../src/internal/store.ts"],"mappings":"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"}
|
|
@@ -183,6 +183,12 @@ function atomFamily(options) {
|
|
|
183
183
|
return family;
|
|
184
184
|
}
|
|
185
185
|
//#endregion
|
|
186
|
+
//#region src/internal/mutation.ts
|
|
187
|
+
const MUTATION_RUN = Symbol("kvark.mutationRun");
|
|
188
|
+
function mutation(fn) {
|
|
189
|
+
return { [MUTATION_RUN]: fn };
|
|
190
|
+
}
|
|
191
|
+
//#endregion
|
|
186
192
|
//#region src/internal/store.ts
|
|
187
193
|
const PENDING_STATE = {
|
|
188
194
|
status: "pending",
|
|
@@ -319,6 +325,33 @@ var Store = class {
|
|
|
319
325
|
this.#pending.add(atom);
|
|
320
326
|
this.#schedulePendingFlush();
|
|
321
327
|
}
|
|
328
|
+
#relatedOptimisticWrite(target, valueOrMutate, relatedSnapshots) {
|
|
329
|
+
const targetEntry = this.#getOrCreate(target);
|
|
330
|
+
if (!relatedSnapshots.has(target)) relatedSnapshots.set(target, {
|
|
331
|
+
state: targetEntry.state,
|
|
332
|
+
version: targetEntry.version
|
|
333
|
+
});
|
|
334
|
+
this.#controllers.get(target)?.abort();
|
|
335
|
+
targetEntry.promise = null;
|
|
336
|
+
targetEntry.state = {
|
|
337
|
+
status: "fresh",
|
|
338
|
+
value: typeof valueOrMutate === "function" ? valueOrMutate(extractPreviousValue(targetEntry.state)) : valueOrMutate,
|
|
339
|
+
error: void 0
|
|
340
|
+
};
|
|
341
|
+
targetEntry.version++;
|
|
342
|
+
this.#scheduleNotify(target);
|
|
343
|
+
this.#markReverseDependentsStale(target);
|
|
344
|
+
}
|
|
345
|
+
#rollbackRelatedSnapshots(relatedSnapshots) {
|
|
346
|
+
for (const [target, targetSnap] of relatedSnapshots) {
|
|
347
|
+
const targetEntry = this.#atoms.get(target);
|
|
348
|
+
if (targetEntry != null) {
|
|
349
|
+
targetEntry.state = targetSnap.state;
|
|
350
|
+
targetEntry.version = targetSnap.version;
|
|
351
|
+
this.#scheduleNotify(target);
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
}
|
|
322
355
|
#registerRdeps(atom, deps) {
|
|
323
356
|
for (const dep of Object.values(deps)) {
|
|
324
357
|
let set = this.#rdeps.get(dep);
|
|
@@ -398,6 +431,7 @@ var Store = class {
|
|
|
398
431
|
const baseCtx = this.#makeCtx(atom, deps);
|
|
399
432
|
const entry = this.#getOrCreate(atom);
|
|
400
433
|
const optimisticSnapshot = { current: null };
|
|
434
|
+
const relatedSnapshots = /* @__PURE__ */ new Map();
|
|
401
435
|
const ctx = {
|
|
402
436
|
...baseCtx,
|
|
403
437
|
setOptimisticValue: (valueOrMutate) => {
|
|
@@ -413,7 +447,12 @@ var Store = class {
|
|
|
413
447
|
entry.version++;
|
|
414
448
|
this.#scheduleNotify(atom);
|
|
415
449
|
this.#markReverseDependentsStale(atom);
|
|
416
|
-
}
|
|
450
|
+
},
|
|
451
|
+
writeOptimistic: (target, valueOrMutate) => {
|
|
452
|
+
this.#relatedOptimisticWrite(target, valueOrMutate, relatedSnapshots);
|
|
453
|
+
},
|
|
454
|
+
invalidate: (target) => this.invalidate(target),
|
|
455
|
+
invalidateMany: (targets) => this.invalidateMany(targets)
|
|
417
456
|
};
|
|
418
457
|
try {
|
|
419
458
|
await config.set(ctx, ...args);
|
|
@@ -424,10 +463,27 @@ var Store = class {
|
|
|
424
463
|
entry.version = snap.version;
|
|
425
464
|
this.#scheduleNotify(atom);
|
|
426
465
|
}
|
|
466
|
+
this.#rollbackRelatedSnapshots(relatedSnapshots);
|
|
427
467
|
throw e;
|
|
428
468
|
}
|
|
429
469
|
this.invalidate(atom);
|
|
430
470
|
}
|
|
471
|
+
async mutate(mutation, ...args) {
|
|
472
|
+
const relatedSnapshots = /* @__PURE__ */ new Map();
|
|
473
|
+
const ctx = {
|
|
474
|
+
writeOptimistic: (target, valueOrMutate) => {
|
|
475
|
+
this.#relatedOptimisticWrite(target, valueOrMutate, relatedSnapshots);
|
|
476
|
+
},
|
|
477
|
+
invalidate: (target) => this.invalidate(target),
|
|
478
|
+
invalidateMany: (targets) => this.invalidateMany(targets)
|
|
479
|
+
};
|
|
480
|
+
try {
|
|
481
|
+
await mutation[MUTATION_RUN](ctx, ...args);
|
|
482
|
+
} catch (e) {
|
|
483
|
+
this.#rollbackRelatedSnapshots(relatedSnapshots);
|
|
484
|
+
throw e;
|
|
485
|
+
}
|
|
486
|
+
}
|
|
431
487
|
write(atom, valueOrMutate) {
|
|
432
488
|
const entry = this.#getOrCreate(atom);
|
|
433
489
|
this.#controllers.get(atom)?.abort();
|
|
@@ -446,6 +502,7 @@ var Store = class {
|
|
|
446
502
|
this.#client = {
|
|
447
503
|
get: (atom) => this.resolve(atom),
|
|
448
504
|
set: (atom, ...args) => this.set(atom, ...args),
|
|
505
|
+
mutate: (m, ...args) => this.mutate(m, ...args),
|
|
449
506
|
write: (atom, valueOrMutate) => this.write(atom, valueOrMutate),
|
|
450
507
|
invalidate: (atom) => this.invalidate(atom),
|
|
451
508
|
invalidateMany: (atoms) => this.invalidateMany(atoms),
|
|
@@ -467,6 +524,6 @@ function extractPreviousValue(state) {
|
|
|
467
524
|
if (state.status === "error") return state.value;
|
|
468
525
|
}
|
|
469
526
|
//#endregion
|
|
470
|
-
export {
|
|
527
|
+
export { atom as i, mutation as n, atomFamily as r, createStore as t };
|
|
471
528
|
|
|
472
|
-
//# sourceMappingURL=store-
|
|
529
|
+
//# sourceMappingURL=store-DvSUP7R9.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store-DvSUP7R9.js","names":["#maxSize","#nodeMap","#valueMap","#head","#tail","#moveToMru","#insertBeforeTail","#evict","#detach","#atoms","#rdeps","#pending","#controllers","#familyUnsubs","#registeredFamilies","#getOrCreate","#runGet","#registerRdeps","#makeCtx","#scheduleNotify","#markStale","#schedulePendingFlush","#flushScheduled","#flushPending","#markReverseDependentsStale","#autoRegisterFamily","#relatedOptimisticWrite","#rollbackRelatedSnapshots","#client"],"sources":["../src/internal/atom.ts","../src/internal/lru-cache.ts","../src/internal/family.ts","../src/internal/mutation.ts","../src/internal/store.ts"],"sourcesContent":["import type {\n Atom,\n AtomConfig,\n InternalAtomConfig,\n WritableAtom,\n WritableAtomContext,\n} from \"@/internal/types.js\";\nimport { CONFIG, WRITABLE } from \"@/internal/types.js\";\n\ntype WritableConfig<\n Value,\n Deps extends Record<string, Atom<unknown>>,\n Args extends readonly unknown[],\n> = AtomConfig<Value, Deps, Args> & {\n set: (ctx: WritableAtomContext<Deps, Value>, ...args: Args) => Promise<void>;\n};\n\ntype ReadonlyConfig<Value, Deps extends Record<string, Atom<unknown>>> = Omit<\n AtomConfig<Value, Deps, readonly []>,\n \"set\"\n>;\n\nexport function atom<\n Value,\n Deps extends Record<string, Atom<unknown>> = Record<never, never>,\n Args extends readonly unknown[] = readonly [],\n>(config: WritableConfig<Value, Deps, Args>): WritableAtom<Value, Args>;\n\nexport function atom<Value, Deps extends Record<string, Atom<unknown>> = Record<never, never>>(\n config: ReadonlyConfig<Value, Deps>,\n): Atom<Value>;\n\nexport function atom<\n Value,\n Deps extends Record<string, Atom<unknown>> = Record<never, never>,\n Args extends readonly unknown[] = readonly [],\n>(config: AtomConfig<Value, Deps, Args>): Atom<Value> {\n const internal: InternalAtomConfig<Value> = Object.create(null) as InternalAtomConfig<Value>;\n internal.get = config.get as InternalAtomConfig<Value>[\"get\"];\n\n if (config.debugLabel != null) {\n internal.debugLabel = config.debugLabel;\n }\n if (config.dependencies != null) {\n internal.dependencies = config.dependencies as Record<string, Atom<unknown>>;\n }\n if (config.stalePolicy != null) {\n internal.stalePolicy = config.stalePolicy;\n }\n if (config.set != null) {\n internal.set = config.set as NonNullable<InternalAtomConfig<Value>[\"set\"]>;\n }\n if (config.onMount != null) {\n internal.onMount = config.onMount as NonNullable<InternalAtomConfig<Value>[\"onMount\"]>;\n }\n\n if (config.set != null) {\n return {\n [CONFIG]: internal,\n [WRITABLE]: [] as unknown as Args,\n debugLabel: config.debugLabel,\n } as unknown as Atom<Value>;\n }\n\n return {\n [CONFIG]: internal,\n debugLabel: config.debugLabel,\n } as Atom<Value>;\n}\n","type LruNode<K> = {\n key: K;\n prev: LruNode<K> | null;\n next: LruNode<K> | null;\n};\n\n/**\n * Fixed-capacity cache with O(1) get, set, delete and LRU eviction.\n *\n * Pass `maxSize: Infinity` to disable eviction (keep-all semantics).\n *\n * LRU end (oldest): head.next — MRU end (newest): tail.prev.\n */\nexport class LruCache<K, V> {\n readonly #maxSize: number;\n readonly #nodeMap = new Map<K, LruNode<K>>();\n readonly #valueMap = new Map<K, V>();\n readonly #head: LruNode<K>;\n readonly #tail: LruNode<K>;\n\n constructor(maxSize: number) {\n this.#maxSize = maxSize;\n this.#head = { key: undefined as unknown as K, prev: null, next: null };\n this.#tail = { key: undefined as unknown as K, prev: this.#head, next: null };\n this.#head.next = this.#tail;\n }\n\n /** Returns the value and marks the entry as most-recently used. */\n get(key: K): V | undefined {\n const node = this.#nodeMap.get(key);\n if (node == null) {\n return undefined;\n }\n this.#moveToMru(node);\n return this.#valueMap.get(key);\n }\n\n /** Returns the value without affecting LRU order. */\n peek(key: K): V | undefined {\n return this.#valueMap.get(key);\n }\n\n /** Inserts or updates a value and evicts the LRU entry if over capacity. */\n set(key: K, value: V): void {\n const existing = this.#nodeMap.get(key);\n if (existing != null) {\n this.#valueMap.set(key, value);\n this.#moveToMru(existing);\n return;\n }\n\n const node: LruNode<K> = { key, prev: null, next: null };\n this.#nodeMap.set(key, node);\n this.#valueMap.set(key, value);\n this.#insertBeforeTail(node);\n this.#evict();\n }\n\n delete(key: K): void {\n const node = this.#nodeMap.get(key);\n if (node == null) {\n return;\n }\n this.#detach(node);\n this.#nodeMap.delete(key);\n this.#valueMap.delete(key);\n }\n\n values(): IterableIterator<V> {\n return this.#valueMap.values();\n }\n\n /** Returns a live read-only view of the underlying map. */\n asReadonlyMap(): ReadonlyMap<K, V> {\n return this.#valueMap;\n }\n\n #moveToMru(node: LruNode<K>): void {\n this.#detach(node);\n this.#insertBeforeTail(node);\n }\n\n #detach(node: LruNode<K>): void {\n const { prev, next } = node;\n if (prev == null || next == null) {\n return;\n }\n prev.next = next;\n next.prev = prev;\n }\n\n #insertBeforeTail(node: LruNode<K>): void {\n const before = this.#tail.prev;\n if (before == null) {\n return;\n }\n before.next = node;\n node.prev = before;\n node.next = this.#tail;\n this.#tail.prev = node;\n }\n\n #evict(): void {\n if (!Number.isFinite(this.#maxSize)) {\n return;\n }\n while (this.#nodeMap.size > this.#maxSize) {\n const oldest = this.#head.next;\n if (oldest == null) {\n break;\n }\n this.#detach(oldest);\n this.#nodeMap.delete(oldest.key);\n this.#valueMap.delete(oldest.key);\n }\n }\n}\n","import type { Atom, AtomContext, StalePolicy, WritableAtomContext } from \"@/internal/types.js\";\nimport { FAMILY_LINK } from \"@/internal/types.js\";\nimport { atom } from \"@/internal/atom.js\";\nimport { LruCache } from \"@/internal/lru-cache.js\";\n\nexport type AtomFamilyOptions<\n Param,\n Value,\n Deps extends Record<string, Atom<unknown>>,\n Args extends readonly unknown[],\n Key = Param,\n> = {\n dependencies?: (param: Param) => Deps;\n stalePolicy?: StalePolicy;\n cachePolicy?: \"keep-all\" | \"lru\";\n lruSize?: number;\n debugLabel?: string;\n /**\n * Optional function to derive a stable cache key from `param`.\n * Use when `Param` is an object and you want equality-by-value semantics.\n * The returned key is used for all cache operations (get, set, LRU, invalidate, remove).\n * The original `param` is still passed to `get`, `set`, and `dependencies`.\n *\n * For plain objects/arrays you can use `stableFamilyKey` from `@kdeveloper/kvark/family`.\n * Treat the param object as immutable after the first call — `stableFamilyKey` memoises\n * by object reference via a WeakMap.\n */\n paramKey?: (param: Param) => Key;\n get: (param: Param) => (ctx: AtomContext<Deps>) => Promise<Value>;\n set?: (param: Param) => (ctx: WritableAtomContext<Deps, Value>, ...args: Args) => Promise<void>;\n};\n\nexport interface AtomFamily<Param, Value, Key = Param> {\n (param: Param): Atom<Value>;\n invalidate(param: Param): void;\n invalidateAll(): void;\n remove(param: Param): void;\n getCache(): ReadonlyMap<Key, Atom<Value>>;\n}\n\nexport interface FamilyLink {\n invalidateAtom: (atom: Atom<unknown>) => void;\n registerStore: (cb: (atom: Atom<unknown>) => void) => () => void;\n}\n\nexport function getFamilyLink(target: Atom<unknown>): FamilyLink | undefined {\n return (target as unknown as Record<symbol, FamilyLink | undefined>)[FAMILY_LINK];\n}\n\nexport function atomFamily<\n Param,\n Value,\n Deps extends Record<string, Atom<unknown>> = Record<never, never>,\n Args extends readonly unknown[] = readonly [],\n Key = Param,\n>(options: AtomFamilyOptions<Param, Value, Deps, Args, Key>): AtomFamily<Param, Value, Key> {\n const maxSize = options.cachePolicy === \"lru\" ? (options.lruSize ?? 100) : Infinity;\n const cache = new LruCache<Key, Atom<Value>>(maxSize);\n const storeCallbacks = new Set<(atom: Atom<unknown>) => void>();\n\n function keyOf(param: Param): Key {\n return options.paramKey != null ? options.paramKey(param) : (param as unknown as Key);\n }\n\n const link: FamilyLink = {\n invalidateAtom(target: Atom<unknown>): void {\n for (const cb of storeCallbacks) {\n cb(target);\n }\n },\n registerStore(cb: (atom: Atom<unknown>) => void): () => void {\n storeCallbacks.add(cb);\n return () => {\n storeCallbacks.delete(cb);\n };\n },\n };\n\n function attachLink(target: Atom<Value>): void {\n (target as unknown as Record<symbol, FamilyLink>)[FAMILY_LINK] = link;\n }\n\n function getOrCreate(param: Param): Atom<Value> {\n const key = keyOf(param);\n const cached = cache.get(key);\n if (cached != null) {\n return cached;\n }\n\n const deps = options.dependencies?.(param);\n const getFn = options.get(param);\n const setFn = options.set?.(param);\n\n const labelSuffix = options.paramKey != null ? String(key) : String(param);\n const label = options.debugLabel != null ? `${options.debugLabel}(${labelSuffix})` : undefined;\n\n const created = createAtom(label, deps, getFn, setFn);\n attachLink(created);\n cache.set(key, created);\n\n return created;\n }\n\n function createAtom(\n label: string | undefined,\n deps: Deps | undefined,\n getFn: (ctx: AtomContext<Deps>) => Promise<Value>,\n setFn: ((ctx: WritableAtomContext<Deps, Value>, ...args: Args) => Promise<void>) | undefined,\n ): Atom<Value> {\n const base = {\n get: getFn as (ctx: AtomContext<Deps>) => Promise<Value>,\n } as {\n debugLabel?: string;\n dependencies?: Deps;\n stalePolicy?: StalePolicy;\n get: (ctx: AtomContext<Deps>) => Promise<Value>;\n set?: (ctx: WritableAtomContext<Deps, Value>, ...args: Args) => Promise<void>;\n };\n\n if (label != null) {\n base.debugLabel = label;\n }\n if (deps != null) {\n base.dependencies = deps;\n }\n if (options.stalePolicy != null) {\n base.stalePolicy = options.stalePolicy;\n }\n\n if (setFn != null) {\n base.set = setFn;\n return atom(\n base as typeof base & {\n set: (ctx: WritableAtomContext<Deps, Value>, ...args: Args) => Promise<void>;\n },\n ) as Atom<Value>;\n }\n\n return atom(base as Omit<typeof base, \"set\">);\n }\n\n const family = getOrCreate as AtomFamily<Param, Value, Key>;\n\n family.invalidate = (param: Param): void => {\n const cached = cache.peek(keyOf(param));\n if (cached != null) {\n link.invalidateAtom(cached);\n }\n };\n\n family.invalidateAll = (): void => {\n for (const cached of cache.values()) {\n link.invalidateAtom(cached);\n }\n };\n\n family.remove = (param: Param): void => {\n cache.delete(keyOf(param));\n };\n\n family.getCache = (): ReadonlyMap<Key, Atom<Value>> => cache.asReadonlyMap();\n\n return family;\n}\n","import type { MutationContext } from \"@/internal/types.js\";\n\nexport const MUTATION_RUN = Symbol(\"kvark.mutationRun\");\n\nexport type Mutation<in out Args extends readonly unknown[]> = {\n readonly [MUTATION_RUN]: (ctx: MutationContext, ...args: Args) => Promise<void>;\n};\n\nexport function mutation<const Args extends readonly unknown[]>(\n fn: (ctx: MutationContext, ...args: Args) => Promise<void>,\n): Mutation<Args> {\n return { [MUTATION_RUN]: fn } as Mutation<Args>;\n}\n","import type {\n Atom,\n AtomContext,\n AtomState,\n InternalAtomConfig,\n MutationContext,\n StalePolicy,\n WritableAtom,\n WritableAtomContext,\n} from \"@/internal/types.js\";\nimport { CONFIG } from \"@/internal/types.js\";\nimport { getFamilyLink } from \"@/internal/family.js\";\nimport { MUTATION_RUN, type Mutation } from \"@/internal/mutation.js\";\n\ntype AtomEntry<V> = {\n state: AtomState<V>;\n version: number;\n promise: Promise<V> | null;\n listeners: Set<() => void>;\n mountCount: number;\n unmount: (() => void) | null;\n};\n\nexport interface StoreClient {\n get<V>(atom: Atom<V>): Promise<V>;\n set<V, A extends readonly unknown[]>(atom: WritableAtom<V, A>, ...args: A): Promise<void>;\n mutate<Args extends readonly unknown[]>(mutation: Mutation<Args>, ...args: Args): Promise<void>;\n write<V>(atom: Atom<V>, value: V): void;\n write<V>(atom: Atom<V>, mutate: (prev: V | undefined) => V): void;\n invalidate(atom: Atom<unknown>): void;\n invalidateMany(atoms: ReadonlyArray<Atom<unknown>>): void;\n subscribe<V>(atom: Atom<V>, listener: (state: AtomState<V>) => void): () => void;\n}\n\nconst PENDING_STATE: AtomState<never> = {\n status: \"pending\",\n value: undefined,\n error: undefined,\n} as AtomState<never>;\n\nexport class Store {\n readonly #atoms = new WeakMap<Atom<unknown>, AtomEntry<unknown>>();\n readonly #rdeps = new Map<Atom<unknown>, Set<Atom<unknown>>>();\n readonly #pending = new Set<Atom<unknown>>();\n readonly #controllers = new WeakMap<Atom<unknown>, AbortController>();\n readonly #familyUnsubs = new Set<() => void>();\n readonly #registeredFamilies = new WeakSet<object>();\n #client: StoreClient | null = null;\n #flushScheduled = false;\n\n #getOrCreate<V>(atom: Atom<V>): AtomEntry<V> {\n let entry = this.#atoms.get(atom) as AtomEntry<V> | undefined;\n if (entry == null) {\n entry = {\n state: PENDING_STATE as AtomState<V>,\n version: 0,\n promise: null,\n listeners: new Set(),\n mountCount: 0,\n unmount: null,\n };\n this.#atoms.set(atom, entry as AtomEntry<unknown>);\n }\n return entry;\n }\n\n resolve<V>(atom: Atom<V>): Promise<V> {\n const entry = this.#getOrCreate(atom);\n if (entry.promise != null) {\n return entry.promise;\n }\n\n const promise = this.#runGet(atom).finally(() => {\n const e = this.#atoms.get(atom) as AtomEntry<V> | undefined;\n if (e != null) {\n e.promise = null;\n }\n });\n entry.promise = promise;\n return promise;\n }\n\n async #runGet<V>(atom: Atom<V>): Promise<V> {\n const config: InternalAtomConfig<V> = atom[CONFIG];\n const dependencies = config.dependencies;\n const stalePolicy: StalePolicy = config.stalePolicy ?? \"keep\";\n const entry = this.#getOrCreate(atom);\n\n if (dependencies != null) {\n await Promise.all(Object.values(dependencies).map((dep) => this.resolve(dep)));\n this.#registerRdeps(atom, dependencies);\n }\n\n const ctx = this.#makeCtx(atom, dependencies ?? {});\n\n try {\n const value = await config.get(ctx);\n if (ctx.signal.aborted) {\n throw new DOMException(\"The operation was aborted\", \"AbortError\");\n }\n entry.state = { status: \"fresh\", value, error: undefined };\n entry.version++;\n this.#scheduleNotify(atom);\n return value;\n } catch (e: unknown) {\n if (isAbortError(e)) {\n throw e;\n }\n const prevValue = extractPreviousValue<V>(entry.state);\n entry.state = {\n status: \"error\",\n value: stalePolicy === \"keep\" ? prevValue : undefined,\n error: e,\n } as AtomState<V>;\n entry.version++;\n this.#scheduleNotify(atom);\n throw e;\n }\n }\n\n invalidate(atom: Atom<unknown>): void {\n this.#markStale(atom);\n this.#pending.add(atom);\n this.#schedulePendingFlush();\n }\n\n invalidateMany(atoms: ReadonlyArray<Atom<unknown>>): void {\n for (const a of atoms) {\n this.#markStale(a);\n this.#pending.add(a);\n }\n if (this.#pending.size > 0) {\n this.#schedulePendingFlush();\n }\n }\n\n #markStale(atom: Atom<unknown>, visited = new Set<Atom<unknown>>()): void {\n if (visited.has(atom)) {\n return;\n }\n visited.add(atom);\n\n const entry = this.#atoms.get(atom);\n if (entry != null) {\n const stalePolicy: StalePolicy = atom[CONFIG].stalePolicy ?? \"keep\";\n\n if (entry.state.status === \"fresh\") {\n if (stalePolicy === \"reset\") {\n entry.state = PENDING_STATE;\n } else {\n entry.state = { ...entry.state, status: \"stale\" };\n }\n }\n\n entry.promise = null;\n this.#controllers.get(atom)?.abort();\n }\n\n const rdeps = this.#rdeps.get(atom);\n if (rdeps != null) {\n for (const dep of rdeps) {\n this.#markStale(dep, visited);\n }\n }\n }\n\n #markReverseDependentsStale(atom: Atom<unknown>): void {\n const rdeps = this.#rdeps.get(atom);\n if (rdeps != null) {\n const visited = new Set<Atom<unknown>>([atom]);\n for (const dep of rdeps) {\n this.#markStale(dep, visited);\n this.#pending.add(dep);\n }\n }\n }\n\n #flushPending(): void {\n const batch = [...this.#pending];\n this.#pending.clear();\n const toNotify = new Set<() => void>();\n for (const a of batch) {\n const entry = this.#atoms.get(a);\n if (entry != null) {\n for (const l of entry.listeners) {\n toNotify.add(l);\n }\n }\n }\n for (const l of toNotify) {\n l();\n }\n }\n\n #schedulePendingFlush(): void {\n if (!this.#flushScheduled) {\n this.#flushScheduled = true;\n queueMicrotask(() => {\n this.#flushScheduled = false;\n this.#flushPending();\n });\n }\n }\n\n #scheduleNotify(atom: Atom<unknown>): void {\n this.#pending.add(atom);\n this.#schedulePendingFlush();\n }\n\n #relatedOptimisticWrite<U>(\n target: Atom<U>,\n valueOrMutate: U | ((prev: U | undefined) => U),\n relatedSnapshots: Map<Atom<unknown>, { state: AtomState<unknown>; version: number }>,\n ): void {\n const targetEntry = this.#getOrCreate(target);\n if (!relatedSnapshots.has(target)) {\n relatedSnapshots.set(target, { state: targetEntry.state, version: targetEntry.version });\n }\n this.#controllers.get(target)?.abort();\n targetEntry.promise = null;\n const next =\n typeof valueOrMutate === \"function\"\n ? (valueOrMutate as (prev: U | undefined) => U)(extractPreviousValue(targetEntry.state))\n : valueOrMutate;\n targetEntry.state = { status: \"fresh\", value: next, error: undefined };\n targetEntry.version++;\n this.#scheduleNotify(target);\n this.#markReverseDependentsStale(target);\n }\n\n #rollbackRelatedSnapshots(\n relatedSnapshots: Map<Atom<unknown>, { state: AtomState<unknown>; version: number }>,\n ): void {\n for (const [target, targetSnap] of relatedSnapshots) {\n const targetEntry = this.#atoms.get(target) as AtomEntry<unknown> | undefined;\n if (targetEntry != null) {\n targetEntry.state = targetSnap.state;\n targetEntry.version = targetSnap.version;\n this.#scheduleNotify(target);\n }\n }\n }\n\n #registerRdeps(atom: Atom<unknown>, deps: Record<string, Atom<unknown>>): void {\n for (const dep of Object.values(deps)) {\n let set = this.#rdeps.get(dep);\n if (set == null) {\n set = new Set();\n this.#rdeps.set(dep, set);\n }\n set.add(atom);\n }\n }\n\n #makeCtx(\n atom: Atom<unknown>,\n deps: Record<string, Atom<unknown>>,\n ): AtomContext<Record<string, Atom<unknown>>> {\n this.#controllers.get(atom)?.abort();\n const controller = new AbortController();\n this.#controllers.set(atom, controller);\n\n return {\n signal: controller.signal,\n get: async (key: string) => {\n const dep = deps[key];\n if (dep == null) {\n throw new Error(`Unknown dependency key: \"${String(key)}\"`);\n }\n return this.resolve(dep);\n },\n };\n }\n\n subscribe<V>(atom: Atom<V>, listener: () => void): () => void {\n const entry = this.#getOrCreate(atom);\n entry.listeners.add(listener);\n\n this.#autoRegisterFamily(atom);\n\n if (entry.state.status === \"pending\" && entry.promise == null) {\n void this.resolve(atom);\n }\n\n entry.mountCount++;\n if (entry.mountCount === 1) {\n const config: InternalAtomConfig<V> = atom[CONFIG];\n if (config.onMount != null) {\n const setValue = (value: V): void => {\n entry.state = { status: \"fresh\", value, error: undefined };\n entry.version++;\n this.#scheduleNotify(atom);\n };\n const cleanup = config.onMount(setValue as (value: unknown) => void);\n if (typeof cleanup === \"function\") {\n entry.unmount = cleanup;\n }\n }\n }\n\n return () => {\n entry.listeners.delete(listener);\n entry.mountCount--;\n if (entry.mountCount === 0 && entry.unmount != null) {\n entry.unmount();\n entry.unmount = null;\n }\n };\n }\n\n #autoRegisterFamily(atom: Atom<unknown>): void {\n const link = getFamilyLink(atom);\n if (link == null) {\n return;\n }\n if (this.#registeredFamilies.has(link)) {\n return;\n }\n this.#registeredFamilies.add(link);\n const unsub = link.registerStore((target: Atom<unknown>) => {\n this.invalidate(target);\n });\n this.#familyUnsubs.add(unsub);\n }\n\n getSnapshot<V>(atom: Atom<V>): AtomState<V> {\n return this.#getOrCreate(atom).state;\n }\n\n getServerSnapshot<V>(atom: Atom<V>): AtomState<V> {\n const entry = this.#atoms.get(atom) as AtomEntry<V> | undefined;\n if (entry != null) {\n return entry.state;\n }\n return PENDING_STATE as AtomState<V>;\n }\n\n async set<V, A extends readonly unknown[]>(atom: WritableAtom<V, A>, ...args: A): Promise<void> {\n const config: InternalAtomConfig<V> = atom[CONFIG];\n if (config.set == null) {\n throw new Error(\n `Atom${atom.debugLabel != null ? ` \"${atom.debugLabel}\"` : \"\"} is not writable`,\n );\n }\n\n const deps = config.dependencies ?? {};\n const baseCtx = this.#makeCtx(atom, deps);\n const entry = this.#getOrCreate(atom);\n\n const optimisticSnapshot: {\n current: { state: AtomState<V>; version: number } | null;\n } = { current: null };\n const relatedSnapshots = new Map<\n Atom<unknown>,\n { state: AtomState<unknown>; version: number }\n >();\n\n const ctx: WritableAtomContext<Record<string, Atom<unknown>>, V> = {\n ...baseCtx,\n setOptimisticValue: (valueOrMutate: V | ((prev: V | undefined) => V)): void => {\n if (optimisticSnapshot.current == null) {\n optimisticSnapshot.current = { state: entry.state, version: entry.version };\n }\n const next =\n typeof valueOrMutate === \"function\"\n ? (valueOrMutate as (prev: V | undefined) => V)(extractPreviousValue(entry.state))\n : valueOrMutate;\n entry.state = { status: \"fresh\", value: next, error: undefined };\n entry.version++;\n this.#scheduleNotify(atom);\n this.#markReverseDependentsStale(atom);\n },\n writeOptimistic: <U>(\n target: Atom<U>,\n valueOrMutate: U | ((prev: U | undefined) => U),\n ): void => {\n this.#relatedOptimisticWrite(target, valueOrMutate, relatedSnapshots);\n },\n invalidate: (target: Atom<unknown>): void => this.invalidate(target),\n invalidateMany: (targets: ReadonlyArray<Atom<unknown>>): void => this.invalidateMany(targets),\n };\n\n try {\n await config.set(ctx, ...args);\n } catch (e: unknown) {\n const snap = optimisticSnapshot.current;\n if (snap != null) {\n entry.state = snap.state;\n entry.version = snap.version;\n this.#scheduleNotify(atom);\n }\n this.#rollbackRelatedSnapshots(relatedSnapshots);\n throw e;\n }\n\n this.invalidate(atom);\n }\n\n async mutate<Args extends readonly unknown[]>(\n mutation: Mutation<Args>,\n ...args: Args\n ): Promise<void> {\n const relatedSnapshots = new Map<\n Atom<unknown>,\n { state: AtomState<unknown>; version: number }\n >();\n\n const ctx: MutationContext = {\n writeOptimistic: <U>(\n target: Atom<U>,\n valueOrMutate: U | ((prev: U | undefined) => U),\n ): void => {\n this.#relatedOptimisticWrite(target, valueOrMutate, relatedSnapshots);\n },\n invalidate: (target: Atom<unknown>): void => this.invalidate(target),\n invalidateMany: (targets: ReadonlyArray<Atom<unknown>>): void => this.invalidateMany(targets),\n };\n\n try {\n await mutation[MUTATION_RUN](ctx, ...args);\n } catch (e: unknown) {\n this.#rollbackRelatedSnapshots(relatedSnapshots);\n throw e;\n }\n }\n\n write<V>(atom: Atom<V>, value: V): void;\n write<V>(atom: Atom<V>, mutate: (prev: V | undefined) => V): void;\n write<V>(atom: Atom<V>, valueOrMutate: V | ((prev: V | undefined) => V)): void {\n const entry = this.#getOrCreate(atom);\n this.#controllers.get(atom)?.abort();\n entry.promise = null;\n const next =\n typeof valueOrMutate === \"function\"\n ? (valueOrMutate as (prev: V | undefined) => V)(extractPreviousValue(entry.state))\n : valueOrMutate;\n entry.state = { status: \"fresh\", value: next, error: undefined };\n entry.version++;\n this.#scheduleNotify(atom);\n this.#markReverseDependentsStale(atom);\n }\n\n getClient(): StoreClient {\n if (this.#client != null) {\n return this.#client;\n }\n\n this.#client = {\n get: <V>(atom: Atom<V>): Promise<V> => this.resolve(atom),\n set: <V, A extends readonly unknown[]>(atom: WritableAtom<V, A>, ...args: A): Promise<void> =>\n this.set(atom, ...args),\n mutate: <Args extends readonly unknown[]>(m: Mutation<Args>, ...args: Args): Promise<void> =>\n this.mutate(m, ...args),\n write: <V>(atom: Atom<V>, valueOrMutate: V | ((prev: V | undefined) => V)): void =>\n this.write(atom, valueOrMutate as V),\n invalidate: (atom: Atom<unknown>): void => this.invalidate(atom),\n invalidateMany: (atoms: ReadonlyArray<Atom<unknown>>): void => this.invalidateMany(atoms),\n subscribe: <V>(atom: Atom<V>, listener: (state: AtomState<V>) => void): (() => void) =>\n this.subscribe(atom, () => {\n listener(this.getSnapshot(atom));\n }),\n };\n return this.#client;\n }\n}\n\nexport function createStore(): Store {\n return new Store();\n}\n\nfunction isAbortError(e: unknown): boolean {\n return e instanceof DOMException && e.name === \"AbortError\";\n}\n\nfunction extractPreviousValue<V>(state: AtomState<V>): V | undefined {\n if (state.status === \"stale\" || state.status === \"fresh\") {\n return state.value;\n }\n if (state.status === \"error\") {\n return state.value;\n }\n return undefined;\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types-B2mzc3A5.js","names":[],"sources":["../src/internal/types.ts"],"sourcesContent":["export const CONFIG = Symbol(\"kvark.config\");\nexport const WRITABLE = Symbol(\"kvark.writable\");\nexport const FAMILY_LINK = Symbol(\"kvark.familyLink\");\n\nexport type AtomState<Value> =\n | { status: \"pending\"; value: undefined; error: undefined }\n | { status: \"stale\"; value: Value; error: undefined }\n | { status: \"fresh\"; value: Value; error: undefined }\n | { status: \"error\"; value: Value | undefined; error: unknown };\n\nexport type StalePolicy = \"keep\" | \"suspend\" | \"reset\";\n\nexport type AtomContext<Deps extends Record<string, Atom<unknown>>> = {\n get: <K extends keyof Deps>(key: K) => Promise<AtomValue<Deps[K]>>;\n signal: AbortSignal;\n};\n\nexport interface WritableAtomContext
|
|
1
|
+
{"version":3,"file":"types-B2mzc3A5.js","names":[],"sources":["../src/internal/types.ts"],"sourcesContent":["export const CONFIG = Symbol(\"kvark.config\");\nexport const WRITABLE = Symbol(\"kvark.writable\");\nexport const FAMILY_LINK = Symbol(\"kvark.familyLink\");\n\nexport type AtomState<Value> =\n | { status: \"pending\"; value: undefined; error: undefined }\n | { status: \"stale\"; value: Value; error: undefined }\n | { status: \"fresh\"; value: Value; error: undefined }\n | { status: \"error\"; value: Value | undefined; error: unknown };\n\nexport type StalePolicy = \"keep\" | \"suspend\" | \"reset\";\n\nexport type AtomContext<Deps extends Record<string, Atom<unknown>>> = {\n get: <K extends keyof Deps>(key: K) => Promise<AtomValue<Deps[K]>>;\n signal: AbortSignal;\n};\n\n/** Context for standalone mutations: optimistic writes and invalidation (no primary atom). */\nexport type MutationContext = {\n writeOptimistic<U>(atom: Atom<U>, value: U): void;\n writeOptimistic<U>(atom: Atom<U>, mutate: (prev: U | undefined) => U): void;\n invalidate(atom: Atom<unknown>): void;\n invalidateMany(atoms: ReadonlyArray<Atom<unknown>>): void;\n};\n\nexport interface WritableAtomContext<Deps extends Record<string, Atom<unknown>>, Value>\n extends AtomContext<Deps>, MutationContext {\n setOptimisticValue(value: Value): void;\n setOptimisticValue(mutate: (prev: Value | undefined) => Value): void;\n}\n\nexport type AtomConfig<\n Value,\n Deps extends Record<string, Atom<unknown>>,\n Args extends readonly unknown[],\n> = {\n dependencies?: Deps;\n stalePolicy?: StalePolicy;\n debugLabel?: string;\n get: (ctx: AtomContext<Deps>) => Promise<Value>;\n set?: (ctx: WritableAtomContext<Deps, Value>, ...args: Args) => Promise<void>;\n onMount?: (set: (value: Value) => void) => (() => void) | void;\n};\n\nexport interface InternalAtomConfig<Value> {\n dependencies?: Record<string, Atom<unknown>>;\n stalePolicy?: StalePolicy;\n debugLabel?: string;\n get: (ctx: AtomContext<Record<string, Atom<unknown>>>) => Promise<Value>;\n // Internal erased config: `Value` in WritableAtomContext is invariant; `any` matches all atom instantiations.\n set?: (\n // oxlint-disable-next-line typescript/no-explicit-any\n ctx: WritableAtomContext<Record<string, Atom<unknown>>, any>,\n ...args: readonly unknown[]\n ) => Promise<void>;\n onMount?: (set: (value: unknown) => void) => (() => void) | void;\n}\n\nexport interface Atom<out Value> {\n readonly [CONFIG]: InternalAtomConfig<Value>;\n readonly debugLabel: string | undefined;\n}\n\nexport interface WritableAtom<\n out Value,\n in out Args extends readonly unknown[],\n> extends Atom<Value> {\n readonly [WRITABLE]: Args;\n}\n\nexport type AtomValue<A> = A extends Atom<infer V> ? V : never;\nexport type IsWritable<A> = A extends WritableAtom<unknown, readonly unknown[]> ? true : false;\nexport type AtomArgs<A> = A extends WritableAtom<unknown, infer Args> ? Args : never;\n"],"mappings":";AAAA,MAAa,SAAS,OAAO,eAAe;AAC5C,MAAa,WAAW,OAAO,iBAAiB;AAChD,MAAa,cAAc,OAAO,mBAAmB"}
|
package/dist/vue/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { h as WritableAtom, i as Mutation, n as StoreClient, o as Atom, t as Store } from "../store-DLoedZQo.js";
|
|
2
2
|
import * as _$vue from "vue";
|
|
3
3
|
import { PropType, ShallowRef } from "vue";
|
|
4
4
|
|
|
@@ -34,6 +34,9 @@ declare function useAtomValue<V>(atom: Atom<V>, opts: {
|
|
|
34
34
|
//#region src/vue/use-set-atom.d.ts
|
|
35
35
|
declare function useSetAtom<V, A extends readonly unknown[]>(atom: WritableAtom<V, A>): (...args: A) => Promise<void>;
|
|
36
36
|
//#endregion
|
|
37
|
+
//#region src/vue/use-mutation.d.ts
|
|
38
|
+
declare function useMutation<Args extends readonly unknown[]>(mutation: Mutation<Args>): (...args: Args) => Promise<void>;
|
|
39
|
+
//#endregion
|
|
37
40
|
//#region src/vue/use-atom.d.ts
|
|
38
41
|
type ThenableAtomTuple<V, A extends readonly unknown[]> = readonly [ThenableShallowRef<V>, (...args: A) => Promise<void>] & PromiseLike<readonly [Readonly<ShallowRef<V>>, (...args: A) => Promise<void>]>;
|
|
39
42
|
declare function useAtom<V, A extends readonly unknown[]>(atom: WritableAtom<V, A>): ThenableAtomTuple<V, A>;
|
|
@@ -41,5 +44,5 @@ declare function useAtom<V, A extends readonly unknown[]>(atom: WritableAtom<V,
|
|
|
41
44
|
//#region src/vue/use-atom-context.d.ts
|
|
42
45
|
declare function useAtomContext<R>(callback: (ctx: StoreClient) => Promise<R>): () => Promise<R>;
|
|
43
46
|
//#endregion
|
|
44
|
-
export { type ObservedValue, Provider, type ThenableObservedShallowRef, type ThenableShallowRef, useAtom, useAtomContext, useAtomValue, useSetAtom, useStore };
|
|
47
|
+
export { type ObservedValue, Provider, type ThenableObservedShallowRef, type ThenableShallowRef, useAtom, useAtomContext, useAtomValue, useMutation, useSetAtom, useStore };
|
|
45
48
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/vue/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../../src/vue/provider.ts","../../src/vue/use-atom-value.ts","../../src/vue/use-set-atom.ts","../../src/vue/use-atom.ts","../../src/vue/use-atom-context.ts"],"mappings":";;;;;cAKa,QAAA,QAAQ,eAAA,CAGgB,KAAA,CAHhB,gBAAA;;UAGQ,QAAA,CAAS,KAAA;;;sBAHjB,KAAA,CAAA,YAAA;;gIAGgB,KAAA,CAAA,gBAAA;;UAAR,QAAA,CAAS,KAAA;;;;iBAQtB,QAAA,CAAA,GAAY,KAAA;;;KCZhB,aAAA;EACV,KAAA,EAAO,CAAA;EACP,OAAA;EACA,KAAA;AAAA;AAAA,KAGU,kBAAA,MAAwB,QAAA,CAAS,UAAA,CAAW,CAAA,iBACtD,WAAA,CAAY,QAAA,CAAS,UAAA,CAAW,CAAA;AAAA,KAEtB,0BAAA,MAAgC,QAAA,CAAS,UAAA,CAAW,aAAA,CAAc,CAAA,MAC5E,WAAA,CAAY,QAAA,CAAS,UAAA,CAAW,aAAA,CAAc,CAAA;AAAA,iBAEhC,YAAA,GAAA,CAAgB,IAAA,EAAM,IAAA,CAAK,CAAA,IAAK,kBAAA,CAAmB,CAAA;AAAA,iBACnD,YAAA,GAAA,CACd,IAAA,EAAM,IAAA,CAAK,CAAA,GACX,IAAA;EAAQ,OAAA;AAAA,IACP,0BAAA,CAA2B,CAAA;;;iBCjBd,UAAA,iCAAA,CACd,IAAA,EAAM,YAAA,CAAa,CAAA,EAAG,CAAA,QACjB,IAAA,EAAM,CAAA,KAAM,OAAA;;;
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../../src/vue/provider.ts","../../src/vue/use-atom-value.ts","../../src/vue/use-set-atom.ts","../../src/vue/use-mutation.ts","../../src/vue/use-atom.ts","../../src/vue/use-atom-context.ts"],"mappings":";;;;;cAKa,QAAA,QAAQ,eAAA,CAGgB,KAAA,CAHhB,gBAAA;;UAGQ,QAAA,CAAS,KAAA;;;sBAHjB,KAAA,CAAA,YAAA;;gIAGgB,KAAA,CAAA,gBAAA;;UAAR,QAAA,CAAS,KAAA;;;;iBAQtB,QAAA,CAAA,GAAY,KAAA;;;KCZhB,aAAA;EACV,KAAA,EAAO,CAAA;EACP,OAAA;EACA,KAAA;AAAA;AAAA,KAGU,kBAAA,MAAwB,QAAA,CAAS,UAAA,CAAW,CAAA,iBACtD,WAAA,CAAY,QAAA,CAAS,UAAA,CAAW,CAAA;AAAA,KAEtB,0BAAA,MAAgC,QAAA,CAAS,UAAA,CAAW,aAAA,CAAc,CAAA,MAC5E,WAAA,CAAY,QAAA,CAAS,UAAA,CAAW,aAAA,CAAc,CAAA;AAAA,iBAEhC,YAAA,GAAA,CAAgB,IAAA,EAAM,IAAA,CAAK,CAAA,IAAK,kBAAA,CAAmB,CAAA;AAAA,iBACnD,YAAA,GAAA,CACd,IAAA,EAAM,IAAA,CAAK,CAAA,GACX,IAAA;EAAQ,OAAA;AAAA,IACP,0BAAA,CAA2B,CAAA;;;iBCjBd,UAAA,iCAAA,CACd,IAAA,EAAM,YAAA,CAAa,CAAA,EAAG,CAAA,QACjB,IAAA,EAAM,CAAA,KAAM,OAAA;;;iBCFH,WAAA,iCAAA,CACd,QAAA,EAAU,QAAA,CAAS,IAAA,QACd,IAAA,EAAM,IAAA,KAAS,OAAA;;;KCAjB,iBAAA,8CACH,kBAAA,CAAmB,CAAA,OACf,IAAA,EAAM,CAAA,KAAM,OAAA,UAEhB,WAAA,WAAsB,QAAA,CAAS,UAAA,CAAW,CAAA,QAAS,IAAA,EAAM,CAAA,KAAM,OAAA;AAAA,iBAEjD,OAAA,iCAAA,CACd,IAAA,EAAM,YAAA,CAAa,CAAA,EAAG,CAAA,IACrB,iBAAA,CAAkB,CAAA,EAAG,CAAA;;;iBCVR,cAAA,GAAA,CAAkB,QAAA,GAAW,GAAA,EAAK,WAAA,KAAgB,OAAA,CAAQ,CAAA,UAAW,OAAA,CAAQ,CAAA"}
|
package/dist/vue/index.js
CHANGED
|
@@ -74,6 +74,12 @@ function useSetAtom(atom) {
|
|
|
74
74
|
return (...args) => store.set(atom, ...args);
|
|
75
75
|
}
|
|
76
76
|
//#endregion
|
|
77
|
+
//#region src/vue/use-mutation.ts
|
|
78
|
+
function useMutation(mutation) {
|
|
79
|
+
const store = useStore();
|
|
80
|
+
return (...args) => store.mutate(mutation, ...args);
|
|
81
|
+
}
|
|
82
|
+
//#endregion
|
|
77
83
|
//#region src/vue/use-atom.ts
|
|
78
84
|
function useAtom(atom) {
|
|
79
85
|
const value = useAtomValue(atom);
|
|
@@ -89,6 +95,6 @@ function useAtomContext(callback) {
|
|
|
89
95
|
return () => callback(store.getClient());
|
|
90
96
|
}
|
|
91
97
|
//#endregion
|
|
92
|
-
export { Provider, useAtom, useAtomContext, useAtomValue, useSetAtom, useStore };
|
|
98
|
+
export { Provider, useAtom, useAtomContext, useAtomValue, useMutation, useSetAtom, useStore };
|
|
93
99
|
|
|
94
100
|
//# sourceMappingURL=index.js.map
|
package/dist/vue/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../src/vue/provider.ts","../../src/vue/use-atom-value.ts","../../src/vue/use-set-atom.ts","../../src/vue/use-atom.ts","../../src/vue/use-atom-context.ts"],"sourcesContent":["import { type InjectionKey, type PropType, defineComponent, inject, provide } from \"vue\";\nimport type { Store } from \"@/internal/store.js\";\n\nconst StoreKey: InjectionKey<Store> = Symbol(\"kvark-store\");\n\nexport const Provider = defineComponent({\n name: \"KvarkProvider\",\n props: {\n store: { type: Object as PropType<Store>, required: true },\n },\n setup(props, { slots }) {\n provide(StoreKey, props.store);\n return () => slots[\"default\"]?.();\n },\n});\n\nexport function useStore(): Store {\n const store = inject(StoreKey);\n if (store == null) {\n throw new Error(\"useStore must be used within a <Provider>\");\n }\n return store;\n}\n","import { type ShallowRef, readonly, shallowRef, watchEffect } from \"vue\";\nimport type { Atom, AtomState } from \"@/internal/types.js\";\nimport { useStore } from \"@/vue/provider.js\";\n\nexport type ObservedValue<V> = {\n value: V | undefined;\n isStale: boolean;\n error: unknown;\n};\n\nexport type ThenableShallowRef<V> = Readonly<ShallowRef<V | undefined>> &\n PromiseLike<Readonly<ShallowRef<V>>>;\n\nexport type ThenableObservedShallowRef<V> = Readonly<ShallowRef<ObservedValue<V>>> &\n PromiseLike<Readonly<ShallowRef<ObservedValue<V>>>>;\n\nexport function useAtomValue<V>(atom: Atom<V>): ThenableShallowRef<V>;\nexport function useAtomValue<V>(\n atom: Atom<V>,\n opts: { observe: true },\n): ThenableObservedShallowRef<V>;\nexport function useAtomValue<V>(\n atom: Atom<V>,\n opts?: { observe: true },\n): ThenableShallowRef<V> | ThenableObservedShallowRef<V> {\n const store = useStore();\n\n function derive(snapshot: AtomState<V>): V | ObservedValue<V> {\n if (snapshot.status === \"pending\") {\n void store.resolve(atom);\n if (opts?.observe === true) {\n return { value: undefined as V, isStale: false, error: undefined };\n }\n return undefined as V;\n }\n\n if (snapshot.status === \"stale\") {\n void store.resolve(atom);\n if (opts?.observe === true) {\n return { value: snapshot.value, isStale: true, error: undefined };\n }\n return snapshot.value;\n }\n\n if (snapshot.status === \"error\") {\n if (opts?.observe === true && snapshot.value !== undefined) {\n return { value: snapshot.value as V, isStale: false, error: snapshot.error };\n }\n throw snapshot.error;\n }\n\n // status === \"fresh\"\n if (opts?.observe === true) {\n return { value: snapshot.value, isStale: false, error: undefined };\n }\n return snapshot.value;\n }\n\n const result = shallowRef(derive(store.getSnapshot(atom)));\n\n watchEffect((onCleanup) => {\n const unsub = store.subscribe(atom, () => {\n result.value = derive(store.getSnapshot(atom));\n });\n onCleanup(unsub);\n });\n\n const ref = readonly(result);\n\n return new Proxy(ref, {\n get(target, prop, receiver) {\n if (prop === \"then\") {\n return (onFulfilled?: (v: unknown) => unknown, onRejected?: (e: unknown) => unknown) =>\n store\n .resolve(atom)\n .then(() => ref, onRejected)\n .then(onFulfilled as never);\n }\n return Reflect.get(target, prop, receiver);\n },\n }) as ThenableShallowRef<V> | ThenableObservedShallowRef<V>;\n}\n","import type { WritableAtom } from \"@/internal/types.js\";\nimport { useStore } from \"@/vue/provider.js\";\n\nexport function useSetAtom<V, A extends readonly unknown[]>(\n atom: WritableAtom<V, A>,\n): (...args: A) => Promise<void> {\n const store = useStore();\n return (...args: A): Promise<void> => store.set(atom, ...args);\n}\n","import type { ShallowRef } from \"vue\";\nimport type { WritableAtom } from \"@/internal/types.js\";\nimport { type ThenableShallowRef, useAtomValue } from \"@/vue/use-atom-value.js\";\nimport { useSetAtom } from \"@/vue/use-set-atom.js\";\n\ntype ThenableAtomTuple<V, A extends readonly unknown[]> = readonly [\n ThenableShallowRef<V>,\n (...args: A) => Promise<void>,\n] &\n PromiseLike<readonly [Readonly<ShallowRef<V>>, (...args: A) => Promise<void>]>;\n\nexport function useAtom<V, A extends readonly unknown[]>(\n atom: WritableAtom<V, A>,\n): ThenableAtomTuple<V, A> {\n const value = useAtomValue(atom);\n const setter = useSetAtom(atom);\n const tuple = [value, setter] as const;\n\n return Object.assign(tuple, {\n // oxlint-disable-next-line unicorn/no-thenable -- PromiseLike for await useAtom()\n then(onFulfilled?: (v: typeof tuple) => unknown, onRejected?: (e: unknown) => unknown) {\n return Promise.resolve(value)\n .then(() => [value, setter] as const, onRejected)\n .then(onFulfilled as never);\n },\n }) as ThenableAtomTuple<V, A>;\n}\n","import type { StoreClient } from \"@/internal/store.js\";\nimport { useStore } from \"@/vue/provider.js\";\n\nexport function useAtomContext<R>(callback: (ctx: StoreClient) => Promise<R>): () => Promise<R> {\n const store = useStore();\n return (): Promise<R> => callback(store.getClient());\n}\n"],"mappings":";;AAGA,MAAM,WAAgC,OAAO,cAAc;AAE3D,MAAa,WAAW,gBAAgB;CACtC,MAAM;CACN,OAAO,EACL,OAAO;EAAE,MAAM;EAA2B,UAAU;EAAM,EAC3D;CACD,MAAM,OAAO,EAAE,SAAS;AACtB,UAAQ,UAAU,MAAM,MAAM;AAC9B,eAAa,MAAM,cAAc;;CAEpC,CAAC;AAEF,SAAgB,WAAkB;CAChC,MAAM,QAAQ,OAAO,SAAS;AAC9B,KAAI,SAAS,KACX,OAAM,IAAI,MAAM,4CAA4C;AAE9D,QAAO;;;;ACAT,SAAgB,aACd,MACA,MACuD;CACvD,MAAM,QAAQ,UAAU;CAExB,SAAS,OAAO,UAA8C;AAC5D,MAAI,SAAS,WAAW,WAAW;AAC5B,SAAM,QAAQ,KAAK;AACxB,OAAI,MAAM,YAAY,KACpB,QAAO;IAAE,OAAO,KAAA;IAAgB,SAAS;IAAO,OAAO,KAAA;IAAW;AAEpE;;AAGF,MAAI,SAAS,WAAW,SAAS;AAC1B,SAAM,QAAQ,KAAK;AACxB,OAAI,MAAM,YAAY,KACpB,QAAO;IAAE,OAAO,SAAS;IAAO,SAAS;IAAM,OAAO,KAAA;IAAW;AAEnE,UAAO,SAAS;;AAGlB,MAAI,SAAS,WAAW,SAAS;AAC/B,OAAI,MAAM,YAAY,QAAQ,SAAS,UAAU,KAAA,EAC/C,QAAO;IAAE,OAAO,SAAS;IAAY,SAAS;IAAO,OAAO,SAAS;IAAO;AAE9E,SAAM,SAAS;;AAIjB,MAAI,MAAM,YAAY,KACpB,QAAO;GAAE,OAAO,SAAS;GAAO,SAAS;GAAO,OAAO,KAAA;GAAW;AAEpE,SAAO,SAAS;;CAGlB,MAAM,SAAS,WAAW,OAAO,MAAM,YAAY,KAAK,CAAC,CAAC;AAE1D,cAAa,cAAc;AAIzB,YAHc,MAAM,UAAU,YAAY;AACxC,UAAO,QAAQ,OAAO,MAAM,YAAY,KAAK,CAAC;IAC9C,CACc;GAChB;CAEF,MAAM,MAAM,SAAS,OAAO;AAE5B,QAAO,IAAI,MAAM,KAAK,EACpB,IAAI,QAAQ,MAAM,UAAU;AAC1B,MAAI,SAAS,OACX,SAAQ,aAAuC,eAC7C,MACG,QAAQ,KAAK,CACb,WAAW,KAAK,WAAW,CAC3B,KAAK,YAAqB;AAEjC,SAAO,QAAQ,IAAI,QAAQ,MAAM,SAAS;IAE7C,CAAC;;;;AC7EJ,SAAgB,WACd,MAC+B;CAC/B,MAAM,QAAQ,UAAU;AACxB,SAAQ,GAAG,SAA2B,MAAM,IAAI,MAAM,GAAG,KAAK;;;;
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../src/vue/provider.ts","../../src/vue/use-atom-value.ts","../../src/vue/use-set-atom.ts","../../src/vue/use-mutation.ts","../../src/vue/use-atom.ts","../../src/vue/use-atom-context.ts"],"sourcesContent":["import { type InjectionKey, type PropType, defineComponent, inject, provide } from \"vue\";\nimport type { Store } from \"@/internal/store.js\";\n\nconst StoreKey: InjectionKey<Store> = Symbol(\"kvark-store\");\n\nexport const Provider = defineComponent({\n name: \"KvarkProvider\",\n props: {\n store: { type: Object as PropType<Store>, required: true },\n },\n setup(props, { slots }) {\n provide(StoreKey, props.store);\n return () => slots[\"default\"]?.();\n },\n});\n\nexport function useStore(): Store {\n const store = inject(StoreKey);\n if (store == null) {\n throw new Error(\"useStore must be used within a <Provider>\");\n }\n return store;\n}\n","import { type ShallowRef, readonly, shallowRef, watchEffect } from \"vue\";\nimport type { Atom, AtomState } from \"@/internal/types.js\";\nimport { useStore } from \"@/vue/provider.js\";\n\nexport type ObservedValue<V> = {\n value: V | undefined;\n isStale: boolean;\n error: unknown;\n};\n\nexport type ThenableShallowRef<V> = Readonly<ShallowRef<V | undefined>> &\n PromiseLike<Readonly<ShallowRef<V>>>;\n\nexport type ThenableObservedShallowRef<V> = Readonly<ShallowRef<ObservedValue<V>>> &\n PromiseLike<Readonly<ShallowRef<ObservedValue<V>>>>;\n\nexport function useAtomValue<V>(atom: Atom<V>): ThenableShallowRef<V>;\nexport function useAtomValue<V>(\n atom: Atom<V>,\n opts: { observe: true },\n): ThenableObservedShallowRef<V>;\nexport function useAtomValue<V>(\n atom: Atom<V>,\n opts?: { observe: true },\n): ThenableShallowRef<V> | ThenableObservedShallowRef<V> {\n const store = useStore();\n\n function derive(snapshot: AtomState<V>): V | ObservedValue<V> {\n if (snapshot.status === \"pending\") {\n void store.resolve(atom);\n if (opts?.observe === true) {\n return { value: undefined as V, isStale: false, error: undefined };\n }\n return undefined as V;\n }\n\n if (snapshot.status === \"stale\") {\n void store.resolve(atom);\n if (opts?.observe === true) {\n return { value: snapshot.value, isStale: true, error: undefined };\n }\n return snapshot.value;\n }\n\n if (snapshot.status === \"error\") {\n if (opts?.observe === true && snapshot.value !== undefined) {\n return { value: snapshot.value as V, isStale: false, error: snapshot.error };\n }\n throw snapshot.error;\n }\n\n // status === \"fresh\"\n if (opts?.observe === true) {\n return { value: snapshot.value, isStale: false, error: undefined };\n }\n return snapshot.value;\n }\n\n const result = shallowRef(derive(store.getSnapshot(atom)));\n\n watchEffect((onCleanup) => {\n const unsub = store.subscribe(atom, () => {\n result.value = derive(store.getSnapshot(atom));\n });\n onCleanup(unsub);\n });\n\n const ref = readonly(result);\n\n return new Proxy(ref, {\n get(target, prop, receiver) {\n if (prop === \"then\") {\n return (onFulfilled?: (v: unknown) => unknown, onRejected?: (e: unknown) => unknown) =>\n store\n .resolve(atom)\n .then(() => ref, onRejected)\n .then(onFulfilled as never);\n }\n return Reflect.get(target, prop, receiver);\n },\n }) as ThenableShallowRef<V> | ThenableObservedShallowRef<V>;\n}\n","import type { WritableAtom } from \"@/internal/types.js\";\nimport { useStore } from \"@/vue/provider.js\";\n\nexport function useSetAtom<V, A extends readonly unknown[]>(\n atom: WritableAtom<V, A>,\n): (...args: A) => Promise<void> {\n const store = useStore();\n return (...args: A): Promise<void> => store.set(atom, ...args);\n}\n","import type { Mutation } from \"@/internal/mutation.js\";\nimport { useStore } from \"@/vue/provider.js\";\n\nexport function useMutation<Args extends readonly unknown[]>(\n mutation: Mutation<Args>,\n): (...args: Args) => Promise<void> {\n const store = useStore();\n return (...args: Args): Promise<void> => store.mutate(mutation, ...args);\n}\n","import type { ShallowRef } from \"vue\";\nimport type { WritableAtom } from \"@/internal/types.js\";\nimport { type ThenableShallowRef, useAtomValue } from \"@/vue/use-atom-value.js\";\nimport { useSetAtom } from \"@/vue/use-set-atom.js\";\n\ntype ThenableAtomTuple<V, A extends readonly unknown[]> = readonly [\n ThenableShallowRef<V>,\n (...args: A) => Promise<void>,\n] &\n PromiseLike<readonly [Readonly<ShallowRef<V>>, (...args: A) => Promise<void>]>;\n\nexport function useAtom<V, A extends readonly unknown[]>(\n atom: WritableAtom<V, A>,\n): ThenableAtomTuple<V, A> {\n const value = useAtomValue(atom);\n const setter = useSetAtom(atom);\n const tuple = [value, setter] as const;\n\n return Object.assign(tuple, {\n // oxlint-disable-next-line unicorn/no-thenable -- PromiseLike for await useAtom()\n then(onFulfilled?: (v: typeof tuple) => unknown, onRejected?: (e: unknown) => unknown) {\n return Promise.resolve(value)\n .then(() => [value, setter] as const, onRejected)\n .then(onFulfilled as never);\n },\n }) as ThenableAtomTuple<V, A>;\n}\n","import type { StoreClient } from \"@/internal/store.js\";\nimport { useStore } from \"@/vue/provider.js\";\n\nexport function useAtomContext<R>(callback: (ctx: StoreClient) => Promise<R>): () => Promise<R> {\n const store = useStore();\n return (): Promise<R> => callback(store.getClient());\n}\n"],"mappings":";;AAGA,MAAM,WAAgC,OAAO,cAAc;AAE3D,MAAa,WAAW,gBAAgB;CACtC,MAAM;CACN,OAAO,EACL,OAAO;EAAE,MAAM;EAA2B,UAAU;EAAM,EAC3D;CACD,MAAM,OAAO,EAAE,SAAS;AACtB,UAAQ,UAAU,MAAM,MAAM;AAC9B,eAAa,MAAM,cAAc;;CAEpC,CAAC;AAEF,SAAgB,WAAkB;CAChC,MAAM,QAAQ,OAAO,SAAS;AAC9B,KAAI,SAAS,KACX,OAAM,IAAI,MAAM,4CAA4C;AAE9D,QAAO;;;;ACAT,SAAgB,aACd,MACA,MACuD;CACvD,MAAM,QAAQ,UAAU;CAExB,SAAS,OAAO,UAA8C;AAC5D,MAAI,SAAS,WAAW,WAAW;AAC5B,SAAM,QAAQ,KAAK;AACxB,OAAI,MAAM,YAAY,KACpB,QAAO;IAAE,OAAO,KAAA;IAAgB,SAAS;IAAO,OAAO,KAAA;IAAW;AAEpE;;AAGF,MAAI,SAAS,WAAW,SAAS;AAC1B,SAAM,QAAQ,KAAK;AACxB,OAAI,MAAM,YAAY,KACpB,QAAO;IAAE,OAAO,SAAS;IAAO,SAAS;IAAM,OAAO,KAAA;IAAW;AAEnE,UAAO,SAAS;;AAGlB,MAAI,SAAS,WAAW,SAAS;AAC/B,OAAI,MAAM,YAAY,QAAQ,SAAS,UAAU,KAAA,EAC/C,QAAO;IAAE,OAAO,SAAS;IAAY,SAAS;IAAO,OAAO,SAAS;IAAO;AAE9E,SAAM,SAAS;;AAIjB,MAAI,MAAM,YAAY,KACpB,QAAO;GAAE,OAAO,SAAS;GAAO,SAAS;GAAO,OAAO,KAAA;GAAW;AAEpE,SAAO,SAAS;;CAGlB,MAAM,SAAS,WAAW,OAAO,MAAM,YAAY,KAAK,CAAC,CAAC;AAE1D,cAAa,cAAc;AAIzB,YAHc,MAAM,UAAU,YAAY;AACxC,UAAO,QAAQ,OAAO,MAAM,YAAY,KAAK,CAAC;IAC9C,CACc;GAChB;CAEF,MAAM,MAAM,SAAS,OAAO;AAE5B,QAAO,IAAI,MAAM,KAAK,EACpB,IAAI,QAAQ,MAAM,UAAU;AAC1B,MAAI,SAAS,OACX,SAAQ,aAAuC,eAC7C,MACG,QAAQ,KAAK,CACb,WAAW,KAAK,WAAW,CAC3B,KAAK,YAAqB;AAEjC,SAAO,QAAQ,IAAI,QAAQ,MAAM,SAAS;IAE7C,CAAC;;;;AC7EJ,SAAgB,WACd,MAC+B;CAC/B,MAAM,QAAQ,UAAU;AACxB,SAAQ,GAAG,SAA2B,MAAM,IAAI,MAAM,GAAG,KAAK;;;;ACJhE,SAAgB,YACd,UACkC;CAClC,MAAM,QAAQ,UAAU;AACxB,SAAQ,GAAG,SAA8B,MAAM,OAAO,UAAU,GAAG,KAAK;;;;ACI1E,SAAgB,QACd,MACyB;CACzB,MAAM,QAAQ,aAAa,KAAK;CAChC,MAAM,SAAS,WAAW,KAAK;AAG/B,QAAO,OAAO,OAFA,CAAC,OAAO,OAAO,EAED,EAE1B,KAAK,aAA4C,YAAsC;AACrF,SAAO,QAAQ,QAAQ,MAAM,CAC1B,WAAW,CAAC,OAAO,OAAO,EAAW,WAAW,CAChD,KAAK,YAAqB;IAEhC,CAAC;;;;ACtBJ,SAAgB,eAAkB,UAA8D;CAC9F,MAAM,QAAQ,UAAU;AACxB,cAAyB,SAAS,MAAM,WAAW,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kdeveloper/kvark",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"description": "Atomic state management with explicit dependency graphs",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"files": [
|
|
@@ -19,6 +19,10 @@
|
|
|
19
19
|
"types": "./dist/react/index.d.ts",
|
|
20
20
|
"import": "./dist/react/index.js"
|
|
21
21
|
},
|
|
22
|
+
"./preact": {
|
|
23
|
+
"types": "./dist/preact/index.d.ts",
|
|
24
|
+
"import": "./dist/preact/index.js"
|
|
25
|
+
},
|
|
22
26
|
"./vue": {
|
|
23
27
|
"types": "./dist/vue/index.d.ts",
|
|
24
28
|
"import": "./dist/vue/index.js"
|
|
@@ -30,6 +34,7 @@
|
|
|
30
34
|
},
|
|
31
35
|
"devDependencies": {
|
|
32
36
|
"@testing-library/dom": "^10.4.1",
|
|
37
|
+
"@testing-library/preact": "^3.2.4",
|
|
33
38
|
"@testing-library/react": "^16.3.2",
|
|
34
39
|
"@types/node": "^25.5.0",
|
|
35
40
|
"@types/react": "^19.2.14",
|
|
@@ -39,6 +44,7 @@
|
|
|
39
44
|
"oxfmt": "^0.42.0",
|
|
40
45
|
"oxlint": "^1.57.0",
|
|
41
46
|
"oxlint-tsgolint": "^0.18.1",
|
|
47
|
+
"preact": "^10.29.0",
|
|
42
48
|
"react": ">=18",
|
|
43
49
|
"react-dom": "^19.2.4",
|
|
44
50
|
"tsdown": "^0.21.7",
|
|
@@ -47,6 +53,7 @@
|
|
|
47
53
|
"vue": "^3.5.31"
|
|
48
54
|
},
|
|
49
55
|
"peerDependencies": {
|
|
56
|
+
"preact": ">=10",
|
|
50
57
|
"react": ">=18",
|
|
51
58
|
"vue": ">=3.4"
|
|
52
59
|
},
|
|
@@ -54,6 +61,9 @@
|
|
|
54
61
|
"react": {
|
|
55
62
|
"optional": true
|
|
56
63
|
},
|
|
64
|
+
"preact": {
|
|
65
|
+
"optional": true
|
|
66
|
+
},
|
|
57
67
|
"vue": {
|
|
58
68
|
"optional": true
|
|
59
69
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"store-Cng0OzIQ.d.ts","names":[],"sources":["../src/internal/types.ts","../src/internal/store.ts"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"store-DuKg4_ng.js","names":["#maxSize","#nodeMap","#valueMap","#head","#tail","#moveToMru","#insertBeforeTail","#evict","#detach","#atoms","#rdeps","#pending","#controllers","#familyUnsubs","#registeredFamilies","#getOrCreate","#runGet","#registerRdeps","#makeCtx","#scheduleNotify","#markStale","#schedulePendingFlush","#flushScheduled","#flushPending","#autoRegisterFamily","#markReverseDependentsStale","#client"],"sources":["../src/internal/atom.ts","../src/internal/lru-cache.ts","../src/internal/family.ts","../src/internal/store.ts"],"sourcesContent":["import type {\n Atom,\n AtomConfig,\n InternalAtomConfig,\n WritableAtom,\n WritableAtomContext,\n} from \"@/internal/types.js\";\nimport { CONFIG, WRITABLE } from \"@/internal/types.js\";\n\ntype WritableConfig<\n Value,\n Deps extends Record<string, Atom<unknown>>,\n Args extends readonly unknown[],\n> = AtomConfig<Value, Deps, Args> & {\n set: (ctx: WritableAtomContext<Deps, Value>, ...args: Args) => Promise<void>;\n};\n\ntype ReadonlyConfig<Value, Deps extends Record<string, Atom<unknown>>> = Omit<\n AtomConfig<Value, Deps, readonly []>,\n \"set\"\n>;\n\nexport function atom<\n Value,\n Deps extends Record<string, Atom<unknown>> = Record<never, never>,\n Args extends readonly unknown[] = readonly [],\n>(config: WritableConfig<Value, Deps, Args>): WritableAtom<Value, Args>;\n\nexport function atom<Value, Deps extends Record<string, Atom<unknown>> = Record<never, never>>(\n config: ReadonlyConfig<Value, Deps>,\n): Atom<Value>;\n\nexport function atom<\n Value,\n Deps extends Record<string, Atom<unknown>> = Record<never, never>,\n Args extends readonly unknown[] = readonly [],\n>(config: AtomConfig<Value, Deps, Args>): Atom<Value> {\n const internal: InternalAtomConfig<Value> = Object.create(null) as InternalAtomConfig<Value>;\n internal.get = config.get as InternalAtomConfig<Value>[\"get\"];\n\n if (config.debugLabel != null) {\n internal.debugLabel = config.debugLabel;\n }\n if (config.dependencies != null) {\n internal.dependencies = config.dependencies as Record<string, Atom<unknown>>;\n }\n if (config.stalePolicy != null) {\n internal.stalePolicy = config.stalePolicy;\n }\n if (config.set != null) {\n internal.set = config.set as NonNullable<InternalAtomConfig<Value>[\"set\"]>;\n }\n if (config.onMount != null) {\n internal.onMount = config.onMount as NonNullable<InternalAtomConfig<Value>[\"onMount\"]>;\n }\n\n if (config.set != null) {\n return {\n [CONFIG]: internal,\n [WRITABLE]: [] as unknown as Args,\n debugLabel: config.debugLabel,\n } as unknown as Atom<Value>;\n }\n\n return {\n [CONFIG]: internal,\n debugLabel: config.debugLabel,\n } as Atom<Value>;\n}\n","type LruNode<K> = {\n key: K;\n prev: LruNode<K> | null;\n next: LruNode<K> | null;\n};\n\n/**\n * Fixed-capacity cache with O(1) get, set, delete and LRU eviction.\n *\n * Pass `maxSize: Infinity` to disable eviction (keep-all semantics).\n *\n * LRU end (oldest): head.next — MRU end (newest): tail.prev.\n */\nexport class LruCache<K, V> {\n readonly #maxSize: number;\n readonly #nodeMap = new Map<K, LruNode<K>>();\n readonly #valueMap = new Map<K, V>();\n readonly #head: LruNode<K>;\n readonly #tail: LruNode<K>;\n\n constructor(maxSize: number) {\n this.#maxSize = maxSize;\n this.#head = { key: undefined as unknown as K, prev: null, next: null };\n this.#tail = { key: undefined as unknown as K, prev: this.#head, next: null };\n this.#head.next = this.#tail;\n }\n\n /** Returns the value and marks the entry as most-recently used. */\n get(key: K): V | undefined {\n const node = this.#nodeMap.get(key);\n if (node == null) {\n return undefined;\n }\n this.#moveToMru(node);\n return this.#valueMap.get(key);\n }\n\n /** Returns the value without affecting LRU order. */\n peek(key: K): V | undefined {\n return this.#valueMap.get(key);\n }\n\n /** Inserts or updates a value and evicts the LRU entry if over capacity. */\n set(key: K, value: V): void {\n const existing = this.#nodeMap.get(key);\n if (existing != null) {\n this.#valueMap.set(key, value);\n this.#moveToMru(existing);\n return;\n }\n\n const node: LruNode<K> = { key, prev: null, next: null };\n this.#nodeMap.set(key, node);\n this.#valueMap.set(key, value);\n this.#insertBeforeTail(node);\n this.#evict();\n }\n\n delete(key: K): void {\n const node = this.#nodeMap.get(key);\n if (node == null) {\n return;\n }\n this.#detach(node);\n this.#nodeMap.delete(key);\n this.#valueMap.delete(key);\n }\n\n values(): IterableIterator<V> {\n return this.#valueMap.values();\n }\n\n /** Returns a live read-only view of the underlying map. */\n asReadonlyMap(): ReadonlyMap<K, V> {\n return this.#valueMap;\n }\n\n #moveToMru(node: LruNode<K>): void {\n this.#detach(node);\n this.#insertBeforeTail(node);\n }\n\n #detach(node: LruNode<K>): void {\n const { prev, next } = node;\n if (prev == null || next == null) {\n return;\n }\n prev.next = next;\n next.prev = prev;\n }\n\n #insertBeforeTail(node: LruNode<K>): void {\n const before = this.#tail.prev;\n if (before == null) {\n return;\n }\n before.next = node;\n node.prev = before;\n node.next = this.#tail;\n this.#tail.prev = node;\n }\n\n #evict(): void {\n if (!Number.isFinite(this.#maxSize)) {\n return;\n }\n while (this.#nodeMap.size > this.#maxSize) {\n const oldest = this.#head.next;\n if (oldest == null) {\n break;\n }\n this.#detach(oldest);\n this.#nodeMap.delete(oldest.key);\n this.#valueMap.delete(oldest.key);\n }\n }\n}\n","import type { Atom, AtomContext, StalePolicy } from \"@/internal/types.js\";\nimport { FAMILY_LINK } from \"@/internal/types.js\";\nimport { atom } from \"@/internal/atom.js\";\nimport { LruCache } from \"@/internal/lru-cache.js\";\n\nexport type AtomFamilyOptions<\n Param,\n Value,\n Deps extends Record<string, Atom<unknown>>,\n Args extends readonly unknown[],\n Key = Param,\n> = {\n dependencies?: (param: Param) => Deps;\n stalePolicy?: StalePolicy;\n cachePolicy?: \"keep-all\" | \"lru\";\n lruSize?: number;\n debugLabel?: string;\n /**\n * Optional function to derive a stable cache key from `param`.\n * Use when `Param` is an object and you want equality-by-value semantics.\n * The returned key is used for all cache operations (get, set, LRU, invalidate, remove).\n * The original `param` is still passed to `get`, `set`, and `dependencies`.\n *\n * For plain objects/arrays you can use `stableFamilyKey` from `@kdeveloper/kvark/family`.\n * Treat the param object as immutable after the first call — `stableFamilyKey` memoises\n * by object reference via a WeakMap.\n */\n paramKey?: (param: Param) => Key;\n get: (param: Param) => (ctx: AtomContext<Deps>) => Promise<Value>;\n set?: (param: Param) => (ctx: AtomContext<Deps>, ...args: Args) => Promise<void>;\n};\n\nexport interface AtomFamily<Param, Value, Key = Param> {\n (param: Param): Atom<Value>;\n invalidate(param: Param): void;\n invalidateAll(): void;\n remove(param: Param): void;\n getCache(): ReadonlyMap<Key, Atom<Value>>;\n}\n\nexport interface FamilyLink {\n invalidateAtom: (atom: Atom<unknown>) => void;\n registerStore: (cb: (atom: Atom<unknown>) => void) => () => void;\n}\n\nexport function getFamilyLink(target: Atom<unknown>): FamilyLink | undefined {\n return (target as unknown as Record<symbol, FamilyLink | undefined>)[FAMILY_LINK];\n}\n\nexport function atomFamily<\n Param,\n Value,\n Deps extends Record<string, Atom<unknown>> = Record<never, never>,\n Args extends readonly unknown[] = readonly [],\n Key = Param,\n>(options: AtomFamilyOptions<Param, Value, Deps, Args, Key>): AtomFamily<Param, Value, Key> {\n const maxSize = options.cachePolicy === \"lru\" ? (options.lruSize ?? 100) : Infinity;\n const cache = new LruCache<Key, Atom<Value>>(maxSize);\n const storeCallbacks = new Set<(atom: Atom<unknown>) => void>();\n\n function keyOf(param: Param): Key {\n return options.paramKey != null ? options.paramKey(param) : (param as unknown as Key);\n }\n\n const link: FamilyLink = {\n invalidateAtom(target: Atom<unknown>): void {\n for (const cb of storeCallbacks) {\n cb(target);\n }\n },\n registerStore(cb: (atom: Atom<unknown>) => void): () => void {\n storeCallbacks.add(cb);\n return () => {\n storeCallbacks.delete(cb);\n };\n },\n };\n\n function attachLink(target: Atom<Value>): void {\n (target as unknown as Record<symbol, FamilyLink>)[FAMILY_LINK] = link;\n }\n\n function getOrCreate(param: Param): Atom<Value> {\n const key = keyOf(param);\n const cached = cache.get(key);\n if (cached != null) {\n return cached;\n }\n\n const deps = options.dependencies?.(param);\n const getFn = options.get(param);\n const setFn = options.set?.(param);\n\n const labelSuffix = options.paramKey != null ? String(key) : String(param);\n const label = options.debugLabel != null ? `${options.debugLabel}(${labelSuffix})` : undefined;\n\n const created = createAtom(label, deps, getFn, setFn);\n attachLink(created);\n cache.set(key, created);\n\n return created;\n }\n\n function createAtom(\n label: string | undefined,\n deps: Deps | undefined,\n getFn: (ctx: AtomContext<Deps>) => Promise<Value>,\n setFn: ((ctx: AtomContext<Deps>, ...args: Args) => Promise<void>) | undefined,\n ): Atom<Value> {\n const base = {\n get: getFn as (ctx: AtomContext<Deps>) => Promise<Value>,\n } as {\n debugLabel?: string;\n dependencies?: Deps;\n stalePolicy?: StalePolicy;\n get: (ctx: AtomContext<Deps>) => Promise<Value>;\n set?: (ctx: AtomContext<Deps>, ...args: Args) => Promise<void>;\n };\n\n if (label != null) {\n base.debugLabel = label;\n }\n if (deps != null) {\n base.dependencies = deps;\n }\n if (options.stalePolicy != null) {\n base.stalePolicy = options.stalePolicy;\n }\n\n if (setFn != null) {\n base.set = setFn;\n return atom(\n base as typeof base & {\n set: (ctx: AtomContext<Deps>, ...args: Args) => Promise<void>;\n },\n ) as Atom<Value>;\n }\n\n return atom(base as Omit<typeof base, \"set\">);\n }\n\n const family = getOrCreate as AtomFamily<Param, Value, Key>;\n\n family.invalidate = (param: Param): void => {\n const cached = cache.peek(keyOf(param));\n if (cached != null) {\n link.invalidateAtom(cached);\n }\n };\n\n family.invalidateAll = (): void => {\n for (const cached of cache.values()) {\n link.invalidateAtom(cached);\n }\n };\n\n family.remove = (param: Param): void => {\n cache.delete(keyOf(param));\n };\n\n family.getCache = (): ReadonlyMap<Key, Atom<Value>> => cache.asReadonlyMap();\n\n return family;\n}\n","import type {\n Atom,\n AtomContext,\n AtomState,\n InternalAtomConfig,\n StalePolicy,\n WritableAtom,\n WritableAtomContext,\n} from \"@/internal/types.js\";\nimport { CONFIG } from \"@/internal/types.js\";\nimport { getFamilyLink } from \"@/internal/family.js\";\n\ntype AtomEntry<V> = {\n state: AtomState<V>;\n version: number;\n promise: Promise<V> | null;\n listeners: Set<() => void>;\n mountCount: number;\n unmount: (() => void) | null;\n};\n\nexport interface StoreClient {\n get<V>(atom: Atom<V>): Promise<V>;\n set<V, A extends readonly unknown[]>(atom: WritableAtom<V, A>, ...args: A): Promise<void>;\n write<V>(atom: Atom<V>, value: V): void;\n write<V>(atom: Atom<V>, mutate: (prev: V | undefined) => V): void;\n invalidate(atom: Atom<unknown>): void;\n invalidateMany(atoms: ReadonlyArray<Atom<unknown>>): void;\n subscribe<V>(atom: Atom<V>, listener: (state: AtomState<V>) => void): () => void;\n}\n\nconst PENDING_STATE: AtomState<never> = {\n status: \"pending\",\n value: undefined,\n error: undefined,\n} as AtomState<never>;\n\nexport class Store {\n readonly #atoms = new WeakMap<Atom<unknown>, AtomEntry<unknown>>();\n readonly #rdeps = new Map<Atom<unknown>, Set<Atom<unknown>>>();\n readonly #pending = new Set<Atom<unknown>>();\n readonly #controllers = new WeakMap<Atom<unknown>, AbortController>();\n readonly #familyUnsubs = new Set<() => void>();\n readonly #registeredFamilies = new WeakSet<object>();\n #client: StoreClient | null = null;\n #flushScheduled = false;\n\n #getOrCreate<V>(atom: Atom<V>): AtomEntry<V> {\n let entry = this.#atoms.get(atom) as AtomEntry<V> | undefined;\n if (entry == null) {\n entry = {\n state: PENDING_STATE as AtomState<V>,\n version: 0,\n promise: null,\n listeners: new Set(),\n mountCount: 0,\n unmount: null,\n };\n this.#atoms.set(atom, entry as AtomEntry<unknown>);\n }\n return entry;\n }\n\n resolve<V>(atom: Atom<V>): Promise<V> {\n const entry = this.#getOrCreate(atom);\n if (entry.promise != null) {\n return entry.promise;\n }\n\n const promise = this.#runGet(atom).finally(() => {\n const e = this.#atoms.get(atom) as AtomEntry<V> | undefined;\n if (e != null) {\n e.promise = null;\n }\n });\n entry.promise = promise;\n return promise;\n }\n\n async #runGet<V>(atom: Atom<V>): Promise<V> {\n const config: InternalAtomConfig<V> = atom[CONFIG];\n const dependencies = config.dependencies;\n const stalePolicy: StalePolicy = config.stalePolicy ?? \"keep\";\n const entry = this.#getOrCreate(atom);\n\n if (dependencies != null) {\n await Promise.all(Object.values(dependencies).map((dep) => this.resolve(dep)));\n this.#registerRdeps(atom, dependencies);\n }\n\n const ctx = this.#makeCtx(atom, dependencies ?? {});\n\n try {\n const value = await config.get(ctx);\n if (ctx.signal.aborted) {\n throw new DOMException(\"The operation was aborted\", \"AbortError\");\n }\n entry.state = { status: \"fresh\", value, error: undefined };\n entry.version++;\n this.#scheduleNotify(atom);\n return value;\n } catch (e: unknown) {\n if (isAbortError(e)) {\n throw e;\n }\n const prevValue = extractPreviousValue<V>(entry.state);\n entry.state = {\n status: \"error\",\n value: stalePolicy === \"keep\" ? prevValue : undefined,\n error: e,\n } as AtomState<V>;\n entry.version++;\n this.#scheduleNotify(atom);\n throw e;\n }\n }\n\n invalidate(atom: Atom<unknown>): void {\n this.#markStale(atom);\n this.#pending.add(atom);\n this.#schedulePendingFlush();\n }\n\n invalidateMany(atoms: ReadonlyArray<Atom<unknown>>): void {\n for (const a of atoms) {\n this.#markStale(a);\n this.#pending.add(a);\n }\n if (this.#pending.size > 0) {\n this.#schedulePendingFlush();\n }\n }\n\n #markStale(atom: Atom<unknown>, visited = new Set<Atom<unknown>>()): void {\n if (visited.has(atom)) {\n return;\n }\n visited.add(atom);\n\n const entry = this.#atoms.get(atom);\n if (entry != null) {\n const stalePolicy: StalePolicy = atom[CONFIG].stalePolicy ?? \"keep\";\n\n if (entry.state.status === \"fresh\") {\n if (stalePolicy === \"reset\") {\n entry.state = PENDING_STATE;\n } else {\n entry.state = { ...entry.state, status: \"stale\" };\n }\n }\n\n entry.promise = null;\n this.#controllers.get(atom)?.abort();\n }\n\n const rdeps = this.#rdeps.get(atom);\n if (rdeps != null) {\n for (const dep of rdeps) {\n this.#markStale(dep, visited);\n }\n }\n }\n\n #markReverseDependentsStale(atom: Atom<unknown>): void {\n const rdeps = this.#rdeps.get(atom);\n if (rdeps != null) {\n const visited = new Set<Atom<unknown>>([atom]);\n for (const dep of rdeps) {\n this.#markStale(dep, visited);\n this.#pending.add(dep);\n }\n }\n }\n\n #flushPending(): void {\n const batch = [...this.#pending];\n this.#pending.clear();\n const toNotify = new Set<() => void>();\n for (const a of batch) {\n const entry = this.#atoms.get(a);\n if (entry != null) {\n for (const l of entry.listeners) {\n toNotify.add(l);\n }\n }\n }\n for (const l of toNotify) {\n l();\n }\n }\n\n #schedulePendingFlush(): void {\n if (!this.#flushScheduled) {\n this.#flushScheduled = true;\n queueMicrotask(() => {\n this.#flushScheduled = false;\n this.#flushPending();\n });\n }\n }\n\n #scheduleNotify(atom: Atom<unknown>): void {\n this.#pending.add(atom);\n this.#schedulePendingFlush();\n }\n\n #registerRdeps(atom: Atom<unknown>, deps: Record<string, Atom<unknown>>): void {\n for (const dep of Object.values(deps)) {\n let set = this.#rdeps.get(dep);\n if (set == null) {\n set = new Set();\n this.#rdeps.set(dep, set);\n }\n set.add(atom);\n }\n }\n\n #makeCtx(\n atom: Atom<unknown>,\n deps: Record<string, Atom<unknown>>,\n ): AtomContext<Record<string, Atom<unknown>>> {\n this.#controllers.get(atom)?.abort();\n const controller = new AbortController();\n this.#controllers.set(atom, controller);\n\n return {\n signal: controller.signal,\n get: async (key: string) => {\n const dep = deps[key];\n if (dep == null) {\n throw new Error(`Unknown dependency key: \"${String(key)}\"`);\n }\n return this.resolve(dep);\n },\n };\n }\n\n subscribe<V>(atom: Atom<V>, listener: () => void): () => void {\n const entry = this.#getOrCreate(atom);\n entry.listeners.add(listener);\n\n this.#autoRegisterFamily(atom);\n\n if (entry.state.status === \"pending\" && entry.promise == null) {\n void this.resolve(atom);\n }\n\n entry.mountCount++;\n if (entry.mountCount === 1) {\n const config: InternalAtomConfig<V> = atom[CONFIG];\n if (config.onMount != null) {\n const setValue = (value: V): void => {\n entry.state = { status: \"fresh\", value, error: undefined };\n entry.version++;\n this.#scheduleNotify(atom);\n };\n const cleanup = config.onMount(setValue as (value: unknown) => void);\n if (typeof cleanup === \"function\") {\n entry.unmount = cleanup;\n }\n }\n }\n\n return () => {\n entry.listeners.delete(listener);\n entry.mountCount--;\n if (entry.mountCount === 0 && entry.unmount != null) {\n entry.unmount();\n entry.unmount = null;\n }\n };\n }\n\n #autoRegisterFamily(atom: Atom<unknown>): void {\n const link = getFamilyLink(atom);\n if (link == null) {\n return;\n }\n if (this.#registeredFamilies.has(link)) {\n return;\n }\n this.#registeredFamilies.add(link);\n const unsub = link.registerStore((target: Atom<unknown>) => {\n this.invalidate(target);\n });\n this.#familyUnsubs.add(unsub);\n }\n\n getSnapshot<V>(atom: Atom<V>): AtomState<V> {\n return this.#getOrCreate(atom).state;\n }\n\n getServerSnapshot<V>(atom: Atom<V>): AtomState<V> {\n const entry = this.#atoms.get(atom) as AtomEntry<V> | undefined;\n if (entry != null) {\n return entry.state;\n }\n return PENDING_STATE as AtomState<V>;\n }\n\n async set<V, A extends readonly unknown[]>(atom: WritableAtom<V, A>, ...args: A): Promise<void> {\n const config: InternalAtomConfig<V> = atom[CONFIG];\n if (config.set == null) {\n throw new Error(\n `Atom${atom.debugLabel != null ? ` \"${atom.debugLabel}\"` : \"\"} is not writable`,\n );\n }\n\n const deps = config.dependencies ?? {};\n const baseCtx = this.#makeCtx(atom, deps);\n const entry = this.#getOrCreate(atom);\n\n // Ref: assignments inside setOptimisticValue are not tracked on a plain `let` for catch narrowing.\n const optimisticSnapshot: {\n current: { state: AtomState<V>; version: number } | null;\n } = { current: null };\n\n const ctx: WritableAtomContext<Record<string, Atom<unknown>>, V> = {\n ...baseCtx,\n setOptimisticValue: (valueOrMutate: V | ((prev: V | undefined) => V)): void => {\n if (optimisticSnapshot.current == null) {\n optimisticSnapshot.current = { state: entry.state, version: entry.version };\n }\n const next =\n typeof valueOrMutate === \"function\"\n ? (valueOrMutate as (prev: V | undefined) => V)(extractPreviousValue(entry.state))\n : valueOrMutate;\n entry.state = { status: \"fresh\", value: next, error: undefined };\n entry.version++;\n this.#scheduleNotify(atom);\n this.#markReverseDependentsStale(atom);\n },\n };\n\n try {\n await config.set(ctx, ...args);\n } catch (e: unknown) {\n const snap = optimisticSnapshot.current;\n if (snap != null) {\n entry.state = snap.state;\n entry.version = snap.version;\n this.#scheduleNotify(atom);\n }\n throw e;\n }\n\n this.invalidate(atom);\n }\n\n write<V>(atom: Atom<V>, value: V): void;\n write<V>(atom: Atom<V>, mutate: (prev: V | undefined) => V): void;\n write<V>(atom: Atom<V>, valueOrMutate: V | ((prev: V | undefined) => V)): void {\n const entry = this.#getOrCreate(atom);\n this.#controllers.get(atom)?.abort();\n entry.promise = null;\n const next =\n typeof valueOrMutate === \"function\"\n ? (valueOrMutate as (prev: V | undefined) => V)(extractPreviousValue(entry.state))\n : valueOrMutate;\n entry.state = { status: \"fresh\", value: next, error: undefined };\n entry.version++;\n this.#scheduleNotify(atom);\n this.#markReverseDependentsStale(atom);\n }\n\n getClient(): StoreClient {\n if (this.#client != null) {\n return this.#client;\n }\n\n this.#client = {\n get: <V>(atom: Atom<V>): Promise<V> => this.resolve(atom),\n set: <V, A extends readonly unknown[]>(atom: WritableAtom<V, A>, ...args: A): Promise<void> =>\n this.set(atom, ...args),\n write: <V>(atom: Atom<V>, valueOrMutate: V | ((prev: V | undefined) => V)): void =>\n this.write(atom, valueOrMutate as V),\n invalidate: (atom: Atom<unknown>): void => this.invalidate(atom),\n invalidateMany: (atoms: ReadonlyArray<Atom<unknown>>): void => this.invalidateMany(atoms),\n subscribe: <V>(atom: Atom<V>, listener: (state: AtomState<V>) => void): (() => void) =>\n this.subscribe(atom, () => {\n listener(this.getSnapshot(atom));\n }),\n };\n return this.#client;\n }\n}\n\nexport function createStore(): Store {\n return new Store();\n}\n\nfunction isAbortError(e: unknown): boolean {\n return e instanceof DOMException && e.name === \"AbortError\";\n}\n\nfunction extractPreviousValue<V>(state: AtomState<V>): V | undefined {\n if (state.status === \"stale\" || state.status === \"fresh\") {\n return state.value;\n }\n if (state.status === \"error\") {\n return state.value;\n }\n return undefined;\n}\n"],"mappings":"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"}
|