@ktjs/core 0.22.0 → 0.22.5

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/dist/index.d.ts CHANGED
@@ -7,6 +7,8 @@ type HTMLTag = keyof HTMLElementTagNameMap;
7
7
  type SVGTag = keyof SVGElementTagNameMap;
8
8
  type MathMLTag = keyof MathMLElementTagNameMap;
9
9
 
10
+ type InputElementTag = 'input' | 'select' | 'textarea';
11
+
10
12
  type RefChangeHandler<T> = (newValue: T, oldValue: T) => void;
11
13
  declare class KTRef<T> {
12
14
  /**
@@ -19,6 +21,10 @@ declare class KTRef<T> {
19
21
  */
20
22
  get value(): T;
21
23
  set value(newValue: T);
24
+ /**
25
+ * Register a callback when the value changes
26
+ * @param callback (newValue, oldValue) => xxx
27
+ */
22
28
  addOnChange(callback: RefChangeHandler<T>): void;
23
29
  removeOnChange(callback: RefChangeHandler<T>): boolean;
24
30
  }
@@ -27,9 +33,11 @@ declare const isKTRef: <T = any>(obj: any) => obj is KTRef<T>;
27
33
  * Reference to the created HTML element.
28
34
  * - **Only** respond to `ref.value` changes, not reactive to internal changes of the element.
29
35
  * - can alse be used to store normal values, but it is not reactive.
36
+ * - if the value is already a `KTRef`, it will be returned **directly**.
30
37
  * @param value mostly an HTMLElement
31
38
  */
