@lunora/vue 1.0.0-alpha.106 → 1.0.0-alpha.107

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
@@ -81,7 +81,7 @@ const { mutate, pending } = useMutation(api.messages.send);
81
81
  | `useQuery` | `useQuery` | Live query `ShallowRef` — re-subscribes when reactive args change. |
82
82
  | `useMutation` | `useMutation` | Optimistic mutation handle (`data`, `error`, `pending`, `mutate`, `reset`). |
83
83
  | `useSubscription` | `useSubscription` | Raw subscription `ShallowRef` — unbounded live stream. |
84
- | `usePaginatedQuery` | `usePaginatedQuery` | Cursor-paginated query with `loadMore`, `status`, and `results`. |
84
+ | `usePaginatedQuery` | `usePaginatedQuery` | Cursor-paginated query with `loadMore`, `status`, `results`, and `error`. |
85
85
  | `useInfiniteQuery` | `useInfiniteQuery` | Infinite-scroll variant of `usePaginatedQuery`. |
86
86
  | `useAuth` | `useAuth` | Reactive auth: readonly `token`/`user` refs plus `setToken`. |
87
87
  | `usePresence` | `usePresence` | Collaborative-awareness — heartbeat + live present-members `ShallowRef`. |
package/dist/index.d.mts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { Component, Ref, InjectionKey, App, MaybeRefOrGetter, ComputedRef, DeepReadonly, ShallowRef } from 'vue';
2
- import { Preloaded, LunoraClient, SubscriptionErrorCallback, FunctionReference, ArgsOf, ActionCallOptions, ReturnOf, User, ConnectionStatus, MutationCallOptions, MutatorHandle } from '@lunora/client';
2
+ import { Preloaded, SubscriptionErrorCallback, LunoraClient, FunctionReference, ArgsOf, ActionCallOptions, ReturnOf, User, ConnectionStatus, MutationCallOptions, MutatorHandle, SubscriptionError } from '@lunora/client';
3
3
  export type { ArgsOf, FunctionReference, LunoraClient, MutationCallOptions, MutatorHandle, MutatorTransaction, OptimisticLocalStore, OptimisticUpdate, Preloaded, ReturnOf, SubscriptionError, SubscriptionErrorCallback, Unsubscribe, User } from '@lunora/client';
4
4
  import { PaginationStatus } from '@lunora/client/pagination';
5
5
  export type { PaginationResult, PaginationStatus } from '@lunora/client/pagination';
@@ -33,6 +33,10 @@ declare const AuthLoading: Component;
33
33
  * The subscription tears down with the surrounding effect scope (component
34
34
  * unmount or `effectScope().stop()`), inherited from `subscribeToQuery`.
35
35
  *
36
+ * Pass `onError` to surface a subscription-scoped error the server pushes (a
37
+ * session expiry, an RLS denial). Without it such an error is dropped and the
38
+ * ref keeps rendering the SSR snapshot as if it were live.
39
+ *
36
40
  * The ref is `Ref<T>`, not `Ref<T | undefined>`: `subscribeToQuery`'s ref widens
37
41
  * to `undefined` because it also serves the unseeded `useQuery` case, but this
38
42
  * entry point always passes `seed: preloaded.value`, so the "seeded
@@ -40,7 +44,9 @@ declare const AuthLoading: Component;
40
44
  * other adapter's `hydratePreloaded` returns `T`; narrowing here stops Vue
41
45
  * consumers guarding a state that cannot occur.
42
46
  */
43
- declare const hydratePreloaded: <T>(preloaded: Preloaded<T>) => Ref<T>;
47
+ declare const hydratePreloaded: <T>(preloaded: Preloaded<T>, options?: {
48
+ onError?: SubscriptionErrorCallback;
49
+ }) => Ref<T>;
44
50
  /**
45
51
  * Injection key carrying the {@link LunoraClient} down the component tree.
46
52
  * Exported so advanced consumers can inject it by hand; most apps use
@@ -681,9 +687,18 @@ type PageItemOf<F extends FunctionReference> = ReturnOf<F> extends {
681
687
  interface UsePaginatedQueryOptions {
682
688
  /** Page size for the first page (and the default for `loadMore`). */
683
689
  initialNumItems: number;
690
+ /** Called when a page subscription reports an error (also surfaced on the `error` ref). */
691
+ onError?: SubscriptionErrorCallback;
684
692
  shardKey?: string;
685
693
  }
