@gjsify/process 0.3.13 → 0.3.14

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.
Files changed (2) hide show
  1. package/lib/esm/index.js +598 -632
  2. package/package.json +6 -6
package/lib/esm/index.js CHANGED
@@ -1,642 +1,636 @@
1
1
  import { EventEmitter } from "@gjsify/events";
2
2
  import { ensureMainLoop, quitMainLoop } from "@gjsify/utils";
3
3
  import { nativeTerminal } from "@gjsify/terminal-native";
4
+
5
+ //#region src/index.ts
4
6
  const _encoder = new TextEncoder();
5
7
  function getGjsGlobal() {
6
- return globalThis;
8
+ return globalThis;
7
9
  }
8
10
  function detectGjsVersion() {
9
- try {
10
- const system = getGjsGlobal().imports?.system;
11
- if (system?.version !== void 0) {
12
- const v = Number(system.version);
13
- const major = Math.floor(v / 1e4);
14
- const minor = Math.floor(v % 1e4 / 100);
15
- const patch = v % 100;
16
- return `${major}.${minor}.${patch}`;
17
- }
18
- } catch {
19
- }
20
- return void 0;
11
+ try {
12
+ const system = getGjsGlobal().imports?.system;
13
+ if (system?.version !== undefined) {
14
+ const v = Number(system.version);
15
+ const major = Math.floor(v / 1e4);
16
+ const minor = Math.floor(v % 1e4 / 100);
17
+ const patch = v % 100;
18
+ return `${major}.${minor}.${patch}`;
19
+ }
20
+ } catch {}
21
+ return undefined;
21
22
  }
22
23
  function detectNodeVersion() {
23
- if (typeof globalThis.process?.versions?.node === "string") {
24
- return globalThis.process.versions.node;
25
- }
26
- return void 0;
24
+ if (typeof globalThis.process?.versions?.node === "string") {
25
+ return globalThis.process.versions.node;
26
+ }
27
+ return undefined;
27
28
  }
28
29
  function detectVersionInfo() {
29
- const nodeVersion = detectNodeVersion();
30
- if (nodeVersion) {
31
- return {
32
- version: globalThis.process.version,
33
- versions: { ...globalThis.process.versions },
34
- title: globalThis.process?.title || "node"
35
- };
36
- }
37
- const gjsVersion = detectGjsVersion();
38
- const versions2 = {
39
- node: "20.0.0"
40
- // Compatibility version — many npm packages check process.versions.node
41
- };
42
- if (gjsVersion) versions2.gjs = gjsVersion;
43
- return {
44
- version: "v20.0.0",
45
- // Compatibility version for Node.js API level checks
46
- versions: versions2,
47
- title: "gjs"
48
- };
30
+ const nodeVersion = detectNodeVersion();
31
+ if (nodeVersion) {
32
+ return {
33
+ version: globalThis.process.version,
34
+ versions: { ...globalThis.process.versions },
35
+ title: globalThis.process?.title || "node"
36
+ };
37
+ }
38
+ const gjsVersion = detectGjsVersion();
39
+ const versions = { node: "20.0.0" };
40
+ if (gjsVersion) versions.gjs = gjsVersion;
41
+ return {
42
+ version: "v20.0.0",
43
+ versions,
44
+ title: "gjs"
45
+ };
49
46
  }
50
47
  function detectPpid() {
51
- if (typeof globalThis.process?.ppid === "number") {
52
- return globalThis.process.ppid;
53
- }
54
- try {
55
- const GLib = getGjsGlobal().imports?.gi?.GLib;
56
- if (GLib) {
57
- const [, contents] = GLib.file_get_contents("/proc/self/status");
58
- if (contents) {
59
- const str = new TextDecoder().decode(contents);
60
- const match = str.match(/PPid:\s+(\d+)/);
61
- if (match) return parseInt(match[1], 10);
62
- }
63
- }
64
- } catch {
65
- }
66
- return 0;
48
+ if (typeof globalThis.process?.ppid === "number") {
49
+ return globalThis.process.ppid;
50
+ }
51
+ try {
52
+ const GLib = getGjsGlobal().imports?.gi?.GLib;
53
+ if (GLib) {
54
+ const [, contents] = GLib.file_get_contents("/proc/self/status");
55
+ if (contents) {
56
+ const str = new TextDecoder().decode(contents);
57
+ const match = str.match(/PPid:\s+(\d+)/);
58
+ if (match) return parseInt(match[1], 10);
59
+ }
60
+ }
61
+ } catch {}
62
+ return 0;
67
63
  }
68
64
  function detectPlatform() {
69
- try {
70
- const GLib = getGjsGlobal().imports?.gi?.GLib;
71
- if (GLib) {
72
- const osInfo = GLib.get_os_info("ID");
73
- if (osInfo) return "linux";
74
- }
75
- } catch {
76
- }
77
- if (typeof getGjsGlobal().imports?.system !== "undefined") {
78
- return "linux";
79
- }
80
- if (typeof globalThis.process?.platform === "string") {
81
- return globalThis.process.platform;
82
- }
83
- return "linux";
65
+ try {
66
+ const GLib = getGjsGlobal().imports?.gi?.GLib;
67
+ if (GLib) {
68
+ const osInfo = GLib.get_os_info("ID");
69
+ if (osInfo) return "linux";
70
+ }
71
+ } catch {}
72
+ if (typeof getGjsGlobal().imports?.system !== "undefined") {
73
+ return "linux";
74
+ }
75
+ if (typeof globalThis.process?.platform === "string") {
76
+ return globalThis.process.platform;
77
+ }
78
+ return "linux";
84
79
  }
85
80
  function detectArch() {
86
- if (typeof globalThis.process?.arch === "string") {
87
- return globalThis.process.arch;
88
- }
89
- return "x64";
81
+ if (typeof globalThis.process?.arch === "string") {
82
+ return globalThis.process.arch;
83
+ }
84
+ return "x64";
90
85
  }
