about summary refs log tree commit diff stats
path: root/js/scripting-lang/web/src/dev.js
diff options
context:
space:
mode:
Diffstat (limited to 'js/scripting-lang/web/src/dev.js')
-rw-r--r--js/scripting-lang/web/src/dev.js268
1 files changed, 268 insertions, 0 deletions
diff --git a/js/scripting-lang/web/src/dev.js b/js/scripting-lang/web/src/dev.js
new file mode 100644
index 0000000..8341d1c
--- /dev/null
+++ b/js/scripting-lang/web/src/dev.js
@@ -0,0 +1,268 @@
+// devMode.js
+// Enhanced dev mode with harness integration for unified debugging
+
+/**
+ * Initialize enhanced dev mode: exposes an API for stepping through state history
+ * with integration to Baba Yaga harness versioning capabilities.
+ * @param {object} opts
+ * @param {function} opts.getState - returns current app state
+ * @param {function} opts.setState - sets app state
+ * @param {function} opts.render - triggers app re-render
+ * @param {object} opts.harness - Baba Yaga FunctionalHarness instance (optional)
+ */
+export function initDevMode({ getState, setState, render, harness = null }) {
+  let history = [];
+  let pointer = -1;
+  let firstLoad = true;
+  let harnessCorrelation = []; // Track web state ↔ harness state correlation
+
+  function pushState(state) {
+    if (pointer < history.length - 1) history = history.slice(0, pointer + 1);
+    history.push(clone(state));
+    pointer = history.length - 1;
+    
+    // Track correlation with harness if available
+    if (harness) {
+      const harnessVersion = harness.currentVersion || 0;
+      harnessCorrelation.push({
+        webVersion: pointer,
+        harnessVersion,
+        timestamp: Date.now()
+      });
+    }
+    
+    logInstructions();
+  }
+
+  function goTo(idx) {
+    if (idx < 0 || idx >= history.length) return;
+    pointer = idx;
+    setState(clone(history[pointer]));
+    render();
+    logInstructions();
+  }
+
+  function next() {
+    if (pointer < history.length - 1) goTo(pointer + 1);
+  }
+
+  function prev() {
+    if (pointer > 0) goTo(pointer - 1);
+  }
+
+  function get() {
+    return history[pointer];
+  }
+
+  function clone(obj) {
+    return JSON.parse(JSON.stringify(obj));
+  }
+
+  function table(obj) {
+    console.table(dev.history);
+  }
+
+  // Harness integration functions
+  function getHarnessHistory() {
+    console.log('[DevMode] getHarnessHistory called, harness available:', !!harness);
+    if (!harness) {
+      console.warn('[DevMode] No harness available for versioning - run a Baba Yaga script first');
+      return [];
+    }
+    const history = harness.getVersionHistory();
+    console.log('[DevMode] Harness history:', history.length, 'versions');
+    return history;
+  }
+
+  function getHarnessDiff(from, to) {
+    if (!harness) {
+      console.warn('[DevMode] No harness available for diffing');
+      return null;
+    }
+    return harness.getStateDiff(from, to);
+  }
+
+  function getCorrelation() {
+    console.log('[DevMode] getCorrelation called, harness available:', !!harness);
+    if (!harness) {
+      console.warn('[DevMode] No harness available for correlation - run a Baba Yaga script first');
+      return null;
+    }
+    
+    const webState = get();
+    const harnessVersions = getHarnessHistory();
+    const currentCorrelation = harnessCorrelation.find(c => c.webVersion === pointer);
+    
+    const result = {
+      webState,
+      webVersion: pointer,
+      harnessVersions,
+      currentCorrelation,
+      allCorrelations: harnessCorrelation
+    };
+    
+    console.log('[DevMode] Correlation result:', {
+      webVersion: result.webVersion,
+      harnessVersions: result.harnessVersions.length,
+      correlations: result.allCorrelations.length
+    });
+    
+    return result;
+  }
+
+  function debugExecution(webVersion, harnessVersion) {
+    if (!harness) {
+      console.warn('[DevMode] No harness available for execution debugging');
+      return null;
+    }
+
+    const webState = history[webVersion];
+    const harnessState = harness.stateHistory.getVersion(harnessVersion);
+    const diff = getHarnessDiff(harnessVersion - 1, harnessVersion);
+    
+    return {
+      webState,
+      harnessState,
+      scriptDiff: diff,
+      correlation: `Web v${webVersion} ↔ Harness v${harnessVersion}`
+    };
+  }
+
+  function stepCombined(direction) {
+    if (direction === 'next') {
+      next();
+      // Could also step harness if correlated
+      const correlation = harnessCorrelation.find(c => c.webVersion === pointer);
+      if (correlation && harness) {
+        console.log(`[DevMode] Web v${pointer} correlates with Harness v${correlation.harnessVersion}`);
+      }
+    } else {
+      prev();
+    }
+  }
+
+  function logInstructions() {
+    if (firstLoad) {
+      console.log('[DevMode] Enhanced state history debugger with harness integration');
+      console.log('Web App Debugging:');
+      console.log('- dev.next()   // step forward');
+      console.log('- dev.prev()   // step backward');
+      console.log('- dev.goTo(n)  // jump to state n (1-based)');
+      console.log('- dev.get()    // get current state');
+      console.log('- dev.table()  // display history as a table');
+      console.log('- dev.history  // array of all states');
+      console.log('- dev.pointer  // current pointer (0-based)');
+      
+      if (harness) {
+        console.log('\nHarness Integration:');
+        console.log('- dev.harnessHistory()  // get harness version history');
+        console.log('- dev.harnessDiff(from, to)  // get state diff');
+        console.log('- dev.correlation()  // show web ↔ harness correlation');
+        console.log('- dev.debugExecution(webVer, harnessVer)  // debug specific execution');
+        console.log('- dev.stepCombined(direction)  // step both systems');
+      }
+      
+      console.log('\nEnhanced Console API:');
+      console.log('- debug.web  // web app debugging');
+      console.log('- debug.harness  // harness debugging');
+      console.log('- debug.combined  // combined debugging');
+      
+      firstLoad = false;
+    }
+  }
+
+  // Function to update harness instance (called after script execution)
+  function updateHarness(newHarness) {
+    console.log('[DevMode] updateHarness called with:', !!newHarness);
+    harness = newHarness;
+    console.log('[DevMode] Harness instance updated for enhanced debugging');
+    
+    // Re-expose the enhanced debug API with updated harness
+    window.debug = enhancedDebug;
+  }
+
+  // Function to check current dev tools status
+  function getStatus() {
+    return {
+      devMode: true,
+      webStates: history.length,
+      currentPointer: pointer,
+      harnessAvailable: !!harness,
+      harnessVersions: harness ? harness.getVersionHistory().length : 0,
+      correlations: harnessCorrelation.length
+    };
+  }
+
+  // Enhanced console API
+  const enhancedDebug = {
+    // Web app debugging
+    web: {
+      next,
+      prev,
+      goTo,
+      get,
+      table,
+      get pointer() { return pointer; },
+      get history() { return history.slice(); },
+    },
+    
+    // Harness debugging
+    harness: {
+      history: getHarnessHistory,
+      diff: getHarnessDiff,
+      correlation: getCorrelation,
+      debugExecution,
+    },
+    
+    // Combined debugging
+    combined: {
+      correlation: getCorrelation,
+      step: stepCombined,
+      execution: debugExecution,
+      status: getStatus,
+    }
+  };
+
+  // Expose API globally for console use
+  window.dev = {
+    next,
+    prev,
+    goTo,
+    get,
+    table,
+    get pointer() { return pointer; },
+    get history() { return history.slice(); },
+    // Harness integration methods
+    harnessHistory: getHarnessHistory,
+    harnessDiff: getHarnessDiff,
+    correlation: getCorrelation,
+    debugExecution,
+    stepCombined,
+    updateHarness,
+    getStatus,
+  };
+
+  // Debug logging to verify function exposure
+  console.log('[DevMode] Dev API functions exposed:', {
+    updateHarness: typeof window.dev.updateHarness,
+    getStatus: typeof window.dev.getStatus,
+    harnessHistory: typeof window.dev.harnessHistory,
+    correlation: typeof window.dev.correlation
+  });
+
+  // Expose enhanced debug API
+  window.debug = enhancedDebug;
+  
+  // Debug logging to verify API exposure
+  console.log('[DevMode] Enhanced debug API exposed:', {
+    debugAvailable: typeof window.debug !== 'undefined',
+    webAvailable: typeof window.debug?.web !== 'undefined',
+    harnessAvailable: typeof window.debug?.harness !== 'undefined',
+    combinedAvailable: typeof window.debug?.combined !== 'undefined'
+  });
+
+  // Initial state
+  pushState(getState());
+
+  return { pushState };
+} 
\ No newline at end of file