From cdb1e6ed1c0c0ad9025b87fa8f2c2c83ad3c1606 Mon Sep 17 00:00:00 2001 From: Jonas Nicklas Date: Sat, 29 Jan 2022 13:01:17 +0100 Subject: [PATCH] Add remote package for calling interactors on a remote process --- package.json | 2 + packages/remote/example/client.ts | 12 +++ packages/remote/example/server.ts | 20 +++++ packages/remote/package.json | 61 +++++++++++++ packages/remote/src/index.ts | 103 ++++++++++++++++++++++ packages/remote/tsconfig.build.json | 15 ++++ packages/remote/tsconfig.json | 4 + packages/remote/typedoc.json | 7 ++ yarn.lock | 132 ++++++++++++++++++++++++++-- 9 files changed, 351 insertions(+), 5 deletions(-) create mode 100644 packages/remote/example/client.ts create mode 100644 packages/remote/example/server.ts create mode 100644 packages/remote/package.json create mode 100644 packages/remote/src/index.ts create mode 100644 packages/remote/tsconfig.build.json create mode 100644 packages/remote/tsconfig.json create mode 100644 packages/remote/typedoc.json diff --git a/package.json b/package.json index 36bca341..dbcf956f 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,7 @@ "packages/globals", "packages/core", "packages/keyboard", + "packages/remote", "packages/html", "packages/material-ui", "packages/with-cypress" @@ -48,6 +49,7 @@ "resolutions": { "@definitelytyped/typescript-versions": "^0.0.40", "@typescript-eslint/eslint-plugin": "^4.12.0", + "@effection/core": "^2.2.0", "chromedriver": "96.0.0", "typescript": "^4.1.3", "yargs-parser": "^13.1.2" diff --git a/packages/remote/example/client.ts b/packages/remote/example/client.ts new file mode 100644 index 00000000..cc4e5249 --- /dev/null +++ b/packages/remote/example/client.ts @@ -0,0 +1,12 @@ +import { connect } from '../src/index'; +import { main } from 'effection'; +import { Heading, Link } from '@interactors/html'; + +main(function*() { + console.log("[client] connecting..."); + yield connect('ws://127.0.0.1:30400'); + console.log("[client] connected!"); + + yield Heading('Hello World').exists(); + yield Link('Some Link').has({ href: '/incorrect' }); +}); diff --git a/packages/remote/example/server.ts b/packages/remote/example/server.ts new file mode 100644 index 00000000..1d40e80f --- /dev/null +++ b/packages/remote/example/server.ts @@ -0,0 +1,20 @@ +import { serve } from '../src/index'; +import { main } from 'effection'; +import { Heading, Link } from '@interactors/html'; +import { JSDOM } from 'jsdom'; +import { setDocumentResolver } from '@interactors/globals'; + +let dom = new JSDOM(` + + +

Hello World

+ Some Link + +`); + +setDocumentResolver(() => dom.window.document); + +main(function*() { + console.log('[server] starting'); + yield serve(30400, [Heading, Link]); +}); diff --git a/packages/remote/package.json b/packages/remote/package.json new file mode 100644 index 00000000..b7662952 --- /dev/null +++ b/packages/remote/package.json @@ -0,0 +1,61 @@ +{ + "name": "@interactors/remote", + "version": "1.0.0-rc1.2", + "description": "Call interactors running in a remote process", + "main": "dist/cjs/index.js", + "browser": "dist/esm/index.js", + "types": "dist/index.d.ts", + "repository": "https://github.com/thefrontside/interactors.git", + "homepage": "https://frontside.com/interactors", + "author": "Frontside Engineering ", + "license": "MIT", + "files": [ + "dist/**/*", + "src/**/*", + "README.md" + ], + "exports": { + ".": { + "require": "./dist/cjs/index.js", + "default": "./dist/esm/index.js" + } + }, + "scripts": { + "clean": "rm -rf dist *.tsbuildinfo", + "lint": "eslint \"{src,test}/**/*.ts\"", + "check:types": "tsc --noEmit", + "test": "mocha -r ts-node/register \"test/**/*.test.ts\"", + "docs": "rm -rf docs && yarn typedoc --options typedoc.json", + "docs:netlify": "yarn prepack && yarn docs", + "docs:preview": "yarn parcel docs/api/v1/index.html", + "prepack": "tsc --build ./tsconfig.build.json && yarn prepack:es2015 && yarn prepack:commonjs", + "prepack:es2015": "tsc --project ./tsconfig.build.json --outdir dist/esm --module es2015", + "prepack:commonjs": "tsc --project ./tsconfig.build.json --outdir dist/cjs --module commonjs" + }, + "dependencies": { + "@effection/core": "^2.2.0", + "@effection/dispatch": "^2.0.3", + "@effection/websocket-client": "^2.0.3", + "@effection/websocket-server": "^2.0.3", + "@interactors/core": "1.0.0-rc1.2", + "@interactors/globals": "1.0.0-rc1.1", + "uuid": "^8.3.2" + }, + "devDependencies": { + "@frontside/tsconfig": "^1.2.0", + "@types/mocha": "^7.0.1", + "@types/node": "^14.17.5", + "@types/uuid": "^8.3.4", + "expect": "^24.9.0", + "jsdom": "^16.2.2", + "mocha": "^6.2.2", + "parcel": "^2.0.0-beta.2", + "ts-node": "^10.4.0", + "typedoc": "^0.22.7", + "typescript": "~4.4.4" + }, + "volta": { + "node": "14.17.5", + "yarn": "1.22.11" + } +} diff --git a/packages/remote/src/index.ts b/packages/remote/src/index.ts new file mode 100644 index 00000000..1b144d7c --- /dev/null +++ b/packages/remote/src/index.ts @@ -0,0 +1,103 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +import { Operation, spawn } from '@effection/core'; +import { addInteractionWrapper } from '@interactors/globals'; +import { InteractorConstructor, Interactor } from '@interactors/core'; +import { createWebSocketServer, WebSocketConnection, WebSocketServer } from '@effection/websocket-server'; +import { createWebSocketClient, WebSocketClient } from '@effection/websocket-client'; +import { createDispatch } from '@effection/dispatch'; +import { v4 as uuid } from 'uuid'; + +type ServerMessage = { + key: string; + name: string; + args: unknown[]; + options: SerializedOptions, +}; + +type ClientMessage = { + key: string; + status: "success" | "error"; + value?: unknown; + error?: string; +}; + +// TODO: we should change InteractionOptions in core so it is more easily serializable +type SerializedOptions = { + name: string; + locator: string | undefined; + filters: Record; + ancestors: SerializedOptions[]; +} + +function serializeOptions(options: Interactor['options']): SerializedOptions { + return { + name: options.name, + locator: options.locator?.value as string | undefined, + filters: options.filter.filters, + ancestors: options.ancestors.map(serializeOptions), + } +} + +export function connect(url: string): Operation { + return { + *init() { + let client: WebSocketClient = yield createWebSocketClient(url); + let dispatch = createDispatch(); + + addInteractionWrapper(function*(perform, interaction) { + let key = uuid(); + let interactor = interaction.interactor as Interactor; + yield client.send({ + key, + name: interaction.options.name, + args: interaction.options.args, + options: serializeOptions(interactor.options), + }); + + let reply: ClientMessage = yield dispatch.get(key).expect(); + if(reply.status === 'error') { + throw new Error(reply.error || "unknown error"); + } else { + return reply.value as any; + } + }) + + yield spawn(client.forEach(function*(message) { + dispatch.send(message.key, message); + })); + } + } +} + +export function* serve(port: number, interactors: InteractorConstructor[]): Operation { + let map = new Map(interactors.map((i) => [i.interactorName, i])); + console.log('[server] strarting...'); + let server: WebSocketServer = yield createWebSocketServer({ port }); + + console.log(`[server] started! Listening on port ${port}`); + + while(true) { + let connection: WebSocketConnection = yield server.first(); + if(!connection) break; + + yield spawn(connection.forEach(({ options, key, name, args }) => function*() { + try { + console.log('[server] received request', key, options); + let constructor = map.get(options.name); + if(!constructor) throw new Error(`no such interactor: ${options.name}`); + + let interactor = options.locator ? + constructor(options.locator, options.filters) : + constructor(options.filters); + + let value = yield interactor[name](...args); + + console.log('[server] success', key); + yield connection.send({ key, status: "success", value }); + } catch(error: any) { + console.log('[server] error', key); + yield connection.send({ key, status: "error", error: error.message }); + } + })); + } +} diff --git a/packages/remote/tsconfig.build.json b/packages/remote/tsconfig.build.json new file mode 100644 index 00000000..a522a96a --- /dev/null +++ b/packages/remote/tsconfig.build.json @@ -0,0 +1,15 @@ +{ + "extends": "../../tsconfig-base.json", + "compilerOptions": { + "outDir": "dist/cjs", + "rootDir": "./src", + "declarationDir": "dist" + }, + "include": [ + "src/**/*.ts" + ], + "references": [ + { "path": "../core/tsconfig.build.json" }, + { "path": "../globals/tsconfig.build.json" } + ] +} diff --git a/packages/remote/tsconfig.json b/packages/remote/tsconfig.json new file mode 100644 index 00000000..c04c6762 --- /dev/null +++ b/packages/remote/tsconfig.json @@ -0,0 +1,4 @@ +{ + "extends": "@frontside/tsconfig", + "exclude": ["types/**/*.ts"] +} diff --git a/packages/remote/typedoc.json b/packages/remote/typedoc.json new file mode 100644 index 00000000..a6273867 --- /dev/null +++ b/packages/remote/typedoc.json @@ -0,0 +1,7 @@ +{ + "out": "docs/api/v1", + "name": "@interactors/html", + "entryPoints": "src/index.ts", + "includeVersion": true, + "excludePrivate": true +} diff --git a/yarn.lock b/yarn.lock index 8b5bac40..7782285c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1803,18 +1803,29 @@ "@effection/events" "2.0.1" "@effection/stream" "2.0.1" -"@effection/core@2.0.1": - version "2.0.1" - resolved "https://registry.yarnpkg.com/@effection/core/-/core-2.0.1.tgz#f200e4df020666ec5dc232da3057bafb63aa19af" - integrity sha512-Bl2pfu9gbTwlieTgcEhFOwz70QDPXpyVRuOiOqccGVBvZpa3/mzepH6LFZSCyothnc7YO0b31xXV551POiLEow== +"@effection/channel@2.0.3": + version "2.0.3" + resolved "https://registry.yarnpkg.com/@effection/channel/-/channel-2.0.3.tgz#825ade1a4a09b860efdf7077fc02f81d6c7614bb" + integrity sha512-HZE2q7dtErIur0g+BVMPqa+dVBgrIIaYMrzMBNM1UoIB6urMGgr+uPWXwgQb3Vzm4Il9SCiCzoM3RE3gDiV1Ig== + dependencies: + "@effection/core" "2.2.0" + "@effection/events" "2.0.3" + "@effection/stream" "2.0.3" -"@effection/core@2.2.0": +"@effection/core@2.0.1", "@effection/core@2.2.0", "@effection/core@^2.2.0": version "2.2.0" resolved "https://registry.yarnpkg.com/@effection/core/-/core-2.2.0.tgz#4d11d7948144aecd70a26daf8abaa29ee89bc259" integrity sha512-1RBMrDS0Ya02NEM0TQQRwzlGDSZmwoHhuD3qmWp9NLjZowhO1gJBZ16fQL2NbKvcpS71xho+oZsDedId+C1q8Q== dependencies: abort-controller "^3.0.0" +"@effection/dispatch@^2.0.3": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@effection/dispatch/-/dispatch-2.0.4.tgz#d666cbea72f55b8010866492048791728b3165b4" + integrity sha512-kcPFHtABGAibkDz2mF6NkMi0W7czKiq13Izilitehu2vFutK2OX4uLcTTIKiKuVlDKAswI80M2Sw46lTuZQMVg== + dependencies: + effection "2.0.4" + "@effection/duplex-channel@^2.0.1": version "2.0.1" resolved "https://registry.yarnpkg.com/@effection/duplex-channel/-/duplex-channel-2.0.1.tgz#48c5f1795123e0d91af5dea65fc23a84179e9bbd" @@ -1830,6 +1841,14 @@ "@effection/core" "2.0.1" "@effection/stream" "2.0.1" +"@effection/events@2.0.3": + version "2.0.3" + resolved "https://registry.yarnpkg.com/@effection/events/-/events-2.0.3.tgz#cf212748f8e433dcf776e5e1dd0145716213a7bc" + integrity sha512-x8NBNXHZxI4SJ/db1zy7zs6BRtMIKu8NgymUMpbyrRdapPSIu6rmf4WgXyWrk1uvQPSViEkxOXPw8B2MLu/YnA== + dependencies: + "@effection/core" "2.2.0" + "@effection/stream" "2.0.3" + "@effection/fetch@2.0.1": version "2.0.1" resolved "https://registry.yarnpkg.com/@effection/fetch/-/fetch-2.0.1.tgz#f67a307ef6b4450007bbf2207c6be00c143d4ce2" @@ -1840,6 +1859,14 @@ cross-fetch "^3.0.4" node-fetch "^2.6.1" +"@effection/fetch@2.0.4": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@effection/fetch/-/fetch-2.0.4.tgz#8f76f0b630b3974ef267bd8803599448db956cda" + integrity sha512-IhUYqSAM0stEB6VCWK9Mz8F56jWFFpM9yQ4boxGs4F/sdoHnY/9KKW1zxAY05jyYPUHxuUky7sazZVFJm5xRmw== + dependencies: + "@effection/core" "2.2.0" + cross-fetch "3.1.5" + "@effection/main@2.0.1": version "2.0.1" resolved "https://registry.yarnpkg.com/@effection/main/-/main-2.0.1.tgz#becbaf0b28665e401b05e429d4cad8c2c5c84ee2" @@ -1849,6 +1876,15 @@ chalk "^4.1.2" stacktrace-parser "^0.1.10" +"@effection/main@2.0.3": + version "2.0.3" + resolved "https://registry.yarnpkg.com/@effection/main/-/main-2.0.3.tgz#10dceb9c8340fd98b7c6704db0b6e8f652f32802" + integrity sha512-UHMRECFMzX+OU6I0Mg2653MyxNTIT8qXpRtl0bZT4E0rSoYnxsV+gSCEbTZFkDIZWFakp0K6awYvtyYhCeugpg== + dependencies: + "@effection/core" "2.2.0" + chalk "^4.1.2" + stacktrace-parser "^0.1.10" + "@effection/process@^2.0.1": version "2.0.1" resolved "https://registry.yarnpkg.com/@effection/process/-/process-2.0.1.tgz#fd88dc56d9b1b524121c4c6289555dca03bd1585" @@ -1867,6 +1903,14 @@ "@effection/core" "2.0.1" "@effection/subscription" "2.0.1" +"@effection/stream@2.0.3": + version "2.0.3" + resolved "https://registry.yarnpkg.com/@effection/stream/-/stream-2.0.3.tgz#c1610c63dfe6d10b0b6aeda6969fea24018364b0" + integrity sha512-l1A8PUfxR04eyUBOD1H5gdCu4U5OMwUh2TB/O/IeUlfVoP9tg64daTu7zpZGij9uDcDWV5IP9LJYoWe2lVGbKg== + dependencies: + "@effection/core" "2.2.0" + "@effection/subscription" "2.0.3" + "@effection/subscription@2.0.1": version "2.0.1" resolved "https://registry.yarnpkg.com/@effection/subscription/-/subscription-2.0.1.tgz#677cfdaa21a0a16f5aee4834e9da10afbfb5678b" @@ -1874,6 +1918,29 @@ dependencies: "@effection/core" "2.0.1" +"@effection/subscription@2.0.3": + version "2.0.3" + resolved "https://registry.yarnpkg.com/@effection/subscription/-/subscription-2.0.3.tgz#ab6e56bf52663b769eb00d0022195b2e753a127d" + integrity sha512-P+bAh0iqCduvzAM+0hbn29HJ+J4TT+lkJTDydw3tI6lSe/OVX9+FJhX/zx2QW3APjFpseMJphjRiEyzf21b/Xw== + dependencies: + "@effection/core" "2.2.0" + +"@effection/websocket-client@^2.0.3": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@effection/websocket-client/-/websocket-client-2.0.4.tgz#319ed228c71fe83d61ab87b93bdc7431c58b61bf" + integrity sha512-22kdwxEzYDEnOmQBSmNGXSpcS86DigjqY6TiEaEWVB2DZAqaWmwrBFqpBzsxw6Egml/hCA/EFQqsXS4RHt/RCw== + dependencies: + effection "2.0.4" + isomorphic-ws "^4.0.1" + +"@effection/websocket-server@^2.0.3": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@effection/websocket-server/-/websocket-server-2.0.4.tgz#e0adfabd40be129f800836d24fdc4f597c66f400" + integrity sha512-ftzFvdvvf+b8o2jhna6NUxflzdL3nXQTi7ZvXk5+EU0SMJjhrvWZh4egESDHFEfNGjcqmbs73GZEP5r9HHASYA== + dependencies: + effection "2.0.4" + ws "^7.4.6" + "@emotion/cache@^10.0.27": version "10.0.29" resolved "https://registry.yarnpkg.com/@emotion/cache/-/cache-10.0.29.tgz#87e7e64f412c060102d589fe7c6dc042e6f9d1e0" @@ -4571,6 +4638,11 @@ resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.6.tgz#250a7b16c3b91f672a24552ec64678eeb1d3a08d" integrity sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ== +"@types/uuid@^8.3.4": + version "8.3.4" + resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-8.3.4.tgz#bd86a43617df0594787d38b735f55c805becf1bc" + integrity sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw== + "@types/webpack-env@^1.16.0": version "1.16.2" resolved "https://registry.yarnpkg.com/@types/webpack-env/-/webpack-env-1.16.2.tgz#8db514b059c1b2ae14ce9d7bb325296de6a9a0fa" @@ -7259,6 +7331,13 @@ create-require@^1.1.0: resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== +cross-fetch@3.1.5: + version "3.1.5" + resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.1.5.tgz#e1389f44d9e7ba767907f7af8454787952ab534f" + integrity sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw== + dependencies: + node-fetch "2.6.7" + cross-fetch@^3.0.4: version "3.1.4" resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.1.4.tgz#9723f3a3a247bf8b89039f3a380a9244e8fa2f39" @@ -8289,6 +8368,19 @@ effection@2.0.1, effection@^2.0.1: "@effection/stream" "2.0.1" "@effection/subscription" "2.0.1" +effection@2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/effection/-/effection-2.0.4.tgz#2ca9defcebfa75b408f83f6a16ae10ec6c70b48a" + integrity sha512-8haobRaTJbwNM32GeSS5Do0WHB/Xev94SukFtQHEli+3TTDxYwW+NQcp0lAb8J4ISzvKjL+OyodGPMEyegbjog== + dependencies: + "@effection/channel" "2.0.3" + "@effection/core" "2.2.0" + "@effection/events" "2.0.3" + "@effection/fetch" "2.0.4" + "@effection/main" "2.0.3" + "@effection/stream" "2.0.3" + "@effection/subscription" "2.0.3" + effection@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/effection/-/effection-1.0.0.tgz#7c20ee4ea6e63fddb5a51461dda8009b649b4195" @@ -11369,6 +11461,11 @@ isobject@^4.0.0: resolved "https://registry.yarnpkg.com/isobject/-/isobject-4.0.0.tgz#3f1c9155e73b192022a80819bacd0343711697b0" integrity sha512-S/2fF5wH8SJA/kmwr6HYhK/RI/OkhD84k8ntalo0iJjZikgq1XFvR5M8NPT1x5F7fBwCG3qHfnzeP/Vh/ZxCUA== +isomorphic-ws@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz#55fd4cd6c5e6491e76dc125938dd863f5cd4f2dc" + integrity sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w== + isstream@^0.1.2, isstream@~0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" @@ -12924,6 +13021,13 @@ node-fetch@2.6.1, node-fetch@^2.6.1: resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052" integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw== +node-fetch@2.6.7: + version "2.6.7" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad" + integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ== + dependencies: + whatwg-url "^5.0.0" + node-forge@^0.10.0: version "0.10.0" resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.10.0.tgz#32dea2afb3e9926f02ee5ce8794902691a676bf3" @@ -17311,6 +17415,11 @@ tr46@^2.1.0: dependencies: punycode "^2.1.1" +tr46@~0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" + integrity sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o= + trim-newlines@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-3.0.1.tgz#260a5d962d8b752425b32f3a7db0dcacd176c144" @@ -18126,6 +18235,11 @@ web-namespaces@^1.0.0: resolved "https://registry.yarnpkg.com/web-namespaces/-/web-namespaces-1.1.4.tgz#bc98a3de60dadd7faefc403d1076d529f5e030ec" integrity sha512-wYxSGajtmoP4WxfejAPIr4l0fVh+jeMXZb08wNc0tMg6xsfZXj3cECqIK0G7ZAqUq0PP8WlMDtaOGVBTAWztNw== +webidl-conversions@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" + integrity sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE= + webidl-conversions@^4.0.2: version "4.0.2" resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad" @@ -18295,6 +18409,14 @@ whatwg-mimetype@^2.2.0, whatwg-mimetype@^2.3.0: resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf" integrity sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g== +whatwg-url@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" + integrity sha1-lmRU6HZUYuN2RNNib2dCzotwll0= + dependencies: + tr46 "~0.0.3" + webidl-conversions "^3.0.0" + whatwg-url@^7.0.0: version "7.1.0" resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-7.1.0.tgz#c2c492f1eca612988efd3d2266be1b9fc6170d06"