@fedify/postgres 0.3.0-dev.22 → 0.4.0-dev.30
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/.github/FUNDING.yaml +2 -0
- package/.github/workflows/main.yaml +100 -0
- package/.vscode/extensions.json +6 -0
- package/.vscode/settings.json +33 -0
- package/.zed/settings.json +30 -0
- package/README.md +5 -1
- package/deno.json +34 -0
- package/deno.json.tmp +34 -0
- package/deno.lock +767 -0
- package/mod.ts +1 -0
- package/package.json +31 -42
- package/src/kv.test.ts +137 -0
- package/src/kv.ts +146 -0
- package/src/mod.ts +2 -0
- package/src/mq.test.ts +114 -0
- package/src/mq.ts +261 -0
- package/src/utils.ts +7 -0
- package/tsdown.config.ts +12 -0
- package/esm/_dnt.shims.js +0 -64
- package/esm/mod.js +0 -1
- package/esm/package.json +0 -3
- package/esm/src/kv.js +0 -125
- package/esm/src/mod.js +0 -2
- package/esm/src/mq.js +0 -225
- package/esm/src/utils.js +0 -5
- package/script/_dnt.shims.js +0 -69
- package/script/mod.js +0 -17
- package/script/package.json +0 -3
- package/script/src/kv.js +0 -129
- package/script/src/mod.js +0 -18
- package/script/src/mq.js +0 -255
- package/script/src/utils.js +0 -8
- package/types/_dnt.shims.d.ts +0 -9
- package/types/_dnt.shims.d.ts.map +0 -1
- package/types/mod.d.ts +0 -2
- package/types/mod.d.ts.map +0 -1
- package/types/src/kv.d.ts +0 -56
- package/types/src/kv.d.ts.map +0 -1
- package/types/src/mod.d.ts +0 -3
- package/types/src/mod.d.ts.map +0 -1
- package/types/src/mq.d.ts +0 -63
- package/types/src/mq.d.ts.map +0 -1
- package/types/src/utils.d.ts +0 -3
- package/types/src/utils.d.ts.map +0 -1
package/esm/src/mq.js
DELETED
|
@@ -1,225 +0,0 @@
|
|
|
1
|
-
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
2
|
-
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
3
|
-
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
4
|
-
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
5
|
-
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
6
|
-
};
|
|
7
|
-
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
8
|
-
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
9
|
-
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
10
|
-
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
11
|
-
};
|
|
12
|
-
var _PostgresMessageQueue_instances, _PostgresMessageQueue_sql, _PostgresMessageQueue_tableName, _PostgresMessageQueue_channelName, _PostgresMessageQueue_pollIntervalMs, _PostgresMessageQueue_initialized, _PostgresMessageQueue_driverSerializesJson, _PostgresMessageQueue_json;
|
|
13
|
-
import * as dntShim from "../_dnt.shims.js";
|
|
14
|
-
import { getLogger } from "@logtape/logtape";
|
|
15
|
-
import postgres from "postgres";
|
|
16
|
-
import { driverSerializesJson } from "./utils.js";
|
|
17
|
-
const logger = getLogger(["fedify", "postgres", "mq"]);
|
|
18
|
-
/**
|
|
19
|
-
* A message queue that uses PostgreSQL as the underlying storage.
|
|
20
|
-
*
|
|
21
|
-
* @example
|
|
22
|
-
* ```ts
|
|
23
|
-
* import { createFederation } from "@fedify/fedify";
|
|
24
|
-
* import { PostgresMessageQueue } from "@fedify/postgres";
|
|
25
|
-
* import postgres from "postgres";
|
|
26
|
-
*
|
|
27
|
-
* const federation = createFederation({
|
|
28
|
-
* // ...
|
|
29
|
-
* queue: new PostgresMessageQueue(
|
|
30
|
-
* postgres("postgres://user:pass@localhost/db")
|
|
31
|
-
* ),
|
|
32
|
-
* });
|
|
33
|
-
* ```
|
|
34
|
-
*/
|
|
35
|
-
export class PostgresMessageQueue {
|
|
36
|
-
constructor(
|
|
37
|
-
// deno-lint-ignore ban-types
|
|
38
|
-
sql, options = {}) {
|
|
39
|
-
_PostgresMessageQueue_instances.add(this);
|
|
40
|
-
// deno-lint-ignore ban-types
|
|
41
|
-
_PostgresMessageQueue_sql.set(this, void 0);
|
|
42
|
-
_PostgresMessageQueue_tableName.set(this, void 0);
|
|
43
|
-
_PostgresMessageQueue_channelName.set(this, void 0);
|
|
44
|
-
_PostgresMessageQueue_pollIntervalMs.set(this, void 0);
|
|
45
|
-
_PostgresMessageQueue_initialized.set(this, void 0);
|
|
46
|
-
_PostgresMessageQueue_driverSerializesJson.set(this, false);
|
|
47
|
-
__classPrivateFieldSet(this, _PostgresMessageQueue_sql, sql, "f");
|
|
48
|
-
__classPrivateFieldSet(this, _PostgresMessageQueue_tableName, options?.tableName ?? "fedify_message_v2", "f");
|
|
49
|
-
__classPrivateFieldSet(this, _PostgresMessageQueue_channelName, options?.channelName ?? "fedify_channel", "f");
|
|
50
|
-
__classPrivateFieldSet(this, _PostgresMessageQueue_pollIntervalMs, dntShim.Temporal.Duration.from(options?.pollInterval ?? { seconds: 5 }).total("millisecond"), "f");
|
|
51
|
-
__classPrivateFieldSet(this, _PostgresMessageQueue_initialized, options?.initialized ?? false, "f");
|
|
52
|
-
}
|
|
53
|
-
async enqueue(
|
|
54
|
-
// deno-lint-ignore no-explicit-any
|
|
55
|
-
message, options) {
|
|
56
|
-
await this.initialize();
|
|
57
|
-
const delay = options?.delay ?? dntShim.Temporal.Duration.from({ seconds: 0 });
|
|
58
|
-
if (options?.delay) {
|
|
59
|
-
logger.debug("Enqueuing a message with a delay of {delay}...", {
|
|
60
|
-
delay,
|
|
61
|
-
message,
|
|
62
|
-
});
|
|
63
|
-
}
|
|
64
|
-
else {
|
|
65
|
-
logger.debug("Enqueuing a message...", { message });
|
|
66
|
-
}
|
|
67
|
-
await __classPrivateFieldGet(this, _PostgresMessageQueue_sql, "f").bind(this) `
|
|
68
|
-
INSERT INTO ${__classPrivateFieldGet(this, _PostgresMessageQueue_sql, "f").call(this, __classPrivateFieldGet(this, _PostgresMessageQueue_tableName, "f"))} (message, delay)
|
|
69
|
-
VALUES (
|
|
70
|
-
${__classPrivateFieldGet(this, _PostgresMessageQueue_instances, "m", _PostgresMessageQueue_json).call(this, message)},
|
|
71
|
-
${delay.toString()}
|
|
72
|
-
);
|
|
73
|
-
`;
|
|
74
|
-
logger.debug("Enqueued a message.", { message });
|
|
75
|
-
await __classPrivateFieldGet(this, _PostgresMessageQueue_sql, "f").notify(__classPrivateFieldGet(this, _PostgresMessageQueue_channelName, "f"), delay.toString());
|
|
76
|
-
logger.debug("Notified the message queue channel {channelName}.", {
|
|
77
|
-
channelName: __classPrivateFieldGet(this, _PostgresMessageQueue_channelName, "f"),
|
|
78
|
-
message,
|
|
79
|
-
});
|
|
80
|
-
}
|
|
81
|
-
async enqueueMany(
|
|
82
|
-
// deno-lint-ignore no-explicit-any
|
|
83
|
-
messages, options) {
|
|
84
|
-
if (messages.length === 0)
|
|
85
|
-
return;
|
|
86
|
-
await this.initialize();
|
|
87
|
-
const delay = options?.delay ?? dntShim.Temporal.Duration.from({ seconds: 0 });
|
|
88
|
-
if (options?.delay) {
|
|
89
|
-
logger.debug("Enqueuing messages with a delay of {delay}...", {
|
|
90
|
-
delay,
|
|
91
|
-
messages,
|
|
92
|
-
});
|
|
93
|
-
}
|
|
94
|
-
else {
|
|
95
|
-
logger.debug("Enqueuing messages...", { messages });
|
|
96
|
-
}
|
|
97
|
-
for (const message of messages) {
|
|
98
|
-
await __classPrivateFieldGet(this, _PostgresMessageQueue_sql, "f").bind(this) `
|
|
99
|
-
INSERT INTO ${__classPrivateFieldGet(this, _PostgresMessageQueue_sql, "f").call(this, __classPrivateFieldGet(this, _PostgresMessageQueue_tableName, "f"))} (message, delay)
|
|
100
|
-
VALUES (
|
|
101
|
-
${__classPrivateFieldGet(this, _PostgresMessageQueue_instances, "m", _PostgresMessageQueue_json).call(this, message)},
|
|
102
|
-
${delay.toString()}
|
|
103
|
-
);
|
|
104
|
-
`;
|
|
105
|
-
}
|
|
106
|
-
logger.debug("Enqueued messages.", { messages });
|
|
107
|
-
await __classPrivateFieldGet(this, _PostgresMessageQueue_sql, "f").notify(__classPrivateFieldGet(this, _PostgresMessageQueue_channelName, "f"), delay.toString());
|
|
108
|
-
logger.debug("Notified the message queue channel {channelName}.", {
|
|
109
|
-
channelName: __classPrivateFieldGet(this, _PostgresMessageQueue_channelName, "f"),
|
|
110
|
-
messages,
|
|
111
|
-
});
|
|
112
|
-
}
|
|
113
|
-
async listen(
|
|
114
|
-
// deno-lint-ignore no-explicit-any
|
|
115
|
-
handler, options = {}) {
|
|
116
|
-
await this.initialize();
|
|
117
|
-
const { signal } = options;
|
|
118
|
-
const poll = async () => {
|
|
119
|
-
while (!signal?.aborted) {
|
|
120
|
-
const query = __classPrivateFieldGet(this, _PostgresMessageQueue_sql, "f").bind(this) `
|
|
121
|
-
DELETE FROM ${__classPrivateFieldGet(this, _PostgresMessageQueue_sql, "f").call(this, __classPrivateFieldGet(this, _PostgresMessageQueue_tableName, "f"))}
|
|
122
|
-
WHERE id = (
|
|
123
|
-
SELECT id
|
|
124
|
-
FROM ${__classPrivateFieldGet(this, _PostgresMessageQueue_sql, "f").call(this, __classPrivateFieldGet(this, _PostgresMessageQueue_tableName, "f"))}
|
|
125
|
-
WHERE created + delay < CURRENT_TIMESTAMP
|
|
126
|
-
ORDER BY created
|
|
127
|
-
LIMIT 1
|
|
128
|
-
)
|
|
129
|
-
RETURNING message;
|
|
130
|
-
`.execute();
|
|
131
|
-
const cancel = query.cancel.bind(query);
|
|
132
|
-
signal?.addEventListener("abort", cancel);
|
|
133
|
-
let i = 0;
|
|
134
|
-
for (const message of await query) {
|
|
135
|
-
if (signal?.aborted)
|
|
136
|
-
return;
|
|
137
|
-
await handler(message.message);
|
|
138
|
-
i++;
|
|
139
|
-
}
|
|
140
|
-
signal?.removeEventListener("abort", cancel);
|
|
141
|
-
if (i < 1)
|
|
142
|
-
break;
|
|
143
|
-
}
|
|
144
|
-
};
|
|
145
|
-
const timeouts = new Set();
|
|
146
|
-
const listen = await __classPrivateFieldGet(this, _PostgresMessageQueue_sql, "f").listen(__classPrivateFieldGet(this, _PostgresMessageQueue_channelName, "f"), async (delay) => {
|
|
147
|
-
const duration = dntShim.Temporal.Duration.from(delay);
|
|
148
|
-
const durationMs = duration.total("millisecond");
|
|
149
|
-
if (durationMs < 1)
|
|
150
|
-
await poll();
|
|
151
|
-
else
|
|
152
|
-
timeouts.add(setTimeout(poll, durationMs));
|
|
153
|
-
}, poll);
|
|
154
|
-
signal?.addEventListener("abort", () => {
|
|
155
|
-
listen.unlisten();
|
|
156
|
-
for (const timeout of timeouts)
|
|
157
|
-
clearTimeout(timeout);
|
|
158
|
-
});
|
|
159
|
-
while (!signal?.aborted) {
|
|
160
|
-
let timeout;
|
|
161
|
-
await new Promise((resolve) => {
|
|
162
|
-
signal?.addEventListener("abort", resolve);
|
|
163
|
-
timeout = setTimeout(() => {
|
|
164
|
-
signal?.removeEventListener("abort", resolve);
|
|
165
|
-
resolve(0);
|
|
166
|
-
}, __classPrivateFieldGet(this, _PostgresMessageQueue_pollIntervalMs, "f"));
|
|
167
|
-
timeouts.add(timeout);
|
|
168
|
-
});
|
|
169
|
-
if (timeout != null)
|
|
170
|
-
timeouts.delete(timeout);
|
|
171
|
-
await poll();
|
|
172
|
-
}
|
|
173
|
-
await new Promise((resolve) => {
|
|
174
|
-
signal?.addEventListener("abort", () => resolve());
|
|
175
|
-
if (signal?.aborted)
|
|
176
|
-
return resolve();
|
|
177
|
-
});
|
|
178
|
-
}
|
|
179
|
-
/**
|
|
180
|
-
* Initializes the message queue table if it does not already exist.
|
|
181
|
-
*/
|
|
182
|
-
async initialize() {
|
|
183
|
-
if (__classPrivateFieldGet(this, _PostgresMessageQueue_initialized, "f"))
|
|
184
|
-
return;
|
|
185
|
-
logger.debug("Initializing the message queue table {tableName}...", {
|
|
186
|
-
tableName: __classPrivateFieldGet(this, _PostgresMessageQueue_tableName, "f"),
|
|
187
|
-
});
|
|
188
|
-
try {
|
|
189
|
-
await __classPrivateFieldGet(this, _PostgresMessageQueue_sql, "f").bind(this) `
|
|
190
|
-
CREATE TABLE IF NOT EXISTS ${__classPrivateFieldGet(this, _PostgresMessageQueue_sql, "f").call(this, __classPrivateFieldGet(this, _PostgresMessageQueue_tableName, "f"))} (
|
|
191
|
-
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
192
|
-
message jsonb NOT NULL,
|
|
193
|
-
delay interval DEFAULT '0 seconds',
|
|
194
|
-
created timestamp with time zone DEFAULT CURRENT_TIMESTAMP
|
|
195
|
-
);
|
|
196
|
-
`;
|
|
197
|
-
}
|
|
198
|
-
catch (error) {
|
|
199
|
-
if (!(error instanceof postgres.PostgresError &&
|
|
200
|
-
error.constraint_name === "pg_type_typname_nsp_index")) {
|
|
201
|
-
logger.error("Failed to initialize the message queue table: {error}", {
|
|
202
|
-
error,
|
|
203
|
-
});
|
|
204
|
-
throw error;
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
__classPrivateFieldSet(this, _PostgresMessageQueue_driverSerializesJson, await driverSerializesJson(__classPrivateFieldGet(this, _PostgresMessageQueue_sql, "f")), "f");
|
|
208
|
-
__classPrivateFieldSet(this, _PostgresMessageQueue_initialized, true, "f");
|
|
209
|
-
logger.debug("Initialized the message queue table {tableName}.", {
|
|
210
|
-
tableName: __classPrivateFieldGet(this, _PostgresMessageQueue_tableName, "f"),
|
|
211
|
-
});
|
|
212
|
-
}
|
|
213
|
-
/**
|
|
214
|
-
* Drops the message queue table if it exists.
|
|
215
|
-
*/
|
|
216
|
-
async drop() {
|
|
217
|
-
await __classPrivateFieldGet(this, _PostgresMessageQueue_sql, "f").bind(this) `DROP TABLE IF EXISTS ${__classPrivateFieldGet(this, _PostgresMessageQueue_sql, "f").call(this, __classPrivateFieldGet(this, _PostgresMessageQueue_tableName, "f"))};`;
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
_PostgresMessageQueue_sql = new WeakMap(), _PostgresMessageQueue_tableName = new WeakMap(), _PostgresMessageQueue_channelName = new WeakMap(), _PostgresMessageQueue_pollIntervalMs = new WeakMap(), _PostgresMessageQueue_initialized = new WeakMap(), _PostgresMessageQueue_driverSerializesJson = new WeakMap(), _PostgresMessageQueue_instances = new WeakSet(), _PostgresMessageQueue_json = function _PostgresMessageQueue_json(value) {
|
|
221
|
-
if (__classPrivateFieldGet(this, _PostgresMessageQueue_driverSerializesJson, "f"))
|
|
222
|
-
return __classPrivateFieldGet(this, _PostgresMessageQueue_sql, "f").json(value);
|
|
223
|
-
return __classPrivateFieldGet(this, _PostgresMessageQueue_sql, "f").json(JSON.stringify(value));
|
|
224
|
-
};
|
|
225
|
-
// cSpell: ignore typname
|
package/esm/src/utils.js
DELETED
package/script/_dnt.shims.js
DELETED
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.dntGlobalThis = exports.Temporal = exports.Deno = void 0;
|
|
4
|
-
const shim_deno_1 = require("@deno/shim-deno");
|
|
5
|
-
var shim_deno_2 = require("@deno/shim-deno");
|
|
6
|
-
Object.defineProperty(exports, "Deno", { enumerable: true, get: function () { return shim_deno_2.Deno; } });
|
|
7
|
-
const polyfill_1 = require("@js-temporal/polyfill");
|
|
8
|
-
var polyfill_2 = require("@js-temporal/polyfill");
|
|
9
|
-
Object.defineProperty(exports, "Temporal", { enumerable: true, get: function () { return polyfill_2.Temporal; } });
|
|
10
|
-
const dntGlobals = {
|
|
11
|
-
Deno: shim_deno_1.Deno,
|
|
12
|
-
Temporal: polyfill_1.Temporal,
|
|
13
|
-
};
|
|
14
|
-
exports.dntGlobalThis = createMergeProxy(globalThis, dntGlobals);
|
|
15
|
-
function createMergeProxy(baseObj, extObj) {
|
|
16
|
-
return new Proxy(baseObj, {
|
|
17
|
-
get(_target, prop, _receiver) {
|
|
18
|
-
if (prop in extObj) {
|
|
19
|
-
return extObj[prop];
|
|
20
|
-
}
|
|
21
|
-
else {
|
|
22
|
-
return baseObj[prop];
|
|
23
|
-
}
|
|
24
|
-
},
|
|
25
|
-
set(_target, prop, value) {
|
|
26
|
-
if (prop in extObj) {
|
|
27
|
-
delete extObj[prop];
|
|
28
|
-
}
|
|
29
|
-
baseObj[prop] = value;
|
|
30
|
-
return true;
|
|
31
|
-
},
|
|
32
|
-
deleteProperty(_target, prop) {
|
|
33
|
-
let success = false;
|
|
34
|
-
if (prop in extObj) {
|
|
35
|
-
delete extObj[prop];
|
|
36
|
-
success = true;
|
|
37
|
-
}
|
|
38
|
-
if (prop in baseObj) {
|
|
39
|
-
delete baseObj[prop];
|
|
40
|
-
success = true;
|
|
41
|
-
}
|
|
42
|
-
return success;
|
|
43
|
-
},
|
|
44
|
-
ownKeys(_target) {
|
|
45
|
-
const baseKeys = Reflect.ownKeys(baseObj);
|
|
46
|
-
const extKeys = Reflect.ownKeys(extObj);
|
|
47
|
-
const extKeysSet = new Set(extKeys);
|
|
48
|
-
return [...baseKeys.filter((k) => !extKeysSet.has(k)), ...extKeys];
|
|
49
|
-
},
|
|
50
|
-
defineProperty(_target, prop, desc) {
|
|
51
|
-
if (prop in extObj) {
|
|
52
|
-
delete extObj[prop];
|
|
53
|
-
}
|
|
54
|
-
Reflect.defineProperty(baseObj, prop, desc);
|
|
55
|
-
return true;
|
|
56
|
-
},
|
|
57
|
-
getOwnPropertyDescriptor(_target, prop) {
|
|
58
|
-
if (prop in extObj) {
|
|
59
|
-
return Reflect.getOwnPropertyDescriptor(extObj, prop);
|
|
60
|
-
}
|
|
61
|
-
else {
|
|
62
|
-
return Reflect.getOwnPropertyDescriptor(baseObj, prop);
|
|
63
|
-
}
|
|
64
|
-
},
|
|
65
|
-
has(_target, prop) {
|
|
66
|
-
return prop in extObj || prop in baseObj;
|
|
67
|
-
},
|
|
68
|
-
});
|
|
69
|
-
}
|
package/script/mod.js
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
-
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
-
};
|
|
16
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
__exportStar(require("./src/mod.js"), exports);
|
package/script/package.json
DELETED
package/script/src/kv.js
DELETED
|
@@ -1,129 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
3
|
-
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
4
|
-
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
5
|
-
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
6
|
-
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
7
|
-
};
|
|
8
|
-
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
9
|
-
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
10
|
-
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
11
|
-
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
12
|
-
};
|
|
13
|
-
var _PostgresKvStore_instances, _PostgresKvStore_sql, _PostgresKvStore_tableName, _PostgresKvStore_initialized, _PostgresKvStore_driverSerializesJson, _PostgresKvStore_expire, _PostgresKvStore_json;
|
|
14
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
-
exports.PostgresKvStore = void 0;
|
|
16
|
-
const logtape_1 = require("@logtape/logtape");
|
|
17
|
-
const utils_js_1 = require("./utils.js");
|
|
18
|
-
const logger = (0, logtape_1.getLogger)(["fedify", "postgres", "kv"]);
|
|
19
|
-
/**
|
|
20
|
-
* A key-value store that uses PostgreSQL as the underlying storage.
|
|
21
|
-
*
|
|
22
|
-
* @example
|
|
23
|
-
* ```ts
|
|
24
|
-
* import { createFederation } from "@fedify/fedify";
|
|
25
|
-
* import { PostgresKvStore } from "@fedify/postgres";
|
|
26
|
-
* import postgres from "postgres";
|
|
27
|
-
*
|
|
28
|
-
* const federation = createFederation({
|
|
29
|
-
* // ...
|
|
30
|
-
* kv: new PostgresKvStore(postgres("postgres://user:pass@localhost/db")),
|
|
31
|
-
* });
|
|
32
|
-
* ```
|
|
33
|
-
*/
|
|
34
|
-
class PostgresKvStore {
|
|
35
|
-
/**
|
|
36
|
-
* Creates a new PostgreSQL key-value store.
|
|
37
|
-
* @param sql The PostgreSQL client to use.
|
|
38
|
-
* @param options The options for the key-value store.
|
|
39
|
-
*/
|
|
40
|
-
constructor(
|
|
41
|
-
// deno-lint-ignore ban-types
|
|
42
|
-
sql, options = {}) {
|
|
43
|
-
_PostgresKvStore_instances.add(this);
|
|
44
|
-
// deno-lint-ignore ban-types
|
|
45
|
-
_PostgresKvStore_sql.set(this, void 0);
|
|
46
|
-
_PostgresKvStore_tableName.set(this, void 0);
|
|
47
|
-
_PostgresKvStore_initialized.set(this, void 0);
|
|
48
|
-
_PostgresKvStore_driverSerializesJson.set(this, false);
|
|
49
|
-
__classPrivateFieldSet(this, _PostgresKvStore_sql, sql, "f");
|
|
50
|
-
__classPrivateFieldSet(this, _PostgresKvStore_tableName, options.tableName ?? "fedify_kv_v2", "f");
|
|
51
|
-
__classPrivateFieldSet(this, _PostgresKvStore_initialized, options.initialized ?? false, "f");
|
|
52
|
-
}
|
|
53
|
-
async get(key) {
|
|
54
|
-
await this.initialize();
|
|
55
|
-
const result = await __classPrivateFieldGet(this, _PostgresKvStore_sql, "f").bind(this) `
|
|
56
|
-
SELECT value
|
|
57
|
-
FROM ${__classPrivateFieldGet(this, _PostgresKvStore_sql, "f").call(this, __classPrivateFieldGet(this, _PostgresKvStore_tableName, "f"))}
|
|
58
|
-
WHERE key = ${key} AND (ttl IS NULL OR created + ttl > CURRENT_TIMESTAMP);
|
|
59
|
-
`;
|
|
60
|
-
if (result.length < 1)
|
|
61
|
-
return undefined;
|
|
62
|
-
return result[0].value;
|
|
63
|
-
}
|
|
64
|
-
async set(key, value, options) {
|
|
65
|
-
await this.initialize();
|
|
66
|
-
const ttl = options?.ttl == null ? null : options.ttl.toString();
|
|
67
|
-
await __classPrivateFieldGet(this, _PostgresKvStore_sql, "f").bind(this) `
|
|
68
|
-
INSERT INTO ${__classPrivateFieldGet(this, _PostgresKvStore_sql, "f").call(this, __classPrivateFieldGet(this, _PostgresKvStore_tableName, "f"))} (key, value, ttl)
|
|
69
|
-
VALUES (
|
|
70
|
-
${key},
|
|
71
|
-
${__classPrivateFieldGet(this, _PostgresKvStore_instances, "m", _PostgresKvStore_json).call(this, value)},
|
|
72
|
-
${ttl}
|
|
73
|
-
)
|
|
74
|
-
ON CONFLICT (key)
|
|
75
|
-
DO UPDATE SET value = EXCLUDED.value, ttl = EXCLUDED.ttl;
|
|
76
|
-
`;
|
|
77
|
-
await __classPrivateFieldGet(this, _PostgresKvStore_instances, "m", _PostgresKvStore_expire).call(this);
|
|
78
|
-
}
|
|
79
|
-
async delete(key) {
|
|
80
|
-
await this.initialize();
|
|
81
|
-
await __classPrivateFieldGet(this, _PostgresKvStore_sql, "f").bind(this) `
|
|
82
|
-
DELETE FROM ${__classPrivateFieldGet(this, _PostgresKvStore_sql, "f").call(this, __classPrivateFieldGet(this, _PostgresKvStore_tableName, "f"))}
|
|
83
|
-
WHERE key = ${key};
|
|
84
|
-
`;
|
|
85
|
-
await __classPrivateFieldGet(this, _PostgresKvStore_instances, "m", _PostgresKvStore_expire).call(this);
|
|
86
|
-
}
|
|
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
|
-
async initialize() {
|
|
92
|
-
if (__classPrivateFieldGet(this, _PostgresKvStore_initialized, "f"))
|
|
93
|
-
return;
|
|
94
|
-
logger.debug("Initializing the key-value store table {tableName}...", {
|
|
95
|
-
tableName: __classPrivateFieldGet(this, _PostgresKvStore_tableName, "f"),
|
|
96
|
-
});
|
|
97
|
-
await __classPrivateFieldGet(this, _PostgresKvStore_sql, "f").bind(this) `
|
|
98
|
-
CREATE UNLOGGED TABLE IF NOT EXISTS ${__classPrivateFieldGet(this, _PostgresKvStore_sql, "f").call(this, __classPrivateFieldGet(this, _PostgresKvStore_tableName, "f"))} (
|
|
99
|
-
key text[] PRIMARY KEY,
|
|
100
|
-
value jsonb NOT NULL,
|
|
101
|
-
created timestamp with time zone DEFAULT CURRENT_TIMESTAMP,
|
|
102
|
-
ttl interval
|
|
103
|
-
);
|
|
104
|
-
`;
|
|
105
|
-
__classPrivateFieldSet(this, _PostgresKvStore_driverSerializesJson, await (0, utils_js_1.driverSerializesJson)(__classPrivateFieldGet(this, _PostgresKvStore_sql, "f")), "f");
|
|
106
|
-
__classPrivateFieldSet(this, _PostgresKvStore_initialized, true, "f");
|
|
107
|
-
logger.debug("Initialized the key-value store table {tableName}.", {
|
|
108
|
-
tableName: __classPrivateFieldGet(this, _PostgresKvStore_tableName, "f"),
|
|
109
|
-
});
|
|
110
|
-
}
|
|
111
|
-
/**
|
|
112
|
-
* Drops the table used by the key-value store. Does nothing if the table
|
|
113
|
-
* does not exist.
|
|
114
|
-
*/
|
|
115
|
-
async drop() {
|
|
116
|
-
await __classPrivateFieldGet(this, _PostgresKvStore_sql, "f").bind(this) `DROP TABLE IF EXISTS ${__classPrivateFieldGet(this, _PostgresKvStore_sql, "f").call(this, __classPrivateFieldGet(this, _PostgresKvStore_tableName, "f"))};`;
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
exports.PostgresKvStore = PostgresKvStore;
|
|
120
|
-
_PostgresKvStore_sql = new WeakMap(), _PostgresKvStore_tableName = new WeakMap(), _PostgresKvStore_initialized = new WeakMap(), _PostgresKvStore_driverSerializesJson = new WeakMap(), _PostgresKvStore_instances = new WeakSet(), _PostgresKvStore_expire = async function _PostgresKvStore_expire() {
|
|
121
|
-
await __classPrivateFieldGet(this, _PostgresKvStore_sql, "f").bind(this) `
|
|
122
|
-
DELETE FROM ${__classPrivateFieldGet(this, _PostgresKvStore_sql, "f").call(this, __classPrivateFieldGet(this, _PostgresKvStore_tableName, "f"))}
|
|
123
|
-
WHERE ttl IS NOT NULL AND created + ttl < CURRENT_TIMESTAMP;
|
|
124
|
-
`;
|
|
125
|
-
}, _PostgresKvStore_json = function _PostgresKvStore_json(value) {
|
|
126
|
-
if (__classPrivateFieldGet(this, _PostgresKvStore_driverSerializesJson, "f"))
|
|
127
|
-
return __classPrivateFieldGet(this, _PostgresKvStore_sql, "f").json(value);
|
|
128
|
-
return __classPrivateFieldGet(this, _PostgresKvStore_sql, "f").json(JSON.stringify(value));
|
|
129
|
-
};
|
package/script/src/mod.js
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
-
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
-
};
|
|
16
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
__exportStar(require("./kv.js"), exports);
|
|
18
|
-
__exportStar(require("./mq.js"), exports);
|