import { ITelemetryLoggerPropertyBag } from '@fluidframework/telemetry-utils' ; import { ITelemetryBaseEvent } from '@fluidframework/common-definitions' ; import { IFluidHandle } from '@fluidframework/core-interfaces' ; import { Payload } from './generic' ; const defaultFailMessage = 'Assertion failed' ; public export const sharedTreeAssertionErrorType = 'SharedTreeAssertion' ; /**
 * Telemetry properties decorated on all SharedTree events.
 */ export interface SharedTreeTelemetryProperties extends ITelemetryLoggerPropertyBag { isSharedTreeEvent : true ; } /**
 * Returns if the supplied event is a SharedTree telemetry event.
 */ export function isSharedTreeEvent ( event ) { return ( event as unknown as SharedTreeTelemetryProperties ) . isSharedTreeEvent === true ; } /**
 * Error object thrown by assertion failures in `SharedTree`.
 */ class SharedTreeAssertionError extends Error { public readonly errorType = sharedTreeAssertionErrorType ; public constructor ( message ) { super ( message ) ; this . name = 'Assertion error' ; Error . captureStackTrace ?. ( this ) ; } } returns public export function comparePayloads ( a , b ) { if ( Object . is ( a , b ) ) { return true ; } if ( typeof a !== 'object' || typeof b !== 'object' ) { return false ; } if ( a === null || b === null ) { return false ; } { const aHandle = a as IFluidHandle ; const bHandle = b as IFluidHandle ; if ( aHandle . IFluidHandle === a ) { if ( bHandle . IFluidHandle !== b ) { return false ; } return a . absolutePath === b . absolutePath ; } } const aKeys = Object . keys ( a ) ; const bKeys = Object . keys ( b ) ; if ( aKeys . length !== bKeys . length ) { return false ; } if ( Array . isArray ( a ) !== Array . isArray ( b ) ) { return false ; } if ( ! Array . isArray ( a ) ) { aKeys . sort ( ) ; bKeys . sort ( ) ; } if ( ! compareArrays ( aKeys , bKeys ) ) { return false ; } for ( let i = 0 ; i < aKeys . length ; i ++ ) { const aItem = a [ aKeys [ i ] ] ; const bItem = b [ bKeys [ i ] ] ; const aSelf = Object . is ( aItem , a ) ; const bSelf = Object . is ( bItem , b ) ; if ( aSelf !== bSelf ) { return false ; } if ( ! aSelf ) { if ( ! comparePayloads ( aItem , bItem ) ) { return false ; } } } return true ; } param condition param message param containsPII export function assert ( condition , message ? , containsPII = false ) { if ( ! condition ) { fail ( message , containsPII ) ; } } param message param containsPII export function fail ( message = defaultFailMessage , containsPII = false ) { if ( process . env . NODE_ENV !== 'production' ) { debugger ; console . error ( message ) ; } throw new SharedTreeAssertionError ( containsPII ? 'Assertion failed' : message ) ; } param value param message export function assertNotUndefined < T > ( value , message = 'value must not be undefined' ) { assert ( value !== undefined , message ) ; return value ; } param array param message export function assertArrayOfOne < T > ( array , message = 'array value must contain exactly one item' ) { assert ( array . length === 1 , message ) ; return array [ 0 ] ; } example param object param propName param value export function memoizeGetter < T , K extends keyof T > ( object , propName , value ) { Object . defineProperty ( object , propName , { value , enumerable : true , configurable : true } ) ; return value ; } param iterableA param iterableB param elementComparator export function compareIterables < T > ( iterableA , iterableB , elementComparator = Object . is ) { return compareIterators < T > ( iterableA [ Symbol . iterator ] ( ) , iterableB [ Symbol . iterator ] ( ) , elementComparator ) ; } param iteratorA param iteratorB param elementComparator function compareIterators < T , TReturn extends T = T > ( iteratorA , iteratorB , elementComparator = Object . is ) { let a ; let b ; for ( a = iteratorA . next ( ) , b = iteratorB . next ( ) ; a . done !== true && b . done !== true ; a = iteratorA . next ( ) , b = iteratorB . next ( ) ) { if ( ! elementComparator ( a . value , b . value ) ) { return false ; } } return a . done === b . done ; } param arrayA param arrayB param elementComparator export function compareArrays < T > ( arrayA , arrayB , elementComparator = Object . is ) { if ( arrayA . length !== arrayB . length ) { return false ; } for ( let i = 0 ; i < arrayA . length ; i ++ ) { if ( ! elementComparator ( arrayA [ i ] , arrayB [ i ] ) ) { return false ; } } return true ; } /**
 * Function which does nothing (no-ops).
 */ export function noop ( ) { } /**
 * Copies a property in such a way that it is only set on `destination` if it is present on `source`.
 * This avoids having explicit undefined values under properties that would cause `Object.hasOwnProperty` to return true.
 */ export function copyPropertyIfDefined < TSrc , TDst > ( source , destination , property ) { const value = source [ property ] ; if ( value !== undefined ) { ( destination as any ) [ property ] = value ; } } /**
 * A developer facing (non-localized) error message.
 * TODO: better error system.
 */ export type ErrorString = string ;