import { ArrayExt , StringExt } from '@lumino/algorithm' ; import { ReadonlyJSONValue } from '@lumino/coreutils' ; import { Field } from './field' ; import { createDuplexId } from './utilities' ; /**
 * A field which represents a collaborative atomic value.
 */ export class RegisterField < T extends ReadonlyJSONValue > extends Field < RegisterField . Value < T > , RegisterField . Update < T > , RegisterField . Metadata < T > , RegisterField . Change < T > , RegisterField . Patch < T > > { param options constructor ( options ) { super ( options ) ; this . value = options . value ; } /**
     * The discriminated type of the field.
     */ get type ( ) : 'register' { return 'register' ; } /**
     * The initial value for the field.
     */ readonly value : T ; returns createValue ( ) { return this . value ; } returns createMetadata ( ) { return { ids : [ ] , values : [ ] } ; } param args returns applyUpdate ( args ) { let { previous , update , metadata , version , storeId } = args ; let id = createDuplexId ( version , storeId ) ; let value = Private . insertIntoMetadata ( metadata , id , update ) ; let change = { previous , current : value } ; let patch = { id , value : update } ; return { value , change , patch } ; } param args returns applyPatch ( args ) { let { previous , patch , metadata } = args ; let value = Private . insertIntoMetadata ( metadata , patch . id , patch . value ) ; let change = { previous , current : value } ; return { value , change } ; } param args returns unapplyPatch ( args ) { let { previous , patch , metadata } = args ; let value = Private . removeFromMetadata ( metadata , patch . id , this . value ) ; let change = { previous , current : value } ; return { value , change } ; } param first param second returns mergeChange ( first , second ) { return { previous : first . previous , current : second . current } ; } param first param second returns mergePatch ( first , second ) { return second ; } } /**
 * The namespace for the `RegisterField` class statics.
 */ export namespace RegisterField { /**
     * An options object for initializing a register field.
     */ export interface IOptions < T extends ReadonlyJSONValue > extends Field . IOptions { /**
         * The initial value for the field.
         */ value : T ; } /**
     * A type alias for the register field value type.
     */ export type Value < T extends ReadonlyJSONValue > = T ; /**
     * A type alias for the register field update type.
     */ export type Update < T extends ReadonlyJSONValue > = T ; /**
     * A type alias for the register field change type.
     */ export type Change < T extends ReadonlyJSONValue > = { /**
         * The previous value of the field.
         */ readonly previous : T ; /**
         * The current value of the field.
         */ readonly current : T ; } ; /**
     * A type alias for the register field patch type.
     */ export type Patch < T extends ReadonlyJSONValue > = { /**
         * The unique id for the value.
         */ readonly id : string ; /**
         * The current value of the field.
         */ readonly value : T ; } ; /**
     * A type alias for the register field metadata type.
     */ export type Metadata < T extends ReadonlyJSONValue > = { /**
         * An array of id history.
         */ readonly ids : Array < string > ; /**
         * An array of value history.
         */ readonly values : Array < T > ; } ; } /**
 * The namespace for the module implementation details.
 */ namespace Private { param metadata param id param value returns export function insertIntoMetadata < T extends ReadonlyJSONValue > ( metadata , id , value ) { let { ids , values } = metadata ; let i = ArrayExt . lowerBound ( ids , id , StringExt . cmp ) ; if ( i < ids . length && ids [ i ] === id ) { values [ i ] = value ; } else { ArrayExt . insert ( ids , i , id ) ; ArrayExt . insert ( values , i , value ) ; } return values [ values . length - 1 ] ; } param metadata param id param initial returns export function removeFromMetadata < T extends ReadonlyJSONValue > ( metadata , id , initial ) { let { ids , values } = metadata ; let i = ArrayExt . lowerBound ( ids , id , StringExt . cmp ) ; if ( ids [ i ] === id ) { ArrayExt . removeAt ( ids , i ) ; ArrayExt . removeAt ( values , i ) ; } return values . length ? values [ values . length - 1 ] : initial ; } }