銀の弾丸

プログラミングに関して、いろいろ書き残していければと思っております。

mochaとBabelでESモジュールをテストする

f:id:takamints:20181110123153j:plain

npm内のESモジュールをmochaでテストしようとしたのですが、上手くいかない。 Babelが必要なんですね。mochaのテストスクリプトをbabelで変換しないと import / export が構文エラーになってしまうのです。

事前に変換しなくても、@babel/register を使ってmocha実行時に変換しながらテストできるらしいのですが、 そのやり方を調べてみると、断片的な情報がバラバラとある状態で「ココだけ見てやったらバッチリOK」ってな情報源には出会えずじまい。 あっちやこっちを見ながら最終的には何とかなりましたが、結構苦労したので備忘録としてまとめてここに書いておきます。



目次

前提条件

  • 使用するBabelのバージョンは7。
  • テストランナーは mocha。
  • テストはnode.jsで動かします(ブラウザで行うテストじゃないです)。
  • テスト対象はnpm内の ESモジュールのクラスです。

必要なモジュール

上記の変換を行う為に最低限必要なモジュールは以下4つ。 各モジュールのバージョンは現在確認したワタシの環境のものです。おそらく現時点での最新バージョン。

  • @babel/core - 7.3.4
  • @babel/register - 7.0.0
  • babel-preset-env - 1.7.0
  • mocha - 6.0.2

飽くまでも最低限のモジュールです。ほかに必要になるモジュールがあるかもしれません。 例えばワタシはアサーションchaiを使いますし、分割代入などを使う場合はまた別のが必要になったりするんじゃないかなと思います。

npmに上記モジュールをインストールするには以下のコマンドでOK。

npm i -D @babel/core @babel/register babel-preset-env mocha

注意:ここに上げた最低限のモジュールは、次項の .babelrc の記述内容に依存しているかも知れません。 そういう意味で、この記事は「こうやればできた」に過ぎないかもしれないので注意してください。 今のところこれ以上深堀をしていないので。

Babel の設定

Babelの変換を定義する .babelrc も必要です。 babel-preset-envを指定しています。 このため依存モジュールにbabel-preset-env が必要だったのだと思います。

.babelrc

{
  "presets": [
    [
      "env",
      {
        "targets": {
          "node": true
        },
        "useBuiltIns": true
      }
    ]
  ]
}


テスト対象のESモジュールとテストスクリプト

テスト対象のESモジュール

src/my-class.js

"use strict";

/**
 * MyClass.
 * @constructor
 */
export function MyClass() {}

/**
 * bar.
 * @returns {string} "foo" を返す
 */
MyClass.prototype.bar = function() {
    return "foo";
};

mochaでESモジュールをテストするスクリプト

test/my-class.test.js

※ 以下、chaiを使っているので、npm i -D chai が必要ですよ。

"use strict";
import { assert } from "chai";
import { MyClass } from "../src/my-class.js";

describe("MyClass", () => {
    describe("#bar", () => {
        it("should returns 'foo'", () => {
            assert.equal( "foo", (new MyClass()).bar() );
        });
    });
});

mocha実行時のオプション

mocha実行時に変換するためには、以下のように --require オプションで @babel/register を指定します。

mocha --require @babel/register test/**/*.test.js

テスト対象はnpmなので、package.json のscripts を以下のように設定しておけば、npm test でテスト実行できますね。

{
  ~略~
  "scripts": {
    "test": "mocha --require @babel/register test/**/*.test.js"
  }
  ~略~
}

npmパッケージのダウンロード数をアカウント別に一括取得

f:id:takamints:20190209220050p:plain
Nervously Peeking Much Because I Love NPM

入門JavaScriptプログラミング
JD アイザック
翔泳社
売り上げランキング: 20,011

自分で公開しているパッケージのダウンロード数をまとめて取得したかったので、 npmのユーザーアカウントを指定して、そのアカウントが公開している全パッケージの直近ダウンロード数(前日・前週・前月)を表示するnpmパッケージを公開しました(ちょっとややこしいですね)。

目次

概要

npm-dlc というコマンドラインのツールです。npmユーザーの名前を指定して実行するとそのユーザーが公開しているパッケージの直近のダウンロード数を表示します。

npmではダウンロード数を取得するAPIはありますが、それ以外の情報を取得するのはありませんので、指定されたユーザーページをスクレイピングして、公開されているパッケージのリストを取得しています。

www.npmjs.com

インストール

