diff --git a/packages/super-editor/src/editors/v1/extensions/track-changes/trackChangesHelpers/getTrackChanges.js b/packages/super-editor/src/editors/v1/extensions/track-changes/trackChangesHelpers/getTrackChanges.js index aaaf6ea4da..4450620adc 100644 --- a/packages/super-editor/src/editors/v1/extensions/track-changes/trackChangesHelpers/getTrackChanges.js +++ b/packages/super-editor/src/editors/v1/extensions/track-changes/trackChangesHelpers/getTrackChanges.js @@ -3,12 +3,18 @@ import { findInlineNodes } from './documentHelpers.js'; /** * Get track changes marks. - * @param {import('prosemirror-state').EditorState} state - * @param {string} id + * + * Tolerates a missing or partially-initialized state and returns an empty array + * instead of throwing. Comment-import bootstrap can call this through a + * setTimeout(0) before the editor's PM state is attached (SD-2641). + * + * @param {import('prosemirror-state').EditorState | null | undefined} state + * @param {string} [id] * @returns {Array} Array with track changes marks. */ export const getTrackChanges = (state, id = null) => { const trackedChanges = []; + if (!state?.doc) return trackedChanges; const allInlineNodes = findInlineNodes(state.doc); if (!allInlineNodes.length) { diff --git a/packages/super-editor/src/editors/v1/extensions/track-changes/trackChangesHelpers/getTrackChanges.test.js b/packages/super-editor/src/editors/v1/extensions/track-changes/trackChangesHelpers/getTrackChanges.test.js new file mode 100644 index 0000000000..34d3805b47 --- /dev/null +++ b/packages/super-editor/src/editors/v1/extensions/track-changes/trackChangesHelpers/getTrackChanges.test.js @@ -0,0 +1,26 @@ +import { describe, test, expect } from 'vitest'; +import { getTrackChanges } from './getTrackChanges.js'; + +// SD-2641: The helper must not throw when called before the editor's PM state +// is initialized. During DOCX comment-import bootstrap, the orchestrator schedules +// the call via setTimeout(0) which only defers to the next tick — it does not wait +// for editor.state to be attached. The helper is reused from 4 call sites in +// comments-store.js, so we harden it once at the source rather than guarding each +// caller. +describe('getTrackChanges — null-safe input handling', () => { + test('returns [] when state is undefined', () => { + expect(getTrackChanges(undefined)).toEqual([]); + }); + + test('returns [] when state is null', () => { + expect(getTrackChanges(null)).toEqual([]); + }); + + test('returns [] when state has no doc property', () => { + expect(getTrackChanges({})).toEqual([]); + }); + + test('returns [] when state.doc is undefined', () => { + expect(getTrackChanges({ doc: undefined })).toEqual([]); + }); +});