From f9abc6419c9b32aacec4b05a625d08ec7ff407ba Mon Sep 17 00:00:00 2001 From: Akim <59872966+akim-bow@users.noreply.github.com> Date: Wed, 25 Oct 2023 19:02:42 +0700 Subject: [PATCH] chore(js-client)!: Simplify/optimize js-client and update README [fixes DXJ-490] (#366) * Update README * Improve build experience * Fix eslint * Fix eslint * Fix eslint * Fix tooling * Fix formatting * Fix formatting * Fix test resource name * Remove async * Fix comments * Add ts-check * Add new line * Fix arg * add todo's * Fix lint * Fix typo * Type module * Add deps to isomorphic package * Extract function type * Fix newline * Remove private * Use prepare hook instead of postinstall --- .gitignore | 1 + .prettierignore | 4 +- README.md | 123 +++++------- packages/@tests/test-utils/src/index.ts | 2 +- packages/core/aqua-to-js/package.json | 1 - .../src/generate/__test__/generate.spec.ts | 6 + .../core/js-client-isomorphic/package.json | 33 ++++ .../src/fetchers/browser.ts | 38 ++++ .../src/fetchers/node.ts | 38 ++-- .../core/js-client-isomorphic/src/types.ts | 23 +++ .../src/worker-resolvers/browser.ts | 38 ++++ .../src/worker-resolvers/node.ts | 35 ++++ .../core/js-client-isomorphic/tsconfig.json | 8 + packages/core/js-client/.gitignore | 2 + packages/core/js-client/.prettierignore | 1 - packages/core/js-client/README.md | 11 -- packages/core/js-client/createVersionFile.js | 41 ++++ packages/core/js-client/package.json | 22 +-- .../core/js-client/src/fetchers/browser.ts | 69 ------- packages/core/js-client/src/index.ts | 104 +++------- packages/core/js-client/src/network.ts | 187 ++++++++++++++++++ packages/core/js-client/tsconfig.json | 1 - packages/core/js-client/vite.config.ts | 7 +- pnpm-lock.yaml | 59 +++++- 24 files changed, 576 insertions(+), 278 deletions(-) create mode 100644 packages/core/js-client-isomorphic/package.json create mode 100644 packages/core/js-client-isomorphic/src/fetchers/browser.ts rename packages/core/{js-client => js-client-isomorphic}/src/fetchers/node.ts (59%) create mode 100644 packages/core/js-client-isomorphic/src/types.ts create mode 100644 packages/core/js-client-isomorphic/src/worker-resolvers/browser.ts create mode 100644 packages/core/js-client-isomorphic/src/worker-resolvers/node.ts create mode 100644 packages/core/js-client-isomorphic/tsconfig.json delete mode 100644 packages/core/js-client/.prettierignore delete mode 100644 packages/core/js-client/README.md create mode 100644 packages/core/js-client/createVersionFile.js delete mode 100644 packages/core/js-client/src/fetchers/browser.ts create mode 100644 packages/core/js-client/src/network.ts diff --git a/.gitignore b/.gitignore index 784700b5..d13592cd 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ node_modules/ # Build directory **/dist **/public +.DS_Store diff --git a/.prettierignore b/.prettierignore index ce207483..dd425f10 100644 --- a/.prettierignore +++ b/.prettierignore @@ -7,4 +7,6 @@ pnpm-lock.yaml **/build **/public -**/CHANGELOG.md \ No newline at end of file +**/CHANGELOG.md + +packages/core/js-client/src/versions.ts \ No newline at end of file diff --git a/README.md b/README.md index b8aa604b..c6ed200e 100644 --- a/README.md +++ b/README.md @@ -1,92 +1,72 @@ # Fluence JS Client -[![npm](https://img.shields.io/npm/v/@fluencelabs/js-client.api?label=@fluencelabs/js-client.api)](https://www.npmjs.com/package/@fluencelabs/js-client.api) -[![npm](https://img.shields.io/npm/v/@fluencelabs/js-client.web.standalone?label=@fluencelabs/js-client.web.standalone)](https://www.npmjs.com/package/@fluencelabs/js-client.web.standalone) +[![npm](https://img.shields.io/npm/v/@fluencelabs/js-client?label=@fluencelabs/js-client)](https://www.npmjs.com/package/@fluencelabs/js-client) This is the Javascript client for the [Fluence](https://fluence.network) network. The main role of the JS client is to connect to the Fluence Network and allow you to integrate Aqua code into your application. ## Installation -Adding the Fluence JS client for your web application is very easy. +> JS Client only supports the ESM format that means not every Node.js project can install it. +> You can read more [here](https://nodejs.org/api/esm.html) -### Browser-based Apps +1. Install the client: -1. Add a script tag with the JS Client bundle to your `index.html`. The easiest way to do this is using a CDN (like [JSDELIVR](https://www.jsdelivr.com/) or [UNPKG](https://unpkg.com/)). The script is large, thus we highly recommend to use the `async` attribute. - - Here is an example using the JSDELIVR CDN: - - ```html - - Cool App - - - ``` - - If you cannot or don't want to use a CDN, feel free to get the script directly from the [npm package](https://www.npmjs.com/package/@fluencelabs/js-client.web.standalone) and host it yourself. You can find the script in the `/dist` directory of the package. (Note: this option means that developers understand what they are doing and know how to serve this file from their own web server.) - -2. Install the following packages: - - ``` - npm i @fluencelabs/js-client.api @fluencelabs/fluence-network-environment - ``` - -3. Add the following lines at the beginning of your code: - - ``` - import { Fluence } from "@fluencelabs/js-client.api"; - import { randomKras } from '@fluencelabs/fluence-network-environment'; - - Fluence.connect(randomKras()); - ``` - -### Node.js Apps - -**Prerequisites:** - -The Fluence JS Client only supports the ESM format. This implies that a few preliminary steps are required if your project is not already using ESM: - -- Add `"type": "module"` to your package.json. -- Replace `"main": "index.js"` with `"exports": "./index.js"` in your package.json. -- Remove `'use strict';` from all JavaScript files. -- Replace all `require()`/`module.export` with `import`/`export`. -- Use only full relative file paths for imports: `import x from '.';` → `import x from './index.js';`. - -If you are using TypeScript: - -- Make sure you are using TypeScript 4.7 or later. -- Add [`"module": "ESNext", "target": "ESNext", "moduleResolution": "nodenext"`](https://www.typescriptlang.org/tsconfig#module) to your tsconfig.json. -- Use only full relative file paths for imports: `import x from '.';` → `import x from './index.js';`. -- Remove `namespace` usage and use `export` instead. -- You must use a `.js` extension in relative imports even though you're importing `.ts` files. - -**Installation:** - -1. Install the following packages: - - ``` - npm i @fluencelabs/js-client.api"@fluencelabs/js-client.node @fluencelabs/fluence-network-environment + ```bash + npm i @fluencelabs/js-client ``` 2. Add the following lines at the beginning of your code: - ``` - import '@fluencelabs/js-client.node'; - import { Fluence } from "@fluencelabs/js-client.api"; - import { randomKras } from '@fluencelabs/fluence-network-environment'; + ```javascript + import { Fluence, randomKras } from "@fluencelabs/js-client"; Fluence.connect(randomKras()); ``` +### HTML page + +Add a script tag with the JS Client bundle to your `index.html`. The easiest way to do this is using a CDN ( +like [JSDELIVR](https://www.jsdelivr.com/) or [UNPKG](https://unpkg.com/)). + +Here is an example using the JSDELIVR CDN: + +```html + + Cool App + + +``` + +If you cannot or don't want to use a CDN, feel free to get the script directly from +the [npm package](https://www.npmjs.com/package/@fluencelabs/js-client) and host it yourself. You can find the script in +the `/dist` directory of the package. (Note: this option means that developers understand what they are doing and know +how to serve this file from their own web server.) + +After importing JS-client to HTML page the client is available as `window.Fluence` variable. +To get a specific network you can peek at + +``` +https://cdn.jsdelivr.net/npm/@fluencelabs/js-client/dist/network.js +``` + +and hardcode selected network. So initialization would look like this + +```javascript +// Passing 1 kras network config from ./dist/network.js above +window.Fluence.connect({ + multiaddr: + "/dns4/0-kras.fluence.dev/tcp/9000/wss/p2p/12D3KooWSD5PToNiLQwKDXsu8JSysCwUt8BVUJEqCHcDe7P5h45e", + peerId: "12D3KooWSD5PToNiLQwKDXsu8JSysCwUt8BVUJEqCHcDe7P5h45e", +}); +``` + ## Usage in an Application Once you've added the client, you can compile [Aqua](https://github.com/fluencelabs/aqua) and run it in your application. To compile Aqua, use [Fluence CLI](https://github.com/fluencelabs/cli). 1. Install the package: - ``` + ```bash npm i -D @fluencelabs/cli ``` @@ -130,7 +110,7 @@ Once you've added the client, you can compile [Aqua](https://github.com/fluencel 6. Now you can import and call Aqua code from your application like this: - ``` + ```javascript import { getRelayTime } from "./_aqua/demo"; async function buttonClick() { @@ -172,7 +152,7 @@ Star (`*`) character can be used as a wildcard to enable logs for multiple compo ### Enabling logs in Node.js -enable logs, pass the environment variable `DEBUG` with the corresponding log level. For example: +Enable logs by passing the environment variable `DEBUG` with the corresponding log level. For example: ```sh DEBUG=fluence:* node --loader ts-node/esm ./src/index.ts @@ -182,13 +162,14 @@ DEBUG=fluence:* node --loader ts-node/esm ./src/index.ts To enable logs, set the `localStorage.debug` variable. For example: -``` -localStorage.debug = 'fluence:*' +```javascript +localStorage.debug = "fluence:*"; ``` **NOTE** -In Chromium-based web browsers (e.g. Brave, Chrome, and Electron), the JavaScript console will—by default—only show messages logged by debug if the "Verbose" log level is enabled. +In Chromium-based web browsers (e.g. Brave, Chrome, and Electron), the JavaScript console will be default—only to show +messages logged by debug if the "Verbose" log level is enabled. ## Development diff --git a/packages/@tests/test-utils/src/index.ts b/packages/@tests/test-utils/src/index.ts index 5cf9c599..4dfef918 100644 --- a/packages/@tests/test-utils/src/index.ts +++ b/packages/@tests/test-utils/src/index.ts @@ -59,7 +59,7 @@ export const startContentServer = ( rewrites: [ { source: "/js-client.min.js", - destination: "/source/index.umd.cjs", + destination: "/source/index.min.js", }, // TODO: // something like this diff --git a/packages/core/aqua-to-js/package.json b/packages/core/aqua-to-js/package.json index 39503e50..a6f2f33b 100644 --- a/packages/core/aqua-to-js/package.json +++ b/packages/core/aqua-to-js/package.json @@ -21,7 +21,6 @@ "@fluencelabs/aqua-api": "0.12.0", "@fluencelabs/aqua-lib": "0.7.3", "@fluencelabs/interfaces": "workspace:*", - "@fluencelabs/js-client": "workspace:*", "@fluencelabs/registry": "0.8.7", "@fluencelabs/spell": "0.5.20", "@fluencelabs/trust-graph": "0.4.7", diff --git a/packages/core/aqua-to-js/src/generate/__test__/generate.spec.ts b/packages/core/aqua-to-js/src/generate/__test__/generate.spec.ts index 34effb2b..4457d334 100644 --- a/packages/core/aqua-to-js/src/generate/__test__/generate.spec.ts +++ b/packages/core/aqua-to-js/src/generate/__test__/generate.spec.ts @@ -40,12 +40,18 @@ describe("Aqua to js/ts compiler", () => { }, }; + // TODO: see https://github.com/fluencelabs/js-client/pull/366#discussion_r1370567711 + // @ts-expect-error don't use compileFromPath directly here const jsResult = generateSources(res, "js", pkg); + // TODO: see https://github.com/fluencelabs/js-client/pull/366#discussion_r1370567711 + // @ts-expect-error don't use compileFromPath directly here const jsTypes = generateTypes(res, pkg); expect(jsResult).toMatchSnapshot(); expect(jsTypes).toMatchSnapshot(); + // TODO: see https://github.com/fluencelabs/js-client/pull/366#discussion_r1370567711 + // @ts-expect-error don't use compileFromPath directly here const tsResult = generateSources(res, "ts", pkg); expect(tsResult).toMatchSnapshot(); diff --git a/packages/core/js-client-isomorphic/package.json b/packages/core/js-client-isomorphic/package.json new file mode 100644 index 00000000..175178ed --- /dev/null +++ b/packages/core/js-client-isomorphic/package.json @@ -0,0 +1,33 @@ +{ + "type": "module", + "name": "@fluencelabs/js-client-isomorphic", + "version": "1.0.0", + "description": "Isomorphic entities for js-client", + "files": [ + "dist" + ], + "main": "index.js", + "scripts": { + "build": "tsc" + }, + "exports": { + ".": "./dist/types.js", + "./fetcher": { + "node": "./dist/fetchers/node.js", + "default": "./dist/fetchers/browser.js" + }, + "./worker-resolver": { + "node": "./dist/worker-resolvers/node.js", + "default": "./dist/worker-resolvers/browser.js" + } + }, + "dependencies": { + "@fluencelabs/avm": "0.52.0", + "@fluencelabs/marine-js": "0.7.2", + "@fluencelabs/marine-worker": "workspace:*", + "threads": "fluencelabs/threads.js#b00a5342380b0278d3ae56dcfb170effb3cad7cd" + }, + "keywords": [], + "author": "Fluence Labs", + "license": "Apache-2.0" +} diff --git a/packages/core/js-client-isomorphic/src/fetchers/browser.ts b/packages/core/js-client-isomorphic/src/fetchers/browser.ts new file mode 100644 index 00000000..e90e07c1 --- /dev/null +++ b/packages/core/js-client-isomorphic/src/fetchers/browser.ts @@ -0,0 +1,38 @@ +/** + * Copyright 2023 Fluence Labs Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { VersionedPackage } from "../types.js"; + +/** + * @param pkg name of package with version + * @param assetPath path of required asset in given package + * @param root CDN domain in browser or file system root in node + */ +export async function fetchResource( + pkg: VersionedPackage, + assetPath: string, + root: string, +) { + const refinedAssetPath = assetPath.startsWith("/") + ? assetPath.slice(1) + : assetPath; + + const url = new URL(`${pkg.name}@${pkg.version}/` + refinedAssetPath, root); + + return fetch(url).catch(() => { + throw new Error(`Cannot fetch from ${url.toString()}`); + }); +} diff --git a/packages/core/js-client/src/fetchers/node.ts b/packages/core/js-client-isomorphic/src/fetchers/node.ts similarity index 59% rename from packages/core/js-client/src/fetchers/node.ts rename to packages/core/js-client-isomorphic/src/fetchers/node.ts index 38a40ee3..94c0751e 100644 --- a/packages/core/js-client/src/fetchers/node.ts +++ b/packages/core/js-client-isomorphic/src/fetchers/node.ts @@ -14,49 +14,41 @@ * limitations under the License. */ -import fs from "fs"; -import module from "module"; -import path from "path"; +import { readFile } from "fs/promises"; +import { createRequire } from "module"; +import { sep, posix, join } from "path"; + +import type { VersionedPackage } from "../types.js"; /** - * @param pkg name of package + * @param pkg name of package with version * @param assetPath path of required asset in given package - * @param root CDN domain in browser or file system root in node + * @param root CDN domain in browser or js-client itself in node */ export async function fetchResource( - pkg: string, + pkg: VersionedPackage, assetPath: string, root: string, ) { // TODO: `root` will be handled somehow in the future. For now, we use filesystem root where js-client is running; root = "/"; - const require = module.createRequire(import.meta.url); - const packagePathIndex = require.resolve(pkg); + const require = createRequire(import.meta.url); + const packagePathIndex = require.resolve(pkg.name); // Ensure that windows path is converted to posix path. So we can find a package - const posixPath = packagePathIndex.split(path.sep).join(path.posix.sep); + const posixPath = packagePathIndex.split(sep).join(posix.sep); - const matches = new RegExp(`(.+${pkg})`).exec(posixPath); + const matches = new RegExp(`(.+${pkg.name})`).exec(posixPath); const packagePath = matches?.[0]; if (packagePath == null) { - throw new Error(`Cannot find dependency ${pkg} in path ${posixPath}`); + throw new Error(`Cannot find dependency ${pkg.name} in path ${posixPath}`); } - const pathToResource = path.join(root, packagePath, assetPath); + const pathToResource = join(root, packagePath, assetPath); - const file = await new Promise((resolve, reject) => { - // Cannot use 'fs/promises' with current vite config. This module is not polyfilled by default. - fs.readFile(pathToResource, (err, data) => { - if (err != null) { - reject(err); - return; - } - - resolve(data); - }); - }); + const file = await readFile(pathToResource); return new Response(file, { headers: { diff --git a/packages/core/js-client-isomorphic/src/types.ts b/packages/core/js-client-isomorphic/src/types.ts new file mode 100644 index 00000000..389bed28 --- /dev/null +++ b/packages/core/js-client-isomorphic/src/types.ts @@ -0,0 +1,23 @@ +/** + * Copyright 2023 Fluence Labs Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Worker } from "threads/master"; + +export type VersionedPackage = { name: string; version: string }; +export type GetWorker = ( + pkg: VersionedPackage, + CDNUrl: string, +) => Promise; diff --git a/packages/core/js-client-isomorphic/src/worker-resolvers/browser.ts b/packages/core/js-client-isomorphic/src/worker-resolvers/browser.ts new file mode 100644 index 00000000..c197c821 --- /dev/null +++ b/packages/core/js-client-isomorphic/src/worker-resolvers/browser.ts @@ -0,0 +1,38 @@ +/** + * Copyright 2023 Fluence Labs Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { BlobWorker } from "threads/master"; + +import { fetchResource } from "../fetchers/browser.js"; +import type { GetWorker, VersionedPackage } from "../types.js"; + +export const getWorker: GetWorker = async ( + pkg: VersionedPackage, + CDNUrl: string, +) => { + const fetchWorkerCode = async () => { + const resource = await fetchResource( + pkg, + "/dist/browser/marine-worker.umd.cjs", + CDNUrl, + ); + + return resource.text(); + }; + + const workerCode = await fetchWorkerCode(); + return BlobWorker.fromText(workerCode); +}; diff --git a/packages/core/js-client-isomorphic/src/worker-resolvers/node.ts b/packages/core/js-client-isomorphic/src/worker-resolvers/node.ts new file mode 100644 index 00000000..6e23bf8e --- /dev/null +++ b/packages/core/js-client-isomorphic/src/worker-resolvers/node.ts @@ -0,0 +1,35 @@ +/** + * Copyright 2023 Fluence Labs Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { createRequire } from "module"; +import { dirname, relative } from "path"; +import { fileURLToPath } from "url"; + +import { Worker } from "threads/master"; + +import type { GetWorker, VersionedPackage } from "../types.js"; + +export const getWorker: GetWorker = (pkg: VersionedPackage) => { + const require = createRequire(import.meta.url); + + const pathToThisFile = dirname(fileURLToPath(import.meta.url)); + + const pathToWorker = require.resolve(pkg.name); + + const relativePathToWorker = relative(pathToThisFile, pathToWorker); + + return Promise.resolve(new Worker(relativePathToWorker)); +}; diff --git a/packages/core/js-client-isomorphic/tsconfig.json b/packages/core/js-client-isomorphic/tsconfig.json new file mode 100644 index 00000000..a04ef1f8 --- /dev/null +++ b/packages/core/js-client-isomorphic/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../../../tsconfig.json", + "compilerOptions": { + "outDir": "./dist" + }, + "include": ["src/**/*"], + "exclude": ["node_modules", "dist"] +} diff --git a/packages/core/js-client/.gitignore b/packages/core/js-client/.gitignore index fe11902d..dfa77d72 100644 --- a/packages/core/js-client/.gitignore +++ b/packages/core/js-client/.gitignore @@ -22,3 +22,5 @@ jspm_packages/ # workaround to make integration tests work src/marine/worker-script/index.js + +src/versions.ts diff --git a/packages/core/js-client/.prettierignore b/packages/core/js-client/.prettierignore deleted file mode 100644 index 178135c2..00000000 --- a/packages/core/js-client/.prettierignore +++ /dev/null @@ -1 +0,0 @@ -/dist/ diff --git a/packages/core/js-client/README.md b/packages/core/js-client/README.md deleted file mode 100644 index 271a05d1..00000000 --- a/packages/core/js-client/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# JS Peer - -TDB - -## Contributing - -While the project is still in the early stages of development, you are welcome to track progress and contribute. As the project is undergoing rapid changes, interested contributors should contact the team before embarking on larger pieces of work. All contributors should consult with and agree to our [basic contributing rules](CONTRIBUTING.md). - -## License - -[Apache 2.0](LICENSE) diff --git a/packages/core/js-client/createVersionFile.js b/packages/core/js-client/createVersionFile.js new file mode 100644 index 00000000..32e58999 --- /dev/null +++ b/packages/core/js-client/createVersionFile.js @@ -0,0 +1,41 @@ +/* + * Copyright 2023 Fluence Labs Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// @ts-check + +import pkg from "./package.json" assert { type: "json" }; +import { writeFile } from "fs/promises"; +import { join, dirname } from "path"; +import { fileURLToPath } from "url"; + +const names = [ + "@fluencelabs/avm", + "@fluencelabs/marine-js", + "@fluencelabs/marine-worker", +]; + +const entries = Object.entries({ + ...pkg.dependencies, + ...pkg.devDependencies, +}).filter(([name]) => names.includes(name)); + +const output = Object.fromEntries(entries); + +await writeFile( + join(dirname(fileURLToPath(import.meta.url)), "src", "versions.ts"), + `/* eslint-disable */ +export default ${JSON.stringify(output, null, 2)} as const`, +); diff --git a/packages/core/js-client/package.json b/packages/core/js-client/package.json index 3e5b644d..fcd0a565 100644 --- a/packages/core/js-client/package.json +++ b/packages/core/js-client/package.json @@ -9,24 +9,23 @@ "files": [ "dist" ], - "main": "./dist/index.js", - "unpkg": "./dist/browser/index.umd.js", + "main": "./dist/browser/index.min.js", "types": "./dist/index.d.ts", "exports": { - "types": "./dist/index.d.ts", - "node": "./dist/index.js", - "default": "./dist/browser/index.js" - }, - "imports": { - "#fetcher": { - "node": "./dist/fetchers/node.js", - "default": "./dist/fetchers/browser.js" + ".": { + "types": "./dist/index.d.ts", + "import": "./dist/index.js" + }, + "./keypair": { + "types": "./dist/keypair/index.d.ts", + "import": "./dist/keypair/index.js" } }, "type": "module", "scripts": { "build": "tsc && vite build", - "test": "vitest --threads false run" + "test": "vitest --threads false run", + "prepare": "node createVersionFile.js" }, "repository": "https://github.com/fluencelabs/fluence-js", "author": "Fluence Labs", @@ -36,6 +35,7 @@ "@chainsafe/libp2p-yamux": "5.0.0", "@fluencelabs/avm": "0.52.0", "@fluencelabs/interfaces": "workspace:*", + "@fluencelabs/js-client-isomorphic": "workspace:*", "@fluencelabs/marine-worker": "0.4.0", "@libp2p/crypto": "2.0.3", "@libp2p/interface": "0.1.2", diff --git a/packages/core/js-client/src/fetchers/browser.ts b/packages/core/js-client/src/fetchers/browser.ts deleted file mode 100644 index 114579fa..00000000 --- a/packages/core/js-client/src/fetchers/browser.ts +++ /dev/null @@ -1,69 +0,0 @@ -/** - * Copyright 2023 Fluence Labs Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -interface PackageJsonContent { - dependencies: Record; - devDependencies: Record; -} - -// This will be substituted in build phase -const packageJsonContentString = `__PACKAGE_JSON_CONTENT__`; -let parsedPackageJsonContent: PackageJsonContent | undefined; - -/** - * @param pkg name of package - * @param assetPath path of required asset in given package - * @param root CDN domain in browser or file system root in node - */ -export async function fetchResource( - pkg: string, - assetPath: string, - root: string, -) { - const packageJsonContent = - parsedPackageJsonContent ?? - // TODO: Should be validated - // eslint-disable-next-line @typescript-eslint/consistent-type-assertions - (parsedPackageJsonContent = JSON.parse( - packageJsonContentString, - ) as PackageJsonContent); - - const version = - packageJsonContent.dependencies[pkg] ?? - packageJsonContent.devDependencies[pkg]; - - if (version === undefined) { - const availableDeps = [ - ...Object.keys(packageJsonContent.dependencies), - ...Object.keys(packageJsonContent.devDependencies), - ]; - - throw new Error( - `Cannot find version of ${pkg} in package.json. Available versions: ${availableDeps.join( - ",", - )}`, - ); - } - - const refinedAssetPath = assetPath.startsWith("/") - ? assetPath.slice(1) - : assetPath; - - const url = new globalThis.URL(`${pkg}@${version}/` + refinedAssetPath, root); - return fetch(url).catch(() => { - throw new Error(`Cannot fetch from ${url.toString()}`); - }); -} diff --git a/packages/core/js-client/src/index.ts b/packages/core/js-client/src/index.ts index 755382eb..3c12cb45 100644 --- a/packages/core/js-client/src/index.ts +++ b/packages/core/js-client/src/index.ts @@ -14,12 +14,9 @@ * limitations under the License. */ -import module from "module"; -import path from "path"; -import process from "process"; -import url from "url"; - -import { BlobWorker, Worker } from "threads/master"; +import type { VersionedPackage } from "@fluencelabs/js-client-isomorphic"; +import { fetchResource } from "@fluencelabs/js-client-isomorphic/fetcher"; +import { getWorker } from "@fluencelabs/js-client-isomorphic/worker-resolver"; import { ClientPeer, makeClientPeerConfig } from "./clientPeer/ClientPeer.js"; import { @@ -30,36 +27,26 @@ import { import { callAquaFunction } from "./compilerSupport/callFunction.js"; import { registerService } from "./compilerSupport/registerService.js"; import { MarineBackgroundRunner } from "./marine/worker/index.js"; -import { doRegisterNodeUtils } from "./services/NodeUtils.js"; - -import { fetchResource } from "#fetcher"; +import versions from "./versions.js"; const DEFAULT_CDN_URL = "https://unpkg.com"; -const isNode = - // process.release is undefined in browser env - // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition - typeof process !== "undefined" && process.release?.name === "node"; +const getVersionedPackage = (pkg: keyof typeof versions): VersionedPackage => { + return { + name: pkg, + version: versions[pkg], + }; +}; const createClient = async ( relay: RelayOptions, - config: ClientConfig, + config: ClientConfig = {}, ): Promise => { const CDNUrl = config.CDNUrl ?? DEFAULT_CDN_URL; - const fetchWorkerCode = async () => { - const resource = await fetchResource( - "@fluencelabs/marine-worker", - "/dist/browser/marine-worker.umd.cjs", - CDNUrl, - ); - - return resource.text(); - }; - const fetchMarineJsWasm = async () => { const resource = await fetchResource( - "@fluencelabs/marine-js", + getVersionedPackage("@fluencelabs/marine-js"), "/dist/marine-js.wasm", CDNUrl, ); @@ -69,7 +56,7 @@ const createClient = async ( const fetchAvmWasm = async () => { const resource = await fetchResource( - "@fluencelabs/avm", + getVersionedPackage("@fluencelabs/avm"), "/dist/avm.wasm", CDNUrl, ); @@ -83,25 +70,10 @@ const createClient = async ( const marine = new MarineBackgroundRunner( { async getValue() { - if (isNode) { - const require = module.createRequire(import.meta.url); - - const pathToThisFile = path.dirname( - url.fileURLToPath(import.meta.url), - ); - - const pathToWorker = require.resolve("@fluencelabs/marine-worker"); - - const relativePathToWorker = path.relative( - pathToThisFile, - pathToWorker, - ); - - return new Worker(relativePathToWorker); - } else { - const workerCode = await fetchWorkerCode(); - return BlobWorker.fromText(workerCode); - } + return getWorker( + getVersionedPackage("@fluencelabs/marine-worker"), + CDNUrl, + ); }, start() { return Promise.resolve(undefined); @@ -141,9 +113,10 @@ const createClient = async ( const client = new ClientPeer(peerConfig, relayConfig, keyPair, marine); - if (isNode) { - doRegisterNodeUtils(client); - } + // TODO: Support node specific utils + // if (isNode) { + // doRegisterNodeUtils(client); + // } await client.connect(); return client; @@ -154,7 +127,7 @@ const createClient = async ( */ interface FluencePublicApi { defaultClient: ClientPeer | undefined; - connect: (relay: RelayOptions, config: ClientConfig) => Promise; + connect: (relay: RelayOptions, config?: ClientConfig) => Promise; disconnect: () => Promise; onConnectionStateChange: ( handler: (state: ConnectionState) => void, @@ -205,37 +178,8 @@ export const Fluence: FluencePublicApi = { }, }; -export type { CallParams } from "@fluencelabs/interfaces"; - export type { ClientConfig, IFluenceClient } from "./clientPeer/types.js"; -export type { - ArrayType, - ArrowType, - ArrowWithCallbacks, - ArrowWithoutCallbacks, - BottomType, - FunctionCallConstants, - FunctionCallDef, - LabeledProductType, - NilType, - NonArrowType, - OptionType, - ProductType, - ScalarNames, - ScalarType, - ServiceDef, - StructType, - TopType, - UnlabeledProductType, - CallAquaFunctionType, - CallAquaFunctionArgs, - PassedArgs, - FnConfig, - RegisterServiceType, - RegisterServiceArgs, -} from "@fluencelabs/interfaces"; - export { v5_callFunction, v5_registerService } from "./api.js"; // @ts-expect-error Writing to global object like this prohibited by ts @@ -249,9 +193,13 @@ globalThis.fluence = { }; export { createClient, callAquaFunction, registerService }; + +// Deprecated exports. Later they will be exposed only under js-client/keypair path export { KeyPair, fromBase64Sk, fromBase58Sk, fromOpts, } from "./keypair/index.js"; + +export * from "./network.js"; diff --git a/packages/core/js-client/src/network.ts b/packages/core/js-client/src/network.ts new file mode 100644 index 00000000..42c74f73 --- /dev/null +++ b/packages/core/js-client/src/network.ts @@ -0,0 +1,187 @@ +/** + * Copyright 2023 Fluence Labs Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export type Relay = { peerId: string; multiaddr: string }; + +export const stage: Relay[] = [ + { + multiaddr: + "/dns4/0-stage.fluence.dev/tcp/9000/wss/p2p/12D3KooWDcpWuyrMTDinqNgmXAuRdfd2mTdY9VoXZSAet2pDzh6r", + peerId: "12D3KooWDcpWuyrMTDinqNgmXAuRdfd2mTdY9VoXZSAet2pDzh6r", + }, + { + multiaddr: + "/dns4/1-stage.fluence.dev/tcp/9000/wss/p2p/12D3KooWHCJbJKGDfCgHSoCuK9q4STyRnVveqLoXAPBbXHTZx9Cv", + peerId: "12D3KooWHCJbJKGDfCgHSoCuK9q4STyRnVveqLoXAPBbXHTZx9Cv", + }, + { + multiaddr: + "/dns4/2-stage.fluence.dev/tcp/9000/wss/p2p/12D3KooWMigkP4jkVyufq5JnDJL6nXvyjeaDNpRfEZqQhsG3sYCU", + peerId: "12D3KooWMigkP4jkVyufq5JnDJL6nXvyjeaDNpRfEZqQhsG3sYCU", + }, + { + multiaddr: + "/dns4/3-stage.fluence.dev/tcp/9000/wss/p2p/12D3KooWMMGdfVEJ1rWe1nH1nehYDzNEHhg5ogdfiGk88AupCMnf", + peerId: "12D3KooWMMGdfVEJ1rWe1nH1nehYDzNEHhg5ogdfiGk88AupCMnf", + }, + { + multiaddr: + "/dns4/4-stage.fluence.dev/tcp/9000/wss/p2p/12D3KooWJ4bTHirdTFNZpCS72TAzwtdmavTBkkEXtzo6wHL25CtE", + peerId: "12D3KooWJ4bTHirdTFNZpCS72TAzwtdmavTBkkEXtzo6wHL25CtE", + }, + { + multiaddr: + "/dns4/5-stage.fluence.dev/tcp/9000/wss/p2p/12D3KooWAKNos2KogexTXhrkMZzFYpLHuWJ4PgoAhurSAv7o5CWA", + peerId: "12D3KooWAKNos2KogexTXhrkMZzFYpLHuWJ4PgoAhurSAv7o5CWA", + }, +]; + +export const testNet: Relay[] = [ + { + multiaddr: + "/dns4/0-testnet.fluence.dev/tcp/9000/wss/p2p/12D3KooWMhVpgfQxBLkQkJed8VFNvgN4iE6MD7xCybb1ZYWW2Gtz", + peerId: "12D3KooWMhVpgfQxBLkQkJed8VFNvgN4iE6MD7xCybb1ZYWW2Gtz", + }, + { + multiaddr: + "/dns4/1-testnet.fluence.dev/tcp/9000/wss/p2p/12D3KooWEXNUbCXooUwHrHBbrmjsrpHXoEphPwbjQXEGyzbqKnE9", + peerId: "12D3KooWEXNUbCXooUwHrHBbrmjsrpHXoEphPwbjQXEGyzbqKnE9", + }, + { + multiaddr: + "/dns4/2-testnet.fluence.dev/tcp/9000/wss/p2p/12D3KooWHk9BjDQBUqnavciRPhAYFvqKBe4ZiPPvde7vDaqgn5er", + peerId: "12D3KooWHk9BjDQBUqnavciRPhAYFvqKBe4ZiPPvde7vDaqgn5er", + }, + { + multiaddr: + "/dns4/3-testnet.fluence.dev/tcp/9000/wss/p2p/12D3KooWBUJifCTgaxAUrcM9JysqCcS4CS8tiYH5hExbdWCAoNwb", + peerId: "12D3KooWBUJifCTgaxAUrcM9JysqCcS4CS8tiYH5hExbdWCAoNwb", + }, + { + multiaddr: + "/dns4/4-testnet.fluence.dev/tcp/9000/wss/p2p/12D3KooWJbJFaZ3k5sNd8DjQgg3aERoKtBAnirEvPV8yp76kEXHB", + peerId: "12D3KooWJbJFaZ3k5sNd8DjQgg3aERoKtBAnirEvPV8yp76kEXHB", + }, + { + multiaddr: + "/dns4/5-testnet.fluence.dev/tcp/9000/wss/p2p/12D3KooWCKCeqLPSgMnDjyFsJuWqREDtKNHx1JEBiwaMXhCLNTRb", + peerId: "12D3KooWCKCeqLPSgMnDjyFsJuWqREDtKNHx1JEBiwaMXhCLNTRb", + }, + { + multiaddr: + "/dns4/6-testnet.fluence.dev/tcp/9000/wss/p2p/12D3KooWKnRcsTpYx9axkJ6d69LPfpPXrkVLe96skuPTAo76LLVH", + peerId: "12D3KooWKnRcsTpYx9axkJ6d69LPfpPXrkVLe96skuPTAo76LLVH", + }, + { + multiaddr: + "/dns4/7-testnet.fluence.dev/tcp/9000/wss/p2p/12D3KooWBSdm6TkqnEFrgBuSkpVE3dR1kr6952DsWQRNwJZjFZBv", + peerId: "12D3KooWBSdm6TkqnEFrgBuSkpVE3dR1kr6952DsWQRNwJZjFZBv", + }, + { + multiaddr: + "/dns4/8-testnet.fluence.dev/tcp/9000/wss/p2p/12D3KooWGzNvhSDsgFoHwpWHAyPf1kcTYCGeRBPfznL8J6qdyu2H", + peerId: "12D3KooWGzNvhSDsgFoHwpWHAyPf1kcTYCGeRBPfznL8J6qdyu2H", + }, + { + multiaddr: + "/dns4/9-testnet.fluence.dev/tcp/9000/wss/p2p/12D3KooWF7gjXhQ4LaKj6j7ntxsPpGk34psdQicN2KNfBi9bFKXg", + peerId: "12D3KooWF7gjXhQ4LaKj6j7ntxsPpGk34psdQicN2KNfBi9bFKXg", + }, + { + multiaddr: + "/dns4/10-testnet.fluence.dev/tcp/9000/wss/p2p/12D3KooWB9P1xmV3c7ZPpBemovbwCiRRTKd3Kq2jsVPQN4ZukDfy", + peerId: "12D3KooWB9P1xmV3c7ZPpBemovbwCiRRTKd3Kq2jsVPQN4ZukDfy", + }, +]; + +export const kras: Relay[] = [ + { + multiaddr: + "/dns4/0-kras.fluence.dev/tcp/9000/wss/p2p/12D3KooWSD5PToNiLQwKDXsu8JSysCwUt8BVUJEqCHcDe7P5h45e", + peerId: "12D3KooWSD5PToNiLQwKDXsu8JSysCwUt8BVUJEqCHcDe7P5h45e", + }, + { + multiaddr: + "/dns4/1-kras.fluence.dev/tcp/9000/wss/p2p/12D3KooWR4cv1a8tv7pps4HH6wePNaK6gf1Hww5wcCMzeWxyNw51", + peerId: "12D3KooWR4cv1a8tv7pps4HH6wePNaK6gf1Hww5wcCMzeWxyNw51", + }, + { + multiaddr: + "/dns4/2-kras.fluence.dev/tcp/9000/wss/p2p/12D3KooWKnEqMfYo9zvfHmqTLpLdiHXPe4SVqUWcWHDJdFGrSmcA", + peerId: "12D3KooWKnEqMfYo9zvfHmqTLpLdiHXPe4SVqUWcWHDJdFGrSmcA", + }, + { + multiaddr: + "/dns4/3-kras.fluence.dev/tcp/9000/wss/p2p/12D3KooWHLxVhUQyAuZe6AHMB29P7wkvTNMn7eDMcsqimJYLKREf", + peerId: "12D3KooWHLxVhUQyAuZe6AHMB29P7wkvTNMn7eDMcsqimJYLKREf", + }, + { + multiaddr: + "/dns4/4-kras.fluence.dev/tcp/9000/wss/p2p/12D3KooWJd3HaMJ1rpLY1kQvcjRPEvnDwcXrH8mJvk7ypcZXqXGE", + peerId: "12D3KooWJd3HaMJ1rpLY1kQvcjRPEvnDwcXrH8mJvk7ypcZXqXGE", + }, + { + multiaddr: + "/dns4/5-kras.fluence.dev/tcp/9000/wss/p2p/12D3KooWFEwNWcHqi9rtsmDhsYcDbRUCDXH84RC4FW6UfsFWaoHi", + peerId: "12D3KooWFEwNWcHqi9rtsmDhsYcDbRUCDXH84RC4FW6UfsFWaoHi", + }, + { + multiaddr: + "/dns4/6-kras.fluence.dev/tcp/9000/wss/p2p/12D3KooWCMr9mU894i8JXAFqpgoFtx6qnV1LFPSfVc3Y34N4h4LS", + peerId: "12D3KooWCMr9mU894i8JXAFqpgoFtx6qnV1LFPSfVc3Y34N4h4LS", + }, + { + multiaddr: + "/dns4/7-kras.fluence.dev/tcp/9000/wss/p2p/12D3KooWDUszU2NeWyUVjCXhGEt1MoZrhvdmaQQwtZUriuGN1jTr", + peerId: "12D3KooWDUszU2NeWyUVjCXhGEt1MoZrhvdmaQQwtZUriuGN1jTr", + }, + { + multiaddr: + "/dns4/8-kras.fluence.dev/tcp/9000/wss/p2p/12D3KooWEFFCZnar1cUJQ3rMWjvPQg6yMV2aXWs2DkJNSRbduBWn", + peerId: "12D3KooWEFFCZnar1cUJQ3rMWjvPQg6yMV2aXWs2DkJNSRbduBWn", + }, + { + multiaddr: + "/dns4/9-kras.fluence.dev/tcp/9000/wss/p2p/12D3KooWFtf3rfCDAfWwt6oLZYZbDfn9Vn7bv7g6QjjQxUUEFVBt", + peerId: "12D3KooWFtf3rfCDAfWwt6oLZYZbDfn9Vn7bv7g6QjjQxUUEFVBt", + }, + { + multiaddr: + "/dns4/10-kras.fluence.dev/tcp/9000/wss/p2p/12D3KooWD7CvsYcpF9HE9CCV9aY3SJ317tkXVykjtZnht2EbzDPm", + peerId: "12D3KooWD7CvsYcpF9HE9CCV9aY3SJ317tkXVykjtZnht2EbzDPm", + }, +]; + +export const randomKras = () => { + return randomItem(kras); +}; + +export const randomTestNet = () => { + return randomItem(testNet); +}; + +export const randomStage = () => { + return randomItem(stage); +}; + +function randomItem(arr: Relay[]) { + const index = randomInt(0, arr.length); + return arr[index]; +} + +function randomInt(min: number, max: number) { + return Math.floor(Math.random() * (max - min)) + min; +} diff --git a/packages/core/js-client/tsconfig.json b/packages/core/js-client/tsconfig.json index 70f838c9..6486ca5d 100644 --- a/packages/core/js-client/tsconfig.json +++ b/packages/core/js-client/tsconfig.json @@ -3,7 +3,6 @@ "compilerOptions": { "types": ["vite/client"], "outDir": "./dist", - "esModuleInterop": true, "resolveJsonModule": true, "rootDir": "src" }, diff --git a/packages/core/js-client/vite.config.ts b/packages/core/js-client/vite.config.ts index 6cfe3847..80af8845 100644 --- a/packages/core/js-client/vite.config.ts +++ b/packages/core/js-client/vite.config.ts @@ -17,7 +17,6 @@ import inject from "@rollup/plugin-inject"; import tsconfigPaths from "vite-tsconfig-paths"; import { createRequire } from "module"; -import { readFileSync } from "fs"; import { UserConfig } from "vite"; const require = createRequire(import.meta.url); @@ -30,7 +29,8 @@ const config: UserConfig = { lib: { entry: "./src/index.ts", name: "js-client", - fileName: "index", + fileName: () => "index.min.js", + formats: ["umd"], }, outDir: "./dist/browser", rollupOptions: { @@ -55,9 +55,6 @@ const config: UserConfig = { }, }, }, - define: { - __PACKAGE_JSON_CONTENT__: readFileSync("./package.json", "utf-8"), - }, }; export default config; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e09e67cf..9c9477f9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -169,9 +169,6 @@ importers: '@fluencelabs/interfaces': specifier: workspace:* version: link:../interfaces - '@fluencelabs/js-client': - specifier: workspace:* - version: link:../js-client '@fluencelabs/registry': specifier: 0.8.7 version: 0.8.7 @@ -211,6 +208,9 @@ importers: '@fluencelabs/interfaces': specifier: workspace:* version: link:../interfaces + '@fluencelabs/js-client-isomorphic': + specifier: workspace:* + version: link:../js-client-isomorphic '@fluencelabs/marine-worker': specifier: 0.4.0 version: link:../marine-worker @@ -318,6 +318,21 @@ importers: specifier: 0.34.6 version: 0.34.6 + packages/core/js-client-isomorphic: + dependencies: + '@fluencelabs/avm': + specifier: 0.52.0 + version: 0.52.0 + '@fluencelabs/marine-js': + specifier: 0.7.2 + version: 0.7.2 + '@fluencelabs/marine-worker': + specifier: workspace:* + version: link:../marine-worker + threads: + specifier: fluencelabs/threads.js#b00a5342380b0278d3ae56dcfb170effb3cad7cd + version: github.com/fluencelabs/threads.js/b00a5342380b0278d3ae56dcfb170effb3cad7cd + packages/core/marine-worker: dependencies: '@fluencelabs/marine-js': @@ -1166,6 +1181,16 @@ packages: '@babel/helper-plugin-utils': 7.22.5 dev: false + /@babel/plugin-syntax-flow@7.22.5(@babel/core@7.22.10): + resolution: {integrity: sha512-9RdCl0i+q0QExayk2nOS7853w08yLucnnPML6EN9S8fgMPVtdLDCdx/cOQ/i44Lb9UeQX9A35yaqBBOMMZxPxQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.10 + '@babel/helper-plugin-utils': 7.22.5 + dev: false + /@babel/plugin-syntax-flow@7.22.5(@babel/core@7.22.5): resolution: {integrity: sha512-9RdCl0i+q0QExayk2nOS7853w08yLucnnPML6EN9S8fgMPVtdLDCdx/cOQ/i44Lb9UeQX9A35yaqBBOMMZxPxQ==} engines: {node: '>=6.9.0'} @@ -1252,6 +1277,16 @@ packages: '@babel/helper-plugin-utils': 7.22.5 dev: false + /@babel/plugin-syntax-jsx@7.22.5(@babel/core@7.22.10): + resolution: {integrity: sha512-gvyP4hZrgrs/wWMaocvxZ44Hw0b3W8Pe+cMxc8V1ULQ07oh8VNbIRaoD1LRZVTvD+0nieDKjfgKg89sD7rrKrg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.10 + '@babel/helper-plugin-utils': 7.22.5 + dev: false + /@babel/plugin-syntax-jsx@7.22.5(@babel/core@7.22.5): resolution: {integrity: sha512-gvyP4hZrgrs/wWMaocvxZ44Hw0b3W8Pe+cMxc8V1ULQ07oh8VNbIRaoD1LRZVTvD+0nieDKjfgKg89sD7rrKrg==} engines: {node: '>=6.9.0'} @@ -2375,6 +2410,20 @@ packages: '@babel/plugin-transform-react-jsx': 7.22.5(@babel/core@7.22.5) dev: false + /@babel/plugin-transform-react-jsx@7.22.5(@babel/core@7.22.10): + resolution: {integrity: sha512-rog5gZaVbUip5iWDMTYbVM15XQq+RkUKhET/IHR6oizR+JEoN6CAfTTuHcK4vwUyzca30qqHqEpzBOnaRMWYMA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.10 + '@babel/helper-annotate-as-pure': 7.22.5 + '@babel/helper-module-imports': 7.22.5 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-jsx': 7.22.5(@babel/core@7.22.10) + '@babel/types': 7.22.5 + dev: false + /@babel/plugin-transform-react-jsx@7.22.5(@babel/core@7.22.5): resolution: {integrity: sha512-rog5gZaVbUip5iWDMTYbVM15XQq+RkUKhET/IHR6oizR+JEoN6CAfTTuHcK4vwUyzca30qqHqEpzBOnaRMWYMA==} engines: {node: '>=6.9.0'} @@ -10373,8 +10422,8 @@ packages: '@babel/plugin-transform-react-jsx': ^7.14.9 eslint: ^8.1.0 dependencies: - '@babel/plugin-syntax-flow': 7.22.5(@babel/core@7.22.5) - '@babel/plugin-transform-react-jsx': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-syntax-flow': 7.22.5(@babel/core@7.22.10) + '@babel/plugin-transform-react-jsx': 7.22.5(@babel/core@7.22.10) eslint: 8.50.0 lodash: 4.17.21 string-natural-compare: 3.0.1