Table renames

This commit is contained in:
Hakan Shehu
2024-10-28 21:47:32 +01:00
parent 9141d60b5c
commit 78402bbf64
24 changed files with 202 additions and 208 deletions

View File

@@ -44,27 +44,28 @@ const createNodesTable: Migration = {
},
};
const createNodeUserStatesTable: Migration = {
const createUserNodesTable: Migration = {
up: async (db) => {
await db.schema
.createTable('node_user_states')
.createTable('user_nodes')
.addColumn('user_id', 'text', (col) => col.notNull())
.addColumn('node_id', 'text', (col) =>
col.notNull().references('nodes.id'),
)
.addColumn('user_id', 'text', (col) => col.notNull())
.addColumn('last_seen_version_id', 'text')
.addColumn('last_seen_at', 'text')
.addColumn('mentions_count', 'integer', (col) =>
col.notNull().defaultTo(0),
)
.addColumn('attributes', 'text')
.addColumn('version_id', 'text', (col) => col.notNull())
.addColumn('created_at', 'text', (col) => col.notNull())
.addColumn('updated_at', 'text')
.addPrimaryKeyConstraint('node_user_states_pk', ['node_id', 'user_id'])
.addPrimaryKeyConstraint('user_nodes_pk', ['user_id', 'node_id'])
.execute();
},
down: async (db) => {
await db.schema.dropTable('node_user_states').execute();
await db.schema.dropTable('user_nodes').execute();
},
};
@@ -167,7 +168,7 @@ const createDownloadsTable: Migration = {
export const workspaceDatabaseMigrations: Record<string, Migration> = {
'00001_create_nodes_table': createNodesTable,
'00002_create_node_user_states_table': createNodeUserStatesTable,
'00002_create_user_nodes_table': createUserNodesTable,
'00003_create_changes_table': createChangesTable,
'00004_create_node_names_table': createNodeNamesTable,
'00005_create_uploads_table': createUploadsTable,

View File

@@ -21,20 +21,21 @@ export type SelectNode = Selectable<NodeTable>;
export type CreateNode = Insertable<NodeTable>;
export type UpdateNode = Updateable<NodeTable>;
interface NodeUserStateTable {
node_id: ColumnType<string, string, never>;
interface UserNodeTable {
user_id: ColumnType<string, string, never>;
node_id: ColumnType<string, string, never>;
last_seen_version_id: ColumnType<string | null, string | null, string | null>;
last_seen_at: ColumnType<string | null, string | null, string | null>;
mentions_count: ColumnType<number, number, number>;
attributes: ColumnType<string | null, string | null, string | null>;
version_id: ColumnType<string, string, string>;
created_at: ColumnType<string, string, never>;
updated_at: ColumnType<string | null, string | null, string | null>;
}
export type SelectNodeUserState = Selectable<NodeUserStateTable>;
export type CreateNodeUserState = Insertable<NodeUserStateTable>;
export type UpdateNodeUserState = Updateable<NodeUserStateTable>;
export type SelectUserNode = Selectable<UserNodeTable>;
export type CreateUserNode = Insertable<UserNodeTable>;
export type UpdateUserNode = Updateable<UserNodeTable>;
interface ChangeTable {
id: ColumnType<number, never, never>;
@@ -73,7 +74,7 @@ export type UpdateDownload = Updateable<DownloadTable>;
export interface WorkspaceDatabaseSchema {
nodes: NodeTable;
node_user_states: NodeUserStateTable;
user_nodes: UserNodeTable;
changes: ChangeTable;
uploads: UploadTable;
downloads: DownloadTable;

View File

@@ -3,8 +3,8 @@ import { LocalNodeSyncMessageHandler } from '@/main/handlers/messages/local-node
import { LocalNodeDeleteMessageHandler } from '@/main/handlers/messages/local-node-delete';
import { ServerNodeSyncMessageHandler } from '@/main/handlers/messages/server-node-sync';
import { ServerNodeDeleteMessageHandler } from '@/main/handlers/messages/server-node-delete';
import { ServerNodeUserStateSyncMessageHandler } from '@/main/handlers/messages/server-node-user-state-sync';
import { LocalNodeUserStateSyncMessageHandler } from '@/main/handlers/messages/local-node-user-state-sync';
import { ServerUserNodeSyncMessageHandler } from '@/main/handlers/messages/server-user-node-sync';
import { LocalUserNodeSyncMessageHandler } from '@/main/handlers/messages/local-user-node-sync';
type MessageHandlerMap = {
[K in keyof MessageMap]: MessageHandler<MessageMap[K]>;
@@ -15,6 +15,6 @@ export const messageHandlerMap: MessageHandlerMap = {
local_node_delete: new LocalNodeDeleteMessageHandler(),
server_node_sync: new ServerNodeSyncMessageHandler(),
server_node_delete: new ServerNodeDeleteMessageHandler(),
server_node_user_state_sync: new ServerNodeUserStateSyncMessageHandler(),
local_node_user_state_sync: new LocalNodeUserStateSyncMessageHandler(),
server_user_node_sync: new ServerUserNodeSyncMessageHandler(),
local_user_node_sync: new LocalUserNodeSyncMessageHandler(),
};

View File

@@ -1,13 +1,13 @@
import { MessageContext, MessageHandler } from '@/operations/messages';
import { LocalNodeUserStateSyncMessageInput } from '@/operations/messages/local-node-user-state-sync';
import { LocalUserNodeSyncMessageInput } from '@/operations/messages/local-user-node-sync';
import { socketManager } from '@/main/sockets/socket-manager';
export class LocalNodeUserStateSyncMessageHandler
implements MessageHandler<LocalNodeUserStateSyncMessageInput>
export class LocalUserNodeSyncMessageHandler
implements MessageHandler<LocalUserNodeSyncMessageInput>
{
public async handleMessage(
context: MessageContext,
input: LocalNodeUserStateSyncMessageInput,
input: LocalUserNodeSyncMessageInput,
): Promise<void> {
socketManager.sendMessage(context.accountId, input);
}

View File

@@ -1,16 +1,16 @@
import { MessageContext, MessageHandler } from '@/operations/messages';
import { ServerNodeUserStateSyncMessageInput } from '@/operations/messages/server-node-user-state-sync';
import { ServerUserNodeSyncMessageInput } from '@/operations/messages/server-user-node-sync';
import { mediator } from '@/main/mediator';
export class ServerNodeUserStateSyncMessageHandler
implements MessageHandler<ServerNodeUserStateSyncMessageInput>
export class ServerUserNodeSyncMessageHandler
implements MessageHandler<ServerUserNodeSyncMessageInput>
{
public async handleMessage(
context: MessageContext,
input: ServerNodeUserStateSyncMessageInput,
input: ServerUserNodeSyncMessageInput,
): Promise<void> {
await mediator.executeMutation({
type: 'server_node_user_state_sync',
type: 'server_user_node_sync',
accountId: context.accountId,
nodeId: input.nodeId,
userId: input.userId,

View File

@@ -36,7 +36,7 @@ import { FileCreateMutationHandler } from '@/main/handlers/mutations/file-create
import { FileDownloadMutationHandler } from '@/main/handlers/mutations/file-download';
import { SpaceUpdateMutationHandler } from '@/main/handlers/mutations/space-update';
import { AccountUpdateMutationHandler } from '@/main/handlers/mutations/account-update';
import { ServerNodeUserStateSyncMutationHandler } from '@/main/handlers/mutations/server-node-user-state-sync';
import { ServerUserNodeSyncMutationHandler } from '@/main/handlers/mutations/server-user-node-sync';
import { MarkNodeAsSeenMutationHandler } from '@/main/handlers/mutations/mark-node-as-seen';
type MutationHandlerMap = {
@@ -81,6 +81,6 @@ export const mutationHandlerMap: MutationHandlerMap = {
file_download: new FileDownloadMutationHandler(),
space_update: new SpaceUpdateMutationHandler(),
account_update: new AccountUpdateMutationHandler(),
server_node_user_state_sync: new ServerNodeUserStateSyncMutationHandler(),
server_user_node_sync: new ServerUserNodeSyncMutationHandler(),
mark_node_as_seen: new MarkNodeAsSeenMutationHandler(),
};

View File

@@ -2,7 +2,7 @@ import { generateId, IdType } from '@/lib/id';
import { databaseManager } from '@/main/data/database-manager';
import { MutationHandler, MutationResult } from '@/operations/mutations';
import { MarkNodeAsSeenMutationInput } from '@/operations/mutations/mark-node-as-seen';
import { LocalNodeUserStateChangeData } from '@/types/sync';
import { LocalUserNodeChangeData } from '@/types/sync';
export class MarkNodeAsSeenMutationHandler
implements MutationHandler<MarkNodeAsSeenMutationInput>
@@ -14,8 +14,8 @@ export class MarkNodeAsSeenMutationHandler
input.userId,
);
const changeData: LocalNodeUserStateChangeData = {
type: 'node_user_state_update',
const changeData: LocalUserNodeChangeData = {
type: 'user_node_update',
nodeId: input.nodeId,
userId: input.userId,
lastSeenVersionId: input.versionId,
@@ -26,7 +26,7 @@ export class MarkNodeAsSeenMutationHandler
await workspaceDatabase.transaction().execute(async (trx) => {
await trx
.updateTable('node_user_states')
.updateTable('user_nodes')
.set({
last_seen_version_id: input.versionId,
last_seen_at: new Date().toISOString(),
@@ -53,7 +53,7 @@ export class MarkNodeAsSeenMutationHandler
changes: [
{
type: 'workspace',
table: 'node_user_states',
table: 'user_nodes',
userId: input.userId,
},
{

View File

@@ -1,18 +1,14 @@
import { databaseManager } from '@/main/data/database-manager';
import { socketManager } from '@/main/sockets/socket-manager';
import {
MutationChange,
MutationHandler,
MutationResult,
} from '@/operations/mutations';
import { ServerNodeUserStateSyncMutationInput } from '@/operations/mutations/server-node-user-state-sync';
import { MutationHandler, MutationResult } from '@/operations/mutations';
import { ServerUserNodeSyncMutationInput } from '@/operations/mutations/server-user-node-sync';
export class ServerNodeUserStateSyncMutationHandler
implements MutationHandler<ServerNodeUserStateSyncMutationInput>
export class ServerUserNodeSyncMutationHandler
implements MutationHandler<ServerUserNodeSyncMutationInput>
{
public async handleMutation(
input: ServerNodeUserStateSyncMutationInput,
): Promise<MutationResult<ServerNodeUserStateSyncMutationInput>> {
input: ServerUserNodeSyncMutationInput,
): Promise<MutationResult<ServerUserNodeSyncMutationInput>> {
const workspace = await databaseManager.appDatabase
.selectFrom('workspaces')
.selectAll()
@@ -37,10 +33,10 @@ export class ServerNodeUserStateSyncMutationHandler
await databaseManager.getWorkspaceDatabase(userId);
await workspaceDatabase
.insertInto('node_user_states')
.insertInto('user_nodes')
.values({
node_id: input.nodeId,
user_id: input.userId,
node_id: input.nodeId,
version_id: input.versionId,
last_seen_at: input.lastSeenAt,
last_seen_version_id: input.lastSeenVersionId,
@@ -60,11 +56,11 @@ export class ServerNodeUserStateSyncMutationHandler
.execute();
socketManager.sendMessage(workspace.account_id, {
type: 'local_node_user_state_sync',
type: 'local_user_node_sync',
userId: input.userId,
nodeId: input.nodeId,
versionId: input.versionId,
workspaceId: input.workspaceId,
userId: input.userId,
});
return {
@@ -74,7 +70,7 @@ export class ServerNodeUserStateSyncMutationHandler
changes: [
{
type: 'workspace',
table: 'node_user_states',
table: 'user_nodes',
userId: userId,
},
],

View File

@@ -52,7 +52,7 @@ export class SidebarChatListQueryHandler
!changes.some(
(change) =>
change.type === 'workspace' &&
(change.table === 'nodes' || change.table === 'node_user_states') &&
(change.table === 'nodes' || change.table === 'user_nodes') &&
change.userId === input.userId,
)
) {
@@ -157,16 +157,16 @@ export class SidebarChatListQueryHandler
const chatIds = chats.map((chat) => chat.id);
const unreadCounts = await workspaceDatabase
.selectFrom('node_user_states as nus')
.innerJoin('nodes as n', 'nus.node_id', 'n.id')
.where('nus.user_id', '=', input.userId)
.selectFrom('user_nodes as un')
.innerJoin('nodes as n', 'un.node_id', 'n.id')
.where('un.user_id', '=', input.userId)
.where('n.type', '=', NodeTypes.Message)
.where('n.parent_id', 'in', chatIds)
.where('nus.last_seen_version_id', 'is', null)
.where('un.last_seen_version_id', 'is', null)
.select(['n.parent_id as node_id'])
.select((eb) => [
eb.fn.count<number>('nus.node_id').as('unread_count'),
eb.fn.sum<number>('nus.mentions_count').as('mentions_count'),
eb.fn.count<number>('un.node_id').as('unread_count'),
eb.fn.sum<number>('un.mentions_count').as('mentions_count'),
])
.groupBy('n.parent_id')
.execute();

View File

@@ -48,7 +48,7 @@ export class SidebarSpaceListQueryHandler
!changes.some(
(change) =>
change.type === 'workspace' &&
(change.table === 'nodes' || change.table === 'node_user_states') &&
(change.table === 'nodes' || change.table === 'user_nodes') &&
change.userId === input.userId,
)
) {
@@ -119,16 +119,16 @@ export class SidebarSpaceListQueryHandler
.map((r) => r.id);
const unreadCounts = await workspaceDatabase
.selectFrom('node_user_states as nus')
.innerJoin('nodes as n', 'nus.node_id', 'n.id')
.where('nus.user_id', '=', input.userId)
.selectFrom('user_nodes as un')
.innerJoin('nodes as n', 'un.node_id', 'n.id')
.where('un.user_id', '=', input.userId)
.where('n.type', '=', NodeTypes.Message)
.where('n.parent_id', 'in', channelIds)
.where('nus.last_seen_version_id', 'is', null)
.where('un.last_seen_version_id', 'is', null)
.select(['n.parent_id as node_id'])
.select((eb) => [
eb.fn.count<number>('nus.node_id').as('unread_count'),
eb.fn.sum<number>('nus.mentions_count').as('mentions_count'),
eb.fn.count<number>('un.node_id').as('unread_count'),
eb.fn.sum<number>('un.mentions_count').as('mentions_count'),
])
.groupBy('n.parent_id')
.execute();

View File

@@ -1,13 +0,0 @@
export type LocalNodeUserStateSyncMessageInput = {
type: 'local_node_user_state_sync';
nodeId: string;
userId: string;
workspaceId: string;
versionId: string;
};
declare module '@/operations/messages' {
interface MessageMap {
local_node_user_state_sync: LocalNodeUserStateSyncMessageInput;
}
}

View File

@@ -0,0 +1,13 @@
export type LocalUserNodeSyncMessageInput = {
type: 'local_user_node_sync';
nodeId: string;
userId: string;
workspaceId: string;
versionId: string;
};
declare module '@/operations/messages' {
interface MessageMap {
local_user_node_sync: LocalUserNodeSyncMessageInput;
}
}

View File

@@ -1,5 +1,5 @@
export type ServerNodeUserStateSyncMessageInput = {
type: 'server_node_user_state_sync';
export type ServerUserNodeSyncMessageInput = {
type: 'server_user_node_sync';
nodeId: string;
userId: string;
workspaceId: string;
@@ -13,6 +13,6 @@ export type ServerNodeUserStateSyncMessageInput = {
declare module '@/operations/messages' {
interface MessageMap {
server_node_user_state_sync: ServerNodeUserStateSyncMessageInput;
server_user_node_sync: ServerUserNodeSyncMessageInput;
}
}

View File

@@ -1,5 +1,5 @@
export type ServerNodeUserStateSyncMutationInput = {
type: 'server_node_user_state_sync';
export type ServerUserNodeSyncMutationInput = {
type: 'server_user_node_sync';
accountId: string;
nodeId: string;
userId: string;
@@ -12,15 +12,15 @@ export type ServerNodeUserStateSyncMutationInput = {
updatedAt: string | null;
};
export type ServerNodeUserStateSyncMutationOutput = {
export type ServerUserNodeSyncMutationOutput = {
success: boolean;
};
declare module '@/operations/mutations' {
interface MutationMap {
server_node_user_state_sync: {
input: ServerNodeUserStateSyncMutationInput;
output: ServerNodeUserStateSyncMutationOutput;
server_user_node_sync: {
input: ServerUserNodeSyncMutationInput;
output: ServerUserNodeSyncMutationOutput;
};
}
}

View File

@@ -34,8 +34,8 @@ export type LocalDeleteNodeChangeData = {
deletedBy: string;
};
export type LocalNodeUserStateChangeData = {
type: 'node_user_state_update';
export type LocalUserNodeChangeData = {
type: 'user_node_update';
nodeId: string;
userId: string;
lastSeenVersionId: string;
@@ -48,4 +48,4 @@ export type LocalNodeChangeData =
| LocalCreateNodeChangeData
| LocalUpdateNodeChangeData
| LocalDeleteNodeChangeData
| LocalNodeUserStateChangeData;
| LocalUserNodeChangeData;

View File

@@ -281,49 +281,47 @@ const createNodeCollaboratorsTable: Migration = {
},
};
const createNodeUserStatesTable: Migration = {
const createUserNodesTable: Migration = {
up: async (db) => {
await db.schema
.createTable('node_user_states')
.addColumn('node_id', 'varchar(30)', (col) => col.notNull())
.createTable('user_nodes')
.addColumn('user_id', 'varchar(30)', (col) => col.notNull())
.addColumn('node_id', 'varchar(30)', (col) => col.notNull())
.addColumn('workspace_id', 'varchar(30)', (col) => col.notNull())
.addColumn('last_seen_version_id', 'varchar(30)')
.addColumn('last_seen_at', 'timestamptz')
.addColumn('mentions_count', 'integer', (col) =>
col.notNull().defaultTo(0),
)
.addColumn('attributes', 'jsonb')
.addColumn('created_at', 'timestamptz', (col) => col.notNull())
.addColumn('updated_at', 'timestamptz')
.addColumn('access_removed_at', 'timestamptz')
.addColumn('version_id', 'varchar(30)', (col) => col.notNull())
.addPrimaryKeyConstraint('node_user_states_pkey', ['node_id', 'user_id'])
.addPrimaryKeyConstraint('user_nodes_pkey', ['user_id', 'node_id'])
.execute();
},
down: async (db) => {
await db.schema.dropTable('node_user_states').execute();
await db.schema.dropTable('user_nodes').execute();
},
};
const createNodeDeviceStatesTable: Migration = {
const createDeviceNodesTable: Migration = {
up: async (db) => {
await db.schema
.createTable('node_device_states')
.addColumn('node_id', 'varchar(30)', (col) => col.notNull())
.createTable('device_nodes')
.addColumn('device_id', 'varchar(30)', (col) => col.notNull())
.addColumn('node_id', 'varchar(30)', (col) => col.notNull())
.addColumn('workspace_id', 'varchar(30)', (col) => col.notNull())
.addColumn('node_version_id', 'varchar(30)')
.addColumn('user_state_version_id', 'varchar(30)')
.addColumn('user_node_version_id', 'varchar(30)')
.addColumn('node_synced_at', 'timestamptz')
.addColumn('user_state_synced_at', 'timestamptz')
.addPrimaryKeyConstraint('node_device_states_pkey', [
'node_id',
'device_id',
])
.addColumn('user_node_synced_at', 'timestamptz')
.addPrimaryKeyConstraint('device_nodes_pkey', ['device_id', 'node_id'])
.execute();
},
down: async (db) => {
await db.schema.dropTable('node_device_states').execute();
await db.schema.dropTable('device_nodes').execute();
},
};
@@ -335,6 +333,6 @@ export const databaseMigrations: Record<string, Migration> = {
'00005_create_nodes_table': createNodesTable,
'00006_create_node_paths_table': createNodePathsTable,
'00007_create_node_collaborators_table': createNodeCollaboratorsTable,
'00008_create_node_user_states_table': createNodeUserStatesTable,
'00009_create_node_device_states_table': createNodeDeviceStatesTable,
'00008_create_user_nodes_table': createUserNodesTable,
'00009_create_device_nodes_table': createDeviceNodesTable,
};

View File

@@ -128,37 +128,38 @@ export type SelectNodeCollaborator = Selectable<NodeCollaboratorTable>;
export type CreateNodeCollaborator = Insertable<NodeCollaboratorTable>;
export type UpdateNodeCollaborator = Updateable<NodeCollaboratorTable>;
interface NodeUserStateTable {
interface UserNodeTable {
node_id: ColumnType<string, string, never>;
user_id: ColumnType<string, string, never>;
workspace_id: ColumnType<string, string, never>;
last_seen_version_id: ColumnType<string | null, string | null, string | null>;
last_seen_at: ColumnType<Date | null, Date | null, Date>;
mentions_count: ColumnType<number, number, number>;
attributes: JSONColumnType<any, string | null, string | null>;
created_at: ColumnType<Date, Date, never>;
updated_at: ColumnType<Date | null, Date | null, Date>;
access_removed_at: ColumnType<Date | null, Date | null, Date>;
version_id: ColumnType<string, string, string>;
}
export type SelectNodeUserState = Selectable<NodeUserStateTable>;
export type CreateNodeUserState = Insertable<NodeUserStateTable>;
export type UpdateNodeUserState = Updateable<NodeUserStateTable>;
export type SelectUserNode = Selectable<UserNodeTable>;
export type CreateUserNode = Insertable<UserNodeTable>;
export type UpdateUserNode = Updateable<UserNodeTable>;
interface NodeDeviceStateTable {
interface DeviceNodeTable {
node_id: ColumnType<string, string, never>;
device_id: ColumnType<string, string, never>;
workspace_id: ColumnType<string, string, string>;
node_version_id: ColumnType<string | null, string | null, string | null>;
user_state_version_id: ColumnType<
string | null,
string | null,
string | null
>;
user_node_version_id: ColumnType<string | null, string | null, string | null>;
node_synced_at: ColumnType<Date | null, Date | null, Date>;
user_state_synced_at: ColumnType<Date | null, Date | null, Date>;
user_node_synced_at: ColumnType<Date | null, Date | null, Date>;
}
export type SelectDeviceNode = Selectable<DeviceNodeTable>;
export type CreateDeviceNode = Insertable<DeviceNodeTable>;
export type UpdateDeviceNode = Updateable<DeviceNodeTable>;
export interface DatabaseSchema {
accounts: AccountTable;
devices: DeviceTable;
@@ -167,6 +168,6 @@ export interface DatabaseSchema {
nodes: NodeTable;
node_paths: NodePathTable;
node_collaborators: NodeCollaboratorTable;
node_user_states: NodeUserStateTable;
node_device_states: NodeDeviceStateTable;
user_nodes: UserNodeTable;
device_nodes: DeviceNodeTable;
}

View File

@@ -1,6 +1,6 @@
import { database } from '@/data/database';
import { redisConfig } from '@/data/redis';
import { CreateNodeUserState } from '@/data/schema';
import { CreateUserNode } from '@/data/schema';
import { filesStorage } from '@/data/storage';
import { BUCKET_NAMES } from '@/data/storage';
import { NodeTypes } from '@/lib/constants';
@@ -61,7 +61,7 @@ const handleEventJob = async (job: Job) => {
const handleNodeCreatedEvent = async (
event: NodeCreatedEvent,
): Promise<void> => {
await createNodeUserStates(event);
await createUserNodes(event);
await synapse.sendSynapseMessage({
type: 'node_create',
nodeId: event.id,
@@ -99,13 +99,13 @@ const handleNodeDeletedEvent = async (
});
};
const createNodeUserStates = async (event: NodeCreatedEvent): Promise<void> => {
const userStatesToCreate: CreateNodeUserState[] = [];
const createUserNodes = async (event: NodeCreatedEvent): Promise<void> => {
const userNodesToCreate: CreateUserNode[] = [];
if (event.attributes.type === NodeTypes.User) {
const userIds = await fetchWorkspaceUsers(event.workspaceId);
for (const userId of userIds) {
userStatesToCreate.push({
userNodesToCreate.push({
user_id: userId,
node_id: event.id,
workspace_id: event.workspaceId,
@@ -122,7 +122,7 @@ const createNodeUserStates = async (event: NodeCreatedEvent): Promise<void> => {
continue;
}
userStatesToCreate.push({
userNodesToCreate.push({
user_id: event.id,
node_id: userId,
workspace_id: event.workspaceId,
@@ -140,7 +140,7 @@ const createNodeUserStates = async (event: NodeCreatedEvent): Promise<void> => {
const collaboratorIds = collaborators.map((c) => c.collaboratorId);
for (const collaboratorId of collaboratorIds) {
userStatesToCreate.push({
userNodesToCreate.push({
user_id: collaboratorId,
node_id: event.id,
workspace_id: event.workspaceId,
@@ -157,10 +157,10 @@ const createNodeUserStates = async (event: NodeCreatedEvent): Promise<void> => {
}
}
if (userStatesToCreate.length > 0) {
if (userNodesToCreate.length > 0) {
await database
.insertInto('node_user_states')
.values(userStatesToCreate)
.insertInto('user_nodes')
.values(userNodesToCreate)
.onConflict((cb) => cb.doNothing())
.execute();
}
@@ -187,16 +187,14 @@ const checkForCollaboratorsChange = async (
}
if (addedCollaborators.length > 0) {
const existingNodeUserStates = await database
.selectFrom('node_user_states')
const existingUserNodes = await database
.selectFrom('user_nodes')
.select('user_id')
.where('node_id', '=', event.id)
.where('user_id', 'in', addedCollaborators)
.execute();
const existingCollaboratorIds = existingNodeUserStates.map(
(e) => e.user_id,
);
const existingCollaboratorIds = existingUserNodes.map((e) => e.user_id);
const actualAddedCollaborators = difference(
addedCollaborators,
@@ -211,10 +209,10 @@ const checkForCollaboratorsChange = async (
.execute();
const descendantIds = descendants.map((d) => d.descendant_id);
const userStatesToCreate: CreateNodeUserState[] = [];
const userNodesToCreate: CreateUserNode[] = [];
for (const collaboratorId of addedCollaborators) {
for (const descendantId of descendantIds) {
userStatesToCreate.push({
userNodesToCreate.push({
user_id: collaboratorId,
node_id: descendantId,
last_seen_version_id: null,
@@ -228,10 +226,10 @@ const checkForCollaboratorsChange = async (
}
}
if (userStatesToCreate.length > 0) {
if (userNodesToCreate.length > 0) {
await database
.insertInto('node_user_states')
.values(userStatesToCreate)
.insertInto('user_nodes')
.values(userNodesToCreate)
.onConflict((cb) => cb.doNothing())
.execute();
}
@@ -255,7 +253,7 @@ const checkForCollaboratorsChange = async (
const descendantIds = descendants.map((d) => d.descendant_id);
await database
.updateTable('node_user_states')
.updateTable('user_nodes')
.set({
access_removed_at: new Date(),
})

View File

@@ -54,7 +54,7 @@ const handleCleanDeviceDataTask = async (
}
await database
.deleteFrom('node_device_states')
.deleteFrom('device_nodes')
.where('device_id', '=', task.deviceId)
.execute();
};

View File

@@ -315,7 +315,7 @@ const handleNodeUserStateChange = async (
}
await database
.updateTable('node_user_states')
.updateTable('user_nodes')
.set({
last_seen_version_id: changeData.lastSeenVersionId,
last_seen_at: new Date(changeData.lastSeenAt),
@@ -328,7 +328,7 @@ const handleNodeUserStateChange = async (
.execute();
await synapse.sendSynapseMessage({
type: 'node_user_state_update',
type: 'user_node_update',
nodeId: changeData.nodeId,
userId: changeData.userId,
workspaceId: workspaceUser.workspace_id,

View File

@@ -7,8 +7,8 @@ import { redis } from '@/data/redis';
import {
SynapseMessage,
SynapseNodeChangeMessage,
SynapseNodeUserStateChangeMessage,
} from '@/types/events';
SynapseUserNodeChangeMessage,
} from '@/types/synapse';
import { getIdType, IdType } from '@/lib/id';
import { MessageInput } from '@/types/messages';
@@ -108,13 +108,13 @@ class SynapseService {
) {
if (message.type === 'local_node_sync') {
await database
.insertInto('node_device_states')
.insertInto('device_nodes')
.values({
node_id: message.nodeId,
device_id: connection.deviceId,
node_version_id: message.versionId,
user_state_version_id: null,
user_state_synced_at: null,
user_node_version_id: null,
user_node_synced_at: null,
workspace_id: message.workspaceId,
node_synced_at: new Date(),
})
@@ -126,29 +126,29 @@ class SynapseService {
}),
)
.execute();
} else if (message.type === 'local_node_user_state_sync') {
} else if (message.type === 'local_user_node_sync') {
await database
.insertInto('node_device_states')
.insertInto('device_nodes')
.values({
node_id: message.nodeId,
device_id: connection.deviceId,
node_version_id: null,
user_state_version_id: message.versionId,
user_state_synced_at: new Date(),
user_node_version_id: message.versionId,
user_node_synced_at: new Date(),
workspace_id: message.workspaceId,
node_synced_at: new Date(),
})
.onConflict((cb) =>
cb.columns(['node_id', 'device_id']).doUpdateSet({
workspace_id: message.workspaceId,
user_state_version_id: message.versionId,
user_state_synced_at: new Date(),
user_node_version_id: message.versionId,
user_node_synced_at: new Date(),
}),
)
.execute();
} else if (message.type === 'local_node_delete') {
await database
.deleteFrom('node_device_states')
.deleteFrom('device_nodes')
.where('device_id', '=', connection.deviceId)
.where('node_id', '=', message.nodeId)
.execute();
@@ -159,7 +159,7 @@ class SynapseService {
if (userId) {
await database
.deleteFrom('node_user_states')
.deleteFrom('user_nodes')
.where('node_id', '=', message.nodeId)
.where('user_id', '=', userId)
.execute();
@@ -181,8 +181,8 @@ class SynapseService {
data.type === 'node_delete'
) {
this.handleNodeChangeMessage(data);
} else if (data.type === 'node_user_state_update') {
this.handleNodeUserStateUpdateMessage(data);
} else if (data.type === 'user_node_update') {
this.handleUserNodeUpdateMessage(data);
}
}
@@ -202,21 +202,21 @@ class SynapseService {
return;
}
const nodeUserStates = await database
.selectFrom('node_user_states')
const userNodes = await database
.selectFrom('user_nodes')
.selectAll()
.where((eb) =>
eb.and([eb('user_id', 'in', userIds), eb('node_id', '=', data.nodeId)]),
)
.execute();
if (nodeUserStates.length === 0) {
if (userNodes.length === 0) {
return;
}
if (data.type === 'node_delete') {
for (const nodeUserState of nodeUserStates) {
const deviceIds = userDevices.get(nodeUserState.user_id) ?? [];
for (const userNode of userNodes) {
const deviceIds = userDevices.get(userNode.user_id) ?? [];
for (const deviceId of deviceIds) {
const socketConnection = this.connections.get(deviceId);
if (socketConnection === undefined) {
@@ -254,8 +254,8 @@ class SynapseService {
return;
}
for (const nodeUserState of nodeUserStates) {
const deviceIds = userDevices.get(nodeUserState.user_id) ?? [];
for (const userNode of userNodes) {
const deviceIds = userDevices.get(userNode.user_id) ?? [];
if (deviceIds.length === 0) {
continue;
}
@@ -266,7 +266,7 @@ class SynapseService {
continue;
}
if (nodeUserState.access_removed_at !== null) {
if (userNode.access_removed_at !== null) {
this.sendSocketMessage(socketConnection, {
type: 'server_node_delete',
id: data.nodeId,
@@ -291,22 +291,22 @@ class SynapseService {
}
}
private async handleNodeUserStateUpdateMessage(
data: SynapseNodeUserStateChangeMessage,
private async handleUserNodeUpdateMessage(
data: SynapseUserNodeChangeMessage,
) {
const userDevices = this.getWorkspaceUserDevices(data.workspaceId);
if (!userDevices.has(data.userId)) {
return;
}
const userState = await database
.selectFrom('node_user_states')
const userNode = await database
.selectFrom('user_nodes')
.selectAll()
.where('user_id', '=', data.userId)
.where('node_id', '=', data.nodeId)
.executeTakeFirst();
if (!userState) {
if (!userNode) {
return;
}
@@ -318,16 +318,16 @@ class SynapseService {
}
this.sendSocketMessage(socketConnection, {
type: 'server_node_user_state_sync',
type: 'server_user_node_sync',
userId: data.userId,
nodeId: data.nodeId,
lastSeenVersionId: userState.last_seen_version_id,
lastSeenVersionId: userNode.last_seen_version_id,
workspaceId: data.workspaceId,
versionId: userState.version_id,
lastSeenAt: userState.last_seen_at?.toISOString() ?? null,
createdAt: userState.created_at.toISOString(),
updatedAt: userState.updated_at?.toISOString() ?? null,
mentionsCount: userState.mentions_count,
versionId: userNode.version_id,
lastSeenAt: userNode.last_seen_at?.toISOString() ?? null,
createdAt: userNode.created_at.toISOString(),
updatedAt: userNode.updated_at?.toISOString() ?? null,
mentionsCount: userNode.mentions_count,
});
}
}
@@ -354,9 +354,9 @@ class SynapseService {
}
const unsyncedNodes = await database
.selectFrom('node_user_states as nus')
.selectFrom('user_nodes as nus')
.leftJoin('nodes as n', 'n.id', 'nus.node_id')
.leftJoin('node_device_states as nds', (join) =>
.leftJoin('device_nodes as nds', (join) =>
join
.onRef('nds.node_id', '=', 'nus.node_id')
.on('nds.device_id', '=', connection.deviceId),
@@ -380,9 +380,9 @@ class SynapseService {
'nus.mentions_count',
'nus.created_at',
'nus.updated_at',
'nus.version_id as user_state_version_id',
'nus.version_id as user_node_version_id',
'nds.node_version_id as device_node_version_id',
'nds.user_state_version_id as device_user_state_version_id',
'nds.user_node_version_id as device_user_node_version_id',
])
.where((eb) =>
eb.and([
@@ -392,8 +392,8 @@ class SynapseService {
eb('nus.access_removed_at', 'is not', null),
eb('nds.node_version_id', 'is', null),
eb('nds.node_version_id', '!=', eb.ref('n.version_id')),
eb('nds.user_state_version_id', 'is', null),
eb('nds.user_state_version_id', '!=', eb.ref('nus.version_id')),
eb('nds.user_node_version_id', 'is', null),
eb('nds.user_node_version_id', '!=', eb.ref('nus.version_id')),
]),
]),
)
@@ -416,13 +416,13 @@ class SynapseService {
continue;
}
if (row.user_state_version_id !== row.device_user_state_version_id) {
if (row.user_node_version_id !== row.device_user_node_version_id) {
this.sendSocketMessage(connection, {
type: 'server_node_user_state_sync',
type: 'server_user_node_sync',
nodeId: row.node_id,
userId: row.user_id,
workspaceId: row.workspace_id,
versionId: row.user_state_version_id!,
versionId: row.user_node_version_id!,
lastSeenAt: row.last_seen_at?.toISOString() ?? null,
lastSeenVersionId: row.last_seen_version_id ?? null,
mentionsCount: row.mentions_count,

View File

@@ -32,20 +32,3 @@ export type NodeDeletedEvent = {
attributes: ServerNodeAttributes;
deletedAt: string;
};
export type SynapseNodeChangeMessage = {
workspaceId: string;
nodeId: string;
type: 'node_create' | 'node_update' | 'node_delete';
};
export type SynapseNodeUserStateChangeMessage = {
workspaceId: string;
nodeId: string;
userId: string;
type: 'node_user_state_update';
};
export type SynapseMessage =
| SynapseNodeChangeMessage
| SynapseNodeUserStateChangeMessage;

View File

@@ -11,8 +11,8 @@ export type LocalNodeDeleteMessageInput = {
workspaceId: string;
};
export type LocalNodeUserStateSyncMessageInput = {
type: 'local_node_user_state_sync';
export type LocalUserNodeSyncMessageInput = {
type: 'local_user_node_sync';
nodeId: string;
userId: string;
workspaceId: string;
@@ -33,10 +33,10 @@ export type ServerNodeSyncMessageInput = {
versionId: string;
};
export type ServerNodeUserStateSyncMessageInput = {
type: 'server_node_user_state_sync';
nodeId: string;
export type ServerUserNodeSyncMessageInput = {
type: 'server_user_node_sync';
userId: string;
nodeId: string;
workspaceId: string;
versionId: string;
lastSeenAt: string | null;
@@ -57,5 +57,5 @@ export type MessageInput =
| LocalNodeDeleteMessageInput
| ServerNodeSyncMessageInput
| ServerNodeDeleteMessageInput
| LocalNodeUserStateSyncMessageInput
| ServerNodeUserStateSyncMessageInput;
| LocalUserNodeSyncMessageInput
| ServerUserNodeSyncMessageInput;

View File

@@ -0,0 +1,16 @@
export type SynapseNodeChangeMessage = {
workspaceId: string;
nodeId: string;
type: 'node_create' | 'node_update' | 'node_delete';
};
export type SynapseUserNodeChangeMessage = {
workspaceId: string;
nodeId: string;
userId: string;
type: 'user_node_update';
};
export type SynapseMessage =
| SynapseNodeChangeMessage
| SynapseUserNodeChangeMessage;