Skip to content
This repository has been archived by the owner on Mar 14, 2024. It is now read-only.

Commit

Permalink
feat: add support for the optional fields introduced in v0.15.0 of th…
Browse files Browse the repository at this point in the history
…e pocketbase sdk
  • Loading branch information
goknsh committed May 23, 2023
1 parent f17e3e9 commit f5c1603
Show file tree
Hide file tree
Showing 10 changed files with 75 additions and 31 deletions.
5 changes: 5 additions & 0 deletions .changeset/witty-doors-tickle.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'svelte-query-pocketbase': minor
---

feat: add support for the optional fields introduced in v0.15.0 of the pocketbase sdk
13 changes: 10 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,12 @@ Creates a TanStack Query that updates a Pocketbase record in realtime. View the
const someRecord = createRecordQuery<SomeCollectionResponse>(
pocketbase.collection(Collections.SomeCollection),
'some_id',
{ queryParams: { expand: 'some_field' } }
{
queryParams: {
expand: 'some_field',
fields: 'some_field' // the library will internally add id and updated to this
}
}
);
</script>
Expand Down Expand Up @@ -287,7 +292,8 @@ Creates a TanStack Query that updates an array of Pocketbase records in realtime
queryParams: {
expand: 'some_field',
sort: '-created', // sort by date created, descending
filter: 'created >= "2022-01-01 00:00:00"'
filter: 'created >= "2022-01-01 00:00:00"',
fields: 'some_field' // the library will internally add id and updated to this
},
// sortFunction and filterFunction are applied after a realtime update is applied
sortFunction: (a, b) => new Date(a.created) - new Date(b.created) // sort by date created, descending
Expand Down Expand Up @@ -515,7 +521,8 @@ Creates a TanStack Infinite Query that updates paginated Pocketbase records in r
queryParams: {
expand: 'some_field',
sort: '-created', // sort by date created, descending
filter: 'created >= "2022-01-01 00:00:00"'
filter: 'created >= "2022-01-01 00:00:00"',
fields: 'some_field' // the library will internally add id and updated to this
},
// sortFunction and filterFunction are applied after a realtime update is applied
sortFunction: (a, b) => new Date(a.created) - new Date(b.created) // sort by date created, descending
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
"dependencies": {
"@tanstack/svelte-query": "^4.22.2",
"immer": "^9.0.19",
"pocketbase": "^0.11.1 || ^0.12.0 || ^0.13.0 || ^0.14.0",
"pocketbase": "^0.11.1 || ^0.12.0 || ^0.13.0 || ^0.14.0 || ^0.15.0",
"svelte": "^3.54.0"
},
"devDependencies": {
Expand Down
8 changes: 4 additions & 4 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

27 changes: 26 additions & 1 deletion src/lib/internal/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { Record, RecordService } from 'pocketbase';
import type { BaseQueryParams, Record, RecordService } from 'pocketbase';

/**
* Meant for internal use, simply returns the expanded record if there is an expand query param.
Expand All @@ -16,3 +16,28 @@ export const realtimeStoreExpand = async <T extends Pick<Record, 'id'>>(
expand
? await collection.getOne<T>(record.id, typeof expand === 'string' ? { expand } : undefined)
: record;

export const reconcileOptionalFields = (queryParams: BaseQueryParams | undefined) => {
if (
queryParams &&
'fields' in queryParams &&
typeof queryParams.fields === 'string' &&
queryParams.fields.length > 0
) {
// it is ok to split by comma since pocketbase doesn't allow collection fields to contain commas
const fields = queryParams.fields.split(',');
let shouldJoin = false;
if (fields.findIndex((field) => field === 'id') === -1) {
fields.push('id');
shouldJoin = true;
}
if (fields.findIndex((field) => field === 'updated') === -1) {
fields.push('updated');
shouldJoin = true;
}
if (shouldJoin) {
queryParams.fields = fields.join(',');
}
}
return queryParams;
};
14 changes: 8 additions & 6 deletions src/lib/queries/collection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import type {
RecordSubscription
} from 'pocketbase';

import { realtimeStoreExpand } from '../internal';
import { realtimeStoreExpand, reconcileOptionalFields } from '../internal';
import { collectionKeys } from '../query-key-factory';
import type { CollectionQueryPrefetchOptions, CollectionStoreOptions } from '../types';

Expand All @@ -31,7 +31,7 @@ const collectionStoreCallback = async <
queryKey: TQueryKey,
subscription: RecordSubscription<T>,
collection: RecordService,
queryParams: RecordListQueryParams | undefined = undefined,
queryParams: Pick<RecordListQueryParams, 'expand'> | undefined = undefined,
sortFunction?: (a: T, b: T) => number,
filterFunction?: (value: T, index: number, array: T[]) => boolean,
filterFunctionThisArg?: any
Expand Down Expand Up @@ -100,21 +100,23 @@ const collectionStoreCallback = async <
* Meant for SSR use, simply returns all the records from a collection. See [TanStack's documentation](https://tanstack.com/query/v4/docs/svelte/ssr#using-initialdata) and this project's README.md for some examples.
*
* @param collection The collection from which to get all the records.
* @param [options.queryParams] The query params that will be passed on to `getFullList`.
* @param [options.queryParams] The query params that will be passed on to `getFullList`. If you use `fields` to specify optional fields, note that `id` and `updated` will be added to it since the library uses them internally.
* @returns The initial data required for a collection query, i.e. an array of Pocketbase records.
*/
export const createCollectionQueryInitialData = async <
T extends Pick<Record, 'id' | 'updated'> = Pick<Record, 'id' | 'updated'>
>(
collection: RecordService,
{ queryParams = undefined }: { queryParams?: RecordListQueryParams }
): Promise<Array<T>> => [...(await collection.getFullList<T>(queryParams))];
): Promise<Array<T>> => [
...(await collection.getFullList<T>(reconcileOptionalFields(queryParams)))
];

