use-debug-diff-tracker.ts 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. import { useEffect, useMemo, useRef } from 'react'
  2. import { DocumentContainer } from '../editor/document-container'
  3. import { DocId } from '../../../../../types/project-settings'
  4. import { debugConsole } from '@/utils/debugging'
  5. import { diffChars } from 'diff'
  6. const DIFF_TIMEOUT_MS = 5000
  7. async function tryGetDiffSize(
  8. currentContents: string | null | undefined,
  9. projectId: string | null,
  10. docId: DocId | null | undefined
  11. ): Promise<number | null> {
  12. debugConsole.debug('tryGetDiffSize')
  13. // If we don't know the current content or id, there's not much we can do
  14. if (!projectId) {
  15. debugConsole.debug('tryGetDiffSize: missing projectId')
  16. return null
  17. }
  18. if (!currentContents) {
  19. debugConsole.debug('tryGetDiffSize: missing currentContents')
  20. return null
  21. }
  22. if (!docId) {
  23. debugConsole.debug('tryGetDiffSize: missing docId')
  24. return null
  25. }
  26. try {
  27. const response = await fetch(
  28. `/Project/${projectId}/doc/${docId}/download`,
  29. { signal: AbortSignal.timeout(DIFF_TIMEOUT_MS) }
  30. )
  31. const serverContent = await response.text()
  32. const differences = diffChars(serverContent, currentContents)
  33. let diffSize = 0
  34. for (const diff of differences) {
  35. if (diff.added || diff.removed) {
  36. diffSize += diff.value.length
  37. }
  38. }
  39. return diffSize
  40. } catch {
  41. // There's a good chance we're offline, so just return null
  42. debugConsole.debug('tryGetDiffSize: fetch failed')
  43. return null
  44. }
  45. }
  46. export const useDebugDiffTracker = (
  47. projectId: string,
  48. currentDocument: DocumentContainer | null
  49. ) => {
  50. const debugCurrentDocument = useRef<DocumentContainer | null>(null)
  51. const debugProjectId = useRef<string | null>(null)
  52. const debugTimers = useRef<Record<string, number>>({})
  53. useEffect(() => {
  54. debugCurrentDocument.current = currentDocument
  55. }, [currentDocument])
  56. useEffect(() => {
  57. debugProjectId.current = projectId
  58. }, [projectId])
  59. const createDebugDiff = useMemo(
  60. () => async () =>
  61. await tryGetDiffSize(
  62. debugCurrentDocument.current?.getSnapshot(),
  63. debugProjectId.current,
  64. debugCurrentDocument.current?.doc_id as DocId | undefined
  65. ),
  66. []
  67. )
  68. return {
  69. createDebugDiff,
  70. debugTimers,
  71. }
  72. }