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

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
@@ -29,1672 +29,12 @@ __export(index_exports, {
29
29
  });
30
30
  module.exports = __toCommonJS(index_exports);
31
31
 
32
- // ../core/src/performance/monitor.js
33
- function createPerformanceMonitor(options = {}) {
34
- const opts = {
35
- enabled: true,
36
- metrics: {
37
- custom: {}
38
- },
39
- sampling: {
40
- enabled: false,
41
- rate: 1,
42
- strategy: "random"
43
- },
44
- reporting: {
45
- enabled: false,
46
- interval: 6e4,
47
- format: "json",
48
- batch: {
49
- enabled: false,
50
- maxSize: 100,
51
- flushInterval: 5e3
52
- },
53
- onReport: null
54
- },
55
- alerts: {
56
- enabled: true,
57
- debounceMs: 5e3,
58
- rules: []
59
- },
60
- resources: {
61
- enabled: false,
62
- track: ["memory"],
63
- interval: 1e3
64
- },
65
- profiling: {
66
- enabled: false,
67
- mode: "production",
68
- flamegraph: false,
69
- tracing: {
70
- enabled: false,
71
- sampleRate: 0.01
72
- }
73
- },
74
- ...options
75
- };
76
- opts.reporting.batch = {
77
- enabled: false,
78
- maxSize: 100,
79
- flushInterval: 5e3,
80
- ...options.reporting?.batch || {}
81
- };
82
- const metrics = {
83
- builtin: {
84
- renderTime: { type: "histogram", unit: "ms", values: [] },
85
- componentCount: { type: "counter", unit: "renders", value: 0 },
86
- errorCount: { type: "counter", unit: "errors", value: 0 },
87
- memoryUsage: { type: "gauge", unit: "MB", values: [] }
88
- },
89
- custom: {}
90
- };
91
- Object.entries(opts.metrics.custom).forEach(([name, config]) => {
92
- metrics.custom[name] = {
93
- type: config.type || "counter",
94
- unit: config.unit || "",
95
- threshold: config.threshold,
96
- values: config.type === "histogram" ? [] : void 0,
97
- value: config.type === "counter" || config.type === "gauge" ? 0 : void 0
98
- };
99
- });
100
- const samplingState = {
101
- count: 0,
102
- sampled: 0,
103
- adaptiveRate: opts.sampling.rate
104
- };
105
- const reportingState = {
106
- batch: [],
107
- lastReport: Date.now(),
108
- reportTimer: null,
109
- flushTimer: null
110
- };
111
- const alertState = {
112
- triggered: /* @__PURE__ */ new Map(),
113
- history: []
114
- };
115
- const resourceState = {
116
- samples: [],
117
- timer: null
118
- };
119
- const profilingState = {
120
- traces: [],
121
- flamegraphData: []
122
- };
123
- const stats = {
124
- metricsRecorded: 0,
125
- sampleRate: opts.sampling.rate,
126
- reportsGenerated: 0,
127
- alertsTriggered: 0
128
- };
129
- function shouldSample() {
130
- if (!opts.sampling.enabled) return true;
131
- samplingState.count++;
132
- if (opts.sampling.strategy === "random") {
133
- return Math.random() < samplingState.adaptiveRate;
134
- } else if (opts.sampling.strategy === "deterministic") {
135
- return samplingState.count % Math.ceil(1 / samplingState.adaptiveRate) === 0;
136
- } else if (opts.sampling.strategy === "adaptive") {
137
- const recentRenderTimes = metrics.builtin.renderTime.values.slice(-10);
138
- if (recentRenderTimes.length > 0) {
139
- const avgTime = recentRenderTimes.reduce((a, b) => a + b, 0) / recentRenderTimes.length;
140
- samplingState.adaptiveRate = avgTime > 16 ? Math.min(1, opts.sampling.rate * 2) : opts.sampling.rate;
141
- }
142
- return Math.random() < samplingState.adaptiveRate;
143
- }
144
- return true;
145
- }
146
- function recordMetric(name, value, metadata = {}) {
147
- if (!opts.enabled) return;
148
- if (!shouldSample()) return;
149
- stats.metricsRecorded++;
150
- const builtinMetric = metrics.builtin[name];
151
- if (builtinMetric) {
152
- if (builtinMetric.type === "histogram") {
153
- builtinMetric.values.push(value);
154
- if (builtinMetric.values.length > 1e3) {
155
- builtinMetric.values = builtinMetric.values.slice(-1e3);
156
- }
157
- } else if (builtinMetric.type === "counter") {
158
- builtinMetric.value += value;
159
- } else if (builtinMetric.type === "gauge") {
160
- builtinMetric.values.push(value);
161
- if (builtinMetric.values.length > 100) {
162
- builtinMetric.values = builtinMetric.values.slice(-100);
163
- }
164
- }
165
- }
166
- const customMetric = metrics.custom[name];
167
- if (customMetric) {
168
- if (customMetric.type === "histogram") {
169
- customMetric.values = customMetric.values || [];
170
- customMetric.values.push(value);
171
- if (customMetric.values.length > 1e3) {
172
- customMetric.values = customMetric.values.slice(-1e3);
173
- }
174
- } else if (customMetric.type === "counter") {
175
- customMetric.value = (customMetric.value || 0) + value;
176
- } else if (customMetric.type === "gauge") {
177
- customMetric.values = customMetric.values || [];
178
- customMetric.values.push(value);
179
- if (customMetric.values.length > 100) {
180
- customMetric.values = customMetric.values.slice(-100);
181
- }
182
- }
183
- if (customMetric.threshold) {
184
- const currentValue = customMetric.type === "histogram" || customMetric.type === "gauge" ? customMetric.values[customMetric.values.length - 1] : customMetric.value;
185
- if (currentValue > customMetric.threshold) {
186
- checkAlerts(name, currentValue);
187
- }
188
- }
189
- }
190
- if (opts.reporting.enabled && opts.reporting.batch.enabled) {
191
- reportingState.batch.push({
192
- metric: name,
193
- value,
194
- metadata,
195
- timestamp: Date.now()
196
- });
197
- if (reportingState.batch.length >= opts.reporting.batch.maxSize) {
198
- flushBatch();
199
- }
200
- }
201
- checkAlerts(name, value);
202
- }
203
- function checkAlerts(metric, value) {
204
- if (!opts.alerts.enabled) return;
205
- opts.alerts.rules.forEach((rule) => {
206
- if (rule.metric !== metric) return;
207
- let triggered = false;
208
- if (rule.condition === "exceeds" && value > rule.threshold) {
209
- triggered = true;
210
- } else if (rule.condition === "below" && value < rule.threshold) {
211
- triggered = true;
212
- } else if (rule.condition === "equals" && value === rule.threshold) {
213
- triggered = true;
214
- }
215
- if (triggered) {
216
- const alertKey = `${rule.metric}-${rule.condition}-${rule.threshold}`;
217
- const lastTriggered = alertState.triggered.get(alertKey);
218
- const now = Date.now();
219
- if (!lastTriggered || now - lastTriggered > opts.alerts.debounceMs) {
220
- alertState.triggered.set(alertKey, now);
221
- alertState.history.push({
222
- rule,
223
- value,
224
- timestamp: now
225
- });
226
- stats.alertsTriggered++;
227
- if (rule.action) {
228
- rule.action(value, rule);
229
- }
230
- }
231
- }
232
- });
233
- }
234
- function flushBatch() {
235
- if (reportingState.batch.length === 0) return;
236
- const batch = [...reportingState.batch];
237
- reportingState.batch = [];
238
- if (opts.reporting.onReport) {
239
- opts.reporting.onReport({ type: "batch", data: batch });
240
- }
241
- }
242
- function generateReport() {
243
- const report = {
244
- timestamp: Date.now(),
245
- statistics: { ...stats },
246
- metrics: {}
247
- };
248
- Object.entries(metrics.builtin).forEach(([name, metric]) => {
249
- if (metric.type === "histogram") {
250
- report.metrics[name] = {
251
- type: "histogram",
252
- unit: metric.unit,
253
- count: metric.values.length,
254
- min: metric.values.length > 0 ? Math.min(...metric.values) : 0,
255
- max: metric.values.length > 0 ? Math.max(...metric.values) : 0,
256
- avg: metric.values.length > 0 ? metric.values.reduce((a, b) => a + b, 0) / metric.values.length : 0,
257
- p50: percentile(metric.values, 0.5),
258
- p95: percentile(metric.values, 0.95),
259
- p99: percentile(metric.values, 0.99)
260
- };
261
- } else if (metric.type === "counter") {
262
- report.metrics[name] = {
263
- type: "counter",
264
- unit: metric.unit,
265
- value: metric.value
266
- };
267
- } else if (metric.type === "gauge") {
268
- report.metrics[name] = {
269
- type: "gauge",
270
- unit: metric.unit,
271
- current: metric.values.length > 0 ? metric.values[metric.values.length - 1] : 0,
272
- avg: metric.values.length > 0 ? metric.values.reduce((a, b) => a + b, 0) / metric.values.length : 0
273
- };
274
- }
275
- });
276
- Object.entries(metrics.custom).forEach(([name, metric]) => {
277
- if (metric.type === "histogram") {
278
- report.metrics[name] = {
279
- type: "histogram",
280
- unit: metric.unit,
281
- count: metric.values?.length || 0,
282
- min: metric.values?.length > 0 ? Math.min(...metric.values) : 0,
283
- max: metric.values?.length > 0 ? Math.max(...metric.values) : 0,
284
- avg: metric.values?.length > 0 ? metric.values.reduce((a, b) => a + b, 0) / metric.values.length : 0,
285
- p95: percentile(metric.values || [], 0.95),
286
- p99: percentile(metric.values || [], 0.99)
287
- };
288
- } else if (metric.type === "counter") {
289
- report.metrics[name] = {
290
- type: "counter",
291
- unit: metric.unit,
292
- value: metric.value || 0
293
- };
294
- } else if (metric.type === "gauge") {
295
- report.metrics[name] = {
296
- type: "gauge",
297
- unit: metric.unit,
298
- current: metric.values?.length > 0 ? metric.values[metric.values.length - 1] : 0,
299
- avg: metric.values?.length > 0 ? metric.values.reduce((a, b) => a + b, 0) / metric.values.length : 0
300
- };
301
- }
302
- });
303
- report.alerts = {
304
- total: alertState.history.length,
305
- recent: alertState.history.slice(-10)
306
- };
307
- if (opts.resources.enabled) {
308
- report.resources = {
309
- samples: resourceState.samples.slice(-20)
310
- };
311
- }
312
- stats.reportsGenerated++;
313
- if (opts.reporting.onReport) {
314
- opts.reporting.onReport({ type: "report", data: report });
315
- }
316
- return report;
317
- }
318
- function percentile(values, p) {
319
- if (values.length === 0) return 0;
320
- const sorted = [...values].sort((a, b) => a - b);
321
- const index = Math.ceil(sorted.length * p) - 1;
322
- return sorted[Math.max(0, index)];
323
- }
324
- function startResourceMonitoring() {
325
- if (!opts.resources.enabled) return;
326
- const collectResources = () => {
327
- const sample = {
328
- timestamp: Date.now()
329
- };
330
- if (opts.resources.track.includes("memory")) {
331
- if (typeof process !== "undefined" && process.memoryUsage) {
332
- const mem = process.memoryUsage();
333
- sample.memory = {
334
- heapUsed: mem.heapUsed / 1024 / 1024,
335
- heapTotal: mem.heapTotal / 1024 / 1024,
336
- external: mem.external / 1024 / 1024,
337
- rss: mem.rss / 1024 / 1024
338
- };
339
- } else if (typeof performance !== "undefined" && performance.memory) {
340
- sample.memory = {
341
- heapUsed: performance.memory.usedJSHeapSize / 1024 / 1024,
342
- heapTotal: performance.memory.totalJSHeapSize / 1024 / 1024
343
- };
344
- }
345
- }
346
- resourceState.samples.push(sample);
347
- if (resourceState.samples.length > 100) {
348
- resourceState.samples = resourceState.samples.slice(-100);
349
- }
350
- resourceState.timer = setTimeout(collectResources, opts.resources.interval);
351
- };
352
- collectResources();
353
- }
354
- function stopResourceMonitoring() {
355
- if (resourceState.timer) {
356
- clearTimeout(resourceState.timer);
357
- resourceState.timer = null;
358
- }
359
- }
360
- function startReporting() {
361
- if (!opts.reporting.enabled) return;
362
- reportingState.reportTimer = setInterval(() => {
363
- generateReport();
364
- }, opts.reporting.interval);
365
- if (opts.reporting.batch.enabled) {
366
- reportingState.flushTimer = setInterval(() => {
367
- flushBatch();
368
- }, opts.reporting.batch.flushInterval);
369
- }
370
- }
371
- function stopReporting() {
372
- if (reportingState.reportTimer) {
373
- clearInterval(reportingState.reportTimer);
374
- reportingState.reportTimer = null;
375
- }
376
- if (reportingState.flushTimer) {
377
- clearInterval(reportingState.flushTimer);
378
- reportingState.flushTimer = null;
379
- }
380
- flushBatch();
381
- }
382
- function startProfiling() {
383
- if (!opts.profiling.enabled) return;
384
- }
385
- function recordTrace(name, duration, metadata = {}) {
386
- if (!opts.profiling.enabled || !opts.profiling.tracing.enabled) return;
387
- if (Math.random() < opts.profiling.tracing.sampleRate) {
388
- profilingState.traces.push({
389
- name,
390
- duration,
391
- metadata,
392
- timestamp: Date.now()
393
- });
394
- if (profilingState.traces.length > 1e3) {
395
- profilingState.traces = profilingState.traces.slice(-1e3);
396
- }
397
- }
398
- }
399
- function measure(name, fn, metadata = {}) {
400
- if (!opts.enabled) return fn();
401
- const start = performance.now();
402
- try {
403
- const result = fn();
404
- const duration = performance.now() - start;
405
- recordMetric("renderTime", duration, { name, ...metadata });
406
- recordTrace(name, duration, metadata);
407
- return result;
408
- } catch (error) {
409
- recordMetric("errorCount", 1, { name, error: error.message });
410
- throw error;
411
- }
412
- }
413
- async function measureAsync(name, fn, metadata = {}) {
414
- if (!opts.enabled) return fn();
415
- const start = performance.now();
416
- try {
417
- const result = await fn();
418
- const duration = performance.now() - start;
419
- recordMetric("renderTime", duration, { name, ...metadata });
420
- recordTrace(name, duration, metadata);
421
- return result;
422
- } catch (error) {
423
- recordMetric("errorCount", 1, { name, error: error.message });
424
- throw error;
425
- }
426
- }
427
- function addMetric(name, config) {
428
- metrics.custom[name] = {
429
- type: config.type || "counter",
430
- unit: config.unit || "",
431
- threshold: config.threshold,
432
- values: config.type === "histogram" ? [] : void 0,
433
- value: config.type === "counter" || config.type === "gauge" ? 0 : void 0
434
- };
435
- }
436
- function addAlertRule(rule) {
437
- opts.alerts.rules.push(rule);
438
- }
439
- function getStats() {
440
- return {
441
- ...stats,
442
- sampleRate: samplingState.adaptiveRate,
443
- batchSize: reportingState.batch.length,
444
- resourceSamples: resourceState.samples.length,
445
- traces: profilingState.traces.length,
446
- alerts: {
447
- total: alertState.history.length,
448
- unique: alertState.triggered.size
449
- }
450
- };
451
- }
452
- function reset() {
453
- Object.values(metrics.builtin).forEach((metric) => {
454
- if (metric.type === "histogram" || metric.type === "gauge") {
455
- metric.values = [];
456
- } else if (metric.type === "counter") {
457
- metric.value = 0;
458
- }
459
- });
460
- Object.values(metrics.custom).forEach((metric) => {
461
- if (metric.type === "histogram" || metric.type === "gauge") {
462
- metric.values = [];
463
- } else if (metric.type === "counter") {
464
- metric.value = 0;
465
- }
466
- });
467
- samplingState.count = 0;
468
- samplingState.sampled = 0;
469
- reportingState.batch = [];
470
- alertState.history = [];
471
- alertState.triggered.clear();
472
- resourceState.samples = [];
473
- profilingState.traces = [];
474
- stats.metricsRecorded = 0;
475
- stats.reportsGenerated = 0;
476
- stats.alertsTriggered = 0;
477
- }
478
- if (opts.enabled) {
479
- startResourceMonitoring();
480
- startReporting();
481
- startProfiling();
482
- }
483
- return {
484
- recordMetric,
485
- measure,
486
- measureAsync,
487
- addMetric,
488
- addAlertRule,
489
- generateReport,
490
- getStats,
491
- reset,
492
- start() {
493
- opts.enabled = true;
494
- startResourceMonitoring();
495
- startReporting();
496
- startProfiling();
497
- },
498
- stop() {
499
- opts.enabled = false;
500
- stopResourceMonitoring();
501
- stopReporting();
502
- return generateReport();
503
- }
504
- };
505
- }
506
- var performanceMonitor2 = createPerformanceMonitor();
507
-
508
- // ../core/src/core/object-utils.js
509
- function validateComponent(component, path = "root") {
510
- if (component === null || component === void 0) {
511
- throw new Error(`Invalid component at ${path}: null or undefined`);
512
- }
513
- if (["string", "number", "boolean"].includes(typeof component)) {
514
- return true;
515
- }
516
- if (typeof component === "function") {
517
- return true;
518
- }
519
- if (Array.isArray(component)) {
520
- component.forEach((child, index) => {
521
- validateComponent(child, `${path}[${index}]`);
522
- });
523
- return true;
524
- }
525
- if (typeof component === "object") {
526
- const keys = Object.keys(component);
527
- if (keys.length === 0) {
528
- throw new Error(`Empty object at ${path}`);
529
- }
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}`);
534
- }
535
- if (value && typeof value === "object" && !Array.isArray(value)) {
536
- if (value.children) {
537
- validateComponent(value.children, `${path}.${key}.children`);
538
- }
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}`);
541
- }
542
- });
543
- return true;
544
- }
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;
550
- }
551
- const keys = Object.keys(obj);
552
- if (keys.length === 0) {
553
- return false;
554
- }
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 {};
563
- }
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 };
572
- }
573
- });
574
- return props;
575
- }
576
- function hasChildren(component) {
577
- if (Array.isArray(component)) {
578
- return component.length > 0;
579
- }
580
- if (isCoherentObject(component)) {
581
- if (component.children !== void 0 && component.children !== null) {
582
- return Array.isArray(component.children) ? component.children.length > 0 : true;
583
- }
584
- const keys = Object.keys(component);
585
- return keys.some((key) => {
586
- const value = component[key];
587
- return value && typeof value === "object" && value.children;
588
- });
589
- }
590
- return false;
591
- }
592
- function normalizeChildren(children) {
593
- if (children === null || children === void 0) {
594
- return [];
595
- }
596
- if (Array.isArray(children)) {
597
- return children.flat().filter((child) => child !== null && child !== void 0);
598
- }
599
- return [children];
600
- }
601
-
602
- // ../core/src/index.js
603
- var scopeCounter = { value: 0 };
604
- function generateScopeId() {
605
- return `coh-${scopeCounter.value++}`;
606
- }
607
- function scopeCSS(css, scopeId) {
608
- if (!css || typeof css !== "string") return css;
609
- return css.replace(/([^{}]*)\s*{/g, (match, selector) => {
610
- const selectors = selector.split(",").map((s) => {
611
- const trimmed = s.trim();
612
- if (!trimmed) return s;
613
- if (trimmed.includes(":")) {
614
- return trimmed.replace(/([^:]+)(:.*)?/, `$1[${scopeId}]$2`);
615
- }
616
- return `${trimmed}[${scopeId}]`;
617
- });
618
- return `${selectors.join(", ")} {`;
619
- });
620
- }
621
- function applyScopeToElement(element, scopeId) {
622
- if (typeof element === "string" || typeof element === "number" || !element) {
623
- return element;
624
- }
625
- if (Array.isArray(element)) {
626
- return element.map((item) => applyScopeToElement(item, scopeId));
627
- }
628
- if (typeof element === "object") {
629
- const scoped = {};
630
- for (const [tagName, props] of Object.entries(element)) {
631
- if (typeof props === "object" && props !== null) {
632
- const scopedProps = { ...props };
633
- scopedProps[scopeId] = "";
634
- if (scopedProps.children) {
635
- scopedProps.children = applyScopeToElement(scopedProps.children, scopeId);
636
- }
637
- scoped[tagName] = scopedProps;
638
- } else {
639
- scoped[tagName] = props;
640
- }
641
- }
642
- return scoped;
643
- }
644
- return element;
645
- }
646
- function escapeHtml(text) {
647
- if (typeof text !== "string") return text;
648
- return text.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#x27;");
649
- }
650
- function isTrustedContent(value) {
651
- return value && typeof value === "object" && value.__trusted === true && typeof value.__html === "string";
652
- }
653
- function isVoidElement(tagName) {
654
- const voidElements = /* @__PURE__ */ new Set([
655
- "area",
656
- "base",
657
- "br",
658
- "col",
659
- "embed",
660
- "hr",
661
- "img",
662
- "input",
663
- "link",
664
- "meta",
665
- "param",
666
- "source",
667
- "track",
668
- "wbr"
669
- ]);
670
- return voidElements.has(tagName.toLowerCase());
671
- }
672
- function formatAttributes(attrs) {
673
- if (!attrs || typeof attrs !== "object") return "";
674
- return Object.entries(attrs).filter(([, value]) => value !== null && value !== void 0 && value !== false).map(([key, value]) => {
675
- if (typeof value === "function") {
676
- value = value();
677
- }
678
- const attrName = key === "className" ? "class" : key;
679
- if (value === true) return attrName;
680
- return `${attrName}="${escapeHtml(String(value))}"`;
681
- }).join(" ");
682
- }
683
- function renderRaw(obj) {
684
- if (obj === null || obj === void 0) return "";
685
- if (typeof obj === "string" || typeof obj === "number") return escapeHtml(String(obj));
686
- if (Array.isArray(obj)) return obj.map(renderRaw).join("");
687
- if (typeof obj === "function") {
688
- const result = obj(renderRaw);
689
- return renderRaw(result);
690
- }
691
- if (typeof obj !== "object") return escapeHtml(String(obj));
692
- if (obj.text !== void 0) {
693
- return escapeHtml(String(obj.text));
694
- }
695
- for (const [tagName, props] of Object.entries(obj)) {
696
- if (typeof props === "object" && props !== null) {
697
- const { children, text, ...attributes } = props;
698
- const attrsStr = formatAttributes(attributes);
699
- const openTag = attrsStr ? `<${tagName} ${attrsStr}>` : `<${tagName}>`;
700
- if (isVoidElement(tagName)) {
701
- return openTag.replace(">", " />");
702
- }
703
- let content = "";
704
- if (text !== void 0) {
705
- if (isTrustedContent(text)) {
706
- content = text.__html;
707
- } else {
708
- content = escapeHtml(String(text));
709
- }
710
- } else if (children) {
711
- content = renderRaw(children);
712
- }
713
- return `${openTag}${content}</${tagName}>`;
714
- } else if (typeof props === "string") {
715
- const content = isTrustedContent(props) ? props.__html : escapeHtml(props);
716
- return isVoidElement(tagName) ? `<${tagName} />` : `<${tagName}>${content}</${tagName}>`;
717
- }
718
- }
719
- return "";
720
- }
721
- function render(obj, options = {}) {
722
- const { scoped = false } = options;
723
- if (scoped) {
724
- return renderScopedComponent(obj);
725
- }
726
- return renderRaw(obj);
727
- }
728
- function renderScopedComponent(component) {
729
- const scopeId = generateScopeId();
730
- function processScopedElement(element) {
731
- if (!element || typeof element !== "object") {
732
- return element;
733
- }
734
- if (Array.isArray(element)) {
735
- return element.map(processScopedElement);
736
- }
737
- const result = {};
738
- for (const [tagName, props] of Object.entries(element)) {
739
- if (tagName === "style" && typeof props === "object" && props.text) {
740
- result[tagName] = {
741
- ...props,
742
- text: scopeCSS(props.text, scopeId)
743
- };
744
- } else if (typeof props === "object" && props !== null) {
745
- const scopedProps = { ...props };
746
- if (scopedProps.children) {
747
- scopedProps.children = processScopedElement(scopedProps.children);
748
- }
749
- result[tagName] = scopedProps;
750
- } else {
751
- result[tagName] = props;
752
- }
753
- }
754
- return result;
755
- }
756
- const processedComponent = processScopedElement(component);
757
- const scopedComponent = applyScopeToElement(processedComponent, scopeId);
758
- return renderRaw(scopedComponent);
759
- }
760
-
761
- // ../core/src/utils/dependency-utils.js
762
- async function importPeerDependency(packageName, integrationName) {
763
- try {
764
- return await import(packageName);
765
- } catch {
766
- throw new Error(
767
- `${integrationName} integration requires the '${packageName}' package to be installed.
768
- Please install it with: npm install ${packageName}
769
- Or with pnpm: pnpm add ${packageName}
770
- Or with yarn: yarn add ${packageName}`
771
- );
772
- }
773
- }
774
-
775
- // ../core/src/rendering/base-renderer.js
776
- var DEFAULT_RENDERER_CONFIG = {
777
- // Core rendering options
778
- maxDepth: 100,
779
- enableValidation: true,
780
- enableMonitoring: false,
781
- validateInput: true,
782
- // HTML Renderer specific options
783
- enableCache: true,
784
- minify: false,
785
- cacheSize: 1e3,
786
- cacheTTL: 3e5,
787
- // 5 minutes
788
- // Streaming Renderer specific options
789
- chunkSize: 1024,
790
- // Size of each chunk in bytes
791
- bufferSize: 4096,
792
- // Internal buffer size
793
- enableMetrics: false,
794
- // Track streaming metrics
795
- yieldThreshold: 100,
796
- // Yield control after N elements
797
- encoding: "utf8",
798
- // Output encoding
799
- // DOM Renderer specific options
800
- enableHydration: true,
801
- // Enable hydration support
802
- namespace: null,
803
- // SVG namespace support
804
- // Performance options
805
- enablePerformanceTracking: false,
806
- performanceThreshold: 10,
807
- // ms threshold for slow renders
808
- // Development options
809
- enableDevWarnings: typeof process !== "undefined" && process.env && true,
810
- enableDebugLogging: false,
811
- // Error handling options
812
- errorFallback: "",
813
- // Fallback content on errors
814
- throwOnError: true
815
- // Whether to throw or return fallback
816
- };
817
- var BaseRenderer = class {
818
- constructor(options = {}) {
819
- this.config = this.validateAndMergeConfig(options);
820
- this.metrics = {
821
- startTime: null,
822
- endTime: null,
823
- elementsProcessed: 0
824
- };
825
- }
826
- /**
827
- * Validate and merge configuration options
828
- */
829
- validateAndMergeConfig(options) {
830
- const config = { ...DEFAULT_RENDERER_CONFIG, ...options };
831
- if (typeof config.maxDepth !== "number") {
832
- throw new Error("maxDepth must be a number");
833
- }
834
- if (config.maxDepth <= 0) {
835
- throw new Error("maxDepth must be a positive number");
836
- }
837
- if (typeof config.chunkSize !== "number") {
838
- throw new Error("chunkSize must be a number");
839
- }
840
- if (config.chunkSize <= 0) {
841
- throw new Error("chunkSize must be a positive number");
842
- }
843
- if (typeof config.yieldThreshold !== "number") {
844
- throw new Error("yieldThreshold must be a number");
845
- }
846
- if (config.yieldThreshold <= 0) {
847
- throw new Error("yieldThreshold must be a positive number");
848
- }
849
- if (config.enableDevWarnings) {
850
- if (config.maxDepth > 1e3) {
851
- console.warn("Coherent.js: maxDepth > 1000 may cause performance issues");
852
- }
853
- if (config.chunkSize > 16384) {
854
- console.warn("Coherent.js: Large chunkSize may increase memory usage");
855
- }
856
- }
857
- return config;
858
- }
859
- /**
860
- * Get configuration for specific renderer type
861
- */
862
- getRendererConfig(rendererType) {
863
- const baseConfig = { ...this.config };
864
- switch (rendererType) {
865
- case "html":
866
- return {
867
- ...baseConfig,
868
- // HTML-specific defaults
869
- enableCache: baseConfig.enableCache !== false,
870
- enableMonitoring: baseConfig.enableMonitoring !== false
871
- };
872
- case "streaming":
873
- return {
874
- ...baseConfig,
875
- // Streaming-specific defaults
876
- enableMetrics: baseConfig.enableMetrics ?? false,
877
- maxDepth: baseConfig.maxDepth ?? 1e3
878
- // Higher default for streaming
879
- };
880
- case "dom":
881
- return {
882
- ...baseConfig,
883
- // DOM-specific defaults
884
- enableHydration: baseConfig.enableHydration !== false
885
- };
886
- default:
887
- return baseConfig;
888
- }
889
- }
890
- /**
891
- * Validate component structure
892
- */
893
- validateComponent(component) {
894
- if (this.config.validateInput !== false) {
895
- return validateComponent(component);
896
- }
897
- return true;
898
- }
899
- /**
900
- * Check if component is valid for rendering
901
- */
902
- isValidComponent(component) {
903
- if (component === null || component === void 0) return true;
904
- if (typeof component === "string" || typeof component === "number") return true;
905
- if (typeof component === "function") return true;
906
- if (Array.isArray(component)) return component.every((child) => this.isValidComponent(child));
907
- if (isCoherentObject(component)) return true;
908
- return false;
909
- }
910
- /**
911
- * Validate rendering depth to prevent stack overflow
912
- */
913
- validateDepth(depth) {
914
- if (depth > this.config.maxDepth) {
915
- throw new Error(`Maximum render depth (${this.config.maxDepth}) exceeded`);
916
- }
917
- }
918
- /**
919
- * Handle different component types with consistent logic
920
- */
921
- processComponentType(component) {
922
- if (component === null || component === void 0) {
923
- return { type: "empty", value: "" };
924
- }
925
- if (typeof component === "string") {
926
- return { type: "text", value: component };
927
- }
928
- if (typeof component === "number" || typeof component === "boolean") {
929
- return { type: "text", value: String(component) };
930
- }
931
- if (typeof component === "function") {
932
- return { type: "function", value: component };
933
- }
934
- if (Array.isArray(component)) {
935
- return { type: "array", value: component };
936
- }
937
- if (isCoherentObject(component)) {
938
- return { type: "element", value: component };
939
- }
940
- return { type: "unknown", value: component };
941
- }
942
- /**
943
- * Execute function components with _error handling
944
- */
945
- executeFunctionComponent(func, depth = 0) {
946
- try {
947
- const isContextProvider = func.length > 0 || func.isContextProvider;
948
- let result;
949
- if (isContextProvider) {
950
- result = func((children) => {
951
- return this.renderComponent(children, this.config, depth + 1);
952
- });
953
- } else {
954
- result = func();
955
- }
956
- if (typeof result === "function") {
957
- return this.executeFunctionComponent(result, depth);
958
- }
959
- return result;
960
- } catch (_error) {
961
- if (this.config.enableMonitoring) {
962
- performanceMonitor2.recordError("functionComponent", _error);
963
- }
964
- if (typeof process !== "undefined" && process.env && true) {
965
- console.warn("Coherent.js Function Component Error:", _error.message);
966
- }
967
- return null;
968
- }
969
- }
970
- /**
971
- * Process element children consistently
972
- */
973
- processChildren(children, options, depth) {
974
- if (!hasChildren({ children })) {
975
- return [];
976
- }
977
- const normalizedChildren = normalizeChildren(children);
978
- return normalizedChildren.map(
979
- (child) => this.renderComponent(child, options, depth + 1)
980
- );
981
- }
982
- /**
983
- * Extract and process element attributes
984
- */
985
- extractElementAttributes(props) {
986
- if (!props || typeof props !== "object") return {};
987
- const attributes = { ...props };
988
- delete attributes.children;
989
- delete attributes.text;
990
- return attributes;
991
- }
992
- /**
993
- * Record performance metrics
994
- */
995
- recordPerformance(operation, startTime, fromCache = false, metadata = {}) {
996
- if (this.config.enableMonitoring) {
997
- performanceMonitor2.recordRender(
998
- operation,
999
- this.getCurrentTime() - startTime,
1000
- fromCache,
1001
- metadata
1002
- );
1003
- }
1004
- }
1005
- /**
1006
- * Record _error for monitoring
1007
- */
1008
- recordError(operation, _error, metadata = {}) {
1009
- if (this.config.enableMonitoring) {
1010
- performanceMonitor2.recordError(operation, _error, metadata);
1011
- }
1012
- }
1013
- /**
1014
- * Get current timestamp with fallback
1015
- */
1016
- getCurrentTime() {
1017
- if (typeof performance !== "undefined" && performance.now) {
1018
- return performance.now();
1019
- }
1020
- return Date.now();
1021
- }
1022
- /**
1023
- * Start performance timing
1024
- */
1025
- startTiming() {
1026
- this.metrics.startTime = this.getCurrentTime();
1027
- }
1028
- /**
1029
- * End performance timing
1030
- */
1031
- endTiming() {
1032
- this.metrics.endTime = this.getCurrentTime();
1033
- }
1034
- /**
1035
- * Get performance metrics
1036
- */
1037
- getMetrics() {
1038
- const duration = this.metrics.endTime ? this.metrics.endTime - this.metrics.startTime : this.getCurrentTime() - this.metrics.startTime;
1039
- return {
1040
- ...this.metrics,
1041
- duration,
1042
- elementsPerSecond: this.metrics.elementsProcessed / (duration / 1e3)
1043
- };
1044
- }
1045
- /**
1046
- * Reset metrics for new render
1047
- */
1048
- resetMetrics() {
1049
- this.metrics = {
1050
- startTime: null,
1051
- endTime: null,
1052
- elementsProcessed: 0
1053
- };
1054
- }
1055
- /**
1056
- * Abstract method - must be implemented by subclasses
1057
- */
1058
- renderComponent() {
1059
- throw new Error("renderComponent must be implemented by subclass");
1060
- }
1061
- /**
1062
- * Abstract method - must be implemented by subclasses
1063
- */
1064
- render() {
1065
- throw new Error("render must be implemented by subclass");
1066
- }
1067
- };
1068
- var RendererUtils = {
1069
- /**
1070
- * Check if element is static (no functions)
1071
- */
1072
- isStaticElement(element) {
1073
- if (!element || typeof element !== "object") {
1074
- return typeof element === "string" || typeof element === "number";
1075
- }
1076
- for (const [key, value] of Object.entries(element)) {
1077
- if (typeof value === "function") return false;
1078
- if (key === "children" && Array.isArray(value)) {
1079
- return value.every((child) => RendererUtils.isStaticElement(child));
1080
- }
1081
- if (key === "children" && typeof value === "object" && value !== null) {
1082
- return RendererUtils.isStaticElement(value);
1083
- }
1084
- }
1085
- return true;
1086
- },
1087
- /**
1088
- * Check if object has functions (for caching decisions)
1089
- */
1090
- hasFunctions(obj, visited = /* @__PURE__ */ new WeakSet()) {
1091
- if (visited.has(obj)) return false;
1092
- visited.add(obj);
1093
- for (const value of Object.values(obj)) {
1094
- if (typeof value === "function") return true;
1095
- if (typeof value === "object" && value !== null && RendererUtils.hasFunctions(value, visited)) {
1096
- return true;
1097
- }
1098
- }
1099
- return false;
1100
- },
1101
- /**
1102
- * Get element complexity score
1103
- */
1104
- getElementComplexity(element) {
1105
- if (!element || typeof element !== "object") return 1;
1106
- let complexity = Object.keys(element).length;
1107
- if (element.children && Array.isArray(element.children)) {
1108
- complexity += element.children.reduce(
1109
- (sum, child) => sum + RendererUtils.getElementComplexity(child),
1110
- 0
1111
- );
1112
- }
1113
- return complexity;
1114
- },
1115
- /**
1116
- * Generate cache key for element
1117
- */
1118
- generateCacheKey(tagName, element) {
1119
- try {
1120
- const keyData = {
1121
- tag: tagName,
1122
- props: extractProps(element),
1123
- hasChildren: hasChildren(element),
1124
- childrenType: Array.isArray(element.children) ? "array" : typeof element.children
1125
- };
1126
- return `element:${JSON.stringify(keyData)}`;
1127
- } catch (_error) {
1128
- if (typeof process !== "undefined" && process.env && true) {
1129
- console.warn("Failed to generate cache key:", _error);
1130
- }
1131
- return null;
1132
- }
1133
- },
1134
- /**
1135
- * Check if element is cacheable
1136
- */
1137
- isCacheable(element, options) {
1138
- if (!options.enableCache) return false;
1139
- if (RendererUtils.hasFunctions(element)) return false;
1140
- if (RendererUtils.getElementComplexity(element) > 1e3) return false;
1141
- const cacheKey = RendererUtils.generateCacheKey(element.tagName || "unknown", element);
1142
- if (!cacheKey) return false;
1143
- return true;
1144
- }
1145
- };
1146
-
1147
- // ../core/src/core/html-utils.js
1148
- function escapeHtml2(text) {
1149
- if (typeof text !== "string") return text;
1150
- return text.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
1151
- }
1152
- function isVoidElement2(tagName) {
1153
- if (typeof tagName !== "string") {
1154
- return false;
1155
- }
1156
- const voidElements = /* @__PURE__ */ new Set([
1157
- "area",
1158
- "base",
1159
- "br",
1160
- "col",
1161
- "embed",
1162
- "hr",
1163
- "img",
1164
- "input",
1165
- "link",
1166
- "meta",
1167
- "param",
1168
- "source",
1169
- "track",
1170
- "wbr"
1171
- ]);
1172
- return voidElements.has(tagName.toLowerCase());
1173
- }
1174
- function formatAttributes2(props) {
1175
- let formatted = "";
1176
- for (const key in props) {
1177
- if (props.hasOwnProperty(key)) {
1178
- let value = props[key];
1179
- const attributeName = key === "className" ? "class" : key;
1180
- if (typeof value === "function") {
1181
- if (attributeName.startsWith("on")) {
1182
- const actionId = `__coherent_action_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
1183
- const DEBUG = typeof process !== "undefined" && process && process.env && (process.env.COHERENT_DEBUG === "1" || true) || typeof window !== "undefined" && window && window.COHERENT_DEBUG === true;
1184
- if (typeof global !== "undefined") {
1185
- if (!global.__coherentActionRegistry) {
1186
- global.__coherentActionRegistry = {};
1187
- if (DEBUG) console.log("Initialized global action registry");
1188
- }
1189
- global.__coherentActionRegistry[actionId] = value;
1190
- if (DEBUG) console.log(`Added action ${actionId} to global registry, total: ${Object.keys(global.__coherentActionRegistry).length}`);
1191
- if (DEBUG) console.log(`Global registry keys: ${Object.keys(global.__coherentActionRegistry).join(", ")}`);
1192
- if (DEBUG) {
1193
- if (typeof global.__coherentActionRegistryLog === "undefined") {
1194
- global.__coherentActionRegistryLog = [];
1195
- }
1196
- global.__coherentActionRegistryLog.push({
1197
- action: "add",
1198
- actionId,
1199
- timestamp: Date.now(),
1200
- registrySize: Object.keys(global.__coherentActionRegistry).length
1201
- });
1202
- }
1203
- } else if (typeof window !== "undefined") {
1204
- if (!window.__coherentActionRegistry) {
1205
- window.__coherentActionRegistry = {};
1206
- if (DEBUG) console.log("Initialized window action registry");
1207
- }
1208
- window.__coherentActionRegistry[actionId] = value;
1209
- if (DEBUG) console.log(`Added action ${actionId} to window registry, total: ${Object.keys(window.__coherentActionRegistry).length}`);
1210
- if (DEBUG) console.log(`Window registry keys: ${Object.keys(window.__coherentActionRegistry).join(", ")}`);
1211
- }
1212
- const eventType = attributeName.substring(2);
1213
- formatted += ` data-action="${actionId}" data-event="${eventType}"`;
1214
- continue;
1215
- } else {
1216
- try {
1217
- value = value();
1218
- } catch (_error) {
1219
- console.warn(`Error executing function for attribute '${key}':`, {
1220
- _error: _error.message,
1221
- stack: _error.stack,
1222
- attributeKey: key
1223
- });
1224
- value = "";
1225
- }
1226
- }
1227
- }
1228
- if (value === true) {
1229
- formatted += ` ${attributeName}`;
1230
- } else if (value !== false && value !== null && value !== void 0) {
1231
- formatted += ` ${attributeName}="${escapeHtml2(String(value))}"`;
1232
- }
1233
- }
1234
- }
1235
- return formatted.trim();
1236
- }
1237
- function minifyHtml(html, options = {}) {
1238
- if (!options.minify) return html;
1239
- return html.replace(/<!--[\s\S]*?-->/g, "").replace(/\s+/g, " ").replace(/>\s+</g, "><").trim();
1240
- }
1241
-
1242
- // ../core/src/performance/cache-manager.js
1243
- function createCacheManager(options = {}) {
1244
- const {
1245
- maxCacheSize = 1e3,
1246
- maxMemoryMB = 100,
1247
- ttlMs = 1e3 * 60 * 5,
1248
- // 5 minutes
1249
- enableStatistics = true
1250
- } = options;
1251
- const caches = {
1252
- static: /* @__PURE__ */ new Map(),
1253
- // Never-changing components
1254
- component: /* @__PURE__ */ new Map(),
1255
- // Component results with deps
1256
- template: /* @__PURE__ */ new Map(),
1257
- // Template strings
1258
- data: /* @__PURE__ */ new Map()
1259
- // General purpose data
1260
- };
1261
- let memoryUsage = 0;
1262
- const stats = {
1263
- hits: 0,
1264
- misses: 0,
1265
- hitRate: {
1266
- static: 0,
1267
- component: 0,
1268
- template: 0,
1269
- data: 0
1270
- },
1271
- accessCount: {
1272
- static: 0,
1273
- component: 0,
1274
- template: 0,
1275
- data: 0
1276
- }
1277
- };
1278
- let cleanupInterval;
1279
- if (typeof setInterval === "function") {
1280
- cleanupInterval = setInterval(() => cleanup(), 3e4);
1281
- if (cleanupInterval.unref) {
1282
- cleanupInterval.unref();
1283
- }
1284
- }
1285
- function generateCacheKey(component, props = {}, context = {}) {
1286
- const componentStr = typeof component === "function" ? component.name || component.toString() : JSON.stringify(component);
1287
- const propsStr = JSON.stringify(props, Object.keys(props).sort());
1288
- const contextStr = JSON.stringify(context);
1289
- const hash = simpleHash(componentStr + propsStr + contextStr);
1290
- return `${extractComponentName(component)}_${hash}`;
1291
- }
1292
- function get(key, type = "component") {
1293
- const cache = caches[type] || caches.component;
1294
- const entry = cache.get(key);
1295
- if (!entry) {
1296
- stats.misses++;
1297
- if (enableStatistics) stats.accessCount[type]++;
1298
- return null;
1299
- }
1300
- if (Date.now() - entry.timestamp > ttlMs) {
1301
- cache.delete(key);
1302
- updateMemoryUsage(-entry.size);
1303
- stats.misses++;
1304
- if (enableStatistics) stats.accessCount[type]++;
1305
- return null;
1306
- }
1307
- entry.lastAccess = Date.now();
1308
- entry.accessCount++;
1309
- stats.hits++;
1310
- if (enableStatistics) {
1311
- stats.accessCount[type]++;
1312
- stats.hitRate[type] = stats.hits / (stats.hits + stats.misses) * 100;
1313
- }
1314
- return entry.value;
1315
- }
1316
- function set(key, value, type = "component", metadata = {}) {
1317
- const cache = caches[type] || caches.component;
1318
- const size = calculateSize(value);
1319
- if (memoryUsage + size > maxMemoryMB * 1024 * 1024) {
1320
- optimize(type, size);
1321
- }
1322
- const entry = {
1323
- value,
1324
- timestamp: Date.now(),
1325
- lastAccess: Date.now(),
1326
- size,
1327
- metadata,
1328
- accessCount: 0
1329
- };
1330
- const existing = cache.get(key);
1331
- if (existing) {
1332
- updateMemoryUsage(-existing.size);
1333
- }
1334
- cache.set(key, entry);
1335
- updateMemoryUsage(size);
1336
- if (cache.size > maxCacheSize) {
1337
- optimize(type);
1338
- }
1339
- }
1340
- function remove(key, type) {
1341
- if (type) {
1342
- const cache = caches[type];
1343
- if (!cache) return false;
1344
- const entry = cache.get(key);
1345
- if (entry) {
1346
- updateMemoryUsage(-entry.size);
1347
- return cache.delete(key);
1348
- }
1349
- return false;
1350
- }
1351
- for (const [, cache] of Object.entries(caches)) {
1352
- const entry = cache.get(key);
1353
- if (entry) {
1354
- updateMemoryUsage(-entry.size);
1355
- return cache.delete(key);
1356
- }
1357
- }
1358
- return false;
1359
- }
1360
- function clear(type) {
1361
- if (type) {
1362
- const cache = caches[type];
1363
- if (cache) {
1364
- cache.clear();
1365
- }
1366
- } else {
1367
- Object.values(caches).forEach((cache) => cache.clear());
1368
- }
1369
- memoryUsage = 0;
1370
- }
1371
- function getStats() {
1372
- const entries = Object.values(caches).reduce((sum, cache) => sum + cache.size, 0);
1373
- return {
1374
- hits: stats.hits,
1375
- misses: stats.misses,
1376
- size: memoryUsage,
1377
- entries,
1378
- hitRate: stats.hitRate,
1379
- accessCount: stats.accessCount
1380
- };
1381
- }
1382
- function cleanup() {
1383
- const now = Date.now();
1384
- let freed = 0;
1385
- for (const [, cache] of Object.entries(caches)) {
1386
- for (const [key, entry] of cache.entries()) {
1387
- if (now - entry.timestamp > ttlMs) {
1388
- cache.delete(key);
1389
- updateMemoryUsage(-entry.size);
1390
- freed++;
1391
- }
1392
- }
1393
- }
1394
- return { freed };
1395
- }
1396
- function calculateSize(value) {
1397
- if (value === null || value === void 0) return 0;
1398
- if (typeof value === "string") return value.length * 2;
1399
- if (typeof value === "number") return 8;
1400
- if (typeof value === "boolean") return 4;
1401
- if (Array.isArray(value)) {
1402
- return value.reduce((sum, item) => sum + calculateSize(item), 0);
1403
- }
1404
- if (typeof value === "object") {
1405
- return Object.values(value).reduce((sum, val) => sum + calculateSize(val), 0);
1406
- }
1407
- return 0;
1408
- }
1409
- function updateMemoryUsage(delta) {
1410
- memoryUsage = Math.max(0, memoryUsage + delta);
1411
- }
1412
- function optimize(type, requiredSpace = 0) {
1413
- const cache = caches[type] || caches.component;
1414
- const entries = Array.from(cache.entries()).sort(([, a], [, b]) => a.lastAccess - b.lastAccess);
1415
- let freed = 0;
1416
- for (const [key, entry] of entries) {
1417
- if (freed >= requiredSpace) break;
1418
- cache.delete(key);
1419
- updateMemoryUsage(-entry.size);
1420
- freed += entry.size;
1421
- }
1422
- return { freed };
1423
- }
1424
- function simpleHash(str) {
1425
- let hash = 0;
1426
- for (let i = 0; i < str.length; i++) {
1427
- const char = str.charCodeAt(i);
1428
- hash = (hash << 5) - hash + char;
1429
- hash = hash & hash;
1430
- }
1431
- return Math.abs(hash).toString(36);
1432
- }
1433
- function extractComponentName(component) {
1434
- if (typeof component === "function") {
1435
- return component.name || "AnonymousComponent";
1436
- }
1437
- if (component && typeof component === "object") {
1438
- const keys = Object.keys(component);
1439
- return keys.length > 0 ? keys[0] : "ObjectComponent";
1440
- }
1441
- return "UnknownComponent";
1442
- }
1443
- function destroy() {
1444
- if (cleanupInterval) {
1445
- clearInterval(cleanupInterval);
1446
- }
1447
- clear();
1448
- }
1449
- return {
1450
- get,
1451
- set,
1452
- remove,
1453
- clear,
1454
- getStats,
1455
- cleanup,
1456
- destroy,
1457
- generateCacheKey,
1458
- get memoryUsage() {
1459
- return memoryUsage;
1460
- },
1461
- get maxMemory() {
1462
- return maxMemoryMB * 1024 * 1024;
1463
- }
1464
- };
1465
- }
1466
- var cacheManager = createCacheManager();
1467
-
1468
- // ../core/src/rendering/html-renderer.js
1469
- var rendererCache = createCacheManager({
1470
- maxSize: 1e3,
1471
- ttlMs: 3e5
1472
- // 5 minutes
1473
- });
1474
- var HTMLRenderer = class extends BaseRenderer {
1475
- constructor(options = {}) {
1476
- super({
1477
- enableCache: options.enableCache !== false,
1478
- enableMonitoring: options.enableMonitoring !== false,
1479
- minify: options.minify || false,
1480
- streaming: options.streaming || false,
1481
- maxDepth: options.maxDepth || 100,
1482
- ...options
1483
- });
1484
- if (this.config.enableCache && !this.cache) {
1485
- this.cache = rendererCache;
1486
- }
1487
- }
1488
- /**
1489
- * Main render method - converts components to HTML string
1490
- *
1491
- * @param {Object|Array|string|Function} component - Component to render
1492
- * @param {Object} [options={}] - Rendering options
1493
- * @param {Object} [options.context] - Rendering context
1494
- * @param {boolean} [options.enableCache] - Override cache setting
1495
- * @param {number} [options.depth=0] - Current rendering depth
1496
- * @returns {string} Rendered HTML string
1497
- *
1498
- * @example
1499
- * const html = renderer.render({
1500
- * div: {
1501
- * className: 'container',
1502
- * children: [
1503
- * { h1: { text: 'Title' } },
1504
- * { p: { text: 'Content' } }
1505
- * ]
1506
- * }
1507
- * });
1508
- */
1509
- render(component, options = {}) {
1510
- const config = { ...this.config, ...options };
1511
- this.startTiming();
1512
- try {
1513
- if (config.validateInput && !this.isValidComponent(component)) {
1514
- throw new Error("Invalid component structure");
1515
- }
1516
- const html = this.renderComponent(component, config, 0);
1517
- const finalHtml = config.minify ? minifyHtml(html, config) : html;
1518
- this.endTiming();
1519
- this.recordPerformance("render", this.metrics.startTime, false, {
1520
- cacheEnabled: config.enableCache
1521
- });
1522
- return finalHtml;
1523
- } catch (_error) {
1524
- this.recordError("render", _error);
1525
- throw _error;
1526
- }
1527
- }
1528
- /**
1529
- * Render a single component with full optimization pipeline
1530
- */
1531
- renderComponent(component, options, depth = 0) {
1532
- this.validateDepth(depth);
1533
- const { type, value } = this.processComponentType(component);
1534
- switch (type) {
1535
- case "empty":
1536
- return "";
1537
- case "text":
1538
- return escapeHtml2(value);
1539
- case "function":
1540
- const result = this.executeFunctionComponent(value, depth);
1541
- return this.renderComponent(result, options, depth + 1);
1542
- case "array":
1543
- return value.map((child) => this.renderComponent(child, options, depth + 1)).join("");
1544
- case "element":
1545
- const tagName = Object.keys(value)[0];
1546
- const elementContent = value[tagName];
1547
- return this.renderElement(tagName, elementContent, options, depth);
1548
- default:
1549
- this.recordError("renderComponent", new Error(`Unknown component type: ${type}`));
1550
- return "";
1551
- }
1552
- }
1553
- /**
1554
- * Render an HTML element with advanced caching and optimization
1555
- */
1556
- renderElement(tagName, element, options, depth = 0) {
1557
- const startTime = performance.now();
1558
- if (options.enableMonitoring && this.cache) {
1559
- }
1560
- if (options.enableCache && this.cache && RendererUtils.isStaticElement(element)) {
1561
- const cacheKey = `static:${tagName}:${JSON.stringify(element)}`;
1562
- const cached = this.cache.get("static", cacheKey);
1563
- if (cached) {
1564
- this.recordPerformance(tagName, startTime, true);
1565
- return cached.value;
1566
- }
1567
- }
1568
- if (typeof element === "string" || typeof element === "number" || typeof element === "boolean") {
1569
- const html2 = isVoidElement2(tagName) ? `<${tagName}>` : `<${tagName}>${escapeHtml2(String(element))}</${tagName}>`;
1570
- this.cacheIfStatic(tagName, element, html2, options);
1571
- this.recordPerformance(tagName, startTime, false);
1572
- return html2;
1573
- }
1574
- if (typeof element === "function") {
1575
- const result = this.executeFunctionComponent(element, depth);
1576
- return this.renderElement(tagName, result, options, depth);
1577
- }
1578
- if (element && typeof element === "object") {
1579
- return this.renderObjectElement(tagName, element, options, depth);
1580
- }
1581
- if (element === null || element === void 0) {
1582
- const html2 = isVoidElement2(tagName) ? `<${tagName}>` : `<${tagName}></${tagName}>`;
1583
- this.recordPerformance(tagName, startTime, false);
1584
- return html2;
1585
- }
1586
- const html = `<${tagName}>${escapeHtml2(String(element))}</${tagName}>`;
1587
- this.recordPerformance(tagName, startTime, false);
1588
- return html;
1589
- }
1590
- /**
1591
- * Cache element if it's static
1592
- */
1593
- cacheIfStatic(tagName, element, html) {
1594
- if (this.config.enableCache && this.cache && RendererUtils.isStaticElement(element)) {
1595
- const cacheKey = `static:${tagName}:${JSON.stringify(element)}`;
1596
- this.cache.set("static", cacheKey, html, {
1597
- ttlMs: this.config.cacheTTL || 5 * 60 * 1e3,
1598
- // 5 minutes default
1599
- size: html.length
1600
- // Approximate size
1601
- });
1602
- }
1603
- }
1604
- /**
1605
- * Render complex object elements with attributes and children
1606
- */
1607
- renderObjectElement(tagName, element, options, depth = 0) {
1608
- const startTime = performance.now();
1609
- if (options.enableCache && this.cache) {
1610
- const cacheKey = RendererUtils.generateCacheKey(tagName, element);
1611
- if (cacheKey) {
1612
- const cached = this.cache.get(cacheKey);
1613
- if (cached) {
1614
- this.recordPerformance(tagName, startTime, true);
1615
- return cached;
1616
- }
1617
- }
1618
- }
1619
- const { children, text, ...attributes } = element || {};
1620
- const attributeString = formatAttributes2(attributes);
1621
- const openingTag = attributeString ? `<${tagName} ${attributeString}>` : `<${tagName}>`;
1622
- let textContent = "";
1623
- if (text !== void 0) {
1624
- const isScript = tagName === "script";
1625
- const isStyle = tagName === "style";
1626
- const isRawTag = isScript || isStyle;
1627
- const raw = typeof text === "function" ? String(text()) : String(text);
1628
- if (isRawTag) {
1629
- const safe = raw.replace(/<\/(script)/gi, "<\\/$1").replace(/<\/(style)/gi, "<\\/$1").replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
1630
- textContent = safe;
1631
- } else {
1632
- textContent = escapeHtml2(raw);
1633
- }
1634
- }
1635
- let childrenHtml = "";
1636
- if (hasChildren(element)) {
1637
- const normalizedChildren = normalizeChildren(children);
1638
- childrenHtml = normalizedChildren.map((child) => this.renderComponent(child, options, depth + 1)).join("");
1639
- }
1640
- const html = `${openingTag}${textContent}${childrenHtml}</${tagName}>`;
1641
- if (options.enableCache && this.cache && RendererUtils.isCacheable(element, options)) {
1642
- const cacheKey = RendererUtils.generateCacheKey(tagName, element);
1643
- if (cacheKey) {
1644
- this.cache.set(cacheKey, html);
1645
- }
1646
- }
1647
- this.recordPerformance(tagName, startTime, false);
1648
- return html;
1649
- }
1650
- };
1651
- function render2(component, options = {}) {
1652
- const mergedOptions = {
1653
- enableCache: true,
1654
- enableMonitoring: false,
1655
- ...options
1656
- };
1657
- const renderer = new HTMLRenderer(mergedOptions);
1658
- return renderer.render(component, mergedOptions);
1659
- }
1660
-
1661
- // ../core/src/utils/render-utils.js
1662
- function renderWithMonitoring(component, options = {}) {
1663
- const {
1664
- enablePerformanceMonitoring = false
1665
- } = options;
1666
- let html;
1667
- if (enablePerformanceMonitoring) {
1668
- const renderId = performanceMonitor2.startRender();
1669
- html = render2(component);
1670
- performanceMonitor2.endRender(renderId);
1671
- } else {
1672
- html = render2(component);
1673
- }
1674
- return html;
1675
- }
1676
- function renderWithTemplate(component, options = {}) {
1677
- const {
1678
- template = "<!DOCTYPE html>\n{{content}}"
1679
- } = options;
1680
- const html = renderWithMonitoring(component, options);
1681
- return template.replace("{{content}}", html);
1682
- }
1683
- async function renderComponentFactory(componentFactory, factoryArgs, options = {}) {
1684
- const component = await Promise.resolve(
1685
- componentFactory(...factoryArgs)
1686
- );
1687
- if (!component) {
1688
- throw new Error("Component factory returned null/undefined");
1689
- }
1690
- return renderWithTemplate(component, options);
1691
- }
1692
-
1693
32
  // src/coherent-nextjs.js
33
+ var import_core = require("@coherent.js/core");
1694
34
  function createCoherentNextHandler(componentFactory, options = {}) {
1695
35
  return async (req, res) => {
1696
36
  try {
1697
- const finalHtml = await renderComponentFactory(
37
+ const finalHtml = await (0, import_core.renderComponentFactory)(
1698
38
  componentFactory,
1699
39
  [req, res],
1700
40
  options
@@ -1710,7 +50,7 @@ function createCoherentNextHandler(componentFactory, options = {}) {
1710
50
  function createCoherentAppRouterHandler(componentFactory, options = {}) {
1711
51
  return async function handler(request) {
1712
52
  try {
1713
- const finalHtml = await renderComponentFactory(
53
+ const finalHtml = await (0, import_core.renderComponentFactory)(
1714
54
  componentFactory,
1715
55
  [request],
1716
56
  options
@@ -1737,7 +77,7 @@ async function createCoherentServerComponent(componentFactory, options = {}) {
1737
77
  } = options;
1738
78
  let React;
1739
79
  try {
1740
- React = await importPeerDependency("react", "React");
80
+ React = await (0, import_core.importPeerDependency)("react", "React");
1741
81
  } catch (_error) {
1742
82
  throw new Error(
1743
83
  `Next.js Server Component integration requires React. ${_error.message}`
@@ -1753,11 +93,11 @@ async function createCoherentServerComponent(componentFactory, options = {}) {
1753
93
  }
1754
94
  let html;
1755
95
  if (enablePerformanceMonitoring) {
1756
- const renderId = performanceMonitor.startRender();
1757
- html = render(component);
1758
- performanceMonitor.endRender(renderId);
96
+ const renderId = import_core.performanceMonitor.startRender();
97
+ html = (0, import_core.render)(component);
98
+ import_core.performanceMonitor.endRender(renderId);
1759
99
  } else {
1760
- html = render(component);
100
+ html = (0, import_core.render)(component);
1761
101
  }
1762
102
  return React.default.createElement("div", {
1763
103
  dangerouslySetInnerHTML: { __html: html }
@@ -1774,7 +114,7 @@ async function createCoherentClientComponent(componentFactory, options = {}) {
1774
114
  } = options;
1775
115
  let React;
1776
116
  try {
1777
- React = await importPeerDependency("react", "React");
117
+ React = await (0, import_core.importPeerDependency)("react", "React");
1778
118
  } catch (_error) {
1779
119
  throw new Error(
1780
120
  `Next.js Client Component integration requires React. ${_error.message}`
@@ -1794,11 +134,11 @@ async function createCoherentClientComponent(componentFactory, options = {}) {
1794
134
  }
1795
135
  let renderedHtml;
1796
136
  if (enablePerformanceMonitoring) {
1797
- const renderId = performanceMonitor.startRender();
1798
- renderedHtml = render(component);
1799
- performanceMonitor.endRender(renderId);
137
+ const renderId = import_core.performanceMonitor.startRender();
138
+ renderedHtml = (0, import_core.render)(component);
139
+ import_core.performanceMonitor.endRender(renderId);
1800
140
  } else {
1801
- renderedHtml = render(component);
141
+ renderedHtml = (0, import_core.render)(component);
1802
142
  }
1803
143
  setHtml(renderedHtml);
1804
144
  } catch (_error) {
@@ -1815,8 +155,8 @@ async function createCoherentClientComponent(componentFactory, options = {}) {
1815
155
  }
1816
156
  async function createNextIntegration(options = {}) {
1817
157
  try {
1818
- await importPeerDependency("next", "Next.js");
1819
- await importPeerDependency("react", "React");
158
+ await (0, import_core.importPeerDependency)("next", "Next.js");
159
+ await (0, import_core.importPeerDependency)("react", "React");
1820
160
  return {
1821
161
  createCoherentNextHandler: (componentFactory, handlerOptions = {}) => createCoherentNextHandler(componentFactory, { ...options, ...handlerOptions }),
1822
162
  createCoherentAppRouterHandler: (componentFactory, handlerOptions = {}) => createCoherentAppRouterHandler(componentFactory, { ...options, ...handlerOptions }),
@@ -1842,18 +182,4 @@ var coherent_nextjs_default = {
1842
182
  createCoherentServerComponent,
1843
183
  createNextIntegration
1844
184
  });
1845
- /**
1846
- * Coherent.js - Object-Based Rendering Framework
1847
- * A pure JavaScript framework for server-side rendering using natural object syntax
1848
- *
1849
- * @version 2.0.0
1850
- * @author Coherent Framework Team
1851
- * @license MIT
1852
- */
1853
- /**
1854
- * Advanced caching system with memory management and smart invalidation for Coherent.js
1855
- *
1856
- * @module @coherent/performance/cache-manager
1857
- * @license MIT
1858
- */
1859
185
  //# sourceMappingURL=index.cjs.map