91
86
  function getCwd() {
92
- try {
93
- const GLib = getGjsGlobal().imports?.gi?.GLib;
94
- if (GLib?.get_current_dir) return GLib.get_current_dir();
95
- } catch {
96
- }
97
- return "/";
87
+ try {
88
+ const GLib = getGjsGlobal().imports?.gi?.GLib;
89
+ if (GLib?.get_current_dir) return GLib.get_current_dir();
90
+ } catch {}
91
+ return "/";
98
92
  }
99
93
  function getEnvProxy() {
100
- if (typeof globalThis.process?.env === "object") {
101
- return globalThis.process.env;
102
- }
103
- try {
104
- const GLib = getGjsGlobal().imports?.gi?.GLib;
105
- if (GLib) {
106
- return new Proxy({}, {
107
- get(_target, prop) {
108
- if (typeof prop !== "string") return void 0;
109
- return GLib.getenv(prop) ?? void 0;
110
- },
111
- set(_target, prop, value) {
112
- if (typeof prop !== "string") return false;
113
- GLib.setenv(prop, String(value), true);
114
- return true;
115
- },
116
- deleteProperty(_target, prop) {
117
- if (typeof prop !== "string") return false;
118
- GLib.unsetenv(prop);
119
- return true;
120
- },
121
- has(_target, prop) {
122
- if (typeof prop !== "string") return false;
123
- return GLib.getenv(prop) !== null;
124
- },
125
- ownKeys(_target) {
126
- const envp = GLib.listenv();
127
- return envp;
128
- },
129
- getOwnPropertyDescriptor(_target, prop) {
130
- if (typeof prop !== "string") return void 0;
131
- const val = GLib.getenv(prop);
132
- if (val === null) return void 0;
133
- return { configurable: true, enumerable: true, writable: true, value: val };
134
- }
135
- });
136
- }
137
- } catch {
138
- }
139
- return {};
94
+ if (typeof globalThis.process?.env === "object") {
95
+ return globalThis.process.env;
96
+ }
97
+ try {
98
+ const GLib = getGjsGlobal().imports?.gi?.GLib;
99
+ if (GLib) {
100
+ return new Proxy({}, {
101
+ get(_target, prop) {
102
+ if (typeof prop !== "string") return undefined;
103
+ return GLib.getenv(prop) ?? undefined;
104
+ },
105
+ set(_target, prop, value) {
106
+ if (typeof prop !== "string") return false;
107
+ GLib.setenv(prop, String(value), true);
108
+ return true;
109
+ },
110
+ deleteProperty(_target, prop) {
111
+ if (typeof prop !== "string") return false;
112
+ GLib.unsetenv(prop);
113
+ return true;
114
+ },
115
+ has(_target, prop) {
116
+ if (typeof prop !== "string") return false;
117
+ return GLib.getenv(prop) !== null;
118
+ },
119
+ ownKeys(_target) {
120
+ const envp = GLib.listenv();
121
+ return envp;
122
+ },
123
+ getOwnPropertyDescriptor(_target, prop) {
124
+ if (typeof prop !== "string") return undefined;
125
+ const val = GLib.getenv(prop);
126
+ if (val === null) return undefined;
127
+ return {
128
+ configurable: true,
129
+ enumerable: true,
130
+ writable: true,
131
+ value: val
132
+ };
133
+ }
134
+ });
135
+ }
136
+ } catch {}
137
+ return {};
140
138
  }
141
139
  function getArgv() {
142
- if (typeof globalThis.process?.argv !== "undefined") {
143
- return globalThis.process.argv;
144
- }
145
- try {
146
- const system = getGjsGlobal().imports?.system;
147
- if (system?.programArgs) {
148
- return ["gjs", system.programInvocationName || "", ...system.programArgs];
149
- }
150
- } catch {
151
- }
152
- return ["gjs"];
140
+ if (typeof globalThis.process?.argv !== "undefined") {
141
+ return globalThis.process.argv;
142
+ }
143
+ try {
144
+ const system = getGjsGlobal().imports?.system;
145
+ if (system?.programArgs) {
146
+ return [
147
+ "gjs",
148
+ system.programInvocationName || "",
149
+ ...system.programArgs
150
+ ];
151
+ }
152
+ } catch {}
153
+ return ["gjs"];
153
154
  }
154
155
  function getExecPath() {
155
- if (typeof globalThis.process?.execPath === "string") {
156
- return globalThis.process.execPath;
157
- }
158
- try {
159
- const system = getGjsGlobal().imports?.system;
160
- if (system?.programInvocationName) return system.programInvocationName;
161
- } catch {
162
- }
163
- return "/usr/bin/gjs";
156
+ if (typeof globalThis.process?.execPath === "string") {
157
+ return globalThis.process.execPath;
158
+ }
159
+ try {
160
+ const system = getGjsGlobal().imports?.system;
161
+ if (system?.programInvocationName) return system.programInvocationName;
162
+ } catch {}
163
+ return "/usr/bin/gjs";
164
164
  }
165
165
  function getPid() {
166
- if (typeof globalThis.process?.pid === "number") {
167
- return globalThis.process.pid;
168
- }
169
- try {
170
- const GLib = getGjsGlobal().imports?.gi?.GLib;
171
- if (GLib) {
172
- const [, contents] = GLib.file_get_contents("/proc/self/stat");
173
- if (contents) {
174
- const str = new TextDecoder().decode(contents);
175
- const pid2 = parseInt(str, 10);
176
- if (!isNaN(pid2)) return pid2;
177
- }
178
- }
179
- } catch {
180
- }
181
- return 0;
166
+ if (typeof globalThis.process?.pid === "number") {
167
+ return globalThis.process.pid;
168
+ }
169
+ try {
170
+ const GLib = getGjsGlobal().imports?.gi?.GLib;
171
+ if (GLib) {
172
+ const [, contents] = GLib.file_get_contents("/proc/self/stat");
173
+ if (contents) {
174
+ const str = new TextDecoder().decode(contents);
175
+ const pid = parseInt(str, 10);
176
+ if (!isNaN(pid)) return pid;
177
+ }
178
+ }
179
+ } catch {}
180
+ return 0;
182
181
  }
