Source
This app’s code and revision history are public. Download a copy or explore the files below.
Public
The app’s code and revision history are public.
Run it yourself
Take the whole tree and run it on your own machine. The download needs no account. Cloning needs a sign-in.
Download .zip
bounded clone 80ddb8c5df822e290afdd3c7
A copy you download is not bounded. The guarantees this app runs under - declared egress, proven invariants, writes that fail closed - live in the runtime serving this page, not in the files. What you get is auditable source you can read and run, with no runtime guarantees attached.
src/lib/protocol.ts
// What the two devices say to each other over the WebRTC data channel. Text messages are JSON;
// binary messages are the bytes of the file being sent, in order. Nothing here touches a server.
export interface FileInfo {
/** Position in the sender's list; stays the same when the sender adds more files. */
i: number;
name: string;
size: number;
type: string;
/** A folder, zipped on the sender's device as it is sent. */
zip?: boolean;
}
/** Sender to receiver. */
export type FromSender =
| { t: "files"; from: string; files: FileInfo[] }
// Every byte of file i from the requested offset has been sent.
| { t: "end"; i: number }
// SHA-256 of file i, in hex, worked out on the sender's device.
| { t: "sum"; i: number; hex: string }
| { t: "error"; i: number; message: string }
| { t: "bye" };
/** Receiver to sender. */
export type FromReceiver =
// Send file i, starting at byte `from` (above 0 after a dropped connection).
| { t: "get"; i: number; from: number }
// Bytes of file i saved so far: the sender stays at most a window ahead of this.
| { t: "ack"; i: number; at: number }
| { t: "sum"; i: number }
// Progress, so the sender can show it: bytes received and wanted, files done and wanted.
| { t: "progress"; got: number; total: number; done: number; count: number };
/** Bytes per data channel message. 64 KiB works between every browser. */
export const CHUNK = 64 * 1024;
/** How far the sender may run ahead of what the receiver has saved. */
export const WINDOW = 16 * 1024 * 1024;
export function parse<T>(raw: unknown): T | null {
if (typeof raw !== "string") return null;
try {
const m = JSON.parse(raw);
return m && typeof m.t === "string" ? (m as T) : null;
} catch {
return null;
}
}
Change history
Point OpenApps links to openapps.free
Bind agent address in policy
Retry release capture
Use OpenApps service URLs and add contribution strip
Bounded source sync
Bounded source sync
Bounded source sync