@zintrust/core 1.5.3 → 1.5.5

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 (47) hide show
  1. package/bin/z.js +102 -2
  2. package/bin/zin.js +192 -2
  3. package/bin/zintrust-main.d.ts.map +1 -1
  4. package/bin/zintrust-main.js +32 -6
  5. package/bin/zintrust.d.ts.map +1 -1
  6. package/bin/zintrust.js +102 -2
  7. package/bin/zt.js +99 -2
  8. package/package.json +1 -1
  9. package/src/boot/bootstrap.d.ts +1 -1
  10. package/src/boot/bootstrap.d.ts.map +1 -1
  11. package/src/boot/bootstrap.js +119 -49
  12. package/src/boot/registry/runtime.d.ts.map +1 -1
  13. package/src/boot/registry/runtime.js +37 -2
  14. package/src/boot/registry/worker.d.ts.map +1 -1
  15. package/src/boot/registry/worker.js +3 -2
  16. package/src/cli/commands/StartCommand.d.ts.map +1 -1
  17. package/src/cli/commands/StartCommand.js +1 -0
  18. package/src/cli/utils/spawn.d.ts +1 -0
  19. package/src/cli/utils/spawn.d.ts.map +1 -1
  20. package/src/cli/utils/spawn.js +311 -38
  21. package/src/config/index.d.ts +2 -1
  22. package/src/config/index.d.ts.map +1 -1
  23. package/src/config/index.js +3 -3
  24. package/src/config/queue.d.ts.map +1 -1
  25. package/src/config/queue.js +32 -3
  26. package/src/helper/ShutdownTrace.d.ts +9 -0
  27. package/src/helper/ShutdownTrace.d.ts.map +1 -0
  28. package/src/helper/ShutdownTrace.js +165 -0
  29. package/src/helper/index.d.ts +1 -0
  30. package/src/helper/index.d.ts.map +1 -1
  31. package/src/helper/index.js +1 -0
  32. package/src/http/RequestContext.d.ts.map +1 -1
  33. package/src/http/RequestContext.js +6 -3
  34. package/src/index.js +3 -3
  35. package/src/migrations/schema/Schema.d.ts.map +1 -1
  36. package/src/migrations/schema/Schema.js +4 -3
  37. package/src/runtime/PluginManager.d.ts.map +1 -1
  38. package/src/runtime/PluginManager.js +9 -3
  39. package/src/runtime/WorkerAdapterImports.d.ts +2 -2
  40. package/src/runtime/WorkerAdapterImports.js +1 -1
  41. package/src/runtime/plugins/trace-runtime.d.ts.map +1 -1
  42. package/src/runtime/plugins/trace-runtime.js +2 -1
  43. package/src/runtime/plugins/trace.d.ts +1 -0
  44. package/src/runtime/plugins/trace.d.ts.map +1 -1
  45. package/src/runtime/plugins/trace.js +7 -5
  46. package/src/tools/queue/QueueReliabilityOrchestrator.d.ts.map +1 -1
  47. package/src/tools/queue/QueueReliabilityOrchestrator.js +11 -0
package/bin/z.js CHANGED
@@ -3,5 +3,105 @@
3
3
  * ZinTrust CLI Shortcut - 'z'
4
4
  * Mirrors bin/zintrust.ts for convenience
5
5
  */
