@grammyjs/conversations
Version:
Conversational interfaces for grammY
111 lines (110 loc) • 3.79 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.PLUGIN_DATA_VERSION = void 0;
exports.pinVersion = pinVersion;
exports.uniformStorage = uniformStorage;
/** Current data version of this plugin */
exports.PLUGIN_DATA_VERSION = 0;
/**
* Takes a version number and state management functions that are pinned to this
* version.
*
* The two functions it returns are `versionify` and `unpack`. The former can be
* used to add a version to some data. The latter can be used to unpack the data
* again, validating the version on the fly.
*
* ```ts
* import { assert } from "jsr:@std/assert";
*
* const { versionify, unpack } = pinVersion(42);
*
* const data = { prop: "pizza" };
* const versioned = versionify(data);
* const unpacked = unpack(versioned);
* assert(data === unpacked);
* ```
*
* @param version the version to use for pinning
*/
function pinVersion(version) {
function versionify(state) {
return { version: [exports.PLUGIN_DATA_VERSION, version], state };
}
function unpack(data) {
if (data === undefined)
return undefined;
if (!Array.isArray(data.version)) {
throw new Error("Unknown data format, cannot parse version");
}
const [pluginVersion, dataVersion] = data.version;
if (dataVersion !== version)
return undefined;
if (pluginVersion !== exports.PLUGIN_DATA_VERSION) {
// In the future, we might want to migrate the data from an old
// plugin version to a new one here.
return undefined;
}
return data.state;
}
return { versionify, unpack };
}
function defaultStorageKey(ctx) {
var _a;
return (_a = ctx.chatId) === null || _a === void 0 ? void 0 : _a.toString();
}
function defaultStorage() {
const store = new Map();
return {
type: "key",
adapter: {
read: (key) => store.get(key),
write: (key, state) => void store.set(key, state),
delete: (key) => void store.delete(key),
},
};
}
/**
* Coerces different storages to a single uniform abstraction.
*
* This function takes a {@link ConversationStorage} object and unifies its
* union members behind a common abstraction that simply exposes a read, write,
* and delete method for a given context object.
*
* @param storage An object defining how to store data
*/
function uniformStorage(storage) {
var _a;
storage !== null && storage !== void 0 ? storage : (storage = defaultStorage());
if (storage.type === undefined) {
return uniformStorage({ type: "key", adapter: storage });
}
const version = (_a = storage.version) !== null && _a !== void 0 ? _a : 0;
const { versionify, unpack } = pinVersion(version);
if (storage.type === "key") {
const { getStorageKey = defaultStorageKey, prefix = "", adapter } = storage;
return (ctx) => {
const key = prefix + getStorageKey(ctx);
return key === undefined
? {
read: () => undefined,
write: () => undefined,
delete: () => undefined,
}
: {
read: async () => unpack(await adapter.read(key)),
write: (state) => adapter.write(key, versionify(state)),
delete: () => adapter.delete(key),
};
};
}
else {
const { adapter } = storage;
return (ctx) => {
return {
read: async () => unpack(await adapter.read(ctx)),
write: (state) => adapter.write(ctx, versionify(state)),
delete: () => adapter.delete(ctx),
};
};
}
}