@lunora/angular 1.0.0-alpha.50 → 1.0.0-alpha.52

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
@@ -110,4 +110,21 @@ import { connectionStatus } from "@lunora/angular";
110
110
  readonly status = connectionStatus(); // Signal<"idle" | "connecting" | "connected" | "offline">
111
111
  ```
112
112
 
113
+ ## Agents
114
+
115
+ ```ts
116
+ import { agentToolEvents, voiceAgent } from "@lunora/angular";
117
+
118
+ // One thread's tool lifecycle: call / result / awaiting-approval / progress.
119
+ readonly events = agentToolEvents({ api, threadKey: "t1", stream: api.chat.liveEvents }).events;
120
+
121
+ // A full-duplex voice call against api.agents.<name>Voice.
122
+ readonly call = voiceAgent({ threadKey: "t1", voice: api.agents.supportVoice });
123
+ ```
124
+
125
+ `voiceAgent` opens nothing until `call.startCall()` — that call is what requests
126
+ the microphone, so it must run from a user gesture. `call.endCall()` releases the
127
+ socket, the mic tracks and the Web Audio graph, and the owning `DestroyRef` runs
128
+ it on destroy.
129
+
113
130
  Part of the [Lunora](https://github.com/anolilab/lunora) framework.
package/dist/index.d.mts CHANGED
@@ -625,16 +625,15 @@ interface ConnectionStatusOptions {
625
625
  * @experimental
626
626
  */
627
627
  declare const connectionStatus: (options?: ConnectionStatusOptions) => Signal<ConnectionStatus>;
628
+ /** The value kinds a flag resolves to — OpenFeature's boolean / number / string / structured (JSON) flags. */
629
+ type FlagValue$1 = boolean | number | string | {
630
+ [key: string]: unknown;
631
+ } | unknown[] | null;
628
632
  /**
629
633
  * The value kinds a flag resolves to — OpenFeature's boolean / number / string / structured (JSON) flags.
630
634
  * @experimental
631
635
  */
632
- type FlagValue = boolean | number | string | Record<string, unknown> | unknown[] | null;
633
- /**
634
- * Targeting context bag forwarded to the OpenFeature provider.
635
- * @experimental
636
- */
637
- type FlagContext = Record<string, unknown>;
636
+ type FlagValue = FlagValue$1;
638
637
  /**
639
638
  * `FlagOptions` is part of the experimental `@lunora/angular` API and may change without a major version bump.
640
639
  * @experimental
@@ -642,11 +641,6 @@ type FlagContext = Record<string, unknown>;
642
641
  interface FlagOptions {
643
642
  /** Client to bind to. Defaults to the injected `LUNORA_CLIENT`. */
644
643
  client?: LunoraClient;
645
- /**
646
- * Per-call targeting context merged on top of the app's default `identify`
647
- * targeting key.
648
- */
649
- context?: FlagContext;
650
644
  /** `DestroyRef` whose `onDestroy` tears down the subscription. Defaults to `inject(DestroyRef)`. */
651
645
  destroyRef?: DestroyRef;
652
646
  }
@@ -658,9 +652,16 @@ interface FlagOptions {
658
652
  * The flag's kind is inferred from `defaultValue`'s runtime type, so
659
653
  * `flag("dark", false)` reads a boolean and `flag("hero", "control")` a string.
660
654
  *
655
+ * The reactive channel is public, so the server evaluates every flag under the
656
+ * socket's own verified identity — the targeting key your `defineFlags({
657
+ * identify })` derives — and accepts no client-supplied targeting context. For
658
+ * evaluation under a context you compute, call `ctx.flags.*` inside a query,
659
+ * mutation, or action and return the resolved value.
660
+ *
661
661
  * Evaluation runs through whatever OpenFeature provider the app wired in
662
662
  * `lunora/flags.ts`; the read never throws — a provider error resolves the
663
- * default (the same fail-open contract as server-side `ctx.flags`).
663
+ * default (the same fail-open contract as server-side `ctx.flags`). No
664
+ * subscription opens during SSR; the signal stays at `defaultValue`.
664
665
  *
665
666
  * Call from an injection context:
666
667
  * ```ts
