From 0bb76dc89511a4cd3c23b6ade0f6457ff0fbb9e6 Mon Sep 17 00:00:00 2001 From: Marc-Antoine Parent Date: Mon, 6 Jul 2026 16:22:02 -0400 Subject: [PATCH 1/3] eng-2004-converter-cross-app-node-to-localContent --- packages/database/src/crossAppContracts.ts | 10 +- .../database/src/lib/crossAppConverters.ts | 91 +++++++++++++++++++ 2 files changed, 96 insertions(+), 5 deletions(-) create mode 100644 packages/database/src/lib/crossAppConverters.ts diff --git a/packages/database/src/crossAppContracts.ts b/packages/database/src/crossAppContracts.ts index 55633fa96..c996332c3 100644 --- a/packages/database/src/crossAppContracts.ts +++ b/packages/database/src/crossAppContracts.ts @@ -1,7 +1,7 @@ import type { ContentType } from "@repo/content-model"; import { Enums } from "./dbTypes"; -type LocalRef = { +export type LocalRef = { // This localId is expected to be unique within the current space localId: string; }; @@ -12,24 +12,24 @@ type DbRef = { }; // Generalized reference -type Ref = LocalRef | DbRef; +export type Ref = LocalRef | DbRef; // Common attributes for most types -type CrossAppBase = LocalRef & { +export type CrossAppBase = LocalRef & { createdAt: Date; modifiedAt?: Date; author: Ref; }; // An inline vector semantic embedding -type CrossAppEmbedding = { +export type CrossAppEmbedding = { value: number[]; embedding?: Enums<"EmbeddingName">; }; // A Content object. It can be put inline inside a concept. // Missing CrossAppBase attributes are inferred from enclosing object. -type InlineCrossAppContent = Partial & { +export type InlineCrossAppContent = Partial & { value: string; embedding?: CrossAppEmbedding; scale?: Enums<"Scale">; diff --git a/packages/database/src/lib/crossAppConverters.ts b/packages/database/src/lib/crossAppConverters.ts new file mode 100644 index 000000000..25cdf8eed --- /dev/null +++ b/packages/database/src/lib/crossAppConverters.ts @@ -0,0 +1,91 @@ +import { + LocalRef, + Ref, + CrossAppEmbedding, + InlineCrossAppContent, + CrossAppBase, + CrossAppNode, +} from "../crossAppContracts"; +import { LocalContentDataInput } from "../inputTypes"; +import { Enums, CompositeTypes } from "../dbTypes"; + +type InlineEmbeddingInput = CompositeTypes<"inline_embedding_input">; +type InlineAbstractBase = Partial; + +const decodeLocalRef = ( + ref: LocalRef | InlineAbstractBase | undefined, + localVarName: LocalVarName, +): Record | Record => { + if (ref === undefined) return {}; + if ("localId" in ref) { + return { + [localVarName]: ref.localId, + } as Record; + } + return {}; +}; + +const decodeRef = ( + ref: Ref | undefined, + dbVarName: DbVarName, + localVarName: LocalVarName, +): + | Record + | Record + | Record => { + if (ref === undefined) return {}; + if ("dbId" in ref) + return { [dbVarName]: ref.dbId } as Record; + return decodeLocalRef(ref, localVarName); +}; + +const crossAppEmbeddingToDbEmbedding = ( + embedding: CrossAppEmbedding | undefined, +): InlineEmbeddingInput | undefined => + embedding === undefined + ? undefined + : { + vector: embedding.value, + model: embedding.embedding || "openai_text_embedding_3_small_1536", + }; + +const filterUndefined = >(data: T): T => { + return Object.fromEntries( + Object.entries(data).filter(([, v]) => v !== undefined), + ) as T; +}; + +const crossAppContentToDbContent = ( + content: InlineCrossAppContent | undefined, + variant: Enums<"ContentVariant">, + node?: CrossAppNode, +): LocalContentDataInput | undefined => { + if (content === undefined) return undefined; + return filterUndefined({ + ...decodeLocalRef(content, "source_local_id"), + text: content.value, + scale: content.scale || "document", + content_type: + content.contentType || + (variant === "full" ? document?.contentType : undefined) || + "text/plain", + variant: variant, + created: (content.createdAt || node?.createdAt)?.toISOString(), + last_modified: (content.modifiedAt || node?.modifiedAt)?.toISOString(), + ...decodeRef( + content.author || node?.author, + "author_id", + "author_local_id", + ), + embedding_inline: crossAppEmbeddingToDbEmbedding(content.embedding), + }); +}; + +export const crossAppInlineContentToDbContent = ( + node: CrossAppNode | undefined, + variant: "full" | "direct", +): LocalContentDataInput | undefined => { + if (node === undefined) return undefined; + const content = node.content[variant]; + return crossAppContentToDbContent(content, variant, node); +}; From 1fe7ec790e76c5edd26ae37d20ad97c19e80f785 Mon Sep 17 00:00:00 2001 From: Marc-Antoine Parent Date: Mon, 6 Jul 2026 16:27:15 -0400 Subject: [PATCH 2/3] Devin: document not part of the arguments anymore --- packages/database/src/lib/crossAppConverters.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/packages/database/src/lib/crossAppConverters.ts b/packages/database/src/lib/crossAppConverters.ts index 25cdf8eed..a56fae329 100644 --- a/packages/database/src/lib/crossAppConverters.ts +++ b/packages/database/src/lib/crossAppConverters.ts @@ -65,10 +65,7 @@ const crossAppContentToDbContent = ( ...decodeLocalRef(content, "source_local_id"), text: content.value, scale: content.scale || "document", - content_type: - content.contentType || - (variant === "full" ? document?.contentType : undefined) || - "text/plain", + content_type: content.contentType || "text/plain", variant: variant, created: (content.createdAt || node?.createdAt)?.toISOString(), last_modified: (content.modifiedAt || node?.modifiedAt)?.toISOString(), From 24cd0fdeb9cc34d095411cd002a60ac7f5a897f8 Mon Sep 17 00:00:00 2001 From: Marc-Antoine Parent Date: Tue, 7 Jul 2026 10:35:10 -0400 Subject: [PATCH 3/3] adjustments while using converters --- .../database/src/lib/crossAppConverters.ts | 27 ++++++++++--------- 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/packages/database/src/lib/crossAppConverters.ts b/packages/database/src/lib/crossAppConverters.ts index a56fae329..b6fa56494 100644 --- a/packages/database/src/lib/crossAppConverters.ts +++ b/packages/database/src/lib/crossAppConverters.ts @@ -55,10 +55,9 @@ const filterUndefined = >(data: T): T => { ) as T; }; -const crossAppContentToDbContent = ( +const inlineCrossAppContentToDbContent = ( content: InlineCrossAppContent | undefined, variant: Enums<"ContentVariant">, - node?: CrossAppNode, ): LocalContentDataInput | undefined => { if (content === undefined) return undefined; return filterUndefined({ @@ -66,23 +65,27 @@ const crossAppContentToDbContent = ( text: content.value, scale: content.scale || "document", content_type: content.contentType || "text/plain", - variant: variant, - created: (content.createdAt || node?.createdAt)?.toISOString(), - last_modified: (content.modifiedAt || node?.modifiedAt)?.toISOString(), - ...decodeRef( - content.author || node?.author, - "author_id", - "author_local_id", - ), + variant, + created: content.createdAt?.toISOString(), + last_modified: content.modifiedAt?.toISOString(), + ...decodeRef(content.author, "author_id", "author_local_id"), embedding_inline: crossAppEmbeddingToDbEmbedding(content.embedding), }); }; -export const crossAppInlineContentToDbContent = ( +export const crossAppNodeToDbContent = ( node: CrossAppNode | undefined, variant: "full" | "direct", ): LocalContentDataInput | undefined => { if (node === undefined) return undefined; const content = node.content[variant]; - return crossAppContentToDbContent(content, variant, node); + return inlineCrossAppContentToDbContent( + { + ...content, + createdAt: content.createdAt || node.createdAt, + modifiedAt: content.modifiedAt || node.modifiedAt, + author: content.author || node.author, + }, + variant, + ); };