Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Switch from NextJS -> Vite / plain React for demos #83

Merged
merged 27 commits into from
Mar 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
aab8ce4
Switch from NextJS -> Vite for supabase-todolist demo.
rkistner Feb 28, 2024
45ba14a
Some demo cleanup.
rkistner Mar 5, 2024
5582445
Merge remote-tracking branch 'origin/main' into todolist-demo-vite
rkistner Mar 5, 2024
58ac056
Fix null-check issues.
rkistner Mar 5, 2024
1fe6521
Rename nextjs-supabase-todolist -> react-supabase-todolist.
rkistner Mar 5, 2024
493979f
Add a basic Next.JS example again.
rkistner Mar 5, 2024
6fb26d9
Migrate Yjs demo to vite.
rkistner Mar 5, 2024
1c1de76
Rename yjs-nextjs-supabase-text-collab ->
rkistner Mar 5, 2024
f99714a
Add missing files.
rkistner Mar 5, 2024
57aeb14
Merge remote-tracking branch 'origin/main' into todolist-demo-vite
rkistner Mar 5, 2024
261b2a2
Fixes.
rkistner Mar 5, 2024
ddf48a0
Minor cleanup.
rkistner Mar 5, 2024
f82d6ad
let -> const
rkistner Mar 6, 2024
d14f9d9
Add back PWA support; fix readme.
rkistner Mar 6, 2024
6353003
PWA support for Yjs demo.
rkistner Mar 6, 2024
790206d
Tweaks.
rkistner Mar 6, 2024
e685599
Merge remote-tracking branch 'origin/todolist-demo-vite' into todolis…
rkistner Mar 6, 2024
880ef16
Fix some null-check issues.
rkistner Mar 7, 2024
19729bb
Use development tokens for example-nextjs.
rkistner Mar 7, 2024
d73eb06
Merge remote-tracking branch 'origin/main' into todolist-demo-vite
rkistner Mar 7, 2024
33cdcc8
Bump some demo dependencies to avoid duplicates
rkistner Mar 11, 2024
612b133
Fix layouts to not have navbar on login/register.
rkistner Mar 11, 2024
2021010
Cleanup.
rkistner Mar 11, 2024
de63073
Update demos/example-nextjs/README.md
rkistner Mar 11, 2024
f8c211d
Merge remote-tracking branch 'origin/main' into todolist-demo-vite
rkistner Mar 11, 2024
6cb64af
Fix null-check issue.
rkistner Mar 11, 2024
1aed928
Add changeset.
rkistner Mar 11, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .changeset/fair-flowers-type.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@journeyapps/powersync-sdk-react-native": minor
"@journeyapps/powersync-sdk-common": minor
"@journeyapps/powersync-sdk-web": minor
---

Fix PowerSyncBackendConnector.fetchCredentials type to allow returning null
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,13 @@ _Bad connectivity is everywhere, and we're tired of it. PowerSync is on a missio

