feat: F5.5 large binary files as blobs on server F
From 16 KB a picture's or binary file's entry names its bytes by their SHA-256 instead of holding them; the bytes are on F, content-addressed (GET/POST /blobs with the session's grant, from the editor's origin, at most 16 MiB). A document's blob side says where they are: the editor's fetches and uploads, the room thread's asks F's main thread, and a start waits for the ones asked for; without a side everything stays in the document. Text stays Y.Text. A blob whose bytes are not there is never written back empty. A blob F has not got yet is asked for again a few times, and a running room reads late bytes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -4,10 +4,16 @@
|
||||
// rooms, each with a replica of its project's document: the document's
|
||||
// updates go both ways, a person's messages go in, the room's come out,
|
||||
// each for one person (a room tells its people apart; the main thread
|
||||
// numbers them).
|
||||
// numbers them). A room's large binary files (blobs) are F's: the thread
|
||||
// asks for the ones it has not got, and gives F the ones the simulation
|
||||
// makes before the document's change that names them.
|
||||
|
||||
import type { HostMessage } from '@mdg-filius/protocol';
|
||||
|
||||
/** How often, and how long apart, a thread asks again for a blob F has not got (yet). */
|
||||
export const BLOB_ASKS = 5;
|
||||
export const BLOB_ASK_AGAIN_MILLISECONDS = 1_000;
|
||||
|
||||
export type ToRoomThread =
|
||||
/** A room for a project, its document as it is now. */
|
||||
| { readonly type: 'open'; readonly room: string; readonly state: Uint8Array }
|
||||
@@ -19,10 +25,16 @@ export type ToRoomThread =
|
||||
/** The simulation stopped (what it left written back first); answered by `stopped`. */
|
||||
| { readonly type: 'stop'; readonly room: string }
|
||||
/** The room ended — stopped first with `writeBack`, else as it is (its project is gone); answered by `closed`. */
|
||||
| { readonly type: 'close'; readonly room: string; readonly writeBack: boolean };
|
||||
| { readonly type: 'close'; readonly room: string; readonly writeBack: boolean }
|
||||
/** The blobs asked for: those F has, and the names of those it has not. */
|
||||
| { readonly type: 'blobs'; readonly room: string; readonly blobs: readonly { readonly sha: string; readonly bytes: Uint8Array }[]; readonly missing: readonly string[] };
|
||||
|
||||
export type FromRoomThread =
|
||||
| { readonly type: 'doc'; readonly room: string; readonly update: Uint8Array }
|
||||
| { readonly type: 'host'; readonly room: string; readonly client: number; readonly message: HostMessage }
|
||||
| { readonly type: 'stopped'; readonly room: string }
|
||||
/** Blobs the document names that the thread has not got. */
|
||||
| { readonly type: 'needBlobs'; readonly room: string; readonly shas: readonly string[] }
|
||||
/** A blob the simulation made (before the change that names it). */
|
||||
| { readonly type: 'blob'; readonly room: string; readonly bytes: Uint8Array }
|
||||
| { readonly type: 'closed'; readonly room: string };
|
||||
|
||||
Reference in New Issue
Block a user