open-index/open-npm huggingface dataset:
npm package: @jacobberglund/animated-swap
Description: A web component for animated content swapping
Author: Jacob Berglund
Latest version: 1.0.0

# @jacobberglund/animated-swap

A web component that animates between two slotted states with a smooth sliding transition. Perfect for "Copy → Copied!" feedback patterns.

## Installation

```bash
npm install @jacobberglund/animated-swap
```

## Usage

```javascript
import "@jacobberglund/animated-swap";
```

```html
<button onclick="this.querySelector('animated-swap').swapped = true">
  <animated-swap auto duration="2000">
    <span>Copy</span>
    <span slot="swap-to">Copied!</span>
  </animated-swap>
</button>
```

## Attributes

| Attribute  | Type      | Description                                      |
| ---------- | --------- | ------------------------------------------------ |
| `swapped`  | `boolean` | Toggles to the swapped state                     |
| `auto`     | `boolean` | Auto-resets to initial state after `duration`    |
| `duration` | `number`  | Reset delay in ms (default: `2500`)              |

## CSS Custom Properties

| Property                     | Default                      | Description                  |
| ---------------------------- | ---------------------------- | ---------------------------- |
| `--swap-offset`              | `100%`                       | Vertical offset for slide    |
| `--swap-duration`            | `500ms`                      | Transform transition duration|
| `--swap-opacity-duration`    | `var(--swap-duration)`       | Opacity transition duration  |
| `--swap-easing`              | `cubic-bezier(0, 0, 0, 1.03)`| Easing function              |

## CSS Parts

| Part        | Description                     |
| ----------- | ------------------------------- |
| `swap-from` | Container for the default slot  |
| `swap-to`   | Container for the swap-to slot  |
npm package: @jacobberglund/bind-input-css
Description: A web component that binds input values to CSS custom properties
Author: Jacob Berglund
Latest version: 1.0.0

# @jacobberglund/bind-input-css

A web component that binds input elements to CSS custom properties for real-time styling control.

## Installation

```bash
npm install @jacobberglund/bind-input-css
```

## Usage

```javascript
import "@jacobberglund/bind-input-css";
```

```html
<!-- Bind to a global element -->
<bind-input-css variable="--scale" unit="px" target=":root" strategy="global">
  <input type="range" min="0" max="100" />
  <input type="number" />
</bind-input-css>

<!-- Bind to the closest ancestor -->
<div class="card">
  <bind-input-css variable="--card-padding" unit="rem" target=".card">
    <input type="number" min="0" max="5" />
  </bind-input-css>
</div>

<!-- Bind to the component itself -->
<bind-input-css variable="--opacity" strategy="self">
  <input type="range" min="0" max="1" step="0.1" />
</bind-input-css>
```

## Attributes

| Attribute  | Description                                              | Default     |
| ---------- | -------------------------------------------------------- | ----------- |
| `variable` | **Required.** CSS custom property name (must start with `--`) | —           |
| `unit`     | Unit to append to the value (`px`, `%`, `rem`, etc.)     | `""`        |
| `target`   | CSS selector for the element to bind to                  | —           |
| `strategy` | How to resolve the target: `closest`, `global`, or `self` | `"closest"` |

## Features

- 🔗 **Two-way binding** - Syncs CSS variables with input values
- 🎚️ **Input sync** - Multiple inputs (range + number) stay in sync
- 🎯 **Flexible targeting** - Bind to ancestors, global elements, or self
- 📐 **Unit support** - Append any CSS unit automatically
npm package: @jacobberglund/enhance-form
Description: A web component for enhancing HTML forms with additional functionality
Author: Jacob Berglund
Latest version: 1.0.0

# @jacobberglund/enhance-form

A web component that progressively enhances HTML forms with AJAX submission, field-level validation, and targeted DOM updates.

## Installation

```bash
npm install @jacobberglund/enhance-form
```

## Usage

```javascript
import "@jacobberglund/enhance-form";
```

```html
<enhance-form target="#results" fail-target="#error-container">
  <form action="/submit" method="POST">
    <fieldset enhance-form-group>
      <input name="email" enhance-validate />
    </fieldset>
    <button type="submit">Submit</button>
  </form>
</enhance-form>

<div id="results"></div>
<div id="error-container"></div>
```

## Attributes

| Attribute     | Description                                              |
| ------------- | -------------------------------------------------------- |
| `target`      | CSS selector for element to replace on success (200)     |
| `fail-target` | CSS selector for element to replace on server errors (5xx). Defaults to `target` |

## Form Attributes

| Attribute             | Description                                      |
| --------------------- | ------------------------------------------------ |
| `enhance-form-group`  | Marks a container (e.g., fieldset) for partial updates during validation |
| `enhance-validate`    | Enables blur validation on an input              |

## Response Headers

The server can use these headers to control behavior:

| Header               | Description                          |
| -------------------- | ------------------------------------ |
| `X-Enhance-Redirect` | Triggers a redirect to the specified URL |

## Request Headers

These headers are sent with requests to help the server understand the context:

| Header              | Description                              |
| ------------------- | ---------------------------------------- |
| `X-Enhance-Submit`  | Indicates a full form submission         |
| `X-Enhance-Validate`| Indicates a field validation request (value is the field name) |

## Features

