Skip to content
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
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ pnpm install
pnpm dev
```

This starts the app at `http://localhost:1430`. By default it connects to the public STUN server included below, so peer-to-peer collaboration works out of the box; run your own [signaling worker](./signaling) if you want to self-host that piece too.
This starts the app at `http://localhost:1430`. By default it connects to public y-webrtc signaling relays and the public STUN server included below, so peer-to-peer collaboration works out of the box; run your own [signaling worker](./signaling) if you want to self-host that piece too.

### Scripts

Expand All @@ -43,7 +43,7 @@ Copy `app/.env.example` to `app/.env.local` and adjust as needed:
| Variable | Purpose | Default |
| --- | --- | --- |
| `VITE_HOMEPAGE` | Where the wordmark links | `https://subscript.to` |
| `VITE_SIGNALING_URL` | WebRTC signaling endpoint | `ws://localhost:8787` (local `wrangler dev`) |
| `VITE_SIGNALING_URL` | WebRTC signaling endpoints, comma-separated | `wss://y-webrtc-signaling.fly.dev,wss://y-webrtc.fly.dev` |
| `VITE_STUN_URL` | STUN server for NAT traversal | `stun:stun.l.google.com:19302` |
| `VITE_TURN_URL` / `VITE_TURN_USERNAME` / `VITE_TURN_CREDENTIAL` | Optional TURN relay for peers behind restrictive NATs | unset |

Expand Down
9 changes: 5 additions & 4 deletions app/.env.example
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
# Homepage link behind the wordmark. Defaults to https://subscript.to when unset.
VITE_HOMEPAGE=https://subscript.to

# WebRTC signaling endpoint. Defaults to the public y-webrtc relay so Write
# works out of the box. Point this at your own deployed Cloudflare Worker
# (see ../signaling) or `wrangler dev`'s local URL if you'd rather self-host.
VITE_SIGNALING_URL=wss://y-webrtc-eu.fly.dev
# WebRTC signaling endpoints, comma-separated. Defaults to two public y-webrtc
# relays so Write works out of the box; peers connect to every listed relay.
# Point this at your own deployed Cloudflare Worker (see ../signaling) or
# `wrangler dev`'s local URL if you'd rather self-host.
VITE_SIGNALING_URL=wss://y-webrtc-signaling.fly.dev,wss://y-webrtc.fly.dev

# STUN is used to discover a public IP for direct peer connections. The Google
# STUN server below is free and requires no setup; swap in your own if you'd
Expand Down
20 changes: 20 additions & 0 deletions app/src/lib/config.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { describe, expect, it } from "vitest";
import { defaultConfig, mergeConfig, signalingUrls } from "./config";

describe("signaling configuration", () => {
it("defaults to the reachable public y-webrtc relays", () => {
expect(signalingUrls(defaultConfig.signalingUrl)).toEqual([
"wss://y-webrtc-signaling.fly.dev",
"wss://y-webrtc.fly.dev",
]);
});

it("no longer defaults to the offline y-webrtc-eu relay", () => {
expect(defaultConfig.signalingUrl).not.toContain("y-webrtc-eu.fly.dev");
});

it("splits comma-separated overrides and drops blanks", () => {
const config = mergeConfig({ signalingUrl: " wss://a.example , ,wss://b.example " });
expect(signalingUrls(config.signalingUrl)).toEqual(["wss://a.example", "wss://b.example"]);
});
});
8 changes: 7 additions & 1 deletion app/src/lib/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,17 @@ export type WriteConfig = {

export const defaultConfig: WriteConfig = {
homepage: "https://subscript.to",
signalingUrl: "wss://y-webrtc-eu.fly.dev",
signalingUrl: "wss://y-webrtc-signaling.fly.dev,wss://y-webrtc.fly.dev",
stunUrl: "stun:stun.l.google.com:19302",
subscriptEnabled: false,
};

export const signalingUrls = (value: string) =>
value
.split(",")
.map((url) => url.trim())
.filter(Boolean);

export const mergeConfig = (overrides?: Partial<WriteConfig>): WriteConfig => {
const defined = Object.fromEntries(
Object.entries(overrides ?? {}).filter(([, value]) => value !== undefined),
Expand Down
7 changes: 2 additions & 5 deletions app/src/lib/project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { IndexeddbPersistence } from "y-indexeddb";
import { WebrtcProvider } from "y-webrtc";
import * as Y from "yjs";
import { transformAnnotations } from "./annotation_ranges";
import type { WriteConfig } from "./config";
import { signalingUrls, type WriteConfig } from "./config";
import type { ScreenplayParagraph } from "./fdx";
import { blankParagraph } from "./fdx";
import type { DeviceIdentity, Signed } from "./identity";
Expand Down Expand Up @@ -800,10 +800,7 @@ export class LocalProject {

connect(room: string) {
this.provider?.destroy();
const signaling = this.config.signalingUrl
.split(",")
.map((url) => url.trim())
.filter(Boolean);
const signaling = signalingUrls(this.config.signalingUrl);
const iceServers: RTCIceServer[] = [{ urls: this.config.stunUrl }];
if (this.config.turnUrl) {
iceServers.push({
Expand Down
4 changes: 2 additions & 2 deletions signaling/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,6 @@ Use that URL as `VITE_SIGNALING_URL` when building the app.

## Do you need to self-host this?

No. By default `VITE_SIGNALING_URL` points at the public `wss://y-webrtc-eu.fly.dev` relay, so Write works out of the box without deploying anything.
No. By default `VITE_SIGNALING_URL` points at the public `wss://y-webrtc-signaling.fly.dev` and `wss://y-webrtc.fly.dev` relays, so Write works out of the box without deploying anything. These are community-run relays with no uptime guarantee; for production, deploy your own worker.

Write is local-first: your script never leaves your browser except peer-to-peer over WebRTC. This worker (or the public relay) only helps two browsers find each other; it never sees document content. If you'd rather not depend on a third-party relay, deploy your own copy with the steps above and point `VITE_SIGNALING_URL` at it.
Write is local-first: your script never leaves your browser except peer-to-peer over WebRTC. This worker (or the public relays) only helps two browsers find each other; it never sees document content. If you'd rather not depend on a third-party relay, deploy your own copy with the steps above and point `VITE_SIGNALING_URL` at it.
Loading