@ktjs/core 0.20.3 → 0.22.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.
@@ -3,15 +3,13 @@ var __ktjs_core__ = (function (exports) {
3
3
 
4
4
  // Cached native methods for performance optimization
5
5
  const $isArray = Array.isArray;
6
+ const $entries = Object.entries;
6
7
  const $isThenable = (o) => typeof o === 'object' && o !== null && typeof o.then === 'function';
7
8
 
8
9
  // Error handling utilities
9
10
  const $throw = (message) => {
10
11
  throw new Error('@ktjs/shared: ' + message);
11
12
  };
12
-
13
- // DOM manipulation utilities
14
- // # dom natives
15
13
  /**
16
14
  * & Remove `bind` because it is shockingly slower than wrapper
17
15
  * & `window.document` is safe because it is not configurable and its setter is undefined
@@ -51,7 +49,97 @@ var __ktjs_core__ = (function (exports) {
51
49
 
52
50
  // Shared utilities and cached native methods for kt.js framework
53
51
  // Re-export all utilities
54
- Object.defineProperty(window, '@ktjs/shared', { value: '0.20.0' });
52
+ Object.defineProperty(window, '@ktjs/shared', { value: '0.20.2' });
53
+
54
+ class KTRef {
55
+ /**
56
+ * Indicates that this is a KTRef instance
57
+ */
58
+ isKT = true;
59
+ /**
60
+ * @internal
61
+ */
62
+ _value;
63
+ /**
64
+ * @internal
65
+ */
66
+ _onChanges;
67
+ constructor(_value, _onChanges) {
68
+ this._value = _value;
69
+ this._onChanges = _onChanges;
70
+ }
71
+ /**
72
+ * If new value and old value are both nodes, the old one will be replaced in the DOM
73
+ */
74
+ get value() {
75
+ return this._value;
76
+ }
77
+ set value(newValue) {
78
+ if (newValue === this._value) {
79
+ return;
80
+ }
81
+ // replace the old node with the new one in the DOM if both are nodes
82
+ if (this._value instanceof Node && newValue instanceof Node) {
83
+ if (newValue.contains(this._value)) {
84
+ this._value.remove();
85
+ }
86
+ this._value.replaceWith(newValue);
87
+ }
88
+ const oldValue = this._value;
89
+ this._value = newValue;
90
+ for (let i = 0; i < this._onChanges.length; i++) {
91
+ this._onChanges[i](newValue, oldValue);
92
+ }
93
+ }
94
+ addOnChange(callback) {
95
+ this._onChanges.push(callback);
96
+ }
97
+ removeOnChange(callback) {
98
+ for (let i = this._onChanges.length - 1; i >= 0; i--) {
99
+ if (this._onChanges[i] === callback) {
100
+ this._onChanges.splice(i, 1);
101
+ return true;
102
+ }
103
+ }
104
+ return false;
105
+ }
106
+ }
107
+ const isKTRef = (obj) => {
108
+ return typeof obj === 'object' && obj !== null && obj.isKT === true;
109
+ };
110
+ /**
111
+ * Reference to the created HTML element.
112
+ * - **Only** respond to `ref.value` changes, not reactive to internal changes of the element.
113
+ * - can alse be used to store normal values, but it is not reactive.
114
+ * @param value mostly an HTMLElement
115
+ */
116
+ function ref(value, onChange) {
117
+ return new KTRef(value, onChange ? [onChange] : []);
118
+ }
119
+ function kcollect() {
120
+ const newObj = {};
121
+ const entries = $entries(this);
122
+ for (let i = 0; i < entries.length; i++) {
123
+ const key = entries[i][0];
124
+ if (key === 'kcollect') {
125
+ continue;
126
+ }
127
+ newObj[key] = entries[i][1].value;
128
+ }
129
+ return newObj;
130
+ }
131
+ /**
132
+ * Make all first-level properties of the object a `KTRef`.
133
+ * - `obj.a.b` is not reactive
134
+ */
135
+ const surfaceRef = (obj) => {
136
+ const entries = $entries(obj);
137
+ const newObj = { kcollect };
138
+ for (let i = 0; i < entries.length; i++) {
139
+ newObj[entries[i][0]] = ref(entries[i][1]);
140
+ }
141
+ return newObj;
142
+ };
55
143
 
56
144
  const booleanHandler = (element, key, value) => {
57
145
  if (key in element) {
@@ -117,6 +205,7 @@ var __ktjs_core__ = (function (exports) {
117
205
  key === 'style' ||
118
206
  key === 'children' ||
119
207
  key === 'k-if' ||
208
+ key.startsWith('k-model') ||
120
209
  key === 'ref') {
121
210
  continue;
122
211
  }
@@ -194,7 +283,29 @@ var __ktjs_core__ = (function (exports) {
194
283
  }
195
284
  }
196
285
 
197
- document.createElement('div');
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) {
292
+ if (element instanceof HTMLInputElement) {
293
+ if (element.type === 'radio' || element.type === 'checkbox') {
294
+ register(element, valueRef, 'checked', 'change');
295
+ }
296
+ else {
297
+ register(element, valueRef, 'value', 'input');
298
+ }
299
+ }
300
+ else if (element instanceof HTMLSelectElement) {
301
+ register(element, valueRef, 'value', 'change');
302
+ }
303
+ else if (element instanceof HTMLTextAreaElement) {
304
+ register(element, valueRef, 'value', 'input');
305
+ }
306
+ console.warn('[kt.js warn] not supported element for k-model:', element.tagName);
307
+ }
308
+
198
309
  const htmlCreator = (tag) => document.createElement(tag);
199
310
  const svgCreator = (tag) => document.createElementNS('http://www.w3.org/2000/svg', tag);
200
311
  const mathMLCreator = (tag) => document.createElementNS('http://www.w3.org/1998/Math/MathML', tag);
@@ -212,7 +323,7 @@ var __ktjs_core__ = (function (exports) {
212
323
  * ## About
213
324
  * @package @ktjs/core
214
325
  * @author Kasukabe Tsumugi <futami16237@gmail.com>
215
- * @version 0.20.3 (Last Update: 2026.02.01 18:38:02.198)
326
+ * @version 0.22.0 (Last Update: 2026.02.02 17:11:04.703)
216
327
  * @license MIT
217
328
  * @link https://github.com/baendlorel/kt.js
218
329
  * @link https://baendlorel.github.io/ Welcome to my site!
@@ -241,101 +352,60 @@ var __ktjs_core__ = (function (exports) {
241
352
  // * Handle content
242
353
  applyAttr(element, attr);
243
354
  applyContent(element, content);
244
- // if (tag === 'svg') {
245
- // tempWrapper.innerHTML = element.outerHTML;
246
- // return tempWrapper.firstChild as HTML<T>;
247
- // }
248
- // if (tag === 'math') {
249
- // tempWrapper.innerHTML = element.outerHTML;
250
- // return tempWrapper.firstChild as HTML<T>;
251
- // }
252
- return element;
253
- };
254
-
255
- class KTRef {
256
- /**
257
- * Indicates that this is a KTRef instance
258
- */
259
- isKT = true;
260
- /**
261
- * @internal
262
- */
263
- _value;
264
- /**
265
- * @internal
266
- */
267
- _onChanges;
268
- constructor(_value, _onChanges) {
269
- this._value = _value;
270
- this._onChanges = _onChanges;
271
- }
272
- /**
273
- * If new value and old value are both nodes, the old one will be replaced in the DOM
274
- */
275
- get value() {
276
- return this._value;
277
- }
278
- set value(newValue) {
279
- if (newValue === this._value) {
280
- return;
281
- }
282
- // replace the old node with the new one in the DOM if both are nodes
283
- if (this._value instanceof Node && newValue instanceof Node) {
284
- if (newValue.contains(this._value)) {
285
- this._value.remove();
286
- }
287
- this._value.replaceWith(newValue);
355
+ if (typeof attr === 'object' && attr !== null && 'k-model' in attr) {
356
+ const kmodel = attr['k-model'];
357
+ if (isKTRef(kmodel)) {
358
+ applyModel(element, kmodel);
288
359
  }
289
- const oldValue = this._value;
290
- this._value = newValue;
291
- for (let i = 0; i < this._onChanges.length; i++) {
292
- this._onChanges[i](newValue, oldValue);
293
- }
294
- }
295
- addOnChange(callback) {
296
- this._onChanges.push(callback);
297
- }
298
- removeOnChange(callback) {
299
- for (let i = this._onChanges.length - 1; i >= 0; i--) {
300
- if (this._onChanges[i] === callback) {
301
- this._onChanges.splice(i, 1);
302
- return true;
303
- }
360
+ else {
361
+ $throw('k-model value must be a KTRef.');
304
362
  }
305
- return false;
306
363
  }
307
- }
308
- /**
309
- * Reference to the created HTML element.
310
- * - can alse be used to store normal values, but it is not reactive.
311
- * @param value mostly an HTMLElement
312
- */
313
- function ref(value, onChange) {
314
- return new KTRef(value, onChange ? [onChange] : []);
315
- }
364
+ return element;
365
+ };
316
366
 
317
367
  const dummyRef = { value: null };
368
+ const create = (tag, props) => {
369
+ if (typeof tag === 'function') {
370
+ return tag(props);
371
+ }
372
+ else {
373
+ return h(tag, props, props.children);
374
+ }
375
+ };
376
+ const placeholder = () => document.createComment('k-if');
318
377
  /**
319
378
  * @param tag html tag or function component
320
379
  * @param props properties/attributes
321
380
  */
322
381
  function jsx(tag, props) {
323
- const ref = props.ref?.isKT ? props.ref : dummyRef;
382
+ const maybeDummyRef = isKTRef(props.ref) ? props.ref : dummyRef;
324
383
  let el;
325
- if ('k-if' in props && !props['k-if']) {
326
- // & make comment placeholder in case that ref might be redrawn later
327
- el = document.createComment('k-if');
328
- ref.value = el;
329
- return el;
330
- }
331
- // Handle function components
332
- if (typeof tag === 'function') {
333
- el = tag(props);
334
- }
335
- else {
336
- el = h(tag, props, props.children);
384
+ if ('k-if' in props) {
385
+ const kif = props['k-if'];
386
+ let condition = kif; // assume boolean by default
387
+ // Handle reactive k-if
388
+ if (isKTRef(kif)) {
389
+ kif.addOnChange((newValue, oldValue) => {
390
+ if (newValue === oldValue) {
391
+ return;
392
+ }
393
+ const oldEl = el;
394
+ el = newValue ? create(tag, props) : placeholder();
395
+ oldEl.replaceWith(el);
396
+ maybeDummyRef.value = el;
397
+ });
398
+ condition = kif.value;
399
+ }
400
+ if (!condition) {
401
+ // & make comment placeholder in case that ref might be redrawn later
402
+ el = placeholder();
403
+ maybeDummyRef.value = el;
404
+ return el;
405
+ }
337
406
  }
338
- ref.value = el;
407
+ el = create(tag, props);
408
+ maybeDummyRef.value = el;
339
409
  return el;
340
410
  }
341
411
  /**
@@ -634,10 +704,12 @@ var __ktjs_core__ = (function (exports) {
634
704
  exports.createElement = h;
635
705
  exports.createRedrawable = createRedrawable;
636
706
  exports.h = h;
707
+ exports.isKTRef = isKTRef;
637
708
  exports.jsx = jsx;
638
709
  exports.jsxDEV = jsxDEV;
639
710
  exports.jsxs = jsxs;
640
711
  exports.ref = ref;
712
+ exports.surfaceRef = surfaceRef;
641
713
 
642
714
  return exports;
643
715
 
@@ -3,15 +3,13 @@ var __ktjs_core__ = (function (exports) {
3
3
 
4
4
  // Cached native methods for performance optimization
5
5
  const $isArray = Array.isArray;
6
+ const $entries = Object.entries;
6
7
  const $isThenable = (o) => typeof o === 'object' && o !== null && typeof o.then === 'function';
7
8
 
8
9
  // Error handling utilities
9
10
  const $throw = (message) => {
10
11
  throw new Error('@ktjs/shared: ' + message);
11
12
  };
12
-
13
- // DOM manipulation utilities
14
- // # dom natives
15
13
  /**
16
14
  * & Remove `bind` because it is shockingly slower than wrapper
17
15
  * & `window.document` is safe because it is not configurable and its setter is undefined
@@ -51,7 +49,94 @@ var __ktjs_core__ = (function (exports) {
51
49
 
52
50
  // Shared utilities and cached native methods for kt.js framework
53
51
  // Re-export all utilities
54
- Object.defineProperty(window, '@ktjs/shared', { value: '0.20.0' });
52
+ Object.defineProperty(window, '@ktjs/shared', { value: '0.20.2' });
53
+
54
+ var KTRef = /** @class */ (function () {
55
+ function KTRef(_value, _onChanges) {
56
+ /**
57
+ * Indicates that this is a KTRef instance
58
+ */
59
+ this.isKT = true;
60
+ this._value = _value;
61
+ this._onChanges = _onChanges;
62
+ }
63
+ Object.defineProperty(KTRef.prototype, "value", {
64
+ /**
65
+ * If new value and old value are both nodes, the old one will be replaced in the DOM
66
+ */
67
+ get: function () {
68
+ return this._value;
69
+ },
70
+ set: function (newValue) {
71
+ if (newValue === this._value) {
72
+ return;
73
+ }
74
+ // replace the old node with the new one in the DOM if both are nodes
75
+ if (this._value instanceof Node && newValue instanceof Node) {
76
+ if (newValue.contains(this._value)) {
77
+ this._value.remove();
78
+ }
79
+ this._value.replaceWith(newValue);
80
+ }
81
+ var oldValue = this._value;
82
+ this._value = newValue;
83
+ for (var i = 0; i < this._onChanges.length; i++) {
84
+ this._onChanges[i](newValue, oldValue);
85
+ }
86
+ },
87
+ enumerable: false,
88
+ configurable: true
89
+ });
90
+ KTRef.prototype.addOnChange = function (callback) {
91
+ this._onChanges.push(callback);
92
+ };
93
+ KTRef.prototype.removeOnChange = function (callback) {
94
+ for (var i = this._onChanges.length - 1; i >= 0; i--) {
95
+ if (this._onChanges[i] === callback) {
96
+ this._onChanges.splice(i, 1);
97
+ return true;
98
+ }
99
+ }
100
+ return false;
101
+ };
102
+ return KTRef;
103
+ }());
104
+ var isKTRef = function (obj) {
105
+ return typeof obj === 'object' && obj !== null && obj.isKT === true;
106
+ };
107
+ /**
108
+ * Reference to the created HTML element.
109
+ * - **Only** respond to `ref.value` changes, not reactive to internal changes of the element.
110
+ * - can alse be used to store normal values, but it is not reactive.
111
+ * @param value mostly an HTMLElement
112
+ */
113
+ function ref(value, onChange) {
114
+ return new KTRef(value, onChange ? [onChange] : []);
115
+ }
116
+ function kcollect() {
117
+ var newObj = {};
118
+ var entries = $entries(this);
119
+ for (var i = 0; i < entries.length; i++) {
120
+ var key = entries[i][0];
121
+ if (key === 'kcollect') {
122
+ continue;
123
+ }
124
+ newObj[key] = entries[i][1].value;
125
+ }
126
+ return newObj;
127
+ }
128
+ /**
129
+ * Make all first-level properties of the object a `KTRef`.
130
+ * - `obj.a.b` is not reactive
131
+ */
132
+ var surfaceRef = function (obj) {
133
+ var entries = $entries(obj);
134
+ var newObj = { kcollect: kcollect };
135
+ for (var i = 0; i < entries.length; i++) {
136
+ newObj[entries[i][0]] = ref(entries[i][1]);
137
+ }
138
+ return newObj;
139
+ };
55
140
 
56
141
  var booleanHandler = function (element, key, value) {
57
142
  if (key in element) {
@@ -119,6 +204,7 @@ var __ktjs_core__ = (function (exports) {
119
204
  key === 'style' ||
120
205
  key === 'children' ||
121
206
  key === 'k-if' ||
207
+ key.startsWith('k-model') ||
122
208
  key === 'ref') {
123
209
  continue;
124
210
  }
@@ -199,7 +285,29 @@ var __ktjs_core__ = (function (exports) {
199
285
  }
200
286
  }
201
287
 
202
- document.createElement('div');
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) {
294
+ if (element instanceof HTMLInputElement) {
295
+ if (element.type === 'radio' || element.type === 'checkbox') {
296
+ register(element, valueRef, 'checked', 'change');
297
+ }
298
+ else {
299
+ register(element, valueRef, 'value', 'input');
300
+ }
301
+ }
302
+ else if (element instanceof HTMLSelectElement) {
303
+ register(element, valueRef, 'value', 'change');
304
+ }
305
+ else if (element instanceof HTMLTextAreaElement) {
306
+ register(element, valueRef, 'value', 'input');
307
+ }
308
+ console.warn('[kt.js warn] not supported element for k-model:', element.tagName);
309
+ }
310
+
203
311
  var htmlCreator = function (tag) { return document.createElement(tag); };
204
312
  var svgCreator = function (tag) { return document.createElementNS('http://www.w3.org/2000/svg', tag); };
205
313
  var mathMLCreator = function (tag) { return document.createElementNS('http://www.w3.org/1998/Math/MathML', tag); };
@@ -217,7 +325,7 @@ var __ktjs_core__ = (function (exports) {
217
325
  * ## About
218
326
  * @package @ktjs/core
219
327
  * @author Kasukabe Tsumugi <futami16237@gmail.com>
220
- * @version 0.20.3 (Last Update: 2026.02.01 18:38:02.198)
328
+ * @version 0.22.0 (Last Update: 2026.02.02 17:11:04.703)
221
329
  * @license MIT
222
330
  * @link https://github.com/baendlorel/kt.js
223
331
  * @link https://baendlorel.github.io/ Welcome to my site!
@@ -246,99 +354,60 @@ var __ktjs_core__ = (function (exports) {
246
354
  // * Handle content
247
355
  applyAttr(element, attr);
248
356
  applyContent(element, content);
249
- // if (tag === 'svg') {
250
- // tempWrapper.innerHTML = element.outerHTML;
251
- // return tempWrapper.firstChild as HTML<T>;
252
- // }
253
- // if (tag === 'math') {
254
- // tempWrapper.innerHTML = element.outerHTML;
255
- // return tempWrapper.firstChild as HTML<T>;
256
- // }
357
+ if (typeof attr === 'object' && attr !== null && 'k-model' in attr) {
358
+ var kmodel = attr['k-model'];
359
+ if (isKTRef(kmodel)) {
360
+ applyModel(element, kmodel);
361
+ }
362
+ else {
363
+ $throw('k-model value must be a KTRef.');
364
+ }
365
+ }
257
366
  return element;
258
367
  };
259
368
 
260
- var KTRef = /** @class */ (function () {
261
- function KTRef(_value, _onChanges) {
262
- /**
263
- * Indicates that this is a KTRef instance
264
- */
265
- this.isKT = true;
266
- this._value = _value;
267
- this._onChanges = _onChanges;
268
- }
269
- Object.defineProperty(KTRef.prototype, "value", {
270
- /**
271
- * If new value and old value are both nodes, the old one will be replaced in the DOM
272
- */
273
- get: function () {
274
- return this._value;
275
- },
276
- set: function (newValue) {
277
- if (newValue === this._value) {
278
- return;
279
- }
280
- // replace the old node with the new one in the DOM if both are nodes
281
- if (this._value instanceof Node && newValue instanceof Node) {
282
- if (newValue.contains(this._value)) {
283
- this._value.remove();
284
- }
285
- this._value.replaceWith(newValue);
286
- }
287
- var oldValue = this._value;
288
- this._value = newValue;
289
- for (var i = 0; i < this._onChanges.length; i++) {
290
- this._onChanges[i](newValue, oldValue);
291
- }
292
- },
293
- enumerable: false,
294
- configurable: true
295
- });
296
- KTRef.prototype.addOnChange = function (callback) {
297
- this._onChanges.push(callback);
298
- };
299
- KTRef.prototype.removeOnChange = function (callback) {
300
- for (var i = this._onChanges.length - 1; i >= 0; i--) {
301
- if (this._onChanges[i] === callback) {
302
- this._onChanges.splice(i, 1);
303
- return true;
304
- }
305
- }
306
- return false;
307
- };
308
- return KTRef;
309
- }());
310
- /**
311
- * Reference to the created HTML element.
312
- * - can alse be used to store normal values, but it is not reactive.
313
- * @param value mostly an HTMLElement
314
- */
315
- function ref(value, onChange) {
316
- return new KTRef(value, onChange ? [onChange] : []);
317
- }
318
-
319
369
  var dummyRef = { value: null };
370
+ var create = function (tag, props) {
371
+ if (typeof tag === 'function') {
372
+ return tag(props);
373
+ }
374
+ else {
375
+ return h(tag, props, props.children);
376
+ }
377
+ };
378
+ var placeholder = function () { return document.createComment('k-if'); };
320
379
  /**
321
380
  * @param tag html tag or function component
322
381
  * @param props properties/attributes
323
382
  */
324
383
  function jsx(tag, props) {
325
- var _a;
326
- var ref = ((_a = props.ref) === null || _a === void 0 ? void 0 : _a.isKT) ? props.ref : dummyRef;
384
+ var maybeDummyRef = isKTRef(props.ref) ? props.ref : dummyRef;
327
385
  var el;
328
- if ('k-if' in props && !props['k-if']) {
329
- // & make comment placeholder in case that ref might be redrawn later
330
- el = document.createComment('k-if');
331
- ref.value = el;
332
- return el;
333
- }
334
- // Handle function components
335
- if (typeof tag === 'function') {
336
- el = tag(props);
337
- }
338
- else {
339
- el = h(tag, props, props.children);
386
+ if ('k-if' in props) {
387
+ var kif = props['k-if'];
388
+ var condition = kif; // assume boolean by default
389
+ // Handle reactive k-if
390
+ if (isKTRef(kif)) {
391
+ kif.addOnChange(function (newValue, oldValue) {
392
+ if (newValue === oldValue) {
393
+ return;
394
+ }
395
+ var oldEl = el;
396
+ el = newValue ? create(tag, props) : placeholder();
397
+ oldEl.replaceWith(el);
398
+ maybeDummyRef.value = el;
399
+ });
400
+ condition = kif.value;
401
+ }
402
+ if (!condition) {
403
+ // & make comment placeholder in case that ref might be redrawn later
404
+ el = placeholder();
405
+ maybeDummyRef.value = el;
406
+ return el;
407
+ }
340
408
  }
341
- ref.value = el;
409
+ el = create(tag, props);
410
+ maybeDummyRef.value = el;
342
411
  return el;
343
412
  }
344
413
  /**
@@ -644,10 +713,12 @@ var __ktjs_core__ = (function (exports) {
644
713
  exports.createElement = h;
645
714
  exports.createRedrawable = createRedrawable;
646
715
  exports.h = h;
716
+ exports.isKTRef = isKTRef;
647
717
  exports.jsx = jsx;
648
718
  exports.jsxDEV = jsxDEV;
649
719
  exports.jsxs = jsxs;
650
720
  exports.ref = ref;
721
+ exports.surfaceRef = surfaceRef;
651
722
 
652
723
  return exports;
653
724