const FunctionHistory = { oninit: function(vnode) { // Initialize indices in state vnode.state.leftIndex = vnode.attrs.versions.length - 1; // Earliest vnode.state.rightIndex = 0; // Latest }, view: function (vnode) { const versions = vnode.attrs.versions; return m("div", [ m("div.flex.gap-4.mb-4", [ m("div.flex-1", [ m("label.block.text-sm.font-medium.text-gray-700", "Left Version"), m("select.mt-1.block.w-full.rounded-md.border-gray-300.shadow-sm", { onchange: (e) => { vnode.state.leftIndex = parseInt(e.target.value); vnode.state.leftVersion = versions[vnode.state.leftIndex]; vnode.state.updateDiff(); }, value: vnode.state.leftIndex }, versions.map((v, idx) => m("option", { value: idx }, `Version ${v.version_number} (${new Date(v.versioned_at).toLocaleString()})`) )) ]), m("div.flex-1", [ m("label.block.text-sm.font-medium.text-gray-700", "Right Version"), m("select.mt-1.block.w-full.rounded-md.border-gray-300.shadow-sm", { onchange: (e) => { vnode.state.rightIndex = parseInt(e.target.value); vnode.state.rightVersion = versions[vnode.state.rightIndex]; vnode.state.updateDiff(); }, value: vnode.state.rightIndex }, versions.map((v, idx) => m("option", { value: idx }, `Version ${v.version_number} (${new Date(v.versioned_at).toLocaleString()})`) )) ]) ]), m("div", { id: "diff-container", style: "height: 500px; position: relative;" }) ]); }, oncreate: function (vnode) { const versions = vnode.attrs.versions; // Initialize with the earliest and most recent versions if available if (versions.length >= 2) { vnode.state.leftVersion = versions[versions.length - 1]; // Earliest version vnode.state.rightVersion = versions[0]; // Latest version } else if (versions.length === 1) { vnode.state.leftVersion = versions[0]; vnode.state.rightVersion = versions[0]; } vnode.state.updateDiff = function () { if (vnode.state.aceDiffer) { // Clean up previous instance vnode.state.aceDiffer.destroy(); } vnode.state.aceDiffer = new AceDiff({ element: '#diff-container', mode: "ace/mode/javascript", left: { content: vnode.state.leftVersion ? vnode.state.leftVersion.script : "", editable: false, }, right: { content: vnode.state.rightVersion ? vnode.state.rightVersion.script : "", editable: false, } }); // Configure both editors const editors = vnode.state.aceDiffer.getEditors(); ['left', 'right'].forEach(side => { editors[side].setOptions({ maxLines: 20, autoScrollEditorIntoView: true, }); editors[side].session.setOption("useWorker", false); }); }; // Initial diff setup vnode.state.updateDiff(); }, onremove: function (vnode) { // Clean up AceDiff when component is removed if (vnode.state.aceDiffer) { vnode.state.aceDiffer.destroy(); } } }; export default FunctionHistory;