@@ -8,66 +8,97 @@ import type {
88 Input ,
99 Output ,
1010 Query ,
11- ResultType ,
11+ ReadonlyJSONValue ,
1212 Schema ,
1313 TTL ,
1414 ViewFactory ,
1515} from '@rocicorp/zero'
16+ import type { Ref } from 'vue'
1617import { applyChange } from '@rocicorp/zero'
17- import { reactive } from 'vue'
18-
19- interface QueryResultDetails {
20- readonly type : ResultType
18+ import { ref } from 'vue'
19+
20+ // zero does not export this type
21+ type ErroredQuery = {
22+ error : 'app'
23+ queryName : string
24+ details : ReadonlyJSONValue
25+ } | {
26+ error : 'zero'
27+ queryName : string
28+ details : ReadonlyJSONValue
29+ } | {
30+ error : 'http'
31+ queryName : string
32+ status : number
33+ details : ReadonlyJSONValue
2134}
2235
23- type State = [ Entry , QueryResultDetails ]
24-
25- const complete = { type : 'complete' } as const
26- const unknown = { type : 'unknown' } as const
36+ export type QueryStatus = 'complete' | 'unknown' | 'error'
37+
38+ export type QueryError = {
39+ type : 'app'
40+ queryName : string
41+ details : ReadonlyJSONValue
42+ } | {
43+ type : 'http'
44+ queryName : string
45+ status : number
46+ details : ReadonlyJSONValue
47+ }
2748
2849export class VueView < V > implements Output {
2950 readonly #input: Input
3051 readonly #format: Format
3152 readonly #onDestroy: ( ) => void
3253 readonly #updateTTL: ( ttl : TTL ) => void
3354
34- #state: State
55+ #data: Ref < Entry >
56+ #status: Ref < QueryStatus >
57+ #error: Ref < QueryError | undefined >
3558
3659 constructor (
3760 input : Input ,
3861 onTransactionCommit : ( cb : ( ) => void ) => void ,
39- format : Format = { singular : false , relationships : { } } ,
62+ format : Format ,
4063 onDestroy : ( ) => void = ( ) => { } ,
41- queryComplete : true | Promise < true > ,
64+ queryComplete : true | ErroredQuery | Promise < true > ,
4265 updateTTL : ( ttl : TTL ) => void ,
4366 ) {
4467 this . #input = input
4568 this . #format = format
4669 this . #onDestroy = onDestroy
4770 this . #updateTTL = updateTTL
48- this . #state = reactive ( [
49- { '' : format . singular ? undefined : [ ] } ,
50- queryComplete === true ? complete : unknown ,
51- ] )
71+ this . #data = ref ( { '' : format . singular ? undefined : [ ] } )
72+ this . #status = ref ( queryComplete === true ? 'complete' : 'error' in queryComplete ? 'error' : 'unknown' )
73+ this . #error = ref ( queryComplete !== true && 'error' in queryComplete ? makeError ( queryComplete ) : undefined ) as Ref < QueryError | undefined >
74+
5275 input . setOutput ( this )
5376
5477 for ( const node of input . fetch ( { } ) ) {
5578 this . #applyChange( { type : 'add' , node } )
5679 }
5780
58- if ( queryComplete !== true ) {
81+ if ( queryComplete !== true && ! ( 'error' in queryComplete ) ) {
5982 void queryComplete . then ( ( ) => {
60- this . #state[ 1 ] = complete
83+ this . #status. value = 'complete'
84+ this . #error. value = undefined
85+ } ) . catch ( ( error : ErroredQuery ) => {
86+ this . #status. value = 'error'
87+ this . #error. value = makeError ( error )
6188 } )
6289 }
6390 }
6491
6592 get data ( ) {
66- return this . #state [ 0 ] [ '' ] as V
93+ return this . #data . value [ '' ] as V
6794 }
6895
6996 get status ( ) {
70- return this . #state[ 1 ] . type
97+ return this . #status. value
98+ }
99+
100+ get error ( ) {
101+ return this . #error. value
71102 }
72103
73104 destroy ( ) {
@@ -76,7 +107,7 @@ export class VueView<V> implements Output {
76107
77108 #applyChange( change : Change ) : void {
78109 applyChange (
79- this . #state [ 0 ] ,
110+ this . #data . value ,
80111 change ,
81112 this . #input. getSchema ( ) ,
82113 '' ,
@@ -93,6 +124,21 @@ export class VueView<V> implements Output {
93124 }
94125}
95126
127+ function makeError ( error : ErroredQuery ) : QueryError {
128+ return error . error === 'app' || error . error === 'zero'
129+ ? {
130+ type : 'app' ,
131+ queryName : error . queryName ,
132+ details : error . details ,
133+ }
134+ : {
135+ type : 'http' ,
136+ queryName : error . queryName ,
137+ status : error . status ,
138+ details : error . details ,
139+ }
140+ }
141+
96142export function vueViewFactory <
97143 TSchema extends Schema ,
98144 TTable extends keyof TSchema [ 'tables' ] & string ,
@@ -103,7 +149,7 @@ export function vueViewFactory<
103149 format : Format ,
104150 onDestroy : ( ) => void ,
105151 onTransactionCommit : ( cb : ( ) => void ) => void ,
106- queryComplete : true | Promise < true > ,
152+ queryComplete : true | ErroredQuery | Promise < true > ,
107153 updateTTL ?: ( ttl : TTL ) => void ,
108154) {
109155 interface UpdateTTL {
0 commit comments