@lunora/angular 1.0.0-alpha.35 → 1.0.0-alpha.37

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
@@ -57,6 +57,31 @@ export class MessagesComponent {
57
57
 
58
58
  Pass `"skip"` as the args to short-circuit (no network call, no socket).
59
59
 
60
+ Pass a function/`Signal` instead of a plain object to make the args reactive —
61
+ each change tears the old subscription down and opens a fresh one for the new
62
+ args:
63
+
64
+ ```ts
65
+ export class MessagesComponent {
66
+ private readonly channelId = input.required<string>();
67
+
68
+ readonly messages = liveQuery(api.messages.list, () => ({ channelId: this.channelId() }));
69
+ }
70
+ ```
71
+
72
+ `subscription` and `paginatedQuery`/`infiniteQuery` accept the same reactive
73
+ args form. Calling from outside an injection context (e.g. `ngOnInit`) needs an
74
+ explicit `injector` alongside `client`/`destroyRef` for the reactive form —
75
+ `effect()` can't resolve one on its own there:
76
+
77
+ ```ts
78
+ liveQuery(api.messages.list, () => ({ channelId: this.channelId() }), {
79
+ client: this.client,
80
+ destroyRef: this.destroyRef,
81
+ injector: this.injector,
82
+ });
83
+ ```
84
+
60
85
  ## Mutations
61
86
 
62
87
  ```ts
package/dist/index.d.mts CHANGED
@@ -1,5 +1,5 @@
1
- import { DestroyRef, Signal, InjectionToken, EnvironmentProviders } from '@angular/core';
2
- import { FunctionReference, LunoraClient, SubscriptionError, User, LunoraClientOptions, ConnectionStatus, Preloaded, ArgsOf, ReturnOf, MutationCallOptions, MutatorHandle } from '@lunora/client';
1
+ import { DestroyRef, Signal, InjectionToken, EnvironmentProviders, Injector } from '@angular/core';
2
+ import { FunctionReference, LunoraClient, SubscriptionError, User, LunoraClientOptions, ConnectionStatus, Preloaded, ArgsOf, ReturnOf, MutationCallOptions, MutatorHandle, ActionCallOptions } from '@lunora/client';
3
3
  export type { ArgsOf, ConnectionStatus, FunctionReference, LunoraClient, LunoraClientOptions, MutationCallOptions, Preloaded, ReturnOf, SubscriptionError, Unsubscribe } from '@lunora/client';
4
4
  import { PaginationStatus } from '@lunora/client/pagination';
5
5
  import { RateLimitStatus, RateLimitConfig } from '@lunora/ratelimit';
@@ -754,6 +754,16 @@ interface LiveQueryOptions {
754
754
  * component is destroyed. Pass one explicitly to control the lifetime yourself.
755
755
  */
756
756
  destroyRef?: DestroyRef;
757
+ /**
758
+ * `Injector` to create the reactive-args `effect()` from. Only needed when
759
+ * `args` is a function/`Signal` AND `liveQuery` is called outside an injection
760
+ * context (an explicit `destroyRef` is also being passed — e.g. from
761
+ * `ngOnInit`, or from a test with no `TestBed`) — `effect()` cannot resolve an
762
+ * injector on its own there. Defaults to the ambient injection context, the
763
+ * same source `inject(DestroyRef)` already relies on. Unused for the static
764
+ * `args` form, which never creates an `effect()`.
765
+ */
766
+ injector?: Injector;
757
767
  /**
758
768
  * Called when the subscription errors after the initial attach — the async
759
769
  * error channel `createQuerySubscription` only wires when a sink is present.
@@ -787,9 +797,16 @@ interface LiveQueryOptions {
787
797
  * short-circuit — no network call, no socket; the signal stays `undefined`. To
788
798
  * call outside an injection context (e.g. lazily in `ngOnInit`), supply `client`
789
799
  * and `destroyRef` via {@link LiveQueryOptions}.
800
+ *
801
+ * `args` also accepts a function/`Signal` — `() => ({ channelId: channelId() })`
802
+ * — to make the subscription reactive: an args change tears the old
803
+ * subscription down and opens a fresh one for the new args, mirroring
804
+ * `@lunora/solid`'s `createQuery`/`@lunora/vue`'s `useQuery`. A static (plain
805
+ * object) `args` resolves once and never re-runs — no `effect()` is created for
806
+ * it, so it carries none of the reactive form's DI requirement.
790
807
  * @experimental
791
808
  */
792
- declare const liveQuery: <F extends FunctionReference>(reference: F, args: ArgsOf<F> | "skip", options?: LiveQueryOptions) => Signal<ReturnOf<F> | undefined>;
809
+ declare const liveQuery: <F extends FunctionReference>(reference: F, args: ArgsOf<F> | "skip" | (() => ArgsOf<F> | "skip"), options?: LiveQueryOptions) => Signal<ReturnOf<F> | undefined>;
793
810
  /**
794
811
  * `MutateOptions` is part of the experimental `@lunora/angular` API and may change without a major version bump.
795
812
  * @experimental
@@ -877,6 +894,13 @@ interface PaginatedQueryOptions {
877
894
  destroyRef?: DestroyRef;
878
895
  /** Page size for the first page (and the default for `loadMore`). */
879
896
  initialNumItems: number;
897
+ /**
898
+ * `Injector` to create the reactive-args `effect()` from. Only needed when
899
+ * `args` is a function/`Signal` AND the call is outside an injection context
900
+ * (an explicit `destroyRef` is also being passed). Defaults to the ambient
901
+ * injection context. Unused for the static `args` form.
902
+ */
903
+ injector?: Injector;
880
904
  /** Route to a specific shard when the target function is `.shardBy(...)`-partitioned. */
881
905
  shardKey?: string;
882
906
  }
@@ -927,9 +951,13 @@ interface InfiniteQueryResult<T> {
927
951
  * ```ts
928
952
  * readonly messages = paginatedQuery(api.messages.list, {}, { initialNumItems: 20 });
929
953
  * ```
954
+ *
955
+ * `args` also accepts a function/`Signal` to make the query reactive — an args
956
+ * change disposes the current pagination engine and builds a fresh one for the
957
+ * new args. A static (plain object) `args` resolves once and never re-runs.
930
958
  * @experimental
931
959
  */
932
- declare const paginatedQuery: <F extends FunctionReference>(reference: F, args: PaginatedArgs<F> | "skip", options: PaginatedQueryOptions) => PaginatedQueryResult<PageItemOf<F>>;
960
+ declare const paginatedQuery: <F extends FunctionReference>(reference: F, args: PaginatedArgs<F> | "skip" | (() => PaginatedArgs<F> | "skip"), options: PaginatedQueryOptions) => PaginatedQueryResult<PageItemOf<F>>;
933
961
  /**
934
962
  * Subscribe to a reactively-paginated query and expose its pages discretely.
935
963
  *
@@ -941,9 +969,12 @@ declare const paginatedQuery: <F extends FunctionReference>(reference: F, args:
941
969
  * ```ts
942
970
  * readonly feed = infiniteQuery(api.messages.list, {}, { initialNumItems: 20 });
943
971
  * ```
972
+ *
973
+ * `args` also accepts a function/`Signal` to make the query reactive — see
974
+ * `paginatedQuery`'s equivalent note.
944
975
  * @experimental
945
976
  */
946
- declare const infiniteQuery: <F extends FunctionReference>(reference: F, args: PaginatedArgs<F> | "skip", options: PaginatedQueryOptions) => InfiniteQueryResult<PageItemOf<F>>;
977
+ declare const infiniteQuery: <F extends FunctionReference>(reference: F, args: PaginatedArgs<F> | "skip" | (() => PaginatedArgs<F> | "skip"), options: PaginatedQueryOptions) => InfiniteQueryResult<PageItemOf<F>>;
947
978
  /**
948
979
  * `HeartbeatReference` is part of the experimental `@lunora/angular` API and may change without a major version bump.
949
980
  * @experimental
@@ -1065,6 +1096,43 @@ interface RateLimitResult {
1065
1096
  * @experimental
1066
1097
  */
1067
1098
  declare const rateLimit: (config: RateLimitConfig, options?: RateLimitOptions) => RateLimitResult;
1099
+ /**
1100
+ * `RunActionOptions` is part of the experimental `@lunora/angular` API and may change without a major version bump.
1101
+ * @experimental
1102
+ */
1103
+ interface RunActionOptions extends ActionCallOptions {
1104
+ /**
1105
+ * Client to run the action on. Defaults to the injected `LUNORA_CLIENT`.
1106
+ * Because actions usually fire from event handlers — which run *outside* an
1107
+ * injection context — capture the client once (`injectLunoraClient()` in a
1108
+ * field) and pass it here, or call `client.action(...)` directly.
1109
+ */
1110
+ client?: LunoraClient;
1111
+ }
1112
+ /**
1113
+ * Run a Lunora action and resolve with the server result (rejects on failure).
1114
+ *
1115
+ * The sibling of `mutate`, and a plain function for the same reason: Angular's
1116
+ * adapter models writes as calls rather than reactive handles, because they fire
1117
+ * from event handlers where a signal-returning primitive has nothing to bind to.
1118
+ * The other adapters return a reactive `{ call, pending, … }` handle because
1119
+ * their idioms make that natural; this one does not.
1120
+ *
1121
+ * Unlike `mutate` there are no `optimistic` / `optimisticUpdate` options. An
1122
+ * optimistic update patches the subscription cache on the assumption a write
1123
+ * will land; an action is not a write — it runs in the Worker, may call a third
1124
+ * party, and has no declared effect on any query.
1125
+ *
1126
+ * ```ts
1127
+ * private readonly client = injectLunoraClient();
1128
+ * verify = () => runAction(api.commands.run, { command: "lunora", args: ["verify"] }, { client: this.client });
1129
+ * ```
1130
+ *
1131
+ * When called from within an injection context you may omit `client` and let it
1132
+ * resolve from the injector.
1133
+ * @experimental
1134
+ */
1135
+ declare const runAction: <F extends FunctionReference>(reference: F, args: ArgsOf<F>, options?: RunActionOptions) => Promise<ReturnOf<F>>;
1068
1136
  /**
1069
1137
  * The lifecycle of a stream the primitive is observing.
1070
1138
  * @experimental
@@ -1131,6 +1199,14 @@ interface SubscriptionOptions {
1131
1199
  * `inject(DestroyRef)` — the calling component/service.
1132
1200
  */
1133
1201
  destroyRef?: DestroyRef;
1202
+ /**
1203
+ * `Injector` to create the reactive-args `effect()` from. Only needed when
1204
+ * `args` is a function/`Signal` AND `subscription` is called outside an
1205
+ * injection context (an explicit `destroyRef` is also being passed).
1206
+ * Defaults to the ambient injection context. Unused for the static `args`
1207
+ * form, which never creates an `effect()`.
1208
+ */
1209
+ injector?: Injector;
1134
1210
  /**
1135
1211
  * Called when the subscription errors after the initial attach. Without it,
1136
1212
  * a post-attach failure is dropped silently.
@@ -1164,9 +1240,13 @@ interface SubscriptionResult<T> {
1164
1240
  * ```ts
1165
1241
  * readonly stream = subscription(api.events.stream, { roomId: "general" });
1166
1242
  * ```
1243
+ *
1244
+ * `args` also accepts a function/`Signal` to make the subscription reactive —
1245
+ * an args change tears the old subscription down and opens a fresh one for the
1246
+ * new args. A static (plain object) `args` resolves once and never re-runs.
1167
1247
  * @experimental
1168
1248
  */
1169
- declare const subscription: <F extends FunctionReference>(reference: F, args: ArgsOf<F> | "skip", options?: SubscriptionOptions) => SubscriptionResult<ReturnOf<F>>;
1249
+ declare const subscription: <F extends FunctionReference>(reference: F, args: ArgsOf<F> | "skip" | (() => ArgsOf<F> | "skip"), options?: SubscriptionOptions) => SubscriptionResult<ReturnOf<F>>;
1170
1250
  /**
1171
1251
  * Browser Web Audio subsystems for `voiceAgent` — the default microphone capture
1172
1252
  * and speaker playback implementations injected into the primitive via its
@@ -1352,4 +1432,4 @@ export { type AgentApi, type AgentChatApi, type AgentChatMessage, type AgentChat
1352
1432
  * queue pass through to the client). `connectionStatus` is a `signal` of the
1353
1433
  * aggregate live-socket status.
1354
1434
  */
1355
- type ProvideLunoraOptions, type RateLimitOptions, type RateLimitResult, type StreamOptions, type StreamResult, type StreamStatus, type SubscriptionOptions, type SubscriptionResult, type VoiceAgentOptions, type VoiceAgentResult, type VoiceAudioFormat, type VoiceReference, type VoiceStatus, agent, agentChat, agentState, agentToolEvents, auth, authGate, connectionStatus, flag, flags, hydratePreloaded, infiniteQuery, injectLunoraClient, liveQuery, mutate, mutator, paginatedQuery, presence, provideLunora, rateLimit, stream, subscription, voiceAgent };
1435
+ type ProvideLunoraOptions, type RateLimitOptions, type RateLimitResult, type RunActionOptions, type StreamOptions, type StreamResult, type StreamStatus, type SubscriptionOptions, type SubscriptionResult, type VoiceAgentOptions, type VoiceAgentResult, type VoiceAudioFormat, type VoiceReference, type VoiceStatus, agent, agentChat, agentState, agentToolEvents, auth, authGate, connectionStatus, flag, flags, hydratePreloaded, infiniteQuery, injectLunoraClient, liveQuery, mutate, mutator, paginatedQuery, presence, provideLunora, rateLimit, runAction, stream, subscription, voiceAgent };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { DestroyRef, Signal, InjectionToken, EnvironmentProviders } from '@angular/core';
2
- import { FunctionReference, LunoraClient, SubscriptionError, User, LunoraClientOptions, ConnectionStatus, Preloaded, ArgsOf, ReturnOf, MutationCallOptions, MutatorHandle } from '@lunora/client';
1
+ import { DestroyRef, Signal, InjectionToken, EnvironmentProviders, Injector } from '@angular/core';
2
+ import { FunctionReference, LunoraClient, SubscriptionError, User, LunoraClientOptions, ConnectionStatus, Preloaded, ArgsOf, ReturnOf, MutationCallOptions, MutatorHandle, ActionCallOptions } from '@lunora/client';
3
3
  export type { ArgsOf, ConnectionStatus, FunctionReference, LunoraClient, LunoraClientOptions, MutationCallOptions, Preloaded, ReturnOf, SubscriptionError, Unsubscribe } from '@lunora/client';
4
4
  import { PaginationStatus } from '@lunora/client/pagination';
5
5
  import { RateLimitStatus, RateLimitConfig } from '@lunora/ratelimit';
@@ -754,6 +754,16 @@ interface LiveQueryOptions {
754
754
  * component is destroyed. Pass one explicitly to control the lifetime yourself.
755
755
  */
756
756
  destroyRef?: DestroyRef;
757
+ /**
758
+ * `Injector` to create the reactive-args `effect()` from. Only needed when
759
+ * `args` is a function/`Signal` AND `liveQuery` is called outside an injection
760
+ * context (an explicit `destroyRef` is also being passed — e.g. from
761
+ * `ngOnInit`, or from a test with no `TestBed`) — `effect()` cannot resolve an
762
+ * injector on its own there. Defaults to the ambient injection context, the
763
+ * same source `inject(DestroyRef)` already relies on. Unused for the static
764
+ * `args` form, which never creates an `effect()`.
765
+ */
766
+ injector?: Injector;
757
767
  /**
758
768
  * Called when the subscription errors after the initial attach — the async
759
769
  * error channel `createQuerySubscription` only wires when a sink is present.
@@ -787,9 +797,16 @@ interface LiveQueryOptions {
787
797
  * short-circuit — no network call, no socket; the signal stays `undefined`. To
788
798
  * call outside an injection context (e.g. lazily in `ngOnInit`), supply `client`
789
799
  * and `destroyRef` via {@link LiveQueryOptions}.
800
+ *
801
+ * `args` also accepts a function/`Signal` — `() => ({ channelId: channelId() })`
802
+ * — to make the subscription reactive: an args change tears the old
803
+ * subscription down and opens a fresh one for the new args, mirroring
804
+ * `@lunora/solid`'s `createQuery`/`@lunora/vue`'s `useQuery`. A static (plain
805
+ * object) `args` resolves once and never re-runs — no `effect()` is created for
806
+ * it, so it carries none of the reactive form's DI requirement.
790
807
  * @experimental
791
808
  */
792
- declare const liveQuery: <F extends FunctionReference>(reference: F, args: ArgsOf<F> | "skip", options?: LiveQueryOptions) => Signal<ReturnOf<F> | undefined>;
809
+ declare const liveQuery: <F extends FunctionReference>(reference: F, args: ArgsOf<F> | "skip" | (() => ArgsOf<F> | "skip"), options?: LiveQueryOptions) => Signal<ReturnOf<F> | undefined>;
793
810
  /**
794
811
  * `MutateOptions` is part of the experimental `@lunora/angular` API and may change without a major version bump.
795
812
  * @experimental
@@ -877,6 +894,13 @@ interface PaginatedQueryOptions {
877
894
  destroyRef?: DestroyRef;
878
895
  /** Page size for the first page (and the default for `loadMore`). */
879
896
  initialNumItems: number;
897
+ /**
898
+ * `Injector` to create the reactive-args `effect()` from. Only needed when
899
+ * `args` is a function/`Signal` AND the call is outside an injection context
900
+ * (an explicit `destroyRef` is also being passed). Defaults to the ambient
901
+ * injection context. Unused for the static `args` form.
902
+ */
903
+ injector?: Injector;
880
904
  /** Route to a specific shard when the target function is `.shardBy(...)`-partitioned. */
881
905
  shardKey?: string;
882
906
  }
@@ -927,9 +951,13 @@ interface InfiniteQueryResult<T> {
927
951
  * ```ts
928
952
  * readonly messages = paginatedQuery(api.messages.list, {}, { initialNumItems: 20 });
929
953
  * ```
954
+ *
955
+ * `args` also accepts a function/`Signal` to make the query reactive — an args
956
+ * change disposes the current pagination engine and builds a fresh one for the
957
+ * new args. A static (plain object) `args` resolves once and never re-runs.
930
958
  * @experimental
931
959
  */
932
- declare const paginatedQuery: <F extends FunctionReference>(reference: F, args: PaginatedArgs<F> | "skip", options: PaginatedQueryOptions) => PaginatedQueryResult<PageItemOf<F>>;
960
+ declare const paginatedQuery: <F extends FunctionReference>(reference: F, args: PaginatedArgs<F> | "skip" | (() => PaginatedArgs<F> | "skip"), options: PaginatedQueryOptions) => PaginatedQueryResult<PageItemOf<F>>;
933
961
  /**
934
962
  * Subscribe to a reactively-paginated query and expose its pages discretely.
935
963
  *
@@ -941,9 +969,12 @@ declare const paginatedQuery: <F extends FunctionReference>(reference: F, args:
941
969
  * ```ts
942
970
  * readonly feed = infiniteQuery(api.messages.list, {}, { initialNumItems: 20 });
943
971
  * ```
972
+ *
973
+ * `args` also accepts a function/`Signal` to make the query reactive — see
974
+ * `paginatedQuery`'s equivalent note.
944
975
  * @experimental
945
976
  */
946
- declare const infiniteQuery: <F extends FunctionReference>(reference: F, args: PaginatedArgs<F> | "skip", options: PaginatedQueryOptions) => InfiniteQueryResult<PageItemOf<F>>;
977
+ declare const infiniteQuery: <F extends FunctionReference>(reference: F, args: PaginatedArgs<F> | "skip" | (() => PaginatedArgs<F> | "skip"), options: PaginatedQueryOptions) => InfiniteQueryResult<PageItemOf<F>>;
947
978
  /**
948
979
  * `HeartbeatReference` is part of the experimental `@lunora/angular` API and may change without a major version bump.
949
980
  * @experimental
@@ -1065,6 +1096,43 @@ interface RateLimitResult {
1065
1096
  * @experimental
1066
1097
  */
1067
1098
  declare const rateLimit: (config: RateLimitConfig, options?: RateLimitOptions) => RateLimitResult;
1099
+ /**
1100
+ * `RunActionOptions` is part of the experimental `@lunora/angular` API and may change without a major version bump.
1101
+ * @experimental
1102
+ */
1103
+ interface RunActionOptions extends ActionCallOptions {
1104
+ /**
1105
+ * Client to run the action on. Defaults to the injected `LUNORA_CLIENT`.
1106
+ * Because actions usually fire from event handlers — which run *outside* an
1107
+ * injection context — capture the client once (`injectLunoraClient()` in a
1108
+ * field) and pass it here, or call `client.action(...)` directly.
1109
+ */
1110
+ client?: LunoraClient;
1111
+ }
1112
+ /**
1113
+ * Run a Lunora action and resolve with the server result (rejects on failure).
1114
+ *
1115
+ * The sibling of `mutate`, and a plain function for the same reason: Angular's
1116
+ * adapter models writes as calls rather than reactive handles, because they fire
1117
+ * from event handlers where a signal-returning primitive has nothing to bind to.
1118
+ * The other adapters return a reactive `{ call, pending, … }` handle because
1119
+ * their idioms make that natural; this one does not.
1120
+ *
1121
+ * Unlike `mutate` there are no `optimistic` / `optimisticUpdate` options. An
1122
+ * optimistic update patches the subscription cache on the assumption a write
1123
+ * will land; an action is not a write — it runs in the Worker, may call a third
1124
+ * party, and has no declared effect on any query.
1125
+ *
1126
+ * ```ts
1127
+ * private readonly client = injectLunoraClient();
1128
+ * verify = () => runAction(api.commands.run, { command: "lunora", args: ["verify"] }, { client: this.client });
1129
+ * ```
1130
+ *
1131
+ * When called from within an injection context you may omit `client` and let it
1132
+ * resolve from the injector.
1133
+ * @experimental
1134
+ */
1135
+ declare const runAction: <F extends FunctionReference>(reference: F, args: ArgsOf<F>, options?: RunActionOptions) => Promise<ReturnOf<F>>;
1068
1136
  /**
1069
1137
  * The lifecycle of a stream the primitive is observing.
1070
1138
  * @experimental
@@ -1131,6 +1199,14 @@ interface SubscriptionOptions {
1131
1199
  * `inject(DestroyRef)` — the calling component/service.
1132
1200
  */
1133
1201
  destroyRef?: DestroyRef;
1202
+ /**
1203
+ * `Injector` to create the reactive-args `effect()` from. Only needed when
1204
+ * `args` is a function/`Signal` AND `subscription` is called outside an
1205
+ * injection context (an explicit `destroyRef` is also being passed).
1206
+ * Defaults to the ambient injection context. Unused for the static `args`
1207
+ * form, which never creates an `effect()`.
1208
+ */
1209
+ injector?: Injector;
1134
1210
  /**
1135
1211
  * Called when the subscription errors after the initial attach. Without it,
1136
1212
  * a post-attach failure is dropped silently.
@@ -1164,9 +1240,13 @@ interface SubscriptionResult<T> {
1164
1240
  * ```ts
1165
1241
  * readonly stream = subscription(api.events.stream, { roomId: "general" });
1166
1242
  * ```
1243
+ *
1244
+ * `args` also accepts a function/`Signal` to make the subscription reactive —
1245
+ * an args change tears the old subscription down and opens a fresh one for the
1246
+ * new args. A static (plain object) `args` resolves once and never re-runs.
1167
1247
  * @experimental
1168
1248
  */
1169
- declare const subscription: <F extends FunctionReference>(reference: F, args: ArgsOf<F> | "skip", options?: SubscriptionOptions) => SubscriptionResult<ReturnOf<F>>;
1249
+ declare const subscription: <F extends FunctionReference>(reference: F, args: ArgsOf<F> | "skip" | (() => ArgsOf<F> | "skip"), options?: SubscriptionOptions) => SubscriptionResult<ReturnOf<F>>;
1170
1250
  /**
1171
1251
  * Browser Web Audio subsystems for `voiceAgent` — the default microphone capture
1172
1252
  * and speaker playback implementations injected into the primitive via its
@@ -1352,4 +1432,4 @@ export { type AgentApi, type AgentChatApi, type AgentChatMessage, type AgentChat
1352
1432
  * queue pass through to the client). `connectionStatus` is a `signal` of the
1353
1433
  * aggregate live-socket status.
1354
1434
  */
1355
- type ProvideLunoraOptions, type RateLimitOptions, type RateLimitResult, type StreamOptions, type StreamResult, type StreamStatus, type SubscriptionOptions, type SubscriptionResult, type VoiceAgentOptions, type VoiceAgentResult, type VoiceAudioFormat, type VoiceReference, type VoiceStatus, agent, agentChat, agentState, agentToolEvents, auth, authGate, connectionStatus, flag, flags, hydratePreloaded, infiniteQuery, injectLunoraClient, liveQuery, mutate, mutator, paginatedQuery, presence, provideLunora, rateLimit, stream, subscription, voiceAgent };
1435
+ type ProvideLunoraOptions, type RateLimitOptions, type RateLimitResult, type RunActionOptions, type StreamOptions, type StreamResult, type StreamStatus, type SubscriptionOptions, type SubscriptionResult, type VoiceAgentOptions, type VoiceAgentResult, type VoiceAudioFormat, type VoiceReference, type VoiceStatus, agent, agentChat, agentState, agentToolEvents, auth, authGate, connectionStatus, flag, flags, hydratePreloaded, infiniteQuery, injectLunoraClient, liveQuery, mutate, mutator, paginatedQuery, presence, provideLunora, rateLimit, runAction, stream, subscription, voiceAgent };
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- import{agent as e}from"./packem_shared/agent-DcC06SOO.mjs";import{agentChat as m}from"./packem_shared/agentChat-Cit2jdK_.mjs";import{agentState as a}from"./packem_shared/agentState-CBH9dKb7.mjs";import{agentToolEvents as x}from"./packem_shared/agentToolEvents-DSNEBf37.mjs";import{auth as i,authGate as u}from"./packem_shared/auth-BgwruT_M.mjs";import{LUNORA_CLIENT as s,injectLunoraClient as c,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 Q}from"./packem_shared/hydratePreloaded-DYqgj4Y1.mjs";import{liveQuery as A}from"./packem_shared/liveQuery-DR3i-aOo.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-C1vVL3Nk.mjs";import{presence as K}from"./packem_shared/presence-BfPC_yqX.mjs";import{rateLimit as R}from"./packem_shared/rateLimit-B3h9qzh-.mjs";import{stream as _}from"./packem_shared/stream-CcjYdpzt.mjs";import{subscription as q}from"./packem_shared/subscription-CWp5w6K4.mjs";import{voiceAgent as z}from"./packem_shared/voiceAgent-CzyUcUKj.mjs";import{SKIP as D}from"@lunora/client/query";export{s as LUNORA_CLIENT,D as SKIP,e as agent,m as agentChat,a as agentState,x as agentToolEvents,i as auth,u as authGate,L as connectionStatus,v as flag,y as flags,Q as hydratePreloaded,b as infiniteQuery,c as injectLunoraClient,A as liveQuery,I as mutate,P as mutator,j as paginatedQuery,K as presence,l as provideLunora,R as rateLimit,_ as stream,q as subscription,z 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-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-CIprZdJt.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 +1 @@
1
- import{inject as p,DestroyRef as R,computed as o,signal as h}from"@angular/core";import{resolveLunoraClient as v}from"./LUNORA_CLIENT-B0toApHY.mjs";import{subscription as w}from"./subscription-CWp5w6K4.mjs";const k=e=>{const{api:i,cancel:r,run:d,runArgs:l,threadKey:n}=e,a=v(e.client),u=e.destroyRef??p(R),{data:f}=w(i.agents.agentThread,{key:n},{client:a,destroyRef:u}),s=o(()=>f()),y=o(()=>s()?.status),c=h(!1),m=async(t,g)=>{c.set(!0);try{await a.mutation(d,{input:t,threadKey:n,...l,...g})}finally{c.set(!1)}};return{cancel:async()=>{const t=s()?.instanceId;r===void 0||t===void 0||await a.mutation(r,{instanceId:t,threadKey:n})},pending:c.asReadonly(),run:m,status:y,thread:s}};export{k as agent};
1
+ import{inject as p,DestroyRef as R,computed as o,signal as h}from"@angular/core";import{resolveLunoraClient as v}from"./LUNORA_CLIENT-B0toApHY.mjs";import{subscription as w}from"./subscription-DqtYnats.mjs";const k=e=>{const{api:i,cancel:r,run:d,runArgs:l,threadKey:n}=e,a=v(e.client),u=e.destroyRef??p(R),{data:f}=w(i.agents.agentThread,{key:n},{client:a,destroyRef:u}),s=o(()=>f()),y=o(()=>s()?.status),c=h(!1),m=async(t,g)=>{c.set(!0);try{await a.mutation(d,{input:t,threadKey:n,...l,...g})}finally{c.set(!1)}};return{cancel:async()=>{const t=s()?.instanceId;r===void 0||t===void 0||await a.mutation(r,{instanceId:t,threadKey:n})},pending:c.asReadonly(),run:m,status:y,thread:s}};export{k as agent};
@@ -1 +1 @@
1
- import{inject as K,DestroyRef as M,signal as O,computed as c}from"@angular/core";import{reconcileOptimistic as R,maxSeq as k}from"@lunora/client";import{resolveLunoraClient as F}from"./LUNORA_CLIENT-B0toApHY.mjs";import{stream as L}from"./stream-CcjYdpzt.mjs";import{subscription as w}from"./subscription-CWp5w6K4.mjs";const N={__lunoraRef:""},U=m=>{const{api:d,cancel:g,limit:f,send:x,sendArgs:A,stream:h,threadKey:n}=m,r=F(m.client),l=m.destroyRef??K(M),I=f===void 0?{key:n}:{key:n,limit:f},{data:b}=w(d.agents.agentMessages,I,{client:r,destroyRef:l}),{data:j}=w(d.agents.agentThread,{key:n},{client:r,destroyRef:l}),S=h===void 0?"skip":{key:n},{chunks:q}=L(h??N,S,{client:r,destroyRef:l}),o=O([]);let y=0;const u=c(()=>j()),C=c(()=>u()?.status),i=c(()=>b()??[]),D=c(()=>{const t=i(),e=R(o(),t);if(e.length===0)return t;const s=k(t);return[...t,...e.map((a,p)=>({content:a.content,optimistic:!0,role:"user",seq:s+1+p}))]}),_=c(()=>{const t=i().filter(e=>e.role==="assistant").length;return q().filter(e=>e.kind!=="progress"&&e.threadKey===n&&e.turn>=t).map(e=>e.text).join("")}),E=async(t,e)=>{const s=y;y+=1;const a=k(i());o.set([...R(o(),i()),{content:t,id:s,maxDurableSeqAtSend:a}]);try{await r.mutation(x,{input:t,threadKey:n,...A,...e})}catch(p){throw o.set(o().filter(T=>T.id!==s)),p}},v=async(t,e,s)=>{const a=u()?.instanceId;if(a===void 0)throw new Error(`agentChat: cannot ${t} — no in-flight run (thread has no instanceId)`);await r.mutation(d.agents.agentResolveApproval,{decision:t,instanceId:a,threadKey:n,toolCallId:e,...s===void 0?{}:{note:s}})};return{approve:async(t,e)=>v("approve",t,e),cancel:async()=>{const t=u()?.instanceId;g===void 0||t===void 0||await r.mutation(g,{instanceId:t,threadKey:n})},messages:D,reject:async(t,e)=>v("reject",t,e),send:E,status:C,streamingText:_}};export{U as agentChat};
1
+ import{inject as K,DestroyRef as M,signal as O,computed as c}from"@angular/core";import{reconcileOptimistic as R,maxSeq as k}from"@lunora/client";import{resolveLunoraClient as F}from"./LUNORA_CLIENT-B0toApHY.mjs";import{stream as L}from"./stream-CcjYdpzt.mjs";import{subscription as w}from"./subscription-DqtYnats.mjs";const N={__lunoraRef:""},U=m=>{const{api:d,cancel:g,limit:f,send:x,sendArgs:A,stream:h,threadKey:n}=m,r=F(m.client),l=m.destroyRef??K(M),I=f===void 0?{key:n}:{key:n,limit:f},{data:b}=w(d.agents.agentMessages,I,{client:r,destroyRef:l}),{data:j}=w(d.agents.agentThread,{key:n},{client:r,destroyRef:l}),S=h===void 0?"skip":{key:n},{chunks:q}=L(h??N,S,{client:r,destroyRef:l}),o=O([]);let y=0;const u=c(()=>j()),C=c(()=>u()?.status),i=c(()=>b()??[]),D=c(()=>{const t=i(),e=R(o(),t);if(e.length===0)return t;const s=k(t);return[...t,...e.map((a,p)=>({content:a.content,optimistic:!0,role:"user",seq:s+1+p}))]}),_=c(()=>{const t=i().filter(e=>e.role==="assistant").length;return q().filter(e=>e.kind!=="progress"&&e.threadKey===n&&e.turn>=t).map(e=>e.text).join("")}),E=async(t,e)=>{const s=y;y+=1;const a=k(i());o.set([...R(o(),i()),{content:t,id:s,maxDurableSeqAtSend:a}]);try{await r.mutation(x,{input:t,threadKey:n,...A,...e})}catch(p){throw o.set(o().filter(T=>T.id!==s)),p}},v=async(t,e,s)=>{const a=u()?.instanceId;if(a===void 0)throw new Error(`agentChat: cannot ${t} — no in-flight run (thread has no instanceId)`);await r.mutation(d.agents.agentResolveApproval,{decision:t,instanceId:a,threadKey:n,toolCallId:e,...s===void 0?{}:{note:s}})};return{approve:async(t,e)=>v("approve",t,e),cancel:async()=>{const t=u()?.instanceId;g===void 0||t===void 0||await r.mutation(g,{instanceId:t,threadKey:n})},messages:D,reject:async(t,e)=>v("reject",t,e),send:E,status:C,streamingText:_}};export{U as agentChat};
@@ -1 +1 @@
1
- import{computed as c}from"@angular/core";import{subscription as n}from"./subscription-CWp5w6K4.mjs";const d=t=>{const{data:e,error:r}=n(t.api.agents.agentState,{key:t.threadKey},{client:t.client,destroyRef:t.destroyRef}),a=c(()=>e());return{error:r,state:a}};export{d as agentState};
1
+ import{computed as c}from"@angular/core";import{subscription as n}from"./subscription-DqtYnats.mjs";const d=t=>{const{data:e,error:r}=n(t.api.agents.agentState,{key:t.threadKey},{client:t.client,destroyRef:t.destroyRef}),a=c(()=>e());return{error:r,state:a}};export{d as agentState};
@@ -1 +1 @@
1
- import{inject as v,DestroyRef as f,computed as y}from"@angular/core";import{resolveLunoraClient as C}from"./LUNORA_CLIENT-B0toApHY.mjs";import{stream as I}from"./stream-CcjYdpzt.mjs";import{subscription as N}from"./subscription-CWp5w6K4.mjs";const m={__lunoraRef:""},E=[],R=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}}]},A=t=>{const{api:r,limit:e,stream:n,threadKey:l}=t,a=C(t.client),i=t.destroyRef??v(f),u=e===void 0?{key:l}:{key:l,limit:e},{data:s}=N(r.agents.agentMessages,u,{client:a,destroyRef:i}),p=n===void 0?"skip":{key:l},{chunks:c}=I(n??m,p,{client:a,destroyRef:i});return{events:y(()=>{const d=(s()??E).flatMap(o=>R(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{A as agentToolEvents};
1
+ import{inject as v,DestroyRef as f,computed as y}from"@angular/core";import{resolveLunoraClient as C}from"./LUNORA_CLIENT-B0toApHY.mjs";import{stream as I}from"./stream-CcjYdpzt.mjs";import{subscription as N}from"./subscription-DqtYnats.mjs";const m={__lunoraRef:""},E=[],R=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}}]},A=t=>{const{api:r,limit:e,stream:n,threadKey:l}=t,a=C(t.client),i=t.destroyRef??v(f),u=e===void 0?{key:l}:{key:l,limit:e},{data:s}=N(r.agents.agentMessages,u,{client:a,destroyRef:i}),p=n===void 0?"skip":{key:l},{chunks:c}=I(n??m,p,{client:a,destroyRef:i});return{events:y(()=>{const d=(s()??E).flatMap(o=>R(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{A as agentToolEvents};
@@ -1 +1 @@
1
- import{inject as m,DestroyRef as b,signal as n}from"@angular/core";import{resolveLunoraClient as v}from"./LUNORA_CLIENT-B0toApHY.mjs";import{s as h}from"./platform-1MW9DnW6.mjs";const x=(s,e={})=>{const c=v(e.client),a=e.destroyRef===void 0,i=e.destroyRef??m(b),{args:d,functionPath:f,shardKey:l,value:u}=s,t=n(u),o=n(void 0),y={__lunoraRef:f};if(h(a)){const R=c.subscribe(y,d,r=>{t.set(r),o.set(void 0)},{onError:r=>{o.set(r)},shardKey:l});i.onDestroy(R)}return{data:t.asReadonly(),error:o.asReadonly()}};export{x as hydratePreloaded};
1
+ import{inject as m,DestroyRef as b,signal as n}from"@angular/core";import{resolveLunoraClient as v}from"./LUNORA_CLIENT-B0toApHY.mjs";import{s as h}from"./platform-I2VyCEIl.mjs";const x=(s,e={})=>{const c=v(e.client),a=e.destroyRef===void 0,i=e.destroyRef??m(b),{args:d,functionPath:f,shardKey:l,value:u}=s,t=n(u),o=n(void 0),y={__lunoraRef:f};if(h(a)){const R=c.subscribe(y,d,r=>{t.set(r),o.set(void 0)},{onError:r=>{o.set(r)},shardKey:l});i.onDestroy(R)}return{data:t.asReadonly(),error:o.asReadonly()}};export{x as hydratePreloaded};
@@ -0,0 +1 @@
1
+ import{computed as j,inject as W,DestroyRef as Q,signal as C}from"@angular/core";import{initialPages as X,derivePaginationStatus as U,applyLoadMore as Y,rebalance as Z}from"@lunora/client/pagination";import{resolveLunoraClient as V}from"./LUNORA_CLIENT-B0toApHY.mjs";import{s as q,a as v}from"./platform-I2VyCEIl.mjs";const tt=(t,n)=>t<n?-1:t>n?1:0,F=t=>{if(t===void 0)return"null";if(typeof t=="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 t=="number"){if(Number.isNaN(t))return"nan";if(t===1/0)return"inf";if(t===-1/0)return"-inf";if(Object.is(t,-0))return"-0"}if(t===null||typeof t!="object")return JSON.stringify(t);if(Array.isArray(t))return`[${t.map(e=>F(e)).join(",")}]`;const n=Object.getPrototypeOf(t);if(n!==null&&n!==Object.prototype){const e=t.constructor?.name??"value";throw new TypeError(`stableStringify: cannot use a ${e} in a stable JSON cache key — only plain objects, arrays, and JSON primitives are supported (wire-typed values key via stableWireKey)`)}const o=t,s=Object.keys(o).toSorted(tt),i=[];for(const e of s){const r=o[e];r!==void 0&&i.push(`${JSON.stringify(e)}:${F(r)}`)}return`{${i.join(",")}}`},_=t=>{let n="";for(let s=0;s<t.length;s+=32768)n+=String.fromCharCode(...t.subarray(s,s+32768));return btoa(n)},y="$lunora.wire$",D=64,et="__proto__",nt=t=>{if(t===null||typeof t!="object")return!1;const n=Object.getPrototypeOf(t);return n===null||n===Object.prototype},h=(t,n=0)=>{if(n>D)throw new RangeError(`wire-codec: value nesting exceeds the ${D}-level limit`);if(t===void 0)return[y,"undefined"];if(t===null)return null;const o=typeof t;if(o==="bigint")return[y,"bigint",t.toString()];if(o==="number"){const e=t;return Number.isNaN(e)?[y,"nan"]:e===1/0?[y,"inf"]:e===-1/0?[y,"-inf"]:e}if(o!=="object")return t;if(t instanceof Date)return[y,"date",h(t.getTime(),n+1)];if(t instanceof Error){const e=t,r={};for(const d of Object.keys(e))e[d]!==void 0&&(r[d]=h(e[d],n+1));const f=[y,"error",e.name,e.message,r];return e.cause!==void 0&&f.push(h(e.cause,n+1)),f}if(t instanceof URL)return[y,"url",t.href];if(t instanceof Map)return[y,"map",[...t.entries()].map(([e,r])=>[h(e,n+1),h(r,n+1)])];if(t instanceof Set)return[y,"set",[...t].map(e=>h(e,n+1))];if(t instanceof ArrayBuffer)return[y,"bytes",_(new Uint8Array(t)),"ArrayBuffer"];if(ArrayBuffer.isView(t)){const e=t,r=e.constructor.name,f=new Uint8Array(e.buffer,e.byteOffset,e.byteLength);return r==="Uint8Array"?[y,"bytes",_(f)]:[y,"bytes",_(f),r]}if(Array.isArray(t)){const e=t.map(r=>h(r,n+1));return e.length>0&&e[0]===y?[y,"arr",e]:e}if(!nt(t)){const e=t.constructor?.name??"value";throw new TypeError(`wire-codec: cannot encode a ${e} 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 s=t,i={};for(const e of Object.keys(s)){const r=s[e];if(r===void 0)continue;const f=h(r,n+1);e===et?Object.defineProperty(i,e,{configurable:!0,enumerable:!0,value:f,writable:!0}):i[e]=f}return i},rt=t=>F(h(t)),K=(t,n)=>`${t}::${rt(n)}`,R=(t,n)=>({...n,paginationOpts:{cursor:t.lower,endCursor:t.upper,numItems:t.numItems}}),J=(t,n,o,s)=>{const i=V(o.client),e=o.destroyRef===void 0&&s===void 0,{initialNumItems:r,shardKey:f}=o,d=t.__lunoraRef,m=n==="skip"?{}:n,c=C(X(r)),M=C([]),B=C("LoadingFirstPage"),S=new Map,w=new Map,N=new Set,k=()=>{const g=c().map(a=>{const l=K(d,R(a,m));return w.get(l)});M.set(g);const{status:P}=U(n==="skip",g);B.set(P)},G=(p,g)=>{const P=a=>K(d,R(a,m));for(const a of g){const l=P(a);if(w.has(l))continue;const b=p.find(u=>u.lower===a.lower);if(b){const u=w.get(P(b));u&&w.set(l,u)}}},H=p=>{const g=new Set;for(const a of p)g.add(K(d,R(a,m)));for(const[a,l]of S)g.has(l.currentKey)||(l.unsub(),S.delete(a),w.delete(l.currentKey));const P=new Set([...S.values()].map(a=>a.currentKey));for(const a of p){const l=R(a,m),b=K(d,l);if(P.has(b))continue;const u={currentKey:b,unsub:void 0};N.add(b);const L=i.subscribe(t,l,x=>{if(w.set(u.currentKey,x),N.delete(u.currentKey),k(),N.size===0){const O=c(),A=Z(O,M());A&&(G(O,A),c.set(A),I(A),k())}},{onError:()=>{N.delete(u.currentKey),k()},shardKey:f});u.unsub=L,S.set(b,u),P.add(b)}};let E=!1,$=!1;const I=p=>{if(E){$=!0;return}E=!0;try{let g=p;do $=!1,H(g),g=c();while($)}finally{E=!1}};n!=="skip"&&q(e)&&I(c()),k();const T=()=>{for(const p of S.values())p.unsub();S.clear(),w.clear()};return s===void 0?(o.destroyRef??W(Q)).onDestroy(T):s(T),{loadMore:p=>{if(n==="skip")return;const{nextCursor:g,status:P}=U(!1,M());if(P!=="CanLoadMore")return;const a=Y(c(),g,p);if(!a)return;const l=c().at(-1),b=a.at(-2);if(l&&b){const u=K(d,R(l,m)),L=K(d,R(b,m)),x=S.get(u);if(x&&u!==L){const O=w.get(u);O&&w.set(L,O),x.unsub(),S.delete(u),w.delete(u)}}c.set(a),I(c()),k()},pageResults:M,status:B}},z=(t,n,o)=>{if(typeof n!="function")return J(t,n,o);const s=V(o.client),i=o.destroyRef===void 0,e=o.destroyRef??W(Q),r=C(void 0);return q(i)&&v(n,{destroyRef:e,injector:o.injector},(f,d)=>{const m=[];r.set(J(t,f,{...o,client:s},c=>m.push(c))),d(()=>{for(const c of m)c()})}),{loadMore:f=>{r()?.loadMore(f)},pageResults:j(()=>r()?.pageResults()??[]),status:j(()=>r()?.status()??"LoadingFirstPage")}},ft=(t,n,o)=>{const s=z(t,n,o),i=j(()=>s.pageResults().flatMap(r=>r?.page??[]));return{isLoading:j(()=>{const r=s.status();return r==="LoadingFirstPage"||r==="LoadingMore"}),loadMore:s.loadMore,results:i,status:s.status}},ut=(t,n,o)=>{const{initialNumItems:s}=o,i=z(t,n,o),e=j(()=>i.pageResults().flatMap(c=>c?[c.page]:[])),r=j(()=>i.status()==="LoadingFirstPage"),f=j(()=>i.status()==="CanLoadMore"),d=j(()=>i.status()==="LoadingMore");return{fetchNextPage:c=>{i.loadMore(c??s)},hasNextPage:f,isFetchingNextPage:d,isLoading:r,pages:e,status:i.status}};export{ut as infiniteQuery,ft as paginatedQuery};
@@ -0,0 +1 @@
1
+ import{inject as y,DestroyRef as d,signal as m}from"@angular/core";import{createQuerySubscription as v}from"@lunora/client/query";import{resolveLunoraClient as R}from"./LUNORA_CLIENT-B0toApHY.mjs";import{s as p,a as b}from"./platform-I2VyCEIl.mjs";const g=(c,r,e={})=>{const i=R(e.client),a=e.destroyRef===void 0,n=e.destroyRef??y(d),t=m(void 0),s=(o,f)=>{const l=v(i,c,o,{onData:u=>{t.set(u)},onError:e.onError,onReset:()=>{t.set(void 0)}},{shardKey:e.shardKey});f(l)};return p(a)&&(typeof r=="function"?b(r,{destroyRef:n,injector:e.injector},s):s(r,o=>n.onDestroy(o))),t.asReadonly()};export{g as liveQuery};
@@ -0,0 +1 @@
1
+ import{inject as c,PLATFORM_ID as i,effect as a,untracked as u,NgZone as d}from"@angular/core";const f=t=>t?c(i,{optional:!0})!=="server":!0,p=(t,e)=>{const r=t?c(d,{optional:!0}):void 0;return r?r.runOutsideAngular(e):e()},v=(t,e,r)=>{let n;try{n=a(o=>{const s=t();u(()=>{r(s,o)})},{injector:e.injector,manualCleanup:!0})}catch(o){throw e.injector!==void 0?o:new Error("reactive `args` need an injection context: call this primitive from a component/service field or constructor, or pass `injector` alongside `destroyRef`.",{cause:o})}e.destroyRef.onDestroy(()=>{n.destroy()})};export{v as a,p as r,f as s};
@@ -0,0 +1 @@
1
+ import{inject as D,DestroyRef as S,signal as h}from"@angular/core";import{resolveLunoraClient as I}from"./LUNORA_CLIENT-B0toApHY.mjs";import{s as A,r as C}from"./platform-I2VyCEIl.mjs";const U=()=>{if(typeof crypto<"u"){if(typeof crypto.randomUUID=="function")return crypto.randomUUID();if(typeof crypto.getRandomValues=="function"){const n=crypto.getRandomValues(new Uint8Array(16));return Array.from(n,e=>e.toString(16).padStart(2,"0")).join("")}}return Date.now().toString(36)},E=1e4,M=(n,e)=>{const s=I(e.client),d=e.destroyRef===void 0,l=e.destroyRef??D(S),{heartbeat:y,listPresent:m,shardKey:i}=e,r=e.intervalMs??E,a=e.sessionId??U(),u=h(void 0);if(!Number.isFinite(r)||r<=0)throw new RangeError(`presence intervalMs must be a positive number, got ${String(r)}`);let c=e.data;const o=()=>{const t={roomId:n,sessionId:a};c!==void 0&&(t.data=c),s.mutation(y,t,{shardKey:i}).catch(()=>{})},v=t=>{c=t,o()};if(A(d)){const t=s.acquireConnectionContext({roomId:n,sessionId:a},{shardKey:i});o();const f=()=>{typeof document<"u"&&document.visibilityState==="visible"&&o()},p=C(d,()=>(typeof document<"u"&&document.addEventListener("visibilitychange",f),setInterval(o,r))),b={roomId:n},g=s.subscribe(m,b,R=>{u.set(R)},{shardKey:i});l.onDestroy(()=>{clearInterval(p),typeof document<"u"&&document.removeEventListener("visibilitychange",f),t(),g()})}return{present:u.asReadonly(),sessionId:a,setData:v}};export{M as presence};
@@ -0,0 +1 @@
1
+ import{resolveLunoraClient as e}from"./LUNORA_CLIENT-B0toApHY.mjs";const l=(n,o,t={})=>{const{client:r,...c}=t;return e(r).action(n,o,c)};export{l as runAction};
@@ -0,0 +1 @@
1
+ import{inject as m,DestroyRef as R,signal as a}from"@angular/core";import{createQuerySubscription as p}from"@lunora/client/query";import{resolveLunoraClient as b}from"./LUNORA_CLIENT-B0toApHY.mjs";import{s as h,a as j}from"./platform-I2VyCEIl.mjs";const C=(d,n,e={})=>{const f=b(e.client),v=e.destroyRef===void 0,i=e.destroyRef??m(R),l=e.onError,o=a(void 0),r=a(void 0),c=(t,u)=>{if(t==="skip"){o.set(void 0),r.set(void 0);return}const y=p(f,d,t,{onData:s=>{o.set(s),r.set(void 0)},onError:s=>{r.set(s),o.set(void 0),l?.(s)},onReset:()=>{o.set(void 0)}},{shardKey:e.shardKey});u(y)};return h(v)&&(typeof n=="function"?j(n,{destroyRef:i,injector:e.injector},c):c(n,t=>i.onDestroy(t))),{data:o.asReadonly(),error:r.asReadonly()}};export{C as subscription};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lunora/angular",
3
- "version": "1.0.0-alpha.35",
3
+ "version": "1.0.0-alpha.37",
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.51",
57
- "@lunora/ratelimit": "1.0.0-alpha.23",
56
+ "@lunora/client": "1.0.0-alpha.53",
57
+ "@lunora/ratelimit": "1.0.0-alpha.24",
58
58
  "@visulima/storage-client": "1.0.2"
