kt.js 0.0.2 → 0.0.4

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,22 +1,85 @@
1
1
  # KT.js
2
2
 
3
- (still developing)
3
+ [中文](./README.zh.md) | [English](./README.md)
4
4
 
5
- (image wait to be placed here)
5
+ For more awesome packages, check out [my homepage💛](https://baendlorel.github.io/?repoType=npm)
6
6
 
7
- ## Philosophy: No Forced Repaint
7
+ > Note: developing
8
8
 
9
- KT.js is designed with a simple but radical philosophy: **never repaint unless absolutely necessary**. Unlike most frontend frameworks that rely on frequent DOM diffing and re-rendering, KT.js believes in minimal DOM operations and maximum stability.
9
+ kt.js is a tiny, high-performance DOM utility focused on minimal re-rendering and direct DOM manipulation. It favors not forcing re-renders and aims to keep DOM updates to the absolute minimum for maximum performance.
10
10
 
11
- - **Direct DOM Manipulation**: KT.js works with the DOM as it is, updating only what truly needs to change. No virtual DOM, no diffing, no hidden magic.
12
- - **Predictable UI**: Your UI remains stable and predictable. If you don't explicitly change something, KT.js won't touch it.
13
- - **Performance First**: By avoiding unnecessary redraws, KT.js achieves high performance, especially in complex or dynamic interfaces.
14
- - **Developer Control**: You decide when and what to update. KT.js gives you the tools, not the rules.
11
+ ## Philosophy
15
12
 
16
- > "Just don't repaint. Let the DOM be."
13
+ As a web framework, repeatedly creating a large number of variables and objects is unacceptable. This is a provocation against browsers and the V8 engine(or SpiderMonkey, or JSC). So I created KT.js.
17
14
 
18
- KT.js is for developers who want full control, minimal abstraction, and a framework that respects the browser's native strengths.
15
+ KT.js follows one rule: avoid repainting unless necessary. It updates the DOM directly and only where needed no virtual DOM, no automatic diffing. That keeps the UI predictable and fast, while leaving control to the developer.
19
16
 
20
- ---
17
+ - **Direct DOM**: update only what changes.
18
+ - **Minimal updates**: avoid unnecessary reflows and repaints.
19
+ - **Predictable and fast**: stable UI with high performance.
20
+ - **Developer control**: you decide when to update.
21
21
 
22
- For API details and usage, see the documentation and examples in the `example/` folder.
22
+ ## Getting started
23
+
24
+ Install via npm but pnpm is recommended:
25
+
26
+ ```bash
27
+ npm install kt.js
28
+ # or
29
+ pnpm add kt.js
30
+ ```
31
+
32
+ Import KT.js into your project.
33
+
34
+ ```ts
35
+ import { h, createApp } from 'kt.js';
36
+
37
+ const app = h('div', { id: 'app' }, 'Hello, KT.js!');
38
+
39
+ createApp(app);
40
+ ```
41
+
42
+ ## Core Api
43
+
44
+ - `h` — hyperscript helper
45
+ - Creates a KT-enhanced DOM element representation.
46
+ - Typical usage:` h('div', { id: 'root' }, 'Hello')`.
47
+ - Returns an `HTMLKEnhancedElement` (an HTMLElement with extra `enhance` properties described below).
48
+
49
+ - `createApp` — mount helper
50
+ - Mounts a root `HTMLKEnhancedElement` to the document.
51
+ - Signature: `createApp(rootElement: HTMLKEnhancedElement, mountTo?: HTMLElement)`
52
+ - If `mountTo` is omitted, it tries `#app` and falls back to `document.body`.
53
+
54
+ ## Enhance-added properties and methods
55
+
56
+ After calling `enhance(element)` (done internally by `h` when appropriate), an HTMLElement becomes an `HTMLKEnhancedElement` with the following additions:
57
+
58
+ - Properties
59
+ - `kid` (number): a per-element unique index generated by an internal `Indexer.nextKid()`.
60
+ - `isKT` (true): boolean marker that identifies the element as a KText element.
61
+ - `ktext` (string): getter/setter that proxies to an internal Text node stored on the element (reads/writes element text content).
62
+ - `kchildren` (array): getter/setter that exposes the element's children as an array of strings / enhanced elements. Setting `kchildren` replaces the element's content and accepts strings, Text nodes or other KT.js enhanced elements.
63
+
64
+ - Methods
65
+ - `kon(type, listener, options?)` — enhanced addEventListener
66
+ - Normalizes options. Supports a `triggerLimit` option which will remove the listener after N triggers (if `triggerLimit === 1` it becomes `once`).
67
+ - Returns the listener (or a wrapped listener used for limited triggers).
68
+ - `koff(type, listener, options?)` — enhanced removeEventListener
69
+ - Removes event listeners respecting provided options.
70
+ - `kmount(element)` — append/mount helper
71
+ - Equivalent to `element.appendChild(this)` and returns `this` for chaining.
72
+
73
+ ## Notes and caveats
74
+
75
+ - This library manipulates the DOM directly and intentionally keeps re-rendering minimal.
76
+ - `enhance` augments elements with non-enumerable descriptors for `ktext`, `isKT`, and `kid`, and assigns `kon`, `koff`, and `kmount` methods directly.
77
+ - The API is small and low-level by design — it's intended as a performance-focused building block rather than a full component framework.
78
+
79
+ ## Contributing
80
+
81
+ PRs and issues are welcome. If you add features that affect the public API, update README and tests accordingly.
82
+
83
+ ## License
84
+
85
+ MIT
package/README.zh.md ADDED
@@ -0,0 +1,85 @@
1
+ # KT.js
2
+
3
+ [中文](./README.zh.md) | [English](./README.md)
4
+
5
+ For more awesome packages, check out [my homepage💛](https://baendlorel.github.io/?repoType=npm)
6
+
7
+ > Note: 持续开发中。
8
+
9
+ KT.js 是一个微小的高性能 DOM 工具,专注于最小化重绘和直接操作 DOM。它的设计目标是尽量不强制重绘,只在必要时更新 DOM,从而获得极致性能。
10
+
11
+ ## 核心理念
12
+
13
+ 作为一个web框架,反复创建大量对象、反复重绘是不可接受的,这是对浏览器和V8引擎(或者SpiderMonkey, 或者说JSC)的挑衅。所以我创建了 KT.js。
14
+
15
+ KT.js 遵循一条原则:尽量避免不必要的重绘。它直接按需更新 DOM —— 无虚拟 DOM、无自动 diff。这样能保持界面可预测且高效,同时把更新控制权交给开发者。
16
+
17
+ - **直接操作 DOM**:只更新真正改变的部分。
18
+ - **最小化更新**:避免不必要的回流与重绘。
19
+ - **可预测且高效**:界面稳定,性能优秀。
20
+ - **开发者掌控**:什么时候更新由你决定。
21
+
22
+ ## 快速开始
23
+
24
+ 通过 npm 安装,但推荐使用 pnpm:
25
+
26
+ ```bash
27
+ npm install kt.js
28
+ # or
29
+ pnpm add kt.js
30
+ ```
31
+
32
+ 将 KT.js 导入到你的项目:
33
+
34
+ ```ts
35
+ import { h, createApp } from 'kt.js';
36
+
37
+ const app = h('div', { id: 'app' }, 'Hello, KT.js!');
38
+
39
+ createApp(app);
40
+ ```
41
+
42
+ ## 核心 API
43
+
44
+ - `h` — hyperscript 辅助函数
45
+ - 创建带有 KText 增强属性的 DOM 元素。
46
+ - 用法示例:h('div', { id: 'root' }, 'Hello')。
47
+ - 返回 `HTMLKEnhancedElement`(一个带有额外 `enhance` 属性的 HTMLElement)。
48
+
49
+ - `createApp` — 挂载助手
50
+ - 将根 `HTMLKEnhancedElement` 挂载到文档。
51
+ - 签名:`createApp(rootElement: HTMLKEnhancedElement, mountTo?: HTMLElement)`
52
+ - 若省略 `mountTo`,会尝试 `#app`,找不到则回退到 `document.body`。
53
+
54
+ ## enhance 增添的属性和方法
55
+
56
+ 当调用 `enhance(element)`(在需要时 `h` 会内部调用)后,HTMLElement 会被增强为 `HTMLKEnhancedElement`,包含以下新增项:
57
+
58
+ - 属性
59
+ - `kid`(number):由内部 `Indexer.nextKid()` 生成的每个元素唯一索引。
60
+ - `isKT`(true):标记元素是 KText 元素的布尔值。
61
+ - `ktext`(string):getter/setter,代理内部 Text 节点,可方便地设置文本内容。
62
+ - `kchildren`(数组):getter/setter,暴露元素的子项为字符串或增强元素数组。设置 `kchildren` 会替换元素内容,接受字符串、Text 节点或 KT.js 增强元素。
63
+
64
+ - 方法
65
+ - `kon(type, listener, options?)` — 增强的 addEventListener
66
+ - 规范化 options,支持 `triggerLimit`(监听器在触发 N 次后移除;若 `triggerLimit === 1` 则等同于 `once`)。
67
+ - 返回 listener(或用于限制触发次数的包装监听器)。
68
+ - `koff(type, listener, options?)` — 增强的 removeEventListener
69
+ - 移除事件监听,遵循提供的 options。
70
+ - `kmount(element)` — 挂载/追加辅助方法
71
+ - 等价于 `element.appendChild(this)`,并返回 `this` 以方便链式调用。
72
+
73
+ ## 注意
74
+
75
+ - 本库直接操作 DOM,故意将重绘控制在最低。
76
+ - `enhance` 为元素添加了非枚举描述符的属性 `ktext`、`isKT` 和 `kid`,并直接赋值 `kon`、`koff`、`kmount` 方法。
77
+ - 该 API 小且低级,旨在作为性能优先的构建块,而非完整的组件框架。
78
+
79
+ ## 贡献
80
+
81
+ 欢迎 PR 和 issue。如果你修改了公共 API,请同步更新 README 和测试。
82
+
83
+ ## License
84
+
85
+ MIT
package/dist/index.d.ts CHANGED
@@ -1,37 +1,29 @@
1
- /**
2
- * Tagged template helper to collect CSS strings.
3
- *
4
- * Usage:
5
- * css` .cls { color: red } `;
6
- *
7
- * The function concatenates the template literal parts and any interpolated
8
- * values, trims the result, pushes it into `cssList` and returns the final
9
- * string.
10
- *
11
- * @param strings Template string parts
12
- * @param values Interpolated values
13
- * @returns The concatenated CSS string that was pushed into `cssList`
14
- */
15
- declare function css(strings: TemplateStringsArray, ...values: any[]): string;
16
-
17
1
  /**
18
2
  * Create an enhanced HTMLElement.
19
3
  * @param tag tag of an `HTMLElement`
20
4
  * @param attr attribute object or className
21
5
  * @param content a string or an array of HTMLEnhancedElement as child nodes
22
6
  */
23
- declare function h<Tag extends HTMLElementTag>(
24
- tag: Tag,
25
- attr?: KAttribute | string,
26
- content?: (HTMLKEnhancedElement | string)[] | HTMLKEnhancedElement | string
27
- ): HTMLKEnhancedElement<Tag>;
7
+ declare function h<Tag extends HTMLElementTag>(tag: Tag, attr?: KAttribute | string, content?: (HTMLKEnhancedElement | string)[] | HTMLKEnhancedElement | string): HTMLKEnhancedElement<Tag>;
28
8
 
29
- declare function useScope(scopeName?: string): {
30
- h: typeof h;
31
- css: typeof css;
32
- };
9
+ /**
10
+ * ## About
11
+ * @package Kt.js
12
+ * @author Kasukabe Tsumugi <futami16237@gmail.com>
13
+ * @version 0.0.4 (Last Update: 2025.09.19 19:11:25.259)
14
+ * @license MIT
15
+ * @link https://github.com/baendlorel/kt.js
16
+ * @description A simple and easy-to-use web framework, never re-render. Abbreviation of Kasukabe Tsumugi.
17
+ * @copyright Copyright (c) 2025 Kasukabe Tsumugi. All rights reserved.
18
+ *
19
+ * ## Usage
20
+ * Mount root element to `#app`(`body` if not found) or to the given element.
21
+ * @param rootElement an instance of `HTMLKEnhancedElement`, created by `h` function.
22
+ * @param mountTo any `HTMLElement` to mount to, if omitted, will mount to `#app` or `body`.
23
+ */
24
+ declare function createApp(rootElement: HTMLKEnhancedElement, mountTo?: HTMLElement): void;
33
25
 
34
- export { css, h, useScope };
26
+ export { createApp, h };
35
27
 
36
28
  // # from: src/global.d.ts
37
29
  declare const __IS_DEV__: boolean;
@@ -40,6 +32,7 @@ interface KAttribute {
40
32
  [k: string]: any;
41
33
 
42
34
  id?: string;
35
+
43
36
  type?: string;
44
37
  for?: string;
45
38
  name?: string;
@@ -53,7 +46,17 @@ interface KAttribute {
53
46
  class?: string | string[];
54
47
  style?: string | Partial<CSSStyleDeclaration>;
55
48
  action?: string;
56
- method?: 'POST' | 'GET' | 'PUT' | 'DELETE' | 'PATCH' | 'HEAD' | 'OPTIONS' | 'CONNECT' | 'TRACE';
49
+ method?:
50
+ | 'POST'
51
+ | 'GET'
52
+ | 'PUT'
53
+ | 'DELETE'
54
+ | 'PATCH'
55
+ | 'HEAD'
56
+ | 'OPTIONS'
57
+ | 'CONNECT'
58
+ | 'TRACE'
59
+ | (string & {});
57
60
  }
58
61
 
59
62
  interface KOnOptions extends AddEventListenerOptions {
@@ -70,17 +73,48 @@ type KListener<E extends HTMLElement, K extends keyof HTMLElementEventMap> = (
70
73
  ) => unknown;
71
74
 
72
75
  // # from: src/types/enhance.d.ts
73
-
74
76
  type HTMLElementTag = keyof HTMLElementTagNameMap;
75
77
 
78
+ type KChildren = HTMLKEnhancedElement | Text;
79
+
76
80
  interface KEnhanced {
77
81
  /**
78
- * Unique id of the KT.js enhanced html element;
82
+ * Unique numeric identifier for a KT.js enhanced element instance.
83
+ * Used internally to track and distinguish enhanced elements.
79
84
  */
80
85
  kid: number;
81
86
 
87
+ /**
88
+ * Marker property that is always true for enhanced elements.
89
+ */
82
90
  isKT: true;
83
91
 
92
+ /**
93
+ * The element's text content as maintained by KT.js.
94
+ * - it is not recommended to use `textContent` any more
95
+ */
96
+ ktext: string;
97
+
98
+ /**
99
+ * Array of children for this enhanced element.
100
+ * - read as `Array`, not `HTMLCollection`.
101
+ * - can be set to replace all child nodes.
102
+ */
103
+ kchildren: KChildren[];
104
+
105
+ /**
106
+ * Attach an event listener to the element and return a typed listener
107
+ * function. The generic parameters ensure the listener and returned
108
+ * function are correctly typed for the element and event.
109
+ * - `triggerLimit` option is the max trigger time of a listner.
110
+ * - its priority is higher than `once` option.
111
+ * - if it is `1`, will fallback to `once` behavior.
112
+ *
113
+ * @param type event type (e.g., 'click')
114
+ * @param listener event listener callback
115
+ * @param options listener options or capture flag
116
+ * @returns the listener function typed for the specific element and event
117
+ */
84
118
  kon: <El extends HTMLElement, K extends keyof HTMLElementEventMap>(
85
119
  this: El,
86
120
  type: K,
@@ -88,6 +122,19 @@ interface KEnhanced {
88
122
  options?: KOnOptions
89
123
  ) => KListener<El, K>;
90
124
 
125
+ /**
126
+ * Remove or detach an event listener from the element. Semantically this
127
+ * is the counterpart to `kon` and accepts the same arguments. Returns
128
+ * nothing.
129
+ *
130
+ * Note: the original inline comment said "Equivalent to `element.appendChild(this)`"
131
+ * which does not apply to event removal — keep this method focused on
132
+ * removing listeners according to the project's implementation.
133
+ *
134
+ * @param type event type
135
+ * @param listener event listener to remove
136
+ * @param options listener options
137
+ */
91
138
  koff: <El extends HTMLElement, K extends keyof HTMLElementEventMap>(
92
139
  this: El,
93
140
  type: K,
@@ -95,6 +142,14 @@ interface KEnhanced {
95
142
  options?: KOnOptions
96
143
  ) => void;
97
144
 
145
+ /**
146
+ * Mount this enhanced element onto a host DOM element. This typically
147
+ * appends the enhanced element to the supplied `element` and performs any
148
+ * needed setup. Returns the mounted enhanced element.
149
+ *
150
+ * @param element the DOM element to mount into
151
+ * @returns the mounted enhanced element (this)
152
+ */
98
153
  kmount: <El extends HTMLKEnhancedElement>(this: El, element: HTMLElement) => El;
99
154
  }
100
155
 
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- class t extends Error{reason;filename;line;column;source;constructor(t,n,e,s,i){super(`${t}:${e}:${s}: ${n}`),this.reason=n,this.filename=t,this.line=e,this.column=s,this.source=i}}class n{start;end;source;constructor(t,n,e){this.start=t,this.end=n,this.source=e}}var e;!function(t){t.stylesheet="stylesheet",t.rule="rule",t.declaration="declaration",t.comment="comment",t.container="container",t.charset="charset",t.document="document",t.customMedia="custom-media",t.fontFace="font-face",t.host="host",t.import="import",t.keyframes="keyframes",t.keyframe="keyframe",t.layer="layer",t.media="media",t.namespace="namespace",t.page="page",t.startingStyle="starting-style",t.supports="supports"}(e||(e={}));const s=(t,n,e)=>{let s=e,i=1e4;do{const e=n.map(n=>t.indexOf(n,s));e.push(t.indexOf("\\",s));const r=e.filter(t=>-1!==t);if(0===r.length)return-1;const o=Math.min(...r);if("\\"!==t[o])return o;s=o+2,i--}while(i>0);throw new Error("Too many escaping")},i=(t,n,e)=>{let r=e,o=1e4;do{const e=n.map(n=>t.indexOf(n,r));e.push(t.indexOf("(",r)),e.push(t.indexOf('"',r)),e.push(t.indexOf("'",r)),e.push(t.indexOf("\\",r));const c=e.filter(t=>-1!==t);if(0===c.length)return-1;const h=Math.min(...c);switch(t[h]){case"\\":r=h+2;break;case"(":{const n=i(t,[")"],h+1);if(-1===n)return-1;r=n+1}break;case'"':{const n=s(t,['"'],h+1);if(-1===n)return-1;r=n+1}break;case"'":{const n=s(t,["'"],h+1);if(-1===n)return-1;r=n+1}break;default:return h}o--}while(o>0);throw new Error("Too many escaping")},r=/\/\*[^]*?(?:\*\/|$)/g;function o(t){return t?t.trim():""}function c(t,n){const e=t&&"string"==typeof t.type,s=e?t:n;for(const n in t){const e=t[n];Array.isArray(e)?e.forEach(t=>{c(t,s)}):e&&"object"==typeof e&&c(e,s)}return e&&Object.defineProperty(t,"parent",{configurable:!0,writable:!0,enumerable:!1,value:n||null}),t}class h{level=0;indentation=" ";compress=!1;constructor(t){"string"==typeof t?.indent&&(this.indentation=t?.indent),t?.compress&&(this.compress=!0)}emit(t,n){return t}indent(t){return this.level=this.level||1,t?(this.level+=t,""):Array(this.level).join(this.indentation)}visit(t){switch(t.type){case e.stylesheet:return this.stylesheet(t);case e.rule:return this.rule(t);case e.declaration:return this.declaration(t);case e.comment:return this.comment(t);case e.container:return this.container(t);case e.charset:return this.charset(t);case e.document:return this.document(t);case e.customMedia:return this.customMedia(t);case e.fontFace:return this.fontFace(t);case e.host:return this.host(t);case e.import:return this.import(t);case e.keyframes:return this.keyframes(t);case e.keyframe:return this.keyframe(t);case e.layer:return this.layer(t);case e.media:return this.media(t);case e.namespace:return this.namespace(t);case e.page:return this.page(t);case e.startingStyle:return this.startingStyle(t);case e.supports:return this.supports(t)}}mapVisit(t,n){let e="";n=n||"";for(let s=0,i=t.length;s<i;s++)e+=this.visit(t[s]),n&&s<i-1&&(e+=this.emit(n));return e}compile(t){return this.compress?t.stylesheet.rules.map(this.visit,this).join(""):this.stylesheet(t)}stylesheet(t){return this.mapVisit(t.stylesheet.rules,"\n\n")}comment(t){return this.compress?this.emit("",t.position):this.emit(`${this.indent()}/*${t.comment}*/`,t.position)}container(t){return this.compress?this.emit(`@container ${t.container}`,t.position)+this.emit("{")+this.mapVisit(t.rules)+this.emit("}"):this.emit(`${this.indent()}@container ${t.container}`,t.position)+this.emit(` {\n${this.indent(1)}`)+this.mapVisit(t.rules,"\n\n")+this.emit(`\n${this.indent(-1)}${this.indent()}}`)}layer(t){return this.compress?this.emit(`@layer ${t.layer}`,t.position)+(t.rules?this.emit("{")+this.mapVisit(t.rules)+this.emit("}"):";"):this.emit(`${this.indent()}@layer ${t.layer}`,t.position)+(t.rules?this.emit(` {\n${this.indent(1)}`)+this.mapVisit(t.rules,"\n\n")+this.emit(`\n${this.indent(-1)}${this.indent()}}`):";")}import(t){return this.emit(`@import ${t.import};`,t.position)}media(t){return this.compress?this.emit(`@media ${t.media}`,t.position)+this.emit("{")+this.mapVisit(t.rules)+this.emit("}"):this.emit(`${this.indent()}@media ${t.media}`,t.position)+this.emit(` {\n${this.indent(1)}`)+this.mapVisit(t.rules,"\n\n")+this.emit(`\n${this.indent(-1)}${this.indent()}}`)}document(t){const n=`@${t.vendor||""}document ${t.document}`;return this.compress?this.emit(n,t.position)+this.emit("{")+this.mapVisit(t.rules)+this.emit("}"):this.emit(n,t.position)+this.emit(` {\n${this.indent(1)}`)+this.mapVisit(t.rules,"\n\n")+this.emit(`${this.indent(-1)}\n}`)}charset(t){return this.emit(`@charset ${t.charset};`,t.position)}namespace(t){return this.emit(`@namespace ${t.namespace};`,t.position)}startingStyle(t){return this.compress?this.emit("@starting-style",t.position)+this.emit("{")+this.mapVisit(t.rules)+this.emit("}"):this.emit(`${this.indent()}@starting-style`,t.position)+this.emit(` {\n${this.indent(1)}`)+this.mapVisit(t.rules,"\n\n")+this.emit(`\n${this.indent(-1)}${this.indent()}}`)}supports(t){return this.compress?this.emit(`@supports ${t.supports}`,t.position)+this.emit("{")+this.mapVisit(t.rules)+this.emit("}"):this.emit(`${this.indent()}@supports ${t.supports}`,t.position)+this.emit(` {\n${this.indent(1)}`)+this.mapVisit(t.rules,"\n\n")+this.emit(`\n${this.indent(-1)}${this.indent()}}`)}keyframes(t){return this.compress?this.emit(`@${t.vendor||""}keyframes ${t.name}`,t.position)+this.emit("{")+this.mapVisit(t.keyframes)+this.emit("}"):this.emit(`@${t.vendor||""}keyframes ${t.name}`,t.position)+this.emit(` {\n${this.indent(1)}`)+this.mapVisit(t.keyframes,"\n")+this.emit(`${this.indent(-1)}}`)}keyframe(t){const n=t.declarations;return this.compress?this.emit(t.values.join(","),t.position)+this.emit("{")+this.mapVisit(n)+this.emit("}"):this.emit(this.indent())+this.emit(t.values.join(", "),t.position)+this.emit(` {\n${this.indent(1)}`)+this.mapVisit(n,"\n")+this.emit(`${this.indent(-1)}\n${this.indent()}}\n`)}page(t){if(this.compress){const n=t.selectors.length?t.selectors.join(", "):"";return this.emit(`@page ${n}`,t.position)+this.emit("{")+this.mapVisit(t.declarations)+this.emit("}")}const n=t.selectors.length?`${t.selectors.join(", ")} `:"";return this.emit(`@page ${n}`,t.position)+this.emit("{\n")+this.emit(this.indent(1))+this.mapVisit(t.declarations,"\n")+this.emit(this.indent(-1))+this.emit("\n}")}fontFace(t){return this.compress?this.emit("@font-face",t.position)+this.emit("{")+this.mapVisit(t.declarations)+this.emit("}"):this.emit("@font-face ",t.position)+this.emit("{\n")+this.emit(this.indent(1))+this.mapVisit(t.declarations,"\n")+this.emit(this.indent(-1))+this.emit("\n}")}host(t){return this.compress?this.emit("@host",t.position)+this.emit("{")+this.mapVisit(t.rules)+this.emit("}"):this.emit("@host",t.position)+this.emit(` {\n${this.indent(1)}`)+this.mapVisit(t.rules,"\n\n")+this.emit(`${this.indent(-1)}\n}`)}customMedia(t){return this.emit(`@custom-media ${t.name} ${t.media};`,t.position)}rule(t){const n=t.declarations;if(!n.length)return"";if(this.compress)return this.emit(t.selectors.join(","),t.position)+this.emit("{")+this.mapVisit(n)+this.emit("}");const e=this.indent();return this.emit(t.selectors.map(t=>e+t).join(",\n"),t.position)+this.emit(" {\n")+this.emit(this.indent(1))+this.mapVisit(n,"\n")+this.emit(this.indent(-1))+this.emit(`\n${this.indent()}}`)}declaration(t){return this.compress?this.emit(`${t.property}:${t.value}`,t.position)+this.emit(";"):"grid-template-areas"===t.property?this.emit(this.indent())+this.emit(t.property+": "+t.value.split("\n").join("\n".padEnd(22)+this.indent()),t.position)+this.emit(";"):this.emit(this.indent())+this.emit(`${t.property}: ${t.value}`,t.position)+this.emit(";")}}const u=(s,h)=>{h=h||{};let u=1,a=1;function f(){const t={line:u,column:a};return e=>(e.position=new n(t,{line:u,column:a},h?.source||""),$(),e)}const l=[];function m(n){const e=new t(h?.source||"",n,u,a,s);if(!h?.silent)throw e;l.push(e)}function p(){const t=/^{\s*/.exec(s);return!!t&&(g(t),!0)}function d(){const t=/^}/.exec(s);return!!t&&(g(t),!0)}function y(){let t;const n=[];for($(),E(n);s.length&&"}"!==s.charAt(0)&&(t=S()||j(),t);)n.push(t),E(n);return n}function g(t){const n=t[0];return function(t){const n=t.match(/\n/g);n&&(u+=n.length);const e=t.lastIndexOf("\n");a=~e?t.length-e:a+t.length}(n),s=s.slice(n.length),t}function $(){const t=/^\s*/.exec(s);t&&g(t)}function E(t){t=t||[];let n=T();for(;n;)t.push(n),n=T();return t}function T(){const t=f();if("/"!==s.charAt(0)||"*"!==s.charAt(1))return;const n=/^\/\*[^]*?\*\//.exec(s);return n?(g(n),t({type:e.comment,comment:n[0].slice(2,-2)})):m("End of comment missing")}function L(){const t=/^([^{]+)/.exec(s);if(t)return g(t),((t,n)=>{const e=[];let s=0;for(;s<t.length;){const r=i(t,n,s);if(-1===r)return e.push(t.substring(s)),e;e.push(t.substring(s,r)),s=r+1}return e})(o(t[0]).replace(r,""),[","]).map(t=>o(t))}function M(){const t=f(),n=/^(\*?[-#/*\\\w]+(\[[0-9a-z_-]+\])?)\s*/.exec(s);if(!n)return;g(n);const c=o(n[0]),h=/^:\s*/.exec(s);if(!h)return m("property missing ':'");g(h);let u="";const a=i(s,[";","}"]);-1!==a&&(u=s.substring(0,a),g([u]),u=o(u).replace(r,""));const l=t({type:e.declaration,property:c.replace(r,""),value:u}),p=/^[;\s]*/.exec(s);return p&&g(p),l}function H(){const t=[];if(!p())return m("missing '{'");E(t);let n=M();for(;n;)t.push(n),E(t),n=M();return d()?t:m("missing '}'")}function w(){const t=[],n=f();let i=/^((\d+\.\d+|\.\d+|\d+)%?|[a-z]+)\s*/.exec(s);for(;i;){const n=g(i);t.push(n[1]);const e=/^,\s*/.exec(s);e&&g(e),i=/^((\d+\.\d+|\.\d+|\d+)%?|[a-z]+)\s*/.exec(s)}if(t.length)return n({type:e.keyframe,values:t,declarations:H()||[]})}const b=B("import"),v=B("charset"),k=B("namespace");function B(t){const n=new RegExp("^@"+t+"\\s*((?::?[^;'\"]|\"(?:\\\\\"|[^\"])*?\"|'(?:\\\\'|[^'])*?')+)(?:;|$)");return()=>{const e=f(),i=n.exec(s);if(!i)return;const r=g(i),o={type:t};return o[t]=r[1].trim(),e(o)}}function S(){if("@"===s[0])return function(){const t=f(),n=/^@([-\w]+)?keyframes\s*/.exec(s);if(!n)return;const i=g(n)[1],r=/^([-\w]+)\s*/.exec(s);if(!r)return m("@keyframes missing name");const o=g(r)[1];if(!p())return m("@keyframes missing '{'");let c=E(),h=w();for(;h;)c.push(h),c=c.concat(E()),h=w();return d()?t({type:e.keyframes,name:o,vendor:i,keyframes:c}):m("@keyframes missing '}'")}()||function(){const t=f(),n=/^@media *([^{]+)/.exec(s);if(!n)return;const i=o(g(n)[1]);if(!p())return m("@media missing '{'");const r=E().concat(y());return d()?t({type:e.media,media:i,rules:r}):m("@media missing '}'")}()||function(){const t=f(),n=/^@custom-media\s+(--\S+)\s+([^{;\s][^{;]*);/.exec(s);if(!n)return;const i=g(n);return t({type:e.customMedia,name:o(i[1]),media:o(i[2])})}()||function(){const t=f(),n=/^@supports *([^{]+)/.exec(s);if(!n)return;const i=o(g(n)[1]);if(!p())return m("@supports missing '{'");const r=E().concat(y());return d()?t({type:e.supports,supports:i,rules:r}):m("@supports missing '}'")}()||b()||v()||k()||function(){const t=f(),n=/^@([-\w]+)?document *([^{]+)/.exec(s);if(!n)return;const i=g(n),r=o(i[1]),c=o(i[2]);if(!p())return m("@document missing '{'");const h=E().concat(y());return d()?t({type:e.document,document:c,vendor:r,rules:h}):m("@document missing '}'")}()||function(){const t=f(),n=/^@page */.exec(s);if(!n)return;g(n);const i=L()||[];if(!p())return m("@page missing '{'");let r=E(),o=M();for(;o;)r.push(o),r=r.concat(E()),o=M();return d()?t({type:e.page,selectors:i,declarations:r}):m("@page missing '}'")}()||function(){const t=f(),n=/^@host\s*/.exec(s);if(!n)return;if(g(n),!p())return m("@host missing '{'");const i=E().concat(y());return d()?t({type:e.host,rules:i}):m("@host missing '}'")}()||function(){const t=f(),n=/^@font-face\s*/.exec(s);if(!n)return;if(g(n),!p())return m("@font-face missing '{'");let i=E(),r=M();for(;r;)i.push(r),i=i.concat(E()),r=M();return d()?t({type:e.fontFace,declarations:i}):m("@font-face missing '}'")}()||function(){const t=f(),n=/^@container *([^{]+)/.exec(s);if(!n)return;const i=o(g(n)[1]);if(!p())return m("@container missing '{'");const r=E().concat(y());return d()?t({type:e.container,container:i,rules:r}):m("@container missing '}'")}()||function(){const t=f(),n=/^@starting-style\s*/.exec(s);if(!n)return;if(g(n),!p())return m("@starting-style missing '{'");const i=E().concat(y());return d()?t({type:e.startingStyle,rules:i}):m("@starting-style missing '}'")}()||function(){const t=f(),n=/^@layer *([^{;@]+)/.exec(s);if(!n)return;const i=o(g(n)[1]);if(!p()){const n=/^[;\s]*/.exec(s);return n&&g(n),t({type:e.layer,layer:i})}const r=E().concat(y());return d()?t({type:e.layer,layer:i,rules:r}):m("@layer missing '}'")}()}function j(){const t=f(),n=L();return n?(E(),t({type:e.rule,selectors:n,declarations:H()||[]})):m("selector missing")}return c(function(){const t=y();return{type:e.stylesheet,stylesheet:{source:h?.source,rules:t,parsingErrors:l}}}())},a=Reflect.apply,f=Reflect.get,l=Reflect.defineProperty,m=Array.isArray,p=Object.keys,d=Object.assign,y=Object.is,g=Number.isSafeInteger,$=t=>"object"==typeof t&&null!==t,E=document.createElement.bind(document),T=document.createTextNode.bind(document);function L(t,n){const e=[];for(let s=0;s<t.length;s++)e.push(t[s]),s<n.length&&e.push(String(n[s]));return e.join("").replace(/\r\n/g,"\n").trim()}function M(t,...n){return L(t,n)}function H(t){return function(n,...s){const i=L(n,s),r=u(i),o=n=>{if(!$(n))return;n.type===e.rule&&(n.selectors=n.selectors.map(n=>`[${t}]${n}`));const s=p(n),i=s.length;for(let t=0;t<i;t++){const e=f(n,s[t]);if(m(e)){const t=e.length;for(let n=0;n<t;n++)o(e[n]);continue}$(e)&&o(e)}};o(r);const c=((t,n)=>new h(n||{}).compile(t))(r);return c}}class w extends(null){static kid=0;static scopeIndex=0;static genScopeName(){return"data-k-"+(++w.scopeIndex).toString(36).padStart(6,"0")}static nextKid(){return++w.kid}}const b=Symbol();function v(t,n,e=b){if(y(e,b))return a(addEventListener,this,[t,n]),n;if(!$(e)||!("triggerLimit"in e))return a(addEventListener,this,[t,n,e]),n;const s=e.triggerLimit;if(delete e.triggerLimit,!g(s)||s<=0)throw new TypeError("[Kt.js:kon] options.triggerLimit must be a positive safe integer.");if(1===s)return e.once=!0,a(addEventListener,this,[t,n,e]),n;let i=s;const r=function(s){const o=a(n,this,[s]);return i--,i<=0&&a(removeEventListener,this,[t,r,e]),o};return a(addEventListener,this,[t,r,e]),r}function k(t,n,e=b){y(b,e)?a(removeEventListener,this,[t,n]):a(removeEventListener,this,[t,n,e])}function B(t){return t.appendChild(this)}function S(t,n="",e=""){if("string"!=typeof t)throw new TypeError("[Kt.js:h] tagName must be a string.");if("string"!=typeof n&&!$(n))throw new TypeError("[Kt.js:h] attr must be an object.");if("string"!=typeof e&&!$(e)&&!m(e))throw new TypeError("[Kt.js:h] content must be a string or an array of html elements.");const s=E(t);if(l(s,"kid",{value:w.nextKid(),enumerable:!0}),l(s,"isKT",{value:!0}),s.kon=v,s.koff=k,s.kmount=B,"string"==typeof e){const t=T(e);s.appendChild(t)}else if(m(e)){const t=e.length;for(let n=0;n<t;n++){const t=e[n];if("string"!=typeof t){if(!t.isKT)throw new TypeError("[Kt.js:h] content must be a string or an array of HTMLEnhancedElement.");s.appendChild(t)}else s.appendChild(T(t))}}else e.isKT&&s.appendChild(e);if(!n)return s;if("string"==typeof n)return s.className=n,s;n.class&&(m(n.class)?s.classList.add(...n.class):s.className=n.class,delete n.class),n.style&&("string"==typeof n.style?s.setAttribute("style",n.style):d(s.style,n.style),delete n.style);const i=p(n),r=i.length;for(let t=0;t<r;t++){const e=i[t],r=n[e];"function"!=typeof r&&("checked"!==e?"value"!==e?"selected"!==e?"defaultValue"!==e?"defaultChecked"!==e?"defaultSelected"!==e?"disabled"!==e?"readOnly"!==e?"multiple"!==e?"autofocus"!==e?"required"!==e?"hidden"!==e?"open"===e&&s instanceof HTMLDetailsElement?s.open=Boolean(r):"controls"===e&&s instanceof HTMLMediaElement?s.controls=Boolean(r):"autoplay"===e&&s instanceof HTMLMediaElement?s.autoplay=Boolean(r):"loop"===e&&s instanceof HTMLMediaElement?s.loop=Boolean(r):"muted"===e&&s instanceof HTMLMediaElement?s.muted=Boolean(r):"defer"===e&&s instanceof HTMLScriptElement?s.defer=Boolean(r):"async"===e&&s instanceof HTMLScriptElement?s.async=Boolean(r):s.setAttribute(e,r):s.hidden=Boolean(r):s instanceof HTMLInputElement||s instanceof HTMLSelectElement||s instanceof HTMLTextAreaElement?s.required=Boolean(r):s.setAttribute(e,r):s instanceof HTMLInputElement||s instanceof HTMLButtonElement||s instanceof HTMLSelectElement||s instanceof HTMLTextAreaElement?s.autofocus=Boolean(r):s.setAttribute(e,r):s instanceof HTMLSelectElement?s.multiple=Boolean(r):s.setAttribute(e,r):s instanceof HTMLInputElement||s instanceof HTMLTextAreaElement?s.readOnly=Boolean(r):s.setAttribute(e,r):s instanceof HTMLInputElement||s instanceof HTMLButtonElement||s instanceof HTMLSelectElement||s instanceof HTMLOptGroupElement||s instanceof HTMLOptionElement||s instanceof HTMLFieldSetElement||s instanceof HTMLTextAreaElement?s.disabled=Boolean(r):s.setAttribute(e,r):s instanceof HTMLOptionElement?s.defaultSelected=Boolean(r):s.setAttribute(e,r):s instanceof HTMLInputElement?s.defaultChecked=Boolean(r):s.setAttribute(e,r):s instanceof HTMLInputElement||s instanceof HTMLTextAreaElement?s.defaultValue=String(r):s.setAttribute(e,r):s instanceof HTMLOptionElement?s.selected=Boolean(r):s.setAttribute(e,r):s instanceof HTMLInputElement||s instanceof HTMLTextAreaElement||s instanceof HTMLSelectElement?s.value=String(r):s.setAttribute(e,r):s instanceof HTMLInputElement?s.checked=Boolean(r):s.setAttribute(e,r))}return s}function j(t){return function(...n){const e=S(...n);return e.setAttribute(t,""),e}}function x(t=w.genScopeName()){return{h:j(t),css:H(t)}}export{M as css,S as h,x as useScope};
1
+ const e=Symbol("KText"),t=Symbol("NotProvided"),n=Reflect.set,o=Reflect.get,i=Reflect.defineProperty,r=Array.isArray,s=Array.from,a=Object.keys,l=Object.assign,c=document.getElementById.bind(document),f=document.createElement.bind(document),u=document.createTextNode.bind(document),m=HTMLElement.prototype.addEventListener,T=HTMLElement.prototype.removeEventListener,d=HTMLElement.prototype.appendChild,h=HTMLElement.prototype.setAttribute;class E extends(null){static kid=0;static index=0;static genIndex(){return"data-k-"+(++E.index).toString(36).padStart(6,"0")}static nextKid(){return++E.kid}}const p=Object.is,M=Number.isSafeInteger,L=e=>"object"==typeof e&&null!==e,H={get:function(){return o(this,e).textContent},set:function(t){o(this,e).textContent=t}},y={value:!0},w={get(){return s(this.children)},set(e){this.innerHTML="";const t=e.length;for(let n=0;n<t;n++){const t=e[n];if("string"!=typeof t){if(!(t instanceof Text||t.isKT))throw new TypeError(`[Kt.js:kchildren] Invalid child element at index ${n}. Only string, Text nodes or KT.js enhanced elements are allowed.`);d.call(this,t)}else d.call(this,u(t))}}};function B(e,n,o=t){if(p(o,t))return m.call(this,e,n),n;if(!L(o)||!("triggerLimit"in o))return m.call(this,e,n,o),n;const i=o.triggerLimit;if(delete o.triggerLimit,!M(i)||i<=0)throw new TypeError("[Kt.js:kon] options.triggerLimit must be a positive safe integer.");if(1===i)return o.once=!0,m.call(this,e,n,o),n;let r=i;const s=function(t){const i=n.call(this,t);return r--,r<=0&&T.call(this,e,s,o),i};return m.call(this,e,s,o),s}function g(e,n,o=t){p(t,o)?T.call(this,e,n):T.call(this,e,n,o)}function b(e){return d.call(e,this)}function x(e){i(e,"kid",{value:E.nextKid(),enumerable:!0}),i(e,"isKT",y),i(e,"ktext",H),i(e,"kchildren",w),e.kon=B,e.koff=g,e.kmount=b}class S{t=null;o=null;add(e,t){if("function"!=typeof t)throw new TypeError("Branch must be a function");return e&&(this.t=t),this}nomatch(e){if("function"!=typeof e)throw new TypeError("Branch must be a function");return this.t||e(),this}deferedNomatch(e){if("function"!=typeof e)throw new TypeError("Branch must be a function");return this.o=e,this}run(...e){return this.t?this.t(...e):this.o?this.o(...e):void 0}}const j=()=>new S,I=(e,t)=>e.className=t,K=(e,t)=>{t.class&&(r(t.class)?e.classList.add(...t.class):e.className=t.class,delete t.class),t.style&&("string"==typeof t.style?e.setAttribute("style",t.style):l(e.style,t.style),delete t.style);const n=a(t),o=n.length;for(let i=0;i<o;i++){const o=n[i],r=t[o];"function"!=typeof r&&("checked"!==o?"value"!==o?"selected"!==o?"defaultValue"!==o?"defaultChecked"!==o?"defaultSelected"!==o?"disabled"!==o?"readOnly"!==o?"multiple"!==o?"autofocus"!==o?"required"!==o?"hidden"!==o?"open"===o&&e instanceof HTMLDetailsElement?e.open=Boolean(r):"controls"===o&&e instanceof HTMLMediaElement?e.controls=Boolean(r):"autoplay"===o&&e instanceof HTMLMediaElement?e.autoplay=Boolean(r):"loop"===o&&e instanceof HTMLMediaElement?e.loop=Boolean(r):"muted"===o&&e instanceof HTMLMediaElement?e.muted=Boolean(r):"defer"===o&&e instanceof HTMLScriptElement?e.defer=Boolean(r):"async"===o&&e instanceof HTMLScriptElement?e.async=Boolean(r):h.call(e,String(o),r):e.hidden=Boolean(r):e instanceof HTMLInputElement||e instanceof HTMLSelectElement||e instanceof HTMLTextAreaElement?e.required=Boolean(r):h.call(e,o,r):e instanceof HTMLInputElement||e instanceof HTMLButtonElement||e instanceof HTMLSelectElement||e instanceof HTMLTextAreaElement?e.autofocus=Boolean(r):h.call(e,o,r):e instanceof HTMLSelectElement?e.multiple=Boolean(r):h.call(e,o,r):e instanceof HTMLInputElement||e instanceof HTMLTextAreaElement?e.readOnly=Boolean(r):h.call(e,o,r):e instanceof HTMLInputElement||e instanceof HTMLButtonElement||e instanceof HTMLSelectElement||e instanceof HTMLOptGroupElement||e instanceof HTMLOptionElement||e instanceof HTMLFieldSetElement||e instanceof HTMLTextAreaElement?e.disabled=Boolean(r):h.call(e,o,r):e instanceof HTMLOptionElement?e.defaultSelected=Boolean(r):h.call(e,o,r):e instanceof HTMLInputElement?e.defaultChecked=Boolean(r):h.call(e,o,r):e instanceof HTMLInputElement||e instanceof HTMLTextAreaElement?e.defaultValue=String(r):h.call(e,o,r):e instanceof HTMLOptionElement?e.selected=Boolean(r):h.call(e,o,r):e instanceof HTMLInputElement||e instanceof HTMLTextAreaElement||e instanceof HTMLSelectElement?e.value=String(r):h.call(e,o,r):e instanceof HTMLInputElement?e.checked=Boolean(r):h.call(e,o,r))}},k=()=>{throw new TypeError("[Kt.js:h] attr must be an object.")},O=(e,t)=>{e.ktext=t},A=(e,t)=>{const n=t.length;for(let o=0;o<n;o++){const n=t[o];"string"!=typeof n?n.isKT?d.call(e,n):N():d.call(e,u(n))}},v=(e,t)=>{t.isKT||N(),d.call(e,t)},N=()=>{throw new TypeError("[Kt.js:h] content must be a string, HTMLEnhancedElement or an array of HTMLEnhancedElement.")};function R(t,o="",i=""){if("string"!=typeof t)throw new TypeError("[Kt.js:h] tagName must be a string.");const s=(e=>j().add("string"==typeof e,I).add(L(e),K).nomatch(k))(o),a=(e=>j().add("string"==typeof e,O).add(L(e),v).add(r(e),A).nomatch(N))(i),l=f(t),c=u("");return d.call(l,c),n(l,e,c),x(l),a.run(l,i),s.run(l,o),l}function q(e,n=t){if(!e.isKT)throw new TypeError("Root element must be a KText element.");const o=c("app")??document.body;if(p(n,t)&&e.kmount(o),!L(n))throw new TypeError("mountTo must be an HTMLElement or omitted.")}export{q as createApp,R as h};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kt.js",
3
- "version": "0.0.2",
3
+ "version": "0.0.4",
4
4
  "author": {
5
5
  "name": "Kasukabe Tsumugi",
6
6
  "email": "futami16237@gmail.com"
@@ -42,6 +42,7 @@
42
42
  "devDependencies": {
43
43
  "@babel/plugin-proposal-decorators": "^7.28.0",
44
44
  "@babel/preset-env": "^7.28.3",
45
+ "@emotion/css": "^11.13.5",
45
46
  "@rollup/plugin-alias": "^5.1.1",
46
47
  "@rollup/plugin-babel": "^6.0.4",
47
48
  "@rollup/plugin-commonjs": "^28.0.6",
@@ -64,6 +65,6 @@
64
65
  "vitest": "^3.2.4"
65
66
  },
66
67
  "dependencies": {
67
- "@adobe/css-tools": "^4.4.4"
68
+ "defered-branch": "^1.2.2"
68
69
  }
69
70
  }