@kdeveloper/kvark 0.5.3 → 0.6.1

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 CHANGED
@@ -1,12 +1,12 @@
1
1
  # @kdeveloper/kvark
2
2
 
3
- Atomic state management for React with **explicit dependency graphs**, stale-while-revalidate, and first-class external invalidation.
3
+ Atomic state management for **React** and **Vue 3** with **explicit dependency graphs**, stale-while-revalidate, and first-class external invalidation.
4
4
 
5
- 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 any React hooks.
5
+ 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.
6
6
 
7
- ```
8
- npm install @kdeveloper/kvark
9
- # peer dependency: react >=18
7
+ ```bash
8
+ pnpm add @kdeveloper/kvark
9
+ # optional peers: react >=18 and/or vue >=3.4 (install the one you use)
10
10
  ```
11
11
 
12
12
  ## Why Kvark?
@@ -26,7 +26,7 @@ npm install @kdeveloper/kvark
26
26
 
27
27
  ```bash
28
28
  pnpm add @kdeveloper/kvark
29
- # react >=18 is a peer dependency
29
+ # optional peers: react >=18 and/or vue >=3.4
30
30
  ```
31
31
 
32
32
  ## Quick Start
@@ -73,6 +73,69 @@ function UserCard() {
73
73
  }
74
74
  ```
75
75
 
