@mulsense/xnew 0.6.5 → 0.6.7

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/xnew.js CHANGED
@@ -523,92 +523,15 @@
523
523
  // utils
524
524
  //----------------------------------------------------------------------------------------------------
525
525
  const SYSTEM_EVENTS = ['start', 'update', 'render', 'stop', 'finalize'];
526
- class UnitPromise {
527
- constructor(promise, Component) {
528
- this.promise = promise;
529
- this.Component = Component;
530
- }
531
- then(callback) { return this.wrap('then', callback); }
532
- catch(callback) { return this.wrap('catch', callback); }
533
- finally(callback) { return this.wrap('finally', callback); }
534
- wrap(key, callback) {
535
- const snapshot = Unit.snapshot(Unit.currentUnit);
536
- this.promise = this.promise[key]((...args) => Unit.scope(snapshot, callback, ...args));
537
- return this;
538
- }
539
- }
540
- class UnitTimer {
541
- constructor() {
542
- this.unit = null;
543
- this.stack = [];
544
- }
545
- clear() {
546
- var _a;
547
- this.stack = [];
548
- (_a = this.unit) === null || _a === void 0 ? void 0 : _a.finalize();
549
- this.unit = null;
550
- }
551
- timeout(callback, duration = 0) {
552
- return UnitTimer.execute(this, { callback, duration }, 1);
553
- }
554
- interval(callback, duration = 0, iterations = 0) {
555
- return UnitTimer.execute(this, { callback, duration }, iterations);
556
- }
557
- transition(transition, duration = 0, easing) {
558
- return UnitTimer.execute(this, { transition, duration, easing }, 1);
559
- }
560
- static execute(timer, options, iterations) {
561
- const props = { options, iterations, snapshot: Unit.snapshot(Unit.currentUnit) };
562
- if (timer.unit === null || timer.unit._.state === 'finalized') {
563
- timer.unit = new Unit(Unit.currentUnit, null, UnitTimer.Component, props);
564
- }
565
- else if (timer.stack.length === 0) {
566
- timer.stack.push(props);
567
- timer.unit.on('finalize', () => UnitTimer.next(timer));
568
- }
569
- else {
570
- timer.stack.push(props);
571
- }
572
- return timer;
573
- }
574
- static next(timer) {
575
- if (timer.stack.length > 0) {
576
- timer.unit = new Unit(Unit.currentUnit, null, UnitTimer.Component, timer.stack.shift());
577
- timer.unit.on('finalize', () => UnitTimer.next(timer));
578
- }
579
- }
580
- static Component(unit, { options, iterations, snapshot }) {
581
- let counter = 0;
582
- let timer = new Timer({ callback, transition, duration: options.duration, easing: options.easing });
583
- function callback() {
584
- if (options.callback)
585
- Unit.scope(snapshot, options.callback);
586
- if (iterations <= 0 || counter < iterations - 1) {
587
- timer = new Timer({ callback, transition, duration: options.duration, easing: options.easing });
588
- }
589
- else {
590
- unit.finalize();
591
- }
592
- counter++;
593
- }
594
- function transition(value) {
595
- if (options.transition)
596
- Unit.scope(snapshot, options.transition, { value });
597
- }
598
- unit.on('finalize', () => timer.clear());
599
- }
600
- }
601
- function DefaultComponent(unit, { text }) {
602
- if (text !== undefined) {
603
- unit.element.textContent = text;
604
- }
605
- }
606
526
  //----------------------------------------------------------------------------------------------------
607
527
  // unit
608
528
  //----------------------------------------------------------------------------------------------------
