deckrun 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,400 @@
1
+ /**
2
+ * Content that drives the editor's discovery surfaces: the welcome deck, the
3
+ * snippet registry behind the guide drawer and the command palette, and the
4
+ * ambient tips carousel. Kept as data so every surface renders the same list.
5
+ */
6
+ export const SNIPPET_GROUPS = [
7
+ "Slides",
8
+ "Text",
9
+ "Lists & tables",
10
+ "Code",
11
+ "Images",
12
+ "Embeds",
13
+ "Actions",
14
+ ];
15
+ export const SNIPPETS = [
16
+ // ── Slides ───────────────────────────────────────────────────────────────
17
+ {
18
+ id: "slide-break",
19
+ group: "Slides",
20
+ label: "New slide",
21
+ hint: "Three dashes on their own line end one slide and start the next.",
22
+ syntax: "---",
23
+ insert: "\n---\n\n## {caret}\n",
24
+ keys: "Cmd D",
25
+ },
26
+ {
27
+ id: "slide-title",
28
+ group: "Slides",
29
+ label: "Title slide",
30
+ hint: "An h1 reads largest and in mauve. Use it for the opener and section breaks.",
31
+ syntax: "# Title\\n\\nSubtitle line",
32
+ insert: "# {caret}\n\nOne line that frames the talk.\n",
33
+ block: true,
34
+ },
35
+ {
36
+ id: "slide-section",
37
+ group: "Slides",
38
+ label: "Section divider",
39
+ hint: "A slide holding nothing but an h1 gives the audience a beat to reset.",
40
+ syntax: "# Part 2",
41
+ insert: "\n---\n\n# {caret}\n",
42
+ },
43
+ {
44
+ id: "slide-notes",
45
+ group: "Slides",
46
+ label: "Speaker notes",
47
+ hint: "Stripped from the slide and the PDF. Shown under the preview while you write.",
48
+ syntax: '<!-- notes: what to say here -->',
49
+ insert: "\n<!-- notes: {caret} -->\n",
50
+ },
51
+ // ── Text ─────────────────────────────────────────────────────────────────
52
+ {
53
+ id: "h2",
54
+ group: "Text",
55
+ label: "Slide title (h2)",
56
+ hint: "Blue, the workhorse heading for a content slide.",
57
+ syntax: "## Slide title",
58
+ insert: "## {caret}",
59
+ },
60
+ {
61
+ id: "h3",
62
+ group: "Text",
63
+ label: "Subheading (h3)",
64
+ hint: "Sky blue, for splitting a slide into two named halves.",
65
+ syntax: "### Subheading",
66
+ insert: "### {caret}",
67
+ },
68
+ {
69
+ id: "bold",
70
+ group: "Text",
71
+ label: "Bold",
72
+ hint: "Renders peach. Reserve it for the one term that has to land.",
73
+ syntax: "**term**",
74
+ insert: "**{sel}**",
75
+ keys: "Cmd B",
76
+ },
77
+ {
78
+ id: "italic",
79
+ group: "Text",
80
+ label: "Italic",
81
+ hint: "Muted grey, right for an aside or a caveat.",
82
+ syntax: "*aside*",
83
+ insert: "*{sel}*",
84
+ keys: "Cmd I",
85
+ },
86
+ {
87
+ id: "inline-code",
88
+ group: "Text",
89
+ label: "Inline code",
90
+ hint: "Green chip. Use it for identifiers, flags, paths, and config keys.",
91
+ syntax: "`fsync()`",
92
+ insert: "`{sel}`",
93
+ keys: "Cmd E",
94
+ },
95
+ {
96
+ id: "quote",
97
+ group: "Text",
98
+ label: "Blockquote",
99
+ hint: "Mauve rule on a tinted background. Good for the insight in one sentence.",
100
+ syntax: "> the log is the source of truth",
101
+ insert: "> {caret}",
102
+ block: true,
103
+ },
104
+ {
105
+ id: "link",
106
+ group: "Text",
107
+ label: "Link",
108
+ hint: "Blue with an underline. Clickable while presenting.",
109
+ syntax: "[label](https://example.com)",
110
+ insert: "[{sel}](https://{caret})",
111
+ keys: "Cmd K",
112
+ },
113
+ {
114
+ id: "kbd",
115
+ group: "Text",
116
+ label: "Keyboard key",
117
+ hint: "Raw HTML renders as a physical key cap. Handy for demo instructions.",
118
+ syntax: "<kbd>Cmd</kbd>",
119
+ insert: "<kbd>{sel}</kbd>",
120
+ },
121
+ {
122
+ id: "mark",
123
+ group: "Text",
124
+ label: "Highlight",
125
+ hint: "Yellow underline on a tinted background, for the number that matters.",
126
+ syntax: "<mark>42ms</mark>",
127
+ insert: "<mark>{sel}</mark>",
128
+ },
129
+ {
130
+ id: "rule",
131
+ group: "Text",
132
+ label: "Horizontal rule",
133
+ hint: "A rule inside a slide. Never use --- for this, it breaks the slide.",
134
+ syntax: "***",
135
+ insert: "\n***\n",
136
+ },
137
+ // ── Lists & tables ───────────────────────────────────────────────────────
138
+ {
139
+ id: "bullets",
140
+ group: "Lists & tables",
141
+ label: "Bullet list",
142
+ hint: "Mauve markers. Seven bullets is about the ceiling for a projected slide.",
143
+ syntax: "- point",
144
+ insert: "- {caret}\n- \n- ",
145
+ block: true,
146
+ },
147
+ {
148
+ id: "numbered",
149
+ group: "Lists & tables",
150
+ label: "Numbered list",
151
+ hint: "Use it when order carries meaning, like the steps of a protocol.",
152
+ syntax: "1. first",
153
+ insert: "1. {caret}\n2. \n3. ",
154
+ block: true,
155
+ },
156
+ {
157
+ id: "nested",
158
+ group: "Lists & tables",
159
+ label: "Nested list",
160
+ hint: "Two spaces per level. One level of nesting is usually enough.",
161
+ syntax: "- parent\\n - child",
162
+ insert: "- {caret}\n - \n - ",
163
+ block: true,
164
+ },
165
+ {
166
+ id: "table",
167
+ group: "Lists & tables",
168
+ label: "Table",
169
+ hint: "Lavender headers, mauve underline, zebra rows. Ideal for benchmarks.",
170
+ syntax: "| col | col |",
171
+ insert: "| Config | Throughput | p99 |\n| ------ | ---------- | --- |\n| {caret} | | |\n| | | |",
172
+ block: true,
173
+ },
174
+ // ── Code ─────────────────────────────────────────────────────────────────
175
+ {
176
+ id: "code-go",
177
+ group: "Code",
178
+ label: "Code block (Go)",
179
+ hint: "Tag the language and Highlight.js picks the right grammar.",
180
+ syntax: "```go",
181
+ insert: "```go\n{caret}\n```",
182
+ block: true,
183
+ },
184
+ {
185
+ id: "code-ts",
186
+ group: "Code",
187
+ label: "Code block (TypeScript)",
188
+ hint: "Long lines scroll sideways instead of reflowing mid-talk.",
189
+ syntax: "```typescript",
190
+ insert: "```typescript\n{caret}\n```",
191
+ block: true,
192
+ },
193
+ {
194
+ id: "code-sql",
195
+ group: "Code",
196
+ label: "Code block (SQL)",
197
+ hint: "Trim to the clause that makes the point. No boilerplate.",
198
+ syntax: "```sql",
199
+ insert: "```sql\n{caret}\n```",
200
+ block: true,
201
+ },
202
+ {
203
+ id: "code-bash",
204
+ group: "Code",
205
+ label: "Code block (shell)",
206
+ hint: "Use it for the command you want the audience to copy.",
207
+ syntax: "```bash",
208
+ insert: "```bash\n{caret}\n```",
209
+ block: true,
210
+ },
211
+ {
212
+ id: "code-plain",
213
+ group: "Code",
214
+ label: "ASCII diagram",
215
+ hint: "An untagged block keeps spacing exact. Boxes and arrows beat prose.",
216
+ syntax: "```text",
217
+ insert: "```text\nClient --> [ LB ] --> [ App ] --> [ DB ]\n{caret}\n```",
218
+ block: true,
219
+ },
220
+ // ── Images ───────────────────────────────────────────────────────────────
221
+ {
222
+ id: "img-inline",
223
+ group: "Images",
224
+ label: "Inline image",
225
+ hint: "Path resolves against the folder you launched in. Centered, capped at 55% of the slide height.",
226
+ syntax: "![alt](diagram.png)",
227
+ insert: "![{sel}](diagram.png)",
228
+ },
229
+ {
230
+ id: "img-right",
231
+ group: "Images",
232
+ label: "Split: image right",
233
+ hint: "Text takes the left half, the image fills the right. The best default for a diagram.",
234
+ syntax: '![alt](diagram.png "right")',
235
+ insert: '![{sel}](diagram.png "right")',
236
+ },
237
+ {
238
+ id: "img-left",
239
+ group: "Images",
240
+ label: "Split: image left",
241
+ hint: "Mirror of the above. Alternate sides across consecutive slides.",
242
+ syntax: '![alt](diagram.png "left")',
243
+ insert: '![{sel}](diagram.png "left")',
244
+ },
245
+ {
246
+ id: "img-bg",
247
+ group: "Images",
248
+ label: "Background image",
249
+ hint: "Covers the whole canvas under the text. Pair it with a low opacity.",
250
+ syntax: '![alt](cover.png "bg opacity:0.25")',
251
+ insert: '![{sel}](cover.png "bg opacity:0.25")',
252
+ },
253
+ {
254
+ id: "img-opacity",
255
+ group: "Images",
256
+ label: "Image opacity",
257
+ hint: "Any value from 0.0 to 1.0, combinable with left, right, or bg.",
258
+ syntax: '"right opacity:0.8"',
259
+ insert: '![{sel}](diagram.png "right opacity:0.8")',
260
+ },
261
+ // ── Embeds ───────────────────────────────────────────────────────────────
262
+ {
263
+ id: "embed-youtube",
264
+ group: "Embeds",
265
+ label: "YouTube video",
266
+ hint: "Raw HTML passes straight through. Sized to 16:9 automatically.",
267
+ syntax: '<iframe src="https://www.youtube.com/embed/ID">',
268
+ insert: '<iframe src="https://www.youtube.com/embed/{caret}" title="YouTube" allowfullscreen></iframe>',
269
+ block: true,
270
+ },
271
+ {
272
+ id: "embed-video",
273
+ group: "Embeds",
274
+ label: "Local video",
275
+ hint: "Served from the folder you launched in. MP4 and WebM both work.",
276
+ syntax: "<video src=\"clip.mp4\" controls>",
277
+ insert: '<video src="{caret}clip.mp4" controls muted loop></video>',
278
+ block: true,
279
+ },
280
+ {
281
+ id: "embed-iframe",
282
+ group: "Embeds",
283
+ label: "Any iframe",
284
+ hint: "Dashboards, playgrounds, live docs. Anything that allows framing.",
285
+ syntax: '<iframe src="https://...">',
286
+ insert: '<iframe src="https://{caret}" title="Embed"></iframe>',
287
+ block: true,
288
+ },
289
+ // ── Actions ──────────────────────────────────────────────────────────────
290
+ { id: "act-present", group: "Actions", label: "Present this deck", hint: "Opens the real presentation in a new tab.", syntax: "", action: "present", keys: "Cmd Enter" },
291
+ { id: "act-download", group: "Actions", label: "Export as Markdown", hint: "Downloads a plain .md file. Yours to keep.", syntax: "", action: "download", keys: "Cmd S" },
292
+ { id: "act-pdf", group: "Actions", label: "Export as PDF", hint: "A real PDF file, one 16:9 page per slide, styling intact.", syntax: "", action: "pdf", keys: "Cmd Shift S" },
293
+ { id: "act-html", group: "Actions", label: "Export as HTML", hint: "One standalone page holding the whole deck, ready to host or send.", syntax: "", action: "html" },
294
+ { id: "act-open", group: "Actions", label: "Import a Markdown file", hint: "Loads a local .md in as a new deck, leaving the others alone.", syntax: "", action: "open" },
295
+ { id: "act-grid", group: "Actions", label: "Toggle grid preview", hint: "See every slide at once, click one to jump there.", syntax: "", action: "grid", keys: "Cmd G" },
296
+ { id: "act-theme", group: "Actions", label: "Theme and type size", hint: "Fourteen palettes with their own fonts and backdrops, at four type sizes. Arrows preview live, brackets resize.", syntax: "", action: "theme", keys: "Cmd Shift L" },
297
+ { id: "act-guide", group: "Actions", label: "Open the guide", hint: "Every layout, style, and embed this editor supports.", syntax: "", action: "guide", keys: "Cmd /" },
298
+ { id: "act-decks", group: "Actions", label: "Switch deck", hint: "Every deck you have written, kept in this browser.", syntax: "", action: "decks", keys: "Cmd O" },
299
+ { id: "act-new", group: "Actions", label: "New deck", hint: "Starts an empty deck and keeps the current one in the library.", syntax: "", action: "new" },
300
+ { id: "act-dupe", group: "Actions", label: "Duplicate this deck", hint: "Copies it into the library and switches to the copy.", syntax: "", action: "duplicate" },
301
+ { id: "act-delete", group: "Actions", label: "Delete this deck", hint: "Removes it from this browser. Download it first to keep it.", syntax: "", action: "delete" },
302
+ ];
303
+ /** Ambient one-liners cycled in the status bar. */
304
+ export const TIPS = [
305
+ 'Add "right" to an image title and the slide splits: text left, image right.',
306
+ "Images load by path from the folder you launched in, so keep the deck next to its diagrams.",
307
+ "Cmd K opens the command palette. Every style, layout, and embed is in there.",
308
+ "Your caret drives the preview. Move it into a slide and the preview follows.",
309
+ "Every deck you write is kept in this browser. Cmd O switches between them.",
310
+ "Cmd G lays out every slide as a grid. Click one to jump the caret there.",
311
+ 'A background image reads best around "bg opacity:0.25".',
312
+ "Speaker notes live in <!-- notes: ... --> and never reach the slide or the PDF.",
313
+ "Tag the language on a code fence and Highlight.js does the rest.",
314
+ "Everything autosaves to this browser. Nothing is uploaded anywhere.",
315
+ "Drop a .md file onto the editor to load it as a new deck.",
316
+ "Paste a YouTube embed as raw HTML. It is sized to 16:9 for you.",
317
+ "Use *** for a rule inside a slide. --- would start a new one.",
318
+ "<kbd>Cmd</kbd> renders as a key cap, <mark>42ms</mark> as a highlight.",
319
+ "Cmd Enter presents the deck in a new tab, exactly as your audience sees it.",
320
+ "Alt Up and Alt Down hop the caret between slides.",
321
+ "Export as PDF from the top bar: a real file, 16:9 pages, no print dialog to wrestle.",
322
+ "Seven bullets is about the ceiling before a slide stops reading from the back row.",
323
+ "Drag the divider to resize. Double-click it to snap back to an even split.",
324
+ "While presenting, press ? for every control the deck has.",
325
+ "L turns on a laser pointer while presenting. D gives you a pen to draw with.",
326
+ "C drops a blank canvas over the slide, for the diagram you did not plan.",
327
+ "B blacks out the screen mid-talk. Press it again to come back.",
328
+ ];
329
+ /** Deck loaded on a first visit. Doubles as the feature tour. */
330
+ export const WELCOME_DECK = `# deckrun
331
+
332
+ ### Write slides in Markdown, present in the browser
333
+
334
+ Everything on the left is a plain \`.md\` file. The right side is the real deck.
335
+
336
+ <!-- notes: Notes live here. They never reach the slide or the PDF, but you can see them while you write. -->
337
+
338
+ ---
339
+
340
+ ## Type on the left, watch the right
341
+
342
+ - The preview follows your caret, so it always shows the slide you are editing
343
+ - Press <kbd>Cmd</kbd> <kbd>K</kbd> for every style, layout, and embed
344
+ - Press <kbd>Cmd</kbd> <kbd>G</kbd> to see the whole deck as a grid
345
+ - Press <kbd>Cmd</kbd> <kbd>Enter</kbd> to present for real
346
+
347
+ Three dashes on their own line start a new slide.
348
+
349
+ ---
350
+
351
+ ## Code gets highlighted
352
+
353
+ Tag the language and the grammar comes for free:
354
+
355
+ \`\`\`go
356
+ func (w *WAL) Append(e Entry) error {
357
+ if _, err := w.file.Write(e.Encode()); err != nil {
358
+ return fmt.Errorf("append: %w", err)
359
+ }
360
+ return w.file.Sync()
361
+ }
362
+ \`\`\`
363
+
364
+ > the log is the source of truth, the data file is a materialized view of it
365
+
366
+ ---
367
+
368
+ ## Tables, lists, and accents
369
+
370
+ | Configuration | Throughput | p99 latency |
371
+ | -------------- | ---------- | --------------- |
372
+ | Single node | 12,400/s | <mark>18.2ms</mark> |
373
+ | 3-node cluster | 35,100/s | 6.4ms |
374
+
375
+ - **Bold** lands peach, *italic* recedes, \`inline code\` gets a green chip
376
+ - Nesting works too
377
+ - two spaces per level
378
+
379
+ ---
380
+
381
+ ## Images split the slide
382
+
383
+ An image path resolves against the folder you launched in. Add a directive to the title and it changes the layout:
384
+
385
+ \`\`\`markdown
386
+ ![Diagram](diagram.png "right")
387
+ ![Diagram](diagram.png "left opacity:0.8")
388
+ ![Cover](cover.png "bg opacity:0.25")
389
+ \`\`\`
390
+
391
+ <!-- notes: Launch deckrun in the folder holding your diagrams and the paths just work. -->
392
+
393
+ ---
394
+
395
+ # Your turn
396
+
397
+ - Start typing over this deck, or press Cmd O and make a new one
398
+ - <kbd>Cmd</kbd> <kbd>S</kbd> downloads the Markdown
399
+ - <kbd>Cmd</kbd> <kbd>/</kbd> opens the full guide
400
+ `;