Input: Adds a refinement on a hierarchical facet . [CODESPLIT] function ( facet , path ) { if ( this . isHierarchicalFacetRefined ( facet ) ) { throw new Error ( facet + ' is already refined.' ) ; } var mod = { } ; mod [ facet ] = [ path ] ; return this . setQueryParameters ( { hierarchicalFacetsRefinements : defaults ( { } , mod , this . hierarchicalFacetsRefinements ) } ) ; }


Input: Returns true if the facet is refined either for a specific value or in general . [CODESPLIT] function isFacetRefined ( facet , value ) { if ( ! this . isConjunctiveFacet ( facet ) ) { throw new Error ( facet + ' is not defined in the facets attribute of the helper configuration' ) ; } return RefinementList . isRefined ( this . facetsRefinements , facet , value ) ; }


Input: Returns true if the facet contains exclusions or if a specific value is excluded . [CODESPLIT] function isExcludeRefined ( facet , value ) { if ( ! this . isConjunctiveFacet ( facet ) ) { throw new Error ( facet + ' is not defined in the facets attribute of the helper configuration' ) ; } return RefinementList . isRefined ( this . facetsExcludes , facet , value ) ; }


Input: Returns true if the facet contains a refinement or if a value passed is a refinement for the facet . [CODESPLIT] function isDisjunctiveFacetRefined ( facet , value ) { if ( ! this . isDisjunctiveFacet ( facet ) ) { throw new Error ( facet + ' is not defined in the disjunctiveFacets attribute of the helper configuration' ) ; } return RefinementList . isRefined ( this . disjunctiveFacetsRefinements , facet , value ) ; }


Input: Returns true if the facet contains a refinement or if a value passed is a refinement for the facet . [CODESPLIT] function isHierarchicalFacetRefined ( facet , value ) { if ( ! this . isHierarchicalFacet ( facet ) ) { throw new Error ( facet + ' is not defined in the hierarchicalFacets attribute of the helper configuration' ) ; } var refinements = this . getHierarchicalRefinement ( facet ) ; if ( ! value ) { return refinements . length > 0 ; } return indexOf ( refinements , value ) !== - 1 ; }


Input: Test if the triple ( attribute operator value ) is already refined . If only the attribute and the operator are provided it tests if the contains any refinement value . [CODESPLIT] function isNumericRefined ( attribute , operator , value ) { if ( isUndefined ( value ) && isUndefined ( operator ) ) { return ! ! this . numericRefinements [ attribute ] ; } var isOperatorDefined = this . numericRefinements [ attribute ] && ! isUndefined ( this . numericRefinements [ attribute ] [ operator ] ) ; if ( isUndefined ( value ) || ! isOperatorDefined ) { return isOperatorDefined ; } var parsedValue = valToNumber ( value ) ; var isAttributeValueDefined = ! isUndefined ( findArray ( this . numericRefinements [ attribute ] [ operator ] , parsedValue ) ) ; return isOperatorDefined && isAttributeValueDefined ; }