- 🔄 **AJAX Submission** - No page reload required
- ✅ **Field Validation** - Validate on blur with server-side logic
- 🎯 **Targeted Updates** - Replace specific DOM elements with response
- 🎬 **View Transitions** - Integrates with View Transitions API when available
- 📱 **Progressive Enhancement** - Falls back gracefully without JS
npm package: @jacobbubu/between-ts
Description: [![Build Status](https://travis-ci.org/jacobbubu/between-ts.svg)](https://travis-ci.org/jacobbubu/between-ts) [![Coverage Status](https://coveralls.io/repos/github/jacobbubu/between-ts/badge.svg)](https://coveralls.io/github/jacobbubu/between-ts) [![npm](
Author: jacobbubu
Latest version: 1.0.0

# @jacobbubu/between-ts

[![Build Status](https://travis-ci.org/jacobbubu/between-ts.svg)](https://travis-ci.org/jacobbubu/between-ts)
[![Coverage Status](https://coveralls.io/repos/github/jacobbubu/between-ts/badge.svg)](https://coveralls.io/github/jacobbubu/between-ts)
[![npm](https://img.shields.io/npm/v/@jacobbubu/between-ts.svg)](https://www.npmjs.com/package/@jacobbubu/between-ts/)

> Rewritten [between](http://github.com/dominictarr/between) in TypeScript

## Intro.

This repo. is a TypeScript rewrite of [between](http://github.com/dominictarr/between) and it's [guarded version](https://github.com/dashed/between2).

## Usage

```bash
npm i @jacoebubu/between-ts
npm run example:ex1
```

``` ts
import { between } from '@jacoebubu/between-ts'

console.log(between('A', 'B'))
// AV
```

Please read the code in test folder for the detail usage.
npm package: @jacobbubu/capped-event
Description: [![Build Status](https://travis-ci.org/jacobbubu/capped-event.svg)](https://travis-ci.org/jacobbubu/capped-event) [![Coverage Status](https://coveralls.io/repos/github/jacobbubu/capped-event/badge.svg)](https://coveralls.io/github/jacobbubu/capped-event) 
Author: jacobbubu
Latest version: 1.2.1

# @jacobbubu/capped-event

[![Build Status](https://travis-ci.org/jacobbubu/capped-event.svg)](https://travis-ci.org/jacobbubu/capped-event)
[![Coverage Status](https://coveralls.io/repos/github/jacobbubu/capped-event/badge.svg)](https://coveralls.io/github/jacobbubu/capped-event)
[![npm](https://img.shields.io/npm/v/@jacobbubu/capped-event.svg)](https://www.npmjs.com/package/@jacobbubu/capped-event/)

> A derived class from ReliableEvent in [scuttlebutt-pull](https://github.com/jacobbubu/scuttlebutt-pull) that provides basic cache management capabilities.

## Intro.

The `ReliableEvent` in [scuttlebutt-pull](https://github.com/jacobbubu/scuttlebutt-pull) has not provided cache mechanism.

You can only push events into the instance of `ReliableEvent`, but there is no way to remove them.

In `CappedEvent`, we fire a notification when the items count for some event reached a `warningLine` that is setting by the `options` you passed through the construction.

For removing items from cache, we provide to methods:

- `pruneBefore(before: number, key: string)`: prune the items before xxx milliseconds.
- `pruneTo(remain: number, key: string)`: just keep `remain` items in cache.

Please the test case for the detail.
npm package: @jacobbubu/ci-test1
Description: [![Build Status](https://travis-ci.org/jacobbubu/ci-test1.svg)](https://travis-ci.org/jacobbubu/ci-test1) [![Coverage Status](https://coveralls.io/repos/github/jacobbubu/ci-test1/badge.svg)](https://coveralls.io/github/jacobbubu/ci-test1) [![npm](https://
Author: jacobbubu
Latest version: 3.0.0

# @jacobbubu/ci-test1

[![Build Status](https://travis-ci.org/jacobbubu/ci-test1.svg)](https://travis-ci.org/jacobbubu/ci-test1)
[![Coverage Status](https://coveralls.io/repos/github/jacobbubu/ci-test1/badge.svg)](https://coveralls.io/github/jacobbubu/ci-test1)
[![npm](https://img.shields.io/npm/v/@jacobbubu/ci-test1.svg)](https://www.npmjs.com/package/@jacobbubu/ci-test1/)

> A starter project that makes creating a TypeScript module extremely easy.

## Intro.

Making a little change for internal demo.

This tool is a modification of [typescript-library-starter](https://github.com/alexjoverm/typescript-library-starter), I'm using it to create Node.JS modules.

## Usage

```bash
git clone https://github.com/jacobbubu/typescript-starter.git YOURFOLDERNAME
cd YOURFOLDERNAME
npm install
```

**Start coding!** `package.json` and entry files are already set up for you, so don't worry about linking to your main file, typings, etc. Just keep those files with the same name.

## Features

This project follows the [all-contributors](https://github.com/kentcdodds/all-contributors) specification. Contributions of any kind are welcome!
npm package: @jacobbubu/crdt-pull
Description: [![Build Status](https://travis-ci.org/jacobbubu/crdt-pull.svg)](https://travis-ci.org/jacobbubu/crdt-pull) [![Coverage Status](https://coveralls.io/repos/github/jacobbubu/crdt-pull/badge.svg)](https://coveralls.io/github/jacobbubu/crdt-pull) [![npm](http
Author: jacobbubu
Latest version: 1.0.2

# @jacobbubu/crdt-pull

[![Build Status](https://travis-ci.org/jacobbubu/crdt-pull.svg)](https://travis-ci.org/jacobbubu/crdt-pull)
[![Coverage Status](https://coveralls.io/repos/github/jacobbubu/crdt-pull/badge.svg)](https://coveralls.io/github/jacobbubu/crdt-pull)
[![npm](https://img.shields.io/npm/v/@jacobbubu/crdt-pull.svg)](https://www.npmjs.com/package/@jacobbubu/crdt-pull/)

> Rewritten [crdt](https://github.com/dominictarr/crdt) in TypeScript and work with [scuttlebutt-pull](https://github.com/jacobbubu/scuttlebutt-pull)

## Intro.

``

## Usage

```bash
npm install @jacobbubu/crdt-pull
```

``` ts
import { Doc } from '../src'
import { link } from '@jacobbubu/scuttlebutt-pull'
import { delay } from './utils'

const main = async () => {
  const doc = new Doc({ id: 'doc' })
  const hoc = new Doc({ id: 'hoc' })
  const ds = doc.createStream({ name: 'd-h', wrapper: 'raw' })
  const hs = hoc.createStream({ name: 'h-d', wrapper: 'raw' })

  link(ds, hs)
  doc.add({ id: 'abc', hello: 3 })
  await delay(100)

  console.log(hoc.toJSON())
}

// tslint:disable-next-line no-floating-promises
main()
```

Please see the test cases  for the detail.
npm package: @jacobbubu/debug
Description: Yet another [debug](https://github.com/visionmedia/debug) module written in typescript.
Author: jacobbubu
Latest version: 1.2.0

# @jacobbubu/debug

[![Build Status](https://travis-ci.org/jacobbubu/debug.svg)](https://travis-ci.org/jacobbubu/debug)

Yet another [debug](https://github.com/visionmedia/debug) module written in typescript.

## Install

```b ash
npm install
```

## Run Example

``` bash
npm run example:ex1
```

Got the output:

![ex1's output](./docs/ex1-1.png)
npm package: @jacobbubu/dnode-pull
Description: [![Build Status](https://travis-ci.org/jacobbubu/dnode-pull.svg)](https://travis-ci.org/jacobbubu/dnode-pull) [![Coverage Status](https://coveralls.io/repos/github/jacobbubu/dnode-pull/badge.svg?branch=master)](https://coveralls.io/github/jacobbubu/dnode-
Author: jacobbubu
Latest version: 1.0.0

# @jacobbubu/dnode-pull

[![Build Status](https://travis-ci.org/jacobbubu/dnode-pull.svg)](https://travis-ci.org/jacobbubu/dnode-pull)
[![Coverage Status](https://coveralls.io/repos/github/jacobbubu/dnode-pull/badge.svg?branch=master)](https://coveralls.io/github/jacobbubu/dnode-pull?branch=master)
[![npm](https://img.shields.io/npm/v/@jacobbubu/dnode-pull.svg)](https://www.npmjs.com/package/@jacobbubu/dnode-pull/)

> A [pull-stream](https://github.com/pull-stream/pull-stream) implementation of [dnode](https://github.com/substack/dnode).

## Intro.

This tool is a modification of [typescript-library-starter](https://github.com/alexjoverm/typescript-library-starter), I'm using it to create Node.JS modules.

## Usage

```bash
npm install @jacobbubu/dnode-pull
npm run example:ex1
```
npm package: @jacobbubu/gitlab-ci-npmrc
Description: > Used to generate `.npmrc` files in the gitlab ci pipeline.
Author: jacobbubu
Latest version: 1.0.1

# @jacobbubu/gitlab-ci-npmrc

> Used to generate `.npmrc` files in the gitlab ci pipeline.

## Usage

in `.gitlab-ci.yml`:

``` yaml
  script:
    - |
      npx @jacobbubu/gitlab-ci-npmrc ./.npmrc

  artifacts:
    when: always
    paths:
      - .npmrc
```

`@jacobbubu/gitlab-ci-npmrc` will generate the url of the npm registry based on the namespace and project id of the current project, if the key already exists in `.npmc`, the value of the key will be preserved.
npm package: @jacobbubu/gitlab-ci-registry
Description: > Provides a command-line tool to perform the task of setting "publishConfig.registry" in the gitlab CI pipeline file (gitlab-ci.yml).
Author: jacobbubu
Latest version: 1.0.4

# @jacobbubu/gitlab-ci-registry

> Provides a command-line tool to perform the task of setting "publishConfig.registry" in the gitlab CI pipeline file (gitlab-ci.yml).

## Intro.

If you want to publish your package to the gitlab registry, you need to set the correct URL in the `publishConfig.registry` field of `package.json`, since it contains the `project id`. You can only set this up correctly after the project has been created in GitLab.

To avoid source code containing `project id`, we provide this simple command-line tool that temporarily sets up `publicConfig.registry` by running `npx gitlab-ci-registry ./package.json`.

If `publicConfig.registry` already exists or the CI environment variables are incomplete, there will be no changes to the `package.json` file.
npm package: @jacobbubu/infer-partial-order
Description: infer the partial order of a set from a set of examples
Author: jacobbubu
Latest version: 1.0.0

# @jacobbubu/infer-partial-order

[![Build Status](https://github.com/jacobbubu/infer-partial-order/workflows/Build%20and%20Release/badge.svg)](https://github.com/jacobbubu/infer-partial-order/actions?query=workflow%3A%22Build+and+Release%22)
[![Coverage Status](https://coveralls.io/repos/github/jacobbubu/infer-partial-order/badge.svg)](https://coveralls.io/github/jacobbubu/infer-partial-order)
[![npm](https://img.shields.io/npm/v/@jacobbubu/infer-partial-order.svg)](https://www.npmjs.com/package/@jacobbubu/infer-partial-order/)

> Rewrite [infer-partial-order](https://github.com/dominictarr/infer-partial-order) with TypeScript

# Why rewrite

* Rewriting makes me more aware of the author’s intentions
* Adding a type declaration to the original module will not save much

In order to understand of the function of the module, the following is the original README copied.

# infer-partial-order

infer the partial order of a set from a set of examples.

say we have two sequences `A, B, C` and `B, A, C`.
Here `A < C` and `B < C`, but sometimes `B == A`.
This relationship is obvious, because there are only 3 items,
but as the number of items increase, it's much less clear.

## Example

represent a partial ordering like this:
``` ts
import { infer } from '@jacobbubu/infer-partial-order'

infer([ [A, B, C], [B, A, C] ])

=> {
  A:[],
  B:[],
  C:[A, B]
}
```

Each key maps to the list of items that always come before it.

for more complex cases, you might want to use the canonical mode,
it strips out items that are indirectly lesser than a given item.
This is still enough information to build a graph of the order
relationships.
``` js
var infer = require('infer-partial-order')

infer([ [A, B, C, D, E], [B, A, D, C, E], [A, B, C, D, E])

=> {
  A:[],
  B:[],
  C:[A, B],
  D:[A, B],
  E:[C, D]
}
```

## License

MIT
npm package: @jacobbubu/job-model
Description: [![Build Status](https://travis-ci.org/YOURNAME/@jacobbubu/job-model.svg)](https://travis-ci.org/YOURNAME/@jacobbubu/job-model) [![Coverage Status](https://coveralls.io/repos/github/YOURNAME/@jacobbubu/job-model/badge.svg)](https://coveralls.io/github/YOU
Author: jacobbubu
Latest version: 1.2.0

# @jacobbubu/job-model

[![Build Status](https://travis-ci.org/YOURNAME/@jacobbubu/job-model.svg)](https://travis-ci.org/YOURNAME/@jacobbubu/job-model)
[![Coverage Status](https://coveralls.io/repos/github/YOURNAME/@jacobbubu/job-model/badge.svg)](https://coveralls.io/github/YOURNAME/job-model)
[![npm](https://img.shields.io/npm/v/@YOURNAME/@jacobbubu/job-model.svg)](https://www.npmjs.com/package/@jacobbubu/job-model/)

> Implement a replicated job queue based on [scuttlebutt-pull](https://github.com/jacobbubu/scuttlebutt-pull).

## Intro.

This tool is a modification of [typescript-library-starter](https://github.com/alexjoverm/typescript-library-starter), I'm using it to create Node.JS modules.

## Usage

Please see the example('./examples/simple.ts') for the usage.
npm package: @jacobbubu/lcov-badge
Description: [![Build Status](https://github.com/jacobbubu/lcov-badge/workflows/Build%20and%20Release/badge.svg)](https://github.com/jacobbubu/lcov-badge/actions?query=workflow%3A%22Build+and+Release%22) [![Coverage Status](https://coveralls.io/repos/github/jacobbubu/
Author: jacobbubu
Latest version: 1.0.2

# @jacobbubu/lcov-badge

[![Build Status](https://github.com/jacobbubu/lcov-badge/workflows/Build%20and%20Release/badge.svg)](https://github.com/jacobbubu/lcov-badge/actions?query=workflow%3A%22Build+and+Release%22)
[![Coverage Status](https://coveralls.io/repos/github/jacobbubu/lcov-badge/badge.svg)](https://coveralls.io/github/jacobbubu/lcov-badge)
[![npm](https://img.shields.io/npm/v/@jacobbubu/lcov-badge.svg)](https://www.npmjs.com/package/@jacobbubu/lcov-badge/)

> Generate summarized coverage text from the lcov.info code coverage file.

# Intro.

This project was designed to make it easy for GitLab CI to extract the overall code coverage numbers and generate [coverage badges](https://docs.gitlab.com/ee/ci/pipelines/settings.html#test-coverage-parsing).

# Usage

```
lcov-badge path/to/lcov.info
```
npm package: @jacobbubu/looper
Description: [![Build Status](https://github.com/jacobbubu/looper/workflows/Build%20and%20Release/badge.svg)](https://github.com/jacobbubu/looper/actions?query=workflow%3A%22Build+and+Release%22) [![Coverage Status](https://coveralls.io/repos/github/jacobbubu/looper/b
Author: jacobbubu
Latest version: 1.0.0

# @jacobbubu/looper

[![Build Status](https://github.com/jacobbubu/looper/workflows/Build%20and%20Release/badge.svg)](https://github.com/jacobbubu/looper/actions?query=workflow%3A%22Build+and+Release%22)
[![Coverage Status](https://coveralls.io/repos/github/jacobbubu/looper/badge.svg)](https://coveralls.io/github/jacobbubu/looper)
[![npm](https://img.shields.io/npm/v/@jacobbubu/looper.svg)](https://www.npmjs.com/package/@jacobbubu/looper/)

> Rewritten [looper](https://github.com/dominictarr/looper) in TypeScript.

## Synopsis

Normally, if `mightBeAsync` calls it's cb immediately
this would `RangeError`:

``` js
let l = 100000
;(function next () {
  if(--l) mightBeAsync(next)
})
```

`looper` detects that case, and falls back to a `while` loop,
in computer science something like this is called a [trampoline](https://en.wikipedia.org/wiki/Trampoline_(computing))
this module is simpler than other trampoline libraries such as [tail-call](https://github.com/Gozala/js-tail-call)
because it does not preserve arguments. But this is still useful
for looping when  async recursion is sometimes sync.

This is about 10 times faster than using [setImmediate](http://devdocs.io/node~6_lts/timers#timers_setimmediate_callback_args)

## Example

``` js
import looper from 'looper'

let l = 100000
const next = looper(function () {
  if(--l) probablySync(next)
})

next()
```

when you want to stop looping, don't call `next`.
`looper` checks if each callback is sync or not,
so you can even mix sync and async calls!

## License

MIT
npm package: @jacobbubu/merged-model
Description: [![Build Status](https://github.com/jacobbubu/merged-model/workflows/Build%20and%20Release/badge.svg)](https://github.com/jacobbubu/merged-model/actions?query=workflow%3A%22Build+and+Release%22) [![Coverage Status](https://coveralls.io/repos/github/jacobb
Author: jacobbubu
Latest version: 1.0.3

# @jacobbubu/merged-model

[![Build Status](https://github.com/jacobbubu/merged-model/workflows/Build%20and%20Release/badge.svg)](https://github.com/jacobbubu/merged-model/actions?query=workflow%3A%22Build+and+Release%22)
[![Coverage Status](https://coveralls.io/repos/github/jacobbubu/merged-model/badge.svg)](https://coveralls.io/github/jacobbubu/merged-model)
[![npm](https://img.shields.io/npm/v/@jacobbubu/merged-model.svg)](https://www.npmjs.com/package/@jacobbubu/merged-model/)

> A subclass of scuttlebutt-pull/model that supports merged values with same key.

## Usage

``` ts
const a = new MergedModel('A')
const b = new MergedModel('B')

const s1 = a.createStream({ name: 'a->b' })
const s2 = b.createStream({ name: 'b->a' })

a.set('num', 1)
b.set('num', 2)
a.set('foo', { foo: 'one' })
b.set('foo', { bar: 'two' })

s2.on('synced', () => {
  expect(b.toJSON()).toEqual({ num: 2, foo: { foo: 'one', bar: 'two' } })
  done()
})

link(s1, s2)
```
npm package: @jacobbubu/meta-job-list
Description: [![Build Status](https://github.com/jacobbubu/meta-job-list/workflows/Build%20and%20Release/badge.svg)](https://github.com/jacobbubu/meta-job-list/actions?query=workflow%3A%22Build+and+Release%22) [![Coverage Status](https://coveralls.io/repos/github/jaco
Author: jacobbubu
Latest version: 1.2.0

# @jacobbubu/meta-job-list

[![Build Status](https://github.com/jacobbubu/meta-job-list/workflows/Build%20and%20Release/badge.svg)](https://github.com/jacobbubu/meta-job-list/actions?query=workflow%3A%22Build+and+Release%22)
[![Coverage Status](https://coveralls.io/repos/github/jacobbubu/meta-job-list/badge.svg)](https://coveralls.io/github/jacobbubu/meta-job-list)
[![npm](https://img.shields.io/npm/v/@jacobbubu/meta-job-list.svg)](https://www.npmjs.com/package/@jacobbubu/meta-job-list/)

> Combine JobList and MergedModel to implement a JobList that cleans up jobs based on the number of how many peers been synced.

## Intro.

I use a MergedModel to keep track of how many peers have synced for each job, so I can boldly delete the job.

`MetaJobList` is a class that combine a jobList and a mergedModel that used to store meta data.

`CappedJobList` is more like an example to show how to use `MetaJobList`. it shows how to set a sync threshold. When the number of peers synced to a job reaches this threshold, we delete the job and `applyUpdate` will not accept any further updates to the job.

Please use the [example](./examples/ex1.ts) to understand how this logic works.
npm package: @jacobbubu/multiplex-pull
Description: [![Build Status](https://travis-ci.org/jacobbubu/multiplex-pull.svg)](https://travis-ci.org/NXMIX/jacobbubu/multiplex-pull) [![Coverage Status](https://coveralls.io/repos/github/NXMIX/jacobbubu/multiplex-pull/badge.svg)](https://coveralls.io/github/jacobb
Author: jacobbubu
Latest version: 1.0.1

# @jacobbubu/multiplex-pull

[![Build Status](https://travis-ci.org/jacobbubu/multiplex-pull.svg)](https://travis-ci.org/NXMIX/jacobbubu/multiplex-pull)
[![Coverage Status](https://coveralls.io/repos/github/NXMIX/jacobbubu/multiplex-pull/badge.svg)](https://coveralls.io/github/jacobbubu/multiplex-pull)
[![npm](https://img.shields.io/npm/v/@jacobbubu/multiplex-pull.svg)](https://www.npmjs.com/package/@jacobbubu/multiplex-pull/)

> A [multiplex](https://github.com/maxogden/multiplex) impementation that uses [pull-stream](https://github.com/pull-stream/pull-stream).

### Usage

```bash
npm install @jacobbubu/multiplex-pull
npm run example.ex1
```

```ts
import * as pull from 'pull-stream'
import { Multiplex, Channel } from '@jacobbubu/multiplex-pull'

const plex1 = new Multiplex()

const plex2 = new Multiplex(null, (channel: Channel, name: string) => {
  pull(
    channel.source,
    pull.collect((err, result) => {
      expect(err).toBeFalsy()
      expect(result.toString()).toEqual('plex1')
      done()
    })
  )
})

pull(p1.source, p2.sink)
pull(p2.source, p1.sink)

pull(pull.values(['plex1']), channelAt1.sink)
```
npm package: @jacobbubu/npm-name
Description: Check whether a package or organization name is available on npm
Author: Rong Shen
Latest version: 6.0.1

# npm-name [![Build Status](https://travis-ci.org/sindresorhus/npm-name.svg?branch=master)](https://travis-ci.org/sindresorhus/npm-name)

> Check whether a package or organization name is available on npm

## Install

```
$ npm install npm-name
```

## Usage

```js
const npmName = require('npm-name');

(async () => {
	// Check a package name
	console.log(await npmName('chalk'));
	//=> false


	// Check an organization name
	console.log(await npmName('@ava'));
	//=> false

	console.log(await npmName('@abc123'));
	//=> true


	const result = await npmName.many(['chalk', '@sindresorhus/is', 'abc123']);

	console.log(result.get('chalk'));
	//=> false

	console.log(result.get('@sindresorhus/is'));
	//=> false

	console.log(result.get('abc123'));
	//=> true

	try {
		await npmName('_ABC');
	} catch (error) {
		console.log(error.message);
		// Invalid package name: _ABC
		// - name cannot start with an underscore
		// - name can no longer contain capital letters
	}
})();
```

## API

### npmName(name, options?)

Check whether a package/organization name is available (not registered) on npm.

An organization name should start with `@` and should not be a scoped package.

Returns a `Promise<boolean>` of whether the given name is available.

#### name

Type: `string`

Name to check.

#### options

Type: `object`

##### registryUrl

Default: User's configured npm registry URL.

Registry URL to check name availability against.

**Note:** You're unlikely to need this option. Most use-cases are best solved by using the default. You should only use this option if you need to check a package name against a specific registry.

### npmName.many(names, options?)

Check whether multiple package/organization names are available (not registered) on npm.

Returns a `Promise<Map>` of name and status.

#### names

Type: `string[]`

Multiple names to check.

#### options

Type: `object`

Same as `npmName()`.

## Related

- [npm-name-cli](https://github.com/sindresorhus/npm-name-cli) - CLI for this module
npm package: @jacobbubu/pidfile
Description: [![Build Status](https://github.com/jacobbubu/pidfile/workflows/Build%20and%20Release/badge.svg)](https://github.com/jacobbubu/pidfile/actions?query=workflow%3A%22Build+and+Release%22) [![Coverage Status](https://coveralls.io/repos/github/jacobbubu/pidfil
Author: jacobbubu
Latest version: 1.0.0

# @jacobbubu/pidfile

[![Build Status](https://github.com/jacobbubu/pidfile/workflows/Build%20and%20Release/badge.svg)](https://github.com/jacobbubu/pidfile/actions?query=workflow%3A%22Build+and+Release%22)
[![Coverage Status](https://coveralls.io/repos/github/jacobbubu/pidfile/badge.svg)](https://coveralls.io/github/jacobbubu/pidfile)
[![npm](https://img.shields.io/npm/v/@jacobbubu/pidfile.svg)](https://www.npmjs.com/package/@jacobbubu/pidfile/)

> A simple pidfile generate module (ref. https://github.com/kesla/pidlockfile)

## Usage

``` ts
import * as path from 'path'
import { promises as fs } from 'fs'
import pidlock from '@jacobbubu/pidfile'

const main = async () => {
  const filename = path.join(__dirname, 'lock.pid')
  const unlock = await pidlock(path.join(__dirname, 'lock.pid'), { unlockOnExit: false })
  if (unlock instanceof Error) {
    // unlock is an Error object withe message 'Lockfile already acquired'
  } else {
    const pid = await fs.readFile(filename, 'utf8')
    console.log({ pidInFile: pid, pid: process.pid })
    unlock()
  }
}

main()
```

## Before push

Before pushing the code to GitHub, please make sure that `NPM_TOKEN` is configured in `https://github.com/__your_repo__/settings/secrets`, or you can do this through [`semantic-release-cli`](https://github.com/semantic-release/cli).
npm package: @jacobbubu/pull-abortable
Description: [![Build Status](https://github.com/jacobbubu/pull-abortable/workflows/Build%20and%20Release/badge.svg)](https://github.com/jacobbubu/pull-abortable/actions?query=workflow%3A%22Build+and+Release%22) [![Coverage Status](https://coveralls.io/repos/github/ja
Author: jacobbubu
Latest version: 1.0.1

# @jacobbubu/pull-abortable

[![Build Status](https://github.com/jacobbubu/pull-abortable/workflows/Build%20and%20Release/badge.svg)](https://github.com/jacobbubu/pull-abortable/actions?query=workflow%3A%22Build+and+Release%22)
[![Coverage Status](https://coveralls.io/repos/github/jacobbubu/pull-abortable/badge.svg)](https://coveralls.io/github/jacobbubu/pull-abortable)
[![npm](https://img.shields.io/npm/v/@jacobbubu/pull-abortable.svg)](https://www.npmjs.com/package/@jacobbubu/pull-abortable/)

> Rewriting the [pull-abortable](https://github.com/dominictarr/pull-abortable) with TypeScript.

# pull-abortable

a pull-stream that may be aborted from the outside.

## why rewriting?

* Familiarity with the original author's intent
* Strong type declarations for colleagues to understand and migrate to other programming languages

## example

``` js
import * as pull from 'pull-stream'
import Abortable from '@jacobbubu/pull-abortable'

const abortable = Abortable()
pull(
  source,
  abortable,
  sink
)
//at any time you can abort the pipeline,
//the source will be cleaned up, and any
//error will be passed to the sink next time it reads.
atAnyTime(function () {
  abortable.abort()
})

// abort the stream and end with an error
abortable.abort(new Error('example'))
```

## License

MIT
npm package: @jacobbubu/pull-bitflipper
Description: [![Build Status](https://github.com/jacobbubu/pull-bitflipper/workflows/Build%20and%20Release/badge.svg)](https://github.com/jacobbubu/pull-bitflipper/actions?query=workflow%3A%22Build+and+Release%22) [![Coverage Status](https://coveralls.io/repos/github/
Author: jacobbubu
Latest version: 1.0.0

# @jacobbubu/pull-bitflipper

[![Build Status](https://github.com/jacobbubu/pull-bitflipper/workflows/Build%20and%20Release/badge.svg)](https://github.com/jacobbubu/pull-bitflipper/actions?query=workflow%3A%22Build+and+Release%22)
[![Coverage Status](https://coveralls.io/repos/github/jacobbubu/pull-bitflipper/badge.svg)](https://coveralls.io/github/jacobbubu/pull-bitflipper)
[![npm](https://img.shields.io/npm/v/@jacobbubu/pull-bitflipper.svg)](https://www.npmjs.com/package/@jacobbubu/pull-bitflipper/)

> Rewritten [pull-bitflipper](https://github.com/dominictarr/pull-bitflipper) in TypeScript.

# pull-bitflipper

pull stream that randomly flips bits in input stream,
useful for testing authenticated cryptography.

## Example

``` js
import bitFlipper from '@jacobbubu/pull-bitflipper'

pull(
  // Create a source that calls a callback when it gets aborted.
  source(function onAbort(err) {
    // This should be called when the output fails because a bit was filpped.
  }),

  createEncryptStream(),

  // Pass in the probability that a particular message should
  // Contain a flipped bit.
  bitFlipper(prop = 0.1),

  createDecryptStream(),

  sink(function (err) {
    // The sink should error when the decryption stream
    // finds a packet that does not authenticate.
  })
)

```
npm package: @jacobbubu/pull-file
Description: [![Build Status](https://travis-ci.org/jacobbubu/pull-file.svg)](https://travis-ci.org/jacobbubu/pull-file) [![Coverage Status](https://coveralls.io/repos/github/jacobbubu/pull-file/badge.svg)](https://coveralls.io/github/jacobbubu/pull-file) [![npm](http
Author: jacobbubu
Latest version: 1.0.1

# @jacobbubu/pull-file

[![Build Status](https://travis-ci.org/jacobbubu/pull-file.svg)](https://travis-ci.org/jacobbubu/pull-file)
[![Coverage Status](https://coveralls.io/repos/github/jacobbubu/pull-file/badge.svg)](https://coveralls.io/github/jacobbubu/pull-file)
[![npm](https://img.shields.io/npm/v/@jacobbubu/pull-file.svg)](https://www.npmjs.com/package/@jacobbubu/pull-file/)

> Rewritten [pull-file](https://github.com/DamonOehlman/pull-file) in TypeScript.

## Usage

Please see https://github.com/jacobbubu/pull-file/blob/master/examples for the usage.
npm package: @jacobbubu/pull-hang
Description: [![Build Status](https://travis-ci.org/jacobbubu/pull-hang.svg)](https://travis-ci.org/jacobbubu/pull-hang) [![Coverage Status](https://coveralls.io/repos/github/jacobbubu/pull-hang/badge.svg)](https://coveralls.io/github/jacobbubu/pull-hang) [![npm](http
Author: jacobbubu
Latest version: 1.0.0

# @jacobbubu/pull-hang

[![Build Status](https://travis-ci.org/jacobbubu/pull-hang.svg)](https://travis-ci.org/jacobbubu/pull-hang)
[![Coverage Status](https://coveralls.io/repos/github/jacobbubu/pull-hang/badge.svg)](https://coveralls.io/github/jacobbubu/pull-hang)
[![npm](https://img.shields.io/npm/v/@jacobbubu/pull-hang.svg)](https://www.npmjs.com/package/@jacobbubu/pull-hang/)

> Written [pull-hang](https://github.com/dominictarr/pull-hang) in TypeScript.

# pull-hang

a pull-stream source that does nothing until you abort it.

``` js
import Hang from 'pull-hang'

const hang = Hang()
pull(
  hang
  pull.collect(function (err) {
    //this will never callback, until you call hang(true, cb)
  })
)

//abort the stream after a timeout.
setTimeout(function () {
  hang(true, function () {})
}, 100)

```

## License

MIT
npm package: @jacobbubu/pull-high-watermark
Description: [![Build Status](https://github.com/jacobbubu/pull-high-watermark/workflows/Build%20and%20Release/badge.svg)](https://github.com/jacobbubu/pull-high-watermark/actions?query=workflow%3A%22Build+and+Release%22) [![Coverage Status](https://coveralls.io/repos
Author: jacobbubu
Latest version: 1.0.0

# @jacobbubu/pull-high-watermark

[![Build Status](https://github.com/jacobbubu/pull-high-watermark/workflows/Build%20and%20Release/badge.svg)](https://github.com/jacobbubu/pull-high-watermark/actions?query=workflow%3A%22Build+and+Release%22)
[![Coverage Status](https://coveralls.io/repos/github/jacobbubu/pull-high-watermark/badge.svg)](https://coveralls.io/github/jacobbubu/pull-high-watermark)
[![npm](https://img.shields.io/npm/v/@jacobbubu/pull-high-watermark.svg)](https://www.npmjs.com/package/@jacobbubu/pull-high-watermark/)

> A starter project that makes creating a TypeScript module extremely easy.

## Intro.

This tool was modified from [typescript-library-starter](https://github.com/alexjoverm/typescript-library-starter), but I made the following revisions:

  - Use GitHub Actions instead of TravisCI
  - Used to develop Node.JS Module instead of packaging code for browser

## Usage

```bash
git clone https://github.com/jacobbubu/typescript-starter.git YOURFOLDERNAME
cd YOURFOLDERNAME
npm install
```

**Start coding!** `package.json` and entry files are already set up for you, so don't worry about linking to your main file, typings, etc. Just keep those files with the same name.

## Before push

Before pushing the code to GitHub, please make sure that `NPM_TOKEN` is configured in `https://github.com/__your_repo__/settings/secrets`, or you can do this through [`semantic-release-cli`](https://github.com/semantic-release/cli).
npm package: @jacobbubu/pull-length-prefixed
Description: [![Build Status](https://github.com/jacobbubu/pull-length-prefixed/workflows/Build%20and%20Release/badge.svg)](https://github.com/jacobbubu/pull-length-prefixed/actions?query=workflow%3A%22Build+and+Release%22) [![Coverage Status](https://coveralls.io/rep
Author: jacobbubu
Latest version: 1.0.2

# @jacobbubu/pull-length-prefixed

[![Build Status](https://github.com/jacobbubu/pull-length-prefixed/workflows/Build%20and%20Release/badge.svg)](https://github.com/jacobbubu/pull-length-prefixed/actions?query=workflow%3A%22Build+and+Release%22)
[![Coverage Status](https://coveralls.io/repos/github/jacobbubu/pull-length-prefixed/badge.svg)](https://coveralls.io/github/jacobbubu/pull-length-prefixed)
[![npm](https://img.shields.io/npm/v/@jacobbubu/pull-length-prefixed.svg)](https://www.npmjs.com/package/@jacobbubu/pull-length-prefixed/)

> A starter project that makes creating a TypeScript module extremely easy.

## Intro.

This tool was modified from [typescript-library-starter](https://github.com/alexjoverm/typescript-library-starter), but I made the following revisions:

  - Use GitHub Actions instead of TravisCI
  - Used to develop Node.JS Module instead of packaging code for browser

## Usage

```bash
git clone https://github.com/jacobbubu/typescript-starter.git YOURFOLDERNAME
cd YOURFOLDERNAME
npm install
```

**Start coding!** `package.json` and entry files are already set up for you, so don't worry about linking to your main file, typings, etc. Just keep those files with the same name.

## Before push

Before pushing the code to GitHub, please make sure that `NPM_TOKEN` is configured in `https://github.com/__your_repo__/settings/secrets`, or you can do this through [`semantic-release-cli`](https://github.com/semantic-release/cli).
npm package: @jacobbubu/pull-many
Description: [![Build Status](https://travis-ci.org/jacobbubu/pull-many.svg)](https://travis-ci.org/jacobbubu/pull-many) [![Coverage Status](https://coveralls.io/repos/github/jacobbubu/pull-many/badge.svg)](https://coveralls.io/github/jacobbubu/pull-many) [![npm](http
Author: jacobbubu
Latest version: 1.1.0

# @jacobbubu/pull-many

[![Build Status](https://travis-ci.org/jacobbubu/pull-many.svg)](https://travis-ci.org/jacobbubu/pull-many)
[![Coverage Status](https://coveralls.io/repos/github/jacobbubu/pull-many/badge.svg)](https://coveralls.io/github/jacobbubu/pull-many)
[![npm](https://img.shields.io/npm/v/@jacobbubu/pull-many.svg)](https://www.npmjs.com/package/@jacobbubu/pull-many/)

> Rewritten [pull-many](https://github.com/pull-stream/pull-many) in typescript for personal study.

## Usage

```ts
import * as pull from 'pull-stream'
import many from 'pull-many'

pull(
  many([pull.values([1, 2, 3]), pull.values([1, 3, 5]), pull.values([2, 4, 6])]),
  pull.collect(function(err, ary) {
    if (err) throw err
    console.log(ary)
    //=> [1, 1, 2, 2, 3, 4, 3, 5, 6]
  })
)
```
npm package: @jacobbubu/pull-merge
Description: [![Build Status](https://github.com/jacobbubu/pull-merge/workflows/Build%20and%20Release/badge.svg)](https://github.com/jacobbubu/pull-merge/actions?query=workflow%3A%22Build+and+Release%22) [![Coverage Status](https://coveralls.io/repos/github/jacobbubu/
Author: jacobbubu
Latest version: 1.0.2

# @jacobbubu/pull-merge

[![Build Status](https://github.com/jacobbubu/pull-merge/workflows/Build%20and%20Release/badge.svg)](https://github.com/jacobbubu/pull-merge/actions?query=workflow%3A%22Build+and+Release%22)
[![Coverage Status](https://coveralls.io/repos/github/jacobbubu/pull-merge/badge.svg)](https://coveralls.io/github/jacobbubu/pull-merge)
[![npm](https://img.shields.io/npm/v/@jacobbubu/pull-merge.svg)](https://www.npmjs.com/package/@jacobbubu/pull-merge/)

> Rewriting the [pull-merge](https://github.com/dominictarr/pull-merge) with TypeScript.

# pull-merge

merge sorted pull-streams into one pull stream, while maintaining back-pressure.
Source pull streams MUST be in order.

## why rewriting?

* Familiarity with the original author's intent
* Strong type declarations for colleagues to understand and migrate to other programming languages

## example

``` ts
import * as pull from 'pull-stream'
import merge from '@jacobbubu/pull-merge'

pull(
  merge(pull.values([1, 5, 6]), pull.values([2, 4, 7])),
  pull.collect(function (err, ary) {
    if(err) throw err

    console.log(ary)
    //=> [1, 2, 4, 5, 6, 7]
  })
)

```

## signatures

### merge(left, right, compare?)

return a stream that is the merge of left and right streams.
merge pulls a chunk from both `left` and `right` and then
compares them. `compare` has the same signature as `Array#sort(compare)`.

If the two chunks are compared the same, the chunk from the right stream
is taken, but the left chunk is dropped.

Otherwise, the lowest chunk is passed to the stream.

### merge([streams...], compare?)

Merge a collection of steams. This calls the first signature recursively.


## License

MIT
npm package: @jacobbubu/pull-mesh
Description: [![Build Status](https://github.com/jacobbubu/pull-mesh/workflows/Build%20and%20Release/badge.svg)](https://github.com/jacobbubu/pull-mesh/actions?query=workflow%3A%22Build+and+Release%22) [![Coverage Status](https://coveralls.io/repos/github/jacobbubu/pu
Author: jacobbubu
Latest version: 3.1.1

# @jacobbubu/pull-mesh

[![Build Status](https://github.com/jacobbubu/pull-mesh/workflows/Build%20and%20Release/badge.svg)](https://github.com/jacobbubu/pull-mesh/actions?query=workflow%3A%22Build+and+Release%22)
[![Coverage Status](https://coveralls.io/repos/github/jacobbubu/pull-mesh/badge.svg)](https://coveralls.io/github/jacobbubu/pull-mesh)
[![npm](https://img.shields.io/npm/v/@jacobbubu/pull-mesh.svg)](https://www.npmjs.com/package/@jacobbubu/pull-mesh/)

> 创建一个通信网格 (mesh)，用于在不确定的网络连通的环境下实现两个 pull duplex 通信

## 概述

`pull-mesh` 试图解决一个问题，即两个仅仅知道名字(URI)的 duplex 如何通过一个相互连通的网格来建立连接。如下图: `duplexA` 和 `duplexB` 之间存在一个网格(mesh)，网格各个节点之间有些相连，有些是中断的。只要存在一条相连的通路，`duplexA` 和 `duplexB` 即可相互连接。

![网格示意](./docs/mesh.drawio.svg)

## 示例

[两节点直连](./examples/two-nodes.ts)的例子展示了最简单的情况。其示意图如下:
![两节点示意](./docs/port.drawio.svg)

`one` 和 `two` 分别是两端的 duplex 名字，我们用 `sourceURI` 来标识。`one` 和 `two` 为了连接到 mesh，首先需要和它们所知道的 `meshNode` 建立连接。这是通过 `meshNode.createPortStream(sourceURI, destURI)` 来完成的。`destURI` 标记了当前 duplex 希望连接的远端的 duplex 的名字。在整个 mesh 网格内，URI 应该是唯一的。`one` 和 `two` 不知道对方的具体的位置或地址，消息由 `meshNode` 之间转发来完成。

`portStream` 可以在 `meshNode` 事先创建好，也可以通过 `meshNode` 在构造时传入的 `onOpenPort` 回调函数来创建。[两节点直连](./examples/two-nodes.ts) 演示了这种用法。

`meshNode` 之间会创建 `relayStream`。`relayStream` 负责将两个 `meshNode` 连接，它也仅仅负责这件事，对所要传播的 `message` 的语义并不关心。

还有两个例子演示了更复杂一些的用法:
* [同步 scuttlebutt 数据结构](./examples/model.ts): 这个例子演示了如何在两个节点间同步 scuttlebutt model。
* [三节点同步](./examples/three-nodes.ts): 顾名思义，从两节点变成三节点。

### 节点间消息是如何传播的

每个消息都有一个全网唯一的 id。`meshNode` 在收到消息后，首先会发给所有它所拥有的的 `portStream`，如果没有一个 `portStream` 能处理，则逐一发给它的 `relayStream`。这些 `relayStream` 将把消息传递给其他 `meshNode`，继而重复上述步骤。为了避免消息在 `meshNode` 之间重复传递，每个 `relayStream` 确保在一段时间内具有相同 `id` 的消息仅仅传输一次，重复收到的消息将被丢弃。

## 注意

该模块目前仅仅出于验证概念阶段，大量的测试用例和连通检测功能还有待完善。
npm package: @jacobbubu/pull-mux
Description: [![Build Status](https://travis-ci.org/jacobbubu/pull-mux.svg)](https://travis-ci.org/jacobbubu/pull-mux) [![Coverage Status](https://coveralls.io/repos/github/jacobbubu/pull-mux/badge.svg)](https://coveralls.io/github/jacobbubu/pull-mux) [![npm](https://
Author: jacobbubu
Latest version: 1.1.0

# @jacobbubu/pull-mux

[![Build Status](https://travis-ci.org/jacobbubu/pull-mux.svg)](https://travis-ci.org/jacobbubu/pull-mux)
[![Coverage Status](https://coveralls.io/repos/github/jacobbubu/pull-mux/badge.svg)](https://coveralls.io/github/jacobbubu/pull-mux)
[![npm](https://img.shields.io/npm/v/@jacobbubu/pull-mux.svg)](https://www.npmjs.com/package/@jacobbubu/pull-mux/)

> Mux and demux for pull-stream

## Intro.

This repo. is highly inspired by [pull-mux](https://github.com/nichoth/pull-mux) but support add sun stream dynamically.

## Usage

Please see the [examples](https://github.com/jacobbubu/pull-mux/tree/master/examples) for the usage.
npm package: @jacobbubu/pull-pair
Description: [![Build Status](https://travis-ci.org/jacobbubu/pull-pair.svg)](https://travis-ci.org/jacobbubu/pull-pair) [![Coverage Status](https://coveralls.io/repos/github/jacobbubu/pull-pair/badge.svg)](https://coveralls.io/github/jacobbubu/pull-pair) [![npm](http
Author: jacobbubu
Latest version: 1.0.1

# @jacobbubu/pull-pair

[![Build Status](https://travis-ci.org/jacobbubu/pull-pair.svg)](https://travis-ci.org/jacobbubu/pull-pair)
[![Coverage Status](https://coveralls.io/repos/github/jacobbubu/pull-pair/badge.svg)](https://coveralls.io/github/jacobbubu/pull-pair)
[![npm](https://img.shields.io/npm/v/@jacobbubu/pull-pair.svg)](https://www.npmjs.com/package/@jacobbubu/pull-pair/)

> Rewritten [pull-pair](https://github.com/dominictarr/pull-pair) in TypeScript.

# pull-pair

A pair of {source, sink} streams that are internally connected,
(what goes into the sink comes out the source)

This can be used to construct pipelines that are connected.

``` js
import * as pull from 'pull-stream'
import { pair } from '@jacobbubu/pull-pair'

const pa = pair()

// Read values into this sink...
pull(pull.values([1, 2, 3]), pa.sink)

// But that should become the source over here.
pull(pa.source, pull.collect(function (err, values) {
  if(err) throw err
  console.log(values) //[1, 2, 3]
}))

```

This is particularly useful for creating duplex streams especially
around servers. Use `pull-pair/duplex` to get two duplex streams
that are attached to each other.

``` js
import { duplex } from '@jacobbubu/pull-pair'

const dup = duplex()

// The "client": pipe to the first duplex and get the response.
pull(
  pull.values([1,2,3]),
  dup[0],
  pull.collect(console.log) // => 10, 20, 30
)

// The "server": pipe from the second stream back to itself
// (in this case) applying a transformation.
pull(
  dup[1],
  pull.map(function (e) {
    return e*10
  }),
  dup[1]
)
```
npm package: @jacobbubu/pull-plex
Description: [![Build Status](https://github.com/jacobbubu/pull-plex/workflows/Build%20and%20Release/badge.svg)](https://github.com/jacobbubu/pull-plex/actions?query=workflow%3A%22Build+and+Release%22) [![Coverage Status](https://coveralls.io/repos/github/jacobbubu/pu
Author: jacobbubu
Latest version: 1.6.1

# @jacobbubu/pull-plex

[![Build Status](https://github.com/jacobbubu/pull-plex/workflows/Build%20and%20Release/badge.svg)](https://github.com/jacobbubu/pull-plex/actions?query=workflow%3A%22Build+and+Release%22)
[![Coverage Status](https://coveralls.io/repos/github/jacobbubu/pull-plex/badge.svg)](https://coveralls.io/github/jacobbubu/pull-plex)
[![npm](https://img.shields.io/npm/v/@jacobbubu/pull-plex.svg)](https://www.npmjs.com/package/@jacobbubu/pull-plex/)

> A multiplex solution for pull-stream.

# Usage

``` ts
import * as pull from 'pull-stream'
import { Plex, Channel } from '../src'

const plex1 = new Plex('p1')
const plex2 = new Plex('p2')

const a = plex1.createChannel('a')
pull(pull.values([1, 2, 3]), a.sink)
pull(
  a.source,
  pull.collect((_, ary) => {
    console.log(`received data on channel ${a.name}/${plex1.plexName}:`, ary)
  })
)

plex2.on('channel', (channel: Channel) => {
  pull(
    channel.source,
    pull.collect((_, ary) => {
      console.log(`received data on channel ${channel.name}/${plex2.plexName}:`, ary)
    })
  )
  pull(pull.values([4, 5, 6]), channel.sink)
})

pull(plex1, plex2)
pull(plex2, plex1)
```