mirror of
https://github.com/denoland/deno.git
synced 2024-11-25 15:29:32 -05:00
fix(dts): improve types for the Deno.KV API (#18510)
This commit is contained in:
parent
e888c3f534
commit
02e01b171f
3 changed files with 91 additions and 33 deletions
|
@ -6,6 +6,7 @@ import {
|
||||||
assertRejects,
|
assertRejects,
|
||||||
assertThrows,
|
assertThrows,
|
||||||
} from "./test_util.ts";
|
} from "./test_util.ts";
|
||||||
|
import { assertType, IsExact } from "../../../test_util/std/testing/types.ts";
|
||||||
|
|
||||||
let isCI: boolean;
|
let isCI: boolean;
|
||||||
try {
|
try {
|
||||||
|
@ -529,8 +530,10 @@ Deno.test("KvU64 unbox", () => {
|
||||||
assertEquals(a.value, 1n);
|
assertEquals(a.value, 1n);
|
||||||
});
|
});
|
||||||
|
|
||||||
async function collect(iter: Deno.KvListIterator): Promise<Deno.KvEntry[]> {
|
async function collect<T>(
|
||||||
const entries: Deno.KvEntry[] = [];
|
iter: Deno.KvListIterator<T>,
|
||||||
|
): Promise<Deno.KvEntry<T>[]> {
|
||||||
|
const entries: Deno.KvEntry<T>[] = [];
|
||||||
for await (const entry of iter) {
|
for await (const entry of iter) {
|
||||||
entries.push(entry);
|
entries.push(entry);
|
||||||
}
|
}
|
||||||
|
@ -1134,3 +1137,46 @@ dbTest("operation size limit", async (db) => {
|
||||||
"too many mutations (max 10)",
|
"too many mutations (max 10)",
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// This function is never called, it is just used to check that all the types
|
||||||
|
// are behaving as expected.
|
||||||
|
async function _typeCheckingTests() {
|
||||||
|
const kv = new Deno.Kv();
|
||||||
|
|
||||||
|
const a = await kv.get(["a"]);
|
||||||
|
assertType<IsExact<typeof a, Deno.KvEntryMaybe<unknown>>>(true);
|
||||||
|
|
||||||
|
const b = await kv.get<string>(["b"]);
|
||||||
|
assertType<IsExact<typeof b, Deno.KvEntryMaybe<string>>>(true);
|
||||||
|
|
||||||
|
const c = await kv.getMany([["a"], ["b"]]);
|
||||||
|
assertType<
|
||||||
|
IsExact<typeof c, [Deno.KvEntryMaybe<unknown>, Deno.KvEntryMaybe<unknown>]>
|
||||||
|
>(true);
|
||||||
|
|
||||||
|
const d = await kv.getMany([["a"], ["b"]] as const);
|
||||||
|
assertType<
|
||||||
|
IsExact<typeof d, [Deno.KvEntryMaybe<unknown>, Deno.KvEntryMaybe<unknown>]>
|
||||||
|
>(true);
|
||||||
|
|
||||||
|
const e = await kv.getMany<[string, number]>([["a"], ["b"]]);
|
||||||
|
assertType<
|
||||||
|
IsExact<typeof e, [Deno.KvEntryMaybe<string>, Deno.KvEntryMaybe<number>]>
|
||||||
|
>(true);
|
||||||
|
|
||||||
|
const keys: Deno.KvKey[] = [["a"], ["b"]];
|
||||||
|
const f = await kv.getMany(keys);
|
||||||
|
assertType<IsExact<typeof f, Deno.KvEntryMaybe<unknown>[]>>(true);
|
||||||
|
|
||||||
|
const g = kv.list({ prefix: ["a"] });
|
||||||
|
assertType<IsExact<typeof g, Deno.KvListIterator<unknown>>>(true);
|
||||||
|
const h = await g.next();
|
||||||
|
assert(!h.done);
|
||||||
|
assertType<IsExact<typeof h.value, Deno.KvEntry<unknown>>>(true);
|
||||||
|
|
||||||
|
const i = kv.list<string>({ prefix: ["a"] });
|
||||||
|
assertType<IsExact<typeof i, Deno.KvListIterator<string>>>(true);
|
||||||
|
const j = await i.next();
|
||||||
|
assert(!j.done);
|
||||||
|
assertType<IsExact<typeof j.value, Deno.KvEntry<string>>>(true);
|
||||||
|
}
|
||||||
|
|
56
cli/tsc/dts/lib.deno.unstable.d.ts
vendored
56
cli/tsc/dts/lib.deno.unstable.d.ts
vendored
|
@ -1661,7 +1661,7 @@ declare namespace Deno {
|
||||||
*
|
*
|
||||||
* @category KV
|
* @category KV
|
||||||
*/
|
*/
|
||||||
export class KvListIterator implements AsyncIterableIterator<KvEntry> {
|
export class KvListIterator<T> implements AsyncIterableIterator<KvEntry<T>> {
|
||||||
/**
|
/**
|
||||||
* Returns the cursor of the current position in the iteration. This cursor
|
* Returns the cursor of the current position in the iteration. This cursor
|
||||||
* can be used to resume the iteration from the current position in the
|
* can be used to resume the iteration from the current position in the
|
||||||
|
@ -1669,8 +1669,8 @@ declare namespace Deno {
|
||||||
*/
|
*/
|
||||||
get cursor(): string;
|
get cursor(): string;
|
||||||
|
|
||||||
next(): Promise<IteratorResult<KvEntry, any>>;
|
next(): Promise<IteratorResult<KvEntry<T>, undefined>>;
|
||||||
[Symbol.asyncIterator](): AsyncIterableIterator<KvEntry>;
|
[Symbol.asyncIterator](): AsyncIterableIterator<KvEntry<T>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** **UNSTABLE**: New API, yet to be vetted.
|
/** **UNSTABLE**: New API, yet to be vetted.
|
||||||
|
@ -1680,16 +1680,26 @@ declare namespace Deno {
|
||||||
* The `versionstamp` is a string that represents the current version of the
|
* The `versionstamp` is a string that represents the current version of the
|
||||||
* key-value pair. It can be used to perform atomic operations on the KV store
|
* key-value pair. It can be used to perform atomic operations on the KV store
|
||||||
* by passing it to the `check` method of a {@linkcode Deno.AtomicOperation}.
|
* by passing it to the `check` method of a {@linkcode Deno.AtomicOperation}.
|
||||||
* A `null` versionstamp indicates that no value exists for the given key in
|
|
||||||
* the KV store.
|
|
||||||
*
|
*
|
||||||
* @category KV
|
* @category KV
|
||||||
*/
|
*/
|
||||||
export interface KvEntry {
|
export type KvEntry<T> = { key: KvKey; value: T; versionstamp: string };
|
||||||
|
|
||||||
|
/**
|
||||||
|
* **UNSTABLE**: New API, yet to be vetted.
|
||||||
|
*
|
||||||
|
* An optional versioned pair of key and value in a {@linkcode Deno.Kv}.
|
||||||
|
*
|
||||||
|
* This is the same as a {@linkcode KvEntry}, but the `value` and `versionstamp`
|
||||||
|
* fields may be `null` if no value exists for the given key in the KV store.
|
||||||
|
*
|
||||||
|
* @category KV
|
||||||
|
*/
|
||||||
|
export type KvEntryMaybe<T> = KvEntry<T> | {
|
||||||
key: KvKey;
|
key: KvKey;
|
||||||
value: unknown;
|
value: null;
|
||||||
versionstamp: string | null;
|
versionstamp: null;
|
||||||
}
|
};
|
||||||
|
|
||||||
/** **UNSTABLE**: New API, yet to be vetted.
|
/** **UNSTABLE**: New API, yet to be vetted.
|
||||||
*
|
*
|
||||||
|
@ -1881,8 +1891,8 @@ declare namespace Deno {
|
||||||
export class Kv {
|
export class Kv {
|
||||||
/**
|
/**
|
||||||
* Retrieve the value and versionstamp for the given key from the database
|
* Retrieve the value and versionstamp for the given key from the database
|
||||||
* in the form of a {@linkcode Deno.KvEntry}. If no value exists for the key,
|
* in the form of a {@linkcode Deno.KvEntryMaybe}. If no value exists for
|
||||||
* the returned entry will have a `null` value and versionstamp.
|
* the key, the returned entry will have a `null` value and versionstamp.
|
||||||
*
|
*
|
||||||
* ```ts
|
* ```ts
|
||||||
* const db = await Deno.openKv();
|
* const db = await Deno.openKv();
|
||||||
|
@ -1898,17 +1908,17 @@ declare namespace Deno {
|
||||||
* information on consistency levels, see the documentation for
|
* information on consistency levels, see the documentation for
|
||||||
* {@linkcode Deno.KvConsistencyLevel}.
|
* {@linkcode Deno.KvConsistencyLevel}.
|
||||||
*/
|
*/
|
||||||
get(
|
get<T = unknown>(
|
||||||
key: KvKey,
|
key: KvKey,
|
||||||
options?: { consistency?: KvConsistencyLevel },
|
options?: { consistency?: KvConsistencyLevel },
|
||||||
): Promise<KvEntry>;
|
): Promise<KvEntryMaybe<T>>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve multiple values and versionstamps from the database in the form
|
* Retrieve multiple values and versionstamps from the database in the form
|
||||||
* of an array of {@linkcode Deno.KvEntry} objects. The returned array will
|
* of an array of {@linkcode Deno.KvEntryMaybe} objects. The returned array
|
||||||
* have the same length as the `keys` array, and the entries will be in the
|
* will have the same length as the `keys` array, and the entries will be in
|
||||||
* same order as the keys. If no value exists for a given key, the returned
|
* the same order as the keys. If no value exists for a given key, the
|
||||||
* entry will have a `null` value and versionstamp.
|
* returned entry will have a `null` value and versionstamp.
|
||||||
*
|
*
|
||||||
* ```ts
|
* ```ts
|
||||||
* const db = await Deno.openKv();
|
* const db = await Deno.openKv();
|
||||||
|
@ -1927,11 +1937,10 @@ declare namespace Deno {
|
||||||
* information on consistency levels, see the documentation for
|
* information on consistency levels, see the documentation for
|
||||||
* {@linkcode Deno.KvConsistencyLevel}.
|
* {@linkcode Deno.KvConsistencyLevel}.
|
||||||
*/
|
*/
|
||||||
getMany(
|
getMany<T extends readonly unknown[]>(
|
||||||
keys: KvKey[],
|
keys: readonly [...{ [K in keyof T]: KvKey }],
|
||||||
options?: { consistency?: KvConsistencyLevel },
|
options?: { consistency?: KvConsistencyLevel },
|
||||||
): Promise<KvEntry[]>;
|
): Promise<{ [K in keyof T]: KvEntryMaybe<T[K]> }>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the value for the given key in the database. If a value already
|
* Set the value for the given key in the database. If a value already
|
||||||
* exists for the key, it will be overwritten.
|
* exists for the key, it will be overwritten.
|
||||||
|
@ -1993,7 +2002,10 @@ declare namespace Deno {
|
||||||
* list operation. See the documentation for {@linkcode Deno.KvListOptions}
|
* list operation. See the documentation for {@linkcode Deno.KvListOptions}
|
||||||
* for more information.
|
* for more information.
|
||||||
*/
|
*/
|
||||||
list(selector: KvListSelector, options?: KvListOptions): KvListIterator;
|
list<T = unknown>(
|
||||||
|
selector: KvListSelector,
|
||||||
|
options?: KvListOptions,
|
||||||
|
): KvListIterator<T>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new {@linkcode Deno.AtomicOperation} object which can be used to
|
* Create a new {@linkcode Deno.AtomicOperation} object which can be used to
|
||||||
|
|
|
@ -75,7 +75,7 @@ class Kv {
|
||||||
async getMany(
|
async getMany(
|
||||||
keys: Deno.KvKey[],
|
keys: Deno.KvKey[],
|
||||||
opts?: { consistency?: Deno.KvConsistencyLevel },
|
opts?: { consistency?: Deno.KvConsistencyLevel },
|
||||||
): Promise<Deno.KvEntry[]> {
|
): Promise<Deno.KvEntry<unknown>[]> {
|
||||||
keys = keys.map(convertKey);
|
keys = keys.map(convertKey);
|
||||||
const ranges: RawKvEntry[][] = await core.opAsync(
|
const ranges: RawKvEntry[][] = await core.opAsync(
|
||||||
"op_kv_snapshot_read",
|
"op_kv_snapshot_read",
|
||||||
|
@ -174,7 +174,7 @@ class Kv {
|
||||||
cursor: string | undefined,
|
cursor: string | undefined,
|
||||||
reverse: boolean,
|
reverse: boolean,
|
||||||
consistency: Deno.KvConsistencyLevel,
|
consistency: Deno.KvConsistencyLevel,
|
||||||
) => Promise<Deno.KvEntry[]> {
|
) => Promise<Deno.KvEntry<unknown>[]> {
|
||||||
return async (selector, cursor, reverse, consistency) => {
|
return async (selector, cursor, reverse, consistency) => {
|
||||||
const [entries]: [RawKvEntry[]] = await core.opAsync(
|
const [entries]: [RawKvEntry[]] = await core.opAsync(
|
||||||
"op_kv_snapshot_read",
|
"op_kv_snapshot_read",
|
||||||
|
@ -304,7 +304,7 @@ function convertKey(key: Deno.KvKey | Deno.KvKeyPart): Deno.KvKey {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function deserializeValue(entry: RawKvEntry): Deno.KvEntry {
|
function deserializeValue(entry: RawKvEntry): Deno.KvEntry<unknown> {
|
||||||
const { kind, value } = entry.value;
|
const { kind, value } = entry.value;
|
||||||
switch (kind) {
|
switch (kind) {
|
||||||
case "v8":
|
case "v8":
|
||||||
|
@ -357,9 +357,9 @@ const AsyncIteratorPrototype = ObjectGetPrototypeOf(AsyncGeneratorPrototype);
|
||||||
const AsyncIterator = AsyncIteratorPrototype.constructor;
|
const AsyncIterator = AsyncIteratorPrototype.constructor;
|
||||||
|
|
||||||
class KvListIterator extends AsyncIterator
|
class KvListIterator extends AsyncIterator
|
||||||
implements AsyncIterator<Deno.KvEntry> {
|
implements AsyncIterator<Deno.KvEntry<unknown>> {
|
||||||
#selector: Deno.KvListSelector;
|
#selector: Deno.KvListSelector;
|
||||||
#entries: Deno.KvEntry[] | null = null;
|
#entries: Deno.KvEntry<unknown>[] | null = null;
|
||||||
#cursorGen: (() => string) | null = null;
|
#cursorGen: (() => string) | null = null;
|
||||||
#done = false;
|
#done = false;
|
||||||
#lastBatch = false;
|
#lastBatch = false;
|
||||||
|
@ -368,7 +368,7 @@ class KvListIterator extends AsyncIterator
|
||||||
cursor: string | undefined,
|
cursor: string | undefined,
|
||||||
reverse: boolean,
|
reverse: boolean,
|
||||||
consistency: Deno.KvConsistencyLevel,
|
consistency: Deno.KvConsistencyLevel,
|
||||||
) => Promise<Deno.KvEntry[]>;
|
) => Promise<Deno.KvEntry<unknown>[]>;
|
||||||
#limit: number | undefined;
|
#limit: number | undefined;
|
||||||
#count = 0;
|
#count = 0;
|
||||||
#reverse: boolean;
|
#reverse: boolean;
|
||||||
|
@ -388,7 +388,7 @@ class KvListIterator extends AsyncIterator
|
||||||
cursor: string | undefined,
|
cursor: string | undefined,
|
||||||
reverse: boolean,
|
reverse: boolean,
|
||||||
consistency: Deno.KvConsistencyLevel,
|
consistency: Deno.KvConsistencyLevel,
|
||||||
) => Promise<Deno.KvEntry[]>;
|
) => Promise<Deno.KvEntry<unknown>[]>;
|
||||||
},
|
},
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
|
@ -443,7 +443,7 @@ class KvListIterator extends AsyncIterator
|
||||||
return this.#cursorGen();
|
return this.#cursorGen();
|
||||||
}
|
}
|
||||||
|
|
||||||
async next(): Promise<IteratorResult<Deno.KvEntry>> {
|
async next(): Promise<IteratorResult<Deno.KvEntry<unknown>>> {
|
||||||
// Fused or limit exceeded
|
// Fused or limit exceeded
|
||||||
if (
|
if (
|
||||||
this.#done ||
|
this.#done ||
|
||||||
|
@ -493,7 +493,7 @@ class KvListIterator extends AsyncIterator
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
[Symbol.asyncIterator](): AsyncIterator<Deno.KvEntry> {
|
[Symbol.asyncIterator](): AsyncIterator<Deno.KvEntry<unknown>> {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue