Skip to content

Commit

Permalink
refactor(deno/idb): do not replace self.indexedDB
Browse files Browse the repository at this point in the history
  • Loading branch information
hasundue committed Apr 22, 2024
1 parent 8cc8754 commit a1d89a8
Show file tree
Hide file tree
Showing 6 changed files with 108 additions and 147 deletions.
26 changes: 4 additions & 22 deletions app/common/nostr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { EventFilter, EventKind, NostrEvent } from "@lophus/nips";

export class Relay extends WithPool(_Relay) implements RelayLike {}

interface EventSource extends Pick<RelayLike, "config"> {
export interface EventSource extends Pick<RelayLike, "config"> {
list<K extends EventKind>(
filter: EventFilter<K>,
): AsyncIterable<NostrEvent<K>>;
Expand All @@ -13,7 +13,7 @@ interface EventSource extends Pick<RelayLike, "config"> {
): Promise<NostrEvent<K> | undefined>;
}

interface EventStore extends EventSource {
export interface EventStore extends EventSource {
put<K extends EventKind>(event: NostrEvent<K>): Promise<void>;
}

Expand All @@ -26,32 +26,14 @@ const knowns = new RelayGroup([
*/
export const nostr: EventSource = {
config: { name: "nostr" },
async get(filter) {
return await cache.get(filter) ?? _get(knowns, filter);
get(filter) {
return _get(knowns, filter);
},
list(filter) {
return knowns.subscribe(filter);
},
};

export const cache: EventStore = {
config: { name: "cache" },
async get<K extends EventKind>(filter: EventFilter<K>) {
const kv = await Deno.openKv();
if (filter.ids?.length) {
return Promise.any(
filter.ids.map((id) =>
new Promise<NostrEvent<K>>((resolve, reject) =>
kv.get<NostrEvent<K>>(["events", id]).then(({ value }) =>
value ? resolve(value) : reject()
)
)
),
).catch(() => undefined);
}
},
};

async function _get<K extends EventKind>(
source: RelayLike,
filter: EventFilter<K>,
Expand Down
32 changes: 4 additions & 28 deletions deno.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

110 changes: 53 additions & 57 deletions deno/idb/mod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,65 +24,61 @@ export interface IDBFactory {
deleteDatabase(name: string): IDBOpenDBRequest<undefined, null>;
}

const kv = await Deno.openKv();

export const indexedDB: IDBFactory = {
open(
name: string,
version: number = 1,
): IDBOpenDBRequest<IDBDatabase, null> {
return new _IDBOpenDBRequest(async function () {
// Check if the database already exists and is up to date.
const existed = await kv.get<IDBDatabaseInfo>($.database(name));
if (existed.value?.version && existed.value.version >= version) {
const stores = new Map<string, IDBObjectStoreParameters>();
const iter = kv.list<IDBObjectStoreParameters>({
prefix: $.store.prefix,
});
for await (const { key, value } of iter) {
const name = key.toReversed()[0] as string;
stores.set(name, value);
export function createIDBFactory(
kv: Deno.Kv,
): IDBFactory {
return {
open(
name: string,
version: number = 1,
): IDBOpenDBRequest<IDBDatabase, null> {
return new _IDBOpenDBRequest(async function () {
// Check if the database already exists and is up to date.
const existed = await kv.get<IDBDatabaseInfo>($.database(name));
if (existed.value?.version && existed.value.version >= version) {
const stores = new Map<string, IDBObjectStoreParameters>();
const iter = kv.list<IDBObjectStoreParameters>({
prefix: $.store.prefix,
});
for await (const { key, value } of iter) {
const name = key.toReversed()[0] as string;
stores.set(name, value);
}
return new _IDBDatabase(name, version, kv, stores);
}
return new _IDBDatabase(name, version, kv, stores);
}
// Create the new database.
await kv.set($.database(name), { name, version });
const db = new _IDBDatabase(name, version, kv, new Map());
const transaction = new _IDBTransaction(db, "versionchange");
this.transaction = transaction as IDBTransaction<"versionchange">;
db._transaction = transaction;
this.result = db;
this.dispatchEvent(
new _IDBVersionChangeEvent(existed.value?.version ?? 0, version),
);
await new Promise((resolve) => {
transaction.addEventListener("complete", resolve);
});
db._transaction = null;
return db;
}) as IDBOpenDBRequest<IDBDatabase, null>;
},

cmp(_a: unknown, _b: unknown): -1 | 0 | 1 {
console.warn("indexedDB.cmp is not implemented");
return 0;
},
// Create the new database.
await kv.set($.database(name), { name, version });
const db = new _IDBDatabase(name, version, kv, new Map());
const transaction = new _IDBTransaction(db, "versionchange");
this.transaction = transaction as IDBTransaction<"versionchange">;
db._transaction = transaction;
this.result = db;
this.dispatchEvent(
new _IDBVersionChangeEvent(existed.value?.version ?? 0, version),
);
await new Promise((resolve) => {
transaction.addEventListener("complete", resolve);
});
db._transaction = null;
return db;
}) as IDBOpenDBRequest<IDBDatabase, null>;
},

async databases(): Promise<IDBDatabaseInfo[]> {
const iter = kv.list<IDBDatabaseInfo>({ prefix: $.database.prefix });
return (await Array.fromAsync(iter)).map((it) => it.value);
},
cmp(_a: unknown, _b: unknown): -1 | 0 | 1 {
console.warn("indexedDB.cmp is not implemented");
return 0;
},

deleteDatabase(name: string): IDBOpenDBRequest<undefined, null> {
return new _IDBOpenDBRequest(async () => {
await kv.delete($.database(name));
return undefined;
}) as IDBOpenDBRequest<undefined, null>;
},
};
async databases(): Promise<IDBDatabaseInfo[]> {
const iter = kv.list<IDBDatabaseInfo>({ prefix: $.database.prefix });
return (await Array.fromAsync(iter)).map((it) => it.value);
},

if (self.indexedDB === undefined && self.Deno.Kv) {
console.warn("Using an experimental IndexedDB polyfill with Deno KV");
// @ts-ignore We type IDBFactory better
self.indexedDB = indexedDB;
deleteDatabase(name: string): IDBOpenDBRequest<undefined, null> {
return new _IDBOpenDBRequest(async () => {
await kv.delete($.database(name));
return undefined;
}) as IDBOpenDBRequest<undefined, null>;
},
};
}
Loading

0 comments on commit a1d89a8

Please sign in to comment.