Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add presence #2

Merged
merged 32 commits into from
Feb 18, 2020
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
21 changes: 21 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,24 @@ room.onUpdate(newDoc => {
console.log(newDoc);
});
```

## Server Side Rendering

To render on the server, you must include any headers that should be passed along to your
auth endpoint. In most cases, this is just your session cookie.

For example, in Next.js:

```ts
const room = client.room("my-room");

MyComponent.getInitialProps = async ctx => {
const { doc } = await room.init({
headers: {
cookie: ctx.req.headers
}
});

return { doc };
};
```
20 changes: 20 additions & 0 deletions errors/cant-access-auth-endpoint.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Failing network on the server

Example text:

```
Room Service can't access the auth endpoint.
```

## Why this error is happening

Your auth endpoint isn't setup correctly.

## How to fix this

Please confirm that:

1. You've made an [auth endpoint](https://www.roomservice.dev/docs/auth).
2. Your auth endpoint has a valid API key.
3. Your auth endpoint itself isn't logging any errors.
4. Your auth endpoint is pointed to the correct domain, for example, ensure it's not pointing to `localhost:3000` while running in production.
19 changes: 19 additions & 0 deletions errors/server-side-no-network.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Failing network on the server

Example text:

```
Room Service can't access the auth endpoint on the server.
```

## Why this error is happening

Room Service can't access your auth endpoint when attempting to render on the server (SSR).

## How to fix this

The **most likely case** is that your auth endpoint isn't setup correctly. Please confirm that:

1. You've made an [auth endpoint](https://www.roomservice.dev/docs/auth).
2. Your auth endpoint has a valid API key.
3. Your auth endpoint itself isn't logging any errors.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@roomservice/browser",
"version": "0.3.2-0",
"version": "0.4.0-10",
"main": "dist/index",
"types": "dist/index",
"files": [
Expand Down
5 changes: 4 additions & 1 deletion src/authorize.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ interface RoomValue {

export default async function authorize(
authorizationUrl: string,
roomReference: string
roomReference: string,
headers?: Headers
) {
// Generates and then records a session token
const result = await ky.post(authorizationUrl, {
Expand All @@ -19,6 +20,8 @@ export default async function authorize(
}
},

headers: headers || undefined,

// This only works on sites that have setup DNS,
// or the debugger on roomservice.dev/app, which
// uses this SDK.
Expand Down
26 changes: 20 additions & 6 deletions src/client.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import RoomServiceClient from "./client";
import Offline from "./offline";
import Sockets from "./socket";
import { injectFakeSocket } from "./test-socket";
import { uniq } from "lodash";

const URL = "https://coolsite.com";
jest.mock("idb-keyval");
Expand Down Expand Up @@ -50,12 +51,19 @@ test("room gets called with bearer token", async () => {
});
const room = client.room("my-room");
await room.init();
const [url, args] = mock.calls[0];

expect(url).toBe("https://api.roomservice.dev");
const urls = mock.calls.map(([url]) => url);
const args = mock.calls.map(([_, args]) => args);

expect(uniq(urls.sort())).toStrictEqual(
[
"https://api.roomservice.dev/v1/doc",
"https://api.roomservice.dev/v1/presence"
].sort()
);

// @ts-ignore because bad typings make me sad
expect(args.transportOptions!.polling.extraHeaders.authorization).toBe(
expect(args[0].transportOptions.polling.extraHeaders.authorization).toBe(
"Bearer short-lived-token"
);
});
Expand All @@ -72,7 +80,7 @@ test("room.publish() can change a document", async () => {
await room.init();
sockets.emit("connect");

const newState = await room.publishDoc(prevState => {
const newState = await room.setDoc((prevState: any) => {
prevState.someOption = "hello!";
});

Expand All @@ -85,6 +93,12 @@ test("room.restore() attempts to restore from offline", async () => {
});
const room = client.room("my-room");

// @ts-ignore because trust me typescript, I am very wise and have
// been on this earth longer than thee, and I, the great programmer,
// know for certain that window.indexDB is, in fact, equal to
// wiggly-woggle-pop.
window.indexedDB = "wiggly-woggle-pop";

jest.spyOn(Offline, "getDoc").mockImplementation(async (ref, doc) => {
return save(from({ name: "offlinedoc" }));
});
Expand Down Expand Up @@ -122,10 +136,10 @@ test("room.onUpdateDoc callback tries to save the document to offline", async do
const room = client.room("my-room");

const cb = jest.fn();
room.onUpdateDoc(cb);
room.onSetDoc(cb);

// @ts-ignore private
const onUpdateSocket = room._onUpdateSocketCallback;
const onUpdateSocket = room._docClient._onUpdateSocketCallback;
expect(onUpdateSocket).toBeTruthy();

await room.init();
Expand Down
24 changes: 18 additions & 6 deletions src/client.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,30 @@
import RoomClient from "./room-client";
import { KeyValueObject } from "./types";
import { Obj } from "./types";

export default class RoomServiceClient {
private readonly _authorizationUrl: string;
private readonly _headers?: Headers;

constructor(parameters: { authUrl: string }) {
private readonly _roomPool: { [key: string]: RoomClient } = {};

constructor(parameters: { authUrl: string; headers?: Headers }) {
this._authorizationUrl = parameters.authUrl;
this._headers = parameters.headers;
}

room<T extends KeyValueObject>(roomReference: string, state?: T) {
return new RoomClient<T>({
room<T extends Obj>(roomReference: string, defaultDoc?: T) {
if (this._roomPool[roomReference]) {
return this._roomPool[roomReference];
}

const room = new RoomClient({
authUrl: this._authorizationUrl,
reference: roomReference,
state
roomReference,
defaultDoc,
headers: this._headers
});

this._roomPool[roomReference] = room;
return room;
}
}
Loading