kt.js 0.2.0 → 0.3.0

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,14 +1,13 @@
1
1
  # KT.js
2
2
 
3
3
  [![npm version](https://img.shields.io/npm/v/kt.js.svg)](https://www.npmjs.com/package/kt.js)
4
-
5
4
  [![license](https://img.shields.io/github/license/baendlorel/kt.js.svg)](https://github.com/baendlorel/kt.js/blob/main/LICENSE)
6
5
 
7
6
  [CHANGLOG✨](CHANGELOG.md)
8
7
 
9
8
  > Note: This framework is still under development. APIs, type declarations, and other parts **may change frequently**. If you use it, please watch for updates in the near future. Feel free to mail me if you have any questions!
10
9
 
11
- KT.js is a tiny(1.3KB runtime without alias helpers and 0.68kb gzipped) DOM utility focused on direct DOM manipulation. It favors not forcing re-renders and aims to keep DOM updates to the absolute minimum for maximum performance.
10
+ KT.js is a tiny DOM utility focused on direct DOM manipulation. It favors not forcing re-renders and aims to keep DOM updates to the absolute minimum for maximum performance.
12
11
 
13
12
  For more awesome packages, check out [my homepage💛](https://baendlorel.github.io/?repoType=npm)
14
13
 
@@ -18,8 +17,35 @@ As a web framework, repeatedly creating a large number of variables and objects
18
17
 
19
18
  KT.js follows one rule: full controll of dom and avoid unless repainting.
20
19
 
20
+ ## Current Core Features
21
+
22
+ - `h` function and its aliases
23
+ - Router
24
+ - Automatically adapts to environment: uses async navigation guards when `Promise` is available, falls back to synchronous mode otherwise
25
+ - **Full ES5 compatibility** - works in IE9+ and other legacy browsers
26
+ - Transpiled to ES5 with no modern syntax
27
+ - Optional minimal Promise polyfill included for older environments
28
+
21
29
  ## Getting started
22
30
 
31
+ ### Using IIFE (direct browser usage)
32
+
33
+ KT.js provides an IIFE build that can be included directly in HTML:
34
+
35
+ ```html
36
+ <script src="https://unpkg.com/kt.js@0.3.0/dist/index.iife.js"></script>
37
+ <script>
38
+ // KT is available globally
39
+ const { h, div } = KT;
40
+ const app = div('container', 'Hello World');
41
+ document.body.appendChild(app);
42
+ </script>
43
+ ```
44
+
45
+ ### Using ES Modules
46
+
47
+ Install via package managers:
48
+
23
49
  ```bash
24
50
  npm install kt.js
25
51
  # or
@@ -116,11 +142,34 @@ console.log(current?.path, current?.params, current?.query);
116
142
  - Hash-based routing (`#/path`)
117
143
  - Dynamic route parameters (`/user/:id`)
118
144
  - Query string parsing (`?key=value`)
119
- - Async navigation guards (`beforeEach`)
145
+ - Async navigation guards (`beforeEach`) - automatically disabled in non-Promise environments
120
146
  - Lifecycle hooks (`afterEach`)
121
147
  - Error handling (`onError`)
122
148
  - Minimal footprint
123
149
 
150
+ ## Browser Compatibility
151
+
152
+ KT.js is transpiled to ES5 and works in all modern browsers as well as legacy browsers including IE9+.
153
+
154
+ ### Promise Polyfill
155
+
156
+ For environments without native `Promise` support (like IE11 and below), KT.js provides a minimal Promise polyfill:
157
+
158
+ ```html
159
+ <!-- Load the Promise polyfill before KT.js -->
160
+ <script src="https://unpkg.com/kt.js@0.3.0/dist/promise-polyfill.js"></script>
161
+ <script src="https://unpkg.com/kt.js@0.3.0/dist/index.iife.js"></script>
162
+ ```
163
+
164
+ Or when using module bundlers:
165
+
166
+ ```js
167
+ import 'kt.js/dist/promise-polyfill';
168
+ import { h, div, createRouter } from 'kt.js';
169
+ ```
170
+
171
+ **Note:** The Router will work without Promise support, but navigation guards (`beforeEach`) will run synchronously and cannot use async/await patterns.
172
+
124
173
  ## Notes
125
174
 
126
175
  - `call`, `apply` on `Function.prototype` is trusted.
package/dist/index.d.ts CHANGED
@@ -70,4 +70,36 @@ declare const img: (attr?: RawAttr, content?: RawContent) => HTMLImageElement;
70
70
  */
71
71
  declare function h<T extends HTMLTag>(tag: T, attr?: RawAttr, content?: RawContent): HTMLElementTagNameMap[T];
72
72
 
73
- export { a, btn, div, form, h, h1, h2, h3, h4, h5, h6, img, input, label, li, ol, option, p, select, span, table, tbody, td, th, thead, tr, ul };
73
+ // Minimal router types
74
+
75
+ interface RouteContext {
76
+ params: Record<string, string>;
77
+ query: Record<string, string>;
78
+ path: string;
79
+ meta?: Record<string, any>;
80
+ }
81
+
82
+ type RouteHandler = (ctx: RouteContext) => HTMLElement | void | Promise<HTMLElement | void>;
83
+
84
+ interface RouteConfig {
85
+ path: string;
86
+ handler: RouteHandler;
87
+ meta?: Record<string, any>;
88
+ }
89
+
90
+ interface RouterConfig {
91
+ routes: RouteConfig[];
92
+ container?: HTMLElement;
93
+ beforeEach?: (to: RouteContext, from: RouteContext | null) => boolean | Promise<boolean>;
94
+ afterEach?: (to: RouteContext) => void;
95
+ onError?: (error: Error) => void;
96
+ }
97
+
98
+ declare function createRouter(config: RouterConfig): {
99
+ start: () => void;
100
+ stop: () => void;
101
+ push: (path: string) => void;
102
+ current: () => RouteContext | null;
103
+ };
104
+
105
+ export { a, btn, createRouter, div, form, h, h1, h2, h3, h4, h5, h6, img, input, label, li, ol, option, p, select, span, table, tbody, td, th, thead, tr, ul };
@@ -0,0 +1 @@
1
+ var kt=function(n){"use strict";var t=document.createElement,e=document.createTextNode,r=document.createDocumentFragment,o=function(n){return void 0===n&&(n=""),e.call(document,n)},u=HTMLElement.prototype.addEventListener,i=HTMLElement.prototype.setAttribute,a=HTMLElement.prototype.appendChild,f="function"==typeof HTMLElement.prototype.append?HTMLElement.prototype.append:function(){for(var n=[],t=0;t<arguments.length;t++)n[t]=arguments[t];if(n.length<50)for(var e=0;e<n.length;e++){"string"==typeof(i=n[e])?a.call(this,o(i)):a.call(this,i)}else{var u=r.call(document);for(e=0;e<n.length;e++){var i;"string"==typeof(i=n[e])?a.call(u,o(i)):a.call(u,i)}a.call(this,u)}},c=Array.isArray,d=Object.keys,l=Promise.resolve,v=Promise.reject,s=function(n){throw new Error("Kt.js:".concat(n))};function p(n,t,e){t in n?n[t]=!!e:i.call(n,t,e)}function m(n,t,e){t in n?n[t]=e:i.call(n,t,e)}var h={checked:p,selected:p,value:m,valueAsDate:m,valueAsNumber:m,defaultValue:m,defaultChecked:p,defaultSelected:p,disabled:p,readOnly:p,multiple:p,required:p,autofocus:p,open:p,controls:p,autoplay:p,loop:p,muted:p,defer:p,async:p,hidden:function(n,t,e){n.hidden=!!e}},y=function(n,t,e){return i.call(n,t,e)};function w(n,t){"string"==typeof t?n.className=t:"object"==typeof t&&null!==t?function(n,t){var e=t.class,r=t.style;if(void 0!==e&&(n.className=e,delete t.class),void 0!==r){if("string"==typeof r)i.call(n,"style",r);else for(var o in n.style)n.style[o]=r[o];delete t.style}for(var a=d(t),f=a.length-1;f>=0;f--){var c=t[o=a[f]];"function"!=typeof c?(h[o]||y)(n,o,c):u.call(n,o,c)}void 0!==e&&(t.style=e),void 0!==r&&(t.style=r)}(n,t):s("applyAttr attr must be an object.")}function g(n,e,r){void 0===e&&(e=""),void 0===r&&(r=""),"string"!=typeof n&&s("h tagName must be a string.");var o,u=(o=n,t.call(document,o));return w(u,e),function(n,t){c(t)?f.apply(n,t):f.call(n,t)}(u,r),u}var b=function(n){return function(t,e){return g(n,t,e)}},E=b("div"),H=b("span"),L=b("label"),M=b("p"),R=b("h1"),T=b("h2"),j=b("h3"),k=b("h4"),A=b("h5"),q=b("h6"),C=b("ul"),N=b("ol"),P=b("li"),I=b("button"),O=b("form"),U=b("input"),x=b("select"),D=b("option"),K=b("table"),S=b("thead"),V=b("tbody"),$=b("tr"),z=b("th"),B=b("td"),F=b("a"),G=b("img"),J=function(){return!0};return n.a=F,n.btn=I,n.createRouter=function(n){var t=n.routes,e=n.container,r=n.beforeEach,o=void 0===r?J:r,u=n.afterEach,i=void 0===u?J:u,a=n.onError,f=void 0===a?console.error:a,c=null,d=t.map(function(n){var t=[],e=n.path.replace(/\/:([^/]+)/g,function(n,e){return t.push(e),"/([^/]+)"});return{route:n,pattern:new RegExp("^".concat(e,"$")),names:t}}),s=function(n){for(var t=0;t<d.length;t++){var e=d[t],r=e.route,o=e.pattern,u=e.names,i=n.match(o);if(i){for(var a={},f=0;f<u.length;f++)a[u[f]]=i[f+1];return{route:r,params:a}}}return null},p=function(n){var t={};if(!n)return t;for(var e=(0===n.indexOf("?")?n.slice(1):n).split("&"),r=0;r<e.length;r++){var o=e[r].split("="),u=o[0];u&&(t[decodeURIComponent(u)]=decodeURIComponent(o[1]||""))}return t},m="undefined"!=typeof Promise?function(n){var t=n.split("?"),r=t[0],u=t[1],a=p(u||""),d=s(r);if(!d){var m=new Error("Route not found: ".concat(r));return f(m),v(m)}var h={params:d.params,query:a,path:r,meta:d.route.meta};return l(o(h,c)).then(function(n){return n?(window.location.hash=u?"".concat(r,"?").concat(u):r,d.route.handler(h)):v(new Error("Navigation blocked by guard"))}).then(function(n){e&&n&&(e.innerHTML="",e.appendChild(n)),i(c=h)}).catch(function(n){return f(n),v(n)})}:function(n){var t=n.split("?"),r=t[0],u=t[1],a=p(u||""),d=s(r);if(d){var l={params:d.params,query:a,path:r,meta:d.route.meta};try{if(!o(l,c))return;window.location.hash=u?"".concat(r,"?").concat(u):r;var v=d.route.handler(l);e&&v&&"function"!=typeof v.then&&(e.innerHTML="",e.appendChild(v)),i(c=l)}catch(n){f(n)}}else f(new Error("Route not found: ".concat(r)))},h=function(){return m(window.location.hash.slice(1)||"/")};return{start:function(){window.addEventListener("hashchange",h),h()},stop:function(){return window.removeEventListener("hashchange",h)},push:function(n){return m(n)},current:function(){return c}}},n.div=E,n.form=O,n.h=g,n.h1=R,n.h2=T,n.h3=j,n.h4=k,n.h5=A,n.h6=q,n.img=G,n.input=U,n.label=L,n.li=P,n.ol=N,n.option=D,n.p=M,n.select=x,n.span=H,n.table=K,n.tbody=V,n.td=B,n.th=z,n.thead=S,n.tr=$,n.ul=C,n}({});
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- const t=document.createElement,e=HTMLElement.prototype.append,n=HTMLElement.prototype.addEventListener,o=HTMLElement.prototype.setAttribute,l=Array.isArray,a=Object.keys,c=Object.assign,d=t=>{throw new Error("Kt.js:"+t)},i=(t,e,n)=>{e in t?t[e]=!!n:o.call(t,e,n)},u=(t,e,n)=>{e in t?t[e]=n:o.call(t,e,n)},r={checked:i,selected:i,value:u,valueAsDate:u,valueAsNumber:u,defaultValue:u,defaultChecked:i,defaultSelected:i,disabled:i,readOnly:i,multiple:i,required:i,autofocus:i,open:i,controls:i,autoplay:i,loop:i,muted:i,defer:i,async:i,hidden:(t,e,n)=>t.hidden=!!n},s=(t,e,n)=>o.call(t,e,n);function f(t,e){"string"==typeof e?t.className=e:"object"==typeof e&&null!==e?function(t,e){const l=e.class,d=e.style;void 0!==l&&(t.className=l,delete e.class),void 0!==d&&("string"==typeof d?o.call(t,"style",d):c(t.style,d),delete e.style);const i=a(e);for(let o=i.length-1;o>=0;o--){const l=i[o],a=e[l];"function"!=typeof a?(r[l]||s)(t,l,a):n.call(t,l,a)}void 0!==l&&(e.style=l),void 0!==d&&(e.style=d)}(t,e):d("applyAttr attr must be an object.")}function p(n,o="",a=""){"string"!=typeof n&&d("h tagName must be a string.");const c=(i=n,t.call(document,i));var i;return f(c,o),function(t,n){"string"==typeof n?t.textContent=n:l(n)?e.apply(t,n):n instanceof HTMLElement?e.call(t,n):d("applyContent invalid content.")}(c,a),c}const m=t=>(e,n)=>p(t,e,n),y=m("div"),h=m("span"),b=m("label"),v=m("p"),g=m("h1"),j=m("h2"),E=m("h3"),A=m("h4"),H=m("h5"),L=m("h6"),M=m("ul"),T=m("ol"),O=m("li"),k=m("button"),w=m("form"),C=m("input"),N=m("select"),q=m("option"),x=m("table"),D=m("thead"),K=m("tbody"),S=m("tr"),V=m("th"),z=m("td"),B=m("a"),F=m("img");export{B as a,k as btn,y as div,w as form,p as h,g as h1,j as h2,E as h3,A as h4,H as h5,L as h6,F as img,C as input,b as label,O as li,T as ol,q as option,v as p,N as select,h as span,x as table,K as tbody,z as td,V as th,D as thead,S as tr,M as ul};
1
+ var n=document.createElement,t=document.createTextNode,e=document.createDocumentFragment,r=function(n){return void 0===n&&(n=""),t.call(document,n)},o=HTMLElement.prototype.addEventListener,u=HTMLElement.prototype.setAttribute,i=HTMLElement.prototype.appendChild,a="function"==typeof HTMLElement.prototype.append?HTMLElement.prototype.append:function(){for(var n=[],t=0;t<arguments.length;t++)n[t]=arguments[t];if(n.length<50)for(var o=0;o<n.length;o++){"string"==typeof(a=n[o])?i.call(this,r(a)):i.call(this,a)}else{var u=e.call(document);for(o=0;o<n.length;o++){var a;"string"==typeof(a=n[o])?i.call(u,r(a)):i.call(u,a)}i.call(this,u)}},f=Array.isArray,c=Object.keys,d=Promise.resolve,l=Promise.reject,v=function(n){throw new Error("Kt.js:".concat(n))};function s(n,t,e){t in n?n[t]=!!e:u.call(n,t,e)}function p(n,t,e){t in n?n[t]=e:u.call(n,t,e)}var m={checked:s,selected:s,value:p,valueAsDate:p,valueAsNumber:p,defaultValue:p,defaultChecked:s,defaultSelected:s,disabled:s,readOnly:s,multiple:s,required:s,autofocus:s,open:s,controls:s,autoplay:s,loop:s,muted:s,defer:s,async:s,hidden:function(n,t,e){n.hidden=!!e}},h=function(n,t,e){return u.call(n,t,e)};function y(n,t){"string"==typeof t?n.className=t:"object"==typeof t&&null!==t?function(n,t){var e=t.class,r=t.style;if(void 0!==e&&(n.className=e,delete t.class),void 0!==r){if("string"==typeof r)u.call(n,"style",r);else for(var i in n.style)n.style[i]=r[i];delete t.style}for(var a=c(t),f=a.length-1;f>=0;f--){var d=t[i=a[f]];"function"!=typeof d?(m[i]||h)(n,i,d):o.call(n,i,d)}void 0!==e&&(t.style=e),void 0!==r&&(t.style=r)}(n,t):v("applyAttr attr must be an object.")}function w(t,e,r){void 0===e&&(e=""),void 0===r&&(r=""),"string"!=typeof t&&v("h tagName must be a string.");var o,u=(o=t,n.call(document,o));return y(u,e),function(n,t){f(t)?a.apply(n,t):a.call(n,t)}(u,r),u}var g=function(n){return function(t,e){return w(n,t,e)}},b=g("div"),E=g("span"),H=g("label"),L=g("p"),M=g("h1"),R=g("h2"),T=g("h3"),j=g("h4"),A=g("h5"),k=g("h6"),q=g("ul"),C=g("ol"),N=g("li"),P=g("button"),x=g("form"),I=g("input"),O=g("select"),U=g("option"),D=g("table"),K=g("thead"),S=g("tbody"),V=g("tr"),$=g("th"),z=g("td"),B=g("a"),F=g("img"),G=function(){return!0};function J(n){var t=n.routes,e=n.container,r=n.beforeEach,o=void 0===r?G:r,u=n.afterEach,i=void 0===u?G:u,a=n.onError,f=void 0===a?console.error:a,c=null,v=t.map(function(n){var t=[],e=n.path.replace(/\/:([^/]+)/g,function(n,e){return t.push(e),"/([^/]+)"});return{route:n,pattern:new RegExp("^".concat(e,"$")),names:t}}),s=function(n){for(var t=0;t<v.length;t++){var e=v[t],r=e.route,o=e.pattern,u=e.names,i=n.match(o);if(i){for(var a={},f=0;f<u.length;f++)a[u[f]]=i[f+1];return{route:r,params:a}}}return null},p=function(n){var t={};if(!n)return t;for(var e=(0===n.indexOf("?")?n.slice(1):n).split("&"),r=0;r<e.length;r++){var o=e[r].split("="),u=o[0];u&&(t[decodeURIComponent(u)]=decodeURIComponent(o[1]||""))}return t},m="undefined"!=typeof Promise?function(n){var t=n.split("?"),r=t[0],u=t[1],a=p(u||""),v=s(r);if(!v){var m=new Error("Route not found: ".concat(r));return f(m),l(m)}var h={params:v.params,query:a,path:r,meta:v.route.meta};return d(o(h,c)).then(function(n){return n?(window.location.hash=u?"".concat(r,"?").concat(u):r,v.route.handler(h)):l(new Error("Navigation blocked by guard"))}).then(function(n){e&&n&&(e.innerHTML="",e.appendChild(n)),i(c=h)}).catch(function(n){return f(n),l(n)})}:function(n){var t=n.split("?"),r=t[0],u=t[1],a=p(u||""),d=s(r);if(d){var l={params:d.params,query:a,path:r,meta:d.route.meta};try{if(!o(l,c))return;window.location.hash=u?"".concat(r,"?").concat(u):r;var v=d.route.handler(l);e&&v&&"function"!=typeof v.then&&(e.innerHTML="",e.appendChild(v)),i(c=l)}catch(n){f(n)}}else f(new Error("Route not found: ".concat(r)))},h=function(){return m(window.location.hash.slice(1)||"/")};return{start:function(){window.addEventListener("hashchange",h),h()},stop:function(){return window.removeEventListener("hashchange",h)},push:function(n){return m(n)},current:function(){return c}}}export{B as a,P as btn,J as createRouter,b as div,x as form,w as h,M as h1,R as h2,T as h3,j as h4,A as h5,k as h6,F as img,I as input,H as label,N as li,C as ol,U as option,L as p,O as select,E as span,D as table,S as tbody,z as td,$ as th,K as thead,V as tr,q as ul};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kt.js",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "author": {
5
5
  "name": "Kasukabe Tsumugi",
6
6
  "email": "futami16237@gmail.com"
@@ -59,7 +59,6 @@
59
59
  "rollup-plugin-const-enum": "^1.1.4",
60
60
  "rollup-plugin-dts": "^6.2.3",
61
61
  "rollup-plugin-func-macro": "^1.1.1",
62
- "tinyrainbow": "^3.0.3",
63
62
  "tslib": "^2.8.1",
64
63
  "typescript": "^5.9.2",
65
64
  "vitest": "^3.2.4"