@lunora/solid 1.0.0-alpha.82 → 1.0.0-alpha.84

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/dist/index.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { LunoraClient, FunctionReference, ArgsOf, ActionCallOptions, ReturnOf, User, ConnectionStatus, MutationCallOptions, MutatorHandle, SubscriptionErrorCallback, SubscriptionError, Preloaded } from '@lunora/client';
1
+ import { LunoraClient, FunctionReference, ArgsOf, ActionCallOptions, ReturnOf, SubscriptionErrorCallback, User, ConnectionStatus, MutationCallOptions, MutatorHandle, SubscriptionError, Preloaded } from '@lunora/client';
2
2
  export type { ArgsOf, FunctionReference, MutatorHandle, MutatorTransaction, OptimisticUpdate, Preloaded, ReturnOf, SubscriptionError, SubscriptionErrorCallback, Unsubscribe } from '@lunora/client';
3
3
  import { Context, Accessor } from 'solid-js';
4
4
  import { PaginationStatus } from '@lunora/client/pagination';
@@ -120,6 +120,12 @@ interface CreateAgentOptions {
120
120
  * no-op.
121
121
  */
122
122
  cancel?: FunctionReference<"mutation">;
123
+ /**
124
+ * Called when the live thread subscription reports an error (a session
125
+ * expiry, an RLS denial). Without it — and without reading `error` — such a
126
+ * failure is invisible and `thread` / `status` are cleared until a later frame arrives.
127
+ */
128
+ onError?: SubscriptionErrorCallback;
123
129
  /**
124
130
  * The app mutation that starts (or continues) a run — a thin wrapper over
125
131
  * `ctx.agents.<name>.run(...)`. Called with `{ threadKey, input }` merged with
@@ -137,6 +143,8 @@ interface CreateAgentResult {
137
143
  * no-op when no `cancel` mutation was supplied or no run is in flight.
138
144
  */
139
145
  cancel: () => Promise<void>;
146
+ /** The live thread subscription's last error, or `undefined`. */
147
+ error: Accessor<Error | undefined>;
140
148
  /** `true` while a `run` invocation is in flight. */
141
149
  pending: Accessor<boolean>;
142
150
  /** Start (or continue) a run with a user message; extra args merge over `runArgs`. */
@@ -276,6 +284,12 @@ interface CreateAgentChatOptions {
276
284
  cancel?: FunctionReference<"mutation">;
277
285
  /** History depth forwarded to `agents:agentMessages`. */
278
286
  limit?: number;
287
+ /**
288
+ * Called when the live history or thread subscription reports an error (a
289
+ * session expiry, an RLS denial). Without it — and without reading `error` —
290
+ * such a failure is invisible and `messages` / `status` are cleared until a later frame arrives.
291
+ */
292
+ onError?: SubscriptionErrorCallback;
279
293
  /**
280
294
  * The app mutation that starts (or continues) a run — a thin wrapper over
281
295
  * `ctx.agents.<name>.run(...)`. Called with `{ threadKey, input }` merged with
@@ -301,6 +315,8 @@ interface CreateAgentChatResult {
301
315
  * no-op when no `cancel` mutation was supplied or no run is in flight.
302
316
  */
303
317
  cancel: () => Promise<void>;
318
+ /** The history or thread subscription's last error, or `undefined`. */
319
+ error: Accessor<Error | undefined>;
304
320
  /** Durable thread history (oldest first) plus any un-acknowledged optimistic user turns. */
305
321
  messages: Accessor<ReadonlyArray<AgentChatMessage>>;
306
322
  /** Reject a paused human-in-the-loop tool call (optionally with a reason). */
@@ -768,6 +784,12 @@ interface CreatePresenceOptions<H extends HeartbeatReference, L extends ListPres
768
784
  intervalMs?: number;
769
785
  /** The `api.*` reference for the presence listPresent query. */
770
786
  listPresent: L;
787
+ /**
788
+ * Called when the `listPresent` subscription reports an error (a session
789
+ * expiry, an RLS denial). Without it — and without reading `error` — such a
790
+ * failure is invisible and `present` is cleared until a later frame arrives.
791
+ */
792
+ onError?: SubscriptionErrorCallback;
771
793
  /**
772
794
  * Stable id for this presence row. Defaults to a fresh per-mount id.
773
795
  * Pass a user/connection id to control deduping across tabs.
@@ -777,6 +799,8 @@ interface CreatePresenceOptions<H extends HeartbeatReference, L extends ListPres
777
799
  shardKey?: string;
778
800
  }
779
801
  interface CreatePresenceResult<L extends ListPresentReference> {
802
+ /** The `listPresent` subscription's last error, or `undefined`. */
803
+ error: () => SubscriptionError | undefined;
780
804
  /** The present members for the room. `undefined` until the first push. */
781
805
  present: () => ReturnOf<L> | undefined;
782
806
  /** This mount's session id (generated when not supplied). */
@@ -893,8 +917,13 @@ interface CreateSubscriptionResult<T> {
893
917
  * Subscribe to a reactive server push stream. Returns `{ data, error }`
894
918
  * accessors that update whenever the server emits. Passing `"skip"` as `args`
895
919
  * (or an accessor that resolves to `"skip"`) tears down the subscription.
920
+ *
921
+ * `onError` mirrors the other adapters' subscription primitives: it receives the
922
+ * raw wire-level subscription error (code included) alongside the normalised
923
+ * `error` accessor.
896
924
  */
897
925
  declare const createSubscription: <F extends FunctionReference>(function_: F, args: ArgsOf<F> | "skip" | Accessor<ArgsOf<F> | "skip">, options?: {
926
+ onError?: SubscriptionErrorCallback;
898
927
  shardKey?: string;
899
928
  }) => CreateSubscriptionResult<ReturnOf<F>>;
900
929
  /**
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { LunoraClient, FunctionReference, ArgsOf, ActionCallOptions, ReturnOf, User, ConnectionStatus, MutationCallOptions, MutatorHandle, SubscriptionErrorCallback, SubscriptionError, Preloaded } from '@lunora/client';
1
+ import { LunoraClient, FunctionReference, ArgsOf, ActionCallOptions, ReturnOf, SubscriptionErrorCallback, User, ConnectionStatus, MutationCallOptions, MutatorHandle, SubscriptionError, Preloaded } from '@lunora/client';
2
2
  export type { ArgsOf, FunctionReference, MutatorHandle, MutatorTransaction, OptimisticUpdate, Preloaded, ReturnOf, SubscriptionError, SubscriptionErrorCallback, Unsubscribe } from '@lunora/client';
3
3
  import { Context, Accessor } from 'solid-js';
4
4
  import { PaginationStatus } from '@lunora/client/pagination';
@@ -120,6 +120,12 @@ interface CreateAgentOptions {
120
120
  * no-op.
121
121
  */
122
122
  cancel?: FunctionReference<"mutation">;
123
+ /**
124
+ * Called when the live thread subscription reports an error (a session
125
+ * expiry, an RLS denial). Without it — and without reading `error` — such a
126
+ * failure is invisible and `thread` / `status` are cleared until a later frame arrives.
127
+ */
128
+ onError?: SubscriptionErrorCallback;
123
129
  /**
124
130
  * The app mutation that starts (or continues) a run — a thin wrapper over
125
131
  * `ctx.agents.<name>.run(...)`. Called with `{ threadKey, input }` merged with
@@ -137,6 +143,8 @@ interface CreateAgentResult {
137
143
  * no-op when no `cancel` mutation was supplied or no run is in flight.
138
144
  */
139
145
  cancel: () => Promise<void>;
146
+ /** The live thread subscription's last error, or `undefined`. */
147
+ error: Accessor<Error | undefined>;
140
148
  /** `true` while a `run` invocation is in flight. */
141
149
  pending: Accessor<boolean>;
142
150
  /** Start (or continue) a run with a user message; extra args merge over `runArgs`. */
@@ -276,6 +284,12 @@ interface CreateAgentChatOptions {
276
284
  cancel?: FunctionReference<"mutation">;
277
285
  /** History depth forwarded to `agents:agentMessages`. */
278
286
  limit?: number;
287
+ /**
288
+ * Called when the live history or thread subscription reports an error (a
289
+ * session expiry, an RLS denial). Without it — and without reading `error` —
290
+ * such a failure is invisible and `messages` / `status` are cleared until a later frame arrives.
291
+ */
292
+ onError?: SubscriptionErrorCallback;
279
293
  /**
280
294
  * The app mutation that starts (or continues) a run — a thin wrapper over
281
295
  * `ctx.agents.<name>.run(...)`. Called with `{ threadKey, input }` merged with
@@ -301,6 +315,8 @@ interface CreateAgentChatResult {
301
315
  * no-op when no `cancel` mutation was supplied or no run is in flight.
302
316
  */
303
317
  cancel: () => Promise<void>;
318
+ /** The history or thread subscription's last error, or `undefined`. */
319
+ error: Accessor<Error | undefined>;
304
320
  /** Durable thread history (oldest first) plus any un-acknowledged optimistic user turns. */
305
321
  messages: Accessor<ReadonlyArray<AgentChatMessage>>;
306
322
  /** Reject a paused human-in-the-loop tool call (optionally with a reason). */
@@ -768,6 +784,12 @@ interface CreatePresenceOptions<H extends HeartbeatReference, L extends ListPres
768
784
  intervalMs?: number;
769
785
  /** The `api.*` reference for the presence listPresent query. */
770
786
  listPresent: L;
787
+ /**
788
+ * Called when the `listPresent` subscription reports an error (a session
789
+ * expiry, an RLS denial). Without it — and without reading `error` — such a
790
+ * failure is invisible and `present` is cleared until a later frame arrives.
791
+ */
792
+ onError?: SubscriptionErrorCallback;
771
793
  /**
772
794
  * Stable id for this presence row. Defaults to a fresh per-mount id.
773
795
  * Pass a user/connection id to control deduping across tabs.
@@ -777,6 +799,8 @@ interface CreatePresenceOptions<H extends HeartbeatReference, L extends ListPres
777
799
  shardKey?: string;
778
800
  }
779
801
  interface CreatePresenceResult<L extends ListPresentReference> {
802
+ /** The `listPresent` subscription's last error, or `undefined`. */
803
+ error: () => SubscriptionError | undefined;
780
804
  /** The present members for the room. `undefined` until the first push. */
781
805
  present: () => ReturnOf<L> | undefined;
782
806
  /** This mount's session id (generated when not supplied). */
@@ -893,8 +917,13 @@ interface CreateSubscriptionResult<T> {
893
917
  * Subscribe to a reactive server push stream. Returns `{ data, error }`
894
918
  * accessors that update whenever the server emits. Passing `"skip"` as `args`
895
919
  * (or an accessor that resolves to `"skip"`) tears down the subscription.
920
+ *
921
+ * `onError` mirrors the other adapters' subscription primitives: it receives the
922
+ * raw wire-level subscription error (code included) alongside the normalised
923
+ * `error` accessor.
896
924
  */
897
925
  declare const createSubscription: <F extends FunctionReference>(function_: F, args: ArgsOf<F> | "skip" | Accessor<ArgsOf<F> | "skip">, options?: {
926
+ onError?: SubscriptionErrorCallback;
898
927
  shardKey?: string;
899
928
  }) => CreateSubscriptionResult<ReturnOf<F>>;
900
929
  /**
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- import{LunoraContext as r,useLunora as o}from"./packem_shared/LunoraContext-dPcjtn6R.mjs";import{createAction as c,createActionForClient as n}from"./packem_shared/createAction-M4s8XBXV.mjs";import{createAgent as m}from"./packem_shared/createAgent-hhL-sw_X.mjs";import{createAgentChat as x}from"./packem_shared/createAgentChat-CK0_VzMa.mjs";import{createAgentState as u}from"./packem_shared/createAgentState-D3UsBxBI.mjs";import{createAgentToolEvents as A}from"./packem_shared/createAgentToolEvents-BoC23C-n.mjs";import{AuthLoading as l,Authenticated as s,Unauthenticated as h,createAuth as C}from"./packem_shared/AuthLoading-6vueEnV0.mjs";import{default as y}from"./packem_shared/createConnectionStatus-BnlXYWeE.mjs";import{createFlag as P,createFlags as S}from"./packem_shared/createFlag-BmHiFrD-.mjs";import{createMutation as Q,createMutationForClient as v}from"./packem_shared/createMutation-DcSsIbGF.mjs";import{createMutator as E}from"./packem_shared/createMutator-q9cMjGKv.mjs";import{createInfiniteQuery as R,createPaginatedQuery as T}from"./packem_shared/createInfiniteQuery-B_UTdD9R.mjs";import{createPresence as V}from"./packem_shared/createPresence-eSor6sjx.mjs";import{createQuery as k}from"./packem_shared/createQuery-CdWTlKJM.mjs";import{createRateLimit as w}from"./packem_shared/createRateLimit-CIVWrD5H.mjs";import{createStream as B}from"./packem_shared/createStream-Dx7SnivS.mjs";import{createSubscription as G}from"./packem_shared/createSubscription-1glD6fxF.mjs";import{createVoiceAgent as J}from"./packem_shared/createVoiceAgent-BM9H7p7P.mjs";import{default as N}from"./packem_shared/hydratePreloaded-Bhxdstm1.mjs";import{LunoraProvider as W}from"./packem_shared/LunoraProvider-BKWckcDR.mjs";export{l as AuthLoading,s as Authenticated,r as LunoraContext,W as LunoraProvider,h as Unauthenticated,c as createAction,n as createActionForClient,m as createAgent,x as createAgentChat,u as createAgentState,A as createAgentToolEvents,C as createAuth,y as createConnectionStatus,P as createFlag,S as createFlags,R as createInfiniteQuery,Q as createMutation,v as createMutationForClient,E as createMutator,T as createPaginatedQuery,V as createPresence,k as createQuery,w as createRateLimit,B as createStream,G as createSubscription,J as createVoiceAgent,N as hydratePreloaded,o as useLunora};
1
+ import{LunoraContext as r,useLunora as o}from"./packem_shared/LunoraContext-dPcjtn6R.mjs";import{createAction as c,createActionForClient as n}from"./packem_shared/createAction-M4s8XBXV.mjs";import{createAgent as m}from"./packem_shared/createAgent-DuksX_2d.mjs";import{createAgentChat as x}from"./packem_shared/createAgentChat-Ch4Hqox4.mjs";import{createAgentState as u}from"./packem_shared/createAgentState-Catc7Xux.mjs";import{createAgentToolEvents as A}from"./packem_shared/createAgentToolEvents-BjdgzYqX.mjs";import{AuthLoading as l,Authenticated as s,Unauthenticated as h,createAuth as C}from"./packem_shared/AuthLoading-6vueEnV0.mjs";import{default as y}from"./packem_shared/createConnectionStatus-BnlXYWeE.mjs";import{createFlag as P,createFlags as S}from"./packem_shared/createFlag-DsxOYsJW.mjs";import{createMutation as Q,createMutationForClient as v}from"./packem_shared/createMutation-DcSsIbGF.mjs";import{createMutator as E}from"./packem_shared/createMutator-q9cMjGKv.mjs";import{createInfiniteQuery as R,createPaginatedQuery as T}from"./packem_shared/createInfiniteQuery-CK1FR0g2.mjs";import{createPresence as V}from"./packem_shared/createPresence-Bu4loG39.mjs";import{createQuery as k}from"./packem_shared/createQuery-CdWTlKJM.mjs";import{createRateLimit as w}from"./packem_shared/createRateLimit-CIVWrD5H.mjs";import{createStream as B}from"./packem_shared/createStream-Dx7SnivS.mjs";import{createSubscription as G}from"./packem_shared/createSubscription-CsrywUOa.mjs";import{createVoiceAgent as J}from"./packem_shared/createVoiceAgent-BiALuzBe.mjs";import{default as N}from"./packem_shared/hydratePreloaded-Bhxdstm1.mjs";import{LunoraProvider as W}from"./packem_shared/LunoraProvider-BKWckcDR.mjs";export{l as AuthLoading,s as Authenticated,r as LunoraContext,W as LunoraProvider,h as Unauthenticated,c as createAction,n as createActionForClient,m as createAgent,x as createAgentChat,u as createAgentState,A as createAgentToolEvents,C as createAuth,y as createConnectionStatus,P as createFlag,S as createFlags,R as createInfiniteQuery,Q as createMutation,v as createMutationForClient,E as createMutator,T as createPaginatedQuery,V as createPresence,k as createQuery,w as createRateLimit,B as createStream,G as createSubscription,J as createVoiceAgent,N as hydratePreloaded,o as useLunora};
@@ -0,0 +1 @@
1
+ import{createMemo as s}from"solid-js";import{createMutation as i}from"./createMutation-DcSsIbGF.mjs";import{createSubscription as R}from"./createSubscription-CsrywUOa.mjs";const _={__lunoraRef:""},a=t=>typeof t=="function"?t():t,b=t=>{const{api:u,cancel:c,onError:d,run:f,runArgs:m,threadKey:n}=t,o=i(f),p=i(c??_),{data:y,error:g}=R(u.agents.agentThread,()=>({key:a(n)}),{onError:d}),r=s(()=>y()),h=s(()=>r()?.status),M=async(e,l)=>{await o.mutate({input:e,threadKey:a(n),...m,...l})};return{cancel:async()=>{const e=r()?.instanceId;c===void 0||e===void 0||await p.mutate({instanceId:e,threadKey:a(n)})},error:g,pending:o.pending,run:M,status:h,thread:r}};export{_ as NO_MUTATION_REF,b as createAgent,a as resolveMaybe};
@@ -0,0 +1 @@
1
+ import{reconcileOptimistic as E,maxSeq as M}from"@lunora/client";import{createMemo as s,createSignal as B}from"solid-js";import{resolveMaybe as o,NO_MUTATION_REF as G}from"./createAgent-DuksX_2d.mjs";import{createMutation as u}from"./createMutation-DcSsIbGF.mjs";import{createStream as H}from"./createStream-Dx7SnivS.mjs";import{createSubscription as k}from"./createSubscription-CsrywUOa.mjs";import{t as J}from"./solid-compat-ByG5HD_F.mjs";const L={__lunoraRef:""},nt=R=>{const{api:m,cancel:l,limit:h,onError:f,send:S,sendArgs:b,stream:g,threadKey:n}=R,{data:w,error:x}=k(m.agents.agentMessages,()=>{const t=o(n);return h===void 0?{key:t}:{key:t,limit:h}},{onError:f}),{data:I,error:_}=k(m.agents.agentThread,()=>({key:o(n)}),{onError:f}),K=s(()=>x()??_()),O=g===void 0?"skip":()=>({key:o(n)}),{chunks:T}=H(g??L,O),j=u(S),q=u(l??G),C=u(m.agents.agentResolveApproval),[y,d]=B([]);let v=0;J(()=>o(n),()=>{y().length>0&&d([])});const p=s(()=>I()),D=s(()=>p()?.status),i=s(()=>w()??[]),N=s(()=>{const t=i(),r=E(y(),t);if(r.length===0)return t;const e=M(t);return[...t,...r.map((a,c)=>({content:a.content,optimistic:!0,role:"user",seq:e+1+c}))]}),F=s(()=>{const t=o(n),r=i().filter(e=>e.role==="assistant").length;return T().filter(e=>e.kind!=="progress"&&e.threadKey===t&&e.turn>=r).map(e=>e.text).join("")}),U=async(t,r)=>{const e=v;v+=1;const a=M(i());d(c=>[...E(c,i()),{content:t,id:e,maxDurableSeqAtSend:a}]);try{await j.mutate({input:t,threadKey:o(n),...b,...r})}catch(c){throw d($=>$.filter(z=>z.id!==e)),c}},A=async(t,r,e)=>{const a=p()?.instanceId;if(a===void 0)throw new Error(`createAgentChat: cannot ${t} — no in-flight run (thread has no instanceId)`);await C.mutate({decision:t,instanceId:a,threadKey:o(n),toolCallId:r,...e===void 0?{}:{note:e}})};return{approve:async(t,r)=>A("approve",t,r),cancel:async()=>{const t=p()?.instanceId;l===void 0||t===void 0||await q.mutate({instanceId:t,threadKey:o(n)})},error:K,messages:N,reject:async(t,r)=>A("reject",t,r),send:U,status:D,streamingText:F}};export{nt as createAgentChat};
@@ -1 +1 @@
1
- import{createMemo as o}from"solid-js";import{resolveMaybe as n}from"./createAgent-hhL-sw_X.mjs";import{createSubscription as c}from"./createSubscription-1glD6fxF.mjs";const p=e=>{const{data:t,error:r}=c(e.api.agents.agentState,()=>({key:n(e.threadKey)})),a=o(()=>t());return{error:r,state:a}};export{p as createAgentState};
1
+ import{createMemo as o}from"solid-js";import{resolveMaybe as n}from"./createAgent-DuksX_2d.mjs";import{createSubscription as c}from"./createSubscription-CsrywUOa.mjs";const p=e=>{const{data:t,error:r}=c(e.api.agents.agentState,()=>({key:n(e.threadKey)})),a=o(()=>t());return{error:r,state:a}};export{p as createAgentState};
@@ -1 +1 @@
1
- import{createMemo as v}from"solid-js";import{resolveMaybe as n}from"./createAgent-hhL-sw_X.mjs";import{createStream as f}from"./createStream-Dx7SnivS.mjs";import{createSubscription as y}from"./createSubscription-1glD6fxF.mjs";const C={__lunoraRef:""},I=[],N=t=>{if(t.role==="assistant"&&t.toolCalls)return t.toolCalls.map(r=>({input:r.input,seq:t.seq,toolCallId:r.id,toolName:r.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}}]},_=t=>{const{api:r,limit:a,stream:i,threadKey:e}=t,u=()=>{const l=n(e);return a===void 0?{key:l}:{key:l,limit:a}},{data:p}=y(r.agents.agentMessages,u),s=i===void 0?"skip":()=>({key:n(e)}),{chunks:c}=f(i??C,s);return{events:v(()=>{const l=n(e),d=(p()??I).flatMap(o=>N(o)??[]);for(const o of c())o.kind==="progress"&&o.threadKey===l&&d.push({data:o.data,toolCallId:o.toolCallId,type:"progress"});return d})}};export{_ as createAgentToolEvents};
1
+ import{createMemo as v}from"solid-js";import{resolveMaybe as n}from"./createAgent-DuksX_2d.mjs";import{createStream as f}from"./createStream-Dx7SnivS.mjs";import{createSubscription as y}from"./createSubscription-CsrywUOa.mjs";const C={__lunoraRef:""},I=[],N=t=>{if(t.role==="assistant"&&t.toolCalls)return t.toolCalls.map(r=>({input:r.input,seq:t.seq,toolCallId:r.id,toolName:r.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}}]},_=t=>{const{api:r,limit:a,stream:i,threadKey:e}=t,u=()=>{const l=n(e);return a===void 0?{key:l}:{key:l,limit:a}},{data:p}=y(r.agents.agentMessages,u),s=i===void 0?"skip":()=>({key:n(e)}),{chunks:c}=f(i??C,s);return{events:v(()=>{const l=n(e),d=(p()??I).flatMap(o=>N(o)??[]);for(const o of c())o.kind==="progress"&&o.threadKey===l&&d.push({data:o.data,toolCallId:o.toolCallId,type:"progress"});return d})}};export{_ as createAgentToolEvents};
@@ -1 +1 @@
1
- import{createSignal as u}from"solid-js";import{useLunora as a}from"./LunoraContext-dPcjtn6R.mjs";import{resolveMaybe as b}from"./createAgent-hhL-sw_X.mjs";import{t as d,o as m}from"./solid-compat-ByG5HD_F.mjs";const _="__lunora_flags__:eval",p=t=>{const e=typeof t;return e==="boolean"||e==="number"||e==="string"?e:"object"},y={__lunoraRef:_},f=(t,e,r)=>{try{return t.subscribe(y,{default:e.default,key:e.key,type:p(e.default)},o=>{r(o)},{onError:()=>{r(e.default)}})}catch{return()=>{}}},A=(t,e)=>{const r=a(),[o,s]=u(e);return d(()=>b(t),n=>(s(()=>e),f(r,{default:e,key:n},c=>{s(()=>c)}))),o},E=t=>{const e=a(),[r,o]=u(t);return m(()=>{const s=[];for(const[n,c]of Object.entries(t))s.push(f(e,{default:c,key:n},l=>{o(i=>({...i,[n]:l}))}));return()=>{for(const n of s)n()}}),r};export{A as createFlag,E as createFlags};
1
+ import{createSignal as u}from"solid-js";import{useLunora as a}from"./LunoraContext-dPcjtn6R.mjs";import{resolveMaybe as b}from"./createAgent-DuksX_2d.mjs";import{t as d,o as m}from"./solid-compat-ByG5HD_F.mjs";const _="__lunora_flags__:eval",p=t=>{const e=typeof t;return e==="boolean"||e==="number"||e==="string"?e:"object"},y={__lunoraRef:_},f=(t,e,r)=>{try{return t.subscribe(y,{default:e.default,key:e.key,type:p(e.default)},o=>{r(o)},{onError:()=>{r(e.default)}})}catch{return()=>{}}},A=(t,e)=>{const r=a(),[o,s]=u(e);return d(()=>b(t),n=>(s(()=>e),f(r,{default:e,key:n},c=>{s(()=>c)}))),o},E=t=>{const e=a(),[r,o]=u(t);return m(()=>{const s=[];for(const[n,c]of Object.entries(t))s.push(f(e,{default:c,key:n},l=>{o(i=>({...i,[n]:l}))}));return()=>{for(const n of s)n()}}),r};export{A as createFlag,E as createFlags};
@@ -0,0 +1 @@
1
+ import{initialPages as U,derivePaginationStatus as J,applyLoadMore as Y,rebalance as Z}from"@lunora/client/pagination";import{createMemo as h,createSignal as I}from"solid-js";import{useLunora as v}from"./LunoraContext-dPcjtn6R.mjs";import{t as W}from"./solid-compat-ByG5HD_F.mjs";const ee=/["\\\u0000-\u001F\uD800-\uDFFF]/,q=e=>ee.test(e)?JSON.stringify(e):`"${e}"`,C=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 q(e);if(e===null||typeof e!="object")return JSON.stringify(e);if(Array.isArray(e)){let r="[";for(let o=0;o<e.length;o++)o>0&&(r+=","),r+=C(e[o]);return r+"]"}const n=Object.getPrototypeOf(e);if(n!==null&&n!==Object.prototype){const r=e.constructor?.name??"value";throw new TypeError(`stableStringify: cannot use a ${r} in a stable JSON cache key — only plain objects, arrays, and JSON primitives are supported (wire-typed values key via stableWireKey)`)}const d=e,y=Object.keys(d).sort();let u="{",t=!0;for(const r of y){const o=d[r];o!==void 0&&(t?t=!1:u+=",",u+=q(r),u+=":",u+=C(o))}return u+"}"},T=e=>{let n="";for(let y=0;y<e.length;y+=32768)n+=String.fromCharCode(...e.subarray(y,y+32768));return btoa(n)},l="$lunora.wire$",Q=64,z="__proto__",te=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>Q)throw new RangeError(`wire-codec: value nesting exceeds the ${Q}-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,r={};for(const i of Object.keys(t)){if(t[i]===void 0)continue;const b=S(t[i],n+1);i===z?Object.defineProperty(r,i,{configurable:!0,enumerable:!0,value:b,writable:!0}):r[i]=b}const o=[l,"error",t.name,t.message,r];return t.cause!==void 0&&o.push(S(t.cause,n+1)),o}if(e instanceof URL)return[l,"url",e.href];if(e instanceof Map)return[l,"map",[...e.entries()].map(([t,r])=>[S(t,n+1),S(r,n+1)])];if(e instanceof Set)return[l,"set",[...e].map(t=>S(t,n+1))];if(e instanceof ArrayBuffer)return[l,"bytes",T(new Uint8Array(e)),"ArrayBuffer"];if(ArrayBuffer.isView(e)){const t=e,r=t.constructor.name,o=new Uint8Array(t.buffer,t.byteOffset,t.byteLength);return r==="Uint8Array"?[l,"bytes",T(o)]:[l,"bytes",T(o),r]}if(Array.isArray(e)){const t=e.map(r=>S(r,n+1));return t.length>0&&t[0]===l?[l,"arr",t]:t}if(!te(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 y=e,u={};for(const t of Object.keys(y)){const r=y[t];if(r===void 0)continue;const o=S(r,n+1);t===z?Object.defineProperty(u,t,{configurable:!0,enumerable:!0,value:o,writable:!0}):u[t]=o}return u},ne=e=>C(S(e)),A=(e,n)=>({...n,paginationOpts:{cursor:e.lower,endCursor:e.upper,numItems:e.numItems}}),R=(e,n)=>`${e}::${ne(n)}`,G=(e,n,d)=>{const y=v(),{initialNumItems:u,onError:t,shardKey:r}=d,o=()=>typeof n=="function"?n():n,[i,b]=I(U(u)),p=new Map,[E,L]=I([]),[$,P]=I(void 0),M=new Map,j=new Set,_=(s,f)=>{const w=s.map(c=>{const a=R(e.__lunoraRef,A(c,f));return p.get(a)});L(w)},H=(s,f,w)=>{const c=a=>R(e.__lunoraRef,A(a,w));for(const a of f){const g=c(a);if(p.has(g))continue;const N=s.find(m=>m.lower===a.lower);if(N){const m=p.get(c(N));m&&p.set(g,m)}}},V=(s,f)=>{const w=new Set;for(const c of s)w.add(R(e.__lunoraRef,A(c,f)));for(const[c,a]of M)w.has(c)||(a(),M.delete(c),j.delete(c),p.delete(c));for(const c of s){const a=A(c,f),g=R(e.__lunoraRef,a);if(M.has(g))continue;j.add(g);const N=y.subscribe(e,a,m=>{p.set(g,m),j.delete(g),P(void 0);const k=o();if(k!=="skip"&&(_(i(),k),j.size===0)){const O=i(),F=Z(O,E());F&&(H(O,F,k),b(F))}},{onError:m=>{j.delete(g),P(m);const k=i(),O=k.at(-1);k.length>1&&O&&!p.has(g)&&R(e.__lunoraRef,A(O,f))===g&&b(k.slice(0,-1)),t?.(m)},shardKey:r});M.set(g,N)}};let K=!1,x=!1;const B=(s,f)=>{if(K){x=!0;return}K=!0;try{let w=s,c=f;do{x=!1,V(w,c);const a=o();if(a==="skip")break;w=i(),c=a}while(x)}finally{K=!1}},D=()=>{for(const s of M.values())s();M.clear(),p.clear(),j.clear()};W(o,s=>(D(),b(U(u)),L([]),P(void 0),s!=="skip"&&(B(i(),s),_(i(),s)),D)),W(i,s=>{const f=o();f!=="skip"&&(B(s,f),_(s,f))});const X=h(()=>{const s=o()==="skip";return J(s,E()).status});return{error:$,loadMore:s=>{const f=o();if(f==="skip")return;const{nextCursor:w,status:c}=J(!1,E());if(c!=="CanLoadMore")return;const a=Y(i(),w,s);if(!a)return;const g=i().at(-1),N=a.at(-2);if(g&&N){const m=R(e.__lunoraRef,A(g,f)),k=R(e.__lunoraRef,A(N,f));if(m!==k){const O=p.get(m);O&&p.set(k,O)}}P(void 0),b(a)},pageResults:E,status:X}},ae=(e,n,d)=>{const{error:y,loadMore:u,pageResults:t,status:r}=G(e,n,d),o=h(()=>t().flatMap(p=>p?.page??[])),i=h(()=>(typeof n=="function"?n():n)==="skip"),b=h(()=>!i()&&(r()==="LoadingFirstPage"||r()==="LoadingMore"));return{error:y,isLoading:b,loadMore:u,results:o,status:r}},fe=(e,n,d)=>{const{initialNumItems:y}=d,{error:u,loadMore:t,pageResults:r,status:o}=G(e,n,d),i=h(()=>r().flatMap(P=>P?[P.page]:[])),b=h(()=>(typeof n=="function"?n():n)==="skip"),p=h(()=>!b()&&o()==="LoadingFirstPage"),E=h(()=>o()==="CanLoadMore"),L=h(()=>!b()&&o()==="LoadingMore");return{error:u,fetchNextPage:P=>{t(P??y)},hasNextPage:E,isFetchingNextPage:L,isLoading:p,pages:i,status:o}};export{fe as createInfiniteQuery,ae as createPaginatedQuery};
@@ -0,0 +1 @@
1
+ import{createSignal as f}from"solid-js";import{useLunora as E}from"./LunoraContext-dPcjtn6R.mjs";import{o as S}from"./solid-compat-ByG5HD_F.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("")}}throw new Error("randomSessionId: no Web Crypto available — a session id needs crypto.randomUUID or crypto.getRandomValues")},D=1e4,A=(t,e)=>{const s=E(),{heartbeat:l,intervalMs:m=D,listPresent:y,shardKey:i}=e,a=e.sessionId??h(),[v,p]=f(void 0),[b,d]=f(void 0);let c=e.data;const o=()=>{const n={roomId:t,sessionId:a,...c===void 0?{}:{data:c}};s.mutation(l,n,{shardKey:i}).catch(()=>{})},g=n=>{c=n,o()};return S(()=>{o();const n=setInterval(o,m),u=()=>{typeof document<"u"&&document.visibilityState==="visible"&&o()};typeof document<"u"&&document.addEventListener("visibilitychange",u);const I=s.acquireConnectionContext({roomId:t,sessionId:a},{shardKey:i}),U=s.subscribe(y,{roomId:t},r=>{p(()=>r),d(void 0)},{onError:r=>{d(r),e.onError?.(r)},shardKey:i});return()=>{clearInterval(n),typeof document<"u"&&document.removeEventListener("visibilitychange",u),I(),U()}}),{error:b,present:v,sessionId:a,setData:g}};export{A as createPresence};
@@ -0,0 +1 @@
1
+ import{createQuerySubscription as v}from"@lunora/client/query";import{LunoraError as l}from"@lunora/errors";import{createSignal as d}from"solid-js";import{useLunora as p}from"./LunoraContext-dPcjtn6R.mjs";import{t as u}from"./solid-compat-ByG5HD_F.mjs";const D=(i,r,n={})=>{const m=p(),[c,e]=d(void 0),[s,t]=d(void 0);return u(typeof r=="function"?r:()=>r,a=>{if(e(()=>{}),t(()=>{}),a!=="skip")return v(m,i,a,{onData:o=>{e(()=>o),t(()=>{})},onError:o=>{const f=o.code?new l(o.code,o.message):new Error(o.message);t(()=>f),e(()=>{}),n.onError?.(o)},onReset:()=>{e(()=>{})}},{shardKey:n.shardKey})}),{data:c,error:s}};export{D as createSubscription};
@@ -1 +1 @@
1
- import{createSignal as y,onCleanup as J}from"solid-js";import{useLunora as G}from"./LunoraContext-dPcjtn6R.mjs";import{resolveMaybe as X}from"./createAgent-hhL-sw_X.mjs";const D="/_lunora/ws",j="/_lunora/voice/",z=4001,F=e=>e.startsWith("https://")?`wss://${e.slice(8)}`:e.startsWith("http://")?`ws://${e.slice(7)}`:e,Q=e=>{const r=e.startsWith("agents:")?e.slice(7):e;return r.endsWith("Voice")?r.slice(0,-5):r},Y=(e,r)=>{if(r===void 0||r==="")return F(e);if(r.endsWith(D))return r.slice(0,-D.length);try{return new URL(r).origin}catch{return F(e)}},Z=e=>{const r=Y(e.httpUrl,e.wsUrl),s=r.endsWith("/")?r.slice(0,-1):r,i=new URLSearchParams({threadKey:e.threadKey});return`${s}${j}${encodeURIComponent(e.agent)}?${i.toString()}`},ee=(e,r)=>{if(r?.code===z)return new Error(`${e}: authentication token expired — refresh the credential and start a new call`)},te=(e,r,s)=>{const i=e.currentIdentity();return e.onAuthTokenChange(()=>{e.currentIdentity()!==i&&s(new Error(`${r}: the signed-in identity changed during the call — the session was ended; start a new call`))})},ne=16e3,re=e=>{if(e.length===0)return 0;let r=0;for(const s of e)r+=s*s;return Math.sqrt(r/e.length)},oe=(e,r)=>{const s=r/ne,i=s>1?Math.floor(e.length/s):e.length,f=new ArrayBuffer(i*2),l=new DataView(f);for(let u=0;u<i;u+=1){const k=e[Math.floor(u*s)]??0,g=Math.max(-1,Math.min(1,k));l.setInt16(u*2,g<0?g*32768:g*32767,!0)}return new Uint8Array(f)},se=async e=>{const r=globalThis,s=r.navigator?.mediaDevices?.getUserMedia.bind(r.navigator.mediaDevices),i=r.AudioContext??r.webkitAudioContext;if(!s||!i)throw new Error("createVoiceAgent: microphone capture requires getUserMedia + AudioContext (no browser audio available)");const f=await s({audio:{channelCount:1,echoCancellation:!0,noiseSuppression:!0}}),l=new i,u=l.createMediaStreamSource(f),k=l.createScriptProcessor(4096,1,1);let g=!1,w=!1,c=0,p=0;return k.onaudioprocess=o=>{const h=o.inputBuffer.getChannelData(0),m=g?0:re(h);if(e.onLevel(m),g)return;if(e.onAudio(oe(h,l.sampleRate)),e.isTurnActive()){p=m>=e.interruptThreshold?p+1:0,p>=e.interruptChunks&&(p=0,e.onInterrupt());return}p=0;const b=h.length/l.sampleRate*1e3;if(m>=e.silenceThreshold){w=!0,c=0;return}w&&(c+=b,c>=e.silenceDurationMs&&(w=!1,c=0,e.onSilence()))},u.connect(k),k.connect(l.destination),{setMuted:o=>{g=o},stop:()=>{k.disconnect(),u.disconnect();for(const o of f.getTracks())o.stop();l.close()}}},ae=()=>{const e=globalThis,r=e.AudioContext??e.webkitAudioContext;if(!r)throw new Error("createVoiceAgent: audio playback requires AudioContext (no browser audio available)");const s=new r,i=new Set;let f=0,l=Promise.resolve(),u=0;const k=async(c,p)=>{if(p!==u)return;let o;try{o=await s.decodeAudioData(c.buffer)}catch{return}if(p!==u)return;const h=s.createBufferSource();h.buffer=o,h.connect(s.destination);const m=Math.max(s.currentTime,f);h.start(m),f=m+o.duration,i.add(h),h.onended=()=>{i.delete(h)}},g=c=>{const p=Uint8Array.from(c),o=u;l=l.then(()=>k(p,o))},w=()=>{u+=1;for(const c of i)try{c.stop()}catch{}i.clear(),f=s.currentTime};return{enqueue:g,interrupt:w,stop:()=>{w(),s.close()}}},V=1,ie=.01,ce=1200,ue=.15,le=3,fe=e=>{const{createMicrophone:r=se,createSpeaker:s=ae,createSocket:i,interruptChunks:f=le,interruptThreshold:l=ue,silenceDurationMs:u=ce,silenceThreshold:k=ie,threadKey:g,voice:w}=e,c=G(),[p,o]=y("idle"),[h,m]=y(!1),[b,M]=y(""),[W,v]=y(""),[N,x]=y(0),[I,U]=y(!1),[O,S]=y(void 0);let a,C=!1;const _=t=>{const n=a?.socket;return n?.readyState===V?(n.send(JSON.stringify(t)),!0):!1},T=()=>{const t=a;if(a=void 0,t){t.unwatchIdentity?.(),t.microphone?.stop(),t.speaker?.stop(),t.socket.onmessage=null,t.socket.onerror=null,t.socket.onclose=null;try{t.socket.close()}catch{}}C=!1,m(!1),o("idle"),x(0)},P=T,H=t=>{const n=a;switch(t.type){case"assistant_delta":{n&&(n.speaking=!0),o("speaking"),v(R=>R+t.text);break}case"assistant_done":{n&&(n.awaitingTurn=!1,n.speaking=!1),v(t.text),o("listening");break}case"error":{n&&(n.awaitingTurn=!1,n.speaking=!1),S(new Error(t.message)),o("listening");break}case"interrupted":{n&&(n.awaitingTurn=!1,n.speaking=!1,n.suppressAudio=!1),n?.speaker?.interrupt(),o("listening");break}case"ready":{n&&(n.audioFormat=t.audioFormat,n.suppressAudio=!1),m(!0),o("listening");break}case"user_transcript":{n&&(n.suppressAudio=!1),M(t.text),v(""),o("thinking");break}}},$=t=>{const n=a;!n||n.suppressAudio||(n.speaker??=s({audioFormat:n.audioFormat}),n.speaking=!0,o("speaking"),n.speaker.enqueue(t))},B=async()=>{if(a||C)return;C=!0,S(void 0),M(""),v("");let t;try{const n=Z({agent:Q(w.__lunoraRef),httpUrl:c.url,threadKey:X(g),wsUrl:c.wsUrl}),A=(i??(d=>{const E=c.getWebSocketImpl();if(!E)throw new Error("createVoiceAgent: no WebSocket implementation available (pass createSocket explicitly)");return new E(d)}))(n);A.binaryType="arraybuffer",t={audioFormat:"mp3",microphone:void 0,socket:A,speaker:void 0,speaking:!1,awaitingTurn:!1,suppressAudio:!1,unwatchIdentity:void 0},a=t,t.unwatchIdentity=te(c,"createVoiceAgent",d=>{a===t&&(S(d),T())}),A.onmessage=d=>{if(typeof d.data=="string"){try{H(JSON.parse(d.data))}catch{}return}$(new Uint8Array(d.data))},A.onerror=()=>{S(new Error("createVoiceAgent: voice socket error"))},A.onclose=d=>{if(a!==t)return;const E=ee("createVoiceAgent",d);E&&S(E),T()};const L=await r({interruptChunks:f,interruptThreshold:l,isTurnActive:()=>(a?.speaking??!1)||(a?.awaitingTurn??!1),onAudio:d=>{A.readyState===V&&A.send(d)},onInterrupt:()=>{_({type:"interrupt"}),a?.speaker?.interrupt(),a&&(a.awaitingTurn=!1,a.speaking=!1,a.suppressAudio=!0),o("listening")},onLevel:d=>{x(d)},onSilence:()=>{_({type:"commit"}),a&&(a.awaitingTurn=!0),o("thinking")},silenceDurationMs:u,silenceThreshold:k});a===t?(t.microphone=L,U(!1),t.speaking||o("listening")):L.stop()}catch(n){a===t&&(S(n instanceof Error?n:new Error(String(n))),T())}finally{C=!1}},K=()=>{const t=!I();return a?.microphone?.setMuted(t),U(t),t},q=t=>{_({text:t,type:"text"})&&(a&&(a.awaitingTurn=!0),o("thinking"))};return J(T),{audioLevel:N,connected:h,endCall:P,error:O,interimTranscript:W,isMuted:I,sendText:q,startCall:B,status:p,toggleMute:K,transcript:b}};export{fe as createVoiceAgent};
1
+ import{createSignal as y,onCleanup as J}from"solid-js";import{useLunora as G}from"./LunoraContext-dPcjtn6R.mjs";import{resolveMaybe as X}from"./createAgent-DuksX_2d.mjs";const D="/_lunora/ws",j="/_lunora/voice/",z=4001,F=e=>e.startsWith("https://")?`wss://${e.slice(8)}`:e.startsWith("http://")?`ws://${e.slice(7)}`:e,Q=e=>{const r=e.startsWith("agents:")?e.slice(7):e;return r.endsWith("Voice")?r.slice(0,-5):r},Y=(e,r)=>{if(r===void 0||r==="")return F(e);if(r.endsWith(D))return r.slice(0,-D.length);try{return new URL(r).origin}catch{return F(e)}},Z=e=>{const r=Y(e.httpUrl,e.wsUrl),s=r.endsWith("/")?r.slice(0,-1):r,i=new URLSearchParams({threadKey:e.threadKey});return`${s}${j}${encodeURIComponent(e.agent)}?${i.toString()}`},ee=(e,r)=>{if(r?.code===z)return new Error(`${e}: authentication token expired — refresh the credential and start a new call`)},te=(e,r,s)=>{const i=e.currentIdentity();return e.onAuthTokenChange(()=>{e.currentIdentity()!==i&&s(new Error(`${r}: the signed-in identity changed during the call — the session was ended; start a new call`))})},ne=16e3,re=e=>{if(e.length===0)return 0;let r=0;for(const s of e)r+=s*s;return Math.sqrt(r/e.length)},oe=(e,r)=>{const s=r/ne,i=s>1?Math.floor(e.length/s):e.length,f=new ArrayBuffer(i*2),l=new DataView(f);for(let u=0;u<i;u+=1){const k=e[Math.floor(u*s)]??0,g=Math.max(-1,Math.min(1,k));l.setInt16(u*2,g<0?g*32768:g*32767,!0)}return new Uint8Array(f)},se=async e=>{const r=globalThis,s=r.navigator?.mediaDevices?.getUserMedia.bind(r.navigator.mediaDevices),i=r.AudioContext??r.webkitAudioContext;if(!s||!i)throw new Error("createVoiceAgent: microphone capture requires getUserMedia + AudioContext (no browser audio available)");const f=await s({audio:{channelCount:1,echoCancellation:!0,noiseSuppression:!0}}),l=new i,u=l.createMediaStreamSource(f),k=l.createScriptProcessor(4096,1,1);let g=!1,w=!1,c=0,p=0;return k.onaudioprocess=o=>{const h=o.inputBuffer.getChannelData(0),m=g?0:re(h);if(e.onLevel(m),g)return;if(e.onAudio(oe(h,l.sampleRate)),e.isTurnActive()){p=m>=e.interruptThreshold?p+1:0,p>=e.interruptChunks&&(p=0,e.onInterrupt());return}p=0;const b=h.length/l.sampleRate*1e3;if(m>=e.silenceThreshold){w=!0,c=0;return}w&&(c+=b,c>=e.silenceDurationMs&&(w=!1,c=0,e.onSilence()))},u.connect(k),k.connect(l.destination),{setMuted:o=>{g=o},stop:()=>{k.disconnect(),u.disconnect();for(const o of f.getTracks())o.stop();l.close()}}},ae=()=>{const e=globalThis,r=e.AudioContext??e.webkitAudioContext;if(!r)throw new Error("createVoiceAgent: audio playback requires AudioContext (no browser audio available)");const s=new r,i=new Set;let f=0,l=Promise.resolve(),u=0;const k=async(c,p)=>{if(p!==u)return;let o;try{o=await s.decodeAudioData(c.buffer)}catch{return}if(p!==u)return;const h=s.createBufferSource();h.buffer=o,h.connect(s.destination);const m=Math.max(s.currentTime,f);h.start(m),f=m+o.duration,i.add(h),h.onended=()=>{i.delete(h)}},g=c=>{const p=Uint8Array.from(c),o=u;l=l.then(()=>k(p,o))},w=()=>{u+=1;for(const c of i)try{c.stop()}catch{}i.clear(),f=s.currentTime};return{enqueue:g,interrupt:w,stop:()=>{w(),s.close()}}},V=1,ie=.01,ce=1200,ue=.15,le=3,fe=e=>{const{createMicrophone:r=se,createSpeaker:s=ae,createSocket:i,interruptChunks:f=le,interruptThreshold:l=ue,silenceDurationMs:u=ce,silenceThreshold:k=ie,threadKey:g,voice:w}=e,c=G(),[p,o]=y("idle"),[h,m]=y(!1),[b,M]=y(""),[W,v]=y(""),[N,x]=y(0),[I,U]=y(!1),[O,S]=y(void 0);let a,C=!1;const _=t=>{const n=a?.socket;return n?.readyState===V?(n.send(JSON.stringify(t)),!0):!1},T=()=>{const t=a;if(a=void 0,t){t.unwatchIdentity?.(),t.microphone?.stop(),t.speaker?.stop(),t.socket.onmessage=null,t.socket.onerror=null,t.socket.onclose=null;try{t.socket.close()}catch{}}C=!1,m(!1),o("idle"),x(0)},P=T,H=t=>{const n=a;switch(t.type){case"assistant_delta":{n&&(n.speaking=!0),o("speaking"),v(R=>R+t.text);break}case"assistant_done":{n&&(n.awaitingTurn=!1,n.speaking=!1),v(t.text),o("listening");break}case"error":{n&&(n.awaitingTurn=!1,n.speaking=!1),S(new Error(t.message)),o("listening");break}case"interrupted":{n&&(n.awaitingTurn=!1,n.speaking=!1,n.suppressAudio=!1),n?.speaker?.interrupt(),o("listening");break}case"ready":{n&&(n.audioFormat=t.audioFormat,n.suppressAudio=!1),m(!0),o("listening");break}case"user_transcript":{n&&(n.suppressAudio=!1),M(t.text),v(""),o("thinking");break}}},$=t=>{const n=a;!n||n.suppressAudio||(n.speaker??=s({audioFormat:n.audioFormat}),n.speaking=!0,o("speaking"),n.speaker.enqueue(t))},B=async()=>{if(a||C)return;C=!0,S(void 0),M(""),v("");let t;try{const n=Z({agent:Q(w.__lunoraRef),httpUrl:c.url,threadKey:X(g),wsUrl:c.wsUrl}),A=(i??(d=>{const E=c.getWebSocketImpl();if(!E)throw new Error("createVoiceAgent: no WebSocket implementation available (pass createSocket explicitly)");return new E(d)}))(n);A.binaryType="arraybuffer",t={audioFormat:"mp3",microphone:void 0,socket:A,speaker:void 0,speaking:!1,awaitingTurn:!1,suppressAudio:!1,unwatchIdentity:void 0},a=t,t.unwatchIdentity=te(c,"createVoiceAgent",d=>{a===t&&(S(d),T())}),A.onmessage=d=>{if(typeof d.data=="string"){try{H(JSON.parse(d.data))}catch{}return}$(new Uint8Array(d.data))},A.onerror=()=>{S(new Error("createVoiceAgent: voice socket error"))},A.onclose=d=>{if(a!==t)return;const E=ee("createVoiceAgent",d);E&&S(E),T()};const L=await r({interruptChunks:f,interruptThreshold:l,isTurnActive:()=>(a?.speaking??!1)||(a?.awaitingTurn??!1),onAudio:d=>{A.readyState===V&&A.send(d)},onInterrupt:()=>{_({type:"interrupt"}),a?.speaker?.interrupt(),a&&(a.awaitingTurn=!1,a.speaking=!1,a.suppressAudio=!0),o("listening")},onLevel:d=>{x(d)},onSilence:()=>{_({type:"commit"}),a&&(a.awaitingTurn=!0),o("thinking")},silenceDurationMs:u,silenceThreshold:k});a===t?(t.microphone=L,U(!1),t.speaking||o("listening")):L.stop()}catch(n){a===t&&(S(n instanceof Error?n:new Error(String(n))),T())}finally{C=!1}},K=()=>{const t=!I();return a?.microphone?.setMuted(t),U(t),t},q=t=>{_({text:t,type:"text"})&&(a&&(a.awaitingTurn=!0),o("thinking"))};return J(T),{audioLevel:N,connected:h,endCall:P,error:O,interimTranscript:W,isMuted:I,sendText:q,startCall:B,status:p,toggleMute:K,transcript:b}};export{fe as createVoiceAgent};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lunora/solid",
3
- "version": "1.0.0-alpha.82",
3
+ "version": "1.0.0-alpha.84",
4
4
  "description": "SolidJS adapter for Lunora — live queries, optimistic mutations, and reactive loaders",
5
5
  "keywords": [
6
6
  "cloudflare",
@@ -54,7 +54,7 @@
54
54
  "access": "public"
55
55
  },
56
56
  "dependencies": {
57
- "@lunora/client": "1.0.0-alpha.79",
57
+ "@lunora/client": "1.0.0-alpha.80",
58
58
  "@lunora/errors": "1.0.0-alpha.32",
59
59
  "@lunora/ratelimit": "1.0.0-alpha.39",
60
60
  "@visulima/storage-client": "1.0.2"
@@ -1 +0,0 @@
1
- import{createMemo as s}from"solid-js";import{createMutation as i}from"./createMutation-DcSsIbGF.mjs";import{createSubscription as M}from"./createSubscription-1glD6fxF.mjs";const l={__lunoraRef:""},c=t=>typeof t=="function"?t():t,K=t=>{const{api:u,cancel:r,run:d,runArgs:f,threadKey:n}=t,o=i(d),m=i(r??l),{data:p}=M(u.agents.agentThread,()=>({key:c(n)})),a=s(()=>p()),y=s(()=>a()?.status),g=async(e,h)=>{await o.mutate({input:e,threadKey:c(n),...f,...h})};return{cancel:async()=>{const e=a()?.instanceId;r===void 0||e===void 0||await m.mutate({instanceId:e,threadKey:c(n)})},pending:o.pending,run:g,status:y,thread:a}};export{l as NO_MUTATION_REF,K as createAgent,c as resolveMaybe};
@@ -1 +0,0 @@
1
- import{reconcileOptimistic as A,maxSeq as M}from"@lunora/client";import{createSignal as F,createMemo as c}from"solid-js";import{resolveMaybe as a,NO_MUTATION_REF as U}from"./createAgent-hhL-sw_X.mjs";import{createMutation as p}from"./createMutation-DcSsIbGF.mjs";import{createStream as $}from"./createStream-Dx7SnivS.mjs";import{createSubscription as k}from"./createSubscription-1glD6fxF.mjs";import{t as z}from"./solid-compat-ByG5HD_F.mjs";const B={__lunoraRef:""},Z=R=>{const{api:m,cancel:u,limit:f,send:S,sendArgs:w,stream:h,threadKey:r}=R,{data:x}=k(m.agents.agentMessages,()=>{const t=a(r);return f===void 0?{key:t}:{key:t,limit:f}}),{data:I}=k(m.agents.agentThread,()=>({key:a(r)})),b=h===void 0?"skip":()=>({key:a(r)}),{chunks:_}=$(h??B,b),E=p(S),K=p(u??U),O=p(m.agents.agentResolveApproval),[g,d]=F([]);let y=0;z(()=>a(r),()=>{g().length>0&&d([])});const l=c(()=>I()),T=c(()=>l()?.status),i=c(()=>x()??[]),j=c(()=>{const t=i(),n=A(g(),t);if(n.length===0)return t;const e=M(t);return[...t,...n.map((s,o)=>({content:s.content,optimistic:!0,role:"user",seq:e+1+o}))]}),q=c(()=>{const t=a(r),n=i().filter(e=>e.role==="assistant").length;return _().filter(e=>e.kind!=="progress"&&e.threadKey===t&&e.turn>=n).map(e=>e.text).join("")}),C=async(t,n)=>{const e=y;y+=1;const s=M(i());d(o=>[...A(o,i()),{content:t,id:e,maxDurableSeqAtSend:s}]);try{await E.mutate({input:t,threadKey:a(r),...w,...n})}catch(o){throw d(D=>D.filter(N=>N.id!==e)),o}},v=async(t,n,e)=>{const s=l()?.instanceId;if(s===void 0)throw new Error(`createAgentChat: cannot ${t} — no in-flight run (thread has no instanceId)`);await O.mutate({decision:t,instanceId:s,threadKey:a(r),toolCallId:n,...e===void 0?{}:{note:e}})};return{approve:async(t,n)=>v("approve",t,n),cancel:async()=>{const t=l()?.instanceId;u===void 0||t===void 0||await K.mutate({instanceId:t,threadKey:a(r)})},messages:j,reject:async(t,n)=>v("reject",t,n),send:C,status:T,streamingText:q}};export{Z as createAgentChat};
@@ -1 +0,0 @@
1
- import{initialPages as U,derivePaginationStatus as J,applyLoadMore as Y,rebalance as Z}from"@lunora/client/pagination";import{createMemo as A,createSignal as T}from"solid-js";import{useLunora as v}from"./LunoraContext-dPcjtn6R.mjs";import{t as W}from"./solid-compat-ByG5HD_F.mjs";const ee=/["\\\u0000-\u001F\uD800-\uDFFF]/,q=e=>ee.test(e)?JSON.stringify(e):`"${e}"`,$=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 q(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+=$(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 d=e,y=Object.keys(d).sort();let u="{",t=!0;for(const n of y){const o=d[n];o!==void 0&&(t?t=!1:u+=",",u+=q(n),u+=":",u+=$(o))}return u+"}"},C=e=>{let r="";for(let y=0;y<e.length;y+=32768)r+=String.fromCharCode(...e.subarray(y,y+32768));return btoa(r)},l="$lunora.wire$",Q=64,z="__proto__",te=e=>{if(e===null||typeof e!="object")return!1;const r=Object.getPrototypeOf(e);return r===null||r===Object.prototype},P=(e,r=0)=>{if(r>Q)throw new RangeError(`wire-codec: value nesting exceeds the ${Q}-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",P(e.getTime(),r+1)];if(e instanceof Error){const t=e,n={};for(const i of Object.keys(t)){if(t[i]===void 0)continue;const m=P(t[i],r+1);i===z?Object.defineProperty(n,i,{configurable:!0,enumerable:!0,value:m,writable:!0}):n[i]=m}const o=[l,"error",t.name,t.message,n];return t.cause!==void 0&&o.push(P(t.cause,r+1)),o}if(e instanceof URL)return[l,"url",e.href];if(e instanceof Map)return[l,"map",[...e.entries()].map(([t,n])=>[P(t,r+1),P(n,r+1)])];if(e instanceof Set)return[l,"set",[...e].map(t=>P(t,r+1))];if(e instanceof ArrayBuffer)return[l,"bytes",C(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"?[l,"bytes",C(o)]:[l,"bytes",C(o),n]}if(Array.isArray(e)){const t=e.map(n=>P(n,r+1));return t.length>0&&t[0]===l?[l,"arr",t]:t}if(!te(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 y=e,u={};for(const t of Object.keys(y)){const n=y[t];if(n===void 0)continue;const o=P(n,r+1);t===z?Object.defineProperty(u,t,{configurable:!0,enumerable:!0,value:o,writable:!0}):u[t]=o}return u},re=e=>$(P(e)),O=(e,r)=>({...r,paginationOpts:{cursor:e.lower,endCursor:e.upper,numItems:e.numItems}}),N=(e,r)=>`${e}::${re(r)}`,G=(e,r,d)=>{const y=v(),{initialNumItems:u,onError:t,shardKey:n}=d,o=()=>typeof r=="function"?r():r,[i,m]=T(U(u)),p=new Map,[R,_]=T([]),[E,L]=T(void 0),M=new Map,j=new Set,K=(s,f)=>{const w=s.map(c=>{const a=N(e.__lunoraRef,O(c,f));return p.get(a)});_(w)},H=(s,f,w)=>{const c=a=>N(e.__lunoraRef,O(a,w));for(const a of f){const g=c(a);if(p.has(g))continue;const h=s.find(b=>b.lower===a.lower);if(h){const b=p.get(c(h));b&&p.set(g,b)}}},V=(s,f)=>{const w=new Set;for(const c of s)w.add(N(e.__lunoraRef,O(c,f)));for(const[c,a]of M)w.has(c)||(a(),M.delete(c),j.delete(c),p.delete(c));for(const c of s){const a=O(c,f),g=N(e.__lunoraRef,a);if(M.has(g))continue;j.add(g);const h=y.subscribe(e,a,b=>{p.set(g,b),j.delete(g),L(void 0);const k=o();if(k!=="skip"&&(K(i(),k),j.size===0)){const S=i(),I=Z(S,R());I&&(H(S,I,k),m(I))}},{onError:b=>{j.delete(g),L(b);const k=i(),S=k.at(-1);k.length>1&&S&&!p.has(g)&&N(e.__lunoraRef,O(S,f))===g&&m(k.slice(0,-1)),t?.(b)},shardKey:n});M.set(g,h)}};let x=!1,F=!1;const B=(s,f)=>{if(x){F=!0;return}x=!0;try{let w=s,c=f;do{F=!1,V(w,c);const a=o();if(a==="skip")break;w=i(),c=a}while(F)}finally{x=!1}},D=()=>{for(const s of M.values())s();M.clear(),p.clear(),j.clear()};W(o,s=>(D(),m(U(u)),_([]),L(void 0),s!=="skip"&&(B(i(),s),K(i(),s)),D)),W(i,s=>{const f=o();f!=="skip"&&(B(s,f),K(s,f))});const X=A(()=>{const s=o()==="skip";return J(s,R()).status});return{error:E,loadMore:s=>{const f=o();if(f==="skip")return;const{nextCursor:w,status:c}=J(!1,R());if(c!=="CanLoadMore")return;const a=Y(i(),w,s);if(!a)return;const g=i().at(-1),h=a.at(-2);if(g&&h){const b=N(e.__lunoraRef,O(g,f)),k=N(e.__lunoraRef,O(h,f));if(b!==k){const S=p.get(b);S&&p.set(k,S)}}L(void 0),m(a)},pageResults:R,status:X}},ae=(e,r,d)=>{const{error:y,loadMore:u,pageResults:t,status:n}=G(e,r,d),o=A(()=>t().flatMap(m=>m?.page??[])),i=A(()=>n()==="LoadingFirstPage"||n()==="LoadingMore");return{error:y,isLoading:i,loadMore:u,results:o,status:n}},fe=(e,r,d)=>{const{initialNumItems:y}=d,{error:u,loadMore:t,pageResults:n,status:o}=G(e,r,d),i=A(()=>n().flatMap(E=>E?[E.page]:[])),m=A(()=>o()==="LoadingFirstPage"),p=A(()=>o()==="CanLoadMore"),R=A(()=>o()==="LoadingMore");return{error:u,fetchNextPage:E=>{t(E??y)},hasNextPage:p,isFetchingNextPage:R,isLoading:m,pages:i,status:o}};export{fe as createInfiniteQuery,ae as createPaginatedQuery};
@@ -1 +0,0 @@
1
- import{createSignal as g}from"solid-js";import{useLunora as I}from"./LunoraContext-dPcjtn6R.mjs";import{o as U}from"./solid-compat-ByG5HD_F.mjs";const S=()=>{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")},h=1e4,L=(e,t)=>{const r=I(),{heartbeat:d,intervalMs:u=h,listPresent:f,shardKey:s}=t,i=t.sessionId??S(),[l,m]=g(void 0);let a=t.data;const o=()=>{const n={roomId:e,sessionId:i,...a===void 0?{}:{data:a}};r.mutation(d,n,{shardKey:s}).catch(()=>{})},y=n=>{a=n,o()};return U(()=>{o();const n=setInterval(o,u),c=()=>{typeof document<"u"&&document.visibilityState==="visible"&&o()};typeof document<"u"&&document.addEventListener("visibilitychange",c);const p=r.acquireConnectionContext({roomId:e,sessionId:i},{shardKey:s}),v=r.subscribe(f,{roomId:e},b=>{m(()=>b)},{shardKey:s});return()=>{clearInterval(n),typeof document<"u"&&document.removeEventListener("visibilitychange",c),p(),v()}}),{present:l,sessionId:i,setData:y}};export{L as createPresence};
@@ -1 +0,0 @@
1
- import{createQuerySubscription as v}from"@lunora/client/query";import{LunoraError as p}from"@lunora/errors";import{createSignal as a}from"solid-js";import{useLunora as u}from"./LunoraContext-dPcjtn6R.mjs";import{t as l}from"./solid-compat-ByG5HD_F.mjs";const D=(i,r,d={})=>{const s=u(),[c,e]=a(void 0),[m,t]=a(void 0);return l(typeof r=="function"?r:()=>r,n=>{if(e(()=>{}),t(()=>{}),n!=="skip")return v(s,i,n,{onData:o=>{e(()=>o),t(()=>{})},onError:o=>{const f=o.code?new p(o.code,o.message):new Error(o.message);t(()=>f),e(()=>{})},onReset:()=>{e(()=>{})}},{shardKey:d.shardKey})}),{data:c,error:m}};export{D as createSubscription};