From 1f00cd284fd8121a043949a8ff16f496b09d4145 Mon Sep 17 00:00:00 2001 From: Maxwell Date: Thu, 21 Nov 2024 19:32:41 +0200 Subject: [PATCH] refactor: migrate from npm mongo client to jsr --- deno.lock | 27 +++++++++++++++++++--- src/common/core/setup.ts | 2 +- src/common/mongo/collection.ts | 2 +- src/common/mongo/factory.ts | 41 +++++++++++++-------------------- src/common/mongo/types.ts | 6 ++--- src/common/mongo/utils.ts | 5 ++-- src/common/types/core.ts | 4 ++-- src/config/local/source.ts | 4 ++-- src/config/local/types.ts | 2 +- src/config/transformer/index.ts | 3 +-- src/import_map.json | 4 ++-- src/news/local/source.ts | 6 ++--- src/news/local/transformer.ts | 2 +- src/news/local/types.ts | 2 +- src/news/mapper.ts | 5 ++-- src/series/local/source.ts | 17 +++++++------- src/series/local/transformer.ts | 5 ++-- src/series/local/types.ts | 2 +- 18 files changed, 74 insertions(+), 65 deletions(-) diff --git a/deno.lock b/deno.lock index 783b89a..1033b9a 100644 --- a/deno.lock +++ b/deno.lock @@ -1,11 +1,13 @@ { "version": "4", "specifiers": { + "jsr:@db/mongo@0.33.0": "0.33.0", "jsr:@growthbook/growthbook@*": "1.2.2", "jsr:@growthbook/growthbook@1.2.2": "1.2.2", "jsr:@libs/typing@3": "3.1.0", "jsr:@libs/xml@*": "6.0.1", "jsr:@libs/xml@6.0.1": "6.0.1", + "jsr:@lucsoft/web-bson@~0.3.1": "0.3.1", "jsr:@oak/commons@0.10": "0.10.2", "jsr:@oak/commons@1": "1.0.0", "jsr:@oak/oak@*": "17.1.3", @@ -21,17 +23,19 @@ "jsr:@std/collections@*": "1.0.9", "jsr:@std/collections@1.0.9": "1.0.9", "jsr:@std/crypto@1": "1.0.3", + "jsr:@std/crypto@~0.220.1": "0.220.1", "jsr:@std/dotenv@*": "0.225.2", "jsr:@std/dotenv@0.225.2": "0.225.2", "jsr:@std/encoding@1": "1.0.5", "jsr:@std/encoding@^1.0.5": "1.0.5", + "jsr:@std/encoding@~0.220.1": "0.220.1", "jsr:@std/fmt@^1.0.2": "1.0.3", "jsr:@std/fmt@^1.0.3": "1.0.3", "jsr:@std/http@*": "1.0.9", "jsr:@std/http@1": "1.0.10", "jsr:@std/http@1.0.10": "1.0.10", "jsr:@std/io@0.224": "0.224.9", - "jsr:@std/media-types@1": "1.0.3", + "jsr:@std/media-types@1": "1.1.0", "jsr:@std/media-types@^1.0.3": "1.0.3", "jsr:@std/media-types@^1.1.0": "1.1.0", "jsr:@std/net@^1.0.4": "1.0.4", @@ -46,6 +50,14 @@ "npm:path-to-regexp@6.2.1": "6.2.1" }, "jsr": { + "@db/mongo@0.33.0": { + "integrity": "89312b9db63ad733920901d60faf8c667aa3cb0a64b67f8c3e74601465273e3a", + "dependencies": [ + "jsr:@lucsoft/web-bson", + "jsr:@std/crypto@~0.220.1", + "jsr:@std/encoding@~0.220.1" + ] + }, "@growthbook/growthbook@1.2.2": { "integrity": "12e31fd319094cac3c92a26bde429658b0fc254b57e4d50920b46097c88bae4d", "dependencies": [ @@ -61,6 +73,9 @@ "jsr:@libs/typing" ] }, + "@lucsoft/web-bson@0.3.1": { + "integrity": "dccad36fe5cc68286a4d3fe1993f7e7a81df0970c5946a5894dae9173adafe60" + }, "@oak/commons@0.10.2": { "integrity": "f47aebe12c3c73372ebe96250dbcd469d11f9e9df0cd89169d245bf674a347d5" }, @@ -69,7 +84,7 @@ "dependencies": [ "jsr:@std/assert", "jsr:@std/bytes@1", - "jsr:@std/crypto", + "jsr:@std/crypto@1", "jsr:@std/encoding@1", "jsr:@std/http@1", "jsr:@std/media-types@1" @@ -81,7 +96,7 @@ "jsr:@oak/commons@1", "jsr:@std/assert", "jsr:@std/bytes@1", - "jsr:@std/crypto", + "jsr:@std/crypto@1", "jsr:@std/http@1", "jsr:@std/io", "jsr:@std/media-types@1", @@ -110,12 +125,18 @@ "@std/collections@1.0.9": { "integrity": "4f58104ead08a04a2199374247f07befe50ba01d9cca8cbb23ab9a0419921e71" }, + "@std/crypto@0.220.1": { + "integrity": "4cec173974f33398041a3f66cc2f9b2fcc4a5ceaddd0e60840887d3bb7289d23" + }, "@std/crypto@1.0.3": { "integrity": "a2a32f51ddef632d299e3879cd027c630dcd4d1d9a5285d6e6788072f4e51e7f" }, "@std/dotenv@0.225.2": { "integrity": "e2025dce4de6c7bca21dece8baddd4262b09d5187217e231b033e088e0c4dd23" }, + "@std/encoding@0.220.1": { + "integrity": "8dc38dd72e36cd68857a5837e24eb09a64bb296b96c295239c75eec17d45d23f" + }, "@std/encoding@1.0.5": { "integrity": "ecf363d4fc25bd85bd915ff6733a7e79b67e0e7806334af15f4645c569fefc04" }, diff --git a/src/common/core/setup.ts b/src/common/core/setup.ts index d88b0d6..5e67cc2 100644 --- a/src/common/core/setup.ts +++ b/src/common/core/setup.ts @@ -55,7 +55,7 @@ const onTerminationRequest = (): void => { logger.debug( 'common.core.setup:onTerminationRequest: OS dispatched signal', ); - const token = setTimeout(async () => await _localSourceFactory.disconnect()); + const token = setTimeout(() => _localSourceFactory.disconnect()); logger.debug( 'common.core.setup:onTerminationRequest: Attempting to exit Deno process', ); diff --git a/src/common/mongo/collection.ts b/src/common/mongo/collection.ts index fcc35f7..1227511 100644 --- a/src/common/mongo/collection.ts +++ b/src/common/mongo/collection.ts @@ -1,4 +1,4 @@ -import { Document } from 'npm/mongodb'; +import { Document } from 'mongo'; import { Local } from '../types/core.ts'; export const collection = ( diff --git a/src/common/mongo/factory.ts b/src/common/mongo/factory.ts index 29595c0..1a64b36 100644 --- a/src/common/mongo/factory.ts +++ b/src/common/mongo/factory.ts @@ -1,52 +1,43 @@ -import { MongoClient } from 'npm/mongodb'; +import { MongoClient } from 'mongo'; import { logger } from '../core/logger.ts'; import { between } from 'optic'; import { env } from '../core/env.ts'; import { Local } from '../types/core.ts'; class LocalSourceFactory { - constructor(private readonly client: MongoClient) { - logger.mark('mongo_connection_start'); - client.on('timeout', () => { - logger.warn( - 'common.mongo.factory:LocalSourceFactory: Connection timed out', - ); - }); - } + constructor(private readonly client: MongoClient) {} connect = async (): Promise => { - return await this.client.connect() + logger.mark('mongo_connection_start'); + return await this.client.connect(env('MONGO_URL')) .then((client) => { logger.mark('mongo_connection_end'); logger.measure( between('mongo_connection_start', 'mongo_connection_end'), ); - return client.db(); + return client; }) - .catch((e) => { + .catch((e: unknown) => { logger.error('common.mongo.factory:connect:', e); return undefined; }); }; - disconnect = async () => { + disconnect = () => { logger.mark('mongo_close_start'); - await this.client.close(true) - .then(() => { - }).catch((e) => { - logger.error('common.mongo.factory:disconnect:', e); - }).finally(() => { - logger.mark('mongo_close_end'); - logger.measure(between('mongo_close_start', 'mongo_close_end')); - }); + try { + this.client.close(); + } catch (e) { + logger.error('common.mongo.factory:disconnect:', e); + } finally { + logger.mark('mongo_close_end'); + logger.measure(between('mongo_close_start', 'mongo_close_end')); + } }; } const _localSourceFactory = new LocalSourceFactory( - new MongoClient(env('MONGO_URL'), { - connectTimeoutMS: 1000, - monitorCommands: true, - }), + new MongoClient(), ); export default _localSourceFactory; diff --git a/src/common/mongo/types.ts b/src/common/mongo/types.ts index 98b5641..f5373cf 100644 --- a/src/common/mongo/types.ts +++ b/src/common/mongo/types.ts @@ -1,13 +1,13 @@ -import { Document, OptionalId, SortDirection } from 'npm/mongodb'; +import { Document } from 'mongo'; export type Optional = T | undefined | null; export type ProjectionOption = { - [K in keyof OptionalId]?: 0 | 1; + [K in keyof T]?: 0 | 1; }; export type SortOption = { - [K in keyof OptionalId]?: SortDirection; + [K in keyof T]?: 1 | -1 | 'asc' | 'desc'; }; export interface EntityCursor { diff --git a/src/common/mongo/utils.ts b/src/common/mongo/utils.ts index 7514ffc..7881f1c 100644 --- a/src/common/mongo/utils.ts +++ b/src/common/mongo/utils.ts @@ -1,11 +1,10 @@ -import { Document, ObjectId, Sort } from 'npm/mongodb'; +import { Document, ObjectId } from 'mongo'; import { ProjectionOption, SortOption } from './types.ts'; export const projectionOf = ( projection: ProjectionOption, ) => projection; -export const sortOf = (option: SortOption): Sort => - option as Sort; +export const sortOf = (option: SortOption) => option; export const idOf = (id: ObjectId): string => id.toHexString(); diff --git a/src/common/types/core.ts b/src/common/types/core.ts index 2a84ec9..a47bd41 100644 --- a/src/common/types/core.ts +++ b/src/common/types/core.ts @@ -1,7 +1,7 @@ import { Context } from 'oak'; import { State } from './state.ts'; import { GrowthBook } from 'growthbook'; -import { Db } from 'npm/mongodb'; +import { Database } from 'mongo'; import { AppFeatures } from '../experiment/types.ts'; export type RCF822Date = string; @@ -14,4 +14,4 @@ export type AppContext = Context; export type Features = GrowthBook; -export type Local = Db | undefined; +export type Local = Database | undefined; diff --git a/src/config/local/source.ts b/src/config/local/source.ts index 807369f..a344924 100644 --- a/src/config/local/source.ts +++ b/src/config/local/source.ts @@ -1,4 +1,4 @@ -import { Collection, WithId } from 'npm/mongodb'; +import { Collection } from 'mongo'; import { logger } from '../../common/core/logger.ts'; import { ConfigDocument } from './types.ts'; import { Optional } from '../../common/mongo/types.ts'; @@ -8,7 +8,7 @@ export class LocalSource { private readonly collection?: Collection, ) {} - getConfig = async (): Promise>> => { + getConfig = async (): Promise> => { const config = await this.collection?.findOne() ?.catch((e) => { logger.error( diff --git a/src/config/local/types.ts b/src/config/local/types.ts index 8a85442..d12b2c4 100644 --- a/src/config/local/types.ts +++ b/src/config/local/types.ts @@ -1,4 +1,4 @@ -import { Document } from 'npm/mongodb'; +import { Document } from 'mongo'; export interface NavigationConfig extends Document { criteria: string; diff --git a/src/config/transformer/index.ts b/src/config/transformer/index.ts index 4be4b8a..cf7cdf9 100644 --- a/src/config/transformer/index.ts +++ b/src/config/transformer/index.ts @@ -1,4 +1,3 @@ -import { WithId } from 'npm/mongodb'; import { getPlatformSource, isAnalyticsEnabled, @@ -19,7 +18,7 @@ const toImageUrl = (image: string, source?: PlatformSource): string => { export const transform: Transform< { - document: WithId; + document: ConfigDocument; features: Features; }, ClientConfiguration diff --git a/src/import_map.json b/src/import_map.json index d8d4c09..f6f2055 100644 --- a/src/import_map.json +++ b/src/import_map.json @@ -10,7 +10,7 @@ "deepmerge": "jsr:@rebeccastevens/deepmerge@7.1.3", "growthbook": "jsr:@growthbook/growthbook@1.2.2", "xml": "jsr:@libs/xml@6.0.1", - "npm/logtail": "npm:@logtail/node@0.5.2", - "npm/mongodb": "npm:mongodb@6.10.0" + "mongo": "jsr:@db/mongo@0.33.0", + "npm/logtail": "npm:@logtail/node@0.5.2" } } diff --git a/src/news/local/source.ts b/src/news/local/source.ts index 424c257..076aa34 100644 --- a/src/news/local/source.ts +++ b/src/news/local/source.ts @@ -1,4 +1,4 @@ -import { Collection, Filter, FindOptions, ObjectId, WithId } from 'npm/mongodb'; +import { Collection, Filter, FindOptions, ObjectId } from 'mongo'; import { logger } from '../../common/core/logger.ts'; import { IPaging } from '../../common/types/paging.ts'; import { IResponse } from '../../common/types/response.ts'; @@ -42,7 +42,7 @@ export default class LocalSource { const filter: Filter = { id: { $exists: true }, }; - const options: FindOptions> = { + const options: FindOptions = { projection: projectionOf({ published_on: 1 }), sort: sortOf({ published_on: 'desc' }), }; @@ -76,7 +76,7 @@ export default class LocalSource { _id: { $gt: new ObjectId(id.cursor) }, } : {}; - const options: FindOptions> = { + const options: FindOptions = { sort: sortOf({ published_on: 'desc' }), limit: 25, }; diff --git a/src/news/local/transformer.ts b/src/news/local/transformer.ts index 7413868..e881e27 100644 --- a/src/news/local/transformer.ts +++ b/src/news/local/transformer.ts @@ -1,4 +1,4 @@ -import { Document } from 'npm/mongodb'; +import { Document } from 'mongo'; import { Transform } from '../../common/transformer/types.ts'; import { News } from '../types.ts'; diff --git a/src/news/local/types.ts b/src/news/local/types.ts index 7c20689..4fc5908 100644 --- a/src/news/local/types.ts +++ b/src/news/local/types.ts @@ -1,4 +1,4 @@ -import { Document } from 'npm/mongodb'; +import { Document } from 'mongo'; import { EntityCursor } from '../../common/mongo/types.ts'; export interface NewsDocument extends Document { diff --git a/src/news/mapper.ts b/src/news/mapper.ts index 756ba55..d9b64ab 100644 --- a/src/news/mapper.ts +++ b/src/news/mapper.ts @@ -1,9 +1,8 @@ import { News, NewsEntity } from './types.ts'; import { NewsDocument } from './local/types.ts'; -import { OptionalId, WithId } from 'npm/mongodb'; import { idOf } from '../common/mongo/index.ts'; -export const toEntity = (data: WithId): NewsEntity => { +export const toEntity = (data: NewsDocument): NewsEntity => { return { id: idOf(data._id), slug: data.slug, @@ -18,7 +17,7 @@ export const toEntity = (data: WithId): NewsEntity => { }; }; -export const toDocument = (data: News): OptionalId => { +export const toDocument = (data: News): NewsDocument => { return { slug: data.slug, title: data.title, diff --git a/src/series/local/source.ts b/src/series/local/source.ts index d7113cd..35eb048 100644 --- a/src/series/local/source.ts +++ b/src/series/local/source.ts @@ -2,15 +2,15 @@ import { Collection, Document, Filter, - FindOneAndReplaceOptions, -} from 'npm/mongodb'; + FindAndModifyOptions, + FindOptions, +} from 'mongo'; import { logger } from '../../common/core/logger.ts'; import { IResponse } from '../../common/types/response.ts'; import { MediaWithSeason } from '../types.ts'; import { transform } from './transformer.ts'; import { MediaDocument } from './types.ts'; import { MediaParamId } from './types.ts'; -import { FindOptions } from 'npm/mongodb'; import { between } from 'optic'; export default class LocalSource { @@ -22,7 +22,7 @@ export default class LocalSource { const filter: Filter = { 'mediaId.anilist': mediaId.anilist, }; - const options: FindOptions = {}; + const options: FindOptions = {}; logger.mark('series_source_get_start'); const document = await this.collection ?.findOne(filter, options) @@ -56,15 +56,16 @@ export default class LocalSource { const filter: Filter = { 'mediaId.anilist': media.mediaId.anilist, }; - const options: FindOneAndReplaceOptions = { - upsert: true, - }; const replacement: MediaDocument = { ...media, }; + const options: FindAndModifyOptions = { + upsert: true, + update: replacement, + }; logger.mark('series_source_save_start'); - await this.collection?.findOneAndReplace(filter, replacement, options) + await this.collection?.findAndModify(filter, options) ?.then((result) => { logger.debug('seriese.local.source:save: Saved document', result?._id); logger.mark('series_source_save_end'); diff --git a/src/series/local/transformer.ts b/src/series/local/transformer.ts index ddbad4c..740211b 100644 --- a/src/series/local/transformer.ts +++ b/src/series/local/transformer.ts @@ -1,11 +1,10 @@ -import { WithId } from 'npm/mongodb'; import { Transform } from '../../common/transformer/types.ts'; import { MediaEntity } from '../types.ts'; import { idOf, Optional } from '../../common/mongo/index.ts'; import { MediaDocument } from './types.ts'; const map = ( - document: WithId, + document: MediaDocument, ): Optional => { return { id: idOf(document._id), @@ -33,6 +32,6 @@ const map = ( }; export const transform: Transform< - Optional>, + Optional, Optional > = (sourceData) => sourceData ? map(sourceData) : undefined; diff --git a/src/series/local/types.ts b/src/series/local/types.ts index ebb9c66..3892b1f 100644 --- a/src/series/local/types.ts +++ b/src/series/local/types.ts @@ -1,4 +1,4 @@ -import { Document } from 'npm/mongodb'; +import { Document } from 'mongo'; import { MediaWithSeason } from '../types.ts'; export interface MediaDocument extends Document, MediaWithSeason {