@myko/ui-vue 6.1.0 → 6.2.0

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
@@ -14,7 +14,7 @@ pnpm add @myko/ui-vue
14
14
 
15
15
  ```vue
16
16
  <script setup>
17
- import { useQuery, useReport, useConnection } from '@myko/ui-vue'
17
+ import { useQuery, useQueryState, useReport, useConnection } from '@myko/ui-vue'
18
18
  import { queries, reports } from '@your-app/entities'
19
19
 
20
20
  // Connection management
@@ -23,6 +23,10 @@ const { status, isConnected, connect, disconnect } = useConnection()
23
23
  // Query data with automatic cleanup
24
24
  const { items, itemsArray, resolved } = useQuery(queries.GetAllTargets({}))
25
25
 
26
+ // Large keyed results can also expose lifecycle and incremental changes
27
+ const targets = useQueryState(queries.GetAllTargets({}))
28
+ // targets.status, targets.error, targets.revision, targets.changes
29
+
26
30
  // Report data with automatic cleanup
27
31
  const { value: count } = useReport(reports.CountAllTargets({}))
28
32
 
@@ -66,6 +70,7 @@ async function deleteTarget(id: string) {
66
70
  ### Composables
67
71
 
68
72
  - `useQuery(queryFactory)` - Watch a query with reactive Map updates
73
+ - `useQueryState(queryFactory)` - Add lifecycle, error, revision, and latest-diff state
69
74
  - `useReport(reportFactory)` - Watch a report with reactive value
70
75
  - `useConnection()` - Manage connection status
71
76
 
@@ -74,14 +79,17 @@ async function deleteTarget(id: string) {
74
79
  - `getMykoClient()` - Get the global singleton client
75
80
  - `createMykoClient()` - Create a new client instance
76
81
  - `myko` - Direct access to the global client
82
+ - `queryState(queryFactory)` - Ref-counted keyed query state without full-array rebuilds
77
83
 
78
84
  ## Types
79
85
 
80
86
  ```typescript
81
87
  import type {
82
88
  ReactiveQuery,
89
+ ReactiveQueryState,
83
90
  ReactiveReport,
84
91
  UseQueryReturn,
92
+ UseQueryStateReturn,
85
93
  UseReportReturn,
86
94
  UseConnectionReturn
87
95
  } from '@myko/ui-vue'
@@ -1,3 +1,3 @@
1
- export { useQuery, type UseQueryReturn } from './useQuery';
1
+ export { useQuery, useQueryState, type UseQueryReturn, type UseQueryStateReturn } from './useQuery';
2
2
  export { useReport, type UseReportReturn } from './useReport';
3
3
  export { useConnection, type UseConnectionReturn } from './useConnection';
@@ -1,5 +1,5 @@
1
- import { ComputedRef, Ref } from 'vue';
2
- import { Query, QueryItem } from '@myko/core';
1
+ import { ComputedRef, Ref, ShallowRef } from 'vue';
2
+ import { CollectionChanges, LiveCollectionStatus, Query, QueryItem } from '@myko/core';
3
3
 
