Use comlink in workers (#5915)
parent
d38a0f0366
commit
a66d2ca1b9
|
@ -2,6 +2,7 @@ const webpack = require("webpack");
|
|||
const path = require("path");
|
||||
const TerserPlugin = require("terser-webpack-plugin");
|
||||
const ManifestPlugin = require("webpack-manifest-plugin");
|
||||
const WorkerPlugin = require("worker-plugin");
|
||||
const paths = require("./paths.js");
|
||||
const env = require("./env.js");
|
||||
const { babelLoaderConfig } = require("./babel.js");
|
||||
|
@ -51,6 +52,7 @@ const createWebpackConfig = ({
|
|||
],
|
||||
},
|
||||
plugins: [
|
||||
new WorkerPlugin(),
|
||||
new ManifestPlugin(),
|
||||
new webpack.DefinePlugin({
|
||||
__DEV__: !isProdBuild,
|
||||
|
@ -105,7 +107,7 @@ const createWebpackConfig = ({
|
|||
latestBuild ? "frontend_latest" : "frontend_es5"
|
||||
),
|
||||
publicPath: latestBuild ? "/frontend_latest/" : "/frontend_es5/",
|
||||
// For workerize loader
|
||||
// To silence warning in worker plugin
|
||||
globalObject: "self",
|
||||
},
|
||||
};
|
||||
|
|
|
@ -86,6 +86,7 @@
|
|||
"chart.js": "~2.8.0",
|
||||
"chartjs-chart-timeline": "^0.3.0",
|
||||
"codemirror": "^5.49.0",
|
||||
"comlink": "^4.3.0",
|
||||
"cpx": "^1.5.0",
|
||||
"deep-clone-simple": "^1.1.1",
|
||||
"deep-freeze": "^0.0.1",
|
||||
|
@ -108,6 +109,7 @@
|
|||
"memoize-one": "^5.0.2",
|
||||
"moment": "^2.24.0",
|
||||
"node-vibrant": "^3.1.5",
|
||||
"proxy-polyfill": "^0.3.1",
|
||||
"regenerator-runtime": "^0.13.2",
|
||||
"resize-observer": "^1.0.0",
|
||||
"roboto-fontface": "^0.10.0",
|
||||
|
@ -195,7 +197,7 @@
|
|||
"webpack-dev-server": "^3.10.3",
|
||||
"webpack-manifest-plugin": "^2.0.4",
|
||||
"workbox-build": "^5.1.3",
|
||||
"workerize-loader": "^1.1.0"
|
||||
"worker-plugin": "^4.0.3"
|
||||
},
|
||||
"_comment": "Polymer fixed to 3.1 because 3.2 throws on logbook page",
|
||||
"_comment_2": "Fix in https://github.com/Polymer/polymer/pull/5569",
|
||||
|
|
|
@ -14,9 +14,6 @@ import { classMap } from "lit-html/directives/class-map";
|
|||
import { ifDefined } from "lit-html/directives/if-defined";
|
||||
import { styleMap } from "lit-html/directives/style-map";
|
||||
import { scroll } from "lit-virtualizer";
|
||||
// @ts-ignore
|
||||
// eslint-disable-next-line import/no-webpack-loader-syntax
|
||||
import sortFilterWorker from "workerize-loader!./sort_filter_worker";
|
||||
import { fireEvent } from "../../common/dom/fire_event";
|
||||
import "../../common/search/search-input";
|
||||
import { debounce } from "../../common/util/debounce";
|
||||
|
@ -24,6 +21,7 @@ import { nextRender } from "../../common/util/render-status";
|
|||
import "../ha-checkbox";
|
||||
import type { HaCheckbox } from "../ha-checkbox";
|
||||
import "../ha-icon";
|
||||
import { filterSortData } from "./sort-filter";
|
||||
|
||||
declare global {
|
||||
// for fire event
|
||||
|
@ -117,8 +115,6 @@ export class HaDataTable extends LitElement {
|
|||
|
||||
private curRequest = 0;
|
||||
|
||||
private _worker: any | undefined;
|
||||
|
||||
private _debounceSearch = debounce(
|
||||
(value: string) => {
|
||||
this._filter = value;
|
||||
|
@ -140,11 +136,6 @@ export class HaDataTable extends LitElement {
|
|||
}
|
||||
}
|
||||
|
||||
protected firstUpdated(properties: PropertyValues) {
|
||||
super.firstUpdated(properties);
|
||||
this._worker = sortFilterWorker();
|
||||
}
|
||||
|
||||
protected updated(properties: PropertyValues) {
|
||||
super.updated(properties);
|
||||
|
||||
|
@ -383,7 +374,7 @@ export class HaDataTable extends LitElement {
|
|||
this.curRequest++;
|
||||
const curRequest = this.curRequest;
|
||||
|
||||
const filterProm = this._worker.filterSortData(
|
||||
const filterProm = filterSortData(
|
||||
this.data,
|
||||
this._sortColumns,
|
||||
this._filter,
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
import { wrap } from "comlink";
|
||||
|
||||
type FilterSortDataType = typeof import("./sort_filter_worker").api["filterSortData"];
|
||||
type filterSortDataParamTypes = Parameters<FilterSortDataType>;
|
||||
|
||||
let worker: any | undefined;
|
||||
|
||||
export const filterSortData = async (
|
||||
data: filterSortDataParamTypes[0],
|
||||
columns: filterSortDataParamTypes[1],
|
||||
filter: filterSortDataParamTypes[2],
|
||||
direction: filterSortDataParamTypes[3],
|
||||
sortColumn: filterSortDataParamTypes[4]
|
||||
): Promise<ReturnType<FilterSortDataType>> => {
|
||||
if (!worker) {
|
||||
worker = wrap(new Worker("./sort_filter_worker", { type: "module" }));
|
||||
}
|
||||
|
||||
return await worker.filterSortData(
|
||||
data,
|
||||
columns,
|
||||
filter,
|
||||
direction,
|
||||
sortColumn
|
||||
);
|
||||
};
|
|
@ -1,57 +1,34 @@
|
|||
import memoizeOne from "memoize-one";
|
||||
// eslint-disable-next-line import/no-cycle
|
||||
import {
|
||||
DataTableColumnContainer,
|
||||
DataTableColumnData,
|
||||
// To use comlink under ES5
|
||||
import "proxy-polyfill";
|
||||
import { expose } from "comlink";
|
||||
import type {
|
||||
DataTableSortColumnData,
|
||||
DataTableRowData,
|
||||
SortingDirection,
|
||||
HaDataTable,
|
||||
} from "./ha-data-table";
|
||||
|
||||
export const filterSortData = memoizeOne(
|
||||
async (
|
||||
type SortableColumnContainer = HaDataTable["_sortColumns"];
|
||||
|
||||
const filterSortData = (
|
||||
data: DataTableRowData[],
|
||||
columns: DataTableColumnContainer,
|
||||
columns: SortableColumnContainer,
|
||||
filter: string,
|
||||
direction: SortingDirection,
|
||||
sortColumn?: string
|
||||
) =>
|
||||
sortColumn
|
||||
? _memSortData(
|
||||
await _memFilterData(data, columns, filter),
|
||||
columns,
|
||||
direction,
|
||||
sortColumn
|
||||
)
|
||||
: _memFilterData(data, columns, filter)
|
||||
);
|
||||
) => {
|
||||
const filteredData = filter ? filterData(data, columns, filter) : data;
|
||||
|
||||
const _memFilterData = memoizeOne(
|
||||
async (
|
||||
data: DataTableRowData[],
|
||||
columns: DataTableColumnContainer,
|
||||
filter: string
|
||||
) => {
|
||||
if (!filter) {
|
||||
return data;
|
||||
if (!sortColumn) {
|
||||
return filteredData;
|
||||
}
|
||||
return filterData(data, columns, filter.toUpperCase());
|
||||
}
|
||||
);
|
||||
|
||||
const _memSortData = memoizeOne(
|
||||
(
|
||||
data: DataTableRowData[],
|
||||
columns: DataTableColumnContainer,
|
||||
direction: SortingDirection,
|
||||
sortColumn: string
|
||||
) => {
|
||||
return sortData(data, columns[sortColumn], direction, sortColumn);
|
||||
}
|
||||
);
|
||||
return sortData(filteredData, columns, direction, sortColumn);
|
||||
};
|
||||
|
||||
export const filterData = (
|
||||
const filterData = (
|
||||
data: DataTableRowData[],
|
||||
columns: DataTableColumnContainer,
|
||||
columns: SortableColumnContainer,
|
||||
filter: string
|
||||
) =>
|
||||
data.filter((row) => {
|
||||
|
@ -70,9 +47,9 @@ export const filterData = (
|
|||
});
|
||||
});
|
||||
|
||||
export const sortData = (
|
||||
const sortData = (
|
||||
data: DataTableRowData[],
|
||||
column: DataTableColumnData,
|
||||
column: DataTableSortColumnData,
|
||||
direction: SortingDirection,
|
||||
sortColumn: string
|
||||
) =>
|
||||
|
@ -105,3 +82,10 @@ export const sortData = (
|
|||
}
|
||||
return 0;
|
||||
});
|
||||
|
||||
// Export for types
|
||||
export const api = {
|
||||
filterSortData,
|
||||
};
|
||||
|
||||
expose(api);
|
||||
|
|
|
@ -1,10 +1,6 @@
|
|||
import { customElement, property, UpdatingElement } from "lit-element";
|
||||
// @ts-ignore
|
||||
// eslint-disable-next-line import/no-webpack-loader-syntax
|
||||
import markdownWorker from "workerize-loader!../resources/markdown_worker";
|
||||
import { fireEvent } from "../common/dom/fire_event";
|
||||
|
||||
let worker: any | undefined;
|
||||
import { renderMarkdown } from "../resources/render-markdown";
|
||||
|
||||
@customElement("ha-markdown")
|
||||
class HaMarkdown extends UpdatingElement {
|
||||
|
@ -16,16 +12,11 @@ class HaMarkdown extends UpdatingElement {
|
|||
|
||||
protected update(changedProps) {
|
||||
super.update(changedProps);
|
||||
|
||||
if (!worker) {
|
||||
worker = markdownWorker();
|
||||
}
|
||||
|
||||
this._render();
|
||||
}
|
||||
|
||||
private async _render() {
|
||||
this.innerHTML = await worker.renderMarkdown(
|
||||
this.innerHTML = await renderMarkdown(
|
||||
this.content,
|
||||
{
|
||||
breaks: this.breaks,
|
||||
|
|
|
@ -2,6 +2,8 @@ import objAssign from "es6-object-assign";
|
|||
import "mdn-polyfills/Array.prototype.includes";
|
||||
import "regenerator-runtime/runtime";
|
||||
import "unfetch/polyfill";
|
||||
// To use comlink under ES5
|
||||
import "proxy-polyfill";
|
||||
|
||||
objAssign.polyfill();
|
||||
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
// To use comlink under ES5
|
||||
import "proxy-polyfill";
|
||||
import { expose } from "comlink";
|
||||
import marked from "marked";
|
||||
// @ts-ignore
|
||||
import filterXSS from "xss";
|
||||
|
@ -9,14 +12,14 @@ interface WhiteList {
|
|||
let whiteListNormal: WhiteList | undefined;
|
||||
let whiteListSvg: WhiteList | undefined;
|
||||
|
||||
export const renderMarkdown = (
|
||||
const renderMarkdown = (
|
||||
content: string,
|
||||
markedOptions: object,
|
||||
hassOptions: {
|
||||
// Do not allow SVG on untrusted content, it allows XSS.
|
||||
allowSvg?: boolean;
|
||||
} = {}
|
||||
) => {
|
||||
): string => {
|
||||
if (!whiteListNormal) {
|
||||
whiteListNormal = {
|
||||
...filterXSS.whiteList,
|
||||
|
@ -45,3 +48,10 @@ export const renderMarkdown = (
|
|||
whiteList,
|
||||
});
|
||||
};
|
||||
|
||||
// Export for types
|
||||
export const api = {
|
||||
renderMarkdown,
|
||||
};
|
||||
|
||||
expose(api);
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
import { wrap } from "comlink";
|
||||
|
||||
type RenderMarkdownType = typeof import("./markdown_worker").api["renderMarkdown"];
|
||||
type renderMarkdownParamTypes = Parameters<RenderMarkdownType>;
|
||||
|
||||
let worker: any | undefined;
|
||||
|
||||
export const renderMarkdown = async (
|
||||
content: renderMarkdownParamTypes[0],
|
||||
markedOptions: renderMarkdownParamTypes[1],
|
||||
hassOptions?: renderMarkdownParamTypes[2]
|
||||
): Promise<ReturnType<RenderMarkdownType>> => {
|
||||
if (!worker) {
|
||||
worker = wrap(new Worker("./markdown_worker", { type: "module" }));
|
||||
}
|
||||
|
||||
return await worker.renderMarkdown(content, markedOptions, hassOptions);
|
||||
};
|
20
yarn.lock
20
yarn.lock
|
@ -5691,6 +5691,11 @@ combined-stream@^1.0.6, combined-stream@~1.0.6:
|
|||
dependencies:
|
||||
delayed-stream "~1.0.0"
|
||||
|
||||
comlink@^4.3.0:
|
||||
version "4.3.0"
|
||||
resolved "https://registry.yarnpkg.com/comlink/-/comlink-4.3.0.tgz#80b3366baccd87897dab3638ebfcfae28b2f87c7"
|
||||
integrity sha512-mu4KKKNuW8TvkfpW/H88HBPeILubBS6T94BdD1VWBXNXfiyqVtwUCVNO1GeNOBTsIswzsMjWlycYr+77F5b84g==
|
||||
|
||||
command-line-args@^5.0.2:
|
||||
version "5.1.0"
|
||||
resolved "https://registry.yarnpkg.com/command-line-args/-/command-line-args-5.1.0.tgz#632d3d3df35c8f0cc4365e442a3fd6d63b65621b"
|
||||
|
@ -12146,6 +12151,11 @@ proxy-addr@~2.0.5:
|
|||
forwarded "~0.1.2"
|
||||
ipaddr.js "1.9.0"
|
||||
|
||||
proxy-polyfill@^0.3.1:
|
||||
version "0.3.1"
|
||||
resolved "https://registry.yarnpkg.com/proxy-polyfill/-/proxy-polyfill-0.3.1.tgz#163d5283cf928dd8ddb5c5e88528e4ccd233496f"
|
||||
integrity sha512-jywE1NIksgIGqZc4uF0QLbXGz2RcHQobsCkAW+8F0nr/6agap+TWksEAKyLnIBafPD88HT9qZR2ec0oomHdjcQ==
|
||||
|
||||
prr@~1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476"
|
||||
|
@ -15517,12 +15527,12 @@ worker-farm@^1.7.0:
|
|||
dependencies:
|
||||
errno "~0.1.7"
|
||||
|
||||
workerize-loader@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/workerize-loader/-/workerize-loader-1.1.0.tgz#d3a634390dcb685cc1ee292cd1fffeef0a646044"
|
||||
integrity sha512-cU2jPVE3AzzVxOonBe9lCCO//qwE9s/K4a9njFVRLueznzNDNND5vGHVorGuzK6xvamdDOZ9+g7CPIc7QKzucQ==
|
||||
worker-plugin@^4.0.3:
|
||||
version "4.0.3"
|
||||
resolved "https://registry.yarnpkg.com/worker-plugin/-/worker-plugin-4.0.3.tgz#7c42e600d5931ad154d3d5f187a32446df64db0f"
|
||||
integrity sha512-7hFDYWiKcE3yHZvemsoM9lZis/PzurHAEX1ej8PLCu818Rt6QqUAiDdxHPCKZctzmhqzPpcFSgvMCiPbtooqAg==
|
||||
dependencies:
|
||||
loader-utils "^1.2.3"
|
||||
loader-utils "^1.1.0"
|
||||
|
||||
wrap-ansi@^2.0.0:
|
||||
version "2.1.0"
|
||||
|
|
Loading…
Reference in New Issue