mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-12 12:28:42 +00:00
feat(server): events system (#5145)
This commit is contained in:
@@ -3,6 +3,7 @@ import { Module } from '@nestjs/common';
|
||||
import { AppController } from './app.controller';
|
||||
import { CacheModule } from './cache';
|
||||
import { ConfigModule } from './config';
|
||||
import { EventModule } from './event';
|
||||
import { BusinessModules } from './modules';
|
||||
import { AuthModule } from './modules/auth';
|
||||
import { PrismaModule } from './prisma';
|
||||
@@ -14,6 +15,7 @@ const BasicModules = [
|
||||
PrismaModule,
|
||||
ConfigModule.forRoot(),
|
||||
CacheModule,
|
||||
EventModule,
|
||||
StorageModule.forRoot(),
|
||||
SessionModule,
|
||||
RateLimiterModule,
|
||||
|
||||
28
packages/backend/server/src/event/events.ts
Normal file
28
packages/backend/server/src/event/events.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
import type { Snapshot, User, Workspace } from '@prisma/client';
|
||||
|
||||
import { ChangePayload, Flatten, Payload } from './types';
|
||||
|
||||
interface EventDefinitions {
|
||||
user: {
|
||||
created: Payload<User>;
|
||||
updated: Payload<ChangePayload<User>>;
|
||||
deleted: Payload<User['id']>;
|
||||
};
|
||||
|
||||
workspace: {
|
||||
created: Payload<Workspace>;
|
||||
updated: Payload<ChangePayload<Workspace>>;
|
||||
deleted: Payload<Workspace['id']>;
|
||||
};
|
||||
|
||||
snapshot: {
|
||||
created: Payload<Snapshot>;
|
||||
updated: Payload<ChangePayload<Snapshot>>;
|
||||
deleted: Payload<Pick<Snapshot, 'id' | 'workspaceId'>>;
|
||||
};
|
||||
}
|
||||
|
||||
export type EventKV = Flatten<EventDefinitions>;
|
||||
|
||||
export type Event = keyof EventKV;
|
||||
export type EventPayload<E extends Event> = EventKV[E];
|
||||
44
packages/backend/server/src/event/index.ts
Normal file
44
packages/backend/server/src/event/index.ts
Normal file
@@ -0,0 +1,44 @@
|
||||
import { Global, Injectable, Module } from '@nestjs/common';
|
||||
import {
|
||||
EventEmitter2,
|
||||
EventEmitterModule,
|
||||
OnEvent as RawOnEvent,
|
||||
} from '@nestjs/event-emitter';
|
||||
|
||||
import { Event, EventPayload } from './events';
|
||||
|
||||
@Injectable()
|
||||
export class EventEmitter {
|
||||
constructor(private readonly emitter: EventEmitter2) {}
|
||||
|
||||
emit<E extends Event>(event: E, payload: EventPayload<E>) {
|
||||
return this.emitter.emit(event, payload);
|
||||
}
|
||||
|
||||
emitAsync<E extends Event>(event: E, payload: EventPayload<E>) {
|
||||
return this.emitter.emitAsync(event, payload);
|
||||
}
|
||||
|
||||
on<E extends Event>(event: E, handler: (payload: EventPayload<E>) => void) {
|
||||
return this.emitter.on(event, handler);
|
||||
}
|
||||
|
||||
once<E extends Event>(event: E, handler: (payload: EventPayload<E>) => void) {
|
||||
return this.emitter.once(event, handler);
|
||||
}
|
||||
}
|
||||
|
||||
export const OnEvent = (
|
||||
event: Event,
|
||||
opts?: Parameters<typeof RawOnEvent>[1]
|
||||
) => {
|
||||
return RawOnEvent(event, opts);
|
||||
};
|
||||
|
||||
@Global()
|
||||
@Module({
|
||||
imports: [EventEmitterModule.forRoot()],
|
||||
providers: [EventEmitter],
|
||||
exports: [EventEmitter],
|
||||
})
|
||||
export class EventModule {}
|
||||
38
packages/backend/server/src/event/types.ts
Normal file
38
packages/backend/server/src/event/types.ts
Normal file
@@ -0,0 +1,38 @@
|
||||
export type Payload<T> = {
|
||||
__payload: true;
|
||||
data: T;
|
||||
};
|
||||
|
||||
export type ChangePayload<T> = {
|
||||
from: Partial<T>;
|
||||
to: Partial<T>;
|
||||
};
|
||||
|
||||
export type Join<A extends string, B extends string> = A extends ''
|
||||
? B
|
||||
: `${A}.${B}`;
|
||||
|
||||
export type PathType<T, Path extends string> = string extends Path
|
||||
? unknown
|
||||
: Path extends keyof T
|
||||
? T[Path]
|
||||
: Path extends `${infer K}.${infer R}`
|
||||
? K extends keyof T
|
||||
? PathType<T[K], R>
|
||||
: unknown
|
||||
: unknown;
|
||||
|
||||
export type Leaves<T, P extends string = ''> = T extends Payload<any>
|
||||
? P
|
||||
: T extends Record<string, any>
|
||||
? {
|
||||
[K in keyof T]: K extends string ? Leaves<T[K], Join<P, K>> : never;
|
||||
}[keyof T]
|
||||
: never;
|
||||
|
||||
export type Flatten<T> = Leaves<T> extends infer R
|
||||
? {
|
||||
// @ts-expect-error yo, ts can't make it
|
||||
[K in R]: PathType<T, K> extends Payload<infer U> ? { data: U } : never;
|
||||
}
|
||||
: never;
|
||||
@@ -1,5 +1,4 @@
|
||||
import { DynamicModule, Type } from '@nestjs/common';
|
||||
import { EventEmitterModule } from '@nestjs/event-emitter';
|
||||
import { ScheduleModule } from '@nestjs/schedule';
|
||||
|
||||
import { GqlModule } from '../graphql.module';
|
||||
@@ -11,11 +10,7 @@ import { SyncModule } from './sync';
|
||||
import { UsersModule } from './users';
|
||||
import { WorkspaceModule } from './workspaces';
|
||||
|
||||
const BusinessModules: (Type | DynamicModule)[] = [
|
||||
EventEmitterModule.forRoot({
|
||||
global: true,
|
||||
}),
|
||||
];
|
||||
const BusinessModules: (Type | DynamicModule)[] = [];
|
||||
|
||||
switch (SERVER_FLAVOR) {
|
||||
case 'sync':
|
||||
|
||||
Reference in New Issue
Block a user