Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/goknsh/svelte-query-pocketbase

TanStack Query wrappers around Pocketbase Realtime for Svelte
https://github.com/goknsh/svelte-query-pocketbase

pocketbase pocketbase-realtime realtime svelte svelte-store tanstack tanstack-query

Last synced: 3 months ago
JSON representation

TanStack Query wrappers around Pocketbase Realtime for Svelte

Awesome Lists containing this project

README

        

> [!WARNING]
> The repository is no longer being worked on, and the npm package has been deprecated. Feel free to fork and continue development.

# svelte-query-pocketbase

TanStack Query wrappers around Pocketbase Realtime for Svelte.

## Installation

```
npm i -D svelte-query-pocketbase
```

## Record Query

Creates a TanStack Query that updates a Pocketbase record in realtime. View the JSDoc for the relevant functions for more documentation on their available options.

### Simple Example

View Code

```svelte

import Pocketbase from 'pocketbase';
import { PUBLIC_POCKETBASE_URL } from '$env/static/public';

// Types generated from https://github.com/patmood/pocketbase-typegen
import { Collections, type SomeCollectionResponse } from '$lib/collections';

import { createRecordQuery } from 'svelte-query-pocketbase';

const pocketbase = new Pocketbase(PUBLIC_POCKETBASE_URL);

const someRecord = createRecordQuery<SomeCollectionResponse>(
pocketbase.collection(Collections.SomeCollection),
'some_id'
);

{#if $someRecord.data}

Fetched record:


{JSON.stringify($someRecord.data, null, 2)}

{:else if $someRecord.error}
{#if $someRecord.error.status === 404}

The record couldn't be found in the database.


{:else}

Something went wrong.


$someRecord.refetch()}>Try again
{/if}
{:else}

Loading...


{/if}
```

### With Query Params

View Code

```svelte

import Pocketbase from 'pocketbase';
import { PUBLIC_POCKETBASE_URL } from '$env/static/public';

// Types generated from https://github.com/patmood/pocketbase-typegen
import { Collections, type SomeCollectionResponse } from '$lib/collections';

import { createRecordQuery } from 'svelte-query-pocketbase';

const pocketbase = new Pocketbase(PUBLIC_POCKETBASE_URL);

const someRecord = createRecordQuery<SomeCollectionResponse>(
pocketbase.collection(Collections.SomeCollection),
'some_id',
{
queryParams: {
expand: 'some_field',
fields: 'some_field' // the library will internally add id and updated to this
}
}
);

{#if $someRecord.data}

Fetched record, with some_field expanded:


{JSON.stringify($someRecord.data, null, 2)}

{:else if $someRecord.error}
{#if $someRecord.error.status === 404}

The record couldn't be found in the database.


{:else}

Something went wrong.


$someRecord.refetch()}>Try again
{/if}
{:else}

Loading...


{/if}
```

### Using SSR

