protected getCommon()

in packages/calling-stateful-client/src/CallAgentDeclarativeCommon.ts [173:256]


  protected getCommon<AgentType extends CallAgent | TeamsCallAgent, P extends keyof CallAgent>(
    target: AgentType,
    prop: P | 'incomingCalls'
  ): any {
    switch (prop) {
      case 'startCall': {
        return this._context.withErrorTeedToState((...args: Parameters<AgentType['startCall']>): CallCommon => {
          const call = this.startCall(target, args);
          this.addCall(call);
          return this.getOrCreateDeclarativeCall(call);
        }, 'CallAgent.startCall');
      }
      case 'join': {
        return this._context.withErrorTeedToState((...args: Parameters<AgentType['join']>): CallCommon => {
          const call = this.joinCall(target, args);
          this.addCall(call);
          return this.getOrCreateDeclarativeCall(call);
        }, 'CallAgent.join');
      }
      case 'calls': {
        return Array.from(this._declarativeCalls.values());
      }
      case 'on': {
        return (...args: Parameters<AgentType['on']>): void => {
          // typescript is not smart enough to handle multiple overloads and pull the correct type here so force casting args
          const event = args[0] as 'incomingCall' | 'callsUpdated' | 'connectionStateChanged';

          const isCallsUpdated = event === 'callsUpdated';
          if (isCallsUpdated) {
            const listener = args[1] as unknown as CollectionUpdatedEvent<CallCommon>;
            this._externalCallsUpdatedListeners.add(listener);
          } else {
            this.agentSubscribe(target, args);
          }
        };
      }
      case 'off': {
        return (...args: Parameters<AgentType['off']>): void => {
          // typescript is not smart enough to handle multiple overloads and pull the correct type here so force casting args
          const event = args[0] as 'incomingCall' | 'callsUpdated' | 'connectionStateChanged';

          const isCallsUpdated = event === 'callsUpdated';
          if (isCallsUpdated) {
            const listener = args[1] as unknown as CollectionUpdatedEvent<CallCommon>;
            this._externalCallsUpdatedListeners.delete(listener);
          } else {
            this.agentUnsubscribe(target, args);
          }
        };
      }
      case 'dispose': {
        /* @conditional-compile-remove(calling-beta-sdk) */
        return (): void => {
          target.dispose();
          this.unsubscribe();
        };
        // Wrapping CallAgent.dispose in a callback type (): Promise<void> to accomodate the change of CallAgent.dispose
        // in calling beta version 1.8.0-beta.1 from callback type (): Promise<void> to (): void
        const callAgentDisposeAsyncCallbackWrapper = async (): Promise<void> => {
          await target.dispose();
          return Promise.resolve();
        };
        return (): Promise<void> => {
          return callAgentDisposeAsyncCallbackWrapper().then(() => {
            this.unsubscribe();
          });
        };
      }
      /**
       * This attribute is a special case and doesn't exist on the CallAgent interface.
       * We need this to be able to return a declarative incoming call object using the call agent.
       * In a standard headless SDK usage, the right way to get an incoming call is to use the `incomingCall` event.
       * However, using the declarative layer, the ideal usage would be to:
       * 1. subscribe to the `onStateChange` event
       * 2. Get the incoming call from the new state and it's ID
       * 3. Use `callAgent.incomingCalls` and filter an incoming call ID to get a declarative incoming call object
       */
      case 'incomingCalls': {
        return Array.from(this._incomingCalls.values());
      }
      default:
        return Reflect.get(target, prop);
    }
  }