686
694
  interface UsePaginatedQueryResult<T> {
695
+ /**
696
+ * The last page subscription error, or `undefined`. A tail page that fails
697
+ * before its first frame is dropped so `status` returns to `"CanLoadMore"`
698
+ * and `loadMore` can retry it; cleared by the next successful frame,
699
+ * `loadMore`, or an args change.
700
+ */
701
+ error: Ref<SubscriptionError | undefined>;
687
702
  /** `true` while the first page or a `loadMore` page is in flight. */
688
703
  isLoading: Ref<boolean>;
689
704
  /** Request the next page. A no-op unless `status === "CanLoadMore"`. */
@@ -715,9 +730,13 @@ declare const usePaginatedQuery: <F extends FunctionReference>(function_: F, arg
715
730
  interface UseInfiniteQueryOptions {
716
731
  /** Page size for the first page (and the default for `fetchNextPage`). */
717
732
  initialNumItems: number;
733
+ /** Called when a page subscription reports an error (also surfaced on the `error` ref). */
734
+ onError?: SubscriptionErrorCallback;
718
735
  shardKey?: string;
719
736
  }
720
737
  interface UseInfiniteQueryResult<T> {
738
+ /** The last page subscription error, or `undefined` — see `UsePaginatedQueryResult.error`. */
739
+ error: Ref<SubscriptionError | undefined>;
721
740
  /** Request the next page. A no-op unless `status === "CanLoadMore"`. */
722
741
  fetchNextPage: (numberItems?: number) => void;
723
742
  /** `true` when the loaded tail reports it can load another page. */
@@ -801,7 +820,9 @@ declare const usePresence: <H extends HeartbeatReference, L extends ListPresentR
801
820
  * replays the last value synchronously, so multiple consumers of the same query
802
821
  * ride one server-side registration. `seed` sets the ref's value synchronously
803
822
  * before the subscription attaches, so the first read shows the SSR value with
804
- * no loading flash.
823
+ * no loading flash. `onError` receives a subscription-scoped error the server
824
+ * pushes (a session expiry, an RLS denial); without it the ref keeps rendering
825
+ * the seed as if it were live.
805
826
  *
806
827
  * Teardown is wired to the active effect scope (`onScopeDispose`), so it fires
807
828
  * on component unmount or `effectScope().stop()`. Call it inside `setup()` / an
@@ -810,6 +831,7 @@ declare const usePresence: <H extends HeartbeatReference, L extends ListPresentR
810
831
  * `getCurrentScope` guard only avoids throwing, it does not auto-clean.
811
832
  */
812
833
  declare const subscribeToQuery: <F extends FunctionReference, T = ReturnOf<F>>(client: LunoraClient, function_: F, args: ArgsOf<F>, options?: {
834
+ onError?: SubscriptionErrorCallback;
813
835
  seed?: T;
814
836
  shardKey?: string;
815
837
  }) => Ref<T | undefined>;
@@ -820,8 +842,8 @@ declare const subscribeToQuery: <F extends FunctionReference, T = ReturnOf<F>>(c
820
842
  * updates on every delta the server pushes — the Vue-idiomatic equivalent of
821
843
  * React's `useQuery`. `args` may be a plain value, a `ref`, or a getter: passing
822
844
  * a reactive source makes the subscription reactive — when the args change the
823
- * old subscription is torn down and a fresh one opens for the new args (matching
824
- * `@lunora/react`/`@lunora/solid`). Pass `"skip"` (or a source resolving to
845
+ * old subscription is torn down, the ref resets to `undefined`, and a fresh one
846
+ * opens for the new args (matching `@lunora/react`/`@lunora/solid`). Pass `"skip"` (or a source resolving to
825
847
  * `"skip"`) to short-circuit: no network call, no socket. The subscription tears
826
848
  * down automatically when the owning component unmounts (or the effect scope
827
849
  * stops).
@@ -881,6 +903,13 @@ interface UseStreamResult<T> {
881
903
  status: Ref<UseStreamStatus>;
882
904
  }
883
905
  interface UseStreamOptions {
906
+ /**
907
+ * Opt into resume-on-reconnect for a stream the server declared `durable`.
908
+ * The chunks already received are kept and the socket re-attaches to the same
909
+ * run, so a dropped connection mid-generation continues instead of surfacing
910
+ * `STREAM_DISCONNECTED`. Has no effect on an ephemeral stream.
911
+ */
912
+ durable?: boolean;
884
913
  /** Forwarded to `client.stream()` — caps the in-flight chunk buffer. */
885
914
  maxBuffer?: number;
886
915
  shardKey?: string;
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { Component, Ref, InjectionKey, App, MaybeRefOrGetter, ComputedRef, DeepReadonly, ShallowRef } from 'vue';
2
- import { Preloaded, LunoraClient, SubscriptionErrorCallback, FunctionReference, ArgsOf, ActionCallOptions, ReturnOf, User, ConnectionStatus, MutationCallOptions, MutatorHandle } from '@lunora/client';
2
+ import { Preloaded, SubscriptionErrorCallback, LunoraClient, FunctionReference, ArgsOf, ActionCallOptions, ReturnOf, User, ConnectionStatus, MutationCallOptions, MutatorHandle, SubscriptionError } from '@lunora/client';
3
3
  export type { ArgsOf, FunctionReference, LunoraClient, MutationCallOptions, MutatorHandle, MutatorTransaction, OptimisticLocalStore, OptimisticUpdate, Preloaded, ReturnOf, SubscriptionError, SubscriptionErrorCallback, Unsubscribe, User } from '@lunora/client';
4
4
  import { PaginationStatus } from '@lunora/client/pagination';
5
5
  export type { PaginationResult, PaginationStatus } from '@lunora/client/pagination';
@@ -33,6 +33,10 @@ declare const AuthLoading: Component;
33
33
  * The subscription tears down with the surrounding effect scope (component
34
34
  * unmount or `effectScope().stop()`), inherited from `subscribeToQuery`.
35
35
  *
36
+ * Pass `onError` to surface a subscription-scoped error the server pushes (a
37
+ * session expiry, an RLS denial). Without it such an error is dropped and the
38
+ * ref keeps rendering the SSR snapshot as if it were live.
39
+ *
36
40
  * The ref is `Ref<T>`, not `Ref<T | undefined>`: `subscribeToQuery`'s ref widens
37
41
  * to `undefined` because it also serves the unseeded `useQuery` case, but this
38
42
  * entry point always passes `seed: preloaded.value`, so the "seeded
@@ -40,7 +44,9 @@ declare const AuthLoading: Component;
40
44
  * other adapter's `hydratePreloaded` returns `T`; narrowing here stops Vue
41
45
  * consumers guarding a state that cannot occur.
42
46
  */
43
- declare const hydratePreloaded: <T>(preloaded: Preloaded<T>) => Ref<T>;
47
+ declare const hydratePreloaded: <T>(preloaded: Preloaded<T>, options?: {
48
+ onError?: SubscriptionErrorCallback;
49
+ }) => Ref<T>;
44
50
  /**
45
51
  * Injection key carrying the {@link LunoraClient} down the component tree.
46
52
  * Exported so advanced consumers can inject it by hand; most apps use
@@ -681,9 +687,18 @@ type PageItemOf<F extends FunctionReference> = ReturnOf<F> extends {
681
687
  interface UsePaginatedQueryOptions {
682
688
  /** Page size for the first page (and the default for `loadMore`). */
683
689
  initialNumItems: number;
690
+ /** Called when a page subscription reports an error (also surfaced on the `error` ref). */
691
+ onError?: SubscriptionErrorCallback;
684
692
  shardKey?: string;
685
693
  }
686
694
  interface UsePaginatedQueryResult<T> {
695
+ /**
696
+ * The last page subscription error, or `undefined`. A tail page that fails
697
+ * before its first frame is dropped so `status` returns to `"CanLoadMore"`
698
+ * and `loadMore` can retry it; cleared by the next successful frame,
699
+ * `loadMore`, or an args change.
700
+ */
701
+ error: Ref<SubscriptionError | undefined>;
687
702
  /** `true` while the first page or a `loadMore` page is in flight. */
688
703
  isLoading: Ref<boolean>;
689
704
  /** Request the next page. A no-op unless `status === "CanLoadMore"`. */
@@ -715,9 +730,13 @@ declare const usePaginatedQuery: <F extends FunctionReference>(function_: F, arg
715
730
  interface UseInfiniteQueryOptions {
716
731
  /** Page size for the first page (and the default for `fetchNextPage`). */
717
732
  initialNumItems: number;
733
+ /** Called when a page subscription reports an error (also surfaced on the `error` ref). */
734
+ onError?: SubscriptionErrorCallback;
718
735
  shardKey?: string;
719
736
  }
720
737
  interface UseInfiniteQueryResult<T> {
738
+ /** The last page subscription error, or `undefined` — see `UsePaginatedQueryResult.error`. */
739
+ error: Ref<SubscriptionError | undefined>;
721
740
  /** Request the next page. A no-op unless `status === "CanLoadMore"`. */
722
741
  fetchNextPage: (numberItems?: number) => void;
723
742
  /** `true` when the loaded tail reports it can load another page. */
@@ -801,7 +820,9 @@ declare const usePresence: <H extends HeartbeatReference, L extends ListPresentR
801
820
  * replays the last value synchronously, so multiple consumers of the same query
802
821
  * ride one server-side registration. `seed` sets the ref's value synchronously
803
822
  * before the subscription attaches, so the first read shows the SSR value with
804
- * no loading flash.
823
+ * no loading flash. `onError` receives a subscription-scoped error the server
824
+ * pushes (a session expiry, an RLS denial); without it the ref keeps rendering
825
+ * the seed as if it were live.
805
826
  *
806
827
  * Teardown is wired to the active effect scope (`onScopeDispose`), so it fires
807
828
  * on component unmount or `effectScope().stop()`. Call it inside `setup()` / an
@@ -810,6 +831,7 @@ declare const usePresence: <H extends HeartbeatReference, L extends ListPresentR
810
831
  * `getCurrentScope` guard only avoids throwing, it does not auto-clean.
811
832
  */
812
833
  declare const subscribeToQuery: <F extends FunctionReference, T = ReturnOf<F>>(client: LunoraClient, function_: F, args: ArgsOf<F>, options?: {
834
+ onError?: SubscriptionErrorCallback;
813
835
  seed?: T;
814
836
  shardKey?: string;
815
837
  }) => Ref<T | undefined>;
@@ -820,8 +842,8 @@ declare const subscribeToQuery: <F extends FunctionReference, T = ReturnOf<F>>(c
820
842
  * updates on every delta the server pushes — the Vue-idiomatic equivalent of
821
843
  * React's `useQuery`. `args` may be a plain value, a `ref`, or a getter: passing
822
844
  * a reactive source makes the subscription reactive — when the args change the
823
- * old subscription is torn down and a fresh one opens for the new args (matching
824
- * `@lunora/react`/`@lunora/solid`). Pass `"skip"` (or a source resolving to
845
+ * old subscription is torn down, the ref resets to `undefined`, and a fresh one
846
+ * opens for the new args (matching `@lunora/react`/`@lunora/solid`). Pass `"skip"` (or a source resolving to
825
847
  * `"skip"`) to short-circuit: no network call, no socket. The subscription tears
826
848
  * down automatically when the owning component unmounts (or the effect scope
827
849
  * stops).
@@ -881,6 +903,13 @@ interface UseStreamResult<T> {
881
903
  status: Ref<UseStreamStatus>;
882
904
  }
883
905
  interface UseStreamOptions {
906
+ /**
907
+ * Opt into resume-on-reconnect for a stream the server declared `durable`.
908
+ * The chunks already received are kept and the socket re-attaches to the same
909
+ * run, so a dropped connection mid-generation continues instead of surfacing
910
+ * `STREAM_DISCONNECTED`. Has no effect on an ephemeral stream.
911
+ */
912
+ durable?: boolean;
884
913
  /** Forwarded to `client.stream()` — caps the in-flight chunk buffer. */
885
914
  maxBuffer?: number;
886
915
  shardKey?: string;
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- import{AuthLoading as r,Authenticated as t,Unauthenticated as u}from"./packem_shared/AuthLoading-nfI43dvD.mjs";import{hydratePreloaded as a}from"./packem_shared/hydratePreloaded-BtfKkWB8.mjs";import{LUNORA_INJECTION_KEY as f,createLunora as m,provideLunora as p,useLunora as x}from"./packem_shared/LUNORA_INJECTION_KEY-Bct9tKCj.mjs";import{useAction as A}from"./packem_shared/useAction-C4VLsh4M.mjs";import{useAgent as d}from"./packem_shared/useAgent-Bji8ptsw.mjs";import{useAgentChat as h}from"./packem_shared/useAgentChat-BZBKErKQ.mjs";import{useAgentState as l}from"./packem_shared/useAgentState-B_LPf5ZX.mjs";import{useAgentToolEvents as Q}from"./packem_shared/useAgentToolEvents-DYYeyrXW.mjs";import{useAuth as b}from"./packem_shared/useAuth-DJ9902_4.mjs";import{default as E}from"./packem_shared/useConnectionStatus-BSFJBnmi.mjs";import{useFlag as N,useFlags as P}from"./packem_shared/useFlag-xVfWC_c6.mjs";import{useMutation as v}from"./packem_shared/useMutation-D6PkaNaE.mjs";import{useMutator as M}from"./packem_shared/useMutator-CO7nXlRf.mjs";import{useInfiniteQuery as R,usePaginatedQuery as U}from"./packem_shared/useInfiniteQuery-Dr8XgbH7.mjs";import{usePresence as J}from"./packem_shared/usePresence-D5H9k1UX.mjs";import{subscribeToQuery as V,useQuery as Y}from"./packem_shared/subscribeToQuery-CHbbz_3v.mjs";import{useRateLimit as k}from"./packem_shared/useRateLimit-zoPsflSG.mjs";import{useStream as w}from"./packem_shared/useStream-pSLl_8ix.mjs";import{useSubscription as B}from"./packem_shared/useSubscription-uZqOa1Pu.mjs";import{useVoiceAgent as G}from"./packem_shared/useVoiceAgent-CR6Tyf_3.mjs";export{r as AuthLoading,t as Authenticated,f as LUNORA_INJECTION_KEY,u as Unauthenticated,m as createLunora,a as hydratePreloaded,p as provideLunora,V as subscribeToQuery,A as useAction,d as useAgent,h as useAgentChat,l as useAgentState,Q as useAgentToolEvents,b as useAuth,E as useConnectionStatus,N as useFlag,P as useFlags,R as useInfiniteQuery,x as useLunora,v as useMutation,M as useMutator,U as usePaginatedQuery,J as usePresence,Y as useQuery,k as useRateLimit,w as useStream,B as useSubscription,G as useVoiceAgent};
1
+ import{AuthLoading as r,Authenticated as t,Unauthenticated as u}from"./packem_shared/AuthLoading-nfI43dvD.mjs";import{hydratePreloaded as a}from"./packem_shared/hydratePreloaded-BpzZkPH4.mjs";import{LUNORA_INJECTION_KEY as f,createLunora as m,provideLunora as p,useLunora as x}from"./packem_shared/LUNORA_INJECTION_KEY-Bct9tKCj.mjs";import{useAction as A}from"./packem_shared/useAction-C4VLsh4M.mjs";import{useAgent as d}from"./packem_shared/useAgent-By6FSLfF.mjs";import{useAgentChat as h}from"./packem_shared/useAgentChat-Dv_y3vQH.mjs";import{useAgentState as l}from"./packem_shared/useAgentState-BYx1l9vy.mjs";import{useAgentToolEvents as Q}from"./packem_shared/useAgentToolEvents-BMwcZ2G9.mjs";import{useAuth as b}from"./packem_shared/useAuth-DJ9902_4.mjs";import{default as E}from"./packem_shared/useConnectionStatus-BSFJBnmi.mjs";import{useFlag as N,useFlags as P}from"./packem_shared/useFlag-xVfWC_c6.mjs";import{useMutation as v}from"./packem_shared/useMutation-D6PkaNaE.mjs";import{useMutator as M}from"./packem_shared/useMutator-CO7nXlRf.mjs";import{useInfiniteQuery as R,usePaginatedQuery as U}from"./packem_shared/useInfiniteQuery-CvBV9XVA.mjs";import{usePresence as J}from"./packem_shared/usePresence-BOs1lDlC.mjs";import{subscribeToQuery as V,useQuery as Y}from"./packem_shared/subscribeToQuery-G5w094pU.mjs";import{useRateLimit as k}from"./packem_shared/useRateLimit-zoPsflSG.mjs";import{useStream as w}from"./packem_shared/useStream-Ca4Rkw4p.mjs";import{useSubscription as B}from"./packem_shared/useSubscription-yGJRK0w-.mjs";import{useVoiceAgent as G}from"./packem_shared/useVoiceAgent-CR6Tyf_3.mjs";export{r as AuthLoading,t as Authenticated,f as LUNORA_INJECTION_KEY,u as Unauthenticated,m as createLunora,a as hydratePreloaded,p as provideLunora,V as subscribeToQuery,A as useAction,d as useAgent,h as useAgentChat,l as useAgentState,Q as useAgentToolEvents,b as useAuth,E as useConnectionStatus,N as useFlag,P as useFlags,R as useInfiniteQuery,x as useLunora,v as useMutation,M as useMutator,U as usePaginatedQuery,J as usePresence,Y as useQuery,k as useRateLimit,w as useStream,B as useSubscription,G as useVoiceAgent};
@@ -0,0 +1 @@
1
+ import{useLunora as u}from"./LUNORA_INJECTION_KEY-Bct9tKCj.mjs";import{subscribeToQuery as a}from"./subscribeToQuery-G5w094pU.mjs";const l=(r,e={})=>{const o=u(),{args:n,functionPath:t,shardKey:c,value:s}=r;return a(o,{__lunoraRef:t},n,{onError:e.onError,seed:s,shardKey:c})};export{l as hydratePreloaded};
@@ -0,0 +1 @@
1
+ import{createQuerySubscription as b}from"@lunora/client/query";import{shallowRef as i,watch as f,toValue as l}from"vue";import{i as n}from"./is-browser-BEdfLJHK.mjs";import{useLunora as v}from"./LUNORA_INJECTION_KEY-Bct9tKCj.mjs";import{o as p}from"./scope-dispose-Mq3k4nvP.mjs";const Q=(s,t,o,e={})=>{const r=i(e.seed);if(n()){const a=s.subscribe(t,o,u=>{r.value=u},{onError:e.onError,shardKey:e.shardKey});p(a)}return r},D=(s,t,o={})=>{const e=v(),r=i(void 0);return f(()=>l(t),(a,u,c)=>{if(!n())return;r.value=void 0;const m=b(e,s,a,{onData:d=>{r.value=d},onError:o.onError,onReset:()=>{r.value=void 0}},{shardKey:o.shardKey});c(m)},{immediate:!0}),r};export{Q as subscribeToQuery,D as useQuery};
@@ -1 +1 @@
1
- import{computed as o,toValue as a}from"vue";import{useMutation as s}from"./useMutation-D6PkaNaE.mjs";import{useSubscription as y}from"./useSubscription-uZqOa1Pu.mjs";const v={__lunoraRef:""},I=u=>{const{api:i,cancel:c,run:d,runArgs:l,threadKey:e}=u,r=s(d),m=s(c??v),{data:p}=y(i.agents.agentThread,()=>({key:a(e)})),n=o(()=>p.value),f=o(()=>n.value?.status),g=async(t,h)=>{await r.mutate({input:t,threadKey:a(e),...l,...h})};return{cancel:async()=>{const t=n.value?.instanceId;c===void 0||t===void 0||await m.mutate({instanceId:t,threadKey:a(e)})},pending:r.pending,run:g,status:f,thread:n}};export{v as NO_MUTATION_REF,I as useAgent};
1
+ import{computed as o,toValue as a}from"vue";import{useMutation as s}from"./useMutation-D6PkaNaE.mjs";import{useSubscription as y}from"./useSubscription-yGJRK0w-.mjs";const v={__lunoraRef:""},I=u=>{const{api:i,cancel:c,run:d,runArgs:l,threadKey:e}=u,r=s(d),m=s(c??v),{data:p}=y(i.agents.agentThread,()=>({key:a(e)})),n=o(()=>p.value),f=o(()=>n.value?.status),g=async(t,h)=>{await r.mutate({input:t,threadKey:a(e),...l,...h})};return{cancel:async()=>{const t=n.value?.instanceId;c===void 0||t===void 0||await m.mutate({instanceId:t,threadKey:a(e)})},pending:r.pending,run:g,status:f,thread:n}};export{v as NO_MUTATION_REF,I as useAgent};
@@ -1 +1 @@
1
- import{reconcileOptimistic as y,maxSeq as A}from"@lunora/client";import{ref as D,watch as N,toValue as s,computed as c}from"vue";import{NO_MUTATION_REF as F}from"./useAgent-Bji8ptsw.mjs";import{useMutation as m}from"./useMutation-D6PkaNaE.mjs";import{useStream as U}from"./useStream-pSLl_8ix.mjs";import{useSubscription as w}from"./useSubscription-uZqOa1Pu.mjs";const V={__lunoraRef:""},W=R=>{const{api:u,cancel:v,limit:p,send:k,sendArgs:x,stream:h,threadKey:a}=R,{data:I}=w(u.agents.agentMessages,()=>{const t=s(a);return p===void 0?{key:t}:{key:t,limit:p}}),{data:M}=w(u.agents.agentThread,()=>({key:s(a)})),S=h===void 0?"skip":()=>({key:s(a)}),{chunks:_}=U(h??V,S),b=m(k),K=m(v??F),T=m(u.agents.agentResolveApproval),r=D([]);let f=0;N(()=>s(a),()=>{r.value=[]});const l=c(()=>M.value),j=c(()=>l.value?.status),i=c(()=>I.value??[]),q=c(()=>{const t=i.value,n=y(r.value,t);if(n.length===0)return t;const e=A(t);return[...t,...n.map((o,d)=>({content:o.content,optimistic:!0,role:"user",seq:e+1+d}))]}),E=c(()=>{const t=s(a),n=i.value.filter(e=>e.role==="assistant").length;return _.value.filter(e=>e.kind!=="progress"&&e.threadKey===t&&e.turn>=n).map(e=>e.text).join("")}),O=async(t,n)=>{const e=f;f+=1;const o=A(i.value);r.value=[...y(r.value,i.value),{content:t,id:e,maxDurableSeqAtSend:o}];try{await b.mutate({input:t,threadKey:s(a),...x,...n})}catch(d){throw r.value=r.value.filter(C=>C.id!==e),d}},g=async(t,n,e)=>{const o=l.value?.instanceId;if(o===void 0)throw new Error(`useAgentChat: cannot ${t} — no in-flight run (thread has no instanceId)`);await T.mutate({decision:t,instanceId:o,threadKey:s(a),toolCallId:n,...e===void 0?{}:{note:e}})};return{approve:async(t,n)=>g("approve",t,n),cancel:async()=>{const t=l.value?.instanceId;v===void 0||t===void 0||await K.mutate({instanceId:t,threadKey:s(a)})},messages:q,reject:async(t,n)=>g("reject",t,n),send:O,status:j,streamingText:E}};export{W as useAgentChat};
1
+ import{reconcileOptimistic as y,maxSeq as A}from"@lunora/client";import{ref as D,watch as N,toValue as s,computed as c}from"vue";import{NO_MUTATION_REF as F}from"./useAgent-By6FSLfF.mjs";import{useMutation as m}from"./useMutation-D6PkaNaE.mjs";import{useStream as U}from"./useStream-Ca4Rkw4p.mjs";import{useSubscription as w}from"./useSubscription-yGJRK0w-.mjs";const V={__lunoraRef:""},W=R=>{const{api:u,cancel:v,limit:p,send:k,sendArgs:x,stream:h,threadKey:a}=R,{data:I}=w(u.agents.agentMessages,()=>{const t=s(a);return p===void 0?{key:t}:{key:t,limit:p}}),{data:M}=w(u.agents.agentThread,()=>({key:s(a)})),S=h===void 0?"skip":()=>({key:s(a)}),{chunks:_}=U(h??V,S),b=m(k),K=m(v??F),T=m(u.agents.agentResolveApproval),r=D([]);let f=0;N(()=>s(a),()=>{r.value=[]});const l=c(()=>M.value),j=c(()=>l.value?.status),i=c(()=>I.value??[]),q=c(()=>{const t=i.value,n=y(r.value,t);if(n.length===0)return t;const e=A(t);return[...t,...n.map((o,d)=>({content:o.content,optimistic:!0,role:"user",seq:e+1+d}))]}),E=c(()=>{const t=s(a),n=i.value.filter(e=>e.role==="assistant").length;return _.value.filter(e=>e.kind!=="progress"&&e.threadKey===t&&e.turn>=n).map(e=>e.text).join("")}),O=async(t,n)=>{const e=f;f+=1;const o=A(i.value);r.value=[...y(r.value,i.value),{content:t,id:e,maxDurableSeqAtSend:o}];try{await b.mutate({input:t,threadKey:s(a),...x,...n})}catch(d){throw r.value=r.value.filter(C=>C.id!==e),d}},g=async(t,n,e)=>{const o=l.value?.instanceId;if(o===void 0)throw new Error(`useAgentChat: cannot ${t} — no in-flight run (thread has no instanceId)`);await T.mutate({decision:t,instanceId:o,threadKey:s(a),toolCallId:n,...e===void 0?{}:{note:e}})};return{approve:async(t,n)=>g("approve",t,n),cancel:async()=>{const t=l.value?.instanceId;v===void 0||t===void 0||await K.mutate({instanceId:t,threadKey:s(a)})},messages:q,reject:async(t,n)=>g("reject",t,n),send:O,status:j,streamingText:E}};export{W as useAgentChat};
@@ -1 +1 @@
1
- import{computed as o,toValue as n}from"vue";import{useSubscription as u}from"./useSubscription-uZqOa1Pu.mjs";const m=t=>{const{data:e,error:r}=u(t.api.agents.agentState,()=>({key:n(t.threadKey)})),a=o(()=>e.value);return{error:r,state:a}};export{m as useAgentState};
1
+ import{computed as o,toValue as n}from"vue";import{useSubscription as u}from"./useSubscription-yGJRK0w-.mjs";const m=t=>{const{data:e,error:r}=u(t.api.agents.agentState,()=>({key:n(t.threadKey)})),a=o(()=>e.value);return{error:r,state:a}};export{m as useAgentState};
@@ -1 +1 @@
1
- import{computed as v,toValue as e}from"vue";import{useStream as f}from"./useStream-pSLl_8ix.mjs";import{useSubscription as C}from"./useSubscription-uZqOa1Pu.mjs";const y={__lunoraRef:""},I=[],N=t=>{if(t.role==="assistant"&&t.toolCalls)return t.toolCalls.map(l=>({input:l.input,seq:t.seq,toolCallId:l.id,toolName:l.name,type:"call"}));if(t.role==="tool")return t.status==="awaiting_approval"?[{seq:t.seq,type:"awaiting-approval",...t.toolCallId===void 0?{}:{toolCallId:t.toolCallId},...t.toolName===void 0?{}:{toolName:t.toolName}}]:[{output:t.content,seq:t.seq,type:"result",...t.status==="approved"||t.status==="rejected"?{status:t.status}:{},...t.toolCallId===void 0?{}:{toolCallId:t.toolCallId},...t.toolName===void 0?{}:{toolName:t.toolName}}]},h=t=>{const{api:l,limit:a,stream:u,threadKey:n}=t,d=()=>{const r=e(n);return a===void 0?{key:r}:{key:r,limit:a}},{data:p}=C(l.agents.agentMessages,d),s=u===void 0?"skip":()=>({key:e(n)}),{chunks:c}=f(u??y,s);return{events:v(()=>{const r=e(n),i=(p.value??I).flatMap(o=>N(o)??[]);for(const o of c.value)o.kind==="progress"&&o.threadKey===r&&i.push({data:o.data,toolCallId:o.toolCallId,type:"progress"});return i})}};export{h as useAgentToolEvents};
1
+ import{computed as v,toValue as e}from"vue";import{useStream as f}from"./useStream-Ca4Rkw4p.mjs";import{useSubscription as C}from"./useSubscription-yGJRK0w-.mjs";const y={__lunoraRef:""},I=[],N=t=>{if(t.role==="assistant"&&t.toolCalls)return t.toolCalls.map(l=>({input:l.input,seq:t.seq,toolCallId:l.id,toolName:l.name,type:"call"}));if(t.role==="tool")return t.status==="awaiting_approval"?[{seq:t.seq,type:"awaiting-approval",...t.toolCallId===void 0?{}:{toolCallId:t.toolCallId},...t.toolName===void 0?{}:{toolName:t.toolName}}]:[{output:t.content,seq:t.seq,type:"result",...t.status==="approved"||t.status==="rejected"?{status:t.status}:{},...t.toolCallId===void 0?{}:{toolCallId:t.toolCallId},...t.toolName===void 0?{}:{toolName:t.toolName}}]},h=t=>{const{api:l,limit:a,stream:u,threadKey:n}=t,d=()=>{const r=e(n);return a===void 0?{key:r}:{key:r,limit:a}},{data:p}=C(l.agents.agentMessages,d),s=u===void 0?"skip":()=>({key:e(n)}),{chunks:c}=f(u??y,s);return{events:v(()=>{const r=e(n),i=(p.value??I).flatMap(o=>N(o)??[]);for(const o of c.value)o.kind==="progress"&&o.threadKey===r&&i.push({data:o.data,toolCallId:o.toolCallId,type:"progress"});return i})}};export{h as useAgentToolEvents};
@@ -0,0 +1 @@
1
+ import{shallowRef as _,watch as v,toValue as j,onScopeDispose as V,computed as E}from"vue";import{initialPages as $,derivePaginationStatus as D,rebalance as q,applyLoadMore as z}from"@lunora/client/pagination";import{i as G}from"./is-browser-BEdfLJHK.mjs";import{useLunora as H}from"./LUNORA_INJECTION_KEY-Bct9tKCj.mjs";const X=/["\\\u0000-\u001F\uD800-\uDFFF]/,T=e=>X.test(e)?JSON.stringify(e):`"${e}"`,x=e=>{if(e===void 0)return"null";if(typeof e=="bigint")throw new TypeError("stableStringify: cannot use a bigint in a stable JSON cache key — pass it as a string, or use stableWireKey");if(typeof e=="number"){if(Number.isNaN(e))return"nan";if(e===1/0)return"inf";if(e===-1/0)return"-inf";if(Object.is(e,-0))return"-0"}if(typeof e=="string")return T(e);if(e===null||typeof e!="object")return JSON.stringify(e);if(Array.isArray(e)){let o="[";for(let r=0;r<e.length;r++)r>0&&(o+=","),o+=x(e[r]);return o+"]"}const n=Object.getPrototypeOf(e);if(n!==null&&n!==Object.prototype){const o=e.constructor?.name??"value";throw new TypeError(`stableStringify: cannot use a ${o} in a stable JSON cache key — only plain objects, arrays, and JSON primitives are supported (wire-typed values key via stableWireKey)`)}const d=e,u=Object.keys(d).sort();let a="{",t=!0;for(const o of u){const r=d[o];r!==void 0&&(t?t=!1:a+=",",a+=T(o),a+=":",a+=x(r))}return a+"}"},F=e=>{let n="";for(let u=0;u<e.length;u+=32768)n+=String.fromCharCode(...e.subarray(u,u+32768));return btoa(n)},l="$lunora.wire$",U=64,Y="__proto__",Z=e=>{if(e===null||typeof e!="object")return!1;const n=Object.getPrototypeOf(e);return n===null||n===Object.prototype},S=(e,n=0)=>{if(n>U)throw new RangeError(`wire-codec: value nesting exceeds the ${U}-level limit`);if(e===void 0)return[l,"undefined"];if(e===null)return null;const d=typeof e;if(d==="bigint")return[l,"bigint",e.toString()];if(d==="number"){const t=e;return Number.isNaN(t)?[l,"nan"]:t===1/0?[l,"inf"]:t===-1/0?[l,"-inf"]:t}if(d!=="object")return e;if(e instanceof Date)return[l,"date",S(e.getTime(),n+1)];if(e instanceof Error){const t=e,o={};for(const y of Object.keys(t))t[y]!==void 0&&(o[y]=S(t[y],n+1));const r=[l,"error",t.name,t.message,o];return t.cause!==void 0&&r.push(S(t.cause,n+1)),r}if(e instanceof URL)return[l,"url",e.href];if(e instanceof Map)return[l,"map",[...e.entries()].map(([t,o])=>[S(t,n+1),S(o,n+1)])];if(e instanceof Set)return[l,"set",[...e].map(t=>S(t,n+1))];if(e instanceof ArrayBuffer)return[l,"bytes",F(new Uint8Array(e)),"ArrayBuffer"];if(ArrayBuffer.isView(e)){const t=e,o=t.constructor.name,r=new Uint8Array(t.buffer,t.byteOffset,t.byteLength);return o==="Uint8Array"?[l,"bytes",F(r)]:[l,"bytes",F(r),o]}if(Array.isArray(e)){const t=e.map(o=>S(o,n+1));return t.length>0&&t[0]===l?[l,"arr",t]:t}if(!Z(e)){const t=e.constructor?.name??"value";throw new TypeError(`wire-codec: cannot encode a ${t} over the Lunora wire — only plain objects, arrays, and the supported built-ins (Date, Error, URL, Map, Set, ArrayBuffer/typed arrays, bigint) round-trip`)}const u=e,a={};for(const t of Object.keys(u)){const o=u[t];if(o===void 0)continue;const r=S(o,n+1);t===Y?Object.defineProperty(a,t,{configurable:!0,enumerable:!0,value:r,writable:!0}):a[t]=r}return a},J=e=>x(S(e)),A=(e,n)=>`${e}::${J(n)}`,M=(e,n)=>({...n,paginationOpts:{cursor:e.lower,endCursor:e.upper,numItems:e.numItems}}),W=(e,n,d)=>{const u=H(),{initialNumItems:a,onError:t,shardKey:o}=d,r=_($(a)),y=_([]),P=_(void 0);let R;const w=new Map,b=new Map,m=new Set,K=(s,i)=>{y.value=s.map(h=>{const f=A(e.__lunoraRef,M(h,i));return b.get(f)})},Q=(s,i,h)=>{const f=p=>A(e.__lunoraRef,M(p,h));for(const p of i){const g=f(p);if(b.has(g))continue;const O=s.find(c=>c.lower===p.lower);if(O){const c=b.get(f(O));c&&b.set(g,c)}}},C=(s,i)=>{const h=new Set;for(const f of s)h.add(A(e.__lunoraRef,M(f,i)));for(const[f,p]of w)h.has(f)||(p(),w.delete(f),b.delete(f),m.delete(f));for(const f of s){const p=M(f,i),g=A(e.__lunoraRef,p);if(w.has(g))continue;m.add(g);const O=u.subscribe(e,p,c=>{b.set(g,c),m.delete(g),P.value=void 0;const k=j(n);if(K(r.value,k),m.size===0){const N=r.value,L=q(N,y.value);L&&(Q(N,L,k),r.value=L)}},{onError:c=>{m.delete(g),P.value=c;const k=r.value,N=k.at(-1);k.length>1&&N&&!b.has(g)&&A(e.__lunoraRef,M(N,i))===g&&(r.value=k.slice(0,-1)),t?.(c)},shardKey:o});w.set(g,O)}},I=()=>{for(const s of w.values())s();w.clear(),b.clear(),m.clear()};v(()=>J(j(n)),()=>{if(!G())return;const s=j(n);I(),r.value=$(a),y.value=[],P.value=void 0,R=void 0,s!=="skip"&&(C(r.value,s),K(r.value,s))},{immediate:!0}),v(()=>r.value,s=>{const i=j(n);R=void 0,i!=="skip"&&(C(s,i),K(s,i))}),V(I);const B=_("LoadingFirstPage");return v([()=>j(n),y],([s,i])=>{B.value=D(s==="skip",i).status},{immediate:!0}),{error:P,loadMore:s=>{const i=j(n);if(i==="skip")return;const{nextCursor:h,status:f}=D(!1,y.value);if(f!=="CanLoadMore"||h===R)return;const p=z(r.value,h,s);if(!p)return;R=h,P.value=void 0;const g=r.value.at(-1),O=p.at(-2);if(g&&O){const c=A(e.__lunoraRef,M(g,i)),k=A(e.__lunoraRef,M(O,i)),N=w.get(c);if(N&&c!==k){const L=b.get(c);L&&b.set(k,L),N(),w.delete(c),b.delete(c),m.delete(c)}}r.value=p},pageResults:y,status:B}},se=(e,n,d)=>{const{error:u,loadMore:a,pageResults:t,status:o}=W(e,n,d),r=E(()=>t.value.flatMap(P=>P?.page??[])),y=E(()=>o.value==="LoadingFirstPage"||o.value==="LoadingMore");return{error:u,isLoading:y,loadMore:a,results:r,status:o}},ie=(e,n,d)=>{const{initialNumItems:u}=d,{error:a,loadMore:t,pageResults:o,status:r}=W(e,n,d),y=E(()=>o.value.flatMap(m=>m?[m.page]:[])),P=E(()=>r.value==="LoadingFirstPage"),R=E(()=>r.value==="CanLoadMore"),w=E(()=>r.value==="LoadingMore");return{error:a,fetchNextPage:m=>{t(m??u)},hasNextPage:R,isFetchingNextPage:w,isLoading:P,pages:y,status:r}};export{ie as useInfiniteQuery,se as usePaginatedQuery};
@@ -0,0 +1 @@
1
+ import{shallowRef as b}from"vue";import{i as I}from"./is-browser-BEdfLJHK.mjs";import{useLunora as U}from"./LUNORA_INJECTION_KEY-Bct9tKCj.mjs";import{o as g}from"./scope-dispose-Mq3k4nvP.mjs";const h=()=>{if(typeof crypto<"u"){if(typeof crypto.randomUUID=="function")return crypto.randomUUID();if(typeof crypto.getRandomValues=="function"){const e=crypto.getRandomValues(new Uint8Array(16));return Array.from(e,t=>t.toString(16).padStart(2,"0")).join("")}}throw new Error("randomSessionId: no Web Crypto available — a session id needs crypto.randomUUID or crypto.getRandomValues")},w=1e4,R=(e,t)=>{const r=U(),{heartbeat:u,intervalMs:f=w,listPresent:l,shardKey:s}=t,i=t.sessionId??h(),c=b(void 0);let a=t.data;const o=()=>{const n={roomId:e,sessionId:i,...a===void 0?{}:{data:a}};r.mutation(u,n,{shardKey:s}).catch(()=>{})},m=n=>{a=n,o()};if(I()){o();const n=setInterval(o,f),d=()=>{typeof document<"u"&&document.visibilityState==="visible"&&o()};typeof document<"u"&&document.addEventListener("visibilitychange",d);const p=r.acquireConnectionContext({roomId:e,sessionId:i},{shardKey:s}),y=r.subscribe(l,{roomId:e},v=>{c.value=v},{shardKey:s});g(()=>{clearInterval(n),typeof document<"u"&&document.removeEventListener("visibilitychange",d),p(),y()})}return{present:c,sessionId:i,setData:m}};export{R as usePresence};
@@ -0,0 +1 @@
1
+ import{ref as l,watch as p,toValue as b,onScopeDispose as y}from"vue";import{useLunora as k}from"./LUNORA_INJECTION_KEY-Bct9tKCj.mjs";const S=(v,m,o={})=>{const d=k(),a=l([]),u=l(void 0),e=l("idle");let t;const s=()=>{t?.()};return p(()=>b(m),(i,w,h)=>{if(a.value=[],u.value=void 0,i==="skip"){e.value="idle";return}e.value="streaming";let c=!0;const f=d.stream(v,i,{durable:o.durable,maxBuffer:o.maxBuffer,shardKey:o.shardKey}),n=()=>{f.cancel()};t=n,(async()=>{try{for await(const r of f){if(!c)return;a.value=[...a.value,r]}c&&(e.value="complete")}catch(r){if(!c)return;u.value=r instanceof Error?r:new Error(String(r)),e.value="error"}})().catch(()=>{}),h(()=>{c=!1,n(),t===n&&(t=void 0)})},{immediate:!0}),y(()=>{s()}),{cancel:s,chunks:a,error:u,status:e}};export{S as useStream};
@@ -0,0 +1 @@
1
+ import{createQuerySubscription as m}from"@lunora/client/query";import{LunoraError as l}from"@lunora/errors";import{ref as i,watch as c,toValue as p,onScopeDispose as f}from"vue";import{i as w}from"./is-browser-BEdfLJHK.mjs";import{useLunora as h}from"./LUNORA_INJECTION_KEY-Bct9tKCj.mjs";const g=(t,u,v={})=>{const s=h(),e=i(void 0),r=i(void 0);return c(()=>p(u),(a,y,d)=>{if(e.value=void 0,r.value=void 0,a==="skip"||!w())return;const n=m(s,t,a,{onData:o=>{e.value=o,r.value=void 0},onError:o=>{r.value=o.code===void 0?new Error(o.message):new l(o.code,o.message),e.value=void 0},onReset:()=>{e.value=void 0}},{shardKey:v.shardKey});d(n)},{immediate:!0}),f(()=>{e.value=void 0,r.value=void 0}),{data:e,error:r}};export{g as useSubscription};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lunora/vue",
3
- "version": "1.0.0-alpha.106",
3
+ "version": "1.0.0-alpha.107",
4
4
  "description": "Vue adapter for Lunora — live composables, optimistic mutations, and reactive loaders",
5
5
  "keywords": [
6
6
  "cloudflare",
@@ -54,9 +54,9 @@
54
54
  "access": "public"
55
55
  },
56
56
  "dependencies": {
57
- "@lunora/client": "1.0.0-alpha.71",
58
- "@lunora/errors": "1.0.0-alpha.29",
59
- "@lunora/ratelimit": "1.0.0-alpha.35",
57
+ "@lunora/client": "1.0.0-alpha.72",
58
+ "@lunora/errors": "1.0.0-alpha.30",
59
+ "@lunora/ratelimit": "1.0.0-alpha.36",
60
60
  "@visulima/storage-client": "1.0.2"
61
61
  },
62
62
  "peerDependencies": {
@@ -1 +0,0 @@
1
- import{useLunora as s}from"./LUNORA_INJECTION_KEY-Bct9tKCj.mjs";import{subscribeToQuery as u}from"./subscribeToQuery-CHbbz_3v.mjs";const d=e=>{const r=s(),{args:n,functionPath:o,shardKey:t,value:c}=e;return u(r,{__lunoraRef:o},n,{seed:c,shardKey:t})};export{d as hydratePreloaded};
@@ -1 +0,0 @@
1
- import{createQuerySubscription as b}from"@lunora/client/query";import{shallowRef as i,watch as f,toValue as p}from"vue";import{i as n}from"./is-browser-BEdfLJHK.mjs";import{useLunora as l}from"./LUNORA_INJECTION_KEY-Bct9tKCj.mjs";import{o as y}from"./scope-dispose-Mq3k4nvP.mjs";const D=(s,t,e,o={})=>{const r=i(o.seed);if(n()){const a=s.subscribe(t,e,u=>{r.value=u},{shardKey:o.shardKey});y(a)}return r},E=(s,t,e={})=>{const o=l(),r=i(void 0);return f(()=>p(t),(a,u,c)=>{if(!n())return;const m=b(o,s,a,{onData:d=>{r.value=d},onError:e.onError,onReset:()=>{r.value=void 0}},{shardKey:e.shardKey});c(m)},{immediate:!0}),r};export{D as subscribeToQuery,E as useQuery};
@@ -1 +0,0 @@
1
- import{shallowRef as E,watch as _,toValue as N,onScopeDispose as V,computed as L}from"vue";import{initialPages as D,derivePaginationStatus as T,rebalance as q,applyLoadMore as z}from"@lunora/client/pagination";import{i as G}from"./is-browser-BEdfLJHK.mjs";import{useLunora as H}from"./LUNORA_INJECTION_KEY-Bct9tKCj.mjs";const X=/["\\\u0000-\u001F\uD800-\uDFFF]/,U=e=>X.test(e)?JSON.stringify(e):`"${e}"`,x=e=>{if(e===void 0)return"null";if(typeof e=="bigint")throw new TypeError("stableStringify: cannot use a bigint in a stable JSON cache key — pass it as a string, or use stableWireKey");if(typeof e=="number"){if(Number.isNaN(e))return"nan";if(e===1/0)return"inf";if(e===-1/0)return"-inf";if(Object.is(e,-0))return"-0"}if(typeof e=="string")return U(e);if(e===null||typeof e!="object")return JSON.stringify(e);if(Array.isArray(e)){let n="[";for(let o=0;o<e.length;o++)o>0&&(n+=","),n+=x(e[o]);return n+"]"}const r=Object.getPrototypeOf(e);if(r!==null&&r!==Object.prototype){const n=e.constructor?.name??"value";throw new TypeError(`stableStringify: cannot use a ${n} in a stable JSON cache key — only plain objects, arrays, and JSON primitives are supported (wire-typed values key via stableWireKey)`)}const l=e,u=Object.keys(l).sort();let i="{",t=!0;for(const n of u){const o=l[n];o!==void 0&&(t?t=!1:i+=",",i+=U(n),i+=":",i+=x(o))}return i+"}"},F=e=>{let r="";for(let u=0;u<e.length;u+=32768)r+=String.fromCharCode(...e.subarray(u,u+32768));return btoa(r)},y="$lunora.wire$",J=64,Y="__proto__",Z=e=>{if(e===null||typeof e!="object")return!1;const r=Object.getPrototypeOf(e);return r===null||r===Object.prototype},S=(e,r=0)=>{if(r>J)throw new RangeError(`wire-codec: value nesting exceeds the ${J}-level limit`);if(e===void 0)return[y,"undefined"];if(e===null)return null;const l=typeof e;if(l==="bigint")return[y,"bigint",e.toString()];if(l==="number"){const t=e;return Number.isNaN(t)?[y,"nan"]:t===1/0?[y,"inf"]:t===-1/0?[y,"-inf"]:t}if(l!=="object")return e;if(e instanceof Date)return[y,"date",S(e.getTime(),r+1)];if(e instanceof Error){const t=e,n={};for(const p of Object.keys(t))t[p]!==void 0&&(n[p]=S(t[p],r+1));const o=[y,"error",t.name,t.message,n];return t.cause!==void 0&&o.push(S(t.cause,r+1)),o}if(e instanceof URL)return[y,"url",e.href];if(e instanceof Map)return[y,"map",[...e.entries()].map(([t,n])=>[S(t,r+1),S(n,r+1)])];if(e instanceof Set)return[y,"set",[...e].map(t=>S(t,r+1))];if(e instanceof ArrayBuffer)return[y,"bytes",F(new Uint8Array(e)),"ArrayBuffer"];if(ArrayBuffer.isView(e)){const t=e,n=t.constructor.name,o=new Uint8Array(t.buffer,t.byteOffset,t.byteLength);return n==="Uint8Array"?[y,"bytes",F(o)]:[y,"bytes",F(o),n]}if(Array.isArray(e)){const t=e.map(n=>S(n,r+1));return t.length>0&&t[0]===y?[y,"arr",t]:t}if(!Z(e)){const t=e.constructor?.name??"value";throw new TypeError(`wire-codec: cannot encode a ${t} over the Lunora wire — only plain objects, arrays, and the supported built-ins (Date, Error, URL, Map, Set, ArrayBuffer/typed arrays, bigint) round-trip`)}const u=e,i={};for(const t of Object.keys(u)){const n=u[t];if(n===void 0)continue;const o=S(n,r+1);t===Y?Object.defineProperty(i,t,{configurable:!0,enumerable:!0,value:o,writable:!0}):i[t]=o}return i},W=e=>x(S(e)),O=(e,r)=>`${e}::${W(r)}`,A=(e,r)=>({...r,paginationOpts:{cursor:e.lower,endCursor:e.upper,numItems:e.numItems}}),v=(e,r,l)=>{const u=H(),{initialNumItems:i,shardKey:t}=l,n=E(D(i)),o=E([]);let p;const b=new Map,g=new Map,h=new Set,K=(s,a)=>{o.value=s.map(w=>{const P=O(e.__lunoraRef,A(w,a));return g.get(P)})},Q=(s,a,w)=>{const P=c=>O(e.__lunoraRef,A(c,w));for(const c of a){const d=P(c);if(g.has(d))continue;const m=s.find(f=>f.lower===c.lower);if(m){const f=g.get(P(m));f&&g.set(d,f)}}},C=(s,a)=>{const w=new Set;for(const c of s)w.add(O(e.__lunoraRef,A(c,a)));for(const[c,d]of b)w.has(d.currentKey)||(d.unsub(),b.delete(c),g.delete(d.currentKey),h.delete(d.currentKey));const P=new Set([...b.values()].map(c=>c.currentKey));for(const c of s){const d=A(c,a),m=O(e.__lunoraRef,d);if(P.has(m))continue;const f={currentKey:m,unsub:void 0};h.add(m);const k=u.subscribe(e,d,M=>{g.set(f.currentKey,M),h.delete(f.currentKey);const R=N(r);if(K(n.value,R),h.size===0){const $=n.value,j=q($,o.value);j&&(Q($,j,R),n.value=j)}},{shardKey:t});f.unsub=k,b.set(m,f),P.add(m)}},I=()=>{for(const s of b.values())s.unsub();b.clear(),g.clear(),h.clear()};_(()=>W(N(r)),()=>{if(!G())return;const s=N(r);I(),n.value=D(i),o.value=[],p=void 0,s!=="skip"&&(C(n.value,s),K(n.value,s))},{immediate:!0}),_(()=>n.value,s=>{const a=N(r);a!=="skip"&&(C(s,a),K(s,a))}),V(I);const B=E("LoadingFirstPage");return _([()=>N(r),o],([s,a])=>{B.value=T(s==="skip",a).status},{immediate:!0}),{loadMore:s=>{const a=N(r);if(a==="skip")return;const{nextCursor:w,status:P}=T(!1,o.value);if(P!=="CanLoadMore"||w===p)return;const c=z(n.value,w,s);if(!c)return;p=w;const d=n.value.at(-1),m=c.at(-2);if(d&&m){const f=O(e.__lunoraRef,A(d,a)),k=O(e.__lunoraRef,A(m,a)),M=b.get(f);if(M&&f!==k){M.currentKey=k,b.set(k,M),b.delete(f);const R=g.get(f);R&&(g.set(k,R),g.delete(f))}}n.value=c},pageResults:o,status:B}},se=(e,r,l)=>{const{loadMore:u,pageResults:i,status:t}=v(e,r,l),n=L(()=>i.value.flatMap(p=>p?.page??[]));return{isLoading:L(()=>t.value==="LoadingFirstPage"||t.value==="LoadingMore"),loadMore:u,results:n,status:t}},ie=(e,r,l)=>{const{initialNumItems:u}=l,{loadMore:i,pageResults:t,status:n}=v(e,r,l),o=L(()=>t.value.flatMap(K=>K?[K.page]:[])),p=L(()=>n.value==="LoadingFirstPage"),b=L(()=>n.value==="CanLoadMore"),g=L(()=>n.value==="LoadingMore");return{fetchNextPage:K=>{i(K??u)},hasNextPage:b,isFetchingNextPage:g,isLoading:p,pages:o,status:n}};export{ie as useInfiniteQuery,se as usePaginatedQuery};
@@ -1 +0,0 @@
1
- import{shallowRef as b}from"vue";import{i as g}from"./is-browser-BEdfLJHK.mjs";import{useLunora as D}from"./LUNORA_INJECTION_KEY-Bct9tKCj.mjs";import{o as S}from"./scope-dispose-Mq3k4nvP.mjs";const h=()=>{if(typeof crypto<"u"){if(typeof crypto.randomUUID=="function")return crypto.randomUUID();if(typeof crypto.getRandomValues=="function"){const t=crypto.getRandomValues(new Uint8Array(16));return Array.from(t,e=>e.toString(16).padStart(2,"0")).join("")}}return Date.now().toString(36)},w=1e4,E=(t,e)=>{const r=D(),{heartbeat:u,intervalMs:f=w,listPresent:l,shardKey:s}=e,i=e.sessionId??h(),c=b(void 0);let a=e.data;const o=()=>{const n={roomId:t,sessionId:i,...a===void 0?{}:{data:a}};r.mutation(u,n,{shardKey:s}).catch(()=>{})},m=n=>{a=n,o()};if(g()){o();const n=setInterval(o,f),d=()=>{typeof document<"u"&&document.visibilityState==="visible"&&o()};typeof document<"u"&&document.addEventListener("visibilitychange",d);const p=r.acquireConnectionContext({roomId:t,sessionId:i},{shardKey:s}),y=r.subscribe(l,{roomId:t},v=>{c.value=v},{shardKey:s});S(()=>{clearInterval(n),typeof document<"u"&&document.removeEventListener("visibilitychange",d),p(),y()})}return{present:c,sessionId:i,setData:m}};export{E as usePresence};
@@ -1 +0,0 @@
1
- import{ref as u,watch as p,toValue as y,onScopeDispose as k}from"vue";import{useLunora as w}from"./LUNORA_INJECTION_KEY-Bct9tKCj.mjs";const b=(v,m,s={})=>{const d=w(),t=u([]),c=u(void 0),e=u("idle");let a;const i=()=>{a?.()};return p(()=>y(m),(l,x,h)=>{if(t.value=[],c.value=void 0,l==="skip"){e.value="idle";return}e.value="streaming";let o=!0;const f=d.stream(v,l,{maxBuffer:s.maxBuffer,shardKey:s.shardKey}),n=()=>{f.cancel()};a=n,(async()=>{try{for await(const r of f){if(!o)return;t.value=[...t.value,r]}o&&(e.value="complete")}catch(r){if(!o)return;c.value=r instanceof Error?r:new Error(String(r)),e.value="error"}})().catch(()=>{}),h(()=>{o=!1,n(),a===n&&(a=void 0)})},{immediate:!0}),k(()=>{i()}),{cancel:i,chunks:t,error:c,status:e}};export{b as useStream};
@@ -1 +0,0 @@
1
- import{createQuerySubscription as m}from"@lunora/client/query";import{LunoraError as l}from"@lunora/errors";import{ref as i,watch as c,toValue as p,onScopeDispose as f}from"vue";import{i as w}from"./is-browser-BEdfLJHK.mjs";import{useLunora as h}from"./LUNORA_INJECTION_KEY-Bct9tKCj.mjs";const g=(t,u,v={})=>{const s=h(),e=i(void 0),r=i(void 0);return c(()=>p(u),(a,y,d)=>{if(a==="skip"){e.value=void 0,r.value=void 0;return}if(!w())return;const n=m(s,t,a,{onData:o=>{e.value=o,r.value=void 0},onError:o=>{r.value=o.code===void 0?new Error(o.message):new l(o.code,o.message),e.value=void 0},onReset:()=>{e.value=void 0}},{shardKey:v.shardKey});d(n)},{immediate:!0}),f(()=>{e.value=void 0,r.value=void 0}),{data:e,error:r}};export{g as useSubscription};