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 🙏

© 2025 – Pkg Stats / Ryan Hefner

ray-worker

v1.0.4

Published

ray worker

Readme

ray-worker

install

npm i --save ray-worker

props

|params|type|default|descr| |------|------|------|------| | children | node or func | - | 内容区,自定义 worker接收展示, func: (workerState) => {} | | workerRes | string or func | - | 创建worker,当为 string时,表示 worker 路径,当为 function时,可将整个worker包装进一个 function进行创建 | | options | object | - | worker参数,如: { name: 'myworker' } | | worker | object | - | 自定义 Worker 实例,如:采用 worker-loader加载worker时,可创建后传递 | | parser | func | - | data 解析器,解析从 Worker 中收到的message | | onMessage | func | - | 处理从 worker 接收到的消息数据 | | onError | func | - | worker错误处理 | | serializer | func | v => v | 序列化或者处理发送至 worker 的数据, 在 手动调用 postMessage 之后处理data | | forceMessage | bool | false | 强制接收消息,即:即使dom没有加载完成,也接收 worker 消息 | | preventWorker | bool | - | 不给 children 注入 worker 的属性,当采用 ref 方式处理worker时,可以设置为 true |

注意: 默认情况下,只有 dom 加载完成之后,才接收 worker 中的消息,如果 设置 forceMessagetrue 时,则只要 worker 创建,则可接收。

workerstate

|params|type|default|descr| |------|------|------|------| | messages | array | [] | 从worker中接收到的所有的数据日志,{ data, date } | | errors | array | [] | 从worker中接收到的所有的错误信息,{ error, date } | | data | any | undefined | 从worker中接收到的数据,最新数据 | | error | any | undefined | 从worker中接收到的错误信息,最新错误信息 | | updateTime | Date | undefined | 更新日期,worker发送数据或错误时的当前日期 | | lastPostTime | Date | undefined | 最后一次发送向worker数据的日期 | | postMessage | func: (data) => {} | - | 向 worker 发送消息 |

注意: 默认在 componentWillUnmount 中执行了 worker.terminate,同时向 worker 发送了 type = 'CLOSED'的数据,用于告知worker执行关闭。如果需要关闭 worker,则自行在worker中进行处理,如:

worker.js


self.addEventListener('message', e => {
  if (!e) {
    return;
  }
  let data = e.data;

  if (data && data.type === 'CLOSED'){
    self.close(); // Terminates the worker.
  }
  console.log('Received msg from UI:', data);
  postMessage(data + random());
});

USAGE

  • basic

app.js

import React, { Component } from 'react';
import RWorker from 'ray-worker';
import Button from './Button';

/**
 * 采用直接导入 worker 的方式
 *
 * @class WorkerDemo
 * @extends {Component}
 */
class WorkerDemo extends Component {
  render() {
    return (
      <RWorker workerRes="/demo1.js">
        {({ data, error, postMessage, updatedAt, lastPostTime }) => (
          <div className="worker-msg-box">
            {data && (
              <div>
                <strong>[采用普通loader进行]Received some data:</strong>
                <pre>{JSON.stringify(data, null, 2)}</pre>
              </div>
            )}
            <Button updatedAt={updatedAt} lastPostTime={lastPostTime} postMessage={postMessage} />
          </div>
        )}
      </RWorker>
    );
  }
}

WorkerDemo.propTypes = {};

export default WorkerDemo;

demo1.js (worker)

function random() {
  const i = Math.random() * 100 + 1;
  return `ilex- ${parseInt(i)}`;
}

self.addEventListener('message', e => {
  if (!e) {
    return;
  }
  let data = e.data;

  console.log('Received msg from UI:', data);

  postMessage(data + random());
});
  • use normal module

将 worker 作为一个 function 进行

app.js

import React, { Component } from 'react';
import RWorker from 'ray-worker';
import Button from './Button';
import demo from './demo';

/**
 * 采用 模块加载的方式
 *
 * @class WorkerDemo
 * @extends {Component}
 */
class WorkerDemo extends Component {
  render() {
    return (
      <RWorker workerRes={demo}>
        {({ data, error, postMessage, updatedAt, lastPostTime }) => (
          <div className="worker-msg-box">
            {data && (
              <div>
                <strong>Received some data:</strong>
                <pre>{JSON.stringify(data, null, 2)}</pre>
              </div>
            )}
            <Button updatedAt={updatedAt} lastPostTime={lastPostTime} postMessage={postMessage} />
          </div>
        )}
      </RWorker>
    );
  }
}

WorkerDemo.propTypes = {};

export default WorkerDemo;

demo.js (worker)


export default () => {
  function random() {
    const i = Math.random() * 100 + 1;
    return `ilex- ${parseInt(i)}`;
  }
  self.addEventListener('message', e => {
    if (!e) {
      return;
    }
    let data = e.data;

    console.log('Received msg from UI:', data);

    postMessage(data + random());
  });
};
  • worker-loader

app.js

import React, { Component } from 'react';
import RWorker from 'ray-worker';
import Button from './Button';
import Worker from './demo.worker.js';

/**
 * 采用 worker loader 方式
 *
 * @class WorkerLoaderDemo
 * @extends {Component}
 */
class WorkerLoaderDemo extends Component {

  constructor(props) {
    super(props);
    this.worker = new Worker();
  }

  render() {
    return (
      <RWorker worker={this.worker}>
        {({ data, error, postMessage, updatedAt, lastPostTime }) => (
          <div className="worker-msg-box">
            {data && (
              <div>
                <strong>[采用worker-loader进行]Received some data:</strong>
                <pre>{JSON.stringify(data, null, 2)}</pre>
              </div>
            )}
            <Button updatedAt={updatedAt} lastPostTime={lastPostTime} postMessage={postMessage} />
          </div>
        )}
      </RWorker>
    );
  }
}

WorkerLoaderDemo.propTypes = {};

export default WorkerLoaderDemo;

demo.worker.js (worker)

worker 中可以采用 es6 模块

import { random } from './_third';

// function random() {
//   const i = Math.random() * 100 + 1;
//   return `ilex- ${parseInt(i)}`;
// }

self.addEventListener('message', e => {
  if (!e) {
    return;
  }
  let data = e.data;

  if (data && data.type === 'CLOSED'){
    self.close(); // Terminates the worker.
  }

  console.log('Received msg from UI:', data);

  postMessage(data + random());
});

扩展

  • DataPane
  • Pending
  • WError

使用datapane, app.js

import React, { Component } from 'react';
import RWorker from 'ray-worker';
import Worker from './inner.worker.js';

const { Pending, DataPane, WError } = RWorker;

/**
 * 采用 worker loader 方式
 *
 * @class WorkerInnerDemo
 * @extends {Component}
 */
class WorkerInnerDemo extends Component {

  constructor(props) {
    super(props);
    this.worker = new Worker();
  }

  render() {
    return (
      <RWorker worker={this.worker}>
        <DataPane>
          {
            (data, workerState) => (
              <div className="worker-msg-box">
                <div>auto data:{data}</div>
                <div className="all-msg">
                  <p>所有数据</p>
                  {JSON.stringify(workerState)}
                </div>
              </div>
            )
          }
        </DataPane>
      </RWorker>
    );
  }
}

WorkerInnerDemo.propTypes = {};

export default WorkerInnerDemo;

inner.worker.js (worker)

import { random } from './_third';

self.addEventListener('message', e => {
  if (!e) {
    return;
  }
  let data = e.data;

  if (data && data.type === 'CLOSED'){
    self.close(); // Terminates the worker.
  }

  console.log('Received msg from UI:', data);
  postMessage(data + random());
});

postMessage(`auto data ${random()}`);

setInterval(() => {
  postMessage(`auto data ${random()}`);
}, 2000);

WorkerPlugin

import React, { Component } from 'react';
import { WorkerPlugin } from 'ray-worker';
import demo from './workers/demo';

/**
 * 采用 worker plugin
 *
 * @class WorkerDemo
 * @extends {Component}
 */
class WorkerDemo extends Component {

  constructor(props) {
    super(props);
    this.state = {
      data: undefined
    };
    this.worker = new WorkerPlugin({
      workerRes: demo,
      onMessage: this.onMessage
    });
  }

  componentWillUnmount() {
    this.worker.destroy();
  }

  onMessage = (data) => {
    this.setState({
      data
    });
  }

  onClick = () => {
    this.worker.postMessage('hello');
  }

  render() {
    const { data } = this.state;
    return (
      <div className="worker-msg-box">
        {data && (
          <div>
            <strong>Received some data:</strong>
            <pre>{JSON.stringify(data, null, 2)}</pre>
          </div>
        )}
        <div className="action-button">
          <button onClick={this.onClick}>发送消息</button>
        </div>
      </div>
    );
  }
}

WorkerDemo.propTypes = {};

export default WorkerDemo;
  • params
{
  workerRes: 'string|func',
  options: 'object',
  worker: 'any',
  parser: 'func',
  onMessage: 'func',
  onStateChange: 'func',
  serializer: 'func',
  onError: 'func'
}
  • methods
postMessage()
getWorkerState()
destroy()

UIWorkerFactory

自行处理 主线程 worker UI

import React, { Component } from 'react';
import { UIWorkerFactory } from 'ray-worker';
import Worker from './workers/inner.worker.js';

/**
 * 采用 worker loader 方式
 *
 * @class NonUIWorkerDemo
 * @extends {Component}
 */
class NonUIWorkerDemo extends Component {

  constructor(props) {
    super(props);
    this.worker = new Worker();
    this.uiWorkerFactory = new UIWorkerFactory({
      worker: this.worker,
      onMessage: this.onMessage,
      onError: this.onError
    });
    this.state = {
      messages: [],
      msg: ''
    };
  }

  onMessage = (msg) => {
    this.setState(prevState => ({
      messages: [
        ...prevState.messages,
        msg
      ],
      msg
    }));
  }

  onError = (err) => {
    console.log(err);
  }

  render() {
    return (
      <div className="worker-msg-box">
        <div>current message:{this.state.msg}</div>
        <div className="all-msg">
          <p>所有数据:</p>
          {JSON.stringify(this.uiWorkerFactory.workerState, null, 2)}
        </div>
      </div>
    );
  }
}

NonUIWorkerDemo.propTypes = {};

export default NonUIWorkerDemo;

注意

children 为function时,参数为 RayWorker 整个 state; 当为 普通react组件时,默认注入 RayWorker 整个state

其它情况,如果要使用 RayWorker state,则可以使用 getWorkerState 方法获取。

import RWorker from 'ray-worker';

const workerState = this.rworkerRef.getWorkerState();

<RWorker ref={node => this.rworkerRef = node}>

Lecense

MIT