Use setTimeout to delay unsubscribing in EventSubscriber

Browsers have no setImmediate. The web bundle only had one because jszip
depended on the setimmediate package, which installs it as a global.
Since jszip was replaced in #1011 every component using a subscription
threw on unmount, breaking page changes in the web interface.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
bbassieandClaude Opus 5.5 committed 2026-10-17 19:25:23 +00:00
1 parent 5e2ecdd143
commit c746b74bae
2 files changed
+21 -3

No files matched your search

+1 -1
View File
@@ -598,7 +598,7 @@ export class EventSubscriber<E, S = null> {
// By delaying the unsubscription here the subscription happens
// before the unsubscription, thus preventing the redundant
// updates from being sent out.
setImmediate(() => {
setTimeout(() => {
let index = this._callbacks.lastIndexOf(handler);
if (index === -1) {
return;
+20 -2
View File
@@ -1045,6 +1045,24 @@ describe("lib/subscriptions", function() {
));
});
it("should unsubscribe without setImmediate, which browsers lack", async function() {
const unsubscribe = eventSubscriber.subscribe(() => {});
await onceConnectorSend();
const setImmediate = globalThis.setImmediate;
delete globalThis.setImmediate;
try {
unsubscribe();
} finally {
globalThis.setImmediate = setImmediate;
}
await onceConnectorSend();
assertLastMessage(new lib.SubscriptionRequest(
RegisteredEvent.name, "replace", -1, lib.SubscriptionFilters.empty()
));
});
it("should notify all callbacks", async function() {
let called1, called2;
const event = new RegisteredEvent();
@@ -1066,7 +1084,7 @@ describe("lib/subscriptions", function() {
eventSubscriber.subscribe((e, s) => { called2 = [e, s]; });
unsubscribe();
await new Promise(r => setImmediate(r));
await new Promise(r => setTimeout(r));
await eventSubscriber._handleEvent(event);
assert.deepEqual(called1, undefined);
@@ -1407,7 +1425,7 @@ describe("lib/subscriptions", function() {
eventSubscriber.control.sendTo = function() {};
unsubscribe();
await new Promise(r => setImmediate(r));
await new Promise(r => setTimeout(r));
const [,, error2] = eventSubscriber.getSnapshot();
assert.deepEqual(error2, null);
});