@deno/kv
Version:
A Deno KV client library optimized for Node.js.
161 lines (160 loc) • 7.57 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.openKv = exports.UnknownV8 = exports.makeLimitedV8Serializer = void 0;
// Copyright 2023 the Deno authors. All rights reserved. MIT license.
const dntShim = __importStar(require("./_dnt.shims.js"));
const check_js_1 = require("./check.js");
const in_memory_js_1 = require("./in_memory.js");
const napi_based_js_1 = require("./napi_based.js");
const native_js_1 = require("./native.js");
const remote_js_1 = require("./remote.js");
__exportStar(require("./napi_based.js"), exports);
__exportStar(require("./remote.js"), exports);
__exportStar(require("./in_memory.js"), exports);
__exportStar(require("./kv_types.js"), exports);
var v8_js_1 = require("./v8.js");
Object.defineProperty(exports, "makeLimitedV8Serializer", { enumerable: true, get: function () { return v8_js_1.makeLimitedV8Serializer; } });
Object.defineProperty(exports, "UnknownV8", { enumerable: true, get: function () { return v8_js_1.UnknownV8; } });
/**
* Open a new {@linkcode Kv} connection to persist data.
*
* When an url is provided, this will connect to a remote [Deno Deploy](https://deno.com/deploy) database
* or any other endpoint that supports the open [KV Connect](https://github.com/denoland/denokv/blob/main/proto/kv-connect.md) protocol.
*
* When a local path is provided, this will use a sqlite database on disk. Read and write access to the file is required.
*
* When no path is provided, this will use an ephemeral in-memory implementation.
*/
async function openKv(path, opts = {}) {
(0, check_js_1.checkOptionalString)("path", path);
(0, check_js_1.checkRecord)("opts", opts);
(0, check_js_1.checkOptionalBoolean)("opts.debug", opts.debug);
(0, check_js_1.check)("opts.implementation", opts.implementation, opts.implementation === undefined ||
["in-memory", "sqlite", "remote"].includes(opts.implementation));
const { debug, implementation } = opts;
// use built-in native implementation if available when running on Deno
if ("Deno" in dntShim.dntGlobalThis && !implementation) {
// deno-lint-ignore no-explicit-any
const { openKv } = dntShim.dntGlobalThis.Deno;
if (typeof openKv === "function")
return (0, native_js_1.makeNativeService)().openKv(path);
}
// use in-memory implementation if no path provided
if (path === undefined || path === "" || implementation === "in-memory") {
const maxQueueAttempts = typeof opts.maxQueueAttempts === "number"
? opts.maxQueueAttempts
: undefined;
return await (0, in_memory_js_1.makeInMemoryService)({ debug, maxQueueAttempts }).openKv(path);
}
const { encodeV8, decodeV8 } = await (async () => {
const { encodeV8, decodeV8 } = opts;
const defined = [encodeV8, decodeV8].filter((v) => v !== undefined).length;
if (defined === 1) {
throw new Error(`Provide both 'encodeV8' or 'decodeV8', or neither`);
}
if (defined > 0) {
if (typeof encodeV8 !== "function") {
throw new Error(`Unexpected 'encodeV8': ${encodeV8}`);
}
if (typeof decodeV8 !== "function") {
throw new Error(`Unexpected 'decodeV8': ${decodeV8}`);
}
return { encodeV8: encodeV8, decodeV8: decodeV8 };
}
if ("Bun" in dntShim.dntGlobalThis) {
throw new Error(`Bun provides v8.serialize/deserialize, but it uses an incompatible format (JavaScriptCore). Provide explicit 'encodeV8' and 'decodeV8' functions via options. See https://www.npmjs.com/package/@deno/kv#other-runtimes`); // https://discord.com/channels/876711213126520882/888937948345684008/1150135641137487892
}
const v8 = await Promise.resolve(`${`${"v8"}`}`).then(s => __importStar(require(s)));
if (!v8)
throw new Error(`Unable to import the v8 module`);
const { serialize, deserialize } = v8;
if (typeof serialize !== "function") {
throw new Error(`Unexpected 'serialize': ${serialize}`);
}
if (typeof deserialize !== "function") {
throw new Error(`Unexpected 'deserialize': ${deserialize}`);
}
return {
encodeV8: serialize,
decodeV8: deserialize,
};
})();
// use remote implementation if path looks like a url
if (/^https?:\/\//i.test(path) || implementation === "remote") {
let accessToken = typeof opts.accessToken === "string" && opts.accessToken !== ""
? opts.accessToken
: undefined;
if (accessToken === undefined) {
// deno-lint-ignore no-explicit-any
accessToken = dntShim.dntGlobalThis?.process?.env?.DENO_KV_ACCESS_TOKEN;
if (typeof accessToken !== "string") {
throw new Error(`Set the DENO_KV_ACCESS_TOKEN to your access token`);
}
}
const fetcher = typeof opts.fetcher === "function"
? opts.fetcher
: undefined;
const maxRetries = typeof opts.maxRetries === "number"
? opts.maxRetries
: undefined;
const wrapUnknownValues = typeof opts.wrapUnknownValues === "boolean"
? opts.wrapUnknownValues
: undefined;
const supportedVersions = Array.isArray(opts.supportedVersions) &&
opts.supportedVersions.every((v) => typeof v === "number")
? opts.supportedVersions
: undefined;
return await (0, remote_js_1.makeRemoteService)({
debug,
accessToken,
encodeV8,
decodeV8,
fetcher,
maxRetries,
supportedVersions,
wrapUnknownValues,
}).openKv(path);
}
// else use the sqlite napi implementation
const { napi } = opts;
if (napi !== undefined && !(0, napi_based_js_1.isNapiInterface)(napi)) {
throw new Error(`Unexpected napi interface for sqlite`);
}
const inMemory = typeof opts.inMemory === "boolean"
? opts.inMemory
: undefined;
return await (0, napi_based_js_1.makeNapiBasedService)({
debug,
encodeV8,
decodeV8,
napi,
inMemory,
}).openKv(path);
}
exports.openKv = openKv;