59
59
  },
60
60
  "peerDependencies": {
@@ -1 +0,0 @@
1
- import{computed as O,inject as Q,DestroyRef as V,signal as T}from"@angular/core";import{initialPages as q,derivePaginationStatus as F,applyLoadMore as z,rebalance as G}from"@lunora/client/pagination";import{resolveLunoraClient as H}from"./LUNORA_CLIENT-B0toApHY.mjs";import{s as X}from"./platform-1MW9DnW6.mjs";const Y=(t,n)=>t<n?-1:t>n?1:0,I=t=>{if(t===void 0)return"null";if(typeof t=="bigint")throw new TypeError("stableStringify: cannot use a bigint in a stable JSON cache key — pass it as a string, or use stableWireKey");if(t===null||typeof t!="object")return JSON.stringify(t);if(Array.isArray(t))return`[${t.map(e=>I(e)).join(",")}]`;const n=Object.getPrototypeOf(t);if(n!==null&&n!==Object.prototype){const e=t.constructor?.name??"value";throw new TypeError(`stableStringify: cannot use a ${e} in a stable JSON cache key — only plain objects, arrays, and JSON primitives are supported (wire-typed values key via stableWireKey)`)}const i=t,s=Object.keys(i).toSorted(Y),c=[];for(const e of s){const r=i[e];r!==void 0&&c.push(`${JSON.stringify(e)}:${I(r)}`)}return`{${c.join(",")}}`},_=t=>{let n="";for(let s=0;s<t.length;s+=32768)n+=String.fromCharCode(...t.subarray(s,s+32768));return btoa(n)},u="$lunora.wire$",U=64,Z="__proto__",v=t=>{if(t===null||typeof t!="object")return!1;const n=Object.getPrototypeOf(t);return n===null||n===Object.prototype},P=(t,n=0)=>{if(n>U)throw new RangeError(`wire-codec: value nesting exceeds the ${U}-level limit`);if(t===void 0)return[u,"undefined"];if(t===null)return null;const i=typeof t;if(i==="bigint")return[u,"bigint",t.toString()];if(i==="number"){const e=t;return Number.isNaN(e)?[u,"nan"]:e===1/0?[u,"inf"]:e===-1/0?[u,"-inf"]:e}if(i!=="object")return t;if(t instanceof Date)return[u,"date",P(t.getTime(),n+1)];if(t instanceof Error){const e=t,r={};for(const l of Object.keys(e))e[l]!==void 0&&(r[l]=P(e[l],n+1));const d=[u,"error",e.name,e.message,r];return e.cause!==void 0&&d.push(P(e.cause,n+1)),d}if(t instanceof URL)return[u,"url",t.href];if(t instanceof Map)return[u,"map",[...t.entries()].map(([e,r])=>[P(e,n+1),P(r,n+1)])];if(t instanceof Set)return[u,"set",[...t].map(e=>P(e,n+1))];if(t instanceof ArrayBuffer)return[u,"bytes",_(new Uint8Array(t)),"ArrayBuffer"];if(ArrayBuffer.isView(t)){const e=t,r=e.constructor.name,d=new Uint8Array(e.buffer,e.byteOffset,e.byteLength);return r==="Uint8Array"?[u,"bytes",_(d)]:[u,"bytes",_(d),r]}if(Array.isArray(t)){const e=t.map(r=>P(r,n+1));return e.length>0&&e[0]===u?[u,"arr",e]:e}if(!v(t)){const e=t.constructor?.name??"value";throw new TypeError(`wire-codec: cannot encode a ${e} 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 s=t,c={};for(const e of Object.keys(s)){const r=s[e];if(r===void 0)continue;const d=P(r,n+1);e===Z?Object.defineProperty(c,e,{configurable:!0,enumerable:!0,value:d,writable:!0}):c[e]=d}return c},tt=t=>I(P(t)),K=(t,n)=>`${t}::${tt(n)}`,k=(t,n)=>({...n,paginationOpts:{cursor:t.lower,endCursor:t.upper,numItems:t.numItems}}),D=(t,n,i)=>{const s=H(i.client),c=i.destroyRef===void 0,e=i.destroyRef??Q(V),{initialNumItems:r,shardKey:d}=i,l=t.__lunoraRef,h=n==="skip"?{}:n,f=T(q(r)),L=T([]),B=T("LoadingFirstPage"),S=new Map,m=new Map,N=new Set,j=()=>{const g=f().map(o=>{const y=K(l,k(o,h));return m.get(y)});L.set(g);const{status:w}=F(n==="skip",g);B.set(w)},J=(p,g)=>{const w=o=>K(l,k(o,h));for(const o of g){const y=w(o);if(m.has(y))continue;const b=p.find(a=>a.lower===o.lower);if(b){const a=m.get(w(b));a&&m.set(y,a)}}},W=p=>{const g=new Set;for(const o of p)g.add(K(l,k(o,h)));for(const[o,y]of S)g.has(y.currentKey)||(y.unsub(),S.delete(o),m.delete(y.currentKey));const w=new Set([...S.values()].map(o=>o.currentKey));for(const o of p){const y=k(o,h),b=K(l,y);if(w.has(b))continue;const a={currentKey:b,unsub:void 0};N.add(b);const R=s.subscribe(t,y,A=>{if(m.set(a.currentKey,A),N.delete(a.currentKey),j(),N.size===0){const M=f(),x=G(M,L());x&&(J(M,x),f.set(x),C(x),j())}},{onError:()=>{N.delete(a.currentKey),j()},shardKey:d});a.unsub=R,S.set(b,a),w.add(b)}};let E=!1,$=!1;const C=p=>{if(E){$=!0;return}E=!0;try{let g=p;do $=!1,W(g),g=f();while($)}finally{E=!1}};return n!=="skip"&&X(c)&&C(f()),j(),e.onDestroy(()=>{for(const p of S.values())p.unsub();S.clear(),m.clear()}),{loadMore:p=>{if(n==="skip")return;const{nextCursor:g,status:w}=F(!1,L());if(w!=="CanLoadMore")return;const o=z(f(),g,p);if(!o)return;const y=f().at(-1),b=o.at(-2);if(y&&b){const a=K(l,k(y,h)),R=K(l,k(b,h)),A=S.get(a);if(A&&a!==R){const M=m.get(a);M&&m.set(R,M),A.unsub(),S.delete(a),m.delete(a)}}f.set(o),C(f()),j()},pageResults:L,status:B}},it=(t,n,i)=>{const s=D(t,n,i),c=O(()=>s.pageResults().flatMap(r=>r?.page??[]));return{isLoading:O(()=>{const r=s.status();return r==="LoadingFirstPage"||r==="LoadingMore"}),loadMore:s.loadMore,results:c,status:s.status}},ct=(t,n,i)=>{const{initialNumItems:s}=i,c=D(t,n,i),e=O(()=>c.pageResults().flatMap(f=>f?[f.page]:[])),r=O(()=>c.status()==="LoadingFirstPage"),d=O(()=>c.status()==="CanLoadMore"),l=O(()=>c.status()==="LoadingMore");return{fetchNextPage:f=>{c.loadMore(f??s)},hasNextPage:d,isFetchingNextPage:l,isLoading:r,pages:e,status:c.status}};export{ct as infiniteQuery,it as paginatedQuery};
@@ -1 +0,0 @@
1
- import{inject as d,DestroyRef as f,signal as u}from"@angular/core";import{createQuerySubscription as y}from"@lunora/client/query";import{resolveLunoraClient as l}from"./LUNORA_CLIENT-B0toApHY.mjs";import{s as m}from"./platform-1MW9DnW6.mjs";const h=(o,t,e={})=>{const n=l(e.client),s=e.destroyRef===void 0,i=e.destroyRef??d(f),r=u(void 0);if(m(s)){const c=y(n,o,t,{onData:a=>{r.set(a)},onError:e.onError,onReset:()=>{r.set(void 0)}},{shardKey:e.shardKey});i.onDestroy(c)}return r.asReadonly()};export{h as liveQuery};
@@ -1 +0,0 @@
1
- import{inject as o,PLATFORM_ID as u,NgZone as e}from"@angular/core";const i=r=>r?o(u,{optional:!0})!=="server":!0,a=(r,n)=>{const t=r?o(e,{optional:!0}):void 0;return t?t.runOutsideAngular(n):n()};export{a as r,i as s};
@@ -1 +0,0 @@
1
- import{inject as D,DestroyRef as S,signal as h}from"@angular/core";import{resolveLunoraClient as I}from"./LUNORA_CLIENT-B0toApHY.mjs";import{s as A,r as C}from"./platform-1MW9DnW6.mjs";const U=(t="sess")=>{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`${t}-${Array.from(e,s=>s.toString(16).padStart(2,"0")).join("")}`}}return`${t}-${Date.now().toString(36)}`},E=1e4,M=(t,e)=>{const s=I(e.client),d=e.destroyRef===void 0,l=e.destroyRef??D(S),{heartbeat:y,listPresent:m,shardKey:i}=e,o=e.intervalMs??E,a=e.sessionId??U(),u=h(void 0);if(!Number.isFinite(o)||o<=0)throw new RangeError(`presence intervalMs must be a positive number, got ${String(o)}`);let c=e.data;const r=()=>{const n={roomId:t,sessionId:a};c!==void 0&&(n.data=c),s.mutation(y,n,{shardKey:i}).catch(()=>{})},v=n=>{c=n,r()};if(A(d)){const n=s.acquireConnectionContext({roomId:t,sessionId:a},{shardKey:i});r();const f=()=>{typeof document<"u"&&document.visibilityState==="visible"&&r()},b=C(d,()=>(typeof document<"u"&&document.addEventListener("visibilitychange",f),setInterval(r,o))),p={roomId:t},g=s.subscribe(m,p,R=>{u.set(R)},{shardKey:i});l.onDestroy(()=>{clearInterval(b),typeof document<"u"&&document.removeEventListener("visibilitychange",f),n(),g()})}return{present:u.asReadonly(),sessionId:a,setData:v}};export{M as presence};
@@ -1 +0,0 @@
1
- import{inject as y,DestroyRef as m,signal as n}from"@angular/core";import{createQuerySubscription as l}from"@lunora/client/query";import{resolveLunoraClient as v}from"./LUNORA_CLIENT-B0toApHY.mjs";import{s as R}from"./platform-1MW9DnW6.mjs";const E=(i,s,o={})=>{const c=v(o.client),d=o.destroyRef===void 0,a=o.destroyRef??y(m),r=n(void 0),t=n(void 0);if(s!=="skip"&&R(d)){const f=o.onError,u=l(c,i,s,{onData:e=>{r.set(e),t.set(void 0)},onError:e=>{t.set(e),r.set(void 0),f?.(e)},onReset:()=>{r.set(void 0)}},{shardKey:o.shardKey});a.onDestroy(u)}return{data:r.asReadonly(),error:t.asReadonly()}};export{E as subscription};