Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
WIP
  • Loading branch information
kobiebotha committed Dec 23, 2024
1 parent 76fe38c commit d5412f2
Show file tree
Hide file tree
Showing 22 changed files with 2,653 additions and 0 deletions.
5 changes: 5 additions & 0 deletions demos/supabase-infinite-scroll/.env.local.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Copy this template: `cp .env.local.template .env.local`
# Edit .env.local and enter your Supabase and PowerSync project details.
VITE_SUPABASE_URL=https://foo.supabase.co
VITE_SUPABASE_ANON_KEY=foo
VITE_POWERSYNC_URL=https://foo.powersync.journeyapps.com
47 changes: 47 additions & 0 deletions demos/supabase-infinite-scroll/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.js
.yarn/install-state.gz

# testing
/coverage

# next.js
/.next/
/out/

# production
/build
# misc
.DS_Store
*.pem

# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# local env files
.env*.local

# vercel
.vercel

# typescript
*.tsbuildinfo
next-env.d.ts

# ide
.idea
.fleet
.vscode

# PWA
**/public/workbox-*.js
**/public/sw.js
**/public/swe-worker-*
**/public/worker-*.js
**/public/fallback-*.js
79 changes: 79 additions & 0 deletions demos/supabase-infinite-scroll/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# PowerSync + Supabase Web Demo: Infinite Scrolling

## Overview