npmでグローバルにインストールしてください。

$ npm install -g npm-dlc

使い方

グローバルインストールすると、‘npm-dlc‘ というコマンドが使えるようになります。 npmのユーザー名を指定すれば、そのユーザーが公開しているパッケージのダウンロード数を表形式で表示します。

$ npm-dlc <user-name>[ <user-name> ... ]

出力サンプル

以下は実際の出力結果(vzg03566は私です)。 各パッケージの最新バージョンと公開された大まかな時期も一緒に表示します。

$ npm-dlc vzg03566
 
Download count of public package published by vzg03566.
(https://www.npmjs.com/~vzg03566)
 
-------------------- ------- ------------ ----- ------ -------
NAME                 VERSION PUBLISHED    DAILY WEEKLY MONTHLY
-------------------- ------- ------------ ----- ------ -------
hash-arg             0.3.3   a year ago       0     17      65
list-it              0.4.1   2 years ago     17    101     324
aws-node-util        0.9.9   7 months ago     0     42     168
mz700-js             1.0.6   13 days ago      0    224    1042
yea-stringify        1.0.1   2 years ago      2      5       9
minty-mocha          1.0.0   2 years ago      0      3       6
fractional-timer     1.0.2   2 years ago      0      4      19
transworker          1.2.1   a month ago     12     19     103
b-box                0.1.2   9 months ago     0      7      23
dock-n-liquid        0.5.3   9 months ago     0     15      50
fullscrn             1.3.1   2 years ago      0      9      40
svg-z-order          1.2.1   2 years ago      2     16      55
parse-int-array      0.9.0   2 years ago      0      3       8
rough-name           1.0.0   2 years ago      1      3      15
exl                  0.1.0   8 months ago     1      2       5
local-lambda-invoker 1.0.0   7 months ago     0      1       4
lex-bnf              0.2.0   7 months ago     0      7      16
gdrive-fs            1.1.2   3 months ago     0      5      17
-------------------- ------- ------------ ----- ------ -------
This list was created at 2019-2-9 12:40:34
 

あとがき

このプログラム、実は数年前にPHPで書いていたので今回Node.jsへ移植した感じです。 驚いたのはその速度。一瞬で終了するではありませんか。PHPは非同期処理が書けない(?)からでしょうかね。あー驚いた。

コンソールへの出力は、list-it を使用してます。

takamints.hatenablog.jp

Gitbookのライブ・リロードがWindowsで異常終了する問題を(とりあえず)回避する

f:id:takamints:20190201191029j:plain
photo credit: tgrauros Helsingin yliopiston kirjasto / Biblioteca de la Universitat de Hèlsinki via photopin (license)

プランナー一年生のためのゲーム仕様書の書き方
株式会社サクセス (2017-01-15)
売り上げランキング: 2,254

マークダウンで複数ページからなるドキュメントを綺麗に書けるGitbookですけれど、仕事では先日初めて使うことになりまして「Windowsではライブ・リロードが正しく動かない」ってことを思い出しましたので、とりあえずの回避方法をさらっと書いておきます。

目次

Gitbook?

GitbookはMarkdownで書いた文書を電子文書的にキレイにまとめてくれるツールです。

章立てされた一連の文書を相互にリンクを貼って並べてくれるので便利です。

Markdownを書いて、gitbook build でHTMLを出力します。

また、gitbook serve で、ローカルWEBサーバーを起動するので、ブラウザで出力された文書を確認できます( http://localhost:4000/ )。

Gitbookのライブ・リロード?

Gitbookのライブ・リロード(live reload)は、出力したドキュメントを gitbook serve で確認している時、ソースファイル(Markdown)の更新を監視し、自動的にビルドし、ページをリロードしてくれる標準のプラグインです。

Windowsでは上手く動かない

めっちゃ便利な機能ですけど、残念ながらWindowsでは正しく動いてくれません。 ソースファイルを更新するとローカルWEBサーバーが異常終了してしまうのです。

PS C:\Users\Takami\rd\gitbook-on-win> gitbook serve
Live reload server started on port: 35729
Press CTRL+C to quit ...

info: 8 plugins are installed
info: 7 explicitly listed
info: loading plugin "livereload"... OK
(中略)
info: loading plugin "theme-default"... OK
info: found 1 pages
info: found 3 asset files
info: >> generation finished with success in 1.0s !

Starting server ...
Serving book on http://localhost:4000 #このあとソースファイルを再保存すると・・・
Restart after change in file README.md

Stopping server #停止した
events.js:167
      throw er; // Unhandled 'error' event
      ^

Error: EPERM: operation not permitted, watch
    at FSEvent.FSWatcher._handle.onchange (internal/fs/watchers.js:123:28)
Emitted 'error' event at:
    at FSWatcher._handleError (C:\Users\Takami\.gitbook\versions\3.2.3\node_modules\chokidar\index.js:236:10)
    (中略)
    at FSReqWrap.oncomplete (fs.js:141:20)

とりあえずの回避方法

この挙動、GitHubでIssueが上がっていますが完全放置状態。しかしIssueのコメントにとりあえずの対処法が書かれていました。

git serve でWEBサーバーが起動したあと、出力フォルダ(デフォルトで _book)を一度消せば、その後正常動作する」というものです。

実際にやってみると確かに解決。 _bookディレクトリは、消した直後にビルドされてすぐに復活。 ファイルを何度更新しても自動ビルドが正しく行われ、元気に動き続けてました。

しかし、この操作もちょっと面倒。 コンソールから gitbook serveした後は、同じコンソールが使えませんから別コンソールを起動して(またはエクスプローラでフォルダを開いて)_bookを消すことになりますからね。

そこで作業開始時にコンソールでgitbook serveしておいて、別コンソールを立ち上げて rm -r _book。そのままファイルを編集しはじめれば、それほど手間には感じません。

npm scripts でチョットだけ楽をする

ちなみにワタシは npm scriptsからgitbookを叩いていますので、以下のように設定しています。

  ・・・
  "scripts": {
    "serve": "gitbook serve",
    "open": "rm -rf _book && opn http://localhost:4000",
  },
  ・・・

npm run serve の後、別コンソールで、npm run open としてページを開きます。 (※ npm内の opnコマンドは npm install --save-dev opn-cli で使用できるようにしています)

gitbook serve --openでWEBサーバー起動後にドキュメントを開けますが、これをするとファイルを更新する度にタブが追加されて最新ページが表示されてタブだらけになるのです。

リンク

github.com

toolchain.gitbook.com

JavaScriptで可変長引数を扱うモダンな書き方

f:id:takamints:20190125200451j:plain
photo credit: wuestenigel Domino effect via photopin (license)

みんなのコンピュータサイエンス
翔泳社 (2019-01-15)
売り上げランキング: 12,305

JavaScript 可変長引数」でググると「arguments」のことばっかり出てきますけど「今やJavaScriptの可変長引数は arguments を使わなくてもスッキリ書けますからねっ!」ってことを書いています。

歴史の古いJavaScriptには、初期の言語仕様が多く残されており、今でもある程度互換性を保っていますから、少々古い書き方でも大方うまく動いてくれます。 一方で、新たな構文や概念も多々導入されていますから、古くからJavaScriptを使っている人が最新のコードを見ると「なんじゃい?この書き方は?」となるかもしれません。 しかし、安全性や利便性が向上しているのは確かですから、少しづつでもモダンなJavaScriptを習得したいものですね。

ということで、ここではES2015(ES6)以降のJavaScriptでスッキリ書ける「可変長引数」と「レストパラメータ」について書いております。

目次

可変長引数を扱う古い方法:arguments を使用する

まずは古い方法から。arguments はよく知ってるよって人は、このセクションは読み飛ばしてもらって結構ですよ。

JavaScriptの関数内では arguments というオブジェクトが、実行時に指定されたパラメータをすべて保持しています。

arguments は配列(Array)のように扱えるArgumentクラスのオブジェクトです。

引数以外にも呼び出し元や呼び出されている関数自体なども保持しています(ただし”use strict”; なstrictモードでは使えないものがあります。)

argumentsの使い方

引数に関しての使い方は、ほぼ配列です。

以下の関数fooは、受け取った引数をコンソールへ出力するだけの関数です。

function foo() {
    console.log("引数の数=" + arguments.length);
    for(let i = 0; i < arguments.length; i++) {
        console.log("[" + i + "]=" + arguments[i]);
    }
}
foo("A");
    // 引数の数=1
    // [0]=A
foo(1,2,3);
    // 引数の数=3
    // [0]=1
    // [1]=2
    // [2]=3

argumentsは明示的な引数宣言と無関係

関数に明示的な引数リストが宣言されていても、 arguments はそれら全てを含んでいます。

function foo(param0) {
    console.log("引数の数=" + arguments.length);
    for(let i = 0; i < arguments.length; i++) {
        console.log("[" + i + "]=" + arguments[i]);
    }
    console.log("param0=" + param0);
}
foo("A");
    // 引数の数=1
    // [0]=A
    // param0=A
foo(1,2,3);
    // 引数の数=3
    // [0]=1
    // [1]=2
    // [2]=3
    // param0=1

argumentsは配列ほど便利ではない

argumentsは配列っぽく使えますが、Arrayクラスの多くのメソッドが使えません。

これでは不便なので、以下のように一旦配列に変換するのが定石的なコードです。

function foo() {
    const vargs = Array.from(arguments);
    console.log("引数の数=" + vargs.length);
    vargs.forEach( function(item, index) {
        console.log("[" + index + "]=" + item);
    });
}

明示的な引数宣言がある場合は、途中からだけ変換したり。

function foo(bar,baz) {
    const vargs = Array.from(arguments).slice(2);
    console.log("引数の数=" + vargs.length);
    vargs.forEach( function(item, index) {
        console.log("[" + index + "]=" + item);
    });
}

arguments はアロー関数で使えない

アロー関数の中では arguments を使用できません。

つまり、アロー関数で可変長引数を受け取るには新しい方法でなければなりません。

argumentsの問題点まとめ

ここまで長々と書いてきましたが、argumentsの問題点は、アロー関数で使えないという致命的な点に加えて、可読性や保守性を損なっている点です。

上に書いたように歴史的に定石コードが使われてきましたが、それでも「単純だが見つけにくいバグ」が入る隙間ができています(これが一番の困り者)。

こういったコードの隙間はできる限りふさいでおくほうが安全です。

そういう意味でも、新しい方法が推奨されます。

可変長引数を扱う新しい方法:レストパラメータの使用

最新のJavaScript(ES6以降)では可変長引数をレストパラメータ(rest parameters)で宣言します。

レストパラメータとは、関数の最後の引数が ...args という形式(ドット3つに変数名)になっているものです (レスト = rest =「残り」ですので、「残りのパラメータ」というような意味でしょう)。

const foo = (param0, ...args) => {
    console.log("可変長引数の数=" + args.length);
    args.forEach( function(item, index) {
        console.log("[" + index + "]=" + item);
    });
    console.log("param0=" + param0);
};
foo("A");
    // 可変長引数の数=0
    // param0=A
foo(1,2,3);
    // 可変長引数の数=2
    // [0]=2
    // [1]=3
    // param0=1

ここでargsは単なるパラメータの名前ですから別の名前(例えば ...list )でも構いません。

レストパラメータは配列(Arrayオブジェクト)であり、この位置以降に指定された引数の値をすべて保持しています。

名前付きの可変長引数:スプレッド構文と組み合わせて

名前付きの可変長引数を使用できます。レストパラメータは配列ですが「スプレッド構文」との合わせ技で可能になります。

以下の例の第二引数が名前付きの可変長引数(...[va0,va1,va2]の部分)です。つまりこれ全体がレストパラメータで、[va0,va1,va2] の部分がスプレッド構文なんですね。

const foo = (param0, ...[va0,va1,va2]) => {
    va0=va0||0;
    va1=va1||0;
    va2=va2||0;
    const result = va0+va1+va2;
    console.log(`${param0}=${va0}+${va1}+${va2}=${result}`);
    return result;
};
foo("A", 1,2,3);
    // A=1+2+3=6
foo("A", 1,2);
    // A=1+2+0=3

指定しなかったところはundefinedになるようですね。

スプレッド構文というのは配列やオブジェクトを個々の要素に分解する構文なんですが、上の部分を見ると何となく理解できますでしょうか。

スプレッド構文の詳細は以下を参照してください。

ちょっとややこしいですけど、名前付きの可変長引数の最後の変数をレストパラメータにできます。

以下の例では、va2がそのように指定されています。この場合、fooに引数を与えなくても、va2は必ず配列になります。

const foo = (param0, ...[va0,va1,...va2]) => {

まとめ

  • argumentsは配列みたいなオブジェクトですが配列ほどには便利ではありません。レストパラメータは配列ですからそれなりに便利。
  • arguments は第一引数からすべてを保持しています、レストパラメータは宣言位置以降の値を保持します。
  • arguments はアロー関数では使用できませんがレストパラメータは使用可能(もちろん通常の function でもOK)。
  • argumentsはローカル変数ですが、ローカル関数の内部からはアクセスできません(ローカル関数自身のargumentsに置き換わります)。
  • レストパラメータはスプレッド構文と組み合わせることで可変長引数に名前を付けられます。

古いからといって間違いではありませんから、既存の動作しているコードを変更する必要などはありません (もしも変更するならば、ユニットテストを用意して取り掛かりましょう)。

しかし今から書くコードは(arguments に限らず)できるかぎり最新の手法を使うべきですね。

WebWorkerを手軽に扱うTransWorker v1.1でSharedWorkerが利用可能になりました!

f:id:takamints:20160131175631p:plain
photo credit: Pallet via photopin (license)

JavaScript において、メソッド呼び出し感覚で手軽に WebWorker によるマルチスレッドを扱える npmモジュール TransWorker を v1.1.0 に更新しました。

従来 DedicatedWorker にしか対応していなかったため、ワーカースレッドを生成したメインスレッドからしか扱えませんでしたが、 複数スレッドで共有できる SharedWorker が使えるようなり、ブラウザの異なるタブやウィンドウ間でワーカースレッドを共有できます。

その他、ちょっとした機能増強や不具合修正なども合わせて対応しています。

このページには、今回の変更点の概要、WebWorkerの基本事項、TransWorkerの使い方などを書いています。その他詳細はnpmのREADMEを参照してみてくださいね。

www.npmjs.com


目次

関連記事:

takamints.hatenablog.jp


TransWorker 更新内容 v1.0 => v1.1

SharedWorkerに対応【機能追加】

既に上で書いていますが、これまで DedicatedWorker にしか対応していなかったため、生成元のスレッドからしかワーカースレッドを扱えませんでした。

v1.1からは、複数スレッド間で共有できる SharedWorker が使えるようなったので、ブラウザの異なるタブやウィンドウ間でワーカースレッドを共有できます。

ワーカーからの通知のハンドラを後付け可能に【機能追加】

メインスレッド側でTransWorkerのインスタンスを生成するときに、ワーカースレッドからの通知を受け取るハンドラーをまとめて指定する形式をとっていましたが、インスタンス生成後に、個々の通知に対するハンドラーを設定できるように機能を追加しました(TransWorker.subscribe)。

メソッド呼び出し時の空のコールバックを不要に【不具合修正】

従来、メソッドの戻り値が無くてコールバックが不要な場合にでも、空のコールバック(()=>{} 等)を指定しなければいけなかったのですが、あまりにも不便でバグの元になっていたので修正しました。

引数リストの最後に関数オブジェクトが指定されていない場合は、コールバックは不要と判定します。 このチェックのため、動作速度に若干の影響があるかもしれません。 ほぼ体感できないレベルだとは思いますが、何らかの対策を考えたいです。

WebWorker について

※ここ、知ってる人は読み飛ばしてもらって結構ですよ。

WebWorkerはブラウザ上で動作するJavaScriptをマルチスレッド化するための仕組みですね。 メインスレッド(UIスレッド)からワーカースレッド(独立した実行コンテキスト)を生成し、スレッド間メッセージで通信できます。

DedicatedWorker と SharedWorker

ワーカースレッドには DedicatedWorker と SharedWorker という2つのワーカーが存在します(ServiceWorkerは別扱い)。

2つの違いは、その名前があらわしており "Dedicated" =「占有される」、"Shared" =「共有される」ということです。

つまり、DedicatedWorker は生成元のスレッドとしか通信できないのですが、SharedWorker は複数のスレッド間で共有され、各スレッドと通信可能なワーカーです。

例えばワーカースレッドで動作しているアプリケーションのコアロジックをブラウザの複数のタブやウィンドウから利用できるようになるわけです。

SharedWorkerの対応状況と制限事項

Chromeだけ?

せっかく SharedWorker に対応したのに、ざっと確認したところ、2018年12月現在 SharedWorkerがまともに動いているのは Chrome だけっぽいのです。 FirefoxではDedicatdWorkerと同様の動きをしており、EdgeやIE11では「SharedWorkerが見つかりません」と、にべもない。 SafariOpera は未確認です。

ChromeのSharedWorkerではコンソール出力が使えない?

唯一SharedWorkerに対応しているように見える Chrome で、SharedWorkerの実行コンテキスト内から console.log が使えませんでした。 エラーにはなりませんが、何も出力されません(DedicatedWorkerでは出力されます。ただし大量に出力するとフリーズしやすかった)。

このため、後述の TransWorker で、SharedWorkerを使用している場合は、メインスレッド側へ転送して出力するようにしています。

TransWorkerの概要とサンプルコード

TransWorker は、WebWorker を手軽に利用するための npm モジュールです。

ワーカースレッドで実行したい処理をクラスのインスタンスメソッドとして定義 しておけば、メソッド呼び出しと同様の手順でマルチスレッドを利用できます。 スレッド間メッセージを意識する必要はなく、普通にJavaScriptのクラスを実装する感覚で実装できます。

メソッド呼び出しをスレッド間メッセージに変換

TransWorkerは与えられたクラスのインターフェースを読み取って、メソッド呼び出しをスレッド間のメッセージ通信に変換 します。

全てのメソッドは非同期メソッドとなり、各メソッドの戻り値はコールバック関数で受け取れます。

以下に最もシンプルなサンプルを示します。もう少し複雑なサンプルはコチラにあります。

foo-bar.js

以下のクラス はひとつの値を保持するクラスで、値を設定するメソッドと、読み取るメソッドが定義されています。 これら2つのメソッドはワーカースレッドで実行されます(実際にはコンストラクタもですね)。 特別にマルチスレッドで処理したいことではありませんがサンプルなのでご容赦を。

function FooBar() {
    this._value = null;
}
FooBar.prototype.setValue = function(value) {
    this._value = value;
};
FooBar.prototype.getValue = function() {
    return this._value;
};

index.html

WEBページでは、TransWorker、FooBarクラスと、次に説明するメインスレッド側のスクリプトを読み込んでいます。 バンドラーでまとめる場合は別な形式になると思いますが、とりあえずサンプルはシンプルに書いています。

<html>
    <script src="path/to/the/transworker.js"></script>
    <script src="foo-bar.js"></script>
    <script src="main-thread.js"></script>
</html>

main-thread.js

メインスレッド側のスクリプトです。

FooBarのコンストラクタを与えてTransWorkerを生成し、それを通じてFooBarのメソッドを呼び出します。 この呼び出しはTransWorkerによってスレッド間通信に変換され、ワーカースレッド側のFooBarのインスタンスメソッドを呼び出します。 この戻り値は、コールバックで受け取ります。

//メインスレッド側ではワーカースクリプトとクラスの
//プロトタイプを参照して生成する
const fooBarWorker = TransWorker.createInvoker(
    "./worker-thread.js", FooBar);

fooBarWorker.setValue("Baz"); //戻り値が無いのでコールバック不要

//FooBar.getValueの戻り値はコールバックで受け取る
fooBarWorker.getValue(value => {
    console.log(value); // > Baz
});

woker-thread.js

ワーカースレッド側のスクリプトです。FooBarのインスタンスを指定してTransWorkerのワーカー側インスタンスを生成しています。

importScripts(
    "path/to/the/transworker",
    "./foo-bar.js");

//ワーカースレッド側ではFooBarのインスタンスを利用
TransWorker.createWorker(new FooBar());

ワーカースレッド側からの通知

また、ワーカースレッド側から(メソッド呼び出しの戻り値ではなく)能動的な通知も行えます(TransWorker.postNotify)。 SharedWorkerを使っている場合、この通知は共有するすべてのスレッドへブロードキャストされます。 ただし、ワーカーのどの通知を受け取るかは生成元または共有元の各スレッドで決定できます(TransWorker.subscribe)。

以下の例は上のサンプルを一部書き換えたものです。

foo-bar.js

function FooBar() {
    this._value = null;
}

FooBar.prototype.setValue = function(value) {
    this._value = value;

    //通知を発行する。
    this._transworker.postNotify("valueUpdated", value);
        //_transworkerフィールドはTransWorkerのファクトリが
        //注入する、このインスタンスを保持するTransWorkerの
        //インスタンスです。
};

FooBar.prototype.getValue = function() {
    return this._value;
};

main-thread.js

const fooBarWorker = TransWorker.createInvoker(
    "./worker-thread.js", FooBar);

// "valueUpdated"通知を受け取る
fooBarWorker.subscribe("valueUpdated", value => {
    console.log(`valueUpdated ${value}`);
});

//valueUpdated通知が発行される
fooBarWorker.setValue("Baz");

API

メインスレッド向け

ワーカースレッド向け

リンク

ここに記述していること以外の詳細、モジュール自体の使い方や、サンプルプログラムなどについては、以下 npm や GitHubリポジトリのREADME、またGitHub.IoのAPIドキュメントに記述してあります。