@travetto/runtime 8.0.0-alpha.19 → 8.0.0-alpha.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/env.ts CHANGED
@@ -3,11 +3,13 @@ import { castKey, castTo } from './types.ts';
3
3
  const IS_TRUE = /^(true|yes|on|1)$/i;
4
4
  const IS_FALSE = /^(false|no|off|0)$/i;
5
5
 
6
- export interface EnvData { }
6
+ export interface EnvData {}
7
7
 
8
8
  export class EnvProp<T> {
9
9
  readonly key: string;
10
- constructor(key: string) { this.key = key; }
10
+ constructor(key: string) {
11
+ this.key = key;
12
+ }
11
13
 
12
14
  /** Set value according to type */
13
15
  set(value: T | undefined | null): void {
@@ -26,14 +28,18 @@ export class EnvProp<T> {
26
28
  /** Export value */
27
29
  export(value?: T | undefined | null): Record<string, string> {
28
30
  let out: string;
29
- if (arguments.length === 0) { // If nothing passed in
31
+ // biome-ignore lint/complexity/noArguments: We want to use arguments here to detect if nothing was truly passed
32
+ if (arguments.length === 0) {
33
+ // If nothing passed in
30
34
  out = `${this.value}`;
31
35
  } else if (value === undefined || value === null) {
32
36
  out = '';
33
37
  } else if (Array.isArray(value)) {
34
38
  out = value.join(',');
35
39
  } else if (typeof value === 'object') {
36
- out = Object.entries(value).map(([key, keyValue]) => `${key}=${keyValue}`).join(',');
40
+ out = Object.entries(value)
41
+ .map(([key, keyValue]) => `${key}=${keyValue}`)
42
+ .join(',');
37
43
  } else {
38
44
  out = `${value}`;
39
45
  }
@@ -41,13 +47,19 @@ export class EnvProp<T> {
41
47
  }
42
48
 
43
49
  /** Read value as string */
44
- get value(): string | undefined { return process.env[this.key] || undefined; }
50
+ get value(): string | undefined {
51
+ return process.env[this.key] || undefined;
52
+ }
45
53
 
46
54
  /** Read value as list */
47
55
  get list(): string[] | undefined {
48
56
  const value = this.value;
49
- return (value === undefined || value === '') ?
50
- undefined : value.split(/[, ]+/g).map(item => item.trim()).filter(item => !!item);
57
+ return value === undefined || value === ''
58
+ ? undefined
59
+ : value
60
+ .split(/[, ]+/g)
61
+ .map(item => item.trim())
62
+ .filter(item => !!item);
51
63
  }
52
64
 
53
65
  /** Read value as object */
@@ -58,7 +70,7 @@ export class EnvProp<T> {
58
70
 
59
71
  /** Add values to list */
60
72
  add(...items: string[]): void {
61
- process.env[this.key] = [... new Set([...this.list ?? [], ...items])].join(',');
73
+ process.env[this.key] = [...new Set([...(this.list ?? []), ...items])].join(',');
62
74
  }
63
75
 
64
76
  /** Read value as int */
@@ -70,7 +82,7 @@ export class EnvProp<T> {
70
82
  /** Read value as boolean */
71
83
  get bool(): boolean | undefined {
72
84
  const value = this.value;
73
- return (value === undefined || value === '') ? undefined : IS_TRUE.test(value);
85
+ return value === undefined || value === '' ? undefined : IS_TRUE.test(value);
74
86
  }
75
87
 
76
88
  /** Determine if the underlying value is truthy */
@@ -91,24 +103,32 @@ export class EnvProp<T> {
91
103
  }
92
104
 
93
105
  type EnvDataCombinedType = {
94
- [K in keyof EnvData]: Pick<EnvProp<EnvData[K]>, 'key' | 'export' | 'value' | 'set' | 'clear' | 'isSet' |
95
- (EnvData[K] extends unknown[] ? 'list' | 'add' : never) |
96
- (Extract<EnvData[K], object> extends never ? never : 'object') |
97
- (Extract<EnvData[K], number> extends never ? never : 'int') |
98
- (Extract<EnvData[K], boolean> extends never ? never : 'bool' | 'isTrue' | 'isFalse')
99
- >
106
+ [K in keyof EnvData]: Pick<
107
+ EnvProp<EnvData[K]>,
108
+ | 'key'
109
+ | 'export'
110
+ | 'value'
111
+ | 'set'
112
+ | 'clear'
113
+ | 'isSet'
114
+ | (EnvData[K] extends unknown[] ? 'list' | 'add' : never)
115
+ | (Extract<EnvData[K], object> extends never ? never : 'object')
116
+ | (Extract<EnvData[K], number> extends never ? never : 'int')
117
+ | (Extract<EnvData[K], boolean> extends never ? never : 'bool' | 'isTrue' | 'isFalse')
118
+ >;
100
119
  };
101
120
 
102
121
  function delegate<T extends object>(base: T): EnvDataCombinedType & T {
103
122
  return new Proxy(castTo(base), {
104
123
  get(target, property): unknown {
105
- return typeof property !== 'string' ? undefined :
106
- (property in base ? base[castKey(property)] :
107
- target[castKey<typeof target>(property)] ??= castTo(new EnvProp(property))
108
- );
124
+ return typeof property !== 'string'
125
+ ? undefined
126
+ : property in base
127
+ ? base[castKey(property)]
128
+ : (target[castKey<typeof target>(property)] ??= castTo(new EnvProp(property)));
109
129
  }
110
130
  });
111
131
  }
112
132
 
113
133
  /** Basic utils for reading known environment variables */
114
- export const Env = delegate({});
134
+ export const Env = delegate({});
package/src/error.ts CHANGED
@@ -1,13 +1,6 @@
1
1
  import { castTo } from './types.ts';
2
2
 
3
- export type ErrorCategory =
4
- 'general' |
5
- 'notfound' |
6
- 'data' |
7
- 'permissions' |
8
- 'authentication' |
9
- 'timeout' |
10
- 'unavailable';
3
+ export type ErrorCategory = 'general' | 'notfound' | 'data' | 'permissions' | 'authentication' | 'timeout' | 'unavailable';
11
4
 
12
5
  export type RuntimeErrorOptions<T> = Omit<Partial<RuntimeError>, 'details'> & (T extends undefined ? { details?: T } : { details: T });
13
6
 
@@ -15,7 +8,6 @@ export type RuntimeErrorOptions<T> = Omit<Partial<RuntimeError>, 'details'> & (T
15
8
  * Framework error class, with the aim of being extensible
16
9
  */
17
10
  export class RuntimeError<T = Record<string, unknown> | undefined> extends Error {
18
-
19
11
  static defaultCategory: ErrorCategory = 'general';
20
12
 
21
13
  type: string;
@@ -28,14 +20,11 @@ export class RuntimeError<T = Record<string, unknown> | undefined> extends Error
28
20
  *
29
21
  * @param message The error message
30
22
  */
31
- constructor(
32
- ...[message, options]:
33
- T extends undefined ? ([string] | [string, RuntimeErrorOptions<T>]) : [string, RuntimeErrorOptions<T>]
34
- ) {
23
+ constructor(...[message, options]: T extends undefined ? [string] | [string, RuntimeErrorOptions<T>] : [string, RuntimeErrorOptions<T>]) {
35
24
  super(message, options?.cause ? { cause: options.cause } : undefined);
36
25
  this.type = options?.type ?? this.constructor.name;
37
- this.details = options?.details!;
26
+ this.details = options?.details ?? undefined!;
38
27
  this.category = options?.category ?? castTo<typeof RuntimeError>(this.constructor).defaultCategory ?? 'general';
39
28
  this.at = new Date(options?.at ?? Date.now());
40
29
  }
41
- }
30
+ }
package/src/exec.ts CHANGED
@@ -1,9 +1,9 @@
1
- import { type ChildProcess, spawn, type SpawnOptions } from 'node:child_process';
1
+ import { type ChildProcess, type SpawnOptions, spawn } from 'node:child_process';
2
2
 
3
- import { castTo } from './types.ts';
4
- import { RuntimeIndex } from './manifest-index.ts';
5
- import { BinaryUtil, type BinaryArray } from './binary.ts';
3
+ import { type BinaryArray, BinaryUtil } from './binary.ts';
6
4
  import { CodecUtil } from './codec.ts';
5
+ import { RuntimeIndex } from './manifest-index.ts';
6
+ import { castTo } from './types.ts';
7
7
 
8
8
  const ResultSymbol = Symbol();
9
9
 
@@ -39,7 +39,6 @@ type ExecutionBaseResult = Omit<ExecutionResult, 'stdout' | 'stderr'>;
39
39
  * Standard utilities for managing executions
40
40
  */
41
41
  export class ExecUtil {
42
-
43
42
  /** Read stream as string from a result */
44
43
  static toString(result: ExecutionResult<BinaryArray | string>, stream: 'stdout' | 'stderr' | 'any'): string {
45
44
  if (stream === 'any') {
@@ -61,11 +60,14 @@ export class ExecUtil {
61
60
  * @param options The options to use to enhance the process
62
61
  */
63
62
  static getResult(subProcess: ChildProcess): Promise<ExecutionResult<string>>;
64
- static getResult(subProcess: ChildProcess, options: { catch?: boolean, binary?: false }): Promise<ExecutionResult<string>>;
65
- static getResult(subProcess: ChildProcess, options: { catch?: boolean, binary: true }): Promise<ExecutionResult<BinaryArray>>;
66
- static getResult<T extends string | BinaryArray>(subProcess: ChildProcess, options: { catch?: boolean, binary?: boolean } = {}): Promise<ExecutionResult<T>> {
63
+ static getResult(subProcess: ChildProcess, options: { catch?: boolean; binary?: false }): Promise<ExecutionResult<string>>;
64
+ static getResult(subProcess: ChildProcess, options: { catch?: boolean; binary: true }): Promise<ExecutionResult<BinaryArray>>;
65
+ static getResult<T extends string | BinaryArray>(
66
+ subProcess: ChildProcess,
67
+ options: { catch?: boolean; binary?: boolean } = {}
68
+ ): Promise<ExecutionResult<T>> {
67
69
  const typed: ChildProcess & { [ResultSymbol]?: Promise<ExecutionResult> } = subProcess;
68
- const result = typed[ResultSymbol] ??= new Promise<ExecutionResult>(resolve => {
70
+ const result = (typed[ResultSymbol] ??= new Promise<ExecutionResult>(resolve => {
69
71
  const stdout: BinaryArray[] = [];
70
72
  const stderr: BinaryArray[] = [];
71
73
  let done = false;
@@ -77,7 +79,7 @@ export class ExecUtil {
77
79
 
78
80
  const buffers = {
79
81
  stdout: BinaryUtil.combineBinaryArrays(stdout),
80
- stderr: BinaryUtil.combineBinaryArrays(stderr),
82
+ stderr: BinaryUtil.combineBinaryArrays(stderr)
81
83
  };
82
84
 
83
85
  const final = {
@@ -86,37 +88,37 @@ export class ExecUtil {
86
88
  ...finalResult
87
89
  };
88
90
 
89
- resolve(!final.valid ?
90
- { ...final, message: `${final.message || final.stderr || final.stdout || 'failed'}` } :
91
- final
92
- );
91
+ resolve(!final.valid ? { ...final, message: `${final.message || final.stderr || final.stdout || 'failed'}` } : final);
93
92
  };
94
93
 
95
94
  subProcess.stdout?.on('data', data => stdout.push(CodecUtil.readChunk(data, subProcess.stdout?.readableEncoding)));
96
95
  subProcess.stderr?.on('data', data => stderr.push(CodecUtil.readChunk(data, subProcess.stderr?.readableEncoding)));
97
96
 
98
- subProcess.on('error', (error: Error) =>
99
- finish({ code: 1, message: error.message, valid: false }));
97
+ subProcess.on('error', (error: Error) => finish({ code: 1, message: error.message, valid: false }));
100
98
 
101
- subProcess.on('close', (code: number) =>
102
- finish({ code, valid: code === null || code === 0 }));
99
+ subProcess.on('close', (code: number) => finish({ code, valid: code === null || code === 0 }));
103
100
 
104
- if (subProcess.exitCode !== null) { // We are already done
101
+ if (subProcess.exitCode !== null) {
102
+ // We are already done
105
103
  finish({ code: subProcess.exitCode, valid: subProcess.exitCode === 0 });
106
104
  }
107
- });
108
-
109
- return castTo(options.catch ? result : result.then(executionResult => {
110
- if (executionResult.valid) {
111
- return executionResult;
112
- } else {
113
- throw new Error(executionResult.message);
114
- }
115
105
  }));
106
+
107
+ return castTo(
108
+ options.catch
109
+ ? result
110
+ : result.then(executionResult => {
111
+ if (executionResult.valid) {
112
+ return executionResult;
113
+ } else {
114
+ throw new Error(executionResult.message);
115
+ }
116
+ })
117
+ );
116
118
  }
117
119
 
118
120
  /** Spawn a package command */
119
121
  static spawnPackageCommand(cmd: string, args: string[], config: SpawnOptions = {}): ChildProcess {
120
122
  return spawn(process.argv0, [RuntimeIndex.resolvePackageCommand(cmd), ...args], config);
121
123
  }
122
- }
124
+ }
@@ -2,14 +2,13 @@ import { createReadStream } from 'node:fs';
2
2
  import fs from 'node:fs/promises';
3
3
  import path from 'node:path';
4
4
 
5
+ import { type BinaryArray, type BinaryStream, BinaryUtil } from './binary.ts';
5
6
  import { RuntimeError } from './error.ts';
6
- import { BinaryUtil, type BinaryArray, type BinaryStream } from './binary.ts';
7
7
 
8
8
  /**
9
9
  * File loader that will search for files across the provided search paths
10
10
  */
11
11
  export class FileLoader {
12
-
13
12
  #searchPaths: readonly string[];
14
13
 
15
14
  constructor(paths: string[]) {
@@ -72,4 +71,4 @@ export class FileLoader {
72
71
  const buffer = BinaryUtil.binaryArrayToBuffer(await this.readBinaryArray(relativePath));
73
72
  return new File([buffer], path.basename(relativePath));
74
73
  }
75
- }
74
+ }
package/src/function.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { ManifestModuleUtil } from '@travetto/manifest';
2
2
 
3
- export type FunctionMetadataTag = { hash: number, lines: [start: number, end: number, bodyStart?: number] };
3
+ export type FunctionMetadataTag = { hash: number; lines: [start: number, end: number, bodyStart?: number] };
4
4
  export type FunctionMetadata = FunctionMetadataTag & {
5
5
  id: string;
6
6
  import: string;
@@ -26,13 +26,16 @@ const pending = new Set<Function>([]);
26
26
  * @private
27
27
  */
28
28
  export function registerFunction(
29
- input: Function, [module, relativePath]: [string, string], tag: FunctionMetadataTag,
30
- methods?: Record<string, FunctionMetadataTag>, abstract?: boolean,
29
+ input: Function,
30
+ [module, relativePath]: [string, string],
31
+ tag: FunctionMetadataTag,
32
+ methods?: Record<string, FunctionMetadataTag>,
33
+ abstract?: boolean
31
34
  ): void {
32
35
  const modulePath = ManifestModuleUtil.withoutSourceExtension(relativePath);
33
36
 
34
37
  const metadata: FunctionMetadata = {
35
- id: (input.name ? `${module}:${modulePath}#${input.name}` : `${module}:${modulePath}`),
38
+ id: input.name ? `${module}:${modulePath}#${input.name}` : `${module}:${modulePath}`,
36
39
  import: `${module}/${relativePath}`,
37
40
  module,
38
41
  modulePath,
@@ -65,5 +68,10 @@ export function describeFunction(input?: Function): FunctionMetadata | undefined
65
68
 
66
69
  const foreignTypeRegistry = new Map<string, Function>();
67
70
  export function foreignType(id: string): Function {
68
- return foreignTypeRegistry.getOrInsert(id, class { static Ⲑid = id; });
69
- }
71
+ return foreignTypeRegistry.getOrInsert(
72
+ id,
73
+ class {
74
+ static Ⲑid = id;
75
+ }
76
+ );
77
+ }
package/src/json.ts CHANGED
@@ -3,27 +3,33 @@ import { AssertionError } from 'node:assert';
3
3
  import type { BinaryArray } from './binary.ts';
4
4
  import { CodecUtil } from './codec.ts';
5
5
  import { RuntimeError, type RuntimeErrorOptions } from './error.ts';
6
- import { castTo, type Any } from './types.ts';
6
+ import { type Any, castTo } from './types.ts';
7
7
 
8
8
  const VALID_JSON_ERROR_TYPES = ['runtime', 'plain', 'assert'] as const;
9
9
  const VALID_JSON_ERROR_TYPE_SET = new Set<unknown>(VALID_JSON_ERROR_TYPES);
10
10
 
11
11
  type JSONTransformer = (this: unknown, key: string, value: unknown) => unknown;
12
- type JSONOutputConfig = { indent?: number, replacer?: JSONTransformer };
12
+ type JSONOutputConfig = { indent?: number; replacer?: JSONTransformer };
13
13
  type JSONInputConfig = { reviver?: JSONTransformer };
14
14
  type JSONCloneConfig = JSONOutputConfig & JSONInputConfig;
15
- type JSONError = { $trv: (typeof VALID_JSON_ERROR_TYPES)[number], name?: string } & Partial<RuntimeErrorOptions<Record<string, unknown>>>;
15
+ type JSONError = { $trv: (typeof VALID_JSON_ERROR_TYPES)[number]; name?: string } & Partial<RuntimeErrorOptions<Record<string, unknown>>>;
16
16
 
17
17
  Object.defineProperty(BigInt.prototype, 'toJSON', {
18
- value() { return `${this}n`; },
18
+ value() {
19
+ return `${this}n`;
20
+ }
19
21
  });
20
22
 
21
23
  Object.defineProperty(Error.prototype, 'toJSON', {
22
- value() { return JSONUtil.errorToJSONError(this); },
24
+ value() {
25
+ return JSONUtil.errorToJSONError(this);
26
+ }
23
27
  });
24
28
 
25
29
  Object.defineProperty(RuntimeError.prototype, 'toJSON', {
26
- value() { return JSONUtil.errorToJSONError(this); },
30
+ value() {
31
+ return JSONUtil.errorToJSONError(this);
32
+ }
27
33
  });
28
34
 
29
35
  const ISO_8601_REGEX = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:\d{2})?$/;
@@ -31,7 +37,6 @@ const BIGINT_REGEX = /^-?\d+n$/;
31
37
 
32
38
  /** Utilities for JSON */
33
39
  export class JSONUtil {
34
-
35
40
  static includeStackTraces = false;
36
41
 
37
42
  static TRANSMIT_REVIVER: JSONTransformer = function (this: unknown, key: string, value: unknown): unknown {
@@ -47,7 +52,6 @@ export class JSONUtil {
47
52
  return value;
48
53
  };
49
54
 
50
-
51
55
  static isJSONError(value: unknown): value is JSONError {
52
56
  return typeof value === 'object' && value !== null && '$trv' in value && VALID_JSON_ERROR_TYPE_SET.has(value.$trv);
53
57
  }
@@ -57,12 +61,20 @@ export class JSONUtil {
57
61
  const { $trv, message, stack, name, ...rest } = error;
58
62
  let response: Error;
59
63
  switch ($trv) {
60
- case 'runtime': response = new RuntimeError(message!, castTo<Any>(rest)); break;
61
- case 'assert': response = new AssertionError({ message, ...rest }); break;
62
- case 'plain': response = new Error(message!); break;
64
+ case 'runtime':
65
+ response = new RuntimeError(message!, castTo<Any>(rest));
66
+ break;
67
+ case 'assert':
68
+ response = new AssertionError({ message, ...rest });
69
+ break;
70
+ case 'plain':
71
+ response = new Error(message!);
72
+ break;
63
73
  }
64
74
  response.stack = stack;
65
- if (name) { response.name = name; }
75
+ if (name) {
76
+ response.name = name;
77
+ }
66
78
  return response;
67
79
  }
68
80
 
@@ -73,21 +85,29 @@ export class JSONUtil {
73
85
  includeStack ??= JSONUtil.includeStackTraces;
74
86
  let $trv: JSONError['$trv'];
75
87
  switch (true) {
76
- case error instanceof RuntimeError: $trv = 'runtime'; break;
77
- case error instanceof AssertionError: $trv = 'assert'; break;
78
- default: $trv = 'plain'; break;
88
+ case error instanceof RuntimeError:
89
+ $trv = 'runtime';
90
+ break;
91
+ case error instanceof AssertionError:
92
+ $trv = 'assert';
93
+ break;
94
+ default:
95
+ $trv = 'plain';
96
+ break;
79
97
  }
80
98
  return {
81
99
  $trv,
82
100
  message: error.message,
83
101
  ...(error.cause ? { cause: `${error.cause}` } : undefined),
84
102
  ...(includeStack ? { stack: error.stack } : undefined),
85
- ...(error instanceof RuntimeError ? {
86
- category: error.category,
87
- type: error.type,
88
- at: error.at,
89
- ...(error.details ? { details: error.details } : undefined!),
90
- } : {})
103
+ ...(error instanceof RuntimeError
104
+ ? {
105
+ category: error.category,
106
+ type: error.type,
107
+ at: error.at,
108
+ ...(error.details ? { details: error.details } : undefined!)
109
+ }
110
+ : {})
91
111
  };
92
112
  }
93
113
 
@@ -147,4 +167,4 @@ export class JSONUtil {
147
167
  static cloneFromTransmit<T, R = T>(input: T): R {
148
168
  return JSONUtil.clone<T, R>(input, { reviver: JSONUtil.TRANSMIT_REVIVER });
149
169
  }
150
- }
170
+ }
@@ -1,4 +1,4 @@
1
1
  import { ManifestIndex } from '@travetto/manifest';
2
2
 
3
3
  /** Runtime manifest index */
4
- export const RuntimeIndex = new ManifestIndex();
4
+ export const RuntimeIndex = new ManifestIndex();
package/src/queue.ts CHANGED
@@ -2,7 +2,6 @@
2
2
  * An asynchronous queue
3
3
  */
4
4
  export class AsyncQueue<X> implements AsyncIterator<X>, AsyncIterable<X> {
5
-
6
5
  #buffer: X[] = [];
7
6
  #done = false;
8
7
  #ready = Promise.withResolvers<void>();
@@ -59,4 +58,4 @@ export class AsyncQueue<X> implements AsyncIterator<X>, AsyncIterable<X> {
59
58
  this.#ready.reject(error);
60
59
  return { value: undefined, done: this.#done };
61
60
  }
62
- }
61
+ }
package/src/resources.ts CHANGED
@@ -25,4 +25,4 @@ class $RuntimeResources extends FileLoader {
25
25
  }
26
26
 
27
27
  /** Runtime resources */
28
- export const RuntimeResources = new $RuntimeResources();
28
+ export const RuntimeResources = new $RuntimeResources();
package/src/shutdown.ts CHANGED
@@ -1,17 +1,21 @@
1
1
  import type { ChildProcess } from 'node:child_process';
2
2
 
3
3
  import { Env } from './env.ts';
4
- import { Util } from './util.ts';
5
4
  import { TimeUtil } from './time.ts';
5
+ import { Util } from './util.ts';
6
6
 
7
- const MAPPING = [['restart', 200], ['error', 1], ['quit', 0]] as const;
8
- export type ShutdownReason = typeof MAPPING[number][0];
7
+ const MAPPING = [
8
+ ['restart', 200],
9
+ ['error', 1],
10
+ ['quit', 0]
11
+ ] as const;
12
+ export type ShutdownReason = (typeof MAPPING)[number][0];
9
13
 
10
14
  const REASON_TO_CODE = new Map<ShutdownReason, number>(MAPPING);
11
15
  const CODE_TO_REASON = new Map<number, ShutdownReason>(MAPPING.map(([k, v]) => [v, k]));
12
16
 
13
17
  type Handler = (event: Event) => unknown;
14
- type ShutdownEvent = { reason?: ShutdownReason, mode?: 'exit' | 'interrupt' };
18
+ type ShutdownEvent = { reason?: ShutdownReason; mode?: 'exit' | 'interrupt' };
15
19
 
16
20
  const isShutdownEvent = (event: unknown): event is ShutdownEvent =>
17
21
  typeof event === 'object' && event !== null && 'type' in event && event.type === 'shutdown';
@@ -33,14 +37,20 @@ export class ShutdownManager {
33
37
  static #controller = new AbortController();
34
38
 
35
39
  static {
36
- this.#controller.signal.addEventListener = (_: 'abort', listener: Handler): void => { this.#registered.add(listener); };
37
- this.#controller.signal.removeEventListener = (_: 'abort', listener: Handler): void => { this.#registered.delete(listener); };
40
+ this.#controller.signal.addEventListener = (_: 'abort', listener: Handler): void => {
41
+ this.#registered.add(listener);
42
+ };
43
+ this.#controller.signal.removeEventListener = (_: 'abort', listener: Handler): void => {
44
+ this.#registered.delete(listener);
45
+ };
38
46
  try {
39
47
  process
40
- .on('message', event => { isShutdownEvent(event) && this.shutdown(event); })
48
+ .on('message', event => {
49
+ isShutdownEvent(event) && this.shutdown(event);
50
+ })
41
51
  .on('SIGINT', () => this.shutdown({ mode: 'interrupt' }))
42
52
  .on('SIGTERM', () => this.shutdown());
43
- } catch { }
53
+ } catch {}
44
54
  }
45
55
 
46
56
  static get signal(): AbortSignal {
@@ -60,7 +70,7 @@ export class ShutdownManager {
60
70
 
61
71
  /** Trigger a watch signal signal to a subprocess */
62
72
  static async shutdownChild(subprocess: ChildProcess, config?: ShutdownEvent): Promise<void> {
63
- subprocess?.send!({ type: 'shutdown', ...config });
73
+ subprocess?.send?.({ type: 'shutdown', ...config });
64
74
  }
65
75
 
66
76
  /**
@@ -87,10 +97,7 @@ export class ShutdownManager {
87
97
  this.#controller.abort('Shutdown started');
88
98
  console.debug('Shutdown started', context);
89
99
 
90
- const winner = await Promise.race([
91
- Util.nonBlockingTimeout(timeout).then(() => this),
92
- Promise.all([...this.#registered].map(wrapped))
93
- ]);
100
+ const winner = await Promise.race([Util.nonBlockingTimeout(timeout).then(() => this), Promise.all([...this.#registered].map(wrapped))]);
94
101
 
95
102
  if (winner !== this) {
96
103
  console.debug('Shutdown completed', context);
@@ -102,4 +109,4 @@ export class ShutdownManager {
102
109
  process.exit();
103
110
  }
104
111
  }
105
- }
112
+ }
package/src/time.ts CHANGED
@@ -2,16 +2,32 @@ import { RuntimeError } from './error.ts';
2
2
  import { castTo } from './types.ts';
3
3
 
4
4
  const TIME_UNIT_TO_TEMPORAL_UNIT = {
5
- y: 'years', year: 'years', years: 'years',
6
- M: 'months', month: 'months', months: 'months',
7
- w: 'weeks', week: 'weeks', weeks: 'weeks',
8
- d: 'days', day: 'days', days: 'days',
9
- h: 'hours', hour: 'hours', hours: 'hours',
10
- m: 'minutes', minute: 'minutes', minutes: 'minutes',
11
- s: 'seconds', second: 'seconds', seconds: 'seconds',
12
- ms: 'milliseconds', millisecond: 'milliseconds', milliseconds: 'milliseconds'
5
+ y: 'years',
6
+ year: 'years',
7
+ years: 'years',
8
+ M: 'months',
9
+ month: 'months',
10
+ months: 'months',
11
+ w: 'weeks',
12
+ week: 'weeks',
13
+ weeks: 'weeks',
14
+ d: 'days',
15
+ day: 'days',
16
+ days: 'days',
17
+ h: 'hours',
18
+ hour: 'hours',
19
+ hours: 'hours',
20
+ m: 'minutes',
21
+ minute: 'minutes',
22
+ minutes: 'minutes',
23
+ s: 'seconds',
24
+ second: 'seconds',
25
+ seconds: 'seconds',
26
+ ms: 'milliseconds',
27
+ millisecond: 'milliseconds',
28
+ milliseconds: 'milliseconds'
13
29
  } as const;
14
- type TemporalUnit = typeof TIME_UNIT_TO_TEMPORAL_UNIT[keyof typeof TIME_UNIT_TO_TEMPORAL_UNIT];
30
+ type TemporalUnit = (typeof TIME_UNIT_TO_TEMPORAL_UNIT)[keyof typeof TIME_UNIT_TO_TEMPORAL_UNIT];
15
31
 
16
32
  export type TimeSpan = `${number}${keyof typeof TIME_UNIT_TO_TEMPORAL_UNIT}`;
17
33
  export type TimeUnit = keyof typeof TIME_UNIT_TO_TEMPORAL_UNIT;
@@ -19,7 +35,6 @@ export type TimeUnit = keyof typeof TIME_UNIT_TO_TEMPORAL_UNIT;
19
35
  const TIME_PATTERN = /^(?<amount>-?[0-9]+)(?<unit>(?:year|month|week|day|hour|minute|second|millisecond)s?|y|M|w|d|h|m|s|ms)$/;
20
36
 
21
37
  export class TimeUtil {
22
-
23
38
  /**
24
39
  * Test to see if a string is valid for relative time
25
40
  */
@@ -50,20 +65,40 @@ export class TimeUtil {
50
65
  }
51
66
 
52
67
  switch (unit) {
53
- case 'years': { unit = 'hours'; value = value * 365 * 24; break; }
54
- case 'months': { value = value * 30 * 24; unit = 'hours'; break; }
55
- case 'weeks': { value = value * 7 * 24; unit = 'hours'; break; }
56
- case 'days': { value = value * 24; unit = 'hours'; break; }
68
+ case 'years': {
69
+ unit = 'hours';
70
+ value = value * 365 * 24;
71
+ break;
72
+ }
73
+ case 'months': {
74
+ value = value * 30 * 24;
75
+ unit = 'hours';
76
+ break;
77
+ }
78
+ case 'weeks': {
79
+ value = value * 7 * 24;
80
+ unit = 'hours';
81
+ break;
82
+ }
83
+ case 'days': {
84
+ value = value * 24;
85
+ unit = 'hours';
86
+ break;
87
+ }
57
88
  }
58
89
 
59
90
  const duration = Temporal.Duration.from({ [unit]: value });
60
91
  if (outputUnit) {
61
92
  const resolved = TIME_UNIT_TO_TEMPORAL_UNIT[outputUnit];
62
93
  switch (resolved) {
63
- case 'years': return Math.trunc(duration.total('hours') / (365 * 24));
64
- case 'months': return Math.trunc(duration.total('hours') / (30 * 24));
65
- case 'weeks': return Math.trunc(duration.total('hours') / (7 * 24));
66
- default: return Math.trunc(duration.total(resolved));
94
+ case 'years':
95
+ return Math.trunc(duration.total('hours') / (365 * 24));
96
+ case 'months':
97
+ return Math.trunc(duration.total('hours') / (30 * 24));
98
+ case 'weeks':
99
+ return Math.trunc(duration.total('hours') / (7 * 24));
100
+ default:
101
+ return Math.trunc(duration.total(resolved));
67
102
  }
68
103
  } else {
69
104
  return duration;
@@ -94,4 +129,4 @@ export class TimeUtil {
94
129
  return `${toFixed(seconds)}s`;
95
130
  }
96
131
  }
97
- }
132
+ }