Skip to content

Latest commit

 

History

History
182 lines (144 loc) · 11.2 KB

File metadata and controls

182 lines (144 loc) · 11.2 KB

Next Editor

Next Editor Logo

Interactive Code Recording & Replay

Next Editor is a browser-based collaborative lesson editor and replay engine for real coding projects. It combines Monaco, a multi-file workspace, Yjs live rooms, WebContainer-backed runtime playback, rrweb preview capture, an in-preview HTTP API client, synchronized slides, captions, optional instructor camera capture, and streamed .ne recordings that can begin playback before the full file has downloaded. The same Cloudflare deployment also hosts the authenticated /learn catalog, publishing workflow, playlists, and private collaboration assets.

Overview

  • Multi-file workspace editing with file and folder management in the sidebar, plus drag-and-drop upload of local assets (images, video, audio, fonts).
  • Starter templates for common stacks, switchable from the editor header: HTML / CSS, React, Vue, Solid, Svelte, and HTMX + Express.
  • Two lesson surfaces:
    • Runtime lessons (React, Vue, Solid, Svelte, HTMX + Express) run inside WebContainers with preview, terminal, and runtime dock state captured into the recording timeline.
    • The HTML/CSS lesson renders a lightweight static preview from local HTML, CSS, and JavaScript files.
  • Runtime preview is recorded and replayed with rrweb: the live DOM, scroll, input, and pointer all ride a single event stream, replayed by an rrweb Replayer driven from the recording timeline.
  • Runtime lessons also include an API client mode: a built-in HTTP client that sends requests to the running server inside the preview iframe (same-origin, no CORS) and records each request/response so they replay on the timeline.
  • Subtitles (captions) can be imported from .vtt/.srt files or shipped alongside a hosted .ne, and render as a time-synced overlay with per-language track selection.
  • Recording captures more than text deltas: it stores workspace changes, rrweb preview snapshots, API client requests/responses, slide events, cursor motion, runtime events, audio, and optional camera video.
  • Playback restores the recorded project state and replays it from a single timeline.
  • Import and export use the SCR3 .ne container.
  • Progressive loading lets /code?url=... start playing a recording from a partial download.
  • Authenticated collaboration rooms support owner/editor/viewer roles, offline Yjs edits, remote cursors, follow-host state, private binary assets, and host-only browser recording.
  • Opt-in, audio-only voice chat inside a live room runs over the direct Cloudflare Realtime SFU behind a room-scoped authenticated gateway; remote voice is never captured by recordings.
  • Published lessons, authors, search, and playlists run through a same-origin Cloudflare Worker; public lesson/playlist JSON uses Workers KV.

Current Capabilities

  • Monaco-powered editing across a real workspace.
  • Starter templates for React, Vue, Solid, Svelte, HTMX + Express, and HTML/CSS.
  • Local asset upload into the workspace, with content-addressed descriptors, object-URL previews, and IndexedDB-backed Blob storage.
  • Runtime-backed preview for framework and package-based Node lessons.
  • Static preview mode for HTML/CSS lessons.
  • rrweb-based capture and replay of the runtime preview (DOM, scroll, input, and pointer in one event stream).
  • In-preview HTTP API client for runtime lessons: method/path/headers/body composer, response viewer with status, timing, and size, and a request history — all captured and replayed.
  • Timeline replay for frames, cursor motion, slide transitions, preview snapshots, API client requests/responses, workspace events, and runtime events.
  • Subtitle (caption) overlay with .vtt/.srt import, hosted sibling caption files, multi-track language selection, and RTL support.
  • Variable-speed playback with pitch-preserving audio.
  • Portable .ne export and import.
  • Optional instructor camera recording with synced playback overlay.
  • Built-in reveal.js slide support.
  • Live Yjs collaboration with invitations, role enforcement, awareness, reconnect/bootstrap recovery, and content-addressed R2 assets.
  • Feature-flagged voice chat per room: join muted, explicit unmute, speaking indicators, and a mute that physically releases the microphone.
  • Authenticated lesson publishing, public author pages, search, and ordered playlists.

Browser Support

  • Chromium-based browsers are the supported target for the WebContainer-backed runtime lessons (React, Vue, Solid, Svelte, HTMX + Express, and Node) because WebContainers require modern browser APIs and cross-origin isolation.
  • The static HTML/CSS preview path works without the runtime dock when full WebContainer support is not needed.

