commit
						736d0c6a9a
					
				
							
								
								
									
										1
									
								
								.gitingore
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								.gitingore
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1 @@ | ||||
| deno.lock | ||||
							
								
								
									
										3
									
								
								.vscode/settings.json
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.vscode/settings.json
									
									
									
									
										vendored
									
									
								
							| @ -1,4 +1,3 @@ | ||||
| { | ||||
|     "deno.enable": true, | ||||
|     "deno.unstable": true | ||||
|     "deno.enable": true | ||||
| } | ||||
							
								
								
									
										4
									
								
								app.tsx
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								app.tsx
									
									
									
									
									
								
							| @ -1 +1,3 @@ | ||||
| export default ()=>{}; | ||||
| export default ()=><div> | ||||
|     <h1>App!</h1> | ||||
| </div>; | ||||
							
								
								
									
										222
									
								
								checker.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										222
									
								
								checker.tsx
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,222 @@ | ||||
| import { parse as JSONC } from "https://deno.land/x/jsonct@v0.1.0/mod.ts"; | ||||
| 
 | ||||
| type ConfigCheck = {path?:string, text?:string, json?:Record<string, string|Record<string, string|string[]>>}; | ||||
| type ConfigCheckPair = [config:ConfigCheck, imports:ConfigCheck]; | ||||
| 
 | ||||
