UNPKG

@salutejs/jazz-sdk-electron

Version:

Jazz SDK Electron

769 lines (741 loc) 22.9 kB
import { JazzSdkOptions, JazzSdk, JazzActivityEvent, JazzRoomEventParticipantLeft, JazzRoomEventParticipantJoined, JazzRoomEventParticipantUpdate, JazzRoomEventParticipants, JazzRoomEventLocalParticipantChanged, JazzRoomEventLocalParticipantId, JazzRoomEventDisconnecting, JazzRoomParticipantId, JazzSdkAdditionalPlugins, JazzRoom, JazzClient, JazzSdkPlugin, } from '@salutejs/jazz-sdk-web'; import { Container } from 'ditox'; import { IpcRenderer } from 'electron'; /** * Creates Jazz SDK for electron applications. */ declare function createJazzSdkElectron( options?: JazzSdkOptions, ): Promise<JazzSdk>; type TransportEventRegisterEndpoint = { type: 'registerEndpoint'; payload: { endpointName: string; }; }; type TransportEventUnregisterEndpoint = { type: 'unregisterEndpoint'; payload: { endpointName: string; }; }; type TransportEventHandsRaised = { type: 'handsRaised'; payload: { handsRaised: JazzRoomParticipantId[]; }; }; type ElectronVersion = { major: number; minor: number; patch: number; }; type MetaInfo = Readonly<{ electronVersion: ElectronVersion; }>; type TransportEventMetaIn = Readonly<{ type: 'electron:meta:out'; payload: MetaInfo; }>; type TransportEventMetaOut = Readonly<{ type: 'electron:meta:in'; }>; type TransportEvent = ( | JazzActivityEvent | JazzRoomEventParticipantLeft | JazzRoomEventParticipantJoined | JazzRoomEventParticipantUpdate | JazzRoomEventParticipants | JazzRoomEventLocalParticipantChanged | JazzRoomEventLocalParticipantId | JazzRoomEventDisconnecting | TransportEventRegisterEndpoint | TransportEventUnregisterEndpoint | TransportEventUnregisterEndpoint | TransportEventHandsRaised | TransportEventMetaIn | TransportEventMetaOut ) & EventLike$1; /** * experimental */ type TransportInvokeEvent = | { type: 'someType1'; payload: { foo: 'bar'; }; response: { bar: 'foo'; }; } | { type: 'someType2'; response: { bar: 'foo'; }; }; type EventLike$1 = { type: string; to?: string; }; type EventLikeWithResponse = { type: string; payload?: unknown; response: unknown; }; type EventLikeWithResponsePayload = { type: string; payload: unknown; response: unknown; }; /** * @deprecated use elebus + multiWindowTransport MULTI_WINDOW_TRANSPORT_SERVICE_TOKEN */ type TransportService< M extends EventLike$1 = TransportEvent, I extends EventLikeWithResponse = TransportInvokeEvent, > = { once: < Type extends M['type'], Result extends M & { type: Type; }, >( key: Type, callback: ( ...args: Result extends { payload: infer S; } ? [S] : [] ) => void, ) => () => void; on: < Type extends M['type'], Result extends M & { type: Type; }, >( key: Type, callback: ( ...args: Result extends { payload: infer S; } ? [S] : [] ) => void, ) => () => void; off: < Type extends M['type'], Result extends M & { type: Type; }, >( key: Type, callback: ( ...args: Result extends { payload: infer S; } ? [S] : [] ) => void, ) => void; /** * reference to "on" */ subscribe: < Type extends M['type'], Result extends M & { type: Type; }, >( key: Type, callback: ( ...args: Result extends { payload: infer S; } ? [S] : [] ) => void, ) => () => void; addListener: < Type extends M['type'], Result extends M & { type: Type; }, >( key: Type, callback: ( ...args: Result extends { payload: infer S; } ? [S] : [] ) => void, ) => void; /** * reference to "off" */ removeListener: < Type extends M['type'], Result extends M & { type: Type; }, >( key: Type, callback: ( ...args: Result extends { payload: infer S; } ? [S] : [] ) => void, ) => void; send: (event: M) => void; /** * experimental */ __invoke: < Type extends I['type'], Payload extends I & { type: Type; }, Response extends (I & { type: Type; })['response'], >( params: Payload extends EventLikeWithResponsePayload ? { type: Type; payload: Payload['payload']; } : { type: Type; }, ) => Promise<Response>; withType: < S extends EventLike$1 | undefined | void | null, O extends EventLikeWithResponse | undefined | void | null = void, >() => S extends EventLike$1 ? O extends EventLikeWithResponse ? TransportService<M | S, I | O> : TransportService<M | S, I> : O extends EventLikeWithResponse ? TransportService<M, I | O> : TransportService<M, I>; }; type JazzSdkElectronBridge = { transport: TransportService; }; type JazzSdkElectronEndpointOptions = Readonly<{ container?: Container; /** Extensions for the SDK */ plugins?: JazzSdkAdditionalPlugins; endpointName: string; bridge?: () => JazzSdkElectronBridge; ipcRenderer?: IpcRenderer; }>; type JazzSdkElectronEndpoint = Readonly<{ container: Container; destroy: () => void; }>; /** * Creates Jazz SDK for browserWindows of electron. */ declare function createJazzSdkElectronEndpoint( options: JazzSdkElectronEndpointOptions, ): Promise<JazzSdkElectronEndpoint>; declare function getJazzSdkMetaInfo(jazzSdk: JazzSdk): MetaInfo; /** * Event name for subscribe to all events in transport */ declare type AllEventTypes = '*'; declare interface BaseEventBusReadonly<EVENTS extends EventLike> extends BaseEventBusSubscriber<EVENTS> { name?: string; } declare interface BaseEventBusSubscriber<EVENTS extends EventLike> { /** * Method for subscribing to bus events. * In addition to events of the type, you can also specify the * event, * which will allow you to subscribe to all bus events. * The method returns a function for unsubscribing the callback * (this can also be done via the off or removeEventListener methods). * * If the onSubscribe lifecycle method is passed, * it will be called when this event is sent. * * If the transport was destroyed, this method will do nothing. * * @example * ```ts * type Events = { event: string }; * const eventBus = createBaseEventBus<Events>(); * * const unsubscriber = eventBus.on('event', (event, payload) => console.log(payload)); * unsubscriber(); * * eventBus.send('event', 'test'); * ``` */ on<EVENT extends string & keyof EVENTS>( event: EVENT, callback: (event: EVENT, payload: EVENTS[EVENT]) => void, ): Unsubscriber; /** * unsubscribe from an event. * If there are no subscribers left for the event, we remove it from the map. * * If the onUnsubscribe lifecycle callback is passed, * it will be called each time this function is called. * * If the transport was destroyed, the method does not work. * * @example * ```ts * type Events = { event: string }; * const eventBus = createBaseEventBus<Events>(); * * function handler(type: string, payload: string): void {} * * eventBus.on('event', handler); * eventBus.off('event', handler); * ``` */ off<EVENT extends string & keyof EVENTS>( event: EVENT, callback: (event: EVENT, payload: EVENTS[EVENT]) => void, ): void; } declare interface BaseTransportNodeReadonly { name?: string; __isRoot: Readonly<false>; /** * A property indicating that a class has been destroyed. * Once resolved, all methods in it stop working and the data is cleared. */ isDestroyed: boolean; /** * Method to get the root node object referenced by the node. */ getTransports: () => TransportRootNodes; } declare interface BaseTransportRoot extends DestroyedNode { name?: string; __isRoot: Readonly<true>; } /** * A node that has a cleanup mechanism. After the method chchchch is executed, * the node becomes inactive because event subscriptions and message sending stop functioning. */ declare interface DestroyedNode { /** * whether the transport is destroyed. * If the transport is destroyed, * then subscriptions and event sending do not work, and the subscriber list is destroyed. * Also, all dependent nodes are automatically unsubscribed from the destroyed node. */ isDestroyed: boolean; destroy(): void; } declare type EventLike = Record<string, unknown>; declare type Namespace = string; declare type TransportLifecycleEvents<EVENTS extends EventLike> = { /** * The transport was cleared. After that, * it stops functioning and all data in it is cleared. */ destroy: undefined; /** * Subscribed to some event. * The object indicates what event was subscribed to and whether it is the first. */ subscribe: { event: string & keyof EVENTS; mode: 'on' | 'once'; subscriber: Parameters<TransportRootSubscribers<EVENTS>['on']>[1]; subscribersCount: number; }; /** * Unsubscribed from some event. * The object indicates what event was unsubscribed from and whether there are more subscribers. */ unsubscribe: { event: string & keyof EVENTS; mode: 'on' | 'once'; subscriber: Parameters<TransportRootSubscribers<EVENTS>['off']>[1]; subscribersCount: number; }; }; declare interface TransportReadonlyNode<EVENTS extends EventLike> extends TransportReadonlyNodeBase<EVENTS> { lifecycle: TransportRoot<EVENTS>['lifecycle']; } declare type TransportReadonlyNodeBase<EVENTS extends EventLike> = TransportRootSubscribers<EVENTS> & BaseTransportNodeReadonly; declare interface TransportRoot<EVENTS extends EventLike> extends TransportRootBase<EVENTS> { /** * Sync mode sending events * * @default false */ sync?: Readonly<boolean>; /** * Method for sending an event to listeners. * If the transport was destroyed, * or no one is subscribed to this event, the method will do nothing. * * If there are subscribers to *, * they will listen to all events that were forwarded. * * The method works in 2 modes: synchronous and asynchronous (asynchronous mode is enabled by default). * To change this, you need to pass the 3rd argument. * * @example * ```ts * type Events = { event: string, event_empty: undefined }; * const transport = createTransport<Events>(); * * transport.on('event', (event, payload) => console.log(payload)); * transport.on('event_empty', (event, payload) => console.log(payload)); * transport.on('*', (event, payload) => console.log(payload)); * * transport.send('event', 'test'); * transport.send('event_empty'); * transport.send('event_empty', undefined); * ``` */ send< TYPE extends string & keyof EVENTS, PARAMETERS extends EVENTS[TYPE] extends undefined ? (payload?: EVENTS[TYPE]) => void : (payload: EVENTS[TYPE]) => void, >( type: TYPE, ...other: Parameters<PARAMETERS> ): void; /** * Method for getting a node that has only subscription interfaces (on/once/off). * Recommended for use in public API services to hide methods * for direct control of transport state from the outside. */ asReadonly(): TransportReadonlyNode<EVENTS>; } declare type TransportRootBase<EVENTS extends EventLike> = TransportRootSubscribers<EVENTS> & BaseTransportRoot & { /** * Transport lifecycle event bus. You can subscribe to 3 events: * 1) destroy - the transport was cleared. After that, it stops functioning and all data in it is cleared. * 2) subscribe - subscribed to some event. The object indicates what event was subscribed to and whether it is the first. * 3) unsubscribe - unsubscribed from some event. The object indicates what event was unsubscribed from and whether there are more subscribers. * * When the main transport is destroyed, the lifecycle event bus also dies. * * @example * ```ts * const transport = createTransport<Events>(); * * transport.lifecycle.on('destroy', () => console.log('transport is destroy')); * transport.lifecycle.on('subscribe', ({ event, isFirstSubscribe }) => console.log(`subscribe to event ${event} isFirst=${isFirstSubscribe}`)); * transport.lifecycle.on('unubscribe', ({ event, isHasSubscribers }) => console.log(`unsubscribe from event ${event} isHasSubscribers=${isHasSubscribers}`)); * * const unsubscriber1 = transport.on('event1', () => {}) // subscribe to event event1 isFirst=true * const unsubscriber2 = transport.on('event1', () => {}) // subscribe to event event1 isFirst=false * const unsubscriber3 = transport.on('event2', () => {}) // subscribe to event event2 isFirst=true * * unsubscriber3() // unsubscribe from event event2 isHasSubscribers=false * unsubscriber2() // unsubscribe from event event1 isHasSubscribers=true * unsubscriber1() // unsubscribe from event event1 isHasSubscribers=false * * transport.destroy(); // transport is destroy * ``` */ lifecycle: Readonly< BaseEventBusReadonly<TransportLifecycleEvents<EVENTS>> >; }; /** * List of nodes the node is subscribed to. */ declare type TransportRootNodes = Record<Namespace, Array<TransportRoot<any>>>; declare interface TransportRootSubscribers<EVENTS extends EventLike> { /** * Method for subscribing to bus events. * In addition to events of the type, you can also specify the * event, * which will allow you to subscribe to all bus events. * The method returns a function for unsubscribing the callback * (this can also be done via the off or removeEventListener methods). * * If the onSubscribe lifecycle method is passed, * it will be called when this event is sent. * * If the transport was destroyed, this method will do nothing. * * @example * ```ts * type Events = { event: string }; * const transport = createTransport<Events>(); * * transport.on('event', (event, payload) => console.log(payload)); * const unsubscriber = transport.on('*', (event, payload) => console.log(payload)); * unsubscriber(); * * transport.send('event', 'test'); * ``` */ on< EVENT_TYPE extends string & (keyof EVENTS | AllEventTypes), EVENT extends EVENT_TYPE extends AllEventTypes ? string & keyof EVENTS : EVENT_TYPE, CB extends { [TYPE in EVENT]: [TYPE, EVENTS[TYPE]]; }, >( event: EVENT_TYPE, callback: (...args: CB[EVENT]) => void, ): Unsubscriber; /** * A method for one-time subscription to bus events. * In addition to events of the type, you can also specify an event *, * which will allow you to subscribe to all bus events. * The method returns a function for unsubscribing the callback * (this can also be done via the off or removeEventListener methods). * * If the onSubscribe lifecycle method is passed, * it will be called when this event is sent. * * If the transport was destroyed, this method will do nothing. * * @example * ```ts * type Events = { event: string }; * const transport = createTransport<Events>(); * * transport.once('event', (event, payload) => console.log(payload)); * const unsubscriber = transport.once('*', (event, payload) => console.log(payload)); * unsubscriber(); * * transport.send('event', 'test'); * transport.send('event', 'test'); // not call subscribers * ``` */ once< EVENT_TYPE extends string & (keyof EVENTS | AllEventTypes), EVENT extends EVENT_TYPE extends AllEventTypes ? string & keyof EVENTS : EVENT_TYPE, CB extends { [TYPE in EVENT]: [TYPE, EVENTS[TYPE]]; }, >( event: EVENT_TYPE, callback: (...args: CB[EVENT]) => void, ): Unsubscriber; /** * unsubscribe from an event. * If there are no subscribers left for the event, we remove it from the map. * * If the onUnsubscribe lifecycle callback is passed, * it will be called each time this function is called. * * If the transport was destroyed, the method does not work. * * @example * ```ts * type Events = { event: string }; * const transport = createTransport<Events>(); * * function handler(type: string, payload: string): void {} * * transport.on('event', handler); * transport.off('event', handler); * ``` */ off<EVENT_TYPE extends string & (keyof EVENTS | AllEventTypes)>( event: EVENT_TYPE, callback: (...args: any[]) => void, ): void; } /** * unsubscribe function to unsubscribe from an event. */ declare type Unsubscriber = () => void; type MultiWindowTransportWindowName = LooseAutocomplete< MainProcessWindowName | MainWindowName >; type MultiWindowTransportTransportName = string; type MainProcessWindowName = 'main_process'; /** * Зарезервированное имя по умолчанию для сервиса в render процессе */ type MainWindowName = 'mainWindow'; type LooseAutocomplete<T extends string> = T | (string & {}); type MultiWindowTransportSendTo = | LooseAutocomplete<'*' | MainProcessWindowName | MainWindowName> | MultiWindowTransportWindowName[]; type MultiWindowTransportServiceGetEventsForTransport = { isReady: undefined; 'service:register': { window: MultiWindowTransportWindowName; }; 'service:unregister': { window: MultiWindowTransportWindowName; }; 'service:initialized': { window: MultiWindowTransportWindowName; }; 'transport:register': { transport: MultiWindowTransportTransportName; window: MultiWindowTransportWindowName; }; 'transport:unregister': { transport: MultiWindowTransportTransportName; window: MultiWindowTransportWindowName; }; 'transport:event:subscribe': { transport: MultiWindowTransportTransportName; window: MultiWindowTransportWindowName; event: string; }; 'transport:event:unsubscribe': { transport: MultiWindowTransportTransportName; window: MultiWindowTransportWindowName; event: string; }; }; type MultiWindowTransportModify< INITIAL_TYPE extends EventLike, MODIFY_TYPE extends EventLike = INITIAL_TYPE, > = { /** * Модификация отправляемых данных в другие окна */ send: < TYPE extends keyof INITIAL_TYPE & string, PAYLOAD extends INITIAL_TYPE[TYPE], >( type: TYPE, payload: PAYLOAD, ) => Promise<MODIFY_TYPE>; /** * Модификация событий, полученных из других окон приложения */ get: < TYPE extends keyof MODIFY_TYPE & string, PAYLOAD extends MODIFY_TYPE[TYPE], >( type: TYPE, payload: PAYLOAD, ) => Promise<INITIAL_TYPE>; }; type MultiWindowTransportUnsubscribe = () => void; type MultiWindowTransportRegisterOptions< INITIAL_TYPE extends EventLike, MODIFY_TYPE extends EventLike = INITIAL_TYPE, > = { /** * под каким именем будет использоваться транспорт. * Если параметр не передан, то имя будет взято из транспорта. */ name?: MultiWindowTransportWindowName; /** * elebus шина событий */ transport: TransportRoot<INITIAL_TYPE>; /** * Модификация отправляемых и получаем событий из других окон приложения * Нужно, если нужно видоизменить данные. Особенно важно, если событие * содержит не сериализуемые/дессириализуемые данные (классы) */ modify?: MultiWindowTransportModify<INITIAL_TYPE, MODIFY_TYPE>; /** * В какие окна должны пересылаться события * По умолчанию они отправляются во все окна подписчики * (см параметр name при регистрации плагина) * * @default '*' */ to?: MultiWindowTransportSendTo; }; type MultiWindowTransportRegisterInfo = { unsubscribe: MultiWindowTransportUnsubscribe; }; type MultiWindowTransportService = { register: <INITIAL_TYPE extends EventLike, MODIFY_TYPE extends EventLike>( options: MultiWindowTransportRegisterOptions<INITIAL_TYPE, MODIFY_TYPE>, ) => MultiWindowTransportRegisterInfo; unregister: <EVENTS extends EventLike>( transport: TransportRoot<EVENTS>, ) => void; /** * Проинициализирован ли сервис до конца */ getIsReady: () => boolean; /** * Подписка на события сервиса */ on: TransportRoot<MultiWindowTransportServiceGetEventsForTransport>['on']; once: TransportRoot<MultiWindowTransportServiceGetEventsForTransport>['once']; off: TransportRoot<MultiWindowTransportServiceGetEventsForTransport>['off']; }; type MultiWindowTransportPluginSettings = { /** * Имя сервиса. Для каждого окна оно должно быть уникальным * Если имя не передано, то будет использоваться значение по умолчанию * * `WARNING`: несколько окон с одним именем не должно существовать * Зарезервировано 2 имени: * `main_process` - для сервиса на уровне main процесса в electron * `mainWindow` - для главного окна приложения */ name?: MultiWindowTransportTransportName; /** * Если у нас идет в окне изоляция и мы не можем получить доступ * к preload слою, то передаем в плагин ipcRender, * чтоб создать свой бридж */ ipcRenderer?: IpcRenderer; }; declare function getMultiWindowTransport( sdk: JazzRoom | JazzClient | JazzSdk, ): MultiWindowTransportService; declare function multiWindowTransportPlugin( settings?: MultiWindowTransportPluginSettings, ): JazzSdkPlugin; export { type JazzSdkElectronEndpoint, type JazzSdkElectronEndpointOptions, type MultiWindowTransportModify, type MultiWindowTransportPluginSettings, type MultiWindowTransportRegisterInfo, type MultiWindowTransportRegisterOptions, type MultiWindowTransportSendTo, type MultiWindowTransportService, type MultiWindowTransportUnsubscribe, createJazzSdkElectron, createJazzSdkElectronEndpoint, getJazzSdkMetaInfo, getMultiWindowTransport, multiWindowTransportPlugin, };