diff --git a/nats-base-client/kv.ts b/nats-base-client/kv.ts index 65f5740e..2782a7f9 100644 --- a/nats-base-client/kv.ts +++ b/nats-base-client/kv.ts @@ -460,8 +460,29 @@ export class Bucket implements KV, KvRemove { } as KvEntry; } - create(k: string, data: Uint8Array): Promise<number> { - return this.put(k, data, { previousSeq: 0 }); + async create(k: string, data: Uint8Array): Promise<number> { + let firstErr; + try { + const n = await this.put(k, data, { previousSeq: 0 }); + return Promise.resolve(n); + } catch (err) { + firstErr = err; + if (err?.api_error?.err_code !== 10071) { + return Promise.reject(err); + } + } + let rev = 0; + try { + const e = await this.get(k); + if (e?.operation === "DEL" || e?.operation === "PURGE") { + rev = e !== null ? e.revision : 0; + return this.update(k, data, rev); + } else { + return Promise.reject(firstErr); + } + } catch (err) { + return Promise.reject(err); + } } update(k: string, data: Uint8Array, version: number): Promise<number> { diff --git a/nats-base-client/types.ts b/nats-base-client/types.ts index 8e1c5e56..d2361249 100644 --- a/nats-base-client/types.ts +++ b/nats-base-client/types.ts @@ -2787,7 +2787,8 @@ export interface RoKV { export interface KV extends RoKV { /** - * Creates a new entry ensuring that the entry does not exist. + * Creates a new entry ensuring that the entry does not exist (or + * the current version is deleted or the key is purged) * If the entry already exists, this operation fails. * @param k * @param data diff --git a/tests/kv_test.ts b/tests/kv_test.ts index 083d4c12..32f63511 100644 --- a/tests/kv_test.ts +++ b/tests/kv_test.ts @@ -1681,3 +1681,20 @@ Deno.test("kv - mirror cross domain", async () => { await cleanup(lns, lnc); }); + +Deno.test("kv - create after delete", async () => { + const { ns, nc } = await setup(jetstreamServerConf({}, true)); + + const js = nc.jetstream(); + const kv = await js.views.kv("K"); + await kv.create("a", Empty); + + await assertRejects(async () => { + await kv.create("a", Empty); + }); + await kv.delete("a"); + await kv.create("a", Empty); + await kv.purge("a"); + await kv.create("a", Empty); + await cleanup(ns, nc); +});