wdwh 1.12.7 → 1.12.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,6 +1,12 @@
1
- # WDWH (Easyer web dev without html)
1
+ # WDWH (Easier web dev without html)
2
2
 
3
- Works only with Bun runtime
3
+ The Bun frontend framework.
4
+ Designed to simplify static-site web development using TypeScript and Bun runtime.
5
+ The framework automatically converts `src/app/**/index.tsx` pages into HTML
6
+ during build, supports multi‑page projects, and bundles client-side code with
7
+ tailwind CSS.
8
+ For development you need the Bun runtime.
9
+ [Install bun](https://bun.com/docs/installation)
4
10
 
5
11
  ## Init project
6
12
 
@@ -29,9 +35,18 @@ bun i wdwh@latest
29
35
 
30
36
  ### 3. [Add files](https://github.com/kubashh/wdwh/tree/main/template/template)
31
37
 
32
- - `src/app/index.tsx` (contains only `html` `head` `body` tags and `metadata`)
33
- - `src/app/App.tsx` (app entry point)
38
+ - `src/app/index.tsx` and additional `src/app/` subfolders **all**
39
+ `index.tsx` files are treated as separate pages and will produce
40
+ `/dist/index.html`, `/dist/foo/index.html`, etc.
41
+ - `src/app/App.tsx`
34
42
  - `src/app/react.svg` (favicon, can be any other image, bun path must be specify in `src/app/index.tsx`)
35
43
  - `src/app/global.css` (must contain `@import "tailwindcss";`)
36
44
  - `package.json` (with scripts `dev` `build`)
37
- - `tsconfig.json` (for `typescript`)
45
+ - `tsconfig.json` (for `typescript`). The framework ships with strict
46
+ settings and checks every page file during build.
47
+
48
+ ### Optional helper utilities
49
+
50
+ - You can use built‑in helpers such as `useUrl()` (client side hook that
51
+ returns the current path) and other future `comptime` helpers for compiling
52
+ data at build time. Extend them by editing `src/lib/*` or adding plugins.
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "wdwh",
3
- "version": "1.12.7",
3
+ "version": "1.12.10",
4
4
  "author": "kubashh",
5
- "description": "The Bun framework. Easyer web dev without html for static sites",
5
+ "description": "The Bun Frontend Framework.",
6
6
  "license": "MIT",
7
7
  "repository": "https://github.com/kubashh/wdwh",
8
8
  "keywords": [
@@ -17,14 +17,13 @@
17
17
  "files": [
18
18
  "LICENSE",
19
19
  "README.md",
20
- "index.d.ts",
21
20
  "hooks.js",
22
21
  "hooks.d.ts",
23
22
  "signal.js",
24
23
  "signal.d.ts"
25
24
  ],
26
25
  "scripts": {
27
- "dev": "bun dev/dev.ts",
26
+ "dev": "clear && bun dev/dev.ts",
28
27
  "build": "bun dev/scripts.ts",
29
28
  "pub": "bun dev/scripts.ts pub",
30
29
  "zip": "zip -r template/template.zip template/template"
@@ -36,7 +35,7 @@
36
35
  "bun-plugin-tailwind": "latest"
37
36
  },
38
37
  "devDependencies": {
39
- "@types/bun": "^1.3.9",
38
+ "@types/bun": "^1.3.10",
40
39
  "@types/react": "^19.2.14",
41
40
  "tailwindcss": "^4.2.1",
42
41
  "typescript": "^5.9.3",
package/signal.d.ts CHANGED
@@ -1,9 +1,10 @@
1
- type Void = () => void;
1
+ type Listener = () => void;
2
2
  export type Signal<T> = {
3
- refresh: Void;
4
- bind: (fn?: Void) => void;
5
- value: T;
3
+ get(): T;
4
+ set(value: T): void;
5
+ forceRefresh(): void;
6
+ subscribe(listener: Listener): () => void;
6
7
  };
7
- export declare function signal<T>(v: T): Signal<T>;
8
- export declare function useSignal<T>(v: T, f?: Void): Signal<T>;
8
+ export declare function createSignal<T>(initial: T): Signal<T>;
9
+ export declare function useSignal<T>(signal: Signal<T>): T;
9
10
  export {};
package/signal.js CHANGED
@@ -1,2 +1,2 @@
1
1
  // @bun
2
- import{useState as s}from"react";function o(e){return s(e)[0]}function n(){let e=s(!1)[1];return()=>e((r)=>!r)}class t{v;refresh=()=>{throw Error("Refresh not bind!")};constructor(e){this.v=e}bind(e){if(e){let r=n();this.refresh=()=>{e(),r()}}else this.refresh=n()}get value(){return this.v}set value(e){this.v=e,this.refresh?.()}}function f(e){return new t(e)}function T(e,r){let i=o(new t(e));return i.bind(r),i}export{T as useSignal,f as signal};
2
+ import{useSyncExternalStore as o}from"react";function u(t){let r=t,i=new Set;return{get(){return r},set(e){let n=typeof e==="function"?e(r):e;if(Object.is(r,n))return;r=n,i.forEach((s)=>s())},forceRefresh(){i.forEach((e)=>e())},subscribe(e){return i.add(e),()=>i.delete(e)}}}function T(t){return o(t.subscribe,t.get)}export{T as useSignal,u as createSignal};
package/wdwh.js CHANGED
@@ -1,11 +1,11 @@
1
1
  #!/usr/bin/env bun
2
2
  // @bun
3
- import{cpSync as D,existsSync as g,rmSync as P}from"fs";import f from"path";var q=`import { createRoot } from "react-dom/client";
3
+ import{cpSync as F,existsSync as o,rmSync as P}from"fs";import d from"path";var X=`import { createRoot } from "react-dom/client";
4
4
  import "../../../src/app/global.css";
5
5
  import App from "APP_PATH";
6
6
 
7
7
  createRoot(document.getElementsByTagName("body")[0]).render(<App />);
8
- `;var B=`import index from "./index.html";
8
+ `;var O=`import index from "./index.html";
9
9
 
10
10
  const { url } = Bun.serve({
11
11
  routes: { "/*": index },
@@ -13,15 +13,15 @@ const { url } = Bun.serve({
13
13
  });
14
14
 
15
15
  process.send?.(\`> Server running at \${url}\`);
16
- `;var V=`
16
+ `;var L=`
17
17
  [serve.static]
18
18
  plugins = ["bun-plugin-tailwind"]
19
- env = "BUN_PUBLIC_*"`;var F="../../../src/app/App.tsx",L="./src/app/index.tsx",U="./node_modules/.cache/wdwh",X={[`${U}/frontend.tsx`]:q.replace("APP_PATH",F),[`${U}/server.ts`]:B};import K from"path";async function W(_){_=_;let v=await S();for(let N in X)await Bun.write(N,X[N]);let{headContent:$,body:p}=await r(),{title:A,iconPath:G,...I}=v,w=["<!DOCTYPE html>",'<html lang="en">',"<head>",'<meta charset="UTF-8" />','<meta name="viewport" content="width=device-width, initial-scale=1.0" />',$,...Object.keys(I).map((N)=>`<meta name="${N}" content="${I[N]}" />`),`<link rel="icon" href="${G}" />`,`<title>${A}</title>`,'<script src="./frontend.tsx"></script>',"</head>",p,"</html>"];await Bun.write(`${U}/index.html`,w.join(`
20
- `))}async function S(){let _=await Bun.file(L).text(),v=E(_,"export const metadata");if(v.iconPath&&v.iconPath[0]===".")v.iconPath=K.join("../../../src/app",v.iconPath);return v}function E(_,v){let $=_.indexOf("{",_.indexOf(v)),p=_.indexOf("}",$)+1,A=_.slice($,p).trim();return A=A.replace(/\/\/.*$/gm,""),A=A.replace(/\/\*[\s\S]*?\*\//g,""),A=A.replace(/,\s*([}\]])/g,"$1"),A=A.replace(/([{,]\s*)([A-Za-z0-9_$]+)\s*:/g,'$1"$2":'),A=A.replace(/'|`/g,'"'),JSON.parse(A)}async function r(){let _=await Bun.file(L).text(),v=M(_,"head").slice(6,-7),$=M(_,"body").replaceAll("className","class"),p=$.indexOf(">")+1,A=$.lastIndexOf("<");return $=$.replace($.slice(p,A),""),{headContent:v,body:$}}function M(_,v){for(let $,p=_.indexOf("export default");;p++){if(!$&&_.startsWith(`<${v}`,p))$=p;if($&&_.startsWith(`</${v}>`,p))return _.slice($,p+v.length+3).replaceAll(`
21
- `," ").replaceAll(/\s{2,}/g," ").trim()}}function Y(){let _=new Bun.Glob("**/index.tsx"),v=[];for(let $ of _.scanSync("src/app"))v.push({filePath:K.join("src/app",$),tmpPath:K.join(),htmlPath:K.join(),iconPath:K.join(),urlPath:""});return v}async function H(){let _=Y();await W(_);let v=Bun.file("./bunfig.toml");if(await v.exists()){let p=await v.text();if(!p.includes("bun-plugin-tailwind")){p+=`${p===""?"":`
22
- `}${V}`,await v.write(p);try{await Bun.$`bunx wdwh dev`}catch{}process.exit()}}else{await v.write(V);async function p(){let A=Bun.file("bunfig.toml");try{if(await A.exists())await A.delete()}catch{}}process.on("SIGINT",p),setTimeout(p,250);try{await Bun.$`bunx wdwh dev`}catch{}process.exit()}await Bun.spawn({cmd:["bun","node_modules/.cache/wdwh/server.ts"],stdout:"ignore",stderr:"inherit",ipc:(p)=>{console.log(p)}}).exited}import y from"bun-plugin-tailwind";import b from"fs";async function z(){let _=performance.now(),v=Y(),p=(await Bun.file("package.json").json()).wdwh||{};if(!p.outdir)p.outdir="dist";await W(v);let A={entrypoints:[`${U}/index.html`],outdir:p.outdir,plugins:[y],minify:!0,target:"browser",sourcemap:"none",external:p.external,naming:p.hashFiles===!1?{chunk:"[name].[ext]",asset:"[name].[ext]"}:void 0,define:{"process.env.NODE_ENV":'"production"'}};if(p.cleanPrev)b.rmSync(p.outdir,{recursive:!0,force:!0});let G=await Bun.build(A),I=Bun.file(`${p.outdir}/index.html`),w=k(await I.text());if(v.length===1){let J=G.outputs.find((Q)=>Q.path.endsWith(".css"));if(J?.path){let Q=Bun.file(J.path),j=w.indexOf('<link rel="stylesheet"'),R=j;for(;R<w.length;R++)if(["/>",'">'].includes(w.slice(R,R+2))){R+=2;break}let C=w.slice(j,R),T=`<style>${k(await Q.text())}</style>`;w=w.replace(C,T),await Q.delete(),G.outputs.splice(G.outputs.indexOf(J),1)}}await I.write(w);let N=performance.now();if(process.argv.includes("--dir"))console.log(`See "${p.outdir}"`);if(process.argv.includes("--time"))console.log(`Build in ${N-_}ms`)}function k(_){return _.replaceAll(`
23
- `," ").replaceAll(/\s{2,}/g," ").replaceAll(/ > | >|> /g,">").replaceAll(/ < | <|< /g,"<").replaceAll(/ ; | ;|; /g,";").replaceAll(/ { | {|{ /g,"{").replaceAll(/ } | }|} /g,"}").replaceAll(/ " | "|" /g,'"').replaceAll(/ , | ,|, /g,",")}var Z="./tmp.zip",m="https://raw.githubusercontent.com/kubashh/wdwh/main/template/template.zip";switch(process.argv[2]){case"dev":await H();break;case"build":await z();break;case"init":{let _=await fetch(m);if(!_.ok)console.log(`feach error: ${_.status}`),process.exit(1);let v=await _.bytes();await Bun.write(Z,v);let $=process.platform==="win32"?["powershell","-Command","Expand-Archiv","-Path",Z,"-DestinationPath",".","-Force"]:["unzip","-o",Z,"-d","."];Bun.spawnSync($);let p=new Bun.Glob("**/*");for(let A of p.scanSync("template/template"))if(!g(A))D(f.join("template/template",A),A),console.log(`+ ${A}`);D("./template/template",".",{recursive:!0}),P(Z),P("./template",{recursive:!0}),console.log(`
24
- Run "bun i && bun dev" and start development!`);break}default:console.log(`Usage:
19
+ env = "BUN_PUBLIC_*"`;var b="../../../src/app/App.tsx",B="./node_modules/.cache/wdwh",k={[`${B}/frontend.tsx`]:X.replace("APP_PATH",b),[`${B}/server.ts`]:O};import D from"path";async function M(R){for(let U of R){for(let N in k)await Bun.write(N,k[N]);let{headContent:A,body:_}=await x(U),v=D.join(B,U.urlPath,"index.html"),G=["<!DOCTYPE html>",'<html lang="en">',"<head>",'<meta charset="UTF-8" />','<meta name="viewport" content="width=device-width, initial-scale=1.0" />',A,'<script src="./frontend.tsx"></script>',"</head>",_,"</html>"];await Bun.write(v,G.join(`
20
+ `))}}async function x(R){let U=await Bun.file(R.tsxPath).text(),A=$(U,"head").slice(6,-7),_=A.match(/<link\s+rel=["']icon["']\s+href=["']([^"']+)["']\s*\/?>/)?.at(1);if(_){let W=D.join("../".repeat(R.urlPath.split("/").length+2),"src/app",R.urlPath,_);A=A.replace(/<link\s+rel=["']icon["']\s+href=["'][^"']+["']\s*\/?>/,`<link rel="icon" href="${W}" />`)}let v=$(U,"body").replaceAll("className","class"),G=v.indexOf(">")+1,N=v.lastIndexOf("<");return v=v.replace(v.slice(G,N),""),{headContent:A,body:v}}function $(R,U){for(let A,_=R.indexOf("export default");;_++){if(!A&&R.startsWith(`<${U}`,_))A=_;if(A&&R.startsWith(`</${U}>`,_))return R.slice(A,_+U.length+3).replaceAll(`
21
+ `," ").replaceAll(/\s{2,}/g," ").trim()}}function Q(){let R=new Bun.Glob("**/index.tsx"),U=[];for(let A of R.scanSync("src/app")){let _=D.join("src/app",A),v=A.replace(/index\.tsx$/,"").replace(/\\/g,"/");U.push({tsxPath:_,urlPath:v})}return U}async function w(){let R=Q();await M(R);let U=Bun.file("./bunfig.toml");if(await U.exists()){console.log("Creating bunfig...");let _=await U.text();if(!_.includes("bun-plugin-tailwind"))_+=`${_===""?"":`
22
+ `}${L}`,await U.write(_),await H()}else{console.log("Deleting bunfig..."),await U.write(L);async function _(){let v=Bun.file("bunfig.toml");try{if(await v.exists())await v.delete()}catch{}}process.on("SIGINT",_),setTimeout(_,250),await H()}console.log("Exists of bunfig...");function A(){console.log("Exit")}process.on("SIGINT",A);try{await Bun.spawn({cmd:["bun","node_modules/.cache/wdwh/server.ts"],stdio:["ignore","ignore","pipe"],ipc:(v)=>{console.log(v)}}).exited}catch(_){console.error(_)}}async function H(){try{await Bun.$`bunx wdwh dev`}catch{}process.exit()}import u from"fs";import z from"path";import g from"bun-plugin-tailwind";async function T(){let R=Q(),U=performance.now(),_=(await Bun.file("package.json").json()).wdwh||{};if(!_.outdir)_.outdir="dist";await M(R);let G={entrypoints:R.map((Y)=>z.join(B,Y.urlPath,"index.html")),outdir:_.outdir,plugins:[g],minify:!0,target:"browser",sourcemap:"none",external:_.external,naming:_.hashFiles===!1?{chunk:"[name].[ext]",asset:"[name].[ext]"}:void 0,define:{"process.env.NODE_ENV":'"production"'}};if(_.cleanPrev)u.rmSync(_.outdir,{recursive:!0,force:!0});let N=await Bun.build(G);for(let Y of R){let J=Bun.file(z.join(_.outdir,Y.urlPath,"index.html")),j=C(await J.text());if(R.length===1){let Z=N.outputs.find((K)=>K.path.endsWith(".css"));if(Z?.path){let K=Bun.file(Z.path),I=j.indexOf('<link rel="stylesheet"'),q=I;for(;q<j.length;q++)if(["/>",'">'].includes(j.slice(q,q+2))){q+=2;break}let S=j.slice(I,q),E=`<style>${C(await K.text())}</style>`;j=j.replace(S,E),await K.delete(),N.outputs.splice(N.outputs.indexOf(Z),1)}}await J.write(j)}let W=performance.now();if(process.argv.includes("--dir"))console.log(`See "${_.outdir}"`);if(process.argv.includes("--time"))console.log(`Build in ${W-U}ms`)}function C(R){return R.replaceAll(`
23
+ `," ").replaceAll(/\s{2,}/g," ").replaceAll(/ > | >|> /g,">").replaceAll(/ < | <|< /g,"<").replaceAll(/ ; | ;|; /g,";").replaceAll(/ { | {|{ /g,"{").replaceAll(/ } | }|} /g,"}").replaceAll(/ " | "|" /g,'"').replaceAll(/ , | ,|, /g,",")}var V="./tmp.zip",f="https://raw.githubusercontent.com/kubashh/wdwh/main/template/template.zip";switch(process.argv[2]){case"dev":await w();break;case"build":await T();break;case"init":{let R=await fetch(f);if(!R.ok)console.log(`feach error: ${R.status}`),process.exit(1);let U=await R.bytes();await Bun.write(V,U);let A=process.platform==="win32"?["powershell","-Command","Expand-Archiv","-Path",V,"-DestinationPath",".","-Force"]:["unzip","-o",V,"-d","."];Bun.spawnSync(A);let _=new Bun.Glob("**/*");for(let v of _.scanSync("template/template"))if(!o(v))F(d.join("template/template",v),v),console.log(`+ ${v}`);F("./template/template",".",{recursive:!0}),P(V),P("./template",{recursive:!0}),console.log("Installing dependencies..."),await Bun.$`bun update`,console.log(`
24
+ Run "bun dev" and start development!`);break}default:console.log(`Usage:
25
25
  wdwh dev
26
26
  wdwh build
27
27
  --dir # Print out dir
package/index.d.ts DELETED
@@ -1,9 +0,0 @@
1
- export type Metadata = {
2
- iconPath: string;
3
- title: string;
4
- description?: string;
5
- author?: string;
6
- keywords?: string;
7
- themeColor?: string;
8
- [name: string]: string | undefined;
9
- };