Demo app illustrating various infinite scrolling strategies using lazy-load scenarios described in [Use Case Examples: Infinite Scrolling](https://docs.powersync.com/usage/use-case-examples/infinite-scrolling)

## Prerequisites

1. You will need to sign up for a PowerSync account and create an instance connected to Supabase. A step-by-step guide on Supabase<>PowerSync integration is available [here](https://docs.powersync.com/integration-guides/supabase).
1. Apply the contents of `Supabase.sql` in this repo to your Supabase project.
1. Enable Anonymous Sign-ins in Supabase (**Project Settings -> Authentication -> User Signups**)

## Getting Started

First install the project dependencies. Run the following command in the repo root:

```bash
pnpm install
pnpm build:packages
```

Then switch into this demo's directory:

```bash
cd demos/supabase-infinite-scroll
```

Set up the Environment variables: Copy the `.env.local.template` file:

```bash
cp .env.local.template .env.local
```

And then edit `.env.local` to insert your credentials for Supabase and PowerSync.

Run the development server:

```bash
pnpm dev
```

This will start the Vite development server. Open your browser and navigate to the URL provided in the terminal (usually [http://localhost:5173](http://localhost:5173)) to view the demo. Use the control buttons to toggle between scenarios and get a feel for the behavior.

## Specific Scenarios
This section provides an index to the various scenarios described in the [docs](https://docs.powersync.com/usage/use-case-examples/infinite-scrolling).

### Pre-sync all data and query the local database

* Implemented in [`src/dataSources/preSync.js`](src/dataSources/preSync.js)

### Control data sync using client parameters

* Implemented in [`src/dataSources/pagedSync.js`](src/dataSources/pagedSync.js)
* Uses the `paged_list` table in Postgres

### Client-side triggers a server-side function to flag data to sync

* Implemented in [`src/dataSources/triggerSync.js`](src/dataSources/triggerSync.js)
* Uses the `syncto_list` table in Postgres

### Sync limited data and then load more data from an API

* Not implemented. A trivial modification of `preSync.js` would suffice.
* Would also use the `syncto_list` table in Postgres

## Framework For Running Scenarios

### Page Framework Files
`styles.css`
`index.html`
`index.js`

### Virtual Listbox
`src/listBox/index.js`
`src/listBox/itemBuffer.js`

### Known Issues

* Sometimes when switching scenarios using the control buttons there is a remnant loading spinner. Simply scroll to dismiss it.
85 changes: 85 additions & 0 deletions demos/supabase-infinite-scroll/Supabase.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
-- Presync List
CREATE TABLE list (
id uuid DEFAULT gen_random_uuid() PRIMARY KEY NOT NULL,
text text NOT NULL,
created_at timestamp with time zone DEFAULT current_timestamp
);

DO $$
DECLARE
i INT;
page INT := 1;
current_timestamp TIMESTAMP := NOW();
BEGIN
FOR i IN 1..10000 LOOP
INSERT INTO list (text, created_at)
VALUES ('item ' || i, current_timestamp + (i || ' milliseconds')::INTERVAL);
IF i % 100 = 0 THEN page := page + 1; END IF;
END LOOP;
END $$;

-- Paged List
DROP TABLE IF EXISTS paged_list;

CREATE TABLE paged_list (
id uuid DEFAULT gen_random_uuid() PRIMARY KEY NOT NULL,
text text NOT NULL,
page integer,
created_at timestamp with time zone DEFAULT current_timestamp
);

DO $$
DECLARE
i INT;
page INT := 1;
current_timestamp TIMESTAMP := NOW();
BEGIN
FOR i IN 1..10000 LOOP
INSERT INTO paged_list (text, page, created_at)
VALUES ('item ' || i, page, current_timestamp + (i || ' milliseconds')::INTERVAL);
IF i % 100 = 0 THEN page := page + 1; END IF;
END LOOP;
END $$;

-- SyncTo List
CREATE TABLE syncto_list (
id uuid DEFAULT gen_random_uuid() PRIMARY KEY NOT NULL,
text text NOT NULL,
sync_to uuid[] NOT NULL,
created_at timestamp with time zone NOT NULL
);

DO $$
DECLARE
i INT;
page INT := 1;
current_timestamp TIMESTAMP := NOW();
BEGIN
FOR i IN 1..10000 LOOP
INSERT INTO syncto_list (text, sync_to, created_at)
VALUES ('item ' || i, ARRAY[]::UUID[], current_timestamp + (i || ' milliseconds')::INTERVAL);
IF i % 100 = 0 THEN page := page + 1; END IF;
END LOOP;
END $$;

CREATE OR REPLACE FUNCTION update_sync_to(start_value INT, end_value INT, user_uuid UUID)
RETURNS VOID AS $$
BEGIN
-- Add the UUID to sync_to for the specified range of rows
WITH ranked_rows AS (
SELECT id, ROW_NUMBER() OVER (ORDER BY created_at ASC) AS row_num
FROM syncto_list
)
UPDATE syncto_list
SET sync_to = CASE
WHEN sync_to IS NULL THEN ARRAY[user_uuid]
ELSE array_append(sync_to, user_uuid)
END
FROM ranked_rows
WHERE syncto_list.id = ranked_rows.id
AND ranked_rows.row_num BETWEEN start_value AND end_value;
END;
$$ LANGUAGE plpgsql;

-- Create Publication
CREATE PUBLICATION powersync FOR ALL TABLES;
49 changes: 49 additions & 0 deletions demos/supabase-infinite-scroll/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>PowerSync Infinite Scroll Demos</title>
<link rel="stylesheet" href="styles.css">
</head>

<body id="body">
<div id="app">


<div style="display: flex; flex-direction: column; align-items: center; width:250px">
<h2>Infinite Scroll Demos</h2>
</div>
<div class="content-wrapper">
<div id="listBox">
<div id="listItems"></div> <!-- This will scroll -->
</div>
<div id="spinner" class="spinner hidden"></div> <!-- Spinner stays fixed -->
<div class="button-container">
<h3 id="which">select method</h3>
<button id="arrayProvider">0: In-memory</button>
<button disabled id="preSyncProvider">1: Pre-Sync all data</button>
<button disabled id="pagedSyncProvider">2: Paged via client params</button>
<button disabled id="triggerSyncProvider">3: Server-side triggers</button>
<button disabled>4: Load from API (not implemented)</button>
</div>
</div>


<div>
<div style="width:fit-content; margin-left:auto; margin-right:auto;margin-top:10px;">
console output
</div>
<div id="console-list"></div>
</div>
</div>


<!-- <script src="https://cdn.jsdelivr.net/npm/eruda"></script>
<script>eruda.init();</script> -->

<script type="module" src="src/index.js"></script>
</body>

</html>
Loading

0 comments on commit d5412f2

Please sign in to comment.