6
- import { run } from './zintrust-main.js';
7
- await run();
6
+ import { spawn } from 'node:child_process';
7
+ import { existsSync } from 'node:fs';
8
+ import { createRequire } from 'node:module';
9
+ import path from 'node:path';
10
+ import { fileURLToPath } from 'node:url';
11
+ const here = path.dirname(fileURLToPath(import.meta.url));
12
+ const require = createRequire(import.meta.url);
13
+ const tsTarget = path.join(here, 'zintrust-main.ts');
14
+ const jsTarget = path.join(here, 'zintrust-main.js');
15
+ const target = existsSync(tsTarget) ? tsTarget : jsTarget;
16
+ const tsxImportPath = require.resolve('tsx');
17
+ const nodeArgs = target.endsWith('.ts')
18
+ ? ['--import', tsxImportPath, target, ...process.argv.slice(2)]
19
+ : [target, ...process.argv.slice(2)];
20
+ const child = spawn(process.execPath, nodeArgs, {
21
+ stdio: ['inherit', 'pipe', 'pipe'],
22
+ env: process.env,
23
+ });
24
+ child.stdout?.on('data', (chunk) => {
25
+ process.stdout.write(chunk);
26
+ });
27
+ child.stderr?.on('data', (chunk) => {
28
+ process.stderr.write(chunk);
29
+ });
30
+ let childClosed = false;
31
+ let delayedSignalTimer;
32
+ const clearDelayedSignal = () => {
33
+ if (delayedSignalTimer === undefined)
34
+ return;
35
+ clearTimeout(delayedSignalTimer);
36
+ delayedSignalTimer = undefined;
37
+ };
38
+ const forwardSignal = (signal) => {
39
+ if (childClosed)
40
+ return;
41
+ try {
42
+ child.kill(signal);
43
+ }
44
+ catch {
45
+ // best-effort
46
+ }
47
+ };
48
+ const scheduleSignalForward = (signal) => {
49
+ if (childClosed || delayedSignalTimer !== undefined)
50
+ return;
51
+ delayedSignalTimer = globalThis.setTimeout(() => {
52
+ delayedSignalTimer = undefined;
53
+ forwardSignal(signal);
54
+ }, 1500);
55
+ delayedSignalTimer.unref?.();
56
+ };
57
+ const onSigint = () => {
58
+ if (process.stdin.isTTY === true) {
59
+ scheduleSignalForward('SIGINT');
60
+ return;
61
+ }
62
+ forwardSignal('SIGINT');
63
+ };
64
+ const onSigterm = () => {
65
+ if (process.stdin.isTTY === true) {
66
+ scheduleSignalForward('SIGTERM');
67
+ return;
68
+ }
69
+ forwardSignal('SIGTERM');
70
+ };
71
+ process.on('SIGINT', onSigint);
72
+ process.on('SIGTERM', onSigterm);
73
+ const result = await new Promise((resolve, reject) => {
74
+ let settled = false;
75
+ let childResult = {
76
+ exitCode: null,
77
+ signal: null,
78
+ };
79
+ const finalize = () => {
80
+ if (settled) {
81
+ return;
82
+ }
83
+ settled = true;
84
+ childClosed = true;
85
+ clearDelayedSignal();
86
+ process.off('SIGINT', onSigint);
87
+ process.off('SIGTERM', onSigterm);
88
+ child.off?.('error', reject);
89
+ child.off?.('exit', handleExit);
90
+ child.off?.('close', handleClose);
91
+ resolve(childResult);
92
+ };
93
+ const handleExit = (exitCode, signal) => {
94
+ childResult = { exitCode, signal };
95
+ };
96
+ const handleClose = (exitCode, signal) => {
97
+ childResult = {
98
+ exitCode: childResult.exitCode ?? exitCode,
99
+ signal: childResult.signal ?? signal,
100
+ };
101
+ finalize();
102
+ };
103
+ child.once('error', reject);
104
+ child.once('exit', handleExit);
105
+ child.once('close', handleClose);
106
+ });
107
+ process.exit(result.exitCode ?? (result.signal === 'SIGINT' || result.signal === 'SIGTERM' ? 0 : 1));
package/bin/zin.js CHANGED
@@ -3,5 +3,195 @@
3
3
  * ZinTrust CLI Shortcut - 'zin'
4
4
  * Mirrors bin/zintrust.ts for convenience
5
5
  */
