feat: release 3.0.0

This commit is contained in:
2026-01-05 23:19:42 +01:00
parent ed15a0eb27
commit 4aaf12948c
25 changed files with 1799 additions and 1812 deletions

View File

@@ -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());
}
}

View File

@@ -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

View File

@@ -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) {

View File

@@ -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();
}
}

View File

@@ -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);
});
});