Repository: tauri-apps/tauri
File: packages/api/src/mocks.ts (TypeScript)

Code before:
  function handleEmit(args: { event: EventName; payload?: unknown }) {
    const eventListeners = listeners.get(args.event) || []
    for (const handler of eventListeners) {
      runCallback(handler, args)
    }
    return null
  }
  function handleRemoveListener(args: { event: EventName; id: number }) {
    const eventListeners = listeners.get(args.event)
    if (eventListeners) {
      const index = eventListeners.indexOf(args.id)
      if (index !== -1) {
        eventListeners.splice(index, 1)
      }
    }
  }

  // eslint-disable-next-line @typescript-eslint/require-await
  async function invoke<T>(
    cmd: string,
    args?: InvokeArgs,
    _options?: InvokeOptions
  ): Promise<T> {
    if (isEventPluginInvoke(cmd)) {
      return handleEventPlugin(cmd, args) as T
    }

    return cb(cmd, args) as T
  }

  const callbacks = new Map<number, (data: unknown) => void>()

  function registerCallback<T = unknown>(
    callback?: (response: T) => void,
    once = false
  ) {
    const identifier = window.crypto.getRandomValues(new Uint32Array(1))[0]
    callbacks.set(identifier, (data) => {
      if (once) {
        unregisterCallback(identifier)
      }
      return callback && callback(data as T)
    })
    return identifier
  }

  function unregisterCallback(id: number) {
    callbacks.delete(id)
  }

  function runCallback(id: number, data: unknown) {

Review comment (bug):
Actually, I'm not entirely sure if this is fine to do, since this way you can't handle these events yourself even if you wanted to, this will break the code for people doing custom handlings, maybe we should make this opt-in until v3?

Code after:
      case 'plugin:event|unlisten':
        return handleRemoveListener(args as { event: EventName; id: number })
    }
  }

  const listeners = new Map<string, number[]>()
  function handleListen(args: { event: EventName; handler: number }) {
    if (!listeners.has(args.event)) {
      listeners.set(args.event, [])
    }
    listeners.get(args.event)!.push(args.handler)
    return args.handler
  }

  function handleEmit(args: { event: EventName; payload?: unknown }) {
    const eventListeners = listeners.get(args.event) || []
    for (const handler of eventListeners) {
      runCallback(handler, args)
    }
    return null
  }
  function handleRemoveListener(args: { event: EventName; id: number }) {
    const eventListeners = listeners.get(args.event)
    if (eventListeners) {
      const index = eventListeners.indexOf(args.id)
      if (index !== -1) {
        eventListeners.splice(index, 1)
      }
    }
  }

  // eslint-disable-next-line @typescript-eslint/require-await
  async function invoke<T>(
    cmd: string,
    args?: InvokeArgs,
    _options?: InvokeOptions
  ): Promise<T> {
    if (options?.shouldMockEvents && isEventPluginInvoke(cmd)) {
      return handleEventPlugin(cmd, args) as T
    }

    return cb(cmd, args) as T
  }

  const callbacks = new Map<number, (data: unknown) => void>()

  function registerCallback<T = unknown>(
    callback?: (response: T) => void,
    once = false
  ) {
    const identifier = window.crypto.getRandomValues(new Uint32Array(1))[0]