diff --git a/.github/renovate.json b/.github/renovate.json index 19d5313cfa..503b6865cf 100644 --- a/.github/renovate.json +++ b/.github/renovate.json @@ -23,6 +23,7 @@ "^@tanstack/", "^@tiptap/", "@types/markdown-it", + "comlink", "d3-", "prosemirror-" ], diff --git a/angular-workspace/projects/ni/nimble-angular/CHANGELOG.json b/angular-workspace/projects/ni/nimble-angular/CHANGELOG.json index e8b7bf13b5..81fa7d8153 100644 --- a/angular-workspace/projects/ni/nimble-angular/CHANGELOG.json +++ b/angular-workspace/projects/ni/nimble-angular/CHANGELOG.json @@ -1,6 +1,21 @@ { "name": "@ni/nimble-angular", "entries": [ + { + "date": "Wed, 28 Feb 2024 21:22:49 GMT", + "version": "20.2.13", + "tag": "@ni/nimble-angular_v20.2.13", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@ni/nimble-angular", + "comment": "Bump @ni/nimble-components to v21.7.1", + "commit": "not available" + } + ] + } + }, { "date": "Wed, 28 Feb 2024 19:35:04 GMT", "version": "20.2.12", diff --git a/angular-workspace/projects/ni/nimble-angular/CHANGELOG.md b/angular-workspace/projects/ni/nimble-angular/CHANGELOG.md index e580df39ab..db79e75155 100644 --- a/angular-workspace/projects/ni/nimble-angular/CHANGELOG.md +++ b/angular-workspace/projects/ni/nimble-angular/CHANGELOG.md @@ -1,9 +1,17 @@ # Change Log - @ni/nimble-angular -This log was last generated on Wed, 28 Feb 2024 19:35:04 GMT and should not be manually modified. +This log was last generated on Wed, 28 Feb 2024 21:22:49 GMT and should not be manually modified. +## 20.2.13 + +Wed, 28 Feb 2024 21:22:49 GMT + +### Patches + +- Bump @ni/nimble-components to v21.7.1 + ## 20.2.12 Wed, 28 Feb 2024 19:35:04 GMT diff --git a/angular-workspace/projects/ni/nimble-angular/package.json b/angular-workspace/projects/ni/nimble-angular/package.json index 211816a498..58bdfdcf42 100644 --- a/angular-workspace/projects/ni/nimble-angular/package.json +++ b/angular-workspace/projects/ni/nimble-angular/package.json @@ -1,6 +1,6 @@ { "name": "@ni/nimble-angular", - "version": "20.2.12", + "version": "20.2.13", "description": "Angular components for the NI Nimble Design System", "scripts": { "invoke-publish": "cd ../../../ && npm run build:library && cd dist/ni/nimble-angular && npm publish" @@ -31,7 +31,7 @@ "@angular/forms": "^15.2.10", "@angular/localize": "^15.2.10", "@angular/router": "^15.2.10", - "@ni/nimble-components": "^21.7.0" + "@ni/nimble-components": "^21.7.1" }, "dependencies": { "tslib": "^2.2.0" diff --git a/package-lock.json b/package-lock.json index bcf30a1168..a048d1cda9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -83,7 +83,7 @@ }, "angular-workspace/projects/ni/nimble-angular": { "name": "@ni/nimble-angular", - "version": "20.2.12", + "version": "20.2.13", "license": "MIT", "dependencies": { "tslib": "^2.2.0" @@ -94,7 +94,7 @@ "@angular/forms": "^15.2.10", "@angular/localize": "^15.2.10", "@angular/router": "^15.2.10", - "@ni/nimble-components": "^21.7.0" + "@ni/nimble-components": "^21.7.1" } }, "node_modules/@11ty/dependency-tree": { @@ -14510,6 +14510,11 @@ "node": ">= 0.8" } }, + "node_modules/comlink": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/comlink/-/comlink-4.4.1.tgz", + "integrity": "sha512-+1dlx0aY5Jo1vHy/tSsIGpSkN4tS9rZSW8FIhG0JH/crs9wwweswIo/POr451r7bZww3hFbPAKnTpimzL/mm4Q==" + }, "node_modules/commander": { "version": "8.3.0", "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", @@ -33892,7 +33897,7 @@ }, "packages/nimble-blazor": { "name": "@ni/nimble-blazor", - "version": "14.3.9", + "version": "14.3.10", "hasInstallScript": true, "license": "MIT", "devDependencies": { @@ -34014,7 +34019,7 @@ }, "packages/nimble-components": { "name": "@ni/nimble-components", - "version": "21.7.0", + "version": "21.7.1", "license": "MIT", "dependencies": { "@microsoft/fast-colors": "^5.3.1", @@ -34044,6 +34049,7 @@ "@types/d3-selection": "^3.0.0", "@types/d3-zoom": "^3.0.0", "@types/markdown-it": "^13.0.0", + "comlink": "4.4.1", "d3-array": "^3.2.2", "d3-random": "^3.0.1", "d3-scale": "^4.0.2", diff --git a/packages/nimble-blazor/package.json b/packages/nimble-blazor/package.json index 6bd8a13519..6b80a7936b 100644 --- a/packages/nimble-blazor/package.json +++ b/packages/nimble-blazor/package.json @@ -1,6 +1,6 @@ { "name": "@ni/nimble-blazor", - "version": "14.3.9", + "version": "14.3.10", "description": "Blazor components for the NI Nimble Design System", "scripts": { "postinstall": "node build/generate-playwright-version-properties/source/index.js", diff --git a/packages/nimble-components/.gitignore b/packages/nimble-components/.gitignore index c1ee1d4086..1495b9d049 100644 --- a/packages/nimble-components/.gitignore +++ b/packages/nimble-components/.gitignore @@ -1 +1,2 @@ src/icons +src/wafer-map/workers \ No newline at end of file diff --git a/packages/nimble-components/.prettierignore b/packages/nimble-components/.prettierignore index 6ea3009480..413a7f4cf2 100644 --- a/packages/nimble-components/.prettierignore +++ b/packages/nimble-components/.prettierignore @@ -29,3 +29,4 @@ src/utilities/tests/fixture.ts src/utilities/style/direction.ts src/icons/**/*.ts build/transform-fragments.js +src/wafer-map/workers diff --git a/packages/nimble-components/CHANGELOG.json b/packages/nimble-components/CHANGELOG.json index 33e4a52a42..b9702703b3 100644 --- a/packages/nimble-components/CHANGELOG.json +++ b/packages/nimble-components/CHANGELOG.json @@ -1,6 +1,21 @@ { "name": "@ni/nimble-components", "entries": [ + { + "date": "Wed, 28 Feb 2024 21:22:49 GMT", + "version": "21.7.1", + "tag": "@ni/nimble-components_v21.7.1", + "comments": { + "patch": [ + { + "author": "110180309+Razvan1928@users.noreply.github.com", + "package": "@ni/nimble-components", + "commit": "52693524c553f3b115e6c1004c902d10e7dd4050", + "comment": "Create web worker class for future faster rendering wafer map" + } + ] + } + }, { "date": "Wed, 28 Feb 2024 19:35:04 GMT", "version": "21.7.0", diff --git a/packages/nimble-components/CHANGELOG.md b/packages/nimble-components/CHANGELOG.md index 4f08eec2e9..e8f7ddece4 100644 --- a/packages/nimble-components/CHANGELOG.md +++ b/packages/nimble-components/CHANGELOG.md @@ -1,9 +1,17 @@ # Change Log - @ni/nimble-components -This log was last generated on Wed, 28 Feb 2024 19:35:04 GMT and should not be manually modified. +This log was last generated on Wed, 28 Feb 2024 21:22:49 GMT and should not be manually modified. +## 21.7.1 + +Wed, 28 Feb 2024 21:22:49 GMT + +### Patches + +- Create web worker class for future faster rendering wafer map ([ni/nimble@5269352](https://github.com/ni/nimble/commit/52693524c553f3b115e6c1004c902d10e7dd4050)) + ## 21.7.0 Wed, 28 Feb 2024 19:35:04 GMT diff --git a/packages/nimble-components/build/generate-workers/README.md b/packages/nimble-components/build/generate-workers/README.md new file mode 100644 index 0000000000..4f397ba281 --- /dev/null +++ b/packages/nimble-components/build/generate-workers/README.md @@ -0,0 +1,18 @@ +# Generate Workers + +This directory contains wafer map rendering code and build scripts which compile it to run in a web worker. + +## Behavior + +- the `source` directory and `index.ts` are built using `tsc` +- `source/matrix-renderer.ts` is bundled with rollup +- `index.ts` has the purpose to prepare and move `dist/bundle/matrix-renderer` to `src/wafer-map/worker` +- `src/wafer-map/worker/matrix-renderer` will be used to create a `Blob` object which is then used to create a `URL` for a web worker. + +## How to run + +This script runs as part of `npm run build` but before `npm run build-components`. + +To run manually: + +1. Run `npm run generate-workers` inside nimble-components directory. diff --git a/packages/nimble-components/build/generate-workers/index.ts b/packages/nimble-components/build/generate-workers/index.ts new file mode 100644 index 0000000000..35fb9676ca --- /dev/null +++ b/packages/nimble-components/build/generate-workers/index.ts @@ -0,0 +1,39 @@ +const fs = require('fs'); +const path = require('path'); + +function resolveModulePath(moduleName: string): string { + return path.resolve(require.resolve(moduleName)); +} + +function prepareDirectory(dirPath: string): void { + if (fs.existsSync(dirPath)) { + console.log(`Deleting existing directory "${dirPath}"`); + fs.rmSync(dirPath, { recursive: true }); + console.log('Finished deleting existing directory'); + } + console.log(`Creating directory "${dirPath}"`); + fs.mkdirSync(dirPath); + console.log('Finished creating directory'); +} + +function writeFile(filePath: string, content: string): void { + console.log(`Writing file "${filePath}"`); + fs.writeFileSync(filePath, content, { encoding: 'utf-8' }); + console.log('Finished writing file'); +} + +const renderModuleName: string = '../bundle/matrix-renderer.js'; +const workersDirectory: string = path.resolve('./src/wafer-map/workers'); + +prepareDirectory(workersDirectory); + +const modulePath: string = resolveModulePath(renderModuleName); +const sourceCode: string = fs.readFileSync(modulePath, 'utf-8'); + +const fileContent: string = `// eslint-disable-next-line no-template-curly-in-string +export const workerCode = ${JSON.stringify(sourceCode)}; +`; + +const renderFilePath: string = path.resolve(workersDirectory, 'matrix-renderer.ts'); + +writeFile(renderFilePath, fileContent); \ No newline at end of file diff --git a/packages/nimble-components/build/generate-workers/rollup.config.js b/packages/nimble-components/build/generate-workers/rollup.config.js new file mode 100644 index 0000000000..5f9decf64b --- /dev/null +++ b/packages/nimble-components/build/generate-workers/rollup.config.js @@ -0,0 +1,13 @@ +import nodeResolve from '@rollup/plugin-node-resolve'; +import path from 'path'; + +export default { + input: path.resolve(__dirname, 'dist/esm/source/matrix-renderer.js'), + output: { + file: path.resolve(__dirname, 'dist/bundle/matrix-renderer.js'), + format: 'iife', + name: 'MatrixRenderer', + sourcemap: false + }, + plugins: [nodeResolve()] +}; \ No newline at end of file diff --git a/packages/nimble-components/build/generate-workers/source/matrix-renderer.ts b/packages/nimble-components/build/generate-workers/source/matrix-renderer.ts new file mode 100644 index 0000000000..96bae5689d --- /dev/null +++ b/packages/nimble-components/build/generate-workers/source/matrix-renderer.ts @@ -0,0 +1,23 @@ +import { expose } from 'comlink'; + +/** + * MatrixRenderer class is meant to be used within a Web Worker context, + * using Comlink to facilitate communication between the main thread and the worker. + * The MatrixRenderer class manages a matrix of dies, once an instance of MatrixRenderer is created, + * it is exposed to the main thread using Comlink's `expose` method. + * This setup is used in the wafer-map component to perform heavy computational duties + */ +export class MatrixRenderer { + public dieMatrix: Uint8Array = Uint8Array.from([]); + + public emptyMatrix(): void { + this.dieMatrix = Uint8Array.from([]);; + } + + public updateMatrix( + data: Iterable + ): void { + this.dieMatrix = Uint8Array.from(data); + } +} +expose(MatrixRenderer); \ No newline at end of file diff --git a/packages/nimble-components/build/generate-workers/source/tests/matrix-renderer.spec.ts b/packages/nimble-components/build/generate-workers/source/tests/matrix-renderer.spec.ts new file mode 100644 index 0000000000..c144814f18 --- /dev/null +++ b/packages/nimble-components/build/generate-workers/source/tests/matrix-renderer.spec.ts @@ -0,0 +1,28 @@ +import { Remote, expose, wrap } from 'comlink'; +import { MatrixRenderer } from '../matrix-renderer'; + +describe('MatrixRenderer with MessageChannel', () => { + let matrixRenderer: Remote; + + beforeEach(async () => { + const { port1, port2 } = new MessageChannel(); + const worker = new MatrixRenderer(); + expose(worker, port1); + matrixRenderer = await wrap(port2); + }); + + it('updateMatrix should update the dieMatrix', async () => { + const testData = [4, 5, 6]; + await matrixRenderer.updateMatrix(testData); + + const updatedMatrix = await matrixRenderer.dieMatrix; + expect(updatedMatrix).toEqual(Uint8Array.from(testData)); + }); + + it('emptyMatrix should empty the dieMatrix', async () => { + await matrixRenderer.emptyMatrix(); + + const updatedMatrix = await matrixRenderer.dieMatrix; + expect(updatedMatrix.length).toEqual(0); + }); +}); diff --git a/packages/nimble-components/build/generate-workers/tsconfig.json b/packages/nimble-components/build/generate-workers/tsconfig.json new file mode 100644 index 0000000000..9109e6e2bf --- /dev/null +++ b/packages/nimble-components/build/generate-workers/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "../../tsconfig.json", + "include": ["source", "index.ts"], + "compilerOptions": { + "outDir": "./dist/esm" + } +} \ No newline at end of file diff --git a/packages/nimble-components/package.json b/packages/nimble-components/package.json index d5df1c41f1..23208164f4 100644 --- a/packages/nimble-components/package.json +++ b/packages/nimble-components/package.json @@ -1,9 +1,9 @@ { "name": "@ni/nimble-components", - "version": "21.7.0", + "version": "21.7.1", "description": "Styled web components for the NI Nimble Design System", "scripts": { - "build": "npm run generate-icons && npm run build-components && npm run bundle-components && npm run generate-scss && npm run build-storybook", + "build": "npm run generate-icons && npm run generate-workers && npm run build-components && npm run bundle-components && npm run generate-scss && npm run build-storybook", "lint": "npm run eslint && npm run prettier", "format": "npm run eslint-fix && npm run prettier-fix", "eslint": "eslint .", @@ -24,6 +24,10 @@ "generate-scss": "npm run generate-scss:bundle && npm run generate-scss:run", "generate-scss:bundle": "rollup --bundleConfigAsCjs --config build/generate-scss/rollup.config.js", "generate-scss:run": "node build/generate-scss/dist/index.js", + "generate-workers": "npm run generate-workers:build && npm run generate-workers:bundle && npm run generate-workers:run", + "generate-workers:build": "tsc -p build/generate-workers/tsconfig.json", + "generate-workers:bundle": "rollup --bundleConfigAsCjs --config build/generate-workers/rollup.config.js", + "generate-workers:run": "node build/generate-workers/dist/esm/index.js", "tdd": "npm run build-components && npm run test-chrome", "tdd:watch": "npm run build-components:watch & npm run test-chrome:watch", "tdd-firefox": "npm run build-components && npm run test-firefox", @@ -87,6 +91,7 @@ "@types/d3-selection": "^3.0.0", "@types/d3-zoom": "^3.0.0", "@types/markdown-it": "^13.0.0", + "comlink": "4.4.1", "d3-array": "^3.2.2", "d3-random": "^3.0.1", "d3-scale": "^4.0.2", diff --git a/packages/nimble-components/src/utilities/tests/setup.ts b/packages/nimble-components/src/utilities/tests/setup.ts index 017668edf4..3364f6c46e 100644 --- a/packages/nimble-components/src/utilities/tests/setup.ts +++ b/packages/nimble-components/src/utilities/tests/setup.ts @@ -10,3 +10,10 @@ require('./setup-configuration.js'); // all browser test scripts importAll(require.context('../../', true, /\.spec\.js$/)); +importAll( + require.context( + '../../../../build/generate-workers/dist/esm', + true, + /\.spec\.js$/ + ) +); diff --git a/packages/nimble-components/src/wafer-map/modules/create-matrix-renderer.ts b/packages/nimble-components/src/wafer-map/modules/create-matrix-renderer.ts new file mode 100644 index 0000000000..735b1bdc2d --- /dev/null +++ b/packages/nimble-components/src/wafer-map/modules/create-matrix-renderer.ts @@ -0,0 +1,28 @@ +import { wrap, Remote } from 'comlink'; +import { workerCode } from '../workers/matrix-renderer'; +import type { MatrixRenderer } from '../../../build/generate-workers/dist/esm/source/matrix-renderer'; + +let url: string; + +/** + * Asynchronously creates and returns a Remote instance. + * This function simplifies the process of creating and accessing MatrixRenderer instances. + */ +export const createMatrixRenderer = async (): Promise<{ + matrixRenderer: Remote, + terminate: () => void +}> => { + if (url === undefined) { + const blob = new Blob([workerCode], { type: 'text/javascript' }); + url = URL.createObjectURL(blob); + } + const worker = new Worker(url); + // eslint-disable-next-line @typescript-eslint/naming-convention + const RemoteMatrixRenderer = wrap MatrixRenderer>(worker); + const matrixRenderer = await new RemoteMatrixRenderer(); + const terminate = (): void => worker.terminate(); + return { + matrixRenderer, + terminate + }; +}; diff --git a/packages/nimble-components/src/wafer-map/tests/create-matrix-renderer.spec.ts b/packages/nimble-components/src/wafer-map/tests/create-matrix-renderer.spec.ts new file mode 100644 index 0000000000..c412092a38 --- /dev/null +++ b/packages/nimble-components/src/wafer-map/tests/create-matrix-renderer.spec.ts @@ -0,0 +1,36 @@ +import type { Remote } from 'comlink'; +import { createMatrixRenderer } from '../modules/create-matrix-renderer'; +import type { MatrixRenderer } from '../../../build/generate-workers/dist/esm/source/matrix-renderer'; + +describe('MatrixRenderer worker', () => { + let matrixRenderer: Remote; + let terminate: () => void; + + beforeEach(async () => { + const result = await createMatrixRenderer(); + matrixRenderer = result.matrixRenderer; + terminate = result.terminate; + }); + + afterEach(() => { + terminate(); + matrixRenderer = undefined!; + }); + + it('updateMatrix should update the dieMatrix', async () => { + const testData = [4, 5, 6]; + await matrixRenderer.updateMatrix(testData); + const resolvedDieMatrix = await matrixRenderer.dieMatrix; + expect(Array.from(resolvedDieMatrix)).toEqual( + Array.from(Uint8Array.from(testData)) + ); + }); + + it('emptyMatrix should empty the dieMatrix', async () => { + const testData = [4, 5, 6]; + await matrixRenderer.updateMatrix(testData); + await matrixRenderer.emptyMatrix(); + const resolvedDieMatrix = await matrixRenderer.dieMatrix; + expect(resolvedDieMatrix.length).toEqual(0); + }); +});