chalk-talk 0.16.0 → 0.17.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.
package/scripts/build.mjs CHANGED
@@ -22,7 +22,7 @@ import { basename, dirname, join, resolve } from 'node:path'
22
22
  import { fileURLToPath } from 'node:url'
23
23
  import { runPages } from './browser.mjs'
24
24
  import { fill, inline } from './page.mjs'
25
- import { ChalkTextError, chaptersFor, parseChalk, PROP_ALIASES, PROP_NAMES, validateScene } from './contract.mjs'
25
+ import { ChalkTextError, chaptersFor, parseChalk, PROP_ALIASES, PROP_NAMES, purposeWarnings, validateScene } from './contract.mjs'
26
26
  import { syntaxForLine, syntaxForStep } from './syntax.mjs'
27
27
 
28
28
  const here = dirname(fileURLToPath(import.meta.url))
@@ -149,10 +149,17 @@ if (scenes.some((s) => Object.keys(s.lotties ?? {}).length)) {
149
149
  }
150
150
  writeFileSync(out, page)
151
151
 
152
+ // back-of-napkin: what a drawing of its purpose usually misses (a pitch with no ask…) — drawn anyway, to fix like a
153
+ // review finding (exit 3).
154
+ let warned = false
152
155
  scenes.forEach((scene, k) => {
153
156
  const values = Object.keys(scene.params ?? {}).length + Object.keys(scene.switches ?? {}).length
154
157
  const who = course ? ` (${k + 1}) ${scene.title}: ` : ' '
155
158
  console.log(`✓ contract${who}${scene.steps.length} steps, ${chaptersFor(scene).length} chapters, ${values} values`)
159
+ for (const w of purposeWarnings(scene)) {
160
+ console.log(`! ${scene.kind.padEnd(9)}${course ? ` (${k + 1})` : ''} ${w.text}`)
161
+ warned = true
162
+ }
156
163
  })
157
164
 
158
165
  // Onda C: a figure made with `define` is seen by nobody when the build passes at once (the review measures, it does
@@ -172,7 +179,7 @@ const ran = jobs.length ? await runPages(jobs, { timeout }) : { results: [] }
172
179
  const name = (exe) => basename(exe).replace(/\.exe$/i, '')
173
180
  const result = (what, k) => ran.results?.[jobs.findIndex((j) => j.what === what && j.k === k)]
174
181
 
175
- let code = 0
182
+ let code = warned ? 3 : 0
176
183
  if (noReview) console.log('• review skipped (--no-review); the page checks itself when opened')
177
184
  else if (!ran.results) console.log('• review no Chrome, Chromium or Edge here: the page checks itself when opened')