/**
* Meant for SSR use, allows for prefetching queries on the server so that data is already available in the cache, and no initial fetch occurs client-side. See [TanStack's documentation](https://tanstack.com/query/v4/docs/svelte/ssr#using-prefetchquery) and this project's README.md for some examples.
*
* @param collection The collection from which to get all the records.
* @param [options.queryParams] The query params are simply passed on to `getFullList` for the initial data fetch, and `getOne` for realtime updates. If the `expand` key is provided, the record is expanded every time a realtime update is received.
* @param [options.queryParams] The query params are simply passed on to `getFullList` for the initial data fetch, and `getOne` for realtime updates. If the `expand` key is provided, the record is expanded every time a realtime update is received. If you use `fields` to specify optional fields, note that `id` and `updated` will be added to it since the library uses them internally.
* @param [options.queryKey] Provides the query key option for TanStack Query. By default, uses the `collectionKeys` function from this package.
* @param [options.staleTime] Provides the stale time option for TanStack Query. By default, `Infinity` since the query receives realtime updates. Note that the package will take care of automatically marking the query as stale when the last subscriber unsubscribes from this query.
* @param [options] The rest of the options are passed to the `prefetchQuery` function from TanStack Query, this library has no defaults for them.
Expand Down Expand Up @@ -150,7 +152,7 @@ export const createCollectionQueryPrefetch = <
* - If a `create` action is received via the realtime subscription, the new record is added to the end of the query's data array before the `filterFunction` and `sortFunction` run.
*
* @param collection The collection from which to get all the records.
* @param [options.queryParams] The query params are simply passed on to `getFullList` for the initial data fetch, and `getOne` for realtime updates. If the `expand` key is provided, the record is expanded every time a realtime update is received.
* @param [options.queryParams] The query params are simply passed on to `getFullList` for the initial data fetch, and `getOne` for realtime updates. If the `expand` key is provided, the record is expanded every time a realtime update is received. If you use `fields` to specify optional fields, note that `id` and `updated` will be added to it since the library uses them internally.
* @param [options.sortFunction] `compareFn` from `Array.prototype.sort` that runs when an action is received via the realtime subscription. This is used since Pocketbase realtime subscriptions does not support `sort` in `queryParams`.
* @param [options.filterFunction] `predicate` from `Array.prototype.filter` that runs when an action is received via the realtime subscription. This is used since Pocketbase realtime subscriptions does not support `filter` in `queryParams`.
* @param [options.filterFunctionThisArg] `thisArg` from `Array.prototype.filter` that runs when an action is received via the realtime subscription. This is used since Pocketbase realtime subscriptions does not support `filter` in `queryParams`.
Expand Down
14 changes: 8 additions & 6 deletions src/lib/queries/infinite-collection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import {

import { produce, setAutoFreeze, type Draft } from 'immer';

import { realtimeStoreExpand } from '../internal';
import { realtimeStoreExpand, reconcileOptionalFields } from '../internal';
import { collectionKeys } from '../query-key-factory';
import type { InfiniteCollectionStoreOptions, InfiniteQueryPrefetchOptions } from '../types';

Expand All @@ -33,7 +33,7 @@ const infiniteCollectionStoreCallback = async <
subscription: RecordSubscription<T>,
collection: RecordService,
perPage: number,
queryParams: RecordListQueryParams | undefined = undefined,
queryParams: Pick<RecordListQueryParams, 'expand'> | undefined = undefined,
sortFunction?: (a: T, b: T) => number,
filterFunction?: (value: T, index: number, array: T[]) => boolean,
filterFunctionThisArg?: any
Expand Down Expand Up @@ -231,7 +231,7 @@ const infiniteCollectionStoreCallback = async <
* @param collection The collection from which to get paginated records.
* @param [options.page] The page that will be passed on to `getList`. By default, `1`.
* @param [options.perPage] The per page that will be passed on to `getList`. By default, `20`.
* @param [options.queryParams] The query params that will be passed on to `getList`.
* @param [options.queryParams] The query params that will be passed on to `getList`. If you use `fields` to specify optional fields, note that `id` and `updated` will be added to it since the library uses them internally.
* @returns The initial data required for a collection query, i.e. an array of Pocketbase records.
*/
export const infiniteCollectionQueryInitialData = async <
Expand All @@ -243,15 +243,17 @@ export const infiniteCollectionQueryInitialData = async <
perPage = 20,
queryParams = undefined
}: { page?: number; perPage?: number; queryParams?: RecordListQueryParams } = {}
): Promise<ListResult<T>> => ({ ...(await collection.getList<T>(page, perPage, queryParams)) });
): Promise<ListResult<T>> => ({
...(await collection.getList<T>(page, perPage, reconcileOptionalFields(queryParams)))
});