| 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 | ||||
|     { | ||||
|         path = "deno.json" | ||||
|         resp = await fetch(Root + "/" + path); | ||||
|         text = await resp.text(); | ||||
|     } | ||||
|     catch(e) | ||||
|     { | ||||
|         try | ||||
|         { | ||||
|             path = "deno.jsonc"; | ||||
|             resp = await fetch(Root + "/" + path); | ||||
|             text = await resp.text(); | ||||
|         } | ||||
|         catch(e) | ||||
|         { | ||||
|             try | ||||
|             { | ||||
|                 path = ".vscode/settings.json"; | ||||
|                 resp = await fetch(Root + "/" + path); | ||||
|                 json = await resp.json(); | ||||
| 
 | ||||
|                 path = json["deno.config"]; | ||||
|                 json = undefined; | ||||
|                 if(path) | ||||
|                 { | ||||
|                     resp = await fetch(Root + "/" + path); | ||||
|                     text = await resp.text(); | ||||
|                 } | ||||
|             } | ||||
|             catch(e) | ||||
|             { | ||||
|                 path = ""; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     if(path) | ||||
|     { | ||||
|         try | ||||
|         { | ||||
|             json = JSONC(text); | ||||
|         } | ||||
|         catch(e) | ||||
|         { | ||||
|             json = undefined; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     let imports:ConfigCheck = {}; | ||||
|     if(json && json.imports) | ||||
|     { | ||||
|         // config.imports
 | ||||
|         imports.json = json; | ||||
|         imports.text = JSON.stringify(json); | ||||
|         imports.path = path; | ||||
|     } | ||||
|     else if(json && !json.imports && json.importMap) | ||||
|     { | ||||
|         // config.importMap
 | ||||
|         try | ||||
|         { | ||||
|             imports.path = json.importMap; | ||||
|             resp = await fetch(Root + "/" + imports.path); | ||||
|             imports.text = await resp.text(); | ||||
|             try | ||||
|             { | ||||
|                 imports.json = JSONC(imports.text); | ||||
|             } | ||||
|             catch(e) | ||||
|             { | ||||
|                 imports.json = undefined; | ||||
|             } | ||||
|         } | ||||
|         catch(e) | ||||
|         { | ||||
|             // malformed import map
 | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     return [{path, text, json}, imports] as ConfigCheckPair | ||||
| } | ||||
| 
 | ||||
| export async function Install(file:string, overrideName?:string, handler?:(content:string)=>string) | ||||
| { | ||||
|     const pathFile = RootHost + "install__/" + file; | ||||
| 
 | ||||
|     try{ | ||||
|         const check = await Deno.readTextFile(Deno.cwd()+"/"+file); | ||||
|         const replace = confirm(`⚠️🚧 The file "${file}" already exists. Replace it?`); | ||||
|         if(replace) | ||||
|         { | ||||
|             throw("") | ||||
|         } | ||||
|         console.log(`Using pre-existing "${file}" for now.`); | ||||
|     } | ||||
|     catch(e) | ||||
|     { | ||||
|         const resp = await fetch(pathFile); | ||||
|         const text = await resp.text(); | ||||
|         const name = overrideName || file; | ||||
|         await Deno.writeTextFile(Deno.cwd()+"/"+name, handler ? handler(text) : text);    | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| export async function Check() | ||||
| { | ||||
|     let [config, imports] = await HuntConfig(); | ||||
|     try | ||||
|     { | ||||
|          | ||||
|         //console.log(config, imports);
 | ||||
|         if(!config.path) | ||||
|         { | ||||
|             console.log(`🛠️ No Deno configuration found. Creating "deno.json" now.`); | ||||
|             await Deno.writeTextFile(Deno.cwd()+"/deno.json", `{"imports":{}}`);    | ||||
|             Check(); | ||||
|             return; | ||||
|         } | ||||
|         else if(!config.json) | ||||
|         { | ||||
|             if(confirm(`🚧 Deno configuration is malformed. Replace "${config.path}" with a new one?.`)) | ||||
|             { | ||||
|                 await Deno.writeTextFile(Deno.cwd()+"/"+config.path, `{"imports":{}}`);    | ||||
|                 Check(); | ||||
|                 return; | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 throw("⛔ Invalid configuration."); | ||||
|             } | ||||
|         } | ||||
|         else if(!imports.json) | ||||
|         {         | ||||
|             if(imports.path != config.path) | ||||
|             { | ||||
|                 if(confirm(`🚧 External import map "${imports.path}" is missing or malformed. Replace it with defaults?.`)) | ||||
|                 { | ||||
|                     await Deno.writeTextFile(Deno.cwd()+"/"+imports.path, `{"imports":{}}`);    | ||||
|                     Check(); | ||||
|                     return; | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     throw("⛔ Invalid configuration."); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         else if(!imports.json?.imports) | ||||
|         { | ||||
|             imports.json.imports = {}; | ||||
|         } | ||||
| 
 | ||||
|         if(config.json && imports.json?.imports) | ||||
|         { | ||||
|             const importMap = imports.json.imports as Record<string, string>; | ||||
|             const bake =async(obj:ConfigCheck)=> await Deno.writeTextFile(Deno.cwd()+"/"+obj.path, JSON.stringify(obj.json, null, "\t"));  | ||||
| 
 | ||||
|             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"]) | ||||
|             { | ||||
|                 importMap[">able/app.tsx"] = `./app.tsx`; | ||||
|                 await Install("app.tsx"); | ||||
|             } | ||||
|             if(!importMap[">able/api.tsx"]) | ||||
|             { | ||||
|                 if(confirm(`🤔 OPTIONAL: Add backend ">able/api.tsx"?`)) | ||||
|                 { | ||||
|                     importMap[">able/api.tsx"] = "./api.tsx"; | ||||
|                     await Install("api.tsx"); | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             const tasks:Record<string, string> = { | ||||
|                 "check": `deno run -A --no-lock ${RootHost}cli.tsx check`, | ||||
|                 "local": `deno run -A --no-lock ${RootHost}cli.tsx local`, | ||||
|                 "debug": `deno run -A --no-lock ${RootHost}cli.tsx debug`, | ||||
|                 "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<string, string>; | ||||
|             config.json.tasks = {...confTasks, ...tasks}; | ||||
| 
 | ||||
|             const options =  | ||||
|             { | ||||
|                 "lib": ["deno.window", "dom", "dom.asynciterable"], | ||||
|                 "jsx": "react-jsx", | ||||
|                 "jsxImportSource": "react" | ||||
|             } | ||||
|             const compOpts = config.json.compilerOptions as Record<string, string|string[]> || {}; | ||||
|             const compLib:string[] = compOpts.lib as string[] || []; | ||||
|             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) | ||||
|     { | ||||
|         console.log(e, "\n (Able Exiting...)"); | ||||
|         Deno.exit(); | ||||
|     } | ||||
|     console.log(`🚗 Good to go!`); | ||||
| 
 | ||||
| } | ||||
							
								
								
									
										136
									
								
								cli.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										136
									
								
								cli.tsx
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,136 @@ | ||||
| import * as Env from "https://deno.land/std@0.194.0/dotenv/mod.ts"; | ||||
| import * as Arg from "https://deno.land/std@0.194.0/flags/mod.ts"; | ||||
| import { RootHost, HuntConfig, Install, Check } from "./checker.tsx"; | ||||
| 
 | ||||
| let arg = await Arg.parse(Deno.args); | ||||
| let env = await Env.load(); | ||||
| const collect =async(inKey:string, inArg:Record<string, string>, inEnv:Record<string, string>):Promise<string|undefined>=> | ||||
| { | ||||
|     const scanArg = inArg[inKey]; | ||||
|     const scanEnvFile = inEnv[inKey]; | ||||
|     const scanEnvDeno = Deno.env.get(inKey); | ||||
| 
 | ||||
|     if(scanArg) | ||||
|     { | ||||
|         console.log(`Using "${inKey}" from passed argument.`); | ||||
|         return scanArg; | ||||
|     } | ||||
|     if(scanEnvFile) | ||||
|     { | ||||
|         console.log(`Using "${inKey}" from .env file.`); | ||||
|         return scanEnvFile; | ||||
|     } | ||||
|     if(scanEnvDeno) | ||||
|     { | ||||
|         console.log(`Using "${inKey}" from environment variable.`); | ||||
|         return scanEnvDeno; | ||||
|     } | ||||
| 
 | ||||
|     const scanUser = prompt(`No "${inKey}" found. Enter one here:`); | ||||
|     if(!scanUser || scanUser?.length < 3) | ||||
|     { | ||||
|         console.log("Exiting..."); | ||||
|         Deno.exit(); | ||||
|     } | ||||
|     return scanUser; | ||||
| }; | ||||
| 
 | ||||
| export async function SubProcess(args:string[]) | ||||
| { | ||||
|     const command = new Deno.Command( | ||||
|         `deno`, | ||||
|         { | ||||
|             args, | ||||
|             stdin: "piped", | ||||
|             stdout: "piped" | ||||
|         } | ||||
|     ); | ||||
| 
 | ||||
|     const child = command.spawn(); | ||||
| 
 | ||||
|     // open a file and pipe the subprocess output to it.
 | ||||
|     const writableStream = new WritableStream({ | ||||
|         write(chunk: Uint8Array): Promise<void> { | ||||
|             Deno.stdout.write(chunk); | ||||
|             return Promise.resolve(); | ||||
|         }, | ||||
|     }); | ||||
|     child.stdout.pipeTo(writableStream); | ||||
| 
 | ||||
|     // manually close stdin
 | ||||
|     child.stdin.close(); | ||||
|     const status = await child.status;     | ||||
|      | ||||
|     return status; | ||||
| } | ||||
| 
 | ||||
| if(arg._.length) | ||||
| { | ||||
| 
 | ||||
|     const [config, imports] = await HuntConfig(); | ||||
| 
 | ||||
|     console.log("able subprocesses running with ", config.path); | ||||
| 
 | ||||
|     switch(arg._[0]) | ||||
|     { | ||||
|         case "check" : | ||||
|         case "setup" : | ||||
|         { | ||||
|             await Check(); | ||||
|             break; | ||||
|         } | ||||
| 
 | ||||
|         case "local" : | ||||
|         { | ||||
|             await SubProcess(["run", `-A`, `--no-lock`, `--config=${config.path}`, RootHost+"run.tsx", "--dev", ...Deno.args]); | ||||
|             break; | ||||
|         } | ||||
|         case "debug" : | ||||
|         { | ||||
|             await SubProcess(["run", `-A`, `--no-lock`, `--config=${config.path}`, `--inspect-brk`, RootHost+"run.tsx", "--dev", ...Deno.args]); | ||||
|             break; | ||||
|         } | ||||
|         case "serve" : | ||||
|         { | ||||
|             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" : | ||||
|         { | ||||
|             let useToken = await collect("DENO_DEPLOY_TOKEN", arg, env); | ||||
|             let useProject = await collect("DENO_DEPLOY_PROJECT", arg, env); | ||||
|              | ||||
|             let scanProd:string[]|string|null = prompt(`Do you want to deploy to *production*?`); | ||||
|             if(scanProd) | ||||
|             { | ||||
|                 scanProd = prompt(`Are you sure? This will update the live project at "${useProject}"`); | ||||
|                 scanProd = scanProd ? ["--prod"] : []; | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 scanProd = []; | ||||
|             } | ||||
| 
 | ||||
|             await SubProcess([ | ||||
|                 "run", | ||||
|                 "-A", | ||||
|                 "--no-lock", | ||||
|                 `--config=${config.path}`, | ||||
|                 "https://deno.land/x/deploy/deployctl.ts", | ||||
|                 "deploy", | ||||
|                 `--project=${useProject}`, | ||||
|                 `--token=${useToken}`, | ||||
|                 `--import-map=${imports.path}`, | ||||
|                 RootHost+"run.tsx", | ||||
|                 ...scanProd, | ||||
|                 ...Deno.args]); | ||||
|         } | ||||
|         case "upgrade" : | ||||
|         { | ||||
|             await SubProcess(["install", `-A`, `-r`, `-f`, `--no-lock`, `--config=${config.path}`, RootHost+"cli.tsx", ...Deno.args]); | ||||
|             break; | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										26
									
								
								deno.jsonc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								deno.jsonc
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,26 @@ | ||||
| { | ||||
| 	"imports": { | ||||
| 		"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", | ||||
| 		"@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", | ||||
| 		"install": "deno install -A -r -f http://localhost:4507/cli.tsx" | ||||
| 	}, | ||||
| 	"compilerOptions": { | ||||
| 		"jsx": "react-jsx", | ||||
| 		"jsxImportSource": "react", | ||||
| 		"lib": [ | ||||
| 			"deno.window", | ||||
| 			"dom", | ||||
| 			"dom.asynciterable" | ||||
| 		] | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										28
									
								
								deno.lock
									
									
									
									
									
								
							
							
						
						
									
										28
									
								
								deno.lock
									
									
									
									
									
								
							| @ -1,28 +0,0 @@ | ||||
| { | ||||
|   "version": "2", | ||||
|   "remote": { | ||||
|     "http://localhost:4507/hmr-static.tsx": "b88a33a019b7a6090d05a43d15843b36fe294196c4423c753fe3654ab369f1b1", | ||||
|     "http://localhost:4507/run-local.tsx": "2c0bf9b994677f2c0bb6ef26616960f25f61e3f8b4767891a95896fb7752a74e", | ||||
|     "http://localhost:4507/run-serve.tsx": "400828ea6457485c3bfcfe3bfdd60b1844e6e66f56a3606d250ce9a7481c6ead", | ||||
|     "http://localhost:4507/run.tsx": "f7f2a90d2bda35e5de3b307e36666120439f516d88f44a4388a3251679a99e3e", | ||||
|     "https://deno.land/std@0.180.0/media_types/_db.ts": "7606d83e31f23ce1a7968cbaee852810c2cf477903a095696cdc62eaab7ce570", | ||||
|     "https://deno.land/std@0.180.0/media_types/_util.ts": "916efbd30b6148a716f110e67a4db29d6949bf4048997b754415dd7e42c52378", | ||||
|     "https://deno.land/std@0.180.0/media_types/content_type.ts": "c682589a0aeb016bfed355cc1ed6fbb3ead2ea48fc0000ac5de6a5730613ad1c", | ||||
|     "https://deno.land/std@0.180.0/media_types/extension.ts": "7a4ef2813d7182f724a941f38161525996e4a67abc3cf6a0f9bc2168d73a0f0e", | ||||
|     "https://deno.land/std@0.180.0/media_types/extensions_by_type.ts": "4358023feac696e6e9d49c0f1e76a859f03ca254df57812f31f8536890c3a443", | ||||
|     "https://deno.land/std@0.180.0/media_types/format_media_type.ts": "1e35e16562e5c417401ffc388a9f8f421f97f0ee06259cbe990c51bae4e6c7a8", | ||||
|     "https://deno.land/std@0.180.0/media_types/get_charset.ts": "8be15a1fd31a545736b91ace56d0e4c66ea0d7b3fdc5c90760e8202e7b4b1fad", | ||||
|     "https://deno.land/std@0.180.0/media_types/mod.ts": "d3f0b99f85053bc0b98ecc24eaa3546dfa09b856dc0bbaf60d8956d2cdd710c8", | ||||
|     "https://deno.land/std@0.180.0/media_types/parse_media_type.ts": "bed260d868ea271445ae41d748e7afed9b5a7f407d2777ead08cecf73e9278de", | ||||
|     "https://deno.land/std@0.180.0/media_types/type_by_extension.ts": "6076a7fc63181d70f92ec582fdea2c927eb2cfc7f9c9bee9d6add2aca86f2355", | ||||
|     "https://deno.land/std@0.180.0/media_types/vendor/mime-db.v1.52.0.ts": "6925bbcae81ca37241e3f55908d0505724358cda3384eaea707773b2c7e99586", | ||||
|     "https://esm.sh/@swc/wasm-web@1.3.62": "e077889c90bd43ad29e9cf086818efc334bdf31b933575e0c27972173053a3c6", | ||||
|     "https://esm.sh/preact@10.15.1/compat/jsx-runtime": "3f191e04473646ff8f5f76fb4378fc502a7cc892d9e147584d4f7531981bc86b", | ||||
|     "https://esm.sh/stable/preact@10.15.1/denonext/compat.js": "bad6b5b4d4fdfa5975b7a8d30410bd6877247f058e4952799fab39f66a94b8cf", | ||||
|     "https://esm.sh/stable/preact@10.15.1/denonext/compat/jsx-runtime.js": "e5c016fa258601ca873ba29188e56cede90372a0bdb52e58b0dfb801f2e2f219", | ||||
|     "https://esm.sh/stable/preact@10.15.1/denonext/hooks.js": "5c989ad368cf4f2cb3a5d7d1801843d9348c599fe3e7731d04728f7b845d724e", | ||||
|     "https://esm.sh/stable/preact@10.15.1/denonext/jsx-runtime.js": "52806054f5b3477005ab4bdc17de3d219ccc6c130d0cd803c45667b0cac2f6ed", | ||||
|     "https://esm.sh/stable/preact@10.15.1/denonext/preact.mjs": "30710ac1d5ff3711ae0c04eddbeb706f34f82d97489f61aaf09897bc75d2a628", | ||||
|     "https://esm.sh/v130/@swc/wasm-web@1.3.62/denonext/wasm-web.mjs": "57046d46c9ef1398a294ba7447034f5966e48866a05c309cccec4bb4d6e7c61b" | ||||
|   } | ||||
| } | ||||
| @ -1,19 +1,20 @@ | ||||
| { | ||||
|     "compilerOptions": { "lib": ["deno.window", "dom"], | ||||
|         "jsx": "react-jsx", | ||||
|         "jsxImportSource": "https://esm.sh/preact@10.15.1/compat" | ||||
|         "jsxImportSource": "react" | ||||
|     }, | ||||
|     "imports": | ||||
|     { | ||||
|         "react":"https://esm.sh/preact@10.15.1/compat", | ||||
|         "react/":"https://esm.sh/preact@10.15.1/compat/", | ||||
|         "react-original":"https://esm.sh/preact@10.15.1/compat", | ||||
|         "able/": "http://localhost:4507/" | ||||
| 
 | ||||
|     }, | ||||
|     "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", | ||||
|         "debug": "deno run -A --reload=http://localhost:4507 --inspect-wait --no-lock ./run-serve.tsx --port=1234", | ||||
|         "deploy":"deno run -A --no-lock --reload=http://localhost:4507 http://localhost:4507/run-deploy.tsx" | ||||
|         "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", | ||||
|     } | ||||
| } | ||||
| @ -1,56 +0,0 @@ | ||||
| import { Router, Switch, Case } from ">able/iso-elements.tsx"; | ||||
| 
 | ||||
| import React from "react"; | ||||
| 
 | ||||
| const CTXString = React.createContext("lol"); | ||||
| 
 | ||||
| type StateBinding<T> = [get:T, set:React.StateUpdater<T>]; | ||||
| const CTXState = React.createContext(null) as React.Context<StateBinding<number>|null>; | ||||
| const Outer =(props:{children:React.JSX.Element})=> | ||||
| { | ||||
|     const binding = React.useState(11); | ||||
|     return <CTXState.Provider value={binding}> | ||||
|         {props.children} | ||||
|     </CTXState.Provider> | ||||
| }; | ||||
| const Inner =()=> | ||||
| { | ||||
|     const [stateGet, stateSet] = React.useContext(CTXState) || ["default", ()=>{}]; | ||||
|     return <button onClick={e=>stateSet((old)=>old+1)}>count: {stateGet} :)</button> | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| 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 <CTXString.Provider value="intradestink"> | ||||
|         <Router.Provider> | ||||
|             <div class="my-4 font-sans"> | ||||
|                 <h1 class="font-black text-xl text-red-500">Title</h1> | ||||
|                 <h2 class="font-black text-blue-500 p-4">subtitle</h2> | ||||
|                 <p> | ||||
|                     <button onClick={e=>Dispatch(1)}>{Store.name}|{Store.age}?</button> | ||||
|                 </p> | ||||
|             </div> | ||||
|             <Outer> | ||||
|                 <Inner/> | ||||
|             </Outer> | ||||
|             <Outer> | ||||
|                 <Inner/> | ||||
|             </Outer> | ||||
|         </Router.Provider> | ||||
|     </CTXString.Provider>;          | ||||
| } | ||||
| @ -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"] | ||||
|     } | ||||
| } | ||||
| @ -1,56 +0,0 @@ | ||||
| import { Router, Switch, Case } from ">able/iso-elements.tsx"; | ||||
| 
 | ||||
| import React from "react"; | ||||
| 
 | ||||
| const CTXString = React.createContext("lol"); | ||||
| 
 | ||||
| type StateBinding<T> = [get:T, set:React.StateUpdater<T>]; | ||||
| const CTXState = React.createContext(null) as React.Context<StateBinding<number>|null>; | ||||
| const Outer =(props:{children:React.JSX.Element})=> | ||||
| { | ||||
|     const binding = React.useState(11); | ||||
|     return <CTXState.Provider value={binding}> | ||||
|         {props.children} | ||||
|     </CTXState.Provider> | ||||
| }; | ||||
| const Inner =()=> | ||||
| { | ||||
|     const [stateGet, stateSet] = React.useContext(CTXState) || ["default", ()=>{}]; | ||||
|     return <button onClick={e=>stateSet((old)=>old+1)}>count: {stateGet} :)</button> | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| 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 <CTXString.Provider value="intradestink"> | ||||
|         <Router.Provider> | ||||
|             <div class="my-4 font-sans"> | ||||
|                 <h1 class="font-black text-xl text-red-500">Title</h1> | ||||
|                 <h2 class="font-black text-blue-500 p-4">subtitle</h2> | ||||
|                 <p> | ||||
|                     <button onClick={e=>Dispatch(1)}>{Store.name}|{Store.age}?</button> | ||||
|                 </p> | ||||
|             </div> | ||||
|             <Outer> | ||||
|                 <Inner/> | ||||
|             </Outer> | ||||
|             <Outer> | ||||
|                 <Inner/> | ||||
|             </Outer> | ||||
|         </Router.Provider> | ||||
|     </CTXString.Provider>;          | ||||
| } | ||||
| @ -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" | ||||
|     } | ||||
| } | ||||
| @ -1,9 +0,0 @@ | ||||
| import Configure from ">able/run.tsx"; | ||||
| 
 | ||||
| Configure({ | ||||
|     Start:"/app.tsx", | ||||
|     Serve() | ||||
|     { | ||||
|         return false;      | ||||
|     } | ||||
| }) | ||||
							
								
								
									
										4
									
								
								install__/api.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								install__/api.tsx
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,4 @@ | ||||
| export default (req:Request):Response|false=> | ||||
| { | ||||
|     return false; | ||||
| } | ||||
							
								
								
									
										3
									
								
								install__/app.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								install__/app.tsx
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,3 @@ | ||||
| export default ()=><div> | ||||
|     <h1>App!</h1> | ||||
| </div>; | ||||
| @ -16,6 +16,10 @@ Configure({ | ||||
|             { | ||||
|                 syntax: "typescript", | ||||
|                 tsx: true, | ||||
|             }, | ||||
|             transform: | ||||
|             { | ||||
|                 react: { runtime: "automatic" } | ||||
|             } | ||||
|         } | ||||
|     }, | ||||
|  | ||||
| @ -1,70 +1,51 @@ | ||||
| import * as MIME from "https://deno.land/std@0.180.0/media_types/mod.ts"; | ||||
| import * as SWCW from "https://esm.sh/@swc/wasm-web@1.3.62"; | ||||
| 
 | ||||
| import { HuntConfig } from "./checker.tsx"; | ||||
| import CustomServe from ">able/api.tsx";  | ||||
| 
 | ||||
| export const Root = new URL(`file://${Deno.cwd().replaceAll("\\", "/")}`).toString(); | ||||
| 
 | ||||
| type DenoConfig = {imports:Record<string, string>}; | ||||
| const ImportMap:DenoConfig = {imports:{}}; | ||||
| let ImportMapOriginal = {}; | ||||
| let ImportMapProxies:Record<string, string> = {}; | ||||
| 
 | ||||
| const ImportMapReload =async()=> | ||||
| { | ||||
|     let json:DenoConfig; | ||||
|     const path = Root+"/deno.json"; | ||||
|     try | ||||
|     { | ||||
|         const resp = await fetch(path); | ||||
|         json = await resp.json(); | ||||
|         if(!json?.imports) | ||||
|         { throw new Error("imports not specified in deno.json") } | ||||
|         ImportMapOriginal = json; | ||||
|     } | ||||
|     catch(e) | ||||
|     { | ||||
|         console.log(`error reading deno config "${path}" message:"${e}"`); | ||||
|         return; | ||||
|     } | ||||
|     const [, {json, path}] = await HuntConfig(); | ||||
|     const imports = (json as DenoConfig).imports; | ||||
| 
 | ||||
|     if(!json.imports["react"]) | ||||
|     if(imports) | ||||
|     { | ||||
|         console.log(`"react" specifier not defined in import map`); | ||||
|     } | ||||
|     else if(!json.imports["react/"]) | ||||
|     { | ||||
|         json.imports["react/"] = json.imports["react"]+"/"; | ||||
|     } | ||||
| 
 | ||||
|     if(!json.imports["able:app"]) | ||||
|     { | ||||
|         console.log(`"able:app" specifier not defined in import map.`); | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     ImportMapProxies = {}; | ||||
|     Object.entries(json.imports).forEach(([key, value])=> | ||||
|     { | ||||
|         if(value.startsWith("./")) | ||||
|         { | ||||
|             json.imports[key] = value.substring(1); | ||||
|         } | ||||
|         if(key.startsWith(">")) | ||||
|         ImportMapProxies = {}; | ||||
|         Object.entries(imports).forEach(([key, value])=> | ||||
|         { | ||||
|             if(value.startsWith("./")) | ||||
|             { | ||||
|                 ImportMapProxies[encodeURI(key)] = value.substring(1); | ||||
|                 json.imports[key] = value.substring(1);  | ||||
|                 imports[key] = value.substring(1); | ||||
|             } | ||||
|             else | ||||
|             if(key.startsWith(">")) | ||||
|             { | ||||
|                 ImportMapProxies["/"+encodeURI(key)] = value; | ||||
|                 json.imports[key] = "/"+key;     | ||||
|                 if(value.startsWith("./")) | ||||
|                 { | ||||
|                     ImportMapProxies[encodeURI(key)] = value.substring(1); | ||||
|                     imports[key] = value.substring(1);  | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     ImportMapProxies["/"+encodeURI(key)] = value; | ||||
|                     imports[key] = "/"+key;     | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     }); | ||||
|         }); | ||||
| 
 | ||||
|         ImportMap.imports = Configuration.Remap(imports, Configuration); | ||||
| 
 | ||||
|     } | ||||
|     else | ||||
|     { | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     ImportMap.imports = Configuration.Remap(json.imports, Configuration); | ||||
| }; | ||||
| 
 | ||||
| export type CustomHTTPHandler = (inReq:Request, inURL:URL, inExt:string|false, inMap:{imports:Record<string, string>}, inConfig:Configuration)=>void|false|Response|Promise<Response|void|false>; | ||||
| @ -266,9 +247,9 @@ export default async()=> | ||||
|     if(running){return}; | ||||
|     running = true; | ||||
|      | ||||
|     await ImportMapReload(); | ||||
|     try | ||||
|     { | ||||
|         await ImportMapReload(); | ||||
|         await SWCW.default(); | ||||
|     } | ||||
|     catch(e) | ||||
| @ -276,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); | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user