Skip to content

Commit

Permalink
📝 update documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
nabeelvalley committed Mar 26, 2024
1 parent cf32b1f commit bfa883b
Show file tree
Hide file tree
Showing 3 changed files with 172 additions and 7 deletions.
175 changes: 170 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,179 @@ A library for developing offline-first web applications based on async data repl
- [ ] Method for initial sync and cleanup of bad entries
- [ ] Can we make it possible to sync to a file system, check: https://github.com/streetwriters/notesnook/tree/master/packages/streamable-fs

## Examples
# Examples

<details>

For usage take a look at the `src/examples` directory which has examples for:

1. `src/example/websocket-server` - A Node.js erver using an in-memory db and the websocket interfaces
2. `src/example/websocket-client-produce` - A Node.js client using the `WebsocketNodeJSConnector` that produces and replicates data from the server
3. `src/example/websocket-client-watch` - A Node.js client using the `WebsocketNodeJSConnector` that replicates data from the server
4. `src/example/browser` - Browser app using the `IndexedDBStore` and `WebsocketClientConnector`
1. `pnpm run example:server` - Example can be found in `src/example/websocket-server` - A Node.js erver using an in-memory db and the websocket interfaces

```ts
import { InMemoryOwnedStore } from "@sftsrv/synk/in-memory"
import { WebSocket, WebSocketServer } from "ws"
import { Changes } from "../types"
import { Notify } from "../async/types"
import { Data } from "./types"

let connections: WebSocket[] = []

const Command = Changes(Data)

const db = new InMemoryOwnedStore<Data>()
db.put({
version: 0,
type: "user",
id: "initial",
name: "initial user",
age: 5,
})

const wss = new WebSocketServer({ port: 8080 }, () =>
console.log("Server Listening")
)

wss.on("connection", (ws) => {
connections.push(ws)

ws.on("message", (data) => {
const message = Command.safeParse(JSON.parse(data.toString()))
if (!message.success) {
console.error(message.error)
return
}

console.log(message)

const command = message.data

db.applyChanges(command)
const changes = db.getChanges(command.version)
const newVersion = db.getVersion()

console.log("changes to client", changes)

// send latest data to the client that submitted the change
ws.send(JSON.stringify(changes))

// send a notification to all other clients that there is new data available
const notify: Notify = {
type: "notify",
version: newVersion,
}

connections.forEach((conn) => conn.send(JSON.stringify(notify)))
})

ws.on("open", () => {
console.log("open")
connections.push(ws)
})

ws.on("close", () => {
console.log("closed")
connections = connections.filter((conn) => conn !== ws)
})

ws.on("error", (err) => {
console.log(err)
connections = connections.filter((conn) => conn !== ws)
})
})
```

2. `pnpm run example:client-produce` - Example can be found in `src/example/websocket-client-produce` - A Node.js client using the `WebsocketNodeJSConnector` that produces and replicates data from the server

```ts
import { WebsocketNodeJSClientConnector } from "@sftsrv/synk/websocket"
import { InMemoryReplicatedStore } from "@sftsrv/synk/in-memory"
import WebSocket from "ws"
import { Data } from "./types"

const ws = new WebSocket("ws://localhost:8080")
const db = new InMemoryReplicatedStore<Data>()

const connector = new WebsocketNodeJSClientConnector(db, ws, console.log, Data)

setInterval(() => {
connector.putOne({
type: "post",
id: Date.now().toString(),
version: db.getVersion(),
userId: "1",
content: "some content",
})
}, 5000)
```

3. `pnpm run example:client-watch` - Example can be found in `src/example/websocket-client-watch` - A Node.js client using the `WebsocketNodeJSConnector` that replicates data from the server

```ts
import { InMemoryReplicatedStore } from "@sftsrv/synk/in-memory"
import { WebsocketNodeJSClientConnector } from "@sftsrv/synk/websocket"
import WebSocket from "ws"
import { Data } from "./types"

const ws = new WebSocket("ws://localhost:8080")
const db = new InMemoryReplicatedStore<Data>()

const connector = new WebsocketNodeJSClientConnector(db, ws, console.log, Data)
```

4. `pnpm run example:client-browser` - Example can be found in `src/example/browser` - Browser app using the `IndexedDBStore` and `WebsocketClientConnector`

```ts
import { IndexedDBStore } from "@sftsrv/synk/indexed-db"
import { WebsocketClientConnector } from "@sftsrv/synk/websocket"
import { Data } from "../types"

const changes = document.getElementById("changes") as HTMLDivElement
const database = document.getElementById("database") as HTMLDivElement
const add = document.getElementById("add") as HTMLButtonElement
const dlt = document.getElementById("delete") as HTMLButtonElement
const input = document.getElementById("input") as HTMLInputElement

const main = async () => {
console.log("Starting")
const db = new IndexedDBStore<Data>("my-store")

const ws = new WebSocket("ws://localhost:8080")

const connector = new WebsocketClientConnector<Data>(db, ws, async (data) => {
const version = await db.getVersion()
const store = await db.getAll()
changes.innerHTML = JSON.stringify(data, null, 2)
database.innerHTML = JSON.stringify({ version, store }, null, 2)
})

add.addEventListener("click", async () => {
connector.putOne({
version: await db.getVersion(),
type: "user",
id: new Date().toString(),
name: input.value || "",
age: Date.now(),
})

input.value = ""
})

dlt.addEventListener("click", async () => {
const data = await db.getAll()
const first = await data[0]

if (!first) {
return
}

await connector.delete(first)
})
}

main()
```

</details>

> Running any client example requires the server to also be running, the relevant commands for running the examples can be found in the `package.json` file
Expand Down
2 changes: 1 addition & 1 deletion jsr.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"$schema": "https://jsr.io/schema/config-file.v1.json",
"name": "@sftsrv/synk",
"version": "0.0.4",
"version": "0.0.5",
"exports": {
".": "./dist/index.js",
"./in-memory": "./dist/in-memory/index.js",
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@sftsv/synk",
"version": "0.0.3",
"version": "0.0.5",
"description": "A library for developing offline-first web applications based on async data replication and synchronization between clients and the server",
"type": "commonjs",
"module": "dist/index.js",
Expand Down

0 comments on commit bfa883b

Please sign in to comment.