feat: release 3.0.0
This commit is contained in:
@@ -1,8 +1,9 @@
|
||||
import { type IDBPDatabase, openDB } from "idb";
|
||||
|
||||
import { Collection } from "../../collection.ts";
|
||||
import type { IndexSpec } from "../../index/manager.ts";
|
||||
import type { DBLogger } from "../../logger.ts";
|
||||
import type { Index, Registrars } from "../../registrars.ts";
|
||||
import type { Registrars } from "../../registrars.ts";
|
||||
import { IndexedDBStorage } from "./storage.ts";
|
||||
|
||||
export class IndexedDB<TOptions extends IndexedDBOptions> {
|
||||
@@ -12,10 +13,22 @@ export class IndexedDB<TOptions extends IndexedDBOptions> {
|
||||
constructor(readonly options: TOptions) {
|
||||
this.#db = openDB(options.name, options.version ?? 1, {
|
||||
upgrade: (db: IDBPDatabase) => {
|
||||
for (const { name, indexes = [] } of options.registrars) {
|
||||
const store = db.createObjectStore(name);
|
||||
for (const [keyPath, options] of indexes) {
|
||||
store.createIndex(keyPath, keyPath, options);
|
||||
for (const { name, indexes } of options.registrars) {
|
||||
const store = db.createObjectStore(name, {
|
||||
keyPath: indexes.find((index: IndexSpec<any>) => index.kind === "primary")?.field,
|
||||
});
|
||||
for (const { field, kind } of indexes) {
|
||||
switch (kind) {
|
||||
case "primary":
|
||||
case "unique": {
|
||||
store.createIndex(field, field, { unique: true });
|
||||
break;
|
||||
}
|
||||
case "shared": {
|
||||
store.createIndex(field, field);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -48,7 +61,7 @@ export class IndexedDB<TOptions extends IndexedDBOptions> {
|
||||
name: TName;
|
||||
storage: IndexedDBStorage;
|
||||
schema: TSchema;
|
||||
indexes: Index[];
|
||||
indexes: IndexSpec<any>[];
|
||||
}> {
|
||||
const collection = this.#collections.get(name);
|
||||
if (collection === undefined) {
|
||||
@@ -73,8 +86,8 @@ export class IndexedDB<TOptions extends IndexedDBOptions> {
|
||||
}
|
||||
}
|
||||
|
||||
close() {
|
||||
this.#db.then((db) => db.close());
|
||||
async close() {
|
||||
await this.#db.then((db) => db.close());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,8 +3,8 @@ import { Query, update } from "mingo";
|
||||
import type { Criteria } from "mingo/types";
|
||||
import type { Modifier } from "mingo/updater";
|
||||
|
||||
import type { IndexSpec } from "../../index/manager.ts";
|
||||
import { type DBLogger, InsertLog, QueryLog, RemoveLog, UpdateLog } from "../../logger.ts";
|
||||
import type { Index } from "../../registrars.ts";
|
||||
import { addOptions, type QueryOptions, Storage, type UpdateResult } from "../../storage.ts";
|
||||
import type { AnyDocument } from "../../types.ts";
|
||||
import { IndexedDBCache } from "./cache.ts";
|
||||
@@ -21,7 +21,7 @@ export class IndexedDBStorage<TSchema extends AnyDocument = AnyDocument> extends
|
||||
|
||||
constructor(
|
||||
name: string,
|
||||
indexes: Index[],
|
||||
indexes: IndexSpec<TSchema>[],
|
||||
promise: Promise<IDBPDatabase>,
|
||||
readonly log: DBLogger = function log() {},
|
||||
) {
|
||||
@@ -29,21 +29,6 @@ export class IndexedDBStorage<TSchema extends AnyDocument = AnyDocument> extends
|
||||
this.#promise = promise;
|
||||
}
|
||||
|
||||
async resolve() {
|
||||
if (this.#db === undefined) {
|
||||
this.#db = await this.#promise;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
async has(id: string): Promise<boolean> {
|
||||
const document = await this.db.getFromIndex(this.name, "id", id);
|
||||
if (document !== undefined) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
get db() {
|
||||
if (this.#db === undefined) {
|
||||
throw new Error("Database not initialized");
|
||||
@@ -51,6 +36,13 @@ export class IndexedDBStorage<TSchema extends AnyDocument = AnyDocument> extends
|
||||
return this.#db;
|
||||
}
|
||||
|
||||
async resolve() {
|
||||
if (this.#db === undefined) {
|
||||
this.#db = await this.#promise;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------------
|
||||
| Insert
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { Collection } from "../../collection.ts";
|
||||
import type { Index, Registrars } from "../../registrars.ts";
|
||||
import type { IndexSpec } from "../../index/manager.ts";
|
||||
import type { Registrars } from "../../registrars.ts";
|
||||
import { MemoryStorage } from "./storage.ts";
|
||||
|
||||
export class MemoryDatabase<TOptions extends MemoryDatabaseOptions> {
|
||||
@@ -42,7 +43,7 @@ export class MemoryDatabase<TOptions extends MemoryDatabaseOptions> {
|
||||
name: TName;
|
||||
storage: MemoryStorage;
|
||||
schema: TSchema;
|
||||
indexes: Index[];
|
||||
indexes: IndexSpec<any>[];
|
||||
}> {
|
||||
const collection = this.#collections.get(name);
|
||||
if (collection === undefined) {
|
||||
|
||||
@@ -5,18 +5,18 @@ import type { Modifier } from "mingo/updater";
|
||||
import { IndexManager, type IndexSpec } from "../../index/manager.ts";
|
||||
import type { UpdateResult } from "../../storage.ts";
|
||||
import { addOptions, type QueryOptions, Storage } from "../../storage.ts";
|
||||
import type { AnyDocument } from "../../types.ts";
|
||||
import type { AnyDocument, StringKeyOf } from "../../types.ts";
|
||||
|
||||
export class MemoryStorage<TSchema extends AnyDocument = AnyDocument> extends Storage<TSchema> {
|
||||
readonly index: IndexManager<TSchema>;
|
||||
|
||||
constructor(name: string, indexes: IndexSpec[]) {
|
||||
constructor(name: string, indexes: IndexSpec<TSchema>[]) {
|
||||
super(name, indexes);
|
||||
this.index = new IndexManager(indexes);
|
||||
}
|
||||
|
||||
get documents() {
|
||||
return this.index.primary.tree;
|
||||
return this.index.primary.documents;
|
||||
}
|
||||
|
||||
async resolve() {
|
||||
@@ -30,14 +30,14 @@ export class MemoryStorage<TSchema extends AnyDocument = AnyDocument> extends St
|
||||
this.broadcast("insert", documents);
|
||||
}
|
||||
|
||||
async getByIndex(index: string, value: string): Promise<TSchema[]> {
|
||||
return this.index.get(index)?.get(value) ?? [];
|
||||
async getByIndex(field: StringKeyOf<TSchema>, value: string): Promise<TSchema[]> {
|
||||
return this.index.getByIndex(field, value);
|
||||
}
|
||||
|
||||
async find(condition: Criteria<TSchema> = {}, options?: QueryOptions): Promise<TSchema[]> {
|
||||
let cursor = new Query(condition).find<TSchema>(this.documents);
|
||||
const cursor = new Query(condition).find<TSchema>(this.documents);
|
||||
if (options !== undefined) {
|
||||
cursor = addOptions(cursor, options);
|
||||
return addOptions(cursor, options).all();
|
||||
}
|
||||
return cursor.all();
|
||||
}
|
||||
@@ -58,7 +58,7 @@ export class MemoryStorage<TSchema extends AnyDocument = AnyDocument> extends St
|
||||
if (modified.length > 0) {
|
||||
modifiedCount += 1;
|
||||
documents.push(document);
|
||||
this.documents.add(document);
|
||||
this.index.update(document);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,7 +72,7 @@ export class MemoryStorage<TSchema extends AnyDocument = AnyDocument> extends St
|
||||
async remove(condition: Criteria<TSchema>): Promise<number> {
|
||||
const documents = await this.find(condition);
|
||||
for (const document of documents) {
|
||||
this.documents.delete(document);
|
||||
this.index.remove(document);
|
||||
}
|
||||
this.broadcast("remove", documents);
|
||||
return documents.length;
|
||||
@@ -83,6 +83,6 @@ export class MemoryStorage<TSchema extends AnyDocument = AnyDocument> extends St
|
||||
}
|
||||
|
||||
async flush(): Promise<void> {
|
||||
this.documents.clear();
|
||||
this.index.flush();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
import { describe, it } from "@std/testing/bdd";
|
||||
import { expect } from "expect";
|
||||
|
||||
import { MemoryStorage } from "../storage.ts";
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------------
|
||||
| Unit Tests
|
||||
|--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
describe("Memory Storage", () => {
|
||||
it("should insert new records", async () => {
|
||||
const storage = new MemoryStorage("test", [["id", { primary: true }]]);
|
||||
|
||||
const documents = [
|
||||
{
|
||||
id: "abc",
|
||||
foo: "bar",
|
||||
},
|
||||
];
|
||||
|
||||
await storage.insert(documents);
|
||||
|
||||
console.log(storage);
|
||||
|
||||
expect(storage.documents).toContain(documents);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user