Skip to content

v1.7.2

Choose a tag to compare

@github-actions github-actions released this 18 Aug 17:40
· 32 commits to main since this release

1.7.2 (2026-08-18)

Version 1.7.2 aligns textmode.export.js with the updated plugin architecture in textmode.js 0.17.2, migrates extension definitions to host-managed properties with automatic cleanup, enhances video recording bitrate resolution, streamlines UI components, and modernizes developer tooling with the modular @textmode/* ecosystem.


Highlights

  • Updated Plugin Contract: Fully aligned with the new textmode.js (0.17.2) plugin system. ExportPlugin.install() now returns a cleanup disposer function that cleanly removes the UI overlay and unregisters hooks during host rollback or sketch destruction.
  • Host-Managed Instance Extensions: Migrated all export methods (exportPNG, exportSVG, exportGIF, exportMP4, exportWebM, headless blob export APIs, and overlay controls) to context.defineExtension(), allowing textmode.js to manage conflict detection and instance lifecycle.
  • Video Recording & Bitrate Enhancements: Improved bitrate calculation and validation in VideoRecorder with documented 8 Mbps defaults and positive bitrate clamping.
  • Streamlined UI Overlay: Removed redundant range input components and unused stylesheet declarations, reducing bundle weight.
  • Plugin Lifecycle Test Suite: Added dedicated unit test coverage for ExportPlugin installation, returned cleanup execution, extension integrity, and error recovery.
  • Modernized Tooling: Adopted the modular @textmode/* developer tooling suite (@textmode/build, @textmode/lint, @textmode/release).

Quick Start & Usage

import { textmode } from 'textmode.js';
import { ExportPlugin } from 'textmode.export.js';

const t = textmode.create({
  width: 80,
  height: 40,
  plugins: [ExportPlugin]
});

t.setup = () => {
  // Show interactive on-screen export UI overlay
  t.showExportOverlay();
};

t.draw(() => {
  t.background(0);
  t.print(10, 10, 'EXPORT READY');
});

// Programmatic export triggers
window.addEventListener('keydown', async (e) => {
  if (e.key === 's') {
    // Export high-resolution PNG snapshot
    await t.exportPNG({ filename: 'snapshot', scale: 2 });
  } else if (e.key === 'g') {
    // Record and export animated GIF
    await t.exportGIF({ filename: 'animation', duration: 3, fps: 30 });
  } else if (e.key === 'v') {
    // Record MP4 video with custom bitrate
    await t.exportMP4({ filename: 'capture', duration: 5, fps: 60, bitrate: 12_000_000 });
  }
});

Headless Blob Exports

Export files directly as in-memory Blob objects for custom upload or processing pipelines:

// Export image as PNG Blob
const pngBlob = await t.exportBlobPNG({ scale: 2 });

// Export 3-second WebM video as Blob
const webmBlob = await t.exportBlobWebM({ duration: 3, fps: 30 });