├── .gitignore ├── .vscode └── extensions.json ├── README.md ├── fixtures ├── ssr │ ├── package.json │ ├── src │ │ ├── app.tsx │ │ ├── blink.tsx │ │ ├── dev.ts │ │ ├── say-hello.tsx │ │ └── server.tsx │ └── tsconfig.json └── wire-format │ ├── package.json │ ├── src │ ├── app.tsx │ ├── blink.tsx │ ├── dev.ts │ ├── edge.tsx │ ├── origin.tsx │ └── say-hello.tsx │ └── tsconfig.json ├── nx.json ├── package.json ├── packages ├── .gitkeep └── joe-dom │ ├── jsx-runtime │ ├── package.json │ └── src │ │ ├── index.d.ts │ │ └── index.js │ ├── loader.js │ ├── metadata.d.ts │ ├── metadata.js │ ├── node-loader.js │ ├── package.json │ ├── run-tests.js │ ├── server.d.ts │ ├── server.js │ ├── src │ ├── joe-dom.server.ts │ ├── joe-dom.ts │ ├── jsx.d.ts │ ├── runtime.ts │ ├── serializer.ts │ ├── types.d.ts │ └── utils.ts │ ├── tests │ ├── loader.test.ts │ ├── serializer.test.ts │ ├── ssr.test.tsx │ └── wire-format.test.tsx │ ├── tsconfig.json │ └── tsconfig.test.json └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # compiled output 4 | dist 5 | tmp 6 | /out-tsc 7 | *.tsbuildinfo 8 | 9 | # dependencies 10 | node_modules 11 | 12 | # IDEs and editors 13 | /.idea 14 | .project 15 | .classpath 16 | .c9/ 17 | *.launch 18 | .settings/ 19 | *.sublime-workspace 20 | 21 | # IDE - VSCode 22 | .vscode/* 23 | !.vscode/settings.json 24 | !.vscode/tasks.json 25 | !.vscode/launch.json 26 | !.vscode/extensions.json 27 | 28 | # misc 29 | /.sass-cache 30 | /connect.lock 31 | /coverage 32 | /libpeerconnection.log 33 | npm-debug.log 34 | yarn-error.log 35 | testem.log 36 | /typings 37 | 38 | # System Files 39 | .DS_Store 40 | Thumbs.db 41 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | 4 | "nrwl.angular-console" 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # joe-dom 2 | 3 | A server-first virtual DOM that supports a wire format, async components, and client references out of the box. 4 | -------------------------------------------------------------------------------- /fixtures/ssr/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@fixtures/ssr", 3 | "version": "0.0.0", 4 | "type": "module", 5 | "scripts": { 6 | "build": "tsc -b", 7 | "start": "JOE_CLIENT=1 node --no-warnings --loader tsx --loader joe-dom/node-loader --conditions source src/server.tsx" 8 | }, 9 | "dependencies": { 10 | "joe-dom": "*", 11 | "mime-types": "2.1.35", 12 | "tsx": "3.12.7", 13 | "typescript": "5.1.3" 14 | }, 15 | "devDependencies": { 16 | "concurrently": "8.2.0", 17 | "esbuild": "0.18.4" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /fixtures/ssr/src/app.tsx: -------------------------------------------------------------------------------- 1 | import { type FunctionComponent } from "joe-dom"; 2 | 3 | import { SayHello } from "./say-hello"; 4 | 5 | export function App() { 6 | return ( 7 | 8 | 9 | joe-dom 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | ); 19 | } 20 | 21 | const Boundary: FunctionComponent = ({ children }) => children; 22 | Boundary.fallback = () =>
Loading...
; 23 | 24 | const Profile: FunctionComponent = async () => { 25 | await new Promise((resolve) => setTimeout(resolve, 1000)); 26 | return ; 27 | }; 28 | -------------------------------------------------------------------------------- /fixtures/ssr/src/blink.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import { useEffect, useRef } from "joe-dom"; 4 | 5 | export function Blink({ children }) { 6 | const ref = useRef(); 7 | useEffect(() => { 8 | let dimmed = false; 9 | const interval = setInterval(() => { 10 | dimmed = !dimmed; 11 | ref.current.style.opacity = dimmed ? "0.5" : "1"; 12 | }, 300); 13 | return () => clearInterval(interval); 14 | }, []); 15 | return {children}; 16 | } 17 | -------------------------------------------------------------------------------- /fixtures/ssr/src/dev.ts: -------------------------------------------------------------------------------- 1 | import * as path from "node:path"; 2 | 3 | import * as esbuild from "esbuild"; 4 | import * as mime from "mime-types"; 5 | 6 | import * as metadata from "joe-dom/metadata"; 7 | 8 | let buildPromise: Promise | null = null; 9 | let buildDone: (result: esbuild.BuildResult) => void; 10 | 11 | async function createContext() { 12 | const clientModules = Array.from(metadata.clientModules).map((m) => 13 | path.join(process.cwd(), String(m)) 14 | ); 15 | clientModules.push("joe-dom"); 16 | return await esbuild.context({ 17 | absWorkingDir: process.cwd(), 18 | entryPoints: clientModules, 19 | format: "esm", 20 | target: "es2020", 21 | outdir: path.join(process.cwd(), "public/build"), 22 | publicPath: "/build/", 23 | splitting: true, 24 | bundle: true, 25 | metafile: true, 26 | write: false, 27 | logLevel: "info", 28 | plugins: [ 29 | { 30 | name: "dev-plugin", 31 | setup(build) { 32 | build.onStart(() => { 33 | buildPromise = new Promise((resolve) => { 34 | buildDone = resolve; 35 | }); 36 | }); 37 | build.onEnd((result) => { 38 | buildDone(result); 39 | }); 40 | }, 41 | }, 42 | ], 43 | }); 44 | } 45 | 46 | export async function watch() { 47 | let context = await createContext(); 48 | let buildResult = await context.rebuild(); 49 | if (buildResult.errors.length > 0) { 50 | throw new Error( 51 | ( 52 | await esbuild.formatMessages(buildResult.errors, { 53 | kind: "error", 54 | color: true, 55 | }) 56 | ).join("\n") 57 | ); 58 | } 59 | 60 | context.watch({}); 61 | 62 | let clientModulesSize = metadata.clientModules.size; 63 | return { 64 | async getAsset(url: URL) { 65 | if (clientModulesSize !== metadata.clientModules.size) { 66 | clientModulesSize = metadata.clientModules.size; 67 | await context.dispose(); 68 | context = await createContext(); 69 | buildResult = await context.rebuild(); 70 | context.watch({}); 71 | } else { 72 | buildResult = (await buildPromise) || buildResult; 73 | } 74 | 75 | const map = new Map( 76 | buildResult.outputFiles.map((o) => [ 77 | "/" + 78 | path 79 | .relative(path.join(process.cwd(), "public"), o.path) 80 | .replace(/\\/g, "/"), 81 | o.contents, 82 | ]) 83 | ); 84 | 85 | const contents = map.get(url.pathname); 86 | if (contents) { 87 | return { 88 | contentType: 89 | ((mime.lookup(url.pathname) as string | false) || "text/plain") + 90 | "; charset=utf-8", 91 | contents, 92 | }; 93 | } 94 | }, 95 | async getClientReferenceId(id: string | number) { 96 | if (clientModulesSize !== metadata.clientModules.size) { 97 | clientModulesSize = metadata.clientModules.size; 98 | await context.dispose(); 99 | context = await createContext(); 100 | buildResult = await context.rebuild(); 101 | context.watch({}); 102 | } else { 103 | buildResult = (await buildPromise) || buildResult; 104 | } 105 | 106 | if (typeof id !== "string") throw new Error("Expected non-string id"); 107 | let [pathname, exp] = id.split("#", 2); 108 | 109 | for (const [key, value] of Object.entries(buildResult.metafile.outputs)) { 110 | if (id === "joe-dom") { 111 | if (value.entryPoint?.endsWith("joe-dom/dist/src/joe-dom.js")) { 112 | pathname = 113 | "/" + key.replace(/\\/g, "/").replace(/^\/?public\//, ""); 114 | exp = "*"; 115 | return `${pathname}#${exp}`; 116 | } 117 | } else if (value.entryPoint === pathname) { 118 | pathname = "/" + key.replace(/\\/g, "/").replace(/^\/?public\//, ""); 119 | return `${pathname}#${exp}`; 120 | } 121 | } 122 | 123 | throw new Error(`Could not find client reference for ${id}`); 124 | }, 125 | }; 126 | } 127 | -------------------------------------------------------------------------------- /fixtures/ssr/src/say-hello.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import { Blink } from "./blink"; 4 | 5 | export function SayHello({ name }: { name: string }) { 6 | return ( 7 | 10 | ); 11 | } 12 | -------------------------------------------------------------------------------- /fixtures/ssr/src/server.tsx: -------------------------------------------------------------------------------- 1 | import * as fs from "node:fs"; 2 | import * as http from "node:http"; 3 | import * as path from "node:path"; 4 | import * as stream from "node:stream"; 5 | import * as webStream from "node:stream/web"; 6 | import * as url from "node:url"; 7 | 8 | import { render } from "joe-dom/server"; 9 | 10 | // import { App } from "./app"; 11 | let appPath = path.resolve( 12 | path.dirname(url.fileURLToPath(import.meta.url)), 13 | "app.tsx" 14 | ); 15 | let lastAppTS = fs.statSync(appPath).mtimeMs; 16 | let { App } = await import("./app"); 17 | 18 | // if (process.env.NODE_ENV === "development") { 19 | let dev: Awaited>; 20 | if (true) { 21 | dev = await (await import("./dev")).watch(); 22 | } 23 | 24 | function getClientReferenceId(id) { 25 | if (dev) { 26 | return dev.getClientReferenceId(id); 27 | } 28 | throw new Error("TODO: implement production client reference"); 29 | } 30 | 31 | http 32 | .createServer(async (req, res) => { 33 | try { 34 | const url = new URL(req.url ?? "/", `http://${req.headers.host}`); 35 | if (dev) { 36 | const asset = await dev.getAsset(url); 37 | if (asset) { 38 | res.writeHead(200, { 39 | "Content-Type": asset.contentType, 40 | }); 41 | res.end(new TextDecoder().decode(asset.contents)); 42 | return; 43 | } 44 | 45 | const ts = fs.statSync(appPath).mtimeMs; 46 | if (ts > lastAppTS) { 47 | lastAppTS = ts; 48 | ({ App } = await import("./app?" + ts)); 49 | } 50 | } 51 | const rendered = render(, { 52 | getClientReferenceId, 53 | }); 54 | res.writeHead(200, { 55 | "Content-Type": "text/html; charset=utf-8", 56 | }); 57 | stream.Readable.fromWeb(rendered).pipe(res, { end: true }); 58 | } catch (reason) { 59 | console.error(reason); 60 | if (!res.headersSent) res.writeHead(500); 61 | res.end(); 62 | } 63 | }) 64 | .listen(3000, () => { 65 | console.log("Listening at http://localhost:3000"); 66 | }); 67 | -------------------------------------------------------------------------------- /fixtures/ssr/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": ["src/**/*"], 3 | "compilerOptions": { 4 | "composite": true, 5 | "module": "ES2022", 6 | "target": "ES2022", 7 | "moduleResolution": "node", 8 | "jsx": "react-jsx", 9 | "jsxImportSource": "joe-dom", 10 | "noEmit": true 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /fixtures/wire-format/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@fixtures/wire-format", 3 | "version": "0.0.0", 4 | "type": "module", 5 | "scripts": { 6 | "build": "tsc -b", 7 | "start": "concurrently \"npm:start:*\"", 8 | "start:origin": "node --no-warnings --loader tsx --loader joe-dom/node-loader --conditions source src/origin.tsx", 9 | "start:edge": "JOE_CLIENT=1 node --no-warnings --loader tsx --loader joe-dom/node-loader --conditions source src/edge.tsx" 10 | }, 11 | "dependencies": { 12 | "joe-dom": "*", 13 | "tsx": "3.12.7", 14 | "typescript": "5.1.3" 15 | }, 16 | "devDependencies": { 17 | "concurrently": "8.2.0" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /fixtures/wire-format/src/app.tsx: -------------------------------------------------------------------------------- 1 | import { type FunctionComponent } from "joe-dom"; 2 | 3 | import { SayHello } from "./say-hello"; 4 | 5 | export function App() { 6 | return ( 7 | 8 | 9 | joe-dom 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | ); 19 | } 20 | 21 | const Boundary: FunctionComponent = ({ children }) => children; 22 | Boundary.fallback = () =>
Loading...
; 23 | 24 | const Profile: FunctionComponent = async () => { 25 | await new Promise((resolve) => setTimeout(resolve, 1000)); 26 | return ; 27 | }; 28 | -------------------------------------------------------------------------------- /fixtures/wire-format/src/blink.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import { useEffect, useRef } from "joe-dom"; 4 | 5 | export function Blink({ children }) { 6 | const ref = useRef(); 7 | useEffect(() => { 8 | let dimmed = false; 9 | const interval = setInterval(() => { 10 | dimmed = !dimmed; 11 | ref.current.style.opacity = dimmed ? "0.5" : "1"; 12 | }, 300); 13 | return () => clearInterval(interval); 14 | }, []); 15 | return {children}; 16 | } 17 | -------------------------------------------------------------------------------- /fixtures/wire-format/src/dev.ts: -------------------------------------------------------------------------------- 1 | import * as path from "node:path"; 2 | 3 | import * as esbuild from "esbuild"; 4 | import * as mime from "mime-types"; 5 | 6 | import * as metadata from "joe-dom/metadata"; 7 | 8 | let buildPromise: Promise | null = null; 9 | let buildDone: (result: esbuild.BuildResult) => void; 10 | 11 | async function createContext() { 12 | const clientModules = Array.from(metadata.clientModules).map((m) => 13 | path.join(process.cwd(), String(m)) 14 | ); 15 | clientModules.push("joe-dom"); 16 | return await esbuild.context({ 17 | absWorkingDir: process.cwd(), 18 | entryPoints: clientModules, 19 | format: "esm", 20 | target: "es2020", 21 | outdir: path.join(process.cwd(), "public/build"), 22 | publicPath: "/build/", 23 | splitting: true, 24 | bundle: true, 25 | metafile: true, 26 | write: false, 27 | logLevel: "info", 28 | plugins: [ 29 | { 30 | name: "dev-plugin", 31 | setup(build) { 32 | build.onStart(() => { 33 | buildPromise = new Promise((resolve) => { 34 | buildDone = resolve; 35 | }); 36 | }); 37 | build.onEnd((result) => { 38 | buildDone(result); 39 | }); 40 | }, 41 | }, 42 | ], 43 | }); 44 | } 45 | 46 | export async function watch() { 47 | let context = await createContext(); 48 | let buildResult = await context.rebuild(); 49 | if (buildResult.errors.length > 0) { 50 | throw new Error( 51 | ( 52 | await esbuild.formatMessages(buildResult.errors, { 53 | kind: "error", 54 | color: true, 55 | }) 56 | ).join("\n") 57 | ); 58 | } 59 | 60 | context.watch({}); 61 | 62 | let clientModulesSize = metadata.clientModules.size; 63 | return { 64 | async getAsset(url: URL) { 65 | if (clientModulesSize !== metadata.clientModules.size) { 66 | clientModulesSize = metadata.clientModules.size; 67 | await context.dispose(); 68 | context = await createContext(); 69 | buildResult = await context.rebuild(); 70 | context.watch({}); 71 | } else { 72 | buildResult = (await buildPromise) || buildResult; 73 | } 74 | 75 | const map = new Map( 76 | buildResult.outputFiles.map((o) => [ 77 | "/" + 78 | path 79 | .relative(path.join(process.cwd(), "public"), o.path) 80 | .replace(/\\/g, "/"), 81 | o.contents, 82 | ]) 83 | ); 84 | 85 | const contents = map.get(url.pathname); 86 | if (contents) { 87 | return { 88 | contentType: 89 | ((mime.lookup(url.pathname) as string | false) || "text/plain") + 90 | "; charset=utf-8", 91 | contents, 92 | }; 93 | } 94 | }, 95 | async getClientReferenceId(id: string | number) { 96 | if (clientModulesSize !== metadata.clientModules.size) { 97 | clientModulesSize = metadata.clientModules.size; 98 | await context.dispose(); 99 | context = await createContext(); 100 | buildResult = await context.rebuild(); 101 | context.watch({}); 102 | } else { 103 | buildResult = (await buildPromise) || buildResult; 104 | } 105 | 106 | if (typeof id !== "string") throw new Error("Expected non-string id"); 107 | let [pathname, exp] = id.split("#", 2); 108 | 109 | for (const [key, value] of Object.entries(buildResult.metafile.outputs)) { 110 | if (id === "joe-dom") { 111 | if (value.entryPoint?.endsWith("joe-dom/dist/src/joe-dom.js")) { 112 | pathname = 113 | "/" + key.replace(/\\/g, "/").replace(/^\/?public\//, ""); 114 | exp = "*"; 115 | return `${pathname}#${exp}`; 116 | } 117 | } else if (value.entryPoint === pathname) { 118 | pathname = "/" + key.replace(/\\/g, "/").replace(/^\/?public\//, ""); 119 | return `${pathname}#${exp}`; 120 | } 121 | } 122 | 123 | throw new Error(`Could not find client reference for ${id}`); 124 | }, 125 | }; 126 | } 127 | -------------------------------------------------------------------------------- /fixtures/wire-format/src/edge.tsx: -------------------------------------------------------------------------------- 1 | import * as http from "node:http"; 2 | import * as path from "node:path"; 3 | import * as stream from "node:stream"; 4 | import * as webStream from "node:stream/web"; 5 | 6 | import { deserialize, render } from "joe-dom/server"; 7 | 8 | // if (process.env.NODE_ENV === "development") { 9 | let dev: Awaited>; 10 | if (true) { 11 | dev = await (await import("./dev")).watch(); 12 | } 13 | 14 | function getClientReferenceId(id) { 15 | if (dev) { 16 | return dev.getClientReferenceId(id); 17 | } 18 | throw new Error("TODO: implement production client reference"); 19 | } 20 | 21 | const cwd = process.cwd(); 22 | async function loadClientComponent(id: string | number) { 23 | const [filepath, exp] = String(id).split("#", 2); 24 | 25 | if (!filepath || !exp) { 26 | throw new Error(`Invalid client component: ${id}`); 27 | } 28 | 29 | const resolved = path.resolve(cwd, filepath); 30 | if (!resolved.startsWith(cwd + path.sep)) { 31 | throw new Error(`Invalid client component: ${id}`); 32 | } 33 | 34 | const mod = await import(resolved); 35 | 36 | return mod[exp]; 37 | } 38 | 39 | http 40 | .createServer(async (req, res) => { 41 | try { 42 | const url = new URL(req.url ?? "/", `http://${req.headers.host}`); 43 | if (dev) { 44 | const asset = await dev.getAsset(url); 45 | if (asset) { 46 | res.writeHead(200, { 47 | "Content-Type": asset.contentType, 48 | }); 49 | res.end(new TextDecoder().decode(asset.contents)); 50 | return; 51 | } 52 | } 53 | const response = await fetch("http://localhost:3001"); 54 | const [deserialized] = await deserialize( 55 | response.body, 56 | loadClientComponent 57 | ); 58 | const rendered = render(deserialized, { 59 | getClientReferenceId, 60 | }); 61 | stream.Readable.fromWeb(rendered).pipe(res, { end: true }); 62 | } catch (reason) { 63 | console.error(reason); 64 | if (!res.headersSent) res.writeHead(500); 65 | res.end(); 66 | } 67 | }) 68 | .listen(3000, () => { 69 | console.log("Listening at http://localhost:3000"); 70 | }); 71 | -------------------------------------------------------------------------------- /fixtures/wire-format/src/origin.tsx: -------------------------------------------------------------------------------- 1 | import * as http from "node:http"; 2 | import * as stream from "node:stream"; 3 | import * as webStream from "node:stream/web"; 4 | 5 | import { serialize } from "joe-dom/server"; 6 | 7 | import { App } from "./app"; 8 | 9 | http 10 | .createServer((_, res) => { 11 | const rendered = serialize( 12 | 13 | ) as unknown as webStream.ReadableStream; 14 | 15 | stream.Readable.fromWeb(rendered).pipe(res, { end: true }); 16 | }) 17 | .listen(3001, () => { 18 | console.log("Listening at http://localhost:3001"); 19 | }); 20 | -------------------------------------------------------------------------------- /fixtures/wire-format/src/say-hello.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import { Blink } from "./blink"; 4 | 5 | export function SayHello({ name }: { name: string }) { 6 | return ( 7 | 10 | ); 11 | } 12 | -------------------------------------------------------------------------------- /fixtures/wire-format/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": ["src/**/*"], 3 | "compilerOptions": { 4 | "composite": true, 5 | "module": "ES2022", 6 | "target": "ES2022", 7 | "moduleResolution": "node", 8 | "jsx": "react-jsx", 9 | "jsxImportSource": "joe-dom", 10 | "noEmit": true 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /nx.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "nx/presets/npm.json", 3 | "$schema": "./node_modules/nx/schemas/nx-schema.json", 4 | "tasksRunnerOptions": { 5 | "default": { 6 | "runner": "nx-cloud", 7 | "options": { 8 | "cacheableOperations": ["build", "test"], 9 | "accessToken": "ZDczNDEyMzktZjVmZS00ODgyLTg4YTktYjhlMzE2ODRlMzA0fHJlYWQtd3JpdGU=" 10 | } 11 | } 12 | }, 13 | "targetDefaults": { 14 | "build": { 15 | "dependsOn": ["^build"] 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "joe-dom-workspace", 3 | "version": "0.0.0", 4 | "license": "MIT", 5 | "type": "module", 6 | "scripts": { 7 | "build": "nx run-many --targets=build", 8 | "test": "NX_VERBOSE_LOGGING=true nx run-many --targets=test" 9 | }, 10 | "private": true, 11 | "dependencies": {}, 12 | "devDependencies": { 13 | "@types/node": "20.3.1", 14 | "nx": "16.3.2", 15 | "nx-cloud": "latest" 16 | }, 17 | "workspaces": [ 18 | "fixtures/*", 19 | "packages/*" 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /packages/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jacob-ebey/joe-dom/ee0556d4db2dea65b46d1c0086b550a65b8597d4/packages/.gitkeep -------------------------------------------------------------------------------- /packages/joe-dom/jsx-runtime/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jsx-runtime", 3 | "version": "0.0.0", 4 | "type": "module", 5 | "types": "src/index.d.ts", 6 | "main": "src/index.js", 7 | "exports": { 8 | ".": { 9 | "types": "./src/index.d.ts", 10 | "import": "./src/index.js" 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /packages/joe-dom/jsx-runtime/src/index.d.ts: -------------------------------------------------------------------------------- 1 | export { Fragment } from "../../src/joe-dom.js"; 2 | import { 3 | ComponentType, 4 | ComponentChild, 5 | ComponentChildren, 6 | VNode, 7 | Attributes, 8 | } from "../../src/types.js"; 9 | import { JSXInternal } from "../../src/jsx.js"; 10 | 11 | export function jsx( 12 | type: string, 13 | props: JSXInternal.HTMLAttributes & 14 | JSXInternal.SVGAttributes & 15 | Record & { children?: ComponentChild }, 16 | key?: string 17 | ): VNode; 18 | export function jsx

( 19 | type: ComponentType

, 20 | props: Attributes & P & { children?: ComponentChild }, 21 | key?: string 22 | ): VNode; 23 | 24 | export function jsxs( 25 | type: string, 26 | props: JSXInternal.HTMLAttributes & 27 | JSXInternal.SVGAttributes & 28 | Record & { children?: ComponentChild[] }, 29 | key?: string 30 | ): VNode; 31 | export function jsxs

( 32 | type: ComponentType

, 33 | props: Attributes & P & { children?: ComponentChild[] }, 34 | key?: string 35 | ): VNode; 36 | 37 | export function jsxDEV( 38 | type: string, 39 | props: JSXInternal.HTMLAttributes & 40 | JSXInternal.SVGAttributes & 41 | Record & { children?: ComponentChildren }, 42 | key?: string 43 | ): VNode; 44 | export function jsxDEV

( 45 | type: ComponentType

, 46 | props: Attributes & P & { children?: ComponentChildren }, 47 | key?: string 48 | ): VNode; 49 | 50 | export { JSXInternal as JSX }; 51 | -------------------------------------------------------------------------------- /packages/joe-dom/jsx-runtime/src/index.js: -------------------------------------------------------------------------------- 1 | export * from "preact/jsx-runtime"; 2 | 3 | // import { Fragment, VNODE_SYMBOL } from "joe-dom"; 4 | 5 | // /** @typedef {import('preact').VNode} VNode */ 6 | 7 | // /** 8 | // * @fileoverview 9 | // * This file exports various methods that implement Babel's "automatic" JSX runtime API: 10 | // * - jsx(type, props, key) 11 | // * - jsxs(type, props, key) 12 | // * - jsxDEV(type, props, key, __source, __self) 13 | // * 14 | // * The implementation of createVNode here is optimized for performance. 15 | // * Benchmarks: https://esbench.com/bench/5f6b54a0b4632100a7dcd2b3 16 | // */ 17 | 18 | // /** 19 | // * JSX.Element factory used by Babel's {runtime:"automatic"} JSX transform 20 | // * @param {VNode['type']} type 21 | // * @param {VNode['props']} props 22 | // * @param {VNode['key']} [key] 23 | // * @param {unknown} [isStaticChildren] 24 | // * @param {unknown} [__source] 25 | // * @param {unknown} [__self] 26 | // */ 27 | // function createVNode(type, props, key, isStaticChildren, __source, __self) { 28 | // // We'll want to preserve `ref` in props to get rid of the need for 29 | // // forwardRef components in the future, but that should happen via 30 | // // a separate PR. 31 | // let normalizedProps = {}, 32 | // ref, 33 | // i; 34 | // for (i in props) { 35 | // if (i === "ref") { 36 | // ref = props[i]; 37 | // } else { 38 | // normalizedProps[i] = props[i]; 39 | // } 40 | // } 41 | 42 | // const vnode = { 43 | // $$typeof: VNODE_SYMBOL, 44 | // type, 45 | // props: normalizedProps, 46 | // key, 47 | // ref, 48 | // __source, 49 | // __self, 50 | // }; 51 | 52 | // // If a Component VNode, check for and apply defaultProps. 53 | // // Note: `type` is often a String, and can be `undefined` in development. 54 | // if (typeof type === "function" && (ref = type.defaultProps)) { 55 | // for (i in ref) 56 | // if (typeof normalizedProps[i] === "undefined") { 57 | // normalizedProps[i] = ref[i]; 58 | // } 59 | // } 60 | 61 | // return vnode; 62 | // } 63 | 64 | // export { 65 | // createVNode as jsx, 66 | // createVNode as jsxs, 67 | // createVNode as jsxDEV, 68 | // Fragment, 69 | // }; 70 | -------------------------------------------------------------------------------- /packages/joe-dom/loader.js: -------------------------------------------------------------------------------- 1 | import * as acorn from "acorn-loose"; 2 | 3 | const DIRTY_CHECK = /(['"])use (client|server)(['"])/g; 4 | 5 | /** 6 | * @param {string} source 7 | */ 8 | export function clientModuleTransform(source, moduleId) { 9 | const match = source.match(DIRTY_CHECK); 10 | if (!match || match[1] !== match[3]) { 11 | return { useClient: false, useServer: false, source }; 12 | } 13 | 14 | const tree = acorn.parse(source, { 15 | ecmaVersion: "latest", 16 | }); 17 | 18 | let useClient = false; 19 | let useServer = false; 20 | let defaultName; 21 | const exportNames = []; 22 | for (const node of tree.body) { 23 | switch (node.type) { 24 | case "ExpressionStatement": { 25 | if (node.directive === "use client") { 26 | useClient = true; 27 | } else if (node.directive === "use server") { 28 | useServer = true; 29 | } 30 | break; 31 | } 32 | case "ExportNamedDeclaration": { 33 | if (node.source) { 34 | throw new Error("Export from not supported"); 35 | } 36 | if (Array.isArray(node.specifiers)) { 37 | for (const specifier of node.specifiers) { 38 | if (specifier.exported.name) { 39 | exportNames.push(specifier.exported.name); 40 | } 41 | } 42 | } 43 | if (Array.isArray(node.declaration?.declarations)) { 44 | for (const declaration of node.declaration.declarations) { 45 | if (declaration.id?.name) { 46 | exportNames.push(declaration.id.name); 47 | } 48 | } 49 | } 50 | break; 51 | } 52 | case "ExportDefaultDeclaration": { 53 | if (!node?.declaration?.name) { 54 | throw new Error("Default exports must be named"); 55 | } 56 | defaultName = node.declaration.name; 57 | exportNames.push("default"); 58 | break; 59 | } 60 | case "ExportAllDeclaration": { 61 | throw new Error("Export all not supported"); 62 | } 63 | case "ExportSpecifier": { 64 | exportNames.push(node.exported.name); 65 | break; 66 | } 67 | } 68 | } 69 | 70 | if (!useClient && !useServer) { 71 | return { useClient: false, useServer: false, source }; 72 | } 73 | if (useClient && useServer) { 74 | throw new Error( 75 | "Cannot both 'use client' and 'use server' in the same module" 76 | ); 77 | } 78 | 79 | if (useServer) { 80 | let str = `import {SERVER_SYMBOL} from "joe-dom";\n`; 81 | 82 | for (const name of exportNames) { 83 | const exp = `{$$typeof:SERVER_SYMBOL,$$id:${JSON.stringify( 84 | `${moduleId}#${name}` 85 | )}}`; 86 | if (name === "default") { 87 | str += `export default ${exp};\n`; 88 | } else { 89 | str += `export const ${name} = ${exp};\n`; 90 | } 91 | } 92 | 93 | return { 94 | useClient: false, 95 | useServer: true, 96 | exportNames, 97 | defaultName, 98 | source: str, 99 | }; 100 | } 101 | 102 | let str = (source += "\n"); 103 | 104 | for (let name of exportNames) { 105 | if (name === "default") { 106 | name = defaultName; 107 | } 108 | str += `if (typeof ${name} === "function")`; 109 | str += `Object.defineProperties(${name}, {`; 110 | str += `$$typeof: { value: Symbol.for("joe-dom.client") },`; 111 | str += `$$id: { value: ${JSON.stringify(`${moduleId}#${name}`)} }`; 112 | str += "})"; 113 | } 114 | return { 115 | useClient: true, 116 | useServer: false, 117 | exportNames, 118 | defaultName, 119 | source: str, 120 | }; 121 | } 122 | 123 | /** 124 | * @param {string} source 125 | */ 126 | export function serverModuleTransform(source, moduleId) { 127 | const match = source.match(DIRTY_CHECK); 128 | if (!match || match[1] !== match[3]) { 129 | return { useClient: false, useServer: false, source }; 130 | } 131 | 132 | const tree = acorn.parse(source, { 133 | ecmaVersion: "latest", 134 | }); 135 | 136 | let useClient = false; 137 | let useServer = false; 138 | let defaultName; 139 | const exportNames = []; 140 | for (const node of tree.body) { 141 | switch (node.type) { 142 | case "ExpressionStatement": { 143 | if (node.directive === "use client") { 144 | useClient = true; 145 | } else if (node.directive === "use server") { 146 | useServer = true; 147 | } 148 | break; 149 | } 150 | case "ExportNamedDeclaration": { 151 | if (node.source) { 152 | throw new Error("Export from not supported"); 153 | } 154 | if (Array.isArray(node.specifiers)) { 155 | for (const specifier of node.specifiers) { 156 | if (specifier.exported.name) { 157 | exportNames.push(specifier.exported.name); 158 | } 159 | } 160 | } 161 | if (Array.isArray(node.declaration?.declarations)) { 162 | for (const declaration of node.declaration.declarations) { 163 | if (declaration.id?.name) { 164 | exportNames.push(declaration.id.name); 165 | } 166 | } 167 | } 168 | break; 169 | } 170 | case "ExportDefaultDeclaration": { 171 | if (!node?.declaration?.name) { 172 | throw new Error("Default exports must be named"); 173 | } 174 | defaultName = node.declaration.name; 175 | exportNames.push("default"); 176 | break; 177 | } 178 | case "ExportAllDeclaration": { 179 | throw new Error("Export all not supported"); 180 | } 181 | case "ExportSpecifier": { 182 | exportNames.push(node.exported.name); 183 | break; 184 | } 185 | } 186 | } 187 | 188 | if (!useClient && !useServer) { 189 | return { useClient: false, useServer: false, source }; 190 | } 191 | if (useClient && useServer) { 192 | throw new Error( 193 | "Cannot both 'use client' and 'use server' in the same module" 194 | ); 195 | } 196 | 197 | if (useClient) { 198 | let str = `import {CLIENT_SYMBOL} from "joe-dom";\n`; 199 | 200 | for (const name of exportNames) { 201 | const exp = `{$$typeof:CLIENT_SYMBOL,$$id:${JSON.stringify( 202 | `${moduleId}#${name}` 203 | )}}`; 204 | if (name === "default") { 205 | str += `export default ${exp};\n`; 206 | } else { 207 | str += `export const ${name} = ${exp};\n`; 208 | } 209 | } 210 | 211 | return { 212 | useClient: true, 213 | useServer: false, 214 | exportNames, 215 | defaultName, 216 | source: str, 217 | }; 218 | } 219 | 220 | let str = (source += "\n"); 221 | 222 | for (let name of exportNames) { 223 | if (name === "default") { 224 | name = defaultName; 225 | } 226 | str += `if (typeof ${name} === "function")`; 227 | str += `Object.defineProperties(${name}, {`; 228 | str += `$$typeof: { value: Symbol.for("joe-dom.server") },`; 229 | str += `$$id: { value: ${JSON.stringify(`${moduleId}#${name}`)} }`; 230 | str += "})"; 231 | } 232 | return { 233 | useClient: false, 234 | useServer: true, 235 | exportNames, 236 | defaultName, 237 | source: str, 238 | }; 239 | } 240 | -------------------------------------------------------------------------------- /packages/joe-dom/metadata.d.ts: -------------------------------------------------------------------------------- 1 | export declare const clientModules: Set; 2 | export declare const serverModules: Set; 3 | -------------------------------------------------------------------------------- /packages/joe-dom/metadata.js: -------------------------------------------------------------------------------- 1 | throw new Error( 2 | "This is a placeholder file. It should be replaced at build or runtime." 3 | ); 4 | -------------------------------------------------------------------------------- /packages/joe-dom/node-loader.js: -------------------------------------------------------------------------------- 1 | import * as url from "node:url"; 2 | 3 | import { clientModuleTransform, serverModuleTransform } from "./loader.js"; 4 | 5 | export async function resolve(specifier, ctx, defaultResolve) { 6 | if (specifier === "joe-dom/metadata") { 7 | return { 8 | shortCircuit: true, 9 | url: new URL("joe-dom:metadata").href, 10 | }; 11 | } 12 | return defaultResolve(specifier, ctx, defaultResolve); 13 | } 14 | 15 | export async function load(file, ctx, nextLoad) { 16 | if (file === "joe-dom:metadata") { 17 | return { 18 | format: "module", 19 | shortCircuit: true, 20 | source: ` 21 | export const clientModules = new Set(); 22 | export const serverModules = new Set(); 23 | `, 24 | }; 25 | } 26 | 27 | const loaded = await nextLoad(file, ctx, nextLoad); 28 | 29 | if (loaded.format === "module") { 30 | const filepath = url.fileURLToPath(file); 31 | let moduleId = filepath.slice(process.cwd().length + 1); 32 | moduleId = moduleId.replace(/\\/g, "/"); 33 | 34 | let loadedSource = loaded.source.toString(); 35 | let { useClient, useServer, source } = process.env.JOE_CLIENT 36 | ? clientModuleTransform(loadedSource, moduleId) 37 | : serverModuleTransform(loadedSource, moduleId); 38 | 39 | if (useClient || useServer) { 40 | source += `\nawait import("joe-dom/metadata").then(m => {`; 41 | source += `m.${ 42 | useClient ? "client" : "server" 43 | }Modules.add(${JSON.stringify(moduleId)});`; 44 | source += "})\n"; 45 | } 46 | 47 | return { 48 | format: "module", 49 | source, 50 | }; 51 | } 52 | 53 | return loaded; 54 | } 55 | -------------------------------------------------------------------------------- /packages/joe-dom/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "joe-dom", 3 | "version": "0.0.0", 4 | "type": "module", 5 | "license": "MIT", 6 | "files": [ 7 | "dist/src", 8 | "jsx-runtime", 9 | "src", 10 | "server.js", 11 | "server.d.ts" 12 | ], 13 | "main": "dist/src/joe-dom.js", 14 | "types": "dist/src/joe-dom.d.ts", 15 | "exports": { 16 | ".": { 17 | "source": "./src/joe-dom.ts", 18 | "types": "./dist/src/joe-dom.d.ts", 19 | "import": "./dist/src/joe-dom.js" 20 | }, 21 | "./server": { 22 | "source": "./src/joe-dom.server.ts", 23 | "types": "./dist/src/joe-dom.server.d.ts", 24 | "import": "./dist/src/joe-dom.server.js" 25 | }, 26 | "./jsx-runtime": { 27 | "types": "./jsx-runtime/src/index.d.ts", 28 | "import": "./jsx-runtime/src/index.js" 29 | }, 30 | "./jsx-dev-runtime": { 31 | "types": "./jsx-runtime/src/index.d.ts", 32 | "import": "./jsx-runtime/src/index.js" 33 | }, 34 | "./loader": "./loader.js", 35 | "./node-loader": "./node-loader.js", 36 | "./metadata": { 37 | "types": "./metadata.d.ts", 38 | "import": "./metadata.js" 39 | } 40 | }, 41 | "scripts": { 42 | "build": "tsc -b && cp src/types.d.ts dist/src/types.d.ts && cp src/jsx.d.ts dist/src/jsx.d.ts", 43 | "test": "node run-tests.js" 44 | }, 45 | "private": true, 46 | "dependencies": { 47 | "acorn-loose": "8.3.0", 48 | "preact": "10.15.1" 49 | }, 50 | "devDependencies": { 51 | "arg": "5.0.2", 52 | "cross-env": "7.0.3", 53 | "glob": "10.2.7", 54 | "source-map-support": "0.5.21", 55 | "tsx": "3.12.7", 56 | "typescript": "5.1.3" 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /packages/joe-dom/run-tests.js: -------------------------------------------------------------------------------- 1 | import { spawn } from "node:child_process"; 2 | 3 | import arg from "arg"; 4 | import { glob } from "glob"; 5 | 6 | const { "--only": only, _: providedTestFiles } = arg({ 7 | "--only": Boolean, 8 | }); 9 | 10 | const testFiles = 11 | providedTestFiles.length > 0 12 | ? providedTestFiles 13 | : await glob(["tests/*.test.ts", "tests/*.test.tsx"], { 14 | nodir: true, 15 | }); 16 | 17 | const args = [ 18 | "--no-warnings", 19 | "--loader", 20 | "tsx", 21 | "--conditions", 22 | "source", 23 | "-r", 24 | "source-map-support/register", 25 | only ? "--test-only" : "--test", 26 | ...testFiles, 27 | ]; 28 | 29 | const childProcess = spawn("node", args, { 30 | stdio: "inherit", 31 | env: { 32 | ...process.env, 33 | ESBK_TSCONFIG_PATH: "./tsconfig.test.json", 34 | }, 35 | }); 36 | 37 | childProcess.on("exit", (code) => { 38 | process.exit(code ?? 1); 39 | }); 40 | -------------------------------------------------------------------------------- /packages/joe-dom/server.d.ts: -------------------------------------------------------------------------------- 1 | export * from "./dist/src/joe-dom.server.js"; 2 | -------------------------------------------------------------------------------- /packages/joe-dom/server.js: -------------------------------------------------------------------------------- 1 | export * from "./dist/src/joe-dom.server.js"; 2 | -------------------------------------------------------------------------------- /packages/joe-dom/src/joe-dom.server.ts: -------------------------------------------------------------------------------- 1 | import { CLIENT_SYMBOL } from "./joe-dom.js"; 2 | 3 | import type { 4 | ClientComponent, 5 | ComponentChild, 6 | ComponentChildren, 7 | ComponentProps, 8 | FunctionComponent, 9 | VNode, 10 | } from "./types.js"; 11 | import type { JSXInternal } from "./jsx.js"; 12 | import { fallbackRuntime, islandRuntime } from "./runtime.js"; 13 | export { deserialize, serialize } from "./serializer.js"; 14 | import { 15 | UNSAFE_NAME, 16 | VOID_ELEMENTS, 17 | XLINK, 18 | XLINK_REPLACE_REGEX, 19 | encodeEntities, 20 | isPromise, 21 | styleObjToCss, 22 | } from "./utils.js"; 23 | 24 | interface IDIncrementor { 25 | (): number; 26 | previous: number; 27 | } 28 | 29 | export type AllReadyReadableStream = 30 | ReadableStreamType & { 31 | allReady: Promise; 32 | }; 33 | 34 | export interface RenderOptions { 35 | signal?: AbortSignal; 36 | getClientReferenceId?: ( 37 | id: string | number 38 | ) => string | number | Promise; 39 | } 40 | 41 | export function render( 42 | children: ComponentChildren, 43 | options?: RenderOptions 44 | ): AllReadyReadableStream { 45 | const { signal } = options || {}; 46 | 47 | let allReady: () => void, 48 | cancel: (reason?: unknown) => void, 49 | removeSignalListener: undefined | (() => void); 50 | const allReadyPromise = new Promise((resolve, reject) => { 51 | allReady = () => { 52 | if (removeSignalListener) removeSignalListener(); 53 | resolve(); 54 | }; 55 | cancel = (reason) => { 56 | if (removeSignalListener) removeSignalListener(); 57 | reason = reason || new Error("Render cancelled"); 58 | reject(reason); 59 | }; 60 | }); 61 | allReadyPromise.catch(() => {}); 62 | 63 | let fallbackIdIncrementor = -1; 64 | const nextFallbackId = (() => ++fallbackIdIncrementor) as IDIncrementor; 65 | Object.defineProperties(nextFallbackId, { 66 | previous: { enumerable: true, get: () => fallbackIdIncrementor }, 67 | }); 68 | let islandIdIncrementor = -1; 69 | const nextIslandId = (() => ++islandIdIncrementor) as IDIncrementor; 70 | Object.defineProperties(nextIslandId, { 71 | previous: { enumerable: true, get: () => islandIdIncrementor }, 72 | }); 73 | 74 | const encoder = new TextEncoder(); 75 | const stream = new ReadableStream({ 76 | async start(controller) { 77 | try { 78 | let queuedPromises = []; 79 | const queueChunk = (promise) => { 80 | queuedPromises.push(promise); 81 | }; 82 | const html = await renderChildren( 83 | children, 84 | nextFallbackId, 85 | nextIslandId, 86 | queueChunk, 87 | options, 88 | null, 89 | false, 90 | false 91 | ); 92 | controller.enqueue(encoder.encode(html)); 93 | 94 | if (queuedPromises.length > 0) { 95 | controller.enqueue(encoder.encode(fallbackRuntime)); 96 | // TODO: Make this runtime optional 97 | controller.enqueue(encoder.encode(islandRuntime)); 98 | } 99 | while (queuedPromises.length > 0) { 100 | const processQueuedPromises = []; 101 | for (const promise of queuedPromises) { 102 | processQueuedPromises.push( 103 | promise.then((chunk) => { 104 | controller.enqueue(encoder.encode(chunk)); 105 | }) 106 | ); 107 | } 108 | queuedPromises = []; 109 | queuedPromises.length = 0; 110 | await Promise.all(processQueuedPromises); 111 | } 112 | 113 | controller.close(); 114 | allReady(); 115 | } catch (reason) { 116 | cancel(reason); 117 | throw reason; 118 | } 119 | }, 120 | cancel(reason) { 121 | cancel(reason); 122 | }, 123 | }); 124 | 125 | if (signal) { 126 | const onAbort = () => { 127 | stream.cancel(signal.reason); 128 | }; 129 | signal.addEventListener("abort", onAbort); 130 | removeSignalListener = () => signal.removeEventListener("abort", onAbort); 131 | } 132 | 133 | return Object.defineProperties( 134 | stream as unknown as AllReadyReadableStream, 135 | { 136 | allReady: { enumerable: true, value: allReadyPromise }, 137 | } 138 | ); 139 | } 140 | 141 | async function renderChildren( 142 | children: ComponentChildren, 143 | nextFallbackId: IDIncrementor, 144 | nextIslandId: IDIncrementor, 145 | queueChunk: (chunk: Promise) => void, 146 | options: RenderOptions, 147 | selectedValue: string | null, 148 | svgMode: boolean, 149 | clientMode: boolean 150 | ) { 151 | if (children == null) return ""; 152 | const childrenToRender = Array.isArray(children) ? children : [children]; 153 | 154 | const childPromises = []; 155 | for (let child of childrenToRender) { 156 | const promise = (async () => { 157 | if (isPromise(child)) child = await child; 158 | const type = !!child && child.type; 159 | let childSvgMode = 160 | type === "svg" || (type !== "foreignObject" && svgMode); 161 | let html = ""; 162 | for await (const chunk of renderChild( 163 | child, 164 | nextFallbackId, 165 | nextIslandId, 166 | queueChunk, 167 | options, 168 | selectedValue, 169 | childSvgMode, 170 | clientMode 171 | )) { 172 | html += chunk; 173 | } 174 | return html; 175 | })(); 176 | promise.catch(() => {}); 177 | childPromises.push(promise); 178 | } 179 | await Promise.all(childPromises); 180 | 181 | return (await Promise.all(childPromises)).join(""); 182 | } 183 | 184 | async function* renderChild( 185 | child: ComponentChild, 186 | nextFallbackId: IDIncrementor, 187 | nextIslandId: IDIncrementor, 188 | queueChunk: (chunk: Promise) => void, 189 | options: RenderOptions, 190 | selectedValue: string | null, 191 | svgMode: boolean, 192 | clientMode: boolean 193 | ): AsyncGenerator { 194 | if (isPromise(child)) { 195 | child = await child; 196 | } 197 | 198 | switch (typeof child) { 199 | case "string": 200 | case "number": 201 | case "bigint": 202 | return yield "" + child; 203 | case "undefined": 204 | case "boolean": 205 | return yield child ? "true" : ""; 206 | case "function": 207 | case "symbol": 208 | throw new Error("Invalid child '" + typeof child + "'"); 209 | default: 210 | if (!child) return yield ""; 211 | let { $$typeof, type, props } = (child as VNode) || {}; 212 | if (typeof type !== "string" && typeof type !== "function") { 213 | throw new Error("Invalid child type '" + typeof type + "'"); 214 | } 215 | 216 | if (typeof type !== "string") { 217 | type = type as FunctionComponent; 218 | let children = type(props, {}); 219 | 220 | // options._commit, we don't schedule any effects in this library right now, 221 | // so we can pass an empty queue to this hook. 222 | 223 | const prom = isPromise(children); 224 | let id = prom ? nextFallbackId() : nextFallbackId.previous; 225 | let clientComponent = type.$$typeof === CLIENT_SYMBOL; 226 | let fellback = false; 227 | 228 | const renderedChildren = renderChildren( 229 | children, 230 | nextFallbackId, 231 | nextIslandId, 232 | queueChunk, 233 | options, 234 | selectedValue, 235 | svgMode, 236 | clientComponent 237 | ).then(async (rendered) => { 238 | let r = ""; 239 | let islandId = 240 | (fellback && clientComponent) || (clientComponent && !clientMode) 241 | ? nextIslandId() 242 | : undefined; 243 | if (typeof islandId === "number") { 244 | r += ``; 245 | } 246 | r += rendered; 247 | if (typeof islandId === "number") { 248 | r += ``; 249 | if (!options.getClientReferenceId) { 250 | throw new Error( 251 | "Missing getClientReferenceId option for client component" 252 | ); 253 | } 254 | queueChunk( 255 | Promise.resolve( 256 | `` 265 | ) 266 | ); 267 | } 268 | return r; 269 | }); 270 | if ((prom || id !== nextFallbackId.previous) && type.fallback) { 271 | fellback = true; 272 | if (!prom) { 273 | id = nextFallbackId(); 274 | } 275 | const fallback = type.fallback(props); 276 | 277 | const chunkPromise = renderedChildren.then((chunk) => { 278 | return ``; 279 | }); 280 | // TODO: catch errors from chunkPromise 281 | 282 | queueChunk(chunkPromise); 283 | 284 | // TODO: queue children to render after fallback 285 | const fallbackHTML = await renderChildren( 286 | fallback, 287 | nextFallbackId, 288 | nextIslandId, 289 | queueChunk, 290 | options, 291 | selectedValue, 292 | svgMode, 293 | clientMode 294 | ); 295 | 296 | return yield `${fallbackHTML}`; 297 | } 298 | 299 | return yield renderedChildren; 300 | } 301 | return yield renderDOMNode( 302 | child as VNode, 303 | nextFallbackId, 304 | nextIslandId, 305 | queueChunk, 306 | options, 307 | selectedValue, 308 | svgMode, 309 | clientMode 310 | ); 311 | } 312 | } 313 | 314 | // Adapted from https://github.com/preactjs/preact-render-to-string 315 | async function renderDOMNode( 316 | vnode: VNode>, 317 | nextFallbackId: IDIncrementor, 318 | nextIslandId: IDIncrementor, 319 | queueChunk: (chunk: Promise) => void, 320 | options: RenderOptions, 321 | selectedValue: string | null, 322 | svgMode: boolean, 323 | clientMode: boolean 324 | ) { 325 | const { type, props } = vnode as Omit< 326 | VNode>, 327 | "type" 328 | > & { type: string }; 329 | 330 | let html = "<" + type; 331 | 332 | const seenKeys = new Set(); 333 | for (let key of Object.keys(props)) { 334 | if (key.startsWith("on")) continue; 335 | let v = props[key]; 336 | 337 | switch (key) { 338 | case "key": 339 | case "ref": 340 | case "__self": 341 | case "__source": 342 | case "children": 343 | continue; 344 | case "checked": 345 | case "defaultChecked": 346 | key = "checked"; 347 | if (seenKeys.has(key)) { 348 | // TODO: surface warning about duplicate key with line position 349 | console.warn("Duplicate key 'checked' and 'defaultChecked' found"); 350 | continue; 351 | } 352 | break; 353 | case "class": 354 | case "className": 355 | key = "class"; 356 | if (seenKeys.has(key)) { 357 | // TODO: surface warning about duplicate key with line position 358 | console.warn("Duplicate key 'class' and 'className' found"); 359 | continue; 360 | } 361 | seenKeys.add(key); 362 | break; 363 | case "dangerouslySetInnerHTML": 364 | throw new Error("TODO: implement dangerouslySetInnerHTML"); 365 | case "html": 366 | case "htmlFor": 367 | key = "for"; 368 | if (seenKeys.has(key)) { 369 | // TODO: surface warning about duplicate key with line position 370 | console.warn("Duplicate key 'for' and 'htmlFor' found"); 371 | continue; 372 | } 373 | break; 374 | case "selected": 375 | case "defaultSelected": 376 | key = "selected"; 377 | if (seenKeys.has(key)) { 378 | // TODO: surface warning about duplicate key with line position 379 | console.warn("Duplicate key 'selected' and 'defaultSelected' found"); 380 | continue; 381 | } 382 | break; 383 | case "style": 384 | v = styleObjToCss(v); 385 | break; 386 | case "value": 387 | case "defaultValue": 388 | key = "value"; 389 | if (seenKeys.has(key)) { 390 | // TODO: surface warning about duplicate key with line position 391 | console.warn("Duplicate key 'value' and 'defaultValue' found"); 392 | continue; 393 | } 394 | switch (type) { 395 | case "textarea": 396 | props.children = v; 397 | continue; 398 | case "select": 399 | selectedValue = v; 400 | continue; 401 | case "option": 402 | if (v == selectedValue) { 403 | html += " selected"; 404 | } 405 | } 406 | break; 407 | default: 408 | if (svgMode && XLINK.test(key)) { 409 | key = key.toLowerCase().replace(XLINK_REPLACE_REGEX, "xlink:"); 410 | } else if (UNSAFE_NAME.test(key)) { 411 | continue; 412 | } else if ((key[4] === "-" || key === "draggable") && v != null) { 413 | // serialize boolean aria-xyz or draggable attribute values as strings 414 | // `draggable` is an enumerated attribute and not Boolean. A value of `true` or `false` is mandatory 415 | // https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/draggable 416 | v += ""; 417 | } 418 | } 419 | 420 | if (v != null && v !== false && typeof v !== "function") { 421 | if (v === true || v === "") { 422 | html += " " + key; 423 | } else { 424 | html += " " + key + '="' + encodeEntities(v + "") + '"'; 425 | } 426 | } 427 | } 428 | const children = props.children; 429 | const selfClosed = VOID_ELEMENTS.test(type) && children == null; 430 | html += ">"; 431 | 432 | if (!selfClosed && children != null) { 433 | html += await renderChildren( 434 | children, 435 | nextFallbackId, 436 | nextIslandId, 437 | queueChunk, 438 | options, 439 | selectedValue, 440 | svgMode, 441 | clientMode 442 | ); 443 | } 444 | 445 | if (!selfClosed) { 446 | html += ""; 447 | } 448 | 449 | return html; 450 | } 451 | -------------------------------------------------------------------------------- /packages/joe-dom/src/joe-dom.ts: -------------------------------------------------------------------------------- 1 | import type { FunctionComponent, ComponentChildren, VNode } from "./types.js"; 2 | import { 3 | hydrate as pHydrate, 4 | createElement as pCreateElement, 5 | Fragment as PFragment, 6 | } from "preact"; 7 | 8 | import { 9 | useCallback as pUseCallback, 10 | useEffect as pUseEffect, 11 | useLayoutEffect as pUseLayoutEffect, 12 | useMemo as pUseMemo, 13 | useReducer as pUseReducer, 14 | useRef as pUseRef, 15 | useState as pUseState, 16 | } from "preact/hooks"; 17 | 18 | export type * from "./types.js"; 19 | 20 | export const CLIENT_SYMBOL = Symbol.for("joe-dom.client"); 21 | export const SERVER_SYMBOL = Symbol.for("joe-dom.server"); 22 | 23 | export const Fragment = PFragment as FunctionComponent; 24 | 25 | export const createElement = pCreateElement as ( 26 | type: VNode["type"], 27 | props?: Record | null | undefined, 28 | ...children: ComponentChildren[] 29 | ) => VNode; 30 | export { createElement as h }; 31 | 32 | export const hydrate = pHydrate as (v: VNode, c: Element) => void; 33 | 34 | // is server check that works in Bun, Deno and Node 35 | const IS_SERVER = 36 | typeof document === "undefined" || 37 | // @ts-expect-error 38 | typeof Deno !== "undefined" || 39 | typeof window === "undefined"; 40 | 41 | export const useCallback = ((...args) => { 42 | if (IS_SERVER) { 43 | return args[0]; 44 | } 45 | return pUseCallback(...args); 46 | }) as typeof pUseCallback; 47 | 48 | export const useEffect = ((...args) => { 49 | if (IS_SERVER) { 50 | return; 51 | } 52 | return pUseEffect(...args); 53 | }) as typeof pUseEffect; 54 | 55 | export const useLayoutEffect = ((...args) => { 56 | if (IS_SERVER) { 57 | return; 58 | } 59 | return pUseLayoutEffect(...args); 60 | }) as typeof pUseLayoutEffect; 61 | 62 | export const useMemo = ((...args) => { 63 | if (IS_SERVER) { 64 | return args[0](); 65 | } 66 | return pUseMemo(...args); 67 | }) as typeof pUseMemo; 68 | 69 | export const useReducer = ((...args: any) => { 70 | if (IS_SERVER) { 71 | return [ 72 | args[1], 73 | () => { 74 | throw new Error("useReducer dispatch not supported on server"); 75 | }, 76 | ]; 77 | } 78 | // @ts-expect-error 79 | return pUseReducer(...args); 80 | }) as typeof pUseReducer; 81 | 82 | export const useRef = ((...args) => { 83 | if (IS_SERVER) { 84 | return { current: args[0] }; 85 | } 86 | // @ts-expect-error 87 | return pUseRef(...args); 88 | }) as typeof pUseRef; 89 | 90 | export const useState = ((...args) => { 91 | if (IS_SERVER) { 92 | return [ 93 | args[0], 94 | () => { 95 | throw new Error("useState setter not supported on server"); 96 | }, 97 | ]; 98 | } 99 | // @ts-expect-error 100 | return pUseState(...args); 101 | }) as typeof pUseState; 102 | 103 | // export const Fragment = ({ children }) => children; 104 | 105 | // export function createElement( 106 | // type: VNode["type"], 107 | // props?: Record | null | undefined, 108 | // ...children: ComponentChildren[] 109 | // ): VNode { 110 | // let normalizedProps: { children: ComponentChildren } = { 111 | // children: undefined, 112 | // }, 113 | // key, 114 | // ref, 115 | // i; 116 | // for (i in props) { 117 | // if (i == "key") key = props[i]; 118 | // else if (i == "ref") ref = props[i]; 119 | // else normalizedProps[i] = props[i]; 120 | // } 121 | // if (arguments.length > 2) { 122 | // normalizedProps.children = children; 123 | // } 124 | // if (Array.isArray(normalizedProps.children)) { 125 | // normalizedProps.children = normalizedProps.children.flat(Infinity); 126 | // } 127 | 128 | // return createVNode(type, normalizedProps, key, ref); 129 | // } 130 | 131 | // /** 132 | // * Create a VNode (used internally by Preact) 133 | // * @param {import('./internal').VNode["type"]} type The node name or Component 134 | // * Constructor for this virtual node 135 | // * @param {object | string | number | null} props The properties of this virtual node. 136 | // * If this virtual node represents a text node, this is the text of the node (string or number). 137 | // * @param {string | number | null} key The key for this virtual node, used when 138 | // * diffing it against its children 139 | // * @param {import('./internal').VNode["ref"]} ref The ref property that will 140 | // * receive a reference to its created child 141 | // * @returns {import('./internal').VNode} 142 | // */ 143 | // export function createVNode( 144 | // type: VNode["type"], 145 | // props: { children: ComponentChildren }, 146 | // key?: Key, 147 | // ref?: Ref | null | undefined 148 | // ) { 149 | // // V8 seems to be better at detecting type shapes if the object is allocated from the same call site 150 | // // Do not inline into createElement and coerceToVNode! 151 | // const vnode: VNode = { 152 | // $$typeof: VNODE_SYMBOL, 153 | // type, 154 | // props, 155 | // key, 156 | // ref, 157 | // }; 158 | 159 | // return vnode; 160 | // } 161 | -------------------------------------------------------------------------------- /packages/joe-dom/src/runtime.ts: -------------------------------------------------------------------------------- 1 | const fallbackSource = ` 2 | window.$_JOE_INIT = {}; 3 | window.$_JOE_INIT.promise = new Promise((resolve,reject) => { 4 | window.$_JOE_INIT.resolve = resolve; 5 | window.$_JOE_INIT.reject = reject; 6 | }); 7 | customElements.define( 8 | "joe-fb", 9 | class extends HTMLElement { 10 | connectedCallback() { 11 | let self = this, 12 | iterator = document.createNodeIterator(document, 128), 13 | i, 14 | j, 15 | s, 16 | e; 17 | 18 | if (!self.isConnected) return; 19 | 20 | setTimeout(() => { 21 | i = self.getAttribute("data-id"); 22 | if (!i) return; 23 | 24 | while (iterator.nextNode()) { 25 | j = iterator.referenceNode; 26 | if (j.data == "joe:" + i) s = j; 27 | else if (j.data == "/joe:" + i) e = j; 28 | if (s && e) break; 29 | } 30 | if (s && e) { 31 | i = e.previousSibling; 32 | while (i != s) { 33 | if (!i || i == s) break; 34 | 35 | e.parentNode.removeChild(i); 36 | i = e.previousSibling; 37 | } 38 | 39 | while (self.firstChild) { 40 | e.parentNode.insertBefore(self.firstChild, e); 41 | } 42 | self.parentNode.removeChild(self); 43 | } 44 | }, 0); 45 | } 46 | } 47 | ); 48 | `; 49 | 50 | const minifiedFallback = `window.$_JOE_INIT={},window.$_JOE_INIT.promise=new Promise(((e,o)=>{window.$_JOE_INIT.resolve=e,window.$_JOE_INIT.reject=o})),customElements.define("joe-fb",class extends HTMLElement{connectedCallback(){let e,o,t,i,d=this,r=document.createNodeIterator(document,128);d.isConnected&&setTimeout((()=>{if(e=d.getAttribute("data-id"),e){for(;r.nextNode()&&(o=r.referenceNode,o.data=="joe:"+e?t=o:o.data=="/joe:"+e&&(i=o),!t||!i););if(t&&i){for(e=i.previousSibling;e!=t&&e&&e!=t;)i.parentNode.removeChild(e),e=i.previousSibling;for(;d.firstChild;)i.parentNode.insertBefore(d.firstChild,i);d.parentNode.removeChild(d)}}}),0)}});`; 51 | 52 | export const fallbackRuntime = `"; 53 | 54 | const islandSource = ` 55 | window.$_JOE = window.$_JOE || function(i, runtimeId, referenceId, props) { 56 | if (i == null) return; 57 | 58 | let iterator = document.createNodeIterator(document, 128), 59 | j, 60 | s, 61 | e; 62 | 63 | while (iterator.nextNode()) { 64 | j = iterator.referenceNode; 65 | if (j.data == "joec:" + i) s = j; 66 | else if (j.data == "/joec:" + i) e = j; 67 | if (s && e) break; 68 | } 69 | if (s && e) { 70 | window.$_JOEI = window.$_JOEI || (async (p) => { 71 | let [a,b] = p.split("#"); 72 | const mod = await import(a); 73 | if (b == "*") return mod; 74 | return mod[b]; 75 | }); 76 | Promise.all([ 77 | window.$_JOEI(runtimeId), 78 | window.$_JOEI(referenceId) 79 | ]) 80 | .then(([runtime,Island]) => { 81 | j = document.createElement("div"); 82 | i = s.nextSibling; 83 | while (i != s) { 84 | if (!i || i == e) break; 85 | 86 | s.parentNode.removeChild(i); 87 | j.appendChild(i); 88 | i = e.nextSibling; 89 | } 90 | runtime.hydrate(runtime.h(Island, props), j); 91 | while (j.firstChild) { 92 | e.parentNode.insertBefore(j.firstChild, e); 93 | } 94 | }).catch(reason => { 95 | console.error("Failed to hydrate island " + i, reason); 96 | }); 97 | } 98 | }; 99 | window.$_JOE_INIT.resolve(); 100 | `; 101 | 102 | const minifiedIsland = `window.$_JOE=window.$_JOE||function(e,o,t,n){if(null==e)return;let r,d,i,a=document.createNodeIterator(document,128);for(;a.nextNode()&&(r=a.referenceNode,r.data=="joec:"+e?d=r:r.data=="/joec:"+e&&(i=r),!d||!i););d&&i&&(window.$_JOEI=window.$_JOEI||(async e=>{let[o,t]=e.split("#");const n=await import(o);return"*"==t?n:n[t]}),Promise.all([window.$_JOEI(o),window.$_JOEI(t)]).then((([o,t])=>{for(r=document.createElement("div"),e=d.nextSibling;e!=d&&e&&e!=i;)d.parentNode.removeChild(e),r.appendChild(e),e=i.nextSibling;for(o.hydrate(o.h(t,n),r);r.firstChild;)i.parentNode.insertBefore(r.firstChild,i)})).catch((o=>{console.error("Failed to hydrate island "+e,o)})))},window.$_JOE_INIT.resolve();`; 103 | 104 | export const islandRuntime = 105 | `"; 106 | -------------------------------------------------------------------------------- /packages/joe-dom/src/serializer.ts: -------------------------------------------------------------------------------- 1 | // Adapted from https://github.com/Rich-Harris/devalue 2 | import { 3 | type FunctionComponent, 4 | CLIENT_SYMBOL, 5 | createElement, 6 | } from "./joe-dom.js"; 7 | 8 | const UNDEFINED = -1, 9 | HOLE = -2, 10 | NAN = -3, 11 | POSITIVE_INFINITY = -4, 12 | NEGATIVE_INFINITY = -5, 13 | NEGATIVE_ZERO = -6; 14 | 15 | export function serialize(value: unknown) { 16 | const pending = new Set>(); 17 | 18 | let promiseCount = 0; 19 | function queuePromise(promise: Promise) { 20 | const id = promiseCount++; 21 | pending.add( 22 | promise 23 | .then((value) => { 24 | return [id, { value }]; 25 | }) 26 | .catch((error) => { 27 | let value = { message: "Unknown error", stack: undefined }; 28 | if (error && error instanceof Error) { 29 | value = { message: error.message, stack: error.stack }; 30 | } else if (error && error.message) { 31 | value = { message: error.message, stack: undefined }; 32 | } else if (typeof error === "string") { 33 | value = { message: error, stack: undefined }; 34 | } 35 | return [id, { error: value }]; 36 | }) 37 | ); 38 | return id; 39 | } 40 | 41 | const ids = new Map(); 42 | function flatten(value: unknown, stringified: string[], depth = 0) { 43 | let count = 0; 44 | const keys = []; 45 | 46 | function flattenRecursive(value: unknown): number | string { 47 | switch (typeof value) { 48 | case "function": 49 | throw new DevalueError("Cannot serialize functions", keys); 50 | case "undefined": 51 | return UNDEFINED; 52 | case "number": 53 | if (Number.isNaN(value)) return NAN; 54 | if (value === Infinity) return POSITIVE_INFINITY; 55 | if (value === -Infinity) return NEGATIVE_INFINITY; 56 | if (value === 0 && 1 / value === -Infinity) return NEGATIVE_ZERO; 57 | } 58 | 59 | if (ids.has(value)) return ids.get(value); 60 | 61 | const index = stringified.length; 62 | stringified.length += 1; 63 | const id = `"${depth}:${index}"`; 64 | ids.set(value, id); 65 | 66 | stringified[index] = serializeValue( 67 | value, 68 | keys, 69 | flattenRecursive, 70 | queuePromise 71 | ); 72 | 73 | return id; 74 | } 75 | 76 | return flattenRecursive(value); 77 | } 78 | 79 | const encoder = new TextEncoder(); 80 | return new ReadableStream({ 81 | async start(controller) { 82 | const stringified: string[] = []; 83 | const id = flatten(value, stringified); 84 | 85 | const line = 86 | typeof id === "number" && id < 0 87 | ? `${id}` 88 | : `[${stringified.join(",")}]`; 89 | controller.enqueue(encoder.encode(line + "\n")); 90 | 91 | let sentLines = 1; 92 | while (pending.size > 0) { 93 | const promises = [...pending]; 94 | pending.clear(); 95 | 96 | await Promise.all( 97 | promises.map((promise) => 98 | promise.then(([promiseId, result]) => { 99 | const stringified: string[] = []; 100 | const id = flatten(result, stringified, sentLines++); 101 | 102 | const line = 103 | typeof id === "number" && id < 0 104 | ? `${id}` 105 | : `[${stringified.join(",")}]`; 106 | 107 | controller.enqueue(encoder.encode(`$${promiseId}:${line}\n`)); 108 | }) 109 | ) 110 | ); 111 | } 112 | 113 | controller.close(); 114 | }, 115 | }); 116 | } 117 | 118 | export async function deserialize( 119 | stream: ReadableStream, 120 | loadClientComponent?: (id: string | number) => Promise 121 | ): Promise<[any, Promise]> { 122 | const hydrated = {}; 123 | const promises: Record> = {}; 124 | function unflatten(parsed, line) { 125 | if (typeof parsed === "number") return hydrate(parsed, true); 126 | if (!Array.isArray(parsed) || parsed.length === 0) { 127 | throw new Error("Invalid input"); 128 | } 129 | 130 | const values = parsed.reduce( 131 | (p, value, i) => Object.assign(p, { [`${line}:${i}`]: value }), 132 | {} 133 | ); 134 | 135 | /** 136 | * @param {string} index 137 | * @returns {any} 138 | */ 139 | function hydrate(index, standalone = false) { 140 | if (index === UNDEFINED) return undefined; 141 | if (index === NAN) return NaN; 142 | if (index === POSITIVE_INFINITY) return Infinity; 143 | if (index === NEGATIVE_INFINITY) return -Infinity; 144 | if (index === NEGATIVE_ZERO) return -0; 145 | 146 | if (standalone) throw new Error(`Invalid input`); 147 | 148 | if (index in hydrated) return hydrated[index]; 149 | 150 | const value = values[index]; 151 | 152 | if (!value || typeof value !== "object") { 153 | hydrated[index] = value; 154 | } else if (Array.isArray(value)) { 155 | if (typeof value[0] === "string") { 156 | const type = value[0]; 157 | 158 | switch (type) { 159 | case "Symbol": 160 | hydrated[index] = Symbol.for(value[1]); 161 | break; 162 | 163 | case "Promise": 164 | const deferred = new Deferred(); 165 | promises[value[1]] = deferred; 166 | hydrated[index] = deferred.promise; 167 | break; 168 | 169 | case "V": 170 | const vnode = hydrate(value[1]); 171 | const Component: FunctionComponent = () => vnode; 172 | if (value.length > 2) { 173 | const fvnode = hydrate(value[2]); 174 | Component.fallback = () => fvnode; 175 | } 176 | hydrated[index] = createElement(Component); 177 | break; 178 | 179 | case "C": 180 | if (!loadClientComponent) 181 | throw new Error("loadClientComponent not provided"); 182 | 183 | const id = hydrate(value[1]); 184 | const componentPromise = loadClientComponent(id); 185 | const props = hydrate(value[2]); 186 | const ClientComponent: FunctionComponent = async () => { 187 | const Component = (await componentPromise) as FunctionComponent; 188 | return createElement(Component, props); 189 | }; 190 | hydrated[index] = createElement(ClientComponent); 191 | break; 192 | 193 | case "Date": 194 | hydrated[index] = new Date(value[1]); 195 | break; 196 | 197 | case "Set": 198 | const set = new Set(); 199 | hydrated[index] = set; 200 | for (let i = 1; i < value.length; i += 1) { 201 | set.add(hydrate(value[i])); 202 | } 203 | break; 204 | 205 | case "Map": 206 | const map = new Map(); 207 | hydrated[index] = map; 208 | for (let i = 1; i < value.length; i += 2) { 209 | map.set(hydrate(value[i]), hydrate(value[i + 1])); 210 | } 211 | break; 212 | 213 | case "RegExp": 214 | hydrated[index] = new RegExp(value[1], value[2]); 215 | break; 216 | 217 | case "Object": 218 | hydrated[index] = Object(value[1]); 219 | break; 220 | 221 | case "BigInt": 222 | hydrated[index] = BigInt(value[1]); 223 | break; 224 | 225 | case "null": 226 | const obj = Object.create(null); 227 | hydrated[index] = obj; 228 | for (let i = 1; i < value.length; i += 2) { 229 | obj[value[i]] = hydrate(value[i + 1]); 230 | } 231 | break; 232 | 233 | default: 234 | const array = new Array(value.length); 235 | hydrated[index] = array; 236 | 237 | for (let i = 0; i < value.length; i += 1) { 238 | const n = value[i]; 239 | if (n === HOLE) continue; 240 | 241 | array[i] = hydrate(n); 242 | } 243 | } 244 | } else { 245 | const array = new Array(value.length); 246 | hydrated[index] = array; 247 | 248 | for (let i = 0; i < value.length; i += 1) { 249 | const n = value[i]; 250 | if (n === HOLE) continue; 251 | 252 | array[i] = hydrate(n); 253 | } 254 | } 255 | } else { 256 | /** @type {Record} */ 257 | const object = {}; 258 | hydrated[index] = object; 259 | 260 | for (const key in value) { 261 | const n = value[key]; 262 | object[key] = hydrate(n); 263 | } 264 | } 265 | 266 | return hydrated[index]; 267 | } 268 | 269 | return hydrate(`${line}:0`); 270 | } 271 | 272 | const reader = stream.getReader(); 273 | const lines = lineIterator(reader); 274 | 275 | const line = await lines.next(); 276 | if (line.done || !line.value) { 277 | throw new Error("Unexpected end of input"); 278 | } 279 | let lineCount = 0; 280 | const initialValue = unflatten(JSON.parse(line.value), lineCount++); 281 | 282 | const allReadyPromise = (async () => { 283 | for await (const line of lines) { 284 | if (line[0] !== "$") { 285 | throw new Error("Unexpected input"); 286 | } 287 | const match = line.match(/^\$(\d+):/); 288 | let promiseId: number; 289 | let deferred: Deferred; 290 | if ( 291 | !match || 292 | !match[1] || 293 | !Number.isSafeInteger((promiseId = Number.parseInt(match[1], 10))) || 294 | !(deferred = promises[promiseId]) 295 | ) { 296 | throw new Error("Unexpected input"); 297 | } 298 | const promiseResult = unflatten( 299 | JSON.parse(line.slice(match[0].length)), 300 | lineCount++ 301 | ); 302 | if ("error" in promiseResult) { 303 | deferred.reject(promiseResult.error); 304 | } else { 305 | deferred.resolve(promiseResult.value); 306 | } 307 | } 308 | })(); 309 | allReadyPromise.catch(() => {}); 310 | 311 | return [initialValue, allReadyPromise]; 312 | } 313 | 314 | async function* lineIterator(reader: ReadableStreamDefaultReader) { 315 | const utf8Decoder = new TextDecoder("utf-8"); 316 | 317 | let { value: binaryChunk, done: readerDone } = await reader.read(); 318 | let chunk = binaryChunk 319 | ? utf8Decoder.decode(binaryChunk, { stream: true }) 320 | : ""; 321 | 322 | const re = /\r\n|\n|\r/gm; 323 | let startIndex = 0; 324 | 325 | for (;;) { 326 | const result = re.exec(chunk); 327 | if (!result) { 328 | if (readerDone) { 329 | break; 330 | } 331 | let remainder = chunk.substr(startIndex); 332 | ({ value: binaryChunk, done: readerDone } = await reader.read()); 333 | chunk = 334 | remainder + 335 | (chunk ? utf8Decoder.decode(binaryChunk, { stream: true }) : ""); 336 | startIndex = re.lastIndex = 0; 337 | continue; 338 | } 339 | yield chunk.substring(startIndex, result.index); 340 | startIndex = re.lastIndex; 341 | } 342 | if (startIndex < chunk.length) { 343 | // last line didn't end in a newline char 344 | yield chunk.slice(startIndex); 345 | } 346 | } 347 | 348 | function serializeValue( 349 | thing: any, 350 | keys: string[], 351 | flatten: (value: any) => number | string, 352 | queuePromise: (promise: Promise) => number 353 | ) { 354 | let str = ""; 355 | 356 | if (typeof thing === "symbol") { 357 | const keyFor = Symbol.keyFor(thing); 358 | if (!keyFor) { 359 | throw new DevalueError( 360 | "Cannot symbols unless created with Symbol.for()", 361 | keys 362 | ); 363 | } 364 | str = `["Symbol",${stringify_primitive(keyFor)}]`; 365 | } else if (is_primitive(thing)) { 366 | str = stringify_primitive(thing); 367 | } else { 368 | const type = get_type(thing); 369 | 370 | switch (type) { 371 | case "Boolean": 372 | case "Number": 373 | case "String": 374 | str = `["Object",${stringify_primitive(thing)}]`; 375 | break; 376 | 377 | case "BigInt": 378 | str = `["BigInt",${thing}]`; 379 | break; 380 | 381 | case "Date": 382 | str = `["Date","${thing.toISOString()}"]`; 383 | break; 384 | 385 | case "RegExp": 386 | const { source, flags } = thing; 387 | str = flags 388 | ? `["RegExp",${stringify_string(source)},"${flags}"]` 389 | : `["RegExp",${stringify_string(source)}]`; 390 | break; 391 | 392 | case "Array": 393 | str = "["; 394 | 395 | for (let i = 0; i < thing.length; i += 1) { 396 | if (i > 0) str += ","; 397 | 398 | if (i in thing) { 399 | keys.push(`[${i}]`); 400 | str += flatten(thing[i]); 401 | keys.pop(); 402 | } else { 403 | str += HOLE; 404 | } 405 | } 406 | 407 | str += "]"; 408 | 409 | break; 410 | 411 | case "Set": 412 | str = '["Set"'; 413 | 414 | for (const value of thing) { 415 | str += `,${flatten(value)}`; 416 | } 417 | 418 | str += "]"; 419 | break; 420 | 421 | case "Map": 422 | str = '["Map"'; 423 | 424 | for (const [key, value] of thing) { 425 | keys.push( 426 | `.get(${is_primitive(key) ? stringify_primitive(key) : "..."})` 427 | ); 428 | str += `,${flatten(key)},${flatten(value)}`; 429 | } 430 | 431 | str += "]"; 432 | break; 433 | 434 | default: 435 | if (thing) { 436 | if (thing instanceof Promise) { 437 | str = `["Promise",${queuePromise(thing)}]`; 438 | break; 439 | } 440 | 441 | if (thing && "__c" in thing && thing.type) { 442 | if (thing.type.$$typeof === CLIENT_SYMBOL) { 443 | str = `["C",${flatten(thing.type.$$id)},${flatten(thing.props)}]`; 444 | break; 445 | } 446 | 447 | if (typeof thing.type === "function") { 448 | let children = thing.type(thing.props); 449 | 450 | let fallback = undefined; 451 | if (typeof thing.type.fallback === "function") { 452 | fallback = thing.type.fallback(thing.props); 453 | } 454 | str = `["V",${flatten(children)}`; 455 | if (fallback) { 456 | str += `,${flatten(fallback)}`; 457 | } 458 | str += "]"; 459 | break; 460 | } 461 | 462 | const rest: Record = {}; 463 | if (thing.__source) { 464 | rest.__source = thing.__source; 465 | } 466 | if (thing.__self) { 467 | rest.__self = thing.__self; 468 | } 469 | thing = { 470 | type: thing.type, 471 | props: thing.props, 472 | ...rest, 473 | }; 474 | } 475 | } 476 | 477 | if (!is_plain_object(thing)) { 478 | throw new DevalueError(`Cannot stringify arbitrary non-POJOs`, keys); 479 | } 480 | 481 | if (Object.getOwnPropertySymbols(thing).length > 0) { 482 | throw new DevalueError( 483 | `Cannot stringify POJOs with symbolic keys`, 484 | keys 485 | ); 486 | } 487 | 488 | if (Object.getPrototypeOf(thing) === null) { 489 | str = '["null"'; 490 | for (const key in thing) { 491 | keys.push(`.${key}`); 492 | str += `,${stringify_string(key)},${flatten(thing[key])}`; 493 | keys.pop(); 494 | } 495 | str += "]"; 496 | } else { 497 | str = "{"; 498 | let started = false; 499 | for (const key in thing) { 500 | if (started) str += ","; 501 | started = true; 502 | keys.push(`.${key}`); 503 | str += `${stringify_string(key)}:${flatten(thing[key])}`; 504 | keys.pop(); 505 | } 506 | str += "}"; 507 | } 508 | } 509 | } 510 | 511 | return str; 512 | } 513 | 514 | /** 515 | * @param {any} thing 516 | * @returns {string} 517 | */ 518 | function stringify_primitive(thing) { 519 | const type = typeof thing; 520 | if (type === "string") return stringify_string(thing); 521 | if (thing instanceof String) return stringify_string(thing.toString()); 522 | if (thing === void 0) return UNDEFINED.toString(); 523 | if (thing === 0 && 1 / thing < 0) return NEGATIVE_ZERO.toString(); 524 | if (type === "bigint") return `["BigInt","${thing}"]`; 525 | return String(thing); 526 | } 527 | 528 | /** @type {Record} */ 529 | export const escaped = { 530 | "<": "\\u003C", 531 | "\\": "\\\\", 532 | "\b": "\\b", 533 | "\f": "\\f", 534 | "\n": "\\n", 535 | "\r": "\\r", 536 | "\t": "\\t", 537 | "\u2028": "\\u2028", 538 | "\u2029": "\\u2029", 539 | }; 540 | 541 | export class DevalueError extends Error { 542 | path: string; 543 | /** 544 | * @param {string} message 545 | * @param {string[]} keys 546 | */ 547 | constructor(message, keys) { 548 | super(message); 549 | this.name = "DevalueError"; 550 | this.path = keys.join(""); 551 | } 552 | } 553 | 554 | /** @param {any} thing */ 555 | function is_primitive(thing) { 556 | return Object(thing) !== thing; 557 | } 558 | 559 | const object_proto_names = /* @__PURE__ */ Object.getOwnPropertyNames( 560 | Object.prototype 561 | ) 562 | .sort() 563 | .join("\0"); 564 | 565 | /** @param {any} thing */ 566 | function is_plain_object(thing) { 567 | const proto = Object.getPrototypeOf(thing); 568 | 569 | return ( 570 | proto === Object.prototype || 571 | proto === null || 572 | Object.getOwnPropertyNames(proto).sort().join("\0") === object_proto_names 573 | ); 574 | } 575 | 576 | /** @param {any} thing */ 577 | function get_type(thing) { 578 | return Object.prototype.toString.call(thing).slice(8, -1); 579 | } 580 | 581 | /** @param {string} char */ 582 | function get_escaped_char(char) { 583 | switch (char) { 584 | case '"': 585 | return '\\"'; 586 | case "<": 587 | return "\\u003C"; 588 | case "\\": 589 | return "\\\\"; 590 | case "\n": 591 | return "\\n"; 592 | case "\r": 593 | return "\\r"; 594 | case "\t": 595 | return "\\t"; 596 | case "\b": 597 | return "\\b"; 598 | case "\f": 599 | return "\\f"; 600 | case "\u2028": 601 | return "\\u2028"; 602 | case "\u2029": 603 | return "\\u2029"; 604 | default: 605 | return char < " " 606 | ? `\\u${char.charCodeAt(0).toString(16).padStart(4, "0")}` 607 | : ""; 608 | } 609 | } 610 | 611 | /** @param {string} str */ 612 | function stringify_string(str) { 613 | let result = ""; 614 | let last_pos = 0; 615 | const len = str.length; 616 | 617 | for (let i = 0; i < len; i += 1) { 618 | const char = str[i]; 619 | const replacement = get_escaped_char(char); 620 | if (replacement) { 621 | result += str.slice(last_pos, i) + replacement; 622 | last_pos = i + 1; 623 | } 624 | } 625 | 626 | return `"${last_pos === 0 ? str : result + str.slice(last_pos)}"`; 627 | } 628 | 629 | class Deferred { 630 | promise: Promise; 631 | resolve: (value: T) => void; 632 | reject: (reason?: any) => void; 633 | constructor() { 634 | this.promise = new Promise((resolve, reject) => { 635 | this.resolve = resolve; 636 | this.reject = reject; 637 | }); 638 | } 639 | } 640 | -------------------------------------------------------------------------------- /packages/joe-dom/src/types.d.ts: -------------------------------------------------------------------------------- 1 | // Adapted from https://github.com/preactjs/preact 2 | 3 | export as namespace joedom; 4 | 5 | import { JSXInternal } from "./jsx.js"; 6 | 7 | export import JSX = JSXInternal; 8 | 9 | // 10 | // Preact Virtual DOM 11 | // ----------------------------------- 12 | 13 | export interface VNode

{ 14 | $$typeof: symbol; 15 | type: ComponentType

| string; 16 | props: P & { children: ComponentChildren }; 17 | key: Key; 18 | /** 19 | * ref is not guaranteed by React.ReactElement, for compatibility reasons 20 | * with popular react libs we define it as optional too 21 | */ 22 | ref?: Ref | null; 23 | } 24 | 25 | // 26 | // Preact Component interface 27 | // ----------------------------------- 28 | 29 | export type Key = string | number | any; 30 | 31 | export type RefObject = { current: T | null }; 32 | export type RefCallback = (instance: T | null) => void; 33 | export type Ref = RefObject | RefCallback | null; 34 | 35 | export type ComponentChildType = 36 | | VNode 37 | | object 38 | | string 39 | | number 40 | | bigint 41 | | boolean 42 | | null 43 | | undefined; 44 | 45 | export type ComponentChild = ComponentChildType | Promise; 46 | export type ComponentChildren = ComponentChild[] | ComponentChild; 47 | 48 | export interface Attributes { 49 | key?: Key | undefined; 50 | jsx?: boolean | undefined; 51 | } 52 | 53 | export interface ComponentAttributes extends Attributes { 54 | ref?: Ref; 55 | } 56 | 57 | export interface JOEDOMAttributes { 58 | children?: ComponentChildren; 59 | dangerouslySetInnerHTML?: { 60 | __html: string; 61 | }; 62 | } 63 | 64 | export interface ErrorInfo { 65 | componentStack?: string; 66 | } 67 | 68 | export type RenderableProps = P & 69 | Readonly }>; 70 | 71 | export interface ClientComponent

{ 72 | (props: RenderableProps

, context?: any): ComponentChild; 73 | $$typeof: symbol; 74 | $$id: string | number; 75 | } 76 | 77 | export type ComponentType

= FunctionComponent

| ClientComponent

; 78 | export type ComponentFactory

= ComponentType

; 79 | 80 | export type ComponentProps< 81 | C extends ComponentType | keyof JSXInternal.IntrinsicElements 82 | > = C extends ComponentType 83 | ? P 84 | : C extends keyof JSXInternal.IntrinsicElements 85 | ? JSXInternal.IntrinsicElements[C] 86 | : never; 87 | 88 | export interface FunctionComponent

{ 89 | $$typeof?: symbol | undefined; 90 | $$id?: string | number | undefined; 91 | (props: RenderableProps

, context?: any): ComponentChild; 92 | displayName?: string; 93 | defaultProps?: Partial

| undefined; 94 | fallback?: FunctionComponent

| undefined; 95 | } 96 | 97 | // Type alias for a component instance considered generally, whether stateless or stateful. 98 | export type AnyComponent

= 99 | | FunctionComponent

100 | | Component; 101 | 102 | export interface Component

{ 103 | componentWillMount?(): void; 104 | componentDidMount?(): void; 105 | componentWillUnmount?(): void; 106 | getChildContext?(): object; 107 | componentWillReceiveProps?(nextProps: Readonly

, nextContext: any): void; 108 | shouldComponentUpdate?( 109 | nextProps: Readonly

, 110 | nextState: Readonly, 111 | nextContext: any 112 | ): boolean; 113 | componentWillUpdate?( 114 | nextProps: Readonly

, 115 | nextState: Readonly, 116 | nextContext: any 117 | ): void; 118 | getSnapshotBeforeUpdate?(oldProps: Readonly

, oldState: Readonly): any; 119 | componentDidUpdate?( 120 | previousProps: Readonly

, 121 | previousState: Readonly, 122 | snapshot: any 123 | ): void; 124 | componentDidCatch?(error: any, errorInfo: ErrorInfo): void; 125 | } 126 | 127 | export abstract class Component { 128 | constructor(props?: P, context?: any); 129 | 130 | static displayName?: string; 131 | static defaultProps?: any; 132 | static contextType?: Context; 133 | 134 | // Static members cannot reference class type parameters. This is not 135 | // supported in TypeScript. Reusing the same type arguments from `Component` 136 | // will lead to an impossible state where one cannot satisfy the type 137 | // constraint under no circumstances, see #1356.In general type arguments 138 | // seem to be a bit buggy and not supported well at the time of this 139 | // writing with TS 3.3.3333. 140 | static getDerivedStateFromProps?( 141 | props: Readonly, 142 | state: Readonly 143 | ): object | null; 144 | static getDerivedStateFromError?(error: any): object | null; 145 | 146 | state: Readonly; 147 | props: RenderableProps

; 148 | context: any; 149 | base?: Element | Text; 150 | 151 | // From https://github.com/DefinitelyTyped/DefinitelyTyped/blob/e836acc75a78cf0655b5dfdbe81d69fdd4d8a252/types/react/index.d.ts#L402 152 | // // We MUST keep setState() as a unified signature because it allows proper checking of the method return type. 153 | // // See: https://github.com/DefinitelyTyped/DefinitelyTyped/issues/18365#issuecomment-351013257 154 | setState( 155 | state: 156 | | (( 157 | prevState: Readonly, 158 | props: Readonly

159 | ) => Pick | Partial | null) 160 | | (Pick | Partial | null), 161 | callback?: () => void 162 | ): void; 163 | 164 | forceUpdate(callback?: () => void): void; 165 | 166 | abstract render( 167 | props?: RenderableProps

, 168 | state?: Readonly, 169 | context?: any 170 | ): ComponentChild; 171 | } 172 | 173 | // 174 | // Preact createElement 175 | // ----------------------------------- 176 | 177 | export function createElement( 178 | type: "input", 179 | props: 180 | | (JSXInternal.DOMAttributes & 181 | ComponentAttributes) 182 | | null, 183 | ...children: ComponentChildren[] 184 | ): VNode; 185 | export function createElement< 186 | P extends JSXInternal.HTMLAttributes, 187 | T extends HTMLElement 188 | >( 189 | type: keyof JSXInternal.IntrinsicElements, 190 | props: (ComponentAttributes & P) | null, 191 | ...children: ComponentChildren[] 192 | ): VNode; 193 | export function createElement< 194 | P extends JSXInternal.SVGAttributes, 195 | T extends HTMLElement 196 | >( 197 | type: keyof JSXInternal.IntrinsicElements, 198 | props: (ComponentAttributes & P) | null, 199 | ...children: ComponentChildren[] 200 | ): VNode; 201 | export function createElement( 202 | type: string, 203 | props: 204 | | (ComponentAttributes & 205 | JSXInternal.HTMLAttributes & 206 | JSXInternal.SVGAttributes) 207 | | null, 208 | ...children: ComponentChildren[] 209 | ): VNode; 210 | export function createElement

( 211 | type: ComponentType

, 212 | props: (Attributes & P) | null, 213 | ...children: ComponentChildren[] 214 | ): VNode; 215 | export namespace createElement { 216 | export import JSX = JSXInternal; 217 | } 218 | 219 | export function h( 220 | type: "input", 221 | props: 222 | | (JSXInternal.DOMAttributes & 223 | ComponentAttributes) 224 | | null, 225 | ...children: ComponentChildren[] 226 | ): VNode; 227 | export function h< 228 | P extends JSXInternal.HTMLAttributes, 229 | T extends HTMLElement 230 | >( 231 | type: keyof JSXInternal.IntrinsicElements, 232 | props: (ComponentAttributes & P) | null, 233 | ...children: ComponentChildren[] 234 | ): VNode; 235 | export function h< 236 | P extends JSXInternal.SVGAttributes, 237 | T extends HTMLElement 238 | >( 239 | type: keyof JSXInternal.IntrinsicElements, 240 | props: (ComponentAttributes & P) | null, 241 | ...children: ComponentChildren[] 242 | ): VNode; 243 | export function h( 244 | type: string, 245 | props: 246 | | (ComponentAttributes & 247 | JSXInternal.HTMLAttributes & 248 | JSXInternal.SVGAttributes) 249 | | null, 250 | ...children: ComponentChildren[] 251 | ): VNode; 252 | export function h

( 253 | type: ComponentType

, 254 | props: (Attributes & P) | null, 255 | ...children: ComponentChildren[] 256 | ): VNode; 257 | export namespace h { 258 | export import JSX = JSXInternal; 259 | } 260 | 261 | // 262 | // Preact render 263 | // ----------------------------------- 264 | 265 | interface ContainerNode { 266 | nodeType: Node["nodeType"]; 267 | parentNode: Node["parentNode"]; 268 | firstChild: Node["firstChild"]; 269 | insertBefore: Node["insertBefore"]; 270 | appendChild: Node["appendChild"]; 271 | removeChild: Node["removeChild"]; 272 | childNodes: ArrayLike; 273 | } 274 | 275 | export function render(vnode: ComponentChild, parent: ContainerNode): void; 276 | /** 277 | * @deprecated Will be removed in v11. 278 | * 279 | * Replacement Preact 10+ implementation can be found here: https://gist.github.com/developit/f4c67a2ede71dc2fab7f357f39cff28c 280 | */ 281 | export function render( 282 | vnode: ComponentChild, 283 | parent: ContainerNode, 284 | replaceNode?: Element | Text 285 | ): void; 286 | export function hydrate(vnode: ComponentChild, parent: ContainerNode): void; 287 | export function cloneElement( 288 | vnode: VNode, 289 | props?: any, 290 | ...children: ComponentChildren[] 291 | ): VNode; 292 | export function cloneElement

( 293 | vnode: VNode

, 294 | props?: any, 295 | ...children: ComponentChildren[] 296 | ): VNode

; 297 | 298 | // 299 | // Preact Built-in Components 300 | // ----------------------------------- 301 | 302 | // TODO: Revisit what the public type of this is... 303 | export const Fragment: FunctionComponent<{}>; 304 | 305 | // 306 | // Preact options 307 | // ----------------------------------- 308 | 309 | /** 310 | * Global options for preact 311 | */ 312 | export interface Options { 313 | /** Attach a hook that is invoked whenever a VNode is created. */ 314 | vnode?(vnode: VNode): void; 315 | /** Attach a hook that is invoked immediately before a vnode is unmounted. */ 316 | unmount?(vnode: VNode): void; 317 | /** Attach a hook that is invoked after a vnode has rendered. */ 318 | diffed?(vnode: VNode): void; 319 | event?(e: Event): any; 320 | requestAnimationFrame?(callback: () => void): void; 321 | debounceRendering?(cb: () => void): void; 322 | useDebugValue?(value: string | number): void; 323 | _addHookName?(name: string | number): void; 324 | __suspenseDidResolve?(vnode: VNode, cb: () => void): void; 325 | // __canSuspenseResolve?(vnode: VNode, cb: () => void): void; 326 | } 327 | 328 | export const options: Options; 329 | 330 | // 331 | // Preact helpers 332 | // ----------------------------------- 333 | export function createRef(): RefObject; 334 | export function toChildArray( 335 | children: ComponentChildren 336 | ): Array; 337 | export function isValidElement(vnode: any): vnode is VNode; 338 | 339 | // 340 | // Context 341 | // ----------------------------------- 342 | export interface Consumer 343 | extends FunctionComponent<{ 344 | children: (value: T) => ComponentChildren; 345 | }> {} 346 | export interface JOEConsumer extends Consumer {} 347 | 348 | export interface Provider 349 | extends FunctionComponent<{ 350 | value: T; 351 | children: ComponentChildren; 352 | }> {} 353 | export interface JOEProvider extends Provider {} 354 | export type ContextType> = C extends Context 355 | ? T 356 | : never; 357 | 358 | export interface Context { 359 | Consumer: Consumer; 360 | Provider: Provider; 361 | displayName?: string; 362 | } 363 | export interface JOEContext extends Context {} 364 | 365 | export function createContext(defaultValue: T): Context; 366 | -------------------------------------------------------------------------------- /packages/joe-dom/src/utils.ts: -------------------------------------------------------------------------------- 1 | export function isPromise(obj): obj is Promise { 2 | return ( 3 | obj && typeof obj.then === "function" && typeof obj.catch === "function" 4 | ); 5 | } 6 | 7 | // Adapted from https://github.com/preactjs/preact-render-to-string 8 | 9 | export const VOID_ELEMENTS = 10 | /^(?:area|base|br|col|embed|hr|img|input|link|meta|param|source|track|wbr)$/; 11 | export const UNSAFE_NAME = /[\s\n\\/='"\0<>]/; 12 | export const XLINK = /^xlink:?./; 13 | export const XLINK_REPLACE_REGEX = /^xlink:?/; 14 | // DOM properties that should NOT have "px" added when numeric 15 | const ENCODED_ENTITIES = /["&<]/; 16 | export function encodeEntities(str) { 17 | // Skip all work for strings with no entities needing encoding: 18 | if (str.length === 0 || ENCODED_ENTITIES.test(str) === false) return str; 19 | 20 | let last = 0, 21 | i = 0, 22 | out = "", 23 | ch = ""; 24 | 25 | // Seek forward in str until the next entity char: 26 | for (; i < str.length; i++) { 27 | switch (str.charCodeAt(i)) { 28 | case 34: 29 | ch = """; 30 | break; 31 | case 38: 32 | ch = "&"; 33 | break; 34 | case 60: 35 | ch = "<"; 36 | break; 37 | default: 38 | continue; 39 | } 40 | // Append skipped/buffered characters and the encoded entity: 41 | if (i !== last) out += str.slice(last, i); 42 | out += ch; 43 | // Start the next seek/buffer after the entity's offset: 44 | last = i + 1; 45 | } 46 | if (i !== last) out += str.slice(last, i); 47 | return out; 48 | } 49 | 50 | const CSS_REGEX = /[A-Z]/g; 51 | const IS_NON_DIMENSIONAL = new Set([ 52 | "animation-iteration-count", 53 | "border-image-outset", 54 | "border-image-slice", 55 | "border-image-width", 56 | "box-flex", 57 | "box-flex-group", 58 | "box-ordinal-group", 59 | "column-count", 60 | "fill-opacity", 61 | "flex", 62 | "flex-grow", 63 | "flex-negative", 64 | "flex-order", 65 | "flex-positive", 66 | "flex-shrink", 67 | "flood-opacity", 68 | "font-weight", 69 | "grid-column", 70 | "grid-row", 71 | "line-clamp", 72 | "line-height", 73 | "opacity", 74 | "order", 75 | "orphans", 76 | "stop-opacity", 77 | "stroke-dasharray", 78 | "stroke-dashoffset", 79 | "stroke-miterlimit", 80 | "stroke-opacity", 81 | "stroke-width", 82 | "tab-size", 83 | "widows", 84 | "z-index", 85 | "zoom", 86 | ]); 87 | 88 | const JS_TO_CSS = {}; 89 | export function styleObjToCss(s) { 90 | let str = ""; 91 | for (let prop in s) { 92 | let val = s[prop]; 93 | if (val != null && val !== "") { 94 | const name = 95 | prop[0] == "-" 96 | ? prop 97 | : JS_TO_CSS[prop] || 98 | (JS_TO_CSS[prop] = prop.replace(CSS_REGEX, "-$&").toLowerCase()); 99 | 100 | let suffix = ";"; 101 | if ( 102 | typeof val === "number" && 103 | // Exclude custom-attributes 104 | !name.startsWith("--") && 105 | !IS_NON_DIMENSIONAL.has(name) 106 | ) { 107 | suffix = "px;"; 108 | } 109 | str = str + name + ":" + val + suffix; 110 | } 111 | } 112 | return str || undefined; 113 | } 114 | -------------------------------------------------------------------------------- /packages/joe-dom/tests/loader.test.ts: -------------------------------------------------------------------------------- 1 | import { deepStrictEqual, strictEqual } from "node:assert/strict"; 2 | import { describe, it } from "node:test"; 3 | 4 | import { serverModuleTransform } from "../loader.js"; 5 | 6 | describe("loader", () => { 7 | it("should ignore non use client or user server modules", () => { 8 | const input = ` 9 | // "use client"; 10 | // "use server"; 11 | `; 12 | deepStrictEqual(serverModuleTransform(input), { 13 | useClient: false, 14 | useServer: false, 15 | source: input, 16 | }); 17 | }); 18 | 19 | it("should transform use client modules", () => { 20 | const input = ` 21 | "use client"; 22 | import { a } from "./foo.js"; 23 | export const foo = () => {}; 24 | export let bar = () => {}; 25 | export var baz = () => {}; 26 | const qux = () => {}; 27 | export { a, qux }; 28 | const def = () => {}; 29 | export default def; 30 | `; 31 | deepStrictEqual(serverModuleTransform(input, "/foo.js"), { 32 | useClient: true, 33 | useServer: false, 34 | exportNames: ["foo", "bar", "baz", "a", "qux", "default"], 35 | defaultName: "def", 36 | source: 37 | 'import {CLIENT_SYMBOL} from "joe-dom";\nexport const foo = {$$typeof:CLIENT_SYMBOL,$$id:"/foo.js#foo"};\nexport const bar = {$$typeof:CLIENT_SYMBOL,$$id:"/foo.js#bar"};\nexport const baz = {$$typeof:CLIENT_SYMBOL,$$id:"/foo.js#baz"};\nexport const a = {$$typeof:CLIENT_SYMBOL,$$id:"/foo.js#a"};\nexport const qux = {$$typeof:CLIENT_SYMBOL,$$id:"/foo.js#qux"};\nexport default {$$typeof:CLIENT_SYMBOL,$$id:"/foo.js#default"};\n', 38 | }); 39 | }); 40 | 41 | it("should error on direct re-exports", () => { 42 | const input = ` 43 | "use client"; 44 | export { error } from "./foo.js"; 45 | `; 46 | try { 47 | serverModuleTransform(input); 48 | } catch (error) { 49 | strictEqual(error.message, "Export from not supported"); 50 | return; 51 | } 52 | throw new Error("Expected error to be thrown."); 53 | }); 54 | 55 | it("should error on export all", () => { 56 | const input = ` 57 | "use client"; 58 | export * from "./foo.js"; 59 | `; 60 | try { 61 | serverModuleTransform(input); 62 | } catch (error) { 63 | strictEqual(error.message, "Export all not supported"); 64 | return; 65 | } 66 | throw new Error("Expected error to be thrown."); 67 | }); 68 | }); 69 | -------------------------------------------------------------------------------- /packages/joe-dom/tests/serializer.test.ts: -------------------------------------------------------------------------------- 1 | import { strictEqual, deepEqual } from "node:assert/strict"; 2 | import { describe, it } from "node:test"; 3 | 4 | import { serialize, deserialize } from "../src/serializer.js"; 5 | 6 | describe("serializer", () => { 7 | it("should serialize primitives", async () => { 8 | const value = [ 9 | undefined, 10 | null, 11 | true, 12 | false, 13 | 0, 14 | 1, 15 | -1, 16 | 1.2, 17 | -1.2, 18 | NaN, 19 | Infinity, 20 | -Infinity, 21 | ]; 22 | const stream = serialize(value); 23 | const [a, b] = stream.tee(); 24 | const serialized = await new Response(a).text(); 25 | strictEqual( 26 | serialized, 27 | '[[-1,"0:1","0:2","0:3","0:4","0:5","0:6","0:7","0:8",-3,-4,-5],null,true,false,0,1,-1,1.2,-1.2]\n' 28 | ); 29 | const [deserialized] = await deserialize(b); 30 | deepEqual(deserialized, value); 31 | }); 32 | 33 | it("should serialize strings", async () => { 34 | const stream = serialize(["", "foo", "bar", "baz"]); 35 | const [a, b] = stream.tee(); 36 | const serialized = await new Response(a).text(); 37 | strictEqual( 38 | serialized, 39 | '[["0:1","0:2","0:3","0:4"],"","foo","bar","baz"]\n' 40 | ); 41 | const [deserialized] = await deserialize(b); 42 | deepEqual(deserialized, ["", "foo", "bar", "baz"]); 43 | }); 44 | 45 | it("should dedupe strings", async () => { 46 | const stream = serialize(["foo", "bar", "foo", "bar"]); 47 | const [a, b] = stream.tee(); 48 | const serialized = await new Response(a).text(); 49 | strictEqual(serialized, '[["0:1","0:2","0:1","0:2"],"foo","bar"]\n'); 50 | const [deserialized] = await deserialize(b); 51 | deepEqual(deserialized, ["foo", "bar", "foo", "bar"]); 52 | }); 53 | 54 | it("should serialize objects", async () => { 55 | const stream = serialize([{ foo: "bar" }, { foo: "bar" }]); 56 | const [a, b] = stream.tee(); 57 | const serialized = await new Response(a).text(); 58 | strictEqual( 59 | serialized, 60 | '[["0:1","0:3"],{"foo":"0:2"},"bar",{"foo":"0:2"}]\n' 61 | ); 62 | const [deserialized] = await deserialize(b); 63 | deepEqual(deserialized, [{ foo: "bar" }, { foo: "bar" }]); 64 | }); 65 | 66 | it("should serialize circular objects", async () => { 67 | const a = { foo: "bar" }; 68 | const b = { fiz: "bang" }; 69 | (a as any).b = b; 70 | (b as any).a = a; 71 | const stream = serialize(a); 72 | const [sa, sb] = stream.tee(); 73 | const serialized = await new Response(sa).text(); 74 | strictEqual( 75 | serialized, 76 | '[{"foo":"0:1","b":"0:2"},"bar",{"fiz":"0:3","a":"0:0"},"bang"]\n' 77 | ); 78 | const [deserialized] = await deserialize(sb); 79 | deepEqual(deserialized, a); 80 | }); 81 | 82 | it("should serialize dates", async () => { 83 | const stream = serialize([new Date(0), new Date(1)]); 84 | const [a, b] = stream.tee(); 85 | const serialized = await new Response(a).text(); 86 | strictEqual( 87 | serialized, 88 | '[["0:1","0:2"],["Date","1970-01-01T00:00:00.000Z"],["Date","1970-01-01T00:00:00.001Z"]]\n' 89 | ); 90 | const [deserialized] = await deserialize(b); 91 | deepEqual(deserialized, [new Date(0), new Date(1)]); 92 | }); 93 | 94 | it("should serialize regexps", async () => { 95 | const stream = serialize([/foo/, /bar/g]); 96 | const [a, b] = stream.tee(); 97 | const serialized = await new Response(a).text(); 98 | strictEqual( 99 | serialized, 100 | '[["0:1","0:2"],["RegExp","foo"],["RegExp","bar","g"]]\n' 101 | ); 102 | const [deserialized] = await deserialize(b); 103 | deepEqual(deserialized, [/foo/, /bar/g]); 104 | }); 105 | 106 | it("should serialize bigints", async () => { 107 | const stream = serialize([BigInt(0), BigInt(1)]); 108 | const [a, b] = stream.tee(); 109 | const serialized = await new Response(a).text(); 110 | strictEqual(serialized, '[["0:1","0:2"],["BigInt","0"],["BigInt","1"]]\n'); 111 | const [deserialized] = await deserialize(b); 112 | deepEqual(deserialized, [BigInt(0), BigInt(1)]); 113 | }); 114 | 115 | it("should serialize symbols", async () => { 116 | const stream = serialize([Symbol.for("foo"), Symbol.for("bar")]); 117 | const [a, b] = stream.tee(); 118 | const serialized = await new Response(a).text(); 119 | strictEqual( 120 | serialized, 121 | '[["0:1","0:2"],["Symbol","foo"],["Symbol","bar"]]\n' 122 | ); 123 | const [deserialized] = await deserialize(b); 124 | deepEqual(deserialized, [Symbol.for("foo"), Symbol.for("bar")]); 125 | }); 126 | 127 | it("should serialize promise", async () => { 128 | const stream = serialize([0, 1, Promise.resolve(0), Promise.resolve(1)]); 129 | const [a, b] = stream.tee(); 130 | const serialized = await new Response(a).text(); 131 | strictEqual( 132 | serialized, 133 | '[["0:1","0:2","0:3","0:4"],0,1,["Promise",0],["Promise",1]]\n$0:[{"value":"0:1"}]\n$1:[{"value":"0:2"}]\n' 134 | ); 135 | const [deserialized] = await deserialize(b); 136 | strictEqual(deserialized[0], 0); 137 | strictEqual(deserialized[1], 1); 138 | strictEqual(deserialized[2] instanceof Promise, true); 139 | strictEqual(deserialized[3] instanceof Promise, true); 140 | strictEqual(await deserialized[2], 0); 141 | strictEqual(await deserialized[3], 1); 142 | }); 143 | 144 | it("should serialize promise that returns cyclic object in initial response", async () => { 145 | const a = { foo: "bar" }; 146 | const b = { fiz: "bang" }; 147 | (a as any).b = b; 148 | (b as any).a = a; 149 | const stream = serialize({ a, b: Promise.resolve(b) }); 150 | const [sa, sb] = stream.tee(); 151 | const serialized = await new Response(sa).text(); 152 | strictEqual( 153 | serialized, 154 | '[{"a":"0:1","b":"0:5"},{"foo":"0:2","b":"0:3"},"bar",{"fiz":"0:4","a":"0:1"},"bang",["Promise",0]]\n$0:[{"value":"0:3"}]\n' 155 | ); 156 | const [deserialized] = await deserialize(sb); 157 | strictEqual(deserialized.a.foo, "bar"); 158 | strictEqual(deserialized.a.b, await deserialized.b); 159 | strictEqual((await deserialized.b).fiz, "bang"); 160 | strictEqual((await deserialized.b).a, deserialized.a); 161 | }); 162 | 163 | it("should allow for nested promises", async () => { 164 | const a = Promise.resolve({ 165 | b: Promise.resolve({ 166 | c: Promise.resolve("c"), 167 | }), 168 | }); 169 | const stream = serialize(a); 170 | const [sa, sb] = stream.tee(); 171 | const serialized = await new Response(sa).text(); 172 | strictEqual( 173 | serialized, 174 | '[["Promise",0]]\n$0:[{"value":"1:1"},{"b":"1:2"},["Promise",1]]\n$1:[{"value":"2:1"},{"c":"2:2"},["Promise",2]]\n$2:[{"value":"3:1"},"c"]\n' 175 | ); 176 | const [deserialized] = await deserialize(sb); 177 | strictEqual(deserialized instanceof Promise, true); 178 | strictEqual((await deserialized).b instanceof Promise, true); 179 | strictEqual((await (await deserialized).b).c instanceof Promise, true); 180 | strictEqual(await (await (await deserialized).b).c, "c"); 181 | }); 182 | }); 183 | -------------------------------------------------------------------------------- /packages/joe-dom/tests/ssr.test.tsx: -------------------------------------------------------------------------------- 1 | import { strictEqual } from "node:assert/strict"; 2 | import { describe, it } from "node:test"; 3 | 4 | import { type FunctionComponent, createElement } from "../src/joe-dom.js"; 5 | import { render } from "../src/joe-dom.server.js"; 6 | import { fallbackRuntime, islandRuntime } from "../src/runtime.js"; 7 | 8 | describe("SSR", () => { 9 | it("should render div", async () => { 10 | const rendered = render(

Hello, World!
); 11 | const html = await new Response(rendered).text(); 12 | strictEqual(html, "
Hello, World!
"); 13 | }); 14 | 15 | it("should render nested tags", async () => { 16 | const rendered = render( 17 |
18 | Hello 19 | , 20 | World! 21 |
22 | ); 23 | const html = await new Response(rendered).text(); 24 | strictEqual(html, "
Hello,World!
"); 25 | }); 26 | 27 | it("should render self closing tags", async () => { 28 | const rendered = render( 29 | <> 30 | 31 | 32 |
33 | 34 | 35 |
36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | ); 46 | const html = await new Response(rendered).text(); 47 | strictEqual( 48 | html, 49 | "

" 50 | ); 51 | }); 52 | 53 | it("should render attributes", async () => { 54 | const rendered = render( 55 |
56 | {}} /> 57 |
58 | 61 | " + 72 | "
" 73 | ); 74 | }); 75 | 76 | it("should render svg", async () => { 77 | const rendered = render( 78 | 79 | 80 | 81 | {/* @ts-expect-error */} 82 |
83 | 84 | 85 | 86 | 87 | 88 | ); 89 | const html = await new Response(rendered).text(); 90 | strictEqual( 91 | html, 92 | '
' 93 | ); 94 | }); 95 | 96 | it("should render component", async () => { 97 | const SayHello = ({ name }: { name: string }) => `Hello, ${name}!`; 98 | 99 | const rendered = render( 100 |
101 | 102 |
103 | ); 104 | const html = await new Response(rendered).text(); 105 | strictEqual(html, "
Hello, World!
"); 106 | }); 107 | 108 | it("should render async component", async () => { 109 | const SayHello = async ({ name }: { name: string }) => `Hello, ${name}!`; 110 | 111 | const rendered = render( 112 |
113 | 114 |
115 | ); 116 | const html = await new Response(rendered).text(); 117 | strictEqual(html, "
Hello, World!
"); 118 | }); 119 | 120 | it("should render multiple async components", async () => { 121 | const SayHello = async ({ 122 | name, 123 | timeout, 124 | }: { 125 | name: string; 126 | timeout: number; 127 | }) => { 128 | await new Promise((resolve) => setTimeout(resolve, timeout)); 129 | return
Hello, {name}!
; 130 | }; 131 | 132 | const rendered = render( 133 | <> 134 | 135 | 136 | 137 | ); 138 | const html = await new Response(rendered).text(); 139 | strictEqual(html, "
Hello, 1!
Hello, 2!
"); 140 | }); 141 | 142 | it("should render fallback", async () => { 143 | const SayHello: FunctionComponent<{ name: string }> = async ({ name }) => ( 144 |
Hello, {name}!
145 | ); 146 | SayHello.fallback = () =>
Loading...
; 147 | 148 | const rendered = render(); 149 | const html = await new Response(rendered).text(); 150 | strictEqual( 151 | html, 152 | `
Loading...
${fallbackRuntime}${islandRuntime}` 153 | ); 154 | }); 155 | 156 | it("should render multiple fallbacks", async () => { 157 | const SayHello: FunctionComponent<{ 158 | name: string; 159 | timeout: number; 160 | }> = async ({ name, timeout }) => { 161 | await new Promise((resolve) => setTimeout(resolve, timeout)); 162 | return
Hello, {name}!
; 163 | }; 164 | SayHello.fallback = ({ name }) =>
Loading {name}...
; 165 | 166 | const rendered = render( 167 | <> 168 | 169 | 170 | 171 | ); 172 | const html = await new Response(rendered).text(); 173 | strictEqual( 174 | html, 175 | `
Loading 1...
Loading 2...
${fallbackRuntime}${islandRuntime}` 176 | ); 177 | }); 178 | 179 | it("should render fallback caused by child", async () => { 180 | const Boundary: FunctionComponent = ({ children }) => { 181 | return children; 182 | }; 183 | Boundary.fallback = () =>
Loading...
; 184 | 185 | const SayHello: FunctionComponent<{ name: string }> = async ({ name }) => ( 186 |
Hello, {name}!
187 | ); 188 | 189 | const rendered = render( 190 | 191 | 192 | 193 | ); 194 | const html = await new Response(rendered).text(); 195 | strictEqual( 196 | html, 197 | `
Loading...
${fallbackRuntime}${islandRuntime}` 198 | ); 199 | }); 200 | 201 | it("should render fallback caused by descendant", async () => { 202 | const Boundary: FunctionComponent = ({ children }) => { 203 | return ; 204 | }; 205 | Boundary.fallback = () =>
Loading...
; 206 | 207 | const SayHello: FunctionComponent<{ name: string }> = async ({ name }) => ( 208 |
Hello, {name}!
209 | ); 210 | 211 | const rendered = render(); 212 | const html = await new Response(rendered).text(); 213 | strictEqual( 214 | html, 215 | `
Loading...
${fallbackRuntime}${islandRuntime}` 216 | ); 217 | }); 218 | 219 | it("works with createElement", async () => { 220 | const SayHello: FunctionComponent<{ 221 | name: string; 222 | timeout: number; 223 | }> = async ({ name, timeout }) => { 224 | await new Promise((resolve) => setTimeout(resolve, timeout)); 225 | return createElement("div", undefined, "Hello, ", name, "!"); 226 | }; 227 | SayHello.fallback = ({ name }) => 228 | createElement("div", undefined, ["Loading ", name, "..."]); 229 | 230 | const rendered = render([ 231 | createElement(SayHello, { name: "1", timeout: 10 }), 232 | createElement(SayHello, { name: "2", timeout: 5 }), 233 | ]); 234 | const html = await new Response(rendered).text(); 235 | strictEqual( 236 | html, 237 | `
Loading 1...
Loading 2...
${fallbackRuntime}${islandRuntime}` 238 | ); 239 | }); 240 | }); 241 | -------------------------------------------------------------------------------- /packages/joe-dom/tests/wire-format.test.tsx: -------------------------------------------------------------------------------- 1 | import { strictEqual } from "node:assert/strict"; 2 | import { describe, it } from "node:test"; 3 | 4 | import { 5 | type ClientComponent, 6 | type FunctionComponent, 7 | CLIENT_SYMBOL, 8 | createElement, 9 | } from "../src/joe-dom.js"; 10 | import { deserialize, render, serialize } from "../src/joe-dom.server.js"; 11 | import { fallbackRuntime, islandRuntime } from "../src/runtime.js"; 12 | 13 | describe("wire format", () => { 14 | it("should render div", async () => { 15 | const serialized = serialize(
Hello, World!
); 16 | const [deserialized] = await deserialize(serialized); 17 | const rendered = render(deserialized); 18 | const html = await new Response(rendered).text(); 19 | strictEqual(html, "
Hello, World!
"); 20 | }); 21 | 22 | it("should render nested tags", async () => { 23 | const serialized = serialize( 24 |
25 | Hello 26 | , 27 | World! 28 |
29 | ); 30 | const [deserialized] = await deserialize(serialized); 31 | const rendered = render(deserialized); 32 | const html = await new Response(rendered).text(); 33 | strictEqual(html, "
Hello,World!
"); 34 | }); 35 | 36 | it("should render self closing tags", async () => { 37 | const serialized = serialize( 38 | <> 39 | 40 | 41 |
42 | 43 | 44 |
45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | ); 55 | const [deserialized] = await deserialize(serialized); 56 | const rendered = render(deserialized); 57 | const html = await new Response(rendered).text(); 58 | strictEqual( 59 | html, 60 | "

" 61 | ); 62 | }); 63 | 64 | it("should render attributes", async () => { 65 | const serialized = serialize( 66 |
67 | 68 |
69 | 72 | " + 85 | "
" 86 | ); 87 | }); 88 | 89 | it("should render svg", async () => { 90 | const serialized = serialize( 91 | 92 | 93 | 94 | {/* @ts-expect-error */} 95 |
96 | 97 | 98 | 99 | 100 | 101 | ); 102 | const [deserialized] = await deserialize(serialized); 103 | const rendered = render(deserialized); 104 | const html = await new Response(rendered).text(); 105 | strictEqual( 106 | html, 107 | '
' 108 | ); 109 | }); 110 | 111 | it("should render component", async () => { 112 | const SayHello = ({ name }: { name: string }) => `Hello, ${name}!`; 113 | 114 | const serialized = serialize( 115 |
116 | 117 |
118 | ); 119 | const [deserialized] = await deserialize(serialized); 120 | const rendered = render(deserialized); 121 | const html = await new Response(rendered).text(); 122 | strictEqual(html, "
Hello, World!
"); 123 | }); 124 | 125 | it("should render async component", async () => { 126 | const SayHello = async ({ name }: { name: string }) => `Hello, ${name}!`; 127 | 128 | const serialized = serialize( 129 |
130 | 131 |
132 | ); 133 | const [deserialized] = await deserialize(serialized); 134 | const rendered = render(deserialized); 135 | const html = await new Response(rendered).text(); 136 | strictEqual(html, "
Hello, World!
"); 137 | }); 138 | 139 | it("should render multiple async components", async () => { 140 | const SayHello = async ({ 141 | name, 142 | timeout, 143 | }: { 144 | name: string; 145 | timeout: number; 146 | }) => { 147 | await new Promise((resolve) => setTimeout(resolve, timeout)); 148 | return
Hello, {name}!
; 149 | }; 150 | 151 | const serialized = serialize( 152 | <> 153 | 154 | 155 | 156 | ); 157 | const [deserialized] = await deserialize(serialized); 158 | const rendered = render(deserialized); 159 | const html = await new Response(rendered).text(); 160 | strictEqual(html, "
Hello, 1!
Hello, 2!
"); 161 | }); 162 | 163 | it("should render fallback", async () => { 164 | const SayHello: FunctionComponent<{ name: string }> = async ({ name }) => ( 165 |
Hello, {name}!
166 | ); 167 | SayHello.fallback = () =>
Loading...
; 168 | 169 | const serialized = serialize(); 170 | const [deserialized] = await deserialize(serialized); 171 | const rendered = render(deserialized); 172 | const html = await new Response(rendered).text(); 173 | strictEqual( 174 | html, 175 | `
Loading...
${fallbackRuntime}${islandRuntime}` 176 | ); 177 | }); 178 | 179 | it("should render multiple fallbacks", async () => { 180 | const SayHello: FunctionComponent<{ 181 | name: string; 182 | timeout: number; 183 | }> = async ({ name, timeout }) => { 184 | await new Promise((resolve) => setTimeout(resolve, timeout)); 185 | return
Hello, {name}!
; 186 | }; 187 | SayHello.fallback = ({ name }) =>
Loading {name}...
; 188 | 189 | const serialized = serialize( 190 | <> 191 | 192 | 193 | 194 | ); 195 | const [deserialized] = await deserialize(serialized); 196 | const rendered = render(deserialized); 197 | const html = await new Response(rendered).text(); 198 | strictEqual( 199 | html, 200 | `
Loading 1...
Loading 2...
${fallbackRuntime}${islandRuntime}` 201 | ); 202 | }); 203 | 204 | it("should render fallback caused by child", async () => { 205 | const Boundary: FunctionComponent = ({ children }) => { 206 | return children; 207 | }; 208 | Boundary.fallback = () =>
Loading...
; 209 | 210 | const SayHello: FunctionComponent<{ name: string }> = async ({ name }) => ( 211 |
Hello, {name}!
212 | ); 213 | 214 | const serialized = serialize( 215 | 216 | 217 | 218 | ); 219 | const [deserialized] = await deserialize(serialized); 220 | const rendered = render(deserialized); 221 | const html = await new Response(rendered).text(); 222 | strictEqual( 223 | html, 224 | `
Loading...
${fallbackRuntime}${islandRuntime}` 225 | ); 226 | }); 227 | 228 | it("should render fallback caused by descendant", async () => { 229 | const Boundary: FunctionComponent = ({ children }) => { 230 | return ; 231 | }; 232 | Boundary.fallback = () =>
Loading...
; 233 | 234 | const SayHello: FunctionComponent<{ name: string }> = async ({ name }) => ( 235 |
Hello, {name}!
236 | ); 237 | 238 | const serialized = serialize(); 239 | const [deserialized] = await deserialize(serialized); 240 | const rendered = render(deserialized); 241 | const html = await new Response(rendered).text(); 242 | strictEqual( 243 | html, 244 | `
Loading...
${fallbackRuntime}${islandRuntime}` 245 | ); 246 | }); 247 | 248 | it("works with createElement", async () => { 249 | const SayHello: FunctionComponent<{ 250 | name: string; 251 | timeout: number; 252 | }> = async ({ name, timeout }) => { 253 | await new Promise((resolve) => setTimeout(resolve, timeout)); 254 | return createElement("div", undefined, "Hello, ", name, "!"); 255 | }; 256 | SayHello.fallback = ({ name }) => 257 | createElement("div", undefined, ["Loading ", name, "..."]); 258 | 259 | const serialized = serialize([ 260 | createElement(SayHello, { name: "1", timeout: 10 }), 261 | createElement(SayHello, { name: "2", timeout: 5 }), 262 | ]); 263 | const [deserialized] = await deserialize(serialized); 264 | const rendered = render(deserialized); 265 | const html = await new Response(rendered).text(); 266 | strictEqual( 267 | html, 268 | `
Loading 1...
Loading 2...
${fallbackRuntime}${islandRuntime}` 269 | ); 270 | }); 271 | 272 | it("should render client component", async () => { 273 | const SayHelloClient = { 274 | $$typeof: CLIENT_SYMBOL, 275 | $$id: "say-hello", 276 | } as ClientComponent<{ name: string }>; 277 | const serialized = serialize( 278 |
279 | 280 |
281 | ); 282 | const [deserialized] = await deserialize(serialized, async (id) => { 283 | if (id === "say-hello") { 284 | return async ({ name }: { name: string }) => `Hello, ${name}!`; 285 | } 286 | throw new Error("Unknown client component '" + id + "'"); 287 | }); 288 | const rendered = render(deserialized); 289 | const html = await new Response(rendered).text(); 290 | strictEqual(html, "
Hello, World!
"); 291 | }); 292 | 293 | it("should render multiple client component instances", async () => { 294 | const SayHelloClient = { 295 | $$typeof: CLIENT_SYMBOL, 296 | $$id: "say-hello", 297 | } as ClientComponent<{ name: string }>; 298 | const serialized = serialize( 299 | <> 300 | 301 | 302 | 303 | ); 304 | const [deserialized] = await deserialize(serialized, async (id) => { 305 | if (id === "say-hello") { 306 | return async ({ name }: { name: string }) =>
Hello, {name}!
; 307 | } 308 | throw new Error("Unknown client component '" + id + "'"); 309 | }); 310 | const rendered = render(deserialized); 311 | const html = await new Response(rendered).text(); 312 | strictEqual(html, "
Hello, Foo!
Hello, Bar!
"); 313 | }); 314 | }); 315 | -------------------------------------------------------------------------------- /packages/joe-dom/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": ["src/**/*"], 3 | "references": [{ "path": "./tsconfig.test.json" }], 4 | "compilerOptions": { 5 | "module": "ES2022", 6 | "target": "ES2022", 7 | "moduleResolution": "node16", 8 | "outDir": "./dist", 9 | "declaration": true, 10 | "rootDir": "." 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /packages/joe-dom/tsconfig.test.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": ["src/**/*", "tests/**/*"], 3 | "exclude": ["tests/dist/**/*"], 4 | "compilerOptions": { 5 | "composite": true, 6 | "module": "ES2022", 7 | "target": "ES2022", 8 | "moduleResolution": "node16", 9 | "jsx": "react-jsx", 10 | "jsxImportSource": "joe-dom", 11 | "rootDir": ".", 12 | "outDir": "./dist" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@babel/runtime@^7.21.0": 6 | version "7.22.5" 7 | resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.22.5.tgz#8564dd588182ce0047d55d7a75e93921107b57ec" 8 | integrity sha512-ecjvYlnAaZ/KVneE/OdKYBYfgXV3Ptu6zQWmgEF7vwKhQnvVS6bjMD2XYgj+SNvQ1GfK/pjgokfPkC/2CO8CuA== 9 | dependencies: 10 | regenerator-runtime "^0.13.11" 11 | 12 | "@esbuild-kit/cjs-loader@^2.4.2": 13 | version "2.4.2" 14 | resolved "https://registry.yarnpkg.com/@esbuild-kit/cjs-loader/-/cjs-loader-2.4.2.tgz#cb4dde00fbf744a68c4f20162ea15a8242d0fa54" 15 | integrity sha512-BDXFbYOJzT/NBEtp71cvsrGPwGAMGRB/349rwKuoxNSiKjPraNNnlK6MIIabViCjqZugu6j+xeMDlEkWdHHJSg== 16 | dependencies: 17 | "@esbuild-kit/core-utils" "^3.0.0" 18 | get-tsconfig "^4.4.0" 19 | 20 | "@esbuild-kit/core-utils@^3.0.0": 21 | version "3.1.0" 22 | resolved "https://registry.yarnpkg.com/@esbuild-kit/core-utils/-/core-utils-3.1.0.tgz#49945d533dbd5e1b7620aa0fc522c15e6ec089c5" 23 | integrity sha512-Uuk8RpCg/7fdHSceR1M6XbSZFSuMrxcePFuGgyvsBn+u339dk5OeL4jv2EojwTN2st/unJGsVm4qHWjWNmJ/tw== 24 | dependencies: 25 | esbuild "~0.17.6" 26 | source-map-support "^0.5.21" 27 | 28 | "@esbuild-kit/esm-loader@^2.5.5": 29 | version "2.5.5" 30 | resolved "https://registry.yarnpkg.com/@esbuild-kit/esm-loader/-/esm-loader-2.5.5.tgz#b82da14fcee3fc1d219869756c06f43f67d1ca71" 31 | integrity sha512-Qwfvj/qoPbClxCRNuac1Du01r9gvNOT+pMYtJDapfB1eoGN1YlJ1BixLyL9WVENRx5RXgNLdfYdx/CuswlGhMw== 32 | dependencies: 33 | "@esbuild-kit/core-utils" "^3.0.0" 34 | get-tsconfig "^4.4.0" 35 | 36 | "@esbuild/android-arm64@0.17.19": 37 | version "0.17.19" 38 | resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.17.19.tgz#bafb75234a5d3d1b690e7c2956a599345e84a2fd" 39 | integrity sha512-KBMWvEZooR7+kzY0BtbTQn0OAYY7CsiydT63pVEaPtVYF0hXbUaOyZog37DKxK7NF3XacBJOpYT4adIJh+avxA== 40 | 41 | "@esbuild/android-arm64@0.18.4": 42 | version "0.18.4" 43 | resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.18.4.tgz#9c4f95559cff6fac4b0957fb45e32b442706ba42" 44 | integrity sha512-yQVgO+V307hA2XhzELQ6F91CBGX7gSnlVGAj5YIqjQOxThDpM7fOcHT2YLJbE6gNdPtgRSafQrsK8rJ9xHCaZg== 45 | 46 | "@esbuild/android-arm@0.17.19": 47 | version "0.17.19" 48 | resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.17.19.tgz#5898f7832c2298bc7d0ab53701c57beb74d78b4d" 49 | integrity sha512-rIKddzqhmav7MSmoFCmDIb6e2W57geRsM94gV2l38fzhXMwq7hZoClug9USI2pFRGL06f4IOPHHpFNOkWieR8A== 50 | 51 | "@esbuild/android-arm@0.18.4": 52 | version "0.18.4" 53 | resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.18.4.tgz#b8173173fa779b807e41146328f36324bf4513c1" 54 | integrity sha512-yKmQC9IiuvHdsNEbPHSprnMHg6OhL1cSeQZLzPpgzJBJ9ppEg9GAZN8MKj1TcmB4tZZUrq5xjK7KCmhwZP8iDA== 55 | 56 | "@esbuild/android-x64@0.17.19": 57 | version "0.17.19" 58 | resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.17.19.tgz#658368ef92067866d95fb268719f98f363d13ae1" 59 | integrity sha512-uUTTc4xGNDT7YSArp/zbtmbhO0uEEK9/ETW29Wk1thYUJBz3IVnvgEiEwEa9IeLyvnpKrWK64Utw2bgUmDveww== 60 | 61 | "@esbuild/android-x64@0.18.4": 62 | version "0.18.4" 63 | resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.18.4.tgz#2f79c625c4524a4310b1c96038dba7e3245789d6" 64 | integrity sha512-yLKXMxQg6sk1ntftxQ5uwyVgG4/S2E7UoOCc5N4YZW7fdkfRiYEXqm7CMuIfY2Vs3FTrNyKmSfNevIuIvJnMww== 65 | 66 | "@esbuild/darwin-arm64@0.17.19": 67 | version "0.17.19" 68 | resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.17.19.tgz#584c34c5991b95d4d48d333300b1a4e2ff7be276" 69 | integrity sha512-80wEoCfF/hFKM6WE1FyBHc9SfUblloAWx6FJkFWTWiCoht9Mc0ARGEM47e67W9rI09YoUxJL68WHfDRYEAvOhg== 70 | 71 | "@esbuild/darwin-arm64@0.18.4": 72 | version "0.18.4" 73 | resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.18.4.tgz#2f1a73decc212987ad9d97b6c2638be66bd586ad" 74 | integrity sha512-MVPEoZjZpk2xQ1zckZrb8eQuQib+QCzdmMs3YZAYEQPg+Rztk5pUxGyk8htZOC8Z38NMM29W+MqY9Sqo/sDGKw== 75 | 76 | "@esbuild/darwin-x64@0.17.19": 77 | version "0.17.19" 78 | resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.17.19.tgz#7751d236dfe6ce136cce343dce69f52d76b7f6cb" 79 | integrity sha512-IJM4JJsLhRYr9xdtLytPLSH9k/oxR3boaUIYiHkAawtwNOXKE8KoU8tMvryogdcT8AU+Bflmh81Xn6Q0vTZbQw== 80 | 81 | "@esbuild/darwin-x64@0.18.4": 82 | version "0.18.4" 83 | resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.18.4.tgz#a0a3b2270ba201331e8056d7c896598d8a96a12f" 84 | integrity sha512-uEsRtYRUDsz7i2tXg/t/SyF+5gU1cvi9B6B8i5ebJgtUUHJYWyIPIesmIOL4/+bywjxsDMA/XrNFMgMffLnh5A== 85 | 86 | "@esbuild/freebsd-arm64@0.17.19": 87 | version "0.17.19" 88 | resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.19.tgz#cacd171665dd1d500f45c167d50c6b7e539d5fd2" 89 | integrity sha512-pBwbc7DufluUeGdjSU5Si+P3SoMF5DQ/F/UmTSb8HXO80ZEAJmrykPyzo1IfNbAoaqw48YRpv8shwd1NoI0jcQ== 90 | 91 | "@esbuild/freebsd-arm64@0.18.4": 92 | version "0.18.4" 93 | resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.4.tgz#7966b77bfad31af17e82e21ecaf06e1392dcd3f3" 94 | integrity sha512-I8EOigqWnOHRin6Zp5Y1cfH3oT54bd7Sdz/VnpUNksbOtfp8IWRTH4pgkgO5jWaRQPjCpJcOpdRjYAMjPt8wXg== 95 | 96 | "@esbuild/freebsd-x64@0.17.19": 97 | version "0.17.19" 98 | resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.17.19.tgz#0769456eee2a08b8d925d7c00b79e861cb3162e4" 99 | integrity sha512-4lu+n8Wk0XlajEhbEffdy2xy53dpR06SlzvhGByyg36qJw6Kpfk7cp45DR/62aPH9mtJRmIyrXAS5UWBrJT6TQ== 100 | 101 | "@esbuild/freebsd-x64@0.18.4": 102 | version "0.18.4" 103 | resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.18.4.tgz#7c942bc3ca10ed140764a58dcc04e60e5bdca11a" 104 | integrity sha512-1bHfgMz/cNMjbpsYxjVgMJ1iwKq+NdDPlACBrWULD7ZdFmBQrhMicMaKb5CdmdVyvIwXmasOuF4r6Iq574kUTA== 105 | 106 | "@esbuild/linux-arm64@0.17.19": 107 | version "0.17.19" 108 | resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.17.19.tgz#38e162ecb723862c6be1c27d6389f48960b68edb" 109 | integrity sha512-ct1Tg3WGwd3P+oZYqic+YZF4snNl2bsnMKRkb3ozHmnM0dGWuxcPTTntAF6bOP0Sp4x0PjSF+4uHQ1xvxfRKqg== 110 | 111 | "@esbuild/linux-arm64@0.18.4": 112 | version "0.18.4" 113 | resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.18.4.tgz#5d9802d13fc33cc43efc647a56583525e6d40464" 114 | integrity sha512-J42vLHaYREyiBwH0eQE4/7H1DTfZx8FuxyWSictx4d7ezzuKE3XOkIvOg+SQzRz7T9HLVKzq2tvbAov4UfufBw== 115 | 116 | "@esbuild/linux-arm@0.17.19": 117 | version "0.17.19" 118 | resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.17.19.tgz#1a2cd399c50040184a805174a6d89097d9d1559a" 119 | integrity sha512-cdmT3KxjlOQ/gZ2cjfrQOtmhG4HJs6hhvm3mWSRDPtZ/lP5oe8FWceS10JaSJC13GBd4eH/haHnqf7hhGNLerA== 120 | 121 | "@esbuild/linux-arm@0.18.4": 122 | version "0.18.4" 123 | resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.18.4.tgz#7eb1af7227506dd7cb01ef4a400c53f52ea1c4f9" 124 | integrity sha512-4XCGqM/Ay1LCXUBH59bL4JbSbbTK1K22dWHymWMGaEh2sQCDOUw+OQxozYV/YdBb91leK2NbuSrE2BRamwgaYw== 125 | 126 | "@esbuild/linux-ia32@0.17.19": 127 | version "0.17.19" 128 | resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.17.19.tgz#e28c25266b036ce1cabca3c30155222841dc035a" 129 | integrity sha512-w4IRhSy1VbsNxHRQpeGCHEmibqdTUx61Vc38APcsRbuVgK0OPEnQ0YD39Brymn96mOx48Y2laBQGqgZ0j9w6SQ== 130 | 131 | "@esbuild/linux-ia32@0.18.4": 132 | version "0.18.4" 133 | resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.18.4.tgz#9d22fa5bb59d7dfbff7d981d933b434585d96dae" 134 | integrity sha512-4ksIqFwhq7OExty7Sl1n0vqQSCqTG4sU6i99G2yuMr28CEOUZ/60N+IO9hwI8sIxBqmKmDgncE1n5CMu/3m0IA== 135 | 136 | "@esbuild/linux-loong64@0.17.19": 137 | version "0.17.19" 138 | resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.17.19.tgz#0f887b8bb3f90658d1a0117283e55dbd4c9dcf72" 139 | integrity sha512-2iAngUbBPMq439a+z//gE+9WBldoMp1s5GWsUSgqHLzLJ9WoZLZhpwWuym0u0u/4XmZ3gpHmzV84PonE+9IIdQ== 140 | 141 | "@esbuild/linux-loong64@0.18.4": 142 | version "0.18.4" 143 | resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.18.4.tgz#659f91aae2abdc93ace39bc4f8e965f2a7dbf6aa" 144 | integrity sha512-bsWtoVHkGQgAsFXioDueXRiUIfSGrVkJjBBz4gcBJxXcD461cWFQFyu8Fxdj9TP+zEeqJ8C/O4LFFMBNi6Fscw== 145 | 146 | "@esbuild/linux-mips64el@0.17.19": 147 | version "0.17.19" 148 | resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.17.19.tgz#f5d2a0b8047ea9a5d9f592a178ea054053a70289" 149 | integrity sha512-LKJltc4LVdMKHsrFe4MGNPp0hqDFA1Wpt3jE1gEyM3nKUvOiO//9PheZZHfYRfYl6AwdTH4aTcXSqBerX0ml4A== 150 | 151 | "@esbuild/linux-mips64el@0.18.4": 152 | version "0.18.4" 153 | resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.18.4.tgz#f57cef70de4147df9efb761ff0056509d8d1ba87" 154 | integrity sha512-LRD9Fu8wJQgIOOV1o3nRyzrheFYjxA0C1IVWZ93eNRRWBKgarYFejd5WBtrp43cE4y4D4t3qWWyklm73Mrsd/g== 155 | 156 | "@esbuild/linux-ppc64@0.17.19": 157 | version "0.17.19" 158 | resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.17.19.tgz#876590e3acbd9fa7f57a2c7d86f83717dbbac8c7" 159 | integrity sha512-/c/DGybs95WXNS8y3Ti/ytqETiW7EU44MEKuCAcpPto3YjQbyK3IQVKfF6nbghD7EcLUGl0NbiL5Rt5DMhn5tg== 160 | 161 | "@esbuild/linux-ppc64@0.18.4": 162 | version "0.18.4" 163 | resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.18.4.tgz#7654e479378e4e9ec6ac96cabb471a6c1c819b42" 164 | integrity sha512-jtQgoZjM92gauVRxNaaG/TpL3Pr4WcL3Pwqi9QgdrBGrEXzB+twohQiWNSTycs6lUygakos4mm2h0B9/SHveng== 165 | 166 | "@esbuild/linux-riscv64@0.17.19": 167 | version "0.17.19" 168 | resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.17.19.tgz#7f49373df463cd9f41dc34f9b2262d771688bf09" 169 | integrity sha512-FC3nUAWhvFoutlhAkgHf8f5HwFWUL6bYdvLc/TTuxKlvLi3+pPzdZiFKSWz/PF30TB1K19SuCxDTI5KcqASJqA== 170 | 171 | "@esbuild/linux-riscv64@0.18.4": 172 | version "0.18.4" 173 | resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.18.4.tgz#eb762cae575bb070627415921ca43e5f7e3ee3a1" 174 | integrity sha512-7WaU/kRZG0VCV09Xdlkg6LNAsfU9SAxo6XEdaZ8ffO4lh+DZoAhGTx7+vTMOXKxa+r2w1LYDGxfJa2rcgagMRA== 175 | 176 | "@esbuild/linux-s390x@0.17.19": 177 | version "0.17.19" 178 | resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.17.19.tgz#e2afd1afcaf63afe2c7d9ceacd28ec57c77f8829" 179 | integrity sha512-IbFsFbxMWLuKEbH+7sTkKzL6NJmG2vRyy6K7JJo55w+8xDk7RElYn6xvXtDW8HCfoKBFK69f3pgBJSUSQPr+4Q== 180 | 181 | "@esbuild/linux-s390x@0.18.4": 182 | version "0.18.4" 183 | resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.18.4.tgz#d7d47a6cde5536e97b698d5e913f3e04662ff3da" 184 | integrity sha512-D19ed0xreKQvC5t+ArE2njSnm18WPpE+1fhwaiJHf+Xwqsq+/SUaV8Mx0M27nszdU+Atq1HahrgCOZCNNEASUg== 185 | 186 | "@esbuild/linux-x64@0.17.19": 187 | version "0.17.19" 188 | resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.17.19.tgz#8a0e9738b1635f0c53389e515ae83826dec22aa4" 189 | integrity sha512-68ngA9lg2H6zkZcyp22tsVt38mlhWde8l3eJLWkyLrp4HwMUr3c1s/M2t7+kHIhvMjglIBrFpncX1SzMckomGw== 190 | 191 | "@esbuild/linux-x64@0.18.4": 192 | version "0.18.4" 193 | resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.18.4.tgz#bcdc75f060fd1dd02f6fbd8183caa8362d6b3ab4" 194 | integrity sha512-Rx3AY1sxyiO/gvCGP00nL69L60dfmWyjKWY06ugpB8Ydpdsfi3BHW58HWC24K3CAjAPSwxcajozC2PzA9JBS1g== 195 | 196 | "@esbuild/netbsd-x64@0.17.19": 197 | version "0.17.19" 198 | resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.17.19.tgz#c29fb2453c6b7ddef9a35e2c18b37bda1ae5c462" 199 | integrity sha512-CwFq42rXCR8TYIjIfpXCbRX0rp1jo6cPIUPSaWwzbVI4aOfX96OXY8M6KNmtPcg7QjYeDmN+DD0Wp3LaBOLf4Q== 200 | 201 | "@esbuild/netbsd-x64@0.18.4": 202 | version "0.18.4" 203 | resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.18.4.tgz#fc511ecd4b46b1b38410f635dd3e0db500a8b325" 204 | integrity sha512-AaShPmN9c6w1mKRpliKFlaWcSkpBT4KOlk93UfFgeI3F3cbjzdDKGsbKnOZozmYbE1izZKLmNJiW0sFM+A5JPA== 205 | 206 | "@esbuild/openbsd-x64@0.17.19": 207 | version "0.17.19" 208 | resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.17.19.tgz#95e75a391403cb10297280d524d66ce04c920691" 209 | integrity sha512-cnq5brJYrSZ2CF6c35eCmviIN3k3RczmHz8eYaVlNasVqsNY+JKohZU5MKmaOI+KkllCdzOKKdPs762VCPC20g== 210 | 211 | "@esbuild/openbsd-x64@0.18.4": 212 | version "0.18.4" 213 | resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.18.4.tgz#b6db15ec5dfa6ac4b0088cd38ec5ceb8a57f48d4" 214 | integrity sha512-tRGvGwou3BrvHVvF8HxTqEiC5VtPzySudS9fh2jBIKpLX7HCW8jIkW+LunkFDNwhslx4xMAgh0jAHsx/iCymaQ== 215 | 216 | "@esbuild/sunos-x64@0.17.19": 217 | version "0.17.19" 218 | resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.17.19.tgz#722eaf057b83c2575937d3ffe5aeb16540da7273" 219 | integrity sha512-vCRT7yP3zX+bKWFeP/zdS6SqdWB8OIpaRq/mbXQxTGHnIxspRtigpkUcDMlSCOejlHowLqII7K2JKevwyRP2rg== 220 | 221 | "@esbuild/sunos-x64@0.18.4": 222 | version "0.18.4" 223 | resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.18.4.tgz#f0aa5f8c3929a49e721faca4e7491865324a6bb5" 224 | integrity sha512-acORFDI95GKhmAnlH8EarBeuqoy/j3yxIU+FDB91H3+ZON+8HhTadtT450YkaMzX6lEWbhi+mjVUCj00M5yyOQ== 225 | 226 | "@esbuild/win32-arm64@0.17.19": 227 | version "0.17.19" 228 | resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.17.19.tgz#9aa9dc074399288bdcdd283443e9aeb6b9552b6f" 229 | integrity sha512-yYx+8jwowUstVdorcMdNlzklLYhPxjniHWFKgRqH7IFlUEa0Umu3KuYplf1HUZZ422e3NU9F4LGb+4O0Kdcaag== 230 | 231 | "@esbuild/win32-arm64@0.18.4": 232 | version "0.18.4" 233 | resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.18.4.tgz#6e0518345d702012e68d9cdbbcf897367764eb9e" 234 | integrity sha512-1NxP+iOk8KSvS1L9SSxEvBAJk39U0GiGZkiiJGbuDF9G4fG7DSDw6XLxZMecAgmvQrwwx7yVKdNN3GgNh0UfKg== 235 | 236 | "@esbuild/win32-ia32@0.17.19": 237 | version "0.17.19" 238 | resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.17.19.tgz#95ad43c62ad62485e210f6299c7b2571e48d2b03" 239 | integrity sha512-eggDKanJszUtCdlVs0RB+h35wNlb5v4TWEkq4vZcmVt5u/HiDZrTXe2bWFQUez3RgNHwx/x4sk5++4NSSicKkw== 240 | 241 | "@esbuild/win32-ia32@0.18.4": 242 | version "0.18.4" 243 | resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.18.4.tgz#ddbc327a08b75280cbceb80ff6f29ab4035c9bad" 244 | integrity sha512-OKr8jze93vbgqZ/r23woWciTixUwLa976C9W7yNBujtnVHyvsL/ocYG61tsktUfJOpyIz5TsohkBZ6Lo2+PCcQ== 245 | 246 | "@esbuild/win32-x64@0.17.19": 247 | version "0.17.19" 248 | resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.17.19.tgz#8cfaf2ff603e9aabb910e9c0558c26cf32744061" 249 | integrity sha512-lAhycmKnVOuRYNtRtatQR1LPQf2oYCkRGkSFnseDAKPl8lu5SOsK/e1sXe5a0Pc5kHIHe6P2I/ilntNv2xf3cA== 250 | 251 | "@esbuild/win32-x64@0.18.4": 252 | version "0.18.4" 253 | resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.18.4.tgz#2562ce6dfd48c15a80b8daa2e38cce5b50573624" 254 | integrity sha512-qJr3wVvcLjPFcV4AMDS3iquhBfTef2zo/jlm8RMxmiRp3Vy2HY8WMxrykJlcbCnqLXZPA0YZxZGND6eug85ogg== 255 | 256 | "@isaacs/cliui@^8.0.2": 257 | version "8.0.2" 258 | resolved "https://registry.yarnpkg.com/@isaacs/cliui/-/cliui-8.0.2.tgz#b37667b7bc181c168782259bab42474fbf52b550" 259 | integrity sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA== 260 | dependencies: 261 | string-width "^5.1.2" 262 | string-width-cjs "npm:string-width@^4.2.0" 263 | strip-ansi "^7.0.1" 264 | strip-ansi-cjs "npm:strip-ansi@^6.0.1" 265 | wrap-ansi "^8.1.0" 266 | wrap-ansi-cjs "npm:wrap-ansi@^7.0.0" 267 | 268 | "@nodelib/fs.scandir@2.1.5": 269 | version "2.1.5" 270 | resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" 271 | integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== 272 | dependencies: 273 | "@nodelib/fs.stat" "2.0.5" 274 | run-parallel "^1.1.9" 275 | 276 | "@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": 277 | version "2.0.5" 278 | resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" 279 | integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== 280 | 281 | "@nodelib/fs.walk@^1.2.3": 282 | version "1.2.8" 283 | resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" 284 | integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== 285 | dependencies: 286 | "@nodelib/fs.scandir" "2.1.5" 287 | fastq "^1.6.0" 288 | 289 | "@nrwl/nx-cloud@16.0.5": 290 | version "16.0.5" 291 | resolved "https://registry.yarnpkg.com/@nrwl/nx-cloud/-/nx-cloud-16.0.5.tgz#c963480a71c4afa964fbbe9e4d6bbf222764e9cd" 292 | integrity sha512-1p82ym8WE9ziejwgPslstn19iV/VkHfHfKr/5YOnfCHQS+NxUf92ogcYhHXtqWLblVZ9Zs4W4pkSXK4e04wCmQ== 293 | dependencies: 294 | nx-cloud "16.0.5" 295 | 296 | "@nrwl/tao@16.3.2": 297 | version "16.3.2" 298 | resolved "https://registry.yarnpkg.com/@nrwl/tao/-/tao-16.3.2.tgz#eefc1974342afbbe48e4e5351d6707ad2f9fb179" 299 | integrity sha512-2Kg7dtv6JcQagCZPSq+okceI81NqmXGGgbKWqS7sOfdmp1otxS9uiUFNXw+Pdtnw38mdRviMtSOXScntu4sUKg== 300 | dependencies: 301 | nx "16.3.2" 302 | 303 | "@nx/nx-darwin-arm64@16.3.2": 304 | version "16.3.2" 305 | resolved "https://registry.yarnpkg.com/@nx/nx-darwin-arm64/-/nx-darwin-arm64-16.3.2.tgz#83b6e78b27d2d7da8f7626560f52070c8735d28a" 306 | integrity sha512-YfYVNfsJBzBcBnJUU4AcA6A4QMkgnVlETfp4KGL36Otq542mRY1ISGHdox63ocI5AKh5gay5AaGcR4wR9PU9Vg== 307 | 308 | "@nx/nx-darwin-x64@16.3.2": 309 | version "16.3.2" 310 | resolved "https://registry.yarnpkg.com/@nx/nx-darwin-x64/-/nx-darwin-x64-16.3.2.tgz#0ae2a64356542c5fb73ca8038ce10ec4512e7fcb" 311 | integrity sha512-bJtpozz0zSRVRrcQ76GrlT3TWEGTymLYWrVG51bH5KZ46t6/a4EQBI3uL3vubMmOZ0jR4ywybOcPBBhxmBJ68w== 312 | 313 | "@nx/nx-freebsd-x64@16.3.2": 314 | version "16.3.2" 315 | resolved "https://registry.yarnpkg.com/@nx/nx-freebsd-x64/-/nx-freebsd-x64-16.3.2.tgz#202adf4d6070f47ed46450f006ecd50851147c74" 316 | integrity sha512-ZvufI0bWqT67nLbBo6ejrIGxypdoedRQTP/tudWbs/4isvxLe1uVku1BfKCTQUsJG367SqNOU1H5kzI/MRr3ow== 317 | 318 | "@nx/nx-linux-arm-gnueabihf@16.3.2": 319 | version "16.3.2" 320 | resolved "https://registry.yarnpkg.com/@nx/nx-linux-arm-gnueabihf/-/nx-linux-arm-gnueabihf-16.3.2.tgz#62314a82566e3647866b9dd4167a2d0e1397f001" 321 | integrity sha512-IQL4kxdiZLvifar7+SIum3glRuVsxtE0dL8RvteSDXrxDQnaTUrjILC+VGhalRmk7ngBbGKNrhWOeeL7390CzQ== 322 | 323 | "@nx/nx-linux-arm64-gnu@16.3.2": 324 | version "16.3.2" 325 | resolved "https://registry.yarnpkg.com/@nx/nx-linux-arm64-gnu/-/nx-linux-arm64-gnu-16.3.2.tgz#02826400aa55b8f44bac83332dd29647d0e95001" 326 | integrity sha512-f6AWgPVu3mfUEoOBa0rY2/7QY0Or9eR0KtLFpcPh7RUpxPw2EXzIbjD/0RGipdpspSrgiMKbZpsUjo6mXBFsQA== 327 | 328 | "@nx/nx-linux-arm64-musl@16.3.2": 329 | version "16.3.2" 330 | resolved "https://registry.yarnpkg.com/@nx/nx-linux-arm64-musl/-/nx-linux-arm64-musl-16.3.2.tgz#a0a81520e0904aa026a7ab0a8a3bf3facec9f14c" 331 | integrity sha512-AvrWcYz7021E3b5P9/0i26p60XMZfw86Epks51L6AhlflarlOH4AcEChc7APMtb1ELAIbDWx2S6oIDRbQ7rtVA== 332 | 333 | "@nx/nx-linux-x64-gnu@16.3.2": 334 | version "16.3.2" 335 | resolved "https://registry.yarnpkg.com/@nx/nx-linux-x64-gnu/-/nx-linux-x64-gnu-16.3.2.tgz#e79b5c142ec8d9bfb458ea5803bc4b62abbcf296" 336 | integrity sha512-K2pWGAcbCNm6b7UZI9cc8z4Rb540QcuepBXD7akjPjWerzXriT6VCn4i9mVKsCg2mwSfknTJJVJ1PZwJSmTl/Q== 337 | 338 | "@nx/nx-linux-x64-musl@16.3.2": 339 | version "16.3.2" 340 | resolved "https://registry.yarnpkg.com/@nx/nx-linux-x64-musl/-/nx-linux-x64-musl-16.3.2.tgz#900aee8f171638b9fb44378e2ac0548cb4aa99a7" 341 | integrity sha512-sY1QDuQlqyYiRPJZanrtV07tU0DOXiCrWb0pDsGiO0qHuUSmW5Vw17GWEY4z3rt0/5U8fJ+/9WQrneviOmsOKg== 342 | 343 | "@nx/nx-win32-arm64-msvc@16.3.2": 344 | version "16.3.2" 345 | resolved "https://registry.yarnpkg.com/@nx/nx-win32-arm64-msvc/-/nx-win32-arm64-msvc-16.3.2.tgz#88db772b3535648e147b1a0206b1a1fe875fa9a5" 346 | integrity sha512-wBfohT2hjrLKn9WFHvG0MFVk7uYhgYNiptnTLdTouziHgFyZ08vyl7XYBq55BwHPMQ5iswVoEfjn/5ZBfCPscg== 347 | 348 | "@nx/nx-win32-x64-msvc@16.3.2": 349 | version "16.3.2" 350 | resolved "https://registry.yarnpkg.com/@nx/nx-win32-x64-msvc/-/nx-win32-x64-msvc-16.3.2.tgz#2195faaf1fc465c7a89bfdd62323fdd2a5d91f15" 351 | integrity sha512-QC0sWrfQm0/WdvvM//7UAgm+otbak6bznZ0zawTeqmLBh1hLjNeweyzSVKQEtZtlzDMKpzCVuuwkJq+VKBLvmw== 352 | 353 | "@parcel/watcher@2.0.4": 354 | version "2.0.4" 355 | resolved "https://registry.yarnpkg.com/@parcel/watcher/-/watcher-2.0.4.tgz#f300fef4cc38008ff4b8c29d92588eced3ce014b" 356 | integrity sha512-cTDi+FUDBIUOBKEtj+nhiJ71AZVlkAsQFuGQTun5tV9mwQBQgZvhCzG+URPQc8myeN32yRVZEfVAPCs1RW+Jvg== 357 | dependencies: 358 | node-addon-api "^3.2.1" 359 | node-gyp-build "^4.3.0" 360 | 361 | "@pkgjs/parseargs@^0.11.0": 362 | version "0.11.0" 363 | resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33" 364 | integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== 365 | 366 | "@types/node@20.3.1": 367 | version "20.3.1" 368 | resolved "https://registry.yarnpkg.com/@types/node/-/node-20.3.1.tgz#e8a83f1aa8b649377bb1fb5d7bac5cb90e784dfe" 369 | integrity sha512-EhcH/wvidPy1WeML3TtYFGR83UzjxeWRen9V402T8aUGYsCHOmfoisV3ZSg03gAFIbLq8TnWOJ0f4cALtnSEUg== 370 | 371 | "@yarnpkg/lockfile@^1.1.0": 372 | version "1.1.0" 373 | resolved "https://registry.yarnpkg.com/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz#e77a97fbd345b76d83245edcd17d393b1b41fb31" 374 | integrity sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ== 375 | 376 | "@yarnpkg/parsers@^3.0.0-rc.18": 377 | version "3.0.0-rc.45" 378 | resolved "https://registry.yarnpkg.com/@yarnpkg/parsers/-/parsers-3.0.0-rc.45.tgz#fcc7d0ab7828afdb20d1e13160b1d117c07536f4" 379 | integrity sha512-Aj0aHBV/crFQTpKQvL6k1xNiOhnlfVLu06LunelQAvl1MTeWrSi8LD9UJJDCFJiG4kx8NysUE6Tx0KZyPQUzIw== 380 | dependencies: 381 | js-yaml "^3.10.0" 382 | tslib "^2.4.0" 383 | 384 | "@zkochan/js-yaml@0.0.6": 385 | version "0.0.6" 386 | resolved "https://registry.yarnpkg.com/@zkochan/js-yaml/-/js-yaml-0.0.6.tgz#975f0b306e705e28b8068a07737fa46d3fc04826" 387 | integrity sha512-nzvgl3VfhcELQ8LyVrYOru+UtAy1nrygk2+AGbTm8a5YcO6o8lSjAT+pfg3vJWxIoZKOUhrK6UU7xW/+00kQrg== 388 | dependencies: 389 | argparse "^2.0.1" 390 | 391 | acorn-loose@8.3.0: 392 | version "8.3.0" 393 | resolved "https://registry.yarnpkg.com/acorn-loose/-/acorn-loose-8.3.0.tgz#0cd62461d21dce4f069785f8d3de136d5525029a" 394 | integrity sha512-75lAs9H19ldmW+fAbyqHdjgdCrz0pWGXKmnqFoh8PyVd1L2RIb4RzYrSjmopeqv3E1G3/Pimu6GgLlrGbrkF7w== 395 | dependencies: 396 | acorn "^8.5.0" 397 | 398 | acorn@^8.5.0: 399 | version "8.9.0" 400 | resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.9.0.tgz#78a16e3b2bcc198c10822786fa6679e245db5b59" 401 | integrity sha512-jaVNAFBHNLXspO543WnNNPZFRtavh3skAkITqD0/2aeMkKZTN+254PyhwxFYrk3vQ1xfY+2wbesJMs/JC8/PwQ== 402 | 403 | ansi-colors@^4.1.1: 404 | version "4.1.3" 405 | resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.3.tgz#37611340eb2243e70cc604cad35d63270d48781b" 406 | integrity sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw== 407 | 408 | ansi-regex@^5.0.1: 409 | version "5.0.1" 410 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" 411 | integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== 412 | 413 | ansi-regex@^6.0.1: 414 | version "6.0.1" 415 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.0.1.tgz#3183e38fae9a65d7cb5e53945cd5897d0260a06a" 416 | integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA== 417 | 418 | ansi-styles@^4.0.0, ansi-styles@^4.1.0: 419 | version "4.3.0" 420 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" 421 | integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== 422 | dependencies: 423 | color-convert "^2.0.1" 424 | 425 | ansi-styles@^6.1.0: 426 | version "6.2.1" 427 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.1.tgz#0e62320cf99c21afff3b3012192546aacbfb05c5" 428 | integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug== 429 | 430 | arg@5.0.2: 431 | version "5.0.2" 432 | resolved "https://registry.yarnpkg.com/arg/-/arg-5.0.2.tgz#c81433cc427c92c4dcf4865142dbca6f15acd59c" 433 | integrity sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg== 434 | 435 | argparse@^1.0.7: 436 | version "1.0.10" 437 | resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" 438 | integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== 439 | dependencies: 440 | sprintf-js "~1.0.2" 441 | 442 | argparse@^2.0.1: 443 | version "2.0.1" 444 | resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" 445 | integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== 446 | 447 | asynckit@^0.4.0: 448 | version "0.4.0" 449 | resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" 450 | integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== 451 | 452 | axios@1.1.3: 453 | version "1.1.3" 454 | resolved "https://registry.yarnpkg.com/axios/-/axios-1.1.3.tgz#8274250dada2edf53814ed7db644b9c2866c1e35" 455 | integrity sha512-00tXVRwKx/FZr/IDVFt4C+f9FYairX517WoGCL6dpOntqLkZofjhu43F/Xl44UOpqa+9sLFDrG/XAnFsUYgkDA== 456 | dependencies: 457 | follow-redirects "^1.15.0" 458 | form-data "^4.0.0" 459 | proxy-from-env "^1.1.0" 460 | 461 | axios@^1.0.0: 462 | version "1.4.0" 463 | resolved "https://registry.yarnpkg.com/axios/-/axios-1.4.0.tgz#38a7bf1224cd308de271146038b551d725f0be1f" 464 | integrity sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA== 465 | dependencies: 466 | follow-redirects "^1.15.0" 467 | form-data "^4.0.0" 468 | proxy-from-env "^1.1.0" 469 | 470 | balanced-match@^1.0.0: 471 | version "1.0.2" 472 | resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" 473 | integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== 474 | 475 | base64-js@^1.3.1: 476 | version "1.5.1" 477 | resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" 478 | integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== 479 | 480 | bl@^4.0.3: 481 | version "4.1.0" 482 | resolved "https://registry.yarnpkg.com/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a" 483 | integrity sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w== 484 | dependencies: 485 | buffer "^5.5.0" 486 | inherits "^2.0.4" 487 | readable-stream "^3.4.0" 488 | 489 | brace-expansion@^1.1.7: 490 | version "1.1.11" 491 | resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" 492 | integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== 493 | dependencies: 494 | balanced-match "^1.0.0" 495 | concat-map "0.0.1" 496 | 497 | brace-expansion@^2.0.1: 498 | version "2.0.1" 499 | resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" 500 | integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== 501 | dependencies: 502 | balanced-match "^1.0.0" 503 | 504 | braces@^3.0.2: 505 | version "3.0.2" 506 | resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" 507 | integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== 508 | dependencies: 509 | fill-range "^7.0.1" 510 | 511 | buffer-from@^1.0.0: 512 | version "1.1.2" 513 | resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" 514 | integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== 515 | 516 | buffer@^5.5.0: 517 | version "5.7.1" 518 | resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" 519 | integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== 520 | dependencies: 521 | base64-js "^1.3.1" 522 | ieee754 "^1.1.13" 523 | 524 | chalk@^4.1.0, chalk@^4.1.2: 525 | version "4.1.2" 526 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" 527 | integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== 528 | dependencies: 529 | ansi-styles "^4.1.0" 530 | supports-color "^7.1.0" 531 | 532 | chownr@^2.0.0: 533 | version "2.0.0" 534 | resolved "https://registry.yarnpkg.com/chownr/-/chownr-2.0.0.tgz#15bfbe53d2eab4cf70f18a8cd68ebe5b3cb1dece" 535 | integrity sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ== 536 | 537 | cli-cursor@3.1.0: 538 | version "3.1.0" 539 | resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307" 540 | integrity sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw== 541 | dependencies: 542 | restore-cursor "^3.1.0" 543 | 544 | cli-spinners@2.6.1: 545 | version "2.6.1" 546 | resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.6.1.tgz#adc954ebe281c37a6319bfa401e6dd2488ffb70d" 547 | integrity sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g== 548 | 549 | cliui@^7.0.2: 550 | version "7.0.4" 551 | resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" 552 | integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== 553 | dependencies: 554 | string-width "^4.2.0" 555 | strip-ansi "^6.0.0" 556 | wrap-ansi "^7.0.0" 557 | 558 | cliui@^8.0.1: 559 | version "8.0.1" 560 | resolved "https://registry.yarnpkg.com/cliui/-/cliui-8.0.1.tgz#0c04b075db02cbfe60dc8e6cf2f5486b1a3608aa" 561 | integrity sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ== 562 | dependencies: 563 | string-width "^4.2.0" 564 | strip-ansi "^6.0.1" 565 | wrap-ansi "^7.0.0" 566 | 567 | color-convert@^2.0.1: 568 | version "2.0.1" 569 | resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" 570 | integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== 571 | dependencies: 572 | color-name "~1.1.4" 573 | 574 | color-name@~1.1.4: 575 | version "1.1.4" 576 | resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" 577 | integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== 578 | 579 | combined-stream@^1.0.8: 580 | version "1.0.8" 581 | resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" 582 | integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== 583 | dependencies: 584 | delayed-stream "~1.0.0" 585 | 586 | concat-map@0.0.1: 587 | version "0.0.1" 588 | resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" 589 | integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== 590 | 591 | concurrently@8.2.0: 592 | version "8.2.0" 593 | resolved "https://registry.yarnpkg.com/concurrently/-/concurrently-8.2.0.tgz#cdc9f621a4d913366600355d68254df2c5e782f3" 594 | integrity sha512-nnLMxO2LU492mTUj9qX/az/lESonSZu81UznYDoXtz1IQf996ixVqPAgHXwvHiHCAef/7S8HIK+fTFK7Ifk8YA== 595 | dependencies: 596 | chalk "^4.1.2" 597 | date-fns "^2.30.0" 598 | lodash "^4.17.21" 599 | rxjs "^7.8.1" 600 | shell-quote "^1.8.1" 601 | spawn-command "0.0.2" 602 | supports-color "^8.1.1" 603 | tree-kill "^1.2.2" 604 | yargs "^17.7.2" 605 | 606 | cross-env@7.0.3: 607 | version "7.0.3" 608 | resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-7.0.3.tgz#865264b29677dc015ba8418918965dd232fc54cf" 609 | integrity sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw== 610 | dependencies: 611 | cross-spawn "^7.0.1" 612 | 613 | cross-spawn@^7.0.0, cross-spawn@^7.0.1: 614 | version "7.0.3" 615 | resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" 616 | integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== 617 | dependencies: 618 | path-key "^3.1.0" 619 | shebang-command "^2.0.0" 620 | which "^2.0.1" 621 | 622 | date-fns@^2.30.0: 623 | version "2.30.0" 624 | resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.30.0.tgz#f367e644839ff57894ec6ac480de40cae4b0f4d0" 625 | integrity sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw== 626 | dependencies: 627 | "@babel/runtime" "^7.21.0" 628 | 629 | define-lazy-prop@^2.0.0: 630 | version "2.0.0" 631 | resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz#3f7ae421129bcaaac9bc74905c98a0009ec9ee7f" 632 | integrity sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og== 633 | 634 | delayed-stream@~1.0.0: 635 | version "1.0.0" 636 | resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" 637 | integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== 638 | 639 | dotenv@~10.0.0: 640 | version "10.0.0" 641 | resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-10.0.0.tgz#3d4227b8fb95f81096cdd2b66653fb2c7085ba81" 642 | integrity sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q== 643 | 644 | duplexer@^0.1.1: 645 | version "0.1.2" 646 | resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.2.tgz#3abe43aef3835f8ae077d136ddce0f276b0400e6" 647 | integrity sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg== 648 | 649 | eastasianwidth@^0.2.0: 650 | version "0.2.0" 651 | resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" 652 | integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== 653 | 654 | emoji-regex@^8.0.0: 655 | version "8.0.0" 656 | resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" 657 | integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== 658 | 659 | emoji-regex@^9.2.2: 660 | version "9.2.2" 661 | resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" 662 | integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== 663 | 664 | end-of-stream@^1.4.1: 665 | version "1.4.4" 666 | resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" 667 | integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== 668 | dependencies: 669 | once "^1.4.0" 670 | 671 | enquirer@~2.3.6: 672 | version "2.3.6" 673 | resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d" 674 | integrity sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg== 675 | dependencies: 676 | ansi-colors "^4.1.1" 677 | 678 | esbuild@0.18.4: 679 | version "0.18.4" 680 | resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.18.4.tgz#8c047747baa0d8837a8aa8c84eed2ee8b06f43e4" 681 | integrity sha512-9rxWV/Cb2DMUXfe9aUsYtqg0KTlw146ElFH22kYeK9KVV1qT082X4lpmiKsa12ePiCcIcB686TQJxaGAa9TFvA== 682 | optionalDependencies: 683 | "@esbuild/android-arm" "0.18.4" 684 | "@esbuild/android-arm64" "0.18.4" 685 | "@esbuild/android-x64" "0.18.4" 686 | "@esbuild/darwin-arm64" "0.18.4" 687 | "@esbuild/darwin-x64" "0.18.4" 688 | "@esbuild/freebsd-arm64" "0.18.4" 689 | "@esbuild/freebsd-x64" "0.18.4" 690 | "@esbuild/linux-arm" "0.18.4" 691 | "@esbuild/linux-arm64" "0.18.4" 692 | "@esbuild/linux-ia32" "0.18.4" 693 | "@esbuild/linux-loong64" "0.18.4" 694 | "@esbuild/linux-mips64el" "0.18.4" 695 | "@esbuild/linux-ppc64" "0.18.4" 696 | "@esbuild/linux-riscv64" "0.18.4" 697 | "@esbuild/linux-s390x" "0.18.4" 698 | "@esbuild/linux-x64" "0.18.4" 699 | "@esbuild/netbsd-x64" "0.18.4" 700 | "@esbuild/openbsd-x64" "0.18.4" 701 | "@esbuild/sunos-x64" "0.18.4" 702 | "@esbuild/win32-arm64" "0.18.4" 703 | "@esbuild/win32-ia32" "0.18.4" 704 | "@esbuild/win32-x64" "0.18.4" 705 | 706 | esbuild@~0.17.6: 707 | version "0.17.19" 708 | resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.17.19.tgz#087a727e98299f0462a3d0bcdd9cd7ff100bd955" 709 | integrity sha512-XQ0jAPFkK/u3LcVRcvVHQcTIqD6E2H1fvZMA5dQPSOWb3suUbWbfbRf94pjc0bNzRYLfIrDRQXr7X+LHIm5oHw== 710 | optionalDependencies: 711 | "@esbuild/android-arm" "0.17.19" 712 | "@esbuild/android-arm64" "0.17.19" 713 | "@esbuild/android-x64" "0.17.19" 714 | "@esbuild/darwin-arm64" "0.17.19" 715 | "@esbuild/darwin-x64" "0.17.19" 716 | "@esbuild/freebsd-arm64" "0.17.19" 717 | "@esbuild/freebsd-x64" "0.17.19" 718 | "@esbuild/linux-arm" "0.17.19" 719 | "@esbuild/linux-arm64" "0.17.19" 720 | "@esbuild/linux-ia32" "0.17.19" 721 | "@esbuild/linux-loong64" "0.17.19" 722 | "@esbuild/linux-mips64el" "0.17.19" 723 | "@esbuild/linux-ppc64" "0.17.19" 724 | "@esbuild/linux-riscv64" "0.17.19" 725 | "@esbuild/linux-s390x" "0.17.19" 726 | "@esbuild/linux-x64" "0.17.19" 727 | "@esbuild/netbsd-x64" "0.17.19" 728 | "@esbuild/openbsd-x64" "0.17.19" 729 | "@esbuild/sunos-x64" "0.17.19" 730 | "@esbuild/win32-arm64" "0.17.19" 731 | "@esbuild/win32-ia32" "0.17.19" 732 | "@esbuild/win32-x64" "0.17.19" 733 | 734 | escalade@^3.1.1: 735 | version "3.1.1" 736 | resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" 737 | integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== 738 | 739 | escape-string-regexp@^1.0.5: 740 | version "1.0.5" 741 | resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" 742 | integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== 743 | 744 | esprima@^4.0.0: 745 | version "4.0.1" 746 | resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" 747 | integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== 748 | 749 | fast-glob@3.2.7: 750 | version "3.2.7" 751 | resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.7.tgz#fd6cb7a2d7e9aa7a7846111e85a196d6b2f766a1" 752 | integrity sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q== 753 | dependencies: 754 | "@nodelib/fs.stat" "^2.0.2" 755 | "@nodelib/fs.walk" "^1.2.3" 756 | glob-parent "^5.1.2" 757 | merge2 "^1.3.0" 758 | micromatch "^4.0.4" 759 | 760 | fastq@^1.6.0: 761 | version "1.15.0" 762 | resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.15.0.tgz#d04d07c6a2a68fe4599fea8d2e103a937fae6b3a" 763 | integrity sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw== 764 | dependencies: 765 | reusify "^1.0.4" 766 | 767 | figures@3.2.0: 768 | version "3.2.0" 769 | resolved "https://registry.yarnpkg.com/figures/-/figures-3.2.0.tgz#625c18bd293c604dc4a8ddb2febf0c88341746af" 770 | integrity sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg== 771 | dependencies: 772 | escape-string-regexp "^1.0.5" 773 | 774 | fill-range@^7.0.1: 775 | version "7.0.1" 776 | resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" 777 | integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== 778 | dependencies: 779 | to-regex-range "^5.0.1" 780 | 781 | flat@^5.0.2: 782 | version "5.0.2" 783 | resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" 784 | integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== 785 | 786 | follow-redirects@^1.15.0: 787 | version "1.15.2" 788 | resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13" 789 | integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA== 790 | 791 | foreground-child@^3.1.0: 792 | version "3.1.1" 793 | resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-3.1.1.tgz#1d173e776d75d2772fed08efe4a0de1ea1b12d0d" 794 | integrity sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg== 795 | dependencies: 796 | cross-spawn "^7.0.0" 797 | signal-exit "^4.0.1" 798 | 799 | form-data@^4.0.0: 800 | version "4.0.0" 801 | resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" 802 | integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww== 803 | dependencies: 804 | asynckit "^0.4.0" 805 | combined-stream "^1.0.8" 806 | mime-types "^2.1.12" 807 | 808 | fs-constants@^1.0.0: 809 | version "1.0.0" 810 | resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" 811 | integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== 812 | 813 | fs-extra@^11.1.0: 814 | version "11.1.1" 815 | resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-11.1.1.tgz#da69f7c39f3b002378b0954bb6ae7efdc0876e2d" 816 | integrity sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ== 817 | dependencies: 818 | graceful-fs "^4.2.0" 819 | jsonfile "^6.0.1" 820 | universalify "^2.0.0" 821 | 822 | fs-minipass@^2.0.0: 823 | version "2.1.0" 824 | resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb" 825 | integrity sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg== 826 | dependencies: 827 | minipass "^3.0.0" 828 | 829 | fs.realpath@^1.0.0: 830 | version "1.0.0" 831 | resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" 832 | integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== 833 | 834 | fsevents@~2.3.2: 835 | version "2.3.2" 836 | resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" 837 | integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== 838 | 839 | get-caller-file@^2.0.5: 840 | version "2.0.5" 841 | resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" 842 | integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== 843 | 844 | get-tsconfig@^4.4.0: 845 | version "4.6.0" 846 | resolved "https://registry.yarnpkg.com/get-tsconfig/-/get-tsconfig-4.6.0.tgz#e977690993a42f3e320e932427502a40f7af6d05" 847 | integrity sha512-lgbo68hHTQnFddybKbbs/RDRJnJT5YyGy2kQzVwbq+g67X73i+5MVTval34QxGkOe9X5Ujf1UYpCaphLyltjEg== 848 | dependencies: 849 | resolve-pkg-maps "^1.0.0" 850 | 851 | glob-parent@^5.1.2: 852 | version "5.1.2" 853 | resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" 854 | integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== 855 | dependencies: 856 | is-glob "^4.0.1" 857 | 858 | glob@10.2.7: 859 | version "10.2.7" 860 | resolved "https://registry.yarnpkg.com/glob/-/glob-10.2.7.tgz#9dd2828cd5bc7bd861e7738d91e7113dda41d7d8" 861 | integrity sha512-jTKehsravOJo8IJxUGfZILnkvVJM/MOfHRs8QcXolVef2zNI9Tqyy5+SeuOAZd3upViEZQLyFpQhYiHLrMUNmA== 862 | dependencies: 863 | foreground-child "^3.1.0" 864 | jackspeak "^2.0.3" 865 | minimatch "^9.0.1" 866 | minipass "^5.0.0 || ^6.0.2" 867 | path-scurry "^1.7.0" 868 | 869 | glob@7.1.4: 870 | version "7.1.4" 871 | resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.4.tgz#aa608a2f6c577ad357e1ae5a5c26d9a8d1969255" 872 | integrity sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A== 873 | dependencies: 874 | fs.realpath "^1.0.0" 875 | inflight "^1.0.4" 876 | inherits "2" 877 | minimatch "^3.0.4" 878 | once "^1.3.0" 879 | path-is-absolute "^1.0.0" 880 | 881 | glob@^7.1.3: 882 | version "7.2.3" 883 | resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" 884 | integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== 885 | dependencies: 886 | fs.realpath "^1.0.0" 887 | inflight "^1.0.4" 888 | inherits "2" 889 | minimatch "^3.1.1" 890 | once "^1.3.0" 891 | path-is-absolute "^1.0.0" 892 | 893 | graceful-fs@^4.1.6, graceful-fs@^4.2.0: 894 | version "4.2.11" 895 | resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" 896 | integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== 897 | 898 | has-flag@^4.0.0: 899 | version "4.0.0" 900 | resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" 901 | integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== 902 | 903 | ieee754@^1.1.13: 904 | version "1.2.1" 905 | resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" 906 | integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== 907 | 908 | ignore@^5.0.4: 909 | version "5.2.4" 910 | resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324" 911 | integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== 912 | 913 | inflight@^1.0.4: 914 | version "1.0.6" 915 | resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" 916 | integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== 917 | dependencies: 918 | once "^1.3.0" 919 | wrappy "1" 920 | 921 | inherits@2, inherits@^2.0.3, inherits@^2.0.4: 922 | version "2.0.4" 923 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" 924 | integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== 925 | 926 | is-docker@^2.0.0, is-docker@^2.1.1: 927 | version "2.2.1" 928 | resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" 929 | integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== 930 | 931 | is-extglob@^2.1.1: 932 | version "2.1.1" 933 | resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" 934 | integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== 935 | 936 | is-fullwidth-code-point@^3.0.0: 937 | version "3.0.0" 938 | resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" 939 | integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== 940 | 941 | is-glob@^4.0.1: 942 | version "4.0.3" 943 | resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" 944 | integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== 945 | dependencies: 946 | is-extglob "^2.1.1" 947 | 948 | is-number@^7.0.0: 949 | version "7.0.0" 950 | resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" 951 | integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== 952 | 953 | is-wsl@^2.2.0: 954 | version "2.2.0" 955 | resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" 956 | integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== 957 | dependencies: 958 | is-docker "^2.0.0" 959 | 960 | isexe@^2.0.0: 961 | version "2.0.0" 962 | resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" 963 | integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== 964 | 965 | jackspeak@^2.0.3: 966 | version "2.2.1" 967 | resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-2.2.1.tgz#655e8cf025d872c9c03d3eb63e8f0c024fef16a6" 968 | integrity sha512-MXbxovZ/Pm42f6cDIDkl3xpwv1AGwObKwfmjs2nQePiy85tP3fatofl3FC1aBsOtP/6fq5SbtgHwWcMsLP+bDw== 969 | dependencies: 970 | "@isaacs/cliui" "^8.0.2" 971 | optionalDependencies: 972 | "@pkgjs/parseargs" "^0.11.0" 973 | 974 | js-yaml@4.1.0: 975 | version "4.1.0" 976 | resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" 977 | integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== 978 | dependencies: 979 | argparse "^2.0.1" 980 | 981 | js-yaml@^3.10.0: 982 | version "3.14.1" 983 | resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" 984 | integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== 985 | dependencies: 986 | argparse "^1.0.7" 987 | esprima "^4.0.0" 988 | 989 | json5@^2.2.2: 990 | version "2.2.3" 991 | resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" 992 | integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== 993 | 994 | jsonc-parser@3.2.0: 995 | version "3.2.0" 996 | resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-3.2.0.tgz#31ff3f4c2b9793f89c67212627c51c6394f88e76" 997 | integrity sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w== 998 | 999 | jsonfile@^6.0.1: 1000 | version "6.1.0" 1001 | resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae" 1002 | integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ== 1003 | dependencies: 1004 | universalify "^2.0.0" 1005 | optionalDependencies: 1006 | graceful-fs "^4.1.6" 1007 | 1008 | lines-and-columns@~2.0.3: 1009 | version "2.0.3" 1010 | resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-2.0.3.tgz#b2f0badedb556b747020ab8ea7f0373e22efac1b" 1011 | integrity sha512-cNOjgCnLB+FnvWWtyRTzmB3POJ+cXxTA81LoW7u8JdmhfXzriropYwpjShnz1QLLWsQwY7nIxoDmcPTwphDK9w== 1012 | 1013 | lodash@^4.17.21: 1014 | version "4.17.21" 1015 | resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" 1016 | integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== 1017 | 1018 | lru-cache@^6.0.0: 1019 | version "6.0.0" 1020 | resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" 1021 | integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== 1022 | dependencies: 1023 | yallist "^4.0.0" 1024 | 1025 | lru-cache@^9.1.1: 1026 | version "9.1.2" 1027 | resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-9.1.2.tgz#255fdbc14b75589d6d0e73644ca167a8db506835" 1028 | integrity sha512-ERJq3FOzJTxBbFjZ7iDs+NiK4VI9Wz+RdrrAB8dio1oV+YvdPzUEE4QNiT2VD51DkIbCYRUUzCRkssXCHqSnKQ== 1029 | 1030 | merge2@^1.3.0: 1031 | version "1.4.1" 1032 | resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" 1033 | integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== 1034 | 1035 | micromatch@^4.0.4: 1036 | version "4.0.5" 1037 | resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" 1038 | integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== 1039 | dependencies: 1040 | braces "^3.0.2" 1041 | picomatch "^2.3.1" 1042 | 1043 | mime-db@1.52.0: 1044 | version "1.52.0" 1045 | resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" 1046 | integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== 1047 | 1048 | mime-types@2.1.35, mime-types@^2.1.12: 1049 | version "2.1.35" 1050 | resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" 1051 | integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== 1052 | dependencies: 1053 | mime-db "1.52.0" 1054 | 1055 | mimic-fn@^2.1.0: 1056 | version "2.1.0" 1057 | resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" 1058 | integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== 1059 | 1060 | minimatch@3.0.5: 1061 | version "3.0.5" 1062 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.5.tgz#4da8f1290ee0f0f8e83d60ca69f8f134068604a3" 1063 | integrity sha512-tUpxzX0VAzJHjLu0xUfFv1gwVp9ba3IOuRAVH2EGuRW8a5emA2FlACLqiT/lDVtS1W+TGNwqz3sWaNyLgDJWuw== 1064 | dependencies: 1065 | brace-expansion "^1.1.7" 1066 | 1067 | minimatch@^3.0.4, minimatch@^3.1.1: 1068 | version "3.1.2" 1069 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" 1070 | integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== 1071 | dependencies: 1072 | brace-expansion "^1.1.7" 1073 | 1074 | minimatch@^9.0.1: 1075 | version "9.0.1" 1076 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.1.tgz#8a555f541cf976c622daf078bb28f29fb927c253" 1077 | integrity sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w== 1078 | dependencies: 1079 | brace-expansion "^2.0.1" 1080 | 1081 | minimist@^1.2.0, minimist@^1.2.6: 1082 | version "1.2.8" 1083 | resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" 1084 | integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== 1085 | 1086 | minipass@^3.0.0: 1087 | version "3.3.6" 1088 | resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.3.6.tgz#7bba384db3a1520d18c9c0e5251c3444e95dd94a" 1089 | integrity sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw== 1090 | dependencies: 1091 | yallist "^4.0.0" 1092 | 1093 | "minipass@^5.0.0 || ^6.0.2": 1094 | version "6.0.2" 1095 | resolved "https://registry.yarnpkg.com/minipass/-/minipass-6.0.2.tgz#542844b6c4ce95b202c0995b0a471f1229de4c81" 1096 | integrity sha512-MzWSV5nYVT7mVyWCwn2o7JH13w2TBRmmSqSRCKzTw+lmft9X4z+3wjvs06Tzijo5z4W/kahUCDpRXTF+ZrmF/w== 1097 | 1098 | minizlib@^2.1.1: 1099 | version "2.1.2" 1100 | resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.2.tgz#e90d3466ba209b932451508a11ce3d3632145931" 1101 | integrity sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg== 1102 | dependencies: 1103 | minipass "^3.0.0" 1104 | yallist "^4.0.0" 1105 | 1106 | mkdirp@^1.0.3: 1107 | version "1.0.4" 1108 | resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" 1109 | integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== 1110 | 1111 | node-addon-api@^3.2.1: 1112 | version "3.2.1" 1113 | resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-3.2.1.tgz#81325e0a2117789c0128dab65e7e38f07ceba161" 1114 | integrity sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A== 1115 | 1116 | node-gyp-build@^4.3.0: 1117 | version "4.6.0" 1118 | resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.6.0.tgz#0c52e4cbf54bbd28b709820ef7b6a3c2d6209055" 1119 | integrity sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ== 1120 | 1121 | node-machine-id@^1.1.12: 1122 | version "1.1.12" 1123 | resolved "https://registry.yarnpkg.com/node-machine-id/-/node-machine-id-1.1.12.tgz#37904eee1e59b320bb9c5d6c0a59f3b469cb6267" 1124 | integrity sha512-QNABxbrPa3qEIfrE6GOJ7BYIuignnJw7iQ2YPbc3Nla1HzRJjXzZOiikfF8m7eAMfichLt3M4VgLOetqgDmgGQ== 1125 | 1126 | npm-run-path@^4.0.1: 1127 | version "4.0.1" 1128 | resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" 1129 | integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== 1130 | dependencies: 1131 | path-key "^3.0.0" 1132 | 1133 | nx-cloud@16.0.5, nx-cloud@latest: 1134 | version "16.0.5" 1135 | resolved "https://registry.yarnpkg.com/nx-cloud/-/nx-cloud-16.0.5.tgz#fa0b0185d254405ec47fcbcdbbd8b12ff1add096" 1136 | integrity sha512-13P7r0aKikjBtmdZrNorwXzVPeVIV4MLEwqGY+DEG6doLBtI5KqEQk/d5B5l2dCF2BEi/LXEmLYCmf9gwbOJ+Q== 1137 | dependencies: 1138 | "@nrwl/nx-cloud" "16.0.5" 1139 | axios "1.1.3" 1140 | chalk "^4.1.0" 1141 | dotenv "~10.0.0" 1142 | fs-extra "^11.1.0" 1143 | node-machine-id "^1.1.12" 1144 | open "~8.4.0" 1145 | strip-json-comments "^3.1.1" 1146 | tar "6.1.11" 1147 | yargs-parser ">=21.1.1" 1148 | 1149 | nx@16.3.2: 1150 | version "16.3.2" 1151 | resolved "https://registry.yarnpkg.com/nx/-/nx-16.3.2.tgz#92a2d7ef06d15b3b111b7cf9d35de08de0a22d90" 1152 | integrity sha512-fOzCVL7qoCJAcYTJwvJ9j+PSaL791ro4AICWuLxaphZsp2jcLoav4Ev7ONPks2Wlkt8FS9bee3nqQ3w1ya36Og== 1153 | dependencies: 1154 | "@nrwl/tao" "16.3.2" 1155 | "@parcel/watcher" "2.0.4" 1156 | "@yarnpkg/lockfile" "^1.1.0" 1157 | "@yarnpkg/parsers" "^3.0.0-rc.18" 1158 | "@zkochan/js-yaml" "0.0.6" 1159 | axios "^1.0.0" 1160 | chalk "^4.1.0" 1161 | cli-cursor "3.1.0" 1162 | cli-spinners "2.6.1" 1163 | cliui "^7.0.2" 1164 | dotenv "~10.0.0" 1165 | enquirer "~2.3.6" 1166 | fast-glob "3.2.7" 1167 | figures "3.2.0" 1168 | flat "^5.0.2" 1169 | fs-extra "^11.1.0" 1170 | glob "7.1.4" 1171 | ignore "^5.0.4" 1172 | js-yaml "4.1.0" 1173 | jsonc-parser "3.2.0" 1174 | lines-and-columns "~2.0.3" 1175 | minimatch "3.0.5" 1176 | npm-run-path "^4.0.1" 1177 | open "^8.4.0" 1178 | semver "7.3.4" 1179 | string-width "^4.2.3" 1180 | strong-log-transformer "^2.1.0" 1181 | tar-stream "~2.2.0" 1182 | tmp "~0.2.1" 1183 | tsconfig-paths "^4.1.2" 1184 | tslib "^2.3.0" 1185 | v8-compile-cache "2.3.0" 1186 | yargs "^17.6.2" 1187 | yargs-parser "21.1.1" 1188 | optionalDependencies: 1189 | "@nx/nx-darwin-arm64" "16.3.2" 1190 | "@nx/nx-darwin-x64" "16.3.2" 1191 | "@nx/nx-freebsd-x64" "16.3.2" 1192 | "@nx/nx-linux-arm-gnueabihf" "16.3.2" 1193 | "@nx/nx-linux-arm64-gnu" "16.3.2" 1194 | "@nx/nx-linux-arm64-musl" "16.3.2" 1195 | "@nx/nx-linux-x64-gnu" "16.3.2" 1196 | "@nx/nx-linux-x64-musl" "16.3.2" 1197 | "@nx/nx-win32-arm64-msvc" "16.3.2" 1198 | "@nx/nx-win32-x64-msvc" "16.3.2" 1199 | 1200 | once@^1.3.0, once@^1.4.0: 1201 | version "1.4.0" 1202 | resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" 1203 | integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== 1204 | dependencies: 1205 | wrappy "1" 1206 | 1207 | onetime@^5.1.0: 1208 | version "5.1.2" 1209 | resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" 1210 | integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== 1211 | dependencies: 1212 | mimic-fn "^2.1.0" 1213 | 1214 | open@^8.4.0, open@~8.4.0: 1215 | version "8.4.2" 1216 | resolved "https://registry.yarnpkg.com/open/-/open-8.4.2.tgz#5b5ffe2a8f793dcd2aad73e550cb87b59cb084f9" 1217 | integrity sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ== 1218 | dependencies: 1219 | define-lazy-prop "^2.0.0" 1220 | is-docker "^2.1.1" 1221 | is-wsl "^2.2.0" 1222 | 1223 | path-is-absolute@^1.0.0: 1224 | version "1.0.1" 1225 | resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" 1226 | integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== 1227 | 1228 | path-key@^3.0.0, path-key@^3.1.0: 1229 | version "3.1.1" 1230 | resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" 1231 | integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== 1232 | 1233 | path-scurry@^1.7.0: 1234 | version "1.9.2" 1235 | resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-1.9.2.tgz#90f9d296ac5e37e608028e28a447b11d385b3f63" 1236 | integrity sha512-qSDLy2aGFPm8i4rsbHd4MNyTcrzHFsLQykrtbuGRknZZCBBVXSv2tSCDN2Cg6Rt/GFRw8GoW9y9Ecw5rIPG1sg== 1237 | dependencies: 1238 | lru-cache "^9.1.1" 1239 | minipass "^5.0.0 || ^6.0.2" 1240 | 1241 | picomatch@^2.3.1: 1242 | version "2.3.1" 1243 | resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" 1244 | integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== 1245 | 1246 | preact@10.15.1: 1247 | version "10.15.1" 1248 | resolved "https://registry.yarnpkg.com/preact/-/preact-10.15.1.tgz#a1de60c9fc0c79a522d969c65dcaddc5d994eede" 1249 | integrity sha512-qs2ansoQEwzNiV5eAcRT1p1EC/dmEzaATVDJNiB3g2sRDWdA7b7MurXdJjB2+/WQktGWZwxvDrnuRFbWuIr64g== 1250 | 1251 | proxy-from-env@^1.1.0: 1252 | version "1.1.0" 1253 | resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2" 1254 | integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== 1255 | 1256 | queue-microtask@^1.2.2: 1257 | version "1.2.3" 1258 | resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" 1259 | integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== 1260 | 1261 | readable-stream@^3.1.1, readable-stream@^3.4.0: 1262 | version "3.6.2" 1263 | resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" 1264 | integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== 1265 | dependencies: 1266 | inherits "^2.0.3" 1267 | string_decoder "^1.1.1" 1268 | util-deprecate "^1.0.1" 1269 | 1270 | regenerator-runtime@^0.13.11: 1271 | version "0.13.11" 1272 | resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9" 1273 | integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg== 1274 | 1275 | require-directory@^2.1.1: 1276 | version "2.1.1" 1277 | resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" 1278 | integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== 1279 | 1280 | resolve-pkg-maps@^1.0.0: 1281 | version "1.0.0" 1282 | resolved "https://registry.yarnpkg.com/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz#616b3dc2c57056b5588c31cdf4b3d64db133720f" 1283 | integrity sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw== 1284 | 1285 | restore-cursor@^3.1.0: 1286 | version "3.1.0" 1287 | resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e" 1288 | integrity sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA== 1289 | dependencies: 1290 | onetime "^5.1.0" 1291 | signal-exit "^3.0.2" 1292 | 1293 | reusify@^1.0.4: 1294 | version "1.0.4" 1295 | resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" 1296 | integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== 1297 | 1298 | rimraf@^3.0.0: 1299 | version "3.0.2" 1300 | resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" 1301 | integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== 1302 | dependencies: 1303 | glob "^7.1.3" 1304 | 1305 | run-parallel@^1.1.9: 1306 | version "1.2.0" 1307 | resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" 1308 | integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== 1309 | dependencies: 1310 | queue-microtask "^1.2.2" 1311 | 1312 | rxjs@^7.8.1: 1313 | version "7.8.1" 1314 | resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.8.1.tgz#6f6f3d99ea8044291efd92e7c7fcf562c4057543" 1315 | integrity sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg== 1316 | dependencies: 1317 | tslib "^2.1.0" 1318 | 1319 | safe-buffer@~5.2.0: 1320 | version "5.2.1" 1321 | resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" 1322 | integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== 1323 | 1324 | semver@7.3.4: 1325 | version "7.3.4" 1326 | resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.4.tgz#27aaa7d2e4ca76452f98d3add093a72c943edc97" 1327 | integrity sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw== 1328 | dependencies: 1329 | lru-cache "^6.0.0" 1330 | 1331 | shebang-command@^2.0.0: 1332 | version "2.0.0" 1333 | resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" 1334 | integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== 1335 | dependencies: 1336 | shebang-regex "^3.0.0" 1337 | 1338 | shebang-regex@^3.0.0: 1339 | version "3.0.0" 1340 | resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" 1341 | integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== 1342 | 1343 | shell-quote@^1.8.1: 1344 | version "1.8.1" 1345 | resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.8.1.tgz#6dbf4db75515ad5bac63b4f1894c3a154c766680" 1346 | integrity sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA== 1347 | 1348 | signal-exit@^3.0.2: 1349 | version "3.0.7" 1350 | resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" 1351 | integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== 1352 | 1353 | signal-exit@^4.0.1: 1354 | version "4.0.2" 1355 | resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.0.2.tgz#ff55bb1d9ff2114c13b400688fa544ac63c36967" 1356 | integrity sha512-MY2/qGx4enyjprQnFaZsHib3Yadh3IXyV2C321GY0pjGfVBu4un0uDJkwgdxqO+Rdx8JMT8IfJIRwbYVz3Ob3Q== 1357 | 1358 | source-map-support@0.5.21, source-map-support@^0.5.21: 1359 | version "0.5.21" 1360 | resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" 1361 | integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== 1362 | dependencies: 1363 | buffer-from "^1.0.0" 1364 | source-map "^0.6.0" 1365 | 1366 | source-map@^0.6.0: 1367 | version "0.6.1" 1368 | resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" 1369 | integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== 1370 | 1371 | spawn-command@0.0.2: 1372 | version "0.0.2" 1373 | resolved "https://registry.yarnpkg.com/spawn-command/-/spawn-command-0.0.2.tgz#9544e1a43ca045f8531aac1a48cb29bdae62338e" 1374 | integrity sha512-zC8zGoGkmc8J9ndvml8Xksr1Amk9qBujgbF0JAIWO7kXr43w0h/0GJNM/Vustixu+YE8N/MTrQ7N31FvHUACxQ== 1375 | 1376 | sprintf-js@~1.0.2: 1377 | version "1.0.3" 1378 | resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" 1379 | integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g== 1380 | 1381 | "string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: 1382 | version "4.2.3" 1383 | resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" 1384 | integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== 1385 | dependencies: 1386 | emoji-regex "^8.0.0" 1387 | is-fullwidth-code-point "^3.0.0" 1388 | strip-ansi "^6.0.1" 1389 | 1390 | string-width@^5.0.1, string-width@^5.1.2: 1391 | version "5.1.2" 1392 | resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794" 1393 | integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA== 1394 | dependencies: 1395 | eastasianwidth "^0.2.0" 1396 | emoji-regex "^9.2.2" 1397 | strip-ansi "^7.0.1" 1398 | 1399 | string_decoder@^1.1.1: 1400 | version "1.3.0" 1401 | resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" 1402 | integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== 1403 | dependencies: 1404 | safe-buffer "~5.2.0" 1405 | 1406 | "strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: 1407 | version "6.0.1" 1408 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" 1409 | integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== 1410 | dependencies: 1411 | ansi-regex "^5.0.1" 1412 | 1413 | strip-ansi@^7.0.1: 1414 | version "7.1.0" 1415 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" 1416 | integrity sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ== 1417 | dependencies: 1418 | ansi-regex "^6.0.1" 1419 | 1420 | strip-bom@^3.0.0: 1421 | version "3.0.0" 1422 | resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" 1423 | integrity sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA== 1424 | 1425 | strip-json-comments@^3.1.1: 1426 | version "3.1.1" 1427 | resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" 1428 | integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== 1429 | 1430 | strong-log-transformer@^2.1.0: 1431 | version "2.1.0" 1432 | resolved "https://registry.yarnpkg.com/strong-log-transformer/-/strong-log-transformer-2.1.0.tgz#0f5ed78d325e0421ac6f90f7f10e691d6ae3ae10" 1433 | integrity sha512-B3Hgul+z0L9a236FAUC9iZsL+nVHgoCJnqCbN588DjYxvGXaXaaFbfmQ/JhvKjZwsOukuR72XbHv71Qkug0HxA== 1434 | dependencies: 1435 | duplexer "^0.1.1" 1436 | minimist "^1.2.0" 1437 | through "^2.3.4" 1438 | 1439 | supports-color@^7.1.0: 1440 | version "7.2.0" 1441 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" 1442 | integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== 1443 | dependencies: 1444 | has-flag "^4.0.0" 1445 | 1446 | supports-color@^8.1.1: 1447 | version "8.1.1" 1448 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" 1449 | integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== 1450 | dependencies: 1451 | has-flag "^4.0.0" 1452 | 1453 | tar-stream@~2.2.0: 1454 | version "2.2.0" 1455 | resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.2.0.tgz#acad84c284136b060dc3faa64474aa9aebd77287" 1456 | integrity sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ== 1457 | dependencies: 1458 | bl "^4.0.3" 1459 | end-of-stream "^1.4.1" 1460 | fs-constants "^1.0.0" 1461 | inherits "^2.0.3" 1462 | readable-stream "^3.1.1" 1463 | 1464 | tar@6.1.11: 1465 | version "6.1.11" 1466 | resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.11.tgz#6760a38f003afa1b2ffd0ffe9e9abbd0eab3d621" 1467 | integrity sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA== 1468 | dependencies: 1469 | chownr "^2.0.0" 1470 | fs-minipass "^2.0.0" 1471 | minipass "^3.0.0" 1472 | minizlib "^2.1.1" 1473 | mkdirp "^1.0.3" 1474 | yallist "^4.0.0" 1475 | 1476 | through@^2.3.4: 1477 | version "2.3.8" 1478 | resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" 1479 | integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg== 1480 | 1481 | tmp@~0.2.1: 1482 | version "0.2.1" 1483 | resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.1.tgz#8457fc3037dcf4719c251367a1af6500ee1ccf14" 1484 | integrity sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ== 1485 | dependencies: 1486 | rimraf "^3.0.0" 1487 | 1488 | to-regex-range@^5.0.1: 1489 | version "5.0.1" 1490 | resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" 1491 | integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== 1492 | dependencies: 1493 | is-number "^7.0.0" 1494 | 1495 | tree-kill@^1.2.2: 1496 | version "1.2.2" 1497 | resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.2.2.tgz#4ca09a9092c88b73a7cdc5e8a01b507b0790a0cc" 1498 | integrity sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A== 1499 | 1500 | tsconfig-paths@^4.1.2: 1501 | version "4.2.0" 1502 | resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz#ef78e19039133446d244beac0fd6a1632e2d107c" 1503 | integrity sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg== 1504 | dependencies: 1505 | json5 "^2.2.2" 1506 | minimist "^1.2.6" 1507 | strip-bom "^3.0.0" 1508 | 1509 | tslib@^2.1.0, tslib@^2.3.0, tslib@^2.4.0: 1510 | version "2.5.3" 1511 | resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.5.3.tgz#24944ba2d990940e6e982c4bea147aba80209913" 1512 | integrity sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w== 1513 | 1514 | tsx@3.12.7: 1515 | version "3.12.7" 1516 | resolved "https://registry.yarnpkg.com/tsx/-/tsx-3.12.7.tgz#b3b8b0fc79afc8260d1e14f9e995616c859a91e9" 1517 | integrity sha512-C2Ip+jPmqKd1GWVQDvz/Eyc6QJbGfE7NrR3fx5BpEHMZsEHoIxHL1j+lKdGobr8ovEyqeNkPLSKp6SCSOt7gmw== 1518 | dependencies: 1519 | "@esbuild-kit/cjs-loader" "^2.4.2" 1520 | "@esbuild-kit/core-utils" "^3.0.0" 1521 | "@esbuild-kit/esm-loader" "^2.5.5" 1522 | optionalDependencies: 1523 | fsevents "~2.3.2" 1524 | 1525 | typescript@5.1.3: 1526 | version "5.1.3" 1527 | resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.1.3.tgz#8d84219244a6b40b6fb2b33cc1c062f715b9e826" 1528 | integrity sha512-XH627E9vkeqhlZFQuL+UsyAXEnibT0kWR2FWONlr4sTjvxyJYnyefgrkyECLzM5NenmKzRAy2rR/OlYLA1HkZw== 1529 | 1530 | universalify@^2.0.0: 1531 | version "2.0.0" 1532 | resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717" 1533 | integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ== 1534 | 1535 | util-deprecate@^1.0.1: 1536 | version "1.0.2" 1537 | resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" 1538 | integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== 1539 | 1540 | v8-compile-cache@2.3.0: 1541 | version "2.3.0" 1542 | resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" 1543 | integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== 1544 | 1545 | which@^2.0.1: 1546 | version "2.0.2" 1547 | resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" 1548 | integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== 1549 | dependencies: 1550 | isexe "^2.0.0" 1551 | 1552 | "wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: 1553 | version "7.0.0" 1554 | resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" 1555 | integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== 1556 | dependencies: 1557 | ansi-styles "^4.0.0" 1558 | string-width "^4.1.0" 1559 | strip-ansi "^6.0.0" 1560 | 1561 | wrap-ansi@^8.1.0: 1562 | version "8.1.0" 1563 | resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" 1564 | integrity sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ== 1565 | dependencies: 1566 | ansi-styles "^6.1.0" 1567 | string-width "^5.0.1" 1568 | strip-ansi "^7.0.1" 1569 | 1570 | wrappy@1: 1571 | version "1.0.2" 1572 | resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" 1573 | integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== 1574 | 1575 | y18n@^5.0.5: 1576 | version "5.0.8" 1577 | resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" 1578 | integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== 1579 | 1580 | yallist@^4.0.0: 1581 | version "4.0.0" 1582 | resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" 1583 | integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== 1584 | 1585 | yargs-parser@21.1.1, yargs-parser@>=21.1.1, yargs-parser@^21.1.1: 1586 | version "21.1.1" 1587 | resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35" 1588 | integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== 1589 | 1590 | yargs@^17.6.2, yargs@^17.7.2: 1591 | version "17.7.2" 1592 | resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.2.tgz#991df39aca675a192b816e1e0363f9d75d2aa269" 1593 | integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w== 1594 | dependencies: 1595 | cliui "^8.0.1" 1596 | escalade "^3.1.1" 1597 | get-caller-file "^2.0.5" 1598 | require-directory "^2.1.1" 1599 | string-width "^4.2.3" 1600 | y18n "^5.0.5" 1601 | yargs-parser "^21.1.1" 1602 | --------------------------------------------------------------------------------