astro-mermaid 1.2.0 → 1.3.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/README.md CHANGED
@@ -218,7 +218,7 @@ All mermaid diagram types are supported:
218
218
 
219
219
  ## Version
220
220
 
221
- **Current:** `v1.0.4` - Enhanced universal compatibility with dual plugin system
221
+ **Current:** `v1.2.0` - Enhanced universal compatibility with dual plugin system
222
222
 
223
223
  See [changelog](https://github.com/joesaby/astro-mermaid/releases) for version history.
224
224
 
@@ -224,12 +224,16 @@ const hasMermaidDiagrams = () => {
224
224
  return document.querySelectorAll('pre.mermaid').length > 0;
225
225
  };
226
226
 
227
- // Only proceed if there are mermaid diagrams on the page
228
- if (hasMermaidDiagrams()) {
229
- console.log('[astro-mermaid] Mermaid diagrams detected, loading mermaid.js...');
230
-
231
- // Dynamically import mermaid only when needed
232
- import('mermaid').then(async ({ default: mermaid }) => {
227
+ // Shared mermaid initialization function
228
+ let mermaidPromise = null;
229
+ let mermaidInstance = null;
230
+
231
+ async function loadMermaid() {
232
+ if (mermaidPromise) return mermaidPromise;
233
+
234
+ console.log('[astro-mermaid] Loading mermaid.js...');
235
+
236
+ mermaidPromise = import('mermaid').then(async ({ default: mermaid }) => {
233
237
  // Register icon packs if provided
234
238
  const iconPacks = ${JSON.stringify(iconPacksConfig)};
235
239
  if (iconPacks && iconPacks.length > 0) {
@@ -250,132 +254,147 @@ if (elkModule?.default) {
250
254
  }
251
255
  ` : ``}
252
256
 
253
- // Mermaid configuration
254
- const defaultConfig = ${JSON.stringify({
255
- startOnLoad: false,
256
- theme: theme,
257
- ...mermaidConfig
258
- })};
259
-
260
- // Theme mapping for auto-theme switching
261
- const themeMap = {
262
- 'light': 'default',
263
- 'dark': 'dark'
264
- };
265
-
266
- // Initialize all mermaid diagrams
267
- async function initMermaid() {
268
- console.log('[astro-mermaid] Initializing mermaid diagrams...');
269
- const diagrams = document.querySelectorAll('pre.mermaid');
270
-
271
- console.log('[astro-mermaid] Found', diagrams.length, 'mermaid diagrams');
272
-
273
- if (diagrams.length === 0) {
274
- return;
275
- }
276
-
277
- // Get current theme from multiple sources
278
- let currentTheme = defaultConfig.theme;
279
-
280
- if (${autoTheme}) {
281
- // Check both html and body for data-theme attribute
282
- const htmlTheme = document.documentElement.getAttribute('data-theme');
283
- const bodyTheme = document.body.getAttribute('data-theme');
284
- const dataTheme = htmlTheme || bodyTheme;
285
- currentTheme = themeMap[dataTheme] || defaultConfig.theme;
286
- console.log('[astro-mermaid] Using theme:', currentTheme, 'from', htmlTheme ? 'html' : 'body');
287
- }
288
-
289
- // Configure mermaid with gitGraph support
290
- mermaid.initialize({
291
- ...defaultConfig,
292
- theme: currentTheme,
293
- gitGraph: {
294
- mainBranchName: 'main',
295
- showCommitLabel: true,
296
- showBranches: true,
297
- rotateCommitLabel: true
298
- }
299
- });
300
-
301
- // Render each diagram
302
- for (const diagram of diagrams) {
303
- // Skip if already processed
304
- if (diagram.hasAttribute('data-processed')) continue;
305
-
306
- // Store original content
307
- if (!diagram.hasAttribute('data-diagram')) {
308
- diagram.setAttribute('data-diagram', diagram.textContent || '');
309
- }
310
-
311
- const diagramDefinition = diagram.getAttribute('data-diagram') || '';
312
- const id = 'mermaid-' + Math.random().toString(36).slice(2, 11);
313
-
314
- console.log('[astro-mermaid] Rendering diagram:', id);
315
-
316
- try {
317
- // Clear any existing error state
318
- const existingGraph = document.getElementById(id);
319
- if (existingGraph) {
320
- existingGraph.remove();
321
- }
322
-
323
- const { svg } = await mermaid.render(id, diagramDefinition);
324
- diagram.innerHTML = svg;
325
- diagram.setAttribute('data-processed', 'true');
326
- console.log('[astro-mermaid] Successfully rendered diagram:', id);
327
- } catch (error) {
328
- console.error('[astro-mermaid] Mermaid rendering error for diagram:', id, error);
329
- diagram.innerHTML = \`<div style="color: red; padding: 1rem; border: 1px solid red; border-radius: 0.5rem;">
330
- <strong>Error rendering diagram:</strong><br/>
331
- \${error.message || 'Unknown error'}
332
- </div>\`;
333
- diagram.setAttribute('data-processed', 'true');
334
- }
335
- }
257
+ mermaidInstance = mermaid;
258
+ return mermaid;
259
+ }).catch(error => {
260
+ console.error('[astro-mermaid] Failed to load mermaid:', error);
261
+ mermaidPromise = null;
262
+ throw error;
263
+ });
264
+
265
+ return mermaidPromise;
266
+ }
267
+
268
+ // Mermaid configuration
269
+ const defaultConfig = ${JSON.stringify({
270
+ startOnLoad: false,
271
+ theme: theme,
272
+ ...mermaidConfig
273
+ })};
274
+
275
+ // Theme mapping for auto-theme switching
276
+ const themeMap = {
277
+ 'light': 'default',
278
+ 'dark': 'dark'
279
+ };
280
+
281
+ // Initialize all mermaid diagrams
282
+ async function initMermaid() {
283
+ console.log('[astro-mermaid] Initializing mermaid diagrams...');
284
+ const diagrams = document.querySelectorAll('pre.mermaid');
285
+
286
+ console.log('[astro-mermaid] Found', diagrams.length, 'mermaid diagrams');
287
+
288
+ if (diagrams.length === 0) {
289
+ return;
290
+ }
291
+
292
+ // Load mermaid if not already loaded
293
+ const mermaid = await loadMermaid();
294
+
295
+ // Get current theme from multiple sources
296
+ let currentTheme = defaultConfig.theme;
297
+
298
+ if (${autoTheme}) {
299
+ // Check both html and body for data-theme attribute
300
+ const htmlTheme = document.documentElement.getAttribute('data-theme');
301
+ const bodyTheme = document.body.getAttribute('data-theme');
302
+ const dataTheme = htmlTheme || bodyTheme;
303
+ currentTheme = themeMap[dataTheme] || defaultConfig.theme;
304
+ console.log('[astro-mermaid] Using theme:', currentTheme, 'from', htmlTheme ? 'html' : 'body');
305
+ }
306
+
307
+ // Configure mermaid with gitGraph support
308
+ mermaid.initialize({
309
+ ...defaultConfig,
310
+ theme: currentTheme,
311
+ gitGraph: {
312
+ mainBranchName: 'main',
313
+ showCommitLabel: true,
314
+ showBranches: true,
315
+ rotateCommitLabel: true
336
316
  }
317
+ });
337
318
 
338
- // Initialize immediately since DOM is ready
339
- initMermaid();
319
+ // Render each diagram
320
+ for (const diagram of diagrams) {
321
+ // Skip if already processed
322
+ if (diagram.hasAttribute('data-processed')) continue;
340
323
 
341
- // Re-render on theme change if auto-theme is enabled
342
- if (${autoTheme}) {
343
- const observer = new MutationObserver((mutations) => {
344
- for (const mutation of mutations) {
345
- if (mutation.type === 'attributes' && mutation.attributeName === 'data-theme') {
346
- // Reset processed state and re-render
347
- document.querySelectorAll('pre.mermaid[data-processed]').forEach(diagram => {
348
- diagram.removeAttribute('data-processed');
349
- });
350
- initMermaid();
351
- }
352
- }
353
- });
354
-
355
- // Observe both html and body for data-theme changes
356
- observer.observe(document.documentElement, {
357
- attributes: true,
358
- attributeFilter: ['data-theme']
359
- });
360
- observer.observe(document.body, {
361
- attributes: true,
362
- attributeFilter: ['data-theme']
363
- });
324
+ // Store original content
325
+ if (!diagram.hasAttribute('data-diagram')) {
326
+ diagram.setAttribute('data-diagram', diagram.textContent || '');
364
327
  }
365
328
 
366
- // Handle view transitions (for Astro View Transitions API)
367
- document.addEventListener('astro:after-swap', () => {
368
- // Check again if new page has diagrams
369
- if (hasMermaidDiagrams()) {
329
+ const diagramDefinition = diagram.getAttribute('data-diagram') || '';
330
+ const id = 'mermaid-' + Math.random().toString(36).slice(2, 11);
331
+
332
+ console.log('[astro-mermaid] Rendering diagram:', id);
333
+
334
+ try {
335
+ // Clear any existing error state
336
+ const existingGraph = document.getElementById(id);
337
+ if (existingGraph) {
338
+ existingGraph.remove();
339
+ }
340
+
341
+ const { svg } = await mermaid.render(id, diagramDefinition);
342
+ diagram.innerHTML = svg;
343
+ diagram.setAttribute('data-processed', 'true');
344
+ console.log('[astro-mermaid] Successfully rendered diagram:', id);
345
+ } catch (error) {
346
+ console.error('[astro-mermaid] Mermaid rendering error for diagram:', id, error);
347
+ diagram.innerHTML = \`<div style="color: red; padding: 1rem; border: 1px solid red; border-radius: 0.5rem;">
348
+ <strong>Error rendering diagram:</strong><br/>
349
+ \${error.message || 'Unknown error'}
350
+ </div>\`;
351
+ diagram.setAttribute('data-processed', 'true');
352
+ }
353
+ }
354
+ }
355
+
356
+ // Initialize on first load if there are diagrams
357
+ if (hasMermaidDiagrams()) {
358
+ console.log('[astro-mermaid] Mermaid diagrams detected on initial load');
359
+ initMermaid();
360
+ } else {
361
+ console.log('[astro-mermaid] No mermaid diagrams found on initial load');
362
+ }
363
+
364
+ // Re-render on theme change if auto-theme is enabled
365
+ if (${autoTheme}) {
366
+ const observer = new MutationObserver((mutations) => {
367
+ for (const mutation of mutations) {
368
+ if (mutation.type === 'attributes' && mutation.attributeName === 'data-theme') {
369
+ // Reset processed state and re-render
370
+ document.querySelectorAll('pre.mermaid[data-processed]').forEach(diagram => {
371
+ diagram.removeAttribute('data-processed');
372
+ });
370
373
  initMermaid();
371
374
  }
372
- });
373
- }).catch(error => {
374
- console.error('[astro-mermaid] Failed to load mermaid:', error);
375
+ }
376
+ });
377
+
378
+ // Observe both html and body for data-theme changes
379
+ observer.observe(document.documentElement, {
380
+ attributes: true,
381
+ attributeFilter: ['data-theme']
382
+ });
383
+ observer.observe(document.body, {
384
+ attributes: true,
385
+ attributeFilter: ['data-theme']
375
386
  });
376
- } else {
377
- console.log('[astro-mermaid] No mermaid diagrams found on this page, skipping mermaid.js load');
378
387
  }
388
+
389
+ // Handle view transitions (for Astro View Transitions API)
390
+ // This is registered ALWAYS, not just when initial page has diagrams
391
+ document.addEventListener('astro:after-swap', () => {
392
+ console.log('[astro-mermaid] View transition detected');
393
+ // Check if new page has diagrams
394
+ if (hasMermaidDiagrams()) {
395
+ initMermaid();
396
+ }
397
+ });
379
398
  `;
380
399
 
381
400
  injectScript('page', mermaidScriptContent);
@@ -465,4 +484,4 @@ if (elkModule?.default) {
465
484
  }
466
485
  }
467
486
  };
468
- }
487
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "astro-mermaid",
3
- "version": "1.2.0",
3
+ "version": "1.3.1",
4
4
  "description": "An Astro integration for rendering Mermaid diagrams with automatic theme switching and client-side rendering",
5
5
  "type": "module",
6
6
  "main": "./astro-mermaid-integration.js",
@@ -39,13 +39,11 @@
39
39
  }
40
40
  },
41
41
  "dependencies": {
42
- "@anthropic-ai/claude-code": "^1.0.128",
43
42
  "import-meta-resolve": "^4.2.0",
44
43
  "mdast-util-to-string": "^4.0.0",
45
44
  "unist-util-visit": "^5.0.0"
46
45
  },
47
46
  "scripts": {
48
- "claude": "claude",
49
47
  "test": "vitest",
50
48
  "test:ui": "vitest --ui",
51
49
  "test:coverage": "vitest --coverage"