6
- import { run } from './zintrust-main.js';
7
- await run();
6
+ import { spawn } from 'node:child_process';
7
+ import { existsSync } from 'node:fs';
8
+ import { createRequire } from 'node:module';
9
+ import path from 'node:path';
10
+ import { fileURLToPath } from 'node:url';
11
+ const CLI_SPAWN_TRACE_ENV_KEYS = ['CLI_SPAWN_TRACE', 'ZIN_SPAWN_TRACE'];
12
+ const isCliSpawnTraceEnabled = () => {
13
+ return CLI_SPAWN_TRACE_ENV_KEYS.some((key) => {
14
+ const raw = process.env[key];
15
+ if (typeof raw !== 'string')
16
+ return false;
17
+ const normalized = raw.trim().toLowerCase();
18
+ return (normalized === '1' || normalized === 'true' || normalized === 'yes' || normalized === 'on');
19
+ });
20
+ };
21
+ const writeCliSpawnTrace = (label, details = {}) => {
22
+ if (!isCliSpawnTraceEnabled())
23
+ return;
24
+ process.stderr.write(`${JSON.stringify({ trace: 'cli-wrapper', label, pid: process.pid, details })}\n`);
25
+ };
26
+ const here = path.dirname(fileURLToPath(import.meta.url));
27
+ const require = createRequire(import.meta.url);
28
+ const tsTarget = path.join(here, 'zintrust-main.ts');
29
+ const jsTarget = path.join(here, 'zintrust-main.js');
30
+ const target = existsSync(tsTarget) ? tsTarget : jsTarget;
31
+ const tsxImportPath = require.resolve('tsx');
32
+ const nodeArgs = target.endsWith('.ts')
33
+ ? ['--import', tsxImportPath, target, ...process.argv.slice(2)]
34
+ : [target, ...process.argv.slice(2)];
35
+ const child = spawn(process.execPath, nodeArgs, {
36
+ stdio: ['inherit', 'pipe', 'pipe'],
37
+ env: process.env,
38
+ });
39
+ writeCliSpawnTrace('wrapper.child.started', {
40
+ childPid: child.pid,
41
+ command: process.execPath,
42
+ args: nodeArgs,
43
+ });
44
+ child.stdout?.on('data', (chunk) => {
45
+ writeCliSpawnTrace('wrapper.child.stdout.data', {
46
+ childPid: child.pid,
47
+ bytes: typeof chunk === 'string' ? Buffer.byteLength(chunk) : chunk.length,
48
+ });
49
+ process.stdout.write(chunk);
50
+ });
51
+ child.stdout?.on('end', () => {
52
+ writeCliSpawnTrace('wrapper.child.stdout.end', {
53
+ childPid: child.pid,
54
+ });
55
+ });
56
+ child.stdout?.on('close', () => {
57
+ writeCliSpawnTrace('wrapper.child.stdout.close', {
58
+ childPid: child.pid,
59
+ });
60
+ });
61
+ child.stderr?.on('data', (chunk) => {
62
+ writeCliSpawnTrace('wrapper.child.stderr.data', {
63
+ childPid: child.pid,
64
+ bytes: typeof chunk === 'string' ? Buffer.byteLength(chunk) : chunk.length,
65
+ });
66
+ process.stderr.write(chunk);
67
+ });
68
+ child.stderr?.on('end', () => {
69
+ writeCliSpawnTrace('wrapper.child.stderr.end', {
70
+ childPid: child.pid,
71
+ });
72
+ });
73
+ child.stderr?.on('close', () => {
74
+ writeCliSpawnTrace('wrapper.child.stderr.close', {
75
+ childPid: child.pid,
76
+ });
77
+ });
78
+ let childClosed = false;
79
+ let delayedSignalTimer;
80
+ const clearDelayedSignal = () => {
81
+ if (delayedSignalTimer === undefined)
82
+ return;
83
+ clearTimeout(delayedSignalTimer);
84
+ delayedSignalTimer = undefined;
85
+ };
86
+ const forwardSignal = (signal) => {
87
+ if (childClosed)
88
+ return;
89
+ try {
90
+ writeCliSpawnTrace('wrapper.signal.forward.attempt', {
91
+ childPid: child.pid,
92
+ signal,
93
+ });
94
+ child.kill(signal);
95
+ writeCliSpawnTrace('wrapper.signal.forward.complete', {
96
+ childPid: child.pid,
97
+ signal,
98
+ });
99
+ }
100
+ catch {
101
+ // best-effort
102
+ }
103
+ };
104
+ const scheduleSignalForward = (signal) => {
105
+ if (childClosed || delayedSignalTimer !== undefined)
106
+ return;
107
+ delayedSignalTimer = globalThis.setTimeout(() => {
108
+ delayedSignalTimer = undefined;
109
+ writeCliSpawnTrace('wrapper.signal.delay.fire', {
110
+ childPid: child.pid,
111
+ signal,
112
+ });
113
+ forwardSignal(signal);
114
+ }, 1500);
115
+ writeCliSpawnTrace('wrapper.signal.delay.schedule', {
116
+ childPid: child.pid,
117
+ signal,
118
+ delayMs: 1500,
119
+ });
120
+ delayedSignalTimer.unref?.();
121
+ };
122
+ const onSigint = () => {
123
+ writeCliSpawnTrace('wrapper.signal.received', {
124
+ childPid: child.pid,
125
+ signal: 'SIGINT',
126
+ tty: process.stdin.isTTY === true,
127
+ });
128
+ if (process.stdin.isTTY === true) {
129
+ scheduleSignalForward('SIGINT');
130
+ return;
131
+ }
132
+ forwardSignal('SIGINT');
133
+ };
134
+ const onSigterm = () => {
135
+ writeCliSpawnTrace('wrapper.signal.received', {
136
+ childPid: child.pid,
137
+ signal: 'SIGTERM',
138
+ tty: process.stdin.isTTY === true,
139
+ });
140
+ if (process.stdin.isTTY === true) {
141
+ scheduleSignalForward('SIGTERM');
142
+ return;
143
+ }
144
+ forwardSignal('SIGTERM');
145
+ };
146
+ process.on('SIGINT', onSigint);
147
+ process.on('SIGTERM', onSigterm);
148
+ const result = await new Promise((resolve, reject) => {
149
+ let settled = false;
150
+ let childResult = {
151
+ exitCode: null,
152
+ signal: null,
153
+ };
154
+ const finalize = () => {
155
+ if (settled) {
156
+ return;
157
+ }
158
+ settled = true;
159
+ writeCliSpawnTrace('wrapper.child.finalize', {
160
+ childPid: child.pid,
161
+ exitCode: childResult.exitCode,
162
+ signal: childResult.signal,
163
+ });
164
+ childClosed = true;
165
+ clearDelayedSignal();
166
+ process.off('SIGINT', onSigint);
167
+ process.off('SIGTERM', onSigterm);
168
+ child.off?.('error', reject);
169
+ child.off?.('exit', handleExit);
170
+ child.off?.('close', handleClose);
171
+ resolve(childResult);
172
+ };
173
+ const handleExit = (exitCode, signal) => {
174
+ writeCliSpawnTrace('wrapper.child.exit', {
175
+ childPid: child.pid,
176
+ exitCode,
177
+ signal,
178
+ });
179
+ childResult = { exitCode, signal };
180
+ };
181
+ const handleClose = (exitCode, signal) => {
182
+ writeCliSpawnTrace('wrapper.child.close', {
183
+ childPid: child.pid,
184
+ exitCode,
185
+ signal,
186
+ });
187
+ childResult = {
188
+ exitCode: childResult.exitCode ?? exitCode,
189
+ signal: childResult.signal ?? signal,
190
+ };
191
+ finalize();
192
+ };
193
+ child.once('error', reject);
194
+ child.once('exit', handleExit);
195
+ child.once('close', handleClose);
196
+ });
197
+ process.exit(result.exitCode ?? (result.signal === 'SIGINT' || result.signal === 'SIGTERM' ? 0 : 1));
@@ -1 +1 @@
1
- {"version":3,"file":"zintrust-main.d.ts","sourceRoot":"","sources":["../../bin/zintrust-main.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAOH,KAAK,qBAAqB,GAAG;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;CACrB,CAAC;AA0WF,wBAAsB,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC,CAMzC;AAED,eAAO,MAAM,mBAAmB;;qCAzUQ,MAAM,KAAG,qBAAqB,GAAG,SAAS;mCA6C5C,MAAM,GAAG,IAAI,UAAU,MAAM,CAAC,OAAO,GAAG,IAAI,KAAG,MAAM;iCAnEzD,MAAM;8BAIP,MAAM,KAAG,MAAM;uCAsEtC,qBAAqB,WACpB,MAAM,EAAE,KAChB,OAAO,CAAC,KAAK,CAAC;oCAhEsB,MAAM,sBAAsB,MAAM,KAAG,OAAO;6CA2G7B,MAAM,EAAE,KAAG,OAAO,CAAC,OAAO,CAAC;yCAtE1E,MAAM,sBACS,MAAM,QACrB,MAAM,CAAC,UAAU,KACrB,qBAAqB,GAAG,SAAS;EAqTlC,CAAC;AAEH,OAAO,EAAE,CAAC"}
1
+ {"version":3,"file":"zintrust-main.d.ts","sourceRoot":"","sources":["../../bin/zintrust-main.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAOH,KAAK,qBAAqB,GAAG;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;CACrB,CAAC;AAiYF,wBAAsB,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC,CAMzC;AAED,eAAO,MAAM,mBAAmB;;qCAhWQ,MAAM,KAAG,qBAAqB,GAAG,SAAS;mCA6C5C,MAAM,GAAG,IAAI,UAAU,MAAM,CAAC,OAAO,GAAG,IAAI,KAAG,MAAM;iCAnEzD,MAAM;8BAIP,MAAM,KAAG,MAAM;uCAoGtC,qBAAqB,WACpB,MAAM,EAAE,KAChB,OAAO,CAAC,KAAK,CAAC;oCA9FsB,MAAM,sBAAsB,MAAM,KAAG,OAAO;6CAkI7B,MAAM,EAAE,KAAG,OAAO,CAAC,OAAO,CAAC;yCA7F1E,MAAM,sBACS,MAAM,QACrB,MAAM,CAAC,UAAU,KACrB,qBAAqB,GAAG,SAAS;EA4UlC,CAAC;AAaH,OAAO,EAAE,CAAC"}
@@ -80,6 +80,28 @@ const getHandoffExitCode = (exitCode, signal) => {
80
80
  return 0;
81
81
  return 1;
82
82
  };
83
+ const waitForChildTermination = async (child) => {
84
+ return await new Promise((resolve, reject) => {
85
+ let settled = false;
86
+ const finish = (exitCode, signal) => {
87
+ if (settled)
88
+ return;
89
+ settled = true;
90
+ child.off?.('exit', onExit);
91
+ child.off?.('close', onClose);
92
+ resolve({ exitCode, signal });
93
+ };
94
+ const onExit = (exitCode, signal) => {
95
+ finish(exitCode, signal);
96
+ };
97
+ const onClose = (exitCode, signal) => {
98
+ finish(exitCode, signal);
99
+ };
100
+ child.once('error', reject);
101
+ child.once('exit', onExit);
102
+ child.once('close', onClose);
103
+ });
104
+ };
83
105
  const handoffToProjectLocalCli = async (target, rawArgs) => {
84
106
  const child = spawn(process.execPath, [target.binPath, ...rawArgs], {
85
107
  stdio: 'inherit',
@@ -104,12 +126,7 @@ const handoffToProjectLocalCli = async (target, rawArgs) => {
104
126
  process.on('SIGINT', onSigint);
105
127
  process.on('SIGTERM', onSigterm);
106
128
  try {
107
- const result = await new Promise((resolve, reject) => {
108
- child.once('error', reject);
109
- child.once('close', (exitCode, signal) => {
110
- resolve({ exitCode, signal });
111
- });
112
- });
129
+ const result = await waitForChildTermination(child);
113
130
  process.exit(getHandoffExitCode(result.exitCode, result.signal));
114
131
  }
115
132
  finally {
@@ -317,3 +334,12 @@ export const CliLauncherInternal = Object.freeze({
317
334
  maybeHandoffToProjectLocalCli,
318
335
  resolveProjectLocalCliHandoff,
319
336
  });
337
+ const shouldRunAsMain = () => {
338
+ const entryArg = process.argv[1];
339
+ if (typeof entryArg !== 'string' || entryArg.trim() === '')
340
+ return false;
341
+ return getRealPath(entryArg) === getRealPath(fileURLToPath(import.meta.url));
342
+ };
343
+ if (shouldRunAsMain()) {
344
+ await run();
345
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"zintrust.d.ts","sourceRoot":"","sources":["../../bin/zintrust.ts"],"names":[],"mappings":";AAEA;;;;;;GAMG;AAKH,OAAO,EAAE,CAAC"}
1
+ {"version":3,"file":"zintrust.d.ts","sourceRoot":"","sources":["../../bin/zintrust.ts"],"names":[],"mappings":";AAEA;;;;;;GAMG;AA6HH,OAAO,EAAE,CAAC"}
package/bin/zintrust.js CHANGED
@@ -6,5 +6,105 @@
6
6
  * bin/zintrust-main.ts. Keeping the implementation hashbang-free allows other
7
7
  * shortcuts (zin/z/zt) to import it without parse issues.
8
8
  */
9
- import { run } from './zintrust-main.js';
10
- await run();
9
+ import { spawn } from 'node:child_process';
10
+ import { existsSync } from 'node:fs';
11
+ import { createRequire } from 'node:module';
12
+ import path from 'node:path';
13
+ import { fileURLToPath } from 'node:url';
14
+ const here = path.dirname(fileURLToPath(import.meta.url));
15
+ const require = createRequire(import.meta.url);
16
+ const tsTarget = path.join(here, 'zintrust-main.ts');
17
+ const jsTarget = path.join(here, 'zintrust-main.js');
18
+ const target = existsSync(tsTarget) ? tsTarget : jsTarget;
19
+ const tsxImportPath = require.resolve('tsx');
20
+ const nodeArgs = target.endsWith('.ts')
21
+ ? ['--import', tsxImportPath, target, ...process.argv.slice(2)]
22
+ : [target, ...process.argv.slice(2)];
23
+ const child = spawn(process.execPath, nodeArgs, {
24
+ stdio: ['inherit', 'pipe', 'pipe'],
25
+ env: process.env,
26
+ });
27
+ child.stdout?.on('data', (chunk) => {
28
+ process.stdout.write(chunk);
29
+ });
30
+ child.stderr?.on('data', (chunk) => {
31
+ process.stderr.write(chunk);
32
+ });
33
+ let childClosed = false;
34
+ let delayedSignalTimer;
35
+ const clearDelayedSignal = () => {
36
+ if (delayedSignalTimer === undefined)
37
+ return;
38
+ clearTimeout(delayedSignalTimer);
39
+ delayedSignalTimer = undefined;
40
+ };
41
+ const forwardSignal = (signal) => {
42
+ if (childClosed)
43
+ return;
44
+ try {
45
+ child.kill(signal);
46
+ }
47
+ catch {
48
+ // best-effort
49
+ }
50
+ };
51
+ const scheduleSignalForward = (signal) => {
52
+ if (childClosed || delayedSignalTimer !== undefined)
53
+ return;
54
+ delayedSignalTimer = globalThis.setTimeout(() => {
55
+ delayedSignalTimer = undefined;
56
+ forwardSignal(signal);
57
+ }, 1500);
58
+ delayedSignalTimer.unref?.();
59
+ };
60
+ const onSigint = () => {
61
+ if (process.stdin.isTTY === true) {
62
+ scheduleSignalForward('SIGINT');
63
+ return;
64
+ }
65
+ forwardSignal('SIGINT');
66
+ };
67
+ const onSigterm = () => {
68
+ if (process.stdin.isTTY === true) {
69
+ scheduleSignalForward('SIGTERM');
70
+ return;
71
+ }
72
+ forwardSignal('SIGTERM');
73
+ };
74
+ process.on('SIGINT', onSigint);
75
+ process.on('SIGTERM', onSigterm);
76
+ const result = await new Promise((resolve, reject) => {
77
+ let settled = false;
78
+ let childResult = {
79
+ exitCode: null,
80
+ signal: null,
81
+ };
82
+ const finalize = () => {
83
+ if (settled) {
84
+ return;
85
+ }
86
+ settled = true;
87
+ childClosed = true;
88
+ clearDelayedSignal();
89
+ process.off('SIGINT', onSigint);
90
+ process.off('SIGTERM', onSigterm);
91
+ child.off?.('error', reject);
92
+ child.off?.('exit', handleExit);
93
+ child.off?.('close', handleClose);
94
+ resolve(childResult);
95
+ };
96
+ const handleExit = (exitCode, signal) => {
97
+ childResult = { exitCode, signal };
98
+ };
99
+ const handleClose = (exitCode, signal) => {
100
+ childResult = {
101
+ exitCode: childResult.exitCode ?? exitCode,
102
+ signal: childResult.signal ?? signal,
103
+ };
104
+ finalize();
105
+ };
106
+ child.once('error', reject);
107
+ child.once('exit', handleExit);
108
+ child.once('close', handleClose);
109
+ });
110
+ process.exit(result.exitCode ?? (result.signal === 'SIGINT' || result.signal === 'SIGTERM' ? 0 : 1));
package/bin/zt.js CHANGED
@@ -3,5 +3,102 @@
3
3
  * ZinTrust CLI Shortcut - 'z'
4
4
  * Mirrors bin/zintrust.ts for convenience
5
5
  */
6
- import { run } from './zintrust-main.js';
7
- await run();
6
+ import { spawn } from 'node:child_process';
7
+ import { existsSync } from 'node:fs';
8
+ import path from 'node:path';
9
+ import { fileURLToPath } from 'node:url';
10
+ const here = path.dirname(fileURLToPath(import.meta.url));
11
+ const tsTarget = path.join(here, 'zintrust-main.ts');
12
+ const jsTarget = path.join(here, 'zintrust-main.js');
13
+ const target = existsSync(tsTarget) ? tsTarget : jsTarget;
14
+ const nodeArgs = target.endsWith('.ts')
15
+ ? ['--import', 'tsx', target, ...process.argv.slice(2)]
16
+ : [target, ...process.argv.slice(2)];
17
+ const child = spawn(process.execPath, nodeArgs, {
18
+ stdio: ['inherit', 'pipe', 'pipe'],
19
+ env: process.env,
20
+ });
21
+ child.stdout?.on('data', (chunk) => {
22
+ process.stdout.write(chunk);
23
+ });
24
+ child.stderr?.on('data', (chunk) => {
25
+ process.stderr.write(chunk);
26
+ });
27
+ let childClosed = false;
28
+ let delayedSignalTimer;
29
+ const clearDelayedSignal = () => {
30
+ if (delayedSignalTimer === undefined)
31
+ return;
32
+ clearTimeout(delayedSignalTimer);
33
+ delayedSignalTimer = undefined;
34
+ };
35
+ const forwardSignal = (signal) => {
36
+ if (childClosed)
37
+ return;
38
+ try {
39
+ child.kill(signal);
40
+ }
41
+ catch {
42
+ // best-effort
43
+ }
44
+ };
45
+ const scheduleSignalForward = (signal) => {
46
+ if (childClosed || delayedSignalTimer !== undefined)
47
+ return;
48
+ delayedSignalTimer = globalThis.setTimeout(() => {
49
+ delayedSignalTimer = undefined;
50
+ forwardSignal(signal);
51
+ }, 1500);
52
+ delayedSignalTimer.unref?.();
53
+ };
54
+ const onSigint = () => {
55
+ if (process.stdin.isTTY === true) {
56
+ scheduleSignalForward('SIGINT');
57
+ return;
58
+ }
59
+ forwardSignal('SIGINT');
60
+ };
61
+ const onSigterm = () => {
62
+ if (process.stdin.isTTY === true) {
63
+ scheduleSignalForward('SIGTERM');
64
+ return;
65
+ }
66
+ forwardSignal('SIGTERM');
67
+ };
68
+ process.on('SIGINT', onSigint);
69
+ process.on('SIGTERM', onSigterm);
70
+ const result = await new Promise((resolve, reject) => {
71
+ let settled = false;
72
+ let childResult = {
73
+ exitCode: null,
74
+ signal: null,
75
+ };
76
+ const finalize = () => {
77
+ if (settled) {
78
+ return;
79
+ }
80
+ settled = true;
81
+ childClosed = true;
82
+ clearDelayedSignal();
83
+ process.off('SIGINT', onSigint);
84
+ process.off('SIGTERM', onSigterm);
85
+ child.off?.('error', reject);
86
+ child.off?.('exit', handleExit);
87
+ child.off?.('close', handleClose);
88
+ resolve(childResult);
89
+ };
90
+ const handleExit = (exitCode, signal) => {
91
+ childResult = { exitCode, signal };
92
+ };
93
+ const handleClose = (exitCode, signal) => {
94
+ childResult = {
95
+ exitCode: childResult.exitCode ?? exitCode,
96
+ signal: childResult.signal ?? signal,
97
+ };
98
+ finalize();
99
+ };
100
+ child.once('error', reject);
101
+ child.once('exit', handleExit);
102
+ child.once('close', handleClose);
103
+ });
104
+ process.exit(result.exitCode ?? (result.signal === 'SIGINT' || result.signal === 'SIGTERM' ? 0 : 1));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zintrust/core",
3
- "version": "1.5.3",
3
+ "version": "1.5.5",
4
4
  "description": "Production-grade TypeScript backend framework for JavaScript",
5
5
  "homepage": "https://zintrust.com",
6
6
  "repository": {
@@ -3,5 +3,5 @@
3
3
  * Entry point for running the ZinTrust server
4
4
  * Sealed namespace for immutability
5
5
  */
6
- export {};
6
+ export declare const bootstrapReady: Promise<void>;
7
7
  //# sourceMappingURL=bootstrap.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"bootstrap.d.ts","sourceRoot":"","sources":["../../../src/boot/bootstrap.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}
1
+ {"version":3,"file":"bootstrap.d.ts","sourceRoot":"","sources":["../../../src/boot/bootstrap.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAgbH,eAAO,MAAM,cAAc,eAAmB,CAAC"}