@tracecode/harness 0.6.2 → 0.6.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -57,6 +57,7 @@ __export(src_exports, {
57
57
  getSupportedLanguageProfiles: () => getSupportedLanguageProfiles,
58
58
  identifyConversions: () => identifyConversions,
59
59
  isLanguageSupported: () => isLanguageSupported,
60
+ normalizeJavaSerializedResult: () => normalizeJavaSerializedResult,
60
61
  normalizeJavaSpikeTraceContract: () => normalizeJavaTraceContract,
61
62
  normalizeJavaTraceContract: () => normalizeJavaTraceContract,
62
63
  normalizeRuntimeTraceContract: () => normalizeRuntimeTraceContract,
@@ -429,6 +430,16 @@ function parseScalar(raw) {
429
430
  }
430
431
  return raw;
431
432
  }
433
+ function normalizeJavaSerializedResult(output) {
434
+ if (typeof output !== "string") {
435
+ return output;
436
+ }
437
+ try {
438
+ return JSON.parse(output);
439
+ } catch {
440
+ return output;
441
+ }
442
+ }
432
443
  function parseKeyValuePairs(fragment) {
433
444
  const variables = {};
434
445
  const matches = Array.from(fragment.matchAll(/\b([A-Za-z_][A-Za-z0-9_.]*)=/g));
@@ -609,10 +620,29 @@ function parseAccessEvent(payload) {
609
620
  pathDepth: 1
610
621
  }];
611
622
  }
623
+ const indexedMutatingCall = payload.match(/^mutate-indexed ([A-Za-z_][A-Za-z0-9_]*)\[(\d+)\] method=([A-Za-z_][A-Za-z0-9_]*)$/);
624
+ if (indexedMutatingCall) {
625
+ return [{
626
+ variable: indexedMutatingCall[1],
627
+ kind: "mutating-call",
628
+ indices: [Number.parseInt(indexedMutatingCall[2], 10)],
629
+ method: indexedMutatingCall[3],
630
+ pathDepth: 1
631
+ }];
632
+ }
633
+ const keyedCall = payload.match(/^keyed-call ([A-Za-z_][A-Za-z0-9_]*) method=([A-Za-z_][A-Za-z0-9_]*)(?:\s+.*)?$/);
634
+ if (keyedCall) {
635
+ return [{
636
+ variable: keyedCall[1],
637
+ kind: "mutating-call",
638
+ method: keyedCall[2],
639
+ pathDepth: 1
640
+ }];
641
+ }
612
642
  return void 0;
613
643
  }
