{
  "version": 3,
  "sources": ["../../../src/components/provider/use-entity-contains-snapshot.js"],
  "sourcesContent": ["import {\n\tuseEffect,\n\tuseLayoutEffect,\n\tuseRef,\n\tuseState,\n} from '@wordpress/element';\nimport { useRegistry, useSelect } from '@wordpress/data';\nimport {\n\tstore as coreStore,\n\tprivateApis as coreDataPrivateApis,\n} from '@wordpress/core-data';\nimport { store as editorStore } from '../../store';\nimport { unlock } from '../../lock-unlock';\n\nconst { entityContainsSnapshot } = unlock( coreDataPrivateApis );\n\n/**\n * How long the snapshot status decision waits for the shared document to\n * sync before failing open and resolving to 'missing'. The decision can\n * resolve earlier when the document proves it contains the snapshot or the\n * connection fails.\n */\nexport const SNAPSHOT_STATUS_SYNC_WAIT_MS = 3000;\n\n/**\n * Decides whether the shared (CRDT) document for a post contains everything\n * a previously captured snapshot describes.\n *\n * The decision is made at most once, shortly after mount:\n *\n * - 'present' when the shared document proves it holds everything the\n *   snapshot captured. The changes the snapshot describes are either part of\n *   the document or were deliberately superseded by later changes, so any\n *   artifact recorded alongside the snapshot (an autosave, a browser backup)\n *   is redundant.\n * - 'missing' when the snapshot cannot be confirmed: no snapshot was given,\n *   collaboration is not (or no longer) enabled for the post, the sync\n *   connection failed, or the document did not confirm the snapshot within\n *   `SNAPSHOT_STATUS_SYNC_WAIT_MS`. Callers should fail open and treat the\n *   snapshotted artifact as meaningful.\n * - 'pending' while the decision is still waiting for one of those signals.\n *\n * IMPORTANT: Call this hook after the mount effect that dispatches\n * `setupEditor`, so that the collaboration check can read the current post.\n *\n * @param {Object}        props            Hook props.\n * @param {string}        props.postType   The post type.\n * @param {number|string} props.postId     The post ID.\n * @param {string}        [props.snapshot] Base64-encoded snapshot to check.\n *\n * @return {'pending'|'present'|'missing'} The snapshot status.\n */\nexport default function useEntityContainsSnapshot( {\n\tpostType,\n\tpostId,\n\tsnapshot,\n} ) {\n\tconst registry = useRegistry();\n\n\tconst [ snapshotStatus, setSnapshotStatus ] = useState( 'pending' );\n\n\t// Whether the decision is still waiting for a signal from the shared\n\t// document. Only set for collaborative posts.\n\tconst isPendingRef = useRef( false );\n\n\t// Whether the decision has waited long enough for the shared document\n\t// to sync.\n\tconst [ hasWaitExpired, setHasWaitExpired ] = useState( false );\n\n\t// Selected values used to re-run the decision effect below. The effect\n\t// reads fresh store values when it runs.\n\tconst { syncStatus, isCollaborationEnabledForPost } = useSelect(\n\t\t( select ) => {\n\t\t\tif ( ! snapshot ) {\n\t\t\t\treturn {\n\t\t\t\t\tsyncStatus: undefined,\n\t\t\t\t\tisCollaborationEnabledForPost: false,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tconst connectionStatus = unlock(\n\t\t\t\tselect( coreStore )\n\t\t\t).getEntitySyncConnectionStatus( 'postType', postType, postId );\n\n\t\t\treturn {\n\t\t\t\tsyncStatus: connectionStatus?.status,\n\t\t\t\tisCollaborationEnabledForPost: unlock(\n\t\t\t\t\tselect( editorStore )\n\t\t\t\t).isCollaborationEnabledForCurrentPost(),\n\t\t\t};\n\t\t},\n\t\t[ postType, postId, snapshot ]\n\t);\n\n\tuseLayoutEffect( () => {\n\t\tconst canDefer =\n\t\t\tsnapshot &&\n\t\t\tunlock(\n\t\t\t\tregistry.select( editorStore )\n\t\t\t).isCollaborationEnabledForCurrentPost();\n\n\t\t// Without a snapshot to check, or outside real-time collaboration,\n\t\t// the shared document can never confirm the snapshot. Fail open\n\t\t// right away.\n\t\tif ( ! canDefer ) {\n\t\t\tsetSnapshotStatus( 'missing' );\n\t\t\treturn;\n\t\t}\n\n\t\t// Defer the decision until the shared document confirms the snapshot,\n\t\t// sync fails, or the wait deadline below expires (see the decision\n\t\t// effect below).\n\t\tisPendingRef.current = true;\n\n\t\tconst timeoutId = setTimeout( () => {\n\t\t\tsetHasWaitExpired( true );\n\t\t}, SNAPSHOT_STATUS_SYNC_WAIT_MS );\n\n\t\treturn () => clearTimeout( timeoutId );\n\n\t\t// The decision is initiated once, on mount.\n\t\t// eslint-disable-next-line react-hooks/exhaustive-deps\n\t}, [] );\n\n\t// Deferred snapshot status decision for collaborative posts. See the\n\t// hook docblock for the full decision rules.\n\tuseEffect( () => {\n\t\tif ( ! isPendingRef.current ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst containsSnapshot = entityContainsSnapshot(\n\t\t\t'postType',\n\t\t\tpostType,\n\t\t\tpostId,\n\t\t\tsnapshot\n\t\t);\n\n\t\tconst isCollaborationEnabled = unlock(\n\t\t\tregistry.select( editorStore )\n\t\t).isCollaborationEnabledForCurrentPost();\n\t\tconst connectionStatus = unlock(\n\t\t\tregistry.select( coreStore )\n\t\t).getEntitySyncConnectionStatus( 'postType', postType, postId );\n\n\t\tlet nextSnapshotStatus;\n\n\t\tif ( containsSnapshot ) {\n\t\t\tnextSnapshotStatus = 'present';\n\t\t} else if ( ! isCollaborationEnabled ) {\n\t\t\t// Collaboration was disabled after mount (e.g. incompatible\n\t\t\t// metaboxes were detected). Sync will never connect.\n\t\t\tnextSnapshotStatus = 'missing';\n\t\t} else if ( 'disconnected' === connectionStatus?.status ) {\n\t\t\t// The connection failed before it was established, so the\n\t\t\t// shared document may be missing the snapshotted content.\n\t\t\tnextSnapshotStatus = 'missing';\n\t\t} else if ( hasWaitExpired ) {\n\t\t\t// The document did not confirm the snapshot in time. Treat the\n\t\t\t// snapshotted content as missing from the shared document.\n\t\t\tnextSnapshotStatus = 'missing';\n\t\t} else {\n\t\t\t// Keep waiting for a definitive signal.\n\t\t\treturn;\n\t\t}\n\n\t\tisPendingRef.current = false;\n\t\tsetSnapshotStatus( nextSnapshotStatus );\n\n\t\t// The decision must run at most once. `snapshot` is stable for the\n\t\t// lifetime of the caller; the values below only trigger\n\t\t// re-evaluation.\n\t\t// eslint-disable-next-line react-hooks/exhaustive-deps\n\t}, [\n\t\tsyncStatus,\n\t\thasWaitExpired,\n\t\tisCollaborationEnabledForPost,\n\t\tpostType,\n\t\tpostId,\n\t] );\n\n\treturn snapshotStatus;\n}\n"],
  "mappings": ";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,qBAKO;AACP,kBAAuC;AACvC,uBAGO;AACP,mBAAqC;AACrC,yBAAuB;AAEvB,IAAM,EAAE,uBAAuB,QAAI,2BAAQ,iBAAAA,WAAoB;AAQxD,IAAM,+BAA+B;AA8B7B,SAAR,0BAA4C;AAAA,EAClD;AAAA,EACA;AAAA,EACA;AACD,GAAI;AACH,QAAM,eAAW,yBAAY;AAE7B,QAAM,CAAE,gBAAgB,iBAAkB,QAAI,yBAAU,SAAU;AAIlE,QAAM,mBAAe,uBAAQ,KAAM;AAInC,QAAM,CAAE,gBAAgB,iBAAkB,QAAI,yBAAU,KAAM;AAI9D,QAAM,EAAE,YAAY,8BAA8B,QAAI;AAAA,IACrD,CAAE,WAAY;AACb,UAAK,CAAE,UAAW;AACjB,eAAO;AAAA,UACN,YAAY;AAAA,UACZ,+BAA+B;AAAA,QAChC;AAAA,MACD;AAEA,YAAM,uBAAmB;AAAA,QACxB,OAAQ,iBAAAC,KAAU;AAAA,MACnB,EAAE,8BAA+B,YAAY,UAAU,MAAO;AAE9D,aAAO;AAAA,QACN,YAAY,kBAAkB;AAAA,QAC9B,mCAA+B;AAAA,UAC9B,OAAQ,aAAAC,KAAY;AAAA,QACrB,EAAE,qCAAqC;AAAA,MACxC;AAAA,IACD;AAAA,IACA,CAAE,UAAU,QAAQ,QAAS;AAAA,EAC9B;AAEA,sCAAiB,MAAM;AACtB,UAAM,WACL,gBACA;AAAA,MACC,SAAS,OAAQ,aAAAA,KAAY;AAAA,IAC9B,EAAE,qCAAqC;AAKxC,QAAK,CAAE,UAAW;AACjB,wBAAmB,SAAU;AAC7B;AAAA,IACD;AAKA,iBAAa,UAAU;AAEvB,UAAM,YAAY,WAAY,MAAM;AACnC,wBAAmB,IAAK;AAAA,IACzB,GAAG,4BAA6B;AAEhC,WAAO,MAAM,aAAc,SAAU;AAAA,EAItC,GAAG,CAAC,CAAE;AAIN,gCAAW,MAAM;AAChB,QAAK,CAAE,aAAa,SAAU;AAC7B;AAAA,IACD;AAEA,UAAM,mBAAmB;AAAA,MACxB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACD;AAEA,UAAM,6BAAyB;AAAA,MAC9B,SAAS,OAAQ,aAAAA,KAAY;AAAA,IAC9B,EAAE,qCAAqC;AACvC,UAAM,uBAAmB;AAAA,MACxB,SAAS,OAAQ,iBAAAD,KAAU;AAAA,IAC5B,EAAE,8BAA+B,YAAY,UAAU,MAAO;AAE9D,QAAI;AAEJ,QAAK,kBAAmB;AACvB,2BAAqB;AAAA,IACtB,WAAY,CAAE,wBAAyB;AAGtC,2BAAqB;AAAA,IACtB,WAAY,mBAAmB,kBAAkB,QAAS;AAGzD,2BAAqB;AAAA,IACtB,WAAY,gBAAiB;AAG5B,2BAAqB;AAAA,IACtB,OAAO;AAEN;AAAA,IACD;AAEA,iBAAa,UAAU;AACvB,sBAAmB,kBAAmB;AAAA,EAMvC,GAAG;AAAA,IACF;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACD,CAAE;AAEF,SAAO;AACR;",
  "names": ["coreDataPrivateApis", "coreStore", "editorStore"]
}
