@ktjs/core 0.33.0 → 0.33.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.mjs CHANGED
@@ -1,34 +1,10 @@
1
- import { $isArray, $isThenable, $isNode, $emptyFn, $is, $applyModel, $forEach, $identity } from '@ktjs/shared';
1
+ import { $isArray, $isThenable, $isNode, $emptyFn, $is, $applyModel, $forEach, $identity } from "@ktjs/shared";
2
2
 
3
- const isKT = (obj) => obj?.isKT;
4
- const isRef = (obj) => {
5
- // & This is tested to be the fastest way.
6
- // faster than includes, arrayindex, if or.
7
- if (obj.ktType === undefined) {
8
- return false;
9
- }
10
- return obj.ktType === 3 /* KTReactiveType.Ref */;
11
- };
12
- const isComputed = (obj) => obj?.ktType === 2 /* KTReactiveType.Computed */;
13
-
14
- const booleanHandler = (element, key, value) => {
15
- if (key in element) {
16
- element[key] = !!value;
17
- }
18
- else {
19
- element.setAttribute(key, value);
20
- }
21
- };
22
- const valueHandler = (element, key, value) => {
23
- if (key in element) {
24
- element[key] = value;
25
- }
26
- else {
27
- element.setAttribute(key, value);
28
- }
29
- };
30
- // Attribute handlers map for optimized lookup
31
- const handlers = {
3
+ const isKT = obj => obj?.isKT, isRef = obj => void 0 !== obj.ktType && 3 === obj.ktType, isComputed = obj => 2 === obj?.ktType, booleanHandler = (element, key, value) => {
4
+ key in element ? element[key] = !!value : element.setAttribute(key, value);
5
+ }, valueHandler = (element, key, value) => {
6
+ key in element ? element[key] = value : element.setAttribute(key, value);
7
+ }, handlers = {
32
8
  checked: booleanHandler,
33
9
  selected: booleanHandler,
34
10
  value: valueHandler,
@@ -49,485 +25,224 @@ const handlers = {
49
25
  muted: booleanHandler,
50
26
  defer: booleanHandler,
51
27
  async: booleanHandler,
52
- hidden: (element, _key, value) => (element.hidden = !!value),
28
+ hidden: (element, _key, value) => element.hidden = !!value
29
+ }, defaultHandler = (element, key, value) => element.setAttribute(key, value), setElementStyle = (element, style) => {
30
+ if ("string" != typeof style) for (const key in style) element.style[key] = style[key]; else element.style.cssText = style;
53
31
  };
54
32
 
55
- const defaultHandler = (element, key, value) => element.setAttribute(key, value);
56
- const setElementStyle = (element, style) => {
57
- if (typeof style === 'string') {
58
- element.style.cssText = style;
59
- return;
60
- }
61
- for (const key in style) {
62
- element.style[key] = style[key];
63
- }
64
- };
65
- function attrIsObject(element, attr) {
66
- const classValue = attr.class || attr.className;
67
- if (classValue !== undefined) {
68
- if (isKT(classValue)) {
69
- element.setAttribute('class', classValue.value);
70
- classValue.addOnChange((v) => element.setAttribute('class', v));
71
- }
72
- else {
73
- element.setAttribute('class', classValue);
74
- }
75
- }
76
- const style = attr.style;
77
- if (style) {
78
- if (typeof style === 'string') {
79
- element.setAttribute('style', style);
80
- }
81
- else if (typeof style === 'object') {
82
- if (isKT(style)) {
83
- setElementStyle(element, style.value);
84
- style.addOnChange((v) => setElementStyle(element, v));
33
+ function applyAttr(element, attr) {
34
+ if (attr) {
35
+ if ("object" != typeof attr || null === attr) throw new Error("[@ktjs/core error] attr must be an object.");
36
+ !function(element, attr) {
37
+ const classValue = attr.class || attr.className;
38
+ void 0 !== classValue && (isKT(classValue) ? (element.setAttribute("class", classValue.value),
39
+ classValue.addOnChange(v => element.setAttribute("class", v))) : element.setAttribute("class", classValue));
40
+ const style = attr.style;
41
+ if (style && ("string" == typeof style ? element.setAttribute("style", style) : "object" == typeof style && (isKT(style) ? (setElementStyle(element, style.value),
42
+ style.addOnChange(v => setElementStyle(element, v))) : setElementStyle(element, style))),
43
+ "k-html" in attr) {
44
+ const html = attr["k-html"];
45
+ isKT(html) ? (element.innerHTML = html.value, html.addOnChange(v => element.innerHTML = v)) : element.innerHTML = html;
85
46
  }
86
- else {
87
- setElementStyle(element, style);
47
+ for (const key in attr) {
48
+ if ("k-model" === key || "k-for" === key || "k-key" === key || "ref" === key || "class" === key || "className" === key || "style" === key || "children" === key || "k-html" === key) continue;
49
+ const o = attr[key];
50
+ if (key.startsWith("on:")) {
51
+ o && element.addEventListener(key.slice(3), o);
52
+ continue;
53
+ }
54
+ const handler = handlers[key] || defaultHandler;
55
+ isKT(o) ? (handler(element, key, o.value), o.addOnChange(v => handler(element, key, v))) : handler(element, key, o);
88
56
  }
89
- }
90
- }
91
- if ('k-html' in attr) {
92
- const html = attr['k-html'];
93
- if (isKT(html)) {
94
- element.innerHTML = html.value;
95
- html.addOnChange((v) => (element.innerHTML = v));
96
- }
97
- else {
98
- element.innerHTML = html;
99
- }
100
- }
101
- for (const key in attr) {
102
- // & Arranged in order of usage frequency
103
- if (
104
- // key === 'k-if' ||
105
- // key === 'k-else' ||
106
- key === 'k-model' ||
107
- key === 'k-for' ||
108
- key === 'k-key' ||
109
- key === 'ref' ||
110
- key === 'class' ||
111
- key === 'className' ||
112
- key === 'style' ||
113
- key === 'children' ||
114
- key === 'k-html') {
115
- continue;
116
- }
117
- const o = attr[key];
118
- // normal event handler
119
- if (key.startsWith('on:')) {
120
- if (o) {
121
- element.addEventListener(key.slice(3), o); // chop off the `on:`
122
- }
123
- continue;
124
- }
125
- // normal attributes
126
- const handler = handlers[key] || defaultHandler;
127
- if (isKT(o)) {
128
- handler(element, key, o.value);
129
- o.addOnChange((v) => handler(element, key, v));
130
- }
131
- else {
132
- handler(element, key, o);
133
- }
134
- }
135
- }
136
- function applyAttr(element, attr) {
137
- if (!attr) {
138
- return;
139
- }
140
- if (typeof attr === 'object' && attr !== null) {
141
- attrIsObject(element, attr);
142
- }
143
- else {
144
- throw new Error('[@ktjs/core error] attr must be an object.');
57
+ }(element, attr);
145
58
  }
146
59
  }
147
60
 
148
- const assureNode = (o) => ($isNode(o) ? o : document.createTextNode(o));
61
+ const assureNode = o => $isNode(o) ? o : document.createTextNode(o);
62
+
149
63
  function apdSingle(element, c) {
150
- // & Ignores falsy values, consistent with React's behavior
151
- if (c === undefined || c === null || c === false) {
152
- return;
153
- }
154
- if (isKT(c)) {
64
+ if (null != c && !1 !== c) if (isKT(c)) {
155
65
  let node = assureNode(c.value);
156
- element.appendChild(node);
157
- c.addOnChange((newValue, _oldValue) => {
66
+ element.appendChild(node), c.addOnChange((newValue, _oldValue) => {
158
67
  const oldNode = node;
159
- node = assureNode(newValue);
160
- oldNode.replaceWith(node);
68
+ node = assureNode(newValue), oldNode.replaceWith(node);
161
69
  });
162
- }
163
- else {
70
+ } else {
164
71
  const node = assureNode(c);
165
72
  element.appendChild(node);
166
- // Handle KTFor anchor
167
73
  const list = node.__kt_for_list__;
168
- if ($isArray(list)) {
169
- apd(element, list);
170
- }
74
+ $isArray(list) && apd(element, list);
171
75
  }
172
76
  }
77
+
173
78
  function apd(element, c) {
174
- if ($isThenable(c)) {
175
- c.then((r) => apd(element, r));
176
- }
177
- else if ($isArray(c)) {
178
- for (let i = 0; i < c.length; i++) {
179
- // & might be thenable here too
180
- const ci = c[i];
181
- if ($isThenable(ci)) {
182
- const comment = document.createComment('ktjs-promise-placeholder');
183
- element.appendChild(comment);
184
- ci.then((awaited) => comment.replaceWith(awaited));
185
- }
186
- else {
187
- apdSingle(element, ci);
188
- }
189
- }
190
- }
191
- else {
192
- // & here is thened, so must be a simple elementj
193
- apdSingle(element, c);
194
- }
79
+ if ($isThenable(c)) c.then(r => apd(element, r)); else if ($isArray(c)) for (let i = 0; i < c.length; i++) {
80
+ const ci = c[i];
81
+ if ($isThenable(ci)) {
82
+ const comment = document.createComment("ktjs-promise-placeholder");
83
+ element.appendChild(comment), ci.then(awaited => comment.replaceWith(awaited));
84
+ } else apdSingle(element, ci);
85
+ } else apdSingle(element, c);
195
86
  }
87
+
196
88
  function applyContent(element, content) {
197
- if ($isArray(content)) {
198
- for (let i = 0; i < content.length; i++) {
199
- apd(element, content[i]);
200
- }
201
- }
202
- else {
203
- apd(element, content);
204
- }
89
+ if ($isArray(content)) for (let i = 0; i < content.length; i++) apd(element, content[i]); else apd(element, content);
205
90
  }
206
91
 
207
- // # internal methods that cannot be placed in @ktjs/shared
208
92
  const IdGenerator = {
209
93
  _refOnChangeId: 1,
210
94
  get refOnChangeId() {
211
95
  return this._refOnChangeId++;
212
- }};
96
+ }
97
+ };
213
98
 
214
99
  class KTReactive {
215
- /**
216
- * Indicates that this is a KTRef instance
217
- */
218
- isKT = true;
219
- ktType = 1 /* KTReactiveType.Reative */;
220
- /**
221
- * @internal
222
- */
100
+ isKT=!0;
101
+ ktType=1;
223
102
  _value;
224
- /**
225
- * @internal
226
- */
227
- _changeHandlers = new Map();
228
- /**
229
- * @internal
230
- */
103
+ _changeHandlers=new Map;
231
104
  _emit(newValue, oldValue, handlerKeys) {
232
105
  if (handlerKeys) {
233
- for (let i = 0; i < handlerKeys.length; i++) {
234
- this._changeHandlers.get(handlerKeys[i])?.(newValue, oldValue);
235
- }
106
+ for (let i = 0; i < handlerKeys.length; i++) this._changeHandlers.get(handlerKeys[i])?.(newValue, oldValue);
236
107
  return this;
237
108
  }
238
- this._changeHandlers.forEach((c) => c(newValue, oldValue));
239
- return this;
109
+ return this._changeHandlers.forEach(c => c(newValue, oldValue)), this;
240
110
  }
241
111
  constructor(_value) {
242
- this._value = _value;
243
- this._changeHandlers = new Map();
112
+ this._value = _value, this._changeHandlers = new Map;
244
113
  }
245
- /**
246
- * If new value and old value are both nodes, the old one will be replaced in the DOM
247
- * - Use `.mutable` to modify the value.
248
- * @readonly
249
- */
250
114
  get value() {
251
115
  return this._value;
252
116
  }
253
- set value(_newValue) {
254
- // Only allow KTRef to be set.
255
- }
256
- /**
257
- * Force all listeners to run even when reference identity has not changed.
258
- * Useful for in-place array/object mutations.
259
- * - Is implemented differently in `KTRef` and `KTComputed`
260
- */
261
- notify(..._args) {
262
- throw new Error('This is meant to be override in ref.ts and computed.ts');
117
+ set value(_newValue) {}
118
+ notify(handlerKeys) {
119
+ return this._emit(this._value, this._value, handlerKeys);
263
120
  }
264
121
  map(..._args) {
265
- throw new Error('This is meant to be override in computed.ts');
122
+ throw new Error("This is meant to be override in computed.ts");
266
123
  }
267
- /**
268
- * Register a callback when the value changes
269
- * @param callback newValue and oldValue are references. You can use `a.draft` to make in-place mutations since `a.value` will not trigger `onChange` handers.
270
- * @param key Optional key to identify the callback, allowing multiple listeners on the same ref and individual removal. If not provided, a unique ID will be generated.
271
- */
272
- // todo 链式调用addOnChange改造
273
124
  addOnChange(callback, key) {
274
- if (typeof callback !== 'function') {
275
- throw new Error('[@ktjs/core error] KTRef.addOnChange: callback must be a function');
276
- }
125
+ if ("function" != typeof callback) throw new Error("[@ktjs/core error] KTRef.addOnChange: callback must be a function");
277
126
  const k = key ?? IdGenerator.refOnChangeId;
278
- this._changeHandlers.set(k, callback);
279
- return this;
127
+ return this._changeHandlers.set(k, callback), this;
280
128
  }
281
129
  removeOnChange(key) {
282
130
  const callback = this._changeHandlers.get(key);
283
- this._changeHandlers.delete(key);
284
- return callback;
131
+ return this._changeHandlers.delete(key), callback;
285
132
  }
286
133
  }
287
134
 
288
- // Use microqueue to schedule the flush of pending reactions
289
- const reactiveToOldValue = new Map();
290
- let scheduled = false;
291
- const markMutation = (reactive) => {
292
- if (!reactiveToOldValue.has(reactive)) {
293
- // @ts-expect-error accessing protected property
294
- reactiveToOldValue.set(reactive, reactive._value);
295
- // # schedule by microqueue
296
- if (scheduled) {
297
- return;
298
- }
299
- scheduled = true;
300
- Promise.resolve().then(() => {
301
- scheduled = false;
302
- reactiveToOldValue.forEach((oldValue, reactive) => {
303
- // @ts-expect-error accessing protected property
304
- reactive._changeHandlers.forEach((handler) => handler(reactive.value, oldValue));
305
- });
306
- reactiveToOldValue.clear();
307
- });
308
- }
309
- };
135
+ const reactiveToOldValue = new Map;
136
+
137
+ let scheduled = !1;
310
138
 
311
139
  class KTRef extends KTReactive {
312
- ktType = 3 /* KTReactiveType.Ref */;
313
- // ! Cannot be omitted, otherwise this will override `KTReactive` with only setter. And getter will return undefined.
140
+ ktType=3;
314
141
  get value() {
315
142
  return this._value;
316
143
  }
317
144
  set value(newValue) {
318
- if ($is(newValue, this._value)) {
319
- return;
320
- }
145
+ if ($is(newValue, this._value)) return;
321
146
  const oldValue = this._value;
322
- this._value = newValue;
323
- this._emit(newValue, oldValue);
147
+ this._value = newValue, this._emit(newValue, oldValue);
324
148
  }
325
- // todo 编译器要对这个属性的逃逸(也就是什么都没改或者被赋值)进行检测,比如const a = xxx.draft.
326
149
  get draft() {
327
- markMutation(this);
328
- return this._value;
329
- }
330
- /**
331
- * Force all listeners to run even when reference identity has not changed.
332
- */
333
- notify(oldValue = this._value, newValue = this._value, handlerKeys) {
334
- return this._emit(newValue, oldValue, handlerKeys);
150
+ return (reactive => {
151
+ if (!reactiveToOldValue.has(reactive)) {
152
+ if (reactiveToOldValue.set(reactive, reactive._value), scheduled) return;
153
+ scheduled = !0, Promise.resolve().then(() => {
154
+ scheduled = !1, reactiveToOldValue.forEach((oldValue, reactive) => {
155
+ reactive._changeHandlers.forEach(handler => handler(reactive.value, oldValue));
156
+ }), reactiveToOldValue.clear();
157
+ });
158
+ }
159
+ })(this), this._value;
335
160
  }
336
161
  }
337
- /**
338
- * Create a `KTRef` object.
339
- * - use `refObject.state` to get plain data
340
- * - use `refObject.map(calculator)` to create a computed value based on this ref
341
- * - use `refObject.mutable` to set too, but it will recalculate in the next microtask. Useful for deep objects, `Map`, `Set` or other custom objects
342
- *
343
- * @param value any data
344
- * @param onChange event handler triggered when the value changes, with signature `(newValue, oldValue) => void`
345
- * @returns
346
- */
347
- const ref = (value) => new KTRef(value);
348
- /**
349
- * Assert k-model to be a ref object
350
- */
351
- const $modelOrRef = (props, defaultValue) => {
352
- // & props is an object. Won't use it in any other place
353
- if ('k-model' in props) {
354
- const kmodel = props['k-model'];
355
- if (isRef(kmodel)) {
356
- return kmodel;
357
- }
358
- else {
359
- throw new Error(`[@ktjs/core error] k-model data must be a KTRef object, please use 'ref(...)' to wrap it.`);
360
- }
162
+
163
+ const ref = value => new KTRef(value), $modelOrRef = (props, defaultValue) => {
164
+ if ("k-model" in props) {
165
+ const kmodel = props["k-model"];
166
+ if (isRef(kmodel)) return kmodel;
167
+ throw new Error("[@ktjs/core error] k-model data must be a KTRef object, please use 'ref(...)' to wrap it.");
361
168
  }
362
169
  return ref(defaultValue);
363
- };
364
- const $refSetter = (props, node) => (props.ref.value = node);
365
- /**
366
- * Whether `props.ref` is a `KTRef` only needs to be checked in the initial render
367
- */
368
- const $initRef = (props, node) => {
369
- if (!('ref' in props)) {
370
- return $emptyFn;
371
- }
170
+ }, $refSetter = (props, node) => props.ref.value = node, $initRef = (props, node) => {
171
+ if (!("ref" in props)) return $emptyFn;
372
172
  const r = props.ref;
373
- if (isRef(r)) {
374
- r.value = node;
375
- return $refSetter;
376
- }
377
- else {
378
- throw new Error('[@ktjs/core error] Fragment: ref must be a KTRef');
379
- }
173
+ if (isRef(r)) return r.value = node, $refSetter;
174
+ throw new Error("[@ktjs/core error] Fragment: ref must be a KTRef");
380
175
  };
381
176
 
382
177
  class KTComputed extends KTReactive {
383
- ktType = 2 /* KTReactiveType.Computed */;
384
- /**
385
- * @internal
386
- */
178
+ ktType=2;
387
179
  _calculator;
388
- /**
389
- * @internal
390
- */
391
- _recalculate(forceEmit = false, handlerKeys) {
392
- const oldValue = this._value;
393
- const newValue = this._calculator();
394
- if (oldValue === newValue) {
395
- if (forceEmit) {
396
- this._emit(newValue, oldValue, handlerKeys);
397
- }
398
- return this;
399
- }
400
- this._value = newValue;
401
- this._emit(newValue, oldValue, handlerKeys);
402
- return this;
180
+ _recalculate(forceEmit = !1, handlerKeys) {
181
+ const oldValue = this._value, newValue = this._calculator();
182
+ return oldValue === newValue ? (forceEmit && this._emit(newValue, oldValue, handlerKeys),
183
+ this) : (this._value = newValue, this._emit(newValue, oldValue, handlerKeys), this);
403
184
  }
404
- // todo 侦听的dependency数量比较多的,纳入scheduler
405
185
  constructor(_calculator, dependencies) {
406
- super(_calculator());
407
- this._calculator = _calculator;
408
- for (let i = 0; i < dependencies.length; i++) {
409
- dependencies[i].addOnChange(() => this._recalculate());
410
- }
186
+ super(_calculator()), this._calculator = _calculator;
187
+ for (let i = 0; i < dependencies.length; i++) dependencies[i].addOnChange(() => this._recalculate());
411
188
  }
412
- /**
413
- * If new value and old value are both nodes, the old one will be replaced in the DOM
414
- */
415
189
  get value() {
416
190
  return this._value;
417
191
  }
418
192
  set value(_newValue) {
419
- console.warn('[@ktjs/core warn]',`'value' of Computed are read-only.`);
193
+ console.warn("[@ktjs/core warn]", "'value' of Computed are read-only.");
420
194
  }
421
- /**
422
- * Force listeners to run once with the latest computed result.
423
- */
424
195
  notify(handlerKeys) {
425
- return this._recalculate(true, handlerKeys);
196
+ return this._recalculate(!0, handlerKeys);
426
197
  }
427
198
  }
428
- KTReactive.prototype.map = function (calculator, dependencies) {
429
- return new KTComputed(() => calculator(this._value), dependencies ? [this, ...dependencies] : [this]);
430
- };
431
- /**
432
- * Create a reactive computed value
433
- * @param computeFn
434
- * @param dependencies refs and computeds that this computed depends on
435
- */
199
+
436
200
  function computed(computeFn, dependencies) {
437
- if (dependencies.some((v) => !isKT(v))) {
438
- throw new Error('[@ktjs/core error] computed: all reactives must be KTRef or KTComputed instances');
439
- }
201
+ if (dependencies.some(v => !isKT(v))) throw new Error("[@ktjs/core error] computed: all reactives must be KTRef or KTComputed instances");
440
202
  return new KTComputed(computeFn, dependencies);
441
203
  }
442
204
 
443
- /**
444
- * Register a reactive effect with options.
445
- * @param effectFn The effect function to run when dependencies change
446
- * @param reactives The reactive dependencies
447
- * @param options Effect options: lazy, onCleanup, debugName
448
- * @returns stop function to remove all listeners
449
- */
450
205
  function effect(effectFn, reactives, options) {
451
- const { lazy = false, onCleanup = $emptyFn, debugName = '' } = Object(options);
452
- const listenerKeys = [];
453
- let active = true;
206
+ const {lazy: lazy = !1, onCleanup: onCleanup = $emptyFn, debugName: debugName = ""} = Object(options), listenerKeys = [];
207
+ let active = !0;
454
208
  const run = () => {
455
- if (!active) {
456
- return;
457
- }
458
- // cleanup before rerun
459
- onCleanup();
460
- try {
461
- effectFn();
462
- }
463
- catch (err) {
464
- console.debug('[@ktjs/core debug]','effect error:', debugName, err);
209
+ if (active) {
210
+ onCleanup();
211
+ try {
212
+ effectFn();
213
+ } catch (err) {
214
+ console.debug("[@ktjs/core debug]", "effect error:", debugName, err);
215
+ }
465
216
  }
466
217
  };
467
- // subscribe to dependencies
468
- for (let i = 0; i < reactives.length; i++) {
469
- listenerKeys[i] = i;
470
- reactives[i].addOnChange(run, i);
471
- }
472
- // auto run unless lazy
473
- if (!lazy) {
474
- run();
475
- }
476
- // stop function
477
- return () => {
478
- if (!active) {
479
- return;
480
- }
481
- active = false;
482
- for (let i = 0; i < reactives.length; i++) {
483
- reactives[i].removeOnChange(listenerKeys[i]);
218
+ for (let i = 0; i < reactives.length; i++) listenerKeys[i] = i, reactives[i].addOnChange(run, i);
219
+ return lazy || run(), () => {
220
+ if (active) {
221
+ active = !1;
222
+ for (let i = 0; i < reactives.length; i++) reactives[i].removeOnChange(listenerKeys[i]);
223
+ onCleanup();
484
224
  }
485
- // final cleanup
486
- onCleanup();
487
225
  };
488
226
  }
489
227
 
490
- /**
491
- *
492
- * @param value
493
- * @returns
494
- */
495
- const toReactive = (value) => isKT(value) ? value : ref(value);
496
- /**
497
- * Extracts the value from a KTReactive, or returns the value directly if it's not reactive.
498
- */
228
+ KTReactive.prototype.map = function(calculator, dependencies) {
229
+ return new KTComputed(() => calculator(this._value), dependencies ? [ this, ...dependencies ] : [ this ]);
230
+ };
231
+
232
+ const toReactive = value => isKT(value) ? value : ref(value);
233
+
499
234
  function dereactive(value) {
500
235
  return isKT(value) ? value.value : value;
501
236
  }
502
237
 
503
238
  function applyKModel(element, valueRef) {
504
- if (!isKT(valueRef)) {
505
- throw new Error('[@ktjs/core error] k-model value must be a KTRef.');
506
- }
507
- if (element.tagName === 'INPUT') {
508
- if (element.type === 'radio' || element.type === 'checkbox') {
509
- $applyModel(element, valueRef, 'checked', 'change');
510
- return;
511
- }
512
- if (element.type === 'number') {
513
- $applyModel(element, valueRef, 'checked', 'change', Number);
514
- return;
515
- }
516
- if (element.type === 'date') {
517
- $applyModel(element, valueRef, 'checked', 'change', (v) => new Date(v));
518
- return;
519
- }
520
- $applyModel(element, valueRef, 'value', 'input');
521
- }
522
- else if (element.tagName === 'SELECT') {
523
- $applyModel(element, valueRef, 'value', 'change');
524
- }
525
- else if (element.tagName === 'TEXTAREA') {
526
- $applyModel(element, valueRef, 'value', 'input');
527
- }
528
- else {
529
- console.warn('[@ktjs/core warn]','not supported element for k-model:');
530
- }
239
+ if (!isKT(valueRef)) throw new Error("[@ktjs/core error] k-model value must be a KTRef.");
240
+ if ("INPUT" === element.tagName) {
241
+ if ("radio" === element.type || "checkbox" === element.type) return void $applyModel(element, valueRef, "checked", "change");
242
+ if ("number" === element.type) return void $applyModel(element, valueRef, "checked", "change", Number);
243
+ if ("date" === element.type) return void $applyModel(element, valueRef, "checked", "change", v => new Date(v));
244
+ $applyModel(element, valueRef, "value", "input");
245
+ } else "SELECT" === element.tagName ? $applyModel(element, valueRef, "value", "change") : "TEXTAREA" === element.tagName ? $applyModel(element, valueRef, "value", "input") : console.warn("[@ktjs/core warn]", "not supported element for k-model:");
531
246
  }
532
247
 
533
248
  /**
@@ -540,470 +255,226 @@ function applyKModel(element, valueRef) {
540
255
  * ## About
541
256
  * @package @ktjs/core
542
257
  * @author Kasukabe Tsumugi <futami16237@gmail.com>
543
- * @version 0.33.0 (Last Update: 2026.03.21 22:19:51.700)
258
+ * @version 0.33.2 (Last Update: 2026.03.22 00:10:18.944)
544
259
  * @license MIT
545
260
  * @link https://github.com/baendlorel/kt.js
546
261
  * @link https://baendlorel.github.io/ Welcome to my site!
547
262
  * @description Core functionality for kt.js - DOM manipulation utilities with JSX/TSX support
548
263
  * @copyright Copyright (c) 2026 Kasukabe Tsumugi. All rights reserved.
549
- */
550
- const h = (tag, attr, content) => {
551
- if (typeof tag !== 'string') {
552
- throw new Error('[@ktjs/core error] tagName must be a string.');
553
- }
554
- // * start creating the element
264
+ */ const h = (tag, attr, content) => {
265
+ if ("string" != typeof tag) throw new Error("[@ktjs/core error] tagName must be a string.");
555
266
  const element = document.createElement(tag);
556
- if (typeof attr === 'object' && attr !== null && 'k-model' in attr) {
557
- applyKModel(element, attr['k-model']);
558
- }
559
- // * Handle content
560
- applyAttr(element, attr);
561
- applyContent(element, content);
562
- return element;
563
- };
564
- const svg$1 = (tag, attr, content) => {
565
- if (typeof tag !== 'string') {
566
- throw new Error('[@ktjs/core error] tagName must be a string.');
567
- }
568
- // * start creating the element
569
- const element = document.createElementNS('http://www.w3.org/2000/svg', tag);
570
- // * Handle content
571
- applyAttr(element, attr);
572
- applyContent(element, content);
573
- if (typeof attr === 'object' && attr !== null && 'k-model' in attr) {
574
- applyKModel(element, attr['k-model']);
575
- }
576
- return element;
577
- };
578
- const mathml$1 = (tag, attr, content) => {
579
- if (typeof tag !== 'string') {
580
- throw new Error('[@ktjs/core error] tagName must be a string.');
581
- }
582
- // * start creating the element
583
- const element = document.createElementNS('http://www.w3.org/1998/Math/MathML', tag);
584
- // * Handle content
585
- applyAttr(element, attr);
586
- applyContent(element, content);
587
- if (typeof attr === 'object' && attr !== null && 'k-model' in attr) {
588
- applyKModel(element, attr['k-model']);
589
- }
590
- return element;
267
+ return "object" == typeof attr && null !== attr && "k-model" in attr && applyKModel(element, attr["k-model"]),
268
+ applyAttr(element, attr), applyContent(element, content), element;
269
+ }, svg$1 = (tag, attr, content) => {
270
+ if ("string" != typeof tag) throw new Error("[@ktjs/core error] tagName must be a string.");
271
+ const element = document.createElementNS("http://www.w3.org/2000/svg", tag);
272
+ return applyAttr(element, attr), applyContent(element, content), "object" == typeof attr && null !== attr && "k-model" in attr && applyKModel(element, attr["k-model"]),
273
+ element;
274
+ }, mathml$1 = (tag, attr, content) => {
275
+ if ("string" != typeof tag) throw new Error("[@ktjs/core error] tagName must be a string.");
276
+ const element = document.createElementNS("http://www.w3.org/1998/Math/MathML", tag);
277
+ return applyAttr(element, attr), applyContent(element, content), "object" == typeof attr && null !== attr && "k-model" in attr && applyKModel(element, attr["k-model"]),
278
+ element;
591
279
  };
592
280
 
593
- const FRAGMENT_MOUNT_PATCHED = '__kt_fragment_mount_patched__';
594
- const FRAGMENT_MOUNT = '__kt_fragment_mount__';
595
- if (typeof Node !== 'undefined' && !globalThis[FRAGMENT_MOUNT_PATCHED]) {
596
- globalThis[FRAGMENT_MOUNT_PATCHED] = true;
281
+ if ("undefined" != typeof Node && !globalThis.__kt_fragment_mount_patched__) {
282
+ globalThis.__kt_fragment_mount_patched__ = !0;
597
283
  const originAppendChild = Node.prototype.appendChild;
598
- Node.prototype.appendChild = function (node) {
599
- const result = originAppendChild.call(this, node);
600
- const mount = node[FRAGMENT_MOUNT];
601
- if (typeof mount === 'function') {
602
- mount();
603
- }
604
- return result;
284
+ Node.prototype.appendChild = function(node) {
285
+ const result = originAppendChild.call(this, node), mount = node.__kt_fragment_mount__;
286
+ return "function" == typeof mount && mount(), result;
605
287
  };
606
288
  const originInsertBefore = Node.prototype.insertBefore;
607
- Node.prototype.insertBefore = function (node, child) {
608
- const result = originInsertBefore.call(this, node, child);
609
- const mount = node[FRAGMENT_MOUNT];
610
- if (typeof mount === 'function') {
611
- mount();
612
- }
613
- return result;
289
+ Node.prototype.insertBefore = function(node, child) {
290
+ const result = originInsertBefore.call(this, node, child), mount = node.__kt_fragment_mount__;
291
+ return "function" == typeof mount && mount(), result;
614
292
  };
615
293
  }
616
- /**
617
- * Fragment - Container component for managing arrays of child elements
618
- *
619
- * Features:
620
- * 1. Returns a comment anchor node, child elements are inserted after the anchor
621
- * 2. Supports reactive arrays, automatically updates DOM when array changes
622
- * 3. Basic version uses simple replacement algorithm (remove all old elements, insert all new elements)
623
- * 4. Future enhancement: key-based optimization
624
- *
625
- * Usage example:
626
- * ```tsx
627
- * const children = ref([<div>A</div>, <div>B</div>]);
628
- * const fragment = <Fragment children={children} />;
629
- * document.body.appendChild(fragment);
630
- *
631
- * // Automatic update
632
- * children.value = [<div>C</div>, <div>D</div>];
633
- * ```
634
- */
635
- function Fragment$1(props) {
636
- const elements = [];
637
- const anchor = document.createComment('kt-fragment');
638
- let inserted = false;
639
- let observer;
640
- const redraw = () => {
641
- const newElements = childrenRef.value;
642
- const parent = anchor.parentNode;
643
- if (!parent) {
644
- elements.length = 0;
645
- for (let i = 0; i < newElements.length; i++) {
646
- elements.push(newElements[i]);
647
- }
648
- anchor.__kt_fragment_list__ = elements;
649
- return;
650
- }
651
- for (let i = 0; i < elements.length; i++) {
652
- elements[i].remove();
653
- }
654
- const fragment = document.createDocumentFragment();
655
- elements.length = 0;
656
- for (let i = 0; i < newElements.length; i++) {
657
- const element = newElements[i];
658
- elements.push(element);
659
- fragment.appendChild(element);
660
- }
661
- parent.insertBefore(fragment, anchor.nextSibling);
662
- inserted = true;
663
- delete anchor[FRAGMENT_MOUNT];
664
- observer?.disconnect();
665
- observer = undefined;
666
- anchor.__kt_fragment_list__ = elements;
667
- };
668
- const childrenRef = toReactive(props.children).addOnChange(redraw);
669
- const renderInitial = () => {
670
- const current = childrenRef.value;
671
- elements.length = 0;
672
- const fragment = document.createDocumentFragment();
673
- for (let i = 0; i < current.length; i++) {
674
- const element = current[i];
675
- elements.push(element);
676
- fragment.appendChild(element);
677
- }
678
- anchor.__kt_fragment_list__ = elements;
679
- const parent = anchor.parentNode;
680
- if (parent && !inserted) {
681
- parent.insertBefore(fragment, anchor.nextSibling);
682
- inserted = true;
683
- }
684
- };
685
- renderInitial();
686
- anchor[FRAGMENT_MOUNT] = () => {
687
- if (!inserted && anchor.parentNode) {
688
- redraw();
689
- }
690
- };
691
- observer = new MutationObserver(() => {
692
- if (anchor.parentNode && !inserted) {
693
- redraw();
694
- observer?.disconnect();
695
- observer = undefined;
696
- }
697
- });
698
- observer.observe(document.body, { childList: true, subtree: true });
699
- $initRef(props, anchor);
700
- return anchor;
701
- }
702
- /**
703
- * Convert KTRawContent to HTMLElement array
704
- */
705
- function convertChildrenToElements(children) {
706
- const elements = [];
707
- const processChild = (child) => {
708
- if (child === undefined || child === null || child === false || child === true) {
709
- // Ignore null, undefined, false, true
710
- return;
711
- }
712
- if ($isArray(child)) {
713
- // Recursively process array
714
- $forEach(child, processChild);
715
- return;
716
- }
717
- if (typeof child === 'string' || typeof child === 'number') {
718
- const span = document.createElement('span');
719
- span.textContent = String(child);
720
- elements.push(span);
721
- return;
722
- }
723
- if (child instanceof HTMLElement) {
724
- elements.push(child);
725
- return;
726
- }
727
- if (isKT(child)) {
728
- processChild(child.value);
729
- return;
730
- }
731
- console.warn('[@ktjs/core warn]','Fragment: unsupported child type', child);
732
- };
733
- processChild(children);
734
- return elements;
735
- }
736
294
 
737
- const jsxh = (tag, props) => (typeof tag === 'function' ? tag(props) : h(tag, props, props.children));
738
- const placeholder = (data) => document.createComment(data);
295
+ const jsxh = (tag, props) => "function" == typeof tag ? tag(props) : h(tag, props, props.children), placeholder = data => document.createComment(data);
739
296
 
740
297
  function create(creator, tag, props) {
741
- if (props.ref && isComputed(props.ref)) {
742
- throw new Error('[@ktjs/core error] Cannot assign a computed value to an element.');
743
- }
298
+ if (props.ref && isComputed(props.ref)) throw new Error("[@ktjs/core error] Cannot assign a computed value to an element.");
744
299
  const el = creator(tag, props, props.children);
745
- $initRef(props, el);
746
- return el;
300
+ return $initRef(props, el), el;
747
301
  }
748
- const jsx = (tag, props) => create(jsxh, tag, props);
749
- const svg = (tag, props) => create(svg$1, tag, props);
750
- const mathml = (tag, props) => create(mathml$1, tag, props);
751
- /**
752
- * Fragment support - returns an array of children
753
- * Enhanced Fragment component that manages arrays of elements
754
- */
302
+
303
+ const jsx = (tag, props) => create(jsxh, tag, props), svg = (tag, props) => create(svg$1, tag, props), mathml = (tag, props) => create(mathml$1, tag, props);
304
+
755
305
  function Fragment(props) {
756
- const { children } = props ?? {};
757
- if (!children) {
758
- return placeholder('kt-fragment-empty');
759
- }
760
- const elements = convertChildrenToElements(children);
761
- return Fragment$1({ children: elements });
306
+ const {children: children} = props ?? {};
307
+ if (!children) return placeholder("kt-fragment-empty");
308
+ const elements = function(children) {
309
+ const elements = [], processChild = child => {
310
+ if (null != child && !1 !== child && !0 !== child) if ($isArray(child)) $forEach(child, processChild); else {
311
+ if ("string" == typeof child || "number" == typeof child) {
312
+ const span = document.createElement("span");
313
+ return span.textContent = String(child), void elements.push(span);
314
+ }
315
+ if (child instanceof HTMLElement) elements.push(child); else {
316
+ if (!isKT(child)) throw console.warn("[@ktjs/core warn]", "Fragment: unsupported child type", child),
317
+ new Error("Fragment: unsupported child type");
318
+ processChild(child.value);
319
+ }
320
+ }
321
+ };
322
+ return processChild(children), elements;
323
+ }(children);
324
+ return function(props) {
325
+ const elements = [], anchor = document.createComment("kt-fragment");
326
+ let observer, inserted = !1;
327
+ const redraw = () => {
328
+ const newElements = childrenRef.value, parent = anchor.parentNode;
329
+ if (!parent) {
330
+ elements.length = 0;
331
+ for (let i = 0; i < newElements.length; i++) elements.push(newElements[i]);
332
+ return void (anchor.__kt_fragment_list__ = elements);
333
+ }
334
+ for (let i = 0; i < elements.length; i++) elements[i].remove();
335
+ const fragment = document.createDocumentFragment();
336
+ elements.length = 0;
337
+ for (let i = 0; i < newElements.length; i++) {
338
+ const element = newElements[i];
339
+ elements.push(element), fragment.appendChild(element);
340
+ }
341
+ parent.insertBefore(fragment, anchor.nextSibling), inserted = !0, delete anchor.__kt_fragment_mount__,
342
+ observer?.disconnect(), observer = void 0, anchor.__kt_fragment_list__ = elements;
343
+ }, childrenRef = toReactive(props.children).addOnChange(redraw);
344
+ return (() => {
345
+ const current = childrenRef.value;
346
+ elements.length = 0;
347
+ const fragment = document.createDocumentFragment();
348
+ for (let i = 0; i < current.length; i++) {
349
+ const element = current[i];
350
+ elements.push(element), fragment.appendChild(element);
351
+ }
352
+ anchor.__kt_fragment_list__ = elements;
353
+ const parent = anchor.parentNode;
354
+ parent && !inserted && (parent.insertBefore(fragment, anchor.nextSibling), inserted = !0);
355
+ })(), anchor.__kt_fragment_mount__ = () => {
356
+ !inserted && anchor.parentNode && redraw();
357
+ }, observer = new MutationObserver(() => {
358
+ anchor.parentNode && !inserted && (redraw(), observer?.disconnect(), observer = void 0);
359
+ }), observer.observe(document.body, {
360
+ childList: !0,
361
+ subtree: !0
362
+ }), $initRef(props, anchor), anchor;
363
+ }({
364
+ children: elements
365
+ });
762
366
  }
763
- /**
764
- * JSX Development runtime - same as jsx but with additional dev checks
765
- */
766
- const jsxDEV = (...args) => {
767
- // console.log('JSX DEV called:', ...args);
768
- // console.log('children', (args[1] as any)?.children);
769
- return jsx(...args);
770
- };
771
- /**
772
- * JSX runtime for React 17+ automatic runtime
773
- * This is called when using jsx: "react-jsx" or "react-jsxdev"
774
- */
775
- const jsxs = jsx;
367
+
368
+ const jsxDEV = (...args) => jsx(...args), jsxs = jsx;
776
369
 
777
370
  function KTAsync(props) {
778
371
  const raw = props.component(props);
779
- let comp = props.skeleton ?? document.createComment('ktjs-suspense-placeholder');
780
- if ($isThenable(raw)) {
781
- raw.then((resolved) => comp.replaceWith(resolved));
782
- }
783
- else {
784
- comp = raw;
785
- }
786
- return comp;
372
+ let comp = props.skeleton ?? document.createComment("ktjs-suspense-placeholder");
373
+ return $isThenable(raw) ? raw.then(resolved => comp.replaceWith(resolved)) : comp = raw,
374
+ comp;
787
375
  }
788
376
 
789
- // task 对于template标签的for和if,会编译为fragment,可特殊处理,让它们保持原样
790
- /**
791
- * KTFor - List rendering component with key-based optimization
792
- * Returns a Comment anchor node with rendered elements in __kt_for_list__
793
- */
794
377
  function KTFor(props) {
795
- const redraw = () => {
796
- const newList = listRef.value;
797
- const parent = anchor.parentNode;
378
+ const {key: currentKey = item => item, map: currentMap = $identity} = props, listRef = toReactive(props.list).addOnChange(() => {
379
+ const newList = listRef.value, parent = anchor.parentNode;
798
380
  if (!parent) {
799
- // If not in DOM yet, just rebuild the list
800
381
  const newElements = [];
801
382
  nodeMap.clear();
802
383
  for (let index = 0; index < newList.length; index++) {
803
- const item = newList[index];
804
- const itemKey = currentKey(item, index, newList);
805
- const node = currentMap(item, index, newList);
806
- nodeMap.set(itemKey, node);
807
- newElements.push(node);
384
+ const item = newList[index], itemKey = currentKey(item, index, newList), node = currentMap(item, index, newList);
385
+ nodeMap.set(itemKey, node), newElements.push(node);
808
386
  }
809
- anchor.__kt_for_list__ = newElements;
810
- return anchor;
811
- }
812
- const oldLength = anchor.__kt_for_list__.length;
813
- const newLength = newList.length;
814
- // Fast path: empty list
815
- if (newLength === 0) {
816
- nodeMap.forEach((node) => node.remove());
817
- nodeMap.clear();
818
- anchor.__kt_for_list__ = [];
819
- return anchor;
387
+ return anchor.__kt_for_list__ = newElements, anchor;
820
388
  }
821
- // Fast path: all new items
822
- if (oldLength === 0) {
823
- const newElements = [];
824
- const fragment = document.createDocumentFragment();
389
+ const oldLength = anchor.__kt_for_list__.length, newLength = newList.length;
390
+ if (0 === newLength) return nodeMap.forEach(node => node.remove()), nodeMap.clear(),
391
+ anchor.__kt_for_list__ = [], anchor;
392
+ if (0 === oldLength) {
393
+ const newElements = [], fragment = document.createDocumentFragment();
825
394
  for (let i = 0; i < newLength; i++) {
826
- const item = newList[i];
827
- const itemKey = currentKey(item, i, newList);
828
- const node = currentMap(item, i, newList);
829
- nodeMap.set(itemKey, node);
830
- newElements.push(node);
831
- fragment.appendChild(node);
395
+ const item = newList[i], itemKey = currentKey(item, i, newList), node = currentMap(item, i, newList);
396
+ nodeMap.set(itemKey, node), newElements.push(node), fragment.appendChild(node);
832
397
  }
833
- parent.insertBefore(fragment, anchor.nextSibling);
834
- anchor.__kt_for_list__ = newElements;
835
- return anchor;
398
+ return parent.insertBefore(fragment, anchor.nextSibling), anchor.__kt_for_list__ = newElements,
399
+ anchor;
836
400
  }
837
- // Build key index map and new elements array in one pass
838
- const newKeyToNewIndex = new Map();
839
- const newElements = new Array(newLength);
840
- let maxNewIndexSoFar = 0;
841
- let moved = false;
401
+ const newKeyToNewIndex = new Map, newElements = new Array(newLength);
402
+ let maxNewIndexSoFar = 0, moved = !1;
842
403
  for (let i = 0; i < newLength; i++) {
843
- const item = newList[i];
844
- const itemKey = currentKey(item, i, newList);
845
- newKeyToNewIndex.set(itemKey, i);
846
- if (nodeMap.has(itemKey)) {
847
- // Reuse existing node
404
+ const item = newList[i], itemKey = currentKey(item, i, newList);
405
+ if (newKeyToNewIndex.set(itemKey, i), nodeMap.has(itemKey)) {
848
406
  const node = nodeMap.get(itemKey);
849
- newElements[i] = node;
850
- // Track if items moved
851
- if (i < maxNewIndexSoFar) {
852
- moved = true;
853
- }
854
- else {
855
- maxNewIndexSoFar = i;
856
- }
857
- }
858
- else {
859
- // Create new node
860
- newElements[i] = currentMap(item, i, newList);
861
- }
407
+ newElements[i] = node, i < maxNewIndexSoFar ? moved = !0 : maxNewIndexSoFar = i;
408
+ } else newElements[i] = currentMap(item, i, newList);
862
409
  }
863
- // Remove nodes not in new list
864
410
  const toRemove = [];
865
411
  nodeMap.forEach((node, key) => {
866
- if (!newKeyToNewIndex.has(key)) {
867
- toRemove.push(node);
868
- }
412
+ newKeyToNewIndex.has(key) || toRemove.push(node);
869
413
  });
870
- for (let i = 0; i < toRemove.length; i++) {
871
- toRemove[i].remove();
872
- }
873
- // Update DOM with minimal operations
414
+ for (let i = 0; i < toRemove.length; i++) toRemove[i].remove();
874
415
  if (moved) {
875
- // Use longest increasing subsequence to minimize moves
876
- const seq = getSequence(newElements.map((el, i) => (nodeMap.has(currentKey(newList[i], i, newList)) ? i : -1)));
877
- let j = seq.length - 1;
878
- let anchor = null;
879
- // Traverse from end to start for stable insertions
880
- for (let i = newLength - 1; i >= 0; i--) {
881
- const node = newElements[i];
882
- if (j < 0 || i !== seq[j]) {
883
- // Node needs to be moved or inserted
884
- if (anchor) {
885
- parent.insertBefore(node, anchor);
886
- }
887
- else {
888
- // Insert at end
889
- let temp = anchor.nextSibling; // ?? 这里难道不是null?
890
- while (temp && newElements.includes(temp)) {
891
- temp = temp.nextSibling;
892
- }
893
- parent.insertBefore(node, temp);
416
+ const seq = function(arr) {
417
+ const p = arr.slice(), result = [ 0 ];
418
+ let i, j, u, v, c;
419
+ const len = arr.length;
420
+ for (i = 0; i < len; i++) {
421
+ const arrI = arr[i];
422
+ if (-1 !== arrI) if (j = result[result.length - 1], arr[j] < arrI) p[i] = j, result.push(i); else {
423
+ for (u = 0, v = result.length - 1; u < v; ) c = (u + v) / 2 | 0, arr[result[c]] < arrI ? u = c + 1 : v = c;
424
+ arrI < arr[result[u]] && (u > 0 && (p[i] = result[u - 1]), result[u] = i);
894
425
  }
895
426
  }
896
- else {
897
- j--;
898
- }
427
+ u = result.length, v = result[u - 1];
428
+ for (;u-- > 0; ) result[u] = v, v = p[v];
429
+ return result;
430
+ }(newElements.map((el, i) => nodeMap.has(currentKey(newList[i], i, newList)) ? i : -1));
431
+ let j = seq.length - 1, anchor = null;
432
+ for (let i = newLength - 1; i >= 0; i--) {
433
+ const node = newElements[i];
434
+ if (j < 0 || i !== seq[j]) if (anchor) parent.insertBefore(node, anchor); else {
435
+ let temp = anchor.nextSibling;
436
+ for (;temp && newElements.includes(temp); ) temp = temp.nextSibling;
437
+ parent.insertBefore(node, temp);
438
+ } else j--;
899
439
  anchor = node;
900
440
  }
901
- }
902
- else {
903
- // No moves needed, just insert new nodes
441
+ } else {
904
442
  let currentNode = anchor.nextSibling;
905
443
  for (let i = 0; i < newLength; i++) {
906
444
  const node = newElements[i];
907
- if (currentNode !== node) {
908
- parent.insertBefore(node, currentNode);
909
- }
910
- else {
911
- currentNode = currentNode.nextSibling;
912
- }
445
+ currentNode !== node ? parent.insertBefore(node, currentNode) : currentNode = currentNode.nextSibling;
913
446
  }
914
447
  }
915
- // Update maps
916
448
  nodeMap.clear();
917
449
  for (let i = 0; i < newLength; i++) {
918
450
  const itemKey = currentKey(newList[i], i, newList);
919
451
  nodeMap.set(itemKey, newElements[i]);
920
452
  }
921
- anchor.__kt_for_list__ = newElements;
922
- return anchor;
923
- };
924
- const { key: currentKey = (item) => item, map: currentMap = $identity } = props;
925
- const listRef = toReactive(props.list).addOnChange(redraw);
926
- const anchor = document.createComment('kt-for');
927
- // Map to track rendered nodes by key
928
- const nodeMap = new Map();
929
- // Render initial list
930
- const elements = [];
453
+ return anchor.__kt_for_list__ = newElements, anchor;
454
+ }), anchor = document.createComment("kt-for"), nodeMap = new Map, elements = [];
931
455
  for (let index = 0; index < listRef.value.length; index++) {
932
- const item = listRef.value[index];
933
- const itemKey = currentKey(item, index, listRef.value);
934
- const node = currentMap(item, index, listRef.value);
935
- nodeMap.set(itemKey, node);
936
- elements.push(node);
456
+ const item = listRef.value[index], itemKey = currentKey(item, index, listRef.value), node = currentMap(item, index, listRef.value);
457
+ nodeMap.set(itemKey, node), elements.push(node);
937
458
  }
938
- anchor.__kt_for_list__ = elements;
939
- $initRef(props, anchor);
940
- return anchor;
941
- }
942
- // Longest Increasing Subsequence algorithm (optimized for diff)
943
- function getSequence(arr) {
944
- const p = arr.slice();
945
- const result = [0];
946
- let i, j, u, v, c;
947
- const len = arr.length;
948
- for (i = 0; i < len; i++) {
949
- const arrI = arr[i];
950
- if (arrI === -1)
951
- continue;
952
- j = result[result.length - 1];
953
- if (arr[j] < arrI) {
954
- p[i] = j;
955
- result.push(i);
956
- continue;
957
- }
958
- u = 0;
959
- v = result.length - 1;
960
- while (u < v) {
961
- c = ((u + v) / 2) | 0;
962
- if (arr[result[c]] < arrI) {
963
- u = c + 1;
964
- }
965
- else {
966
- v = c;
967
- }
968
- }
969
- if (arrI < arr[result[u]]) {
970
- if (u > 0) {
971
- p[i] = result[u - 1];
972
- }
973
- result[u] = i;
974
- }
975
- }
976
- u = result.length;
977
- v = result[u - 1];
978
- while (u-- > 0) {
979
- result[u] = v;
980
- v = p[v];
981
- }
982
- return result;
459
+ return anchor.__kt_for_list__ = elements, $initRef(props, anchor), anchor;
983
460
  }
984
461
 
985
462
  function KTConditional(condition, tagIf, propsIf, tagElse, propsElse) {
986
- if (!isKT(condition)) {
987
- return condition ? jsxh(tagIf, propsIf) : tagElse ? jsxh(tagElse, propsElse) : placeholder('kt-conditional');
988
- }
463
+ if (!isKT(condition)) return condition ? jsxh(tagIf, propsIf) : tagElse ? jsxh(tagElse, propsElse) : placeholder("kt-conditional");
989
464
  if (tagElse) {
990
465
  let current = condition.value ? jsxh(tagIf, propsIf) : jsxh(tagElse, propsElse);
991
- condition.addOnChange((newValue) => {
466
+ return condition.addOnChange(newValue => {
992
467
  const old = current;
993
- current = newValue ? jsxh(tagIf, propsIf) : jsxh(tagElse, propsElse);
994
- old.replaceWith(current);
995
- });
996
- return current;
468
+ current = newValue ? jsxh(tagIf, propsIf) : jsxh(tagElse, propsElse), old.replaceWith(current);
469
+ }), current;
997
470
  }
998
- else {
999
- const dummy = placeholder('kt-conditional');
471
+ {
472
+ const dummy = placeholder("kt-conditional");
1000
473
  let current = condition.value ? jsxh(tagIf, propsIf) : dummy;
1001
- condition.addOnChange((newValue) => {
474
+ return condition.addOnChange(newValue => {
1002
475
  const old = current;
1003
- current = newValue ? jsxh(tagIf, propsIf) : dummy;
1004
- old.replaceWith(current);
1005
- });
1006
- return current;
476
+ current = newValue ? jsxh(tagIf, propsIf) : dummy, old.replaceWith(current);
477
+ }), current;
1007
478
  }
1008
479
  }
1009
480