183
182
  const startTime = Date.now();
184
183
  function getGioNamespace() {
185
- const _gi = globalThis.imports?.gi;
186
- if (!_gi) return null;
187
- let gio = null;
188
- try {
189
- gio = _gi["GioUnix"];
190
- } catch {
191
- }
192
- if (!gio) {
193
- try {
194
- gio = _gi["Gio"];
195
- } catch {
196
- }
197
- }
198
- return gio;
199
- }
200
- class ProcessWriteStream extends EventEmitter {
201
- fd;
202
- // Required by Stream.pipe(): without this, pipe skips dest.write() entirely.
203
- writable = true;
204
- _outGio = null;
205
- constructor(fd) {
206
- super();
207
- this.fd = fd;
208
- const gio = getGioNamespace();
209
- if (gio) {
210
- const Cls = gio.UnixOutputStream ?? gio.OutputStream;
211
- if (Cls) {
212
- try {
213
- this._outGio = Cls.new(this.fd, false);
214
- } catch {
215
- }
216
- }
217
- }
218
- }
219
- write(data) {
220
- if (this._outGio) {
221
- try {
222
- const bytes = typeof data === "string" ? _encoder.encode(data) : data;
223
- this._outGio.write_all(bytes, null);
224
- return true;
225
- } catch {
226
- }
227
- }
228
- if (this.fd === 2) {
229
- console.error(data);
230
- } else {
231
- console.log(data);
232
- }
233
- return true;
234
- }
235
- get isTTY() {
236
- if (nativeTerminal) return nativeTerminal.Terminal.is_tty(this.fd);
237
- try {
238
- const GLib = getGjsGlobal().imports?.gi?.GLib;
239
- if (GLib) return !!GLib.log_writer_supports_color(this.fd);
240
- } catch {
241
- }
242
- return false;
243
- }
244
- get columns() {
245
- if (nativeTerminal) {
246
- const [ok, , cols] = nativeTerminal.Terminal.get_size(this.fd);
247
- if (ok && cols > 0) return cols;
248
- }
249
- try {
250
- const GLib = getGjsGlobal().imports?.gi?.GLib;
251
- if (GLib) {
252
- const c = parseInt(GLib.getenv("COLUMNS") ?? "0", 10);
253
- if (c > 0) return c;
254
- }
255
- } catch {
256
- }
257
- return 80;
258
- }
259
- // stdout/stderr must never be closed — the process owns the fds.
260
- // pipe() calls end() when its source emits 'end' (e.g. MuteStream); no-op here.
261
- end() {
262
- }
263
- destroy() {
264
- }
265
- get rows() {
266
- if (nativeTerminal) {
267
- const [ok, rows] = nativeTerminal.Terminal.get_size(this.fd);
268
- if (ok && rows > 0) return rows;
269
- }
270
- try {
271
- const GLib = getGjsGlobal().imports?.gi?.GLib;
272
- if (GLib) {
273
- const r = parseInt(GLib.getenv("LINES") ?? "0", 10);
274
- if (r > 0) return r;
275
- }
276
- } catch {
277
- }
278
- return 24;
279
- }
280
- }
281
- class ProcessReadStream extends EventEmitter {
282
- fd;
283
- isRaw = false;
284
- // Do NOT expose `readableFlowing` as an instance property: @inquirer/core uses
285
- // `'readableFlowing' in input` to defer startCycle() via setImmediate. In GJS,
286
- // setImmediate fires as a microtask — the property must stay absent so
287
- // @inquirer/core calls startCycle() synchronously on its own schedule.
288
- _gio = null;
289
- _stdinGio = null;
290
- _reading = false;
291
- _flowing = false;
292
- _sttyCleanupRegistered = false;
293
- _mainLoopHeld = false;
294
- // True while a read_bytes_async is in-flight. Prevents a second concurrent
295
- // read from starting when pause()+resume() fires between GLib iterations.
296
- _pendingRead = false;
297
- constructor(fd) {
298
- super();
299
- this.fd = fd;
300
- this._gio = getGioNamespace();
301
- }
302
- get isTTY() {
303
- if (nativeTerminal) return nativeTerminal.Terminal.is_tty(this.fd);
304
- return false;
305
- }
306
- setRawMode(mode) {
307
- if (nativeTerminal) {
308
- const ok = nativeTerminal.Terminal.set_raw_mode(this.fd, mode);
309
- if (ok) {
310
- this.isRaw = mode;
311
- return this;
312
- }
313
- }
314
- this._setRawModeViaStty(mode);
315
- this.isRaw = mode;
316
- return this;
317
- }
318
- _setRawModeViaStty(mode) {
319
- try {
320
- const _gi = globalThis.imports?.gi;
321
- const Gio = _gi?.Gio ?? _gi?.["Gio"];
322
- if (!Gio) return;
323
- const STDIN_INHERIT = Gio.SubprocessFlags?.STDIN_INHERIT ?? 2;
324
- const argv2 = mode ? ["stty", "-icanon", "-echo", "-icrnl", "min", "1", "time", "0"] : ["stty", "icanon", "echo", "icrnl"];
325
- const launcher = new Gio.SubprocessLauncher({ flags: STDIN_INHERIT });
326
- const proc = launcher.spawnv(argv2);
327
- proc.wait(null);
328
- if (mode && !this._sttyCleanupRegistered) {
329
- this._sttyCleanupRegistered = true;
330
- const proc_ = globalThis.process;
331
- if (proc_?.once && typeof proc_.once === "function") {
332
- proc_.once("exit", () => this._setRawModeViaStty(false));
333
- }
334
- }
335
- } catch {
336
- }
337
- }
338
- setEncoding(_enc) {
339
- return this;
340
- }
341
- resume() {
342
- this._flowing = true;
343
- if (this._gio && this.fd === 0 && !this._reading) {
344
- this._startReading();
345
- }
346
- return this;
347
- }
348
- pause() {
349
- this._flowing = false;
350
- this._reading = false;
351
- if (this._mainLoopHeld) {
352
- this._mainLoopHeld = false;
353
- const _gi = globalThis.imports?.gi;
354
- const GLib = _gi?.GLib ?? _gi?.["GLib"];
355
- if (GLib?.idle_add) {
356
- GLib.idle_add(300, () => {
357
- if (!this._mainLoopHeld) quitMainLoop();
358
- return false;
359
- });
360
- } else {
361
- quitMainLoop();
362
- }
363
- }
364
- return this;
365
- }
366
- read() {
367
- return null;
368
- }
369
- _startReading() {
370
- if (!this._gio || this._reading) return;
371
- if (this._pendingRead) {
372
- this._reading = true;
373
- if (!this._mainLoopHeld) {
374
- this._mainLoopHeld = true;
375
- ensureMainLoop();
376
- }
377
- return;
378
- }
379
- this._reading = true;
380
- if (!this._mainLoopHeld) {
381
- this._mainLoopHeld = true;
382
- ensureMainLoop();
383
- }
384
- if (!this._stdinGio) {
385
- const Cls = this._gio.UnixInputStream ?? this._gio.InputStream;
386
- if (!Cls) {
387
- this._reading = false;
388
- return;
389
- }
390
- try {
391
- this._stdinGio = Cls.new(this.fd, false);
392
- } catch {
393
- this._reading = false;
394
- return;
395
- }
396
- }
397
- const loop = () => {
398
- if (!this._reading) {
399
- this._pendingRead = false;
400
- return;
401
- }
402
- this._pendingRead = true;
403
- this._stdinGio.read_bytes_async(
404
- 4096,
405
- 0,
406
- null,
407
- (src, res) => {
408
- this._pendingRead = false;
409
- try {
410
- const bytes = src.read_bytes_finish(res);
411
- const data = bytes?.get_data?.() ?? null;
412
- if (data && data.byteLength > 0) {
413
- this.emit("data", Buffer.from(data));
414
- } else if (data !== null && data.byteLength === 0) {
415
- this._reading = false;
416
- this.emit("end");
417
- return;
418
- }
419
- } catch {
420
- this._reading = false;
421
- return;
422
- }
423
- if (this._reading) loop();
424
- }
425
- );
426
- };
427
- loop();
428
- }
184
+ const _gi = globalThis.imports?.gi;
185
+ if (!_gi) return null;
186
+ let gio = null;
187
+ try {
188
+ gio = _gi["GioUnix"];
189
+ } catch {}
190
+ if (!gio) {
191
+ try {
192
+ gio = _gi["Gio"];
193
+ } catch {}
194
+ }
195
+ return gio;
429
196
  }
