npm package: @gocorus/socket
Description: Absinthe Socket
Author: Mauro Titimoli
Latest version: 0.2.5
Deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.

# @gocorus/socket

> Absinthe Socket

<!-- START doctoc -->

<!-- END doctoc -->

## Features

- Immutable functional API
  > All received and returned objects with the exception of AbsintheSocket
  > instances (there are plans to make this immutable too) are treated in an
  > immutable way. Objects have no methods and instead we provide independant
  > stateless functions to interact with them.
- Lazy connect / join
  > If provided phoenix socket instance is not connected, then instead of
  > connecting at creation time, connection will be established on the next
  > invocation of [send](#send).
- Handle pending operations on connection lost
  > Pending mutations will be aborted, queries will be resent, and subscriptions
  > reestablished.
- Cancellable requests
  > Calling [cancel](#cancel) removes given notifier from absintheSocket instance
  > and sends a Cancel event to all its observers and unsubscribes in case it
  > holds a subscription request.
- Operations deduplication
  > If an already sent request is given to [send](#send), then instead of sending
  > it again, the notifier associated with it will be returned.
- Observer support of recoverable errors
  > Since connection lost is handled, then two events needs to exist to represent
  > this fact: Error (recoverable), Abort (unrecoverable).
- Multiple observers per request
  > Calling [send](#send) returns a notifier which allows attaching any number of
  > observers that will be notified when result arrives.
- Observer interaction depending on operation type
  > For the case of subscriptions, _Start_ event is dispatched when the
  > subscription is established, while for the other types
  > (queries and mutations), when the request is sent.

## Installation

### Using [npm](https://docs.npmjs.com/cli/npm)

    $ npm install --save phoenix @gocorus/socket

### Using [yarn](https://yarnpkg.com)

    $ yarn add phoenix @gocorus/socket

## Types

```flowtype
type RequestStatus = "canceled" | "canceling" | "pending" | "sent" | "sending";

// from @jumpn/utils-graphql
type GqlRequest<Variables: void | Object = void> = {
  operation: string,
  variables?: Variables
};

// from @jumpn/utils-graphql
type GqlResponse<Data> = {
  data?: Data,
  errors?: Array<GqlError>
};

// from @jumpn/utils-graphql
type GqlOperationType = "mutation" | "query" | "subscription";

type Observer<Result, Variables: void | Object = void> = {|
  onAbort?: (error: Error) => any,
  onCancel?: () => any,
  onError?: (error: Error) => any,
  onStart?: (notifier: Notifier<Result, Variables>) => any,
  onResult?: (result: Result) => any
|};

type Notifier<Result, Variables: void | Object = void> = {|
  activeObservers: $ReadOnlyArray<Observer<Result, Variables>>,
  canceledObservers: $ReadOnlyArray<Observer<Result, Variables>>,
  isActive: boolean,
  operationType: GqlOperationType,
  request: GqlRequest<Variables>,
  requestStatus: RequestStatus,
  subscriptionId?: string
|};

type AbsintheSocket = {|
  channel: Channel,
  channelJoinCreated: boolean,
  notifiers: Array<Notifier<any>>,
  phoenixSocket: PhoenixSocket
|};
```

## API

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

### cancel

Cancels a notifier sending a Cancel event to all its observers and
unsubscribing in case it holds a subscription request

#### Parameters

- `absintheSocket` **AbsintheSocket**
- `notifier` **Notifier&lt;any, any>**

#### Examples

```javascript
import * as withAbsintheSocket from "@gocorus/socket";

withAbsintheSocket.cancel(absintheSocket, notifier);
```

Returns **AbsintheSocket**

### create

Creates an Absinthe Socket using the given Phoenix Socket instance

#### Parameters

- `phoenixSocket` **PhoenixSocket**

#### Examples

```javascript
import * as withAbsintheSocket from "@gocorus/socket";
import { Socket as PhoenixSocket } from "phoenix";

const absintheSocket = withAbsintheSocket.create(
  new PhoenixSocket("ws://localhost:4000/socket")
);
```

Returns **AbsintheSocket**

### observe

Observes given notifier using the provided observer

#### Parameters

- `absintheSocket` **AbsintheSocket**
- `notifier` **Notifier&lt;Result, Variables>**
- `observer` **Observer&lt;Result, Variables>**

#### Examples

```javascript
import * as withAbsintheSocket from "@gocorus/socket";

const logEvent = (eventName) => (...args) => console.log(eventName, ...args);

const updatedNotifier = withAbsintheSocket.observe(absintheSocket, notifier, {
  onAbort: logEvent("abort"),
  onError: logEvent("error"),
  onStart: logEvent("open"),
  onResult: logEvent("result"),
});
```

### send

Sends given request and returns an object (notifier) to track its progress
(see observe function)

#### Parameters

- `absintheSocket` **AbsintheSocket**
- `request` **GqlRequest&lt;Variables>**

#### Examples

```javascript
import * as withAbsintheSocket from "@gocorus/socket";

const operation = `
  subscription userSubscription($userId: ID!) {
    user(userId: $userId) {
      id
      name
    }
  }
`;

// This example uses a subscription, but the functionallity is the same for
// all operation types (queries, mutations and subscriptions)

const notifier = withAbsintheSocket.send(absintheSocket, {
  operation,
  variables: { userId: 10 },
});
```

Returns **Notifier&lt;Result, Variables>**

### toObservable

Creates an Observable that will follow the given notifier

#### Parameters

- `absintheSocket` **AbsintheSocket**
- `notifier` **Notifier&lt;Result, Variables>**
- `options` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)?** (optional, default `{}`)
  - `options.unsubscribe` **function (): [undefined](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined)?**
  - `options.onError` **function (error: [Error](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Error)): [undefined](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined)?**
  - `options.onStart` **function (notifier: Notifier&lt;Result, Variables>): [undefined](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined)?**
  - `options.handlers` **...any**

#### Examples

```javascript
import * as withAbsintheSocket from "@gocorus/socket";

const unobserveOrCancelIfNeeded = (absintheSocket, notifier, observer) => {
  if (notifier && observer) {
    withAbsintheSocket.unobserveOrCancel(absintheSocket, notifier, observer);
  }
};

const logEvent = (eventName) => (...args) => console.log(eventName, ...args);

const observable = withAbsintheSocket.toObservable(absintheSocket, notifier, {
  onError: logEvent("error"),
  onStart: logEvent("open"),
  unsubscribe: unobserveOrCancelIfNeeded,
});
```

Returns **Observable**

### unobserve

Detaches observer from notifier

#### Parameters

- `absintheSocket` **AbsintheSocket**
- `notifier` **Notifier&lt;any, any>**
- `observer` **Observer&lt;any, any>**

#### Examples

```javascript
import * as withAbsintheSocket from "@gocorus/socket";

withAbsintheSocket.unobserve(absintheSocket, notifier, observer);
```

Returns **AbsintheSocket**

### unobserveOrCancel

Cancels notifier if there are no more observers apart from the one given, or
detaches given observer from notifier otherwise

#### Parameters

- `absintheSocket` **AbsintheSocket**
- `notifier` **Notifier&lt;Result, Variables>**
- `observer` **Observer&lt;Result, Variables>**

#### Examples

```javascript
import * as withAbsintheSocket from "@gocorus/socket";

withAbsintheSocket.unobserve(absintheSocket, notifier, observer);
```

## License

[MIT](LICENSE.txt) :copyright: Jumpn Limited.