/**
* Meant for SSR use, allows for prefetching queries on the server so that data is already available in the cache, and no initial fetch occurs client-side. See [TanStack's documentation](https://tanstack.com/query/v4/docs/svelte/ssr#using-prefetchquery) and this project's README.md for some examples.
*
* @param collection The collection from which to get paginated records.
* @param [options.page] The page that will be passed on to `getList`. By default, `1`.
* @param [options.perPage] The per page that will be passed on to `getList`. By default, `20`.
* @param [options.queryParams] The query params are simply passed on to `getList` for the initial data fetch, and `getOne` for realtime updates. If the `expand` key is provided, the record is expanded every time a realtime update is received.
* @param [options.queryParams] The query params are simply passed on to `getList` for the initial data fetch, and `getOne` for realtime updates. If the `expand` key is provided, the record is expanded every time a realtime update is received. If you use `fields` to specify optional fields, note that `id` and `updated` will be added to it since the library uses them internally.
* @param [options.queryKey] Provides the query key option for TanStack Infinite Query. By default, uses the `collectionKeys` function from this package.
* @param [options.staleTime] Provides the stale time option for TanStack Infinite Query. By default, `Infinity` since the query receives realtime updates. Note that the package will take care of automatically marking the query as stale when the last subscriber unsubscribes from this query.
* @param [options] The rest of the options are passed to the `prefetchQuery` function from TanStack Infinite Query, this library has no defaults for them.
Expand Down Expand Up @@ -294,7 +296,7 @@ export const infiniteCollectionQueryPrefetch = <
* @param collection The collection from which to get paginated records.
* @param [options.page] The page that will be passed on to `getList`. By default, `1`.
* @param [options.perPage] The per page that will be passed on to `getList`. By default, `20`.
* @param [options.queryParams] The query params are simply passed on to `getFullList` for the initial data fetch, and `getOne` for realtime updates. If the `expand` key is provided, the record is expanded every time a realtime update is received.
* @param [options.queryParams] The query params are simply passed on to `getFullList` for the initial data fetch, and `getOne` for realtime updates. If the `expand` key is provided, the record is expanded every time a realtime update is received. If you use `fields` to specify optional fields, note that `id` and `updated` will be added to it since the library uses them internally.
* @param [options.keepCurrentPageOnly] Only keeps data from the current page of the infinite query, and discards the rest of the data when a page is changed.
* @param [options.sortFunction] `compareFn` from `Array.prototype.sort` that runs when an action is received via the realtime subscription. This is used since Pocketbase realtime subscriptions does not support `sort` in `queryParams`.
* @param [options.filterFunction] `predicate` from `Array.prototype.filter` that runs when an action is received via the realtime subscription. This is used since Pocketbase realtime subscriptions does not support `filter` in `queryParams`.
Expand Down
12 changes: 6 additions & 6 deletions src/lib/queries/record.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import type {
RecordSubscription
} from 'pocketbase';

import { realtimeStoreExpand } from '../internal';
import { realtimeStoreExpand, reconcileOptionalFields } from '../internal';
import { collectionKeys } from '../query-key-factory';
import type { QueryPrefetchOptions, RecordStoreOptions } from '../types';

Expand All @@ -27,7 +27,7 @@ const createRecordQueryCallback = async <
queryKey: TQueryKey,
subscription: RecordSubscription<T>,
collection: RecordService,
queryParams: RecordQueryParams | undefined = undefined
queryParams: Pick<RecordQueryParams, 'expand'> | undefined = undefined
) => {
let data = queryClient.getQueryData<T | null>(queryKey);

Expand Down Expand Up @@ -63,7 +63,7 @@ const createRecordQueryCallback = async <
*
* @param collection The collection from which to get the record.
* @param id The `id` of the record to get from the collection.
* @param [options.queryParams] The query params that will be passed on to `getOne`.
* @param [options.queryParams] The query params that will be passed on to `getOne`. If you use `fields` to specify optional fields, note that `id` and `updated` will be added to it since the library uses them internally.
* @returns The initial data required for a record query, i.e. the Pocketbase record.
*/
export const createRecordQueryInitialData = <
Expand All @@ -72,14 +72,14 @@ export const createRecordQueryInitialData = <
collection: RecordService,
id: string,
{ queryParams = undefined }: { queryParams?: RecordQueryParams }
): Promise<T> => collection.getOne<T>(id, queryParams);
): Promise<T> => collection.getOne<T>(id, reconcileOptionalFields(queryParams));

