Compare commits

..

2 Commits

Author SHA1 Message Date
Guido D'Orsi
11f1a9d5ba docs: add docs about worker storage 2025-01-30 13:05:53 +01:00
Guido D'Orsi
91265d62dd feat: add storage peer option to worker 2025-01-30 13:03:32 +01:00
12 changed files with 100 additions and 76 deletions

View File

@@ -0,0 +1,5 @@
---
"jazz-nodejs": patch
---
Add storage peer option

View File

@@ -27,24 +27,15 @@ jobs:
with:
submodules: true
- name: Enable corepack
run: corepack enable
- name: Install Node.js
uses: actions/setup-node@v3
with:
node-version-file: '.node-version'
cache: 'pnpm'
steps:
- name: Use Latest Corepack
run: |
echo "Before: corepack version => $(corepack --version || echo 'not installed')"
npm install -g corepack@latest
echo "After : corepack version => $(corepack --version)"
corepack enable
pnpm --version
- name: Enable corepack
run: corepack enable
- name: Get pnpm store directory
shell: bash
run: |

View File

@@ -18,23 +18,15 @@ jobs:
with:
submodules: true
- name: Enable corepack
run: corepack enable
- name: Install Node.js
uses: actions/setup-node@v3
with:
node-version-file: '.node-version'
cache: 'pnpm'
- name: Use Latest Corepack
run: |
echo "Before: corepack version => $(corepack --version || echo 'not installed')"
npm install -g corepack@latest
echo "After : corepack version => $(corepack --version)"
corepack enable
pnpm --version
- name: Enable corepack
run: corepack enable
- name: Get pnpm store directory
shell: bash
run: |

View File

@@ -16,23 +16,15 @@ jobs:
with:
submodules: true
- name: Enable corepack
run: corepack enable
- name: Install Node.js
uses: actions/setup-node@v3
with:
node-version-file: '.node-version'
cache: 'pnpm'
- name: Use Latest Corepack
run: |
echo "Before: corepack version => $(corepack --version || echo 'not installed')"
npm install -g corepack@latest
echo "After : corepack version => $(corepack --version)"
corepack enable
pnpm --version
- name: Enable corepack
run: corepack enable
- name: Get pnpm store directory
shell: bash
run: |

View File

@@ -20,23 +20,15 @@ jobs:
with:
submodules: true
- name: Enable corepack
run: corepack enable
- name: Install Node.js
uses: actions/setup-node@v3
with:
node-version-file: '.node-version'
cache: 'pnpm'
- name: Use Latest Corepack
run: |
echo "Before: corepack version => $(corepack --version || echo 'not installed')"
npm install -g corepack@latest
echo "After : corepack version => $(corepack --version)"
corepack enable
pnpm --version
- name: Enable corepack
run: corepack enable
- name: Get pnpm store directory
shell: bash
run: |

View File

@@ -22,23 +22,15 @@ jobs:
- name: Checkout Repo
uses: actions/checkout@v3
- name: Enable corepack
run: corepack enable
- name: Install Node.js
uses: actions/setup-node@v3
with:
node-version-file: '.node-version'
cache: 'pnpm'
- name: Use Latest Corepack
run: |
echo "Before: corepack version => $(corepack --version || echo 'not installed')"
npm install -g corepack@latest
echo "After : corepack version => $(corepack --version)"
corepack enable
pnpm --version
- name: Enable corepack
run: corepack enable
- name: Get pnpm store directory
shell: bash
run: |

View File

@@ -15,23 +15,15 @@ jobs:
- name: Checkout
uses: actions/checkout@v4
- name: Enable corepack
run: corepack enable
- name: Install Node.js
uses: actions/setup-node@v3
uses: actions/setup-node@v4
with:
node-version-file: '.node-version'
cache: 'pnpm'
- name: Use Latest Corepack
run: |
echo "Before: corepack version => $(corepack --version || echo 'not installed')"
npm install -g corepack@latest
echo "After : corepack version => $(corepack --version)"
corepack enable
pnpm --version
- name: Enable corepack
run: corepack enable
- name: Get pnpm store directory
shell: bash
run: |

View File

