Some checks failed
build / lint (22) (push) Failing after 17s
build / test (22) (push) Failing after 8s
build / lint (23) (push) Failing after 2s
build / build (22) (push) Has been skipped
build / build (23) (push) Has been skipped
build / test (23) (push) Failing after 4s
docsearch / docsearch (push) Failing after 1s
107 lines
2.9 KiB
TypeScript
107 lines
2.9 KiB
TypeScript
import { Redis } from "@hocuspocus/extension-redis";
|
|
import type { onAwarenessChangeParameters } from "@hocuspocus/provider";
|
|
import test from "ava";
|
|
import {
|
|
newHocuspocus,
|
|
newHocuspocusProvider,
|
|
redisConnectionSettings,
|
|
} from "../utils/index.ts";
|
|
|
|
test("syncs existing awareness state", async (t) => {
|
|
const documentName = `test-${crypto.randomUUID()}`;
|
|
|
|
await new Promise(async (resolve) => {
|
|
const server = await newHocuspocus(t, {
|
|
extensions: [
|
|
new Redis({
|
|
...redisConnectionSettings,
|
|
identifier: `server${crypto.randomUUID()}`,
|
|
}),
|
|
],
|
|
});
|
|
|
|
const anotherServer = await newHocuspocus(t, {
|
|
extensions: [
|
|
new Redis({
|
|
...redisConnectionSettings,
|
|
identifier: `anotherServer${crypto.randomUUID()}`,
|
|
}),
|
|
],
|
|
});
|
|
|
|
const provider = newHocuspocusProvider(t, server, {
|
|
name: documentName,
|
|
onSynced() {
|
|
// Once we're set up, change the local Awareness state.
|
|
// The updated state then needs to go through Redis:
|
|
// provider -> server -> Redis -> anotherServer -> anotherProvider
|
|
provider.setAwarenessField("name", "first");
|
|
|
|
// Time to initialize a second provider, and connect to `anotherServer`
|
|
// to check whether existing Awareness states are synced through Redis.
|
|
newHocuspocusProvider(t, anotherServer, {
|
|
name: documentName,
|
|
onAwarenessChange({ states }: onAwarenessChangeParameters) {
|
|
// Wait until we have exactly 2 states with the expected data
|
|
const state = states.find(
|
|
(state) => state.clientId === provider.document.clientID,
|
|
);
|
|
if (states.length === 2 && state?.name === "first") {
|
|
t.pass();
|
|
resolve("done");
|
|
}
|
|
},
|
|
});
|
|
},
|
|
});
|
|
});
|
|
});
|
|
|
|
test("syncs awareness between servers and clients", async (t) => {
|
|
const documentName = `test-${crypto.randomUUID()}`;
|
|
|
|
await new Promise(async (resolve) => {
|
|
const server = await newHocuspocus(t, {
|
|
extensions: [
|
|
new Redis({
|
|
...redisConnectionSettings,
|
|
identifier: `server${crypto.randomUUID()}`,
|
|
}),
|
|
],
|
|
});
|
|
|
|
const anotherServer = await newHocuspocus(t, {
|
|
extensions: [
|
|
new Redis({
|
|
...redisConnectionSettings,
|
|
identifier: `anotherServer${crypto.randomUUID()}`,
|
|
}),
|
|
],
|
|
});
|
|
|
|
const provider = newHocuspocusProvider(t, anotherServer, {
|
|
name: documentName,
|
|
onSynced() {
|
|
// once we're setup change awareness on provider, to get to client it will
|
|
// need to pass through the pubsub extension:
|
|
// provider -> anotherServer -> pubsub -> server -> client
|
|
provider.setAwarenessField("name", "second");
|
|
},
|
|
});
|
|
|
|
newHocuspocusProvider(t, server, {
|
|
name: documentName,
|
|
onAwarenessChange: ({ states }: onAwarenessChangeParameters) => {
|
|
// Wait until we have exactly 2 states with the expected data
|
|
const state = states.find(
|
|
(state) => state.clientId === provider.document.clientID,
|
|
);
|
|
if (states.length === 2 && state?.name === "second") {
|
|
t.pass();
|
|
resolve("done");
|
|
}
|
|
},
|
|
});
|
|
});
|
|
});
|