You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This library is very powerful, but I discovered a suboptimal DX in a fairly simple case, which is an API that requires you to provide some arguments (i.e. specify what IDs to fetch). I've constructed an example that should demonstrate it:
typeExternalAccountId=string&{__brand: "ExternalAccountId"};interfaceAccount{externalId: ExternalAccountId;}interfaceAccountExternalData{accountId: ExternalAccountId;data: object;}declarefunctionfetchAccounts(): Promise<Account[]>;declarefunctionfetchAccountsExternalData(accountIds: ExternalAccountId[]): Promise<AccountExternalData[]>;constaccountCollection=createCollection(queryCollectionOptions({queryKey: ["accounts"],queryFn: ()=>fetchAccounts(),getKey: (data)=>data.externalId,
queryClient,}));constaccountExternalDataCollection=createCollection(queryCollectionOptions({syncMode: "on-demand",queryKey: ["accounts","externalData"],queryFn: ({ meta })=>{const{ filters }=parseLoadSubsetOptions(meta?.loadSubsetOptions);// We need to figure out which account ids to fetch external data for,// because the API requires a list of account ids.constaccountIdFilter=filters.find(({ operator, field })=>operator==="in"&&field.length===1&&field[0]==="externlId");// Fingers crossed teammates don't use this query without the filter.if(!accountIdFilter)throwError("Must provide a filter for externalId");// We have to cast to ExternalAccountId[],// because LoadSubsetOptions has no way of knowing the type.constaccountIds=accountIdFilter.valueasExternalAccountId[];returnfetchAccountsExternalData(accountIds);// Whoops, nobody caught the typo in "externlId"!},getKey: (data)=>data.accountId,
queryClient,}));createCollection(liveQueryCollectionOptions({query: (q)=>q.from({account: accountCollection}).join({data: accountExternalDataCollection},({ account, data })=>eq(account.externalId,data.accountId),"left"),startSync: true,}));
As can be seen, the issues are:
no way to enforce that queries using accountExternalDataCollection are fetched with an array of externalIds
i.e. this is invalid: useLiveQuery(q => q.from({data: accountExternalDataCollection}))
loss of type information by using loadSubsetOptions, demonstrated by the typo in "externlId"
I'm wondering if there's a way this use-case can be satisfied. The tricky part is that arbitrary parametrization like this (imagine API) has a problem:
The problem being that changing the parameter would likely have to delete all rows from the collection, because there is no clear relationship between the inputs and outputs, so client-side filtering can't work.
@samwillis seemed to be wiling to give this a thought and had some ideas with custom operators, so I'm hoping we can keep this discussion going.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
-
Hi, I'm creating this discussion based on this discord conversation.
This library is very powerful, but I discovered a suboptimal DX in a fairly simple case, which is an API that requires you to provide some arguments (i.e. specify what IDs to fetch). I've constructed an example that should demonstrate it:
As can be seen, the issues are:
accountExternalDataCollectionare fetched with an array of externalIdsi.e. this is invalid:
useLiveQuery(q => q.from({data: accountExternalDataCollection}))loadSubsetOptions, demonstrated by the typo in "externlId"I'm wondering if there's a way this use-case can be satisfied. The tricky part is that arbitrary parametrization like this (imagine API) has a problem:
The problem being that changing the parameter would likely have to delete all rows from the collection, because there is no clear relationship between the inputs and outputs, so client-side filtering can't work.
@samwillis seemed to be wiling to give this a thought and had some ideas with custom operators, so I'm hoping we can keep this discussion going.
Any ideas welcome, thanks!
Beta Was this translation helpful? Give feedback.
All reactions