@atproto/bsync 0.0.28 → 0.0.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/CHANGELOG.md +12 -0
- package/dist/db/index.d.ts +4 -5
- package/dist/db/index.d.ts.map +1 -1
- package/dist/db/index.js +2 -1
- package/dist/db/index.js.map +1 -1
- package/dist/db/migrations/provider.d.ts +1 -1
- package/dist/db/migrations/provider.d.ts.map +1 -1
- package/dist/db/migrations/provider.js.map +1 -1
- package/dist/db/types.d.ts +1 -1
- package/dist/db/types.d.ts.map +1 -1
- package/dist/db/types.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +18 -10
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/src/db/index.ts +1 -1
- package/src/db/migrations/provider.ts +1 -1
- package/src/db/types.ts +3 -1
- package/src/index.ts +22 -13
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @atproto/bsync
|
|
2
2
|
|
|
3
|
+
## 0.0.30
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#5117](https://github.com/bluesky-social/atproto/pull/5117) [`8a4c88b`](https://github.com/bluesky-social/atproto/commit/8a4c88b0f63fb2d82b1391d64c54e0c760fac48b) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Use http-terminator to close http server
|
|
8
|
+
|
|
9
|
+
## 0.0.29
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- [#5086](https://github.com/bluesky-social/atproto/pull/5086) [`20665c1`](https://github.com/bluesky-social/atproto/commit/20665c18322effe648f73d70fc1a8dcc7e312992) Thanks [@devinivy](https://github.com/devinivy)! - Upgrade kysely from 0.22 to 0.29
|
|
14
|
+
|
|
3
15
|
## 0.0.28
|
|
4
16
|
|
|
5
17
|
### Patch Changes
|
package/dist/db/index.d.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { Migrator } from 'kysely';
|
|
2
|
-
|
|
3
|
-
declare const PgPool: typeof pg.Pool;
|
|
1
|
+
import { Migrator } from 'kysely/migration';
|
|
2
|
+
declare const PgPool: typeof import("pg").Pool;
|
|
4
3
|
type PgPool = InstanceType<typeof PgPool>;
|
|
5
4
|
import type TypedEmitter from 'typed-emitter';
|
|
6
5
|
import { DatabaseSchema } from './schema/index.js';
|
|
@@ -23,8 +22,8 @@ export declare class Database {
|
|
|
23
22
|
transaction<T>(fn: (db: Database) => Promise<T>): Promise<T>;
|
|
24
23
|
onCommit(fn: () => void): void;
|
|
25
24
|
close(): Promise<void>;
|
|
26
|
-
migrateToOrThrow(migration: string): Promise<import("kysely").MigrationResult[]>;
|
|
27
|
-
migrateToLatestOrThrow(): Promise<import("kysely").MigrationResult[]>;
|
|
25
|
+
migrateToOrThrow(migration: string): Promise<import("kysely/migration").MigrationResult[]>;
|
|
26
|
+
migrateToLatestOrThrow(): Promise<import("kysely/migration").MigrationResult[]>;
|
|
28
27
|
}
|
|
29
28
|
export default Database;
|
|
30
29
|
type TxnEmitter = TypedEmitter.default<TxnEvents>;
|
package/dist/db/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/db/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/db/index.ts"],"names":[],"mappings":"AAYA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAI3C,QAAA,MAAc,MAAM,0BAAuB,CAAA;AAC3C,KAAK,MAAM,GAAG,YAAY,CAAC,OAAO,MAAM,CAAC,CAAA;AACzC,OAAO,KAAK,YAAY,MAAM,eAAe,CAAA;AAI7C,OAAO,EAAE,cAAc,EAAsB,MAAM,mBAAmB,CAAA;AACtE,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AAEtC,qBAAa,QAAQ;IAQV,IAAI,EAAE,SAAS;IAPxB,IAAI,EAAE,MAAM,CAAA;IACZ,EAAE,EAAE,cAAc,CAAA;IAClB,QAAQ,EAAE,QAAQ,CAAA;IAClB,KAAK,EAAyB,UAAU,CAAA;IACxC,SAAS,UAAQ;IAEjB,YACS,IAAI,EAAE,SAAS,EACtB,SAAS,CAAC,EAAE;QAAE,EAAE,EAAE,cAAc,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAgDjD;IAED,IAAI,MAAM,IAAI,MAAM,GAAG,SAAS,CAE/B;IAED,IAAI,aAAa,YAEhB;IAED,iBAAiB,SAEhB;IAED,oBAAoB,SAEnB;IAEK,WAAW,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAsBjE;IAED,QAAQ,CAAC,EAAE,EAAE,MAAM,IAAI,QAGtB;IAEK,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAI3B;IAEK,gBAAgB,CAAC,SAAS,EAAE,MAAM,yDAYvC;IAEK,sBAAsB,0DAY3B;CACF;eAEc,QAAQ;AA6BvB,KAAK,UAAU,GAAG,YAAY,CAAC,OAAO,CAAC,SAAS,CAAC,CAAA;AAEjD,KAAK,SAAS,GAAG;IACf,MAAM,EAAE,MAAM,IAAI,CAAA;CACnB,CAAA"}
|
package/dist/db/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import assert from 'node:assert';
|
|
2
2
|
import { EventEmitter } from 'node:events';
|
|
3
|
-
import { Kysely,
|
|
3
|
+
import { Kysely, PostgresDialect, } from 'kysely';
|
|
4
|
+
import { Migrator } from 'kysely/migration';
|
|
4
5
|
// eslint-disable-next-line import/default
|
|
5
6
|
import pg from 'pg';
|
|
6
7
|
// eslint-disable-next-line import/no-named-as-default-member
|
package/dist/db/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/db/index.ts"],"names":[],"mappings":"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","sourcesContent":["import assert from 'node:assert'\nimport { EventEmitter } from 'node:events'\nimport {\n Kysely,\n KyselyPlugin,\n Migrator,\n PluginTransformQueryArgs,\n PluginTransformResultArgs,\n PostgresDialect,\n QueryResult,\n RootOperationNode,\n UnknownRow,\n} from 'kysely'\n// eslint-disable-next-line import/default\nimport pg from 'pg'\n// eslint-disable-next-line import/no-named-as-default-member\nconst { Pool: PgPool, types: pgTypes } = pg\ntype PgPool = InstanceType<typeof PgPool>\nimport type TypedEmitter from 'typed-emitter'\nimport { dbLogger } from '../logger.js'\nimport * as migrations from './migrations/index.js'\nimport { DbMigrationProvider } from './migrations/provider.js'\nimport { DatabaseSchema, DatabaseSchemaType } from './schema/index.js'\nimport { PgOptions } from './types.js'\n\nexport class Database {\n pool: PgPool\n db: DatabaseSchema\n migrator: Migrator\n txEvt = new EventEmitter() as TxnEmitter\n destroyed = false\n\n constructor(\n public opts: PgOptions,\n instances?: { db: DatabaseSchema; pool: PgPool },\n ) {\n // if instances are provided, use those\n if (instances) {\n this.db = instances.db\n this.pool = instances.pool\n } else {\n // else create a pool & connect\n const { schema, url } = opts\n const pool =\n opts.pool ??\n new PgPool({\n connectionString: url,\n max: opts.poolSize,\n maxUses: opts.poolMaxUses,\n idleTimeoutMillis: opts.poolIdleTimeoutMs,\n })\n\n // Select count(*) and other pg bigints as js integer\n pgTypes.setTypeParser(pgTypes.builtins.INT8, (n) => parseInt(n, 10))\n\n // Setup schema usage, primarily for test parallelism (each test suite runs in its own pg schema)\n if (schema && !/^[a-z_]+$/i.test(schema)) {\n throw new Error(\n `Postgres schema must only contain [A-Za-z_]: ${schema}`,\n )\n }\n\n pool.on('error', onPoolError)\n pool.on('connect', (client) => {\n client.on('error', onClientError)\n if (schema) {\n // Shared objects such as extensions will go in the public schema\n client.query(`SET search_path TO \"${schema}\",public;`)\n }\n })\n\n this.pool = pool\n this.db = new Kysely<DatabaseSchemaType>({\n dialect: new PostgresDialect({ pool }),\n })\n }\n\n this.migrator = new Migrator({\n db: this.db,\n migrationTableSchema: opts.schema,\n provider: new DbMigrationProvider(migrations),\n })\n }\n\n get schema(): string | undefined {\n return this.opts.schema\n }\n\n get isTransaction() {\n return this.db.isTransaction\n }\n\n assertTransaction() {\n assert(this.isTransaction, 'Transaction required')\n }\n\n assertNotTransaction() {\n assert(!this.isTransaction, 'Cannot be in a transaction')\n }\n\n async transaction<T>(fn: (db: Database) => Promise<T>): Promise<T> {\n const leakyTxPlugin = new LeakyTxPlugin()\n const { dbTxn, txRes } = await this.db\n .withPlugin(leakyTxPlugin)\n .transaction()\n .execute(async (txn) => {\n const dbTxn = new Database(this.opts, {\n db: txn,\n pool: this.pool,\n })\n const txRes = await fn(dbTxn)\n .catch(async (err) => {\n leakyTxPlugin.endTx()\n // ensure that all in-flight queries are flushed & the connection is open\n await dbTxn.db.getExecutor().provideConnection(noopAsync)\n throw err\n })\n .finally(() => leakyTxPlugin.endTx())\n return { dbTxn, txRes }\n })\n dbTxn?.txEvt.emit('commit')\n return txRes\n }\n\n onCommit(fn: () => void) {\n this.assertTransaction()\n this.txEvt.once('commit', fn)\n }\n\n async close(): Promise<void> {\n if (this.destroyed) return\n await this.db.destroy()\n this.destroyed = true\n }\n\n async migrateToOrThrow(migration: string) {\n if (this.schema) {\n await this.db.schema.createSchema(this.schema).ifNotExists().execute()\n }\n const { error, results } = await this.migrator.migrateTo(migration)\n if (error) {\n throw error\n }\n if (!results) {\n throw new Error('An unknown failure occurred while migrating')\n }\n return results\n }\n\n async migrateToLatestOrThrow() {\n if (this.schema) {\n await this.db.schema.createSchema(this.schema).ifNotExists().execute()\n }\n const { error, results } = await this.migrator.migrateToLatest()\n if (error) {\n throw error\n }\n if (!results) {\n throw new Error('An unknown failure occurred while migrating')\n }\n return results\n }\n}\n\nexport default Database\n\nconst onPoolError = (err: Error) => dbLogger.error({ err }, 'db pool error')\nconst onClientError = (err: Error) => dbLogger.error({ err }, 'db client error')\n\n// utils\n// -------\n\nclass LeakyTxPlugin implements KyselyPlugin {\n private txOver = false\n\n endTx() {\n this.txOver = true\n }\n\n transformQuery(args: PluginTransformQueryArgs): RootOperationNode {\n if (this.txOver) {\n throw new Error('tx already failed')\n }\n return args.node\n }\n\n async transformResult(\n args: PluginTransformResultArgs,\n ): Promise<QueryResult<UnknownRow>> {\n return args.result\n }\n}\n\ntype TxnEmitter = TypedEmitter.default<TxnEvents>\n\ntype TxnEvents = {\n commit: () => void\n}\n\nconst noopAsync = async () => {}\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/db/index.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,aAAa,CAAA;AAChC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAC1C,OAAO,EACL,MAAM,EAIN,eAAe,GAIhB,MAAM,QAAQ,CAAA;AACf,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAC3C,0CAA0C;AAC1C,OAAO,EAAE,MAAM,IAAI,CAAA;AACnB,6DAA6D;AAC7D,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,CAAA;AAG3C,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAA;AACvC,OAAO,KAAK,UAAU,MAAM,uBAAuB,CAAA;AACnD,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAA;AAI9D,MAAM,OAAO,QAAQ;IAOnB,YACS,IAAe,EACtB,SAAgD;QADzC,SAAI,GAAJ,IAAI,CAAW;QAJxB,UAAK,GAAG,IAAI,YAAY,EAAgB,CAAA;QACxC,cAAS,GAAG,KAAK,CAAA;QAMf,uCAAuC;QACvC,IAAI,SAAS,EAAE,CAAC;YACd,IAAI,CAAC,EAAE,GAAG,SAAS,CAAC,EAAE,CAAA;YACtB,IAAI,CAAC,IAAI,GAAG,SAAS,CAAC,IAAI,CAAA;QAC5B,CAAC;aAAM,CAAC;YACN,+BAA+B;YAC/B,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,IAAI,CAAA;YAC5B,MAAM,IAAI,GACR,IAAI,CAAC,IAAI;gBACT,IAAI,MAAM,CAAC;oBACT,gBAAgB,EAAE,GAAG;oBACrB,GAAG,EAAE,IAAI,CAAC,QAAQ;oBAClB,OAAO,EAAE,IAAI,CAAC,WAAW;oBACzB,iBAAiB,EAAE,IAAI,CAAC,iBAAiB;iBAC1C,CAAC,CAAA;YAEJ,qDAAqD;YACrD,OAAO,CAAC,aAAa,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAA;YAEpE,iGAAiG;YACjG,IAAI,MAAM,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;gBACzC,MAAM,IAAI,KAAK,CACb,gDAAgD,MAAM,EAAE,CACzD,CAAA;YACH,CAAC;YAED,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,WAAW,CAAC,CAAA;YAC7B,IAAI,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,MAAM,EAAE,EAAE;gBAC5B,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,aAAa,CAAC,CAAA;gBACjC,IAAI,MAAM,EAAE,CAAC;oBACX,iEAAiE;oBACjE,MAAM,CAAC,KAAK,CAAC,uBAAuB,MAAM,WAAW,CAAC,CAAA;gBACxD,CAAC;YACH,CAAC,CAAC,CAAA;YAEF,IAAI,CAAC,IAAI,GAAG,IAAI,CAAA;YAChB,IAAI,CAAC,EAAE,GAAG,IAAI,MAAM,CAAqB;gBACvC,OAAO,EAAE,IAAI,eAAe,CAAC,EAAE,IAAI,EAAE,CAAC;aACvC,CAAC,CAAA;QACJ,CAAC;QAED,IAAI,CAAC,QAAQ,GAAG,IAAI,QAAQ,CAAC;YAC3B,EAAE,EAAE,IAAI,CAAC,EAAE;YACX,oBAAoB,EAAE,IAAI,CAAC,MAAM;YACjC,QAAQ,EAAE,IAAI,mBAAmB,CAAC,UAAU,CAAC;SAC9C,CAAC,CAAA;IACJ,CAAC;IAED,IAAI,MAAM;QACR,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,CAAA;IACzB,CAAC;IAED,IAAI,aAAa;QACf,OAAO,IAAI,CAAC,EAAE,CAAC,aAAa,CAAA;IAC9B,CAAC;IAED,iBAAiB;QACf,MAAM,CAAC,IAAI,CAAC,aAAa,EAAE,sBAAsB,CAAC,CAAA;IACpD,CAAC;IAED,oBAAoB;QAClB,MAAM,CAAC,CAAC,IAAI,CAAC,aAAa,EAAE,4BAA4B,CAAC,CAAA;IAC3D,CAAC;IAED,KAAK,CAAC,WAAW,CAAI,EAAgC;QACnD,MAAM,aAAa,GAAG,IAAI,aAAa,EAAE,CAAA;QACzC,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,EAAE;aACnC,UAAU,CAAC,aAAa,CAAC;aACzB,WAAW,EAAE;aACb,OAAO,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;YACrB,MAAM,KAAK,GAAG,IAAI,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE;gBACpC,EAAE,EAAE,GAAG;gBACP,IAAI,EAAE,IAAI,CAAC,IAAI;aAChB,CAAC,CAAA;YACF,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,KAAK,CAAC;iBAC1B,KAAK,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;gBACnB,aAAa,CAAC,KAAK,EAAE,CAAA;gBACrB,yEAAyE;gBACzE,MAAM,KAAK,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAA;gBACzD,MAAM,GAAG,CAAA;YACX,CAAC,CAAC;iBACD,OAAO,CAAC,GAAG,EAAE,CAAC,aAAa,CAAC,KAAK,EAAE,CAAC,CAAA;YACvC,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAA;QACzB,CAAC,CAAC,CAAA;QACJ,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;QAC3B,OAAO,KAAK,CAAA;IACd,CAAC;IAED,QAAQ,CAAC,EAAc;QACrB,IAAI,CAAC,iBAAiB,EAAE,CAAA;QACxB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAA;IAC/B,CAAC;IAED,KAAK,CAAC,KAAK;QACT,IAAI,IAAI,CAAC,SAAS;YAAE,OAAM;QAC1B,MAAM,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,CAAA;QACvB,IAAI,CAAC,SAAS,GAAG,IAAI,CAAA;IACvB,CAAC;IAED,KAAK,CAAC,gBAAgB,CAAC,SAAiB;QACtC,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,MAAM,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,CAAC,OAAO,EAAE,CAAA;QACxE,CAAC;QACD,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,SAAS,CAAC,CAAA;QACnE,IAAI,KAAK,EAAE,CAAC;YACV,MAAM,KAAK,CAAA;QACb,CAAC;QACD,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAA;QAChE,CAAC;QACD,OAAO,OAAO,CAAA;IAChB,CAAC;IAED,KAAK,CAAC,sBAAsB;QAC1B,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,MAAM,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,CAAC,OAAO,EAAE,CAAA;QACxE,CAAC;QACD,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,eAAe,EAAE,CAAA;QAChE,IAAI,KAAK,EAAE,CAAC;YACV,MAAM,KAAK,CAAA;QACb,CAAC;QACD,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAA;QAChE,CAAC;QACD,OAAO,OAAO,CAAA;IAChB,CAAC;CACF;AAED,eAAe,QAAQ,CAAA;AAEvB,MAAM,WAAW,GAAG,CAAC,GAAU,EAAE,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,EAAE,eAAe,CAAC,CAAA;AAC5E,MAAM,aAAa,GAAG,CAAC,GAAU,EAAE,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,EAAE,iBAAiB,CAAC,CAAA;AAEhF,QAAQ;AACR,UAAU;AAEV,MAAM,aAAa;IAAnB;QACU,WAAM,GAAG,KAAK,CAAA;IAkBxB,CAAC;IAhBC,KAAK;QACH,IAAI,CAAC,MAAM,GAAG,IAAI,CAAA;IACpB,CAAC;IAED,cAAc,CAAC,IAA8B;QAC3C,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAA;QACtC,CAAC;QACD,OAAO,IAAI,CAAC,IAAI,CAAA;IAClB,CAAC;IAED,KAAK,CAAC,eAAe,CACnB,IAA+B;QAE/B,OAAO,IAAI,CAAC,MAAM,CAAA;IACpB,CAAC;CACF;AAQD,MAAM,SAAS,GAAG,KAAK,IAAI,EAAE,GAAE,CAAC,CAAA","sourcesContent":["import assert from 'node:assert'\nimport { EventEmitter } from 'node:events'\nimport {\n Kysely,\n KyselyPlugin,\n PluginTransformQueryArgs,\n PluginTransformResultArgs,\n PostgresDialect,\n QueryResult,\n RootOperationNode,\n UnknownRow,\n} from 'kysely'\nimport { Migrator } from 'kysely/migration'\n// eslint-disable-next-line import/default\nimport pg from 'pg'\n// eslint-disable-next-line import/no-named-as-default-member\nconst { Pool: PgPool, types: pgTypes } = pg\ntype PgPool = InstanceType<typeof PgPool>\nimport type TypedEmitter from 'typed-emitter'\nimport { dbLogger } from '../logger.js'\nimport * as migrations from './migrations/index.js'\nimport { DbMigrationProvider } from './migrations/provider.js'\nimport { DatabaseSchema, DatabaseSchemaType } from './schema/index.js'\nimport { PgOptions } from './types.js'\n\nexport class Database {\n pool: PgPool\n db: DatabaseSchema\n migrator: Migrator\n txEvt = new EventEmitter() as TxnEmitter\n destroyed = false\n\n constructor(\n public opts: PgOptions,\n instances?: { db: DatabaseSchema; pool: PgPool },\n ) {\n // if instances are provided, use those\n if (instances) {\n this.db = instances.db\n this.pool = instances.pool\n } else {\n // else create a pool & connect\n const { schema, url } = opts\n const pool =\n opts.pool ??\n new PgPool({\n connectionString: url,\n max: opts.poolSize,\n maxUses: opts.poolMaxUses,\n idleTimeoutMillis: opts.poolIdleTimeoutMs,\n })\n\n // Select count(*) and other pg bigints as js integer\n pgTypes.setTypeParser(pgTypes.builtins.INT8, (n) => parseInt(n, 10))\n\n // Setup schema usage, primarily for test parallelism (each test suite runs in its own pg schema)\n if (schema && !/^[a-z_]+$/i.test(schema)) {\n throw new Error(\n `Postgres schema must only contain [A-Za-z_]: ${schema}`,\n )\n }\n\n pool.on('error', onPoolError)\n pool.on('connect', (client) => {\n client.on('error', onClientError)\n if (schema) {\n // Shared objects such as extensions will go in the public schema\n client.query(`SET search_path TO \"${schema}\",public;`)\n }\n })\n\n this.pool = pool\n this.db = new Kysely<DatabaseSchemaType>({\n dialect: new PostgresDialect({ pool }),\n })\n }\n\n this.migrator = new Migrator({\n db: this.db,\n migrationTableSchema: opts.schema,\n provider: new DbMigrationProvider(migrations),\n })\n }\n\n get schema(): string | undefined {\n return this.opts.schema\n }\n\n get isTransaction() {\n return this.db.isTransaction\n }\n\n assertTransaction() {\n assert(this.isTransaction, 'Transaction required')\n }\n\n assertNotTransaction() {\n assert(!this.isTransaction, 'Cannot be in a transaction')\n }\n\n async transaction<T>(fn: (db: Database) => Promise<T>): Promise<T> {\n const leakyTxPlugin = new LeakyTxPlugin()\n const { dbTxn, txRes } = await this.db\n .withPlugin(leakyTxPlugin)\n .transaction()\n .execute(async (txn) => {\n const dbTxn = new Database(this.opts, {\n db: txn,\n pool: this.pool,\n })\n const txRes = await fn(dbTxn)\n .catch(async (err) => {\n leakyTxPlugin.endTx()\n // ensure that all in-flight queries are flushed & the connection is open\n await dbTxn.db.getExecutor().provideConnection(noopAsync)\n throw err\n })\n .finally(() => leakyTxPlugin.endTx())\n return { dbTxn, txRes }\n })\n dbTxn?.txEvt.emit('commit')\n return txRes\n }\n\n onCommit(fn: () => void) {\n this.assertTransaction()\n this.txEvt.once('commit', fn)\n }\n\n async close(): Promise<void> {\n if (this.destroyed) return\n await this.db.destroy()\n this.destroyed = true\n }\n\n async migrateToOrThrow(migration: string) {\n if (this.schema) {\n await this.db.schema.createSchema(this.schema).ifNotExists().execute()\n }\n const { error, results } = await this.migrator.migrateTo(migration)\n if (error) {\n throw error\n }\n if (!results) {\n throw new Error('An unknown failure occurred while migrating')\n }\n return results\n }\n\n async migrateToLatestOrThrow() {\n if (this.schema) {\n await this.db.schema.createSchema(this.schema).ifNotExists().execute()\n }\n const { error, results } = await this.migrator.migrateToLatest()\n if (error) {\n throw error\n }\n if (!results) {\n throw new Error('An unknown failure occurred while migrating')\n }\n return results\n }\n}\n\nexport default Database\n\nconst onPoolError = (err: Error) => dbLogger.error({ err }, 'db pool error')\nconst onClientError = (err: Error) => dbLogger.error({ err }, 'db client error')\n\n// utils\n// -------\n\nclass LeakyTxPlugin implements KyselyPlugin {\n private txOver = false\n\n endTx() {\n this.txOver = true\n }\n\n transformQuery(args: PluginTransformQueryArgs): RootOperationNode {\n if (this.txOver) {\n throw new Error('tx already failed')\n }\n return args.node\n }\n\n async transformResult(\n args: PluginTransformResultArgs,\n ): Promise<QueryResult<UnknownRow>> {\n return args.result\n }\n}\n\ntype TxnEmitter = TypedEmitter.default<TxnEvents>\n\ntype TxnEvents = {\n commit: () => void\n}\n\nconst noopAsync = async () => {}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../../src/db/migrations/provider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../../src/db/migrations/provider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAA;AAE/D,qBAAa,mBAAoB,YAAW,iBAAiB;IAC/C,OAAO,CAAC,UAAU;IAA9B,YAAoB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,EAAI;IACvD,aAAa,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAExD;CACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"provider.js","sourceRoot":"","sources":["../../../src/db/migrations/provider.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,mBAAmB;IAC9B,YAAoB,UAAqC;0BAArC,UAAU;IAA8B,CAAC;IAC7D,KAAK,CAAC,aAAa;QACjB,OAAO,IAAI,CAAC,UAAU,CAAA;IACxB,CAAC;CACF","sourcesContent":["import { Migration, MigrationProvider } from 'kysely'\n\nexport class DbMigrationProvider implements MigrationProvider {\n constructor(private migrations: Record<string, Migration>) {}\n async getMigrations(): Promise<Record<string, Migration>> {\n return this.migrations\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"provider.js","sourceRoot":"","sources":["../../../src/db/migrations/provider.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,mBAAmB;IAC9B,YAAoB,UAAqC;0BAArC,UAAU;IAA8B,CAAC;IAC7D,KAAK,CAAC,aAAa;QACjB,OAAO,IAAI,CAAC,UAAU,CAAA;IACxB,CAAC;CACF","sourcesContent":["import { Migration, MigrationProvider } from 'kysely/migration'\n\nexport class DbMigrationProvider implements MigrationProvider {\n constructor(private migrations: Record<string, Migration>) {}\n async getMigrations(): Promise<Record<string, Migration>> {\n return this.migrations\n }\n}\n"]}
|
package/dist/db/types.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { DynamicModule, RawBuilder, SelectQueryBuilder } from 'kysely';
|
|
2
2
|
import pg from 'pg';
|
|
3
3
|
type PgPool = pg.Pool;
|
|
4
|
-
export type DbRef = RawBuilder | ReturnType<DynamicModule['ref']>;
|
|
4
|
+
export type DbRef = RawBuilder<unknown> | ReturnType<DynamicModule<unknown>['ref']>;
|
|
5
5
|
export type AnyQb = SelectQueryBuilder<any, any, any>;
|
|
6
6
|
export type PgOptions = {
|
|
7
7
|
url: string;
|
package/dist/db/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/db/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,QAAQ,CAAA;AAEtE,OAAO,EAAE,MAAM,IAAI,CAAA;AACnB,KAAK,MAAM,GAAG,EAAE,CAAC,IAAI,CAAA;AAErB,MAAM,MAAM,KAAK,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/db/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,QAAQ,CAAA;AAEtE,OAAO,EAAE,MAAM,IAAI,CAAA;AACnB,KAAK,MAAM,GAAG,EAAE,CAAC,IAAI,CAAA;AAErB,MAAM,MAAM,KAAK,GACb,UAAU,CAAC,OAAO,CAAC,GACnB,UAAU,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,CAAA;AAE7C,MAAM,MAAM,KAAK,GAAG,kBAAkB,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAA;AAErD,MAAM,MAAM,SAAS,GAAG;IACtB,GAAG,EAAE,MAAM,CAAA;IACX,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,iBAAiB,CAAC,EAAE,MAAM,CAAA;CAC3B,CAAA"}
|
package/dist/db/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/db/types.ts"],"names":[],"mappings":"","sourcesContent":["import { DynamicModule, RawBuilder, SelectQueryBuilder } from 'kysely'\n// eslint-disable-next-line import/default\nimport pg from 'pg'\ntype PgPool = pg.Pool\n\nexport type DbRef
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/db/types.ts"],"names":[],"mappings":"","sourcesContent":["import { DynamicModule, RawBuilder, SelectQueryBuilder } from 'kysely'\n// eslint-disable-next-line import/default\nimport pg from 'pg'\ntype PgPool = pg.Pool\n\nexport type DbRef =\n | RawBuilder<unknown>\n | ReturnType<DynamicModule<unknown>['ref']>\n\nexport type AnyQb = SelectQueryBuilder<any, any, any>\n\nexport type PgOptions = {\n url: string\n pool?: PgPool\n schema?: string\n poolSize?: number\n poolMaxUses?: number\n poolIdleTimeoutMs?: number\n}\n"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -9,9 +9,9 @@ export { httpLogger } from './logger.js';
|
|
|
9
9
|
export declare class BsyncService {
|
|
10
10
|
ctx: AppContext;
|
|
11
11
|
server: http.Server;
|
|
12
|
-
private ac;
|
|
13
12
|
private terminator;
|
|
14
|
-
private
|
|
13
|
+
private ac;
|
|
14
|
+
private state;
|
|
15
15
|
constructor(opts: {
|
|
16
16
|
ctx: AppContext;
|
|
17
17
|
server: http.Server;
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,IAAI,MAAM,WAAW,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,IAAI,MAAM,WAAW,CAAA;AAI5B,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAC1C,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAA;AAO5D,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AACxC,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AACzC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAIxC,qBAAa,YAAY;IAChB,GAAG,EAAE,UAAU,CAAA;IACf,MAAM,EAAE,IAAI,CAAC,MAAM,CAAA;IAC1B,OAAO,CAAC,UAAU,CAA+B;IACjD,OAAO,CAAC,EAAE,CAAiB;IAC3B,OAAO,CAAC,KAAK,CAAmC;IAEhD,YAAY,IAAI,EAAE;QAChB,GAAG,EAAE,UAAU,CAAA;QACf,MAAM,EAAE,IAAI,CAAC,MAAM,CAAA;QACnB,EAAE,EAAE,eAAe,CAAA;KACpB,EAKA;IAED,OAAa,MAAM,CACjB,GAAG,EAAE,YAAY,EACjB,SAAS,CAAC,EAAE,OAAO,CAAC,iBAAiB,CAAC,GACrC,OAAO,CAAC,YAAY,CAAC,CAiBvB;IAEK,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CA0BlC;IAEK,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAS7B;IAEK,cAAc,kBAoBnB;CACF;eAEc,YAAY"}
|
package/dist/index.js
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
import events from 'node:events';
|
|
2
2
|
import http from 'node:http';
|
|
3
3
|
import { connectNodeAdapter } from '@connectrpc/connect-node';
|
|
4
|
-
// eslint-disable-next-line import/default
|
|
4
|
+
// eslint-disable-next-line import/default
|
|
5
5
|
import httpTerminator from 'http-terminator';
|
|
6
|
-
// eslint-disable-next-line import/no-named-as-default-member
|
|
7
|
-
const { createHttpTerminator } = httpTerminator;
|
|
8
6
|
import { AppContext } from './context.js';
|
|
9
7
|
import { createMuteOpChannel } from './db/schema/mute_op.js';
|
|
10
8
|
import { createNotifOpChannel } from './db/schema/notif_op.js';
|
|
@@ -18,10 +16,11 @@ export { AppContext } from './context.js';
|
|
|
18
16
|
export { httpLogger } from './logger.js';
|
|
19
17
|
export class BsyncService {
|
|
20
18
|
constructor(opts) {
|
|
19
|
+
this.state = 'initialized';
|
|
21
20
|
this.ctx = opts.ctx;
|
|
22
21
|
this.server = opts.server;
|
|
23
22
|
this.ac = opts.ac;
|
|
24
|
-
this.terminator = createHttpTerminator(
|
|
23
|
+
this.terminator = httpTerminator.createHttpTerminator(opts);
|
|
25
24
|
}
|
|
26
25
|
static async create(cfg, overrides) {
|
|
27
26
|
const ac = new AbortController();
|
|
@@ -42,16 +41,20 @@ export class BsyncService {
|
|
|
42
41
|
return new BsyncService({ ctx, server, ac });
|
|
43
42
|
}
|
|
44
43
|
async start() {
|
|
45
|
-
if (this.
|
|
44
|
+
if (this.state !== 'initialized') {
|
|
46
45
|
throw new Error(`${this.constructor.name} already started`);
|
|
47
46
|
}
|
|
48
|
-
this.
|
|
47
|
+
this.state = 'started';
|
|
48
|
+
const dbStatsInterval = setInterval(() => {
|
|
49
49
|
dbLogger.info({
|
|
50
50
|
idleCount: this.ctx.db.pool.idleCount,
|
|
51
51
|
totalCount: this.ctx.db.pool.totalCount,
|
|
52
52
|
waitingCount: this.ctx.db.pool.waitingCount,
|
|
53
53
|
}, 'db pool stats');
|
|
54
54
|
}, 10000);
|
|
55
|
+
this.ac.signal.addEventListener('abort', () => {
|
|
56
|
+
clearInterval(dbStatsInterval);
|
|
57
|
+
});
|
|
55
58
|
await this.setupAppEvents();
|
|
56
59
|
this.server.listen(this.ctx.cfg.service.port);
|
|
57
60
|
this.server.keepAliveTimeout = 90000;
|
|
@@ -59,11 +62,16 @@ export class BsyncService {
|
|
|
59
62
|
return this.server;
|
|
60
63
|
}
|
|
61
64
|
async destroy() {
|
|
65
|
+
if (this.state === 'destroyed')
|
|
66
|
+
return;
|
|
67
|
+
this.state = 'destroyed';
|
|
62
68
|
this.ac.abort();
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
69
|
+
try {
|
|
70
|
+
await this.terminator.terminate();
|
|
71
|
+
}
|
|
72
|
+
finally {
|
|
73
|
+
await this.ctx.db.close();
|
|
74
|
+
}
|
|
67
75
|
}
|
|
68
76
|
async setupAppEvents() {
|
|
69
77
|
const conn = await this.ctx.db.pool.connect();
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,aAAa,CAAA;AAChC,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAA;AAC7D,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["import events from 'node:events'\nimport http from 'node:http'\nimport { connectNodeAdapter } from '@connectrpc/connect-node'\n// eslint-disable-next-line import/default\nimport httpTerminator from 'http-terminator'\nimport { ServerConfig } from './config.js'\nimport { AppContext, AppContextOptions } from './context.js'\nimport { createMuteOpChannel } from './db/schema/mute_op.js'\nimport { createNotifOpChannel } from './db/schema/notif_op.js'\nimport { createOperationChannel } from './db/schema/operation.js'\nimport { dbLogger, loggerMiddleware } from './logger.js'\nimport routes from './routes/index.js'\n\nexport * from './config.js'\nexport * from './client.js'\nexport { Database } from './db/index.js'\nexport { AppContext } from './context.js'\nexport { httpLogger } from './logger.js'\n\ntype BsyncServiceState = 'initialized' | 'started' | 'destroyed'\n\nexport class BsyncService {\n public ctx: AppContext\n public server: http.Server\n private terminator: httpTerminator.HttpTerminator\n private ac: AbortController\n private state: BsyncServiceState = 'initialized'\n\n constructor(opts: {\n ctx: AppContext\n server: http.Server\n ac: AbortController\n }) {\n this.ctx = opts.ctx\n this.server = opts.server\n this.ac = opts.ac\n this.terminator = httpTerminator.createHttpTerminator(opts)\n }\n\n static async create(\n cfg: ServerConfig,\n overrides?: Partial<AppContextOptions>,\n ): Promise<BsyncService> {\n const ac = new AbortController()\n const ctx = await AppContext.fromConfig(cfg, ac.signal, overrides)\n const handler = connectNodeAdapter({\n routes: routes(ctx),\n shutdownSignal: ac.signal,\n })\n const server = http.createServer((req, res) => {\n loggerMiddleware(req, res)\n if (isHealth(req.url)) {\n res.statusCode = 200\n res.setHeader('content-type', 'application/json')\n return res.end(JSON.stringify({ version: cfg.service.version }))\n }\n handler(req, res)\n })\n return new BsyncService({ ctx, server, ac })\n }\n\n async start(): Promise<http.Server> {\n if (this.state !== 'initialized') {\n throw new Error(`${this.constructor.name} already started`)\n }\n this.state = 'started'\n\n const dbStatsInterval = setInterval(() => {\n dbLogger.info(\n {\n idleCount: this.ctx.db.pool.idleCount,\n totalCount: this.ctx.db.pool.totalCount,\n waitingCount: this.ctx.db.pool.waitingCount,\n },\n 'db pool stats',\n )\n }, 10000)\n\n this.ac.signal.addEventListener('abort', () => {\n clearInterval(dbStatsInterval)\n })\n\n await this.setupAppEvents()\n this.server.listen(this.ctx.cfg.service.port)\n this.server.keepAliveTimeout = 90000\n await events.once(this.server, 'listening')\n return this.server\n }\n\n async destroy(): Promise<void> {\n if (this.state === 'destroyed') return\n this.state = 'destroyed'\n this.ac.abort()\n try {\n await this.terminator.terminate()\n } finally {\n await this.ctx.db.close()\n }\n }\n\n async setupAppEvents() {\n const conn = await this.ctx.db.pool.connect()\n this.ac.signal.addEventListener('abort', () => conn.release(), {\n once: true,\n })\n // if these error, unhandled rejection should cause process to exit\n conn.query(`listen ${createMuteOpChannel}`)\n conn.query(`listen ${createNotifOpChannel}`)\n conn.query(`listen ${createOperationChannel}`)\n conn.on('notification', (notif) => {\n if (notif.channel === createMuteOpChannel) {\n this.ctx.events.emit(createMuteOpChannel)\n }\n if (notif.channel === createNotifOpChannel) {\n this.ctx.events.emit(createNotifOpChannel)\n }\n if (notif.channel === createOperationChannel) {\n this.ctx.events.emit(createOperationChannel)\n }\n })\n }\n}\n\nexport default BsyncService\n\nconst isHealth = (urlStr: string | undefined) => {\n if (!urlStr) return false\n const url = new URL(urlStr, 'http://host')\n return url.pathname === '/_health'\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atproto/bsync",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.30",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "Sychronizing service for app.bsky App View (Bluesky API)",
|
|
6
6
|
"keywords": [
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"@connectrpc/connect": "^1.1.4",
|
|
22
22
|
"@connectrpc/connect-node": "^1.1.4",
|
|
23
23
|
"http-terminator": "^3.2.0",
|
|
24
|
-
"kysely": "^0.
|
|
24
|
+
"kysely": "^0.29.2",
|
|
25
25
|
"pg": "^8.10.0",
|
|
26
26
|
"pino-http": "^8.2.1",
|
|
27
27
|
"typed-emitter": "^2.1.0",
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"@bufbuild/buf": "^1.28.1",
|
|
33
33
|
"@bufbuild/protoc-gen-es": "^1.5.0",
|
|
34
34
|
"@connectrpc/protoc-gen-connect-es": "^1.1.4",
|
|
35
|
-
"@types/pg": "^8.
|
|
35
|
+
"@types/pg": "^8.15.5",
|
|
36
36
|
"get-port": "^5.1.1",
|
|
37
37
|
"jest": "^30.0.0",
|
|
38
38
|
"ts-node": "^10.8.2"
|
package/src/db/index.ts
CHANGED
|
@@ -3,7 +3,6 @@ import { EventEmitter } from 'node:events'
|
|
|
3
3
|
import {
|
|
4
4
|
Kysely,
|
|
5
5
|
KyselyPlugin,
|
|
6
|
-
Migrator,
|
|
7
6
|
PluginTransformQueryArgs,
|
|
8
7
|
PluginTransformResultArgs,
|
|
9
8
|
PostgresDialect,
|
|
@@ -11,6 +10,7 @@ import {
|
|
|
11
10
|
RootOperationNode,
|
|
12
11
|
UnknownRow,
|
|
13
12
|
} from 'kysely'
|
|
13
|
+
import { Migrator } from 'kysely/migration'
|
|
14
14
|
// eslint-disable-next-line import/default
|
|
15
15
|
import pg from 'pg'
|
|
16
16
|
// eslint-disable-next-line import/no-named-as-default-member
|
package/src/db/types.ts
CHANGED
|
@@ -3,7 +3,9 @@ import { DynamicModule, RawBuilder, SelectQueryBuilder } from 'kysely'
|
|
|
3
3
|
import pg from 'pg'
|
|
4
4
|
type PgPool = pg.Pool
|
|
5
5
|
|
|
6
|
-
export type DbRef =
|
|
6
|
+
export type DbRef =
|
|
7
|
+
| RawBuilder<unknown>
|
|
8
|
+
| ReturnType<DynamicModule<unknown>['ref']>
|
|
7
9
|
|
|
8
10
|
export type AnyQb = SelectQueryBuilder<any, any, any>
|
|
9
11
|
|
package/src/index.ts
CHANGED
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
import events from 'node:events'
|
|
2
2
|
import http from 'node:http'
|
|
3
3
|
import { connectNodeAdapter } from '@connectrpc/connect-node'
|
|
4
|
-
// eslint-disable-next-line import/default
|
|
4
|
+
// eslint-disable-next-line import/default
|
|
5
5
|
import httpTerminator from 'http-terminator'
|
|
6
|
-
// eslint-disable-next-line import/no-named-as-default-member
|
|
7
|
-
const { createHttpTerminator } = httpTerminator
|
|
8
|
-
type HttpTerminator = ReturnType<typeof createHttpTerminator>
|
|
9
6
|
import { ServerConfig } from './config.js'
|
|
10
7
|
import { AppContext, AppContextOptions } from './context.js'
|
|
11
8
|
import { createMuteOpChannel } from './db/schema/mute_op.js'
|
|
@@ -20,12 +17,14 @@ export { Database } from './db/index.js'
|
|
|
20
17
|
export { AppContext } from './context.js'
|
|
21
18
|
export { httpLogger } from './logger.js'
|
|
22
19
|
|
|
20
|
+
type BsyncServiceState = 'initialized' | 'started' | 'destroyed'
|
|
21
|
+
|
|
23
22
|
export class BsyncService {
|
|
24
23
|
public ctx: AppContext
|
|
25
24
|
public server: http.Server
|
|
25
|
+
private terminator: httpTerminator.HttpTerminator
|
|
26
26
|
private ac: AbortController
|
|
27
|
-
private
|
|
28
|
-
private dbStatsInterval?: NodeJS.Timeout
|
|
27
|
+
private state: BsyncServiceState = 'initialized'
|
|
29
28
|
|
|
30
29
|
constructor(opts: {
|
|
31
30
|
ctx: AppContext
|
|
@@ -35,7 +34,7 @@ export class BsyncService {
|
|
|
35
34
|
this.ctx = opts.ctx
|
|
36
35
|
this.server = opts.server
|
|
37
36
|
this.ac = opts.ac
|
|
38
|
-
this.terminator = createHttpTerminator(
|
|
37
|
+
this.terminator = httpTerminator.createHttpTerminator(opts)
|
|
39
38
|
}
|
|
40
39
|
|
|
41
40
|
static async create(
|
|
@@ -61,10 +60,12 @@ export class BsyncService {
|
|
|
61
60
|
}
|
|
62
61
|
|
|
63
62
|
async start(): Promise<http.Server> {
|
|
64
|
-
if (this.
|
|
63
|
+
if (this.state !== 'initialized') {
|
|
65
64
|
throw new Error(`${this.constructor.name} already started`)
|
|
66
65
|
}
|
|
67
|
-
this.
|
|
66
|
+
this.state = 'started'
|
|
67
|
+
|
|
68
|
+
const dbStatsInterval = setInterval(() => {
|
|
68
69
|
dbLogger.info(
|
|
69
70
|
{
|
|
70
71
|
idleCount: this.ctx.db.pool.idleCount,
|
|
@@ -74,6 +75,11 @@ export class BsyncService {
|
|
|
74
75
|
'db pool stats',
|
|
75
76
|
)
|
|
76
77
|
}, 10000)
|
|
78
|
+
|
|
79
|
+
this.ac.signal.addEventListener('abort', () => {
|
|
80
|
+
clearInterval(dbStatsInterval)
|
|
81
|
+
})
|
|
82
|
+
|
|
77
83
|
await this.setupAppEvents()
|
|
78
84
|
this.server.listen(this.ctx.cfg.service.port)
|
|
79
85
|
this.server.keepAliveTimeout = 90000
|
|
@@ -82,11 +88,14 @@ export class BsyncService {
|
|
|
82
88
|
}
|
|
83
89
|
|
|
84
90
|
async destroy(): Promise<void> {
|
|
91
|
+
if (this.state === 'destroyed') return
|
|
92
|
+
this.state = 'destroyed'
|
|
85
93
|
this.ac.abort()
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
94
|
+
try {
|
|
95
|
+
await this.terminator.terminate()
|
|
96
|
+
} finally {
|
|
97
|
+
await this.ctx.db.close()
|
|
98
|
+
}
|
|
90
99
|
}
|
|
91
100
|
|
|
92
101
|
async setupAppEvents() {
|