Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add close/onclose event to fakeIndexedDatabase. fixed #50 #87

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 11 additions & 9 deletions src/FDBDatabase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
TransactionInactiveError,
} from "./lib/errors.js";
import FakeDOMStringList from "./lib/FakeDOMStringList.js";
import FakeEvent from "./lib/FakeEvent.js";
import FakeEventTarget from "./lib/FakeEventTarget.js";
import ObjectStore from "./lib/ObjectStore.js";
import { queueTask } from "./lib/scheduling.js";
Expand Down Expand Up @@ -43,11 +44,12 @@ const closeConnection = (connection: FDBDatabase) => {
const transactionsComplete = connection._rawDatabase.transactions.every(
(transaction) => {
return transaction._state === "finished";
},
}
);

if (transactionsComplete) {
connection._closed = true;
connection.dispatchEvent(new FakeEvent("close"));
connection._rawDatabase.connections =
connection._rawDatabase.connections.filter((otherConnection) => {
return connection !== otherConnection;
Expand Down Expand Up @@ -79,14 +81,14 @@ class FDBDatabase extends FakeEventTarget {
this.name = rawDatabase.name;
this.version = rawDatabase.version;
this.objectStoreNames = new FakeDOMStringList(
...Array.from(rawDatabase.rawObjectStores.keys()).sort(),
...Array.from(rawDatabase.rawObjectStores.keys()).sort()
);
}

// http://w3c.github.io/IndexedDB/#dom-idbdatabase-createobjectstore
public createObjectStore(
name: string,
options: { autoIncrement?: boolean; keyPath?: KeyPath } | null = {},
options: { autoIncrement?: boolean; keyPath?: KeyPath } | null = {}
) {
if (name === undefined) {
throw new TypeError();
Expand Down Expand Up @@ -130,14 +132,14 @@ class FDBDatabase extends FakeEventTarget {
this._rawDatabase,
name,
keyPath,
autoIncrement,
autoIncrement
);
this.objectStoreNames._push(name);
this.objectStoreNames._sort();
transaction._scope.add(name);
this._rawDatabase.rawObjectStores.set(name, rawObjectStore);
transaction.objectStoreNames = new FakeDOMStringList(
...this.objectStoreNames,
...this.objectStoreNames
);
return transaction.objectStore(name);
}
Expand All @@ -156,10 +158,10 @@ class FDBDatabase extends FakeEventTarget {
this.objectStoreNames = new FakeDOMStringList(
...Array.from(this.objectStoreNames).filter((objectStoreName) => {
return objectStoreName !== name;
}),
})
);
transaction.objectStoreNames = new FakeDOMStringList(
...this.objectStoreNames,
...this.objectStoreNames
);

transaction._rollbackLog.push(() => {
Expand Down Expand Up @@ -191,7 +193,7 @@ class FDBDatabase extends FakeEventTarget {
transaction.mode === "versionchange" &&
transaction.db === this
);
},
}
);
if (hasActiveVersionchange) {
throw new InvalidStateError();
Expand All @@ -210,7 +212,7 @@ class FDBDatabase extends FakeEventTarget {
for (const storeName of storeNames) {
if (!this.objectStoreNames.contains(storeName)) {
throw new NotFoundError(
"No objectStore named " + storeName + " in this database",
"No objectStore named " + storeName + " in this database"
);
}
}
Expand Down
7 changes: 5 additions & 2 deletions src/lib/FakeEventTarget.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import FakeEvent from "./FakeEvent.js";
import { EventCallback, EventType } from "./types.js";

type EventTypeProp =
| "onclose"
| "onabort"
| "onblocked"
| "oncomplete"
Expand Down Expand Up @@ -43,6 +44,7 @@ const invokeEventListeners = (event: FakeEvent, obj: FakeEventTarget) => {
}

const typeToProp: { [key in EventType]: EventTypeProp } = {
close: "onclose",
abort: "onabort",
blocked: "onblocked",
complete: "oncomplete",
Expand Down Expand Up @@ -74,6 +76,7 @@ abstract class FakeEventTarget {
public readonly listeners: Listener[] = [];

// These will be overridden in individual subclasses and made not readonly
public readonly onclose: EventCallback | null | undefined;
public readonly onabort: EventCallback | null | undefined;
public readonly onblocked: EventCallback | null | undefined;
public readonly oncomplete: EventCallback | null | undefined;
Expand All @@ -85,7 +88,7 @@ abstract class FakeEventTarget {
public addEventListener(
type: EventType,
callback: EventCallback,
capture = false,
capture = false
) {
this.listeners.push({
callback,
Expand All @@ -97,7 +100,7 @@ abstract class FakeEventTarget {
public removeEventListener(
type: EventType,
callback: EventCallback,
capture = false,
capture = false
) {
const i = this.listeners.findIndex((listener) => {
return (
Expand Down
1 change: 1 addition & 0 deletions src/lib/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ interface EventInCallback extends Event {
export type EventCallback = (event: EventInCallback) => void;

export type EventType =
| "close"
| "abort"
| "blocked"
| "complete"
Expand Down
9 changes: 9 additions & 0 deletions src/test/fakeIndexedDB/fakeIndexedDB.ts
Original file line number Diff line number Diff line change
Expand Up @@ -712,6 +712,15 @@ describe("fakeIndexedDB Tests", () => {
done();
});
});

it("should trigger onclose event", (done) => {
const request = fakeIndexedDB.open("test" + Math.random());
request.onsuccess = (e) => {
const db = e.target.result;
db.addEventListener("close", done);
db.close();
};
});
});

it("confirm openCursor works (issue #60)", (done) => {
Expand Down