614
644
  function parseStructureState(payload) {
615
- const match = payload.match(/^state (linked-list|tree) ([A-Za-z_][A-Za-z0-9_]*)=(.+)$/);
645
+ const match = payload.match(/^state (linked-list|tree|graph-adjacency) ([A-Za-z_][A-Za-z0-9_]*)=(.+)$/);
616
646
  if (!match) return null;
617
647
  return {
618
648
  structure: match[1],
@@ -628,6 +658,22 @@ function parseObjectState(payload) {
628
658
  visualization: JSON.parse(match[2])
629
659
  };
630
660
  }
661
+ function parseMapState(payload) {
662
+ const match = payload.match(/^map-state ([A-Za-z_][A-Za-z0-9_]*)=(.+)$/);
663
+ if (!match) return null;
664
+ return {
665
+ variable: match[1],
666
+ visualization: JSON.parse(match[2])
667
+ };
668
+ }
669
+ function parseSetState(payload) {
670
+ const match = payload.match(/^set-state ([A-Za-z_][A-Za-z0-9_]*)=(.+)$/);
671
+ if (!match) return null;
672
+ return {
673
+ variable: match[1],
674
+ visualization: JSON.parse(match[2])
675
+ };
676
+ }
631
677
  function parseObjectFieldEvent(payload) {
632
678
  const match = payload.match(/^(access|write) ([A-Za-z_][A-Za-z0-9_]*)\.([A-Za-z_][A-Za-z0-9_]*)=(.+)$/);
633
679
  if (!match) return null;
@@ -637,6 +683,9 @@ function parseObjectFieldEvent(payload) {
637
683
  value: parseScalar(match[4])
638
684
  };
639
685
  }
686
+ function isArrayLengthAccessEvent(payload) {
687
+ return /^access [A-Za-z_][A-Za-z0-9_]*\.length=\d+$/.test(payload);
688
+ }
640
689
  function buildFieldVisualization(event) {
641
690
  return {
642
691
  objectKinds: {
@@ -716,12 +765,13 @@ function filterStructuredVariables(variables) {
716
765
  }
717
766
  return Object.fromEntries(entries);
718
767
  }
719
- function appendJavaTraceStep(trace, step, pendingAccesses) {
768
+ function appendJavaTraceStep(trace, step, pendingAccesses, options = {}) {
720
769
  const nextStep = pendingAccesses.length > 0 ? { ...step, accesses: [...pendingAccesses] } : step;
721
770
  pendingAccesses.length = 0;
722
- if (!maybeMergeConsecutiveLineStep(trace, nextStep)) {
723
- trace.push(nextStep);
771
+ if (options.allowMerge !== false && maybeMergeConsecutiveLineStep(trace, nextStep)) {
772
+ return;
724
773
  }
774
+ trace.push(nextStep);
725
775
  }
726
776
  function mergeIntoPreviousMatchingLineStep(trace, line, currentFunction, currentCallStack, patch) {
727
777
  const candidate = trace.at(-1);
@@ -755,11 +805,14 @@ function eventsToRawTrace(events, sourceText) {
755
805
  const stack = [];
756
806
  const pendingAccesses = [];
757
807
  let currentFunction = "<module>";
808
+ let previousRawLine = null;
758
809
  const lineRemap = buildLineRemap(sourceText);
759
810
  const declarationLines = buildMethodDeclarationLineSet(sourceText);
760
811
  for (const rawEvent of events) {
761
812
  if (rawEvent === "clear" || rawEvent === "reset") continue;
762
813
  const metadata = extractLineMetadata(rawEvent);
814
+ const previousEventRawLine = previousRawLine;
815
+ previousRawLine = metadata.line;
763
816
  const line = lineRemap?.get(metadata.line) ?? metadata.line;
764
817
  const payload = metadata.payload;
765
818
  const isDeclarationLine = declarationLines?.has(line) === true;
@@ -767,28 +820,31 @@ function eventsToRawTrace(events, sourceText) {
767
820
  const match = payload.match(/^call\s+(\S+)(?:\s+(.*))?$/);
768
821
  const functionName = match?.[1] ?? currentFunction;
769
822
  const argsFragment = match?.[2] ?? "";
770
- Object.assign(variables, parseKeyValuePairs(argsFragment));
823
+ const args = parseKeyValuePairs(argsFragment);
824
+ Object.assign(variables, args);
771
825
  currentFunction = functionName || currentFunction;
772
- stack.push({ function: currentFunction, line });
826
+ stack.push({ function: currentFunction, line, args });
773
827
  appendJavaTraceStep(trace, {
774
828
  line,
775
829
  event: "call",
776
830
  function: currentFunction,
777
831
  variables: { ...variables },
778
- callStack: stack.map((frame) => ({ function: frame.function, line: frame.line, args: {} }))
832
+ callStack: stack.map((frame) => ({ function: frame.function, line: frame.line, args: { ...frame.args } }))
779
833
  }, pendingAccesses);
780
834
  continue;
781
835
  }
782
836
  if (payload.startsWith("return ")) {
783
- const match = payload.match(/^return\s+(\S+)$/);
837
+ const match = payload.match(/^return\s+(\S+)(?:\s+value=(.*))?$/);
784
838
  const functionName = match?.[1] ?? currentFunction;
839
+ const returnValue = match?.[2] !== void 0 ? parseScalar(match[2].trim()) : void 0;
785
840
  const returnVariables = functionName === "<module>" ? { ...variables } : filterStructuredVariables(variables) ?? {};
786
841
  appendJavaTraceStep(trace, {
787
842
  line,
788
843
  event: "return",
789
844
  function: functionName || currentFunction,
790
845
  variables: returnVariables,
791
- callStack: stack.map((frame) => ({ function: frame.function, line: frame.line, args: {} }))
846
+ callStack: stack.map((frame) => ({ function: frame.function, line: frame.line, args: { ...frame.args } })),
847
+ ...returnValue !== void 0 ? { returnValue } : {}
792
848
  }, pendingAccesses);
793
849
  stack.pop();
794
850
  currentFunction = stack[stack.length - 1]?.function ?? "<module>";
@@ -803,8 +859,8 @@ function eventsToRawTrace(events, sourceText) {
803
859
  event: "line",
804
860
  function: currentFunction,
805
861
  variables: { ...variables },
806
- ...stack.length > 0 ? { callStack: stack.map((frame) => ({ function: frame.function, line: frame.line, args: {} })) } : {}
807
- }, pendingAccesses);
862
+ ...stack.length > 0 ? { callStack: stack.map((frame) => ({ function: frame.function, line: frame.line, args: { ...frame.args } })) } : {}
863
+ }, pendingAccesses, { allowMerge: previousEventRawLine !== metadata.line });
808
864
  continue;
809
865
  }
810
866
  const structureState = parseStructureState(payload);
@@ -816,7 +872,7 @@ function eventsToRawTrace(events, sourceText) {
816
872
  event: "line",
817
873
  function: currentFunction,
818
874
  variables: { ...variables },
819
- callStack: stack.map((frame) => ({ function: frame.function, line: frame.line, args: {} })),
875
+ callStack: stack.map((frame) => ({ function: frame.function, line: frame.line, args: { ...frame.args } })),
820
876
  visualization: {
821
877
  objectKinds: { ...objectKinds }
822
878
  }
@@ -831,7 +887,7 @@ function eventsToRawTrace(events, sourceText) {
831
887
  event: "line",
832
888
  function: currentFunction,
833
889
  variables: { ...variables },
834
- callStack: stack.map((frame) => ({ function: frame.function, line: frame.line, args: {} })),
890
+ callStack: stack.map((frame) => ({ function: frame.function, line: frame.line, args: { ...frame.args } })),
835
891
  visualization: {
836
892
  objectKinds: { [objectState.variable]: "object" },
837
893
  hashMaps: [objectState.visualization]
@@ -839,10 +895,56 @@ function eventsToRawTrace(events, sourceText) {
839
895
  }, pendingAccesses);
840
896
  continue;
841
897
  }
898
+ const mapState = parseMapState(payload);
899
+ if (mapState) {
900
+ const entries = mapState.visualization.entries.map((entry) => [entry.key, entry.value]);
901
+ variables[mapState.variable] = { __type__: "map", entries };
902
+ appendJavaTraceStep(trace, {
903
+ line,
904
+ event: "line",
905
+ function: currentFunction,
906
+ variables: { ...variables },
907
+ callStack: stack.map((frame) => ({ function: frame.function, line: frame.line, args: { ...frame.args } })),
908
+ visualization: {
909
+ objectKinds: { [mapState.variable]: "map" },
910
+ hashMaps: [mapState.visualization]
911
+ }
912
+ }, pendingAccesses);
913
+ continue;
914
+ }
915
+ const setState = parseSetState(payload);
916
+ if (setState) {
917
+ const values = setState.visualization.entries.map((entry) => entry.key);
918
+ variables[setState.variable] = { __type__: "set", values };
919
+ appendJavaTraceStep(trace, {
920
+ line,
921
+ event: "line",
922
+ function: currentFunction,
923
+ variables: { ...variables },
924
+ callStack: stack.map((frame) => ({ function: frame.function, line: frame.line, args: { ...frame.args } })),
925
+ visualization: {
926
+ objectKinds: { [setState.variable]: "set" },
927
+ hashMaps: [setState.visualization]
928
+ }
929
+ }, pendingAccesses);
930
+ continue;
931
+ }
932
+ if (isArrayLengthAccessEvent(payload)) {
933
+ continue;
934
+ }
935
+ const accesses = parseAccessEvent(payload);
936
+ if (accesses) {
937
+ const currentCallStack = stack.length > 0 ? stack.map((frame) => ({ function: frame.function, line: frame.line, args: { ...frame.args } })) : void 0;
938
+ if (mergeAccessesIntoPreviousMatchingLineStep(trace, line, currentFunction, currentCallStack, accesses)) {
939
+ continue;
940
+ }
941
+ pendingAccesses.push(...accesses);
942
+ continue;
943
+ }
842
944
  const objectField = parseObjectFieldEvent(payload);
843
945
  if (objectField) {
844
946
  variables[objectField.variable] = { __ref__: `${objectField.variable}-object` };
845
- const currentCallStack = stack.length > 0 ? stack.map((frame) => ({ function: frame.function, line: frame.line, args: {} })) : void 0;
947
+ const currentCallStack = stack.length > 0 ? stack.map((frame) => ({ function: frame.function, line: frame.line, args: { ...frame.args } })) : void 0;
846
948
  if (mergeIntoPreviousMatchingLineStep(trace, line, currentFunction, currentCallStack, {
847
949
  variables: { ...variables },
848
950
  accesses: void 0,
@@ -855,27 +957,18 @@ function eventsToRawTrace(events, sourceText) {
855
957
  event: "line",
856
958
  function: currentFunction,
857
959
  variables: { ...variables },
858
- callStack: stack.map((frame) => ({ function: frame.function, line: frame.line, args: {} })),
960
+ callStack: stack.map((frame) => ({ function: frame.function, line: frame.line, args: { ...frame.args } })),
859
961
  visualization: buildFieldVisualization(objectField)
860
962
  }, pendingAccesses);
861
963
  continue;
862
964
  }
863
965
  Object.assign(variables, parseKeyValuePairs(payload));
864
- const accesses = parseAccessEvent(payload);
865
- if (accesses) {
866
- const currentCallStack = stack.length > 0 ? stack.map((frame) => ({ function: frame.function, line: frame.line, args: {} })) : void 0;
867
- if (mergeAccessesIntoPreviousMatchingLineStep(trace, line, currentFunction, currentCallStack, accesses)) {
868
- continue;
869
- }
870
- pendingAccesses.push(...accesses);
871
- continue;
872
- }
873
966
  appendJavaTraceStep(trace, {
874
967
  line,
875
968
  event: "line",
876
969
  function: currentFunction,
877
970
  variables: { ...variables },
878
- ...stack.length > 0 ? { callStack: stack.map((frame) => ({ function: frame.function, line: frame.line, args: {} })) } : {}
971
+ ...stack.length > 0 ? { callStack: stack.map((frame) => ({ function: frame.function, line: frame.line, args: { ...frame.args } })) } : {}
879
972
  }, pendingAccesses);
880
973
  }
881
974
  if (pendingAccesses.length > 0 && trace.length > 0) {
@@ -884,11 +977,11 @@ function eventsToRawTrace(events, sourceText) {
884
977
  }
885
978
  return trace;
886
979
  }
887
- function buildJavaExecutionResult(output, events, executionTimeMs = 0, traceLimitExceeded, timeoutReason, maxTraceSteps, sourceText) {
980
+ function buildJavaExecutionResult(output, events, executionTimeMs = 0, traceLimitExceeded, timeoutReason, maxTraceSteps, sourceText, options = {}) {
888
981
  const trace = eventsToRawTrace(events, sourceText);
889
982
  return {
890
983
  success: true,
891
- output,
984
+ output: options.outputIsSerialized === false ? output : normalizeJavaSerializedResult(output),
892
985
  trace,
893
986
  executionTimeMs,
894
987
  consoleOutput: [],
@@ -1802,7 +1895,8 @@ var JavaRuntimeClient = class {
1802
1895
  rawResult.traceLimitExceeded,
1803
1896
  rawResult.timeoutReason,
1804
1897
  void 0,
1805
- rawResult.sourceText
1898
+ rawResult.sourceText,
1899
+ { outputIsSerialized: false }
1806
1900
  )
1807
1901
  );
1808
1902
  return {
@@ -2735,6 +2829,7 @@ function generateSolutionScript(solutionCode, functionName, inputs) {
2735
2829
  return `
2736
2830
  import json
2737
2831
  import sys
2832
+ from typing import *
2738
2833
 
2739
2834
  ${PYTHON_CLASS_DEFINITIONS}
2740
2835
 
@@ -3886,6 +3981,7 @@ async function executeTypeScriptCode(code, functionName, inputs, executionStyle
3886
3981
  getSupportedLanguageProfiles,
3887
3982
  identifyConversions,
3888
3983
  isLanguageSupported,
3984
+ normalizeJavaSerializedResult,
3889
3985
  normalizeJavaSpikeTraceContract,
3890
3986
  normalizeJavaTraceContract,
3891
3987
  normalizeRuntimeTraceContract,