diff --git a/bun.lock b/bun.lock index b7b75d82bb..7b233e4c85 100644 --- a/bun.lock +++ b/bun.lock @@ -16,7 +16,7 @@ }, "packages/client-query": { "name": "@hcengineering/communication-client-query", - "version": "0.1.4", + "version": "0.1.5", "dependencies": { "@hcengineering/communication-query": "workspace:*", "@hcengineering/communication-sdk-types": "workspace:*", @@ -32,7 +32,7 @@ }, "packages/client-sqlite": { "name": "@hcengineering/communication-client-sqlite", - "version": "0.1.4", + "version": "0.1.5", "dependencies": { "@hcengineering/communication-sdk-types": "workspace:*", "@hcengineering/communication-sqlite-wasm": "workspace:*", @@ -48,7 +48,7 @@ }, "packages/client-ws": { "name": "@hcengineering/communication-client-ws", - "version": "0.1.4", + "version": "0.1.5", "dependencies": { "@hcengineering/communication-sdk-types": "workspace:*", "@hcengineering/communication-types": "workspace:*", @@ -63,7 +63,7 @@ }, "packages/cockroach": { "name": "@hcengineering/communication-cockroach", - "version": "0.1.4", + "version": "0.1.5", "dependencies": { "@hcengineering/communication-sdk-types": "workspace:*", "@hcengineering/communication-types": "workspace:*", @@ -80,7 +80,7 @@ }, "packages/examples": { "name": "@hcengineering/communication-examples", - "version": "0.1.4", + "version": "0.1.5", "dependencies": { "@hcengineering/communication-client-query": "workspace:*", "@hcengineering/communication-client-sqlite": "workspace:*", @@ -96,7 +96,7 @@ }, "packages/query": { "name": "@hcengineering/communication-query", - "version": "0.1.4", + "version": "0.1.5", "dependencies": { "@hcengineering/communication-sdk-types": "workspace:*", "@hcengineering/communication-types": "workspace:*", @@ -112,7 +112,7 @@ }, "packages/sdk-types": { "name": "@hcengineering/communication-sdk-types", - "version": "0.1.4", + "version": "0.1.5", "dependencies": { "@hcengineering/communication-types": "^0.1.0", }, @@ -125,7 +125,7 @@ }, "packages/server-core": { "name": "@hcengineering/communication-server-core", - "version": "0.1.4", + "version": "0.1.5", "dependencies": { "@hcengineering/communication-cockroach": "workspace:*", "@hcengineering/communication-sdk-types": "workspace:*", @@ -144,7 +144,7 @@ }, "packages/server-ws": { "name": "@hcengineering/communication-server-ws", - "version": "0.1.4", + "version": "0.1.5", "dependencies": { "@hcengineering/communication-cockroach": "workspace:*", "@hcengineering/communication-sdk-types": "workspace:*", @@ -168,7 +168,7 @@ }, "packages/sqlite-wasm": { "name": "@hcengineering/communication-sqlite-wasm", - "version": "0.1.4", + "version": "0.1.5", "dependencies": { "@hcengineering/communication-sdk-types": "workspace:*", "@hcengineering/communication-types": "workspace:*", @@ -185,7 +185,7 @@ }, "packages/types": { "name": "@hcengineering/communication-types", - "version": "0.1.4", + "version": "0.1.5", "dependencies": { "@hcengineering/core": "0.6.411", }, diff --git a/packages/client-query/package.json b/packages/client-query/package.json index 5b1834f7bc..10d80ae805 100644 --- a/packages/client-query/package.json +++ b/packages/client-query/package.json @@ -1,6 +1,6 @@ { "name": "@hcengineering/communication-client-query", - "version": "0.1.4", + "version": "0.1.5", "main": "dist/index.js", "module": "dist/index.js", "types": "./types/index.d.ts", diff --git a/packages/client-sqlite/package.json b/packages/client-sqlite/package.json index a1fe8a26f6..a5b3b7c72c 100644 --- a/packages/client-sqlite/package.json +++ b/packages/client-sqlite/package.json @@ -1,6 +1,6 @@ { "name": "@hcengineering/communication-client-sqlite", - "version": "0.1.4", + "version": "0.1.5", "main": "dist/index.js", "module": "dist/index.js", "types": "./types/index.d.ts", diff --git a/packages/client-ws/package.json b/packages/client-ws/package.json index c5d682eae9..3140dc508b 100644 --- a/packages/client-ws/package.json +++ b/packages/client-ws/package.json @@ -1,6 +1,6 @@ { "name": "@hcengineering/communication-client-ws", - "version": "0.1.4", + "version": "0.1.5", "main": "dist/index.js", "module": "dist/index.js", "types": "./types/index.d.ts", diff --git a/packages/cockroach/package.json b/packages/cockroach/package.json index 33c53a3028..f59ea50c07 100644 --- a/packages/cockroach/package.json +++ b/packages/cockroach/package.json @@ -1,6 +1,6 @@ { "name": "@hcengineering/communication-cockroach", - "version": "0.1.4", + "version": "0.1.5", "main": "dist/index.js", "module": "dist/index.js", "types": "./types/index.d.ts", diff --git a/packages/examples/package.json b/packages/examples/package.json index 351076565e..42af3af812 100644 --- a/packages/examples/package.json +++ b/packages/examples/package.json @@ -1,6 +1,6 @@ { "name": "@hcengineering/communication-examples", - "version": "0.1.4", + "version": "0.1.5", "main": "dist/index.js", "module": "dist/index.js", "types": "./types/index.d.ts", diff --git a/packages/query/package.json b/packages/query/package.json index 8ba544a91d..bedab9911b 100644 --- a/packages/query/package.json +++ b/packages/query/package.json @@ -1,6 +1,6 @@ { "name": "@hcengineering/communication-query", - "version": "0.1.4", + "version": "0.1.5", "main": "dist/index.js", "module": "dist/index.js", "types": "./types/index.d.ts", diff --git a/packages/sdk-types/package.json b/packages/sdk-types/package.json index 0e2d265502..b2d4bef0f4 100644 --- a/packages/sdk-types/package.json +++ b/packages/sdk-types/package.json @@ -1,6 +1,6 @@ { "name": "@hcengineering/communication-sdk-types", - "version": "0.1.4", + "version": "0.1.5", "main": "./dist/index.js", "module": "./dist/index.js", "types": "./types/index.d.ts", diff --git a/packages/sdk-types/src/serverApi.ts b/packages/sdk-types/src/serverApi.ts index c26f7106c1..77bc2ea485 100644 --- a/packages/sdk-types/src/serverApi.ts +++ b/packages/sdk-types/src/serverApi.ts @@ -1,6 +1,6 @@ import type { FindMessagesParams, Message, SocialID } from '@hcengineering/communication-types' -import type { BroadcastEvent, EventResult, Event } from './event' +import type { EventResult, Event } from './event' export interface ConnectionInfo { sessionId: string @@ -8,17 +8,13 @@ export interface ConnectionInfo { socialId: SocialID } -export type Result = { - broadcastEvent?: BroadcastEvent - result: EventResult -} - export interface ServerApi { findMessages(info: ConnectionInfo, params: FindMessagesParams, queryId?: number): Promise - unsubscribeQuery(info: ConnectionInfo, id: number): Promise + event(info: ConnectionInfo, event: Event): Promise - event(info: ConnectionInfo, event: Event): Promise + closeSession(sessionId: string): Promise + unsubscribeQuery(info: ConnectionInfo, id: number): Promise close(): Promise } diff --git a/packages/server-core/package.json b/packages/server-core/package.json index f731ff2fbf..c0ef6fb0ad 100644 --- a/packages/server-core/package.json +++ b/packages/server-core/package.json @@ -1,6 +1,6 @@ { "name": "@hcengineering/communication-server-core", - "version": "0.1.4", + "version": "0.1.5", "main": "dist/index.js", "module": "dist/index.js", "types": "./types/index.d.ts", diff --git a/packages/server-core/src/index.ts b/packages/server-core/src/index.ts index 9c919919e6..9df66f2b2f 100644 --- a/packages/server-core/src/index.ts +++ b/packages/server-core/src/index.ts @@ -1,10 +1,9 @@ import type { MeasureContext } from '@hcengineering/core' import type { FindMessagesParams, Message } from '@hcengineering/communication-types' import { createDbAdapter } from '@hcengineering/communication-cockroach' -import type { ConnectionInfo, DbAdapter, Event, ServerApi } from '@hcengineering/communication-sdk-types' +import type { ConnectionInfo, DbAdapter, Event, EventResult, ServerApi } from '@hcengineering/communication-sdk-types' -import { type Result } from './eventProcessor.ts' -import { Manager } from './manager.ts' +import { Manager, type BroadcastSessionsFunc } from './manager.ts' export class Api implements ServerApi { private readonly manager: Manager @@ -12,14 +11,20 @@ export class Api implements ServerApi { private constructor( private readonly ctx: MeasureContext, private readonly workspace: string, - db: DbAdapter + db: DbAdapter, + broadcast: BroadcastSessionsFunc ) { - this.manager = new Manager(this.ctx, db, this.workspace) + this.manager = new Manager(this.ctx, db, this.workspace, broadcast) } - static async create(ctx: MeasureContext, workspace: string, dbUrl: string): Promise { + static async create( + ctx: MeasureContext, + workspace: string, + dbUrl: string, + broadcast: BroadcastSessionsFunc + ): Promise { const db = await createDbAdapter(dbUrl) - return new Api(ctx, workspace, db) + return new Api(ctx, workspace, db, broadcast) } async findMessages(info: ConnectionInfo, params: FindMessagesParams, queryId?: number): Promise { @@ -30,10 +35,14 @@ export class Api implements ServerApi { this.manager.unsubscribeQuery(info, id) } - async event(info: ConnectionInfo, event: Event): Promise { + async event(info: ConnectionInfo, event: Event): Promise { return await this.manager.event(info, event) } + async closeSession(sessionId: string): Promise { + this.manager.closeSession(sessionId) + } + async close(): Promise { this.manager.close() } diff --git a/packages/server-core/src/manager.ts b/packages/server-core/src/manager.ts index 85f3e6b2c6..e66af2e92b 100644 --- a/packages/server-core/src/manager.ts +++ b/packages/server-core/src/manager.ts @@ -5,7 +5,8 @@ import { EventType, type NotificationContextCreatedEvent, type NotificationCreatedEvent, - type Event + type Event, + type EventResult } from '@hcengineering/communication-sdk-types' import type { FindMessagesParams, @@ -16,12 +17,14 @@ import type { } from '@hcengineering/communication-types' import { Triggers } from './triggers.ts' -import { EventProcessor, type Result } from './eventProcessor.ts' +import { EventProcessor } from './eventProcessor.ts' import type { MeasureContext } from '@hcengineering/core' type QueryId = number | string type QueryType = 'message' | 'notification' | 'context' +export type BroadcastSessionsFunc = (ctx: MeasureContext, sessionIds: string[], result: any) => void + type SessionInfo = { personalWorkspace: string messageQueries: Map @@ -37,10 +40,11 @@ export class Manager { constructor( private readonly ctx: MeasureContext, private readonly db: DbAdapter, - private readonly workspace: string + private readonly workspace: string, + private readonly broadcast: BroadcastSessionsFunc ) { this.eventProcessor = new EventProcessor(db, this.workspace) - this.triggers = new Triggers(db) + this.triggers = new Triggers(db, this.workspace) } async findMessages(info: ConnectionInfo, params: FindMessagesParams, queryId?: number): Promise { @@ -51,18 +55,13 @@ export class Manager { return result } - async event(info: ConnectionInfo, event: Event): Promise { - return await this.eventProcessor.process(info.personalWorkspace, event) - // const { result, broadcastEvent } = await this.eventProcessor.process(personalWorkspace, event) - // if (broadcastEvent !== undefined) { - // void this.manager.next(broadcastEvent) - // } - // return result + async event(info: ConnectionInfo, event: Event): Promise { + const { result, broadcastEvent } = await this.eventProcessor.process(info.personalWorkspace, event) + if (broadcastEvent !== undefined) { + void this.next(broadcastEvent) + } + return result } - // - // async broadcastEvent (ctx: MeasureContext, personalWorkspace: string, event: BroadcastEvent): Promise { - // void this.manager.next(event, personalWorkspace) - // } subscribeQuery(info: ConnectionInfo, type: QueryType, queryId: number, params: Record): void { const { sessionId, personalWorkspace } = info @@ -94,30 +93,28 @@ export class Manager { data.contextQueries.delete(queryId) } - // closeSession(sessionId: string): void { - // this.dataBySessionId.delete(sessionId) - // } + closeSession(sessionId: string): void { + this.dataBySessionId.delete(sessionId) + } - // async next(event: BroadcastEvent, workspace: string): Promise { - // // await this.broadcast(event, workspace) - // // const derived = await this.triggers.process(event, workspace) - // // const derivedPromises: Promise[] = [] - // // for (const d of derived) { - // // derivedPromises.push(this.next(d, workspace)) - // // } - // // await Promise.all(derivedPromises) - // } + async next(event: BroadcastEvent): Promise { + await this.broadcastEvent(event) + const derived = await this.triggers.process(event) + await Promise.all(derived.map((it) => this.next(it))) + } - // private async broadcast(event: BroadcastEvent, workspace: string): Promise { - // // const sessions = this.sessionsByWorkspace.get(workspace) ?? [] - // // const response: Response = { result: event } - // // for (const session of sessions) { - // // const msg = serializeResponse(response, session.session.binary) - // // if (this.match(event, session)) { - // // session.ws.send(msg) - // // } - // // } - // } + private async broadcastEvent(event: BroadcastEvent): Promise { + const sessionIds: string[] = [] + for (const [sessionId, session] of this.dataBySessionId.entries()) { + if (this.match(event, session)) { + sessionIds.push(sessionId) + } + } + + if (sessionIds.length > 0) { + this.broadcast(this.ctx, sessionIds, event) + } + } private match(event: BroadcastEvent, info: SessionInfo): boolean { switch (event.type) { diff --git a/packages/server-core/src/triggers.ts b/packages/server-core/src/triggers.ts index cf512903d4..abc1396718 100644 --- a/packages/server-core/src/triggers.ts +++ b/packages/server-core/src/triggers.ts @@ -9,18 +9,21 @@ import { import type { NotificationContext, ContextID, CardID } from '@hcengineering/communication-types' export class Triggers { - constructor(private readonly db: DbAdapter) {} + constructor( + private readonly db: DbAdapter, + private readonly workspace: string + ) {} - async process(event: BroadcastEvent, workspace: string): Promise { + async process(event: BroadcastEvent): Promise { switch (event.type) { case EventType.MessageCreated: - return this.createNotifications(event, workspace) + return this.createNotifications(event) } return [] } - private async createNotifications(event: MessageCreatedEvent, workspace: string): Promise { + private async createNotifications(event: MessageCreatedEvent): Promise { const card = event.message.card as any as CardID const subscribedPersonalWorkspaces = [ 'cd0aba36-1c4f-4170-95f2-27a12a5415f7', @@ -28,16 +31,16 @@ export class Triggers { ] const res: BroadcastEvent[] = [] - const contexts = await this.db.findContexts({ card }, [], workspace) + const contexts = await this.db.findContexts({ card }, [], this.workspace) res.push(...(await this.updateNotificationContexts(event.message.created, contexts))) for (const personalWorkspace of subscribedPersonalWorkspaces) { const existsContext = contexts.find( - (it) => it.card === card && it.personalWorkspace === personalWorkspace && workspace === it.workspace + (it) => it.card === card && it.personalWorkspace === personalWorkspace && this.workspace === it.workspace ) const contextId = await this.getOrCreateContextId( - workspace, + this.workspace, card, personalWorkspace, res, diff --git a/packages/server-ws/package.json b/packages/server-ws/package.json index 0f313d72ec..0d3d8b8592 100644 --- a/packages/server-ws/package.json +++ b/packages/server-ws/package.json @@ -1,6 +1,6 @@ { "name": "@hcengineering/communication-server-ws", - "version": "0.1.4", + "version": "0.1.5", "main": "dist/index.js", "module": "dist/index.js", "types": "./types/index.d.ts", diff --git a/packages/sqlite-wasm/package.json b/packages/sqlite-wasm/package.json index d14a8a11f6..2a3ac5ff70 100644 --- a/packages/sqlite-wasm/package.json +++ b/packages/sqlite-wasm/package.json @@ -1,6 +1,6 @@ { "name": "@hcengineering/communication-sqlite-wasm", - "version": "0.1.4", + "version": "0.1.5", "main": "dist/index.js", "module": "dist/index.js", "types": "./types/index.d.ts", diff --git a/packages/types/package.json b/packages/types/package.json index 39778187f5..b0e085b1ec 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -1,6 +1,6 @@ { "name": "@hcengineering/communication-types", - "version": "0.1.4", + "version": "0.1.5", "main": "dist/index.js", "module": "dist/index.js", "types": "./types/index.d.ts",