UNPKG

@fjell/core

Version:

Core Item and Key Framework for Fjell

140 lines (139 loc) 7.66 kB
import { ComKey, Item, ItemTypeArray, LocKeyArray, PriKey } from '@fjell/types'; import { BaseEvent } from './events'; import { Subscription, SubscriptionOptions } from './subscription'; /** * Core EventEmitter interface that storage libraries implement. * Each item type gets its own EventEmitter instance for full type safety. * Libraries implement separate EventEmitters per item type (UserEventEmitter, MessageEventEmitter, etc.) */ export interface EventEmitter<S extends string, L1 extends string = never, L2 extends string = never, L3 extends string = never, L4 extends string = never, L5 extends string = never> { /** * Emit a generic event with full control over event properties. * Libraries can use this for custom events or when they need full control. */ emit(event: BaseEvent<S, L1, L2, L3, L4, L5>): Promise<void>; /** * Emit a create event when an item is created. * Convenience method that constructs a properly typed CreateEvent. */ emitCreate(key: PriKey<S> | ComKey<S, L1, L2, L3, L4, L5>, scopes: string[], item: Item<S, L1, L2, L3, L4, L5>): Promise<void>; /** * Emit an update event when an item is modified. * Convenience method that constructs a properly typed UpdateEvent. */ emitUpdate(key: PriKey<S> | ComKey<S, L1, L2, L3, L4, L5>, scopes: string[], changes: string[], before?: Item<S, L1, L2, L3, L4, L5>, after?: Item<S, L1, L2, L3, L4, L5>): Promise<void>; /** * Emit a delete event when an item is deleted. * Convenience method that constructs a properly typed DeleteEvent. */ emitDelete(key: PriKey<S> | ComKey<S, L1, L2, L3, L4, L5>, scopes: string[], item?: Item<S, L1, L2, L3, L4, L5>): Promise<void>; /** * Emit an action event when a custom action is performed. * Convenience method that constructs a properly typed ActionEvent. */ emitAction(key: PriKey<S> | ComKey<S, L1, L2, L3, L4, L5>, scopes: string[], actionName: string, actionData?: Record<string, unknown>): Promise<void>; /** * Create a scoped emitter that automatically includes the specified scopes. * Libraries can use this to avoid passing scopes to every emit call. */ withScopes(scopes: string[]): ScopedEventEmitter<S, L1, L2, L3, L4, L5>; } /** * Scoped EventEmitter that automatically includes configured scopes. * Convenience interface for libraries to avoid passing scopes repeatedly. */ export interface ScopedEventEmitter<S extends string, L1 extends string = never, L2 extends string = never, L3 extends string = never, L4 extends string = never, L5 extends string = never> { /** The scopes that will be automatically included in all events */ readonly scopes: string[]; /** * Emit a generic event with automatic scope inclusion. * The event should omit scopes since they'll be added automatically. */ emit(event: Omit<BaseEvent<S, L1, L2, L3, L4, L5>, 'scopes'>): Promise<void>; /** * Emit a create event with automatic scope inclusion. */ emitCreate(key: PriKey<S> | ComKey<S, L1, L2, L3, L4, L5>, item: Item<S, L1, L2, L3, L4, L5>): Promise<void>; /** * Emit an update event with automatic scope inclusion. */ emitUpdate(key: PriKey<S> | ComKey<S, L1, L2, L3, L4, L5>, changes: string[], before?: Item<S, L1, L2, L3, L4, L5>, after?: Item<S, L1, L2, L3, L4, L5>): Promise<void>; /** * Emit a delete event with automatic scope inclusion. */ emitDelete(key: PriKey<S> | ComKey<S, L1, L2, L3, L4, L5>, item?: Item<S, L1, L2, L3, L4, L5>): Promise<void>; /** * Emit an action event with automatic scope inclusion. */ emitAction(key: PriKey<S> | ComKey<S, L1, L2, L3, L4, L5>, actionName: string, actionData?: Record<string, unknown>): Promise<void>; } /** * EventSubscriber interface for subscribing to and receiving events. * Each item type gets its own EventSubscriber instance for full type safety. */ export interface EventSubscriber<S extends string, L1 extends string = never, L2 extends string = never, L3 extends string = never, L4 extends string = never, L5 extends string = never> { /** * Subscribe to events using a full subscription object. * Returns the subscription ID for later unsubscribing. */ subscribe(subscription: Omit<Subscription<S, L1, L2, L3, L4, L5>, 'id'>): Promise<string>; /** * Unsubscribe from events using the subscription ID. */ unsubscribe(subscriptionId: string): Promise<void>; /** * Register a callback to be called when events are received. * Multiple callbacks can be registered and they'll all be called. */ onEvent(callback: (event: BaseEvent<S, L1, L2, L3, L4, L5>) => void): void; /** * Remove a previously registered event callback. */ removeEventListener(callback: (event: BaseEvent<S, L1, L2, L3, L4, L5>) => void): void; /** * Convenience method to subscribe to a specific item. * Automatically creates an ItemSubscription with the provided options. */ subscribeToItem(key: PriKey<S> | ComKey<S, L1, L2, L3, L4, L5>, options?: SubscriptionOptions<S, L1, L2, L3, L4, L5>): Promise<string>; /** * Convenience method to subscribe to a location. * Automatically creates a LocationSubscription with the provided options. */ subscribeToLocation(kta: ItemTypeArray<S, L1, L2, L3, L4, L5>, location: LocKeyArray<L1, L2, L3, L4, L5>, options?: SubscriptionOptions<S, L1, L2, L3, L4, L5>): Promise<string>; /** * Get all currently active subscriptions. * Useful for debugging and subscription management. */ getActiveSubscriptions(): Subscription<S, L1, L2, L3, L4, L5>[]; /** * Check if an event matches any active subscriptions. * Used internally by libraries to determine if an event should be processed. */ matchesSubscription(event: BaseEvent<S, L1, L2, L3, L4, L5>): boolean; /** * Check if an event matches a specific subscription. * Used internally for subscription matching logic. */ matchesSpecificSubscription(event: BaseEvent<S, L1, L2, L3, L4, L5>, subscription: Subscription<S, L1, L2, L3, L4, L5>): boolean; } /** * Combined EventSystem interface that includes both emitter and subscriber. * Libraries can implement this interface to provide both event emission and subscription. */ export interface EventSystem<S extends string, L1 extends string = never, L2 extends string = never, L3 extends string = never, L4 extends string = never, L5 extends string = never> { /** Event emitter for publishing events */ readonly emitter: EventEmitter<S, L1, L2, L3, L4, L5>; /** Event subscriber for receiving events */ readonly subscriber: EventSubscriber<S, L1, L2, L3, L4, L5>; } /** * Factory function type for creating EventSystems. * Libraries implement this to create properly configured event systems. */ export type EventSystemFactory<S extends string, L1 extends string = never, L2 extends string = never, L3 extends string = never, L4 extends string = never, L5 extends string = never> = (scopes: string[]) => EventSystem<S, L1, L2, L3, L4, L5>; export type UserEventEmitter = EventEmitter<'User'>; export type UserEventSubscriber = EventSubscriber<'User'>; export type UserEventSystem = EventSystem<'User'>; export type MessageEventEmitter<L1 extends string, L2 extends string> = EventEmitter<'Message', L1, L2>; export type MessageEventSubscriber<L1 extends string, L2 extends string> = EventSubscriber<'Message', L1, L2>; export type MessageEventSystem<L1 extends string, L2 extends string> = EventSystem<'Message', L1, L2>;