@ktjs/core 0.28.2 → 0.29.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +434 -1472
- package/dist/index.mjs +826 -1023
- package/package.json +2 -2
- package/LICENSE +0 -21
- package/dist/index.iife.js +0 -1144
- package/dist/index.legacy.js +0 -1153
- package/dist/jsx/index.d.ts +0 -1331
- package/dist/jsx/index.mjs +0 -676
- package/dist/jsx/jsx-runtime.d.ts +0 -237
- package/dist/jsx/jsx-runtime.mjs +0 -676
package/dist/index.legacy.js
DELETED
|
@@ -1,1153 +0,0 @@
|
|
|
1
|
-
var __ktjs_core__ = (function (exports) {
|
|
2
|
-
'use strict';
|
|
3
|
-
|
|
4
|
-
// Cached native methods for performance optimization
|
|
5
|
-
const $isArray = Array.isArray;
|
|
6
|
-
const $is = Object.is;
|
|
7
|
-
const $entries = Object.entries;
|
|
8
|
-
const $random = Math.random;
|
|
9
|
-
const $isThenable = (o) => typeof o?.then === 'function';
|
|
10
|
-
|
|
11
|
-
if (typeof Symbol === 'undefined') {
|
|
12
|
-
window.Symbol = function Symbol(description) {
|
|
13
|
-
return `@@SYMBOL_${description || ''}_${$random().toString(36).slice(2)}`;
|
|
14
|
-
};
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
// Shared constants
|
|
18
|
-
// Empty for now - can be extended with framework-wide constants
|
|
19
|
-
/**
|
|
20
|
-
* Mark the attribute as SVG to handle special cases during rendering.
|
|
21
|
-
*/
|
|
22
|
-
const SVG_ATTR_FLAG = '__kt_svg__';
|
|
23
|
-
/**
|
|
24
|
-
* Mark the attribute as MathML to handle special cases during rendering.
|
|
25
|
-
*/
|
|
26
|
-
const MATHML_ATTR_FLAG = '__kt_mathml__';
|
|
27
|
-
|
|
28
|
-
// DOM manipulation utilities
|
|
29
|
-
// # dom natives
|
|
30
|
-
const $isNode = (x) => x?.nodeType > 0;
|
|
31
|
-
/**
|
|
32
|
-
* Safe replace `oldNode` With `newNode`
|
|
33
|
-
*/
|
|
34
|
-
const $replaceNode = (oldNode, newNode) => {
|
|
35
|
-
if ($isNode(oldNode) && $isNode(newNode)) {
|
|
36
|
-
if (newNode.contains(oldNode)) {
|
|
37
|
-
newNode.remove();
|
|
38
|
-
}
|
|
39
|
-
oldNode.replaceWith(newNode);
|
|
40
|
-
}
|
|
41
|
-
};
|
|
42
|
-
/**
|
|
43
|
-
* & Remove `bind` because it is shockingly slower than wrapper
|
|
44
|
-
* & `window.document` is safe because it is not configurable and its setter is undefined
|
|
45
|
-
*/
|
|
46
|
-
const $appendChild = HTMLElement.prototype.appendChild;
|
|
47
|
-
const originAppend = HTMLElement.prototype.append;
|
|
48
|
-
const $append = // for ie 9/10/11
|
|
49
|
-
typeof originAppend === 'function'
|
|
50
|
-
? originAppend
|
|
51
|
-
: function (...nodes) {
|
|
52
|
-
if (nodes.length < 50) {
|
|
53
|
-
for (let i = 0; i < nodes.length; i++) {
|
|
54
|
-
const node = nodes[i];
|
|
55
|
-
if (typeof node === 'string') {
|
|
56
|
-
$appendChild.call(this, document.createTextNode(node));
|
|
57
|
-
}
|
|
58
|
-
else {
|
|
59
|
-
$appendChild.call(this, node);
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
else {
|
|
64
|
-
const fragment = document.createDocumentFragment();
|
|
65
|
-
for (let i = 0; i < nodes.length; i++) {
|
|
66
|
-
const node = nodes[i];
|
|
67
|
-
if (typeof node === 'string') {
|
|
68
|
-
$appendChild.call(fragment, document.createTextNode(node));
|
|
69
|
-
}
|
|
70
|
-
else {
|
|
71
|
-
$appendChild.call(fragment, node);
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
$appendChild.call(this, fragment);
|
|
75
|
-
}
|
|
76
|
-
};
|
|
77
|
-
const { get: $buttonDisabledGetter, set: $buttonDisabledSetter } = Object.getOwnPropertyDescriptor(HTMLButtonElement.prototype, 'disabled');
|
|
78
|
-
/**
|
|
79
|
-
* Used for `k-model`
|
|
80
|
-
*/
|
|
81
|
-
const $applyModel = (element, valueRef, propName, eventName) => {
|
|
82
|
-
element[propName] = valueRef.value; // initialize
|
|
83
|
-
valueRef.addOnChange((newValue) => (element[propName] = newValue));
|
|
84
|
-
element.addEventListener(eventName, () => (valueRef.value = element[propName]));
|
|
85
|
-
};
|
|
86
|
-
|
|
87
|
-
// String manipulation utilities
|
|
88
|
-
/**
|
|
89
|
-
* Default empty function
|
|
90
|
-
*/
|
|
91
|
-
const $emptyFn = (() => true);
|
|
92
|
-
/**
|
|
93
|
-
* Safe and quick forEach implementation that works with array-like objects and handles sparse arrays.
|
|
94
|
-
*/
|
|
95
|
-
const $forEach = (array, callback) => {
|
|
96
|
-
const len = array.length;
|
|
97
|
-
for (let i = 0; i < len; i++) {
|
|
98
|
-
callback(array[i], i, array);
|
|
99
|
-
}
|
|
100
|
-
};
|
|
101
|
-
|
|
102
|
-
// incase that symbol is not supported
|
|
103
|
-
Object.defineProperty(window, '__ktjs__', { value: '0.23.11' });
|
|
104
|
-
|
|
105
|
-
var isKT = function (obj) { return obj === null || obj === void 0 ? void 0 : obj.isKT; };
|
|
106
|
-
var isRef = function (obj) { return (obj === null || obj === void 0 ? void 0 : obj.ktType) === 1 /* KTReactiveType.REF */; };
|
|
107
|
-
var isComputed = function (obj) { return (obj === null || obj === void 0 ? void 0 : obj.ktType) === 2 /* KTReactiveType.COMPUTED */; };
|
|
108
|
-
|
|
109
|
-
var booleanHandler = function (element, key, value) {
|
|
110
|
-
if (key in element) {
|
|
111
|
-
element[key] = !!value;
|
|
112
|
-
}
|
|
113
|
-
else {
|
|
114
|
-
element.setAttribute(key, value);
|
|
115
|
-
}
|
|
116
|
-
};
|
|
117
|
-
var valueHandler = function (element, key, value) {
|
|
118
|
-
if (key in element) {
|
|
119
|
-
element[key] = value;
|
|
120
|
-
}
|
|
121
|
-
else {
|
|
122
|
-
element.setAttribute(key, value);
|
|
123
|
-
}
|
|
124
|
-
};
|
|
125
|
-
// Attribute handlers map for optimized lookup
|
|
126
|
-
var handlers = {
|
|
127
|
-
checked: booleanHandler,
|
|
128
|
-
selected: booleanHandler,
|
|
129
|
-
value: valueHandler,
|
|
130
|
-
valueAsDate: valueHandler,
|
|
131
|
-
valueAsNumber: valueHandler,
|
|
132
|
-
defaultValue: valueHandler,
|
|
133
|
-
defaultChecked: booleanHandler,
|
|
134
|
-
defaultSelected: booleanHandler,
|
|
135
|
-
disabled: booleanHandler,
|
|
136
|
-
readOnly: booleanHandler,
|
|
137
|
-
multiple: booleanHandler,
|
|
138
|
-
required: booleanHandler,
|
|
139
|
-
autofocus: booleanHandler,
|
|
140
|
-
open: booleanHandler,
|
|
141
|
-
controls: booleanHandler,
|
|
142
|
-
autoplay: booleanHandler,
|
|
143
|
-
loop: booleanHandler,
|
|
144
|
-
muted: booleanHandler,
|
|
145
|
-
defer: booleanHandler,
|
|
146
|
-
async: booleanHandler,
|
|
147
|
-
hidden: function (element, _key, value) { return (element.hidden = !!value); },
|
|
148
|
-
};
|
|
149
|
-
|
|
150
|
-
var defaultHandler = function (element, key, value) {
|
|
151
|
-
return element.setAttribute(key, value);
|
|
152
|
-
};
|
|
153
|
-
var setElementStyle = function (element, style) {
|
|
154
|
-
if (typeof style === 'string') {
|
|
155
|
-
element.style.cssText = style;
|
|
156
|
-
return;
|
|
157
|
-
}
|
|
158
|
-
for (var key in style) {
|
|
159
|
-
element.style[key] = style[key];
|
|
160
|
-
}
|
|
161
|
-
};
|
|
162
|
-
function attrIsObject(element, attr) {
|
|
163
|
-
var classValue = attr.class || attr.className;
|
|
164
|
-
if (classValue !== undefined) {
|
|
165
|
-
if (isKT(classValue)) {
|
|
166
|
-
element.setAttribute('class', classValue.value);
|
|
167
|
-
classValue.addOnChange(function (v) { return element.setAttribute('class', v); });
|
|
168
|
-
}
|
|
169
|
-
else {
|
|
170
|
-
element.setAttribute('class', classValue);
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
var style = attr.style;
|
|
174
|
-
if (style) {
|
|
175
|
-
if (typeof style === 'string') {
|
|
176
|
-
element.setAttribute('style', style);
|
|
177
|
-
}
|
|
178
|
-
else if (typeof style === 'object') {
|
|
179
|
-
if (isKT(style)) {
|
|
180
|
-
setElementStyle(element, style.value);
|
|
181
|
-
style.addOnChange(function (v) { return setElementStyle(element, v); });
|
|
182
|
-
}
|
|
183
|
-
else {
|
|
184
|
-
setElementStyle(element, style);
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
if ('k-html' in attr) {
|
|
189
|
-
var html = attr['k-html'];
|
|
190
|
-
if (isKT(html)) {
|
|
191
|
-
element.innerHTML = html.value;
|
|
192
|
-
html.addOnChange(function (v) { return (element.innerHTML = v); });
|
|
193
|
-
}
|
|
194
|
-
else {
|
|
195
|
-
element.innerHTML = html;
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
var _loop_1 = function (key) {
|
|
199
|
-
if (key === 'k-if' ||
|
|
200
|
-
key === 'k-model' ||
|
|
201
|
-
key === 'ref' ||
|
|
202
|
-
key === 'class' ||
|
|
203
|
-
key === 'className' ||
|
|
204
|
-
key === 'style' ||
|
|
205
|
-
key === 'children' ||
|
|
206
|
-
key === 'k-html') {
|
|
207
|
-
return "continue";
|
|
208
|
-
}
|
|
209
|
-
var o = attr[key];
|
|
210
|
-
// normal event handler
|
|
211
|
-
if (key.startsWith('on:')) {
|
|
212
|
-
element.addEventListener(key.slice(3), o); // chop off the `on:`
|
|
213
|
-
}
|
|
214
|
-
// normal attributes
|
|
215
|
-
else {
|
|
216
|
-
var handler_1 = handlers[key] || defaultHandler;
|
|
217
|
-
if (isKT(o)) {
|
|
218
|
-
handler_1(element, key, o.value);
|
|
219
|
-
o.addOnChange(function (v) { return handler_1(element, key, v); });
|
|
220
|
-
}
|
|
221
|
-
else {
|
|
222
|
-
handler_1(element, key, o);
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
};
|
|
226
|
-
for (var key in attr) {
|
|
227
|
-
_loop_1(key);
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
function applyAttr(element, attr) {
|
|
231
|
-
if (!attr) {
|
|
232
|
-
return;
|
|
233
|
-
}
|
|
234
|
-
if (typeof attr === 'object' && attr !== null) {
|
|
235
|
-
attrIsObject(element, attr);
|
|
236
|
-
}
|
|
237
|
-
else {
|
|
238
|
-
throw new Error('[kt.js error] attr must be an object.');
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
var assureNode = function (o) { return ($isNode(o) ? o : document.createTextNode(o)); };
|
|
243
|
-
function apdSingle(element, c) {
|
|
244
|
-
// & JSX should ignore false, undefined, and null
|
|
245
|
-
if (c === false || c === undefined || c === null) {
|
|
246
|
-
return;
|
|
247
|
-
}
|
|
248
|
-
if (isKT(c)) {
|
|
249
|
-
var node_1 = assureNode(c.value);
|
|
250
|
-
$append.call(element, node_1);
|
|
251
|
-
c.addOnChange(function (newValue, oldValue) {
|
|
252
|
-
if ($isNode(newValue) && $isNode(oldValue)) {
|
|
253
|
-
// & this case is handled automically in `class KTRef`
|
|
254
|
-
return;
|
|
255
|
-
}
|
|
256
|
-
var oldNode = node_1;
|
|
257
|
-
node_1 = assureNode(newValue);
|
|
258
|
-
oldNode.replaceWith(node_1);
|
|
259
|
-
});
|
|
260
|
-
}
|
|
261
|
-
else {
|
|
262
|
-
$append.call(element, c);
|
|
263
|
-
// Handle KTFor anchor
|
|
264
|
-
// todo Maybe not needed anymore
|
|
265
|
-
var list = c.__kt_for_list__;
|
|
266
|
-
if ($isArray(list)) {
|
|
267
|
-
apd(element, list);
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
function apd(element, c) {
|
|
272
|
-
if ($isThenable(c)) {
|
|
273
|
-
c.then(function (r) { return apd(element, r); });
|
|
274
|
-
}
|
|
275
|
-
else if ($isArray(c)) {
|
|
276
|
-
var _loop_1 = function (i) {
|
|
277
|
-
// & might be thenable here too
|
|
278
|
-
var ci = c[i];
|
|
279
|
-
if ($isThenable(ci)) {
|
|
280
|
-
var comment_1 = document.createComment('ktjs-promise-placeholder');
|
|
281
|
-
$append.call(element, comment_1);
|
|
282
|
-
ci.then(function (awaited) { return comment_1.replaceWith(awaited); });
|
|
283
|
-
}
|
|
284
|
-
else {
|
|
285
|
-
apdSingle(element, ci);
|
|
286
|
-
}
|
|
287
|
-
};
|
|
288
|
-
for (var i = 0; i < c.length; i++) {
|
|
289
|
-
_loop_1(i);
|
|
290
|
-
}
|
|
291
|
-
}
|
|
292
|
-
else {
|
|
293
|
-
// & here is thened, so must be a simple elementj
|
|
294
|
-
apdSingle(element, c);
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
function applyContent(element, content) {
|
|
298
|
-
if ($isArray(content)) {
|
|
299
|
-
for (var i = 0; i < content.length; i++) {
|
|
300
|
-
apd(element, content[i]);
|
|
301
|
-
}
|
|
302
|
-
}
|
|
303
|
-
else {
|
|
304
|
-
apd(element, content);
|
|
305
|
-
}
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
var KTRef = /** @class */ (function () {
|
|
309
|
-
function KTRef(_value, _onChanges) {
|
|
310
|
-
/**
|
|
311
|
-
* Indicates that this is a KTRef instance
|
|
312
|
-
*/
|
|
313
|
-
this.isKT = true;
|
|
314
|
-
this.ktType = 1 /* KTReactiveType.REF */;
|
|
315
|
-
this._value = _value;
|
|
316
|
-
this._onChanges = _onChanges;
|
|
317
|
-
}
|
|
318
|
-
/**
|
|
319
|
-
* @internal
|
|
320
|
-
*/
|
|
321
|
-
KTRef.prototype._emit = function (newValue, oldValue) {
|
|
322
|
-
for (var i = 0; i < this._onChanges.length; i++) {
|
|
323
|
-
this._onChanges[i](newValue, oldValue);
|
|
324
|
-
}
|
|
325
|
-
};
|
|
326
|
-
Object.defineProperty(KTRef.prototype, "value", {
|
|
327
|
-
/**
|
|
328
|
-
* If new value and old value are both nodes, the old one will be replaced in the DOM
|
|
329
|
-
*/
|
|
330
|
-
get: function () {
|
|
331
|
-
return this._value;
|
|
332
|
-
},
|
|
333
|
-
set: function (newValue) {
|
|
334
|
-
if ($is(newValue, this._value)) {
|
|
335
|
-
return;
|
|
336
|
-
}
|
|
337
|
-
var oldValue = this._value;
|
|
338
|
-
$replaceNode(oldValue, newValue);
|
|
339
|
-
this._value = newValue;
|
|
340
|
-
this._emit(newValue, oldValue);
|
|
341
|
-
},
|
|
342
|
-
enumerable: false,
|
|
343
|
-
configurable: true
|
|
344
|
-
});
|
|
345
|
-
/**
|
|
346
|
-
* Force all listeners to run even when reference identity has not changed.
|
|
347
|
-
* Useful for in-place array/object mutations.
|
|
348
|
-
*/
|
|
349
|
-
KTRef.prototype.notify = function () {
|
|
350
|
-
this._emit(this._value, this._value);
|
|
351
|
-
};
|
|
352
|
-
/**
|
|
353
|
-
* Mutate current value in-place and notify listeners once.
|
|
354
|
-
*
|
|
355
|
-
* @example
|
|
356
|
-
* const items = ref<number[]>([1, 2]);
|
|
357
|
-
* items.mutate((list) => list.push(3));
|
|
358
|
-
*/
|
|
359
|
-
KTRef.prototype.mutate = function (mutator) {
|
|
360
|
-
if (typeof mutator !== 'function') {
|
|
361
|
-
throw new Error('[kt.js error] KTRef.mutate: mutator must be a function');
|
|
362
|
-
}
|
|
363
|
-
var oldValue = this._value;
|
|
364
|
-
var result = mutator(this._value);
|
|
365
|
-
this._emit(this._value, oldValue);
|
|
366
|
-
return result;
|
|
367
|
-
};
|
|
368
|
-
/**
|
|
369
|
-
* Register a callback when the value changes
|
|
370
|
-
* @param callback (newValue, oldValue) => xxx
|
|
371
|
-
*/
|
|
372
|
-
KTRef.prototype.addOnChange = function (callback) {
|
|
373
|
-
if (typeof callback !== 'function') {
|
|
374
|
-
throw new Error('[kt.js error] KTRef.addOnChange: callback must be a function');
|
|
375
|
-
}
|
|
376
|
-
this._onChanges.push(callback);
|
|
377
|
-
};
|
|
378
|
-
KTRef.prototype.removeOnChange = function (callback) {
|
|
379
|
-
for (var i = this._onChanges.length - 1; i >= 0; i--) {
|
|
380
|
-
if (this._onChanges[i] === callback) {
|
|
381
|
-
this._onChanges.splice(i, 1);
|
|
382
|
-
return true;
|
|
383
|
-
}
|
|
384
|
-
}
|
|
385
|
-
return false;
|
|
386
|
-
};
|
|
387
|
-
return KTRef;
|
|
388
|
-
}());
|
|
389
|
-
/**
|
|
390
|
-
* Reference to the created HTML element.
|
|
391
|
-
* - **Only** respond to `ref.value` changes, not reactive to internal changes of the element.
|
|
392
|
-
* - can alse be used to store normal values, but it is not reactive.
|
|
393
|
-
* - if the value is already a `KTRef`, it will be returned **directly**.
|
|
394
|
-
* @param value mostly an HTMLElement
|
|
395
|
-
*/
|
|
396
|
-
function ref(value, onChange) {
|
|
397
|
-
return new KTRef(value, onChange ? [onChange] : []);
|
|
398
|
-
}
|
|
399
|
-
/**
|
|
400
|
-
* Convert a value to `KTRef`.
|
|
401
|
-
* - Returns the original value if it is already a `KTRef`.
|
|
402
|
-
* - Throws error if the value is a `KTComputed`.
|
|
403
|
-
* - Otherwise wraps the value with `ref()`.
|
|
404
|
-
* @param o value to convert
|
|
405
|
-
*/
|
|
406
|
-
var toRef = function (o) {
|
|
407
|
-
if (isRef(o)) {
|
|
408
|
-
return o;
|
|
409
|
-
}
|
|
410
|
-
else if (isComputed(o)) {
|
|
411
|
-
throw new Error('[kt.js error] Computed values cannot be used as KTRef.');
|
|
412
|
-
}
|
|
413
|
-
else {
|
|
414
|
-
return ref(o);
|
|
415
|
-
}
|
|
416
|
-
};
|
|
417
|
-
function kcollect() {
|
|
418
|
-
var newObj = {};
|
|
419
|
-
var entries = $entries(this);
|
|
420
|
-
for (var i = 0; i < entries.length; i++) {
|
|
421
|
-
var key = entries[i][0];
|
|
422
|
-
if (key === 'kcollect') {
|
|
423
|
-
continue;
|
|
424
|
-
}
|
|
425
|
-
newObj[key] = entries[i][1].value;
|
|
426
|
-
}
|
|
427
|
-
return newObj;
|
|
428
|
-
}
|
|
429
|
-
/**
|
|
430
|
-
* Make all first-level properties of the object a `KTRef`.
|
|
431
|
-
* - `obj.a.b` is not reactive
|
|
432
|
-
*/
|
|
433
|
-
var surfaceRef = function (obj) {
|
|
434
|
-
var entries = $entries(obj);
|
|
435
|
-
var newObj = { kcollect: kcollect };
|
|
436
|
-
for (var i = 0; i < entries.length; i++) {
|
|
437
|
-
newObj[entries[i][0]] = ref(entries[i][1]);
|
|
438
|
-
}
|
|
439
|
-
return newObj;
|
|
440
|
-
};
|
|
441
|
-
// # asserts
|
|
442
|
-
/**
|
|
443
|
-
* Assert k-model to be a ref object
|
|
444
|
-
*/
|
|
445
|
-
var $modelOrRef = function (props, defaultValue) {
|
|
446
|
-
// & props is an object. Won't use it in any other place
|
|
447
|
-
if ('k-model' in props) {
|
|
448
|
-
var kmodel = props['k-model'];
|
|
449
|
-
if (isRef(kmodel)) {
|
|
450
|
-
return kmodel;
|
|
451
|
-
}
|
|
452
|
-
else {
|
|
453
|
-
throw new Error("[kt.js error] k-model data must be a KTRef object, please use 'ref(...)' to wrap it.");
|
|
454
|
-
}
|
|
455
|
-
}
|
|
456
|
-
return ref(defaultValue);
|
|
457
|
-
};
|
|
458
|
-
var $setRef = function (props, node) {
|
|
459
|
-
if ('ref' in props) {
|
|
460
|
-
var r = props.ref;
|
|
461
|
-
if (isRef(r)) {
|
|
462
|
-
r.value = node;
|
|
463
|
-
}
|
|
464
|
-
else {
|
|
465
|
-
throw new Error('[kt.js error] Fragment: ref must be a KTRef');
|
|
466
|
-
}
|
|
467
|
-
}
|
|
468
|
-
};
|
|
469
|
-
|
|
470
|
-
var KTComputed = /** @class */ (function () {
|
|
471
|
-
function KTComputed(_calculator, reactives) {
|
|
472
|
-
/**
|
|
473
|
-
* Indicates that this is a KTRef instance
|
|
474
|
-
*/
|
|
475
|
-
this.isKT = true;
|
|
476
|
-
this.ktType = 2 /* KTReactiveType.COMPUTED */;
|
|
477
|
-
/**
|
|
478
|
-
* @internal
|
|
479
|
-
*/
|
|
480
|
-
this._onChanges = [];
|
|
481
|
-
this._calculator = _calculator;
|
|
482
|
-
this._value = _calculator();
|
|
483
|
-
this._subscribe(reactives);
|
|
484
|
-
}
|
|
485
|
-
/**
|
|
486
|
-
* @internal
|
|
487
|
-
*/
|
|
488
|
-
KTComputed.prototype._emit = function (newValue, oldValue) {
|
|
489
|
-
for (var i = 0; i < this._onChanges.length; i++) {
|
|
490
|
-
this._onChanges[i](newValue, oldValue);
|
|
491
|
-
}
|
|
492
|
-
};
|
|
493
|
-
/**
|
|
494
|
-
* @internal
|
|
495
|
-
*/
|
|
496
|
-
KTComputed.prototype._recalculate = function (forceEmit) {
|
|
497
|
-
if (forceEmit === void 0) { forceEmit = false; }
|
|
498
|
-
var oldValue = this._value;
|
|
499
|
-
var newValue = this._calculator();
|
|
500
|
-
if (oldValue === newValue) {
|
|
501
|
-
if (forceEmit) {
|
|
502
|
-
this._emit(newValue, oldValue);
|
|
503
|
-
}
|
|
504
|
-
return;
|
|
505
|
-
}
|
|
506
|
-
this._value = newValue;
|
|
507
|
-
$replaceNode(oldValue, newValue);
|
|
508
|
-
this._emit(newValue, oldValue);
|
|
509
|
-
};
|
|
510
|
-
/**
|
|
511
|
-
* @internal
|
|
512
|
-
*/
|
|
513
|
-
KTComputed.prototype._subscribe = function (reactives) {
|
|
514
|
-
var _this = this;
|
|
515
|
-
for (var i = 0; i < reactives.length; i++) {
|
|
516
|
-
var reactive = reactives[i];
|
|
517
|
-
reactive.addOnChange(function () { return _this._recalculate(); });
|
|
518
|
-
}
|
|
519
|
-
};
|
|
520
|
-
Object.defineProperty(KTComputed.prototype, "value", {
|
|
521
|
-
/**
|
|
522
|
-
* If new value and old value are both nodes, the old one will be replaced in the DOM
|
|
523
|
-
*/
|
|
524
|
-
get: function () {
|
|
525
|
-
return this._value;
|
|
526
|
-
},
|
|
527
|
-
set: function (_newValue) {
|
|
528
|
-
throw new Error('[kt.js error] KTComputed: cannot set value of a computed value');
|
|
529
|
-
},
|
|
530
|
-
enumerable: false,
|
|
531
|
-
configurable: true
|
|
532
|
-
});
|
|
533
|
-
/**
|
|
534
|
-
* Force listeners to run once with the latest computed result.
|
|
535
|
-
*/
|
|
536
|
-
KTComputed.prototype.notify = function () {
|
|
537
|
-
this._recalculate(true);
|
|
538
|
-
};
|
|
539
|
-
/**
|
|
540
|
-
* Computed values are derived from dependencies and should not be mutated manually.
|
|
541
|
-
*/
|
|
542
|
-
KTComputed.prototype.mutate = function () {
|
|
543
|
-
console.warn('[kt.js warn]','KTComputed.mutate: computed is derived automatically; manual mutate is ignored. Use notify() instead');
|
|
544
|
-
return this._value;
|
|
545
|
-
};
|
|
546
|
-
/**
|
|
547
|
-
* Register a callback when the value changes
|
|
548
|
-
* @param callback (newValue, oldValue) => xxx
|
|
549
|
-
*/
|
|
550
|
-
KTComputed.prototype.addOnChange = function (callback) {
|
|
551
|
-
if (typeof callback !== 'function') {
|
|
552
|
-
throw new Error('[kt.js error] KTRef.addOnChange: callback must be a function');
|
|
553
|
-
}
|
|
554
|
-
this._onChanges.push(callback);
|
|
555
|
-
};
|
|
556
|
-
/**
|
|
557
|
-
* Unregister a callback
|
|
558
|
-
* @param callback (newValue, oldValue) => xxx
|
|
559
|
-
*/
|
|
560
|
-
KTComputed.prototype.removeOnChange = function (callback) {
|
|
561
|
-
for (var i = this._onChanges.length - 1; i >= 0; i--) {
|
|
562
|
-
if (this._onChanges[i] === callback) {
|
|
563
|
-
this._onChanges.splice(i, 1);
|
|
564
|
-
return true;
|
|
565
|
-
}
|
|
566
|
-
}
|
|
567
|
-
return false;
|
|
568
|
-
};
|
|
569
|
-
return KTComputed;
|
|
570
|
-
}());
|
|
571
|
-
/**
|
|
572
|
-
* Create a reactive computed value
|
|
573
|
-
* @param computeFn
|
|
574
|
-
* @param reactives refs and computeds that this computed depends on
|
|
575
|
-
*/
|
|
576
|
-
function computed(computeFn, reactives) {
|
|
577
|
-
if (reactives.some(function (v) { return !isKT(v); })) {
|
|
578
|
-
throw new Error('[kt.js error] computed: all reactives must be KTRef or KTComputed instances');
|
|
579
|
-
}
|
|
580
|
-
return new KTComputed(computeFn, reactives);
|
|
581
|
-
}
|
|
582
|
-
|
|
583
|
-
/**
|
|
584
|
-
* Register a reactive effect with options.
|
|
585
|
-
* @param effectFn The effect function to run when dependencies change
|
|
586
|
-
* @param reactives The reactive dependencies
|
|
587
|
-
* @param options Effect options: lazy, onCleanup, debugName
|
|
588
|
-
* @returns stop function to remove all listeners
|
|
589
|
-
*/
|
|
590
|
-
function effect(effectFn, reactives, options) {
|
|
591
|
-
var _a = Object(options), _b = _a.lazy, lazy = _b === void 0 ? false : _b, _c = _a.onCleanup, onCleanup = _c === void 0 ? $emptyFn : _c, _d = _a.debugName, debugName = _d === void 0 ? '' : _d;
|
|
592
|
-
var active = true;
|
|
593
|
-
var run = function () {
|
|
594
|
-
if (!active) {
|
|
595
|
-
return;
|
|
596
|
-
}
|
|
597
|
-
// cleanup before rerun
|
|
598
|
-
onCleanup();
|
|
599
|
-
try {
|
|
600
|
-
effectFn();
|
|
601
|
-
}
|
|
602
|
-
catch (err) {
|
|
603
|
-
console.debug('[kt.js debug]','effect error:', debugName, err);
|
|
604
|
-
}
|
|
605
|
-
};
|
|
606
|
-
// subscribe to dependencies
|
|
607
|
-
for (var i = 0; i < reactives.length; i++) {
|
|
608
|
-
reactives[i].addOnChange(run);
|
|
609
|
-
}
|
|
610
|
-
// auto run unless lazy
|
|
611
|
-
if (!lazy) {
|
|
612
|
-
run();
|
|
613
|
-
}
|
|
614
|
-
// stop function
|
|
615
|
-
return function () {
|
|
616
|
-
if (!active) {
|
|
617
|
-
return;
|
|
618
|
-
}
|
|
619
|
-
active = false;
|
|
620
|
-
for (var i = 0; i < reactives.length; i++) {
|
|
621
|
-
reactives[i].removeOnChange(run);
|
|
622
|
-
}
|
|
623
|
-
// final cleanup
|
|
624
|
-
onCleanup();
|
|
625
|
-
};
|
|
626
|
-
}
|
|
627
|
-
|
|
628
|
-
var toReactive = function (value, onChange) {
|
|
629
|
-
if (isKT(value)) {
|
|
630
|
-
if (onChange) {
|
|
631
|
-
value.addOnChange(onChange);
|
|
632
|
-
}
|
|
633
|
-
return value;
|
|
634
|
-
}
|
|
635
|
-
else {
|
|
636
|
-
return ref(value, onChange);
|
|
637
|
-
}
|
|
638
|
-
};
|
|
639
|
-
/**
|
|
640
|
-
* Extracts the value from a KTReactive, or returns the value directly if it's not reactive.
|
|
641
|
-
*/
|
|
642
|
-
function dereactive(value) {
|
|
643
|
-
return isKT(value) ? value.value : value;
|
|
644
|
-
}
|
|
645
|
-
|
|
646
|
-
function applyKModel(element, valueRef) {
|
|
647
|
-
if (!isKT(valueRef)) {
|
|
648
|
-
console.warn('[kt.js warn]','k-model value must be a KTRef.');
|
|
649
|
-
return;
|
|
650
|
-
}
|
|
651
|
-
if (element instanceof HTMLInputElement) {
|
|
652
|
-
if (element.type === 'radio' || element.type === 'checkbox') {
|
|
653
|
-
$applyModel(element, valueRef, 'checked', 'change');
|
|
654
|
-
}
|
|
655
|
-
else {
|
|
656
|
-
$applyModel(element, valueRef, 'value', 'input');
|
|
657
|
-
}
|
|
658
|
-
}
|
|
659
|
-
else if (element instanceof HTMLSelectElement) {
|
|
660
|
-
$applyModel(element, valueRef, 'value', 'change');
|
|
661
|
-
}
|
|
662
|
-
else if (element instanceof HTMLTextAreaElement) {
|
|
663
|
-
$applyModel(element, valueRef, 'value', 'input');
|
|
664
|
-
}
|
|
665
|
-
else {
|
|
666
|
-
console.warn('[kt.js warn]','not supported element for k-model:');
|
|
667
|
-
}
|
|
668
|
-
}
|
|
669
|
-
|
|
670
|
-
var htmlCreator = function (tag) { return document.createElement(tag); };
|
|
671
|
-
var svgCreator = function (tag) { return document.createElementNS('http://www.w3.org/2000/svg', tag); };
|
|
672
|
-
var mathMLCreator = function (tag) { return document.createElementNS('http://www.w3.org/1998/Math/MathML', tag); };
|
|
673
|
-
var creator = htmlCreator;
|
|
674
|
-
/**
|
|
675
|
-
* Create an enhanced HTMLElement.
|
|
676
|
-
* - Only supports HTMLElements, **NOT** SVGElements or other Elements.
|
|
677
|
-
* @param tag tag of an `HTMLElement`
|
|
678
|
-
* @param attr attribute object or className
|
|
679
|
-
* @param content a string or an array of HTMLEnhancedElement as child nodes
|
|
680
|
-
*
|
|
681
|
-
* ## About
|
|
682
|
-
* @package @ktjs/core
|
|
683
|
-
* @author Kasukabe Tsumugi <futami16237@gmail.com>
|
|
684
|
-
* @version 0.28.2 (Last Update: 2026.02.10 14:46:21.243)
|
|
685
|
-
* @license MIT
|
|
686
|
-
* @link https://github.com/baendlorel/kt.js
|
|
687
|
-
* @link https://baendlorel.github.io/ Welcome to my site!
|
|
688
|
-
* @description Core functionality for kt.js - DOM manipulation utilities with JSX/TSX support
|
|
689
|
-
* @copyright Copyright (c) 2026 Kasukabe Tsumugi. All rights reserved.
|
|
690
|
-
*/
|
|
691
|
-
var h = function (tag, attr, content) {
|
|
692
|
-
if (typeof tag !== 'string') {
|
|
693
|
-
throw new Error('[kt.js error] tagName must be a string.');
|
|
694
|
-
}
|
|
695
|
-
if (attr) {
|
|
696
|
-
if (SVG_ATTR_FLAG in attr) {
|
|
697
|
-
delete attr[SVG_ATTR_FLAG];
|
|
698
|
-
creator = svgCreator;
|
|
699
|
-
}
|
|
700
|
-
else if (MATHML_ATTR_FLAG in attr) {
|
|
701
|
-
delete attr[MATHML_ATTR_FLAG];
|
|
702
|
-
creator = mathMLCreator;
|
|
703
|
-
}
|
|
704
|
-
else {
|
|
705
|
-
creator = htmlCreator;
|
|
706
|
-
}
|
|
707
|
-
}
|
|
708
|
-
// * start creating the element
|
|
709
|
-
var element = creator(tag);
|
|
710
|
-
// * Handle content
|
|
711
|
-
applyAttr(element, attr);
|
|
712
|
-
applyContent(element, content);
|
|
713
|
-
if (typeof attr === 'object' && attr !== null && 'k-model' in attr) {
|
|
714
|
-
applyKModel(element, attr['k-model']);
|
|
715
|
-
}
|
|
716
|
-
return element;
|
|
717
|
-
};
|
|
718
|
-
|
|
719
|
-
/**
|
|
720
|
-
* Fragment - Container component for managing arrays of child elements
|
|
721
|
-
*
|
|
722
|
-
* Features:
|
|
723
|
-
* 1. Returns a comment anchor node, child elements are inserted after the anchor
|
|
724
|
-
* 2. Supports reactive arrays, automatically updates DOM when array changes
|
|
725
|
-
* 3. Basic version uses simple replacement algorithm (remove all old elements, insert all new elements)
|
|
726
|
-
* 4. Future enhancement: key-based optimization
|
|
727
|
-
*
|
|
728
|
-
* Usage example:
|
|
729
|
-
* ```tsx
|
|
730
|
-
* const children = ref([<div>A</div>, <div>B</div>]);
|
|
731
|
-
* const fragment = <Fragment children={children} />;
|
|
732
|
-
* document.body.appendChild(fragment);
|
|
733
|
-
*
|
|
734
|
-
* // Automatic update
|
|
735
|
-
* children.value = [<div>C</div>, <div>D</div>];
|
|
736
|
-
* ```
|
|
737
|
-
*/
|
|
738
|
-
function Fragment$1(props) {
|
|
739
|
-
// key parameter reserved for future enhancement, currently unused
|
|
740
|
-
// const { key: _key } = props;
|
|
741
|
-
var redraw = function () {
|
|
742
|
-
var newElements = childrenRef.value;
|
|
743
|
-
var parent = anchor.parentNode;
|
|
744
|
-
if (!parent) {
|
|
745
|
-
// If anchor is not in DOM, only update internal state
|
|
746
|
-
elements.length = 0;
|
|
747
|
-
for (var i = 0; i < newElements.length; i++) {
|
|
748
|
-
elements.push(newElements[i]);
|
|
749
|
-
}
|
|
750
|
-
return;
|
|
751
|
-
}
|
|
752
|
-
// Simple replacement algorithm: remove all old elements, insert all new elements
|
|
753
|
-
// todo Future enhancement: key-based optimization
|
|
754
|
-
// 1. Remove all old elements
|
|
755
|
-
for (var i = 0; i < elements.length; i++) {
|
|
756
|
-
elements[i].remove();
|
|
757
|
-
}
|
|
758
|
-
// 2. Insert all new elements
|
|
759
|
-
var fragment = document.createDocumentFragment();
|
|
760
|
-
elements.length = 0;
|
|
761
|
-
for (var i = 0; i < newElements.length; i++) {
|
|
762
|
-
var element = newElements[i];
|
|
763
|
-
elements.push(element);
|
|
764
|
-
fragment.appendChild(element);
|
|
765
|
-
}
|
|
766
|
-
// Insert after anchor
|
|
767
|
-
parent.insertBefore(fragment, anchor.nextSibling);
|
|
768
|
-
};
|
|
769
|
-
var initialized = false;
|
|
770
|
-
var childrenRef = toReactive(props.children, redraw);
|
|
771
|
-
var elements = [];
|
|
772
|
-
var anchor = document.createComment('kt-fragment');
|
|
773
|
-
// Observe DOM insertion
|
|
774
|
-
var observer = new MutationObserver(function () {
|
|
775
|
-
if (anchor.isConnected && !initialized) {
|
|
776
|
-
initialized = true;
|
|
777
|
-
redraw();
|
|
778
|
-
observer.disconnect();
|
|
779
|
-
}
|
|
780
|
-
});
|
|
781
|
-
observer.observe(document.body, { childList: true, subtree: true });
|
|
782
|
-
// Set ref reference
|
|
783
|
-
$setRef(props, anchor);
|
|
784
|
-
return anchor;
|
|
785
|
-
}
|
|
786
|
-
/**
|
|
787
|
-
* Convert KTRawContent to HTMLElement array
|
|
788
|
-
*/
|
|
789
|
-
function convertChildrenToElements(children) {
|
|
790
|
-
var elements = [];
|
|
791
|
-
var processChild = function (child) {
|
|
792
|
-
if (child === undefined || child === null || child === false || child === true) {
|
|
793
|
-
// Ignore null, undefined, false, true
|
|
794
|
-
return;
|
|
795
|
-
}
|
|
796
|
-
if ($isArray(child)) {
|
|
797
|
-
// Recursively process array
|
|
798
|
-
$forEach(child, processChild);
|
|
799
|
-
return;
|
|
800
|
-
}
|
|
801
|
-
if (typeof child === 'string' || typeof child === 'number') {
|
|
802
|
-
// & Wrap text in span element? No! use text node instead
|
|
803
|
-
var textNode = document.createTextNode(String(child));
|
|
804
|
-
elements.push(textNode);
|
|
805
|
-
return;
|
|
806
|
-
}
|
|
807
|
-
if (child instanceof HTMLElement) {
|
|
808
|
-
elements.push(child);
|
|
809
|
-
return;
|
|
810
|
-
}
|
|
811
|
-
if (isKT(child)) {
|
|
812
|
-
processChild(child.value);
|
|
813
|
-
return;
|
|
814
|
-
}
|
|
815
|
-
// Other types ignored or converted to string
|
|
816
|
-
console.warn('[kt.js warn]','Fragment: unsupported child type', child);
|
|
817
|
-
};
|
|
818
|
-
processChild(children);
|
|
819
|
-
return elements;
|
|
820
|
-
}
|
|
821
|
-
|
|
822
|
-
var create = function (tag, props) {
|
|
823
|
-
if (typeof tag === 'function') {
|
|
824
|
-
return tag(props);
|
|
825
|
-
}
|
|
826
|
-
else {
|
|
827
|
-
return h(tag, props, props.children);
|
|
828
|
-
}
|
|
829
|
-
};
|
|
830
|
-
var placeholder = function () { return document.createComment('k-if'); };
|
|
831
|
-
/**
|
|
832
|
-
* @param tag html tag or function component
|
|
833
|
-
* @param props properties/attributes
|
|
834
|
-
*/
|
|
835
|
-
function jsx(tag, props) {
|
|
836
|
-
if (isComputed(props.ref)) {
|
|
837
|
-
throw new Error('[kt.js error] Cannot assign a computed value to an element.');
|
|
838
|
-
}
|
|
839
|
-
var el;
|
|
840
|
-
if ('k-if' in props) {
|
|
841
|
-
var kif = props['k-if'];
|
|
842
|
-
var condition = kif; // assume boolean by default
|
|
843
|
-
// Handle reactive k-if
|
|
844
|
-
if (isKT(kif)) {
|
|
845
|
-
kif.addOnChange(function (newValue, oldValue) {
|
|
846
|
-
if (newValue === oldValue) {
|
|
847
|
-
return;
|
|
848
|
-
}
|
|
849
|
-
var oldEl = el;
|
|
850
|
-
$setRef(props, (el = newValue ? create(tag, props) : placeholder()));
|
|
851
|
-
$replaceNode(oldEl, el);
|
|
852
|
-
});
|
|
853
|
-
condition = kif.value;
|
|
854
|
-
}
|
|
855
|
-
if (!condition) {
|
|
856
|
-
// & make comment placeholder in case that ref might be redrawn later
|
|
857
|
-
$setRef(props, (el = placeholder()));
|
|
858
|
-
return el;
|
|
859
|
-
}
|
|
860
|
-
}
|
|
861
|
-
$setRef(props, (el = create(tag, props)));
|
|
862
|
-
return el;
|
|
863
|
-
}
|
|
864
|
-
/**
|
|
865
|
-
* Fragment support - returns an array of children
|
|
866
|
-
* Enhanced Fragment component that manages arrays of elements
|
|
867
|
-
*/
|
|
868
|
-
function Fragment(props) {
|
|
869
|
-
var children = (props !== null && props !== void 0 ? props : {}).children;
|
|
870
|
-
if (!children) {
|
|
871
|
-
return document.createComment('kt-fragment-empty');
|
|
872
|
-
}
|
|
873
|
-
var elements = convertChildrenToElements(children);
|
|
874
|
-
return Fragment$1({ children: elements });
|
|
875
|
-
}
|
|
876
|
-
/**
|
|
877
|
-
* JSX Development runtime - same as jsx but with additional dev checks
|
|
878
|
-
*/
|
|
879
|
-
var jsxDEV = function () {
|
|
880
|
-
var args = [];
|
|
881
|
-
for (var _i = 0; _i < arguments.length; _i++) {
|
|
882
|
-
args[_i] = arguments[_i];
|
|
883
|
-
}
|
|
884
|
-
// console.log('JSX DEV called:', ...args);
|
|
885
|
-
// console.log('children', (args[1] as any)?.children);
|
|
886
|
-
return jsx.apply(void 0, args);
|
|
887
|
-
};
|
|
888
|
-
/**
|
|
889
|
-
* JSX runtime for React 17+ automatic runtime
|
|
890
|
-
* This is called when using jsx: "react-jsx" or "react-jsxdev"
|
|
891
|
-
*/
|
|
892
|
-
var jsxs = jsx;
|
|
893
|
-
/**
|
|
894
|
-
* A helper to create redrawable elements
|
|
895
|
-
* ```tsx
|
|
896
|
-
* export function MyComponent() {
|
|
897
|
-
* let aa = 10;
|
|
898
|
-
* // ...
|
|
899
|
-
* // aa might be changed
|
|
900
|
-
* return createRedrawable(() => <div>{aa}</div>);
|
|
901
|
-
* }
|
|
902
|
-
* ```
|
|
903
|
-
* Then the returned element has a `redraw` method to redraw itself with new values.
|
|
904
|
-
* @param creator a simple creator function that returns an element
|
|
905
|
-
* @returns created element's ref
|
|
906
|
-
*/
|
|
907
|
-
function createRedrawable(creator) {
|
|
908
|
-
var elRef = ref();
|
|
909
|
-
var redraw = function () {
|
|
910
|
-
elRef.value = creator(); // ref setter automatically calls replaceWith
|
|
911
|
-
elRef.redraw = redraw;
|
|
912
|
-
return elRef.value;
|
|
913
|
-
};
|
|
914
|
-
redraw();
|
|
915
|
-
return elRef;
|
|
916
|
-
}
|
|
917
|
-
|
|
918
|
-
function KTAsync(props) {
|
|
919
|
-
var _a;
|
|
920
|
-
var raw = props.component(props);
|
|
921
|
-
var comp = (_a = props.skeleton) !== null && _a !== void 0 ? _a : document.createComment('ktjs-suspense-placeholder');
|
|
922
|
-
if ($isThenable(raw)) {
|
|
923
|
-
raw.then(function (resolved) { return comp.replaceWith(resolved); });
|
|
924
|
-
}
|
|
925
|
-
else {
|
|
926
|
-
comp = raw;
|
|
927
|
-
}
|
|
928
|
-
return comp;
|
|
929
|
-
}
|
|
930
|
-
|
|
931
|
-
/**
|
|
932
|
-
* KTFor - List rendering component with key-based optimization
|
|
933
|
-
* Returns a Comment anchor node with rendered elements in __kt_for_list__
|
|
934
|
-
*/
|
|
935
|
-
function KTFor(props) {
|
|
936
|
-
var redraw = function () {
|
|
937
|
-
var newList = listRef.value;
|
|
938
|
-
var parent = anchor.parentNode;
|
|
939
|
-
if (!parent) {
|
|
940
|
-
// If not in DOM yet, just rebuild the list
|
|
941
|
-
var newElements_1 = [];
|
|
942
|
-
nodeMap.clear();
|
|
943
|
-
for (var index = 0; index < newList.length; index++) {
|
|
944
|
-
var item = newList[index];
|
|
945
|
-
var itemKey = currentKey(item, index, newList);
|
|
946
|
-
var node = currentMap(item, index, newList);
|
|
947
|
-
nodeMap.set(itemKey, node);
|
|
948
|
-
newElements_1.push(node);
|
|
949
|
-
}
|
|
950
|
-
anchor.__kt_for_list__ = newElements_1;
|
|
951
|
-
return anchor;
|
|
952
|
-
}
|
|
953
|
-
var oldLength = anchor.__kt_for_list__.length;
|
|
954
|
-
var newLength = newList.length;
|
|
955
|
-
// Fast path: empty list
|
|
956
|
-
if (newLength === 0) {
|
|
957
|
-
nodeMap.forEach(function (node) { return node.remove(); });
|
|
958
|
-
nodeMap.clear();
|
|
959
|
-
anchor.__kt_for_list__ = [];
|
|
960
|
-
return anchor;
|
|
961
|
-
}
|
|
962
|
-
// Fast path: all new items
|
|
963
|
-
if (oldLength === 0) {
|
|
964
|
-
var newElements_2 = [];
|
|
965
|
-
var fragment = document.createDocumentFragment();
|
|
966
|
-
for (var i = 0; i < newLength; i++) {
|
|
967
|
-
var item = newList[i];
|
|
968
|
-
var itemKey = currentKey(item, i, newList);
|
|
969
|
-
var node = currentMap(item, i, newList);
|
|
970
|
-
nodeMap.set(itemKey, node);
|
|
971
|
-
newElements_2.push(node);
|
|
972
|
-
fragment.appendChild(node);
|
|
973
|
-
}
|
|
974
|
-
parent.insertBefore(fragment, anchor.nextSibling);
|
|
975
|
-
anchor.__kt_for_list__ = newElements_2;
|
|
976
|
-
return anchor;
|
|
977
|
-
}
|
|
978
|
-
// Build key index map and new elements array in one pass
|
|
979
|
-
var newKeyToNewIndex = new Map();
|
|
980
|
-
var newElements = new Array(newLength);
|
|
981
|
-
var maxNewIndexSoFar = 0;
|
|
982
|
-
var moved = false;
|
|
983
|
-
for (var i = 0; i < newLength; i++) {
|
|
984
|
-
var item = newList[i];
|
|
985
|
-
var itemKey = currentKey(item, i, newList);
|
|
986
|
-
newKeyToNewIndex.set(itemKey, i);
|
|
987
|
-
if (nodeMap.has(itemKey)) {
|
|
988
|
-
// Reuse existing node
|
|
989
|
-
var node = nodeMap.get(itemKey);
|
|
990
|
-
newElements[i] = node;
|
|
991
|
-
// Track if items moved
|
|
992
|
-
if (i < maxNewIndexSoFar) {
|
|
993
|
-
moved = true;
|
|
994
|
-
}
|
|
995
|
-
else {
|
|
996
|
-
maxNewIndexSoFar = i;
|
|
997
|
-
}
|
|
998
|
-
}
|
|
999
|
-
else {
|
|
1000
|
-
// Create new node
|
|
1001
|
-
newElements[i] = currentMap(item, i, newList);
|
|
1002
|
-
}
|
|
1003
|
-
}
|
|
1004
|
-
// Remove nodes not in new list
|
|
1005
|
-
var toRemove = [];
|
|
1006
|
-
nodeMap.forEach(function (node, key) {
|
|
1007
|
-
if (!newKeyToNewIndex.has(key)) {
|
|
1008
|
-
toRemove.push(node);
|
|
1009
|
-
}
|
|
1010
|
-
});
|
|
1011
|
-
for (var i = 0; i < toRemove.length; i++) {
|
|
1012
|
-
toRemove[i].remove();
|
|
1013
|
-
}
|
|
1014
|
-
// Update DOM with minimal operations
|
|
1015
|
-
if (moved) {
|
|
1016
|
-
// Use longest increasing subsequence to minimize moves
|
|
1017
|
-
var seq = getSequence(newElements.map(function (el, i) { return (nodeMap.has(currentKey(newList[i], i, newList)) ? i : -1); }));
|
|
1018
|
-
var j = seq.length - 1;
|
|
1019
|
-
var anchor_1 = null;
|
|
1020
|
-
// Traverse from end to start for stable insertions
|
|
1021
|
-
for (var i = newLength - 1; i >= 0; i--) {
|
|
1022
|
-
var node = newElements[i];
|
|
1023
|
-
if (j < 0 || i !== seq[j]) {
|
|
1024
|
-
// Node needs to be moved or inserted
|
|
1025
|
-
if (anchor_1) {
|
|
1026
|
-
parent.insertBefore(node, anchor_1);
|
|
1027
|
-
}
|
|
1028
|
-
else {
|
|
1029
|
-
// Insert at end
|
|
1030
|
-
var nextSibling = anchor_1.nextSibling;
|
|
1031
|
-
var temp = nextSibling;
|
|
1032
|
-
while (temp && newElements.includes(temp)) {
|
|
1033
|
-
temp = temp.nextSibling;
|
|
1034
|
-
}
|
|
1035
|
-
parent.insertBefore(node, temp);
|
|
1036
|
-
}
|
|
1037
|
-
}
|
|
1038
|
-
else {
|
|
1039
|
-
j--;
|
|
1040
|
-
}
|
|
1041
|
-
anchor_1 = node;
|
|
1042
|
-
}
|
|
1043
|
-
}
|
|
1044
|
-
else {
|
|
1045
|
-
// No moves needed, just insert new nodes
|
|
1046
|
-
var currentNode = anchor.nextSibling;
|
|
1047
|
-
for (var i = 0; i < newLength; i++) {
|
|
1048
|
-
var node = newElements[i];
|
|
1049
|
-
if (currentNode !== node) {
|
|
1050
|
-
parent.insertBefore(node, currentNode);
|
|
1051
|
-
}
|
|
1052
|
-
else {
|
|
1053
|
-
currentNode = currentNode.nextSibling;
|
|
1054
|
-
}
|
|
1055
|
-
}
|
|
1056
|
-
}
|
|
1057
|
-
// Update maps
|
|
1058
|
-
nodeMap.clear();
|
|
1059
|
-
for (var i = 0; i < newLength; i++) {
|
|
1060
|
-
var itemKey = currentKey(newList[i], i, newList);
|
|
1061
|
-
nodeMap.set(itemKey, newElements[i]);
|
|
1062
|
-
}
|
|
1063
|
-
anchor.__kt_for_list__ = newElements;
|
|
1064
|
-
return anchor;
|
|
1065
|
-
};
|
|
1066
|
-
var _a = props.key, currentKey = _a === void 0 ? function (item) { return item; } : _a, currentMap = props.map;
|
|
1067
|
-
var listRef = toReactive(props.list, redraw);
|
|
1068
|
-
var anchor = document.createComment('kt-for');
|
|
1069
|
-
// Map to track rendered nodes by key
|
|
1070
|
-
var nodeMap = new Map();
|
|
1071
|
-
// Render initial list
|
|
1072
|
-
var elements = [];
|
|
1073
|
-
for (var index = 0; index < listRef.value.length; index++) {
|
|
1074
|
-
var item = listRef.value[index];
|
|
1075
|
-
var itemKey = currentKey(item, index, listRef.value);
|
|
1076
|
-
var node = currentMap(item, index, listRef.value);
|
|
1077
|
-
nodeMap.set(itemKey, node);
|
|
1078
|
-
elements.push(node);
|
|
1079
|
-
}
|
|
1080
|
-
anchor.__kt_for_list__ = elements;
|
|
1081
|
-
$setRef(props, anchor);
|
|
1082
|
-
return anchor;
|
|
1083
|
-
}
|
|
1084
|
-
// Longest Increasing Subsequence algorithm (optimized for diff)
|
|
1085
|
-
function getSequence(arr) {
|
|
1086
|
-
var p = arr.slice();
|
|
1087
|
-
var result = [0];
|
|
1088
|
-
var i, j, u, v, c;
|
|
1089
|
-
var len = arr.length;
|
|
1090
|
-
for (i = 0; i < len; i++) {
|
|
1091
|
-
var arrI = arr[i];
|
|
1092
|
-
if (arrI === -1)
|
|
1093
|
-
continue;
|
|
1094
|
-
j = result[result.length - 1];
|
|
1095
|
-
if (arr[j] < arrI) {
|
|
1096
|
-
p[i] = j;
|
|
1097
|
-
result.push(i);
|
|
1098
|
-
continue;
|
|
1099
|
-
}
|
|
1100
|
-
u = 0;
|
|
1101
|
-
v = result.length - 1;
|
|
1102
|
-
while (u < v) {
|
|
1103
|
-
c = ((u + v) / 2) | 0;
|
|
1104
|
-
if (arr[result[c]] < arrI) {
|
|
1105
|
-
u = c + 1;
|
|
1106
|
-
}
|
|
1107
|
-
else {
|
|
1108
|
-
v = c;
|
|
1109
|
-
}
|
|
1110
|
-
}
|
|
1111
|
-
if (arrI < arr[result[u]]) {
|
|
1112
|
-
if (u > 0) {
|
|
1113
|
-
p[i] = result[u - 1];
|
|
1114
|
-
}
|
|
1115
|
-
result[u] = i;
|
|
1116
|
-
}
|
|
1117
|
-
}
|
|
1118
|
-
u = result.length;
|
|
1119
|
-
v = result[u - 1];
|
|
1120
|
-
while (u-- > 0) {
|
|
1121
|
-
result[u] = v;
|
|
1122
|
-
v = p[v];
|
|
1123
|
-
}
|
|
1124
|
-
return result;
|
|
1125
|
-
}
|
|
1126
|
-
|
|
1127
|
-
exports.$modelOrRef = $modelOrRef;
|
|
1128
|
-
exports.$setRef = $setRef;
|
|
1129
|
-
exports.Fragment = Fragment;
|
|
1130
|
-
exports.KTAsync = KTAsync;
|
|
1131
|
-
exports.KTComputed = KTComputed;
|
|
1132
|
-
exports.KTFor = KTFor;
|
|
1133
|
-
exports.KTRef = KTRef;
|
|
1134
|
-
exports.computed = computed;
|
|
1135
|
-
exports.createElement = h;
|
|
1136
|
-
exports.createRedrawable = createRedrawable;
|
|
1137
|
-
exports.dereactive = dereactive;
|
|
1138
|
-
exports.effect = effect;
|
|
1139
|
-
exports.h = h;
|
|
1140
|
-
exports.isComputed = isComputed;
|
|
1141
|
-
exports.isKT = isKT;
|
|
1142
|
-
exports.isRef = isRef;
|
|
1143
|
-
exports.jsx = jsx;
|
|
1144
|
-
exports.jsxDEV = jsxDEV;
|
|
1145
|
-
exports.jsxs = jsxs;
|
|
1146
|
-
exports.ref = ref;
|
|
1147
|
-
exports.surfaceRef = surfaceRef;
|
|
1148
|
-
exports.toReactive = toReactive;
|
|
1149
|
-
exports.toRef = toRef;
|
|
1150
|
-
|
|
1151
|
-
return exports;
|
|
1152
|
-
|
|
1153
|
-
})({});
|