@fluidframework/shared-object-base 2.33.2 → 2.40.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -0
- package/api-report/shared-object-base.legacy.alpha.api.md +7 -5
- package/dist/gcHandleVisitor.d.ts +1 -1
- package/dist/gcHandleVisitor.d.ts.map +1 -1
- package/dist/gcHandleVisitor.js +1 -1
- package/dist/gcHandleVisitor.js.map +1 -1
- package/dist/handle.d.ts +21 -1
- package/dist/handle.d.ts.map +1 -1
- package/dist/handle.js +10 -1
- package/dist/handle.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -1
- package/dist/index.js.map +1 -1
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/dist/serializer.d.ts +3 -2
- package/dist/serializer.d.ts.map +1 -1
- package/dist/serializer.js +4 -2
- package/dist/serializer.js.map +1 -1
- package/dist/sharedObject.d.ts +57 -11
- package/dist/sharedObject.d.ts.map +1 -1
- package/dist/sharedObject.js +72 -16
- package/dist/sharedObject.js.map +1 -1
- package/dist/sharedObjectKernel.d.ts +186 -0
- package/dist/sharedObjectKernel.d.ts.map +1 -0
- package/dist/sharedObjectKernel.js +227 -0
- package/dist/sharedObjectKernel.js.map +1 -0
- package/dist/types.d.ts +13 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/lib/gcHandleVisitor.d.ts +1 -1
- package/lib/gcHandleVisitor.d.ts.map +1 -1
- package/lib/gcHandleVisitor.js +1 -1
- package/lib/gcHandleVisitor.js.map +1 -1
- package/lib/handle.d.ts +21 -1
- package/lib/handle.d.ts.map +1 -1
- package/lib/handle.js +8 -0
- package/lib/handle.js.map +1 -1
- package/lib/index.d.ts +2 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +2 -0
- package/lib/index.js.map +1 -1
- package/lib/packageVersion.d.ts +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/lib/serializer.d.ts +3 -2
- package/lib/serializer.d.ts.map +1 -1
- package/lib/serializer.js +4 -2
- package/lib/serializer.js.map +1 -1
- package/lib/sharedObject.d.ts +57 -11
- package/lib/sharedObject.d.ts.map +1 -1
- package/lib/sharedObject.js +73 -17
- package/lib/sharedObject.js.map +1 -1
- package/lib/sharedObjectKernel.d.ts +186 -0
- package/lib/sharedObjectKernel.d.ts.map +1 -0
- package/lib/sharedObjectKernel.js +222 -0
- package/lib/sharedObjectKernel.js.map +1 -0
- package/lib/types.d.ts +13 -1
- package/lib/types.d.ts.map +1 -1
- package/lib/types.js.map +1 -1
- package/package.json +15 -14
- package/src/gcHandleVisitor.ts +1 -4
- package/src/handle.ts +29 -1
- package/src/index.ts +11 -0
- package/src/packageVersion.ts +1 -1
- package/src/serializer.ts +7 -4
- package/src/sharedObject.ts +74 -18
- package/src/sharedObjectKernel.ts +467 -0
- package/src/types.ts +13 -1
package/lib/serializer.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"serializer.js","sourceRoot":"","sources":["../src/serializer.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { IFluidHandle } from \"@fluidframework/core-interfaces\";\nimport {\n\tIFluidHandleContext,\n\ttype IFluidHandleInternal,\n} from \"@fluidframework/core-interfaces/internal\";\nimport { assert, shallowCloneObject } from \"@fluidframework/core-utils/internal\";\nimport {\n\tencodeHandleForSerialization,\n\tgenerateHandleContextPath,\n\tisSerializedHandle,\n\tisFluidHandle,\n\ttoFluidHandleInternal,\n\ttype ISerializedHandle,\n\tRemoteFluidObjectHandle,\n} from \"@fluidframework/runtime-utils/internal\";\n\n/**\n * @legacy\n * @alpha\n */\nexport interface IFluidSerializer {\n\t/**\n\t * Given a mostly-plain object that may have handle objects embedded within, will return a fully-plain object\n\t * where any embedded IFluidHandles have been replaced with a serializable form.\n\t *\n\t * The original `input` object is not mutated. This method will shallowly clones all objects in the path from\n\t * the root to any replaced handles. (If no handles are found, returns the original object.)\n\t */\n\tencode(value: unknown, bind: IFluidHandle): unknown;\n\n\t/**\n\t * Given a fully-jsonable object tree that may have encoded handle objects embedded within, will return an\n\t * equivalent object tree where any encoded IFluidHandles have been replaced with their decoded form.\n\t *\n\t * The original `input` object is not mutated. This method will shallowly clone all objects in the path from\n\t * the root to any replaced handles. (If no handles are found, returns the original object.)\n\t *\n\t * The decoded handles are implicitly bound to the handle context of this serializer.\n\t */\n\tdecode(input: unknown): unknown;\n\n\t/**\n\t * Stringifies a given value. Converts any IFluidHandle to its stringified equivalent.\n\t */\n\tstringify(value: unknown, bind: IFluidHandle): string;\n\n\t/**\n\t * Parses the given JSON input string and returns the JavaScript object defined by it. Any Fluid\n\t * handles will be realized as part of the parse\n\t */\n\tparse(value: string): unknown;\n}\n\n/**\n * Data Store serializer implementation\n * @internal\n */\nexport class FluidSerializer implements IFluidSerializer {\n\tprivate readonly root: IFluidHandleContext;\n\n\tpublic constructor(private readonly context: IFluidHandleContext) {\n\t\tthis.root = this.context;\n\t\twhile (this.root.routeContext !== undefined) {\n\t\t\tthis.root = this.root.routeContext;\n\t\t}\n\t}\n\n\tpublic get IFluidSerializer(): IFluidSerializer {\n\t\treturn this;\n\t}\n\n\t/**\n\t * Given a mostly-jsonable object tree that may have handle objects embedded within, will return a\n\t * fully-jsonable object tree where any embedded IFluidHandles have been replaced with a serializable form.\n\t *\n\t * The original `input` object is not mutated. This method will shallowly clone all objects in the path from\n\t * the root to any replaced handles. (If no handles are found, returns the original object.)\n\t *\n\t * Any unbound handles encountered are bound to the provided IFluidHandle.\n\t */\n\tpublic encode(input: unknown, bind: IFluidHandleInternal): unknown {\n\t\t// If the given 'input' cannot contain handles, return it immediately. Otherwise,\n\t\t// return the result of 'recursivelyReplace()'.\n\t\t// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions\n\t\treturn !!input && typeof input === \"object\"\n\t\t\t? this.recursivelyReplace(input, this.encodeValue.bind(this), bind)\n\t\t\t: input;\n\t}\n\n\t/**\n\t * Given a fully-jsonable object tree that may have encoded handle objects embedded within, will return an\n\t * equivalent object tree where any encoded IFluidHandles have been replaced with their decoded form.\n\t *\n\t * The original `input` object is not mutated. This method will shallowly clone all objects in the path from\n\t * the root to any replaced handles. (If no handles are found, returns the original object.)\n\t *\n\t * The decoded handles are implicitly bound to the handle context of this serializer.\n\t */\n\tpublic decode(input: unknown): unknown {\n\t\t// If the given 'input' cannot contain handles, return it immediately. Otherwise,\n\t\t// return the result of 'recursivelyReplace()'.\n\t\t// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions\n\t\treturn !!input && typeof input === \"object\"\n\t\t\t? this.recursivelyReplace(input, this.decodeValue.bind(this))\n\t\t\t: input;\n\t}\n\n\t/**\n\t * Serializes the input object into a JSON string.\n\t * Any IFluidHandles in the object will be replaced with their serialized form before stringify,\n\t * being bound to the given bind context in the process.\n\t */\n\tpublic stringify(input: unknown, bind: IFluidHandle): string {\n\t\tconst bindInternal = toFluidHandleInternal(bind);\n\t\treturn JSON.stringify(input, (key, value) => this.encodeValue(value, bindInternal));\n\t}\n\n\t/**\n\t * Parses the serialized data - context must match the context with which the JSON was stringified\n\t */\n\tpublic parse(input: string): unknown {\n\t\treturn JSON.parse(input, (key, value) => this.decodeValue(value));\n\t}\n\n\t/**\n\t * If the given 'value' is an IFluidHandle, returns the encoded IFluidHandle.\n\t * Otherwise returns the original 'value'. Used by 'encode()' and 'stringify()'.\n\t */\n\tprotected encodeValue(value: unknown, bind?: IFluidHandleInternal): unknown {\n\t\t// If 'value' is an IFluidHandle return its encoded form.\n\t\tif (isFluidHandle(value)) {\n\t\t\tassert(bind !== undefined, 0xa93 /* Cannot encode a handle without a bind context */);\n\t\t\treturn this.bindAndEncodeHandle(toFluidHandleInternal(value), bind);\n\t\t}\n\t\treturn value;\n\t}\n\n\t/**\n\t * If the given 'value' is an encoded IFluidHandle, returns the decoded IFluidHandle.\n\t * Otherwise returns the original 'value'. Used by 'decode()' and 'parse()'.\n\t */\n\tprotected decodeValue(value: unknown): unknown {\n\t\t// If 'value' is a serialized IFluidHandle return the deserialized result.\n\t\tif (isSerializedHandle(value)) {\n\t\t\t// Old documents may have handles with relative path in their summaries. Convert these to absolute\n\t\t\t// paths. This will ensure that future summaries will have absolute paths for these handles.\n\t\t\tconst absolutePath = value.url.startsWith(\"/\")\n\t\t\t\t? value.url\n\t\t\t\t: generateHandleContextPath(value.url, this.context);\n\n\t\t\treturn new RemoteFluidObjectHandle(\n\t\t\t\tabsolutePath,\n\t\t\t\tthis.root,\n\t\t\t\tvalue.payloadPending === true,\n\t\t\t);\n\t\t} else {\n\t\t\treturn value;\n\t\t}\n\t}\n\n\t/**\n\t * Invoked for non-null objects to recursively replace references to IFluidHandles.\n\t * Clones as-needed to avoid mutating the `input` object. If no IFluidHandles are present,\n\t * returns the original `input`.\n\t */\n\tprivate recursivelyReplace<TContext = unknown>(\n\t\tinput: object,\n\t\treplacer: (input: unknown, context?: TContext) => unknown,\n\t\tcontext?: TContext,\n\t): unknown {\n\t\t// Note: Caller is responsible for ensuring that `input` is defined / non-null.\n\t\t// (Required for Object.keys() below.)\n\n\t\t// Execute the `replace` on the current input. Note that Caller is responsible for ensuring that `input`\n\t\t// is a non-null object.\n\t\tconst maybeReplaced = replacer(input, context);\n\n\t\t// If either input or the replaced result is a Fluid Handle, there is no need to descend further.\n\t\t// IFluidHandles are always leaves in the object graph, and the code below cannot deal with IFluidHandle's structure.\n\t\tif (isFluidHandle(input) || isFluidHandle(maybeReplaced)) {\n\t\t\treturn maybeReplaced;\n\t\t}\n\n\t\t// Otherwise descend into the object graph looking for IFluidHandle instances.\n\t\tlet clone: object | undefined;\n\t\tfor (const key of Object.keys(input)) {\n\t\t\tconst value: unknown = input[key];\n\t\t\t// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions\n\t\t\tif (!!value && typeof value === \"object\") {\n\t\t\t\t// Note: Except for IFluidHandle, `input` must not contain circular references (as object must\n\t\t\t\t// be JSON serializable.) Therefore, guarding against infinite recursion here would only\n\t\t\t\t// lead to a later error when attempting to stringify().\n\t\t\t\tconst replaced = this.recursivelyReplace(value, replacer, context);\n\n\t\t\t\t// If the `replaced` object is different than the original `value` then the subgraph contained one\n\t\t\t\t// or more handles. If this happens, we need to return a clone of the `input` object where the\n\t\t\t\t// current property is replaced by the `replaced` value.\n\t\t\t\tif (replaced !== value) {\n\t\t\t\t\t// Lazily create a shallow clone of the `input` object if we haven't done so already.\n\t\t\t\t\tclone ??= shallowCloneObject(input);\n\n\t\t\t\t\t// Overwrite the current property `key` in the clone with the `replaced` value.\n\t\t\t\t\tclone[key] = replaced;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn clone ?? input;\n\t}\n\n\t/**\n\t * Encodes the given IFluidHandle into a JSON-serializable form,\n\t * also binding it to another node to ensure it attaches at the right time.\n\t * @param handle - The IFluidHandle to serialize.\n\t * @param bind - The binding context for the handle (the handle will become attached whenever this context is attached).\n\t * @returns The serialized handle.\n\t */\n\tprotected bindAndEncodeHandle(\n\t\thandle: IFluidHandleInternal,\n\t\tbind: IFluidHandleInternal,\n\t): ISerializedHandle {\n\t\tbind.bind(handle);\n\t\treturn encodeHandleForSerialization(handle);\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"serializer.js","sourceRoot":"","sources":["../src/serializer.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH,OAAO,EAAE,MAAM,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AACjF,OAAO,EACN,4BAA4B,EAC5B,yBAAyB,EACzB,kBAAkB,EAClB,aAAa,EACb,qBAAqB,EAErB,uBAAuB,GACvB,MAAM,wCAAwC,CAAC;AAEhD,OAAO,EAAE,qBAAqB,EAA4B,MAAM,aAAa,CAAC;AAuC9E;;;GAGG;AACH,MAAM,OAAO,eAAe;IAG3B,YAAoC,OAA4B;QAA5B,YAAO,GAAP,OAAO,CAAqB;QAC/D,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC;QACzB,OAAO,IAAI,CAAC,IAAI,CAAC,YAAY,KAAK,SAAS,EAAE,CAAC;YAC7C,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC;QACpC,CAAC;IACF,CAAC;IAED,IAAW,gBAAgB;QAC1B,OAAO,IAAI,CAAC;IACb,CAAC;IAED;;;;;;;;OAQG;IACI,MAAM,CAAC,KAAc,EAAE,IAA0B;QACvD,MAAM,CAAC,qBAAqB,CAAC,IAAI,CAAC,EAAE,KAAK,CAAC,yCAAyC,CAAC,CAAC;QACrF,kFAAkF;QAClF,+CAA+C;QAC/C,yEAAyE;QACzE,OAAO,CAAC,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ;YAC1C,CAAC,CAAC,IAAI,CAAC,kBAAkB,CAAC,KAAK,EAAE,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC;YACnE,CAAC,CAAC,KAAK,CAAC;IACV,CAAC;IAED;;;;;;;;OAQG;IACI,MAAM,CAAC,KAAc;QAC3B,kFAAkF;QAClF,+CAA+C;QAC/C,yEAAyE;QACzE,OAAO,CAAC,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ;YAC1C,CAAC,CAAC,IAAI,CAAC,kBAAkB,CAAC,KAAK,EAAE,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC7D,CAAC,CAAC,KAAK,CAAC;IACV,CAAC;IAED;;;;OAIG;IACI,SAAS,CAAC,KAAc,EAAE,IAAkB;QAClD,MAAM,CAAC,qBAAqB,CAAC,IAAI,CAAC,EAAE,KAAK,CAAC,yCAAyC,CAAC,CAAC;QACrF,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC;IAC7E,CAAC;IAED;;OAEG;IACI,KAAK,CAAC,KAAa;QACzB,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC;IACnE,CAAC;IAED;;;OAGG;IACO,WAAW,CAAC,KAAc,EAAE,IAA0B;QAC/D,yDAAyD;QACzD,IAAI,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC;YAC1B,MAAM,CAAC,IAAI,KAAK,SAAS,EAAE,KAAK,CAAC,mDAAmD,CAAC,CAAC;YACtF,OAAO,IAAI,CAAC,mBAAmB,CAAC,qBAAqB,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC,CAAC;QACrE,CAAC;QACD,OAAO,KAAK,CAAC;IACd,CAAC;IAED;;;OAGG;IACO,WAAW,CAAC,KAAc;QACnC,0EAA0E;QAC1E,IAAI,kBAAkB,CAAC,KAAK,CAAC,EAAE,CAAC;YAC/B,kGAAkG;YAClG,4FAA4F;YAC5F,MAAM,YAAY,GAAG,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC;gBAC7C,CAAC,CAAC,KAAK,CAAC,GAAG;gBACX,CAAC,CAAC,yBAAyB,CAAC,KAAK,CAAC,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;YAEtD,OAAO,IAAI,uBAAuB,CACjC,YAAY,EACZ,IAAI,CAAC,IAAI,EACT,KAAK,CAAC,cAAc,KAAK,IAAI,CAC7B,CAAC;QACH,CAAC;aAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACd,CAAC;IACF,CAAC;IAED;;;;OAIG;IACK,kBAAkB,CACzB,KAAa,EACb,QAAyD,EACzD,OAAkB;QAElB,+EAA+E;QAC/E,4CAA4C;QAE5C,yGAAyG;QACzG,wBAAwB;QACxB,MAAM,aAAa,GAAG,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QAE/C,iGAAiG;QACjG,qHAAqH;QACrH,IAAI,aAAa,CAAC,KAAK,CAAC,IAAI,aAAa,CAAC,aAAa,CAAC,EAAE,CAAC;YAC1D,OAAO,aAAa,CAAC;QACtB,CAAC;QAED,8EAA8E;QAC9E,IAAI,KAAyB,CAAC;QAC9B,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;YACtC,MAAM,KAAK,GAAY,KAAK,CAAC,GAAG,CAAC,CAAC;YAClC,yEAAyE;YACzE,IAAI,CAAC,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;gBAC1C,8FAA8F;gBAC9F,+FAA+F;gBAC/F,8DAA8D;gBAC9D,MAAM,QAAQ,GAAG,IAAI,CAAC,kBAAkB,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;gBAEnE,kGAAkG;gBAClG,+FAA+F;gBAC/F,wDAAwD;gBACxD,IAAI,QAAQ,KAAK,KAAK,EAAE,CAAC;oBACxB,qFAAqF;oBACrF,KAAK,KAAK,kBAAkB,CAAC,KAAK,CAAC,CAAC;oBAEpC,+EAA+E;oBAC/E,KAAK,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC;gBACvB,CAAC;YACF,CAAC;QACF,CAAC;QACD,OAAO,KAAK,IAAI,KAAK,CAAC;IACvB,CAAC;IAED;;;;;;OAMG;IACO,mBAAmB,CAC5B,MAA4B,EAC5B,IAAyB;QAEzB,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAClB,OAAO,4BAA4B,CAAC,MAAM,CAAC,CAAC;IAC7C,CAAC;CACD","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { IFluidHandle } from \"@fluidframework/core-interfaces\";\nimport {\n\tIFluidHandleContext,\n\ttype IFluidHandleInternal,\n} from \"@fluidframework/core-interfaces/internal\";\nimport { assert, shallowCloneObject } from \"@fluidframework/core-utils/internal\";\nimport {\n\tencodeHandleForSerialization,\n\tgenerateHandleContextPath,\n\tisSerializedHandle,\n\tisFluidHandle,\n\ttoFluidHandleInternal,\n\ttype ISerializedHandle,\n\tRemoteFluidObjectHandle,\n} from \"@fluidframework/runtime-utils/internal\";\n\nimport { isISharedObjectHandle, type ISharedObjectHandle } from \"./handle.js\";\n\n/**\n * @legacy\n * @alpha\n */\nexport interface IFluidSerializer {\n\t/**\n\t * Given a mostly-plain object that may have handle objects embedded within, will return a fully-plain object\n\t * where any embedded IFluidHandles have been replaced with a serializable form.\n\t *\n\t * The original `input` object is not mutated. This method will shallowly clones all objects in the path from\n\t * the root to any replaced handles. (If no handles are found, returns the original object.)\n\t */\n\tencode(value: unknown, bind: IFluidHandle): unknown;\n\n\t/**\n\t * Given a fully-jsonable object tree that may have encoded handle objects embedded within, will return an\n\t * equivalent object tree where any encoded IFluidHandles have been replaced with their decoded form.\n\t *\n\t * The original `input` object is not mutated. This method will shallowly clone all objects in the path from\n\t * the root to any replaced handles. (If no handles are found, returns the original object.)\n\t *\n\t * The decoded handles are implicitly bound to the handle context of this serializer.\n\t */\n\tdecode(input: unknown): unknown;\n\n\t/**\n\t * Stringifies a given value. Converts any IFluidHandle to its stringified equivalent.\n\t */\n\tstringify(value: unknown, bind: IFluidHandle): string;\n\n\t/**\n\t * Parses the given JSON input string and returns the JavaScript object defined by it. Any Fluid\n\t * handles will be realized as part of the parse\n\t */\n\tparse(value: string): unknown;\n}\n\n/**\n * Data Store serializer implementation\n * @internal\n */\nexport class FluidSerializer implements IFluidSerializer {\n\tprivate readonly root: IFluidHandleContext;\n\n\tpublic constructor(private readonly context: IFluidHandleContext) {\n\t\tthis.root = this.context;\n\t\twhile (this.root.routeContext !== undefined) {\n\t\t\tthis.root = this.root.routeContext;\n\t\t}\n\t}\n\n\tpublic get IFluidSerializer(): IFluidSerializer {\n\t\treturn this;\n\t}\n\n\t/**\n\t * Given a mostly-jsonable object tree that may have handle objects embedded within, will return a\n\t * fully-jsonable object tree where any embedded IFluidHandles have been replaced with a serializable form.\n\t *\n\t * The original `input` object is not mutated. This method will shallowly clone all objects in the path from\n\t * the root to any replaced handles. (If no handles are found, returns the original object.)\n\t *\n\t * Any unbound handles encountered are bound to the provided IFluidHandle.\n\t */\n\tpublic encode(input: unknown, bind: IFluidHandleInternal): unknown {\n\t\tassert(isISharedObjectHandle(bind), 0xb8c /* bind must be an ISharedObjectHandle */);\n\t\t// If the given 'input' cannot contain handles, return it immediately. Otherwise,\n\t\t// return the result of 'recursivelyReplace()'.\n\t\t// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions\n\t\treturn !!input && typeof input === \"object\"\n\t\t\t? this.recursivelyReplace(input, this.encodeValue.bind(this), bind)\n\t\t\t: input;\n\t}\n\n\t/**\n\t * Given a fully-jsonable object tree that may have encoded handle objects embedded within, will return an\n\t * equivalent object tree where any encoded IFluidHandles have been replaced with their decoded form.\n\t *\n\t * The original `input` object is not mutated. This method will shallowly clone all objects in the path from\n\t * the root to any replaced handles. (If no handles are found, returns the original object.)\n\t *\n\t * The decoded handles are implicitly bound to the handle context of this serializer.\n\t */\n\tpublic decode(input: unknown): unknown {\n\t\t// If the given 'input' cannot contain handles, return it immediately. Otherwise,\n\t\t// return the result of 'recursivelyReplace()'.\n\t\t// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions\n\t\treturn !!input && typeof input === \"object\"\n\t\t\t? this.recursivelyReplace(input, this.decodeValue.bind(this))\n\t\t\t: input;\n\t}\n\n\t/**\n\t * Serializes the input object into a JSON string.\n\t * Any IFluidHandles in the object will be replaced with their serialized form before stringify,\n\t * being bound to the given bind context in the process.\n\t */\n\tpublic stringify(input: unknown, bind: IFluidHandle): string {\n\t\tassert(isISharedObjectHandle(bind), 0xb8d /* bind must be an ISharedObjectHandle */);\n\t\treturn JSON.stringify(input, (key, value) => this.encodeValue(value, bind));\n\t}\n\n\t/**\n\t * Parses the serialized data - context must match the context with which the JSON was stringified\n\t */\n\tpublic parse(input: string): unknown {\n\t\treturn JSON.parse(input, (key, value) => this.decodeValue(value));\n\t}\n\n\t/**\n\t * If the given 'value' is an IFluidHandle, returns the encoded IFluidHandle.\n\t * Otherwise returns the original 'value'. Used by 'encode()' and 'stringify()'.\n\t */\n\tprotected encodeValue(value: unknown, bind?: ISharedObjectHandle): unknown {\n\t\t// If 'value' is an IFluidHandle return its encoded form.\n\t\tif (isFluidHandle(value)) {\n\t\t\tassert(bind !== undefined, 0xa93 /* Cannot encode a handle without a bind context */);\n\t\t\treturn this.bindAndEncodeHandle(toFluidHandleInternal(value), bind);\n\t\t}\n\t\treturn value;\n\t}\n\n\t/**\n\t * If the given 'value' is an encoded IFluidHandle, returns the decoded IFluidHandle.\n\t * Otherwise returns the original 'value'. Used by 'decode()' and 'parse()'.\n\t */\n\tprotected decodeValue(value: unknown): unknown {\n\t\t// If 'value' is a serialized IFluidHandle return the deserialized result.\n\t\tif (isSerializedHandle(value)) {\n\t\t\t// Old documents may have handles with relative path in their summaries. Convert these to absolute\n\t\t\t// paths. This will ensure that future summaries will have absolute paths for these handles.\n\t\t\tconst absolutePath = value.url.startsWith(\"/\")\n\t\t\t\t? value.url\n\t\t\t\t: generateHandleContextPath(value.url, this.context);\n\n\t\t\treturn new RemoteFluidObjectHandle(\n\t\t\t\tabsolutePath,\n\t\t\t\tthis.root,\n\t\t\t\tvalue.payloadPending === true,\n\t\t\t);\n\t\t} else {\n\t\t\treturn value;\n\t\t}\n\t}\n\n\t/**\n\t * Invoked for non-null objects to recursively replace references to IFluidHandles.\n\t * Clones as-needed to avoid mutating the `input` object. If no IFluidHandles are present,\n\t * returns the original `input`.\n\t */\n\tprivate recursivelyReplace<TContext = unknown>(\n\t\tinput: object,\n\t\treplacer: (input: unknown, context?: TContext) => unknown,\n\t\tcontext?: TContext,\n\t): unknown {\n\t\t// Note: Caller is responsible for ensuring that `input` is defined / non-null.\n\t\t// (Required for Object.keys() below.)\n\n\t\t// Execute the `replace` on the current input. Note that Caller is responsible for ensuring that `input`\n\t\t// is a non-null object.\n\t\tconst maybeReplaced = replacer(input, context);\n\n\t\t// If either input or the replaced result is a Fluid Handle, there is no need to descend further.\n\t\t// IFluidHandles are always leaves in the object graph, and the code below cannot deal with IFluidHandle's structure.\n\t\tif (isFluidHandle(input) || isFluidHandle(maybeReplaced)) {\n\t\t\treturn maybeReplaced;\n\t\t}\n\n\t\t// Otherwise descend into the object graph looking for IFluidHandle instances.\n\t\tlet clone: object | undefined;\n\t\tfor (const key of Object.keys(input)) {\n\t\t\tconst value: unknown = input[key];\n\t\t\t// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions\n\t\t\tif (!!value && typeof value === \"object\") {\n\t\t\t\t// Note: Except for IFluidHandle, `input` must not contain circular references (as object must\n\t\t\t\t// be JSON serializable.) Therefore, guarding against infinite recursion here would only\n\t\t\t\t// lead to a later error when attempting to stringify().\n\t\t\t\tconst replaced = this.recursivelyReplace(value, replacer, context);\n\n\t\t\t\t// If the `replaced` object is different than the original `value` then the subgraph contained one\n\t\t\t\t// or more handles. If this happens, we need to return a clone of the `input` object where the\n\t\t\t\t// current property is replaced by the `replaced` value.\n\t\t\t\tif (replaced !== value) {\n\t\t\t\t\t// Lazily create a shallow clone of the `input` object if we haven't done so already.\n\t\t\t\t\tclone ??= shallowCloneObject(input);\n\n\t\t\t\t\t// Overwrite the current property `key` in the clone with the `replaced` value.\n\t\t\t\t\tclone[key] = replaced;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn clone ?? input;\n\t}\n\n\t/**\n\t * Encodes the given IFluidHandle into a JSON-serializable form,\n\t * also binding it to another node to ensure it attaches at the right time.\n\t * @param handle - The IFluidHandle to serialize.\n\t * @param bind - The binding context for the handle (the handle will become attached whenever this context is attached).\n\t * @returns The serialized handle.\n\t */\n\tprotected bindAndEncodeHandle(\n\t\thandle: IFluidHandleInternal,\n\t\tbind: ISharedObjectHandle,\n\t): ISerializedHandle {\n\t\tbind.bind(handle);\n\t\treturn encodeHandleForSerialization(handle);\n\t}\n}\n"]}
|
package/lib/sharedObject.d.ts
CHANGED
|
@@ -13,13 +13,33 @@ import { ITelemetryLoggerExt, EventEmitterWithErrorHandling } from "@fluidframew
|
|
|
13
13
|
import { IFluidSerializer } from "./serializer.js";
|
|
14
14
|
import { ISharedObject, ISharedObjectEvents } from "./types.js";
|
|
15
15
|
/**
|
|
16
|
-
* Base class from which all shared objects derive.
|
|
16
|
+
* Base class from which all {@link ISharedObject|shared objects} derive.
|
|
17
|
+
* @remarks
|
|
18
|
+
* This class implements common behaviors that implementations of {@link ISharedObject} may want to reuse.
|
|
19
|
+
* Even more such behaviors are implemented in the {@link SharedObject} class.
|
|
20
|
+
* @privateRemarks
|
|
21
|
+
* Currently some documentation (like the above) implies that this is supposed to be the only implementation of ISharedObject, which is both package-exported and not `@sealed`.
|
|
22
|
+
* This situation should be clarified to indicate if other implementations of ISharedObject are allowed and just currently don't exist,
|
|
23
|
+
* or if the intention is that no other implementations should exist and creating some might break things.
|
|
24
|
+
* As part of this, any existing implementations of ISharedObject (via SharedObjectCore or otherwise) in use by legacy API users will need to be considered.
|
|
25
|
+
*
|
|
26
|
+
* TODO:
|
|
27
|
+
* This class should eventually be made internal, as custom subclasses of it outside this repository are intended to be made unsupported in the future.
|
|
17
28
|
* @legacy
|
|
18
29
|
* @alpha
|
|
19
30
|
*/
|
|
20
31
|
export declare abstract class SharedObjectCore<TEvent extends ISharedObjectEvents = ISharedObjectEvents> extends EventEmitterWithErrorHandling<TEvent> implements ISharedObject<TEvent> {
|
|
32
|
+
/**
|
|
33
|
+
* The ID of the shared object.
|
|
34
|
+
*/
|
|
21
35
|
id: string;
|
|
36
|
+
/**
|
|
37
|
+
* The runtime instance that contains the Shared Object.
|
|
38
|
+
*/
|
|
22
39
|
protected runtime: IFluidDataStoreRuntime;
|
|
40
|
+
/**
|
|
41
|
+
* The attributes of the Shared Object.
|
|
42
|
+
*/
|
|
23
43
|
readonly attributes: IChannelAttributes;
|
|
24
44
|
get IFluidLoadable(): this;
|
|
25
45
|
private readonly opProcessingHelper;
|
|
@@ -54,12 +74,19 @@ export declare abstract class SharedObjectCore<TEvent extends ISharedObjectEvent
|
|
|
54
74
|
* @returns The state of the connection
|
|
55
75
|
*/
|
|
56
76
|
get connected(): boolean;
|
|
77
|
+
constructor(
|
|
78
|
+
/**
|
|
79
|
+
* The ID of the shared object.
|
|
80
|
+
*/
|
|
81
|
+
id: string,
|
|
57
82
|
/**
|
|
58
|
-
*
|
|
59
|
-
* @param runtime - The IFluidDataStoreRuntime which contains the shared object
|
|
60
|
-
* @param attributes - Attributes of the shared object
|
|
83
|
+
* The runtime instance that contains the Shared Object.
|
|
61
84
|
*/
|
|
62
|
-
|
|
85
|
+
runtime: IFluidDataStoreRuntime,
|
|
86
|
+
/**
|
|
87
|
+
* The attributes of the Shared Object.
|
|
88
|
+
*/
|
|
89
|
+
attributes: IChannelAttributes);
|
|
63
90
|
/**
|
|
64
91
|
* Accessor for `this.runtime`'s {@link @fluidframework/datastore-definitions#IFluidDataStoreRuntime.deltaManager} as a {@link @fluidframework/container-definitions/internal#IDeltaManager}
|
|
65
92
|
*/
|
|
@@ -210,6 +237,14 @@ export declare abstract class SharedObjectCore<TEvent extends ISharedObjectEvent
|
|
|
210
237
|
* @param localOpMetadata - The local metadata associated with the original message.
|
|
211
238
|
*/
|
|
212
239
|
protected reSubmitCore(content: unknown, localOpMetadata: unknown): void;
|
|
240
|
+
/**
|
|
241
|
+
* Called when a message has to be resubmitted but its content should be "squashed" if any subsequent pending changes
|
|
242
|
+
* override the content in the fashion described on {@link @fluidframework/datastore-definitions#IDeltaHandler.reSubmit}.
|
|
243
|
+
*
|
|
244
|
+
* @param content - The content of the original message.
|
|
245
|
+
* @param localOpMetadata - The local metadata associated with the original message.
|
|
246
|
+
*/
|
|
247
|
+
protected reSubmitSquashed(content: unknown, localOpMetadata: unknown): void;
|
|
213
248
|
/**
|
|
214
249
|
* Promises that are waiting for an ack from the server before resolving should use this instead of new Promise.
|
|
215
250
|
* It ensures that if something changes that will interrupt that ack (e.g. the FluidDataStoreRuntime disposes),
|
|
@@ -250,6 +285,8 @@ export declare abstract class SharedObjectCore<TEvent extends ISharedObjectEvent
|
|
|
250
285
|
* reconnection.
|
|
251
286
|
* @param content - The content of the original message.
|
|
252
287
|
* @param localOpMetadata - The local metadata associated with the original message.
|
|
288
|
+
* @param squash - Optional. If `true`, the message will be resubmitted in a squashed form. If `undefined` or `false`,
|
|
289
|
+
* the legacy behavior (no squashing) will be used. Defaults to `false` for backward compatibility.
|
|
253
290
|
*/
|
|
254
291
|
private reSubmit;
|
|
255
292
|
/**
|
|
@@ -293,14 +330,24 @@ export declare abstract class SharedObjectCore<TEvent extends ISharedObjectEvent
|
|
|
293
330
|
* @returns Whatever `super.emit()` returns.
|
|
294
331
|
*/
|
|
295
332
|
private emitInternal;
|
|
333
|
+
private throwUnsupported;
|
|
296
334
|
}
|
|
297
335
|
/**
|
|
298
|
-
*
|
|
299
|
-
*
|
|
336
|
+
* Helper for implementing {@link ISharedObject} with simplified, synchronous summarization and garbage collection.
|
|
337
|
+
* @remarks
|
|
338
|
+
* DDS implementations with async and incremental summarization should extend {@link SharedObjectCore} directly instead.
|
|
339
|
+
* @privateRemarks
|
|
340
|
+
* TODO:
|
|
341
|
+
* This class is badly named.
|
|
342
|
+
* Once it becomes `@internal` "SharedObjectCore" should probably become "SharedObject"
|
|
343
|
+
* and this class should be renamed to something like "SharedObjectSynchronous".
|
|
300
344
|
* @legacy
|
|
301
345
|
* @alpha
|
|
302
346
|
*/
|
|
303
347
|
export declare abstract class SharedObject<TEvent extends ISharedObjectEvents = ISharedObjectEvents> extends SharedObjectCore<TEvent> {
|
|
348
|
+
/**
|
|
349
|
+
* The prefix to use for telemetry events emitted by this object.
|
|
350
|
+
*/
|
|
304
351
|
private readonly telemetryContextPrefix;
|
|
305
352
|
/**
|
|
306
353
|
* True while we are garbage collecting this object's data.
|
|
@@ -311,12 +358,11 @@ export declare abstract class SharedObject<TEvent extends ISharedObjectEvents =
|
|
|
311
358
|
*/
|
|
312
359
|
private readonly _serializer;
|
|
313
360
|
protected get serializer(): IFluidSerializer;
|
|
361
|
+
constructor(id: string, runtime: IFluidDataStoreRuntime, attributes: IChannelAttributes,
|
|
314
362
|
/**
|
|
315
|
-
*
|
|
316
|
-
* @param runtime - The IFluidDataStoreRuntime which contains the shared object
|
|
317
|
-
* @param attributes - Attributes of the shared object
|
|
363
|
+
* The prefix to use for telemetry events emitted by this object.
|
|
318
364
|
*/
|
|
319
|
-
|
|
365
|
+
telemetryContextPrefix: string);
|
|
320
366
|
/**
|
|
321
367
|
* {@inheritDoc @fluidframework/datastore-definitions#(IChannel:interface).getAttachSummary}
|
|
322
368
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sharedObject.d.ts","sourceRoot":"","sources":["../src/sharedObject.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AAErE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gDAAgD,CAAC;AACpF,OAAO,EAA4B,KAAK,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAC5F,OAAO,EACN,KAAK,oBAAoB,EACzB,KAAK,cAAc,EACnB,MAAM,0CAA0C,CAAC;AAElD,OAAO,EACN,gBAAgB,EAChB,sBAAsB,EAEtB,kBAAkB,EAClB,KAAK,eAAe,EACpB,sBAAsB,EAGtB,MAAM,gDAAgD,CAAC;AACxD,OAAO,EACN,KAAK,gBAAgB,EACrB,yBAAyB,EACzB,MAAM,6CAA6C,CAAC;AACrD,OAAO,EACN,sCAAsC,EACtC,qBAAqB,EACrB,iBAAiB,EACjB,sBAAsB,EAGtB,KAAK,yBAAyB,EAE9B,MAAM,8CAA8C,CAAC;AAKtD,OAAO,EACN,mBAAmB,EAEnB,6BAA6B,
|
|
1
|
+
{"version":3,"file":"sharedObject.d.ts","sourceRoot":"","sources":["../src/sharedObject.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AAErE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gDAAgD,CAAC;AACpF,OAAO,EAA4B,KAAK,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAC5F,OAAO,EACN,KAAK,oBAAoB,EACzB,KAAK,cAAc,EACnB,MAAM,0CAA0C,CAAC;AAElD,OAAO,EACN,gBAAgB,EAChB,sBAAsB,EAEtB,kBAAkB,EAClB,KAAK,eAAe,EACpB,sBAAsB,EAGtB,MAAM,gDAAgD,CAAC;AACxD,OAAO,EACN,KAAK,gBAAgB,EACrB,yBAAyB,EACzB,MAAM,6CAA6C,CAAC;AACrD,OAAO,EACN,sCAAsC,EACtC,qBAAqB,EACrB,iBAAiB,EACjB,sBAAsB,EAGtB,KAAK,yBAAyB,EAE9B,MAAM,8CAA8C,CAAC;AAKtD,OAAO,EACN,mBAAmB,EAEnB,6BAA6B,EAS7B,MAAM,0CAA0C,CAAC;AAKlD,OAAO,EAAmB,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACpE,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAYhE;;;;;;;;;;;;;;;GAeG;AACH,8BAAsB,gBAAgB,CACpC,MAAM,SAAS,mBAAmB,GAAG,mBAAmB,CAEzD,SAAQ,6BAA6B,CAAC,MAAM,CAC5C,YAAW,aAAa,CAAC,MAAM,CAAC;IAoD/B;;OAEG;IACI,EAAE,EAAE,MAAM;IACjB;;OAEG;IACH,SAAS,CAAC,OAAO,EAAE,sBAAsB;IACzC;;OAEG;aACa,UAAU,EAAE,kBAAkB;IA7D/C,IAAW,cAAc,IAAI,IAAI,CAEhC;IAED,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAGjC;IACF,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAkC;IAElE;;OAEG;IACH,SAAgB,MAAM,EAAE,oBAAoB,CAAC;IAE7C;;OAEG;IACH,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,mBAAmB,CAAC;IAC/C,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAoB;IAEvC;;OAEG;IACH,OAAO,CAAC,UAAU,CAAS;IAE3B;;OAEG;IACH,OAAO,CAAC,QAAQ,CAA+B;IAE/C;;OAEG;IACH,OAAO,CAAC,iBAAiB,CAAkB;IAE3C;;OAEG;IACH,OAAO,CAAC,UAAU,CAAC,CAA4D;IAE/E;;;OAGG;IACH,IAAW,SAAS,IAAI,OAAO,CAE9B;;IAGA;;OAEG;IACI,EAAE,EAAE,MAAM;IACjB;;OAEG;IACO,OAAO,EAAE,sBAAsB;IACzC;;OAEG;IACa,UAAU,EAAE,kBAAkB;IA0C/C;;OAEG;IACH,SAAS,KAAK,YAAY,IAAI,aAAa,CAAC,yBAAyB,EAAE,gBAAgB,CAAC,CAEvF;IAED;;;;;OAKG;IACH,OAAO,CAAC,4BAA4B;IAuCpC;;;;OAIG;IACH,OAAO,CAAC,cAAc;IAMtB;;OAEG;IACH,OAAO,CAAC,eAAe;IAMvB;;;;;;;;;OASG;IACH,OAAO,CAAC,yBAAyB;IAWjC,OAAO,CAAC,uBAAuB;IAmB/B;;;;OAIG;IACU,IAAI,CAAC,QAAQ,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;IAU5D;;;OAGG;IACI,eAAe,IAAI,IAAI;IAI9B;;OAEG;IACI,aAAa,IAAI,IAAI;IAY5B;;OAEG;IACI,OAAO,CAAC,QAAQ,EAAE,gBAAgB,GAAG,IAAI;IAWhD;;OAEG;IACI,UAAU,IAAI,OAAO;IAI5B;;OAEG;aACa,gBAAgB,CAC/B,QAAQ,CAAC,EAAE,OAAO,EAClB,UAAU,CAAC,EAAE,OAAO,EACpB,gBAAgB,CAAC,EAAE,iBAAiB,GAClC,qBAAqB;IAExB;;OAEG;aACa,SAAS,CACxB,QAAQ,CAAC,EAAE,OAAO,EAClB,UAAU,CAAC,EAAE,OAAO,EACpB,gBAAgB,CAAC,EAAE,iBAAiB,GAClC,OAAO,CAAC,qBAAqB,CAAC;IAEjC;;OAEG;aACa,SAAS,CAAC,MAAM,CAAC,EAAE,OAAO,GAAG,sBAAsB;IAEnE;;;OAGG;IACH,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,QAAQ,EAAE,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC;IAE5E;;OAEG;IACH,SAAS,CAAC,mBAAmB,IAAI,IAAI;IAIrC;;;OAGG;IACH,SAAS,CAAC,SAAS,IAAI,IAAI;IAI3B;;;;;;;;OAQG;IACH,SAAS,CAAC,QAAQ,CAAC,WAAW,CAC7B,OAAO,EAAE,yBAAyB,EAClC,KAAK,EAAE,OAAO,EACd,eAAe,EAAE,OAAO,GACtB,IAAI;IAGP;;;;;;;;;;;;;;OAcG;IAEH,SAAS,CAAC,mBAAmB,CAAC,CAAC,kBAAkB,EAAE,yBAAyB,GAAG,IAAI;IAEnF;;;;OAIG;IACH,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAE5B;IAEV;;OAEG;IAEH,SAAS,CAAC,QAAQ,CAAC,YAAY,IAAI,IAAI;IAEvC;;OAEG;IACH,SAAS,CAAC,QAAQ,KAAK,UAAU,IAAI,gBAAgB,CAAC;IAEtD;;;;;;;OAOG;IACH,SAAS,CAAC,kBAAkB,CAAC,OAAO,EAAE,OAAO,EAAE,eAAe,GAAE,OAAmB,GAAG,IAAI;IAiB1F;;;OAGG;IACH,SAAS,CAAC,KAAK,IAAI,IAAI;IASvB;;;OAGG;IACH,SAAS,CAAC,SAAS,IAAI,IAAI;IAE3B;;;;;;;OAOG;IACH,SAAS,CAAC,YAAY,CAAC,OAAO,EAAE,OAAO,EAAE,eAAe,EAAE,OAAO,GAAG,IAAI;IAIxE;;;;;;OAMG;IACH,SAAS,CAAC,gBAAgB,CAAC,OAAO,EAAE,OAAO,EAAE,eAAe,EAAE,OAAO,GAAG,IAAI;IAc5E;;;;;OAKG;cACa,kBAAkB,CAAC,CAAC,EACnC,QAAQ,EAAE,CACT,OAAO,EAAE,CAAC,KAAK,EAAE,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,KAAK,IAAI,EAC5C,MAAM,EAAE,CAAC,MAAM,CAAC,EAAE,OAAO,KAAK,IAAI,KAC9B,IAAI,GACP,OAAO,CAAC,CAAC,CAAC;IAqBb,OAAO,CAAC,kBAAkB;IA0B1B;;;OAGG;IACH,OAAO,CAAC,kBAAkB;IA0B1B;;;;;;;;OAQG;IACH,OAAO,CAAC,OAAO;IAyBf;;;;;;;;;;OAUG;IAEH,OAAO,CAAC,eAAe;IAyBvB;;;;;;;OAOG;IACH,OAAO,CAAC,QAAQ;IAUhB;;OAEG;IACH,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,OAAO,EAAE,eAAe,EAAE,OAAO,GAAG,IAAI;IAIpE;;;;;;;;;;;;;;;;OAgBG;IACH,SAAS,CAAC,QAAQ,CAAC,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAEzD;;;;;;;;;OASG;IACI,IAAI,CAAC,KAAK,EAAE,qBAAqB,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,OAAO;IAOlE;;;;;;OAMG;IACH,OAAO,CAAC,YAAY;IAIpB,OAAO,CAAC,gBAAgB;CAMxB;AAED;;;;;;;;;;;GAWG;AACH,8BAAsB,YAAY,CACjC,MAAM,SAAS,mBAAmB,GAAG,mBAAmB,CACvD,SAAQ,gBAAgB,CAAC,MAAM,CAAC;IA8BhC;;OAEG;IACH,OAAO,CAAC,QAAQ,CAAC,sBAAsB;IAhCxC;;OAEG;IACH,OAAO,CAAC,QAAQ,CAAkB;IAElC;;OAEG;IACH,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAmB;IAE/C,SAAS,KAAK,UAAU,IAAI,gBAAgB,CAa3C;gBAGA,EAAE,EAAE,MAAM,EACV,OAAO,EAAE,sBAAsB,EAC/B,UAAU,EAAE,kBAAkB;IAC9B;;OAEG;IACc,sBAAsB,EAAE,MAAM;IAOhD;;OAEG;IACI,gBAAgB,CACtB,QAAQ,GAAE,OAAe,EACzB,UAAU,GAAE,OAAe,EAC3B,gBAAgB,CAAC,EAAE,iBAAiB,GAClC,qBAAqB;IAexB;;OAEG;IACU,SAAS,CACrB,QAAQ,GAAE,OAAe,EACzB,UAAU,GAAE,OAAe,EAC3B,gBAAgB,CAAC,EAAE,iBAAiB,EACpC,yBAAyB,CAAC,EAAE,sCAAsC,GAChE,OAAO,CAAC,qBAAqB,CAAC;IAmBjC;;OAEG;IACI,SAAS,CAAC,MAAM,GAAE,OAAe,GAAG,sBAAsB;IA0BjE;;;;;;;;;OASG;IACH,SAAS,CAAC,iBAAiB,CAAC,UAAU,EAAE,gBAAgB,GAAG,IAAI;IAO/D;;;OAGG;IACH,SAAS,CAAC,QAAQ,CAAC,aAAa,CAC/B,UAAU,EAAE,gBAAgB,EAC5B,gBAAgB,CAAC,EAAE,iBAAiB,EACpC,yBAAyB,CAAC,EAAE,sCAAsC,GAChE,qBAAqB;IAExB,OAAO,CAAC,wBAAwB;CAmBhC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,WAAW,iBAAiB,CAAC,aAAa;IAC/C;;;;;;;;;OASG;IACH,UAAU,IAAI,eAAe,CAAC,aAAa,CAAC,CAAC;IAE7C;;;;;;;;;;;;;;;;;;OAkBG;IACH,MAAM,CAAC,OAAO,EAAE,sBAAsB,EAAE,EAAE,CAAC,EAAE,MAAM,GAAG,aAAa,CAAC;CACpE;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,gBAAgB,CAAC,GAAG,CAAC,aAAa,GAAG,OAAO,CAC5D,SAAQ,UAAU,CAAC,SAAS,CAAC,kBAAkB,EAAE,aAAa,CAAC,CAAC;IAChE;;;OAGG;IACH,EAAE,CAAC,KAAK,EAAE,cAAc,GAAG,KAAK,IAAI,cAAc,GAAG,aAAa,CAAC;CACnE;AAED;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CAAC,aAAa,EACnD,OAAO,EAAE,CAAC,UAAU,eAAe,CAAC,aAAa,CAAC,CAAC,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC7E,iBAAiB,CAAC,aAAa,CAAC,GAAG,gBAAgB,CAAC,aAAa,CAAC,CAiBpE"}
|
package/lib/sharedObject.js
CHANGED
|
@@ -6,14 +6,25 @@ import { AttachState } from "@fluidframework/container-definitions";
|
|
|
6
6
|
import { assert } from "@fluidframework/core-utils/internal";
|
|
7
7
|
import { blobCountPropertyName, totalBlobSizePropertyName, } from "@fluidframework/runtime-definitions/internal";
|
|
8
8
|
import { toDeltaManagerInternal, } from "@fluidframework/runtime-utils/internal";
|
|
9
|
-
import { DataProcessingError, EventEmitterWithErrorHandling, SampledTelemetryHelper, createChildLogger, loggerToMonitoringContext, tagCodeArtifacts, } from "@fluidframework/telemetry-utils/internal";
|
|
9
|
+
import { DataProcessingError, EventEmitterWithErrorHandling, SampledTelemetryHelper, createChildLogger, loggerToMonitoringContext, tagCodeArtifacts, LoggingError, } from "@fluidframework/telemetry-utils/internal";
|
|
10
10
|
import { v4 as uuid } from "uuid";
|
|
11
11
|
import { GCHandleVisitor } from "./gcHandleVisitor.js";
|
|
12
12
|
import { SharedObjectHandle } from "./handle.js";
|
|
13
13
|
import { FluidSerializer } from "./serializer.js";
|
|
14
14
|
import { bindHandles, makeHandlesSerializable, parseHandles } from "./utils.js";
|
|
15
15
|
/**
|
|
16
|
-
* Base class from which all shared objects derive.
|
|
16
|
+
* Base class from which all {@link ISharedObject|shared objects} derive.
|
|
17
|
+
* @remarks
|
|
18
|
+
* This class implements common behaviors that implementations of {@link ISharedObject} may want to reuse.
|
|
19
|
+
* Even more such behaviors are implemented in the {@link SharedObject} class.
|
|
20
|
+
* @privateRemarks
|
|
21
|
+
* Currently some documentation (like the above) implies that this is supposed to be the only implementation of ISharedObject, which is both package-exported and not `@sealed`.
|
|
22
|
+
* This situation should be clarified to indicate if other implementations of ISharedObject are allowed and just currently don't exist,
|
|
23
|
+
* or if the intention is that no other implementations should exist and creating some might break things.
|
|
24
|
+
* As part of this, any existing implementations of ISharedObject (via SharedObjectCore or otherwise) in use by legacy API users will need to be considered.
|
|
25
|
+
*
|
|
26
|
+
* TODO:
|
|
27
|
+
* This class should eventually be made internal, as custom subclasses of it outside this repository are intended to be made unsupported in the future.
|
|
17
28
|
* @legacy
|
|
18
29
|
* @alpha
|
|
19
30
|
*/
|
|
@@ -28,12 +39,19 @@ export class SharedObjectCore extends EventEmitterWithErrorHandling {
|
|
|
28
39
|
get connected() {
|
|
29
40
|
return this._connected;
|
|
30
41
|
}
|
|
42
|
+
constructor(
|
|
43
|
+
/**
|
|
44
|
+
* The ID of the shared object.
|
|
45
|
+
*/
|
|
46
|
+
id,
|
|
47
|
+
/**
|
|
48
|
+
* The runtime instance that contains the Shared Object.
|
|
49
|
+
*/
|
|
50
|
+
runtime,
|
|
31
51
|
/**
|
|
32
|
-
*
|
|
33
|
-
* @param runtime - The IFluidDataStoreRuntime which contains the shared object
|
|
34
|
-
* @param attributes - Attributes of the shared object
|
|
52
|
+
* The attributes of the Shared Object.
|
|
35
53
|
*/
|
|
36
|
-
|
|
54
|
+
attributes) {
|
|
37
55
|
super((event, e) => this.eventListenerErrorHandler(event, e));
|
|
38
56
|
this.id = id;
|
|
39
57
|
this.runtime = runtime;
|
|
@@ -270,6 +288,24 @@ export class SharedObjectCore extends EventEmitterWithErrorHandling {
|
|
|
270
288
|
reSubmitCore(content, localOpMetadata) {
|
|
271
289
|
this.submitLocalMessage(content, localOpMetadata);
|
|
272
290
|
}
|
|
291
|
+
/**
|
|
292
|
+
* Called when a message has to be resubmitted but its content should be "squashed" if any subsequent pending changes
|
|
293
|
+
* override the content in the fashion described on {@link @fluidframework/datastore-definitions#IDeltaHandler.reSubmit}.
|
|
294
|
+
*
|
|
295
|
+
* @param content - The content of the original message.
|
|
296
|
+
* @param localOpMetadata - The local metadata associated with the original message.
|
|
297
|
+
*/
|
|
298
|
+
reSubmitSquashed(content, localOpMetadata) {
|
|
299
|
+
const allowStagingModeWithoutSquashing = loggerToMonitoringContext(this.logger).config.getBoolean("Fluid.SharedObject.AllowStagingModeWithoutSquashing") ??
|
|
300
|
+
this.runtime.options.allowStagingModeWithoutSquashing ??
|
|
301
|
+
true;
|
|
302
|
+
if (allowStagingModeWithoutSquashing) {
|
|
303
|
+
this.reSubmitCore(content, localOpMetadata);
|
|
304
|
+
}
|
|
305
|
+
else {
|
|
306
|
+
this.throwUnsupported("reSubmitSquashed");
|
|
307
|
+
}
|
|
308
|
+
}
|
|
273
309
|
/**
|
|
274
310
|
* Promises that are waiting for an ack from the server before resolving should use this instead of new Promise.
|
|
275
311
|
* It ensures that if something changes that will interrupt that ack (e.g. the FluidDataStoreRuntime disposes),
|
|
@@ -302,8 +338,8 @@ export class SharedObjectCore extends EventEmitterWithErrorHandling {
|
|
|
302
338
|
setConnectionState: (connected) => {
|
|
303
339
|
this.setConnectionState(connected);
|
|
304
340
|
},
|
|
305
|
-
reSubmit: (content, localOpMetadata) => {
|
|
306
|
-
this.reSubmit(content, localOpMetadata);
|
|
341
|
+
reSubmit: (content, localOpMetadata, squash) => {
|
|
342
|
+
this.reSubmit(content, localOpMetadata, squash);
|
|
307
343
|
},
|
|
308
344
|
applyStashedOp: (content) => {
|
|
309
345
|
this.applyStashedOp(parseHandles(content, this.serializer));
|
|
@@ -400,15 +436,24 @@ export class SharedObjectCore extends EventEmitterWithErrorHandling {
|
|
|
400
436
|
* reconnection.
|
|
401
437
|
* @param content - The content of the original message.
|
|
402
438
|
* @param localOpMetadata - The local metadata associated with the original message.
|
|
439
|
+
* @param squash - Optional. If `true`, the message will be resubmitted in a squashed form. If `undefined` or `false`,
|
|
440
|
+
* the legacy behavior (no squashing) will be used. Defaults to `false` for backward compatibility.
|
|
403
441
|
*/
|
|
404
|
-
reSubmit(content, localOpMetadata) {
|
|
405
|
-
|
|
442
|
+
reSubmit(content, localOpMetadata, squash) {
|
|
443
|
+
// Back-compat: squash argument may not be provided by container-runtime layer.
|
|
444
|
+
// Default to previous behavior (no squash).
|
|
445
|
+
if (squash ?? false) {
|
|
446
|
+
this.reSubmitSquashed(content, localOpMetadata);
|
|
447
|
+
}
|
|
448
|
+
else {
|
|
449
|
+
this.reSubmitCore(content, localOpMetadata);
|
|
450
|
+
}
|
|
406
451
|
}
|
|
407
452
|
/**
|
|
408
453
|
* Revert an op
|
|
409
454
|
*/
|
|
410
455
|
rollback(content, localOpMetadata) {
|
|
411
|
-
|
|
456
|
+
this.throwUnsupported("rollback");
|
|
412
457
|
}
|
|
413
458
|
/**
|
|
414
459
|
* Emit an event. This function is only intended for use by DDS classes that extend SharedObject/SharedObjectCore,
|
|
@@ -436,10 +481,22 @@ export class SharedObjectCore extends EventEmitterWithErrorHandling {
|
|
|
436
481
|
emitInternal(event, ...args) {
|
|
437
482
|
return super.emit(event, ...args);
|
|
438
483
|
}
|
|
484
|
+
throwUnsupported(featureName) {
|
|
485
|
+
throw new LoggingError("Unsupported DDS feature", {
|
|
486
|
+
featureName,
|
|
487
|
+
...tagCodeArtifacts({ ddsType: this.attributes.type }),
|
|
488
|
+
});
|
|
489
|
+
}
|
|
439
490
|
}
|
|
440
491
|
/**
|
|
441
|
-
*
|
|
442
|
-
*
|
|
492
|
+
* Helper for implementing {@link ISharedObject} with simplified, synchronous summarization and garbage collection.
|
|
493
|
+
* @remarks
|
|
494
|
+
* DDS implementations with async and incremental summarization should extend {@link SharedObjectCore} directly instead.
|
|
495
|
+
* @privateRemarks
|
|
496
|
+
* TODO:
|
|
497
|
+
* This class is badly named.
|
|
498
|
+
* Once it becomes `@internal` "SharedObjectCore" should probably become "SharedObject"
|
|
499
|
+
* and this class should be renamed to something like "SharedObjectSynchronous".
|
|
443
500
|
* @legacy
|
|
444
501
|
* @alpha
|
|
445
502
|
*/
|
|
@@ -455,12 +512,11 @@ export class SharedObject extends SharedObjectCore {
|
|
|
455
512
|
assert(!this._isGCing, 0x075 /* "SummarySerializer should be used for serializing data during summary." */);
|
|
456
513
|
return this._serializer;
|
|
457
514
|
}
|
|
515
|
+
constructor(id, runtime, attributes,
|
|
458
516
|
/**
|
|
459
|
-
*
|
|
460
|
-
* @param runtime - The IFluidDataStoreRuntime which contains the shared object
|
|
461
|
-
* @param attributes - Attributes of the shared object
|
|
517
|
+
* The prefix to use for telemetry events emitted by this object.
|
|
462
518
|
*/
|
|
463
|
-
|
|
519
|
+
telemetryContextPrefix) {
|
|
464
520
|
super(id, runtime, attributes);
|
|
465
521
|
this.telemetryContextPrefix = telemetryContextPrefix;
|
|
466
522
|
/**
|