@fedify/postgres 2.4.0-pr.934.40 → 2.4.0-pr.936.41
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/README.md +0 -9
- package/dist/kv.cjs +12 -91
- package/dist/kv.d.cts +0 -12
- package/dist/kv.d.ts +0 -12
- package/dist/kv.js +12 -91
- package/dist/mq.cjs +0 -1
- package/dist/mq.d.cts +0 -1
- package/dist/mq.d.ts +0 -1
- package/dist/mq.js +0 -1
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -25,15 +25,6 @@ const federation = createFederation({
|
|
|
25
25
|
});
|
|
26
26
|
~~~~
|
|
27
27
|
|
|
28
|
-
`PostgresKvStore` uses a crash-safe logged table by default. For transient
|
|
29
|
-
data where losing the table contents after a PostgreSQL crash is acceptable,
|
|
30
|
-
pass `{ unlogged: true }` as its second constructor argument.
|
|
31
|
-
|
|
32
|
-
When a store created by an earlier version still uses an unlogged table, its
|
|
33
|
-
next initialization converts that table to logged storage. PostgreSQL rewrites
|
|
34
|
-
the table and takes an `ACCESS EXCLUSIVE` lock during this one-time migration,
|
|
35
|
-
so schedule the upgrade accordingly for a large or busy table.
|
|
36
|
-
|
|
37
28
|
[JSR badge]: https://jsr.io/badges/@fedify/postgres
|
|
38
29
|
[JSR]: https://jsr.io/@fedify/postgres
|
|
39
30
|
[npm badge]: https://img.shields.io/npm/v/@fedify/postgres?logo=npm
|
package/dist/kv.cjs
CHANGED
|
@@ -8,9 +8,6 @@ const logger = (0, require("@logtape/logtape").getLogger)([
|
|
|
8
8
|
"postgres",
|
|
9
9
|
"kv"
|
|
10
10
|
]);
|
|
11
|
-
function quoteIdentifier(identifier) {
|
|
12
|
-
return `"${identifier.replaceAll("\"", "\"\"").replaceAll(".", "\".\"")}"`;
|
|
13
|
-
}
|
|
14
11
|
/**
|
|
15
12
|
* A key–value store that uses PostgreSQL as the underlying storage.
|
|
16
13
|
*
|
|
@@ -29,9 +26,7 @@ function quoteIdentifier(identifier) {
|
|
|
29
26
|
var PostgresKvStore = class {
|
|
30
27
|
#sql;
|
|
31
28
|
#tableName;
|
|
32
|
-
#unlogged;
|
|
33
29
|
#initialized;
|
|
34
|
-
#initializing;
|
|
35
30
|
#driverSerializesJson = false;
|
|
36
31
|
/**
|
|
37
32
|
* Creates a new PostgreSQL key–value store.
|
|
@@ -41,7 +36,6 @@ var PostgresKvStore = class {
|
|
|
41
36
|
constructor(sql, options = {}) {
|
|
42
37
|
this.#sql = sql;
|
|
43
38
|
this.#tableName = options.tableName ?? "fedify_kv_v2";
|
|
44
|
-
this.#unlogged = options.unlogged ?? false;
|
|
45
39
|
this.#initialized = options.initialized ?? false;
|
|
46
40
|
}
|
|
47
41
|
async #expire() {
|
|
@@ -84,54 +78,6 @@ var PostgresKvStore = class {
|
|
|
84
78
|
await this.#expire();
|
|
85
79
|
}
|
|
86
80
|
/**
|
|
87
|
-
* {@inheritDoc KvStore.cas}
|
|
88
|
-
* @since 2.4.0
|
|
89
|
-
*/
|
|
90
|
-
async cas(key, expectedValue, newValue, options) {
|
|
91
|
-
await this.initialize();
|
|
92
|
-
const ttl = options?.ttl == null ? null : options.ttl.toString();
|
|
93
|
-
if (expectedValue === void 0 && newValue === void 0) return await this.get(key) === void 0;
|
|
94
|
-
let result;
|
|
95
|
-
if (expectedValue === void 0) result = await this.#sql`
|
|
96
|
-
INSERT INTO ${this.#sql(this.#tableName)} AS existing
|
|
97
|
-
(key, value, created, ttl)
|
|
98
|
-
VALUES (
|
|
99
|
-
${key},
|
|
100
|
-
${this.#json(newValue)},
|
|
101
|
-
CURRENT_TIMESTAMP,
|
|
102
|
-
${ttl}
|
|
103
|
-
)
|
|
104
|
-
ON CONFLICT (key)
|
|
105
|
-
DO UPDATE SET
|
|
106
|
-
value = EXCLUDED.value,
|
|
107
|
-
created = EXCLUDED.created,
|
|
108
|
-
ttl = EXCLUDED.ttl
|
|
109
|
-
WHERE existing.ttl IS NOT NULL
|
|
110
|
-
AND existing.created + existing.ttl <= CURRENT_TIMESTAMP
|
|
111
|
-
RETURNING key;
|
|
112
|
-
`;
|
|
113
|
-
else if (newValue === void 0) result = await this.#sql`
|
|
114
|
-
DELETE FROM ${this.#sql(this.#tableName)}
|
|
115
|
-
WHERE key = ${key}
|
|
116
|
-
AND (ttl IS NULL OR created + ttl > CURRENT_TIMESTAMP)
|
|
117
|
-
AND value = ${this.#json(expectedValue)}
|
|
118
|
-
RETURNING key;
|
|
119
|
-
`;
|
|
120
|
-
else result = await this.#sql`
|
|
121
|
-
UPDATE ${this.#sql(this.#tableName)}
|
|
122
|
-
SET
|
|
123
|
-
value = ${this.#json(newValue)},
|
|
124
|
-
created = CURRENT_TIMESTAMP,
|
|
125
|
-
ttl = ${ttl}
|
|
126
|
-
WHERE key = ${key}
|
|
127
|
-
AND (ttl IS NULL OR created + ttl > CURRENT_TIMESTAMP)
|
|
128
|
-
AND value = ${this.#json(expectedValue)}
|
|
129
|
-
RETURNING key;
|
|
130
|
-
`;
|
|
131
|
-
await this.#expire();
|
|
132
|
-
return result.length > 0;
|
|
133
|
-
}
|
|
134
|
-
/**
|
|
135
81
|
* {@inheritDoc KvStore.list}
|
|
136
82
|
* @since 1.10.0
|
|
137
83
|
*/
|
|
@@ -166,43 +112,18 @@ var PostgresKvStore = class {
|
|
|
166
112
|
*/
|
|
167
113
|
async initialize() {
|
|
168
114
|
if (this.#initialized) return;
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
CREATE TABLE IF NOT EXISTS ${this.#sql(this.#tableName)} (
|
|
182
|
-
key text[] PRIMARY KEY,
|
|
183
|
-
value jsonb NOT NULL,
|
|
184
|
-
created timestamp with time zone DEFAULT CURRENT_TIMESTAMP,
|
|
185
|
-
ttl interval
|
|
186
|
-
);
|
|
187
|
-
`;
|
|
188
|
-
if ((await this.#sql`
|
|
189
|
-
SELECT relpersistence
|
|
190
|
-
FROM pg_class
|
|
191
|
-
WHERE oid = to_regclass(${quoteIdentifier(this.#tableName)});
|
|
192
|
-
`)[0]?.relpersistence === "u") await this.#sql`
|
|
193
|
-
ALTER TABLE ${this.#sql(this.#tableName)} SET LOGGED;
|
|
194
|
-
`;
|
|
195
|
-
}
|
|
196
|
-
this.#driverSerializesJson = await require_utils.driverSerializesJson(this.#sql);
|
|
197
|
-
this.#initialized = true;
|
|
198
|
-
logger.debug("Initialized the key–value store table {tableName}.", { tableName: this.#tableName });
|
|
199
|
-
})();
|
|
200
|
-
try {
|
|
201
|
-
await this.#initializing;
|
|
202
|
-
} catch (error) {
|
|
203
|
-
this.#initializing = void 0;
|
|
204
|
-
throw error;
|
|
205
|
-
}
|
|
115
|
+
logger.debug("Initializing the key–value store table {tableName}...", { tableName: this.#tableName });
|
|
116
|
+
await this.#sql`
|
|
117
|
+
CREATE UNLOGGED TABLE IF NOT EXISTS ${this.#sql(this.#tableName)} (
|
|
118
|
+
key text[] PRIMARY KEY,
|
|
119
|
+
value jsonb NOT NULL,
|
|
120
|
+
created timestamp with time zone DEFAULT CURRENT_TIMESTAMP,
|
|
121
|
+
ttl interval
|
|
122
|
+
);
|
|
123
|
+
`;
|
|
124
|
+
this.#driverSerializesJson = await require_utils.driverSerializesJson(this.#sql);
|
|
125
|
+
this.#initialized = true;
|
|
126
|
+
logger.debug("Initialized the key–value store table {tableName}.", { tableName: this.#tableName });
|
|
206
127
|
}
|
|
207
128
|
/**
|
|
208
129
|
* Drops the table used by the key–value store. Does nothing if the table
|
package/dist/kv.d.cts
CHANGED
|
@@ -18,13 +18,6 @@ interface PostgresKvStoreOptions {
|
|
|
18
18
|
* @default `false`
|
|
19
19
|
*/
|
|
20
20
|
readonly initialized?: boolean;
|
|
21
|
-
/**
|
|
22
|
-
* Whether to use an unlogged table. Unlogged tables are faster, but are
|
|
23
|
-
* truncated after a PostgreSQL crash and are not replicated. `false` by
|
|
24
|
-
* default.
|
|
25
|
-
* @default `false`
|
|
26
|
-
*/
|
|
27
|
-
readonly unlogged?: boolean;
|
|
28
21
|
}
|
|
29
22
|
/**
|
|
30
23
|
* A key–value store that uses PostgreSQL as the underlying storage.
|
|
@@ -53,11 +46,6 @@ declare class PostgresKvStore implements KvStore {
|
|
|
53
46
|
set(key: KvKey, value: unknown, options?: KvStoreSetOptions | undefined): Promise<void>;
|
|
54
47
|
delete(key: KvKey): Promise<void>;
|
|
55
48
|
/**
|
|
56
|
-
* {@inheritDoc KvStore.cas}
|
|
57
|
-
* @since 2.4.0
|
|
58
|
-
*/
|
|
59
|
-
cas(key: KvKey, expectedValue: unknown, newValue: unknown, options?: KvStoreSetOptions): Promise<boolean>;
|
|
60
|
-
/**
|
|
61
49
|
* {@inheritDoc KvStore.list}
|
|
62
50
|
* @since 1.10.0
|
|
63
51
|
*/
|
package/dist/kv.d.ts
CHANGED
|
@@ -18,13 +18,6 @@ interface PostgresKvStoreOptions {
|
|
|
18
18
|
* @default `false`
|
|
19
19
|
*/
|
|
20
20
|
readonly initialized?: boolean;
|
|
21
|
-
/**
|
|
22
|
-
* Whether to use an unlogged table. Unlogged tables are faster, but are
|
|
23
|
-
* truncated after a PostgreSQL crash and are not replicated. `false` by
|
|
24
|
-
* default.
|
|
25
|
-
* @default `false`
|
|
26
|
-
*/
|
|
27
|
-
readonly unlogged?: boolean;
|
|
28
21
|
}
|
|
29
22
|
/**
|
|
30
23
|
* A key–value store that uses PostgreSQL as the underlying storage.
|
|
@@ -53,11 +46,6 @@ declare class PostgresKvStore implements KvStore {
|
|
|
53
46
|
set(key: KvKey, value: unknown, options?: KvStoreSetOptions | undefined): Promise<void>;
|
|
54
47
|
delete(key: KvKey): Promise<void>;
|
|
55
48
|
/**
|
|
56
|
-
* {@inheritDoc KvStore.cas}
|
|
57
|
-
* @since 2.4.0
|
|
58
|
-
*/
|
|
59
|
-
cas(key: KvKey, expectedValue: unknown, newValue: unknown, options?: KvStoreSetOptions): Promise<boolean>;
|
|
60
|
-
/**
|
|
61
49
|
* {@inheritDoc KvStore.list}
|
|
62
50
|
* @since 1.10.0
|
|
63
51
|
*/
|
package/dist/kv.js
CHANGED
|
@@ -7,9 +7,6 @@ const logger = getLogger([
|
|
|
7
7
|
"postgres",
|
|
8
8
|
"kv"
|
|
9
9
|
]);
|
|
10
|
-
function quoteIdentifier(identifier) {
|
|
11
|
-
return `"${identifier.replaceAll("\"", "\"\"").replaceAll(".", "\".\"")}"`;
|
|
12
|
-
}
|
|
13
10
|
/**
|
|
14
11
|
* A key–value store that uses PostgreSQL as the underlying storage.
|
|
15
12
|
*
|
|
@@ -28,9 +25,7 @@ function quoteIdentifier(identifier) {
|
|
|
28
25
|
var PostgresKvStore = class {
|
|
29
26
|
#sql;
|
|
30
27
|
#tableName;
|
|
31
|
-
#unlogged;
|
|
32
28
|
#initialized;
|
|
33
|
-
#initializing;
|
|
34
29
|
#driverSerializesJson = false;
|
|
35
30
|
/**
|
|
36
31
|
* Creates a new PostgreSQL key–value store.
|
|
@@ -40,7 +35,6 @@ var PostgresKvStore = class {
|
|
|
40
35
|
constructor(sql, options = {}) {
|
|
41
36
|
this.#sql = sql;
|
|
42
37
|
this.#tableName = options.tableName ?? "fedify_kv_v2";
|
|
43
|
-
this.#unlogged = options.unlogged ?? false;
|
|
44
38
|
this.#initialized = options.initialized ?? false;
|
|
45
39
|
}
|
|
46
40
|
async #expire() {
|
|
@@ -83,54 +77,6 @@ var PostgresKvStore = class {
|
|
|
83
77
|
await this.#expire();
|
|
84
78
|
}
|
|
85
79
|
/**
|
|
86
|
-
* {@inheritDoc KvStore.cas}
|
|
87
|
-
* @since 2.4.0
|
|
88
|
-
*/
|
|
89
|
-
async cas(key, expectedValue, newValue, options) {
|
|
90
|
-
await this.initialize();
|
|
91
|
-
const ttl = options?.ttl == null ? null : options.ttl.toString();
|
|
92
|
-
if (expectedValue === void 0 && newValue === void 0) return await this.get(key) === void 0;
|
|
93
|
-
let result;
|
|
94
|
-
if (expectedValue === void 0) result = await this.#sql`
|
|
95
|
-
INSERT INTO ${this.#sql(this.#tableName)} AS existing
|
|
96
|
-
(key, value, created, ttl)
|
|
97
|
-
VALUES (
|
|
98
|
-
${key},
|
|
99
|
-
${this.#json(newValue)},
|
|
100
|
-
CURRENT_TIMESTAMP,
|
|
101
|
-
${ttl}
|
|
102
|
-
)
|
|
103
|
-
ON CONFLICT (key)
|
|
104
|
-
DO UPDATE SET
|
|
105
|
-
value = EXCLUDED.value,
|
|
106
|
-
created = EXCLUDED.created,
|
|
107
|
-
ttl = EXCLUDED.ttl
|
|
108
|
-
WHERE existing.ttl IS NOT NULL
|
|
109
|
-
AND existing.created + existing.ttl <= CURRENT_TIMESTAMP
|
|
110
|
-
RETURNING key;
|
|
111
|
-
`;
|
|
112
|
-
else if (newValue === void 0) result = await this.#sql`
|
|
113
|
-
DELETE FROM ${this.#sql(this.#tableName)}
|
|
114
|
-
WHERE key = ${key}
|
|
115
|
-
AND (ttl IS NULL OR created + ttl > CURRENT_TIMESTAMP)
|
|
116
|
-
AND value = ${this.#json(expectedValue)}
|
|
117
|
-
RETURNING key;
|
|
118
|
-
`;
|
|
119
|
-
else result = await this.#sql`
|
|
120
|
-
UPDATE ${this.#sql(this.#tableName)}
|
|
121
|
-
SET
|
|
122
|
-
value = ${this.#json(newValue)},
|
|
123
|
-
created = CURRENT_TIMESTAMP,
|
|
124
|
-
ttl = ${ttl}
|
|
125
|
-
WHERE key = ${key}
|
|
126
|
-
AND (ttl IS NULL OR created + ttl > CURRENT_TIMESTAMP)
|
|
127
|
-
AND value = ${this.#json(expectedValue)}
|
|
128
|
-
RETURNING key;
|
|
129
|
-
`;
|
|
130
|
-
await this.#expire();
|
|
131
|
-
return result.length > 0;
|
|
132
|
-
}
|
|
133
|
-
/**
|
|
134
80
|
* {@inheritDoc KvStore.list}
|
|
135
81
|
* @since 1.10.0
|
|
136
82
|
*/
|
|
@@ -165,43 +111,18 @@ var PostgresKvStore = class {
|
|
|
165
111
|
*/
|
|
166
112
|
async initialize() {
|
|
167
113
|
if (this.#initialized) return;
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
CREATE TABLE IF NOT EXISTS ${this.#sql(this.#tableName)} (
|
|
181
|
-
key text[] PRIMARY KEY,
|
|
182
|
-
value jsonb NOT NULL,
|
|
183
|
-
created timestamp with time zone DEFAULT CURRENT_TIMESTAMP,
|
|
184
|
-
ttl interval
|
|
185
|
-
);
|
|
186
|
-
`;
|
|
187
|
-
if ((await this.#sql`
|
|
188
|
-
SELECT relpersistence
|
|
189
|
-
FROM pg_class
|
|
190
|
-
WHERE oid = to_regclass(${quoteIdentifier(this.#tableName)});
|
|
191
|
-
`)[0]?.relpersistence === "u") await this.#sql`
|
|
192
|
-
ALTER TABLE ${this.#sql(this.#tableName)} SET LOGGED;
|
|
193
|
-
`;
|
|
194
|
-
}
|
|
195
|
-
this.#driverSerializesJson = await driverSerializesJson(this.#sql);
|
|
196
|
-
this.#initialized = true;
|
|
197
|
-
logger.debug("Initialized the key–value store table {tableName}.", { tableName: this.#tableName });
|
|
198
|
-
})();
|
|
199
|
-
try {
|
|
200
|
-
await this.#initializing;
|
|
201
|
-
} catch (error) {
|
|
202
|
-
this.#initializing = void 0;
|
|
203
|
-
throw error;
|
|
204
|
-
}
|
|
114
|
+
logger.debug("Initializing the key–value store table {tableName}...", { tableName: this.#tableName });
|
|
115
|
+
await this.#sql`
|
|
116
|
+
CREATE UNLOGGED TABLE IF NOT EXISTS ${this.#sql(this.#tableName)} (
|
|
117
|
+
key text[] PRIMARY KEY,
|
|
118
|
+
value jsonb NOT NULL,
|
|
119
|
+
created timestamp with time zone DEFAULT CURRENT_TIMESTAMP,
|
|
120
|
+
ttl interval
|
|
121
|
+
);
|
|
122
|
+
`;
|
|
123
|
+
this.#driverSerializesJson = await driverSerializesJson(this.#sql);
|
|
124
|
+
this.#initialized = true;
|
|
125
|
+
logger.debug("Initialized the key–value store table {tableName}.", { tableName: this.#tableName });
|
|
205
126
|
}
|
|
206
127
|
/**
|
|
207
128
|
* Drops the table used by the key–value store. Does nothing if the table
|
package/dist/mq.cjs
CHANGED
package/dist/mq.d.cts
CHANGED
|
@@ -62,7 +62,6 @@ interface PostgresMessageQueueOptions {
|
|
|
62
62
|
*/
|
|
63
63
|
declare class PostgresMessageQueue implements MessageQueue {
|
|
64
64
|
#private;
|
|
65
|
-
readonly atomicEnqueueMany = false;
|
|
66
65
|
constructor(sql: Sql<{}>, options?: PostgresMessageQueueOptions);
|
|
67
66
|
enqueue(message: any, options?: MessageQueueEnqueueOptions): Promise<void>;
|
|
68
67
|
enqueueMany(messages: readonly any[], options?: MessageQueueEnqueueOptions): Promise<void>;
|
package/dist/mq.d.ts
CHANGED
|
@@ -62,7 +62,6 @@ interface PostgresMessageQueueOptions {
|
|
|
62
62
|
*/
|
|
63
63
|
declare class PostgresMessageQueue implements MessageQueue {
|
|
64
64
|
#private;
|
|
65
|
-
readonly atomicEnqueueMany = false;
|
|
66
65
|
constructor(sql: Sql<{}>, options?: PostgresMessageQueueOptions);
|
|
67
66
|
enqueue(message: any, options?: MessageQueueEnqueueOptions): Promise<void>;
|
|
68
67
|
enqueueMany(messages: readonly any[], options?: MessageQueueEnqueueOptions): Promise<void>;
|
package/dist/mq.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fedify/postgres",
|
|
3
|
-
"version": "2.4.0-pr.
|
|
3
|
+
"version": "2.4.0-pr.936.41+59c7432c",
|
|
4
4
|
"description": "PostgreSQL drivers for Fedify",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"fedify",
|
|
@@ -71,15 +71,15 @@
|
|
|
71
71
|
},
|
|
72
72
|
"peerDependencies": {
|
|
73
73
|
"postgres": "^3.4.7",
|
|
74
|
-
"@fedify/fedify": "^2.4.0-pr.
|
|
74
|
+
"@fedify/fedify": "^2.4.0-pr.936.41+59c7432c"
|
|
75
75
|
},
|
|
76
76
|
"devDependencies": {
|
|
77
77
|
"@js-temporal/polyfill": "^0.5.1",
|
|
78
78
|
"@std/async": "npm:@jsr/std__async@^1.0.13",
|
|
79
79
|
"tsdown": "^0.22.0",
|
|
80
80
|
"typescript": "^6.0.0",
|
|
81
|
-
"@fedify/
|
|
82
|
-
"@fedify/
|
|
81
|
+
"@fedify/fixture": "^2.0.0",
|
|
82
|
+
"@fedify/testing": "^2.4.0-pr.936.41+59c7432c"
|
|
83
83
|
},
|
|
84
84
|
"scripts": {
|
|
85
85
|
"build:self": "tsdown",
|