Tech Stack

  • UI: React 19, Vite 8, Rolldown 1.0
  • Editor and state: Monaco Editor, XState 5
  • Runtime: @webcontainer/api
  • Preview capture/replay: rrweb
  • Slides: reveal.js
  • Audio: pitch-preserving variable-speed playback via @soundtouchjs/audio-worklet
  • Styling: Tailwind CSS 4, Motion
  • Recording/storage: SCR3 stream container, msgpack, fflate (zlib + zip)
  • Cloud platform: Cloudflare Workers + Hono, D1, R2, Workers KV, and Static Assets
  • Collaboration data plane: Yjs over binary WebSockets, room Durable Objects with SQLite, and QStash delayed-cleanup jobs
  • Voice media plane: partytracks/WebRTC to the Cloudflare Realtime SFU, coordinated by per-room voice Durable Objects (audio only, feature-flagged)
  • Quality checks: vite-plus, Oxlint, TypeScript native preview (tsgo)

Project Structure

  • src/core: recording/playback state machines, frame delta encoding, slide and preview types, and public editor APIs.
  • src/components: editor UI, preview surfaces, media controls, slides, runtime dock, and camera overlay.
  • src/contexts: editor, workspace, slides, runtime, and provider wiring.
  • src/storage: SCR3 codec, IndexedDB persistence, import/export helpers, and worker-backed decoding.
  • src/hooks: URL loading, live stream forwarding, workspace/runtime hooks, and app adapters.
  • src/collaboration: Yjs project schema, provider protocol, room lifecycle, and workspace adapter.
  • src/voice: voice-chat engine, state machine, partytracks adapter, audio sinks, and recorder privacy bridge.
  • public: static assets, wasm artifacts, fonts, and sample recordings.
  • infra: Hono Worker, D1 migrations, Cloudflare bindings, and browser auth/upload adapters.
  • tube: /learn catalog, lesson detail, authors, search, and playlists.

Local Development

Prerequisites

  • Bun
  • A Chromium-based browser for full runtime support

Install Dependencies

bun install

Start The App

vp dev

Routes:

  • Landing page: http://localhost:5173/
  • Editor: http://localhost:5173/code
  • Lesson catalog: http://localhost:5173/learn
  • System architecture: http://localhost:5173/architecture
  • Streamed sample recording: http://localhost:5173/code?url=/introduction.ne

Validation Commands

vp check --fix
vp check
vp build

Additional scripts:

vp test
vp preview

Recording And Storage Model

Next Editor records a timeline of delta-compressed editor frames plus timed side-channel events for slides, preview state, rrweb preview snapshots, API client requests/responses, workspace mutations, runtime events, cursor samples, audio, and optional camera video.

Recordings use the SCR3 .ne container as raw binary end-to-end — the exporter writes raw SCR3 bytes and the loader reads them directly, with no base64 wrapping. Content-addressed workspace assets ride in dedicated raw segments while project snapshots retain only descriptors; progressive readers persist those bytes and release the handoff buffer. SCR3 is append-only and prefix-decodable, which enables progressive playback from an incomplete download and live forwarding through recordingStreamSink. Caption tracks ride along in the SCR3 metadata, either inlined as parsed cues or referenced by captionFiles so a hosted .ne can load sibling .vtt/.srt files.

Streaming And Camera Notes

  • useUrlLoader progressively decodes larger SCR3 prefixes and updates playback in place through extendRecording.
  • Finalized SCR3 recordings carry workspace assets once, followed by time-clustered frame and event segments; audio and camera remain streamable sibling media files.
  • The audio playback actor can reattach a growing contiguous blob snapshot as more audio fragments arrive during progressive playback.
  • Camera capture is optional. Playback uses cameraStartOffsetMs to align the overlay video with the main timeline.

Subtitles (Captions)

  • Captions are imported from .vtt (WebVTT) or .srt (SubRip) files through the captions control in the media bar; the parser detects the format, strips cue tags, and normalizes/sorts cues.
  • The track language is inferred from the filename (e.g. lesson.es.vttes), and multiple tracks can be loaded — the captions button switches into a language menu when more than one track is present.
  • CaptionsOverlay renders the active cue against the live timeline, with binary-search cue lookup, right-to-left layout for RTL languages, and on/off plus language preference persisted in localStorage.
  • Hosted recordings can declare sibling caption files via captionFiles in the SCR3 metadata; useUrlLoader resolves and fetches them relative to the .ne URL (captions are never guessed from sibling filenames).

API Client

  • Runtime lessons (any WebContainer-backed stack — React, Vue, Solid, Svelte, HTMX + Express, Node) expose an API mode toggle in the preview chrome alongside the browser view.
  • The panel composes a request (method, path, headers, JSON/text body) and posts it into the running preview iframe through a same-origin message bridge, so requests hit the live server without CORS. Responses show status, status text, headers, body (pretty-printed when JSON), duration, and size, plus a request history you can re-inspect.
  • Each sent request, received response, request-tab switch, and history inspection is recorded as a preview event, so the API client interactions replay deterministically from the timeline without re-running the server.

Learn More

License

This project is licensed under the MIT License. See LICENSE.