moost 0.6.36 → 0.6.38
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/dist/index.cjs +91 -6
- package/dist/index.d.ts +26 -3
- package/dist/index.mjs +91 -6
- package/package.json +3 -3
package/dist/index.cjs
CHANGED
|
@@ -48,7 +48,7 @@ let stamped = false;
|
|
|
48
48
|
if (stamped) return;
|
|
49
49
|
stamped = true;
|
|
50
50
|
stampModuleIdentity({
|
|
51
|
-
version: "0.6.
|
|
51
|
+
version: "0.6.38",
|
|
52
52
|
path: typeof __filename === "string" ? __filename : require("url").pathToFileURL(__filename).href
|
|
53
53
|
});
|
|
54
54
|
}
|
|
@@ -670,7 +670,7 @@ const disposeSymbol = typeof Symbol.dispose === "symbol" ? Symbol.dispose : void
|
|
|
670
670
|
/** Class name of an instance, read through the prototype (never touches own props). */ function classNameOf(instance) {
|
|
671
671
|
return Object.getPrototypeOf(instance)?.constructor?.name || "Object";
|
|
672
672
|
}
|
|
673
|
-
function errorMessage(error) {
|
|
673
|
+
/** @internal Message of a thrown value, whatever it is. */ function errorMessage(error) {
|
|
674
674
|
return error instanceof Error ? error.message : String(error);
|
|
675
675
|
}
|
|
676
676
|
/** `Class.method (message)` pairs for every failed hook. */ function formatDisposeErrors(errors) {
|
|
@@ -1952,6 +1952,67 @@ function lostCtorParamsMessage(input, ancestor, count) {
|
|
|
1952
1952
|
return [auditRouteDrop(input), auditLostCtorParams(input)].filter((f) => f !== void 0);
|
|
1953
1953
|
}
|
|
1954
1954
|
|
|
1955
|
+
//#endregion
|
|
1956
|
+
//#region packages/moost/src/dispose-signals.ts
|
|
1957
|
+
/**
|
|
1958
|
+
* Global key for the record above. Global (rather than module-scoped) for the
|
|
1959
|
+
* same reason the module-identity stamp is: two copies of moost, or the entry
|
|
1960
|
+
* re-executing under the `@moostjs/vite` dev server, must share one set of
|
|
1961
|
+
* process listeners instead of stacking one per app.
|
|
1962
|
+
*/ const DISPOSE_SIGNALS_KEY = Symbol.for("moost:dispose-on-signals");
|
|
1963
|
+
/**
|
|
1964
|
+
* Removes every registered listener and forgets the record. A no-op for a record
|
|
1965
|
+
* that is no longer the live one (a stale unregister fn, or a signal that already
|
|
1966
|
+
* dropped it).
|
|
1967
|
+
*/ function dropSignalsRecord(record) {
|
|
1968
|
+
const holder = globalThis;
|
|
1969
|
+
if (holder[DISPOSE_SIGNALS_KEY] !== record) return;
|
|
1970
|
+
for (const [signal, listener] of record.listeners) process.off(signal, listener);
|
|
1971
|
+
record.listeners.clear();
|
|
1972
|
+
delete holder[DISPOSE_SIGNALS_KEY];
|
|
1973
|
+
}
|
|
1974
|
+
/**
|
|
1975
|
+
* The one listener body per signal (NestJS `enableShutdownHooks` semantics):
|
|
1976
|
+
* unhook every listener first, dispose the newest app, then re-raise `signal`
|
|
1977
|
+
* so the process exits with Node's default status for it. Because the listeners
|
|
1978
|
+
* are already gone, a second signal while disposal runs gets Node's default
|
|
1979
|
+
* handling (exit `128 + n`) — an impatient Ctrl-C is never stuck.
|
|
1980
|
+
*/ async function onSignal(signal) {
|
|
1981
|
+
const record = globalThis[DISPOSE_SIGNALS_KEY];
|
|
1982
|
+
if (!record) return;
|
|
1983
|
+
const { app } = record;
|
|
1984
|
+
dropSignalsRecord(record);
|
|
1985
|
+
try {
|
|
1986
|
+
await app.dispose();
|
|
1987
|
+
} catch (error) {
|
|
1988
|
+
app.getLogger().warn(`[moost] dispose on ${signal} failed: ${errorMessage(error)}`);
|
|
1989
|
+
}
|
|
1990
|
+
process.kill(process.pid, signal);
|
|
1991
|
+
}
|
|
1992
|
+
/**
|
|
1993
|
+
* @internal Backs `Moost.disposeOnSignals()` — see that method's JSDoc for the
|
|
1994
|
+
* full contract. Registers at most one process listener per signal, ever, and
|
|
1995
|
+
* re-targets the existing ones at `app`.
|
|
1996
|
+
*/ function registerDisposeOnSignals(app, signals) {
|
|
1997
|
+
var _holder, _DISPOSE_SIGNALS_KEY;
|
|
1998
|
+
const record = (_holder = globalThis)[_DISPOSE_SIGNALS_KEY = DISPOSE_SIGNALS_KEY] ?? (_holder[_DISPOSE_SIGNALS_KEY] = {
|
|
1999
|
+
app,
|
|
2000
|
+
listeners: /* @__PURE__ */ new Map()
|
|
2001
|
+
});
|
|
2002
|
+
record.app = app;
|
|
2003
|
+
for (const signal of signals) {
|
|
2004
|
+
if (record.listeners.has(signal)) continue;
|
|
2005
|
+
const listener = () => {
|
|
2006
|
+
onSignal(signal);
|
|
2007
|
+
};
|
|
2008
|
+
record.listeners.set(signal, listener);
|
|
2009
|
+
process.on(signal, listener);
|
|
2010
|
+
}
|
|
2011
|
+
return () => {
|
|
2012
|
+
dropSignalsRecord(record);
|
|
2013
|
+
};
|
|
2014
|
+
}
|
|
2015
|
+
|
|
1955
2016
|
//#endregion
|
|
1956
2017
|
//#region packages/moost/src/moost.ts
|
|
1957
2018
|
function _define_property(obj, key, value) {
|
|
@@ -2136,14 +2197,38 @@ function _define_property(obj, key, value) {
|
|
|
2136
2197
|
* cleanup helpers when a clean container is what you need.
|
|
2137
2198
|
*
|
|
2138
2199
|
* ```ts
|
|
2139
|
-
*
|
|
2140
|
-
* process.once(signal, () => { void app.dispose().finally(() => process.exit(0)) })
|
|
2141
|
-
* }
|
|
2200
|
+
* app.disposeOnSignals() // SIGTERM + SIGINT → dispose() → re-raise
|
|
2142
2201
|
* ```
|
|
2143
2202
|
*/ dispose() {
|
|
2144
2203
|
if (!this.disposePromise) this.disposePromise = this.runDispose();
|
|
2145
2204
|
return this.disposePromise;
|
|
2146
2205
|
}
|
|
2206
|
+
/**
|
|
2207
|
+
* ### disposeOnSignals
|
|
2208
|
+
* Disposes this app when the process receives one of `signals` (default
|
|
2209
|
+
* `['SIGTERM', 'SIGINT']`), then re-raises the signal with no listener left,
|
|
2210
|
+
* so the process exits with Node's default status for it.
|
|
2211
|
+
*
|
|
2212
|
+
* Registers each process listener **once per process**: calling it again —
|
|
2213
|
+
* e.g. the entry re-executing under the `@moostjs/vite` dev server — re-targets
|
|
2214
|
+
* the existing listeners at the newest app instead of stacking one handler per
|
|
2215
|
+
* old app (which is what a plain `process.once(...)` in the entry does, until
|
|
2216
|
+
* Node warns about a listener leak). Signals are unioned across calls; an
|
|
2217
|
+
* already-registered one is never replaced or removed.
|
|
2218
|
+
*
|
|
2219
|
+
* A second signal while disposal runs gets Node's default handling, since the
|
|
2220
|
+
* listeners are already removed. A failing `dispose()` is logged as a warning
|
|
2221
|
+
* and the signal is re-raised all the same.
|
|
2222
|
+
*
|
|
2223
|
+
* Returns a function that unregisters the listeners (tests, embedded runners).
|
|
2224
|
+
*
|
|
2225
|
+
* ```ts
|
|
2226
|
+
* await app.init()
|
|
2227
|
+
* app.disposeOnSignals()
|
|
2228
|
+
* ```
|
|
2229
|
+
*/ disposeOnSignals(signals = ["SIGTERM", "SIGINT"]) {
|
|
2230
|
+
return registerDisposeOnSignals(this, signals);
|
|
2231
|
+
}
|
|
2147
2232
|
/** Adapters' `onDispose` in registration order; errors are collected, not fatal. */ async disposeAdapters() {
|
|
2148
2233
|
const errors = [];
|
|
2149
2234
|
for (const a of this.adapters) try {
|
|
@@ -2154,7 +2239,7 @@ function _define_property(obj, key, value) {
|
|
|
2154
2239
|
method: "onDispose",
|
|
2155
2240
|
error
|
|
2156
2241
|
});
|
|
2157
|
-
this.logger.warn(`[moost] adapter "${a.name}" onDispose failed: ${
|
|
2242
|
+
this.logger.warn(`[moost] adapter "${a.name}" onDispose failed: ${errorMessage(error)}`);
|
|
2158
2243
|
}
|
|
2159
2244
|
return errors;
|
|
2160
2245
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -762,12 +762,35 @@ declare class Moost extends Hookable {
|
|
|
762
762
|
* cleanup helpers when a clean container is what you need.
|
|
763
763
|
*
|
|
764
764
|
* ```ts
|
|
765
|
-
*
|
|
766
|
-
* process.once(signal, () => { void app.dispose().finally(() => process.exit(0)) })
|
|
767
|
-
* }
|
|
765
|
+
* app.disposeOnSignals() // SIGTERM + SIGINT → dispose() → re-raise
|
|
768
766
|
* ```
|
|
769
767
|
*/
|
|
770
768
|
dispose(): Promise<void>;
|
|
769
|
+
/**
|
|
770
|
+
* ### disposeOnSignals
|
|
771
|
+
* Disposes this app when the process receives one of `signals` (default
|
|
772
|
+
* `['SIGTERM', 'SIGINT']`), then re-raises the signal with no listener left,
|
|
773
|
+
* so the process exits with Node's default status for it.
|
|
774
|
+
*
|
|
775
|
+
* Registers each process listener **once per process**: calling it again —
|
|
776
|
+
* e.g. the entry re-executing under the `@moostjs/vite` dev server — re-targets
|
|
777
|
+
* the existing listeners at the newest app instead of stacking one handler per
|
|
778
|
+
* old app (which is what a plain `process.once(...)` in the entry does, until
|
|
779
|
+
* Node warns about a listener leak). Signals are unioned across calls; an
|
|
780
|
+
* already-registered one is never replaced or removed.
|
|
781
|
+
*
|
|
782
|
+
* A second signal while disposal runs gets Node's default handling, since the
|
|
783
|
+
* listeners are already removed. A failing `dispose()` is logged as a warning
|
|
784
|
+
* and the signal is re-raised all the same.
|
|
785
|
+
*
|
|
786
|
+
* Returns a function that unregisters the listeners (tests, embedded runners).
|
|
787
|
+
*
|
|
788
|
+
* ```ts
|
|
789
|
+
* await app.init()
|
|
790
|
+
* app.disposeOnSignals()
|
|
791
|
+
* ```
|
|
792
|
+
*/
|
|
793
|
+
disposeOnSignals(signals?: NodeJS.Signals[]): () => void;
|
|
771
794
|
/** Adapters' `onDispose` in registration order; errors are collected, not fatal. */
|
|
772
795
|
protected disposeAdapters(): Promise<TDisposeError[]>;
|
|
773
796
|
/** The one-shot body behind {@link Moost.dispose} (see its docs for the contract). */
|
package/dist/index.mjs
CHANGED
|
@@ -47,7 +47,7 @@ let stamped = false;
|
|
|
47
47
|
if (stamped) return;
|
|
48
48
|
stamped = true;
|
|
49
49
|
stampModuleIdentity({
|
|
50
|
-
version: "0.6.
|
|
50
|
+
version: "0.6.38",
|
|
51
51
|
path: typeof __filename === "string" ? __filename : import.meta.url
|
|
52
52
|
});
|
|
53
53
|
}
|
|
@@ -669,7 +669,7 @@ const disposeSymbol = typeof Symbol.dispose === "symbol" ? Symbol.dispose : void
|
|
|
669
669
|
/** Class name of an instance, read through the prototype (never touches own props). */ function classNameOf(instance) {
|
|
670
670
|
return Object.getPrototypeOf(instance)?.constructor?.name || "Object";
|
|
671
671
|
}
|
|
672
|
-
function errorMessage(error) {
|
|
672
|
+
/** @internal Message of a thrown value, whatever it is. */ function errorMessage(error) {
|
|
673
673
|
return error instanceof Error ? error.message : String(error);
|
|
674
674
|
}
|
|
675
675
|
/** `Class.method (message)` pairs for every failed hook. */ function formatDisposeErrors(errors) {
|
|
@@ -1951,6 +1951,67 @@ function lostCtorParamsMessage(input, ancestor, count) {
|
|
|
1951
1951
|
return [auditRouteDrop(input), auditLostCtorParams(input)].filter((f) => f !== void 0);
|
|
1952
1952
|
}
|
|
1953
1953
|
|
|
1954
|
+
//#endregion
|
|
1955
|
+
//#region packages/moost/src/dispose-signals.ts
|
|
1956
|
+
/**
|
|
1957
|
+
* Global key for the record above. Global (rather than module-scoped) for the
|
|
1958
|
+
* same reason the module-identity stamp is: two copies of moost, or the entry
|
|
1959
|
+
* re-executing under the `@moostjs/vite` dev server, must share one set of
|
|
1960
|
+
* process listeners instead of stacking one per app.
|
|
1961
|
+
*/ const DISPOSE_SIGNALS_KEY = Symbol.for("moost:dispose-on-signals");
|
|
1962
|
+
/**
|
|
1963
|
+
* Removes every registered listener and forgets the record. A no-op for a record
|
|
1964
|
+
* that is no longer the live one (a stale unregister fn, or a signal that already
|
|
1965
|
+
* dropped it).
|
|
1966
|
+
*/ function dropSignalsRecord(record) {
|
|
1967
|
+
const holder = globalThis;
|
|
1968
|
+
if (holder[DISPOSE_SIGNALS_KEY] !== record) return;
|
|
1969
|
+
for (const [signal, listener] of record.listeners) process.off(signal, listener);
|
|
1970
|
+
record.listeners.clear();
|
|
1971
|
+
delete holder[DISPOSE_SIGNALS_KEY];
|
|
1972
|
+
}
|
|
1973
|
+
/**
|
|
1974
|
+
* The one listener body per signal (NestJS `enableShutdownHooks` semantics):
|
|
1975
|
+
* unhook every listener first, dispose the newest app, then re-raise `signal`
|
|
1976
|
+
* so the process exits with Node's default status for it. Because the listeners
|
|
1977
|
+
* are already gone, a second signal while disposal runs gets Node's default
|
|
1978
|
+
* handling (exit `128 + n`) — an impatient Ctrl-C is never stuck.
|
|
1979
|
+
*/ async function onSignal(signal) {
|
|
1980
|
+
const record = globalThis[DISPOSE_SIGNALS_KEY];
|
|
1981
|
+
if (!record) return;
|
|
1982
|
+
const { app } = record;
|
|
1983
|
+
dropSignalsRecord(record);
|
|
1984
|
+
try {
|
|
1985
|
+
await app.dispose();
|
|
1986
|
+
} catch (error) {
|
|
1987
|
+
app.getLogger().warn(`[moost] dispose on ${signal} failed: ${errorMessage(error)}`);
|
|
1988
|
+
}
|
|
1989
|
+
process.kill(process.pid, signal);
|
|
1990
|
+
}
|
|
1991
|
+
/**
|
|
1992
|
+
* @internal Backs `Moost.disposeOnSignals()` — see that method's JSDoc for the
|
|
1993
|
+
* full contract. Registers at most one process listener per signal, ever, and
|
|
1994
|
+
* re-targets the existing ones at `app`.
|
|
1995
|
+
*/ function registerDisposeOnSignals(app, signals) {
|
|
1996
|
+
var _holder, _DISPOSE_SIGNALS_KEY;
|
|
1997
|
+
const record = (_holder = globalThis)[_DISPOSE_SIGNALS_KEY = DISPOSE_SIGNALS_KEY] ?? (_holder[_DISPOSE_SIGNALS_KEY] = {
|
|
1998
|
+
app,
|
|
1999
|
+
listeners: /* @__PURE__ */ new Map()
|
|
2000
|
+
});
|
|
2001
|
+
record.app = app;
|
|
2002
|
+
for (const signal of signals) {
|
|
2003
|
+
if (record.listeners.has(signal)) continue;
|
|
2004
|
+
const listener = () => {
|
|
2005
|
+
onSignal(signal);
|
|
2006
|
+
};
|
|
2007
|
+
record.listeners.set(signal, listener);
|
|
2008
|
+
process.on(signal, listener);
|
|
2009
|
+
}
|
|
2010
|
+
return () => {
|
|
2011
|
+
dropSignalsRecord(record);
|
|
2012
|
+
};
|
|
2013
|
+
}
|
|
2014
|
+
|
|
1954
2015
|
//#endregion
|
|
1955
2016
|
//#region packages/moost/src/moost.ts
|
|
1956
2017
|
function _define_property(obj, key, value) {
|
|
@@ -2135,14 +2196,38 @@ function _define_property(obj, key, value) {
|
|
|
2135
2196
|
* cleanup helpers when a clean container is what you need.
|
|
2136
2197
|
*
|
|
2137
2198
|
* ```ts
|
|
2138
|
-
*
|
|
2139
|
-
* process.once(signal, () => { void app.dispose().finally(() => process.exit(0)) })
|
|
2140
|
-
* }
|
|
2199
|
+
* app.disposeOnSignals() // SIGTERM + SIGINT → dispose() → re-raise
|
|
2141
2200
|
* ```
|
|
2142
2201
|
*/ dispose() {
|
|
2143
2202
|
if (!this.disposePromise) this.disposePromise = this.runDispose();
|
|
2144
2203
|
return this.disposePromise;
|
|
2145
2204
|
}
|
|
2205
|
+
/**
|
|
2206
|
+
* ### disposeOnSignals
|
|
2207
|
+
* Disposes this app when the process receives one of `signals` (default
|
|
2208
|
+
* `['SIGTERM', 'SIGINT']`), then re-raises the signal with no listener left,
|
|
2209
|
+
* so the process exits with Node's default status for it.
|
|
2210
|
+
*
|
|
2211
|
+
* Registers each process listener **once per process**: calling it again —
|
|
2212
|
+
* e.g. the entry re-executing under the `@moostjs/vite` dev server — re-targets
|
|
2213
|
+
* the existing listeners at the newest app instead of stacking one handler per
|
|
2214
|
+
* old app (which is what a plain `process.once(...)` in the entry does, until
|
|
2215
|
+
* Node warns about a listener leak). Signals are unioned across calls; an
|
|
2216
|
+
* already-registered one is never replaced or removed.
|
|
2217
|
+
*
|
|
2218
|
+
* A second signal while disposal runs gets Node's default handling, since the
|
|
2219
|
+
* listeners are already removed. A failing `dispose()` is logged as a warning
|
|
2220
|
+
* and the signal is re-raised all the same.
|
|
2221
|
+
*
|
|
2222
|
+
* Returns a function that unregisters the listeners (tests, embedded runners).
|
|
2223
|
+
*
|
|
2224
|
+
* ```ts
|
|
2225
|
+
* await app.init()
|
|
2226
|
+
* app.disposeOnSignals()
|
|
2227
|
+
* ```
|
|
2228
|
+
*/ disposeOnSignals(signals = ["SIGTERM", "SIGINT"]) {
|
|
2229
|
+
return registerDisposeOnSignals(this, signals);
|
|
2230
|
+
}
|
|
2146
2231
|
/** Adapters' `onDispose` in registration order; errors are collected, not fatal. */ async disposeAdapters() {
|
|
2147
2232
|
const errors = [];
|
|
2148
2233
|
for (const a of this.adapters) try {
|
|
@@ -2153,7 +2238,7 @@ function _define_property(obj, key, value) {
|
|
|
2153
2238
|
method: "onDispose",
|
|
2154
2239
|
error
|
|
2155
2240
|
});
|
|
2156
|
-
this.logger.warn(`[moost] adapter "${a.name}" onDispose failed: ${
|
|
2241
|
+
this.logger.warn(`[moost] adapter "${a.name}" onDispose failed: ${errorMessage(error)}`);
|
|
2157
2242
|
}
|
|
2158
2243
|
return errors;
|
|
2159
2244
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "moost",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.38",
|
|
4
4
|
"description": "moost",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"composables",
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
}
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"@prostojs/infact": "^0.5.
|
|
41
|
+
"@prostojs/infact": "^0.5.1",
|
|
42
42
|
"@prostojs/logger": "^0.4.3",
|
|
43
43
|
"@prostojs/mate": "^0.5.0",
|
|
44
44
|
"@wooksjs/event-core": "^0.7.23",
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
"@wooksjs/event-http": "^0.7.23",
|
|
50
50
|
"@wooksjs/http-body": "^0.7.23",
|
|
51
51
|
"vitest": "3.2.7",
|
|
52
|
-
"@moostjs/event-http": "^0.6.
|
|
52
|
+
"@moostjs/event-http": "^0.6.38"
|
|
53
53
|
},
|
|
54
54
|
"scripts": {
|
|
55
55
|
"pub": "pnpm publish --access public",
|