Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
37 changes: 37 additions & 0 deletions Caddyfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# global options
{
admin off # there's no need for the admin api in railway's environment
persist_config off # storage isn't persistent anyway
auto_https off # railway handles https for us, this would cause issues if left enabled
# runtime logs
log {
format json # set runtime log format to json mode
}
# server options
servers {
trusted_proxies static private_ranges 100.0.0.0/8 # trust railway's proxy
}
}

# site block, listens on the $PORT environment variable, automatically assigned by railway
:{$PORT:3000} {
# access logs
log {
format json # set access log format to json mode
}

# health check for railway
rewrite /health /*

# serve from the 'dist' folder (Vite builds into the 'dist' folder)
root * dist

# enable gzipping responses
encode gzip

# serve files from 'dist'
file_server

# if path doesn't exist, redirect it to 'index.html' for client side routing
try_files {path} /index.html
}
40 changes: 40 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Use the Node alpine official image
# https://hub.docker.com/_/node
FROM node:lts-alpine AS build

# Set config
ENV NPM_CONFIG_UPDATE_NOTIFIER=false
ENV NPM_CONFIG_FUND=false

# Create and change to the app directory.
WORKDIR /app

# Copy the files to the container image
COPY package*.json ./

# Install packages
RUN npm ci

# Copy local code to the container image.
COPY . ./

# Build the app.
RUN npm run build

# Use the Caddy image
FROM caddy

# Create and change to the app directory.
WORKDIR /app

# Copy Caddyfile to the container image.
COPY Caddyfile ./

# Copy local code to the container image.
RUN caddy fmt Caddyfile --overwrite

# Copy files to the container image.
COPY --from=build /app/dist ./dist

# Use Caddy to run/serve the app
CMD ["caddy", "run", "--config", "Caddyfile", "--adapter", "caddyfile"]
23 changes: 15 additions & 8 deletions eslint.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,28 @@ import globals from 'globals'
import reactHooks from 'eslint-plugin-react-hooks'
import reactRefresh from 'eslint-plugin-react-refresh'
import tseslint from 'typescript-eslint'
import { globalIgnores } from 'eslint/config'
import { defineConfig, globalIgnores } from 'eslint/config'

export default tseslint.config([
export default defineConfig([
globalIgnores(['dist']),
js.configs.recommended,
...tseslint.configs.recommended,
{
files: ['**/*.{ts,tsx}'],
extends: [
js.configs.recommended,
tseslint.configs.recommended,
reactHooks.configs['recommended-latest'],
reactRefresh.configs.vite,
],
plugins: {
'react-hooks': reactHooks,
'react-refresh': reactRefresh,
},
languageOptions: {
ecmaVersion: 2020,
globals: globals.browser,
},
rules: {
...reactHooks.configs.recommended.rules,
'react-refresh/only-export-components': [
'warn',
{ allowConstantExport: true },
],
},
},
])
49 changes: 26 additions & 23 deletions src/powersync/System.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ import {
createBaseLogger,
LogLevel,
PowerSyncDatabase,
SyncClientImplementation,
WASQLiteOpenFactory,
WASQLiteVFS
} from "@powersync/web";
import { AppSchema } from "./AppSchema";
import { connector } from "./SupabaseConnector";
Expand All @@ -11,17 +14,17 @@ logger.useDefaults();
logger.setLevel(LogLevel.DEBUG);

/**
* Default configuration - uses IndexedDB storage
* Default configuration AccessHandlePoolVFS - uses IndexedDB
* ✅ Use this for: Simple setup, most browsers
* ❌ Avoid if: You need Safari support or have stability issues
*/
export const powerSync = new PowerSyncDatabase({
schema: AppSchema,
database: {
dbFilename: 'example.db'
},
logger: logger
});
// export const powerSync = new PowerSyncDatabase({
// schema: AppSchema,
// database: {
// dbFilename: 'example.db'
// },
// logger: logger
// });

/**
* Alternative configuration with OPFS storage (Origin Private File System)
Expand All @@ -41,20 +44,20 @@ export const powerSync = new PowerSyncDatabase({
*
* 📚 Learn more: https://docs.powersync.com/client-sdk-references/javascript-web#sqlite-virtual-file-systems
*/
// export const powerSync = new PowerSyncDatabase({
// database: new WASQLiteOpenFactory({
// dbFilename: "exampleVFS.db",
// vfs: WASQLiteVFS.OPFSCoopSyncVFS, // Use AccessHandlePoolVFS for single-tab only
// flags: {
// enableMultiTabs: typeof SharedWorker !== "undefined",
// },
// }),
// flags: {
// enableMultiTabs: typeof SharedWorker !== "undefined",
// },
// schema: AppSchema,
// logger: logger,
// });
export const powerSync = new PowerSyncDatabase({
database: new WASQLiteOpenFactory({
dbFilename: "exampleVFS.db",
vfs: WASQLiteVFS.OPFSCoopSyncVFS, // Use AccessHandlePoolVFS for single-tab only
flags: {
enableMultiTabs: typeof SharedWorker !== "undefined",
},
}),
flags: {
enableMultiTabs: typeof SharedWorker !== "undefined",
},
schema: AppSchema,
logger: logger,
});

/**
* Quick Decision Guide:
Expand All @@ -69,4 +72,4 @@ export const powerSync = new PowerSyncDatabase({
await connector.signInAnonymously();

// Establish connection between PowerSync and the Supabase connector
powerSync.connect(connector);
powerSync.connect(connector, { clientImplementation: SyncClientImplementation.RUST });