@@ -676,11 +677,6 @@ declare const flag: <T extends FlagValue>(key: string, defaultValue: T, options?
676
677
  interface FlagsOptions {
677
678
  /** Client to bind to. Defaults to the injected `LUNORA_CLIENT`. */
678
679
  client?: LunoraClient;
679
- /**
680
- * Targeting context shared by every flag in the set, merged on top of the
681
- * app's default `identify` targeting key.
682
- */
683
- context?: FlagContext;
684
680
  /** `DestroyRef` whose `onDestroy` tears down the subscriptions. Defaults to `inject(DestroyRef)`. */
685
681
  destroyRef?: DestroyRef;
686
682
  }
@@ -689,7 +685,8 @@ interface FlagsOptions {
689
685
  *
690
686
  * Pass a record of `key → defaultValue`; each flag's kind is inferred from its
691
687
  * default, and the returned signal holds the same-shaped record with resolved
692
- * values (the defaults until each evaluation lands).
688
+ * values (the defaults until each evaluation lands). Like {@link flag} it
689
+ * evaluates under the socket's server-verified identity only.
693
690
  *
694
691
  * Call from an injection context:
695
692
  * ```ts
@@ -1416,7 +1413,7 @@ interface VoiceAgentResult {
1416
1413
  * @experimental
1417
1414
  */
1418
1415
  declare const voiceAgent: (options: VoiceAgentOptions) => VoiceAgentResult;
1419
- export { type AgentApi, type AgentChatApi, type AgentChatMessage, type AgentChatOptions, type AgentChatResult, type AgentLiveEvent, type AgentOptions, type AgentProgressEvent, type AgentResult, type AgentStateApi, type AgentStateOptions, type AgentStateResult, type AgentThreadRecord, type AgentThreadStatus, type AgentTokenDelta, type AgentTokenStreamReference, type AgentToolEvent, type AgentToolEventsApi, type AgentToolEventsOptions, type AgentToolEventsResult, type AuthGateResult, type AuthOptions, type AuthResult, type ConnectionStatusOptions, type FlagContext, type FlagOptions, type FlagValue, type FlagsOptions, type HeartbeatReference, type HydratePreloadedOptions, type HydratePreloadedResult, type InfiniteQueryResult, LUNORA_CLIENT, type ListPresentReference, type LiveQueryOptions, type MutateOptions, type MutatorResult, type PaginatedQueryOptions, type PaginatedQueryResult, type PresenceOptions, type PresenceResult,
1416
+ export { type AgentApi, type AgentChatApi, type AgentChatMessage, type AgentChatOptions, type AgentChatResult, type AgentLiveEvent, type AgentOptions, type AgentProgressEvent, type AgentResult, type AgentStateApi, type AgentStateOptions, type AgentStateResult, type AgentThreadRecord, type AgentThreadStatus, type AgentTokenDelta, type AgentTokenStreamReference, type AgentToolEvent, type AgentToolEventsApi, type AgentToolEventsOptions, type AgentToolEventsResult, type AuthGateResult, type AuthOptions, type AuthResult, type ConnectionStatusOptions, type FlagOptions, type FlagValue, type FlagsOptions, type HeartbeatReference, type HydratePreloadedOptions, type HydratePreloadedResult, type InfiniteQueryResult, LUNORA_CLIENT, type ListPresentReference, type LiveQueryOptions, type MutateOptions, type MutatorResult, type PaginatedQueryOptions, type PaginatedQueryResult, type PresenceOptions, type PresenceResult,
1420
1417
  /**
1421
1418
  * The Angular adapter for Lunora.
1422
1419
  *
package/dist/index.d.ts CHANGED
@@ -625,16 +625,15 @@ interface ConnectionStatusOptions {
625
625
  * @experimental
626
626
  */
627
627
  declare const connectionStatus: (options?: ConnectionStatusOptions) => Signal<ConnectionStatus>;
628
+ /** The value kinds a flag resolves to — OpenFeature's boolean / number / string / structured (JSON) flags. */
629
+ type FlagValue$1 = boolean | number | string | {
630
+ [key: string]: unknown;
631
+ } | unknown[] | null;
628
632
  /**
629
633
  * The value kinds a flag resolves to — OpenFeature's boolean / number / string / structured (JSON) flags.
630
634
  * @experimental
631
635
  */
632
- type FlagValue = boolean | number | string | Record<string, unknown> | unknown[] | null;
633
- /**
634
- * Targeting context bag forwarded to the OpenFeature provider.
635
- * @experimental
636
- */
637
- type FlagContext = Record<string, unknown>;
636
+ type FlagValue = FlagValue$1;
638
637
  /**
639
638
  * `FlagOptions` is part of the experimental `@lunora/angular` API and may change without a major version bump.
640
639
  * @experimental
@@ -642,11 +641,6 @@ type FlagContext = Record<string, unknown>;
642
641
  interface FlagOptions {
643
642
  /** Client to bind to. Defaults to the injected `LUNORA_CLIENT`. */
644
643
  client?: LunoraClient;
645
- /**
646
- * Per-call targeting context merged on top of the app's default `identify`
647
- * targeting key.
648
- */
649
- context?: FlagContext;
650
644
  /** `DestroyRef` whose `onDestroy` tears down the subscription. Defaults to `inject(DestroyRef)`. */
651
645
  destroyRef?: DestroyRef;
652
646
  }
@@ -658,9 +652,16 @@ interface FlagOptions {
658
652
  * The flag's kind is inferred from `defaultValue`'s runtime type, so
659
653
  * `flag("dark", false)` reads a boolean and `flag("hero", "control")` a string.
660
654
  *
655
+ * The reactive channel is public, so the server evaluates every flag under the
656
+ * socket's own verified identity — the targeting key your `defineFlags({
657
+ * identify })` derives — and accepts no client-supplied targeting context. For
658
+ * evaluation under a context you compute, call `ctx.flags.*` inside a query,
659
+ * mutation, or action and return the resolved value.
660
+ *
661
661
  * Evaluation runs through whatever OpenFeature provider the app wired in
662
662
  * `lunora/flags.ts`; the read never throws — a provider error resolves the
663
- * default (the same fail-open contract as server-side `ctx.flags`).
663
+ * default (the same fail-open contract as server-side `ctx.flags`). No
664
+ * subscription opens during SSR; the signal stays at `defaultValue`.
664
665
  *
665
666
  * Call from an injection context:
666
667
  * ```ts
@@ -676,11 +677,6 @@ declare const flag: <T extends FlagValue>(key: string, defaultValue: T, options?
676
677
  interface FlagsOptions {
677
678
  /** Client to bind to. Defaults to the injected `LUNORA_CLIENT`. */
678
679
  client?: LunoraClient;
679
- /**
680
- * Targeting context shared by every flag in the set, merged on top of the
681
- * app's default `identify` targeting key.
682
- */
683
- context?: FlagContext;
684
680
  /** `DestroyRef` whose `onDestroy` tears down the subscriptions. Defaults to `inject(DestroyRef)`. */
685
681
  destroyRef?: DestroyRef;
686
682
  }
@@ -689,7 +685,8 @@ interface FlagsOptions {
689
685
  *
690
686
  * Pass a record of `key → defaultValue`; each flag's kind is inferred from its
691
687
  * default, and the returned signal holds the same-shaped record with resolved
692
- * values (the defaults until each evaluation lands).
688
+ * values (the defaults until each evaluation lands). Like {@link flag} it
689
+ * evaluates under the socket's server-verified identity only.
693
690
  *
694
691
  * Call from an injection context:
695
692
  * ```ts
@@ -1416,7 +1413,7 @@ interface VoiceAgentResult {
1416
1413
  * @experimental
1417
1414
  */
1418
1415
  declare const voiceAgent: (options: VoiceAgentOptions) => VoiceAgentResult;
1419
- export { type AgentApi, type AgentChatApi, type AgentChatMessage, type AgentChatOptions, type AgentChatResult, type AgentLiveEvent, type AgentOptions, type AgentProgressEvent, type AgentResult, type AgentStateApi, type AgentStateOptions, type AgentStateResult, type AgentThreadRecord, type AgentThreadStatus, type AgentTokenDelta, type AgentTokenStreamReference, type AgentToolEvent, type AgentToolEventsApi, type AgentToolEventsOptions, type AgentToolEventsResult, type AuthGateResult, type AuthOptions, type AuthResult, type ConnectionStatusOptions, type FlagContext, type FlagOptions, type FlagValue, type FlagsOptions, type HeartbeatReference, type HydratePreloadedOptions, type HydratePreloadedResult, type InfiniteQueryResult, LUNORA_CLIENT, type ListPresentReference, type LiveQueryOptions, type MutateOptions, type MutatorResult, type PaginatedQueryOptions, type PaginatedQueryResult, type PresenceOptions, type PresenceResult,
1416
+ export { type AgentApi, type AgentChatApi, type AgentChatMessage, type AgentChatOptions, type AgentChatResult, type AgentLiveEvent, type AgentOptions, type AgentProgressEvent, type AgentResult, type AgentStateApi, type AgentStateOptions, type AgentStateResult, type AgentThreadRecord, type AgentThreadStatus, type AgentTokenDelta, type AgentTokenStreamReference, type AgentToolEvent, type AgentToolEventsApi, type AgentToolEventsOptions, type AgentToolEventsResult, type AuthGateResult, type AuthOptions, type AuthResult, type ConnectionStatusOptions, type FlagOptions, type FlagValue, type FlagsOptions, type HeartbeatReference, type HydratePreloadedOptions, type HydratePreloadedResult, type InfiniteQueryResult, LUNORA_CLIENT, type ListPresentReference, type LiveQueryOptions, type MutateOptions, type MutatorResult, type PaginatedQueryOptions, type PaginatedQueryResult, type PresenceOptions, type PresenceResult,
1420
1417
  /**
1421
1418
  * The Angular adapter for Lunora.
1422
1419
  *
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- import{agent as t}from"./packem_shared/agent-BPvUvuXh.mjs";import{agentChat as m}from"./packem_shared/agentChat-BgD9zNFw.mjs";import{agentState as f}from"./packem_shared/agentState-BBAruY2b.mjs";import{agentToolEvents as n}from"./packem_shared/agentToolEvents-CUwrn-Nu.mjs";import{auth as i,authGate as u}from"./packem_shared/auth-BgwruT_M.mjs";import{LUNORA_CLIENT as c,injectLunoraClient as s,provideLunora as l}from"./packem_shared/LUNORA_CLIENT-B0toApHY.mjs";import{connectionStatus as L}from"./packem_shared/connectionStatus-UhmuwzMa.mjs";import{flag as v,flags as y}from"./packem_shared/flag-orUoJY7A.mjs";import{hydratePreloaded as C}from"./packem_shared/hydratePreloaded-C8lNoww0.mjs";import{liveQuery as S}from"./packem_shared/liveQuery-BvA2co81.mjs";import{mutate as I}from"./packem_shared/mutate-BZvLQLyu.mjs";import{mutator as P}from"./packem_shared/mutator-DjG1yGk8.mjs";import{infiniteQuery as b,paginatedQuery as j}from"./packem_shared/infiniteQuery-B5Q21vgn.mjs";import{presence as K}from"./packem_shared/presence-vJUxsR5f.mjs";import{rateLimit as R}from"./packem_shared/rateLimit-B3h9qzh-.mjs";import{runAction as _}from"./packem_shared/runAction-BfiPq4Xz.mjs";import{stream as q}from"./packem_shared/stream-CcjYdpzt.mjs";import{subscription as z}from"./packem_shared/subscription-DqtYnats.mjs";import{voiceAgent as D}from"./packem_shared/voiceAgent-CzyUcUKj.mjs";import{SKIP as H}from"@lunora/client/query";export{c as LUNORA_CLIENT,H as SKIP,t as agent,m as agentChat,f as agentState,n as agentToolEvents,i as auth,u as authGate,L as connectionStatus,v as flag,y as flags,C as hydratePreloaded,b as infiniteQuery,s as injectLunoraClient,S as liveQuery,I as mutate,P as mutator,j as paginatedQuery,K as presence,l as provideLunora,R as rateLimit,_ as runAction,q as stream,z as subscription,D as voiceAgent};
1
+ import{agent as t}from"./packem_shared/agent-BPvUvuXh.mjs";import{agentChat as m}from"./packem_shared/agentChat-BgD9zNFw.mjs";import{agentState as f}from"./packem_shared/agentState-BBAruY2b.mjs";import{agentToolEvents as n}from"./packem_shared/agentToolEvents-CUwrn-Nu.mjs";import{auth as i,authGate as u}from"./packem_shared/auth-BgwruT_M.mjs";import{LUNORA_CLIENT as c,injectLunoraClient as s,provideLunora as l}from"./packem_shared/LUNORA_CLIENT-B0toApHY.mjs";import{connectionStatus as L}from"./packem_shared/connectionStatus-UhmuwzMa.mjs";import{flag as v,flags as y}from"./packem_shared/flag-CeGmnEZN.mjs";import{hydratePreloaded as C}from"./packem_shared/hydratePreloaded-C8lNoww0.mjs";import{liveQuery as S}from"./packem_shared/liveQuery-BvA2co81.mjs";import{mutate as I}from"./packem_shared/mutate-BZvLQLyu.mjs";import{mutator as P}from"./packem_shared/mutator-DjG1yGk8.mjs";import{infiniteQuery as b,paginatedQuery as j}from"./packem_shared/infiniteQuery-B5Q21vgn.mjs";import{presence as K}from"./packem_shared/presence-vJUxsR5f.mjs";import{rateLimit as R}from"./packem_shared/rateLimit-B3h9qzh-.mjs";import{runAction as _}from"./packem_shared/runAction-BfiPq4Xz.mjs";import{stream as q}from"./packem_shared/stream-CcjYdpzt.mjs";import{subscription as z}from"./packem_shared/subscription-DqtYnats.mjs";import{voiceAgent as D}from"./packem_shared/voiceAgent-CzyUcUKj.mjs";import{SKIP as H}from"@lunora/client/query";export{c as LUNORA_CLIENT,H as SKIP,t as agent,m as agentChat,f as agentState,n as agentToolEvents,i as auth,u as authGate,L as connectionStatus,v as flag,y as flags,C as hydratePreloaded,b as infiniteQuery,s as injectLunoraClient,S as liveQuery,I as mutate,P as mutator,j as paginatedQuery,K as presence,l as provideLunora,R as rateLimit,_ as runAction,q as stream,z as subscription,D as voiceAgent};
@@ -0,0 +1 @@
1
+ import{inject as l,DestroyRef as u,signal as a}from"@angular/core";import{resolveLunoraClient as i}from"./LUNORA_CLIENT-B0toApHY.mjs";import{s as d}from"./platform-I2VyCEIl.mjs";const m="__lunora_flags__:eval",_=t=>{const e=typeof t;return e==="boolean"||e==="number"||e==="string"?e:"object"},v={__lunoraRef:m},y=(t,e,n)=>{try{return t.subscribe(v,{default:e.default,key:e.key,type:_(e.default)},c=>{n(c)},{onError:()=>{n(e.default)}})}catch{return()=>{}}},k=(t,e,n={})=>{const c=i(n.client),f=n.destroyRef===void 0,o=n.destroyRef??l(u),r=a(e);return d(f)&&o.onDestroy(y(c,{default:e,key:t},s=>{r.set(s)})),r.asReadonly()},h=(t,e={})=>{const n=i(e.client),c=e.destroyRef===void 0,f=e.destroyRef??l(u),o=a({...t});if(!d(c))return o.asReadonly();const r=[];for(const[s,b]of Object.entries(t))r.push(y(n,{default:b,key:s},R=>{o.set({...o(),[s]:R})}));return f.onDestroy(()=>{for(const s of r)s()}),o.asReadonly()};export{k as flag,h as flags};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lunora/angular",
3
- "version": "1.0.0-alpha.50",
3
+ "version": "1.0.0-alpha.52",
4
4
  "description": "Angular reactive adapter for Lunora — signal-based live queries and mutations",
5
5
  "keywords": [
6
6
  "angular",
@@ -53,8 +53,8 @@
53
53
  "access": "public"
54
54
  },
55
55
  "dependencies": {
56
- "@lunora/client": "1.0.0-alpha.66",
57
- "@lunora/ratelimit": "1.0.0-alpha.30",
56
+ "@lunora/client": "1.0.0-alpha.68",
57
+ "@lunora/ratelimit": "1.0.0-alpha.32",
58
58
  "@visulima/storage-client": "1.0.2"
59
59
  },
60
60
  "peerDependencies": {
@@ -1 +0,0 @@
1
- import{inject as l,DestroyRef as i,signal as a}from"@angular/core";import{resolveLunoraClient as b}from"./LUNORA_CLIENT-B0toApHY.mjs";const d="__lunora_flags__:eval",y=o=>{const e=typeof o;return e==="boolean"||e==="number"||e==="string"?e:"object"},R={__lunoraRef:d},x=(o,e,r={})=>{const f=b(r.client),n=r.destroyRef??l(i),c=y(e),t=a(e);let s;try{s=f.subscribe(R,{context:r.context,default:e,key:o,type:c},u=>{t.set(u)},{onError:()=>{t.set(e)}})}catch{}return s&&n.onDestroy(s),t.asReadonly()},v=(o,e={})=>{const r=b(e.client),f=e.destroyRef??l(i),n=a({...o}),c=[];for(const[t,s]of Object.entries(o))try{const u=r.subscribe(R,{context:e.context,default:s,key:t,type:y(s)},_=>{n.set({...n(),[t]:_})},{onError:()=>{n.set({...n(),[t]:s})}});c.push(u)}catch{}return f.onDestroy(()=>{for(const t of c)t()}),n.asReadonly()};export{x as flag,v as flags};