@fedify/mysql 2.1.0-dev.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ MIT License
2
+
3
+ Copyright 2024–2026 Hong Minhee
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
6
+ this software and associated documentation files (the "Software"), to deal in
7
+ the Software without restriction, including without limitation the rights to
8
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9
+ the Software, and to permit persons to whom the Software is furnished to do so,
10
+ subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,48 @@
1
+ <!-- deno-fmt-ignore-file -->
2
+
3
+ @fedify/mysql: MySQL/MariaDB drivers for Fedify
4
+ ===============================================
5
+
6
+ [![JSR][JSR badge]][JSR]
7
+ [![npm][npm badge]][npm]
8
+
9
+ This package provides [Fedify]'s [`KvStore`] and [`MessageQueue`]
10
+ implementations for MySQL/MariaDB:
11
+
12
+ - [`MysqlKvStore`]
13
+ - [`MysqlMessageQueue`]
14
+
15
+ ~~~~ typescript
16
+ import { createFederation } from "@fedify/fedify";
17
+ import { MysqlKvStore, MysqlMessageQueue } from "@fedify/mysql";
18
+ import mysql from "mysql2/promise";
19
+
20
+ const pool = mysql.createPool("mysql://user:password@localhost/dbname");
21
+
22
+ const federation = createFederation({
23
+ kv: new MysqlKvStore(pool),
24
+ queue: new MysqlMessageQueue(pool),
25
+ });
26
+ ~~~~
27
+
28
+ [JSR badge]: https://jsr.io/badges/@fedify/mysql
29
+ [JSR]: https://jsr.io/@fedify/mysql
30
+ [npm badge]: https://img.shields.io/npm/v/@fedify/mysql?logo=npm
31
+ [npm]: https://www.npmjs.com/package/@fedify/mysql
32
+ [Fedify]: https://fedify.dev/
33
+ [`KvStore`]: https://jsr.io/@fedify/fedify/doc/federation/~/KvStore
34
+ [`MessageQueue`]: https://jsr.io/@fedify/fedify/doc/federation/~/MessageQueue
35
+ [`MysqlKvStore`]: https://jsr.io/@fedify/mysql/doc/~/MysqlKvStore
36
+ [`MysqlMessageQueue`]: https://jsr.io/@fedify/mysql/doc/mq/~/MysqlMessageQueue
37
+
38
+
39
+ Installation
40
+ ------------
41
+
42
+ ~~~~ sh
43
+ deno add jsr:@fedify/mysql # Deno
44
+ npm add @fedify/mysql mysql2 # npm
45
+ pnpm add @fedify/mysql mysql2 # pnpm
46
+ yarn add @fedify/mysql mysql2 # Yarn
47
+ bun add @fedify/mysql mysql2 # Bun
48
+ ~~~~
@@ -0,0 +1,33 @@
1
+
2
+ const { Temporal } = require("@js-temporal/polyfill");
3
+
4
+ //#region rolldown:runtime
5
+ var __create = Object.create;
6
+ var __defProp = Object.defineProperty;
7
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
8
+ var __getOwnPropNames = Object.getOwnPropertyNames;
9
+ var __getProtoOf = Object.getPrototypeOf;
10
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
13
+ key = keys[i];
14
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
15
+ get: ((k) => from[k]).bind(null, key),
16
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
17
+ });
18
+ }
19
+ return to;
20
+ };
21
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
22
+ value: mod,
23
+ enumerable: true
24
+ }) : target, mod));
25
+
26
+ //#endregion
27
+
28
+ Object.defineProperty(exports, '__toESM', {
29
+ enumerable: true,
30
+ get: function () {
31
+ return __toESM;
32
+ }
33
+ });
package/dist/kv.cjs ADDED
@@ -0,0 +1,235 @@
1
+
2
+ const { Temporal } = require("@js-temporal/polyfill");
3
+
4
+ const require_rolldown_runtime = require('./_virtual/rolldown_runtime.cjs');
5
+ const es_toolkit = require_rolldown_runtime.__toESM(require("es-toolkit"));
6
+ const __logtape_logtape = require_rolldown_runtime.__toESM(require("@logtape/logtape"));
7
+
8
+ //#region src/kv.ts
9
+ const logger = (0, __logtape_logtape.getLogger)([
10
+ "fedify",
11
+ "mysql",
12
+ "kv"
13
+ ]);
14
+ /**
15
+ * A key-value store that uses MySQL (or MariaDB) as the underlying storage.
16
+ *
17
+ * @example
18
+ * ```ts
19
+ * import { createFederation } from "@fedify/fedify";
20
+ * import { MysqlKvStore } from "@fedify/mysql";
21
+ * import mysql from "mysql2/promise";
22
+ *
23
+ * const pool = mysql.createPool("mysql://user:pass@localhost/db");
24
+ *
25
+ * const federation = createFederation({
26
+ * // ...
27
+ * kv: new MysqlKvStore(pool),
28
+ * });
29
+ * ```
30
+ *
31
+ * @since 2.1.0
32
+ */
33
+ var MysqlKvStore = class {
34
+ #pool;
35
+ #tableName;
36
+ #expireCleanupRate;
37
+ #initialized;
38
+ /**
39
+ * Creates a new MySQL key-value store.
40
+ * @param pool The MySQL connection pool to use.
41
+ * @param options The options for the key-value store.
42
+ * @since 2.1.0
43
+ */
44
+ constructor(pool, options = {}) {
45
+ this.#pool = pool;
46
+ const tableName = options.tableName ?? "fedify_kv";
47
+ if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(tableName)) throw new RangeError(`Invalid table name: ${JSON.stringify(tableName)}. Table names must start with a letter or underscore and contain only letters, digits, and underscores.`);
48
+ if (tableName.length > 50) throw new RangeError(`Invalid table name: ${JSON.stringify(tableName)}. Table names must be at most 50 characters long (MySQL identifier limit is 64 chars; the derived index "idx_<name>_expires" uses 12 more).`);
49
+ this.#tableName = tableName;
50
+ const expireCleanupRate = options.expireCleanupRate ?? 1;
51
+ if (expireCleanupRate < 0 || expireCleanupRate > 1) throw new RangeError(`Invalid expireCleanupRate: ${expireCleanupRate}. Must be a number between 0 and 1 inclusive.`);
52
+ this.#expireCleanupRate = expireCleanupRate;
53
+ this.#initialized = options.initialized ?? false;
54
+ }
55
+ async #expire() {
56
+ if (this.#expireCleanupRate <= 0) return;
57
+ if (this.#expireCleanupRate < 1 && Math.random() >= this.#expireCleanupRate) return;
58
+ await this.#pool.query(`DELETE FROM \`${this.#tableName}\`
59
+ WHERE \`expires\` IS NOT NULL AND \`expires\` < NOW(6)`);
60
+ }
61
+ /**
62
+ * {@inheritDoc KvStore.get}
63
+ * @since 2.1.0
64
+ */
65
+ async get(key) {
66
+ await this.initialize();
67
+ const serializedKey = JSON.stringify([...key]);
68
+ const [rows] = await this.#pool.query(`SELECT \`value\` FROM \`${this.#tableName}\`
69
+ WHERE \`key\` = ?
70
+ AND (\`expires\` IS NULL OR \`expires\` > NOW(6))`, [serializedKey]);
71
+ if (rows.length < 1) return void 0;
72
+ return rows[0].value;
73
+ }
74
+ /**
75
+ * {@inheritDoc KvStore.set}
76
+ * @since 2.1.0
77
+ */
78
+ async set(key, value, options) {
79
+ if (value === void 0) return;
80
+ await this.initialize();
81
+ const serializedKey = JSON.stringify([...key]);
82
+ const jsonValue = JSON.stringify(value);
83
+ if (options?.ttl != null) {
84
+ const ttlSeconds = durationToSeconds(options.ttl);
85
+ await this.#pool.query(`INSERT INTO \`${this.#tableName}\` (\`key\`, \`value\`, \`expires\`)
86
+ VALUES (?, CAST(? AS JSON),
87
+ DATE_ADD(NOW(6), INTERVAL ? SECOND))
88
+ ON DUPLICATE KEY UPDATE
89
+ \`value\` = VALUES(\`value\`),
90
+ \`expires\` = VALUES(\`expires\`)`, [
91
+ serializedKey,
92
+ jsonValue,
93
+ ttlSeconds
94
+ ]);
95
+ } else await this.#pool.query(`INSERT INTO \`${this.#tableName}\` (\`key\`, \`value\`, \`expires\`)
96
+ VALUES (?, CAST(? AS JSON), NULL)
97
+ ON DUPLICATE KEY UPDATE
98
+ \`value\` = VALUES(\`value\`),
99
+ \`expires\` = NULL`, [serializedKey, jsonValue]);
100
+ await this.#expire();
101
+ }
102
+ /**
103
+ * {@inheritDoc KvStore.delete}
104
+ * @since 2.1.0
105
+ */
106
+ async delete(key) {
107
+ await this.initialize();
108
+ const serializedKey = JSON.stringify([...key]);
109
+ await this.#pool.query(`DELETE FROM \`${this.#tableName}\` WHERE \`key\` = ?`, [serializedKey]);
110
+ await this.#expire();
111
+ }
112
+ /**
113
+ * {@inheritDoc KvStore.cas}
114
+ * @since 2.1.0
115
+ */
116
+ async cas(key, expectedValue, newValue, options) {
117
+ await this.initialize();
118
+ const serializedKey = JSON.stringify([...key]);
119
+ let conn;
120
+ try {
121
+ conn = await this.#pool.getConnection();
122
+ await conn.beginTransaction();
123
+ const [rows] = await conn.query(`SELECT
124
+ \`value\`,
125
+ (\`expires\` IS NOT NULL AND \`expires\` <= NOW(6)) AS \`is_expired\`
126
+ FROM \`${this.#tableName}\`
127
+ WHERE \`key\` = ?
128
+ FOR UPDATE`, [serializedKey]);
129
+ const row = rows[0];
130
+ const currentValue = !row || row.is_expired ? void 0 : row.value;
131
+ if (!(0, es_toolkit.isEqual)(currentValue, expectedValue)) {
132
+ await conn.rollback();
133
+ return false;
134
+ }
135
+ if (newValue === void 0) await conn.query(`DELETE FROM \`${this.#tableName}\` WHERE \`key\` = ?`, [serializedKey]);
136
+ else {
137
+ const jsonValue = JSON.stringify(newValue);
138
+ if (options?.ttl != null) {
139
+ const ttlSeconds = durationToSeconds(options.ttl);
140
+ await conn.query(`INSERT INTO \`${this.#tableName}\`
141
+ (\`key\`, \`value\`, \`expires\`)
142
+ VALUES (?, CAST(? AS JSON),
143
+ DATE_ADD(NOW(6), INTERVAL ? SECOND))
144
+ ON DUPLICATE KEY UPDATE
145
+ \`value\` = VALUES(\`value\`),
146
+ \`expires\` = VALUES(\`expires\`)`, [
147
+ serializedKey,
148
+ jsonValue,
149
+ ttlSeconds
150
+ ]);
151
+ } else await conn.query(`INSERT INTO \`${this.#tableName}\`
152
+ (\`key\`, \`value\`, \`expires\`)
153
+ VALUES (?, CAST(? AS JSON), NULL)
154
+ ON DUPLICATE KEY UPDATE
155
+ \`value\` = VALUES(\`value\`),
156
+ \`expires\` = NULL`, [serializedKey, jsonValue]);
157
+ }
158
+ await conn.commit();
159
+ await this.#expire();
160
+ return true;
161
+ } catch (e) {
162
+ if (conn) await conn.rollback();
163
+ throw e;
164
+ } finally {
165
+ if (conn) conn.release();
166
+ }
167
+ }
168
+ /**
169
+ * {@inheritDoc KvStore.list}
170
+ * @since 2.1.0
171
+ */
172
+ async *list(prefix) {
173
+ await this.initialize();
174
+ let rows;
175
+ if (prefix == null || prefix.length === 0) [rows] = await this.#pool.query(`SELECT \`key\`, \`value\` FROM \`${this.#tableName}\`
176
+ WHERE \`expires\` IS NULL OR \`expires\` > NOW(6)
177
+ ORDER BY \`key\``);
178
+ else {
179
+ const serializedPrefix = JSON.stringify([...prefix]);
180
+ const likePrefix = serializedPrefix.slice(0, -1).replace(/[%_\\]/g, "\\$&") + ",%";
181
+ [rows] = await this.#pool.query(`SELECT \`key\`, \`value\` FROM \`${this.#tableName}\`
182
+ WHERE (\`key\` = ? OR \`key\` LIKE ? ESCAPE '\\\\')
183
+ AND (\`expires\` IS NULL OR \`expires\` > NOW(6))
184
+ ORDER BY \`key\``, [serializedPrefix, likePrefix]);
185
+ }
186
+ for (const row of rows) yield {
187
+ key: JSON.parse(row.key),
188
+ value: row.value
189
+ };
190
+ }
191
+ /**
192
+ * Creates the table used by the key-value store if it does not already exist.
193
+ * Does nothing if the table already exists.
194
+ *
195
+ * @since 2.1.0
196
+ */
197
+ async initialize() {
198
+ if (this.#initialized) return;
199
+ logger.debug("Initializing the key-value store table {tableName}...", { tableName: this.#tableName });
200
+ await this.#pool.query(`CREATE TABLE IF NOT EXISTS \`${this.#tableName}\` (
201
+ \`key\` VARCHAR(768) NOT NULL,
202
+ \`value\` JSON NOT NULL,
203
+ \`expires\` DATETIME(6) NULL DEFAULT NULL,
204
+ PRIMARY KEY (\`key\`)
205
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin`);
206
+ try {
207
+ await this.#pool.query(`CREATE INDEX \`idx_${this.#tableName}_expires\`
208
+ ON \`${this.#tableName}\` (\`expires\`)`);
209
+ } catch (e) {
210
+ if (e.code !== "ER_DUP_KEYNAME") throw e;
211
+ }
212
+ this.#initialized = true;
213
+ logger.debug("Initialized the key-value store table {tableName}.", { tableName: this.#tableName });
214
+ }
215
+ /**
216
+ * Drops the table used by the key-value store. Does nothing if the table
217
+ * does not exist. Resets the initialized flag so that
218
+ * {@link MysqlKvStore.initialize} can recreate the table on the next call.
219
+ *
220
+ * @since 2.1.0
221
+ */
222
+ async drop() {
223
+ await this.#pool.query(`DROP TABLE IF EXISTS \`${this.#tableName}\``);
224
+ this.#initialized = false;
225
+ }
226
+ };
227
+ function durationToSeconds(duration) {
228
+ return duration.total({
229
+ unit: "second",
230
+ relativeTo: Temporal.Now.plainDateTimeISO()
231
+ });
232
+ }
233
+
234
+ //#endregion
235
+ exports.MysqlKvStore = MysqlKvStore;
package/dist/kv.d.cts ADDED
@@ -0,0 +1,103 @@
1
+ import { KvKey, KvStore, KvStoreListEntry, KvStoreSetOptions } from "@fedify/fedify";
2
+ import { Pool } from "mysql2/promise";
3
+
4
+ //#region src/kv.d.ts
5
+ /**
6
+ * Options for the MySQL key-value store.
7
+ *
8
+ * @since 2.1.0
9
+ */
10
+ interface MysqlKvStoreOptions {
11
+ /**
12
+ * The table name to use for the key-value store.
13
+ * `"fedify_kv"` by default.
14
+ * @default `"fedify_kv"`
15
+ * @since 2.1.0
16
+ */
17
+ readonly tableName?: string;
18
+ /**
19
+ * Whether the table has been initialized. `false` by default.
20
+ * @default `false`
21
+ * @since 2.1.0
22
+ */
23
+ readonly initialized?: boolean;
24
+ /**
25
+ * The probability (between 0 and 1, inclusive) that expired entries are
26
+ * cleaned up on each mutation. Defaults to `1` (always clean up).
27
+ * Set to `0` to disable automatic expiry cleanup entirely.
28
+ * @default `1`
29
+ * @since 2.1.0
30
+ */
31
+ readonly expireCleanupRate?: number;
32
+ }
33
+ /**
34
+ * A key-value store that uses MySQL (or MariaDB) as the underlying storage.
35
+ *
36
+ * @example
37
+ * ```ts
38
+ * import { createFederation } from "@fedify/fedify";
39
+ * import { MysqlKvStore } from "@fedify/mysql";
40
+ * import mysql from "mysql2/promise";
41
+ *
42
+ * const pool = mysql.createPool("mysql://user:pass@localhost/db");
43
+ *
44
+ * const federation = createFederation({
45
+ * // ...
46
+ * kv: new MysqlKvStore(pool),
47
+ * });
48
+ * ```
49
+ *
50
+ * @since 2.1.0
51
+ */
52
+ declare class MysqlKvStore implements KvStore {
53
+ #private;
54
+ /**
55
+ * Creates a new MySQL key-value store.
56
+ * @param pool The MySQL connection pool to use.
57
+ * @param options The options for the key-value store.
58
+ * @since 2.1.0
59
+ */
60
+ constructor(pool: Pool, options?: MysqlKvStoreOptions);
61
+ /**
62
+ * {@inheritDoc KvStore.get}
63
+ * @since 2.1.0
64
+ */
65
+ get<T = unknown>(key: KvKey): Promise<T | undefined>;
66
+ /**
67
+ * {@inheritDoc KvStore.set}
68
+ * @since 2.1.0
69
+ */
70
+ set(key: KvKey, value: unknown, options?: KvStoreSetOptions | undefined): Promise<void>;
71
+ /**
72
+ * {@inheritDoc KvStore.delete}
73
+ * @since 2.1.0
74
+ */
75
+ delete(key: KvKey): Promise<void>;
76
+ /**
77
+ * {@inheritDoc KvStore.cas}
78
+ * @since 2.1.0
79
+ */
80
+ cas(key: KvKey, expectedValue: unknown, newValue: unknown, options?: KvStoreSetOptions): Promise<boolean>;
81
+ /**
82
+ * {@inheritDoc KvStore.list}
83
+ * @since 2.1.0
84
+ */
85
+ list(prefix?: KvKey): AsyncIterable<KvStoreListEntry>;
86
+ /**
87
+ * Creates the table used by the key-value store if it does not already exist.
88
+ * Does nothing if the table already exists.
89
+ *
90
+ * @since 2.1.0
91
+ */
92
+ initialize(): Promise<void>;
93
+ /**
94
+ * Drops the table used by the key-value store. Does nothing if the table
95
+ * does not exist. Resets the initialized flag so that
96
+ * {@link MysqlKvStore.initialize} can recreate the table on the next call.
97
+ *
98
+ * @since 2.1.0
99
+ */
100
+ drop(): Promise<void>;
101
+ }
102
+ //#endregion
103
+ export { MysqlKvStore, MysqlKvStoreOptions };
package/dist/kv.d.ts ADDED
@@ -0,0 +1,104 @@
1
+ import { Temporal } from "@js-temporal/polyfill";
2
+ import { KvKey, KvStore, KvStoreListEntry, KvStoreSetOptions } from "@fedify/fedify";
3
+ import { Pool } from "mysql2/promise";
4
+
5
+ //#region src/kv.d.ts
6
+ /**
7
+ * Options for the MySQL key-value store.
8
+ *
9
+ * @since 2.1.0
10
+ */
11
+ interface MysqlKvStoreOptions {
12
+ /**
13
+ * The table name to use for the key-value store.
14
+ * `"fedify_kv"` by default.
15
+ * @default `"fedify_kv"`
16
+ * @since 2.1.0
17
+ */
18
+ readonly tableName?: string;
19
+ /**
20
+ * Whether the table has been initialized. `false` by default.
21
+ * @default `false`
22
+ * @since 2.1.0
23
+ */
24
+ readonly initialized?: boolean;
25
+ /**
26
+ * The probability (between 0 and 1, inclusive) that expired entries are
27
+ * cleaned up on each mutation. Defaults to `1` (always clean up).
28
+ * Set to `0` to disable automatic expiry cleanup entirely.
29
+ * @default `1`
30
+ * @since 2.1.0
31
+ */
32
+ readonly expireCleanupRate?: number;
33
+ }
34
+ /**
35
+ * A key-value store that uses MySQL (or MariaDB) as the underlying storage.
36
+ *
37
+ * @example
38
+ * ```ts
39
+ * import { createFederation } from "@fedify/fedify";
40
+ * import { MysqlKvStore } from "@fedify/mysql";
41
+ * import mysql from "mysql2/promise";
42
+ *
43
+ * const pool = mysql.createPool("mysql://user:pass@localhost/db");
44
+ *
45
+ * const federation = createFederation({
46
+ * // ...
47
+ * kv: new MysqlKvStore(pool),
48
+ * });
49
+ * ```
50
+ *
51
+ * @since 2.1.0
52
+ */
53
+ declare class MysqlKvStore implements KvStore {
54
+ #private;
55
+ /**
56
+ * Creates a new MySQL key-value store.
57
+ * @param pool The MySQL connection pool to use.
58
+ * @param options The options for the key-value store.
59
+ * @since 2.1.0
60
+ */
61
+ constructor(pool: Pool, options?: MysqlKvStoreOptions);
62
+ /**
63
+ * {@inheritDoc KvStore.get}
64
+ * @since 2.1.0
65
+ */
66
+ get<T = unknown>(key: KvKey): Promise<T | undefined>;
67
+ /**
68
+ * {@inheritDoc KvStore.set}
69
+ * @since 2.1.0
70
+ */
71
+ set(key: KvKey, value: unknown, options?: KvStoreSetOptions | undefined): Promise<void>;
72
+ /**
73
+ * {@inheritDoc KvStore.delete}
74
+ * @since 2.1.0
75
+ */
76
+ delete(key: KvKey): Promise<void>;
77
+ /**
78
+ * {@inheritDoc KvStore.cas}
79
+ * @since 2.1.0
80
+ */
81
+ cas(key: KvKey, expectedValue: unknown, newValue: unknown, options?: KvStoreSetOptions): Promise<boolean>;
82
+ /**
83
+ * {@inheritDoc KvStore.list}
84
+ * @since 2.1.0
85
+ */
86
+ list(prefix?: KvKey): AsyncIterable<KvStoreListEntry>;
87
+ /**
88
+ * Creates the table used by the key-value store if it does not already exist.
89
+ * Does nothing if the table already exists.
90
+ *
91
+ * @since 2.1.0
92
+ */
93
+ initialize(): Promise<void>;
94
+ /**
95
+ * Drops the table used by the key-value store. Does nothing if the table
96
+ * does not exist. Resets the initialized flag so that
97
+ * {@link MysqlKvStore.initialize} can recreate the table on the next call.
98
+ *
99
+ * @since 2.1.0
100
+ */
101
+ drop(): Promise<void>;
102
+ }
103
+ //#endregion
104
+ export { MysqlKvStore, MysqlKvStoreOptions };