@cogitator-ai/channels 0.9.3 → 0.10.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/README.md +101 -11
- package/dist/assistant-config.d.ts +16 -0
- package/dist/assistant-config.d.ts.map +1 -1
- package/dist/assistant-config.js +22 -0
- package/dist/assistant-config.js.map +1 -1
- package/dist/channels/bluesky/account.d.ts +18 -0
- package/dist/channels/bluesky/account.d.ts.map +1 -0
- package/dist/channels/bluesky/account.js +25 -0
- package/dist/channels/bluesky/account.js.map +1 -0
- package/dist/channels/bluesky/channel.d.ts +89 -0
- package/dist/channels/bluesky/channel.d.ts.map +1 -0
- package/dist/channels/bluesky/channel.js +427 -0
- package/dist/channels/bluesky/channel.js.map +1 -0
- package/dist/channels/bluesky/config.d.ts +16 -0
- package/dist/channels/bluesky/config.d.ts.map +1 -0
- package/dist/channels/bluesky/config.js +2 -0
- package/dist/channels/bluesky/config.js.map +1 -0
- package/dist/channels/bluesky/connection.d.ts +40 -0
- package/dist/channels/bluesky/connection.d.ts.map +1 -0
- package/dist/channels/bluesky/connection.js +159 -0
- package/dist/channels/bluesky/connection.js.map +1 -0
- package/dist/channels/bluesky/feed.d.ts +59 -0
- package/dist/channels/bluesky/feed.d.ts.map +1 -0
- package/dist/channels/bluesky/feed.js +324 -0
- package/dist/channels/bluesky/feed.js.map +1 -0
- package/dist/channels/bluesky/index.d.ts +5 -0
- package/dist/channels/bluesky/index.d.ts.map +1 -0
- package/dist/channels/bluesky/index.js +4 -0
- package/dist/channels/bluesky/index.js.map +1 -0
- package/dist/channels/threads/account.d.ts +42 -0
- package/dist/channels/threads/account.d.ts.map +1 -0
- package/dist/channels/threads/account.js +64 -0
- package/dist/channels/threads/account.js.map +1 -0
- package/dist/channels/threads/channel.d.ts +119 -0
- package/dist/channels/threads/channel.d.ts.map +1 -0
- package/dist/channels/threads/channel.js +405 -0
- package/dist/channels/threads/channel.js.map +1 -0
- package/dist/channels/threads/client.d.ts +42 -0
- package/dist/channels/threads/client.d.ts.map +1 -0
- package/dist/channels/threads/client.js +97 -0
- package/dist/channels/threads/client.js.map +1 -0
- package/dist/channels/threads/feed.d.ts +74 -0
- package/dist/channels/threads/feed.d.ts.map +1 -0
- package/dist/channels/threads/feed.js +372 -0
- package/dist/channels/threads/feed.js.map +1 -0
- package/dist/channels/threads/index.d.ts +6 -0
- package/dist/channels/threads/index.d.ts.map +1 -0
- package/dist/channels/threads/index.js +6 -0
- package/dist/channels/threads/index.js.map +1 -0
- package/dist/channels/threads/token.d.ts +51 -0
- package/dist/channels/threads/token.d.ts.map +1 -0
- package/dist/channels/threads/token.js +128 -0
- package/dist/channels/threads/token.js.map +1 -0
- package/dist/feeds/attachments.d.ts +15 -0
- package/dist/feeds/attachments.d.ts.map +1 -0
- package/dist/feeds/attachments.js +85 -0
- package/dist/feeds/attachments.js.map +1 -0
- package/dist/feeds/errors.d.ts +39 -0
- package/dist/feeds/errors.d.ts.map +1 -0
- package/dist/feeds/errors.js +62 -0
- package/dist/feeds/errors.js.map +1 -0
- package/dist/feeds/index.d.ts +8 -0
- package/dist/feeds/index.d.ts.map +1 -0
- package/dist/feeds/index.js +6 -0
- package/dist/feeds/index.js.map +1 -0
- package/dist/feeds/publish-store.d.ts +148 -0
- package/dist/feeds/publish-store.d.ts.map +1 -0
- package/dist/feeds/publish-store.js +345 -0
- package/dist/feeds/publish-store.js.map +1 -0
- package/dist/feeds/publisher.d.ts +118 -0
- package/dist/feeds/publisher.d.ts.map +1 -0
- package/dist/feeds/publisher.js +308 -0
- package/dist/feeds/publisher.js.map +1 -0
- package/dist/feeds/storage.d.ts +33 -0
- package/dist/feeds/storage.d.ts.map +1 -0
- package/dist/feeds/storage.js +61 -0
- package/dist/feeds/storage.js.map +1 -0
- package/dist/feeds/text.d.ts +26 -0
- package/dist/feeds/text.d.ts.map +1 -0
- package/dist/feeds/text.js +126 -0
- package/dist/feeds/text.js.map +1 -0
- package/dist/feeds/token-store.d.ts +45 -0
- package/dist/feeds/token-store.d.ts.map +1 -0
- package/dist/feeds/token-store.js +128 -0
- package/dist/feeds/token-store.js.map +1 -0
- package/dist/formatters/markdown.d.ts.map +1 -1
- package/dist/formatters/markdown.js +6 -0
- package/dist/formatters/markdown.js.map +1 -1
- package/dist/formatters/plain-text.d.ts +7 -0
- package/dist/formatters/plain-text.d.ts.map +1 -0
- package/dist/formatters/plain-text.js +38 -0
- package/dist/formatters/plain-text.js.map +1 -0
- package/dist/gateway.js +1 -1
- package/dist/gateway.js.map +1 -1
- package/dist/index.d.ts +5 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/runtime-builder.d.ts.map +1 -1
- package/dist/runtime-builder.js +54 -0
- package/dist/runtime-builder.js.map +1 -1
- package/package.json +23 -15
|
@@ -0,0 +1,345 @@
|
|
|
1
|
+
import { mkdir, readdir, readFile, rm } from 'node:fs/promises';
|
|
2
|
+
import { homedir } from 'node:os';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import { createIfMissing, fromJson, SerialQueue, TABLE_NAME, writeFileAtomic, } from './storage.js';
|
|
5
|
+
/** Whether a job still has a feed to publish to. */
|
|
6
|
+
export function isPending(job) {
|
|
7
|
+
return job.deliveries.some((delivery) => delivery.status === 'pending');
|
|
8
|
+
}
|
|
9
|
+
/** When the job's next pending delivery is due, or `undefined` when it is done. */
|
|
10
|
+
export function nextDueAt(job) {
|
|
11
|
+
const due = job.deliveries
|
|
12
|
+
.filter((delivery) => delivery.status === 'pending')
|
|
13
|
+
.map((delivery) => delivery.nextAttemptAt);
|
|
14
|
+
return due.length > 0 ? Math.min(...due) : undefined;
|
|
15
|
+
}
|
|
16
|
+
/** A job as JSON: attachment bytes become base64. */
|
|
17
|
+
export function encodeJob(job) {
|
|
18
|
+
return JSON.stringify(job, (_key, value) => value instanceof Uint8Array ? { __bytes: Buffer.from(value).toString('base64') } : value);
|
|
19
|
+
}
|
|
20
|
+
/** A job back from `encodeJob`. */
|
|
21
|
+
export function decodeJob(json) {
|
|
22
|
+
const text = typeof json === 'string' ? json : JSON.stringify(json);
|
|
23
|
+
return JSON.parse(text, (_key, value) => typeof value === 'object' &&
|
|
24
|
+
value !== null &&
|
|
25
|
+
'__bytes' in value &&
|
|
26
|
+
typeof value.__bytes === 'string'
|
|
27
|
+
? new Uint8Array(Buffer.from(value.__bytes, 'base64'))
|
|
28
|
+
: value);
|
|
29
|
+
}
|
|
30
|
+
const copyOf = (job) => decodeJob(encodeJob(job));
|
|
31
|
+
/** Claims held by one process, for the in-memory and file stores. */
|
|
32
|
+
class LocalClaims {
|
|
33
|
+
now;
|
|
34
|
+
claims = new Map();
|
|
35
|
+
constructor(now) {
|
|
36
|
+
this.now = now;
|
|
37
|
+
}
|
|
38
|
+
held(id) {
|
|
39
|
+
return (this.claims.get(id)?.until ?? 0) > this.now();
|
|
40
|
+
}
|
|
41
|
+
holds(id, owner) {
|
|
42
|
+
const claim = this.claims.get(id);
|
|
43
|
+
return claim?.owner === owner && claim.until > this.now();
|
|
44
|
+
}
|
|
45
|
+
take(id, claim) {
|
|
46
|
+
this.claims.set(id, { owner: claim.owner, until: this.now() + claim.ttl });
|
|
47
|
+
}
|
|
48
|
+
release(id, owner) {
|
|
49
|
+
if (this.claims.get(id)?.owner === owner)
|
|
50
|
+
this.claims.delete(id);
|
|
51
|
+
}
|
|
52
|
+
drop(id) {
|
|
53
|
+
this.claims.delete(id);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
/** Jobs in memory, for tests and a publisher that needs no restart safety. */
|
|
57
|
+
export class MemoryPublishStore {
|
|
58
|
+
jobs = new Map();
|
|
59
|
+
claims;
|
|
60
|
+
constructor(now = Date.now) {
|
|
61
|
+
this.claims = new LocalClaims(now);
|
|
62
|
+
}
|
|
63
|
+
async add(job) {
|
|
64
|
+
const existing = job.key
|
|
65
|
+
? [...this.jobs.values()].find((candidate) => candidate.key === job.key)
|
|
66
|
+
: undefined;
|
|
67
|
+
if (existing)
|
|
68
|
+
return copyOf(existing);
|
|
69
|
+
this.jobs.set(job.id, copyOf(job));
|
|
70
|
+
return copyOf(job);
|
|
71
|
+
}
|
|
72
|
+
async get(id) {
|
|
73
|
+
const job = this.jobs.get(id);
|
|
74
|
+
return job ? copyOf(job) : undefined;
|
|
75
|
+
}
|
|
76
|
+
async claimNext(now, claim) {
|
|
77
|
+
const [next] = [...this.jobs.values()]
|
|
78
|
+
.filter((job) => !this.claims.held(job.id) && (nextDueAt(job) ?? Infinity) <= now)
|
|
79
|
+
.sort((a, b) => (nextDueAt(a) ?? 0) - (nextDueAt(b) ?? 0));
|
|
80
|
+
if (!next)
|
|
81
|
+
return undefined;
|
|
82
|
+
this.claims.take(next.id, claim);
|
|
83
|
+
return copyOf(next);
|
|
84
|
+
}
|
|
85
|
+
async claim(id, claim) {
|
|
86
|
+
if (!this.jobs.has(id) || this.claims.held(id))
|
|
87
|
+
return false;
|
|
88
|
+
this.claims.take(id, claim);
|
|
89
|
+
return true;
|
|
90
|
+
}
|
|
91
|
+
async extend(id, claim) {
|
|
92
|
+
if (!this.claims.holds(id, claim.owner))
|
|
93
|
+
return false;
|
|
94
|
+
this.claims.take(id, claim);
|
|
95
|
+
return true;
|
|
96
|
+
}
|
|
97
|
+
async save(job, owner) {
|
|
98
|
+
if (!this.claims.holds(job.id, owner))
|
|
99
|
+
return false;
|
|
100
|
+
this.jobs.set(job.id, copyOf(job));
|
|
101
|
+
return true;
|
|
102
|
+
}
|
|
103
|
+
async release(id, owner) {
|
|
104
|
+
this.claims.release(id, owner);
|
|
105
|
+
}
|
|
106
|
+
async list(filter = {}) {
|
|
107
|
+
return [...this.jobs.values()]
|
|
108
|
+
.filter((job) => filter.pending === undefined || isPending(job) === filter.pending)
|
|
109
|
+
.sort((a, b) => a.createdAt - b.createdAt)
|
|
110
|
+
.map(copyOf);
|
|
111
|
+
}
|
|
112
|
+
async remove(id) {
|
|
113
|
+
if (this.claims.held(id))
|
|
114
|
+
return false;
|
|
115
|
+
return this.jobs.delete(id);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Jobs as one JSON file each, written atomically, for a single publishing
|
|
120
|
+
* process: claims live in that process. Several workers need
|
|
121
|
+
* `PostgresPublishStore`.
|
|
122
|
+
*/
|
|
123
|
+
export class FilePublishStore {
|
|
124
|
+
directory;
|
|
125
|
+
queue = new SerialQueue();
|
|
126
|
+
claims;
|
|
127
|
+
constructor(options = {}, now = Date.now) {
|
|
128
|
+
this.directory = options.directory ?? join(homedir(), '.cogitator', 'feed-jobs');
|
|
129
|
+
this.claims = new LocalClaims(now);
|
|
130
|
+
}
|
|
131
|
+
async add(job) {
|
|
132
|
+
return this.queue.run(async () => {
|
|
133
|
+
if (job.key) {
|
|
134
|
+
const existing = (await this.readAll()).find((candidate) => candidate.key === job.key);
|
|
135
|
+
if (existing)
|
|
136
|
+
return existing;
|
|
137
|
+
}
|
|
138
|
+
await this.write(job);
|
|
139
|
+
return copyOf(job);
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
async get(id) {
|
|
143
|
+
return this.queue.run(() => this.read(id));
|
|
144
|
+
}
|
|
145
|
+
async claimNext(now, claim) {
|
|
146
|
+
return this.queue.run(async () => {
|
|
147
|
+
const [next] = (await this.readAll())
|
|
148
|
+
.filter((job) => !this.claims.held(job.id) && (nextDueAt(job) ?? Infinity) <= now)
|
|
149
|
+
.sort((a, b) => (nextDueAt(a) ?? 0) - (nextDueAt(b) ?? 0));
|
|
150
|
+
if (next)
|
|
151
|
+
this.claims.take(next.id, claim);
|
|
152
|
+
return next;
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
async claim(id, claim) {
|
|
156
|
+
return this.queue.run(async () => {
|
|
157
|
+
if (this.claims.held(id) || !(await this.read(id)))
|
|
158
|
+
return false;
|
|
159
|
+
this.claims.take(id, claim);
|
|
160
|
+
return true;
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
async extend(id, claim) {
|
|
164
|
+
return this.queue.run(async () => {
|
|
165
|
+
if (!this.claims.holds(id, claim.owner))
|
|
166
|
+
return false;
|
|
167
|
+
this.claims.take(id, claim);
|
|
168
|
+
return true;
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
async save(job, owner) {
|
|
172
|
+
return this.queue.run(async () => {
|
|
173
|
+
if (!this.claims.holds(job.id, owner))
|
|
174
|
+
return false;
|
|
175
|
+
await this.write(job);
|
|
176
|
+
return true;
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
async release(id, owner) {
|
|
180
|
+
await this.queue.run(async () => this.claims.release(id, owner));
|
|
181
|
+
}
|
|
182
|
+
async list(filter = {}) {
|
|
183
|
+
return this.queue.run(async () => (await this.readAll())
|
|
184
|
+
.filter((job) => filter.pending === undefined || isPending(job) === filter.pending)
|
|
185
|
+
.sort((a, b) => a.createdAt - b.createdAt));
|
|
186
|
+
}
|
|
187
|
+
async remove(id) {
|
|
188
|
+
return this.queue.run(async () => {
|
|
189
|
+
if (this.claims.held(id) || !(await this.read(id)))
|
|
190
|
+
return false;
|
|
191
|
+
await rm(this.fileOf(id), { force: true });
|
|
192
|
+
this.claims.drop(id);
|
|
193
|
+
return true;
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
fileOf(id) {
|
|
197
|
+
return join(this.directory, `${id.replace(/[^\w-]/g, '_')}.json`);
|
|
198
|
+
}
|
|
199
|
+
async write(job) {
|
|
200
|
+
await writeFileAtomic(this.fileOf(job.id), encodeJob(job));
|
|
201
|
+
}
|
|
202
|
+
async read(id) {
|
|
203
|
+
try {
|
|
204
|
+
return decodeJob(await readFile(this.fileOf(id), 'utf-8'));
|
|
205
|
+
}
|
|
206
|
+
catch (error) {
|
|
207
|
+
if (error.code === 'ENOENT')
|
|
208
|
+
return undefined;
|
|
209
|
+
throw error;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
async readAll() {
|
|
213
|
+
await mkdir(this.directory, { recursive: true });
|
|
214
|
+
const jobs = [];
|
|
215
|
+
for (const name of await readdir(this.directory)) {
|
|
216
|
+
if (!name.endsWith('.json'))
|
|
217
|
+
continue;
|
|
218
|
+
try {
|
|
219
|
+
jobs.push(decodeJob(await readFile(join(this.directory, name), 'utf-8')));
|
|
220
|
+
}
|
|
221
|
+
catch {
|
|
222
|
+
console.warn(`[feeds] Skipping unreadable job file ${join(this.directory, name)}`);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
return jobs;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Jobs in a Postgres table. Claims are leases on the database clock, taken
|
|
230
|
+
* with `FOR UPDATE SKIP LOCKED`, so several publishing workers split the due
|
|
231
|
+
* jobs between them, and a worker saves a job only while its lease holds.
|
|
232
|
+
*/
|
|
233
|
+
export class PostgresPublishStore {
|
|
234
|
+
client;
|
|
235
|
+
table;
|
|
236
|
+
ready;
|
|
237
|
+
constructor(options) {
|
|
238
|
+
const table = options.table ?? 'cogitator_feed_jobs';
|
|
239
|
+
if (!TABLE_NAME.test(table))
|
|
240
|
+
throw new Error(`Invalid feed job table name: ${table}`);
|
|
241
|
+
this.client = options.client;
|
|
242
|
+
this.table = table;
|
|
243
|
+
}
|
|
244
|
+
async add(job) {
|
|
245
|
+
await this.ensureTable();
|
|
246
|
+
const { rows } = await this.client.query(`INSERT INTO ${this.table} (id, key, next_due_at, created_at, data)
|
|
247
|
+
VALUES ($1, $2, $3, $4, $5::jsonb)
|
|
248
|
+
ON CONFLICT DO NOTHING
|
|
249
|
+
RETURNING data`, [job.id, job.key ?? null, nextDueAt(job) ?? null, job.createdAt, encodeJob(job)]);
|
|
250
|
+
if (rows[0])
|
|
251
|
+
return decodeJob(fromJson(rows[0].data));
|
|
252
|
+
const existing = job.key
|
|
253
|
+
? await this.client.query(`SELECT data FROM ${this.table} WHERE key = $1`, [job.key])
|
|
254
|
+
: await this.client.query(`SELECT data FROM ${this.table} WHERE id = $1`, [job.id]);
|
|
255
|
+
if (!existing.rows[0])
|
|
256
|
+
throw new Error(`Could not add feed job ${job.id}`);
|
|
257
|
+
return decodeJob(fromJson(existing.rows[0].data));
|
|
258
|
+
}
|
|
259
|
+
async get(id) {
|
|
260
|
+
await this.ensureTable();
|
|
261
|
+
const { rows } = await this.client.query(`SELECT data FROM ${this.table} WHERE id = $1`, [id]);
|
|
262
|
+
return rows[0] ? decodeJob(fromJson(rows[0].data)) : undefined;
|
|
263
|
+
}
|
|
264
|
+
async claimNext(now, claim) {
|
|
265
|
+
await this.ensureTable();
|
|
266
|
+
const { rows } = await this.client.query(`UPDATE ${this.table}
|
|
267
|
+
SET claimed_until = now() + $2::double precision * interval '1 millisecond',
|
|
268
|
+
claimed_by = $3
|
|
269
|
+
WHERE id = (
|
|
270
|
+
SELECT id FROM ${this.table}
|
|
271
|
+
WHERE next_due_at IS NOT NULL AND next_due_at <= $1
|
|
272
|
+
AND (claimed_until IS NULL OR claimed_until < now())
|
|
273
|
+
ORDER BY next_due_at
|
|
274
|
+
LIMIT 1
|
|
275
|
+
FOR UPDATE SKIP LOCKED)
|
|
276
|
+
RETURNING data`, [now, claim.ttl, claim.owner]);
|
|
277
|
+
return rows[0] ? decodeJob(fromJson(rows[0].data)) : undefined;
|
|
278
|
+
}
|
|
279
|
+
async claim(id, claim) {
|
|
280
|
+
await this.ensureTable();
|
|
281
|
+
const { rows } = await this.client.query(`UPDATE ${this.table}
|
|
282
|
+
SET claimed_until = now() + $2::double precision * interval '1 millisecond',
|
|
283
|
+
claimed_by = $3
|
|
284
|
+
WHERE id = $1 AND (claimed_until IS NULL OR claimed_until < now())
|
|
285
|
+
RETURNING id`, [id, claim.ttl, claim.owner]);
|
|
286
|
+
return rows.length > 0;
|
|
287
|
+
}
|
|
288
|
+
async extend(id, claim) {
|
|
289
|
+
await this.ensureTable();
|
|
290
|
+
const { rows } = await this.client.query(`UPDATE ${this.table}
|
|
291
|
+
SET claimed_until = now() + $2::double precision * interval '1 millisecond'
|
|
292
|
+
WHERE id = $1 AND claimed_by = $3 AND claimed_until > now()
|
|
293
|
+
RETURNING id`, [id, claim.ttl, claim.owner]);
|
|
294
|
+
return rows.length > 0;
|
|
295
|
+
}
|
|
296
|
+
async save(job, owner) {
|
|
297
|
+
await this.ensureTable();
|
|
298
|
+
const { rows } = await this.client.query(`UPDATE ${this.table} SET data = $2::jsonb, next_due_at = $3
|
|
299
|
+
WHERE id = $1 AND claimed_by = $4 AND claimed_until > now()
|
|
300
|
+
RETURNING id`, [job.id, encodeJob(job), nextDueAt(job) ?? null, owner]);
|
|
301
|
+
return rows.length > 0;
|
|
302
|
+
}
|
|
303
|
+
async release(id, owner) {
|
|
304
|
+
await this.ensureTable();
|
|
305
|
+
await this.client.query(`UPDATE ${this.table} SET claimed_until = NULL, claimed_by = NULL
|
|
306
|
+
WHERE id = $1 AND claimed_by = $2`, [id, owner]);
|
|
307
|
+
}
|
|
308
|
+
async list(filter = {}) {
|
|
309
|
+
await this.ensureTable();
|
|
310
|
+
const where = filter.pending === undefined
|
|
311
|
+
? ''
|
|
312
|
+
: filter.pending
|
|
313
|
+
? 'WHERE next_due_at IS NOT NULL'
|
|
314
|
+
: 'WHERE next_due_at IS NULL';
|
|
315
|
+
const { rows } = await this.client.query(`SELECT data FROM ${this.table} ${where} ORDER BY created_at`);
|
|
316
|
+
return rows.map((row) => decodeJob(fromJson(row.data)));
|
|
317
|
+
}
|
|
318
|
+
async remove(id) {
|
|
319
|
+
await this.ensureTable();
|
|
320
|
+
const { rows } = await this.client.query(`DELETE FROM ${this.table}
|
|
321
|
+
WHERE id = $1 AND (claimed_until IS NULL OR claimed_until < now())
|
|
322
|
+
RETURNING id`, [id]);
|
|
323
|
+
return rows.length > 0;
|
|
324
|
+
}
|
|
325
|
+
ensureTable() {
|
|
326
|
+
this.ready ??= (async () => {
|
|
327
|
+
await createIfMissing(this.client, `CREATE TABLE IF NOT EXISTS ${this.table} (
|
|
328
|
+
id text PRIMARY KEY,
|
|
329
|
+
key text UNIQUE,
|
|
330
|
+
next_due_at bigint,
|
|
331
|
+
created_at bigint NOT NULL,
|
|
332
|
+
claimed_until timestamptz,
|
|
333
|
+
claimed_by text,
|
|
334
|
+
data jsonb NOT NULL
|
|
335
|
+
)`);
|
|
336
|
+
const index = `${this.table.replace('.', '_')}_due_idx`;
|
|
337
|
+
await createIfMissing(this.client, `CREATE INDEX IF NOT EXISTS ${index} ON ${this.table} (next_due_at) WHERE next_due_at IS NOT NULL`);
|
|
338
|
+
})().catch((error) => {
|
|
339
|
+
this.ready = undefined;
|
|
340
|
+
throw error;
|
|
341
|
+
});
|
|
342
|
+
return this.ready;
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
//# sourceMappingURL=publish-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"publish-store.js","sourceRoot":"","sources":["../../src/feeds/publish-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import type { FeedChannel, FeedPost, PublishedPost } from '@cogitator-ai/types';
|
|
2
|
+
import { type PublishJob, type PublishStore } from './publish-store.js';
|
|
3
|
+
export interface FeedRetryOptions {
|
|
4
|
+
/** Attempts per feed before it fails for good (default 5). */
|
|
5
|
+
maxAttempts?: number;
|
|
6
|
+
/** The wait before the second attempt, doubled for each one after, in ms (default 60 000). */
|
|
7
|
+
baseDelay?: number;
|
|
8
|
+
/** The longest wait between attempts, in ms (default one hour). */
|
|
9
|
+
maxDelay?: number;
|
|
10
|
+
}
|
|
11
|
+
export interface FeedPublishedEvent {
|
|
12
|
+
job: PublishJob;
|
|
13
|
+
feed: string;
|
|
14
|
+
post: PublishedPost;
|
|
15
|
+
}
|
|
16
|
+
export interface FeedFailedEvent {
|
|
17
|
+
job: PublishJob;
|
|
18
|
+
feed: string;
|
|
19
|
+
error: Error;
|
|
20
|
+
/** Whether the feed gave up: no attempt follows. */
|
|
21
|
+
final: boolean;
|
|
22
|
+
}
|
|
23
|
+
export interface FeedPublisherOptions {
|
|
24
|
+
feeds: FeedChannel[];
|
|
25
|
+
/** Where jobs are kept (default in memory: scheduled and retried posts do not survive a restart). */
|
|
26
|
+
store?: PublishStore;
|
|
27
|
+
retry?: FeedRetryOptions;
|
|
28
|
+
/** How often a started publisher looks for due jobs, in ms (default 15 000). */
|
|
29
|
+
pollInterval?: number;
|
|
30
|
+
/**
|
|
31
|
+
* How long a claim on a job lasts, in ms (default five minutes). The
|
|
32
|
+
* publisher extends it every third of that while it works on the job, so
|
|
33
|
+
* this is how soon another worker takes over a job whose worker died.
|
|
34
|
+
*/
|
|
35
|
+
claimTtl?: number;
|
|
36
|
+
/**
|
|
37
|
+
* A text longer than a feed takes: `truncate` (default) cuts it at a word
|
|
38
|
+
* with an ellipsis for that feed, `fail` fails that feed.
|
|
39
|
+
*/
|
|
40
|
+
overflow?: 'truncate' | 'fail';
|
|
41
|
+
/** Goes through every step but publishing. Dry runs keep their keys apart from real ones. */
|
|
42
|
+
dryRun?: boolean;
|
|
43
|
+
onPublished?: (event: FeedPublishedEvent) => void | Promise<void>;
|
|
44
|
+
onFailed?: (event: FeedFailedEvent) => void | Promise<void>;
|
|
45
|
+
/** The clock, for tests. */
|
|
46
|
+
now?: () => number;
|
|
47
|
+
}
|
|
48
|
+
export interface PublishOptions {
|
|
49
|
+
/** The feeds to publish to, by type (default every feed of the publisher). */
|
|
50
|
+
feeds?: string[];
|
|
51
|
+
/** Publishing twice with the same key publishes once: the second call returns the first job. */
|
|
52
|
+
key?: string;
|
|
53
|
+
/** When to publish. A time in the future schedules the post. */
|
|
54
|
+
publishAt?: Date | number;
|
|
55
|
+
}
|
|
56
|
+
export interface PublishOutcome {
|
|
57
|
+
job: PublishJob;
|
|
58
|
+
/** Whether the post waits for its time, or for another attempt, rather than being done. */
|
|
59
|
+
pending: boolean;
|
|
60
|
+
/** Whether a job with the same key existed, which is what `job` is. */
|
|
61
|
+
duplicate: boolean;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Publishes posts to several feeds: now or at a time, each feed tried and
|
|
65
|
+
* retried on its own, each outcome saved as soon as it is known. Each
|
|
66
|
+
* delivery keeps the feed's idempotency key from before its first attempt,
|
|
67
|
+
* so an attempt after a crash or a lost answer finds the post instead of
|
|
68
|
+
* publishing it twice, and a key makes the whole publication idempotent.
|
|
69
|
+
*/
|
|
70
|
+
export declare class FeedPublisher {
|
|
71
|
+
private readonly options;
|
|
72
|
+
private readonly feeds;
|
|
73
|
+
private readonly store;
|
|
74
|
+
private readonly retry;
|
|
75
|
+
private readonly pollInterval;
|
|
76
|
+
private readonly claimTtl;
|
|
77
|
+
private readonly now;
|
|
78
|
+
private readonly owner;
|
|
79
|
+
private timer?;
|
|
80
|
+
private ticking?;
|
|
81
|
+
private stopping;
|
|
82
|
+
private readonly connected;
|
|
83
|
+
constructor(options: FeedPublisherOptions);
|
|
84
|
+
/** Publishes `post` now, or schedules it with `publishAt`. */
|
|
85
|
+
publish(post: FeedPost, options?: PublishOptions): Promise<PublishOutcome>;
|
|
86
|
+
/** Looks for due jobs every `pollInterval` until `stop()`: scheduled posts and retries. */
|
|
87
|
+
start(): void;
|
|
88
|
+
/** Stops looking for due jobs, letting the job being published finish, and waits for it. */
|
|
89
|
+
stop(): Promise<void>;
|
|
90
|
+
/**
|
|
91
|
+
* Publishes the jobs that are due now, one at a time, so a claim is taken
|
|
92
|
+
* only when the job is about to be published. `start()` does this on a timer.
|
|
93
|
+
*/
|
|
94
|
+
tick(): Promise<void>;
|
|
95
|
+
get(id: string): Promise<PublishJob | undefined>;
|
|
96
|
+
list(filter?: {
|
|
97
|
+
pending?: boolean;
|
|
98
|
+
}): Promise<PublishJob[]>;
|
|
99
|
+
/** Drops a job before it is published, `false` when it is missing or being published. */
|
|
100
|
+
cancel(id: string): Promise<boolean>;
|
|
101
|
+
/**
|
|
102
|
+
* Connects feeds that will publish later, so a feed that keeps a token
|
|
103
|
+
* renews it until then instead of finding it expired when the post is due.
|
|
104
|
+
* A feed that cannot connect now is tried again the next time.
|
|
105
|
+
*/
|
|
106
|
+
private connect;
|
|
107
|
+
private claimOf;
|
|
108
|
+
/** Publishes a job this publisher claimed, extending the claim while it works, then releases it. */
|
|
109
|
+
private run;
|
|
110
|
+
private process;
|
|
111
|
+
/** Saves the job while the claim holds, `false` when another worker took it over. */
|
|
112
|
+
private save;
|
|
113
|
+
private attempt;
|
|
114
|
+
private send;
|
|
115
|
+
private backoff;
|
|
116
|
+
private notify;
|
|
117
|
+
}
|
|
118
|
+
//# sourceMappingURL=publisher.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"publisher.d.ts","sourceRoot":"","sources":["../../src/feeds/publisher.ts"],"names":[],"mappings":"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"}
|