diff --git a/data/project-templates/react-js/package.json b/data/project-templates/react-js/package.json index 425645b..8e150e4 100644 --- a/data/project-templates/react-js/package.json +++ b/data/project-templates/react-js/package.json @@ -10,8 +10,9 @@ "preview": "vite preview" }, "dependencies": { - "@golem-sdk/golem-js": "^3.0.0", - "@golem-sdk/react": "^3.0.1", + "@golem-sdk/golem-js": "^3.1.0", + "@golem-sdk/react": "^4.0.0", + "@golem-sdk/task-executor": "^2.0.0", "react": "^18.2.0", "react-dom": "^18.2.0" }, diff --git a/data/project-templates/react-js/src/components/NodeVersionCheck.jsx b/data/project-templates/react-js/src/components/NodeVersionCheck.jsx index 9084878..28c2012 100644 --- a/data/project-templates/react-js/src/components/NodeVersionCheck.jsx +++ b/data/project-templates/react-js/src/components/NodeVersionCheck.jsx @@ -1,39 +1,42 @@ import { useExecutor } from "@golem-sdk/react"; -import { ProposalFilterFactory } from "@golem-sdk/golem-js"; -import { NodeVersionCheckTask } from "./NodeVersionCheckTask.jsx"; +import { NodeVersionCheckTask } from "./NodeVersionCheckTask"; export function NodeVersionCheck() { const { executor, initialize, isInitialized, isInitializing, terminate, error } = useExecutor({ - // What do you want to run - package: "golem/node:20-alpine", - - // How much you wish to spend - budget: 2, - - // How do you want to select market proposals - proposalFilter: ProposalFilterFactory.limitPriceFilter({ - start: 1.0, - cpuPerSec: 1.0 / 3600, - envPerSec: 1.0 / 3600, - }), - + demand: { + workload: { + imageTag: "golem/node:20-alpine", + }, + }, // Where you want to spend payment: { - network: "goerli", + network: "holesky", + }, + market: { + // Let's rent the provider for no more than 15 minutes + rentHours: 15 / 60, + // Let's agree to pay at most 0.5 GLM per hour + pricing: { + model: "burn-rate", + avgGlmPerHour: 0.5, + }, }, - // Control the execution of tasks - maxTaskRetries: 0, - taskTimeout: 5 * 60 * 1000, + task: { + taskTimeout: 5 * 60 * 1000, + maxTaskRetries: 0, + }, + // Look at the browser console to see what's happening under the hood + enableLogging: true, }); return (
{error &&
Error: {error.toString()}
} - {isInitialized && } + {isInitialized && executor && } {isInitializing &&
Executor is initializing
} {!isInitialized && ( - )} diff --git a/data/project-templates/react-js/src/components/NodeVersionCheckTask.jsx b/data/project-templates/react-js/src/components/NodeVersionCheckTask.jsx index d8eee36..e0fdde4 100644 --- a/data/project-templates/react-js/src/components/NodeVersionCheckTask.jsx +++ b/data/project-templates/react-js/src/components/NodeVersionCheckTask.jsx @@ -4,8 +4,8 @@ import PropTypes from "prop-types"; export function NodeVersionCheckTask({ executor }) { const { isRunning, result, run, error } = useTask(executor); - const getNodeVersionTask = async (ctx) => { - return (await ctx.run("node -v")).stdout?.toString() ?? "No version information"; + const getNodeVersionTask = async (exe) => { + return (await exe.run("node -v")).stdout?.toString() ?? "No version information"; }; return ( diff --git a/data/project-templates/react-ts/package.json b/data/project-templates/react-ts/package.json index f9d62c3..22b91a8 100644 --- a/data/project-templates/react-ts/package.json +++ b/data/project-templates/react-ts/package.json @@ -10,8 +10,9 @@ "preview": "vite preview" }, "dependencies": { - "@golem-sdk/golem-js": "^3.0.0", - "@golem-sdk/react": "^3.0.1", + "@golem-sdk/golem-js": "^3.1.0", + "@golem-sdk/react": "^4.0.0", + "@golem-sdk/task-executor": "^2.0.0", "react": "^18.2.0", "react-dom": "^18.2.0" }, diff --git a/data/project-templates/react-ts/src/components/NodeVersionCheck.tsx b/data/project-templates/react-ts/src/components/NodeVersionCheck.tsx index 78c6839..28c2012 100644 --- a/data/project-templates/react-ts/src/components/NodeVersionCheck.tsx +++ b/data/project-templates/react-ts/src/components/NodeVersionCheck.tsx @@ -1,30 +1,33 @@ import { useExecutor } from "@golem-sdk/react"; -import { ProposalFilterFactory } from "@golem-sdk/golem-js"; import { NodeVersionCheckTask } from "./NodeVersionCheckTask"; export function NodeVersionCheck() { const { executor, initialize, isInitialized, isInitializing, terminate, error } = useExecutor({ - // What do you want to run - package: "golem/node:20-alpine", - - // How much you wish to spend - budget: 2, - - // How do you want to select market proposals - proposalFilter: ProposalFilterFactory.limitPriceFilter({ - start: 1.0, - cpuPerSec: 1.0 / 3600, - envPerSec: 1.0 / 3600, - }), - + demand: { + workload: { + imageTag: "golem/node:20-alpine", + }, + }, // Where you want to spend payment: { - network: "goerli", + network: "holesky", + }, + market: { + // Let's rent the provider for no more than 15 minutes + rentHours: 15 / 60, + // Let's agree to pay at most 0.5 GLM per hour + pricing: { + model: "burn-rate", + avgGlmPerHour: 0.5, + }, }, - // Control the execution of tasks - maxTaskRetries: 0, - taskTimeout: 5 * 60 * 1000, + task: { + taskTimeout: 5 * 60 * 1000, + maxTaskRetries: 0, + }, + // Look at the browser console to see what's happening under the hood + enableLogging: true, }); return ( @@ -33,7 +36,7 @@ export function NodeVersionCheck() { {isInitialized && executor && } {isInitializing &&
Executor is initializing
} {!isInitialized && ( - )} diff --git a/data/project-templates/react-ts/src/components/NodeVersionCheckTask.tsx b/data/project-templates/react-ts/src/components/NodeVersionCheckTask.tsx index 1f9a7e2..e21c89a 100644 --- a/data/project-templates/react-ts/src/components/NodeVersionCheckTask.tsx +++ b/data/project-templates/react-ts/src/components/NodeVersionCheckTask.tsx @@ -1,10 +1,10 @@ -import { TaskExecutor, useTask, Worker } from "@golem-sdk/react"; - +import { useTask } from "@golem-sdk/react"; +import type { TaskFunction, TaskExecutor } from "@golem-sdk/task-executor"; export function NodeVersionCheckTask({ executor }: { executor: TaskExecutor }) { const { isRunning, result, run, error } = useTask(executor); - const getNodeVersionTask: Worker = async (ctx) => { - return (await ctx.run("node -v")).stdout?.toString() ?? "No version information"; + const getNodeVersionTask: TaskFunction = async (exe) => { + return (await exe.run("node -v")).stdout?.toString() ?? "No version information"; }; return ( diff --git a/package-lock.json b/package-lock.json index f661f53..cd09205 100644 --- a/package-lock.json +++ b/package-lock.json @@ -76,8 +76,9 @@ "name": "react-js-golem-app", "version": "0.0.0", "dependencies": { - "@golem-sdk/golem-js": "^3.0.0", - "@golem-sdk/react": "^3.0.1", + "@golem-sdk/golem-js": "^3.1.0", + "@golem-sdk/react": "^4.0.0", + "@golem-sdk/task-executor": "^2.0.0", "react": "^18.2.0", "react-dom": "^18.2.0" }, @@ -92,12 +93,39 @@ "vite": "^5.1.4" } }, + "data/project-templates/react-js/node_modules/@golem-sdk/react": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@golem-sdk/react/-/react-4.0.0.tgz", + "integrity": "sha512-Q9BLQrz377764FbKkIDGMdiCxa6ju4FuscC3q+rt6FwXKs5gdaebQYcnRJ/RlxyQPhp2QR6F13zzXSZ3AelSjQ==", + "dependencies": { + "swr": "^2.2.2" + }, + "peerDependencies": { + "@golem-sdk/golem-js": "^3.0.0", + "@golem-sdk/task-executor": "^2.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "data/project-templates/react-js/node_modules/@golem-sdk/task-executor": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@golem-sdk/task-executor/-/task-executor-2.0.0.tgz", + "integrity": "sha512-qEtr3Opa5e1+lgaY43vQVDGEzpeU6H9OreK0Sbvpaww7SOLShQxanzcnrEfgTLWFvnx7VB2zksCqVDmMAtGN/A==", + "dependencies": { + "@golem-sdk/golem-js": "v3.1.0", + "eventemitter3": "^5.0.1" + }, + "engines": { + "node": ">=18.0.0" + } + }, "data/project-templates/react-ts": { "name": "react-ts-golem-app", "version": "0.0.0", "dependencies": { - "@golem-sdk/golem-js": "^3.0.0", - "@golem-sdk/react": "^3.0.1", + "@golem-sdk/golem-js": "^3.1.0", + "@golem-sdk/react": "^4.0.0", + "@golem-sdk/task-executor": "^2.0.0", "react": "^18.2.0", "react-dom": "^18.2.0" }, @@ -114,6 +142,32 @@ "vite": "^5.1.4" } }, + "data/project-templates/react-ts/node_modules/@golem-sdk/react": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@golem-sdk/react/-/react-4.0.0.tgz", + "integrity": "sha512-Q9BLQrz377764FbKkIDGMdiCxa6ju4FuscC3q+rt6FwXKs5gdaebQYcnRJ/RlxyQPhp2QR6F13zzXSZ3AelSjQ==", + "dependencies": { + "swr": "^2.2.2" + }, + "peerDependencies": { + "@golem-sdk/golem-js": "^3.0.0", + "@golem-sdk/task-executor": "^2.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "data/project-templates/react-ts/node_modules/@golem-sdk/task-executor": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@golem-sdk/task-executor/-/task-executor-2.0.0.tgz", + "integrity": "sha512-qEtr3Opa5e1+lgaY43vQVDGEzpeU6H9OreK0Sbvpaww7SOLShQxanzcnrEfgTLWFvnx7VB2zksCqVDmMAtGN/A==", + "dependencies": { + "@golem-sdk/golem-js": "v3.1.0", + "eventemitter3": "^5.0.1" + }, + "engines": { + "node": ">=18.0.0" + } + }, "data/project-templates/ts-node": { "name": "ts-node-golem-app", "version": "1.0.0", @@ -2104,10 +2158,11 @@ } }, "node_modules/@golem-sdk/golem-js": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@golem-sdk/golem-js/-/golem-js-3.0.0.tgz", - "integrity": "sha512-jqjV+egfTIgkNQL3aGh4gorj+K9yD4/BokZ4FdT8C8LX7gkRrPSwT5OJcWUrt/Qq03aDI5J4FuOeN8RLWOiWAw==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@golem-sdk/golem-js/-/golem-js-3.1.0.tgz", + "integrity": "sha512-Ft58Q46yA1NawG5W9sW+t3zwbSzjRIOdwkkQLC/9AXa5HT+DVT8yVZz7caDXrBclFzs58jWKKlBTqlLQP6H91A==", "dependencies": { + "@golem-sdk/pino-logger": "^1.1.0", "async-lock": "^1.4.1", "async-retry": "^1.3.3", "axios": "^1.6.7", @@ -2152,128 +2207,51 @@ "uuid": "dist/bin/uuid" } }, - "node_modules/@golem-sdk/react": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@golem-sdk/react/-/react-3.0.1.tgz", - "integrity": "sha512-a+svKmjLlfiHucRp2yt48Wy+rTgo4rwwZNhDQbSv6gn6C4OcrgBbfOCxLCLG4hs9bpUUoijcVkc9Mcb9+fI+fg==", + "node_modules/@golem-sdk/pino-logger": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@golem-sdk/pino-logger/-/pino-logger-1.1.0.tgz", + "integrity": "sha512-FxVqTnx7ToKPCABzfEHhwXT2x/B4PWez6y6AG9AeMjH9DA/itY8kclv0DUgWPPRTW4jr1Qrf6ovZYLhPZ5o3Dw==", "dependencies": { - "@golem-sdk/golem-js": "^2.2.0", - "@golem-sdk/task-executor": "^1.0.1", - "swr": "^2.2.2" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" - } - }, - "node_modules/@golem-sdk/react/node_modules/@golem-sdk/golem-js": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/@golem-sdk/golem-js/-/golem-js-2.4.3.tgz", - "integrity": "sha512-B7NMPkjhiy7XobM0dHrNStOGOTsugS9fdMQRw1K1Opu2BOcDrlbrvDZa+m3eRw76s6akq483z2Tme5vboCtKug==", - "dependencies": { - "async-lock": "^1.4.1", - "axios": "^1.6.7", - "bottleneck": "^2.19.5", - "collect.js": "^4.36.1", - "debug": "^4.3.4", - "decimal.js-light": "^2.5.1", - "eventemitter3": "^5.0.1", - "eventsource": "^2.0.2", - "flatbuffers": "^23.5.26", - "ip-num": "^1.5.1", - "js-sha3": "^0.9.3", - "pino": "^8.19.0", - "pino-pretty": "^10.3.1", - "semver": "^7.5.4", - "tmp": "^0.2.2", - "uuid": "^9.0.1", - "ws": "^8.16.0", - "ya-ts-client": "^0.5.3" + "pino": "^8.20.0", + "pino-pretty": "^11.0.0" }, "engines": { "node": ">=18.0.0" }, - "optionalDependencies": { - "@rollup/rollup-darwin-x64": "^4", - "@rollup/rollup-win32-arm64-msvc": "^4", - "@rollup/rollup-win32-x64-msvc": "^4" - } - }, - "node_modules/@golem-sdk/react/node_modules/ya-ts-client": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/ya-ts-client/-/ya-ts-client-0.5.3.tgz", - "integrity": "sha512-jwJmgmrb39NW/IKPjoH+ISKMCDna2Q9ylfmqQwVToKiOIrsnzt37ExxW6WxWrjJ5IZ8AkYfXQMOa2WRDvyZrJA==", - "dependencies": { - "axios": "^0.21.4" - } - }, - "node_modules/@golem-sdk/react/node_modules/ya-ts-client/node_modules/axios": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", - "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", - "dependencies": { - "follow-redirects": "^1.14.0" - } - }, - "node_modules/@golem-sdk/task-executor": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@golem-sdk/task-executor/-/task-executor-1.4.0.tgz", - "integrity": "sha512-biUd9FC0Kx1iGfyQ9qkM+SWNbkXKgORaqZbLZCf/wW1bIzdo/vUSuTOy1iNbS3Gx2L/OGxLUeeD34nbQdqA6MQ==", - "dependencies": { - "@golem-sdk/golem-js": "^2.4.3", - "eventemitter3": "^5.0.1" - }, - "engines": { - "node": ">=18.0.0" + "peerDependencies": { + "@golem-sdk/golem-js": "<4" } }, - "node_modules/@golem-sdk/task-executor/node_modules/@golem-sdk/golem-js": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/@golem-sdk/golem-js/-/golem-js-2.4.3.tgz", - "integrity": "sha512-B7NMPkjhiy7XobM0dHrNStOGOTsugS9fdMQRw1K1Opu2BOcDrlbrvDZa+m3eRw76s6akq483z2Tme5vboCtKug==", + "node_modules/@golem-sdk/pino-logger/node_modules/pino-pretty": { + "version": "11.2.1", + "resolved": "https://registry.npmjs.org/pino-pretty/-/pino-pretty-11.2.1.tgz", + "integrity": "sha512-O05NuD9tkRasFRWVaF/uHLOvoRDFD7tb5VMertr78rbsYFjYp48Vg3477EshVAF5eZaEw+OpDl/tu+B0R5o+7g==", "dependencies": { - "async-lock": "^1.4.1", - "axios": "^1.6.7", - "bottleneck": "^2.19.5", - "collect.js": "^4.36.1", - "debug": "^4.3.4", - "decimal.js-light": "^2.5.1", - "eventemitter3": "^5.0.1", - "eventsource": "^2.0.2", - "flatbuffers": "^23.5.26", - "ip-num": "^1.5.1", - "js-sha3": "^0.9.3", - "pino": "^8.19.0", - "pino-pretty": "^10.3.1", - "semver": "^7.5.4", - "tmp": "^0.2.2", - "uuid": "^9.0.1", - "ws": "^8.16.0", - "ya-ts-client": "^0.5.3" - }, - "engines": { - "node": ">=18.0.0" + "colorette": "^2.0.7", + "dateformat": "^4.6.3", + "fast-copy": "^3.0.2", + "fast-safe-stringify": "^2.1.1", + "help-me": "^5.0.0", + "joycon": "^3.1.1", + "minimist": "^1.2.6", + "on-exit-leak-free": "^2.1.0", + "pino-abstract-transport": "^1.0.0", + "pump": "^3.0.0", + "readable-stream": "^4.0.0", + "secure-json-parse": "^2.4.0", + "sonic-boom": "^4.0.1", + "strip-json-comments": "^3.1.1" }, - "optionalDependencies": { - "@rollup/rollup-darwin-x64": "^4", - "@rollup/rollup-win32-arm64-msvc": "^4", - "@rollup/rollup-win32-x64-msvc": "^4" - } - }, - "node_modules/@golem-sdk/task-executor/node_modules/ya-ts-client": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/ya-ts-client/-/ya-ts-client-0.5.3.tgz", - "integrity": "sha512-jwJmgmrb39NW/IKPjoH+ISKMCDna2Q9ylfmqQwVToKiOIrsnzt37ExxW6WxWrjJ5IZ8AkYfXQMOa2WRDvyZrJA==", - "dependencies": { - "axios": "^0.21.4" + "bin": { + "pino-pretty": "bin.js" } }, - "node_modules/@golem-sdk/task-executor/node_modules/ya-ts-client/node_modules/axios": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", - "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", + "node_modules/@golem-sdk/pino-logger/node_modules/sonic-boom": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-4.0.1.tgz", + "integrity": "sha512-hTSD/6JMLyT4r9zeof6UtuBDpjJ9sO08/nmS5djaA9eozT9oOlNdpXSnzcgj4FTqpk3nkLrs61l4gip9r1HCrQ==", "dependencies": { - "follow-redirects": "^1.14.0" + "atomic-sleep": "^1.0.0" } }, "node_modules/@humanwhocodes/config-array": { @@ -4838,11 +4816,6 @@ "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==", "dev": true }, - "node_modules/collect.js": { - "version": "4.36.1", - "resolved": "https://registry.npmjs.org/collect.js/-/collect.js-4.36.1.tgz", - "integrity": "sha512-jd97xWPKgHn6uvK31V6zcyPd40lUJd7gpYxbN2VOVxGWO4tyvS9Li4EpsFjXepGTo2tYcOTC4a8YsbQXMJ4XUw==" - }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -6358,11 +6331,6 @@ "node": "^10.12.0 || >=12.0.0" } }, - "node_modules/flatbuffers": { - "version": "23.5.26", - "resolved": "https://registry.npmjs.org/flatbuffers/-/flatbuffers-23.5.26.tgz", - "integrity": "sha512-vE+SI9vrJDwi1oETtTIFldC/o9GsVKRM+s6EL0nQgxXlYV1Vc4Tk30hj4xGICftInKQKj1F3up2n8UbIVobISQ==" - }, "node_modules/flatted": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", @@ -12196,30 +12164,6 @@ "split2": "^4.0.0" } }, - "node_modules/pino-pretty": { - "version": "10.3.1", - "resolved": "https://registry.npmjs.org/pino-pretty/-/pino-pretty-10.3.1.tgz", - "integrity": "sha512-az8JbIYeN/1iLj2t0jR9DV48/LQ3RC6hZPpapKPkb84Q+yTidMCpgWxIT3N0flnBDilyBQ1luWNpOeJptjdp/g==", - "dependencies": { - "colorette": "^2.0.7", - "dateformat": "^4.6.3", - "fast-copy": "^3.0.0", - "fast-safe-stringify": "^2.1.1", - "help-me": "^5.0.0", - "joycon": "^3.1.1", - "minimist": "^1.2.6", - "on-exit-leak-free": "^2.1.0", - "pino-abstract-transport": "^1.0.0", - "pump": "^3.0.0", - "readable-stream": "^4.0.0", - "secure-json-parse": "^2.4.0", - "sonic-boom": "^3.0.0", - "strip-json-comments": "^3.1.1" - }, - "bin": { - "pino-pretty": "bin.js" - } - }, "node_modules/pino-std-serializers": { "version": "6.2.2", "resolved": "https://registry.npmjs.org/pino-std-serializers/-/pino-std-serializers-6.2.2.tgz", @@ -14418,18 +14362,6 @@ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", "dev": true }, - "node_modules/uuid": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", - "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", - "funding": [ - "https://github.com/sponsors/broofa", - "https://github.com/sponsors/ctavan" - ], - "bin": { - "uuid": "dist/bin/uuid" - } - }, "node_modules/v8-compile-cache-lib": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", diff --git a/src/new/new.action.ts b/src/new/new.action.ts index c928674..5deff44 100644 --- a/src/new/new.action.ts +++ b/src/new/new.action.ts @@ -56,12 +56,10 @@ async function getTemplate(providedTemplate?: string): Promise { { name: "js-node", hint: "Plain Javascript CLI application (CommonJS)" }, { name: "js-node-esm", hint: "Plain Javascript CLI application (ESM)" }, { - name: "(coming soon) react-js", + name: "react-js", hint: "React web application (with Vite and plain Javascript)", - disabled: true, }, - { name: "(coming soon) react-ts", hint: "React web application (with Vite and Typescript)", disabled: true }, - // { name: "js-webapp", hint: "Plain Javascript Express based web application" }, + { name: "react-ts", hint: "React web application (with Vite and Typescript)" }, ], })) as { template: string };