From 9d7c51644b66c9361e5436e2c43f463f4f219f90 Mon Sep 17 00:00:00 2001 From: tada5hi Date: Mon, 4 Nov 2024 09:52:22 +0100 Subject: [PATCH] feat: enhance typing for doamin entities --- .../src/core/entity-manager/module.ts | 48 +++---- .../src/core/entity-manager/type.ts | 11 +- .../src/core/entity-socket/module.ts | 87 ++++++------ .../client-vue/src/core/entity-socket/type.ts | 15 +- packages/client-vue/src/core/list/module.ts | 57 ++++---- packages/client-vue/src/core/list/type.ts | 21 ++- .../domains/analysis-bucket-file/entity.ts | 7 - .../src/domains/analysis-bucket/entity.ts | 7 - .../src/domains/analysis-log/entity.ts | 7 - .../src/domains/analysis-node/entity.ts | 12 -- .../src/domains/analysis-permission/entity.ts | 7 - .../core-kit/src/domains/analysis/entity.ts | 7 - .../domains/master-image-event-log/entity.ts | 7 - .../src/domains/master-image-group/entity.ts | 8 -- .../src/domains/master-image/entity.ts | 8 -- packages/core-kit/src/domains/node/entity.ts | 7 - .../src/domains/project-node/entity.ts | 7 - .../core-kit/src/domains/project/entity.ts | 7 - .../src/domains/registry-project/entity.ts | 7 - .../core-kit/src/domains/registry/entity.ts | 8 -- packages/core-kit/src/domains/types.ts | 132 +++++++----------- packages/core-kit/src/domains/utils.ts | 14 +- packages/core-realtime-kit/src/types.ts | 29 ++-- .../server-kit/src/domain-event/publish.ts | 4 +- .../src/domain-event/redis/publish.ts | 4 +- .../src/domain-event/socket/publish.ts | 9 +- 26 files changed, 199 insertions(+), 338 deletions(-) diff --git a/packages/client-vue/src/core/entity-manager/module.ts b/packages/client-vue/src/core/entity-manager/module.ts index 153258253..8b3df0a14 100644 --- a/packages/client-vue/src/core/entity-manager/module.ts +++ b/packages/client-vue/src/core/entity-manager/module.ts @@ -8,7 +8,7 @@ import { hasOwnProperty } from '@privateaim/kit'; import type { DomainAPI } from '@authup/core-http-kit'; import type { - DomainEntity, DomainEntityID, DomainType, + DomainEntityID, DomainTypeMap, } from '@privateaim/core-kit'; import type { BuildInput } from 'rapiq'; import { isObject } from 'smob'; @@ -26,22 +26,20 @@ import type { } from './type'; import { buildEntityManagerSlotProps } from './utils'; -type DomainTypeInfer = T extends DomainEntity ? U extends `${DomainType}` ? U : never : never; - export function createEntityManager< - A extends DomainTypeInfer>, - T = DomainEntity, + TYPE extends keyof DomainTypeMap, + RECORD extends DomainTypeMap[TYPE], >( - ctx: EntityManagerContext, -) : EntityManager { + ctx: EntityManagerContext, +) : EntityManager { const client = injectCoreHTTPClient(); - let domainAPI : DomainAPI | undefined; + let domainAPI : DomainAPI | undefined; if (hasOwnProperty(client, ctx.type)) { domainAPI = client[ctx.type] as any; } - const entity : Ref = ref(undefined); - const entityId = computed | undefined>( + const entity : Ref = ref(undefined); + const entityId = computed | undefined>( () => ( entity.value ? (entity.value as any).id : undefined), ); @@ -71,13 +69,13 @@ export function createEntityManager< }, ); - const lockId = ref(undefined) as Ref | undefined>; + const lockId = ref(undefined) as Ref | undefined>; if (ctx.props && ctx.props.entity) { entity.value = ctx.props.entity; } - const created = (value: T) => { + const created = (value: RECORD) => { if (ctx.setup && ctx.setup.emit) { ctx.setup.emit('created', value); } @@ -87,23 +85,23 @@ export function createEntityManager< } }; - const deleted = (value: T) => { + const deleted = (value: RECORD) => { if (ctx.setup && ctx.setup.emit) { - ctx.setup.emit('deleted', (value || entity.value) as T); + ctx.setup.emit('deleted', (value || entity.value) as RECORD); } if (ctx.onDeleted) { - ctx.onDeleted((value || entity.value) as T); + ctx.onDeleted((value || entity.value) as RECORD); } }; - const updated = (value: Partial) => { + const updated = (value: Partial) => { if (entity.value) { extendObjectProperties(entity.value, value); } if (ctx.setup && ctx.setup.emit) { - ctx.setup.emit('updated', (entity.value || value) as T); + ctx.setup.emit('updated', (entity.value || value) as RECORD); } if (ctx.onUpdated) { @@ -111,7 +109,7 @@ export function createEntityManager< } }; - const resolved = (value?: T) => { + const resolved = (value?: RECORD) => { if (ctx.setup && ctx.setup.emit) { ctx.setup.emit('resolved', value); } @@ -133,7 +131,7 @@ export function createEntityManager< const busy = ref(false); - const update = async (data: Partial) => { + const update = async (data: Partial) => { if (!domainAPI || busy.value || !entityId.value) { return; } @@ -186,7 +184,7 @@ export function createEntityManager< } }; - const create = async (data: Partial) : Promise => { + const create = async (data: Partial) : Promise => { if (!domainAPI || busy.value) { return; } @@ -211,7 +209,7 @@ export function createEntityManager< } }; - const createOrUpdate = async (data: Partial) : Promise => { + const createOrUpdate = async (data: Partial) : Promise => { if (entity.value) { await update(data); } else { @@ -227,7 +225,7 @@ export function createEntityManager< typeof ctx.socket === 'function' || ctx.socket ) { - let socketContext : EntitySocketContext = { + let socketContext : EntitySocketContext = { type: ctx.type, }; @@ -288,12 +286,12 @@ export function createEntityManager< resolveByProps(); - const resolve = async (resolveCtx: EntityManagerResolveContext = {}) => { + const resolve = async (resolveCtx: EntityManagerResolveContext = {}) => { if (entity.value && !resolveCtx.reset) { return; } - let query : (T extends Record ? BuildInput : never) | undefined; + let query : (RECORD extends Record ? BuildInput : never) | undefined; if (resolveCtx.query) { query = resolveCtx.query; } @@ -384,7 +382,7 @@ export function createEntityManager< } }; - const manager : EntityManager = { + const manager : EntityManager = { resolve, lockId, busy, diff --git a/packages/client-vue/src/core/entity-manager/type.ts b/packages/client-vue/src/core/entity-manager/type.ts index 9c6e4e214..94561863c 100644 --- a/packages/client-vue/src/core/entity-manager/type.ts +++ b/packages/client-vue/src/core/entity-manager/type.ts @@ -5,10 +5,6 @@ * view the LICENSE file that was distributed with this source code. */ -import type { - DomainEntity, - DomainType, -} from '@privateaim/core-kit'; import type { BuildInput, FieldsBuildInput, FiltersBuildInput } from 'rapiq'; import type { MaybeRef, Ref, SetupContext, SlotsType, @@ -77,10 +73,9 @@ export type EntityManagerEventsType = { resolved: (_item: T | undefined) => true }; -type SocketContext = Omit, 'type'>; export type EntityManagerContext< - A extends `${DomainType}`, - T = DomainEntity, + A extends string, + T extends Record, > = { type: A, setup?: Partial, SlotsType>>>, @@ -91,5 +86,5 @@ export type EntityManagerContext< onUpdated?(entity: Partial): any, onDeleted?(entity: T): any, onFailed?(e: Error): any, - socket?: SocketContext | boolean; + socket?: Omit, 'type'> | boolean; }; diff --git a/packages/client-vue/src/core/entity-socket/module.ts b/packages/client-vue/src/core/entity-socket/module.ts index a055e3aa7..909fe6509 100644 --- a/packages/client-vue/src/core/entity-socket/module.ts +++ b/packages/client-vue/src/core/entity-socket/module.ts @@ -6,6 +6,10 @@ */ import { DomainEventName, REALM_MASTER_NAME } from '@authup/core-kit'; +import type { + DomainEventSubscriptionFullName, + DomainTypeMap, +} from '@privateaim/core-kit'; import { DomainEventSubscriptionName, buildDomainChannelName, @@ -14,14 +18,8 @@ import { buildDomainNamespaceName, } from '@privateaim/core-kit'; import type { - DomainEntity, - DomainEventContext, - DomainEventSubscriptionFullName, - DomainInput, - DomainType, -} from '@privateaim/core-kit'; -import type { - STCEventContext, + STCEventHandler, + STCEventRecord, } from '@privateaim/core-realtime-kit'; import { computed, isRef, onMounted, onUnmounted, watch, @@ -30,13 +28,11 @@ import { storeToRefs, useStore } from '@authup/client-web-kit'; import type { EntitySocket, EntitySocketContext } from './type'; import { injectSocketManager, isSocketManagerUsable } from '../socket'; -type DT = T extends DomainEntity ? U extends `${DomainType}` ? U : never : never; - export function createEntitySocket< - A extends DT>, - T = DomainEntity, + TYPE extends keyof DomainTypeMap, + RECORD extends DomainTypeMap[TYPE], >( - ctx: EntitySocketContext, + ctx: EntitySocketContext, ) : EntitySocket { if (!isSocketManagerUsable()) { return { @@ -73,7 +69,7 @@ export function createEntitySocket< const lockId = computed(() => (isRef(ctx.lockId) ? ctx.lockId.value : ctx.lockId)); - const processEvent = (event: STCEventContext>) : boolean => { + const processEvent = (event: STCEventRecord) : boolean => { if ( ctx.processEvent && !ctx.processEvent(event, realmId.value) @@ -96,32 +92,38 @@ export function createEntitySocket< return event.data.id !== lockId.value; }; - const handleCreated = (event: STCEventContext>) => { + const handleCreated : STCEventHandler = ( + event, + ) => { if (!processEvent(event)) { return; } if (ctx.onCreated) { - ctx.onCreated(event.data as T); + ctx.onCreated(event.data as RECORD); } }; - const handleUpdated = (event: STCEventContext>) => { + const handleUpdated : STCEventHandler = ( + event, + ) => { if (!processEvent(event)) { return; } if (ctx.onUpdated) { - ctx.onUpdated(event.data as T); + ctx.onUpdated(event.data as RECORD); } }; - const handleDeleted = (event: STCEventContext>) => { + const handleDeleted : STCEventHandler = ( + event, + ) => { if (!processEvent(event)) { return; } if (ctx.onDeleted) { - ctx.onDeleted(event.data as T); + ctx.onDeleted(event.data as RECORD); } }; @@ -135,41 +137,41 @@ export function createEntitySocket< const socket = await socketManager.connect(buildDomainNamespaceName(realmId.value)); - let event : DomainEventSubscriptionFullName | undefined; + let event : DomainEventSubscriptionFullName | undefined; if (ctx.buildSubscribeEventName) { event = ctx.buildSubscribeEventName(); } else { event = buildDomainEventSubscriptionFullName( - ctx.type as DomainInput, + ctx.type, DomainEventSubscriptionName.SUBSCRIBE, ); } - socket.emit( + socket.emit( event, - targetId.value, + targetId.value as EventTarget, () => { // todo: handle error! }, ); if (ctx.onCreated) { - socket.on(buildDomainEventFullName( - ctx.type as DomainInput, + socket.on(buildDomainEventFullName( + ctx.type, DomainEventName.CREATED, ), handleCreated); } if (ctx.onUpdated) { - socket.on(buildDomainEventFullName( - ctx.type as DomainInput, + socket.on(buildDomainEventFullName( + ctx.type, DomainEventName.UPDATED, ), handleUpdated); } if (ctx.onDeleted) { - socket.on(buildDomainEventFullName( - ctx.type as DomainInput, + socket.on(buildDomainEventFullName( + ctx.type, DomainEventName.DELETED, ), handleDeleted); } @@ -184,38 +186,38 @@ export function createEntitySocket< const socket = await socketManager.connect(buildDomainNamespaceName(realmId.value)); - let event : DomainEventSubscriptionFullName | undefined; + let event : DomainEventSubscriptionFullName; if (ctx.buildUnsubscribeEventName) { event = ctx.buildUnsubscribeEventName(); } else { event = buildDomainEventSubscriptionFullName( - ctx.type as DomainInput, + ctx.type, DomainEventSubscriptionName.SUBSCRIBE, ); } - socket.emit( + socket.emit( event, - targetId.value, + targetId.value as EventTarget, ); if (ctx.onCreated) { - socket.off(buildDomainEventFullName( - ctx.type as DomainInput, + socket.off(buildDomainEventFullName( + ctx.type, DomainEventName.UPDATED, ), handleCreated); } if (ctx.onUpdated) { - socket.off(buildDomainEventFullName( - ctx.type as DomainInput, + socket.off(buildDomainEventFullName( + ctx.type, DomainEventName.UPDATED, ), handleUpdated); } if (ctx.onDeleted) { - socket.off(buildDomainEventFullName( - ctx.type as DomainInput, + socket.off(buildDomainEventFullName( + ctx.type, DomainEventName.DELETED, ), handleDeleted); } @@ -226,8 +228,9 @@ export function createEntitySocket< watch(targetId, (val, oldValue) => { if (val !== oldValue) { - unmount(); - mount(); + Promise.resolve() + .then(() => unmount()) + .then(() => mount()); } }); diff --git a/packages/client-vue/src/core/entity-socket/type.ts b/packages/client-vue/src/core/entity-socket/type.ts index fef1dadda..bffef870a 100644 --- a/packages/client-vue/src/core/entity-socket/type.ts +++ b/packages/client-vue/src/core/entity-socket/type.ts @@ -6,20 +6,17 @@ */ import type { - DomainEntity, DomainEntityID, - DomainEventContext, DomainEventSubscriptionFullName, - DomainType, } from '@privateaim/core-kit'; import type { - STCEventContext, + STCEventRecord, } from '@privateaim/core-realtime-kit'; import type { MaybeRef } from 'vue'; export type EntitySocketContext< - A extends `${DomainType}`, - T = DomainEntity, + A extends string, + T extends Record, > = { type: A, realmId?: MaybeRef, @@ -29,10 +26,10 @@ export type EntitySocketContext< onCreated?(entity: T): any, onUpdated?(entity: Partial): any, onDeleted?(entity: T): any, - processEvent?(event: STCEventContext>, realmId?: string) : boolean; + processEvent?(event: STCEventRecord, realmId?: string) : boolean; buildChannelName?(entityId?: DomainEntityID) : string; - buildSubscribeEventName?(): DomainEventSubscriptionFullName; - buildUnsubscribeEventName?(): DomainEventSubscriptionFullName; + buildSubscribeEventName?(): DomainEventSubscriptionFullName; + buildUnsubscribeEventName?(): DomainEventSubscriptionFullName; }; export type EntitySocket = { diff --git a/packages/client-vue/src/core/list/module.ts b/packages/client-vue/src/core/list/module.ts index e6a39b299..ee7166282 100644 --- a/packages/client-vue/src/core/list/module.ts +++ b/packages/client-vue/src/core/list/module.ts @@ -7,7 +7,7 @@ import { hasOwnProperty } from '@privateaim/kit'; import type { DomainAPI } from '@authup/core-http-kit'; -import type { DomainEntity, DomainType } from '@privateaim/core-kit'; +import type { DomainTypeMap } from '@privateaim/core-kit'; import type { ListFooterBuildOptionsInput, ListHeaderBuildOptionsInput, } from '@vuecs/list-controls'; @@ -40,7 +40,6 @@ import { } from './utils'; type Entity = T extends Record ? T : never; -type DomainTypeInfer = T extends DomainEntity ? U extends `${DomainType}` ? U : never : never; const merger = createMerger({ array: false, @@ -49,19 +48,19 @@ const merger = createMerger({ }); export function createList< - A extends DomainTypeInfer>, - T = DomainEntity, + TYPE extends keyof DomainTypeMap, + RECORD extends DomainTypeMap[TYPE], >( - context: ListCreateContext, -) : List { - const data : Ref = ref([]); + context: ListCreateContext, +) : List { + const data : Ref = ref([]); const busy = ref(false); const total = ref(0); const meta = ref({ pagination: { limit: 10, }, - }) as Ref>; + }) as Ref>; const realmId = computed( () => { @@ -79,21 +78,21 @@ export function createList< const client = injectCoreHTTPClient(); - let domainAPI : DomainAPI> | undefined; + let domainAPI : DomainAPI> | undefined; if (hasOwnProperty(client, context.type)) { domainAPI = client[context.type] as any; } - let query : BuildInput> | undefined; + let query : BuildInput> | undefined; - async function load(input: ListMeta = {}) { + async function load(input: ListMeta = {}) { if (!domainAPI || busy.value) return; busy.value = true; meta.value.busy = true; try { - let filters : FiltersBuildInput> | undefined; + let filters : FiltersBuildInput> | undefined; if ( context.queryFilters && input.filters && @@ -101,7 +100,7 @@ export function createList< typeof input.filters.name === 'string' ) { // todo: queryFilters should customize full filters object! - filters = context.queryFilters(input.filters.name) as FiltersBuildInput>; + filters = context.queryFilters(input.filters.name) as FiltersBuildInput>; } query = undefined; @@ -121,7 +120,7 @@ export function createList< } } - const nextQuery : ListMeta = merger( + const nextQuery : ListMeta = merger( (filters ? { filters } : {}), input || {}, { @@ -134,15 +133,15 @@ export function createList< ); const response = await domainAPI.getMany( - nextQuery as BuildInput>, + nextQuery as BuildInput>, ); meta.value = nextQuery; if (context.loadAll) { - data.value.push(...response.data as T[]); + data.value.push(...response.data as RECORD[]); } else { - data.value = response.data as T[]; + data.value = response.data as RECORD[]; } total.value = response.meta.total; @@ -195,15 +194,15 @@ export function createList< }); const handleUpdated = buildListUpdatedHandler(data); - let options : ListRenderOptions = context.props; + let options : ListRenderOptions = context.props; - const setDefaults = (defaults: ListRenderOptions) => { + const setDefaults = (defaults: ListRenderOptions) => { options = mergeListOptions(context.props, defaults); }; function render() : VNodeChild { - const header : ListHeaderBuildOptionsInput = boolableToObject(options.header || {}); - const footer : ListFooterBuildOptionsInput = boolableToObject(options.footer || {}); + const header : ListHeaderBuildOptionsInput = boolableToObject(options.header || {}); + const footer : ListFooterBuildOptionsInput = boolableToObject(options.footer || {}); if (options.item) { if ( @@ -216,7 +215,7 @@ export function createList< } } - return buildList>({ + return buildList>({ footer, header, noMore: options.noMore, @@ -225,18 +224,18 @@ export function createList< total: total.value, load, busy: busy.value, - data: data.value as Entity[], + data: data.value as Entity[], meta: { ...meta.value, total: total.value, }, - onCreated(value: T) { + onCreated(value: RECORD) { handleCreated(value); }, - onDeleted(value: T) { + onDeleted(value: RECORD) { handleDeleted(value); }, - onUpdated: (value: T) => { + onUpdated: (value: RECORD) => { handleUpdated(value); }, slotItems: context.setup.slots || {}, @@ -268,7 +267,7 @@ export function createList< typeof context.socket === 'undefined' || context.socket ) { - const socketContext : EntitySocketContext = { + const socketContext : EntitySocketContext = { type: context.type, ...(isObject(context.socket) ? context.socket : {}), }; @@ -294,10 +293,10 @@ export function createList< handleCreated(entity); } }; - socketContext.onDeleted = (entity: T) => { + socketContext.onDeleted = (entity: RECORD) => { handleDeleted(entity); }; - socketContext.onUpdated = (entity: T) => { + socketContext.onUpdated = (entity: RECORD) => { handleDeleted(entity); }; socketContext.realmId = realmId; diff --git a/packages/client-vue/src/core/list/type.ts b/packages/client-vue/src/core/list/type.ts index 9aac41a55..058c8ea79 100644 --- a/packages/client-vue/src/core/list/type.ts +++ b/packages/client-vue/src/core/list/type.ts @@ -5,7 +5,6 @@ * view the LICENSE file that was distributed with this source code. */ -import type { DomainEntity, DomainType } from '@privateaim/core-kit'; import type { ListBodyBuildOptionsInput, ListBodySlotProps, @@ -112,17 +111,17 @@ export type ListEventsType = { }; export type ListCreateContext< - A extends `${DomainType}`, - T = DomainEntity, + TYPE extends string, + RECORD extends Record, > = { - type: A, + type: TYPE, realmId?: MaybeRef, - setup: SetupContext>, - props: ListProps, + setup: SetupContext>, + props: ListProps, loadAll?: boolean, - query?: BuildInput> | (() => BuildInput>), - queryFilters?: ((q: string) => FiltersBuildInput>), - onCreated?: (entity: T, meta: ListMeta) => void | Promise, - onLoaded?: (meta: ListMeta) => void | Promise, - socket?: boolean | Omit, 'type'> + query?: BuildInput> | (() => BuildInput>), + queryFilters?: ((q: string) => FiltersBuildInput>), + onCreated?: (entity: RECORD, meta: ListMeta) => void | Promise, + onLoaded?: (meta: ListMeta) => void | Promise, + socket?: boolean | Omit, 'type'> }; diff --git a/packages/core-kit/src/domains/analysis-bucket-file/entity.ts b/packages/core-kit/src/domains/analysis-bucket-file/entity.ts index e4e22bdc6..83fc0bddb 100644 --- a/packages/core-kit/src/domains/analysis-bucket-file/entity.ts +++ b/packages/core-kit/src/domains/analysis-bucket-file/entity.ts @@ -7,9 +7,7 @@ import type { Realm, Robot, User } from '@authup/core-kit'; import type { AnalysisBucket } from '../analysis-bucket'; -import type { DomainType } from '../constants'; import type { Analysis } from '../analysis'; -import type { DomainEventBaseContext } from '../types-base'; export interface AnalysisBucketFile { id: string; @@ -48,8 +46,3 @@ export interface AnalysisBucketFile { robot_id: Robot['id'] | null; } - -export type AnalysisFileEventContext = DomainEventBaseContext & { - type: `${DomainType.ANALYSIS_BUCKET_FILE}`, - data: AnalysisBucketFile -}; diff --git a/packages/core-kit/src/domains/analysis-bucket/entity.ts b/packages/core-kit/src/domains/analysis-bucket/entity.ts index de931176b..ad7b09083 100644 --- a/packages/core-kit/src/domains/analysis-bucket/entity.ts +++ b/packages/core-kit/src/domains/analysis-bucket/entity.ts @@ -7,8 +7,6 @@ import type { Realm } from '@authup/core-kit'; import type { Analysis } from '../analysis'; -import type { DomainType } from '../constants'; -import type { DomainEventBaseContext } from '../types-base'; import type { AnalysisBucketType } from './constants'; export interface AnalysisBucket { @@ -34,8 +32,3 @@ export interface AnalysisBucket { realm_id: Realm['id']; } - -export type AnalysisBucketEventContext = DomainEventBaseContext & { - type: `${DomainType.ANALYSIS_BUCKET}`, - data: AnalysisBucket -}; diff --git a/packages/core-kit/src/domains/analysis-log/entity.ts b/packages/core-kit/src/domains/analysis-log/entity.ts index 3582d6211..24aa046de 100644 --- a/packages/core-kit/src/domains/analysis-log/entity.ts +++ b/packages/core-kit/src/domains/analysis-log/entity.ts @@ -6,11 +6,9 @@ */ import type { Realm } from '@authup/core-kit'; -import type { DomainType } from '../constants'; import type { Analysis, } from '../analysis'; -import type { DomainEventBaseContext } from '../types-base'; export interface AnalysisLog { id: string; @@ -71,8 +69,3 @@ export interface AnalysisLog { realm_id: Realm['id']; } - -export type AnalysisLogEventContext = DomainEventBaseContext & { - type: `${DomainType.ANALYSIS_LOG}`, - data: AnalysisLog -}; diff --git a/packages/core-kit/src/domains/analysis-node/entity.ts b/packages/core-kit/src/domains/analysis-node/entity.ts index a8ef89fed..1eb932ad3 100644 --- a/packages/core-kit/src/domains/analysis-node/entity.ts +++ b/packages/core-kit/src/domains/analysis-node/entity.ts @@ -6,10 +6,8 @@ */ import type { Realm } from '@authup/core-kit'; -import type { DomainType } from '../constants'; import type { Node } from '../node'; import type { Analysis } from '../analysis'; -import type { DomainEventBaseContext } from '../types-base'; import type { AnalysisNodeApprovalStatus, AnalysisNodeRunStatus } from './constants'; export interface AnalysisNode { @@ -53,13 +51,3 @@ export interface AnalysisNode { node_realm_id: Realm['id']; } - -export type TrainStationEventContext = DomainEventBaseContext & { - type: `${DomainType.ANALYSIS_NODE}`, - data: AnalysisNode -}; - -export type AnalyseNodeSocketEventData = Record; -export type AnalyseNodeSocketCTSEvents = { - analysisNodes: (id: Analysis['id'], cb?: (err: null | Error, data: AnalyseNodeSocketEventData) => void) => void -}; diff --git a/packages/core-kit/src/domains/analysis-permission/entity.ts b/packages/core-kit/src/domains/analysis-permission/entity.ts index cdec77224..4c920260b 100644 --- a/packages/core-kit/src/domains/analysis-permission/entity.ts +++ b/packages/core-kit/src/domains/analysis-permission/entity.ts @@ -7,8 +7,6 @@ import type { PermissionRelation, Realm } from '@authup/core-kit'; import type { Analysis } from '../analysis'; -import type { DomainType } from '../constants'; -import type { DomainEventBaseContext } from '../types-base'; export interface AnalysisPermission extends PermissionRelation { id: string; @@ -31,8 +29,3 @@ export interface AnalysisPermission extends PermissionRelation { updated_at: Date | string; } - -export type AnalysisPermissionEventContext = DomainEventBaseContext & { - type: `${DomainType.ANALYSIS_PERMISSION}`, - data: AnalysisPermission -}; diff --git a/packages/core-kit/src/domains/analysis/entity.ts b/packages/core-kit/src/domains/analysis/entity.ts index 9cf061ae6..bf851cc49 100644 --- a/packages/core-kit/src/domains/analysis/entity.ts +++ b/packages/core-kit/src/domains/analysis/entity.ts @@ -6,10 +6,8 @@ */ import type { Realm, User } from '@authup/core-kit'; -import type { DomainType } from '../constants'; import type { MasterImage } from '../master-image'; import type { Project } from '../project'; -import type { DomainEventBaseContext } from '../types-base'; import type { AnalysisBuildStatus, AnalysisRunStatus, @@ -67,8 +65,3 @@ export interface Analysis { master_image: MasterImage; } - -export type AnalysisEventContext = DomainEventBaseContext & { - type: `${DomainType.ANALYSIS}`, - data: Analysis -}; diff --git a/packages/core-kit/src/domains/master-image-event-log/entity.ts b/packages/core-kit/src/domains/master-image-event-log/entity.ts index c7f6fa4f1..0f8469845 100644 --- a/packages/core-kit/src/domains/master-image-event-log/entity.ts +++ b/packages/core-kit/src/domains/master-image-event-log/entity.ts @@ -5,9 +5,7 @@ * view the LICENSE file that was distributed with this source code. */ -import type { DomainType } from '../constants'; import type { MasterImage } from '../master-image'; -import type { DomainEventBaseContext } from '../types-base'; export interface MasterImageEventLog { id: string; @@ -34,8 +32,3 @@ export interface MasterImageEventLog { updated_at: Date; } - -export type MasterImageEventLogEventContext = DomainEventBaseContext & { - type: `${DomainType.MASTER_IMAGE_EVENT_LOG}`, - data: MasterImageEventLog -}; diff --git a/packages/core-kit/src/domains/master-image-group/entity.ts b/packages/core-kit/src/domains/master-image-group/entity.ts index 50f3f75ed..20903139d 100644 --- a/packages/core-kit/src/domains/master-image-group/entity.ts +++ b/packages/core-kit/src/domains/master-image-group/entity.ts @@ -5,9 +5,6 @@ * view the LICENSE file that was distributed with this source code. */ -import type { DomainType } from '../constants'; -import type { DomainEventBaseContext } from '../types-base'; - export interface MasterImageGroup { id: string; @@ -27,8 +24,3 @@ export interface MasterImageGroup { updated_at: Date; } - -export type MasterImageGroupEventContext = DomainEventBaseContext & { - type: `${DomainType.MASTER_IMAGE_GROUP}`, - data: MasterImageGroup -}; diff --git a/packages/core-kit/src/domains/master-image/entity.ts b/packages/core-kit/src/domains/master-image/entity.ts index 31c7823bc..6833a8570 100644 --- a/packages/core-kit/src/domains/master-image/entity.ts +++ b/packages/core-kit/src/domains/master-image/entity.ts @@ -5,9 +5,6 @@ * view the LICENSE file that was distributed with this source code. */ -import type { DomainType } from '../constants'; -import type { DomainEventBaseContext } from '../types-base'; - export interface MasterImage { id: string; @@ -29,8 +26,3 @@ export interface MasterImage { updated_at: Date; } - -export type MasterImageEventContext = DomainEventBaseContext & { - type: `${DomainType.MASTER_IMAGE}`, - data: MasterImage -}; diff --git a/packages/core-kit/src/domains/node/entity.ts b/packages/core-kit/src/domains/node/entity.ts index 230e8215b..dd969684b 100644 --- a/packages/core-kit/src/domains/node/entity.ts +++ b/packages/core-kit/src/domains/node/entity.ts @@ -6,10 +6,8 @@ */ import type { Realm, Robot } from '@authup/core-kit'; -import type { DomainType } from '../constants'; import type { RegistryProject } from '../registry-project'; import type { Registry } from '../registry'; -import type { DomainEventBaseContext } from '../types-base'; import type { NodeType } from './constants'; export interface Node { @@ -49,8 +47,3 @@ export interface Node { updated_at: Date; } - -export type NodeEventContext = DomainEventBaseContext & { - type: `${DomainType.NODE}`, - data: Node -}; diff --git a/packages/core-kit/src/domains/project-node/entity.ts b/packages/core-kit/src/domains/project-node/entity.ts index 271ec62f7..f9ebc9de9 100644 --- a/packages/core-kit/src/domains/project-node/entity.ts +++ b/packages/core-kit/src/domains/project-node/entity.ts @@ -6,10 +6,8 @@ */ import type { Realm } from '@authup/core-kit'; -import type { DomainType } from '../constants'; import type { Project } from '../project'; import type { Node } from '../node'; -import type { DomainEventBaseContext } from '../types-base'; import type { ProjectNodeApprovalStatus } from './constants'; export interface ProjectNode { @@ -39,8 +37,3 @@ export interface ProjectNode { node_realm_id: Realm['id']; } - -export type ProjectNodeEventContext = DomainEventBaseContext & { - type: `${DomainType.PROJECT_NODE}`, - data: ProjectNode -}; diff --git a/packages/core-kit/src/domains/project/entity.ts b/packages/core-kit/src/domains/project/entity.ts index a755871a5..944ada1b7 100644 --- a/packages/core-kit/src/domains/project/entity.ts +++ b/packages/core-kit/src/domains/project/entity.ts @@ -6,9 +6,7 @@ */ import type { Realm, Robot, User } from '@authup/core-kit'; -import type { DomainType } from '../constants'; import type { MasterImage } from '../master-image'; -import type { DomainEventBaseContext } from '../types-base'; export interface Project { id: string; @@ -41,8 +39,3 @@ export interface Project { master_image: MasterImage | null; } - -export type ProjectEventContext = DomainEventBaseContext & { - type: `${DomainType.PROJECT}`, - data: Project -}; diff --git a/packages/core-kit/src/domains/registry-project/entity.ts b/packages/core-kit/src/domains/registry-project/entity.ts index 0a9572b84..d0206cbf6 100644 --- a/packages/core-kit/src/domains/registry-project/entity.ts +++ b/packages/core-kit/src/domains/registry-project/entity.ts @@ -6,9 +6,7 @@ */ import type { Realm } from '@authup/core-kit'; -import type { DomainType } from '../constants'; import type { Registry } from '../registry'; -import type { DomainEventBaseContext } from '../types-base'; import type { RegistryProjectType } from './constants'; export interface RegistryProject { @@ -57,8 +55,3 @@ export interface RegistryProject { updated_at: Date; } - -export type RegistryProjectEventContext = DomainEventBaseContext & { - type: `${DomainType.REGISTRY_PROJECT}`, - data: RegistryProject -}; diff --git a/packages/core-kit/src/domains/registry/entity.ts b/packages/core-kit/src/domains/registry/entity.ts index 848c75785..a964b4aa4 100644 --- a/packages/core-kit/src/domains/registry/entity.ts +++ b/packages/core-kit/src/domains/registry/entity.ts @@ -5,9 +5,6 @@ * view the LICENSE file that was distributed with this source code. */ -import type { DomainType } from '../constants'; -import type { DomainEventBaseContext } from '../types-base'; - export interface Registry { id: string; @@ -27,8 +24,3 @@ export interface Registry { updated_at: Date; } - -export type RegistryEventContext = DomainEventBaseContext & { - type: `${DomainType.REGISTRY}`, - data: Registry -}; diff --git a/packages/core-kit/src/domains/types.ts b/packages/core-kit/src/domains/types.ts index e9ba732db..d8a54d902 100644 --- a/packages/core-kit/src/domains/types.ts +++ b/packages/core-kit/src/domains/types.ts @@ -5,100 +5,64 @@ * view the LICENSE file that was distributed with this source code. */ -import type { AnalysisBucket, AnalysisBucketEventContext } from './analysis-bucket'; +import type { AnalysisBucket } from './analysis-bucket'; import type { DomainEventName, DomainEventSubscriptionName, DomainSubType, DomainType, } from './constants'; -import type { MasterImage, MasterImageEventContext } from './master-image'; -import type { MasterImageEventLog, MasterImageEventLogEventContext } from './master-image-event-log'; -import type { MasterImageGroup, MasterImageGroupEventContext } from './master-image-group'; -import type { Project, ProjectEventContext } from './project'; -import type { ProjectNode, ProjectNodeEventContext } from './project-node'; -import type { Registry, RegistryEventContext } from './registry'; -import type { RegistryProject, RegistryProjectEventContext } from './registry-project'; -import type { Node, NodeEventContext } from './node'; -import type { Analysis, AnalysisEventContext } from './analysis'; -import type { AnalysisBucketFile, AnalysisFileEventContext } from './analysis-bucket-file'; -import type { AnalysisLog, AnalysisLogEventContext } from './analysis-log'; -import type { AnalysisNode, TrainStationEventContext } from './analysis-node'; +import type { MasterImage } from './master-image'; +import type { MasterImageEventLog } from './master-image-event-log'; +import type { MasterImageGroup } from './master-image-group'; +import type { Project } from './project'; +import type { ProjectNode } from './project-node'; +import type { Registry } from './registry'; +import type { RegistryProject } from './registry-project'; +import type { Node } from './node'; +import type { Analysis } from './analysis'; +import type { AnalysisBucketFile } from './analysis-bucket-file'; +import type { AnalysisLog } from './analysis-log'; +import type { AnalysisNode } from './analysis-node'; -export type DomainsEventContext = MasterImageEventContext | -MasterImageEventLogEventContext | -MasterImageGroupEventContext | -ProjectEventContext | -ProjectNodeEventContext | -RegistryEventContext | -RegistryProjectEventContext | -NodeEventContext | -AnalysisEventContext | -AnalysisLogEventContext | -AnalysisFileEventContext | -TrainStationEventContext; +type DomainTypeMapRaw = { + [DomainType.MASTER_IMAGE]: MasterImage, + [DomainType.MASTER_IMAGE_EVENT_LOG]: MasterImageEventLog, + [DomainType.MASTER_IMAGE_GROUP]: MasterImageGroup, + [DomainType.PROJECT]: Project, + [DomainType.PROJECT_NODE]: ProjectNode, + [DomainSubType.PROJECT_NODE_IN]: ProjectNode, + [DomainSubType.PROJECT_NODE_OUT]: ProjectNode, + [DomainType.REGISTRY]: Registry, + [DomainType.REGISTRY_PROJECT]: RegistryProject + [DomainType.NODE]: Node, + [DomainType.ANALYSIS]: Analysis, + [DomainType.ANALYSIS_BUCKET]: AnalysisBucket, + [DomainType.ANALYSIS_BUCKET_FILE]: AnalysisBucketFile, + [DomainType.ANALYSIS_LOG]: AnalysisLog, + [DomainType.ANALYSIS_NODE]: AnalysisNode, + [DomainSubType.ANALYSIS_NODE_IN]: AnalysisNode, + [DomainSubType.ANALYSIS_NODE_OUT]: AnalysisNode, +}; -export type DomainEventContext = - T extends `${DomainType.MASTER_IMAGE}` ? - MasterImageEventContext : - T extends `${DomainType.MASTER_IMAGE_GROUP}` ? - MasterImageGroupEventContext : - T extends `${DomainType.MASTER_IMAGE_EVENT_LOG}` ? - MasterImageEventLogEventContext : - T extends `${DomainType.PROJECT}` ? - ProjectEventContext : - T extends `${DomainType.PROJECT_NODE}` | `${DomainSubType.PROJECT_NODE_IN}` | `${DomainSubType.PROJECT_NODE_OUT}` ? - ProjectNodeEventContext : - T extends `${DomainType.REGISTRY}` ? - RegistryEventContext : - T extends `${DomainType.REGISTRY_PROJECT}` ? - RegistryProjectEventContext : - T extends `${DomainType.NODE}` ? - NodeEventContext : - T extends `${DomainType.ANALYSIS}` ? - AnalysisEventContext : - T extends `${DomainType.ANALYSIS_BUCKET}` ? - AnalysisBucketEventContext : - T extends `${DomainType.ANALYSIS_LOG}` ? - AnalysisLogEventContext : - T extends `${DomainType.ANALYSIS_BUCKET_FILE}` ? - AnalysisFileEventContext : - T extends `${DomainType.ANALYSIS_NODE}` | `${DomainSubType.ANALYSIS_NODE_IN}` | `${DomainSubType.ANALYSIS_NODE_OUT}` ? - TrainStationEventContext : - never; +export type DomainTypeMap = { + [K in keyof DomainTypeMapRaw as `${K}`]: DomainTypeMapRaw[K] +}; -export type DomainEntity = - T extends `${DomainType.MASTER_IMAGE}` ? - MasterImage : - T extends `${DomainType.MASTER_IMAGE_EVENT_LOG}` ? - MasterImageEventLog : - T extends `${DomainType.MASTER_IMAGE_GROUP}` ? - MasterImageGroup : - T extends `${DomainType.PROJECT}` ? - Project : - T extends `${DomainType.PROJECT_NODE}` | `${DomainSubType.PROJECT_NODE_IN}` | `${DomainSubType.PROJECT_NODE_OUT}` ? - ProjectNode : - T extends `${DomainType.REGISTRY}` ? - Registry : - T extends `${DomainType.REGISTRY_PROJECT}` ? - RegistryProject : - T extends `${DomainType.NODE}` ? - Node : - T extends `${DomainType.ANALYSIS}` ? - Analysis : - T extends `${DomainType.ANALYSIS_BUCKET}` ? - AnalysisBucket : - T extends `${DomainType.ANALYSIS_LOG}` ? - AnalysisLog : - T extends `${DomainType.ANALYSIS_BUCKET_FILE}` ? - AnalysisBucketFile : - T extends `${DomainType.ANALYSIS_NODE}` | `${DomainSubType.ANALYSIS_NODE_IN}` | `${DomainSubType.ANALYSIS_NODE_OUT}` ? - AnalysisNode : - never; +export type EventRecord< + T extends string, + D extends Record, +> = { + type: T, + data: D, + event: `${DomainEventName}`, +}; -export type DomainInput = `${DomainType}` | DomainType | `${DomainSubType}` | DomainSubType; +export type DomainsEvents = { + [T in keyof DomainTypeMap]: EventRecord +}[keyof DomainTypeMap]; export type DomainEventFullName< - T extends DomainInput = DomainInput, + T extends string, > = `${T}${Capitalize<`${DomainEventName}`>}`; export type DomainEventSubscriptionFullName< - T extends DomainInput = DomainInput, + T extends string, > = `${T}${Capitalize<`${DomainEventSubscriptionName}`>}`; diff --git a/packages/core-kit/src/domains/utils.ts b/packages/core-kit/src/domains/utils.ts index 91ddb57d3..57ac871d3 100644 --- a/packages/core-kit/src/domains/utils.ts +++ b/packages/core-kit/src/domains/utils.ts @@ -8,11 +8,13 @@ import type { DomainEventName, DomainEventSubscriptionName, } from './constants'; -import type { DomainEventFullName, DomainEventSubscriptionFullName, DomainInput } from './types'; +import type { + DomainEventFullName, DomainEventSubscriptionFullName, +} from './types'; -export function buildDomainEventFullName( +export function buildDomainEventFullName( type: T, - event: `${DomainEventName}` | DomainEventName, + event: `${DomainEventName}`, ) : DomainEventFullName { const eventCapitalized = event.substring(0, 1).toUpperCase() + event.substring(1); @@ -20,17 +22,17 @@ export function buildDomainEventFullName( } export function buildDomainEventSubscriptionFullName< - T extends DomainInput, + T extends string, >( type: T, - event: `${DomainEventSubscriptionName}` | DomainEventSubscriptionName, + event: `${DomainEventSubscriptionName}`, ) : DomainEventSubscriptionFullName { const eventCapitalized = event.substring(0, 1).toUpperCase() + event.substring(1); return type + eventCapitalized as DomainEventSubscriptionFullName; } -export function buildDomainChannelName(type: DomainInput, id?: string | number) { +export function buildDomainChannelName(type: string, id?: string | number) { return `${type}${id ? `:${id}` : ''}`; } diff --git a/packages/core-realtime-kit/src/types.ts b/packages/core-realtime-kit/src/types.ts index f00874bb5..d6edaf34e 100644 --- a/packages/core-realtime-kit/src/types.ts +++ b/packages/core-realtime-kit/src/types.ts @@ -6,14 +6,16 @@ */ import type { - DomainEventContext, DomainEventFullName, DomainEventSubscriptionFullName, - DomainSubType, - DomainType, + DomainTypeMap, + EventRecord, } from '@privateaim/core-kit'; -export type STCEventContext> = T & { +export type STCEventRecord< + TYPE extends string, + RECORD extends Record, +> = EventRecord & { meta: { roomName?: string, roomId?: string | number @@ -30,15 +32,20 @@ export type STSEvents = { [event: string]: (...args: any[]) => void; }; +export type STCEventHandler< + TYPE extends string, + RECORD extends Record, +> = ( + data: STCEventRecord +) => void; export type STCEvents = { - [K in `${DomainType}` | `${DomainSubType}` as DomainEventFullName]: ( - data: STCEventContext> - ) => void + [K in keyof DomainTypeMap as DomainEventFullName]: STCEventHandler }; +export type CTSEventHandler = ( + target: EventTarget, + cb: EventCallback +) => void; export type CTSEvents = { - [K in DomainEventSubscriptionFullName<`${DomainType}` | `${DomainSubType}`>]: ( - target?: EventTarget, - cb?: EventCallback - ) => void + [K in keyof DomainTypeMap as DomainEventSubscriptionFullName]: CTSEventHandler }; diff --git a/packages/server-kit/src/domain-event/publish.ts b/packages/server-kit/src/domain-event/publish.ts index f11ca0bfb..f8cbbaea2 100644 --- a/packages/server-kit/src/domain-event/publish.ts +++ b/packages/server-kit/src/domain-event/publish.ts @@ -5,7 +5,7 @@ * view the LICENSE file that was distributed with this source code. */ -import type { DomainsEventContext } from '@privateaim/core-kit'; +import type { DomainsEvents } from '@privateaim/core-kit'; import type { Client } from 'redis-extension'; import { publishDomainRedisEvent } from './redis'; import { publishDomainSocketEvent } from './socket'; @@ -13,7 +13,7 @@ import type { DomainEventDestinations } from './type'; export async function publishDomainEvent( client: Client, - context: DomainsEventContext, + context: DomainsEvents, destinations: DomainEventDestinations, ) { await publishDomainRedisEvent(client, context, destinations); diff --git a/packages/server-kit/src/domain-event/redis/publish.ts b/packages/server-kit/src/domain-event/redis/publish.ts index 3b68706fa..f982dedf9 100644 --- a/packages/server-kit/src/domain-event/redis/publish.ts +++ b/packages/server-kit/src/domain-event/redis/publish.ts @@ -6,14 +6,14 @@ */ import { DomainEventName } from '@privateaim/core-kit'; -import type { DomainsEventContext } from '@privateaim/core-kit'; +import type { DomainsEvents } from '@privateaim/core-kit'; import type { Client } from 'redis-extension'; import type { DomainEventDestinations } from '../type'; import { buildDomainEventChannelName, transformDomainEventData } from '../utils'; export async function publishDomainRedisEvent( client: Client, - context: DomainsEventContext, + context: DomainsEvents, destinations: DomainEventDestinations, ) : Promise { context = transformDomainEventData(context); diff --git a/packages/server-kit/src/domain-event/socket/publish.ts b/packages/server-kit/src/domain-event/socket/publish.ts index 9faa7b879..ef7d81fb9 100644 --- a/packages/server-kit/src/domain-event/socket/publish.ts +++ b/packages/server-kit/src/domain-event/socket/publish.ts @@ -5,7 +5,7 @@ * view the LICENSE file that was distributed with this source code. */ -import type { DomainsEventContext } from '@privateaim/core-kit'; +import type { DomainsEvents } from '@privateaim/core-kit'; import { DomainEventName, buildDomainEventFullName } from '@privateaim/core-kit'; import { Emitter } from '@socket.io/redis-emitter'; import type { Client } from 'redis-extension'; @@ -14,7 +14,7 @@ import { buildDomainEventChannelName, transformDomainEventData } from '../utils' export function publishDomainSocketEvent( client: Client, - context: DomainsEventContext, + context: DomainsEvents, destinations: DomainEventDestinations, ) { context = transformDomainEventData(context); @@ -27,7 +27,10 @@ export function publishDomainSocketEvent( let roomName = buildDomainEventChannelName(destinations[i].channel); - const fullEventName = buildDomainEventFullName(context.type, context.event); + const fullEventName = buildDomainEventFullName( + context.type, + context.event, + ); emitter .in(roomName)