@fedify/botkit-postgres 0.4.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 +661 -0
- package/README.md +130 -0
- package/dist/mod.d.ts +121 -0
- package/dist/mod.d.ts.map +1 -0
- package/dist/mod.js +460 -0
- package/dist/mod.js.map +1 -0
- package/package.json +63 -0
package/README.md
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
@fedify/botkit-postgres
|
|
2
|
+
=======================
|
|
3
|
+
|
|
4
|
+
[![JSR][JSR badge]][JSR]
|
|
5
|
+
[![npm][npm badge]][npm]
|
|
6
|
+
[![GitHub Actions][GitHub Actions badge]][GitHub Actions]
|
|
7
|
+
|
|
8
|
+
This package is a [PostgreSQL]-based repository implementation for [BotKit].
|
|
9
|
+
It provides persistent shared storage for bots running on either [Deno] or
|
|
10
|
+
[Node.js], supports connection pooling through [Postgres.js], and stores BotKit
|
|
11
|
+
repository data in ordinary PostgreSQL tables under a dedicated schema.
|
|
12
|
+
|
|
13
|
+
[JSR badge]: https://jsr.io/badges/@fedify/botkit-postgres
|
|
14
|
+
[JSR]: https://jsr.io/@fedify/botkit-postgres
|
|
15
|
+
[npm badge]: https://img.shields.io/npm/v/@fedify/botkit-postgres?logo=npm
|
|
16
|
+
[npm]: https://www.npmjs.com/package/@fedify/botkit-postgres
|
|
17
|
+
[GitHub Actions badge]: https://github.com/fedify-dev/botkit/actions/workflows/main.yaml/badge.svg
|
|
18
|
+
[GitHub Actions]: https://github.com/fedify-dev/botkit/actions/workflows/main.yaml
|
|
19
|
+
[PostgreSQL]: https://www.postgresql.org/
|
|
20
|
+
[BotKit]: https://botkit.fedify.dev/
|
|
21
|
+
[Deno]: https://deno.land/
|
|
22
|
+
[Node.js]: https://nodejs.org/
|
|
23
|
+
[Postgres.js]: https://github.com/porsager/postgres
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
Installation
|
|
27
|
+
------------
|
|
28
|
+
|
|
29
|
+
~~~~ sh
|
|
30
|
+
deno add jsr:@fedify/botkit-postgres
|
|
31
|
+
npm add @fedify/botkit-postgres
|
|
32
|
+
pnpm add @fedify/botkit-postgres
|
|
33
|
+
yarn add @fedify/botkit-postgres
|
|
34
|
+
~~~~
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
Usage
|
|
38
|
+
-----
|
|
39
|
+
|
|
40
|
+
The `PostgresRepository` can be used as a drop-in repository implementation for
|
|
41
|
+
BotKit:
|
|
42
|
+
|
|
43
|
+
~~~~ typescript
|
|
44
|
+
import { createBot } from "@fedify/botkit";
|
|
45
|
+
import { PostgresRepository } from "@fedify/botkit-postgres";
|
|
46
|
+
|
|
47
|
+
const bot = createBot({
|
|
48
|
+
username: "mybot",
|
|
49
|
+
repository: new PostgresRepository({
|
|
50
|
+
url: "postgresql://localhost/botkit",
|
|
51
|
+
schema: "botkit",
|
|
52
|
+
maxConnections: 10,
|
|
53
|
+
}),
|
|
54
|
+
});
|
|
55
|
+
~~~~
|
|
56
|
+
|
|
57
|
+
You can also inject an existing [Postgres.js] client. In that case the
|
|
58
|
+
repository does not own the client and `close()` will not shut it down:
|
|
59
|
+
|
|
60
|
+
~~~~ typescript
|
|
61
|
+
import postgres from "postgres";
|
|
62
|
+
import { PostgresRepository } from "@fedify/botkit-postgres";
|
|
63
|
+
|
|
64
|
+
const sql = postgres("postgresql://localhost/botkit");
|
|
65
|
+
const repository = new PostgresRepository({
|
|
66
|
+
sql,
|
|
67
|
+
schema: "botkit",
|
|
68
|
+
});
|
|
69
|
+
~~~~
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
Options
|
|
73
|
+
-------
|
|
74
|
+
|
|
75
|
+
The `PostgresRepository` constructor accepts the following options:
|
|
76
|
+
|
|
77
|
+
- **`sql`**: An existing [Postgres.js] client to use.
|
|
78
|
+
|
|
79
|
+
- **`url`**: A PostgreSQL connection string for an internally managed
|
|
80
|
+
connection pool.
|
|
81
|
+
|
|
82
|
+
- **`schema`** (optional): The PostgreSQL schema name used for BotKit tables.
|
|
83
|
+
Defaults to `"botkit"`.
|
|
84
|
+
|
|
85
|
+
- **`maxConnections`** (optional): Maximum number of connections for an
|
|
86
|
+
internally managed pool created from `url`.
|
|
87
|
+
|
|
88
|
+
- **`prepare`** (optional): Whether to use prepared statements for queries.
|
|
89
|
+
Defaults to `true`.
|
|
90
|
+
|
|
91
|
+
The options are mutually exclusive: use either `sql` or `url`. The
|
|
92
|
+
`maxConnections` option is only valid together with `url`.
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
Schema setup
|
|
96
|
+
------------
|
|
97
|
+
|
|
98
|
+
The repository creates its schema and tables automatically on first use.
|
|
99
|
+
If you want to provision them explicitly ahead of time, use the exported
|
|
100
|
+
`initializePostgresRepositorySchema()` helper:
|
|
101
|
+
|
|
102
|
+
~~~~ typescript
|
|
103
|
+
import postgres from "postgres";
|
|
104
|
+
import { initializePostgresRepositorySchema } from "@fedify/botkit-postgres";
|
|
105
|
+
|
|
106
|
+
const sql = postgres("postgresql://localhost/botkit");
|
|
107
|
+
await initializePostgresRepositorySchema(sql, "botkit");
|
|
108
|
+
~~~~
|
|
109
|
+
|
|
110
|
+
If you disable prepared statements, pass `false` as the third argument so
|
|
111
|
+
schema initialization uses the same setting.
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
Features
|
|
115
|
+
--------
|
|
116
|
+
|
|
117
|
+
- **Cross-runtime**: Works with both Deno and Node.js using [Postgres.js]
|
|
118
|
+
|
|
119
|
+
- **Shared persistent storage**: Suitable for multi-process and
|
|
120
|
+
multi-instance deployments backed by PostgreSQL
|
|
121
|
+
|
|
122
|
+
- **Schema namespacing**: Keeps BotKit tables grouped under a dedicated
|
|
123
|
+
PostgreSQL schema
|
|
124
|
+
|
|
125
|
+
- **Full `Repository` API**: Implements BotKit repository storage for key
|
|
126
|
+
pairs, messages, followers, follows, followees, and poll votes
|
|
127
|
+
|
|
128
|
+
- **Explicit resource ownership**: Repositories created from a URL own their
|
|
129
|
+
pool, while repositories created from an injected client leave lifecycle
|
|
130
|
+
control to the caller
|
package/dist/mod.d.ts
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { Actor, Announce, Create, Follow } from "@fedify/vocab";
|
|
2
|
+
import postgres from "postgres";
|
|
3
|
+
import { Repository, RepositoryGetFollowersOptions, RepositoryGetMessagesOptions, Uuid } from "@fedify/botkit/repository";
|
|
4
|
+
|
|
5
|
+
//#region src/mod.d.ts
|
|
6
|
+
type Queryable = Pick<postgres.Sql, "unsafe">;
|
|
7
|
+
/**
|
|
8
|
+
* Common options for creating a PostgreSQL repository.
|
|
9
|
+
* @since 0.4.0
|
|
10
|
+
*/
|
|
11
|
+
interface PostgresRepositoryOptionsBase {
|
|
12
|
+
/**
|
|
13
|
+
* The PostgreSQL schema name to use.
|
|
14
|
+
* @default `"botkit"`
|
|
15
|
+
*/
|
|
16
|
+
readonly schema?: string;
|
|
17
|
+
/**
|
|
18
|
+
* Whether to use prepared statements for queries.
|
|
19
|
+
* @default true
|
|
20
|
+
*/
|
|
21
|
+
readonly prepare?: boolean;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Options for creating a PostgreSQL repository from an injected client.
|
|
25
|
+
* @since 0.4.0
|
|
26
|
+
*/
|
|
27
|
+
interface PostgresRepositoryOptionsWithClient extends PostgresRepositoryOptionsBase {
|
|
28
|
+
/**
|
|
29
|
+
* A pre-configured PostgreSQL client to use.
|
|
30
|
+
*/
|
|
31
|
+
readonly sql: postgres.Sql;
|
|
32
|
+
/**
|
|
33
|
+
* Disallowed when `sql` is provided.
|
|
34
|
+
*/
|
|
35
|
+
readonly url?: never;
|
|
36
|
+
/**
|
|
37
|
+
* Disallowed when `sql` is provided.
|
|
38
|
+
*/
|
|
39
|
+
readonly maxConnections?: never;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Options for creating a PostgreSQL repository from a connection string.
|
|
43
|
+
* @since 0.4.0
|
|
44
|
+
*/
|
|
45
|
+
interface PostgresRepositoryOptionsWithUrl extends PostgresRepositoryOptionsBase {
|
|
46
|
+
/**
|
|
47
|
+
* A PostgreSQL connection string to connect with.
|
|
48
|
+
*/
|
|
49
|
+
readonly url: string | URL;
|
|
50
|
+
/**
|
|
51
|
+
* Disallowed when `url` is provided.
|
|
52
|
+
*/
|
|
53
|
+
readonly sql?: never;
|
|
54
|
+
/**
|
|
55
|
+
* The maximum number of connections for an owned pool.
|
|
56
|
+
*/
|
|
57
|
+
readonly maxConnections?: number;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Options for creating a PostgreSQL repository.
|
|
61
|
+
* @since 0.4.0
|
|
62
|
+
*/
|
|
63
|
+
type PostgresRepositoryOptions = PostgresRepositoryOptionsWithClient | PostgresRepositoryOptionsWithUrl;
|
|
64
|
+
/**
|
|
65
|
+
* Initializes the PostgreSQL schema used by BotKit repositories.
|
|
66
|
+
* @param sql The PostgreSQL client to initialize the schema with.
|
|
67
|
+
* @param schema The PostgreSQL schema name to initialize.
|
|
68
|
+
* @param prepare Whether to use prepared statements for schema queries.
|
|
69
|
+
* @since 0.4.0
|
|
70
|
+
*/
|
|
71
|
+
declare function initializePostgresRepositorySchema(sql: Queryable, schema?: string, prepare?: boolean): Promise<void>;
|
|
72
|
+
/**
|
|
73
|
+
* A repository for storing bot data using PostgreSQL.
|
|
74
|
+
* @since 0.4.0
|
|
75
|
+
*/
|
|
76
|
+
declare class PostgresRepository implements Repository, AsyncDisposable {
|
|
77
|
+
readonly sql: postgres.Sql;
|
|
78
|
+
readonly schema: string;
|
|
79
|
+
readonly prepare: boolean;
|
|
80
|
+
private readonly ownsSql;
|
|
81
|
+
private readonly ready;
|
|
82
|
+
constructor(options: PostgresRepositoryOptions);
|
|
83
|
+
[Symbol.asyncDispose](): Promise<void>;
|
|
84
|
+
/**
|
|
85
|
+
* Closes the underlying PostgreSQL connection pool if owned by the
|
|
86
|
+
* repository.
|
|
87
|
+
*/
|
|
88
|
+
close(): Promise<void>;
|
|
89
|
+
setKeyPairs(keyPairs: CryptoKeyPair[]): Promise<void>;
|
|
90
|
+
getKeyPairs(): Promise<CryptoKeyPair[] | undefined>;
|
|
91
|
+
addMessage(id: Uuid, activity: Create | Announce): Promise<void>;
|
|
92
|
+
updateMessage(id: Uuid, updater: (existing: Create | Announce) => Create | Announce | undefined | Promise<Create | Announce | undefined>): Promise<boolean>;
|
|
93
|
+
removeMessage(id: Uuid): Promise<Create | Announce | undefined>;
|
|
94
|
+
getMessages(options?: RepositoryGetMessagesOptions): AsyncIterable<Create | Announce>;
|
|
95
|
+
getMessage(id: Uuid): Promise<Create | Announce | undefined>;
|
|
96
|
+
countMessages(): Promise<number>;
|
|
97
|
+
addFollower(followId: URL, follower: Actor): Promise<void>;
|
|
98
|
+
removeFollower(followId: URL, followerId: URL): Promise<Actor | undefined>;
|
|
99
|
+
hasFollower(followerId: URL): Promise<boolean>;
|
|
100
|
+
getFollowers(options?: RepositoryGetFollowersOptions): AsyncIterable<Actor>;
|
|
101
|
+
countFollowers(): Promise<number>;
|
|
102
|
+
addSentFollow(id: Uuid, follow: Follow): Promise<void>;
|
|
103
|
+
removeSentFollow(id: Uuid): Promise<Follow | undefined>;
|
|
104
|
+
getSentFollow(id: Uuid): Promise<Follow | undefined>;
|
|
105
|
+
addFollowee(followeeId: URL, follow: Follow): Promise<void>;
|
|
106
|
+
removeFollowee(followeeId: URL): Promise<Follow | undefined>;
|
|
107
|
+
getFollowee(followeeId: URL): Promise<Follow | undefined>;
|
|
108
|
+
vote(messageId: Uuid, voterId: URL, option: string): Promise<void>;
|
|
109
|
+
countVoters(messageId: Uuid): Promise<number>;
|
|
110
|
+
countVotes(messageId: Uuid): Promise<Readonly<Record<string, number>>>;
|
|
111
|
+
private table;
|
|
112
|
+
private lockFollowRequest;
|
|
113
|
+
private lockFollower;
|
|
114
|
+
private lockFollowers;
|
|
115
|
+
private cleanupFollower;
|
|
116
|
+
private ensureReady;
|
|
117
|
+
private query;
|
|
118
|
+
}
|
|
119
|
+
//#endregion
|
|
120
|
+
export { PostgresRepository, PostgresRepositoryOptions, initializePostgresRepositorySchema };
|
|
121
|
+
//# sourceMappingURL=mod.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mod.d.ts","names":[],"sources":["../src/mod.ts"],"sourcesContent":[],"mappings":"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"}
|