@coherent.js/nextjs 1.0.0-beta.3 → 1.0.0-beta.5

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.cjs CHANGED
@@ -1,9 +1,7 @@
1
1
  "use strict";
2
- var __create = Object.create;
3
2
  var __defProp = Object.defineProperty;
4
3
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
5
  var __hasOwnProp = Object.prototype.hasOwnProperty;
8
6
  var __export = (target, all) => {
9
7
  for (var name in all)
@@ -17,14 +15,6 @@ var __copyProps = (to, from, except, desc) => {
17
15
  }
18
16
  return to;
19
17
  };
20
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
- // If the importer is in node compatibility mode or this is not an ESM
22
- // file that has been converted to a CommonJS file using a Babel-
23
- // compatible transform (i.e. "__esModule" has not been set), then set
24
- // "default" to the CommonJS "module.exports" for node compatibility.
25
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
- mod
27
- ));
28
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
19
 
30
20
  // src/index.js
@@ -64,6 +54,7 @@ function createPerformanceMonitor(options = {}) {
64
54
  },
65
55
  alerts: {
66
56
  enabled: true,
57
+ debounceMs: 5e3,
67
58
  rules: []
68
59
  },
69
60
  resources: {
@@ -225,7 +216,7 @@ function createPerformanceMonitor(options = {}) {
225
216
  const alertKey = `${rule.metric}-${rule.condition}-${rule.threshold}`;
226
217
  const lastTriggered = alertState.triggered.get(alertKey);
227
218
  const now = Date.now();
228
- if (!lastTriggered || now - lastTriggered > 5e3) {
219
+ if (!lastTriggered || now - lastTriggered > opts.alerts.debounceMs) {
229
220
  alertState.triggered.set(alertKey, now);
230
221
  alertState.history.push({
231
222
  rule,
@@ -515,1951 +506,98 @@ function createPerformanceMonitor(options = {}) {
515
506
  var performanceMonitor2 = createPerformanceMonitor();
516
507
 
517
508
  // ../core/src/core/object-utils.js
518
- function deepClone(obj, seen = /* @__PURE__ */ new WeakMap()) {
519
- if (obj === null || typeof obj !== "object") {
520
- return obj;
521
- }
522
- if (seen.has(obj)) {
523
- return seen.get(obj);
524
- }
525
- if (obj instanceof Date) {
526
- return new Date(obj.getTime());
527
- }
528
- if (obj instanceof RegExp) {
529
- return new RegExp(obj.source, obj.flags);
530
- }
531
- if (Array.isArray(obj)) {
532
- const clonedArray = [];
533
- seen.set(obj, clonedArray);
534
- for (let i = 0; i < obj.length; i++) {
535
- clonedArray[i] = deepClone(obj[i], seen);
536
- }
537
- return clonedArray;
538
- }
539
- if (typeof obj === "function") {
540
- return obj;
541
- }
542
- if (obj instanceof Map) {
543
- const clonedMap = /* @__PURE__ */ new Map();
544
- seen.set(obj, clonedMap);
545
- for (const [key, value] of obj) {
546
- clonedMap.set(deepClone(key, seen), deepClone(value, seen));
547
- }
548
- return clonedMap;
549
- }
550
- if (obj instanceof Set) {
551
- const clonedSet = /* @__PURE__ */ new Set();
552
- seen.set(obj, clonedSet);
553
- for (const value of obj) {
554
- clonedSet.add(deepClone(value, seen));
555
- }
556
- return clonedSet;
557
- }
558
- if (obj instanceof WeakMap) {
559
- return /* @__PURE__ */ new WeakMap();
560
- }
561
- if (obj instanceof WeakSet) {
562
- return /* @__PURE__ */ new WeakSet();
563
- }
564
- const clonedObj = {};
565
- seen.set(obj, clonedObj);
566
- if (obj.constructor && obj.constructor !== Object) {
567
- try {
568
- clonedObj.__proto__ = obj.__proto__;
569
- } catch {
570
- Object.setPrototypeOf(clonedObj, Object.getPrototypeOf(obj));
571
- }
572
- }
573
- for (const key in obj) {
574
- if (obj.hasOwnProperty(key)) {
575
- clonedObj[key] = deepClone(obj[key], seen);
576
- }
577
- }
578
- const descriptors = Object.getOwnPropertyDescriptors(obj);
579
- for (const key of Object.keys(descriptors)) {
580
- if (!descriptors[key].enumerable && descriptors[key].configurable) {
581
- try {
582
- Object.defineProperty(clonedObj, key, {
583
- ...descriptors[key],
584
- value: deepClone(descriptors[key].value, seen)
585
- });
586
- } catch {
587
- }
588
- }
589
- }
590
- return clonedObj;
591
- }
592
- function validateComponent(component, path2 = "root") {
593
- if (component === null || component === void 0) {
594
- throw new Error(`Invalid component at ${path2}: null or undefined`);
595
- }
596
- if (["string", "number", "boolean"].includes(typeof component)) {
597
- return true;
598
- }
599
- if (typeof component === "function") {
600
- return true;
601
- }
602
- if (Array.isArray(component)) {
603
- component.forEach((child, index) => {
604
- validateComponent(child, `${path2}[${index}]`);
605
- });
606
- return true;
607
- }
608
- if (typeof component === "object") {
609
- const keys = Object.keys(component);
610
- if (keys.length === 0) {
611
- throw new Error(`Empty object at ${path2}`);
612
- }
613
- keys.forEach((key) => {
614
- const value = component[key];
615
- if (!/^[a-zA-Z][a-zA-Z0-9-]*$/.test(key) && key !== "text") {
616
- console.warn(`Potentially invalid tag name at ${path2}: ${key}`);
617
- }
618
- if (value && typeof value === "object" && !Array.isArray(value)) {
619
- if (value.children) {
620
- validateComponent(value.children, `${path2}.${key}.children`);
621
- }
622
- } else if (value && typeof value !== "string" && typeof value !== "number" && typeof value !== "function") {
623
- throw new Error(`Invalid value type at ${path2}.${key}: ${typeof value}`);
624
- }
625
- });
626
- return true;
627
- }
628
- throw new Error(`Invalid component type at ${path2}: ${typeof component}`);
629
- }
630
- function isCoherentObject(obj) {
631
- if (!obj || typeof obj !== "object" || Array.isArray(obj)) {
632
- return false;
633
- }
634
- const keys = Object.keys(obj);
635
- if (keys.length === 0) {
636
- return false;
637
- }
638
- return keys.every((key) => {
639
- if (key === "text") return true;
640
- return /^[a-zA-Z][a-zA-Z0-9-]*$/.test(key);
641
- });
642
- }
643
- function extractProps(coherentObj) {
644
- if (!isCoherentObject(coherentObj)) {
645
- return {};
646
- }
647
- const props = {};
648
- const keys = Object.keys(coherentObj);
649
- keys.forEach((tag) => {
650
- const value = coherentObj[tag];
651
- if (value && typeof value === "object" && !Array.isArray(value)) {
652
- props[tag] = { ...value };
653
- } else {
654
- props[tag] = { text: value };
655
- }
656
- });
657
- return props;
658
- }
659
- function hasChildren(component) {
660
- if (Array.isArray(component)) {
661
- return component.length > 0;
662
- }
663
- if (isCoherentObject(component)) {
664
- if (component.children !== void 0 && component.children !== null) {
665
- return Array.isArray(component.children) ? component.children.length > 0 : true;
666
- }
667
- const keys = Object.keys(component);
668
- return keys.some((key) => {
669
- const value = component[key];
670
- return value && typeof value === "object" && value.children;
671
- });
672
- }
673
- return false;
674
- }
675
- function normalizeChildren(children) {
676
- if (children === null || children === void 0) {
677
- return [];
678
- }
679
- if (Array.isArray(children)) {
680
- return children.flat().filter((child) => child !== null && child !== void 0);
681
- }
682
- return [children];
683
- }
684
-
685
- // ../core/src/components/component-system.js
686
- var COMPONENT_METADATA = /* @__PURE__ */ new WeakMap();
687
- var ComponentState = class {
688
- constructor(initialState = {}) {
689
- this.state = { ...initialState };
690
- this.listeners = /* @__PURE__ */ new Set();
691
- this.isUpdating = false;
692
- }
693
- /**
694
- * Get state value by key or entire state
695
- *
696
- * @param {string} [key] - State key to retrieve
697
- * @returns {*} State value or entire state object
698
- */
699
- get(key) {
700
- return key ? this.state[key] : { ...this.state };
701
- }
702
- /**
703
- * Update state with new values
704
- *
705
- * @param {Object} updates - State updates to apply
706
- * @returns {ComponentState} This instance for chaining
707
- */
708
- set(updates) {
709
- if (this.isUpdating) return this;
710
- const oldState = { ...this.state };
711
- if (typeof updates === "function") {
712
- updates = updates(oldState);
713
- }
714
- this.state = { ...this.state, ...updates };
715
- this.notifyListeners(oldState, this.state);
716
- return this;
717
- }
718
- subscribe(listener) {
719
- this.listeners.add(listener);
720
- return () => this.listeners.delete(listener);
721
- }
722
- notifyListeners(oldState, newState) {
723
- if (this.listeners.size === 0) return;
724
- this.isUpdating = true;
725
- this.listeners.forEach((listener) => {
726
- try {
727
- listener(newState, oldState);
728
- } catch (_error) {
729
- console.error("State listener _error:", _error);
730
- }
731
- });
732
- this.isUpdating = false;
733
- }
734
- };
735
- var Component = class _Component {
736
- constructor(definition = {}) {
737
- this.definition = definition;
738
- this.name = definition.name || "AnonymousComponent";
739
- this.props = {};
740
- this.state = new ComponentState(definition.state || {});
741
- this.children = [];
742
- this.parent = null;
743
- this.rendered = null;
744
- this.isMounted = false;
745
- this.isDestroyed = false;
746
- this.hooks = {
747
- beforeCreate: definition.beforeCreate || (() => {
748
- }),
749
- created: definition.created || (() => {
750
- }),
751
- beforeMount: definition.beforeMount || (() => {
752
- }),
753
- mounted: definition.mounted || (() => {
754
- }),
755
- beforeUpdate: definition.beforeUpdate || (() => {
756
- }),
757
- updated: definition.updated || (() => {
758
- }),
759
- beforeDestroy: definition.beforeDestroy || (() => {
760
- }),
761
- destroyed: definition.destroyed || (() => {
762
- }),
763
- errorCaptured: definition.errorCaptured || (() => {
764
- })
765
- };
766
- this.methods = definition.methods || {};
767
- Object.keys(this.methods).forEach((methodName) => {
768
- if (typeof this.methods[methodName] === "function") {
769
- this[methodName] = this.methods[methodName].bind(this);
770
- }
771
- });
772
- this.computed = definition.computed || {};
773
- this.computedCache = /* @__PURE__ */ new Map();
774
- this.watchers = definition.watch || {};
775
- this.setupWatchers();
776
- COMPONENT_METADATA.set(this, {
777
- createdAt: Date.now(),
778
- updateCount: 0,
779
- renderCount: 0
780
- });
781
- this.callHook("beforeCreate");
782
- this.initialize();
783
- this.callHook("created");
784
- }
785
- /**
786
- * Initialize component
787
- */
788
- initialize() {
789
- this.unsubscribeState = this.state.subscribe((newState, oldState) => {
790
- this.onStateChange(newState, oldState);
791
- });
792
- this.initializeComputed();
793
- }
794
- /**
795
- * Set up watchers for reactive data
796
- */
797
- setupWatchers() {
798
- Object.keys(this.watchers).forEach((key) => {
799
- const handler = this.watchers[key];
800
- this.state.subscribe((newState, oldState) => {
801
- if (newState[key] !== oldState[key]) {
802
- handler.call(this, newState[key], oldState[key]);
803
- }
804
- });
805
- });
806
- }
807
- /**
808
- * Initialize computed properties
809
- */
810
- initializeComputed() {
811
- Object.keys(this.computed).forEach((key) => {
812
- Object.defineProperty(this, key, {
813
- get: () => {
814
- if (!this.computedCache.has(key)) {
815
- const value = this.computed[key].call(this);
816
- this.computedCache.set(key, value);
817
- }
818
- return this.computedCache.get(key);
819
- },
820
- enumerable: true
821
- });
822
- });
823
- }
824
- /**
825
- * Handle state changes
826
- */
827
- onStateChange() {
828
- if (this.isDestroyed) return;
829
- this.computedCache.clear();
830
- if (this.isMounted) {
831
- this.update();
832
- }
833
- }
834
- /**
835
- * Call lifecycle hook
836
- */
837
- callHook(hookName, ...args) {
838
- try {
839
- if (this.hooks[hookName]) {
840
- return this.hooks[hookName].call(this, ...args);
841
- }
842
- } catch (_error) {
843
- this.handleError(_error, `${hookName} hook`);
844
- }
845
- }
846
- /**
847
- * Handle component errors
848
- */
849
- handleError(_error) {
850
- console.error(`Component Error in ${this.name}:`, _error);
851
- this.callHook("errorCaptured", _error);
852
- if (this.parent && this.parent.handleError) {
853
- this.parent.handleError(_error, `${this.name} -> ${context}`);
854
- }
855
- }
856
- /**
857
- * Render the component
858
- */
859
- render(props = {}) {
860
- if (this.isDestroyed) {
861
- console.warn(`Attempting to render destroyed component: ${this.name}`);
862
- return null;
863
- }
864
- try {
865
- const metadata = COMPONENT_METADATA.get(this);
866
- if (metadata) {
867
- metadata.renderCount++;
868
- }
869
- this.props = { ...props };
870
- if (typeof this.definition.render === "function") {
871
- this.rendered = this.definition.render.call(this, this.props, this.state.get());
872
- } else if (typeof this.definition.template !== "undefined") {
873
- this.rendered = this.processTemplate(this.definition.template, this.props, this.state.get());
874
- } else {
875
- throw new Error(`Component ${this.name} must have either render method or template`);
876
- }
877
- if (this.rendered !== null) {
878
- validateComponent(this.rendered, this.name);
879
- }
880
- return this.rendered;
881
- } catch (_error) {
882
- this.handleError(_error);
883
- return { div: { className: "component-_error", text: `Error in ${this.name}` } };
884
- }
885
- }
886
- /**
887
- * Process template with data
888
- */
889
- processTemplate(template, props, state) {
890
- if (typeof template === "function") {
891
- return template.call(this, props, state);
892
- }
893
- if (typeof template === "string") {
894
- return template.replace(/\{\{(\w+)\}\}/g, (match, key) => {
895
- return props[key] || state[key] || "";
896
- });
897
- }
898
- const processed = deepClone(template);
899
- this.interpolateObject(processed, { ...props, ...state });
900
- return processed;
901
- }
902
- /**
903
- * Interpolate object with data
904
- */
905
- interpolateObject(obj, data) {
906
- if (typeof obj === "string") {
907
- return obj.replace(/\{\{(\w+)\}\}/g, (match, key) => data[key] || "");
908
- }
909
- if (Array.isArray(obj)) {
910
- return obj.map((item) => this.interpolateObject(item, data));
911
- }
912
- if (obj && typeof obj === "object") {
913
- Object.keys(obj).forEach((key) => {
914
- obj[key] = this.interpolateObject(obj[key], data);
915
- });
916
- }
917
- return obj;
918
- }
919
- /**
920
- * Mount the component
921
- */
922
- mount() {
923
- if (this.isMounted || this.isDestroyed) return this;
924
- this.callHook("beforeMount");
925
- this.isMounted = true;
926
- this.callHook("mounted");
927
- return this;
928
- }
929
- /**
930
- * Update the component
931
- */
932
- update() {
933
- if (!this.isMounted || this.isDestroyed) return this;
934
- const metadata = COMPONENT_METADATA.get(this);
935
- if (metadata) {
936
- metadata.updateCount++;
937
- }
938
- this.callHook("beforeUpdate");
939
- this.callHook("updated");
940
- return this;
941
- }
942
- /**
943
- * Destroy the component
944
- */
945
- destroy() {
946
- if (this.isDestroyed) return this;
947
- this.callHook("beforeDestroy");
948
- if (this.unsubscribeState) {
949
- this.unsubscribeState();
950
- }
951
- this.children.forEach((child) => {
952
- if (child.destroy) {
953
- child.destroy();
954
- }
955
- });
956
- this.isMounted = false;
957
- this.isDestroyed = true;
958
- this.children = [];
959
- this.parent = null;
960
- this.callHook("destroyed");
961
- return this;
962
- }
963
- /**
964
- * Get component metadata
965
- */
966
- getMetadata() {
967
- return COMPONENT_METADATA.get(this) || {};
968
- }
969
- /**
970
- * Clone component with new props/state
971
- */
972
- clone(overrides = {}) {
973
- const newDefinition = { ...this.definition, ...overrides };
974
- return new _Component(newDefinition);
975
- }
976
- };
977
- if (performanceMonitor2) {
978
- const originalRender = Component.prototype.render;
979
- Component.prototype.render = function(...args) {
980
- const start = performance.now();
981
- const result = originalRender.apply(this, args);
982
- const duration = performance.now() - start;
983
- performanceMonitor2.recordMetric("renderTime", duration, {
984
- type: "component",
985
- name: this.name,
986
- propsSize: JSON.stringify(this.props || {}).length,
987
- hasState: Object.keys(this.state?.get() || {}).length > 0
988
- });
989
- return result;
990
- };
991
- }
992
-
993
- // ../core/src/utils/error-handler.js
994
- var CoherentError = class _CoherentError extends Error {
995
- constructor(message, options = {}) {
996
- super(message);
997
- this.name = "CoherentError";
998
- this.type = options.type || "generic";
999
- this.component = options.component;
1000
- this.context = options.context;
1001
- this.suggestions = options.suggestions || [];
1002
- this.timestamp = Date.now();
1003
- if (Error.captureStackTrace) {
1004
- Error.captureStackTrace(this, _CoherentError);
1005
- }
1006
- }
1007
- toJSON() {
1008
- return {
1009
- name: this.name,
1010
- message: this.message,
1011
- type: this.type,
1012
- component: this.component,
1013
- context: this.context,
1014
- suggestions: this.suggestions,
1015
- timestamp: this.timestamp,
1016
- stack: this.stack
1017
- };
1018
- }
1019
- };
1020
- var ComponentValidationError = class extends CoherentError {
1021
- constructor(message, component, suggestions = []) {
1022
- super(message, {
1023
- type: "validation",
1024
- component,
1025
- suggestions: [
1026
- "Check component structure and syntax",
1027
- "Ensure all required properties are present",
1028
- "Validate prop types and values",
1029
- ...suggestions
1030
- ]
1031
- });
1032
- this.name = "ComponentValidationError";
1033
- }
1034
- };
1035
- var RenderingError = class extends CoherentError {
1036
- constructor(message, component, context2, suggestions = []) {
1037
- super(message, {
1038
- type: "rendering",
1039
- component,
1040
- context: context2,
1041
- suggestions: [
1042
- "Check for circular references",
1043
- "Validate component depth",
1044
- "Ensure all functions return valid components",
1045
- ...suggestions
1046
- ]
1047
- });
1048
- this.name = "RenderingError";
1049
- }
1050
- };
1051
- var PerformanceError = class extends CoherentError {
1052
- constructor(message, metrics, suggestions = []) {
1053
- super(message, {
1054
- type: "performance",
1055
- context: metrics,
1056
- suggestions: [
1057
- "Consider component memoization",
1058
- "Reduce component complexity",
1059
- "Enable caching",
1060
- ...suggestions
1061
- ]
1062
- });
1063
- this.name = "PerformanceError";
1064
- }
1065
- };
1066
- var StateError = class extends CoherentError {
1067
- constructor(message, state, suggestions = []) {
1068
- super(message, {
1069
- type: "state",
1070
- context: state,
1071
- suggestions: [
1072
- "Check state mutations",
1073
- "Ensure proper state initialization",
1074
- "Validate state transitions",
1075
- ...suggestions
1076
- ]
1077
- });
1078
- this.name = "StateError";
1079
- }
1080
- };
1081
- var ErrorHandler = class {
1082
- constructor(options = {}) {
1083
- this.options = {
1084
- enableStackTrace: options.enableStackTrace !== false,
1085
- enableSuggestions: options.enableSuggestions !== false,
1086
- enableLogging: options.enableLogging !== false,
1087
- logLevel: options.logLevel || "_error",
1088
- maxErrorHistory: options.maxErrorHistory || 100,
1089
- ...options
1090
- };
1091
- this.errorHistory = [];
1092
- this.errorCounts = /* @__PURE__ */ new Map();
1093
- this.suppressedErrors = /* @__PURE__ */ new Set();
1094
- }
1095
- /**
1096
- * Handle and report errors with detailed context
1097
- */
1098
- handle(_error, context2 = {}) {
1099
- const enhancedError = this.enhanceError(_error, context2);
1100
- this.addToHistory(enhancedError);
1101
- if (this.options.enableLogging) {
1102
- this.logError(enhancedError);
1103
- }
1104
- return enhancedError;
1105
- }
1106
- /**
1107
- * Enhance existing errors with more context
1108
- */
1109
- enhanceError(_error, context2 = {}) {
1110
- if (_error instanceof CoherentError) {
1111
- return _error;
1112
- }
1113
- const errorType = this.classifyError(_error, context2);
1114
- switch (errorType) {
1115
- case "validation":
1116
- return new ComponentValidationError(
1117
- _error.message,
1118
- context2.component,
1119
- this.generateSuggestions(_error, context2)
1120
- );
1121
- case "rendering":
1122
- return new RenderingError(
1123
- _error.message,
1124
- context2.component,
1125
- context2.renderContext,
1126
- this.generateSuggestions(_error, context2)
1127
- );
1128
- case "performance":
1129
- return new PerformanceError(
1130
- _error.message,
1131
- context2.metrics,
1132
- this.generateSuggestions(_error, context2)
1133
- );
1134
- case "state":
1135
- return new StateError(
1136
- _error.message,
1137
- context2.state,
1138
- this.generateSuggestions(_error, context2)
1139
- );
1140
- default:
1141
- return new CoherentError(_error.message, {
1142
- type: errorType,
1143
- component: context2.component,
1144
- context: context2.context,
1145
- suggestions: this.generateSuggestions(_error, context2)
1146
- });
1147
- }
1148
- }
1149
- /**
1150
- * Classify _error type based on message and context
1151
- */
1152
- classifyError(_error, context2) {
1153
- const message = _error.message.toLowerCase();
1154
- if (message.includes("invalid") || message.includes("validation") || message.includes("required") || message.includes("type")) {
1155
- return "validation";
1156
- }
1157
- if (message.includes("render") || message.includes("circular") || message.includes("depth") || message.includes("cannot render")) {
1158
- return "rendering";
1159
- }
1160
- if (message.includes("slow") || message.includes("memory") || message.includes("performance") || message.includes("timeout")) {
1161
- return "performance";
1162
- }
1163
- if (message.includes("state") || message.includes("mutation") || message.includes("store") || context2.state) {
1164
- return "state";
1165
- }
1166
- if (context2.component) return "validation";
1167
- if (context2.renderContext) return "rendering";
1168
- if (context2.metrics) return "performance";
1169
- return "generic";
1170
- }
1171
- /**
1172
- * Generate helpful suggestions based on _error
1173
- */
1174
- generateSuggestions(_error, context2 = {}) {
1175
- const suggestions = [];
1176
- const message = _error.message.toLowerCase();
1177
- const patterns = [
1178
- {
1179
- pattern: /cannot render|render.*failed/,
1180
- suggestions: [
1181
- "Check if component returns a valid object structure",
1182
- "Ensure all properties are properly defined",
1183
- "Look for undefined variables or null references"
1184
- ]
1185
- },
1186
- {
1187
- pattern: /circular.*reference/,
1188
- suggestions: [
1189
- "Remove circular references between components",
1190
- "Use lazy loading or memoization to break cycles",
1191
- "Check for self-referencing components"
1192
- ]
1193
- },
1194
- {
1195
- pattern: /maximum.*depth/,
1196
- suggestions: [
1197
- "Reduce component nesting depth",
1198
- "Break complex components into smaller parts",
1199
- "Check for infinite recursion in component functions"
1200
- ]
1201
- },
1202
- {
1203
- pattern: /invalid.*component/,
1204
- suggestions: [
1205
- "Ensure component follows the expected object structure",
1206
- "Check property names and values for typos",
1207
- "Verify component is not null or undefined"
1208
- ]
1209
- },
1210
- {
1211
- pattern: /performance|slow|timeout/,
1212
- suggestions: [
1213
- "Enable component caching",
1214
- "Use memoization for expensive operations",
1215
- "Reduce component complexity",
1216
- "Consider lazy loading for large components"
1217
- ]
1218
- }
1219
- ];
1220
- patterns.forEach(({ pattern, suggestions: patternSuggestions }) => {
1221
- if (pattern.test(message)) {
1222
- suggestions.push(...patternSuggestions);
1223
- }
1224
- });
1225
- if (context2.component) {
1226
- const componentType = typeof context2.component;
1227
- if (componentType === "function") {
1228
- suggestions.push("Check function component return value");
1229
- } else if (componentType === "object" && context2.component === null) {
1230
- suggestions.push("Component is null - ensure proper initialization");
1231
- } else if (Array.isArray(context2.component)) {
1232
- suggestions.push("Arrays should contain valid component objects");
1233
- }
1234
- }
1235
- if (suggestions.length === 0) {
1236
- suggestions.push(
1237
- "Enable development tools for more detailed debugging",
1238
- "Check browser console for additional _error details",
1239
- "Use component validation tools to identify issues"
1240
- );
1241
- }
1242
- return [...new Set(suggestions)];
1243
- }
1244
- /**
1245
- * Add _error to history with deduplication
1246
- */
1247
- addToHistory(_error) {
1248
- const errorKey = `${_error.name}:${_error.message}`;
1249
- this.errorCounts.set(errorKey, (this.errorCounts.get(errorKey) || 0) + 1);
1250
- const historyEntry = {
1251
- ..._error.toJSON(),
1252
- count: this.errorCounts.get(errorKey),
1253
- firstSeen: this.errorHistory.find((e) => e.key === errorKey)?.firstSeen || _error.timestamp,
1254
- key: errorKey
1255
- };
1256
- this.errorHistory = this.errorHistory.filter((e) => e.key !== errorKey);
1257
- this.errorHistory.unshift(historyEntry);
1258
- if (this.errorHistory.length > this.options.maxErrorHistory) {
1259
- this.errorHistory = this.errorHistory.slice(0, this.options.maxErrorHistory);
1260
- }
1261
- }
1262
- /**
1263
- * Log _error with enhanced formatting
1264
- */
1265
- logError(_error) {
1266
- if (this.suppressedErrors.has(`${_error.name}:${_error.message}`)) {
1267
- return;
1268
- }
1269
- const isRepeated = this.errorCounts.get(`${_error.name}:${_error.message}`) > 1;
1270
- const errorGroup = `\u{1F6A8} ${_error.name}${isRepeated ? ` (\xD7${this.errorCounts.get(`${_error.name}:${_error.message}`)})` : ""}`;
1271
- console.group(errorGroup);
1272
- console.error(`\u274C ${_error.message}`);
1273
- if (_error.component) {
1274
- console.log("\u{1F50D} Component:", this.formatComponent(_error.component));
1275
- }
1276
- if (_error.context) {
1277
- console.log("\u{1F4CB} Context:", _error.context);
1278
- }
1279
- if (this.options.enableSuggestions && _error.suggestions.length > 0) {
1280
- console.group("\u{1F4A1} Suggestions:");
1281
- _error.suggestions.forEach((suggestion, index) => {
1282
- console.log(`${index + 1}. ${suggestion}`);
1283
- });
1284
- console.groupEnd();
1285
- }
1286
- if (this.options.enableStackTrace && _error.stack) {
1287
- console.log("\u{1F4DA} Stack trace:", _error.stack);
1288
- }
1289
- console.groupEnd();
1290
- }
1291
- /**
1292
- * Format component for logging
1293
- */
1294
- formatComponent(component, maxDepth = 2, currentDepth = 0) {
1295
- if (currentDepth > maxDepth) {
1296
- return "[...deep]";
1297
- }
1298
- if (typeof component === "function") {
1299
- return `[Function: ${component.name || "anonymous"}]`;
1300
- }
1301
- if (Array.isArray(component)) {
1302
- return component.slice(0, 3).map(
1303
- (item) => this.formatComponent(item, maxDepth, currentDepth + 1)
1304
- );
1305
- }
1306
- if (component && typeof component === "object") {
1307
- const formatted = {};
1308
- const keys = Object.keys(component).slice(0, 5);
1309
- for (const key of keys) {
1310
- if (key === "children" && component[key]) {
1311
- formatted[key] = this.formatComponent(component[key], maxDepth, currentDepth + 1);
1312
- } else {
1313
- formatted[key] = component[key];
1314
- }
1315
- }
1316
- if (Object.keys(component).length > 5) {
1317
- formatted["..."] = `(${Object.keys(component).length - 5} more)`;
1318
- }
1319
- return formatted;
1320
- }
1321
- return component;
1322
- }
1323
- /**
1324
- * Suppress specific _error types
1325
- */
1326
- suppress(errorPattern) {
1327
- this.suppressedErrors.add(errorPattern);
1328
- }
1329
- /**
1330
- * Clear _error history
1331
- */
1332
- clearHistory() {
1333
- this.errorHistory = [];
1334
- this.errorCounts.clear();
1335
- }
1336
- /**
1337
- * Get _error statistics
1338
- */
1339
- getStats() {
1340
- const errorsByType = {};
1341
- const errorsByTime = {};
1342
- this.errorHistory.forEach((_error) => {
1343
- errorsByType[_error.type] = (errorsByType[_error.type] || 0) + _error.count;
1344
- const hour = new Date(_error.timestamp).toISOString().slice(0, 13);
1345
- errorsByTime[hour] = (errorsByTime[hour] || 0) + _error.count;
1346
- });
1347
- return {
1348
- totalErrors: this.errorHistory.reduce((sum, e) => sum + e.count, 0),
1349
- uniqueErrors: this.errorHistory.length,
1350
- errorsByType,
1351
- errorsByTime,
1352
- mostCommonErrors: this.getMostCommonErrors(5),
1353
- recentErrors: this.errorHistory.slice(0, 10)
1354
- };
1355
- }
1356
- /**
1357
- * Get most common errors
1358
- */
1359
- getMostCommonErrors(limit = 10) {
1360
- return this.errorHistory.sort((a, b) => b.count - a.count).slice(0, limit).map(({ name, message, count, type }) => ({
1361
- name,
1362
- message,
1363
- count,
1364
- type
1365
- }));
1366
- }
1367
- };
1368
- var globalErrorHandler = new ErrorHandler();
1369
-
1370
- // ../core/src/components/lifecycle.js
1371
- var LIFECYCLE_PHASES = {
1372
- BEFORE_CREATE: "beforeCreate",
1373
- CREATED: "created",
1374
- BEFORE_MOUNT: "beforeMount",
1375
- MOUNTED: "mounted",
1376
- BEFORE_UPDATE: "beforeUpdate",
1377
- UPDATED: "updated",
1378
- BEFORE_UNMOUNT: "beforeUnmount",
1379
- UNMOUNTED: "unmounted",
1380
- ERROR: "_error"
1381
- };
1382
- var componentInstances = /* @__PURE__ */ new WeakMap();
1383
- var ComponentEventSystem = class {
1384
- constructor() {
1385
- this.events = /* @__PURE__ */ new Map();
1386
- this.globalHandlers = /* @__PURE__ */ new Map();
1387
- }
1388
- /**
1389
- * Emit event to component or globally
1390
- */
1391
- emit(eventName, data = {}, target = null) {
1392
- const event = {
1393
- name: eventName,
1394
- data,
1395
- target,
1396
- timestamp: Date.now(),
1397
- stopped: false,
1398
- preventDefault: false
1399
- };
1400
- if (target) {
1401
- const instance = componentInstances.get(target);
1402
- if (instance) {
1403
- this._notifyHandlers(instance.id, event);
1404
- }
1405
- } else {
1406
- this._notifyGlobalHandlers(event);
1407
- }
1408
- return event;
1409
- }
1410
- /**
1411
- * Listen for events on component or globally
1412
- */
1413
- on(eventName, handler, componentId = null) {
1414
- if (componentId) {
1415
- if (!this.events.has(componentId)) {
1416
- this.events.set(componentId, /* @__PURE__ */ new Map());
1417
- }
1418
- const componentEvents = this.events.get(componentId);
1419
- if (!componentEvents.has(eventName)) {
1420
- componentEvents.set(eventName, /* @__PURE__ */ new Set());
1421
- }
1422
- componentEvents.get(eventName).add(handler);
1423
- } else {
1424
- if (!this.globalHandlers.has(eventName)) {
1425
- this.globalHandlers.set(eventName, /* @__PURE__ */ new Set());
1426
- }
1427
- this.globalHandlers.get(eventName).add(handler);
1428
- }
1429
- return () => this.off(eventName, handler, componentId);
1430
- }
1431
- /**
1432
- * Remove event handler
1433
- */
1434
- off(eventName, handler, componentId = null) {
1435
- if (componentId) {
1436
- const componentEvents = this.events.get(componentId);
1437
- if (componentEvents && componentEvents.has(eventName)) {
1438
- componentEvents.get(eventName).delete(handler);
1439
- if (componentEvents.get(eventName).size === 0) {
1440
- componentEvents.delete(eventName);
1441
- if (componentEvents.size === 0) {
1442
- this.events.delete(componentId);
1443
- }
1444
- }
1445
- }
1446
- } else {
1447
- const handlers = this.globalHandlers.get(eventName);
1448
- if (handlers) {
1449
- handlers.delete(handler);
1450
- if (handlers.size === 0) {
1451
- this.globalHandlers.delete(eventName);
1452
- }
1453
- }
1454
- }
1455
- }
1456
- /**
1457
- * Listen once
1458
- */
1459
- once(eventName, handler, componentId = null) {
1460
- const onceHandler = (event) => {
1461
- handler(event);
1462
- this.off(eventName, onceHandler, componentId);
1463
- };
1464
- return this.on(eventName, onceHandler, componentId);
1465
- }
1466
- /**
1467
- * Notify component handlers
1468
- */
1469
- _notifyHandlers(componentId, event) {
1470
- const componentEvents = this.events.get(componentId);
1471
- if (componentEvents && componentEvents.has(event.name)) {
1472
- const handlers = componentEvents.get(event.name);
1473
- for (const handler of handlers) {
1474
- if (event.stopped) break;
1475
- try {
1476
- handler(event);
1477
- } catch (_error) {
1478
- globalErrorHandler.handle(_error, {
1479
- type: "event-handler-_error",
1480
- context: { event, handler: handler.toString() }
1481
- });
1482
- }
1483
- }
1484
- }
1485
- }
1486
- /**
1487
- * Notify global handlers
1488
- */
1489
- _notifyGlobalHandlers(event) {
1490
- const handlers = this.globalHandlers.get(event.name);
1491
- if (handlers) {
1492
- for (const handler of handlers) {
1493
- if (event.stopped) break;
1494
- try {
1495
- handler(event);
1496
- } catch (_error) {
1497
- globalErrorHandler.handle(_error, {
1498
- type: "global-event-handler-_error",
1499
- context: { event, handler: handler.toString() }
1500
- });
1501
- }
1502
- }
1503
- }
1504
- }
1505
- /**
1506
- * Clean up events for a component
1507
- */
1508
- cleanup(componentId) {
1509
- this.events.delete(componentId);
1510
- }
1511
- /**
1512
- * Get event statistics
1513
- */
1514
- getStats() {
1515
- return {
1516
- componentEvents: this.events.size,
1517
- globalEvents: this.globalHandlers.size,
1518
- totalHandlers: Array.from(this.events.values()).reduce((sum, events) => {
1519
- return sum + Array.from(events.values()).reduce((eventSum, handlers) => {
1520
- return eventSum + handlers.size;
1521
- }, 0);
1522
- }, 0) + Array.from(this.globalHandlers.values()).reduce((sum, handlers) => {
1523
- return sum + handlers.size;
1524
- }, 0)
1525
- };
1526
- }
1527
- };
1528
- var eventSystem = new ComponentEventSystem();
1529
- function createLifecycleHooks() {
1530
- const hooks = {};
1531
- Object.values(LIFECYCLE_PHASES).forEach((phase) => {
1532
- hooks[phase] = (callback) => {
1533
- const instance = getCurrentInstance();
1534
- if (instance) {
1535
- instance.hook(phase, callback);
1536
- }
1537
- };
1538
- });
1539
- return hooks;
1540
- }
1541
- var currentInstance = null;
1542
- function getCurrentInstance() {
1543
- return currentInstance;
1544
- }
1545
- var useHooks = createLifecycleHooks();
1546
-
1547
- // ../core/src/events/event-bus.js
1548
- function throttle(func, delay) {
1549
- let lastCall = 0;
1550
- let timeoutId = null;
1551
- return function throttled(...args) {
1552
- const now = Date.now();
1553
- const timeSinceLastCall = now - lastCall;
1554
- if (timeSinceLastCall >= delay) {
1555
- lastCall = now;
1556
- return func.apply(this, args);
1557
- } else {
1558
- if (timeoutId) clearTimeout(timeoutId);
1559
- timeoutId = setTimeout(() => {
1560
- lastCall = Date.now();
1561
- func.apply(this, args);
1562
- }, delay - timeSinceLastCall);
1563
- }
1564
- };
1565
- }
1566
- var EventBus = class {
1567
- constructor(options = {}) {
1568
- this.listeners = /* @__PURE__ */ new Map();
1569
- this.handlers = /* @__PURE__ */ new Map();
1570
- this.actionHandlers = /* @__PURE__ */ new Map();
1571
- this.middleware = [];
1572
- this.throttledEmitters = /* @__PURE__ */ new Map();
1573
- this.debouncedEmitters = /* @__PURE__ */ new Map();
1574
- this.options = {
1575
- debug: false,
1576
- performance: true,
1577
- maxListeners: 100,
1578
- enableWildcards: true,
1579
- enableAsync: true,
1580
- wildcardSeparator: ":",
1581
- enablePriority: true,
1582
- defaultPriority: 0,
1583
- errorHandler: null,
1584
- filters: {
1585
- allowList: null,
1586
- // null means allow all
1587
- blockList: []
1588
- },
1589
- throttle: {
1590
- enabled: false,
1591
- defaultDelay: 100,
1592
- events: {}
1593
- },
1594
- batching: {
1595
- enabled: false,
1596
- maxBatchSize: 10,
1597
- flushInterval: 16
1598
- },
1599
- ...options
1600
- };
1601
- this.stats = {
1602
- eventsEmitted: 0,
1603
- listenersExecuted: 0,
1604
- errorsOccurred: 0,
1605
- averageEmitTime: 0,
1606
- throttledEvents: 0,
1607
- filteredEvents: 0
1608
- };
1609
- if (this.options.batching.enabled) {
1610
- this.batchQueue = [];
1611
- this.batchTimer = null;
1612
- }
1613
- if (this.options.debug) {
1614
- this.use((event, data, next) => {
1615
- console.log(`[EventBus] ${event}:`, data);
1616
- next();
1617
- });
1618
- }
1619
- }
1620
- /**
1621
- * Add middleware
1622
- */
1623
- use(middleware) {
1624
- if (typeof middleware !== "function") {
1625
- throw new Error("Middleware must be a function");
1626
- }
1627
- this.middleware.push(middleware);
1628
- return this;
1629
- }
1630
- /**
1631
- * Check if event passes filters
1632
- */
1633
- passesFilters(event) {
1634
- const { allowList, blockList } = this.options.filters;
1635
- if (blockList && blockList.length > 0) {
1636
- for (const pattern of blockList) {
1637
- if (this.matchPattern(pattern, event)) {
1638
- this.stats.filteredEvents++;
1639
- return false;
1640
- }
1641
- }
1642
- }
1643
- if (allowList && allowList.length > 0) {
1644
- for (const pattern of allowList) {
1645
- if (this.matchPattern(pattern, event)) {
1646
- return true;
1647
- }
1648
- }
1649
- this.stats.filteredEvents++;
1650
- return false;
1651
- }
1652
- return true;
1653
- }
1654
- /**
1655
- * Match event against pattern
1656
- */
1657
- matchPattern(pattern, event) {
1658
- const sep = this.options.wildcardSeparator;
1659
- const patternParts = pattern.split(sep);
1660
- const eventParts = event.split(sep);
1661
- if (pattern.includes("*")) {
1662
- if (patternParts.length !== eventParts.length) {
1663
- return false;
1664
- }
1665
- return patternParts.every((part, i) => part === "*" || part === eventParts[i]);
1666
- }
1667
- return pattern === event;
1668
- }
1669
- /**
1670
- * Emit an event
1671
- */
1672
- async emit(event, data = null) {
1673
- if (!this.passesFilters(event)) {
1674
- if (this.options.debug) {
1675
- console.warn(`[EventBus] Event filtered: ${event}`);
1676
- }
1677
- return;
1678
- }
1679
- if (this.options.batching.enabled) {
1680
- return this.addToBatch(event, data);
1681
- }
1682
- if (this.options.throttle.enabled) {
1683
- const throttleDelay = this.options.throttle.events && this.options.throttle.events[event] || this.options.throttle.defaultDelay;
1684
- if (throttleDelay > 0) {
1685
- return this.emitThrottled(event, data, throttleDelay);
1686
- }
1687
- }
1688
- return this.emitImmediate(event, data);
1689
- }
1690
- /**
1691
- * Emit immediately without throttling
1692
- */
1693
- async emitImmediate(event, data = null) {
1694
- const startTime = this.options.performance ? performance.now() : 0;
1695
- try {
1696
- await this.runMiddleware(event, data);
1697
- const listeners = this.getEventListeners(event);
1698
- if (listeners.length === 0) {
1699
- if (this.options.debug) {
1700
- console.warn(`[EventBus] No listeners for event: ${event}`);
1701
- }
1702
- return;
1703
- }
1704
- const promises = listeners.map(
1705
- (listenerObj) => this.executeListener(listenerObj.listener, event, data, listenerObj.options)
1706
- );
1707
- if (this.options.enableAsync) {
1708
- await Promise.allSettled(promises);
1709
- } else {
1710
- for (const promise of promises) {
1711
- await promise;
1712
- }
1713
- }
1714
- this.stats.eventsEmitted++;
1715
- this.stats.listenersExecuted += listeners.length;
1716
- } catch (error) {
1717
- this.stats.errorsOccurred++;
1718
- this.handleError(error, event, data);
1719
- } finally {
1720
- if (this.options.performance) {
1721
- const duration = performance.now() - startTime;
1722
- this.updatePerformanceStats(duration);
1723
- }
1724
- }
1725
- }
1726
- /**
1727
- * Emit with throttling
1728
- */
1729
- emitThrottled(event, data, delay) {
1730
- if (!this.throttledEmitters.has(event)) {
1731
- const throttled = throttle((evt, d) => this.emitImmediate(evt, d), delay);
1732
- this.throttledEmitters.set(event, throttled);
1733
- }
1734
- this.stats.throttledEvents++;
1735
- return this.throttledEmitters.get(event)(event, data);
1736
- }
1737
- /**
1738
- * Add event to batch queue
1739
- */
1740
- addToBatch(event, data) {
1741
- this.batchQueue.push({ event, data, timestamp: Date.now() });
1742
- if (this.batchQueue.length >= this.options.batching.maxBatchSize) {
1743
- this.flushBatch();
1744
- } else if (!this.batchTimer) {
1745
- this.batchTimer = setTimeout(() => {
1746
- this.flushBatch();
1747
- }, this.options.batching.flushInterval);
1748
- }
1749
- }
1750
- /**
1751
- * Flush batch queue
1752
- */
1753
- async flushBatch() {
1754
- if (this.batchTimer) {
1755
- clearTimeout(this.batchTimer);
1756
- this.batchTimer = null;
1757
- }
1758
- const batch = this.batchQueue.splice(0);
1759
- for (const { event, data } of batch) {
1760
- await this.emitImmediate(event, data);
1761
- }
1762
- }
1763
- /**
1764
- * Register event listener with options
1765
- */
1766
- on(event, listener, options = {}) {
1767
- if (typeof listener !== "function") {
1768
- throw new Error("Listener must be a function");
1769
- }
1770
- if (!this.listeners.has(event)) {
1771
- this.listeners.set(event, []);
1772
- }
1773
- const listeners = this.listeners.get(event);
1774
- if (listeners.length >= this.options.maxListeners) {
1775
- console.warn(`[EventBus] Max listeners (${this.options.maxListeners}) reached for event: ${event}`);
1776
- }
1777
- const listenerId = this.generateListenerId(event);
1778
- const listenerObj = {
1779
- listener,
1780
- listenerId,
1781
- priority: options.priority !== void 0 ? options.priority : this.options.defaultPriority,
1782
- condition: options.condition || null,
1783
- timeout: options.timeout || null,
1784
- options
1785
- };
1786
- listener.__listenerId = listenerId;
1787
- listener.__event = event;
1788
- if (this.options.enablePriority) {
1789
- const insertIndex = listeners.findIndex((l) => l.priority < listenerObj.priority);
1790
- if (insertIndex === -1) {
1791
- listeners.push(listenerObj);
1792
- } else {
1793
- listeners.splice(insertIndex, 0, listenerObj);
1794
- }
1795
- } else {
1796
- listeners.push(listenerObj);
1797
- }
1798
- return listenerId;
1799
- }
1800
- /**
1801
- * Register one-time listener
1802
- */
1803
- once(event, listener, options = {}) {
1804
- const onceListener = (...args) => {
1805
- this.off(event, onceListener.__listenerId);
1806
- return listener.call(this, ...args);
1807
- };
1808
- if (options.timeout) {
1809
- const timeoutId = setTimeout(() => {
1810
- this.off(event, onceListener.__listenerId);
1811
- if (this.options.debug) {
1812
- console.warn(`[EventBus] Listener timeout for event: ${event}`);
1813
- }
1814
- }, options.timeout);
1815
- onceListener.__cleanup = () => clearTimeout(timeoutId);
1816
- }
1817
- return this.on(event, onceListener, options);
1818
- }
1819
- /**
1820
- * Remove listener
1821
- */
1822
- off(event, listenerId) {
1823
- if (!this.listeners.has(event)) {
1824
- return false;
1825
- }
1826
- const listeners = this.listeners.get(event);
1827
- const index = listeners.findIndex((l) => l.listenerId === listenerId);
1828
- if (index !== -1) {
1829
- const listenerObj = listeners[index];
1830
- if (listenerObj.listener.__cleanup) {
1831
- listenerObj.listener.__cleanup();
1832
- }
1833
- listeners.splice(index, 1);
1834
- if (listeners.length === 0) {
1835
- this.listeners.delete(event);
1836
- }
1837
- return true;
1838
- }
1839
- return false;
1840
- }
1841
- /**
1842
- * Remove all listeners for an event
1843
- */
1844
- removeAllListeners(event) {
1845
- if (event) {
1846
- this.listeners.delete(event);
1847
- } else {
1848
- this.listeners.clear();
1849
- }
1850
- }
1851
- /**
1852
- * Get event listeners with wildcard support
1853
- */
1854
- getEventListeners(event) {
1855
- const listeners = [];
1856
- if (this.listeners.has(event)) {
1857
- listeners.push(...this.listeners.get(event));
1858
- }
1859
- if (this.options.enableWildcards) {
1860
- for (const [pattern, patternListeners] of this.listeners) {
1861
- if (pattern.includes("*") && this.matchPattern(pattern, event)) {
1862
- listeners.push(...patternListeners);
1863
- }
1864
- }
1865
- }
1866
- if (this.options.enablePriority) {
1867
- listeners.sort((a, b) => b.priority - a.priority);
1868
- }
1869
- return listeners;
1870
- }
1871
- /**
1872
- * Execute listener with options
1873
- */
1874
- async executeListener(listener, event, data, options = {}) {
1875
- try {
1876
- if (options.condition && !options.condition(data)) {
1877
- return;
1878
- }
1879
- const result = listener.call(this, data, event);
1880
- if (result && typeof result.then === "function") {
1881
- await result;
1882
- }
1883
- return result;
1884
- } catch (error) {
1885
- this.handleError(error, event, data);
1886
- }
1887
- }
1888
- /**
1889
- * Run middleware chain
1890
- */
1891
- async runMiddleware(event, data) {
1892
- if (this.middleware.length === 0) return;
1893
- let index = 0;
1894
- const next = async () => {
1895
- if (index < this.middleware.length) {
1896
- const middleware = this.middleware[index++];
1897
- await middleware(event, data, next);
1898
- }
1899
- };
1900
- await next();
1901
- }
1902
- /**
1903
- * Handle errors
1904
- */
1905
- handleError(error, event, data) {
1906
- if (this.options.errorHandler) {
1907
- this.options.errorHandler(error, event, data);
1908
- } else if (this.options.debug) {
1909
- console.error(`[EventBus] Error in event ${event}:`, error, data);
1910
- }
1911
- this.emitSync("eventbus:error", { error, event, data });
509
+ function validateComponent(component, path = "root") {
510
+ if (component === null || component === void 0) {
511
+ throw new Error(`Invalid component at ${path}: null or undefined`);
1912
512
  }
1913
- /**
1914
- * Synchronous emit
1915
- */
1916
- emitSync(event, data = null) {
1917
- try {
1918
- const listeners = this.getEventListeners(event);
1919
- listeners.forEach((listenerObj) => {
1920
- try {
1921
- if (!listenerObj.options.condition || listenerObj.options.condition(data)) {
1922
- listenerObj.listener.call(this, data, event);
1923
- }
1924
- } catch (error) {
1925
- this.handleError(error, event, data);
1926
- }
1927
- });
1928
- this.stats.eventsEmitted++;
1929
- this.stats.listenersExecuted += listeners.length;
1930
- } catch (error) {
1931
- this.stats.errorsOccurred++;
1932
- this.handleError(error, event, data);
1933
- }
513
+ if (["string", "number", "boolean"].includes(typeof component)) {
514
+ return true;
1934
515
  }
1935
- /**
1936
- * Register action handler
1937
- */
1938
- registerAction(action, handler) {
1939
- if (typeof handler !== "function") {
1940
- throw new Error("Action handler must be a function");
1941
- }
1942
- this.actionHandlers.set(action, handler);
1943
- if (this.options.debug) {
1944
- console.log(`[EventBus] Registered action: ${action}`);
1945
- }
516
+ if (typeof component === "function") {
517
+ return true;
1946
518
  }
1947
- /**
1948
- * Register multiple actions
1949
- */
1950
- registerActions(actions) {
1951
- Object.entries(actions).forEach(([action, handler]) => {
1952
- this.registerAction(action, handler);
519
+ if (Array.isArray(component)) {
520
+ component.forEach((child, index) => {
521
+ validateComponent(child, `${path}[${index}]`);
1953
522
  });
523
+ return true;
1954
524
  }
1955
- /**
1956
- * Get registered actions
1957
- */
1958
- getRegisteredActions() {
1959
- return Array.from(this.actionHandlers.keys());
1960
- }
1961
- /**
1962
- * Handle action event (called by DOM integration)
1963
- */
1964
- handleAction(action, element, event, data) {
1965
- const handler = this.actionHandlers.get(action);
1966
- if (!handler) {
1967
- if (this.options.debug) {
1968
- console.warn(`[EventBus] No handler registered for action: ${action}`);
1969
- }
1970
- return;
1971
- }
1972
- try {
1973
- handler.call(element, {
1974
- element,
1975
- event,
1976
- data,
1977
- emit: this.emit.bind(this),
1978
- emitSync: this.emitSync.bind(this)
1979
- });
1980
- } catch (error) {
1981
- this.handleError(error, `action:${action}`, { element, event, data });
1982
- }
1983
- }
1984
- /**
1985
- * Generate unique listener ID
1986
- */
1987
- generateListenerId(event) {
1988
- return `${event}_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
1989
- }
1990
- /**
1991
- * Update performance stats
1992
- */
1993
- updatePerformanceStats(duration) {
1994
- const count = this.stats.eventsEmitted;
1995
- this.stats.averageEmitTime = (this.stats.averageEmitTime * (count - 1) + duration) / count;
1996
- }
1997
- /**
1998
- * Get statistics
1999
- */
2000
- getStats() {
2001
- return { ...this.stats };
2002
- }
2003
- /**
2004
- * Reset statistics
2005
- */
2006
- resetStats() {
2007
- this.stats = {
2008
- eventsEmitted: 0,
2009
- listenersExecuted: 0,
2010
- errorsOccurred: 0,
2011
- averageEmitTime: 0,
2012
- throttledEvents: 0,
2013
- filteredEvents: 0
2014
- };
2015
- }
2016
- /**
2017
- * Destroy event bus
2018
- */
2019
- destroy() {
2020
- this.removeAllListeners();
2021
- this.actionHandlers.clear();
2022
- this.handlers.clear();
2023
- this.middleware = [];
2024
- this.throttledEmitters.clear();
2025
- this.debouncedEmitters.clear();
2026
- if (this.batchTimer) {
2027
- clearTimeout(this.batchTimer);
2028
- }
2029
- }
2030
- };
2031
- function createEventBus(options = {}) {
2032
- return new EventBus(options);
2033
- }
2034
- var globalEventBus = createEventBus();
2035
- var emit = globalEventBus.emit.bind(globalEventBus);
2036
- var emitSync = globalEventBus.emitSync.bind(globalEventBus);
2037
- var on = globalEventBus.on.bind(globalEventBus);
2038
- var once = globalEventBus.once.bind(globalEventBus);
2039
- var off = globalEventBus.off.bind(globalEventBus);
2040
- var registerAction = globalEventBus.registerAction.bind(globalEventBus);
2041
- var handleAction = globalEventBus.handleAction.bind(globalEventBus);
2042
-
2043
- // ../core/src/events/dom-integration.js
2044
- var DOMEventIntegration = class {
2045
- constructor(eventBus = globalEventBus, options = {}) {
2046
- this.eventBus = eventBus;
2047
- this.options = {
2048
- debug: false,
2049
- debounceDelay: 150,
2050
- throttleDelay: 100,
2051
- enableDelegation: true,
2052
- enableDebounce: true,
2053
- enableThrottle: false,
2054
- ...options
2055
- };
2056
- this.boundHandlers = /* @__PURE__ */ new Map();
2057
- this.activeElement = null;
2058
- this.isInitialized = false;
2059
- this.handleClick = this.handleClick.bind(this);
2060
- this.handleChange = this.handleChange.bind(this);
2061
- this.handleInput = this.handleInput.bind(this);
2062
- this.handleSubmit = this.handleSubmit.bind(this);
2063
- this.handleKeydown = this.handleKeydown.bind(this);
2064
- this.handleFocus = this.handleFocus.bind(this);
2065
- this.handleBlur = this.handleBlur.bind(this);
2066
- }
2067
- /**
2068
- * Initialize DOM event listeners
2069
- * @param {HTMLElement} rootElement - Root element to attach listeners to (default: document)
2070
- */
2071
- initialize(rootElement = document) {
2072
- if (this.isInitialized) {
2073
- console.warn("[DOMEventIntegration] Already initialized");
2074
- return;
2075
- }
2076
- if (typeof window === "undefined" || !rootElement) {
2077
- console.warn("[DOMEventIntegration] Cannot initialize: no DOM environment");
2078
- return;
2079
- }
2080
- this.rootElement = rootElement;
2081
- this.setupDOMEventListeners();
2082
- this.isInitialized = true;
2083
- if (this.options.debug) {
2084
- console.log("[DOMEventIntegration] Initialized with options:", this.options);
525
+ if (typeof component === "object") {
526
+ const keys = Object.keys(component);
527
+ if (keys.length === 0) {
528
+ throw new Error(`Empty object at ${path}`);
2085
529
  }
2086
- }
2087
- /**
2088
- * Set up delegated DOM event listeners
2089
- * @private
2090
- */
2091
- setupDOMEventListeners() {
2092
- const clickHandler = this.createDelegatedHandler("click", this.handleClick);
2093
- this.rootElement.addEventListener("click", clickHandler, { passive: false });
2094
- this.boundHandlers.set("click", clickHandler);
2095
- const changeHandler = this.options.enableDebounce ? this.debounce(this.createDelegatedHandler("change", this.handleChange), this.options.debounceDelay) : this.createDelegatedHandler("change", this.handleChange);
2096
- this.rootElement.addEventListener("change", changeHandler, { passive: true });
2097
- this.boundHandlers.set("change", changeHandler);
2098
- const inputHandler = this.options.enableDebounce ? this.debounce(this.createDelegatedHandler("input", this.handleInput), this.options.debounceDelay) : this.createDelegatedHandler("input", this.handleInput);
2099
- this.rootElement.addEventListener("input", inputHandler, { passive: true });
2100
- this.boundHandlers.set("input", inputHandler);
2101
- const submitHandler = this.createDelegatedHandler("submit", this.handleSubmit);
2102
- this.rootElement.addEventListener("submit", submitHandler, { passive: false });
2103
- this.boundHandlers.set("submit", submitHandler);
2104
- const keydownHandler = this.createDelegatedHandler("keydown", this.handleKeydown);
2105
- this.rootElement.addEventListener("keydown", keydownHandler, { passive: false });
2106
- this.boundHandlers.set("keydown", keydownHandler);
2107
- const focusHandler = this.createDelegatedHandler("focus", this.handleFocus);
2108
- this.rootElement.addEventListener("focus", focusHandler, { passive: true, capture: true });
2109
- this.boundHandlers.set("focus", focusHandler);
2110
- const blurHandler = this.createDelegatedHandler("blur", this.handleBlur);
2111
- this.rootElement.addEventListener("blur", blurHandler, { passive: true, capture: true });
2112
- this.boundHandlers.set("blur", blurHandler);
2113
- }
2114
- /**
2115
- * Create a delegated event handler
2116
- * @private
2117
- */
2118
- createDelegatedHandler(eventType, handler) {
2119
- return (event) => {
2120
- const target = event.target;
2121
- if (!target) return;
2122
- const actionElement = this.options.enableDelegation ? target.closest("[data-action]") : target.hasAttribute?.("data-action") ? target : null;
2123
- if (actionElement) {
2124
- handler(actionElement, event);
2125
- } else {
2126
- handler(target, event);
530
+ keys.forEach((key) => {
531
+ const value = component[key];
532
+ if (!/^[a-zA-Z][a-zA-Z0-9-]*$/.test(key) && key !== "text") {
533
+ console.warn(`Potentially invalid tag name at ${path}: ${key}`);
2127
534
  }
2128
- };
2129
- }
2130
- /**
2131
- * Handle click events
2132
- * @private
2133
- */
2134
- handleClick(element, event) {
2135
- const action = element.getAttribute?.("data-action");
2136
- if (action) {
2137
- this.handleDataAction(element, event, action);
2138
- }
2139
- this.eventBus.emitSync("dom:click", {
2140
- element,
2141
- event,
2142
- action,
2143
- data: this.parseDataAttributes(element)
2144
- });
2145
- }
2146
- /**
2147
- * Handle change events
2148
- * @private
2149
- */
2150
- handleChange(element, event) {
2151
- const action = element.getAttribute?.("data-action");
2152
- if (action) {
2153
- this.handleDataAction(element, event, action);
2154
- }
2155
- this.eventBus.emitSync("dom:change", {
2156
- element,
2157
- event,
2158
- value: element.value,
2159
- action,
2160
- data: this.parseDataAttributes(element)
2161
- });
2162
- }
2163
- /**
2164
- * Handle input events
2165
- * @private
2166
- */
2167
- handleInput(element, event) {
2168
- const action = element.getAttribute?.("data-action");
2169
- if (action) {
2170
- this.handleDataAction(element, event, action);
2171
- }
2172
- this.eventBus.emitSync("dom:input", {
2173
- element,
2174
- event,
2175
- value: element.value,
2176
- action,
2177
- data: this.parseDataAttributes(element)
2178
- });
2179
- }
2180
- /**
2181
- * Handle submit events
2182
- * @private
2183
- */
2184
- handleSubmit(element, event) {
2185
- const action = element.getAttribute?.("data-action");
2186
- if (action) {
2187
- event.preventDefault();
2188
- this.handleDataAction(element, event, action);
2189
- }
2190
- this.eventBus.emitSync("dom:submit", {
2191
- element,
2192
- event,
2193
- action,
2194
- formData: this.extractFormData(element),
2195
- data: this.parseDataAttributes(element)
2196
- });
2197
- }
2198
- /**
2199
- * Handle keydown events
2200
- * @private
2201
- */
2202
- handleKeydown(element, event) {
2203
- const action = element.getAttribute?.("data-action");
2204
- const keyAction = element.getAttribute?.(`data-key-${event.key.toLowerCase()}`);
2205
- if (action && this.shouldTriggerKeyAction(event)) {
2206
- this.handleDataAction(element, event, action);
2207
- }
2208
- if (keyAction) {
2209
- this.handleDataAction(element, event, keyAction);
2210
- }
2211
- this.eventBus.emitSync("dom:keydown", {
2212
- element,
2213
- event,
2214
- key: event.key,
2215
- code: event.code,
2216
- action,
2217
- keyAction,
2218
- data: this.parseDataAttributes(element)
2219
- });
2220
- }
2221
- /**
2222
- * Handle focus events
2223
- * @private
2224
- */
2225
- handleFocus(element, event) {
2226
- this.activeElement = element;
2227
- this.eventBus.emitSync("dom:focus", {
2228
- element,
2229
- event,
2230
- data: this.parseDataAttributes(element)
2231
- });
2232
- }
2233
- /**
2234
- * Handle blur events
2235
- * @private
2236
- */
2237
- handleBlur(element, event) {
2238
- if (this.activeElement === element) {
2239
- this.activeElement = null;
2240
- }
2241
- this.eventBus.emitSync("dom:blur", {
2242
- element,
2243
- event,
2244
- data: this.parseDataAttributes(element)
2245
- });
2246
- }
2247
- /**
2248
- * Handle data-action attributes
2249
- * @private
2250
- */
2251
- handleDataAction(element, event, action) {
2252
- if (!action) return;
2253
- const data = this.parseDataAttributes(element);
2254
- this.eventBus.emitSync("dom:action", {
2255
- action,
2256
- element,
2257
- event,
2258
- data
2259
- });
2260
- this.eventBus.handleAction(action, element, event, data);
2261
- if (this.options.debug) {
2262
- console.log(`[DOMEventIntegration] Action triggered: ${action}`, {
2263
- element,
2264
- event: event.type,
2265
- data
2266
- });
2267
- }
2268
- }
2269
- /**
2270
- * Parse data attributes from an element
2271
- * @private
2272
- */
2273
- parseDataAttributes(element) {
2274
- if (!element?.attributes) return {};
2275
- const data = {};
2276
- Array.from(element.attributes).forEach((attr) => {
2277
- if (attr.name.startsWith("data-") && attr.name !== "data-action") {
2278
- const key = attr.name.slice(5).replace(/-([a-z])/g, (_, letter) => letter.toUpperCase());
2279
- let value = attr.value;
2280
- try {
2281
- if (value === "true") value = true;
2282
- else if (value === "false") value = false;
2283
- else if (value === "null") value = null;
2284
- else if (value === "undefined") value = void 0;
2285
- else if (/^\d+$/.test(value)) value = parseInt(value, 10);
2286
- else if (/^\d*\.\d+$/.test(value)) value = parseFloat(value);
2287
- else if (value.startsWith("{") && value.endsWith("}") || value.startsWith("[") && value.endsWith("]")) {
2288
- value = JSON.parse(value);
2289
- }
2290
- } catch {
535
+ if (value && typeof value === "object" && !Array.isArray(value)) {
536
+ if (value.children) {
537
+ validateComponent(value.children, `${path}.${key}.children`);
2291
538
  }
2292
- data[key] = value;
539
+ } else if (value && typeof value !== "string" && typeof value !== "number" && typeof value !== "function") {
540
+ throw new Error(`Invalid value type at ${path}.${key}: ${typeof value}`);
2293
541
  }
2294
542
  });
2295
- return data;
2296
- }
2297
- /**
2298
- * Extract form data from a form element
2299
- * @private
2300
- */
2301
- extractFormData(formElement) {
2302
- if (!formElement || formElement.tagName !== "FORM") {
2303
- return {};
2304
- }
2305
- const formData = new FormData(formElement);
2306
- const data = {};
2307
- for (const [key, value] of formData.entries()) {
2308
- if (data[key]) {
2309
- if (Array.isArray(data[key])) {
2310
- data[key].push(value);
2311
- } else {
2312
- data[key] = [data[key], value];
2313
- }
2314
- } else {
2315
- data[key] = value;
2316
- }
2317
- }
2318
- return data;
2319
- }
2320
- /**
2321
- * Check if a key event should trigger an action
2322
- * @private
2323
- */
2324
- shouldTriggerKeyAction(event) {
2325
- const triggerKeys = ["Enter", "Space", "Escape"];
2326
- return triggerKeys.includes(event.key);
543
+ return true;
2327
544
  }
2328
- /**
2329
- * Debounce utility function
2330
- * @private
2331
- */
2332
- debounce(func, wait) {
2333
- let timeout;
2334
- return function executedFunction(...args) {
2335
- const later = () => {
2336
- clearTimeout(timeout);
2337
- func.apply(this, args);
2338
- };
2339
- clearTimeout(timeout);
2340
- timeout = setTimeout(later, wait);
2341
- };
545
+ throw new Error(`Invalid component type at ${path}: ${typeof component}`);
546
+ }
547
+ function isCoherentObject(obj) {
548
+ if (!obj || typeof obj !== "object" || Array.isArray(obj)) {
549
+ return false;
2342
550
  }
2343
- /**
2344
- * Throttle utility function
2345
- * @private
2346
- */
2347
- throttle(func, limit) {
2348
- let inThrottle;
2349
- return function executedFunction(...args) {
2350
- if (!inThrottle) {
2351
- func.apply(this, args);
2352
- inThrottle = true;
2353
- setTimeout(() => inThrottle = false, limit);
2354
- }
2355
- };
551
+ const keys = Object.keys(obj);
552
+ if (keys.length === 0) {
553
+ return false;
2356
554
  }
2357
- /**
2358
- * Add custom event listener
2359
- * @param {string} eventType - Event type
2360
- * @param {Function} handler - Event handler
2361
- * @param {Object} options - Event listener options
2362
- */
2363
- addCustomListener(eventType, handler, options = {}) {
2364
- const wrappedHandler = this.createDelegatedHandler(eventType, handler);
2365
- this.rootElement.addEventListener(eventType, wrappedHandler, options);
2366
- this.boundHandlers.set(`custom:${eventType}`, wrappedHandler);
555
+ return keys.every((key) => {
556
+ if (key === "text") return true;
557
+ return /^[a-zA-Z][a-zA-Z0-9-]*$/.test(key);
558
+ });
559
+ }
560
+ function extractProps(coherentObj) {
561
+ if (!isCoherentObject(coherentObj)) {
562
+ return {};
2367
563
  }
2368
- /**
2369
- * Remove custom event listener
2370
- * @param {string} eventType - Event type
2371
- */
2372
- removeCustomListener(eventType) {
2373
- const handler = this.boundHandlers.get(`custom:${eventType}`);
2374
- if (handler) {
2375
- this.rootElement.removeEventListener(eventType, handler);
2376
- this.boundHandlers.delete(`custom:${eventType}`);
564
+ const props = {};
565
+ const keys = Object.keys(coherentObj);
566
+ keys.forEach((tag) => {
567
+ const value = coherentObj[tag];
568
+ if (value && typeof value === "object" && !Array.isArray(value)) {
569
+ props[tag] = { ...value };
570
+ } else {
571
+ props[tag] = { text: value };
2377
572
  }
573
+ });
574
+ return props;
575
+ }
576
+ function hasChildren(component) {
577
+ if (Array.isArray(component)) {
578
+ return component.length > 0;
2378
579
  }
2379
- /**
2380
- * Register action handlers in bulk
2381
- * @param {Object} actions - Object mapping action names to handlers
2382
- */
2383
- registerActions(actions) {
2384
- this.eventBus.registerActions(actions);
2385
- }
2386
- /**
2387
- * Get the currently active (focused) element
2388
- * @returns {HTMLElement|null}
2389
- */
2390
- getActiveElement() {
2391
- return this.activeElement;
2392
- }
2393
- /**
2394
- * Trigger an action programmatically
2395
- * @param {string} action - Action name
2396
- * @param {HTMLElement} element - Target element
2397
- * @param {Object} data - Additional data
2398
- */
2399
- triggerAction(action, element, data = {}) {
2400
- const syntheticEvent = new CustomEvent("synthetic", {
2401
- bubbles: true,
2402
- cancelable: true,
2403
- detail: data
2404
- });
2405
- this.eventBus.handleAction(action, element, syntheticEvent, data);
2406
- }
2407
- /**
2408
- * Clean up event listeners
2409
- */
2410
- destroy() {
2411
- if (!this.isInitialized) return;
2412
- this.boundHandlers.forEach((handler, eventType) => {
2413
- this.rootElement.removeEventListener(
2414
- eventType.replace("custom:", ""),
2415
- handler
2416
- );
2417
- });
2418
- this.boundHandlers.clear();
2419
- this.activeElement = null;
2420
- this.isInitialized = false;
2421
- if (this.options.debug) {
2422
- console.log("[DOMEventIntegration] Destroyed");
580
+ if (isCoherentObject(component)) {
581
+ if (component.children !== void 0 && component.children !== null) {
582
+ return Array.isArray(component.children) ? component.children.length > 0 : true;
2423
583
  }
2424
- }
2425
- };
2426
- var globalDOMIntegration = new DOMEventIntegration(globalEventBus, {
2427
- debug: typeof process !== "undefined" && true
2428
- });
2429
- if (typeof window !== "undefined") {
2430
- if (document.readyState === "loading") {
2431
- document.addEventListener("DOMContentLoaded", () => {
2432
- globalDOMIntegration.initialize();
584
+ const keys = Object.keys(component);
585
+ return keys.some((key) => {
586
+ const value = component[key];
587
+ return value && typeof value === "object" && value.children;
2433
588
  });
2434
- } else {
2435
- globalDOMIntegration.initialize();
2436
589
  }
590
+ return false;
2437
591
  }
2438
-
2439
- // ../core/src/events/index.js
2440
- var eventSystem2 = {
2441
- // Core bus
2442
- bus: globalEventBus,
2443
- dom: globalDOMIntegration,
2444
- // Quick access methods
2445
- emit: globalEventBus.emit.bind(globalEventBus),
2446
- emitSync: globalEventBus.emitSync.bind(globalEventBus),
2447
- on: globalEventBus.on.bind(globalEventBus),
2448
- once: globalEventBus.once.bind(globalEventBus),
2449
- off: globalEventBus.off.bind(globalEventBus),
2450
- // Action methods
2451
- registerAction: globalEventBus.registerAction.bind(globalEventBus),
2452
- registerActions: globalEventBus.registerActions.bind(globalEventBus),
2453
- handleAction: globalEventBus.handleAction.bind(globalEventBus),
2454
- // Statistics and debugging
2455
- getStats: globalEventBus.getStats.bind(globalEventBus),
2456
- resetStats: globalEventBus.resetStats.bind(globalEventBus),
2457
- // Lifecycle
2458
- destroy() {
2459
- globalEventBus.destroy();
2460
- globalDOMIntegration.destroy();
592
+ function normalizeChildren(children) {
593
+ if (children === null || children === void 0) {
594
+ return [];
2461
595
  }
2462
- };
596
+ if (Array.isArray(children)) {
597
+ return children.flat().filter((child) => child !== null && child !== void 0);
598
+ }
599
+ return [children];
600
+ }
2463
601
 
2464
602
  // ../core/src/index.js
2465
603
  var scopeCounter = { value: 0 };
@@ -3144,10 +1282,10 @@ function createCacheManager(options = {}) {
3144
1282
  cleanupInterval.unref();
3145
1283
  }
3146
1284
  }
3147
- function generateCacheKey(component, props = {}, context2 = {}) {
1285
+ function generateCacheKey(component, props = {}, context = {}) {
3148
1286
  const componentStr = typeof component === "function" ? component.name || component.toString() : JSON.stringify(component);
3149
1287
  const propsStr = JSON.stringify(props, Object.keys(props).sort());
3150
- const contextStr = JSON.stringify(context2);
1288
+ const contextStr = JSON.stringify(context);
3151
1289
  const hash = simpleHash(componentStr + propsStr + contextStr);
3152
1290
  return `${extractComponentName(component)}_${hash}`;
3153
1291
  }
@@ -3327,107 +1465,6 @@ function createCacheManager(options = {}) {
3327
1465
  }
3328
1466
  var cacheManager = createCacheManager();
3329
1467
 
3330
- // ../core/src/rendering/css-manager.js
3331
- var import_promises = __toESM(require("node:fs/promises"), 1);
3332
- var import_node_path = __toESM(require("node:path"), 1);
3333
- var CSSManager = class {
3334
- constructor(options = {}) {
3335
- this.options = {
3336
- basePath: process.cwd(),
3337
- minify: false,
3338
- cache: true,
3339
- autoprefixer: false,
3340
- ...options
3341
- };
3342
- this.cache = /* @__PURE__ */ new Map();
3343
- this.loadedFiles = /* @__PURE__ */ new Set();
3344
- }
3345
- /**
3346
- * Load CSS file content
3347
- */
3348
- async loadCSSFile(filePath) {
3349
- const fullPath = import_node_path.default.resolve(this.options.basePath, filePath);
3350
- const cacheKey = fullPath;
3351
- if (this.options.cache && this.cache.has(cacheKey)) {
3352
- return this.cache.get(cacheKey);
3353
- }
3354
- try {
3355
- let content = await import_promises.default.readFile(fullPath, "utf8");
3356
- if (this.options.minify) {
3357
- content = this.minifyCSS(content);
3358
- }
3359
- if (this.options.cache) {
3360
- this.cache.set(cacheKey, content);
3361
- }
3362
- this.loadedFiles.add(filePath);
3363
- return content;
3364
- } catch (_error) {
3365
- console.warn(`Failed to load CSS file: ${filePath}`, _error.message);
3366
- return "";
3367
- }
3368
- }
3369
- /**
3370
- * Load multiple CSS files
3371
- */
3372
- async loadCSSFiles(filePaths) {
3373
- if (!Array.isArray(filePaths)) {
3374
- filePaths = [filePaths];
3375
- }
3376
- const cssContents = await Promise.all(
3377
- filePaths.map((filePath) => this.loadCSSFile(filePath))
3378
- );
3379
- return cssContents.join("\n");
3380
- }
3381
- /**
3382
- * Generate CSS link tags for external files
3383
- */
3384
- generateCSSLinks(filePaths, baseUrl = "/") {
3385
- if (!Array.isArray(filePaths)) {
3386
- filePaths = [filePaths];
3387
- }
3388
- return filePaths.map((filePath) => {
3389
- const href = filePath.startsWith("http") ? filePath : `${baseUrl}${filePath}`.replace(/\/+/g, "/");
3390
- return `<link rel="stylesheet" href="${this.escapeHtml(href)}" />`;
3391
- }).join("\n");
3392
- }
3393
- /**
3394
- * Generate inline style tag with CSS content
3395
- */
3396
- generateInlineStyles(cssContent) {
3397
- if (!cssContent) return "";
3398
- return `<style type="text/css">
3399
- ${cssContent}
3400
- </style>`;
3401
- }
3402
- /**
3403
- * Basic CSS minification
3404
- */
3405
- minifyCSS(css) {
3406
- return css.replace(/\/\*[\s\S]*?\*\//g, "").replace(/\s+/g, " ").replace(/;\s*}/g, "}").replace(/{\s+/g, "{").replace(/;\s+/g, ";").trim();
3407
- }
3408
- /**
3409
- * Escape HTML entities
3410
- */
3411
- escapeHtml(text) {
3412
- const div = { textContent: text };
3413
- return div.innerHTML || text;
3414
- }
3415
- /**
3416
- * Clear cache
3417
- */
3418
- clearCache() {
3419
- this.cache.clear();
3420
- this.loadedFiles.clear();
3421
- }
3422
- /**
3423
- * Get loaded file list
3424
- */
3425
- getLoadedFiles() {
3426
- return Array.from(this.loadedFiles);
3427
- }
3428
- };
3429
- var defaultCSSManager = new CSSManager();
3430
-
3431
1468
  // ../core/src/rendering/html-renderer.js
3432
1469
  var rendererCache = createCacheManager({
3433
1470
  maxSize: 1e3,