improved typing
This commit is contained in:
parent
eb12efae50
commit
836c4bcea8
@ -104,6 +104,8 @@
|
|||||||
"https://deno.land/std@0.224.0/path/windows/relative.ts": "3e1abc7977ee6cc0db2730d1f9cb38be87b0ce4806759d271a70e4997fc638d7",
|
"https://deno.land/std@0.224.0/path/windows/relative.ts": "3e1abc7977ee6cc0db2730d1f9cb38be87b0ce4806759d271a70e4997fc638d7",
|
||||||
"https://deno.land/std@0.224.0/path/windows/resolve.ts": "8dae1dadfed9d46ff46cc337c9525c0c7d959fb400a6308f34595c45bdca1972",
|
"https://deno.land/std@0.224.0/path/windows/resolve.ts": "8dae1dadfed9d46ff46cc337c9525c0c7d959fb400a6308f34595c45bdca1972",
|
||||||
"https://deno.land/std@0.224.0/path/windows/to_file_url.ts": "40e560ee4854fe5a3d4d12976cef2f4e8914125c81b11f1108e127934ced502e",
|
"https://deno.land/std@0.224.0/path/windows/to_file_url.ts": "40e560ee4854fe5a3d4d12976cef2f4e8914125c81b11f1108e127934ced502e",
|
||||||
"https://deno.land/std@0.224.0/path/windows/to_namespaced_path.ts": "4ffa4fb6fae321448d5fe810b3ca741d84df4d7897e61ee29be961a6aac89a4c"
|
"https://deno.land/std@0.224.0/path/windows/to_namespaced_path.ts": "4ffa4fb6fae321448d5fe810b3ca741d84df4d7897e61ee29be961a6aac89a4c",
|
||||||
|
"https://vanjs.org/code/van-1.5.5.nomodule.min.js": "32403d4dd6203a46513f000fd64b18e4eaef0823bf757ca0092e70130d059aa3",
|
||||||
|
"https://vanjs.org/code/van-x-0.6.3.nomodule.min.js": "e4b7de89bf2f84c22669ce7bcef592fb398d9dcf8b8a36f4562b8ac6354b1f2f"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
3
dist/bundle_entry.js
vendored
Normal file
3
dist/bundle_entry.js
vendored
Normal file
File diff suppressed because one or more lines are too long
103
dist/core.d.ts
vendored
103
dist/core.d.ts
vendored
@ -1,103 +0,0 @@
|
|||||||
export {}
|
|
||||||
declare global
|
|
||||||
{
|
|
||||||
namespace Van {
|
|
||||||
|
|
||||||
interface State<T> {
|
|
||||||
val: T
|
|
||||||
readonly oldVal: T
|
|
||||||
readonly rawVal: T
|
|
||||||
}
|
|
||||||
|
|
||||||
// Defining readonly view of State<T> for covariance.
|
|
||||||
// Basically we want StateView<string> to implement StateView<string | number>
|
|
||||||
type StateView<T> = Readonly<State<T>>
|
|
||||||
|
|
||||||
type Val<T> = State<T> | T
|
|
||||||
|
|
||||||
type Primitive = string | number | boolean | bigint
|
|
||||||
|
|
||||||
// deno-lint-ignore no-explicit-any
|
|
||||||
type PropValue = Primitive | ((e: any) => void) | null
|
|
||||||
|
|
||||||
type PropValueOrDerived = PropValue | StateView<PropValue> | (() => PropValue)
|
|
||||||
|
|
||||||
type Props = Record<string, PropValueOrDerived> & { class?: PropValueOrDerived; is?: string }
|
|
||||||
|
|
||||||
type PropsWithKnownKeys<ElementType> = Partial<{[K in keyof ElementType]: PropValueOrDerived}>
|
|
||||||
|
|
||||||
type ValidChildDomValue = Primitive | Node | null | undefined
|
|
||||||
|
|
||||||
type BindingFunc = ((dom?: Node) => ValidChildDomValue) | ((dom?: Element) => Element)
|
|
||||||
|
|
||||||
type ChildDom = ValidChildDomValue | StateView<Primitive | null | undefined> | BindingFunc | readonly ChildDom[]
|
|
||||||
|
|
||||||
type TagFunc<Result> = (first?: Props & PropsWithKnownKeys<Result> | ChildDom, ...rest: readonly ChildDom[]) => Result
|
|
||||||
|
|
||||||
type Tags = Readonly<Record<string, TagFunc<Element>>> & {
|
|
||||||
[K in keyof HTMLElementTagNameMap]: TagFunc<HTMLElementTagNameMap[K]>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const van:{
|
|
||||||
readonly state: <T>(initVal: T, HMRKey?:string)=> Van.State<T>
|
|
||||||
readonly derive: <T>(f: () => T) => Van.State<T>
|
|
||||||
readonly add: (dom: Element, ...children: readonly Van.ChildDom[]) => Element
|
|
||||||
readonly tags: Van.Tags & ((namespaceURI: string) => Readonly<Record<string, Van.TagFunc<Element>>>)
|
|
||||||
readonly hydrate: <T extends Node>(dom: T, f: (dom: T) => T | null | undefined) => T
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
namespace VanX
|
|
||||||
{
|
|
||||||
type StateOf<T> = { readonly [K in keyof T]: Van.State<T[K]> }
|
|
||||||
type ValueType<T> = T extends (infer V)[] ? V : T[keyof T]
|
|
||||||
type KeyType<T> = T extends unknown[] ? number : string
|
|
||||||
type ReplacementFunc<T> =
|
|
||||||
T extends (infer V)[] ? (items: V[]) => readonly V[] :
|
|
||||||
(items: [string, T[keyof T]][]) => readonly [string, T[keyof T]][]
|
|
||||||
}
|
|
||||||
const vanX:{
|
|
||||||
readonly calc: <R>(f: () => R) => R
|
|
||||||
readonly reactive: <T extends object>(obj: T, HMRKey?:string) => T
|
|
||||||
readonly noreactive: <T extends object>(obj: T) => T
|
|
||||||
readonly stateFields: <T extends object>(obj: T) => VanX.StateOf<T>
|
|
||||||
readonly raw: <T extends object>(obj: T) => T
|
|
||||||
readonly list: <T extends object, ElementType extends Element>(
|
|
||||||
container: (() => ElementType) | ElementType,
|
|
||||||
items: T,itemFunc: (v: Van.State<VanX.ValueType<T>>, deleter: () => void, k: VanX.KeyType<T>) => Node
|
|
||||||
) => ElementType
|
|
||||||
readonly replace: <T extends object>(obj: T, replacement: VanX.ReplacementFunc<T> | T) => T
|
|
||||||
readonly compact: <T extends object>(obj: T) => T
|
|
||||||
// my addition
|
|
||||||
readonly Store: <T extends object>(obj:T, key:string)=>T
|
|
||||||
};
|
|
||||||
|
|
||||||
namespace Gale {
|
|
||||||
type KeyQuery = "@";
|
|
||||||
type KeyState = ":";
|
|
||||||
type KeyChild = ".";
|
|
||||||
type KeyGroup = "^";
|
|
||||||
type UserStyles = Partial<CSSStyleDeclaration> & {[key: `${KeyQuery|KeyState|KeyChild|KeyGroup}${string}`]: UserStyles }
|
|
||||||
type UserSheet = Record<string, UserStyles>
|
|
||||||
type CollectKeys<Obj> = {[Key in keyof Obj]: Obj[Key] extends object ? Key | CollectKeys<Obj[Key]> : Key }[keyof Obj]
|
|
||||||
type FilterKeys<Keys> = Keys extends `${KeyChild|KeyGroup}${infer Rest}` ? Keys : never
|
|
||||||
type CrossMultiply<A, B> = A extends string ? B extends string ? `${A}${B}` : never : never
|
|
||||||
type CrossMultiplyRecord<Rec> = keyof Rec | { [K in keyof Rec]: K extends string ? CrossMultiply<K, FilterKeys<CollectKeys<Rec[K]>>> : never }[keyof Rec]
|
|
||||||
type Tier = (selector:string, obj:UserStyles, suffix:string)=>string;
|
|
||||||
type CreateSheet = <T extends UserSheet>(sheet:UserSheet&T, hash?:string)=>{
|
|
||||||
Tag:(...args:CrossMultiplyRecord<T>[])=>string,
|
|
||||||
CSS:string,
|
|
||||||
DOM:Elemental<CrossMultiplyRecord<T>>,
|
|
||||||
Div:Circular<CrossMultiplyRecord<T>, Van.TagFunc<HTMLDivElement>>
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
type Elemental<T extends string> = {[K in keyof HTMLElementTagNameMap]: Van.TagFunc<HTMLElementTagNameMap[K]>&Circular<T, Van.TagFunc<HTMLElementTagNameMap[K]>>}
|
|
||||||
|
|
||||||
type Circular<Keys extends string, Func> = {
|
|
||||||
[K in Keys]: Circular<Keys, Func>&Func
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
const Gale:Gale.CreateSheet
|
|
||||||
}
|
|
3
dist/core.js
vendored
3
dist/core.js
vendored
File diff suppressed because one or more lines are too long
1
dist/hmr-NY37ZYM7.js
vendored
Normal file
1
dist/hmr-NY37ZYM7.js
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
var g=0,c={};function d(){for(let e in c)sessionStorage.setItem(e,c[e]);c={},g=0}function f(e,t){c[e]=t,g||(g=setTimeout(d,500)),console.log("SAVE",e,t)}function m(e){let t=sessionStorage.getItem(e);return console.log("LOAD",e,t),t}var S,u=0;function v(e){u=0,S=e}function h(){return S?S+"_"+u+++"_":""}var I=globalThis.van.state;globalThis.van.state=(e,t="")=>{let n=typeof e,o=l=>l,a=l=>l?.toString()||null;switch(n){case"boolean":o=l=>l==="true";break;case"number":o=parseFloat;break;case"object":o=JSON.parse,a=JSON.stringify;break}let r="HMR_"+h()+t,s=m(r),i=I(s?o(s):e);return van.derive(()=>f(r,a(i.val))),i};var w=globalThis.vanX.reactive;globalThis.vanX.reactive=(e,t)=>{v(t);let n=w(e);return v(),n};new WebSocket("ws://"+window.location.host+"/ws").addEventListener("message",e=>e.data==="reload"&&window.location.reload());vanX.Store=(e,t)=>{let n=JSON.stringify(e),o=localStorage.getItem(t+"check");localStorage.setItem(t+"check",n);let a;if(n==o){let s=localStorage.getItem(t);try{a=JSON.parse(s)||e}catch{a=e}}else a=e;let r=vanX.reactive(a);return van.derive(()=>localStorage.setItem(t,JSON.stringify(vanX.compact(r)))),r};
|
@ -1,6 +1,5 @@
|
|||||||
const bundle = await fetch(import.meta.resolve("../dist/core.js")).then(r=>r.text());
|
|
||||||
const index = await fetch(import.meta.resolve("../dist/index.html")).then(r=>r.text());
|
const index = await fetch(import.meta.resolve("../dist/index.html")).then(r=>r.text());
|
||||||
export const HTML = index.replace(`</head>`, `<script>${bundle}</script></head>`);
|
export const HTML = index.replace(`</head>`, `<script type="module" src="/dist/bundle_entry.js?map&hmr"></script></head>`);
|
||||||
export const Root = import.meta.resolve("../");
|
export const Root = import.meta.resolve("../");
|
||||||
export const Load =async(file:string)=> await fetch(Root + file).then(resp=>resp.text());
|
export const Load =async(file:string)=> await fetch(Root + file).then(resp=>resp.text());
|
||||||
export const Save =async(text:string, name:string)=> await Deno.writeTextFile(name, text);
|
export const Save =async(text:string, name:string)=> await Deno.writeTextFile(name, text);
|
@ -7,8 +7,27 @@ globalThis.vanX = VanX;
|
|||||||
import Gale from "../src/gale.js";
|
import Gale from "../src/gale.js";
|
||||||
globalThis.Gale = Gale;
|
globalThis.Gale = Gale;
|
||||||
|
|
||||||
import BindHMR from "../src/hmr.js";
|
const args = new URL(import.meta.url).searchParams;
|
||||||
BindHMR();
|
|
||||||
|
|
||||||
import Boot from "../src/boot.js";
|
//Store
|
||||||
Boot();
|
vanX.Store=(e,t)=>{const a=localStorage.getItem(t),r=vanX.reactive(a?JSON.parse(a):e);return van.derive((()=>localStorage.setItem(t,JSON.stringify(vanX.compact(r))))),r};
|
||||||
|
|
||||||
|
if(args.has("hmr"))
|
||||||
|
{
|
||||||
|
await import("../src/hmr.js");
|
||||||
|
}
|
||||||
|
|
||||||
|
const root = args.get("root")||"/";
|
||||||
|
fetch(root+"deno.json")
|
||||||
|
.then(text=>text.json())
|
||||||
|
.then(json=>{
|
||||||
|
const Script=(t,e)=>{let n=document.createElement("script"); n.type=t; n.textContent=e; document.head.appendChild(n); return n;};
|
||||||
|
const imports = json.imports;
|
||||||
|
for(let n in imports)
|
||||||
|
{
|
||||||
|
const path=imports[n];
|
||||||
|
path.startsWith("./")&&(imports[n]=root+path.substring(2))
|
||||||
|
}
|
||||||
|
args.has("map") && Script("importmap",JSON.stringify({imports}));
|
||||||
|
Script("module").src=imports.entry;
|
||||||
|
});
|
@ -5,8 +5,14 @@ const command = new Deno.Command("deno", {
|
|||||||
"--platform=browser",
|
"--platform=browser",
|
||||||
"--inline-imports=true",
|
"--inline-imports=true",
|
||||||
"--output=dist/core.js",
|
"--output=dist/core.js",
|
||||||
|
"--outdir=dist",
|
||||||
"--minify",
|
"--minify",
|
||||||
|
"--code-splitting",
|
||||||
"scripts/bundle_entry.ts"
|
"scripts/bundle_entry.ts"
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
command.outputSync();
|
const result = command.outputSync();
|
||||||
|
|
||||||
|
const textDecoder = new TextDecoder();
|
||||||
|
console.log("stdout:", textDecoder.decode(result.stdout));
|
||||||
|
console.log("stderr:", textDecoder.decode(result.stderr));
|
13
src/boot.js
13
src/boot.js
@ -1,13 +0,0 @@
|
|||||||
export default (root="/")=>fetch(root+"deno.json")
|
|
||||||
.then(text=>text.json())
|
|
||||||
.then(json=>{
|
|
||||||
const n=(t,e)=>{let n=document.createElement("script");n.type=t,n.textContent=e,document.head.appendChild(n)};
|
|
||||||
const imports = json.imports;
|
|
||||||
for(let n in imports)
|
|
||||||
{
|
|
||||||
const path=imports[n];
|
|
||||||
path.startsWith("./")&&(imports[n]=root+path.substring(2))
|
|
||||||
}
|
|
||||||
n("importmap",JSON.stringify({imports})),
|
|
||||||
n("module",'import "entry"; ')
|
|
||||||
})
|
|
31
src/hmr.js
31
src/hmr.js
@ -47,11 +47,11 @@ function NextID()
|
|||||||
return _ID ? _ID + "_" + (_index++) + "_" : "";
|
return _ID ? _ID + "_" + (_index++) + "_" : "";
|
||||||
}
|
}
|
||||||
|
|
||||||
export default()=>{
|
|
||||||
//bind Van
|
//bind Van
|
||||||
const origninalState = globalThis.van.state;
|
const origninalState = globalThis.van.state;
|
||||||
globalThis.van.state =(value, key="")=>
|
globalThis.van.state =(value, key="")=>
|
||||||
{
|
{
|
||||||
const type = typeof value;
|
const type = typeof value;
|
||||||
let reader =d=>d;
|
let reader =d=>d;
|
||||||
let writer =d=>d?.toString() || null;
|
let writer =d=>d?.toString() || null;
|
||||||
@ -74,23 +74,23 @@ export default()=>{
|
|||||||
van.derive(()=>Save(fullKey, writer(signal.val)));
|
van.derive(()=>Save(fullKey, writer(signal.val)));
|
||||||
|
|
||||||
return signal;
|
return signal;
|
||||||
};
|
};
|
||||||
|
|
||||||
//bind VanX
|
//bind VanX
|
||||||
const originalReactive = globalThis.vanX.reactive;
|
const originalReactive = globalThis.vanX.reactive;
|
||||||
globalThis.vanX.reactive =(obj, id)=>
|
globalThis.vanX.reactive =(obj, id)=>
|
||||||
{
|
{
|
||||||
StartID(id);
|
StartID(id);
|
||||||
const state = originalReactive(obj);
|
const state = originalReactive(obj);
|
||||||
StartID();
|
StartID();
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
// added in devmode to index.html
|
// added in devmode to index.html
|
||||||
new WebSocket('ws://'+window.location.host+'/ws').addEventListener('message',e=>e.data==='reload'&&window.location.reload());
|
new WebSocket('ws://'+window.location.host+'/ws').addEventListener('message',e=>e.data==='reload'&&window.location.reload());
|
||||||
|
|
||||||
vanX.Store =(obj, key)=>
|
vanX.Store =(obj, key)=>
|
||||||
{
|
{
|
||||||
let checkInit = JSON.stringify(obj);
|
let checkInit = JSON.stringify(obj);
|
||||||
let checkStore = localStorage.getItem(key+"check");
|
let checkStore = localStorage.getItem(key+"check");
|
||||||
localStorage.setItem(key+"check", checkInit);
|
localStorage.setItem(key+"check", checkInit);
|
||||||
@ -117,5 +117,4 @@ export default()=>{
|
|||||||
const store = vanX.reactive( recallJSON );
|
const store = vanX.reactive( recallJSON );
|
||||||
van.derive(() => localStorage.setItem(key, JSON.stringify(vanX.compact(store))));
|
van.derive(() => localStorage.setItem(key, JSON.stringify(vanX.compact(store))));
|
||||||
return store;
|
return store;
|
||||||
}
|
|
||||||
}
|
}
|
45
types.d.ts
vendored
Normal file
45
types.d.ts
vendored
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
import type * as VAN from "https://vanjs.org/code/van-1.5.5.d.ts";
|
||||||
|
import type * as VANX from "https://vanjs.org/code/van-x-0.6.3.d.ts";
|
||||||
|
type Replace<T extends object, K extends keyof T, R> = Omit<T, K> & { readonly [P in K]: R };
|
||||||
|
declare module "vanjs-core" { export type State<T> = VAN.State<T> }
|
||||||
|
declare global
|
||||||
|
{
|
||||||
|
namespace Van { export type * from "https://vanjs.org/code/van-1.5.5.d.ts"; }
|
||||||
|
namespace VanX { export type * from "https://vanjs.org/code/van-x-0.6.3.d.ts"; }
|
||||||
|
const van: Replace<VAN.Van, "state", <T>(arg:T, HMRKey?:string)=>VAN.State<T>>
|
||||||
|
const vanX: Replace<typeof VANX, "reactive", <T extends object>(obj: T, HMRKey?:string) => T> & {Store:<T>(obj:T, key:string)=>T}
|
||||||
|
}
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
|
||||||
|
namespace Gale {
|
||||||
|
type KeyQuery = "@";
|
||||||
|
type KeyState = ":";
|
||||||
|
type KeyChild = ".";
|
||||||
|
type KeyGroup = "^";
|
||||||
|
type UserStyles = Partial<CSSStyleDeclaration> & {[key: `${KeyQuery|KeyState|KeyChild|KeyGroup}${string}`]: UserStyles }
|
||||||
|
type UserSheet = Record<string, UserStyles>
|
||||||
|
type CollectKeys<Obj> = {[Key in keyof Obj]: Obj[Key] extends object ? Key | CollectKeys<Obj[Key]> : Key }[keyof Obj]
|
||||||
|
type FilterKeys<Keys> = Keys extends `${KeyChild|KeyGroup}${infer Rest}` ? Keys : never
|
||||||
|
type CrossMultiply<A, B> = A extends string ? B extends string ? `${A}${B}` : never : never
|
||||||
|
type CrossMultiplyRecord<Rec> = keyof Rec | { [K in keyof Rec]: K extends string ? CrossMultiply<K, FilterKeys<CollectKeys<Rec[K]>>> : never }[keyof Rec]
|
||||||
|
type Tier = (selector:string, obj:UserStyles, suffix:string)=>string;
|
||||||
|
type CreateSheet = <T extends UserSheet>(sheet:UserSheet&T, hash?:string)=>{
|
||||||
|
Tag:(...args:CrossMultiplyRecord<T>[])=>string,
|
||||||
|
CSS:string,
|
||||||
|
DOM:Elemental<CrossMultiplyRecord<T>>,
|
||||||
|
Div:Circular<CrossMultiplyRecord<T>, Van.TagFunc<HTMLDivElement>>
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
type Elemental<T extends string> = {[K in keyof HTMLElementTagNameMap]: Van.TagFunc<HTMLElementTagNameMap[K]>&Circular<T, Van.TagFunc<HTMLElementTagNameMap[K]>>}
|
||||||
|
|
||||||
|
type Circular<Keys extends string, Func> = {
|
||||||
|
[K in Keys]: Circular<Keys, Func>&Func
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const Gale:Gale.CreateSheet
|
||||||
|
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user