diff --git a/.vscode/settings.json b/.vscode/settings.json index 8675ad5..b943dbc 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,4 +1,3 @@ { - "deno.enable": true, - "deno.unstable": true + "deno.enable": true } \ No newline at end of file diff --git a/checker.tsx b/checker.tsx index 01a117b..a5f1100 100644 --- a/checker.tsx +++ b/checker.tsx @@ -7,6 +7,7 @@ export const RootHost = import.meta.resolve("./"); export const Root = new URL(`file://${Deno.cwd().replaceAll("\\", "/")}`).toString(); export async function HuntConfig() { + console.log("hunting in", Root); let path:string, resp:Response, text="", json; try { @@ -116,16 +117,14 @@ export async function Install(file:string, overrideName?:string, handler?:(conte export async function Check() { let [config, imports] = await HuntConfig(); - console.log(`Checking directory "${Root}"`); - console.log("Found", config, imports); try { //console.log(config, imports); if(!config.path) { - console.log(`🛠️ No Deno configuration found. Creating "deno.jsonc" now.`); - await Deno.writeTextFile(Deno.cwd()+"/deno.jsonc", `{"imports":{}}`); + console.log(`🛠️ No Deno configuration found. Creating "deno.json" now.`); + await Deno.writeTextFile(Deno.cwd()+"/deno.json", `{"imports":{}}`); Check(); return; } @@ -168,20 +167,22 @@ export async function Check() const importMap = imports.json.imports as Record; const bake =async(obj:ConfigCheck)=> await Deno.writeTextFile(Deno.cwd()+"/"+obj.path, JSON.stringify(obj.json, null, "\t")); - if(!importMap["react"]) + importMap["react"] = `https://esm.sh/preact@10.17.1/compat`; + importMap["react/"] = `https://esm.sh/preact@10.17.1/compat/`; + importMap["@preact/signals"] = `https://esm.sh/@preact/signals@1.2.1`; + importMap[">able/"] = `${RootHost}`; + if(!importMap[">able/app.tsx"]) { - console.log(`🛠️ Adding React import specifier ("react")`); - importMap["react"] = `https://esm.sh/preact@10.16.0/compat`; - importMap["react/"] = `https://esm.sh/preact@10.16.0/compat/`; - await bake(imports); - console.log(`🚦 NOTE: Deno will need to cache "react" for intellisense to work properly.`) - + importMap[">able/app.tsx"] = `./app.tsx`; + await Install("app.tsx"); } - if(!importMap[">able/"]) + if(!importMap[">able/api.tsx"]) { - console.log(`🛠️ Adding Able import specifier (">able/").`); - importMap[">able/"] = `${RootHost}`; - await bake(imports); + if(confirm(`🤔 OPTIONAL: Add backend ">able/api.tsx"?`)) + { + importMap[">able/api.tsx"] = "./api.tsx"; + await Install("api.tsx"); + } } const tasks:Record = { @@ -191,21 +192,8 @@ export async function Check() "serve": `deno run -A --no-lock ${RootHost}cli.tsx serve`, "cloud": `deno run -A --no-lock ${RootHost}cli.tsx cloud` }; - const confTasks = (config.json.tasks || {}) as Record; - for(const key in tasks) - { - if(tasks[key] !== confTasks[key]) - { - if(confirm(`🤔 OPTIONAL: The tasks defined in your config contain missing or modified values. Update tasks?`)) - { - config.json.tasks = {...confTasks, ...tasks}; - await bake(config); - } - break; - } - } - + config.json.tasks = {...confTasks, ...tasks}; const options = { @@ -213,89 +201,15 @@ export async function Check() "jsx": "react-jsx", "jsxImportSource": "react" } - const compOpts = config.json.compilerOptions as Record || {}; - const compJSX = compOpts.jsx == options.jsx; - const compJSXImportSource = compOpts.jsxImportSource == options.jsxImportSource; const compLib:string[] = compOpts.lib as string[] || []; - let compLibHasAll = true; - options.lib.forEach(item=> !compLib.includes(item) && (compLibHasAll = false)) - - if(!compOpts || !compJSX || !compJSXImportSource || !compLibHasAll) - { - console.log(`🛠️ Adding values to "compilerOptions" configuration.`); - compOpts.jsx = options.jsx; - compOpts.jsxImportSource = options.jsxImportSource; - compOpts.lib = [...compLib, ...options.lib]; - config.json.compilerOptions = compOpts; - await bake(config); - } - - - if(!importMap[">able/app.tsx"]) - { - if(confirm(`🤔 OPTIONAL: Your import map does not override the default/empty FRONT-END app with the specifier ">able/app.tsx". Create this file and add the specifier?`)) - { - importMap[">able/app.tsx"] = `./app.tsx`; - await bake(imports); - await Install("app.tsx"); - } - } - else - { - /* - try - { - const app = await import(importMap[">able/app.tsx"]); - // @ts-ignore - const result = app.default().$$typeof; - } - catch(e) - { - console.log(e); - if(confirm(`🚧 Your FRONT-END app ("${importMap[">able/app.tsx"]}") does not export a default function that returns VDOM nodes. Replace it?`)) - { - await Install("app.tsx", importMap[">able/app.tsx"]); - } - else - { - throw("⛔ Your FRONT-END app has incorrect export types."); - } - } - */ - } - - if(!importMap[">able/api.tsx"]) - { - if(confirm(`🤔 OPTIONAL: Your import map does not override the default/empty BACK-END api with the specifier ">able/api.tsx". Create this file and add the specifier?`)) - { - importMap[">able/api.tsx"] = "./api.tsx"; - await bake(imports); - await Install("api.tsx"); - } - } - else - { - /* - try - { - const api = await import(importMap[">able/api.tsx"]); - const result = api.default(new Request(new URL("https://fake-deno-testing-domain.com/"))); - } - catch(e) - { - if(confirm(`🚧 Your starter backend app ("${importMap[">able/api.tsx"]}") does not export a default function that accepts a Request. Replace it?`)) - { - await Install("api.tsx", importMap[">able/api.tsx"]); - } - else - { - throw("⛔ Starter backend app has incorrect export types."); - } - } - */ - } + compOpts.jsx = options.jsx; + compOpts.jsxImportSource = options.jsxImportSource; + compOpts.lib = [...compLib, ...options.lib]; + config.json.compilerOptions = compOpts; + await bake(imports); + await bake(config); } } catch(e) diff --git a/cli.tsx b/cli.tsx index 8264873..13b9f3e 100644 --- a/cli.tsx +++ b/cli.tsx @@ -68,7 +68,9 @@ if(arg._.length) { const [config, imports] = await HuntConfig(); - + + console.log("able subprocesses running with ", config.path); + switch(arg._[0]) { case "check" : @@ -80,17 +82,19 @@ if(arg._.length) case "local" : { - await SubProcess(["run", `--config=${config.path}`, RootHost+"run.tsx", "--dev", ...Deno.args]); + await SubProcess(["run", `-A`, `--no-lock`, `--config=${config.path}`, RootHost+"run.tsx", "--dev", ...Deno.args]); break; } case "debug" : { - await SubProcess(["run", `--config=${config.path}`, `--inspect-brk`, RootHost+"run.tsx", "--dev", ...Deno.args]); + await SubProcess(["run", `-A`, `--no-lock`, `--config=${config.path}`, `--inspect-brk`, RootHost+"run.tsx", "--dev", ...Deno.args]); break; } case "serve" : { - await SubProcess(["run", `--config=${config.path}`, RootHost+"run.tsx", ...Deno.args]); + const args = ["run", `-A`, `--no-lock`, `--config=${config.path}`, RootHost+"run.tsx", ...Deno.args]; + console.log("args are", args); + await SubProcess(args); break; } case "cloud" : @@ -123,5 +127,10 @@ if(arg._.length) ...scanProd, ...Deno.args]); } + case "upgrade" : + { + await SubProcess(["install", `-A`, `-r`, `-f`, `--no-lock`, `--config=${config.path}`, RootHost+"cli.tsx", ...Deno.args]); + break; + } } } \ No newline at end of file diff --git a/deno.jsonc b/deno.jsonc index a1945eb..95b17a3 100644 --- a/deno.jsonc +++ b/deno.jsonc @@ -1,16 +1,18 @@ { "imports": { - "react": "https://esm.sh/preact@10.16.0/compat", - "react/": "https://esm.sh/preact@10.16.0/compat/", + "react": "https://esm.sh/preact@10.17.1/compat", + "react/": "https://esm.sh/preact@10.17.1/compat/", ">able/": "http://localhost:4507/", - ">able/app.tsx": "./app.tsx" + ">able/app.tsx": "./app.tsx", + "@preact/signals": "https://esm.sh/@preact/signals@1.2.1" }, "tasks": { "check": "deno run -A --no-lock http://localhost:4507/cli.tsx check", "local": "deno run -A --no-lock http://localhost:4507/cli.tsx local", "debug": "deno run -A --no-lock http://localhost:4507/cli.tsx debug", "serve": "deno run -A --no-lock http://localhost:4507/cli.tsx serve", - "cloud": "deno run -A --no-lock http://localhost:4507/cli.tsx cloud" + "cloud": "deno run -A --no-lock http://localhost:4507/cli.tsx cloud", + "install": "deno install -A -r -f http://localhost:4507/cli.tsx" }, "compilerOptions": { "jsx": "react-jsx", diff --git a/example-config/app.tsx b/example-config/app.tsx deleted file mode 100644 index 88f14aa..0000000 --- a/example-config/app.tsx +++ /dev/null @@ -1,56 +0,0 @@ -import { Router, Switch, Case } from ">able/iso-elements.tsx"; - -import React from "react"; - -const CTXString = React.createContext("lol"); - -type StateBinding = [get:T, set:React.StateUpdater]; -const CTXState = React.createContext(null) as React.Context|null>; -const Outer =(props:{children:React.JSX.Element})=> -{ - const binding = React.useState(11); - return - {props.children} - -}; -const Inner =()=> -{ - const [stateGet, stateSet] = React.useContext(CTXState) || ["default", ()=>{}]; - return -}; - - -type Store = {name:string, age:number} -const reducer =(inState:Store, inAction:number)=> -{ - return {...inState, age:inState.age+inAction}; -} - -const builder =(inState:Store):Store=> -{ - inState.age = 100; - return inState; -} - - -export default ()=> -{ - const [Store, Dispatch] = React.useReducer(reducer, {name:"seth", age:24} as Store, builder) - return - -
-

Title

-

subtitle

-

- -

-
- - - - - - -
-
; -} diff --git a/example-config/deno.json b/example-config/deno.json deleted file mode 100644 index ae6483b..0000000 --- a/example-config/deno.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "imports": - { - "react": "https://esm.sh/preact@10.15.1/compat", - ">able/": "http://localhost:4507/", - ">able/app.tsx": "./app.tsx" - }, - "tasks": - { - "serve": "deno run -A --no-lock --config=deno.json --reload=http://localhost:4507 http://localhost:4507/run.tsx", - "local": "deno run -A --no-lock --config=deno.json --reload=http://localhost:4507 http://localhost:4507/run.tsx --dev", - "debug": "deno run -A --no-lock --config=deno.json --reload=http://localhost:4507 --inspect-wait http://localhost:4507/run.tsx", - "cloud": "deno run -A --no-lock --config=deno.json --reload=http://localhost:4507 http://localhost:4507/run.tsx --dep" - }, - "compilerOptions": - { - "lib": ["deno.window", "dom"] - } -} \ No newline at end of file diff --git a/example-script/app.tsx b/example-script/app.tsx deleted file mode 100644 index 88f14aa..0000000 --- a/example-script/app.tsx +++ /dev/null @@ -1,56 +0,0 @@ -import { Router, Switch, Case } from ">able/iso-elements.tsx"; - -import React from "react"; - -const CTXString = React.createContext("lol"); - -type StateBinding = [get:T, set:React.StateUpdater]; -const CTXState = React.createContext(null) as React.Context|null>; -const Outer =(props:{children:React.JSX.Element})=> -{ - const binding = React.useState(11); - return - {props.children} - -}; -const Inner =()=> -{ - const [stateGet, stateSet] = React.useContext(CTXState) || ["default", ()=>{}]; - return -}; - - -type Store = {name:string, age:number} -const reducer =(inState:Store, inAction:number)=> -{ - return {...inState, age:inState.age+inAction}; -} - -const builder =(inState:Store):Store=> -{ - inState.age = 100; - return inState; -} - - -export default ()=> -{ - const [Store, Dispatch] = React.useReducer(reducer, {name:"seth", age:24} as Store, builder) - return - -
-

Title

-

subtitle

-

- -

-
- - - - - - -
-
; -} diff --git a/example-script/deno.json b/example-script/deno.json deleted file mode 100644 index c8e26a5..0000000 --- a/example-script/deno.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "compilerOptions": { "lib": ["deno.window", "dom"] }, - "imports": - { - "react": "https://esm.sh/preact@10.15.1/compat", - ">able/": "http://localhost:4507/" - }, - "tasks": - { - "local": "deno run -A --no-lock --reload=http://localhost:4507 run__.tsx --dev", - "serve": "deno run -A --no-lock --reload=http://localhost:4507 run__.tsx", - "debug": "deno run -A --no-lock --reload=http://localhost:4507 --inspect-wait run__.tsx", - "cloud": "deno run -A --no-lock --reload=http://localhost:4507 run__.tsx --dep" - } -} \ No newline at end of file diff --git a/example-script/run__.tsx b/example-script/run__.tsx deleted file mode 100644 index 8bc8091..0000000 --- a/example-script/run__.tsx +++ /dev/null @@ -1,9 +0,0 @@ -import Configure from ">able/run.tsx"; - -Configure({ - Start:"/app.tsx", - Serve() - { - return false; - } -}) \ No newline at end of file diff --git a/install__/deno.jsonc b/install__/deno.jsonc deleted file mode 100644 index de8f769..0000000 --- a/install__/deno.jsonc +++ /dev/null @@ -1,43 +0,0 @@ -{ - "imports": - { - "react":"https://esm.sh/preact@10.15.1/compat", // (required) Specifier for 'react' - "react/":"https://esm.sh/preact@10.15.1/compat/", // (conditional) This allows the use of JSX without explicitly importing React into a module. If you choose to remove this (and make importing react required), also remove "jsx" and "jsxImportSource" from "compilerOptions" (below) - ">able/": "{{server}}", // (required) Specifier 'able'. (See note below about "isomorphic proxies") - {{commentApp}}">able/app.tsx": "{{app}}", - {{commentApi}}">able/api.tsx": "{{api}}" - }, - - "tasks": - { - "local": "deno run -A --reload=http://localhost:4507 --no-lock ./run-local.tsx --port=1234", - "serve": "deno run -A --reload=http://localhost:4507 --no-lock ./run-serve.tsx --port=1234", - "cloud": "deno run -A --reload=http://localhost:4507 --no-lock ./run-deploy.tsx", - "debug": "deno run -A --reload=http://localhost:4507 --no-lock --inspect-wait ./run-serve.tsx --port=1234" - }, - - "compilerOptions": - { - "lib": ["deno.window", "dom"], // makes the Deno Language Server OK with browser-specific code - "jsx": "react-jsx", // see "react/" import above - "jsxImportSource": "react" // ^ - } - -/* - - Imports prefixed with ">" are "isomorphic proxies." - In addition to functioning normally as bare module specifiers for Deno, **these imports are added as routes when the server starts**. - Assuming the specifier points to remotely a hosted directory containing typescript files, requests to your running Able server on these proxy routes are actually fetched from the remote, then transpiled (and cached), then send back as a response. - For example, after the Able server starts, if it sees a web request to '/>able/iso-elements.tsx' it would actually return a browser-friendly transpiled copy of what was on the remote. - Conversely, if the Deno Language Server were to see: `import * as Iso from ">able/iso-elements.tsx";` in one of your modules, - that will be resolved normally with the import map and Deno will just receive the tsx file as-is from the remote, typings and all, so intellisense will work in your IDE. - - While ">able/" is a required "import proxy" to pull in Able source code, you are free to use this convention to also add your own proxies as you see fit. - E.g. adding this record to imports: - ">your-import/": "https://raw.githubusercontent.com/your-name/your-lib/master/" - will give both Deno and browsers running your Able project everything they need - import CoolComponent from ">your-import/cc.tsx"; - ... - -*/ -} \ No newline at end of file diff --git a/run-local.tsx b/run-local.tsx index bef5370..94553e5 100644 --- a/run-local.tsx +++ b/run-local.tsx @@ -16,6 +16,10 @@ Configure({ { syntax: "typescript", tsx: true, + }, + transform: + { + react: { runtime: "automatic" } } } }, diff --git a/run-serve.tsx b/run-serve.tsx index 78bbb24..74e81a5 100644 --- a/run-serve.tsx +++ b/run-serve.tsx @@ -5,7 +5,6 @@ import CustomServe from ">able/api.tsx"; export const Root = new URL(`file://${Deno.cwd().replaceAll("\\", "/")}`).toString(); - type DenoConfig = {imports:Record}; const ImportMap:DenoConfig = {imports:{}}; let ImportMapProxies:Record = {}; @@ -248,9 +247,9 @@ export default async()=> if(running){return}; running = true; - await ImportMapReload(); try { + await ImportMapReload(); await SWCW.default(); } catch(e) @@ -258,7 +257,6 @@ export default async()=> console.log("swc init error:", e); } - const server = Deno.serve({port:parseInt(Deno.env.get("port")||"8000")}, async(req: Request)=> { const url:URL = new URL(req.url);