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

@fcanvas/communicate

v1.1.7

Published

This package allows a simple connection between MessageChannel-based channels such as WebWorker

Downloads

173

Readme

@fcanvas/communicate

This package allows a simple connection between MessageChannel-based channels such as WebWorker, IFrame...

View source code at: https://github.com/fcanvas/fcanvas

NPM Size Download

Install

pnpm add @fcanvas/communicate

Usage

With MessageChannel

// listen run function 
import { listen } from "@fcanvas/communicate"


const { port1, port2 } = new MessageChannel()
port1.start()
port2.start()

listen(port1, "hello world", (name: string) => {
  console.log(`run: hello world '${name}'`)

  return "run done"
})

// call function
import { put } from "@fcanvas/communicate"
console.log(await put(port2, "hello world", "Shin")) // "run done"

With WebWorker

worker.ts

import { listen } from "@fcanvas/communicate"

listen(self, "hello world", (name: string) => {
  console.log(`run: hello world '${name}'`)

  return "run done"
})

main.ts

import Worker from "./worker?worker"
import { put } from "@fcanvas/communicate"

const worker = new Worker()

console.log(await put(worker, "hello world", "Shin")) // "run done"

2-way use

You can use both ways set listen to Worker or Threat

worker.ts

import { listen } from "@fcanvas/communicate"

listen(self, "hello world", async (name: string) => {
  console.log(`run: hello world '${name}'`)
  
  console.log("input: ", await put(self, "get input"))
  
  return "run done"
})

main.ts

import Worker from "./worker?worker"
import { put } from "@fcanvas/communicate"

const worker = new Worker()
listen(worker, "get input", () => {
  return document.querySelector("#input").value
})

console.log(await put(worker, "hello world", "Shin")) // "run done"

Docs

@fcanvas/communicate provides 3 methods that can be used anywhere

listen

This function to listen and process calls from put and pit - like is server

function listen(
  port: LikeMessagePort, // current port to listen and process. Example `self` in `worker`
  name: string, // the name of the listen
  cb: Function, // its handler function takes a sequence of `arguments` passed from `put` or `pit` and returns a result either a `config` or a `promise`
  options?: {
    once?: boolean // if this option is enabled the listener will self-destruct after being called once by `put` or `pit`
  }
): StopListen/** @type () => void */

| Name | Type | Description | | --- | --- | --- | | port | LikeMessagePort | Current port to listen and process. Example self in worker | | name | string | The name of the listen | | cb | Function | Its handler function takes a sequence of arguments passed from put or pit and returns a result either a config or a Promise | options | { once?: boolean } | if once: true is enabled the listener will self-destruct after being called once by put or pit

cb normally returns primitive values ​​but if it returns a value that needs transfer like Offscreen or ArrayBuffer return an Options

interface Options {
  return: any // your value return
  transfer?: Transferable[] // value transfer
  targetOrigin?: string // This option is only available if communicating with `IFrame`
}
listen(self, "get buffer", async () => {
  const buffer = new Uint8Array([1, 0xf, 0x3]).buffer
  return {
    return: buffer,
    transfer: [buffer]
  }
})

listen returns a noop ​​function that, when called, cancels listening

put

This function sends a request to listen and returns a promise that is the result of cb of listen - like is client

function put<Fn extends (...args: any[]) => any>(
  port: LikeMessagePort, // current port to listen and process. Example `self` in `worker`
  name: string, // name of call
  ...args: Parameters<Fn>
): Promise<ReturnType<Fn>>

function put<Fn extends (...args: any[]) => any>(
  port: LikeMessagePort, // current port to listen and process. Example `self` in `worker`
  options: {
    name: string // name of call
    timeout?: number // timeout
    signal?: AbortSignal, // controller
    transfer?: Transferable[], // value transfer
    targetOrigin?: string  // This option is only available if communicating with `IFrame`
  },
  ...args: Parameters<Fn>
): Promise<ReturnType<Fn>>

| Name | Type | Description | | --- | --- | ---- | | port | LikeMessagePort | Current port to listen and process. Example self in worker | | name | string | name of call | | options.name | string | is like name | options.timeout | number? | timeout listen returns a result. if timeout without response will generate error Error('timeout') | | options.signal | AbortSignal? | if canceled the function will generate an error Error('aborted') | | options.transfer | Transferable[]? | values ​​to transfer | | options.targetOrigin | string? | This option is only available if communicating with IFrame | | ...args | any[] | values ​​to send to listen |

put returns the value that cb of listen returns

pit (as ping)

This is a shortened function of put that takes no response. it also doesn't care if the call has been sent to listen or not

The options of this function are identical to put except that it does not accept options.timeout, option.signal and returns nothing.

wait

This function waits for a call from ping or put

await wait(port1, "ready", 60_000)

console.log("Done")
//

await put(port2, "ready") // after promise resolve console.log("Done") start run

TypeScript

This plugin also supports TypeScript strong and weak type inference

Weak inference with function:

interface FnHello {
  (name: string): string
}

listen<FnHello>(self, "hello", (name /** @type string */) => {
  return 'done' /** @type string */
})

put<FnHello>(self, "hello", "Shin") // ✔ ok
put<FnHello>(self, "hello", 0) // ❗ error

Strong inference with Record:

interface Connect {
  hello(name: string): void
}

listen<Connect>("self", "hello", () => {}) // ✔ ok
listen<Connect>("self", "hellx", () => {}) // ❗ error

put<Connect>(self, "hello", "Shin") // ✔ ok
put<Connect>(self, "hello", 0) // ❗ error
put<Connect>(self, "hello") // ❗ error
put<Connect>(self, "hellx", "Shin") // ❗ error

Since some limited features of typescript cause mixed types to be incorrect, I have added a new syntax i.e. put, ping and listen functions will return a function call after calling the function that will be the real result

await put<{
  getValue(): string
  getNumber(): number
  setValue(val: string): void
  setNumber(val: number): void
}>(self)("getValue") // string

await put<{
  getValue(): string
  getNumber(): number
  setValue(val: string): void
  setNumber(val: number): void
}>(self)("setValue", "Hello world") // only accept string
listen<{
  getValue(): string
  getNumber(): number
  setValue(val: string): void
  setNumber(val: number): void
}>(self)("getValue", () => {
  return "hello" // accept string
})

listen<{
  getValue(): string
  getNumber(): number
  setValue(val: string): void
  setNumber(val: number): void
}>(self)("setValue", value => {
  // value is string
})

Copyright

MIT - (c) 2022-now Tachibana Shin (橘しん)