diff --git a/src/collections/config/types/index.ts b/src/collections/config/types/index.ts index 2af0f07e..171cccf7 100644 --- a/src/collections/config/types/index.ts +++ b/src/collections/config/types/index.ts @@ -40,8 +40,11 @@ export type MultiTenancyConfig = { enabled: boolean; }; +export type ReplicationDeletionStrategy = 'DeleteOnConflict' | 'NoAutomatedResolution'; + export type ReplicationConfig = { asyncEnabled: boolean; + deletionStrategy: ReplicationDeletionStrategy; factor: number; }; diff --git a/src/collections/config/utils.ts b/src/collections/config/utils.ts index 79854a05..3466f05b 100644 --- a/src/collections/config/utils.ts +++ b/src/collections/config/utils.ts @@ -265,6 +265,7 @@ class ConfigMapping { return { factor: v.factor, asyncEnabled: v.asyncEnabled ? v.asyncEnabled : false, + deletionStrategy: v.deletionStrategy ? v.deletionStrategy : 'NoAutomatedResolution', }; } static sharding(v?: WeaviateShardingConfig): ShardingConfig { diff --git a/src/collections/configure/index.ts b/src/collections/configure/index.ts index 3ad323b8..4c9d2ca4 100644 --- a/src/collections/configure/index.ts +++ b/src/collections/configure/index.ts @@ -3,6 +3,8 @@ import { InvertedIndexConfigUpdate, MultiTenancyConfigCreate, ReplicationConfigCreate, + ReplicationConfigUpdate, + ReplicationDeletionStrategy, ShardingConfigCreate, VectorConfigUpdate, VectorIndexType, @@ -131,10 +133,19 @@ const configure = { * See [the docs](https://weaviate.io/developers/weaviate/concepts/replication-architecture#replication-vs-sharding) for more details. * * @param {boolean} [options.asyncEnabled] Whether asynchronous replication is enabled. Default is false. + * @param {ReplicationDeletionStrategy} [options.deletionStrategy] The deletion strategy when replication conflicts are detected between deletes and reads. * @param {number} [options.factor] The replication factor. Default is 1. */ - replication: (options: { asyncEnabled?: boolean; factor?: number }): ReplicationConfigCreate => { - return { asyncEnabled: options.asyncEnabled, factor: options.factor }; + replication: (options: { + asyncEnabled?: boolean; + deletionStrategy?: ReplicationDeletionStrategy; + factor?: number; + }): ReplicationConfigCreate => { + return { + asyncEnabled: options.asyncEnabled, + deletionStrategy: options.deletionStrategy, + factor: options.factor, + }; }, /** * Create a `ShardingConfigCreate` object to be used when defining the sharding configuration of your collection. @@ -217,10 +228,19 @@ const reconfigure = { * See [the docs](https://weaviate.io/developers/weaviate/concepts/replication-architecture#replication-vs-sharding) for more details. * * @param {boolean} [options.asyncEnabled] Whether asynchronous replication is enabled. + * @param {ReplicationDeletionStrategy} [options.deletionStrategy] The deletion strategy when replication conflicts are detected between deletes and reads. * @param {number} [options.factor] The replication factor. */ - replication: (options: { asyncEnabled?: boolean; factor?: number }): ReplicationConfigCreate => { - return { asyncEnabled: options.asyncEnabled, factor: options.factor }; + replication: (options: { + asyncEnabled?: boolean; + deletionStrategy?: ReplicationDeletionStrategy; + factor?: number; + }): ReplicationConfigUpdate => { + return { + asyncEnabled: options.asyncEnabled, + deletionStrategy: options.deletionStrategy, + factor: options.factor, + }; }, }; diff --git a/src/collections/configure/types/base.ts b/src/collections/configure/types/base.ts index 4e5d3bfd..0ee1cde2 100644 --- a/src/collections/configure/types/base.ts +++ b/src/collections/configure/types/base.ts @@ -1,11 +1,18 @@ import { WeaviateNestedProperty, WeaviateProperty } from '../../../openapi/types.js'; -import { InvertedIndexConfig, MultiTenancyConfig, ReplicationConfig } from '../../config/types/index.js'; +import { + InvertedIndexConfig, + MultiTenancyConfig, + ReplicationConfig, + ReplicationDeletionStrategy, +} from '../../config/types/index.js'; import { DataType } from '../../types/index.js'; import { NonRefKeys, RefKeys } from '../../types/internal.js'; -export type RecursivePartial = { - [P in keyof T]?: RecursivePartial; -}; +export type RecursivePartial = T extends object + ? { + [P in keyof T]?: RecursivePartial; + } + : T; export type InvertedIndexConfigCreate = RecursivePartial; @@ -133,6 +140,7 @@ export type ReplicationConfigCreate = RecursivePartial; export type ReplicationConfigUpdate = { asyncEnabled?: boolean; + deletionStrategy?: ReplicationDeletionStrategy; factor?: number; }; diff --git a/src/collections/configure/unit.test.ts b/src/collections/configure/unit.test.ts index fbd28df3..ef1d3215 100644 --- a/src/collections/configure/unit.test.ts +++ b/src/collections/configure/unit.test.ts @@ -14,17 +14,18 @@ import { ModuleConfig, VectorConfigCreate, } from '../types/index.js'; -import { configure } from './index.js'; +import { configure, reconfigure } from './index.js'; import { InvertedIndexConfigCreate, MultiTenancyConfigCreate, ReplicationConfigCreate, + ReplicationConfigUpdate, ShardingConfigCreate, VectorIndexConfigFlatCreate, VectorIndexConfigHNSWCreate, } from './types/index.js'; -describe('Unit testing of the configure factory class', () => { +describe('Unit testing of the configure & reconfigure factory classes', () => { it('should create the correct InvertedIndexConfig type with all values', () => { const config = configure.invertedIndex({ bm25b: 0.5, @@ -76,13 +77,28 @@ describe('Unit testing of the configure factory class', () => { }); }); - it('should create the correct ReplicationConfig type with all values', () => { + it('should create the correct ReplicationConfigCreate type with all values', () => { const config = configure.replication({ asyncEnabled: true, + deletionStrategy: 'DeleteOnConflict', factor: 2, }); expect(config).toEqual({ asyncEnabled: true, + deletionStrategy: 'DeleteOnConflict', + factor: 2, + }); + }); + + it('should create the correct ReplicationConfigUpdate type with all values', () => { + const config = reconfigure.replication({ + asyncEnabled: true, + deletionStrategy: 'DeleteOnConflict', + factor: 2, + }); + expect(config).toEqual({ + asyncEnabled: true, + deletionStrategy: 'DeleteOnConflict', factor: 2, }); }); diff --git a/src/collections/integration.test.ts b/src/collections/integration.test.ts index a1e4c325..feb405be 100644 --- a/src/collections/integration.test.ts +++ b/src/collections/integration.test.ts @@ -6,6 +6,7 @@ import { PQConfig, PhoneNumber, PropertyConfig, + ReplicationDeletionStrategy, Text2VecContextionaryConfig, Text2VecOpenAIConfig, VectorIndexConfigHNSW, @@ -578,6 +579,10 @@ describe('Testing of the collections.create method', () => { expect(response.multiTenancy.enabled).toEqual(true); + expect(response.replication.asyncEnabled).toEqual(false); + expect(response.replication.deletionStrategy).toEqual( + 'NoAutomatedResolution' + ); expect(response.replication.factor).toEqual(2); const indexConfig = response.vectorizers.default.indexConfig as VectorIndexConfigHNSW; diff --git a/src/collections/journey.test.ts b/src/collections/journey.test.ts index 5e50a070..502ccf51 100644 --- a/src/collections/journey.test.ts +++ b/src/collections/journey.test.ts @@ -145,6 +145,7 @@ describe('Journey testing of the client using a WCD cluster', () => { references: [], replication: { asyncEnabled: false, + deletionStrategy: 'NoAutomatedResolution', factor: 1, }, reranker: {