import { IFluidHandle } from "@fluidframework/core-interfaces" ; import { IFluidSerializer , ISerializedHandle , parseHandles , serializeHandles , SharedObject , ValueType , } from "@fluidframework/shared-object-base" ; import { ISerializableValue , ISerializedValue , IValueOpEmitter , IValueOperation , IValueType , } from "./mapKernelInterfaces" ; /**
 * A local value to be stored in a container type DDS.
 */ export interface ILocalValue { /**
     * Type indicator of the value stored within.
     */ readonly type : string ; /**
     * The in-memory value stored within.
     */ readonly value : any ; param serializer param bind returns makeSerialized ( serializer , bind ) : ISerializedValue ; } export function makeSerializable ( localValue , serializer , bind ) { const value = localValue . makeSerialized ( serializer , bind ) ; return { type : value . type , value : value . value && JSON . parse ( value . value ) } ; } /**
 * Manages a contained plain value.  May also contain shared object handles.
 */ export class PlainLocalValue implements ILocalValue { param value constructor ( public readonly value ) { } /**
     * {@inheritDoc ILocalValue."type"}
     */ public get type ( ) : string { return ValueType [ ValueType . Plain ] ; } /**
     * {@inheritDoc ILocalValue.makeSerialized}
     */ public makeSerialized ( serializer , bind ) { const value = serializeHandles ( this . value , serializer , bind ) ; return { type : this . type , value } ; } } privateRemarks alpha export class ValueTypeLocalValue implements ILocalValue { param value param valueType constructor ( public readonly value , private readonly valueType ) { } /**
     * {@inheritDoc ILocalValue."type"}
     */ public get type ( ) : string { return this . valueType . name ; } /**
     * {@inheritDoc ILocalValue.makeSerialized}
     */ public makeSerialized ( serializer , bind ) { const storedValueType = this . valueType . factory . store ( this . value ) ; const value = serializeHandles ( storedValueType , serializer , bind ) ; return { type : this . type , value } ; } param opName returns public getOpHandler ( opName ) { const handler = this . valueType . ops . get ( opName ) ; if ( ! handler ) { throw new Error ( "Unknown type message" ) ; } return handler ; } } /**
 * A LocalValueMaker enables a container type DDS to produce and store local values with minimal awareness of how
 * those objects are stored, serialized, and deserialized.
 */ export class LocalValueMaker { /**
     * The value types this maker is able to produce.
     */ private readonly valueTypes = new Map < string , IValueType < any > > ( ) ; param serializer constructor ( private readonly serializer ) { } param type alpha public registerValueType < T > ( type ) { this . valueTypes . set ( type . name , type ) ; } param serializable public fromSerializable ( serializable ) { if ( serializable . type === ValueType [ ValueType . Shared ] ) { serializable . type = ValueType [ ValueType . Plain ] ; const handle = { type : "__fluid_handle__" , url : serializable . value as string } ; serializable . value = handle ; } const translatedValue = parseHandles ( serializable . value , this . serializer ) ; return new PlainLocalValue ( translatedValue ) ; } param serializable param emitter public fromSerializableValueType ( serializable , emitter ) { if ( this . valueTypes . has ( serializable . type ) ) { const valueType = this . valueTypes . get ( serializable . type ) ! ; serializable . value = parseHandles ( serializable . value , this . serializer ) ; const localValue = valueType . factory . load ( emitter , serializable . value ) ; return new ValueTypeLocalValue ( localValue , valueType ) ; } else { throw new Error ( `Unknown value type "${ serializable . type }"` ) ; } } param value returns public fromInMemory ( value ) { if ( SharedObject . is ( value ) ) { throw new Error ( "SharedObject sets are no longer supported. Instead set the SharedObject handle." ) ; } return new PlainLocalValue ( value ) ; } param type param emitter param params returns alpha public makeValueType ( type , emitter , params ) { const valueType = this . loadValueType ( params , type , emitter ) ; return new ValueTypeLocalValue ( valueType , this . valueTypes . get ( type ) ! ) ; } param params param type param emitter returns alpha private loadValueType ( params , type , emitter ) { const valueType = this . valueTypes . get ( type ) ; if ( ! valueType ) { throw new Error ( `Unknown type '${ type }' specified` ) ; } return valueType . factory . load ( emitter , params ) ; } }