diff --git a/examples/write-patterns/patterns/4-through-the-db/index.tsx b/examples/write-patterns/patterns/4-through-the-db/index.tsx
index ca072b1d8c..1b3ec880a8 100644
--- a/examples/write-patterns/patterns/4-through-the-db/index.tsx
+++ b/examples/write-patterns/patterns/4-through-the-db/index.tsx
@@ -31,7 +31,7 @@ await pglite.electric.syncShapeToTable({
url: `${ELECTRIC_URL}/v1/shape`,
table: 'todos',
},
- shapeKey: 'todos',
+ shapeKey: 'p4_todos',
table: 'p4_todos_synced',
primaryKey: ['id'],
})
@@ -110,7 +110,7 @@ function ThroughTheDB() {
- 4. Through the DB sync
+ 4. Through the DB
diff --git a/examples/write-patterns/patterns/4-through-the-db/sync.ts b/examples/write-patterns/patterns/4-through-the-db/sync.ts
index 8334f8623b..9fc214fe21 100644
--- a/examples/write-patterns/patterns/4-through-the-db/sync.ts
+++ b/examples/write-patterns/patterns/4-through-the-db/sync.ts
@@ -49,6 +49,8 @@ export default class LocalChangeSynchronizer {
console.log('start')
this.#unsubscribe = await this.#db.listen('p4_changes', this.handle.bind(this))
+
+ this.process()
}
/*
diff --git a/examples/write-patterns/shared/app/db.ts b/examples/write-patterns/shared/app/db.ts
index 79ae25620b..cef8387bcd 100644
--- a/examples/write-patterns/shared/app/db.ts
+++ b/examples/write-patterns/shared/app/db.ts
@@ -2,11 +2,13 @@ import { PGlite } from '@electric-sql/pglite'
import { PGliteWithLive, live } from '@electric-sql/pglite/live'
import { electricSync } from '@electric-sql/pglite-sync'
-const pglite: PGliteWithLive = await PGlite.create({
- extensions: {
- electric: electricSync(),
- live,
- },
-})
+const pglite: PGliteWithLive = await PGlite.create(
+ 'idb://electric-write-patterns', {
+ extensions: {
+ electric: electricSync(),
+ live
+ }
+ }
+)
export default pglite
\ No newline at end of file
diff --git a/examples/write-patterns/shared/backend/api.js b/examples/write-patterns/shared/backend/api.js
index 7389090d3e..bd202ec0bd 100644
--- a/examples/write-patterns/shared/backend/api.js
+++ b/examples/write-patterns/shared/backend/api.js
@@ -22,7 +22,7 @@ const idSchema = z.string().uuid()
const createSchema = z.object({
id: z.string().uuid(),
title: z.string(),
- created_at: z.string(),
+ created_at: z.string()
})
const updateSchema = z.object({
completed: z.boolean()
@@ -37,7 +37,11 @@ const createTodo = async (id, title, created_at) => {
VALUES ($1, $2, false, $3)
`
- const params = [id, title, created_at]
+ const params = [
+ id,
+ title,
+ created_at
+ ]
return await db.query(sql, params)
}
@@ -63,7 +67,7 @@ const deleteTodo = async (id) => {
return await db.query(sql, params)
}
-// Expose the API.
+// Expose the shared REST API to create, update and delete todos.
app.post(`/todos`, async (req, res) => {
let data
@@ -123,6 +127,67 @@ app.delete(`/todos/:id`, async (req, res) => {
return res.status(200).json({ status: 'OK' })
})
+// And expose a `POST /changes` route specifically to support the
+// through the DB sync pattern.
+
+const transactionsSchema = z.array(
+ z.object({
+ id: z.string(),
+ changes: z.array(
+ z.object({
+ operation: z.string(),
+ value: z.object({
+ id: z.string().uuid(),
+ title: z.string().optional(),
+ completed: z.boolean().optional(),
+ created_at: z.string().optional()
+ })
+ })
+ )
+ })
+)
+
+app.post(`/changes`, async (req, res) => {
+ let data
+ try {
+ data = transactionsSchema.parse(req.body)
+ }
+ catch (err) {
+ return res.status(400).json({ errors: err.errors })
+ }
+
+ try {
+ await db.query('BEGIN')
+
+ data.forEach((tx) => {
+ tx.changes.forEach(({operation, value}) => {
+ switch (operation) {
+ case 'insert':
+ createTodo(value.id, value.title, value.created_at)
+ break
+
+ case 'update':
+ updateTodo(value.id, value.completed)
+ break
+
+ case 'delete':
+ deleteTodo(value.id)
+ break
+ }
+ })
+ })
+
+ await db.query('COMMIT')
+ }
+ catch (err) {
+ await db.query('ROLLBACK')
+
+ return res.status(500).json({ errors: err })
+ }
+
+ return res.status(200).json({ status: 'OK' })
+})
+
// Start the server
app.listen(PORT, () => {
console.log(`Server listening at http://localhost:${PORT}`)
diff --git a/examples/write-patterns/shared/migrations/01-create-todos.sql b/examples/write-patterns/shared/migrations/01-create-todos.sql
index 71df8d7d73..8bdd835474 100644
--- a/examples/write-patterns/shared/migrations/01-create-todos.sql
+++ b/examples/write-patterns/shared/migrations/01-create-todos.sql
@@ -6,7 +6,7 @@ CREATE TABLE IF NOT EXISTS todos (
created_at TIMESTAMP WITH TIME ZONE NOT NULL
);
--- Insert a todo to get started.
+-- Insert some todos to get started.
INSERT INTO todos (
id,
title,