Coder Social home page Coder Social logo

goknsh / svelte-pocketbase-stores Goto Github PK

View Code? Open in Web Editor NEW
0.0 1.0 0.0 172 KB

Async Svelte store wrappers around Pocketbase Realtime

License: MIT License

JavaScript 6.48% Shell 0.39% HTML 1.28% CSS 0.28% TypeScript 86.37% Svelte 5.20%
pocketbase realtime svelte svelte-store pocketbase-realtime

svelte-pocketbase-stores's Introduction

svelte-pocketbase-stores

Warning Package has been deprecated in favor of svelte-query-pocketbase

A set of asynchronous Svelte store wrappers for Pocketbase that update in realtime.

Installation

npm i -D svelte-pocketbase-stores

Record Store

Readable asynchronous Svelte store wrapper around a Pocketbase record that updates in realtime.

Notes:

  • When running server-side, this store returns the "empty version" version of this store, i.e. undefined.
  • If a delete action is received via the realtime subscription, the store's value changes to undefined.

Simple Example

<script lang="ts">
	import Pocketbase from 'pocketbase';
	import { safeLoad, recordStore } from 'svelte-pocketbase-stores';

	const pocketbase = new Pocketbase(process.env.PB_URL);

	// If you use https://github.com/patmood/pocketbase-typegen, you should do `recordStore<SomeCollectionResponse>(Collections.SomeCollection)`.
	const { state, ...record } = recordStore(pocketbase.collection('some_collection'), 'some_id');
</script>