197
+ var ProcessWriteStream = class extends EventEmitter {
198
+ fd;
199
+ writable = true;
200
+ _outGio = null;
201
+ constructor(fd) {
202
+ super();
203
+ this.fd = fd;
204
+ const gio = getGioNamespace();
205
+ if (gio) {
206
+ const Cls = gio.UnixOutputStream ?? gio.OutputStream;
207
+ if (Cls) {
208
+ try {
209
+ this._outGio = Cls.new(this.fd, false);
210
+ } catch {}
211
+ }
212
+ }
213
+ }
214
+ write(data) {
215
+ if (this._outGio) {
216
+ try {
217
+ const bytes = typeof data === "string" ? _encoder.encode(data) : data;
218
+ this._outGio.write_all(bytes, null);
219
+ return true;
220
+ } catch {}
221
+ }
222
+ if (this.fd === 2) {
223
+ console.error(data);
224
+ } else {
225
+ console.log(data);
226
+ }
227
+ return true;
228
+ }
229
+ get isTTY() {
230
+ if (nativeTerminal) return nativeTerminal.Terminal.is_tty(this.fd);
231
+ try {
232
+ const GLib = getGjsGlobal().imports?.gi?.GLib;
233
+ if (GLib) return !!GLib.log_writer_supports_color(this.fd);
234
+ } catch {}
235
+ return false;
236
+ }
237
+ get columns() {
238
+ if (nativeTerminal) {
239
+ const [ok, , cols] = nativeTerminal.Terminal.get_size(this.fd);
240
+ if (ok && cols > 0) return cols;
241
+ }
242
+ try {
243
+ const GLib = getGjsGlobal().imports?.gi?.GLib;
244
+ if (GLib) {
245
+ const c = parseInt(GLib.getenv("COLUMNS") ?? "0", 10);
246
+ if (c > 0) return c;
247
+ }
248
+ } catch {}
249
+ return 80;
250
+ }
251
+ end() {}
252
+ destroy() {}
253
+ get rows() {
254
+ if (nativeTerminal) {
255
+ const [ok, rows] = nativeTerminal.Terminal.get_size(this.fd);
256
+ if (ok && rows > 0) return rows;
257
+ }
258
+ try {
259
+ const GLib = getGjsGlobal().imports?.gi?.GLib;
260
+ if (GLib) {
261
+ const r = parseInt(GLib.getenv("LINES") ?? "0", 10);
262
+ if (r > 0) return r;
263
+ }
264
+ } catch {}
265
+ return 24;
266
+ }
267
+ };
268
+ var ProcessReadStream = class extends EventEmitter {
269
+ fd;
270
+ isRaw = false;
271
+ _gio = null;
272
+ _stdinGio = null;
273
+ _reading = false;
274
+ _flowing = false;
275
+ _sttyCleanupRegistered = false;
276
+ _mainLoopHeld = false;
277
+ _pendingRead = false;
278
+ constructor(fd) {
279
+ super();
280
+ this.fd = fd;
281
+ this._gio = getGioNamespace();
282
+ }
283
+ get isTTY() {
284
+ if (nativeTerminal) return nativeTerminal.Terminal.is_tty(this.fd);
285
+ return false;
286
+ }
287
+ setRawMode(mode) {
288
+ if (nativeTerminal) {
289
+ const ok = nativeTerminal.Terminal.set_raw_mode(this.fd, mode);
290
+ if (ok) {
291
+ this.isRaw = mode;
292
+ return this;
293
+ }
294
+ }
295
+ this._setRawModeViaStty(mode);
296
+ this.isRaw = mode;
297
+ return this;
298
+ }
299
+ _setRawModeViaStty(mode) {
300
+ try {
301
+ const _gi = globalThis.imports?.gi;
302
+ const Gio = _gi?.Gio ?? _gi?.["Gio"];
303
+ if (!Gio) return;
304
+ const STDIN_INHERIT = Gio.SubprocessFlags?.STDIN_INHERIT ?? 2;
305
+ const argv = mode ? [
306
+ "stty",
307
+ "-icanon",
308
+ "-echo",
309
+ "-icrnl",
310
+ "min",
311
+ "1",
312
+ "time",
313
+ "0"
314
+ ] : [
315
+ "stty",
316
+ "icanon",
317
+ "echo",
318
+ "icrnl"
319
+ ];
320
+ const launcher = new Gio.SubprocessLauncher({ flags: STDIN_INHERIT });
321
+ const proc = launcher.spawnv(argv);
322
+ proc.wait(null);
323
+ if (mode && !this._sttyCleanupRegistered) {
324
+ this._sttyCleanupRegistered = true;
325
+ const proc_ = globalThis.process;
326
+ if (proc_?.once && typeof proc_.once === "function") {
327
+ proc_.once("exit", () => this._setRawModeViaStty(false));
328
+ }
329
+ }
330
+ } catch {}
331
+ }
332
+ setEncoding(_enc) {
333
+ return this;
334
+ }
335
+ resume() {
336
+ this._flowing = true;
337
+ if (this._gio && this.fd === 0 && !this._reading) {
338
+ this._startReading();
339
+ }
340
+ return this;
341
+ }
342
+ pause() {
343
+ this._flowing = false;
344
+ this._reading = false;
345
+ if (this._mainLoopHeld) {
346
+ this._mainLoopHeld = false;
347
+ const _gi = globalThis.imports?.gi;
348
+ const GLib = _gi?.GLib ?? _gi?.["GLib"];
349
+ if (GLib?.idle_add) {
350
+ GLib.idle_add(300, () => {
351
+ if (!this._mainLoopHeld) quitMainLoop();
352
+ return false;
353
+ });
354
+ } else {
355
+ quitMainLoop();
356
+ }
357
+ }
358
+ return this;
359
+ }
360
+ read() {
361
+ return null;
362
+ }
363
+ _startReading() {
364
+ if (!this._gio || this._reading) return;
365
+ if (this._pendingRead) {
366
+ this._reading = true;
367
+ if (!this._mainLoopHeld) {
368
+ this._mainLoopHeld = true;
369
+ ensureMainLoop();
370
+ }
371
+ return;
372
+ }
373
+ this._reading = true;
374
+ if (!this._mainLoopHeld) {
375
+ this._mainLoopHeld = true;
376
+ ensureMainLoop();
377
+ }
378
+ if (!this._stdinGio) {
379
+ const Cls = this._gio.UnixInputStream ?? this._gio.InputStream;
380
+ if (!Cls) {
381
+ this._reading = false;
382
+ return;
383
+ }
384
+ try {
385
+ this._stdinGio = Cls.new(this.fd, false);
386
+ } catch {
387
+ this._reading = false;
388
+ return;
389
+ }
390
+ }
391
+ const loop = () => {
392
+ if (!this._reading) {
393
+ this._pendingRead = false;
394
+ return;
395
+ }
396
+ this._pendingRead = true;
397
+ this._stdinGio.read_bytes_async(4096, 0, null, (src, res) => {
398
+ this._pendingRead = false;
399
+ try {
400
+ const bytes = src.read_bytes_finish(res);
401
+ const data = bytes?.get_data?.() ?? null;
402
+ if (data && data.byteLength > 0) {
403
+ this.emit("data", Buffer.from(data));
404
+ } else if (data !== null && data.byteLength === 0) {
405
+ this._reading = false;
406
+ this.emit("end");
407
+ return;
408
+ }
409
+ } catch {
410
+ this._reading = false;
411
+ return;
412
+ }
413
+ if (this._reading) loop();
414
+ });
415
+ };
416
+ loop();
417
+ }
418
+ };
430
419
  function getMonotonicTime() {
431
- try {
432
- const GLib = getGjsGlobal().imports?.gi?.GLib;
433
- if (GLib?.get_monotonic_time) {
434
- return BigInt(GLib.get_monotonic_time()) * 1000n;
435
- }
436
- } catch {
437
- }
438
- if (typeof performance?.now === "function") {
439
- return BigInt(Math.round(performance.now() * 1e6));
440
- }
441
- return BigInt(Date.now()) * 1000000n;
420
+ try {
421
+ const GLib = getGjsGlobal().imports?.gi?.GLib;
422
+ if (GLib?.get_monotonic_time) {
423
+ return BigInt(GLib.get_monotonic_time()) * 1000n;
424
+ }
425
+ } catch {}
426
+ if (typeof performance?.now === "function") {
427
+ return BigInt(Math.round(performance.now() * 1e6));
428
+ }
429
+ return BigInt(Date.now()) * 1000000n;
442
430
  }