/**
* Meant for SSR use, allows for prefetching queries on the server so that data is already available in the cache, and no initial fetch occurs client-side. See [TanStack's documentation](https://tanstack.com/query/v4/docs/svelte/ssr#using-prefetchquery) and this project's README.md for some examples.
*
* @param collection The collection from which to get the record.
* @param id The `id` of the record to get from the collection.
* @param [options.queryParams] The query params are simply passed on to `getOne` and if the `expand` key is provided, the record is expanded every time a realtime update is received.
* @param [options.queryParams] The query params are simply passed on to `getOne` and if the `expand` key is provided, the record is expanded every time a realtime update is received. If you use `fields` to specify optional fields, note that `id` and `updated` will be added to it since the library uses them internally.
* @param [options.queryKey] Provides the query key option for TanStack Query. By default, uses the `collectionKeys` function from this package.
* @param [options.staleTime] Provides the stale time option for TanStack Query. By default, `Infinity` since the query receives realtime updates. Note that the package will take care of automatically marking the query as stale when the last subscriber unsubscribes from this query.
* @param [options] The rest of the options are passed to the `prefetchQuery` function from TanStack Query, this library has no defaults for them.
Expand Down Expand Up @@ -117,7 +117,7 @@ export const createRecordQueryPrefetch = <
*
* @param collection The collection from which to get the record.
* @param id The `id` of the record to get from the collection.
* @param [options.queryParams] The query params are simply passed on to `getOne` and if the `expand` key is provided, the record is expanded every time a realtime update is received.
* @param [options.queryParams] The query params are simply passed on to `getOne` and if the `expand` key is provided, the record is expanded every time a realtime update is received. If you use `fields` to specify optional fields, note that `id` and `updated` will be added to it since the library uses them internally.
* @param [options.disableRealtime] Provides an option to disable realtime updates to the Pocketbase record. By default, `false` since we want the Pocketbase record to be updated in realtime. If set to `true`, a realtime subscription to the Pocketbase server is never sent. Don't forget to set `options.staleTime` to a more appropriate value than `Infinity` you disable realtime updates.
* @param [options.invalidateQueryOnRealtimeError] Provides an option to invalidate the query if a realtime error occurs. By default, `true` since if a realtime error occurs, the query's data would be stale.
* @param [options.onRealtimeUpdate] This function is called with the realtime action every time an realtime action is received.
Expand Down
Loading

0 comments on commit f5c1603

Please sign in to comment.