@particle-academy/fancy-term 0.6.1 → 0.6.2

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
@@ -14,6 +14,58 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
14
14
 
15
15
  ## [Unreleased]
16
16
 
17
+ ## 0.6.2 — 2026-10-10
18
+
19
+ ### Fixed
20
+
21
+ - **The ESM bundle could not be imported under plain Node.** It emitted
22
+ `import { Terminal } from "@xterm/xterm"`, and because that package is
23
+ CommonJS-only with exports Node's `cjs-module-lexer` cannot statically detect,
24
+ any bundler-free import threw:
25
+
26
+ ```
27
+ SyntaxError: Named export 'Terminal' not found. The requested module
28
+ '@xterm/xterm' is a CommonJS module, which may not support all
29
+ module.exports as named exports.
30
+ ```
31
+
32
+ `require("@xterm/xterm")` worked fine, which is exactly why this read as our
33
+ bug rather than a lexer limit. **Vite's interop hid it**, so the component
34
+ worked in every bundled app and nobody hit it — until an SSR consumer tried
35
+ `react-dom/server`. Reported with measurements by `claude · genie2`, whose SSR
36
+ render tests died at import on CI and in a test VM.
37
+
38
+ Fixed by importing the default and destructuring, which works under Node and
39
+ every bundler. **Nothing to change on your side** — the public API is
40
+ identical.
41
+
42
+ - **A real-Node import check now runs on every `npm test`**
43
+ (`scripts/check-esm-import.mjs`). This defect was invisible to the whole
44
+ suite and always would have been: **vitest runs through Vite, whose CommonJS
45
+ interop rewrites the exact import that breaks.** The check loads the built
46
+ bundle in a separate Node process, with a positive control that the import
47
+ actually yields `Terminal` + `useTerminal` — so a bundle that imported
48
+ nothing cannot pass it.
49
+
50
+ ### Documentation
51
+
52
+ - **`docs/Terminal.md` now says this package is CLIENT-ONLY, with the
53
+ measurement.** A server-side import throws `ReferenceError: self is not
54
+ defined` **before any component runs**, and the cause is narrower than it
55
+ looks:
56
+
57
+ | import, in plain Node | result |
58
+ |---|---|
59
+ | `@xterm/xterm` | loads |
60
+ | **`@xterm/addon-fit`** | **`ReferenceError: self is not defined`** |
61
+
62
+ `@xterm/addon-fit` is a UMD bundle whose wrapper references the browser global
63
+ `self`. **That is upstream packaging and is NOT fixed by this release** — it
64
+ cannot be, from here. Load the package from a dynamic, client-side `import()`
65
+ for SSR; the docs show the shape. Worth stating plainly because the two
66
+ failures are easy to conflate, and a consumer who finds out the way genie2 did
67
+ spends a CI run on it.
68
+
17
69
  ## 0.6.1 — 2026-10-10
18
70
 
19
71
  ### Added
package/dist/index.cjs CHANGED
@@ -1,10 +1,15 @@
1
1
  'use strict';
2
2
 
3
3
  var react = require('react');
4
- var xterm = require('@xterm/xterm');
5
- var addonFit = require('@xterm/addon-fit');
4
+ var xtermPkg = require('@xterm/xterm');
5
+ var addonFitPkg = require('@xterm/addon-fit');
6
6
  var jsxRuntime = require('react/jsx-runtime');
7
7
 
8
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
9
+
10
+ var xtermPkg__default = /*#__PURE__*/_interopDefault(xtermPkg);
11
+ var addonFitPkg__default = /*#__PURE__*/_interopDefault(addonFitPkg);
12
+
8
13
  // src/components/Terminal.tsx
9
14
 
10
15
  // src/theme.ts
@@ -219,6 +224,8 @@ function registerOsc52(term, provider, mode) {
219
224
  }
220
225
 
221
226
  // src/hooks/use-terminal.ts
227
+ var { Terminal: XTermCtor } = xtermPkg__default.default;
228
+ var { FitAddon: FitAddonCtor } = addonFitPkg__default.default;
222
229
  var DEFAULT_FONT = 'ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace';
223
230
  function makeDeferred() {
224
231
  let resolve;
@@ -295,7 +302,7 @@ function useTerminal(containerRef, options = {}) {
295
302
  const el = containerRef.current;
296
303
  if (!el) return;
297
304
  const o = optsRef.current;
298
- const term = new xterm.Terminal({
305
+ const term = new XTermCtor({
299
306
  theme: o.theme ?? fancyDarkTheme,
300
307
  // Only pass rows/cols when explicitly set. xterm validates these and
301
308
  // console-errors "rows/cols must be numeric" if handed `undefined`, rather
@@ -310,7 +317,7 @@ function useTerminal(containerRef, options = {}) {
310
317
  scrollback: o.scrollback ?? 1e3,
311
318
  allowProposedApi: true
312
319
  });
313
- const fitAddon = new addonFit.FitAddon();
320
+ const fitAddon = new FitAddonCtor();
314
321
  term.loadAddon(fitAddon);
315
322
  term.open(el);
316
323
  xtermRef.current = term;