From 5278437c1e71b67d4a33e6c35048890e2d4a582f Mon Sep 17 00:00:00 2001 From: Darshan Date: Wed, 11 Feb 2026 17:27:48 +0530 Subject: [PATCH 01/22] add: vectordb sdk support. --- bun.lock | 4 +- package.json | 2 +- src/lib/stores/sdk.ts | 4 +- .../(entity)/helpers/sdk.ts | 124 ++++++++++++++---- .../(entity)/helpers/terminology.ts | 8 +- 5 files changed, 110 insertions(+), 32 deletions(-) diff --git a/bun.lock b/bun.lock index 5242072a9..416a42d2f 100644 --- a/bun.lock +++ b/bun.lock @@ -6,7 +6,7 @@ "name": "@appwrite/console", "dependencies": { "@ai-sdk/svelte": "^1.1.24", - "@appwrite.io/console": "https://pkg.vc/-/@appwrite/@appwrite.io/console@c91a6f3", + "@appwrite.io/console": "https://pkg.vc/-/@appwrite/@appwrite.io/console@d6a457f", "@appwrite.io/pink-icons": "0.25.0", "@appwrite.io/pink-icons-svelte": "https://pkg.vc/-/@appwrite/@appwrite.io/pink-icons-svelte@df765cc", "@appwrite.io/pink-legacy": "^1.0.3", @@ -120,7 +120,7 @@ "@analytics/type-utils": ["@analytics/type-utils@0.6.4", "", {}, "sha512-Ou1gQxFakOWLcPnbFVsrPb8g1wLLUZYYJXDPjHkG07+5mustGs5yqACx42UAu4A6NszNN6Z5gGxhyH45zPWRxw=="], - "@appwrite.io/console": ["@appwrite.io/console@https://pkg.vc/-/@appwrite/@appwrite.io/console@c91a6f3", { "dependencies": { "bignumber.js": "9.0.0", "json-bigint": "1.0.0" } }], + "@appwrite.io/console": ["@appwrite.io/console@https://pkg.vc/-/@appwrite/@appwrite.io/console@d6a457f", { "dependencies": { "bignumber.js": "9.0.0", "json-bigint": "1.0.0" } }], "@appwrite.io/pink-icons": ["@appwrite.io/pink-icons@0.25.0", "", {}, "sha512-0O3i2oEuh5mWvjO80i+X6rbzrWLJ1m5wmv2/M3a1p2PyBJsFxN8xQMTEmTn3Wl/D26SsM7SpzbdW6gmfgoVU9Q=="], diff --git a/package.json b/package.json index 96d2f7b1c..7acf9d2b6 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,7 @@ }, "dependencies": { "@ai-sdk/svelte": "^1.1.24", - "@appwrite.io/console": "https://pkg.vc/-/@appwrite/@appwrite.io/console@c91a6f3", + "@appwrite.io/console": "https://pkg.vc/-/@appwrite/@appwrite.io/console@d6a457f", "@appwrite.io/pink-icons": "0.25.0", "@appwrite.io/pink-icons-svelte": "https://pkg.vc/-/@appwrite/@appwrite.io/pink-icons-svelte@df765cc", "@appwrite.io/pink-legacy": "^1.0.3", diff --git a/src/lib/stores/sdk.ts b/src/lib/stores/sdk.ts index ff72486fd..e6c0cdcc6 100644 --- a/src/lib/stores/sdk.ts +++ b/src/lib/stores/sdk.ts @@ -25,7 +25,8 @@ import { Domains, DocumentsDB, Realtime, - Organizations + Organizations, + VectorDB } from '@appwrite.io/console'; import { Sources } from '$lib/sdk/sources'; import { @@ -137,6 +138,7 @@ const sdkForProject = { sites: new Sites(clientProject), tablesDB: new TablesDB(clientProject), documentsDB: new DocumentsDB(clientProject), + vectorDB: new VectorDB(clientProject), console: new Console(clientProject) // for suggestions API }; diff --git a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/(entity)/helpers/sdk.ts b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/(entity)/helpers/sdk.ts index a809f0fe0..2f5f38b95 100644 --- a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/(entity)/helpers/sdk.ts +++ b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/(entity)/helpers/sdk.ts @@ -30,6 +30,7 @@ export type DatabaseSdkResult = { entityId: string; name: string; databaseType?: DatabaseType; + dimension?: number /* vectorDB specific */; }) => Promise; getEntity: (params: { databaseId: string; @@ -126,8 +127,9 @@ export function useDatabaseSdk( case 'documentsdb': { return await baseSdk.documentsDB.create(params); } - case 'vectordb': - throw new Error('Database type not supported yet'); + case 'vectordb': { + return await baseSdk.vectorDB.create(params); + } default: throw new Error('Unknown database type'); } @@ -135,10 +137,9 @@ export function useDatabaseSdk( async list(params): Promise { const results = await Promise.all([ - baseSdk.tablesDB.list(params) - - // not available just yet! - // baseSdk.documentsDB.list(params), + baseSdk.tablesDB.list(params), + baseSdk.documentsDB.list(params), + baseSdk.vectorDB.list(params) ]); return results.reduce( @@ -168,8 +169,15 @@ export function useDatabaseSdk( return toSupportiveEntity(table); } - case 'vectordb': - throw new Error('Database type not supported yet'); + case 'vectordb': { + const collection = await baseSdk.vectorDB.createCollection({ + ...params, + dimension: params.dimension, + collectionId: params.entityId + }); + + return toSupportiveEntity(collection); + } default: throw new Error('Unknown database type'); } @@ -187,8 +195,10 @@ export function useDatabaseSdk( await baseSdk.documentsDB.listCollections(params); return { total, entities: collections.map(toSupportiveEntity) }; } - case 'vectordb': - throw new Error(`Database type not supported yet`); + case 'vectordb': { + const { total, collections } = await baseSdk.vectorDB.listCollections(params); + return { total, entities: collections.map(toSupportiveEntity) }; + } default: throw new Error(`Unknown database type`); } @@ -212,8 +222,14 @@ export function useDatabaseSdk( return toSupportiveEntity(collection); } - case 'vectordb': - throw new Error(`Database type not supported yet`); + case 'vectordb': { + const collection = await baseSdk.vectorDB.getCollection({ + databaseId: params.databaseId, + collectionId: params.entityId + }); + + return toSupportiveEntity(collection); + } default: throw new Error(`Unknown database type`); } @@ -227,7 +243,7 @@ export function useDatabaseSdk( case 'documentsdb': return await baseSdk.documentsDB.delete(params); case 'vectordb': - throw new Error('Database type not supported yet'); + return await baseSdk.vectorDB.delete(params); default: throw new Error(`Unknown database type`); } @@ -247,7 +263,10 @@ export function useDatabaseSdk( collectionId: params.entityId }); case 'vectordb': - throw new Error('Database type not supported yet'); + return await baseSdk.vectorDB.deleteCollection({ + databaseId: params.databaseId, + collectionId: params.entityId + }); default: throw new Error(`Unknown database type`); } @@ -272,8 +291,15 @@ export function useDatabaseSdk( data: params.data, permissions: params.permissions }); - case 'vectordb': - throw new Error('Database type not supported yet'); + case 'vectordb': { + return await baseSdk.vectorDB.createDocument({ + databaseId: params.databaseId, + collectionId: params.entityId, + documentId: params.recordId, + data: params.data, + permissions: params.permissions + }); + } default: throw new Error(`Unknown database type`); } @@ -298,8 +324,17 @@ export function useDatabaseSdk( data: params.data, permissions: params.permissions }); - case 'vectordb': - throw new Error('Database type not supported yet'); + case 'vectordb': { + const { documents } = await baseSdk.vectorDB.upsertDocument({ + databaseId: params.databaseId, + collectionId: params.entityId, + documentId: params.recordId, + data: params.data, + permissions: params.permissions + }); + + return toSupportiveRecord(documents[0]); + } default: throw new Error(`Unknown database type`); } @@ -322,8 +357,16 @@ export function useDatabaseSdk( documentId: params.recordId, permissions: params.permissions }); - case 'vectordb': - throw new Error('Database type not supported yet'); + case 'vectordb': { + const { documents } = await baseSdk.vectorDB.upsertDocument({ + databaseId: params.databaseId, + collectionId: params.entityId, + documentId: params.recordId, + permissions: params.permissions + }); + + return toSupportiveRecord(documents[0]); + } default: throw new Error(`Unknown database type`); } @@ -348,8 +391,19 @@ export function useDatabaseSdk( }); return toSupportiveRecord(document); } - case 'vectordb': - throw new Error('Database type not supported yet'); + case 'vectordb': { + if (!params.recordId) { + throw new Error('Record ID is required to delete a VectorDB document'); + } + + const document = await baseSdk.vectorDB.deleteDocument({ + databaseId: params.databaseId, + collectionId: params.entityId, + documentId: params.recordId + }); + + return toSupportiveRecord(document); + } default: throw new Error(`Unknown database type`); } @@ -374,8 +428,15 @@ export function useDatabaseSdk( }); return { total, records: documents.map(toSupportiveRecord) }; } - case 'vectordb': - throw new Error('Database type not supported yet'); + case 'vectordb': { + const { total, documents } = await baseSdk.vectorDB.deleteDocuments({ + databaseId: params.databaseId, + collectionId: params.entityId, + queries: params.queries + }); + + return { total, records: documents.map(toSupportiveRecord) }; + } default: throw new Error(`Unknown database type`); } @@ -408,8 +469,19 @@ export function useDatabaseSdk( }); return toSupportiveIndex(index); } - case 'vectordb': - throw new Error('Database type not supported yet'); + case 'vectordb': { + const index = await baseSdk.vectorDB.createIndex({ + databaseId: params.databaseId, + collectionId: params.entityId, + key: params.key, + type: params.type, + attributes: params.attributes, + lengths: params.lengths, + orders: params.orders + }); + + return toSupportiveIndex(index); + } default: throw new Error(`Unknown database type`); } diff --git a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/(entity)/helpers/terminology.ts b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/(entity)/helpers/terminology.ts index 713e90717..83f85355b 100644 --- a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/(entity)/helpers/terminology.ts +++ b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/(entity)/helpers/terminology.ts @@ -6,7 +6,7 @@ import type { Attributes, Collection, Columns, Table } from '$database/store'; import type { Term, TerminologyResult, TerminologyShape } from '$database/(entity)/helpers/types'; type BaseTerminology = typeof baseTerminology; -type ImplementedDBTypes = Omit; +type ImplementedDBTypes = Omit; /* manual type for the time being because vectordb is pending */ export type DatabaseType = 'legacy' | 'tablesdb' | 'documentsdb' | 'vectordb'; @@ -62,7 +62,11 @@ export const baseTerminology = { field: 'attribute', record: 'document' }, - vectordb: {} + vectordb: { + entity: 'table', + field: 'column', + record: 'row' + } } as const; const createTerm = (singular: string, pluralForm: string): Term => { From f38a9bc1d634bc7a0b7e0ade636700c7c5e956fc Mon Sep 17 00:00:00 2001 From: Prem Palanisamy Date: Mon, 16 Mar 2026 11:44:26 +0000 Subject: [PATCH 02/22] fix: rename vectordb to vectorsdb for naming consistency. --- bun.lock | 4 +- src/lib/helpers/faker.ts | 2 +- src/lib/stores/sdk.ts | 4 +- .../(entity)/helpers/sdk.ts | 64 +++++++++---------- .../(entity)/helpers/terminology.ts | 12 ++-- .../(entity)/views/indexes/create.svelte | 30 ++++----- .../(suggestions)/indexes.svelte | 16 ++--- .../(suggestions)/store.ts | 4 +- .../databases/store.ts | 4 +- 9 files changed, 70 insertions(+), 70 deletions(-) diff --git a/bun.lock b/bun.lock index b3a79ed60..02d2053e4 100644 --- a/bun.lock +++ b/bun.lock @@ -6,7 +6,7 @@ "name": "@appwrite/console", "dependencies": { "@ai-sdk/svelte": "^1.1.24", - "@appwrite.io/console": "https://pkg.vc/-/@appwrite/@appwrite.io/console@13c8c34", + "@appwrite.io/console": "github:appwrite/sdk-for-console#b8d2d50", "@appwrite.io/pink-icons": "0.25.0", "@appwrite.io/pink-icons-svelte": "https://pkg.vc/-/@appwrite/@appwrite.io/pink-icons-svelte@df765cc", "@appwrite.io/pink-legacy": "^1.0.3", @@ -122,7 +122,7 @@ "@analytics/type-utils": ["@analytics/type-utils@0.6.4", "", {}, "sha512-Ou1gQxFakOWLcPnbFVsrPb8g1wLLUZYYJXDPjHkG07+5mustGs5yqACx42UAu4A6NszNN6Z5gGxhyH45zPWRxw=="], - "@appwrite.io/console": ["@appwrite.io/console@https://pkg.vc/-/@appwrite/@appwrite.io/console@13c8c34", { "dependencies": { "json-bigint": "1.0.0" } }], + "@appwrite.io/console": ["@appwrite.io/console@github:appwrite/sdk-for-console#b8d2d50", { "dependencies": { "json-bigint": "1.0.0" } }, "appwrite-sdk-for-console-b8d2d50"], "@appwrite.io/pink-icons": ["@appwrite.io/pink-icons@0.25.0", "", {}, "sha512-0O3i2oEuh5mWvjO80i+X6rbzrWLJ1m5wmv2/M3a1p2PyBJsFxN8xQMTEmTn3Wl/D26SsM7SpzbdW6gmfgoVU9Q=="], diff --git a/src/lib/helpers/faker.ts b/src/lib/helpers/faker.ts index 22197bd77..83b390beb 100644 --- a/src/lib/helpers/faker.ts +++ b/src/lib/helpers/faker.ts @@ -77,7 +77,7 @@ export async function generateFields( } case 'documentsdb': /* doesn't need any fields */ - case 'vectordb': /* vector embeddings + metadata defined at collection creation */ { + case 'vectorsdb': /* vector embeddings + metadata defined at collection creation */ { /* no individual field creation needed */ return []; } diff --git a/src/lib/stores/sdk.ts b/src/lib/stores/sdk.ts index e6c0cdcc6..e844ce6ce 100644 --- a/src/lib/stores/sdk.ts +++ b/src/lib/stores/sdk.ts @@ -26,7 +26,7 @@ import { DocumentsDB, Realtime, Organizations, - VectorDB + VectorsDB } from '@appwrite.io/console'; import { Sources } from '$lib/sdk/sources'; import { @@ -138,7 +138,7 @@ const sdkForProject = { sites: new Sites(clientProject), tablesDB: new TablesDB(clientProject), documentsDB: new DocumentsDB(clientProject), - vectorDB: new VectorDB(clientProject), + vectorsDB: new VectorsDB(clientProject), console: new Console(clientProject) // for suggestions API }; diff --git a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/(entity)/helpers/sdk.ts b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/(entity)/helpers/sdk.ts index 252589f9f..44d1206b9 100644 --- a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/(entity)/helpers/sdk.ts +++ b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/(entity)/helpers/sdk.ts @@ -13,7 +13,7 @@ import { toSupportiveIndex } from './terminology'; -import type { IndexType, Models, OrderBy } from '@appwrite.io/console'; +import type { Models, OrderBy, TablesDBIndexType, DocumentsDBIndexType, VectorsDBIndexType } from '@appwrite.io/console'; export type DatabaseSdkResult = { create: ( @@ -30,7 +30,7 @@ export type DatabaseSdkResult = { entityId: string; name: string; databaseType?: DatabaseType; - dimension?: number /* vectorDB specific */; + dimension?: number /* vectorsDB specific */; }) => Promise; getEntity: (params: { databaseId: string; @@ -88,7 +88,7 @@ export type DatabaseSdkResult = { databaseId: string; entityId: string; key: string; - type: IndexType; + type: string; attributes: string[]; lengths?: number[]; orders?: OrderBy[]; @@ -127,8 +127,8 @@ export function useDatabaseSdk( case 'documentsdb': { return await baseSdk.documentsDB.create(params); } - case 'vectordb': { - return await baseSdk.vectorDB.create(params); + case 'vectorsdb': { + return await baseSdk.vectorsDB.create(params); } default: throw new Error('Unknown database type'); @@ -139,7 +139,7 @@ export function useDatabaseSdk( const results = await Promise.all([ baseSdk.tablesDB.list(params), baseSdk.documentsDB.list(params), - baseSdk.vectorDB.list(params) + baseSdk.vectorsDB.list(params) ]); return results.reduce( @@ -169,8 +169,8 @@ export function useDatabaseSdk( return toSupportiveEntity(table); } - case 'vectordb': { - const collection = await baseSdk.vectorDB.createCollection({ + case 'vectorsdb': { + const collection = await baseSdk.vectorsDB.createCollection({ ...params, dimension: params.dimension, collectionId: params.entityId @@ -195,8 +195,8 @@ export function useDatabaseSdk( await baseSdk.documentsDB.listCollections(params); return { total, entities: collections.map(toSupportiveEntity) }; } - case 'vectordb': { - const { total, collections } = await baseSdk.vectorDB.listCollections(params); + case 'vectorsdb': { + const { total, collections } = await baseSdk.vectorsDB.listCollections(params); return { total, entities: collections.map(toSupportiveEntity) }; } default: @@ -222,8 +222,8 @@ export function useDatabaseSdk( return toSupportiveEntity(collection); } - case 'vectordb': { - const collection = await baseSdk.vectorDB.getCollection({ + case 'vectorsdb': { + const collection = await baseSdk.vectorsDB.getCollection({ databaseId: params.databaseId, collectionId: params.entityId }); @@ -242,8 +242,8 @@ export function useDatabaseSdk( return await baseSdk.tablesDB.delete(params); case 'documentsdb': return await baseSdk.documentsDB.delete(params); - case 'vectordb': - return await baseSdk.vectorDB.delete(params); + case 'vectorsdb': + return await baseSdk.vectorsDB.delete(params); default: throw new Error(`Unknown database type`); } @@ -262,8 +262,8 @@ export function useDatabaseSdk( databaseId: params.databaseId, collectionId: params.entityId }); - case 'vectordb': - return await baseSdk.vectorDB.deleteCollection({ + case 'vectorsdb': + return await baseSdk.vectorsDB.deleteCollection({ databaseId: params.databaseId, collectionId: params.entityId }); @@ -291,8 +291,8 @@ export function useDatabaseSdk( data: params.data, permissions: params.permissions }); - case 'vectordb': { - return await baseSdk.vectorDB.createDocument({ + case 'vectorsdb': { + return await baseSdk.vectorsDB.createDocument({ databaseId: params.databaseId, collectionId: params.entityId, documentId: params.recordId, @@ -324,8 +324,8 @@ export function useDatabaseSdk( data: params.data, permissions: params.permissions }); - case 'vectordb': { - const { documents } = await baseSdk.vectorDB.upsertDocument({ + case 'vectorsdb': { + const { documents } = await baseSdk.vectorsDB.upsertDocument({ databaseId: params.databaseId, collectionId: params.entityId, documentId: params.recordId, @@ -357,8 +357,8 @@ export function useDatabaseSdk( documentId: params.recordId, permissions: params.permissions }); - case 'vectordb': { - const { documents } = await baseSdk.vectorDB.upsertDocument({ + case 'vectorsdb': { + const { documents } = await baseSdk.vectorsDB.upsertDocument({ databaseId: params.databaseId, collectionId: params.entityId, documentId: params.recordId, @@ -391,12 +391,12 @@ export function useDatabaseSdk( }); return toSupportiveRecord(document); } - case 'vectordb': { + case 'vectorsdb': { if (!params.recordId) { - throw new Error('Record ID is required to delete a VectorDB document'); + throw new Error('Record ID is required to delete a VectorsDB document'); } - const document = await baseSdk.vectorDB.deleteDocument({ + const document = await baseSdk.vectorsDB.deleteDocument({ databaseId: params.databaseId, collectionId: params.entityId, documentId: params.recordId @@ -428,8 +428,8 @@ export function useDatabaseSdk( }); return { total, records: documents.map(toSupportiveRecord) }; } - case 'vectordb': { - const { total, documents } = await baseSdk.vectorDB.deleteDocuments({ + case 'vectorsdb': { + const { total, documents } = await baseSdk.vectorsDB.deleteDocuments({ databaseId: params.databaseId, collectionId: params.entityId, queries: params.queries @@ -450,7 +450,7 @@ export function useDatabaseSdk( databaseId: params.databaseId, tableId: params.entityId, key: params.key, - type: params.type, + type: params.type as TablesDBIndexType, columns: params.attributes, lengths: params.lengths, orders: params.orders @@ -462,19 +462,19 @@ export function useDatabaseSdk( databaseId: params.databaseId, collectionId: params.entityId, key: params.key, - type: params.type, + type: params.type as DocumentsDBIndexType, attributes: params.attributes, lengths: params.lengths, orders: params.orders }); return toSupportiveIndex(index); } - case 'vectordb': { - const index = await baseSdk.vectorDB.createIndex({ + case 'vectorsdb': { + const index = await baseSdk.vectorsDB.createIndex({ databaseId: params.databaseId, collectionId: params.entityId, key: params.key, - type: params.type, + type: params.type as VectorsDBIndexType, attributes: params.attributes, lengths: params.lengths, orders: params.orders diff --git a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/(entity)/helpers/terminology.ts b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/(entity)/helpers/terminology.ts index 83f85355b..7d54a9918 100644 --- a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/(entity)/helpers/terminology.ts +++ b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/(entity)/helpers/terminology.ts @@ -1,15 +1,15 @@ import type { Page } from '@sveltejs/kit'; import { capitalize, plural } from '$lib/helpers/string'; -import { AppwriteException, type IndexType, type Models } from '@appwrite.io/console'; +import { AppwriteException, type DatabasesIndexType, type Models } from '@appwrite.io/console'; import type { Attributes, Collection, Columns, Table } from '$database/store'; import type { Term, TerminologyResult, TerminologyShape } from '$database/(entity)/helpers/types'; type BaseTerminology = typeof baseTerminology; type ImplementedDBTypes = Omit; -/* manual type for the time being because vectordb is pending */ -export type DatabaseType = 'legacy' | 'tablesdb' | 'documentsdb' | 'vectordb'; +/* manual type for the time being because vectorsdb is pending */ +export type DatabaseType = 'legacy' | 'tablesdb' | 'documentsdb' | 'vectorsdb'; export type RecordType = ImplementedDBTypes[keyof ImplementedDBTypes]['record']; @@ -28,7 +28,7 @@ export type Record = Partial & { export type Index = Partial & { fields: Models.Index['attributes'] | Models.ColumnIndex['columns']; - type: IndexType; + type: DatabasesIndexType; }; export type EntityList = { @@ -62,7 +62,7 @@ export const baseTerminology = { field: 'attribute', record: 'document' }, - vectordb: { + vectorsdb: { entity: 'table', field: 'column', record: 'row' @@ -99,7 +99,7 @@ const terminologyData = Object.fromEntries( export function toSupportiveIndex(index: Models.Index | Models.ColumnIndex): Index { return { ...index, - type: index.type as IndexType, + type: index.type as DatabasesIndexType, fields: (index as Models.Index).attributes ?? (index as Models.ColumnIndex).columns ?? [] }; } diff --git a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/(entity)/views/indexes/create.svelte b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/(entity)/views/indexes/create.svelte index 7b009ccbc..9f3a8fc17 100644 --- a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/(entity)/views/indexes/create.svelte +++ b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/(entity)/views/indexes/create.svelte @@ -1,8 +1,8 @@ diff --git a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/spreadsheet.svelte b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/spreadsheet.svelte index 14a00e2c3..6dfbbfd89 100644 --- a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/spreadsheet.svelte +++ b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/spreadsheet.svelte @@ -60,6 +60,7 @@ type JsonValue, NoSqlEditor } from '$database/collection-[collection]/(components)/editor'; + import EmbeddingModal from '$database/collection-[collection]/(components)/editor/embeddingModal.svelte'; import { buildFieldUrl } from '$database/(entity)/helpers/navigation'; import { SpreadsheetOptions, @@ -75,13 +76,15 @@ $: if ($documents) { paginatedDocuments.clear(); + const docs = $documents.documents; + // If we have a new document, add it at the start if ($noSqlDocument.isDirty && $noSqlDocument.isNew) { const tempDoc = $noSqlDocument.document as Models.DefaultDocument; - const docsWithTemp = [tempDoc, ...$documents.documents]; + const docsWithTemp = [tempDoc, ...docs]; paginatedDocuments.setPage(1, docsWithTemp); } else { - paginatedDocuments.setPage(1, $documents.documents); + paginatedDocuments.setPage(1, docs); } } @@ -89,6 +92,25 @@ const collectionId = page.params.collection; const databaseSdk = useDatabaseSdk(page.params.region, page.params.project, data.database.type); + const isVectorsDb = data.database.type === 'vectorsdb'; + let showEmbeddingModal = false; + let editorRef: { replaceData: (data: JsonValue) => void } | undefined; + + const projectSdk = sdk.forProject(page.params.region, page.params.project); + const listDocumentsFn = isVectorsDb + ? projectSdk.vectorsDB.listDocuments.bind(projectSdk.vectorsDB) + : projectSdk.documentsDB.listDocuments.bind(projectSdk.documentsDB); + const getDocumentFn = isVectorsDb + ? projectSdk.vectorsDB.getDocument.bind(projectSdk.vectorsDB) + : projectSdk.documentsDB.getDocument.bind(projectSdk.documentsDB); + + function handleEmbeddingGenerated(embeddings: number[]) { + if ($noSqlDocument.document && typeof $noSqlDocument.document === 'object') { + const updated = { ...$noSqlDocument.document, embeddings }; + editorRef?.replaceData(updated); + } + } + const emptyCellsLimit = $spreadsheetLoading ? 30 : $isSmallViewport @@ -115,13 +137,11 @@ const documentId = $noSqlDocument.documentId; noSqlDocument.update({ documentId: null }); // reset for later! - const loadedDocument = await sdk - .forProject(page.params.region, page.params.project) - .documentsDB.getDocument({ - databaseId: page.params.database, - collectionId: page.params.collection, - documentId - }); + const loadedDocument = await getDocumentFn({ + databaseId: page.params.database, + collectionId: page.params.collection, + documentId + }); if (loadedDocument) { noSqlDocument.edit(loadedDocument); @@ -462,7 +482,9 @@ spreadsheetRenderKey.set(hash(Date.now().toString())); const firstDocument = $documents?.documents?.[0]; if (firstDocument) { - noSqlDocument.update({ document: firstDocument }); + noSqlDocument.update({ + document: firstDocument + }); } } catch (error) { addNotification({ @@ -492,19 +514,17 @@ const filterQueries = parsedQueries.size ? data.parsedQueries.values() : []; $paginatedDocumentsLoading = true; - const loadedRows = await sdk - .forProject(page.params.region, page.params.project) - .documentsDB.listDocuments({ - databaseId, - collectionId, - queries: [ - getCorrectOrderQuery(), - Query.limit(SPREADSHEET_PAGE_LIMIT), - Query.offset(pageToOffset(pageNumber, SPREADSHEET_PAGE_LIMIT)), - ...filterQueries /* filter queries */, - ...buildWildcardEntitiesQuery(collection) - ] - }); + const loadedRows = await listDocumentsFn({ + databaseId, + collectionId, + queries: [ + getCorrectOrderQuery(), + Query.limit(SPREADSHEET_PAGE_LIMIT), + Query.offset(pageToOffset(pageNumber, SPREADSHEET_PAGE_LIMIT)), + ...filterQueries /* filter queries */, + ...buildWildcardEntitiesQuery(collection) + ] + }); paginatedDocuments.setPage(pageNumber, loadedRows.documents); $paginatedDocumentsLoading = false; @@ -520,18 +540,16 @@ paginatedDocuments.setMaxPage(targetPageNum); $paginatedDocumentsLoading = true; - const loadedRows = await sdk - .forProject(page.params.region, page.params.project) - .documentsDB.listDocuments({ - databaseId, - collectionId, - queries: [ - getCorrectOrderQuery(), - Query.limit(SPREADSHEET_PAGE_LIMIT), - Query.offset(pageToOffset(targetPageNum, SPREADSHEET_PAGE_LIMIT)), - ...buildWildcardEntitiesQuery(collection) - ] - }); + const loadedRows = await listDocumentsFn({ + databaseId, + collectionId, + queries: [ + getCorrectOrderQuery(), + Query.limit(SPREADSHEET_PAGE_LIMIT), + Query.offset(pageToOffset(targetPageNum, SPREADSHEET_PAGE_LIMIT)), + ...buildWildcardEntitiesQuery(collection) + ] + }); paginatedDocuments.setPage(targetPageNum, loadedRows.documents); $paginatedDocumentsLoading = false; @@ -556,11 +574,29 @@ $noSqlDocument.isNew && ($documents?.documents?.length ?? 0) < MIN_DOCS_FOR_FUZZY_SUGGESTIONS; + $: metadataKeys = isVectorsDb && $documents?.documents + ? fuzzySearchKeys( + $documents.documents.map((d) => d.metadata ?? {}), + { minOccurrences: 2 } + ) ?? [] + : []; + + $: vectorsDbMetadataDefaults = isVectorsDb + ? Object.fromEntries( + (metadataKeys.length + ? metadataKeys + : mockSuggestions.columns.map((c) => c.name) + ).map((key) => [key, '']) + ) + : {}; + $: suggestedAttributes = $noSqlDocument.isNew && $documents?.documents - ? useMockSuggestions - ? mockSuggestions.columns.map((column) => column.name) - : (fuzzySearchKeys($documents.documents, { minOccurrences: 2 }) ?? []) + ? isVectorsDb + ? ['metadata', 'embeddings'] + : useMockSuggestions + ? mockSuggestions.columns.map((column) => column.name) + : (fuzzySearchKeys($documents.documents, { minOccurrences: 2 }) ?? []) : []; $: showSuggestions = $noSqlDocument.isNew && suggestedAttributes.length > 0; @@ -863,6 +899,7 @@ {#snippet noSqlEditor()} { const firstDocument = $documents?.documents?.[0]; if (firstDocument) { @@ -881,7 +922,8 @@ } }} onSave={async (document) => await createOrUpdateDocument(document)} - onChange={(_, hasDataChanged) => noSqlDocument.update({ hasDataChanged })} /> + onChange={(_, hasDataChanged) => noSqlDocument.update({ hasDataChanged })} + onGenerateEmbedding={isVectorsDb ? () => (showEmbeddingModal = true) : undefined} /> {/snippet} {#snippet sideSheetHeaderAction()} @@ -981,6 +1023,10 @@ {/if} +{#if isVectorsDb} + +{/if} + From d735f7f6854f2260e62cce903dd29a3f7e72623e Mon Sep 17 00:00:00 2001 From: Prem Palanisamy Date: Sat, 21 Mar 2026 22:02:42 +0000 Subject: [PATCH 09/22] (fix): remove databaseType param from suggestColumns call --- .../database-[database]/collection-[collection]/+layout.svelte | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/+layout.svelte b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/+layout.svelte index 1427e8f58..177d64265 100644 --- a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/+layout.svelte +++ b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/+layout.svelte @@ -249,8 +249,7 @@ databaseId: page.params.database, tableId: page.params.collection, context: $entityColumnSuggestions.context ?? undefined, - min: 6, - databaseType: data.database?.type + min: 6 })) as unknown as { total: number; columns: ColumnInput[]; From 51b499a6e78fc87c4df5ea9cd0448c6078b54b16 Mon Sep 17 00:00:00 2001 From: Prem Palanisamy Date: Sat, 21 Mar 2026 22:16:06 +0000 Subject: [PATCH 10/22] (chore): update console SDK to 2291c59 with rebuilt dist --- bun.lock | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/bun.lock b/bun.lock index 5a7f9e3c8..28909921d 100644 --- a/bun.lock +++ b/bun.lock @@ -6,7 +6,7 @@ "name": "@appwrite/console", "dependencies": { "@ai-sdk/svelte": "^1.1.24", - "@appwrite.io/console": "github:appwrite/sdk-for-console#04899af", + "@appwrite.io/console": "github:appwrite/sdk-for-console#2291c59", "@appwrite.io/pink-icons": "0.25.0", "@appwrite.io/pink-icons-svelte": "https://pkg.vc/-/@appwrite/@appwrite.io/pink-icons-svelte@bfe7ce3", "@appwrite.io/pink-legacy": "^1.0.3", @@ -121,7 +121,7 @@ "@analytics/type-utils": ["@analytics/type-utils@0.6.4", "", {}, "sha512-Ou1gQxFakOWLcPnbFVsrPb8g1wLLUZYYJXDPjHkG07+5mustGs5yqACx42UAu4A6NszNN6Z5gGxhyH45zPWRxw=="], - "@appwrite.io/console": ["@appwrite.io/console@github:appwrite/sdk-for-console#04899af", { "dependencies": { "json-bigint": "1.0.0" } }, "appwrite-sdk-for-console-04899af"], + "@appwrite.io/console": ["@appwrite.io/console@github:appwrite/sdk-for-console#2291c59", { "dependencies": { "json-bigint": "1.0.0" } }, "appwrite-sdk-for-console-2291c59"], "@appwrite.io/pink-icons": ["@appwrite.io/pink-icons@0.25.0", "", {}, "sha512-0O3i2oEuh5mWvjO80i+X6rbzrWLJ1m5wmv2/M3a1p2PyBJsFxN8xQMTEmTn3Wl/D26SsM7SpzbdW6gmfgoVU9Q=="], diff --git a/package.json b/package.json index 65a446a58..9de000847 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,7 @@ }, "dependencies": { "@ai-sdk/svelte": "^1.1.24", - "@appwrite.io/console": "github:appwrite/sdk-for-console#04899af", + "@appwrite.io/console": "github:appwrite/sdk-for-console#2291c59", "@appwrite.io/pink-icons": "0.25.0", "@appwrite.io/pink-icons-svelte": "https://pkg.vc/-/@appwrite/@appwrite.io/pink-icons-svelte@bfe7ce3", "@appwrite.io/pink-legacy": "^1.0.3", From 2a5aa4d2e3aa65a2058c57545215eeaa4031f5dd Mon Sep 17 00:00:00 2001 From: Prem Palanisamy Date: Sun, 22 Mar 2026 10:10:29 +0000 Subject: [PATCH 11/22] (fix): embedding fold preview with inline values, vectorsdb sample data label --- .../(suggestions)/input.svelte | 9 ++-- .../(components)/editor/view.svelte | 50 +++++++++++++++---- 2 files changed, 45 insertions(+), 14 deletions(-) diff --git a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/(suggestions)/input.svelte b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/(suggestions)/input.svelte index 361336d92..a9c0b1e04 100644 --- a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/(suggestions)/input.svelte +++ b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/(suggestions)/input.svelte @@ -35,6 +35,8 @@ const record = terminology.record.lower; const entity = terminology.entity.lower.singular; + const isSchemaless = type === 'documentsdb' || type === 'vectorsdb'; + const title = $derived.by(() => { switch (type) { default: @@ -45,20 +47,19 @@ : `Smart ${field.singular} suggestions available on Cloud`; case 'documentsdb': + case 'vectorsdb': return featureActive ? `Sample Data` : `Sample Data available on Cloud`; } }); const subtitle = $derived.by(() => { - const isDocs = type === 'documentsdb'; - if (featureActive) { - return isDocs + return isSchemaless ? `Generate sample ${record.plural} based on your ${entity} name` : `Enable AI to suggest useful ${field.plural} based on your ${entity} name`; } - return isDocs + return isSchemaless ? `Sign up for Cloud to generate sample documents based on your ${entity} name` : `Sign up for Cloud to generate ${field.plural} based on your ${entity} name`; }); diff --git a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/(components)/editor/view.svelte b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/(components)/editor/view.svelte index 272ca5ae0..682f31ce5 100644 --- a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/(components)/editor/view.svelte +++ b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/(components)/editor/view.svelte @@ -15,6 +15,7 @@ + +
+ {@render children()} +
+ + diff --git a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/(components)/sonners/suggestions.svelte b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/(components)/sonners/suggestions.svelte index 9474076ea..993eb9485 100644 --- a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/(components)/sonners/suggestions.svelte +++ b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/(components)/sonners/suggestions.svelte @@ -1,6 +1,7 @@ + + +
+ +
+ + +
+ +
+ + {#if localTags.length > 0} + + { + removeLocalFilter(e.detail); + }} /> + + {/if} +
+
+
+
+
+ + + + + + +
+ + From 8f5aa4a29e382622a7f5be4bbc020df7d0c516ec Mon Sep 17 00:00:00 2001 From: Prem Palanisamy Date: Mon, 30 Mar 2026 14:10:52 +0100 Subject: [PATCH 19/22] vectorsdb create index: dynamic form per index type, HNSW auto-fills embeddings, Object/HNSW send empty orders --- .../indexes/+page.svelte | 1 + .../indexes/createIndex.svelte | 148 ++++++++++++------ 2 files changed, 102 insertions(+), 47 deletions(-) diff --git a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/indexes/+page.svelte b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/indexes/+page.svelte index ef993605b..ce5f1aaad 100644 --- a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/indexes/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/indexes/+page.svelte @@ -46,6 +46,7 @@ {#snippet createIndexForm()} diff --git a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/indexes/createIndex.svelte b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/indexes/createIndex.svelte index fc99ca463..d2a3c98b9 100644 --- a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/indexes/createIndex.svelte +++ b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/indexes/createIndex.svelte @@ -1,6 +1,7 @@ + + + + + {#if !showCustomId} +
+ { + showCustomId = true; + }}> Database ID +
+ {/if} + + + + {#if isCloud} + {#if !$currentPlan?.backupsEnabled} + + Upgrade your plan to ensure your data stays safe and backed up. + + + + + {:else} + + {/if} + {/if} + + + + +
diff --git a/src/routes/(console)/project-[region]-[project]/databases/create/+page.svelte b/src/routes/(console)/project-[region]-[project]/databases/create/+page.svelte index 81b59b07e..2e27083e2 100644 --- a/src/routes/(console)/project-[region]-[project]/databases/create/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/databases/create/+page.svelte @@ -24,6 +24,9 @@ import type { PageProps } from './$types'; import { createDatabaseStore } from './store'; import { isTabletViewport } from '$lib/stores/viewport'; + import { flags } from '$lib/flags'; + import { user } from '$lib/stores/user'; + import { organization } from '$lib/stores/organization'; const { data }: PageProps = $props(); @@ -42,30 +45,36 @@ const isDark = $derived($app.themeInUse === 'dark'); const backupsImg = $derived(isDark ? EmptyDarkMobile : EmptyLightMobile); + const isMultiDb = $derived(flags.multiDb({ account: $user, organization: $organization })); + const databaseTypes: Array<{ type: DatabaseType; title: string; subtitle: string; - }> = [ + }> = $derived([ { - type: 'tablesdb', + type: 'tablesdb' as DatabaseType, title: 'TablesDB', subtitle: 'Structure your data in rows and columns. Best for relational data and advanced querying.' }, - { - type: 'documentsdb', - title: 'DocumentsDB', - subtitle: - 'Store flexible data without a fixed schema. Best for unstructured data and simple querying.' - }, - { - type: 'vectorsdb', - title: 'VectorsDB', - subtitle: - 'Store data as vectors to find similar results. Best for semantic search and recommendations.' - } - ]; + ...(isMultiDb + ? [ + { + type: 'documentsdb' as DatabaseType, + title: 'DocumentsDB', + subtitle: + 'Store flexible data without a fixed schema. Best for unstructured data and simple querying.' + }, + { + type: 'vectorsdb' as DatabaseType, + title: 'VectorsDB', + subtitle: + 'Store data as vectors to find similar results. Best for semantic search and recommendations.' + } + ] + : []) + ]); afterNavigate(({ from }) => (previousPage = from?.url?.pathname || previousPage)); diff --git a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/indexes/createIndex.svelte b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/indexes/createIndex.svelte index d2a3c98b9..bac7d84d6 100644 --- a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/indexes/createIndex.svelte +++ b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/indexes/createIndex.svelte @@ -132,10 +132,13 @@ } }); - // HNSW indexes: auto-fill embeddings, single field only + // HNSW indexes: auto-fill embeddings, single field only. + // When switching away to Key/Unique, reset stale `order: null` left over from HNSW. $effect(() => { if (isHnswType) { fieldList = [{ value: 'embeddings', order: null, length: null }]; + } else if (!isObjectType && fieldList.some((f) => f.order === null)) { + fieldList = [{ value: '', order: OrderBy.Asc, length: null }]; } }); diff --git a/src/routes/(console)/project-[region]-[project]/databases/empty.svelte b/src/routes/(console)/project-[region]-[project]/databases/empty.svelte index 85a01d15b..eb4a25375 100644 --- a/src/routes/(console)/project-[region]-[project]/databases/empty.svelte +++ b/src/routes/(console)/project-[region]-[project]/databases/empty.svelte @@ -19,6 +19,9 @@ import { isSmallViewport } from '$lib/stores/viewport'; import type { DatabaseType } from '$database/(entity)'; + import { flags } from '$lib/flags'; + import { user } from '$lib/stores/user'; + import { organization } from '$lib/stores/organization'; const { disabled, @@ -62,23 +65,25 @@ image: tablesDbImage })} - - {@render databaseTypeCard({ - type: 'documentsdb', - title: 'DocumentsDB', - subtitle: - 'Store flexible data without a fixed schema. Best for unstructured data and simple querying.', - image: documentsDbImage - })} + {#if flags.multiDb({ account: $user, organization: $organization })} + + {@render databaseTypeCard({ + type: 'documentsdb', + title: 'DocumentsDB', + subtitle: + 'Store flexible data without a fixed schema. Best for unstructured data and simple querying.', + image: documentsDbImage + })} - - {@render databaseTypeCard({ - type: 'vectorsdb', - title: 'VectorsDB', - subtitle: - 'Store data as vectors to find similar results. Best for semantic search and recommendations.', - image: vectorsDbImage - })} + + {@render databaseTypeCard({ + type: 'vectorsdb', + title: 'VectorsDB', + subtitle: + 'Store data as vectors to find similar results. Best for semantic search and recommendations.', + image: vectorsDbImage + })} + {/if} {/snippet} From 881027abef857733ffbff84c11ddd1cda14e8a4e Mon Sep 17 00:00:00 2001 From: Prem Date: Fri, 17 Apr 2026 07:34:24 +0100 Subject: [PATCH 21/22] fix: remove duplicate Import/Export JSON buttons --- .../collection-[collection]/+page.svelte | 27 ------------------- 1 file changed, 27 deletions(-) diff --git a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/+page.svelte b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/+page.svelte index 8c1f4118c..1df280dce 100644 --- a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/+page.svelte @@ -167,33 +167,6 @@ alignItems="center" justifyContent="flex-end"> {#if !$isSmallViewport} - - - Import JSON - - - - - Export JSON - Date: Fri, 17 Apr 2026 07:52:42 +0100 Subject: [PATCH 22/22] fix: use collection-specific CreateIndex in layout sheet to support HNSW --- .../collection-[collection]/+layout.svelte | 3 ++- .../collection-[collection]/indexes/createIndex.svelte | 6 +++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/+layout.svelte b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/+layout.svelte index 177d64265..abae1c256 100644 --- a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/+layout.svelte +++ b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/collection-[collection]/+layout.svelte @@ -51,12 +51,12 @@ SideSheet, EditRecordPermissions, RecordActivity, - CreateIndex, useDatabaseSdk, DEFAULT_VECTOR_DIMENSION, type Field, type Index } from '$database/(entity)'; + import CreateIndex from './indexes/createIndex.svelte'; import { entityColumnSuggestions, type ColumnInput, @@ -368,6 +368,7 @@ }}> Promise; } = $props(); @@ -98,7 +100,9 @@ function initialize() { selectedType = databaseType === 'vectorsdb' ? VectorsDBIndexType.Key : DocumentsDBIndexType.Key; - fieldList = [{ value: '', order: OrderBy.Asc, length: null }]; + fieldList = externalFieldKey + ? [{ value: externalFieldKey, order: OrderBy.Asc, length: null }] + : [{ value: '', order: OrderBy.Asc, length: null }]; key = `index_${entity.indexes.length + 1}`; }