diff.tsx 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  1. import { checksum } from "@opencode-ai/util/encode"
  2. import { FileDiff } from "@pierre/diffs"
  3. import { createEffect, createMemo, onCleanup, splitProps } from "solid-js"
  4. import { createDefaultOptions, type DiffProps, styleVariables } from "../pierre"
  5. import { getWorkerPool } from "../pierre/worker"
  6. export function Diff<T>(props: DiffProps<T>) {
  7. let container!: HTMLDivElement
  8. const [local, others] = splitProps(props, ["before", "after", "class", "classList", "annotations"])
  9. const options = createMemo(() => ({
  10. ...createDefaultOptions(props.diffStyle),
  11. ...others,
  12. }))
  13. let instance: FileDiff<T> | undefined
  14. createEffect(() => {
  15. const opts = options()
  16. const workerPool = getWorkerPool(props.diffStyle)
  17. const annotations = local.annotations
  18. const beforeContents = typeof local.before?.contents === "string" ? local.before.contents : ""
  19. const afterContents = typeof local.after?.contents === "string" ? local.after.contents : ""
  20. instance?.cleanUp()
  21. instance = new FileDiff<T>(opts, workerPool)
  22. container.innerHTML = ""
  23. instance.render({
  24. oldFile: {
  25. ...local.before,
  26. contents: beforeContents,
  27. cacheKey: checksum(beforeContents),
  28. },
  29. newFile: {
  30. ...local.after,
  31. contents: afterContents,
  32. cacheKey: checksum(afterContents),
  33. },
  34. lineAnnotations: annotations,
  35. containerWrapper: container,
  36. })
  37. })
  38. onCleanup(() => {
  39. instance?.cleanUp()
  40. })
  41. return <div data-component="diff" style={styleVariables} ref={container} />
  42. }