@memberjunction/react-test-harness 2.111.0 → 2.112.0

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.
@@ -24,7 +24,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
24
24
  };
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
26
  exports.ComponentRunner = void 0;
27
- const core_1 = require("@memberjunction/core");
27
+ const global_1 = require("@memberjunction/global");
28
28
  const component_linter_1 = require("./component-linter");
29
29
  const core_entities_1 = require("@memberjunction/core-entities");
30
30
  const ai_vectors_memory_1 = require("@memberjunction/ai-vectors-memory");
@@ -63,10 +63,10 @@ class ComponentRunner {
63
63
  async lintComponent(componentCode, componentName, componentSpec, isRootComponent, contextUser, options) {
64
64
  const lintResult = await component_linter_1.ComponentLinter.lintComponent(componentCode, componentName, componentSpec, isRootComponent, contextUser, false, // debugMode
65
65
  options);
66
- const hasErrors = lintResult.violations.some(v => v.severity === 'critical' || v.severity === 'high');
66
+ const hasErrors = lintResult.violations.some((v) => v.severity === 'critical' || v.severity === 'high');
67
67
  return {
68
68
  violations: lintResult.violations,
69
- hasErrors
69
+ hasErrors,
70
70
  };
71
71
  }
72
72
  async executeComponent(options) {
@@ -89,7 +89,7 @@ class ComponentRunner {
89
89
  page.setDefaultTimeout(globalTimeout);
90
90
  // Load component metadata and libraries first (needed for library loading)
91
91
  await core_entities_1.ComponentMetadataEngine.Instance.Config(false, options.contextUser);
92
- const allLibraries = core_entities_1.ComponentMetadataEngine.Instance.ComponentLibraries.map(c => c.GetAll());
92
+ const allLibraries = core_entities_1.ComponentMetadataEngine.Instance.ComponentLibraries.map((c) => c.GetAll());
93
93
  try {
94
94
  // Navigate to a blank page FIRST, then load runtime
95
95
  await page.goto('about:blank');
@@ -101,12 +101,12 @@ class ComponentRunner {
101
101
  <meta charset="utf-8">
102
102
  <title>React Component Test (V2)</title>
103
103
  <style>
104
- body {
105
- margin: 0;
106
- padding: 20px;
104
+ body {
105
+ margin: 0;
106
+ padding: 20px;
107
107
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
108
108
  }
109
- #root {
109
+ #root {
110
110
  min-height: 100vh;
111
111
  background-color: white;
112
112
  padding: 20px;
@@ -130,7 +130,7 @@ class ComponentRunner {
130
130
  hasReact: typeof window.React !== 'undefined',
131
131
  hasReactDOM: typeof window.ReactDOM !== 'undefined',
132
132
  hasBabel: typeof window.Babel !== 'undefined',
133
- mjRuntimeKeys: window.MJReactRuntime ? Object.keys(window.MJReactRuntime) : []
133
+ mjRuntimeKeys: window.MJReactRuntime ? Object.keys(window.MJReactRuntime) : [],
134
134
  };
135
135
  });
136
136
  if (debug) {
@@ -152,10 +152,10 @@ class ComponentRunner {
152
152
  console.log(' - props:', JSON.stringify(options.props || {}, null, 2));
153
153
  // Show spec-specific libraries, not all available libraries
154
154
  if (options.componentSpec.libraries && options.componentSpec.libraries.length > 0) {
155
- console.log(' - spec requires libraries:', options.componentSpec.libraries.map(lib => ({
155
+ console.log(' - spec requires libraries:', options.componentSpec.libraries.map((lib) => ({
156
156
  name: lib.name,
157
157
  globalVariable: lib.globalVariable,
158
- version: lib.version
158
+ version: lib.version,
159
159
  })));
160
160
  }
161
161
  else {
@@ -213,7 +213,7 @@ class ComponentRunner {
213
213
  // Diagnostic: Check if React is available before creating context
214
214
  if (!window.React) {
215
215
  console.error('🔴 CRITICAL: React is NULL when creating runtimeContext!');
216
- console.error('Window keys:', Object.keys(window).filter(k => k.toLowerCase().includes('react')));
216
+ console.error('Window keys:', Object.keys(window).filter((k) => k.toLowerCase().includes('react')));
217
217
  throw new Error('React is not available in window context');
218
218
  }
219
219
  if (debug) {
@@ -222,13 +222,13 @@ class ComponentRunner {
222
222
  useState: typeof window.React?.useState,
223
223
  useEffect: typeof window.React?.useEffect,
224
224
  useRef: typeof window.React?.useRef,
225
- useMemo: typeof window.React?.useMemo
225
+ useMemo: typeof window.React?.useMemo,
226
226
  });
227
227
  }
228
228
  const runtimeContext = {
229
229
  React: window.React,
230
230
  ReactDOM: window.ReactDOM,
231
- libraries: {} // Libraries are loaded internally by the compiler
231
+ libraries: {}, // Libraries are loaded internally by the compiler
232
232
  };
233
233
  // Create instances with debug mode to see library loading
234
234
  const compiler = new ComponentCompiler({ debug: debug });
@@ -277,7 +277,7 @@ class ComponentRunner {
277
277
  continue;
278
278
  }
279
279
  if (!specLib.globalVariable) {
280
- const libDef = componentLibraries.find(l => l && l.Name && l.Name.toLowerCase() === specLib.name.toLowerCase());
280
+ const libDef = componentLibraries.find((l) => l && l.Name && l.Name.toLowerCase() === specLib.name.toLowerCase());
281
281
  if (libDef && libDef.GlobalVariable) {
282
282
  specLib.globalVariable = libDef.GlobalVariable;
283
283
  if (debug) {
@@ -289,7 +289,7 @@ class ComponentRunner {
289
289
  if (debug) {
290
290
  console.log('🔍 Spec libraries after enhancement:', spec.libraries.map((l) => ({
291
291
  name: l.name,
292
- globalVariable: l.globalVariable
292
+ globalVariable: l.globalVariable,
293
293
  })));
294
294
  }
295
295
  }
@@ -315,8 +315,8 @@ class ComponentRunner {
315
315
  dependencies: spec.dependencies?.map((d) => ({
316
316
  name: d.name,
317
317
  location: d.location,
318
- hasCode: !!d.code
319
- }))
318
+ hasCode: !!d.code,
319
+ })),
320
320
  });
321
321
  }
322
322
  // NEW: Use ComponentManager.loadHierarchy instead of registrar.registerHierarchy
@@ -328,21 +328,23 @@ class ComponentRunner {
328
328
  defaultVersion: 'v1',
329
329
  returnType: 'both',
330
330
  resolutionMode: 'embed', // Convert to embedded format for browser execution
331
- allLibraries: componentLibraries || [] // Pass libraries for compiler
331
+ allLibraries: componentLibraries || [], // Pass libraries for compiler
332
332
  });
333
333
  if (debug) {
334
334
  console.log('📋 [BROWSER] LoadHierarchy result:', {
335
335
  success: loadResult.success,
336
336
  rootComponent: !!loadResult.rootComponent,
337
- resolvedSpec: loadResult.resolvedSpec ? {
338
- name: loadResult.resolvedSpec.name,
339
- location: loadResult.resolvedSpec.location,
340
- registry: loadResult.resolvedSpec.registry,
341
- libraries: loadResult.resolvedSpec.libraries,
342
- hasCode: !!loadResult.resolvedSpec.code
343
- } : null,
337
+ resolvedSpec: loadResult.resolvedSpec
338
+ ? {
339
+ name: loadResult.resolvedSpec.name,
340
+ location: loadResult.resolvedSpec.location,
341
+ registry: loadResult.resolvedSpec.registry,
342
+ libraries: loadResult.resolvedSpec.libraries,
343
+ hasCode: !!loadResult.resolvedSpec.code,
344
+ }
345
+ : null,
344
346
  loadedComponents: loadResult.loadedComponents,
345
- errors: loadResult.errors
347
+ errors: loadResult.errors,
346
348
  });
347
349
  }
348
350
  // Convert to old format for compatibility
@@ -351,7 +353,7 @@ class ComponentRunner {
351
353
  registeredComponents: loadResult.loadedComponents,
352
354
  errors: loadResult.errors.map((e) => ({ componentName: e.componentName || '', error: e.message, phase: e.phase })),
353
355
  warnings: [],
354
- resolvedSpec: loadResult.resolvedSpec
356
+ resolvedSpec: loadResult.resolvedSpec,
355
357
  };
356
358
  }
357
359
  catch (registrationError) {
@@ -363,7 +365,7 @@ class ComponentRunner {
363
365
  stack: registrationError.stack,
364
366
  type: 'registration-error',
365
367
  phase: 'component-compilation',
366
- source: 'runtime-wrapper'
368
+ source: 'runtime-wrapper',
367
369
  });
368
370
  window.__testHarnessTestFailed = true;
369
371
  // Don't re-throw - let execution continue to collect this error properly
@@ -371,7 +373,7 @@ class ComponentRunner {
371
373
  return {
372
374
  success: false,
373
375
  error: `Component registration failed: ${registrationError.message || registrationError}`,
374
- componentCount: 0
376
+ componentCount: 0,
375
377
  };
376
378
  }
377
379
  if (debug && !registrationResult.success) {
@@ -413,10 +415,7 @@ class ComponentRunner {
413
415
  antd: typeof window.antd,
414
416
  React: typeof window.React,
415
417
  ReactDOM: typeof window.ReactDOM,
416
- windowKeys: Object.keys(window).filter(k => k.toLowerCase().includes('apex') ||
417
- k.toLowerCase().includes('antd') ||
418
- k === 'ApexCharts' ||
419
- k === 'antd')
418
+ windowKeys: Object.keys(window).filter((k) => k.toLowerCase().includes('apex') || k.toLowerCase().includes('antd') || k === 'ApexCharts' || k === 'antd'),
420
419
  });
421
420
  // If libraries were supposed to be loaded, check their actual presence
422
421
  if (spec.libraries && spec.libraries.length > 0) {
@@ -479,7 +478,7 @@ class ComponentRunner {
479
478
  '',
480
479
  'Inspect all instances where you are using JSX elements that come from libraries or components to ensure they are properly referenced.',
481
480
  '',
482
- 'The exact fix depends on the specific library or component structure.'
481
+ 'The exact fix depends on the specific library or component structure.',
483
482
  ].join('\\n');
484
483
  // Log to both console and error tracking
485
484
  console.error('🔴 Invalid JSX Element Type Detected:', errorMsg);
@@ -489,7 +488,7 @@ class ComponentRunner {
489
488
  type: 'invalid-element-type',
490
489
  phase: 'createElement',
491
490
  source: 'enhanced-detection',
492
- elementInfo: objectInfo
491
+ elementInfo: objectInfo,
493
492
  });
494
493
  // Still try to call the original to get React's error too
495
494
  // This will provide the component stack trace
@@ -504,14 +503,14 @@ class ComponentRunner {
504
503
  '',
505
504
  'Inspect how this component is being accessed - it may not exist in the expected location or may have a different name.',
506
505
  '',
507
- 'Check that the component exists in your dependencies or libraries and is properly referenced.'
506
+ 'Check that the component exists in your dependencies or libraries and is properly referenced.',
508
507
  ].join('\\n');
509
508
  console.error('🔴 Undefined JSX Component:', errorMsg);
510
509
  window.__testHarnessRuntimeErrors.push({
511
510
  message: errorMsg,
512
511
  type: 'undefined-component',
513
512
  phase: 'createElement',
514
- source: 'enhanced-detection'
513
+ source: 'enhanced-detection',
515
514
  });
516
515
  }
517
516
  // Call original createElement
@@ -540,7 +539,7 @@ class ComponentRunner {
540
539
  window.__testHarnessRuntimeErrors.push({
541
540
  message: `Likely infinite render loop: ${currentRenderCount} createElement calls (max: ${MAX_RENDERS_ALLOWED})`,
542
541
  type: 'render-loop',
543
- source: 'test-harness'
542
+ source: 'test-harness',
544
543
  });
545
544
  // Try to unmount to stop the madness
546
545
  try {
@@ -574,8 +573,8 @@ class ComponentRunner {
574
573
  CreateSimpleNotification: (message, style, hideAfter) => {
575
574
  console.log('[Test Harness] CreateSimpleNotification called:', { message, style, hideAfter });
576
575
  // In test harness, we just log but don't display actual notifications
577
- }
578
- }
576
+ },
577
+ },
579
578
  };
580
579
  if (debug) {
581
580
  console.log('🎨 Rendering component with props:', Object.keys(componentProps));
@@ -604,7 +603,7 @@ class ComponentRunner {
604
603
  stack: error.stack,
605
604
  type: 'react-render-error',
606
605
  phase: 'component-render',
607
- source: 'user-component' // This is the actual error from user's component
606
+ source: 'user-component', // This is the actual error from user's component
608
607
  });
609
608
  window.__testHarnessTestFailed = true;
610
609
  return { hasError: true, error };
@@ -640,7 +639,7 @@ class ComponentRunner {
640
639
  }
641
640
  return {
642
641
  success: true,
643
- componentCount: registrationResult.registeredComponents.length
642
+ componentCount: registrationResult.registeredComponents.length,
644
643
  };
645
644
  }
646
645
  catch (error) {
@@ -657,19 +656,19 @@ class ComponentRunner {
657
656
  message: error.message || String(error),
658
657
  stack: error.stack,
659
658
  type: 'execution-error',
660
- source: 'runtime-wrapper'
659
+ source: 'runtime-wrapper',
661
660
  });
662
661
  window.__testHarnessTestFailed = true;
663
662
  return {
664
663
  success: false,
665
- error: error.message || String(error)
664
+ error: error.message || String(error),
666
665
  };
667
666
  }
668
667
  }, {
669
668
  spec: options.componentSpec,
670
669
  props: options.props,
671
670
  debug,
672
- componentLibraries: allLibraries || []
671
+ componentLibraries: allLibraries || [],
673
672
  });
674
673
  // Create timeout promise (Recommendation #1)
675
674
  const timeoutPromise = new Promise((_, reject) => setTimeout(() => reject(new Error(`Component execution timeout after ${globalTimeout}ms`)), globalTimeout));
@@ -685,21 +684,21 @@ class ComponentRunner {
685
684
  errors.push(`Component execution timed out after ${globalTimeout}ms`);
686
685
  executionResult = {
687
686
  success: false,
688
- error: timeoutError instanceof Error ? timeoutError.message : 'Execution timeout'
687
+ error: timeoutError instanceof Error ? timeoutError.message : 'Execution timeout',
689
688
  };
690
689
  }
691
690
  // Ensure executionResult has proper shape
692
691
  if (!executionResult) {
693
692
  executionResult = {
694
693
  success: false,
695
- error: 'Component execution returned no result'
694
+ error: 'Component execution returned no result',
696
695
  };
697
696
  errors.push('Component execution failed to return a result');
698
697
  }
699
698
  else if (!executionResult.success && executionResult.error) {
700
699
  // Add the execution error if it hasn't been captured elsewhere
701
700
  const errorMsg = `Component execution failed: ${executionResult.error}`;
702
- if (!errors.some(e => e.includes(executionResult.error))) {
701
+ if (!errors.some((e) => e.includes(executionResult.error))) {
703
702
  errors.push(errorMsg);
704
703
  }
705
704
  }
@@ -715,13 +714,12 @@ class ComponentRunner {
715
714
  const runtimeErrorsWithSource = await this.collectRuntimeErrors(page);
716
715
  // Filter out JSX element type errors when adding to errors array
717
716
  errors.push(...runtimeErrorsWithSource
718
- .filter(e => {
717
+ .filter((e) => {
719
718
  // Skip JSX element type errors from error count
720
- const isJSXError = e.type === 'invalid-element-type' ||
721
- e.type === 'undefined-component';
719
+ const isJSXError = e.type === 'invalid-element-type' || e.type === 'undefined-component';
722
720
  return !isJSXError;
723
721
  })
724
- .map(e => e.message)); // Extract messages for backward compat
722
+ .map((e) => e.message)); // Extract messages for backward compat
725
723
  // Collect warnings (separate from errors)
726
724
  const collectedWarnings = await this.collectWarnings(page);
727
725
  warnings.push(...collectedWarnings);
@@ -730,21 +728,20 @@ class ComponentRunner {
730
728
  await page.waitForTimeout(asyncWaitTime);
731
729
  const asyncErrors = await this.collectRuntimeErrors(page);
732
730
  // Only add new errors (excluding JSX element type errors)
733
- asyncErrors.forEach(err => {
734
- const isJSXError = err.type === 'invalid-element-type' ||
735
- err.type === 'undefined-component';
731
+ asyncErrors.forEach((err) => {
732
+ const isJSXError = err.type === 'invalid-element-type' || err.type === 'undefined-component';
736
733
  if (!isJSXError && !errors.includes(err.message)) {
737
734
  errors.push(err.message);
738
735
  runtimeErrorsWithSource.push(err); // Keep the structured version too
739
736
  }
740
- else if (isJSXError && !runtimeErrorsWithSource.some(e => e.message === err.message)) {
737
+ else if (isJSXError && !runtimeErrorsWithSource.some((e) => e.message === err.message)) {
741
738
  // Still track JSX errors for logging but don't add to errors array
742
739
  runtimeErrorsWithSource.push(err);
743
740
  }
744
741
  });
745
742
  // Also check for new warnings
746
743
  const asyncWarnings = await this.collectWarnings(page);
747
- asyncWarnings.forEach(warn => {
744
+ asyncWarnings.forEach((warn) => {
748
745
  if (!warnings.includes(warn)) {
749
746
  warnings.push(warn);
750
747
  }
@@ -759,16 +756,13 @@ class ComponentRunner {
759
756
  errors.push(`Possible render loop: ${renderCount} createElement calls detected (likely infinite loop)`);
760
757
  }
761
758
  // Determine success
762
- const success = errors.length === 0 &&
763
- !hasRenderLoop &&
764
- !hasTimeout &&
765
- executionResult.success;
759
+ const success = errors.length === 0 && !hasRenderLoop && !hasTimeout && executionResult.success;
766
760
  // Combine runtime errors with data errors
767
761
  const allErrors = [...errors, ...dataErrors];
768
762
  // Map runtime errors with source info and specific rules
769
763
  // Filter out JSX element type errors - they're too noisy and often false positives
770
764
  const errorViolations = runtimeErrorsWithSource
771
- .filter(e => {
765
+ .filter((e) => {
772
766
  // Skip JSX element type errors - still logged but not reported as violations
773
767
  const isJSXError = e.rule === 'invalid-jsx-element' ||
774
768
  e.rule === 'undefined-jsx-component' ||
@@ -779,13 +773,13 @@ class ComponentRunner {
779
773
  }
780
774
  return !isJSXError;
781
775
  })
782
- .map(e => ({
776
+ .map((e) => ({
783
777
  message: e.message,
784
778
  severity: 'critical',
785
779
  rule: e.rule || 'runtime-error', // Use specific rule from collectRuntimeErrors
786
780
  line: 0,
787
781
  column: 0,
788
- source: e.source
782
+ source: e.source,
789
783
  }));
790
784
  // Add timeout error if detected
791
785
  if (hasTimeout) {
@@ -795,7 +789,7 @@ class ComponentRunner {
795
789
  rule: 'timeout',
796
790
  line: 0,
797
791
  column: 0,
798
- source: 'test-harness' // This is a test harness timeout
792
+ source: 'test-harness', // This is a test harness timeout
799
793
  });
800
794
  }
801
795
  // Add render loop error if detected
@@ -806,25 +800,25 @@ class ComponentRunner {
806
800
  rule: 'render-loop',
807
801
  line: 0,
808
802
  column: 0,
809
- source: 'test-harness' // This is a test harness detection
803
+ source: 'test-harness', // This is a test harness detection
810
804
  });
811
805
  }
812
806
  // Add data errors without source
813
- dataErrors.forEach(e => {
807
+ dataErrors.forEach((e) => {
814
808
  errorViolations.push({
815
809
  message: e,
816
810
  severity: 'critical',
817
811
  rule: 'runtime-error',
818
812
  line: 0,
819
813
  column: 0,
820
- source: 'user-component' // Data errors are from user's data access code
814
+ source: 'user-component', // Data errors are from user's data access code
821
815
  });
822
816
  });
823
817
  // Check warnings for critical patterns and move them to errors
824
818
  const criticalWarningViolations = [];
825
819
  const regularWarnings = [];
826
- warnings.forEach(w => {
827
- if (ComponentRunner.CRITICAL_WARNING_PATTERNS.some(pattern => pattern.test(w))) {
820
+ warnings.forEach((w) => {
821
+ if (ComponentRunner.CRITICAL_WARNING_PATTERNS.some((pattern) => pattern.test(w))) {
828
822
  // This is a critical warning - add to errors
829
823
  criticalWarningViolations.push({
830
824
  message: w,
@@ -832,7 +826,7 @@ class ComponentRunner {
832
826
  rule: 'critical-react-warning',
833
827
  line: 0,
834
828
  column: 0,
835
- source: 'react-framework'
829
+ source: 'react-framework',
836
830
  });
837
831
  }
838
832
  else {
@@ -846,17 +840,17 @@ class ComponentRunner {
846
840
  success: success && dataErrors.length === 0 && criticalWarningViolations.length === 0, // Fail on critical warnings too
847
841
  html,
848
842
  errors: allErrorViolations,
849
- warnings: regularWarnings.map(w => ({
843
+ warnings: regularWarnings.map((w) => ({
850
844
  message: w,
851
845
  severity: 'low',
852
846
  rule: 'warning',
853
847
  line: 0,
854
- column: 0
848
+ column: 0,
855
849
  })),
856
850
  console: consoleLogs,
857
851
  screenshot,
858
852
  executionTime: Date.now() - startTime,
859
- renderCount
853
+ renderCount,
860
854
  };
861
855
  if (debug) {
862
856
  this.dumpDebugInfo(result);
@@ -867,42 +861,44 @@ class ComponentRunner {
867
861
  // For catch block errors, we need to handle them specially
868
862
  const catchError = {
869
863
  message: error instanceof Error ? error.message : String(error),
870
- source: 'test-harness' // Errors caught here are usually test harness issues
864
+ source: 'test-harness', // Errors caught here are usually test harness issues
871
865
  };
872
866
  // Create error violations including the catch error
873
- const errorViolations = [{
867
+ const errorViolations = [
868
+ {
874
869
  message: catchError.message,
875
870
  severity: 'critical',
876
871
  rule: 'runtime-error',
877
872
  line: 0,
878
873
  column: 0,
879
- source: catchError.source
880
- }];
874
+ source: catchError.source,
875
+ },
876
+ ];
881
877
  // Add any data errors
882
- dataErrors.forEach(e => {
878
+ dataErrors.forEach((e) => {
883
879
  errorViolations.push({
884
880
  message: e,
885
881
  severity: 'critical',
886
882
  rule: 'runtime-error',
887
883
  line: 0,
888
884
  column: 0,
889
- source: 'user-component'
885
+ source: 'user-component',
890
886
  });
891
887
  });
892
888
  const result = {
893
889
  success: false,
894
890
  html: '',
895
891
  errors: errorViolations,
896
- warnings: warnings.map(w => ({
892
+ warnings: warnings.map((w) => ({
897
893
  message: w,
898
894
  severity: 'low',
899
895
  rule: 'warning',
900
896
  line: 0,
901
- column: 0
897
+ column: 0,
902
898
  })),
903
899
  console: consoleLogs,
904
900
  executionTime: Date.now() - startTime,
905
- renderCount
901
+ renderCount,
906
902
  };
907
903
  if (debug) {
908
904
  console.log('\n❌ Component execution failed with error:', error);
@@ -940,7 +936,7 @@ class ComponentRunner {
940
936
  try {
941
937
  await Promise.race([
942
938
  page.addScriptTag({ url }),
943
- new Promise((_, reject) => setTimeout(() => reject(new Error(`Script load timeout: ${url}`)), timeout))
939
+ new Promise((_, reject) => setTimeout(() => reject(new Error(`Script load timeout: ${url}`)), timeout)),
944
940
  ]);
945
941
  }
946
942
  catch (error) {
@@ -978,7 +974,7 @@ class ComponentRunner {
978
974
  React: typeof window.React !== 'undefined',
979
975
  ReactDOM: typeof window.ReactDOM !== 'undefined',
980
976
  Babel: typeof window.Babel !== 'undefined',
981
- MJRuntime: typeof window.MJReactRuntime !== 'undefined'
977
+ MJRuntime: typeof window.MJReactRuntime !== 'undefined',
982
978
  };
983
979
  });
984
980
  // All core libraries loaded successfully
@@ -997,10 +993,10 @@ class ComponentRunner {
997
993
  async loadComponentLibraries(page, specLibraries, allLibraries, debug = false) {
998
994
  if (debug) {
999
995
  console.log('📚 Loading component libraries:');
1000
- console.log(' 🔍 Component requires libraries:', specLibraries.map(l => l.name));
996
+ console.log(' 🔍 Component requires libraries:', specLibraries.map((l) => l.name));
1001
997
  console.log(' 📦 Total available ComponentLibrary entries:', allLibraries.length);
1002
998
  console.log(' 📋 Sample of available libraries (first 10):');
1003
- allLibraries.slice(0, 10).forEach(lib => {
999
+ allLibraries.slice(0, 10).forEach((lib) => {
1004
1000
  console.log(` - ${lib.Name}@${lib.Version} (${lib.Status})`);
1005
1001
  });
1006
1002
  }
@@ -1020,12 +1016,12 @@ class ComponentRunner {
1020
1016
  console.log(`📦 Loading ${specLib.name}:`, {
1021
1017
  cdnUrl: libDef.CDNUrl,
1022
1018
  globalVariable: libDef.GlobalVariable,
1023
- dependencies: libDef.Dependencies ? JSON.parse(libDef.Dependencies) : null
1019
+ dependencies: libDef.Dependencies ? JSON.parse(libDef.Dependencies) : null,
1024
1020
  });
1025
1021
  }
1026
1022
  // Load CSS if available
1027
1023
  if (libDef.CDNCssUrl) {
1028
- const cssUrls = libDef.CDNCssUrl.split(',').map(url => url.trim());
1024
+ const cssUrls = libDef.CDNCssUrl.split(',').map((url) => url.trim());
1029
1025
  for (const cssUrl of cssUrls) {
1030
1026
  if (cssUrl) {
1031
1027
  await page.addStyleTag({ url: cssUrl });
@@ -1041,7 +1037,7 @@ class ComponentRunner {
1041
1037
  // Add timeout for library loading (Recommendation #3)
1042
1038
  await Promise.race([
1043
1039
  page.addScriptTag({ url: libDef.CDNUrl }),
1044
- new Promise((_, reject) => setTimeout(() => reject(new Error(`Library load timeout: ${libDef.CDNUrl}`)), 10000))
1040
+ new Promise((_, reject) => setTimeout(() => reject(new Error(`Library load timeout: ${libDef.CDNUrl}`)), 10000)),
1045
1041
  ]);
1046
1042
  // Verify the library loaded
1047
1043
  const isLoaded = await page.evaluate((globalVar) => {
@@ -1068,10 +1064,12 @@ class ComponentRunner {
1068
1064
  if (debug) {
1069
1065
  // Log all available global variables that look like libraries
1070
1066
  // Get all the global variables we expect from the spec
1071
- const expectedGlobals = specLibraries.map(lib => {
1067
+ const expectedGlobals = specLibraries
1068
+ .map((lib) => {
1072
1069
  const libDef = libraryMap.get(lib.name.toLowerCase());
1073
1070
  return libDef?.GlobalVariable;
1074
- }).filter(Boolean);
1071
+ })
1072
+ .filter(Boolean);
1075
1073
  const globals = await page.evaluate((expected) => {
1076
1074
  const relevantGlobals = {};
1077
1075
  // Check the expected globals from the spec
@@ -1145,7 +1143,7 @@ class ComponentRunner {
1145
1143
  '',
1146
1144
  'Inspect all instances where you are using JSX elements that come from libraries or components to ensure they are properly referenced.',
1147
1145
  '',
1148
- 'The exact fix depends on the specific library or component structure.'
1146
+ 'The exact fix depends on the specific library or component structure.',
1149
1147
  ].join('\\n');
1150
1148
  // Log to both console and error tracking
1151
1149
  console.error('🔴 Invalid JSX Element Type Detected:', errorMsg);
@@ -1156,7 +1154,7 @@ class ComponentRunner {
1156
1154
  type: 'invalid-element-type',
1157
1155
  phase: 'createElement',
1158
1156
  source: 'enhanced-detection',
1159
- elementInfo: objectInfo
1157
+ elementInfo: objectInfo,
1160
1158
  });
1161
1159
  // Still try to call the original to get React's error too
1162
1160
  // This will provide the component stack trace
@@ -1171,7 +1169,7 @@ class ComponentRunner {
1171
1169
  '',
1172
1170
  'Inspect how this component is being accessed - it may not exist in the expected location or may have a different name.',
1173
1171
  '',
1174
- 'Check that the component exists in your dependencies or libraries and is properly referenced.'
1172
+ 'Check that the component exists in your dependencies or libraries and is properly referenced.',
1175
1173
  ].join('\\n');
1176
1174
  console.error('🔴 Undefined JSX Component:', errorMsg);
1177
1175
  window.__testHarnessRuntimeErrors = window.__testHarnessRuntimeErrors || [];
@@ -1179,7 +1177,7 @@ class ComponentRunner {
1179
1177
  message: errorMsg,
1180
1178
  type: 'undefined-component',
1181
1179
  phase: 'createElement',
1182
- source: 'enhanced-detection'
1180
+ source: 'enhanced-detection',
1183
1181
  });
1184
1182
  }
1185
1183
  // Call original createElement
@@ -1189,7 +1187,7 @@ class ComponentRunner {
1189
1187
  // Override console.error
1190
1188
  const originalConsoleError = console.error;
1191
1189
  console.error = function (...args) {
1192
- const errorText = args.map(arg => typeof arg === 'object' ? JSON.stringify(arg) : String(arg)).join(' ');
1190
+ const errorText = args.map((arg) => (typeof arg === 'object' ? JSON.stringify(arg) : String(arg))).join(' ');
1193
1191
  // Check if this is a warning rather than an error
1194
1192
  // React warnings typically start with "Warning:" or contain warning-related text
1195
1193
  const isWarning = errorText.includes('Warning:') ||
@@ -1220,16 +1218,15 @@ class ComponentRunner {
1220
1218
  isAvailableLibrary: false,
1221
1219
  matchedLibrary: null,
1222
1220
  specLibraries: spec?.libraries || [],
1223
- specDependencies: spec?.dependencies || []
1221
+ specDependencies: spec?.dependencies || [],
1224
1222
  };
1225
1223
  // Check if it's in spec libraries
1226
1224
  result.isInSpecLibraries = result.specLibraries.some((lib) => lib.globalVariable === identifier);
1227
- // Check if it's in spec dependencies
1225
+ // Check if it's in spec dependencies
1228
1226
  result.isInSpecDependencies = result.specDependencies.some((dep) => dep.name === identifier);
1229
1227
  // Check against ALL available libraries (case-insensitive)
1230
1228
  if (availableLibraries) {
1231
- const availableLib = availableLibraries.find((lib) => lib.GlobalVariable &&
1232
- lib.GlobalVariable.toLowerCase() === identifier.toLowerCase());
1229
+ const availableLib = availableLibraries.find((lib) => lib.GlobalVariable && lib.GlobalVariable.toLowerCase() === identifier.toLowerCase());
1233
1230
  if (availableLib) {
1234
1231
  result.isAvailableLibrary = true;
1235
1232
  result.matchedLibrary = availableLib;
@@ -1242,29 +1239,35 @@ class ComponentRunner {
1242
1239
  // Case 1: Trying to use a library not in their spec
1243
1240
  if (analysis.isAvailableLibrary && !analysis.isInSpecLibraries) {
1244
1241
  const libList = analysis.specLibraries.length > 0
1245
- ? analysis.specLibraries.map((l) => l.globalVariable || l.name).filter(Boolean).join(', ')
1242
+ ? analysis.specLibraries
1243
+ .map((l) => l.globalVariable || l.name)
1244
+ .filter(Boolean)
1245
+ .join(', ')
1246
1246
  : 'no third-party libraries';
1247
- return `${identifier} is not defined. It appears you're trying to use the ${analysis.matchedLibrary.Name} library. ` +
1247
+ return (`${identifier} is not defined. It appears you're trying to use the ${analysis.matchedLibrary.Name} library. ` +
1248
1248
  `You do NOT have access to this library. ` +
1249
1249
  `Your architect gave you access to: ${libList}. ` +
1250
- `You must work within these constraints and cannot load additional libraries.`;
1250
+ `You must work within these constraints and cannot load additional libraries.`);
1251
1251
  }
1252
1252
  // Case 2: Should be a component but not properly accessed
1253
1253
  if (analysis.isInSpecDependencies) {
1254
- return `${identifier} is not defined. This component exists in your dependencies. ` +
1254
+ return (`${identifier} is not defined. This component exists in your dependencies. ` +
1255
1255
  `Ensure you've destructured it: const { ${identifier} } = components; ` +
1256
- `or accessed it as: components.${identifier}`;
1256
+ `or accessed it as: components.${identifier}`);
1257
1257
  }
1258
1258
  // Case 3: Not a valid library or component
1259
1259
  const libList = analysis.specLibraries.length > 0
1260
- ? `Available libraries: ${analysis.specLibraries.map((l) => l.globalVariable || l.name).filter(Boolean).join(', ')}`
1260
+ ? `Available libraries: ${analysis.specLibraries
1261
+ .map((l) => l.globalVariable || l.name)
1262
+ .filter(Boolean)
1263
+ .join(', ')}`
1261
1264
  : 'No third-party libraries are available';
1262
1265
  const depList = analysis.specDependencies.length > 0
1263
1266
  ? `Available components: ${analysis.specDependencies.map((d) => d.name).join(', ')}`
1264
1267
  : 'No component dependencies are available';
1265
- return `${identifier} is not defined. This is not a valid library or component in your specification. ` +
1268
+ return (`${identifier} is not defined. This is not a valid library or component in your specification. ` +
1266
1269
  `${libList}. ${depList}. ` +
1267
- `You must only use the libraries and components specified in your component specification.`;
1270
+ `You must only use the libraries and components specified in your component specification.`);
1268
1271
  };
1269
1272
  // Global error handler
1270
1273
  window.addEventListener('error', (event) => {
@@ -1282,7 +1285,7 @@ class ComponentRunner {
1282
1285
  stack: event.error?.stack,
1283
1286
  type: 'undefined-identifier',
1284
1287
  source: 'user-component',
1285
- identifier: identifier
1288
+ identifier: identifier,
1286
1289
  });
1287
1290
  window.__testHarnessTestFailed = true;
1288
1291
  return;
@@ -1296,7 +1299,7 @@ class ComponentRunner {
1296
1299
  message: event.error?.message || event.message,
1297
1300
  stack: event.error?.stack,
1298
1301
  type: 'runtime',
1299
- source: source
1302
+ source: source,
1300
1303
  });
1301
1304
  window.__testHarnessTestFailed = true;
1302
1305
  });
@@ -1306,7 +1309,7 @@ class ComponentRunner {
1306
1309
  message: 'Unhandled Promise Rejection: ' + (event.reason?.message || event.reason),
1307
1310
  stack: event.reason?.stack,
1308
1311
  type: 'promise-rejection',
1309
- source: 'user-component' // Async errors are likely from user code
1312
+ source: 'user-component', // Async errors are likely from user code
1310
1313
  });
1311
1314
  window.__testHarnessTestFailed = true;
1312
1315
  event.preventDefault();
@@ -1321,20 +1324,17 @@ class ComponentRunner {
1321
1324
  return {
1322
1325
  runtimeErrors: window.__testHarnessRuntimeErrors || [],
1323
1326
  consoleErrors: window.__testHarnessConsoleErrors || [],
1324
- testFailed: window.__testHarnessTestFailed || false
1327
+ testFailed: window.__testHarnessTestFailed || false,
1325
1328
  };
1326
1329
  });
1327
1330
  // Track unique errors and their counts
1328
1331
  const errorMap = new Map();
1329
1332
  // Check if we have any specific React render errors
1330
- const hasSpecificReactError = errorData.runtimeErrors.some((error) => error.type === 'react-render-error' &&
1331
- !error.message.includes('Script error'));
1333
+ const hasSpecificReactError = errorData.runtimeErrors.some((error) => error.type === 'react-render-error' && !error.message.includes('Script error'));
1332
1334
  // Process runtime errors with their source information
1333
1335
  errorData.runtimeErrors.forEach((error) => {
1334
1336
  // Skip generic "Script error" messages if we have more specific React errors
1335
- if (hasSpecificReactError &&
1336
- error.type === 'runtime' &&
1337
- error.message === 'Script error.') {
1337
+ if (hasSpecificReactError && error.type === 'runtime' && error.message === 'Script error.') {
1338
1338
  return; // Skip this generic error
1339
1339
  }
1340
1340
  // Map error types to specific rule names
@@ -1381,9 +1381,9 @@ class ComponentRunner {
1381
1381
  message: error.message,
1382
1382
  source: error.source,
1383
1383
  type: error.type,
1384
- rule: rule
1384
+ rule: rule,
1385
1385
  },
1386
- count: 1
1386
+ count: 1,
1387
1387
  });
1388
1388
  }
1389
1389
  });
@@ -1399,9 +1399,9 @@ class ComponentRunner {
1399
1399
  message: error,
1400
1400
  source: 'react-framework',
1401
1401
  type: 'console-error',
1402
- rule: 'console-error'
1402
+ rule: 'console-error',
1403
1403
  },
1404
- count: 1
1404
+ count: 1,
1405
1405
  });
1406
1406
  }
1407
1407
  });
@@ -1409,12 +1409,10 @@ class ComponentRunner {
1409
1409
  const errors = [];
1410
1410
  errorMap.forEach(({ error, count }) => {
1411
1411
  // Append count if > 1
1412
- const message = count > 1
1413
- ? `${error.message} (occurred ${count} times)`
1414
- : error.message;
1412
+ const message = count > 1 ? `${error.message} (occurred ${count} times)` : error.message;
1415
1413
  errors.push({
1416
1414
  ...error,
1417
- message
1415
+ message,
1418
1416
  });
1419
1417
  });
1420
1418
  return errors;
@@ -1425,7 +1423,7 @@ class ComponentRunner {
1425
1423
  async collectWarnings(page) {
1426
1424
  const warningData = await page.evaluate(() => {
1427
1425
  return {
1428
- consoleWarnings: window.__testHarnessConsoleWarnings || []
1426
+ consoleWarnings: window.__testHarnessConsoleWarnings || [],
1429
1427
  };
1430
1428
  });
1431
1429
  const warnings = [];
@@ -1457,23 +1455,23 @@ class ComponentRunner {
1457
1455
  });
1458
1456
  }
1459
1457
  async buildLocalMJUtilities(contextUser) {
1460
- console.log(" Building local MJ utilities");
1461
- const rv = new core_1.RunView();
1462
- const rq = new core_1.RunQuery();
1463
- const md = new core_1.Metadata();
1458
+ console.log(' Building local MJ utilities');
1459
+ const rv = new global_1.RunView();
1460
+ const rq = new global_1.RunQuery();
1461
+ const md = new global_1.Metadata();
1464
1462
  return {
1465
1463
  rv: {
1466
1464
  RunView: rv.RunView,
1467
- RunViews: rv.RunViews
1465
+ RunViews: rv.RunViews,
1468
1466
  },
1469
1467
  rq: {
1470
- RunQuery: rq.RunQuery
1468
+ RunQuery: rq.RunQuery,
1471
1469
  },
1472
1470
  md: {
1473
1471
  GetEntityObject: md.GetEntityObject, // return the function
1474
- Entities: md.Entities // return the function
1472
+ Entities: md.Entities, // return the function
1475
1473
  },
1476
- ai: await this.BuildLocalSimpleAITools(contextUser)
1474
+ ai: await this.BuildLocalSimpleAITools(contextUser),
1477
1475
  };
1478
1476
  }
1479
1477
  async BuildLocalSimpleAITools(contextUser) {
@@ -1490,8 +1488,7 @@ class ComponentRunner {
1490
1488
  await aiEngine.Config(false, params.contextUser);
1491
1489
  const models = aiEngine.Models;
1492
1490
  for (const preferredModel of params.preferredModels) {
1493
- model = models.find((m) => m.Name === preferredModel &&
1494
- m.IsActive === true);
1491
+ model = models.find((m) => m.Name === preferredModel && m.IsActive === true);
1495
1492
  if (model)
1496
1493
  break;
1497
1494
  }
@@ -1501,8 +1498,7 @@ class ComponentRunner {
1501
1498
  if (params.modelPower === 'lowest') {
1502
1499
  // Get lowest power model by sorting in reverse
1503
1500
  await aiEngine.Config(false, params.contextUser);
1504
- const llmModels = aiEngine.Models.filter((m) => m.AIModelType === 'LLM' &&
1505
- m.IsActive === true);
1501
+ const llmModels = aiEngine.Models.filter((m) => m.AIModelType === 'LLM' && m.IsActive === true);
1506
1502
  model = llmModels.sort((a, b) => (a.PowerRank || 0) - (b.PowerRank || 0))[0];
1507
1503
  }
1508
1504
  else if (params.modelPower === 'highest') {
@@ -1511,8 +1507,7 @@ class ComponentRunner {
1511
1507
  else {
1512
1508
  // Default to medium - get a model in the middle range
1513
1509
  await aiEngine.Config(false, params.contextUser);
1514
- const llmModels = aiEngine.Models.filter((m) => m.AIModelType === 'LLM' &&
1515
- m.IsActive === true);
1510
+ const llmModels = aiEngine.Models.filter((m) => m.AIModelType === 'LLM' && m.IsActive === true);
1516
1511
  const sortedModels = llmModels.sort((a, b) => (b.PowerRank || 0) - (a.PowerRank || 0));
1517
1512
  const midIndex = Math.floor(sortedModels.length / 2);
1518
1513
  model = sortedModels[midIndex] || sortedModels[0];
@@ -1521,9 +1516,7 @@ class ComponentRunner {
1521
1516
  // Build full conversation from messages if provided
1522
1517
  let fullUserPrompt = '';
1523
1518
  if (params.messages && params.messages.length > 0) {
1524
- fullUserPrompt = params.messages
1525
- .map(m => `${m.role === 'user' ? 'User' : 'Assistant'}: ${m.message}`)
1526
- .join('\n');
1519
+ fullUserPrompt = params.messages.map((m) => `${m.role === 'user' ? 'User' : 'Assistant'}: ${m.message}`).join('\n');
1527
1520
  }
1528
1521
  // Execute the prompt using AIEngine
1529
1522
  const result = await aiEngine.SimpleLLMCompletion(fullUserPrompt || '', params.contextUser || {}, // Provide empty object if no context user
@@ -1544,35 +1537,33 @@ class ComponentRunner {
1544
1537
  success: true,
1545
1538
  result: result,
1546
1539
  resultObject,
1547
- modelName: model?.Name || 'Unknown'
1540
+ modelName: model?.Name || 'Unknown',
1548
1541
  };
1549
1542
  }
1550
1543
  catch (error) {
1551
- (0, core_1.LogError)(error);
1544
+ (0, global_1.LogError)(error);
1552
1545
  return {
1553
1546
  success: false,
1554
1547
  result: 'Failed to execute prompt: ' + (error instanceof Error ? error.message : String(error)),
1555
- modelName: ''
1548
+ modelName: '',
1556
1549
  };
1557
1550
  }
1558
1551
  },
1559
1552
  EmbedText: async (params) => {
1560
1553
  try {
1561
1554
  // Handle both single string and array of strings
1562
- const texts = Array.isArray(params.textToEmbed)
1563
- ? params.textToEmbed
1564
- : [params.textToEmbed];
1555
+ const texts = Array.isArray(params.textToEmbed) ? params.textToEmbed : [params.textToEmbed];
1565
1556
  // Use appropriate embedding model based on size
1566
1557
  await aiEngine.Config(false, params.contextUser);
1567
1558
  // Get embedding models and filter by size preference
1568
- const embeddingModels = aiEngine.Models.filter((m) => m.AIModelType === 'Embeddings' &&
1569
- m.IsActive === true);
1559
+ const embeddingModels = aiEngine.Models.filter((m) => m.AIModelType === 'Embeddings' && m.IsActive === true);
1570
1560
  // Select model based on size preference
1571
1561
  let model;
1572
1562
  if (params.modelSize === 'small') {
1573
1563
  // Prefer local/smaller models for 'small'
1574
- model = embeddingModels.find((m) => m.Vendor === 'LocalEmbeddings') ||
1575
- embeddingModels.sort((a, b) => (a.PowerRank || 0) - (b.PowerRank || 0))[0];
1564
+ model =
1565
+ embeddingModels.find((m) => m.Vendor === 'LocalEmbeddings') ||
1566
+ embeddingModels.sort((a, b) => (a.PowerRank || 0) - (b.PowerRank || 0))[0];
1576
1567
  }
1577
1568
  else {
1578
1569
  // Use more powerful models for 'medium'
@@ -1593,21 +1584,19 @@ class ComponentRunner {
1593
1584
  }
1594
1585
  }
1595
1586
  // Return single embedding or array based on input
1596
- const returnEmbeddings = Array.isArray(params.textToEmbed)
1597
- ? embeddings
1598
- : embeddings[0];
1587
+ const returnEmbeddings = Array.isArray(params.textToEmbed) ? embeddings : embeddings[0];
1599
1588
  return {
1600
1589
  result: returnEmbeddings,
1601
1590
  modelName: model.Name,
1602
- vectorDimensions: embeddings[0]?.length || 0
1591
+ vectorDimensions: embeddings[0]?.length || 0,
1603
1592
  };
1604
1593
  }
1605
1594
  catch (error) {
1606
- (0, core_1.LogError)(error);
1595
+ (0, global_1.LogError)(error);
1607
1596
  throw error; // Re-throw for embeddings as they're critical
1608
1597
  }
1609
1598
  },
1610
- VectorService: new ai_vectors_memory_1.SimpleVectorService()
1599
+ VectorService: new ai_vectors_memory_1.SimpleVectorService(),
1611
1600
  };
1612
1601
  }
1613
1602
  /**
@@ -1620,7 +1609,7 @@ class ComponentRunner {
1620
1609
  // UserInfo is a simple object that can be serialized
1621
1610
  const serializedContextUser = JSON.parse(JSON.stringify(options.contextUser));
1622
1611
  // utilities - favor the one passed in by the caller, or fall back to the local ones
1623
- const util = options.utilities || await this.buildLocalMJUtilities(options.contextUser);
1612
+ const util = options.utilities || (await this.buildLocalMJUtilities(options.contextUser));
1624
1613
  // Create a lightweight mock metadata object with serializable data
1625
1614
  // This avoids authentication/provider issues in the browser context
1626
1615
  let entitiesData = [];
@@ -1655,7 +1644,7 @@ class ComponentRunner {
1655
1644
  AuditLogTypes: [],
1656
1645
  Authorizations: [],
1657
1646
  VisibleExplorerNavigationItems: [],
1658
- AllExplorerNavigationItems: []
1647
+ AllExplorerNavigationItems: [],
1659
1648
  };
1660
1649
  // Inject both the contextUser and mock metadata into the page
1661
1650
  // Playwright only accepts a single argument, so wrap in an object
@@ -1671,7 +1660,7 @@ class ComponentRunner {
1671
1660
  // This must be available before any component code runs
1672
1661
  if (!window.Metadata) {
1673
1662
  window.Metadata = {
1674
- Provider: mockMd
1663
+ Provider: mockMd,
1675
1664
  };
1676
1665
  // Created global Metadata mock with Provider (early)
1677
1666
  }
@@ -1742,7 +1731,7 @@ class ComponentRunner {
1742
1731
  }
1743
1732
  catch (error) {
1744
1733
  const errorMessage = error instanceof Error ? error.message : String(error);
1745
- const entities = params.map(p => p.EntityName || 'unknown').join(', ');
1734
+ const entities = params.map((p) => p.EntityName || 'unknown').join(', ');
1746
1735
  // Debug logging for errors
1747
1736
  if (debug) {
1748
1737
  console.log(`❌ RunViews FAILED: Entities=[${entities}]`);
@@ -1811,7 +1800,7 @@ class ComponentRunner {
1811
1800
  return {
1812
1801
  success: false,
1813
1802
  result: errorMessage,
1814
- modelName: ''
1803
+ modelName: '',
1815
1804
  };
1816
1805
  }
1817
1806
  });
@@ -1824,9 +1813,7 @@ class ComponentRunner {
1824
1813
  const paramsWithUser = { ...params, contextUser: options.contextUser };
1825
1814
  const result = await util.ai.EmbedText(paramsWithUser);
1826
1815
  if (debug) {
1827
- const count = Array.isArray(result.result)
1828
- ? (Array.isArray(result.result[0]) ? result.result.length : 1)
1829
- : 1;
1816
+ const count = Array.isArray(result.result) ? (Array.isArray(result.result[0]) ? result.result.length : 1) : 1;
1830
1817
  console.log(`🤖 EmbedText SUCCESS: Model="${result.modelName}" Count=${count} Dims=${result.vectorDimensions}`);
1831
1818
  }
1832
1819
  return result;
@@ -1849,7 +1836,9 @@ class ComponentRunner {
1849
1836
  const VectorService = window.MJReactRuntime?.SimpleVectorService ||
1850
1837
  class {
1851
1838
  // Stub implementation if not available
1852
- cosineSimilarity(_a, _b) { return 0; }
1839
+ cosineSimilarity(_a, _b) {
1840
+ return 0;
1841
+ }
1853
1842
  };
1854
1843
  window.__mjUtilities = {
1855
1844
  md: {
@@ -1861,25 +1850,25 @@ class ComponentRunner {
1861
1850
  return mockMd.Entities.find((e) => e.Name === name) || null;
1862
1851
  },
1863
1852
  // Keep async function for GetEntityObject for compatibility
1864
- GetEntityObject: async (entityName) => await window.__mjGetEntityObject(entityName)
1853
+ GetEntityObject: async (entityName) => await window.__mjGetEntityObject(entityName),
1865
1854
  },
1866
1855
  rv: {
1867
1856
  RunView: async (params) => await window.__mjRunView(params),
1868
- RunViews: async (params) => await window.__mjRunViews(params)
1857
+ RunViews: async (params) => await window.__mjRunViews(params),
1869
1858
  },
1870
1859
  rq: {
1871
- RunQuery: async (params) => await window.__mjRunQuery(params)
1860
+ RunQuery: async (params) => await window.__mjRunQuery(params),
1872
1861
  },
1873
1862
  ai: {
1874
1863
  ExecutePrompt: async (params) => await window.__mjExecutePrompt(params),
1875
1864
  EmbedText: async (params) => await window.__mjEmbedText(params),
1876
- VectorService: new VectorService()
1877
- }
1865
+ VectorService: new VectorService(),
1866
+ },
1878
1867
  };
1879
1868
  // Update or create global Metadata mock (in case it wasn't created earlier)
1880
1869
  if (!window.Metadata) {
1881
1870
  window.Metadata = {
1882
- Provider: mockMd
1871
+ Provider: mockMd,
1883
1872
  };
1884
1873
  // Created global Metadata mock with Provider (late)
1885
1874
  }