Add a core package to be reused by desktop and server

This commit is contained in:
Hakan Shehu
2024-11-07 09:15:00 +01:00
parent 00f6ac971e
commit 8a5409ad29
277 changed files with 1193 additions and 1089 deletions

View File

@@ -4,6 +4,6 @@ module.exports = {
'plugin:react/recommended',
'plugin:react/jsx-runtime',
'@electron-toolkit/eslint-config-ts/recommended',
'@electron-toolkit/eslint-config-prettier'
]
}
'@electron-toolkit/eslint-config-prettier',
],
};

View File

@@ -4,7 +4,11 @@ import react from '@vitejs/plugin-react';
export default defineConfig({
main: {
plugins: [externalizeDepsPlugin()],
plugins: [
externalizeDepsPlugin({
exclude: ['@colanode/core'],
}),
],
resolve: {
alias: {
'@/main': resolve('src/main'),

View File

@@ -20,9 +20,9 @@
"build:linux": "electron-vite build && electron-builder --linux"
},
"dependencies": {
"@colanode/core": "workspace:*",
"@electron-toolkit/preload": "^3.0.1",
"@electron-toolkit/utils": "^3.0.0",
"electron-updater": "^6.1.7",
"@hookform/resolvers": "^3.9.0",
"@radix-ui/react-alert-dialog": "^1.1.2",
"@radix-ui/react-checkbox": "^1.1.2",
@@ -78,7 +78,7 @@
"clsx": "^2.1.1",
"cmdk": "^1.0.0",
"date-fns": "^3.6.0",
"diff": "^7.0.0",
"electron-updater": "^6.1.7",
"form-data": "^4.0.1",
"fractional-indexing-jittered": "^0.9.1",
"is-hotkey": "^0.2.0",
@@ -104,27 +104,9 @@
"tailwindcss-animate": "^1.0.7",
"ts-pattern": "^5.5.0",
"ulid": "^2.3.0",
"ws": "^8.18.0",
"yjs": "^13.6.20",
"zod": "^3.23.8"
"ws": "^8.18.0"
},
"devDependencies": {
"@electron-toolkit/eslint-config-prettier": "^2.0.0",
"@electron-toolkit/eslint-config-ts": "^2.0.0",
"@electron-toolkit/tsconfig": "^1.0.1",
"@types/node": "^20.14.8",
"@types/react": "^18.3.3",
"@types/react-dom": "^18.3.0",
"@vitejs/plugin-react": "^4.3.1",
"electron": "^31.0.2",
"electron-builder": "^24.13.3",
"electron-vite": "^2.3.0",
"eslint": "^8.57.0",
"eslint-plugin-react": "^7.34.3",
"prettier": "^3.3.2",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"vite": "^5.3.1",
"@electron-forge/cli": "^7.5.0",
"@electron-forge/maker-deb": "^7.5.0",
"@electron-forge/maker-rpm": "^7.5.0",
@@ -133,22 +115,38 @@
"@electron-forge/plugin-auto-unpack-natives": "^7.5.0",
"@electron-forge/plugin-fuses": "^7.5.0",
"@electron-forge/plugin-vite": "^7.5.0",
"@electron-toolkit/eslint-config-prettier": "^2.0.0",
"@electron-toolkit/eslint-config-ts": "^2.0.0",
"@electron-toolkit/tsconfig": "^1.0.1",
"@electron/fuses": "^1.8.0",
"@types/better-sqlite3": "^7.6.11",
"@types/diff": "^5.2.3",
"@types/is-hotkey": "^0.1.10",
"@types/lodash": "^4.17.12",
"@types/mime-types": "^2.1.4",
"@types/node": "^20.14.8",
"@types/react": "^18.3.3",
"@types/react-dom": "^18.3.0",
"@types/react-window": "^1.8.8",
"@types/ws": "^8.5.12",
"@typescript-eslint/eslint-plugin": "^5.62.0",
"@typescript-eslint/parser": "^5.62.0",
"@vitejs/plugin-react": "^4.3.1",
"autoprefixer": "^10.4.20",
"electron": "^31.0.2",
"electron-builder": "^24.13.3",
"electron-vite": "^2.3.0",
"eslint": "^8.57.0",
"eslint-plugin-import": "^2.31.0",
"eslint-plugin-react": "^7.34.3",
"node-abi": "^3.71.0",
"postcss": "^8.4.47",
"prettier": "^3.3.2",
"prettier-plugin-tailwindcss": "^0.6.8",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"tailwindcss": "^3.4.14",
"ts-node": "^10.9.2"
"ts-node": "^10.9.2",
"vite": "^5.3.1"
}
}

View File

@@ -5,7 +5,7 @@ import {
ViewFilterAttributes,
ViewFieldAttributes,
RecordNode,
} from '@/registry';
} from '@colanode/core';
import { compareString, isStringArray } from '@/lib/utils';
import { generateNodeIndex } from './nodes';
@@ -576,9 +576,9 @@ const recordMatchesBooleanFilter = (
};
const recordMatchesCollaboratorFilter = (
record: RecordNode,
filter: ViewFieldFilterAttributes,
field: FieldAttributes
_: RecordNode,
__: ViewFieldFilterAttributes,
___: FieldAttributes
) => {
return false;
};
@@ -739,9 +739,9 @@ const recordMatchesEmailFilter = (
};
const recordMatchesFileFilter = (
record: RecordNode,
filter: ViewFieldFilterAttributes,
field: FieldAttributes
_: RecordNode,
__: ViewFieldFilterAttributes,
___: FieldAttributes
) => {
return false;
};

View File

@@ -3,7 +3,7 @@ import { generateId, getIdTypeFromNode } from '@/lib/id';
import { generateNodeIndex } from '@/lib/nodes';
import { compareString } from '@/lib/utils';
import { JSONContent } from '@tiptap/core';
import { Block, BlockLeaf } from '@/registry';
import { Block, BlockLeaf } from '@colanode/core';
const leafBlockTypes = new Set([
EditorNodeTypes.Paragraph,
@@ -17,7 +17,7 @@ const leafBlockTypes = new Set([
export const mapContentsToBlocks = (
parentId: string,
contents: JSONContent[],
blocksMap: Map<string, Block>,
blocksMap: Map<string, Block>
): Block[] => {
const blocks: Block[] = [];
mapAndPushContentsToBlocks(contents, parentId, blocks, blocksMap);
@@ -29,7 +29,7 @@ const mapAndPushContentsToBlocks = (
contents: JSONContent[] | null | undefined,
parentId: string,
blocks: Block[],
blocksMap: Map<string, Block>,
blocksMap: Map<string, Block>
): void => {
if (!contents) {
return;
@@ -43,7 +43,7 @@ const mapAndPushContentToBlock = (
content: JSONContent,
parentId: string,
blocks: Block[],
blocksMap: Map<string, Block>,
blocksMap: Map<string, Block>
): void => {
if (!content.type) {
throw new Error('Invalid content type');
@@ -77,7 +77,7 @@ const mapAndPushContentToBlock = (
const mapContentsToBlockLeafs = (
type: string,
contents?: JSONContent[],
contents?: JSONContent[]
): BlockLeaf[] | null => {
if (!leafBlockTypes.has(type) || contents == null || contents.length === 0) {
return null;
@@ -106,7 +106,7 @@ const mapContentsToBlockLeafs = (
export const mapBlocksToContents = (
parentId: string,
blocks: Block[],
blocks: Block[]
): JSONContent[] => {
const contents: JSONContent[] = [];
const children = blocks
@@ -134,7 +134,7 @@ const mapBlockToContent = (block: Block, blocks: Block[]): JSONContent => {
};
const mapBlockLeafsToContents = (
leafs: BlockLeaf[] | null,
leafs: BlockLeaf[] | null
): JSONContent[] | undefined => {
if (leafs == null) {
return undefined;

View File

@@ -1,11 +1,9 @@
import { SelectNode } from '@/main/data/workspace/schema';
import { Node } from '@/registry';
import { generateKeyBetween } from 'fractional-indexing-jittered';
import { NodeTypes } from '@/lib/constants';
export const generateNodeIndex = (
previous?: string | null,
next?: string | null,
next?: string | null
) => {
const lower = previous === undefined ? null : previous;
const upper = next === undefined ? null : next;
@@ -13,24 +11,6 @@ export const generateNodeIndex = (
return generateKeyBetween(lower, upper);
};
export const mapNode = (row: SelectNode): Node => {
return {
id: row.id,
type: row.type as any,
index: row.index,
parentId: row.parent_id,
attributes: JSON.parse(row.attributes),
createdAt: row.created_at,
createdBy: row.created_by,
updatedAt: row.updated_at,
updatedBy: row.updated_by,
versionId: row.version_id,
serverCreatedAt: row.server_created_at,
serverUpdatedAt: row.server_updated_at,
serverVersionId: row.server_version_id,
};
};
export const getDefaultNodeIcon = (type: string) => {
switch (type) {
case NodeTypes.Channel:

View File

@@ -1,8 +0,0 @@
import { SelectServer } from '@/main/data/app/schema';
import { ServerAttributes } from '@/types/servers';
export const buildSynapseUrl = (server: SelectServer, deviceId: string) => {
const attributes = JSON.parse(server.attributes) as ServerAttributes;
const protocol = attributes?.insecure ? 'ws' : 'wss';
return `${protocol}://${server.domain}/v1/synapse?device_id=${deviceId}`;
};

View File

@@ -13,7 +13,7 @@ import { databaseManager } from './data/database-manager';
import { httpClient } from '@/lib/http-client';
import { mediator } from '@/main/mediator';
import { getWorkspaceFilesDirectoryPath } from '@/main/utils';
import { FileAttributes } from '@/registry';
import { FileAttributes } from '@colanode/core';
class FileManager {
public async handleFileRequest(request: Request): Promise<Response> {
@@ -39,7 +39,7 @@ class FileManager {
filePath: string,
fileId: string,
fileExtension: string,
userId: string,
userId: string
): void {
const filesDir = getWorkspaceFilesDirectoryPath(userId);
@@ -49,7 +49,7 @@ class FileManager {
const destinationFilePath = path.join(
filesDir,
`${fileId}${fileExtension}`,
`${fileId}${fileExtension}`
);
fs.copyFileSync(filePath, destinationFilePath);
}
@@ -88,10 +88,10 @@ class FileManager {
}
public async checkForUploads(
credentials: WorkspaceCredentials,
credentials: WorkspaceCredentials
): Promise<void> {
const workspaceDatabase = await databaseManager.getWorkspaceDatabase(
credentials.userId,
credentials.userId
);
const uploads = await workspaceDatabase
@@ -133,7 +133,7 @@ class FileManager {
const attributes: FileAttributes = JSON.parse(file.attributes);
const filePath = path.join(
filesDir,
`${upload.node_id}${attributes.extension}`,
`${upload.node_id}${attributes.extension}`
);
if (!fs.existsSync(filePath)) {
@@ -153,7 +153,7 @@ class FileManager {
serverDomain: credentials.serverDomain,
serverAttributes: credentials.serverAttributes,
token: credentials.token,
},
}
);
const presignedUrl = data.url;
@@ -189,10 +189,10 @@ class FileManager {
}
public async checkForDownloads(
credentials: WorkspaceCredentials,
credentials: WorkspaceCredentials
): Promise<void> {
const workspaceDatabase = await databaseManager.getWorkspaceDatabase(
credentials.userId,
credentials.userId
);
const downloads = await workspaceDatabase
@@ -229,7 +229,7 @@ class FileManager {
const attributes: FileAttributes = JSON.parse(file.attributes);
const filePath = path.join(
filesDir,
`${download.node_id}${attributes.extension}`,
`${download.node_id}${attributes.extension}`
);
if (fs.existsSync(filePath)) {
@@ -251,7 +251,7 @@ class FileManager {
serverDomain: credentials.serverDomain,
serverAttributes: credentials.serverAttributes,
token: credentials.token,
},
}
);
const presignedUrl = data.url;

View File

@@ -1,6 +1,6 @@
import { databaseManager } from '@/main/data/database-manager';
import { httpClient } from '@/lib/http-client';
import { MutationHandler, MutationResult } from '@/operations/mutations';
import { MutationHandler, MutationResult } from '@/main/types';
import { AccountUpdateOutput } from '@/types/accounts';
import { AccountUpdateMutationInput } from '@/operations/mutations/account-update';
@@ -8,7 +8,7 @@ export class AccountUpdateMutationHandler
implements MutationHandler<AccountUpdateMutationInput>
{
async handleMutation(
input: AccountUpdateMutationInput,
input: AccountUpdateMutationInput
): Promise<MutationResult<AccountUpdateMutationInput>> {
const account = await databaseManager.appDatabase
.selectFrom('accounts')
@@ -40,7 +40,7 @@ export class AccountUpdateMutationHandler
serverDomain: server.domain,
serverAttributes: server.attributes,
token: account.token,
},
}
);
await databaseManager.appDatabase

View File

@@ -1,7 +1,7 @@
import fs from 'fs';
import FormData from 'form-data';
import { databaseManager } from '@/main/data/database-manager';
import { MutationHandler, MutationResult } from '@/operations/mutations';
import { MutationHandler, MutationResult } from '@/main/types';
import { AvatarUploadMutationInput } from '@/operations/mutations/avatar-upload';
import { httpClient } from '@/lib/http-client';
@@ -13,7 +13,7 @@ export class AvatarUploadMutationHandler
implements MutationHandler<AvatarUploadMutationInput>
{
async handleMutation(
input: AvatarUploadMutationInput,
input: AvatarUploadMutationInput
): Promise<MutationResult<AvatarUploadMutationInput>> {
const credentials = await databaseManager.appDatabase
.selectFrom('accounts')
@@ -45,7 +45,7 @@ export class AvatarUploadMutationHandler
serverAttributes: credentials.attributes,
token: credentials.token,
headers: formData.getHeaders(),
},
}
);
return {

View File

@@ -1,19 +1,19 @@
import { databaseManager } from '@/main/data/database-manager';
import { generateId, IdType } from '@/lib/id';
import { generateNodeIndex } from '@/lib/nodes';
import { MutationHandler, MutationResult } from '@/operations/mutations';
import { MutationHandler, MutationResult } from '@/main/types';
import { ChannelCreateMutationInput } from '@/operations/mutations/channel-create';
import { ChannelAttributes } from '@/registry';
import { ChannelAttributes } from '@colanode/core';
import { nodeManager } from '@/main/node-manager';
export class ChannelCreateMutationHandler
implements MutationHandler<ChannelCreateMutationInput>
{
async handleMutation(
input: ChannelCreateMutationInput,
input: ChannelCreateMutationInput
): Promise<MutationResult<ChannelCreateMutationInput>> {
const workspaceDatabase = await databaseManager.getWorkspaceDatabase(
input.userId,
input.userId
);
const maxIndexResult = await workspaceDatabase

View File

@@ -1,10 +1,10 @@
import { databaseManager } from '@/main/data/database-manager';
import { NodeRole, NodeTypes } from '@/lib/constants';
import { generateId, IdType } from '@/lib/id';
import { MutationHandler, MutationResult } from '@/operations/mutations';
import { MutationHandler, MutationResult } from '@/main/types';
import { ChatCreateMutationInput } from '@/operations/mutations/chat-create';
import { sql } from 'kysely';
import { ChatAttributes } from '@/registry';
import { ChatAttributes } from '@colanode/core';
import { nodeManager } from '@/main/node-manager';
interface ChatRow {
@@ -15,10 +15,10 @@ export class ChatCreateMutationHandler
implements MutationHandler<ChatCreateMutationInput>
{
public async handleMutation(
input: ChatCreateMutationInput,
input: ChatCreateMutationInput
): Promise<MutationResult<ChatCreateMutationInput>> {
const workspaceDatabase = await databaseManager.getWorkspaceDatabase(
input.userId,
input.userId
);
const query = sql<ChatRow>`

View File

@@ -1,8 +1,8 @@
import { generateId, IdType } from '@/lib/id';
import { generateNodeIndex } from '@/lib/nodes';
import { MutationHandler, MutationResult } from '@/operations/mutations';
import { MutationHandler, MutationResult } from '@/main/types';
import { DatabaseCreateMutationInput } from '@/operations/mutations/database-create';
import { DatabaseAttributes } from '@/registry';
import { DatabaseAttributes } from '@colanode/core';
import { nodeManager } from '@/main/node-manager';
import { databaseManager } from '@/main/data/database-manager';
@@ -10,10 +10,10 @@ export class DatabaseCreateMutationHandler
implements MutationHandler<DatabaseCreateMutationInput>
{
async handleMutation(
input: DatabaseCreateMutationInput,
input: DatabaseCreateMutationInput
): Promise<MutationResult<DatabaseCreateMutationInput>> {
const workspaceDatabase = await databaseManager.getWorkspaceDatabase(
input.userId,
input.userId
);
const databaseId = generateId(IdType.Database);

View File

@@ -1,14 +1,14 @@
import { MutationHandler, MutationResult } from '@/operations/mutations';
import { MutationHandler, MutationResult } from '@/main/types';
import { DocumentSaveMutationInput } from '@/operations/mutations/document-save';
import { mapContentsToBlocks } from '@/lib/editor';
import { Block } from '@/registry';
import { Block } from '@colanode/core';
import { nodeManager } from '@/main/node-manager';
export class DocumentSaveMutationHandler
implements MutationHandler<DocumentSaveMutationInput>
{
async handleMutation(
input: DocumentSaveMutationInput,
input: DocumentSaveMutationInput
): Promise<MutationResult<DocumentSaveMutationInput>> {
await nodeManager.updateNode(
input.userId,
@@ -28,7 +28,7 @@ export class DocumentSaveMutationHandler
const blocks = mapContentsToBlocks(
input.documentId,
input.content.content ?? [],
blocksMap,
blocksMap
);
attributes.content = blocks.reduce(
@@ -36,11 +36,11 @@ export class DocumentSaveMutationHandler
acc[block.id] = block;
return acc;
},
{} as Record<string, Block>,
{} as Record<string, Block>
);
return attributes;
},
}
);
return {

View File

@@ -1,18 +1,14 @@
import { LoginOutput } from '@/types/accounts';
import { databaseManager } from '@/main/data/database-manager';
import { EmailLoginMutationInput } from '@/operations/mutations/email-login';
import {
MutationChange,
MutationHandler,
MutationResult,
} from '@/operations/mutations';
import { MutationChange, MutationHandler, MutationResult } from '@/main/types';
import { httpClient } from '@/lib/http-client';
export class EmailLoginMutationHandler
implements MutationHandler<EmailLoginMutationInput>
{
async handleMutation(
input: EmailLoginMutationInput,
input: EmailLoginMutationInput
): Promise<MutationResult<EmailLoginMutationInput>> {
const server = await databaseManager.appDatabase
.selectFrom('servers')
@@ -37,7 +33,7 @@ export class EmailLoginMutationHandler
{
serverDomain: server.domain,
serverAttributes: server.attributes,
},
}
);
const changedTables: MutationChange[] = [];
@@ -77,7 +73,7 @@ export class EmailLoginMutationHandler
description: workspace.description,
user_id: workspace.user.id,
version_id: workspace.versionId,
})),
}))
)
.execute();
@@ -89,7 +85,7 @@ export class EmailLoginMutationHandler
for (const workspace of data.workspaces) {
const workspaceDatabase = await databaseManager.getWorkspaceDatabase(
workspace.user.id,
workspace.user.id
);
const user = workspace.user.node;

View File

@@ -2,17 +2,13 @@ import { LoginOutput } from '@/types/accounts';
import { databaseManager } from '@/main/data/database-manager';
import { httpClient } from '@/lib/http-client';
import { EmailRegisterMutationInput } from '@/operations/mutations/email-register';
import {
MutationChange,
MutationHandler,
MutationResult,
} from '@/operations/mutations';
import { MutationChange, MutationHandler, MutationResult } from '@/main/types';
export class EmailRegisterMutationHandler
implements MutationHandler<EmailRegisterMutationInput>
{
handleMutation = async (
input: EmailRegisterMutationInput,
input: EmailRegisterMutationInput
): Promise<MutationResult<EmailRegisterMutationInput>> => {
const server = await databaseManager.appDatabase
.selectFrom('servers')
@@ -38,7 +34,7 @@ export class EmailRegisterMutationHandler
{
serverDomain: server.domain,
serverAttributes: server.attributes,
},
}
);
const changedTables: MutationChange[] = [];
@@ -78,7 +74,7 @@ export class EmailRegisterMutationHandler
description: workspace.description,
user_id: workspace.user.id,
version_id: workspace.versionId,
})),
}))
)
.execute();
@@ -90,7 +86,7 @@ export class EmailRegisterMutationHandler
for (const workspace of data.workspaces) {
const workspaceDatabase = await databaseManager.getWorkspaceDatabase(
workspace.user.id,
workspace.user.id
);
const user = workspace.user.node;

View File

@@ -1,7 +1,7 @@
import { generateId, IdType } from '@/lib/id';
import { generateNodeIndex } from '@/lib/nodes';
import { compareString } from '@/lib/utils';
import { MutationHandler, MutationResult } from '@/operations/mutations';
import { MutationHandler, MutationResult } from '@/main/types';
import { FieldCreateMutationInput } from '@/operations/mutations/field-create';
import { nodeManager } from '@/main/node-manager';
@@ -9,7 +9,7 @@ export class FieldCreateMutationHandler
implements MutationHandler<FieldCreateMutationInput>
{
async handleMutation(
input: FieldCreateMutationInput,
input: FieldCreateMutationInput
): Promise<MutationResult<FieldCreateMutationInput>> {
const fieldId = generateId(IdType.Field);
await nodeManager.updateNode(
@@ -34,7 +34,7 @@ export class FieldCreateMutationHandler
};
return attributes;
},
}
);
return {

View File

@@ -1,18 +1,18 @@
import { databaseManager } from '@/main/data/database-manager';
import { MutationHandler, MutationResult } from '@/operations/mutations';
import { MutationHandler, MutationResult } from '@/main/types';
import { generateId, IdType } from '@/lib/id';
import { FileCreateMutationInput } from '@/operations/mutations/file-create';
import { fileManager } from '@/main/file-manager';
import { FileAttributes } from '@/registry';
import { FileAttributes } from '@colanode/core';
import { nodeManager } from '@/main/node-manager';
export class FileCreateMutationHandler
implements MutationHandler<FileCreateMutationInput>
{
async handleMutation(
input: FileCreateMutationInput,
input: FileCreateMutationInput
): Promise<MutationResult<FileCreateMutationInput>> {
const workspaceDatabase = await databaseManager.getWorkspaceDatabase(
input.userId,
input.userId
);
const metadata = fileManager.getFileMetadata(input.filePath);
@@ -25,7 +25,7 @@ export class FileCreateMutationHandler
input.filePath,
id,
metadata.extension,
input.userId,
input.userId
);
const attributes: FileAttributes = {

View File

@@ -1,15 +1,15 @@
import { databaseManager } from '@/main/data/database-manager';
import { MutationHandler, MutationResult } from '@/operations/mutations';
import { MutationHandler, MutationResult } from '@/main/types';
import { FileDownloadMutationInput } from '@/operations/mutations/file-download';
export class FileDownloadMutationHandler
implements MutationHandler<FileDownloadMutationInput>
{
async handleMutation(
input: FileDownloadMutationInput,
input: FileDownloadMutationInput
): Promise<MutationResult<FileDownloadMutationInput>> {
const workspaceDatabase = await databaseManager.getWorkspaceDatabase(
input.userId,
input.userId
);
const node = await workspaceDatabase

View File

@@ -1,7 +1,7 @@
import { generateId, IdType } from '@/lib/id';
import { MutationHandler, MutationResult } from '@/operations/mutations';
import { MutationHandler, MutationResult } from '@/main/types';
import { FolderCreateMutationInput } from '@/operations/mutations/folder-create';
import { FolderAttributes } from '@/registry';
import { FolderAttributes } from '@colanode/core';
import { nodeManager } from '@/main/node-manager';
import { databaseManager } from '@/main/data/database-manager';
@@ -9,10 +9,10 @@ export class FolderCreateMutationHandler
implements MutationHandler<FolderCreateMutationInput>
{
async handleMutation(
input: FolderCreateMutationInput,
input: FolderCreateMutationInput
): Promise<MutationResult<FolderCreateMutationInput>> {
const workspaceDatabase = await databaseManager.getWorkspaceDatabase(
input.userId,
input.userId
);
const attributes: FolderAttributes = {

View File

@@ -1,4 +1,5 @@
import { MutationHandler, MutationMap } from '@/operations/mutations';
import { MutationMap } from '@/operations/mutations';
import { MutationHandler } from '@/main/types';
import { EmailLoginMutationHandler } from '@/main/handlers/mutations/email-login';
import { EmailRegisterMutationHandler } from '@/main/handlers/mutations/email-register';
import { ViewCreateMutationHandler } from '@/main/handlers/mutations/view-create';

View File

@@ -1,7 +1,7 @@
import fs from 'fs';
import { databaseManager } from '@/main/data/database-manager';
import { LogoutMutationInput } from '@/operations/mutations/logout';
import { MutationHandler, MutationResult } from '@/operations/mutations';
import { MutationHandler, MutationResult } from '@/main/types';
import {
getAccountAvatarsDirectoryPath,
getWorkspaceDirectoryPath,
@@ -11,7 +11,7 @@ export class LogoutMutationHandler
implements MutationHandler<LogoutMutationInput>
{
async handleMutation(
input: LogoutMutationInput,
input: LogoutMutationInput
): Promise<MutationResult<LogoutMutationInput>> {
const account = await databaseManager.appDatabase
.selectFrom('accounts')

View File

@@ -1,6 +1,6 @@
import { generateId, IdType } from '@/lib/id';
import { databaseManager } from '@/main/data/database-manager';
import { MutationHandler, MutationResult } from '@/operations/mutations';
import { MutationHandler, MutationResult } from '@/main/types';
import { MarkNodeAsSeenMutationInput } from '@/operations/mutations/mark-node-as-seen';
import { LocalUserNodeChangeData } from '@/types/sync';
@@ -8,10 +8,10 @@ export class MarkNodeAsSeenMutationHandler
implements MutationHandler<MarkNodeAsSeenMutationInput>
{
async handleMutation(
input: MarkNodeAsSeenMutationInput,
input: MarkNodeAsSeenMutationInput
): Promise<MutationResult<MarkNodeAsSeenMutationInput>> {
const workspaceDatabase = await databaseManager.getWorkspaceDatabase(
input.userId,
input.userId
);
const changeData: LocalUserNodeChangeData = {

View File

@@ -2,27 +2,27 @@ import * as Y from 'yjs';
import { databaseManager } from '@/main/data/database-manager';
import { EditorNodeTypes, NodeTypes } from '@/lib/constants';
import { generateId, IdType } from '@/lib/id';
import {
MutationChange,
MutationHandler,
MutationResult,
} from '@/operations/mutations';
import { MutationChange, MutationHandler, MutationResult } from '@/main/types';
import { MessageCreateMutationInput } from '@/operations/mutations/message-create';
import { mapContentsToBlocks } from '@/lib/editor';
import { fileManager } from '@/main/file-manager';
import { CreateDownload, CreateUpload } from '@/main/data/workspace/schema';
import { NodeAttributes } from '@/registry';
import { Block, FileAttributes, MessageAttributes } from '@/registry';
import {
NodeAttributes,
Block,
FileAttributes,
MessageAttributes,
} from '@colanode/core';
import { nodeManager } from '@/main/node-manager';
export class MessageCreateMutationHandler
implements MutationHandler<MessageCreateMutationInput>
{
async handleMutation(
input: MessageCreateMutationInput,
input: MessageCreateMutationInput
): Promise<MutationResult<MessageCreateMutationInput>> {
const workspaceDatabase = await databaseManager.getWorkspaceDatabase(
input.userId,
input.userId
);
const nodeAttributes: NodeAttributes[] = [];
@@ -34,7 +34,7 @@ export class MessageCreateMutationHandler
const blocks = mapContentsToBlocks(
messageId,
input.content.content ?? [],
new Map(),
new Map()
);
// check if there are nested nodes (files, pages, folders etc.)
@@ -56,7 +56,7 @@ export class MessageCreateMutationHandler
path,
fileId,
metadata.extension,
input.userId,
input.userId
);
const fileDoc = new Y.Doc({
@@ -110,7 +110,7 @@ export class MessageCreateMutationHandler
acc[block.id] = block;
return acc;
},
{} as Record<string, Block>,
{} as Record<string, Block>
),
reactions: {},
};
@@ -123,7 +123,7 @@ export class MessageCreateMutationHandler
trx,
input.userId,
messageId,
nodeAttribute,
nodeAttribute
);
}

View File

@@ -1,4 +1,4 @@
import { MutationHandler, MutationResult } from '@/operations/mutations';
import { MutationHandler, MutationResult } from '@/main/types';
import { NodeAttributeDeleteMutationInput } from '@/operations/mutations/node-attribute-delete';
import { nodeManager } from '@/main/node-manager';
import { unset } from 'lodash';
@@ -7,7 +7,7 @@ export class NodeAttributeDeleteMutationHandler
implements MutationHandler<NodeAttributeDeleteMutationInput>
{
async handleMutation(
input: NodeAttributeDeleteMutationInput,
input: NodeAttributeDeleteMutationInput
): Promise<MutationResult<NodeAttributeDeleteMutationInput>> {
await nodeManager.updateNode(input.userId, input.nodeId, (attributes) => {
unset(attributes, input.path);

View File

@@ -1,4 +1,4 @@
import { MutationHandler, MutationResult } from '@/operations/mutations';
import { MutationHandler, MutationResult } from '@/main/types';
import { NodeAttributeSetMutationInput } from '@/operations/mutations/node-attribute-set';
import { nodeManager } from '@/main/node-manager';
import { set } from 'lodash';
@@ -7,7 +7,7 @@ export class NodeAttributeSetMutationHandler
implements MutationHandler<NodeAttributeSetMutationInput>
{
async handleMutation(
input: NodeAttributeSetMutationInput,
input: NodeAttributeSetMutationInput
): Promise<MutationResult<NodeAttributeSetMutationInput>> {
await nodeManager.updateNode(input.userId, input.nodeId, (attributes) => {
set(attributes, input.path, input.value);

View File

@@ -1,4 +1,4 @@
import { MutationHandler, MutationResult } from '@/operations/mutations';
import { MutationHandler, MutationResult } from '@/main/types';
import { NodeCollaboratorCreateMutationInput } from '@/operations/mutations/node-collaborator-create';
import { nodeManager } from '@/main/node-manager';
import { set } from 'lodash';
@@ -7,7 +7,7 @@ export class NodeCollaboratorCreateMutationHandler
implements MutationHandler<NodeCollaboratorCreateMutationInput>
{
async handleMutation(
input: NodeCollaboratorCreateMutationInput,
input: NodeCollaboratorCreateMutationInput
): Promise<MutationResult<NodeCollaboratorCreateMutationInput>> {
await nodeManager.updateNode(input.userId, input.nodeId, (attributes) => {
for (const collaboratorId of input.collaboratorIds) {

View File

@@ -1,5 +1,5 @@
import { nodeManager } from '@/main/node-manager';
import { MutationHandler, MutationResult } from '@/operations/mutations';
import { MutationHandler, MutationResult } from '@/main/types';
import { NodeCollaboratorDeleteMutationInput } from '@/operations/mutations/node-collaborator-delete';
import { unset } from 'lodash';
@@ -7,7 +7,7 @@ export class NodeCollaboratorDeleteMutationHandler
implements MutationHandler<NodeCollaboratorDeleteMutationInput>
{
async handleMutation(
input: NodeCollaboratorDeleteMutationInput,
input: NodeCollaboratorDeleteMutationInput
): Promise<MutationResult<NodeCollaboratorDeleteMutationInput>> {
await nodeManager.updateNode(input.userId, input.nodeId, (attributes) => {
unset(attributes, `collaborators.${input.collaboratorId}`);

View File

@@ -1,5 +1,5 @@
import { nodeManager } from '@/main/node-manager';
import { MutationHandler, MutationResult } from '@/operations/mutations';
import { MutationHandler, MutationResult } from '@/main/types';
import { NodeCollaboratorUpdateMutationInput } from '@/operations/mutations/node-collaborator-update';
import { set } from 'lodash';
@@ -7,7 +7,7 @@ export class NodeCollaboratorUpdateMutationHandler
implements MutationHandler<NodeCollaboratorUpdateMutationInput>
{
async handleMutation(
input: NodeCollaboratorUpdateMutationInput,
input: NodeCollaboratorUpdateMutationInput
): Promise<MutationResult<NodeCollaboratorUpdateMutationInput>> {
await nodeManager.updateNode(input.userId, input.nodeId, (attributes) => {
set(attributes, `collaborators.${input.collaboratorId}`, input.role);

View File

@@ -1,11 +1,7 @@
import { NodeTypes } from '@/lib/constants';
import { databaseManager } from '@/main/data/database-manager';
import { fileManager } from '@/main/file-manager';
import {
MutationChange,
MutationHandler,
MutationResult,
} from '@/operations/mutations';
import { MutationChange, MutationHandler, MutationResult } from '@/main/types';
import { NodeDeleteMutationInput } from '@/operations/mutations/node-delete';
import { LocalDeleteNodeChangeData } from '@/types/sync';
@@ -13,10 +9,10 @@ export class NodeDeleteMutationHandler
implements MutationHandler<NodeDeleteMutationInput>
{
async handleMutation(
input: NodeDeleteMutationInput,
input: NodeDeleteMutationInput
): Promise<MutationResult<NodeDeleteMutationInput>> {
const workspaceDatabase = await databaseManager.getWorkspaceDatabase(
input.userId,
input.userId
);
const node = await workspaceDatabase

View File

@@ -1,12 +1,12 @@
import { nodeManager } from '@/main/node-manager';
import { MutationHandler, MutationResult } from '@/operations/mutations';
import { MutationHandler, MutationResult } from '@/main/types';
import { NodeReactionCreateMutationInput } from '@/operations/mutations/node-reaction-create';
export class NodeReactionCreateMutationHandler
implements MutationHandler<NodeReactionCreateMutationInput>
{
async handleMutation(
input: NodeReactionCreateMutationInput,
input: NodeReactionCreateMutationInput
): Promise<MutationResult<NodeReactionCreateMutationInput>> {
await nodeManager.updateNode(input.userId, input.nodeId, (attributes) => {
if (attributes.type !== 'message') {

View File

@@ -1,12 +1,12 @@
import { nodeManager } from '@/main/node-manager';
import { MutationHandler, MutationResult } from '@/operations/mutations';
import { MutationHandler, MutationResult } from '@/main/types';
import { NodeReactionDeleteMutationInput } from '@/operations/mutations/node-reaction-delete';
export class NodeReactionDeleteMutationHandler
implements MutationHandler<NodeReactionDeleteMutationInput>
{
async handleMutation(
input: NodeReactionDeleteMutationInput,
input: NodeReactionDeleteMutationInput
): Promise<MutationResult<NodeReactionDeleteMutationInput>> {
await nodeManager.updateNode(input.userId, input.nodeId, (attributes) => {
if (attributes.type !== 'message') {

View File

@@ -1,18 +1,18 @@
import { databaseManager } from '@/main/data/database-manager';
import { generateId, IdType } from '@/lib/id';
import { MutationHandler, MutationResult } from '@/operations/mutations';
import { MutationHandler, MutationResult } from '@/main/types';
import { PageCreateMutationInput } from '@/operations/mutations/page-create';
import { PageAttributes } from '@/registry';
import { PageAttributes } from '@colanode/core';
import { nodeManager } from '@/main/node-manager';
export class PageCreateMutationHandler
implements MutationHandler<PageCreateMutationInput>
{
async handleMutation(
input: PageCreateMutationInput,
input: PageCreateMutationInput
): Promise<MutationResult<PageCreateMutationInput>> {
const workspaceDatabase = await databaseManager.getWorkspaceDatabase(
input.userId,
input.userId
);
const id = generateId(IdType.Page);

View File

@@ -1,18 +1,18 @@
import { databaseManager } from '@/main/data/database-manager';
import { generateId, IdType } from '@/lib/id';
import { MutationHandler, MutationResult } from '@/operations/mutations';
import { MutationHandler, MutationResult } from '@/main/types';
import { RecordCreateMutationInput } from '@/operations/mutations/record-create';
import { RecordAttributes } from '@/registry';
import { RecordAttributes } from '@colanode/core';
import { nodeManager } from '@/main/node-manager';
export class RecordCreateMutationHandler
implements MutationHandler<RecordCreateMutationInput>
{
async handleMutation(
input: RecordCreateMutationInput,
input: RecordCreateMutationInput
): Promise<MutationResult<RecordCreateMutationInput>> {
const workspaceDatabase = await databaseManager.getWorkspaceDatabase(
input.userId,
input.userId
);
const id = generateId(IdType.Record);

View File

@@ -1,6 +1,6 @@
import { generateId, IdType } from '@/lib/id';
import { generateNodeIndex } from '@/lib/nodes';
import { MutationHandler, MutationResult } from '@/operations/mutations';
import { MutationHandler, MutationResult } from '@/main/types';
import { SelectOptionCreateMutationInput } from '@/operations/mutations/select-option-create';
import { compareString } from '@/lib/utils';
import { nodeManager } from '@/main/node-manager';
@@ -9,7 +9,7 @@ export class SelectOptionCreateMutationHandler
implements MutationHandler<SelectOptionCreateMutationInput>
{
async handleMutation(
input: SelectOptionCreateMutationInput,
input: SelectOptionCreateMutationInput
): Promise<MutationResult<SelectOptionCreateMutationInput>> {
const id = generateId(IdType.SelectOption);
await nodeManager.updateNode(
@@ -48,7 +48,7 @@ export class SelectOptionCreateMutationHandler
};
return attributes;
},
}
);
return {

View File

@@ -1,6 +1,6 @@
import axios from 'axios';
import { databaseManager } from '@/main/data/database-manager';
import { MutationHandler, MutationResult } from '@/operations/mutations';
import { MutationHandler, MutationResult } from '@/main/types';
import { ServerCreateMutationInput } from '@/operations/mutations/server-create';
import { ServerConfig } from '@/types/servers';
@@ -8,10 +8,10 @@ export class ServerCreateMutationHandler
implements MutationHandler<ServerCreateMutationInput>
{
async handleMutation(
input: ServerCreateMutationInput,
input: ServerCreateMutationInput
): Promise<MutationResult<ServerCreateMutationInput>> {
const { data } = await axios.get<ServerConfig>(
`http://${input.domain}/v1/config`,
`http://${input.domain}/v1/config`
);
await databaseManager.appDatabase

View File

@@ -1,17 +1,13 @@
import { databaseManager } from '@/main/data/database-manager';
import { socketManager } from '@/main/sockets/socket-manager';
import {
MutationChange,
MutationHandler,
MutationResult,
} from '@/operations/mutations';
import { MutationChange, MutationHandler, MutationResult } from '@/main/types';
import { ServerNodeDeleteMutationInput } from '@/operations/mutations/server-node-delete';
export class ServerNodeDeleteMutationHandler
implements MutationHandler<ServerNodeDeleteMutationInput>
{
public async handleMutation(
input: ServerNodeDeleteMutationInput,
input: ServerNodeDeleteMutationInput
): Promise<MutationResult<ServerNodeDeleteMutationInput>> {
const changes: MutationChange[] = [];
@@ -22,7 +18,7 @@ export class ServerNodeDeleteMutationHandler
eb.and([
eb('account_id', '=', input.accountId),
eb('workspace_id', '=', input.workspaceId),
]),
])
)
.executeTakeFirst();

View File

@@ -1,7 +1,7 @@
import { databaseManager } from '@/main/data/database-manager';
import { socketManager } from '@/main/sockets/socket-manager';
import { hasInsertChanges, hasUpdateChanges } from '@/main/utils';
import { MutationHandler, MutationResult } from '@/operations/mutations';
import { MutationHandler, MutationResult } from '@/main/types';
import { ServerNodeSyncMutationInput } from '@/operations/mutations/server-node-sync';
import { toUint8Array } from 'js-base64';
import * as Y from 'yjs';
@@ -10,7 +10,7 @@ export class ServerNodeSyncMutationHandler
implements MutationHandler<ServerNodeSyncMutationInput>
{
public async handleMutation(
input: ServerNodeSyncMutationInput,
input: ServerNodeSyncMutationInput
): Promise<MutationResult<ServerNodeSyncMutationInput>> {
const workspace = await databaseManager.appDatabase
.selectFrom('workspaces')
@@ -19,7 +19,7 @@ export class ServerNodeSyncMutationHandler
eb.and([
eb('account_id', '=', input.accountId),
eb('workspace_id', '=', input.workspaceId),
]),
])
)
.executeTakeFirst();

View File

@@ -1,13 +1,13 @@
import { databaseManager } from '@/main/data/database-manager';
import { socketManager } from '@/main/sockets/socket-manager';
import { MutationHandler, MutationResult } from '@/operations/mutations';
import { MutationHandler, MutationResult } from '@/main/types';
import { ServerUserNodeSyncMutationInput } from '@/operations/mutations/server-user-node-sync';
export class ServerUserNodeSyncMutationHandler
implements MutationHandler<ServerUserNodeSyncMutationInput>
{
public async handleMutation(
input: ServerUserNodeSyncMutationInput,
input: ServerUserNodeSyncMutationInput
): Promise<MutationResult<ServerUserNodeSyncMutationInput>> {
const workspace = await databaseManager.appDatabase
.selectFrom('workspaces')
@@ -16,7 +16,7 @@ export class ServerUserNodeSyncMutationHandler
eb.and([
eb('account_id', '=', input.accountId),
eb('workspace_id', '=', input.workspaceId),
]),
])
)
.executeTakeFirst();
@@ -51,7 +51,7 @@ export class ServerUserNodeSyncMutationHandler
mentions_count: input.mentionsCount,
updated_at: input.updatedAt,
version_id: input.versionId,
}),
})
)
.execute();

View File

@@ -1,20 +1,24 @@
import { databaseManager } from '@/main/data/database-manager';
import { generateId, IdType } from '@/lib/id';
import { generateNodeIndex } from '@/lib/nodes';
import { MutationHandler, MutationResult } from '@/operations/mutations';
import { MutationHandler, MutationResult } from '@/main/types';
import { SpaceCreateMutationInput } from '@/operations/mutations/space-create';
import { NodeRole } from '@/lib/constants';
import { ChannelAttributes, PageAttributes, SpaceAttributes } from '@/registry';
import {
ChannelAttributes,
PageAttributes,
SpaceAttributes,
} from '@colanode/core';
import { nodeManager } from '@/main/node-manager';
export class SpaceCreateMutationHandler
implements MutationHandler<SpaceCreateMutationInput>
{
async handleMutation(
input: SpaceCreateMutationInput,
input: SpaceCreateMutationInput
): Promise<MutationResult<SpaceCreateMutationInput>> {
const workspaceDatabase = await databaseManager.getWorkspaceDatabase(
input.userId,
input.userId
);
const spaceId = generateId(IdType.Space);
@@ -53,7 +57,7 @@ export class SpaceCreateMutationHandler
trx,
input.userId,
channelId,
channelAttributes,
channelAttributes
);
});

View File

@@ -1,4 +1,4 @@
import { MutationHandler, MutationResult } from '@/operations/mutations';
import { MutationHandler, MutationResult } from '@/main/types';
import { SpaceUpdateMutationInput } from '@/operations/mutations/space-update';
import { nodeManager } from '@/main/node-manager';
@@ -6,7 +6,7 @@ export class SpaceUpdateMutationHandler
implements MutationHandler<SpaceUpdateMutationInput>
{
async handleMutation(
input: SpaceUpdateMutationInput,
input: SpaceUpdateMutationInput
): Promise<MutationResult<SpaceUpdateMutationInput>> {
await nodeManager.updateNode(input.userId, input.id, (attributes) => {
if (attributes.type !== 'space') {

View File

@@ -1,5 +1,5 @@
import { generateId, IdType } from '@/lib/id';
import { MutationHandler, MutationResult } from '@/operations/mutations';
import { MutationHandler, MutationResult } from '@/main/types';
import { ViewCreateMutationInput } from '@/operations/mutations/view-create';
import { compareString } from '@/lib/utils';
import { generateNodeIndex } from '@/lib/nodes';
@@ -9,7 +9,7 @@ export class ViewCreateMutationHandler
implements MutationHandler<ViewCreateMutationInput>
{
async handleMutation(
input: ViewCreateMutationInput,
input: ViewCreateMutationInput
): Promise<MutationResult<ViewCreateMutationInput>> {
const id = generateId(IdType.View);
await nodeManager.updateNode(
@@ -37,7 +37,7 @@ export class ViewCreateMutationHandler
};
return attributes;
},
}
);
return {

View File

@@ -1,4 +1,4 @@
import { MutationHandler, MutationResult } from '@/operations/mutations';
import { MutationHandler, MutationResult } from '@/main/types';
import { nodeManager } from '@/main/node-manager';
import { ViewDeleteMutationInput } from '@/operations/mutations/view-delete';
@@ -6,7 +6,7 @@ export class ViewDeleteMutationHandler
implements MutationHandler<ViewDeleteMutationInput>
{
async handleMutation(
input: ViewDeleteMutationInput,
input: ViewDeleteMutationInput
): Promise<MutationResult<ViewDeleteMutationInput>> {
await nodeManager.updateNode(
input.userId,
@@ -18,7 +18,7 @@ export class ViewDeleteMutationHandler
delete attributes.views[input.viewId];
return attributes;
},
}
);
return {

View File

@@ -1,4 +1,4 @@
import { MutationHandler, MutationResult } from '@/operations/mutations';
import { MutationHandler, MutationResult } from '@/main/types';
import { nodeManager } from '@/main/node-manager';
import { ViewUpdateMutationInput } from '@/operations/mutations/view-update';
@@ -6,7 +6,7 @@ export class ViewUpdateMutationHandler
implements MutationHandler<ViewUpdateMutationInput>
{
async handleMutation(
input: ViewUpdateMutationInput,
input: ViewUpdateMutationInput
): Promise<MutationResult<ViewUpdateMutationInput>> {
await nodeManager.updateNode(
input.userId,
@@ -18,7 +18,7 @@ export class ViewUpdateMutationHandler
attributes.views[input.view.id] = input.view;
return attributes;
},
}
);
return {

View File

@@ -1,14 +1,14 @@
import { databaseManager } from '@/main/data/database-manager';
import { httpClient } from '@/lib/http-client';
import { WorkspaceCreateMutationInput } from '@/operations/mutations/workspace-create';
import { MutationHandler, MutationResult } from '@/operations/mutations';
import { MutationHandler, MutationResult } from '@/main/types';
import { WorkspaceOutput } from '@/types/workspaces';
export class WorkspaceCreateMutationHandler
implements MutationHandler<WorkspaceCreateMutationInput>
{
async handleMutation(
input: WorkspaceCreateMutationInput,
input: WorkspaceCreateMutationInput
): Promise<MutationResult<WorkspaceCreateMutationInput>> {
const account = await databaseManager.appDatabase
.selectFrom('accounts')
@@ -41,7 +41,7 @@ export class WorkspaceCreateMutationHandler
serverDomain: server.domain,
serverAttributes: server.attributes,
token: account.token,
},
}
);
await databaseManager.appDatabase
@@ -60,7 +60,7 @@ export class WorkspaceCreateMutationHandler
.execute();
const workspaceDatabase = await databaseManager.getWorkspaceDatabase(
data.user.id,
data.user.id
);
const user = data.user.node;

View File

@@ -1,18 +1,14 @@
import { databaseManager } from '@/main/data/database-manager';
import { httpClient } from '@/lib/http-client';
import { WorkspaceUpdateMutationInput } from '@/operations/mutations/workspace-update';
import {
MutationChange,
MutationHandler,
MutationResult,
} from '@/operations/mutations';
import { MutationHandler, MutationResult } from '@/main/types';
import { Workspace } from '@/types/workspaces';
export class WorkspaceUpdateMutationHandler
implements MutationHandler<WorkspaceUpdateMutationInput>
{
async handleMutation(
input: WorkspaceUpdateMutationInput,
input: WorkspaceUpdateMutationInput
): Promise<MutationResult<WorkspaceUpdateMutationInput>> {
const account = await databaseManager.appDatabase
.selectFrom('accounts')
@@ -45,7 +41,7 @@ export class WorkspaceUpdateMutationHandler
serverDomain: server.domain,
serverAttributes: server.attributes,
token: account.token,
},
}
);
await databaseManager.appDatabase
@@ -61,7 +57,7 @@ export class WorkspaceUpdateMutationHandler
eb.and([
eb('account_id', '=', input.accountId),
eb('workspace_id', '=', input.id),
]),
])
)
.execute();

View File

@@ -1,18 +1,14 @@
import { databaseManager } from '@/main/data/database-manager';
import { httpClient } from '@/lib/http-client';
import { WorkspaceUserRoleUpdateMutationInput } from '@/operations/mutations/workspace-user-role-update';
import {
MutationChange,
MutationHandler,
MutationResult,
} from '@/operations/mutations';
import { MutationChange, MutationHandler, MutationResult } from '@/main/types';
import { WorkspaceUserRoleUpdateOutput } from '@/types/workspaces';
export class WorkspaceUserRoleUpdateMutationHandler
implements MutationHandler<WorkspaceUserRoleUpdateMutationInput>
{
async handleMutation(
input: WorkspaceUserRoleUpdateMutationInput,
input: WorkspaceUserRoleUpdateMutationInput
): Promise<MutationResult<WorkspaceUserRoleUpdateMutationInput>> {
const workspace = await databaseManager.appDatabase
.selectFrom('workspaces')
@@ -65,11 +61,11 @@ export class WorkspaceUserRoleUpdateMutationHandler
serverDomain: server.domain,
serverAttributes: server.attributes,
token: account.token,
},
}
);
const workspaceDatabase = await databaseManager.getWorkspaceDatabase(
input.userId,
input.userId
);
await workspaceDatabase

View File

@@ -1,11 +1,7 @@
import { databaseManager } from '@/main/data/database-manager';
import { httpClient } from '@/lib/http-client';
import { WorkspaceUsersInviteMutationInput } from '@/operations/mutations/workspace-users-invite';
import {
MutationChange,
MutationHandler,
MutationResult,
} from '@/operations/mutations';
import { MutationChange, MutationHandler, MutationResult } from '@/main/types';
import { WorkspaceUsersInviteOutput } from '@/types/workspaces';
import { CreateNode } from '@/main/data/workspace/schema';
@@ -13,7 +9,7 @@ export class WorkspaceUsersInviteMutationHandler
implements MutationHandler<WorkspaceUsersInviteMutationInput>
{
async handleMutation(
input: WorkspaceUsersInviteMutationInput,
input: WorkspaceUsersInviteMutationInput
): Promise<MutationResult<WorkspaceUsersInviteMutationInput>> {
const workspace = await databaseManager.appDatabase
.selectFrom('workspaces')
@@ -66,11 +62,11 @@ export class WorkspaceUsersInviteMutationHandler
serverDomain: server.domain,
serverAttributes: server.attributes,
token: account.token,
},
}
);
const workspaceDatabase = await databaseManager.getWorkspaceDatabase(
input.userId,
input.userId
);
const usersToCreate: CreateNode[] = data.users.map((user) => {

View File

@@ -1,20 +1,20 @@
import { AccountListQueryInput } from '@/operations/queries/account-list';
import { databaseManager } from '@/main/data/database-manager';
import { Account } from '@/types/accounts';
import { SelectAccount } from '@/main/data/app/schema';
import { isEqual } from 'lodash';
import {
MutationChange,
ChangeCheckResult,
QueryHandler,
QueryResult,
} from '@/operations/queries';
import { SelectAccount } from '@/main/data/app/schema';
import { isEqual } from 'lodash';
import { MutationChange } from '@/operations/mutations';
} from '@/main/types';
export class AccountListQueryHandler
implements QueryHandler<AccountListQueryInput>
{
public async handleQuery(
_: AccountListQueryInput,
_: AccountListQueryInput
): Promise<QueryResult<AccountListQueryInput>> {
const rows = await this.fetchAccounts();
return {
@@ -28,11 +28,11 @@ export class AccountListQueryHandler
public async checkForChanges(
changes: MutationChange[],
_: AccountListQueryInput,
state: Record<string, any>,
state: Record<string, any>
): Promise<ChangeCheckResult<AccountListQueryInput>> {
if (
!changes.some(
(change) => change.type === 'app' && change.table === 'accounts',
(change) => change.type === 'app' && change.table === 'accounts'
)
) {
return {

View File

@@ -1,22 +1,22 @@
import { BreadcrumbListQueryInput } from '@/operations/queries/breadcrumb-list';
import { databaseManager } from '@/main/data/database-manager';
import {
ChangeCheckResult,
QueryHandler,
QueryResult,
} from '@/operations/queries';
import { sql } from 'kysely';
import { SelectNode } from '@/main/data/workspace/schema';
import { BreadcrumbNode } from '@/types/workspaces';
import { mapNode } from '@/lib/nodes';
import { mapNode } from '@/main/utils';
import { isEqual } from 'lodash';
import { MutationChange } from '@/operations/mutations';
import {
MutationChange,
ChangeCheckResult,
QueryHandler,
QueryResult,
} from '@/main/types';
export class BreadcrumbListQueryHandler
implements QueryHandler<BreadcrumbListQueryInput>
{
public async handleQuery(
input: BreadcrumbListQueryInput,
input: BreadcrumbListQueryInput
): Promise<QueryResult<BreadcrumbListQueryInput>> {
const rows = await this.fetchNodes(input);
return {
@@ -30,14 +30,14 @@ export class BreadcrumbListQueryHandler
public async checkForChanges(
changes: MutationChange[],
input: BreadcrumbListQueryInput,
state: Record<string, any>,
state: Record<string, any>
): Promise<ChangeCheckResult<BreadcrumbListQueryInput>> {
if (
!changes.some(
(change) =>
change.type === 'workspace' &&
change.table === 'nodes' &&
change.userId === input.userId,
change.userId === input.userId
)
) {
return {
@@ -64,10 +64,10 @@ export class BreadcrumbListQueryHandler
}
private async fetchNodes(
input: BreadcrumbListQueryInput,
input: BreadcrumbListQueryInput
): Promise<SelectNode[]> {
const workspaceDatabase = await databaseManager.getWorkspaceDatabase(
input.userId,
input.userId
);
const query = sql<SelectNode>`
@@ -90,7 +90,7 @@ export class BreadcrumbListQueryHandler
private buildBreadcrumbNodes = (
nodeId: string,
rows: SelectNode[],
rows: SelectNode[]
): BreadcrumbNode[] => {
const breadcrumbNodes: BreadcrumbNode[] = [];

View File

@@ -1,19 +1,19 @@
import { ChatGetQueryInput } from '@/operations/queries/chat-get';
import { databaseManager } from '@/main/data/database-manager';
import { mapNode } from '@/main/utils';
import { SelectNode } from '@/main/data/workspace/schema';
import {
MutationChange,
ChangeCheckResult,
QueryHandler,
QueryResult,
} from '@/operations/queries';
import { mapNode } from '@/lib/nodes';
import { SelectNode } from '@/main/data/workspace/schema';
import { MutationChange } from '@/operations/mutations';
} from '@/main/types';
import { isEqual } from 'lodash';
import { ChatNode } from '@/types/chats';
export class ChatGetQueryHandler implements QueryHandler<ChatGetQueryInput> {
async handleQuery(
input: ChatGetQueryInput,
input: ChatGetQueryInput
): Promise<QueryResult<ChatGetQueryInput>> {
const chat = await this.fetchChat(input);
if (!chat) {
@@ -36,14 +36,14 @@ export class ChatGetQueryHandler implements QueryHandler<ChatGetQueryInput> {
async checkForChanges(
changes: MutationChange[],
input: ChatGetQueryInput,
state: Record<string, any>,
state: Record<string, any>
): Promise<ChangeCheckResult<ChatGetQueryInput>> {
if (
!changes.some(
(change) =>
change.type === 'workspace' &&
change.table === 'nodes' &&
change.userId === input.userId,
change.userId === input.userId
)
) {
return {
@@ -86,10 +86,10 @@ export class ChatGetQueryHandler implements QueryHandler<ChatGetQueryInput> {
}
private async fetchChat(
input: ChatGetQueryInput,
input: ChatGetQueryInput
): Promise<SelectNode | null> {
const workspaceDatabase = await databaseManager.getWorkspaceDatabase(
input.userId,
input.userId
);
const chat = await workspaceDatabase
@@ -103,10 +103,10 @@ export class ChatGetQueryHandler implements QueryHandler<ChatGetQueryInput> {
private async fetchCollaborators(
input: ChatGetQueryInput,
chat: SelectNode,
chat: SelectNode
): Promise<SelectNode[]> {
const workspaceDatabase = await databaseManager.getWorkspaceDatabase(
input.userId,
input.userId
);
if (!chat.attributes) {
@@ -144,7 +144,7 @@ export class ChatGetQueryHandler implements QueryHandler<ChatGetQueryInput> {
private buildChat = (
chat: SelectNode,
collaborators: SelectNode[],
collaborators: SelectNode[]
): ChatNode | null => {
const collaborator = mapNode(collaborators[0]);
if (collaborator.attributes.type !== 'user') {

View File

@@ -5,22 +5,21 @@ import {
DocumentGetQueryOutput,
} from '@/operations/queries/document-get';
import { databaseManager } from '@/main/data/database-manager';
import { SelectNode } from '@/main/data/workspace/schema';
import {
MutationChange,
ChangeCheckResult,
QueryHandler,
QueryResult,
} from '@/operations/queries';
import { SelectNode } from '@/main/data/workspace/schema';
import { MutationChange } from '@/operations/mutations';
import { NodeAttributes } from '@/registry';
} from '@/main/types';
import { NodeAttributes } from '@colanode/core';
import { mapBlocksToContents } from '@/lib/editor';
export class DocumentGetQueryHandler
implements QueryHandler<DocumentGetQueryInput>
{
public async handleQuery(
input: DocumentGetQueryInput,
input: DocumentGetQueryInput
): Promise<QueryResult<DocumentGetQueryInput>> {
const document = await this.fetchDocument(input);
return {
@@ -34,14 +33,14 @@ export class DocumentGetQueryHandler
public async checkForChanges(
changes: MutationChange[],
input: DocumentGetQueryInput,
state: Record<string, any>,
state: Record<string, any>
): Promise<ChangeCheckResult<DocumentGetQueryInput>> {
if (
!changes.some(
(change) =>
change.type === 'workspace' &&
change.table === 'nodes' &&
change.userId === input.userId,
change.userId === input.userId
)
) {
return {
@@ -68,10 +67,10 @@ export class DocumentGetQueryHandler
}
private async fetchDocument(
input: DocumentGetQueryInput,
input: DocumentGetQueryInput
): Promise<SelectNode | undefined> {
const workspaceDatabase = await databaseManager.getWorkspaceDatabase(
input.userId,
input.userId
);
return workspaceDatabase
@@ -82,7 +81,7 @@ export class DocumentGetQueryHandler
}
private buildOutput(
document: SelectNode | null | undefined,
document: SelectNode | null | undefined
): DocumentGetQueryOutput {
if (!document) {
return {

View File

@@ -1,11 +1,11 @@
import { FileGetQueryInput } from '@/operations/queries/file-get';
import { databaseManager } from '@/main/data/database-manager';
import {
MutationChange,
ChangeCheckResult,
QueryHandler,
QueryResult,
} from '@/operations/queries';
import { MutationChange } from '@/operations/mutations';
} from '@/main/types';
import { isEqual } from 'lodash';
import { FileDetails } from '@/types/files';
@@ -22,7 +22,7 @@ interface FileRow {
export class FileGetQueryHandler implements QueryHandler<FileGetQueryInput> {
public async handleQuery(
input: FileGetQueryInput,
input: FileGetQueryInput
): Promise<QueryResult<FileGetQueryInput>> {
const row = await this.fetchFile(input);
@@ -37,14 +37,14 @@ export class FileGetQueryHandler implements QueryHandler<FileGetQueryInput> {
public async checkForChanges(
changes: MutationChange[],
input: FileGetQueryInput,
state: Record<string, any>,
state: Record<string, any>
): Promise<ChangeCheckResult<FileGetQueryInput>> {
if (
!changes.some(
(change) =>
change.type === 'workspace' &&
(change.table === 'nodes' || change.table === 'downloads') &&
change.userId === input.userId,
change.userId === input.userId
)
) {
return {
@@ -71,19 +71,19 @@ export class FileGetQueryHandler implements QueryHandler<FileGetQueryInput> {
}
private async fetchFile(
input: FileGetQueryInput,
input: FileGetQueryInput
): Promise<FileRow | undefined> {
const workspaceDatabase = await databaseManager.getWorkspaceDatabase(
input.userId,
input.userId
);
const row = await workspaceDatabase
.selectFrom('nodes as file')
.leftJoin('downloads as file_downloads', (join) =>
join.onRef('file.id', '=', 'file_downloads.node_id'),
join.onRef('file.id', '=', 'file_downloads.node_id')
)
.leftJoin('nodes as created_by', (join) =>
join.onRef('file.created_by', '=', 'created_by.id'),
join.onRef('file.created_by', '=', 'created_by.id')
)
.select([
'file.id',

View File

@@ -1,11 +1,11 @@
import { FileListQueryInput } from '@/operations/queries/file-list';
import { databaseManager } from '@/main/data/database-manager';
import {
MutationChange,
ChangeCheckResult,
QueryHandler,
QueryResult,
} from '@/operations/queries';
import { MutationChange } from '@/operations/mutations';
} from '@/main/types';
import { NodeTypes } from '@/lib/constants';
import { compareString } from '@/lib/utils';
import { isEqual } from 'lodash';
@@ -23,7 +23,7 @@ interface FileRow {
export class FileListQueryHandler implements QueryHandler<FileListQueryInput> {
public async handleQuery(
input: FileListQueryInput,
input: FileListQueryInput
): Promise<QueryResult<FileListQueryInput>> {
const files = await this.fetchFiles(input);
@@ -38,14 +38,14 @@ export class FileListQueryHandler implements QueryHandler<FileListQueryInput> {
public async checkForChanges(
changes: MutationChange[],
input: FileListQueryInput,
state: Record<string, any>,
state: Record<string, any>
): Promise<ChangeCheckResult<FileListQueryInput>> {
if (
!changes.some(
(change) =>
change.type === 'workspace' &&
(change.table === 'nodes' || change.table === 'downloads') &&
change.userId === input.userId,
change.userId === input.userId
)
) {
return {
@@ -73,14 +73,14 @@ export class FileListQueryHandler implements QueryHandler<FileListQueryInput> {
private async fetchFiles(input: FileListQueryInput): Promise<FileRow[]> {
const workspaceDatabase = await databaseManager.getWorkspaceDatabase(
input.userId,
input.userId
);
const offset = input.page * input.count;
const files = await workspaceDatabase
.selectFrom('nodes')
.leftJoin('downloads', (join) =>
join.onRef('nodes.id', '=', 'downloads.node_id'),
join.onRef('nodes.id', '=', 'downloads.node_id')
)
.select([
'nodes.id',
@@ -95,7 +95,7 @@ export class FileListQueryHandler implements QueryHandler<FileListQueryInput> {
eb.and([
eb('parent_id', '=', input.parentId),
eb('type', '=', NodeTypes.File),
]),
])
)
.orderBy('id', 'asc')
.limit(input.count)

View File

@@ -1,4 +1,5 @@
import { QueryHandler, QueryMap } from '@/operations/queries';
import { QueryMap } from '@/operations/queries';
import { QueryHandler } from '@/main/types';
import { AccountListQueryHandler } from '@/main/handlers/queries/accounts-list';
import { BreadcrumbListQueryHandler } from '@/main/handlers/queries/breadcrumb-list';
import { MessageListQueryHandler } from '@/main/handlers/queries/message-list';

View File

@@ -1,15 +1,15 @@
import { MessageListQueryInput } from '@/operations/queries/message-list';
import { databaseManager } from '@/main/data/database-manager';
import {
MutationChange,
ChangeCheckResult,
QueryHandler,
QueryResult,
} from '@/operations/queries';
import { MutationChange } from '@/operations/mutations';
} from '@/main/types';
import { SelectNode } from '@/main/data/workspace/schema';
import { NodeTypes } from '@/lib/constants';
import { MessageNode, MessageReactionCount } from '@/types/messages';
import { mapNode } from '@/lib/nodes';
import { mapNode } from '@/main/utils';
import { UserNode } from '@/types/users';
import { compareString } from '@/lib/utils';
import { isEqual } from 'lodash';
@@ -19,7 +19,7 @@ export class MessageListQueryHandler
implements QueryHandler<MessageListQueryInput>
{
public async handleQuery(
input: MessageListQueryInput,
input: MessageListQueryInput
): Promise<QueryResult<MessageListQueryInput>> {
const messages = await this.fetchMesssages(input);
const authors = await this.fetchAuthors(input, messages);
@@ -36,14 +36,14 @@ export class MessageListQueryHandler
public async checkForChanges(
changes: MutationChange[],
input: MessageListQueryInput,
state: Record<string, any>,
state: Record<string, any>
): Promise<ChangeCheckResult<MessageListQueryInput>> {
if (
!changes.some(
(change) =>
change.type === 'workspace' &&
change.table === 'nodes' &&
change.userId === input.userId,
change.userId === input.userId
)
) {
return {
@@ -73,10 +73,10 @@ export class MessageListQueryHandler
}
private async fetchMesssages(
input: MessageListQueryInput,
input: MessageListQueryInput
): Promise<SelectNode[]> {
const workspaceDatabase = await databaseManager.getWorkspaceDatabase(
input.userId,
input.userId
);
const offset = input.page * input.count;
@@ -87,7 +87,7 @@ export class MessageListQueryHandler
eb.and([
eb('parent_id', '=', input.conversationId),
eb('type', '=', NodeTypes.Message),
]),
])
)
.orderBy('id', 'desc')
.limit(input.count)
@@ -99,14 +99,14 @@ export class MessageListQueryHandler
private async fetchAuthors(
input: MessageListQueryInput,
messages: SelectNode[],
messages: SelectNode[]
): Promise<SelectNode[]> {
if (messages.length === 0) {
return [];
}
const workspaceDatabase = await databaseManager.getWorkspaceDatabase(
input.userId,
input.userId
);
const authorIds = messages.map((message) => message.created_by);
@@ -122,7 +122,7 @@ export class MessageListQueryHandler
private buildMessages = (
userId: string,
messageRows: SelectNode[],
authorRows: SelectNode[],
authorRows: SelectNode[]
): MessageNode[] => {
const messages: MessageNode[] = [];
const authorMap = new Map<string, UserNode>();
@@ -174,7 +174,7 @@ export class MessageListQueryHandler
},
content: mapBlocksToContents(
messageNode.id,
Object.values(messageNode.attributes.content ?? {}),
Object.values(messageNode.attributes.content ?? {})
),
reactionCounts,
};

View File

@@ -1,17 +1,17 @@
import { NodeCollaboratorListQueryInput } from '@/operations/queries/node-collaborator-list';
import { databaseManager } from '@/main/data/database-manager';
import {
ChangeCheckResult,
QueryHandler,
QueryResult,
} from '@/operations/queries';
import {
InheritNodeCollaboratorsGroup,
NodeCollaboratorsWrapper,
NodeCollaborator,
} from '@/types/nodes';
import { NodeAttributes } from '@/registry';
import { MutationChange } from '@/operations/mutations';
import { NodeAttributes } from '@colanode/core';
import {
MutationChange,
ChangeCheckResult,
QueryHandler,
QueryResult,
} from '@/main/types';
import { isEqual } from 'lodash';
type ExtractedNodeCollaborator = {
@@ -29,17 +29,17 @@ export class NodeCollaboratorListQueryHandler
implements QueryHandler<NodeCollaboratorListQueryInput>
{
public async handleQuery(
input: NodeCollaboratorListQueryInput,
input: NodeCollaboratorListQueryInput
): Promise<QueryResult<NodeCollaboratorListQueryInput>> {
const ancestors = await this.fetchAncestors(input);
const extractedCollaborators = this.extractCollaborators(ancestors);
const collaboratorIds = extractedCollaborators.map(
(collaborator) => collaborator.collaboratorId,
(collaborator) => collaborator.collaboratorId
);
const collaboratorNodes = await this.fetchCollaborators(
input,
collaboratorIds,
collaboratorIds
);
return {
@@ -47,7 +47,7 @@ export class NodeCollaboratorListQueryHandler
input.nodeId,
ancestors,
collaboratorNodes,
extractedCollaborators,
extractedCollaborators
),
state: {
ancestors,
@@ -60,14 +60,14 @@ export class NodeCollaboratorListQueryHandler
public async checkForChanges(
changes: MutationChange[],
input: NodeCollaboratorListQueryInput,
state: Record<string, any>,
state: Record<string, any>
): Promise<ChangeCheckResult<NodeCollaboratorListQueryInput>> {
if (
!changes.some(
(change) =>
change.type === 'workspace' &&
change.table === 'nodes' &&
change.userId === input.userId,
change.userId === input.userId
)
) {
return {
@@ -78,12 +78,12 @@ export class NodeCollaboratorListQueryHandler
const ancestors = await this.fetchAncestors(input);
const extractedCollaborators = this.extractCollaborators(ancestors);
const collaboratorIds = extractedCollaborators.map(
(collaborator) => collaborator.collaboratorId,
(collaborator) => collaborator.collaboratorId
);
const collaboratorNodes = await this.fetchCollaborators(
input,
collaboratorIds,
collaboratorIds
);
if (
@@ -103,7 +103,7 @@ export class NodeCollaboratorListQueryHandler
input.nodeId,
ancestors,
collaboratorNodes,
extractedCollaborators,
extractedCollaborators
),
state: {
ancestors,
@@ -115,10 +115,10 @@ export class NodeCollaboratorListQueryHandler
}
private async fetchAncestors(
input: NodeCollaboratorListQueryInput,
input: NodeCollaboratorListQueryInput
): Promise<NodeWithAttributesRow[]> {
const workspaceDatabase = await databaseManager.getWorkspaceDatabase(
input.userId,
input.userId
);
const result = await workspaceDatabase
@@ -133,7 +133,7 @@ export class NodeCollaboratorListQueryHandler
}
private extractCollaborators(
nodes: NodeWithAttributesRow[],
nodes: NodeWithAttributesRow[]
): ExtractedNodeCollaborator[] {
const map: Map<string, ExtractedNodeCollaborator> = new Map();
@@ -170,14 +170,14 @@ export class NodeCollaboratorListQueryHandler
private async fetchCollaborators(
input: NodeCollaboratorListQueryInput,
collaboratorIds: string[],
collaboratorIds: string[]
): Promise<NodeWithAttributesRow[]> {
if (collaboratorIds.length === 0) {
return [];
}
const workspaceDatabase = await databaseManager.getWorkspaceDatabase(
input.userId,
input.userId
);
const result = await workspaceDatabase
@@ -193,7 +193,7 @@ export class NodeCollaboratorListQueryHandler
nodeId: string,
ancestors: NodeWithAttributesRow[],
collaboratorNodes: NodeWithAttributesRow[],
extractedCollaborators: ExtractedNodeCollaborator[],
extractedCollaborators: ExtractedNodeCollaborator[]
): NodeCollaboratorsWrapper => {
const direct: NodeCollaborator[] = [];
const inherit: InheritNodeCollaboratorsGroup[] = [];
@@ -202,7 +202,7 @@ export class NodeCollaboratorListQueryHandler
for (const extractedCollaborator of extractedCollaborators) {
const collaboratorNode = collaboratorNodes.find(
(row) => row.id === extractedCollaborator.collaboratorId,
(row) => row.id === extractedCollaborator.collaboratorId
);
if (!collaboratorNode) {

View File

@@ -1,22 +1,22 @@
import { NodeCollaboratorSearchQueryInput } from '@/operations/queries/node-collaborator-search';
import { databaseManager } from '@/main/data/database-manager';
import {
ChangeCheckResult,
QueryHandler,
QueryResult,
} from '@/operations/queries';
import { sql } from 'kysely';
import { SelectNode } from '@/main/data/workspace/schema';
import { NodeTypes } from '@/lib/constants';
import { NodeCollaborator } from '@/types/nodes';
import { MutationChange } from '@/operations/mutations';
import {
MutationChange,
ChangeCheckResult,
QueryHandler,
QueryResult,
} from '@/main/types';
import { isEqual } from 'lodash';
export class NodeCollaboratorSearchQueryHandler
implements QueryHandler<NodeCollaboratorSearchQueryInput>
{
public async handleQuery(
input: NodeCollaboratorSearchQueryInput,
input: NodeCollaboratorSearchQueryInput
): Promise<QueryResult<NodeCollaboratorSearchQueryInput>> {
if (input.searchQuery.length === 0) {
return {
@@ -39,14 +39,14 @@ export class NodeCollaboratorSearchQueryHandler
public async checkForChanges(
changes: MutationChange[],
input: NodeCollaboratorSearchQueryInput,
state: Record<string, any>,
state: Record<string, any>
): Promise<ChangeCheckResult<NodeCollaboratorSearchQueryInput>> {
if (
!changes.some(
(change) =>
change.type === 'workspace' &&
change.table === 'nodes' &&
change.userId === input.userId,
change.userId === input.userId
)
) {
return {
@@ -73,14 +73,14 @@ export class NodeCollaboratorSearchQueryHandler
}
private async fetchNodes(
input: NodeCollaboratorSearchQueryInput,
input: NodeCollaboratorSearchQueryInput
): Promise<SelectNode[]> {
if (input.searchQuery.length === 0) {
return [];
}
const workspaceDatabase = await databaseManager.getWorkspaceDatabase(
input.userId,
input.userId
);
const query = sql<SelectNode>`
@@ -93,7 +93,7 @@ export class NodeCollaboratorSearchQueryHandler
input.excluded.length > 0
? sql`AND n.id NOT IN (${sql.join(
input.excluded.map((id) => sql`${id}`),
sql`, `,
sql`, `
)})`
: sql``
}

View File

@@ -1,18 +1,18 @@
import { NodeGetQueryInput } from '@/operations/queries/node-get';
import { databaseManager } from '@/main/data/database-manager';
import { mapNode } from '@/main/utils';
import { SelectNode } from '@/main/data/workspace/schema';
import {
MutationChange,
ChangeCheckResult,
QueryHandler,
QueryResult,
} from '@/operations/queries';
import { mapNode } from '@/lib/nodes';
import { SelectNode } from '@/main/data/workspace/schema';
import { MutationChange } from '@/operations/mutations';
} from '@/main/types';
import { isEqual } from 'lodash';
export class NodeGetQueryHandler implements QueryHandler<NodeGetQueryInput> {
public async handleQuery(
input: NodeGetQueryInput,
input: NodeGetQueryInput
): Promise<QueryResult<NodeGetQueryInput>> {
const row = await this.fetchNode(input);
@@ -27,14 +27,14 @@ export class NodeGetQueryHandler implements QueryHandler<NodeGetQueryInput> {
public async checkForChanges(
changes: MutationChange[],
input: NodeGetQueryInput,
state: Record<string, any>,
state: Record<string, any>
): Promise<ChangeCheckResult<NodeGetQueryInput>> {
if (
!changes.some(
(change) =>
change.type === 'workspace' &&
change.table === 'nodes' &&
change.userId === input.userId,
change.userId === input.userId
)
) {
return {
@@ -61,10 +61,10 @@ export class NodeGetQueryHandler implements QueryHandler<NodeGetQueryInput> {
}
private async fetchNode(
input: NodeGetQueryInput,
input: NodeGetQueryInput
): Promise<SelectNode | undefined> {
const workspaceDatabase = await databaseManager.getWorkspaceDatabase(
input.userId,
input.userId
);
const row = await workspaceDatabase

View File

@@ -1,11 +1,11 @@
import { RecordListQueryInput } from '@/operations/queries/record-list';
import { databaseManager } from '@/main/data/database-manager';
import {
MutationChange,
ChangeCheckResult,
QueryHandler,
QueryResult,
} from '@/operations/queries';
import { MutationChange } from '@/operations/mutations';
} from '@/main/types';
import { SelectNode } from '@/main/data/workspace/schema';
import { sql } from 'kysely';
import {
@@ -25,9 +25,9 @@ import {
ViewSortAttributes,
DatabaseNode,
RecordNode,
} from '@/registry';
} from '@colanode/core';
import { isStringArray } from '@/lib/utils';
import { mapNode } from '@/lib/nodes';
import { mapNode } from '@/main/utils';
import { NodeTypes } from '@/lib/constants';
import { isEqual } from 'lodash';
@@ -35,7 +35,7 @@ export class RecordListQueryHandler
implements QueryHandler<RecordListQueryInput>
{
public async handleQuery(
input: RecordListQueryInput,
input: RecordListQueryInput
): Promise<QueryResult<RecordListQueryInput>> {
const rows = await this.fetchRecords(input);
@@ -50,14 +50,14 @@ export class RecordListQueryHandler
public async checkForChanges(
changes: MutationChange[],
input: RecordListQueryInput,
state: Record<string, any>,
state: Record<string, any>
): Promise<ChangeCheckResult<RecordListQueryInput>> {
if (
!changes.some(
(change) =>
change.type === 'workspace' &&
change.table === 'nodes' &&
change.userId === input.userId,
change.userId === input.userId
)
) {
return {
@@ -84,16 +84,16 @@ export class RecordListQueryHandler
}
private async fetchRecords(
input: RecordListQueryInput,
input: RecordListQueryInput
): Promise<SelectNode[]> {
const workspaceDatabase = await databaseManager.getWorkspaceDatabase(
input.userId,
input.userId
);
const database = await this.fetchDatabase(input.userId, input.databaseId);
const filterQuery = this.buildFiltersQuery(
input.filters,
database.attributes.fields,
database.attributes.fields
);
const orderByQuery = `ORDER BY ${input.sorts.length > 0 ? this.buildSortOrdersQuery(input.sorts, database.attributes.fields) : 'n."index" ASC'}`;
@@ -143,7 +143,7 @@ export class RecordListQueryHandler
private async fetchDatabase(
userId: string,
databaseId: string,
databaseId: string
): Promise<DatabaseNode> {
const workspaceDatabase =
await databaseManager.getWorkspaceDatabase(userId);
@@ -164,7 +164,7 @@ export class RecordListQueryHandler
private buildFiltersQuery = (
filters: ViewFilterAttributes[],
fields: Record<string, FieldAttributes>,
fields: Record<string, FieldAttributes>
): string => {
if (filters.length === 0) {
return '';
@@ -183,7 +183,7 @@ export class RecordListQueryHandler
private buildFilterQuery = (
filter: ViewFilterAttributes,
fields: Record<string, FieldAttributes>,
fields: Record<string, FieldAttributes>
): string | null => {
if (filter.type === 'group') {
return null;
@@ -228,7 +228,7 @@ export class RecordListQueryHandler
buildBooleanFilterQuery = (
filter: ViewFieldFilterAttributes,
field: BooleanFieldAttributes,
field: BooleanFieldAttributes
): string | null => {
if (filter.operator === 'is_true') {
return `json_extract(n.attributes, '$.fields.${field.id}.value') = true`;
@@ -243,7 +243,7 @@ export class RecordListQueryHandler
private buildNumberFilterQuery = (
filter: ViewFieldFilterAttributes,
field: NumberFieldAttributes,
field: NumberFieldAttributes
): string | null => {
if (filter.operator === 'is_empty') {
return this.buildIsEmptyFilterQuery(field.id);
@@ -296,7 +296,7 @@ export class RecordListQueryHandler
private buildTextFilterQuery = (
filter: ViewFieldFilterAttributes,
field: TextFieldAttributes,
field: TextFieldAttributes
): string | null => {
if (filter.operator === 'is_empty') {
return this.buildIsEmptyFilterQuery(field.id);
@@ -354,7 +354,7 @@ export class RecordListQueryHandler
private buildEmailFilterQuery = (
filter: ViewFieldFilterAttributes,
field: EmailFieldAttributes,
field: EmailFieldAttributes
): string | null => {
if (filter.operator === 'is_empty') {
return this.buildIsEmptyFilterQuery(field.id);
@@ -412,7 +412,7 @@ export class RecordListQueryHandler
private buildPhoneFilterQuery = (
filter: ViewFieldFilterAttributes,
field: PhoneFieldAttributes,
field: PhoneFieldAttributes
): string | null => {
if (filter.operator === 'is_empty') {
return this.buildIsEmptyFilterQuery(field.id);
@@ -470,7 +470,7 @@ export class RecordListQueryHandler
private buildUrlFilterQuery = (
filter: ViewFieldFilterAttributes,
field: UrlFieldAttributes,
field: UrlFieldAttributes
): string | null => {
if (filter.operator === 'is_empty') {
return this.buildIsEmptyFilterQuery(field.id);
@@ -528,7 +528,7 @@ export class RecordListQueryHandler
private buildSelectFilterQuery = (
filter: ViewFieldFilterAttributes,
field: SelectFieldAttributes,
field: SelectFieldAttributes
): string | null => {
if (filter.operator === 'is_empty') {
return this.buildIsEmptyFilterQuery(field.id);
@@ -559,7 +559,7 @@ export class RecordListQueryHandler
private buildMultiSelectFilterQuery = (
filter: ViewFieldFilterAttributes,
field: MultiSelectFieldAttributes,
field: MultiSelectFieldAttributes
): string | null => {
if (filter.operator === 'is_empty') {
return `json_extract(n.attributes, '$.fields.${field.id}.value') IS NULL OR json_array_length(json_extract(n.attributes, '$.fields.${field.id}.value')) = 0`;
@@ -590,7 +590,7 @@ export class RecordListQueryHandler
private buildDateFilterQuery = (
filter: ViewFieldFilterAttributes,
field: DateFieldAttributes,
field: DateFieldAttributes
): string | null => {
if (filter.operator === 'is_empty') {
return this.buildIsEmptyFilterQuery(field.id);
@@ -648,7 +648,7 @@ export class RecordListQueryHandler
private buildCreatedAtFilterQuery = (
filter: ViewFieldFilterAttributes,
field: CreatedAtFieldAttributes,
_: CreatedAtFieldAttributes
): string | null => {
if (filter.operator === 'is_empty') {
return `n.created_at IS NULL`;
@@ -718,7 +718,7 @@ export class RecordListQueryHandler
private buildSortOrdersQuery = (
sorts: ViewSortAttributes[],
fields: Record<string, FieldAttributes>,
fields: Record<string, FieldAttributes>
): string => {
return sorts
.map((sort) => this.buildSortOrderQuery(sort, fields))
@@ -728,7 +728,7 @@ export class RecordListQueryHandler
private buildSortOrderQuery = (
sort: ViewSortAttributes,
fields: Record<string, FieldAttributes>,
fields: Record<string, FieldAttributes>
): string | null => {
const field = fields[sort.fieldId];
if (!field) {

View File

@@ -1,12 +1,12 @@
import { ServerListQueryInput } from '@/operations/queries/server-list';
import { databaseManager } from '@/main/data/database-manager';
import { SelectServer } from '@/main/data/app/schema';
import {
MutationChange,
ChangeCheckResult,
QueryHandler,
QueryResult,
} from '@/operations/queries';
import { SelectServer } from '@/main/data/app/schema';
import { MutationChange } from '@/operations/mutations';
} from '@/main/types';
import { isEqual } from 'lodash';
import { Server } from '@/types/servers';
@@ -14,7 +14,7 @@ export class ServerListQueryHandler
implements QueryHandler<ServerListQueryInput>
{
async handleQuery(
_: ServerListQueryInput,
_: ServerListQueryInput
): Promise<QueryResult<ServerListQueryInput>> {
const rows = await this.fetchServers();
return {
@@ -28,11 +28,11 @@ export class ServerListQueryHandler
async checkForChanges(
changes: MutationChange[],
_: ServerListQueryInput,
state: Record<string, any>,
state: Record<string, any>
): Promise<ChangeCheckResult<ServerListQueryInput>> {
if (
!changes.some(
(change) => change.type === 'app' && change.table === 'servers',
(change) => change.type === 'app' && change.table === 'servers'
)
) {
return {

View File

@@ -1,15 +1,15 @@
import { SidebarChatListQueryInput } from '@/operations/queries/sidebar-chat-list';
import { databaseManager } from '@/main/data/database-manager';
import {
ChangeCheckResult,
QueryHandler,
QueryResult,
} from '@/operations/queries';
import { SelectNode } from '@/main/data/workspace/schema';
import { NodeTypes } from '@/lib/constants';
import { SidebarChatNode } from '@/types/workspaces';
import { mapNode } from '@/lib/nodes';
import { MutationChange } from '@/operations/mutations';
import { mapNode } from '@/main/utils';
import {
MutationChange,
ChangeCheckResult,
QueryHandler,
QueryResult,
} from '@/main/types';
import { isEqual } from 'lodash';
interface UnreadCountRow {
@@ -22,7 +22,7 @@ export class SidebarChatListQueryHandler
implements QueryHandler<SidebarChatListQueryInput>
{
public async handleQuery(
input: SidebarChatListQueryInput,
input: SidebarChatListQueryInput
): Promise<QueryResult<SidebarChatListQueryInput>> {
const chats = await this.fetchChats(input);
const collaborators = await this.fetchChatCollaborators(input, chats);
@@ -33,7 +33,7 @@ export class SidebarChatListQueryHandler
input.userId,
chats,
collaborators,
unreadCounts,
unreadCounts
),
state: {
chats,
@@ -46,14 +46,14 @@ export class SidebarChatListQueryHandler
public async checkForChanges(
changes: MutationChange[],
input: SidebarChatListQueryInput,
state: Record<string, any>,
state: Record<string, any>
): Promise<ChangeCheckResult<SidebarChatListQueryInput>> {
if (
!changes.some(
(change) =>
change.type === 'workspace' &&
(change.table === 'nodes' || change.table === 'user_nodes') &&
change.userId === input.userId,
change.userId === input.userId
)
) {
return {
@@ -82,7 +82,7 @@ export class SidebarChatListQueryHandler
input.userId,
chats,
collaborators,
unreadCounts,
unreadCounts
),
state: {
chats,
@@ -94,10 +94,10 @@ export class SidebarChatListQueryHandler
}
private async fetchChats(
input: SidebarChatListQueryInput,
input: SidebarChatListQueryInput
): Promise<SelectNode[]> {
const workspaceDatabase = await databaseManager.getWorkspaceDatabase(
input.userId,
input.userId
);
const chats = await workspaceDatabase
@@ -111,10 +111,10 @@ export class SidebarChatListQueryHandler
private async fetchChatCollaborators(
input: SidebarChatListQueryInput,
chats: SelectNode[],
chats: SelectNode[]
): Promise<SelectNode[]> {
const workspaceDatabase = await databaseManager.getWorkspaceDatabase(
input.userId,
input.userId
);
const collaboratorIds: string[] = [];
@@ -149,10 +149,10 @@ export class SidebarChatListQueryHandler
private async fetchUnreadCounts(
input: SidebarChatListQueryInput,
chats: SelectNode[],
chats: SelectNode[]
): Promise<UnreadCountRow[]> {
const workspaceDatabase = await databaseManager.getWorkspaceDatabase(
input.userId,
input.userId
);
const chatIds = chats.map((chat) => chat.id);
@@ -178,7 +178,7 @@ export class SidebarChatListQueryHandler
userId: string,
chats: SelectNode[],
collaborators: SelectNode[],
unreadCounts: UnreadCountRow[],
unreadCounts: UnreadCountRow[]
): SidebarChatNode[] => {
const sidebarChatNodes: SidebarChatNode[] = [];
@@ -204,7 +204,7 @@ export class SidebarChatListQueryHandler
}
const collaboratorRow = collaborators.find(
(r) => r.id === collaboratorId,
(r) => r.id === collaboratorId
);
if (!collaboratorRow) {

View File

@@ -1,17 +1,17 @@
import { SidebarSpaceListQueryInput } from '@/operations/queries/sidebar-space-list';
import { databaseManager } from '@/main/data/database-manager';
import {
ChangeCheckResult,
QueryHandler,
QueryResult,
} from '@/operations/queries';
import { sql } from 'kysely';
import { SelectNode } from '@/main/data/workspace/schema';
import { NodeTypes } from '@/lib/constants';
import { SidebarNode, SidebarSpaceNode } from '@/types/workspaces';
import { mapNode } from '@/lib/nodes';
import { Node } from '@/registry';
import { MutationChange } from '@/operations/mutations';
import { mapNode } from '@/main/utils';
import { Node } from '@colanode/core';
import {
MutationChange,
ChangeCheckResult,
QueryHandler,
QueryResult,
} from '@/main/types';
import { isEqual } from 'lodash';
import { compareString } from '@/lib/utils';
@@ -25,7 +25,7 @@ export class SidebarSpaceListQueryHandler
implements QueryHandler<SidebarSpaceListQueryInput>
{
public async handleQuery(
input: SidebarSpaceListQueryInput,
input: SidebarSpaceListQueryInput
): Promise<QueryResult<SidebarSpaceListQueryInput>> {
const rows = await this.fetchNodes(input);
const unreadCounts = await this.fetchUnreadCounts(input, rows);
@@ -42,14 +42,14 @@ export class SidebarSpaceListQueryHandler
public async checkForChanges(
changes: MutationChange[],
input: SidebarSpaceListQueryInput,
state: Record<string, any>,
state: Record<string, any>
): Promise<ChangeCheckResult<SidebarSpaceListQueryInput>> {
if (
!changes.some(
(change) =>
change.type === 'workspace' &&
(change.table === 'nodes' || change.table === 'user_nodes') &&
change.userId === input.userId,
change.userId === input.userId
)
) {
return {
@@ -80,10 +80,10 @@ export class SidebarSpaceListQueryHandler
}
private async fetchNodes(
input: SidebarSpaceListQueryInput,
input: SidebarSpaceListQueryInput
): Promise<SelectNode[]> {
const workspaceDatabase = await databaseManager.getWorkspaceDatabase(
input.userId,
input.userId
);
const query = sql<SelectNode>`
@@ -108,10 +108,10 @@ export class SidebarSpaceListQueryHandler
private async fetchUnreadCounts(
input: SidebarSpaceListQueryInput,
rows: SelectNode[],
rows: SelectNode[]
): Promise<UnreadCountRow[]> {
const workspaceDatabase = await databaseManager.getWorkspaceDatabase(
input.userId,
input.userId
);
const channelIds = rows
@@ -138,7 +138,7 @@ export class SidebarSpaceListQueryHandler
private buildSidebarSpaceNodes = (
rows: SelectNode[],
unreadCounts: UnreadCountRow[],
unreadCounts: UnreadCountRow[]
): SidebarSpaceNode[] => {
const nodes: Node[] = rows.map(mapNode);
const spaces: SidebarSpaceNode[] = [];
@@ -164,7 +164,7 @@ export class SidebarSpaceListQueryHandler
private buildSpaceNode = (
node: Node,
children: Node[],
unreadCounts: UnreadCountRow[],
unreadCounts: UnreadCountRow[]
): SidebarSpaceNode | null => {
if (node.type !== 'space') {
return null;
@@ -191,7 +191,7 @@ export class SidebarSpaceListQueryHandler
private buildSidearNode = (
node: Node,
unreadCounts: UnreadCountRow[],
unreadCounts: UnreadCountRow[]
): SidebarNode | null => {
const unreadCountRow = unreadCounts.find((r) => r.node_id === node.id);

View File

@@ -1,22 +1,22 @@
import { UserSearchQueryInput } from '@/operations/queries/user-search';
import { databaseManager } from '@/main/data/database-manager';
import {
ChangeCheckResult,
QueryHandler,
QueryResult,
} from '@/operations/queries';
import { sql } from 'kysely';
import { SelectNode } from '@/main/data/workspace/schema';
import { NodeTypes } from '@/lib/constants';
import { UserNode } from '@/types/users';
import { MutationChange } from '@/operations/mutations';
import {
MutationChange,
ChangeCheckResult,
QueryHandler,
QueryResult,
} from '@/main/types';
import { isEqual } from 'lodash';
export class UserSearchQueryHandler
implements QueryHandler<UserSearchQueryInput>
{
public async handleQuery(
input: UserSearchQueryInput,
input: UserSearchQueryInput
): Promise<QueryResult<UserSearchQueryInput>> {
const rows =
input.searchQuery.length > 0
@@ -33,14 +33,14 @@ export class UserSearchQueryHandler
public async checkForChanges(
changes: MutationChange[],
input: UserSearchQueryInput,
state: Record<string, any>,
state: Record<string, any>
): Promise<ChangeCheckResult<UserSearchQueryInput>> {
if (
!changes.some(
(change) =>
change.type === 'workspace' &&
change.table === 'nodes' &&
change.userId === input.userId,
change.userId === input.userId
)
) {
return {
@@ -71,10 +71,10 @@ export class UserSearchQueryHandler
}
private async searchUsers(
input: UserSearchQueryInput,
input: UserSearchQueryInput
): Promise<SelectNode[]> {
const workspaceDatabase = await databaseManager.getWorkspaceDatabase(
input.userId,
input.userId
);
const query = sql<SelectNode>`
@@ -92,7 +92,7 @@ export class UserSearchQueryHandler
private async fetchUsers(input: UserSearchQueryInput): Promise<SelectNode[]> {
const workspaceDatabase = await databaseManager.getWorkspaceDatabase(
input.userId,
input.userId
);
return workspaceDatabase

View File

@@ -1,20 +1,20 @@
import { WorkspaceListQueryInput } from '@/operations/queries/workspace-list';
import { databaseManager } from '@/main/data/database-manager';
import { Workspace, WorkspaceRole } from '@/types/workspaces';
import { SelectWorkspace } from '@/main/data/app/schema';
import {
MutationChange,
ChangeCheckResult,
QueryHandler,
QueryResult,
} from '@/operations/queries';
import { Workspace, WorkspaceRole } from '@/types/workspaces';
import { SelectWorkspace } from '@/main/data/app/schema';
import { MutationChange } from '@/operations/mutations';
} from '@/main/types';
import { isEqual } from 'lodash';
export class WorkspaceListQueryHandler
implements QueryHandler<WorkspaceListQueryInput>
{
public async handleQuery(
input: WorkspaceListQueryInput,
_: WorkspaceListQueryInput
): Promise<QueryResult<WorkspaceListQueryInput>> {
const rows = await this.fetchWorkspaces();
@@ -28,12 +28,12 @@ export class WorkspaceListQueryHandler
public async checkForChanges(
changes: MutationChange[],
input: WorkspaceListQueryInput,
state: Record<string, any>,
_: WorkspaceListQueryInput,
state: Record<string, any>
): Promise<ChangeCheckResult<WorkspaceListQueryInput>> {
if (
!changes.some(
(change) => change.type === 'app' && change.table === 'workspaces',
(change) => change.type === 'app' && change.table === 'workspaces'
)
) {
return {
@@ -69,7 +69,7 @@ export class WorkspaceListQueryHandler
databaseManager.appDatabase
.selectFrom('accounts')
.where('status', '=', 'active')
.select('id'),
.select('id')
)
.execute();
}

View File

@@ -1,22 +1,22 @@
import { WorkspaceUserListQueryInput } from '@/operations/queries/workspace-user-list';
import { databaseManager } from '@/main/data/database-manager';
import { NodeTypes } from '@/lib/constants';
import { mapNode } from '@/main/utils';
import { SelectNode } from '@/main/data/workspace/schema';
import { UserNode } from '@colanode/core';
import {
MutationChange,
ChangeCheckResult,
QueryHandler,
QueryResult,
} from '@/operations/queries';
import { NodeTypes } from '@/lib/constants';
import { mapNode } from '@/lib/nodes';
import { SelectNode } from '@/main/data/workspace/schema';
import { UserNode } from '@/registry';
import { MutationChange } from '@/operations/mutations';
} from '@/main/types';
import { isEqual } from 'lodash';
export class WorkspaceUserListQueryHandler
implements QueryHandler<WorkspaceUserListQueryInput>
{
public async handleQuery(
input: WorkspaceUserListQueryInput,
input: WorkspaceUserListQueryInput
): Promise<QueryResult<WorkspaceUserListQueryInput>> {
const rows = await this.fetchNodes(input);
return {
@@ -30,14 +30,14 @@ export class WorkspaceUserListQueryHandler
public async checkForChanges(
changes: MutationChange[],
input: WorkspaceUserListQueryInput,
state: Record<string, any>,
state: Record<string, any>
): Promise<ChangeCheckResult<WorkspaceUserListQueryInput>> {
if (
!changes.some(
(change) =>
change.type === 'workspace' &&
change.table === 'nodes' &&
change.userId === input.userId,
change.userId === input.userId
)
) {
return {
@@ -64,10 +64,10 @@ export class WorkspaceUserListQueryHandler
}
private async fetchNodes(
input: WorkspaceUserListQueryInput,
input: WorkspaceUserListQueryInput
): Promise<SelectNode[]> {
const workspaceDatabase = await databaseManager.getWorkspaceDatabase(
input.userId,
input.userId
);
const offset = input.page * input.count;

View File

@@ -1,16 +1,8 @@
import {
MutationChange,
MutationHandler,
MutationInput,
MutationMap,
} from '@/operations/mutations';
import { MutationInput, MutationMap } from '@/operations/mutations';
import { MutationChange, MutationHandler } from '@/main/types';
import { mutationHandlerMap } from '@/main/handlers/mutations';
import {
QueryHandler,
QueryInput,
QueryMap,
SubscribedQuery,
} from '@/operations/queries';
import { QueryInput, QueryMap } from '@/operations/queries';
import { QueryHandler, SubscribedQuery } from '@/main/types';
import { queryHandlerMap } from '@/main/handlers/queries';
import { eventBus } from '@/lib/event-bus';
import {
@@ -25,7 +17,7 @@ class Mediator {
new Map();
public async executeMutation<T extends MutationInput>(
input: T,
input: T
): Promise<MutationMap[T['type']]['output']> {
const handler = mutationHandlerMap[
input.type
@@ -40,7 +32,7 @@ class Mediator {
}
public async executeQuery<T extends QueryInput>(
input: T,
input: T
): Promise<QueryMap[T['type']]['output']> {
const handler = queryHandlerMap[input.type] as unknown as QueryHandler<T>;
const result = await handler.handleQuery(input);
@@ -49,7 +41,7 @@ class Mediator {
public async executeQueryAndSubscribe<T extends QueryInput>(
id: string,
input: T,
input: T
): Promise<QueryMap[T['type']]['output']> {
const handler = queryHandlerMap[input.type] as unknown as QueryHandler<T>;
const result = await handler.handleQuery(input);
@@ -62,7 +54,7 @@ class Mediator {
public async executeMessage<T extends MessageInput>(
context: MessageContext,
input: T,
input: T
): Promise<void> {
const handler = messageHandlerMap[input.type] as MessageHandler<T>;
await handler.handleMessage(context, input);
@@ -85,7 +77,7 @@ class Mediator {
const changeCheckResult = await handler.checkForChanges(
changes,
query.input,
query.result.state,
query.result.state
);
if (changeCheckResult.hasChanges && changeCheckResult.result) {
const newResult = changeCheckResult.result;

View File

@@ -1,12 +1,10 @@
import * as Y from 'yjs';
import { NodeAttributes } from '@/registry';
import { NodeAttributes, registry, applyCrdt } from '@colanode/core';
import { fromUint8Array, toUint8Array } from 'js-base64';
import { applyCrdt } from '@/main/crdt';
import {
LocalCreateNodeChangeData,
LocalUpdateNodeChangeData,
} from '@/types/sync';
import { registry } from '@/registry';
import { generateId } from '@/lib/id';
import { IdType } from '@/lib/id';
import { databaseManager } from '@/main/data/database-manager';
@@ -19,7 +17,7 @@ class NodeManager {
transaction: Transaction<WorkspaceDatabaseSchema>,
userId: string,
id: string,
attributes: NodeAttributes,
attributes: NodeAttributes
) {
const doc = new Y.Doc({
guid: id,
@@ -75,7 +73,7 @@ class NodeManager {
async updateNode(
userId: string,
id: string,
updater: (attributes: NodeAttributes) => NodeAttributes,
updater: (attributes: NodeAttributes) => NodeAttributes
) {
const workspaceDatabase =
await databaseManager.getWorkspaceDatabase(userId);
@@ -113,7 +111,7 @@ class NodeManager {
applyCrdt(
registry[updatedAttributes.type].schema,
updatedAttributes,
attributesMap,
attributesMap
);
});
@@ -165,10 +163,10 @@ class NodeManager {
return hasChanges;
});
if (result) {
return true;
}
return result;
}
throw new Error('Failed to update node');
}
}

View File

@@ -1,9 +1,15 @@
import { WebSocket } from 'ws';
import { buildSynapseUrl } from '@/lib/servers';
import { BackoffCalculator } from '@/lib/backoff-calculator';
import { MessageContext, MessageInput } from '@/operations/messages';
import { mediator } from '@/main/mediator';
import { SelectAccount, SelectServer } from '@/main/data/app/schema';
import { ServerAttributes } from '@/types/servers';
const buildSynapseUrl = (server: SelectServer, deviceId: string) => {
const attributes = JSON.parse(server.attributes) as ServerAttributes;
const protocol = attributes?.insecure ? 'ws' : 'wss';
return `${protocol}://${server.domain}/v1/synapse?device_id=${deviceId}`;
};
export class SocketConnection {
private readonly server: SelectServer;
@@ -35,7 +41,7 @@ export class SocketConnection {
headers: {
authorization: this.account.token,
},
},
}
);
this.socket.onmessage = async (event) => {

View File

@@ -0,0 +1,50 @@
import { AppDatabaseSchema } from '@/main/data/app/schema';
import { WorkspaceDatabaseSchema } from '@/main/data/workspace/schema';
import { MutationInput, MutationMap } from '@/operations/mutations';
import { QueryInput, QueryMap } from '@/operations/queries';
export interface MutationHandler<T extends MutationInput> {
handleMutation: (input: T) => Promise<MutationResult<T>>;
}
export type MutationResult<T extends MutationInput> = {
output: MutationMap[T['type']]['output'];
changes?: MutationChange[];
};
export type MutationChange = AppMutationChange | WorkspaceMutationChange;
export type AppMutationChange = {
type: 'app';
table: keyof AppDatabaseSchema;
};
export type WorkspaceMutationChange = {
type: 'workspace';
table: keyof WorkspaceDatabaseSchema;
userId: string;
};
export interface QueryHandler<T extends QueryInput> {
handleQuery: (input: T) => Promise<QueryResult<T>>;
checkForChanges: (
changes: MutationChange[],
input: T,
state: Record<string, any>
) => Promise<ChangeCheckResult<T>>;
}
export type QueryResult<T extends QueryInput> = {
output: QueryMap[T['type']]['output'];
state: Record<string, any>;
};
export type SubscribedQuery<T extends QueryInput> = {
input: T;
result: QueryResult<T>;
};
export type ChangeCheckResult<T extends QueryInput> = {
hasChanges: boolean;
result?: QueryResult<T>;
};

View File

@@ -1,6 +1,8 @@
import { app } from 'electron';
import { DeleteResult, InsertResult, UpdateResult } from 'kysely';
import path from 'path';
import { SelectNode } from '@/main/data/workspace/schema';
import { Node } from '@colanode/core';
export const appPath = app.getPath('userData');
@@ -24,7 +26,7 @@ export const hasInsertChanges = (result: InsertResult[]): boolean => {
}
return result.some(
(r) => r.numInsertedOrUpdatedRows && r.numInsertedOrUpdatedRows > 0n,
(r) => r.numInsertedOrUpdatedRows && r.numInsertedOrUpdatedRows > 0n
);
};
@@ -39,3 +41,21 @@ export const hasUpdateChanges = (result: UpdateResult[]): boolean => {
export const hasDeleteChanges = (result: DeleteResult[]): boolean => {
return result.some((r) => r.numDeletedRows && r.numDeletedRows > 0n);
};
export const mapNode = (row: SelectNode): Node => {
return {
id: row.id,
type: row.type as any,
index: row.index,
parentId: row.parent_id,
attributes: JSON.parse(row.attributes),
createdAt: row.created_at,
createdBy: row.created_by,
updatedAt: row.updated_at,
updatedBy: row.updated_by,
versionId: row.version_id,
serverCreatedAt: row.server_created_at,
serverUpdatedAt: row.server_updated_at,
serverVersionId: row.server_version_id,
};
};

View File

@@ -1,4 +1,4 @@
import { FieldType } from '@/registry';
import { FieldType } from '@colanode/core';
export type FieldCreateMutationInput = {
type: 'field_create';

View File

@@ -1,28 +1,3 @@
import { AppDatabaseSchema } from '@/main/data/app/schema';
import { WorkspaceDatabaseSchema } from '@/main/data/workspace/schema';
export interface MutationMap {}
export type MutationInput = MutationMap[keyof MutationMap]['input'];
export interface MutationHandler<T extends MutationInput> {
handleMutation: (input: T) => Promise<MutationResult<T>>;
}
export type MutationResult<T extends MutationInput> = {
output: MutationMap[T['type']]['output'];
changes?: MutationChange[];
};
export type MutationChange = AppMutationChange | WorkspaceMutationChange;
export type AppMutationChange = {
type: 'app';
table: keyof AppDatabaseSchema;
};
export type WorkspaceMutationChange = {
type: 'workspace';
table: keyof WorkspaceDatabaseSchema;
userId: string;
};

View File

@@ -1,4 +1,4 @@
import { ViewAttributes } from '@/registry';
import { ViewAttributes } from '@colanode/core';
export type ViewUpdateMutationInput = {
type: 'view_update';

View File

@@ -1,29 +1,3 @@
import { MutationChange } from '@/operations/mutations';
export interface QueryMap {}
export type QueryInput = QueryMap[keyof QueryMap]['input'];
export interface QueryHandler<T extends QueryInput> {
handleQuery: (input: T) => Promise<QueryResult<T>>;
checkForChanges: (
changes: MutationChange[],
input: T,
state: Record<string, any>
) => Promise<ChangeCheckResult<T>>;
}
export type QueryResult<T extends QueryInput> = {
output: QueryMap[T['type']]['output'];
state: Record<string, any>;
};
export type SubscribedQuery<T extends QueryInput> = {
input: T;
result: QueryResult<T>;
};
export type ChangeCheckResult<T extends QueryInput> = {
hasChanges: boolean;
result?: QueryResult<T>;
};

View File

@@ -1,4 +1,4 @@
import { Node } from '@/registry';
import { Node } from '@colanode/core';
export type NodeGetQueryInput = {
type: 'node_get';

View File

@@ -1,5 +1,8 @@
import { RecordNode } from '@/registry';
import { ViewFilterAttributes, ViewSortAttributes } from '@/registry';
import {
RecordNode,
ViewFilterAttributes,
ViewSortAttributes,
} from '@colanode/core';
export type RecordListQueryInput = {
type: 'record_list';

View File

@@ -1,4 +1,4 @@
import { UserNode } from '@/registry';
import { UserNode } from '@colanode/core';
export type WorkspaceUserListQueryInput = {
type: 'workspace_user_list';

View File

@@ -1,4 +1,3 @@
import React from 'react';
import { Spinner } from '@/renderer/components/ui/spinner';
export const AppLoading = () => {

View File

@@ -1,4 +1,3 @@
import React from 'react';
import {
AlertDialog,
AlertDialogCancel,

View File

@@ -1,4 +1,3 @@
import React from 'react';
import {
Dialog,
DialogContent,
@@ -23,7 +22,6 @@ interface AccountSettingsDialogProps {
}
export const AccountSettingsDialog = ({
id,
open,
onOpenChange,
}: AccountSettingsDialogProps) => {

View File

@@ -1,4 +1,3 @@
import React from 'react';
import { Input } from '@/renderer/components/ui/input';
import { Button } from '@/renderer/components/ui/button';
import { Spinner } from '@/renderer/components/ui/spinner';

View File

@@ -1,4 +1,3 @@
import React from 'react';
import { Input } from '@/renderer/components/ui/input';
import { Button } from '@/renderer/components/ui/button';
import { Spinner } from '@/renderer/components/ui/spinner';

View File

@@ -1,4 +1,3 @@
import React from 'react';
import { LoginForm } from '@/renderer/components/accounts/login-form';
import { useQuery } from '@/renderer/hooks/use-query';

View File

@@ -1,4 +1,3 @@
import React from 'react';
import {
Tabs,
TabsContent,

View File

@@ -16,7 +16,7 @@ export const AvatarUpload = ({ onUpload }: AvatarUploadProps) => {
const [isFileDialogOpen, setIsFileDialogOpen] = React.useState(false);
const [url, setUrl] = React.useState<string | undefined>(undefined);
const handleSubmit = async (url: string) => {
const handleSubmit = async (_: string) => {
// TODO
};

View File

@@ -1,4 +1,3 @@
import React from 'react';
import { cn } from '@/lib/utils';
import {
getAvatarSizeClasses,
@@ -57,7 +56,7 @@ const AvatarFallback = ({ id, name, size, className }: AvatarProps) => {
className={cn(
'inline-flex items-center justify-center overflow-hidden rounded text-white shadow',
getAvatarSizeClasses(size),
className,
className
)}
style={{ backgroundColor: color }}
>

View File

@@ -1,4 +1,3 @@
import React from 'react';
import { Conversation } from '@/renderer/components/messages/conversation';
interface ChannelContainerProps {

View File

@@ -1,4 +1,3 @@
import React from 'react';
import { useWorkspace } from '@/renderer/contexts/workspace';
import {
Dialog,

View File

@@ -1,4 +1,3 @@
import React from 'react';
import {
AlertDialog,
AlertDialogCancel,

View File

@@ -1,4 +1,3 @@
import React from 'react';
import { Conversation } from '@/renderer/components/messages/conversation';
interface ChatContainerProps {

View File

@@ -1,4 +1,3 @@
import React from 'react';
import {
DropdownMenu,
DropdownMenuContent,

View File

@@ -1,4 +1,3 @@
import React from 'react';
import { NodeCollaborator as NodeCollaboratorType } from '@/types/nodes';
import { Avatar } from '@/renderer/components/avatars/avatar';
import { NodeCollaboratorRoleDropdown } from '@/renderer/components/collaborators/node-collaborator-role-dropdown';

View File

@@ -1,4 +1,3 @@
import React from 'react';
import {
Popover,
PopoverTrigger,

View File

@@ -1,8 +1,11 @@
import React from 'react';
import { useWorkspace } from '@/renderer/contexts/workspace';
import { useMutation } from '@/renderer/hooks/use-mutation';
import { RecordNode } from '@/registry';
import { SelectFieldAttributes, SelectOptionAttributes } from '@/registry';
import {
RecordNode,
SelectFieldAttributes,
SelectOptionAttributes,
} from '@colanode/core';
import { useDrag } from 'react-dnd';
import { cn } from '@/lib/utils';
@@ -22,7 +25,7 @@ export const BoardViewCard = ({ record }: BoardViewCardProps) => {
const [, drag] = useDrag({
type: 'board-record',
item: { id: record.id },
end: (item, monitor) => {
end: (_, monitor) => {
const dropResult = monitor.getDropResult<DragResult>();
if (dropResult != null) {
if (isPending) return;
@@ -64,7 +67,7 @@ export const BoardViewCard = ({ record }: BoardViewCardProps) => {
key={record.id}
className={cn(
'animate-fade-in flex cursor-pointer flex-col gap-1 rounded-md border p-2 text-left hover:bg-gray-50',
hasName ? '' : 'text-muted-foreground',
hasName ? '' : 'text-muted-foreground'
)}
onClick={() => workspace.openModal(record.id)}
>

View File

@@ -1,6 +1,5 @@
import React from 'react';
import { SelectOptionBadge } from '@/renderer/components/databases/fields/select-option-badge';
import { SelectOptionAttributes } from '@/registry';
import { SelectOptionAttributes } from '@colanode/core';
interface BoardViewColumnHeaderProps {
option: SelectOptionAttributes;

View File

@@ -1,11 +1,10 @@
import React from 'react';
import { useDatabase } from '@/renderer/contexts/database';
import { useInfiniteQuery } from '@/renderer/hooks/use-infinite-query';
import {
SelectFieldAttributes,
SelectOptionAttributes,
ViewFilterAttributes,
} from '@/registry';
} from '@colanode/core';
import { BoardViewCard } from '@/renderer/components/databases/boards/board-view-card';
import { useWorkspace } from '@/renderer/contexts/workspace';
import { useView } from '@/renderer/contexts/view';
@@ -35,38 +34,37 @@ export const BoardViewColumnRecords = ({
value: [option.id],
},
];
const { data, isPending, isFetchingNextPage, fetchNextPage, hasNextPage } =
useInfiniteQuery({
initialPageInput: {
const { data } = useInfiniteQuery({
initialPageInput: {
type: 'record_list',
databaseId: database.id,
filters: filters,
sorts: view.sorts,
page: 0,
count: RECORDS_PER_PAGE,
userId: workspace.userId,
},
getNextPageInput(page, pages) {
if (page > pages.length) {
return undefined;
}
const lastPage = pages[page - 1];
if (lastPage.length < RECORDS_PER_PAGE) {
return undefined;
}
return {
type: 'record_list',
databaseId: database.id,
filters: filters,
sorts: view.sorts,
page: 0,
sorts: Object.values(view.sorts),
page: page,
count: RECORDS_PER_PAGE,
userId: workspace.userId,
},
getNextPageInput(page, pages) {
if (page > pages.length) {
return undefined;
}
const lastPage = pages[page - 1];
if (lastPage.length < RECORDS_PER_PAGE) {
return undefined;
}
return {
type: 'record_list',
databaseId: database.id,
filters: filters,
sorts: Object.values(view.sorts),
page: page,
count: RECORDS_PER_PAGE,
userId: workspace.userId,
};
},
});
};
},
});
const records = data?.flatMap((page) => page) ?? [];
return (

View File

@@ -2,7 +2,7 @@ import React from 'react';
import { getSelectOptionLightColorClass } from '@/lib/databases';
import { cn } from '@/lib/utils';
import { useDrop } from 'react-dnd';
import { SelectFieldAttributes, SelectOptionAttributes } from '@/registry';
import { SelectFieldAttributes, SelectOptionAttributes } from '@colanode/core';
import { BoardViewColumnHeader } from '@/renderer/components/databases/boards/board-view-column-header';
import { BoardViewColumnRecords } from '@/renderer/components/databases/boards/board-view-column-records';

View File

@@ -1,6 +1,5 @@
import React from 'react';
import { useWorkspace } from '@/renderer/contexts/workspace';
import { RecordNode } from '@/registry';
import { RecordNode } from '@colanode/core';
import { cn } from '@/lib/utils';
interface CalendarViewCardProps {
@@ -19,7 +18,7 @@ export const CalendarViewCard = ({ record }: CalendarViewCardProps) => {
key={record.id}
className={cn(
'animate-fade-in flex cursor-pointer flex-col gap-1 rounded-md border p-2 hover:bg-gray-50',
hasName ? '' : 'text-muted-foreground',
hasName ? '' : 'text-muted-foreground'
)}
onClick={() => workspace.openModal(record.id)}
>

View File

@@ -1,6 +1,5 @@
import React from 'react';
import { cn, isSameDay } from '@/lib/utils';
import { RecordNode } from '@/registry';
import { RecordNode } from '@colanode/core';
import { CalendarViewCard } from '@/renderer/components/databases/calendars/calendar-view-card';
import { Plus } from 'lucide-react';
@@ -27,13 +26,13 @@ export const CalendarViewDay = ({
<div
className={cn(
'flex justify-between text-sm',
isOutside ? 'text-muted-foreground' : '',
isOutside ? 'text-muted-foreground' : ''
)}
>
<Plus
className={cn(
'size-4 cursor-pointer opacity-0',
canCreateRecord ? 'group-hover:opacity-100' : '',
canCreateRecord ? 'group-hover:opacity-100' : ''
)}
onClick={() => {}}
/>

Some files were not shown because too many files have changed in this diff Show More