npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

socket-generator

v1.1.0

Published

Turn any async generator / function into a Websocket stream in 2 lines.

Downloads

18

Readme

socket-generator

Turn any JS/TS async generator / function into a typed Websocket stream in 2 lines.

Coverage Status npm version Build Passing

Why this?

There wasn't any easy way to turn my server's simple async generator functions into a Websocket stream without a lot of fuss, and Socket.io is arguably the best Websocket streaming library, so why not make it easy to glue them together!? Also,

  • Mix and match plain async functions with async generators
  • Bi-directional: frontends can be endpoints and servers can be clients, if you want
  • Request / Response paradigm you're used to, but over Websockets with fallback to HTTP long polling
  • Same mechanics you know and love from async generators, try/catch error handling etc.
  • Zero dependencies (except implicitly on Socket.io >= v4)
  • 100% line + branch test coverage, because you deserve it :-)

Hello World Example:

Define an async generator function for streaming (usually only on the server)

async function* wordGenerator(input: string) {
  const words = input.split(' ');
  for (const word of words) {
    yield word;
  }
}

Define a shared contract where client sends 1 string parameter and endpoint streams / yields strings back

const helloContract = newContract<[string], string, undefined>('hello');

Define a client (usually just on the frontend) that can issue requests

const helloClient = helloContract.newClient(clientSocket, 1);

Define an endpoint (usually just on the server) that can respond to requests and define the generator function

helloContract.newEndpoint(wordGenerator).bindClient(serverSocket);

Client streams the server's wordGenerator function remotely as if it was local!

const wordGenerator = helloClient('hello world');
for await (const word of wordGenerator) {
  console.log(word);
}

See __tests__/examples.test.ts for all advanced usages and how to create Socket.io client / server sockets

Javascript note: If you're not using Typescript :-(, just remove anywhere you see <> in example code and it'll work just the same, though you won't get typing benefits of a shared client / server Contract.

Install

Just install the NPM package with:

npm i socket-generator

API

newContract

Creates a new Contract which is a shared type agreement between Socket.io client and endpoints. Because Socket.io is bidirectional, front-ends may be endpoints and servers may be clients too! A client initializes a request by sending PARAMS and the endpoint responds with a stream of YIELDs ending in a RETURN.

@param uniqueName A unique name for this Socket.io client / endpoint contract

@returns A Contract instance that either client or endpoint can further instantiate with more context

function newContract<PARAMS extends unknown[], YIELD, RETURN>(uniqueName: string)

API Types

Contract

An instantiated Contract is a factory pattern than can then be used to either create the ClientFn (after binding a client Socket.io socket) or an Endpoint (after binding both a server Socket.io socket and the contract's responseGenerator implementation)

type Contract<PARAMS extends unknown[], YIELD, RETURN> = {
  newClient: (
    socket: ClientSocket<any, any>, 
    timeoutMs?: number) => ClientFn<PARAMS, YIELD, RETURN>,
  newEndpoint: (
    responseGenerator: (...req: PARAMS) => AsyncGenerator<YIELD, RETURN, undefined> | Promise<RETURN>,
    logger?: (msg: string) => void) => Endpoint
}

ClientFn

An instance of an async generator that can be iterated to stream YIELDs from the parent Contract's endpoint, ending with a RETURN value when done

type ClientFn<PARAMS extends unknown[], YIELD, RETURN> = (
  ...req: PARAMS
) => AsyncGenerator<YIELD, RETURN, undefined>

Endpoint

After initializing contract.newEndpoint, you can bind many incoming clients' sockets to the new Endpoint by calling bindClient.

type Endpoint = {
  bindClient: (socket: ServerSocket) => void
}

Supported parameter / yield return types

Since all data must be passed over the wire, only JSON-supported types are allowed, except for the special case of yielding or returning undefined, which is supported on top of all JSON-compatible types.

More Links

See official Socket.io v4 documentation.

Contributing

I can't think of what more this lib needs but if you can think of something cool, open a pull request or Issue.