Read [TanStack Query's docs on this](https://tanstack.com/query/v4/docs/svelte/ssr) first. The examples below are modified versions of the examples on that page.

#### Using `initialData`

View Code

**src/routes/+page.ts**

```ts
import type { PageLoad } from './$types';

import Pocketbase from 'pocketbase';
import { PUBLIC_POCKETBASE_URL } from '$env/static/public';

// Types generated from https://github.com/patmood/pocketbase-typegen
import { Collections, type SomeCollectionResponse } from '$lib/collections';

import { createRecordQueryInitialData } from 'svelte-query-pocketbase';

export const load: PageLoad = async () => {
const someIdInitialData = await createRecordQueryInitialData(
pocketbase.collection(Collections.SomeCollection),
'some_id'
);
return { someIdInitialData };
};
```

**src/routes/+page.svelte**

```svelte

import Pocketbase from 'pocketbase';
import { PUBLIC_POCKETBASE_URL } from '$env/static/public';

import type { PageData } from './$types';
export let data: PageData;

// Types generated from https://github.com/patmood/pocketbase-typegen
import { Collections, type SomeCollectionResponse } from '$lib/collections';

import { createRecordQuery } from 'svelte-query-pocketbase';

const pocketbase = new Pocketbase(PUBLIC_POCKETBASE_URL);

const someRecord = createRecordQuery<SomeCollectionResponse>(
pocketbase.collection(Collections.SomeCollection),
'some_id',
{
initialData: data.someIdInitialData
}
);

```

#### Using `prefetchQuery`

View Code

**src/routes/+layout.ts**

_Same as TanStack Query's docs_

**src/routes/+layout.svelte**

_Same as TanStack Query's docs_

**src/routes/+page.ts**

```ts
import type { PageLoad } from './$types';

import Pocketbase from 'pocketbase';
import { PUBLIC_POCKETBASE_URL } from '$env/static/public';

// Types generated from https://github.com/patmood/pocketbase-typegen
import { Collections, type SomeCollectionResponse } from '$lib/collections';

import { createRecordQueryPrefetch } from 'svelte-query-pocketbase';

export const load: PageLoad = async ({ parent }) => {
const { queryClient } = await parent();

// As long as the same collection, id, and queryParams are supplied to
// `createRecordQueryPrefetch` and `createRecordQuery`, the library will
// generate the same `queryKey`s for both functions, and you need not specify one
await queryClient.prefetchQuery(
createRecordQueryPrefetch(
pocketbase.collection(Collections.SomeCollection),
'some_id'
)
);
};
```

**src/routes/+page.svelte**

```svelte

import Pocketbase from 'pocketbase';
import { PUBLIC_POCKETBASE_URL } from '$env/static/public';

import type { PageData } from './$types';
export let data: PageData;

// Types generated from https://github.com/patmood/pocketbase-typegen
import { Collections, type SomeCollectionResponse } from '$lib/collections';

import { createRecordQuery } from 'svelte-query-pocketbase';

const pocketbase = new Pocketbase(PUBLIC_POCKETBASE_URL);

// This data is cached by prefetchQuery in +page.ts so no fetch actually happens here
const someRecord = createRecordQuery<SomeCollectionResponse>(
pocketbase.collection(Collections.SomeCollection),
'some_id'
);

```

## Collection Query

Creates a TanStack Query that updates an array of Pocketbase records in realtime. View the JSDoc for the relevant functions for more documentation on their available options.

### Simple Example

View Code

```svelte

import Pocketbase from 'pocketbase';
import { PUBLIC_POCKETBASE_URL } from '$env/static/public';

// Types generated from https://github.com/patmood/pocketbase-typegen
import { Collections, type SomeCollectionResponse } from '$lib/collections';

import { createCollectionQuery } from 'svelte-query-pocketbase';

const pocketbase = new Pocketbase(PUBLIC_POCKETBASE_URL);

const someCollection = createCollectionQuery<SomeCollectionResponse>(
pocketbase.collection(Collections.SomeCollection)
);

{#if $someCollection.data}

Fetched collection:


{JSON.stringify($someCollection.data, null, 2)}

{:else if $someCollection.error}
{#if $someCollection.error.status === 404}

The collection couldn't be found in the database.


{:else}

Something went wrong.


$someCollection.refetch()}>Try again
{/if}
{:else}

Loading...


{/if}
```

### With Query Params

View Code

```svelte

import Pocketbase from 'pocketbase';
import { PUBLIC_POCKETBASE_URL } from '$env/static/public';

// Types generated from https://github.com/patmood/pocketbase-typegen
import { Collections, type SomeCollectionResponse } from '$lib/collections';

import { createCollectionQuery } from 'svelte-query-pocketbase';

const pocketbase = new Pocketbase(PUBLIC_POCKETBASE_URL);

const someCollection = createCollectionQuery<SomeCollectionResponse>(
pocketbase.collection(Collections.SomeCollection),
{
queryParams: {
expand: 'some_field',
sort: '-created', // sort by date created, descending
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
filterFunction: (record) => new Date(record.created) >= new Date("2022-01-01 00:00:00")
}
);

{#if $someCollection.data}


Fetched collection, with some_field expanded, sorted by date created (descending), and filtered
by date created after 2022-01-01 00:00:00:


{JSON.stringify($someCollection.data, null, 2)}

{:else if $someCollection.error}
{#if $someCollection.error.status === 404}

The collection couldn't be found in the database.


{:else}

Something went wrong.


$someCollection.refetch()}>Try again
{/if}
{:else}

Loading...


{/if}
```

### Using SSR

Read [TanStack Query's docs on this](https://tanstack.com/query/v4/docs/svelte/ssr) first. The examples below are modified versions of the examples on that page.

#### Using `initialData`

View Code

**src/routes/+page.ts**

```ts
import type { PageLoad } from './$types';

import Pocketbase from 'pocketbase';
import { PUBLIC_POCKETBASE_URL } from '$env/static/public';

// Types generated from https://github.com/patmood/pocketbase-typegen
import { Collections, type SomeCollectionResponse } from '$lib/collections';

import { createCollectionQueryInitialData } from 'svelte-query-pocketbase';

export const load: PageLoad = async () => {
const someCollectionInitialData = await createCollectionQueryInitialData(
pocketbase.collection(Collections.SomeCollection)
);
return { someCollectionInitialData };
};
```

**src/routes/+page.svelte**

```svelte

import Pocketbase from 'pocketbase';
import { PUBLIC_POCKETBASE_URL } from '$env/static/public';

import type { PageData } from './$types';
export let data: PageData;

// Types generated from https://github.com/patmood/pocketbase-typegen
import { Collections, type SomeCollectionResponse } from '$lib/collections';

import { createCollectionQuery } from 'svelte-query-pocketbase';

const pocketbase = new Pocketbase(PUBLIC_POCKETBASE_URL);

const someCollection = createCollectionQuery<SomeCollectionResponse>(
pocketbase.collection(Collections.SomeCollection),
{
initialData: data.someCollectionInitialData
}
);

```

#### Using `prefetchQuery`

View Code

**src/routes/+layout.ts**

_Same as TanStack Query's docs_

**src/routes/+layout.svelte**

_Same as TanStack Query's docs_

**src/routes/+page.ts**

```ts
import type { PageLoad } from './$types';

import Pocketbase from 'pocketbase';
import { PUBLIC_POCKETBASE_URL } from '$env/static/public';

// Types generated from https://github.com/patmood/pocketbase-typegen
import { Collections, type SomeCollectionResponse } from '$lib/collections';

import { createCollectionQueryPrefetch } from 'svelte-query-pocketbase';

export const load: PageLoad = async ({ parent }) => {
const { queryClient } = await parent();

// As long as the same collection, id, and queryParams are supplied to
// `createCollectionQueryPrefetch` and `createCollectionQuery`, the library will
// generate the same `queryKey`s for both functions, and you need not specify one
await queryClient.prefetchQuery(
createCollectionQueryPrefetch(
pocketbase.collection(Collections.SomeCollection)
)
);
};
```

**src/routes/+page.svelte**

```svelte

import Pocketbase from 'pocketbase';
import { PUBLIC_POCKETBASE_URL } from '$env/static/public';

import type { PageData } from './$types';
export let data: PageData;

// Types generated from https://github.com/patmood/pocketbase-typegen
import { Collections, type SomeCollectionResponse } from '$lib/collections';

import { createCollectionQuery } from 'svelte-query-pocketbase';

const pocketbase = new Pocketbase(PUBLIC_POCKETBASE_URL);

// This data is cached by prefetchQuery in +page.ts so no fetch actually happens here
const someCollection = createCollectionQuery<SomeCollectionResponse>(
pocketbase.collection(Collections.SomeCollection)
);

```

## Infinite Collection Query

Creates a TanStack Infinite Query that updates paginated Pocketbase records in realtime. View the JSDoc for the relevant functions for more documentation on their available options.

### Simple Example

View Code

```svelte

import Pocketbase from 'pocketbase';
import { PUBLIC_POCKETBASE_URL } from '$env/static/public';

// Types generated from https://github.com/patmood/pocketbase-typegen
import { Collections, type SomeCollectionResponse } from '$lib/collections';

import { createInfiniteCollectionQuery } from 'svelte-query-pocketbase';

const pocketbase = new Pocketbase(PUBLIC_POCKETBASE_URL);

const someInfiniteCollection = createInfiniteCollectionQuery<SomeCollectionResponse>(
pocketbase.collection(Collections.SomeCollection)
);

{#if $someInfiniteCollection.data}

Fetched infinite collection:


{JSON.stringify($someInfiniteCollection.data, null, 2)}

{#if $someInfiniteCollection.hasNextPage}
$someInfiniteCollection.fetchNextPage()}
disabled={$someInfiniteCollection.isFetchingNextPage}
>{$someInfiniteCollection.isFetchingNextPage
? 'Fetching next page...'
: 'Fetch next page'}
{/if}
{:else if $someInfiniteCollection.error}
{#if $someInfiniteCollection.error.status === 404}

The collection couldn't be found in the database.


{:else}

Something went wrong.


$someInfiniteCollection.refetch()}>Try again
{/if}
{:else}

Loading...


{/if}
```

### With Query Params

View Code

```svelte

import Pocketbase from 'pocketbase';
import { PUBLIC_POCKETBASE_URL } from '$env/static/public';

// Types generated from https://github.com/patmood/pocketbase-typegen
import { Collections, type SomeCollectionResponse } from '$lib/collections';

import { createInfiniteCollectionQuery } from 'svelte-query-pocketbase';

const pocketbase = new Pocketbase(PUBLIC_POCKETBASE_URL);

const someInfiniteCollection = createInfiniteCollectionQuery<SomeCollectionResponse>(
pocketbase.collection(Collections.SomeCollection),
{
queryParams: {
expand: 'some_field',
sort: '-created', // sort by date created, descending
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
filterFunction: (record) => new Date(record.created) >= new Date("2022-01-01 00:00:00")
}
);

{#if $someInfiniteCollection.data}


Fetched infinite collection, with some_field expanded, sorted by date created (descending), and
filtered by date created after 2022-01-01 00:00:00:


{JSON.stringify($someInfiniteCollection.data, null, 2)}

{#if $someInfiniteCollection.hasNextPage}
$someInfiniteCollection.fetchNextPage()}
disabled={$someInfiniteCollection.isFetchingNextPage}
>{$someInfiniteCollection.isFetchingNextPage
? 'Fetching next page...'
: 'Fetch next page'}
{/if}
{:else if $someInfiniteCollection.error}
{#if $someInfiniteCollection.error.status === 404}

The collection couldn't be found in the database.


{:else}

Something went wrong.


$someInfiniteCollection.refetch()}>Try again
{/if}
{:else}

Loading...


{/if}
```

### Using SSR

Read [TanStack Query's docs on this](https://tanstack.com/query/v4/docs/svelte/ssr) first. The examples below are modified versions of the examples on that page.

#### Using `initialData`

View Code

**src/routes/+page.ts**

```ts
import type { PageLoad } from './$types';

import Pocketbase from 'pocketbase';
import { PUBLIC_POCKETBASE_URL } from '$env/static/public';

// Types generated from https://github.com/patmood/pocketbase-typegen
import { Collections, type SomeCollectionResponse } from '$lib/collections';

import { infiniteCollectionQueryInitialData } from 'svelte-query-pocketbase';

export const load: PageLoad = async () => {
const someInfiniteCollectionInitialData =
await infiniteCollectionQueryInitialData(
pocketbase.collection(Collections.SomeCollection)
);
return { someInfiniteCollectionInitialData };
};
```

**src/routes/+page.svelte**

```svelte

import Pocketbase from 'pocketbase';
import { PUBLIC_POCKETBASE_URL } from '$env/static/public';

import type { PageData } from './$types';
export let data: PageData;

// Types generated from https://github.com/patmood/pocketbase-typegen
import { Collections, type SomeCollectionResponse } from '$lib/collections';

import { createInfiniteCollectionQuery } from 'svelte-query-pocketbase';

const pocketbase = new Pocketbase(PUBLIC_POCKETBASE_URL);

const someInfiniteCollection = createInfiniteCollectionQuery<SomeCollectionResponse>(
pocketbase.collection(Collections.SomeCollection),
{
initialData: data.someInfiniteCollectionInitialData
}
);

```

#### Using `prefetchQuery`

View Code

**src/routes/+layout.ts**

_Same as TanStack Query's docs_

**src/routes/+layout.svelte**

_Same as TanStack Query's docs_

**src/routes/+page.ts**

```ts
import type { PageLoad } from './$types';

import Pocketbase from 'pocketbase';
import { PUBLIC_POCKETBASE_URL } from '$env/static/public';

// Types generated from https://github.com/patmood/pocketbase-typegen
import { Collections, type SomeCollectionResponse } from '$lib/collections';

import { infiniteCollectionQueryPrefetch } from 'svelte-query-pocketbase';

export const load: PageLoad = async ({ parent }) => {
const { queryClient } = await parent();

// As long as the same collection, id, and queryParams are supplied to
// `infiniteCollectionQueryPrefetch` and `createCollectionQuery`, the library will
// generate the same `queryKey`s for both functions, and you need not specify one
await queryClient.prefetchQuery(
infiniteCollectionQueryPrefetch(
pocketbase.collection(Collections.SomeCollection)
)
);
};
```

**src/routes/+page.svelte**

```svelte

import Pocketbase from 'pocketbase';
import { PUBLIC_POCKETBASE_URL } from '$env/static/public';

import type { PageData } from './$types';
export let data: PageData;

// Types generated from https://github.com/patmood/pocketbase-typegen
import { Collections, type SomeCollectionResponse } from '$lib/collections';

import { createInfiniteCollectionQuery } from 'svelte-query-pocketbase';

const pocketbase = new Pocketbase(PUBLIC_POCKETBASE_URL);

// This data is cached by prefetchQuery in +page.ts so no fetch actually happens here
const someInfiniteCollection = createInfiniteCollectionQuery<SomeCollectionResponse>(
pocketbase.collection(Collections.SomeCollection)
);

```

## User Store

Svelte store wrapper around the authenticated Pocketbase user that updates in realtime.

### Using Default Auth Store

View Code

```svelte

import Pocketbase from 'pocketbase';
import { PUBLIC_POCKETBASE_URL } from '$env/static/public';

import { userStore, type KnownUser } from 'svelte-query-pocketbase';

const pocketbase = new Pocketbase(PUBLIC_POCKETBASE_URL);

interface CustomKnownUser extends KnownUser {
id: string;
name: string;
username: string;
avatar?: string;
}

const user = userStore<CustomKnownUser>(pocketbase, (authStore) => ({
isLoggedIn: true,
id: authStore.model?.id ?? '',
avatar: authStore.model?.avatar,
username: authStore.model?.username ?? ''
name: authStore.model?.name ?? '',
}));

{#if $user.isLoggedIn}

Welcome, {$user.name}:


{JSON.stringify($user, null, 2)}

{:else}

You are not logged in.


{/if}
```

### Using Local Auth Store

View Code

```svelte

import Pocketbase, { LocalAuthStore } from 'pocketbase';
import { PUBLIC_POCKETBASE_URL } from '$env/static/public';

import { userStore, type KnownUser } from 'svelte-query-pocketbase';

const pocketbase = new Pocketbase(PUBLIC_POCKETBASE_URL, new LocalAuthStore("authInfo"));

interface CustomKnownUser extends KnownUser {
id: string;
name: string;
username: string;
avatar?: string;
}

const user = userStore<CustomKnownUser, LocalAuthStore>(pocketbase, (authStore) => ({
isLoggedIn: true,
id: authStore.model?.id ?? '',
avatar: authStore.model?.avatar,
username: authStore.model?.username ?? ''
name: authStore.model?.name ?? '',
}));

{#if $user.isLoggedIn}

Welcome, {$user.name}:


{JSON.stringify($user, null, 2)}

{:else}

You are not logged in.


{/if}
```