# async-proxy [![npm](https://img.shields.io/npm/v/async-proxy.svg?maxAge=2592000)](https://www.npmjs.com/package/async-proxy) [![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/BlackGlory/async-proxy/master/LICENSE) [![Build Status](https://travis-ci.org/BlackGlory/async-proxy.svg?branch=master)](https://travis-ci.org/BlackGlory/async-proxy) [![Coverage Status](https://coveralls.io/repos/github/BlackGlory/async-proxy/badge.svg)](https://coveralls.io/github/BlackGlory/async-proxy)

Create asynchronous nesting proxy in Node.js and browser.

## Installation

```sh
npm install --save async-proxy
# or
yarn add async-proxy
```

```javascript
import createAsyncProxy from 'async-proxy'
```

## Usage

Just modify handlers to suit your project.

Default handler(get, set, remove methods come from [object-path-operator](https://github.com/BlackGlory/object-path-operator) module):

```javascript
{
  async get(target, path) {
    return get(target, path)
  }
, async apply(target, path, caller, args) {
    return Reflect.apply(get(target, path), caller, args)
  }
, async set(target, path, value) {
    set(target, path, value) // The return value will be ignored
  }
, async deleteProperty(target, path) {
    remove(target, path) // The return value will be ignored
  }
, async construct(target, path, args) {
    return Reflect.construct(get(target, path), args)
  }
, async setPrototypeOf(target, path, prototype) {
    return Reflect.setPrototypeOf(get(target, path), prototype) // The return value will be ignored
  }
, async getPrototypeOf(target, path) {
    return Reflect.getPrototypeOf(get(target, path))
  }
, async defineProperty(target, path, prop, descriptor) {
    return Reflect.defineProperty(get(target, path), prop, descriptor) // The return value will be ignored
  }
}
```

### Example

#### create

```javascript
const localBaseObj = {}

const proxy = createAsyncProxy(localBaseObj, {})
```

#### get

```javascript
;(async () => {
  await proxy.something.asynchronous.property
})()
```

#### apply

```javascript
;(async () => {
  // handled by apply handler
  await proxy.something.asynchronous.method(some, args)

  // handled by get handler
  ;(await proxy.something.asynchronous.method)(some, args)
})()
```

#### set

```javascript
;(async () => {
  // The return value is not reliable, ou should check the results by other means to ensure that the operation is successful.
  // Non-blocking when it is an asynchronous operation, so your asynchronous operation should have an inside sequence queue.
  proxy.something.asynchronous.property = 'something'
})()
```

#### delete

```javascript
;(async () => {
  // The return value is not reliable, ou should check the results by other means to ensure that the operation is successful.
  // Non-blocking when it is an asynchronous operation, so your asynchronous operation should have an inside sequence queue.
  delete proxy.something.asynchronous.property
})()
```

#### new

```javascript
;(async () => {
  // handled by construct handler
  await new proxy.something.asynchronous.construct()

  // handled by get handler
  new (await proxy.something.construct)()
})()
```

#### for await

```javascript
;(async () => {
  for await (const prop of await proxy.something.enumerable) {
    ...
  }
})()
```

#### setPrototypeOf

```javascript
;(async () => {
  // The return value is not reliable, ou should check the results by other means to ensure that the operation is successful.
  // Non-blocking when it is an asynchronous operation, so your asynchronous operation should have an inside sequence queue.
  Object.setPrototypeOf(proxy.something.asynchronous.something, Array.prototype)
})
```

#### getPrototypeOf

```javascript
;(async () => {
  // handled by getPrototypeOf handler
  await Object.getPrototypeOf(proxy.something.asynchronous.property)

  // handled by get handler
  Object.getPrototypeOf(await proxy.something.asynchronous.property)
})()
```

#### defineProperty

```javascript
;(async () => {
  // The return value is not reliable, ou should check the results by other means to ensure that the operation is successful.
  // Non-blocking when it is an asynchronous operation, so your asynchronous operation should have an inside sequence queue.
  Object.defineProperty(proxy.something.asynchronous, 'property', {
    value: 'something'
  })
})()
```

## API

<!-- Generated by documentation.js. Update this documentation by updating the source code. -->

#### Table of Contents

-   [createAsyncProxy](#createasyncproxy)

### createAsyncProxy

Create a Proxy to asynchronous operate object.

**Parameters**

-   `target` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** Target object (optional, default `{}`)
-   `handlers` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** Async Proxy handlers (optional, default `{}`)
    -   `handlers.get` **function (target: [Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object), path: [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)&lt;[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)>): [Promise](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)&lt;any>** "get" handler
    -   `handlers.apply` **function (target: [Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object), path: [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)&lt;[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)>, caller: [Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object), args: [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)&lt;any>): Promsie&lt;any>** "apply" handler
    -   `handlers.set` **function (target: [Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object), path: [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)&lt;[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)>, value: any): void** "set" handler
    -   `handlers.deleteProperty` **function (target: [Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object), path: [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)&lt;[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)>): void** "deleteProperty" handler
    -   `handlers.construct` **function (target: [Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object), path: [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)&lt;[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)>, args: [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)&lt;any>): [Promise](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)&lt;any>** "construct" handler
    -   `handlers.setPrototypeOf` **function (target: [Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object), path: [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)&lt;[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)>, prototype: [Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)): void** "setPrototypeOf" handler
    -   `handlers.getPrototypeOf` **function (target: [Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object), path: [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)&lt;[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)>): [Promise](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)&lt;any>** "getPrototypeOf" handler
    -   `handlers.defineProperty` **function (target: [Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object), path: [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)&lt;[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)>, prop: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), descriptor: [Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)): void** "defineProperty" handler

Returns **[Proxy](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Proxy)** Async Proxy