76
+ ### Vue 3
77
+
78
+ The same atoms and store work with `@kdeveloper/kvark/vue`. Composables mirror the React hooks; `useAtomValue` returns a [`shallowRef`](https://vuejs.org/api/reactivity-advanced.html#shallowref) to the value — use `.value` in `<script setup>` (templates unwrap refs automatically).
79
+
80
+ Composables must run **inside** a `Provider` subtree. Put `useAtomValue` / `useAtom` in a child component (or a nested route), not in the same component that renders `Provider` without passing the store through a wrapper.
81
+
82
+ `atoms.ts` — lift the atom definitions from the Quick Start into a shared module:
83
+
84
+ ```ts
85
+ import { atom } from "@kdeveloper/kvark";
86
+
87
+ export const userIdAtom = atom({
88
+ debugLabel: "userId",
89
+ get: async () => 1,
90
+ set: async () => {},
91
+ });
92
+
93
+ export const userAtom = atom({
94
+ debugLabel: "user",
95
+ dependencies: { userId: userIdAtom },
96
+ get: async (ctx) => {
97
+ const id = await ctx.get("userId");
98
+ const res = await fetch(`/api/users/${id}`, { signal: ctx.signal });
99
+ return res.json();
100
+ },
101
+ });
102
+ ```
103
+
104
+ `UserCard.vue`
105
+
106
+ ```vue
107
+ <script setup lang="ts">
108
+ import { useAtomValue } from "@kdeveloper/kvark/vue";
109
+ import { userAtom } from "./atoms";
110
+
111
+ const user = useAtomValue(userAtom);
112
+ </script>
113
+
114
+ <template>
115
+ <div>{{ user.name }}</div>
116
+ </template>
117
+ ```
118
+
119
+ `App.vue`
120
+
121
+ ```vue
122
+ <script setup lang="ts">
123
+ import { createStore } from "@kdeveloper/kvark";
124
+ import { Provider } from "@kdeveloper/kvark/vue";
125
+ import UserCard from "./UserCard.vue";
126
+
127
+ const store = createStore();
128
+ </script>
129
+
130
+ <template>
131
+ <Provider :store="store">
132
+ <UserCard />
133
+ </Provider>
134
+ </template>
135
+ ```
136
+
137
+ Unlike React’s `Suspense` around `useAtomValue`, Vue’s `<Suspense>` only activates for **async** child components. To show a fallback until the first `get` completes, use **`async setup`**, `useStore()`, `useAtomValue(atom)`, then **`await store.resolve(atom)`**, and wrap that child in `<Suspense>` — see [Suspense (Vue 3)](#suspense-vue-3).
138
+
76
139
  ## Core Concepts
77
140
 
78
141
  ### Atoms
@@ -174,7 +237,7 @@ Both can update an atom's cached value, but they serve different purposes:
174
237
 
175
238
  ### `onMount`
176
239
 
177
- Optional lifecycle hook that runs when the atom **first gains a subscriber** in a store (for example when a React component using `useAtomValue` mounts). It receives a synchronous `set(value)` that marks the atom `fresh` and notifies listeners — useful for timers, subscriptions, or imperative updates that should not go through `get`.
240
+ Optional lifecycle hook that runs when the atom **first gains a subscriber** in a store (for example when a component using `useAtomValue` mounts). It receives a synchronous `set(value)` that marks the atom `fresh` and notifies listeners — useful for timers, subscriptions, or imperative updates that should not go through `get`.
178
241
 
179
242
  You may return a cleanup function; it runs when the **last** subscriber unsubscribes (for example when the last mounted consumer unmounts). If several components subscribe to the same atom, `onMount` runs once and the cleanup runs once after all of them unsubscribe.
180
243
 
@@ -300,10 +363,14 @@ A built-in helper that serialises plain objects and arrays into a deterministic
300
363
  - Not supported: class instances (other than plain `Object`/`Array`), `Map`, `Set`, `Symbol`, functions, circular references.
301
364
  - Memoises by object reference via a `WeakMap` — repeated calls with the **same object reference** are O(1). Treat param objects as **immutable** after the first call; mutating an object after it has been memoised will silently return the stale key.
302
365
 
303
- ## React Hooks
366
+ ## React (`@kdeveloper/kvark/react`)
304
367
 
305
368
  All hooks must be used inside a `<Provider>`.
306
369
 
370
+ ### `useStore`
371
+
372
+ Returns the `Store` instance from context — for advanced cases (e.g. calling `store.resolve` in async setup patterns) or when you need the store outside atom helpers.
373
+
307
374
  ### `useAtomValue`
308
375
 
309
376
  Reads an atom value and subscribes to updates. Suspends on first load.
@@ -346,9 +413,77 @@ const readBalance = useAtomContext(async (client) => {
346
413
  const balance = await readBalance();
347
414
  ```
348
415
 
416
+ ## Vue 3 (`@kdeveloper/kvark/vue`)
417
+
418
+ Same composable names and behaviour as React: `Provider`, `useStore`, `useAtomValue`, `useSetAtom`, `useAtom`, `useAtomContext`. Wrap your app (or subtree) with `Provider` and pass `:store="store"`.
419
+
420
+ `useAtomValue` / `useAtom` expose values as **shallow refs** — in script code use `.value`; in templates Vue unwraps refs for you.
421
+
422
+ ### Suspense (Vue 3)
423
+
424
+ Vue’s `<Suspense>` boundary applies to **async** components (e.g. **`async setup`** or [top-level `await` in `<script setup>`](https://vuejs.org/guide/built-ins/suspense.html#async-setup)), not to composables alone. To get a loading fallback until the first `get` finishes, the child that uses `useAtomValue` should **`await store.resolve(atom)`** after subscribing, and be wrapped in `<Suspense>`.
425
+
426
+ `atoms.ts`
427
+
428
+ ```ts
429
+ import { atom } from "@kdeveloper/kvark";
430
+
431
+ export const slowAtom = atom({
432
+ get: async () => {
433
+ await new Promise((r) => setTimeout(r, 50));
434
+ return "ready";
435
+ },
436
+ });
437
+ ```
438
+
439
+ `AsyncRead.vue` (under `Provider`; top-level `await` makes this component async for Suspense)
440
+
441
+ ```vue
442
+ <script setup lang="ts">
443
+ import { useAtomValue, useStore } from "@kdeveloper/kvark/vue";
444
+ import { slowAtom } from "./atoms";
445
+
446
+ const store = useStore();
447
+ const value = useAtomValue(slowAtom);
448
+ await store.resolve(slowAtom);
449
+ </script>
450
+
451
+ <template>
452
+ <div>{{ value }}</div>
453
+ </template>
454
+ ```
455
+
456
+ `App.vue`
457
+
458
+ ```vue
459
+ <script setup lang="ts">
460
+ import { Suspense } from "vue";
461
+ import { createStore } from "@kdeveloper/kvark";
462
+ import { Provider } from "@kdeveloper/kvark/vue";
463
+ import AsyncRead from "./AsyncRead.vue";
464
+
465
+ const store = createStore();
466
+ </script>
467
+
468
+ <template>
469
+ <Provider :store="store">
470
+ <Suspense>
471
+ <template #default>
472
+ <AsyncRead />
473
+ </template>
474
+ <template #fallback>
475
+ <div>Loading…</div>
476
+ </template>
477
+ </Suspense>
478
+ </Provider>
479
+ </template>
480
+ ```
481
+
482
+ Alternatively, use **`defineComponent({ async setup() { ... } })`** and `await store.resolve(slowAtom)` before returning the render function — the same pattern as in `test/vue/hooks.test.ts`.
483
+
349
484
  ## External Invalidation
350
485
 
351
- `StoreClient` exposes the store's full capabilities outside of React — useful for WebSocket handlers, SSE streams, polling timers, and Service Workers.
486
+ `StoreClient` exposes the store's full capabilities outside your component tree — useful for WebSocket handlers, SSE streams, polling timers, and Service Workers.
352
487
 
353
488
  ```ts
354
489
  import { createStore } from "@kdeveloper/kvark";
@@ -377,7 +512,7 @@ sse.addEventListener("prices.updated", () => {
377
512
  // Polling
378
513
  setInterval(() => client.invalidate(statusAtom), 30_000);
379
514
 
380
- // Subscribe to state changes outside React
515
+ // Subscribe to state changes outside components
381
516
  const unsub = client.subscribe(userAtom, (state) => {
382
517
  if (state.status === "fresh") {
383
518
  analytics.identify(state.value.id);
@@ -424,6 +559,8 @@ interface StoreClient {
424
559
 
425
560
  ## Provider and Store Setup
426
561
 
562
+ **React**
563
+
427
564
  ```tsx
428
565
  // store.ts
429
566
  import { createStore } from "@kdeveloper/kvark";
@@ -442,6 +579,23 @@ export function App() {
442
579
  }
443
580
  ```
444
581
 
582
+ **Vue 3**
583
+
584
+ ```vue
585
+ <script setup lang="ts">
586
+ import { createStore } from "@kdeveloper/kvark";
587
+ import { Provider } from "@kdeveloper/kvark/vue";
588
+
589
+ const store = createStore();
590
+ </script>
591
+
592
+ <template>
593
+ <Provider :store="store">
594
+ <RouterView />
595
+ </Provider>
596
+ </template>
597
+ ```
598
+
445
599
  ## Utility Types
446
600
 
447
601
  ```ts
@@ -454,19 +608,21 @@ type Writable = IsWritable<typeof countAtom>; // → true | false
454
608
 
455
609
  ## Package Structure
456
610
 
457
- | Import | Contents |
458
- | -------------------------- | --------------------------------------------------------------------- |
459
- | `@kdeveloper/kvark` | `atom`, `createStore`, all types |
460
- | `@kdeveloper/kvark/react` | `Provider`, `useAtomValue`, `useSetAtom`, `useAtom`, `useAtomContext` |
461
- | `@kdeveloper/kvark/family` | `atomFamily` |
611
+ | Import | Contents |
612
+ | -------------------------- | ------------------------------------------------------------------------------------------- |
613
+ | `@kdeveloper/kvark` | `atom`, `createStore`, all types |
614
+ | `@kdeveloper/kvark/react` | `Provider`, `useStore`, `useAtomValue`, `useSetAtom`, `useAtom`, `useAtomContext` |
615
+ | `@kdeveloper/kvark/vue` | `Provider`, `useStore`, `useAtomValue`, `useSetAtom`, `useAtom`, `useAtomContext` |
616
+ | `@kdeveloper/kvark/family` | `atomFamily`, `stableFamilyKey`, re-exports `atom` / `createStore` and core types |
462
617
 
463
- The core (`@kdeveloper/kvark`) has **zero runtime dependencies**. React is a peer dependency only needed when using the `/react` subpath.
618
+ The core (`@kdeveloper/kvark`) has **zero runtime dependencies**. **React** and **Vue** are optional peer dependencies install the framework you use and import from `/react` or `/vue`.
464
619
 
465
620
  ## Requirements
466
621
 
467
622
  - **Node.js** ≥ 20
468
623
  - **TypeScript** ≥ 6 (strict mode recommended)
469
- - **React** ≥ 18 (for `@kdeveloper/kvark/react`)
624
+ - **React** ≥ 18 (optional peer, for `@kdeveloper/kvark/react`)
625
+ - **Vue** ≥ 3.4 (optional peer, for `@kdeveloper/kvark/vue`)
470
626
 
471
627
  ## License
472
628
 
@@ -0,0 +1,42 @@
1
+ import { f as WritableAtom, i as Atom, n as StoreClient, t as Store } from "../store-DQL8VJhU.mjs";
2
+ import * as _$vue from "vue";
3
+ import { PropType, ShallowRef } from "vue";
4
+
5
+ //#region src/vue/provider.d.ts
6
+ declare const Provider: _$vue.DefineComponent<_$vue.ExtractPropTypes<{
7
+ store: {
8
+ type: PropType<Store>;
9
+ required: true;
10
+ };
11
+ }>, () => _$vue.VNode<_$vue.RendererNode, _$vue.RendererElement, {
12
+ [key: string]: any;
13
+ }>[] | undefined, {}, {}, {}, _$vue.ComponentOptionsMixin, _$vue.ComponentOptionsMixin, {}, string, _$vue.PublicProps, Readonly<_$vue.ExtractPropTypes<{
14
+ store: {
15
+ type: PropType<Store>;
16
+ required: true;
17
+ };
18
+ }>> & Readonly<{}>, {}, {}, {}, {}, string, _$vue.ComponentProvideOptions, true, {}, any>;
19
+ declare function useStore(): Store;
20
+ //#endregion
21
+ //#region src/vue/use-atom-value.d.ts
22
+ type ObservedValue<V> = {
23
+ value: V;
24
+ isStale: boolean;
25
+ error: unknown;
26
+ };
27
+ declare function useAtomValue<V>(atom: Atom<V>): Readonly<ShallowRef<V>>;
28
+ declare function useAtomValue<V>(atom: Atom<V>, opts: {
29
+ observe: true;
30
+ }): Readonly<ShallowRef<ObservedValue<V>>>;
31
+ //#endregion
32
+ //#region src/vue/use-set-atom.d.ts
33
+ declare function useSetAtom<V, A extends readonly unknown[]>(atom: WritableAtom<V, A>): (...args: A) => Promise<void>;
34
+ //#endregion
35
+ //#region src/vue/use-atom.d.ts
36
+ declare function useAtom<V, A extends readonly unknown[]>(atom: WritableAtom<V, A>): readonly [Readonly<ShallowRef<V>>, (...args: A) => Promise<void>];
37
+ //#endregion
38
+ //#region src/vue/use-atom-context.d.ts
39
+ declare function useAtomContext<R>(callback: (ctx: StoreClient) => Promise<R>): () => Promise<R>;
40
+ //#endregion
41
+ export { Provider, useAtom, useAtomContext, useAtomValue, useSetAtom, useStore };
42
+ //# sourceMappingURL=index.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.mts","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":";;;;;cAWa,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;;;KClBvB,aAAA;EACH,KAAA,EAAO,CAAA;EACP,OAAA;EACA,KAAA;AAAA;AAAA,iBAGc,YAAA,GAAA,CAAgB,IAAA,EAAM,IAAA,CAAK,CAAA,IAAK,QAAA,CAAS,UAAA,CAAW,CAAA;AAAA,iBACpD,YAAA,GAAA,CACd,IAAA,EAAM,IAAA,CAAK,CAAA,GACX,IAAA;EAAQ,OAAA;AAAA,IACP,QAAA,CAAS,UAAA,CAAW,aAAA,CAAc,CAAA;;;iBCXrB,UAAA,iCAAA,CACd,IAAA,EAAM,YAAA,CAAa,CAAA,EAAG,CAAA,QACjB,IAAA,EAAM,CAAA,KAAM,OAAA;;;iBCAH,OAAA,iCAAA,CACd,IAAA,EAAM,YAAA,CAAa,CAAA,EAAG,CAAA,cACX,QAAA,CAAS,UAAA,CAAW,CAAA,QAAS,IAAA,EAAM,CAAA,KAAM,OAAA;;;iBCJtC,cAAA,GAAA,CAAkB,QAAA,GAAW,GAAA,EAAK,WAAA,KAAgB,OAAA,CAAQ,CAAA,UAAW,OAAA,CAAQ,CAAA"}
@@ -0,0 +1,86 @@
1
+ import { defineComponent, inject, provide, readonly, shallowRef, watchEffect } from "vue";
2
+ //#region src/vue/provider.ts
3
+ const StoreKey = Symbol("kvark-store");
4
+ const Provider = defineComponent({
5
+ name: "KvarkProvider",
6
+ props: { store: {
7
+ type: Object,
8
+ required: true
9
+ } },
10
+ setup(props, { slots }) {
11
+ provide(StoreKey, props.store);
12
+ return () => slots["default"]?.();
13
+ }
14
+ });
15
+ function useStore() {
16
+ const store = inject(StoreKey);
17
+ if (store == null) throw new Error("useStore must be used within a <Provider>");
18
+ return store;
19
+ }
20
+ //#endregion
21
+ //#region src/vue/use-atom-value.ts
22
+ function useAtomValue(atom, opts) {
23
+ const store = useStore();
24
+ function derive(snapshot) {
25
+ if (snapshot.status === "pending") {
26
+ store.resolve(atom);
27
+ if (opts?.observe === true) return {
28
+ value: void 0,
29
+ isStale: false,
30
+ error: void 0
31
+ };
32
+ return;
33
+ }
34
+ if (snapshot.status === "stale") {
35
+ store.resolve(atom);
36
+ if (opts?.observe === true) return {
37
+ value: snapshot.value,
38
+ isStale: true,
39
+ error: void 0
40
+ };
41
+ return snapshot.value;
42
+ }
43
+ if (snapshot.status === "error") {
44
+ if (opts?.observe === true && snapshot.value !== void 0) return {
45
+ value: snapshot.value,
46
+ isStale: false,
47
+ error: snapshot.error
48
+ };
49
+ throw snapshot.error;
50
+ }
51
+ if (opts?.observe === true) return {
52
+ value: snapshot.value,
53
+ isStale: false,
54
+ error: void 0
55
+ };
56
+ return snapshot.value;
57
+ }
58
+ const result = shallowRef(derive(store.getSnapshot(atom)));
59
+ watchEffect((onCleanup) => {
60
+ onCleanup(store.subscribe(atom, () => {
61
+ result.value = derive(store.getSnapshot(atom));
62
+ }));
63
+ });
64
+ return readonly(result);
65
+ }
66
+ //#endregion
67
+ //#region src/vue/use-set-atom.ts
68
+ function useSetAtom(atom) {
69
+ const store = useStore();
70
+ return (...args) => store.set(atom, ...args);
71
+ }
72
+ //#endregion
73
+ //#region src/vue/use-atom.ts
74
+ function useAtom(atom) {
75
+ return [useAtomValue(atom), useSetAtom(atom)];
76
+ }
77
+ //#endregion
78
+ //#region src/vue/use-atom-context.ts
79
+ function useAtomContext(callback) {
80
+ const store = useStore();
81
+ return () => callback(store.getClient());
82
+ }
83
+ //#endregion
84
+ export { Provider, useAtom, useAtomContext, useAtomValue, useSetAtom, useStore };
85
+
86
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","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 {\n type InjectionKey,\n type PropType,\n defineComponent,\n inject,\n provide,\n} from \"vue\";\nimport { 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\ntype ObservedValue<V> = {\n value: V;\n isStale: boolean;\n error: unknown;\n};\n\nexport function useAtomValue<V>(atom: Atom<V>): Readonly<ShallowRef<V>>;\nexport function useAtomValue<V>(\n atom: Atom<V>,\n opts: { observe: true },\n): Readonly<ShallowRef<ObservedValue<V>>>;\nexport function useAtomValue<V>(\n atom: Atom<V>,\n opts?: { observe: true },\n): Readonly<ShallowRef<V | ObservedValue<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 return readonly(result) as Readonly<ShallowRef<V | ObservedValue<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 { useAtomValue } from \"@/vue/use-atom-value.js\";\nimport { useSetAtom } from \"@/vue/use-set-atom.js\";\n\nexport function useAtom<V, A extends readonly unknown[]>(\n atom: WritableAtom<V, A>,\n): readonly [Readonly<ShallowRef<V>>, (...args: A) => Promise<void>] {\n const value = useAtomValue(atom);\n const setter = useSetAtom(atom);\n return [value, setter] as const;\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":";;AASA,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;;;;ACZT,SAAgB,aACd,MACA,MAC4C;CAC5C,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;AAEF,QAAO,SAAS,OAAO;;;;AC1DzB,SAAgB,WACd,MAC+B;CAC/B,MAAM,QAAQ,UAAU;AACxB,SAAQ,GAAG,SAA2B,MAAM,IAAI,MAAM,GAAG,KAAK;;;;ACFhE,SAAgB,QACd,MACmE;AAGnE,QAAO,CAFO,aAAa,KAAK,EACjB,WAAW,KAAK,CACT;;;;ACPxB,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.5.3",
3
+ "version": "0.6.1",
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.mts",
20
20
  "import": "./dist/react/index.mjs"
21
21
  },
22
+ "./vue": {
23
+ "types": "./dist/vue/index.d.mts",
24
+ "import": "./dist/vue/index.mjs"
25
+ },
22
26
  "./family": {
23
27
  "types": "./dist/family.d.mts",
24
28
  "import": "./dist/family.mjs"
@@ -29,6 +33,7 @@
29
33
  "@testing-library/react": "^16.3.2",
30
34
  "@types/react": "^19.2.14",
31
35
  "@types/react-dom": "^19.2.3",
36
+ "@vue/test-utils": "^2.4.6",
32
37
  "jsdom": "^29.0.1",
33
38
  "oxfmt": "^0.42.0",
34
39
  "oxlint": "^1.57.0",
@@ -36,10 +41,20 @@
36
41
  "react-dom": "^19.2.4",
37
42
  "tsdown": "^0.21.6",
38
43
  "typescript": "^6.0.2",
39
- "vitest": "^4.1.2"
44
+ "vitest": "^4.1.2",
45
+ "vue": "^3.5.31"
40
46
  },
41
47
  "peerDependencies": {
42
- "react": ">=18"
48
+ "react": ">=18",
49
+ "vue": ">=3.4"
50
+ },
51
+ "peerDependenciesMeta": {
52
+ "react": {
53
+ "optional": true
54
+ },
55
+ "vue": {
56
+ "optional": true
57
+ }
43
58
  },
44
59
  "engines": {
45
60
  "node": ">=20"