609
529
  class Unit {
610
- constructor(parent, target, component, props) {
530
+ constructor(parent, target, Component, props) {
611
531
  var _a;
532
+ const backup = Unit.currentUnit;
533
+ Unit.currentUnit = this;
534
+ parent === null || parent === void 0 ? void 0 : parent._.children.push(this);
612
535
  let baseElement;
613
536
  if (target instanceof HTMLElement || target instanceof SVGElement) {
614
537
  baseElement = target;
@@ -620,20 +543,45 @@
620
543
  baseElement = (document === null || document === void 0 ? void 0 : document.body) ? document.body : null;
621
544
  }
622
545
  let baseComponent;
623
- if (typeof component === 'function') {
624
- baseComponent = component;
546
+ if (typeof Component === 'function') {
547
+ baseComponent = Component;
625
548
  }
626
- else if (typeof component === 'string' || typeof component === 'number') {
627
- baseComponent = DefaultComponent;
628
- props = { text: component.toString() };
549
+ else if (typeof Component === 'string' || typeof Component === 'number') {
550
+ baseComponent = (unit) => { unit.element.textContent = Component.toString(); };
629
551
  }
630
552
  else {
631
- baseComponent = DefaultComponent;
553
+ baseComponent = (unit) => { };
632
554
  }
633
- const baseContext = (_a = parent === null || parent === void 0 ? void 0 : parent._.currentContext) !== null && _a !== void 0 ? _a : { stack: null };
634
- this._ = { parent, target, baseElement, baseContext, baseComponent, props };
635
- parent === null || parent === void 0 ? void 0 : parent._.children.push(this);
636
- Unit.initialize(this, null);
555
+ const baseContext = (_a = parent === null || parent === void 0 ? void 0 : parent._.currentContext) !== null && _a !== void 0 ? _a : { previous: null };
556
+ this._ = {
557
+ parent,
558
+ state: 'invoked',
559
+ tostart: true,
560
+ protected: false,
561
+ currentElement: baseElement,
562
+ currentContext: baseContext,
563
+ currentComponent: null,
564
+ ancestors: parent ? [parent, ...parent._.ancestors] : [],
565
+ children: [],
566
+ nestElements: [],
567
+ promises: [],
568
+ results: {},
569
+ Components: [],
570
+ listeners: new MapMap(),
571
+ defines: {},
572
+ systems: { start: [], update: [], render: [], stop: [], finalize: [] },
573
+ eventor: new Eventor(),
574
+ };
575
+ // nest html element
576
+ if (typeof target === 'string') {
577
+ Unit.nest(this, target);
578
+ }
579
+ // setup Component
580
+ Unit.extend(this, baseComponent, props);
581
+ if (this._.state === 'invoked') {
582
+ this._.state = 'initialized';
583
+ }
584
+ Unit.currentUnit = backup;
637
585
  }
638
586
  get element() {
639
587
  return this._.currentElement;
@@ -648,77 +596,39 @@
648
596
  finalize() {
649
597
  Unit.stop(this);
650
598
  Unit.finalize(this);
651
- if (this._.parent) {
652
- this._.parent._.children = this._.parent._.children.filter((unit) => unit !== this);
653
- }
654
- }
655
- reboot() {
656
- let anchor = null;
657
- if (this._.nestElements[0] && this._.nestElements[0].owned === true) {
658
- anchor = this._.nestElements[0].element.nextElementSibling;
659
- }
660
- Unit.stop(this);
661
- Unit.finalize(this);
662
- Unit.initialize(this, anchor);
663
- }
664
- static initialize(unit, anchor) {
665
- const backup = Unit.currentUnit;
666
- Unit.currentUnit = unit;
667
- const done = {
668
- promise: null,
669
- resolve: null,
670
- reject: null
671
- };
672
- done.promise = new Promise((resolve, reject) => { done.resolve = resolve; done.reject = reject; });
673
- unit._ = Object.assign(unit._, {
674
- currentElement: unit._.baseElement,
675
- currentContext: unit._.baseContext,
676
- currentComponent: null,
677
- anchor,
678
- state: 'invoked',
679
- tostart: true,
680
- protected: false,
681
- ancestors: unit._.parent ? [unit._.parent, ...unit._.parent._.ancestors] : [],
682
- children: [],
683
- nestElements: [],
684
- promises: [],
685
- done,
686
- components: [],
687
- listeners: new MapMap(),
688
- defines: {},
689
- systems: { start: [], update: [], render: [], stop: [], finalize: [] },
690
- eventor: new Eventor(),
691
- });
692
- // nest html element
693
- if (typeof unit._.target === 'string') {
694
- Unit.nest(unit, unit._.target);
695
- }
696
- // setup component
697
- Unit.extend(unit, unit._.baseComponent, unit._.props);
698
- // whether the unit promise was resolved
699
- // Promise.all(unit._.promises.map(p => p.promise)).then(() => unit._.state = 'initialized');
700
- unit._.state = 'initialized';
701
- Unit.currentUnit = backup;
702
599
  }
703
600
  static finalize(unit) {
704
601
  if (unit._.state !== 'finalized' && unit._.state !== 'finalizing') {
705
602
  unit._.state = 'finalizing';
706
- [...unit._.children].reverse().forEach((child) => child.finalize());
707
- [...unit._.systems.finalize].reverse().forEach(({ execute }) => execute());
603
+ unit._.children.reverse().forEach((child) => child.finalize());
604
+ unit._.systems.finalize.reverse().forEach(({ execute }) => execute());
708
605
  unit.off();
709
- unit._.components.forEach((component) => Unit.component2units.delete(component, unit));
710
- for (const { element, owned } of unit._.nestElements.reverse()) {
711
- if (owned === true) {
712
- element.remove();
606
+ unit._.nestElements.reverse().filter(item => item.owned).forEach(item => item.element.remove());
607
+ unit._.Components.forEach((Component) => Unit.component2units.delete(Component, unit));
608
+ // remove contexts
609
+ const contexts = Unit.unit2Contexts.get(unit);
610
+ contexts === null || contexts === void 0 ? void 0 : contexts.forEach((context) => {
611
+ let temp = context.previous;
612
+ while (temp !== null) {
613
+ if (contexts.has(temp) === false && temp.key !== undefined) {
614
+ context.previous = temp;
615
+ context.key = undefined;
616
+ context.value = undefined;
617
+ break;
618
+ }
619
+ temp = temp.previous;
713
620
  }
714
- }
715
- unit._.currentElement = unit._.baseElement;
716
- // reset defines
621
+ });
622
+ Unit.unit2Contexts.delete(unit);
623
+ unit._.currentContext = { previous: null };
717
624
  Object.keys(unit._.defines).forEach((key) => {
718
625
  delete unit[key];
719
626
  });
720
627
  unit._.defines = {};
721
628
  unit._.state = 'finalized';
629
+ if (unit._.parent) {
630
+ unit._.parent._.children = unit._.parent._.children.filter((u) => u !== unit);
631
+ }
722
632
  }
723
633
  }
724
634
  static nest(unit, target, textContent) {
@@ -730,16 +640,8 @@
730
640
  else {
731
641
  const match = target.match(/<((\w+)[^>]*?)\/?>/);
732
642
  if (match !== null) {
733
- let element;
734
- if (unit._.anchor !== null) {
735
- unit._.anchor.insertAdjacentHTML('beforebegin', `<${match[1]}></${match[2]}>`);
736
- element = unit._.anchor.previousElementSibling;
737
- unit._.anchor = null;
738
- }
739
- else {
740
- unit._.currentElement.insertAdjacentHTML('beforeend', `<${match[1]}></${match[2]}>`);
741
- element = unit._.currentElement.children[unit._.currentElement.children.length - 1];
742
- }
643
+ unit._.currentElement.insertAdjacentHTML('beforeend', `<${match[1]}></${match[2]}>`);
644
+ const element = unit._.currentElement.children[unit._.currentElement.children.length - 1];
743
645
  unit._.currentElement = element;
744
646
  if (textContent !== undefined) {
745
647
  element.textContent = textContent.toString();
@@ -754,25 +656,20 @@
754
656
  }
755
657
  static extend(unit, Component, props) {
756
658
  var _a;
757
- if (unit._.components.includes(Component) === true) {
758
- throw new Error(`The component is already extended.`);
659
+ if (unit._.Components.includes(Component) === true) {
660
+ throw new Error(`The Component is already extended.`);
759
661
  }
760
662
  else {
761
663
  const backupComponent = unit._.currentComponent;
762
664
  unit._.currentComponent = Component;
763
- const defines = (_a = Component(unit, props !== null && props !== void 0 ? props : {})) !== null && _a !== void 0 ? _a : {};
764
- if (unit._.parent && Component !== DefaultComponent) {
765
- if (Component === unit._.baseComponent) {
766
- Unit.context(unit._.parent, Component, unit);
767
- }
768
- else {
769
- Unit.context(unit, Component, unit);
770
- Unit.context(unit._.parent, Component, unit);
771
- }
665
+ if (unit._.parent !== null) {
666
+ Unit.addContext(unit._.parent, unit, Component, unit);
772
667
  }
668
+ Unit.addContext(unit, unit, Component, unit);
669
+ const defines = (_a = Component(unit, props !== null && props !== void 0 ? props : {})) !== null && _a !== void 0 ? _a : {};
773
670
  unit._.currentComponent = backupComponent;
774
671
  Unit.component2units.add(Component, unit);
775
- unit._.components.push(Component);
672
+ unit._.Components.push(Component);
776
673
  Object.keys(defines).forEach((key) => {
777
674
  if (unit[key] !== undefined && unit._.defines[key] === undefined) {
778
675
  throw new Error(`The property "${key}" already exists.`);
@@ -790,7 +687,7 @@
790
687
  wrapper.value = (...args) => Unit.scope(snapshot, descriptor.value, ...args);
791
688
  }
792
689
  else {
793
- throw new Error(`Only function properties can be defined as component defines. [${key}]`);
690
+ throw new Error(`Only function properties can be defined as Component defines. [${key}]`);
794
691
  }
795
692
  Object.defineProperty(unit._.defines, key, wrapper);
796
693
  Object.defineProperty(unit, key, wrapper);
@@ -850,7 +747,7 @@
850
747
  Unit.currentUnit = snapshot.unit;
851
748
  snapshot.unit._.currentContext = snapshot.context;
852
749
  snapshot.unit._.currentElement = snapshot.element;
853
- snapshot.unit._.currentComponent = snapshot.component;
750
+ snapshot.unit._.currentComponent = snapshot.Component;
854
751
  return func(...args);
855
752
  }
856
753
  catch (error) {
@@ -860,21 +757,22 @@
860
757
  Unit.currentUnit = currentUnit;
861
758
  snapshot.unit._.currentContext = backup.context;
862
759
  snapshot.unit._.currentElement = backup.element;
863
- snapshot.unit._.currentComponent = backup.component;
760
+ snapshot.unit._.currentComponent = backup.Component;
864
761
  }
865
762
  }
866
763
  static snapshot(unit) {
867
- return { unit, context: unit._.currentContext, element: unit._.currentElement, component: unit._.currentComponent };
764
+ return { unit, context: unit._.currentContext, element: unit._.currentElement, Component: unit._.currentComponent };
868
765
  }
869
- static context(unit, key, value) {
870
- if (value !== undefined) {
871
- unit._.currentContext = { stack: unit._.currentContext, key, value };
872
- }
873
- else {
874
- for (let context = unit._.currentContext; context.stack !== null; context = context.stack) {
875
- if (context.key === key)
876
- return context.value;
877
- }
766
+ static addContext(unit, orner, key, value) {
767
+ unit._.currentContext = { previous: unit._.currentContext, key, value };
768
+ Unit.unit2Contexts.add(orner, unit._.currentContext);
769
+ }
770
+ static getContext(unit, key) {
771
+ for (let context = unit._.currentContext; context.previous !== null; context = context.previous) {
772
+ if (context.value === Unit.currentUnit && key === Unit.currentUnit._.currentComponent)
773
+ continue;
774
+ if (context.key === key)
775
+ return context.value;
878
776
  }
879
777
  }
880
778
  static find(Component) {
@@ -898,7 +796,7 @@
898
796
  unit._.systems[type].push({ listener, execute });
899
797
  }
900
798
  if (unit._.listeners.has(type, listener) === false) {
901
- unit._.listeners.set(type, listener, { element: unit.element, component: unit._.currentComponent, execute });
799
+ unit._.listeners.set(type, listener, { element: unit.element, Component: unit._.currentComponent, execute });
902
800
  Unit.type2units.add(type, unit);
903
801
  if (/^[A-Za-z]/.test(type)) {
904
802
  unit._.eventor.add(unit.element, type, execute, options);
@@ -940,11 +838,90 @@
940
838
  }
941
839
  }
942
840
  Unit.currentComponent = () => { };
841
+ Unit.unit2Contexts = new MapSet();
943
842
  Unit.component2units = new MapSet();
944
843
  //----------------------------------------------------------------------------------------------------
945
844
  // event
946
845
  //----------------------------------------------------------------------------------------------------
947
846
  Unit.type2units = new MapSet();
847
+ //----------------------------------------------------------------------------------------------------
848
+ // extensions
849
+ //----------------------------------------------------------------------------------------------------
850
+ class UnitPromise {
851
+ constructor(promise, Component) {
852
+ this.promise = promise;
853
+ this.Component = Component;
854
+ }
855
+ then(callback) { return this.wrap('then', callback); }
856
+ catch(callback) { return this.wrap('catch', callback); }
857
+ finally(callback) { return this.wrap('finally', callback); }
858
+ wrap(key, callback) {
859
+ const snapshot = Unit.snapshot(Unit.currentUnit);
860
+ this.promise = this.promise[key]((...args) => Unit.scope(snapshot, callback, ...args));
861
+ return this;
862
+ }
863
+ }
864
+ class UnitTimer {
865
+ constructor() {
866
+ this.unit = null;
867
+ this.queue = [];
868
+ }
869
+ clear() {
870
+ var _a;
871
+ this.queue = [];
872
+ (_a = this.unit) === null || _a === void 0 ? void 0 : _a.finalize();
873
+ this.unit = null;
874
+ }
875
+ timeout(callback, duration = 0) {
876
+ return UnitTimer.execute(this, { callback, duration }, 1);
877
+ }
878
+ interval(callback, duration = 0, iterations = 0) {
879
+ return UnitTimer.execute(this, { callback, duration }, iterations);
880
+ }
881
+ transition(transition, duration = 0, easing) {
882
+ return UnitTimer.execute(this, { transition, duration, easing }, 1);
883
+ }
884
+ static execute(timer, options, iterations) {
885
+ const props = { options, iterations, snapshot: Unit.snapshot(Unit.currentUnit) };
886
+ if (timer.unit === null || timer.unit._.state === 'finalized') {
887
+ timer.unit = new Unit(Unit.currentUnit, null, UnitTimer.Component, props);
888
+ }
889
+ else if (timer.queue.length === 0) {
890
+ timer.queue.push(props);
891
+ timer.unit.on('finalize', () => UnitTimer.next(timer));
892
+ }
893
+ else {
894
+ timer.queue.push(props);
895
+ }
896
+ return timer;
897
+ }
898
+ static next(timer) {
899
+ if (timer.queue.length > 0) {
900
+ timer.unit = new Unit(Unit.currentUnit, null, UnitTimer.Component, timer.queue.shift());
901
+ timer.unit.on('finalize', () => UnitTimer.next(timer));
902
+ }
903
+ }
904
+ static Component(unit, { options, iterations, snapshot }) {
905
+ let counter = 0;
906
+ let timer = new Timer({ callback, transition, duration: options.duration, easing: options.easing });
907
+ function callback() {
908
+ if (options.callback)
909
+ Unit.scope(snapshot, options.callback);
910
+ if (iterations <= 0 || counter < iterations - 1) {
911
+ timer = new Timer({ callback, transition, duration: options.duration, easing: options.easing });
912
+ }
913
+ else {
914
+ unit.finalize();
915
+ }
916
+ counter++;
917
+ }
918
+ function transition(value) {
919
+ if (options.transition)
920
+ Unit.scope(snapshot, options.transition, { value });
921
+ }
922
+ unit.on('finalize', () => timer.clear());
923
+ }
924
+ }
948
925
 
949
926
  const xnew$1 = Object.assign(function (...args) {
950
927
  if (Unit.rootUnit === undefined)
@@ -961,7 +938,8 @@
961
938
  }
962
939
  const Component = args.shift();
963
940
  const props = args.shift();
964
- return new Unit(Unit.currentUnit, target, Component, props);
941
+ const unit = new Unit(Unit.currentUnit, target, Component, props);
942
+ return unit;
965
943
  }, {
966
944
  /**
967
945
  * Creates a nested HTML/SVG element within the current component
@@ -998,7 +976,8 @@
998
976
  if (Unit.currentUnit._.state !== 'invoked') {
999
977
  throw new Error('xnew.extend can not be called after initialized.');
1000
978
  }
1001
- return Unit.extend(Unit.currentUnit, Component, props);
979
+ const defines = Unit.extend(Unit.currentUnit, Component, props);
980
+ return defines;
1002
981
  }
1003
982
  catch (error) {
1004
983
  console.error('xnew.extend(component: Function, props?: Object): ', error);
@@ -1007,7 +986,7 @@
1007
986
  },
1008
987
  /**
1009
988
  * Gets a context value that can be accessed in follow context
1010
- * @param component - component function
989
+ * @param key - component function
1011
990
  * @returns The context value
1012
991
  * @example
1013
992
  * // Create unit
@@ -1017,12 +996,12 @@
1017
996
  * // Get context in child
1018
997
  * const a = xnew.context(A)
1019
998
  */
1020
- context(component) {
999
+ context(key) {
1021
1000
  try {
1022
- return Unit.context(Unit.currentUnit, component);
1001
+ return Unit.getContext(Unit.currentUnit, key);
1023
1002
  }
1024
1003
  catch (error) {
1025
- console.error('xnew.context(component: Function): ', error);
1004
+ console.error('xnew.context(key: any): ', error);
1026
1005
  throw error;
1027
1006
  }
1028
1007
  },
@@ -1035,16 +1014,17 @@
1035
1014
  */
1036
1015
  promise(promise) {
1037
1016
  try {
1038
- const component = Unit.currentUnit._.currentComponent;
1017
+ const Component = Unit.currentUnit._.currentComponent;
1039
1018
  let unitPromise;
1040
1019
  if (promise instanceof Unit) {
1041
- unitPromise = new UnitPromise(promise._.done.promise, component);
1020
+ unitPromise = new UnitPromise(Promise.all(promise._.promises.map(p => p.promise)), Component)
1021
+ .then(() => promise._.results);
1042
1022
  }
1043
1023
  else if (promise instanceof Promise) {
1044
- unitPromise = new UnitPromise(promise, component);
1024
+ unitPromise = new UnitPromise(promise, Component);
1045
1025
  }
1046
1026
  else {
1047
- unitPromise = new UnitPromise(new Promise(xnew$1.scope(promise)), component);
1027
+ unitPromise = new UnitPromise(new Promise(xnew$1.scope(promise)), Component);
1048
1028
  }
1049
1029
  Unit.currentUnit._.promises.push(unitPromise);
1050
1030
  return unitPromise;
@@ -1063,12 +1043,9 @@
1063
1043
  */
1064
1044
  then(callback) {
1065
1045
  try {
1066
- const Component = Unit.currentUnit._.currentComponent;
1067
- const promises = Unit.currentUnit._.promises;
1068
- return new UnitPromise(Promise.all(promises.map(p => p.promise)), null)
1069
- .then((results) => {
1070
- callback(results.filter((_, index) => promises[index].Component !== null && promises[index].Component === Component));
1071
- });
1046
+ const currentUnit = Unit.currentUnit;
1047
+ return new UnitPromise(Promise.all(Unit.currentUnit._.promises.map(p => p.promise)), null)
1048
+ .then(() => callback(currentUnit._.results));
1072
1049
  }
1073
1050
  catch (error) {
1074
1051
  console.error('xnew.then(callback: Function): ', error);
@@ -1084,8 +1061,7 @@
1084
1061
  */
1085
1062
  catch(callback) {
1086
1063
  try {
1087
- const promises = Unit.currentUnit._.promises;
1088
- return new UnitPromise(Promise.all(promises.map(p => p.promise)), null)
1064
+ return new UnitPromise(Promise.all(Unit.currentUnit._.promises.map(p => p.promise)), null)
1089
1065
  .catch(callback);
1090
1066
  }
1091
1067
  catch (error) {
@@ -1094,36 +1070,18 @@
1094
1070
  }
1095
1071
  },
1096
1072
  /**
1097
- * Resolves the current unit's promise with the given value
1098
- * @param value - Value to resolve the promise with
1073
+ * Commits a value to the current unit's promise results
1074
+ * @param object - object to commit to the promise
1099
1075
  * @returns void
1100
1076
  * @example
1101
- * xnew.resolve('data');
1077
+ * xnew.commit({ data: 123});
1102
1078
  */
1103
- resolve(value) {
1079
+ commit(object) {
1104
1080
  try {
1105
- const done = Unit.currentUnit._.done;
1106
- done.resolve(value);
1081
+ Object.assign(Unit.currentUnit._.results, object);
1107
1082
  }
1108
1083
  catch (error) {
1109
- console.error('xnew.resolve(value?: any): ', error);
1110
- throw error;
1111
- }
1112
- },
1113
- /**
1114
- * Rejects the current unit's promise with the given reason
1115
- * @param reason - Reason to reject the promise
1116
- * @returns void
1117
- * @example
1118
- * xnew.reject(new Error('Something went wrong'));
1119
- */
1120
- reject(reason) {
1121
- try {
1122
- const done = Unit.currentUnit._.done;
1123
- done.reject(reason);
1124
- }
1125
- catch (error) {
1126
- console.error('xnew.reject(reason?: any): ', error);
1084
+ console.error('xnew.commit(object?: Record<string, any>): ', error);
1127
1085
  throw error;
1128
1086
  }
1129
1087
  },
@@ -1136,8 +1094,7 @@
1136
1094
  */
1137
1095
  finally(callback) {
1138
1096
  try {
1139
- const promises = Unit.currentUnit._.promises;
1140
- return new UnitPromise(Promise.all(promises.map(p => p.promise)), null)
1097
+ return new UnitPromise(Promise.all(Unit.currentUnit._.promises.map(p => p.promise)), null)
1141
1098
  .finally(callback);
1142
1099
  }
1143
1100
  catch (error) {
@@ -1160,19 +1117,19 @@
1160
1117
  },
1161
1118
  /**
1162
1119
  * Finds all instances of a component in the component tree
1163
- * @param component - Component function to search for
1120
+ * @param Component - Component function to search for
1164
1121
  * @returns Array of Unit instances matching the component
1165
1122
  * @throws Error if component parameter is invalid
1166
1123
  * @example
1167
1124
  * const buttons = xnew.find(ButtonComponent)
1168
1125
  * buttons.forEach(btn => btn.finalize())
1169
1126
  */
1170
- find(component) {
1127
+ find(Component) {
1171
1128
  try {
1172
- return Unit.find(component);
1129
+ return Unit.find(Component);
1173
1130
  }
1174
1131
  catch (error) {
1175
- console.error('xnew.find(component: Function): ', error);
1132
+ console.error('xnew.find(Component: Function): ', error);
1176
1133
  throw error;
1177
1134
  }
1178
1135
  },
@@ -1428,13 +1385,13 @@
1428
1385
 
1429
1386
  const currentColorA = 'color-mix(in srgb, currentColor 70%, transparent)';
1430
1387
  const currentColorB = 'color-mix(in srgb, currentColor 10%, transparent)';
1431
- function Panel(unit, { name, open = false, params }) {
1388
+ function Panel(unit, { params }) {
1432
1389
  const object = params !== null && params !== void 0 ? params : {};
1433
- xnew$1.extend(Group, { name, open });
1434
1390
  return {
1435
1391
  group({ name, open, params }, inner) {
1436
1392
  const group = xnew$1((unit) => {
1437
- xnew$1.extend(Panel, { name, open, params: params !== null && params !== void 0 ? params : object });
1393
+ xnew$1.extend(Group, { name, open });
1394
+ xnew$1.extend(Panel, { params: params !== null && params !== void 0 ? params : object });
1438
1395
  inner(unit);
1439
1396
  });
1440
1397
  return group;
@@ -1443,23 +1400,23 @@
1443
1400
  const button = xnew$1(Button, { key });
1444
1401
  return button;
1445
1402
  },
1446
- select(key, { options = [] } = {}) {
1403
+ select(key, { value, items = [] } = {}) {
1447
1404
  var _a, _b;
1448
- object[key] = (_b = (_a = object[key]) !== null && _a !== void 0 ? _a : options[0]) !== null && _b !== void 0 ? _b : '';
1449
- const select = xnew$1(Select, { key, value: object[key], options });
1405
+ object[key] = (_b = (_a = value !== null && value !== void 0 ? value : object[key]) !== null && _a !== void 0 ? _a : items[0]) !== null && _b !== void 0 ? _b : '';
1406
+ const select = xnew$1(Select, { key, value: object[key], items });
1450
1407
  select.on('input', ({ value }) => object[key] = value);
1451
1408
  return select;
1452
1409
  },
1453
- range(key, options = {}) {
1454
- var _a, _b;
1455
- object[key] = (_b = (_a = object[key]) !== null && _a !== void 0 ? _a : options.min) !== null && _b !== void 0 ? _b : 0;
1456
- const number = xnew$1(Range, Object.assign({ key, value: object[key] }, options));
1410
+ range(key, { value, min = 0, max = 100, step = 1 } = {}) {
1411
+ var _a;
1412
+ object[key] = (_a = value !== null && value !== void 0 ? value : object[key]) !== null && _a !== void 0 ? _a : min;
1413
+ const number = xnew$1(Range, { key, value: object[key], min, max, step });
1457
1414
  number.on('input', ({ value }) => object[key] = value);
1458
1415
  return number;
1459
1416
  },
1460
- checkbox(key) {
1417
+ checkbox(key, { value } = {}) {
1461
1418
  var _a;
1462
- object[key] = (_a = object[key]) !== null && _a !== void 0 ? _a : false;
1419
+ object[key] = (_a = value !== null && value !== void 0 ? value : object[key]) !== null && _a !== void 0 ? _a : false;
1463
1420
  const checkbox = xnew$1(Checkbox, { key, value: object[key] });
1464
1421
  checkbox.on('input', ({ value }) => object[key] = value);
1465
1422
  return checkbox;
@@ -1476,7 +1433,7 @@
1476
1433
  unit.on('click', () => group.toggle());
1477
1434
  xnew$1('<svg viewBox="0 0 12 12" style="width: 1em; height: 1em; margin-right: 0.25em;" fill="none" stroke="currentColor">', (unit) => {
1478
1435
  xnew$1('<path d="M6 2 10 6 6 10" />');
1479
- group.on('-transition', ({ state }) => unit.element.style.transform = `rotate(${state * 90}deg)`);
1436
+ group.on('-transition', ({ value }) => unit.element.style.transform = `rotate(${value * 90}deg)`);
1480
1437
  });
1481
1438
  xnew$1('<div>', name);
1482
1439
  });
@@ -1543,14 +1500,14 @@
1543
1500
  update(value);
1544
1501
  });
1545
1502
  }
1546
- function Select(_, { key = '', value, options = [] } = {}) {
1503
+ function Select(_, { key = '', value, items = [] } = {}) {
1547
1504
  var _a;
1548
- const initial = (_a = value !== null && value !== void 0 ? value : options[0]) !== null && _a !== void 0 ? _a : '';
1505
+ const initial = (_a = value !== null && value !== void 0 ? value : items[0]) !== null && _a !== void 0 ? _a : '';
1549
1506
  xnew$1.nest(`<div style="position: relative; height: 2em; margin: 0.125em 0; padding: 0 0.5em; display: flex; align-items: center;">`);
1550
1507
  xnew$1('<div style="flex: 1;">', key);
1551
1508
  const native = xnew$1(`<select name="${key}" style="display: none;">`, () => {
1552
- for (const option of options) {
1553
- xnew$1(`<option value="${option}" ${option === initial ? 'selected' : ''}>`, option);
1509
+ for (const item of items) {
1510
+ xnew$1(`<option value="${item}" ${item === initial ? 'selected' : ''}>`, item);
1554
1511
  }
1555
1512
  });
1556
1513
  const button = xnew$1(`<div style="height: 2em; padding: 0 1.5em 0 0.5em; display: flex; align-items: center; border: 1px solid ${currentColorA}; border-radius: 0.25em; cursor: pointer; user-select: none; min-width: 3em; white-space: nowrap;">`, initial);
@@ -1570,13 +1527,13 @@
1570
1527
  });
1571
1528
  xnew$1.extend(Accordion);
1572
1529
  xnew$1.nest(`<div style="position: relative; border: 1px solid ${currentColorA}; border-radius: 0.25em; overflow: hidden;">`);
1573
- for (const option of options) {
1574
- const item = xnew$1(`<div style="height: 2em; padding: 0 0.5em; display: flex; align-items: center; cursor: pointer; user-select: none;">`, option);
1575
- item.on('pointerover', () => item.element.style.background = currentColorB);
1576
- item.on('pointerout', () => item.element.style.background = '');
1577
- item.on('click', () => {
1578
- button.element.textContent = option;
1579
- native.element.value = option;
1530
+ for (const item of items) {
1531
+ const div = xnew$1(`<div style="height: 2em; padding: 0 0.5em; display: flex; align-items: center; cursor: pointer; user-select: none;">`, item);
1532
+ div.on('pointerover', () => div.element.style.background = currentColorB);
1533
+ div.on('pointerout', () => div.element.style.background = '');
1534
+ div.on('click', () => {
1535
+ button.element.textContent = item;
1536
+ native.element.value = item;
1580
1537
  native.element.dispatchEvent(new Event('input', { bubbles: false }));
1581
1538
  list.finalize();
1582
1539
  });
@@ -1599,6 +1556,24 @@
1599
1556
  }
1600
1557
  }
1601
1558
 
1559
+ function Flow(unit) {
1560
+ let scene = null;
1561
+ return {
1562
+ set scene(value) {
1563
+ scene = value;
1564
+ },
1565
+ get scene() {
1566
+ return scene;
1567
+ },
1568
+ next(Component, props) {
1569
+ var _a;
1570
+ // scene change
1571
+ (_a = unit.scene) === null || _a === void 0 ? void 0 : _a.finalize();
1572
+ unit.scene = xnew$1(Component, props);
1573
+ }
1574
+ };
1575
+ }
1576
+
1602
1577
  const context = new window.AudioContext();
1603
1578
  const master = context.createGain();
1604
1579
  //----------------------------------------------------------------------------------------------------
@@ -1831,6 +1806,7 @@
1831
1806
  Panel,
1832
1807
  Accordion,
1833
1808
  Popup,
1809
+ Flow,
1834
1810
  };
1835
1811
  const audio = {
1836
1812
  load(path) {