@ktjs/core 0.27.2 → 0.28.2
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 +80 -16
- package/dist/index.iife.js +129 -79
- package/dist/index.legacy.js +131 -80
- package/dist/index.mjs +129 -79
- package/dist/jsx/index.d.ts +61 -34
- package/dist/jsx/index.mjs +78 -64
- package/dist/jsx/jsx-runtime.d.ts +52 -2
- package/dist/jsx/jsx-runtime.mjs +78 -64
- package/package.json +2 -2
package/dist/jsx/index.d.ts
CHANGED
|
@@ -1,42 +1,56 @@
|
|
|
1
1
|
import { otherstring, HTMLTag, SVGTag, MathMLTag } from '@ktjs/shared';
|
|
2
2
|
|
|
3
|
-
declare class KTComputed<T> {
|
|
4
|
-
/**
|
|
5
|
-
* Indicates that this is a KTRef instance
|
|
6
|
-
*/
|
|
7
|
-
isKT: true;
|
|
8
|
-
ktType: KTReactiveType;
|
|
9
|
-
constructor(_calculator: () => T, reactives: Array<KTReactive<unknown>>);
|
|
10
|
-
/**
|
|
11
|
-
* If new value and old value are both nodes, the old one will be replaced in the DOM
|
|
12
|
-
*/
|
|
13
|
-
get value(): T;
|
|
14
|
-
set value(_newValue: T);
|
|
15
|
-
/**
|
|
16
|
-
* Register a callback when the value changes
|
|
17
|
-
* @param callback (newValue, oldValue) => xxx
|
|
18
|
-
*/
|
|
19
|
-
addOnChange(callback: ReactiveChangeHandler<T>): void;
|
|
20
|
-
/**
|
|
21
|
-
* Unregister a callback
|
|
22
|
-
* @param callback (newValue, oldValue) => xxx
|
|
23
|
-
*/
|
|
24
|
-
removeOnChange(callback: ReactiveChangeHandler<T>): boolean;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
type KTReactive<T> = KTRef<T> | KTComputed<T>;
|
|
28
|
-
type KTReactify<T> = T extends boolean ? KTReactive<boolean> : T extends any ? KTReactive<T> : never;
|
|
29
|
-
type KTReactifyProps<T extends object> = {
|
|
30
|
-
[K in keyof T]: KTReactify<Exclude<T[K], undefined>> | T[K];
|
|
31
|
-
};
|
|
32
|
-
|
|
33
3
|
declare const enum KTReactiveType {
|
|
34
4
|
REF = 1,
|
|
35
5
|
COMPUTED = 2
|
|
36
6
|
}
|
|
7
|
+
|
|
37
8
|
type ReactiveChangeHandler<T> = (newValue: T, oldValue: T) => void;
|
|
38
9
|
|
|
39
|
-
declare class
|
|
10
|
+
declare class KTReactive<T> {
|
|
11
|
+
/**
|
|
12
|
+
* Indicates that this is a KTRef instance
|
|
13
|
+
*/
|
|
14
|
+
isKT: boolean;
|
|
15
|
+
|
|
16
|
+
ktType: KTReactiveType;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* If new value and old value are both nodes, the old one will be replaced in the DOM
|
|
20
|
+
*/
|
|
21
|
+
get value();
|
|
22
|
+
set value(newValue: T);
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Force all listeners to run even when reference identity has not changed.
|
|
26
|
+
* Useful for in-place array/object mutations.
|
|
27
|
+
*/
|
|
28
|
+
notify(): void;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Mutate current value in-place and notify listeners once.
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* const items = ref<number[]>([1, 2]);
|
|
35
|
+
* items.mutate((list) => list.push(3));
|
|
36
|
+
*/
|
|
37
|
+
mutate<R = void>(mutator: (currentValue: T) => R): R;
|
|
38
|
+
/**
|
|
39
|
+
* Register a callback when the value changes
|
|
40
|
+
* @param callback (newValue, oldValue) => xxx
|
|
41
|
+
*/
|
|
42
|
+
addOnChange(callback: ReactiveChangeHandler<T>): void;
|
|
43
|
+
removeOnChange(callback: ReactiveChangeHandler<T>): void;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// & Shockingly, If T is boolean, KTReactify<T> becomes KTReactive<true> | KTReactive<false>. It causes @ktjs/mui that disabledRefs not assignable.
|
|
47
|
+
type KTReactify<T> = T extends boolean ? KTReactive<boolean> : T extends any ? KTReactive<T> : never;
|
|
48
|
+
|
|
49
|
+
type KTReactifyProps<T extends object> = {
|
|
50
|
+
[K in keyof T]: KTReactify<Exclude<T[K], undefined>> | T[K];
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
declare class KTRef<T> implements KTReactive<T> {
|
|
40
54
|
/**
|
|
41
55
|
* Indicates that this is a KTRef instance
|
|
42
56
|
*/
|
|
@@ -48,6 +62,19 @@ declare class KTRef<T> {
|
|
|
48
62
|
*/
|
|
49
63
|
get value(): T;
|
|
50
64
|
set value(newValue: T);
|
|
65
|
+
/**
|
|
66
|
+
* Force all listeners to run even when reference identity has not changed.
|
|
67
|
+
* Useful for in-place array/object mutations.
|
|
68
|
+
*/
|
|
69
|
+
notify(): void;
|
|
70
|
+
/**
|
|
71
|
+
* Mutate current value in-place and notify listeners once.
|
|
72
|
+
*
|
|
73
|
+
* @example
|
|
74
|
+
* const items = ref<number[]>([1, 2]);
|
|
75
|
+
* items.mutate((list) => list.push(3));
|
|
76
|
+
*/
|
|
77
|
+
mutate<R = void>(mutator: (currentValue: T) => R): R;
|
|
51
78
|
/**
|
|
52
79
|
* Register a callback when the value changes
|
|
53
80
|
* @param callback (newValue, oldValue) => xxx
|
|
@@ -164,7 +191,7 @@ type KTAttribute = KTBaseAttribute & KTPrefixedEventAttribute;
|
|
|
164
191
|
* ## About
|
|
165
192
|
* @package @ktjs/core
|
|
166
193
|
* @author Kasukabe Tsumugi <futami16237@gmail.com>
|
|
167
|
-
* @version 0.
|
|
194
|
+
* @version 0.28.2 (Last Update: 2026.02.10 14:46:21.243)
|
|
168
195
|
* @license MIT
|
|
169
196
|
* @link https://github.com/baendlorel/kt.js
|
|
170
197
|
* @link https://baendlorel.github.io/ Welcome to my site!
|
|
@@ -1269,7 +1296,7 @@ declare global {
|
|
|
1269
1296
|
view: SVGAttributesMap['view'];
|
|
1270
1297
|
}
|
|
1271
1298
|
|
|
1272
|
-
|
|
1299
|
+
interface IntrinsicAttributes {
|
|
1273
1300
|
/**
|
|
1274
1301
|
* Make a reference to the created element
|
|
1275
1302
|
*/
|
|
@@ -1293,7 +1320,7 @@ declare global {
|
|
|
1293
1320
|
*/
|
|
1294
1321
|
'k-html'?: any;
|
|
1295
1322
|
children?: KTRawContent;
|
|
1296
|
-
}
|
|
1323
|
+
}
|
|
1297
1324
|
|
|
1298
1325
|
interface ElementChildrenAttribute {
|
|
1299
1326
|
children: {};
|
package/dist/jsx/index.mjs
CHANGED
|
@@ -10,29 +10,6 @@ if (typeof Symbol === 'undefined') {
|
|
|
10
10
|
};
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
// String manipulation utilities
|
|
14
|
-
/**
|
|
15
|
-
* Default empty function
|
|
16
|
-
*/
|
|
17
|
-
const $emptyFn = (() => true);
|
|
18
|
-
const $emptyArray = [];
|
|
19
|
-
/**
|
|
20
|
-
* Safe and quick forEach implementation that works with array-like objects and handles sparse arrays.
|
|
21
|
-
*/
|
|
22
|
-
const $forEach = (array, callback) => {
|
|
23
|
-
const len = array.length;
|
|
24
|
-
for (let i = 0; i < len; i++) {
|
|
25
|
-
callback(array[i], i, array);
|
|
26
|
-
}
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
const $emptyChildrenRef = { value: $emptyArray };
|
|
30
|
-
// each instance shares the same empty array, but it will be replaced when used
|
|
31
|
-
Comment.prototype.kisFragmentAnchor = false;
|
|
32
|
-
Comment.prototype.kFragmentList = $emptyArray;
|
|
33
|
-
Comment.prototype.kredraw = $emptyFn;
|
|
34
|
-
Comment.prototype.kchildrenRef = $emptyChildrenRef;
|
|
35
|
-
|
|
36
13
|
// Shared constants
|
|
37
14
|
// Empty for now - can be extended with framework-wide constants
|
|
38
15
|
/**
|
|
@@ -102,9 +79,18 @@ const $applyModel = (element, valueRef, propName, eventName) => {
|
|
|
102
79
|
valueRef.addOnChange((newValue) => (element[propName] = newValue));
|
|
103
80
|
element.addEventListener(eventName, () => (valueRef.value = element[propName]));
|
|
104
81
|
};
|
|
82
|
+
/**
|
|
83
|
+
* Safe and quick forEach implementation that works with array-like objects and handles sparse arrays.
|
|
84
|
+
*/
|
|
85
|
+
const $forEach = (array, callback) => {
|
|
86
|
+
const len = array.length;
|
|
87
|
+
for (let i = 0; i < len; i++) {
|
|
88
|
+
callback(array[i], i, array);
|
|
89
|
+
}
|
|
90
|
+
};
|
|
105
91
|
|
|
106
92
|
// incase that symbol is not supported
|
|
107
|
-
Object.defineProperty(window, '__ktjs__', { value: '0.23.
|
|
93
|
+
Object.defineProperty(window, '__ktjs__', { value: '0.23.11' });
|
|
108
94
|
|
|
109
95
|
const isKT = (obj) => obj?.isKT;
|
|
110
96
|
const isRef = (obj) => obj?.ktType === 1 /* KTReactiveType.REF */;
|
|
@@ -315,6 +301,14 @@ class KTRef {
|
|
|
315
301
|
* @internal
|
|
316
302
|
*/
|
|
317
303
|
_onChanges;
|
|
304
|
+
/**
|
|
305
|
+
* @internal
|
|
306
|
+
*/
|
|
307
|
+
_emit(newValue, oldValue) {
|
|
308
|
+
for (let i = 0; i < this._onChanges.length; i++) {
|
|
309
|
+
this._onChanges[i](newValue, oldValue);
|
|
310
|
+
}
|
|
311
|
+
}
|
|
318
312
|
constructor(_value, _onChanges) {
|
|
319
313
|
this._value = _value;
|
|
320
314
|
this._onChanges = _onChanges;
|
|
@@ -332,9 +326,30 @@ class KTRef {
|
|
|
332
326
|
const oldValue = this._value;
|
|
333
327
|
$replaceNode(oldValue, newValue);
|
|
334
328
|
this._value = newValue;
|
|
335
|
-
|
|
336
|
-
|
|
329
|
+
this._emit(newValue, oldValue);
|
|
330
|
+
}
|
|
331
|
+
/**
|
|
332
|
+
* Force all listeners to run even when reference identity has not changed.
|
|
333
|
+
* Useful for in-place array/object mutations.
|
|
334
|
+
*/
|
|
335
|
+
notify() {
|
|
336
|
+
this._emit(this._value, this._value);
|
|
337
|
+
}
|
|
338
|
+
/**
|
|
339
|
+
* Mutate current value in-place and notify listeners once.
|
|
340
|
+
*
|
|
341
|
+
* @example
|
|
342
|
+
* const items = ref<number[]>([1, 2]);
|
|
343
|
+
* items.mutate((list) => list.push(3));
|
|
344
|
+
*/
|
|
345
|
+
mutate(mutator) {
|
|
346
|
+
if (typeof mutator !== 'function') {
|
|
347
|
+
throw new Error('[kt.js error] KTRef.mutate: mutator must be a function');
|
|
337
348
|
}
|
|
349
|
+
const oldValue = this._value;
|
|
350
|
+
const result = mutator(this._value);
|
|
351
|
+
this._emit(this._value, oldValue);
|
|
352
|
+
return result;
|
|
338
353
|
}
|
|
339
354
|
/**
|
|
340
355
|
* Register a callback when the value changes
|
|
@@ -428,7 +443,7 @@ let creator = htmlCreator;
|
|
|
428
443
|
* ## About
|
|
429
444
|
* @package @ktjs/core
|
|
430
445
|
* @author Kasukabe Tsumugi <futami16237@gmail.com>
|
|
431
|
-
* @version 0.
|
|
446
|
+
* @version 0.28.2 (Last Update: 2026.02.10 14:46:21.243)
|
|
432
447
|
* @license MIT
|
|
433
448
|
* @link https://github.com/baendlorel/kt.js
|
|
434
449
|
* @link https://baendlorel.github.io/ Welcome to my site!
|
|
@@ -463,34 +478,6 @@ const h = (tag, attr, content) => {
|
|
|
463
478
|
return element;
|
|
464
479
|
};
|
|
465
480
|
|
|
466
|
-
const kredraw = function () {
|
|
467
|
-
const newElements = this.kchildrenRef.value;
|
|
468
|
-
const parent = this.parentNode;
|
|
469
|
-
if (!parent) {
|
|
470
|
-
// If anchor is not in DOM, only update internal state
|
|
471
|
-
this.kFragmentList.length = 0;
|
|
472
|
-
for (let i = 0; i < newElements.length; i++) {
|
|
473
|
-
this.kFragmentList.push(newElements[i]);
|
|
474
|
-
}
|
|
475
|
-
return;
|
|
476
|
-
}
|
|
477
|
-
// Simple replacement algorithm: remove all old elements, insert all new elements
|
|
478
|
-
// todo Future enhancement: key-based optimization
|
|
479
|
-
// 1. Remove all old elements
|
|
480
|
-
for (let i = 0; i < this.kFragmentList.length; i++) {
|
|
481
|
-
this.kFragmentList[i].remove();
|
|
482
|
-
}
|
|
483
|
-
// 2. Insert all new elements
|
|
484
|
-
const fragment = document.createDocumentFragment();
|
|
485
|
-
this.kFragmentList.length = 0;
|
|
486
|
-
for (let i = 0; i < newElements.length; i++) {
|
|
487
|
-
const element = newElements[i];
|
|
488
|
-
this.kFragmentList.push(element);
|
|
489
|
-
fragment.appendChild(element);
|
|
490
|
-
}
|
|
491
|
-
// Insert after anchor
|
|
492
|
-
parent.insertBefore(fragment, this.nextSibling);
|
|
493
|
-
};
|
|
494
481
|
/**
|
|
495
482
|
* Fragment - Container component for managing arrays of child elements
|
|
496
483
|
*
|
|
@@ -512,17 +499,44 @@ const kredraw = function () {
|
|
|
512
499
|
*/
|
|
513
500
|
function Fragment$1(props) {
|
|
514
501
|
// key parameter reserved for future enhancement, currently unused
|
|
515
|
-
const { key: _key } = props;
|
|
516
|
-
const
|
|
502
|
+
// const { key: _key } = props;
|
|
503
|
+
const redraw = () => {
|
|
504
|
+
const newElements = childrenRef.value;
|
|
505
|
+
const parent = anchor.parentNode;
|
|
506
|
+
if (!parent) {
|
|
507
|
+
// If anchor is not in DOM, only update internal state
|
|
508
|
+
elements.length = 0;
|
|
509
|
+
for (let i = 0; i < newElements.length; i++) {
|
|
510
|
+
elements.push(newElements[i]);
|
|
511
|
+
}
|
|
512
|
+
return;
|
|
513
|
+
}
|
|
514
|
+
// Simple replacement algorithm: remove all old elements, insert all new elements
|
|
515
|
+
// todo Future enhancement: key-based optimization
|
|
516
|
+
// 1. Remove all old elements
|
|
517
|
+
for (let i = 0; i < elements.length; i++) {
|
|
518
|
+
elements[i].remove();
|
|
519
|
+
}
|
|
520
|
+
// 2. Insert all new elements
|
|
521
|
+
const fragment = document.createDocumentFragment();
|
|
522
|
+
elements.length = 0;
|
|
523
|
+
for (let i = 0; i < newElements.length; i++) {
|
|
524
|
+
const element = newElements[i];
|
|
525
|
+
elements.push(element);
|
|
526
|
+
fragment.appendChild(element);
|
|
527
|
+
}
|
|
528
|
+
// Insert after anchor
|
|
529
|
+
parent.insertBefore(fragment, anchor.nextSibling);
|
|
530
|
+
};
|
|
531
|
+
let initialized = false;
|
|
532
|
+
const childrenRef = toReactive(props.children, redraw);
|
|
533
|
+
const elements = [];
|
|
517
534
|
const anchor = document.createComment('kt-fragment');
|
|
518
|
-
anchor.kredraw = kredraw;
|
|
519
|
-
anchor.kchildrenRef = childrenRef;
|
|
520
|
-
anchor.kFragmentList = [];
|
|
521
|
-
anchor.kisFragmentAnchor = true;
|
|
522
535
|
// Observe DOM insertion
|
|
523
536
|
const observer = new MutationObserver(() => {
|
|
524
|
-
if (anchor.isConnected) {
|
|
525
|
-
|
|
537
|
+
if (anchor.isConnected && !initialized) {
|
|
538
|
+
initialized = true;
|
|
539
|
+
redraw();
|
|
526
540
|
observer.disconnect();
|
|
527
541
|
}
|
|
528
542
|
});
|
|
@@ -537,7 +551,7 @@ function Fragment$1(props) {
|
|
|
537
551
|
function convertChildrenToElements(children) {
|
|
538
552
|
const elements = [];
|
|
539
553
|
const processChild = (child) => {
|
|
540
|
-
if (child
|
|
554
|
+
if (child === undefined || child === null || child === false || child === true) {
|
|
541
555
|
// Ignore null, undefined, false, true
|
|
542
556
|
return;
|
|
543
557
|
}
|
|
@@ -4,9 +4,46 @@ declare const enum KTReactiveType {
|
|
|
4
4
|
REF = 1,
|
|
5
5
|
COMPUTED = 2
|
|
6
6
|
}
|
|
7
|
+
|
|
7
8
|
type ReactiveChangeHandler<T> = (newValue: T, oldValue: T) => void;
|
|
8
9
|
|
|
9
|
-
declare class
|
|
10
|
+
declare class KTReactive<T> {
|
|
11
|
+
/**
|
|
12
|
+
* Indicates that this is a KTRef instance
|
|
13
|
+
*/
|
|
14
|
+
isKT: boolean;
|
|
15
|
+
|
|
16
|
+
ktType: KTReactiveType;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* If new value and old value are both nodes, the old one will be replaced in the DOM
|
|
20
|
+
*/
|
|
21
|
+
get value();
|
|
22
|
+
set value(newValue: T);
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Force all listeners to run even when reference identity has not changed.
|
|
26
|
+
* Useful for in-place array/object mutations.
|
|
27
|
+
*/
|
|
28
|
+
notify(): void;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Mutate current value in-place and notify listeners once.
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* const items = ref<number[]>([1, 2]);
|
|
35
|
+
* items.mutate((list) => list.push(3));
|
|
36
|
+
*/
|
|
37
|
+
mutate<R = void>(mutator: (currentValue: T) => R): R;
|
|
38
|
+
/**
|
|
39
|
+
* Register a callback when the value changes
|
|
40
|
+
* @param callback (newValue, oldValue) => xxx
|
|
41
|
+
*/
|
|
42
|
+
addOnChange(callback: ReactiveChangeHandler<T>): void;
|
|
43
|
+
removeOnChange(callback: ReactiveChangeHandler<T>): void;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
declare class KTRef<T> implements KTReactive<T> {
|
|
10
47
|
/**
|
|
11
48
|
* Indicates that this is a KTRef instance
|
|
12
49
|
*/
|
|
@@ -18,6 +55,19 @@ declare class KTRef<T> {
|
|
|
18
55
|
*/
|
|
19
56
|
get value(): T;
|
|
20
57
|
set value(newValue: T);
|
|
58
|
+
/**
|
|
59
|
+
* Force all listeners to run even when reference identity has not changed.
|
|
60
|
+
* Useful for in-place array/object mutations.
|
|
61
|
+
*/
|
|
62
|
+
notify(): void;
|
|
63
|
+
/**
|
|
64
|
+
* Mutate current value in-place and notify listeners once.
|
|
65
|
+
*
|
|
66
|
+
* @example
|
|
67
|
+
* const items = ref<number[]>([1, 2]);
|
|
68
|
+
* items.mutate((list) => list.push(3));
|
|
69
|
+
*/
|
|
70
|
+
mutate<R = void>(mutator: (currentValue: T) => R): R;
|
|
21
71
|
/**
|
|
22
72
|
* Register a callback when the value changes
|
|
23
73
|
* @param callback (newValue, oldValue) => xxx
|
|
@@ -134,7 +184,7 @@ type KTAttribute = KTBaseAttribute & KTPrefixedEventAttribute;
|
|
|
134
184
|
* ## About
|
|
135
185
|
* @package @ktjs/core
|
|
136
186
|
* @author Kasukabe Tsumugi <futami16237@gmail.com>
|
|
137
|
-
* @version 0.
|
|
187
|
+
* @version 0.28.2 (Last Update: 2026.02.10 14:46:21.243)
|
|
138
188
|
* @license MIT
|
|
139
189
|
* @link https://github.com/baendlorel/kt.js
|
|
140
190
|
* @link https://baendlorel.github.io/ Welcome to my site!
|
package/dist/jsx/jsx-runtime.mjs
CHANGED
|
@@ -10,29 +10,6 @@ if (typeof Symbol === 'undefined') {
|
|
|
10
10
|
};
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
// String manipulation utilities
|
|
14
|
-
/**
|
|
15
|
-
* Default empty function
|
|
16
|
-
*/
|
|
17
|
-
const $emptyFn = (() => true);
|
|
18
|
-
const $emptyArray = [];
|
|
19
|
-
/**
|
|
20
|
-
* Safe and quick forEach implementation that works with array-like objects and handles sparse arrays.
|
|
21
|
-
*/
|
|
22
|
-
const $forEach = (array, callback) => {
|
|
23
|
-
const len = array.length;
|
|
24
|
-
for (let i = 0; i < len; i++) {
|
|
25
|
-
callback(array[i], i, array);
|
|
26
|
-
}
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
const $emptyChildrenRef = { value: $emptyArray };
|
|
30
|
-
// each instance shares the same empty array, but it will be replaced when used
|
|
31
|
-
Comment.prototype.kisFragmentAnchor = false;
|
|
32
|
-
Comment.prototype.kFragmentList = $emptyArray;
|
|
33
|
-
Comment.prototype.kredraw = $emptyFn;
|
|
34
|
-
Comment.prototype.kchildrenRef = $emptyChildrenRef;
|
|
35
|
-
|
|
36
13
|
// Shared constants
|
|
37
14
|
// Empty for now - can be extended with framework-wide constants
|
|
38
15
|
/**
|
|
@@ -102,9 +79,18 @@ const $applyModel = (element, valueRef, propName, eventName) => {
|
|
|
102
79
|
valueRef.addOnChange((newValue) => (element[propName] = newValue));
|
|
103
80
|
element.addEventListener(eventName, () => (valueRef.value = element[propName]));
|
|
104
81
|
};
|
|
82
|
+
/**
|
|
83
|
+
* Safe and quick forEach implementation that works with array-like objects and handles sparse arrays.
|
|
84
|
+
*/
|
|
85
|
+
const $forEach = (array, callback) => {
|
|
86
|
+
const len = array.length;
|
|
87
|
+
for (let i = 0; i < len; i++) {
|
|
88
|
+
callback(array[i], i, array);
|
|
89
|
+
}
|
|
90
|
+
};
|
|
105
91
|
|
|
106
92
|
// incase that symbol is not supported
|
|
107
|
-
Object.defineProperty(window, '__ktjs__', { value: '0.23.
|
|
93
|
+
Object.defineProperty(window, '__ktjs__', { value: '0.23.11' });
|
|
108
94
|
|
|
109
95
|
const isKT = (obj) => obj?.isKT;
|
|
110
96
|
const isRef = (obj) => obj?.ktType === 1 /* KTReactiveType.REF */;
|
|
@@ -315,6 +301,14 @@ class KTRef {
|
|
|
315
301
|
* @internal
|
|
316
302
|
*/
|
|
317
303
|
_onChanges;
|
|
304
|
+
/**
|
|
305
|
+
* @internal
|
|
306
|
+
*/
|
|
307
|
+
_emit(newValue, oldValue) {
|
|
308
|
+
for (let i = 0; i < this._onChanges.length; i++) {
|
|
309
|
+
this._onChanges[i](newValue, oldValue);
|
|
310
|
+
}
|
|
311
|
+
}
|
|
318
312
|
constructor(_value, _onChanges) {
|
|
319
313
|
this._value = _value;
|
|
320
314
|
this._onChanges = _onChanges;
|
|
@@ -332,9 +326,30 @@ class KTRef {
|
|
|
332
326
|
const oldValue = this._value;
|
|
333
327
|
$replaceNode(oldValue, newValue);
|
|
334
328
|
this._value = newValue;
|
|
335
|
-
|
|
336
|
-
|
|
329
|
+
this._emit(newValue, oldValue);
|
|
330
|
+
}
|
|
331
|
+
/**
|
|
332
|
+
* Force all listeners to run even when reference identity has not changed.
|
|
333
|
+
* Useful for in-place array/object mutations.
|
|
334
|
+
*/
|
|
335
|
+
notify() {
|
|
336
|
+
this._emit(this._value, this._value);
|
|
337
|
+
}
|
|
338
|
+
/**
|
|
339
|
+
* Mutate current value in-place and notify listeners once.
|
|
340
|
+
*
|
|
341
|
+
* @example
|
|
342
|
+
* const items = ref<number[]>([1, 2]);
|
|
343
|
+
* items.mutate((list) => list.push(3));
|
|
344
|
+
*/
|
|
345
|
+
mutate(mutator) {
|
|
346
|
+
if (typeof mutator !== 'function') {
|
|
347
|
+
throw new Error('[kt.js error] KTRef.mutate: mutator must be a function');
|
|
337
348
|
}
|
|
349
|
+
const oldValue = this._value;
|
|
350
|
+
const result = mutator(this._value);
|
|
351
|
+
this._emit(this._value, oldValue);
|
|
352
|
+
return result;
|
|
338
353
|
}
|
|
339
354
|
/**
|
|
340
355
|
* Register a callback when the value changes
|
|
@@ -428,7 +443,7 @@ let creator = htmlCreator;
|
|
|
428
443
|
* ## About
|
|
429
444
|
* @package @ktjs/core
|
|
430
445
|
* @author Kasukabe Tsumugi <futami16237@gmail.com>
|
|
431
|
-
* @version 0.
|
|
446
|
+
* @version 0.28.2 (Last Update: 2026.02.10 14:46:21.243)
|
|
432
447
|
* @license MIT
|
|
433
448
|
* @link https://github.com/baendlorel/kt.js
|
|
434
449
|
* @link https://baendlorel.github.io/ Welcome to my site!
|
|
@@ -463,34 +478,6 @@ const h = (tag, attr, content) => {
|
|
|
463
478
|
return element;
|
|
464
479
|
};
|
|
465
480
|
|
|
466
|
-
const kredraw = function () {
|
|
467
|
-
const newElements = this.kchildrenRef.value;
|
|
468
|
-
const parent = this.parentNode;
|
|
469
|
-
if (!parent) {
|
|
470
|
-
// If anchor is not in DOM, only update internal state
|
|
471
|
-
this.kFragmentList.length = 0;
|
|
472
|
-
for (let i = 0; i < newElements.length; i++) {
|
|
473
|
-
this.kFragmentList.push(newElements[i]);
|
|
474
|
-
}
|
|
475
|
-
return;
|
|
476
|
-
}
|
|
477
|
-
// Simple replacement algorithm: remove all old elements, insert all new elements
|
|
478
|
-
// todo Future enhancement: key-based optimization
|
|
479
|
-
// 1. Remove all old elements
|
|
480
|
-
for (let i = 0; i < this.kFragmentList.length; i++) {
|
|
481
|
-
this.kFragmentList[i].remove();
|
|
482
|
-
}
|
|
483
|
-
// 2. Insert all new elements
|
|
484
|
-
const fragment = document.createDocumentFragment();
|
|
485
|
-
this.kFragmentList.length = 0;
|
|
486
|
-
for (let i = 0; i < newElements.length; i++) {
|
|
487
|
-
const element = newElements[i];
|
|
488
|
-
this.kFragmentList.push(element);
|
|
489
|
-
fragment.appendChild(element);
|
|
490
|
-
}
|
|
491
|
-
// Insert after anchor
|
|
492
|
-
parent.insertBefore(fragment, this.nextSibling);
|
|
493
|
-
};
|
|
494
481
|
/**
|
|
495
482
|
* Fragment - Container component for managing arrays of child elements
|
|
496
483
|
*
|
|
@@ -512,17 +499,44 @@ const kredraw = function () {
|
|
|
512
499
|
*/
|
|
513
500
|
function Fragment$1(props) {
|
|
514
501
|
// key parameter reserved for future enhancement, currently unused
|
|
515
|
-
const { key: _key } = props;
|
|
516
|
-
const
|
|
502
|
+
// const { key: _key } = props;
|
|
503
|
+
const redraw = () => {
|
|
504
|
+
const newElements = childrenRef.value;
|
|
505
|
+
const parent = anchor.parentNode;
|
|
506
|
+
if (!parent) {
|
|
507
|
+
// If anchor is not in DOM, only update internal state
|
|
508
|
+
elements.length = 0;
|
|
509
|
+
for (let i = 0; i < newElements.length; i++) {
|
|
510
|
+
elements.push(newElements[i]);
|
|
511
|
+
}
|
|
512
|
+
return;
|
|
513
|
+
}
|
|
514
|
+
// Simple replacement algorithm: remove all old elements, insert all new elements
|
|
515
|
+
// todo Future enhancement: key-based optimization
|
|
516
|
+
// 1. Remove all old elements
|
|
517
|
+
for (let i = 0; i < elements.length; i++) {
|
|
518
|
+
elements[i].remove();
|
|
519
|
+
}
|
|
520
|
+
// 2. Insert all new elements
|
|
521
|
+
const fragment = document.createDocumentFragment();
|
|
522
|
+
elements.length = 0;
|
|
523
|
+
for (let i = 0; i < newElements.length; i++) {
|
|
524
|
+
const element = newElements[i];
|
|
525
|
+
elements.push(element);
|
|
526
|
+
fragment.appendChild(element);
|
|
527
|
+
}
|
|
528
|
+
// Insert after anchor
|
|
529
|
+
parent.insertBefore(fragment, anchor.nextSibling);
|
|
530
|
+
};
|
|
531
|
+
let initialized = false;
|
|
532
|
+
const childrenRef = toReactive(props.children, redraw);
|
|
533
|
+
const elements = [];
|
|
517
534
|
const anchor = document.createComment('kt-fragment');
|
|
518
|
-
anchor.kredraw = kredraw;
|
|
519
|
-
anchor.kchildrenRef = childrenRef;
|
|
520
|
-
anchor.kFragmentList = [];
|
|
521
|
-
anchor.kisFragmentAnchor = true;
|
|
522
535
|
// Observe DOM insertion
|
|
523
536
|
const observer = new MutationObserver(() => {
|
|
524
|
-
if (anchor.isConnected) {
|
|
525
|
-
|
|
537
|
+
if (anchor.isConnected && !initialized) {
|
|
538
|
+
initialized = true;
|
|
539
|
+
redraw();
|
|
526
540
|
observer.disconnect();
|
|
527
541
|
}
|
|
528
542
|
});
|
|
@@ -537,7 +551,7 @@ function Fragment$1(props) {
|
|
|
537
551
|
function convertChildrenToElements(children) {
|
|
538
552
|
const elements = [];
|
|
539
553
|
const processChild = (child) => {
|
|
540
|
-
if (child
|
|
554
|
+
if (child === undefined || child === null || child === false || child === true) {
|
|
541
555
|
// Ignore null, undefined, false, true
|
|
542
556
|
return;
|
|
543
557
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ktjs/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.28.2",
|
|
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.23.
|
|
47
|
+
"@ktjs/shared": "0.23.11"
|
|
48
48
|
},
|
|
49
49
|
"scripts": {
|
|
50
50
|
"build": "rollup -c rollup.config.mjs",
|