443
431
  const hrtimeBase = getMonotonicTime();
444
- class Process extends EventEmitter {
445
- platform;
446
- arch;
447
- env;
448
- argv;
449
- argv0;
450
- execPath;
451
- pid;
452
- ppid;
453
- version;
454
- versions;
455
- title;
456
- execArgv;
457
- config;
458
- exitCode;
459
- constructor() {
460
- super();
461
- this.platform = detectPlatform();
462
- this.arch = detectArch();
463
- this.env = getEnvProxy();
464
- this.argv = getArgv();
465
- this.argv0 = this.argv[0] || "gjs";
466
- this.execPath = getExecPath();
467
- this.execArgv = globalThis.process?.execArgv ?? [];
468
- this.config = globalThis.process?.config ?? { target_defaults: {}, variables: {} };
469
- this.pid = getPid();
470
- this.ppid = detectPpid();
471
- const versionInfo = detectVersionInfo();
472
- this.version = versionInfo.version;
473
- this.versions = versionInfo.versions;
474
- this.title = versionInfo.title;
475
- }
476
- cwd() {
477
- return getCwd();
478
- }
479
- chdir(directory) {
480
- try {
481
- const GLib = getGjsGlobal().imports?.gi?.GLib;
482
- if (GLib?.chdir) {
483
- if (!GLib.file_test(
484
- directory,
485
- 16
486
- /* G_FILE_TEST_EXISTS */
487
- )) {
488
- const err = new Error(`ENOENT: no such file or directory, chdir '${directory}'`);
489
- err.code = "ENOENT";
490
- err.syscall = "chdir";
491
- err.path = directory;
492
- throw err;
493
- }
494
- GLib.chdir(directory);
495
- return;
496
- }
497
- } catch (e) {
498
- if (e && typeof e === "object" && e.code === "ENOENT") throw e;
499
- }
500
- const nativeProcess = globalThis.process;
501
- if (nativeProcess && nativeProcess !== this && typeof nativeProcess.chdir === "function") {
502
- nativeProcess.chdir(directory);
503
- return;
504
- }
505
- throw new Error("process.chdir() is not supported in this environment");
506
- }
507
- kill(pid2, signal) {
508
- const nativeProcess = globalThis.process;
509
- if (nativeProcess && nativeProcess !== this && typeof nativeProcess.kill === "function") {
510
- return nativeProcess.kill(pid2, signal);
511
- }
512
- try {
513
- const GLib = getGjsGlobal().imports?.gi?.GLib;
514
- if (GLib) {
515
- const sig = typeof signal === "number" ? String(signal) : signal || "SIGTERM";
516
- const sigArg = sig.startsWith("SIG") ? `-${sig.slice(3)}` : `-${sig}`;
517
- GLib.spawn_command_line_sync(`kill ${sigArg} ${pid2}`);
518
- return true;
519
- }
520
- } catch {
521
- }
522
- throw new Error("process.kill() is not supported in this environment");
523
- }
524
- exit(code) {
525
- this.exitCode = code ?? this.exitCode ?? 0;
526
- this.emit("exit", this.exitCode);
527
- const gjsImports = getGjsGlobal().imports;
528
- const GLib = gjsImports?.gi?.GLib;
529
- const system = gjsImports?.system;
530
- const idleAdd = GLib?.idle_add;
531
- const sourceRemove = GLib?.SOURCE_REMOVE;
532
- const priorityDefault = GLib?.PRIORITY_DEFAULT;
533
- if (system?.exit && idleAdd && typeof priorityDefault === "number" && typeof sourceRemove === "boolean") {
534
- const exitCodeNow = this.exitCode;
535
- ensureMainLoop();
536
- idleAdd(priorityDefault, () => {
537
- quitMainLoop();
538
- system.exit(exitCodeNow);
539
- return sourceRemove;
540
- });
541
- return new Promise(() => {
542
- });
543
- }
544
- try {
545
- if (system?.exit) system.exit(this.exitCode);
546
- } catch {
547
- }
548
- const nativeProcess = globalThis.process;
549
- if (nativeProcess && nativeProcess !== this && typeof nativeProcess.exit === "function") {
550
- nativeProcess.exit(this.exitCode);
551
- }
552
- throw new Error(`process.exit(${this.exitCode})`);
553
- }
554
- nextTick(callback, ...args) {
555
- if (typeof queueMicrotask === "function") {
556
- queueMicrotask(() => callback(...args));
557
- } else {
558
- Promise.resolve().then(() => callback(...args));
559
- }
560
- }
561
- hrtime(time) {
562
- const now = getMonotonicTime() - hrtimeBase;
563
- const seconds = Number(now / 1000000000n);
564
- const nanoseconds = Number(now % 1000000000n);
565
- if (time) {
566
- let diffSec = seconds - time[0];
567
- let diffNano = nanoseconds - time[1];
568
- if (diffNano < 0) {
569
- diffSec--;
570
- diffNano += 1e9;
571
- }
572
- return [diffSec, diffNano];
573
- }
574
- return [seconds, nanoseconds];
575
- }
576
- uptime() {
577
- return (Date.now() - startTime) / 1e3;
578
- }
579
- memoryUsage() {
580
- try {
581
- const GLib = getGjsGlobal().imports?.gi?.GLib;
582
- if (GLib) {
583
- const [, contents] = GLib.file_get_contents("/proc/self/status");
584
- if (contents) {
585
- const str = new TextDecoder().decode(contents);
586
- const vmRSS = str.match(/VmRSS:\s+(\d+)/);
587
- const rss = vmRSS ? parseInt(vmRSS[1], 10) * 1024 : 0;
588
- return { rss, heapTotal: rss, heapUsed: rss, external: 0, arrayBuffers: 0 };
589
- }
590
- }
591
- } catch {
592
- }
593
- const nativeProcess = globalThis.process;
594
- if (nativeProcess && nativeProcess !== this && typeof nativeProcess.memoryUsage === "function") {
595
- return nativeProcess.memoryUsage();
596
- }
597
- return { rss: 0, heapTotal: 0, heapUsed: 0, external: 0, arrayBuffers: 0 };
598
- }
599
- cpuUsage(previousValue) {
600
- const nativeProcess = globalThis.process;
601
- if (nativeProcess && nativeProcess !== this && typeof nativeProcess.cpuUsage === "function") {
602
- return nativeProcess.cpuUsage(previousValue);
603
- }
604
- return { user: 0, system: 0 };
605
- }
606
- // Note: Cannot check globalThis.process.stdout here — on GJS globalThis.process
607
- // IS this instance, so that would cause infinite recursion.
608
- stdout = new ProcessWriteStream(1);
609
- stderr = new ProcessWriteStream(2);
610
- stdin = new ProcessReadStream(0);
611
- abort() {
612
- this.exit(1);
613
- }
614
- // no-op stubs for compatibility
615
- umask(mask) {
616
- return 18;
617
- }
618
- emitWarning(warning, name) {
619
- if (typeof warning === "string") {
620
- console.warn(`(${name || "Warning"}): ${warning}`);
621
- } else {
622
- console.warn(warning.message);
623
- }
624
- }
625
- }
432
+ var Process = class extends EventEmitter {
433
+ platform;
434
+ arch;
435
+ env;
436
+ argv;
437
+ argv0;
438
+ execPath;
439
+ pid;
440
+ ppid;
441
+ version;
442
+ versions;
443
+ title;
444
+ execArgv;
445
+ config;
446
+ exitCode;
447
+ constructor() {
448
+ super();
449
+ this.platform = detectPlatform();
450
+ this.arch = detectArch();
451
+ this.env = getEnvProxy();
452
+ this.argv = getArgv();
453
+ this.argv0 = this.argv[0] || "gjs";
454
+ this.execPath = getExecPath();
455
+ this.execArgv = globalThis.process?.execArgv ?? [];
456
+ this.config = globalThis.process?.config ?? {
457
+ target_defaults: {},
458
+ variables: {}
459
+ };
460
+ this.pid = getPid();
461
+ this.ppid = detectPpid();
462
+ const versionInfo = detectVersionInfo();
463
+ this.version = versionInfo.version;
464
+ this.versions = versionInfo.versions;
465
+ this.title = versionInfo.title;
466
+ }
467
+ cwd() {
468
+ return getCwd();
469
+ }
470
+ chdir(directory) {
471
+ try {
472
+ const GLib = getGjsGlobal().imports?.gi?.GLib;
473
+ if (GLib?.chdir) {
474
+ if (!GLib.file_test(directory, 16)) {
475
+ const err = new Error(`ENOENT: no such file or directory, chdir '${directory}'`);
476
+ err.code = "ENOENT";
477
+ err.syscall = "chdir";
478
+ err.path = directory;
479
+ throw err;
480
+ }
481
+ GLib.chdir(directory);
482
+ return;
483
+ }
484
+ } catch (e) {
485
+ if (e && typeof e === "object" && e.code === "ENOENT") throw e;
486
+ }
487
+ const nativeProcess = globalThis.process;
488
+ if (nativeProcess && nativeProcess !== this && typeof nativeProcess.chdir === "function") {
489
+ nativeProcess.chdir(directory);
490
+ return;
491
+ }
492
+ throw new Error("process.chdir() is not supported in this environment");
493
+ }
494
+ kill(pid, signal) {
495
+ const nativeProcess = globalThis.process;
496
+ if (nativeProcess && nativeProcess !== this && typeof nativeProcess.kill === "function") {
497
+ return nativeProcess.kill(pid, signal);
498
+ }
499
+ try {
500
+ const GLib = getGjsGlobal().imports?.gi?.GLib;
501
+ if (GLib) {
502
+ const sig = typeof signal === "number" ? String(signal) : signal || "SIGTERM";
503
+ const sigArg = sig.startsWith("SIG") ? `-${sig.slice(3)}` : `-${sig}`;
504
+ GLib.spawn_command_line_sync(`kill ${sigArg} ${pid}`);
505
+ return true;
506
+ }
507
+ } catch {}
508
+ throw new Error("process.kill() is not supported in this environment");
509
+ }
510
+ exit(code) {
511
+ this.exitCode = code ?? this.exitCode ?? 0;
512
+ this.emit("exit", this.exitCode);
513
+ const gjsImports = getGjsGlobal().imports;
514
+ const GLib = gjsImports?.gi?.GLib;
515
+ const system = gjsImports?.system;
516
+ const idleAdd = GLib?.idle_add;
517
+ const sourceRemove = GLib?.SOURCE_REMOVE;
518
+ const priorityDefault = GLib?.PRIORITY_DEFAULT;
519
+ if (system?.exit && idleAdd && typeof priorityDefault === "number" && typeof sourceRemove === "boolean") {
520
+ const exitCodeNow = this.exitCode;
521
+ ensureMainLoop();
522
+ idleAdd(priorityDefault, () => {
523
+ quitMainLoop();
524
+ system.exit(exitCodeNow);
525
+ return sourceRemove;
526
+ });
527
+ return new Promise(() => {});
528
+ }
529
+ try {
530
+ if (system?.exit) system.exit(this.exitCode);
531
+ } catch {}
532
+ const nativeProcess = globalThis.process;
533
+ if (nativeProcess && nativeProcess !== this && typeof nativeProcess.exit === "function") {
534
+ nativeProcess.exit(this.exitCode);
535
+ }
536
+ throw new Error(`process.exit(${this.exitCode})`);
537
+ }
538
+ nextTick(callback, ...args) {
539
+ if (typeof queueMicrotask === "function") {
540
+ queueMicrotask(() => callback(...args));
541
+ } else {
542
+ Promise.resolve().then(() => callback(...args));
543
+ }
544
+ }
545
+ hrtime(time) {
546
+ const now = getMonotonicTime() - hrtimeBase;
547
+ const seconds = Number(now / 1000000000n);
548
+ const nanoseconds = Number(now % 1000000000n);
549
+ if (time) {
550
+ let diffSec = seconds - time[0];
551
+ let diffNano = nanoseconds - time[1];
552
+ if (diffNano < 0) {
553
+ diffSec--;
554
+ diffNano += 1e9;
555
+ }
556
+ return [diffSec, diffNano];
557
+ }
558
+ return [seconds, nanoseconds];
559
+ }
560
+ uptime() {
561
+ return (Date.now() - startTime) / 1e3;
562
+ }
563
+ memoryUsage() {
564
+ try {
565
+ const GLib = getGjsGlobal().imports?.gi?.GLib;
566
+ if (GLib) {
567
+ const [, contents] = GLib.file_get_contents("/proc/self/status");
568
+ if (contents) {
569
+ const str = new TextDecoder().decode(contents);
570
+ const vmRSS = str.match(/VmRSS:\s+(\d+)/);
571
+ const rss = vmRSS ? parseInt(vmRSS[1], 10) * 1024 : 0;
572
+ return {
573
+ rss,
574
+ heapTotal: rss,
575
+ heapUsed: rss,
576
+ external: 0,
577
+ arrayBuffers: 0
578
+ };
579
+ }
580
+ }
581
+ } catch {}
582
+ const nativeProcess = globalThis.process;
583
+ if (nativeProcess && nativeProcess !== this && typeof nativeProcess.memoryUsage === "function") {
584
+ return nativeProcess.memoryUsage();
585
+ }
586
+ return {
587
+ rss: 0,
588
+ heapTotal: 0,
589
+ heapUsed: 0,
590
+ external: 0,
591
+ arrayBuffers: 0
592
+ };
593
+ }
594
+ cpuUsage(previousValue) {
595
+ const nativeProcess = globalThis.process;
596
+ if (nativeProcess && nativeProcess !== this && typeof nativeProcess.cpuUsage === "function") {
597
+ return nativeProcess.cpuUsage(previousValue);
598
+ }
599
+ return {
600
+ user: 0,
601
+ system: 0
602
+ };
603
+ }
604
+ stdout = new ProcessWriteStream(1);
605
+ stderr = new ProcessWriteStream(2);
606
+ stdin = new ProcessReadStream(0);
607
+ abort() {
608
+ this.exit(1);
609
+ }
610
+ umask(mask) {
611
+ return 18;
612
+ }
613
+ emitWarning(warning, name) {
614
+ if (typeof warning === "string") {
615
+ console.warn(`(${name || "Warning"}): ${warning}`);
616
+ } else {
617
+ console.warn(warning.message);
618
+ }
619
+ }
620
+ };
626
621
  Process.prototype.hrtime.bigint = function() {
627
- return getMonotonicTime() - hrtimeBase;
622
+ return getMonotonicTime() - hrtimeBase;
628
623
  };
