import { ErrorConstant } from '@remirror/core-constants' ; import { invariant , object } from '@remirror/core-helpers' ; import type { EditorState , Transaction } from '../state' ; import type { CommandFunction , EditorSchema , NonChainableCommandFunction , ProsemirrorCommandFunction , } from './pm-types' ; param tr param state export function chainableEditorState < Schema extends EditorSchema = EditorSchema > ( tr , state ) { const proto = Object . getPrototypeOf ( state ) ; let selection = tr . selection ; let doc = tr . doc ; let storedMarks = tr . storedMarks ; const properties = object ( ) ; for ( const [ key , value ] of Object . entries ( state ) ) { properties [ key ] = { value } ; } return Object . create ( proto , { ... properties , storedMarks : { get ( ) { return storedMarks ; } , } , selection : { get ( ) { return selection ; } , } , doc : { get ( ) { return doc ; } , } , tr : { get ( ) { selection = tr . selection ; doc = tr . doc ; storedMarks = tr . storedMarks ; return tr ; } , } , } ) ; } /**
 * Wraps the default [[ProsemirrorCommandFunction]] and makes it compatible with
 * the default **remirror** [[CommandFunction]] call signature.
 *
 * It extracts all the public APIs of the state object and assigns the
 * chainable transaction to the `state.tr` property to support chaining.
 */ export function convertCommand < Schema extends EditorSchema = EditorSchema , Extra extends object = object > ( commandFunction ) { return ( { state , dispatch , view , tr } ) => commandFunction ( chainableEditorState ( tr , state ) , dispatch , view ) ; } remarks export function nonChainable < Schema extends EditorSchema = EditorSchema , Extra extends object = object > ( commandFunction ) { return ( ( props ) => { invariant ( props . dispatch === undefined || props . dispatch === props . view ?. dispatch , { code : ErrorConstant . NON_CHAINABLE_COMMAND , } ) ; return commandFunction ( props ) ; } ) as NonChainableCommandFunction < Schema , Extra > ; } /**
 * Similar to the chainCommands from the `prosemirror-commands` library. Allows
 * multiple commands to be chained together and runs until one of them returns
 * true.
 */ export function chainCommands < Schema extends EditorSchema = EditorSchema , Extra extends object = object > ( ... commands ) { return ( { state , dispatch , view , tr , ... rest } ) => { for ( const element of commands ) { if ( element ( { state , dispatch , view , tr , ... ( rest as Extra ) } ) ) { return true ; } } return false ; } ; }