Input: Returns the list of all disjunctive facets refined [CODESPLIT] function getRefinedDisjunctiveFacets ( ) { // attributes used for numeric filter can also be disjunctive var disjunctiveNumericRefinedFacets = intersection ( keys ( this . numericRefinements ) , this . disjunctiveFacets ) ; return keys ( this . disjunctiveFacetsRefinements ) . concat ( disjunctiveNumericRefinedFacets ) . concat ( this . getRefinedHierarchicalFacets ( ) ) ; }


Input: Let the user set a specific value for a given parameter . Will return the same instance if the parameter is invalid or if the value is the same as the previous one . [CODESPLIT] function setParameter ( parameter , value ) { if ( this [ parameter ] === value ) return this ; var modification = { } ; modification [ parameter ] = value ; return this . setQueryParameters ( modification ) ; }


Input: Let the user set any of the parameters with a plain object . [CODESPLIT] function setQueryParameters ( params ) { if ( ! params ) return this ; var error = SearchParameters . validate ( this , params ) ; if ( error ) { throw error ; } var parsedParams = SearchParameters . _parseNumbers ( params ) ; return this . mutateMe ( function mergeWith ( newInstance ) { var ks = keys ( params ) ; forEach ( ks , function ( k ) { newInstance [ k ] = parsedParams [ k ] ; } ) ; return newInstance ; } ) ; }


Input: Get the current breadcrumb for a hierarchical facet as an array [CODESPLIT] function ( facetName ) { if ( ! this . isHierarchicalFacet ( facetName ) ) { throw new Error ( 'Cannot get the breadcrumb of an unknown hierarchical facet: `' + facetName + '`' ) ; } var refinement = this . getHierarchicalRefinement ( facetName ) [ 0 ] ; if ( ! refinement ) return [ ] ; var separator = this . _getHierarchicalFacetSeparator ( this . getHierarchicalFacetByName ( facetName ) ) ; var path = refinement . split ( separator ) ; return map ( path , trim ) ; }


Input: Event triggered when the queue of queries have been depleted ( with any result or outdated queries ) @event AlgoliaSearchHelper#event : searchQueueEmpty @example helper . on ( searchQueueEmpty function () { console . log ( No more search pending ) ; // This is received before the result event if we re not expecting new results } ) ; [CODESPLIT] function AlgoliaSearchHelper ( client , index , options ) { if ( client . addAlgoliaAgent && ! doesClientAgentContainsHelper ( client ) ) { client . addAlgoliaAgent ( 'JS Helper (' + version + ')' ) ; } this . setClient ( client ) ; var opts = options || { } ; opts . index = index ; this . state = SearchParameters . make ( opts ) ; this . lastResults = null ; this . _queryId = 0 ; this . _lastQueryIdReceived = - 1 ; this . derivedHelpers = [ ] ; this . _currentNbQueries = 0 ; }


Input: Runs a command using the specified arguments . [CODESPLIT] function runCommand ( cmd , args ) { var prev = null ; console . log ( chalk . cyanBright ( cmd ) + " " + args . map ( arg => { if ( arg . startsWith ( "-" ) ) return chalk . gray ( "\\" ) + "\n " + chalk . bold ( arg ) ; return arg ; } ) . join ( " " ) + "\n" ) ; var proc = child_process . spawnSync ( cmd , args , { stdio : "inherit" } ) ; if ( proc . error ) throw proc . error ; if ( proc . status !== 0 ) throw Error ( "exited with " + proc . status ) ; return proc ; }


Input: Compiles embedded intrinsics used by the targets below . [CODESPLIT] function compileIntrinsics ( ) { var target = path . join ( sourceDirectory , "passes" , "WasmIntrinsics.cpp" ) ; runCommand ( "python" , [ path . join ( binaryenDirectory , "scripts" , "embedwast.py" ) , path . join ( sourceDirectory , "passes" , "wasm-intrinsics.wast" ) , target ] ) ; sourceFiles . push ( target ) ; }


Input: Compiles shared bitcode used to build the targets below . [CODESPLIT] function compileShared ( ) { runCommand ( "python" , [ path . join ( emscriptenDirectory , "em++" ) ] . concat ( sourceFiles ) . concat ( commonOptions ) . concat ( [ "-o" , "shared.bc" ] ) ) ; }


Input: Compiles the JavaScript target . [CODESPLIT] function compileJs ( options ) { runCommand ( "python" , [ path . join ( emscriptenDirectory , "em++" ) , "shared.bc" ] . concat ( commonOptions ) . concat ( [ "--post-js" , options . post , "--closure" , "1" , "-s" , "WASM=0" , "-s" , "EXPORTED_FUNCTIONS=[" + exportedFunctionsArg + "]" , "-s" , "ALLOW_MEMORY_GROWTH=1" , "-s" , "ELIMINATE_DUPLICATE_FUNCTIONS=1" , "-s" , "MODULARIZE_INSTANCE=1" , "-s" , "EXPORT_NAME=\"Binaryen\"" , "-o" , options . out , "-Oz" ] ) ) ; }


Input: Compiles the WebAssembly target . [CODESPLIT] function compileWasm ( options ) { run ( "python" , [ path . join ( emscriptenDirectory , "em++" ) , "shared.bc" ] . concat ( commonOptions ) . concat ( [ "--post-js" , options . post , "--closure" , "1" , "-s" , "EXPORTED_FUNCTIONS=[" + exportedFunctionsArg + "]" , "-s" , "ALLOW_MEMORY_GROWTH=1" , "-s" , "BINARYEN=1" , "-s" , "BINARYEN_METHOD=\"native-wasm\"" , "-s" , "MODULARIZE_INSTANCE=1" , "-s" , "EXPORT_NAME=\"Binaryen\"" , "-o" , options . out , "-Oz" ] ) ) ; }


Input: a function returning the state object [CODESPLIT] function pluginState ( ) { return { _sync : { signedIn : false , userId : null , unsubscribe : { } , pathVariables : { } , patching : false , syncStack : { inserts : [ ] , updates : { } , propDeletions : { } , deletions : [ ] , debounceTimer : null , } , fetched : { } , stopPatchingTimeout : null } } ; }


Input: Merge if exists [CODESPLIT] function helpers ( originVal , newVal ) { if ( isArray ( originVal ) && isArrayHelper ( newVal ) ) { newVal = newVal . executeOn ( originVal ) ; } if ( isNumber ( originVal ) && isIncrementHelper ( newVal ) ) { newVal = newVal . executeOn ( originVal ) ; } return newVal ; // always return newVal as fallback!! }


Input: Debounce helper [CODESPLIT] function startDebounce ( ms ) { var startTime = Date . now ( ) ; var done = new Promise ( function ( resolve , reject ) { var interval = setInterval ( function ( _ ) { var now = Date . now ( ) ; var deltaT = now - startTime ; if ( deltaT >= ms ) { clearInterval ( interval ) ; resolve ( true ) ; } } , 10 ) ; } ) ; var refresh = function ( ) { return ( startTime = Date . now ( ) ) ; } ; return { done : done , refresh : refresh } ; }


Input: Grab until the api limit ( 500 ) put the rest back in the syncStack . [CODESPLIT] function grabUntilApiLimit ( syncStackProp , count , maxCount , state ) { var targets = state . _sync . syncStack [ syncStackProp ] ; // Check if there are more than maxCount batch items already if ( count >= maxCount ) { // already at maxCount or more, leave items in syncstack, and don't add anything to batch targets = [ ] ; } else { // Convert to array if targets is an object (eg. updates) var targetIsObject = isPlainObject ( targets ) ; if ( targetIsObject ) { targets = Object . values ( targets ) ; } // Batch supports only until maxCount items var grabCount = maxCount - count ; var targetsOK = targets . slice ( 0 , grabCount ) ; var targetsLeft = targets . slice ( grabCount ) ; // Put back the remaining items over maxCount if ( targetIsObject ) { targetsLeft = Object . values ( targetsLeft ) . reduce ( function ( carry , update ) { var id = update . id ; carry [ id ] = update ; return carry ; } , { } ) ; } state . _sync . syncStack [ syncStackProp ] = targetsLeft ; // Define the items we'll add below targets = targetsOK ; } return targets ; }


Input: Create a Firebase batch from a syncStack to be passed inside the state param . [CODESPLIT] function makeBatchFromSyncstack ( state , getters , Firebase , batchMaxCount ) { if ( batchMaxCount === void 0 ) { batchMaxCount = 500 ; } // get state & getter variables var firestorePath = state . _conf . firestorePath ; var firestorePathComplete = getters . firestorePathComplete ; var dbRef = getters . dbRef ; var collectionMode = getters . collectionMode ; // make batch var batch = Firebase . firestore ( ) . batch ( ) ; var log = { } ; var count = 0 ; // Add 'updates' to batch var updates = grabUntilApiLimit ( 'updates' , count , batchMaxCount , state ) ; log [ 'updates: ' ] = updates ; count = count + updates . length ; // Add to batch updates . forEach ( function ( item ) { var id = item . id ; var docRef = ( collectionMode ) ? dbRef . doc ( id ) : dbRef ; if ( state . _conf . sync . guard . includes ( 'id' ) ) delete item . id ; // @ts-ignore batch . update ( docRef , item ) ; } ) ; // Add 'propDeletions' to batch var propDeletions = grabUntilApiLimit ( 'propDeletions' , count , batchMaxCount , state ) ; log [ 'prop deletions: ' ] = propDeletions ; count = count + propDeletions . length ; // Add to batch propDeletions . forEach ( function ( item ) { var id = item . id ; var docRef = ( collectionMode ) ? dbRef . doc ( id ) : dbRef ; if ( state . _conf . sync . guard . includes ( 'id' ) ) delete item . id ; // @ts-ignore batch . update ( docRef , item ) ; } ) ; // Add 'deletions' to batch var deletions = grabUntilApiLimit ( 'deletions' , count , batchMaxCount , state ) ; log [ 'deletions: ' ] = deletions ; count = count + deletions . length ; // Add to batch deletions . forEach ( function ( id ) { var docRef = dbRef . doc ( id ) ; batch . delete ( docRef ) ; } ) ; // Add 'inserts' to batch var inserts = grabUntilApiLimit ( 'inserts' , count , batchMaxCount , state ) ; log [ 'inserts: ' ] = inserts ; count = count + inserts . length ; // Add to batch inserts . forEach ( function ( item ) { var newRef = dbRef . doc ( item . id ) ; batch . set ( newRef , item ) ; } ) ; // log the batch contents if ( state . _conf . logging ) { console . group ( '[vuex-easy-firestore] api call batch:' ) ; console . log ( "%cFirestore PATH: " + firestorePathComplete + " [" + firestorePath + "]" , 'color: grey' ) ; Object . keys ( log ) . forEach ( function ( key ) { console . log ( key , log [ key ] ) ; } ) ; console . groupEnd ( ) ; } return batch ; }


Input: Get the matches of path variables : eg . return [ groupId ] if pathPiece is { groupId } [CODESPLIT] function getPathVarMatches ( pathPiece ) { var matches = pathPiece . match ( / \{([a-z]+)\} / gi ) ; if ( ! matches ) return [ ] ; return matches . map ( function ( key ) { return trimAccolades ( key ) ; } ) ; }


Input: Gets an object with { where orderBy } filters and returns a unique identifier for that [CODESPLIT] function createFetchIdentifier ( whereOrderBy ) { if ( whereOrderBy === void 0 ) { whereOrderBy = { } ; } var identifier = '' ; if ( 'where' in whereOrderBy ) { identifier += '[where]' + whereOrderBy . where . map ( function ( where ) { return stringifyParams ( where ) ; } ) . join ( ) ; } if ( 'orderBy' in whereOrderBy ) { identifier += '[orderBy]' + stringifyParams ( whereOrderBy . orderBy ) ; } if ( 'pathVariables' in whereOrderBy ) { delete whereOrderBy . pathVariables . where ; delete whereOrderBy . pathVariables . orderBy ; identifier += '[pathVariables]' + JSON . stringify ( whereOrderBy . pathVariables ) ; } return identifier ; }


Input: Returns a value of a payload piece . Eg . { [ id ] : val } will return val [CODESPLIT] function getValueFromPayloadPiece ( payloadPiece ) { if ( isPlainObject ( payloadPiece ) && ! payloadPiece . id && Object . keys ( payloadPiece ) . length === 1 && isPlainObject ( payloadPiece [ Object . keys ( payloadPiece ) [ 0 ] ] ) ) { return Object . values ( payloadPiece ) [ 0 ] ; } return payloadPiece ; }


Input: define storeUpdateFn () [CODESPLIT] function storeUpdateFn ( _doc ) { switch ( change ) { case 'added' : commit ( 'INSERT_DOC' , _doc ) ; break ; case 'removed' : commit ( 'DELETE_DOC' , id ) ; break ; default : dispatch ( 'deleteMissingProps' , _doc ) ; commit ( 'PATCH_DOC' , _doc ) ; break ; } }


Input: define the store update [CODESPLIT] function storeUpdateFn ( _val ) { commit ( 'PATCH_DOC' , _val ) ; return dispatch ( 'patchDoc' , { id : id , doc : copy ( _val ) } ) ; }


Input: define the store update [CODESPLIT] function storeUpdateFn ( _doc , _ids ) { _ids . forEach ( function ( _id ) { commit ( 'PATCH_DOC' , __assign ( { id : _id } , _doc ) ) ; } ) ; return dispatch ( 'patchDoc' , { ids : _ids , doc : _doc } ) ; }


Input: define the store update [CODESPLIT] function storeUpdateFn ( _ids ) { _ids . forEach ( function ( _id ) { // id is a path var pathDelete = ( _id . includes ( '.' ) || ! getters . collectionMode ) ; if ( pathDelete ) { var path = _id ; if ( ! path ) return error ( 'delete-missing-path' ) ; commit ( 'DELETE_PROP' , path ) ; return dispatch ( 'deleteProp' , path ) ; } if ( ! _id ) return error ( 'delete-missing-id' ) ; commit ( 'DELETE_DOC' , _id ) ; return dispatch ( 'deleteDoc' , _id ) ; } ) ; }


Input: Check the config for type errors for non - TypeScript users [CODESPLIT] function errorCheck ( config ) { var errors = [ ] ; var reqProps = [ 'firestorePath' , 'moduleName' ] ; reqProps . forEach ( function ( prop ) { if ( ! config [ prop ] ) { errors . push ( "Missing `" + prop + "` in your module!" ) ; } } ) ; if ( / (\.|\/) / . test ( config . statePropName ) ) { errors . push ( "statePropName must only include letters from [a-z]" ) ; } if ( / \. / . test ( config . moduleName ) ) { errors . push ( "moduleName must only include letters from [a-z] and forward slashes '/'" ) ; } var syncProps = [ 'where' , 'orderBy' , 'fillables' , 'guard' , 'defaultValues' , 'insertHook' , 'patchHook' , 'deleteHook' , 'insertBatchHook' , 'patchBatchHook' , 'deleteBatchHook' ] ; syncProps . forEach ( function ( prop ) { if ( config [ prop ] ) { errors . push ( "We found `" + prop + "` on your module, are you sure this shouldn't be inside a prop called `sync`?" ) ; } } ) ; var serverChangeProps = [ 'modifiedHook' , 'defaultValues' , 'addedHook' , 'removedHook' ] ; serverChangeProps . forEach ( function ( prop ) { if ( config [ prop ] ) { errors . push ( "We found `" + prop + "` on your module, are you sure this shouldn't be inside a prop called `serverChange`?" ) ; } } ) ; var fetchProps = [ 'docLimit' ] ; fetchProps . forEach ( function ( prop ) { if ( config [ prop ] ) { errors . push ( "We found `" + prop + "` on your module, are you sure this shouldn't be inside a prop called `fetch`?" ) ; } } ) ; var numberProps = [ 'docLimit' ] ; numberProps . forEach ( function ( prop ) { var _prop = config . fetch [ prop ] ; if ( ! isNumber ( _prop ) ) errors . push ( "`" + prop + "` should be a Number, but is not." ) ; } ) ; var functionProps = [ 'insertHook' , 'patchHook' , 'deleteHook' , 'insertBatchHook' , 'patchBatchHook' , 'deleteBatchHook' , 'addedHook' , 'modifiedHook' , 'removedHook' ] ; functionProps . forEach ( function ( prop ) { var _prop = ( syncProps . includes ( prop ) ) ? config . sync [ prop ] : config . serverChange [ prop ] ; if ( ! isFunction ( _prop ) ) errors . push ( "`" + prop + "` should be a Function, but is not." ) ; } ) ; var objectProps = [ 'sync' , 'serverChange' , 'defaultValues' , 'fetch' ] ; objectProps . forEach ( function ( prop ) { var _prop = ( prop === 'defaultValues' ) ? config . sync [ prop ] : config [ prop ] ; if ( ! isPlainObject ( _prop ) ) errors . push ( "`" + prop + "` should be an Object, but is not." ) ; } ) ; var stringProps = [ 'firestorePath' , 'firestoreRefType' , 'moduleName' , 'statePropName' ] ; stringProps . forEach ( function ( prop ) { var _prop = config [ prop ] ; if ( ! isString ( _prop ) ) errors . push ( "`" + prop + "` should be a String, but is not." ) ; } ) ; var arrayProps = [ 'where' , 'orderBy' , 'fillables' , 'guard' ] ; arrayProps . forEach ( function ( prop ) { var _prop = config . sync [ prop ] ; if ( ! isArray ( _prop ) ) errors . push ( "`" + prop + "` should be an Array, but is not." ) ; } ) ; if ( errors . length ) { console . group ( '[vuex-easy-firestore] ERRORS:' ) ; console . error ( "Module: " + config . moduleName ) ; errors . forEach ( function ( e ) { return console . error ( ' - ' , e ) ; } ) ; console . groupEnd ( ) ; return false ; } return true ; }


Input: A function that returns a vuex module object with seamless 2 - way sync for firestore . [CODESPLIT] function iniModule ( userConfig , FirebaseDependency ) { // prepare state._conf var conf = copy ( merge ( { state : { } , mutations : { } , actions : { } , getters : { } } , defaultConfig , userConfig ) ) ; if ( ! errorCheck ( conf ) ) return ; var userState = conf . state ; var userMutations = conf . mutations ; var userActions = conf . actions ; var userGetters = conf . getters ; delete conf . state ; delete conf . mutations ; delete conf . actions ; delete conf . getters ; // prepare rest of state var docContainer = { } ; if ( conf . statePropName ) docContainer [ conf . statePropName ] = { } ; var restOfState = merge ( userState , docContainer ) ; // if 'doc' mode, set merge initial state onto default values if ( conf . firestoreRefType === 'doc' ) { var defaultValsInState = ( conf . statePropName ) ? restOfState [ conf . statePropName ] : restOfState ; conf . sync . defaultValues = copy ( merge ( defaultValsInState , conf . sync . defaultValues ) ) ; } return { namespaced : true , state : merge ( pluginState ( ) , restOfState , { _conf : conf } ) , mutations : merge ( userMutations , pluginMutations ( merge ( userState , { _conf : conf } ) ) ) , actions : merge ( userActions , pluginActions ( FirebaseDependency ) ) , getters : merge ( userGetters , pluginGetters ( FirebaseDependency ) ) } ; }


Input: ------------------------------------------------------------------------------------------ Builds ------------------------------------------------------------------------------------------ [CODESPLIT] function defaults ( config ) { // defaults const defaults = { plugins , external } // defaults.output config . output = config . output . map ( output => { return Object . assign ( { sourcemap : false , name : className , } , output ) } ) return Object . assign ( defaults , config ) }


Input: a function returning the mutations object [CODESPLIT] function pluginMutations ( userState ) { return { SET_PATHVARS : function ( state , pathVars ) { var self = this ; Object . keys ( pathVars ) . forEach ( function ( key ) { var pathPiece = pathVars [ key ] ; self . _vm . $set ( state . _sync . pathVariables , key , pathPiece ) ; } ) ; } , SET_SYNCFILTERS : function ( state , _a ) { var where = _a . where , orderBy = _a . orderBy ; if ( where && isWhat . isArray ( where ) ) state . _conf . sync . where = where ; if ( orderBy && isWhat . isArray ( orderBy ) ) state . _conf . sync . orderBy = orderBy ; } , SET_USER_ID : function ( state , userId ) { if ( ! userId ) { state . _sync . signedIn = false ; state . _sync . userId = null ; } else { state . _sync . signedIn = true ; state . _sync . userId = userId ; } } , CLEAR_USER : function ( state ) { state . _sync . signedIn = false ; state . _sync . userId = null ; } , RESET_VUEX_EASY_FIRESTORE_STATE : function ( state ) { // unsubscribe all DBChannel listeners: Object . keys ( state . _sync . unsubscribe ) . forEach ( function ( unsubscribe ) { if ( isWhat . isFunction ( unsubscribe ) ) unsubscribe ( ) ; } ) ; var self = this ; var _sync = merge ( state . _sync , { // make null once to be able to overwrite with empty object unsubscribe : null , pathVariables : null , syncStack : { updates : null , propDeletions : null } , fetched : null , } , { unsubscribe : { } , pathVariables : { } , patching : false , syncStack : { inserts : [ ] , updates : { } , propDeletions : { } , deletions : [ ] , debounceTimer : null , } , fetched : { } , stopPatchingTimeout : null } ) ; var newState = merge ( userState , { _sync : _sync } ) ; var docContainer = ( state . _conf . statePropName ) ? state [ state . _conf . statePropName ] : state ; Object . keys ( newState ) . forEach ( function ( key ) { self . _vm . $set ( state , key , newState [ key ] ) ; } ) ; Object . keys ( docContainer ) . forEach ( function ( key ) { if ( Object . keys ( newState ) . includes ( key ) ) return ; self . _vm . $delete ( docContainer , key ) ; } ) ; } , resetSyncStack : function ( state ) { state . _sync . syncStack = { updates : { } , deletions : [ ] , inserts : [ ] , debounceTimer : null } ; } , INSERT_DOC : function ( state , doc ) { if ( state . _conf . firestoreRefType . toLowerCase ( ) !== 'collection' ) return ; if ( state . _conf . statePropName ) { this . _vm . $set ( state [ state . _conf . statePropName ] , doc . id , doc ) ; } else { this . _vm . $set ( state , doc . id , doc ) ; } } , PATCH_DOC : function ( state , patches ) { var _this = this ; // Get the state prop ref var ref = ( state . _conf . statePropName ) ? state [ state . _conf . statePropName ] : state ; if ( state . _conf . firestoreRefType . toLowerCase ( ) === 'collection' ) { ref = ref [ patches . id ] ; } if ( ! ref ) return error ( 'patch-no-ref' ) ; return Object . keys ( patches ) . forEach ( function ( key ) { var newVal = patches [ key ] ; // Merge if exists function helpers ( originVal , newVal ) { if ( isWhat . isArray ( originVal ) && isArrayHelper ( newVal ) ) { newVal = newVal . executeOn ( originVal ) ; } if ( isWhat . isNumber ( originVal ) && isIncrementHelper ( newVal ) ) { newVal = newVal . executeOn ( originVal ) ; } return newVal ; // always return newVal as fallback!! } newVal = merge ( { extensions : [ helpers ] } , ref [ key ] , patches [ key ] ) ; _this . _vm . $set ( ref , key , newVal ) ; } ) ; } , DELETE_DOC : function ( state , id ) { if ( state . _conf . firestoreRefType . toLowerCase ( ) !== 'collection' ) return ; if ( state . _conf . statePropName ) { this . _vm . $delete ( state [ state . _conf . statePropName ] , id ) ; } else { this . _vm . $delete ( state , id ) ; } } , DELETE_PROP : function ( state , path ) { var searchTarget = ( state . _conf . statePropName ) ? state [ state . _conf . statePropName ] : state ; var propArr = path . split ( '.' ) ; var target = propArr . pop ( ) ; if ( ! propArr . length ) { return this . _vm . $delete ( searchTarget , target ) ; } var ref = vuexEasyAccess . getDeepRef ( searchTarget , propArr . join ( '.' ) ) ; return this . _vm . $delete ( ref , target ) ; } } ; }


Input: convert to new Date () if defaultValue == %convertTimestamp% [CODESPLIT] function convertTimestamps ( originVal , targetVal ) { if ( originVal === '%convertTimestamp%' ) { // firestore timestamps // @ts-ignore if ( isWhat . isAnyObject ( targetVal ) && ! isWhat . isPlainObject ( targetVal ) && isWhat . isFunction ( targetVal . toDate ) ) { // @ts-ignore return targetVal . toDate ( ) ; } // strings if ( isWhat . isString ( targetVal ) && isWhat . isDate ( new Date ( targetVal ) ) ) { return new Date ( targetVal ) ; } } return targetVal ; }


Input: Merge an object onto defaultValues [CODESPLIT] function setDefaultValues ( obj , defaultValues ) { if ( ! isWhat . isPlainObject ( defaultValues ) ) console . error ( '[vuex-easy-firestore] Trying to merge target:' , obj , 'onto a non-object (defaultValues):' , defaultValues ) ; if ( ! isWhat . isPlainObject ( obj ) ) console . error ( '[vuex-easy-firestore] Trying to merge a non-object:' , obj , 'onto the defaultValues:' , defaultValues ) ; var result = merge ( { extensions : [ convertTimestamps ] } , defaultValues , obj ) ; return findAndReplaceAnything . findAndReplace ( result , '%convertTimestamp%' , null , { onlyPlainObjects : true } ) ; }


Input: gets an ID from a single piece of payload . [CODESPLIT] function getId ( payloadPiece , conf , path , fullPayload ) { if ( isWhat . isString ( payloadPiece ) ) return payloadPiece ; if ( isWhat . isPlainObject ( payloadPiece ) ) { if ( 'id' in payloadPiece ) return payloadPiece . id ; var keys = Object . keys ( payloadPiece ) ; if ( keys . length === 1 ) return keys [ 0 ] ; } return '' ; }


Input: A function returning the actions object [CODESPLIT] function pluginActions ( Firebase ) { var _this = this ; return { setUserId : function ( _a , userId ) { var commit = _a . commit , getters = _a . getters ; if ( userId === undefined ) userId = null ; // undefined cannot be synced to firestore if ( ! userId && Firebase . auth ( ) . currentUser ) { userId = Firebase . auth ( ) . currentUser . uid ; } commit ( 'SET_USER_ID' , userId ) ; if ( getters . firestorePathComplete . includes ( '{userId}' ) ) return error ( 'user-auth' ) ; } , clearUser : function ( _a ) { var commit = _a . commit ; commit ( 'CLEAR_USER' ) ; } , setPathVars : function ( _a , pathVars ) { var commit = _a . commit ; commit ( 'SET_PATHVARS' , pathVars ) ; } , duplicate : function ( _a , id ) { var state = _a . state , getters = _a . getters , commit = _a . commit , dispatch = _a . dispatch ; return __awaiter ( _this , void 0 , void 0 , function ( ) { var _b , doc , dId , idMap ; return __generator ( this , function ( _c ) { switch ( _c . label ) { case 0 : if ( ! getters . collectionMode ) return [ 2 /*return*/ , error ( 'only-in-collection-mode' ) ] ; if ( ! id ) return [ 2 /*return*/ , { } ] ; doc = merge ( getters . storeRef [ id ] , { id : null } ) ; return [ 4 /*yield*/ , dispatch ( 'insert' , doc ) ] ; case 1 : dId = _c . sent ( ) ; idMap = ( _b = { } , _b [ id ] = dId , _b ) ; return [ 2 /*return*/ , idMap ] ; } } ) ; } ) ; } , duplicateBatch : function ( _a , ids ) { var _this = this ; var state = _a . state , getters = _a . getters , commit = _a . commit , dispatch = _a . dispatch ; if ( ids === void 0 ) { ids = [ ] ; } if ( ! getters . collectionMode ) return error ( 'only-in-collection-mode' ) ; if ( ! isWhat . isArray ( ids ) || ! ids . length ) return { } ; var idsMap = ids . reduce ( function ( carry , id ) { return __awaiter ( _this , void 0 , void 0 , function ( ) { var idMap ; return __generator ( this , function ( _a ) { switch ( _a . label ) { case 0 : return [ 4 /*yield*/ , dispatch ( 'duplicate' , id ) ] ; case 1 : idMap = _a . sent ( ) ; return [ 4 /*yield*/ , carry ] ; case 2 : carry = _a . sent ( ) ; return [ 2 /*return*/ , Object . assign ( carry , idMap ) ] ; } } ) ; } ) ; } , { } ) ; return idsMap ; } , patchDoc : function ( _a , _b ) { var state = _a . state , getters = _a . getters , commit = _a . commit , dispatch = _a . dispatch ; var _c = _b === void 0 ? { ids : [ ] , doc : { } } : _b , _d = _c . id , id = _d === void 0 ? '' : _d , _e = _c . ids , ids = _e === void 0 ? [ ] : _e , doc = _c . doc ; // 0. payload correction (only arrays) if ( ! isWhat . isArray ( ids ) ) return error ( "`ids` prop passed to 'patch' needs to be an array" ) ; if ( id ) ids . push ( id ) ; // EXTRA: check if doc is being inserted if so state . _sync . syncStack . inserts . forEach ( function ( newDoc , newDocIndex ) { // get the index of the id that is also in the insert stack var indexIdInInsert = ids . indexOf ( newDoc . id ) ; if ( indexIdInInsert === - 1 ) return ; // the doc trying to be synced is also in insert // prepare the doc as new doc: var patchDoc = getters . prepareForInsert ( [ doc ] ) [ 0 ] ; // replace insert sync stack with merged item: state . _sync . syncStack . inserts [ newDocIndex ] = merge ( newDoc , patchDoc ) ; // empty out the id that was to be patched: ids . splice ( indexIdInInsert , 1 ) ; } ) ; // 1. Prepare for patching var syncStackItems = getters . prepareForPatch ( ids , doc ) ; // 2. Push to syncStack Object . keys ( syncStackItems ) . forEach ( function ( id ) { var newVal ; if ( ! state . _sync . syncStack . updates [ id ] ) { // replace arrayUnion and arrayRemove newVal = findAndReplaceAnything . findAndReplaceIf ( syncStackItems [ id ] , function ( foundVal ) { if ( isArrayHelper ( foundVal ) ) { return foundVal . getFirestoreFieldValue ( ) ; } if ( isIncrementHelper ( foundVal ) ) { return foundVal . getFirestoreFieldValue ( ) ; } return foundVal ; } ) ; } else { newVal = merge ( { extensions : [ function ( originVal , newVal ) { if ( originVal instanceof Firebase . firestore . FieldValue && isArrayHelper ( newVal ) ) { originVal . _elements = originVal . _elements . concat ( newVal . payload ) ; newVal = originVal ; } if ( originVal instanceof Firebase . firestore . FieldValue && isIncrementHelper ( newVal ) ) { originVal . _operand = originVal . _operand + newVal . payload ; newVal = originVal ; } return newVal ; // always return newVal as fallback!! } ] } , state . _sync . syncStack . updates [ id ] , syncStackItems [ id ] ) ; } state . _sync . syncStack . updates [ id ] = newVal ; } ) ; // 3. Create or refresh debounce return dispatch ( 'handleSyncStackDebounce' ) ; } , deleteDoc : function ( _a , ids ) { var state = _a . state , getters = _a . getters , commit = _a . commit , dispatch = _a . dispatch ; if ( ids === void 0 ) { ids = [ ] ; } // 0. payload correction (only arrays) if ( ! isWhat . isArray ( ids ) ) ids = [ ids ] ; // 1. Prepare for patching // 2. Push to syncStack var deletions = state . _sync . syncStack . deletions . concat ( ids ) ; state . _sync . syncStack . deletions = deletions ; if ( ! state . _sync . syncStack . deletions . length ) return ; // 3. Create or refresh debounce return dispatch ( 'handleSyncStackDebounce' ) ; } , deleteProp : function ( _a , path ) { var state = _a . state , getters = _a . getters , commit = _a . commit , dispatch = _a . dispatch ; // 1. Prepare for patching var syncStackItem = getters . prepareForPropDeletion ( path ) ; // 2. Push to syncStack Object . keys ( syncStackItem ) . forEach ( function ( id ) { var newVal = ( ! state . _sync . syncStack . propDeletions [ id ] ) ? syncStackItem [ id ] : merge ( state . _sync . syncStack . propDeletions [ id ] , syncStackItem [ id ] ) ; state . _sync . syncStack . propDeletions [ id ] = newVal ; } ) ; // 3. Create or refresh debounce return dispatch ( 'handleSyncStackDebounce' ) ; } , insertDoc : function ( _a , docs ) { var state = _a . state , getters = _a . getters , commit = _a . commit , dispatch = _a . dispatch ; if ( docs === void 0 ) { docs = [ ] ; } // 0. payload correction (only arrays) if ( ! isWhat . isArray ( docs ) ) docs = [ docs ] ; // 1. Prepare for patching var syncStack = getters . prepareForInsert ( docs ) ; // 2. Push to syncStack var inserts = state . _sync . syncStack . inserts . concat ( syncStack ) ; state . _sync . syncStack . inserts = inserts ; // 3. Create or refresh debounce dispatch ( 'handleSyncStackDebounce' ) ; return docs . map ( function ( d ) { return d . id ; } ) ; } , insertInitialDoc : function ( _a ) { var state = _a . state , getters = _a . getters , commit = _a . commit , dispatch = _a . dispatch ; // 0. only docMode if ( getters . collectionMode ) return ; // 1. Prepare for insert var initialDoc = ( getters . storeRef ) ? getters . storeRef : { } ; var initialDocPrepared = getters . prepareInitialDocForInsert ( initialDoc ) ; // 2. Create a reference to the SF doc. var initialDocRef = getters . dbRef ; return Firebase . firestore ( ) . runTransaction ( function ( transaction ) { // This code may get re-run multiple times if there are conflicts. return transaction . get ( initialDocRef ) . then ( function ( foundInitialDoc ) { if ( ! foundInitialDoc . exists ) { transaction . set ( initialDocRef , initialDocPrepared ) ; } } ) ; } ) . then ( function ( _ ) { if ( state . _conf . logging ) { console . log ( '[vuex-easy-firestore] Initial doc succesfully inserted.' ) ; } } ) . catch ( function ( error$1 ) { return error ( 'initial-doc-failed' , error$1 ) ; } ) ; } , handleSyncStackDebounce : function ( _a ) { var state = _a . state , commit = _a . commit , dispatch = _a . dispatch , getters = _a . getters ; if ( ! getters . signedIn ) return false ; if ( ! state . _sync . syncStack . debounceTimer ) { var ms = state . _conf . sync . debounceTimerMs ; var debounceTimer = startDebounce ( ms ) ; debounceTimer . done . then ( function ( _ ) { return dispatch ( 'batchSync' ) ; } ) ; state . _sync . syncStack . debounceTimer = debounceTimer ; } state . _sync . syncStack . debounceTimer . refresh ( ) ; } , batchSync : function ( _a ) { var getters = _a . getters , commit = _a . commit , dispatch = _a . dispatch , state = _a . state ; var batch = makeBatchFromSyncstack ( state , getters , Firebase ) ; dispatch ( '_startPatching' ) ; state . _sync . syncStack . debounceTimer = null ; return new Promise ( function ( resolve , reject ) { batch . commit ( ) . then ( function ( _ ) { var remainingSyncStack = Object . keys ( state . _sync . syncStack . updates ) . length + state . _sync . syncStack . deletions . length + state . _sync . syncStack . inserts . length + state . _sync . syncStack . propDeletions . length ; if ( remainingSyncStack ) { dispatch ( 'batchSync' ) ; } dispatch ( '_stopPatching' ) ; return resolve ( ) ; } ) . catch ( function ( error$1 ) { state . _sync . patching = 'error' ; state . _sync . syncStack . debounceTimer = null ; return reject ( error$1 ) ; } ) ; } ) ; } , fetch : function ( _a , pathVariables // where: [['archived', '==', true]] // orderBy: ['done_date', 'desc'] ) { var state = _a . state , getters = _a . getters , commit = _a . commit , dispatch = _a . dispatch ; if ( pathVariables === void 0 ) { pathVariables = { where : [ ] , whereFilters : [ ] , orderBy : [ ] } ; } dispatch ( 'setUserId' ) ; var where = pathVariables . where , whereFilters = pathVariables . whereFilters , orderBy = pathVariables . orderBy ; if ( ! isWhat . isArray ( where ) ) where = [ ] ; if ( ! isWhat . isArray ( orderBy ) ) orderBy = [ ] ; if ( isWhat . isArray ( whereFilters ) && whereFilters . length ) where = whereFilters ; // depreciated if ( pathVariables && isWhat . isPlainObject ( pathVariables ) ) { commit ( 'SET_PATHVARS' , pathVariables ) ; } return new Promise ( function ( resolve , reject ) { // log if ( state . _conf . logging ) { console . log ( "%c fetch for Firestore PATH: " + getters . firestorePathComplete + " [" + state . _conf . firestorePath + "]" , 'color: lightcoral' ) ; } if ( ! getters . signedIn ) return resolve ( ) ; var identifier = createFetchIdentifier ( { where : where , orderBy : orderBy } ) ; var fetched = state . _sync . fetched [ identifier ] ; // We've never fetched this before: if ( ! fetched ) { var ref_1 = getters . dbRef ; // apply where filters and orderBy getters . getWhereArrays ( where ) . forEach ( function ( paramsArr ) { ref_1 = ref_1 . where . apply ( ref_1 , paramsArr ) ; } ) ; if ( orderBy . length ) ref_1 = ref_1 . orderBy . apply ( ref_1 , orderBy ) ; state . _sync . fetched [ identifier ] = { ref : ref_1 , done : false , retrievedFetchRefs : [ ] , nextFetchRef : null } ; } var fRequest = state . _sync . fetched [ identifier ] ; // We're already done fetching everything: if ( fRequest . done ) { if ( state . _conf . logging ) console . log ( '[vuex-easy-firestore] done fetching' ) ; return resolve ( { done : true } ) ; } // attach fetch filters var fRef = state . _sync . fetched [ identifier ] . ref ; if ( fRequest . nextFetchRef ) { // get next ref if saved in state fRef = state . _sync . fetched [ identifier ] . nextFetchRef ; } // add doc limit var limit = ( isWhat . isNumber ( pathVariables . limit ) ) ? pathVariables . limit : state . _conf . fetch . docLimit ; if ( limit > 0 ) fRef = fRef . limit ( limit ) ; // Stop if all records already fetched if ( fRequest . retrievedFetchRefs . includes ( fRef ) ) { console . log ( '[vuex-easy-firestore] Already retrieved this part.' ) ; return resolve ( ) ; } // make fetch request fRef . get ( ) . then ( function ( querySnapshot ) { var docs = querySnapshot . docs ; if ( docs . length === 0 ) { state . _sync . fetched [ identifier ] . done = true ; querySnapshot . done = true ; return resolve ( querySnapshot ) ; } if ( docs . length < limit ) { state . _sync . fetched [ identifier ] . done = true ; } state . _sync . fetched [ identifier ] . retrievedFetchRefs . push ( fRef ) ; // Get the last visible document resolve ( querySnapshot ) ; var lastVisible = docs [ docs . length - 1 ] ; // set the reference for the next records. var next = fRef . startAfter ( lastVisible ) ; state . _sync . fetched [ identifier ] . nextFetchRef = next ; } ) . catch ( function ( error$1 ) { return reject ( error ( error$1 ) ) ; } ) ; } ) ; } , fetchAndAdd : function ( _a , pathVariables // where: [['archived', '==', true]] // orderBy: ['done_date', 'desc'] ) { var _this = this ; var state = _a . state , getters = _a . getters , commit = _a . commit , dispatch = _a . dispatch ; if ( pathVariables === void 0 ) { pathVariables = { where : [ ] , whereFilters : [ ] , orderBy : [ ] } ; } if ( pathVariables && isWhat . isPlainObject ( pathVariables ) ) { commit ( 'SET_PATHVARS' , pathVariables ) ; } // 'doc' mode: if ( ! getters . collectionMode ) { dispatch ( 'setUserId' ) ; if ( state . _conf . logging ) { console . log ( "%c fetch for Firestore PATH: " + getters . firestorePathComplete + " [" + state . _conf . firestorePath + "]" , 'color: lightcoral' ) ; } return getters . dbRef . get ( ) . then ( function ( _doc ) { return __awaiter ( _this , void 0 , void 0 , function ( ) { var id , doc ; return __generator ( this , function ( _a ) { switch ( _a . label ) { case 0 : if ( ! ! _doc . exists ) return [ 3 /*break*/ , 2 ] ; // No initial doc found in docMode if ( state . _conf . sync . preventInitialDocInsertion ) throw 'preventInitialDocInsertion' ; if ( state . _conf . logging ) console . log ( '[vuex-easy-firestore] inserting initial doc' ) ; return [ 4 /*yield*/ , dispatch ( 'insertInitialDoc' ) ] ; case 1 : _a . sent ( ) ; return [ 2 /*return*/ , _doc ] ; case 2 : id = getters . docModeId ; doc = getters . cleanUpRetrievedDoc ( _doc . data ( ) , id ) ; dispatch ( 'applyHooksAndUpdateState' , { change : 'modified' , id : id , doc : doc } ) ; return [ 2 /*return*/ , doc ] ; } } ) ; } ) ; } ) . catch ( function ( error$1 ) { return error ( error$1 ) ; } ) ; } // 'collection' mode: return dispatch ( 'fetch' , pathVariables ) . then ( function ( querySnapshot ) { if ( querySnapshot . done === true ) return querySnapshot ; if ( isWhat . isFunction ( querySnapshot . forEach ) ) { querySnapshot . forEach ( function ( _doc ) { var id = _doc . id ; var doc = getters . cleanUpRetrievedDoc ( _doc . data ( ) , id ) ; dispatch ( 'applyHooksAndUpdateState' , { change : 'added' , id : id , doc : doc } ) ; } ) ; } return querySnapshot ; } ) ; } , fetchById : function ( _a , id ) { var dispatch = _a . dispatch , getters = _a . getters , state = _a . state ; return __awaiter ( this , void 0 , void 0 , function ( ) { var ref , _doc , doc , e_1 ; return __generator ( this , function ( _b ) { switch ( _b . label ) { case 0 : _b . trys . push ( [ 0 , 2 , , 3 ] ) ; if ( ! id ) throw 'missing-id' ; if ( ! getters . collectionMode ) throw 'only-in-collection-mode' ; ref = getters . dbRef ; return [ 4 /*yield*/ , ref . doc ( id ) . get ( ) ] ; case 1 : _doc = _b . sent ( ) ; if ( ! _doc . exists ) { if ( state . _conf . logging ) { throw "Doc with id \"" + id + "\" not found!" ; } } doc = getters . cleanUpRetrievedDoc ( _doc . data ( ) , id ) ; dispatch ( 'applyHooksAndUpdateState' , { change : 'added' , id : id , doc : doc } ) ; return [ 2 /*return*/ , doc ] ; case 2 : e_1 = _b . sent ( ) ; return [ 2 /*return*/ , error ( e_1 ) ] ; case 3 : return [ 2 /*return*/ ] ; } } ) ; } ) ; } , applyHooksAndUpdateState : function ( // this is only on server retrievals _a , _b ) { var getters = _a . getters , state = _a . state , commit = _a . commit , dispatch = _a . dispatch ; var change = _b . change , id = _b . id , _c = _b . doc , doc = _c === void 0 ? { } : _c ; var store = this ; // define storeUpdateFn() function storeUpdateFn ( _doc ) { switch ( change ) { case 'added' : commit ( 'INSERT_DOC' , _doc ) ; break ; case 'removed' : commit ( 'DELETE_DOC' , id ) ; break ; default : dispatch ( 'deleteMissingProps' , _doc ) ; commit ( 'PATCH_DOC' , _doc ) ; break ; } } // get user set sync hook function var syncHookFn = state . _conf . serverChange [ change + 'Hook' ] ; if ( isWhat . isFunction ( syncHookFn ) ) { syncHookFn ( storeUpdateFn , doc , id , store , 'server' , change ) ; } else { storeUpdateFn ( doc ) ; } } , deleteMissingProps : function ( _a , doc ) { var getters = _a . getters , commit = _a . commit ; var defaultValues = getters . defaultValues ; var searchTarget = ( getters . collectionMode ) ? getters . storeRef [ doc . id ] : getters . storeRef ; var compareInfo = compareAnything . compareObjectProps ( flatten ( doc ) , // presentIn 0 flatten ( defaultValues ) , // presentIn 1 flatten ( searchTarget ) // presentIn 2 ) ; Object . keys ( compareInfo . presentIn ) . forEach ( function ( prop ) { // don't worry about props not in fillables if ( getters . fillables . length && ! getters . fillables . includes ( prop ) ) { return ; } // don't worry about props in guard if ( getters . guard . includes ( prop ) ) return ; // don't worry about props starting with _sync or _conf if ( prop . split ( '.' ) [ 0 ] === '_sync' || prop . split ( '.' ) [ 0 ] === '_conf' ) return ; // where is the prop present? var presence = compareInfo . presentIn [ prop ] ; var propNotInDoc = ( ! presence . includes ( 0 ) ) ; var propNotInDefaultValues = ( ! presence . includes ( 1 ) ) ; // delete props that are not present in the doc and default values if ( propNotInDoc && propNotInDefaultValues ) { var path = ( getters . collectionMode ) ? doc . id + "." + prop : prop ; return commit ( 'DELETE_PROP' , path ) ; } } ) ; } , openDBChannel : function ( _a , pathVariables ) { var _this = this ; var getters = _a . getters , state = _a . state , commit = _a . commit , dispatch = _a . dispatch ; dispatch ( 'setUserId' ) ; // `first` makes sure that local changes made during offline are reflected as server changes which the app is refreshed during offline mode var first = true ; // set state for pathVariables if ( pathVariables && isWhat . isPlainObject ( pathVariables ) ) { commit ( 'SET_SYNCFILTERS' , pathVariables ) ; delete pathVariables . where ; delete pathVariables . orderBy ; commit ( 'SET_PATHVARS' , pathVariables ) ; } var identifier = createFetchIdentifier ( { where : state . _conf . sync . where , orderBy : state . _conf . sync . orderBy , pathVariables : state . _sync . pathVariables } ) ; if ( isWhat . isFunction ( state . _sync . unsubscribe [ identifier ] ) ) { var channelAlreadyOpenError_1 = "openDBChannel was already called for these filters and pathvariables. Identifier: " + identifier ; if ( state . _conf . logging ) { console . log ( channelAlreadyOpenError_1 ) ; } return new Promise ( function ( resolve , reject ) { reject ( channelAlreadyOpenError_1 ) ; } ) ; } // getters.dbRef should already have pathVariables swapped out var dbRef = getters . dbRef ; // apply where filters and orderBy if ( getters . collectionMode ) { getters . getWhereArrays ( ) . forEach ( function ( whereParams ) { dbRef = dbRef . where . apply ( dbRef , whereParams ) ; } ) ; if ( state . _conf . sync . orderBy . length ) { dbRef = dbRef . orderBy . apply ( dbRef , state . _conf . sync . orderBy ) ; } } // make a promise return new Promise ( function ( resolve , reject ) { // log if ( state . _conf . logging ) { console . log ( "%c openDBChannel for Firestore PATH: " + getters . firestorePathComplete + " [" + state . _conf . firestorePath + "]" , 'color: lightcoral' ) ; } var unsubscribe = dbRef . onSnapshot ( function ( querySnapshot ) { return __awaiter ( _this , void 0 , void 0 , function ( ) { var source , id , doc ; return __generator ( this , function ( _a ) { switch ( _a . label ) { case 0 : source = querySnapshot . metadata . hasPendingWrites ? 'local' : 'server' ; if ( ! ! getters . collectionMode ) return [ 3 /*break*/ , 3 ] ; if ( ! ! querySnapshot . data ( ) ) return [ 3 /*break*/ , 2 ] ; // No initial doc found in docMode if ( state . _conf . sync . preventInitialDocInsertion ) return [ 2 /*return*/ , reject ( 'preventInitialDocInsertion' ) ] ; if ( state . _conf . logging ) console . log ( '[vuex-easy-firestore] inserting initial doc' ) ; return [ 4 /*yield*/ , dispatch ( 'insertInitialDoc' ) ] ; case 1 : _a . sent ( ) ; return [ 2 /*return*/ , resolve ( ) ] ; case 2 : if ( source === 'local' && ! first ) return [ 2 /*return*/ , resolve ( ) ] ; id = getters . docModeId ; doc = getters . cleanUpRetrievedDoc ( querySnapshot . data ( ) , id ) ; dispatch ( 'applyHooksAndUpdateState' , { change : 'modified' , id : id , doc : doc } ) ; first = false ; return [ 2 /*return*/ , resolve ( ) ] ; case 3 : // 'collection' mode: querySnapshot . docChanges ( ) . forEach ( function ( change ) { var changeType = change . type ; // Don't do anything for local modifications & removals if ( source === 'local' && ! first ) return resolve ( ) ; var id = change . doc . id ; var doc = getters . cleanUpRetrievedDoc ( change . doc . data ( ) , id ) ; dispatch ( 'applyHooksAndUpdateState' , { change : changeType , id : id , doc : doc } ) ; } ) ; first = false ; return [ 2 /*return*/ , resolve ( ) ] ; } } ) ; } ) ; } , function ( error$1 ) { state . _sync . patching = 'error' ; return reject ( error ( error$1 ) ) ; } ) ; state . _sync . unsubscribe [ identifier ] = unsubscribe ; } ) ; } , closeDBChannel : function ( _a , _b ) { var getters = _a . getters , state = _a . state , commit = _a . commit , dispatch = _a . dispatch ; var _c = ( _b === void 0 ? { clearModule : false } : _b ) . clearModule , clearModule = _c === void 0 ? false : _c ; var identifier = createFetchIdentifier ( { where : state . _conf . sync . where , orderBy : state . _conf . sync . orderBy , pathVariables : state . _sync . pathVariables } ) ; var unsubscribeDBChannel = state . _sync . unsubscribe [ identifier ] ; if ( isWhat . isFunction ( unsubscribeDBChannel ) ) { unsubscribeDBChannel ( ) ; state . _sync . unsubscribe [ identifier ] = null ; } if ( clearModule ) { commit ( 'RESET_VUEX_EASY_FIRESTORE_STATE' ) ; } } , set : function ( _a , doc ) { var commit = _a . commit , dispatch = _a . dispatch , getters = _a . getters , state = _a . state ; if ( ! doc ) return ; if ( ! getters . collectionMode ) { return dispatch ( 'patch' , doc ) ; } var id = getId ( doc ) ; if ( ! id || ( ! state . _conf . statePropName && ! state [ id ] ) || ( state . _conf . statePropName && ! state [ state . _conf . statePropName ] [ id ] ) ) { return dispatch ( 'insert' , doc ) ; } return dispatch ( 'patch' , doc ) ; } , insert : function ( _a , doc ) { var state = _a . state , getters = _a . getters , commit = _a . commit , dispatch = _a . dispatch ; var store = this ; // check payload if ( ! doc ) return ; // check userId dispatch ( 'setUserId' ) ; var newDoc = doc ; if ( ! newDoc . id ) newDoc . id = getters . dbRef . doc ( ) . id ; // apply default values var newDocWithDefaults = setDefaultValues ( newDoc , state . _conf . sync . defaultValues ) ; // define the store update function storeUpdateFn ( _doc ) { commit ( 'INSERT_DOC' , _doc ) ; return dispatch ( 'insertDoc' , _doc ) ; } // check for hooks if ( state . _conf . sync . insertHook ) { state . _conf . sync . insertHook ( storeUpdateFn , newDocWithDefaults , store ) ; return newDocWithDefaults . id ; } storeUpdateFn ( newDocWithDefaults ) ; return newDocWithDefaults . id ; } , insertBatch : function ( _a , docs ) { var state = _a . state , getters = _a . getters , commit = _a . commit , dispatch = _a . dispatch ; var store = this ; // check payload if ( ! isWhat . isArray ( docs ) || ! docs . length ) return [ ] ; // check userId dispatch ( 'setUserId' ) ; var newDocs = docs . reduce ( function ( carry , _doc ) { var newDoc = getValueFromPayloadPiece ( _doc ) ; if ( ! newDoc . id ) newDoc . id = getters . dbRef . doc ( ) . id ; carry . push ( newDoc ) ; return carry ; } , [ ] ) ; // define the store update function storeUpdateFn ( _docs ) { _docs . forEach ( function ( _doc ) { commit ( 'INSERT_DOC' , _doc ) ; } ) ; return dispatch ( 'insertDoc' , _docs ) ; } // check for hooks if ( state . _conf . sync . insertBatchHook ) { state . _conf . sync . insertBatchHook ( storeUpdateFn , newDocs , store ) ; return newDocs . map ( function ( _doc ) { return _doc . id ; } ) ; } storeUpdateFn ( newDocs ) ; return newDocs . map ( function ( _doc ) { return _doc . id ; } ) ; } , patch : function ( _a , doc ) { var state = _a . state , getters = _a . getters , commit = _a . commit , dispatch = _a . dispatch ; var store = this ; // check payload if ( ! doc ) return ; var id = ( getters . collectionMode ) ? getId ( doc ) : getters . docModeId ; var value = ( getters . collectionMode ) ? getValueFromPayloadPiece ( doc ) : doc ; if ( ! id && getters . collectionMode ) return error ( 'patch-missing-id' ) ; // check userId dispatch ( 'setUserId' ) ; // add id to value if ( ! value . id ) value . id = id ; // define the store update function storeUpdateFn ( _val ) { commit ( 'PATCH_DOC' , _val ) ; return dispatch ( 'patchDoc' , { id : id , doc : copy ( _val ) } ) ; } // check for hooks if ( state . _conf . sync . patchHook ) { state . _conf . sync . patchHook ( storeUpdateFn , value , store ) ; return id ; } storeUpdateFn ( value ) ; return id ; } , patchBatch : function ( _a , _b ) { var state = _a . state , getters = _a . getters , commit = _a . commit , dispatch = _a . dispatch ; var doc = _b . doc , _c = _b . ids , ids = _c === void 0 ? [ ] : _c ; var store = this ; // check payload if ( ! doc ) return [ ] ; if ( ! isWhat . isArray ( ids ) || ! ids . length ) return [ ] ; // check userId dispatch ( 'setUserId' ) ; // define the store update function storeUpdateFn ( _doc , _ids ) { _ids . forEach ( function ( _id ) { commit ( 'PATCH_DOC' , __assign ( { id : _id } , _doc ) ) ; } ) ; return dispatch ( 'patchDoc' , { ids : _ids , doc : _doc } ) ; } // check for hooks if ( state . _conf . sync . patchBatchHook ) { state . _conf . sync . patchBatchHook ( storeUpdateFn , doc , ids , store ) ; return ids ; } storeUpdateFn ( doc , ids ) ; return ids ; } , delete : function ( _a , id ) { var state = _a . state , getters = _a . getters , commit = _a . commit , dispatch = _a . dispatch ; var store = this ; // check payload if ( ! id ) return ; // check userId dispatch ( 'setUserId' ) ; function storeUpdateFn ( _id ) { // id is a path var pathDelete = ( _id . includes ( '.' ) || ! getters . collectionMode ) ; if ( pathDelete ) { var path = _id ; if ( ! path ) return error ( 'delete-missing-path' ) ; commit ( 'DELETE_PROP' , path ) ; return dispatch ( 'deleteProp' , path ) ; } if ( ! _id ) return error ( 'delete-missing-id' ) ; commit ( 'DELETE_DOC' , _id ) ; return dispatch ( 'deleteDoc' , _id ) ; } // check for hooks if ( state . _conf . sync . deleteHook ) { state . _conf . sync . deleteHook ( storeUpdateFn , id , store ) ; return id ; } storeUpdateFn ( id ) ; return id ; } , deleteBatch : function ( _a , ids ) { var state = _a . state , getters = _a . getters , commit = _a . commit , dispatch = _a . dispatch ; var store = this ; // check payload if ( ! isWhat . isArray ( ids ) || ! ids . length ) return [ ] ; // check userId dispatch ( 'setUserId' ) ; // define the store update function storeUpdateFn ( _ids ) { _ids . forEach ( function ( _id ) { // id is a path var pathDelete = ( _id . includes ( '.' ) || ! getters . collectionMode ) ; if ( pathDelete ) { var path = _id ; if ( ! path ) return error ( 'delete-missing-path' ) ; commit ( 'DELETE_PROP' , path ) ; return dispatch ( 'deleteProp' , path ) ; } if ( ! _id ) return error ( 'delete-missing-id' ) ; commit ( 'DELETE_DOC' , _id ) ; return dispatch ( 'deleteDoc' , _id ) ; } ) ; } // check for hooks if ( state . _conf . sync . deleteBatchHook ) { state . _conf . sync . deleteBatchHook ( storeUpdateFn , ids , store ) ; return ids ; } storeUpdateFn ( ids ) ; return ids ; } , _stopPatching : function ( _a ) { var state = _a . state , commit = _a . commit ; if ( state . _sync . stopPatchingTimeout ) { clearTimeout ( state . _sync . stopPatchingTimeout ) ; } state . _sync . stopPatchingTimeout = setTimeout ( function ( _ ) { state . _sync . patching = false ; } , 300 ) ; } , _startPatching : function ( _a ) { var state = _a . state , commit = _a . commit ; if ( state . _sync . stopPatchingTimeout ) { clearTimeout ( state . _sync . stopPatchingTimeout ) ; } state . _sync . patching = true ; } } ; }


Input: A function returning the getters object [CODESPLIT] function pluginGetters ( Firebase ) { return { firestorePathComplete : function ( state , getters ) { var path = state . _conf . firestorePath ; Object . keys ( state . _sync . pathVariables ) . forEach ( function ( key ) { var pathPiece = state . _sync . pathVariables [ key ] ; path = path . replace ( "{" + key + "}" , "" + pathPiece ) ; } ) ; var requireUser = path . includes ( '{userId}' ) ; if ( requireUser ) { var userId = state . _sync . userId ; if ( getters . signedIn && isWhat . isString ( userId ) && userId !== '' && userId !== '{userId}' ) { path = path . replace ( '{userId}' , userId ) ; } } return path ; } , signedIn : function ( state , getters , rootState , rootGetters ) { var requireUser = state . _conf . firestorePath . includes ( '{userId}' ) ; if ( ! requireUser ) return true ; return state . _sync . signedIn ; } , dbRef : function ( state , getters , rootState , rootGetters ) { var path = getters . firestorePathComplete ; return ( getters . collectionMode ) ? Firebase . firestore ( ) . collection ( path ) : Firebase . firestore ( ) . doc ( path ) ; } , storeRef : function ( state , getters , rootState ) { var path = ( state . _conf . statePropName ) ? state . _conf . moduleName + "/" + state . _conf . statePropName : state . _conf . moduleName ; return vuexEasyAccess . getDeepRef ( rootState , path ) ; } , collectionMode : function ( state , getters , rootState ) { return ( state . _conf . firestoreRefType . toLowerCase ( ) === 'collection' ) ; } , docModeId : function ( state , getters ) { return getters . firestorePathComplete . split ( '/' ) . pop ( ) ; } , fillables : function ( state ) { var fillables = state . _conf . sync . fillables ; if ( ! fillables . length ) return fillables ; return fillables . concat ( [ 'updated_at' , 'updated_by' , 'id' , 'created_at' , 'created_by' ] ) ; } , guard : function ( state ) { return state . _conf . sync . guard . concat ( [ '_conf' , '_sync' ] ) ; } , defaultValues : function ( state , getters ) { return merge ( state . _conf . sync . defaultValues , state . _conf . serverChange . defaultValues // depreciated ) ; } , cleanUpRetrievedDoc : function ( state , getters , rootState , rootGetters ) { return function ( doc , id ) { var defaultValues = merge ( getters . defaultValues , state . _conf . serverChange . convertTimestamps ) ; var cleanDoc = setDefaultValues ( doc , defaultValues ) ; cleanDoc . id = id ; return cleanDoc ; } ; } , prepareForPatch : function ( state , getters , rootState , rootGetters ) { return function ( ids , doc ) { if ( ids === void 0 ) { ids = [ ] ; } if ( doc === void 0 ) { doc = { } ; } // get relevant data from the storeRef var collectionMode = getters . collectionMode ; if ( ! collectionMode ) ids . push ( getters . docModeId ) ; // returns {object} -> {id: data} return ids . reduce ( function ( carry , id ) { var patchData = { } ; // retrieve full object in case there's an empty doc passed if ( ! Object . keys ( doc ) . length ) { patchData = ( collectionMode ) ? getters . storeRef [ id ] : getters . storeRef ; } else { patchData = doc ; } // set default fields patchData . updated_at = new Date ( ) ; patchData . updated_by = state . _sync . userId ; // clean up item var cleanedPatchData = filter ( patchData , getters . fillables , getters . guard ) ; var itemToUpdate = flatten ( cleanedPatchData ) ; // add id (required to get ref later at apiHelpers.ts) itemToUpdate . id = id ; carry [ id ] = itemToUpdate ; return carry ; } , { } ) ; } ; } , prepareForPropDeletion : function ( state , getters , rootState , rootGetters ) { return function ( path ) { if ( path === void 0 ) { path = '' ; } var _a ; var collectionMode = getters . collectionMode ; var patchData = { } ; // set default fields patchData . updated_at = new Date ( ) ; patchData . updated_by = state . _sync . userId ; // add fillable and guard defaults // clean up item var cleanedPatchData = filter ( patchData , getters . fillables , getters . guard ) ; // add id (required to get ref later at apiHelpers.ts) var id , cleanedPath ; if ( collectionMode ) { id = path . substring ( 0 , path . indexOf ( '.' ) ) ; cleanedPath = path . substring ( path . indexOf ( '.' ) + 1 ) ; } else { id = getters . docModeId ; cleanedPath = path ; } cleanedPatchData [ cleanedPath ] = Firebase . firestore . FieldValue . delete ( ) ; cleanedPatchData . id = id ; return _a = { } , _a [ id ] = cleanedPatchData , _a ; } ; } , prepareForInsert : function ( state , getters , rootState , rootGetters ) { return function ( items ) { if ( items === void 0 ) { items = [ ] ; } // add fillable and guard defaults return items . reduce ( function ( carry , item ) { // set default fields item . created_at = new Date ( ) ; item . created_by = state . _sync . userId ; // clean up item item = filter ( item , getters . fillables , getters . guard ) ; carry . push ( item ) ; return carry ; } , [ ] ) ; } ; } , prepareInitialDocForInsert : function ( state , getters , rootState , rootGetters ) { return function ( doc ) { // add fillable and guard defaults // set default fields doc . created_at = new Date ( ) ; doc . created_by = state . _sync . userId ; doc . id = getters . docModeId ; // clean up item doc = filter ( doc , getters . fillables , getters . guard ) ; return doc ; } ; } , getWhereArrays : function ( state , getters ) { return function ( whereArrays ) { if ( ! isWhat . isArray ( whereArrays ) ) whereArrays = state . _conf . sync . where ; if ( Firebase . auth ( ) . currentUser ) { state . _sync . signedIn = true ; state . _sync . userId = Firebase . auth ( ) . currentUser . uid ; } return whereArrays . map ( function ( whereClause ) { return whereClause . map ( function ( param ) { if ( ! isWhat . isString ( param ) ) return param ; var cleanedParam = param ; getPathVarMatches ( param ) . forEach ( function ( key ) { var keyRegEx = new RegExp ( "{" + key + "}" , 'g' ) ; if ( key === 'userId' ) { cleanedParam = cleanedParam . replace ( keyRegEx , state . _sync . userId ) ; return ; } if ( ! Object . keys ( state . _sync . pathVariables ) . includes ( key ) ) { return error ( 'missing-path-variables' ) ; } var varVal = state . _sync . pathVariables [ key ] ; // if path is only a param we need to just assign to avoid stringification if ( param === "{" + key + "}" ) { cleanedParam = varVal ; return ; } cleanedParam = cleanedParam . replace ( keyRegEx , varVal ) ; } ) ; return cleanedParam ; } ) ; } ) ; } ; } , } ; }


Input: Firebase Create vuex - easy - firestore modules . Add as single plugin to Vuex Store . [CODESPLIT] function vuexEasyFirestore ( easyFirestoreModule , _a ) { var _b = _a === void 0 ? { logging : false , preventInitialDocInsertion : false , FirebaseDependency : Firebase$2 } : _a , _c = _b . logging , logging = _c === void 0 ? false : _c , _d = _b . preventInitialDocInsertion , preventInitialDocInsertion = _d === void 0 ? false : _d , _e = _b . FirebaseDependency , FirebaseDependency = _e === void 0 ? Firebase$2 : _e ; if ( FirebaseDependency ) { setFirebaseDependency ( FirebaseDependency ) ; setFirebaseDependency$1 ( FirebaseDependency ) ; } return function ( store ) { // Get an array of config files if ( ! isWhat . isArray ( easyFirestoreModule ) ) easyFirestoreModule = [ easyFirestoreModule ] ; // Create a module for each config file easyFirestoreModule . forEach ( function ( config ) { config . logging = logging ; if ( config . sync && config . sync . preventInitialDocInsertion === undefined ) { config . sync . preventInitialDocInsertion = preventInitialDocInsertion ; } var moduleName = vuexEasyAccess . getKeysFromPath ( config . moduleName ) ; store . registerModule ( moduleName , iniModule ( config , FirebaseDependency ) ) ; } ) ; } ; }


Input: / * eslint - disable [CODESPLIT] function addAttrs ( element , attrs ) { Object . keys ( attrs ) . forEach ( function ( key ) { element . setAttribute ( key , attrs [ key ] ) ; } ) ; }


Input: _transformToHierarchy - Transforms a flat array of parent - child links into a hierarchy . @private @param { array<object > } links Set of parent - child link objects @param { array<string > |undefined } attributeFields Set of link fields to be used as attributes [CODESPLIT] function _transformToHierarchy ( links , attributeFields ) { const nodesByName = { } ; const assignNode = name => { if ( ! nodesByName [ name ] ) { nodesByName [ name ] = { name } ; } return nodesByName [ name ] ; } ; const assignNodeWithAttributes = ( name , attributes ) => { if ( ! nodesByName [ name ] ) { nodesByName [ name ] = { name , attributes , } ; } return nodesByName [ name ] ; } ; // Create nodes for each unique source and target. links . forEach ( link => { // if `attributeFields` is defined, create/overwrite current `link.attributes` if ( attributeFields ) { const customAttributes = { } ; attributeFields . forEach ( field => { customAttributes [ field ] = link [ field ] ; } ) ; link . attributes = customAttributes ; } link . source = assignNode ( link . parent ) ; link . target = assignNodeWithAttributes ( link . child , link . attributes ) ; const parent = link . source ; const child = link . target ; parent . id = uuid . v4 ( ) ; child . id = uuid . v4 ( ) ; child . parent = parent . name || null ; parent . _collapsed = child . _collapsed = false ; // eslint-disable-line // NOTE We assign to a custom `_children` field instead of D3's reserved // `children` to avoid update anomalies when collapsing/re-expanding nodes. parent . _children ? parent . _children . push ( child ) : ( parent . _children = [ child ] ) ; } ) ; // Extract & return the root node const rootLinks = links . filter ( link => ! link . source . parent ) ; return [ rootLinks [ 0 ] . source ] ; }


Input: parseCSV - Parses a CSV file into a hierarchy structure . [CODESPLIT] function parseCSV ( csvFilePath , attributeFields ) { return new Promise ( ( resolve , reject ) => { try { csv ( csvFilePath , data => resolve ( _transformToHierarchy ( data , attributeFields ) ) ) ; // lol hello Lisp } catch ( err ) { reject ( err ) ; } } ) ; }


Input: parseJSON - Parses a hierarchical JSON file that requires no further transformation . [CODESPLIT] function parseJSON ( jsonFilePath ) { return new Promise ( ( resolve , reject ) => { try { json ( jsonFilePath , data => resolve ( [ data ] ) ) ; } catch ( err ) { reject ( err ) ; } } ) ; }


Input: parseFlatJSON - Parses a flat JSON file into a hierarchy structure . [CODESPLIT] function parseFlatJSON ( jsonFilePath , attributeFields ) { return new Promise ( ( resolve , reject ) => { try { json ( jsonFilePath , data => resolve ( _transformToHierarchy ( data , attributeFields ) ) ) ; } catch ( err ) { reject ( err ) ; } } ) ; }


Input: Assert that the values match with the type specs . Error messages are memorized and will only be shown once . [CODESPLIT] function checkPropTypes ( typeSpecs , values , location , componentName , getStack ) { if ( true ) { for ( var typeSpecName in typeSpecs ) { if ( typeSpecs . hasOwnProperty ( typeSpecName ) ) { var error ; // Prop type validation may throw. In case they do, we don't want to // fail the render phase where it didn't fail before. So we log it. // After these have been cleaned up, we'll let them throw. try { // This is intentionally an invariant that gets caught. It's the same // behavior as without this statement except with a better message. if ( typeof typeSpecs [ typeSpecName ] !== 'function' ) { var err = Error ( ( componentName || 'React class' ) + ': ' + location + ' type `' + typeSpecName + '` is invalid; ' + 'it must be a function, usually from the `prop-types` package, but received `' + typeof typeSpecs [ typeSpecName ] + '`.' ) ; err . name = 'Invariant Violation' ; throw err ; } error = typeSpecs [ typeSpecName ] ( values , typeSpecName , componentName , location , null , ReactPropTypesSecret ) ; } catch ( ex ) { error = ex ; } if ( error && ! ( error instanceof Error ) ) { printWarning ( ( componentName || 'React class' ) + ': type specification of ' + location + ' `' + typeSpecName + '` is invalid; the type checker ' + 'function must return `null` or an `Error` but returned a ' + typeof error + '. ' + 'You may have forgotten to pass an argument to the type checker ' + 'creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and ' + 'shape all require an argument).' ) } if ( error instanceof Error && ! ( error . message in loggedTypeFailures ) ) { // Only monitor this failure once because there tends to be a lot of the // same error. loggedTypeFailures [ error . message ] = true ; var stack = getStack ? getStack ( ) : '' ; printWarning ( 'Failed ' + location + ' type: ' + error . message + ( stack != null ? stack : '' ) ) ; } } } } }


Input: Call a function while guarding against errors that happens within it . Returns an error if it throws otherwise null . [CODESPLIT] function invokeGuardedCallback ( name , func , context , a , b , c , d , e , f ) { hasError = false ; caughtError = null ; invokeGuardedCallbackImpl$1 . apply ( reporter , arguments ) ; }


Input: Same as invokeGuardedCallback but instead of returning an error it stores it in a global so it can be rethrown by rethrowCaughtError later . TODO : See if caughtError and rethrowError can be unified . [CODESPLIT] function invokeGuardedCallbackAndCatchFirstError ( name , func , context , a , b , c , d , e , f ) { invokeGuardedCallback . apply ( this , arguments ) ; if ( hasError ) { var error = clearCaughtError ( ) ; if ( ! hasRethrowError ) { hasRethrowError = true ; rethrowError = error ; } } }


Input: Given a DOM node return the closest ReactDOMComponent or ReactDOMTextComponent instance ancestor . [CODESPLIT] function getClosestInstanceFromNode ( node ) { if ( node [ internalInstanceKey ] ) { return node [ internalInstanceKey ] ; } while ( ! node [ internalInstanceKey ] ) { if ( node . parentNode ) { node = node . parentNode ; } else { // Top of the tree. This node must not be part of a React tree (or is // unmounted, potentially). return null ; } } var inst = node [ internalInstanceKey ] ; if ( inst . tag === HostComponent || inst . tag === HostText ) { // In Fiber, this will always be the deepest root. return inst ; } return null ; }


Input: Given a DOM node return the ReactDOMComponent or ReactDOMTextComponent instance or null if the node was not rendered by this React . [CODESPLIT] function getInstanceFromNode$1 ( node ) { var inst = node [ internalInstanceKey ] ; if ( inst ) { if ( inst . tag === HostComponent || inst . tag === HostText ) { return inst ; } else { return null ; } } return null ; }


Input: Given a ReactDOMComponent or ReactDOMTextComponent return the corresponding DOM node . [CODESPLIT] function getNodeFromInstance$1 ( inst ) { if ( inst . tag === HostComponent || inst . tag === HostText ) { // In Fiber this, is just the state node right now. We assume it will be // a host component or host text. return inst . stateNode ; } // Without this first invariant, passing a non-DOM-component triggers the next // invariant for a missing parent, which is super confusing. invariant ( false , 'getNodeFromInstance: Invalid argument.' ) ; }


Input: Traverses the ID hierarchy and invokes the supplied cb on any IDs that should would receive a mouseEnter or mouseLeave event . [CODESPLIT] function traverseEnterLeave ( from , to , fn , argFrom , argTo ) { var common = from && to ? getLowestCommonAncestor ( from , to ) : null ; var pathFrom = [ ] ; while ( true ) { if ( ! from ) { break ; } if ( from === common ) { break ; } var alternate = from . alternate ; if ( alternate !== null && alternate === common ) { break ; } pathFrom . push ( from ) ; from = getParent ( from ) ; } var pathTo = [ ] ; while ( true ) { if ( ! to ) { break ; } if ( to === common ) { break ; } var _alternate = to . alternate ; if ( _alternate !== null && _alternate === common ) { break ; } pathTo . push ( to ) ; to = getParent ( to ) ; } for ( var i = 0 ; i < pathFrom . length ; i ++ ) { fn ( pathFrom [ i ] , 'bubbled' , argFrom ) ; } for ( var _i = pathTo . length ; _i -- > 0 ; ) { fn ( pathTo [ _i ] , 'captured' , argTo ) ; } }


Input: A small set of propagation patterns each of which will accept a small amount of information and generate a set of dispatch ready event objects - which are sets of events that have already been annotated with a set of dispatched listener functions / ids . The API is designed this way to discourage these propagation strategies from actually executing the dispatches since we always want to collect the entire set of dispatches before executing even a single one . Tags a SyntheticEvent with dispatched listeners . Creating this function here allows us to not have to bind or create functions for each event . Mutating the event s members allows us to not have to create a wrapping dispatch object that pairs the event with the listener . [CODESPLIT] function accumulateDirectionalDispatches ( inst , phase , event ) { { ! inst ? warningWithoutStack$1 ( false , 'Dispatching inst must not be null' ) : void 0 ; } var listener = listenerAtPhase ( inst , event , phase ) ; if ( listener ) { event . _dispatchListeners = accumulateInto ( event . _dispatchListeners , listener ) ; event . _dispatchInstances = accumulateInto ( event . _dispatchInstances , inst ) ; } }


Input: Generate a mapping of standard vendor prefixes using the defined style property and event name . [CODESPLIT] function makePrefixMap ( styleProp , eventName ) { var prefixes = { } ; prefixes [ styleProp . toLowerCase ( ) ] = eventName . toLowerCase ( ) ; prefixes [ 'Webkit' + styleProp ] = 'webkit' + eventName ; prefixes [ 'Moz' + styleProp ] = 'moz' + eventName ; return prefixes ; }


Input: PooledClass looks for destructor on each instance it releases . [CODESPLIT] function ( ) { var Interface = this . constructor . Interface ; for ( var propName in Interface ) { { Object . defineProperty ( this , propName , getPooledWarningPropertyDefinition ( propName , Interface [ propName ] ) ) ; } } this . dispatchConfig = null ; this . _targetInst = null ; this . nativeEvent = null ; this . isDefaultPrevented = functionThatReturnsFalse ; this . isPropagationStopped = functionThatReturnsFalse ; this . _dispatchListeners = null ; this . _dispatchInstances = null ; { Object . defineProperty ( this , 'nativeEvent' , getPooledWarningPropertyDefinition ( 'nativeEvent' , null ) ) ; Object . defineProperty ( this , 'isDefaultPrevented' , getPooledWarningPropertyDefinition ( 'isDefaultPrevented' , functionThatReturnsFalse ) ) ; Object . defineProperty ( this , 'isPropagationStopped' , getPooledWarningPropertyDefinition ( 'isPropagationStopped' , functionThatReturnsFalse ) ) ; Object . defineProperty ( this , 'preventDefault' , getPooledWarningPropertyDefinition ( 'preventDefault' , function ( ) { } ) ) ; Object . defineProperty ( this , 'stopPropagation' , getPooledWarningPropertyDefinition ( 'stopPropagation' , function ( ) { } ) ) ; } }


Input: Translate native top level events into event types . [CODESPLIT] function getCompositionEventType ( topLevelType ) { switch ( topLevelType ) { case TOP_COMPOSITION_START : return eventTypes . compositionStart ; case TOP_COMPOSITION_END : return eventTypes . compositionEnd ; case TOP_COMPOSITION_UPDATE : return eventTypes . compositionUpdate ; } }


Input: Does our fallback mode think that this event is the end of composition? [CODESPLIT] function isFallbackCompositionEnd ( topLevelType , nativeEvent ) { switch ( topLevelType ) { case TOP_KEY_UP : // Command keys insert or clear IME input. return END_KEYCODES . indexOf ( nativeEvent . keyCode ) !== - 1 ; case TOP_KEY_DOWN : // Expect IME keyCode on each keydown. If we get any other // code we must have exited earlier. return nativeEvent . keyCode !== START_KEYCODE ; case TOP_KEY_PRESS : case TOP_MOUSE_DOWN : case TOP_BLUR : // Events are not possible without cancelling IME. return true ; default : return false ; } }


Input: Get the value for a property on a node . Only used in DEV for SSR validation . The expected argument is used as a hint of what the expected value is . Some properties have multiple equivalent values . [CODESPLIT] function getValueForProperty ( node , name , expected , propertyInfo ) { { if ( propertyInfo . mustUseProperty ) { var propertyName = propertyInfo . propertyName ; return node [ propertyName ] ; } else { var attributeName = propertyInfo . attributeName ; var stringValue = null ; if ( propertyInfo . type === OVERLOADED_BOOLEAN ) { if ( node . hasAttribute ( attributeName ) ) { var value = node . getAttribute ( attributeName ) ; if ( value === '' ) { return true ; } if ( shouldRemoveAttribute ( name , expected , propertyInfo , false ) ) { return value ; } if ( value === '' + expected ) { return expected ; } return value ; } } else if ( node . hasAttribute ( attributeName ) ) { if ( shouldRemoveAttribute ( name , expected , propertyInfo , false ) ) { // We had an attribute but shouldn't have had one, so read it // for the error message. return node . getAttribute ( attributeName ) ; } if ( propertyInfo . type === BOOLEAN ) { // If this was a boolean, it doesn't matter what the value is // the fact that we have it is the same as the expected. return expected ; } // Even if this property uses a namespace we use getAttribute // because we assume its namespaced name is the same as our config. // To use getAttributeNS we need the local name which we don't have // in our config atm. stringValue = node . getAttribute ( attributeName ) ; } if ( shouldRemoveAttribute ( name , expected , propertyInfo , false ) ) { return stringValue === null ? expected : stringValue ; } else if ( stringValue === '' + expected ) { return expected ; } else { return stringValue ; } } } }


Input: Sets the value for a property on a node . [CODESPLIT] function setValueForProperty ( node , name , value , isCustomComponentTag ) { var propertyInfo = getPropertyInfo ( name ) ; if ( shouldIgnoreAttribute ( name , propertyInfo , isCustomComponentTag ) ) { return ; } if ( shouldRemoveAttribute ( name , value , propertyInfo , isCustomComponentTag ) ) { value = null ; } // If the prop isn't in the special list, treat it as a simple attribute. if ( isCustomComponentTag || propertyInfo === null ) { if ( isAttributeNameSafe ( name ) ) { var _attributeName = name ; if ( value === null ) { node . removeAttribute ( _attributeName ) ; } else { node . setAttribute ( _attributeName , '' + value ) ; } } return ; } var mustUseProperty = propertyInfo . mustUseProperty ; if ( mustUseProperty ) { var propertyName = propertyInfo . propertyName ; if ( value === null ) { var type = propertyInfo . type ; node [ propertyName ] = type === BOOLEAN ? false : '' ; } else { // Contrary to `setAttribute`, object properties are properly // `toString`ed by IE8/9. node [ propertyName ] = value ; } return ; } // The rest are treated as attributes with special cases. var attributeName = propertyInfo . attributeName , attributeNamespace = propertyInfo . attributeNamespace ; if ( value === null ) { node . removeAttribute ( attributeName ) ; } else { var _type = propertyInfo . type ; var attributeValue = void 0 ; if ( _type === BOOLEAN || _type === OVERLOADED_BOOLEAN && value === true ) { attributeValue = '' ; } else { // `setAttribute` with objects becomes only `[object]` in IE8/9, // ('' + value) makes it output the correct toString()-value. attributeValue = '' + value ; } if ( attributeNamespace ) { node . setAttributeNS ( attributeNamespace , attributeName , attributeValue ) ; } else { node . setAttribute ( attributeName , attributeValue ) ; } } }


Input: Implements an <input > host component that allows setting these optional props : checked value defaultChecked and defaultValue . [CODESPLIT] function getHostProps ( element , props ) { var node = element ; var checked = props . checked ; var hostProps = _assign ( { } , props , { defaultChecked : undefined , defaultValue : undefined , value : undefined , checked : checked != null ? checked : node . _wrapperState . initialChecked } ) ; return hostProps ; }


Input: For IE8 and IE9 . [CODESPLIT] function getTargetInstForInputEventPolyfill ( topLevelType , targetInst ) { if ( topLevelType === TOP_SELECTION_CHANGE || topLevelType === TOP_KEY_UP || topLevelType === TOP_KEY_DOWN ) { // On the selectionchange event, the target is just document which isn't // helpful for us so just check activeElement instead. // // 99% of the time, keydown and keyup aren't necessary. IE8 fails to fire // propertychange on the first input event after setting `value` from a // script and fires only keydown, keypress, keyup. Catching keyup usually // gets it and catching keydown lets us fire an event for the first // keystroke if user does a key repeat (it'll be a little delayed: right // before the second keystroke). Other input methods (e.g., paste) seem to // fire selectionchange normally. return getInstIfValueChanged ( activeElementInst ) ; } }


Input: For almost every interaction we care about there will be both a top - level mouseover and mouseout event that occurs . Only use mouseout so that we do not extract duplicate events . However moving the mouse into the browser from outside will not fire a mouseout event . In this case we use the mouseover top - level event . [CODESPLIT] function ( topLevelType , targetInst , nativeEvent , nativeEventTarget ) { var isOverEvent = topLevelType === TOP_MOUSE_OVER || topLevelType === TOP_POINTER_OVER ; var isOutEvent = topLevelType === TOP_MOUSE_OUT || topLevelType === TOP_POINTER_OUT ; if ( isOverEvent && ( nativeEvent . relatedTarget || nativeEvent . fromElement ) ) { return null ; } if ( ! isOutEvent && ! isOverEvent ) { // Must not be a mouse or pointer in or out - ignoring. return null ; } var win = void 0 ; if ( nativeEventTarget . window === nativeEventTarget ) { // `nativeEventTarget` is probably a window object. win = nativeEventTarget ; } else { // TODO: Figure out why `ownerDocument` is sometimes undefined in IE8. var doc = nativeEventTarget . ownerDocument ; if ( doc ) { win = doc . defaultView || doc . parentWindow ; } else { win = window ; } } var from = void 0 ; var to = void 0 ; if ( isOutEvent ) { from = targetInst ; var related = nativeEvent . relatedTarget || nativeEvent . toElement ; to = related ? getClosestInstanceFromNode ( related ) : null ; } else { // Moving to a node from outside the window. from = null ; to = targetInst ; } if ( from === to ) { // Nothing pertains to our managed components. return null ; } var eventInterface = void 0 , leaveEventType = void 0 , enterEventType = void 0 , eventTypePrefix = void 0 ; if ( topLevelType === TOP_MOUSE_OUT || topLevelType === TOP_MOUSE_OVER ) { eventInterface = SyntheticMouseEvent ; leaveEventType = eventTypes$2 . mouseLeave ; enterEventType = eventTypes$2 . mouseEnter ; eventTypePrefix = 'mouse' ; } else if ( topLevelType === TOP_POINTER_OUT || topLevelType === TOP_POINTER_OVER ) { eventInterface = SyntheticPointerEvent ; leaveEventType = eventTypes$2 . pointerLeave ; enterEventType = eventTypes$2 . pointerEnter ; eventTypePrefix = 'pointer' ; } var fromNode = from == null ? win : getNodeFromInstance$1 ( from ) ; var toNode = to == null ? win : getNodeFromInstance$1 ( to ) ; var leave = eventInterface . getPooled ( leaveEventType , from , nativeEvent , nativeEventTarget ) ; leave . type = eventTypePrefix + 'leave' ; leave . target = fromNode ; leave . relatedTarget = toNode ; var enter = eventInterface . getPooled ( enterEventType , to , nativeEvent , nativeEventTarget ) ; enter . type = eventTypePrefix + 'enter' ; enter . target = toNode ; enter . relatedTarget = fromNode ; accumulateEnterLeaveDispatches ( leave , enter , from , to ) ; return [ leave , enter ] ; }


Input: Find the deepest React component completely containing the root of the passed - in instance ( for use when entire React trees are nested within each other ) . If React trees are not nested returns null . [CODESPLIT] function findRootContainerNode ( inst ) { // TODO: It may be a good idea to cache this to prevent unnecessary DOM // traversal, but caching is difficult to do correctly without using a // mutation observer to listen for all DOM changes. while ( inst . return ) { inst = inst . return ; } if ( inst . tag !== HostRoot ) { // This can happen if we're in a detached tree. return null ; } return inst . stateNode . containerInfo ; }


Input: We listen for bubbled touch events on the document object . [CODESPLIT] function listenTo ( registrationName , mountAt ) { var isListening = getListeningForDocument ( mountAt ) ; var dependencies = registrationNameDependencies [ registrationName ] ; for ( var i = 0 ; i < dependencies . length ; i ++ ) { var dependency = dependencies [ i ] ; if ( ! ( isListening . hasOwnProperty ( dependency ) && isListening [ dependency ] ) ) { switch ( dependency ) { case TOP_SCROLL : trapCapturedEvent ( TOP_SCROLL , mountAt ) ; break ; case TOP_FOCUS : case TOP_BLUR : trapCapturedEvent ( TOP_FOCUS , mountAt ) ; trapCapturedEvent ( TOP_BLUR , mountAt ) ; // We set the flag for a single dependency later in this function, // but this ensures we mark both as attached rather than just one. isListening [ TOP_BLUR ] = true ; isListening [ TOP_FOCUS ] = true ; break ; case TOP_CANCEL : case TOP_CLOSE : if ( isEventSupported ( getRawEventName ( dependency ) ) ) { trapCapturedEvent ( dependency , mountAt ) ; } break ; case TOP_INVALID : case TOP_SUBMIT : case TOP_RESET : // We listen to them on the target DOM elements. // Some of them bubble so we don't want them to fire twice. break ; default : // By default, listen on the top level to all non-media events. // Media events don't bubble so adding the listener wouldn't do anything. var isMediaEvent = mediaEventTypes . indexOf ( dependency ) !== - 1 ; if ( ! isMediaEvent ) { trapBubbledEvent ( dependency , mountAt ) ; } break ; } isListening [ dependency ] = true ; } } }


Input: Get document associated with the event target . [CODESPLIT] function getEventTargetDocument ( eventTarget ) { return eventTarget . window === eventTarget ? eventTarget . document : eventTarget . nodeType === DOCUMENT_NODE ? eventTarget : eventTarget . ownerDocument ; }


Input: Poll selection to see whether it s changed . [CODESPLIT] function constructSelectEvent ( nativeEvent , nativeEventTarget ) { // Ensure we have the right element, and that the user is not dragging a // selection (this matches native `select` event behavior). In HTML5, select // fires only on input and textarea thus if there's no focused element we // won't dispatch. var doc = getEventTargetDocument ( nativeEventTarget ) ; if ( mouseDown || activeElement$1 == null || activeElement$1 !== getActiveElement ( doc ) ) { return null ; } // Only fire when selection has actually changed. var currentSelection = getSelection ( activeElement$1 ) ; if ( ! lastSelection || ! shallowEqual ( lastSelection , currentSelection ) ) { lastSelection = currentSelection ; var syntheticEvent = SyntheticEvent . getPooled ( eventTypes$3 . select , activeElementInst$1 , nativeEvent , nativeEventTarget ) ; syntheticEvent . type = 'select' ; syntheticEvent . target = activeElement$1 ; accumulateTwoPhaseDispatches ( syntheticEvent ) ; return syntheticEvent ; } return null ; }


Input: Implements an <option > host component that warns when selected is set . [CODESPLIT] function validateProps ( element , props ) { { // This mirrors the codepath above, but runs for hydration too. // Warn about invalid children here so that client and hydration are consistent. // TODO: this seems like it could cause a DEV-only throw for hydration // if children contains a non-element object. We should try to avoid that. if ( typeof props . children === 'object' && props . children !== null ) { React . Children . forEach ( props . children , function ( child ) { if ( child == null ) { return ; } if ( typeof child === 'string' || typeof child === 'number' ) { return ; } if ( typeof child . type !== 'string' ) { return ; } if ( ! didWarnInvalidChild ) { didWarnInvalidChild = true ; warning$1 ( false , 'Only strings and numbers are supported as <option> children.' ) ; } } ) ; } // TODO: Remove support for `selected` in <option>. if ( props . selected != null && ! didWarnSelectedSetOnOption ) { warning$1 ( false , 'Use the `defaultValue` or `value` props on <select> instead of ' + 'setting `selected` on <option>.' ) ; didWarnSelectedSetOnOption = true ; } } }


Input: Set the textContent property of a node . For text updates it s faster to set the nodeValue of the Text node directly instead of using . textContent which will remove the existing node and create a new one . [CODESPLIT] function ( node , text ) { if ( text ) { var firstChild = node . firstChild ; if ( firstChild && firstChild === node . lastChild && firstChild . nodeType === TEXT_NODE ) { firstChild . nodeValue = text ; return ; } } node . textContent = text ; }


Input: Convert a value into the proper css writable value . The style name name should be logical ( no hyphens ) as specified in CSSProperty . isUnitlessNumber . [CODESPLIT] function dangerousStyleValue ( name , value , isCustomProperty ) { // Note that we've removed escapeTextForBrowser() calls here since the // whole string will be escaped when the attribute is injected into // the markup. If you provide unsafe user data here they can inject // arbitrary CSS which may be problematic (I couldn't repro this): // https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet // http://www.thespanner.co.uk/2007/11/26/ultimate-xss-css-injection/ // This is not an XSS hole but instead a potential CSS injection issue // which has lead to a greater discussion about how we're going to // trust URLs moving forward. See #2115901 var isEmpty = value == null || typeof value === 'boolean' || value === '' ; if ( isEmpty ) { return '' ; } if ( ! isCustomProperty && typeof value === 'number' && value !== 0 && ! ( isUnitlessNumber . hasOwnProperty ( name ) && isUnitlessNumber [ name ] ) ) { return value + 'px' ; // Presumes implicit 'px' suffix for unitless numbers } return ( '' + value ) . trim ( ) ; }


Input: Operations for dealing with CSS properties . This creates a string that is expected to be equivalent to the style attribute generated by server - side rendering . It by - passes warnings and security checks so it s not safe to use this value for anything other than comparison . It is only used in DEV for SSR validation . [CODESPLIT] function createDangerousStringForStyles ( styles ) { { var serialized = '' ; var delimiter = '' ; for ( var styleName in styles ) { if ( ! styles . hasOwnProperty ( styleName ) ) { continue ; } var styleValue = styles [ styleName ] ; if ( styleValue != null ) { var isCustomProperty = styleName . indexOf ( '--' ) === 0 ; serialized += delimiter + hyphenateStyleName ( styleName ) + ':' ; serialized += dangerousStyleValue ( styleName , styleValue , isCustomProperty ) ; delimiter = ';' ; } } return serialized || null ; } }


Input: Sets the value for multiple styles on a node . If a value is specified as ( empty string ) the corresponding style property will be unset . [CODESPLIT] function setValueForStyles ( node , styles ) { var style = node . style ; for ( var styleName in styles ) { if ( ! styles . hasOwnProperty ( styleName ) ) { continue ; } var isCustomProperty = styleName . indexOf ( '--' ) === 0 ; { if ( ! isCustomProperty ) { warnValidStyle$1 ( styleName , styles [ styleName ] ) ; } } var styleValue = dangerousStyleValue ( styleName , styles [ styleName ] , isCustomProperty ) ; if ( styleName === 'float' ) { styleName = 'cssFloat' ; } if ( isCustomProperty ) { style . setProperty ( styleName , styleValue ) ; } else { style [ styleName ] = styleValue ; } } }


Input: Exported FiberRoot type includes all properties To avoid requiring potentially error - prone : any casts throughout the project . Profiling properties are only safe to access in profiling builds ( when enableSchedulerTracing is true ) . The types are defined separately within this file to ensure they stay in sync . ( We don t have to use an inline : any cast when enableSchedulerTracing is disabled . ) / * eslint - enable no - use - before - define [CODESPLIT] function createFiberRoot ( containerInfo , isAsync , hydrate ) { // Cyclic construction. This cheats the type system right now because // stateNode is any. var uninitializedFiber = createHostRootFiber ( isAsync ) ; var root = void 0 ; if ( enableSchedulerTracing ) { root = { current : uninitializedFiber , containerInfo : containerInfo , pendingChildren : null , earliestPendingTime : NoWork , latestPendingTime : NoWork , earliestSuspendedTime : NoWork , latestSuspendedTime : NoWork , latestPingedTime : NoWork , didError : false , pendingCommitExpirationTime : NoWork , finishedWork : null , timeoutHandle : noTimeout , context : null , pendingContext : null , hydrate : hydrate , nextExpirationTimeToWorkOn : NoWork , expirationTime : NoWork , firstBatch : null , nextScheduledRoot : null , interactionThreadID : tracing . unstable_getThreadID ( ) , memoizedInteractions : new Set ( ) , pendingInteractionMap : new Map ( ) } ; } else { root = { current : uninitializedFiber , containerInfo : containerInfo , pendingChildren : null , earliestPendingTime : NoWork , latestPendingTime : NoWork , earliestSuspendedTime : NoWork , latestSuspendedTime : NoWork , latestPingedTime : NoWork , didError : false , pendingCommitExpirationTime : NoWork , finishedWork : null , timeoutHandle : noTimeout , context : null , pendingContext : null , hydrate : hydrate , nextExpirationTimeToWorkOn : NoWork , expirationTime : NoWork , firstBatch : null , nextScheduledRoot : null } ; } uninitializedFiber . stateNode = root ; // The reason for the way the Flow types are structured in this file, // Is to avoid needing :any casts everywhere interaction tracing fields are used. // Unfortunately that requires an :any cast for non-interaction tracing capable builds. // $FlowFixMe Remove this :any cast and replace it with something better. return root ; }


Input: TODO : Offscreen updates should never suspend . However a promise that suspended inside an offscreen subtree should be able to ping at the priority of the outer render . [CODESPLIT] function markPendingPriorityLevel ( root , expirationTime ) { // If there's a gap between completing a failed root and retrying it, // additional updates may be scheduled. Clear `didError`, in case the update // is sufficient to fix the error. root . didError = false ; // Update the latest and earliest pending times var earliestPendingTime = root . earliestPendingTime ; if ( earliestPendingTime === NoWork ) { // No other pending updates. root . earliestPendingTime = root . latestPendingTime = expirationTime ; } else { if ( earliestPendingTime > expirationTime ) { // This is the earliest pending update. root . earliestPendingTime = expirationTime ; } else { var latestPendingTime = root . latestPendingTime ; if ( latestPendingTime < expirationTime ) { // This is the latest pending update root . latestPendingTime = expirationTime ; } } } findNextExpirationTimeToWorkOn ( expirationTime , root ) ; }


Input: Warns if there is a duplicate or missing key [CODESPLIT] function warnOnInvalidKey ( child , knownKeys ) { { if ( typeof child !== 'object' || child === null ) { return knownKeys ; } switch ( child . $$typeof ) { case REACT_ELEMENT_TYPE : case REACT_PORTAL_TYPE : warnForMissingKey ( child ) ; var key = child . key ; if ( typeof key !== 'string' ) { break ; } if ( knownKeys === null ) { knownKeys = new Set ( ) ; knownKeys . add ( key ) ; break ; } if ( ! knownKeys . has ( key ) ) { knownKeys . add ( key ) ; break ; } warning$1 ( false , 'Encountered two children with the same key, `%s`. ' + 'Keys should be unique so that components maintain their identity ' + 'across updates. Non-unique keys may cause children to be ' + 'duplicated and/or omitted — the behavior is unsupported and ' + ' ould change in a future version.',  k y);   break ; default : break ; } } return knownKeys ; }


Input: / * function reuseChildrenEffects ( returnFiber : Fiber firstChild : Fiber ) { let child = firstChild ; do { Ensure that the first and last effect of the parent corresponds to the children s first and last effect . if ( !returnFiber . firstEffect ) { returnFiber . firstEffect = child . firstEffect ; } if ( child . lastEffect ) { if ( returnFiber . lastEffect ) { returnFiber . lastEffect . nextEffect = child . firstEffect ; } returnFiber . lastEffect = child . lastEffect ; } } while ( child = child . sibling ) ; } [CODESPLIT] function bailoutOnAlreadyFinishedWork ( current$$1 , workInProgress , renderExpirationTime ) { cancelWorkTimer ( workInProgress ) ; if ( current$$1 !== null ) { // Reuse previous context list workInProgress . firstContextDependency = current$$1 . firstContextDependency ; } if ( enableProfilerTimer ) { // Don't update "base" render times for bailouts. stopProfilerTimerIfRunning ( workInProgress ) ; } // Check if the children have any pending work. var childExpirationTime = workInProgress . childExpirationTime ; if ( childExpirationTime === NoWork || childExpirationTime > renderExpirationTime ) { // The children don't have any work either. We can skip them. // TODO: Once we add back resuming, we should check if the children are // a work-in-progress set. If so, we need to transfer their effects. return null ; } else { // This fiber doesn't have work, but its subtree does. Clone the child // fibers and continue. cloneChildFibers ( current$$1 , workInProgress ) ; return workInProgress . child ; } }


Input: Persistent host tree mode An unfortunate fork of appendAllChildren because we have two different parent types . [CODESPLIT] function ( containerChildSet , workInProgress ) { // We only have the top Fiber that was created but we need recurse down its // children to find all the terminal nodes. var node = workInProgress . child ; while ( node !== null ) { if ( node . tag === HostComponent || node . tag === HostText ) { appendChildToContainerChildSet ( containerChildSet , node . stateNode ) ; } else if ( node . tag === HostPortal ) { // If we have a portal child, then we don't want to traverse // down its children. Instead, we'll get insertions from each child in // the portal directly. } else if ( node . child !== null ) { node . child . return = node ; node = node . child ; continue ; } if ( node === workInProgress ) { return ; } while ( node . sibling === null ) { if ( node . return === null || node . return === workInProgress ) { return ; } node = node . return ; } node . sibling . return = node . return ; node = node . sibling ; } }


Input: Capture errors so they don t interrupt unmounting . [CODESPLIT] function safelyCallComponentWillUnmount ( current$$1 , instance ) { { invokeGuardedCallback ( null , callComponentWillUnmountWithTimer , null , current$$1 , instance ) ; if ( hasCaughtError ( ) ) { var unmountError = clearCaughtError ( ) ; captureCommitPhaseError ( current$$1 , unmountError ) ; } } }


Input: User - originating errors ( lifecycles and refs ) should not interrupt deletion so don t let them throw . Host - originating errors should interrupt deletion so it s okay [CODESPLIT] function commitUnmount ( current$$1 ) { onCommitUnmount ( current$$1 ) ; switch ( current$$1 . tag ) { case ClassComponent : case ClassComponentLazy : { safelyDetachRef ( current$$1 ) ; var instance = current$$1 . stateNode ; if ( typeof instance . componentWillUnmount === 'function' ) { safelyCallComponentWillUnmount ( current$$1 , instance ) ; } return ; } case HostComponent : { safelyDetachRef ( current$$1 ) ; return ; } case HostPortal : { // TODO: this is recursive. // We are also not using this parent because // the portal will get pushed immediately. if ( supportsMutation ) { unmountHostComponents ( current$$1 ) ; } else if ( supportsPersistence ) { emptyPortalContainer ( current$$1 ) ; } return ; } } }


Input: Creates a unique async expiration time . [CODESPLIT] function computeUniqueAsyncExpiration ( ) { var currentTime = requestCurrentTime ( ) ; var result = computeAsyncExpiration ( currentTime ) ; if ( result <= lastUniqueAsyncExpiration ) { // Since we assume the current time monotonically increases, we only hit // this branch when computeUniqueAsyncExpiration is fired multiple times // within a 200ms window (or whatever the async bucket size is). result = lastUniqueAsyncExpiration + 1 ; } lastUniqueAsyncExpiration = result ; return lastUniqueAsyncExpiration ; }


Input: TODO : Batching should be implemented at the renderer level not inside the reconciler . [CODESPLIT] function batchedUpdates$1 ( fn , a ) { var previousIsBatchingUpdates = isBatchingUpdates ; isBatchingUpdates = true ; try { return fn ( a ) ; } finally { isBatchingUpdates = previousIsBatchingUpdates ; if ( ! isBatchingUpdates && ! isRendering ) { performSyncWork ( ) ; } } }