4
4
  export interface UseQueryReturn<Q extends Query<unknown>> {
5
5
  /** Reactive map of items by ID */
@@ -15,6 +15,18 @@ export interface UseQueryReturn<Q extends Query<unknown>> {
15
15
  /** Manually release the subscription (also called on unmount) */
16
16
  release: () => void;
17
17
  }
18
+ export interface UseQueryStateReturn<Q extends Query<unknown>> extends UseQueryReturn<Q> {
19
+ /** Loading, live, or terminal error state. */
20
+ status: Ref<LiveCollectionStatus>;
21
+ /** Latest subscription error while retaining the last live data. */
22
+ error: ShallowRef<Error | undefined>;
23
+ /** Monotonic local revision updated for each diff or error. */
24
+ revision: Ref<number>;
25
+ /** Latest reset/upsert/delete set for row-oriented consumers. */
26
+ changes: ShallowRef<CollectionChanges<QueryItem<Q> & {
27
+ id: string;
28
+ }>>;
29
+ }
18
30
  /**
19
31
  * Vue composable for watching a Myko query.
20
32
  *
@@ -38,3 +50,5 @@ export interface UseQueryReturn<Q extends Query<unknown>> {
38
50
  * ```
39
51
  */
40
52
  export declare function useQuery<Q extends Query<unknown>>(queryFactory: Q): UseQueryReturn<Q>;
53
+ /** Vue query composable with explicit lifecycle and incremental change metadata. */
54
+ export declare function useQueryState<Q extends Query<unknown>>(queryFactory: Q): UseQueryStateReturn<Q>;
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";var S=Object.defineProperty;var p=(s,t,e)=>t in s?S(s,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):s[t]=e;var i=(s,t,e)=>p(s,typeof t!="symbol"?t+"":t,e);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const u=require("@myko/core"),c=require("vue"),f=require("rxjs");class b{constructor(){i(this,"client");i(this,"sharedQueries",new Map);i(this,"sharedReports",new Map);i(this,"commandSuccessSubject",new f.Subject);i(this,"commandErrorSubject",new f.Subject);i(this,"commandSuccess$",this.commandSuccessSubject.asObservable());i(this,"commandError$",this.commandErrorSubject.asObservable());i(this,"_connectionStatus",c.ref(u.ConnectionStatus.Disconnected));this.client=new u.MykoClient,this.client.connectionStatus$.subscribe(t=>{this._connectionStatus.value=t})}getCacheKey(t,e){const n=t==="query"?e.queryId:e.reportId,o=t==="query"?e.query:e.report;return`${t}:${n}:${JSON.stringify(o)}`}get connectionStatus(){return this._connectionStatus}get isConnected(){return this._connectionStatus.value===u.ConnectionStatus.Connected}connect(t){this.client.setAddress(t)}disconnect(){for(const t of this.sharedQueries.values())t.subscription.unsubscribe();this.sharedQueries.clear();for(const t of this.sharedReports.values())t.subscription.unsubscribe();this.sharedReports.clear(),this.client.disconnect()}query(t){const e=this.getCacheKey("query",t);let n=this.sharedQueries.get(e);if(!n){const r=c.shallowReactive(new Map),a=c.ref(!1),h=this.client.watchQueryDiff(t).subscribe({next:m=>{m.sequence===0n&&r.clear();for(const l of m.deletes)r.delete(l);for(const l of m.upserts)r.set(l.id,l);a.value=!0}});n={items:r,resolved:a,subscription:h,refCount:0},this.sharedQueries.set(e,n)}n.refCount++;let o=!1;return{items:n.items,resolved:n.resolved,release:()=>{if(o)return;o=!0;const r=this.sharedQueries.get(e);r&&(r.refCount--,r.refCount<=0&&(r.subscription.unsubscribe(),this.sharedQueries.delete(e)))}}}report(t){const e=this.getCacheKey("report",t);let n=this.sharedReports.get(e);if(!n){const r=c.shallowRef(void 0),a=this.client.watchReport(t).subscribe({next:h=>{r.value=h}});n={value:r,subscription:a,refCount:0},this.sharedReports.set(e,n)}n.refCount++;let o=!1;return{value:n.value,release:()=>{if(o)return;o=!0;const r=this.sharedReports.get(e);r&&(r.refCount--,r.refCount<=0&&(r.subscription.unsubscribe(),this.sharedReports.delete(e)))}}}async sendCommand(t){const e=t.commandId;try{const n=await this.client.sendCommand(t);return this.commandSuccessSubject.next({commandId:e,response:n}),n}catch(n){const o=n instanceof Error?n:new Error(String(n));throw this.commandErrorSubject.next({commandId:e,error:o}),n}}get raw(){return this.client}}const C=new b;function d(){return C}function v(){return new b}function y(s){const e=d().query(s);c.onUnmounted(()=>{e.release()});const n=c.computed(()=>Array.from(e.items.values()));return{items:e.items,itemsArray:n,resolved:e.resolved,release:e.release}}function g(s){const e=d().report(s);return c.onUnmounted(()=>{e.release()}),{value:e.value,release:e.release}}function w(){const s=d(),t=c.computed(()=>s.connectionStatus.value===u.ConnectionStatus.Connected),e=c.computed(()=>s.connectionStatus.value===u.ConnectionStatus.Connecting),n=c.computed(()=>s.connectionStatus.value===u.ConnectionStatus.Disconnected);return{status:s.connectionStatus,isConnected:t,isConnecting:e,isDisconnected:n,connect:o=>s.connect(o),disconnect:()=>s.disconnect()}}Object.defineProperty(exports,"ConnectionStatus",{enumerable:!0,get:()=>u.ConnectionStatus});exports.VueMykoClient=b;exports.createMykoClient=v;exports.getMykoClient=d;exports.myko=C;exports.useConnection=w;exports.useQuery=y;exports.useReport=g;
1
+ "use strict";var w=Object.defineProperty;var R=(n,t,e)=>t in n?w(n,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):n[t]=e;var i=(n,t,e)=>R(n,typeof t!="symbol"?t+"":t,e);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const a=require("@myko/core"),r=require("vue"),C=require("rxjs");class S{constructor(){i(this,"client");i(this,"sharedQueries",new Map);i(this,"sharedReports",new Map);i(this,"commandSuccessSubject",new C.Subject);i(this,"commandErrorSubject",new C.Subject);i(this,"commandSuccess$",this.commandSuccessSubject.asObservable());i(this,"commandError$",this.commandErrorSubject.asObservable());i(this,"_connectionStatus",r.ref(a.ConnectionStatus.Disconnected));this.client=new a.MykoClient,this.client.connectionStatus$.subscribe(t=>{this._connectionStatus.value=t})}getCacheKey(t,e){const s=t==="query"?e.queryId:e.reportId,o=t==="query"?e.query:e.report;return`${t}:${s}:${JSON.stringify(o)}`}get connectionStatus(){return this._connectionStatus}get isConnected(){return this._connectionStatus.value===a.ConnectionStatus.Connected}connect(t){this.client.setAddress(t)}disconnect(){for(const t of this.sharedQueries.values())t.subscription.unsubscribe();this.sharedQueries.clear();for(const t of this.sharedReports.values())t.subscription.unsubscribe();this.sharedReports.clear(),this.client.disconnect()}query(t){const e=this.getCacheKey("query",t);let s=this.sharedQueries.get(e);if(!s){const c=r.shallowReactive(new Map),d=r.ref(!1),f=r.ref("loading"),m=r.shallowRef(),v=r.ref(0),b=r.shallowRef({sequence:null,reset:!1,deletes:[],upserts:[]}),g=this.client.watchQueryDiff(t).subscribe({next:l=>{b.value=a.applyCollectionDiff(c,l),d.value=!0,f.value="live",m.value=void 0,v.value+=1},error:l=>{f.value="error",m.value=l instanceof Error?l:new Error(String(l)),v.value+=1}});s={items:c,resolved:d,status:f,error:m,revision:v,changes:b,subscription:g,refCount:0},this.sharedQueries.set(e,s)}s.refCount++;let o=!1;return{items:s.items,resolved:s.resolved,status:s.status,error:s.error,revision:s.revision,changes:s.changes,release:()=>{if(o)return;o=!0;const c=this.sharedQueries.get(e);c&&(c.refCount--,c.refCount<=0&&(c.subscription.unsubscribe(),this.sharedQueries.delete(e)))}}}queryState(t){return this.query(t)}report(t){const e=this.getCacheKey("report",t);let s=this.sharedReports.get(e);if(!s){const u=r.shallowRef(void 0),c=this.client.watchReport(t).subscribe({next:d=>{u.value=d}});s={value:u,subscription:c,refCount:0},this.sharedReports.set(e,s)}s.refCount++;let o=!1;return{value:s.value,release:()=>{if(o)return;o=!0;const u=this.sharedReports.get(e);u&&(u.refCount--,u.refCount<=0&&(u.subscription.unsubscribe(),this.sharedReports.delete(e)))}}}async sendCommand(t){const e=t.commandId;try{const s=await this.client.sendCommand(t);return this.commandSuccessSubject.next({commandId:e,response:s}),s}catch(s){const o=s instanceof Error?s:new Error(String(s));throw this.commandErrorSubject.next({commandId:e,error:o}),s}}get raw(){return this.client}}const p=new S;function h(){return p}function q(){return new S}function Q(n){return y(n)}function y(n){const e=h().queryState(n);r.onUnmounted(()=>{e.release()});const s=r.computed(()=>Array.from(e.items.values()));return{items:e.items,itemsArray:s,resolved:e.resolved,status:e.status,error:e.error,revision:e.revision,changes:e.changes,release:e.release}}function j(n){const e=h().report(n);return r.onUnmounted(()=>{e.release()}),{value:e.value,release:e.release}}function M(){const n=h(),t=r.computed(()=>n.connectionStatus.value===a.ConnectionStatus.Connected),e=r.computed(()=>n.connectionStatus.value===a.ConnectionStatus.Connecting),s=r.computed(()=>n.connectionStatus.value===a.ConnectionStatus.Disconnected);return{status:n.connectionStatus,isConnected:t,isConnecting:e,isDisconnected:s,connect:o=>n.connect(o),disconnect:()=>n.disconnect()}}Object.defineProperty(exports,"ConnectionStatus",{enumerable:!0,get:()=>a.ConnectionStatus});exports.VueMykoClient=S;exports.createMykoClient=q;exports.getMykoClient=h;exports.myko=p;exports.useConnection=M;exports.useQuery=Q;exports.useQueryState=y;exports.useReport=j;
package/dist/index.d.ts CHANGED
@@ -1,3 +1,3 @@
1
- export { createMykoClient, getMykoClient, myko, VueMykoClient, type CommandError, type CommandSuccess, type ReactiveQuery, type ReactiveReport } from './services/vue-client';
2
- export { useQuery, useReport, useConnection, type UseQueryReturn, type UseReportReturn, type UseConnectionReturn } from './composables';
1
+ export { createMykoClient, getMykoClient, myko, VueMykoClient, type CommandError, type CommandSuccess, type ReactiveQuery, type ReactiveQueryState, type ReactiveReport } from './services/vue-client';
2
+ export { useQuery, useQueryState, useReport, useConnection, type UseQueryReturn, type UseQueryStateReturn, type UseReportReturn, type UseConnectionReturn } from './composables';
3
3
  export { ConnectionStatus } from '@myko/core';
package/dist/index.mjs CHANGED
@@ -1,11 +1,11 @@
1
- var S = Object.defineProperty;
2
- var v = (n, t, e) => t in n ? S(n, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : n[t] = e;
3
- var c = (n, t, e) => v(n, typeof t != "symbol" ? t + "" : t, e);
4
- import { ConnectionStatus as i, MykoClient as g } from "@myko/core";
5
- import { ConnectionStatus as I } from "@myko/core";
6
- import { ref as f, shallowReactive as w, shallowRef as y, onUnmounted as p, computed as l } from "vue";
7
- import { Subject as b } from "rxjs";
8
- class C {
1
+ var R = Object.defineProperty;
2
+ var Q = (n, t, e) => t in n ? R(n, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : n[t] = e;
3
+ var c = (n, t, e) => Q(n, typeof t != "symbol" ? t + "" : t, e);
4
+ import { ConnectionStatus as a, MykoClient as q, applyCollectionDiff as E } from "@myko/core";
5
+ import { ConnectionStatus as U } from "@myko/core";
6
+ import { ref as d, shallowReactive as j, shallowRef as b, onUnmounted as g, computed as h } from "vue";
7
+ import { Subject as C } from "rxjs";
8
+ class y {
9
9
  constructor() {
10
10
  c(this, "client");
11
11
  // Shared queries by cache key
@@ -13,22 +13,22 @@ class C {
13
13
  // Shared reports by cache key
14
14
  c(this, "sharedReports", /* @__PURE__ */ new Map());
15
15
  // Command outcome subjects
16
- c(this, "commandSuccessSubject", new b());
17
- c(this, "commandErrorSubject", new b());
16
+ c(this, "commandSuccessSubject", new C());
17
+ c(this, "commandErrorSubject", new C());
18
18
  /** Observable of all command successes */
19
19
  c(this, "commandSuccess$", this.commandSuccessSubject.asObservable());
20
20
  /** Observable of all command errors */
21
21
  c(this, "commandError$", this.commandErrorSubject.asObservable());
22
22
  // Reactive connection status
23
- c(this, "_connectionStatus", f(i.Disconnected));
24
- this.client = new g(), this.client.connectionStatus$.subscribe((t) => {
23
+ c(this, "_connectionStatus", d(a.Disconnected));
24
+ this.client = new q(), this.client.connectionStatus$.subscribe((t) => {
25
25
  this._connectionStatus.value = t;
26
26
  });
27
27
  }
28
28
  /** Create a stable cache key from a query/report factory */
29
29
  getCacheKey(t, e) {
30
- const s = t === "query" ? e.queryId : e.reportId, o = t === "query" ? e.query : e.report;
31
- return `${t}:${s}:${JSON.stringify(o)}`;
30
+ const s = t === "query" ? e.queryId : e.reportId, r = t === "query" ? e.query : e.report;
31
+ return `${t}:${s}:${JSON.stringify(r)}`;
32
32
  }
33
33
  /** Current connection status (reactive) */
34
34
  get connectionStatus() {
@@ -36,7 +36,7 @@ class C {
36
36
  }
37
37
  /** Whether currently connected (reactive) - use .value to access */
38
38
  get isConnected() {
39
- return this._connectionStatus.value === i.Connected;
39
+ return this._connectionStatus.value === a.Connected;
40
40
  }
41
41
  /** Set the server address and connect */
42
42
  connect(t) {
@@ -74,31 +74,51 @@ class C {
74
74
  const e = this.getCacheKey("query", t);
75
75
  let s = this.sharedQueries.get(e);
76
76
  if (!s) {
77
- const r = w(/* @__PURE__ */ new Map()), u = f(!1), d = this.client.watchQueryDiff(t).subscribe({
78
- next: (h) => {
79
- h.sequence === 0n && r.clear();
80
- for (const a of h.deletes)
81
- r.delete(a);
82
- for (const a of h.upserts)
83
- r.set(a.id, a);
84
- u.value = !0;
77
+ const o = j(/* @__PURE__ */ new Map()), l = d(!1), f = d("loading"), m = b(), v = d(0), S = b({
78
+ sequence: null,
79
+ reset: !1,
80
+ deletes: [],
81
+ upserts: []
82
+ }), w = this.client.watchQueryDiff(t).subscribe({
83
+ next: (u) => {
84
+ S.value = E(o, u), l.value = !0, f.value = "live", m.value = void 0, v.value += 1;
85
+ },
86
+ error: (u) => {
87
+ f.value = "error", m.value = u instanceof Error ? u : new Error(String(u)), v.value += 1;
85
88
  }
86
89
  });
87
- s = { items: r, resolved: u, subscription: d, refCount: 0 }, this.sharedQueries.set(e, s);
90
+ s = {
91
+ items: o,
92
+ resolved: l,
93
+ status: f,
94
+ error: m,
95
+ revision: v,
96
+ changes: S,
97
+ subscription: w,
98
+ refCount: 0
99
+ }, this.sharedQueries.set(e, s);
88
100
  }
89
101
  s.refCount++;
90
- let o = !1;
102
+ let r = !1;
91
103
  return {
92
104
  items: s.items,
93
105
  resolved: s.resolved,
106
+ status: s.status,
107
+ error: s.error,
108
+ revision: s.revision,
109
+ changes: s.changes,
94
110
  release: () => {
95
- if (o) return;
96
- o = !0;
97
- const r = this.sharedQueries.get(e);
98
- r && (r.refCount--, r.refCount <= 0 && (r.subscription.unsubscribe(), this.sharedQueries.delete(e)));
111
+ if (r) return;
112
+ r = !0;
113
+ const o = this.sharedQueries.get(e);
114
+ o && (o.refCount--, o.refCount <= 0 && (o.subscription.unsubscribe(), this.sharedQueries.delete(e)));
99
115
  }
100
116
  };
101
117
  }
118
+ /** Watch a query with explicit lifecycle and incremental change metadata. */
119
+ queryState(t) {
120
+ return this.query(t);
121
+ }
102
122
  /**
103
123
  * Watch a report with reactive value updates.
104
124
  *
@@ -122,26 +142,26 @@ class C {
122
142
  const e = this.getCacheKey("report", t);
123
143
  let s = this.sharedReports.get(e);
124
144
  if (!s) {
125
- const r = y(void 0), u = this.client.watchReport(t).subscribe({
126
- next: (d) => {
127
- r.value = d;
145
+ const i = b(void 0), o = this.client.watchReport(t).subscribe({
146
+ next: (l) => {
147
+ i.value = l;
128
148
  }
129
149
  });
130
150
  s = {
131
- value: r,
132
- subscription: u,
151
+ value: i,
152
+ subscription: o,
133
153
  refCount: 0
134
154
  }, this.sharedReports.set(e, s);
135
155
  }
136
156
  s.refCount++;
137
- let o = !1;
157
+ let r = !1;
138
158
  return {
139
159
  value: s.value,
140
160
  release: () => {
141
- if (o) return;
142
- o = !0;
143
- const r = this.sharedReports.get(e);
144
- r && (r.refCount--, r.refCount <= 0 && (r.subscription.unsubscribe(), this.sharedReports.delete(e)));
161
+ if (r) return;
162
+ r = !0;
163
+ const i = this.sharedReports.get(e);
164
+ i && (i.refCount--, i.refCount <= 0 && (i.subscription.unsubscribe(), this.sharedReports.delete(e)));
145
165
  }
146
166
  };
147
167
  }
@@ -166,8 +186,8 @@ class C {
166
186
  const s = await this.client.sendCommand(t);
167
187
  return this.commandSuccessSubject.next({ commandId: e, response: s }), s;
168
188
  } catch (s) {
169
- const o = s instanceof Error ? s : new Error(String(s));
170
- throw this.commandErrorSubject.next({ commandId: e, error: o }), s;
189
+ const r = s instanceof Error ? s : new Error(String(s));
190
+ throw this.commandErrorSubject.next({ commandId: e, error: r }), s;
171
191
  }
172
192
  }
173
193
  /** Access the underlying MykoClient for advanced use cases */
@@ -175,53 +195,61 @@ class C {
175
195
  return this.client;
176
196
  }
177
197
  }
178
- const R = new C();
179
- function m() {
180
- return R;
198
+ const M = new y();
199
+ function p() {
200
+ return M;
201
+ }
202
+ function I() {
203
+ return new y();
181
204
  }
182
- function x() {
183
- return new C();
205
+ function _(n) {
206
+ return x(n);
184
207
  }
185
- function E(n) {
186
- const e = m().query(n);
187
- p(() => {
208
+ function x(n) {
209
+ const e = p().queryState(n);
210
+ g(() => {
188
211
  e.release();
189
212
  });
190
- const s = l(() => Array.from(e.items.values()));
213
+ const s = h(() => Array.from(e.items.values()));
191
214
  return {
192
215
  items: e.items,
193
216
  itemsArray: s,
194
217
  resolved: e.resolved,
218
+ status: e.status,
219
+ error: e.error,
220
+ revision: e.revision,
221
+ changes: e.changes,
195
222
  release: e.release
196
223
  };
197
224
  }
198
- function $(n) {
199
- const e = m().report(n);
200
- return p(() => {
225
+ function A(n) {
226
+ const e = p().report(n);
227
+ return g(() => {
201
228
  e.release();
202
229
  }), {
203
230
  value: e.value,
204
231
  release: e.release
205
232
  };
206
233
  }
207
- function k() {
208
- const n = m(), t = l(() => n.connectionStatus.value === i.Connected), e = l(() => n.connectionStatus.value === i.Connecting), s = l(() => n.connectionStatus.value === i.Disconnected);
234
+ function O() {
235
+ const n = p(), t = h(() => n.connectionStatus.value === a.Connected), e = h(() => n.connectionStatus.value === a.Connecting), s = h(() => n.connectionStatus.value === a.Disconnected);
209
236
  return {
210
237
  status: n.connectionStatus,
211
238
  isConnected: t,
212
239
  isConnecting: e,
213
240
  isDisconnected: s,
214
- connect: (o) => n.connect(o),
241
+ connect: (r) => n.connect(r),
215
242
  disconnect: () => n.disconnect()
216
243
  };
217
244
  }
218
245
  export {
219
- I as ConnectionStatus,
220
- C as VueMykoClient,
221
- x as createMykoClient,
222
- m as getMykoClient,
223
- R as myko,
224
- k as useConnection,
225
- E as useQuery,
226
- $ as useReport
246
+ U as ConnectionStatus,
247
+ y as VueMykoClient,
248
+ I as createMykoClient,
249
+ p as getMykoClient,
250
+ M as myko,
251
+ O as useConnection,
252
+ _ as useQuery,
253
+ x as useQueryState,
254
+ A as useReport
227
255
  };
@@ -1,4 +1,4 @@
1
- import { ConnectionStatus, MykoClient, Command, CommandResult, QueryItem, Query, ReportResult, Report } from '@myko/core';
1
+ import { ConnectionStatus, MykoClient, CollectionChanges, Command, CommandResult, LiveCollectionStatus, QueryItem, Query, ReportResult, Report } from '@myko/core';
2
2
  import { Ref, ShallowRef } from 'vue';
3
3
  import { Observable } from 'rxjs';
4
4
 
@@ -23,6 +23,19 @@ export type ReactiveQuery<Q extends Query<unknown>> = {
23
23
  /** Release this consumer's reference (unsubscribes when last consumer releases) */
24
24
  release: () => void;
25
25
  };
26
+ /** Reactive query state with incremental change and lifecycle metadata. */
27
+ export type ReactiveQueryState<Q extends Query<unknown>> = ReactiveQuery<Q> & {
28
+ /** Loading, live, or terminal error state. */
29
+ readonly status: Ref<LiveCollectionStatus>;
30
+ /** Latest subscription error; existing items remain available. */
31
+ readonly error: ShallowRef<Error | undefined>;
32
+ /** Monotonic local revision updated for every diff or error. */
33
+ readonly revision: Ref<number>;
34
+ /** Latest reset/upsert/delete set for row-oriented consumers. */
35
+ readonly changes: ShallowRef<CollectionChanges<QueryItem<Q> & {
36
+ id: string;
37
+ }>>;
38
+ };
26
39
  /** Reactive report result - generic over the Report factory type */
27
40
  export type ReactiveReport<R extends Report<unknown>> = {
28
41
  /** Current value (reactive via ref) */
@@ -77,6 +90,8 @@ export declare class VueMykoClient {
77
90
  * ```
78
91
  */
79
92
  query<Q extends Query<unknown>>(queryFactory: Q): ReactiveQuery<Q>;
93
+ /** Watch a query with explicit lifecycle and incremental change metadata. */
94
+ queryState<Q extends Query<unknown>>(queryFactory: Q): ReactiveQueryState<Q>;
80
95
  /**
81
96
  * Watch a report with reactive value updates.
82
97
  *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "dependencies": {
3
- "@myko/core": "^6.1.0"
3
+ "@myko/core": "^6.2.0"
4
4
  },
5
5
  "devDependencies": {
6
6
  "@types/luxon": "^3.4.2",
@@ -50,5 +50,5 @@
50
50
  },
51
51
  "type": "module",
52
52
  "types": "./dist/index.d.ts",
53
- "version": "6.1.0"
53
+ "version": "6.2.0"
54
54
  }