diff --git a/.vscode/launch.json b/.vscode/launch.json index a8aa8e0737..96d8043c23 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -34,7 +34,8 @@ "request": "launch", "args": ["src/__start.ts"], "env": { - "FULLTEXT_URL": "http://localhost:4700", + // "FULLTEXT_URL": "http://localhost:4700", + "FULLTEXT_URL": "http://host.docker.internal:4702", // "MONGO_URL": "mongodb://localhost:27017", // "DB_URL": "mongodb://localhost:27017", // "DB_URL": "postgresql://postgres:example@localhost:5432", @@ -58,7 +59,7 @@ "ELASTIC_INDEX_NAME": "local_storage_index", "UPLOAD_URL": "/files", "AI_BOT_URL": "http://localhost:4010", - "STATS_URL": "http://host.docker.internal:4900", + "STATS_URL": "http://host.docker.internal:4900" }, "runtimeArgs": ["--nolazy", "-r", "ts-node/register"], "runtimeVersion": "20", @@ -74,11 +75,12 @@ "request": "launch", "args": ["src/index.ts"], "env": { - "PORT": "4700",// For mongo - // "PORT": "4701", // for pg + // "PORT": "4700",// For mongo + "PORT": "4702", // for cockroach "FULLTEXT_DB_URL": "http://localhost:9200", - "DB_URL": "mongodb://localhost:27017", + // "DB_URL": "mongodb://localhost:27017", // "DB_URL": "postgresql://postgres:example@localhost:5432", + "DB_URL": "postgresql://root@host.docker.internal:26257/defaultdb?sslmode=disable", "STORAGE_CONFIG": "minio|localhost?accessKey=minioadmin&secretKey=minioadmin", "SERVER_SECRET": "secret", "REKONI_URL": "http://localhost:4004", diff --git a/plugins/text-editor-resources/src/components/extension/mermaid.ts b/plugins/text-editor-resources/src/components/extension/mermaid.ts index b655166e04..a93486492f 100644 --- a/plugins/text-editor-resources/src/components/extension/mermaid.ts +++ b/plugins/text-editor-resources/src/components/extension/mermaid.ts @@ -329,7 +329,8 @@ async function renderMermaidDiagram (code: string, theme: MermaidConfig['theme'] securityLevel: 'loose', fontFamily: 'var(--font-family)', logLevel: 5, - theme + theme, + suppressErrorRendering: true }) const id = `mermaid-diagram-${Math.random().toString(36).substring(2, 9)}` diff --git a/server-plugins/fulltext-resources/src/index.ts b/server-plugins/fulltext-resources/src/index.ts index 999dfc5ff4..f1e2a9b11f 100644 --- a/server-plugins/fulltext-resources/src/index.ts +++ b/server-plugins/fulltext-resources/src/index.ts @@ -87,7 +87,7 @@ export async function OnChange (txes: Tx[], control: TriggerControl): Promise Promise // Bulk update operations - update: (ctx: MeasureContext, domain: Domain, operations: Map, DocumentUpdate>) => Promise + update: ( + ctx: MeasureContext, + domain: Domain, + operations: Map, Partial>> + ) => Promise // Allow to register a handler to listen for domain operations on?: (handler: DbAdapterHandler) => void diff --git a/server/core/src/mem.ts b/server/core/src/mem.ts index 80d53218d4..2dfb16f1a6 100644 --- a/server/core/src/mem.ts +++ b/server/core/src/mem.ts @@ -15,6 +15,7 @@ import core, { type Class, + type Data, type Doc, type DocumentQuery, type DocumentUpdate, @@ -101,7 +102,11 @@ export class DummyDbAdapter implements DbAdapter { async clean (ctx: MeasureContext, domain: Domain, docs: Ref[]): Promise {} - async update (ctx: MeasureContext, domain: Domain, operations: Map, DocumentUpdate>): Promise {} + async update( + ctx: MeasureContext, + domain: Domain, + operations: Map, Partial>> + ): Promise {} async groupBy( ctx: MeasureContext, diff --git a/server/indexer/src/indexer/indexer.ts b/server/indexer/src/indexer/indexer.ts index 72a4f5dbc1..772d3bdccd 100644 --- a/server/indexer/src/indexer/indexer.ts +++ b/server/indexer/src/indexer/indexer.ts @@ -571,7 +571,7 @@ export class FullTextIndexPipeline implements FullTextPipeline { const byClass = groupByArray, Ref>>(result, (it) => it.objectClass) - const docUpdates = new Map, DocumentUpdate>() + const docUpdates = new Map, Partial>() const pushQueue = new RateLimiter(5) diff --git a/server/mongo/src/storage.ts b/server/mongo/src/storage.ts index 8c84af9373..fa8cb11239 100644 --- a/server/mongo/src/storage.ts +++ b/server/mongo/src/storage.ts @@ -1097,7 +1097,7 @@ abstract class MongoAdapterBase implements DbAdapter { }) } - update (ctx: MeasureContext, domain: Domain, operations: Map, DocumentUpdate>): Promise { + update (ctx: MeasureContext, domain: Domain, operations: Map, Partial>): Promise { return ctx.with('update', { domain }, async () => { const coll = this.collection(domain) diff --git a/server/postgres/src/storage.ts b/server/postgres/src/storage.ts index e41ed0cedc..8bc5951e15 100644 --- a/server/postgres/src/storage.ts +++ b/server/postgres/src/storage.ts @@ -481,7 +481,7 @@ abstract class PostgresAdapterBase implements DbAdapter { params.push(converted.data) } await client.unsafe( - `UPDATE ${translateDomain(domain)} SET ${updates.join(', ')} WHERE _id = $1 AND "workspaceId" = $2`, + `UPDATE ${translateDomain(domain)} SET ${updates.join(', ')} WHERE "workspaceId" = $2 AND _id = $1`, params ) } @@ -1347,7 +1347,7 @@ abstract class PostgresAdapterBase implements DbAdapter { return await this.mgr.read('', async (client) => { const res = - await client`SELECT * FROM ${client(translateDomain(domain))} WHERE _id = ANY(${docs}) AND "workspaceId" = ${this.workspaceId.name}` + await client`SELECT * FROM ${client(translateDomain(domain))} WHERE "workspaceId" = ${this.workspaceId.name} AND _id = ANY(${docs})` return res.map((p) => parseDocWithProjection(p as any, domain)) }) }) @@ -1421,7 +1421,7 @@ abstract class PostgresAdapterBase implements DbAdapter { return this.mgr.write( ctx.id, (client) => - client`DELETE FROM ${client(tdomain)} WHERE _id = ANY(${part}) AND "workspaceId" = ${this.workspaceId.name}` + client`DELETE FROM ${client(tdomain)} WHERE "workspaceId" = ${this.workspaceId.name} AND _id = ANY(${part})` ) }) } @@ -1449,46 +1449,16 @@ abstract class PostgresAdapterBase implements DbAdapter { }) } - update (ctx: MeasureContext, domain: Domain, operations: Map, DocumentUpdate>): Promise { - const ids = Array.from(operations.keys()) - return this.mgr.write(ctx.id, async (client) => { - try { - const res: DBDoc[] = - await client`SELECT * FROM ${client(translateDomain(domain))} WHERE _id = ANY(${ids}) AND "workspaceId" = ${this.workspaceId.name} FOR UPDATE` - const schema = getSchema(domain) - const docs = res.map((p) => parseDoc(p, schema)) - const map = new Map(docs.map((d) => [d._id, d])) - const schemaFields = getSchemaAndFields(domain) - for (const [_id, ops] of operations) { - const doc = map.get(_id) - if (doc === undefined) continue - const op = { ...ops } - if ((op as any)['%hash%'] == null) { - ;(op as any)['%hash%'] = this.curHash() - } - TxProcessor.applyUpdate(doc, op) - const converted = convertDoc(domain, doc, this.workspaceId.name, schemaFields) - - const columns: string[] = [] - const { extractedFields, remainingData } = parseUpdate(op, schemaFields) - for (const key in extractedFields) { - columns.push(key) - } - if (Object.keys(remainingData).length > 0) { - columns.push('data') - } - columns.push('modifiedBy') - columns.push('modifiedOn') - await client`UPDATE ${client(translateDomain(domain))} SET ${client( - converted, - columns - )} WHERE _id = ${doc._id} AND "workspaceId" = ${this.workspaceId.name}` - } - } catch (err) { - ctx.error('Error while updating', { domain, operations, err }) - throw err + async update (ctx: MeasureContext, domain: Domain, operations: Map, Partial>): Promise { + const ids = [...operations.entries()] + const groups = groupByArray(ids, (it) => JSON.stringify(it[1])) + for (const [, values] of groups.entries()) { + const ids = values.map((it) => it[0]) + while (ids.length > 0) { + const part = ids.splice(0, 200) + await this.rawUpdate(domain, { _id: { $in: part } }, values[0][1]) } - }) + } } @withContext('insert') @@ -1581,7 +1551,7 @@ class PostgresAdapter extends PostgresAdapterBase { columns.add('modifiedOn') columns.add('data') columns.add('%hash%') - await client`UPDATE ${client(translateDomain(domain))} SET ${client(converted, Array.from(columns))} WHERE _id = ${tx.objectId} AND "workspaceId" = ${this.workspaceId.name}` + await client`UPDATE ${client(translateDomain(domain))} SET ${client(converted, Array.from(columns))} WHERE "workspaceId" = ${this.workspaceId.name} AND _id = ${tx.objectId}` }) }) return {} @@ -1683,7 +1653,7 @@ class PostgresAdapter extends PostgresAdapterBase { if (!columns.includes('%hash%')) { columns.push('%hash%') } - await client`UPDATE ${client(translateDomain(domain))} SET ${client(converted, columns)} WHERE _id = ${tx.objectId} AND "workspaceId" = ${this.workspaceId.name}` + await client`UPDATE ${client(translateDomain(domain))} SET ${client(converted, columns)} WHERE "workspaceId" = ${this.workspaceId.name} AND _id = ${tx.objectId}` }) if (tx.retrieve === true && doc !== undefined) { return { object: doc } @@ -1802,7 +1772,7 @@ class PostgresAdapter extends PostgresAdapterBase { const domain = this.hierarchy.getDomain(_class) return ctx.with('find-doc', { _class }, async () => { const res = - await client`SELECT * FROM ${client(translateDomain(domain))} WHERE _id = ${_id} AND "workspaceId" = ${this.workspaceId.name} ${ + await client`SELECT * FROM ${client(translateDomain(domain))} WHERE "workspaceId" = ${this.workspaceId.name} AND _id = ${_id} ${ forUpdate ? client` FOR UPDATE` : client`` }` const dbDoc = res[0] as any diff --git a/services/github/github-assets/lang/en.json b/services/github/github-assets/lang/en.json index 8b57fcbf27..3ca4e656fc 100644 --- a/services/github/github-assets/lang/en.json +++ b/services/github/github-assets/lang/en.json @@ -72,6 +72,8 @@ "AuthenticatedWithGithubRequired": "Please authorize Github application to act on behind you to perform actions", "Processing": "Processing authentication/installation", "AutoClose": "Processing complete, Tab will be auto-closed in {time} seconds.", + "RequestFailed": "Request failed. Please close the tab and try again.", + "CloseTab": "Close Tab", "PleaseRetry": "Please retry authentication", "Updated": "Updated", "LinkToProject": "Connect to {title}", diff --git a/services/github/github-assets/lang/pt.json b/services/github/github-assets/lang/pt.json index cf23c737a5..ce5646cb18 100644 --- a/services/github/github-assets/lang/pt.json +++ b/services/github/github-assets/lang/pt.json @@ -72,6 +72,8 @@ "AuthenticatedWithGithubRequired": "Por favor, autorize a aplicação do Github a agir em seu nome para realizar ações", "Processing": "Processando autenticação/instalação", "AutoClose": "Processamento concluído, a guia será fechada automaticamente em {time} segundos.", + "RequestFailed": "Solicitação falhou. Por favor, feche a aba e tente novamente.", + "CloseTab": "Fechar aba", "PleaseRetry": "Por favor, tente novamente a autenticação", "Updated": "Atualizado", "LinkToProject": "Conectar ao {title}", diff --git a/services/github/github-assets/lang/ru.json b/services/github/github-assets/lang/ru.json index 5b2f990dc0..4cf09f2d7c 100644 --- a/services/github/github-assets/lang/ru.json +++ b/services/github/github-assets/lang/ru.json @@ -72,6 +72,8 @@ "AuthenticatedWithGithubRequired": "Пожалуйста авторизуйте Github приложение для действий от вашего имени", "Processing": "Происходит авторизация/установка", "AutoClose": "Процесс завершен, Вкладка будет автоматически закрыта через {time} секунд.", + "RequestFailed": "Запрос не выполнен. Пожалуйста, закройте вкладку и попробуйте снова.", + "CloseTab": "Закрыть вкладку", "PleaseRetry": "Пожалуйста повторите авторизацию", "Updated": "Обновлено", "LinkToProject": "Подключить к {title}", diff --git a/services/github/github-assets/lang/sp.json b/services/github/github-assets/lang/sp.json index d94ecdf1b9..5b6e36484d 100644 --- a/services/github/github-assets/lang/sp.json +++ b/services/github/github-assets/lang/sp.json @@ -72,6 +72,8 @@ "AuthenticatedWithGithubRequired": "Por favor, autoriza la aplicación de Github para actuar en tu nombre y realizar acciones", "Processing": "Procesando autenticación/instalación", "AutoClose": "Procesamiento completo, la pestaña se cerrará automáticamente en {time} segundos.", + "RequestFailed": "Solicitud fallida. Por favor, cierre la pestaña e intente nuevamente.", + "CloseTab": "Cerrar pestaña", "PleaseRetry": "Por favor, vuelve a intentar la autenticación", "Updated": "Actualizado", "LinkToProject": "Conectar a {title}", diff --git a/services/github/github-resources/src/components/ConnectApp.svelte b/services/github/github-resources/src/components/ConnectApp.svelte index 01f3b2408b..f9058c1bf1 100644 --- a/services/github/github-resources/src/components/ConnectApp.svelte +++ b/services/github/github-resources/src/components/ConnectApp.svelte @@ -5,7 +5,7 @@ -->