ks-fwork 3.0.0 → 3.0.1

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.
Files changed (2) hide show
  1. package/dist/ks-fwork.js +725 -0
  2. package/package.json +4 -3
@@ -0,0 +1,725 @@
1
+ function addEventListeners(listeners = {}, el, hostComponent = null) {
2
+ const addedListeners = {};
3
+ Object.entries(listeners).forEach(([eventName, handler]) => {
4
+ addedListeners[eventName] = addEventListener(eventName, handler, el, hostComponent);
5
+ });
6
+ return addedListeners;
7
+ }
8
+ function addEventListener(eventName, handler, el, hostComponent = null) {
9
+ function boundHandler() {
10
+ hostComponent ? handler.apply(hostComponent, arguments) : handler(...arguments);
11
+ }
12
+ el.addEventListener(eventName, boundHandler);
13
+ return boundHandler;
14
+ }
15
+ function removeEventListeners(listeners = {}, el) {
16
+ Object.entries(listeners).forEach(([eventName, handler]) => {
17
+ el.removeEventListener(eventName, handler);
18
+ });
19
+ }
20
+
21
+ function withoutNulls(arr) {
22
+ return arr.filter((item) => item != null);
23
+ }
24
+ function arraysDiff(oldArray, newArray) {
25
+ return {
26
+ added: newArray.filter(
27
+ (newItem) => !oldArray.includes(newItem)
28
+ ),
29
+ removed: oldArray.filter(
30
+ (oldItem) => !newArray.includes(oldItem)
31
+ ),
32
+ }
33
+ }
34
+ const ARRAY_DIFF_OP = {
35
+ ADD: 'add',
36
+ REMOVE: 'remove',
37
+ MOVE: 'move',
38
+ NOOP: 'noop'
39
+ };
40
+ class ArrayWithOriginalIndices {
41
+ #oldArray = [];
42
+ #originalIndices = [];
43
+ #equalsFn;
44
+ constructor(array, equalsFn) {
45
+ this.#oldArray = [...array];
46
+ this.#originalIndices = array.map((value, index) => index);
47
+ this.#equalsFn = equalsFn;
48
+ }
49
+ get length() {
50
+ return this.#oldArray.length;
51
+ }
52
+ originalIndexAt(index) {
53
+ return this.#originalIndices[index];
54
+ }
55
+ isAddition(item, startIndex) {
56
+ return this.findIndexFrom(item, startIndex) === -1;
57
+ }
58
+ addItem(item, index) {
59
+ const operation = {
60
+ op: ARRAY_DIFF_OP.ADD,
61
+ index,
62
+ item
63
+ };
64
+ this.#oldArray.splice(index, 0, item);
65
+ this.#originalIndices.splice(index, 0, -1);
66
+ return operation;
67
+ }
68
+ isRemoval(index, newArray) {
69
+ if (index >= this.length) { return false; }
70
+ const item = this.#oldArray[index];
71
+ const indexInNewArray = newArray.findIndex((newArrayItem) => this.#equalsFn(item, newArrayItem));
72
+ return indexInNewArray === -1;
73
+ }
74
+ removeItem(index) {
75
+ const operation = {
76
+ op: ARRAY_DIFF_OP.REMOVE,
77
+ index,
78
+ item: this.#oldArray[index],
79
+ };
80
+ this.#oldArray.splice(index, 1);
81
+ this.#originalIndices.splice(index, 1);
82
+ return operation;
83
+ }
84
+ moveItem(item, toIndex) {
85
+ const fromIndex = this.findIndexFrom(item, toIndex);
86
+ const operation = {
87
+ op: ARRAY_DIFF_OP.MOVE,
88
+ originalIndex: this.originalIndexAt(fromIndex),
89
+ from: fromIndex,
90
+ index: toIndex,
91
+ item: this.#oldArray[fromIndex],
92
+ };
93
+ const [itemToMove] = this.#oldArray.splice(fromIndex, 1);
94
+ this.#oldArray.splice(toIndex, 0, itemToMove);
95
+ const [originalIndex] = this.#originalIndices.splice(fromIndex, 1);
96
+ this.#originalIndices.splice(toIndex, 0, originalIndex);
97
+ return operation;
98
+ }
99
+ isNoop(index, newArray) {
100
+ if (index >= this.length) {return false; }
101
+ const item = this.#oldArray[index];
102
+ const newArrayItem = newArray[index];
103
+ return this.#equalsFn(item, newArrayItem);
104
+ }
105
+ noopItem(index) {
106
+ return {
107
+ op: ARRAY_DIFF_OP.NOOP,
108
+ originalIndex: this.originalIndexAt(index),
109
+ index,
110
+ item: this.#oldArray[index],
111
+ }
112
+ }
113
+ removeItemsAfter(index) {
114
+ const operations = [];
115
+ while (this.length > index) {
116
+ operations.push(this.removeItem(index));
117
+ }
118
+ return operations;
119
+ }
120
+ findIndexFrom(item, startIndex) {
121
+ for (let i = startIndex; i < this.length; i++) {
122
+ if (this.#equalsFn(item, this.#oldArray[i])) {
123
+ return i;
124
+ }
125
+ }
126
+ return -1;
127
+ }
128
+ }
129
+ function arraysDiffSequence(oldArray, newArray, equalsFn = (a, b) => a === b) {
130
+ const sequence = [];
131
+ const array = new ArrayWithOriginalIndices(oldArray, equalsFn);
132
+ for (let index = 0; index < newArray.length; index++) {
133
+ if (array.isRemoval(index, newArray)) {
134
+ sequence.push(array.removeItem(index));
135
+ index--;
136
+ continue;
137
+ }
138
+ if (array.isNoop(index, newArray)) {
139
+ sequence.push(array.noopItem(index));
140
+ continue;
141
+ }
142
+ const item = newArray[index];
143
+ if (array.isAddition(item, index)) {
144
+ sequence.push(array.addItem(item, index));
145
+ continue;
146
+ }
147
+ sequence.push(array.moveItem(item, index));
148
+ }
149
+ sequence.push(...array.removeItemsAfter(newArray.length));
150
+ return sequence;
151
+ }
152
+
153
+ const DOM_TYPES = {
154
+ TEXT: 'text',
155
+ ELEMENT: 'element',
156
+ FRAGMENT: 'fragment',
157
+ COMPONENT: 'component'
158
+ };
159
+ function h(tag, props = {}, children = []) {
160
+ const type = typeof tag === 'string' ? DOM_TYPES.ELEMENT : DOM_TYPES.COMPONENT;
161
+ return {
162
+ tag,
163
+ props,
164
+ type,
165
+ children: mapTextNodes(withoutNulls(children)),
166
+ }
167
+ }
168
+ function hString(str) {
169
+ return {
170
+ type: DOM_TYPES.TEXT,
171
+ value: str
172
+ };
173
+ }
174
+ function hFragment(vNodes) {
175
+ return {
176
+ children: mapTextNodes(withoutNulls(vNodes)),
177
+ type: DOM_TYPES.FRAGMENT,
178
+ }
179
+ }
180
+ function mapTextNodes(children) {
181
+ return children.map((child) =>
182
+ typeof child === 'string' ? hString(child) : child
183
+ )
184
+ }
185
+ function extractChildren(vNode) {
186
+ if (vNode.children == null) return [];
187
+ const children = [];
188
+ for (const child of vNode.children) {
189
+ if (child.type === DOM_TYPES.FRAGMENT) {
190
+ children.push(...extractChildren(child));
191
+ } else {
192
+ children.push(child);
193
+ }
194
+ }
195
+ return children;
196
+ }
197
+
198
+ function destroyDOM(vNode) {
199
+ const { type } = vNode;
200
+ switch (type) {
201
+ case DOM_TYPES.TEXT: {
202
+ removeTextNode(vNode);
203
+ break;
204
+ }
205
+ case DOM_TYPES.ELEMENT: {
206
+ removeElementNode(vNode);
207
+ break;
208
+ }
209
+ case DOM_TYPES.FRAGMENT: {
210
+ removeFragmentNode(vNode);
211
+ break;
212
+ }
213
+ case DOM_TYPES.COMPONENT: {
214
+ vNode.component.unmount();
215
+ break;
216
+ }
217
+ default: {
218
+ throw new Error(`Can't destroy virtual node of type: ${vNode.type}`);
219
+ }
220
+ }
221
+ delete vNode.el;
222
+ }
223
+ function removeTextNode(vNode) {
224
+ const { el } = vNode;
225
+ el.remove();
226
+ }
227
+ function removeElementNode(vNode) {
228
+ const { el, children, listeners } = vNode;
229
+ children.forEach(destroyDOM);
230
+ if (listeners) {
231
+ removeEventListeners(listeners, el);
232
+ delete vNode.listeners;
233
+ }
234
+ el.remove();
235
+ }
236
+ function removeFragmentNode(vNode) {
237
+ const { children } = vNode;
238
+ children.forEach(destroyDOM);
239
+ }
240
+
241
+ class Dispatcher {
242
+ #handlersByCommand = new Map();
243
+ #afterHandlers = [];
244
+ subscribe(commandName, handler) {
245
+ if (!this.#handlersByCommand.has(commandName)) {
246
+ this.#handlersByCommand.set(commandName, []);
247
+ }
248
+ const handlers = this.#handlersByCommand.get(commandName);
249
+ if (handlers.includes(handler)) {
250
+ return () => {}
251
+ }
252
+ handlers.push(handler);
253
+ return () => {
254
+ const index = handlers.indexOf(handler);
255
+ handlers.splice(index, 1);
256
+ }
257
+ }
258
+ afterEveryCommand(handler) {
259
+ this.#afterHandlers.push(handler);
260
+ return () => {
261
+ const index = this.#afterHandlers.indexOf(handler);
262
+ this.#afterHandlers.splice(index, 1);
263
+ }
264
+ }
265
+ dispatch(commandName, payload) {
266
+ if (this.#handlersByCommand.has(commandName)) {
267
+ this.#handlersByCommand.get(commandName).forEach((handler) => handler(payload));
268
+ } else {
269
+ console.warn(`No handlers for command: ${commandName}`);
270
+ }
271
+ this.#afterHandlers.forEach((handler) => handler());
272
+ }
273
+ }
274
+
275
+ function setAttributes(el, attrs) {
276
+ const { class: className, style, ...otherAttrs } = attrs;
277
+ if (className) {
278
+ setClass(el, className);
279
+ }
280
+ if (style) {
281
+ Object.entries(style).forEach(([prop, value]) => {
282
+ setStyle(el, prop, value);
283
+ });
284
+ }
285
+ for (const [name, value] of Object.entries(otherAttrs)) {
286
+ setAttribute(el, name, value);
287
+ }
288
+ }
289
+ function setClass(el, className) {
290
+ el.className = '';
291
+ if (typeof className === 'string') {
292
+ el.className = className;
293
+ }
294
+ if (Array.isArray(className)) {
295
+ el.classList.add(...className);
296
+ }
297
+ }
298
+ function setStyle(el, name, value) {
299
+ el.style[name] = value;
300
+ }
301
+ function removeStyle(el, name) {
302
+ el.style[name] = null;
303
+ }
304
+ function setAttribute(el, name, value) {
305
+ if (value == null) {
306
+ removeAttribute(el, name);
307
+ } else if (name.startsWith('data-')) {
308
+ el.setAttribute(name, value);
309
+ } else {
310
+ el[name] = value;
311
+ }
312
+ }
313
+ function removeAttribute(el, name) {
314
+ el[name] = null;
315
+ el.removeAttribute(name);
316
+ }
317
+
318
+ function mountDOM(vNode, parentEl, index, hostComponent = null) {
319
+ switch (vNode.type) {
320
+ case DOM_TYPES.TEXT: {
321
+ createTextNode(vNode, parentEl, index);
322
+ break;
323
+ }
324
+ case DOM_TYPES.ELEMENT: {
325
+ createElementNode(vNode, parentEl, index, hostComponent);
326
+ break;
327
+ }
328
+ case DOM_TYPES.FRAGMENT: {
329
+ createFragmentNode(vNode, parentEl, index, hostComponent);
330
+ break;
331
+ }
332
+ case DOM_TYPES.COMPONENT: {
333
+ createComponentNode(vNode, parentEl, index);
334
+ }
335
+ default: {
336
+ throw new Error(`Can't mount virtual node of type: ${vNode.type}`);
337
+ }
338
+ }
339
+ }
340
+ function createTextNode(vNode, parentEl, index) {
341
+ const { value } = vNode;
342
+ const textNode = document.createTextNode(value);
343
+ vNode.el = textNode;
344
+ insert(textNode, parentEl, index);
345
+ }
346
+ function createElementNode(vNode, parentEl, index, hostComponent) {
347
+ const { tag, props, children } = vNode;
348
+ const el = document.createElement(tag);
349
+ addProps(el, props, vNode, hostComponent);
350
+ vNode.el = el;
351
+ children.forEach((child) => mountDOM(child, el, null, hostComponent));
352
+ insert(el, parentEl, index);
353
+ }
354
+ function createFragmentNode(vNode, parentEl, index, hostComponent) {
355
+ const { children } = vNode;
356
+ vNode.el = parentEl;
357
+ children.forEach((child, i) => {
358
+ mountDOM(child, parentEl, index ? index + i : null, hostComponent);
359
+ });
360
+ }
361
+ function createComponentNode(vNode, parentEl, index, hostComponent) {
362
+ const Component = vNode.tag;
363
+ const props = vNode.props;
364
+ const component = new Component(props);
365
+ component.mount(parentEl, index);
366
+ vNode.component = component;
367
+ vNode.el = component.firstElement;
368
+ }
369
+ function addProps(el, props, vNode, hostComponent) {
370
+ const { on: events, ...attrs} = props;
371
+ vNode.listeners = addEventListeners(events, el, hostComponent);
372
+ setAttributes(el, attrs);
373
+ }
374
+ function insert(el, parentEl, index) {
375
+ if (index == null) {
376
+ parentEl.append(el);
377
+ return;
378
+ }
379
+ if (index < 0) {
380
+ throw new Error(`Index must be a positive number, got ${index}`);
381
+ }
382
+ const children = parentEl.childNodes;
383
+ if (index >= children.length) {
384
+ parentEl.append(el);
385
+ } else {
386
+ parentEl.insertBefore(el, children[index]);
387
+ }
388
+ }
389
+
390
+ function areNodesEqual(nodeOne, nodeTwo) {
391
+ if (nodeOne.type !== nodeTwo.type) return false;
392
+ if (nodeOne.type === DOM_TYPES.ELEMENT) {
393
+ return nodeOne.tag === nodeTwo.tag;
394
+ }
395
+ return true;
396
+ }
397
+
398
+ function objectsDiff(oldObj, newObj) {
399
+ const oldKeys = Object.keys(oldObj);
400
+ const newKeys = Object.keys(newObj);
401
+ return {
402
+ added: newKeys.filter((newKey) => !(newKey in oldObj)),
403
+ removed: oldKeys.filter((oldKey) => !(oldKey in newObj)),
404
+ updated: newKeys.filter(
405
+ (key) => key in oldObj && oldObj[key] !== newObj[key]
406
+ ),
407
+ }
408
+ }
409
+ function hasOwnProperty(obj, prop) {
410
+ return Object.prototype.hasOwnProperty.call(obj, prop);
411
+ }
412
+
413
+ function isNotEmptyString(str) {
414
+ return str !== '';
415
+ }
416
+ function isNotBlankOrEmptyString(str) {
417
+ return isNotEmptyString(str.trim());
418
+ }
419
+
420
+ function patchDOM(oldVNode, newVNode, parentEl, hostComponent = null) {
421
+ if (!areNodesEqual(oldVNode, newVNode)) {
422
+ const index = findIndexInParent(parentEl, oldVNode.el);
423
+ destroyDOM(oldVNode);
424
+ mountDOM(newVNode, parentEl, index, hostComponent);
425
+ return newVNode;
426
+ }
427
+ newVNode.el = oldVNode.el;
428
+ switch (newVNode.type) {
429
+ case DOM_TYPES.TEXT: {
430
+ patchText(oldVNode, newVNode);
431
+ return newVNode;
432
+ }
433
+ case DOM_TYPES.ELEMENT: {
434
+ patchElement(oldVNode, newVNode, hostComponent);
435
+ break;
436
+ }
437
+ case DOM_TYPES.COMPONENT: {
438
+ patchComponent(oldVNode, newVNode);
439
+ break;
440
+ }
441
+ }
442
+ patchChildren(oldVNode, newVNode, hostComponent);
443
+ return newVNode;
444
+ }
445
+ function findIndexInParent(parentEl, el) {
446
+ const index = Array.from(parentEl.childNodes).indexOf(el);
447
+ if (index < 0) return null;
448
+ return index;
449
+ }
450
+ function patchText(oldVNode, newVNode) {
451
+ const el = oldVNode.el;
452
+ const { value: oldText } = oldVNode;
453
+ const { value: newText } = newVNode;
454
+ if (oldText !== newText) {
455
+ el.nodeValue = newText;
456
+ }
457
+ }
458
+ function patchElement(oldVNode, newVNode, hostComponent) {
459
+ const el = oldVNode.el;
460
+ const {
461
+ class: oldClass,
462
+ style: oldStyle,
463
+ on: oldEvents,
464
+ ...oldAttrs
465
+ } = oldVNode.props;
466
+ const {
467
+ class: newClass,
468
+ style: newStyle,
469
+ on: newEvents,
470
+ ...newAttrs
471
+ } = newVNode.props;
472
+ const { listeners: oldListeners } = oldVNode;
473
+ patchAttrs(el, oldAttrs, newAttrs);
474
+ patchClasses(el, oldClass, newClass);
475
+ patchStyles(el, oldStyle, newStyle);
476
+ newVNode.listeners = patchEvents(el, oldListeners, oldEvents, newEvents, hostComponent);
477
+ }
478
+ function patchComponent(oldVNode, newVNode) {
479
+ const { component } = oldVNode;
480
+ const { props } = newVNode;
481
+ component.updateProps(props);
482
+ newVNode.component = component;
483
+ newVNode.el = component.firstElement;
484
+ }
485
+ function patchAttrs(el, oldAttrs, newAttrs) {
486
+ const { added, removed, updated } = objectsDiff(oldAttrs, newAttrs);
487
+ for (const attr of removed) {
488
+ removeAttribute(el, attr);
489
+ }
490
+ for (const attr of added.concat(updated)) {
491
+ setAttribute(el, attr, newAttrs[attr]);
492
+ }
493
+ }
494
+ function patchClasses(el, oldClass, newClass) {
495
+ const oldClasses = toClassList(oldClass);
496
+ const newClasses = toClassList(newClass);
497
+ const { added, removed } = arraysDiff(oldClasses, newClasses);
498
+ if (removed.length > 0) {
499
+ el.classList.remove(...removed);
500
+ }
501
+ if (added.length > 0) {
502
+ el.classList.add(...added);
503
+ }
504
+ }
505
+ function toClassList(classes = '') {
506
+ return Array.isArray(classes)
507
+ ? classes.filter(isNotBlankOrEmptyString)
508
+ : classes.split(/(\s+)/).filter(isNotBlankOrEmptyString);
509
+ }
510
+ function patchStyles(el, oldStyle = {}, newStyle = {}) {
511
+ const { added, removed, updated} = objectsDiff(oldStyle, newStyle);
512
+ for (const style of removed) {
513
+ removeStyle(el, style);
514
+ }
515
+ for (const style of added.concat(updated)) {
516
+ setStyle(el, style, newStyle[style]);
517
+ }
518
+ }
519
+ function patchEvents(el, oldListeners = {}, oldEvents = {}, newEvents = {}, hostComponent) {
520
+ const { removed, added, updated} = objectsDiff(oldEvents, newEvents);
521
+ for (const eventName of removed.concat(updated)) {
522
+ el.removeEventListener(eventName, oldListeners[eventName]);
523
+ }
524
+ const addedListeners = {};
525
+ for (const eventName of added.concat(updated)) {
526
+ addedListeners[eventName] = addEventListener(eventName, newEvents[eventName], el, hostComponent);
527
+ }
528
+ return addedListeners;
529
+ }
530
+ function patchChildren(oldVNode, newVNode, hostComponent) {
531
+ const oldChildren = extractChildren(oldVNode);
532
+ const newChildren = extractChildren(newVNode);
533
+ const parentEl = oldVNode.el;
534
+ const diffSeq = arraysDiffSequence(oldChildren, newChildren, areNodesEqual);
535
+ for (const operation of diffSeq) {
536
+ const { originalIndex, from, index, item } = operation;
537
+ const offset = hostComponent?.offset ?? 0;
538
+ switch (operation.op) {
539
+ case ARRAY_DIFF_OP.ADD: {
540
+ mountDOM(item, parentEl, index, hostComponent);
541
+ break;
542
+ }
543
+ case ARRAY_DIFF_OP.REMOVE: {
544
+ destroyDOM(item);
545
+ break;
546
+ }
547
+ case ARRAY_DIFF_OP.MOVE: {
548
+ const el = oldChildren[from].el;
549
+ const elAtTargetIndex = parentEl.childNodes[index + offset];
550
+ parentEl.insertBefore(el, elAtTargetIndex);
551
+ patchDOM(oldChildren[from], newChildren[index], parentEl, hostComponent);
552
+ break;
553
+ }
554
+ case ARRAY_DIFF_OP.NOOP: {
555
+ patchDOM(oldChildren[originalIndex], newChildren[index], parentEl, hostComponent);
556
+ break;
557
+ }
558
+ }
559
+ }
560
+ }
561
+
562
+ function createApp({state, view, reducers = {} }) {
563
+ let parentEl = null;
564
+ let rootNode = null;
565
+ let isMounted = false;
566
+ const dispatcher = new Dispatcher();
567
+ const unsubscribers = [dispatcher.afterEveryCommand(renderApp)];
568
+ for (const actionName in reducers) {
569
+ const reducer = reducers[actionName];
570
+ const unsubscribe = dispatcher.subscribe(actionName, (payload) => {
571
+ state = reducer(state, payload);
572
+ });
573
+ unsubscribers.push(unsubscribe);
574
+ }
575
+ function emit(actionName, payload) {
576
+ dispatcher.dispatch(actionName, payload);
577
+ }
578
+ function renderApp() {
579
+ const newRootNode = view(state, emit);
580
+ rootNode = patchDOM(rootNode, newRootNode, parentEl);
581
+ }
582
+ return {
583
+ mount(_parentEl) {
584
+ if (isMounted) throw new Error('The application is already mounted');
585
+ parentEl = _parentEl;
586
+ rootNode = view(state, emit);
587
+ mountDOM(rootNode, parentEl);
588
+ },
589
+ unmount() {
590
+ if (rootNode) {
591
+ destroyDOM(rootNode);
592
+ }
593
+ rootNode = null;
594
+ unsubscribers.forEach((unsubscribe) => unsubscribe());
595
+ isMounted = false;
596
+ },
597
+ }
598
+ }
599
+
600
+ function getDefaultExportFromCjs (x) {
601
+ return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
602
+ }
603
+
604
+ var fastDeepEqual;
605
+ var hasRequiredFastDeepEqual;
606
+ function requireFastDeepEqual () {
607
+ if (hasRequiredFastDeepEqual) return fastDeepEqual;
608
+ hasRequiredFastDeepEqual = 1;
609
+ fastDeepEqual = function equal(a, b) {
610
+ if (a === b) return true;
611
+ if (a && b && typeof a == 'object' && typeof b == 'object') {
612
+ if (a.constructor !== b.constructor) return false;
613
+ var length, i, keys;
614
+ if (Array.isArray(a)) {
615
+ length = a.length;
616
+ if (length != b.length) return false;
617
+ for (i = length; i-- !== 0;)
618
+ if (!equal(a[i], b[i])) return false;
619
+ return true;
620
+ }
621
+ if (a.constructor === RegExp) return a.source === b.source && a.flags === b.flags;
622
+ if (a.valueOf !== Object.prototype.valueOf) return a.valueOf() === b.valueOf();
623
+ if (a.toString !== Object.prototype.toString) return a.toString() === b.toString();
624
+ keys = Object.keys(a);
625
+ length = keys.length;
626
+ if (length !== Object.keys(b).length) return false;
627
+ for (i = length; i-- !== 0;)
628
+ if (!Object.prototype.hasOwnProperty.call(b, keys[i])) return false;
629
+ for (i = length; i-- !== 0;) {
630
+ var key = keys[i];
631
+ if (!equal(a[key], b[key])) return false;
632
+ }
633
+ return true;
634
+ }
635
+ return a!==a && b!==b;
636
+ };
637
+ return fastDeepEqual;
638
+ }
639
+
640
+ var fastDeepEqualExports = requireFastDeepEqual();
641
+ var equal = /*@__PURE__*/getDefaultExportFromCjs(fastDeepEqualExports);
642
+
643
+ function defineComponent({ render, state, ...methods }) {
644
+ class Component {
645
+ #isMounted = false;
646
+ #vNode = null;
647
+ #hostEl = null;
648
+ constructor(props = {}) {
649
+ this.props = props;
650
+ this.state = state ? state(props) : {};
651
+ }
652
+ get elements() {
653
+ if (this.#vNode == null) {
654
+ return [];
655
+ }
656
+ if (this.#vNode.type === DOM_TYPES.FRAGMENT) {
657
+ return extractChildren(this.#vNode).flatMap((child) => {
658
+ if (child.type === DOM_TYPES.COMPONENT) {
659
+ return child.component.elements;
660
+ }
661
+ return [child.el];
662
+ });
663
+ }
664
+ return [this.#vNode.el];
665
+ }
666
+ get firstElement() {
667
+ return this.elements[0];
668
+ }
669
+ get offset() {
670
+ if(this.#vNode.type === DOM_TYPES.FRAGMENT) {
671
+ return Array.from(this.#hostEl.children).indexOf(this.firstElement);
672
+ }
673
+ return 0;
674
+ }
675
+ updateProps(props) {
676
+ const newProps = { ...this.props, ...props };
677
+ if (equal(this.props, newProps)) {
678
+ return;
679
+ }
680
+ this.props = newProps;
681
+ this.#patch();
682
+ }
683
+ updateState(state) {
684
+ this.state = { ...this.state, ...state };
685
+ this.#patch();
686
+ }
687
+ render() {
688
+ return render.call(this);
689
+ }
690
+ mount(hostEl, index = null) {
691
+ if (this.#isMounted) {
692
+ throw new Error('Component is already mounted');
693
+ }
694
+ this.#vNode = this.render();
695
+ mountDOM(this.#vNode, hostEl, index, this);
696
+ this.#hostEl = hostEl;
697
+ this.#isMounted = true;
698
+ }
699
+ unmount() {
700
+ if (!this.#isMounted) {
701
+ throw new Error('Component is not mounted');
702
+ }
703
+ destroyDOM(this.#vNode);
704
+ this.#vNode = null;
705
+ this.#hostEl = null;
706
+ this.#isMounted = false;
707
+ }
708
+ #patch() {
709
+ if (!this.#isMounted) {
710
+ throw new Error('Component is not mounted');
711
+ }
712
+ const vNode = this.render();
713
+ this.#vNode = patchDOM(this.#vNode, vNode, this.#hostEl, this);
714
+ }
715
+ }
716
+ for (const methodName in methods) {
717
+ if (hasOwnProperty(Component, methodName)) {
718
+ throw new Error(`Method "${methodName}()" already exists in the component.`);
719
+ }
720
+ Component.prototype[methodName] = methods[methodName];
721
+ }
722
+ return Component;
723
+ }
724
+
725
+ export { createApp, defineComponent, h, hFragment, hString };
package/package.json CHANGED
@@ -1,12 +1,13 @@
1
1
  {
2
2
  "name": "ks-fwork",
3
- "version": "3.0.0",
3
+ "version": "3.0.1",
4
4
  "description": "Demo Frontend Framework",
5
5
  "license": "ISC",
6
6
  "author": "",
7
7
  "type": "module",
8
- "main": "src/index.js",
9
- "exports": "./src/index.js",
8
+ "main": "dist/ks-fwork.js",
9
+ "module": "dist/ks-fwork.js",
10
+ "exports": "./dist/ks-fwork.js",
10
11
  "files": [
11
12
  "src"
12
13
  ],