@rotorsoft/act 1.23.38 → 1.23.39
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/.tsbuildinfo +1 -1
- package/dist/@types/act.d.ts +24 -0
- package/dist/@types/act.d.ts.map +1 -1
- package/dist/@types/internal/drain-cycle.d.ts +0 -11
- package/dist/@types/internal/drain-cycle.d.ts.map +1 -1
- package/dist/@types/internal/settle.d.ts.map +1 -1
- package/dist/index.cjs +37 -18
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +37 -18
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -2616,13 +2616,6 @@ var EMPTY_DRAIN = {
|
|
|
2616
2616
|
acked: [],
|
|
2617
2617
|
blocked: []
|
|
2618
2618
|
};
|
|
2619
|
-
var contain = (logger, sink, fn) => {
|
|
2620
|
-
try {
|
|
2621
|
-
fn();
|
|
2622
|
-
} catch (error) {
|
|
2623
|
-
logger.error(error, `${sink} listener threw`);
|
|
2624
|
-
}
|
|
2625
|
-
};
|
|
2626
2619
|
var DrainController = class {
|
|
2627
2620
|
_armed = false;
|
|
2628
2621
|
_locked = false;
|
|
@@ -2731,7 +2724,7 @@ var DrainController = class {
|
|
|
2731
2724
|
leading,
|
|
2732
2725
|
eventLimit,
|
|
2733
2726
|
leaseMillis,
|
|
2734
|
-
(b) =>
|
|
2727
|
+
(b) => this._deps.on_blocked(b),
|
|
2735
2728
|
this._deps.lane
|
|
2736
2729
|
);
|
|
2737
2730
|
if (!cycle) {
|
|
@@ -2749,8 +2742,7 @@ var DrainController = class {
|
|
|
2749
2742
|
if (next !== void 0) this._defer.set(h.lease.stream, next);
|
|
2750
2743
|
}
|
|
2751
2744
|
if (this._defer.size > 0) this._defer.schedule();
|
|
2752
|
-
if (acked.length)
|
|
2753
|
-
contain(this._deps.logger, "acked", () => this._deps.on_acked(acked));
|
|
2745
|
+
if (acked.length) this._deps.on_acked(acked);
|
|
2754
2746
|
if (closeable.length) await this._deps.on_close(closeable);
|
|
2755
2747
|
this._deps.breaker.passed();
|
|
2756
2748
|
const has_errors = handled.some(({ error }) => error);
|
|
@@ -3029,8 +3021,7 @@ var SettleLoop = class {
|
|
|
3029
3021
|
const made_progress = subscribed > 0 || drain.acked.length > 0 || drain.blocked.length > 0 || last_id > after_before;
|
|
3030
3022
|
if (!made_progress) break;
|
|
3031
3023
|
}
|
|
3032
|
-
if (settled_drain)
|
|
3033
|
-
contain(log(), "settled", () => this._deps.on_settled(settled_drain));
|
|
3024
|
+
if (settled_drain) this._deps.on_settled(settled_drain);
|
|
3034
3025
|
})().catch((err) => {
|
|
3035
3026
|
this._deps.breaker.failed(Date.now(), err);
|
|
3036
3027
|
}).finally(() => {
|
|
@@ -3102,9 +3093,41 @@ var Act = class {
|
|
|
3102
3093
|
/**
|
|
3103
3094
|
* Emit a lifecycle event. The payload type is inferred from the event name
|
|
3104
3095
|
* via {@link ActLifecycleEvents}.
|
|
3096
|
+
*
|
|
3097
|
+
* **Every listener is contained individually.** Lifecycle listeners are
|
|
3098
|
+
* observers — `observability.md` promises that a throwing one is "contained,
|
|
3099
|
+
* not fatal" — and containment belongs here rather than at each call site,
|
|
3100
|
+
* for two reasons the previous arrangement got wrong (#1437):
|
|
3101
|
+
*
|
|
3102
|
+
* - Wrapping the *emit* rather than each *listener* still let the first
|
|
3103
|
+
* thrower abort the rest: `EventEmitter.emit` stops dispatching on the
|
|
3104
|
+
* first exception, so a second `app.on("acked", …)` never ran. The
|
|
3105
|
+
* documented "the remaining sinks still fire" was false whenever an event
|
|
3106
|
+
* had more than one listener. Same lesson as #1423, where guarding the
|
|
3107
|
+
* loop instead of each callback left every later SSE subscriber unserved.
|
|
3108
|
+
* - Only *some* call sites wrapped at all. The drain contained `acked` and
|
|
3109
|
+
* `blocked`; `committed`, `forgotten` and `close()`'s `closed` did not, so
|
|
3110
|
+
* a throwing listener rejected `do()`, `forget()` and `close()` **after**
|
|
3111
|
+
* their durable work had already landed. A caller retrying a "failed"
|
|
3112
|
+
* `do()` writes the event twice, since the framework has no dedup by
|
|
3113
|
+
* design.
|
|
3114
|
+
*
|
|
3115
|
+
* Containing here makes it a property of emitting, so a new lifecycle event
|
|
3116
|
+
* cannot reintroduce the gap by omission.
|
|
3117
|
+
*
|
|
3118
|
+
* Uses `rawListeners` so `once` wrappers still de-register themselves, and
|
|
3119
|
+
* returns "had listeners" to preserve the `EventEmitter.emit` contract.
|
|
3105
3120
|
*/
|
|
3106
3121
|
emit(event, args) {
|
|
3107
|
-
|
|
3122
|
+
const listeners = this._emitter.rawListeners(event);
|
|
3123
|
+
for (const listener of listeners) {
|
|
3124
|
+
try {
|
|
3125
|
+
listener(args);
|
|
3126
|
+
} catch (error) {
|
|
3127
|
+
this._logger.error(error, `${String(event)} listener threw`);
|
|
3128
|
+
}
|
|
3129
|
+
}
|
|
3130
|
+
return listeners.length > 0;
|
|
3108
3131
|
}
|
|
3109
3132
|
/**
|
|
3110
3133
|
* The single store-failure handler: log it, then emit the `error`
|
|
@@ -3346,11 +3369,7 @@ var Act = class {
|
|
|
3346
3369
|
with_stream_lock: (stream, work) => this._with_close_lock(stream, work)
|
|
3347
3370
|
});
|
|
3348
3371
|
this._forget_closed_subscriptions(result);
|
|
3349
|
-
|
|
3350
|
-
this.emit("closed", result);
|
|
3351
|
-
} catch (err) {
|
|
3352
|
-
this._logger.error(err, "closed listener threw");
|
|
3353
|
-
}
|
|
3372
|
+
this.emit("closed", result);
|
|
3354
3373
|
},
|
|
3355
3374
|
breaker: this._breaker,
|
|
3356
3375
|
// Re-scope the per-lane worker's auto-start ticks so their drain
|