@fluidframework/runtime-utils
Advanced tools
@@ -66,3 +66,3 @@ "use strict"; | ||
| } | ||
| common_utils_1.assert(response.value, "Invalid response value for Fluid object request"); | ||
| common_utils_1.assert(response.value, 0x19a /* "Invalid response value for Fluid object request" */); | ||
| return response.value; | ||
@@ -74,3 +74,3 @@ } | ||
| function createResponseError(status, value, request) { | ||
| common_utils_1.assert(status !== 200, "Cannot not create response error on 200 status"); | ||
| common_utils_1.assert(status !== 200, 0x19b /* "Cannot not create response error on 200 status" */); | ||
| return { | ||
@@ -77,0 +77,0 @@ mimeType: "text/plain", |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"dataStoreHelpers.js","sourceRoot":"","sources":["../src/dataStoreHelpers.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert } from \"@fluidframework/common-utils\";\nimport {\n IFluidObject,\n IFluidRouter,\n IRequest,\n IResponse,\n} from \"@fluidframework/core-interfaces\";\nimport {\n IFluidDataStoreFactory,\n IFluidDataStoreRegistry,\n IProvideFluidDataStoreRegistry,\n} from \"@fluidframework/runtime-definitions\";\n\ninterface IResponseException extends Error {\n errorFromRequestFluidObject: true;\n message: string;\n code: number;\n stack: string;\n}\n\nexport function getStack() {\n const err = new Error();\n if (err.stack !== undefined) {\n return err.stack;\n }\n try {\n throw err;\n } catch (err2) {\n return (err2 as Error).stack;\n }\n}\n\nexport function exceptionToResponse(err: any): IResponse {\n const status = 500;\n // eslint-disable-next-line no-null/no-null\n if (err !== null && typeof err === \"object\" && err.errorFromRequestFluidObject === true) {\n const responseErr: IResponseException = err;\n return {\n mimeType: \"text/plain\",\n status: responseErr.code,\n value: responseErr.message,\n stack: responseErr.stack ?? getStack(),\n };\n }\n return {\n mimeType: \"text/plain\",\n status,\n value: `${err}`,\n stack: getStack(),\n };\n}\n\nexport function responseToException(response: IResponse, request: IRequest) {\n const message = response.value;\n const err = new Error(message);\n const responseErr = err as any as IResponseException;\n responseErr.errorFromRequestFluidObject = true;\n responseErr.message = message;\n responseErr.code = response.status;\n if (response.stack !== undefined) {\n try {\n // not clear if all browsers allow overwriting stack\n responseErr.stack = response.stack;\n } catch (err2) {}\n }\n return err;\n}\n\nexport async function requestFluidObject<T = IFluidObject>(\n router: IFluidRouter, url: string | IRequest): Promise<T> {\n const request = typeof url === \"string\" ? { url } : url;\n const response = await router.request(request);\n\n if (response.status !== 200 || response.mimeType !== \"fluid/object\") {\n throw responseToException(response, request);\n }\n\n assert(response.value, \"Invalid response value for Fluid object request\");\n return response.value as T;\n}\n\nexport const create404Response = (request: IRequest) => createResponseError(404, \"not found\", request);\n\nexport function createResponseError(status: number, value: string, request: IRequest): IResponse {\n assert(status !== 200, \"Cannot not create response error on 200 status\");\n return {\n mimeType: \"text/plain\",\n status,\n value: request.url === undefined ? value : `${value}: ${request.url}`,\n stack: getStack(),\n };\n}\n\nexport type Factory = IFluidDataStoreFactory & Partial<IProvideFluidDataStoreRegistry>;\n\n// eslint-disable-next-line prefer-arrow/prefer-arrow-functions\nexport function createDataStoreFactory(\n type: string,\n factory: Factory | Promise<Factory>,\n ): IFluidDataStoreFactory & IFluidDataStoreRegistry\n{\n return {\n type,\n get IFluidDataStoreFactory() { return this; },\n get IFluidDataStoreRegistry() { return this; },\n instantiateDataStore: async (context) => (await factory).instantiateDataStore(context),\n get: async (name: string) => (await factory).IFluidDataStoreRegistry?.get(name),\n };\n}\n"]} | ||
| {"version":3,"file":"dataStoreHelpers.js","sourceRoot":"","sources":["../src/dataStoreHelpers.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert } from \"@fluidframework/common-utils\";\nimport {\n IFluidObject,\n IFluidRouter,\n IRequest,\n IResponse,\n} from \"@fluidframework/core-interfaces\";\nimport {\n IFluidDataStoreFactory,\n IFluidDataStoreRegistry,\n IProvideFluidDataStoreRegistry,\n} from \"@fluidframework/runtime-definitions\";\n\ninterface IResponseException extends Error {\n errorFromRequestFluidObject: true;\n message: string;\n code: number;\n stack: string;\n}\n\nexport function getStack() {\n const err = new Error();\n if (err.stack !== undefined) {\n return err.stack;\n }\n try {\n throw err;\n } catch (err2) {\n return (err2 as Error).stack;\n }\n}\n\nexport function exceptionToResponse(err: any): IResponse {\n const status = 500;\n // eslint-disable-next-line no-null/no-null\n if (err !== null && typeof err === \"object\" && err.errorFromRequestFluidObject === true) {\n const responseErr: IResponseException = err;\n return {\n mimeType: \"text/plain\",\n status: responseErr.code,\n value: responseErr.message,\n stack: responseErr.stack ?? getStack(),\n };\n }\n return {\n mimeType: \"text/plain\",\n status,\n value: `${err}`,\n stack: getStack(),\n };\n}\n\nexport function responseToException(response: IResponse, request: IRequest) {\n const message = response.value;\n const err = new Error(message);\n const responseErr = err as any as IResponseException;\n responseErr.errorFromRequestFluidObject = true;\n responseErr.message = message;\n responseErr.code = response.status;\n if (response.stack !== undefined) {\n try {\n // not clear if all browsers allow overwriting stack\n responseErr.stack = response.stack;\n } catch (err2) {}\n }\n return err;\n}\n\nexport async function requestFluidObject<T = IFluidObject>(\n router: IFluidRouter, url: string | IRequest): Promise<T> {\n const request = typeof url === \"string\" ? { url } : url;\n const response = await router.request(request);\n\n if (response.status !== 200 || response.mimeType !== \"fluid/object\") {\n throw responseToException(response, request);\n }\n\n assert(response.value, 0x19a /* \"Invalid response value for Fluid object request\" */);\n return response.value as T;\n}\n\nexport const create404Response = (request: IRequest) => createResponseError(404, \"not found\", request);\n\nexport function createResponseError(status: number, value: string, request: IRequest): IResponse {\n assert(status !== 200, 0x19b /* \"Cannot not create response error on 200 status\" */);\n return {\n mimeType: \"text/plain\",\n status,\n value: request.url === undefined ? value : `${value}: ${request.url}`,\n stack: getStack(),\n };\n}\n\nexport type Factory = IFluidDataStoreFactory & Partial<IProvideFluidDataStoreRegistry>;\n\n// eslint-disable-next-line prefer-arrow/prefer-arrow-functions\nexport function createDataStoreFactory(\n type: string,\n factory: Factory | Promise<Factory>,\n ): IFluidDataStoreFactory & IFluidDataStoreRegistry\n{\n return {\n type,\n get IFluidDataStoreFactory() { return this; },\n get IFluidDataStoreRegistry() { return this; },\n instantiateDataStore: async (context) => (await factory).instantiateDataStore(context),\n get: async (name: string) => (await factory).IFluidDataStoreRegistry?.get(name),\n };\n}\n"]} |
@@ -17,3 +17,3 @@ "use strict"; | ||
| // `path` must not include the trailing separator. | ||
| common_utils_1.assert(!path.endsWith("/"), "storage service path has trailing separator"); | ||
| common_utils_1.assert(!path.endsWith("/"), 0x19c /* "storage service path has trailing separator" */); | ||
| } | ||
@@ -20,0 +20,0 @@ async readBlob(path) { |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"objectstoragepartition.js","sourceRoot":"","sources":["../src/objectstoragepartition.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,+DAAsD;AAGtD;;GAEG;AACH,MAAa,sBAAsB;IAC/B,YAA6B,OAA+B,EAAmB,IAAY;QAA9D,YAAO,GAAP,OAAO,CAAwB;QAAmB,SAAI,GAAJ,IAAI,CAAQ;QACvF,kDAAkD;QAClD,qBAAM,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,6CAA6C,CAAC,CAAC;IAC/E,CAAC;IAEM,KAAK,CAAC,QAAQ,CAAC,IAAY;QAC9B,OAAO,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,EAAE,CAAC,CAAC;IACzD,CAAC;IAEM,KAAK,CAAC,QAAQ,CAAC,IAAY;QAC9B,OAAO,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,EAAE,CAAC,CAAC;IACzD,CAAC;IAEM,KAAK,CAAC,IAAI,CAAC,IAAY;QAC1B,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,EAAE,CAAC,CAAC;IACrD,CAAC;CACJ;AAjBD,wDAiBC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert } from \"@fluidframework/common-utils\";\nimport { IChannelStorageService } from \"@fluidframework/datastore-definitions\";\n\n/**\n * Returns a new IChannelStorageService that resolves the given `path` as root.\n */\nexport class ObjectStoragePartition implements IChannelStorageService {\n constructor(private readonly storage: IChannelStorageService, private readonly path: string) {\n // `path` must not include the trailing separator.\n assert(!path.endsWith(\"/\"), \"storage service path has trailing separator\");\n }\n\n public async readBlob(path: string): Promise<ArrayBufferLike> {\n return this.storage.readBlob(`${this.path}/${path}`);\n }\n\n public async contains(path: string): Promise<boolean> {\n return this.storage.contains(`${this.path}/${path}`);\n }\n\n public async list(path: string): Promise<string[]> {\n return this.storage.list(`${this.path}/${path}`);\n }\n}\n"]} | ||
| {"version":3,"file":"objectstoragepartition.js","sourceRoot":"","sources":["../src/objectstoragepartition.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,+DAAsD;AAGtD;;GAEG;AACH,MAAa,sBAAsB;IAC/B,YAA6B,OAA+B,EAAmB,IAAY;QAA9D,YAAO,GAAP,OAAO,CAAwB;QAAmB,SAAI,GAAJ,IAAI,CAAQ;QACvF,kDAAkD;QAClD,qBAAM,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,KAAK,CAAC,mDAAmD,CAAC,CAAC;IAC3F,CAAC;IAEM,KAAK,CAAC,QAAQ,CAAC,IAAY;QAC9B,OAAO,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,EAAE,CAAC,CAAC;IACzD,CAAC;IAEM,KAAK,CAAC,QAAQ,CAAC,IAAY;QAC9B,OAAO,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,EAAE,CAAC,CAAC;IACzD,CAAC;IAEM,KAAK,CAAC,IAAI,CAAC,IAAY;QAC1B,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,EAAE,CAAC,CAAC;IACrD,CAAC;CACJ;AAjBD,wDAiBC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert } from \"@fluidframework/common-utils\";\nimport { IChannelStorageService } from \"@fluidframework/datastore-definitions\";\n\n/**\n * Returns a new IChannelStorageService that resolves the given `path` as root.\n */\nexport class ObjectStoragePartition implements IChannelStorageService {\n constructor(private readonly storage: IChannelStorageService, private readonly path: string) {\n // `path` must not include the trailing separator.\n assert(!path.endsWith(\"/\"), 0x19c /* \"storage service path has trailing separator\" */);\n }\n\n public async readBlob(path: string): Promise<ArrayBufferLike> {\n return this.storage.readBlob(`${this.path}/${path}`);\n }\n\n public async contains(path: string): Promise<boolean> {\n return this.storage.contains(`${this.path}/${path}`);\n }\n\n public async list(path: string): Promise<string[]> {\n return this.storage.list(`${this.path}/${path}`);\n }\n}\n"]} |
@@ -8,3 +8,3 @@ /*! | ||
| export declare const pkgName = "@fluidframework/runtime-utils"; | ||
| export declare const pkgVersion = "0.37.0-20427"; | ||
| export declare const pkgVersion = "0.37.0-20517"; | ||
| //# sourceMappingURL=packageVersion.d.ts.map |
@@ -11,3 +11,3 @@ "use strict"; | ||
| exports.pkgName = "@fluidframework/runtime-utils"; | ||
| exports.pkgVersion = "0.37.0-20427"; | ||
| exports.pkgVersion = "0.37.0-20517"; | ||
| //# sourceMappingURL=packageVersion.js.map |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"packageVersion.js","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAEU,QAAA,OAAO,GAAG,+BAA+B,CAAC;AAC1C,QAAA,UAAU,GAAG,cAAc,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License.\n *\n * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY\n */\n\nexport const pkgName = \"@fluidframework/runtime-utils\";\nexport const pkgVersion = \"0.37.0-20427\";\n"]} | ||
| {"version":3,"file":"packageVersion.js","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAEU,QAAA,OAAO,GAAG,+BAA+B,CAAC;AAC1C,QAAA,UAAU,GAAG,cAAc,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License.\n *\n * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY\n */\n\nexport const pkgName = \"@fluidframework/runtime-utils\";\nexport const pkgVersion = \"0.37.0-20517\";\n"]} |
@@ -27,3 +27,3 @@ "use strict"; | ||
| this.isAttached = true; | ||
| common_utils_1.assert(absolutePath.startsWith("/"), "Handles should always have absolute paths"); | ||
| common_utils_1.assert(absolutePath.startsWith("/"), 0x19d /* "Handles should always have absolute paths" */); | ||
| } | ||
@@ -30,0 +30,0 @@ get IFluidRouter() { return this; } |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"remoteObjectHandle.js","sourceRoot":"","sources":["../src/remoteObjectHandle.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,+DAAsD;AAQtD,yDAAiG;AAEjG;;;;;;GAMG;AACH,MAAa,uBAAuB;IAQhC;;;;OAIG;IACH,YACoB,YAAoB,EACpB,YAAiC;QADjC,iBAAY,GAAZ,YAAY,CAAQ;QACpB,iBAAY,GAAZ,YAAY,CAAqB;QAVrC,eAAU,GAAG,IAAI,CAAC;QAY9B,qBAAM,CAAC,YAAY,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,2CAA2C,CAAC,CAAC;IACtF,CAAC;IAjBD,IAAW,YAAY,KAAK,OAAO,IAAI,CAAC,CAAC,CAAC;IAC1C,IAAW,mBAAmB,KAAK,OAAO,IAAI,CAAC,CAAC,CAAC;IACjD,IAAW,YAAY,KAAK,OAAO,IAAI,CAAC,CAAC,CAAC;IAiB1C;;OAEG;IACH,IAAW,IAAI;QACX,OAAO,IAAI,CAAC,YAAY,CAAC;IAC7B,CAAC;IAEM,KAAK,CAAC,GAAG;QACZ,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS,EAAE;YAC5B,MAAM,OAAO,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,YAAY,EAAE,CAAC;YAC3C,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,YAAY,CAAC,aAAa,CAAC,OAAO,CAAC;iBAClD,IAAI,CAAe,CAAC,QAAQ,EAAE,EAAE;gBAC7B,IAAI,QAAQ,CAAC,QAAQ,KAAK,cAAc,EAAE;oBACtC,OAAO,QAAQ,CAAC,KAAqB,CAAC;iBACzC;gBACD,MAAM,sCAAmB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YACjD,CAAC,CAAC,CAAC;SACV;QACD,OAAO,IAAI,CAAC,OAAO,CAAC;IACxB,CAAC;IAEM,WAAW;QACd,OAAO;IACX,CAAC;IAEM,IAAI,CAAC,MAAoB;QAC5B,MAAM,CAAC,WAAW,EAAE,CAAC;IACzB,CAAC;IAEM,KAAK,CAAC,OAAO,CAAC,OAAiB;QAClC,IAAI;YACA,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,GAAG,EAAkB,CAAC;YAChD,MAAM,MAAM,GAAG,MAAM,CAAC,YAAY,CAAC;YAEnC,OAAO,MAAM,KAAK,SAAS;gBACvB,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC;gBACzB,CAAC,CAAC,oCAAiB,CAAC,OAAO,CAAC,CAAC;SACpC;QAAC,OAAO,KAAK,EAAE;YACZ,OAAO,sCAAmB,CAAC,KAAK,CAAC,CAAC;SACrC;IACL,CAAC;CACJ;AA7DD,0DA6DC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert } from \"@fluidframework/common-utils\";\nimport {\n IFluidObject,\n IFluidHandle,\n IFluidHandleContext,\n IRequest,\n IResponse,\n} from \"@fluidframework/core-interfaces\";\nimport { create404Response, exceptionToResponse, responseToException } from \"./dataStoreHelpers\";\n\n/**\n * This handle is used to dynamically load a Fluid object on a remote client and is created on parsing a serialized\n * FluidObjectHandle.\n * This class is used to generate an IFluidHandle when de-serializing any all handles (including handles to DDSs, custom\n * objects) that are stored in SharedObjects. The Data Store or SharedObject corresponding to the IFluidHandle can be\n * retrieved by calling `get` on it.\n */\nexport class RemoteFluidObjectHandle implements IFluidHandle {\n public get IFluidRouter() { return this; }\n public get IFluidHandleContext() { return this; }\n public get IFluidHandle() { return this; }\n\n public readonly isAttached = true;\n private objectP: Promise<IFluidObject> | undefined;\n\n /**\n * Creates a new RemoteFluidObjectHandle when parsing an IFluidHandle.\n * @param absolutePath - The absolute path to the handle from the container runtime.\n * @param routeContext - The root IFluidHandleContext that has a route to this handle.\n */\n constructor(\n public readonly absolutePath: string,\n public readonly routeContext: IFluidHandleContext,\n ) {\n assert(absolutePath.startsWith(\"/\"), \"Handles should always have absolute paths\");\n }\n\n /**\n * @deprecated - This returns the absolute path.\n */\n public get path() {\n return this.absolutePath;\n }\n\n public async get(): Promise<any> {\n if (this.objectP === undefined) {\n const request = { url: this.absolutePath };\n this.objectP = this.routeContext.resolveHandle(request)\n .then<IFluidObject>((response) => {\n if (response.mimeType === \"fluid/object\") {\n return response.value as IFluidObject;\n }\n throw responseToException(response, request);\n });\n }\n return this.objectP;\n }\n\n public attachGraph(): void {\n return;\n }\n\n public bind(handle: IFluidHandle): void {\n handle.attachGraph();\n }\n\n public async request(request: IRequest): Promise<IResponse> {\n try {\n const object = await this.get() as IFluidObject;\n const router = object.IFluidRouter;\n\n return router !== undefined\n ? router.request(request)\n : create404Response(request);\n } catch (error) {\n return exceptionToResponse(error);\n }\n }\n}\n"]} | ||
| {"version":3,"file":"remoteObjectHandle.js","sourceRoot":"","sources":["../src/remoteObjectHandle.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,+DAAsD;AAQtD,yDAAiG;AAEjG;;;;;;GAMG;AACH,MAAa,uBAAuB;IAQhC;;;;OAIG;IACH,YACoB,YAAoB,EACpB,YAAiC;QADjC,iBAAY,GAAZ,YAAY,CAAQ;QACpB,iBAAY,GAAZ,YAAY,CAAqB;QAVrC,eAAU,GAAG,IAAI,CAAC;QAY9B,qBAAM,CAAC,YAAY,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,KAAK,CAAC,iDAAiD,CAAC,CAAC;IAClG,CAAC;IAjBD,IAAW,YAAY,KAAK,OAAO,IAAI,CAAC,CAAC,CAAC;IAC1C,IAAW,mBAAmB,KAAK,OAAO,IAAI,CAAC,CAAC,CAAC;IACjD,IAAW,YAAY,KAAK,OAAO,IAAI,CAAC,CAAC,CAAC;IAiB1C;;OAEG;IACH,IAAW,IAAI;QACX,OAAO,IAAI,CAAC,YAAY,CAAC;IAC7B,CAAC;IAEM,KAAK,CAAC,GAAG;QACZ,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS,EAAE;YAC5B,MAAM,OAAO,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,YAAY,EAAE,CAAC;YAC3C,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,YAAY,CAAC,aAAa,CAAC,OAAO,CAAC;iBAClD,IAAI,CAAe,CAAC,QAAQ,EAAE,EAAE;gBAC7B,IAAI,QAAQ,CAAC,QAAQ,KAAK,cAAc,EAAE;oBACtC,OAAO,QAAQ,CAAC,KAAqB,CAAC;iBACzC;gBACD,MAAM,sCAAmB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YACjD,CAAC,CAAC,CAAC;SACV;QACD,OAAO,IAAI,CAAC,OAAO,CAAC;IACxB,CAAC;IAEM,WAAW;QACd,OAAO;IACX,CAAC;IAEM,IAAI,CAAC,MAAoB;QAC5B,MAAM,CAAC,WAAW,EAAE,CAAC;IACzB,CAAC;IAEM,KAAK,CAAC,OAAO,CAAC,OAAiB;QAClC,IAAI;YACA,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,GAAG,EAAkB,CAAC;YAChD,MAAM,MAAM,GAAG,MAAM,CAAC,YAAY,CAAC;YAEnC,OAAO,MAAM,KAAK,SAAS;gBACvB,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC;gBACzB,CAAC,CAAC,oCAAiB,CAAC,OAAO,CAAC,CAAC;SACpC;QAAC,OAAO,KAAK,EAAE;YACZ,OAAO,sCAAmB,CAAC,KAAK,CAAC,CAAC;SACrC;IACL,CAAC;CACJ;AA7DD,0DA6DC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert } from \"@fluidframework/common-utils\";\nimport {\n IFluidObject,\n IFluidHandle,\n IFluidHandleContext,\n IRequest,\n IResponse,\n} from \"@fluidframework/core-interfaces\";\nimport { create404Response, exceptionToResponse, responseToException } from \"./dataStoreHelpers\";\n\n/**\n * This handle is used to dynamically load a Fluid object on a remote client and is created on parsing a serialized\n * FluidObjectHandle.\n * This class is used to generate an IFluidHandle when de-serializing any all handles (including handles to DDSs, custom\n * objects) that are stored in SharedObjects. The Data Store or SharedObject corresponding to the IFluidHandle can be\n * retrieved by calling `get` on it.\n */\nexport class RemoteFluidObjectHandle implements IFluidHandle {\n public get IFluidRouter() { return this; }\n public get IFluidHandleContext() { return this; }\n public get IFluidHandle() { return this; }\n\n public readonly isAttached = true;\n private objectP: Promise<IFluidObject> | undefined;\n\n /**\n * Creates a new RemoteFluidObjectHandle when parsing an IFluidHandle.\n * @param absolutePath - The absolute path to the handle from the container runtime.\n * @param routeContext - The root IFluidHandleContext that has a route to this handle.\n */\n constructor(\n public readonly absolutePath: string,\n public readonly routeContext: IFluidHandleContext,\n ) {\n assert(absolutePath.startsWith(\"/\"), 0x19d /* \"Handles should always have absolute paths\" */);\n }\n\n /**\n * @deprecated - This returns the absolute path.\n */\n public get path() {\n return this.absolutePath;\n }\n\n public async get(): Promise<any> {\n if (this.objectP === undefined) {\n const request = { url: this.absolutePath };\n this.objectP = this.routeContext.resolveHandle(request)\n .then<IFluidObject>((response) => {\n if (response.mimeType === \"fluid/object\") {\n return response.value as IFluidObject;\n }\n throw responseToException(response, request);\n });\n }\n return this.objectP;\n }\n\n public attachGraph(): void {\n return;\n }\n\n public bind(handle: IFluidHandle): void {\n handle.attachGraph();\n }\n\n public async request(request: IRequest): Promise<IResponse> {\n try {\n const object = await this.get() as IFluidObject;\n const router = object.IFluidRouter;\n\n return router !== undefined\n ? router.request(request)\n : create404Response(request);\n } catch (error) {\n return exceptionToResponse(error);\n }\n }\n}\n"]} |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"summarizerNode.d.ts","sourceRoot":"","sources":["../../src/summarizerNode/summarizerNode.ts"],"names":[],"mappings":"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"} | ||
| {"version":3,"file":"summarizerNode.d.ts","sourceRoot":"","sources":["../../src/summarizerNode/summarizerNode.ts"],"names":[],"mappings":"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"} |
@@ -60,4 +60,4 @@ "use strict"; | ||
| startSummary(referenceSequenceNumber, summaryLogger) { | ||
| common_utils_1.assert(this.wipSummaryLogger === undefined, "wipSummaryLogger should not be set yet in startSummary"); | ||
| common_utils_1.assert(this.wipReferenceSequenceNumber === undefined, "Already tracking a summary"); | ||
| common_utils_1.assert(this.wipSummaryLogger === undefined, 0x19f /* "wipSummaryLogger should not be set yet in startSummary" */); | ||
| common_utils_1.assert(this.wipReferenceSequenceNumber === undefined, 0x1a0 /* "Already tracking a summary" */); | ||
| this.wipSummaryLogger = summaryLogger; | ||
@@ -70,4 +70,4 @@ for (const child of this.children.values()) { | ||
| async summarize(fullTree) { | ||
| common_utils_1.assert(this.isTrackingInProgress(), "summarize should not be called when not tracking the summary"); | ||
| common_utils_1.assert(this.wipSummaryLogger !== undefined, "wipSummaryLogger should have been set in startSummary or ctor"); | ||
| common_utils_1.assert(this.isTrackingInProgress(), 0x1a1 /* "summarize should not be called when not tracking the summary" */); | ||
| common_utils_1.assert(this.wipSummaryLogger !== undefined, 0x1a2 /* "wipSummaryLogger should have been set in startSummary or ctor" */); | ||
| // Try to reuse the tree if unchanged | ||
@@ -152,4 +152,4 @@ if (this.canReuseHandle && !fullTree && !this.hasChanged()) { | ||
| completeSummaryCore(proposalHandle, parentPath, parentSkipRecursion) { | ||
| common_utils_1.assert(this.wipSummaryLogger !== undefined, "wipSummaryLogger should have been set in startSummary or ctor"); | ||
| common_utils_1.assert(this.wipReferenceSequenceNumber !== undefined, "Not tracking a summary"); | ||
| common_utils_1.assert(this.wipSummaryLogger !== undefined, 0x1a3 /* "wipSummaryLogger should have been set in startSummary or ctor" */); | ||
| common_utils_1.assert(this.wipReferenceSequenceNumber !== undefined, 0x1a4 /* "Not tracking a summary" */); | ||
| let localPathsToUse = this.wipLocalPaths; | ||
@@ -184,3 +184,3 @@ if (parentSkipRecursion) { | ||
| // If there is no latestSummary, clearSummary and return before reaching this code. | ||
| common_utils_1.assert(!!localPathsToUse, "Tracked summary local paths not set"); | ||
| common_utils_1.assert(!!localPathsToUse, 0x1a5 /* "Tracked summary local paths not set" */); | ||
| const summary = new summarizerNodeUtils_1.SummaryNode(Object.assign(Object.assign({}, localPathsToUse), { referenceSequenceNumber: this.wipReferenceSequenceNumber, basePath: parentPath })); | ||
@@ -225,3 +225,3 @@ const fullPathForChildren = summary.fullPathForChildren; | ||
| // This should only happen if parent skipped recursion AND no prior summary existed. | ||
| common_utils_1.assert(this.latestSummary === undefined, "Not found pending summary, but this node has previously completed a summary"); | ||
| common_utils_1.assert(this.latestSummary === undefined, 0x1a6 /* "Not found pending summary, but this node has previously completed a summary" */); | ||
| return; | ||
@@ -232,3 +232,3 @@ } | ||
| // eslint-disable-next-line max-len | ||
| `Pending summary reference sequence number should be consistent: ${summaryNode.referenceSequenceNumber} != ${referenceSequenceNumber}`); | ||
| 0x1a7 /* `Pending summary reference sequence number should be consistent: ${summaryNode.referenceSequenceNumber} != ${referenceSequenceNumber}` */); | ||
| // Clear earlier pending summaries | ||
@@ -308,3 +308,3 @@ this.pendingSummaries.delete(proposalHandle); | ||
| const newOpsLatestSeq = outstandingOps[outstandingOps.length - 1].sequenceNumber; | ||
| common_utils_1.assert(newOpsLatestSeq <= this.trackingSequenceNumber, "When loading base summary, expected outstanding ops <= tracking sequence number"); | ||
| common_utils_1.assert(newOpsLatestSeq <= this.trackingSequenceNumber, 0x1a9 /* "When loading base summary, expected outstanding ops <= tracking sequence number" */); | ||
| } | ||
@@ -319,3 +319,3 @@ return { | ||
| if (lastOp !== undefined) { | ||
| common_utils_1.assert(lastOp.sequenceNumber < op.sequenceNumber, `Out of order change recorded: ${lastOp.sequenceNumber} > ${op.sequenceNumber}`); | ||
| common_utils_1.assert(lastOp.sequenceNumber < op.sequenceNumber, 0x1aa /* `Out of order change recorded: ${lastOp.sequenceNumber} > ${op.sequenceNumber}` */); | ||
| } | ||
@@ -350,3 +350,3 @@ this.invalidate(op.sequenceNumber); | ||
| createParam, config = {}) { | ||
| common_utils_1.assert(!this.children.has(id), "Create SummarizerNode child already exists"); | ||
| common_utils_1.assert(!this.children.has(id), 0x1ab /* "Create SummarizerNode child already exists" */); | ||
| const createDetails = this.getCreateDetailsForChild(id, createParam); | ||
@@ -395,3 +395,3 @@ const child = new SummarizerNode(this.defaultLogger, summarizeInternalFn, config, createDetails.changeSequenceNumber, createDetails.latestSummary, createDetails.initialSummary, this.wipSummaryLogger); | ||
| if (this.initialSummary === undefined) { | ||
| common_utils_1.assert(!!parentLatestSummary, "Cannot create child from summary if parent does not have latest summary"); | ||
| common_utils_1.assert(!!parentLatestSummary, 0x1ac /* "Cannot create child from summary if parent does not have latest summary" */); | ||
| } | ||
@@ -406,3 +406,3 @@ // fallthrough to local | ||
| const { childrenTree } = summarizerNodeUtils_1.parseSummaryTreeForSubtrees(parentInitialSummary.summary.summary); | ||
| common_utils_1.assert(childrenTree.type === 1 /* Tree */, "Parent summary object is not a tree"); | ||
| common_utils_1.assert(childrenTree.type === 1 /* Tree */, 0x1d6 /* "Parent summary object is not a tree" */); | ||
| childSummary = childrenTree.tree[id]; | ||
@@ -412,7 +412,7 @@ } | ||
| // Locally created would not have differential subtree. | ||
| common_utils_1.assert(!!childSummary, "Missing child summary tree"); | ||
| common_utils_1.assert(!!childSummary, 0x1ad /* "Missing child summary tree" */); | ||
| } | ||
| let childSummaryWithStats; | ||
| if (childSummary !== undefined) { | ||
| common_utils_1.assert(childSummary.type === 1 /* Tree */, "Child summary object is not a tree"); | ||
| common_utils_1.assert(childSummary.type === 1 /* Tree */, 0x1ae /* "Child summary object is not a tree" */); | ||
| childSummaryWithStats = { | ||
@@ -419,0 +419,0 @@ summary: childSummary, |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"summarizerNode.js","sourceRoot":"","sources":["../../src/summarizerNode/summarizerNode.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport {\n ISummarizerNode,\n ISummarizerNodeConfig,\n ISummarizeInternalResult,\n ISummarizeResult,\n ISummaryTreeWithStats,\n CreateChildSummarizerNodeParam,\n CreateSummarizerNodeSource,\n} from \"@fluidframework/runtime-definitions\";\nimport {\n ISequencedDocumentMessage,\n SummaryType,\n ISnapshotTree,\n SummaryObject,\n} from \"@fluidframework/protocol-definitions\";\nimport { ITelemetryLogger } from \"@fluidframework/common-definitions\";\nimport { assert, unreachableCase } from \"@fluidframework/common-utils\";\nimport { mergeStats, convertToSummaryTree, calculateStats } from \"../summaryUtils\";\nimport {\n decodeSummary,\n encodeSummary,\n EncodeSummaryParam,\n EscapedPath,\n ICreateChildDetails,\n IInitialSummary,\n ISummarizerNodeRootContract,\n parseSummaryForSubtrees,\n parseSummaryTreeForSubtrees,\n ReadAndParseBlob,\n seqFromTree,\n SummaryNode,\n} from \"./summarizerNodeUtils\";\n\nexport interface IRootSummarizerNode extends ISummarizerNode, ISummarizerNodeRootContract {}\n\n/**\n * Encapsulates the summarizing work and state of an individual tree node in the\n * summary tree. It tracks changes and allows for optimizations when unchanged, or\n * can allow for fallback summaries to be generated when an error is encountered.\n * Usage is for the root node to call startSummary first to begin tracking a WIP\n * (work in progress) summary. Then all nodes will call summarize to summaries their\n * individual parts. Once completed and uploaded to storage, the root node will call\n * completeSummary or clearSummary to clear the WIP summary tracking state if something\n * went wrong. The SummarizerNodes will track all pending summaries that have been\n * recorded by the completeSummary call. When one of them is acked, the root node should\n * call refreshLatestSummary to inform the tree of SummarizerNodes of the new baseline\n * latest successful summary.\n */\nexport class SummarizerNode implements IRootSummarizerNode {\n /**\n * The reference sequence number of the most recent acked summary.\n * Returns 0 if there is not yet an acked summary.\n */\n public get referenceSequenceNumber() {\n return this.latestSummary?.referenceSequenceNumber ?? 0;\n }\n\n protected readonly children = new Map<string, SummarizerNode>();\n protected readonly pendingSummaries = new Map<string, SummaryNode>();\n private readonly outstandingOps: ISequencedDocumentMessage[] = [];\n private wipReferenceSequenceNumber: number | undefined;\n private wipLocalPaths: { localPath: EscapedPath, additionalPath?: EscapedPath } | undefined;\n private wipSkipRecursion = false;\n\n public startSummary(referenceSequenceNumber: number, summaryLogger: ITelemetryLogger) {\n assert(this.wipSummaryLogger === undefined, \"wipSummaryLogger should not be set yet in startSummary\");\n assert(this.wipReferenceSequenceNumber === undefined, \"Already tracking a summary\");\n\n this.wipSummaryLogger = summaryLogger;\n\n for (const child of this.children.values()) {\n child.startSummary(referenceSequenceNumber, this.wipSummaryLogger);\n }\n this.wipReferenceSequenceNumber = referenceSequenceNumber;\n }\n\n public async summarize(fullTree: boolean): Promise<ISummarizeResult> {\n assert(this.isTrackingInProgress(), \"summarize should not be called when not tracking the summary\");\n assert(this.wipSummaryLogger !== undefined, \"wipSummaryLogger should have been set in startSummary or ctor\");\n\n // Try to reuse the tree if unchanged\n if (this.canReuseHandle && !fullTree && !this.hasChanged()) {\n const latestSummary = this.latestSummary;\n if (latestSummary !== undefined) {\n this.wipLocalPaths = {\n localPath: latestSummary.localPath,\n additionalPath: latestSummary.additionalPath,\n };\n this.wipSkipRecursion = true;\n const stats = mergeStats();\n stats.handleNodeCount++;\n return {\n summary: {\n type: SummaryType.Handle,\n handle: latestSummary.fullPath.path,\n handleType: SummaryType.Tree,\n },\n stats,\n };\n }\n }\n\n try {\n const result = await this.summarizeInternalFn(fullTree);\n this.wipLocalPaths = { localPath: EscapedPath.create(result.id) };\n if (result.pathPartsForChildren !== undefined) {\n this.wipLocalPaths.additionalPath = EscapedPath.createAndConcat(result.pathPartsForChildren);\n }\n return { summary: result.summary, stats: result.stats };\n } catch (error) {\n if (this.throwOnError || this.trackingSequenceNumber < this._changeSequenceNumber) {\n throw error;\n }\n const latestSummary = this.latestSummary;\n const initialSummary = this.initialSummary;\n\n let encodeParam: EncodeSummaryParam;\n let localPath: EscapedPath;\n if (latestSummary !== undefined) {\n // Create using handle of latest acked summary\n encodeParam = {\n fromSummary: true,\n summaryNode: latestSummary,\n };\n localPath = latestSummary.localPath;\n } else if (initialSummary?.summary !== undefined) {\n // Create using initial summary from attach op\n encodeParam = {\n fromSummary: false,\n initialSummary: initialSummary.summary,\n };\n localPath = EscapedPath.create(initialSummary.id);\n } else {\n // No base summary to reference\n throw error;\n }\n this.wipSummaryLogger.sendErrorEvent({\n eventName: \"SummarizingWithBasePlusOps\",\n },\n error);\n const summary = encodeSummary(encodeParam, this.outstandingOps);\n this.wipLocalPaths = {\n localPath,\n additionalPath: summary.additionalPath,\n };\n this.wipSkipRecursion = true;\n return { summary: summary.summary, stats: summary.stats };\n }\n }\n\n /**\n * Complete the WIP summary for the given proposalHandle\n */\n public completeSummary(proposalHandle: string) {\n this.completeSummaryCore(proposalHandle, undefined, false);\n }\n\n /**\n * Recursive implementation for completeSummary, with additional internal-only parameters\n */\n protected completeSummaryCore(\n proposalHandle: string,\n parentPath: EscapedPath | undefined,\n parentSkipRecursion: boolean,\n ) {\n assert(this.wipSummaryLogger !== undefined, \"wipSummaryLogger should have been set in startSummary or ctor\");\n assert(this.wipReferenceSequenceNumber !== undefined, \"Not tracking a summary\");\n let localPathsToUse = this.wipLocalPaths;\n\n if (parentSkipRecursion) {\n const latestSummary = this.latestSummary;\n if (latestSummary !== undefined) {\n // This case the parent node created a failure summary or was reused.\n // This node and all children should only try to reference their path\n // by its last known good state in the actual summary tree.\n // If parent fails or is reused, the child summarize is not called so\n // it did not get a chance to change its paths.\n // In this case, essentially only propagate the new summary ref seq num.\n localPathsToUse = {\n localPath: latestSummary.localPath,\n additionalPath: latestSummary.additionalPath,\n };\n } else {\n // This case the child is added after the latest non-failure summary.\n // This node and all children should consider themselves as still not\n // having a successful summary yet.\n // We cannot \"reuse\" this node if unchanged since that summary, because\n // handles will be unable to point to that node. It never made it to the\n // tree itself, and only exists as an attach op in the _outstandingOps.\n this.clearSummary();\n return;\n }\n }\n\n // This should come from wipLocalPaths in normal cases, or from the latestSummary\n // if parentIsFailure or parentIsReused is true.\n // If there is no latestSummary, clearSummary and return before reaching this code.\n assert(!!localPathsToUse, \"Tracked summary local paths not set\");\n\n const summary = new SummaryNode({\n ...localPathsToUse,\n referenceSequenceNumber: this.wipReferenceSequenceNumber,\n basePath: parentPath,\n });\n const fullPathForChildren = summary.fullPathForChildren;\n for (const child of this.children.values()) {\n child.completeSummaryCore(\n proposalHandle,\n fullPathForChildren,\n this.wipSkipRecursion || parentSkipRecursion,\n );\n }\n // Note that this overwrites existing pending summary with\n // the same proposalHandle. If proposalHandle is something like\n // a hash or unique identifier, this should be fine. If storage\n // can return the same proposalHandle for a different summary,\n // this should still be okay, because we should be proposing the\n // newer one later which would have to overwrite the previous one.\n this.pendingSummaries.set(proposalHandle, summary);\n this.clearSummary();\n }\n\n public clearSummary() {\n this.wipReferenceSequenceNumber = undefined;\n this.wipLocalPaths = undefined;\n this.wipSkipRecursion = false;\n this.wipSummaryLogger = undefined;\n for (const child of this.children.values()) {\n child.clearSummary();\n }\n }\n\n public async refreshLatestSummary(\n proposalHandle: string | undefined,\n getSnapshot: () => Promise<ISnapshotTree>,\n readAndParseBlob: ReadAndParseBlob,\n correlatedSummaryLogger: ITelemetryLogger,\n ): Promise<void> {\n if (proposalHandle !== undefined) {\n const maybeSummaryNode = this.pendingSummaries.get(proposalHandle);\n\n if (maybeSummaryNode !== undefined) {\n this.refreshLatestSummaryFromPending(proposalHandle, maybeSummaryNode.referenceSequenceNumber);\n return;\n }\n }\n\n const snapshotTree = await getSnapshot();\n const referenceSequenceNumber = await seqFromTree(snapshotTree, readAndParseBlob);\n await this.refreshLatestSummaryFromSnapshot(\n referenceSequenceNumber,\n snapshotTree,\n undefined,\n EscapedPath.create(\"\"),\n correlatedSummaryLogger,\n readAndParseBlob,\n );\n }\n\n protected refreshLatestSummaryFromPending(\n proposalHandle: string,\n referenceSequenceNumber: number,\n ): void {\n const summaryNode = this.pendingSummaries.get(proposalHandle);\n if (summaryNode === undefined) {\n // This should only happen if parent skipped recursion AND no prior summary existed.\n assert(\n this.latestSummary === undefined,\n \"Not found pending summary, but this node has previously completed a summary\",\n );\n return;\n } else {\n assert(\n referenceSequenceNumber === summaryNode.referenceSequenceNumber,\n // eslint-disable-next-line max-len\n `Pending summary reference sequence number should be consistent: ${summaryNode.referenceSequenceNumber} != ${referenceSequenceNumber}`,\n );\n\n // Clear earlier pending summaries\n this.pendingSummaries.delete(proposalHandle);\n }\n\n this.refreshLatestSummaryCore(referenceSequenceNumber);\n\n this.latestSummary = summaryNode;\n\n // Propagate update to all child nodes\n for (const child of this.children.values()) {\n child.refreshLatestSummaryFromPending(proposalHandle, referenceSequenceNumber);\n }\n }\n\n protected async refreshLatestSummaryFromSnapshot(\n referenceSequenceNumber: number,\n snapshotTree: ISnapshotTree,\n basePath: EscapedPath | undefined,\n localPath: EscapedPath,\n correlatedSummaryLogger: ITelemetryLogger,\n readAndParseBlob: ReadAndParseBlob,\n ): Promise<void> {\n // Possible re-entrancy. If we have already seen a summary later than this one, ignore it.\n if (this.referenceSequenceNumber >= referenceSequenceNumber) {\n return;\n }\n\n this.refreshLatestSummaryCore(referenceSequenceNumber);\n\n const { baseSummary, pathParts } = decodeSummary(snapshotTree, correlatedSummaryLogger);\n\n this.latestSummary = new SummaryNode({\n referenceSequenceNumber,\n basePath,\n localPath,\n });\n\n const { childrenTree, childrenPathPart } = parseSummaryForSubtrees(baseSummary);\n if (childrenPathPart !== undefined) {\n pathParts.push(childrenPathPart);\n }\n\n if (pathParts.length > 0) {\n this.latestSummary.additionalPath = EscapedPath.createAndConcat(pathParts);\n }\n\n // Propagate update to all child nodes\n const pathForChildren = this.latestSummary.fullPathForChildren;\n await Promise.all(Array.from(this.children)\n .filter(([id]) => {\n // Assuming subtrees missing from snapshot are newer than the snapshot,\n // but might be nice to assert this using earliest seq for node.\n return childrenTree.trees[id] !== undefined;\n }).map(async ([id, child]) => {\n return child.refreshLatestSummaryFromSnapshot(\n referenceSequenceNumber,\n childrenTree.trees[id],\n pathForChildren,\n EscapedPath.create(id),\n correlatedSummaryLogger,\n readAndParseBlob,\n );\n }));\n }\n\n private refreshLatestSummaryCore(referenceSequenceNumber: number): void {\n for (const [key, value] of this.pendingSummaries) {\n if (value.referenceSequenceNumber < referenceSequenceNumber) {\n this.pendingSummaries.delete(key);\n }\n }\n\n // Clear earlier outstanding ops\n while (\n this.outstandingOps.length > 0\n && this.outstandingOps[0].sequenceNumber <= referenceSequenceNumber\n ) {\n this.outstandingOps.shift();\n }\n }\n\n public loadBaseSummaryWithoutDifferential(snapshot: ISnapshotTree) {\n // Check base summary to see if it has any additional path parts\n // separating child SummarizerNodes. Checks for .channels subtrees.\n const { childrenPathPart } = parseSummaryForSubtrees(snapshot);\n if (childrenPathPart !== undefined && this.latestSummary !== undefined) {\n this.latestSummary.additionalPath = EscapedPath.create(childrenPathPart);\n }\n }\n\n public async loadBaseSummary(\n snapshot: ISnapshotTree,\n readAndParseBlob: ReadAndParseBlob,\n ): Promise<{ baseSummary: ISnapshotTree, outstandingOps: ISequencedDocumentMessage[] }> {\n const decodedSummary = decodeSummary(snapshot, this.defaultLogger);\n const outstandingOps = await decodedSummary.getOutstandingOps(readAndParseBlob);\n\n const { childrenPathPart } = parseSummaryForSubtrees(decodedSummary.baseSummary);\n if (childrenPathPart !== undefined) {\n decodedSummary.pathParts.push(childrenPathPart);\n }\n\n if (decodedSummary.pathParts.length > 0 && this.latestSummary !== undefined) {\n this.latestSummary.additionalPath = EscapedPath.createAndConcat(decodedSummary.pathParts);\n }\n\n // Defensive assertion: tracking number should already exceed this number.\n // This is probably a little excessive; can remove when stable.\n if (outstandingOps.length > 0) {\n const newOpsLatestSeq = outstandingOps[outstandingOps.length - 1].sequenceNumber;\n assert(\n newOpsLatestSeq <= this.trackingSequenceNumber,\n \"When loading base summary, expected outstanding ops <= tracking sequence number\",\n );\n }\n\n return {\n baseSummary: decodedSummary.baseSummary,\n outstandingOps,\n };\n }\n\n public recordChange(op: ISequencedDocumentMessage): void {\n const lastOp = this.outstandingOps[this.outstandingOps.length - 1];\n if (lastOp !== undefined) {\n assert(\n lastOp.sequenceNumber < op.sequenceNumber,\n `Out of order change recorded: ${lastOp.sequenceNumber} > ${op.sequenceNumber}`,\n );\n }\n this.invalidate(op.sequenceNumber);\n this.trackingSequenceNumber = op.sequenceNumber;\n this.outstandingOps.push(op);\n }\n\n public invalidate(sequenceNumber: number): void {\n if (sequenceNumber > this._changeSequenceNumber) {\n this._changeSequenceNumber = sequenceNumber;\n }\n }\n\n /**\n * True if a change has been recorded with sequence number exceeding\n * the latest successfully acked summary reference sequence number.\n * False implies that the previous summary can be reused.\n */\n protected hasChanged(): boolean {\n return this._changeSequenceNumber > this.referenceSequenceNumber;\n }\n\n private readonly canReuseHandle: boolean;\n private readonly throwOnError: boolean;\n private trackingSequenceNumber: number;\n\n /**\n * Do not call constructor directly.\n * Use createRootSummarizerNode to create root node, or createChild to create child nodes.\n */\n public constructor(\n protected readonly defaultLogger: ITelemetryLogger,\n private readonly summarizeInternalFn: (fullTree: boolean) => Promise<ISummarizeInternalResult>,\n config: ISummarizerNodeConfig,\n private _changeSequenceNumber: number,\n /** Undefined means created without summary */\n private latestSummary?: SummaryNode,\n private readonly initialSummary?: IInitialSummary,\n protected wipSummaryLogger?: ITelemetryLogger,\n ) {\n this.canReuseHandle = config.canReuseHandle ?? true;\n // BUGBUG: Seeing issues with differential summaries.\n // this will disable them, and throw instead\n // while we continue to investigate\n this.throwOnError = true; // config.throwOnFailure ?? false;\n this.trackingSequenceNumber = this._changeSequenceNumber;\n }\n\n public createChild(\n /** Summarize function */\n summarizeInternalFn: (fullTree: boolean) => Promise<ISummarizeInternalResult>,\n /** Initial id or path part of this node */\n id: string,\n /**\n * Information needed to create the node.\n * If it is from a base summary, it will assert that a summary has been seen.\n * Attach information if it is created from an attach op.\n */\n createParam: CreateChildSummarizerNodeParam,\n config: ISummarizerNodeConfig = {},\n ): ISummarizerNode {\n assert(!this.children.has(id), \"Create SummarizerNode child already exists\");\n\n const createDetails: ICreateChildDetails = this.getCreateDetailsForChild(id, createParam);\n const child = new SummarizerNode(\n this.defaultLogger,\n summarizeInternalFn,\n config,\n createDetails.changeSequenceNumber,\n createDetails.latestSummary,\n createDetails.initialSummary,\n this.wipSummaryLogger,\n );\n\n // There may be additional state that has to be updated in this child. For example, if a summary is being\n // tracked, the child's summary tracking state needs to be updated too.\n this.maybeUpdateChildState(child);\n\n this.children.set(id, child);\n return child;\n }\n\n public getChild(id: string): ISummarizerNode | undefined {\n return this.children.get(id);\n }\n\n /**\n * Returns the details needed to create a child node.\n * @param id - Initial id or path part of the child node.\n * @param createParam - Information needed to create the node.\n * @returns the details needed to create the child node.\n */\n protected getCreateDetailsForChild(id: string, createParam: CreateChildSummarizerNodeParam): ICreateChildDetails {\n let initialSummary: IInitialSummary | undefined;\n let latestSummary: SummaryNode | undefined;\n let changeSequenceNumber: number;\n\n const parentLatestSummary = this.latestSummary;\n switch (createParam.type) {\n case CreateSummarizerNodeSource.FromAttach: {\n if (\n parentLatestSummary !== undefined\n && createParam.sequenceNumber <= parentLatestSummary.referenceSequenceNumber\n ) {\n // Prioritize latest summary if it was after this node was attached.\n latestSummary = parentLatestSummary.createForChild(id);\n } else {\n const summary = convertToSummaryTree(createParam.snapshot) as ISummaryTreeWithStats;\n initialSummary = {\n sequenceNumber: createParam.sequenceNumber,\n id,\n summary,\n };\n }\n changeSequenceNumber = createParam.sequenceNumber;\n break;\n }\n case CreateSummarizerNodeSource.FromSummary: {\n if (this.initialSummary === undefined) {\n assert(\n !!parentLatestSummary,\n \"Cannot create child from summary if parent does not have latest summary\");\n }\n // fallthrough to local\n }\n case CreateSummarizerNodeSource.Local: {\n const parentInitialSummary = this.initialSummary;\n if (parentInitialSummary !== undefined) {\n let childSummary: SummaryObject | undefined;\n if (parentInitialSummary.summary !== undefined) {\n const { childrenTree } = parseSummaryTreeForSubtrees(parentInitialSummary.summary.summary);\n assert(\n childrenTree.type === SummaryType.Tree,\n \"Parent summary object is not a tree\",\n );\n childSummary = childrenTree.tree[id];\n }\n if (createParam.type === CreateSummarizerNodeSource.FromSummary) {\n // Locally created would not have differential subtree.\n assert(!!childSummary, \"Missing child summary tree\");\n }\n let childSummaryWithStats: ISummaryTreeWithStats | undefined;\n if (childSummary !== undefined) {\n assert(\n childSummary.type === SummaryType.Tree,\n \"Child summary object is not a tree\",\n );\n childSummaryWithStats = {\n summary: childSummary,\n stats: calculateStats(childSummary),\n };\n }\n initialSummary = {\n sequenceNumber: parentInitialSummary.sequenceNumber,\n id,\n summary: childSummaryWithStats,\n };\n }\n latestSummary = parentLatestSummary?.createForChild(id);\n changeSequenceNumber = parentLatestSummary?.referenceSequenceNumber ?? -1;\n break;\n }\n default: {\n const type = (createParam as unknown as CreateChildSummarizerNodeParam).type;\n unreachableCase(createParam, `Unexpected CreateSummarizerNodeSource: ${type}`);\n }\n }\n\n return {\n initialSummary,\n latestSummary,\n changeSequenceNumber,\n };\n }\n\n /**\n * Updates the state of the child if required. For example, if a summary is currently being tracked, the child's\n * summary tracking state needs to be updated too.\n * @param child - The child node whose state is to be updated.\n */\n protected maybeUpdateChildState(child: SummarizerNode) {\n // If we are tracking a summary, this child was created after the tracking started. So, we need to update the\n // child's tracking state as well.\n if (this.isTrackingInProgress()) {\n child.wipReferenceSequenceNumber = this.wipReferenceSequenceNumber;\n }\n }\n\n /**\n * Tells whether summary tracking is in progress. True if \"startSummary\" API is called before summarize.\n */\n protected isTrackingInProgress(): boolean {\n return this.wipReferenceSequenceNumber !== undefined;\n }\n}\n\n/**\n * Creates a root summarizer node.\n * @param logger - Logger to use within SummarizerNode\n * @param summarizeInternalFn - Function to generate summary\n * @param changeSequenceNumber - Sequence number of latest change to new node/subtree\n * @param referenceSequenceNumber - Reference sequence number of last acked summary,\n * or undefined if not loaded from summary\n * @param config - Configure behavior of summarizer node\n */\nexport const createRootSummarizerNode = (\n logger: ITelemetryLogger,\n summarizeInternalFn: (fullTree: boolean) => Promise<ISummarizeInternalResult>,\n changeSequenceNumber: number,\n referenceSequenceNumber: number | undefined,\n config: ISummarizerNodeConfig = {},\n): IRootSummarizerNode => new SummarizerNode(\n logger,\n summarizeInternalFn,\n config,\n changeSequenceNumber,\n referenceSequenceNumber === undefined ? undefined : SummaryNode.createForRoot(referenceSequenceNumber),\n );\n"]} | ||
| {"version":3,"file":"summarizerNode.js","sourceRoot":"","sources":["../../src/summarizerNode/summarizerNode.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,6EAQ6C;AAQ7C,+DAAuE;AACvE,kDAAmF;AACnF,+DAa+B;AAI/B;;;;;;;;;;;;GAYG;AACH,MAAa,cAAc;IAmYvB;;;OAGG;IACH,YACuB,aAA+B,EACjC,mBAA6E,EAC9F,MAA6B,EACrB,qBAA6B;IACrC,8CAA8C;IACtC,aAA2B,EAClB,cAAgC,EACvC,gBAAmC;;QAP1B,kBAAa,GAAb,aAAa,CAAkB;QACjC,wBAAmB,GAAnB,mBAAmB,CAA0D;QAEtF,0BAAqB,GAArB,qBAAqB,CAAQ;QAE7B,kBAAa,GAAb,aAAa,CAAc;QAClB,mBAAc,GAAd,cAAc,CAAkB;QACvC,qBAAgB,GAAhB,gBAAgB,CAAmB;QAtY9B,aAAQ,GAAG,IAAI,GAAG,EAA0B,CAAC;QAC7C,qBAAgB,GAAG,IAAI,GAAG,EAAuB,CAAC;QACpD,mBAAc,GAAgC,EAAE,CAAC;QAG1D,qBAAgB,GAAG,KAAK,CAAC;QAmY7B,IAAI,CAAC,cAAc,SAAG,MAAM,CAAC,cAAc,mCAAI,IAAI,CAAC;QACpD,qDAAqD;QACrD,4CAA4C;QAC5C,mCAAmC;QACnC,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,CAAC,kCAAkC;QAC5D,IAAI,CAAC,sBAAsB,GAAG,IAAI,CAAC,qBAAqB,CAAC;IAC7D,CAAC;IAtZD;;;OAGG;IACH,IAAW,uBAAuB;;QAC9B,mBAAO,IAAI,CAAC,aAAa,0CAAE,uBAAuB,mCAAI,CAAC,CAAC;IAC5D,CAAC;IASM,YAAY,CAAC,uBAA+B,EAAE,aAA+B;QAChF,qBAAM,CAAC,IAAI,CAAC,gBAAgB,KAAK,SAAS,EACtC,KAAK,CAAC,8DAA8D,CAAC,CAAC;QAC1E,qBAAM,CAAC,IAAI,CAAC,0BAA0B,KAAK,SAAS,EAAE,KAAK,CAAC,kCAAkC,CAAC,CAAC;QAEhG,IAAI,CAAC,gBAAgB,GAAG,aAAa,CAAC;QAEtC,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAE;YACxC,KAAK,CAAC,YAAY,CAAC,uBAAuB,EAAE,IAAI,CAAC,gBAAgB,CAAC,CAAC;SACtE;QACD,IAAI,CAAC,0BAA0B,GAAG,uBAAuB,CAAC;IAC9D,CAAC;IAEM,KAAK,CAAC,SAAS,CAAC,QAAiB;QACpC,qBAAM,CAAC,IAAI,CAAC,oBAAoB,EAAE,EAAE,KAAK,CAAC,oEAAoE,CAAC,CAAC;QAChH,qBAAM,CAAC,IAAI,CAAC,gBAAgB,KAAK,SAAS,EACtC,KAAK,CAAC,qEAAqE,CAAC,CAAC;QAEjF,qCAAqC;QACrC,IAAI,IAAI,CAAC,cAAc,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE;YACxD,MAAM,aAAa,GAAG,IAAI,CAAC,aAAa,CAAC;YACzC,IAAI,aAAa,KAAK,SAAS,EAAE;gBAC7B,IAAI,CAAC,aAAa,GAAG;oBACjB,SAAS,EAAE,aAAa,CAAC,SAAS;oBAClC,cAAc,EAAE,aAAa,CAAC,cAAc;iBAC/C,CAAC;gBACF,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;gBAC7B,MAAM,KAAK,GAAG,yBAAU,EAAE,CAAC;gBAC3B,KAAK,CAAC,eAAe,EAAE,CAAC;gBACxB,OAAO;oBACH,OAAO,EAAE;wBACL,IAAI,gBAAoB;wBACxB,MAAM,EAAE,aAAa,CAAC,QAAQ,CAAC,IAAI;wBACnC,UAAU,cAAkB;qBAC/B;oBACD,KAAK;iBACR,CAAC;aACL;SACJ;QAED,IAAI;YACA,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,mBAAmB,CAAC,QAAQ,CAAC,CAAC;YACxD,IAAI,CAAC,aAAa,GAAG,EAAE,SAAS,EAAE,iCAAW,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC;YAClE,IAAI,MAAM,CAAC,oBAAoB,KAAK,SAAS,EAAE;gBAC3C,IAAI,CAAC,aAAa,CAAC,cAAc,GAAG,iCAAW,CAAC,eAAe,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC;aAChG;YACD,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC;SAC3D;QAAC,OAAO,KAAK,EAAE;YACZ,IAAI,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,sBAAsB,GAAG,IAAI,CAAC,qBAAqB,EAAE;gBAC/E,MAAM,KAAK,CAAC;aACf;YACD,MAAM,aAAa,GAAG,IAAI,CAAC,aAAa,CAAC;YACzC,MAAM,cAAc,GAAG,IAAI,CAAC,cAAc,CAAC;YAE3C,IAAI,WAA+B,CAAC;YACpC,IAAI,SAAsB,CAAC;YAC3B,IAAI,aAAa,KAAK,SAAS,EAAE;gBAC7B,8CAA8C;gBAC9C,WAAW,GAAG;oBACV,WAAW,EAAE,IAAI;oBACjB,WAAW,EAAE,aAAa;iBAC7B,CAAC;gBACF,SAAS,GAAG,aAAa,CAAC,SAAS,CAAC;aACvC;iBAAM,IAAI,CAAA,cAAc,aAAd,cAAc,uBAAd,cAAc,CAAE,OAAO,MAAK,SAAS,EAAE;gBAC9C,8CAA8C;gBAC9C,WAAW,GAAG;oBACV,WAAW,EAAE,KAAK;oBAClB,cAAc,EAAE,cAAc,CAAC,OAAO;iBACzC,CAAC;gBACF,SAAS,GAAG,iCAAW,CAAC,MAAM,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC;aACrD;iBAAM;gBACH,+BAA+B;gBAC/B,MAAM,KAAK,CAAC;aACf;YACD,IAAI,CAAC,gBAAgB,CAAC,cAAc,CAAC;gBACjC,SAAS,EAAE,4BAA4B;aAC1C,EACD,KAAK,CAAC,CAAC;YACP,MAAM,OAAO,GAAG,mCAAa,CAAC,WAAW,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;YAChE,IAAI,CAAC,aAAa,GAAG;gBACjB,SAAS;gBACT,cAAc,EAAE,OAAO,CAAC,cAAc;aACzC,CAAC;YACF,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;YAC7B,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC;SAC7D;IACL,CAAC;IAED;;OAEG;IACI,eAAe,CAAC,cAAsB;QACzC,IAAI,CAAC,mBAAmB,CAAC,cAAc,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;IAC/D,CAAC;IAED;;OAEG;IACO,mBAAmB,CACzB,cAAsB,EACtB,UAAmC,EACnC,mBAA4B;QAE5B,qBAAM,CAAC,IAAI,CAAC,gBAAgB,KAAK,SAAS,EACtC,KAAK,CAAC,qEAAqE,CAAC,CAAC;QACjF,qBAAM,CAAC,IAAI,CAAC,0BAA0B,KAAK,SAAS,EAAE,KAAK,CAAC,8BAA8B,CAAC,CAAC;QAC5F,IAAI,eAAe,GAAG,IAAI,CAAC,aAAa,CAAC;QAEzC,IAAI,mBAAmB,EAAE;YACrB,MAAM,aAAa,GAAG,IAAI,CAAC,aAAa,CAAC;YACzC,IAAI,aAAa,KAAK,SAAS,EAAE;gBAC7B,qEAAqE;gBACrE,qEAAqE;gBACrE,2DAA2D;gBAC3D,qEAAqE;gBACrE,+CAA+C;gBAC/C,wEAAwE;gBACxE,eAAe,GAAG;oBACd,SAAS,EAAE,aAAa,CAAC,SAAS;oBAClC,cAAc,EAAE,aAAa,CAAC,cAAc;iBAC/C,CAAC;aACL;iBAAM;gBACH,qEAAqE;gBACrE,qEAAqE;gBACrE,mCAAmC;gBACnC,uEAAuE;gBACvE,wEAAwE;gBACxE,uEAAuE;gBACvE,IAAI,CAAC,YAAY,EAAE,CAAC;gBACpB,OAAO;aACV;SACJ;QAED,iFAAiF;QACjF,gDAAgD;QAChD,mFAAmF;QACnF,qBAAM,CAAC,CAAC,CAAC,eAAe,EAAE,KAAK,CAAC,2CAA2C,CAAC,CAAC;QAE7E,MAAM,OAAO,GAAG,IAAI,iCAAW,iCACxB,eAAe,KAClB,uBAAuB,EAAE,IAAI,CAAC,0BAA0B,EACxD,QAAQ,EAAE,UAAU,IACtB,CAAC;QACH,MAAM,mBAAmB,GAAG,OAAO,CAAC,mBAAmB,CAAC;QACxD,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAE;YACxC,KAAK,CAAC,mBAAmB,CACrB,cAAc,EACd,mBAAmB,EACnB,IAAI,CAAC,gBAAgB,IAAI,mBAAmB,CAC/C,CAAC;SACL;QACD,0DAA0D;QAC1D,+DAA+D;QAC/D,+DAA+D;QAC/D,8DAA8D;QAC9D,gEAAgE;QAChE,kEAAkE;QAClE,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC;QACnD,IAAI,CAAC,YAAY,EAAE,CAAC;IACxB,CAAC;IAEM,YAAY;QACf,IAAI,CAAC,0BAA0B,GAAG,SAAS,CAAC;QAC5C,IAAI,CAAC,aAAa,GAAG,SAAS,CAAC;QAC/B,IAAI,CAAC,gBAAgB,GAAG,KAAK,CAAC;QAC9B,IAAI,CAAC,gBAAgB,GAAG,SAAS,CAAC;QAClC,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAE;YACxC,KAAK,CAAC,YAAY,EAAE,CAAC;SACxB;IACL,CAAC;IAEM,KAAK,CAAC,oBAAoB,CAC7B,cAAkC,EAClC,WAAyC,EACzC,gBAAkC,EAClC,uBAAyC;QAEzC,IAAI,cAAc,KAAK,SAAS,EAAE;YAC9B,MAAM,gBAAgB,GAAG,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;YAEnE,IAAI,gBAAgB,KAAK,SAAS,EAAE;gBAChC,IAAI,CAAC,+BAA+B,CAAC,cAAc,EAAE,gBAAgB,CAAC,uBAAuB,CAAC,CAAC;gBAC/F,OAAO;aACV;SACJ;QAED,MAAM,YAAY,GAAG,MAAM,WAAW,EAAE,CAAC;QACzC,MAAM,uBAAuB,GAAG,MAAM,iCAAW,CAAC,YAAY,EAAE,gBAAgB,CAAC,CAAC;QAClF,MAAM,IAAI,CAAC,gCAAgC,CACvC,uBAAuB,EACvB,YAAY,EACZ,SAAS,EACT,iCAAW,CAAC,MAAM,CAAC,EAAE,CAAC,EACtB,uBAAuB,EACvB,gBAAgB,CACnB,CAAC;IACN,CAAC;IAES,+BAA+B,CACrC,cAAsB,EACtB,uBAA+B;QAE/B,MAAM,WAAW,GAAG,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;QAC9D,IAAI,WAAW,KAAK,SAAS,EAAE;YAC3B,oFAAoF;YACpF,qBAAM,CACF,IAAI,CAAC,aAAa,KAAK,SAAS,EAChC,KAAK,CAAC,mFAAmF,CAC5F,CAAC;YACF,OAAO;SACV;aAAM;YACH,qBAAM,CACF,uBAAuB,KAAK,WAAW,CAAC,uBAAuB;YAC/D,mCAAmC;YACnC,KAAK,CAAC,4IAA4I,CACrJ,CAAC;YAEF,kCAAkC;YAClC,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;SAChD;QAED,IAAI,CAAC,wBAAwB,CAAC,uBAAuB,CAAC,CAAC;QAEvD,IAAI,CAAC,aAAa,GAAG,WAAW,CAAC;QAEjC,sCAAsC;QACtC,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAE;YACxC,KAAK,CAAC,+BAA+B,CAAC,cAAc,EAAE,uBAAuB,CAAC,CAAC;SAClF;IACL,CAAC;IAES,KAAK,CAAC,gCAAgC,CAC5C,uBAA+B,EAC/B,YAA2B,EAC3B,QAAiC,EACjC,SAAsB,EACtB,uBAAyC,EACzC,gBAAkC;QAElC,0FAA0F;QAC1F,IAAI,IAAI,CAAC,uBAAuB,IAAI,uBAAuB,EAAE;YACzD,OAAO;SACV;QAED,IAAI,CAAC,wBAAwB,CAAC,uBAAuB,CAAC,CAAC;QAEvD,MAAM,EAAE,WAAW,EAAE,SAAS,EAAE,GAAG,mCAAa,CAAC,YAAY,EAAE,uBAAuB,CAAC,CAAC;QAExF,IAAI,CAAC,aAAa,GAAG,IAAI,iCAAW,CAAC;YACjC,uBAAuB;YACvB,QAAQ;YACR,SAAS;SACZ,CAAC,CAAC;QAEH,MAAM,EAAE,YAAY,EAAE,gBAAgB,EAAE,GAAG,6CAAuB,CAAC,WAAW,CAAC,CAAC;QAChF,IAAI,gBAAgB,KAAK,SAAS,EAAE;YAChC,SAAS,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;SACpC;QAED,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE;YACtB,IAAI,CAAC,aAAa,CAAC,cAAc,GAAG,iCAAW,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC;SAC9E;QAED,sCAAsC;QACtC,MAAM,eAAe,GAAG,IAAI,CAAC,aAAa,CAAC,mBAAmB,CAAC;QAC/D,MAAM,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC;aACtC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;YACb,uEAAuE;YACvE,gEAAgE;YAChE,OAAO,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,SAAS,CAAC;QAChD,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE,KAAK,CAAC,EAAE,EAAE;YACzB,OAAO,KAAK,CAAC,gCAAgC,CACzC,uBAAuB,EACvB,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC,EACtB,eAAe,EACf,iCAAW,CAAC,MAAM,CAAC,EAAE,CAAC,EACtB,uBAAuB,EACvB,gBAAgB,CACnB,CAAC;QACN,CAAC,CAAC,CAAC,CAAC;IACZ,CAAC;IAEO,wBAAwB,CAAC,uBAA+B;QAC5D,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,gBAAgB,EAAE;YAC9C,IAAI,KAAK,CAAC,uBAAuB,GAAG,uBAAuB,EAAE;gBACzD,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;aACrC;SACJ;QAED,gCAAgC;QAChC,OACI,IAAI,CAAC,cAAc,CAAC,MAAM,GAAG,CAAC;eAC3B,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,cAAc,IAAI,uBAAuB,EACrE;YACE,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,CAAC;SAC/B;IACL,CAAC;IAEM,kCAAkC,CAAC,QAAuB;QAC7D,gEAAgE;QAChE,mEAAmE;QACnE,MAAM,EAAE,gBAAgB,EAAE,GAAG,6CAAuB,CAAC,QAAQ,CAAC,CAAC;QAC/D,IAAI,gBAAgB,KAAK,SAAS,IAAI,IAAI,CAAC,aAAa,KAAK,SAAS,EAAE;YACpE,IAAI,CAAC,aAAa,CAAC,cAAc,GAAG,iCAAW,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC;SAC5E;IACL,CAAC;IAEM,KAAK,CAAC,eAAe,CACxB,QAAuB,EACvB,gBAAkC;QAElC,MAAM,cAAc,GAAG,mCAAa,CAAC,QAAQ,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;QACnE,MAAM,cAAc,GAAG,MAAM,cAAc,CAAC,iBAAiB,CAAC,gBAAgB,CAAC,CAAC;QAEhF,MAAM,EAAE,gBAAgB,EAAE,GAAG,6CAAuB,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC;QACjF,IAAI,gBAAgB,KAAK,SAAS,EAAE;YAChC,cAAc,CAAC,SAAS,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;SACnD;QAED,IAAI,cAAc,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,IAAI,IAAI,CAAC,aAAa,KAAK,SAAS,EAAE;YACzE,IAAI,CAAC,aAAa,CAAC,cAAc,GAAG,iCAAW,CAAC,eAAe,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC;SAC7F;QAED,0EAA0E;QAC1E,+DAA+D;QAC/D,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE;YAC3B,MAAM,eAAe,GAAG,cAAc,CAAC,cAAc,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,cAAc,CAAC;YACjF,qBAAM,CACF,eAAe,IAAI,IAAI,CAAC,sBAAsB,EAC9C,KAAK,CAAC,uFAAuF,CAChG,CAAC;SACL;QAED,OAAO;YACH,WAAW,EAAE,cAAc,CAAC,WAAW;YACvC,cAAc;SACjB,CAAC;IACN,CAAC;IAEM,YAAY,CAAC,EAA6B;QAC7C,MAAM,MAAM,GAAG,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,cAAc,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QACnE,IAAI,MAAM,KAAK,SAAS,EAAE;YACtB,qBAAM,CACF,MAAM,CAAC,cAAc,GAAG,EAAE,CAAC,cAAc,EACzC,KAAK,CAAC,qFAAqF,CAC9F,CAAC;SACL;QACD,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,cAAc,CAAC,CAAC;QACnC,IAAI,CAAC,sBAAsB,GAAG,EAAE,CAAC,cAAc,CAAC;QAChD,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACjC,CAAC;IAEM,UAAU,CAAC,cAAsB;QACpC,IAAI,cAAc,GAAG,IAAI,CAAC,qBAAqB,EAAE;YAC7C,IAAI,CAAC,qBAAqB,GAAG,cAAc,CAAC;SAC/C;IACL,CAAC;IAED;;;;OAIG;IACO,UAAU;QAChB,OAAO,IAAI,CAAC,qBAAqB,GAAG,IAAI,CAAC,uBAAuB,CAAC;IACrE,CAAC;IA4BM,WAAW;IACd,yBAAyB;IACzB,mBAA6E;IAC7E,2CAA2C;IAC3C,EAAU;IACV;;;;OAIG;IACH,WAA2C,EAC3C,SAAgC,EAAE;QAElC,qBAAM,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,KAAK,CAAC,kDAAkD,CAAC,CAAC;QAEzF,MAAM,aAAa,GAAwB,IAAI,CAAC,wBAAwB,CAAC,EAAE,EAAE,WAAW,CAAC,CAAC;QAC1F,MAAM,KAAK,GAAG,IAAI,cAAc,CAC5B,IAAI,CAAC,aAAa,EAClB,mBAAmB,EACnB,MAAM,EACN,aAAa,CAAC,oBAAoB,EAClC,aAAa,CAAC,aAAa,EAC3B,aAAa,CAAC,cAAc,EAC5B,IAAI,CAAC,gBAAgB,CACxB,CAAC;QAEF,yGAAyG;QACzG,uEAAuE;QACvE,IAAI,CAAC,qBAAqB,CAAC,KAAK,CAAC,CAAC;QAElC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;QAC7B,OAAO,KAAK,CAAC;IACjB,CAAC;IAEM,QAAQ,CAAC,EAAU;QACtB,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACjC,CAAC;IAED;;;;;OAKG;IACO,wBAAwB,CAAC,EAAU,EAAE,WAA2C;;QACtF,IAAI,cAA2C,CAAC;QAChD,IAAI,aAAsC,CAAC;QAC3C,IAAI,oBAA4B,CAAC;QAEjC,MAAM,mBAAmB,GAAG,IAAI,CAAC,aAAa,CAAC;QAC/C,QAAQ,WAAW,CAAC,IAAI,EAAE;YACtB,KAAK,gDAA0B,CAAC,UAAU,CAAC,CAAC;gBACxC,IACI,mBAAmB,KAAK,SAAS;uBAC9B,WAAW,CAAC,cAAc,IAAI,mBAAmB,CAAC,uBAAuB,EAC9E;oBACE,oEAAoE;oBACpE,aAAa,GAAG,mBAAmB,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC;iBAC1D;qBAAM;oBACH,MAAM,OAAO,GAAG,mCAAoB,CAAC,WAAW,CAAC,QAAQ,CAA0B,CAAC;oBACpF,cAAc,GAAG;wBACb,cAAc,EAAE,WAAW,CAAC,cAAc;wBAC1C,EAAE;wBACF,OAAO;qBACV,CAAC;iBACL;gBACD,oBAAoB,GAAG,WAAW,CAAC,cAAc,CAAC;gBAClD,MAAM;aACT;YACD,KAAK,gDAA0B,CAAC,WAAW,CAAC,CAAC;gBACzC,IAAI,IAAI,CAAC,cAAc,KAAK,SAAS,EAAE;oBACnC,qBAAM,CACF,CAAC,CAAC,mBAAmB,EACrB,KAAK,CAAC,+EAA+E,CAAC,CAAC;iBAC9F;gBACD,uBAAuB;aAC1B;YACD,KAAK,gDAA0B,CAAC,KAAK,CAAC,CAAC;gBACnC,MAAM,oBAAoB,GAAG,IAAI,CAAC,cAAc,CAAC;gBACjD,IAAI,oBAAoB,KAAK,SAAS,EAAE;oBACpC,IAAI,YAAuC,CAAC;oBAC5C,IAAI,oBAAoB,CAAC,OAAO,KAAK,SAAS,EAAE;wBAC5C,MAAM,EAAE,YAAY,EAAE,GAAG,iDAA2B,CAAC,oBAAoB,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;wBAC3F,qBAAM,CACF,YAAY,CAAC,IAAI,iBAAqB,EACtC,KAAK,CAAC,2CAA2C,CACpD,CAAC;wBACF,YAAY,GAAG,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;qBACxC;oBACD,IAAI,WAAW,CAAC,IAAI,KAAK,gDAA0B,CAAC,WAAW,EAAE;wBAC7D,uDAAuD;wBACvD,qBAAM,CAAC,CAAC,CAAC,YAAY,EAAE,KAAK,CAAC,kCAAkC,CAAC,CAAC;qBACpE;oBACD,IAAI,qBAAwD,CAAC;oBAC7D,IAAI,YAAY,KAAK,SAAS,EAAE;wBAC5B,qBAAM,CACF,YAAY,CAAC,IAAI,iBAAqB,EACtC,KAAK,CAAC,0CAA0C,CACnD,CAAC;wBACF,qBAAqB,GAAG;4BACpB,OAAO,EAAE,YAAY;4BACrB,KAAK,EAAE,6BAAc,CAAC,YAAY,CAAC;yBACtC,CAAC;qBACL;oBACD,cAAc,GAAG;wBACb,cAAc,EAAE,oBAAoB,CAAC,cAAc;wBACnD,EAAE;wBACF,OAAO,EAAE,qBAAqB;qBACjC,CAAC;iBACL;gBACD,aAAa,GAAG,mBAAmB,aAAnB,mBAAmB,uBAAnB,mBAAmB,CAAE,cAAc,CAAC,EAAE,CAAC,CAAC;gBACxD,oBAAoB,SAAG,mBAAmB,aAAnB,mBAAmB,uBAAnB,mBAAmB,CAAE,uBAAuB,mCAAI,CAAC,CAAC,CAAC;gBAC1E,MAAM;aACT;YACD,OAAO,CAAC,CAAC;gBACL,MAAM,IAAI,GAAI,WAAyD,CAAC,IAAI,CAAC;gBAC7E,8BAAe,CAAC,WAAW,EAAE,0CAA0C,IAAI,EAAE,CAAC,CAAC;aAClF;SACJ;QAED,OAAO;YACH,cAAc;YACd,aAAa;YACb,oBAAoB;SACvB,CAAC;IACN,CAAC;IAED;;;;OAIG;IACO,qBAAqB,CAAC,KAAqB;QACjD,6GAA6G;QAC7G,kCAAkC;QAClC,IAAI,IAAI,CAAC,oBAAoB,EAAE,EAAE;YAC7B,KAAK,CAAC,0BAA0B,GAAG,IAAI,CAAC,0BAA0B,CAAC;SACtE;IACL,CAAC;IAED;;OAEG;IACO,oBAAoB;QAC1B,OAAO,IAAI,CAAC,0BAA0B,KAAK,SAAS,CAAC;IACzD,CAAC;CACJ;AA3iBD,wCA2iBC;AAED;;;;;;;;GAQG;AACI,MAAM,wBAAwB,GAAG,CACpC,MAAwB,EACxB,mBAA6E,EAC7E,oBAA4B,EAC5B,uBAA2C,EAC3C,SAAgC,EAAE,EACf,EAAE,CAAC,IAAI,cAAc,CACpC,MAAM,EACN,mBAAmB,EACnB,MAAM,EACN,oBAAoB,EACpB,uBAAuB,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,iCAAW,CAAC,aAAa,CAAC,uBAAuB,CAAC,CACzG,CAAC;AAZO,QAAA,wBAAwB,4BAY/B","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport {\n ISummarizerNode,\n ISummarizerNodeConfig,\n ISummarizeInternalResult,\n ISummarizeResult,\n ISummaryTreeWithStats,\n CreateChildSummarizerNodeParam,\n CreateSummarizerNodeSource,\n} from \"@fluidframework/runtime-definitions\";\nimport {\n ISequencedDocumentMessage,\n SummaryType,\n ISnapshotTree,\n SummaryObject,\n} from \"@fluidframework/protocol-definitions\";\nimport { ITelemetryLogger } from \"@fluidframework/common-definitions\";\nimport { assert, unreachableCase } from \"@fluidframework/common-utils\";\nimport { mergeStats, convertToSummaryTree, calculateStats } from \"../summaryUtils\";\nimport {\n decodeSummary,\n encodeSummary,\n EncodeSummaryParam,\n EscapedPath,\n ICreateChildDetails,\n IInitialSummary,\n ISummarizerNodeRootContract,\n parseSummaryForSubtrees,\n parseSummaryTreeForSubtrees,\n ReadAndParseBlob,\n seqFromTree,\n SummaryNode,\n} from \"./summarizerNodeUtils\";\n\nexport interface IRootSummarizerNode extends ISummarizerNode, ISummarizerNodeRootContract {}\n\n/**\n * Encapsulates the summarizing work and state of an individual tree node in the\n * summary tree. It tracks changes and allows for optimizations when unchanged, or\n * can allow for fallback summaries to be generated when an error is encountered.\n * Usage is for the root node to call startSummary first to begin tracking a WIP\n * (work in progress) summary. Then all nodes will call summarize to summaries their\n * individual parts. Once completed and uploaded to storage, the root node will call\n * completeSummary or clearSummary to clear the WIP summary tracking state if something\n * went wrong. The SummarizerNodes will track all pending summaries that have been\n * recorded by the completeSummary call. When one of them is acked, the root node should\n * call refreshLatestSummary to inform the tree of SummarizerNodes of the new baseline\n * latest successful summary.\n */\nexport class SummarizerNode implements IRootSummarizerNode {\n /**\n * The reference sequence number of the most recent acked summary.\n * Returns 0 if there is not yet an acked summary.\n */\n public get referenceSequenceNumber() {\n return this.latestSummary?.referenceSequenceNumber ?? 0;\n }\n\n protected readonly children = new Map<string, SummarizerNode>();\n protected readonly pendingSummaries = new Map<string, SummaryNode>();\n private readonly outstandingOps: ISequencedDocumentMessage[] = [];\n private wipReferenceSequenceNumber: number | undefined;\n private wipLocalPaths: { localPath: EscapedPath, additionalPath?: EscapedPath } | undefined;\n private wipSkipRecursion = false;\n\n public startSummary(referenceSequenceNumber: number, summaryLogger: ITelemetryLogger) {\n assert(this.wipSummaryLogger === undefined,\n 0x19f /* \"wipSummaryLogger should not be set yet in startSummary\" */);\n assert(this.wipReferenceSequenceNumber === undefined, 0x1a0 /* \"Already tracking a summary\" */);\n\n this.wipSummaryLogger = summaryLogger;\n\n for (const child of this.children.values()) {\n child.startSummary(referenceSequenceNumber, this.wipSummaryLogger);\n }\n this.wipReferenceSequenceNumber = referenceSequenceNumber;\n }\n\n public async summarize(fullTree: boolean): Promise<ISummarizeResult> {\n assert(this.isTrackingInProgress(), 0x1a1 /* \"summarize should not be called when not tracking the summary\" */);\n assert(this.wipSummaryLogger !== undefined,\n 0x1a2 /* \"wipSummaryLogger should have been set in startSummary or ctor\" */);\n\n // Try to reuse the tree if unchanged\n if (this.canReuseHandle && !fullTree && !this.hasChanged()) {\n const latestSummary = this.latestSummary;\n if (latestSummary !== undefined) {\n this.wipLocalPaths = {\n localPath: latestSummary.localPath,\n additionalPath: latestSummary.additionalPath,\n };\n this.wipSkipRecursion = true;\n const stats = mergeStats();\n stats.handleNodeCount++;\n return {\n summary: {\n type: SummaryType.Handle,\n handle: latestSummary.fullPath.path,\n handleType: SummaryType.Tree,\n },\n stats,\n };\n }\n }\n\n try {\n const result = await this.summarizeInternalFn(fullTree);\n this.wipLocalPaths = { localPath: EscapedPath.create(result.id) };\n if (result.pathPartsForChildren !== undefined) {\n this.wipLocalPaths.additionalPath = EscapedPath.createAndConcat(result.pathPartsForChildren);\n }\n return { summary: result.summary, stats: result.stats };\n } catch (error) {\n if (this.throwOnError || this.trackingSequenceNumber < this._changeSequenceNumber) {\n throw error;\n }\n const latestSummary = this.latestSummary;\n const initialSummary = this.initialSummary;\n\n let encodeParam: EncodeSummaryParam;\n let localPath: EscapedPath;\n if (latestSummary !== undefined) {\n // Create using handle of latest acked summary\n encodeParam = {\n fromSummary: true,\n summaryNode: latestSummary,\n };\n localPath = latestSummary.localPath;\n } else if (initialSummary?.summary !== undefined) {\n // Create using initial summary from attach op\n encodeParam = {\n fromSummary: false,\n initialSummary: initialSummary.summary,\n };\n localPath = EscapedPath.create(initialSummary.id);\n } else {\n // No base summary to reference\n throw error;\n }\n this.wipSummaryLogger.sendErrorEvent({\n eventName: \"SummarizingWithBasePlusOps\",\n },\n error);\n const summary = encodeSummary(encodeParam, this.outstandingOps);\n this.wipLocalPaths = {\n localPath,\n additionalPath: summary.additionalPath,\n };\n this.wipSkipRecursion = true;\n return { summary: summary.summary, stats: summary.stats };\n }\n }\n\n /**\n * Complete the WIP summary for the given proposalHandle\n */\n public completeSummary(proposalHandle: string) {\n this.completeSummaryCore(proposalHandle, undefined, false);\n }\n\n /**\n * Recursive implementation for completeSummary, with additional internal-only parameters\n */\n protected completeSummaryCore(\n proposalHandle: string,\n parentPath: EscapedPath | undefined,\n parentSkipRecursion: boolean,\n ) {\n assert(this.wipSummaryLogger !== undefined,\n 0x1a3 /* \"wipSummaryLogger should have been set in startSummary or ctor\" */);\n assert(this.wipReferenceSequenceNumber !== undefined, 0x1a4 /* \"Not tracking a summary\" */);\n let localPathsToUse = this.wipLocalPaths;\n\n if (parentSkipRecursion) {\n const latestSummary = this.latestSummary;\n if (latestSummary !== undefined) {\n // This case the parent node created a failure summary or was reused.\n // This node and all children should only try to reference their path\n // by its last known good state in the actual summary tree.\n // If parent fails or is reused, the child summarize is not called so\n // it did not get a chance to change its paths.\n // In this case, essentially only propagate the new summary ref seq num.\n localPathsToUse = {\n localPath: latestSummary.localPath,\n additionalPath: latestSummary.additionalPath,\n };\n } else {\n // This case the child is added after the latest non-failure summary.\n // This node and all children should consider themselves as still not\n // having a successful summary yet.\n // We cannot \"reuse\" this node if unchanged since that summary, because\n // handles will be unable to point to that node. It never made it to the\n // tree itself, and only exists as an attach op in the _outstandingOps.\n this.clearSummary();\n return;\n }\n }\n\n // This should come from wipLocalPaths in normal cases, or from the latestSummary\n // if parentIsFailure or parentIsReused is true.\n // If there is no latestSummary, clearSummary and return before reaching this code.\n assert(!!localPathsToUse, 0x1a5 /* \"Tracked summary local paths not set\" */);\n\n const summary = new SummaryNode({\n ...localPathsToUse,\n referenceSequenceNumber: this.wipReferenceSequenceNumber,\n basePath: parentPath,\n });\n const fullPathForChildren = summary.fullPathForChildren;\n for (const child of this.children.values()) {\n child.completeSummaryCore(\n proposalHandle,\n fullPathForChildren,\n this.wipSkipRecursion || parentSkipRecursion,\n );\n }\n // Note that this overwrites existing pending summary with\n // the same proposalHandle. If proposalHandle is something like\n // a hash or unique identifier, this should be fine. If storage\n // can return the same proposalHandle for a different summary,\n // this should still be okay, because we should be proposing the\n // newer one later which would have to overwrite the previous one.\n this.pendingSummaries.set(proposalHandle, summary);\n this.clearSummary();\n }\n\n public clearSummary() {\n this.wipReferenceSequenceNumber = undefined;\n this.wipLocalPaths = undefined;\n this.wipSkipRecursion = false;\n this.wipSummaryLogger = undefined;\n for (const child of this.children.values()) {\n child.clearSummary();\n }\n }\n\n public async refreshLatestSummary(\n proposalHandle: string | undefined,\n getSnapshot: () => Promise<ISnapshotTree>,\n readAndParseBlob: ReadAndParseBlob,\n correlatedSummaryLogger: ITelemetryLogger,\n ): Promise<void> {\n if (proposalHandle !== undefined) {\n const maybeSummaryNode = this.pendingSummaries.get(proposalHandle);\n\n if (maybeSummaryNode !== undefined) {\n this.refreshLatestSummaryFromPending(proposalHandle, maybeSummaryNode.referenceSequenceNumber);\n return;\n }\n }\n\n const snapshotTree = await getSnapshot();\n const referenceSequenceNumber = await seqFromTree(snapshotTree, readAndParseBlob);\n await this.refreshLatestSummaryFromSnapshot(\n referenceSequenceNumber,\n snapshotTree,\n undefined,\n EscapedPath.create(\"\"),\n correlatedSummaryLogger,\n readAndParseBlob,\n );\n }\n\n protected refreshLatestSummaryFromPending(\n proposalHandle: string,\n referenceSequenceNumber: number,\n ): void {\n const summaryNode = this.pendingSummaries.get(proposalHandle);\n if (summaryNode === undefined) {\n // This should only happen if parent skipped recursion AND no prior summary existed.\n assert(\n this.latestSummary === undefined,\n 0x1a6 /* \"Not found pending summary, but this node has previously completed a summary\" */,\n );\n return;\n } else {\n assert(\n referenceSequenceNumber === summaryNode.referenceSequenceNumber,\n // eslint-disable-next-line max-len\n 0x1a7 /* `Pending summary reference sequence number should be consistent: ${summaryNode.referenceSequenceNumber} != ${referenceSequenceNumber}` */,\n );\n\n // Clear earlier pending summaries\n this.pendingSummaries.delete(proposalHandle);\n }\n\n this.refreshLatestSummaryCore(referenceSequenceNumber);\n\n this.latestSummary = summaryNode;\n\n // Propagate update to all child nodes\n for (const child of this.children.values()) {\n child.refreshLatestSummaryFromPending(proposalHandle, referenceSequenceNumber);\n }\n }\n\n protected async refreshLatestSummaryFromSnapshot(\n referenceSequenceNumber: number,\n snapshotTree: ISnapshotTree,\n basePath: EscapedPath | undefined,\n localPath: EscapedPath,\n correlatedSummaryLogger: ITelemetryLogger,\n readAndParseBlob: ReadAndParseBlob,\n ): Promise<void> {\n // Possible re-entrancy. If we have already seen a summary later than this one, ignore it.\n if (this.referenceSequenceNumber >= referenceSequenceNumber) {\n return;\n }\n\n this.refreshLatestSummaryCore(referenceSequenceNumber);\n\n const { baseSummary, pathParts } = decodeSummary(snapshotTree, correlatedSummaryLogger);\n\n this.latestSummary = new SummaryNode({\n referenceSequenceNumber,\n basePath,\n localPath,\n });\n\n const { childrenTree, childrenPathPart } = parseSummaryForSubtrees(baseSummary);\n if (childrenPathPart !== undefined) {\n pathParts.push(childrenPathPart);\n }\n\n if (pathParts.length > 0) {\n this.latestSummary.additionalPath = EscapedPath.createAndConcat(pathParts);\n }\n\n // Propagate update to all child nodes\n const pathForChildren = this.latestSummary.fullPathForChildren;\n await Promise.all(Array.from(this.children)\n .filter(([id]) => {\n // Assuming subtrees missing from snapshot are newer than the snapshot,\n // but might be nice to assert this using earliest seq for node.\n return childrenTree.trees[id] !== undefined;\n }).map(async ([id, child]) => {\n return child.refreshLatestSummaryFromSnapshot(\n referenceSequenceNumber,\n childrenTree.trees[id],\n pathForChildren,\n EscapedPath.create(id),\n correlatedSummaryLogger,\n readAndParseBlob,\n );\n }));\n }\n\n private refreshLatestSummaryCore(referenceSequenceNumber: number): void {\n for (const [key, value] of this.pendingSummaries) {\n if (value.referenceSequenceNumber < referenceSequenceNumber) {\n this.pendingSummaries.delete(key);\n }\n }\n\n // Clear earlier outstanding ops\n while (\n this.outstandingOps.length > 0\n && this.outstandingOps[0].sequenceNumber <= referenceSequenceNumber\n ) {\n this.outstandingOps.shift();\n }\n }\n\n public loadBaseSummaryWithoutDifferential(snapshot: ISnapshotTree) {\n // Check base summary to see if it has any additional path parts\n // separating child SummarizerNodes. Checks for .channels subtrees.\n const { childrenPathPart } = parseSummaryForSubtrees(snapshot);\n if (childrenPathPart !== undefined && this.latestSummary !== undefined) {\n this.latestSummary.additionalPath = EscapedPath.create(childrenPathPart);\n }\n }\n\n public async loadBaseSummary(\n snapshot: ISnapshotTree,\n readAndParseBlob: ReadAndParseBlob,\n ): Promise<{ baseSummary: ISnapshotTree, outstandingOps: ISequencedDocumentMessage[] }> {\n const decodedSummary = decodeSummary(snapshot, this.defaultLogger);\n const outstandingOps = await decodedSummary.getOutstandingOps(readAndParseBlob);\n\n const { childrenPathPart } = parseSummaryForSubtrees(decodedSummary.baseSummary);\n if (childrenPathPart !== undefined) {\n decodedSummary.pathParts.push(childrenPathPart);\n }\n\n if (decodedSummary.pathParts.length > 0 && this.latestSummary !== undefined) {\n this.latestSummary.additionalPath = EscapedPath.createAndConcat(decodedSummary.pathParts);\n }\n\n // Defensive assertion: tracking number should already exceed this number.\n // This is probably a little excessive; can remove when stable.\n if (outstandingOps.length > 0) {\n const newOpsLatestSeq = outstandingOps[outstandingOps.length - 1].sequenceNumber;\n assert(\n newOpsLatestSeq <= this.trackingSequenceNumber,\n 0x1a9 /* \"When loading base summary, expected outstanding ops <= tracking sequence number\" */,\n );\n }\n\n return {\n baseSummary: decodedSummary.baseSummary,\n outstandingOps,\n };\n }\n\n public recordChange(op: ISequencedDocumentMessage): void {\n const lastOp = this.outstandingOps[this.outstandingOps.length - 1];\n if (lastOp !== undefined) {\n assert(\n lastOp.sequenceNumber < op.sequenceNumber,\n 0x1aa /* `Out of order change recorded: ${lastOp.sequenceNumber} > ${op.sequenceNumber}` */,\n );\n }\n this.invalidate(op.sequenceNumber);\n this.trackingSequenceNumber = op.sequenceNumber;\n this.outstandingOps.push(op);\n }\n\n public invalidate(sequenceNumber: number): void {\n if (sequenceNumber > this._changeSequenceNumber) {\n this._changeSequenceNumber = sequenceNumber;\n }\n }\n\n /**\n * True if a change has been recorded with sequence number exceeding\n * the latest successfully acked summary reference sequence number.\n * False implies that the previous summary can be reused.\n */\n protected hasChanged(): boolean {\n return this._changeSequenceNumber > this.referenceSequenceNumber;\n }\n\n private readonly canReuseHandle: boolean;\n private readonly throwOnError: boolean;\n private trackingSequenceNumber: number;\n\n /**\n * Do not call constructor directly.\n * Use createRootSummarizerNode to create root node, or createChild to create child nodes.\n */\n public constructor(\n protected readonly defaultLogger: ITelemetryLogger,\n private readonly summarizeInternalFn: (fullTree: boolean) => Promise<ISummarizeInternalResult>,\n config: ISummarizerNodeConfig,\n private _changeSequenceNumber: number,\n /** Undefined means created without summary */\n private latestSummary?: SummaryNode,\n private readonly initialSummary?: IInitialSummary,\n protected wipSummaryLogger?: ITelemetryLogger,\n ) {\n this.canReuseHandle = config.canReuseHandle ?? true;\n // BUGBUG: Seeing issues with differential summaries.\n // this will disable them, and throw instead\n // while we continue to investigate\n this.throwOnError = true; // config.throwOnFailure ?? false;\n this.trackingSequenceNumber = this._changeSequenceNumber;\n }\n\n public createChild(\n /** Summarize function */\n summarizeInternalFn: (fullTree: boolean) => Promise<ISummarizeInternalResult>,\n /** Initial id or path part of this node */\n id: string,\n /**\n * Information needed to create the node.\n * If it is from a base summary, it will assert that a summary has been seen.\n * Attach information if it is created from an attach op.\n */\n createParam: CreateChildSummarizerNodeParam,\n config: ISummarizerNodeConfig = {},\n ): ISummarizerNode {\n assert(!this.children.has(id), 0x1ab /* \"Create SummarizerNode child already exists\" */);\n\n const createDetails: ICreateChildDetails = this.getCreateDetailsForChild(id, createParam);\n const child = new SummarizerNode(\n this.defaultLogger,\n summarizeInternalFn,\n config,\n createDetails.changeSequenceNumber,\n createDetails.latestSummary,\n createDetails.initialSummary,\n this.wipSummaryLogger,\n );\n\n // There may be additional state that has to be updated in this child. For example, if a summary is being\n // tracked, the child's summary tracking state needs to be updated too.\n this.maybeUpdateChildState(child);\n\n this.children.set(id, child);\n return child;\n }\n\n public getChild(id: string): ISummarizerNode | undefined {\n return this.children.get(id);\n }\n\n /**\n * Returns the details needed to create a child node.\n * @param id - Initial id or path part of the child node.\n * @param createParam - Information needed to create the node.\n * @returns the details needed to create the child node.\n */\n protected getCreateDetailsForChild(id: string, createParam: CreateChildSummarizerNodeParam): ICreateChildDetails {\n let initialSummary: IInitialSummary | undefined;\n let latestSummary: SummaryNode | undefined;\n let changeSequenceNumber: number;\n\n const parentLatestSummary = this.latestSummary;\n switch (createParam.type) {\n case CreateSummarizerNodeSource.FromAttach: {\n if (\n parentLatestSummary !== undefined\n && createParam.sequenceNumber <= parentLatestSummary.referenceSequenceNumber\n ) {\n // Prioritize latest summary if it was after this node was attached.\n latestSummary = parentLatestSummary.createForChild(id);\n } else {\n const summary = convertToSummaryTree(createParam.snapshot) as ISummaryTreeWithStats;\n initialSummary = {\n sequenceNumber: createParam.sequenceNumber,\n id,\n summary,\n };\n }\n changeSequenceNumber = createParam.sequenceNumber;\n break;\n }\n case CreateSummarizerNodeSource.FromSummary: {\n if (this.initialSummary === undefined) {\n assert(\n !!parentLatestSummary,\n 0x1ac /* \"Cannot create child from summary if parent does not have latest summary\" */);\n }\n // fallthrough to local\n }\n case CreateSummarizerNodeSource.Local: {\n const parentInitialSummary = this.initialSummary;\n if (parentInitialSummary !== undefined) {\n let childSummary: SummaryObject | undefined;\n if (parentInitialSummary.summary !== undefined) {\n const { childrenTree } = parseSummaryTreeForSubtrees(parentInitialSummary.summary.summary);\n assert(\n childrenTree.type === SummaryType.Tree,\n 0x1d6 /* \"Parent summary object is not a tree\" */,\n );\n childSummary = childrenTree.tree[id];\n }\n if (createParam.type === CreateSummarizerNodeSource.FromSummary) {\n // Locally created would not have differential subtree.\n assert(!!childSummary, 0x1ad /* \"Missing child summary tree\" */);\n }\n let childSummaryWithStats: ISummaryTreeWithStats | undefined;\n if (childSummary !== undefined) {\n assert(\n childSummary.type === SummaryType.Tree,\n 0x1ae /* \"Child summary object is not a tree\" */,\n );\n childSummaryWithStats = {\n summary: childSummary,\n stats: calculateStats(childSummary),\n };\n }\n initialSummary = {\n sequenceNumber: parentInitialSummary.sequenceNumber,\n id,\n summary: childSummaryWithStats,\n };\n }\n latestSummary = parentLatestSummary?.createForChild(id);\n changeSequenceNumber = parentLatestSummary?.referenceSequenceNumber ?? -1;\n break;\n }\n default: {\n const type = (createParam as unknown as CreateChildSummarizerNodeParam).type;\n unreachableCase(createParam, `Unexpected CreateSummarizerNodeSource: ${type}`);\n }\n }\n\n return {\n initialSummary,\n latestSummary,\n changeSequenceNumber,\n };\n }\n\n /**\n * Updates the state of the child if required. For example, if a summary is currently being tracked, the child's\n * summary tracking state needs to be updated too.\n * @param child - The child node whose state is to be updated.\n */\n protected maybeUpdateChildState(child: SummarizerNode) {\n // If we are tracking a summary, this child was created after the tracking started. So, we need to update the\n // child's tracking state as well.\n if (this.isTrackingInProgress()) {\n child.wipReferenceSequenceNumber = this.wipReferenceSequenceNumber;\n }\n }\n\n /**\n * Tells whether summary tracking is in progress. True if \"startSummary\" API is called before summarize.\n */\n protected isTrackingInProgress(): boolean {\n return this.wipReferenceSequenceNumber !== undefined;\n }\n}\n\n/**\n * Creates a root summarizer node.\n * @param logger - Logger to use within SummarizerNode\n * @param summarizeInternalFn - Function to generate summary\n * @param changeSequenceNumber - Sequence number of latest change to new node/subtree\n * @param referenceSequenceNumber - Reference sequence number of last acked summary,\n * or undefined if not loaded from summary\n * @param config - Configure behavior of summarizer node\n */\nexport const createRootSummarizerNode = (\n logger: ITelemetryLogger,\n summarizeInternalFn: (fullTree: boolean) => Promise<ISummarizeInternalResult>,\n changeSequenceNumber: number,\n referenceSequenceNumber: number | undefined,\n config: ISummarizerNodeConfig = {},\n): IRootSummarizerNode => new SummarizerNode(\n logger,\n summarizeInternalFn,\n config,\n changeSequenceNumber,\n referenceSequenceNumber === undefined ? undefined : SummaryNode.createForRoot(referenceSequenceNumber),\n );\n"]} |
@@ -161,4 +161,4 @@ "use strict"; | ||
| } | ||
| common_utils_1.assert(!!outstandingOpsBlob, "Outstanding ops blob missing, but base summary tree exists"); | ||
| common_utils_1.assert(newBaseSummary !== undefined, "Base summary tree missing, but outstanding ops blob exists"); | ||
| common_utils_1.assert(!!outstandingOpsBlob, 0x1af /* "Outstanding ops blob missing, but base summary tree exists" */); | ||
| common_utils_1.assert(newBaseSummary !== undefined, 0x1b0 /* "Base summary tree missing, but outstanding ops blob exists" */); | ||
| baseSummary = newBaseSummary; | ||
@@ -165,0 +165,0 @@ pathParts.push(baseSummaryTreeKey); |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"summarizerNodeUtils.js","sourceRoot":"","sources":["../../src/summarizerNode/summarizerNodeUtils.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { ITelemetryLogger } from \"@fluidframework/common-definitions\";\nimport { assert } from \"@fluidframework/common-utils\";\nimport {\n ISnapshotTree,\n IDocumentAttributes,\n ISequencedDocumentMessage,\n SummaryType,\n ISummaryTree,\n SummaryObject,\n} from \"@fluidframework/protocol-definitions\";\nimport { channelsTreeName, ISummaryTreeWithStats } from \"@fluidframework/runtime-definitions\";\nimport { SummaryTreeBuilder } from \"../summaryUtils\";\n\nconst baseSummaryTreeKey = \"_baseSummary\";\nconst outstandingOpsBlobKey = \"_outstandingOps\";\nconst maxDecodeDepth = 100;\n\n/** Reads a blob from storage and parses it from JSON. */\nexport type ReadAndParseBlob = <T>(id: string) => Promise<T>;\n\nexport interface ISummarizerNodeRootContract {\n startSummary(referenceSequenceNumber: number, summaryLogger: ITelemetryLogger): void;\n completeSummary(proposalHandle: string): void;\n clearSummary(): void;\n refreshLatestSummary(\n proposalHandle: string | undefined,\n getSnapshot: () => Promise<ISnapshotTree>,\n readAndParseBlob: ReadAndParseBlob,\n correlatedSummaryLogger: ITelemetryLogger,\n ): Promise<void>;\n}\n\n/**\n * Fetches the sequence number of the snapshot tree by examining the protocol.\n * @param tree - snapshot tree to examine\n * @param readAndParseBlob - function to read blob contents from storage\n * and parse the result from JSON.\n */\nexport async function seqFromTree(\n tree: ISnapshotTree,\n readAndParseBlob: ReadAndParseBlob,\n): Promise<number> {\n const attributesHash = tree.trees[\".protocol\"].blobs.attributes;\n const attrib = await readAndParseBlob<IDocumentAttributes>(attributesHash);\n return attrib.sequenceNumber;\n}\n\n/** Path for nodes in a tree with escaped special characters */\nexport class EscapedPath {\n private constructor(public readonly path: string) { }\n public static create(path: string): EscapedPath {\n return new EscapedPath(encodeURIComponent(path));\n }\n public static createAndConcat(pathParts: string[]): EscapedPath {\n let ret = EscapedPath.create(pathParts[0] ?? \"\");\n for (let i = 1; i < pathParts.length; i++) {\n ret = ret.concat(EscapedPath.create(pathParts[i]));\n }\n return ret;\n }\n public toString(): string {\n return this.path;\n }\n public concat(path: EscapedPath): EscapedPath {\n return new EscapedPath(`${this.path}/${path.path}`);\n }\n}\n\n/** Information about a summary relevant to a specific node in the tree */\nexport class SummaryNode {\n /** Creates an instance that is valid for the root with specific basePath and localPath */\n public static createForRoot(referenceSequenceNumber: number): SummaryNode {\n return new SummaryNode({\n referenceSequenceNumber,\n basePath: undefined,\n localPath: EscapedPath.create(\"\"), // root hard-coded to \"\"\n });\n }\n\n /** Summary reference sequence number, i.e. last sequence number seen when it was created */\n public get referenceSequenceNumber(): number {\n return this.summary.referenceSequenceNumber;\n }\n /** Full path to parent node, or undefined if this is the root */\n public get basePath(): EscapedPath | undefined {\n return this.summary.basePath;\n }\n /** Relative path to this node from its parent node */\n public get localPath(): EscapedPath {\n return this.summary.localPath;\n }\n /** Relative path from this node to its node innermost base summary */\n public get additionalPath(): EscapedPath | undefined {\n return this.summary.additionalPath;\n }\n public set additionalPath(additionalPath: EscapedPath | undefined) {\n this.summary.additionalPath = additionalPath;\n }\n constructor(private readonly summary: {\n readonly referenceSequenceNumber: number,\n readonly basePath: EscapedPath | undefined,\n readonly localPath: EscapedPath,\n additionalPath?: EscapedPath,\n }) { }\n\n /** Gets the full path to this node, to be used when sending a handle */\n public get fullPath(): EscapedPath {\n return this.basePath?.concat(this.localPath) ?? this.localPath;\n }\n\n /**\n * Gets the full path to this node's innermost base summary.\n * The children nodes can use this as their basePath to determine their path.\n */\n public get fullPathForChildren(): EscapedPath {\n return this.additionalPath !== undefined\n ? this.fullPath.concat(this.additionalPath)\n : this.fullPath;\n }\n\n /**\n * Creates a new node within the same summary for a child of this node.\n * @param id - id of the child node\n */\n public createForChild(id: string): SummaryNode {\n return new SummaryNode({\n referenceSequenceNumber: this.referenceSequenceNumber,\n basePath: this.fullPathForChildren,\n localPath: EscapedPath.create(id),\n });\n }\n}\n\n/** Result from decoding summary which may have been a differential summary. */\ninterface IDecodedSummary {\n /** The innermost base summary which is not itself a differential summary */\n readonly baseSummary: ISnapshotTree;\n /** The entire path name to the innermost base summary */\n readonly pathParts: string[];\n /** Function to fetch all outstanding ops since the innermost base summary */\n getOutstandingOps(readAndParseBlob: ReadAndParseBlob): Promise<ISequencedDocumentMessage[]>;\n}\n\n/**\n * Checks if the snapshot is created by referencing a previous successful\n * summary plus outstanding ops. If so, it will recursively \"decode\" it until\n * it gets to the last successful summary (the base summary) and returns that\n * as well as a function for fetching the outstanding ops. Also returns the\n * full path to the previous base summary for child summarizer nodes to use as\n * their base path when necessary.\n * @param snapshot - snapshot tree to decode\n */\nexport function decodeSummary(\n snapshot: ISnapshotTree,\n logger: Pick<ITelemetryLogger, \"sendTelemetryEvent\">,\n): IDecodedSummary {\n let baseSummary = snapshot;\n const pathParts: string[] = [];\n const opsBlobs: string[] = [];\n\n for (let i = 0; ; i++) {\n if (i > maxDecodeDepth) {\n logger.sendTelemetryEvent({\n eventName: \"DecodeSummaryMaxDepth\",\n maxDecodeDepth,\n });\n }\n const outstandingOpsBlob = baseSummary.blobs[outstandingOpsBlobKey];\n const newBaseSummary = baseSummary.trees[baseSummaryTreeKey];\n if (outstandingOpsBlob === undefined && newBaseSummary === undefined) {\n return {\n baseSummary,\n pathParts,\n async getOutstandingOps(readAndParseBlob: ReadAndParseBlob) {\n let outstandingOps: ISequencedDocumentMessage[] = [];\n for (const opsBlob of opsBlobs) {\n const newOutstandingOps = await readAndParseBlob<ISequencedDocumentMessage[]>(opsBlob);\n if (outstandingOps.length > 0 && newOutstandingOps.length > 0) {\n const latestSeq = outstandingOps[outstandingOps.length - 1].sequenceNumber;\n const newEarliestSeq = newOutstandingOps[0].sequenceNumber;\n if (newEarliestSeq <= latestSeq) {\n logger.sendTelemetryEvent({\n eventName:\"DuplicateOutstandingOps\",\n category: \"generic\",\n // eslint-disable-next-line max-len\n message: `newEarliestSeq <= latestSeq in decodeSummary: ${newEarliestSeq} <= ${latestSeq}`,\n });\n while (newOutstandingOps.length > 0\n && newOutstandingOps[0].sequenceNumber <= latestSeq) {\n newOutstandingOps.shift();\n }\n }\n }\n outstandingOps = outstandingOps.concat(newOutstandingOps);\n }\n return outstandingOps;\n },\n };\n }\n\n assert(!!outstandingOpsBlob, \"Outstanding ops blob missing, but base summary tree exists\");\n assert(newBaseSummary !== undefined, \"Base summary tree missing, but outstanding ops blob exists\");\n baseSummary = newBaseSummary;\n pathParts.push(baseSummaryTreeKey);\n opsBlobs.unshift(outstandingOpsBlob);\n }\n}\n\n/**\n * Summary tree which is a handle of the previous successfully acked summary\n * and a blob of the outstanding ops since that summary.\n */\ninterface IEncodedSummary extends ISummaryTreeWithStats {\n readonly additionalPath: EscapedPath;\n}\n\n/**\n * Parameter to help encode summary with conditional behavior.\n * When fromSummary is true, it will contain the SummaryNode of\n * its previous summary, which it can use to point to with a handle.\n * When fromSummary is false, it will use an actual summary tree\n * as its base summary in case the first summary is a differential summary.\n */\nexport type EncodeSummaryParam = {\n fromSummary: true;\n summaryNode: SummaryNode;\n} | {\n fromSummary: false;\n initialSummary: ISummaryTreeWithStats;\n};\n\n/**\n * Creates a summary tree which is a handle of the previous successfully acked summary\n * and a blob of the outstanding ops since that summary. If there is no acked summary yet,\n * it will create with the tree found in the initial attach op and the blob of outstanding ops.\n * @param summaryParam - information about last acked summary and paths to encode if from summary,\n * otherwise the initial summary from the attach op.\n * @param outstandingOps - outstanding ops since last acked summary\n */\nexport function encodeSummary(\n summaryParam: EncodeSummaryParam,\n outstandingOps: ISequencedDocumentMessage[],\n): IEncodedSummary {\n let additionalPath = EscapedPath.create(baseSummaryTreeKey);\n\n const builder = new SummaryTreeBuilder();\n builder.addBlob(outstandingOpsBlobKey, JSON.stringify(outstandingOps));\n\n if (summaryParam.fromSummary) {\n // Create using handle of latest acked summary\n const summaryNode = summaryParam.summaryNode;\n if (summaryNode.additionalPath !== undefined) {\n additionalPath = additionalPath.concat(summaryNode.additionalPath);\n }\n builder.addHandle(baseSummaryTreeKey, SummaryType.Tree, summaryNode.fullPath.path);\n } else {\n // Create using initial summary from attach op\n builder.addWithStats(baseSummaryTreeKey, summaryParam.initialSummary);\n }\n\n const summary = builder.getSummaryTree();\n return {\n ...summary,\n additionalPath,\n };\n}\n\n/**\n * Information about the initial summary tree found from an attach op.\n */\nexport interface IInitialSummary {\n sequenceNumber: number;\n id: string;\n summary: ISummaryTreeWithStats | undefined;\n}\n\n/**\n * Represents the details needed to create a child summarizer node.\n */\nexport interface ICreateChildDetails {\n /** Summary from attach op if known */\n initialSummary: IInitialSummary | undefined;\n /** Latest summary from server node data */\n latestSummary: SummaryNode | undefined;\n /** Sequence number of latest known change to the node */\n changeSequenceNumber: number;\n}\n\nexport interface ISubtreeInfo<T extends ISnapshotTree | SummaryObject> {\n /** Tree to use to find children subtrees */\n childrenTree: T,\n /** Additional path part where children are isolated */\n childrenPathPart: string | undefined,\n}\n\n/**\n * Checks if the summary contains .channels subtree where the children subtrees\n * would be located if exists.\n * @param baseSummary - summary to check\n */\nexport function parseSummaryForSubtrees(baseSummary: ISnapshotTree): ISubtreeInfo<ISnapshotTree> {\n // New versions of snapshots have child nodes isolated in .channels subtree\n const channelsSubtree = baseSummary.trees[channelsTreeName];\n if (channelsSubtree !== undefined) {\n return {\n childrenTree: channelsSubtree,\n childrenPathPart: channelsTreeName,\n };\n }\n return {\n childrenTree: baseSummary,\n childrenPathPart: undefined,\n };\n}\n\n/**\n * Checks if the summary contains .channels subtree where the children subtrees\n * would be located if exists.\n * @param baseSummary - summary to check\n */\nexport function parseSummaryTreeForSubtrees(summary: ISummaryTree): ISubtreeInfo<SummaryObject> {\n // New versions of snapshots have child nodes isolated in .channels subtree\n const channelsSubtree = summary.tree[channelsTreeName];\n if (channelsSubtree !== undefined) {\n return {\n childrenTree: channelsSubtree,\n childrenPathPart: channelsTreeName,\n };\n }\n return {\n childrenTree: summary,\n childrenPathPart: undefined,\n };\n}\n"]} | ||
| {"version":3,"file":"summarizerNodeUtils.js","sourceRoot":"","sources":["../../src/summarizerNode/summarizerNodeUtils.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { ITelemetryLogger } from \"@fluidframework/common-definitions\";\nimport { assert } from \"@fluidframework/common-utils\";\nimport {\n ISnapshotTree,\n IDocumentAttributes,\n ISequencedDocumentMessage,\n SummaryType,\n ISummaryTree,\n SummaryObject,\n} from \"@fluidframework/protocol-definitions\";\nimport { channelsTreeName, ISummaryTreeWithStats } from \"@fluidframework/runtime-definitions\";\nimport { SummaryTreeBuilder } from \"../summaryUtils\";\n\nconst baseSummaryTreeKey = \"_baseSummary\";\nconst outstandingOpsBlobKey = \"_outstandingOps\";\nconst maxDecodeDepth = 100;\n\n/** Reads a blob from storage and parses it from JSON. */\nexport type ReadAndParseBlob = <T>(id: string) => Promise<T>;\n\nexport interface ISummarizerNodeRootContract {\n startSummary(referenceSequenceNumber: number, summaryLogger: ITelemetryLogger): void;\n completeSummary(proposalHandle: string): void;\n clearSummary(): void;\n refreshLatestSummary(\n proposalHandle: string | undefined,\n getSnapshot: () => Promise<ISnapshotTree>,\n readAndParseBlob: ReadAndParseBlob,\n correlatedSummaryLogger: ITelemetryLogger,\n ): Promise<void>;\n}\n\n/**\n * Fetches the sequence number of the snapshot tree by examining the protocol.\n * @param tree - snapshot tree to examine\n * @param readAndParseBlob - function to read blob contents from storage\n * and parse the result from JSON.\n */\nexport async function seqFromTree(\n tree: ISnapshotTree,\n readAndParseBlob: ReadAndParseBlob,\n): Promise<number> {\n const attributesHash = tree.trees[\".protocol\"].blobs.attributes;\n const attrib = await readAndParseBlob<IDocumentAttributes>(attributesHash);\n return attrib.sequenceNumber;\n}\n\n/** Path for nodes in a tree with escaped special characters */\nexport class EscapedPath {\n private constructor(public readonly path: string) { }\n public static create(path: string): EscapedPath {\n return new EscapedPath(encodeURIComponent(path));\n }\n public static createAndConcat(pathParts: string[]): EscapedPath {\n let ret = EscapedPath.create(pathParts[0] ?? \"\");\n for (let i = 1; i < pathParts.length; i++) {\n ret = ret.concat(EscapedPath.create(pathParts[i]));\n }\n return ret;\n }\n public toString(): string {\n return this.path;\n }\n public concat(path: EscapedPath): EscapedPath {\n return new EscapedPath(`${this.path}/${path.path}`);\n }\n}\n\n/** Information about a summary relevant to a specific node in the tree */\nexport class SummaryNode {\n /** Creates an instance that is valid for the root with specific basePath and localPath */\n public static createForRoot(referenceSequenceNumber: number): SummaryNode {\n return new SummaryNode({\n referenceSequenceNumber,\n basePath: undefined,\n localPath: EscapedPath.create(\"\"), // root hard-coded to \"\"\n });\n }\n\n /** Summary reference sequence number, i.e. last sequence number seen when it was created */\n public get referenceSequenceNumber(): number {\n return this.summary.referenceSequenceNumber;\n }\n /** Full path to parent node, or undefined if this is the root */\n public get basePath(): EscapedPath | undefined {\n return this.summary.basePath;\n }\n /** Relative path to this node from its parent node */\n public get localPath(): EscapedPath {\n return this.summary.localPath;\n }\n /** Relative path from this node to its node innermost base summary */\n public get additionalPath(): EscapedPath | undefined {\n return this.summary.additionalPath;\n }\n public set additionalPath(additionalPath: EscapedPath | undefined) {\n this.summary.additionalPath = additionalPath;\n }\n constructor(private readonly summary: {\n readonly referenceSequenceNumber: number,\n readonly basePath: EscapedPath | undefined,\n readonly localPath: EscapedPath,\n additionalPath?: EscapedPath,\n }) { }\n\n /** Gets the full path to this node, to be used when sending a handle */\n public get fullPath(): EscapedPath {\n return this.basePath?.concat(this.localPath) ?? this.localPath;\n }\n\n /**\n * Gets the full path to this node's innermost base summary.\n * The children nodes can use this as their basePath to determine their path.\n */\n public get fullPathForChildren(): EscapedPath {\n return this.additionalPath !== undefined\n ? this.fullPath.concat(this.additionalPath)\n : this.fullPath;\n }\n\n /**\n * Creates a new node within the same summary for a child of this node.\n * @param id - id of the child node\n */\n public createForChild(id: string): SummaryNode {\n return new SummaryNode({\n referenceSequenceNumber: this.referenceSequenceNumber,\n basePath: this.fullPathForChildren,\n localPath: EscapedPath.create(id),\n });\n }\n}\n\n/** Result from decoding summary which may have been a differential summary. */\ninterface IDecodedSummary {\n /** The innermost base summary which is not itself a differential summary */\n readonly baseSummary: ISnapshotTree;\n /** The entire path name to the innermost base summary */\n readonly pathParts: string[];\n /** Function to fetch all outstanding ops since the innermost base summary */\n getOutstandingOps(readAndParseBlob: ReadAndParseBlob): Promise<ISequencedDocumentMessage[]>;\n}\n\n/**\n * Checks if the snapshot is created by referencing a previous successful\n * summary plus outstanding ops. If so, it will recursively \"decode\" it until\n * it gets to the last successful summary (the base summary) and returns that\n * as well as a function for fetching the outstanding ops. Also returns the\n * full path to the previous base summary for child summarizer nodes to use as\n * their base path when necessary.\n * @param snapshot - snapshot tree to decode\n */\nexport function decodeSummary(\n snapshot: ISnapshotTree,\n logger: Pick<ITelemetryLogger, \"sendTelemetryEvent\">,\n): IDecodedSummary {\n let baseSummary = snapshot;\n const pathParts: string[] = [];\n const opsBlobs: string[] = [];\n\n for (let i = 0; ; i++) {\n if (i > maxDecodeDepth) {\n logger.sendTelemetryEvent({\n eventName: \"DecodeSummaryMaxDepth\",\n maxDecodeDepth,\n });\n }\n const outstandingOpsBlob = baseSummary.blobs[outstandingOpsBlobKey];\n const newBaseSummary = baseSummary.trees[baseSummaryTreeKey];\n if (outstandingOpsBlob === undefined && newBaseSummary === undefined) {\n return {\n baseSummary,\n pathParts,\n async getOutstandingOps(readAndParseBlob: ReadAndParseBlob) {\n let outstandingOps: ISequencedDocumentMessage[] = [];\n for (const opsBlob of opsBlobs) {\n const newOutstandingOps = await readAndParseBlob<ISequencedDocumentMessage[]>(opsBlob);\n if (outstandingOps.length > 0 && newOutstandingOps.length > 0) {\n const latestSeq = outstandingOps[outstandingOps.length - 1].sequenceNumber;\n const newEarliestSeq = newOutstandingOps[0].sequenceNumber;\n if (newEarliestSeq <= latestSeq) {\n logger.sendTelemetryEvent({\n eventName:\"DuplicateOutstandingOps\",\n category: \"generic\",\n // eslint-disable-next-line max-len\n message: `newEarliestSeq <= latestSeq in decodeSummary: ${newEarliestSeq} <= ${latestSeq}`,\n });\n while (newOutstandingOps.length > 0\n && newOutstandingOps[0].sequenceNumber <= latestSeq) {\n newOutstandingOps.shift();\n }\n }\n }\n outstandingOps = outstandingOps.concat(newOutstandingOps);\n }\n return outstandingOps;\n },\n };\n }\n\n assert(!!outstandingOpsBlob, 0x1af /* \"Outstanding ops blob missing, but base summary tree exists\" */);\n assert(newBaseSummary !== undefined, 0x1b0 /* \"Base summary tree missing, but outstanding ops blob exists\" */);\n baseSummary = newBaseSummary;\n pathParts.push(baseSummaryTreeKey);\n opsBlobs.unshift(outstandingOpsBlob);\n }\n}\n\n/**\n * Summary tree which is a handle of the previous successfully acked summary\n * and a blob of the outstanding ops since that summary.\n */\ninterface IEncodedSummary extends ISummaryTreeWithStats {\n readonly additionalPath: EscapedPath;\n}\n\n/**\n * Parameter to help encode summary with conditional behavior.\n * When fromSummary is true, it will contain the SummaryNode of\n * its previous summary, which it can use to point to with a handle.\n * When fromSummary is false, it will use an actual summary tree\n * as its base summary in case the first summary is a differential summary.\n */\nexport type EncodeSummaryParam = {\n fromSummary: true;\n summaryNode: SummaryNode;\n} | {\n fromSummary: false;\n initialSummary: ISummaryTreeWithStats;\n};\n\n/**\n * Creates a summary tree which is a handle of the previous successfully acked summary\n * and a blob of the outstanding ops since that summary. If there is no acked summary yet,\n * it will create with the tree found in the initial attach op and the blob of outstanding ops.\n * @param summaryParam - information about last acked summary and paths to encode if from summary,\n * otherwise the initial summary from the attach op.\n * @param outstandingOps - outstanding ops since last acked summary\n */\nexport function encodeSummary(\n summaryParam: EncodeSummaryParam,\n outstandingOps: ISequencedDocumentMessage[],\n): IEncodedSummary {\n let additionalPath = EscapedPath.create(baseSummaryTreeKey);\n\n const builder = new SummaryTreeBuilder();\n builder.addBlob(outstandingOpsBlobKey, JSON.stringify(outstandingOps));\n\n if (summaryParam.fromSummary) {\n // Create using handle of latest acked summary\n const summaryNode = summaryParam.summaryNode;\n if (summaryNode.additionalPath !== undefined) {\n additionalPath = additionalPath.concat(summaryNode.additionalPath);\n }\n builder.addHandle(baseSummaryTreeKey, SummaryType.Tree, summaryNode.fullPath.path);\n } else {\n // Create using initial summary from attach op\n builder.addWithStats(baseSummaryTreeKey, summaryParam.initialSummary);\n }\n\n const summary = builder.getSummaryTree();\n return {\n ...summary,\n additionalPath,\n };\n}\n\n/**\n * Information about the initial summary tree found from an attach op.\n */\nexport interface IInitialSummary {\n sequenceNumber: number;\n id: string;\n summary: ISummaryTreeWithStats | undefined;\n}\n\n/**\n * Represents the details needed to create a child summarizer node.\n */\nexport interface ICreateChildDetails {\n /** Summary from attach op if known */\n initialSummary: IInitialSummary | undefined;\n /** Latest summary from server node data */\n latestSummary: SummaryNode | undefined;\n /** Sequence number of latest known change to the node */\n changeSequenceNumber: number;\n}\n\nexport interface ISubtreeInfo<T extends ISnapshotTree | SummaryObject> {\n /** Tree to use to find children subtrees */\n childrenTree: T,\n /** Additional path part where children are isolated */\n childrenPathPart: string | undefined,\n}\n\n/**\n * Checks if the summary contains .channels subtree where the children subtrees\n * would be located if exists.\n * @param baseSummary - summary to check\n */\nexport function parseSummaryForSubtrees(baseSummary: ISnapshotTree): ISubtreeInfo<ISnapshotTree> {\n // New versions of snapshots have child nodes isolated in .channels subtree\n const channelsSubtree = baseSummary.trees[channelsTreeName];\n if (channelsSubtree !== undefined) {\n return {\n childrenTree: channelsSubtree,\n childrenPathPart: channelsTreeName,\n };\n }\n return {\n childrenTree: baseSummary,\n childrenPathPart: undefined,\n };\n}\n\n/**\n * Checks if the summary contains .channels subtree where the children subtrees\n * would be located if exists.\n * @param baseSummary - summary to check\n */\nexport function parseSummaryTreeForSubtrees(summary: ISummaryTree): ISubtreeInfo<SummaryObject> {\n // New versions of snapshots have child nodes isolated in .channels subtree\n const channelsSubtree = summary.tree[channelsTreeName];\n if (channelsSubtree !== undefined) {\n return {\n childrenTree: channelsSubtree,\n childrenPathPart: channelsTreeName,\n };\n }\n return {\n childrenTree: summary,\n childrenPathPart: undefined,\n };\n}\n"]} |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"summarizerNodeWithGc.d.ts","sourceRoot":"","sources":["../../src/summarizerNode/summarizerNodeWithGc.ts"],"names":[],"mappings":"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"} | ||
| {"version":3,"file":"summarizerNodeWithGc.d.ts","sourceRoot":"","sources":["../../src/summarizerNode/summarizerNodeWithGc.ts"],"names":[],"mappings":"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"} |
@@ -81,3 +81,3 @@ "use strict"; | ||
| if (!this.gcDisabled && this.isTrackingInProgress()) { | ||
| common_utils_1.assert(this.wipSerializedUsedRoutes !== undefined, "wip used routes should be set if tracking a summary"); | ||
| common_utils_1.assert(this.wipSerializedUsedRoutes !== undefined, 0x1b1 /* "wip used routes should be set if tracking a summary" */); | ||
| } | ||
@@ -88,3 +88,3 @@ // If trackState is true, get summary from base summarizer node which tracks summary state. | ||
| const summarizeResult = await super.summarize(fullTree); | ||
| // If there is no cached GC data, return empty data in summarize result. It is the caller's responsiblity | ||
| // If there is no cached GC data, return empty data in summarize result. It is the caller's responsibility | ||
| // to ensure that GC data is available by calling getGCData before calling summarize. | ||
@@ -109,4 +109,4 @@ const gcData = this.gcData !== undefined ? garbage_collector_1.cloneGCData(this.gcData) : { gcNodes: {} }; | ||
| async getGCData(fullGC = false) { | ||
| common_utils_1.assert(!this.gcDisabled, "Getting GC data should not be called when GC is disabled!"); | ||
| common_utils_1.assert(this.getGCDataFn !== undefined, "GC data cannot be retrieved without getGCDataFn"); | ||
| common_utils_1.assert(!this.gcDisabled, 0x1b2 /* "Getting GC data should not be called when GC is disabled!" */); | ||
| common_utils_1.assert(this.getGCDataFn !== undefined, 0x1b3 /* "GC data cannot be retrieved without getGCDataFn" */); | ||
| // Load GC details from the initial summary, if not already loaded. If this is the first time this function is | ||
@@ -131,3 +131,3 @@ // called and the node's data has not changed since last summary, the GC data in initial details is returned. | ||
| if (!this.gcDisabled) { | ||
| common_utils_1.assert(this.wipSerializedUsedRoutes === undefined, "We should not already be tracking used routes when to track a new summary"); | ||
| common_utils_1.assert(this.wipSerializedUsedRoutes === undefined, 0x1b4 /* "We should not already be tracking used routes when to track a new summary" */); | ||
| // back-compat: 0.33 - This will be done in `updateUsedRoutes`. Older clients do not have that method, so | ||
@@ -148,3 +148,3 @@ // keeping this one for now. | ||
| wipSerializedUsedRoutes = this.wipSerializedUsedRoutes; | ||
| common_utils_1.assert(wipSerializedUsedRoutes !== undefined, "We should have been tracking used routes"); | ||
| common_utils_1.assert(wipSerializedUsedRoutes !== undefined, 0x1b5 /* "We should have been tracking used routes" */); | ||
| } | ||
@@ -217,3 +217,3 @@ super.completeSummaryCore(proposalHandle, parentPath, parentSkipRecursion); | ||
| var _a; | ||
| common_utils_1.assert(!this.children.has(id), "Create SummarizerNode child already exists"); | ||
| common_utils_1.assert(!this.children.has(id), 0x1b6 /* "Create SummarizerNode child already exists" */); | ||
| const createDetails = this.getCreateDetailsForChild(id, createParam); | ||
@@ -220,0 +220,0 @@ const child = new SummarizerNodeWithGC(this.defaultLogger, summarizeInternalFn, Object.assign(Object.assign({}, config), { |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"summarizerNodeWithGc.js","sourceRoot":"","sources":["../../src/summarizerNode/summarizerNodeWithGc.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { ITelemetryLogger } from \"@fluidframework/common-definitions\";\nimport { assert, LazyPromise } from \"@fluidframework/common-utils\";\nimport { cloneGCData } from \"@fluidframework/garbage-collector\";\nimport { ISnapshotTree } from \"@fluidframework/protocol-definitions\";\nimport {\n CreateChildSummarizerNodeParam,\n gcBlobKey,\n IContextSummarizeResult,\n IGarbageCollectionData,\n IGarbageCollectionSummaryDetails,\n ISummarizeInternalResult,\n ISummarizerNodeConfigWithGC,\n ISummarizerNodeWithGC,\n} from \"@fluidframework/runtime-definitions\";\nimport { SummarizerNode } from \"./summarizerNode\";\nimport {\n EscapedPath,\n ICreateChildDetails,\n IInitialSummary,\n ISummarizerNodeRootContract,\n ReadAndParseBlob,\n SummaryNode,\n} from \"./summarizerNodeUtils\";\n\nexport interface IRootSummarizerNodeWithGC extends ISummarizerNodeWithGC, ISummarizerNodeRootContract {}\n\n// Extend SummaryNode to add used routes tracking to it.\nclass SummaryNodeWithGC extends SummaryNode {\n constructor(\n public readonly serializedUsedRoutes: string,\n summary: {\n readonly referenceSequenceNumber: number,\n readonly basePath: EscapedPath | undefined,\n readonly localPath: EscapedPath,\n additionalPath?: EscapedPath,\n },\n ) {\n super(summary);\n }\n}\n\n/**\n * Extends the functionality of SummarizerNode to manage this node's garbage collection data:\n * - Adds a new API `getGCData` to return GC data of this node.\n * - Caches the result of `getGCData` to be used if nothing changes between summaries.\n * - Adds GC data to the result of summarize.\n * - Manages the used routes of this node. These are used to identify if this node is referenced in the document\n * and to determine if the node's used state changed since last summary.\n * - Adds trackState param to summarize. If trackState is false, it bypasses the SummarizerNode and calls\n * directly into summarizeInternal method.\n */\nexport class SummarizerNodeWithGC extends SummarizerNode implements IRootSummarizerNodeWithGC {\n private gcData: IGarbageCollectionData | undefined;\n\n // Tracks the work-in-progress used routes during summary.\n private wipSerializedUsedRoutes: string | undefined;\n\n // This is the last known used routes of this node as seen by the server as part of a summary.\n private referenceUsedRoutes: string[] | undefined;\n\n // The GC details of this node in the initial summary.\n private readonly gcDetailsInInitialSummaryP: LazyPromise<IGarbageCollectionSummaryDetails>;\n\n // Set used routes to have self route by default. This makes the node referenced by default. This is done to ensure\n // that this node is not marked as collected when running GC has been disabled. Once, the option to disable GC is\n // removed (from runGC flag in IContainerRuntimeOptions), this should be changed to be have no routes by default.\n private _usedRoutes: string[] = [\"\"];\n public get usedRoutes(): string[] {\n return this._usedRoutes;\n }\n\n // True if GC is disabled for this node. If so, do not track GC specific state for a summary.\n private readonly gcDisabled: boolean;\n\n /**\n * Do not call constructor directly.\n * Use createRootSummarizerNodeWithGC to create root node, or createChild to create child nodes.\n */\n public constructor(\n logger: ITelemetryLogger,\n private readonly summarizeFn: (fullTree: boolean, trackState: boolean) => Promise<ISummarizeInternalResult>,\n config: ISummarizerNodeConfigWithGC,\n changeSequenceNumber: number,\n /** Undefined means created without summary */\n latestSummary?: SummaryNode,\n initialSummary?: IInitialSummary,\n wipSummaryLogger?: ITelemetryLogger,\n private readonly getGCDataFn?: (fullGC?: boolean) => Promise<IGarbageCollectionData>,\n getInitialGCSummaryDetailsFn?: () => Promise<IGarbageCollectionSummaryDetails>,\n ) {\n super(\n logger,\n async (fullTree: boolean) => this.summarizeInternal(fullTree, true /* trackState */),\n config,\n changeSequenceNumber,\n latestSummary,\n initialSummary,\n wipSummaryLogger,\n );\n\n this.gcDisabled = config.gcDisabled === true;\n\n this.gcDetailsInInitialSummaryP = new LazyPromise(async () => {\n // back-compat: 0.32. getInitialGCSummaryDetailsFn() returns undefined in 0.31. Remove undefined check\n // when N > 34.\n const gcSummaryDetails = await getInitialGCSummaryDetailsFn?.();\n return gcSummaryDetails ?? { usedRoutes: [] };\n });\n }\n\n /**\n * Loads state from this node's initial GC summary details. This contains the following data from the last summary\n * seen by the server for this client:\n * - usedRoutes: This is used to figure out if the used state of this node changed since last summary.\n * - gcData: The garbage collection data of this node that is required for running GC.\n */\n private async loadInitialGCSummaryDetails() {\n // If referenceUsedRoutes is not undefined, don't do anything because we have already initialized.\n if (this.referenceUsedRoutes === undefined) {\n const gcDetailsInInitialSummary = await this.gcDetailsInInitialSummaryP;\n this.referenceUsedRoutes = gcDetailsInInitialSummary.usedRoutes;\n\n // If the GC details has GC data, initialize our GC data from it.\n if (gcDetailsInInitialSummary.gcData !== undefined) {\n this.gcData = cloneGCData(gcDetailsInInitialSummary.gcData);\n }\n }\n }\n\n public async summarize(fullTree: boolean, trackState: boolean = true): Promise<IContextSummarizeResult> {\n // Load GC details from the initial summary, if it's not already loaded. If this is the first time this node is\n // being summarized, the used routes in it are needed to find out if this node has changed since last summary.\n // If it hasn't changed, the GC data in it needs to be returned as part of the summary.\n await this.loadInitialGCSummaryDetails();\n\n // If GC is not disabled and we are tracking a summary, GC should have run and updated the used routes for this\n // summary by calling updateUsedRoutes which sets wipSerializedUsedRoutes.\n if (!this.gcDisabled && this.isTrackingInProgress()) {\n assert(this.wipSerializedUsedRoutes !== undefined, \"wip used routes should be set if tracking a summary\");\n }\n\n // If trackState is true, get summary from base summarizer node which tracks summary state.\n // If trackState is false, get summary from summarizeInternal.\n if (trackState) {\n const summarizeResult = await super.summarize(fullTree);\n\n // If there is no cached GC data, return empty data in summarize result. It is the caller's responsiblity\n // to ensure that GC data is available by calling getGCData before calling summarize.\n const gcData = this.gcData !== undefined ? cloneGCData(this.gcData) : { gcNodes: {} };\n\n return {\n ...summarizeResult,\n gcData,\n };\n } else {\n return this.summarizeInternal(fullTree, trackState);\n }\n }\n\n private async summarizeInternal(fullTree: boolean, trackState: boolean): Promise<ISummarizeInternalResult> {\n const summarizeResult = await this.summarizeFn(fullTree, trackState);\n this.gcData = cloneGCData(summarizeResult.gcData);\n return summarizeResult;\n }\n\n /**\n * Returns the GC data of this node. If nothing has changed since last summary, it tries to reuse the data from\n * the previous summary. Else, it gets new GC data from the underlying Fluid object.\n * @param fullGC - true to bypass optimizations and force full generation of GC data.\n */\n public async getGCData(fullGC: boolean = false): Promise<IGarbageCollectionData> {\n assert(!this.gcDisabled, \"Getting GC data should not be called when GC is disabled!\");\n assert(this.getGCDataFn !== undefined, \"GC data cannot be retrieved without getGCDataFn\");\n\n // Load GC details from the initial summary, if not already loaded. If this is the first time this function is\n // called and the node's data has not changed since last summary, the GC data in initial details is returned.\n await this.loadInitialGCSummaryDetails();\n\n // If there is no new data since last summary and we have GC data from the previous run, return it. We may not\n // have data from previous GC run for clients with older summary format before GC was added. They won't have\n // GC details in their initial summary.\n if (!fullGC && !this.hasDataChanged() && this.gcData !== undefined) {\n return cloneGCData(this.gcData);\n }\n\n const gcData = await this.getGCDataFn(fullGC);\n this.gcData = cloneGCData(gcData);\n return gcData;\n }\n\n /**\n * Called during the start of a summary. Updates the work-in-progress used routes.\n */\n public startSummary(referenceSequenceNumber: number, summaryLogger: ITelemetryLogger) {\n // If GC is disabled, skip setting wip used routes since we should not track GC state.\n if (!this.gcDisabled) {\n assert(\n this.wipSerializedUsedRoutes === undefined,\n \"We should not already be tracking used routes when to track a new summary\");\n\n // back-compat: 0.33 - This will be done in `updateUsedRoutes`. Older clients do not have that method, so\n // keeping this one for now.\n this.wipSerializedUsedRoutes = JSON.stringify(this.usedRoutes);\n }\n super.startSummary(referenceSequenceNumber, summaryLogger);\n }\n\n /**\n * Called after summary has been uploaded to the server. Add the work-in-progress state to the pending\n * summary queue. We track this until we get an ack from the server for this summary.\n */\n protected completeSummaryCore(\n proposalHandle: string,\n parentPath: EscapedPath | undefined,\n parentSkipRecursion: boolean,\n ) {\n let wipSerializedUsedRoutes: string | undefined;\n // If GC is disabled, don't set wip used routes.\n if (!this.gcDisabled) {\n wipSerializedUsedRoutes = this.wipSerializedUsedRoutes;\n assert(wipSerializedUsedRoutes !== undefined, \"We should have been tracking used routes\");\n }\n\n super.completeSummaryCore(proposalHandle, parentPath, parentSkipRecursion);\n\n // If GC is disabled, skip setting pending summary with GC state.\n if (!this.gcDisabled) {\n const summaryNode = this.pendingSummaries.get(proposalHandle);\n if (summaryNode !== undefined) {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const summaryNodeWithGC = new SummaryNodeWithGC(wipSerializedUsedRoutes!, summaryNode);\n this.pendingSummaries.set(proposalHandle, summaryNodeWithGC);\n }\n }\n }\n\n /**\n * Clears the work-in-progress state.\n */\n public clearSummary() {\n this.wipSerializedUsedRoutes = undefined;\n super.clearSummary();\n }\n\n /**\n * Called when we get an ack from the server for a summary we sent. Update the reference state of this node\n * from the state in the pending summary queue.\n */\n protected refreshLatestSummaryFromPending(\n proposalHandle: string,\n referenceSequenceNumber: number,\n ): void {\n // If GC is disabled, skip setting referenced used routes since we are not tracking GC state.\n if (!this.gcDisabled) {\n const summaryNode = this.pendingSummaries.get(proposalHandle) as SummaryNodeWithGC;\n if (summaryNode !== undefined) {\n this.referenceUsedRoutes = JSON.parse(summaryNode.serializedUsedRoutes);\n }\n }\n\n return super.refreshLatestSummaryFromPending(proposalHandle, referenceSequenceNumber);\n }\n\n /**\n * Called when we need to upload the reference state from the given summary. Read the GC blob and get the state\n * to upload from it.\n */\n protected async refreshLatestSummaryFromSnapshot(\n referenceSequenceNumber: number,\n snapshotTree: ISnapshotTree,\n basePath: EscapedPath | undefined,\n localPath: EscapedPath,\n correlatedSummaryLogger: ITelemetryLogger,\n readAndParseBlob: ReadAndParseBlob,\n ): Promise<void> {\n // If GC is disabled, skip setting referenced used routes since we are not tracking GC state.\n if (!this.gcDisabled) {\n const gcDetailsBlob = snapshotTree.blobs[gcBlobKey];\n if (gcDetailsBlob !== undefined) {\n const gcDetails = await readAndParseBlob<IGarbageCollectionSummaryDetails>(gcDetailsBlob);\n\n // Possible re-entrancy. If we have already seen a summary later than this one, ignore it.\n if (this.referenceSequenceNumber >= referenceSequenceNumber) {\n return;\n }\n\n this.referenceUsedRoutes = gcDetails.usedRoutes;\n }\n }\n\n return super.refreshLatestSummaryFromSnapshot(\n referenceSequenceNumber,\n snapshotTree,\n basePath,\n localPath,\n correlatedSummaryLogger,\n readAndParseBlob,\n );\n }\n\n /**\n * Override the createChild method to return an instance of SummarizerNodeWithGC.\n */\n public createChild(\n /** Summarize function */\n summarizeInternalFn: (fullTree: boolean, trackState: boolean) => Promise<ISummarizeInternalResult>,\n /** Initial id or path part of this node */\n id: string,\n /**\n * Information needed to create the node.\n * If it is from a base summary, it will assert that a summary has been seen.\n * Attach information if it is created from an attach op.\n */\n createParam: CreateChildSummarizerNodeParam,\n config: ISummarizerNodeConfigWithGC = {},\n getGCDataFn?: (fullGC?: boolean) => Promise<IGarbageCollectionData>,\n getInitialGCSummaryDetailsFn?: () => Promise<IGarbageCollectionSummaryDetails>,\n ): ISummarizerNodeWithGC {\n assert(!this.children.has(id), \"Create SummarizerNode child already exists\");\n\n const createDetails: ICreateChildDetails = this.getCreateDetailsForChild(id, createParam);\n const child = new SummarizerNodeWithGC(\n this.defaultLogger,\n summarizeInternalFn,\n {\n ...config,\n // Propagate our gcDisabled state to the child if its not explicity specified in child's config.\n gcDisabled: config.gcDisabled ?? this.gcDisabled,\n },\n createDetails.changeSequenceNumber,\n createDetails.latestSummary,\n createDetails.initialSummary,\n this.wipSummaryLogger,\n getGCDataFn,\n getInitialGCSummaryDetailsFn,\n );\n\n // back-compat: 0.33 - If a child is created during summarize, its wip used routes will updated in\n // `updateUsedRoutes` method. For older clients, do it here since that method does not exist.\n\n // There may be additional state that has to be updated in this child. For example, if a summary is being\n // tracked, the child's summary tracking state needs to be updated too.\n this.maybeUpdateChildState(child);\n\n this.children.set(id, child);\n return child;\n }\n\n /**\n * Override the getChild method to return an instance of SummarizerNodeWithGC.\n */\n public getChild(id: string): ISummarizerNodeWithGC | undefined {\n return this.children.get(id) as SummarizerNodeWithGC;\n }\n\n public isReferenced(): boolean {\n return this.usedRoutes.includes(\"\") || this.usedRoutes.includes(\"/\");\n }\n\n public updateUsedRoutes(usedRoutes: string[]) {\n // Sort the given routes before updating. This will ensure that the routes compared in hasUsedStateChanged()\n // are in the same order.\n this._usedRoutes = usedRoutes.sort();\n\n // If GC is not disabled and we are tracking a summary, update the work-in-progress used routes so that it can\n // be tracked for this summary.\n if (!this.gcDisabled && this.isTrackingInProgress()) {\n this.wipSerializedUsedRoutes = JSON.stringify(this.usedRoutes);\n }\n }\n\n /**\n * Override the hasChanged method. If this node data or its used state changed, the node is considered changed.\n */\n protected hasChanged(): boolean {\n return this.hasDataChanged() || this.hasUsedStateChanged();\n }\n\n /**\n * This tells whether the data in this node has changed or not.\n */\n private hasDataChanged(): boolean {\n return super.hasChanged();\n }\n\n /**\n * This tells whether the used state of this node has changed since last successful summary. If the used routes\n * of this node changed, its used state is considered changed. Basically, if this node or any of its child nodes\n * was previously used and became unused (or vice versa), its used state has changed.\n */\n private hasUsedStateChanged(): boolean {\n // If GC is disabled, we are not tracking used state, return false.\n if (this.gcDisabled) {\n return false;\n }\n\n return this.referenceUsedRoutes === undefined ||\n JSON.stringify(this.usedRoutes) !== JSON.stringify(this.referenceUsedRoutes);\n }\n\n /**\n * Updates the work-in-progress state of the child if summary is in progress.\n * @param child - The child node to be updated.\n */\n protected maybeUpdateChildState(child: SummarizerNodeWithGC) {\n if (this.isTrackingInProgress()) {\n // Update the child's work-in-progress used routes.\n child.updateUsedRoutes(child.usedRoutes);\n }\n super.maybeUpdateChildState(child);\n }\n}\n\n/**\n * Creates a root summarizer node with GC functionality built-in.\n * @param logger - Logger to use within SummarizerNode\n * @param summarizeInternalFn - Function to generate summary\n * @param changeSequenceNumber - Sequence number of latest change to new node/subtree\n * @param referenceSequenceNumber - Reference sequence number of last acked summary,\n * or undefined if not loaded from summary\n * @param config - Configure behavior of summarizer node\n * @param getGCDataFn - Function to get the GC data of this node\n * @param gcDetailsInInitialSummaryP - Function to get the initial GC details of this node\n */\nexport const createRootSummarizerNodeWithGC = (\n logger: ITelemetryLogger,\n summarizeInternalFn: (fullTree: boolean, trackState: boolean) => Promise<ISummarizeInternalResult>,\n changeSequenceNumber: number,\n referenceSequenceNumber: number | undefined,\n config: ISummarizerNodeConfigWithGC = {},\n getGCDataFn?: (fullGC?: boolean) => Promise<IGarbageCollectionData>,\n getInitialGCSummaryDetailsFn?: () => Promise<IGarbageCollectionSummaryDetails>,\n): IRootSummarizerNodeWithGC => new SummarizerNodeWithGC(\n logger,\n summarizeInternalFn,\n config,\n changeSequenceNumber,\n referenceSequenceNumber === undefined ? undefined : SummaryNode.createForRoot(referenceSequenceNumber),\n undefined /* initialSummary */,\n undefined /* wipSummaryLogger */,\n getGCDataFn,\n getInitialGCSummaryDetailsFn,\n);\n"]} | ||
| {"version":3,"file":"summarizerNodeWithGc.js","sourceRoot":"","sources":["../../src/summarizerNode/summarizerNodeWithGc.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { ITelemetryLogger } from \"@fluidframework/common-definitions\";\nimport { assert, LazyPromise } from \"@fluidframework/common-utils\";\nimport { cloneGCData } from \"@fluidframework/garbage-collector\";\nimport { ISnapshotTree } from \"@fluidframework/protocol-definitions\";\nimport {\n CreateChildSummarizerNodeParam,\n gcBlobKey,\n IContextSummarizeResult,\n IGarbageCollectionData,\n IGarbageCollectionSummaryDetails,\n ISummarizeInternalResult,\n ISummarizerNodeConfigWithGC,\n ISummarizerNodeWithGC,\n} from \"@fluidframework/runtime-definitions\";\nimport { SummarizerNode } from \"./summarizerNode\";\nimport {\n EscapedPath,\n ICreateChildDetails,\n IInitialSummary,\n ISummarizerNodeRootContract,\n ReadAndParseBlob,\n SummaryNode,\n} from \"./summarizerNodeUtils\";\n\nexport interface IRootSummarizerNodeWithGC extends ISummarizerNodeWithGC, ISummarizerNodeRootContract {}\n\n// Extend SummaryNode to add used routes tracking to it.\nclass SummaryNodeWithGC extends SummaryNode {\n constructor(\n public readonly serializedUsedRoutes: string,\n summary: {\n readonly referenceSequenceNumber: number,\n readonly basePath: EscapedPath | undefined,\n readonly localPath: EscapedPath,\n additionalPath?: EscapedPath,\n },\n ) {\n super(summary);\n }\n}\n\n/**\n * Extends the functionality of SummarizerNode to manage this node's garbage collection data:\n * - Adds a new API `getGCData` to return GC data of this node.\n * - Caches the result of `getGCData` to be used if nothing changes between summaries.\n * - Adds GC data to the result of summarize.\n * - Manages the used routes of this node. These are used to identify if this node is referenced in the document\n * and to determine if the node's used state changed since last summary.\n * - Adds trackState param to summarize. If trackState is false, it bypasses the SummarizerNode and calls\n * directly into summarizeInternal method.\n */\nexport class SummarizerNodeWithGC extends SummarizerNode implements IRootSummarizerNodeWithGC {\n private gcData: IGarbageCollectionData | undefined;\n\n // Tracks the work-in-progress used routes during summary.\n private wipSerializedUsedRoutes: string | undefined;\n\n // This is the last known used routes of this node as seen by the server as part of a summary.\n private referenceUsedRoutes: string[] | undefined;\n\n // The GC details of this node in the initial summary.\n private readonly gcDetailsInInitialSummaryP: LazyPromise<IGarbageCollectionSummaryDetails>;\n\n // Set used routes to have self route by default. This makes the node referenced by default. This is done to ensure\n // that this node is not marked as collected when running GC has been disabled. Once, the option to disable GC is\n // removed (from runGC flag in IContainerRuntimeOptions), this should be changed to be have no routes by default.\n private _usedRoutes: string[] = [\"\"];\n public get usedRoutes(): string[] {\n return this._usedRoutes;\n }\n\n // True if GC is disabled for this node. If so, do not track GC specific state for a summary.\n private readonly gcDisabled: boolean;\n\n /**\n * Do not call constructor directly.\n * Use createRootSummarizerNodeWithGC to create root node, or createChild to create child nodes.\n */\n public constructor(\n logger: ITelemetryLogger,\n private readonly summarizeFn: (fullTree: boolean, trackState: boolean) => Promise<ISummarizeInternalResult>,\n config: ISummarizerNodeConfigWithGC,\n changeSequenceNumber: number,\n /** Undefined means created without summary */\n latestSummary?: SummaryNode,\n initialSummary?: IInitialSummary,\n wipSummaryLogger?: ITelemetryLogger,\n private readonly getGCDataFn?: (fullGC?: boolean) => Promise<IGarbageCollectionData>,\n getInitialGCSummaryDetailsFn?: () => Promise<IGarbageCollectionSummaryDetails>,\n ) {\n super(\n logger,\n async (fullTree: boolean) => this.summarizeInternal(fullTree, true /* trackState */),\n config,\n changeSequenceNumber,\n latestSummary,\n initialSummary,\n wipSummaryLogger,\n );\n\n this.gcDisabled = config.gcDisabled === true;\n\n this.gcDetailsInInitialSummaryP = new LazyPromise(async () => {\n // back-compat: 0.32. getInitialGCSummaryDetailsFn() returns undefined in 0.31. Remove undefined check\n // when N > 34.\n const gcSummaryDetails = await getInitialGCSummaryDetailsFn?.();\n return gcSummaryDetails ?? { usedRoutes: [] };\n });\n }\n\n /**\n * Loads state from this node's initial GC summary details. This contains the following data from the last summary\n * seen by the server for this client:\n * - usedRoutes: This is used to figure out if the used state of this node changed since last summary.\n * - gcData: The garbage collection data of this node that is required for running GC.\n */\n private async loadInitialGCSummaryDetails() {\n // If referenceUsedRoutes is not undefined, don't do anything because we have already initialized.\n if (this.referenceUsedRoutes === undefined) {\n const gcDetailsInInitialSummary = await this.gcDetailsInInitialSummaryP;\n this.referenceUsedRoutes = gcDetailsInInitialSummary.usedRoutes;\n\n // If the GC details has GC data, initialize our GC data from it.\n if (gcDetailsInInitialSummary.gcData !== undefined) {\n this.gcData = cloneGCData(gcDetailsInInitialSummary.gcData);\n }\n }\n }\n\n public async summarize(fullTree: boolean, trackState: boolean = true): Promise<IContextSummarizeResult> {\n // Load GC details from the initial summary, if it's not already loaded. If this is the first time this node is\n // being summarized, the used routes in it are needed to find out if this node has changed since last summary.\n // If it hasn't changed, the GC data in it needs to be returned as part of the summary.\n await this.loadInitialGCSummaryDetails();\n\n // If GC is not disabled and we are tracking a summary, GC should have run and updated the used routes for this\n // summary by calling updateUsedRoutes which sets wipSerializedUsedRoutes.\n if (!this.gcDisabled && this.isTrackingInProgress()) {\n assert(this.wipSerializedUsedRoutes !== undefined,\n 0x1b1 /* \"wip used routes should be set if tracking a summary\" */);\n }\n\n // If trackState is true, get summary from base summarizer node which tracks summary state.\n // If trackState is false, get summary from summarizeInternal.\n if (trackState) {\n const summarizeResult = await super.summarize(fullTree);\n\n // If there is no cached GC data, return empty data in summarize result. It is the caller's responsibility\n // to ensure that GC data is available by calling getGCData before calling summarize.\n const gcData = this.gcData !== undefined ? cloneGCData(this.gcData) : { gcNodes: {} };\n\n return {\n ...summarizeResult,\n gcData,\n };\n } else {\n return this.summarizeInternal(fullTree, trackState);\n }\n }\n\n private async summarizeInternal(fullTree: boolean, trackState: boolean): Promise<ISummarizeInternalResult> {\n const summarizeResult = await this.summarizeFn(fullTree, trackState);\n this.gcData = cloneGCData(summarizeResult.gcData);\n return summarizeResult;\n }\n\n /**\n * Returns the GC data of this node. If nothing has changed since last summary, it tries to reuse the data from\n * the previous summary. Else, it gets new GC data from the underlying Fluid object.\n * @param fullGC - true to bypass optimizations and force full generation of GC data.\n */\n public async getGCData(fullGC: boolean = false): Promise<IGarbageCollectionData> {\n assert(!this.gcDisabled, 0x1b2 /* \"Getting GC data should not be called when GC is disabled!\" */);\n assert(this.getGCDataFn !== undefined, 0x1b3 /* \"GC data cannot be retrieved without getGCDataFn\" */);\n\n // Load GC details from the initial summary, if not already loaded. If this is the first time this function is\n // called and the node's data has not changed since last summary, the GC data in initial details is returned.\n await this.loadInitialGCSummaryDetails();\n\n // If there is no new data since last summary and we have GC data from the previous run, return it. We may not\n // have data from previous GC run for clients with older summary format before GC was added. They won't have\n // GC details in their initial summary.\n if (!fullGC && !this.hasDataChanged() && this.gcData !== undefined) {\n return cloneGCData(this.gcData);\n }\n\n const gcData = await this.getGCDataFn(fullGC);\n this.gcData = cloneGCData(gcData);\n return gcData;\n }\n\n /**\n * Called during the start of a summary. Updates the work-in-progress used routes.\n */\n public startSummary(referenceSequenceNumber: number, summaryLogger: ITelemetryLogger) {\n // If GC is disabled, skip setting wip used routes since we should not track GC state.\n if (!this.gcDisabled) {\n assert(\n this.wipSerializedUsedRoutes === undefined,\n 0x1b4 /* \"We should not already be tracking used routes when to track a new summary\" */);\n\n // back-compat: 0.33 - This will be done in `updateUsedRoutes`. Older clients do not have that method, so\n // keeping this one for now.\n this.wipSerializedUsedRoutes = JSON.stringify(this.usedRoutes);\n }\n super.startSummary(referenceSequenceNumber, summaryLogger);\n }\n\n /**\n * Called after summary has been uploaded to the server. Add the work-in-progress state to the pending\n * summary queue. We track this until we get an ack from the server for this summary.\n */\n protected completeSummaryCore(\n proposalHandle: string,\n parentPath: EscapedPath | undefined,\n parentSkipRecursion: boolean,\n ) {\n let wipSerializedUsedRoutes: string | undefined;\n // If GC is disabled, don't set wip used routes.\n if (!this.gcDisabled) {\n wipSerializedUsedRoutes = this.wipSerializedUsedRoutes;\n assert(wipSerializedUsedRoutes !== undefined, 0x1b5 /* \"We should have been tracking used routes\" */);\n }\n\n super.completeSummaryCore(proposalHandle, parentPath, parentSkipRecursion);\n\n // If GC is disabled, skip setting pending summary with GC state.\n if (!this.gcDisabled) {\n const summaryNode = this.pendingSummaries.get(proposalHandle);\n if (summaryNode !== undefined) {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const summaryNodeWithGC = new SummaryNodeWithGC(wipSerializedUsedRoutes!, summaryNode);\n this.pendingSummaries.set(proposalHandle, summaryNodeWithGC);\n }\n }\n }\n\n /**\n * Clears the work-in-progress state.\n */\n public clearSummary() {\n this.wipSerializedUsedRoutes = undefined;\n super.clearSummary();\n }\n\n /**\n * Called when we get an ack from the server for a summary we sent. Update the reference state of this node\n * from the state in the pending summary queue.\n */\n protected refreshLatestSummaryFromPending(\n proposalHandle: string,\n referenceSequenceNumber: number,\n ): void {\n // If GC is disabled, skip setting referenced used routes since we are not tracking GC state.\n if (!this.gcDisabled) {\n const summaryNode = this.pendingSummaries.get(proposalHandle) as SummaryNodeWithGC;\n if (summaryNode !== undefined) {\n this.referenceUsedRoutes = JSON.parse(summaryNode.serializedUsedRoutes);\n }\n }\n\n return super.refreshLatestSummaryFromPending(proposalHandle, referenceSequenceNumber);\n }\n\n /**\n * Called when we need to upload the reference state from the given summary. Read the GC blob and get the state\n * to upload from it.\n */\n protected async refreshLatestSummaryFromSnapshot(\n referenceSequenceNumber: number,\n snapshotTree: ISnapshotTree,\n basePath: EscapedPath | undefined,\n localPath: EscapedPath,\n correlatedSummaryLogger: ITelemetryLogger,\n readAndParseBlob: ReadAndParseBlob,\n ): Promise<void> {\n // If GC is disabled, skip setting referenced used routes since we are not tracking GC state.\n if (!this.gcDisabled) {\n const gcDetailsBlob = snapshotTree.blobs[gcBlobKey];\n if (gcDetailsBlob !== undefined) {\n const gcDetails = await readAndParseBlob<IGarbageCollectionSummaryDetails>(gcDetailsBlob);\n\n // Possible re-entrancy. If we have already seen a summary later than this one, ignore it.\n if (this.referenceSequenceNumber >= referenceSequenceNumber) {\n return;\n }\n\n this.referenceUsedRoutes = gcDetails.usedRoutes;\n }\n }\n\n return super.refreshLatestSummaryFromSnapshot(\n referenceSequenceNumber,\n snapshotTree,\n basePath,\n localPath,\n correlatedSummaryLogger,\n readAndParseBlob,\n );\n }\n\n /**\n * Override the createChild method to return an instance of SummarizerNodeWithGC.\n */\n public createChild(\n /** Summarize function */\n summarizeInternalFn: (fullTree: boolean, trackState: boolean) => Promise<ISummarizeInternalResult>,\n /** Initial id or path part of this node */\n id: string,\n /**\n * Information needed to create the node.\n * If it is from a base summary, it will assert that a summary has been seen.\n * Attach information if it is created from an attach op.\n */\n createParam: CreateChildSummarizerNodeParam,\n config: ISummarizerNodeConfigWithGC = {},\n getGCDataFn?: (fullGC?: boolean) => Promise<IGarbageCollectionData>,\n getInitialGCSummaryDetailsFn?: () => Promise<IGarbageCollectionSummaryDetails>,\n ): ISummarizerNodeWithGC {\n assert(!this.children.has(id), 0x1b6 /* \"Create SummarizerNode child already exists\" */);\n\n const createDetails: ICreateChildDetails = this.getCreateDetailsForChild(id, createParam);\n const child = new SummarizerNodeWithGC(\n this.defaultLogger,\n summarizeInternalFn,\n {\n ...config,\n // Propagate our gcDisabled state to the child if its not explicity specified in child's config.\n gcDisabled: config.gcDisabled ?? this.gcDisabled,\n },\n createDetails.changeSequenceNumber,\n createDetails.latestSummary,\n createDetails.initialSummary,\n this.wipSummaryLogger,\n getGCDataFn,\n getInitialGCSummaryDetailsFn,\n );\n\n // back-compat: 0.33 - If a child is created during summarize, its wip used routes will updated in\n // `updateUsedRoutes` method. For older clients, do it here since that method does not exist.\n\n // There may be additional state that has to be updated in this child. For example, if a summary is being\n // tracked, the child's summary tracking state needs to be updated too.\n this.maybeUpdateChildState(child);\n\n this.children.set(id, child);\n return child;\n }\n\n /**\n * Override the getChild method to return an instance of SummarizerNodeWithGC.\n */\n public getChild(id: string): ISummarizerNodeWithGC | undefined {\n return this.children.get(id) as SummarizerNodeWithGC;\n }\n\n public isReferenced(): boolean {\n return this.usedRoutes.includes(\"\") || this.usedRoutes.includes(\"/\");\n }\n\n public updateUsedRoutes(usedRoutes: string[]) {\n // Sort the given routes before updating. This will ensure that the routes compared in hasUsedStateChanged()\n // are in the same order.\n this._usedRoutes = usedRoutes.sort();\n\n // If GC is not disabled and we are tracking a summary, update the work-in-progress used routes so that it can\n // be tracked for this summary.\n if (!this.gcDisabled && this.isTrackingInProgress()) {\n this.wipSerializedUsedRoutes = JSON.stringify(this.usedRoutes);\n }\n }\n\n /**\n * Override the hasChanged method. If this node data or its used state changed, the node is considered changed.\n */\n protected hasChanged(): boolean {\n return this.hasDataChanged() || this.hasUsedStateChanged();\n }\n\n /**\n * This tells whether the data in this node has changed or not.\n */\n private hasDataChanged(): boolean {\n return super.hasChanged();\n }\n\n /**\n * This tells whether the used state of this node has changed since last successful summary. If the used routes\n * of this node changed, its used state is considered changed. Basically, if this node or any of its child nodes\n * was previously used and became unused (or vice versa), its used state has changed.\n */\n private hasUsedStateChanged(): boolean {\n // If GC is disabled, we are not tracking used state, return false.\n if (this.gcDisabled) {\n return false;\n }\n\n return this.referenceUsedRoutes === undefined ||\n JSON.stringify(this.usedRoutes) !== JSON.stringify(this.referenceUsedRoutes);\n }\n\n /**\n * Updates the work-in-progress state of the child if summary is in progress.\n * @param child - The child node to be updated.\n */\n protected maybeUpdateChildState(child: SummarizerNodeWithGC) {\n if (this.isTrackingInProgress()) {\n // Update the child's work-in-progress used routes.\n child.updateUsedRoutes(child.usedRoutes);\n }\n super.maybeUpdateChildState(child);\n }\n}\n\n/**\n * Creates a root summarizer node with GC functionality built-in.\n * @param logger - Logger to use within SummarizerNode\n * @param summarizeInternalFn - Function to generate summary\n * @param changeSequenceNumber - Sequence number of latest change to new node/subtree\n * @param referenceSequenceNumber - Reference sequence number of last acked summary,\n * or undefined if not loaded from summary\n * @param config - Configure behavior of summarizer node\n * @param getGCDataFn - Function to get the GC data of this node\n * @param gcDetailsInInitialSummaryP - Function to get the initial GC details of this node\n */\nexport const createRootSummarizerNodeWithGC = (\n logger: ITelemetryLogger,\n summarizeInternalFn: (fullTree: boolean, trackState: boolean) => Promise<ISummarizeInternalResult>,\n changeSequenceNumber: number,\n referenceSequenceNumber: number | undefined,\n config: ISummarizerNodeConfigWithGC = {},\n getGCDataFn?: (fullGC?: boolean) => Promise<IGarbageCollectionData>,\n getInitialGCSummaryDetailsFn?: () => Promise<IGarbageCollectionSummaryDetails>,\n): IRootSummarizerNodeWithGC => new SummarizerNodeWithGC(\n logger,\n summarizeInternalFn,\n config,\n changeSequenceNumber,\n referenceSequenceNumber === undefined ? undefined : SummaryNode.createForRoot(referenceSequenceNumber),\n undefined /* initialSummary */,\n undefined /* wipSummaryLogger */,\n getGCDataFn,\n getInitialGCSummaryDetailsFn,\n);\n"]} |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"summaryUtils.d.ts","sourceRoot":"","sources":["../src/summaryUtils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAWH,OAAO,EACH,KAAK,EACL,WAAW,EACX,YAAY,EAEZ,YAAY,EAGZ,aAAa,EAChB,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,qCAAqC,CAAC;AAE7G;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,GAAG,KAAK,EAAE,aAAa,EAAE,GAAG,aAAa,CAcnE;AAED,wBAAgB,WAAW,CAAC,OAAO,EAAE,YAAY,CAAC,SAAS,CAAC,GAAG,MAAM,CAMpE;AAwBD,wBAAgB,cAAc,CAAC,OAAO,EAAE,YAAY,GAAG,aAAa,CAInE;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,qBAAqB,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CAQhH;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,qBAAqB,EAAE,GAAG,EAAE,MAAM,EAAE,eAAe,EAAE,gBAAgB,GAAG,IAAI,CAGrH;AAED,qBAAa,kBAAmB,YAAW,qBAAqB;IAC5D,OAAO,CAAC,iBAAiB,CAAa;IAEtC,IAAW,OAAO,IAAI,YAAY,CAKjC;IAED,IAAW,KAAK,IAAI,QAAQ,CAAC,aAAa,CAAC,CAE1C;;IAOD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAyC;IACrE,OAAO,CAAC,YAAY,CAAgB;IAE7B,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI;IAWxD,SAAS,CACZ,GAAG,EAAE,MAAM,EACX,UAAU,EAAE,WAAW,CAAC,IAAI,GAAG,WAAW,CAAC,IAAI,GAAG,WAAW,CAAC,UAAU,EACxE,MAAM,EAAE,MAAM,GAAG,IAAI;IAUlB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,eAAe,EAAE,gBAAgB,GAAG,IAAI;IAKlE,aAAa,CAAC,EAAE,EAAE,MAAM;IAIxB,cAAc,IAAI,qBAAqB;CAGjD;AAED;;;;GAIG;AACH,wBAAgB,6BAA6B,CACzC,QAAQ,EAAE,KAAK,EACf,QAAQ,GAAE,OAAe,GAC1B,qBAAqB,CAyCvB;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAChC,QAAQ,EAAE,KAAK,EACf,QAAQ,GAAE,OAAe,GAC1B,gBAAgB,CAgBlB;AAED;;;;GAIG;AACH,wBAAgB,gCAAgC,CAC5C,QAAQ,EAAE,aAAa,GACxB,qBAAqB,CAkBvB;AAED;;;;GAIG;AACH,wBAAgB,wCAAwC,CACpD,sBAAsB,EAAE,MAAM,GAC/B,YAAY,CAiBd;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,CAAC,WAAW,EAAE,YAAY,GAAG,KAAK,CAsC1E"} | ||
| {"version":3,"file":"summaryUtils.d.ts","sourceRoot":"","sources":["../src/summaryUtils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAWH,OAAO,EACH,KAAK,EACL,WAAW,EACX,YAAY,EAEZ,YAAY,EAGZ,aAAa,EAChB,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,qCAAqC,CAAC;AAE7G;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,GAAG,KAAK,EAAE,aAAa,EAAE,GAAG,aAAa,CAcnE;AAED,wBAAgB,WAAW,CAAC,OAAO,EAAE,YAAY,CAAC,SAAS,CAAC,GAAG,MAAM,CAMpE;AAwBD,wBAAgB,cAAc,CAAC,OAAO,EAAE,YAAY,GAAG,aAAa,CAInE;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,qBAAqB,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CAQhH;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,qBAAqB,EAAE,GAAG,EAAE,MAAM,EAAE,eAAe,EAAE,gBAAgB,GAAG,IAAI,CAGrH;AAED,qBAAa,kBAAmB,YAAW,qBAAqB;IAC5D,OAAO,CAAC,iBAAiB,CAAa;IAEtC,IAAW,OAAO,IAAI,YAAY,CAKjC;IAED,IAAW,KAAK,IAAI,QAAQ,CAAC,aAAa,CAAC,CAE1C;;IAOD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAyC;IACrE,OAAO,CAAC,YAAY,CAAgB;IAE7B,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI;IAWxD,SAAS,CACZ,GAAG,EAAE,MAAM,EACX,UAAU,EAAE,WAAW,CAAC,IAAI,GAAG,WAAW,CAAC,IAAI,GAAG,WAAW,CAAC,UAAU,EACxE,MAAM,EAAE,MAAM,GAAG,IAAI;IAUlB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,eAAe,EAAE,gBAAgB,GAAG,IAAI;IAKlE,aAAa,CAAC,EAAE,EAAE,MAAM;IAIxB,cAAc,IAAI,qBAAqB;CAGjD;AAED;;;;GAIG;AACH,wBAAgB,6BAA6B,CACzC,QAAQ,EAAE,KAAK,EACf,QAAQ,GAAE,OAAe,GAC1B,qBAAqB,CAyCvB;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAChC,QAAQ,EAAE,KAAK,EACf,QAAQ,GAAE,OAAe,GAC1B,gBAAgB,CAgBlB;AAED;;;;GAIG;AACH,wBAAgB,gCAAgC,CAC5C,QAAQ,EAAE,aAAa,GACxB,qBAAqB,CAmBvB;AAED;;;;GAIG;AACH,wBAAgB,wCAAwC,CACpD,sBAAsB,EAAE,MAAM,GAC/B,YAAY,CAiBd;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,CAAC,WAAW,EAAE,YAAY,GAAG,KAAK,CAsC1E"} |
@@ -199,3 +199,3 @@ "use strict"; | ||
| function convertSnapshotTreeToSummaryTree(snapshot) { | ||
| common_utils_1.assert(Object.keys(snapshot.commits).length === 0, "There should not be commit tree entries in snapshot"); | ||
| common_utils_1.assert(Object.keys(snapshot.commits).length === 0, 0x19e /* "There should not be commit tree entries in snapshot" */); | ||
| const builder = new SummaryTreeBuilder(); | ||
@@ -202,0 +202,0 @@ for (const [key, value] of Object.entries(snapshot.blobs)) { |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"summaryUtils.js","sourceRoot":"","sources":["../src/summaryUtils.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport {\n assert,\n fromBase64ToUtf8,\n IsoBuffer,\n Uint8ArrayToString,\n unreachableCase,\n stringToBuffer,\n} from \"@fluidframework/common-utils\";\nimport { AttachmentTreeEntry, BlobTreeEntry, TreeTreeEntry } from \"@fluidframework/protocol-base\";\nimport {\n ITree,\n SummaryType,\n ISummaryTree,\n SummaryObject,\n ISummaryBlob,\n TreeEntry,\n ITreeEntry,\n ISnapshotTree,\n} from \"@fluidframework/protocol-definitions\";\nimport { ISummaryStats, ISummarizeResult, ISummaryTreeWithStats } from \"@fluidframework/runtime-definitions\";\n\n/**\n * Combines summary stats by adding their totals together.\n * Returns empty stats if called without args.\n * @param stats - stats to merge\n */\nexport function mergeStats(...stats: ISummaryStats[]): ISummaryStats {\n const results = {\n treeNodeCount: 0,\n blobNodeCount: 0,\n handleNodeCount: 0,\n totalBlobSize: 0,\n };\n for (const stat of stats) {\n results.treeNodeCount += stat.treeNodeCount;\n results.blobNodeCount += stat.blobNodeCount;\n results.handleNodeCount += stat.handleNodeCount;\n results.totalBlobSize += stat.totalBlobSize;\n }\n return results;\n}\n\nexport function getBlobSize(content: ISummaryBlob[\"content\"]): number {\n if (typeof content === \"string\") {\n return stringToBuffer(content, \"utf8\").byteLength;\n } else {\n return content.byteLength;\n }\n}\n\nfunction calculateStatsCore(summaryObject: SummaryObject, stats: ISummaryStats): void {\n switch (summaryObject.type) {\n case SummaryType.Tree: {\n stats.treeNodeCount++;\n for (const value of Object.values(summaryObject.tree)) {\n calculateStatsCore(value, stats);\n }\n return;\n }\n case SummaryType.Handle: {\n stats.handleNodeCount++;\n return;\n }\n case SummaryType.Blob: {\n stats.blobNodeCount++;\n stats.totalBlobSize += getBlobSize(summaryObject.content);\n return;\n }\n default: return;\n }\n}\n\nexport function calculateStats(summary: ISummaryTree): ISummaryStats {\n const stats = mergeStats();\n calculateStatsCore(summary, stats);\n return stats;\n}\n\nexport function addBlobToSummary(summary: ISummaryTreeWithStats, key: string, content: string | Uint8Array): void {\n const blob: ISummaryBlob = {\n type: SummaryType.Blob,\n content,\n };\n summary.summary.tree[key] = blob;\n summary.stats.blobNodeCount++;\n summary.stats.totalBlobSize += getBlobSize(content);\n}\n\nexport function addTreeToSummary(summary: ISummaryTreeWithStats, key: string, summarizeResult: ISummarizeResult): void {\n summary.summary.tree[key] = summarizeResult.summary;\n summary.stats = mergeStats(summary.stats, summarizeResult.stats);\n}\n\nexport class SummaryTreeBuilder implements ISummaryTreeWithStats {\n private attachmentCounter: number = 0;\n\n public get summary(): ISummaryTree {\n return {\n type: SummaryType.Tree,\n tree: { ...this.summaryTree },\n };\n }\n\n public get stats(): Readonly<ISummaryStats> {\n return { ...this.summaryStats };\n }\n\n constructor() {\n this.summaryStats = mergeStats();\n this.summaryStats.treeNodeCount++;\n }\n\n private readonly summaryTree: { [path: string]: SummaryObject } = {};\n private summaryStats: ISummaryStats;\n\n public addBlob(key: string, content: string | Uint8Array): void {\n // Prevent cloning by directly referencing underlying private properties\n addBlobToSummary({\n summary: {\n type: SummaryType.Tree,\n tree: this.summaryTree,\n },\n stats: this.summaryStats,\n }, key, content);\n }\n\n public addHandle(\n key: string,\n handleType: SummaryType.Tree | SummaryType.Blob | SummaryType.Attachment,\n handle: string): void\n {\n this.summaryTree[key] = {\n type: SummaryType.Handle,\n handleType,\n handle,\n };\n this.summaryStats.handleNodeCount++;\n }\n\n public addWithStats(key: string, summarizeResult: ISummarizeResult): void {\n this.summaryTree[key] = summarizeResult.summary;\n this.summaryStats = mergeStats(this.summaryStats, summarizeResult.stats);\n }\n\n public addAttachment(id: string) {\n this.summaryTree[this.attachmentCounter++] = { id, type: SummaryType.Attachment };\n }\n\n public getSummaryTree(): ISummaryTreeWithStats {\n return { summary: this.summary, stats: this.stats };\n }\n}\n\n/**\n * Converts snapshot ITree to ISummaryTree format and tracks stats.\n * @param snapshot - snapshot in ITree format\n * @param fullTree - true to never use handles, even if id is specified\n */\nexport function convertToSummaryTreeWithStats(\n snapshot: ITree,\n fullTree: boolean = false,\n): ISummaryTreeWithStats {\n const builder = new SummaryTreeBuilder();\n for (const entry of snapshot.entries) {\n switch (entry.type) {\n case TreeEntry.Blob: {\n const blob = entry.value;\n let content: string | Uint8Array;\n if (blob.encoding === \"base64\") {\n content = IsoBuffer.from(blob.contents, \"base64\");\n } else {\n content = blob.contents;\n }\n builder.addBlob(entry.path, content);\n break;\n }\n\n case TreeEntry.Tree: {\n const subtree = convertToSummaryTree(\n entry.value,\n fullTree);\n builder.addWithStats(entry.path, subtree);\n\n break;\n }\n\n case TreeEntry.Attachment: {\n const id = entry.value.id;\n builder.addAttachment(id);\n\n break;\n }\n\n case TreeEntry.Commit:\n throw new Error(\"Should not have Commit TreeEntry in summary\");\n\n default:\n throw new Error(\"Unexpected TreeEntry type\");\n }\n }\n\n return builder.getSummaryTree();\n}\n\n/**\n * Converts snapshot ITree to ISummaryTree format and tracks stats.\n * @param snapshot - snapshot in ITree format\n * @param fullTree - true to never use handles, even if id is specified\n */\nexport function convertToSummaryTree(\n snapshot: ITree,\n fullTree: boolean = false,\n): ISummarizeResult {\n // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions\n if (snapshot.id && !fullTree) {\n const stats = mergeStats();\n stats.handleNodeCount++;\n return {\n summary: {\n handle: snapshot.id,\n handleType: SummaryType.Tree,\n type: SummaryType.Handle,\n },\n stats,\n };\n } else {\n return convertToSummaryTreeWithStats(snapshot, fullTree);\n }\n}\n\n/**\n * Converts ISnapshotTree to ISummaryTree format and tracks stats. This snapshot tree was\n * was taken by serialize api in detached container.\n * @param snapshot - snapshot in ISnapshotTree format\n */\nexport function convertSnapshotTreeToSummaryTree(\n snapshot: ISnapshotTree,\n): ISummaryTreeWithStats {\n assert(Object.keys(snapshot.commits).length === 0, \"There should not be commit tree entries in snapshot\");\n\n const builder = new SummaryTreeBuilder();\n for (const [key, value] of Object.entries(snapshot.blobs)) {\n // The entries in blobs are supposed to be blobPath -> blobId and blobId -> blobValue\n // and we want to push blobPath to blobValue in tree entries.\n if (snapshot.blobs[value] !== undefined) {\n const decoded = fromBase64ToUtf8(snapshot.blobs[value]);\n builder.addBlob(key, decoded);\n }\n }\n\n for (const [key, tree] of Object.entries(snapshot.trees)) {\n const subtree = convertSnapshotTreeToSummaryTree(tree);\n builder.addWithStats(key, subtree);\n }\n return builder.getSummaryTree();\n}\n\n/**\n * Utility to convert serialized snapshot taken in detached container to format where we can use it to\n * attach the container.\n * @param serializedSnapshotTree - serialized snapshot tree to be converted to summary tree for attach.\n */\nexport function convertContainerToDriverSerializedFormat(\n serializedSnapshotTree: string,\n): ISummaryTree {\n const snapshotTree: ISnapshotTree = JSON.parse(serializedSnapshotTree);\n const summaryTree = convertSnapshotTreeToSummaryTree(snapshotTree).summary;\n const appSummaryTree: ISummaryTree = {\n type: SummaryType.Tree,\n tree: {},\n };\n const entries = Object.entries(summaryTree.tree);\n for (const [key, subTree] of entries) {\n if (key !== \".protocol\") {\n appSummaryTree.tree[key] = subTree;\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n delete summaryTree.tree[key];\n }\n }\n summaryTree.tree[\".app\"] = appSummaryTree;\n return summaryTree;\n}\n\n/**\n * Converts ISummaryTree to ITree format. This is needed for back-compat while we get rid of snapshot.\n * @param summaryTree - summary tree in ISummaryTree format\n */\nexport function convertSummaryTreeToITree(summaryTree: ISummaryTree): ITree {\n const entries: ITreeEntry[] = [];\n for (const [key, value] of Object.entries(summaryTree.tree)) {\n switch (value.type) {\n case SummaryType.Blob: {\n let parsedContent: string;\n let encoding: string = \"utf-8\";\n if (typeof value.content === \"string\") {\n parsedContent = value.content;\n } else {\n parsedContent = Uint8ArrayToString(value.content, \"base64\");\n encoding = \"base64\";\n }\n entries.push(new BlobTreeEntry(key, parsedContent, encoding));\n break;\n }\n\n case SummaryType.Tree: {\n entries.push(new TreeTreeEntry(key, convertSummaryTreeToITree(value)));\n break;\n }\n\n case SummaryType.Attachment: {\n entries.push(new AttachmentTreeEntry(key, value.id));\n break;\n }\n\n case SummaryType.Handle: {\n throw new Error(\"Should not have Handle type in summary tree\");\n }\n\n default:\n unreachableCase(value, \"Unexpected summary tree type\");\n }\n }\n return {\n entries,\n };\n}\n"]} | ||
| {"version":3,"file":"summaryUtils.js","sourceRoot":"","sources":["../src/summaryUtils.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport {\n assert,\n fromBase64ToUtf8,\n IsoBuffer,\n Uint8ArrayToString,\n unreachableCase,\n stringToBuffer,\n} from \"@fluidframework/common-utils\";\nimport { AttachmentTreeEntry, BlobTreeEntry, TreeTreeEntry } from \"@fluidframework/protocol-base\";\nimport {\n ITree,\n SummaryType,\n ISummaryTree,\n SummaryObject,\n ISummaryBlob,\n TreeEntry,\n ITreeEntry,\n ISnapshotTree,\n} from \"@fluidframework/protocol-definitions\";\nimport { ISummaryStats, ISummarizeResult, ISummaryTreeWithStats } from \"@fluidframework/runtime-definitions\";\n\n/**\n * Combines summary stats by adding their totals together.\n * Returns empty stats if called without args.\n * @param stats - stats to merge\n */\nexport function mergeStats(...stats: ISummaryStats[]): ISummaryStats {\n const results = {\n treeNodeCount: 0,\n blobNodeCount: 0,\n handleNodeCount: 0,\n totalBlobSize: 0,\n };\n for (const stat of stats) {\n results.treeNodeCount += stat.treeNodeCount;\n results.blobNodeCount += stat.blobNodeCount;\n results.handleNodeCount += stat.handleNodeCount;\n results.totalBlobSize += stat.totalBlobSize;\n }\n return results;\n}\n\nexport function getBlobSize(content: ISummaryBlob[\"content\"]): number {\n if (typeof content === \"string\") {\n return stringToBuffer(content, \"utf8\").byteLength;\n } else {\n return content.byteLength;\n }\n}\n\nfunction calculateStatsCore(summaryObject: SummaryObject, stats: ISummaryStats): void {\n switch (summaryObject.type) {\n case SummaryType.Tree: {\n stats.treeNodeCount++;\n for (const value of Object.values(summaryObject.tree)) {\n calculateStatsCore(value, stats);\n }\n return;\n }\n case SummaryType.Handle: {\n stats.handleNodeCount++;\n return;\n }\n case SummaryType.Blob: {\n stats.blobNodeCount++;\n stats.totalBlobSize += getBlobSize(summaryObject.content);\n return;\n }\n default: return;\n }\n}\n\nexport function calculateStats(summary: ISummaryTree): ISummaryStats {\n const stats = mergeStats();\n calculateStatsCore(summary, stats);\n return stats;\n}\n\nexport function addBlobToSummary(summary: ISummaryTreeWithStats, key: string, content: string | Uint8Array): void {\n const blob: ISummaryBlob = {\n type: SummaryType.Blob,\n content,\n };\n summary.summary.tree[key] = blob;\n summary.stats.blobNodeCount++;\n summary.stats.totalBlobSize += getBlobSize(content);\n}\n\nexport function addTreeToSummary(summary: ISummaryTreeWithStats, key: string, summarizeResult: ISummarizeResult): void {\n summary.summary.tree[key] = summarizeResult.summary;\n summary.stats = mergeStats(summary.stats, summarizeResult.stats);\n}\n\nexport class SummaryTreeBuilder implements ISummaryTreeWithStats {\n private attachmentCounter: number = 0;\n\n public get summary(): ISummaryTree {\n return {\n type: SummaryType.Tree,\n tree: { ...this.summaryTree },\n };\n }\n\n public get stats(): Readonly<ISummaryStats> {\n return { ...this.summaryStats };\n }\n\n constructor() {\n this.summaryStats = mergeStats();\n this.summaryStats.treeNodeCount++;\n }\n\n private readonly summaryTree: { [path: string]: SummaryObject } = {};\n private summaryStats: ISummaryStats;\n\n public addBlob(key: string, content: string | Uint8Array): void {\n // Prevent cloning by directly referencing underlying private properties\n addBlobToSummary({\n summary: {\n type: SummaryType.Tree,\n tree: this.summaryTree,\n },\n stats: this.summaryStats,\n }, key, content);\n }\n\n public addHandle(\n key: string,\n handleType: SummaryType.Tree | SummaryType.Blob | SummaryType.Attachment,\n handle: string): void\n {\n this.summaryTree[key] = {\n type: SummaryType.Handle,\n handleType,\n handle,\n };\n this.summaryStats.handleNodeCount++;\n }\n\n public addWithStats(key: string, summarizeResult: ISummarizeResult): void {\n this.summaryTree[key] = summarizeResult.summary;\n this.summaryStats = mergeStats(this.summaryStats, summarizeResult.stats);\n }\n\n public addAttachment(id: string) {\n this.summaryTree[this.attachmentCounter++] = { id, type: SummaryType.Attachment };\n }\n\n public getSummaryTree(): ISummaryTreeWithStats {\n return { summary: this.summary, stats: this.stats };\n }\n}\n\n/**\n * Converts snapshot ITree to ISummaryTree format and tracks stats.\n * @param snapshot - snapshot in ITree format\n * @param fullTree - true to never use handles, even if id is specified\n */\nexport function convertToSummaryTreeWithStats(\n snapshot: ITree,\n fullTree: boolean = false,\n): ISummaryTreeWithStats {\n const builder = new SummaryTreeBuilder();\n for (const entry of snapshot.entries) {\n switch (entry.type) {\n case TreeEntry.Blob: {\n const blob = entry.value;\n let content: string | Uint8Array;\n if (blob.encoding === \"base64\") {\n content = IsoBuffer.from(blob.contents, \"base64\");\n } else {\n content = blob.contents;\n }\n builder.addBlob(entry.path, content);\n break;\n }\n\n case TreeEntry.Tree: {\n const subtree = convertToSummaryTree(\n entry.value,\n fullTree);\n builder.addWithStats(entry.path, subtree);\n\n break;\n }\n\n case TreeEntry.Attachment: {\n const id = entry.value.id;\n builder.addAttachment(id);\n\n break;\n }\n\n case TreeEntry.Commit:\n throw new Error(\"Should not have Commit TreeEntry in summary\");\n\n default:\n throw new Error(\"Unexpected TreeEntry type\");\n }\n }\n\n return builder.getSummaryTree();\n}\n\n/**\n * Converts snapshot ITree to ISummaryTree format and tracks stats.\n * @param snapshot - snapshot in ITree format\n * @param fullTree - true to never use handles, even if id is specified\n */\nexport function convertToSummaryTree(\n snapshot: ITree,\n fullTree: boolean = false,\n): ISummarizeResult {\n // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions\n if (snapshot.id && !fullTree) {\n const stats = mergeStats();\n stats.handleNodeCount++;\n return {\n summary: {\n handle: snapshot.id,\n handleType: SummaryType.Tree,\n type: SummaryType.Handle,\n },\n stats,\n };\n } else {\n return convertToSummaryTreeWithStats(snapshot, fullTree);\n }\n}\n\n/**\n * Converts ISnapshotTree to ISummaryTree format and tracks stats. This snapshot tree was\n * was taken by serialize api in detached container.\n * @param snapshot - snapshot in ISnapshotTree format\n */\nexport function convertSnapshotTreeToSummaryTree(\n snapshot: ISnapshotTree,\n): ISummaryTreeWithStats {\n assert(Object.keys(snapshot.commits).length === 0,\n 0x19e /* \"There should not be commit tree entries in snapshot\" */);\n\n const builder = new SummaryTreeBuilder();\n for (const [key, value] of Object.entries(snapshot.blobs)) {\n // The entries in blobs are supposed to be blobPath -> blobId and blobId -> blobValue\n // and we want to push blobPath to blobValue in tree entries.\n if (snapshot.blobs[value] !== undefined) {\n const decoded = fromBase64ToUtf8(snapshot.blobs[value]);\n builder.addBlob(key, decoded);\n }\n }\n\n for (const [key, tree] of Object.entries(snapshot.trees)) {\n const subtree = convertSnapshotTreeToSummaryTree(tree);\n builder.addWithStats(key, subtree);\n }\n return builder.getSummaryTree();\n}\n\n/**\n * Utility to convert serialized snapshot taken in detached container to format where we can use it to\n * attach the container.\n * @param serializedSnapshotTree - serialized snapshot tree to be converted to summary tree for attach.\n */\nexport function convertContainerToDriverSerializedFormat(\n serializedSnapshotTree: string,\n): ISummaryTree {\n const snapshotTree: ISnapshotTree = JSON.parse(serializedSnapshotTree);\n const summaryTree = convertSnapshotTreeToSummaryTree(snapshotTree).summary;\n const appSummaryTree: ISummaryTree = {\n type: SummaryType.Tree,\n tree: {},\n };\n const entries = Object.entries(summaryTree.tree);\n for (const [key, subTree] of entries) {\n if (key !== \".protocol\") {\n appSummaryTree.tree[key] = subTree;\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n delete summaryTree.tree[key];\n }\n }\n summaryTree.tree[\".app\"] = appSummaryTree;\n return summaryTree;\n}\n\n/**\n * Converts ISummaryTree to ITree format. This is needed for back-compat while we get rid of snapshot.\n * @param summaryTree - summary tree in ISummaryTree format\n */\nexport function convertSummaryTreeToITree(summaryTree: ISummaryTree): ITree {\n const entries: ITreeEntry[] = [];\n for (const [key, value] of Object.entries(summaryTree.tree)) {\n switch (value.type) {\n case SummaryType.Blob: {\n let parsedContent: string;\n let encoding: string = \"utf-8\";\n if (typeof value.content === \"string\") {\n parsedContent = value.content;\n } else {\n parsedContent = Uint8ArrayToString(value.content, \"base64\");\n encoding = \"base64\";\n }\n entries.push(new BlobTreeEntry(key, parsedContent, encoding));\n break;\n }\n\n case SummaryType.Tree: {\n entries.push(new TreeTreeEntry(key, convertSummaryTreeToITree(value)));\n break;\n }\n\n case SummaryType.Attachment: {\n entries.push(new AttachmentTreeEntry(key, value.id));\n break;\n }\n\n case SummaryType.Handle: {\n throw new Error(\"Should not have Handle type in summary tree\");\n }\n\n default:\n unreachableCase(value, \"Unexpected summary tree type\");\n }\n }\n return {\n entries,\n };\n}\n"]} |
@@ -60,3 +60,3 @@ /*! | ||
| } | ||
| assert(response.value, "Invalid response value for Fluid object request"); | ||
| assert(response.value, 0x19a /* "Invalid response value for Fluid object request" */); | ||
| return response.value; | ||
@@ -66,3 +66,3 @@ } | ||
| export function createResponseError(status, value, request) { | ||
| assert(status !== 200, "Cannot not create response error on 200 status"); | ||
| assert(status !== 200, 0x19b /* "Cannot not create response error on 200 status" */); | ||
| return { | ||
@@ -69,0 +69,0 @@ mimeType: "text/plain", |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"dataStoreHelpers.js","sourceRoot":"","sources":["../src/dataStoreHelpers.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert } from \"@fluidframework/common-utils\";\nimport {\n IFluidObject,\n IFluidRouter,\n IRequest,\n IResponse,\n} from \"@fluidframework/core-interfaces\";\nimport {\n IFluidDataStoreFactory,\n IFluidDataStoreRegistry,\n IProvideFluidDataStoreRegistry,\n} from \"@fluidframework/runtime-definitions\";\n\ninterface IResponseException extends Error {\n errorFromRequestFluidObject: true;\n message: string;\n code: number;\n stack: string;\n}\n\nexport function getStack() {\n const err = new Error();\n if (err.stack !== undefined) {\n return err.stack;\n }\n try {\n throw err;\n } catch (err2) {\n return (err2 as Error).stack;\n }\n}\n\nexport function exceptionToResponse(err: any): IResponse {\n const status = 500;\n // eslint-disable-next-line no-null/no-null\n if (err !== null && typeof err === \"object\" && err.errorFromRequestFluidObject === true) {\n const responseErr: IResponseException = err;\n return {\n mimeType: \"text/plain\",\n status: responseErr.code,\n value: responseErr.message,\n stack: responseErr.stack ?? getStack(),\n };\n }\n return {\n mimeType: \"text/plain\",\n status,\n value: `${err}`,\n stack: getStack(),\n };\n}\n\nexport function responseToException(response: IResponse, request: IRequest) {\n const message = response.value;\n const err = new Error(message);\n const responseErr = err as any as IResponseException;\n responseErr.errorFromRequestFluidObject = true;\n responseErr.message = message;\n responseErr.code = response.status;\n if (response.stack !== undefined) {\n try {\n // not clear if all browsers allow overwriting stack\n responseErr.stack = response.stack;\n } catch (err2) {}\n }\n return err;\n}\n\nexport async function requestFluidObject<T = IFluidObject>(\n router: IFluidRouter, url: string | IRequest): Promise<T> {\n const request = typeof url === \"string\" ? { url } : url;\n const response = await router.request(request);\n\n if (response.status !== 200 || response.mimeType !== \"fluid/object\") {\n throw responseToException(response, request);\n }\n\n assert(response.value, \"Invalid response value for Fluid object request\");\n return response.value as T;\n}\n\nexport const create404Response = (request: IRequest) => createResponseError(404, \"not found\", request);\n\nexport function createResponseError(status: number, value: string, request: IRequest): IResponse {\n assert(status !== 200, \"Cannot not create response error on 200 status\");\n return {\n mimeType: \"text/plain\",\n status,\n value: request.url === undefined ? value : `${value}: ${request.url}`,\n stack: getStack(),\n };\n}\n\nexport type Factory = IFluidDataStoreFactory & Partial<IProvideFluidDataStoreRegistry>;\n\n// eslint-disable-next-line prefer-arrow/prefer-arrow-functions\nexport function createDataStoreFactory(\n type: string,\n factory: Factory | Promise<Factory>,\n ): IFluidDataStoreFactory & IFluidDataStoreRegistry\n{\n return {\n type,\n get IFluidDataStoreFactory() { return this; },\n get IFluidDataStoreRegistry() { return this; },\n instantiateDataStore: async (context) => (await factory).instantiateDataStore(context),\n get: async (name: string) => (await factory).IFluidDataStoreRegistry?.get(name),\n };\n}\n"]} | ||
| {"version":3,"file":"dataStoreHelpers.js","sourceRoot":"","sources":["../src/dataStoreHelpers.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert } from \"@fluidframework/common-utils\";\nimport {\n IFluidObject,\n IFluidRouter,\n IRequest,\n IResponse,\n} from \"@fluidframework/core-interfaces\";\nimport {\n IFluidDataStoreFactory,\n IFluidDataStoreRegistry,\n IProvideFluidDataStoreRegistry,\n} from \"@fluidframework/runtime-definitions\";\n\ninterface IResponseException extends Error {\n errorFromRequestFluidObject: true;\n message: string;\n code: number;\n stack: string;\n}\n\nexport function getStack() {\n const err = new Error();\n if (err.stack !== undefined) {\n return err.stack;\n }\n try {\n throw err;\n } catch (err2) {\n return (err2 as Error).stack;\n }\n}\n\nexport function exceptionToResponse(err: any): IResponse {\n const status = 500;\n // eslint-disable-next-line no-null/no-null\n if (err !== null && typeof err === \"object\" && err.errorFromRequestFluidObject === true) {\n const responseErr: IResponseException = err;\n return {\n mimeType: \"text/plain\",\n status: responseErr.code,\n value: responseErr.message,\n stack: responseErr.stack ?? getStack(),\n };\n }\n return {\n mimeType: \"text/plain\",\n status,\n value: `${err}`,\n stack: getStack(),\n };\n}\n\nexport function responseToException(response: IResponse, request: IRequest) {\n const message = response.value;\n const err = new Error(message);\n const responseErr = err as any as IResponseException;\n responseErr.errorFromRequestFluidObject = true;\n responseErr.message = message;\n responseErr.code = response.status;\n if (response.stack !== undefined) {\n try {\n // not clear if all browsers allow overwriting stack\n responseErr.stack = response.stack;\n } catch (err2) {}\n }\n return err;\n}\n\nexport async function requestFluidObject<T = IFluidObject>(\n router: IFluidRouter, url: string | IRequest): Promise<T> {\n const request = typeof url === \"string\" ? { url } : url;\n const response = await router.request(request);\n\n if (response.status !== 200 || response.mimeType !== \"fluid/object\") {\n throw responseToException(response, request);\n }\n\n assert(response.value, 0x19a /* \"Invalid response value for Fluid object request\" */);\n return response.value as T;\n}\n\nexport const create404Response = (request: IRequest) => createResponseError(404, \"not found\", request);\n\nexport function createResponseError(status: number, value: string, request: IRequest): IResponse {\n assert(status !== 200, 0x19b /* \"Cannot not create response error on 200 status\" */);\n return {\n mimeType: \"text/plain\",\n status,\n value: request.url === undefined ? value : `${value}: ${request.url}`,\n stack: getStack(),\n };\n}\n\nexport type Factory = IFluidDataStoreFactory & Partial<IProvideFluidDataStoreRegistry>;\n\n// eslint-disable-next-line prefer-arrow/prefer-arrow-functions\nexport function createDataStoreFactory(\n type: string,\n factory: Factory | Promise<Factory>,\n ): IFluidDataStoreFactory & IFluidDataStoreRegistry\n{\n return {\n type,\n get IFluidDataStoreFactory() { return this; },\n get IFluidDataStoreRegistry() { return this; },\n instantiateDataStore: async (context) => (await factory).instantiateDataStore(context),\n get: async (name: string) => (await factory).IFluidDataStoreRegistry?.get(name),\n };\n}\n"]} |
@@ -14,3 +14,3 @@ /*! | ||
| // `path` must not include the trailing separator. | ||
| assert(!path.endsWith("/"), "storage service path has trailing separator"); | ||
| assert(!path.endsWith("/"), 0x19c /* "storage service path has trailing separator" */); | ||
| } | ||
@@ -17,0 +17,0 @@ async readBlob(path) { |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"objectstoragepartition.js","sourceRoot":"","sources":["../src/objectstoragepartition.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,8BAA8B,CAAC;AAGtD;;GAEG;AACH,MAAM,OAAO,sBAAsB;IAC/B,YAA6B,OAA+B,EAAmB,IAAY;QAA9D,YAAO,GAAP,OAAO,CAAwB;QAAmB,SAAI,GAAJ,IAAI,CAAQ;QACvF,kDAAkD;QAClD,MAAM,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,6CAA6C,CAAC,CAAC;IAC/E,CAAC;IAEM,KAAK,CAAC,QAAQ,CAAC,IAAY;QAC9B,OAAO,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,EAAE,CAAC,CAAC;IACzD,CAAC;IAEM,KAAK,CAAC,QAAQ,CAAC,IAAY;QAC9B,OAAO,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,EAAE,CAAC,CAAC;IACzD,CAAC;IAEM,KAAK,CAAC,IAAI,CAAC,IAAY;QAC1B,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,EAAE,CAAC,CAAC;IACrD,CAAC;CACJ","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert } from \"@fluidframework/common-utils\";\nimport { IChannelStorageService } from \"@fluidframework/datastore-definitions\";\n\n/**\n * Returns a new IChannelStorageService that resolves the given `path` as root.\n */\nexport class ObjectStoragePartition implements IChannelStorageService {\n constructor(private readonly storage: IChannelStorageService, private readonly path: string) {\n // `path` must not include the trailing separator.\n assert(!path.endsWith(\"/\"), \"storage service path has trailing separator\");\n }\n\n public async readBlob(path: string): Promise<ArrayBufferLike> {\n return this.storage.readBlob(`${this.path}/${path}`);\n }\n\n public async contains(path: string): Promise<boolean> {\n return this.storage.contains(`${this.path}/${path}`);\n }\n\n public async list(path: string): Promise<string[]> {\n return this.storage.list(`${this.path}/${path}`);\n }\n}\n"]} | ||
| {"version":3,"file":"objectstoragepartition.js","sourceRoot":"","sources":["../src/objectstoragepartition.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,8BAA8B,CAAC;AAGtD;;GAEG;AACH,MAAM,OAAO,sBAAsB;IAC/B,YAA6B,OAA+B,EAAmB,IAAY;QAA9D,YAAO,GAAP,OAAO,CAAwB;QAAmB,SAAI,GAAJ,IAAI,CAAQ;QACvF,kDAAkD;QAClD,MAAM,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,KAAK,CAAC,mDAAmD,CAAC,CAAC;IAC3F,CAAC;IAEM,KAAK,CAAC,QAAQ,CAAC,IAAY;QAC9B,OAAO,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,EAAE,CAAC,CAAC;IACzD,CAAC;IAEM,KAAK,CAAC,QAAQ,CAAC,IAAY;QAC9B,OAAO,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,EAAE,CAAC,CAAC;IACzD,CAAC;IAEM,KAAK,CAAC,IAAI,CAAC,IAAY;QAC1B,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,EAAE,CAAC,CAAC;IACrD,CAAC;CACJ","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert } from \"@fluidframework/common-utils\";\nimport { IChannelStorageService } from \"@fluidframework/datastore-definitions\";\n\n/**\n * Returns a new IChannelStorageService that resolves the given `path` as root.\n */\nexport class ObjectStoragePartition implements IChannelStorageService {\n constructor(private readonly storage: IChannelStorageService, private readonly path: string) {\n // `path` must not include the trailing separator.\n assert(!path.endsWith(\"/\"), 0x19c /* \"storage service path has trailing separator\" */);\n }\n\n public async readBlob(path: string): Promise<ArrayBufferLike> {\n return this.storage.readBlob(`${this.path}/${path}`);\n }\n\n public async contains(path: string): Promise<boolean> {\n return this.storage.contains(`${this.path}/${path}`);\n }\n\n public async list(path: string): Promise<string[]> {\n return this.storage.list(`${this.path}/${path}`);\n }\n}\n"]} |
@@ -8,3 +8,3 @@ /*! | ||
| export declare const pkgName = "@fluidframework/runtime-utils"; | ||
| export declare const pkgVersion = "0.37.0-20427"; | ||
| export declare const pkgVersion = "0.37.0-20517"; | ||
| //# sourceMappingURL=packageVersion.d.ts.map |
@@ -8,3 +8,3 @@ /*! | ||
| export const pkgName = "@fluidframework/runtime-utils"; | ||
| export const pkgVersion = "0.37.0-20427"; | ||
| export const pkgVersion = "0.37.0-20517"; | ||
| //# sourceMappingURL=packageVersion.js.map |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"packageVersion.js","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,CAAC,MAAM,OAAO,GAAG,+BAA+B,CAAC;AACvD,MAAM,CAAC,MAAM,UAAU,GAAG,cAAc,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License.\n *\n * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY\n */\n\nexport const pkgName = \"@fluidframework/runtime-utils\";\nexport const pkgVersion = \"0.37.0-20427\";\n"]} | ||
| {"version":3,"file":"packageVersion.js","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,CAAC,MAAM,OAAO,GAAG,+BAA+B,CAAC;AACvD,MAAM,CAAC,MAAM,UAAU,GAAG,cAAc,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License.\n *\n * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY\n */\n\nexport const pkgName = \"@fluidframework/runtime-utils\";\nexport const pkgVersion = \"0.37.0-20517\";\n"]} |
@@ -24,3 +24,3 @@ /*! | ||
| this.isAttached = true; | ||
| assert(absolutePath.startsWith("/"), "Handles should always have absolute paths"); | ||
| assert(absolutePath.startsWith("/"), 0x19d /* "Handles should always have absolute paths" */); | ||
| } | ||
@@ -27,0 +27,0 @@ get IFluidRouter() { return this; } |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"remoteObjectHandle.js","sourceRoot":"","sources":["../src/remoteObjectHandle.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,8BAA8B,CAAC;AAQtD,OAAO,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAEjG;;;;;;GAMG;AACH,MAAM,OAAO,uBAAuB;IAQhC;;;;OAIG;IACH,YACoB,YAAoB,EACpB,YAAiC;QADjC,iBAAY,GAAZ,YAAY,CAAQ;QACpB,iBAAY,GAAZ,YAAY,CAAqB;QAVrC,eAAU,GAAG,IAAI,CAAC;QAY9B,MAAM,CAAC,YAAY,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,2CAA2C,CAAC,CAAC;IACtF,CAAC;IAjBD,IAAW,YAAY,KAAK,OAAO,IAAI,CAAC,CAAC,CAAC;IAC1C,IAAW,mBAAmB,KAAK,OAAO,IAAI,CAAC,CAAC,CAAC;IACjD,IAAW,YAAY,KAAK,OAAO,IAAI,CAAC,CAAC,CAAC;IAiB1C;;OAEG;IACH,IAAW,IAAI;QACX,OAAO,IAAI,CAAC,YAAY,CAAC;IAC7B,CAAC;IAEM,KAAK,CAAC,GAAG;QACZ,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS,EAAE;YAC5B,MAAM,OAAO,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,YAAY,EAAE,CAAC;YAC3C,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,YAAY,CAAC,aAAa,CAAC,OAAO,CAAC;iBAClD,IAAI,CAAe,CAAC,QAAQ,EAAE,EAAE;gBAC7B,IAAI,QAAQ,CAAC,QAAQ,KAAK,cAAc,EAAE;oBACtC,OAAO,QAAQ,CAAC,KAAqB,CAAC;iBACzC;gBACD,MAAM,mBAAmB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YACjD,CAAC,CAAC,CAAC;SACV;QACD,OAAO,IAAI,CAAC,OAAO,CAAC;IACxB,CAAC;IAEM,WAAW;QACd,OAAO;IACX,CAAC;IAEM,IAAI,CAAC,MAAoB;QAC5B,MAAM,CAAC,WAAW,EAAE,CAAC;IACzB,CAAC;IAEM,KAAK,CAAC,OAAO,CAAC,OAAiB;QAClC,IAAI;YACA,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,GAAG,EAAkB,CAAC;YAChD,MAAM,MAAM,GAAG,MAAM,CAAC,YAAY,CAAC;YAEnC,OAAO,MAAM,KAAK,SAAS;gBACvB,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC;gBACzB,CAAC,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC;SACpC;QAAC,OAAO,KAAK,EAAE;YACZ,OAAO,mBAAmB,CAAC,KAAK,CAAC,CAAC;SACrC;IACL,CAAC;CACJ","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert } from \"@fluidframework/common-utils\";\nimport {\n IFluidObject,\n IFluidHandle,\n IFluidHandleContext,\n IRequest,\n IResponse,\n} from \"@fluidframework/core-interfaces\";\nimport { create404Response, exceptionToResponse, responseToException } from \"./dataStoreHelpers\";\n\n/**\n * This handle is used to dynamically load a Fluid object on a remote client and is created on parsing a serialized\n * FluidObjectHandle.\n * This class is used to generate an IFluidHandle when de-serializing any all handles (including handles to DDSs, custom\n * objects) that are stored in SharedObjects. The Data Store or SharedObject corresponding to the IFluidHandle can be\n * retrieved by calling `get` on it.\n */\nexport class RemoteFluidObjectHandle implements IFluidHandle {\n public get IFluidRouter() { return this; }\n public get IFluidHandleContext() { return this; }\n public get IFluidHandle() { return this; }\n\n public readonly isAttached = true;\n private objectP: Promise<IFluidObject> | undefined;\n\n /**\n * Creates a new RemoteFluidObjectHandle when parsing an IFluidHandle.\n * @param absolutePath - The absolute path to the handle from the container runtime.\n * @param routeContext - The root IFluidHandleContext that has a route to this handle.\n */\n constructor(\n public readonly absolutePath: string,\n public readonly routeContext: IFluidHandleContext,\n ) {\n assert(absolutePath.startsWith(\"/\"), \"Handles should always have absolute paths\");\n }\n\n /**\n * @deprecated - This returns the absolute path.\n */\n public get path() {\n return this.absolutePath;\n }\n\n public async get(): Promise<any> {\n if (this.objectP === undefined) {\n const request = { url: this.absolutePath };\n this.objectP = this.routeContext.resolveHandle(request)\n .then<IFluidObject>((response) => {\n if (response.mimeType === \"fluid/object\") {\n return response.value as IFluidObject;\n }\n throw responseToException(response, request);\n });\n }\n return this.objectP;\n }\n\n public attachGraph(): void {\n return;\n }\n\n public bind(handle: IFluidHandle): void {\n handle.attachGraph();\n }\n\n public async request(request: IRequest): Promise<IResponse> {\n try {\n const object = await this.get() as IFluidObject;\n const router = object.IFluidRouter;\n\n return router !== undefined\n ? router.request(request)\n : create404Response(request);\n } catch (error) {\n return exceptionToResponse(error);\n }\n }\n}\n"]} | ||
| {"version":3,"file":"remoteObjectHandle.js","sourceRoot":"","sources":["../src/remoteObjectHandle.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,8BAA8B,CAAC;AAQtD,OAAO,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAEjG;;;;;;GAMG;AACH,MAAM,OAAO,uBAAuB;IAQhC;;;;OAIG;IACH,YACoB,YAAoB,EACpB,YAAiC;QADjC,iBAAY,GAAZ,YAAY,CAAQ;QACpB,iBAAY,GAAZ,YAAY,CAAqB;QAVrC,eAAU,GAAG,IAAI,CAAC;QAY9B,MAAM,CAAC,YAAY,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,KAAK,CAAC,iDAAiD,CAAC,CAAC;IAClG,CAAC;IAjBD,IAAW,YAAY,KAAK,OAAO,IAAI,CAAC,CAAC,CAAC;IAC1C,IAAW,mBAAmB,KAAK,OAAO,IAAI,CAAC,CAAC,CAAC;IACjD,IAAW,YAAY,KAAK,OAAO,IAAI,CAAC,CAAC,CAAC;IAiB1C;;OAEG;IACH,IAAW,IAAI;QACX,OAAO,IAAI,CAAC,YAAY,CAAC;IAC7B,CAAC;IAEM,KAAK,CAAC,GAAG;QACZ,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS,EAAE;YAC5B,MAAM,OAAO,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,YAAY,EAAE,CAAC;YAC3C,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,YAAY,CAAC,aAAa,CAAC,OAAO,CAAC;iBAClD,IAAI,CAAe,CAAC,QAAQ,EAAE,EAAE;gBAC7B,IAAI,QAAQ,CAAC,QAAQ,KAAK,cAAc,EAAE;oBACtC,OAAO,QAAQ,CAAC,KAAqB,CAAC;iBACzC;gBACD,MAAM,mBAAmB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YACjD,CAAC,CAAC,CAAC;SACV;QACD,OAAO,IAAI,CAAC,OAAO,CAAC;IACxB,CAAC;IAEM,WAAW;QACd,OAAO;IACX,CAAC;IAEM,IAAI,CAAC,MAAoB;QAC5B,MAAM,CAAC,WAAW,EAAE,CAAC;IACzB,CAAC;IAEM,KAAK,CAAC,OAAO,CAAC,OAAiB;QAClC,IAAI;YACA,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,GAAG,EAAkB,CAAC;YAChD,MAAM,MAAM,GAAG,MAAM,CAAC,YAAY,CAAC;YAEnC,OAAO,MAAM,KAAK,SAAS;gBACvB,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC;gBACzB,CAAC,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC;SACpC;QAAC,OAAO,KAAK,EAAE;YACZ,OAAO,mBAAmB,CAAC,KAAK,CAAC,CAAC;SACrC;IACL,CAAC;CACJ","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert } from \"@fluidframework/common-utils\";\nimport {\n IFluidObject,\n IFluidHandle,\n IFluidHandleContext,\n IRequest,\n IResponse,\n} from \"@fluidframework/core-interfaces\";\nimport { create404Response, exceptionToResponse, responseToException } from \"./dataStoreHelpers\";\n\n/**\n * This handle is used to dynamically load a Fluid object on a remote client and is created on parsing a serialized\n * FluidObjectHandle.\n * This class is used to generate an IFluidHandle when de-serializing any all handles (including handles to DDSs, custom\n * objects) that are stored in SharedObjects. The Data Store or SharedObject corresponding to the IFluidHandle can be\n * retrieved by calling `get` on it.\n */\nexport class RemoteFluidObjectHandle implements IFluidHandle {\n public get IFluidRouter() { return this; }\n public get IFluidHandleContext() { return this; }\n public get IFluidHandle() { return this; }\n\n public readonly isAttached = true;\n private objectP: Promise<IFluidObject> | undefined;\n\n /**\n * Creates a new RemoteFluidObjectHandle when parsing an IFluidHandle.\n * @param absolutePath - The absolute path to the handle from the container runtime.\n * @param routeContext - The root IFluidHandleContext that has a route to this handle.\n */\n constructor(\n public readonly absolutePath: string,\n public readonly routeContext: IFluidHandleContext,\n ) {\n assert(absolutePath.startsWith(\"/\"), 0x19d /* \"Handles should always have absolute paths\" */);\n }\n\n /**\n * @deprecated - This returns the absolute path.\n */\n public get path() {\n return this.absolutePath;\n }\n\n public async get(): Promise<any> {\n if (this.objectP === undefined) {\n const request = { url: this.absolutePath };\n this.objectP = this.routeContext.resolveHandle(request)\n .then<IFluidObject>((response) => {\n if (response.mimeType === \"fluid/object\") {\n return response.value as IFluidObject;\n }\n throw responseToException(response, request);\n });\n }\n return this.objectP;\n }\n\n public attachGraph(): void {\n return;\n }\n\n public bind(handle: IFluidHandle): void {\n handle.attachGraph();\n }\n\n public async request(request: IRequest): Promise<IResponse> {\n try {\n const object = await this.get() as IFluidObject;\n const router = object.IFluidRouter;\n\n return router !== undefined\n ? router.request(request)\n : create404Response(request);\n } catch (error) {\n return exceptionToResponse(error);\n }\n }\n}\n"]} |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"summarizerNode.d.ts","sourceRoot":"","sources":["../../src/summarizerNode/summarizerNode.ts"],"names":[],"mappings":"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"} | ||
| {"version":3,"file":"summarizerNode.d.ts","sourceRoot":"","sources":["../../src/summarizerNode/summarizerNode.ts"],"names":[],"mappings":"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"} |
@@ -57,4 +57,4 @@ /*! | ||
| startSummary(referenceSequenceNumber, summaryLogger) { | ||
| assert(this.wipSummaryLogger === undefined, "wipSummaryLogger should not be set yet in startSummary"); | ||
| assert(this.wipReferenceSequenceNumber === undefined, "Already tracking a summary"); | ||
| assert(this.wipSummaryLogger === undefined, 0x19f /* "wipSummaryLogger should not be set yet in startSummary" */); | ||
| assert(this.wipReferenceSequenceNumber === undefined, 0x1a0 /* "Already tracking a summary" */); | ||
| this.wipSummaryLogger = summaryLogger; | ||
@@ -67,4 +67,4 @@ for (const child of this.children.values()) { | ||
| async summarize(fullTree) { | ||
| assert(this.isTrackingInProgress(), "summarize should not be called when not tracking the summary"); | ||
| assert(this.wipSummaryLogger !== undefined, "wipSummaryLogger should have been set in startSummary or ctor"); | ||
| assert(this.isTrackingInProgress(), 0x1a1 /* "summarize should not be called when not tracking the summary" */); | ||
| assert(this.wipSummaryLogger !== undefined, 0x1a2 /* "wipSummaryLogger should have been set in startSummary or ctor" */); | ||
| // Try to reuse the tree if unchanged | ||
@@ -149,4 +149,4 @@ if (this.canReuseHandle && !fullTree && !this.hasChanged()) { | ||
| completeSummaryCore(proposalHandle, parentPath, parentSkipRecursion) { | ||
| assert(this.wipSummaryLogger !== undefined, "wipSummaryLogger should have been set in startSummary or ctor"); | ||
| assert(this.wipReferenceSequenceNumber !== undefined, "Not tracking a summary"); | ||
| assert(this.wipSummaryLogger !== undefined, 0x1a3 /* "wipSummaryLogger should have been set in startSummary or ctor" */); | ||
| assert(this.wipReferenceSequenceNumber !== undefined, 0x1a4 /* "Not tracking a summary" */); | ||
| let localPathsToUse = this.wipLocalPaths; | ||
@@ -181,3 +181,3 @@ if (parentSkipRecursion) { | ||
| // If there is no latestSummary, clearSummary and return before reaching this code. | ||
| assert(!!localPathsToUse, "Tracked summary local paths not set"); | ||
| assert(!!localPathsToUse, 0x1a5 /* "Tracked summary local paths not set" */); | ||
| const summary = new SummaryNode(Object.assign(Object.assign({}, localPathsToUse), { referenceSequenceNumber: this.wipReferenceSequenceNumber, basePath: parentPath })); | ||
@@ -222,3 +222,3 @@ const fullPathForChildren = summary.fullPathForChildren; | ||
| // This should only happen if parent skipped recursion AND no prior summary existed. | ||
| assert(this.latestSummary === undefined, "Not found pending summary, but this node has previously completed a summary"); | ||
| assert(this.latestSummary === undefined, 0x1a6 /* "Not found pending summary, but this node has previously completed a summary" */); | ||
| return; | ||
@@ -229,3 +229,3 @@ } | ||
| // eslint-disable-next-line max-len | ||
| `Pending summary reference sequence number should be consistent: ${summaryNode.referenceSequenceNumber} != ${referenceSequenceNumber}`); | ||
| 0x1a7 /* `Pending summary reference sequence number should be consistent: ${summaryNode.referenceSequenceNumber} != ${referenceSequenceNumber}` */); | ||
| // Clear earlier pending summaries | ||
@@ -305,3 +305,3 @@ this.pendingSummaries.delete(proposalHandle); | ||
| const newOpsLatestSeq = outstandingOps[outstandingOps.length - 1].sequenceNumber; | ||
| assert(newOpsLatestSeq <= this.trackingSequenceNumber, "When loading base summary, expected outstanding ops <= tracking sequence number"); | ||
| assert(newOpsLatestSeq <= this.trackingSequenceNumber, 0x1a9 /* "When loading base summary, expected outstanding ops <= tracking sequence number" */); | ||
| } | ||
@@ -316,3 +316,3 @@ return { | ||
| if (lastOp !== undefined) { | ||
| assert(lastOp.sequenceNumber < op.sequenceNumber, `Out of order change recorded: ${lastOp.sequenceNumber} > ${op.sequenceNumber}`); | ||
| assert(lastOp.sequenceNumber < op.sequenceNumber, 0x1aa /* `Out of order change recorded: ${lastOp.sequenceNumber} > ${op.sequenceNumber}` */); | ||
| } | ||
@@ -347,3 +347,3 @@ this.invalidate(op.sequenceNumber); | ||
| createParam, config = {}) { | ||
| assert(!this.children.has(id), "Create SummarizerNode child already exists"); | ||
| assert(!this.children.has(id), 0x1ab /* "Create SummarizerNode child already exists" */); | ||
| const createDetails = this.getCreateDetailsForChild(id, createParam); | ||
@@ -392,3 +392,3 @@ const child = new SummarizerNode(this.defaultLogger, summarizeInternalFn, config, createDetails.changeSequenceNumber, createDetails.latestSummary, createDetails.initialSummary, this.wipSummaryLogger); | ||
| if (this.initialSummary === undefined) { | ||
| assert(!!parentLatestSummary, "Cannot create child from summary if parent does not have latest summary"); | ||
| assert(!!parentLatestSummary, 0x1ac /* "Cannot create child from summary if parent does not have latest summary" */); | ||
| } | ||
@@ -403,3 +403,3 @@ // fallthrough to local | ||
| const { childrenTree } = parseSummaryTreeForSubtrees(parentInitialSummary.summary.summary); | ||
| assert(childrenTree.type === 1 /* Tree */, "Parent summary object is not a tree"); | ||
| assert(childrenTree.type === 1 /* Tree */, 0x1d6 /* "Parent summary object is not a tree" */); | ||
| childSummary = childrenTree.tree[id]; | ||
@@ -409,7 +409,7 @@ } | ||
| // Locally created would not have differential subtree. | ||
| assert(!!childSummary, "Missing child summary tree"); | ||
| assert(!!childSummary, 0x1ad /* "Missing child summary tree" */); | ||
| } | ||
| let childSummaryWithStats; | ||
| if (childSummary !== undefined) { | ||
| assert(childSummary.type === 1 /* Tree */, "Child summary object is not a tree"); | ||
| assert(childSummary.type === 1 /* Tree */, 0x1ae /* "Child summary object is not a tree" */); | ||
| childSummaryWithStats = { | ||
@@ -416,0 +416,0 @@ summary: childSummary, |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"summarizerNode.js","sourceRoot":"","sources":["../../src/summarizerNode/summarizerNode.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAOH,0BAA0B,GAC7B,MAAM,qCAAqC,CAAC;AAQ7C,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AACvE,OAAO,EAAE,UAAU,EAAE,oBAAoB,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACnF,OAAO,EACH,aAAa,EACb,aAAa,EAEb,WAAW,EAIX,uBAAuB,EACvB,2BAA2B,EAE3B,WAAW,EACX,WAAW,GACd,MAAM,uBAAuB,CAAC;AAI/B;;;;;;;;;;;;GAYG;AACH,MAAM,OAAO,cAAc;IAgYvB;;;OAGG;IACH,YACuB,aAA+B,EACjC,mBAA6E,EAC9F,MAA6B,EACrB,qBAA6B;IACrC,8CAA8C;IACtC,aAA2B,EAClB,cAAgC,EACvC,gBAAmC;;QAP1B,kBAAa,GAAb,aAAa,CAAkB;QACjC,wBAAmB,GAAnB,mBAAmB,CAA0D;QAEtF,0BAAqB,GAArB,qBAAqB,CAAQ;QAE7B,kBAAa,GAAb,aAAa,CAAc;QAClB,mBAAc,GAAd,cAAc,CAAkB;QACvC,qBAAgB,GAAhB,gBAAgB,CAAmB;QAnY9B,aAAQ,GAAG,IAAI,GAAG,EAA0B,CAAC;QAC7C,qBAAgB,GAAG,IAAI,GAAG,EAAuB,CAAC;QACpD,mBAAc,GAAgC,EAAE,CAAC;QAG1D,qBAAgB,GAAG,KAAK,CAAC;QAgY7B,IAAI,CAAC,cAAc,SAAG,MAAM,CAAC,cAAc,mCAAI,IAAI,CAAC;QACpD,qDAAqD;QACrD,4CAA4C;QAC5C,mCAAmC;QACnC,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,CAAC,kCAAkC;QAC5D,IAAI,CAAC,sBAAsB,GAAG,IAAI,CAAC,qBAAqB,CAAC;IAC7D,CAAC;IAnZD;;;OAGG;IACH,IAAW,uBAAuB;;QAC9B,mBAAO,IAAI,CAAC,aAAa,0CAAE,uBAAuB,mCAAI,CAAC,CAAC;IAC5D,CAAC;IASM,YAAY,CAAC,uBAA+B,EAAE,aAA+B;QAChF,MAAM,CAAC,IAAI,CAAC,gBAAgB,KAAK,SAAS,EAAE,wDAAwD,CAAC,CAAC;QACtG,MAAM,CAAC,IAAI,CAAC,0BAA0B,KAAK,SAAS,EAAE,4BAA4B,CAAC,CAAC;QAEpF,IAAI,CAAC,gBAAgB,GAAG,aAAa,CAAC;QAEtC,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAE;YACxC,KAAK,CAAC,YAAY,CAAC,uBAAuB,EAAE,IAAI,CAAC,gBAAgB,CAAC,CAAC;SACtE;QACD,IAAI,CAAC,0BAA0B,GAAG,uBAAuB,CAAC;IAC9D,CAAC;IAEM,KAAK,CAAC,SAAS,CAAC,QAAiB;QACpC,MAAM,CAAC,IAAI,CAAC,oBAAoB,EAAE,EAAE,8DAA8D,CAAC,CAAC;QACpG,MAAM,CAAC,IAAI,CAAC,gBAAgB,KAAK,SAAS,EAAE,+DAA+D,CAAC,CAAC;QAE7G,qCAAqC;QACrC,IAAI,IAAI,CAAC,cAAc,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE;YACxD,MAAM,aAAa,GAAG,IAAI,CAAC,aAAa,CAAC;YACzC,IAAI,aAAa,KAAK,SAAS,EAAE;gBAC7B,IAAI,CAAC,aAAa,GAAG;oBACjB,SAAS,EAAE,aAAa,CAAC,SAAS;oBAClC,cAAc,EAAE,aAAa,CAAC,cAAc;iBAC/C,CAAC;gBACF,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;gBAC7B,MAAM,KAAK,GAAG,UAAU,EAAE,CAAC;gBAC3B,KAAK,CAAC,eAAe,EAAE,CAAC;gBACxB,OAAO;oBACH,OAAO,EAAE;wBACL,IAAI,gBAAoB;wBACxB,MAAM,EAAE,aAAa,CAAC,QAAQ,CAAC,IAAI;wBACnC,UAAU,cAAkB;qBAC/B;oBACD,KAAK;iBACR,CAAC;aACL;SACJ;QAED,IAAI;YACA,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,mBAAmB,CAAC,QAAQ,CAAC,CAAC;YACxD,IAAI,CAAC,aAAa,GAAG,EAAE,SAAS,EAAE,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC;YAClE,IAAI,MAAM,CAAC,oBAAoB,KAAK,SAAS,EAAE;gBAC3C,IAAI,CAAC,aAAa,CAAC,cAAc,GAAG,WAAW,CAAC,eAAe,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC;aAChG;YACD,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC;SAC3D;QAAC,OAAO,KAAK,EAAE;YACZ,IAAI,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,sBAAsB,GAAG,IAAI,CAAC,qBAAqB,EAAE;gBAC/E,MAAM,KAAK,CAAC;aACf;YACD,MAAM,aAAa,GAAG,IAAI,CAAC,aAAa,CAAC;YACzC,MAAM,cAAc,GAAG,IAAI,CAAC,cAAc,CAAC;YAE3C,IAAI,WAA+B,CAAC;YACpC,IAAI,SAAsB,CAAC;YAC3B,IAAI,aAAa,KAAK,SAAS,EAAE;gBAC7B,8CAA8C;gBAC9C,WAAW,GAAG;oBACV,WAAW,EAAE,IAAI;oBACjB,WAAW,EAAE,aAAa;iBAC7B,CAAC;gBACF,SAAS,GAAG,aAAa,CAAC,SAAS,CAAC;aACvC;iBAAM,IAAI,CAAA,cAAc,aAAd,cAAc,uBAAd,cAAc,CAAE,OAAO,MAAK,SAAS,EAAE;gBAC9C,8CAA8C;gBAC9C,WAAW,GAAG;oBACV,WAAW,EAAE,KAAK;oBAClB,cAAc,EAAE,cAAc,CAAC,OAAO;iBACzC,CAAC;gBACF,SAAS,GAAG,WAAW,CAAC,MAAM,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC;aACrD;iBAAM;gBACH,+BAA+B;gBAC/B,MAAM,KAAK,CAAC;aACf;YACD,IAAI,CAAC,gBAAgB,CAAC,cAAc,CAAC;gBACjC,SAAS,EAAE,4BAA4B;aAC1C,EACD,KAAK,CAAC,CAAC;YACP,MAAM,OAAO,GAAG,aAAa,CAAC,WAAW,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;YAChE,IAAI,CAAC,aAAa,GAAG;gBACjB,SAAS;gBACT,cAAc,EAAE,OAAO,CAAC,cAAc;aACzC,CAAC;YACF,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;YAC7B,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC;SAC7D;IACL,CAAC;IAED;;OAEG;IACI,eAAe,CAAC,cAAsB;QACzC,IAAI,CAAC,mBAAmB,CAAC,cAAc,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;IAC/D,CAAC;IAED;;OAEG;IACO,mBAAmB,CACzB,cAAsB,EACtB,UAAmC,EACnC,mBAA4B;QAE5B,MAAM,CAAC,IAAI,CAAC,gBAAgB,KAAK,SAAS,EAAE,+DAA+D,CAAC,CAAC;QAC7G,MAAM,CAAC,IAAI,CAAC,0BAA0B,KAAK,SAAS,EAAE,wBAAwB,CAAC,CAAC;QAChF,IAAI,eAAe,GAAG,IAAI,CAAC,aAAa,CAAC;QAEzC,IAAI,mBAAmB,EAAE;YACrB,MAAM,aAAa,GAAG,IAAI,CAAC,aAAa,CAAC;YACzC,IAAI,aAAa,KAAK,SAAS,EAAE;gBAC7B,qEAAqE;gBACrE,qEAAqE;gBACrE,2DAA2D;gBAC3D,qEAAqE;gBACrE,+CAA+C;gBAC/C,wEAAwE;gBACxE,eAAe,GAAG;oBACd,SAAS,EAAE,aAAa,CAAC,SAAS;oBAClC,cAAc,EAAE,aAAa,CAAC,cAAc;iBAC/C,CAAC;aACL;iBAAM;gBACH,qEAAqE;gBACrE,qEAAqE;gBACrE,mCAAmC;gBACnC,uEAAuE;gBACvE,wEAAwE;gBACxE,uEAAuE;gBACvE,IAAI,CAAC,YAAY,EAAE,CAAC;gBACpB,OAAO;aACV;SACJ;QAED,iFAAiF;QACjF,gDAAgD;QAChD,mFAAmF;QACnF,MAAM,CAAC,CAAC,CAAC,eAAe,EAAE,qCAAqC,CAAC,CAAC;QAEjE,MAAM,OAAO,GAAG,IAAI,WAAW,iCACxB,eAAe,KAClB,uBAAuB,EAAE,IAAI,CAAC,0BAA0B,EACxD,QAAQ,EAAE,UAAU,IACtB,CAAC;QACH,MAAM,mBAAmB,GAAG,OAAO,CAAC,mBAAmB,CAAC;QACxD,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAE;YACxC,KAAK,CAAC,mBAAmB,CACrB,cAAc,EACd,mBAAmB,EACnB,IAAI,CAAC,gBAAgB,IAAI,mBAAmB,CAC/C,CAAC;SACL;QACD,0DAA0D;QAC1D,+DAA+D;QAC/D,+DAA+D;QAC/D,8DAA8D;QAC9D,gEAAgE;QAChE,kEAAkE;QAClE,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC;QACnD,IAAI,CAAC,YAAY,EAAE,CAAC;IACxB,CAAC;IAEM,YAAY;QACf,IAAI,CAAC,0BAA0B,GAAG,SAAS,CAAC;QAC5C,IAAI,CAAC,aAAa,GAAG,SAAS,CAAC;QAC/B,IAAI,CAAC,gBAAgB,GAAG,KAAK,CAAC;QAC9B,IAAI,CAAC,gBAAgB,GAAG,SAAS,CAAC;QAClC,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAE;YACxC,KAAK,CAAC,YAAY,EAAE,CAAC;SACxB;IACL,CAAC;IAEM,KAAK,CAAC,oBAAoB,CAC7B,cAAkC,EAClC,WAAyC,EACzC,gBAAkC,EAClC,uBAAyC;QAEzC,IAAI,cAAc,KAAK,SAAS,EAAE;YAC9B,MAAM,gBAAgB,GAAG,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;YAEnE,IAAI,gBAAgB,KAAK,SAAS,EAAE;gBAChC,IAAI,CAAC,+BAA+B,CAAC,cAAc,EAAE,gBAAgB,CAAC,uBAAuB,CAAC,CAAC;gBAC/F,OAAO;aACV;SACJ;QAED,MAAM,YAAY,GAAG,MAAM,WAAW,EAAE,CAAC;QACzC,MAAM,uBAAuB,GAAG,MAAM,WAAW,CAAC,YAAY,EAAE,gBAAgB,CAAC,CAAC;QAClF,MAAM,IAAI,CAAC,gCAAgC,CACvC,uBAAuB,EACvB,YAAY,EACZ,SAAS,EACT,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC,EACtB,uBAAuB,EACvB,gBAAgB,CACnB,CAAC;IACN,CAAC;IAES,+BAA+B,CACrC,cAAsB,EACtB,uBAA+B;QAE/B,MAAM,WAAW,GAAG,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;QAC9D,IAAI,WAAW,KAAK,SAAS,EAAE;YAC3B,oFAAoF;YACpF,MAAM,CACF,IAAI,CAAC,aAAa,KAAK,SAAS,EAChC,6EAA6E,CAChF,CAAC;YACF,OAAO;SACV;aAAM;YACH,MAAM,CACF,uBAAuB,KAAK,WAAW,CAAC,uBAAuB;YAC/D,mCAAmC;YACnC,mEAAmE,WAAW,CAAC,uBAAuB,OAAO,uBAAuB,EAAE,CACzI,CAAC;YAEF,kCAAkC;YAClC,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;SAChD;QAED,IAAI,CAAC,wBAAwB,CAAC,uBAAuB,CAAC,CAAC;QAEvD,IAAI,CAAC,aAAa,GAAG,WAAW,CAAC;QAEjC,sCAAsC;QACtC,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAE;YACxC,KAAK,CAAC,+BAA+B,CAAC,cAAc,EAAE,uBAAuB,CAAC,CAAC;SAClF;IACL,CAAC;IAES,KAAK,CAAC,gCAAgC,CAC5C,uBAA+B,EAC/B,YAA2B,EAC3B,QAAiC,EACjC,SAAsB,EACtB,uBAAyC,EACzC,gBAAkC;QAElC,0FAA0F;QAC1F,IAAI,IAAI,CAAC,uBAAuB,IAAI,uBAAuB,EAAE;YACzD,OAAO;SACV;QAED,IAAI,CAAC,wBAAwB,CAAC,uBAAuB,CAAC,CAAC;QAEvD,MAAM,EAAE,WAAW,EAAE,SAAS,EAAE,GAAG,aAAa,CAAC,YAAY,EAAE,uBAAuB,CAAC,CAAC;QAExF,IAAI,CAAC,aAAa,GAAG,IAAI,WAAW,CAAC;YACjC,uBAAuB;YACvB,QAAQ;YACR,SAAS;SACZ,CAAC,CAAC;QAEH,MAAM,EAAE,YAAY,EAAE,gBAAgB,EAAE,GAAG,uBAAuB,CAAC,WAAW,CAAC,CAAC;QAChF,IAAI,gBAAgB,KAAK,SAAS,EAAE;YAChC,SAAS,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;SACpC;QAED,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE;YACtB,IAAI,CAAC,aAAa,CAAC,cAAc,GAAG,WAAW,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC;SAC9E;QAED,sCAAsC;QACtC,MAAM,eAAe,GAAG,IAAI,CAAC,aAAa,CAAC,mBAAmB,CAAC;QAC/D,MAAM,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC;aACtC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;YACb,uEAAuE;YACvE,gEAAgE;YAChE,OAAO,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,SAAS,CAAC;QAChD,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE,KAAK,CAAC,EAAE,EAAE;YACzB,OAAO,KAAK,CAAC,gCAAgC,CACzC,uBAAuB,EACvB,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC,EACtB,eAAe,EACf,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC,EACtB,uBAAuB,EACvB,gBAAgB,CACnB,CAAC;QACN,CAAC,CAAC,CAAC,CAAC;IACZ,CAAC;IAEO,wBAAwB,CAAC,uBAA+B;QAC5D,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,gBAAgB,EAAE;YAC9C,IAAI,KAAK,CAAC,uBAAuB,GAAG,uBAAuB,EAAE;gBACzD,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;aACrC;SACJ;QAED,gCAAgC;QAChC,OACI,IAAI,CAAC,cAAc,CAAC,MAAM,GAAG,CAAC;eAC3B,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,cAAc,IAAI,uBAAuB,EACrE;YACE,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,CAAC;SAC/B;IACL,CAAC;IAEM,kCAAkC,CAAC,QAAuB;QAC7D,gEAAgE;QAChE,mEAAmE;QACnE,MAAM,EAAE,gBAAgB,EAAE,GAAG,uBAAuB,CAAC,QAAQ,CAAC,CAAC;QAC/D,IAAI,gBAAgB,KAAK,SAAS,IAAI,IAAI,CAAC,aAAa,KAAK,SAAS,EAAE;YACpE,IAAI,CAAC,aAAa,CAAC,cAAc,GAAG,WAAW,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC;SAC5E;IACL,CAAC;IAEM,KAAK,CAAC,eAAe,CACxB,QAAuB,EACvB,gBAAkC;QAElC,MAAM,cAAc,GAAG,aAAa,CAAC,QAAQ,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;QACnE,MAAM,cAAc,GAAG,MAAM,cAAc,CAAC,iBAAiB,CAAC,gBAAgB,CAAC,CAAC;QAEhF,MAAM,EAAE,gBAAgB,EAAE,GAAG,uBAAuB,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC;QACjF,IAAI,gBAAgB,KAAK,SAAS,EAAE;YAChC,cAAc,CAAC,SAAS,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;SACnD;QAED,IAAI,cAAc,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,IAAI,IAAI,CAAC,aAAa,KAAK,SAAS,EAAE;YACzE,IAAI,CAAC,aAAa,CAAC,cAAc,GAAG,WAAW,CAAC,eAAe,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC;SAC7F;QAED,0EAA0E;QAC1E,+DAA+D;QAC/D,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE;YAC3B,MAAM,eAAe,GAAG,cAAc,CAAC,cAAc,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,cAAc,CAAC;YACjF,MAAM,CACF,eAAe,IAAI,IAAI,CAAC,sBAAsB,EAC9C,iFAAiF,CACpF,CAAC;SACL;QAED,OAAO;YACH,WAAW,EAAE,cAAc,CAAC,WAAW;YACvC,cAAc;SACjB,CAAC;IACN,CAAC;IAEM,YAAY,CAAC,EAA6B;QAC7C,MAAM,MAAM,GAAG,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,cAAc,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QACnE,IAAI,MAAM,KAAK,SAAS,EAAE;YACtB,MAAM,CACF,MAAM,CAAC,cAAc,GAAG,EAAE,CAAC,cAAc,EACzC,iCAAiC,MAAM,CAAC,cAAc,MAAM,EAAE,CAAC,cAAc,EAAE,CAClF,CAAC;SACL;QACD,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,cAAc,CAAC,CAAC;QACnC,IAAI,CAAC,sBAAsB,GAAG,EAAE,CAAC,cAAc,CAAC;QAChD,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACjC,CAAC;IAEM,UAAU,CAAC,cAAsB;QACpC,IAAI,cAAc,GAAG,IAAI,CAAC,qBAAqB,EAAE;YAC7C,IAAI,CAAC,qBAAqB,GAAG,cAAc,CAAC;SAC/C;IACL,CAAC;IAED;;;;OAIG;IACO,UAAU;QAChB,OAAO,IAAI,CAAC,qBAAqB,GAAG,IAAI,CAAC,uBAAuB,CAAC;IACrE,CAAC;IA4BM,WAAW;IACd,yBAAyB;IACzB,mBAA6E;IAC7E,2CAA2C;IAC3C,EAAU;IACV;;;;OAIG;IACH,WAA2C,EAC3C,SAAgC,EAAE;QAElC,MAAM,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,4CAA4C,CAAC,CAAC;QAE7E,MAAM,aAAa,GAAwB,IAAI,CAAC,wBAAwB,CAAC,EAAE,EAAE,WAAW,CAAC,CAAC;QAC1F,MAAM,KAAK,GAAG,IAAI,cAAc,CAC5B,IAAI,CAAC,aAAa,EAClB,mBAAmB,EACnB,MAAM,EACN,aAAa,CAAC,oBAAoB,EAClC,aAAa,CAAC,aAAa,EAC3B,aAAa,CAAC,cAAc,EAC5B,IAAI,CAAC,gBAAgB,CACxB,CAAC;QAEF,yGAAyG;QACzG,uEAAuE;QACvE,IAAI,CAAC,qBAAqB,CAAC,KAAK,CAAC,CAAC;QAElC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;QAC7B,OAAO,KAAK,CAAC;IACjB,CAAC;IAEM,QAAQ,CAAC,EAAU;QACtB,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACjC,CAAC;IAED;;;;;OAKG;IACO,wBAAwB,CAAC,EAAU,EAAE,WAA2C;;QACtF,IAAI,cAA2C,CAAC;QAChD,IAAI,aAAsC,CAAC;QAC3C,IAAI,oBAA4B,CAAC;QAEjC,MAAM,mBAAmB,GAAG,IAAI,CAAC,aAAa,CAAC;QAC/C,QAAQ,WAAW,CAAC,IAAI,EAAE;YACtB,KAAK,0BAA0B,CAAC,UAAU,CAAC,CAAC;gBACxC,IACI,mBAAmB,KAAK,SAAS;uBAC9B,WAAW,CAAC,cAAc,IAAI,mBAAmB,CAAC,uBAAuB,EAC9E;oBACE,oEAAoE;oBACpE,aAAa,GAAG,mBAAmB,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC;iBAC1D;qBAAM;oBACH,MAAM,OAAO,GAAG,oBAAoB,CAAC,WAAW,CAAC,QAAQ,CAA0B,CAAC;oBACpF,cAAc,GAAG;wBACb,cAAc,EAAE,WAAW,CAAC,cAAc;wBAC1C,EAAE;wBACF,OAAO;qBACV,CAAC;iBACL;gBACD,oBAAoB,GAAG,WAAW,CAAC,cAAc,CAAC;gBAClD,MAAM;aACT;YACD,KAAK,0BAA0B,CAAC,WAAW,CAAC,CAAC;gBACzC,IAAI,IAAI,CAAC,cAAc,KAAK,SAAS,EAAE;oBACnC,MAAM,CACF,CAAC,CAAC,mBAAmB,EACrB,yEAAyE,CAAC,CAAC;iBAClF;gBACD,uBAAuB;aAC1B;YACD,KAAK,0BAA0B,CAAC,KAAK,CAAC,CAAC;gBACnC,MAAM,oBAAoB,GAAG,IAAI,CAAC,cAAc,CAAC;gBACjD,IAAI,oBAAoB,KAAK,SAAS,EAAE;oBACpC,IAAI,YAAuC,CAAC;oBAC5C,IAAI,oBAAoB,CAAC,OAAO,KAAK,SAAS,EAAE;wBAC5C,MAAM,EAAE,YAAY,EAAE,GAAG,2BAA2B,CAAC,oBAAoB,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;wBAC3F,MAAM,CACF,YAAY,CAAC,IAAI,iBAAqB,EACtC,qCAAqC,CACxC,CAAC;wBACF,YAAY,GAAG,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;qBACxC;oBACD,IAAI,WAAW,CAAC,IAAI,KAAK,0BAA0B,CAAC,WAAW,EAAE;wBAC7D,uDAAuD;wBACvD,MAAM,CAAC,CAAC,CAAC,YAAY,EAAE,4BAA4B,CAAC,CAAC;qBACxD;oBACD,IAAI,qBAAwD,CAAC;oBAC7D,IAAI,YAAY,KAAK,SAAS,EAAE;wBAC5B,MAAM,CACF,YAAY,CAAC,IAAI,iBAAqB,EACtC,oCAAoC,CACvC,CAAC;wBACF,qBAAqB,GAAG;4BACpB,OAAO,EAAE,YAAY;4BACrB,KAAK,EAAE,cAAc,CAAC,YAAY,CAAC;yBACtC,CAAC;qBACL;oBACD,cAAc,GAAG;wBACb,cAAc,EAAE,oBAAoB,CAAC,cAAc;wBACnD,EAAE;wBACF,OAAO,EAAE,qBAAqB;qBACjC,CAAC;iBACL;gBACD,aAAa,GAAG,mBAAmB,aAAnB,mBAAmB,uBAAnB,mBAAmB,CAAE,cAAc,CAAC,EAAE,CAAC,CAAC;gBACxD,oBAAoB,SAAG,mBAAmB,aAAnB,mBAAmB,uBAAnB,mBAAmB,CAAE,uBAAuB,mCAAI,CAAC,CAAC,CAAC;gBAC1E,MAAM;aACT;YACD,OAAO,CAAC,CAAC;gBACL,MAAM,IAAI,GAAI,WAAyD,CAAC,IAAI,CAAC;gBAC7E,eAAe,CAAC,WAAW,EAAE,0CAA0C,IAAI,EAAE,CAAC,CAAC;aAClF;SACJ;QAED,OAAO;YACH,cAAc;YACd,aAAa;YACb,oBAAoB;SACvB,CAAC;IACN,CAAC;IAED;;;;OAIG;IACO,qBAAqB,CAAC,KAAqB;QACjD,6GAA6G;QAC7G,kCAAkC;QAClC,IAAI,IAAI,CAAC,oBAAoB,EAAE,EAAE;YAC7B,KAAK,CAAC,0BAA0B,GAAG,IAAI,CAAC,0BAA0B,CAAC;SACtE;IACL,CAAC;IAED;;OAEG;IACO,oBAAoB;QAC1B,OAAO,IAAI,CAAC,0BAA0B,KAAK,SAAS,CAAC;IACzD,CAAC;CACJ;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,CACpC,MAAwB,EACxB,mBAA6E,EAC7E,oBAA4B,EAC5B,uBAA2C,EAC3C,SAAgC,EAAE,EACf,EAAE,CAAC,IAAI,cAAc,CACpC,MAAM,EACN,mBAAmB,EACnB,MAAM,EACN,oBAAoB,EACpB,uBAAuB,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,aAAa,CAAC,uBAAuB,CAAC,CACzG,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport {\n ISummarizerNode,\n ISummarizerNodeConfig,\n ISummarizeInternalResult,\n ISummarizeResult,\n ISummaryTreeWithStats,\n CreateChildSummarizerNodeParam,\n CreateSummarizerNodeSource,\n} from \"@fluidframework/runtime-definitions\";\nimport {\n ISequencedDocumentMessage,\n SummaryType,\n ISnapshotTree,\n SummaryObject,\n} from \"@fluidframework/protocol-definitions\";\nimport { ITelemetryLogger } from \"@fluidframework/common-definitions\";\nimport { assert, unreachableCase } from \"@fluidframework/common-utils\";\nimport { mergeStats, convertToSummaryTree, calculateStats } from \"../summaryUtils\";\nimport {\n decodeSummary,\n encodeSummary,\n EncodeSummaryParam,\n EscapedPath,\n ICreateChildDetails,\n IInitialSummary,\n ISummarizerNodeRootContract,\n parseSummaryForSubtrees,\n parseSummaryTreeForSubtrees,\n ReadAndParseBlob,\n seqFromTree,\n SummaryNode,\n} from \"./summarizerNodeUtils\";\n\nexport interface IRootSummarizerNode extends ISummarizerNode, ISummarizerNodeRootContract {}\n\n/**\n * Encapsulates the summarizing work and state of an individual tree node in the\n * summary tree. It tracks changes and allows for optimizations when unchanged, or\n * can allow for fallback summaries to be generated when an error is encountered.\n * Usage is for the root node to call startSummary first to begin tracking a WIP\n * (work in progress) summary. Then all nodes will call summarize to summaries their\n * individual parts. Once completed and uploaded to storage, the root node will call\n * completeSummary or clearSummary to clear the WIP summary tracking state if something\n * went wrong. The SummarizerNodes will track all pending summaries that have been\n * recorded by the completeSummary call. When one of them is acked, the root node should\n * call refreshLatestSummary to inform the tree of SummarizerNodes of the new baseline\n * latest successful summary.\n */\nexport class SummarizerNode implements IRootSummarizerNode {\n /**\n * The reference sequence number of the most recent acked summary.\n * Returns 0 if there is not yet an acked summary.\n */\n public get referenceSequenceNumber() {\n return this.latestSummary?.referenceSequenceNumber ?? 0;\n }\n\n protected readonly children = new Map<string, SummarizerNode>();\n protected readonly pendingSummaries = new Map<string, SummaryNode>();\n private readonly outstandingOps: ISequencedDocumentMessage[] = [];\n private wipReferenceSequenceNumber: number | undefined;\n private wipLocalPaths: { localPath: EscapedPath, additionalPath?: EscapedPath } | undefined;\n private wipSkipRecursion = false;\n\n public startSummary(referenceSequenceNumber: number, summaryLogger: ITelemetryLogger) {\n assert(this.wipSummaryLogger === undefined, \"wipSummaryLogger should not be set yet in startSummary\");\n assert(this.wipReferenceSequenceNumber === undefined, \"Already tracking a summary\");\n\n this.wipSummaryLogger = summaryLogger;\n\n for (const child of this.children.values()) {\n child.startSummary(referenceSequenceNumber, this.wipSummaryLogger);\n }\n this.wipReferenceSequenceNumber = referenceSequenceNumber;\n }\n\n public async summarize(fullTree: boolean): Promise<ISummarizeResult> {\n assert(this.isTrackingInProgress(), \"summarize should not be called when not tracking the summary\");\n assert(this.wipSummaryLogger !== undefined, \"wipSummaryLogger should have been set in startSummary or ctor\");\n\n // Try to reuse the tree if unchanged\n if (this.canReuseHandle && !fullTree && !this.hasChanged()) {\n const latestSummary = this.latestSummary;\n if (latestSummary !== undefined) {\n this.wipLocalPaths = {\n localPath: latestSummary.localPath,\n additionalPath: latestSummary.additionalPath,\n };\n this.wipSkipRecursion = true;\n const stats = mergeStats();\n stats.handleNodeCount++;\n return {\n summary: {\n type: SummaryType.Handle,\n handle: latestSummary.fullPath.path,\n handleType: SummaryType.Tree,\n },\n stats,\n };\n }\n }\n\n try {\n const result = await this.summarizeInternalFn(fullTree);\n this.wipLocalPaths = { localPath: EscapedPath.create(result.id) };\n if (result.pathPartsForChildren !== undefined) {\n this.wipLocalPaths.additionalPath = EscapedPath.createAndConcat(result.pathPartsForChildren);\n }\n return { summary: result.summary, stats: result.stats };\n } catch (error) {\n if (this.throwOnError || this.trackingSequenceNumber < this._changeSequenceNumber) {\n throw error;\n }\n const latestSummary = this.latestSummary;\n const initialSummary = this.initialSummary;\n\n let encodeParam: EncodeSummaryParam;\n let localPath: EscapedPath;\n if (latestSummary !== undefined) {\n // Create using handle of latest acked summary\n encodeParam = {\n fromSummary: true,\n summaryNode: latestSummary,\n };\n localPath = latestSummary.localPath;\n } else if (initialSummary?.summary !== undefined) {\n // Create using initial summary from attach op\n encodeParam = {\n fromSummary: false,\n initialSummary: initialSummary.summary,\n };\n localPath = EscapedPath.create(initialSummary.id);\n } else {\n // No base summary to reference\n throw error;\n }\n this.wipSummaryLogger.sendErrorEvent({\n eventName: \"SummarizingWithBasePlusOps\",\n },\n error);\n const summary = encodeSummary(encodeParam, this.outstandingOps);\n this.wipLocalPaths = {\n localPath,\n additionalPath: summary.additionalPath,\n };\n this.wipSkipRecursion = true;\n return { summary: summary.summary, stats: summary.stats };\n }\n }\n\n /**\n * Complete the WIP summary for the given proposalHandle\n */\n public completeSummary(proposalHandle: string) {\n this.completeSummaryCore(proposalHandle, undefined, false);\n }\n\n /**\n * Recursive implementation for completeSummary, with additional internal-only parameters\n */\n protected completeSummaryCore(\n proposalHandle: string,\n parentPath: EscapedPath | undefined,\n parentSkipRecursion: boolean,\n ) {\n assert(this.wipSummaryLogger !== undefined, \"wipSummaryLogger should have been set in startSummary or ctor\");\n assert(this.wipReferenceSequenceNumber !== undefined, \"Not tracking a summary\");\n let localPathsToUse = this.wipLocalPaths;\n\n if (parentSkipRecursion) {\n const latestSummary = this.latestSummary;\n if (latestSummary !== undefined) {\n // This case the parent node created a failure summary or was reused.\n // This node and all children should only try to reference their path\n // by its last known good state in the actual summary tree.\n // If parent fails or is reused, the child summarize is not called so\n // it did not get a chance to change its paths.\n // In this case, essentially only propagate the new summary ref seq num.\n localPathsToUse = {\n localPath: latestSummary.localPath,\n additionalPath: latestSummary.additionalPath,\n };\n } else {\n // This case the child is added after the latest non-failure summary.\n // This node and all children should consider themselves as still not\n // having a successful summary yet.\n // We cannot \"reuse\" this node if unchanged since that summary, because\n // handles will be unable to point to that node. It never made it to the\n // tree itself, and only exists as an attach op in the _outstandingOps.\n this.clearSummary();\n return;\n }\n }\n\n // This should come from wipLocalPaths in normal cases, or from the latestSummary\n // if parentIsFailure or parentIsReused is true.\n // If there is no latestSummary, clearSummary and return before reaching this code.\n assert(!!localPathsToUse, \"Tracked summary local paths not set\");\n\n const summary = new SummaryNode({\n ...localPathsToUse,\n referenceSequenceNumber: this.wipReferenceSequenceNumber,\n basePath: parentPath,\n });\n const fullPathForChildren = summary.fullPathForChildren;\n for (const child of this.children.values()) {\n child.completeSummaryCore(\n proposalHandle,\n fullPathForChildren,\n this.wipSkipRecursion || parentSkipRecursion,\n );\n }\n // Note that this overwrites existing pending summary with\n // the same proposalHandle. If proposalHandle is something like\n // a hash or unique identifier, this should be fine. If storage\n // can return the same proposalHandle for a different summary,\n // this should still be okay, because we should be proposing the\n // newer one later which would have to overwrite the previous one.\n this.pendingSummaries.set(proposalHandle, summary);\n this.clearSummary();\n }\n\n public clearSummary() {\n this.wipReferenceSequenceNumber = undefined;\n this.wipLocalPaths = undefined;\n this.wipSkipRecursion = false;\n this.wipSummaryLogger = undefined;\n for (const child of this.children.values()) {\n child.clearSummary();\n }\n }\n\n public async refreshLatestSummary(\n proposalHandle: string | undefined,\n getSnapshot: () => Promise<ISnapshotTree>,\n readAndParseBlob: ReadAndParseBlob,\n correlatedSummaryLogger: ITelemetryLogger,\n ): Promise<void> {\n if (proposalHandle !== undefined) {\n const maybeSummaryNode = this.pendingSummaries.get(proposalHandle);\n\n if (maybeSummaryNode !== undefined) {\n this.refreshLatestSummaryFromPending(proposalHandle, maybeSummaryNode.referenceSequenceNumber);\n return;\n }\n }\n\n const snapshotTree = await getSnapshot();\n const referenceSequenceNumber = await seqFromTree(snapshotTree, readAndParseBlob);\n await this.refreshLatestSummaryFromSnapshot(\n referenceSequenceNumber,\n snapshotTree,\n undefined,\n EscapedPath.create(\"\"),\n correlatedSummaryLogger,\n readAndParseBlob,\n );\n }\n\n protected refreshLatestSummaryFromPending(\n proposalHandle: string,\n referenceSequenceNumber: number,\n ): void {\n const summaryNode = this.pendingSummaries.get(proposalHandle);\n if (summaryNode === undefined) {\n // This should only happen if parent skipped recursion AND no prior summary existed.\n assert(\n this.latestSummary === undefined,\n \"Not found pending summary, but this node has previously completed a summary\",\n );\n return;\n } else {\n assert(\n referenceSequenceNumber === summaryNode.referenceSequenceNumber,\n // eslint-disable-next-line max-len\n `Pending summary reference sequence number should be consistent: ${summaryNode.referenceSequenceNumber} != ${referenceSequenceNumber}`,\n );\n\n // Clear earlier pending summaries\n this.pendingSummaries.delete(proposalHandle);\n }\n\n this.refreshLatestSummaryCore(referenceSequenceNumber);\n\n this.latestSummary = summaryNode;\n\n // Propagate update to all child nodes\n for (const child of this.children.values()) {\n child.refreshLatestSummaryFromPending(proposalHandle, referenceSequenceNumber);\n }\n }\n\n protected async refreshLatestSummaryFromSnapshot(\n referenceSequenceNumber: number,\n snapshotTree: ISnapshotTree,\n basePath: EscapedPath | undefined,\n localPath: EscapedPath,\n correlatedSummaryLogger: ITelemetryLogger,\n readAndParseBlob: ReadAndParseBlob,\n ): Promise<void> {\n // Possible re-entrancy. If we have already seen a summary later than this one, ignore it.\n if (this.referenceSequenceNumber >= referenceSequenceNumber) {\n return;\n }\n\n this.refreshLatestSummaryCore(referenceSequenceNumber);\n\n const { baseSummary, pathParts } = decodeSummary(snapshotTree, correlatedSummaryLogger);\n\n this.latestSummary = new SummaryNode({\n referenceSequenceNumber,\n basePath,\n localPath,\n });\n\n const { childrenTree, childrenPathPart } = parseSummaryForSubtrees(baseSummary);\n if (childrenPathPart !== undefined) {\n pathParts.push(childrenPathPart);\n }\n\n if (pathParts.length > 0) {\n this.latestSummary.additionalPath = EscapedPath.createAndConcat(pathParts);\n }\n\n // Propagate update to all child nodes\n const pathForChildren = this.latestSummary.fullPathForChildren;\n await Promise.all(Array.from(this.children)\n .filter(([id]) => {\n // Assuming subtrees missing from snapshot are newer than the snapshot,\n // but might be nice to assert this using earliest seq for node.\n return childrenTree.trees[id] !== undefined;\n }).map(async ([id, child]) => {\n return child.refreshLatestSummaryFromSnapshot(\n referenceSequenceNumber,\n childrenTree.trees[id],\n pathForChildren,\n EscapedPath.create(id),\n correlatedSummaryLogger,\n readAndParseBlob,\n );\n }));\n }\n\n private refreshLatestSummaryCore(referenceSequenceNumber: number): void {\n for (const [key, value] of this.pendingSummaries) {\n if (value.referenceSequenceNumber < referenceSequenceNumber) {\n this.pendingSummaries.delete(key);\n }\n }\n\n // Clear earlier outstanding ops\n while (\n this.outstandingOps.length > 0\n && this.outstandingOps[0].sequenceNumber <= referenceSequenceNumber\n ) {\n this.outstandingOps.shift();\n }\n }\n\n public loadBaseSummaryWithoutDifferential(snapshot: ISnapshotTree) {\n // Check base summary to see if it has any additional path parts\n // separating child SummarizerNodes. Checks for .channels subtrees.\n const { childrenPathPart } = parseSummaryForSubtrees(snapshot);\n if (childrenPathPart !== undefined && this.latestSummary !== undefined) {\n this.latestSummary.additionalPath = EscapedPath.create(childrenPathPart);\n }\n }\n\n public async loadBaseSummary(\n snapshot: ISnapshotTree,\n readAndParseBlob: ReadAndParseBlob,\n ): Promise<{ baseSummary: ISnapshotTree, outstandingOps: ISequencedDocumentMessage[] }> {\n const decodedSummary = decodeSummary(snapshot, this.defaultLogger);\n const outstandingOps = await decodedSummary.getOutstandingOps(readAndParseBlob);\n\n const { childrenPathPart } = parseSummaryForSubtrees(decodedSummary.baseSummary);\n if (childrenPathPart !== undefined) {\n decodedSummary.pathParts.push(childrenPathPart);\n }\n\n if (decodedSummary.pathParts.length > 0 && this.latestSummary !== undefined) {\n this.latestSummary.additionalPath = EscapedPath.createAndConcat(decodedSummary.pathParts);\n }\n\n // Defensive assertion: tracking number should already exceed this number.\n // This is probably a little excessive; can remove when stable.\n if (outstandingOps.length > 0) {\n const newOpsLatestSeq = outstandingOps[outstandingOps.length - 1].sequenceNumber;\n assert(\n newOpsLatestSeq <= this.trackingSequenceNumber,\n \"When loading base summary, expected outstanding ops <= tracking sequence number\",\n );\n }\n\n return {\n baseSummary: decodedSummary.baseSummary,\n outstandingOps,\n };\n }\n\n public recordChange(op: ISequencedDocumentMessage): void {\n const lastOp = this.outstandingOps[this.outstandingOps.length - 1];\n if (lastOp !== undefined) {\n assert(\n lastOp.sequenceNumber < op.sequenceNumber,\n `Out of order change recorded: ${lastOp.sequenceNumber} > ${op.sequenceNumber}`,\n );\n }\n this.invalidate(op.sequenceNumber);\n this.trackingSequenceNumber = op.sequenceNumber;\n this.outstandingOps.push(op);\n }\n\n public invalidate(sequenceNumber: number): void {\n if (sequenceNumber > this._changeSequenceNumber) {\n this._changeSequenceNumber = sequenceNumber;\n }\n }\n\n /**\n * True if a change has been recorded with sequence number exceeding\n * the latest successfully acked summary reference sequence number.\n * False implies that the previous summary can be reused.\n */\n protected hasChanged(): boolean {\n return this._changeSequenceNumber > this.referenceSequenceNumber;\n }\n\n private readonly canReuseHandle: boolean;\n private readonly throwOnError: boolean;\n private trackingSequenceNumber: number;\n\n /**\n * Do not call constructor directly.\n * Use createRootSummarizerNode to create root node, or createChild to create child nodes.\n */\n public constructor(\n protected readonly defaultLogger: ITelemetryLogger,\n private readonly summarizeInternalFn: (fullTree: boolean) => Promise<ISummarizeInternalResult>,\n config: ISummarizerNodeConfig,\n private _changeSequenceNumber: number,\n /** Undefined means created without summary */\n private latestSummary?: SummaryNode,\n private readonly initialSummary?: IInitialSummary,\n protected wipSummaryLogger?: ITelemetryLogger,\n ) {\n this.canReuseHandle = config.canReuseHandle ?? true;\n // BUGBUG: Seeing issues with differential summaries.\n // this will disable them, and throw instead\n // while we continue to investigate\n this.throwOnError = true; // config.throwOnFailure ?? false;\n this.trackingSequenceNumber = this._changeSequenceNumber;\n }\n\n public createChild(\n /** Summarize function */\n summarizeInternalFn: (fullTree: boolean) => Promise<ISummarizeInternalResult>,\n /** Initial id or path part of this node */\n id: string,\n /**\n * Information needed to create the node.\n * If it is from a base summary, it will assert that a summary has been seen.\n * Attach information if it is created from an attach op.\n */\n createParam: CreateChildSummarizerNodeParam,\n config: ISummarizerNodeConfig = {},\n ): ISummarizerNode {\n assert(!this.children.has(id), \"Create SummarizerNode child already exists\");\n\n const createDetails: ICreateChildDetails = this.getCreateDetailsForChild(id, createParam);\n const child = new SummarizerNode(\n this.defaultLogger,\n summarizeInternalFn,\n config,\n createDetails.changeSequenceNumber,\n createDetails.latestSummary,\n createDetails.initialSummary,\n this.wipSummaryLogger,\n );\n\n // There may be additional state that has to be updated in this child. For example, if a summary is being\n // tracked, the child's summary tracking state needs to be updated too.\n this.maybeUpdateChildState(child);\n\n this.children.set(id, child);\n return child;\n }\n\n public getChild(id: string): ISummarizerNode | undefined {\n return this.children.get(id);\n }\n\n /**\n * Returns the details needed to create a child node.\n * @param id - Initial id or path part of the child node.\n * @param createParam - Information needed to create the node.\n * @returns the details needed to create the child node.\n */\n protected getCreateDetailsForChild(id: string, createParam: CreateChildSummarizerNodeParam): ICreateChildDetails {\n let initialSummary: IInitialSummary | undefined;\n let latestSummary: SummaryNode | undefined;\n let changeSequenceNumber: number;\n\n const parentLatestSummary = this.latestSummary;\n switch (createParam.type) {\n case CreateSummarizerNodeSource.FromAttach: {\n if (\n parentLatestSummary !== undefined\n && createParam.sequenceNumber <= parentLatestSummary.referenceSequenceNumber\n ) {\n // Prioritize latest summary if it was after this node was attached.\n latestSummary = parentLatestSummary.createForChild(id);\n } else {\n const summary = convertToSummaryTree(createParam.snapshot) as ISummaryTreeWithStats;\n initialSummary = {\n sequenceNumber: createParam.sequenceNumber,\n id,\n summary,\n };\n }\n changeSequenceNumber = createParam.sequenceNumber;\n break;\n }\n case CreateSummarizerNodeSource.FromSummary: {\n if (this.initialSummary === undefined) {\n assert(\n !!parentLatestSummary,\n \"Cannot create child from summary if parent does not have latest summary\");\n }\n // fallthrough to local\n }\n case CreateSummarizerNodeSource.Local: {\n const parentInitialSummary = this.initialSummary;\n if (parentInitialSummary !== undefined) {\n let childSummary: SummaryObject | undefined;\n if (parentInitialSummary.summary !== undefined) {\n const { childrenTree } = parseSummaryTreeForSubtrees(parentInitialSummary.summary.summary);\n assert(\n childrenTree.type === SummaryType.Tree,\n \"Parent summary object is not a tree\",\n );\n childSummary = childrenTree.tree[id];\n }\n if (createParam.type === CreateSummarizerNodeSource.FromSummary) {\n // Locally created would not have differential subtree.\n assert(!!childSummary, \"Missing child summary tree\");\n }\n let childSummaryWithStats: ISummaryTreeWithStats | undefined;\n if (childSummary !== undefined) {\n assert(\n childSummary.type === SummaryType.Tree,\n \"Child summary object is not a tree\",\n );\n childSummaryWithStats = {\n summary: childSummary,\n stats: calculateStats(childSummary),\n };\n }\n initialSummary = {\n sequenceNumber: parentInitialSummary.sequenceNumber,\n id,\n summary: childSummaryWithStats,\n };\n }\n latestSummary = parentLatestSummary?.createForChild(id);\n changeSequenceNumber = parentLatestSummary?.referenceSequenceNumber ?? -1;\n break;\n }\n default: {\n const type = (createParam as unknown as CreateChildSummarizerNodeParam).type;\n unreachableCase(createParam, `Unexpected CreateSummarizerNodeSource: ${type}`);\n }\n }\n\n return {\n initialSummary,\n latestSummary,\n changeSequenceNumber,\n };\n }\n\n /**\n * Updates the state of the child if required. For example, if a summary is currently being tracked, the child's\n * summary tracking state needs to be updated too.\n * @param child - The child node whose state is to be updated.\n */\n protected maybeUpdateChildState(child: SummarizerNode) {\n // If we are tracking a summary, this child was created after the tracking started. So, we need to update the\n // child's tracking state as well.\n if (this.isTrackingInProgress()) {\n child.wipReferenceSequenceNumber = this.wipReferenceSequenceNumber;\n }\n }\n\n /**\n * Tells whether summary tracking is in progress. True if \"startSummary\" API is called before summarize.\n */\n protected isTrackingInProgress(): boolean {\n return this.wipReferenceSequenceNumber !== undefined;\n }\n}\n\n/**\n * Creates a root summarizer node.\n * @param logger - Logger to use within SummarizerNode\n * @param summarizeInternalFn - Function to generate summary\n * @param changeSequenceNumber - Sequence number of latest change to new node/subtree\n * @param referenceSequenceNumber - Reference sequence number of last acked summary,\n * or undefined if not loaded from summary\n * @param config - Configure behavior of summarizer node\n */\nexport const createRootSummarizerNode = (\n logger: ITelemetryLogger,\n summarizeInternalFn: (fullTree: boolean) => Promise<ISummarizeInternalResult>,\n changeSequenceNumber: number,\n referenceSequenceNumber: number | undefined,\n config: ISummarizerNodeConfig = {},\n): IRootSummarizerNode => new SummarizerNode(\n logger,\n summarizeInternalFn,\n config,\n changeSequenceNumber,\n referenceSequenceNumber === undefined ? undefined : SummaryNode.createForRoot(referenceSequenceNumber),\n );\n"]} | ||
| {"version":3,"file":"summarizerNode.js","sourceRoot":"","sources":["../../src/summarizerNode/summarizerNode.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport {\n ISummarizerNode,\n ISummarizerNodeConfig,\n ISummarizeInternalResult,\n ISummarizeResult,\n ISummaryTreeWithStats,\n CreateChildSummarizerNodeParam,\n CreateSummarizerNodeSource,\n} from \"@fluidframework/runtime-definitions\";\nimport {\n ISequencedDocumentMessage,\n SummaryType,\n ISnapshotTree,\n SummaryObject,\n} from \"@fluidframework/protocol-definitions\";\nimport { ITelemetryLogger } from \"@fluidframework/common-definitions\";\nimport { assert, unreachableCase } from \"@fluidframework/common-utils\";\nimport { mergeStats, convertToSummaryTree, calculateStats } from \"../summaryUtils\";\nimport {\n decodeSummary,\n encodeSummary,\n EncodeSummaryParam,\n EscapedPath,\n ICreateChildDetails,\n IInitialSummary,\n ISummarizerNodeRootContract,\n parseSummaryForSubtrees,\n parseSummaryTreeForSubtrees,\n ReadAndParseBlob,\n seqFromTree,\n SummaryNode,\n} from \"./summarizerNodeUtils\";\n\nexport interface IRootSummarizerNode extends ISummarizerNode, ISummarizerNodeRootContract {}\n\n/**\n * Encapsulates the summarizing work and state of an individual tree node in the\n * summary tree. It tracks changes and allows for optimizations when unchanged, or\n * can allow for fallback summaries to be generated when an error is encountered.\n * Usage is for the root node to call startSummary first to begin tracking a WIP\n * (work in progress) summary. Then all nodes will call summarize to summaries their\n * individual parts. Once completed and uploaded to storage, the root node will call\n * completeSummary or clearSummary to clear the WIP summary tracking state if something\n * went wrong. The SummarizerNodes will track all pending summaries that have been\n * recorded by the completeSummary call. When one of them is acked, the root node should\n * call refreshLatestSummary to inform the tree of SummarizerNodes of the new baseline\n * latest successful summary.\n */\nexport class SummarizerNode implements IRootSummarizerNode {\n /**\n * The reference sequence number of the most recent acked summary.\n * Returns 0 if there is not yet an acked summary.\n */\n public get referenceSequenceNumber() {\n return this.latestSummary?.referenceSequenceNumber ?? 0;\n }\n\n protected readonly children = new Map<string, SummarizerNode>();\n protected readonly pendingSummaries = new Map<string, SummaryNode>();\n private readonly outstandingOps: ISequencedDocumentMessage[] = [];\n private wipReferenceSequenceNumber: number | undefined;\n private wipLocalPaths: { localPath: EscapedPath, additionalPath?: EscapedPath } | undefined;\n private wipSkipRecursion = false;\n\n public startSummary(referenceSequenceNumber: number, summaryLogger: ITelemetryLogger) {\n assert(this.wipSummaryLogger === undefined,\n 0x19f /* \"wipSummaryLogger should not be set yet in startSummary\" */);\n assert(this.wipReferenceSequenceNumber === undefined, 0x1a0 /* \"Already tracking a summary\" */);\n\n this.wipSummaryLogger = summaryLogger;\n\n for (const child of this.children.values()) {\n child.startSummary(referenceSequenceNumber, this.wipSummaryLogger);\n }\n this.wipReferenceSequenceNumber = referenceSequenceNumber;\n }\n\n public async summarize(fullTree: boolean): Promise<ISummarizeResult> {\n assert(this.isTrackingInProgress(), 0x1a1 /* \"summarize should not be called when not tracking the summary\" */);\n assert(this.wipSummaryLogger !== undefined,\n 0x1a2 /* \"wipSummaryLogger should have been set in startSummary or ctor\" */);\n\n // Try to reuse the tree if unchanged\n if (this.canReuseHandle && !fullTree && !this.hasChanged()) {\n const latestSummary = this.latestSummary;\n if (latestSummary !== undefined) {\n this.wipLocalPaths = {\n localPath: latestSummary.localPath,\n additionalPath: latestSummary.additionalPath,\n };\n this.wipSkipRecursion = true;\n const stats = mergeStats();\n stats.handleNodeCount++;\n return {\n summary: {\n type: SummaryType.Handle,\n handle: latestSummary.fullPath.path,\n handleType: SummaryType.Tree,\n },\n stats,\n };\n }\n }\n\n try {\n const result = await this.summarizeInternalFn(fullTree);\n this.wipLocalPaths = { localPath: EscapedPath.create(result.id) };\n if (result.pathPartsForChildren !== undefined) {\n this.wipLocalPaths.additionalPath = EscapedPath.createAndConcat(result.pathPartsForChildren);\n }\n return { summary: result.summary, stats: result.stats };\n } catch (error) {\n if (this.throwOnError || this.trackingSequenceNumber < this._changeSequenceNumber) {\n throw error;\n }\n const latestSummary = this.latestSummary;\n const initialSummary = this.initialSummary;\n\n let encodeParam: EncodeSummaryParam;\n let localPath: EscapedPath;\n if (latestSummary !== undefined) {\n // Create using handle of latest acked summary\n encodeParam = {\n fromSummary: true,\n summaryNode: latestSummary,\n };\n localPath = latestSummary.localPath;\n } else if (initialSummary?.summary !== undefined) {\n // Create using initial summary from attach op\n encodeParam = {\n fromSummary: false,\n initialSummary: initialSummary.summary,\n };\n localPath = EscapedPath.create(initialSummary.id);\n } else {\n // No base summary to reference\n throw error;\n }\n this.wipSummaryLogger.sendErrorEvent({\n eventName: \"SummarizingWithBasePlusOps\",\n },\n error);\n const summary = encodeSummary(encodeParam, this.outstandingOps);\n this.wipLocalPaths = {\n localPath,\n additionalPath: summary.additionalPath,\n };\n this.wipSkipRecursion = true;\n return { summary: summary.summary, stats: summary.stats };\n }\n }\n\n /**\n * Complete the WIP summary for the given proposalHandle\n */\n public completeSummary(proposalHandle: string) {\n this.completeSummaryCore(proposalHandle, undefined, false);\n }\n\n /**\n * Recursive implementation for completeSummary, with additional internal-only parameters\n */\n protected completeSummaryCore(\n proposalHandle: string,\n parentPath: EscapedPath | undefined,\n parentSkipRecursion: boolean,\n ) {\n assert(this.wipSummaryLogger !== undefined,\n 0x1a3 /* \"wipSummaryLogger should have been set in startSummary or ctor\" */);\n assert(this.wipReferenceSequenceNumber !== undefined, 0x1a4 /* \"Not tracking a summary\" */);\n let localPathsToUse = this.wipLocalPaths;\n\n if (parentSkipRecursion) {\n const latestSummary = this.latestSummary;\n if (latestSummary !== undefined) {\n // This case the parent node created a failure summary or was reused.\n // This node and all children should only try to reference their path\n // by its last known good state in the actual summary tree.\n // If parent fails or is reused, the child summarize is not called so\n // it did not get a chance to change its paths.\n // In this case, essentially only propagate the new summary ref seq num.\n localPathsToUse = {\n localPath: latestSummary.localPath,\n additionalPath: latestSummary.additionalPath,\n };\n } else {\n // This case the child is added after the latest non-failure summary.\n // This node and all children should consider themselves as still not\n // having a successful summary yet.\n // We cannot \"reuse\" this node if unchanged since that summary, because\n // handles will be unable to point to that node. It never made it to the\n // tree itself, and only exists as an attach op in the _outstandingOps.\n this.clearSummary();\n return;\n }\n }\n\n // This should come from wipLocalPaths in normal cases, or from the latestSummary\n // if parentIsFailure or parentIsReused is true.\n // If there is no latestSummary, clearSummary and return before reaching this code.\n assert(!!localPathsToUse, 0x1a5 /* \"Tracked summary local paths not set\" */);\n\n const summary = new SummaryNode({\n ...localPathsToUse,\n referenceSequenceNumber: this.wipReferenceSequenceNumber,\n basePath: parentPath,\n });\n const fullPathForChildren = summary.fullPathForChildren;\n for (const child of this.children.values()) {\n child.completeSummaryCore(\n proposalHandle,\n fullPathForChildren,\n this.wipSkipRecursion || parentSkipRecursion,\n );\n }\n // Note that this overwrites existing pending summary with\n // the same proposalHandle. If proposalHandle is something like\n // a hash or unique identifier, this should be fine. If storage\n // can return the same proposalHandle for a different summary,\n // this should still be okay, because we should be proposing the\n // newer one later which would have to overwrite the previous one.\n this.pendingSummaries.set(proposalHandle, summary);\n this.clearSummary();\n }\n\n public clearSummary() {\n this.wipReferenceSequenceNumber = undefined;\n this.wipLocalPaths = undefined;\n this.wipSkipRecursion = false;\n this.wipSummaryLogger = undefined;\n for (const child of this.children.values()) {\n child.clearSummary();\n }\n }\n\n public async refreshLatestSummary(\n proposalHandle: string | undefined,\n getSnapshot: () => Promise<ISnapshotTree>,\n readAndParseBlob: ReadAndParseBlob,\n correlatedSummaryLogger: ITelemetryLogger,\n ): Promise<void> {\n if (proposalHandle !== undefined) {\n const maybeSummaryNode = this.pendingSummaries.get(proposalHandle);\n\n if (maybeSummaryNode !== undefined) {\n this.refreshLatestSummaryFromPending(proposalHandle, maybeSummaryNode.referenceSequenceNumber);\n return;\n }\n }\n\n const snapshotTree = await getSnapshot();\n const referenceSequenceNumber = await seqFromTree(snapshotTree, readAndParseBlob);\n await this.refreshLatestSummaryFromSnapshot(\n referenceSequenceNumber,\n snapshotTree,\n undefined,\n EscapedPath.create(\"\"),\n correlatedSummaryLogger,\n readAndParseBlob,\n );\n }\n\n protected refreshLatestSummaryFromPending(\n proposalHandle: string,\n referenceSequenceNumber: number,\n ): void {\n const summaryNode = this.pendingSummaries.get(proposalHandle);\n if (summaryNode === undefined) {\n // This should only happen if parent skipped recursion AND no prior summary existed.\n assert(\n this.latestSummary === undefined,\n 0x1a6 /* \"Not found pending summary, but this node has previously completed a summary\" */,\n );\n return;\n } else {\n assert(\n referenceSequenceNumber === summaryNode.referenceSequenceNumber,\n // eslint-disable-next-line max-len\n 0x1a7 /* `Pending summary reference sequence number should be consistent: ${summaryNode.referenceSequenceNumber} != ${referenceSequenceNumber}` */,\n );\n\n // Clear earlier pending summaries\n this.pendingSummaries.delete(proposalHandle);\n }\n\n this.refreshLatestSummaryCore(referenceSequenceNumber);\n\n this.latestSummary = summaryNode;\n\n // Propagate update to all child nodes\n for (const child of this.children.values()) {\n child.refreshLatestSummaryFromPending(proposalHandle, referenceSequenceNumber);\n }\n }\n\n protected async refreshLatestSummaryFromSnapshot(\n referenceSequenceNumber: number,\n snapshotTree: ISnapshotTree,\n basePath: EscapedPath | undefined,\n localPath: EscapedPath,\n correlatedSummaryLogger: ITelemetryLogger,\n readAndParseBlob: ReadAndParseBlob,\n ): Promise<void> {\n // Possible re-entrancy. If we have already seen a summary later than this one, ignore it.\n if (this.referenceSequenceNumber >= referenceSequenceNumber) {\n return;\n }\n\n this.refreshLatestSummaryCore(referenceSequenceNumber);\n\n const { baseSummary, pathParts } = decodeSummary(snapshotTree, correlatedSummaryLogger);\n\n this.latestSummary = new SummaryNode({\n referenceSequenceNumber,\n basePath,\n localPath,\n });\n\n const { childrenTree, childrenPathPart } = parseSummaryForSubtrees(baseSummary);\n if (childrenPathPart !== undefined) {\n pathParts.push(childrenPathPart);\n }\n\n if (pathParts.length > 0) {\n this.latestSummary.additionalPath = EscapedPath.createAndConcat(pathParts);\n }\n\n // Propagate update to all child nodes\n const pathForChildren = this.latestSummary.fullPathForChildren;\n await Promise.all(Array.from(this.children)\n .filter(([id]) => {\n // Assuming subtrees missing from snapshot are newer than the snapshot,\n // but might be nice to assert this using earliest seq for node.\n return childrenTree.trees[id] !== undefined;\n }).map(async ([id, child]) => {\n return child.refreshLatestSummaryFromSnapshot(\n referenceSequenceNumber,\n childrenTree.trees[id],\n pathForChildren,\n EscapedPath.create(id),\n correlatedSummaryLogger,\n readAndParseBlob,\n );\n }));\n }\n\n private refreshLatestSummaryCore(referenceSequenceNumber: number): void {\n for (const [key, value] of this.pendingSummaries) {\n if (value.referenceSequenceNumber < referenceSequenceNumber) {\n this.pendingSummaries.delete(key);\n }\n }\n\n // Clear earlier outstanding ops\n while (\n this.outstandingOps.length > 0\n && this.outstandingOps[0].sequenceNumber <= referenceSequenceNumber\n ) {\n this.outstandingOps.shift();\n }\n }\n\n public loadBaseSummaryWithoutDifferential(snapshot: ISnapshotTree) {\n // Check base summary to see if it has any additional path parts\n // separating child SummarizerNodes. Checks for .channels subtrees.\n const { childrenPathPart } = parseSummaryForSubtrees(snapshot);\n if (childrenPathPart !== undefined && this.latestSummary !== undefined) {\n this.latestSummary.additionalPath = EscapedPath.create(childrenPathPart);\n }\n }\n\n public async loadBaseSummary(\n snapshot: ISnapshotTree,\n readAndParseBlob: ReadAndParseBlob,\n ): Promise<{ baseSummary: ISnapshotTree, outstandingOps: ISequencedDocumentMessage[] }> {\n const decodedSummary = decodeSummary(snapshot, this.defaultLogger);\n const outstandingOps = await decodedSummary.getOutstandingOps(readAndParseBlob);\n\n const { childrenPathPart } = parseSummaryForSubtrees(decodedSummary.baseSummary);\n if (childrenPathPart !== undefined) {\n decodedSummary.pathParts.push(childrenPathPart);\n }\n\n if (decodedSummary.pathParts.length > 0 && this.latestSummary !== undefined) {\n this.latestSummary.additionalPath = EscapedPath.createAndConcat(decodedSummary.pathParts);\n }\n\n // Defensive assertion: tracking number should already exceed this number.\n // This is probably a little excessive; can remove when stable.\n if (outstandingOps.length > 0) {\n const newOpsLatestSeq = outstandingOps[outstandingOps.length - 1].sequenceNumber;\n assert(\n newOpsLatestSeq <= this.trackingSequenceNumber,\n 0x1a9 /* \"When loading base summary, expected outstanding ops <= tracking sequence number\" */,\n );\n }\n\n return {\n baseSummary: decodedSummary.baseSummary,\n outstandingOps,\n };\n }\n\n public recordChange(op: ISequencedDocumentMessage): void {\n const lastOp = this.outstandingOps[this.outstandingOps.length - 1];\n if (lastOp !== undefined) {\n assert(\n lastOp.sequenceNumber < op.sequenceNumber,\n 0x1aa /* `Out of order change recorded: ${lastOp.sequenceNumber} > ${op.sequenceNumber}` */,\n );\n }\n this.invalidate(op.sequenceNumber);\n this.trackingSequenceNumber = op.sequenceNumber;\n this.outstandingOps.push(op);\n }\n\n public invalidate(sequenceNumber: number): void {\n if (sequenceNumber > this._changeSequenceNumber) {\n this._changeSequenceNumber = sequenceNumber;\n }\n }\n\n /**\n * True if a change has been recorded with sequence number exceeding\n * the latest successfully acked summary reference sequence number.\n * False implies that the previous summary can be reused.\n */\n protected hasChanged(): boolean {\n return this._changeSequenceNumber > this.referenceSequenceNumber;\n }\n\n private readonly canReuseHandle: boolean;\n private readonly throwOnError: boolean;\n private trackingSequenceNumber: number;\n\n /**\n * Do not call constructor directly.\n * Use createRootSummarizerNode to create root node, or createChild to create child nodes.\n */\n public constructor(\n protected readonly defaultLogger: ITelemetryLogger,\n private readonly summarizeInternalFn: (fullTree: boolean) => Promise<ISummarizeInternalResult>,\n config: ISummarizerNodeConfig,\n private _changeSequenceNumber: number,\n /** Undefined means created without summary */\n private latestSummary?: SummaryNode,\n private readonly initialSummary?: IInitialSummary,\n protected wipSummaryLogger?: ITelemetryLogger,\n ) {\n this.canReuseHandle = config.canReuseHandle ?? true;\n // BUGBUG: Seeing issues with differential summaries.\n // this will disable them, and throw instead\n // while we continue to investigate\n this.throwOnError = true; // config.throwOnFailure ?? false;\n this.trackingSequenceNumber = this._changeSequenceNumber;\n }\n\n public createChild(\n /** Summarize function */\n summarizeInternalFn: (fullTree: boolean) => Promise<ISummarizeInternalResult>,\n /** Initial id or path part of this node */\n id: string,\n /**\n * Information needed to create the node.\n * If it is from a base summary, it will assert that a summary has been seen.\n * Attach information if it is created from an attach op.\n */\n createParam: CreateChildSummarizerNodeParam,\n config: ISummarizerNodeConfig = {},\n ): ISummarizerNode {\n assert(!this.children.has(id), 0x1ab /* \"Create SummarizerNode child already exists\" */);\n\n const createDetails: ICreateChildDetails = this.getCreateDetailsForChild(id, createParam);\n const child = new SummarizerNode(\n this.defaultLogger,\n summarizeInternalFn,\n config,\n createDetails.changeSequenceNumber,\n createDetails.latestSummary,\n createDetails.initialSummary,\n this.wipSummaryLogger,\n );\n\n // There may be additional state that has to be updated in this child. For example, if a summary is being\n // tracked, the child's summary tracking state needs to be updated too.\n this.maybeUpdateChildState(child);\n\n this.children.set(id, child);\n return child;\n }\n\n public getChild(id: string): ISummarizerNode | undefined {\n return this.children.get(id);\n }\n\n /**\n * Returns the details needed to create a child node.\n * @param id - Initial id or path part of the child node.\n * @param createParam - Information needed to create the node.\n * @returns the details needed to create the child node.\n */\n protected getCreateDetailsForChild(id: string, createParam: CreateChildSummarizerNodeParam): ICreateChildDetails {\n let initialSummary: IInitialSummary | undefined;\n let latestSummary: SummaryNode | undefined;\n let changeSequenceNumber: number;\n\n const parentLatestSummary = this.latestSummary;\n switch (createParam.type) {\n case CreateSummarizerNodeSource.FromAttach: {\n if (\n parentLatestSummary !== undefined\n && createParam.sequenceNumber <= parentLatestSummary.referenceSequenceNumber\n ) {\n // Prioritize latest summary if it was after this node was attached.\n latestSummary = parentLatestSummary.createForChild(id);\n } else {\n const summary = convertToSummaryTree(createParam.snapshot) as ISummaryTreeWithStats;\n initialSummary = {\n sequenceNumber: createParam.sequenceNumber,\n id,\n summary,\n };\n }\n changeSequenceNumber = createParam.sequenceNumber;\n break;\n }\n case CreateSummarizerNodeSource.FromSummary: {\n if (this.initialSummary === undefined) {\n assert(\n !!parentLatestSummary,\n 0x1ac /* \"Cannot create child from summary if parent does not have latest summary\" */);\n }\n // fallthrough to local\n }\n case CreateSummarizerNodeSource.Local: {\n const parentInitialSummary = this.initialSummary;\n if (parentInitialSummary !== undefined) {\n let childSummary: SummaryObject | undefined;\n if (parentInitialSummary.summary !== undefined) {\n const { childrenTree } = parseSummaryTreeForSubtrees(parentInitialSummary.summary.summary);\n assert(\n childrenTree.type === SummaryType.Tree,\n 0x1d6 /* \"Parent summary object is not a tree\" */,\n );\n childSummary = childrenTree.tree[id];\n }\n if (createParam.type === CreateSummarizerNodeSource.FromSummary) {\n // Locally created would not have differential subtree.\n assert(!!childSummary, 0x1ad /* \"Missing child summary tree\" */);\n }\n let childSummaryWithStats: ISummaryTreeWithStats | undefined;\n if (childSummary !== undefined) {\n assert(\n childSummary.type === SummaryType.Tree,\n 0x1ae /* \"Child summary object is not a tree\" */,\n );\n childSummaryWithStats = {\n summary: childSummary,\n stats: calculateStats(childSummary),\n };\n }\n initialSummary = {\n sequenceNumber: parentInitialSummary.sequenceNumber,\n id,\n summary: childSummaryWithStats,\n };\n }\n latestSummary = parentLatestSummary?.createForChild(id);\n changeSequenceNumber = parentLatestSummary?.referenceSequenceNumber ?? -1;\n break;\n }\n default: {\n const type = (createParam as unknown as CreateChildSummarizerNodeParam).type;\n unreachableCase(createParam, `Unexpected CreateSummarizerNodeSource: ${type}`);\n }\n }\n\n return {\n initialSummary,\n latestSummary,\n changeSequenceNumber,\n };\n }\n\n /**\n * Updates the state of the child if required. For example, if a summary is currently being tracked, the child's\n * summary tracking state needs to be updated too.\n * @param child - The child node whose state is to be updated.\n */\n protected maybeUpdateChildState(child: SummarizerNode) {\n // If we are tracking a summary, this child was created after the tracking started. So, we need to update the\n // child's tracking state as well.\n if (this.isTrackingInProgress()) {\n child.wipReferenceSequenceNumber = this.wipReferenceSequenceNumber;\n }\n }\n\n /**\n * Tells whether summary tracking is in progress. True if \"startSummary\" API is called before summarize.\n */\n protected isTrackingInProgress(): boolean {\n return this.wipReferenceSequenceNumber !== undefined;\n }\n}\n\n/**\n * Creates a root summarizer node.\n * @param logger - Logger to use within SummarizerNode\n * @param summarizeInternalFn - Function to generate summary\n * @param changeSequenceNumber - Sequence number of latest change to new node/subtree\n * @param referenceSequenceNumber - Reference sequence number of last acked summary,\n * or undefined if not loaded from summary\n * @param config - Configure behavior of summarizer node\n */\nexport const createRootSummarizerNode = (\n logger: ITelemetryLogger,\n summarizeInternalFn: (fullTree: boolean) => Promise<ISummarizeInternalResult>,\n changeSequenceNumber: number,\n referenceSequenceNumber: number | undefined,\n config: ISummarizerNodeConfig = {},\n): IRootSummarizerNode => new SummarizerNode(\n logger,\n summarizeInternalFn,\n config,\n changeSequenceNumber,\n referenceSequenceNumber === undefined ? undefined : SummaryNode.createForRoot(referenceSequenceNumber),\n );\n"]} |
@@ -155,4 +155,4 @@ /*! | ||
| } | ||
| assert(!!outstandingOpsBlob, "Outstanding ops blob missing, but base summary tree exists"); | ||
| assert(newBaseSummary !== undefined, "Base summary tree missing, but outstanding ops blob exists"); | ||
| assert(!!outstandingOpsBlob, 0x1af /* "Outstanding ops blob missing, but base summary tree exists" */); | ||
| assert(newBaseSummary !== undefined, 0x1b0 /* "Base summary tree missing, but outstanding ops blob exists" */); | ||
| baseSummary = newBaseSummary; | ||
@@ -159,0 +159,0 @@ pathParts.push(baseSummaryTreeKey); |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"summarizerNodeUtils.js","sourceRoot":"","sources":["../../src/summarizerNode/summarizerNodeUtils.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { ITelemetryLogger } from \"@fluidframework/common-definitions\";\nimport { assert } from \"@fluidframework/common-utils\";\nimport {\n ISnapshotTree,\n IDocumentAttributes,\n ISequencedDocumentMessage,\n SummaryType,\n ISummaryTree,\n SummaryObject,\n} from \"@fluidframework/protocol-definitions\";\nimport { channelsTreeName, ISummaryTreeWithStats } from \"@fluidframework/runtime-definitions\";\nimport { SummaryTreeBuilder } from \"../summaryUtils\";\n\nconst baseSummaryTreeKey = \"_baseSummary\";\nconst outstandingOpsBlobKey = \"_outstandingOps\";\nconst maxDecodeDepth = 100;\n\n/** Reads a blob from storage and parses it from JSON. */\nexport type ReadAndParseBlob = <T>(id: string) => Promise<T>;\n\nexport interface ISummarizerNodeRootContract {\n startSummary(referenceSequenceNumber: number, summaryLogger: ITelemetryLogger): void;\n completeSummary(proposalHandle: string): void;\n clearSummary(): void;\n refreshLatestSummary(\n proposalHandle: string | undefined,\n getSnapshot: () => Promise<ISnapshotTree>,\n readAndParseBlob: ReadAndParseBlob,\n correlatedSummaryLogger: ITelemetryLogger,\n ): Promise<void>;\n}\n\n/**\n * Fetches the sequence number of the snapshot tree by examining the protocol.\n * @param tree - snapshot tree to examine\n * @param readAndParseBlob - function to read blob contents from storage\n * and parse the result from JSON.\n */\nexport async function seqFromTree(\n tree: ISnapshotTree,\n readAndParseBlob: ReadAndParseBlob,\n): Promise<number> {\n const attributesHash = tree.trees[\".protocol\"].blobs.attributes;\n const attrib = await readAndParseBlob<IDocumentAttributes>(attributesHash);\n return attrib.sequenceNumber;\n}\n\n/** Path for nodes in a tree with escaped special characters */\nexport class EscapedPath {\n private constructor(public readonly path: string) { }\n public static create(path: string): EscapedPath {\n return new EscapedPath(encodeURIComponent(path));\n }\n public static createAndConcat(pathParts: string[]): EscapedPath {\n let ret = EscapedPath.create(pathParts[0] ?? \"\");\n for (let i = 1; i < pathParts.length; i++) {\n ret = ret.concat(EscapedPath.create(pathParts[i]));\n }\n return ret;\n }\n public toString(): string {\n return this.path;\n }\n public concat(path: EscapedPath): EscapedPath {\n return new EscapedPath(`${this.path}/${path.path}`);\n }\n}\n\n/** Information about a summary relevant to a specific node in the tree */\nexport class SummaryNode {\n /** Creates an instance that is valid for the root with specific basePath and localPath */\n public static createForRoot(referenceSequenceNumber: number): SummaryNode {\n return new SummaryNode({\n referenceSequenceNumber,\n basePath: undefined,\n localPath: EscapedPath.create(\"\"), // root hard-coded to \"\"\n });\n }\n\n /** Summary reference sequence number, i.e. last sequence number seen when it was created */\n public get referenceSequenceNumber(): number {\n return this.summary.referenceSequenceNumber;\n }\n /** Full path to parent node, or undefined if this is the root */\n public get basePath(): EscapedPath | undefined {\n return this.summary.basePath;\n }\n /** Relative path to this node from its parent node */\n public get localPath(): EscapedPath {\n return this.summary.localPath;\n }\n /** Relative path from this node to its node innermost base summary */\n public get additionalPath(): EscapedPath | undefined {\n return this.summary.additionalPath;\n }\n public set additionalPath(additionalPath: EscapedPath | undefined) {\n this.summary.additionalPath = additionalPath;\n }\n constructor(private readonly summary: {\n readonly referenceSequenceNumber: number,\n readonly basePath: EscapedPath | undefined,\n readonly localPath: EscapedPath,\n additionalPath?: EscapedPath,\n }) { }\n\n /** Gets the full path to this node, to be used when sending a handle */\n public get fullPath(): EscapedPath {\n return this.basePath?.concat(this.localPath) ?? this.localPath;\n }\n\n /**\n * Gets the full path to this node's innermost base summary.\n * The children nodes can use this as their basePath to determine their path.\n */\n public get fullPathForChildren(): EscapedPath {\n return this.additionalPath !== undefined\n ? this.fullPath.concat(this.additionalPath)\n : this.fullPath;\n }\n\n /**\n * Creates a new node within the same summary for a child of this node.\n * @param id - id of the child node\n */\n public createForChild(id: string): SummaryNode {\n return new SummaryNode({\n referenceSequenceNumber: this.referenceSequenceNumber,\n basePath: this.fullPathForChildren,\n localPath: EscapedPath.create(id),\n });\n }\n}\n\n/** Result from decoding summary which may have been a differential summary. */\ninterface IDecodedSummary {\n /** The innermost base summary which is not itself a differential summary */\n readonly baseSummary: ISnapshotTree;\n /** The entire path name to the innermost base summary */\n readonly pathParts: string[];\n /** Function to fetch all outstanding ops since the innermost base summary */\n getOutstandingOps(readAndParseBlob: ReadAndParseBlob): Promise<ISequencedDocumentMessage[]>;\n}\n\n/**\n * Checks if the snapshot is created by referencing a previous successful\n * summary plus outstanding ops. If so, it will recursively \"decode\" it until\n * it gets to the last successful summary (the base summary) and returns that\n * as well as a function for fetching the outstanding ops. Also returns the\n * full path to the previous base summary for child summarizer nodes to use as\n * their base path when necessary.\n * @param snapshot - snapshot tree to decode\n */\nexport function decodeSummary(\n snapshot: ISnapshotTree,\n logger: Pick<ITelemetryLogger, \"sendTelemetryEvent\">,\n): IDecodedSummary {\n let baseSummary = snapshot;\n const pathParts: string[] = [];\n const opsBlobs: string[] = [];\n\n for (let i = 0; ; i++) {\n if (i > maxDecodeDepth) {\n logger.sendTelemetryEvent({\n eventName: \"DecodeSummaryMaxDepth\",\n maxDecodeDepth,\n });\n }\n const outstandingOpsBlob = baseSummary.blobs[outstandingOpsBlobKey];\n const newBaseSummary = baseSummary.trees[baseSummaryTreeKey];\n if (outstandingOpsBlob === undefined && newBaseSummary === undefined) {\n return {\n baseSummary,\n pathParts,\n async getOutstandingOps(readAndParseBlob: ReadAndParseBlob) {\n let outstandingOps: ISequencedDocumentMessage[] = [];\n for (const opsBlob of opsBlobs) {\n const newOutstandingOps = await readAndParseBlob<ISequencedDocumentMessage[]>(opsBlob);\n if (outstandingOps.length > 0 && newOutstandingOps.length > 0) {\n const latestSeq = outstandingOps[outstandingOps.length - 1].sequenceNumber;\n const newEarliestSeq = newOutstandingOps[0].sequenceNumber;\n if (newEarliestSeq <= latestSeq) {\n logger.sendTelemetryEvent({\n eventName:\"DuplicateOutstandingOps\",\n category: \"generic\",\n // eslint-disable-next-line max-len\n message: `newEarliestSeq <= latestSeq in decodeSummary: ${newEarliestSeq} <= ${latestSeq}`,\n });\n while (newOutstandingOps.length > 0\n && newOutstandingOps[0].sequenceNumber <= latestSeq) {\n newOutstandingOps.shift();\n }\n }\n }\n outstandingOps = outstandingOps.concat(newOutstandingOps);\n }\n return outstandingOps;\n },\n };\n }\n\n assert(!!outstandingOpsBlob, \"Outstanding ops blob missing, but base summary tree exists\");\n assert(newBaseSummary !== undefined, \"Base summary tree missing, but outstanding ops blob exists\");\n baseSummary = newBaseSummary;\n pathParts.push(baseSummaryTreeKey);\n opsBlobs.unshift(outstandingOpsBlob);\n }\n}\n\n/**\n * Summary tree which is a handle of the previous successfully acked summary\n * and a blob of the outstanding ops since that summary.\n */\ninterface IEncodedSummary extends ISummaryTreeWithStats {\n readonly additionalPath: EscapedPath;\n}\n\n/**\n * Parameter to help encode summary with conditional behavior.\n * When fromSummary is true, it will contain the SummaryNode of\n * its previous summary, which it can use to point to with a handle.\n * When fromSummary is false, it will use an actual summary tree\n * as its base summary in case the first summary is a differential summary.\n */\nexport type EncodeSummaryParam = {\n fromSummary: true;\n summaryNode: SummaryNode;\n} | {\n fromSummary: false;\n initialSummary: ISummaryTreeWithStats;\n};\n\n/**\n * Creates a summary tree which is a handle of the previous successfully acked summary\n * and a blob of the outstanding ops since that summary. If there is no acked summary yet,\n * it will create with the tree found in the initial attach op and the blob of outstanding ops.\n * @param summaryParam - information about last acked summary and paths to encode if from summary,\n * otherwise the initial summary from the attach op.\n * @param outstandingOps - outstanding ops since last acked summary\n */\nexport function encodeSummary(\n summaryParam: EncodeSummaryParam,\n outstandingOps: ISequencedDocumentMessage[],\n): IEncodedSummary {\n let additionalPath = EscapedPath.create(baseSummaryTreeKey);\n\n const builder = new SummaryTreeBuilder();\n builder.addBlob(outstandingOpsBlobKey, JSON.stringify(outstandingOps));\n\n if (summaryParam.fromSummary) {\n // Create using handle of latest acked summary\n const summaryNode = summaryParam.summaryNode;\n if (summaryNode.additionalPath !== undefined) {\n additionalPath = additionalPath.concat(summaryNode.additionalPath);\n }\n builder.addHandle(baseSummaryTreeKey, SummaryType.Tree, summaryNode.fullPath.path);\n } else {\n // Create using initial summary from attach op\n builder.addWithStats(baseSummaryTreeKey, summaryParam.initialSummary);\n }\n\n const summary = builder.getSummaryTree();\n return {\n ...summary,\n additionalPath,\n };\n}\n\n/**\n * Information about the initial summary tree found from an attach op.\n */\nexport interface IInitialSummary {\n sequenceNumber: number;\n id: string;\n summary: ISummaryTreeWithStats | undefined;\n}\n\n/**\n * Represents the details needed to create a child summarizer node.\n */\nexport interface ICreateChildDetails {\n /** Summary from attach op if known */\n initialSummary: IInitialSummary | undefined;\n /** Latest summary from server node data */\n latestSummary: SummaryNode | undefined;\n /** Sequence number of latest known change to the node */\n changeSequenceNumber: number;\n}\n\nexport interface ISubtreeInfo<T extends ISnapshotTree | SummaryObject> {\n /** Tree to use to find children subtrees */\n childrenTree: T,\n /** Additional path part where children are isolated */\n childrenPathPart: string | undefined,\n}\n\n/**\n * Checks if the summary contains .channels subtree where the children subtrees\n * would be located if exists.\n * @param baseSummary - summary to check\n */\nexport function parseSummaryForSubtrees(baseSummary: ISnapshotTree): ISubtreeInfo<ISnapshotTree> {\n // New versions of snapshots have child nodes isolated in .channels subtree\n const channelsSubtree = baseSummary.trees[channelsTreeName];\n if (channelsSubtree !== undefined) {\n return {\n childrenTree: channelsSubtree,\n childrenPathPart: channelsTreeName,\n };\n }\n return {\n childrenTree: baseSummary,\n childrenPathPart: undefined,\n };\n}\n\n/**\n * Checks if the summary contains .channels subtree where the children subtrees\n * would be located if exists.\n * @param baseSummary - summary to check\n */\nexport function parseSummaryTreeForSubtrees(summary: ISummaryTree): ISubtreeInfo<SummaryObject> {\n // New versions of snapshots have child nodes isolated in .channels subtree\n const channelsSubtree = summary.tree[channelsTreeName];\n if (channelsSubtree !== undefined) {\n return {\n childrenTree: channelsSubtree,\n childrenPathPart: channelsTreeName,\n };\n }\n return {\n childrenTree: summary,\n childrenPathPart: undefined,\n };\n}\n"]} | ||
| {"version":3,"file":"summarizerNodeUtils.js","sourceRoot":"","sources":["../../src/summarizerNode/summarizerNodeUtils.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { ITelemetryLogger } from \"@fluidframework/common-definitions\";\nimport { assert } from \"@fluidframework/common-utils\";\nimport {\n ISnapshotTree,\n IDocumentAttributes,\n ISequencedDocumentMessage,\n SummaryType,\n ISummaryTree,\n SummaryObject,\n} from \"@fluidframework/protocol-definitions\";\nimport { channelsTreeName, ISummaryTreeWithStats } from \"@fluidframework/runtime-definitions\";\nimport { SummaryTreeBuilder } from \"../summaryUtils\";\n\nconst baseSummaryTreeKey = \"_baseSummary\";\nconst outstandingOpsBlobKey = \"_outstandingOps\";\nconst maxDecodeDepth = 100;\n\n/** Reads a blob from storage and parses it from JSON. */\nexport type ReadAndParseBlob = <T>(id: string) => Promise<T>;\n\nexport interface ISummarizerNodeRootContract {\n startSummary(referenceSequenceNumber: number, summaryLogger: ITelemetryLogger): void;\n completeSummary(proposalHandle: string): void;\n clearSummary(): void;\n refreshLatestSummary(\n proposalHandle: string | undefined,\n getSnapshot: () => Promise<ISnapshotTree>,\n readAndParseBlob: ReadAndParseBlob,\n correlatedSummaryLogger: ITelemetryLogger,\n ): Promise<void>;\n}\n\n/**\n * Fetches the sequence number of the snapshot tree by examining the protocol.\n * @param tree - snapshot tree to examine\n * @param readAndParseBlob - function to read blob contents from storage\n * and parse the result from JSON.\n */\nexport async function seqFromTree(\n tree: ISnapshotTree,\n readAndParseBlob: ReadAndParseBlob,\n): Promise<number> {\n const attributesHash = tree.trees[\".protocol\"].blobs.attributes;\n const attrib = await readAndParseBlob<IDocumentAttributes>(attributesHash);\n return attrib.sequenceNumber;\n}\n\n/** Path for nodes in a tree with escaped special characters */\nexport class EscapedPath {\n private constructor(public readonly path: string) { }\n public static create(path: string): EscapedPath {\n return new EscapedPath(encodeURIComponent(path));\n }\n public static createAndConcat(pathParts: string[]): EscapedPath {\n let ret = EscapedPath.create(pathParts[0] ?? \"\");\n for (let i = 1; i < pathParts.length; i++) {\n ret = ret.concat(EscapedPath.create(pathParts[i]));\n }\n return ret;\n }\n public toString(): string {\n return this.path;\n }\n public concat(path: EscapedPath): EscapedPath {\n return new EscapedPath(`${this.path}/${path.path}`);\n }\n}\n\n/** Information about a summary relevant to a specific node in the tree */\nexport class SummaryNode {\n /** Creates an instance that is valid for the root with specific basePath and localPath */\n public static createForRoot(referenceSequenceNumber: number): SummaryNode {\n return new SummaryNode({\n referenceSequenceNumber,\n basePath: undefined,\n localPath: EscapedPath.create(\"\"), // root hard-coded to \"\"\n });\n }\n\n /** Summary reference sequence number, i.e. last sequence number seen when it was created */\n public get referenceSequenceNumber(): number {\n return this.summary.referenceSequenceNumber;\n }\n /** Full path to parent node, or undefined if this is the root */\n public get basePath(): EscapedPath | undefined {\n return this.summary.basePath;\n }\n /** Relative path to this node from its parent node */\n public get localPath(): EscapedPath {\n return this.summary.localPath;\n }\n /** Relative path from this node to its node innermost base summary */\n public get additionalPath(): EscapedPath | undefined {\n return this.summary.additionalPath;\n }\n public set additionalPath(additionalPath: EscapedPath | undefined) {\n this.summary.additionalPath = additionalPath;\n }\n constructor(private readonly summary: {\n readonly referenceSequenceNumber: number,\n readonly basePath: EscapedPath | undefined,\n readonly localPath: EscapedPath,\n additionalPath?: EscapedPath,\n }) { }\n\n /** Gets the full path to this node, to be used when sending a handle */\n public get fullPath(): EscapedPath {\n return this.basePath?.concat(this.localPath) ?? this.localPath;\n }\n\n /**\n * Gets the full path to this node's innermost base summary.\n * The children nodes can use this as their basePath to determine their path.\n */\n public get fullPathForChildren(): EscapedPath {\n return this.additionalPath !== undefined\n ? this.fullPath.concat(this.additionalPath)\n : this.fullPath;\n }\n\n /**\n * Creates a new node within the same summary for a child of this node.\n * @param id - id of the child node\n */\n public createForChild(id: string): SummaryNode {\n return new SummaryNode({\n referenceSequenceNumber: this.referenceSequenceNumber,\n basePath: this.fullPathForChildren,\n localPath: EscapedPath.create(id),\n });\n }\n}\n\n/** Result from decoding summary which may have been a differential summary. */\ninterface IDecodedSummary {\n /** The innermost base summary which is not itself a differential summary */\n readonly baseSummary: ISnapshotTree;\n /** The entire path name to the innermost base summary */\n readonly pathParts: string[];\n /** Function to fetch all outstanding ops since the innermost base summary */\n getOutstandingOps(readAndParseBlob: ReadAndParseBlob): Promise<ISequencedDocumentMessage[]>;\n}\n\n/**\n * Checks if the snapshot is created by referencing a previous successful\n * summary plus outstanding ops. If so, it will recursively \"decode\" it until\n * it gets to the last successful summary (the base summary) and returns that\n * as well as a function for fetching the outstanding ops. Also returns the\n * full path to the previous base summary for child summarizer nodes to use as\n * their base path when necessary.\n * @param snapshot - snapshot tree to decode\n */\nexport function decodeSummary(\n snapshot: ISnapshotTree,\n logger: Pick<ITelemetryLogger, \"sendTelemetryEvent\">,\n): IDecodedSummary {\n let baseSummary = snapshot;\n const pathParts: string[] = [];\n const opsBlobs: string[] = [];\n\n for (let i = 0; ; i++) {\n if (i > maxDecodeDepth) {\n logger.sendTelemetryEvent({\n eventName: \"DecodeSummaryMaxDepth\",\n maxDecodeDepth,\n });\n }\n const outstandingOpsBlob = baseSummary.blobs[outstandingOpsBlobKey];\n const newBaseSummary = baseSummary.trees[baseSummaryTreeKey];\n if (outstandingOpsBlob === undefined && newBaseSummary === undefined) {\n return {\n baseSummary,\n pathParts,\n async getOutstandingOps(readAndParseBlob: ReadAndParseBlob) {\n let outstandingOps: ISequencedDocumentMessage[] = [];\n for (const opsBlob of opsBlobs) {\n const newOutstandingOps = await readAndParseBlob<ISequencedDocumentMessage[]>(opsBlob);\n if (outstandingOps.length > 0 && newOutstandingOps.length > 0) {\n const latestSeq = outstandingOps[outstandingOps.length - 1].sequenceNumber;\n const newEarliestSeq = newOutstandingOps[0].sequenceNumber;\n if (newEarliestSeq <= latestSeq) {\n logger.sendTelemetryEvent({\n eventName:\"DuplicateOutstandingOps\",\n category: \"generic\",\n // eslint-disable-next-line max-len\n message: `newEarliestSeq <= latestSeq in decodeSummary: ${newEarliestSeq} <= ${latestSeq}`,\n });\n while (newOutstandingOps.length > 0\n && newOutstandingOps[0].sequenceNumber <= latestSeq) {\n newOutstandingOps.shift();\n }\n }\n }\n outstandingOps = outstandingOps.concat(newOutstandingOps);\n }\n return outstandingOps;\n },\n };\n }\n\n assert(!!outstandingOpsBlob, 0x1af /* \"Outstanding ops blob missing, but base summary tree exists\" */);\n assert(newBaseSummary !== undefined, 0x1b0 /* \"Base summary tree missing, but outstanding ops blob exists\" */);\n baseSummary = newBaseSummary;\n pathParts.push(baseSummaryTreeKey);\n opsBlobs.unshift(outstandingOpsBlob);\n }\n}\n\n/**\n * Summary tree which is a handle of the previous successfully acked summary\n * and a blob of the outstanding ops since that summary.\n */\ninterface IEncodedSummary extends ISummaryTreeWithStats {\n readonly additionalPath: EscapedPath;\n}\n\n/**\n * Parameter to help encode summary with conditional behavior.\n * When fromSummary is true, it will contain the SummaryNode of\n * its previous summary, which it can use to point to with a handle.\n * When fromSummary is false, it will use an actual summary tree\n * as its base summary in case the first summary is a differential summary.\n */\nexport type EncodeSummaryParam = {\n fromSummary: true;\n summaryNode: SummaryNode;\n} | {\n fromSummary: false;\n initialSummary: ISummaryTreeWithStats;\n};\n\n/**\n * Creates a summary tree which is a handle of the previous successfully acked summary\n * and a blob of the outstanding ops since that summary. If there is no acked summary yet,\n * it will create with the tree found in the initial attach op and the blob of outstanding ops.\n * @param summaryParam - information about last acked summary and paths to encode if from summary,\n * otherwise the initial summary from the attach op.\n * @param outstandingOps - outstanding ops since last acked summary\n */\nexport function encodeSummary(\n summaryParam: EncodeSummaryParam,\n outstandingOps: ISequencedDocumentMessage[],\n): IEncodedSummary {\n let additionalPath = EscapedPath.create(baseSummaryTreeKey);\n\n const builder = new SummaryTreeBuilder();\n builder.addBlob(outstandingOpsBlobKey, JSON.stringify(outstandingOps));\n\n if (summaryParam.fromSummary) {\n // Create using handle of latest acked summary\n const summaryNode = summaryParam.summaryNode;\n if (summaryNode.additionalPath !== undefined) {\n additionalPath = additionalPath.concat(summaryNode.additionalPath);\n }\n builder.addHandle(baseSummaryTreeKey, SummaryType.Tree, summaryNode.fullPath.path);\n } else {\n // Create using initial summary from attach op\n builder.addWithStats(baseSummaryTreeKey, summaryParam.initialSummary);\n }\n\n const summary = builder.getSummaryTree();\n return {\n ...summary,\n additionalPath,\n };\n}\n\n/**\n * Information about the initial summary tree found from an attach op.\n */\nexport interface IInitialSummary {\n sequenceNumber: number;\n id: string;\n summary: ISummaryTreeWithStats | undefined;\n}\n\n/**\n * Represents the details needed to create a child summarizer node.\n */\nexport interface ICreateChildDetails {\n /** Summary from attach op if known */\n initialSummary: IInitialSummary | undefined;\n /** Latest summary from server node data */\n latestSummary: SummaryNode | undefined;\n /** Sequence number of latest known change to the node */\n changeSequenceNumber: number;\n}\n\nexport interface ISubtreeInfo<T extends ISnapshotTree | SummaryObject> {\n /** Tree to use to find children subtrees */\n childrenTree: T,\n /** Additional path part where children are isolated */\n childrenPathPart: string | undefined,\n}\n\n/**\n * Checks if the summary contains .channels subtree where the children subtrees\n * would be located if exists.\n * @param baseSummary - summary to check\n */\nexport function parseSummaryForSubtrees(baseSummary: ISnapshotTree): ISubtreeInfo<ISnapshotTree> {\n // New versions of snapshots have child nodes isolated in .channels subtree\n const channelsSubtree = baseSummary.trees[channelsTreeName];\n if (channelsSubtree !== undefined) {\n return {\n childrenTree: channelsSubtree,\n childrenPathPart: channelsTreeName,\n };\n }\n return {\n childrenTree: baseSummary,\n childrenPathPart: undefined,\n };\n}\n\n/**\n * Checks if the summary contains .channels subtree where the children subtrees\n * would be located if exists.\n * @param baseSummary - summary to check\n */\nexport function parseSummaryTreeForSubtrees(summary: ISummaryTree): ISubtreeInfo<SummaryObject> {\n // New versions of snapshots have child nodes isolated in .channels subtree\n const channelsSubtree = summary.tree[channelsTreeName];\n if (channelsSubtree !== undefined) {\n return {\n childrenTree: channelsSubtree,\n childrenPathPart: channelsTreeName,\n };\n }\n return {\n childrenTree: summary,\n childrenPathPart: undefined,\n };\n}\n"]} |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"summarizerNodeWithGc.d.ts","sourceRoot":"","sources":["../../src/summarizerNode/summarizerNodeWithGc.ts"],"names":[],"mappings":"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"} | ||
| {"version":3,"file":"summarizerNodeWithGc.d.ts","sourceRoot":"","sources":["../../src/summarizerNode/summarizerNodeWithGc.ts"],"names":[],"mappings":"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"} |
@@ -78,3 +78,3 @@ /*! | ||
| if (!this.gcDisabled && this.isTrackingInProgress()) { | ||
| assert(this.wipSerializedUsedRoutes !== undefined, "wip used routes should be set if tracking a summary"); | ||
| assert(this.wipSerializedUsedRoutes !== undefined, 0x1b1 /* "wip used routes should be set if tracking a summary" */); | ||
| } | ||
@@ -85,3 +85,3 @@ // If trackState is true, get summary from base summarizer node which tracks summary state. | ||
| const summarizeResult = await super.summarize(fullTree); | ||
| // If there is no cached GC data, return empty data in summarize result. It is the caller's responsiblity | ||
| // If there is no cached GC data, return empty data in summarize result. It is the caller's responsibility | ||
| // to ensure that GC data is available by calling getGCData before calling summarize. | ||
@@ -106,4 +106,4 @@ const gcData = this.gcData !== undefined ? cloneGCData(this.gcData) : { gcNodes: {} }; | ||
| async getGCData(fullGC = false) { | ||
| assert(!this.gcDisabled, "Getting GC data should not be called when GC is disabled!"); | ||
| assert(this.getGCDataFn !== undefined, "GC data cannot be retrieved without getGCDataFn"); | ||
| assert(!this.gcDisabled, 0x1b2 /* "Getting GC data should not be called when GC is disabled!" */); | ||
| assert(this.getGCDataFn !== undefined, 0x1b3 /* "GC data cannot be retrieved without getGCDataFn" */); | ||
| // Load GC details from the initial summary, if not already loaded. If this is the first time this function is | ||
@@ -128,3 +128,3 @@ // called and the node's data has not changed since last summary, the GC data in initial details is returned. | ||
| if (!this.gcDisabled) { | ||
| assert(this.wipSerializedUsedRoutes === undefined, "We should not already be tracking used routes when to track a new summary"); | ||
| assert(this.wipSerializedUsedRoutes === undefined, 0x1b4 /* "We should not already be tracking used routes when to track a new summary" */); | ||
| // back-compat: 0.33 - This will be done in `updateUsedRoutes`. Older clients do not have that method, so | ||
@@ -145,3 +145,3 @@ // keeping this one for now. | ||
| wipSerializedUsedRoutes = this.wipSerializedUsedRoutes; | ||
| assert(wipSerializedUsedRoutes !== undefined, "We should have been tracking used routes"); | ||
| assert(wipSerializedUsedRoutes !== undefined, 0x1b5 /* "We should have been tracking used routes" */); | ||
| } | ||
@@ -214,3 +214,3 @@ super.completeSummaryCore(proposalHandle, parentPath, parentSkipRecursion); | ||
| var _a; | ||
| assert(!this.children.has(id), "Create SummarizerNode child already exists"); | ||
| assert(!this.children.has(id), 0x1b6 /* "Create SummarizerNode child already exists" */); | ||
| const createDetails = this.getCreateDetailsForChild(id, createParam); | ||
@@ -217,0 +217,0 @@ const child = new SummarizerNodeWithGC(this.defaultLogger, summarizeInternalFn, Object.assign(Object.assign({}, config), { |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"summarizerNodeWithGc.js","sourceRoot":"","sources":["../../src/summarizerNode/summarizerNodeWithGc.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { ITelemetryLogger } from \"@fluidframework/common-definitions\";\nimport { assert, LazyPromise } from \"@fluidframework/common-utils\";\nimport { cloneGCData } from \"@fluidframework/garbage-collector\";\nimport { ISnapshotTree } from \"@fluidframework/protocol-definitions\";\nimport {\n CreateChildSummarizerNodeParam,\n gcBlobKey,\n IContextSummarizeResult,\n IGarbageCollectionData,\n IGarbageCollectionSummaryDetails,\n ISummarizeInternalResult,\n ISummarizerNodeConfigWithGC,\n ISummarizerNodeWithGC,\n} from \"@fluidframework/runtime-definitions\";\nimport { SummarizerNode } from \"./summarizerNode\";\nimport {\n EscapedPath,\n ICreateChildDetails,\n IInitialSummary,\n ISummarizerNodeRootContract,\n ReadAndParseBlob,\n SummaryNode,\n} from \"./summarizerNodeUtils\";\n\nexport interface IRootSummarizerNodeWithGC extends ISummarizerNodeWithGC, ISummarizerNodeRootContract {}\n\n// Extend SummaryNode to add used routes tracking to it.\nclass SummaryNodeWithGC extends SummaryNode {\n constructor(\n public readonly serializedUsedRoutes: string,\n summary: {\n readonly referenceSequenceNumber: number,\n readonly basePath: EscapedPath | undefined,\n readonly localPath: EscapedPath,\n additionalPath?: EscapedPath,\n },\n ) {\n super(summary);\n }\n}\n\n/**\n * Extends the functionality of SummarizerNode to manage this node's garbage collection data:\n * - Adds a new API `getGCData` to return GC data of this node.\n * - Caches the result of `getGCData` to be used if nothing changes between summaries.\n * - Adds GC data to the result of summarize.\n * - Manages the used routes of this node. These are used to identify if this node is referenced in the document\n * and to determine if the node's used state changed since last summary.\n * - Adds trackState param to summarize. If trackState is false, it bypasses the SummarizerNode and calls\n * directly into summarizeInternal method.\n */\nexport class SummarizerNodeWithGC extends SummarizerNode implements IRootSummarizerNodeWithGC {\n private gcData: IGarbageCollectionData | undefined;\n\n // Tracks the work-in-progress used routes during summary.\n private wipSerializedUsedRoutes: string | undefined;\n\n // This is the last known used routes of this node as seen by the server as part of a summary.\n private referenceUsedRoutes: string[] | undefined;\n\n // The GC details of this node in the initial summary.\n private readonly gcDetailsInInitialSummaryP: LazyPromise<IGarbageCollectionSummaryDetails>;\n\n // Set used routes to have self route by default. This makes the node referenced by default. This is done to ensure\n // that this node is not marked as collected when running GC has been disabled. Once, the option to disable GC is\n // removed (from runGC flag in IContainerRuntimeOptions), this should be changed to be have no routes by default.\n private _usedRoutes: string[] = [\"\"];\n public get usedRoutes(): string[] {\n return this._usedRoutes;\n }\n\n // True if GC is disabled for this node. If so, do not track GC specific state for a summary.\n private readonly gcDisabled: boolean;\n\n /**\n * Do not call constructor directly.\n * Use createRootSummarizerNodeWithGC to create root node, or createChild to create child nodes.\n */\n public constructor(\n logger: ITelemetryLogger,\n private readonly summarizeFn: (fullTree: boolean, trackState: boolean) => Promise<ISummarizeInternalResult>,\n config: ISummarizerNodeConfigWithGC,\n changeSequenceNumber: number,\n /** Undefined means created without summary */\n latestSummary?: SummaryNode,\n initialSummary?: IInitialSummary,\n wipSummaryLogger?: ITelemetryLogger,\n private readonly getGCDataFn?: (fullGC?: boolean) => Promise<IGarbageCollectionData>,\n getInitialGCSummaryDetailsFn?: () => Promise<IGarbageCollectionSummaryDetails>,\n ) {\n super(\n logger,\n async (fullTree: boolean) => this.summarizeInternal(fullTree, true /* trackState */),\n config,\n changeSequenceNumber,\n latestSummary,\n initialSummary,\n wipSummaryLogger,\n );\n\n this.gcDisabled = config.gcDisabled === true;\n\n this.gcDetailsInInitialSummaryP = new LazyPromise(async () => {\n // back-compat: 0.32. getInitialGCSummaryDetailsFn() returns undefined in 0.31. Remove undefined check\n // when N > 34.\n const gcSummaryDetails = await getInitialGCSummaryDetailsFn?.();\n return gcSummaryDetails ?? { usedRoutes: [] };\n });\n }\n\n /**\n * Loads state from this node's initial GC summary details. This contains the following data from the last summary\n * seen by the server for this client:\n * - usedRoutes: This is used to figure out if the used state of this node changed since last summary.\n * - gcData: The garbage collection data of this node that is required for running GC.\n */\n private async loadInitialGCSummaryDetails() {\n // If referenceUsedRoutes is not undefined, don't do anything because we have already initialized.\n if (this.referenceUsedRoutes === undefined) {\n const gcDetailsInInitialSummary = await this.gcDetailsInInitialSummaryP;\n this.referenceUsedRoutes = gcDetailsInInitialSummary.usedRoutes;\n\n // If the GC details has GC data, initialize our GC data from it.\n if (gcDetailsInInitialSummary.gcData !== undefined) {\n this.gcData = cloneGCData(gcDetailsInInitialSummary.gcData);\n }\n }\n }\n\n public async summarize(fullTree: boolean, trackState: boolean = true): Promise<IContextSummarizeResult> {\n // Load GC details from the initial summary, if it's not already loaded. If this is the first time this node is\n // being summarized, the used routes in it are needed to find out if this node has changed since last summary.\n // If it hasn't changed, the GC data in it needs to be returned as part of the summary.\n await this.loadInitialGCSummaryDetails();\n\n // If GC is not disabled and we are tracking a summary, GC should have run and updated the used routes for this\n // summary by calling updateUsedRoutes which sets wipSerializedUsedRoutes.\n if (!this.gcDisabled && this.isTrackingInProgress()) {\n assert(this.wipSerializedUsedRoutes !== undefined, \"wip used routes should be set if tracking a summary\");\n }\n\n // If trackState is true, get summary from base summarizer node which tracks summary state.\n // If trackState is false, get summary from summarizeInternal.\n if (trackState) {\n const summarizeResult = await super.summarize(fullTree);\n\n // If there is no cached GC data, return empty data in summarize result. It is the caller's responsiblity\n // to ensure that GC data is available by calling getGCData before calling summarize.\n const gcData = this.gcData !== undefined ? cloneGCData(this.gcData) : { gcNodes: {} };\n\n return {\n ...summarizeResult,\n gcData,\n };\n } else {\n return this.summarizeInternal(fullTree, trackState);\n }\n }\n\n private async summarizeInternal(fullTree: boolean, trackState: boolean): Promise<ISummarizeInternalResult> {\n const summarizeResult = await this.summarizeFn(fullTree, trackState);\n this.gcData = cloneGCData(summarizeResult.gcData);\n return summarizeResult;\n }\n\n /**\n * Returns the GC data of this node. If nothing has changed since last summary, it tries to reuse the data from\n * the previous summary. Else, it gets new GC data from the underlying Fluid object.\n * @param fullGC - true to bypass optimizations and force full generation of GC data.\n */\n public async getGCData(fullGC: boolean = false): Promise<IGarbageCollectionData> {\n assert(!this.gcDisabled, \"Getting GC data should not be called when GC is disabled!\");\n assert(this.getGCDataFn !== undefined, \"GC data cannot be retrieved without getGCDataFn\");\n\n // Load GC details from the initial summary, if not already loaded. If this is the first time this function is\n // called and the node's data has not changed since last summary, the GC data in initial details is returned.\n await this.loadInitialGCSummaryDetails();\n\n // If there is no new data since last summary and we have GC data from the previous run, return it. We may not\n // have data from previous GC run for clients with older summary format before GC was added. They won't have\n // GC details in their initial summary.\n if (!fullGC && !this.hasDataChanged() && this.gcData !== undefined) {\n return cloneGCData(this.gcData);\n }\n\n const gcData = await this.getGCDataFn(fullGC);\n this.gcData = cloneGCData(gcData);\n return gcData;\n }\n\n /**\n * Called during the start of a summary. Updates the work-in-progress used routes.\n */\n public startSummary(referenceSequenceNumber: number, summaryLogger: ITelemetryLogger) {\n // If GC is disabled, skip setting wip used routes since we should not track GC state.\n if (!this.gcDisabled) {\n assert(\n this.wipSerializedUsedRoutes === undefined,\n \"We should not already be tracking used routes when to track a new summary\");\n\n // back-compat: 0.33 - This will be done in `updateUsedRoutes`. Older clients do not have that method, so\n // keeping this one for now.\n this.wipSerializedUsedRoutes = JSON.stringify(this.usedRoutes);\n }\n super.startSummary(referenceSequenceNumber, summaryLogger);\n }\n\n /**\n * Called after summary has been uploaded to the server. Add the work-in-progress state to the pending\n * summary queue. We track this until we get an ack from the server for this summary.\n */\n protected completeSummaryCore(\n proposalHandle: string,\n parentPath: EscapedPath | undefined,\n parentSkipRecursion: boolean,\n ) {\n let wipSerializedUsedRoutes: string | undefined;\n // If GC is disabled, don't set wip used routes.\n if (!this.gcDisabled) {\n wipSerializedUsedRoutes = this.wipSerializedUsedRoutes;\n assert(wipSerializedUsedRoutes !== undefined, \"We should have been tracking used routes\");\n }\n\n super.completeSummaryCore(proposalHandle, parentPath, parentSkipRecursion);\n\n // If GC is disabled, skip setting pending summary with GC state.\n if (!this.gcDisabled) {\n const summaryNode = this.pendingSummaries.get(proposalHandle);\n if (summaryNode !== undefined) {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const summaryNodeWithGC = new SummaryNodeWithGC(wipSerializedUsedRoutes!, summaryNode);\n this.pendingSummaries.set(proposalHandle, summaryNodeWithGC);\n }\n }\n }\n\n /**\n * Clears the work-in-progress state.\n */\n public clearSummary() {\n this.wipSerializedUsedRoutes = undefined;\n super.clearSummary();\n }\n\n /**\n * Called when we get an ack from the server for a summary we sent. Update the reference state of this node\n * from the state in the pending summary queue.\n */\n protected refreshLatestSummaryFromPending(\n proposalHandle: string,\n referenceSequenceNumber: number,\n ): void {\n // If GC is disabled, skip setting referenced used routes since we are not tracking GC state.\n if (!this.gcDisabled) {\n const summaryNode = this.pendingSummaries.get(proposalHandle) as SummaryNodeWithGC;\n if (summaryNode !== undefined) {\n this.referenceUsedRoutes = JSON.parse(summaryNode.serializedUsedRoutes);\n }\n }\n\n return super.refreshLatestSummaryFromPending(proposalHandle, referenceSequenceNumber);\n }\n\n /**\n * Called when we need to upload the reference state from the given summary. Read the GC blob and get the state\n * to upload from it.\n */\n protected async refreshLatestSummaryFromSnapshot(\n referenceSequenceNumber: number,\n snapshotTree: ISnapshotTree,\n basePath: EscapedPath | undefined,\n localPath: EscapedPath,\n correlatedSummaryLogger: ITelemetryLogger,\n readAndParseBlob: ReadAndParseBlob,\n ): Promise<void> {\n // If GC is disabled, skip setting referenced used routes since we are not tracking GC state.\n if (!this.gcDisabled) {\n const gcDetailsBlob = snapshotTree.blobs[gcBlobKey];\n if (gcDetailsBlob !== undefined) {\n const gcDetails = await readAndParseBlob<IGarbageCollectionSummaryDetails>(gcDetailsBlob);\n\n // Possible re-entrancy. If we have already seen a summary later than this one, ignore it.\n if (this.referenceSequenceNumber >= referenceSequenceNumber) {\n return;\n }\n\n this.referenceUsedRoutes = gcDetails.usedRoutes;\n }\n }\n\n return super.refreshLatestSummaryFromSnapshot(\n referenceSequenceNumber,\n snapshotTree,\n basePath,\n localPath,\n correlatedSummaryLogger,\n readAndParseBlob,\n );\n }\n\n /**\n * Override the createChild method to return an instance of SummarizerNodeWithGC.\n */\n public createChild(\n /** Summarize function */\n summarizeInternalFn: (fullTree: boolean, trackState: boolean) => Promise<ISummarizeInternalResult>,\n /** Initial id or path part of this node */\n id: string,\n /**\n * Information needed to create the node.\n * If it is from a base summary, it will assert that a summary has been seen.\n * Attach information if it is created from an attach op.\n */\n createParam: CreateChildSummarizerNodeParam,\n config: ISummarizerNodeConfigWithGC = {},\n getGCDataFn?: (fullGC?: boolean) => Promise<IGarbageCollectionData>,\n getInitialGCSummaryDetailsFn?: () => Promise<IGarbageCollectionSummaryDetails>,\n ): ISummarizerNodeWithGC {\n assert(!this.children.has(id), \"Create SummarizerNode child already exists\");\n\n const createDetails: ICreateChildDetails = this.getCreateDetailsForChild(id, createParam);\n const child = new SummarizerNodeWithGC(\n this.defaultLogger,\n summarizeInternalFn,\n {\n ...config,\n // Propagate our gcDisabled state to the child if its not explicity specified in child's config.\n gcDisabled: config.gcDisabled ?? this.gcDisabled,\n },\n createDetails.changeSequenceNumber,\n createDetails.latestSummary,\n createDetails.initialSummary,\n this.wipSummaryLogger,\n getGCDataFn,\n getInitialGCSummaryDetailsFn,\n );\n\n // back-compat: 0.33 - If a child is created during summarize, its wip used routes will updated in\n // `updateUsedRoutes` method. For older clients, do it here since that method does not exist.\n\n // There may be additional state that has to be updated in this child. For example, if a summary is being\n // tracked, the child's summary tracking state needs to be updated too.\n this.maybeUpdateChildState(child);\n\n this.children.set(id, child);\n return child;\n }\n\n /**\n * Override the getChild method to return an instance of SummarizerNodeWithGC.\n */\n public getChild(id: string): ISummarizerNodeWithGC | undefined {\n return this.children.get(id) as SummarizerNodeWithGC;\n }\n\n public isReferenced(): boolean {\n return this.usedRoutes.includes(\"\") || this.usedRoutes.includes(\"/\");\n }\n\n public updateUsedRoutes(usedRoutes: string[]) {\n // Sort the given routes before updating. This will ensure that the routes compared in hasUsedStateChanged()\n // are in the same order.\n this._usedRoutes = usedRoutes.sort();\n\n // If GC is not disabled and we are tracking a summary, update the work-in-progress used routes so that it can\n // be tracked for this summary.\n if (!this.gcDisabled && this.isTrackingInProgress()) {\n this.wipSerializedUsedRoutes = JSON.stringify(this.usedRoutes);\n }\n }\n\n /**\n * Override the hasChanged method. If this node data or its used state changed, the node is considered changed.\n */\n protected hasChanged(): boolean {\n return this.hasDataChanged() || this.hasUsedStateChanged();\n }\n\n /**\n * This tells whether the data in this node has changed or not.\n */\n private hasDataChanged(): boolean {\n return super.hasChanged();\n }\n\n /**\n * This tells whether the used state of this node has changed since last successful summary. If the used routes\n * of this node changed, its used state is considered changed. Basically, if this node or any of its child nodes\n * was previously used and became unused (or vice versa), its used state has changed.\n */\n private hasUsedStateChanged(): boolean {\n // If GC is disabled, we are not tracking used state, return false.\n if (this.gcDisabled) {\n return false;\n }\n\n return this.referenceUsedRoutes === undefined ||\n JSON.stringify(this.usedRoutes) !== JSON.stringify(this.referenceUsedRoutes);\n }\n\n /**\n * Updates the work-in-progress state of the child if summary is in progress.\n * @param child - The child node to be updated.\n */\n protected maybeUpdateChildState(child: SummarizerNodeWithGC) {\n if (this.isTrackingInProgress()) {\n // Update the child's work-in-progress used routes.\n child.updateUsedRoutes(child.usedRoutes);\n }\n super.maybeUpdateChildState(child);\n }\n}\n\n/**\n * Creates a root summarizer node with GC functionality built-in.\n * @param logger - Logger to use within SummarizerNode\n * @param summarizeInternalFn - Function to generate summary\n * @param changeSequenceNumber - Sequence number of latest change to new node/subtree\n * @param referenceSequenceNumber - Reference sequence number of last acked summary,\n * or undefined if not loaded from summary\n * @param config - Configure behavior of summarizer node\n * @param getGCDataFn - Function to get the GC data of this node\n * @param gcDetailsInInitialSummaryP - Function to get the initial GC details of this node\n */\nexport const createRootSummarizerNodeWithGC = (\n logger: ITelemetryLogger,\n summarizeInternalFn: (fullTree: boolean, trackState: boolean) => Promise<ISummarizeInternalResult>,\n changeSequenceNumber: number,\n referenceSequenceNumber: number | undefined,\n config: ISummarizerNodeConfigWithGC = {},\n getGCDataFn?: (fullGC?: boolean) => Promise<IGarbageCollectionData>,\n getInitialGCSummaryDetailsFn?: () => Promise<IGarbageCollectionSummaryDetails>,\n): IRootSummarizerNodeWithGC => new SummarizerNodeWithGC(\n logger,\n summarizeInternalFn,\n config,\n changeSequenceNumber,\n referenceSequenceNumber === undefined ? undefined : SummaryNode.createForRoot(referenceSequenceNumber),\n undefined /* initialSummary */,\n undefined /* wipSummaryLogger */,\n getGCDataFn,\n getInitialGCSummaryDetailsFn,\n);\n"]} | ||
| {"version":3,"file":"summarizerNodeWithGc.js","sourceRoot":"","sources":["../../src/summarizerNode/summarizerNodeWithGc.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { ITelemetryLogger } from \"@fluidframework/common-definitions\";\nimport { assert, LazyPromise } from \"@fluidframework/common-utils\";\nimport { cloneGCData } from \"@fluidframework/garbage-collector\";\nimport { ISnapshotTree } from \"@fluidframework/protocol-definitions\";\nimport {\n CreateChildSummarizerNodeParam,\n gcBlobKey,\n IContextSummarizeResult,\n IGarbageCollectionData,\n IGarbageCollectionSummaryDetails,\n ISummarizeInternalResult,\n ISummarizerNodeConfigWithGC,\n ISummarizerNodeWithGC,\n} from \"@fluidframework/runtime-definitions\";\nimport { SummarizerNode } from \"./summarizerNode\";\nimport {\n EscapedPath,\n ICreateChildDetails,\n IInitialSummary,\n ISummarizerNodeRootContract,\n ReadAndParseBlob,\n SummaryNode,\n} from \"./summarizerNodeUtils\";\n\nexport interface IRootSummarizerNodeWithGC extends ISummarizerNodeWithGC, ISummarizerNodeRootContract {}\n\n// Extend SummaryNode to add used routes tracking to it.\nclass SummaryNodeWithGC extends SummaryNode {\n constructor(\n public readonly serializedUsedRoutes: string,\n summary: {\n readonly referenceSequenceNumber: number,\n readonly basePath: EscapedPath | undefined,\n readonly localPath: EscapedPath,\n additionalPath?: EscapedPath,\n },\n ) {\n super(summary);\n }\n}\n\n/**\n * Extends the functionality of SummarizerNode to manage this node's garbage collection data:\n * - Adds a new API `getGCData` to return GC data of this node.\n * - Caches the result of `getGCData` to be used if nothing changes between summaries.\n * - Adds GC data to the result of summarize.\n * - Manages the used routes of this node. These are used to identify if this node is referenced in the document\n * and to determine if the node's used state changed since last summary.\n * - Adds trackState param to summarize. If trackState is false, it bypasses the SummarizerNode and calls\n * directly into summarizeInternal method.\n */\nexport class SummarizerNodeWithGC extends SummarizerNode implements IRootSummarizerNodeWithGC {\n private gcData: IGarbageCollectionData | undefined;\n\n // Tracks the work-in-progress used routes during summary.\n private wipSerializedUsedRoutes: string | undefined;\n\n // This is the last known used routes of this node as seen by the server as part of a summary.\n private referenceUsedRoutes: string[] | undefined;\n\n // The GC details of this node in the initial summary.\n private readonly gcDetailsInInitialSummaryP: LazyPromise<IGarbageCollectionSummaryDetails>;\n\n // Set used routes to have self route by default. This makes the node referenced by default. This is done to ensure\n // that this node is not marked as collected when running GC has been disabled. Once, the option to disable GC is\n // removed (from runGC flag in IContainerRuntimeOptions), this should be changed to be have no routes by default.\n private _usedRoutes: string[] = [\"\"];\n public get usedRoutes(): string[] {\n return this._usedRoutes;\n }\n\n // True if GC is disabled for this node. If so, do not track GC specific state for a summary.\n private readonly gcDisabled: boolean;\n\n /**\n * Do not call constructor directly.\n * Use createRootSummarizerNodeWithGC to create root node, or createChild to create child nodes.\n */\n public constructor(\n logger: ITelemetryLogger,\n private readonly summarizeFn: (fullTree: boolean, trackState: boolean) => Promise<ISummarizeInternalResult>,\n config: ISummarizerNodeConfigWithGC,\n changeSequenceNumber: number,\n /** Undefined means created without summary */\n latestSummary?: SummaryNode,\n initialSummary?: IInitialSummary,\n wipSummaryLogger?: ITelemetryLogger,\n private readonly getGCDataFn?: (fullGC?: boolean) => Promise<IGarbageCollectionData>,\n getInitialGCSummaryDetailsFn?: () => Promise<IGarbageCollectionSummaryDetails>,\n ) {\n super(\n logger,\n async (fullTree: boolean) => this.summarizeInternal(fullTree, true /* trackState */),\n config,\n changeSequenceNumber,\n latestSummary,\n initialSummary,\n wipSummaryLogger,\n );\n\n this.gcDisabled = config.gcDisabled === true;\n\n this.gcDetailsInInitialSummaryP = new LazyPromise(async () => {\n // back-compat: 0.32. getInitialGCSummaryDetailsFn() returns undefined in 0.31. Remove undefined check\n // when N > 34.\n const gcSummaryDetails = await getInitialGCSummaryDetailsFn?.();\n return gcSummaryDetails ?? { usedRoutes: [] };\n });\n }\n\n /**\n * Loads state from this node's initial GC summary details. This contains the following data from the last summary\n * seen by the server for this client:\n * - usedRoutes: This is used to figure out if the used state of this node changed since last summary.\n * - gcData: The garbage collection data of this node that is required for running GC.\n */\n private async loadInitialGCSummaryDetails() {\n // If referenceUsedRoutes is not undefined, don't do anything because we have already initialized.\n if (this.referenceUsedRoutes === undefined) {\n const gcDetailsInInitialSummary = await this.gcDetailsInInitialSummaryP;\n this.referenceUsedRoutes = gcDetailsInInitialSummary.usedRoutes;\n\n // If the GC details has GC data, initialize our GC data from it.\n if (gcDetailsInInitialSummary.gcData !== undefined) {\n this.gcData = cloneGCData(gcDetailsInInitialSummary.gcData);\n }\n }\n }\n\n public async summarize(fullTree: boolean, trackState: boolean = true): Promise<IContextSummarizeResult> {\n // Load GC details from the initial summary, if it's not already loaded. If this is the first time this node is\n // being summarized, the used routes in it are needed to find out if this node has changed since last summary.\n // If it hasn't changed, the GC data in it needs to be returned as part of the summary.\n await this.loadInitialGCSummaryDetails();\n\n // If GC is not disabled and we are tracking a summary, GC should have run and updated the used routes for this\n // summary by calling updateUsedRoutes which sets wipSerializedUsedRoutes.\n if (!this.gcDisabled && this.isTrackingInProgress()) {\n assert(this.wipSerializedUsedRoutes !== undefined,\n 0x1b1 /* \"wip used routes should be set if tracking a summary\" */);\n }\n\n // If trackState is true, get summary from base summarizer node which tracks summary state.\n // If trackState is false, get summary from summarizeInternal.\n if (trackState) {\n const summarizeResult = await super.summarize(fullTree);\n\n // If there is no cached GC data, return empty data in summarize result. It is the caller's responsibility\n // to ensure that GC data is available by calling getGCData before calling summarize.\n const gcData = this.gcData !== undefined ? cloneGCData(this.gcData) : { gcNodes: {} };\n\n return {\n ...summarizeResult,\n gcData,\n };\n } else {\n return this.summarizeInternal(fullTree, trackState);\n }\n }\n\n private async summarizeInternal(fullTree: boolean, trackState: boolean): Promise<ISummarizeInternalResult> {\n const summarizeResult = await this.summarizeFn(fullTree, trackState);\n this.gcData = cloneGCData(summarizeResult.gcData);\n return summarizeResult;\n }\n\n /**\n * Returns the GC data of this node. If nothing has changed since last summary, it tries to reuse the data from\n * the previous summary. Else, it gets new GC data from the underlying Fluid object.\n * @param fullGC - true to bypass optimizations and force full generation of GC data.\n */\n public async getGCData(fullGC: boolean = false): Promise<IGarbageCollectionData> {\n assert(!this.gcDisabled, 0x1b2 /* \"Getting GC data should not be called when GC is disabled!\" */);\n assert(this.getGCDataFn !== undefined, 0x1b3 /* \"GC data cannot be retrieved without getGCDataFn\" */);\n\n // Load GC details from the initial summary, if not already loaded. If this is the first time this function is\n // called and the node's data has not changed since last summary, the GC data in initial details is returned.\n await this.loadInitialGCSummaryDetails();\n\n // If there is no new data since last summary and we have GC data from the previous run, return it. We may not\n // have data from previous GC run for clients with older summary format before GC was added. They won't have\n // GC details in their initial summary.\n if (!fullGC && !this.hasDataChanged() && this.gcData !== undefined) {\n return cloneGCData(this.gcData);\n }\n\n const gcData = await this.getGCDataFn(fullGC);\n this.gcData = cloneGCData(gcData);\n return gcData;\n }\n\n /**\n * Called during the start of a summary. Updates the work-in-progress used routes.\n */\n public startSummary(referenceSequenceNumber: number, summaryLogger: ITelemetryLogger) {\n // If GC is disabled, skip setting wip used routes since we should not track GC state.\n if (!this.gcDisabled) {\n assert(\n this.wipSerializedUsedRoutes === undefined,\n 0x1b4 /* \"We should not already be tracking used routes when to track a new summary\" */);\n\n // back-compat: 0.33 - This will be done in `updateUsedRoutes`. Older clients do not have that method, so\n // keeping this one for now.\n this.wipSerializedUsedRoutes = JSON.stringify(this.usedRoutes);\n }\n super.startSummary(referenceSequenceNumber, summaryLogger);\n }\n\n /**\n * Called after summary has been uploaded to the server. Add the work-in-progress state to the pending\n * summary queue. We track this until we get an ack from the server for this summary.\n */\n protected completeSummaryCore(\n proposalHandle: string,\n parentPath: EscapedPath | undefined,\n parentSkipRecursion: boolean,\n ) {\n let wipSerializedUsedRoutes: string | undefined;\n // If GC is disabled, don't set wip used routes.\n if (!this.gcDisabled) {\n wipSerializedUsedRoutes = this.wipSerializedUsedRoutes;\n assert(wipSerializedUsedRoutes !== undefined, 0x1b5 /* \"We should have been tracking used routes\" */);\n }\n\n super.completeSummaryCore(proposalHandle, parentPath, parentSkipRecursion);\n\n // If GC is disabled, skip setting pending summary with GC state.\n if (!this.gcDisabled) {\n const summaryNode = this.pendingSummaries.get(proposalHandle);\n if (summaryNode !== undefined) {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const summaryNodeWithGC = new SummaryNodeWithGC(wipSerializedUsedRoutes!, summaryNode);\n this.pendingSummaries.set(proposalHandle, summaryNodeWithGC);\n }\n }\n }\n\n /**\n * Clears the work-in-progress state.\n */\n public clearSummary() {\n this.wipSerializedUsedRoutes = undefined;\n super.clearSummary();\n }\n\n /**\n * Called when we get an ack from the server for a summary we sent. Update the reference state of this node\n * from the state in the pending summary queue.\n */\n protected refreshLatestSummaryFromPending(\n proposalHandle: string,\n referenceSequenceNumber: number,\n ): void {\n // If GC is disabled, skip setting referenced used routes since we are not tracking GC state.\n if (!this.gcDisabled) {\n const summaryNode = this.pendingSummaries.get(proposalHandle) as SummaryNodeWithGC;\n if (summaryNode !== undefined) {\n this.referenceUsedRoutes = JSON.parse(summaryNode.serializedUsedRoutes);\n }\n }\n\n return super.refreshLatestSummaryFromPending(proposalHandle, referenceSequenceNumber);\n }\n\n /**\n * Called when we need to upload the reference state from the given summary. Read the GC blob and get the state\n * to upload from it.\n */\n protected async refreshLatestSummaryFromSnapshot(\n referenceSequenceNumber: number,\n snapshotTree: ISnapshotTree,\n basePath: EscapedPath | undefined,\n localPath: EscapedPath,\n correlatedSummaryLogger: ITelemetryLogger,\n readAndParseBlob: ReadAndParseBlob,\n ): Promise<void> {\n // If GC is disabled, skip setting referenced used routes since we are not tracking GC state.\n if (!this.gcDisabled) {\n const gcDetailsBlob = snapshotTree.blobs[gcBlobKey];\n if (gcDetailsBlob !== undefined) {\n const gcDetails = await readAndParseBlob<IGarbageCollectionSummaryDetails>(gcDetailsBlob);\n\n // Possible re-entrancy. If we have already seen a summary later than this one, ignore it.\n if (this.referenceSequenceNumber >= referenceSequenceNumber) {\n return;\n }\n\n this.referenceUsedRoutes = gcDetails.usedRoutes;\n }\n }\n\n return super.refreshLatestSummaryFromSnapshot(\n referenceSequenceNumber,\n snapshotTree,\n basePath,\n localPath,\n correlatedSummaryLogger,\n readAndParseBlob,\n );\n }\n\n /**\n * Override the createChild method to return an instance of SummarizerNodeWithGC.\n */\n public createChild(\n /** Summarize function */\n summarizeInternalFn: (fullTree: boolean, trackState: boolean) => Promise<ISummarizeInternalResult>,\n /** Initial id or path part of this node */\n id: string,\n /**\n * Information needed to create the node.\n * If it is from a base summary, it will assert that a summary has been seen.\n * Attach information if it is created from an attach op.\n */\n createParam: CreateChildSummarizerNodeParam,\n config: ISummarizerNodeConfigWithGC = {},\n getGCDataFn?: (fullGC?: boolean) => Promise<IGarbageCollectionData>,\n getInitialGCSummaryDetailsFn?: () => Promise<IGarbageCollectionSummaryDetails>,\n ): ISummarizerNodeWithGC {\n assert(!this.children.has(id), 0x1b6 /* \"Create SummarizerNode child already exists\" */);\n\n const createDetails: ICreateChildDetails = this.getCreateDetailsForChild(id, createParam);\n const child = new SummarizerNodeWithGC(\n this.defaultLogger,\n summarizeInternalFn,\n {\n ...config,\n // Propagate our gcDisabled state to the child if its not explicity specified in child's config.\n gcDisabled: config.gcDisabled ?? this.gcDisabled,\n },\n createDetails.changeSequenceNumber,\n createDetails.latestSummary,\n createDetails.initialSummary,\n this.wipSummaryLogger,\n getGCDataFn,\n getInitialGCSummaryDetailsFn,\n );\n\n // back-compat: 0.33 - If a child is created during summarize, its wip used routes will updated in\n // `updateUsedRoutes` method. For older clients, do it here since that method does not exist.\n\n // There may be additional state that has to be updated in this child. For example, if a summary is being\n // tracked, the child's summary tracking state needs to be updated too.\n this.maybeUpdateChildState(child);\n\n this.children.set(id, child);\n return child;\n }\n\n /**\n * Override the getChild method to return an instance of SummarizerNodeWithGC.\n */\n public getChild(id: string): ISummarizerNodeWithGC | undefined {\n return this.children.get(id) as SummarizerNodeWithGC;\n }\n\n public isReferenced(): boolean {\n return this.usedRoutes.includes(\"\") || this.usedRoutes.includes(\"/\");\n }\n\n public updateUsedRoutes(usedRoutes: string[]) {\n // Sort the given routes before updating. This will ensure that the routes compared in hasUsedStateChanged()\n // are in the same order.\n this._usedRoutes = usedRoutes.sort();\n\n // If GC is not disabled and we are tracking a summary, update the work-in-progress used routes so that it can\n // be tracked for this summary.\n if (!this.gcDisabled && this.isTrackingInProgress()) {\n this.wipSerializedUsedRoutes = JSON.stringify(this.usedRoutes);\n }\n }\n\n /**\n * Override the hasChanged method. If this node data or its used state changed, the node is considered changed.\n */\n protected hasChanged(): boolean {\n return this.hasDataChanged() || this.hasUsedStateChanged();\n }\n\n /**\n * This tells whether the data in this node has changed or not.\n */\n private hasDataChanged(): boolean {\n return super.hasChanged();\n }\n\n /**\n * This tells whether the used state of this node has changed since last successful summary. If the used routes\n * of this node changed, its used state is considered changed. Basically, if this node or any of its child nodes\n * was previously used and became unused (or vice versa), its used state has changed.\n */\n private hasUsedStateChanged(): boolean {\n // If GC is disabled, we are not tracking used state, return false.\n if (this.gcDisabled) {\n return false;\n }\n\n return this.referenceUsedRoutes === undefined ||\n JSON.stringify(this.usedRoutes) !== JSON.stringify(this.referenceUsedRoutes);\n }\n\n /**\n * Updates the work-in-progress state of the child if summary is in progress.\n * @param child - The child node to be updated.\n */\n protected maybeUpdateChildState(child: SummarizerNodeWithGC) {\n if (this.isTrackingInProgress()) {\n // Update the child's work-in-progress used routes.\n child.updateUsedRoutes(child.usedRoutes);\n }\n super.maybeUpdateChildState(child);\n }\n}\n\n/**\n * Creates a root summarizer node with GC functionality built-in.\n * @param logger - Logger to use within SummarizerNode\n * @param summarizeInternalFn - Function to generate summary\n * @param changeSequenceNumber - Sequence number of latest change to new node/subtree\n * @param referenceSequenceNumber - Reference sequence number of last acked summary,\n * or undefined if not loaded from summary\n * @param config - Configure behavior of summarizer node\n * @param getGCDataFn - Function to get the GC data of this node\n * @param gcDetailsInInitialSummaryP - Function to get the initial GC details of this node\n */\nexport const createRootSummarizerNodeWithGC = (\n logger: ITelemetryLogger,\n summarizeInternalFn: (fullTree: boolean, trackState: boolean) => Promise<ISummarizeInternalResult>,\n changeSequenceNumber: number,\n referenceSequenceNumber: number | undefined,\n config: ISummarizerNodeConfigWithGC = {},\n getGCDataFn?: (fullGC?: boolean) => Promise<IGarbageCollectionData>,\n getInitialGCSummaryDetailsFn?: () => Promise<IGarbageCollectionSummaryDetails>,\n): IRootSummarizerNodeWithGC => new SummarizerNodeWithGC(\n logger,\n summarizeInternalFn,\n config,\n changeSequenceNumber,\n referenceSequenceNumber === undefined ? undefined : SummaryNode.createForRoot(referenceSequenceNumber),\n undefined /* initialSummary */,\n undefined /* wipSummaryLogger */,\n getGCDataFn,\n getInitialGCSummaryDetailsFn,\n);\n"]} |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"summaryUtils.d.ts","sourceRoot":"","sources":["../src/summaryUtils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAWH,OAAO,EACH,KAAK,EACL,WAAW,EACX,YAAY,EAEZ,YAAY,EAGZ,aAAa,EAChB,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,qCAAqC,CAAC;AAE7G;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,GAAG,KAAK,EAAE,aAAa,EAAE,GAAG,aAAa,CAcnE;AAED,wBAAgB,WAAW,CAAC,OAAO,EAAE,YAAY,CAAC,SAAS,CAAC,GAAG,MAAM,CAMpE;AAwBD,wBAAgB,cAAc,CAAC,OAAO,EAAE,YAAY,GAAG,aAAa,CAInE;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,qBAAqB,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CAQhH;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,qBAAqB,EAAE,GAAG,EAAE,MAAM,EAAE,eAAe,EAAE,gBAAgB,GAAG,IAAI,CAGrH;AAED,qBAAa,kBAAmB,YAAW,qBAAqB;IAC5D,OAAO,CAAC,iBAAiB,CAAa;IAEtC,IAAW,OAAO,IAAI,YAAY,CAKjC;IAED,IAAW,KAAK,IAAI,QAAQ,CAAC,aAAa,CAAC,CAE1C;;IAOD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAyC;IACrE,OAAO,CAAC,YAAY,CAAgB;IAE7B,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI;IAWxD,SAAS,CACZ,GAAG,EAAE,MAAM,EACX,UAAU,EAAE,WAAW,CAAC,IAAI,GAAG,WAAW,CAAC,IAAI,GAAG,WAAW,CAAC,UAAU,EACxE,MAAM,EAAE,MAAM,GAAG,IAAI;IAUlB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,eAAe,EAAE,gBAAgB,GAAG,IAAI;IAKlE,aAAa,CAAC,EAAE,EAAE,MAAM;IAIxB,cAAc,IAAI,qBAAqB;CAGjD;AAED;;;;GAIG;AACH,wBAAgB,6BAA6B,CACzC,QAAQ,EAAE,KAAK,EACf,QAAQ,GAAE,OAAe,GAC1B,qBAAqB,CAyCvB;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAChC,QAAQ,EAAE,KAAK,EACf,QAAQ,GAAE,OAAe,GAC1B,gBAAgB,CAgBlB;AAED;;;;GAIG;AACH,wBAAgB,gCAAgC,CAC5C,QAAQ,EAAE,aAAa,GACxB,qBAAqB,CAkBvB;AAED;;;;GAIG;AACH,wBAAgB,wCAAwC,CACpD,sBAAsB,EAAE,MAAM,GAC/B,YAAY,CAiBd;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,CAAC,WAAW,EAAE,YAAY,GAAG,KAAK,CAsC1E"} | ||
| {"version":3,"file":"summaryUtils.d.ts","sourceRoot":"","sources":["../src/summaryUtils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAWH,OAAO,EACH,KAAK,EACL,WAAW,EACX,YAAY,EAEZ,YAAY,EAGZ,aAAa,EAChB,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,qCAAqC,CAAC;AAE7G;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,GAAG,KAAK,EAAE,aAAa,EAAE,GAAG,aAAa,CAcnE;AAED,wBAAgB,WAAW,CAAC,OAAO,EAAE,YAAY,CAAC,SAAS,CAAC,GAAG,MAAM,CAMpE;AAwBD,wBAAgB,cAAc,CAAC,OAAO,EAAE,YAAY,GAAG,aAAa,CAInE;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,qBAAqB,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CAQhH;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,qBAAqB,EAAE,GAAG,EAAE,MAAM,EAAE,eAAe,EAAE,gBAAgB,GAAG,IAAI,CAGrH;AAED,qBAAa,kBAAmB,YAAW,qBAAqB;IAC5D,OAAO,CAAC,iBAAiB,CAAa;IAEtC,IAAW,OAAO,IAAI,YAAY,CAKjC;IAED,IAAW,KAAK,IAAI,QAAQ,CAAC,aAAa,CAAC,CAE1C;;IAOD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAyC;IACrE,OAAO,CAAC,YAAY,CAAgB;IAE7B,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI;IAWxD,SAAS,CACZ,GAAG,EAAE,MAAM,EACX,UAAU,EAAE,WAAW,CAAC,IAAI,GAAG,WAAW,CAAC,IAAI,GAAG,WAAW,CAAC,UAAU,EACxE,MAAM,EAAE,MAAM,GAAG,IAAI;IAUlB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,eAAe,EAAE,gBAAgB,GAAG,IAAI;IAKlE,aAAa,CAAC,EAAE,EAAE,MAAM;IAIxB,cAAc,IAAI,qBAAqB;CAGjD;AAED;;;;GAIG;AACH,wBAAgB,6BAA6B,CACzC,QAAQ,EAAE,KAAK,EACf,QAAQ,GAAE,OAAe,GAC1B,qBAAqB,CAyCvB;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAChC,QAAQ,EAAE,KAAK,EACf,QAAQ,GAAE,OAAe,GAC1B,gBAAgB,CAgBlB;AAED;;;;GAIG;AACH,wBAAgB,gCAAgC,CAC5C,QAAQ,EAAE,aAAa,GACxB,qBAAqB,CAmBvB;AAED;;;;GAIG;AACH,wBAAgB,wCAAwC,CACpD,sBAAsB,EAAE,MAAM,GAC/B,YAAY,CAiBd;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,CAAC,WAAW,EAAE,YAAY,GAAG,KAAK,CAsC1E"} |
@@ -188,3 +188,3 @@ /*! | ||
| export function convertSnapshotTreeToSummaryTree(snapshot) { | ||
| assert(Object.keys(snapshot.commits).length === 0, "There should not be commit tree entries in snapshot"); | ||
| assert(Object.keys(snapshot.commits).length === 0, 0x19e /* "There should not be commit tree entries in snapshot" */); | ||
| const builder = new SummaryTreeBuilder(); | ||
@@ -191,0 +191,0 @@ for (const [key, value] of Object.entries(snapshot.blobs)) { |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"summaryUtils.js","sourceRoot":"","sources":["../src/summaryUtils.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport {\n assert,\n fromBase64ToUtf8,\n IsoBuffer,\n Uint8ArrayToString,\n unreachableCase,\n stringToBuffer,\n} from \"@fluidframework/common-utils\";\nimport { AttachmentTreeEntry, BlobTreeEntry, TreeTreeEntry } from \"@fluidframework/protocol-base\";\nimport {\n ITree,\n SummaryType,\n ISummaryTree,\n SummaryObject,\n ISummaryBlob,\n TreeEntry,\n ITreeEntry,\n ISnapshotTree,\n} from \"@fluidframework/protocol-definitions\";\nimport { ISummaryStats, ISummarizeResult, ISummaryTreeWithStats } from \"@fluidframework/runtime-definitions\";\n\n/**\n * Combines summary stats by adding their totals together.\n * Returns empty stats if called without args.\n * @param stats - stats to merge\n */\nexport function mergeStats(...stats: ISummaryStats[]): ISummaryStats {\n const results = {\n treeNodeCount: 0,\n blobNodeCount: 0,\n handleNodeCount: 0,\n totalBlobSize: 0,\n };\n for (const stat of stats) {\n results.treeNodeCount += stat.treeNodeCount;\n results.blobNodeCount += stat.blobNodeCount;\n results.handleNodeCount += stat.handleNodeCount;\n results.totalBlobSize += stat.totalBlobSize;\n }\n return results;\n}\n\nexport function getBlobSize(content: ISummaryBlob[\"content\"]): number {\n if (typeof content === \"string\") {\n return stringToBuffer(content, \"utf8\").byteLength;\n } else {\n return content.byteLength;\n }\n}\n\nfunction calculateStatsCore(summaryObject: SummaryObject, stats: ISummaryStats): void {\n switch (summaryObject.type) {\n case SummaryType.Tree: {\n stats.treeNodeCount++;\n for (const value of Object.values(summaryObject.tree)) {\n calculateStatsCore(value, stats);\n }\n return;\n }\n case SummaryType.Handle: {\n stats.handleNodeCount++;\n return;\n }\n case SummaryType.Blob: {\n stats.blobNodeCount++;\n stats.totalBlobSize += getBlobSize(summaryObject.content);\n return;\n }\n default: return;\n }\n}\n\nexport function calculateStats(summary: ISummaryTree): ISummaryStats {\n const stats = mergeStats();\n calculateStatsCore(summary, stats);\n return stats;\n}\n\nexport function addBlobToSummary(summary: ISummaryTreeWithStats, key: string, content: string | Uint8Array): void {\n const blob: ISummaryBlob = {\n type: SummaryType.Blob,\n content,\n };\n summary.summary.tree[key] = blob;\n summary.stats.blobNodeCount++;\n summary.stats.totalBlobSize += getBlobSize(content);\n}\n\nexport function addTreeToSummary(summary: ISummaryTreeWithStats, key: string, summarizeResult: ISummarizeResult): void {\n summary.summary.tree[key] = summarizeResult.summary;\n summary.stats = mergeStats(summary.stats, summarizeResult.stats);\n}\n\nexport class SummaryTreeBuilder implements ISummaryTreeWithStats {\n private attachmentCounter: number = 0;\n\n public get summary(): ISummaryTree {\n return {\n type: SummaryType.Tree,\n tree: { ...this.summaryTree },\n };\n }\n\n public get stats(): Readonly<ISummaryStats> {\n return { ...this.summaryStats };\n }\n\n constructor() {\n this.summaryStats = mergeStats();\n this.summaryStats.treeNodeCount++;\n }\n\n private readonly summaryTree: { [path: string]: SummaryObject } = {};\n private summaryStats: ISummaryStats;\n\n public addBlob(key: string, content: string | Uint8Array): void {\n // Prevent cloning by directly referencing underlying private properties\n addBlobToSummary({\n summary: {\n type: SummaryType.Tree,\n tree: this.summaryTree,\n },\n stats: this.summaryStats,\n }, key, content);\n }\n\n public addHandle(\n key: string,\n handleType: SummaryType.Tree | SummaryType.Blob | SummaryType.Attachment,\n handle: string): void\n {\n this.summaryTree[key] = {\n type: SummaryType.Handle,\n handleType,\n handle,\n };\n this.summaryStats.handleNodeCount++;\n }\n\n public addWithStats(key: string, summarizeResult: ISummarizeResult): void {\n this.summaryTree[key] = summarizeResult.summary;\n this.summaryStats = mergeStats(this.summaryStats, summarizeResult.stats);\n }\n\n public addAttachment(id: string) {\n this.summaryTree[this.attachmentCounter++] = { id, type: SummaryType.Attachment };\n }\n\n public getSummaryTree(): ISummaryTreeWithStats {\n return { summary: this.summary, stats: this.stats };\n }\n}\n\n/**\n * Converts snapshot ITree to ISummaryTree format and tracks stats.\n * @param snapshot - snapshot in ITree format\n * @param fullTree - true to never use handles, even if id is specified\n */\nexport function convertToSummaryTreeWithStats(\n snapshot: ITree,\n fullTree: boolean = false,\n): ISummaryTreeWithStats {\n const builder = new SummaryTreeBuilder();\n for (const entry of snapshot.entries) {\n switch (entry.type) {\n case TreeEntry.Blob: {\n const blob = entry.value;\n let content: string | Uint8Array;\n if (blob.encoding === \"base64\") {\n content = IsoBuffer.from(blob.contents, \"base64\");\n } else {\n content = blob.contents;\n }\n builder.addBlob(entry.path, content);\n break;\n }\n\n case TreeEntry.Tree: {\n const subtree = convertToSummaryTree(\n entry.value,\n fullTree);\n builder.addWithStats(entry.path, subtree);\n\n break;\n }\n\n case TreeEntry.Attachment: {\n const id = entry.value.id;\n builder.addAttachment(id);\n\n break;\n }\n\n case TreeEntry.Commit:\n throw new Error(\"Should not have Commit TreeEntry in summary\");\n\n default:\n throw new Error(\"Unexpected TreeEntry type\");\n }\n }\n\n return builder.getSummaryTree();\n}\n\n/**\n * Converts snapshot ITree to ISummaryTree format and tracks stats.\n * @param snapshot - snapshot in ITree format\n * @param fullTree - true to never use handles, even if id is specified\n */\nexport function convertToSummaryTree(\n snapshot: ITree,\n fullTree: boolean = false,\n): ISummarizeResult {\n // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions\n if (snapshot.id && !fullTree) {\n const stats = mergeStats();\n stats.handleNodeCount++;\n return {\n summary: {\n handle: snapshot.id,\n handleType: SummaryType.Tree,\n type: SummaryType.Handle,\n },\n stats,\n };\n } else {\n return convertToSummaryTreeWithStats(snapshot, fullTree);\n }\n}\n\n/**\n * Converts ISnapshotTree to ISummaryTree format and tracks stats. This snapshot tree was\n * was taken by serialize api in detached container.\n * @param snapshot - snapshot in ISnapshotTree format\n */\nexport function convertSnapshotTreeToSummaryTree(\n snapshot: ISnapshotTree,\n): ISummaryTreeWithStats {\n assert(Object.keys(snapshot.commits).length === 0, \"There should not be commit tree entries in snapshot\");\n\n const builder = new SummaryTreeBuilder();\n for (const [key, value] of Object.entries(snapshot.blobs)) {\n // The entries in blobs are supposed to be blobPath -> blobId and blobId -> blobValue\n // and we want to push blobPath to blobValue in tree entries.\n if (snapshot.blobs[value] !== undefined) {\n const decoded = fromBase64ToUtf8(snapshot.blobs[value]);\n builder.addBlob(key, decoded);\n }\n }\n\n for (const [key, tree] of Object.entries(snapshot.trees)) {\n const subtree = convertSnapshotTreeToSummaryTree(tree);\n builder.addWithStats(key, subtree);\n }\n return builder.getSummaryTree();\n}\n\n/**\n * Utility to convert serialized snapshot taken in detached container to format where we can use it to\n * attach the container.\n * @param serializedSnapshotTree - serialized snapshot tree to be converted to summary tree for attach.\n */\nexport function convertContainerToDriverSerializedFormat(\n serializedSnapshotTree: string,\n): ISummaryTree {\n const snapshotTree: ISnapshotTree = JSON.parse(serializedSnapshotTree);\n const summaryTree = convertSnapshotTreeToSummaryTree(snapshotTree).summary;\n const appSummaryTree: ISummaryTree = {\n type: SummaryType.Tree,\n tree: {},\n };\n const entries = Object.entries(summaryTree.tree);\n for (const [key, subTree] of entries) {\n if (key !== \".protocol\") {\n appSummaryTree.tree[key] = subTree;\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n delete summaryTree.tree[key];\n }\n }\n summaryTree.tree[\".app\"] = appSummaryTree;\n return summaryTree;\n}\n\n/**\n * Converts ISummaryTree to ITree format. This is needed for back-compat while we get rid of snapshot.\n * @param summaryTree - summary tree in ISummaryTree format\n */\nexport function convertSummaryTreeToITree(summaryTree: ISummaryTree): ITree {\n const entries: ITreeEntry[] = [];\n for (const [key, value] of Object.entries(summaryTree.tree)) {\n switch (value.type) {\n case SummaryType.Blob: {\n let parsedContent: string;\n let encoding: string = \"utf-8\";\n if (typeof value.content === \"string\") {\n parsedContent = value.content;\n } else {\n parsedContent = Uint8ArrayToString(value.content, \"base64\");\n encoding = \"base64\";\n }\n entries.push(new BlobTreeEntry(key, parsedContent, encoding));\n break;\n }\n\n case SummaryType.Tree: {\n entries.push(new TreeTreeEntry(key, convertSummaryTreeToITree(value)));\n break;\n }\n\n case SummaryType.Attachment: {\n entries.push(new AttachmentTreeEntry(key, value.id));\n break;\n }\n\n case SummaryType.Handle: {\n throw new Error(\"Should not have Handle type in summary tree\");\n }\n\n default:\n unreachableCase(value, \"Unexpected summary tree type\");\n }\n }\n return {\n entries,\n };\n}\n"]} | ||
| {"version":3,"file":"summaryUtils.js","sourceRoot":"","sources":["../src/summaryUtils.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport {\n assert,\n fromBase64ToUtf8,\n IsoBuffer,\n Uint8ArrayToString,\n unreachableCase,\n stringToBuffer,\n} from \"@fluidframework/common-utils\";\nimport { AttachmentTreeEntry, BlobTreeEntry, TreeTreeEntry } from \"@fluidframework/protocol-base\";\nimport {\n ITree,\n SummaryType,\n ISummaryTree,\n SummaryObject,\n ISummaryBlob,\n TreeEntry,\n ITreeEntry,\n ISnapshotTree,\n} from \"@fluidframework/protocol-definitions\";\nimport { ISummaryStats, ISummarizeResult, ISummaryTreeWithStats } from \"@fluidframework/runtime-definitions\";\n\n/**\n * Combines summary stats by adding their totals together.\n * Returns empty stats if called without args.\n * @param stats - stats to merge\n */\nexport function mergeStats(...stats: ISummaryStats[]): ISummaryStats {\n const results = {\n treeNodeCount: 0,\n blobNodeCount: 0,\n handleNodeCount: 0,\n totalBlobSize: 0,\n };\n for (const stat of stats) {\n results.treeNodeCount += stat.treeNodeCount;\n results.blobNodeCount += stat.blobNodeCount;\n results.handleNodeCount += stat.handleNodeCount;\n results.totalBlobSize += stat.totalBlobSize;\n }\n return results;\n}\n\nexport function getBlobSize(content: ISummaryBlob[\"content\"]): number {\n if (typeof content === \"string\") {\n return stringToBuffer(content, \"utf8\").byteLength;\n } else {\n return content.byteLength;\n }\n}\n\nfunction calculateStatsCore(summaryObject: SummaryObject, stats: ISummaryStats): void {\n switch (summaryObject.type) {\n case SummaryType.Tree: {\n stats.treeNodeCount++;\n for (const value of Object.values(summaryObject.tree)) {\n calculateStatsCore(value, stats);\n }\n return;\n }\n case SummaryType.Handle: {\n stats.handleNodeCount++;\n return;\n }\n case SummaryType.Blob: {\n stats.blobNodeCount++;\n stats.totalBlobSize += getBlobSize(summaryObject.content);\n return;\n }\n default: return;\n }\n}\n\nexport function calculateStats(summary: ISummaryTree): ISummaryStats {\n const stats = mergeStats();\n calculateStatsCore(summary, stats);\n return stats;\n}\n\nexport function addBlobToSummary(summary: ISummaryTreeWithStats, key: string, content: string | Uint8Array): void {\n const blob: ISummaryBlob = {\n type: SummaryType.Blob,\n content,\n };\n summary.summary.tree[key] = blob;\n summary.stats.blobNodeCount++;\n summary.stats.totalBlobSize += getBlobSize(content);\n}\n\nexport function addTreeToSummary(summary: ISummaryTreeWithStats, key: string, summarizeResult: ISummarizeResult): void {\n summary.summary.tree[key] = summarizeResult.summary;\n summary.stats = mergeStats(summary.stats, summarizeResult.stats);\n}\n\nexport class SummaryTreeBuilder implements ISummaryTreeWithStats {\n private attachmentCounter: number = 0;\n\n public get summary(): ISummaryTree {\n return {\n type: SummaryType.Tree,\n tree: { ...this.summaryTree },\n };\n }\n\n public get stats(): Readonly<ISummaryStats> {\n return { ...this.summaryStats };\n }\n\n constructor() {\n this.summaryStats = mergeStats();\n this.summaryStats.treeNodeCount++;\n }\n\n private readonly summaryTree: { [path: string]: SummaryObject } = {};\n private summaryStats: ISummaryStats;\n\n public addBlob(key: string, content: string | Uint8Array): void {\n // Prevent cloning by directly referencing underlying private properties\n addBlobToSummary({\n summary: {\n type: SummaryType.Tree,\n tree: this.summaryTree,\n },\n stats: this.summaryStats,\n }, key, content);\n }\n\n public addHandle(\n key: string,\n handleType: SummaryType.Tree | SummaryType.Blob | SummaryType.Attachment,\n handle: string): void\n {\n this.summaryTree[key] = {\n type: SummaryType.Handle,\n handleType,\n handle,\n };\n this.summaryStats.handleNodeCount++;\n }\n\n public addWithStats(key: string, summarizeResult: ISummarizeResult): void {\n this.summaryTree[key] = summarizeResult.summary;\n this.summaryStats = mergeStats(this.summaryStats, summarizeResult.stats);\n }\n\n public addAttachment(id: string) {\n this.summaryTree[this.attachmentCounter++] = { id, type: SummaryType.Attachment };\n }\n\n public getSummaryTree(): ISummaryTreeWithStats {\n return { summary: this.summary, stats: this.stats };\n }\n}\n\n/**\n * Converts snapshot ITree to ISummaryTree format and tracks stats.\n * @param snapshot - snapshot in ITree format\n * @param fullTree - true to never use handles, even if id is specified\n */\nexport function convertToSummaryTreeWithStats(\n snapshot: ITree,\n fullTree: boolean = false,\n): ISummaryTreeWithStats {\n const builder = new SummaryTreeBuilder();\n for (const entry of snapshot.entries) {\n switch (entry.type) {\n case TreeEntry.Blob: {\n const blob = entry.value;\n let content: string | Uint8Array;\n if (blob.encoding === \"base64\") {\n content = IsoBuffer.from(blob.contents, \"base64\");\n } else {\n content = blob.contents;\n }\n builder.addBlob(entry.path, content);\n break;\n }\n\n case TreeEntry.Tree: {\n const subtree = convertToSummaryTree(\n entry.value,\n fullTree);\n builder.addWithStats(entry.path, subtree);\n\n break;\n }\n\n case TreeEntry.Attachment: {\n const id = entry.value.id;\n builder.addAttachment(id);\n\n break;\n }\n\n case TreeEntry.Commit:\n throw new Error(\"Should not have Commit TreeEntry in summary\");\n\n default:\n throw new Error(\"Unexpected TreeEntry type\");\n }\n }\n\n return builder.getSummaryTree();\n}\n\n/**\n * Converts snapshot ITree to ISummaryTree format and tracks stats.\n * @param snapshot - snapshot in ITree format\n * @param fullTree - true to never use handles, even if id is specified\n */\nexport function convertToSummaryTree(\n snapshot: ITree,\n fullTree: boolean = false,\n): ISummarizeResult {\n // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions\n if (snapshot.id && !fullTree) {\n const stats = mergeStats();\n stats.handleNodeCount++;\n return {\n summary: {\n handle: snapshot.id,\n handleType: SummaryType.Tree,\n type: SummaryType.Handle,\n },\n stats,\n };\n } else {\n return convertToSummaryTreeWithStats(snapshot, fullTree);\n }\n}\n\n/**\n * Converts ISnapshotTree to ISummaryTree format and tracks stats. This snapshot tree was\n * was taken by serialize api in detached container.\n * @param snapshot - snapshot in ISnapshotTree format\n */\nexport function convertSnapshotTreeToSummaryTree(\n snapshot: ISnapshotTree,\n): ISummaryTreeWithStats {\n assert(Object.keys(snapshot.commits).length === 0,\n 0x19e /* \"There should not be commit tree entries in snapshot\" */);\n\n const builder = new SummaryTreeBuilder();\n for (const [key, value] of Object.entries(snapshot.blobs)) {\n // The entries in blobs are supposed to be blobPath -> blobId and blobId -> blobValue\n // and we want to push blobPath to blobValue in tree entries.\n if (snapshot.blobs[value] !== undefined) {\n const decoded = fromBase64ToUtf8(snapshot.blobs[value]);\n builder.addBlob(key, decoded);\n }\n }\n\n for (const [key, tree] of Object.entries(snapshot.trees)) {\n const subtree = convertSnapshotTreeToSummaryTree(tree);\n builder.addWithStats(key, subtree);\n }\n return builder.getSummaryTree();\n}\n\n/**\n * Utility to convert serialized snapshot taken in detached container to format where we can use it to\n * attach the container.\n * @param serializedSnapshotTree - serialized snapshot tree to be converted to summary tree for attach.\n */\nexport function convertContainerToDriverSerializedFormat(\n serializedSnapshotTree: string,\n): ISummaryTree {\n const snapshotTree: ISnapshotTree = JSON.parse(serializedSnapshotTree);\n const summaryTree = convertSnapshotTreeToSummaryTree(snapshotTree).summary;\n const appSummaryTree: ISummaryTree = {\n type: SummaryType.Tree,\n tree: {},\n };\n const entries = Object.entries(summaryTree.tree);\n for (const [key, subTree] of entries) {\n if (key !== \".protocol\") {\n appSummaryTree.tree[key] = subTree;\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n delete summaryTree.tree[key];\n }\n }\n summaryTree.tree[\".app\"] = appSummaryTree;\n return summaryTree;\n}\n\n/**\n * Converts ISummaryTree to ITree format. This is needed for back-compat while we get rid of snapshot.\n * @param summaryTree - summary tree in ISummaryTree format\n */\nexport function convertSummaryTreeToITree(summaryTree: ISummaryTree): ITree {\n const entries: ITreeEntry[] = [];\n for (const [key, value] of Object.entries(summaryTree.tree)) {\n switch (value.type) {\n case SummaryType.Blob: {\n let parsedContent: string;\n let encoding: string = \"utf-8\";\n if (typeof value.content === \"string\") {\n parsedContent = value.content;\n } else {\n parsedContent = Uint8ArrayToString(value.content, \"base64\");\n encoding = \"base64\";\n }\n entries.push(new BlobTreeEntry(key, parsedContent, encoding));\n break;\n }\n\n case SummaryType.Tree: {\n entries.push(new TreeTreeEntry(key, convertSummaryTreeToITree(value)));\n break;\n }\n\n case SummaryType.Attachment: {\n entries.push(new AttachmentTreeEntry(key, value.id));\n break;\n }\n\n case SummaryType.Handle: {\n throw new Error(\"Should not have Handle type in summary tree\");\n }\n\n default:\n unreachableCase(value, \"Unexpected summary tree type\");\n }\n }\n return {\n entries,\n };\n}\n"]} |
+6
-6
| { | ||
| "name": "@fluidframework/runtime-utils", | ||
| "version": "0.37.0-20427", | ||
| "version": "0.37.0-20517", | ||
| "description": "Collection of utility functions for Fluid Runtime", | ||
@@ -60,8 +60,8 @@ "homepage": "https://fluidframework.com", | ||
| "@fluidframework/common-utils": "^0.29.0-0", | ||
| "@fluidframework/core-interfaces": "0.37.0-20427", | ||
| "@fluidframework/datastore-definitions": "0.37.0-20427", | ||
| "@fluidframework/garbage-collector": "0.37.0-20427", | ||
| "@fluidframework/core-interfaces": "0.37.0-20517", | ||
| "@fluidframework/datastore-definitions": "0.37.0-20517", | ||
| "@fluidframework/garbage-collector": "0.37.0-20517", | ||
| "@fluidframework/protocol-base": "^0.1022.0-0", | ||
| "@fluidframework/protocol-definitions": "^0.1022.0-0", | ||
| "@fluidframework/runtime-definitions": "0.37.0-20427", | ||
| "@fluidframework/runtime-definitions": "0.37.0-20517", | ||
| "assert": "^2.0.0" | ||
@@ -72,3 +72,3 @@ }, | ||
| "@fluidframework/eslint-config-fluid": "^0.23.0", | ||
| "@fluidframework/mocha-test-setup": "0.37.0-20427", | ||
| "@fluidframework/mocha-test-setup": "0.37.0-20517", | ||
| "@microsoft/api-extractor": "^7.13.1", | ||
@@ -75,0 +75,0 @@ "@types/assert": "^1.5.2", |
@@ -83,3 +83,3 @@ /*! | ||
| assert(response.value, "Invalid response value for Fluid object request"); | ||
| assert(response.value, 0x19a /* "Invalid response value for Fluid object request" */); | ||
| return response.value as T; | ||
@@ -91,3 +91,3 @@ } | ||
| export function createResponseError(status: number, value: string, request: IRequest): IResponse { | ||
| assert(status !== 200, "Cannot not create response error on 200 status"); | ||
| assert(status !== 200, 0x19b /* "Cannot not create response error on 200 status" */); | ||
| return { | ||
@@ -94,0 +94,0 @@ mimeType: "text/plain", |
@@ -15,3 +15,3 @@ /*! | ||
| // `path` must not include the trailing separator. | ||
| assert(!path.endsWith("/"), "storage service path has trailing separator"); | ||
| assert(!path.endsWith("/"), 0x19c /* "storage service path has trailing separator" */); | ||
| } | ||
@@ -18,0 +18,0 @@ |
@@ -9,2 +9,2 @@ /*! | ||
| export const pkgName = "@fluidframework/runtime-utils"; | ||
| export const pkgVersion = "0.37.0-20427"; | ||
| export const pkgVersion = "0.37.0-20517"; |
@@ -40,3 +40,3 @@ /*! | ||
| ) { | ||
| assert(absolutePath.startsWith("/"), "Handles should always have absolute paths"); | ||
| assert(absolutePath.startsWith("/"), 0x19d /* "Handles should always have absolute paths" */); | ||
| } | ||
@@ -43,0 +43,0 @@ |
@@ -71,4 +71,5 @@ /*! | ||
| public startSummary(referenceSequenceNumber: number, summaryLogger: ITelemetryLogger) { | ||
| assert(this.wipSummaryLogger === undefined, "wipSummaryLogger should not be set yet in startSummary"); | ||
| assert(this.wipReferenceSequenceNumber === undefined, "Already tracking a summary"); | ||
| assert(this.wipSummaryLogger === undefined, | ||
| 0x19f /* "wipSummaryLogger should not be set yet in startSummary" */); | ||
| assert(this.wipReferenceSequenceNumber === undefined, 0x1a0 /* "Already tracking a summary" */); | ||
@@ -84,4 +85,5 @@ this.wipSummaryLogger = summaryLogger; | ||
| public async summarize(fullTree: boolean): Promise<ISummarizeResult> { | ||
| assert(this.isTrackingInProgress(), "summarize should not be called when not tracking the summary"); | ||
| assert(this.wipSummaryLogger !== undefined, "wipSummaryLogger should have been set in startSummary or ctor"); | ||
| assert(this.isTrackingInProgress(), 0x1a1 /* "summarize should not be called when not tracking the summary" */); | ||
| assert(this.wipSummaryLogger !== undefined, | ||
| 0x1a2 /* "wipSummaryLogger should have been set in startSummary or ctor" */); | ||
@@ -173,4 +175,5 @@ // Try to reuse the tree if unchanged | ||
| ) { | ||
| assert(this.wipSummaryLogger !== undefined, "wipSummaryLogger should have been set in startSummary or ctor"); | ||
| assert(this.wipReferenceSequenceNumber !== undefined, "Not tracking a summary"); | ||
| assert(this.wipSummaryLogger !== undefined, | ||
| 0x1a3 /* "wipSummaryLogger should have been set in startSummary or ctor" */); | ||
| assert(this.wipReferenceSequenceNumber !== undefined, 0x1a4 /* "Not tracking a summary" */); | ||
| let localPathsToUse = this.wipLocalPaths; | ||
@@ -206,3 +209,3 @@ | ||
| // If there is no latestSummary, clearSummary and return before reaching this code. | ||
| assert(!!localPathsToUse, "Tracked summary local paths not set"); | ||
| assert(!!localPathsToUse, 0x1a5 /* "Tracked summary local paths not set" */); | ||
@@ -278,3 +281,3 @@ const summary = new SummaryNode({ | ||
| this.latestSummary === undefined, | ||
| "Not found pending summary, but this node has previously completed a summary", | ||
| 0x1a6 /* "Not found pending summary, but this node has previously completed a summary" */, | ||
| ); | ||
@@ -286,3 +289,3 @@ return; | ||
| // eslint-disable-next-line max-len | ||
| `Pending summary reference sequence number should be consistent: ${summaryNode.referenceSequenceNumber} != ${referenceSequenceNumber}`, | ||
| 0x1a7 /* `Pending summary reference sequence number should be consistent: ${summaryNode.referenceSequenceNumber} != ${referenceSequenceNumber}` */, | ||
| ); | ||
@@ -402,3 +405,3 @@ | ||
| newOpsLatestSeq <= this.trackingSequenceNumber, | ||
| "When loading base summary, expected outstanding ops <= tracking sequence number", | ||
| 0x1a9 /* "When loading base summary, expected outstanding ops <= tracking sequence number" */, | ||
| ); | ||
@@ -418,3 +421,3 @@ } | ||
| lastOp.sequenceNumber < op.sequenceNumber, | ||
| `Out of order change recorded: ${lastOp.sequenceNumber} > ${op.sequenceNumber}`, | ||
| 0x1aa /* `Out of order change recorded: ${lastOp.sequenceNumber} > ${op.sequenceNumber}` */, | ||
| ); | ||
@@ -481,3 +484,3 @@ } | ||
| ): ISummarizerNode { | ||
| assert(!this.children.has(id), "Create SummarizerNode child already exists"); | ||
| assert(!this.children.has(id), 0x1ab /* "Create SummarizerNode child already exists" */); | ||
@@ -542,3 +545,3 @@ const createDetails: ICreateChildDetails = this.getCreateDetailsForChild(id, createParam); | ||
| !!parentLatestSummary, | ||
| "Cannot create child from summary if parent does not have latest summary"); | ||
| 0x1ac /* "Cannot create child from summary if parent does not have latest summary" */); | ||
| } | ||
@@ -555,3 +558,3 @@ // fallthrough to local | ||
| childrenTree.type === SummaryType.Tree, | ||
| "Parent summary object is not a tree", | ||
| 0x1d6 /* "Parent summary object is not a tree" */, | ||
| ); | ||
@@ -562,3 +565,3 @@ childSummary = childrenTree.tree[id]; | ||
| // Locally created would not have differential subtree. | ||
| assert(!!childSummary, "Missing child summary tree"); | ||
| assert(!!childSummary, 0x1ad /* "Missing child summary tree" */); | ||
| } | ||
@@ -569,3 +572,3 @@ let childSummaryWithStats: ISummaryTreeWithStats | undefined; | ||
| childSummary.type === SummaryType.Tree, | ||
| "Child summary object is not a tree", | ||
| 0x1ae /* "Child summary object is not a tree" */, | ||
| ); | ||
@@ -572,0 +575,0 @@ childSummaryWithStats = { |
@@ -206,4 +206,4 @@ /*! | ||
| assert(!!outstandingOpsBlob, "Outstanding ops blob missing, but base summary tree exists"); | ||
| assert(newBaseSummary !== undefined, "Base summary tree missing, but outstanding ops blob exists"); | ||
| assert(!!outstandingOpsBlob, 0x1af /* "Outstanding ops blob missing, but base summary tree exists" */); | ||
| assert(newBaseSummary !== undefined, 0x1b0 /* "Base summary tree missing, but outstanding ops blob exists" */); | ||
| baseSummary = newBaseSummary; | ||
@@ -210,0 +210,0 @@ pathParts.push(baseSummaryTreeKey); |
@@ -144,3 +144,4 @@ /*! | ||
| if (!this.gcDisabled && this.isTrackingInProgress()) { | ||
| assert(this.wipSerializedUsedRoutes !== undefined, "wip used routes should be set if tracking a summary"); | ||
| assert(this.wipSerializedUsedRoutes !== undefined, | ||
| 0x1b1 /* "wip used routes should be set if tracking a summary" */); | ||
| } | ||
@@ -153,3 +154,3 @@ | ||
| // If there is no cached GC data, return empty data in summarize result. It is the caller's responsiblity | ||
| // If there is no cached GC data, return empty data in summarize result. It is the caller's responsibility | ||
| // to ensure that GC data is available by calling getGCData before calling summarize. | ||
@@ -179,4 +180,4 @@ const gcData = this.gcData !== undefined ? cloneGCData(this.gcData) : { gcNodes: {} }; | ||
| public async getGCData(fullGC: boolean = false): Promise<IGarbageCollectionData> { | ||
| assert(!this.gcDisabled, "Getting GC data should not be called when GC is disabled!"); | ||
| assert(this.getGCDataFn !== undefined, "GC data cannot be retrieved without getGCDataFn"); | ||
| assert(!this.gcDisabled, 0x1b2 /* "Getting GC data should not be called when GC is disabled!" */); | ||
| assert(this.getGCDataFn !== undefined, 0x1b3 /* "GC data cannot be retrieved without getGCDataFn" */); | ||
@@ -207,3 +208,3 @@ // Load GC details from the initial summary, if not already loaded. If this is the first time this function is | ||
| this.wipSerializedUsedRoutes === undefined, | ||
| "We should not already be tracking used routes when to track a new summary"); | ||
| 0x1b4 /* "We should not already be tracking used routes when to track a new summary" */); | ||
@@ -230,3 +231,3 @@ // back-compat: 0.33 - This will be done in `updateUsedRoutes`. Older clients do not have that method, so | ||
| wipSerializedUsedRoutes = this.wipSerializedUsedRoutes; | ||
| assert(wipSerializedUsedRoutes !== undefined, "We should have been tracking used routes"); | ||
| assert(wipSerializedUsedRoutes !== undefined, 0x1b5 /* "We should have been tracking used routes" */); | ||
| } | ||
@@ -329,3 +330,3 @@ | ||
| ): ISummarizerNodeWithGC { | ||
| assert(!this.children.has(id), "Create SummarizerNode child already exists"); | ||
| assert(!this.children.has(id), 0x1b6 /* "Create SummarizerNode child already exists" */); | ||
@@ -332,0 +333,0 @@ const createDetails: ICreateChildDetails = this.getCreateDetailsForChild(id, createParam); |
@@ -244,3 +244,4 @@ /*! | ||
| ): ISummaryTreeWithStats { | ||
| assert(Object.keys(snapshot.commits).length === 0, "There should not be commit tree entries in snapshot"); | ||
| assert(Object.keys(snapshot.commits).length === 0, | ||
| 0x19e /* "There should not be commit tree entries in snapshot" */); | ||
@@ -247,0 +248,0 @@ const builder = new SummaryTreeBuilder(); |
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
637967
0.37%6983
0.07%+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed