origam 2.35.0 → 2.35.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.
package/CHANGELOG.md CHANGED
@@ -18,6 +18,16 @@ This project follows [Semantic Versioning](https://semver.org).
18
18
 
19
19
  ## [Unreleased]
20
20
 
21
+ ## [2.35.1] - 2026-10-19
22
+
23
+ ### Fixed — `OrigamCode` : un 2e bloc monté pendant un import de `shiki` en échec restait vide (#1189)
24
+
25
+ Quand `shiki` n'est pas résolvable, deux `<origam-code>` montés dans le même tick : le premier s'affichait en texte brut, le second restait **vide** (zone défilante de hauteur 0) avec un rejet de promesse non capturé. `loadHighlighter()` ne renvoyait la promesse munie de son repli qu'au premier appelant ; un appelant concurrent recevait la promesse brute, qui rejetait, et `rebuild()` n'avait qu'un `try/finally`.
26
+
27
+ - `loadHighlighter()` renvoie désormais la même promesse, déjà munie de son repli (`null` → code brut), à tous les appelants.
28
+ - `rebuild()` capture en plus un éventuel rejet et peint le code en clair : aucun bloc ne reste vide.
29
+ - Prouvé par `packages/tests/TU/components/Code/OrigamCode-concurrent-load-failure.spec.ts` (rouge sur le parent, vert après).
30
+
21
31
  ## [2.35.0] - 2026-10-19
22
32
 
23
33
  ### Added — `OrigamCode` : `lang` ouvert, `createOrigam({ code: { langs } })` (#1180)
@@ -266,6 +266,13 @@ async function rebuild() {
266
266
  const html = await highlight(formattedCode.value, props.lang);
267
267
  if (token !== _renderToken) return;
268
268
  paintIntoDom(html);
269
+ } catch (err) {
270
+ console.warn("[origam] OrigamCode: highlighting failed \u2014 rendering plain code.", err);
271
+ if (token === _renderToken) {
272
+ const plain = document.createElement("div");
273
+ plain.textContent = formattedCode.value;
274
+ paintIntoDom(plain.innerHTML);
275
+ }
269
276
  } finally {
270
277
  if (token === _renderToken) isHighlighting.value = false;
271
278
  }
@@ -37,7 +37,7 @@ function lruSet(key, value) {
37
37
  async function loadHighlighter(loader, langs) {
38
38
  if (_highlighterUnavailable) return null;
39
39
  if (_highlighterPromise) return _highlighterPromise;
40
- _highlighterPromise = (async () => {
40
+ const raw = (async () => {
41
41
  const shiki = loader ? await loader() : await Promise.resolve().then(() => require("shiki"));
42
42
  const highlighter = await shiki.createHighlighter({
43
43
  themes: [_code.CODE_LIGHT_THEME, _code.CODE_DARK_THEME],
@@ -46,7 +46,7 @@ async function loadHighlighter(loader, langs) {
46
46
  _highlighterReady = true;
47
47
  return highlighter;
48
48
  })();
49
- return _highlighterPromise.catch(err => {
49
+ _highlighterPromise = raw.catch(err => {
50
50
  _highlighterUnavailable = true;
51
51
  _highlighterPromise = null;
52
52
  if (!_unavailableWarned) {
@@ -55,6 +55,7 @@ async function loadHighlighter(loader, langs) {
55
55
  }
56
56
  return null;
57
57
  });
58
+ return _highlighterPromise;
58
59
  }
59
60
  function resolveLang(lang, hasCustomHighlighter, extraLangs) {
60
61
  if (hasCustomHighlighter) return lang;
@@ -30,7 +30,7 @@ function lruSet(key, value) {
30
30
  async function loadHighlighter(loader, langs) {
31
31
  if (_highlighterUnavailable) return null;
32
32
  if (_highlighterPromise) return _highlighterPromise;
33
- _highlighterPromise = (async () => {
33
+ const raw = (async () => {
34
34
  const shiki = loader ? await loader() : await import(
35
35
  /* @vite-ignore */
36
36
  "shiki"
@@ -42,7 +42,7 @@ async function loadHighlighter(loader, langs) {
42
42
  _highlighterReady = true;
43
43
  return highlighter;
44
44
  })();
45
- return _highlighterPromise.catch((err) => {
45
+ _highlighterPromise = raw.catch((err) => {
46
46
  _highlighterUnavailable = true;
47
47
  _highlighterPromise = null;
48
48
  if (!_unavailableWarned) {
@@ -54,6 +54,7 @@ async function loadHighlighter(loader, langs) {
54
54
  }
55
55
  return null;
56
56
  });
57
+ return _highlighterPromise;
57
58
  }
58
59
  function resolveLang(lang, hasCustomHighlighter, extraLangs) {
59
60
  if (hasCustomHighlighter) return lang;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "origam",
3
- "version": "2.35.0",
3
+ "version": "2.35.1",
4
4
  "type": "module",
5
5
  "description": "origam — a Vue 3 design system with multi-theme design tokens, CSS-first components and TypeScript types.",
6
6
  "keywords": [