Skip to content

Commit

Permalink
Switch from Flow to TypeScript
Browse files Browse the repository at this point in the history
  • Loading branch information
dumbmatter committed Jan 14, 2020
1 parent 29332dd commit c80e9b3
Show file tree
Hide file tree
Showing 9 changed files with 149 additions and 72 deletions.
4 changes: 3 additions & 1 deletion .babelrc
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
{
"presets": ["@babel/preset-flow"],
"presets": [
"@babel/preset-typescript"
],
"plugins": [
"@babel/plugin-transform-destructuring"
]
Expand Down
3 changes: 0 additions & 3 deletions .flowconfig

This file was deleted.

2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
language: node_js
node_js:
- "8"
- "10"
dist: trusty # needs Ubuntu Trusty
# Note: if you switch to sudo: false, you'll need to launch chrome with --no-sandbox.
# See https://github.com/travis-ci/travis-ci/issues/8836
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# v4.0.1, 2020-01-13

Switched from Flow to TypeScript, cause momentum. Sadly TypeScript sucks at supporting shared workers, so the typings are a bit worse, but promise-worker-bi works the same.

# v4.0.0, 2019-11-06

Split the old PromiseWorker class into two separate classes PWBHost and PWBWorker, so they can be included separately in main and worker bundles, leading to smaller bundle sizes if you use tree shaking and dead code elimination. Savings seems to just be a couple kb of minified JS per bundle, but every byte counts!
Expand Down
17 changes: 9 additions & 8 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@
"description": "Promise-based messaging for Web Workers and Shared Workers",
"main": "dist/commonjs.js",
"module": "dist/esmodules.js",
"types": "dist/index.d.ts",
"scripts": {
"prepublish": "yarn run build",
"build": "rm -rf dist && rollup -c",
"build": "rm -rf dist && rollup -c && yarn run tsc",
"build-test": "yarn run build && node scripts/build-test.js",
"flow": "flow",
"lint": "eslint *.js test/*.js scripts/*.js",
"prettier": "prettier --write '*.js' && prettier --write 'test/*.js' && prettier --write 'scripts/*.js'",
"lint": "eslint src/*.ts test/*.js scripts/*.js",
"prettier": "prettier --write 'src/*.ts' && prettier --write 'test/*.js' && prettier --write 'scripts/*.js'",
"karma": "yarn run build-test && karma start",
"test": "yarn run flow && yarn run lint && yarn run karma"
"test": "yarn run tsc && yarn run lint && yarn run karma"
},
"repository": {
"type": "git",
Expand All @@ -35,13 +35,13 @@
"devDependencies": {
"@babel/core": "^7.8.3",
"@babel/plugin-transform-destructuring": "^7.8.3",
"@babel/preset-flow": "^7.8.3",
"@babel/preset-typescript": "^7.8.3",
"@types/sharedworker": "^0.0.29",
"babel-eslint": "^10.0.3",
"eslint": "^6.8.0",
"eslint-config-airbnb-base": "^14.0.0",
"eslint-config-prettier": "^6.9.0",
"eslint-plugin-import": "^2.20.0",
"flow-bin": "^0.115.0",
"glob": "^7.1.6",
"husky": "^4.0.7",
"karma": "^4.4.1",
Expand All @@ -56,7 +56,8 @@
"rollup-plugin-babel": "^4.3.3",
"rollup-plugin-node-builtins": "^2.1.2",
"rollup-plugin-node-globals": "^1.4.0",
"rollup-plugin-node-resolve": "^5.2.0"
"rollup-plugin-node-resolve": "^5.2.0",
"typescript": "^3.7.4"
},
"files": [
"dist"
Expand Down
8 changes: 6 additions & 2 deletions rollup.config.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const babel = require("rollup-plugin-babel");

module.exports = {
input: "index.js",
input: "src/index.ts",
output: [
{
file: "dist/commonjs.js",
Expand All @@ -12,5 +12,9 @@ module.exports = {
format: "esm"
}
],
plugins: [babel()]
plugins: [
babel({
extensions: [".mjs", ".js", ".json", ".node", ".ts", ".tsx"]
})
]
};
97 changes: 56 additions & 41 deletions index.js → src/index.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
// @flow

type ErrorCallback = Error => void;
type QueryCallback = (any[], number | void) => any;
type ErrorCallback = (a: Error) => void;
type QueryCallback = (a: any[], b: number | undefined) => any;

type FakeError = {
name: string,
message: string,
stack?: string,
fileName?: string,
columnNumber?: number,
lineNumber?: number
name: string;
message: string;
stack?: string;
fileName?: string;
columnNumber?: number;
lineNumber?: number;
};

let messageIDs = 0;
Expand All @@ -28,7 +26,7 @@ const MSGTYPES = [
];

// Inlined from https://github.com/then/is-promise
const isPromise = obj =>
const isPromise = (obj: any) =>
!!obj &&
(typeof obj === "object" || typeof obj === "function") &&
typeof obj.then === "function";
Expand All @@ -44,13 +42,19 @@ const toFakeError = (error: Error): FakeError => {
}

// These are non-standard properties, I think only in some versions of Firefox
// @ts-ignore
if (typeof error.fileName === "string") {
// @ts-ignore
fakeError.fileName = error.fileName;
}
// @ts-ignore
if (typeof error.columnNumber === "number") {
// @ts-ignore
fakeError.columnNumber = error.columnNumber;
}
// @ts-ignore
if (typeof error.lineNumber === "number") {
// @ts-ignore
fakeError.lineNumber = error.lineNumber;
}

Expand All @@ -72,17 +76,18 @@ const logError = (err: Error) => {
};

class PWBBase {
_callbacks: Map<number, (Error | null, any) => void>;
_callbacks: Map<number, (a: Error | null, b: any) => void>;

_queryCallback: QueryCallback;

_workerType: "SharedWorker" | "Worker";
_workerType: "SharedWorker" | "Worker" | undefined;

constructor() {
// console.log('constructor', worker);
this._callbacks = new Map();
this._queryCallback = () => {};

// $FlowFixMe https://github.com/facebook/flow/issues/1517
// @ts-ignore
this._onMessage = this._onMessage.bind(this);
}

Expand All @@ -92,15 +97,15 @@ class PWBBase {
}

// eslint-disable-next-line
_postMessage(obj: any[], targetHostID?: number | void) {
_postMessage(obj: any[], targetHostID?: number | undefined) {
throw new Error("Not implemented");
}

_postResponse(
messageID: number,
error: Error | null,
result: any,
hostID: number | void
result?: any,
hostID?: number | undefined
) {
// console.log('_postResponse', messageID, error, result);
if (error) {
Expand All @@ -115,7 +120,7 @@ class PWBBase {
}
}

_handleQuery(messageID: number, query: any, hostID: number | void) {
_handleQuery(messageID: number, query: any, hostID: number | undefined) {
// console.log('_handleQuery', messageID, query);
try {
const result = this._queryCallback(query, hostID);
Expand All @@ -124,10 +129,10 @@ class PWBBase {
this._postResponse(messageID, null, result, hostID);
} else {
result.then(
finalResult => {
(finalResult: any) => {
this._postResponse(messageID, null, finalResult, hostID);
},
finalError => {
(finalError: any) => {
this._postResponse(messageID, finalError, hostID);
}
);
Expand All @@ -138,7 +143,7 @@ class PWBBase {
}

// Either return messageID and type if further processing is needed, or undefined otherwise
_onMessageCommon(e: MessageEvent): { message: any, type: number } | void {
_onMessageCommon(e: MessageEvent): { message: any; type: number } | void {
// eslint-disable-line no-undef
// console.log('_onMessage', e.data);
const message = e.data;
Expand All @@ -161,7 +166,7 @@ class PWBBase {
if (typeof message[3] !== "number" && message[3] !== undefined) {
throw new Error("Invalid hostID");
}
const hostID: number | void = message[3];
const hostID: number | undefined = message[3];

this._handleQuery(messageID, query, hostID);
return;
Expand Down Expand Up @@ -192,15 +197,15 @@ class PWBBase {
}

class PWBHost extends PWBBase {
_errorCallback: ErrorCallback | void;
_errorCallback: ErrorCallback | undefined;

_hostID: number | void; // Only defined on host
_hostID: number | undefined; // Only defined on host

_hostIDQueue: (() => void)[] | void;
_hostIDQueue: (() => void)[] | undefined;

_worker: SharedWorker | Worker;
_worker: SharedWorker.SharedWorker | Worker;

constructor(worker: SharedWorker | Worker) {
constructor(worker: SharedWorker.SharedWorker | Worker) {
super();

// The following if statement used to check `worker instanceof Worker` but I have recieved
Expand All @@ -212,17 +217,18 @@ class PWBHost extends PWBBase {
// console.log(worker instanceof Worker);
//
// So instead, let's do this test for worker.port which only exists on shared workers.
// @ts-ignore
if (worker.port === undefined) {
this._workerType = "Worker";

// $FlowFixMe Seems to not recognize 'message' as valid type, but it is
// @ts-ignore
worker.addEventListener("message", this._onMessage);
} else {
this._workerType = "SharedWorker";

// $FlowFixMe - it doesn't know if _worker is Worker or SharedWorker, but I do
// @ts-ignore - it doesn't know if _worker is Worker or SharedWorker, but I do
worker.port.addEventListener("message", this._onMessage);
// $FlowFixMe - it doesn't know if _worker is Worker or SharedWorker, but I do
// @ts-ignore - it doesn't know if _worker is Worker or SharedWorker, but I do
worker.port.start();

// Handle tab close. This isn't perfect, but there is no perfect method
Expand Down Expand Up @@ -256,10 +262,10 @@ class PWBHost extends PWBBase {
_postMessage(obj: any[]) {
// console.log('_postMessage', obj);
if (this._workerType === "Worker") {
// $FlowFixMe - it doesn't know if _worker is Worker or SharedWorker, but I do
// @ts-ignore - it doesn't know if _worker is Worker or SharedWorker, but I do
this._worker.postMessage(obj);
} else if (this._workerType === "SharedWorker") {
// $FlowFixMe - it doesn't know if _worker is Worker or SharedWorker, but I do
// @ts-ignore - it doesn't know if _worker is Worker or SharedWorker, but I do
this._worker.port.postMessage(obj);
} else {
throw new Error("WTF");
Expand All @@ -268,7 +274,7 @@ class PWBHost extends PWBBase {

postMessage(userMessage: any): Promise<any> {
// console.log('postMessage', userMessage, targetHostID);
const actuallyPostMessage = (resolve, reject) => {
const actuallyPostMessage = (resolve: (value?: any) => void, reject: (reason?: any) => void) => {
const messageID = messageIDs;
messageIDs += 1;

Expand Down Expand Up @@ -304,7 +310,7 @@ class PWBHost extends PWBBase {

_onMessage(e: MessageEvent) {
const common = this._onMessageCommon(e);
if (common === undefined) {
if (!common) {
return;
}

Expand All @@ -314,7 +320,7 @@ class PWBHost extends PWBBase {
if (message[2] !== undefined && typeof message[2] !== "number") {
throw new Error("Invalid hostID");
}
const hostID: number | void = message[2];
const hostID: number | undefined = message[2];

this._hostID = hostID;

Expand Down Expand Up @@ -350,16 +356,21 @@ class PWBWorker extends PWBBase {
constructor() {
super();

// Only actually used for SharedWorker
this._hosts = new Map();
this._maxHostID = -1;

if (
// @ts-ignore
typeof SharedWorkerGlobalScope !== "undefined" &&
// @ts-ignore
self instanceof SharedWorkerGlobalScope
) {
this._workerType = "SharedWorker";

this._hosts = new Map();
this._maxHostID = -1;

self.addEventListener("connect", e => {
// @ts-ignore
const port = e.ports[0];
port.addEventListener("message", (e2: MessageEvent) =>
this._onMessage(e2)
Expand Down Expand Up @@ -405,7 +416,7 @@ class PWBWorker extends PWBBase {
}
}

_postMessage(obj: any[], targetHostID: number | void) {
_postMessage(obj: any[], targetHostID?: number | undefined) {
// console.log('_postMessage', obj, targetHostID);
if (this._workerType === "SharedWorker") {
// If targetHostID has been deleted, this will do nothing, which is fine I think
Expand All @@ -415,15 +426,19 @@ class PWBWorker extends PWBBase {
}
});
} else if (this._workerType === "Worker") {
// @ts-ignore
self.postMessage(obj);
} else {
throw new Error("WTF");
}
}

postMessage(userMessage: any, targetHostID: number | void): Promise<any> {
postMessage(
userMessage: any,
targetHostID: number | undefined
): Promise<any> {
// console.log('postMessage', userMessage, targetHostID);
const actuallyPostMessage = (resolve, reject) => {
const actuallyPostMessage = (resolve: (value?: any) => void, reject: (reason?: any) => void) => {
const messageID = messageIDs;
messageIDs += 1;

Expand All @@ -446,7 +461,7 @@ class PWBWorker extends PWBBase {

_onMessage(e: MessageEvent) {
const common = this._onMessageCommon(e);
if (common === undefined) {
if (!common) {
return;
}

Expand Down
12 changes: 12 additions & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"compilerOptions": {
"target": "esnext",
"moduleResolution": "node",
"emitDeclarationOnly": true,
"strict": true,
"esModuleInterop": true,
"declaration": true,
"declarationDir": "dist"
},
"include": ["src"]
}
Loading

0 comments on commit c80e9b3

Please sign in to comment.