@kdeveloper/kvark 0.7.0 → 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 +28 -10
- 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/package.json +11 -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).
|
|
@@ -314,10 +324,10 @@ const store = createStore();
|
|
|
314
324
|
await store.mutate(addItem, "new row");
|
|
315
325
|
```
|
|
316
326
|
|
|
317
|
-
**React / Vue**
|
|
327
|
+
**React / Preact / Vue**
|
|
318
328
|
|
|
319
329
|
```tsx
|
|
320
|
-
import { useMutation } from "@kdeveloper/kvark/react";
|
|
330
|
+
import { useMutation } from "@kdeveloper/kvark/react"; // or "@kdeveloper/kvark/preact"
|
|
321
331
|
|
|
322
332
|
const runAddItem = useMutation(addItem);
|
|
323
333
|
|
|
@@ -332,7 +342,7 @@ const runAddItem = useMutation(addItem);
|
|
|
332
342
|
</script>
|
|
333
343
|
```
|
|
334
344
|
|
|
335
|
-
`useMutation` returns a stable function (React: `useCallback` over `store.mutate`) with the same argument tuple as your mutation.
|
|
345
|
+
`useMutation` returns a stable function (React/Preact: `useCallback` over `store.mutate`) with the same argument tuple as your mutation.
|
|
336
346
|
|
|
337
347
|
#### Writable atoms vs `onMount`
|
|
338
348
|
|
|
@@ -531,6 +541,12 @@ const readBalance = useAtomContext(async (client) => {
|
|
|
531
541
|
const balance = await readBalance();
|
|
532
542
|
```
|
|
533
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
|
+
|
|
534
550
|
## Vue 3 (`@kdeveloper/kvark/vue`)
|
|
535
551
|
|
|
536
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"`.
|
|
@@ -682,7 +698,7 @@ interface StoreClient {
|
|
|
682
698
|
|
|
683
699
|
## Provider and Store Setup
|
|
684
700
|
|
|
685
|
-
**React**
|
|
701
|
+
**React / Preact**
|
|
686
702
|
|
|
687
703
|
```tsx
|
|
688
704
|
// store.ts
|
|
@@ -690,7 +706,7 @@ import { createStore } from "@kdeveloper/kvark";
|
|
|
690
706
|
export const store = createStore();
|
|
691
707
|
|
|
692
708
|
// App.tsx
|
|
693
|
-
import { Provider } from "@kdeveloper/kvark/react";
|
|
709
|
+
import { Provider } from "@kdeveloper/kvark/react"; // or "@kdeveloper/kvark/preact"
|
|
694
710
|
import { store } from "./store";
|
|
695
711
|
|
|
696
712
|
export function App() {
|
|
@@ -736,11 +752,12 @@ type Writable = IsWritable<typeof countAtom>; // → true | false
|
|
|
736
752
|
| Import | Contents |
|
|
737
753
|
| -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
738
754
|
| `@kdeveloper/kvark` | `atom`, `mutation`, `createStore`, all types (including `Mutation`, `MutationContext`) |
|
|
739
|
-
| `@kdeveloper/kvark/react`
|
|
740
|
-
| `@kdeveloper/kvark/
|
|
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` |
|
|
741
758
|
| `@kdeveloper/kvark/family` | `atomFamily`, `stableFamilyKey`, re-exports `atom`, `mutation`, `createStore`; types include `AtomFamily`, `Mutation`, `MutationContext`, and core atom types |
|
|
742
759
|
|
|
743
|
-
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`.
|
|
744
761
|
|
|
745
762
|
The published package is **ESM-only** (`import`); there is no CommonJS `require` entry.
|
|
746
763
|
|
|
@@ -763,6 +780,7 @@ Useful variants: `pnpm test:watch`, `pnpm lint:fix`, `pnpm fmt:check`, `pnpm lin
|
|
|
763
780
|
- **Node.js** ≥ 20
|
|
764
781
|
- **TypeScript** ≥ 6 (strict mode recommended)
|
|
765
782
|
- **React** ≥ 18 (optional peer, for `@kdeveloper/kvark/react`)
|
|
783
|
+
- **Preact** ≥ 10 (optional peer, for `@kdeveloper/kvark/preact`)
|
|
766
784
|
- **Vue** ≥ 3.4 (optional peer, for `@kdeveloper/kvark/vue`)
|
|
767
785
|
|
|
768
786
|
## License
|
|
@@ -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/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
|
}
|