@fluid-tools/fetch-tool 2.0.0-internal.5.2.0 → 2.0.0-internal.5.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # @fluid-tools/fetch-tool
2
2
 
3
+ ## 2.0.0-internal.5.3.0
4
+
5
+ Dependency updates only.
6
+
3
7
  ## 2.0.0-internal.5.2.0
4
8
 
5
9
  Dependency updates only.
@@ -1 +1 @@
1
- {"version":3,"file":"fluidAnalyzeMessages.d.ts","sourceRoot":"","sources":["../src/fluidAnalyzeMessages.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAyEH,eAAO,MAAM,YAAY,QAAS,MAAM,KAAG,MAEU,CAAC;AA+YtD,wBAAsB,iBAAiB,CACtC,SAAS,KAAA,EAAE,+CAA+C;AAC1D,gBAAgB,EAAE,OAAO,EACzB,YAAY,EAAE,OAAO,EACrB,iBAAiB,GAAE,GAAG,CAAC,MAAM,CAAqB,iBA0ClD"}
1
+ {"version":3,"file":"fluidAnalyzeMessages.d.ts","sourceRoot":"","sources":["../src/fluidAnalyzeMessages.ts"],"names":[],"mappings":"AAAA;;;GAGG;AA2EH,eAAO,MAAM,YAAY,QAAS,MAAM,KAAG,MAEU,CAAC;AAgZtD,wBAAsB,iBAAiB,CACtC,SAAS,KAAA,EAAE,+CAA+C;AAC1D,gBAAgB,EAAE,OAAO,EACzB,YAAY,EAAE,OAAO,EACrB,iBAAiB,GAAE,GAAG,CAAC,MAAM,CAAqB,iBA0ClD"}
@@ -326,7 +326,8 @@ class SummaryAnalyzer {
326
326
  this.lastSummaryOp = message.sequenceNumber;
327
327
  }
328
328
  if (message.type === protocol_definitions_1.MessageType.SummaryAck || message.type === protocol_definitions_1.MessageType.SummaryNack) {
329
- const contents = message.contents.summaryProposal;
329
+ const contents = message.contents
330
+ .summaryProposal;
330
331
  const distance = message.sequenceNumber - contents.summarySequenceNumber;
331
332
  if (distance > this.maxResponse) {
332
333
  this.maxResponse = distance;
@@ -430,12 +431,16 @@ function processOp(runtimeMessage, dataType, objectStats, msgSize, dataTypeStats
430
431
  }
431
432
  case container_runtime_1.ContainerMessageType.ChunkedOp: {
432
433
  const chunk = runtimeMessage.contents;
434
+ // TODO: Verify whether this should be able to handle server-generated ops (with null clientId)
435
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
433
436
  if (!chunkMap.has(runtimeMessage.clientId)) {
437
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
434
438
  chunkMap.set(runtimeMessage.clientId, {
435
439
  chunks: new Array(chunk.totalChunks),
436
440
  totalSize: 0,
437
441
  });
438
442
  }
443
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
439
444
  const value = chunkMap.get(runtimeMessage.clientId);
440
445
  (0, common_utils_1.assert)(value !== undefined, 0x2b8 /* "Chunk should be set in map" */);
441
446
  const chunks = value.chunks;
@@ -627,6 +632,8 @@ function processQuorumMessages(message, skipMessage, sessionsInProgress, session
627
632
  }
628
633
  else {
629
634
  // message.clientId can be null
635
+ // TODO: Verify whether this should be able to handle server-generated ops (with null clientId)
636
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
630
637
  session = sessionsInProgress.get(message.clientId);
631
638
  if (session === undefined) {
632
639
  session = sessionsInProgress.get(noClientName);
@@ -1 +1 @@
1
- {"version":3,"file":"fluidAnalyzeMessages.js","sourceRoot":"","sources":["../src/fluidAnalyzeMessages.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, unreachableCase } from \"@fluidframework/common-utils\";\nimport {\n\tISequencedDocumentMessage,\n\tISummaryProposal,\n\tMessageType,\n\tTreeEntry,\n} from \"@fluidframework/protocol-definitions\";\nimport { IAttachMessage, IEnvelope } from \"@fluidframework/runtime-definitions\";\nimport {\n\tIChunkedOp,\n\tContainerMessageType,\n\tunpackRuntimeMessage,\n} from \"@fluidframework/container-runtime\";\nimport { DataStoreMessageType } from \"@fluidframework/datastore\";\n\nconst noClientName = \"No Client\";\nconst objectTypePrefix = \"https://graph.microsoft.com/types/\";\n\nfunction incr(map: Map<string, [number, number]>, key: string, size: number, count = 1) {\n\tconst value = map.get(key);\n\tif (value === undefined) {\n\t\tmap.set(key, [count, size]);\n\t} else {\n\t\tvalue[0] += count;\n\t\tvalue[1] += size;\n\t\tmap.set(key, value);\n\t}\n}\n\ninterface ISessionInfo {\n\tstartSeq: number;\n\topCount: number;\n\temail: string;\n\tduration: number;\n}\n\ninterface IMessageAnalyzer {\n\tprocessOp(op: ISequencedDocumentMessage, msgSize: number, filteredOutOp: boolean): void;\n\treportAnalyzes(lastOp: ISequencedDocumentMessage): void;\n}\n\n/**\n * Helper class to track session statistics\n */\nclass ActiveSession {\n\tpublic static create(email: string, message: ISequencedDocumentMessage) {\n\t\treturn new ActiveSession(email, message);\n\t}\n\n\tprivate opCount = 0;\n\n\tconstructor(\n\t\tprivate readonly email: string,\n\t\tprivate readonly startMessage: ISequencedDocumentMessage,\n\t) {}\n\n\tpublic reportOp(timestamp: number) {\n\t\tthis.opCount++;\n\t}\n\n\tpublic leave(timestamp: number): ISessionInfo {\n\t\treturn {\n\t\t\topCount: this.opCount,\n\t\t\temail: this.email,\n\t\t\tstartSeq: this.startMessage.sequenceNumber,\n\t\t\tduration: timestamp - this.startMessage.timestamp,\n\t\t};\n\t}\n}\n\n// Format a number separating 3 digits by comma\nexport const formatNumber = (num: number): string =>\n\t// eslint-disable-next-line unicorn/no-unsafe-regex\n\tnum.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, \",\");\n\nfunction dumpStats(\n\tmap: Map<string, [number, number]>,\n\tprops: {\n\t\ttitle: string;\n\t\theaders: [string, string];\n\t\tlines?: number;\n\t\torderByFirstColumn?: boolean;\n\t\treverseColumnsInUI?: boolean;\n\t\tremoveTotals?: boolean;\n\t\treverseSort?: boolean;\n\t},\n) {\n\tconst fieldSizes = [10, 14];\n\tconst nameLength = 72;\n\tconst fieldsLength = fieldSizes[0] + fieldSizes[1] + 1;\n\tlet headers = props.headers;\n\n\tlet recordsToShow = props.lines ?? 10;\n\tif (map.size !== recordsToShow && props.removeTotals === undefined && recordsToShow > 1) {\n\t\trecordsToShow--;\n\t}\n\n\tlet sorted: [string, [number, number]][];\n\tconst sortIndex = props.orderByFirstColumn === true ? 0 : 1;\n\tlet add: string;\n\tif (props.reverseSort !== undefined) {\n\t\tsorted = [...map.entries()].sort((a, b) => a[1][sortIndex] - b[1][sortIndex]);\n\t\tadd = \"↑\";\n\t} else {\n\t\tsorted = [...map.entries()].sort((a, b) => b[1][sortIndex] - a[1][sortIndex]);\n\t\tadd = \"↓\";\n\t}\n\theaders[sortIndex] = `${headers[sortIndex]} ${add}`;\n\n\tif (props.reverseColumnsInUI !== undefined) {\n\t\theaders = [headers[1], headers[0]];\n\t\tconst sorted2: [string, [number, number]][] = [];\n\t\tfor (const [name, [count, size]] of sorted) {\n\t\t\tsorted2.push([name, [size, count]]);\n\t\t}\n\t\tsorted = sorted2;\n\t}\n\n\tlet totalCount = 0;\n\tlet sizeTotal = 0;\n\n\tprops.title = `${props.title} (${sorted.length})`;\n\tconst header0 = headers[0].padStart(fieldSizes[0]);\n\tlet overflow = header0.length - fieldSizes[0];\n\tconsole.log(\n\t\t`\\n\\n${props.title.padEnd(nameLength)} │ ${header0} ${headers[1].padStart(\n\t\t\tfieldSizes[1] - overflow,\n\t\t)}`,\n\t);\n\n\tconsole.log(`${\"─\".repeat(nameLength + 1)}┼${\"─\".repeat(fieldsLength + 1)}`);\n\tlet index = 0;\n\tlet allOtherCount = 0;\n\tlet allOtherSize = 0;\n\tfor (const [name, [count, size]] of sorted) {\n\t\tindex++;\n\t\ttotalCount += count;\n\t\tsizeTotal += size;\n\t\tif (index <= recordsToShow) {\n\t\t\tconst item = name.padEnd(nameLength);\n\t\t\toverflow = item.length - nameLength;\n\t\t\tconst col1 = formatNumber(count).padStart(fieldSizes[0] - overflow);\n\t\t\toverflow += col1.length - fieldSizes[0];\n\t\t\tconst col2 = formatNumber(size).padStart(fieldSizes[1] - overflow);\n\t\t\tconsole.log(`${item} │ ${col1} ${col2}`);\n\t\t} else {\n\t\t\tallOtherCount += count;\n\t\t\tallOtherSize += size;\n\t\t}\n\t}\n\n\tif (props.removeTotals === undefined) {\n\t\tif (allOtherCount || allOtherSize) {\n\t\t\tconsole.log(\n\t\t\t\t`${`All Others (${sorted.length - recordsToShow})`.padEnd(\n\t\t\t\t\tnameLength,\n\t\t\t\t)} │ ${formatNumber(allOtherCount).padStart(fieldSizes[0])} ${formatNumber(\n\t\t\t\t\tallOtherSize,\n\t\t\t\t).padStart(fieldSizes[1])}`,\n\t\t\t);\n\t\t}\n\t\tconsole.log(`${\"─\".repeat(nameLength + 1)}┼${\"─\".repeat(fieldsLength + 1)}`);\n\t\tconsole.log(\n\t\t\t`${\"Total\".padEnd(nameLength)} │ ${formatNumber(totalCount).padStart(\n\t\t\t\tfieldSizes[0],\n\t\t\t)} ${formatNumber(sizeTotal).padStart(fieldSizes[1])}`,\n\t\t);\n\t}\n}\n\nconst getObjectId = (dataStoreId: string, id: string) => `[${dataStoreId}]/${id}`;\n\n/**\n * Analyzer for sessions\n */\nclass SessionAnalyzer implements IMessageAnalyzer {\n\tprivate readonly sessionsInProgress = new Map<string, ActiveSession>();\n\tprivate readonly sessions = new Map<string, [number, number]>();\n\tprivate readonly users = new Map<string, [number, number]>();\n\n\tprivate first = true;\n\n\tpublic processOp(\n\t\tmessage: ISequencedDocumentMessage,\n\t\tmsgSize: number,\n\t\tskipMessage: boolean,\n\t): void {\n\t\tif (this.first) {\n\t\t\tthis.first = false;\n\t\t\t// Start of the road.\n\t\t\tconst noNameSession = ActiveSession.create(noClientName, message);\n\t\t\tthis.sessionsInProgress.set(noClientName, noNameSession);\n\t\t}\n\t\tconst session = processQuorumMessages(\n\t\t\tmessage,\n\t\t\tskipMessage,\n\t\t\tthis.sessionsInProgress,\n\t\t\tthis.sessions,\n\t\t\tthis.users,\n\t\t);\n\t\tif (!skipMessage && session) {\n\t\t\tsession.reportOp(message.timestamp);\n\t\t}\n\t}\n\n\tpublic reportAnalyzes(lastOp: ISequencedDocumentMessage): void {\n\t\t// Close any open sessions\n\t\treportOpenSessions(lastOp.timestamp, this.sessionsInProgress, this.sessions, this.users);\n\t\tdumpStats(this.users, {\n\t\t\ttitle: \"Users\",\n\t\t\theaders: [\"Sessions\", \"Op count\"],\n\t\t\treverseColumnsInUI: true,\n\t\t\tlines: 6,\n\t\t});\n\t\tdumpStats(this.sessions, {\n\t\t\ttitle: \"Sessions\",\n\t\t\theaders: [\"Duration(s)\", \"Op count\"],\n\t\t\treverseColumnsInUI: true,\n\t\t\tlines: 6,\n\t\t});\n\t\tdumpStats(this.sessions, {\n\t\t\ttitle: \"Sessions\",\n\t\t\theaders: [\"Duration(s)\", \"Op count\"],\n\t\t\torderByFirstColumn: true,\n\t\t\treverseColumnsInUI: true,\n\t\t\tremoveTotals: true,\n\t\t\tlines: 5,\n\t\t});\n\t}\n}\n\n/**\n * Analyzer for data structures\n */\nclass DataStructureAnalyzer implements IMessageAnalyzer {\n\tprivate readonly messageTypeStats = new Map<string, [number, number]>();\n\tprivate readonly dataType = new Map<string, string>();\n\tprivate readonly dataTypeStats = new Map<string, [number, number]>();\n\tprivate readonly objectStats = new Map<string, [number, number]>();\n\t// eslint-disable-next-line @typescript-eslint/member-delimiter-style\n\tprivate readonly chunkMap = new Map<string, { chunks: string[]; totalSize: number }>();\n\n\tpublic processOp(\n\t\tmessage: ISequencedDocumentMessage,\n\t\tmsgSize: number,\n\t\tskipMessage: boolean,\n\t): void {\n\t\tif (!skipMessage) {\n\t\t\tprocessOp(\n\t\t\t\tmessage,\n\t\t\t\tthis.dataType,\n\t\t\t\tthis.objectStats,\n\t\t\t\tmsgSize,\n\t\t\t\tthis.dataTypeStats,\n\t\t\t\tthis.messageTypeStats,\n\t\t\t\tthis.chunkMap,\n\t\t\t);\n\t\t}\n\t}\n\n\tpublic reportAnalyzes(lastOp: ISequencedDocumentMessage): void {\n\t\tdumpStats(this.messageTypeStats, {\n\t\t\ttitle: \"Message Type\",\n\t\t\theaders: [\"Op count\", \"Bytes\"],\n\t\t\tlines: 20,\n\t\t});\n\t\tdumpStats(calcChannelStats(this.dataType, this.objectStats), {\n\t\t\ttitle: \"Channel name\",\n\t\t\theaders: [\"Op count\", \"Bytes\"],\n\t\t\tlines: 7,\n\t\t});\n\t\t/*\n dumpStats(this.dataTypeStats, {\n title: \"Channel type\",\n headers: [\"Op count\", \"Bytes\"],\n });\n */\n\t}\n}\n\n/**\n * Helper class to report if we filtered out any messages.\n */\nclass FilteredMessageAnalyzer implements IMessageAnalyzer {\n\tprivate sizeTotal = 0;\n\tprivate opsTotal = 0;\n\tprivate sizeFiltered = 0;\n\tprivate opsFiltered = 0;\n\tprivate filtered = false;\n\n\tpublic processOp(\n\t\tmessage: ISequencedDocumentMessage,\n\t\tmsgSize: number,\n\t\tskipMessage: boolean,\n\t): void {\n\t\tthis.sizeTotal += msgSize;\n\t\tthis.opsTotal++;\n\t\tif (!skipMessage) {\n\t\t\tthis.sizeFiltered += msgSize;\n\t\t\tthis.opsFiltered++;\n\t\t} else {\n\t\t\tthis.filtered = true;\n\t\t}\n\t}\n\n\tpublic reportAnalyzes(lastOp: ISequencedDocumentMessage): void {\n\t\tif (this.filtered) {\n\t\t\tconsole.log(\n\t\t\t\t`\\nData is filtered according to --filter:messageType argument(s):\\nOp size: ${this.sizeFiltered} / ${this.sizeTotal}\\nOp count ${this.opsFiltered} / ${this.opsTotal}`,\n\t\t\t);\n\t\t}\n\t\tif (this.opsTotal === 0) {\n\t\t\tconsole.error(\"No ops were found\");\n\t\t}\n\t}\n}\n\n/**\n * Helper class to find places where we generated too many ops\n */\nclass MessageDensityAnalyzer implements IMessageAnalyzer {\n\tprivate readonly opChunk = 1000;\n\tprivate opLimit = 1;\n\tprivate size = 0;\n\tprivate timeStart = 0;\n\tprivate doctimerStart = 0;\n\tprivate readonly ranges = new Map<string, [number, number]>();\n\n\tpublic processOp(\n\t\tmessage: ISequencedDocumentMessage,\n\t\tmsgSize: number,\n\t\tskipMessage: boolean,\n\t): void {\n\t\tif (message.sequenceNumber >= this.opLimit) {\n\t\t\tif (message.sequenceNumber !== 1) {\n\t\t\t\tconst timeDiff = durationFromTime(message.timestamp - this.timeStart);\n\t\t\t\tconst opsString = `ops = [${this.opLimit - this.opChunk}, ${\n\t\t\t\t\tthis.opLimit - 1\n\t\t\t\t}]`.padEnd(26);\n\t\t\t\tconst timeString = `time = [${durationFromTime(\n\t\t\t\t\tthis.timeStart - this.doctimerStart,\n\t\t\t\t)}, ${durationFromTime(message.timestamp - this.doctimerStart)}]`;\n\t\t\t\tthis.ranges.set(`${opsString} ${timeString}`, [timeDiff, this.size]);\n\t\t\t} else {\n\t\t\t\tthis.doctimerStart = message.timestamp;\n\t\t\t}\n\t\t\tthis.opLimit += this.opChunk;\n\t\t\tthis.size = 0;\n\t\t\tthis.timeStart = message.timestamp;\n\t\t}\n\t\tif (!skipMessage) {\n\t\t\tthis.size += msgSize;\n\t\t}\n\t}\n\n\tpublic reportAnalyzes(lastOp: ISequencedDocumentMessage): void {\n\t\tdumpStats(this.ranges, {\n\t\t\ttitle: \"Fastest 1000 op ranges\",\n\t\t\theaders: [\"Duration(s)\", \"Bytes\"],\n\t\t\torderByFirstColumn: true,\n\t\t\treverseSort: true,\n\t\t\tremoveTotals: true,\n\t\t\tlines: 3,\n\t\t});\n\t}\n}\n\n/**\n * Helper class to analyze collab window size\n */\nclass CollabWindowSizeAnalyzer implements IMessageAnalyzer {\n\tprivate maxCollabWindow = 0;\n\tprivate opSeq = 0;\n\n\tpublic processOp(\n\t\tmessage: ISequencedDocumentMessage,\n\t\tmsgSize: number,\n\t\tskipMessage: boolean,\n\t): void {\n\t\tconst value = message.sequenceNumber - message.minimumSequenceNumber;\n\t\tif (value > this.maxCollabWindow) {\n\t\t\tthis.maxCollabWindow = value;\n\t\t\tthis.opSeq = message.sequenceNumber;\n\t\t}\n\t}\n\n\tpublic reportAnalyzes(lastOp: ISequencedDocumentMessage): void {\n\t\tconsole.log(`\\nMaximum collab window size: ${this.maxCollabWindow}, seq# ${this.opSeq}`);\n\t}\n}\n\n/**\n * Helper class to analyze frequency of summaries\n */\nclass SummaryAnalyzer implements IMessageAnalyzer {\n\tprivate lastSummaryOp = 0;\n\tprivate maxDistance = 0;\n\tprivate maxSeq = 0;\n\tprivate minDistance = Number.MAX_SAFE_INTEGER;\n\tprivate minSeq = 0;\n\tprivate maxResponse = 0;\n\tprivate maxResponseSeq = 0;\n\n\tpublic processOp(\n\t\tmessage: ISequencedDocumentMessage,\n\t\tmsgSize: number,\n\t\tskipMessage: boolean,\n\t): void {\n\t\tif (message.type === MessageType.SummaryAck) {\n\t\t\tconst distance = message.sequenceNumber - this.lastSummaryOp - 1;\n\t\t\tif (this.maxDistance < distance) {\n\t\t\t\tthis.maxDistance = distance;\n\t\t\t\tthis.maxSeq = message.sequenceNumber;\n\t\t\t}\n\t\t\tif (this.minDistance > distance) {\n\t\t\t\tthis.minDistance = distance;\n\t\t\t\tthis.minSeq = message.sequenceNumber;\n\t\t\t}\n\n\t\t\tthis.lastSummaryOp = message.sequenceNumber;\n\t\t}\n\t\tif (message.type === MessageType.SummaryAck || message.type === MessageType.SummaryNack) {\n\t\t\tconst contents: ISummaryProposal = message.contents.summaryProposal;\n\t\t\tconst distance = message.sequenceNumber - contents.summarySequenceNumber;\n\t\t\tif (distance > this.maxResponse) {\n\t\t\t\tthis.maxResponse = distance;\n\t\t\t\tthis.maxResponseSeq = message.sequenceNumber;\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic reportAnalyzes(lastOp: ISequencedDocumentMessage): void {\n\t\tconst distance = lastOp.sequenceNumber - this.lastSummaryOp;\n\t\tif (this.maxDistance < distance) {\n\t\t\tthis.maxDistance = distance;\n\t\t\tthis.maxSeq = lastOp.sequenceNumber + 1;\n\t\t}\n\n\t\tconsole.log(\"\");\n\t\tif (this.minDistance === Number.MAX_SAFE_INTEGER) {\n\t\t\tconsole.log(\"No summaries found in this document\");\n\t\t} else {\n\t\t\tconsole.log(\n\t\t\t\t`Maximum distance between summaries: ${this.maxDistance}, seq# ${this.maxSeq}`,\n\t\t\t);\n\t\t\tconsole.log(\n\t\t\t\t`Maximum server response for summary: ${this.maxResponse}, seq# ${this.maxResponseSeq}`,\n\t\t\t);\n\t\t\tconsole.log(\n\t\t\t\t`Minimum distance between summaries: ${this.minDistance}, seq# ${this.minSeq}`,\n\t\t\t);\n\t\t}\n\t}\n}\n\n/**\n * Helper class to dump messages to console\n */\nclass MessageDumper implements IMessageAnalyzer {\n\tpublic processOp(\n\t\tmessage: ISequencedDocumentMessage,\n\t\tmsgSize: number,\n\t\tskipMessage: boolean,\n\t): void {\n\t\tif (!skipMessage) {\n\t\t\tconsole.log(JSON.stringify(message, undefined, 2));\n\t\t}\n\t}\n\n\tpublic reportAnalyzes(lastOp: ISequencedDocumentMessage): void {}\n}\n\nexport async function printMessageStats(\n\tgenerator, // AsyncGenerator<ISequencedDocumentMessage[]>,\n\tdumpMessageStats: boolean,\n\tdumpMessages: boolean,\n\tmessageTypeFilter: Set<string> = new Set<string>(),\n) {\n\tlet lastMessage: ISequencedDocumentMessage | undefined;\n\n\tconst analyzers: IMessageAnalyzer[] = [\n\t\tnew FilteredMessageAnalyzer(), // Should come first\n\t\tnew SessionAnalyzer(),\n\t\tnew DataStructureAnalyzer(),\n\t\tnew MessageDensityAnalyzer(),\n\t\tnew CollabWindowSizeAnalyzer(),\n\t\tnew SummaryAnalyzer(),\n\t];\n\n\tif (dumpMessages) {\n\t\tanalyzers.push(new MessageDumper());\n\t}\n\n\tfor await (const messages of generator) {\n\t\tfor (const message of messages as ISequencedDocumentMessage[]) {\n\t\t\tconst msgSize = JSON.stringify(message).length;\n\t\t\tlastMessage = message;\n\n\t\t\tconst skipMessage =\n\t\t\t\tmessageTypeFilter.size !== 0 && !messageTypeFilter.has(message.type);\n\n\t\t\tfor (const analyzer of analyzers) {\n\t\t\t\tanalyzer.processOp(message, msgSize, skipMessage);\n\t\t\t}\n\t\t}\n\t}\n\n\tif (lastMessage !== undefined) {\n\t\tif (dumpMessageStats) {\n\t\t\tfor (const analyzer of analyzers) {\n\t\t\t\tanalyzer.reportAnalyzes(lastMessage);\n\t\t\t}\n\t\t} else {\n\t\t\t// Warn about filtered messages\n\t\t\tanalyzers[0].reportAnalyzes(lastMessage);\n\t\t}\n\t}\n\tconsole.log(\"\");\n}\n\nfunction processOp(\n\truntimeMessage: ISequencedDocumentMessage,\n\tdataType: Map<string, string>,\n\tobjectStats: Map<string, [number, number]>,\n\tmsgSize: number,\n\tdataTypeStats: Map<string, [number, number]>,\n\tmessageTypeStats: Map<string, [number, number]>,\n\tchunkMap: Map<string, { chunks: string[]; totalSize: number }>,\n) {\n\tlet type = runtimeMessage.type;\n\tlet recorded = false;\n\tlet totalMsgSize = msgSize;\n\tlet opCount = 1;\n\tif (unpackRuntimeMessage(runtimeMessage)) {\n\t\tconst messageType = runtimeMessage.type as ContainerMessageType;\n\t\tswitch (messageType) {\n\t\t\tcase ContainerMessageType.Attach: {\n\t\t\t\tconst attachMessage = runtimeMessage.contents as IAttachMessage;\n\t\t\t\tprocessDataStoreAttachOp(attachMessage, dataType);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\t// skip for now because these ops do not have contents\n\t\t\tcase ContainerMessageType.BlobAttach: {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase ContainerMessageType.ChunkedOp: {\n\t\t\t\tconst chunk = runtimeMessage.contents as IChunkedOp;\n\t\t\t\tif (!chunkMap.has(runtimeMessage.clientId)) {\n\t\t\t\t\tchunkMap.set(runtimeMessage.clientId, {\n\t\t\t\t\t\tchunks: new Array<string>(chunk.totalChunks),\n\t\t\t\t\t\ttotalSize: 0,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tconst value = chunkMap.get(runtimeMessage.clientId);\n\t\t\t\tassert(value !== undefined, 0x2b8 /* \"Chunk should be set in map\" */);\n\t\t\t\tconst chunks = value.chunks;\n\t\t\t\tconst chunkIndex = chunk.chunkId - 1;\n\t\t\t\tif (chunks[chunkIndex] !== undefined) {\n\t\t\t\t\tthrow new Error(\"Chunk already assigned\");\n\t\t\t\t}\n\t\t\t\tchunks[chunkIndex] = chunk.contents;\n\t\t\t\tvalue.totalSize += msgSize;\n\t\t\t\tif (chunk.chunkId === chunk.totalChunks) {\n\t\t\t\t\topCount = chunk.totalChunks; // 1 op for each chunk.\n\t\t\t\t\tconst patchedMessage = Object.create(runtimeMessage);\n\t\t\t\t\tpatchedMessage.contents = chunks.join(\"\");\n\t\t\t\t\tpatchedMessage.type = chunk.originalType;\n\t\t\t\t\ttype = chunk.originalType;\n\t\t\t\t\ttotalMsgSize = value.totalSize;\n\t\t\t\t\tchunkMap.delete(patchedMessage.clientId);\n\t\t\t\t} else {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\t// eslint-disable-next-line no-fallthrough\n\t\t\t}\n\t\t\tcase ContainerMessageType.IdAllocation:\n\t\t\tcase ContainerMessageType.FluidDataStoreOp:\n\t\t\tcase ContainerMessageType.Alias:\n\t\t\tcase ContainerMessageType.Rejoin: {\n\t\t\t\tlet envelope = runtimeMessage.contents as IEnvelope;\n\t\t\t\t// TODO: Legacy?\n\t\t\t\tif (envelope !== undefined && typeof envelope === \"string\") {\n\t\t\t\t\tenvelope = JSON.parse(envelope);\n\t\t\t\t}\n\t\t\t\tconst innerContent = envelope.contents as {\n\t\t\t\t\tcontent: any;\n\t\t\t\t\ttype: string;\n\t\t\t\t};\n\t\t\t\tconst address = envelope.address;\n\t\t\t\ttype = `${type}/${innerContent.type}`;\n\t\t\t\tswitch (innerContent.type) {\n\t\t\t\t\tcase DataStoreMessageType.Attach: {\n\t\t\t\t\t\tconst attachMessage = innerContent.content as IAttachMessage;\n\t\t\t\t\t\tlet objectType = attachMessage.type;\n\t\t\t\t\t\tif (objectType.startsWith(objectTypePrefix)) {\n\t\t\t\t\t\t\tobjectType = objectType.substring(objectTypePrefix.length);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tdataType.set(getObjectId(address, attachMessage.id), objectType);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase DataStoreMessageType.ChannelOp:\n\t\t\t\t\tdefault: {\n\t\t\t\t\t\tconst innerEnvelope = innerContent.content as IEnvelope;\n\t\t\t\t\t\tconst innerContent2 = innerEnvelope.contents as {\n\t\t\t\t\t\t\ttype?: string;\n\t\t\t\t\t\t\tvalue?: any;\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\tconst objectId = getObjectId(address, innerEnvelope.address);\n\t\t\t\t\t\tincr(objectStats, objectId, totalMsgSize, opCount);\n\t\t\t\t\t\tlet objectType = dataType.get(objectId);\n\t\t\t\t\t\tif (objectType === undefined) {\n\t\t\t\t\t\t\t// Somehow we do not have data...\n\t\t\t\t\t\t\tdataType.set(objectId, objectId);\n\t\t\t\t\t\t\tobjectType = objectId;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tincr(dataTypeStats, objectType, totalMsgSize, opCount);\n\t\t\t\t\t\trecorded = true;\n\n\t\t\t\t\t\tlet subType = innerContent2.type;\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tinnerContent2.type === \"set\" &&\n\t\t\t\t\t\t\ttypeof innerContent2.value === \"object\" &&\n\t\t\t\t\t\t\tinnerContent2.value !== null\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\ttype = `${type}/${subType}`;\n\t\t\t\t\t\t\tsubType = innerContent2.value.type;\n\t\t\t\t\t\t} else if (objectType === \"mergeTree\" && subType !== undefined) {\n\t\t\t\t\t\t\tconst types = [\"insert\", \"remove\", \"annotate\", \"group\"];\n\t\t\t\t\t\t\tif (types[subType] !== undefined) {\n\t\t\t\t\t\t\t\tsubType = types[subType];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (subType !== undefined) {\n\t\t\t\t\t\t\ttype = `${type}/${subType}`;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\ttype = `${type} (${objectType})`;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\tunreachableCase(messageType, \"Message type not recognized!\");\n\t\t}\n\t}\n\n\tincr(messageTypeStats, type, totalMsgSize, opCount);\n\tif (!recorded) {\n\t\t// const objectId = `${type} (system)`;\n\t\tconst objectId = `(system messages)`;\n\t\tconst objectType = objectId;\n\t\tif (dataType.get(objectId) === undefined) {\n\t\t\tdataType.set(objectId, objectId);\n\t\t}\n\t\tincr(objectStats, objectId, totalMsgSize, opCount);\n\t\tincr(dataTypeStats, objectType, totalMsgSize, opCount);\n\t}\n}\n\nfunction processDataStoreAttachOp(\n\tattachMessage: IAttachMessage | string,\n\tdataType: Map<string, string>,\n) {\n\t// dataType.set(getObjectId(attachMessage.id), attachMessage.type);\n\n\t// That's data store, and it brings a bunch of data structures.\n\t// Let's try to crack it.\n\tconst parsedAttachMessage =\n\t\ttypeof attachMessage === \"string\" ? JSON.parse(attachMessage) : attachMessage;\n\tfor (const entry of parsedAttachMessage.snapshot.entries) {\n\t\tif (entry.type === TreeEntry.Tree) {\n\t\t\tfor (const entry2 of entry.value.entries) {\n\t\t\t\tif (entry2.path === \".attributes\" && entry2.type === TreeEntry.Blob) {\n\t\t\t\t\tconst attrib = JSON.parse(entry2.value.contents);\n\t\t\t\t\tlet objectType: string = attrib.type;\n\t\t\t\t\tif (objectType.startsWith(objectTypePrefix)) {\n\t\t\t\t\t\tobjectType = objectType.substring(objectTypePrefix.length);\n\t\t\t\t\t}\n\t\t\t\t\tdataType.set(getObjectId(parsedAttachMessage.id, entry.path), objectType);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction reportOpenSessions(\n\tlastOpTimestamp: number,\n\tsessionsInProgress: Map<string, ActiveSession>,\n\tsessions: Map<string, [number, number]>,\n\tusers: Map<string, [number, number]>,\n) {\n\tconst activeSessions = new Map<string, [number, number]>();\n\n\tfor (const [clientId, ses] of sessionsInProgress) {\n\t\tconst sessionInfo = ses.leave(lastOpTimestamp);\n\t\tif (clientId !== noClientName) {\n\t\t\tconst sessionName = `${clientId} (${sessionInfo.email})`;\n\t\t\tconst sessionPayload: [number, number] = [\n\t\t\t\tdurationFromTime(sessionInfo.duration),\n\t\t\t\tsessionInfo.opCount,\n\t\t\t];\n\t\t\tsessions.set(sessionName, sessionPayload);\n\t\t\tactiveSessions.set(sessionName, sessionPayload);\n\t\t} else {\n\t\t\tsessions.set(`Full file lifespan (noClient messages)`, [\n\t\t\t\tdurationFromTime(sessionInfo.duration),\n\t\t\t\tsessionInfo.opCount,\n\t\t\t]);\n\t\t}\n\t\tincr(users, sessionInfo.email, sessionInfo.opCount);\n\t}\n\n\tif (activeSessions.size > 0) {\n\t\tdumpStats(activeSessions, {\n\t\t\ttitle: \"Active sessions\",\n\t\t\theaders: [\"Duration\", \"Op count\"],\n\t\t\tlines: 6,\n\t\t\torderByFirstColumn: true,\n\t\t\tremoveTotals: true,\n\t\t});\n\t}\n}\n\nfunction calcChannelStats(\n\tdataType: Map<string, string>,\n\tobjectStats: Map<string, [number, number]>,\n) {\n\tconst channelStats = new Map<string, [number, number]>();\n\tfor (const [objectId, type] of dataType) {\n\t\tlet value = objectStats.get(objectId);\n\t\tif (value === undefined) {\n\t\t\tvalue = [0, 0];\n\t\t}\n\t\tif (type === objectId) {\n\t\t\tchannelStats.set(`${objectId}`, value);\n\t\t} else {\n\t\t\tchannelStats.set(`${objectId} (${type})`, value);\n\t\t}\n\t}\n\treturn channelStats;\n}\n\nfunction processQuorumMessages(\n\tmessage: ISequencedDocumentMessage,\n\tskipMessage: boolean,\n\tsessionsInProgress: Map<string, ActiveSession>,\n\tsessions: Map<string, [number, number]>,\n\tusers: Map<string, [number, number]>,\n) {\n\tlet session: ActiveSession | undefined;\n\tconst dataString = (message as any).data;\n\tif (message.type === \"join\") {\n\t\tconst data = JSON.parse(dataString);\n\t\tsession = ActiveSession.create(data.detail.user.id, message);\n\t\tsessionsInProgress.set(data.clientId, session);\n\t} else if (message.type === \"leave\") {\n\t\tconst clientId = JSON.parse(dataString);\n\t\tsession = sessionsInProgress.get(clientId);\n\t\tsessionsInProgress.delete(clientId);\n\t\tassert(!!session, 0x1b7 /* \"Bad session state for processing quorum messages\" */);\n\t\tif (session !== undefined) {\n\t\t\tif (!skipMessage) {\n\t\t\t\tsession.reportOp(message.timestamp);\n\t\t\t}\n\t\t\tconst sessionInfo: ISessionInfo = session.leave(message.timestamp);\n\t\t\tsessions.set(`${clientId} (${sessionInfo.email})`, [\n\t\t\t\tdurationFromTime(sessionInfo.duration),\n\t\t\t\tsessionInfo.opCount,\n\t\t\t]);\n\t\t\tincr(users, sessionInfo.email, sessionInfo.opCount);\n\t\t\tsession = undefined; // Do not record it second time\n\t\t}\n\t} else {\n\t\t// message.clientId can be null\n\t\tsession = sessionsInProgress.get(message.clientId);\n\t\tif (session === undefined) {\n\t\t\tsession = sessionsInProgress.get(noClientName);\n\t\t\tassert(!!session, 0x1b8 /* \"Bad session state for processing quorum messages\" */);\n\t\t}\n\t}\n\treturn session;\n}\n\nconst durationFromTime = (time: number): number => Math.floor(time / 1000);\n"]}
1
+ {"version":3,"file":"fluidAnalyzeMessages.js","sourceRoot":"","sources":["../src/fluidAnalyzeMessages.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;;;;;;;;AAEH,+DAAuE;AACvE,+EAO8C;AAE9C,yEAI2C;AAC3C,yDAAiE;AAEjE,MAAM,YAAY,GAAG,WAAW,CAAC;AACjC,MAAM,gBAAgB,GAAG,oCAAoC,CAAC;AAE9D,SAAS,IAAI,CAAC,GAAkC,EAAE,GAAW,EAAE,IAAY,EAAE,KAAK,GAAG,CAAC;IACrF,MAAM,KAAK,GAAG,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC3B,IAAI,KAAK,KAAK,SAAS,EAAE;QACxB,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC;KAC5B;SAAM;QACN,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC;QAClB,KAAK,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;QACjB,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;KACpB;AACF,CAAC;AAcD;;GAEG;AACH,MAAM,aAAa;IAOlB,YACkB,KAAa,EACb,YAAuC;QADvC,UAAK,GAAL,KAAK,CAAQ;QACb,iBAAY,GAAZ,YAAY,CAA2B;QAJjD,YAAO,GAAG,CAAC,CAAC;IAKjB,CAAC;IATG,MAAM,CAAC,MAAM,CAAC,KAAa,EAAE,OAAkC;QACrE,OAAO,IAAI,aAAa,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IAC1C,CAAC;IASM,QAAQ,CAAC,SAAiB;QAChC,IAAI,CAAC,OAAO,EAAE,CAAC;IAChB,CAAC;IAEM,KAAK,CAAC,SAAiB;QAC7B,OAAO;YACN,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,QAAQ,EAAE,IAAI,CAAC,YAAY,CAAC,cAAc;YAC1C,QAAQ,EAAE,SAAS,GAAG,IAAI,CAAC,YAAY,CAAC,SAAS;SACjD,CAAC;IACH,CAAC;CACD;AAED,+CAA+C;AACxC,MAAM,YAAY,GAAG,CAAC,GAAW,EAAU,EAAE;AACnD,mDAAmD;AACnD,GAAG,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,uBAAuB,EAAE,GAAG,CAAC,CAAC;AAFzC,QAAA,YAAY,gBAE6B;AAEtD,SAAS,SAAS,CACjB,GAAkC,EAClC,KAQC;;IAED,MAAM,UAAU,GAAG,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;IAC5B,MAAM,UAAU,GAAG,EAAE,CAAC;IACtB,MAAM,YAAY,GAAG,UAAU,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IACvD,IAAI,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC;IAE5B,IAAI,aAAa,GAAG,MAAA,KAAK,CAAC,KAAK,mCAAI,EAAE,CAAC;IACtC,IAAI,GAAG,CAAC,IAAI,KAAK,aAAa,IAAI,KAAK,CAAC,YAAY,KAAK,SAAS,IAAI,aAAa,GAAG,CAAC,EAAE;QACxF,aAAa,EAAE,CAAC;KAChB;IAED,IAAI,MAAoC,CAAC;IACzC,MAAM,SAAS,GAAG,KAAK,CAAC,kBAAkB,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5D,IAAI,GAAW,CAAC;IAChB,IAAI,KAAK,CAAC,WAAW,KAAK,SAAS,EAAE;QACpC,MAAM,GAAG,CAAC,GAAG,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;QAC9E,GAAG,GAAG,GAAG,CAAC;KACV;SAAM;QACN,MAAM,GAAG,CAAC,GAAG,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;QAC9E,GAAG,GAAG,GAAG,CAAC;KACV;IACD,OAAO,CAAC,SAAS,CAAC,GAAG,GAAG,OAAO,CAAC,SAAS,CAAC,IAAI,GAAG,EAAE,CAAC;IAEpD,IAAI,KAAK,CAAC,kBAAkB,KAAK,SAAS,EAAE;QAC3C,OAAO,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;QACnC,MAAM,OAAO,GAAiC,EAAE,CAAC;QACjD,KAAK,MAAM,CAAC,IAAI,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,IAAI,MAAM,EAAE;YAC3C,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;SACpC;QACD,MAAM,GAAG,OAAO,CAAC;KACjB;IAED,IAAI,UAAU,GAAG,CAAC,CAAC;IACnB,IAAI,SAAS,GAAG,CAAC,CAAC;IAElB,KAAK,CAAC,KAAK,GAAG,GAAG,KAAK,CAAC,KAAK,KAAK,MAAM,CAAC,MAAM,GAAG,CAAC;IAClD,MAAM,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;IACnD,IAAI,QAAQ,GAAG,OAAO,CAAC,MAAM,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;IAC9C,OAAO,CAAC,GAAG,CACV,OAAO,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,MAAM,OAAO,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,CACxE,UAAU,CAAC,CAAC,CAAC,GAAG,QAAQ,CACxB,EAAE,CACH,CAAC;IAEF,OAAO,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,UAAU,GAAG,CAAC,CAAC,IAAI,GAAG,CAAC,MAAM,CAAC,YAAY,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC;IAC7E,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,IAAI,aAAa,GAAG,CAAC,CAAC;IACtB,IAAI,YAAY,GAAG,CAAC,CAAC;IACrB,KAAK,MAAM,CAAC,IAAI,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,IAAI,MAAM,EAAE;QAC3C,KAAK,EAAE,CAAC;QACR,UAAU,IAAI,KAAK,CAAC;QACpB,SAAS,IAAI,IAAI,CAAC;QAClB,IAAI,KAAK,IAAI,aAAa,EAAE;YAC3B,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;YACrC,QAAQ,GAAG,IAAI,CAAC,MAAM,GAAG,UAAU,CAAC;YACpC,MAAM,IAAI,GAAG,IAAA,oBAAY,EAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC;YACpE,QAAQ,IAAI,IAAI,CAAC,MAAM,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;YACxC,MAAM,IAAI,GAAG,IAAA,oBAAY,EAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC;YACnE,OAAO,CAAC,GAAG,CAAC,GAAG,IAAI,MAAM,IAAI,IAAI,IAAI,EAAE,CAAC,CAAC;SACzC;aAAM;YACN,aAAa,IAAI,KAAK,CAAC;YACvB,YAAY,IAAI,IAAI,CAAC;SACrB;KACD;IAED,IAAI,KAAK,CAAC,YAAY,KAAK,SAAS,EAAE;QACrC,IAAI,aAAa,IAAI,YAAY,EAAE;YAClC,OAAO,CAAC,GAAG,CACV,GAAG,eAAe,MAAM,CAAC,MAAM,GAAG,aAAa,GAAG,CAAC,MAAM,CACxD,UAAU,CACV,MAAM,IAAA,oBAAY,EAAC,aAAa,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,IAAA,oBAAY,EACzE,YAAY,CACZ,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,CAC3B,CAAC;SACF;QACD,OAAO,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,UAAU,GAAG,CAAC,CAAC,IAAI,GAAG,CAAC,MAAM,CAAC,YAAY,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC;QAC7E,OAAO,CAAC,GAAG,CACV,GAAG,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,MAAM,IAAA,oBAAY,EAAC,UAAU,CAAC,CAAC,QAAQ,CACnE,UAAU,CAAC,CAAC,CAAC,CACb,IAAI,IAAA,oBAAY,EAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,CACtD,CAAC;KACF;AACF,CAAC;AAED,MAAM,WAAW,GAAG,CAAC,WAAmB,EAAE,EAAU,EAAE,EAAE,CAAC,IAAI,WAAW,KAAK,EAAE,EAAE,CAAC;AAElF;;GAEG;AACH,MAAM,eAAe;IAArB;QACkB,uBAAkB,GAAG,IAAI,GAAG,EAAyB,CAAC;QACtD,aAAQ,GAAG,IAAI,GAAG,EAA4B,CAAC;QAC/C,UAAK,GAAG,IAAI,GAAG,EAA4B,CAAC;QAErD,UAAK,GAAG,IAAI,CAAC;IAiDtB,CAAC;IA/CO,SAAS,CACf,OAAkC,EAClC,OAAe,EACf,WAAoB;QAEpB,IAAI,IAAI,CAAC,KAAK,EAAE;YACf,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;YACnB,qBAAqB;YACrB,MAAM,aAAa,GAAG,aAAa,CAAC,MAAM,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;YAClE,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,YAAY,EAAE,aAAa,CAAC,CAAC;SACzD;QACD,MAAM,OAAO,GAAG,qBAAqB,CACpC,OAAO,EACP,WAAW,EACX,IAAI,CAAC,kBAAkB,EACvB,IAAI,CAAC,QAAQ,EACb,IAAI,CAAC,KAAK,CACV,CAAC;QACF,IAAI,CAAC,WAAW,IAAI,OAAO,EAAE;YAC5B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;SACpC;IACF,CAAC;IAEM,cAAc,CAAC,MAAiC;QACtD,0BAA0B;QAC1B,kBAAkB,CAAC,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,kBAAkB,EAAE,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;QACzF,SAAS,CAAC,IAAI,CAAC,KAAK,EAAE;YACrB,KAAK,EAAE,OAAO;YACd,OAAO,EAAE,CAAC,UAAU,EAAE,UAAU,CAAC;YACjC,kBAAkB,EAAE,IAAI;YACxB,KAAK,EAAE,CAAC;SACR,CAAC,CAAC;QACH,SAAS,CAAC,IAAI,CAAC,QAAQ,EAAE;YACxB,KAAK,EAAE,UAAU;YACjB,OAAO,EAAE,CAAC,aAAa,EAAE,UAAU,CAAC;YACpC,kBAAkB,EAAE,IAAI;YACxB,KAAK,EAAE,CAAC;SACR,CAAC,CAAC;QACH,SAAS,CAAC,IAAI,CAAC,QAAQ,EAAE;YACxB,KAAK,EAAE,UAAU;YACjB,OAAO,EAAE,CAAC,aAAa,EAAE,UAAU,CAAC;YACpC,kBAAkB,EAAE,IAAI;YACxB,kBAAkB,EAAE,IAAI;YACxB,YAAY,EAAE,IAAI;YAClB,KAAK,EAAE,CAAC;SACR,CAAC,CAAC;IACJ,CAAC;CACD;AAED;;GAEG;AACH,MAAM,qBAAqB;IAA3B;QACkB,qBAAgB,GAAG,IAAI,GAAG,EAA4B,CAAC;QACvD,aAAQ,GAAG,IAAI,GAAG,EAAkB,CAAC;QACrC,kBAAa,GAAG,IAAI,GAAG,EAA4B,CAAC;QACpD,gBAAW,GAAG,IAAI,GAAG,EAA4B,CAAC;QACnE,qEAAqE;QACpD,aAAQ,GAAG,IAAI,GAAG,EAAmD,CAAC;IAsCxF,CAAC;IApCO,SAAS,CACf,OAAkC,EAClC,OAAe,EACf,WAAoB;QAEpB,IAAI,CAAC,WAAW,EAAE;YACjB,SAAS,CACR,OAAO,EACP,IAAI,CAAC,QAAQ,EACb,IAAI,CAAC,WAAW,EAChB,OAAO,EACP,IAAI,CAAC,aAAa,EAClB,IAAI,CAAC,gBAAgB,EACrB,IAAI,CAAC,QAAQ,CACb,CAAC;SACF;IACF,CAAC;IAEM,cAAc,CAAC,MAAiC;QACtD,SAAS,CAAC,IAAI,CAAC,gBAAgB,EAAE;YAChC,KAAK,EAAE,cAAc;YACrB,OAAO,EAAE,CAAC,UAAU,EAAE,OAAO,CAAC;YAC9B,KAAK,EAAE,EAAE;SACT,CAAC,CAAC;QACH,SAAS,CAAC,gBAAgB,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,WAAW,CAAC,EAAE;YAC5D,KAAK,EAAE,cAAc;YACrB,OAAO,EAAE,CAAC,UAAU,EAAE,OAAO,CAAC;YAC9B,KAAK,EAAE,CAAC;SACR,CAAC,CAAC;QACH;;;;;UAKQ;IACT,CAAC;CACD;AAED;;GAEG;AACH,MAAM,uBAAuB;IAA7B;QACS,cAAS,GAAG,CAAC,CAAC;QACd,aAAQ,GAAG,CAAC,CAAC;QACb,iBAAY,GAAG,CAAC,CAAC;QACjB,gBAAW,GAAG,CAAC,CAAC;QAChB,aAAQ,GAAG,KAAK,CAAC;IA2B1B,CAAC;IAzBO,SAAS,CACf,OAAkC,EAClC,OAAe,EACf,WAAoB;QAEpB,IAAI,CAAC,SAAS,IAAI,OAAO,CAAC;QAC1B,IAAI,CAAC,QAAQ,EAAE,CAAC;QAChB,IAAI,CAAC,WAAW,EAAE;YACjB,IAAI,CAAC,YAAY,IAAI,OAAO,CAAC;YAC7B,IAAI,CAAC,WAAW,EAAE,CAAC;SACnB;aAAM;YACN,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;SACrB;IACF,CAAC;IAEM,cAAc,CAAC,MAAiC;QACtD,IAAI,IAAI,CAAC,QAAQ,EAAE;YAClB,OAAO,CAAC,GAAG,CACV,+EAA+E,IAAI,CAAC,YAAY,MAAM,IAAI,CAAC,SAAS,cAAc,IAAI,CAAC,WAAW,MAAM,IAAI,CAAC,QAAQ,EAAE,CACvK,CAAC;SACF;QACD,IAAI,IAAI,CAAC,QAAQ,KAAK,CAAC,EAAE;YACxB,OAAO,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC;SACnC;IACF,CAAC;CACD;AAED;;GAEG;AACH,MAAM,sBAAsB;IAA5B;QACkB,YAAO,GAAG,IAAI,CAAC;QACxB,YAAO,GAAG,CAAC,CAAC;QACZ,SAAI,GAAG,CAAC,CAAC;QACT,cAAS,GAAG,CAAC,CAAC;QACd,kBAAa,GAAG,CAAC,CAAC;QACT,WAAM,GAAG,IAAI,GAAG,EAA4B,CAAC;IAuC/D,CAAC;IArCO,SAAS,CACf,OAAkC,EAClC,OAAe,EACf,WAAoB;QAEpB,IAAI,OAAO,CAAC,cAAc,IAAI,IAAI,CAAC,OAAO,EAAE;YAC3C,IAAI,OAAO,CAAC,cAAc,KAAK,CAAC,EAAE;gBACjC,MAAM,QAAQ,GAAG,gBAAgB,CAAC,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC;gBACtE,MAAM,SAAS,GAAG,UAAU,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,KACtD,IAAI,CAAC,OAAO,GAAG,CAChB,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;gBACf,MAAM,UAAU,GAAG,WAAW,gBAAgB,CAC7C,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,aAAa,CACnC,KAAK,gBAAgB,CAAC,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC;gBAClE,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,SAAS,IAAI,UAAU,EAAE,EAAE,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;aACrE;iBAAM;gBACN,IAAI,CAAC,aAAa,GAAG,OAAO,CAAC,SAAS,CAAC;aACvC;YACD,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,OAAO,CAAC;YAC7B,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC;YACd,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC;SACnC;QACD,IAAI,CAAC,WAAW,EAAE;YACjB,IAAI,CAAC,IAAI,IAAI,OAAO,CAAC;SACrB;IACF,CAAC;IAEM,cAAc,CAAC,MAAiC;QACtD,SAAS,CAAC,IAAI,CAAC,MAAM,EAAE;YACtB,KAAK,EAAE,wBAAwB;YAC/B,OAAO,EAAE,CAAC,aAAa,EAAE,OAAO,CAAC;YACjC,kBAAkB,EAAE,IAAI;YACxB,WAAW,EAAE,IAAI;YACjB,YAAY,EAAE,IAAI;YAClB,KAAK,EAAE,CAAC;SACR,CAAC,CAAC;IACJ,CAAC;CACD;AAED;;GAEG;AACH,MAAM,wBAAwB;IAA9B;QACS,oBAAe,GAAG,CAAC,CAAC;QACpB,UAAK,GAAG,CAAC,CAAC;IAiBnB,CAAC;IAfO,SAAS,CACf,OAAkC,EAClC,OAAe,EACf,WAAoB;QAEpB,MAAM,KAAK,GAAG,OAAO,CAAC,cAAc,GAAG,OAAO,CAAC,qBAAqB,CAAC;QACrE,IAAI,KAAK,GAAG,IAAI,CAAC,eAAe,EAAE;YACjC,IAAI,CAAC,eAAe,GAAG,KAAK,CAAC;YAC7B,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,cAAc,CAAC;SACpC;IACF,CAAC;IAEM,cAAc,CAAC,MAAiC;QACtD,OAAO,CAAC,GAAG,CAAC,iCAAiC,IAAI,CAAC,eAAe,UAAU,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;IAC1F,CAAC;CACD;AAED;;GAEG;AACH,MAAM,eAAe;IAArB;QACS,kBAAa,GAAG,CAAC,CAAC;QAClB,gBAAW,GAAG,CAAC,CAAC;QAChB,WAAM,GAAG,CAAC,CAAC;QACX,gBAAW,GAAG,MAAM,CAAC,gBAAgB,CAAC;QACtC,WAAM,GAAG,CAAC,CAAC;QACX,gBAAW,GAAG,CAAC,CAAC;QAChB,mBAAc,GAAG,CAAC,CAAC;IAqD5B,CAAC;IAnDO,SAAS,CACf,OAAkC,EAClC,OAAe,EACf,WAAoB;QAEpB,IAAI,OAAO,CAAC,IAAI,KAAK,kCAAW,CAAC,UAAU,EAAE;YAC5C,MAAM,QAAQ,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,aAAa,GAAG,CAAC,CAAC;YACjE,IAAI,IAAI,CAAC,WAAW,GAAG,QAAQ,EAAE;gBAChC,IAAI,CAAC,WAAW,GAAG,QAAQ,CAAC;gBAC5B,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;aACrC;YACD,IAAI,IAAI,CAAC,WAAW,GAAG,QAAQ,EAAE;gBAChC,IAAI,CAAC,WAAW,GAAG,QAAQ,CAAC;gBAC5B,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;aACrC;YAED,IAAI,CAAC,aAAa,GAAG,OAAO,CAAC,cAAc,CAAC;SAC5C;QACD,IAAI,OAAO,CAAC,IAAI,KAAK,kCAAW,CAAC,UAAU,IAAI,OAAO,CAAC,IAAI,KAAK,kCAAW,CAAC,WAAW,EAAE;YACxF,MAAM,QAAQ,GAAsB,OAAO,CAAC,QAAuC;iBACjF,eAAe,CAAC;YAClB,MAAM,QAAQ,GAAG,OAAO,CAAC,cAAc,GAAG,QAAQ,CAAC,qBAAqB,CAAC;YACzE,IAAI,QAAQ,GAAG,IAAI,CAAC,WAAW,EAAE;gBAChC,IAAI,CAAC,WAAW,GAAG,QAAQ,CAAC;gBAC5B,IAAI,CAAC,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC;aAC7C;SACD;IACF,CAAC;IAEM,cAAc,CAAC,MAAiC;QACtD,MAAM,QAAQ,GAAG,MAAM,CAAC,cAAc,GAAG,IAAI,CAAC,aAAa,CAAC;QAC5D,IAAI,IAAI,CAAC,WAAW,GAAG,QAAQ,EAAE;YAChC,IAAI,CAAC,WAAW,GAAG,QAAQ,CAAC;YAC5B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,cAAc,GAAG,CAAC,CAAC;SACxC;QAED,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,IAAI,IAAI,CAAC,WAAW,KAAK,MAAM,CAAC,gBAAgB,EAAE;YACjD,OAAO,CAAC,GAAG,CAAC,qCAAqC,CAAC,CAAC;SACnD;aAAM;YACN,OAAO,CAAC,GAAG,CACV,uCAAuC,IAAI,CAAC,WAAW,UAAU,IAAI,CAAC,MAAM,EAAE,CAC9E,CAAC;YACF,OAAO,CAAC,GAAG,CACV,wCAAwC,IAAI,CAAC,WAAW,UAAU,IAAI,CAAC,cAAc,EAAE,CACvF,CAAC;YACF,OAAO,CAAC,GAAG,CACV,uCAAuC,IAAI,CAAC,WAAW,UAAU,IAAI,CAAC,MAAM,EAAE,CAC9E,CAAC;SACF;IACF,CAAC;CACD;AAED;;GAEG;AACH,MAAM,aAAa;IACX,SAAS,CACf,OAAkC,EAClC,OAAe,EACf,WAAoB;QAEpB,IAAI,CAAC,WAAW,EAAE;YACjB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC;SACnD;IACF,CAAC;IAEM,cAAc,CAAC,MAAiC,IAAS,CAAC;CACjE;AAEM,KAAK,UAAU,iBAAiB,CACtC,SAAS,EAAE,+CAA+C;AAC1D,gBAAyB,EACzB,YAAqB,EACrB,oBAAiC,IAAI,GAAG,EAAU;;IAElD,IAAI,WAAkD,CAAC;IAEvD,MAAM,SAAS,GAAuB;QACrC,IAAI,uBAAuB,EAAE;QAC7B,IAAI,eAAe,EAAE;QACrB,IAAI,qBAAqB,EAAE;QAC3B,IAAI,sBAAsB,EAAE;QAC5B,IAAI,wBAAwB,EAAE;QAC9B,IAAI,eAAe,EAAE;KACrB,CAAC;IAEF,IAAI,YAAY,EAAE;QACjB,SAAS,CAAC,IAAI,CAAC,IAAI,aAAa,EAAE,CAAC,CAAC;KACpC;;QAED,KAA6B,IAAA,cAAA,cAAA,SAAS,CAAA,eAAA;YAA3B,MAAM,QAAQ,sBAAA,CAAA;YACxB,KAAK,MAAM,OAAO,IAAI,QAAuC,EAAE;gBAC9D,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC;gBAC/C,WAAW,GAAG,OAAO,CAAC;gBAEtB,MAAM,WAAW,GAChB,iBAAiB,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;gBAEtE,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE;oBACjC,QAAQ,CAAC,SAAS,CAAC,OAAO,EAAE,OAAO,EAAE,WAAW,CAAC,CAAC;iBAClD;aACD;SACD;;;;;;;;;IAED,IAAI,WAAW,KAAK,SAAS,EAAE;QAC9B,IAAI,gBAAgB,EAAE;YACrB,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE;gBACjC,QAAQ,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC;aACrC;SACD;aAAM;YACN,+BAA+B;YAC/B,SAAS,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC;SACzC;KACD;IACD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;AACjB,CAAC;AA9CD,8CA8CC;AAED,SAAS,SAAS,CACjB,cAAyC,EACzC,QAA6B,EAC7B,WAA0C,EAC1C,OAAe,EACf,aAA4C,EAC5C,gBAA+C,EAC/C,QAA8D;IAE9D,IAAI,IAAI,GAAG,cAAc,CAAC,IAAI,CAAC;IAC/B,IAAI,QAAQ,GAAG,KAAK,CAAC;IACrB,IAAI,YAAY,GAAG,OAAO,CAAC;IAC3B,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,IAAI,IAAA,wCAAoB,EAAC,cAAc,CAAC,EAAE;QACzC,MAAM,WAAW,GAAG,cAAc,CAAC,IAA4B,CAAC;QAChE,QAAQ,WAAW,EAAE;YACpB,KAAK,wCAAoB,CAAC,MAAM,CAAC,CAAC;gBACjC,MAAM,aAAa,GAAG,cAAc,CAAC,QAA0B,CAAC;gBAChE,wBAAwB,CAAC,aAAa,EAAE,QAAQ,CAAC,CAAC;gBAClD,MAAM;aACN;YACD,sDAAsD;YACtD,KAAK,wCAAoB,CAAC,UAAU,CAAC,CAAC;gBACrC,MAAM;aACN;YACD,KAAK,wCAAoB,CAAC,SAAS,CAAC,CAAC;gBACpC,MAAM,KAAK,GAAG,cAAc,CAAC,QAAsB,CAAC;gBACpD,+FAA+F;gBAC/F,4EAA4E;gBAC5E,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,cAAc,CAAC,QAAkB,CAAC,EAAE;oBACrD,4EAA4E;oBAC5E,QAAQ,CAAC,GAAG,CAAC,cAAc,CAAC,QAAkB,EAAE;wBAC/C,MAAM,EAAE,IAAI,KAAK,CAAS,KAAK,CAAC,WAAW,CAAC;wBAC5C,SAAS,EAAE,CAAC;qBACZ,CAAC,CAAC;iBACH;gBACD,4EAA4E;gBAC5E,MAAM,KAAK,GAAG,QAAQ,CAAC,GAAG,CAAC,cAAc,CAAC,QAAkB,CAAC,CAAC;gBAC9D,IAAA,qBAAM,EAAC,KAAK,KAAK,SAAS,EAAE,KAAK,CAAC,kCAAkC,CAAC,CAAC;gBACtE,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;gBAC5B,MAAM,UAAU,GAAG,KAAK,CAAC,OAAO,GAAG,CAAC,CAAC;gBACrC,IAAI,MAAM,CAAC,UAAU,CAAC,KAAK,SAAS,EAAE;oBACrC,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;iBAC1C;gBACD,MAAM,CAAC,UAAU,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC;gBACpC,KAAK,CAAC,SAAS,IAAI,OAAO,CAAC;gBAC3B,IAAI,KAAK,CAAC,OAAO,KAAK,KAAK,CAAC,WAAW,EAAE;oBACxC,OAAO,GAAG,KAAK,CAAC,WAAW,CAAC,CAAC,uBAAuB;oBACpD,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;oBACrD,cAAc,CAAC,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;oBAC1C,cAAc,CAAC,IAAI,GAAG,KAAK,CAAC,YAAY,CAAC;oBACzC,IAAI,GAAG,KAAK,CAAC,YAAY,CAAC;oBAC1B,YAAY,GAAG,KAAK,CAAC,SAAS,CAAC;oBAC/B,QAAQ,CAAC,MAAM,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC;iBACzC;qBAAM;oBACN,OAAO;iBACP;gBACD,0CAA0C;aAC1C;YACD,KAAK,wCAAoB,CAAC,YAAY,CAAC;YACvC,KAAK,wCAAoB,CAAC,gBAAgB,CAAC;YAC3C,KAAK,wCAAoB,CAAC,KAAK,CAAC;YAChC,KAAK,wCAAoB,CAAC,MAAM,CAAC,CAAC;gBACjC,IAAI,QAAQ,GAAG,cAAc,CAAC,QAAqB,CAAC;gBACpD,gBAAgB;gBAChB,IAAI,QAAQ,KAAK,SAAS,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE;oBAC3D,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;iBAChC;gBACD,MAAM,YAAY,GAAG,QAAQ,CAAC,QAG7B,CAAC;gBACF,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC;gBACjC,IAAI,GAAG,GAAG,IAAI,IAAI,YAAY,CAAC,IAAI,EAAE,CAAC;gBACtC,QAAQ,YAAY,CAAC,IAAI,EAAE;oBAC1B,KAAK,gCAAoB,CAAC,MAAM,CAAC,CAAC;wBACjC,MAAM,aAAa,GAAG,YAAY,CAAC,OAAyB,CAAC;wBAC7D,IAAI,UAAU,GAAG,aAAa,CAAC,IAAI,CAAC;wBACpC,IAAI,UAAU,CAAC,UAAU,CAAC,gBAAgB,CAAC,EAAE;4BAC5C,UAAU,GAAG,UAAU,CAAC,SAAS,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC;yBAC3D;wBACD,QAAQ,CAAC,GAAG,CAAC,WAAW,CAAC,OAAO,EAAE,aAAa,CAAC,EAAE,CAAC,EAAE,UAAU,CAAC,CAAC;wBACjE,MAAM;qBACN;oBACD,KAAK,gCAAoB,CAAC,SAAS,CAAC;oBACpC,OAAO,CAAC,CAAC;wBACR,MAAM,aAAa,GAAG,YAAY,CAAC,OAAoB,CAAC;wBACxD,MAAM,aAAa,GAAG,aAAa,CAAC,QAGnC,CAAC;wBAEF,MAAM,QAAQ,GAAG,WAAW,CAAC,OAAO,EAAE,aAAa,CAAC,OAAO,CAAC,CAAC;wBAC7D,IAAI,CAAC,WAAW,EAAE,QAAQ,EAAE,YAAY,EAAE,OAAO,CAAC,CAAC;wBACnD,IAAI,UAAU,GAAG,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;wBACxC,IAAI,UAAU,KAAK,SAAS,EAAE;4BAC7B,iCAAiC;4BACjC,QAAQ,CAAC,GAAG,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;4BACjC,UAAU,GAAG,QAAQ,CAAC;yBACtB;wBACD,IAAI,CAAC,aAAa,EAAE,UAAU,EAAE,YAAY,EAAE,OAAO,CAAC,CAAC;wBACvD,QAAQ,GAAG,IAAI,CAAC;wBAEhB,IAAI,OAAO,GAAG,aAAa,CAAC,IAAI,CAAC;wBACjC,IACC,aAAa,CAAC,IAAI,KAAK,KAAK;4BAC5B,OAAO,aAAa,CAAC,KAAK,KAAK,QAAQ;4BACvC,aAAa,CAAC,KAAK,KAAK,IAAI,EAC3B;4BACD,IAAI,GAAG,GAAG,IAAI,IAAI,OAAO,EAAE,CAAC;4BAC5B,OAAO,GAAG,aAAa,CAAC,KAAK,CAAC,IAAI,CAAC;yBACnC;6BAAM,IAAI,UAAU,KAAK,WAAW,IAAI,OAAO,KAAK,SAAS,EAAE;4BAC/D,MAAM,KAAK,GAAG,CAAC,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC;4BACxD,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,SAAS,EAAE;gCACjC,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC;6BACzB;yBACD;wBACD,IAAI,OAAO,KAAK,SAAS,EAAE;4BAC1B,IAAI,GAAG,GAAG,IAAI,IAAI,OAAO,EAAE,CAAC;yBAC5B;wBAED,IAAI,GAAG,GAAG,IAAI,KAAK,UAAU,GAAG,CAAC;qBACjC;iBACD;gBACD,MAAM;aACN;YACD;gBACC,IAAA,8BAAe,EAAC,WAAW,EAAE,8BAA8B,CAAC,CAAC;SAC9D;KACD;IAED,IAAI,CAAC,gBAAgB,EAAE,IAAI,EAAE,YAAY,EAAE,OAAO,CAAC,CAAC;IACpD,IAAI,CAAC,QAAQ,EAAE;QACd,uCAAuC;QACvC,MAAM,QAAQ,GAAG,mBAAmB,CAAC;QACrC,MAAM,UAAU,GAAG,QAAQ,CAAC;QAC5B,IAAI,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,SAAS,EAAE;YACzC,QAAQ,CAAC,GAAG,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;SACjC;QACD,IAAI,CAAC,WAAW,EAAE,QAAQ,EAAE,YAAY,EAAE,OAAO,CAAC,CAAC;QACnD,IAAI,CAAC,aAAa,EAAE,UAAU,EAAE,YAAY,EAAE,OAAO,CAAC,CAAC;KACvD;AACF,CAAC;AAED,SAAS,wBAAwB,CAChC,aAAsC,EACtC,QAA6B;IAE7B,mEAAmE;IAEnE,+DAA+D;IAC/D,yBAAyB;IACzB,MAAM,mBAAmB,GACxB,OAAO,aAAa,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC;IAC/E,KAAK,MAAM,KAAK,IAAI,mBAAmB,CAAC,QAAQ,CAAC,OAAO,EAAE;QACzD,IAAI,KAAK,CAAC,IAAI,KAAK,gCAAS,CAAC,IAAI,EAAE;YAClC,KAAK,MAAM,MAAM,IAAI,KAAK,CAAC,KAAK,CAAC,OAAO,EAAE;gBACzC,IAAI,MAAM,CAAC,IAAI,KAAK,aAAa,IAAI,MAAM,CAAC,IAAI,KAAK,gCAAS,CAAC,IAAI,EAAE;oBACpE,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;oBACjD,IAAI,UAAU,GAAW,MAAM,CAAC,IAAI,CAAC;oBACrC,IAAI,UAAU,CAAC,UAAU,CAAC,gBAAgB,CAAC,EAAE;wBAC5C,UAAU,GAAG,UAAU,CAAC,SAAS,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC;qBAC3D;oBACD,QAAQ,CAAC,GAAG,CAAC,WAAW,CAAC,mBAAmB,CAAC,EAAE,EAAE,KAAK,CAAC,IAAI,CAAC,EAAE,UAAU,CAAC,CAAC;iBAC1E;aACD;SACD;KACD;AACF,CAAC;AAED,SAAS,kBAAkB,CAC1B,eAAuB,EACvB,kBAA8C,EAC9C,QAAuC,EACvC,KAAoC;IAEpC,MAAM,cAAc,GAAG,IAAI,GAAG,EAA4B,CAAC;IAE3D,KAAK,MAAM,CAAC,QAAQ,EAAE,GAAG,CAAC,IAAI,kBAAkB,EAAE;QACjD,MAAM,WAAW,GAAG,GAAG,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;QAC/C,IAAI,QAAQ,KAAK,YAAY,EAAE;YAC9B,MAAM,WAAW,GAAG,GAAG,QAAQ,KAAK,WAAW,CAAC,KAAK,GAAG,CAAC;YACzD,MAAM,cAAc,GAAqB;gBACxC,gBAAgB,CAAC,WAAW,CAAC,QAAQ,CAAC;gBACtC,WAAW,CAAC,OAAO;aACnB,CAAC;YACF,QAAQ,CAAC,GAAG,CAAC,WAAW,EAAE,cAAc,CAAC,CAAC;YAC1C,cAAc,CAAC,GAAG,CAAC,WAAW,EAAE,cAAc,CAAC,CAAC;SAChD;aAAM;YACN,QAAQ,CAAC,GAAG,CAAC,wCAAwC,EAAE;gBACtD,gBAAgB,CAAC,WAAW,CAAC,QAAQ,CAAC;gBACtC,WAAW,CAAC,OAAO;aACnB,CAAC,CAAC;SACH;QACD,IAAI,CAAC,KAAK,EAAE,WAAW,CAAC,KAAK,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC;KACpD;IAED,IAAI,cAAc,CAAC,IAAI,GAAG,CAAC,EAAE;QAC5B,SAAS,CAAC,cAAc,EAAE;YACzB,KAAK,EAAE,iBAAiB;YACxB,OAAO,EAAE,CAAC,UAAU,EAAE,UAAU,CAAC;YACjC,KAAK,EAAE,CAAC;YACR,kBAAkB,EAAE,IAAI;YACxB,YAAY,EAAE,IAAI;SAClB,CAAC,CAAC;KACH;AACF,CAAC;AAED,SAAS,gBAAgB,CACxB,QAA6B,EAC7B,WAA0C;IAE1C,MAAM,YAAY,GAAG,IAAI,GAAG,EAA4B,CAAC;IACzD,KAAK,MAAM,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,QAAQ,EAAE;QACxC,IAAI,KAAK,GAAG,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACtC,IAAI,KAAK,KAAK,SAAS,EAAE;YACxB,KAAK,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;SACf;QACD,IAAI,IAAI,KAAK,QAAQ,EAAE;YACtB,YAAY,CAAC,GAAG,CAAC,GAAG,QAAQ,EAAE,EAAE,KAAK,CAAC,CAAC;SACvC;aAAM;YACN,YAAY,CAAC,GAAG,CAAC,GAAG,QAAQ,KAAK,IAAI,GAAG,EAAE,KAAK,CAAC,CAAC;SACjD;KACD;IACD,OAAO,YAAY,CAAC;AACrB,CAAC;AAED,SAAS,qBAAqB,CAC7B,OAAkC,EAClC,WAAoB,EACpB,kBAA8C,EAC9C,QAAuC,EACvC,KAAoC;IAEpC,IAAI,OAAkC,CAAC;IACvC,MAAM,UAAU,GAAI,OAAe,CAAC,IAAI,CAAC;IACzC,IAAI,OAAO,CAAC,IAAI,KAAK,MAAM,EAAE;QAC5B,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;QACpC,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;QAC7D,kBAAkB,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;KAC/C;SAAM,IAAI,OAAO,CAAC,IAAI,KAAK,OAAO,EAAE;QACpC,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;QACxC,OAAO,GAAG,kBAAkB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC3C,kBAAkB,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QACpC,IAAA,qBAAM,EAAC,CAAC,CAAC,OAAO,EAAE,KAAK,CAAC,wDAAwD,CAAC,CAAC;QAClF,IAAI,OAAO,KAAK,SAAS,EAAE;YAC1B,IAAI,CAAC,WAAW,EAAE;gBACjB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;aACpC;YACD,MAAM,WAAW,GAAiB,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;YACnE,QAAQ,CAAC,GAAG,CAAC,GAAG,QAAQ,KAAK,WAAW,CAAC,KAAK,GAAG,EAAE;gBAClD,gBAAgB,CAAC,WAAW,CAAC,QAAQ,CAAC;gBACtC,WAAW,CAAC,OAAO;aACnB,CAAC,CAAC;YACH,IAAI,CAAC,KAAK,EAAE,WAAW,CAAC,KAAK,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC;YACpD,OAAO,GAAG,SAAS,CAAC,CAAC,+BAA+B;SACpD;KACD;SAAM;QACN,+BAA+B;QAC/B,+FAA+F;QAC/F,4EAA4E;QAC5E,OAAO,GAAG,kBAAkB,CAAC,GAAG,CAAC,OAAO,CAAC,QAAkB,CAAC,CAAC;QAC7D,IAAI,OAAO,KAAK,SAAS,EAAE;YAC1B,OAAO,GAAG,kBAAkB,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;YAC/C,IAAA,qBAAM,EAAC,CAAC,CAAC,OAAO,EAAE,KAAK,CAAC,wDAAwD,CAAC,CAAC;SAClF;KACD;IACD,OAAO,OAAO,CAAC;AAChB,CAAC;AAED,MAAM,gBAAgB,GAAG,CAAC,IAAY,EAAU,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert, unreachableCase } from \"@fluidframework/common-utils\";\nimport {\n\tISequencedDocumentMessage,\n\tISummaryAck,\n\tISummaryNack,\n\tISummaryProposal,\n\tMessageType,\n\tTreeEntry,\n} from \"@fluidframework/protocol-definitions\";\nimport { IAttachMessage, IEnvelope } from \"@fluidframework/runtime-definitions\";\nimport {\n\tIChunkedOp,\n\tContainerMessageType,\n\tunpackRuntimeMessage,\n} from \"@fluidframework/container-runtime\";\nimport { DataStoreMessageType } from \"@fluidframework/datastore\";\n\nconst noClientName = \"No Client\";\nconst objectTypePrefix = \"https://graph.microsoft.com/types/\";\n\nfunction incr(map: Map<string, [number, number]>, key: string, size: number, count = 1) {\n\tconst value = map.get(key);\n\tif (value === undefined) {\n\t\tmap.set(key, [count, size]);\n\t} else {\n\t\tvalue[0] += count;\n\t\tvalue[1] += size;\n\t\tmap.set(key, value);\n\t}\n}\n\ninterface ISessionInfo {\n\tstartSeq: number;\n\topCount: number;\n\temail: string;\n\tduration: number;\n}\n\ninterface IMessageAnalyzer {\n\tprocessOp(op: ISequencedDocumentMessage, msgSize: number, filteredOutOp: boolean): void;\n\treportAnalyzes(lastOp: ISequencedDocumentMessage): void;\n}\n\n/**\n * Helper class to track session statistics\n */\nclass ActiveSession {\n\tpublic static create(email: string, message: ISequencedDocumentMessage) {\n\t\treturn new ActiveSession(email, message);\n\t}\n\n\tprivate opCount = 0;\n\n\tconstructor(\n\t\tprivate readonly email: string,\n\t\tprivate readonly startMessage: ISequencedDocumentMessage,\n\t) {}\n\n\tpublic reportOp(timestamp: number) {\n\t\tthis.opCount++;\n\t}\n\n\tpublic leave(timestamp: number): ISessionInfo {\n\t\treturn {\n\t\t\topCount: this.opCount,\n\t\t\temail: this.email,\n\t\t\tstartSeq: this.startMessage.sequenceNumber,\n\t\t\tduration: timestamp - this.startMessage.timestamp,\n\t\t};\n\t}\n}\n\n// Format a number separating 3 digits by comma\nexport const formatNumber = (num: number): string =>\n\t// eslint-disable-next-line unicorn/no-unsafe-regex\n\tnum.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, \",\");\n\nfunction dumpStats(\n\tmap: Map<string, [number, number]>,\n\tprops: {\n\t\ttitle: string;\n\t\theaders: [string, string];\n\t\tlines?: number;\n\t\torderByFirstColumn?: boolean;\n\t\treverseColumnsInUI?: boolean;\n\t\tremoveTotals?: boolean;\n\t\treverseSort?: boolean;\n\t},\n) {\n\tconst fieldSizes = [10, 14];\n\tconst nameLength = 72;\n\tconst fieldsLength = fieldSizes[0] + fieldSizes[1] + 1;\n\tlet headers = props.headers;\n\n\tlet recordsToShow = props.lines ?? 10;\n\tif (map.size !== recordsToShow && props.removeTotals === undefined && recordsToShow > 1) {\n\t\trecordsToShow--;\n\t}\n\n\tlet sorted: [string, [number, number]][];\n\tconst sortIndex = props.orderByFirstColumn === true ? 0 : 1;\n\tlet add: string;\n\tif (props.reverseSort !== undefined) {\n\t\tsorted = [...map.entries()].sort((a, b) => a[1][sortIndex] - b[1][sortIndex]);\n\t\tadd = \"↑\";\n\t} else {\n\t\tsorted = [...map.entries()].sort((a, b) => b[1][sortIndex] - a[1][sortIndex]);\n\t\tadd = \"↓\";\n\t}\n\theaders[sortIndex] = `${headers[sortIndex]} ${add}`;\n\n\tif (props.reverseColumnsInUI !== undefined) {\n\t\theaders = [headers[1], headers[0]];\n\t\tconst sorted2: [string, [number, number]][] = [];\n\t\tfor (const [name, [count, size]] of sorted) {\n\t\t\tsorted2.push([name, [size, count]]);\n\t\t}\n\t\tsorted = sorted2;\n\t}\n\n\tlet totalCount = 0;\n\tlet sizeTotal = 0;\n\n\tprops.title = `${props.title} (${sorted.length})`;\n\tconst header0 = headers[0].padStart(fieldSizes[0]);\n\tlet overflow = header0.length - fieldSizes[0];\n\tconsole.log(\n\t\t`\\n\\n${props.title.padEnd(nameLength)} │ ${header0} ${headers[1].padStart(\n\t\t\tfieldSizes[1] - overflow,\n\t\t)}`,\n\t);\n\n\tconsole.log(`${\"─\".repeat(nameLength + 1)}┼${\"─\".repeat(fieldsLength + 1)}`);\n\tlet index = 0;\n\tlet allOtherCount = 0;\n\tlet allOtherSize = 0;\n\tfor (const [name, [count, size]] of sorted) {\n\t\tindex++;\n\t\ttotalCount += count;\n\t\tsizeTotal += size;\n\t\tif (index <= recordsToShow) {\n\t\t\tconst item = name.padEnd(nameLength);\n\t\t\toverflow = item.length - nameLength;\n\t\t\tconst col1 = formatNumber(count).padStart(fieldSizes[0] - overflow);\n\t\t\toverflow += col1.length - fieldSizes[0];\n\t\t\tconst col2 = formatNumber(size).padStart(fieldSizes[1] - overflow);\n\t\t\tconsole.log(`${item} │ ${col1} ${col2}`);\n\t\t} else {\n\t\t\tallOtherCount += count;\n\t\t\tallOtherSize += size;\n\t\t}\n\t}\n\n\tif (props.removeTotals === undefined) {\n\t\tif (allOtherCount || allOtherSize) {\n\t\t\tconsole.log(\n\t\t\t\t`${`All Others (${sorted.length - recordsToShow})`.padEnd(\n\t\t\t\t\tnameLength,\n\t\t\t\t)} │ ${formatNumber(allOtherCount).padStart(fieldSizes[0])} ${formatNumber(\n\t\t\t\t\tallOtherSize,\n\t\t\t\t).padStart(fieldSizes[1])}`,\n\t\t\t);\n\t\t}\n\t\tconsole.log(`${\"─\".repeat(nameLength + 1)}┼${\"─\".repeat(fieldsLength + 1)}`);\n\t\tconsole.log(\n\t\t\t`${\"Total\".padEnd(nameLength)} │ ${formatNumber(totalCount).padStart(\n\t\t\t\tfieldSizes[0],\n\t\t\t)} ${formatNumber(sizeTotal).padStart(fieldSizes[1])}`,\n\t\t);\n\t}\n}\n\nconst getObjectId = (dataStoreId: string, id: string) => `[${dataStoreId}]/${id}`;\n\n/**\n * Analyzer for sessions\n */\nclass SessionAnalyzer implements IMessageAnalyzer {\n\tprivate readonly sessionsInProgress = new Map<string, ActiveSession>();\n\tprivate readonly sessions = new Map<string, [number, number]>();\n\tprivate readonly users = new Map<string, [number, number]>();\n\n\tprivate first = true;\n\n\tpublic processOp(\n\t\tmessage: ISequencedDocumentMessage,\n\t\tmsgSize: number,\n\t\tskipMessage: boolean,\n\t): void {\n\t\tif (this.first) {\n\t\t\tthis.first = false;\n\t\t\t// Start of the road.\n\t\t\tconst noNameSession = ActiveSession.create(noClientName, message);\n\t\t\tthis.sessionsInProgress.set(noClientName, noNameSession);\n\t\t}\n\t\tconst session = processQuorumMessages(\n\t\t\tmessage,\n\t\t\tskipMessage,\n\t\t\tthis.sessionsInProgress,\n\t\t\tthis.sessions,\n\t\t\tthis.users,\n\t\t);\n\t\tif (!skipMessage && session) {\n\t\t\tsession.reportOp(message.timestamp);\n\t\t}\n\t}\n\n\tpublic reportAnalyzes(lastOp: ISequencedDocumentMessage): void {\n\t\t// Close any open sessions\n\t\treportOpenSessions(lastOp.timestamp, this.sessionsInProgress, this.sessions, this.users);\n\t\tdumpStats(this.users, {\n\t\t\ttitle: \"Users\",\n\t\t\theaders: [\"Sessions\", \"Op count\"],\n\t\t\treverseColumnsInUI: true,\n\t\t\tlines: 6,\n\t\t});\n\t\tdumpStats(this.sessions, {\n\t\t\ttitle: \"Sessions\",\n\t\t\theaders: [\"Duration(s)\", \"Op count\"],\n\t\t\treverseColumnsInUI: true,\n\t\t\tlines: 6,\n\t\t});\n\t\tdumpStats(this.sessions, {\n\t\t\ttitle: \"Sessions\",\n\t\t\theaders: [\"Duration(s)\", \"Op count\"],\n\t\t\torderByFirstColumn: true,\n\t\t\treverseColumnsInUI: true,\n\t\t\tremoveTotals: true,\n\t\t\tlines: 5,\n\t\t});\n\t}\n}\n\n/**\n * Analyzer for data structures\n */\nclass DataStructureAnalyzer implements IMessageAnalyzer {\n\tprivate readonly messageTypeStats = new Map<string, [number, number]>();\n\tprivate readonly dataType = new Map<string, string>();\n\tprivate readonly dataTypeStats = new Map<string, [number, number]>();\n\tprivate readonly objectStats = new Map<string, [number, number]>();\n\t// eslint-disable-next-line @typescript-eslint/member-delimiter-style\n\tprivate readonly chunkMap = new Map<string, { chunks: string[]; totalSize: number }>();\n\n\tpublic processOp(\n\t\tmessage: ISequencedDocumentMessage,\n\t\tmsgSize: number,\n\t\tskipMessage: boolean,\n\t): void {\n\t\tif (!skipMessage) {\n\t\t\tprocessOp(\n\t\t\t\tmessage,\n\t\t\t\tthis.dataType,\n\t\t\t\tthis.objectStats,\n\t\t\t\tmsgSize,\n\t\t\t\tthis.dataTypeStats,\n\t\t\t\tthis.messageTypeStats,\n\t\t\t\tthis.chunkMap,\n\t\t\t);\n\t\t}\n\t}\n\n\tpublic reportAnalyzes(lastOp: ISequencedDocumentMessage): void {\n\t\tdumpStats(this.messageTypeStats, {\n\t\t\ttitle: \"Message Type\",\n\t\t\theaders: [\"Op count\", \"Bytes\"],\n\t\t\tlines: 20,\n\t\t});\n\t\tdumpStats(calcChannelStats(this.dataType, this.objectStats), {\n\t\t\ttitle: \"Channel name\",\n\t\t\theaders: [\"Op count\", \"Bytes\"],\n\t\t\tlines: 7,\n\t\t});\n\t\t/*\n dumpStats(this.dataTypeStats, {\n title: \"Channel type\",\n headers: [\"Op count\", \"Bytes\"],\n });\n */\n\t}\n}\n\n/**\n * Helper class to report if we filtered out any messages.\n */\nclass FilteredMessageAnalyzer implements IMessageAnalyzer {\n\tprivate sizeTotal = 0;\n\tprivate opsTotal = 0;\n\tprivate sizeFiltered = 0;\n\tprivate opsFiltered = 0;\n\tprivate filtered = false;\n\n\tpublic processOp(\n\t\tmessage: ISequencedDocumentMessage,\n\t\tmsgSize: number,\n\t\tskipMessage: boolean,\n\t): void {\n\t\tthis.sizeTotal += msgSize;\n\t\tthis.opsTotal++;\n\t\tif (!skipMessage) {\n\t\t\tthis.sizeFiltered += msgSize;\n\t\t\tthis.opsFiltered++;\n\t\t} else {\n\t\t\tthis.filtered = true;\n\t\t}\n\t}\n\n\tpublic reportAnalyzes(lastOp: ISequencedDocumentMessage): void {\n\t\tif (this.filtered) {\n\t\t\tconsole.log(\n\t\t\t\t`\\nData is filtered according to --filter:messageType argument(s):\\nOp size: ${this.sizeFiltered} / ${this.sizeTotal}\\nOp count ${this.opsFiltered} / ${this.opsTotal}`,\n\t\t\t);\n\t\t}\n\t\tif (this.opsTotal === 0) {\n\t\t\tconsole.error(\"No ops were found\");\n\t\t}\n\t}\n}\n\n/**\n * Helper class to find places where we generated too many ops\n */\nclass MessageDensityAnalyzer implements IMessageAnalyzer {\n\tprivate readonly opChunk = 1000;\n\tprivate opLimit = 1;\n\tprivate size = 0;\n\tprivate timeStart = 0;\n\tprivate doctimerStart = 0;\n\tprivate readonly ranges = new Map<string, [number, number]>();\n\n\tpublic processOp(\n\t\tmessage: ISequencedDocumentMessage,\n\t\tmsgSize: number,\n\t\tskipMessage: boolean,\n\t): void {\n\t\tif (message.sequenceNumber >= this.opLimit) {\n\t\t\tif (message.sequenceNumber !== 1) {\n\t\t\t\tconst timeDiff = durationFromTime(message.timestamp - this.timeStart);\n\t\t\t\tconst opsString = `ops = [${this.opLimit - this.opChunk}, ${\n\t\t\t\t\tthis.opLimit - 1\n\t\t\t\t}]`.padEnd(26);\n\t\t\t\tconst timeString = `time = [${durationFromTime(\n\t\t\t\t\tthis.timeStart - this.doctimerStart,\n\t\t\t\t)}, ${durationFromTime(message.timestamp - this.doctimerStart)}]`;\n\t\t\t\tthis.ranges.set(`${opsString} ${timeString}`, [timeDiff, this.size]);\n\t\t\t} else {\n\t\t\t\tthis.doctimerStart = message.timestamp;\n\t\t\t}\n\t\t\tthis.opLimit += this.opChunk;\n\t\t\tthis.size = 0;\n\t\t\tthis.timeStart = message.timestamp;\n\t\t}\n\t\tif (!skipMessage) {\n\t\t\tthis.size += msgSize;\n\t\t}\n\t}\n\n\tpublic reportAnalyzes(lastOp: ISequencedDocumentMessage): void {\n\t\tdumpStats(this.ranges, {\n\t\t\ttitle: \"Fastest 1000 op ranges\",\n\t\t\theaders: [\"Duration(s)\", \"Bytes\"],\n\t\t\torderByFirstColumn: true,\n\t\t\treverseSort: true,\n\t\t\tremoveTotals: true,\n\t\t\tlines: 3,\n\t\t});\n\t}\n}\n\n/**\n * Helper class to analyze collab window size\n */\nclass CollabWindowSizeAnalyzer implements IMessageAnalyzer {\n\tprivate maxCollabWindow = 0;\n\tprivate opSeq = 0;\n\n\tpublic processOp(\n\t\tmessage: ISequencedDocumentMessage,\n\t\tmsgSize: number,\n\t\tskipMessage: boolean,\n\t): void {\n\t\tconst value = message.sequenceNumber - message.minimumSequenceNumber;\n\t\tif (value > this.maxCollabWindow) {\n\t\t\tthis.maxCollabWindow = value;\n\t\t\tthis.opSeq = message.sequenceNumber;\n\t\t}\n\t}\n\n\tpublic reportAnalyzes(lastOp: ISequencedDocumentMessage): void {\n\t\tconsole.log(`\\nMaximum collab window size: ${this.maxCollabWindow}, seq# ${this.opSeq}`);\n\t}\n}\n\n/**\n * Helper class to analyze frequency of summaries\n */\nclass SummaryAnalyzer implements IMessageAnalyzer {\n\tprivate lastSummaryOp = 0;\n\tprivate maxDistance = 0;\n\tprivate maxSeq = 0;\n\tprivate minDistance = Number.MAX_SAFE_INTEGER;\n\tprivate minSeq = 0;\n\tprivate maxResponse = 0;\n\tprivate maxResponseSeq = 0;\n\n\tpublic processOp(\n\t\tmessage: ISequencedDocumentMessage,\n\t\tmsgSize: number,\n\t\tskipMessage: boolean,\n\t): void {\n\t\tif (message.type === MessageType.SummaryAck) {\n\t\t\tconst distance = message.sequenceNumber - this.lastSummaryOp - 1;\n\t\t\tif (this.maxDistance < distance) {\n\t\t\t\tthis.maxDistance = distance;\n\t\t\t\tthis.maxSeq = message.sequenceNumber;\n\t\t\t}\n\t\t\tif (this.minDistance > distance) {\n\t\t\t\tthis.minDistance = distance;\n\t\t\t\tthis.minSeq = message.sequenceNumber;\n\t\t\t}\n\n\t\t\tthis.lastSummaryOp = message.sequenceNumber;\n\t\t}\n\t\tif (message.type === MessageType.SummaryAck || message.type === MessageType.SummaryNack) {\n\t\t\tconst contents: ISummaryProposal = (message.contents as ISummaryAck | ISummaryNack)\n\t\t\t\t.summaryProposal;\n\t\t\tconst distance = message.sequenceNumber - contents.summarySequenceNumber;\n\t\t\tif (distance > this.maxResponse) {\n\t\t\t\tthis.maxResponse = distance;\n\t\t\t\tthis.maxResponseSeq = message.sequenceNumber;\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic reportAnalyzes(lastOp: ISequencedDocumentMessage): void {\n\t\tconst distance = lastOp.sequenceNumber - this.lastSummaryOp;\n\t\tif (this.maxDistance < distance) {\n\t\t\tthis.maxDistance = distance;\n\t\t\tthis.maxSeq = lastOp.sequenceNumber + 1;\n\t\t}\n\n\t\tconsole.log(\"\");\n\t\tif (this.minDistance === Number.MAX_SAFE_INTEGER) {\n\t\t\tconsole.log(\"No summaries found in this document\");\n\t\t} else {\n\t\t\tconsole.log(\n\t\t\t\t`Maximum distance between summaries: ${this.maxDistance}, seq# ${this.maxSeq}`,\n\t\t\t);\n\t\t\tconsole.log(\n\t\t\t\t`Maximum server response for summary: ${this.maxResponse}, seq# ${this.maxResponseSeq}`,\n\t\t\t);\n\t\t\tconsole.log(\n\t\t\t\t`Minimum distance between summaries: ${this.minDistance}, seq# ${this.minSeq}`,\n\t\t\t);\n\t\t}\n\t}\n}\n\n/**\n * Helper class to dump messages to console\n */\nclass MessageDumper implements IMessageAnalyzer {\n\tpublic processOp(\n\t\tmessage: ISequencedDocumentMessage,\n\t\tmsgSize: number,\n\t\tskipMessage: boolean,\n\t): void {\n\t\tif (!skipMessage) {\n\t\t\tconsole.log(JSON.stringify(message, undefined, 2));\n\t\t}\n\t}\n\n\tpublic reportAnalyzes(lastOp: ISequencedDocumentMessage): void {}\n}\n\nexport async function printMessageStats(\n\tgenerator, // AsyncGenerator<ISequencedDocumentMessage[]>,\n\tdumpMessageStats: boolean,\n\tdumpMessages: boolean,\n\tmessageTypeFilter: Set<string> = new Set<string>(),\n) {\n\tlet lastMessage: ISequencedDocumentMessage | undefined;\n\n\tconst analyzers: IMessageAnalyzer[] = [\n\t\tnew FilteredMessageAnalyzer(), // Should come first\n\t\tnew SessionAnalyzer(),\n\t\tnew DataStructureAnalyzer(),\n\t\tnew MessageDensityAnalyzer(),\n\t\tnew CollabWindowSizeAnalyzer(),\n\t\tnew SummaryAnalyzer(),\n\t];\n\n\tif (dumpMessages) {\n\t\tanalyzers.push(new MessageDumper());\n\t}\n\n\tfor await (const messages of generator) {\n\t\tfor (const message of messages as ISequencedDocumentMessage[]) {\n\t\t\tconst msgSize = JSON.stringify(message).length;\n\t\t\tlastMessage = message;\n\n\t\t\tconst skipMessage =\n\t\t\t\tmessageTypeFilter.size !== 0 && !messageTypeFilter.has(message.type);\n\n\t\t\tfor (const analyzer of analyzers) {\n\t\t\t\tanalyzer.processOp(message, msgSize, skipMessage);\n\t\t\t}\n\t\t}\n\t}\n\n\tif (lastMessage !== undefined) {\n\t\tif (dumpMessageStats) {\n\t\t\tfor (const analyzer of analyzers) {\n\t\t\t\tanalyzer.reportAnalyzes(lastMessage);\n\t\t\t}\n\t\t} else {\n\t\t\t// Warn about filtered messages\n\t\t\tanalyzers[0].reportAnalyzes(lastMessage);\n\t\t}\n\t}\n\tconsole.log(\"\");\n}\n\nfunction processOp(\n\truntimeMessage: ISequencedDocumentMessage,\n\tdataType: Map<string, string>,\n\tobjectStats: Map<string, [number, number]>,\n\tmsgSize: number,\n\tdataTypeStats: Map<string, [number, number]>,\n\tmessageTypeStats: Map<string, [number, number]>,\n\tchunkMap: Map<string, { chunks: string[]; totalSize: number }>,\n) {\n\tlet type = runtimeMessage.type;\n\tlet recorded = false;\n\tlet totalMsgSize = msgSize;\n\tlet opCount = 1;\n\tif (unpackRuntimeMessage(runtimeMessage)) {\n\t\tconst messageType = runtimeMessage.type as ContainerMessageType;\n\t\tswitch (messageType) {\n\t\t\tcase ContainerMessageType.Attach: {\n\t\t\t\tconst attachMessage = runtimeMessage.contents as IAttachMessage;\n\t\t\t\tprocessDataStoreAttachOp(attachMessage, dataType);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\t// skip for now because these ops do not have contents\n\t\t\tcase ContainerMessageType.BlobAttach: {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase ContainerMessageType.ChunkedOp: {\n\t\t\t\tconst chunk = runtimeMessage.contents as IChunkedOp;\n\t\t\t\t// TODO: Verify whether this should be able to handle server-generated ops (with null clientId)\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion\n\t\t\t\tif (!chunkMap.has(runtimeMessage.clientId as string)) {\n\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion\n\t\t\t\t\tchunkMap.set(runtimeMessage.clientId as string, {\n\t\t\t\t\t\tchunks: new Array<string>(chunk.totalChunks),\n\t\t\t\t\t\ttotalSize: 0,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion\n\t\t\t\tconst value = chunkMap.get(runtimeMessage.clientId as string);\n\t\t\t\tassert(value !== undefined, 0x2b8 /* \"Chunk should be set in map\" */);\n\t\t\t\tconst chunks = value.chunks;\n\t\t\t\tconst chunkIndex = chunk.chunkId - 1;\n\t\t\t\tif (chunks[chunkIndex] !== undefined) {\n\t\t\t\t\tthrow new Error(\"Chunk already assigned\");\n\t\t\t\t}\n\t\t\t\tchunks[chunkIndex] = chunk.contents;\n\t\t\t\tvalue.totalSize += msgSize;\n\t\t\t\tif (chunk.chunkId === chunk.totalChunks) {\n\t\t\t\t\topCount = chunk.totalChunks; // 1 op for each chunk.\n\t\t\t\t\tconst patchedMessage = Object.create(runtimeMessage);\n\t\t\t\t\tpatchedMessage.contents = chunks.join(\"\");\n\t\t\t\t\tpatchedMessage.type = chunk.originalType;\n\t\t\t\t\ttype = chunk.originalType;\n\t\t\t\t\ttotalMsgSize = value.totalSize;\n\t\t\t\t\tchunkMap.delete(patchedMessage.clientId);\n\t\t\t\t} else {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\t// eslint-disable-next-line no-fallthrough\n\t\t\t}\n\t\t\tcase ContainerMessageType.IdAllocation:\n\t\t\tcase ContainerMessageType.FluidDataStoreOp:\n\t\t\tcase ContainerMessageType.Alias:\n\t\t\tcase ContainerMessageType.Rejoin: {\n\t\t\t\tlet envelope = runtimeMessage.contents as IEnvelope;\n\t\t\t\t// TODO: Legacy?\n\t\t\t\tif (envelope !== undefined && typeof envelope === \"string\") {\n\t\t\t\t\tenvelope = JSON.parse(envelope);\n\t\t\t\t}\n\t\t\t\tconst innerContent = envelope.contents as {\n\t\t\t\t\tcontent: any;\n\t\t\t\t\ttype: string;\n\t\t\t\t};\n\t\t\t\tconst address = envelope.address;\n\t\t\t\ttype = `${type}/${innerContent.type}`;\n\t\t\t\tswitch (innerContent.type) {\n\t\t\t\t\tcase DataStoreMessageType.Attach: {\n\t\t\t\t\t\tconst attachMessage = innerContent.content as IAttachMessage;\n\t\t\t\t\t\tlet objectType = attachMessage.type;\n\t\t\t\t\t\tif (objectType.startsWith(objectTypePrefix)) {\n\t\t\t\t\t\t\tobjectType = objectType.substring(objectTypePrefix.length);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tdataType.set(getObjectId(address, attachMessage.id), objectType);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase DataStoreMessageType.ChannelOp:\n\t\t\t\t\tdefault: {\n\t\t\t\t\t\tconst innerEnvelope = innerContent.content as IEnvelope;\n\t\t\t\t\t\tconst innerContent2 = innerEnvelope.contents as {\n\t\t\t\t\t\t\ttype?: string;\n\t\t\t\t\t\t\tvalue?: any;\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\tconst objectId = getObjectId(address, innerEnvelope.address);\n\t\t\t\t\t\tincr(objectStats, objectId, totalMsgSize, opCount);\n\t\t\t\t\t\tlet objectType = dataType.get(objectId);\n\t\t\t\t\t\tif (objectType === undefined) {\n\t\t\t\t\t\t\t// Somehow we do not have data...\n\t\t\t\t\t\t\tdataType.set(objectId, objectId);\n\t\t\t\t\t\t\tobjectType = objectId;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tincr(dataTypeStats, objectType, totalMsgSize, opCount);\n\t\t\t\t\t\trecorded = true;\n\n\t\t\t\t\t\tlet subType = innerContent2.type;\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tinnerContent2.type === \"set\" &&\n\t\t\t\t\t\t\ttypeof innerContent2.value === \"object\" &&\n\t\t\t\t\t\t\tinnerContent2.value !== null\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\ttype = `${type}/${subType}`;\n\t\t\t\t\t\t\tsubType = innerContent2.value.type;\n\t\t\t\t\t\t} else if (objectType === \"mergeTree\" && subType !== undefined) {\n\t\t\t\t\t\t\tconst types = [\"insert\", \"remove\", \"annotate\", \"group\"];\n\t\t\t\t\t\t\tif (types[subType] !== undefined) {\n\t\t\t\t\t\t\t\tsubType = types[subType];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (subType !== undefined) {\n\t\t\t\t\t\t\ttype = `${type}/${subType}`;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\ttype = `${type} (${objectType})`;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\tunreachableCase(messageType, \"Message type not recognized!\");\n\t\t}\n\t}\n\n\tincr(messageTypeStats, type, totalMsgSize, opCount);\n\tif (!recorded) {\n\t\t// const objectId = `${type} (system)`;\n\t\tconst objectId = `(system messages)`;\n\t\tconst objectType = objectId;\n\t\tif (dataType.get(objectId) === undefined) {\n\t\t\tdataType.set(objectId, objectId);\n\t\t}\n\t\tincr(objectStats, objectId, totalMsgSize, opCount);\n\t\tincr(dataTypeStats, objectType, totalMsgSize, opCount);\n\t}\n}\n\nfunction processDataStoreAttachOp(\n\tattachMessage: IAttachMessage | string,\n\tdataType: Map<string, string>,\n) {\n\t// dataType.set(getObjectId(attachMessage.id), attachMessage.type);\n\n\t// That's data store, and it brings a bunch of data structures.\n\t// Let's try to crack it.\n\tconst parsedAttachMessage =\n\t\ttypeof attachMessage === \"string\" ? JSON.parse(attachMessage) : attachMessage;\n\tfor (const entry of parsedAttachMessage.snapshot.entries) {\n\t\tif (entry.type === TreeEntry.Tree) {\n\t\t\tfor (const entry2 of entry.value.entries) {\n\t\t\t\tif (entry2.path === \".attributes\" && entry2.type === TreeEntry.Blob) {\n\t\t\t\t\tconst attrib = JSON.parse(entry2.value.contents);\n\t\t\t\t\tlet objectType: string = attrib.type;\n\t\t\t\t\tif (objectType.startsWith(objectTypePrefix)) {\n\t\t\t\t\t\tobjectType = objectType.substring(objectTypePrefix.length);\n\t\t\t\t\t}\n\t\t\t\t\tdataType.set(getObjectId(parsedAttachMessage.id, entry.path), objectType);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction reportOpenSessions(\n\tlastOpTimestamp: number,\n\tsessionsInProgress: Map<string, ActiveSession>,\n\tsessions: Map<string, [number, number]>,\n\tusers: Map<string, [number, number]>,\n) {\n\tconst activeSessions = new Map<string, [number, number]>();\n\n\tfor (const [clientId, ses] of sessionsInProgress) {\n\t\tconst sessionInfo = ses.leave(lastOpTimestamp);\n\t\tif (clientId !== noClientName) {\n\t\t\tconst sessionName = `${clientId} (${sessionInfo.email})`;\n\t\t\tconst sessionPayload: [number, number] = [\n\t\t\t\tdurationFromTime(sessionInfo.duration),\n\t\t\t\tsessionInfo.opCount,\n\t\t\t];\n\t\t\tsessions.set(sessionName, sessionPayload);\n\t\t\tactiveSessions.set(sessionName, sessionPayload);\n\t\t} else {\n\t\t\tsessions.set(`Full file lifespan (noClient messages)`, [\n\t\t\t\tdurationFromTime(sessionInfo.duration),\n\t\t\t\tsessionInfo.opCount,\n\t\t\t]);\n\t\t}\n\t\tincr(users, sessionInfo.email, sessionInfo.opCount);\n\t}\n\n\tif (activeSessions.size > 0) {\n\t\tdumpStats(activeSessions, {\n\t\t\ttitle: \"Active sessions\",\n\t\t\theaders: [\"Duration\", \"Op count\"],\n\t\t\tlines: 6,\n\t\t\torderByFirstColumn: true,\n\t\t\tremoveTotals: true,\n\t\t});\n\t}\n}\n\nfunction calcChannelStats(\n\tdataType: Map<string, string>,\n\tobjectStats: Map<string, [number, number]>,\n) {\n\tconst channelStats = new Map<string, [number, number]>();\n\tfor (const [objectId, type] of dataType) {\n\t\tlet value = objectStats.get(objectId);\n\t\tif (value === undefined) {\n\t\t\tvalue = [0, 0];\n\t\t}\n\t\tif (type === objectId) {\n\t\t\tchannelStats.set(`${objectId}`, value);\n\t\t} else {\n\t\t\tchannelStats.set(`${objectId} (${type})`, value);\n\t\t}\n\t}\n\treturn channelStats;\n}\n\nfunction processQuorumMessages(\n\tmessage: ISequencedDocumentMessage,\n\tskipMessage: boolean,\n\tsessionsInProgress: Map<string, ActiveSession>,\n\tsessions: Map<string, [number, number]>,\n\tusers: Map<string, [number, number]>,\n) {\n\tlet session: ActiveSession | undefined;\n\tconst dataString = (message as any).data;\n\tif (message.type === \"join\") {\n\t\tconst data = JSON.parse(dataString);\n\t\tsession = ActiveSession.create(data.detail.user.id, message);\n\t\tsessionsInProgress.set(data.clientId, session);\n\t} else if (message.type === \"leave\") {\n\t\tconst clientId = JSON.parse(dataString);\n\t\tsession = sessionsInProgress.get(clientId);\n\t\tsessionsInProgress.delete(clientId);\n\t\tassert(!!session, 0x1b7 /* \"Bad session state for processing quorum messages\" */);\n\t\tif (session !== undefined) {\n\t\t\tif (!skipMessage) {\n\t\t\t\tsession.reportOp(message.timestamp);\n\t\t\t}\n\t\t\tconst sessionInfo: ISessionInfo = session.leave(message.timestamp);\n\t\t\tsessions.set(`${clientId} (${sessionInfo.email})`, [\n\t\t\t\tdurationFromTime(sessionInfo.duration),\n\t\t\t\tsessionInfo.opCount,\n\t\t\t]);\n\t\t\tincr(users, sessionInfo.email, sessionInfo.opCount);\n\t\t\tsession = undefined; // Do not record it second time\n\t\t}\n\t} else {\n\t\t// message.clientId can be null\n\t\t// TODO: Verify whether this should be able to handle server-generated ops (with null clientId)\n\t\t// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion\n\t\tsession = sessionsInProgress.get(message.clientId as string);\n\t\tif (session === undefined) {\n\t\t\tsession = sessionsInProgress.get(noClientName);\n\t\t\tassert(!!session, 0x1b8 /* \"Bad session state for processing quorum messages\" */);\n\t\t}\n\t}\n\treturn session;\n}\n\nconst durationFromTime = (time: number): number => Math.floor(time / 1000);\n"]}
@@ -169,7 +169,7 @@ async function saveSnapshot(name, fetchedData, saveDir) {
169
169
  async function fetchBlobsFromVersion(storage, version) {
170
170
  const tree = await reportErrors(`getSnapshotTree ${version.id}`, storage.getSnapshotTree(version));
171
171
  if (!tree) {
172
- return Promise.reject(new Error("Failed to load snapshot tree"));
172
+ throw new Error("Failed to load snapshot tree");
173
173
  }
174
174
  return fetchBlobsFromSnapshotTree(storage, tree);
175
175
  }
@@ -1 +1 @@
1
- {"version":3,"file":"fluidFetchSnapshot.js","sourceRoot":"","sources":["../src/fluidFetchSnapshot.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 fs from \"fs\";\nimport util from \"util\";\n\nimport { bufferToString, stringToBuffer } from \"@fluidframework/common-utils\";\nimport { IDocumentService, IDocumentStorageService } from \"@fluidframework/driver-definitions\";\nimport { ISnapshotTree, IVersion } from \"@fluidframework/protocol-definitions\";\n\nimport { formatNumber } from \"./fluidAnalyzeMessages\";\nimport {\n\tdumpSnapshotStats,\n\tdumpSnapshotTrees,\n\tdumpSnapshotVersions,\n\tparamActualFormatting,\n\tparamNumSnapshotVersions,\n\tparamSnapshotVersionIndex,\n} from \"./fluidFetchArgs\";\nimport { latestVersionsId } from \"./fluidFetchInit\";\n\ninterface ISnapshotInfo {\n\tblobCountNew: number;\n\tblobCount: number;\n\tsize: number;\n\tsizeNew: number;\n}\n\ntype IFetchedData = IFetchedBlob | IFetchedTree;\n\ninterface IFetchedBlob {\n\ttreePath: string;\n\tfilename: string;\n\tblobId: string;\n\tblob: Promise<ArrayBufferLike | undefined>;\n\treused: boolean;\n}\n\ninterface IFetchedTree {\n\ttreePath: string;\n\tblobId: string;\n\tfilename: string;\n\tblob: ArrayBufferLike;\n\n\treused: false;\n\n\tpatched: boolean;\n}\n\nfunction isFetchedTree(fetchedData: IFetchedData): fetchedData is IFetchedTree {\n\treturn \"patched\" in fetchedData;\n}\n\nconst blobCache = new Map<string, Promise<ArrayBufferLike>>();\nlet blobCachePrevious = new Map<string, Promise<ArrayBufferLike>>();\nlet blobCacheCurrent = new Map<string, Promise<ArrayBufferLike>>();\n\nfunction fetchBlobs(\n\tprefix: string,\n\ttree: ISnapshotTree,\n\tstorage: IDocumentStorageService,\n\tblobIdMap: Map<string, number>,\n) {\n\tconst result: IFetchedBlob[] = [];\n\tfor (const item of Object.keys(tree.blobs)) {\n\t\tconst treePath = `${prefix}${item}`;\n\t\tconst blobId = tree.blobs[item];\n\t\tif (blobId !== null) {\n\t\t\tlet reused = true;\n\t\t\tlet blob = blobCachePrevious.get(blobId);\n\t\t\tif (!blob) {\n\t\t\t\treused = false;\n\t\t\t\tblob = blobCache.get(blobId);\n\t\t\t\tif (blob === undefined) {\n\t\t\t\t\tblob = storage.readBlob(blobId);\n\t\t\t\t\tblobCache.set(blobId, blob);\n\t\t\t\t}\n\t\t\t}\n\t\t\tblobCacheCurrent.set(blobId, blob);\n\n\t\t\t// Use the blobIdMap to assign a number for each unique blob\n\t\t\t// and use it as a prefix for files to avoid case-insensitive fs\n\t\t\tlet index = blobIdMap.get(blobId);\n\t\t\tif (index === undefined) {\n\t\t\t\tindex = blobIdMap.size;\n\t\t\t\tblobIdMap.set(blobId, index);\n\t\t\t}\n\t\t\tconst filename = `${index}-${blobId}`;\n\t\t\tresult.push({ treePath, blobId, blob, reused, filename });\n\n\t\t\t// patch the tree so that we can write it out to reference the file\n\t\t\ttree.blobs[item] = filename;\n\t\t}\n\t}\n\treturn result;\n}\n\nfunction createTreeBlob(tree: ISnapshotTree, prefix: string, patched: boolean): IFetchedTree {\n\tconst id = tree.id ?? \"original\";\n\tconst blob = stringToBuffer(JSON.stringify(tree), \"utf8\");\n\tconst filename = patched ? \"tree\" : `tree-${id}`;\n\tconst treePath = `${prefix}${filename}`;\n\treturn { treePath, blobId: \"original tree $id\", filename, blob, patched, reused: false };\n}\n\nasync function fetchBlobsFromSnapshotTree(\n\tstorage: IDocumentStorageService,\n\ttree: ISnapshotTree,\n\tprefix: string = \"/\",\n\tparentBlobIdMap?: Map<string, number>,\n): Promise<IFetchedData[]> {\n\tconst isTopLevel = !parentBlobIdMap;\n\tif (isTopLevel && dumpSnapshotTrees) {\n\t\tconsole.log(tree);\n\t}\n\n\tif (prefix === \"/\") {\n\t\tblobCachePrevious = blobCacheCurrent;\n\t\tblobCacheCurrent = new Map<string, Promise<ArrayBufferLike>>();\n\t}\n\n\t// Create the tree info before fetching blobs (which will modify it)\n\tlet topLevelBlob: IFetchedTree | undefined;\n\tif (isTopLevel) {\n\t\ttopLevelBlob = createTreeBlob(tree, prefix, false);\n\t}\n\n\tconst blobIdMap = parentBlobIdMap ?? new Map<string, number>();\n\tlet result: IFetchedData[] = fetchBlobs(prefix, tree, storage, blobIdMap);\n\n\tfor (const subtreeId of Object.keys(tree.trees)) {\n\t\tconst subtree = tree.trees[subtreeId];\n\t\tconst dataStoreBlobs = await fetchBlobsFromSnapshotTree(\n\t\t\tstorage,\n\t\t\tsubtree,\n\t\t\t`${prefix}${subtreeId}/`,\n\t\t\tblobIdMap,\n\t\t);\n\t\tresult = result.concat(dataStoreBlobs);\n\t}\n\n\tif (topLevelBlob) {\n\t\tresult.push(topLevelBlob);\n\t\tresult.push(createTreeBlob(tree, prefix, true));\n\t}\n\treturn result;\n}\n\nfunction getDumpFetchedData(fetchedData: IFetchedData[]) {\n\tconst sorted = fetchedData.sort((a, b) => a.treePath.localeCompare(b.treePath));\n\treturn sorted.filter((item) => !isFetchedTree(item) || !item.patched);\n}\n\nasync function dumpSnapshotTreeVerbose(name: string, fetchedData: IFetchedData[]) {\n\tlet size = 0;\n\tconst sorted = getDumpFetchedData(fetchedData);\n\n\tlet nameLength = 10;\n\tfor (const item of sorted) {\n\t\tnameLength = Math.max(nameLength, item.treePath.length);\n\t}\n\n\tconsole.log(\"\");\n\tconsole.log(`${\"Blob Path\".padEnd(nameLength)} | Reused | Bytes`);\n\tconsole.log(\"-\".repeat(nameLength + 26));\n\tfor (const item of sorted) {\n\t\tconst buffer = await item.blob;\n\t\tif (buffer === undefined) {\n\t\t\tcontinue;\n\t\t}\n\t\tconst blob = bufferToString(buffer, \"utf8\");\n\t\tconsole.log(\n\t\t\t`${item.treePath.padEnd(nameLength)} | ${item.reused ? \"X\" : \" \"} | ${formatNumber(\n\t\t\t\tblob.length,\n\t\t\t).padStart(10)}`,\n\t\t);\n\t\tsize += blob.length;\n\t}\n\n\tconsole.log(\"-\".repeat(nameLength + 26));\n\tconsole.log(\n\t\t`${\"Total snapshot size\".padEnd(nameLength)} | | ${formatNumber(size).padStart(10)}`,\n\t);\n}\n\nasync function dumpSnapshotTree(name: string, fetchedData: IFetchedData[]): Promise<ISnapshotInfo> {\n\tlet size = 0;\n\tlet sizeNew = 0;\n\tlet blobCountNew = 0;\n\tconst sorted = getDumpFetchedData(fetchedData);\n\n\tfor (const item of sorted) {\n\t\tconst buffer = await item.blob;\n\t\tif (buffer === undefined) {\n\t\t\tcontinue;\n\t\t}\n\t\tconst blob = bufferToString(buffer, \"utf8\");\n\t\tif (!item.reused) {\n\t\t\tsizeNew += blob.length;\n\t\t\tblobCountNew++;\n\t\t}\n\t\tsize += blob.length;\n\t}\n\n\treturn { blobCountNew, blobCount: sorted.length, size, sizeNew };\n}\n\nasync function saveSnapshot(name: string, fetchedData: IFetchedData[], saveDir: string) {\n\tconst outDir = `${saveDir}/${name}/`;\n\tconst mkdir = util.promisify(fs.mkdir);\n\n\tawait mkdir(`${outDir}/decoded`, { recursive: true });\n\tawait Promise.all(\n\t\tfetchedData.map(async (item) => {\n\t\t\tconst buffer = await item.blob;\n\t\t\tif (buffer === undefined) {\n\t\t\t\tconsole.error(`ERROR: Unable to get data for blob ${item.blobId}`);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (!isFetchedTree(item)) {\n\t\t\t\t// Just write the data as is.\n\t\t\t\tfs.writeFileSync(`${outDir}/${item.filename}`, Buffer.from(buffer));\n\n\t\t\t\t// we assume that the buffer is utf8 here, which currently is true for\n\t\t\t\t// all of our snapshot blobs. It doesn't necessary be true in the future\n\t\t\t\tlet decoded = bufferToString(buffer, \"utf8\");\n\t\t\t\ttry {\n\t\t\t\t\tif (!paramActualFormatting) {\n\t\t\t\t\t\tdecoded = JSON.stringify(JSON.parse(decoded), undefined, 2);\n\t\t\t\t\t}\n\t\t\t\t} catch (e) {}\n\t\t\t\tfs.writeFileSync(`${outDir}/decoded/${item.filename}.json`, decoded);\n\t\t\t} else {\n\t\t\t\t// Write out same data for tree decoded or not, except for formatting\n\t\t\t\tconst treeString = bufferToString(buffer, \"utf8\");\n\t\t\t\tfs.writeFileSync(`${outDir}/${item.filename}.json`, treeString);\n\t\t\t\tfs.writeFileSync(\n\t\t\t\t\t`${outDir}/decoded/${item.filename}.json`,\n\t\t\t\t\tparamActualFormatting\n\t\t\t\t\t\t? treeString\n\t\t\t\t\t\t: JSON.stringify(JSON.parse(treeString), undefined, 2),\n\t\t\t\t);\n\t\t\t}\n\t\t}),\n\t);\n}\n\nasync function fetchBlobsFromVersion(storage: IDocumentStorageService, version: IVersion) {\n\tconst tree = await reportErrors(\n\t\t`getSnapshotTree ${version.id}`,\n\t\tstorage.getSnapshotTree(version),\n\t);\n\tif (!tree) {\n\t\treturn Promise.reject(new Error(\"Failed to load snapshot tree\"));\n\t}\n\treturn fetchBlobsFromSnapshotTree(storage, tree);\n}\n\nasync function reportErrors<T>(message: string, res: Promise<T>) {\n\ttry {\n\t\treturn await res;\n\t} catch (error) {\n\t\tconsole.error(`Error calling ${message}`);\n\t\tthrow error;\n\t}\n}\n\nexport async function fluidFetchSnapshot(documentService?: IDocumentService, saveDir?: string) {\n\tif (\n\t\t!dumpSnapshotStats &&\n\t\t!dumpSnapshotTrees &&\n\t\t!dumpSnapshotVersions &&\n\t\tsaveDir === undefined\n\t) {\n\t\treturn;\n\t}\n\n\t// --local mode - do not connect to storage.\n\t// For now, bail out early.\n\t// In future, separate download from analyzes parts and allow offline analyzes\n\tif (!documentService) {\n\t\treturn;\n\t}\n\n\tconsole.log(\"\\n\");\n\n\tconst storage = await documentService.connectToStorage();\n\n\tlet version: IVersion | undefined;\n\tconst versions = await reportErrors(\n\t\t`getVersions ${latestVersionsId}`,\n\t\tstorage.getVersions(latestVersionsId, paramNumSnapshotVersions),\n\t);\n\tif (dumpSnapshotVersions) {\n\t\tconsole.log(\"Snapshot versions\");\n\t\tconsole.log(versions);\n\t}\n\n\tlet blobsToDump: IFetchedData[] | undefined;\n\tif (paramSnapshotVersionIndex !== undefined) {\n\t\tversion = versions[paramSnapshotVersionIndex];\n\t\tif (version === undefined) {\n\t\t\tconsole.log(\n\t\t\t\t`There are only ${versions.length} snapshots, --snapshotVersionIndex is too large`,\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\t\tif (saveDir !== undefined) {\n\t\t\tblobsToDump = await fetchBlobsFromVersion(storage, version);\n\t\t\tconst name = version.id;\n\t\t\tconsole.log(`Saving snapshot ${name}`);\n\t\t\tawait saveSnapshot(name, blobsToDump, saveDir);\n\t\t}\n\t} else {\n\t\tversion = versions[0];\n\t\tif (saveDir !== undefined && versions.length > 0) {\n\t\t\tconsole.log(\n\t\t\t\t\" Name | Date | Size | New Size | Blobs | New Blobs\",\n\t\t\t);\n\t\t\tconsole.log(\"-\".repeat(86));\n\n\t\t\t// Go in reverse order, to correctly calculate blob reuse - from oldest to newest snapshots\n\t\t\tfor (let i = versions.length - 1; i >= 0; i--) {\n\t\t\t\tconst v = versions[i];\n\t\t\t\tconst blobs = await fetchBlobsFromVersion(storage, v);\n\t\t\t\tblobsToDump = blobs;\n\t\t\t\tconst name = `${i}-${v.id}`;\n\t\t\t\tconst res = await dumpSnapshotTree(name, blobs);\n\n\t\t\t\tlet date = \"\";\n\t\t\t\tif (v.date !== undefined) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tdate = new Date(v.date).toLocaleString();\n\t\t\t\t\t} catch (e) {\n\t\t\t\t\t\tdate = v.date.replace(\"T\", \" \");\n\t\t\t\t\t\tconst index = date.lastIndexOf(\".\");\n\t\t\t\t\t\tif (index > 0) {\n\t\t\t\t\t\t\tdate = `${date.substr(0, index)} Z`;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tdate = date.padStart(23);\n\t\t\t\tconst size = formatNumber(res.size).padStart(10);\n\t\t\t\tconst sizeNew = formatNumber(res.sizeNew).padStart(10);\n\t\t\t\tconst blobCount = formatNumber(res.blobCount).padStart(6);\n\t\t\t\tconst blobCountNew = formatNumber(res.blobCountNew).padStart(9);\n\n\t\t\t\tconsole.log(\n\t\t\t\t\t`${name.padEnd(\n\t\t\t\t\t\t15,\n\t\t\t\t\t)} | ${date} | ${size} | ${sizeNew} | ${blobCount} | ${blobCountNew}`,\n\t\t\t\t);\n\n\t\t\t\tawait saveSnapshot(name, blobs, saveDir);\n\t\t\t}\n\t\t}\n\t}\n\n\tif (dumpSnapshotStats || dumpSnapshotTrees) {\n\t\tif (version === undefined) {\n\t\t\tconsole.log(\"No snapshot tree\");\n\t\t} else {\n\t\t\tif (blobsToDump === undefined) {\n\t\t\t\tblobsToDump = await fetchBlobsFromVersion(storage, version);\n\t\t\t}\n\t\t\tconsole.log(`\\n\\nSnapshot version ${version.id}`);\n\t\t\tawait dumpSnapshotTreeVerbose(version.id, blobsToDump);\n\t\t}\n\t}\n}\n"]}
1
+ {"version":3,"file":"fluidFetchSnapshot.js","sourceRoot":"","sources":["../src/fluidFetchSnapshot.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 fs from \"fs\";\nimport util from \"util\";\n\nimport { bufferToString, stringToBuffer } from \"@fluidframework/common-utils\";\nimport { IDocumentService, IDocumentStorageService } from \"@fluidframework/driver-definitions\";\nimport { ISnapshotTree, IVersion } from \"@fluidframework/protocol-definitions\";\n\nimport { formatNumber } from \"./fluidAnalyzeMessages\";\nimport {\n\tdumpSnapshotStats,\n\tdumpSnapshotTrees,\n\tdumpSnapshotVersions,\n\tparamActualFormatting,\n\tparamNumSnapshotVersions,\n\tparamSnapshotVersionIndex,\n} from \"./fluidFetchArgs\";\nimport { latestVersionsId } from \"./fluidFetchInit\";\n\ninterface ISnapshotInfo {\n\tblobCountNew: number;\n\tblobCount: number;\n\tsize: number;\n\tsizeNew: number;\n}\n\ntype IFetchedData = IFetchedBlob | IFetchedTree;\n\ninterface IFetchedBlob {\n\ttreePath: string;\n\tfilename: string;\n\tblobId: string;\n\tblob: Promise<ArrayBufferLike | undefined>;\n\treused: boolean;\n}\n\ninterface IFetchedTree {\n\ttreePath: string;\n\tblobId: string;\n\tfilename: string;\n\tblob: ArrayBufferLike;\n\n\treused: false;\n\n\tpatched: boolean;\n}\n\nfunction isFetchedTree(fetchedData: IFetchedData): fetchedData is IFetchedTree {\n\treturn \"patched\" in fetchedData;\n}\n\nconst blobCache = new Map<string, Promise<ArrayBufferLike>>();\nlet blobCachePrevious = new Map<string, Promise<ArrayBufferLike>>();\nlet blobCacheCurrent = new Map<string, Promise<ArrayBufferLike>>();\n\nfunction fetchBlobs(\n\tprefix: string,\n\ttree: ISnapshotTree,\n\tstorage: IDocumentStorageService,\n\tblobIdMap: Map<string, number>,\n) {\n\tconst result: IFetchedBlob[] = [];\n\tfor (const item of Object.keys(tree.blobs)) {\n\t\tconst treePath = `${prefix}${item}`;\n\t\tconst blobId = tree.blobs[item];\n\t\tif (blobId !== null) {\n\t\t\tlet reused = true;\n\t\t\tlet blob = blobCachePrevious.get(blobId);\n\t\t\tif (!blob) {\n\t\t\t\treused = false;\n\t\t\t\tblob = blobCache.get(blobId);\n\t\t\t\tif (blob === undefined) {\n\t\t\t\t\tblob = storage.readBlob(blobId);\n\t\t\t\t\tblobCache.set(blobId, blob);\n\t\t\t\t}\n\t\t\t}\n\t\t\tblobCacheCurrent.set(blobId, blob);\n\n\t\t\t// Use the blobIdMap to assign a number for each unique blob\n\t\t\t// and use it as a prefix for files to avoid case-insensitive fs\n\t\t\tlet index = blobIdMap.get(blobId);\n\t\t\tif (index === undefined) {\n\t\t\t\tindex = blobIdMap.size;\n\t\t\t\tblobIdMap.set(blobId, index);\n\t\t\t}\n\t\t\tconst filename = `${index}-${blobId}`;\n\t\t\tresult.push({ treePath, blobId, blob, reused, filename });\n\n\t\t\t// patch the tree so that we can write it out to reference the file\n\t\t\ttree.blobs[item] = filename;\n\t\t}\n\t}\n\treturn result;\n}\n\nfunction createTreeBlob(tree: ISnapshotTree, prefix: string, patched: boolean): IFetchedTree {\n\tconst id = tree.id ?? \"original\";\n\tconst blob = stringToBuffer(JSON.stringify(tree), \"utf8\");\n\tconst filename = patched ? \"tree\" : `tree-${id}`;\n\tconst treePath = `${prefix}${filename}`;\n\treturn { treePath, blobId: \"original tree $id\", filename, blob, patched, reused: false };\n}\n\nasync function fetchBlobsFromSnapshotTree(\n\tstorage: IDocumentStorageService,\n\ttree: ISnapshotTree,\n\tprefix: string = \"/\",\n\tparentBlobIdMap?: Map<string, number>,\n): Promise<IFetchedData[]> {\n\tconst isTopLevel = !parentBlobIdMap;\n\tif (isTopLevel && dumpSnapshotTrees) {\n\t\tconsole.log(tree);\n\t}\n\n\tif (prefix === \"/\") {\n\t\tblobCachePrevious = blobCacheCurrent;\n\t\tblobCacheCurrent = new Map<string, Promise<ArrayBufferLike>>();\n\t}\n\n\t// Create the tree info before fetching blobs (which will modify it)\n\tlet topLevelBlob: IFetchedTree | undefined;\n\tif (isTopLevel) {\n\t\ttopLevelBlob = createTreeBlob(tree, prefix, false);\n\t}\n\n\tconst blobIdMap = parentBlobIdMap ?? new Map<string, number>();\n\tlet result: IFetchedData[] = fetchBlobs(prefix, tree, storage, blobIdMap);\n\n\tfor (const subtreeId of Object.keys(tree.trees)) {\n\t\tconst subtree = tree.trees[subtreeId];\n\t\tconst dataStoreBlobs = await fetchBlobsFromSnapshotTree(\n\t\t\tstorage,\n\t\t\tsubtree,\n\t\t\t`${prefix}${subtreeId}/`,\n\t\t\tblobIdMap,\n\t\t);\n\t\tresult = result.concat(dataStoreBlobs);\n\t}\n\n\tif (topLevelBlob) {\n\t\tresult.push(topLevelBlob);\n\t\tresult.push(createTreeBlob(tree, prefix, true));\n\t}\n\treturn result;\n}\n\nfunction getDumpFetchedData(fetchedData: IFetchedData[]) {\n\tconst sorted = fetchedData.sort((a, b) => a.treePath.localeCompare(b.treePath));\n\treturn sorted.filter((item) => !isFetchedTree(item) || !item.patched);\n}\n\nasync function dumpSnapshotTreeVerbose(name: string, fetchedData: IFetchedData[]) {\n\tlet size = 0;\n\tconst sorted = getDumpFetchedData(fetchedData);\n\n\tlet nameLength = 10;\n\tfor (const item of sorted) {\n\t\tnameLength = Math.max(nameLength, item.treePath.length);\n\t}\n\n\tconsole.log(\"\");\n\tconsole.log(`${\"Blob Path\".padEnd(nameLength)} | Reused | Bytes`);\n\tconsole.log(\"-\".repeat(nameLength + 26));\n\tfor (const item of sorted) {\n\t\tconst buffer = await item.blob;\n\t\tif (buffer === undefined) {\n\t\t\tcontinue;\n\t\t}\n\t\tconst blob = bufferToString(buffer, \"utf8\");\n\t\tconsole.log(\n\t\t\t`${item.treePath.padEnd(nameLength)} | ${item.reused ? \"X\" : \" \"} | ${formatNumber(\n\t\t\t\tblob.length,\n\t\t\t).padStart(10)}`,\n\t\t);\n\t\tsize += blob.length;\n\t}\n\n\tconsole.log(\"-\".repeat(nameLength + 26));\n\tconsole.log(\n\t\t`${\"Total snapshot size\".padEnd(nameLength)} | | ${formatNumber(size).padStart(10)}`,\n\t);\n}\n\nasync function dumpSnapshotTree(name: string, fetchedData: IFetchedData[]): Promise<ISnapshotInfo> {\n\tlet size = 0;\n\tlet sizeNew = 0;\n\tlet blobCountNew = 0;\n\tconst sorted = getDumpFetchedData(fetchedData);\n\n\tfor (const item of sorted) {\n\t\tconst buffer = await item.blob;\n\t\tif (buffer === undefined) {\n\t\t\tcontinue;\n\t\t}\n\t\tconst blob = bufferToString(buffer, \"utf8\");\n\t\tif (!item.reused) {\n\t\t\tsizeNew += blob.length;\n\t\t\tblobCountNew++;\n\t\t}\n\t\tsize += blob.length;\n\t}\n\n\treturn { blobCountNew, blobCount: sorted.length, size, sizeNew };\n}\n\nasync function saveSnapshot(name: string, fetchedData: IFetchedData[], saveDir: string) {\n\tconst outDir = `${saveDir}/${name}/`;\n\tconst mkdir = util.promisify(fs.mkdir);\n\n\tawait mkdir(`${outDir}/decoded`, { recursive: true });\n\tawait Promise.all(\n\t\tfetchedData.map(async (item) => {\n\t\t\tconst buffer = await item.blob;\n\t\t\tif (buffer === undefined) {\n\t\t\t\tconsole.error(`ERROR: Unable to get data for blob ${item.blobId}`);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (!isFetchedTree(item)) {\n\t\t\t\t// Just write the data as is.\n\t\t\t\tfs.writeFileSync(`${outDir}/${item.filename}`, Buffer.from(buffer));\n\n\t\t\t\t// we assume that the buffer is utf8 here, which currently is true for\n\t\t\t\t// all of our snapshot blobs. It doesn't necessary be true in the future\n\t\t\t\tlet decoded = bufferToString(buffer, \"utf8\");\n\t\t\t\ttry {\n\t\t\t\t\tif (!paramActualFormatting) {\n\t\t\t\t\t\tdecoded = JSON.stringify(JSON.parse(decoded), undefined, 2);\n\t\t\t\t\t}\n\t\t\t\t} catch (e) {}\n\t\t\t\tfs.writeFileSync(`${outDir}/decoded/${item.filename}.json`, decoded);\n\t\t\t} else {\n\t\t\t\t// Write out same data for tree decoded or not, except for formatting\n\t\t\t\tconst treeString = bufferToString(buffer, \"utf8\");\n\t\t\t\tfs.writeFileSync(`${outDir}/${item.filename}.json`, treeString);\n\t\t\t\tfs.writeFileSync(\n\t\t\t\t\t`${outDir}/decoded/${item.filename}.json`,\n\t\t\t\t\tparamActualFormatting\n\t\t\t\t\t\t? treeString\n\t\t\t\t\t\t: JSON.stringify(JSON.parse(treeString), undefined, 2),\n\t\t\t\t);\n\t\t\t}\n\t\t}),\n\t);\n}\n\nasync function fetchBlobsFromVersion(storage: IDocumentStorageService, version: IVersion) {\n\tconst tree = await reportErrors(\n\t\t`getSnapshotTree ${version.id}`,\n\t\tstorage.getSnapshotTree(version),\n\t);\n\tif (!tree) {\n\t\tthrow new Error(\"Failed to load snapshot tree\");\n\t}\n\treturn fetchBlobsFromSnapshotTree(storage, tree);\n}\n\nasync function reportErrors<T>(message: string, res: Promise<T>) {\n\ttry {\n\t\treturn await res;\n\t} catch (error) {\n\t\tconsole.error(`Error calling ${message}`);\n\t\tthrow error;\n\t}\n}\n\nexport async function fluidFetchSnapshot(documentService?: IDocumentService, saveDir?: string) {\n\tif (\n\t\t!dumpSnapshotStats &&\n\t\t!dumpSnapshotTrees &&\n\t\t!dumpSnapshotVersions &&\n\t\tsaveDir === undefined\n\t) {\n\t\treturn;\n\t}\n\n\t// --local mode - do not connect to storage.\n\t// For now, bail out early.\n\t// In future, separate download from analyzes parts and allow offline analyzes\n\tif (!documentService) {\n\t\treturn;\n\t}\n\n\tconsole.log(\"\\n\");\n\n\tconst storage = await documentService.connectToStorage();\n\n\tlet version: IVersion | undefined;\n\tconst versions = await reportErrors(\n\t\t`getVersions ${latestVersionsId}`,\n\t\tstorage.getVersions(latestVersionsId, paramNumSnapshotVersions),\n\t);\n\tif (dumpSnapshotVersions) {\n\t\tconsole.log(\"Snapshot versions\");\n\t\tconsole.log(versions);\n\t}\n\n\tlet blobsToDump: IFetchedData[] | undefined;\n\tif (paramSnapshotVersionIndex !== undefined) {\n\t\tversion = versions[paramSnapshotVersionIndex];\n\t\tif (version === undefined) {\n\t\t\tconsole.log(\n\t\t\t\t`There are only ${versions.length} snapshots, --snapshotVersionIndex is too large`,\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\t\tif (saveDir !== undefined) {\n\t\t\tblobsToDump = await fetchBlobsFromVersion(storage, version);\n\t\t\tconst name = version.id;\n\t\t\tconsole.log(`Saving snapshot ${name}`);\n\t\t\tawait saveSnapshot(name, blobsToDump, saveDir);\n\t\t}\n\t} else {\n\t\tversion = versions[0];\n\t\tif (saveDir !== undefined && versions.length > 0) {\n\t\t\tconsole.log(\n\t\t\t\t\" Name | Date | Size | New Size | Blobs | New Blobs\",\n\t\t\t);\n\t\t\tconsole.log(\"-\".repeat(86));\n\n\t\t\t// Go in reverse order, to correctly calculate blob reuse - from oldest to newest snapshots\n\t\t\tfor (let i = versions.length - 1; i >= 0; i--) {\n\t\t\t\tconst v = versions[i];\n\t\t\t\tconst blobs = await fetchBlobsFromVersion(storage, v);\n\t\t\t\tblobsToDump = blobs;\n\t\t\t\tconst name = `${i}-${v.id}`;\n\t\t\t\tconst res = await dumpSnapshotTree(name, blobs);\n\n\t\t\t\tlet date = \"\";\n\t\t\t\tif (v.date !== undefined) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tdate = new Date(v.date).toLocaleString();\n\t\t\t\t\t} catch (e) {\n\t\t\t\t\t\tdate = v.date.replace(\"T\", \" \");\n\t\t\t\t\t\tconst index = date.lastIndexOf(\".\");\n\t\t\t\t\t\tif (index > 0) {\n\t\t\t\t\t\t\tdate = `${date.substr(0, index)} Z`;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tdate = date.padStart(23);\n\t\t\t\tconst size = formatNumber(res.size).padStart(10);\n\t\t\t\tconst sizeNew = formatNumber(res.sizeNew).padStart(10);\n\t\t\t\tconst blobCount = formatNumber(res.blobCount).padStart(6);\n\t\t\t\tconst blobCountNew = formatNumber(res.blobCountNew).padStart(9);\n\n\t\t\t\tconsole.log(\n\t\t\t\t\t`${name.padEnd(\n\t\t\t\t\t\t15,\n\t\t\t\t\t)} | ${date} | ${size} | ${sizeNew} | ${blobCount} | ${blobCountNew}`,\n\t\t\t\t);\n\n\t\t\t\tawait saveSnapshot(name, blobs, saveDir);\n\t\t\t}\n\t\t}\n\t}\n\n\tif (dumpSnapshotStats || dumpSnapshotTrees) {\n\t\tif (version === undefined) {\n\t\t\tconsole.log(\"No snapshot tree\");\n\t\t} else {\n\t\t\tif (blobsToDump === undefined) {\n\t\t\t\tblobsToDump = await fetchBlobsFromVersion(storage, version);\n\t\t\t}\n\t\t\tconsole.log(`\\n\\nSnapshot version ${version.id}`);\n\t\t\tawait dumpSnapshotTreeVerbose(version.id, blobsToDump);\n\t\t}\n\t}\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fluid-tools/fetch-tool",
3
- "version": "2.0.0-internal.5.2.0",
3
+ "version": "2.0.0-internal.5.3.0",
4
4
  "description": "Console tool to fetch Fluid data from relay service",
5
5
  "homepage": "https://fluidframework.com",
6
6
  "repository": {
@@ -15,26 +15,27 @@
15
15
  "fluid-fetch": "bin/fluid-fetch"
16
16
  },
17
17
  "dependencies": {
18
- "@fluid-tools/fluidapp-odsp-urlresolver": ">=2.0.0-internal.5.2.0 <2.0.0-internal.5.3.0",
18
+ "@fluid-tools/fluidapp-odsp-urlresolver": ">=2.0.0-internal.5.3.0 <2.0.0-internal.5.4.0",
19
19
  "@fluidframework/common-utils": "^1.1.1",
20
- "@fluidframework/container-runtime": ">=2.0.0-internal.5.2.0 <2.0.0-internal.5.3.0",
21
- "@fluidframework/core-interfaces": ">=2.0.0-internal.5.2.0 <2.0.0-internal.5.3.0",
22
- "@fluidframework/datastore": ">=2.0.0-internal.5.2.0 <2.0.0-internal.5.3.0",
23
- "@fluidframework/driver-definitions": ">=2.0.0-internal.5.2.0 <2.0.0-internal.5.3.0",
24
- "@fluidframework/odsp-doclib-utils": ">=2.0.0-internal.5.2.0 <2.0.0-internal.5.3.0",
25
- "@fluidframework/odsp-driver": ">=2.0.0-internal.5.2.0 <2.0.0-internal.5.3.0",
26
- "@fluidframework/odsp-driver-definitions": ">=2.0.0-internal.5.2.0 <2.0.0-internal.5.3.0",
27
- "@fluidframework/odsp-urlresolver": ">=2.0.0-internal.5.2.0 <2.0.0-internal.5.3.0",
20
+ "@fluidframework/container-runtime": ">=2.0.0-internal.5.3.0 <2.0.0-internal.5.4.0",
21
+ "@fluidframework/core-interfaces": ">=2.0.0-internal.5.3.0 <2.0.0-internal.5.4.0",
22
+ "@fluidframework/datastore": ">=2.0.0-internal.5.3.0 <2.0.0-internal.5.4.0",
23
+ "@fluidframework/driver-definitions": ">=2.0.0-internal.5.3.0 <2.0.0-internal.5.4.0",
24
+ "@fluidframework/odsp-doclib-utils": ">=2.0.0-internal.5.3.0 <2.0.0-internal.5.4.0",
25
+ "@fluidframework/odsp-driver": ">=2.0.0-internal.5.3.0 <2.0.0-internal.5.4.0",
26
+ "@fluidframework/odsp-driver-definitions": ">=2.0.0-internal.5.3.0 <2.0.0-internal.5.4.0",
27
+ "@fluidframework/odsp-urlresolver": ">=2.0.0-internal.5.3.0 <2.0.0-internal.5.4.0",
28
28
  "@fluidframework/protocol-definitions": "^1.1.0",
29
- "@fluidframework/routerlicious-driver": ">=2.0.0-internal.5.2.0 <2.0.0-internal.5.3.0",
30
- "@fluidframework/routerlicious-urlresolver": ">=2.0.0-internal.5.2.0 <2.0.0-internal.5.3.0",
31
- "@fluidframework/runtime-definitions": ">=2.0.0-internal.5.2.0 <2.0.0-internal.5.3.0",
32
- "@fluidframework/tool-utils": ">=2.0.0-internal.5.2.0 <2.0.0-internal.5.3.0"
29
+ "@fluidframework/routerlicious-driver": ">=2.0.0-internal.5.3.0 <2.0.0-internal.5.4.0",
30
+ "@fluidframework/routerlicious-urlresolver": ">=2.0.0-internal.5.3.0 <2.0.0-internal.5.4.0",
31
+ "@fluidframework/runtime-definitions": ">=2.0.0-internal.5.3.0 <2.0.0-internal.5.4.0",
32
+ "@fluidframework/tool-utils": ">=2.0.0-internal.5.3.0 <2.0.0-internal.5.4.0"
33
33
  },
34
34
  "devDependencies": {
35
- "@fluid-tools/build-cli": "^0.20.0",
36
- "@fluid-tools/fetch-tool-previous": "npm:@fluid-tools/fetch-tool@2.0.0-internal.5.0.0",
35
+ "@fluid-tools/build-cli": "^0.21.0",
36
+ "@fluid-tools/fetch-tool-previous": "npm:@fluid-tools/fetch-tool@2.0.0-internal.5.2.0",
37
37
  "@fluidframework/build-common": "^1.2.0",
38
+ "@fluidframework/build-tools": "^0.21.0",
38
39
  "@fluidframework/eslint-config-fluid": "^2.0.0",
39
40
  "@types/node": "^14.18.38",
40
41
  "concurrently": "^7.6.0",
@@ -6,6 +6,8 @@
6
6
  import { assert, unreachableCase } from "@fluidframework/common-utils";
7
7
  import {
8
8
  ISequencedDocumentMessage,
9
+ ISummaryAck,
10
+ ISummaryNack,
9
11
  ISummaryProposal,
10
12
  MessageType,
11
13
  TreeEntry,
@@ -425,7 +427,8 @@ class SummaryAnalyzer implements IMessageAnalyzer {
425
427
  this.lastSummaryOp = message.sequenceNumber;
426
428
  }
427
429
  if (message.type === MessageType.SummaryAck || message.type === MessageType.SummaryNack) {
428
- const contents: ISummaryProposal = message.contents.summaryProposal;
430
+ const contents: ISummaryProposal = (message.contents as ISummaryAck | ISummaryNack)
431
+ .summaryProposal;
429
432
  const distance = message.sequenceNumber - contents.summarySequenceNumber;
430
433
  if (distance > this.maxResponse) {
431
434
  this.maxResponse = distance;
@@ -550,13 +553,17 @@ function processOp(
550
553
  }
551
554
  case ContainerMessageType.ChunkedOp: {
552
555
  const chunk = runtimeMessage.contents as IChunkedOp;
553
- if (!chunkMap.has(runtimeMessage.clientId)) {
554
- chunkMap.set(runtimeMessage.clientId, {
556
+ // TODO: Verify whether this should be able to handle server-generated ops (with null clientId)
557
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
558
+ if (!chunkMap.has(runtimeMessage.clientId as string)) {
559
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
560
+ chunkMap.set(runtimeMessage.clientId as string, {
555
561
  chunks: new Array<string>(chunk.totalChunks),
556
562
  totalSize: 0,
557
563
  });
558
564
  }
559
- const value = chunkMap.get(runtimeMessage.clientId);
565
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
566
+ const value = chunkMap.get(runtimeMessage.clientId as string);
560
567
  assert(value !== undefined, 0x2b8 /* "Chunk should be set in map" */);
561
568
  const chunks = value.chunks;
562
569
  const chunkIndex = chunk.chunkId - 1;
@@ -778,7 +785,9 @@ function processQuorumMessages(
778
785
  }
779
786
  } else {
780
787
  // message.clientId can be null
781
- session = sessionsInProgress.get(message.clientId);
788
+ // TODO: Verify whether this should be able to handle server-generated ops (with null clientId)
789
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
790
+ session = sessionsInProgress.get(message.clientId as string);
782
791
  if (session === undefined) {
783
792
  session = sessionsInProgress.get(noClientName);
784
793
  assert(!!session, 0x1b8 /* "Bad session state for processing quorum messages" */);
@@ -254,7 +254,7 @@ async function fetchBlobsFromVersion(storage: IDocumentStorageService, version:
254
254
  storage.getSnapshotTree(version),
255
255
  );
256
256
  if (!tree) {
257
- return Promise.reject(new Error("Failed to load snapshot tree"));
257
+ throw new Error("Failed to load snapshot tree");
258
258
  }
259
259
  return fetchBlobsFromSnapshotTree(storage, tree);
260
260
  }