From 2a30b4a536201e0ae4e2d748c48d2ec7503401b0 Mon Sep 17 00:00:00 2001 From: naskya Date: Mon, 22 Apr 2024 01:47:56 +0900 Subject: [PATCH] Revert "refactor (backend): it turns out that sending the entire note object was redundant" This reverts commit 3b65ebcb3e26d58db78f86c92fac9c06f199f18f. --- packages/backend-rs/index.d.ts | 2 +- .../src/service/add_note_to_antenna.rs | 11 ++- packages/backend-rs/src/service/stream.rs | 2 + packages/backend/package.json | 1 + .../backend/src/prelude/undefined-to-null.ts | 76 +++++++++++++++++++ packages/backend/src/services/note/create.ts | 4 +- pnpm-lock.yaml | 8 ++ 7 files changed, 98 insertions(+), 6 deletions(-) create mode 100644 packages/backend/src/prelude/undefined-to-null.ts diff --git a/packages/backend-rs/index.d.ts b/packages/backend-rs/index.d.ts index 1e086c88ff..7fd93a3845 100644 --- a/packages/backend-rs/index.d.ts +++ b/packages/backend-rs/index.d.ts @@ -1103,7 +1103,7 @@ export interface Webhook { latestSentAt: Date | null latestStatus: number | null } -export function addNoteToAntenna(antennaId: string, noteId: string): void +export function addNoteToAntenna(antennaId: string, note: Note): void /** Initializes Cuid2 generator. Must be called before any [create_id]. */ export function initIdGenerator(length: number, fingerprint: string): void export function getTimestamp(id: string): number diff --git a/packages/backend-rs/src/service/add_note_to_antenna.rs b/packages/backend-rs/src/service/add_note_to_antenna.rs index a92e8dc301..199a5cde5f 100644 --- a/packages/backend-rs/src/service/add_note_to_antenna.rs +++ b/packages/backend-rs/src/service/add_note_to_antenna.rs @@ -1,20 +1,23 @@ use crate::database::{redis_conn, redis_key}; use crate::service::stream::{publish_to_stream, Error, Stream}; +use crate::model::entity::note; use crate::util::id::get_timestamp; use redis::{streams::StreamMaxlen, Commands}; +type Note = note::Model; + #[crate::export] -pub fn add_note_to_antenna(antenna_id: String, note_id: &str) -> Result<(), Error> { +pub fn add_note_to_antenna(antenna_id: String, note: &Note) -> Result<(), Error> { redis_conn()?.xadd_maxlen( redis_key(format!("antennaTimeline:{}", antenna_id)), StreamMaxlen::Approx(200), - format!("{}-*", get_timestamp(note_id)), - &[("note", note_id)], + format!("{}-*", get_timestamp(¬e.id)), + &[("note", ¬e.id)], )?; publish_to_stream( &Stream::Antenna { antenna_id }, Some("note"), - Some(format!("{{ \"id\": \"{}\" }}", note_id)), + Some(serde_json::to_string(note)?), ) } diff --git a/packages/backend-rs/src/service/stream.rs b/packages/backend-rs/src/service/stream.rs index 3ef13961ce..6c5e6be4dd 100644 --- a/packages/backend-rs/src/service/stream.rs +++ b/packages/backend-rs/src/service/stream.rs @@ -41,6 +41,8 @@ pub enum Stream { pub enum Error { #[error("Redis error: {0}")] RedisError(#[from] RedisError), + #[error("Json (de)serialization error: {0}")] + JsonError(#[from] serde_json::Error), #[error("Value error: {0}")] ValueError(String), } diff --git a/packages/backend/package.json b/packages/backend/package.json index 9289c2f7ea..0599a39d4b 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -178,6 +178,7 @@ "ts-loader": "9.5.1", "ts-node": "10.9.2", "tsconfig-paths": "4.2.0", + "type-fest": "4.15.0", "typescript": "5.4.5", "webpack": "^5.91.0", "ws": "8.16.0" diff --git a/packages/backend/src/prelude/undefined-to-null.ts b/packages/backend/src/prelude/undefined-to-null.ts new file mode 100644 index 0000000000..013be3cf9e --- /dev/null +++ b/packages/backend/src/prelude/undefined-to-null.ts @@ -0,0 +1,76 @@ +// https://gist.github.com/tkrotoff/a6baf96eb6b61b445a9142e5555511a0 +import type { Primitive } from "type-fest"; + +type NullToUndefined = T extends null + ? undefined + : T extends Primitive | Function | Date | RegExp + ? T + : T extends Array + ? Array> + : T extends Map + ? Map> + : T extends Set + ? Set> + : T extends object + ? { [K in keyof T]: NullToUndefined } + : unknown; + +type UndefinedToNull = T extends undefined + ? null + : T extends Primitive | Function | Date | RegExp + ? T + : T extends Array + ? Array> + : T extends Map + ? Map> + : T extends Set + ? Set> + : T extends object + ? { [K in keyof T]: UndefinedToNull } + : unknown; + +function _nullToUndefined(obj: T): NullToUndefined { + if (obj === null) { + return undefined as any; + } + + if (typeof obj === "object") { + if (obj instanceof Map) { + obj.forEach((value, key) => obj.set(key, _nullToUndefined(value))); + } else { + for (const key in obj) { + obj[key] = _nullToUndefined(obj[key]) as any; + } + } + } + + return obj as any; +} + +function _undefinedToNull(obj: T): UndefinedToNull { + if (obj === undefined) { + return null as any; + } + + if (typeof obj === "object") { + if (obj instanceof Map) { + obj.forEach((value, key) => obj.set(key, _undefinedToNull(value))); + } else { + for (const key in obj) { + obj[key] = _undefinedToNull(obj[key]) as any; + } + } + } + + return obj as any; +} + +/** + * Recursively converts all undefined values to null. + * + * @param obj object to convert + * @returns a copy of the object with all its undefined values converted to null + */ +export function undefinedToNull(obj: T) { + return _undefinedToNull(structuredClone(obj)); +} diff --git a/packages/backend/src/services/note/create.ts b/packages/backend/src/services/note/create.ts index 8fa2b4e23b..206f6a50ad 100644 --- a/packages/backend/src/services/note/create.ts +++ b/packages/backend/src/services/note/create.ts @@ -62,6 +62,7 @@ import { Mutex } from "redis-semaphore"; import { langmap } from "@/misc/langmap.js"; import Logger from "@/services/logger.js"; import { inspect } from "node:util"; +import { undefinedToNull } from "@/prelude/undefined-to-null.js"; const logger = new Logger("create-note"); @@ -398,7 +399,8 @@ export default async ( for (const antenna of await getAntennas()) { checkHitAntenna(antenna, note, user).then((hit) => { if (hit) { - addNoteToAntenna(antenna.id, note.id); + // TODO: do this more sanely + addNoteToAntenna(antenna.id, undefinedToNull(note) as Note); } }); } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b591ffe9c1..16a4ad6ad4 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -521,6 +521,9 @@ importers: tsconfig-paths: specifier: 4.2.0 version: 4.2.0 + type-fest: + specifier: 4.15.0 + version: 4.15.0 typescript: specifier: 5.4.5 version: 5.4.5 @@ -16632,6 +16635,11 @@ packages: engines: {node: '>=8'} dev: true + /type-fest@4.15.0: + resolution: {integrity: sha512-tB9lu0pQpX5KJq54g+oHOLumOx+pMep4RaM6liXh2PKmVRFF+/vAtUP0ZaJ0kOySfVNjF6doBWPHhBhISKdlIA==} + engines: {node: '>=16'} + dev: true + /type-is@1.6.18: resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} engines: {node: '>= 0.6'}