@fluidframework/container-runtime 0.55.1 → 0.56.0-49831
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/containerRuntime.d.ts +3 -12
- package/dist/containerRuntime.d.ts.map +1 -1
- package/dist/containerRuntime.js +22 -38
- package/dist/containerRuntime.js.map +1 -1
- package/dist/dataStoreContext.d.ts +42 -29
- package/dist/dataStoreContext.d.ts.map +1 -1
- package/dist/dataStoreContext.js +27 -49
- package/dist/dataStoreContext.js.map +1 -1
- package/dist/dataStores.d.ts +2 -1
- package/dist/dataStores.d.ts.map +1 -1
- package/dist/dataStores.js +74 -16
- package/dist/dataStores.js.map +1 -1
- package/dist/garbageCollection.d.ts +22 -9
- package/dist/garbageCollection.d.ts.map +1 -1
- package/dist/garbageCollection.js +55 -35
- package/dist/garbageCollection.js.map +1 -1
- package/dist/index.d.ts +6 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -17
- package/dist/index.js.map +1 -1
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.d.ts.map +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/dist/runningSummarizer.d.ts.map +1 -1
- package/dist/runningSummarizer.js +2 -9
- package/dist/runningSummarizer.js.map +1 -1
- package/dist/summaryFormat.d.ts.map +1 -1
- package/dist/summaryFormat.js +2 -1
- package/dist/summaryFormat.js.map +1 -1
- package/dist/summaryGenerator.d.ts +0 -5
- package/dist/summaryGenerator.d.ts.map +1 -1
- package/dist/summaryGenerator.js.map +1 -1
- package/garbageCollection.md +33 -0
- package/lib/containerRuntime.d.ts +3 -12
- package/lib/containerRuntime.d.ts.map +1 -1
- package/lib/containerRuntime.js +23 -39
- package/lib/containerRuntime.js.map +1 -1
- package/lib/dataStoreContext.d.ts +42 -29
- package/lib/dataStoreContext.d.ts.map +1 -1
- package/lib/dataStoreContext.js +25 -47
- package/lib/dataStoreContext.js.map +1 -1
- package/lib/dataStores.d.ts +2 -1
- package/lib/dataStores.d.ts.map +1 -1
- package/lib/dataStores.js +75 -17
- package/lib/dataStores.js.map +1 -1
- package/lib/garbageCollection.d.ts +22 -9
- package/lib/garbageCollection.d.ts.map +1 -1
- package/lib/garbageCollection.js +55 -35
- package/lib/garbageCollection.js.map +1 -1
- package/lib/index.d.ts +6 -6
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +5 -6
- package/lib/index.js.map +1 -1
- package/lib/packageVersion.d.ts +1 -1
- package/lib/packageVersion.d.ts.map +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/lib/runningSummarizer.d.ts.map +1 -1
- package/lib/runningSummarizer.js +2 -9
- package/lib/runningSummarizer.js.map +1 -1
- package/lib/summaryFormat.d.ts.map +1 -1
- package/lib/summaryFormat.js +2 -1
- package/lib/summaryFormat.js.map +1 -1
- package/lib/summaryGenerator.d.ts +0 -5
- package/lib/summaryGenerator.d.ts.map +1 -1
- package/lib/summaryGenerator.js.map +1 -1
- package/package.json +14 -14
- package/src/containerRuntime.ts +36 -42
- package/src/dataStoreContext.ts +76 -122
- package/src/dataStores.ts +75 -48
- package/src/garbageCollection.ts +62 -39
- package/src/index.ts +51 -6
- package/src/packageVersion.ts +1 -1
- package/src/runningSummarizer.ts +2 -7
- package/src/summaryFormat.ts +2 -1
- package/src/summaryGenerator.ts +0 -5
package/lib/summaryFormat.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"summaryFormat.js","sourceRoot":"","sources":["../src/summaryFormat.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert } from \"@fluidframework/common-utils\";\nimport { IDocumentStorageService } from \"@fluidframework/driver-definitions\";\nimport { readAndParse } from \"@fluidframework/driver-utils\";\nimport { ISequencedDocumentMessage, ISnapshotTree, SummaryType } from \"@fluidframework/protocol-definitions\";\nimport { channelsTreeName, ISummaryTreeWithStats } from \"@fluidframework/runtime-definitions\";\n\ntype OmitAttributesVersions<T> = Omit<T, \"snapshotFormatVersion\" | \"summaryFormatVersion\">;\ninterface IFluidDataStoreAttributes0 {\n readonly snapshotFormatVersion?: undefined;\n readonly summaryFormatVersion?: undefined;\n pkg: string;\n /**\n * This tells whether a data store is root. Root data stores are never collected.\n * Non-root data stores may be collected if they are not used. If this is not present, default it to\n * true. This will ensure that older data stores are incorrectly collected.\n */\n readonly isRootDataStore?: boolean;\n}\ninterface IFluidDataStoreAttributes1 extends OmitAttributesVersions<IFluidDataStoreAttributes0> {\n readonly snapshotFormatVersion: \"0.1\";\n readonly summaryFormatVersion?: undefined;\n}\ninterface IFluidDataStoreAttributes2 extends OmitAttributesVersions<IFluidDataStoreAttributes1> {\n /** Switch from snapshotFormatVersion to summaryFormatVersion */\n readonly snapshotFormatVersion?: undefined;\n readonly summaryFormatVersion: 2;\n /**\n * True if channels are not isolated in .channels subtrees, otherwise isolated.\n * This is required in both datastore attributes as well as the root container,\n * because reused summary handles may cause different format versions in each\n * datastore subtree within the summary.\n */\n readonly disableIsolatedChannels?: true;\n}\n/**\n * Added IFluidDataStoreAttributes similar to IChannelAttributes which will tell the attributes of a\n * store like the package, snapshotFormatVersion to take different decisions based on a particular\n * snapshotFormatVersion.\n */\nexport type ReadFluidDataStoreAttributes =\n | IFluidDataStoreAttributes0\n | IFluidDataStoreAttributes1\n | IFluidDataStoreAttributes2;\nexport type WriteFluidDataStoreAttributes = IFluidDataStoreAttributes1 | IFluidDataStoreAttributes2;\n\nexport function getAttributesFormatVersion(attributes: ReadFluidDataStoreAttributes): number {\n if (attributes.summaryFormatVersion) {\n /**\n * Version 2+: Introduces .channels trees for isolation of\n * channel trees from data store objects.\n */\n return attributes.summaryFormatVersion;\n } else if (attributes.snapshotFormatVersion === \"0.1\") {\n /**\n * Version 1: from this version the pkg within the data store\n * attributes blob is a JSON array rather than a string.\n */\n return 1;\n }\n /**\n * Version 0: format version is missing from summary.\n * This indicates it is an older version.\n */\n return 0;\n}\n\nexport function hasIsolatedChannels(attributes: ReadFluidDataStoreAttributes): boolean {\n return !!attributes.summaryFormatVersion && !attributes.disableIsolatedChannels;\n}\n\nexport type GCVersion = number;\nexport interface IContainerRuntimeMetadata extends ICreateContainerMetadata {\n readonly summaryFormatVersion: 1;\n /** The last message processed at the time of summary. Only primitive propertiy types are added to the summary. */\n readonly message: ISummaryMetadataMessage | undefined;\n /** True if channels are not isolated in .channels subtrees, otherwise isolated. */\n readonly disableIsolatedChannels?: true;\n /** 0 to disable GC, > 0 to enable GC, undefined defaults to disabled. */\n readonly gcFeature?: GCVersion;\n /** Counter of the last summary happened, increments every time we summarize */\n readonly summaryCount?: number;\n /** If this is present, the session for this container will expire after this time and the container will close */\n readonly sessionExpiryTimeoutMs?: number;\n}\n\nexport interface ICreateContainerMetadata {\n /** Runtime version of the container when it was first created */\n createContainerRuntimeVersion?: string;\n /** Timestamp of the container when it was first created */\n createContainerTimestamp?: number;\n}\n\n/** The properties of an ISequencedDocumentMessage to be stored in the metadata blob in summary. */\nexport type ISummaryMetadataMessage = Pick<ISequencedDocumentMessage,\n | \"clientId\"\n | \"clientSequenceNumber\"\n | \"minimumSequenceNumber\"\n | \"referenceSequenceNumber\"\n | \"sequenceNumber\"\n | \"timestamp\"\n | \"type\">;\n\n/**\n * Extracts the properties from an ISequencedDocumentMessage as defined by ISummaryMetadataMessage. This message is\n * added to the metadata blob in summary.\n */\nexport const extractSummaryMetadataMessage = (\n message?: ISequencedDocumentMessage,\n): ISummaryMetadataMessage | undefined => message === undefined ? undefined : {\n clientId: message.clientId,\n clientSequenceNumber: message.clientSequenceNumber,\n minimumSequenceNumber: message.minimumSequenceNumber,\n referenceSequenceNumber: message.referenceSequenceNumber,\n sequenceNumber: message.sequenceNumber,\n timestamp: message.timestamp,\n type: message.type,\n};\n\nexport function getMetadataFormatVersion(metadata?: IContainerRuntimeMetadata): number {\n /**\n * Version 2+: Introduces runtime sequence number for data verification.\n *\n * Version 1+: Introduces .metadata blob and .channels trees for isolation of\n * data store trees from container-level objects.\n * Also introduces enableGC option stored in the summary.\n *\n * Version 0: metadata blob missing; format version is missing from summary.\n * This indicates it is an older version.\n */\n return metadata?.summaryFormatVersion ?? 0;\n}\n\nexport const aliasBlobName = \".aliases\";\nexport const metadataBlobName = \".metadata\";\nexport const chunksBlobName = \".chunks\";\nexport const electedSummarizerBlobName = \".electedSummarizer\";\nexport const blobsTreeName = \".blobs\";\n\nexport function rootHasIsolatedChannels(metadata?: IContainerRuntimeMetadata): boolean {\n return !!metadata && !metadata.disableIsolatedChannels;\n}\n\nexport function getGCVersion(metadata?: IContainerRuntimeMetadata): GCVersion {\n if (!metadata) {\n // Force to 0/disallowed in prior versions\n return 0;\n }\n return metadata.gcFeature ?? 0;\n}\n\nexport const protocolTreeName = \".protocol\";\n\n/**\n * List of tree IDs at the container level which are reserved.\n * This is for older versions of summaries that do not yet have an\n * isolated data stores namespace. Without the namespace, this must\n * be used to prevent name collisions with data store IDs.\n */\nexport const nonDataStorePaths = [protocolTreeName, \".logTail\", \".serviceProtocol\", blobsTreeName];\n\nexport const dataStoreAttributesBlobName = \".component\";\n\n/**\n * Modifies summary tree and stats to put tree under .channels tree.\n * Converts from: {\n * type: SummaryType.Tree,\n * tree: { a: {...}, b: {...}, c: {...} },\n * }\n * to: {\n * type: SummaryType.Tree,\n * tree: {\n * \".channels\": {\n * type: SummaryType.Tree,\n * tree: { a: {...}, b: {...}, c: {...} }\n * },\n * },\n * }\n * And adds +1 to treeNodeCount in stats.\n * @param summarizeResult - summary tree and stats to modify\n */\nexport function wrapSummaryInChannelsTree(summarizeResult: ISummaryTreeWithStats): void {\n summarizeResult.summary = {\n type: SummaryType.Tree,\n tree: { [channelsTreeName]: summarizeResult.summary },\n };\n summarizeResult.stats.treeNodeCount++;\n}\n\nexport async function getFluidDataStoreAttributes(\n storage: IDocumentStorageService,\n snapshot: ISnapshotTree,\n): Promise<ReadFluidDataStoreAttributes> {\n const attributes = await readAndParse<ReadFluidDataStoreAttributes>(\n storage, snapshot.blobs[dataStoreAttributesBlobName]);\n // Use the snapshotFormatVersion to determine how the pkg is encoded in the snapshot.\n // For snapshotFormatVersion = \"0.1\" (1) or above, pkg is jsonified, otherwise it is just a string.\n // However the feature of loading a detached container from snapshot, is added when the\n // snapshotFormatVersion is at least \"0.1\" (1), so we don't expect it to be anything else.\n const formatVersion = getAttributesFormatVersion(attributes);\n assert(formatVersion > 0,\n 0x1d5 /* `Invalid snapshot format version ${attributes.snapshotFormatVersion}` */);\n return attributes;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"summaryFormat.js","sourceRoot":"","sources":["../src/summaryFormat.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert } from \"@fluidframework/common-utils\";\nimport { IDocumentStorageService } from \"@fluidframework/driver-definitions\";\nimport { readAndParse } from \"@fluidframework/driver-utils\";\nimport { ISequencedDocumentMessage, ISnapshotTree, SummaryType } from \"@fluidframework/protocol-definitions\";\nimport { channelsTreeName, ISummaryTreeWithStats } from \"@fluidframework/runtime-definitions\";\nimport { gcTreeKey } from \"./garbageCollection\";\n\ntype OmitAttributesVersions<T> = Omit<T, \"snapshotFormatVersion\" | \"summaryFormatVersion\">;\ninterface IFluidDataStoreAttributes0 {\n readonly snapshotFormatVersion?: undefined;\n readonly summaryFormatVersion?: undefined;\n pkg: string;\n /**\n * This tells whether a data store is root. Root data stores are never collected.\n * Non-root data stores may be collected if they are not used. If this is not present, default it to\n * true. This will ensure that older data stores are incorrectly collected.\n */\n readonly isRootDataStore?: boolean;\n}\ninterface IFluidDataStoreAttributes1 extends OmitAttributesVersions<IFluidDataStoreAttributes0> {\n readonly snapshotFormatVersion: \"0.1\";\n readonly summaryFormatVersion?: undefined;\n}\ninterface IFluidDataStoreAttributes2 extends OmitAttributesVersions<IFluidDataStoreAttributes1> {\n /** Switch from snapshotFormatVersion to summaryFormatVersion */\n readonly snapshotFormatVersion?: undefined;\n readonly summaryFormatVersion: 2;\n /**\n * True if channels are not isolated in .channels subtrees, otherwise isolated.\n * This is required in both datastore attributes as well as the root container,\n * because reused summary handles may cause different format versions in each\n * datastore subtree within the summary.\n */\n readonly disableIsolatedChannels?: true;\n}\n/**\n * Added IFluidDataStoreAttributes similar to IChannelAttributes which will tell the attributes of a\n * store like the package, snapshotFormatVersion to take different decisions based on a particular\n * snapshotFormatVersion.\n */\nexport type ReadFluidDataStoreAttributes =\n | IFluidDataStoreAttributes0\n | IFluidDataStoreAttributes1\n | IFluidDataStoreAttributes2;\nexport type WriteFluidDataStoreAttributes = IFluidDataStoreAttributes1 | IFluidDataStoreAttributes2;\n\nexport function getAttributesFormatVersion(attributes: ReadFluidDataStoreAttributes): number {\n if (attributes.summaryFormatVersion) {\n /**\n * Version 2+: Introduces .channels trees for isolation of\n * channel trees from data store objects.\n */\n return attributes.summaryFormatVersion;\n } else if (attributes.snapshotFormatVersion === \"0.1\") {\n /**\n * Version 1: from this version the pkg within the data store\n * attributes blob is a JSON array rather than a string.\n */\n return 1;\n }\n /**\n * Version 0: format version is missing from summary.\n * This indicates it is an older version.\n */\n return 0;\n}\n\nexport function hasIsolatedChannels(attributes: ReadFluidDataStoreAttributes): boolean {\n return !!attributes.summaryFormatVersion && !attributes.disableIsolatedChannels;\n}\n\nexport type GCVersion = number;\nexport interface IContainerRuntimeMetadata extends ICreateContainerMetadata {\n readonly summaryFormatVersion: 1;\n /** The last message processed at the time of summary. Only primitive propertiy types are added to the summary. */\n readonly message: ISummaryMetadataMessage | undefined;\n /** True if channels are not isolated in .channels subtrees, otherwise isolated. */\n readonly disableIsolatedChannels?: true;\n /** 0 to disable GC, > 0 to enable GC, undefined defaults to disabled. */\n readonly gcFeature?: GCVersion;\n /** Counter of the last summary happened, increments every time we summarize */\n readonly summaryCount?: number;\n /** If this is present, the session for this container will expire after this time and the container will close */\n readonly sessionExpiryTimeoutMs?: number;\n}\n\nexport interface ICreateContainerMetadata {\n /** Runtime version of the container when it was first created */\n createContainerRuntimeVersion?: string;\n /** Timestamp of the container when it was first created */\n createContainerTimestamp?: number;\n}\n\n/** The properties of an ISequencedDocumentMessage to be stored in the metadata blob in summary. */\nexport type ISummaryMetadataMessage = Pick<ISequencedDocumentMessage,\n | \"clientId\"\n | \"clientSequenceNumber\"\n | \"minimumSequenceNumber\"\n | \"referenceSequenceNumber\"\n | \"sequenceNumber\"\n | \"timestamp\"\n | \"type\">;\n\n/**\n * Extracts the properties from an ISequencedDocumentMessage as defined by ISummaryMetadataMessage. This message is\n * added to the metadata blob in summary.\n */\nexport const extractSummaryMetadataMessage = (\n message?: ISequencedDocumentMessage,\n): ISummaryMetadataMessage | undefined => message === undefined ? undefined : {\n clientId: message.clientId,\n clientSequenceNumber: message.clientSequenceNumber,\n minimumSequenceNumber: message.minimumSequenceNumber,\n referenceSequenceNumber: message.referenceSequenceNumber,\n sequenceNumber: message.sequenceNumber,\n timestamp: message.timestamp,\n type: message.type,\n};\n\nexport function getMetadataFormatVersion(metadata?: IContainerRuntimeMetadata): number {\n /**\n * Version 2+: Introduces runtime sequence number for data verification.\n *\n * Version 1+: Introduces .metadata blob and .channels trees for isolation of\n * data store trees from container-level objects.\n * Also introduces enableGC option stored in the summary.\n *\n * Version 0: metadata blob missing; format version is missing from summary.\n * This indicates it is an older version.\n */\n return metadata?.summaryFormatVersion ?? 0;\n}\n\nexport const aliasBlobName = \".aliases\";\nexport const metadataBlobName = \".metadata\";\nexport const chunksBlobName = \".chunks\";\nexport const electedSummarizerBlobName = \".electedSummarizer\";\nexport const blobsTreeName = \".blobs\";\n\nexport function rootHasIsolatedChannels(metadata?: IContainerRuntimeMetadata): boolean {\n return !!metadata && !metadata.disableIsolatedChannels;\n}\n\nexport function getGCVersion(metadata?: IContainerRuntimeMetadata): GCVersion {\n if (!metadata) {\n // Force to 0/disallowed in prior versions\n return 0;\n }\n return metadata.gcFeature ?? 0;\n}\n\nexport const protocolTreeName = \".protocol\";\n\n/**\n * List of tree IDs at the container level which are reserved.\n * This is for older versions of summaries that do not yet have an\n * isolated data stores namespace. Without the namespace, this must\n * be used to prevent name collisions with data store IDs.\n */\nexport const nonDataStorePaths = [protocolTreeName, \".logTail\", \".serviceProtocol\", blobsTreeName, gcTreeKey];\n\nexport const dataStoreAttributesBlobName = \".component\";\n\n/**\n * Modifies summary tree and stats to put tree under .channels tree.\n * Converts from: {\n * type: SummaryType.Tree,\n * tree: { a: {...}, b: {...}, c: {...} },\n * }\n * to: {\n * type: SummaryType.Tree,\n * tree: {\n * \".channels\": {\n * type: SummaryType.Tree,\n * tree: { a: {...}, b: {...}, c: {...} }\n * },\n * },\n * }\n * And adds +1 to treeNodeCount in stats.\n * @param summarizeResult - summary tree and stats to modify\n */\nexport function wrapSummaryInChannelsTree(summarizeResult: ISummaryTreeWithStats): void {\n summarizeResult.summary = {\n type: SummaryType.Tree,\n tree: { [channelsTreeName]: summarizeResult.summary },\n };\n summarizeResult.stats.treeNodeCount++;\n}\n\nexport async function getFluidDataStoreAttributes(\n storage: IDocumentStorageService,\n snapshot: ISnapshotTree,\n): Promise<ReadFluidDataStoreAttributes> {\n const attributes = await readAndParse<ReadFluidDataStoreAttributes>(\n storage, snapshot.blobs[dataStoreAttributesBlobName]);\n // Use the snapshotFormatVersion to determine how the pkg is encoded in the snapshot.\n // For snapshotFormatVersion = \"0.1\" (1) or above, pkg is jsonified, otherwise it is just a string.\n // However the feature of loading a detached container from snapshot, is added when the\n // snapshotFormatVersion is at least \"0.1\" (1), so we don't expect it to be anything else.\n const formatVersion = getAttributesFormatVersion(attributes);\n assert(formatVersion > 0,\n 0x1d5 /* `Invalid snapshot format version ${attributes.snapshotFormatVersion}` */);\n return attributes;\n}\n"]}
|
|
@@ -38,11 +38,6 @@ export declare type SummarizeReason =
|
|
|
38
38
|
* ack op.
|
|
39
39
|
*/
|
|
40
40
|
| "maxOps"
|
|
41
|
-
/**
|
|
42
|
-
* Special case to generate a summary in response to a Save op.
|
|
43
|
-
* @deprecated - do not use save ops
|
|
44
|
-
*/
|
|
45
|
-
| `save;${string}: ${string}`
|
|
46
41
|
/**
|
|
47
42
|
* Special case to attempt to summarize one last time before the
|
|
48
43
|
* summarizer client closes itself. This is to prevent cases where
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"summaryGenerator.d.ts","sourceRoot":"","sources":["../src/summaryGenerator.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,oCAAoC,CAAC;AAC5F,OAAO,EAEH,QAAQ,EACR,aAAa,EACb,mBAAmB,EAEtB,MAAM,8BAA8B,CAAC;AAKtC,OAAO,EACH,iBAAiB,EACjB,kBAAkB,EAClB,iBAAiB,EACjB,uBAAuB,EACvB,iBAAiB,EACjB,uBAAuB,EACvB,qBAAqB,EACrB,mBAAmB,EACnB,mBAAmB,EACnB,yBAAyB,EAC5B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAE5D,oBAAY,eAAe,CAAC,CAAC,IACzB;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,CAAC,CAAA;CAAE,GAC5B;IAAE,MAAM,EAAE,mBAAmB,CAAC,aAAa,CAAC,CAAA;CAAE,GAC9C;IAAE,MAAM,EAAE,WAAW,CAAA;CAAE,CAAC;AAE5B,uEAAuE;AACvE,wBAAsB,SAAS,CAAC,CAAC,EAC7B,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,EACnB,KAAK,EAAE,OAAO,CAAC,mBAAmB,CAAC,EACnC,iBAAiB,CAAC,EAAE,yBAAyB,GAC9C,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAS7B;AAMD,oBAAY,eAAe;AACvB;;;;;GAKG;AACD,MAAM;AACR;;;;GAIG;GACD,SAAS;AACX;;;;;;GAMG;GACD,QAAQ;AACV
|
|
1
|
+
{"version":3,"file":"summaryGenerator.d.ts","sourceRoot":"","sources":["../src/summaryGenerator.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,oCAAoC,CAAC;AAC5F,OAAO,EAEH,QAAQ,EACR,aAAa,EACb,mBAAmB,EAEtB,MAAM,8BAA8B,CAAC;AAKtC,OAAO,EACH,iBAAiB,EACjB,kBAAkB,EAClB,iBAAiB,EACjB,uBAAuB,EACvB,iBAAiB,EACjB,uBAAuB,EACvB,qBAAqB,EACrB,mBAAmB,EACnB,mBAAmB,EACnB,yBAAyB,EAC5B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAE5D,oBAAY,eAAe,CAAC,CAAC,IACzB;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,CAAC,CAAA;CAAE,GAC5B;IAAE,MAAM,EAAE,mBAAmB,CAAC,aAAa,CAAC,CAAA;CAAE,GAC9C;IAAE,MAAM,EAAE,WAAW,CAAA;CAAE,CAAC;AAE5B,uEAAuE;AACvE,wBAAsB,SAAS,CAAC,CAAC,EAC7B,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,EACnB,KAAK,EAAE,OAAO,CAAC,mBAAmB,CAAC,EACnC,iBAAiB,CAAC,EAAE,yBAAyB,GAC9C,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAS7B;AAMD,oBAAY,eAAe;AACvB;;;;;GAKG;AACD,MAAM;AACR;;;;GAIG;GACD,SAAS;AACX;;;;;;GAMG;GACD,QAAQ;AACV;;;;;;GAMG;GACD,aAAa;AACf,4DAA4D;GAC1D,QAAQ,MAAM,EAAE;AAClB,yDAAyD;GACvD,YAAY,MAAM,EAAE;AACtB,uDAAuD;GACrD,WAAW,MAAM,EAAE,CAAC;AA6B1B,qBAAa,sBAAsB;IAC/B,SAAgB,gBAAgB,gEAA4D;IAC5F,SAAgB,oBAAoB,oEAAgE;IACpG,SAAgB,wBAAwB,uEACuC;IAExE,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,iBAAiB,CAAC,EAAE,kBAAkB,EAAE,iBAAiB,CAAC,EAAE,MAAM;IAUpG,KAAK,IAAI,iBAAiB;CAOpC;AAED;;GAEG;AACH,qBAAa,gBAAgB;IAGrB,OAAO,CAAC,QAAQ,CAAC,eAAe;IAChC,OAAO,CAAC,QAAQ,CAAC,aAAa;IAC9B,OAAO,CAAC,QAAQ,CAAC,qBAAqB;IACtC,OAAO,CAAC,QAAQ,CAAC,qBAAqB;IACtC,OAAO,CAAC,QAAQ,CAAC,cAAc;IAC/B,OAAO,CAAC,QAAQ,CAAC,MAAM;IAP3B,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAQ;gBAElB,eAAe,EAAE,aAAa,EAC9B,aAAa,EAAE,uBAAuB,EACtC,qBAAqB,EAAE,CAAC,OAAO,EAAE,qBAAqB,KAAK,OAAO,CAAC,mBAAmB,CAAC,EACvF,qBAAqB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,EAClD,cAAc,EAAE,IAAI,CAAC,qBAAqB,EAAE,cAAc,CAAC,EAC3D,MAAM,EAAE,gBAAgB;IAQ7C;;;;;;OAMG;IACI,SAAS,CACZ,cAAc,EAAE,oBAAoB,EACpC,OAAO,EAAE,iBAAiB,EAC1B,iBAAiB,EAAE,yBAAyB,EAC5C,cAAc,yBAA+B,GAC9C,iBAAiB;YAWN,aAAa;IAkL3B,OAAO,CAAC,qBAAqB;IAatB,OAAO;CAGjB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"summaryGenerator.js","sourceRoot":"","sources":["../src/summaryGenerator.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EACH,MAAM,EACN,QAAQ,EAGR,KAAK,GACR,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,WAAW,EAAE,MAAM,sCAAsC,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAC9F,OAAO,EAAE,6BAA6B,EAAE,MAAM,8BAA8B,CAAC;AAC7E,OAAO,EAAE,eAAe,EAAE,MAAM,oCAAoC,CAAC;AAoBrE,uEAAuE;AACvE,MAAM,CAAC,KAAK,UAAU,SAAS,CAC3B,OAAmB,EACnB,KAAmC,EACnC,iBAA6C;IAE7C,MAAM,QAAQ,GAAkC;QAC5C,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAY,CAAA,CAAC;QAC7D,KAAK,CAAC,IAAI,CAAC,CAAC,EAAE,WAAW,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,MAAM,EAAY,CAAA,CAAC;KACjE,CAAC;IACF,IAAI,iBAAiB,KAAK,SAAS,EAAE;QACjC,QAAQ,CAAC,IAAI,CAAC,iBAAiB,CAAC,aAAa,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,WAAW,EAAY,CAAA,CAAC,CAAC,CAAC;KACjG;IACD,OAAO,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;AAClC,CAAC;AAED,yDAAyD;AACzD,MAAM,uBAAuB,GAAG,KAAK,CAAC,CAAC,SAAS;AAChD,MAAM,wBAAwB,GAAG,CAAC,CAAC,CAAC,4BAA4B;AA4ChE,MAAM,eAAe,GAAG;IACpB;;;;OAIG;IACH,oBAAoB,EAAE,0DAA0D;IAChF;;;OAGG;IACH,oBAAoB,EAAE,kDAAkD;IACxE;;;;OAIG;IACH,qBAAqB,EAAE,qDAAqD;IAC5E;;;OAGG;IACH,WAAW,EAAE,4CAA4C;IAEzD,UAAU,EAAE,+DAA+D;CACrE,CAAC;AAEX,MAAM,OAAO,sBAAsB;IAAnC;QACoB,qBAAgB,GAAG,IAAI,QAAQ,EAA4C,CAAC;QAC5E,yBAAoB,GAAG,IAAI,QAAQ,EAAgD,CAAC;QACpF,6BAAwB,GACpC,IAAI,QAAQ,EAA8D,CAAC;IAmBnF,CAAC;IAjBU,IAAI,CAAC,OAAe,EAAE,KAAU,EAAE,iBAAsC,EAAE,iBAA0B;QACvG,MAAM,CAAC,CAAC,IAAI,CAAC,wBAAwB,CAAC,WAAW,EAC7C,KAAK,CAAC,kEAAkE,CAAC,CAAC;QAE9E,MAAM,MAAM,GACR,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,iBAAiB,EAAW,CAAC;QACpF,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QACtC,IAAI,CAAC,oBAAoB,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAC1C,IAAI,CAAC,wBAAwB,CAAC,OAAO,iCAAM,MAAM,KAAE,IAAI,EAAE,iBAAiB,IAAG,CAAC;IAClF,CAAC;IACM,KAAK;QACR,OAAO;YACH,gBAAgB,EAAE,IAAI,CAAC,gBAAgB,CAAC,OAAO;YAC/C,oBAAoB,EAAE,IAAI,CAAC,oBAAoB,CAAC,OAAO;YACvD,wBAAwB,EAAE,IAAI,CAAC,wBAAwB,CAAC,OAAO;SACzD,CAAC;IACf,CAAC;CACJ;AAED;;GAEG;AACH,MAAM,OAAO,gBAAgB;IAEzB,YACqB,eAA8B,EAC9B,aAAsC,EACtC,qBAAuF,EACvF,qBAAkD,EAClD,cAA2D,EAC3D,MAAwB;QALxB,oBAAe,GAAf,eAAe,CAAe;QAC9B,kBAAa,GAAb,aAAa,CAAyB;QACtC,0BAAqB,GAArB,qBAAqB,CAAkE;QACvF,0BAAqB,GAArB,qBAAqB,CAA6B;QAClD,mBAAc,GAAd,cAAc,CAA6C;QAC3D,WAAM,GAAN,MAAM,CAAkB;QAEzC,IAAI,CAAC,cAAc,GAAG,IAAI,KAAK,CAC3B,uBAAuB,EACvB,GAAG,EAAE,CAAC,IAAI,CAAC,qBAAqB,CAAC,uBAAuB,EAAE,CAAC,CAAC,CAC/D,CAAC;IACN,CAAC;IAED;;;;;;OAMG;IACI,SAAS,CACZ,cAAoC,EACpC,OAA0B,EAC1B,iBAA4C,EAC5C,cAAc,GAAG,IAAI,sBAAsB,EAAE;QAE7C,IAAI,CAAC,aAAa,CAAC,cAAc,EAAE,OAAO,EAAE,cAAc,EAAE,iBAAiB,CAAC;aAC7E,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;YACb,MAAM,OAAO,GAAG,0BAA0B,CAAC;YAC3C,IAAI,CAAC,MAAM,CAAC,cAAc,iBAAG,SAAS,EAAE,OAAO,IAAK,cAAc,GAAI,KAAK,CAAC,CAAC;YAC7E,cAAc,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QACxC,CAAC,CAAC,CAAC;QAEH,OAAO,cAAc,CAAC,KAAK,EAAE,CAAC;IAClC,CAAC;IAEO,KAAK,CAAC,aAAa,CACvB,cAAoC,EACpC,OAA0B,EAC1B,cAAsC,EACtC,iBAA4C;QAE5C,MAAM,EAAE,gBAAgB,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC;QAC/C,MAAM,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,GAAG,EAAE,cAAc,EAAE,CAAC,CAAC;QACnF,MAAM,cAAc,GAAG,gBAAgB,CAAC,KAAK,CAAC,MAAM,EAAE;YAClD,SAAS,EAAE,WAAW;YACtB,gBAAgB;YAChB,QAAQ;YACR,oBAAoB,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,aAAa,CAAC,WAAW,CAAC,WAAW;YAC7E,oBAAoB,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,aAAa,CAAC,qBAAqB,CAAC,WAAW;SAC1F,CAAC,CAAC;QACH,kDAAkD;QAClD,MAAM,cAAc,GAChB,CAAC,SAAuC,EAAE,EAAE,CAAC,GAAG,SAAS,KAAK,eAAe,CAAC,SAAS,CAAC,EAAE,CAAC;QAC/F,MAAM,IAAI,GAAG,CACT,SAAuC,EACvC,KAAW,EACX,UAAiC,EACjC,iBAAsC,EACxC,EAAE;YACA,IAAI,CAAC,qBAAqB,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC,CAAC;YACvD,gEAAgE;YAChE,oFAAoF;YACpF,MAAM,iBAAiB,GAAG,6BAA6B,CAAC,KAAK,CAAC,CAAC;YAE/D,+FAA+F;YAC/F,4FAA4F;YAC5F,oBAAoB;YACpB,MAAM,QAAQ,GAAG,iBAAiB,CAAC,SAAS,IAAI,CAAA,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,SAAS,MAAK,eAAe,CAAC,YAAY,CAAC,CAAC;gBAC/F,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC;YAExB,cAAc,CAAC,MAAM,iCACb,UAAU,KACb,MAAM,EAAE,SAAS,EACjB,QAAQ;gBACR,iBAAiB,KACnB,KAAK,CAAC,CAAC;YACV,cAAc,CAAC,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,iBAAiB,EAAE,iBAAiB,CAAC,CAAC;QAChG,CAAC,CAAC;QAEF,oCAAoC;QACpC,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,CAAC;QAC5B,oDAAoD;QACpD,IAAI,WAA4C,CAAC;QACjD,IAAI,sBAAsB,GAA0D,EAAE,CAAC;QACvF,IAAI;YACA,WAAW,GAAG,MAAM,IAAI,CAAC,qBAAqB,CAAC;gBAC3C,QAAQ;gBACR,gBAAgB;gBAChB,aAAa,EAAE,MAAM;gBACrB,iBAAiB;aACpB,CAAC,CAAC;YAEH,+EAA+E;YAC/E,MAAM,EAAE,uBAAuB,EAAE,iBAAiB,EAAE,GAAG,WAAW,CAAC;YACnE,sBAAsB,GAAG;gBACrB,uBAAuB,EAAE,iBAAiB;gBAC1C,mBAAmB,EAAE,iBAAiB,GAAG,IAAI,CAAC,aAAa,CAAC,WAAW,CAAC,iBAAiB;gBACzF,mBAAmB,EAAE,iBAAiB,GAAG,IAAI,CAAC,aAAa,CAAC,qBAAqB,CAAC,iBAAiB;aACtG,CAAC;YACF,IAAI,WAAW,CAAC,KAAK,KAAK,MAAM,EAAE;gBAC9B,sBAAsB,iDACf,sBAAsB,GACtB,WAAW,CAAC,YAAY,KAC3B,gBAAgB,EAAE,WAAW,CAAC,gBAAgB,GACjD,CAAC;gBAEF,IAAI,WAAW,CAAC,KAAK,KAAK,UAAU,EAAE;oBAClC,sBAAsB,mCACf,sBAAsB,KACzB,MAAM,EAAE,WAAW,CAAC,MAAM,EAC1B,cAAc,EAAE,WAAW,CAAC,cAAc,GAC7C,CAAC;oBAEF,IAAI,WAAW,CAAC,KAAK,KAAK,QAAQ,EAAE;wBAChC,sBAAsB,mCACf,sBAAsB,KACzB,oBAAoB,EAAE,WAAW,CAAC,oBAAoB,GACzD,CAAC;qBACL;iBACJ;aACJ;YAED,IAAI,WAAW,CAAC,KAAK,KAAK,QAAQ,EAAE;gBAChC,OAAO,IAAI,CAAC,sBAAsB,EAAE,WAAW,CAAC,KAAK,EAAE,sBAAsB,CAAC,CAAC;aAClF;YAED,0FAA0F;YAC1F,MAAM,CAAC,kBAAkB,iBAAG,SAAS,EAAE,iBAAiB,IAAK,sBAAsB,EAAG,CAAC;YACvF,cAAc,CAAC,gBAAgB,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC;SACjF;QAAC,OAAO,KAAK,EAAE;YACZ,OAAO,IAAI,CAAC,sBAAsB,EAAE,KAAK,CAAC,CAAC;SAC9C;gBAAS;YACN,IAAI,CAAC,aAAa,CAAC,aAAa,CAAC,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,uBAAuB,CAAC,CAAC;YACvE,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,CAAC;SAC/B;QAED,IAAI;YACA,MAAM,eAAe,GAAG,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,CAAC;YACrD,MAAM,OAAO,GAAG,IAAI,CAAC,cAAc,CAAC,YAAY,CAAC,WAAW,CAAC,oBAAoB,CAAC,CAAC;YAEnF,qBAAqB;YACrB,MAAM,mBAAmB,GAAG,MAAM,SAAS,CAAC,OAAO,CAAC,aAAa,EAAE,EAAE,eAAe,EAAE,iBAAiB,CAAC,CAAC;YACzG,IAAI,mBAAmB,CAAC,MAAM,KAAK,WAAW,EAAE;gBAC5C,OAAO,IAAI,CAAC,YAAY,CAAC,CAAC;aAC7B;YACD,IAAI,mBAAmB,CAAC,MAAM,KAAK,MAAM,EAAE;gBACvC,OAAO,IAAI,CAAC,sBAAsB,CAAC,CAAC;aACvC;YACD,MAAM,WAAW,GAAG,mBAAmB,CAAC,KAAK,CAAC;YAE9C,MAAM,iBAAiB,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,aAAa,CAAC,WAAW,CAAC,WAAW,CAAC;YAClF,cAAc,CAAC,oBAAoB,CAAC,OAAO,CAAC;gBACxC,OAAO,EAAE,IAAI;gBACb,IAAI,EAAE,EAAE,WAAW,EAAE,iBAAiB,EAAE;aAC3C,CAAC,CAAC;YACH,IAAI,CAAC,aAAa,CAAC,WAAW,CAAC,qBAAqB,GAAG,WAAW,CAAC,cAAc,CAAC;YAClF,MAAM,CAAC,kBAAkB,CAAC;gBACtB,SAAS,EAAE,WAAW;gBACtB,QAAQ,EAAE,iBAAiB;gBAC3B,uBAAuB,EAAE,WAAW,CAAC,uBAAuB;gBAC5D,qBAAqB,EAAE,WAAW,CAAC,cAAc;gBACjD,MAAM,EAAE,WAAW,CAAC,QAAQ,CAAC,MAAM;aACtC,CAAC,CAAC;YAEH,oBAAoB;YACpB,MAAM,iBAAiB,GAAG,MAAM,SAAS,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,eAAe,EAAE,iBAAiB,CAAC,CAAC;YACrG,IAAI,iBAAiB,CAAC,MAAM,KAAK,WAAW,EAAE;gBAC1C,OAAO,IAAI,CAAC,YAAY,CAAC,CAAC;aAC7B;YACD,IAAI,iBAAiB,CAAC,MAAM,KAAK,MAAM,EAAE;gBACrC,OAAO,IAAI,CAAC,uBAAuB,CAAC,CAAC;aACxC;YACD,MAAM,SAAS,GAAG,iBAAiB,CAAC,KAAK,CAAC;YAC1C,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,CAAC;YAE7B,6BAA6B;YAC7B,MAAM,eAAe,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,aAAa,CAAC,WAAW,CAAC,WAAW,CAAC;YAChF,MAAM,cAAc,GAA2B;gBAC3C,eAAe,EAAE,eAAe;gBAChC,cAAc,EAAE,SAAS,CAAC,cAAc;gBACxC,qBAAqB,EAAE,SAAS,CAAC,QAAQ,CAAC,eAAe,CAAC,qBAAqB;aAClF,CAAC;YACF,IAAI,SAAS,CAAC,IAAI,KAAK,WAAW,CAAC,UAAU,EAAE;gBAC3C,IAAI,CAAC,aAAa,CAAC,2BAA2B,EAAE,CAAC;gBACjD,cAAc,CAAC,GAAG,iCAAM,cAAc,KAAE,MAAM,EAAE,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,OAAO,EAAE,YAAY,IAAG,CAAC;gBACpG,cAAc,CAAC,wBAAwB,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE;wBACnE,YAAY,EAAE,SAAS;wBACvB,eAAe;qBAClB,EAAC,CAAC,CAAC;aACP;iBAAM;gBACH,gDAAgD;gBAChD,MAAM,CAAC,SAAS,CAAC,IAAI,KAAK,WAAW,CAAC,WAAW,EAAE,KAAK,CAAC,kBAAkB,CAAC,CAAC;gBAC7E,MAAM,WAAW,GAAG,SAAS,CAAC,QAAQ,CAAC;gBACvC,MAAM,OAAO,GAAG,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,OAAO,CAAC;gBACrC,MAAM,iBAAiB,GAAG,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,UAAU,CAAC;gBAElD,MAAM,KAAK,GAAG,IAAI,YAAY,CAAC,gBAAgB,OAAO,EAAE,EAAE,EAAE,iBAAiB,EAAE,CAAC,CAAC;gBACjF,MAAM,CAAC,cAAc,+BACf,SAAS,EAAE,aAAa,IAAK,sBAAsB,KAAE,iBAAiB,KAAI,KAAK,CAAC,CAAC;gBACvF,MAAM,CAAC,6BAA6B,CAAC,KAAK,CAAC,KAAK,iBAAiB,EAAE,KAAK,CAAC,yBAAyB,CAAC,CAAC;gBACpG,iGAAiG;gBACjG,OAAO,IAAI,CACP,aAAa,EACb,KAAK,kCACA,cAAc,KAAE,cAAc,EAAE,iBAAiB,KACtD,EAAE,aAAa,EAAE,SAAS,EAAE,eAAe,EAAE,CAChD,CAAC;aACL;SACJ;gBAAS;YACN,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,CAAC;SAChC;IACL,CAAC;IAEO,qBAAqB,CAAC,IAAY,EAAE,KAAa;QACrD,IAAI,CAAC,MAAM,CAAC,oBAAoB,CAAC;YAC7B,SAAS,EAAE,kBAAkB;YAC7B,WAAW,EAAE,IAAI;YACjB,YAAY,EAAE,KAAK;SACtB,CAAC,CAAC;QACH,IAAI,KAAK,GAAG,wBAAwB,EAAE;YAClC,+BAA+B;YAC/B,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,CAAC;YAC1B,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,qBAAqB,CAAC,QAAQ,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC;SAC9F;IACL,CAAC;IAEM,OAAO;QACV,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,CAAC;IAChC,CAAC;CACJ","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { ITelemetryLogger, ITelemetryProperties } from \"@fluidframework/common-definitions\";\nimport {\n assert,\n Deferred,\n IPromiseTimer,\n IPromiseTimerResult,\n Timer,\n} from \"@fluidframework/common-utils\";\nimport { MessageType } from \"@fluidframework/protocol-definitions\";\nimport { PerformanceEvent, LoggingError, ChildLogger } from \"@fluidframework/telemetry-utils\";\nimport { getRetryDelaySecondsFromError } from \"@fluidframework/driver-utils\";\nimport { DriverErrorType } from \"@fluidframework/driver-definitions\";\nimport {\n IAckSummaryResult,\n INackSummaryResult,\n ISummarizeOptions,\n IBroadcastSummaryResult,\n ISummarizeResults,\n ISummarizeHeuristicData,\n ISubmitSummaryOptions,\n SubmitSummaryResult,\n SummarizeResultPart,\n ISummaryCancellationToken,\n} from \"./summarizerTypes\";\nimport { IClientSummaryWatcher } from \"./summaryCollection\";\n\nexport type raceTimerResult<T> =\n { result: \"done\"; value: T } |\n { result: IPromiseTimerResult[\"timerResult\"] } |\n { result: \"cancelled\" };\n\n/** Helper function to wait for a promise or PromiseTimer to elapse. */\nexport async function raceTimer<T>(\n promise: Promise<T>,\n timer: Promise<IPromiseTimerResult>,\n cancellationToken?: ISummaryCancellationToken,\n): Promise<raceTimerResult<T>> {\n const promises: Promise<raceTimerResult<T>>[] = [\n promise.then((value) => ({ result: \"done\", value } as const)),\n timer.then(({ timerResult: result }) => ({ result } as const)),\n ];\n if (cancellationToken !== undefined) {\n promises.push(cancellationToken.waitCancelled.then(() => ({ result: \"cancelled\" } as const)));\n }\n return Promise.race(promises);\n}\n\n// Send some telemetry if generate summary takes too long\nconst maxSummarizeTimeoutTime = 20000; // 20 sec\nconst maxSummarizeTimeoutCount = 5; // Double and resend 5 times\n\nexport type SummarizeReason =\n /**\n * Attempt to summarize after idle timeout has elapsed.\n * Idle timer restarts whenever an op is received. So this\n * triggers only after some amount of time has passed with\n * no ops being received.\n */\n | \"idle\"\n /**\n * Attempt to summarize after a maximum time since last\n * successful summary has passed. This measures time since\n * last summary ack op was processed.\n */\n | \"maxTime\"\n /**\n * Attempt to summarize after a maximum number of ops have\n * passed since the last successful summary. This compares\n * op sequence numbers with the reference sequence number\n * of the summarize op corresponding to the last summary\n * ack op.\n */\n | \"maxOps\"\n /**\n * Special case to generate a summary in response to a Save op.\n * @deprecated - do not use save ops\n */\n | `save;${string}: ${string}`\n /**\n * Special case to attempt to summarize one last time before the\n * summarizer client closes itself. This is to prevent cases where\n * the summarizer client never gets a chance to summarize, because\n * there are too many outstanding ops and/or parent client cannot\n * stay connected long enough for summarizer client to catch up.\n */\n | \"lastSummary\"\n /** Previous summary attempt failed, and we are retrying. */\n | `retry${number}`\n /** On-demand summary requested with specified reason. */\n | `onDemand;${string}`\n /** Enqueue summarize attempt with specified reason. */\n | `enqueue;${string}`;\n\nconst summarizeErrors = {\n /**\n * Error encountered while generating the summary tree, uploading\n * it to storage, or submitting the op. It could be a result of\n * the client becoming disconnected while generating or an actual error.\n */\n submitSummaryFailure: \"Error while generating, uploading, or submitting summary\",\n /**\n * The summaryAckWaitTimeout time has elapsed before receiving the summarize op\n * sent by this summarize attempt. It is expected to be broadcast quickly.\n */\n summaryOpWaitTimeout: \"Timeout while waiting for summarize op broadcast\",\n /**\n * The summaryAckWaitTimeout time has elapsed before receiving either a\n * summaryAck or summaryNack op from the server in response to this\n * summarize attempt. It is expected that the server should respond.\n */\n summaryAckWaitTimeout: \"Timeout while waiting for summaryAck/summaryNack op\",\n /**\n * The server responded with a summaryNack op, thus rejecting this\n * summarize attempt.\n */\n summaryNack: \"Server rejected summary via summaryNack op\",\n\n disconnect: \"Summary cancelled due to summarizer or main client disconnect\",\n} as const;\n\nexport class SummarizeResultBuilder {\n public readonly summarySubmitted = new Deferred<SummarizeResultPart<SubmitSummaryResult>>();\n public readonly summaryOpBroadcasted = new Deferred<SummarizeResultPart<IBroadcastSummaryResult>>();\n public readonly receivedSummaryAckOrNack =\n new Deferred<SummarizeResultPart<IAckSummaryResult, INackSummaryResult>>();\n\n public fail(message: string, error: any, nackSummaryResult?: INackSummaryResult, retryAfterSeconds?: number) {\n assert(!this.receivedSummaryAckOrNack.isCompleted,\n 0x25e /* \"no reason to call fail if all promises have been completed\" */);\n\n const result: SummarizeResultPart<undefined> =\n { success: false, message, data: undefined, error, retryAfterSeconds } as const;\n this.summarySubmitted.resolve(result);\n this.summaryOpBroadcasted.resolve(result);\n this.receivedSummaryAckOrNack.resolve({ ...result, data: nackSummaryResult });\n }\n public build(): ISummarizeResults {\n return {\n summarySubmitted: this.summarySubmitted.promise,\n summaryOpBroadcasted: this.summaryOpBroadcasted.promise,\n receivedSummaryAckOrNack: this.receivedSummaryAckOrNack.promise,\n } as const;\n }\n}\n\n/**\n * This class generates and tracks a summary attempt.\n */\nexport class SummaryGenerator {\n private readonly summarizeTimer: Timer;\n constructor(\n private readonly pendingAckTimer: IPromiseTimer,\n private readonly heuristicData: ISummarizeHeuristicData,\n private readonly submitSummaryCallback: (options: ISubmitSummaryOptions) => Promise<SubmitSummaryResult>,\n private readonly raiseSummarizingError: (errorCode: string) => void,\n private readonly summaryWatcher: Pick<IClientSummaryWatcher, \"watchSummary\">,\n private readonly logger: ITelemetryLogger,\n ) {\n this.summarizeTimer = new Timer(\n maxSummarizeTimeoutTime,\n () => this.summarizeTimerHandler(maxSummarizeTimeoutTime, 1),\n );\n }\n\n /**\n * Generates summary and listens for broadcast and ack/nack.\n * Returns true for ack, false for nack, and undefined for failure or timeout.\n * @param reason - reason for summarizing\n * @param options - refreshLatestAck to fetch summary ack info from server,\n * fullTree to generate tree without any summary handles even if unchanged\n */\n public summarize(\n summarizeProps: ITelemetryProperties,\n options: ISummarizeOptions,\n cancellationToken: ISummaryCancellationToken,\n resultsBuilder = new SummarizeResultBuilder(),\n ): ISummarizeResults {\n this.summarizeCore(summarizeProps, options, resultsBuilder, cancellationToken)\n .catch((error) => {\n const message = \"UnexpectedSummarizeError\";\n this.logger.sendErrorEvent({ eventName: message, ...summarizeProps }, error);\n resultsBuilder.fail(message, error);\n });\n\n return resultsBuilder.build();\n }\n\n private async summarizeCore(\n summarizeProps: ITelemetryProperties,\n options: ISummarizeOptions,\n resultsBuilder: SummarizeResultBuilder,\n cancellationToken: ISummaryCancellationToken,\n ): Promise<void> {\n const { refreshLatestAck, fullTree } = options;\n const logger = ChildLogger.create(this.logger, undefined, { all: summarizeProps });\n const summarizeEvent = PerformanceEvent.start(logger, {\n eventName: \"Summarize\",\n refreshLatestAck,\n fullTree,\n timeSinceLastAttempt: Date.now() - this.heuristicData.lastAttempt.summaryTime,\n timeSinceLastSummary: Date.now() - this.heuristicData.lastSuccessfulSummary.summaryTime,\n });\n // Helper functions to report failures and return.\n const getFailMessage =\n (errorCode: keyof typeof summarizeErrors) => `${errorCode}: ${summarizeErrors[errorCode]}`;\n const fail = (\n errorCode: keyof typeof summarizeErrors,\n error?: any,\n properties?: ITelemetryProperties,\n nackSummaryResult?: INackSummaryResult,\n ) => {\n this.raiseSummarizingError(summarizeErrors[errorCode]);\n // UploadSummary may fail with 429 and retryAfter - respect that\n // Summary Nack also can have retryAfter, it's parsed below and comes as a property.\n const retryAfterSeconds = getRetryDelaySecondsFromError(error);\n\n // Report any failure as an error unless it was due to cancellation (like \"disconnected\" error)\n // If failure happened on upload, we may not yet realized that socket disconnected, so check\n // offlineError too.\n const category = cancellationToken.cancelled || error?.errorType === DriverErrorType.offlineError ?\n \"generic\" : \"error\";\n\n summarizeEvent.cancel({\n ...properties,\n reason: errorCode,\n category,\n retryAfterSeconds,\n }, error);\n resultsBuilder.fail(getFailMessage(errorCode), error, nackSummaryResult, retryAfterSeconds);\n };\n\n // Wait to generate and send summary\n this.summarizeTimer.start();\n // Use record type to prevent unexpected value types\n let summaryData: SubmitSummaryResult | undefined;\n let generateTelemetryProps: Record<string, string | number | boolean | undefined> = {};\n try {\n summaryData = await this.submitSummaryCallback({\n fullTree,\n refreshLatestAck,\n summaryLogger: logger,\n cancellationToken,\n });\n\n // Cumulatively add telemetry properties based on how far generateSummary went.\n const { referenceSequenceNumber: refSequenceNumber } = summaryData;\n generateTelemetryProps = {\n referenceSequenceNumber: refSequenceNumber,\n opsSinceLastAttempt: refSequenceNumber - this.heuristicData.lastAttempt.refSequenceNumber,\n opsSinceLastSummary: refSequenceNumber - this.heuristicData.lastSuccessfulSummary.refSequenceNumber,\n };\n if (summaryData.stage !== \"base\") {\n generateTelemetryProps = {\n ...generateTelemetryProps,\n ...summaryData.summaryStats,\n generateDuration: summaryData.generateDuration,\n };\n\n if (summaryData.stage !== \"generate\") {\n generateTelemetryProps = {\n ...generateTelemetryProps,\n handle: summaryData.handle,\n uploadDuration: summaryData.uploadDuration,\n };\n\n if (summaryData.stage !== \"upload\") {\n generateTelemetryProps = {\n ...generateTelemetryProps,\n clientSequenceNumber: summaryData.clientSequenceNumber,\n };\n }\n }\n }\n\n if (summaryData.stage !== \"submit\") {\n return fail(\"submitSummaryFailure\", summaryData.error, generateTelemetryProps);\n }\n\n // Log event here on summary success only, as Summarize_cancel duplicates failure logging.\n logger.sendTelemetryEvent({ eventName: \"GenerateSummary\", ...generateTelemetryProps });\n resultsBuilder.summarySubmitted.resolve({ success: true, data: summaryData });\n } catch (error) {\n return fail(\"submitSummaryFailure\", error);\n } finally {\n this.heuristicData.recordAttempt(summaryData?.referenceSequenceNumber);\n this.summarizeTimer.clear();\n }\n\n try {\n const pendingTimeoutP = this.pendingAckTimer.start();\n const summary = this.summaryWatcher.watchSummary(summaryData.clientSequenceNumber);\n\n // Wait for broadcast\n const waitBroadcastResult = await raceTimer(summary.waitBroadcast(), pendingTimeoutP, cancellationToken);\n if (waitBroadcastResult.result === \"cancelled\") {\n return fail(\"disconnect\");\n }\n if (waitBroadcastResult.result !== \"done\") {\n return fail(\"summaryOpWaitTimeout\");\n }\n const summarizeOp = waitBroadcastResult.value;\n\n const broadcastDuration = Date.now() - this.heuristicData.lastAttempt.summaryTime;\n resultsBuilder.summaryOpBroadcasted.resolve({\n success: true,\n data: { summarizeOp, broadcastDuration },\n });\n this.heuristicData.lastAttempt.summarySequenceNumber = summarizeOp.sequenceNumber;\n logger.sendTelemetryEvent({\n eventName: \"SummaryOp\",\n duration: broadcastDuration,\n referenceSequenceNumber: summarizeOp.referenceSequenceNumber,\n summarySequenceNumber: summarizeOp.sequenceNumber,\n handle: summarizeOp.contents.handle,\n });\n\n // Wait for ack/nack\n const waitAckNackResult = await raceTimer(summary.waitAckNack(), pendingTimeoutP, cancellationToken);\n if (waitAckNackResult.result === \"cancelled\") {\n return fail(\"disconnect\");\n }\n if (waitAckNackResult.result !== \"done\") {\n return fail(\"summaryAckWaitTimeout\");\n }\n const ackNackOp = waitAckNackResult.value;\n this.pendingAckTimer.clear();\n\n // Update for success/failure\n const ackNackDuration = Date.now() - this.heuristicData.lastAttempt.summaryTime;\n const telemetryProps: Record<string, number> = {\n ackWaitDuration: ackNackDuration,\n sequenceNumber: ackNackOp.sequenceNumber,\n summarySequenceNumber: ackNackOp.contents.summaryProposal.summarySequenceNumber,\n };\n if (ackNackOp.type === MessageType.SummaryAck) {\n this.heuristicData.markLastAttemptAsSuccessful();\n summarizeEvent.end({ ...telemetryProps, handle: ackNackOp.contents.handle, message: \"summaryAck\" });\n resultsBuilder.receivedSummaryAckOrNack.resolve({ success: true, data: {\n summaryAckOp: ackNackOp,\n ackNackDuration,\n }});\n } else {\n // Check for retryDelay in summaryNack response.\n assert(ackNackOp.type === MessageType.SummaryNack, 0x274 /* \"type check\" */);\n const summaryNack = ackNackOp.contents;\n const message = summaryNack?.message;\n const retryAfterSeconds = summaryNack?.retryAfter;\n\n const error = new LoggingError(`summaryNack: ${message}`, { retryAfterSeconds });\n logger.sendErrorEvent(\n { eventName: \"SummaryNack\", ...generateTelemetryProps, retryAfterSeconds }, error);\n assert(getRetryDelaySecondsFromError(error) === retryAfterSeconds, 0x25f /* \"retryAfterSeconds\" */);\n // This will only set resultsBuilder.receivedSummaryAckOrNack, as other promises are already set.\n return fail(\n \"summaryNack\",\n error,\n { ...telemetryProps, nackRetryAfter: retryAfterSeconds },\n { summaryNackOp: ackNackOp, ackNackDuration },\n );\n }\n } finally {\n this.pendingAckTimer.clear();\n }\n }\n\n private summarizeTimerHandler(time: number, count: number) {\n this.logger.sendPerformanceEvent({\n eventName: \"SummarizeTimeout\",\n timeoutTime: time,\n timeoutCount: count,\n });\n if (count < maxSummarizeTimeoutCount) {\n // Double and start a new timer\n const nextTime = time * 2;\n this.summarizeTimer.start(nextTime, () => this.summarizeTimerHandler(nextTime, count + 1));\n }\n }\n\n public dispose() {\n this.summarizeTimer.clear();\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"summaryGenerator.js","sourceRoot":"","sources":["../src/summaryGenerator.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { ITelemetryLogger, ITelemetryProperties } from \"@fluidframework/common-definitions\";\nimport {\n assert,\n Deferred,\n IPromiseTimer,\n IPromiseTimerResult,\n Timer,\n} from \"@fluidframework/common-utils\";\nimport { MessageType } from \"@fluidframework/protocol-definitions\";\nimport { PerformanceEvent, LoggingError, ChildLogger } from \"@fluidframework/telemetry-utils\";\nimport { getRetryDelaySecondsFromError } from \"@fluidframework/driver-utils\";\nimport { DriverErrorType } from \"@fluidframework/driver-definitions\";\nimport {\n IAckSummaryResult,\n INackSummaryResult,\n ISummarizeOptions,\n IBroadcastSummaryResult,\n ISummarizeResults,\n ISummarizeHeuristicData,\n ISubmitSummaryOptions,\n SubmitSummaryResult,\n SummarizeResultPart,\n ISummaryCancellationToken,\n} from \"./summarizerTypes\";\nimport { IClientSummaryWatcher } from \"./summaryCollection\";\n\nexport type raceTimerResult<T> =\n { result: \"done\"; value: T } |\n { result: IPromiseTimerResult[\"timerResult\"] } |\n { result: \"cancelled\" };\n\n/** Helper function to wait for a promise or PromiseTimer to elapse. */\nexport async function raceTimer<T>(\n promise: Promise<T>,\n timer: Promise<IPromiseTimerResult>,\n cancellationToken?: ISummaryCancellationToken,\n): Promise<raceTimerResult<T>> {\n const promises: Promise<raceTimerResult<T>>[] = [\n promise.then((value) => ({ result: \"done\", value } as const)),\n timer.then(({ timerResult: result }) => ({ result } as const)),\n ];\n if (cancellationToken !== undefined) {\n promises.push(cancellationToken.waitCancelled.then(() => ({ result: \"cancelled\" } as const)));\n }\n return Promise.race(promises);\n}\n\n// Send some telemetry if generate summary takes too long\nconst maxSummarizeTimeoutTime = 20000; // 20 sec\nconst maxSummarizeTimeoutCount = 5; // Double and resend 5 times\n\nexport type SummarizeReason =\n /**\n * Attempt to summarize after idle timeout has elapsed.\n * Idle timer restarts whenever an op is received. So this\n * triggers only after some amount of time has passed with\n * no ops being received.\n */\n | \"idle\"\n /**\n * Attempt to summarize after a maximum time since last\n * successful summary has passed. This measures time since\n * last summary ack op was processed.\n */\n | \"maxTime\"\n /**\n * Attempt to summarize after a maximum number of ops have\n * passed since the last successful summary. This compares\n * op sequence numbers with the reference sequence number\n * of the summarize op corresponding to the last summary\n * ack op.\n */\n | \"maxOps\"\n /**\n * Special case to attempt to summarize one last time before the\n * summarizer client closes itself. This is to prevent cases where\n * the summarizer client never gets a chance to summarize, because\n * there are too many outstanding ops and/or parent client cannot\n * stay connected long enough for summarizer client to catch up.\n */\n | \"lastSummary\"\n /** Previous summary attempt failed, and we are retrying. */\n | `retry${number}`\n /** On-demand summary requested with specified reason. */\n | `onDemand;${string}`\n /** Enqueue summarize attempt with specified reason. */\n | `enqueue;${string}`;\n\nconst summarizeErrors = {\n /**\n * Error encountered while generating the summary tree, uploading\n * it to storage, or submitting the op. It could be a result of\n * the client becoming disconnected while generating or an actual error.\n */\n submitSummaryFailure: \"Error while generating, uploading, or submitting summary\",\n /**\n * The summaryAckWaitTimeout time has elapsed before receiving the summarize op\n * sent by this summarize attempt. It is expected to be broadcast quickly.\n */\n summaryOpWaitTimeout: \"Timeout while waiting for summarize op broadcast\",\n /**\n * The summaryAckWaitTimeout time has elapsed before receiving either a\n * summaryAck or summaryNack op from the server in response to this\n * summarize attempt. It is expected that the server should respond.\n */\n summaryAckWaitTimeout: \"Timeout while waiting for summaryAck/summaryNack op\",\n /**\n * The server responded with a summaryNack op, thus rejecting this\n * summarize attempt.\n */\n summaryNack: \"Server rejected summary via summaryNack op\",\n\n disconnect: \"Summary cancelled due to summarizer or main client disconnect\",\n} as const;\n\nexport class SummarizeResultBuilder {\n public readonly summarySubmitted = new Deferred<SummarizeResultPart<SubmitSummaryResult>>();\n public readonly summaryOpBroadcasted = new Deferred<SummarizeResultPart<IBroadcastSummaryResult>>();\n public readonly receivedSummaryAckOrNack =\n new Deferred<SummarizeResultPart<IAckSummaryResult, INackSummaryResult>>();\n\n public fail(message: string, error: any, nackSummaryResult?: INackSummaryResult, retryAfterSeconds?: number) {\n assert(!this.receivedSummaryAckOrNack.isCompleted,\n 0x25e /* \"no reason to call fail if all promises have been completed\" */);\n\n const result: SummarizeResultPart<undefined> =\n { success: false, message, data: undefined, error, retryAfterSeconds } as const;\n this.summarySubmitted.resolve(result);\n this.summaryOpBroadcasted.resolve(result);\n this.receivedSummaryAckOrNack.resolve({ ...result, data: nackSummaryResult });\n }\n public build(): ISummarizeResults {\n return {\n summarySubmitted: this.summarySubmitted.promise,\n summaryOpBroadcasted: this.summaryOpBroadcasted.promise,\n receivedSummaryAckOrNack: this.receivedSummaryAckOrNack.promise,\n } as const;\n }\n}\n\n/**\n * This class generates and tracks a summary attempt.\n */\nexport class SummaryGenerator {\n private readonly summarizeTimer: Timer;\n constructor(\n private readonly pendingAckTimer: IPromiseTimer,\n private readonly heuristicData: ISummarizeHeuristicData,\n private readonly submitSummaryCallback: (options: ISubmitSummaryOptions) => Promise<SubmitSummaryResult>,\n private readonly raiseSummarizingError: (errorCode: string) => void,\n private readonly summaryWatcher: Pick<IClientSummaryWatcher, \"watchSummary\">,\n private readonly logger: ITelemetryLogger,\n ) {\n this.summarizeTimer = new Timer(\n maxSummarizeTimeoutTime,\n () => this.summarizeTimerHandler(maxSummarizeTimeoutTime, 1),\n );\n }\n\n /**\n * Generates summary and listens for broadcast and ack/nack.\n * Returns true for ack, false for nack, and undefined for failure or timeout.\n * @param reason - reason for summarizing\n * @param options - refreshLatestAck to fetch summary ack info from server,\n * fullTree to generate tree without any summary handles even if unchanged\n */\n public summarize(\n summarizeProps: ITelemetryProperties,\n options: ISummarizeOptions,\n cancellationToken: ISummaryCancellationToken,\n resultsBuilder = new SummarizeResultBuilder(),\n ): ISummarizeResults {\n this.summarizeCore(summarizeProps, options, resultsBuilder, cancellationToken)\n .catch((error) => {\n const message = \"UnexpectedSummarizeError\";\n this.logger.sendErrorEvent({ eventName: message, ...summarizeProps }, error);\n resultsBuilder.fail(message, error);\n });\n\n return resultsBuilder.build();\n }\n\n private async summarizeCore(\n summarizeProps: ITelemetryProperties,\n options: ISummarizeOptions,\n resultsBuilder: SummarizeResultBuilder,\n cancellationToken: ISummaryCancellationToken,\n ): Promise<void> {\n const { refreshLatestAck, fullTree } = options;\n const logger = ChildLogger.create(this.logger, undefined, { all: summarizeProps });\n const summarizeEvent = PerformanceEvent.start(logger, {\n eventName: \"Summarize\",\n refreshLatestAck,\n fullTree,\n timeSinceLastAttempt: Date.now() - this.heuristicData.lastAttempt.summaryTime,\n timeSinceLastSummary: Date.now() - this.heuristicData.lastSuccessfulSummary.summaryTime,\n });\n // Helper functions to report failures and return.\n const getFailMessage =\n (errorCode: keyof typeof summarizeErrors) => `${errorCode}: ${summarizeErrors[errorCode]}`;\n const fail = (\n errorCode: keyof typeof summarizeErrors,\n error?: any,\n properties?: ITelemetryProperties,\n nackSummaryResult?: INackSummaryResult,\n ) => {\n this.raiseSummarizingError(summarizeErrors[errorCode]);\n // UploadSummary may fail with 429 and retryAfter - respect that\n // Summary Nack also can have retryAfter, it's parsed below and comes as a property.\n const retryAfterSeconds = getRetryDelaySecondsFromError(error);\n\n // Report any failure as an error unless it was due to cancellation (like \"disconnected\" error)\n // If failure happened on upload, we may not yet realized that socket disconnected, so check\n // offlineError too.\n const category = cancellationToken.cancelled || error?.errorType === DriverErrorType.offlineError ?\n \"generic\" : \"error\";\n\n summarizeEvent.cancel({\n ...properties,\n reason: errorCode,\n category,\n retryAfterSeconds,\n }, error);\n resultsBuilder.fail(getFailMessage(errorCode), error, nackSummaryResult, retryAfterSeconds);\n };\n\n // Wait to generate and send summary\n this.summarizeTimer.start();\n // Use record type to prevent unexpected value types\n let summaryData: SubmitSummaryResult | undefined;\n let generateTelemetryProps: Record<string, string | number | boolean | undefined> = {};\n try {\n summaryData = await this.submitSummaryCallback({\n fullTree,\n refreshLatestAck,\n summaryLogger: logger,\n cancellationToken,\n });\n\n // Cumulatively add telemetry properties based on how far generateSummary went.\n const { referenceSequenceNumber: refSequenceNumber } = summaryData;\n generateTelemetryProps = {\n referenceSequenceNumber: refSequenceNumber,\n opsSinceLastAttempt: refSequenceNumber - this.heuristicData.lastAttempt.refSequenceNumber,\n opsSinceLastSummary: refSequenceNumber - this.heuristicData.lastSuccessfulSummary.refSequenceNumber,\n };\n if (summaryData.stage !== \"base\") {\n generateTelemetryProps = {\n ...generateTelemetryProps,\n ...summaryData.summaryStats,\n generateDuration: summaryData.generateDuration,\n };\n\n if (summaryData.stage !== \"generate\") {\n generateTelemetryProps = {\n ...generateTelemetryProps,\n handle: summaryData.handle,\n uploadDuration: summaryData.uploadDuration,\n };\n\n if (summaryData.stage !== \"upload\") {\n generateTelemetryProps = {\n ...generateTelemetryProps,\n clientSequenceNumber: summaryData.clientSequenceNumber,\n };\n }\n }\n }\n\n if (summaryData.stage !== \"submit\") {\n return fail(\"submitSummaryFailure\", summaryData.error, generateTelemetryProps);\n }\n\n // Log event here on summary success only, as Summarize_cancel duplicates failure logging.\n logger.sendTelemetryEvent({ eventName: \"GenerateSummary\", ...generateTelemetryProps });\n resultsBuilder.summarySubmitted.resolve({ success: true, data: summaryData });\n } catch (error) {\n return fail(\"submitSummaryFailure\", error);\n } finally {\n this.heuristicData.recordAttempt(summaryData?.referenceSequenceNumber);\n this.summarizeTimer.clear();\n }\n\n try {\n const pendingTimeoutP = this.pendingAckTimer.start();\n const summary = this.summaryWatcher.watchSummary(summaryData.clientSequenceNumber);\n\n // Wait for broadcast\n const waitBroadcastResult = await raceTimer(summary.waitBroadcast(), pendingTimeoutP, cancellationToken);\n if (waitBroadcastResult.result === \"cancelled\") {\n return fail(\"disconnect\");\n }\n if (waitBroadcastResult.result !== \"done\") {\n return fail(\"summaryOpWaitTimeout\");\n }\n const summarizeOp = waitBroadcastResult.value;\n\n const broadcastDuration = Date.now() - this.heuristicData.lastAttempt.summaryTime;\n resultsBuilder.summaryOpBroadcasted.resolve({\n success: true,\n data: { summarizeOp, broadcastDuration },\n });\n this.heuristicData.lastAttempt.summarySequenceNumber = summarizeOp.sequenceNumber;\n logger.sendTelemetryEvent({\n eventName: \"SummaryOp\",\n duration: broadcastDuration,\n referenceSequenceNumber: summarizeOp.referenceSequenceNumber,\n summarySequenceNumber: summarizeOp.sequenceNumber,\n handle: summarizeOp.contents.handle,\n });\n\n // Wait for ack/nack\n const waitAckNackResult = await raceTimer(summary.waitAckNack(), pendingTimeoutP, cancellationToken);\n if (waitAckNackResult.result === \"cancelled\") {\n return fail(\"disconnect\");\n }\n if (waitAckNackResult.result !== \"done\") {\n return fail(\"summaryAckWaitTimeout\");\n }\n const ackNackOp = waitAckNackResult.value;\n this.pendingAckTimer.clear();\n\n // Update for success/failure\n const ackNackDuration = Date.now() - this.heuristicData.lastAttempt.summaryTime;\n const telemetryProps: Record<string, number> = {\n ackWaitDuration: ackNackDuration,\n sequenceNumber: ackNackOp.sequenceNumber,\n summarySequenceNumber: ackNackOp.contents.summaryProposal.summarySequenceNumber,\n };\n if (ackNackOp.type === MessageType.SummaryAck) {\n this.heuristicData.markLastAttemptAsSuccessful();\n summarizeEvent.end({ ...telemetryProps, handle: ackNackOp.contents.handle, message: \"summaryAck\" });\n resultsBuilder.receivedSummaryAckOrNack.resolve({ success: true, data: {\n summaryAckOp: ackNackOp,\n ackNackDuration,\n }});\n } else {\n // Check for retryDelay in summaryNack response.\n assert(ackNackOp.type === MessageType.SummaryNack, 0x274 /* \"type check\" */);\n const summaryNack = ackNackOp.contents;\n const message = summaryNack?.message;\n const retryAfterSeconds = summaryNack?.retryAfter;\n\n const error = new LoggingError(`summaryNack: ${message}`, { retryAfterSeconds });\n logger.sendErrorEvent(\n { eventName: \"SummaryNack\", ...generateTelemetryProps, retryAfterSeconds }, error);\n assert(getRetryDelaySecondsFromError(error) === retryAfterSeconds, 0x25f /* \"retryAfterSeconds\" */);\n // This will only set resultsBuilder.receivedSummaryAckOrNack, as other promises are already set.\n return fail(\n \"summaryNack\",\n error,\n { ...telemetryProps, nackRetryAfter: retryAfterSeconds },\n { summaryNackOp: ackNackOp, ackNackDuration },\n );\n }\n } finally {\n this.pendingAckTimer.clear();\n }\n }\n\n private summarizeTimerHandler(time: number, count: number) {\n this.logger.sendPerformanceEvent({\n eventName: \"SummarizeTimeout\",\n timeoutTime: time,\n timeoutCount: count,\n });\n if (count < maxSummarizeTimeoutCount) {\n // Double and start a new timer\n const nextTime = time * 2;\n this.summarizeTimer.start(nextTime, () => this.summarizeTimerHandler(nextTime, count + 1));\n }\n }\n\n public dispose() {\n this.summarizeTimer.clear();\n }\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fluidframework/container-runtime",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.56.0-49831",
|
|
4
4
|
"description": "Fluid container runtime",
|
|
5
5
|
"homepage": "https://fluidframework.com",
|
|
6
6
|
"repository": "https://github.com/microsoft/FluidFramework",
|
|
@@ -58,27 +58,27 @@
|
|
|
58
58
|
"dependencies": {
|
|
59
59
|
"@fluidframework/common-definitions": "^0.20.1",
|
|
60
60
|
"@fluidframework/common-utils": "^0.32.1",
|
|
61
|
-
"@fluidframework/container-definitions": "^0.
|
|
62
|
-
"@fluidframework/container-runtime-definitions": "
|
|
63
|
-
"@fluidframework/container-utils": "
|
|
64
|
-
"@fluidframework/core-interfaces": "^0.
|
|
65
|
-
"@fluidframework/datastore": "
|
|
66
|
-
"@fluidframework/driver-definitions": "^0.
|
|
67
|
-
"@fluidframework/driver-utils": "
|
|
68
|
-
"@fluidframework/garbage-collector": "
|
|
61
|
+
"@fluidframework/container-definitions": "^0.45.0-0",
|
|
62
|
+
"@fluidframework/container-runtime-definitions": "0.56.0-49831",
|
|
63
|
+
"@fluidframework/container-utils": "0.56.0-49831",
|
|
64
|
+
"@fluidframework/core-interfaces": "^0.42.0-0",
|
|
65
|
+
"@fluidframework/datastore": "0.56.0-49831",
|
|
66
|
+
"@fluidframework/driver-definitions": "^0.44.0-0",
|
|
67
|
+
"@fluidframework/driver-utils": "0.56.0-49831",
|
|
68
|
+
"@fluidframework/garbage-collector": "0.56.0-49831",
|
|
69
69
|
"@fluidframework/protocol-base": "^0.1034.0",
|
|
70
70
|
"@fluidframework/protocol-definitions": "^0.1026.0",
|
|
71
|
-
"@fluidframework/runtime-definitions": "
|
|
72
|
-
"@fluidframework/runtime-utils": "
|
|
73
|
-
"@fluidframework/telemetry-utils": "
|
|
71
|
+
"@fluidframework/runtime-definitions": "0.56.0-49831",
|
|
72
|
+
"@fluidframework/runtime-utils": "0.56.0-49831",
|
|
73
|
+
"@fluidframework/telemetry-utils": "0.56.0-49831",
|
|
74
74
|
"double-ended-queue": "^2.1.0-0",
|
|
75
75
|
"uuid": "^8.3.1"
|
|
76
76
|
},
|
|
77
77
|
"devDependencies": {
|
|
78
78
|
"@fluidframework/build-common": "^0.23.0",
|
|
79
79
|
"@fluidframework/eslint-config-fluid": "^0.25.0",
|
|
80
|
-
"@fluidframework/mocha-test-setup": "
|
|
81
|
-
"@fluidframework/test-runtime-utils": "
|
|
80
|
+
"@fluidframework/mocha-test-setup": "0.56.0-49831",
|
|
81
|
+
"@fluidframework/test-runtime-utils": "0.56.0-49831",
|
|
82
82
|
"@microsoft/api-extractor": "^7.16.1",
|
|
83
83
|
"@rushstack/eslint-config": "^2.5.1",
|
|
84
84
|
"@types/double-ended-queue": "^2.1.0",
|
package/src/containerRuntime.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import { EventEmitter } from "events";
|
|
7
|
-
import { ITelemetryGenericEvent, ITelemetryLogger } from "@fluidframework/common-definitions";
|
|
7
|
+
import { ITelemetryBaseLogger, ITelemetryGenericEvent, ITelemetryLogger } from "@fluidframework/common-definitions";
|
|
8
8
|
import {
|
|
9
9
|
FluidObject,
|
|
10
10
|
IFluidHandle,
|
|
@@ -50,7 +50,6 @@ import {
|
|
|
50
50
|
import { DriverHeader, IDocumentStorageService, ISummaryContext } from "@fluidframework/driver-definitions";
|
|
51
51
|
import { readAndParse, BlobAggregationStorage } from "@fluidframework/driver-utils";
|
|
52
52
|
import {
|
|
53
|
-
CreateProcessingError,
|
|
54
53
|
DataCorruptionError,
|
|
55
54
|
GenericError,
|
|
56
55
|
UsageError,
|
|
@@ -290,6 +289,16 @@ type IRuntimeMessageMetadata = undefined | {
|
|
|
290
289
|
batch?: boolean;
|
|
291
290
|
};
|
|
292
291
|
|
|
292
|
+
/**
|
|
293
|
+
* @deprecated
|
|
294
|
+
* Untagged logger is unsupported going forward. There are old loaders with old ContainerContexts that only
|
|
295
|
+
* have the untagged logger, so to accommodate that scenario the below interface is used. It can be removed once
|
|
296
|
+
* its usage is removed from TaggedLoggerAdapter fallback.
|
|
297
|
+
*/
|
|
298
|
+
interface OldContainerContextWithLogger extends IContainerContext {
|
|
299
|
+
logger: ITelemetryBaseLogger;
|
|
300
|
+
};
|
|
301
|
+
|
|
293
302
|
// Local storage key to set the default flush mode to TurnBased
|
|
294
303
|
const turnBasedFlushModeKey = "Fluid.ContainerRuntime.FlushModeTurnBased";
|
|
295
304
|
|
|
@@ -642,7 +651,9 @@ export class ContainerRuntime extends TypedEventEmitter<IContainerRuntimeEvents>
|
|
|
642
651
|
existing?: boolean,
|
|
643
652
|
): Promise<ContainerRuntime> {
|
|
644
653
|
// If taggedLogger exists, use it. Otherwise, wrap the vanilla logger:
|
|
645
|
-
|
|
654
|
+
// back-compat: Remove the TaggedLoggerAdapter fallback once all the host are using loader > 0.45
|
|
655
|
+
const passLogger = context.taggedLogger ?? new TaggedLoggerAdapter((context as
|
|
656
|
+
OldContainerContextWithLogger).logger);
|
|
646
657
|
const logger = ChildLogger.create(passLogger, undefined, {
|
|
647
658
|
all: {
|
|
648
659
|
runtimeVersion: pkgVersion,
|
|
@@ -758,13 +769,6 @@ export class ContainerRuntime extends TypedEventEmitter<IContainerRuntimeEvents>
|
|
|
758
769
|
return runtime;
|
|
759
770
|
}
|
|
760
771
|
|
|
761
|
-
/**
|
|
762
|
-
* @deprecated This will be removed in a later release. Deprecated in 0.53
|
|
763
|
-
*/
|
|
764
|
-
public get id(): string {
|
|
765
|
-
return this.context.id;
|
|
766
|
-
}
|
|
767
|
-
|
|
768
772
|
public get options(): ILoaderOptions {
|
|
769
773
|
return this.context.options;
|
|
770
774
|
}
|
|
@@ -885,6 +889,9 @@ export class ContainerRuntime extends TypedEventEmitter<IContainerRuntimeEvents>
|
|
|
885
889
|
|
|
886
890
|
private dirtyContainer = false;
|
|
887
891
|
private emitDirtyDocumentEvent = true;
|
|
892
|
+
|
|
893
|
+
private summarizerWarning = (warning: ContainerWarning) =>
|
|
894
|
+
this.mc.logger.sendTelemetryEvent({ eventName: "summarizerWarning" }, warning);
|
|
888
895
|
/**
|
|
889
896
|
* Summarizer is responsible for coordinating when to send generate and send summaries.
|
|
890
897
|
* It is the main entry point for summary work.
|
|
@@ -902,14 +909,6 @@ export class ContainerRuntime extends TypedEventEmitter<IContainerRuntimeEvents>
|
|
|
902
909
|
|
|
903
910
|
private readonly dataStores: DataStores;
|
|
904
911
|
|
|
905
|
-
/**
|
|
906
|
-
* True, if GC data should be written at root of the summary tree.
|
|
907
|
-
* False, if data stores should write GC blobs in their summary tree.
|
|
908
|
-
*/
|
|
909
|
-
public get writeGCDataAtRoot(): boolean {
|
|
910
|
-
return this.garbageCollector.writeDataAtRoot;
|
|
911
|
-
}
|
|
912
|
-
|
|
913
912
|
/**
|
|
914
913
|
* True if generating summaries with isolated channels is
|
|
915
914
|
* explicitly disabled. This only affects how summaries are written,
|
|
@@ -1051,6 +1050,7 @@ export class ContainerRuntime extends TypedEventEmitter<IContainerRuntimeEvents>
|
|
|
1051
1050
|
async () => this.garbageCollector.getDataStoreBaseGCDetails(),
|
|
1052
1051
|
(id: string) => this.garbageCollector.nodeChanged(id),
|
|
1053
1052
|
new Map<string, string>(dataStoreAliasMap),
|
|
1053
|
+
this.garbageCollector.writeDataAtRoot,
|
|
1054
1054
|
);
|
|
1055
1055
|
|
|
1056
1056
|
this.blobManager = new BlobManager(
|
|
@@ -1165,7 +1165,7 @@ export class ContainerRuntime extends TypedEventEmitter<IContainerRuntimeEvents>
|
|
|
1165
1165
|
},
|
|
1166
1166
|
this.runtimeOptions.summaryOptions.summarizerOptions,
|
|
1167
1167
|
);
|
|
1168
|
-
this.summaryManager.on("summarizerWarning", this.
|
|
1168
|
+
this.summaryManager.on("summarizerWarning", this.summarizerWarning);
|
|
1169
1169
|
this.summaryManager.start();
|
|
1170
1170
|
}
|
|
1171
1171
|
}
|
|
@@ -1231,7 +1231,7 @@ export class ContainerRuntime extends TypedEventEmitter<IContainerRuntimeEvents>
|
|
|
1231
1231
|
}, error);
|
|
1232
1232
|
|
|
1233
1233
|
if (this.summaryManager !== undefined) {
|
|
1234
|
-
this.summaryManager.off("summarizerWarning", this.
|
|
1234
|
+
this.summaryManager.off("summarizerWarning", this.summarizerWarning);
|
|
1235
1235
|
this.summaryManager.dispose();
|
|
1236
1236
|
}
|
|
1237
1237
|
this.garbageCollector.dispose();
|
|
@@ -1383,7 +1383,7 @@ export class ContainerRuntime extends TypedEventEmitter<IContainerRuntimeEvents>
|
|
|
1383
1383
|
return convertSummaryTreeToITree(summaryResult.summary);
|
|
1384
1384
|
}
|
|
1385
1385
|
|
|
1386
|
-
private
|
|
1386
|
+
private addContainerStateToSummary(summaryTree: ISummaryTreeWithStats) {
|
|
1387
1387
|
addBlobToSummary(summaryTree, metadataBlobName, JSON.stringify(this.formMetadata()));
|
|
1388
1388
|
if (this.chunkMap.size > 0) {
|
|
1389
1389
|
const content = JSON.stringify([...this.chunkMap]);
|
|
@@ -1408,7 +1408,7 @@ export class ContainerRuntime extends TypedEventEmitter<IContainerRuntimeEvents>
|
|
|
1408
1408
|
addTreeToSummary(summaryTree, blobsTreeName, blobsTree);
|
|
1409
1409
|
}
|
|
1410
1410
|
|
|
1411
|
-
if (this.
|
|
1411
|
+
if (this.garbageCollector.writeDataAtRoot) {
|
|
1412
1412
|
const gcSummary = this.garbageCollector.summarize();
|
|
1413
1413
|
if (gcSummary !== undefined) {
|
|
1414
1414
|
addTreeToSummary(summaryTree, gcTreeKey, gcSummary);
|
|
@@ -1660,20 +1660,18 @@ export class ContainerRuntime extends TypedEventEmitter<IContainerRuntimeEvents>
|
|
|
1660
1660
|
const savedFlushMode = this.flushMode;
|
|
1661
1661
|
this.setFlushMode(FlushMode.TurnBased);
|
|
1662
1662
|
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
this.setFlushMode(savedFlushMode);
|
|
1667
|
-
} catch(error) {
|
|
1668
|
-
this.closeFn(CreateProcessingError(error, "orderSequentially"));
|
|
1669
|
-
throw error; // throw the original error for the consumer of the runtime
|
|
1670
|
-
}
|
|
1663
|
+
this.trackOrderSequentiallyCalls(callback);
|
|
1664
|
+
this.flush();
|
|
1665
|
+
this.setFlushMode(savedFlushMode);
|
|
1671
1666
|
}
|
|
1672
1667
|
|
|
1673
1668
|
private trackOrderSequentiallyCalls(callback: () => void): void {
|
|
1674
1669
|
try {
|
|
1675
1670
|
this._orderSequentiallyCalls++;
|
|
1676
1671
|
callback();
|
|
1672
|
+
} catch (error) {
|
|
1673
|
+
this.closeFn(new GenericError("orderSequentiallyCallbackException", error));
|
|
1674
|
+
throw error; // throw the original error for the consumer of the runtime
|
|
1677
1675
|
} finally {
|
|
1678
1676
|
this._orderSequentiallyCalls--;
|
|
1679
1677
|
}
|
|
@@ -1723,7 +1721,7 @@ export class ContainerRuntime extends TypedEventEmitter<IContainerRuntimeEvents>
|
|
|
1723
1721
|
}
|
|
1724
1722
|
|
|
1725
1723
|
private canSendOps() {
|
|
1726
|
-
return this.connected && !this.deltaManager.readonly;
|
|
1724
|
+
return this.connected && !this.deltaManager.readOnlyInfo.readonly;
|
|
1727
1725
|
}
|
|
1728
1726
|
|
|
1729
1727
|
public getQuorum(): IQuorumClients {
|
|
@@ -1735,11 +1733,6 @@ export class ContainerRuntime extends TypedEventEmitter<IContainerRuntimeEvents>
|
|
|
1735
1733
|
return this.context.audience!;
|
|
1736
1734
|
}
|
|
1737
1735
|
|
|
1738
|
-
// @deprecated Needs to become private
|
|
1739
|
-
public readonly raiseContainerWarning = (warning: ContainerWarning) => {
|
|
1740
|
-
this.context.raiseContainerWarning(warning);
|
|
1741
|
-
};
|
|
1742
|
-
|
|
1743
1736
|
/**
|
|
1744
1737
|
* Returns true of container is dirty, i.e. there are some pending local changes that
|
|
1745
1738
|
* either were not sent out to delta stream or were not yet acknowledged.
|
|
@@ -1810,7 +1803,7 @@ export class ContainerRuntime extends TypedEventEmitter<IContainerRuntimeEvents>
|
|
|
1810
1803
|
// Wrap data store summaries in .channels subtree.
|
|
1811
1804
|
wrapSummaryInChannelsTree(summarizeResult);
|
|
1812
1805
|
}
|
|
1813
|
-
this.
|
|
1806
|
+
this.addContainerStateToSummary(summarizeResult);
|
|
1814
1807
|
return summarizeResult.summary;
|
|
1815
1808
|
}
|
|
1816
1809
|
|
|
@@ -1833,7 +1826,7 @@ export class ContainerRuntime extends TypedEventEmitter<IContainerRuntimeEvents>
|
|
|
1833
1826
|
wrapSummaryInChannelsTree(summarizeResult);
|
|
1834
1827
|
pathPartsForChildren = [channelsTreeName];
|
|
1835
1828
|
}
|
|
1836
|
-
this.
|
|
1829
|
+
this.addContainerStateToSummary(summarizeResult);
|
|
1837
1830
|
return {
|
|
1838
1831
|
...summarizeResult,
|
|
1839
1832
|
id: "",
|
|
@@ -1858,6 +1851,8 @@ export class ContainerRuntime extends TypedEventEmitter<IContainerRuntimeEvents>
|
|
|
1858
1851
|
/** True to run GC sweep phase after the mark phase */
|
|
1859
1852
|
runSweep?: boolean,
|
|
1860
1853
|
}): Promise<ISummaryTreeWithStats> {
|
|
1854
|
+
this.verifyNotClosed();
|
|
1855
|
+
|
|
1861
1856
|
const { summaryLogger, fullTree = false, trackState = true, runGC = true, runSweep, fullGC } = options;
|
|
1862
1857
|
|
|
1863
1858
|
if (runGC) {
|
|
@@ -2018,10 +2013,9 @@ export class ContainerRuntime extends TypedEventEmitter<IContainerRuntimeEvents>
|
|
|
2018
2013
|
try {
|
|
2019
2014
|
summarizeResult = await this.summarize({
|
|
2020
2015
|
summaryLogger,
|
|
2021
|
-
// If the GC
|
|
2022
|
-
//
|
|
2023
|
-
|
|
2024
|
-
fullTree: fullTree || this.garbageCollector.hasGCVersionChanged,
|
|
2016
|
+
// If the GC state needs to be reset, we need to regenerate the summary and update the unreferenced
|
|
2017
|
+
// state of all the nodes.
|
|
2018
|
+
fullTree: fullTree || this.garbageCollector.summaryStateNeedsReset,
|
|
2025
2019
|
trackState: true,
|
|
2026
2020
|
runGC: this.garbageCollector.shouldRunGC,
|
|
2027
2021
|
});
|