lib/renderer/api/remote.js
function proxyFunctionProperties (remoteMemberFunction, metaId, name) {
  let loaded = false

  // Lazily load function properties
  const loadRemoteProperties = () => {
    if (loaded) return
    loaded = true
    const command = 'ELECTRON_BROWSER_MEMBER_GET'
    const meta = ipcRendererInternal.sendSync(command, contextId, metaId, name)
    setObjectMembers(remoteMemberFunction, remoteMemberFunction, meta.id, meta.members)
  }

  return new Proxy(remoteMemberFunction, {
    set: (target, property, value, receiver) => {
      if (property !== 'ref') loadRemoteProperties()
      target[property] = value
      return true
    },
    get: (target, property, receiver) => {
      if (!target.hasOwnProperty(property)) loadRemoteProperties()
      const value = target[property]
      if (property === 'toString' && typeof value === 'function') {
        return value.bind(target)
      }
      return value
    },
    ownKeys: (target) => {
      loadRemoteProperties()
      return Object.getOwnPropertyNames(target)
    },
    getOwnPropertyDescriptor: (target, property) => {
      const descriptor = Object.getOwnPropertyDescriptor(target, property)
      if (descriptor) return descriptor
      loadRemoteProperties()
      return Object.getOwnPropertyDescriptor(target, property)
    }
  })
}
function proxyFunctionProperties (remoteMemberFunction, metaId, name) {
  let loaded = false

  // Lazily load function properties
  const loadRemoteProperties = () => {
    if (loaded) return
    loaded = true
    const command = 'ELECTRON_BROWSER_MEMBER_GET'
    const meta = ipcRendererInternal.sendSync(command, contextId, metaId, name)
    setObjectMembers(remoteMemberFunction, remoteMemberFunction, meta.id, meta.members)
  }

  return new Proxy(remoteMemberFunction, {
    set: (target, property, value, receiver) => {
      if (property !== 'ref') loadRemoteProperties()
      target[property] = value
      return true
    },
    get: (target, property, receiver) => {
      if (!target.hasOwnProperty(property)) loadRemoteProperties()
      const value = target[property]
      if (property === 'toString' && typeof value === 'function') {
        return value.bind(target)
      }
      return value
    },
    ownKeys: (target) => {
      loadRemoteProperties()
      return Object.getOwnPropertyNames(target)
    },
    getOwnPropertyDescriptor: (target, property) => {
      const descriptor = Object.getOwnPropertyDescriptor(target, property)
      if (descriptor) return descriptor
      loadRemoteProperties()
      return Object.getOwnPropertyDescriptor(target, property)
    }
  })
}
function proxyFunctionProperties ( remoteMemberFunction , metaId , name ) { let loaded = false // Lazily load function properties const loadRemoteProperties = ( ) => { if ( loaded ) return loaded = true const command = 'ELECTRON_BROWSER_MEMBER_GET' const meta = ipcRendererInternal . sendSync ( command , contextId , metaId , name ) setObjectMembers ( remoteMemberFunction , remoteMemberFunction , meta . id , meta . members ) } return new Proxy ( remoteMemberFunction , { set : ( target , property , value , receiver ) => { if ( property !== 'ref' ) loadRemoteProperties ( ) target [ property ] = value return true } , get : ( target , property , receiver ) => { if ( ! target . hasOwnProperty ( property ) ) loadRemoteProperties ( ) const value = target [ property ] if ( property === 'toString' && typeof value === 'function' ) { return value . bind ( target ) } return value } , ownKeys : ( target ) => { loadRemoteProperties ( ) return Object . getOwnPropertyNames ( target ) } , getOwnPropertyDescriptor : ( target , property ) => { const descriptor = Object . getOwnPropertyDescriptor ( target , property ) if ( descriptor ) return descriptor loadRemoteProperties ( ) return Object . getOwnPropertyDescriptor ( target , property ) } } ) }
Wrap function in Proxy for accessing remote properties
Wrap function in Proxy for accessing remote properties