178
185
  else {
@@ -1,4 +1,4 @@
1
- // GENERATED by tools/assets.mjs from the drawing engine v0.256.1. Do not edit.
1
+ // GENERATED by tools/assets.mjs from the drawing engine v0.257.0. Do not edit.
2
2
  var WORDS = ["and", "or", "not"];
3
3
 
4
4
  var PROP_NAMES = [
@@ -417,6 +417,7 @@ var hasFace = (name) => {
417
417
  };
418
418
 
419
419
  var MOTIONS = ["spin", "drive", "steam", "talk", "pulse", "float"];
420
+ var KINDS = ["lesson", "pitch", "arch", "decision", "data", "timeline", "story"];
420
421
  var MAX_DEFS = 8;
421
422
  var MAX_LOTTIES = 6;
422
423
  var MAX_LOTTIE_CHARS = 2e5;
@@ -878,6 +879,9 @@ function validateScene(data) {
878
879
  if (!ok) throw new Error('locale: expected a language tag such as "en-US" or "pt-BR".');
879
880
  }
880
881
  choice(s.background, ["dots", "grid", "plain"], "background");
882
+ choice(s.kind, KINDS, "kind");
883
+ optionalText(s.source, "source");
884
+ if (s.quiz !== void 0 && s.kind !== void 0 && s.kind !== "lesson") throw new Error(`quiz: only a lesson has a quiz (this drawing is a ${s.kind}).`);
881
885
  choice(s.theme, ["paper", "chalkboard"], "theme");
882
886
  if (s.quiz !== void 0) {
883
887
  object(s.quiz, "quiz");
@@ -1424,6 +1428,12 @@ function parseChalk(text2, props) {
1424
1428
  case "locale":
1425
1429
  scene.locale = one("a language tag");
1426
1430
  continue;
1431
+ case "kind":
1432
+ scene.kind = one("what the drawing is for");
1433
+ continue;
1434
+ case "source":
1435
+ scene.source = one("where the numbers come from");
1436
+ continue;
1427
1437
  case "background":
1428
1438
  scene.background = one("dots, grid or plain");
1429
1439
  continue;
@@ -1589,7 +1599,8 @@ function printChalk(scene, props) {
1589
1599
  const out = [];
1590
1600
  if (scene.id !== void 0) out.push(`id ${scene.id}`);
1591
1601
  if (scene.title !== void 0) out.push(`title ${scene.title}`);
1592
- for (const k of ["category", "theme", "locale", "background"]) if (scene[k] !== void 0) out.push(`${k} ${scene[k]}`);
1602
+ for (const k of ["kind", "category", "theme", "locale", "background"]) if (scene[k] !== void 0) out.push(`${k} ${scene[k]}`);
1603
+ if (scene.source !== void 0) out.push(`source ${q(scene.source)}`);
1593
1604
  if (scene.width !== 900 || scene.height !== 560) out.push(`size ${scene.width}x${scene.height}`);
1594
1605
  for (const [k, p] of Object.entries(scene.params ?? {})) {
1595
1606
  out.push(`param ${k} ${q(p.label)} ${p.min}..${p.max}${p.step !== 1 ? ` step=${p.step}` : ""} = ${p.value}`);
@@ -1617,13 +1628,48 @@ function printChalk(scene, props) {
1617
1628
  }
1618
1629
  return out.join("\n").replace(/\n{3,}/g, "\n\n") + "\n";
1619
1630
  }
1631
+
1632
+ function all(steps) {
1633
+ return steps.flatMap((s) => {
1634
+ const inner = "steps" in s && Array.isArray(s.steps) ? s.steps : "step" in s && s.step ? [s.step] : [];
1635
+ return [s, ...all(inner)];
1636
+ });
1637
+ }
1638
+ function purposeWarnings(scene) {
1639
+ const steps = all(scene.steps);
1640
+ const last = chaptersFor(scene).at(-1);
1641
+ const endsLit = last ? all(scene.steps.slice(last.start, last.end + 1)).some((s) => s.type === "highlight") : false;
1642
+ const switches = Object.keys(scene.switches ?? {}).length > 0;
1643
+ const params = Object.keys(scene.params ?? {}).length > 0;
1644
+ const out = [];
1645
+ switch (scene.kind) {
1646
+ case "pitch":
1647
+ if (!endsLit) out.push({ key: "pitch-ask", text: "the pitch does not end with an ask (no highlight in its last chapter)" });
1648
+ break;
1649
+ case "arch":
1650
+ if (!switches && !steps.some((s) => s.type === "when")) out.push({ key: "arch-failure", text: "no failure drawn: what happens when something goes down? (no switch, no when)" });
1651
+ break;
1652
+ case "decision":
1653
+ if (!endsLit && !params && !switches) out.push({ key: "decision-winner", text: "the decision does not say which option wins, nor why (no highlight in its last chapter, no value)" });
1654
+ break;
1655
+ case "data":
1656
+ if (!scene.source?.trim()) out.push({ key: "data-source", text: "where do these numbers come from? (no source)" });
1657
+ break;
1658
+ case "timeline":
1659
+ if (!steps.some((s) => s.type === "timeline")) out.push({ key: "timeline-line", text: "the timeline has no line (no timeline step)" });
1660
+ break;
1661
+ }
1662
+ return out;
1663
+ }
1620
1664
  export {
1621
1665
  ChalkTextError,
1666
+ KINDS,
1622
1667
  PROP_ALIASES,
1623
1668
  PROP_NAMES,
1624
1669
  chaptersFor,
1625
1670
  defaultValues,
1626
1671
  parseChalk,
1627
1672
  printChalk,
1673
+ purposeWarnings,
1628
1674
  validateScene
1629
1675
  };