@@ -55,6 +55,22 @@ const { worker } = await startWorker({
- load/subscribe to CoValues: `MyCoValue.subscribe(id, worker, {...})`
- create CoValues & Groups `const val = MyCoValue.create({...}, { owner: worker })`
To make the worker state survive between restarts even on spotty connections, you can pass a `storage` parameter to `startWorker`:
<CodeGroup>
{/* prettier-ignore */}
```ts
import { startWorker } from 'jazz-nodejs';
import { SQLiteStorage } from 'cojson-storage-sqlite';
const { worker } = await startWorker({
AccountSchema: MyWorkerAccount,
syncServer: 'wss://cloud.jazz.tools/?key=you@example.com',
storage: await SQLiteStorage.asPeer({ filename: dbPath }),
});
```
</CodeGroup>
## Using CoValues instead of requests
Just like traditional backend functions, you can use Server Workers to do useful stuff (computations, calls to third-party APIs etc.) and put the results back into CoValues, which subscribed clients automatically get notified about.

View File

@@ -14,6 +14,7 @@
},
"devDependencies": {
"@types/ws": "8.5.10",
"cojson-storage-sqlite": "workspace:*",
"jazz-run": "workspace:*",
"typescript": "~5.6.2"
},

View File

@@ -1,4 +1,4 @@
import { AgentSecret, LocalNode, WasmCrypto } from "cojson";
import { AgentSecret, LocalNode, Peer, WasmCrypto } from "cojson";
import {
Account,
AccountClass,
@@ -14,6 +14,7 @@ type WorkerOptions<Acc extends Account> = {
accountID?: string;
accountSecret?: string;
syncServer?: string;
storage?: Peer;
AccountSchema?: AccountClass<Acc>;
};
@@ -46,6 +47,12 @@ export async function startWorker<Acc extends Account>(
throw new Error("Invalid accountSecret");
}
const peersToLoadFrom = [wsPeer.peer];
if (options.storage) {
peersToLoadFrom.push(options.storage);
}
const context = await createJazzContext({
auth: fixedCredentialsAuth({
accountID: accountID as ID<Acc>,
@@ -54,7 +61,7 @@ export async function startWorker<Acc extends Account>(
AccountSchema,
// TODO: locked sessions similar to browser
sessionProvider: randomSessionProvider,
peersToLoadFrom: [wsPeer.peer],
peersToLoadFrom,
crypto: await WasmCrypto.create(),
});
@@ -69,7 +76,6 @@ export async function startWorker<Acc extends Account>(
async function done() {
await context.account.waitForAllCoValuesSync();
wsPeer.done();
context.done();
}

View File

@@ -1,13 +1,15 @@
import { randomUUID } from "crypto";
import { tmpdir } from "os";
import { join } from "path";
import { SQLiteStorage } from "cojson-storage-sqlite";
import { createWorkerAccount } from "jazz-run/createWorkerAccount";
import { startSyncServer } from "jazz-run/startSyncServer";
import { CoMap, Group, InboxSender, co } from "jazz-tools";
import { CoMap, Group, InboxSender, Peer, co } from "jazz-tools";
import { describe, expect, onTestFinished, test } from "vitest";
import { startWorker } from "../index";
async function setup() {
const { server, port } = await setupSyncServer();
const syncServer = `ws://localhost:${port}`;
const { server, port, syncServer } = await setupSyncServer();
const { worker, done } = await setupWorker(syncServer);
@@ -27,7 +29,9 @@ async function setupSyncServer(defaultPort = "0") {
server.close();
});
return { server, port };
const syncServer = `ws://localhost:${port}`;
return { server, port, syncServer };
}
async function setupWorker(syncServer: string) {
@@ -180,4 +184,42 @@ describe("startWorker integration", () => {
await worker2.done();
newServer.close();
});
test("can use a persistent storage", async () => {
// Create a temporary database file
const dbPath = join(tmpdir(), `test-${randomUUID()}.db`);
const { syncServer, server, port } = await setupSyncServer();
const { accountID, agentSecret } = await createWorkerAccount({
name: "test-worker",
peer: syncServer,
});
const { worker, done } = await startWorker({
accountID: accountID,
accountSecret: agentSecret,
syncServer,
storage: await SQLiteStorage.asPeer({ filename: dbPath }),
});
const map = TestMap.create({ value: "test" }, { owner: worker });
await done();
server.close();
const { worker: worker2, done: done2 } = await startWorker({
accountID: accountID,
accountSecret: agentSecret,
syncServer,
storage: await SQLiteStorage.asPeer({ filename: dbPath }),
});
const mapOnWorker2 = await TestMap.load(map.id, worker2, {});
expect(mapOnWorker2?.value).toBe("test");
await setupSyncServer(port); // Starting a new sync server on the same port so the final waitForSync will work
await done2();
});
});

3
pnpm-lock.yaml generated
View File

@@ -1691,6 +1691,9 @@ importers:
'@types/ws':
specifier: 8.5.10
version: 8.5.10
cojson-storage-sqlite:
specifier: workspace:*
version: link:../cojson-storage-sqlite
jazz-run:
specifier: workspace:*
version: link:../jazz-run