Skip to content

Commit 95b87f9

Browse files
committed
Give up on previous approach; break jsdom sandbox
Fixing one test seemed to break another; I'm not certain that IndexedDB's expected timing and order of operations can be made to work within the microtask queue. Instead, break jsdom's sandbox so that we can use Node.js's setImmediate after all: - jsdom/jsdom#2729 - scala-js/scala-js-macrotask-executor#17
1 parent d6d97ce commit 95b87f9

File tree

4 files changed

+23
-35
lines changed

4 files changed

+23
-35
lines changed

src/FDBDatabase.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import {
1010
import fakeDOMStringList from "./lib/fakeDOMStringList";
1111
import FakeEventTarget from "./lib/FakeEventTarget";
1212
import ObjectStore from "./lib/ObjectStore";
13-
import { queueTask, queueTaskForNextEventLoop } from "./lib/scheduling";
13+
import { queueTask } from "./lib/scheduling";
1414
import { FakeDOMStringList, KeyPath, TransactionMode } from "./lib/types";
1515
import validateKeyPath from "./lib/validateKeyPath";
1616

@@ -55,7 +55,7 @@ const closeConnection = (connection: FDBDatabase) => {
5555
);
5656
} else {
5757
// Wait for the next event loop to give transactions time to finish.
58-
queueTaskForNextEventLoop(() => {
58+
queueTask(() => {
5959
closeConnection(connection);
6060
});
6161
}

src/FDBFactory.ts

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import Database from "./lib/Database";
66
import enforceRange from "./lib/enforceRange";
77
import { AbortError, VersionError } from "./lib/errors";
88
import FakeEvent from "./lib/FakeEvent";
9-
import { queueTask, queueTaskForNextEventLoop } from "./lib/scheduling";
9+
import { queueTask } from "./lib/scheduling";
1010

1111
const waitForOthersClosedDelete = (
1212
databases: Map<string, Database>,
@@ -19,7 +19,7 @@ const waitForOthersClosedDelete = (
1919
});
2020

2121
if (anyOpen) {
22-
queueTaskForNextEventLoop(() =>
22+
queueTask(() =>
2323
waitForOthersClosedDelete(databases, name, openDatabases, cb),
2424
);
2525
return;
@@ -229,9 +229,7 @@ class FDBFactory {
229229
const request = new FDBOpenDBRequest();
230230
request.source = null;
231231

232-
// In order for delete requests to be processed in the proper order (see
233-
// delete-request-queue.js), this must wait until the next event loop.
234-
queueTaskForNextEventLoop(() => {
232+
queueTask(() => {
235233
const db = this._databases.get(name);
236234
const oldVersion = db !== undefined ? db.version : 0;
237235

@@ -280,10 +278,7 @@ class FDBFactory {
280278
const request = new FDBOpenDBRequest();
281279
request.source = null;
282280

283-
// Since deletion has to happen at next event loop (see deleteDatabase),
284-
// opening has to happen at next event loop for
285-
// idbfactory-open-error-properties.js to pass.
286-
queueTaskForNextEventLoop(() => {
281+
queueTask(() => {
287282
openDatabase(
288283
this._databases,
289284
name,

src/FDBTransaction.ts

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import {
1010
import fakeDOMStringList from "./lib/fakeDOMStringList";
1111
import FakeEvent from "./lib/FakeEvent";
1212
import FakeEventTarget from "./lib/FakeEventTarget";
13-
import { queueTask, queueTaskForNextEventLoop } from "./lib/scheduling";
13+
import { queueTask } from "./lib/scheduling";
1414
import {
1515
EventCallback,
1616
FakeDOMStringList,
@@ -150,9 +150,6 @@ class FDBTransaction extends FakeEventTarget {
150150
operation,
151151
request,
152152
});
153-
if (!this._started) {
154-
queueTask(() => this._start());
155-
}
156153

157154
return request;
158155
}
@@ -238,18 +235,12 @@ class FDBTransaction extends FakeEventTarget {
238235

239236
// Check if transaction complete event needs to be fired
240237
if (this._state !== "finished") {
241-
this._started = false;
242-
// Either aborted or committed already
243-
queueTaskForNextEventLoop(() => {
244-
if (!this._started && this._state !== "finished") {
245-
this._state = "finished";
246-
247-
if (!this.error) {
248-
const event = new FakeEvent("complete");
249-
this.dispatchEvent(event);
250-
}
251-
}
252-
});
238+
this._state = "finished";
239+
240+
if (!this.error) {
241+
const event = new FakeEvent("complete");
242+
this.dispatchEvent(event);
243+
}
253244
}
254245
}
255246

src/lib/scheduling.ts

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
1-
export function queueTask(fn: () => void) {
2-
queueMicrotask(fn);
3-
}
4-
5-
export function queueTaskForNextEventLoop(fn: () => void) {
6-
if ("setImmediate" in globalThis) {
7-
(globalThis as any).setImmediate(fn);
1+
function getSetImmediateFromJsdom() {
2+
if (typeof navigator !== "undefined" && /jsdom/.test(navigator.userAgent)) {
3+
const outerRealmFunctionConstructor = Node.constructor as any;
4+
return new outerRealmFunctionConstructor("return setImmediate")();
85
} else {
9-
setTimeout(fn, 0);
6+
return undefined;
107
}
118
}
9+
10+
export const queueTask: (fn: () => void) => void =
11+
globalThis.setImmediate ||
12+
getSetImmediateFromJsdom() ||
13+
((fn: () => void) => setTimeout(fn, 0));

0 commit comments

Comments
 (0)