629
624
  const process = new Process();
630
625
  if (nativeTerminal) {
631
- try {
632
- const watcher = new nativeTerminal.ResizeWatcher();
633
- watcher.connect("resized", (_obj, _rows, _cols) => {
634
- process.stdout.emit("resize");
635
- process.stderr.emit("resize");
636
- });
637
- watcher.start();
638
- } catch {
639
- }
626
+ try {
627
+ const watcher = new nativeTerminal.ResizeWatcher();
628
+ watcher.connect("resized", (_obj, _rows, _cols) => {
629
+ process.stdout.emit("resize");
630
+ process.stderr.emit("resize");
631
+ });
632
+ watcher.start();
633
+ } catch {}
640
634
  }
641
635
  const platform = process.platform;
642
636
  const arch = process.arch;
@@ -665,34 +659,6 @@ const config = process.config;
665
659
  const stdout = process.stdout;
666
660
  const stderr = process.stderr;
667
661
  const stdin = process.stdin;
668
- var index_default = process;
669
- export {
670
- abort,
671
- arch,
672
- argv,
673
- argv0,
674
- chdir,
675
- config,
676
- cpuUsage,
677
- cwd,
678
- index_default as default,
679
- emitWarning,
680
- env,
681
- execArgv,
682
- execPath,
683
- exit,
684
- hrtime,
685
- kill,
686
- memoryUsage,
687
- nextTick,
688
- pid,
689
- platform,
690
- ppid,
691
- stderr,
692
- stdin,
693
- stdout,
694
- umask,
695
- uptime,
696
- version,
697
- versions
698
- };
662
+
663
+ //#endregion
664
+ export { abort, arch, argv, argv0, chdir, config, cpuUsage, cwd, process as default, emitWarning, env, execArgv, execPath, exit, hrtime, kill, memoryUsage, nextTick, pid, platform, ppid, stderr, stdin, stdout, umask, uptime, version, versions };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gjsify/process",
3
- "version": "0.3.13",
3
+ "version": "0.3.14",
4
4
  "description": "Node.js process module for Gjs",
5
5
  "module": "lib/esm/index.js",
6
6
  "types": "lib/types/index.d.ts",
@@ -30,13 +30,13 @@
30
30
  "process"
31
31
  ],
32
32
  "dependencies": {
33
- "@gjsify/events": "^0.3.13",
34
- "@gjsify/terminal-native": "^0.3.13",
35
- "@gjsify/utils": "^0.3.13"
33
+ "@gjsify/events": "^0.3.14",
34
+ "@gjsify/terminal-native": "^0.3.14",
35
+ "@gjsify/utils": "^0.3.14"
36
36
  },
37
37
  "devDependencies": {
38
- "@gjsify/cli": "^0.3.13",
39
- "@gjsify/unit": "^0.3.13",
38
+ "@gjsify/cli": "^0.3.14",
39
+ "@gjsify/unit": "^0.3.14",
40
40
  "@types/node": "^25.6.0",
41
41
  "typescript": "^6.0.3"
42
42
  }