{#await safeLoad(record)}
	<p>Loading...</p>
{:then loadedSafely}
	{#if !loadedSafely}
		Something went wrong...
	{:else}
		<!-- This will now update in realtime -->
		<pre>{JSON.stringify($record, null, 2)}</pre>
		<button on:click={() => record.reload()} disabled={$state.isReloading}
			>{$state.isReloading ? 'Reloading...' : 'Reload'}</button
		>
	{/if}
{/await}

With Query Params

<script lang="ts">
	import Pocketbase from 'pocketbase';
	import { safeLoad, recordStore } from 'svelte-pocketbase-stores';

	const pocketbase = new Pocketbase(process.env.PB_URL);

	// `queryParams` will be used during the inital fetch, and everytime an update is received via the realtime subscription
	const { state, ...record } = recordStore(pocketbase.collection('some_collection'), 'some_id', {
		queryParams: { expand: 'some_field' }
	});
</script>

{#await safeLoad(record)}
	<p>Loading...</p>
{:then loadedSafely}
	{#if !loadedSafely}
		Something went wrong...
	{:else}
		<!-- This will now update in realtime -->
		<pre>{JSON.stringify($record, null, 2)}</pre>
		<button on:click={() => record.reload()} disabled={$state.isReloading}
			>{$state.isReloading ? 'Reloading...' : 'Reload'}</button
		>
	{/if}
{/await}

Using SSR

When running server-side, this store returns the "empty version" version of this store, i.e. undefined, and then executes normally client-side. So you could use it normally as shown in the previous examples, or you could fetch the record server-side and pass it to recordStore. When done so, recordStore will skip the initial fetch and only create the realtime subscription client-side.

// +page.server.ts or +page.ts
export async function load() {
	const pocketbase = new Pocketbase(process.env.PB_URL);

	return {
		initial: await collection.getOne('some_id')
	};
}
<!-- +page.svelte -->
<script lang="ts">
	import Pocketbase from 'pocketbase';
	import { safeLoad, recordStore } from 'svelte-pocketbase-stores';
	import type { PageData } from './$types';

	export let data: PageData;

	const pocketbase = new Pocketbase(process.env.PB_URL);

	const { state, ...record } = recordStore(pocketbase.collection('some_collection'), 'some_id', {
		initial: data.initial
	});
</script>

{#await safeLoad(record)}
	<p>Loading...</p>
{:then loadedSafely}
	{#if !loadedSafely}
		Something went wrong...
	{:else}
		<!-- This will now update in realtime -->
		<pre>{JSON.stringify($record, null, 2)}</pre>
		<button on:click={() => record.reload()} disabled={$state.isReloading}
			>{$state.isReloading ? 'Reloading...' : 'Reload'}</button
		>
	{/if}
{/await}

Collection Store

Readable async Svelte store wrapper around an entire Pocketbase collection that updates in realtime.

  • When running server-side, this store returns the "empty version" version of this store, i.e. an empty array.
  • Create action received by the realtime subscription are added to the end of the returned store.
  • When an action is received via the realtime subscription, sortFunction runs first, then filterFunction runs.
  • This version of the collection store does not have pagination. Use paginatedCollectionStore if you want pagination.

Simple Example

<script lang="ts">
	import Pocketbase from 'pocketbase';
	import { safeLoad, collectionStore } from 'svelte-pocketbase-stores';

	const pocketbase = new Pocketbase(process.env.PB_URL);

	// If you use https://github.com/patmood/pocketbase-typegen, you should do `collectionStore<SomeRecordResponse>(Collections.SomeRecord)`.
	const { state, ...collection } = collectionStore(pocketbase.collection('test'));
</script>

{#await safeLoad(collection)}
	<p>Loading...</p>
{:then loadedSafely}
	{#if !loadedSafely}
		Something went wrong...
	{:else}
		<!-- This will now update in realtime. -->
		{#each $collection as record}
			<p>Record: '{record.id}'</p>
			<pre>{JSON.stringify(record, null, 2)}</pre>
		{/each}
		<button on:click={() => collection.reload()} disabled={$state.isReloading}
			>{$state.isReloading ? 'Reloading...' : 'Reload'}</button
		>
	{/if}
{/await}

With Query Params

<script lang="ts">
	import Pocketbase from 'pocketbase';
	import { safeLoad, collectionStore } from 'svelte-pocketbase-stores';

	const pocketbase = new Pocketbase(process.env.PB_URL);

	// If you wanted to sort, you can do so by adding `queryParams.sort` and `sortFunction`
	const { state, ...record } = collectionStore(pocketbase.collection('test'), {
		queryParams: { filter: 'verified = true' },
		filterFunction: (value, index, array) => value.verified
	});
</script>

{#await safeLoad(collection)}
	<p>Loading...</p>
{:then loadedSafely}
	{#if !loadedSafely}
		Something went wrong...
	{:else}
		<!-- This will now update in realtime. -->
		{#each $collection as record}
			<p>Record: '{record.id}'</p>
			<pre>{JSON.stringify(record, null, 2)}</pre>
		{/each}
		<button on:click={() => collection.reload()} disabled={$state.isReloading}
			>{$state.isReloading ? 'Reloading...' : 'Reload'}</button
		>
	{/if}
{/await}

With SSR

When running server-side, this store returns the "empty version" version of this store, i.e. an empty array, and then executes normally client-side. So you could use it normally as shown in the previous examples, or you could fetch the collection server-side and pass it to collectionStore. When done so, collectionStore will skip the initial fetch and only create the realtime subscription client-side.

// +page.server.ts or +page.ts
export async function load() {
	const pocketbase = new Pocketbase(process.env.PB_URL);

	return {
		initial: await collection.getFullList()
	};
}
<!-- +page.svelte -->
<script lang="ts">
	import Pocketbase from 'pocketbase';
	import { safeLoad, collectionStore } from 'svelte-pocketbase-stores';
	import type { PageData } from './$types';

	export let data: PageData;

	const pocketbase = new Pocketbase(process.env.PB_URL);

	const { state, ...record } = collectionStore(pocketbase.collection('some_collection'), {
		initial: data.initial
	});
</script>

{#await safeLoad(record)}
	<p>Loading...</p>
{:then loadedSafely}
	{#if !loadedSafely}
		Something went wrong...
	{:else}
		<!-- This will now update in realtime -->
		<pre>{JSON.stringify($record, null, 2)}</pre>
		<button on:click={() => record.reload()} disabled={$state.isReloading}
			>{$state.isReloading ? 'Reloading...' : 'Reload'}</button
		>
	{/if}
{/await}

Paginated Collection Store

Paginated readable async Svelte store wrapper around a Pocketbase collection that updates in realtime.

Notes:

  • When running server-side, this store returns the "empty version" version of this store, i.e. an empty ListResult with items set to [], totalItems and totalPages set to 0. setPage, next, and prev will also have no effects.
  • Pagination is only applied when we first get the data and anytime the page number is updated. Pagination is not applied to the realtime subscription, which gets updates from the entire collection.
  • When setPage, next, or prev is called, the returned store is reset to have only the items in the specified page.
  • Create action received by the realtime subscription are added to the end of the returned store.
  • When an action is received via the realtime subscription, sortFunction runs first, then filterFunction runs.
  • This version of the collection store does not get the entire collection. Use collectionStore if you want the entire collection.

Simple Example

<script lang="ts">
	import Pocketbase from 'pocketbase';
	import { safeLoad, paginatedCollectionStore } from 'svelte-pocketbase-stores';

	const pocketbase = new Pocketbase(process.env.PB_URL);

	// If you use https://github.com/patmood/pocketbase-typegen, you should do `collectionStore<SomeRecordResponse>(Collections.SomeRecord)`.
	const { state, ...collection } = paginatedCollectionStore(pocketbase.collection('test'), {
		page: 1,
		perPage: 20
	});
</script>

{#await safeLoad(collection)}
	<p>Loading...</p>
{:then loadedSafely}
	{#if !loadedSafely}
		Something went wrong...
	{:else}
		<!-- This will now update in realtime. -->
		{#each $collection.items as record}
			<p>Record: '{record.id}'</p>
			<pre>{JSON.stringify(record, null, 2)}</pre>
		{/each}
		<p>Current page: {$collection.page}</p>
		<p>Items per page: {$collection.perPage}</p>
		<p>Total items: {$collection.totalItems}</p>
		<p>Total pages: {$collection.totalPages}</p>
		<button on:click={() => collection.next()}>Next Page</button>
		<button on:click={() => collection.prev()}>Previous Page</button>
		<button on:click={() => collection.reload()} disabled={$state.isReloading}
			>{$state.isReloading ? 'Reloading...' : 'Reload'}</button
		>
	{/if}
{/await}

With Query Params

<script lang="ts">
	import Pocketbase from 'pocketbase';
	import { safeLoad, paginatedCollectionStore } from 'svelte-pocketbase-stores';

	const pocketbase = new Pocketbase(process.env.PB_URL);

	// If you wanted to sort, you can do so by adding `queryParams.sort` and `sortFunction`
	const { state, ...record } = paginatedCollectionStore(pocketbase.collection('test'), {
		queryParams: { filter: 'verified = true' },
		filterFunction: (value, index, array) => value.verified
	});
</script>

{#await safeLoad(collection)}
	<p>Loading...</p>
{:then loadedSafely}
	{#if !loadedSafely}
		Something went wrong...
	{:else}
		<!-- This will now update in realtime. -->
		{#each $collection.items as record}
			<p>Record: '{record.id}'</p>
			<pre>{JSON.stringify(record, null, 2)}</pre>
		{/each}
		<p>Current page: {$collection.page}</p>
		<p>Items per page: {$collection.perPage}</p>
		<p>Total items: {$collection.totalItems}</p>
		<p>Total pages: {$collection.totalPages}</p>
		<button on:click={() => collection.next()}>Next Page</button>
		<button on:click={() => collection.prev()}>Previous Page</button>
		<button on:click={() => collection.reload()} disabled={$state.isReloading}
			>{$state.isReloading ? 'Reloading...' : 'Reload'}</button
		>
	{/if}
{/await}

With SSR

When running server-side, this store returns the "empty version" version of this store, i.e. an empty ListResult with items set to [], totalItems and totalPages set to 0. setPage, next, and prev will also have no effects, and then executes normally client-side. So you could use it normally as shown in the previous examples, or you could fetch the collection server-side and pass it to paginatedCollectionStore. When done so, paginatedCollectionStore will skip the initial fetch and only create the realtime subscription client-side.

// +page.server.ts or +page.ts
export async function load() {
	const pocketbase = new Pocketbase(process.env.PB_URL);

	return {
		initial: await collection.getList(1, 20)
	};
}
<!-- +page.svelte -->
<script lang="ts">
	import Pocketbase from 'pocketbase';
	import { safeLoad, paginatedCollectionStore } from 'svelte-pocketbase-stores';
	import type { PageData } from './$types';

	export let data: PageData;

	const pocketbase = new Pocketbase(process.env.PB_URL);

	const { state, ...record } = paginatedCollectionStore(pocketbase.collection('some_collection'), {
		initial: data.initial,
		page: 1,
		perPage: 20
	});
</script>

{#await safeLoad(record)}
	<p>Loading...</p>
{:then loadedSafely}
	{#if !loadedSafely}
		Something went wrong...
	{:else}
		<!-- This will now update in realtime -->
		<pre>{JSON.stringify($record, null, 2)}</pre>
		<button on:click={() => record.reload()} disabled={$state.isReloading}
			>{$state.isReloading ? 'Reloading...' : 'Reload'}</button
		>
	{/if}
{/await}

svelte-pocketbase-stores's People

Contributors

github-actions[bot] avatar goknsh avatar renovate[bot] avatar

Watchers

 avatar

svelte-pocketbase-stores's Issues

Dependency Dashboard

This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.

Ignored or Blocked

These are blocked by an existing closed PR and will not be recreated unless you click a checkbox below.

Detected dependencies

github-actions
.github/workflows/release.yml
  • actions/checkout v3
  • actions/setup-node v3
  • pnpm/action-setup v2.2.4
  • actions/cache v3
  • changesets/action v1
npm
package.json
  • pocketbase ^0.10.0
  • svelte ^3.54.0
  • @changesets/changelog-github 0.4.8
  • @changesets/cli 2.26.0
  • @commitlint/cli 17.4.2
  • @commitlint/config-conventional 17.4.2
  • @commitlint/prompt-cli 17.4.2
  • @square/svelte-store 1.0.13
  • @sveltejs/adapter-node 1.1.4
  • @sveltejs/kit 1.3.2
  • @typescript-eslint/eslint-plugin 5.49.0
  • @typescript-eslint/parser 5.49.0
  • autoprefixer 10.4.13
  • eslint 8.33.0
  • eslint-config-prettier 8.6.0
  • eslint-plugin-svelte3 4.0.0
  • husky 8.0.3
  • lodash 4.17.21
  • postcss 8.4.21
  • prettier 2.8.3
  • prettier-plugin-svelte 2.9.0
  • svelte-check 3.0.3
  • tailwindcss 3.2.4
  • tslib 2.5.0
  • tsup 6.5.0
  • typescript 4.9.4
  • vite 4.0.4
  • vitest 0.28.3

  • Check this box to trigger a request for Renovate to run again on this repository

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.