Files
rdbms-playground/website/casts-src/casts.mjs
T
claude@clouddev1 a0dd202f67 feat(website): pace the projects cast + show table state; record cast guidelines
Projects cast review fixes:
- Pace the confirms: `save as` name and `new` now type, pause, then Enter as
  separate steps, so the viewer can read them before they execute.
- Insert `show tables` at each phase (before save / after `new` / after load),
  since the schema sidebar is hidden at 90 cols (ADR-0046) — the sequence now
  reads "books -> no tables -> books" so the round-trip is followable.

STYLE.md: new "Cast pacing & clarity" guidelines (beat-before-submit; surface
state where the sidebar would). Handoff item 2: chase these up across the
existing casts.
2026-06-11 10:56:46 +00:00

183 lines
8.1 KiB
JavaScript

/**
* Cast source definitions — the durable, human-readable source for the
* asciinema demos (ADR-website-001 §2). `pnpm casts` runs `generate.mjs`,
* which turns each definition into an autocast YAML and records it to
* `public/casts/<name>.cast`. Edit these and re-run to re-record as the app
* evolves; the `.cast` files are regenerable artifacts.
*
* Step kinds:
* { wait: ms } — pause (shown in the recording)
* { type: 'text', after: ms } — type the text + press Enter, then pause
* { type: 'text', enter: false } — type without pressing Enter
* { key: 'Tab'|'Enter'|'CtrlC', after } — press a single named key
*
* Every cast must end by quitting the app so the driver returns to the shell
* prompt — use `{ key: 'CtrlC' }` (Ctrl-C → quit), NOT a typed `quit`: Ctrl-C
* is invisible, so the trim ends the cast on the last content frame instead of
* a dangling `quit`.
*/
/** The shared library narrative, trimmed per cast. */
export const casts = [
{
name: 'projects',
title: 'Save a project, start fresh, then load it back',
width: 90,
height: 26,
typeSpeed: '45ms',
dataDir: true, // isolated data root → picker lists only this cast's projects
steps: [
{ wait: 1000 },
{ type: 'create table books with pk', after: 600 },
{ type: 'add column to books: title (text)', after: 700 },
{ type: "insert into books (title) values ('A Wizard of Earthsea')", after: 800 },
{ type: 'show tables', after: 2000 }, // the project has a "books" table
// save-as: type the name, PAUSE so the viewer reads it, then confirm.
{ type: 'save as', after: 1100 }, // opens the name prompt
{ type: 'library', enter: false, after: 1500 }, // type the name (no Enter yet)
{ key: 'Enter', after: 1600 }, // confirm → saved as "library"
// new: type it, pause, then run — so "new" registers before it executes.
{ type: 'new', enter: false, after: 1100 },
{ key: 'Enter', after: 1500 },
{ type: 'show tables', after: 2200 }, // fresh project — no tables
{ type: 'load', after: 1300 }, // opens the project picker
{ type: 'j', enter: false, after: 1100 }, // move the selection to "library"
{ key: 'Enter', after: 1800 }, // load it
{ type: 'show tables', after: 2200 }, // "books" is back
{ key: 'CtrlC' }, // quit invisibly (Ctrl-C) — cast ends on the last content frame
],
},
{
name: 'modes',
title: 'Simple mode, then advanced — with the SQL the playground runs for you',
width: 90,
height: 26,
typeSpeed: '45ms',
steps: [
{ wait: 1000 },
{ type: 'create table books with pk', after: 700 },
{ type: 'add column to books: title (text)', after: 800 },
{ type: "insert into books (title) values ('A Wizard of Earthsea')", after: 650 },
{ type: "insert into books (title) values ('Invisible Cities')", after: 1100 },
{ type: 'show data books', after: 1600 }, // simple mode — no SQL echo
{ type: 'mode advanced', after: 1300 },
{ type: 'show data books', after: 2400 }, // advanced — shows "Executing SQL: …"
{ key: 'CtrlC' }, // quit invisibly (Ctrl-C) — cast ends on the last content frame
],
},
{
name: 'undo-redo',
title: 'Undo a change — then redo it — each with a confirmation',
width: 90,
height: 26,
typeSpeed: '45ms',
steps: [
{ wait: 1000 },
{ type: 'create table books with pk', after: 700 },
{ type: 'add column to books: title (text)', after: 800 },
{ type: "insert into books (title) values ('A Wizard of Earthsea')", after: 650 },
{ type: "insert into books (title) values ('Invisible Cities')", after: 1100 },
{ type: 'show data books', after: 1500 }, // two rows
{ type: 'undo', after: 1300 }, // opens the confirmation modal
{ type: 'y', enter: false, after: 1600 }, // Y confirms
{ type: 'show data books', after: 1500 }, // one row
{ type: 'redo', after: 1200 },
{ type: 'y', enter: false, after: 1600 },
{ type: 'show data books', after: 1700 }, // two rows again
{ key: 'CtrlC' }, // quit invisibly (Ctrl-C) — cast ends on the last content frame
],
},
{
name: 'joins',
title: 'Switch to advanced mode and join across tables',
width: 90,
height: 26,
typeSpeed: '42ms',
steps: [
{ wait: 900 },
// minimal two-table schema + a few rows to join
{ type: 'create table authors with pk author_id(serial)', after: 650 },
{ type: 'add column to authors: name (text)', after: 650 },
{ type: 'create table books with pk book_id(serial)', after: 650 },
{ type: 'add column to books: title (text)', after: 650 },
{ type: 'add column to books: author_id (int)', after: 800 },
{ type: "insert into authors (name) values ('Ursula K. Le Guin')", after: 600 },
{ type: "insert into authors (name) values ('Italo Calvino')", after: 700 },
{ type: "insert into books (title, author_id) values ('A Wizard of Earthsea', 1)", after: 600 },
{ type: "insert into books (title, author_id) values ('The Left Hand of Darkness', 1)", after: 600 },
{ type: "insert into books (title, author_id) values ('Invisible Cities', 2)", after: 900 },
// switch to SQL and join
{ type: 'mode advanced', after: 1200 },
{
type: 'select authors.name, books.title from books join authors on books.author_id = authors.author_id order by authors.name',
after: 2600,
},
{ key: 'CtrlC' }, // quit invisibly (Ctrl-C) — cast ends on the last content frame
],
},
{
name: 'relationship-diagram',
title: 'Declare a relationship and see it drawn',
width: 90,
height: 26,
typeSpeed: '45ms',
steps: [
{ wait: 900 },
{ type: 'create table authors with pk author_id(serial)', after: 800 },
{ type: 'add column to authors: name (text)', after: 900 },
{ type: 'create table books with pk book_id(serial)', after: 800 },
{ type: 'add column to books: title (text)', after: 700 },
{ type: 'add column to books: author_id (int)', after: 1000 },
{
type: 'add 1:n relationship as books_author from authors.author_id to books.author_id on delete cascade',
after: 1400,
},
// the money shot: the two-table connector diagram
{ type: 'show relationship books_author', after: 2600 },
{ key: 'CtrlC' }, // quit invisibly (Ctrl-C) — cast ends on the last content frame
],
},
{
name: 'assistive-editor',
title: 'The input field helps as you type — completion and a live validity indicator',
width: 90,
height: 26,
typeSpeed: '55ms',
steps: [
{ wait: 1100 },
{ type: 'create table books with pk', after: 850 },
{ type: 'add column to books: title (text)', after: 1100 },
// Completion: type a partial table name, press Tab to complete it.
{ type: 'show data bo', enter: false, after: 1100 },
{ key: 'Tab', after: 1400 },
{ key: 'Enter', after: 1600 },
// Validity indicator: a misspelled table flags [ERR] before you submit.
{ type: 'show data boook', enter: false, after: 1900 },
{ key: 'Enter', after: 1700 },
// The corrected command runs cleanly.
{ type: 'show data books', after: 1600 },
{ key: 'CtrlC' }, // quit invisibly (Ctrl-C) — cast ends on the last content frame
],
},
{
name: 'quickstart',
title: 'RDBMS Playground — first table to first query',
width: 90,
height: 26,
typeSpeed: '45ms',
holdEnd: 2.5, // landing cast loops — pause on the final frame before restart
steps: [
{ wait: 1100 },
{ type: 'create table authors with pk', after: 1000 },
{ type: 'add column to authors: name (text)', after: 850 },
{ type: 'add column to authors: birth_year (int)', after: 900 },
{
type: "insert into authors (name, birth_year) values ('Ursula K. Le Guin', 1929)",
after: 1300,
},
{ type: 'show data authors', after: 1800 },
{ key: 'CtrlC' }, // quit invisibly (Ctrl-C) — cast ends on the last content frame
],
},
];