32
- declare function ref<T = JSX.Element>(value?: T, onChange?: RefChangeHandler<T>): KTRef<T>;
39
+ declare function ref<T = JSX.Element>(value?: T | KTRef<T>, onChange?: RefChangeHandler<T>): KTRef<T>;
40
+ declare function deref<T = JSX.Element>(value: T | KTRef<T>): T;
33
41
  type KTSurfaceRef<T extends Object> = {
34
42
  [K in keyof T]: KTRef<T[K]>;
35
43
  } & {
@@ -43,6 +51,10 @@ type KTSurfaceRef<T extends Object> = {
43
51
  * - `obj.a.b` is not reactive
44
52
  */
45
53
  declare const surfaceRef: <T extends Object>(obj: T) => KTSurfaceRef<T>;
54
+ /**
55
+ * Assert k-model to be a ref object
56
+ */
57
+ declare const $modelOrRef: <T = any>(props: any, defaultValue?: T) => KTRef<T>;
46
58
 
47
59
  type HTML<T extends (HTMLTag | SVGTag | MathMLTag) & otherstring> = T extends SVGTag
48
60
  ? SVGElementTagNameMap[T]
@@ -160,7 +172,7 @@ type KTComponent = (
160
172
  * ## About
161
173
  * @package @ktjs/core
162
174
  * @author Kasukabe Tsumugi <futami16237@gmail.com>
163
- * @version 0.22.0 (Last Update: 2026.02.02 17:11:04.703)
175
+ * @version 0.22.5 (Last Update: 2026.02.03 09:07:21.411)
164
176
  * @license MIT
165
177
  * @link https://github.com/baendlorel/kt.js
166
178
  * @link https://baendlorel.github.io/ Welcome to my site!
@@ -1465,5 +1477,5 @@ interface KTForProps<T> {
1465
1477
  */
1466
1478
  declare function KTFor<T>(props: KTForProps<T>): KTForElement;
1467
1479
 
1468
- export { Fragment, KTAsync, KTFor, KTRef, h as createElement, createRedrawable, h, isKTRef, jsx, jsxDEV, jsxs, ref, surfaceRef };
1469
- export type { EventHandler, HTMLTag, KTAttribute, KTForElement, KTForProps, KTRawAttr, KTRawContent, KTRawContents, KTSurfaceRef };
1480
+ export { $modelOrRef, Fragment, KTAsync, KTFor, KTRef, h as createElement, createRedrawable, deref, h, isKTRef, jsx, jsxDEV, jsxs, ref, surfaceRef };
1481
+ export type { EventHandler, HTMLTag, InputElementTag, KTAttribute, KTForElement, KTForProps, KTRawAttr, KTRawContent, KTRawContents, KTSurfaceRef, MathMLTag, SVGTag };
@@ -6,10 +6,8 @@ var __ktjs_core__ = (function (exports) {
6
6
  const $entries = Object.entries;
7
7
  const $isThenable = (o) => typeof o === 'object' && o !== null && typeof o.then === 'function';
8
8
 
9
- // Error handling utilities
10
- const $throw = (message) => {
11
- throw new Error('@ktjs/shared: ' + message);
12
- };
9
+ // DOM manipulation utilities
10
+ // # dom natives
13
11
  /**
14
12
  * & Remove `bind` because it is shockingly slower than wrapper
15
13
  * & `window.document` is safe because it is not configurable and its setter is undefined
@@ -46,10 +44,18 @@ var __ktjs_core__ = (function (exports) {
46
44
  }
47
45
  };
48
46
  const { get: $buttonDisabledGetter, set: $buttonDisabledSetter } = Object.getOwnPropertyDescriptor(HTMLButtonElement.prototype, 'disabled');
47
+ /**
48
+ * Used for `k-model`
49
+ */
50
+ const applyModel = (element, valueRef, propName, eventName) => {
51
+ element[propName] = valueRef.value; // initialize
52
+ valueRef.addOnChange((newValue) => (element[propName] = newValue));
53
+ element.addEventListener(eventName, () => (valueRef.value = element[propName]));
54
+ };
49
55
 
50
56
  // Shared utilities and cached native methods for kt.js framework
51
57
  // Re-export all utilities
52
- Object.defineProperty(window, '@ktjs/shared', { value: '0.20.2' });
58
+ Object.defineProperty(window, '__ktjs__', { value: '0.22.2' });
53
59
 
54
60
  class KTRef {
55
61
  /**
@@ -91,7 +97,14 @@ var __ktjs_core__ = (function (exports) {
91
97
  this._onChanges[i](newValue, oldValue);
92
98
  }
93
99
  }
100
+ /**
101
+ * Register a callback when the value changes
102
+ * @param callback (newValue, oldValue) => xxx
103
+ */
94
104
  addOnChange(callback) {
105
+ if (typeof callback !== 'function') {
106
+ throw new Error('[kt.js error] KTRef.addOnChange: callback must be a function');
107
+ }
95
108
  this._onChanges.push(callback);
96
109
  }
97
110
  removeOnChange(callback) {
@@ -104,18 +117,26 @@ var __ktjs_core__ = (function (exports) {
104
117
  return false;
105
118
  }
106
119
  }
107
- const isKTRef = (obj) => {
108
- return typeof obj === 'object' && obj !== null && obj.isKT === true;
109
- };
120
+ const isKTRef = (obj) => obj?.isKT === true;
110
121
  /**
111
122
  * Reference to the created HTML element.
112
123
  * - **Only** respond to `ref.value` changes, not reactive to internal changes of the element.
113
124
  * - can alse be used to store normal values, but it is not reactive.
125
+ * - if the value is already a `KTRef`, it will be returned **directly**.
114
126
  * @param value mostly an HTMLElement
115
127
  */
116
128
  function ref(value, onChange) {
129
+ if (isKTRef(value)) {
130
+ if (onChange) {
131
+ value.addOnChange(onChange);
132
+ }
133
+ return value;
134
+ }
117
135
  return new KTRef(value, onChange ? [onChange] : []);
118
136
  }
137
+ function deref(value) {
138
+ return isKTRef(value) ? value.value : value;
139
+ }
119
140
  function kcollect() {
120
141
  const newObj = {};
121
142
  const entries = $entries(this);
@@ -140,6 +161,21 @@ var __ktjs_core__ = (function (exports) {
140
161
  }
141
162
  return newObj;
142
163
  };
164
+ // # asserts
165
+ /**
166
+ * Assert k-model to be a ref object
167
+ */
168
+ const $modelOrRef = (props, defaultValue) => {
169
+ // & props is an object. Won't use it in any other place
170
+ if ('k-model' in props) {
171
+ const kmodel = props['k-model'];
172
+ if (!kmodel?.isKT) {
173
+ throw new Error(`[kt.js error] k-model data must be a KTRef object, please use 'ref(...)' to wrap it.`);
174
+ }
175
+ return kmodel;
176
+ }
177
+ return ref(defaultValue);
178
+ };
143
179
 
144
180
  const booleanHandler = (element, key, value) => {
145
181
  if (key in element) {
@@ -228,7 +264,7 @@ var __ktjs_core__ = (function (exports) {
228
264
  attrIsObject(element, attr);
229
265
  }
230
266
  else {
231
- throw new Error('kt.js: attr must be an object.');
267
+ throw new Error('[kt.js error] attr must be an object.');
232
268
  }
233
269
  }
234
270
 
@@ -283,27 +319,28 @@ var __ktjs_core__ = (function (exports) {
283
319
  }
284
320
  }
285
321
 
286
- function register(element, valueRef, propName, eventName) {
287
- element[propName] = valueRef.value; // initialize
288
- valueRef.addOnChange((newValue) => (element[propName] = newValue));
289
- element.addEventListener(eventName, () => (valueRef.value = element[propName]));
290
- }
291
- function applyModel(element, valueRef) {
322
+ function applyKModel(element, valueRef) {
323
+ if (!isKTRef(valueRef)) {
324
+ console.warn('[kt.js warn] k-model value must be a KTRef.');
325
+ return;
326
+ }
292
327
  if (element instanceof HTMLInputElement) {
293
328
  if (element.type === 'radio' || element.type === 'checkbox') {
294
- register(element, valueRef, 'checked', 'change');
329
+ applyModel(element, valueRef, 'checked', 'change');
295
330
  }
296
331
  else {
297
- register(element, valueRef, 'value', 'input');
332
+ applyModel(element, valueRef, 'value', 'input');
298
333
  }
299
334
  }
300
335
  else if (element instanceof HTMLSelectElement) {
301
- register(element, valueRef, 'value', 'change');
336
+ applyModel(element, valueRef, 'value', 'change');
302
337
  }
303
338
  else if (element instanceof HTMLTextAreaElement) {
304
- register(element, valueRef, 'value', 'input');
339
+ applyModel(element, valueRef, 'value', 'input');
340
+ }
341
+ else {
342
+ console.warn('[kt.js warn] not supported element for k-model:');
305
343
  }
306
- console.warn('[kt.js warn] not supported element for k-model:', element.tagName);
307
344
  }
308
345
 
309
346
  const htmlCreator = (tag) => document.createElement(tag);
@@ -323,7 +360,7 @@ var __ktjs_core__ = (function (exports) {
323
360
  * ## About
324
361
  * @package @ktjs/core
325
362
  * @author Kasukabe Tsumugi <futami16237@gmail.com>
326
- * @version 0.22.0 (Last Update: 2026.02.02 17:11:04.703)
363
+ * @version 0.22.5 (Last Update: 2026.02.03 09:07:21.411)
327
364
  * @license MIT
328
365
  * @link https://github.com/baendlorel/kt.js
329
366
  * @link https://baendlorel.github.io/ Welcome to my site!
@@ -332,7 +369,7 @@ var __ktjs_core__ = (function (exports) {
332
369
  */
333
370
  const h = (tag, attr, content) => {
334
371
  if (typeof tag !== 'string') {
335
- $throw('tagName must be a string.');
372
+ throw new Error('[kt.js error] tagName must be a string.');
336
373
  }
337
374
  if (attr) {
338
375
  if (SVG_ATTR_FLAG in attr) {
@@ -355,10 +392,10 @@ var __ktjs_core__ = (function (exports) {
355
392
  if (typeof attr === 'object' && attr !== null && 'k-model' in attr) {
356
393
  const kmodel = attr['k-model'];
357
394
  if (isKTRef(kmodel)) {
358
- applyModel(element, kmodel);
395
+ applyKModel(element, kmodel);
359
396
  }
360
397
  else {
361
- $throw('k-model value must be a KTRef.');
398
+ throw new Error('[kt.js error] k-model value must be a KTRef.');
362
399
  }
363
400
  }
364
401
  return element;
@@ -413,7 +450,7 @@ var __ktjs_core__ = (function (exports) {
413
450
  * Note: kt.js doesn't have a real Fragment concept,
414
451
  */
415
452
  function Fragment(_props) {
416
- throw new Error("kt.js doesn't have a Fragment concept");
453
+ throw new Error("[kt.js error] doesn't have a Fragment concept");
417
454
  // const { children } = props ?? {};
418
455
  // if (!children) {
419
456
  // return ;
@@ -697,12 +734,14 @@ var __ktjs_core__ = (function (exports) {
697
734
  return result;
698
735
  }
699
736
 
737
+ exports.$modelOrRef = $modelOrRef;
700
738
  exports.Fragment = Fragment;
701
739
  exports.KTAsync = KTAsync;
702
740
  exports.KTFor = KTFor;
703
741
  exports.KTRef = KTRef;
704
742
  exports.createElement = h;
705
743
  exports.createRedrawable = createRedrawable;
744
+ exports.deref = deref;
706
745
  exports.h = h;
707
746
  exports.isKTRef = isKTRef;
708
747
  exports.jsx = jsx;
@@ -6,10 +6,8 @@ var __ktjs_core__ = (function (exports) {
6
6
  const $entries = Object.entries;
7
7
  const $isThenable = (o) => typeof o === 'object' && o !== null && typeof o.then === 'function';
8
8
 
9
- // Error handling utilities
10
- const $throw = (message) => {
11
- throw new Error('@ktjs/shared: ' + message);
12
- };
9
+ // DOM manipulation utilities
10
+ // # dom natives
13
11
  /**
14
12
  * & Remove `bind` because it is shockingly slower than wrapper
15
13
  * & `window.document` is safe because it is not configurable and its setter is undefined
@@ -46,10 +44,18 @@ var __ktjs_core__ = (function (exports) {
46
44
  }
47
45
  };
48
46
  const { get: $buttonDisabledGetter, set: $buttonDisabledSetter } = Object.getOwnPropertyDescriptor(HTMLButtonElement.prototype, 'disabled');
47
+ /**
48
+ * Used for `k-model`
49
+ */
50
+ const applyModel = (element, valueRef, propName, eventName) => {
51
+ element[propName] = valueRef.value; // initialize
52
+ valueRef.addOnChange((newValue) => (element[propName] = newValue));
53
+ element.addEventListener(eventName, () => (valueRef.value = element[propName]));
54
+ };
49
55
 
50
56
  // Shared utilities and cached native methods for kt.js framework
51
57
  // Re-export all utilities
52
- Object.defineProperty(window, '@ktjs/shared', { value: '0.20.2' });
58
+ Object.defineProperty(window, '__ktjs__', { value: '0.22.2' });
53
59
 
54
60
  var KTRef = /** @class */ (function () {
55
61
  function KTRef(_value, _onChanges) {
@@ -87,7 +93,14 @@ var __ktjs_core__ = (function (exports) {
87
93
  enumerable: false,
88
94
  configurable: true
89
95
  });
96
+ /**
97
+ * Register a callback when the value changes
98
+ * @param callback (newValue, oldValue) => xxx
99
+ */
90
100
  KTRef.prototype.addOnChange = function (callback) {
101
+ if (typeof callback !== 'function') {
102
+ throw new Error('[kt.js error] KTRef.addOnChange: callback must be a function');
103
+ }
91
104
  this._onChanges.push(callback);
92
105
  };
93
106
  KTRef.prototype.removeOnChange = function (callback) {
@@ -101,18 +114,26 @@ var __ktjs_core__ = (function (exports) {
101
114
  };
102
115
  return KTRef;
103
116
  }());
104
- var isKTRef = function (obj) {
105
- return typeof obj === 'object' && obj !== null && obj.isKT === true;
106
- };
117
+ var isKTRef = function (obj) { return (obj === null || obj === void 0 ? void 0 : obj.isKT) === true; };
107
118
  /**
108
119
  * Reference to the created HTML element.
109
120
  * - **Only** respond to `ref.value` changes, not reactive to internal changes of the element.
110
121
  * - can alse be used to store normal values, but it is not reactive.
122
+ * - if the value is already a `KTRef`, it will be returned **directly**.
111
123
  * @param value mostly an HTMLElement
112
124
  */
113
125
  function ref(value, onChange) {
126
+ if (isKTRef(value)) {
127
+ if (onChange) {
128
+ value.addOnChange(onChange);
129
+ }
130
+ return value;
131
+ }
114
132
  return new KTRef(value, onChange ? [onChange] : []);
115
133
  }
134
+ function deref(value) {
135
+ return isKTRef(value) ? value.value : value;
136
+ }
116
137
  function kcollect() {
117
138
  var newObj = {};
118
139
  var entries = $entries(this);
@@ -137,6 +158,21 @@ var __ktjs_core__ = (function (exports) {
137
158
  }
138
159
  return newObj;
139
160
  };
161
+ // # asserts
162
+ /**
163
+ * Assert k-model to be a ref object
164
+ */
165
+ var $modelOrRef = function (props, defaultValue) {
166
+ // & props is an object. Won't use it in any other place
167
+ if ('k-model' in props) {
168
+ var kmodel = props['k-model'];
169
+ if (!(kmodel === null || kmodel === void 0 ? void 0 : kmodel.isKT)) {
170
+ throw new Error("[kt.js error] k-model data must be a KTRef object, please use 'ref(...)' to wrap it.");
171
+ }
172
+ return kmodel;
173
+ }
174
+ return ref(defaultValue);
175
+ };
140
176
 
141
177
  var booleanHandler = function (element, key, value) {
142
178
  if (key in element) {
@@ -227,7 +263,7 @@ var __ktjs_core__ = (function (exports) {
227
263
  attrIsObject(element, attr);
228
264
  }
229
265
  else {
230
- throw new Error('kt.js: attr must be an object.');
266
+ throw new Error('[kt.js error] attr must be an object.');
231
267
  }
232
268
  }
233
269
 
@@ -285,27 +321,28 @@ var __ktjs_core__ = (function (exports) {
285
321
  }
286
322
  }
287
323
 
288
- function register(element, valueRef, propName, eventName) {
289
- element[propName] = valueRef.value; // initialize
290
- valueRef.addOnChange(function (newValue) { return (element[propName] = newValue); });
291
- element.addEventListener(eventName, function () { return (valueRef.value = element[propName]); });
292
- }
293
- function applyModel(element, valueRef) {
324
+ function applyKModel(element, valueRef) {
325
+ if (!isKTRef(valueRef)) {
326
+ console.warn('[kt.js warn] k-model value must be a KTRef.');
327
+ return;
328
+ }
294
329
  if (element instanceof HTMLInputElement) {
295
330
  if (element.type === 'radio' || element.type === 'checkbox') {
296
- register(element, valueRef, 'checked', 'change');
331
+ applyModel(element, valueRef, 'checked', 'change');
297
332
  }
298
333
  else {
299
- register(element, valueRef, 'value', 'input');
334
+ applyModel(element, valueRef, 'value', 'input');
300
335
  }
301
336
  }
302
337
  else if (element instanceof HTMLSelectElement) {
303
- register(element, valueRef, 'value', 'change');
338
+ applyModel(element, valueRef, 'value', 'change');
304
339
  }
305
340
  else if (element instanceof HTMLTextAreaElement) {
306
- register(element, valueRef, 'value', 'input');
341
+ applyModel(element, valueRef, 'value', 'input');
342
+ }
343
+ else {
344
+ console.warn('[kt.js warn] not supported element for k-model:');
307
345
  }
308
- console.warn('[kt.js warn] not supported element for k-model:', element.tagName);
309
346
  }
310
347
 
311
348
  var htmlCreator = function (tag) { return document.createElement(tag); };
@@ -325,7 +362,7 @@ var __ktjs_core__ = (function (exports) {
325
362
  * ## About
326
363
  * @package @ktjs/core
327
364
  * @author Kasukabe Tsumugi <futami16237@gmail.com>
328
- * @version 0.22.0 (Last Update: 2026.02.02 17:11:04.703)
365
+ * @version 0.22.5 (Last Update: 2026.02.03 09:07:21.411)
329
366
  * @license MIT
330
367
  * @link https://github.com/baendlorel/kt.js
331
368
  * @link https://baendlorel.github.io/ Welcome to my site!
@@ -334,7 +371,7 @@ var __ktjs_core__ = (function (exports) {
334
371
  */
335
372
  var h = function (tag, attr, content) {
336
373
  if (typeof tag !== 'string') {
337
- $throw('tagName must be a string.');
374
+ throw new Error('[kt.js error] tagName must be a string.');
338
375
  }
339
376
  if (attr) {
340
377
  if (SVG_ATTR_FLAG in attr) {
@@ -357,10 +394,10 @@ var __ktjs_core__ = (function (exports) {
357
394
  if (typeof attr === 'object' && attr !== null && 'k-model' in attr) {
358
395
  var kmodel = attr['k-model'];
359
396
  if (isKTRef(kmodel)) {
360
- applyModel(element, kmodel);
397
+ applyKModel(element, kmodel);
361
398
  }
362
399
  else {
363
- $throw('k-model value must be a KTRef.');
400
+ throw new Error('[kt.js error] k-model value must be a KTRef.');
364
401
  }
365
402
  }
366
403
  return element;
@@ -415,7 +452,7 @@ var __ktjs_core__ = (function (exports) {
415
452
  * Note: kt.js doesn't have a real Fragment concept,
416
453
  */
417
454
  function Fragment(_props) {
418
- throw new Error("kt.js doesn't have a Fragment concept");
455
+ throw new Error("[kt.js error] doesn't have a Fragment concept");
419
456
  // const { children } = props ?? {};
420
457
  // if (!children) {
421
458
  // return ;
@@ -706,12 +743,14 @@ var __ktjs_core__ = (function (exports) {
706
743
  return result;
707
744
  }
708
745
 
746
+ exports.$modelOrRef = $modelOrRef;
709
747
  exports.Fragment = Fragment;
710
748
  exports.KTAsync = KTAsync;
711
749
  exports.KTFor = KTFor;
712
750
  exports.KTRef = KTRef;
713
751
  exports.createElement = h;
714
752
  exports.createRedrawable = createRedrawable;
753
+ exports.deref = deref;
715
754
  exports.h = h;
716
755
  exports.isKTRef = isKTRef;
717
756
  exports.jsx = jsx;
package/dist/index.mjs CHANGED
@@ -3,10 +3,8 @@ const $isArray = Array.isArray;
3
3
  const $entries = Object.entries;
4
4
  const $isThenable = (o) => typeof o === 'object' && o !== null && typeof o.then === 'function';
5
5
 
6
- // Error handling utilities
7
- const $throw = (message) => {
8
- throw new Error('@ktjs/shared: ' + message);
9
- };
6
+ // DOM manipulation utilities
7
+ // # dom natives
10
8
  /**
11
9
  * & Remove `bind` because it is shockingly slower than wrapper
12
10
  * & `window.document` is safe because it is not configurable and its setter is undefined
@@ -43,10 +41,18 @@ const $append = // for ie 9/10/11
43
41
  }
44
42
  };
45
43
  const { get: $buttonDisabledGetter, set: $buttonDisabledSetter } = Object.getOwnPropertyDescriptor(HTMLButtonElement.prototype, 'disabled');
44
+ /**
45
+ * Used for `k-model`
46
+ */
47
+ const applyModel = (element, valueRef, propName, eventName) => {
48
+ element[propName] = valueRef.value; // initialize
49
+ valueRef.addOnChange((newValue) => (element[propName] = newValue));
50
+ element.addEventListener(eventName, () => (valueRef.value = element[propName]));
51
+ };
46
52
 
47
53
  // Shared utilities and cached native methods for kt.js framework
48
54
  // Re-export all utilities
49
- Object.defineProperty(window, '@ktjs/shared', { value: '0.20.2' });
55
+ Object.defineProperty(window, '__ktjs__', { value: '0.22.2' });
50
56
 
51
57
  class KTRef {
52
58
  /**
@@ -88,7 +94,14 @@ class KTRef {
88
94
  this._onChanges[i](newValue, oldValue);
89
95
  }
90
96
  }
97
+ /**
98
+ * Register a callback when the value changes
99
+ * @param callback (newValue, oldValue) => xxx
100
+ */
91
101
  addOnChange(callback) {
102
+ if (typeof callback !== 'function') {
103
+ throw new Error('[kt.js error] KTRef.addOnChange: callback must be a function');
104
+ }
92
105
  this._onChanges.push(callback);
93
106
  }
94
107
  removeOnChange(callback) {
@@ -101,18 +114,26 @@ class KTRef {
101
114
  return false;
102
115
  }
103
116
  }
104
- const isKTRef = (obj) => {
105
- return typeof obj === 'object' && obj !== null && obj.isKT === true;
106
- };
117
+ const isKTRef = (obj) => obj?.isKT === true;
107
118
  /**
108
119
  * Reference to the created HTML element.
109
120
  * - **Only** respond to `ref.value` changes, not reactive to internal changes of the element.
110
121
  * - can alse be used to store normal values, but it is not reactive.
122
+ * - if the value is already a `KTRef`, it will be returned **directly**.
111
123
  * @param value mostly an HTMLElement
112
124
  */
113
125
  function ref(value, onChange) {
126
+ if (isKTRef(value)) {
127
+ if (onChange) {
128
+ value.addOnChange(onChange);
129
+ }
130
+ return value;
131
+ }
114
132
  return new KTRef(value, onChange ? [onChange] : []);
115
133
  }
134
+ function deref(value) {
135
+ return isKTRef(value) ? value.value : value;
136
+ }
116
137
  function kcollect() {
117
138
  const newObj = {};
118
139
  const entries = $entries(this);
@@ -137,6 +158,21 @@ const surfaceRef = (obj) => {
137
158
  }
138
159
  return newObj;
139
160
  };
161
+ // # asserts
162
+ /**
163
+ * Assert k-model to be a ref object
164
+ */
165
+ const $modelOrRef = (props, defaultValue) => {
166
+ // & props is an object. Won't use it in any other place
167
+ if ('k-model' in props) {
168
+ const kmodel = props['k-model'];
169
+ if (!kmodel?.isKT) {
170
+ throw new Error(`[kt.js error] k-model data must be a KTRef object, please use 'ref(...)' to wrap it.`);
171
+ }
172
+ return kmodel;
173
+ }
174
+ return ref(defaultValue);
175
+ };
140
176
 
141
177
  const booleanHandler = (element, key, value) => {
142
178
  if (key in element) {
@@ -225,7 +261,7 @@ function applyAttr(element, attr) {
225
261
  attrIsObject(element, attr);
226
262
  }
227
263
  else {
228
- throw new Error('kt.js: attr must be an object.');
264
+ throw new Error('[kt.js error] attr must be an object.');
229
265
  }
230
266
  }
231
267
 
@@ -280,27 +316,28 @@ function applyContent(element, content) {
280
316
  }
281
317
  }
282
318
 
283
- function register(element, valueRef, propName, eventName) {
284
- element[propName] = valueRef.value; // initialize
285
- valueRef.addOnChange((newValue) => (element[propName] = newValue));
286
- element.addEventListener(eventName, () => (valueRef.value = element[propName]));
287
- }
288
- function applyModel(element, valueRef) {
319
+ function applyKModel(element, valueRef) {
320
+ if (!isKTRef(valueRef)) {
321
+ console.warn('[kt.js warn] k-model value must be a KTRef.');
322
+ return;
323
+ }
289
324
  if (element instanceof HTMLInputElement) {
290
325
  if (element.type === 'radio' || element.type === 'checkbox') {
291
- register(element, valueRef, 'checked', 'change');
326
+ applyModel(element, valueRef, 'checked', 'change');
292
327
  }
293
328
  else {
294
- register(element, valueRef, 'value', 'input');
329
+ applyModel(element, valueRef, 'value', 'input');
295
330
  }
296
331
  }
297
332
  else if (element instanceof HTMLSelectElement) {
298
- register(element, valueRef, 'value', 'change');
333
+ applyModel(element, valueRef, 'value', 'change');
299
334
  }
300
335
  else if (element instanceof HTMLTextAreaElement) {
301
- register(element, valueRef, 'value', 'input');
336
+ applyModel(element, valueRef, 'value', 'input');
337
+ }
338
+ else {
339
+ console.warn('[kt.js warn] not supported element for k-model:');
302
340
  }
303
- console.warn('[kt.js warn] not supported element for k-model:', element.tagName);
304
341
  }
305
342
 
306
343
  const htmlCreator = (tag) => document.createElement(tag);
@@ -320,7 +357,7 @@ const MATHML_ATTR_FLAG = '__kt_mathml__';
320
357
  * ## About
321
358
  * @package @ktjs/core
322
359
  * @author Kasukabe Tsumugi <futami16237@gmail.com>
323
- * @version 0.22.0 (Last Update: 2026.02.02 17:11:04.703)
360
+ * @version 0.22.5 (Last Update: 2026.02.03 09:07:21.411)
324
361
  * @license MIT
325
362
  * @link https://github.com/baendlorel/kt.js
326
363
  * @link https://baendlorel.github.io/ Welcome to my site!
@@ -329,7 +366,7 @@ const MATHML_ATTR_FLAG = '__kt_mathml__';
329
366
  */
330
367
  const h = (tag, attr, content) => {
331
368
  if (typeof tag !== 'string') {
332
- $throw('tagName must be a string.');
369
+ throw new Error('[kt.js error] tagName must be a string.');
333
370
  }
334
371
  if (attr) {
335
372
  if (SVG_ATTR_FLAG in attr) {
@@ -352,10 +389,10 @@ const h = (tag, attr, content) => {
352
389
  if (typeof attr === 'object' && attr !== null && 'k-model' in attr) {
353
390
  const kmodel = attr['k-model'];
354
391
  if (isKTRef(kmodel)) {
355
- applyModel(element, kmodel);
392
+ applyKModel(element, kmodel);
356
393
  }
357
394
  else {
358
- $throw('k-model value must be a KTRef.');
395
+ throw new Error('[kt.js error] k-model value must be a KTRef.');
359
396
  }
360
397
  }
361
398
  return element;
@@ -410,7 +447,7 @@ function jsx(tag, props) {
410
447
  * Note: kt.js doesn't have a real Fragment concept,
411
448
  */
412
449
  function Fragment(_props) {
413
- throw new Error("kt.js doesn't have a Fragment concept");
450
+ throw new Error("[kt.js error] doesn't have a Fragment concept");
414
451
  // const { children } = props ?? {};
415
452
  // if (!children) {
416
453
  // return ;
@@ -694,4 +731,4 @@ function getSequence(arr) {
694
731
  return result;
695
732
  }
696
733
 
697
- export { Fragment, KTAsync, KTFor, KTRef, h as createElement, createRedrawable, h, isKTRef, jsx, jsxDEV, jsxs, ref, surfaceRef };
734
+ export { $modelOrRef, Fragment, KTAsync, KTFor, KTRef, h as createElement, createRedrawable, deref, h, isKTRef, jsx, jsxDEV, jsxs, ref, surfaceRef };
@@ -19,6 +19,10 @@ declare class KTRef<T> {
19
19
  */
20
20
  get value(): T;
21
21
  set value(newValue: T);
22
+ /**
23
+ * Register a callback when the value changes
24
+ * @param callback (newValue, oldValue) => xxx
25
+ */
22
26
  addOnChange(callback: RefChangeHandler<T>): void;
23
27
  removeOnChange(callback: RefChangeHandler<T>): boolean;
24
28
  }
@@ -27,9 +31,11 @@ declare const isKTRef: <T = any>(obj: any) => obj is KTRef<T>;
27
31
  * Reference to the created HTML element.
28
32
  * - **Only** respond to `ref.value` changes, not reactive to internal changes of the element.
29
33
  * - can alse be used to store normal values, but it is not reactive.
34
+ * - if the value is already a `KTRef`, it will be returned **directly**.
30
35
  * @param value mostly an HTMLElement
31
36
  */
32
- declare function ref<T = JSX.Element>(value?: T, onChange?: RefChangeHandler<T>): KTRef<T>;
37
+ declare function ref<T = JSX.Element>(value?: T | KTRef<T>, onChange?: RefChangeHandler<T>): KTRef<T>;
38
+ declare function deref<T = JSX.Element>(value: T | KTRef<T>): T;
33
39
  type KTSurfaceRef<T extends Object> = {
34
40
  [K in keyof T]: KTRef<T[K]>;
35
41
  } & {
@@ -43,6 +49,10 @@ type KTSurfaceRef<T extends Object> = {
43
49
  * - `obj.a.b` is not reactive
44
50
  */
45
51
  declare const surfaceRef: <T extends Object>(obj: T) => KTSurfaceRef<T>;
52
+ /**
53
+ * Assert k-model to be a ref object
54
+ */
55
+ declare const $modelOrRef: <T = any>(props: any, defaultValue?: T) => KTRef<T>;
46
56
 
47
57
  type HTML<T extends (HTMLTag | SVGTag | MathMLTag) & otherstring> = T extends SVGTag
48
58
  ? SVGElementTagNameMap[T]
@@ -146,7 +156,7 @@ type KTAttribute = KTBaseAttribute & KTPrefixedEventHandlers;
146
156
  * ## About
147
157
  * @package @ktjs/core
148
158
  * @author Kasukabe Tsumugi <futami16237@gmail.com>
149
- * @version 0.22.0 (Last Update: 2026.02.02 17:11:04.703)
159
+ * @version 0.22.5 (Last Update: 2026.02.03 09:07:21.411)
150
160
  * @license MIT
151
161
  * @link https://github.com/baendlorel/kt.js
152
162
  * @link https://baendlorel.github.io/ Welcome to my site!
@@ -1425,5 +1435,5 @@ declare global {
1425
1435
  }
1426
1436
  }
1427
1437
 
1428
- export { Fragment, KTRef, h as createElement, createRedrawable, isKTRef, jsx, jsxDEV, jsxs, ref, surfaceRef };
1438
+ export { $modelOrRef, Fragment, KTRef, h as createElement, createRedrawable, deref, isKTRef, jsx, jsxDEV, jsxs, ref, surfaceRef };
1429
1439
  export type { KTSurfaceRef };
@@ -3,10 +3,8 @@ const $isArray = Array.isArray;
3
3
  const $entries = Object.entries;
4
4
  const $isThenable = (o) => typeof o === 'object' && o !== null && typeof o.then === 'function';
5
5
 
6
- // Error handling utilities
7
- const $throw = (message) => {
8
- throw new Error('@ktjs/shared: ' + message);
9
- };
6
+ // DOM manipulation utilities
7
+ // # dom natives
10
8
  /**
11
9
  * & Remove `bind` because it is shockingly slower than wrapper
12
10
  * & `window.document` is safe because it is not configurable and its setter is undefined
@@ -43,10 +41,18 @@ const $append = // for ie 9/10/11
43
41
  }
44
42
  };
45
43
  const { get: $buttonDisabledGetter, set: $buttonDisabledSetter } = Object.getOwnPropertyDescriptor(HTMLButtonElement.prototype, 'disabled');
44
+ /**
45
+ * Used for `k-model`
46
+ */
47
+ const applyModel = (element, valueRef, propName, eventName) => {
48
+ element[propName] = valueRef.value; // initialize
49
+ valueRef.addOnChange((newValue) => (element[propName] = newValue));
50
+ element.addEventListener(eventName, () => (valueRef.value = element[propName]));
51
+ };
46
52
 
47
53
  // Shared utilities and cached native methods for kt.js framework
48
54
  // Re-export all utilities
49
- Object.defineProperty(window, '@ktjs/shared', { value: '0.20.2' });
55
+ Object.defineProperty(window, '__ktjs__', { value: '0.22.2' });
50
56
 
51
57
  class KTRef {
52
58
  /**
@@ -88,7 +94,14 @@ class KTRef {
88
94
  this._onChanges[i](newValue, oldValue);
89
95
  }
90
96
  }
97
+ /**
98
+ * Register a callback when the value changes
99
+ * @param callback (newValue, oldValue) => xxx
100
+ */
91
101
  addOnChange(callback) {
102
+ if (typeof callback !== 'function') {
103
+ throw new Error('[kt.js error] KTRef.addOnChange: callback must be a function');
104
+ }
92
105
  this._onChanges.push(callback);
93
106
  }
94
107
  removeOnChange(callback) {
@@ -101,18 +114,26 @@ class KTRef {
101
114
  return false;
102
115
  }
103
116
  }
104
- const isKTRef = (obj) => {
105
- return typeof obj === 'object' && obj !== null && obj.isKT === true;
106
- };
117
+ const isKTRef = (obj) => obj?.isKT === true;
107
118
  /**
108
119
  * Reference to the created HTML element.
109
120
  * - **Only** respond to `ref.value` changes, not reactive to internal changes of the element.
110
121
  * - can alse be used to store normal values, but it is not reactive.
122
+ * - if the value is already a `KTRef`, it will be returned **directly**.
111
123
  * @param value mostly an HTMLElement
112
124
  */
113
125
  function ref(value, onChange) {
126
+ if (isKTRef(value)) {
127
+ if (onChange) {
128
+ value.addOnChange(onChange);
129
+ }
130
+ return value;
131
+ }
114
132
  return new KTRef(value, onChange ? [onChange] : []);
115
133
  }
134
+ function deref(value) {
135
+ return isKTRef(value) ? value.value : value;
136
+ }
116
137
  function kcollect() {
117
138
  const newObj = {};
118
139
  const entries = $entries(this);
@@ -137,6 +158,21 @@ const surfaceRef = (obj) => {
137
158
  }
138
159
  return newObj;
139
160
  };
161
+ // # asserts
162
+ /**
163
+ * Assert k-model to be a ref object
164
+ */
165
+ const $modelOrRef = (props, defaultValue) => {
166
+ // & props is an object. Won't use it in any other place
167
+ if ('k-model' in props) {
168
+ const kmodel = props['k-model'];
169
+ if (!kmodel?.isKT) {
170
+ throw new Error(`[kt.js error] k-model data must be a KTRef object, please use 'ref(...)' to wrap it.`);
171
+ }
172
+ return kmodel;
173
+ }
174
+ return ref(defaultValue);
175
+ };
140
176
 
141
177
  const booleanHandler = (element, key, value) => {
142
178
  if (key in element) {
@@ -225,7 +261,7 @@ function applyAttr(element, attr) {
225
261
  attrIsObject(element, attr);
226
262
  }
227
263
  else {
228
- throw new Error('kt.js: attr must be an object.');
264
+ throw new Error('[kt.js error] attr must be an object.');
229
265
  }
230
266
  }
231
267
 
@@ -280,27 +316,28 @@ function applyContent(element, content) {
280
316
  }
281
317
  }
282
318
 
283
- function register(element, valueRef, propName, eventName) {
284
- element[propName] = valueRef.value; // initialize
285
- valueRef.addOnChange((newValue) => (element[propName] = newValue));
286
- element.addEventListener(eventName, () => (valueRef.value = element[propName]));
287
- }
288
- function applyModel(element, valueRef) {
319
+ function applyKModel(element, valueRef) {
320
+ if (!isKTRef(valueRef)) {
321
+ console.warn('[kt.js warn] k-model value must be a KTRef.');
322
+ return;
323
+ }
289
324
  if (element instanceof HTMLInputElement) {
290
325
  if (element.type === 'radio' || element.type === 'checkbox') {
291
- register(element, valueRef, 'checked', 'change');
326
+ applyModel(element, valueRef, 'checked', 'change');
292
327
  }
293
328
  else {
294
- register(element, valueRef, 'value', 'input');
329
+ applyModel(element, valueRef, 'value', 'input');
295
330
  }
296
331
  }
297
332
  else if (element instanceof HTMLSelectElement) {
298
- register(element, valueRef, 'value', 'change');
333
+ applyModel(element, valueRef, 'value', 'change');
299
334
  }
300
335
  else if (element instanceof HTMLTextAreaElement) {
301
- register(element, valueRef, 'value', 'input');
336
+ applyModel(element, valueRef, 'value', 'input');
337
+ }
338
+ else {
339
+ console.warn('[kt.js warn] not supported element for k-model:');
302
340
  }
303
- console.warn('[kt.js warn] not supported element for k-model:', element.tagName);
304
341
  }
305
342
 
306
343
  const htmlCreator = (tag) => document.createElement(tag);
@@ -320,7 +357,7 @@ const MATHML_ATTR_FLAG = '__kt_mathml__';
320
357
  * ## About
321
358
  * @package @ktjs/core
322
359
  * @author Kasukabe Tsumugi <futami16237@gmail.com>
323
- * @version 0.22.0 (Last Update: 2026.02.02 17:11:04.703)
360
+ * @version 0.22.5 (Last Update: 2026.02.03 09:07:21.411)
324
361
  * @license MIT
325
362
  * @link https://github.com/baendlorel/kt.js
326
363
  * @link https://baendlorel.github.io/ Welcome to my site!
@@ -329,7 +366,7 @@ const MATHML_ATTR_FLAG = '__kt_mathml__';
329
366
  */
330
367
  const h = (tag, attr, content) => {
331
368
  if (typeof tag !== 'string') {
332
- $throw('tagName must be a string.');
369
+ throw new Error('[kt.js error] tagName must be a string.');
333
370
  }
334
371
  if (attr) {
335
372
  if (SVG_ATTR_FLAG in attr) {
@@ -352,10 +389,10 @@ const h = (tag, attr, content) => {
352
389
  if (typeof attr === 'object' && attr !== null && 'k-model' in attr) {
353
390
  const kmodel = attr['k-model'];
354
391
  if (isKTRef(kmodel)) {
355
- applyModel(element, kmodel);
392
+ applyKModel(element, kmodel);
356
393
  }
357
394
  else {
358
- $throw('k-model value must be a KTRef.');
395
+ throw new Error('[kt.js error] k-model value must be a KTRef.');
359
396
  }
360
397
  }
361
398
  return element;
@@ -410,7 +447,7 @@ function jsx(tag, props) {
410
447
  * Note: kt.js doesn't have a real Fragment concept,
411
448
  */
412
449
  function Fragment(_props) {
413
- throw new Error("kt.js doesn't have a Fragment concept");
450
+ throw new Error("[kt.js error] doesn't have a Fragment concept");
414
451
  // const { children } = props ?? {};
415
452
  // if (!children) {
416
453
  // return ;
@@ -470,4 +507,4 @@ function createRedrawable(creator) {
470
507
  return elRef;
471
508
  }
472
509
 
473
- export { Fragment, KTRef, h as createElement, createRedrawable, isKTRef, jsx, jsxDEV, jsxs, ref, surfaceRef };
510
+ export { $modelOrRef, Fragment, KTRef, h as createElement, createRedrawable, deref, isKTRef, jsx, jsxDEV, jsxs, ref, surfaceRef };
@@ -19,6 +19,10 @@ declare class KTRef<T> {
19
19
  */
20
20
  get value(): T;
21
21
  set value(newValue: T);
22
+ /**
23
+ * Register a callback when the value changes
24
+ * @param callback (newValue, oldValue) => xxx
25
+ */
22
26
  addOnChange(callback: RefChangeHandler<T>): void;
23
27
  removeOnChange(callback: RefChangeHandler<T>): boolean;
24
28
  }
@@ -125,7 +129,7 @@ type KTAttribute = KTBaseAttribute & KTPrefixedEventHandlers;
125
129
  * ## About
126
130
  * @package @ktjs/core
127
131
  * @author Kasukabe Tsumugi <futami16237@gmail.com>
128
- * @version 0.22.0 (Last Update: 2026.02.02 17:11:04.703)
132
+ * @version 0.22.5 (Last Update: 2026.02.03 09:07:21.411)
129
133
  * @license MIT
130
134
  * @link https://github.com/baendlorel/kt.js
131
135
  * @link https://baendlorel.github.io/ Welcome to my site!
@@ -2,10 +2,8 @@
2
2
  const $isArray = Array.isArray;
3
3
  const $isThenable = (o) => typeof o === 'object' && o !== null && typeof o.then === 'function';
4
4
 
5
- // Error handling utilities
6
- const $throw = (message) => {
7
- throw new Error('@ktjs/shared: ' + message);
8
- };
5
+ // DOM manipulation utilities
6
+ // # dom natives
9
7
  /**
10
8
  * & Remove `bind` because it is shockingly slower than wrapper
11
9
  * & `window.document` is safe because it is not configurable and its setter is undefined
@@ -42,10 +40,18 @@ const $append = // for ie 9/10/11
42
40
  }
43
41
  };
44
42
  const { get: $buttonDisabledGetter, set: $buttonDisabledSetter } = Object.getOwnPropertyDescriptor(HTMLButtonElement.prototype, 'disabled');
43
+ /**
44
+ * Used for `k-model`
45
+ */
46
+ const applyModel = (element, valueRef, propName, eventName) => {
47
+ element[propName] = valueRef.value; // initialize
48
+ valueRef.addOnChange((newValue) => (element[propName] = newValue));
49
+ element.addEventListener(eventName, () => (valueRef.value = element[propName]));
50
+ };
45
51
 
46
52
  // Shared utilities and cached native methods for kt.js framework
47
53
  // Re-export all utilities
48
- Object.defineProperty(window, '@ktjs/shared', { value: '0.20.2' });
54
+ Object.defineProperty(window, '__ktjs__', { value: '0.22.2' });
49
55
 
50
56
  class KTRef {
51
57
  /**
@@ -87,7 +93,14 @@ class KTRef {
87
93
  this._onChanges[i](newValue, oldValue);
88
94
  }
89
95
  }
96
+ /**
97
+ * Register a callback when the value changes
98
+ * @param callback (newValue, oldValue) => xxx
99
+ */
90
100
  addOnChange(callback) {
101
+ if (typeof callback !== 'function') {
102
+ throw new Error('[kt.js error] KTRef.addOnChange: callback must be a function');
103
+ }
91
104
  this._onChanges.push(callback);
92
105
  }
93
106
  removeOnChange(callback) {
@@ -100,16 +113,18 @@ class KTRef {
100
113
  return false;
101
114
  }
102
115
  }
103
- const isKTRef = (obj) => {
104
- return typeof obj === 'object' && obj !== null && obj.isKT === true;
105
- };
116
+ const isKTRef = (obj) => obj?.isKT === true;
106
117
  /**
107
118
  * Reference to the created HTML element.
108
119
  * - **Only** respond to `ref.value` changes, not reactive to internal changes of the element.
109
120
  * - can alse be used to store normal values, but it is not reactive.
121
+ * - if the value is already a `KTRef`, it will be returned **directly**.
110
122
  * @param value mostly an HTMLElement
111
123
  */
112
124
  function ref(value, onChange) {
125
+ if (isKTRef(value)) {
126
+ return value;
127
+ }
113
128
  return new KTRef(value, []);
114
129
  }
115
130
 
@@ -200,7 +215,7 @@ function applyAttr(element, attr) {
200
215
  attrIsObject(element, attr);
201
216
  }
202
217
  else {
203
- throw new Error('kt.js: attr must be an object.');
218
+ throw new Error('[kt.js error] attr must be an object.');
204
219
  }
205
220
  }
206
221
 
@@ -255,27 +270,28 @@ function applyContent(element, content) {
255
270
  }
256
271
  }
257
272
 
258
- function register(element, valueRef, propName, eventName) {
259
- element[propName] = valueRef.value; // initialize
260
- valueRef.addOnChange((newValue) => (element[propName] = newValue));
261
- element.addEventListener(eventName, () => (valueRef.value = element[propName]));
262
- }
263
- function applyModel(element, valueRef) {
273
+ function applyKModel(element, valueRef) {
274
+ if (!isKTRef(valueRef)) {
275
+ console.warn('[kt.js warn] k-model value must be a KTRef.');
276
+ return;
277
+ }
264
278
  if (element instanceof HTMLInputElement) {
265
279
  if (element.type === 'radio' || element.type === 'checkbox') {
266
- register(element, valueRef, 'checked', 'change');
280
+ applyModel(element, valueRef, 'checked', 'change');
267
281
  }
268
282
  else {
269
- register(element, valueRef, 'value', 'input');
283
+ applyModel(element, valueRef, 'value', 'input');
270
284
  }
271
285
  }
272
286
  else if (element instanceof HTMLSelectElement) {
273
- register(element, valueRef, 'value', 'change');
287
+ applyModel(element, valueRef, 'value', 'change');
274
288
  }
275
289
  else if (element instanceof HTMLTextAreaElement) {
276
- register(element, valueRef, 'value', 'input');
290
+ applyModel(element, valueRef, 'value', 'input');
291
+ }
292
+ else {
293
+ console.warn('[kt.js warn] not supported element for k-model:');
277
294
  }
278
- console.warn('[kt.js warn] not supported element for k-model:', element.tagName);
279
295
  }
280
296
 
281
297
  const htmlCreator = (tag) => document.createElement(tag);
@@ -295,7 +311,7 @@ const MATHML_ATTR_FLAG = '__kt_mathml__';
295
311
  * ## About
296
312
  * @package @ktjs/core
297
313
  * @author Kasukabe Tsumugi <futami16237@gmail.com>
298
- * @version 0.22.0 (Last Update: 2026.02.02 17:11:04.703)
314
+ * @version 0.22.5 (Last Update: 2026.02.03 09:07:21.411)
299
315
  * @license MIT
300
316
  * @link https://github.com/baendlorel/kt.js
301
317
  * @link https://baendlorel.github.io/ Welcome to my site!
@@ -304,7 +320,7 @@ const MATHML_ATTR_FLAG = '__kt_mathml__';
304
320
  */
305
321
  const h = (tag, attr, content) => {
306
322
  if (typeof tag !== 'string') {
307
- $throw('tagName must be a string.');
323
+ throw new Error('[kt.js error] tagName must be a string.');
308
324
  }
309
325
  if (attr) {
310
326
  if (SVG_ATTR_FLAG in attr) {
@@ -327,10 +343,10 @@ const h = (tag, attr, content) => {
327
343
  if (typeof attr === 'object' && attr !== null && 'k-model' in attr) {
328
344
  const kmodel = attr['k-model'];
329
345
  if (isKTRef(kmodel)) {
330
- applyModel(element, kmodel);
346
+ applyKModel(element, kmodel);
331
347
  }
332
348
  else {
333
- $throw('k-model value must be a KTRef.');
349
+ throw new Error('[kt.js error] k-model value must be a KTRef.');
334
350
  }
335
351
  }
336
352
  return element;
@@ -385,7 +401,7 @@ function jsx(tag, props) {
385
401
  * Note: kt.js doesn't have a real Fragment concept,
386
402
  */
387
403
  function Fragment(_props) {
388
- throw new Error("kt.js doesn't have a Fragment concept");
404
+ throw new Error("[kt.js error] doesn't have a Fragment concept");
389
405
  // const { children } = props ?? {};
390
406
  // if (!children) {
391
407
  // return ;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ktjs/core",
3
- "version": "0.22.0",
3
+ "version": "0.22.5",
4
4
  "description": "Core functionality for kt.js - DOM manipulation utilities with JSX/TSX support",
5
5
  "type": "module",
6
6
  "module": "./dist/index.mjs",
@@ -44,7 +44,7 @@
44
44
  "directory": "packages/core"
45
45
  },
46
46
  "dependencies": {
47
- "@ktjs/shared": "0.20.2"
47
+ "@ktjs/shared": "0.22.2"
48
48
  },
49
49
  "scripts": {
50
50
  "build": "rollup -c rollup.config.mjs",