sketchmark 1.0.0 → 1.0.1

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.

Potentially problematic release.


This version of sketchmark might be problematic. Click here for more details.

@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,MAAe,UAAU,CAAC;AACtD,YAAY,EAAE,UAAU,EAAE,MAAiB,UAAU,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,OAAO,EAAE,QAAQ,EAAC,WAAW,EAAE,MAAM,SAAS,CAAC;AACzE,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU,EAAC,aAAa,EAAE,MAAM,SAAS,CAAC;AAC1F,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAe,UAAU,CAAC;AAItD,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC1D,YAAY,EAAE,kBAAkB,EAAE,MAAS,gBAAgB,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACxF,YAAY,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAG/D,OAAO,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjE,YAAY,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAGtE,OAAO,EACL,SAAS,EAAE,SAAS,EAAE,eAAe,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,EACvE,UAAU,EAAE,eAAe,GAC5B,MAAM,UAAU,CAAC;AAClB,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAG5D,YAAY,EACV,SAAS,EAAE,aAAa,EAAE,UAAU,EACpC,UAAU,EAAE,cAAc,EAC1B,eAAe,EAAE,gBAAgB,EAAE,UAAU,EAAE,QAAQ,EACvD,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,QAAQ,EAC7E,aAAa,EAAE,WAAW,EAAE,WAAW,GACxC,MAAM,aAAa,CAAC;AAGrB,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAOlG,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAK1C,OAAO,EAAE,mBAAmB,EAAiB,MAAM,aAAa,CAAC;AACjE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAS,gBAAgB,CAAC;AAC5D,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAE/D,MAAM,WAAW,aAAa;IAC5B,kDAAkD;IAClD,SAAS,EAAE,MAAM,GAAG,WAAW,GAAG,aAAa,CAAC;IAChD,sBAAsB;IACtB,GAAG,EAAE,MAAM,CAAC;IACZ,iCAAiC;IACjC,QAAQ,CAAC,EAAE,KAAK,GAAG,QAAQ,CAAC;IAC5B,uCAAuC;IACvC,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,2BAA2B;IAC3B,UAAU,CAAC,EAAE,kBAAkB,CAAC;IAChC,8BAA8B;IAC9B,aAAa,CAAC,EAAE,qBAAqB,CAAC;IACtC,oCAAoC;IACpC,WAAW,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,yDAAyD;IACzD,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,mBAAmB,EAAE,GAAG,CAAC,EAAE,aAAa,KAAK,IAAI,CAAC;CACpE;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAM,UAAU,CAAC,OAAO,eAAe,CAAC,CAAC;IAC9C,IAAI,EAAO,mBAAmB,CAAC;IAC/B,GAAG,CAAC,EAAO,aAAa,CAAC;IACzB,MAAM,CAAC,EAAI,iBAAiB,CAAC;IAC7B,iDAAiD;IACjD,MAAM,EAAK,CAAC,GAAG,EAAE,MAAM,KAAK,eAAe,CAAC;IAC5C,SAAS,EAAE,CAAC,QAAQ,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,SAAS,EAAE,CAAC,QAAQ,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACjD;AAED,wBAAgB,MAAM,CAAC,OAAO,EAAE,aAAa,GAAG,eAAe,CA+E9D;AAED,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,gBAAgB,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAC9F,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC"}
package/dist/index.js CHANGED
@@ -7178,6 +7178,7 @@ class AnimationController {
7178
7178
  this._pointerType = 'none';
7179
7179
  // ── TTS ──
7180
7180
  this._tts = false;
7181
+ this._speechDone = null;
7181
7182
  this.drawTargetEdges = getDrawTargetEdgeIds(steps);
7182
7183
  this.drawTargetNodes = getDrawTargetNodeIds(steps);
7183
7184
  // Groups: non-edge draw steps whose target has a #group-{id} element in the SVG.
@@ -7308,7 +7309,11 @@ class AnimationController {
7308
7309
  while (this.canNext) {
7309
7310
  const nextStep = this.steps[this._step + 1];
7310
7311
  this.next();
7311
- await new Promise((r) => setTimeout(r, this._playbackWaitMs(nextStep, msPerStep)));
7312
+ // Wait for timer AND speech to finish (whichever is longer)
7313
+ await Promise.all([
7314
+ new Promise((r) => setTimeout(r, this._playbackWaitMs(nextStep, msPerStep))),
7315
+ this._speechDone ?? Promise.resolve(),
7316
+ ]);
7312
7317
  }
7313
7318
  }
7314
7319
  goTo(index) {
@@ -7346,8 +7351,13 @@ class AnimationController {
7346
7351
  // Compute minimum time the step actually needs to finish
7347
7352
  let minNeeded = 0;
7348
7353
  if (step.action === "narrate") {
7354
+ const text = step.value ?? "";
7349
7355
  // Typing effect: chars × typeMs + fade buffer
7350
- minNeeded = (step.value?.length ?? 0) * ANIMATION.narrationTypeMs + ANIMATION.narrationFadeMs;
7356
+ const typingMs = text.length * ANIMATION.narrationTypeMs + ANIMATION.narrationFadeMs;
7357
+ // TTS estimate: ~150ms per word + 500ms buffer for engine latency
7358
+ const wordCount = text.split(/\s+/).filter(Boolean).length;
7359
+ const ttsMs = this._tts ? wordCount * 150 + 500 : 0;
7360
+ minNeeded = Math.max(typingMs, ttsMs);
7351
7361
  }
7352
7362
  else if (step.action === "circle" || step.action === "underline" ||
7353
7363
  step.action === "crossout" || step.action === "bracket") {
@@ -7892,8 +7902,8 @@ class AnimationController {
7892
7902
  }
7893
7903
  // ── narration ───────────────────────────────────────────
7894
7904
  _initCaption() {
7895
- if (!this._container)
7896
- return;
7905
+ // Remove any leftover caption from a previous instance
7906
+ document.querySelector('.skm-caption')?.remove();
7897
7907
  const cap = document.createElement("div");
7898
7908
  cap.className = "skm-caption";
7899
7909
  cap.style.cssText = `
@@ -7923,7 +7933,7 @@ class AnimationController {
7923
7933
  this._captionTextEl.textContent = text;
7924
7934
  return;
7925
7935
  }
7926
- // Fire TTS first it has internal startup latency, so give it a head start
7936
+ // Fire TTS as full sentence play() waits for _speechDone
7927
7937
  if (this._tts && text)
7928
7938
  this._speak(text);
7929
7939
  // Typing effect
@@ -7946,11 +7956,17 @@ class AnimationController {
7946
7956
  utter.rate = 0.95;
7947
7957
  utter.pitch = 1;
7948
7958
  utter.lang = "en-US";
7959
+ // Track when speech actually finishes
7960
+ this._speechDone = new Promise((resolve) => {
7961
+ utter.onend = () => resolve();
7962
+ utter.onerror = () => resolve();
7963
+ });
7949
7964
  speechSynthesis.speak(utter);
7950
7965
  }
7951
7966
  _cancelSpeech() {
7952
7967
  if (typeof speechSynthesis !== "undefined")
7953
7968
  speechSynthesis.cancel();
7969
+ this._speechDone = null;
7954
7970
  }
7955
7971
  /** Pre-warm the speech engine with a silent utterance to eliminate cold-start delay */
7956
7972
  _warmUpSpeech() {
@@ -8457,12 +8473,10 @@ function render(options) {
8457
8473
  interactive: true,
8458
8474
  onNodeClick,
8459
8475
  });
8460
- // Create rough.js instance for annotations
8476
+ // Create rough.js instance for annotations (same import as SVG renderer)
8461
8477
  let rc = null;
8462
8478
  try {
8463
- const roughMod = window.rough ?? (typeof require !== 'undefined' ? require('roughjs/bin/rough') : null);
8464
- if (roughMod?.svg)
8465
- rc = roughMod.svg(svg);
8479
+ rc = rough.svg(svg);
8466
8480
  }
8467
8481
  catch { /* rough.js not available — annotations disabled */ }
8468
8482
  const containerEl = el instanceof SVGSVGElement ? undefined : el;
@@ -8471,7 +8485,7 @@ function render(options) {
8471
8485
  onReady?.(anim, svg);
8472
8486
  const instance = {
8473
8487
  scene, anim, svg, canvas,
8474
- update: (newDsl) => render({ ...options, dsl: newDsl }),
8488
+ update: (newDsl) => { anim?.destroy(); return render({ ...options, dsl: newDsl }); },
8475
8489
  exportSVG: (filename = 'diagram.svg') => {
8476
8490
  if (svg) {
8477
8491
  Promise.resolve().then(function () { return index; }).then(m => m.exportSVG(svg, { filename }));