From 349be3a36382cc03368b4e792aa8d36ddc191ce5 Mon Sep 17 00:00:00 2001 From: Oliver O'Loughlin <54100972+oliver-oloughlin@users.noreply.github.com> Date: Sat, 8 Feb 2025 17:52:38 +0100 Subject: [PATCH] Move internals to private props (#261) --- .github/workflows/test.yml | 2 - .github/workflows/test_minimum.yml | 39 +++ README.md | 2 +- deno.json | 4 +- deno.lock | 8 +- src/atomic_builder.ts | 51 ++-- src/atomic_pool.ts | 14 +- src/atomic_wrapper.ts | 14 +- src/collection.ts | 287 ++++++++---------- src/ext/encoding/brotli/brotli_compressor.ts | 4 +- src/ext/encoding/json/utils.ts | 6 +- src/ext/kv/async_lock.ts | 6 +- src/ext/kv/utils.ts | 6 +- src/ext/kv/watcher.ts | 2 +- src/kvdex.ts | 3 +- src/types.ts | 25 +- src/utils.ts | 16 +- tests/collection/add.test.ts | 1 + tests/collection/enqueue.test.ts | 5 +- tests/collection/listenQueue.test.ts | 5 +- tests/collection/properties.test.ts | 8 +- tests/db/atomic.test.ts | 5 +- tests/db/kvdex.test.ts | 4 +- tests/db/properties.test.ts | 4 +- tests/indexable_collection/enqueue.test.ts | 5 +- .../indexable_collection/listenQueue.test.ts | 5 +- tests/indexable_collection/properties.test.ts | 12 +- tests/serialized_collection/enqueue.test.ts | 5 +- .../serialized_collection/listenQueue.test.ts | 5 +- .../serialized_collection/properties.test.ts | 10 +- .../enqueue.test.ts | 5 +- .../listenQueue.test.ts | 5 +- .../properties.test.ts | 12 +- 33 files changed, 267 insertions(+), 318 deletions(-) create mode 100644 .github/workflows/test_minimum.yml diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 4f7d79d..b08f879 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -20,8 +20,6 @@ jobs: - name: Setup Deno uses: denoland/setup-deno@v2 - with: - deno-version: v2.x - name: Check Types run: deno task check diff --git a/.github/workflows/test_minimum.yml b/.github/workflows/test_minimum.yml new file mode 100644 index 0000000..f1cca65 --- /dev/null +++ b/.github/workflows/test_minimum.yml @@ -0,0 +1,39 @@ +name: Test + +on: + push: + branches: ["main"] + pull_request: + branches: ["main"] + +permissions: + contents: read + id-token: write # The OIDC ID token is used for authentication with JSR. + +jobs: + test: + runs-on: ubuntu-latest + + steps: + - name: Setup repo + uses: actions/checkout@v3 + + - name: Setup Deno + uses: denoland/setup-deno@v2 + with: + deno-version: v2.0.0 + + - name: Check Types + run: deno task check + + - name: Check formatting + run: deno fmt --check + + - name: Run linter + run: deno lint + + - name: "Test publish" + run: deno publish --dry-run + + - name: Run tests + run: deno task test diff --git a/README.md b/README.md index 118fbb8..317f198 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ native functionality as possible, like atomic operations, real-time data updates and queue listeners. Also works with other runtimes such as Node.js and Bun, and has compatibility options for the browser. -_Supported Deno verisons:_ **^1.43.0** +_Supported Deno verisons:_ **^2.0.0** ## Highlights diff --git a/deno.json b/deno.json index 2cf2989..48a809c 100644 --- a/deno.json +++ b/deno.json @@ -1,6 +1,6 @@ { "name": "@olli/kvdex", - "version": "3.1.2", + "version": "3.1.3", "exports": { ".": "./mod.ts", "./zod": "./src/ext/zod/mod.ts", @@ -34,7 +34,7 @@ "@deno/kv": "npm:@deno/kv@^0.8.4", "@std/assert": "jsr:@std/assert@1.0.7", "@std/bytes": "jsr:@std/bytes@^1.0.4", - "@std/cli": "jsr:@std/cli@^1.0.6", + "@std/cli": "jsr:@std/cli@1.0.12", "@std/collections": "jsr:@std/collections@^1.0.9", "@std/ulid": "jsr:@std/ulid@^1.0.0", "zod": "npm:zod@^3.23.8" diff --git a/deno.lock b/deno.lock index 0f777f8..906f413 100644 --- a/deno.lock +++ b/deno.lock @@ -8,7 +8,7 @@ "jsr:@std/bytes@^1.0.4": "1.0.4", "jsr:@std/cli@0.217": "0.217.0", "jsr:@std/cli@0.220": "0.220.1", - "jsr:@std/cli@^1.0.6": "1.0.6", + "jsr:@std/cli@1.0.12": "1.0.12", "jsr:@std/collections@^1.0.2": "1.0.5", "jsr:@std/collections@^1.0.9": "1.0.9", "jsr:@std/fmt@0.217": "0.217.0", @@ -58,8 +58,8 @@ "jsr:@std/assert@~0.220.1" ] }, - "@std/cli@1.0.6": { - "integrity": "d22d8b38c66c666d7ad1f2a66c5b122da1704f985d3c47f01129f05abb6c5d3d" + "@std/cli@1.0.12": { + "integrity": "e5cfb7814d189da174ecd7a34fbbd63f3513e24a1b307feb2fcd5da47a070d90" }, "@std/collections@1.0.2": { "integrity": "cb1834be534f967e86495f6c64fa06f6b3debdaab5b860c2d3194db59cd30157" @@ -137,7 +137,7 @@ "dependencies": [ "jsr:@std/assert@1.0.7", "jsr:@std/bytes@^1.0.4", - "jsr:@std/cli@^1.0.6", + "jsr:@std/cli@1.0.12", "jsr:@std/collections@^1.0.9", "jsr:@std/ulid@1", "npm:@deno/kv@~0.8.4", diff --git a/src/atomic_builder.ts b/src/atomic_builder.ts index cd0126f..0380188 100644 --- a/src/atomic_builder.ts +++ b/src/atomic_builder.ts @@ -71,7 +71,7 @@ export class AtomicBuilder< operations?: Operations, ) { // Check for large collection - if (collection.一internal.encoder) { + if (collection["encoder"]) { throw new InvalidCollectionError( "Atomic operations are not supported for serialized collections", ); @@ -187,17 +187,15 @@ export class AtomicBuilder< delete(id: ParseId): this { // Create id key from id and collection id key const collection = this.collection; - const idKey = extendKey(collection.一internal.keys.id, id); + const idKey = extendKey(collection["keys"].id, id); // Add delete operation this.operations.atomic.delete(idKey); // If collection is indexable, handle indexing - if (this.collection.一internal.isIndexable) { + if (this.collection["isIndexable"]) { // Add collection key for collision detection - this.operations.indexDeleteCollectionKeys.push( - collection.一internal.keys.base, - ); + this.operations.indexDeleteCollectionKeys.push(collection["keys"].base); // Add delete preperation function to prepeare delete functions list this.operations.prepareDeleteFns.push(async (kv) => { @@ -211,12 +209,8 @@ export class AtomicBuilder< } // Set history entry if keeps history - if (this.collection.一internal.keepsHistory) { - const historyKey = extendKey( - this.collection.一internal.keys.history, - id, - ulid(), - ); + if (this.collection["keepsHistory"]) { + const historyKey = extendKey(this.collection["keys"].history, id, ulid()); const historyEntry: HistoryEntry = { type: "delete", @@ -250,7 +244,7 @@ export class AtomicBuilder< // Create Denoatomic checks from atomci checks input list const checks: DenoAtomicCheck[] = atomicChecks.map( ({ id, versionstamp }) => { - const key = extendKey(this.collection.一internal.keys.id, id); + const key = extendKey(this.collection["keys"].id, id); return { key, versionstamp, @@ -284,7 +278,7 @@ export class AtomicBuilder< id: ParseId, value: TOutput extends DenoKvU64 ? bigint : never, ): this { - const idKey = extendKey(this.collection.一internal.keys.id, id); + const idKey = extendKey(this.collection["keys"].id, id); this.operations.atomic.sum(idKey, value); return this; } @@ -309,7 +303,7 @@ export class AtomicBuilder< id: ParseId, value: TOutput extends DenoKvU64 ? bigint : never, ): this { - const idKey = extendKey(this.collection.一internal.keys.id, id); + const idKey = extendKey(this.collection["keys"].id, id); this.operations.atomic.min(idKey, value); return this; } @@ -334,7 +328,7 @@ export class AtomicBuilder< id: ParseId, value: TOutput extends DenoKvU64 ? bigint : never, ): this { - const idKey = extendKey(this.collection.一internal.keys.id, id); + const idKey = extendKey(this.collection["keys"].id, id); this.operations.atomic.max(idKey, value); return this; } @@ -424,8 +418,8 @@ export class AtomicBuilder< enqueue(data: KvValue, options?: EnqueueOptions): this { // Prepare and add enqueue operation const prep = prepareEnqueue( - this.collection.一internal.keys.base, - this.collection.一internal.keys.undelivered, + this.collection["keys"].base, + this.collection["keys"].undelivered, data, options, ); @@ -523,7 +517,7 @@ export class AtomicBuilder< const overwrite = !!(options as AtomicSetOptions | undefined) ?.overwrite; - if (this.collection.一internal.isIndexable && overwrite) { + if (this.collection["isIndexable"] && overwrite) { throw new InvalidCollectionError( "The overwrite property is not supported for indexable collections", ); @@ -533,12 +527,11 @@ export class AtomicBuilder< // Create id key from collection id key and id const collection = this.collection; - const parsed = - collection.一internal.model._transform?.(value as TInput) ?? - collection.一internal.model.parse(value); + const parsed = collection["model"]._transform?.(value as TInput) ?? + collection["model"].parse(value); - const docId = id ?? await collection.一internal.idGenerator(parsed); - const idKey = extendKey(collection.一internal.keys.id, docId); + const docId = id ?? await collection["idGenerator"](parsed); + const idKey = extendKey(collection["keys"].id, docId); // Add set operation this.operations.atomic.set(idKey, parsed, options); @@ -546,11 +539,9 @@ export class AtomicBuilder< this.operations.atomic.check({ key: idKey, versionstamp: null }); } - if (collection.一internal.isIndexable) { + if (collection["isIndexable"]) { // Add collection id key for collision detection - this.operations.indexAddCollectionKeys.push( - collection.一internal.keys.base, - ); + this.operations.indexAddCollectionKeys.push(collection["keys"].base); // Add indexing operations await setIndices( @@ -564,9 +555,9 @@ export class AtomicBuilder< } // Set history entry if keeps history - if (this.collection.一internal.keepsHistory) { + if (this.collection["keepsHistory"]) { const historyKey = extendKey( - this.collection.一internal.keys.history, + this.collection["keys"].history, docId, ulid(), ); diff --git a/src/atomic_pool.ts b/src/atomic_pool.ts index 079af6e..0983165 100644 --- a/src/atomic_pool.ts +++ b/src/atomic_pool.ts @@ -15,27 +15,27 @@ export class AtomicPool implements DenoAtomicOperation { this.pool = []; } - set(key: DenoKvStrictKey, value: unknown, options?: DenoKvSetOptions) { + set(key: DenoKvStrictKey, value: unknown, options?: DenoKvSetOptions): this { this.pool.push((op) => op.set(key, value, options)); return this; } - delete(key: DenoKvStrictKey) { + delete(key: DenoKvStrictKey): this { this.pool.push((op) => op.delete(key)); return this; } - check(...checks: DenoAtomicCheck[]) { + check(...checks: DenoAtomicCheck[]): this { this.pool.push((op) => op.check(...checks)); return this; } - sum(key: DenoKvStrictKey, n: bigint) { + sum(key: DenoKvStrictKey, n: bigint): this { this.pool.push((op) => op.sum(key, n)); return this; } - max(key: DenoKvStrictKey, n: bigint) { + max(key: DenoKvStrictKey, n: bigint): this { this.pool.push((op) => op.max(key, n)); return this; } @@ -51,7 +51,7 @@ export class AtomicPool implements DenoAtomicOperation { delay?: number | undefined; keysIfUndelivered?: DenoKvStrictKey[]; }, - ) { + ): this { this.pool.push((op) => op.enqueue(value, options)); return this; } @@ -60,7 +60,7 @@ export class AtomicPool implements DenoAtomicOperation { throw Error("Not Implemented"); } - bindTo(atomic: DenoAtomicOperation) { + bindTo(atomic: DenoAtomicOperation): void { this.pool.forEach((mutation) => mutation(atomic)); } } diff --git a/src/atomic_wrapper.ts b/src/atomic_wrapper.ts index 9e51dc0..e251884 100644 --- a/src/atomic_wrapper.ts +++ b/src/atomic_wrapper.ts @@ -37,29 +37,29 @@ export class AtomicWrapper implements DenoAtomicOperation { this.currentKeySize = 0; } - set(key: DenoKvStrictKey, value: unknown, options?: DenoKvSetOptions) { + set(key: DenoKvStrictKey, value: unknown, options?: DenoKvSetOptions): this { this.addMutation((op) => op.set(key, value, options), 67, 2, false); return this; } - delete(key: DenoKvStrictKey) { + delete(key: DenoKvStrictKey): this { this.addMutation((op) => op.delete(key), 3, 2, false); return this; } - check(...checks: DenoAtomicCheck[]) { + check(...checks: DenoAtomicCheck[]): this { checks.forEach((check) => this.addMutation((op) => op.check(check), 3, 2, true) ); return this; } - sum(key: DenoKvStrictKey, n: bigint) { + sum(key: DenoKvStrictKey, n: bigint): this { this.addMutation((op) => op.sum(key, n), 3, 2, false); return this; } - max(key: DenoKvStrictKey, n: bigint) { + max(key: DenoKvStrictKey, n: bigint): this { this.addMutation((op) => op.max(key, n), 3, 2, false); return this; } @@ -75,7 +75,7 @@ export class AtomicWrapper implements DenoAtomicOperation { delay?: number | undefined; keysIfUndelivered?: DenoKvStrictKey[] | undefined; } | undefined, - ) { + ): this { this.addMutation( (op) => op.enqueue(value, options), 96, @@ -128,7 +128,7 @@ export class AtomicWrapper implements DenoAtomicOperation { size: number, keySize: number, isCheck: boolean, - ) { + ): void { this.currentSize += size; this.currentKeySize += keySize; this.currentCount++; diff --git a/src/collection.ts b/src/collection.ts index 52d23e7..e705950 100644 --- a/src/collection.ts +++ b/src/collection.ts @@ -1,7 +1,7 @@ import type { BuilderFn, CheckKeyOf, - CollectionInternals, + CollectionKeys, CollectionOptions, CommitResult, DenoKv, @@ -10,12 +10,14 @@ import type { DenoKvEntryMaybe, DenoKvStrictKey, EncodedEntry, + Encoder, EnqueueOptions, FindManyOptions, FindOptions, HandleOneOptions, HistoryEntry, IdempotentListener, + IdGenerator, IdUpsert, IndexDataEntry, KvId, @@ -151,9 +153,14 @@ export class Collection< private kv: DenoKv; private queueHandlers: QueueHandlers; private idempotentListener: IdempotentListener; - - /** Used for internal workings, do not manipulate or rely on these properties. */ - readonly 一internal: CollectionInternals; + private model: Model; + private primaryIndexList: string[]; + private secondaryIndexList: string[]; + private keys: CollectionKeys; + private idGenerator: IdGenerator>; + private encoder?: Encoder; + private isIndexable: boolean; + private keepsHistory: boolean; constructor( kv: DenoKv, @@ -167,9 +174,12 @@ export class Collection< this.kv = kv; this.queueHandlers = queueHandlers; this.idempotentListener = idempotentListener; + this.model = model; + this.idGenerator = options?.idGenerator ?? generateId as any; + this.encoder = options?.encoder; // Set keys - const keys = { + this.keys = { base: extendKey([KVDEX_KEY_PREFIX], ...key), id: extendKey( [KVDEX_KEY_PREFIX], @@ -213,31 +223,23 @@ export class Collection< const opts = (options ?? {}) as PossibleCollectionOptions; // Set index lists - const primaryIndexList: string[] = []; - const secondaryIndexList: string[] = []; + this.primaryIndexList = []; + this.secondaryIndexList = []; Object.entries(opts?.indices ?? {}).forEach(([index, value]) => { if (value === "primary") { - primaryIndexList.push(index); + this.primaryIndexList.push(index); } else { - secondaryIndexList.push(index); + this.secondaryIndexList.push(index); } }); // Set isIndexable flag - const isIndexable = primaryIndexList.length > 0 || - secondaryIndexList.length > 0; + this.isIndexable = this.primaryIndexList.length > 0 || + this.secondaryIndexList.length > 0; - this.一internal = { - model, - idGenerator: options?.idGenerator ?? generateId as any, - encoder: options?.encoder, - keys, - primaryIndexList, - secondaryIndexList, - isIndexable, - keepsHistory: options?.history ?? false, - }; + // Set keepsHistory flag + this.keepsHistory = options?.history ?? false; } /**********************/ @@ -267,7 +269,7 @@ export class Collection< options?: FindOptions, ): Promise> | null> { // Create document key, get document entry - const key = extendKey(this.一internal.keys.id, id); + const key = extendKey(this.keys.id, id); const entry = await this.kv.get(key, options); return await this.constructDocument(entry); } @@ -294,11 +296,11 @@ export class Collection< options?: FindOptions, ): Promise> | null> { // Serialize and compress index value - const encoded = await encodeData(value, this.一internal.encoder); + const encoded = await encodeData(value, this.encoder); // Create the index key const key = extendKey( - this.一internal.keys.primaryIndex, + this.keys.primaryIndex, index as KvId, encoded, ); @@ -342,11 +344,11 @@ export class Collection< >, ): Promise>>> { // Serialize and compress index value - const encoded = await encodeData(value, this.一internal.encoder); + const encoded = await encodeData(value, this.encoder); // Create prefix key const prefixKey = extendKey( - this.一internal.keys.secondaryIndex, + this.keys.secondaryIndex, index as KvId, encoded, ); @@ -383,7 +385,7 @@ export class Collection< options?: FindManyOptions, ): Promise>[]> { // Create document keys, get document entries - const keys = ids.map((id) => extendKey(this.一internal.keys.id, id)); + const keys = ids.map((id) => extendKey(this.keys.id, id)); const entries = await kvGetMany(keys, this.kv, options); // Create empty result list @@ -431,7 +433,7 @@ export class Collection< ): Promise>> { // Initialize result list and create history key prefix const result: HistoryEntry[] = []; - const keyPrefix = extendKey(this.一internal.keys.history, id); + const keyPrefix = extendKey(this.keys.history, id); const selector = createListSelector(keyPrefix, options); // Create hsitory entries iterator @@ -453,12 +455,12 @@ export class Collection< let historyEntry = value as HistoryEntry; // Handle serialized entries - if (historyEntry.type === "write" && this.一internal.encoder) { + if (historyEntry.type === "write" && this.encoder) { const { ids } = historyEntry.value as EncodedEntry; const timeId = getDocumentId(key as DenoKvStrictKey)!; const keys = ids.map((segmentId) => - extendKey(this.一internal.keys.historySegment, id, timeId, segmentId) + extendKey(this.keys.historySegment, id, timeId, segmentId) ); const entries = await kvGetMany(keys, this.kv); @@ -467,18 +469,18 @@ export class Collection< const data = concat(entries.map((entry) => entry.value as Uint8Array)); // Decompress and deserialize - const decoded = await decodeData(data, this.一internal.encoder); + const decoded = await decodeData(data, this.encoder); // Set history entry historyEntry = { ...historyEntry, - value: this.一internal.model.parse?.(decoded), + value: this.model.parse?.(decoded), }; } else if (historyEntry.type === "write") { // Set history entry historyEntry = { ...historyEntry, - value: this.一internal.model.parse?.(historyEntry.value), + value: this.model.parse?.(historyEntry.value), }; } @@ -558,7 +560,7 @@ export class Collection< * @returns A promise that resovles to void. */ async delete(...ids: ParseId[]): Promise { - await this.deleteDocuments(ids, this.一internal.keepsHistory); + await this.deleteDocuments(ids, this.keepsHistory); } /** @@ -583,11 +585,11 @@ export class Collection< options?: FindOptions, ): Promise { // Serialize and compress index value - const encoded = await encodeData(value, this.一internal.encoder); + const encoded = await encodeData(value, this.encoder); // Create index key const key = extendKey( - this.一internal.keys.primaryIndex, + this.keys.primaryIndex, index as KvId, encoded, ); @@ -606,7 +608,7 @@ export class Collection< & Pick, "__id__">; // Delete document by id - await this.deleteDocuments([__id__], this.一internal.keepsHistory); + await this.deleteDocuments([__id__], this.keepsHistory); } /** @@ -639,11 +641,11 @@ export class Collection< >, ): Promise { // Serialize and compress index value - const encoded = await encodeData(value, this.一internal.encoder); + const encoded = await encodeData(value, this.encoder); // Create prefix key const prefixKey = extendKey( - this.一internal.keys.secondaryIndex, + this.keys.secondaryIndex, index as KvId, encoded, ); @@ -651,7 +653,7 @@ export class Collection< // Delete documents by secondary index, return iterator cursor const { cursor } = await this.handleMany( prefixKey, - (doc) => this.deleteDocuments([doc.id], this.一internal.keepsHistory), + (doc) => this.deleteDocuments([doc.id], this.keepsHistory), options, ); @@ -801,11 +803,11 @@ export class Collection< > > { // Serialize and compress index value - const encoded = await encodeData(value, this.一internal.encoder); + const encoded = await encodeData(value, this.encoder); // Create prefix key const prefixKey = extendKey( - this.一internal.keys.secondaryIndex, + this.keys.secondaryIndex, index as KvId, encoded, ); @@ -978,7 +980,7 @@ export class Collection< > { // Update each document, add commit result to result list return await this.handleMany( - this.一internal.keys.id, + this.keys.id, (doc) => this.updateDocument(doc, value, options), options, ); @@ -1014,10 +1016,7 @@ export class Collection< > > { // Create prefix key - const prefixKey = extendKey( - this.一internal.keys.secondaryIndex, - order as KvId, - ); + const prefixKey = extendKey(this.keys.secondaryIndex, order as KvId); // Update each document by secondary index, add commit result to result list return await this.handleMany( @@ -1060,7 +1059,7 @@ export class Collection< ): Promise> | DenoKvCommitError> { // Update a single document const { result } = await this.handleMany( - this.一internal.keys.id, + this.keys.id, (doc) => this.updateDocument(doc, data, options), { ...options, take: 1 }, ); @@ -1153,10 +1152,7 @@ export class Collection< options?: T, ): Promise> | DenoKvCommitError> { // Create prefix key - const prefixKey = extendKey( - this.一internal.keys.secondaryIndex, - order as KvId, - ); + const prefixKey = extendKey(this.keys.secondaryIndex, order as KvId); // Update a single document const { result } = await this.handleMany( @@ -1261,10 +1257,7 @@ export class Collection< // Perform quick delete if all documents are to be deleted if (selectsAll(options)) { // Create list iterator and empty keys list, init atomic operation - const iter = await this.kv.list( - { prefix: this.一internal.keys.base }, - options, - ); + const iter = await this.kv.list({ prefix: this.keys.base }, options); const keys: DenoKvStrictKey[] = []; const atomic = new AtomicWrapper(this.kv); @@ -1275,10 +1268,8 @@ export class Collection< } // Set history entries if keeps history - if (this.一internal.keepsHistory) { - const historyIter = await this.kv.list({ - prefix: this.一internal.keys.id, - }); + if (this.keepsHistory) { + const historyIter = await this.kv.list({ prefix: this.keys.id }); for await (const { key } of historyIter) { const id = getDocumentId(key as DenoKvStrictKey); @@ -1286,11 +1277,7 @@ export class Collection< continue; } - const historyKey = extendKey( - this.一internal.keys.history, - id, - ulid(), - ); + const historyKey = extendKey(this.keys.history, id, ulid()); const historyEntry: HistoryEntry = { type: "delete", @@ -1308,8 +1295,8 @@ export class Collection< // Execute delete operation for each document entry const { cursor } = await this.handleMany( - this.一internal.keys.id, - (doc) => this.deleteDocuments([doc.id], this.一internal.keepsHistory), + this.keys.id, + (doc) => this.deleteDocuments([doc.id], this.keepsHistory), options, ); @@ -1344,15 +1331,12 @@ export class Collection< >, ): Promise { // Create prefix key - const prefixKey = extendKey( - this.一internal.keys.secondaryIndex, - order as KvId, - ); + const prefixKey = extendKey(this.keys.secondaryIndex, order as KvId); // Delete documents by secondary index, return iterator cursor const { cursor } = await this.handleMany( prefixKey, - (doc) => this.deleteDocuments([doc.id], this.一internal.keepsHistory), + (doc) => this.deleteDocuments([doc.id], this.keepsHistory), options, ); @@ -1387,7 +1371,7 @@ export class Collection< ): Promise>>> { // Get each document, return result list and current iterator cursor return await this.handleMany( - this.一internal.keys.id, + this.keys.id, (doc) => doc, options, ); @@ -1423,10 +1407,7 @@ export class Collection< ParseId >, ): Promise>>> { - const prefixKey = extendKey( - this.一internal.keys.secondaryIndex, - order as KvId, - ); + const prefixKey = extendKey(this.keys.secondaryIndex, order as KvId); return await this.handleMany( prefixKey, (doc) => doc, @@ -1464,7 +1445,7 @@ export class Collection< ): Promise> | null> { // Get result list with one item const { result } = await this.handleMany( - this.一internal.keys.id, + this.keys.id, (doc) => doc, { ...options, take: 1 }, ); @@ -1550,10 +1531,7 @@ export class Collection< >, ): Promise> | null> { // Create prefix key - const prefixKey = extendKey( - this.一internal.keys.secondaryIndex, - order as KvId, - ); + const prefixKey = extendKey(this.keys.secondaryIndex, order as KvId); // Get result list with one item const { result } = await this.handleMany( @@ -1595,7 +1573,7 @@ export class Collection< ): Promise { // Execute callback function for each document entry const { cursor } = await this.handleMany( - this.一internal.keys.id, + this.keys.id, async (doc) => await fn(doc), options, ); @@ -1684,10 +1662,7 @@ export class Collection< >, ): Promise { // Create prefix key - const prefixKey = extendKey( - this.一internal.keys.secondaryIndex, - order as KvId, - ); + const prefixKey = extendKey(this.keys.secondaryIndex, order as KvId); // Execute callback function for each document entry const { cursor } = await this.handleMany( @@ -1731,7 +1706,7 @@ export class Collection< ): Promise>> { // Execute callback function for each document entry, return result and cursor return await this.handleMany( - this.一internal.keys.id, + this.keys.id, (doc) => fn(doc), options, ); @@ -1773,11 +1748,11 @@ export class Collection< >, ): Promise>> { // Serialize and compress index value - const encoded = await encodeData(value, this.一internal.encoder); + const encoded = await encodeData(value, this.encoder); // Create prefix key const prefixKey = extendKey( - this.一internal.keys.secondaryIndex, + this.keys.secondaryIndex, index as KvId, encoded, ); @@ -1823,10 +1798,7 @@ export class Collection< >, ): Promise>> { // Create prefix key - const prefixKey = extendKey( - this.一internal.keys.secondaryIndex, - order as KvId, - ); + const prefixKey = extendKey(this.keys.secondaryIndex, order as KvId); // Execute callback function for each document entry, return result and cursor return await this.handleMany( @@ -1864,10 +1836,7 @@ export class Collection< // Perform efficient count if counting all document entries if (selectsAll(options)) { - const iter = await this.kv.list( - { prefix: this.一internal.keys.id }, - options, - ); + const iter = await this.kv.list({ prefix: this.keys.id }, options); for await (const _ of iter) { result++; } @@ -1875,7 +1844,7 @@ export class Collection< } // Perform count using many documents handler - await this.handleMany(this.一internal.keys.id, () => result++, options); + await this.handleMany(this.keys.id, () => result++, options); return result; } @@ -1905,11 +1874,11 @@ export class Collection< >, ): Promise { // Serialize and compress index value - const encoded = await encodeData(value, this.一internal.encoder); + const encoded = await encodeData(value, this.encoder); // Create prefix key const prefixKey = extendKey( - this.一internal.keys.secondaryIndex, + this.keys.secondaryIndex, index as KvId, encoded, ); @@ -1955,10 +1924,7 @@ export class Collection< >, ): Promise { // Create prefix key - const prefixKey = extendKey( - this.一internal.keys.secondaryIndex, - order as KvId, - ); + const prefixKey = extendKey(this.keys.secondaryIndex, order as KvId); // Initialize count result let result = 0; @@ -2002,8 +1968,8 @@ export class Collection< ): Promise { // Prepare message and options for enqueue const prep = prepareEnqueue( - this.一internal.keys.base, - this.一internal.keys.undelivered, + this.keys.base, + this.keys.undelivered, data, options, ); @@ -2044,10 +2010,7 @@ export class Collection< options?: QueueListenerOptions, ): Promise { // Create handler id - const handlerId = createHandlerId( - this.一internal.keys.base, - options?.topic, - ); + const handlerId = createHandlerId(this.keys.base, options?.topic); // Add new handler to specified handlers const handlers = this.queueHandlers.get(handlerId) ?? []; @@ -2079,7 +2042,7 @@ export class Collection< options?: FindOptions, ): Promise | null> { // Create document key, get document entry - const key = extendKey(this.一internal.keys.undelivered, id); + const key = extendKey(this.keys.undelivered, id); const result = await this.kv.get(key, options); // If no entry exists, return null @@ -2108,11 +2071,8 @@ export class Collection< async deleteHistory(id: ParseId): Promise { // Initialize atomic operation and create iterators const atomic = new AtomicWrapper(this.kv); - const historyKeyPrefix = extendKey(this.一internal.keys.history, id); - const historySegmentKeyPrefix = extendKey( - this.一internal.keys.historySegment, - id, - ); + const historyKeyPrefix = extendKey(this.keys.history, id); + const historySegmentKeyPrefix = extendKey(this.keys.historySegment, id); const historyIter = await this.kv.list({ prefix: historyKeyPrefix }); const historySegmentIter = await this.kv.list({ prefix: historySegmentKeyPrefix, @@ -2143,7 +2103,7 @@ export class Collection< * @param id - Id of undelivered document. */ async deleteUndelivered(id: KvId): Promise { - const key = extendKey(this.一internal.keys.undelivered, id); + const key = extendKey(this.keys.undelivered, id); await this.kv.delete(key); } @@ -2181,7 +2141,7 @@ export class Collection< fn: (doc: Document> | null) => unknown, options?: WatchOptions, ): WatchManager { - const key = extendKey(this.一internal.keys.id, id); + const key = extendKey(this.keys.id, id); return createWatcher(this.kv, options, [key], async (entries) => { const entry = entries.at(0); @@ -2239,7 +2199,7 @@ export class Collection< fn: (doc: (Document> | null)[]) => unknown, options?: WatchOptions, ): WatchManager { - const keys = ids.map((id) => extendKey(this.一internal.keys.id, id)); + const keys = ids.map((id) => extendKey(this.keys.id, id)); return createWatcher(this.kv, options, keys, async (entries) => { // Construct documents @@ -2273,11 +2233,11 @@ export class Collection< options: SetOptions | undefined, ): Promise> | DenoKvCommitError> { // Create id, document key and parse document value - const parsed = this.一internal.model._transform?.(value as TInput) ?? - this.一internal.model.parse(value); + const parsed = this.model._transform?.(value as TInput) ?? + this.model.parse(value); - const docId = id ?? await this.一internal.idGenerator(parsed); - const idKey = extendKey(this.一internal.keys.id, docId); + const docId = id ?? await this.idGenerator(parsed); + const idKey = extendKey(this.keys.id, docId); return await this.setDoc(docId, idKey, parsed, options); } @@ -2314,24 +2274,24 @@ export class Collection< } // Serialize if enabled - if (this.一internal.encoder) { + if (this.encoder) { const encoded = isUint8Array - ? await this.一internal.encoder.compressor?.compress(value) ?? value - : await encodeData(value, this.一internal.encoder); + ? await this.encoder.compressor?.compress(value) ?? value + : await encodeData(value, this.encoder); // Set segmented entries let index = 0; for (let i = 0; i < encoded.length; i += UINT8ARRAY_LENGTH_LIMIT) { const part = encoded.subarray(i, i + UINT8ARRAY_LENGTH_LIMIT); - const key = extendKey(this.一internal.keys.segment, docId, index); + const key = extendKey(this.keys.segment, docId, index); ids.push(index); operationPool.set(key, part, options); // Set history segments if keeps history - if (this.一internal.keepsHistory) { + if (this.keepsHistory) { const historySegmentKey = extendKey( - this.一internal.keys.historySegment, + this.keys.historySegment, docId, timeId, index, @@ -2356,8 +2316,8 @@ export class Collection< operationPool.set(idKey, docValue, options); // Set history entry if keeps history - if (this.一internal.keepsHistory) { - const historyKey = extendKey(this.一internal.keys.history, docId, timeId); + if (this.keepsHistory) { + const historyKey = extendKey(this.keys.history, docId, timeId); const historyEntry: HistoryEntry = { type: "write", @@ -2369,7 +2329,7 @@ export class Collection< } // Set indices if is indexable - if (this.一internal.isIndexable) { + if (this.isIndexable) { await setIndices( docId, value as KvObject, @@ -2412,25 +2372,19 @@ export class Collection< if (options?.batched && indexCheck) { const failedAtomic = new AtomicWrapper(this.kv); - if (this.一internal.keepsHistory) { - const historyKey = extendKey( - this.一internal.keys.history, - docId, - timeId, - ); + if (this.keepsHistory) { + const historyKey = extendKey(this.keys.history, docId, timeId); failedAtomic.delete(historyKey); } - if (this.一internal.encoder) { + if (this.encoder) { const { ids } = docValue as EncodedEntry; ids.forEach((id) => - failedAtomic.delete( - extendKey(this.一internal.keys.segment, docId, id), - ) + failedAtomic.delete(extendKey(this.keys.segment, docId, id)) ); } - if (this.一internal.isIndexable) { + if (this.isIndexable) { await deleteIndices( docId, value as KvObject, @@ -2481,7 +2435,7 @@ export class Collection< const { value, id } = doc; // If indexable, check for index collisions and delete exisitng index entries - if (this.一internal.isIndexable) { + if (this.isIndexable) { const atomic = this.kv.atomic(); await checkIndices( @@ -2507,9 +2461,9 @@ export class Collection< } // If serialized, delete existing segment entries - if (this.一internal.encoder) { + if (this.encoder) { const atomic = new AtomicWrapper(this.kv); - const keyPrefix = extendKey(this.一internal.keys.segment, id); + const keyPrefix = extendKey(this.keys.segment, id); const iter = await this.kv.list({ prefix: keyPrefix }); for await (const { key } of iter) { @@ -2534,12 +2488,12 @@ export class Collection< : deepMerge({ value }, { value: data }, options?.mergeOptions).value; // Parse updated value - const parsed = this.一internal.model.parse(updated as any); + const parsed = this.model.parse(updated as any); // Set new document value return await this.setDoc( id, - extendKey(this.一internal.keys.id, id), + extendKey(this.keys.id, id), parsed, { ...options, @@ -2569,12 +2523,12 @@ export class Collection< return null; } - if (this.一internal.encoder) { + if (this.encoder) { // Get document parts const { ids, isUint8Array } = value as EncodedEntry; const keys = ids.map((segId) => - extendKey(this.一internal.keys.segment, docId, segId) + extendKey(this.keys.segment, docId, segId) ); const docEntries = await kvGetMany(keys, this.kv); @@ -2584,12 +2538,11 @@ export class Collection< // Decompress and deserialize const decoded = isUint8Array - ? (await this.一internal.encoder?.compressor?.decompress(data) ?? - data) as TOutput - : await decodeData(data, this.一internal.encoder); + ? (await this.encoder?.compressor?.decompress(data) ?? data) as TOutput + : await decodeData(data, this.encoder); // Return parsed document - return new Document>(this.一internal.model, { + return new Document>(this.model, { id: docId as ParseId, value: decoded, versionstamp, @@ -2599,7 +2552,7 @@ export class Collection< // Remove id from value and return parsed document if indexed entry if (typeof indexedDocId !== "undefined") { const { __id__, ...val } = value as any; - return new Document>(this.一internal.model, { + return new Document>(this.model, { id: docId as ParseId, value: val as TOutput, versionstamp, @@ -2607,7 +2560,7 @@ export class Collection< } // Return parsed document - return new Document>(this.一internal.model, { + return new Document>(this.model, { id: docId as ParseId, value: value as TOutput, versionstamp, @@ -2707,7 +2660,7 @@ export class Collection< // Set delete history entry if recordHistory is true if (recordHistory) { ids.forEach((id) => { - const historyKey = extendKey(this.一internal.keys.history, id, ulid()); + const historyKey = extendKey(this.keys.history, id, ulid()); const historyEntry: HistoryEntry = { type: "delete", @@ -2718,11 +2671,11 @@ export class Collection< }); } - if (this.一internal.isIndexable && this.一internal.encoder) { + if (this.isIndexable && this.encoder) { // Run delete operations for each id await allFulfilled(ids.map(async (id) => { // Create document id key, get entry and construct document - const idKey = extendKey(this.一internal.keys.id, id); + const idKey = extendKey(this.keys.id, id); const entry = await this.kv.get(idKey); const doc = await this.constructDocument(entry); @@ -2731,7 +2684,7 @@ export class Collection< if (entry.value) { const keys = (entry.value as EncodedEntry).ids.map((segId) => - extendKey(this.一internal.keys.segment, id, segId) + extendKey(this.keys.segment, id, segId) ); keys.forEach((key) => atomic.delete(key)); @@ -2747,11 +2700,11 @@ export class Collection< return; } - if (this.一internal.isIndexable) { + if (this.isIndexable) { // Run delete operations for each id await allFulfilled(ids.map(async (id) => { // Create idKey, get document value - const idKey = extendKey(this.一internal.keys.id, id); + const idKey = extendKey(this.keys.id, id); const { value } = await this.kv.get(idKey); // If no value, abort delete @@ -2769,11 +2722,11 @@ export class Collection< return; } - if (this.一internal.encoder) { + if (this.encoder) { // Perform delete for each id await allFulfilled(ids.map(async (id) => { // Create document id key, get document value - const idKey = extendKey(this.一internal.keys.id, id); + const idKey = extendKey(this.keys.id, id); const { value } = await this.kv.get(idKey); // If no value, abort delete @@ -2785,7 +2738,7 @@ export class Collection< atomic.delete(idKey); const keys = (value as EncodedEntry).ids.map((segId) => - extendKey(this.一internal.keys.segment, id, segId) + extendKey(this.keys.segment, id, segId) ); keys.forEach((key) => atomic.delete(key)); @@ -2797,7 +2750,7 @@ export class Collection< } // Perform delete for each id and commit the operation - ids.forEach((id) => atomic.delete(extendKey(this.一internal.keys.id, id))); + ids.forEach((id) => atomic.delete(extendKey(this.keys.id, id))); await atomic.commit(); } } diff --git a/src/ext/encoding/brotli/brotli_compressor.ts b/src/ext/encoding/brotli/brotli_compressor.ts index 3850703..ca2b9b8 100644 --- a/src/ext/encoding/brotli/brotli_compressor.ts +++ b/src/ext/encoding/brotli/brotli_compressor.ts @@ -23,7 +23,7 @@ class BrotliCompressor implements Compressor { this.quality = quality; } - compress(data: Uint8Array) { + compress(data: Uint8Array): Uint8Array { const buffer = brotliCompressSync(data, { params: { [constants.BROTLI_PARAM_QUALITY]: this.quality }, }); @@ -31,7 +31,7 @@ class BrotliCompressor implements Compressor { return new Uint8Array(buffer); } - decompress(data: Uint8Array) { + decompress(data: Uint8Array): Uint8Array { const buffer = brotliDecompressSync(data, { params: { [constants.BROTLI_PARAM_QUALITY]: this.quality }, }); diff --git a/src/ext/encoding/json/utils.ts b/src/ext/encoding/json/utils.ts index 1810bb5..2d8a2ca 100644 --- a/src/ext/encoding/json/utils.ts +++ b/src/ext/encoding/json/utils.ts @@ -102,7 +102,7 @@ export function jsonParse(value: string): T { * @param value * @returns */ -function replacer(_key: string, value: unknown) { +function replacer(_key: string, value: unknown): unknown { return _replacer(value); } @@ -342,7 +342,7 @@ function _replacer(value: unknown): unknown { * @param value * @returns */ -function reviver(_key: string, value: unknown) { +function reviver(_key: string, value: unknown): unknown { return _reviver(value); } @@ -564,6 +564,6 @@ function postReviver(value: T): T { * @param value - JSON value to map from. * @returns Mapped value. */ -function mapValue(key: string, value: unknown) { +function mapValue(key: string, value: unknown): T { return (value as Record)[key]; } diff --git a/src/ext/kv/async_lock.ts b/src/ext/kv/async_lock.ts index 755d750..d905b22 100644 --- a/src/ext/kv/async_lock.ts +++ b/src/ext/kv/async_lock.ts @@ -12,21 +12,21 @@ export class AsyncLock { return result; } - async close() { + async close(): Promise { for (const lock of this.queue) { lock.resolve(); await lock.promise; } } - private async lock() { + private async lock(): Promise { const prev = this.queue.at(-1); const next = Promise.withResolvers(); this.queue.push(next); await prev?.promise; } - private release() { + private release(): void { const lock = this.queue.shift(); lock?.resolve(); } diff --git a/src/ext/kv/utils.ts b/src/ext/kv/utils.ts index 4614d9c..38394a7 100644 --- a/src/ext/kv/utils.ts +++ b/src/ext/kv/utils.ts @@ -1,7 +1,7 @@ import { ulid } from "@std/ulid"; import type { DenoKvStrictKey, DenoKvStrictKeyPart } from "../../types.ts"; -export function createVersionstamp() { +export function createVersionstamp(): string { return ulid(); } @@ -63,7 +63,7 @@ function sortByType( function sortByValue( part1: DenoKvStrictKeyPart, part2: DenoKvStrictKeyPart, -) { +): number { if (typeof part2 !== typeof part2) { throw Error("Cannot compare values of different type"); } @@ -95,7 +95,7 @@ function sortByValue( } } -function sortByUint8Array(u1: Uint8Array, u2: Uint8Array) { +function sortByUint8Array(u1: Uint8Array, u2: Uint8Array): number { for (let i = 0; i < Math.min(u1.length, u2.length); i++) { const b1 = u1.at(i); const b2 = u2.at(i); diff --git a/src/ext/kv/watcher.ts b/src/ext/kv/watcher.ts index 451d6f3..519a2e1 100644 --- a/src/ext/kv/watcher.ts +++ b/src/ext/kv/watcher.ts @@ -66,7 +66,7 @@ export class Watcher { this.listener.reject = reject; } - cancel() { + cancel(): void { this.listener.reject(); } } diff --git a/src/kvdex.ts b/src/kvdex.ts index 6edb711..8a076b1 100644 --- a/src/kvdex.ts +++ b/src/kvdex.ts @@ -2,6 +2,7 @@ import type { CollectionOptions, CollectionSelector, CountAllOptions, + Database, DenoKv, DenoKvCommitResult, DenoKvStrictKey, @@ -81,7 +82,7 @@ import { AtomicWrapper } from "./atomic_wrapper.ts"; */ export function kvdex( options: KvdexOptions, -): Kvdex> & Schema { +): Database { // Set listener activated flag and queue handlers map let listener: Promise; const queueHandlers = new Map[]>(); diff --git a/src/types.ts b/src/types.ts index 7f4f004..6c7785d 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,6 +1,7 @@ import type { Collection } from "./collection.ts"; import type { DeepMergeOptions } from "@std/collections/deep-merge"; import type { Document } from "./document.ts"; +import type { Kvdex } from "./kvdex.ts"; /*********************/ /* */ @@ -286,22 +287,6 @@ export type AtomicSetOptions> = /* */ /************************/ -/** Used for internal workings, do not manipulate or rely on these properties. */ -export type CollectionInternals< - TInput, - TOutput extends KvValue, - TOptions extends CollectionOptions, -> = { - readonly model: Model; - readonly primaryIndexList: string[]; - readonly secondaryIndexList: string[]; - readonly keys: CollectionKeys; - readonly idGenerator: IdGenerator>; - readonly encoder?: Encoder; - readonly isIndexable: boolean; - readonly keepsHistory: boolean; -}; - /** Options for creating a new collection */ export type CollectionOptions = & { @@ -634,6 +619,14 @@ export type PrimaryIndexUpsert< /* */ /*******************/ +/** + * Kvdex database object. + * Contains configured collections and provides methods for database-level functionalitites. + */ +export type Database = + & Kvdex> + & Schema; + /** Schema definition, containing builder functions and nested schema definitions. */ export type SchemaDefinition = { [key: string]: diff --git a/src/utils.ts b/src/utils.ts index af6b495..6587534 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -98,11 +98,11 @@ export async function createSecondaryIndexKeyPrefix( collection: Collection, ) { // Serialize and compress index value - const encoded = await encodeData(value, collection.一internal.encoder); + const encoded = await encodeData(value, collection["encoder"]); // Create prefix key return extendKey( - collection.一internal.keys.secondaryIndex, + collection["keys"].secondaryIndex, index as KvId, encoded, ); @@ -494,14 +494,14 @@ async function handleIndices( secondary?: (indexKey: KvKey) => void, ): Promise { // Handle primary indices - for (const index of collection.一internal.primaryIndexList) { + for (const index of collection["primaryIndexList"]) { const indexValue = data[index] as KvId | undefined; if (typeof indexValue === "undefined") continue; - const encoded = await encodeData(indexValue, collection.一internal.encoder); + const encoded = await encodeData(indexValue, collection["encoder"]); const indexKey = extendKey( - collection.一internal.keys.primaryIndex, + collection["keys"].primaryIndex, index, encoded, ); @@ -514,14 +514,14 @@ async function handleIndices( } // Handle secondary indices - for (const index of collection.一internal.secondaryIndexList) { + for (const index of collection["secondaryIndexList"]) { const indexValue = data[index] as KvId | undefined; if (typeof indexValue === "undefined") continue; - const encoded = await encodeData(indexValue, collection.一internal.encoder); + const encoded = await encodeData(indexValue, collection["encoder"]); const indexKey = extendKey( - collection.一internal.keys.secondaryIndex, + collection["keys"].secondaryIndex, index, encoded, id, diff --git a/tests/collection/add.test.ts b/tests/collection/add.test.ts index bd476e4..67c8799 100644 --- a/tests/collection/add.test.ts +++ b/tests/collection/add.test.ts @@ -7,6 +7,7 @@ Deno.test("collection - add", async (t) => { await useDb(async (db) => { const cr = await db.users.add(mockUser1); assert(cr.ok); + const doc = await db.users.find(cr.id); assert(doc !== null); assert(doc.value.username === mockUser1.username); diff --git a/tests/collection/enqueue.test.ts b/tests/collection/enqueue.test.ts index 19995c2..e59594f 100644 --- a/tests/collection/enqueue.test.ts +++ b/tests/collection/enqueue.test.ts @@ -21,10 +21,7 @@ Deno.test("collection - enqueue", async (t) => { schema: { numbers: collection(model()) }, }); - const handlerId = createHandlerId( - db.numbers.一internal.keys.base, - undefined, - ); + const handlerId = createHandlerId(db.numbers["keys"].base, undefined); let assertion = false; diff --git a/tests/collection/listenQueue.test.ts b/tests/collection/listenQueue.test.ts index dcae079..c342c6e 100644 --- a/tests/collection/listenQueue.test.ts +++ b/tests/collection/listenQueue.test.ts @@ -27,10 +27,7 @@ Deno.test("collection - listenQueue", async (t) => { }, }); - const handlerId = createHandlerId( - db.numbers.一internal.keys.base, - undefined, - ); + const handlerId = createHandlerId(db.numbers["keys"].base, undefined); let assertion = false; diff --git a/tests/collection/properties.test.ts b/tests/collection/properties.test.ts index 1dd67bc..08e119f 100644 --- a/tests/collection/properties.test.ts +++ b/tests/collection/properties.test.ts @@ -10,8 +10,8 @@ import { sleep } from "../utils.ts"; Deno.test("collection - properties", async (t) => { await t.step("Keys should have the correct prefixes", async () => { await useDb((db) => { - const baseKey = db.users.一internal.keys.base; - const idKey = db.users.一internal.keys.id; + const baseKey = db.users["keys"].base; + const idKey = db.users["keys"].id; const prefix = extendKey([KVDEX_KEY_PREFIX], "users"); assert(keyEq(baseKey, prefix)); @@ -36,8 +36,8 @@ Deno.test("collection - properties", async (t) => { }, }); - const id1 = db.users1.一internal.idGenerator(mockUser1); - const id2 = db.users2.一internal.idGenerator(mockUser1); + const id1 = db.users1["idGenerator"](mockUser1); + const id2 = db.users2["idGenerator"](mockUser1); assert(typeof id1 === "number"); assert(id2 === mockUser1.username); diff --git a/tests/db/atomic.test.ts b/tests/db/atomic.test.ts index ea840cf..c6c9fb6 100644 --- a/tests/db/atomic.test.ts +++ b/tests/db/atomic.test.ts @@ -313,10 +313,7 @@ Deno.test("db - atomic", async (t) => { schema: { numbers: collection(model()) }, }); - const handlerId = createHandlerId( - db.numbers.一internal.keys.base, - undefined, - ); + const handlerId = createHandlerId(db.numbers["keys"].base, undefined); let assertion = false; diff --git a/tests/db/kvdex.test.ts b/tests/db/kvdex.test.ts index f96648d..0638b59 100644 --- a/tests/db/kvdex.test.ts +++ b/tests/db/kvdex.test.ts @@ -18,8 +18,8 @@ Deno.test("db - kvdex", async (t) => { }, }); - const key1 = JSON.stringify(db.numbers.一internal.keys.base); - const key2 = JSON.stringify(db.nested.numbers.一internal.keys.base); + const key1 = JSON.stringify(db.numbers["keys"].base); + const key2 = JSON.stringify(db.nested.numbers["keys"].base); assert(key1 !== key2); assert(key1 === `["${KVDEX_KEY_PREFIX}","numbers"]`); diff --git a/tests/db/properties.test.ts b/tests/db/properties.test.ts index fe0994e..4f7aa1a 100644 --- a/tests/db/properties.test.ts +++ b/tests/db/properties.test.ts @@ -3,13 +3,13 @@ import { kvdex } from "../../mod.ts"; Deno.test("db - properties", async (t) => { await t.step("Should allow native Deno KV type", async () => { - const kv = await Deno.openKv(); + const kv = await Deno.openKv(":memory:"); kvdex({ kv }); kv.close(); }); await t.step("Should allow NPM Deno KV type", async () => { - const kv = await openKv(); + const kv = await openKv(":memory:"); kvdex({ kv }); kv.close(); }); diff --git a/tests/indexable_collection/enqueue.test.ts b/tests/indexable_collection/enqueue.test.ts index c5f621f..3b2c827 100644 --- a/tests/indexable_collection/enqueue.test.ts +++ b/tests/indexable_collection/enqueue.test.ts @@ -22,10 +22,7 @@ Deno.test("indexable_collection - enqueue", async (t) => { }); const sleeper = createResolver(); - const handlerId = createHandlerId( - db.i_users.一internal.keys.base, - undefined, - ); + const handlerId = createHandlerId(db.i_users["keys"].base, undefined); let assertion = false; const listener = kv.listenQueue((msg) => { diff --git a/tests/indexable_collection/listenQueue.test.ts b/tests/indexable_collection/listenQueue.test.ts index 65b852e..2068f18 100644 --- a/tests/indexable_collection/listenQueue.test.ts +++ b/tests/indexable_collection/listenQueue.test.ts @@ -26,10 +26,7 @@ Deno.test("indexable_collection - listenQueue", async (t) => { }); const sleeper = createResolver(); - const handlerId = createHandlerId( - db.i_users.一internal.keys.base, - undefined, - ); + const handlerId = createHandlerId(db.i_users["keys"].base, undefined); let assertion = false; const listener = db.i_users.listenQueue((msgData) => { diff --git a/tests/indexable_collection/properties.test.ts b/tests/indexable_collection/properties.test.ts index b169d59..0b8b97f 100644 --- a/tests/indexable_collection/properties.test.ts +++ b/tests/indexable_collection/properties.test.ts @@ -22,10 +22,10 @@ import { mockUser3 } from "../mocks.ts"; Deno.test("indexable_collection - properties", async (t) => { await t.step("Keys should have the correct prefixes", async () => { await useDb((db) => { - const baseKey = db.i_users.一internal.keys.base; - const idKey = db.i_users.一internal.keys.id; - const primaryIndexKey = db.i_users.一internal.keys.primaryIndex; - const secondaryIndexKey = db.i_users.一internal.keys.secondaryIndex; + const baseKey = db.i_users["keys"].base; + const idKey = db.i_users["keys"].id; + const primaryIndexKey = db.i_users["keys"].primaryIndex; + const secondaryIndexKey = db.i_users["keys"].secondaryIndex; const prefix = extendKey([KVDEX_KEY_PREFIX], "i_users"); assert(keyEq(baseKey, prefix)); @@ -55,8 +55,8 @@ Deno.test("indexable_collection - properties", async (t) => { }, }); - const id1 = db.users1.一internal.idGenerator(mockUser1); - const id2 = db.users2.一internal.idGenerator(mockUser1); + const id1 = db.users1["idGenerator"](mockUser1); + const id2 = db.users2["idGenerator"](mockUser1); assert(typeof id1 === "number"); assert(id2 === mockUser1.username); diff --git a/tests/serialized_collection/enqueue.test.ts b/tests/serialized_collection/enqueue.test.ts index 7d1f9e9..34a7f88 100644 --- a/tests/serialized_collection/enqueue.test.ts +++ b/tests/serialized_collection/enqueue.test.ts @@ -24,10 +24,7 @@ Deno.test("serialized_collection - enqueue", async (t) => { }); const sleeper = createResolver(); - const handlerId = createHandlerId( - db.s_users.一internal.keys.base, - undefined, - ); + const handlerId = createHandlerId(db.s_users["keys"].base, undefined); let assertion = false; const listener = kv.listenQueue((msg) => { diff --git a/tests/serialized_collection/listenQueue.test.ts b/tests/serialized_collection/listenQueue.test.ts index 3cc56d0..2707ceb 100644 --- a/tests/serialized_collection/listenQueue.test.ts +++ b/tests/serialized_collection/listenQueue.test.ts @@ -33,10 +33,7 @@ Deno.test("serialized_collection - listenQueue", async (t) => { sleeper.resolve(); }); - const handlerId = createHandlerId( - db.s_users.一internal.keys.base, - undefined, - ); + const handlerId = createHandlerId(db.s_users["keys"].base, undefined); const msg: QueueMessage = { __is_undefined__: false, diff --git a/tests/serialized_collection/properties.test.ts b/tests/serialized_collection/properties.test.ts index df4ca01..cf7434f 100644 --- a/tests/serialized_collection/properties.test.ts +++ b/tests/serialized_collection/properties.test.ts @@ -16,9 +16,9 @@ import { jsonEncoder } from "../../src/ext/encoding/mod.ts"; Deno.test("serialized_collection - properties", async (t) => { await t.step("Keys should have the correct prefixes", async () => { await useDb((db) => { - const baseKey = db.s_users.一internal.keys.base; - const idKey = db.s_users.一internal.keys.id; - const segmentKey = db.s_users.一internal.keys.segment; + const baseKey = db.s_users["keys"].base; + const idKey = db.s_users["keys"].id; + const segmentKey = db.s_users["keys"].segment; const prefix = extendKey([KVDEX_KEY_PREFIX], "s_users"); assert(keyEq(baseKey, prefix)); @@ -43,8 +43,8 @@ Deno.test("serialized_collection - properties", async (t) => { }, }); - const id1 = db.users1.一internal.idGenerator(mockUser1); - const id2 = db.users2.一internal.idGenerator(mockUser1); + const id1 = db.users1["idGenerator"](mockUser1); + const id2 = db.users2["idGenerator"](mockUser1); assert(typeof id1 === "number"); assert(id2 === mockUser1.username); diff --git a/tests/serialized_indexable_collection/enqueue.test.ts b/tests/serialized_indexable_collection/enqueue.test.ts index a018b54..5c89c8e 100644 --- a/tests/serialized_indexable_collection/enqueue.test.ts +++ b/tests/serialized_indexable_collection/enqueue.test.ts @@ -27,10 +27,7 @@ Deno.test("serialized_indexable_collection - enqueue", async (t) => { }, }); - const handlerId = createHandlerId( - db.is_users.一internal.keys.base, - undefined, - ); + const handlerId = createHandlerId(db.is_users["keys"].base, undefined); let assertion = false; diff --git a/tests/serialized_indexable_collection/listenQueue.test.ts b/tests/serialized_indexable_collection/listenQueue.test.ts index 2e05913..def6173 100644 --- a/tests/serialized_indexable_collection/listenQueue.test.ts +++ b/tests/serialized_indexable_collection/listenQueue.test.ts @@ -32,10 +32,7 @@ Deno.test("serialized_indexable_collection - listenQueue", async (t) => { }, }); - const handlerId = createHandlerId( - db.is_users.一internal.keys.base, - undefined, - ); + const handlerId = createHandlerId(db.is_users["keys"].base, undefined); let assertion = false; diff --git a/tests/serialized_indexable_collection/properties.test.ts b/tests/serialized_indexable_collection/properties.test.ts index 2cf3793..9c85321 100644 --- a/tests/serialized_indexable_collection/properties.test.ts +++ b/tests/serialized_indexable_collection/properties.test.ts @@ -26,10 +26,10 @@ const [user] = generateLargeUsers(1); Deno.test("serialized_indexable_collection - properties", async (t) => { await t.step("Keys should have the correct prefixes", async () => { await useDb((db) => { - const baseKey = db.is_users.一internal.keys.base; - const idKey = db.is_users.一internal.keys.id; - const primaryIndexKey = db.is_users.一internal.keys.primaryIndex; - const secondaryIndexKey = db.is_users.一internal.keys.secondaryIndex; + const baseKey = db.is_users["keys"].base; + const idKey = db.is_users["keys"].id; + const primaryIndexKey = db.is_users["keys"].primaryIndex; + const secondaryIndexKey = db.is_users["keys"].secondaryIndex; const prefix = extendKey([KVDEX_KEY_PREFIX], "is_users"); assert(keyEq(baseKey, prefix)); @@ -61,8 +61,8 @@ Deno.test("serialized_indexable_collection - properties", async (t) => { }, }); - const id1 = db.users1.一internal.idGenerator(user); - const id2 = db.users2.一internal.idGenerator(user); + const id1 = db.users1["idGenerator"](user); + const id2 = db.users2["idGenerator"](user); assert(typeof id1 === "number"); assert(id2 === user.username);