From f85c042a948ab3e05c5dd6764eecc5b30f004259 Mon Sep 17 00:00:00 2001 From: Marcus Schiesser <mail@marcusschiesser.de> Date: Thu, 4 Jan 2024 10:05:47 +0700 Subject: [PATCH] refactor: encapsulate node serialization --- packages/core/src/Node.ts | 19 +++++++++++++++++-- .../indices/vectorStore/VectorStoreIndex.ts | 3 +-- .../core/src/storage/vectorStore/utils.ts | 3 +-- 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/packages/core/src/Node.ts b/packages/core/src/Node.ts index 386c37b44..fef42df93 100644 --- a/packages/core/src/Node.ts +++ b/packages/core/src/Node.ts @@ -1,3 +1,4 @@ +import _ from "lodash"; import { createHash } from "node:crypto"; import path from "path"; import { v4 as uuidv4 } from "uuid"; @@ -141,12 +142,26 @@ export abstract class BaseNode<T extends Metadata = Metadata> { } /** - * Used with built in JSON.stringify - * @returns + * Called by built in JSON.stringify (see https://javascript.info/json) + * Properties are read-only as they are not deep-cloned (not necessary for stringification). + * @see toMutableJSON - use to return a mutable JSON instead */ toJSON(): Record<string, any> { return { ...this, type: this.getType() }; } + + clone(): BaseNode { + return jsonToNode(this.toMutableJSON()) as BaseNode; + } + + /** + * Converts the object to a JSON representation. + * Properties can be safely modified as a deep clone of the properties are created. + * @return {Record<string, any>} - The JSON representation of the object. + */ + toMutableJSON(): Record<string, any> { + return _.cloneDeep(this.toJSON()); + } } /** diff --git a/packages/core/src/indices/vectorStore/VectorStoreIndex.ts b/packages/core/src/indices/vectorStore/VectorStoreIndex.ts index b588b34ee..278209f2c 100644 --- a/packages/core/src/indices/vectorStore/VectorStoreIndex.ts +++ b/packages/core/src/indices/vectorStore/VectorStoreIndex.ts @@ -4,7 +4,6 @@ import { ImageNode, MetadataMode, ObjectType, - jsonToNode, splitNodesByType, } from "../../Node"; import { BaseQueryEngine, RetrieverQueryEngine } from "../../QueryEngine"; @@ -278,7 +277,7 @@ export class VectorStoreIndex extends BaseIndex<IndexDict> { type === ObjectType.INDEX || type === ObjectType.IMAGE ) { - const nodeWithoutEmbedding = jsonToNode(nodes[i].toJSON()); + const nodeWithoutEmbedding = nodes[i].clone(); nodeWithoutEmbedding.embedding = undefined; this.indexStruct.addNode(nodeWithoutEmbedding, newIds[i]); this.docStore.addDocuments([nodeWithoutEmbedding], true); diff --git a/packages/core/src/storage/vectorStore/utils.ts b/packages/core/src/storage/vectorStore/utils.ts index cf9e5728e..a20dbf7e6 100644 --- a/packages/core/src/storage/vectorStore/utils.ts +++ b/packages/core/src/storage/vectorStore/utils.ts @@ -1,4 +1,3 @@ -import _ from "lodash"; import { BaseNode, jsonToNode, Metadata, ObjectType } from "../../Node"; const DEFAULT_TEXT_KEY = "text"; @@ -17,7 +16,7 @@ export function nodeToMetadata( textField: string = DEFAULT_TEXT_KEY, flatMetadata: boolean = false, ): Metadata { - const { metadata, embedding, ...rest } = _.cloneDeep(node.toJSON()); + const { metadata, embedding, ...rest } = node.toMutableJSON(); if (flatMetadata) { validateIsFlat(metadata); -- GitLab