diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index b183510d..bc5d02ae 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -28,6 +28,7 @@ jobs: with: node-version: "${{ matrix.node-version }}" - run: yarn --frozen-lockfile + - run: yarn add nedb --peer - run: yarn build && yarn test test-postgres: runs-on: ubuntu-22.04 @@ -50,6 +51,7 @@ jobs: steps: - uses: actions/checkout@v2 - run: yarn --frozen-lockfile + - run: yarn add nedb --peer - run: yarn test env: BRIDGE_TEST_PGDB: "bridge_integtest" diff --git a/changelog.d/488.removal b/changelog.d/488.removal new file mode 100644 index 00000000..f2f30ea1 --- /dev/null +++ b/changelog.d/488.removal @@ -0,0 +1 @@ +NeDB-based stores are now deprecated. You may still use them by adding "nedb" as a dependency to your project, but no new features or bugfixes are planned. diff --git a/package.json b/package.json index 6996ac6d..9afd1b16 100644 --- a/package.json +++ b/package.json @@ -40,7 +40,6 @@ "js-yaml": "^4.0.0", "matrix-appservice": "^2.0.0", "matrix-bot-sdk": "npm:@vector-im/matrix-bot-sdk@^0.6.6-element.1", - "nedb": "^1.8.0", "nopt": "^5.0.0", "p-queue": "^6.6.2", "pkginfo": "^0.4.1", @@ -70,5 +69,8 @@ "typedoc": "^0.23.28", "typescript": "^5.3.3", "winston-transport": "^4.6.0" + }, + "peerDependencies": { + "nedb": "^1.8.0" } } diff --git a/src/bridge.ts b/src/bridge.ts index 2d228405..6236832b 100644 --- a/src/bridge.ts +++ b/src/bridge.ts @@ -12,7 +12,8 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -import Datastore from "nedb"; +import type Datastore from "nedb"; +const nedb = import("nedb"); import {promises as fs} from "fs"; import * as util from "util"; import yaml from "js-yaml"; @@ -1720,61 +1721,23 @@ export class Bridge { } -function loadDatabase(path: string, Cls: new (db: Datastore) => T) { - const defer = deferPromise(); - const db = new Datastore({ - filename: path, - autoload: true, - onload: function(err) { - if (err) { - defer.reject(err); - } - else { - defer.resolve(new Cls(db)); +async function loadDatabase(path: string, Cls: new (db: Datastore) => T) { + try { + const datastoreFn = (await nedb).default; + return new Promise((resolve, reject) => { + const dbInstance = new datastoreFn({ + filename: path, + autoload: true, + onload: function(err) { + if (err) { + reject(err); + } + else { + resolve(new Cls(dbInstance)); + } } - } - }); - return defer.promise; -} - -function retryAlgorithm( - event: unknown, - attempts: number, - err: { - httpStatus: number, - cors?: string, - name: string, - // eslint-disable-next-line camelcase - data?: { retry_after_ms: number }, - } -) { - if (err.httpStatus === 400 || err.httpStatus === 403 || err.httpStatus === 401) { - // client error; no amount of retrying will save you now. - return -1; - } - // we ship with browser-request which returns { cors: rejected } when trying - // with no connection, so if we match that, give up since they have no conn. - if (err.cors === "rejected") { - return -1; - } - - if (err.name === "M_LIMIT_EXCEEDED") { - const waitTime = err.data?.retry_after_ms; - if (waitTime) { - return waitTime; - } - } - if (attempts > 4) { - return -1; // give up - } - return 1000 + (1000 * attempts); -} - -function queueAlgorithm(event: {getType: () => string, getRoomId(): string}) { - if (event.getType() === "m.room.message") { - // use a separate queue for each room ID - return "message_" + event.getRoomId(); + })}); + } catch (ex) { + throw Error('nedb could not be imported. You will need to add this package as a peer dependency.'); } - // allow all other events continue concurrently. - return null; } diff --git a/src/components/bridge-store.ts b/src/components/bridge-store.ts index 285f1ca7..b7e48932 100644 --- a/src/components/bridge-store.ts +++ b/src/components/bridge-store.ts @@ -16,7 +16,7 @@ limitations under the License. */ import { promisify } from "util"; -import Datastore from "nedb"; +import type Datastore from "nedb"; type Query = Record; diff --git a/src/components/event-bridge-store.ts b/src/components/event-bridge-store.ts index 30e2bbfb..491c18de 100644 --- a/src/components/event-bridge-store.ts +++ b/src/components/event-bridge-store.ts @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -import Datastore from "nedb"; +import type Datastore from "nedb"; import { BridgeStore } from "./bridge-store"; import { StoredEvent, StoredEventDoc } from "../models/events/event"; diff --git a/src/components/room-bridge-store.ts b/src/components/room-bridge-store.ts index 1ae033ab..725b4c9e 100644 --- a/src/components/room-bridge-store.ts +++ b/src/components/room-bridge-store.ts @@ -56,7 +56,7 @@ limitations under the License. * */ -import Datastore from "nedb"; +import type Datastore from "nedb"; import { BridgeStore } from "./bridge-store"; import { MatrixRoom, MatrixRoomData } from "../models/rooms/matrix"; import { RemoteRoom } from "../models/rooms/remote"; diff --git a/src/components/user-activity-store.ts b/src/components/user-activity-store.ts index 2e5c4194..15a7ae86 100644 --- a/src/components/user-activity-store.ts +++ b/src/components/user-activity-store.ts @@ -33,7 +33,7 @@ limitations under the License. * } * } */ -import Datastore from "nedb"; +import type Datastore from "nedb"; import { BridgeStore } from "./bridge-store"; import { UserActivity, UserActivitySet } from "./user-activity"; diff --git a/src/components/user-bridge-store.ts b/src/components/user-bridge-store.ts index b6672db6..5c7ae86f 100644 --- a/src/components/user-bridge-store.ts +++ b/src/components/user-bridge-store.ts @@ -51,7 +51,7 @@ limitations under the License. * matrix_id: "@foo:bar" * } */ -import Datastore from "nedb"; +import type Datastore from "nedb"; import { BridgeStore } from "./bridge-store"; import { MatrixUser } from "../models/users/matrix"; import { RemoteUser } from "../models/users/remote";