spawn-term 3.3.0 → 3.3.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.
@@ -8,7 +8,6 @@ Object.defineProperty(exports, "createSession", {
8
8
  return createSession;
9
9
  }
10
10
  });
11
- var _loadInkts = require("./lib/loadInk.js");
12
11
  function _getRequireWildcardCache(nodeInterop) {
13
12
  if (typeof WeakMap !== "function") return null;
14
13
  var cacheBabelInterop = new WeakMap();
@@ -58,24 +57,32 @@ function createSession(options) {
58
57
  if (realSession) return Promise.resolve(realSession);
59
58
  if (loadError) return Promise.reject(loadError);
60
59
  if (loading) return loading;
61
- loading = new Promise(function(resolve, reject) {
62
- (0, _loadInkts.loadInk)(function(err) {
63
- if (err) {
64
- loadError = err;
65
- loading = null;
66
- return reject(err);
67
- }
68
- Promise.resolve().then(function() {
69
- return /*#__PURE__*/ _interop_require_wildcard(require("./session.js"));
70
- }).then(function(mod) {
71
- realSession = mod.createSession(options);
72
- resolve(realSession);
73
- }).catch(function(err) {
74
- loadError = err;
75
- loading = null;
76
- reject(err);
60
+ loading = Promise.resolve().then(function() {
61
+ return /*#__PURE__*/ _interop_require_wildcard(require("./lib/loadInk.js"));
62
+ }).then(function(mod) {
63
+ return new Promise(function(resolve, reject) {
64
+ mod.loadInk(function(err) {
65
+ if (err) {
66
+ loadError = err;
67
+ loading = null;
68
+ return reject(err);
69
+ }
70
+ Promise.resolve().then(function() {
71
+ return /*#__PURE__*/ _interop_require_wildcard(require("./session.js"));
72
+ }).then(function(sessionMod) {
73
+ realSession = sessionMod.createSession(options);
74
+ resolve(realSession);
75
+ }).catch(function(err) {
76
+ loadError = err;
77
+ loading = null;
78
+ reject(err);
79
+ });
77
80
  });
78
81
  });
82
+ }).catch(function(err) {
83
+ loadError = err;
84
+ loading = null;
85
+ throw err;
79
86
  });
80
87
  return loading;
81
88
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/node/spawn-term/src/createSessionWrapper.ts"],"sourcesContent":["import { loadInk } from './lib/loadInk.ts';\nimport type { ProcessOptions, SessionOptions, SpawnError, SpawnOptions, TerminalCallback } from './types.ts';\n\nexport interface Session {\n spawn(command: string, args: string[], spawnOptions: SpawnOptions, options: ProcessOptions, callback: TerminalCallback): void;\n close(): void;\n waitAndClose(callback?: () => void): void;\n}\n\nexport function createSession(options?: SessionOptions): Session {\n let realSession: Session | null = null;\n let loadError: Error | null = null;\n let loading: Promise<Session> | null = null;\n\n function getSession(): Promise<Session> {\n if (realSession) return Promise.resolve(realSession);\n if (loadError) return Promise.reject(loadError);\n if (loading) return loading;\n\n loading = new Promise((resolve, reject) => {\n loadInk((err) => {\n if (err) {\n loadError = err;\n loading = null;\n return reject(err);\n }\n import('./session.ts')\n .then((mod) => {\n realSession = mod.createSession(options);\n resolve(realSession);\n })\n .catch((err) => {\n loadError = err;\n loading = null;\n reject(err);\n });\n });\n });\n\n return loading;\n }\n\n // Start loading immediately in background\n getSession().catch(() => {});\n\n return {\n spawn(command: string, args: string[], spawnOptions: SpawnOptions, processOptions: ProcessOptions, callback: TerminalCallback): void {\n getSession()\n .then((session) => {\n session.spawn(command, args, spawnOptions, processOptions, callback);\n })\n .catch((err) => {\n callback(err as SpawnError);\n });\n },\n close(): void {\n if (realSession) realSession.close();\n },\n waitAndClose(callback?: () => void): void {\n getSession()\n .then((session) => {\n session.waitAndClose(callback);\n })\n .catch(() => {\n callback?.();\n });\n },\n };\n}\n"],"names":["createSession","options","realSession","loadError","loading","getSession","Promise","resolve","reject","loadInk","err","then","mod","catch","spawn","command","args","spawnOptions","processOptions","callback","session","close","waitAndClose"],"mappings":";;;;+BASgBA;;;eAAAA;;;yBATQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AASjB,SAASA,cAAcC,OAAwB;IACpD,IAAIC,cAA8B;IAClC,IAAIC,YAA0B;IAC9B,IAAIC,UAAmC;IAEvC,SAASC;QACP,IAAIH,aAAa,OAAOI,QAAQC,OAAO,CAACL;QACxC,IAAIC,WAAW,OAAOG,QAAQE,MAAM,CAACL;QACrC,IAAIC,SAAS,OAAOA;QAEpBA,UAAU,IAAIE,QAAQ,SAACC,SAASC;YAC9BC,IAAAA,kBAAO,EAAC,SAACC;gBACP,IAAIA,KAAK;oBACPP,YAAYO;oBACZN,UAAU;oBACV,OAAOI,OAAOE;gBAChB;gBACA;mEAAA,QAAO;mBACJC,IAAI,CAAC,SAACC;oBACLV,cAAcU,IAAIZ,aAAa,CAACC;oBAChCM,QAAQL;gBACV,GACCW,KAAK,CAAC,SAACH;oBACNP,YAAYO;oBACZN,UAAU;oBACVI,OAAOE;gBACT;YACJ;QACF;QAEA,OAAON;IACT;IAEA,0CAA0C;IAC1CC,aAAaQ,KAAK,CAAC,YAAO;IAE1B,OAAO;QACLC,OAAAA,SAAAA,MAAMC,OAAe,EAAEC,IAAc,EAAEC,YAA0B,EAAEC,cAA8B,EAAEC,QAA0B;YAC3Hd,aACGM,IAAI,CAAC,SAACS;gBACLA,QAAQN,KAAK,CAACC,SAASC,MAAMC,cAAcC,gBAAgBC;YAC7D,GACCN,KAAK,CAAC,SAACH;gBACNS,SAAST;YACX;QACJ;QACAW,OAAAA,SAAAA;YACE,IAAInB,aAAaA,YAAYmB,KAAK;QACpC;QACAC,cAAAA,SAAAA,aAAaH,QAAqB;YAChCd,aACGM,IAAI,CAAC,SAACS;gBACLA,QAAQE,YAAY,CAACH;YACvB,GACCN,KAAK,CAAC;gBACLM,qBAAAA,+BAAAA;YACF;QACJ;IACF;AACF"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/node/spawn-term/src/createSessionWrapper.ts"],"sourcesContent":["import type { ProcessOptions, SessionOptions, SpawnError, SpawnOptions, TerminalCallback } from './types.ts';\n\nexport interface Session {\n spawn(command: string, args: string[], spawnOptions: SpawnOptions, options: ProcessOptions, callback: TerminalCallback): void;\n close(): void;\n waitAndClose(callback?: () => void): void;\n}\n\nexport function createSession(options?: SessionOptions): Session {\n let realSession: Session | null = null;\n let loadError: Error | null = null;\n let loading: Promise<Session> | null = null;\n\n function getSession(): Promise<Session> {\n if (realSession) return Promise.resolve(realSession);\n if (loadError) return Promise.reject(loadError);\n if (loading) return loading;\n\n loading = import('./lib/loadInk.ts')\n .then((mod) => {\n return new Promise<Session>((resolve, reject) => {\n mod.loadInk((err) => {\n if (err) {\n loadError = err;\n loading = null;\n return reject(err);\n }\n import('./session.ts')\n .then((sessionMod) => {\n realSession = sessionMod.createSession(options);\n resolve(realSession);\n })\n .catch((err) => {\n loadError = err;\n loading = null;\n reject(err);\n });\n });\n });\n })\n .catch((err) => {\n loadError = err;\n loading = null;\n throw err;\n });\n\n return loading;\n }\n\n // Start loading immediately in background\n getSession().catch(() => {});\n\n return {\n spawn(command: string, args: string[], spawnOptions: SpawnOptions, processOptions: ProcessOptions, callback: TerminalCallback): void {\n getSession()\n .then((session) => {\n session.spawn(command, args, spawnOptions, processOptions, callback);\n })\n .catch((err) => {\n callback(err as SpawnError);\n });\n },\n close(): void {\n if (realSession) realSession.close();\n },\n waitAndClose(callback?: () => void): void {\n getSession()\n .then((session) => {\n session.waitAndClose(callback);\n })\n .catch(() => {\n callback?.();\n });\n },\n };\n}\n"],"names":["createSession","options","realSession","loadError","loading","getSession","Promise","resolve","reject","then","mod","loadInk","err","sessionMod","catch","spawn","command","args","spawnOptions","processOptions","callback","session","close","waitAndClose"],"mappings":";;;;+BAQgBA;;;eAAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAT,SAASA,cAAcC,OAAwB;IACpD,IAAIC,cAA8B;IAClC,IAAIC,YAA0B;IAC9B,IAAIC,UAAmC;IAEvC,SAASC;QACP,IAAIH,aAAa,OAAOI,QAAQC,OAAO,CAACL;QACxC,IAAIC,WAAW,OAAOG,QAAQE,MAAM,CAACL;QACrC,IAAIC,SAAS,OAAOA;QAEpBA,UAAU;2DAAA,QAAO;WACdK,IAAI,CAAC,SAACC;YACL,OAAO,IAAIJ,QAAiB,SAACC,SAASC;gBACpCE,IAAIC,OAAO,CAAC,SAACC;oBACX,IAAIA,KAAK;wBACPT,YAAYS;wBACZR,UAAU;wBACV,OAAOI,OAAOI;oBAChB;oBACA;uEAAA,QAAO;uBACJH,IAAI,CAAC,SAACI;wBACLX,cAAcW,WAAWb,aAAa,CAACC;wBACvCM,QAAQL;oBACV,GACCY,KAAK,CAAC,SAACF;wBACNT,YAAYS;wBACZR,UAAU;wBACVI,OAAOI;oBACT;gBACJ;YACF;QACF,GACCE,KAAK,CAAC,SAACF;YACNT,YAAYS;YACZR,UAAU;YACV,MAAMQ;QACR;QAEF,OAAOR;IACT;IAEA,0CAA0C;IAC1CC,aAAaS,KAAK,CAAC,YAAO;IAE1B,OAAO;QACLC,OAAAA,SAAAA,MAAMC,OAAe,EAAEC,IAAc,EAAEC,YAA0B,EAAEC,cAA8B,EAAEC,QAA0B;YAC3Hf,aACGI,IAAI,CAAC,SAACY;gBACLA,QAAQN,KAAK,CAACC,SAASC,MAAMC,cAAcC,gBAAgBC;YAC7D,GACCN,KAAK,CAAC,SAACF;gBACNQ,SAASR;YACX;QACJ;QACAU,OAAAA,SAAAA;YACE,IAAIpB,aAAaA,YAAYoB,KAAK;QACpC;QACAC,cAAAA,SAAAA,aAAaH,QAAqB;YAChCf,aACGI,IAAI,CAAC,SAACY;gBACLA,QAAQE,YAAY,CAACH;YACvB,GACCN,KAAK,CAAC;gBACLM,qBAAAA,+BAAAA;YACF;QACJ;IACF;AACF"}
@@ -16,6 +16,7 @@ _export(exports, {
16
16
  return loadInk;
17
17
  }
18
18
  });
19
+ var _fs = /*#__PURE__*/ _interop_require_default(require("fs"));
19
20
  var _installmodulelinked = /*#__PURE__*/ _interop_require_default(require("install-module-linked"));
20
21
  var _path = /*#__PURE__*/ _interop_require_default(require("path"));
21
22
  var _url = /*#__PURE__*/ _interop_require_default(require("url"));
@@ -41,14 +42,47 @@ function installDependency(name) {
41
42
  });
42
43
  });
43
44
  }
45
+ function symlinkReactFromInk() {
46
+ return new Promise(function(resolve) {
47
+ // After ink is installed, symlink react to ink's react to avoid duplicate React instances
48
+ var inkPath = _fs.default.realpathSync(_path.default.join(nodeModules, 'ink'));
49
+ var inkReactPath = _path.default.join(inkPath, 'node_modules', 'react');
50
+ var reactPath = _path.default.join(nodeModules, 'react');
51
+ // Check if react already exists
52
+ try {
53
+ var stat = _fs.default.lstatSync(reactPath);
54
+ if (stat.isSymbolicLink()) {
55
+ // It's a symlink - check if it points to the right place
56
+ var existing = _fs.default.readlinkSync(reactPath);
57
+ if (existing === inkReactPath) {
58
+ return resolve(); // Already correct
59
+ }
60
+ // Wrong symlink, remove it
61
+ _fs.default.unlinkSync(reactPath);
62
+ } else {
63
+ // It's a real directory (e.g. from devDependencies) - leave it alone
64
+ return resolve();
65
+ }
66
+ } catch (e) {
67
+ // Doesn't exist, continue to create symlink
68
+ }
69
+ // Create symlink to ink's react
70
+ try {
71
+ _fs.default.symlinkSync(inkReactPath, reactPath);
72
+ } catch (e) {
73
+ // Ignore errors - react may have been installed another way
74
+ }
75
+ resolve();
76
+ });
77
+ }
44
78
  function installInk() {
45
79
  if (installed) return Promise.resolve();
46
80
  if (installing) return installing;
47
- // Install both ink and react - both are needed by session.tsx
48
- installing = Promise.all([
49
- installDependency('ink'),
50
- installDependency('react')
51
- ]).then(function() {
81
+ // Install ink, then symlink react to ink's bundled react
82
+ // This ensures session.tsx and ink use the SAME React instance
83
+ installing = installDependency('ink').then(function() {
84
+ return symlinkReactFromInk();
85
+ }).then(function() {
52
86
  installed = true;
53
87
  }).catch(function(err) {
54
88
  installing = null;
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/node/spawn-term/src/lib/loadInk.ts"],"sourcesContent":["import installModule from 'install-module-linked';\nimport path from 'path';\nimport url from 'url';\n\n// Get the node_modules directory relative to this file\nconst _dirname = path.dirname(typeof __dirname !== 'undefined' ? __dirname : url.fileURLToPath(import.meta.url));\nconst nodeModules = path.join(_dirname, '..', '..', '..', 'node_modules');\n\nlet installed = false;\nlet installing: Promise<void> | null = null;\n\nfunction installDependency(name: string): Promise<void> {\n return new Promise((resolve, reject) => {\n // install-module-linked will:\n // 1. Check if module exists locally or in ~/.iml cache\n // 2. If not, install to ~/.iml\n // 3. Create symlink in nodeModules pointing to ~/.iml/package\n installModule(name, nodeModules, {}, (err) => {\n if (err) return reject(err);\n resolve();\n });\n });\n}\n\nfunction installInk(): Promise<void> {\n if (installed) return Promise.resolve();\n if (installing) return installing;\n\n // Install both ink and react - both are needed by session.tsx\n installing = Promise.all([installDependency('ink'), installDependency('react')])\n .then(() => {\n installed = true;\n })\n .catch((err) => {\n installing = null;\n throw err;\n });\n\n return installing;\n}\n\nexport function loadInk(callback: (err: Error | null) => void): void {\n installInk()\n .then(() => callback(null))\n .catch((err) => callback(err));\n}\n\nexport function isInkInstalled(): boolean {\n return installed;\n}\n"],"names":["isInkInstalled","loadInk","_dirname","path","dirname","__dirname","url","fileURLToPath","nodeModules","join","installed","installing","installDependency","name","Promise","resolve","reject","installModule","err","installInk","all","then","catch","callback"],"mappings":";;;;;;;;;;;QA+CgBA;eAAAA;;QANAC;eAAAA;;;0EAzCU;2DACT;0DACD;;;;;;AAEhB,uDAAuD;AACvD,IAAMC,WAAWC,aAAI,CAACC,OAAO,CAAC,OAAOC,cAAc,cAAcA,YAAYC,YAAG,CAACC,aAAa,CAAC;AAC/F,IAAMC,cAAcL,aAAI,CAACM,IAAI,CAACP,UAAU,MAAM,MAAM,MAAM;AAE1D,IAAIQ,YAAY;AAChB,IAAIC,aAAmC;AAEvC,SAASC,kBAAkBC,IAAY;IACrC,OAAO,IAAIC,QAAQ,SAACC,SAASC;QAC3B,8BAA8B;QAC9B,uDAAuD;QACvD,+BAA+B;QAC/B,8DAA8D;QAC9DC,IAAAA,4BAAa,EAACJ,MAAML,aAAa,CAAC,GAAG,SAACU;YACpC,IAAIA,KAAK,OAAOF,OAAOE;YACvBH;QACF;IACF;AACF;AAEA,SAASI;IACP,IAAIT,WAAW,OAAOI,QAAQC,OAAO;IACrC,IAAIJ,YAAY,OAAOA;IAEvB,8DAA8D;IAC9DA,aAAaG,QAAQM,GAAG,CAAC;QAACR,kBAAkB;QAAQA,kBAAkB;KAAS,EAC5ES,IAAI,CAAC;QACJX,YAAY;IACd,GACCY,KAAK,CAAC,SAACJ;QACNP,aAAa;QACb,MAAMO;IACR;IAEF,OAAOP;AACT;AAEO,SAASV,QAAQsB,QAAqC;IAC3DJ,aACGE,IAAI,CAAC;eAAME,SAAS;OACpBD,KAAK,CAAC,SAACJ;eAAQK,SAASL;;AAC7B;AAEO,SAASlB;IACd,OAAOU;AACT"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/node/spawn-term/src/lib/loadInk.ts"],"sourcesContent":["import fs from 'fs';\nimport installModule from 'install-module-linked';\nimport path from 'path';\nimport url from 'url';\n\n// Get the node_modules directory relative to this file\nconst _dirname = path.dirname(typeof __dirname !== 'undefined' ? __dirname : url.fileURLToPath(import.meta.url));\nconst nodeModules = path.join(_dirname, '..', '..', '..', 'node_modules');\n\nlet installed = false;\nlet installing: Promise<void> | null = null;\n\nfunction installDependency(name: string): Promise<void> {\n return new Promise((resolve, reject) => {\n // install-module-linked will:\n // 1. Check if module exists locally or in ~/.iml cache\n // 2. If not, install to ~/.iml\n // 3. Create symlink in nodeModules pointing to ~/.iml/package\n installModule(name, nodeModules, {}, (err) => {\n if (err) return reject(err);\n resolve();\n });\n });\n}\n\nfunction symlinkReactFromInk(): Promise<void> {\n return new Promise((resolve) => {\n // After ink is installed, symlink react to ink's react to avoid duplicate React instances\n const inkPath = fs.realpathSync(path.join(nodeModules, 'ink'));\n const inkReactPath = path.join(inkPath, 'node_modules', 'react');\n const reactPath = path.join(nodeModules, 'react');\n\n // Check if react already exists\n try {\n const stat = fs.lstatSync(reactPath);\n if (stat.isSymbolicLink()) {\n // It's a symlink - check if it points to the right place\n const existing = fs.readlinkSync(reactPath);\n if (existing === inkReactPath) {\n return resolve(); // Already correct\n }\n // Wrong symlink, remove it\n fs.unlinkSync(reactPath);\n } else {\n // It's a real directory (e.g. from devDependencies) - leave it alone\n return resolve();\n }\n } catch {\n // Doesn't exist, continue to create symlink\n }\n\n // Create symlink to ink's react\n try {\n fs.symlinkSync(inkReactPath, reactPath);\n } catch {\n // Ignore errors - react may have been installed another way\n }\n resolve();\n });\n}\n\nfunction installInk(): Promise<void> {\n if (installed) return Promise.resolve();\n if (installing) return installing;\n\n // Install ink, then symlink react to ink's bundled react\n // This ensures session.tsx and ink use the SAME React instance\n installing = installDependency('ink')\n .then(() => symlinkReactFromInk())\n .then(() => {\n installed = true;\n })\n .catch((err) => {\n installing = null;\n throw err;\n });\n\n return installing;\n}\n\nexport function loadInk(callback: (err: Error | null) => void): void {\n installInk()\n .then(() => callback(null))\n .catch((err) => callback(err));\n}\n\nexport function isInkInstalled(): boolean {\n return installed;\n}\n"],"names":["isInkInstalled","loadInk","_dirname","path","dirname","__dirname","url","fileURLToPath","nodeModules","join","installed","installing","installDependency","name","Promise","resolve","reject","installModule","err","symlinkReactFromInk","inkPath","fs","realpathSync","inkReactPath","reactPath","stat","lstatSync","isSymbolicLink","existing","readlinkSync","unlinkSync","symlinkSync","installInk","then","catch","callback"],"mappings":";;;;;;;;;;;QAsFgBA;eAAAA;;QANAC;eAAAA;;;yDAhFD;0EACW;2DACT;0DACD;;;;;;AAEhB,uDAAuD;AACvD,IAAMC,WAAWC,aAAI,CAACC,OAAO,CAAC,OAAOC,cAAc,cAAcA,YAAYC,YAAG,CAACC,aAAa,CAAC;AAC/F,IAAMC,cAAcL,aAAI,CAACM,IAAI,CAACP,UAAU,MAAM,MAAM,MAAM;AAE1D,IAAIQ,YAAY;AAChB,IAAIC,aAAmC;AAEvC,SAASC,kBAAkBC,IAAY;IACrC,OAAO,IAAIC,QAAQ,SAACC,SAASC;QAC3B,8BAA8B;QAC9B,uDAAuD;QACvD,+BAA+B;QAC/B,8DAA8D;QAC9DC,IAAAA,4BAAa,EAACJ,MAAML,aAAa,CAAC,GAAG,SAACU;YACpC,IAAIA,KAAK,OAAOF,OAAOE;YACvBH;QACF;IACF;AACF;AAEA,SAASI;IACP,OAAO,IAAIL,QAAQ,SAACC;QAClB,0FAA0F;QAC1F,IAAMK,UAAUC,WAAE,CAACC,YAAY,CAACnB,aAAI,CAACM,IAAI,CAACD,aAAa;QACvD,IAAMe,eAAepB,aAAI,CAACM,IAAI,CAACW,SAAS,gBAAgB;QACxD,IAAMI,YAAYrB,aAAI,CAACM,IAAI,CAACD,aAAa;QAEzC,gCAAgC;QAChC,IAAI;YACF,IAAMiB,OAAOJ,WAAE,CAACK,SAAS,CAACF;YAC1B,IAAIC,KAAKE,cAAc,IAAI;gBACzB,yDAAyD;gBACzD,IAAMC,WAAWP,WAAE,CAACQ,YAAY,CAACL;gBACjC,IAAII,aAAaL,cAAc;oBAC7B,OAAOR,WAAW,kBAAkB;gBACtC;gBACA,2BAA2B;gBAC3BM,WAAE,CAACS,UAAU,CAACN;YAChB,OAAO;gBACL,qEAAqE;gBACrE,OAAOT;YACT;QACF,EAAE,UAAM;QACN,4CAA4C;QAC9C;QAEA,gCAAgC;QAChC,IAAI;YACFM,WAAE,CAACU,WAAW,CAACR,cAAcC;QAC/B,EAAE,UAAM;QACN,4DAA4D;QAC9D;QACAT;IACF;AACF;AAEA,SAASiB;IACP,IAAItB,WAAW,OAAOI,QAAQC,OAAO;IACrC,IAAIJ,YAAY,OAAOA;IAEvB,yDAAyD;IACzD,+DAA+D;IAC/DA,aAAaC,kBAAkB,OAC5BqB,IAAI,CAAC;eAAMd;OACXc,IAAI,CAAC;QACJvB,YAAY;IACd,GACCwB,KAAK,CAAC,SAAChB;QACNP,aAAa;QACb,MAAMO;IACR;IAEF,OAAOP;AACT;AAEO,SAASV,QAAQkC,QAAqC;IAC3DH,aACGC,IAAI,CAAC;eAAME,SAAS;OACpBD,KAAK,CAAC,SAAChB;eAAQiB,SAASjB;;AAC7B;AAEO,SAASlB;IACd,OAAOU;AACT"}
@@ -1,4 +1,3 @@
1
- import { loadInk } from './lib/loadInk.js';
2
1
  export function createSession(options) {
3
2
  let realSession = null;
4
3
  let loadError = null;
@@ -7,22 +6,28 @@ export function createSession(options) {
7
6
  if (realSession) return Promise.resolve(realSession);
8
7
  if (loadError) return Promise.reject(loadError);
9
8
  if (loading) return loading;
10
- loading = new Promise((resolve, reject)=>{
11
- loadInk((err)=>{
12
- if (err) {
13
- loadError = err;
14
- loading = null;
15
- return reject(err);
16
- }
17
- import('./session.js').then((mod)=>{
18
- realSession = mod.createSession(options);
19
- resolve(realSession);
20
- }).catch((err)=>{
21
- loadError = err;
22
- loading = null;
23
- reject(err);
9
+ loading = import('./lib/loadInk.js').then((mod)=>{
10
+ return new Promise((resolve, reject)=>{
11
+ mod.loadInk((err)=>{
12
+ if (err) {
13
+ loadError = err;
14
+ loading = null;
15
+ return reject(err);
16
+ }
17
+ import('./session.js').then((sessionMod)=>{
18
+ realSession = sessionMod.createSession(options);
19
+ resolve(realSession);
20
+ }).catch((err)=>{
21
+ loadError = err;
22
+ loading = null;
23
+ reject(err);
24
+ });
24
25
  });
25
26
  });
27
+ }).catch((err)=>{
28
+ loadError = err;
29
+ loading = null;
30
+ throw err;
26
31
  });
27
32
  return loading;
28
33
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/node/spawn-term/src/createSessionWrapper.ts"],"sourcesContent":["import { loadInk } from './lib/loadInk.ts';\nimport type { ProcessOptions, SessionOptions, SpawnError, SpawnOptions, TerminalCallback } from './types.ts';\n\nexport interface Session {\n spawn(command: string, args: string[], spawnOptions: SpawnOptions, options: ProcessOptions, callback: TerminalCallback): void;\n close(): void;\n waitAndClose(callback?: () => void): void;\n}\n\nexport function createSession(options?: SessionOptions): Session {\n let realSession: Session | null = null;\n let loadError: Error | null = null;\n let loading: Promise<Session> | null = null;\n\n function getSession(): Promise<Session> {\n if (realSession) return Promise.resolve(realSession);\n if (loadError) return Promise.reject(loadError);\n if (loading) return loading;\n\n loading = new Promise((resolve, reject) => {\n loadInk((err) => {\n if (err) {\n loadError = err;\n loading = null;\n return reject(err);\n }\n import('./session.ts')\n .then((mod) => {\n realSession = mod.createSession(options);\n resolve(realSession);\n })\n .catch((err) => {\n loadError = err;\n loading = null;\n reject(err);\n });\n });\n });\n\n return loading;\n }\n\n // Start loading immediately in background\n getSession().catch(() => {});\n\n return {\n spawn(command: string, args: string[], spawnOptions: SpawnOptions, processOptions: ProcessOptions, callback: TerminalCallback): void {\n getSession()\n .then((session) => {\n session.spawn(command, args, spawnOptions, processOptions, callback);\n })\n .catch((err) => {\n callback(err as SpawnError);\n });\n },\n close(): void {\n if (realSession) realSession.close();\n },\n waitAndClose(callback?: () => void): void {\n getSession()\n .then((session) => {\n session.waitAndClose(callback);\n })\n .catch(() => {\n callback?.();\n });\n },\n };\n}\n"],"names":["loadInk","createSession","options","realSession","loadError","loading","getSession","Promise","resolve","reject","err","then","mod","catch","spawn","command","args","spawnOptions","processOptions","callback","session","close","waitAndClose"],"mappings":"AAAA,SAASA,OAAO,QAAQ,mBAAmB;AAS3C,OAAO,SAASC,cAAcC,OAAwB;IACpD,IAAIC,cAA8B;IAClC,IAAIC,YAA0B;IAC9B,IAAIC,UAAmC;IAEvC,SAASC;QACP,IAAIH,aAAa,OAAOI,QAAQC,OAAO,CAACL;QACxC,IAAIC,WAAW,OAAOG,QAAQE,MAAM,CAACL;QACrC,IAAIC,SAAS,OAAOA;QAEpBA,UAAU,IAAIE,QAAQ,CAACC,SAASC;YAC9BT,QAAQ,CAACU;gBACP,IAAIA,KAAK;oBACPN,YAAYM;oBACZL,UAAU;oBACV,OAAOI,OAAOC;gBAChB;gBACA,MAAM,CAAC,gBACJC,IAAI,CAAC,CAACC;oBACLT,cAAcS,IAAIX,aAAa,CAACC;oBAChCM,QAAQL;gBACV,GACCU,KAAK,CAAC,CAACH;oBACNN,YAAYM;oBACZL,UAAU;oBACVI,OAAOC;gBACT;YACJ;QACF;QAEA,OAAOL;IACT;IAEA,0CAA0C;IAC1CC,aAAaO,KAAK,CAAC,KAAO;IAE1B,OAAO;QACLC,OAAMC,OAAe,EAAEC,IAAc,EAAEC,YAA0B,EAAEC,cAA8B,EAAEC,QAA0B;YAC3Hb,aACGK,IAAI,CAAC,CAACS;gBACLA,QAAQN,KAAK,CAACC,SAASC,MAAMC,cAAcC,gBAAgBC;YAC7D,GACCN,KAAK,CAAC,CAACH;gBACNS,SAAST;YACX;QACJ;QACAW;YACE,IAAIlB,aAAaA,YAAYkB,KAAK;QACpC;QACAC,cAAaH,QAAqB;YAChCb,aACGK,IAAI,CAAC,CAACS;gBACLA,QAAQE,YAAY,CAACH;YACvB,GACCN,KAAK,CAAC;gBACLM,qBAAAA,+BAAAA;YACF;QACJ;IACF;AACF"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/node/spawn-term/src/createSessionWrapper.ts"],"sourcesContent":["import type { ProcessOptions, SessionOptions, SpawnError, SpawnOptions, TerminalCallback } from './types.ts';\n\nexport interface Session {\n spawn(command: string, args: string[], spawnOptions: SpawnOptions, options: ProcessOptions, callback: TerminalCallback): void;\n close(): void;\n waitAndClose(callback?: () => void): void;\n}\n\nexport function createSession(options?: SessionOptions): Session {\n let realSession: Session | null = null;\n let loadError: Error | null = null;\n let loading: Promise<Session> | null = null;\n\n function getSession(): Promise<Session> {\n if (realSession) return Promise.resolve(realSession);\n if (loadError) return Promise.reject(loadError);\n if (loading) return loading;\n\n loading = import('./lib/loadInk.ts')\n .then((mod) => {\n return new Promise<Session>((resolve, reject) => {\n mod.loadInk((err) => {\n if (err) {\n loadError = err;\n loading = null;\n return reject(err);\n }\n import('./session.ts')\n .then((sessionMod) => {\n realSession = sessionMod.createSession(options);\n resolve(realSession);\n })\n .catch((err) => {\n loadError = err;\n loading = null;\n reject(err);\n });\n });\n });\n })\n .catch((err) => {\n loadError = err;\n loading = null;\n throw err;\n });\n\n return loading;\n }\n\n // Start loading immediately in background\n getSession().catch(() => {});\n\n return {\n spawn(command: string, args: string[], spawnOptions: SpawnOptions, processOptions: ProcessOptions, callback: TerminalCallback): void {\n getSession()\n .then((session) => {\n session.spawn(command, args, spawnOptions, processOptions, callback);\n })\n .catch((err) => {\n callback(err as SpawnError);\n });\n },\n close(): void {\n if (realSession) realSession.close();\n },\n waitAndClose(callback?: () => void): void {\n getSession()\n .then((session) => {\n session.waitAndClose(callback);\n })\n .catch(() => {\n callback?.();\n });\n },\n };\n}\n"],"names":["createSession","options","realSession","loadError","loading","getSession","Promise","resolve","reject","then","mod","loadInk","err","sessionMod","catch","spawn","command","args","spawnOptions","processOptions","callback","session","close","waitAndClose"],"mappings":"AAQA,OAAO,SAASA,cAAcC,OAAwB;IACpD,IAAIC,cAA8B;IAClC,IAAIC,YAA0B;IAC9B,IAAIC,UAAmC;IAEvC,SAASC;QACP,IAAIH,aAAa,OAAOI,QAAQC,OAAO,CAACL;QACxC,IAAIC,WAAW,OAAOG,QAAQE,MAAM,CAACL;QACrC,IAAIC,SAAS,OAAOA;QAEpBA,UAAU,MAAM,CAAC,oBACdK,IAAI,CAAC,CAACC;YACL,OAAO,IAAIJ,QAAiB,CAACC,SAASC;gBACpCE,IAAIC,OAAO,CAAC,CAACC;oBACX,IAAIA,KAAK;wBACPT,YAAYS;wBACZR,UAAU;wBACV,OAAOI,OAAOI;oBAChB;oBACA,MAAM,CAAC,gBACJH,IAAI,CAAC,CAACI;wBACLX,cAAcW,WAAWb,aAAa,CAACC;wBACvCM,QAAQL;oBACV,GACCY,KAAK,CAAC,CAACF;wBACNT,YAAYS;wBACZR,UAAU;wBACVI,OAAOI;oBACT;gBACJ;YACF;QACF,GACCE,KAAK,CAAC,CAACF;YACNT,YAAYS;YACZR,UAAU;YACV,MAAMQ;QACR;QAEF,OAAOR;IACT;IAEA,0CAA0C;IAC1CC,aAAaS,KAAK,CAAC,KAAO;IAE1B,OAAO;QACLC,OAAMC,OAAe,EAAEC,IAAc,EAAEC,YAA0B,EAAEC,cAA8B,EAAEC,QAA0B;YAC3Hf,aACGI,IAAI,CAAC,CAACY;gBACLA,QAAQN,KAAK,CAACC,SAASC,MAAMC,cAAcC,gBAAgBC;YAC7D,GACCN,KAAK,CAAC,CAACF;gBACNQ,SAASR;YACX;QACJ;QACAU;YACE,IAAIpB,aAAaA,YAAYoB,KAAK;QACpC;QACAC,cAAaH,QAAqB;YAChCf,aACGI,IAAI,CAAC,CAACY;gBACLA,QAAQE,YAAY,CAACH;YACvB,GACCN,KAAK,CAAC;gBACLM,qBAAAA,+BAAAA;YACF;QACJ;IACF;AACF"}
@@ -1,3 +1,4 @@
1
+ import fs from 'fs';
1
2
  import installModule from 'install-module-linked';
2
3
  import path from 'path';
3
4
  import url from 'url';
@@ -18,14 +19,45 @@ function installDependency(name) {
18
19
  });
19
20
  });
20
21
  }
22
+ function symlinkReactFromInk() {
23
+ return new Promise((resolve)=>{
24
+ // After ink is installed, symlink react to ink's react to avoid duplicate React instances
25
+ const inkPath = fs.realpathSync(path.join(nodeModules, 'ink'));
26
+ const inkReactPath = path.join(inkPath, 'node_modules', 'react');
27
+ const reactPath = path.join(nodeModules, 'react');
28
+ // Check if react already exists
29
+ try {
30
+ const stat = fs.lstatSync(reactPath);
31
+ if (stat.isSymbolicLink()) {
32
+ // It's a symlink - check if it points to the right place
33
+ const existing = fs.readlinkSync(reactPath);
34
+ if (existing === inkReactPath) {
35
+ return resolve(); // Already correct
36
+ }
37
+ // Wrong symlink, remove it
38
+ fs.unlinkSync(reactPath);
39
+ } else {
40
+ // It's a real directory (e.g. from devDependencies) - leave it alone
41
+ return resolve();
42
+ }
43
+ } catch {
44
+ // Doesn't exist, continue to create symlink
45
+ }
46
+ // Create symlink to ink's react
47
+ try {
48
+ fs.symlinkSync(inkReactPath, reactPath);
49
+ } catch {
50
+ // Ignore errors - react may have been installed another way
51
+ }
52
+ resolve();
53
+ });
54
+ }
21
55
  function installInk() {
22
56
  if (installed) return Promise.resolve();
23
57
  if (installing) return installing;
24
- // Install both ink and react - both are needed by session.tsx
25
- installing = Promise.all([
26
- installDependency('ink'),
27
- installDependency('react')
28
- ]).then(()=>{
58
+ // Install ink, then symlink react to ink's bundled react
59
+ // This ensures session.tsx and ink use the SAME React instance
60
+ installing = installDependency('ink').then(()=>symlinkReactFromInk()).then(()=>{
29
61
  installed = true;
30
62
  }).catch((err)=>{
31
63
  installing = null;
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/node/spawn-term/src/lib/loadInk.ts"],"sourcesContent":["import installModule from 'install-module-linked';\nimport path from 'path';\nimport url from 'url';\n\n// Get the node_modules directory relative to this file\nconst _dirname = path.dirname(typeof __dirname !== 'undefined' ? __dirname : url.fileURLToPath(import.meta.url));\nconst nodeModules = path.join(_dirname, '..', '..', '..', 'node_modules');\n\nlet installed = false;\nlet installing: Promise<void> | null = null;\n\nfunction installDependency(name: string): Promise<void> {\n return new Promise((resolve, reject) => {\n // install-module-linked will:\n // 1. Check if module exists locally or in ~/.iml cache\n // 2. If not, install to ~/.iml\n // 3. Create symlink in nodeModules pointing to ~/.iml/package\n installModule(name, nodeModules, {}, (err) => {\n if (err) return reject(err);\n resolve();\n });\n });\n}\n\nfunction installInk(): Promise<void> {\n if (installed) return Promise.resolve();\n if (installing) return installing;\n\n // Install both ink and react - both are needed by session.tsx\n installing = Promise.all([installDependency('ink'), installDependency('react')])\n .then(() => {\n installed = true;\n })\n .catch((err) => {\n installing = null;\n throw err;\n });\n\n return installing;\n}\n\nexport function loadInk(callback: (err: Error | null) => void): void {\n installInk()\n .then(() => callback(null))\n .catch((err) => callback(err));\n}\n\nexport function isInkInstalled(): boolean {\n return installed;\n}\n"],"names":["installModule","path","url","_dirname","dirname","__dirname","fileURLToPath","nodeModules","join","installed","installing","installDependency","name","Promise","resolve","reject","err","installInk","all","then","catch","loadInk","callback","isInkInstalled"],"mappings":"AAAA,OAAOA,mBAAmB,wBAAwB;AAClD,OAAOC,UAAU,OAAO;AACxB,OAAOC,SAAS,MAAM;AAEtB,uDAAuD;AACvD,MAAMC,WAAWF,KAAKG,OAAO,CAAC,OAAOC,cAAc,cAAcA,YAAYH,IAAII,aAAa,CAAC,YAAYJ,GAAG;AAC9G,MAAMK,cAAcN,KAAKO,IAAI,CAACL,UAAU,MAAM,MAAM,MAAM;AAE1D,IAAIM,YAAY;AAChB,IAAIC,aAAmC;AAEvC,SAASC,kBAAkBC,IAAY;IACrC,OAAO,IAAIC,QAAQ,CAACC,SAASC;QAC3B,8BAA8B;QAC9B,uDAAuD;QACvD,+BAA+B;QAC/B,8DAA8D;QAC9Df,cAAcY,MAAML,aAAa,CAAC,GAAG,CAACS;YACpC,IAAIA,KAAK,OAAOD,OAAOC;YACvBF;QACF;IACF;AACF;AAEA,SAASG;IACP,IAAIR,WAAW,OAAOI,QAAQC,OAAO;IACrC,IAAIJ,YAAY,OAAOA;IAEvB,8DAA8D;IAC9DA,aAAaG,QAAQK,GAAG,CAAC;QAACP,kBAAkB;QAAQA,kBAAkB;KAAS,EAC5EQ,IAAI,CAAC;QACJV,YAAY;IACd,GACCW,KAAK,CAAC,CAACJ;QACNN,aAAa;QACb,MAAMM;IACR;IAEF,OAAON;AACT;AAEA,OAAO,SAASW,QAAQC,QAAqC;IAC3DL,aACGE,IAAI,CAAC,IAAMG,SAAS,OACpBF,KAAK,CAAC,CAACJ,MAAQM,SAASN;AAC7B;AAEA,OAAO,SAASO;IACd,OAAOd;AACT"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/node/spawn-term/src/lib/loadInk.ts"],"sourcesContent":["import fs from 'fs';\nimport installModule from 'install-module-linked';\nimport path from 'path';\nimport url from 'url';\n\n// Get the node_modules directory relative to this file\nconst _dirname = path.dirname(typeof __dirname !== 'undefined' ? __dirname : url.fileURLToPath(import.meta.url));\nconst nodeModules = path.join(_dirname, '..', '..', '..', 'node_modules');\n\nlet installed = false;\nlet installing: Promise<void> | null = null;\n\nfunction installDependency(name: string): Promise<void> {\n return new Promise((resolve, reject) => {\n // install-module-linked will:\n // 1. Check if module exists locally or in ~/.iml cache\n // 2. If not, install to ~/.iml\n // 3. Create symlink in nodeModules pointing to ~/.iml/package\n installModule(name, nodeModules, {}, (err) => {\n if (err) return reject(err);\n resolve();\n });\n });\n}\n\nfunction symlinkReactFromInk(): Promise<void> {\n return new Promise((resolve) => {\n // After ink is installed, symlink react to ink's react to avoid duplicate React instances\n const inkPath = fs.realpathSync(path.join(nodeModules, 'ink'));\n const inkReactPath = path.join(inkPath, 'node_modules', 'react');\n const reactPath = path.join(nodeModules, 'react');\n\n // Check if react already exists\n try {\n const stat = fs.lstatSync(reactPath);\n if (stat.isSymbolicLink()) {\n // It's a symlink - check if it points to the right place\n const existing = fs.readlinkSync(reactPath);\n if (existing === inkReactPath) {\n return resolve(); // Already correct\n }\n // Wrong symlink, remove it\n fs.unlinkSync(reactPath);\n } else {\n // It's a real directory (e.g. from devDependencies) - leave it alone\n return resolve();\n }\n } catch {\n // Doesn't exist, continue to create symlink\n }\n\n // Create symlink to ink's react\n try {\n fs.symlinkSync(inkReactPath, reactPath);\n } catch {\n // Ignore errors - react may have been installed another way\n }\n resolve();\n });\n}\n\nfunction installInk(): Promise<void> {\n if (installed) return Promise.resolve();\n if (installing) return installing;\n\n // Install ink, then symlink react to ink's bundled react\n // This ensures session.tsx and ink use the SAME React instance\n installing = installDependency('ink')\n .then(() => symlinkReactFromInk())\n .then(() => {\n installed = true;\n })\n .catch((err) => {\n installing = null;\n throw err;\n });\n\n return installing;\n}\n\nexport function loadInk(callback: (err: Error | null) => void): void {\n installInk()\n .then(() => callback(null))\n .catch((err) => callback(err));\n}\n\nexport function isInkInstalled(): boolean {\n return installed;\n}\n"],"names":["fs","installModule","path","url","_dirname","dirname","__dirname","fileURLToPath","nodeModules","join","installed","installing","installDependency","name","Promise","resolve","reject","err","symlinkReactFromInk","inkPath","realpathSync","inkReactPath","reactPath","stat","lstatSync","isSymbolicLink","existing","readlinkSync","unlinkSync","symlinkSync","installInk","then","catch","loadInk","callback","isInkInstalled"],"mappings":"AAAA,OAAOA,QAAQ,KAAK;AACpB,OAAOC,mBAAmB,wBAAwB;AAClD,OAAOC,UAAU,OAAO;AACxB,OAAOC,SAAS,MAAM;AAEtB,uDAAuD;AACvD,MAAMC,WAAWF,KAAKG,OAAO,CAAC,OAAOC,cAAc,cAAcA,YAAYH,IAAII,aAAa,CAAC,YAAYJ,GAAG;AAC9G,MAAMK,cAAcN,KAAKO,IAAI,CAACL,UAAU,MAAM,MAAM,MAAM;AAE1D,IAAIM,YAAY;AAChB,IAAIC,aAAmC;AAEvC,SAASC,kBAAkBC,IAAY;IACrC,OAAO,IAAIC,QAAQ,CAACC,SAASC;QAC3B,8BAA8B;QAC9B,uDAAuD;QACvD,+BAA+B;QAC/B,8DAA8D;QAC9Df,cAAcY,MAAML,aAAa,CAAC,GAAG,CAACS;YACpC,IAAIA,KAAK,OAAOD,OAAOC;YACvBF;QACF;IACF;AACF;AAEA,SAASG;IACP,OAAO,IAAIJ,QAAQ,CAACC;QAClB,0FAA0F;QAC1F,MAAMI,UAAUnB,GAAGoB,YAAY,CAAClB,KAAKO,IAAI,CAACD,aAAa;QACvD,MAAMa,eAAenB,KAAKO,IAAI,CAACU,SAAS,gBAAgB;QACxD,MAAMG,YAAYpB,KAAKO,IAAI,CAACD,aAAa;QAEzC,gCAAgC;QAChC,IAAI;YACF,MAAMe,OAAOvB,GAAGwB,SAAS,CAACF;YAC1B,IAAIC,KAAKE,cAAc,IAAI;gBACzB,yDAAyD;gBACzD,MAAMC,WAAW1B,GAAG2B,YAAY,CAACL;gBACjC,IAAII,aAAaL,cAAc;oBAC7B,OAAON,WAAW,kBAAkB;gBACtC;gBACA,2BAA2B;gBAC3Bf,GAAG4B,UAAU,CAACN;YAChB,OAAO;gBACL,qEAAqE;gBACrE,OAAOP;YACT;QACF,EAAE,OAAM;QACN,4CAA4C;QAC9C;QAEA,gCAAgC;QAChC,IAAI;YACFf,GAAG6B,WAAW,CAACR,cAAcC;QAC/B,EAAE,OAAM;QACN,4DAA4D;QAC9D;QACAP;IACF;AACF;AAEA,SAASe;IACP,IAAIpB,WAAW,OAAOI,QAAQC,OAAO;IACrC,IAAIJ,YAAY,OAAOA;IAEvB,yDAAyD;IACzD,+DAA+D;IAC/DA,aAAaC,kBAAkB,OAC5BmB,IAAI,CAAC,IAAMb,uBACXa,IAAI,CAAC;QACJrB,YAAY;IACd,GACCsB,KAAK,CAAC,CAACf;QACNN,aAAa;QACb,MAAMM;IACR;IAEF,OAAON;AACT;AAEA,OAAO,SAASsB,QAAQC,QAAqC;IAC3DJ,aACGC,IAAI,CAAC,IAAMG,SAAS,OACpBF,KAAK,CAAC,CAACf,MAAQiB,SAASjB;AAC7B;AAEA,OAAO,SAASkB;IACd,OAAOzB;AACT"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "spawn-term",
3
- "version": "3.3.0",
3
+ "version": "3.3.2",
4
4
  "description": "Formats spawn with for terminal grouping",
5
5
  "keywords": [
6
6
  "spawn",