Demo applications are located in the [`demos/`](./demos/) directory. Also see our [Demo Apps / Example Projects](https://docs.powersync.com/resources/demo-apps-example-projects) gallery which lists all projects by the backend and client-side framework they use.

- [demos/nextjs-supabase-todolist](./demos/nextjs-supabase-todolist/): A Next.js to-do list example app using the PowerSync Web SDK and a Supabase backend.
- [demos/yjs-nextjs-supabase-text-collab](./demos/yjs-nextjs-supabase-text-collab/README.md): A Next.js real-time text editing collaboration example app powered by [Yjs](https://github.com/yjs/yjs) CRDTs and [Tiptap](https://tiptap.dev/), using the PowerSync Web SDK and a Supabase backend.
- [demos/react-supabase-todolist](./demos/react-supabase-todolist/): A React to-do list example app using the PowerSync Web SDK and a Supabase backend.
- [demos/yjs-react-supabase-text-collab](./demos/yjs-react-supabase-text-collab/README.md): A React real-time text editing collaboration example app powered by [Yjs](https://github.com/yjs/yjs) CRDTs and [Tiptap](https://tiptap.dev/), using the PowerSync Web SDK and a Supabase backend.
- [demos/react-native-supabase-todolist](./demos/react-native-supabase-todolist): A React Native to-do list example app using a Supabase backend.
- [demos/angular-supabase-todolist](./demos/angular-supabase-todolist/README.md) An Angular to-do list example app using the PowerSync Web SDK and a Supabase backend.
- [demos/example-webpack](./demos/example-webpack/README.md): A minimal example demonstrating bundling with Webpack.
- [demos/example-vite](./demos/example-vite/README.md): A minimal example demonstrating bundling with Vite.
- [demos/example-nextjs](./demos/example-nextjs/README.md): An example demonstrating setup with Next.js.

# Development

Expand Down
4 changes: 4 additions & 0 deletions demos/example-nextjs/.env.local.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Copy to .env.local, and complete these variables.
# Leave blank to test local-only.
NEXT_PUBLIC_POWERSYNC_URL=
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We probably need to mention setting this field (and renaming this file) in the Readme?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually getting sync to work would also require setting up a connector. The other two examples (example-vite and example-webpack) also don't have anything for that.

Do you think it's worth expanding all those examples, perhaps with instructions using temporary development tokens?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As newcomer, fake auth connection is good for learning and testing purposes.

NEXT_PUBLIC_POWERSYNC_TOKEN=
File renamed without changes.
10 changes: 10 additions & 0 deletions demos/example-nextjs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# PowerSync Next.js example

This example is built using [Next.js](https://nextjs.org/) and the [PowerSync JS web SDK](https://docs.powersync.com/client-sdk-references/js-web).

To see it in action:

1. Make sure to run `pnpm build:packages` in the root directory of this Git repo.
2. Copy `.env.local.template` to `.env.local`, and complete the environment variables. You can generate a [temporary development token](https://docs.powersync.com/usage/installation/authentication-setup/development-tokens), or leave blank to test with local-only data.
3. `pnpm start`
4. Open the localhost URL in the browser displayed in the terminal output.
56 changes: 56 additions & 0 deletions demos/example-nextjs/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
{
"name": "@journeyapps/powersync-example-nextjs",
"version": "0.0.1",
"private": true,
"scripts": {
"build": "next build",
"clean": "rm -rf .next",
"watch": "next dev",
"start": "next start",
"lint": "next lint"
},
"dependencies": {
"@emotion/react": "^11.11.4",
"@emotion/styled": "^11.11.0",
"@fontsource/roboto": "^5.0.12",
"@journeyapps/powersync-react": "workspace:*",
"@journeyapps/powersync-sdk-web": "workspace:*",
"@journeyapps/wa-sqlite": "~0.1.1",
"@lexical/react": "^0.11.3",
"@mui/icons-material": "^5.15.12",
"@mui/material": "^5.15.12",
"fast-glob": "^3.3.2",
"formik": "^2.4.5",
"highlight.js": "^11.9.0",
"js-logger": "^1.6.1",
"lato-font": "^3.0.0",
"lexical": "^0.11.3",
"lodash": "^4.17.21",
"lowlight": "^2.9.0",
"next": "14.1.0",
"next-images": "1.8.5",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"remixicon": "^2.5.0",
"shiki": "^0.10.1",
"simplify-js": "^1.2.4",
"uuid": "9.0.1"
},
"devDependencies": {
"@types/lodash": "^4.14.202",
"@types/node": "^20.11.25",
"@types/react": "^18.2.64",
"@types/react-dom": "^18.2.21",
"@types/uuid": "9.0.8",
"autoprefixer": "^10.4.18",
"babel-loader": "^9.1.3",
"css-loader": "^6.10.0",
"eslint": "^8.57.0",
"eslint-config-next": "14.0.0",
"postcss": "^8.4.35",
"sass": "^1.71.1",
"sass-loader": "^13.3.3",
"style-loader": "^3.3.4",
"tailwindcss": "^3.4.1"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import React from 'react';
import { CssBaseline } from '@mui/material';

import { ThemeProviderContainer } from '@/components/providers/ThemeProviderContainer';
import { DynamicSystemProvider } from '@/components/providers/DynamicSystemProvider';

import './globals.scss';
Expand All @@ -13,13 +12,11 @@ export default function RootLayout({ children }: { children: React.ReactNode })
return (
<html lang="en">
<head>
<title>PowerSync Yjs CRDT Text Collaboration Demo</title>
<title>PowerSync Next.js Example</title>
</head>
<body>
<CssBaseline />
<ThemeProviderContainer>
<DynamicSystemProvider>{children}</DynamicSystemProvider>
</ThemeProviderContainer>
<DynamicSystemProvider>{children}</DynamicSystemProvider>
</body>
</html>
);
Expand Down
49 changes: 49 additions & 0 deletions demos/example-nextjs/src/app/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
'use client';

import React, { useEffect } from 'react';
import { CircularProgress, Grid, ListItem, styled } from '@mui/material';
import { useRouter } from 'next/navigation';
import { usePowerSync, usePowerSyncWatchedQuery } from '@journeyapps/powersync-react';

export default function EntryPage() {
const router = useRouter();
const db = usePowerSync();
const customers = usePowerSyncWatchedQuery('SELECT id, name FROM customers');

useEffect(() => {
// Insert some test data
const names = ['Fred', 'Willard', 'Tina', 'Jake', 'Corey'];
const name = names[Math.floor(Math.random() * names.length)];
db.execute('INSERT INTO customers(id, name) VALUES(uuid(), ?)', [name]);
return () => { };
}, []);

return (
<S.MainGrid container>
<S.CenteredGrid item xs={12} md={6} lg={5}>
<div>
<h1>Customers</h1>
{
customers.map(c =>
<ListItem key={c.id}>{c.name}</ListItem>
)
}
{customers.length == 0 ? <CircularProgress /> : []}

</div>
</S.CenteredGrid>
</S.MainGrid>
);
}

namespace S {
export const CenteredGrid = styled(Grid)`
display: flex;
justify-content: center;
align-items: center;
`;

export const MainGrid = styled(CenteredGrid)`
min-height: 100vh;
`;
}
35 changes: 35 additions & 0 deletions demos/example-nextjs/src/components/providers/SystemProvider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
'use client';

import { AppSchema } from '@/library/powersync/AppSchema';
import { BackendConnector } from '@/library/powersync/BackendConnector';
import { PowerSyncContext } from '@journeyapps/powersync-react';
import { WASQLitePowerSyncDatabaseOpenFactory } from '@journeyapps/powersync-sdk-web';
import { CircularProgress } from '@mui/material';
import Logger from 'js-logger';
import React, { Suspense } from 'react';

Logger.useDefaults();
Logger.setLevel(Logger.DEBUG);

const powerSync = new WASQLitePowerSyncDatabaseOpenFactory({
dbFilename: 'powersync2.db',
schema: AppSchema,
flags: {
disableSSRWarning: true
}
}).getInstance()
const connector = new BackendConnector();

powerSync.connect(connector);

export const SystemProvider = ({ children }: { children: React.ReactNode }) => {
return (
<Suspense fallback={<CircularProgress />}>
<PowerSyncContext.Provider value={powerSync}>
{children}
</PowerSyncContext.Provider>
</Suspense>
);
};

export default SystemProvider;
13 changes: 13 additions & 0 deletions demos/example-nextjs/src/library/powersync/AppSchema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { column, Schema, TableV2 } from '@journeyapps/powersync-sdk-web';

const customers = new TableV2({
name: column.text,
created_at: column.text
});

export const AppSchema = new Schema({
customers
});

export type Database = (typeof AppSchema)['types'];
export type Customer = Database['customers'];
59 changes: 59 additions & 0 deletions demos/example-nextjs/src/library/powersync/BackendConnector.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { AbstractPowerSyncDatabase, BaseObserver, PowerSyncBackendConnector } from '@journeyapps/powersync-sdk-web';

export class BackendConnector implements PowerSyncBackendConnector {
private powersyncUrl: string | undefined;
private powersyncToken: string | undefined;

constructor() {
this.powersyncUrl = process.env.NEXT_PUBLIC_POWERSYNC_URL;
// This token is for development only.
// For production applications, integrate with an auth provider or custom auth.
this.powersyncToken = process.env.NEXT_PUBLIC_POWERSYNC_TOKEN;
}

async fetchCredentials() {
// TODO: Use an authentication service or custom implementation here.

if (this.powersyncToken == null || this.powersyncUrl == null) {
return null;
}

return {
endpoint: this.powersyncUrl,
token: this.powersyncToken
};
}

async uploadData(database: AbstractPowerSyncDatabase): Promise<void> {
const transaction = await database.getNextCrudTransaction();

if (!transaction) {
return;
}

try {
// TODO: Upload here

await transaction.complete();
} catch (error: any) {
if (shouldDiscardDataOnError(error)) {
// Instead of blocking the queue with these errors, discard the (rest of the) transaction.
//
// Note that these errors typically indicate a bug in the application.
// If protecting against data loss is important, save the failing records
// elsewhere instead of discarding, and/or notify the user.
console.error(`Data upload error - discarding`, error);
await transaction.complete();
} else {
// Error may be retryable - e.g. network error or temporary server error.
// Throwing an error here causes this call to be retried after a delay.
throw error;
}
}
}
}

function shouldDiscardDataOnError(error: any) {
// TODO: Ignore non-retryable errors here
return false;
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,5 @@
}
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
"exclude": ["node_modules"],
"references": [
{
"path": "../../packages/powersync-sdk-web"
}
]
"exclude": ["node_modules"]
}
4 changes: 3 additions & 1 deletion demos/example-vite/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@ export default defineConfig({
outDir: '../dist',
rollupOptions: {
input: 'src/index.html'
}
},
emptyOutDir: true
},
envDir: '..', // Use this dir for env vars, not 'src'.
optimizeDeps: {
// Don't optimize these packages as they contain web workers and WASM files.
// https://github.com/vitejs/vite/issues/11672#issuecomment-1415820673
Expand Down
6 changes: 1 addition & 5 deletions demos/example-webpack/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,7 @@ let PowerSync;
const openDatabase = async () => {
PowerSync = new WASQLitePowerSyncDatabaseOpenFactory({
schema: AppSchema,
dbFilename: 'test.sqlite',
flags: {
// This is disabled once CSR+SSR functionality is verified to be working correctly
disableSSRWarning: true
}
dbFilename: 'test.sqlite'
}).getInstance();

await PowerSync.init();
Expand Down
74 changes: 0 additions & 74 deletions demos/nextjs-supabase-todolist/README.md

This file was deleted.

Loading
Loading