@fluidframework/debugger 2.103.0 → 2.110.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
  # @fluidframework/debugger
2
2
 
3
+ ## 2.110.0
4
+
5
+ Dependency updates only.
6
+
3
7
  ## 2.103.0
4
8
 
5
9
  Dependency updates only.
@@ -237,7 +237,7 @@ class DebugReplayController extends internal_3.ReplayController {
237
237
  this.stepsDeferred = new internal_1.Deferred();
238
238
  this.ui.updateNextOpText(_fetchedOps);
239
239
  this.stepsToPlay = await this.stepsDeferred.promise;
240
- this.stepsDeferred = undefined;
240
+ delete this.stepsDeferred;
241
241
  this.ui.disableNextOpButton(true);
242
242
  }
243
243
  let playOps;
@@ -1 +1 @@
1
- {"version":3,"file":"fluidDebuggerController.js","sourceRoot":"","sources":["../src/fluidDebuggerController.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, Deferred } from \"@fluidframework/core-utils/internal\";\nimport type {\n\tIDocumentDeltaStorageService,\n\tIDocumentService,\n\tIDocumentStorageService,\n\tIDocumentAttributes,\n\tISnapshotTree,\n\tIVersion,\n\tISequencedDocumentMessage,\n} from \"@fluidframework/driver-definitions/internal\";\nimport { readAndParse } from \"@fluidframework/driver-utils/internal\";\nimport type {\n\tIFileSnapshot,\n\tReadDocumentStorageServiceBase,\n} from \"@fluidframework/replay-driver/internal\";\nimport {\n\tFileSnapshotReader,\n\tReplayController,\n\tSnapshotStorage,\n} from \"@fluidframework/replay-driver/internal\";\n\nimport type { IDebuggerController, IDebuggerUI } from \"./fluidDebuggerUi.js\";\nimport { Sanitizer } from \"./sanitizer.js\";\n\n/**\n * @internal\n */\n// eslint-disable-next-line @rushstack/no-new-null\nexport type debuggerUIFactory = (controller: IDebuggerController) => IDebuggerUI | null;\n\n/**\n * Replay controller that uses pop-up window to control op playback\n * @internal\n */\nexport class DebugReplayController extends ReplayController implements IDebuggerController {\n\t// eslint-disable-next-line @rushstack/no-new-null\n\tpublic static create(createUi: debuggerUIFactory): DebugReplayController | null {\n\t\tif (typeof localStorage === \"object\" && localStorage?.FluidDebugger) {\n\t\t\tconst controller = new DebugReplayController();\n\t\t\tconst ui = createUi(controller);\n\t\t\tif (ui) {\n\t\t\t\treturn controller;\n\t\t\t}\n\t\t}\n\t\treturn null;\n\t}\n\n\tprotected static readonly WindowClosedSeq = -1; // Seq# to indicate that user closed window\n\n\tprotected static async seqFromTree(\n\t\tdocumentStorageService: IDocumentStorageService,\n\t\ttree: ISnapshotTree | null,\n\t): Promise<number> {\n\t\tif (!tree) {\n\t\t\treturn 0;\n\t\t}\n\n\t\t// TODO Why are we non null asserting here\n\t\tconst attributesHash = tree.trees[\".protocol\"]!.blobs.attributes!;\n\t\tconst attrib = await readAndParse<IDocumentAttributes>(\n\t\t\tdocumentStorageService,\n\t\t\tattributesHash,\n\t\t);\n\t\treturn attrib.sequenceNumber;\n\t}\n\n\tprotected ui: IDebuggerUI = null as any as IDebuggerUI; // Not to check on every line that it's not null\n\tprotected stepsDeferred?: Deferred<number>;\n\tprotected startSeqDeferred = new Deferred<number>();\n\n\t// True will cause us ping server indefinitely waiting for new ops\n\tprotected retryFetchOpsOnEndOfFile = false;\n\n\tprotected documentService?: IDocumentService;\n\tprotected documentStorageService?: IDocumentStorageService;\n\tprotected versions: IVersion[] = [];\n\tprotected stepsToPlay: number = 0;\n\tprotected lastOpReached = false;\n\tprotected versionCount = 0;\n\n\tprotected storage?: ReadDocumentStorageServiceBase;\n\n\t// Member to prevent repeated initialization in initStorage(...), which also\n\t// returns if this controller should be used or function as a passthrough\n\tprivate shouldUseController: boolean | undefined;\n\n\tpublic connectToUi(ui: IDebuggerUI): void {\n\t\tthis.ui = ui;\n\t}\n\n\tpublic onClose(): void {\n\t\tthis.startSeqDeferred.resolve(DebugReplayController.WindowClosedSeq);\n\t}\n\n\t// eslint-disable-next-line @typescript-eslint/no-misused-promises\n\tpublic async onVersionSelection(version: IVersion): Promise<void> {\n\t\tif (!this.documentStorageService) {\n\t\t\tthrow new Error(\"onVersionSelection: no storage\");\n\t\t}\n\n\t\tconst tree = await this.documentStorageService.getSnapshotTree(version);\n\t\tconst seq = await DebugReplayController.seqFromTree(this.documentStorageService, tree);\n\t\tthis.resolveStorage(seq, new SnapshotStorage(this.documentStorageService, tree), version);\n\t}\n\n\tpublic onOpButtonClick(steps: number): void {\n\t\tif (this.stepsDeferred && !Number.isNaN(steps) && steps > 0) {\n\t\t\tthis.stepsDeferred.resolve(steps);\n\t\t}\n\t}\n\n\tpublic onSnapshotFileSelection(file: File): void {\n\t\tif (!/^snapshot.*\\.json/.test(file.name)) {\n\t\t\talert(`Incorrect file name: ${file.name}`);\n\t\t\treturn;\n\t\t}\n\t\tif (/.*_expanded.*/.test(file.name)) {\n\t\t\talert(`Incorrect file name - please use non-extended files: ${file.name}`);\n\t\t\treturn;\n\t\t}\n\n\t\tconst reader = new FileReader();\n\t\treader.addEventListener(\"load\", () => {\n\t\t\tif (this.documentStorageService) {\n\t\t\t\tconst text = reader.result as string;\n\t\t\t\ttry {\n\t\t\t\t\tconst json: IFileSnapshot = JSON.parse(text) as IFileSnapshot;\n\t\t\t\t\t/*\n Const docStorage = this.documentStorageService;\n const storage = {\n read: (blobId: string) => this.read(docStorage, blobId),\n };\n const seq = await DebugReplayController.seqFromTree(\n storage as IDocumentStorageService,\n tree);\n this.startSeqDeferred.resolve(seq);\n */\n\t\t\t\t\t// No ability to load ops, so just say - pick up from infinite op.\n\t\t\t\t\tthis.retryFetchOpsOnEndOfFile = false;\n\t\t\t\t\tthis.lastOpReached = true;\n\t\t\t\t\tthis.resolveStorage(\n\t\t\t\t\t\tNumber.MAX_SAFE_INTEGER,\n\t\t\t\t\t\tnew FileSnapshotReader(json),\n\t\t\t\t\t\tfile.name,\n\t\t\t\t\t);\n\t\t\t\t} catch (error) {\n\t\t\t\t\talert(`Error parsing file: ${error}`);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t\treader.readAsText(file, \"utf-8\");\n\t}\n\n\tpublic async onDownloadOpsButtonClick(anonymize: boolean): Promise<string> {\n\t\tif (this.documentService === undefined) {\n\t\t\tthrow new Error(\"DocumentService required\");\n\t\t}\n\n\t\tconst documentDeltaStorageService = await this.documentService.connectToDeltaStorage();\n\t\tlet messages = await this.fetchOpsFromDeltaStorage(documentDeltaStorageService);\n\n\t\tif (anonymize) {\n\t\t\tconst sanitizer = new Sanitizer(messages, false /* fullScrub */, false /* noBail */);\n\t\t\tmessages = sanitizer.sanitize();\n\t\t}\n\n\t\treturn JSON.stringify(messages, undefined, 2);\n\t}\n\n\tprivate async fetchOpsFromDeltaStorage(\n\t\tdocumentDeltaStorageService,\n\t): Promise<ISequencedDocumentMessage[]> {\n\t\tconst deltaGenerator = generateSequencedMessagesFromDeltaStorage(\n\t\t\tdocumentDeltaStorageService,\n\t\t);\n\t\tlet messages: ISequencedDocumentMessage[] = [];\n\t\tfor await (const message of deltaGenerator) {\n\t\t\tmessages = messages.concat(message);\n\t\t}\n\t\treturn messages;\n\t}\n\n\tpublic fetchTo(currentOp: number): number | undefined {\n\t\treturn undefined;\n\t}\n\n\t// Returns true if version / file / ops selections is made.\n\tpublic isSelectionMade(): boolean {\n\t\treturn this.storage !== undefined;\n\t}\n\n\tpublic async downloadVersionInfo(\n\t\tdocumentStorageService: IDocumentStorageService,\n\t\tprevRequest: Promise<void>,\n\t\tindex: number,\n\t\tversion: IVersion,\n\t): Promise<void> {\n\t\tif (this.isSelectionMade()) {\n\t\t\treturn;\n\t\t}\n\n\t\tawait prevRequest;\n\n\t\tconst treeV = await documentStorageService.getSnapshotTree(version);\n\t\tconst seqV = await DebugReplayController.seqFromTree(documentStorageService, treeV);\n\n\t\tif (!this.isSelectionMade()) {\n\t\t\tthis.versionCount--;\n\t\t\tthis.ui.updateVersionText(this.versionCount);\n\t\t\tthis.ui.updateVersion(index, version, seqV);\n\t\t}\n\t}\n\n\tpublic async initStorage(documentService: IDocumentService): Promise<boolean> {\n\t\tif (this.shouldUseController !== undefined) {\n\t\t\treturn this.shouldUseController;\n\t\t}\n\n\t\tassert(!!documentService, 0x080 /* \"Invalid document service!\" */);\n\t\tassert(!this.documentService, 0x081 /* \"Document service already set!\" */);\n\t\tassert(!this.documentStorageService, 0x082 /* \"Document storage service already set!\" */);\n\t\tthis.documentService = documentService;\n\t\tthis.documentStorageService = await documentService.connectToStorage();\n\n\t\t// User can chose \"file\" at any moment in time!\n\t\tif (!this.isSelectionMade()) {\n\t\t\tthis.versions = await this.documentStorageService.getVersions(\"\", 50);\n\t\t\tif (!this.isSelectionMade()) {\n\t\t\t\tthis.ui.addVersions(this.versions);\n\t\t\t\tthis.ui.updateVersionText(this.versionCount);\n\t\t\t}\n\t\t}\n\n\t\tthis.versionCount = this.versions.length;\n\n\t\t// Download all versions - do 10 downloads in parallel to avoid being throttled\n\t\tconst buckets = 10;\n\t\tconst work: Promise<void>[] = [];\n\t\tfor (let i = 0; i < buckets; i++) {\n\t\t\tlet prevRequest = Promise.resolve();\n\t\t\tfor (let index = i; index < this.versions.length; index += buckets) {\n\t\t\t\t// Non null asserting here because we are iterating though versions\n\t\t\t\tconst version = this.versions[index]!;\n\t\t\t\tprevRequest = this.downloadVersionInfo(\n\t\t\t\t\tthis.documentStorageService,\n\t\t\t\t\tprevRequest,\n\t\t\t\t\tindex,\n\t\t\t\t\tversion,\n\t\t\t\t);\n\t\t\t}\n\t\t\twork.push(prevRequest);\n\t\t}\n\n\t\t// Don't wait for stuff to populate.\n\t\t// eslint-disable-next-line @typescript-eslint/no-floating-promises\n\t\tPromise.all(work).then(() => {\n\t\t\tthis.ui.updateVersionText(0);\n\t\t});\n\n\t\t// This hangs until the user makes a selection or closes the window.\n\t\tthis.shouldUseController =\n\t\t\t(await this.startSeqDeferred.promise) !== DebugReplayController.WindowClosedSeq;\n\n\t\tassert(\n\t\t\tthis.isSelectionMade() === this.shouldUseController,\n\t\t\t0x083 /* \"User selection status does not match replay controller use status!\" */,\n\t\t);\n\t\treturn this.shouldUseController;\n\t}\n\n\tpublic async readBlob(blobId: string): Promise<ArrayBufferLike> {\n\t\tif (this.storage !== undefined) {\n\t\t\treturn this.storage.readBlob(blobId);\n\t\t}\n\t\tthrow new Error(\"Reading blob before storage is setup properly\");\n\t}\n\n\t// eslint-disable-next-line @rushstack/no-new-null\n\tpublic async getVersions(versionId: string | null, count: number): Promise<IVersion[]> {\n\t\tif (this.storage !== undefined) {\n\t\t\treturn this.storage.getVersions(versionId, count);\n\t\t}\n\t\tthrow new Error(\"initStorage() was not called!\");\n\t}\n\n\t// eslint-disable-next-line @rushstack/no-new-null\n\tpublic async getSnapshotTree(versionRequested?: IVersion): Promise<ISnapshotTree | null> {\n\t\tif (this.storage !== undefined) {\n\t\t\treturn this.storage.getSnapshotTree(versionRequested);\n\t\t}\n\t\tthrow new Error(\"Reading snapshot tree before storage is setup properly\");\n\t}\n\n\tpublic async getStartingOpSequence(): Promise<number> {\n\t\treturn this.startSeqDeferred.promise;\n\t}\n\n\t/**\n\t * Return true if we are done processing ops\n\t */\n\tpublic isDoneFetch(currentOp: number, lastTimeStamp?: number): boolean {\n\t\tif (lastTimeStamp === undefined) {\n\t\t\tthis.lastOpReached = true;\n\t\t\tif (currentOp === Number.MAX_SAFE_INTEGER) {\n\t\t\t\tthis.ui.updateLastOpText(-1, false);\n\t\t\t} else {\n\t\t\t\tthis.ui.updateLastOpText(currentOp, false);\n\t\t\t}\n\t\t} else {\n\t\t\tthis.ui.updateLastOpText(currentOp, true);\n\t\t}\n\t\treturn this.lastOpReached && !this.retryFetchOpsOnEndOfFile;\n\t}\n\n\tpublic async replay(\n\t\temitter: (op: ISequencedDocumentMessage[]) => void,\n\t\tfetchedOps: ISequencedDocumentMessage[],\n\t): Promise<void> {\n\t\tlet _fetchedOps = fetchedOps;\n\t\twhile (true) {\n\t\t\tif (_fetchedOps.length === 0) {\n\t\t\t\tthis.ui.updateNextOpText([]);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (this.stepsToPlay === 0) {\n\t\t\t\tthis.ui.disableNextOpButton(false);\n\t\t\t\tthis.stepsDeferred = new Deferred<number>();\n\n\t\t\t\tthis.ui.updateNextOpText(_fetchedOps);\n\n\t\t\t\tthis.stepsToPlay = await this.stepsDeferred.promise;\n\n\t\t\t\tthis.stepsDeferred = undefined;\n\t\t\t\tthis.ui.disableNextOpButton(true);\n\t\t\t}\n\n\t\t\tlet playOps: ISequencedDocumentMessage[];\n\t\t\tif (this.stepsToPlay >= _fetchedOps.length) {\n\t\t\t\tplayOps = _fetchedOps;\n\t\t\t\tthis.stepsToPlay -= _fetchedOps.length;\n\t\t\t\t_fetchedOps = [];\n\t\t\t} else {\n\t\t\t\tplayOps = _fetchedOps.splice(0, this.stepsToPlay);\n\t\t\t\tthis.stepsToPlay = 0;\n\t\t\t}\n\t\t\temitter(playOps);\n\t\t}\n\t}\n\n\tprotected resolveStorage(\n\t\tseq: number,\n\t\tstorage: ReadDocumentStorageServiceBase,\n\t\tversion: IVersion | string,\n\t): void {\n\t\tassert(\n\t\t\t!this.isSelectionMade(),\n\t\t\t0x084 /* \"On storage resolve, user selection already made!\" */,\n\t\t);\n\t\tassert(!!storage, 0x085 /* \"On storage resolve, missing storage!\" */);\n\t\tthis.storage = storage;\n\t\tassert(\n\t\t\tthis.isSelectionMade(),\n\t\t\t0x086 /* \"After storage resolve, user selection status still false!\" */,\n\t\t);\n\n\t\tthis.ui.versionSelected(seq, version);\n\t\tthis.startSeqDeferred.resolve(seq);\n\t}\n}\n\nasync function* generateSequencedMessagesFromDeltaStorage(\n\tdeltaStorage: IDocumentDeltaStorageService,\n): AsyncGenerator<ISequencedDocumentMessage[], void, undefined> {\n\tconst stream = deltaStorage.fetchMessages(1, undefined);\n\twhile (true) {\n\t\tconst result = await stream.read();\n\t\tif (result.done) {\n\t\t\treturn;\n\t\t}\n\t\tyield result.value;\n\t}\n}\n"]}
1
+ {"version":3,"file":"fluidDebuggerController.js","sourceRoot":"","sources":["../src/fluidDebuggerController.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, Deferred } from \"@fluidframework/core-utils/internal\";\nimport type {\n\tIDocumentDeltaStorageService,\n\tIDocumentService,\n\tIDocumentStorageService,\n\tIDocumentAttributes,\n\tISnapshotTree,\n\tIVersion,\n\tISequencedDocumentMessage,\n} from \"@fluidframework/driver-definitions/internal\";\nimport { readAndParse } from \"@fluidframework/driver-utils/internal\";\nimport type {\n\tIFileSnapshot,\n\tReadDocumentStorageServiceBase,\n} from \"@fluidframework/replay-driver/internal\";\nimport {\n\tFileSnapshotReader,\n\tReplayController,\n\tSnapshotStorage,\n} from \"@fluidframework/replay-driver/internal\";\n\nimport type { IDebuggerController, IDebuggerUI } from \"./fluidDebuggerUi.js\";\nimport { Sanitizer } from \"./sanitizer.js\";\n\n/**\n * @internal\n */\n// eslint-disable-next-line @rushstack/no-new-null\nexport type debuggerUIFactory = (controller: IDebuggerController) => IDebuggerUI | null;\n\n/**\n * Replay controller that uses pop-up window to control op playback\n * @internal\n */\nexport class DebugReplayController extends ReplayController implements IDebuggerController {\n\t// eslint-disable-next-line @rushstack/no-new-null\n\tpublic static create(createUi: debuggerUIFactory): DebugReplayController | null {\n\t\tif (typeof localStorage === \"object\" && localStorage?.FluidDebugger) {\n\t\t\tconst controller = new DebugReplayController();\n\t\t\tconst ui = createUi(controller);\n\t\t\tif (ui) {\n\t\t\t\treturn controller;\n\t\t\t}\n\t\t}\n\t\treturn null;\n\t}\n\n\tprotected static readonly WindowClosedSeq = -1; // Seq# to indicate that user closed window\n\n\tprotected static async seqFromTree(\n\t\tdocumentStorageService: IDocumentStorageService,\n\t\ttree: ISnapshotTree | null,\n\t): Promise<number> {\n\t\tif (!tree) {\n\t\t\treturn 0;\n\t\t}\n\n\t\t// TODO Why are we non null asserting here\n\t\tconst attributesHash = tree.trees[\".protocol\"]!.blobs.attributes!;\n\t\tconst attrib = await readAndParse<IDocumentAttributes>(\n\t\t\tdocumentStorageService,\n\t\t\tattributesHash,\n\t\t);\n\t\treturn attrib.sequenceNumber;\n\t}\n\n\tprotected ui: IDebuggerUI = null as any as IDebuggerUI; // Not to check on every line that it's not null\n\tprotected stepsDeferred?: Deferred<number>;\n\tprotected startSeqDeferred = new Deferred<number>();\n\n\t// True will cause us ping server indefinitely waiting for new ops\n\tprotected retryFetchOpsOnEndOfFile = false;\n\n\tprotected documentService?: IDocumentService;\n\tprotected documentStorageService?: IDocumentStorageService;\n\tprotected versions: IVersion[] = [];\n\tprotected stepsToPlay: number = 0;\n\tprotected lastOpReached = false;\n\tprotected versionCount = 0;\n\n\tprotected storage?: ReadDocumentStorageServiceBase;\n\n\t// Member to prevent repeated initialization in initStorage(...), which also\n\t// returns if this controller should be used or function as a passthrough\n\tprivate shouldUseController: boolean | undefined;\n\n\tpublic connectToUi(ui: IDebuggerUI): void {\n\t\tthis.ui = ui;\n\t}\n\n\tpublic onClose(): void {\n\t\tthis.startSeqDeferred.resolve(DebugReplayController.WindowClosedSeq);\n\t}\n\n\t// eslint-disable-next-line @typescript-eslint/no-misused-promises\n\tpublic async onVersionSelection(version: IVersion): Promise<void> {\n\t\tif (!this.documentStorageService) {\n\t\t\tthrow new Error(\"onVersionSelection: no storage\");\n\t\t}\n\n\t\tconst tree = await this.documentStorageService.getSnapshotTree(version);\n\t\tconst seq = await DebugReplayController.seqFromTree(this.documentStorageService, tree);\n\t\tthis.resolveStorage(seq, new SnapshotStorage(this.documentStorageService, tree), version);\n\t}\n\n\tpublic onOpButtonClick(steps: number): void {\n\t\tif (this.stepsDeferred && !Number.isNaN(steps) && steps > 0) {\n\t\t\tthis.stepsDeferred.resolve(steps);\n\t\t}\n\t}\n\n\tpublic onSnapshotFileSelection(file: File): void {\n\t\tif (!/^snapshot.*\\.json/.test(file.name)) {\n\t\t\talert(`Incorrect file name: ${file.name}`);\n\t\t\treturn;\n\t\t}\n\t\tif (/.*_expanded.*/.test(file.name)) {\n\t\t\talert(`Incorrect file name - please use non-extended files: ${file.name}`);\n\t\t\treturn;\n\t\t}\n\n\t\tconst reader = new FileReader();\n\t\treader.addEventListener(\"load\", () => {\n\t\t\tif (this.documentStorageService) {\n\t\t\t\tconst text = reader.result as string;\n\t\t\t\ttry {\n\t\t\t\t\tconst json: IFileSnapshot = JSON.parse(text) as IFileSnapshot;\n\t\t\t\t\t/*\n Const docStorage = this.documentStorageService;\n const storage = {\n read: (blobId: string) => this.read(docStorage, blobId),\n };\n const seq = await DebugReplayController.seqFromTree(\n storage as IDocumentStorageService,\n tree);\n this.startSeqDeferred.resolve(seq);\n */\n\t\t\t\t\t// No ability to load ops, so just say - pick up from infinite op.\n\t\t\t\t\tthis.retryFetchOpsOnEndOfFile = false;\n\t\t\t\t\tthis.lastOpReached = true;\n\t\t\t\t\tthis.resolveStorage(\n\t\t\t\t\t\tNumber.MAX_SAFE_INTEGER,\n\t\t\t\t\t\tnew FileSnapshotReader(json),\n\t\t\t\t\t\tfile.name,\n\t\t\t\t\t);\n\t\t\t\t} catch (error) {\n\t\t\t\t\talert(`Error parsing file: ${error}`);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t\treader.readAsText(file, \"utf-8\");\n\t}\n\n\tpublic async onDownloadOpsButtonClick(anonymize: boolean): Promise<string> {\n\t\tif (this.documentService === undefined) {\n\t\t\tthrow new Error(\"DocumentService required\");\n\t\t}\n\n\t\tconst documentDeltaStorageService = await this.documentService.connectToDeltaStorage();\n\t\tlet messages = await this.fetchOpsFromDeltaStorage(documentDeltaStorageService);\n\n\t\tif (anonymize) {\n\t\t\tconst sanitizer = new Sanitizer(messages, false /* fullScrub */, false /* noBail */);\n\t\t\tmessages = sanitizer.sanitize();\n\t\t}\n\n\t\treturn JSON.stringify(messages, undefined, 2);\n\t}\n\n\tprivate async fetchOpsFromDeltaStorage(\n\t\tdocumentDeltaStorageService,\n\t): Promise<ISequencedDocumentMessage[]> {\n\t\tconst deltaGenerator = generateSequencedMessagesFromDeltaStorage(\n\t\t\tdocumentDeltaStorageService,\n\t\t);\n\t\tlet messages: ISequencedDocumentMessage[] = [];\n\t\tfor await (const message of deltaGenerator) {\n\t\t\tmessages = messages.concat(message);\n\t\t}\n\t\treturn messages;\n\t}\n\n\tpublic fetchTo(currentOp: number): number | undefined {\n\t\treturn undefined;\n\t}\n\n\t// Returns true if version / file / ops selections is made.\n\tpublic isSelectionMade(): boolean {\n\t\treturn this.storage !== undefined;\n\t}\n\n\tpublic async downloadVersionInfo(\n\t\tdocumentStorageService: IDocumentStorageService,\n\t\tprevRequest: Promise<void>,\n\t\tindex: number,\n\t\tversion: IVersion,\n\t): Promise<void> {\n\t\tif (this.isSelectionMade()) {\n\t\t\treturn;\n\t\t}\n\n\t\tawait prevRequest;\n\n\t\tconst treeV = await documentStorageService.getSnapshotTree(version);\n\t\tconst seqV = await DebugReplayController.seqFromTree(documentStorageService, treeV);\n\n\t\tif (!this.isSelectionMade()) {\n\t\t\tthis.versionCount--;\n\t\t\tthis.ui.updateVersionText(this.versionCount);\n\t\t\tthis.ui.updateVersion(index, version, seqV);\n\t\t}\n\t}\n\n\tpublic async initStorage(documentService: IDocumentService): Promise<boolean> {\n\t\tif (this.shouldUseController !== undefined) {\n\t\t\treturn this.shouldUseController;\n\t\t}\n\n\t\tassert(!!documentService, 0x080 /* \"Invalid document service!\" */);\n\t\tassert(!this.documentService, 0x081 /* \"Document service already set!\" */);\n\t\tassert(!this.documentStorageService, 0x082 /* \"Document storage service already set!\" */);\n\t\tthis.documentService = documentService;\n\t\tthis.documentStorageService = await documentService.connectToStorage();\n\n\t\t// User can chose \"file\" at any moment in time!\n\t\tif (!this.isSelectionMade()) {\n\t\t\tthis.versions = await this.documentStorageService.getVersions(\"\", 50);\n\t\t\tif (!this.isSelectionMade()) {\n\t\t\t\tthis.ui.addVersions(this.versions);\n\t\t\t\tthis.ui.updateVersionText(this.versionCount);\n\t\t\t}\n\t\t}\n\n\t\tthis.versionCount = this.versions.length;\n\n\t\t// Download all versions - do 10 downloads in parallel to avoid being throttled\n\t\tconst buckets = 10;\n\t\tconst work: Promise<void>[] = [];\n\t\tfor (let i = 0; i < buckets; i++) {\n\t\t\tlet prevRequest = Promise.resolve();\n\t\t\tfor (let index = i; index < this.versions.length; index += buckets) {\n\t\t\t\t// Non null asserting here because we are iterating though versions\n\t\t\t\tconst version = this.versions[index]!;\n\t\t\t\tprevRequest = this.downloadVersionInfo(\n\t\t\t\t\tthis.documentStorageService,\n\t\t\t\t\tprevRequest,\n\t\t\t\t\tindex,\n\t\t\t\t\tversion,\n\t\t\t\t);\n\t\t\t}\n\t\t\twork.push(prevRequest);\n\t\t}\n\n\t\t// Don't wait for stuff to populate.\n\t\t// eslint-disable-next-line @typescript-eslint/no-floating-promises\n\t\tPromise.all(work).then(() => {\n\t\t\tthis.ui.updateVersionText(0);\n\t\t});\n\n\t\t// This hangs until the user makes a selection or closes the window.\n\t\tthis.shouldUseController =\n\t\t\t(await this.startSeqDeferred.promise) !== DebugReplayController.WindowClosedSeq;\n\n\t\tassert(\n\t\t\tthis.isSelectionMade() === this.shouldUseController,\n\t\t\t0x083 /* \"User selection status does not match replay controller use status!\" */,\n\t\t);\n\t\treturn this.shouldUseController;\n\t}\n\n\tpublic async readBlob(blobId: string): Promise<ArrayBufferLike> {\n\t\tif (this.storage !== undefined) {\n\t\t\treturn this.storage.readBlob(blobId);\n\t\t}\n\t\tthrow new Error(\"Reading blob before storage is setup properly\");\n\t}\n\n\t// eslint-disable-next-line @rushstack/no-new-null\n\tpublic async getVersions(versionId: string | null, count: number): Promise<IVersion[]> {\n\t\tif (this.storage !== undefined) {\n\t\t\treturn this.storage.getVersions(versionId, count);\n\t\t}\n\t\tthrow new Error(\"initStorage() was not called!\");\n\t}\n\n\t// eslint-disable-next-line @rushstack/no-new-null\n\tpublic async getSnapshotTree(versionRequested?: IVersion): Promise<ISnapshotTree | null> {\n\t\tif (this.storage !== undefined) {\n\t\t\treturn this.storage.getSnapshotTree(versionRequested);\n\t\t}\n\t\tthrow new Error(\"Reading snapshot tree before storage is setup properly\");\n\t}\n\n\tpublic async getStartingOpSequence(): Promise<number> {\n\t\treturn this.startSeqDeferred.promise;\n\t}\n\n\t/**\n\t * Return true if we are done processing ops\n\t */\n\tpublic isDoneFetch(currentOp: number, lastTimeStamp?: number): boolean {\n\t\tif (lastTimeStamp === undefined) {\n\t\t\tthis.lastOpReached = true;\n\t\t\tif (currentOp === Number.MAX_SAFE_INTEGER) {\n\t\t\t\tthis.ui.updateLastOpText(-1, false);\n\t\t\t} else {\n\t\t\t\tthis.ui.updateLastOpText(currentOp, false);\n\t\t\t}\n\t\t} else {\n\t\t\tthis.ui.updateLastOpText(currentOp, true);\n\t\t}\n\t\treturn this.lastOpReached && !this.retryFetchOpsOnEndOfFile;\n\t}\n\n\tpublic async replay(\n\t\temitter: (op: ISequencedDocumentMessage[]) => void,\n\t\tfetchedOps: ISequencedDocumentMessage[],\n\t): Promise<void> {\n\t\tlet _fetchedOps = fetchedOps;\n\t\twhile (true) {\n\t\t\tif (_fetchedOps.length === 0) {\n\t\t\t\tthis.ui.updateNextOpText([]);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (this.stepsToPlay === 0) {\n\t\t\t\tthis.ui.disableNextOpButton(false);\n\t\t\t\tthis.stepsDeferred = new Deferred<number>();\n\n\t\t\t\tthis.ui.updateNextOpText(_fetchedOps);\n\n\t\t\t\tthis.stepsToPlay = await this.stepsDeferred.promise;\n\n\t\t\t\tdelete this.stepsDeferred;\n\t\t\t\tthis.ui.disableNextOpButton(true);\n\t\t\t}\n\n\t\t\tlet playOps: ISequencedDocumentMessage[];\n\t\t\tif (this.stepsToPlay >= _fetchedOps.length) {\n\t\t\t\tplayOps = _fetchedOps;\n\t\t\t\tthis.stepsToPlay -= _fetchedOps.length;\n\t\t\t\t_fetchedOps = [];\n\t\t\t} else {\n\t\t\t\tplayOps = _fetchedOps.splice(0, this.stepsToPlay);\n\t\t\t\tthis.stepsToPlay = 0;\n\t\t\t}\n\t\t\temitter(playOps);\n\t\t}\n\t}\n\n\tprotected resolveStorage(\n\t\tseq: number,\n\t\tstorage: ReadDocumentStorageServiceBase,\n\t\tversion: IVersion | string,\n\t): void {\n\t\tassert(\n\t\t\t!this.isSelectionMade(),\n\t\t\t0x084 /* \"On storage resolve, user selection already made!\" */,\n\t\t);\n\t\tassert(!!storage, 0x085 /* \"On storage resolve, missing storage!\" */);\n\t\tthis.storage = storage;\n\t\tassert(\n\t\t\tthis.isSelectionMade(),\n\t\t\t0x086 /* \"After storage resolve, user selection status still false!\" */,\n\t\t);\n\n\t\tthis.ui.versionSelected(seq, version);\n\t\tthis.startSeqDeferred.resolve(seq);\n\t}\n}\n\nasync function* generateSequencedMessagesFromDeltaStorage(\n\tdeltaStorage: IDocumentDeltaStorageService,\n): AsyncGenerator<ISequencedDocumentMessage[], void, undefined> {\n\tconst stream = deltaStorage.fetchMessages(1, undefined);\n\twhile (true) {\n\t\tconst result = await stream.read();\n\t\tif (result.done) {\n\t\t\treturn;\n\t\t}\n\t\tyield result.value;\n\t}\n}\n"]}
@@ -141,7 +141,7 @@ class DebuggerUI {
141
141
  ? `Playing ${version} file`
142
142
  : `Playing from ${version.id}, seq# ${seqNumber}`;
143
143
  this.wasVersionSelected = true;
144
- this.selector = undefined;
144
+ delete this.selector;
145
145
  const doc = this.debuggerWindow.document;
146
146
  doc.open();
147
147
  doc.write(debuggerWindowHtml2);
@@ -1 +1 @@
1
- {"version":3,"file":"fluidDebuggerUi.js","sourceRoot":"","sources":["../src/fluidDebuggerUi.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert } from \"@fluidframework/core-utils/internal\";\nimport type {\n\tIVersion,\n\tISequencedDocumentMessage,\n} from \"@fluidframework/driver-definitions/internal\";\n\n/**\n * @internal\n */\nexport interface IDebuggerUI {\n\t/**\n\t * Version information is provided.\n\t * Expect updates (information about seq#, timestamp) through updateVersion() calls\n\t */\n\taddVersions(version: IVersion[]): void;\n\n\t/**\n\t * Call when new version is downloaded from storage\n\t * Expect multiple callbacks.\n\t */\n\tupdateVersion(index: number, version: IVersion, seqNumber: number): void;\n\n\t/**\n\t * Called in response to successful onVersionSelection() or onSnapshotFileSelection() call\n\t * and provides extra information about selection.\n\t * It expected that UI layer would change its mode as result of this call, i.e. switch to\n\t * displaying op playback controls (if this is supported)\n\t * Note: There maybe no call to versionSelected() in response to onSnapshotFileSelection() call\n\t * if file does not exist, has wrong name of wrong format.\n\t * @param version - version, file name, or undefined if playing ops.\n\t */\n\tversionSelected(seqNumber: number, version: IVersion | string): void;\n\n\t/**\n\t * Called by controller in response to new ops being downloaded\n\t * Called with disable = true if there are no (currently) ops to play\n\t */\n\tdisableNextOpButton(disable: boolean): void;\n\n\t/**\n\t * Called by controller when new ops arrive (or we are done playing previous batch)\n\t * Indicates next batch of ops that would be played when UI calls controller's onOpButtonClick()\n\t * Called with ops=[] when there are no ops to play.\n\t */\n\tupdateNextOpText(ops: ISequencedDocumentMessage[]): void;\n\n\t/**\n\t * Called periodically when new versions are downloaded from server\n\t */\n\tupdateVersionText(versionsLeft: number): void;\n\n\t/**\n\t * Called periodically to notify about last known op\n\t * @param lastKnownOp - seq number of last known op. -1 if can't play ops in this mode (load from file)\n\t * @param stillLoading - true if we did not reach yet the end of the stream\n\t */\n\tupdateLastOpText(lastKnownOp: number, stillLoading: boolean): void;\n}\n\n/**\n * @internal\n */\nexport interface IDebuggerController {\n\t/**\n\t * Initialization. UI layers calls into controller to connect the two.\n\t * @param ui - UI layer\n\t */\n\tconnectToUi(ui: IDebuggerUI);\n\n\t/**\n\t * Called by UI layer when debugger window is closed by user\n\t * If called before user makes selection of snapshot/file, original\n\t * document service is returned to loader (instead of debugger service) and normal document load continues.\n\t */\n\tonClose(): void;\n\n\t/**\n\t * UI Layer notifies about selection of version to continue.\n\t * On successful load, versionSelected() is called.\n\t * @param version - Snapshot version to start from.\n\t */\n\tonVersionSelection(version: IVersion): void;\n\n\t/**\n\t * UI Layer notifies about selection of version to continue.\n\t * On successful load, versionSelected() is called.\n\t * @param version - File to load snapshot from\n\t */\n\tonSnapshotFileSelection(file: File): void;\n\n\t/**\n\t * \"next op\" button is clicked in the UI\n\t * @param steps - number of ops to play.\n\t */\n\tonOpButtonClick(steps: number): void;\n\n\t/**\n\t * \"Download ops\" option is clicked in the UI. Returns JSON of the full opStream when available.\n\t * @param anonymize - anonymize the ops json using the sanitization tool\n\t */\n\tonDownloadOpsButtonClick(anonymize: boolean): Promise<string>;\n}\n\nconst debuggerWindowHtml = `<Title>Fluid Debugger</Title>\n<body>\n<h3>Fluid Debugger</h3>\nPlease select snapshot or file to start with<br/>\nClose debugger window to proceed to live document<br/><br/>\n<select style='width:250px' id='selector'>\n</select>\n&nbsp; &nbsp; &nbsp;\n<button id='buttonVers' style='width:60px'>Go</button><br/>\n<input id='file' type='file' value='Load from file'/>\n<br/><br/>\n<h4>Download the current document's ops</h4>\n<input type='checkbox' id='anonymize' value='Anonymize'>\n<label for='anonymize'>Anonymize</label>\n<button type='button' id='downloadOps'>Download ops</button>\n<br/><br/><div id='versionText'></div>\n</body>`;\n\nconst debuggerWindowHtml2 = `<Title>Fluid Debugger</Title>\n<body>\n<h3>Fluid Debugger</h3>\n<div id='versionText'></div>\n<div id='lastOp'></div>\n<br/>\nStep to move: <input type='number' id='steps' value='1' min='1' style='width:50px'/>\n&nbsp; &nbsp; &nbsp;<button id='buttonOps' style='width:60px'>Go</button>\n<br/><br/>\n<div id='text1'></div><div id='text2'></div><div id='text3'></div>\n<br/>\n<h4>Download the current document's ops</h4>\n<input type='checkbox' id='anonymize' value='Anonymize'>\n<label for='anonymize'>Anonymize</label>\n<button type='button' id='downloadOps'>Download ops</button>\n</body>`;\n\n/**\n * @internal\n */\nexport class DebuggerUI {\n\tpublic static create(controller: IDebuggerController): DebuggerUI | null {\n\t\tif (\n\t\t\ttypeof window !== \"object\" ||\n\t\t\twindow === null ||\n\t\t\ttypeof window.document !== \"object\" ||\n\t\t\twindow.document === null\n\t\t) {\n\t\t\tconsole.log(\"Can't create debugger window - not running in browser!\");\n\t\t\treturn null;\n\t\t}\n\n\t\tconst debuggerWindow = window.open(\n\t\t\t\"\",\n\t\t\t\"\",\n\t\t\t\"width=400,height=400,resizable=yes,location=no,menubar=no,titlebar=no,status=no,toolbar=no\",\n\t\t);\n\t\tif (!debuggerWindow) {\n\t\t\tconsole.error(\n\t\t\t\t\"Can't create debugger window - please enable pop-up windows in your browser!\",\n\t\t\t);\n\t\t\treturn null;\n\t\t}\n\n\t\treturn new DebuggerUI(controller, debuggerWindow);\n\t}\n\n\tprivate static formatDate(date: number): string {\n\t\t// Alternative - without timezone\n\t\t// new Date().toLocaleString('default', { timeZone: 'UTC'}));\n\t\t// new Date().toLocaleString('default', { year: 'numeric', month: 'short',\n\t\t// day: 'numeric', hour: '2-digit', minute: 'numeric', second: 'numeric' }));\n\t\treturn new Date(date).toUTCString();\n\t}\n\n\tprotected selector?: HTMLSelectElement;\n\tprotected versionText: HTMLDivElement;\n\n\tprotected buttonOps?: HTMLButtonElement;\n\tprotected text1?: HTMLDivElement;\n\tprotected text2?: HTMLDivElement;\n\tprotected text3?: HTMLDivElement;\n\tprotected lastOpText?: HTMLDivElement;\n\tprotected wasVersionSelected = false;\n\tprotected versions: IVersion[] = [];\n\n\tprotected documentClosed = false;\n\n\tprotected constructor(\n\t\tprivate readonly controller: IDebuggerController,\n\t\tprivate readonly debuggerWindow: Window,\n\t) {\n\t\tconst doc = this.debuggerWindow.document;\n\t\tdoc.write(debuggerWindowHtml);\n\n\t\twindow.addEventListener(\n\t\t\t\"beforeunload\",\n\t\t\t(e) => {\n\t\t\t\tthis.documentClosed = true;\n\t\t\t\tthis.debuggerWindow.close();\n\t\t\t},\n\t\t\tfalse,\n\t\t);\n\n\t\tthis.debuggerWindow.addEventListener(\n\t\t\t\"beforeunload\",\n\t\t\t(e) => {\n\t\t\t\tif (!this.documentClosed) {\n\t\t\t\t\tthis.controller.onClose();\n\t\t\t\t}\n\t\t\t},\n\t\t\tfalse,\n\t\t);\n\n\t\tthis.selector = doc.querySelector(\"#selector\") as HTMLSelectElement;\n\n\t\tconst buttonVers = doc.querySelector(\"#buttonVers\") as HTMLDivElement;\n\t\tbuttonVers.addEventListener(\"click\", () => {\n\t\t\tconst index = this.selector!.selectedIndex;\n\t\t\t// TODO Why are we non null asserting here\n\t\t\tcontroller.onVersionSelection(this.versions[index]!);\n\t\t});\n\n\t\tconst fileSnapshot = doc.querySelector(\"#file\") as HTMLInputElement;\n\t\tfileSnapshot.addEventListener(\n\t\t\t\"change\",\n\t\t\t() => {\n\t\t\t\tconst files = fileSnapshot.files;\n\t\t\t\tif (files) {\n\t\t\t\t\t// TODO Why are we non null asserting here\n\t\t\t\t\tcontroller.onSnapshotFileSelection(files[0]!);\n\t\t\t\t}\n\t\t\t},\n\t\t\tfalse,\n\t\t);\n\n\t\tconst opDownloadButton = doc.querySelector(\"#downloadOps\") as HTMLElement;\n\t\tconst anonymizeCheckbox = doc.querySelector(\"#anonymize\") as HTMLInputElement;\n\t\tthis.attachDownloadOpsListener(opDownloadButton, anonymizeCheckbox);\n\n\t\tthis.versionText = doc.querySelector(\"#versionText\") as HTMLDivElement;\n\t\tthis.versionText.textContent = \"Fetching snapshots, please wait...\";\n\n\t\tcontroller.connectToUi(this);\n\t}\n\n\tprivate attachDownloadOpsListener(element: HTMLElement, anonymize: HTMLInputElement): void {\n\t\telement.addEventListener(\"click\", () => {\n\t\t\tthis.controller\n\t\t\t\t.onDownloadOpsButtonClick(anonymize.checked)\n\t\t\t\t.then((opJson) => {\n\t\t\t\t\tthis.download(\"opStream.json\", opJson);\n\t\t\t\t})\n\t\t\t\t.catch((error) => {\n\t\t\t\t\tconsole.log(`Error downloading ops: ${error}`);\n\t\t\t\t});\n\t\t});\n\t}\n\n\tpublic addVersions(versions: IVersion[]): void {\n\t\tif (this.selector) {\n\t\t\tthis.versions = versions;\n\t\t\tfor (const version of versions) {\n\t\t\t\tconst option = document.createElement(\"option\");\n\t\t\t\toption.text =\n\t\t\t\t\tversion.date === undefined\n\t\t\t\t\t\t? `id = ${version.id}`\n\t\t\t\t\t\t: `id = ${version.id}, time = ${version.date}`;\n\t\t\t\tthis.selector.add(option);\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic updateVersion(index: number, version: IVersion, seqNumber: number): void {\n\t\tif (this.selector) {\n\t\t\tconst option = this.selector[index] as HTMLOptionElement;\n\t\t\toption.text = `${option.text}, seq = ${seqNumber}`;\n\t\t\tthis.selector[index] = option;\n\t\t}\n\t}\n\n\tpublic versionSelected(seqNumber: number, version: IVersion | string): void {\n\t\tconst text =\n\t\t\ttypeof version === \"string\"\n\t\t\t\t? `Playing ${version} file`\n\t\t\t\t: `Playing from ${version.id}, seq# ${seqNumber}`;\n\n\t\tthis.wasVersionSelected = true;\n\t\tthis.selector = undefined;\n\n\t\tconst doc = this.debuggerWindow.document;\n\t\tdoc.open();\n\t\tdoc.write(debuggerWindowHtml2);\n\t\tdoc.close();\n\n\t\tthis.lastOpText = doc.querySelector(\"#lastOp\") as HTMLDivElement;\n\t\tthis.text1 = doc.querySelector(\"#text1\") as HTMLDivElement;\n\t\tthis.text2 = doc.querySelector(\"#text2\") as HTMLDivElement;\n\t\tthis.text3 = doc.querySelector(\"#text3\") as HTMLDivElement;\n\n\t\tconst steps = doc.querySelector(\"#steps\") as HTMLInputElement;\n\t\tthis.buttonOps = doc.querySelector(\"#buttonOps\") as HTMLButtonElement;\n\t\tthis.buttonOps.disabled = true;\n\t\tthis.buttonOps.addEventListener(\"click\", () => {\n\t\t\tthis.controller.onOpButtonClick(Number(steps.value));\n\t\t});\n\n\t\tthis.versionText = doc.querySelector(\"#versionText\") as HTMLDivElement;\n\t\tthis.versionText.textContent = text;\n\n\t\tconst opDownloadButton = doc.querySelector(\"#downloadOps\") as HTMLElement;\n\t\tconst anonymizeCheckbox = doc.querySelector(\"#anonymize\") as HTMLInputElement;\n\t\tthis.attachDownloadOpsListener(opDownloadButton, anonymizeCheckbox);\n\t}\n\n\tpublic disableNextOpButton(disable: boolean): void {\n\t\tassert(!!this.buttonOps, 0x088 /* \"Missing button ops button!\" */);\n\t\tthis.buttonOps.disabled = disable;\n\t}\n\n\tpublic updateNextOpText(ops: ISequencedDocumentMessage[]): void {\n\t\tif (ops.length === 0) {\n\t\t\tthis.text1!.textContent = \"\";\n\t\t\tthis.text2!.textContent = \"\";\n\t\t\tthis.text3!.textContent = \"\";\n\t\t} else {\n\t\t\t// Non null asserting here because of the length check above\n\t\t\tconst op = ops[0]!;\n\t\t\tconst seq = op.sequenceNumber;\n\t\t\tconst date = DebuggerUI.formatDate(op.timestamp);\n\t\t\tthis.text1!.textContent = `Next op seq#: ${seq}`;\n\t\t\tthis.text2!.textContent = `Type: ${op.type}`;\n\t\t\tthis.text3!.textContent = `${date}`;\n\t\t}\n\t}\n\n\tpublic updateVersionText(versionCount: number): void {\n\t\tif (!this.wasVersionSelected) {\n\t\t\tconst text =\n\t\t\t\tversionCount === 0 ? \"\" : `Fetching information about ${versionCount} snapshots...`;\n\t\t\tthis.versionText.textContent = text;\n\t\t}\n\t}\n\n\tpublic updateLastOpText(lastKnownOp: number, stillLoading: boolean): void {\n\t\tconst text = stillLoading\n\t\t\t? `Last op (still loading): ${lastKnownOp}`\n\t\t\t: `Document's last op seq#: ${lastKnownOp}`;\n\t\tthis.lastOpText!.textContent = text;\n\t}\n\n\tprivate download(filename: string, data: string): void {\n\t\tconst element = document.createElement(\"a\");\n\t\telement.setAttribute(\"href\", `data:text/plain;charset=utf-8,${encodeURIComponent(data)}`);\n\t\telement.setAttribute(\"download\", filename);\n\n\t\telement.style.display = \"none\";\n\t\tdocument.body.append(element);\n\n\t\telement.click();\n\n\t\telement.remove();\n\t}\n}\n"]}
1
+ {"version":3,"file":"fluidDebuggerUi.js","sourceRoot":"","sources":["../src/fluidDebuggerUi.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert } from \"@fluidframework/core-utils/internal\";\nimport type {\n\tIVersion,\n\tISequencedDocumentMessage,\n} from \"@fluidframework/driver-definitions/internal\";\n\n/**\n * @internal\n */\nexport interface IDebuggerUI {\n\t/**\n\t * Version information is provided.\n\t * Expect updates (information about seq#, timestamp) through updateVersion() calls\n\t */\n\taddVersions(version: IVersion[]): void;\n\n\t/**\n\t * Call when new version is downloaded from storage\n\t * Expect multiple callbacks.\n\t */\n\tupdateVersion(index: number, version: IVersion, seqNumber: number): void;\n\n\t/**\n\t * Called in response to successful onVersionSelection() or onSnapshotFileSelection() call\n\t * and provides extra information about selection.\n\t * It expected that UI layer would change its mode as result of this call, i.e. switch to\n\t * displaying op playback controls (if this is supported)\n\t * Note: There maybe no call to versionSelected() in response to onSnapshotFileSelection() call\n\t * if file does not exist, has wrong name of wrong format.\n\t * @param version - version, file name, or undefined if playing ops.\n\t */\n\tversionSelected(seqNumber: number, version: IVersion | string): void;\n\n\t/**\n\t * Called by controller in response to new ops being downloaded\n\t * Called with disable = true if there are no (currently) ops to play\n\t */\n\tdisableNextOpButton(disable: boolean): void;\n\n\t/**\n\t * Called by controller when new ops arrive (or we are done playing previous batch)\n\t * Indicates next batch of ops that would be played when UI calls controller's onOpButtonClick()\n\t * Called with ops=[] when there are no ops to play.\n\t */\n\tupdateNextOpText(ops: ISequencedDocumentMessage[]): void;\n\n\t/**\n\t * Called periodically when new versions are downloaded from server\n\t */\n\tupdateVersionText(versionsLeft: number): void;\n\n\t/**\n\t * Called periodically to notify about last known op\n\t * @param lastKnownOp - seq number of last known op. -1 if can't play ops in this mode (load from file)\n\t * @param stillLoading - true if we did not reach yet the end of the stream\n\t */\n\tupdateLastOpText(lastKnownOp: number, stillLoading: boolean): void;\n}\n\n/**\n * @internal\n */\nexport interface IDebuggerController {\n\t/**\n\t * Initialization. UI layers calls into controller to connect the two.\n\t * @param ui - UI layer\n\t */\n\tconnectToUi(ui: IDebuggerUI);\n\n\t/**\n\t * Called by UI layer when debugger window is closed by user\n\t * If called before user makes selection of snapshot/file, original\n\t * document service is returned to loader (instead of debugger service) and normal document load continues.\n\t */\n\tonClose(): void;\n\n\t/**\n\t * UI Layer notifies about selection of version to continue.\n\t * On successful load, versionSelected() is called.\n\t * @param version - Snapshot version to start from.\n\t */\n\tonVersionSelection(version: IVersion): void;\n\n\t/**\n\t * UI Layer notifies about selection of version to continue.\n\t * On successful load, versionSelected() is called.\n\t * @param version - File to load snapshot from\n\t */\n\tonSnapshotFileSelection(file: File): void;\n\n\t/**\n\t * \"next op\" button is clicked in the UI\n\t * @param steps - number of ops to play.\n\t */\n\tonOpButtonClick(steps: number): void;\n\n\t/**\n\t * \"Download ops\" option is clicked in the UI. Returns JSON of the full opStream when available.\n\t * @param anonymize - anonymize the ops json using the sanitization tool\n\t */\n\tonDownloadOpsButtonClick(anonymize: boolean): Promise<string>;\n}\n\nconst debuggerWindowHtml = `<Title>Fluid Debugger</Title>\n<body>\n<h3>Fluid Debugger</h3>\nPlease select snapshot or file to start with<br/>\nClose debugger window to proceed to live document<br/><br/>\n<select style='width:250px' id='selector'>\n</select>\n&nbsp; &nbsp; &nbsp;\n<button id='buttonVers' style='width:60px'>Go</button><br/>\n<input id='file' type='file' value='Load from file'/>\n<br/><br/>\n<h4>Download the current document's ops</h4>\n<input type='checkbox' id='anonymize' value='Anonymize'>\n<label for='anonymize'>Anonymize</label>\n<button type='button' id='downloadOps'>Download ops</button>\n<br/><br/><div id='versionText'></div>\n</body>`;\n\nconst debuggerWindowHtml2 = `<Title>Fluid Debugger</Title>\n<body>\n<h3>Fluid Debugger</h3>\n<div id='versionText'></div>\n<div id='lastOp'></div>\n<br/>\nStep to move: <input type='number' id='steps' value='1' min='1' style='width:50px'/>\n&nbsp; &nbsp; &nbsp;<button id='buttonOps' style='width:60px'>Go</button>\n<br/><br/>\n<div id='text1'></div><div id='text2'></div><div id='text3'></div>\n<br/>\n<h4>Download the current document's ops</h4>\n<input type='checkbox' id='anonymize' value='Anonymize'>\n<label for='anonymize'>Anonymize</label>\n<button type='button' id='downloadOps'>Download ops</button>\n</body>`;\n\n/**\n * @internal\n */\nexport class DebuggerUI {\n\tpublic static create(controller: IDebuggerController): DebuggerUI | null {\n\t\tif (\n\t\t\ttypeof window !== \"object\" ||\n\t\t\twindow === null ||\n\t\t\ttypeof window.document !== \"object\" ||\n\t\t\twindow.document === null\n\t\t) {\n\t\t\tconsole.log(\"Can't create debugger window - not running in browser!\");\n\t\t\treturn null;\n\t\t}\n\n\t\tconst debuggerWindow = window.open(\n\t\t\t\"\",\n\t\t\t\"\",\n\t\t\t\"width=400,height=400,resizable=yes,location=no,menubar=no,titlebar=no,status=no,toolbar=no\",\n\t\t);\n\t\tif (!debuggerWindow) {\n\t\t\tconsole.error(\n\t\t\t\t\"Can't create debugger window - please enable pop-up windows in your browser!\",\n\t\t\t);\n\t\t\treturn null;\n\t\t}\n\n\t\treturn new DebuggerUI(controller, debuggerWindow);\n\t}\n\n\tprivate static formatDate(date: number): string {\n\t\t// Alternative - without timezone\n\t\t// new Date().toLocaleString('default', { timeZone: 'UTC'}));\n\t\t// new Date().toLocaleString('default', { year: 'numeric', month: 'short',\n\t\t// day: 'numeric', hour: '2-digit', minute: 'numeric', second: 'numeric' }));\n\t\treturn new Date(date).toUTCString();\n\t}\n\n\tprotected selector?: HTMLSelectElement;\n\tprotected versionText: HTMLDivElement;\n\n\tprotected buttonOps?: HTMLButtonElement;\n\tprotected text1?: HTMLDivElement;\n\tprotected text2?: HTMLDivElement;\n\tprotected text3?: HTMLDivElement;\n\tprotected lastOpText?: HTMLDivElement;\n\tprotected wasVersionSelected = false;\n\tprotected versions: IVersion[] = [];\n\n\tprotected documentClosed = false;\n\n\tprotected constructor(\n\t\tprivate readonly controller: IDebuggerController,\n\t\tprivate readonly debuggerWindow: Window,\n\t) {\n\t\tconst doc = this.debuggerWindow.document;\n\t\tdoc.write(debuggerWindowHtml);\n\n\t\twindow.addEventListener(\n\t\t\t\"beforeunload\",\n\t\t\t(e) => {\n\t\t\t\tthis.documentClosed = true;\n\t\t\t\tthis.debuggerWindow.close();\n\t\t\t},\n\t\t\tfalse,\n\t\t);\n\n\t\tthis.debuggerWindow.addEventListener(\n\t\t\t\"beforeunload\",\n\t\t\t(e) => {\n\t\t\t\tif (!this.documentClosed) {\n\t\t\t\t\tthis.controller.onClose();\n\t\t\t\t}\n\t\t\t},\n\t\t\tfalse,\n\t\t);\n\n\t\tthis.selector = doc.querySelector(\"#selector\") as HTMLSelectElement;\n\n\t\tconst buttonVers = doc.querySelector(\"#buttonVers\") as HTMLDivElement;\n\t\tbuttonVers.addEventListener(\"click\", () => {\n\t\t\tconst index = this.selector!.selectedIndex;\n\t\t\t// TODO Why are we non null asserting here\n\t\t\tcontroller.onVersionSelection(this.versions[index]!);\n\t\t});\n\n\t\tconst fileSnapshot = doc.querySelector(\"#file\") as HTMLInputElement;\n\t\tfileSnapshot.addEventListener(\n\t\t\t\"change\",\n\t\t\t() => {\n\t\t\t\tconst files = fileSnapshot.files;\n\t\t\t\tif (files) {\n\t\t\t\t\t// TODO Why are we non null asserting here\n\t\t\t\t\tcontroller.onSnapshotFileSelection(files[0]!);\n\t\t\t\t}\n\t\t\t},\n\t\t\tfalse,\n\t\t);\n\n\t\tconst opDownloadButton = doc.querySelector(\"#downloadOps\") as HTMLElement;\n\t\tconst anonymizeCheckbox = doc.querySelector(\"#anonymize\") as HTMLInputElement;\n\t\tthis.attachDownloadOpsListener(opDownloadButton, anonymizeCheckbox);\n\n\t\tthis.versionText = doc.querySelector(\"#versionText\") as HTMLDivElement;\n\t\tthis.versionText.textContent = \"Fetching snapshots, please wait...\";\n\n\t\tcontroller.connectToUi(this);\n\t}\n\n\tprivate attachDownloadOpsListener(element: HTMLElement, anonymize: HTMLInputElement): void {\n\t\telement.addEventListener(\"click\", () => {\n\t\t\tthis.controller\n\t\t\t\t.onDownloadOpsButtonClick(anonymize.checked)\n\t\t\t\t.then((opJson) => {\n\t\t\t\t\tthis.download(\"opStream.json\", opJson);\n\t\t\t\t})\n\t\t\t\t.catch((error) => {\n\t\t\t\t\tconsole.log(`Error downloading ops: ${error}`);\n\t\t\t\t});\n\t\t});\n\t}\n\n\tpublic addVersions(versions: IVersion[]): void {\n\t\tif (this.selector) {\n\t\t\tthis.versions = versions;\n\t\t\tfor (const version of versions) {\n\t\t\t\tconst option = document.createElement(\"option\");\n\t\t\t\toption.text =\n\t\t\t\t\tversion.date === undefined\n\t\t\t\t\t\t? `id = ${version.id}`\n\t\t\t\t\t\t: `id = ${version.id}, time = ${version.date}`;\n\t\t\t\tthis.selector.add(option);\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic updateVersion(index: number, version: IVersion, seqNumber: number): void {\n\t\tif (this.selector) {\n\t\t\tconst option = this.selector[index] as HTMLOptionElement;\n\t\t\toption.text = `${option.text}, seq = ${seqNumber}`;\n\t\t\tthis.selector[index] = option;\n\t\t}\n\t}\n\n\tpublic versionSelected(seqNumber: number, version: IVersion | string): void {\n\t\tconst text =\n\t\t\ttypeof version === \"string\"\n\t\t\t\t? `Playing ${version} file`\n\t\t\t\t: `Playing from ${version.id}, seq# ${seqNumber}`;\n\n\t\tthis.wasVersionSelected = true;\n\t\tdelete this.selector;\n\n\t\tconst doc = this.debuggerWindow.document;\n\t\tdoc.open();\n\t\tdoc.write(debuggerWindowHtml2);\n\t\tdoc.close();\n\n\t\tthis.lastOpText = doc.querySelector(\"#lastOp\") as HTMLDivElement;\n\t\tthis.text1 = doc.querySelector(\"#text1\") as HTMLDivElement;\n\t\tthis.text2 = doc.querySelector(\"#text2\") as HTMLDivElement;\n\t\tthis.text3 = doc.querySelector(\"#text3\") as HTMLDivElement;\n\n\t\tconst steps = doc.querySelector(\"#steps\") as HTMLInputElement;\n\t\tthis.buttonOps = doc.querySelector(\"#buttonOps\") as HTMLButtonElement;\n\t\tthis.buttonOps.disabled = true;\n\t\tthis.buttonOps.addEventListener(\"click\", () => {\n\t\t\tthis.controller.onOpButtonClick(Number(steps.value));\n\t\t});\n\n\t\tthis.versionText = doc.querySelector(\"#versionText\") as HTMLDivElement;\n\t\tthis.versionText.textContent = text;\n\n\t\tconst opDownloadButton = doc.querySelector(\"#downloadOps\") as HTMLElement;\n\t\tconst anonymizeCheckbox = doc.querySelector(\"#anonymize\") as HTMLInputElement;\n\t\tthis.attachDownloadOpsListener(opDownloadButton, anonymizeCheckbox);\n\t}\n\n\tpublic disableNextOpButton(disable: boolean): void {\n\t\tassert(!!this.buttonOps, 0x088 /* \"Missing button ops button!\" */);\n\t\tthis.buttonOps.disabled = disable;\n\t}\n\n\tpublic updateNextOpText(ops: ISequencedDocumentMessage[]): void {\n\t\tif (ops.length === 0) {\n\t\t\tthis.text1!.textContent = \"\";\n\t\t\tthis.text2!.textContent = \"\";\n\t\t\tthis.text3!.textContent = \"\";\n\t\t} else {\n\t\t\t// Non null asserting here because of the length check above\n\t\t\tconst op = ops[0]!;\n\t\t\tconst seq = op.sequenceNumber;\n\t\t\tconst date = DebuggerUI.formatDate(op.timestamp);\n\t\t\tthis.text1!.textContent = `Next op seq#: ${seq}`;\n\t\t\tthis.text2!.textContent = `Type: ${op.type}`;\n\t\t\tthis.text3!.textContent = `${date}`;\n\t\t}\n\t}\n\n\tpublic updateVersionText(versionCount: number): void {\n\t\tif (!this.wasVersionSelected) {\n\t\t\tconst text =\n\t\t\t\tversionCount === 0 ? \"\" : `Fetching information about ${versionCount} snapshots...`;\n\t\t\tthis.versionText.textContent = text;\n\t\t}\n\t}\n\n\tpublic updateLastOpText(lastKnownOp: number, stillLoading: boolean): void {\n\t\tconst text = stillLoading\n\t\t\t? `Last op (still loading): ${lastKnownOp}`\n\t\t\t: `Document's last op seq#: ${lastKnownOp}`;\n\t\tthis.lastOpText!.textContent = text;\n\t}\n\n\tprivate download(filename: string, data: string): void {\n\t\tconst element = document.createElement(\"a\");\n\t\telement.setAttribute(\"href\", `data:text/plain;charset=utf-8,${encodeURIComponent(data)}`);\n\t\telement.setAttribute(\"download\", filename);\n\n\t\telement.style.display = \"none\";\n\t\tdocument.body.append(element);\n\n\t\telement.click();\n\n\t\telement.remove();\n\t}\n}\n"]}
@@ -129,7 +129,7 @@ export declare const attachContentsSchema: {
129
129
  id: {
130
130
  type: string;
131
131
  };
132
- entries?: undefined;
132
+ entries?: never;
133
133
  };
134
134
  required: string[];
135
135
  additionalProperties: boolean;
@@ -144,8 +144,8 @@ export declare const attachContentsSchema: {
144
144
  id: {
145
145
  type: string;
146
146
  };
147
- contents?: undefined;
148
- encoding?: undefined;
147
+ contents?: never;
148
+ encoding?: never;
149
149
  };
150
150
  required: string[];
151
151
  additionalProperties: boolean;
@@ -250,7 +250,7 @@ export declare const opContentsSchema: {
250
250
  id: {
251
251
  type: string;
252
252
  };
253
- entries?: undefined;
253
+ entries?: never;
254
254
  };
255
255
  required: string[];
256
256
  additionalProperties: boolean;
@@ -265,8 +265,8 @@ export declare const opContentsSchema: {
265
265
  id: {
266
266
  type: string;
267
267
  };
268
- contents?: undefined;
269
- encoding?: undefined;
268
+ contents?: never;
269
+ encoding?: never;
270
270
  };
271
271
  required: string[];
272
272
  additionalProperties: boolean;
@@ -303,7 +303,7 @@ export declare const opContentsSchema: {
303
303
  id: {
304
304
  type: string;
305
305
  };
306
- entries?: undefined;
306
+ entries?: never;
307
307
  };
308
308
  required: string[];
309
309
  additionalProperties: boolean;
@@ -318,8 +318,8 @@ export declare const opContentsSchema: {
318
318
  id: {
319
319
  type: string;
320
320
  };
321
- contents?: undefined;
322
- encoding?: undefined;
321
+ contents?: never;
322
+ encoding?: never;
323
323
  };
324
324
  required: string[];
325
325
  additionalProperties: boolean;
@@ -387,12 +387,12 @@ export declare const opContentsSchema: {
387
387
  };
388
388
  required: string[];
389
389
  additionalProperties: boolean;
390
- $ref?: undefined;
390
+ $ref?: never;
391
391
  } | {
392
392
  $ref: string;
393
- properties?: undefined;
394
- required?: undefined;
395
- additionalProperties?: undefined;
393
+ properties?: never;
394
+ required?: never;
395
+ additionalProperties?: never;
396
396
  })[];
397
397
  };
398
398
  export declare const opContentsAttachSchema: {
@@ -422,7 +422,7 @@ export declare const opContentsAttachSchema: {
422
422
  id: {
423
423
  type: string;
424
424
  };
425
- entries?: undefined;
425
+ entries?: never;
426
426
  };
427
427
  required: string[];
428
428
  additionalProperties: boolean;
@@ -437,8 +437,8 @@ export declare const opContentsAttachSchema: {
437
437
  id: {
438
438
  type: string;
439
439
  };
440
- contents?: undefined;
441
- encoding?: undefined;
440
+ contents?: never;
441
+ encoding?: never;
442
442
  };
443
443
  required: string[];
444
444
  additionalProperties: boolean;
@@ -234,7 +234,7 @@ export class DebugReplayController extends ReplayController {
234
234
  this.stepsDeferred = new Deferred();
235
235
  this.ui.updateNextOpText(_fetchedOps);
236
236
  this.stepsToPlay = await this.stepsDeferred.promise;
237
- this.stepsDeferred = undefined;
237
+ delete this.stepsDeferred;
238
238
  this.ui.disableNextOpButton(true);
239
239
  }
240
240
  let playOps;
@@ -1 +1 @@
1
- {"version":3,"file":"fluidDebuggerController.js","sourceRoot":"","sources":["../src/fluidDebuggerController.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, Deferred } from \"@fluidframework/core-utils/internal\";\nimport type {\n\tIDocumentDeltaStorageService,\n\tIDocumentService,\n\tIDocumentStorageService,\n\tIDocumentAttributes,\n\tISnapshotTree,\n\tIVersion,\n\tISequencedDocumentMessage,\n} from \"@fluidframework/driver-definitions/internal\";\nimport { readAndParse } from \"@fluidframework/driver-utils/internal\";\nimport type {\n\tIFileSnapshot,\n\tReadDocumentStorageServiceBase,\n} from \"@fluidframework/replay-driver/internal\";\nimport {\n\tFileSnapshotReader,\n\tReplayController,\n\tSnapshotStorage,\n} from \"@fluidframework/replay-driver/internal\";\n\nimport type { IDebuggerController, IDebuggerUI } from \"./fluidDebuggerUi.js\";\nimport { Sanitizer } from \"./sanitizer.js\";\n\n/**\n * @internal\n */\n// eslint-disable-next-line @rushstack/no-new-null\nexport type debuggerUIFactory = (controller: IDebuggerController) => IDebuggerUI | null;\n\n/**\n * Replay controller that uses pop-up window to control op playback\n * @internal\n */\nexport class DebugReplayController extends ReplayController implements IDebuggerController {\n\t// eslint-disable-next-line @rushstack/no-new-null\n\tpublic static create(createUi: debuggerUIFactory): DebugReplayController | null {\n\t\tif (typeof localStorage === \"object\" && localStorage?.FluidDebugger) {\n\t\t\tconst controller = new DebugReplayController();\n\t\t\tconst ui = createUi(controller);\n\t\t\tif (ui) {\n\t\t\t\treturn controller;\n\t\t\t}\n\t\t}\n\t\treturn null;\n\t}\n\n\tprotected static readonly WindowClosedSeq = -1; // Seq# to indicate that user closed window\n\n\tprotected static async seqFromTree(\n\t\tdocumentStorageService: IDocumentStorageService,\n\t\ttree: ISnapshotTree | null,\n\t): Promise<number> {\n\t\tif (!tree) {\n\t\t\treturn 0;\n\t\t}\n\n\t\t// TODO Why are we non null asserting here\n\t\tconst attributesHash = tree.trees[\".protocol\"]!.blobs.attributes!;\n\t\tconst attrib = await readAndParse<IDocumentAttributes>(\n\t\t\tdocumentStorageService,\n\t\t\tattributesHash,\n\t\t);\n\t\treturn attrib.sequenceNumber;\n\t}\n\n\tprotected ui: IDebuggerUI = null as any as IDebuggerUI; // Not to check on every line that it's not null\n\tprotected stepsDeferred?: Deferred<number>;\n\tprotected startSeqDeferred = new Deferred<number>();\n\n\t// True will cause us ping server indefinitely waiting for new ops\n\tprotected retryFetchOpsOnEndOfFile = false;\n\n\tprotected documentService?: IDocumentService;\n\tprotected documentStorageService?: IDocumentStorageService;\n\tprotected versions: IVersion[] = [];\n\tprotected stepsToPlay: number = 0;\n\tprotected lastOpReached = false;\n\tprotected versionCount = 0;\n\n\tprotected storage?: ReadDocumentStorageServiceBase;\n\n\t// Member to prevent repeated initialization in initStorage(...), which also\n\t// returns if this controller should be used or function as a passthrough\n\tprivate shouldUseController: boolean | undefined;\n\n\tpublic connectToUi(ui: IDebuggerUI): void {\n\t\tthis.ui = ui;\n\t}\n\n\tpublic onClose(): void {\n\t\tthis.startSeqDeferred.resolve(DebugReplayController.WindowClosedSeq);\n\t}\n\n\t// eslint-disable-next-line @typescript-eslint/no-misused-promises\n\tpublic async onVersionSelection(version: IVersion): Promise<void> {\n\t\tif (!this.documentStorageService) {\n\t\t\tthrow new Error(\"onVersionSelection: no storage\");\n\t\t}\n\n\t\tconst tree = await this.documentStorageService.getSnapshotTree(version);\n\t\tconst seq = await DebugReplayController.seqFromTree(this.documentStorageService, tree);\n\t\tthis.resolveStorage(seq, new SnapshotStorage(this.documentStorageService, tree), version);\n\t}\n\n\tpublic onOpButtonClick(steps: number): void {\n\t\tif (this.stepsDeferred && !Number.isNaN(steps) && steps > 0) {\n\t\t\tthis.stepsDeferred.resolve(steps);\n\t\t}\n\t}\n\n\tpublic onSnapshotFileSelection(file: File): void {\n\t\tif (!/^snapshot.*\\.json/.test(file.name)) {\n\t\t\talert(`Incorrect file name: ${file.name}`);\n\t\t\treturn;\n\t\t}\n\t\tif (/.*_expanded.*/.test(file.name)) {\n\t\t\talert(`Incorrect file name - please use non-extended files: ${file.name}`);\n\t\t\treturn;\n\t\t}\n\n\t\tconst reader = new FileReader();\n\t\treader.addEventListener(\"load\", () => {\n\t\t\tif (this.documentStorageService) {\n\t\t\t\tconst text = reader.result as string;\n\t\t\t\ttry {\n\t\t\t\t\tconst json: IFileSnapshot = JSON.parse(text) as IFileSnapshot;\n\t\t\t\t\t/*\n Const docStorage = this.documentStorageService;\n const storage = {\n read: (blobId: string) => this.read(docStorage, blobId),\n };\n const seq = await DebugReplayController.seqFromTree(\n storage as IDocumentStorageService,\n tree);\n this.startSeqDeferred.resolve(seq);\n */\n\t\t\t\t\t// No ability to load ops, so just say - pick up from infinite op.\n\t\t\t\t\tthis.retryFetchOpsOnEndOfFile = false;\n\t\t\t\t\tthis.lastOpReached = true;\n\t\t\t\t\tthis.resolveStorage(\n\t\t\t\t\t\tNumber.MAX_SAFE_INTEGER,\n\t\t\t\t\t\tnew FileSnapshotReader(json),\n\t\t\t\t\t\tfile.name,\n\t\t\t\t\t);\n\t\t\t\t} catch (error) {\n\t\t\t\t\talert(`Error parsing file: ${error}`);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t\treader.readAsText(file, \"utf-8\");\n\t}\n\n\tpublic async onDownloadOpsButtonClick(anonymize: boolean): Promise<string> {\n\t\tif (this.documentService === undefined) {\n\t\t\tthrow new Error(\"DocumentService required\");\n\t\t}\n\n\t\tconst documentDeltaStorageService = await this.documentService.connectToDeltaStorage();\n\t\tlet messages = await this.fetchOpsFromDeltaStorage(documentDeltaStorageService);\n\n\t\tif (anonymize) {\n\t\t\tconst sanitizer = new Sanitizer(messages, false /* fullScrub */, false /* noBail */);\n\t\t\tmessages = sanitizer.sanitize();\n\t\t}\n\n\t\treturn JSON.stringify(messages, undefined, 2);\n\t}\n\n\tprivate async fetchOpsFromDeltaStorage(\n\t\tdocumentDeltaStorageService,\n\t): Promise<ISequencedDocumentMessage[]> {\n\t\tconst deltaGenerator = generateSequencedMessagesFromDeltaStorage(\n\t\t\tdocumentDeltaStorageService,\n\t\t);\n\t\tlet messages: ISequencedDocumentMessage[] = [];\n\t\tfor await (const message of deltaGenerator) {\n\t\t\tmessages = messages.concat(message);\n\t\t}\n\t\treturn messages;\n\t}\n\n\tpublic fetchTo(currentOp: number): number | undefined {\n\t\treturn undefined;\n\t}\n\n\t// Returns true if version / file / ops selections is made.\n\tpublic isSelectionMade(): boolean {\n\t\treturn this.storage !== undefined;\n\t}\n\n\tpublic async downloadVersionInfo(\n\t\tdocumentStorageService: IDocumentStorageService,\n\t\tprevRequest: Promise<void>,\n\t\tindex: number,\n\t\tversion: IVersion,\n\t): Promise<void> {\n\t\tif (this.isSelectionMade()) {\n\t\t\treturn;\n\t\t}\n\n\t\tawait prevRequest;\n\n\t\tconst treeV = await documentStorageService.getSnapshotTree(version);\n\t\tconst seqV = await DebugReplayController.seqFromTree(documentStorageService, treeV);\n\n\t\tif (!this.isSelectionMade()) {\n\t\t\tthis.versionCount--;\n\t\t\tthis.ui.updateVersionText(this.versionCount);\n\t\t\tthis.ui.updateVersion(index, version, seqV);\n\t\t}\n\t}\n\n\tpublic async initStorage(documentService: IDocumentService): Promise<boolean> {\n\t\tif (this.shouldUseController !== undefined) {\n\t\t\treturn this.shouldUseController;\n\t\t}\n\n\t\tassert(!!documentService, 0x080 /* \"Invalid document service!\" */);\n\t\tassert(!this.documentService, 0x081 /* \"Document service already set!\" */);\n\t\tassert(!this.documentStorageService, 0x082 /* \"Document storage service already set!\" */);\n\t\tthis.documentService = documentService;\n\t\tthis.documentStorageService = await documentService.connectToStorage();\n\n\t\t// User can chose \"file\" at any moment in time!\n\t\tif (!this.isSelectionMade()) {\n\t\t\tthis.versions = await this.documentStorageService.getVersions(\"\", 50);\n\t\t\tif (!this.isSelectionMade()) {\n\t\t\t\tthis.ui.addVersions(this.versions);\n\t\t\t\tthis.ui.updateVersionText(this.versionCount);\n\t\t\t}\n\t\t}\n\n\t\tthis.versionCount = this.versions.length;\n\n\t\t// Download all versions - do 10 downloads in parallel to avoid being throttled\n\t\tconst buckets = 10;\n\t\tconst work: Promise<void>[] = [];\n\t\tfor (let i = 0; i < buckets; i++) {\n\t\t\tlet prevRequest = Promise.resolve();\n\t\t\tfor (let index = i; index < this.versions.length; index += buckets) {\n\t\t\t\t// Non null asserting here because we are iterating though versions\n\t\t\t\tconst version = this.versions[index]!;\n\t\t\t\tprevRequest = this.downloadVersionInfo(\n\t\t\t\t\tthis.documentStorageService,\n\t\t\t\t\tprevRequest,\n\t\t\t\t\tindex,\n\t\t\t\t\tversion,\n\t\t\t\t);\n\t\t\t}\n\t\t\twork.push(prevRequest);\n\t\t}\n\n\t\t// Don't wait for stuff to populate.\n\t\t// eslint-disable-next-line @typescript-eslint/no-floating-promises\n\t\tPromise.all(work).then(() => {\n\t\t\tthis.ui.updateVersionText(0);\n\t\t});\n\n\t\t// This hangs until the user makes a selection or closes the window.\n\t\tthis.shouldUseController =\n\t\t\t(await this.startSeqDeferred.promise) !== DebugReplayController.WindowClosedSeq;\n\n\t\tassert(\n\t\t\tthis.isSelectionMade() === this.shouldUseController,\n\t\t\t0x083 /* \"User selection status does not match replay controller use status!\" */,\n\t\t);\n\t\treturn this.shouldUseController;\n\t}\n\n\tpublic async readBlob(blobId: string): Promise<ArrayBufferLike> {\n\t\tif (this.storage !== undefined) {\n\t\t\treturn this.storage.readBlob(blobId);\n\t\t}\n\t\tthrow new Error(\"Reading blob before storage is setup properly\");\n\t}\n\n\t// eslint-disable-next-line @rushstack/no-new-null\n\tpublic async getVersions(versionId: string | null, count: number): Promise<IVersion[]> {\n\t\tif (this.storage !== undefined) {\n\t\t\treturn this.storage.getVersions(versionId, count);\n\t\t}\n\t\tthrow new Error(\"initStorage() was not called!\");\n\t}\n\n\t// eslint-disable-next-line @rushstack/no-new-null\n\tpublic async getSnapshotTree(versionRequested?: IVersion): Promise<ISnapshotTree | null> {\n\t\tif (this.storage !== undefined) {\n\t\t\treturn this.storage.getSnapshotTree(versionRequested);\n\t\t}\n\t\tthrow new Error(\"Reading snapshot tree before storage is setup properly\");\n\t}\n\n\tpublic async getStartingOpSequence(): Promise<number> {\n\t\treturn this.startSeqDeferred.promise;\n\t}\n\n\t/**\n\t * Return true if we are done processing ops\n\t */\n\tpublic isDoneFetch(currentOp: number, lastTimeStamp?: number): boolean {\n\t\tif (lastTimeStamp === undefined) {\n\t\t\tthis.lastOpReached = true;\n\t\t\tif (currentOp === Number.MAX_SAFE_INTEGER) {\n\t\t\t\tthis.ui.updateLastOpText(-1, false);\n\t\t\t} else {\n\t\t\t\tthis.ui.updateLastOpText(currentOp, false);\n\t\t\t}\n\t\t} else {\n\t\t\tthis.ui.updateLastOpText(currentOp, true);\n\t\t}\n\t\treturn this.lastOpReached && !this.retryFetchOpsOnEndOfFile;\n\t}\n\n\tpublic async replay(\n\t\temitter: (op: ISequencedDocumentMessage[]) => void,\n\t\tfetchedOps: ISequencedDocumentMessage[],\n\t): Promise<void> {\n\t\tlet _fetchedOps = fetchedOps;\n\t\twhile (true) {\n\t\t\tif (_fetchedOps.length === 0) {\n\t\t\t\tthis.ui.updateNextOpText([]);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (this.stepsToPlay === 0) {\n\t\t\t\tthis.ui.disableNextOpButton(false);\n\t\t\t\tthis.stepsDeferred = new Deferred<number>();\n\n\t\t\t\tthis.ui.updateNextOpText(_fetchedOps);\n\n\t\t\t\tthis.stepsToPlay = await this.stepsDeferred.promise;\n\n\t\t\t\tthis.stepsDeferred = undefined;\n\t\t\t\tthis.ui.disableNextOpButton(true);\n\t\t\t}\n\n\t\t\tlet playOps: ISequencedDocumentMessage[];\n\t\t\tif (this.stepsToPlay >= _fetchedOps.length) {\n\t\t\t\tplayOps = _fetchedOps;\n\t\t\t\tthis.stepsToPlay -= _fetchedOps.length;\n\t\t\t\t_fetchedOps = [];\n\t\t\t} else {\n\t\t\t\tplayOps = _fetchedOps.splice(0, this.stepsToPlay);\n\t\t\t\tthis.stepsToPlay = 0;\n\t\t\t}\n\t\t\temitter(playOps);\n\t\t}\n\t}\n\n\tprotected resolveStorage(\n\t\tseq: number,\n\t\tstorage: ReadDocumentStorageServiceBase,\n\t\tversion: IVersion | string,\n\t): void {\n\t\tassert(\n\t\t\t!this.isSelectionMade(),\n\t\t\t0x084 /* \"On storage resolve, user selection already made!\" */,\n\t\t);\n\t\tassert(!!storage, 0x085 /* \"On storage resolve, missing storage!\" */);\n\t\tthis.storage = storage;\n\t\tassert(\n\t\t\tthis.isSelectionMade(),\n\t\t\t0x086 /* \"After storage resolve, user selection status still false!\" */,\n\t\t);\n\n\t\tthis.ui.versionSelected(seq, version);\n\t\tthis.startSeqDeferred.resolve(seq);\n\t}\n}\n\nasync function* generateSequencedMessagesFromDeltaStorage(\n\tdeltaStorage: IDocumentDeltaStorageService,\n): AsyncGenerator<ISequencedDocumentMessage[], void, undefined> {\n\tconst stream = deltaStorage.fetchMessages(1, undefined);\n\twhile (true) {\n\t\tconst result = await stream.read();\n\t\tif (result.done) {\n\t\t\treturn;\n\t\t}\n\t\tyield result.value;\n\t}\n}\n"]}
1
+ {"version":3,"file":"fluidDebuggerController.js","sourceRoot":"","sources":["../src/fluidDebuggerController.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, Deferred } from \"@fluidframework/core-utils/internal\";\nimport type {\n\tIDocumentDeltaStorageService,\n\tIDocumentService,\n\tIDocumentStorageService,\n\tIDocumentAttributes,\n\tISnapshotTree,\n\tIVersion,\n\tISequencedDocumentMessage,\n} from \"@fluidframework/driver-definitions/internal\";\nimport { readAndParse } from \"@fluidframework/driver-utils/internal\";\nimport type {\n\tIFileSnapshot,\n\tReadDocumentStorageServiceBase,\n} from \"@fluidframework/replay-driver/internal\";\nimport {\n\tFileSnapshotReader,\n\tReplayController,\n\tSnapshotStorage,\n} from \"@fluidframework/replay-driver/internal\";\n\nimport type { IDebuggerController, IDebuggerUI } from \"./fluidDebuggerUi.js\";\nimport { Sanitizer } from \"./sanitizer.js\";\n\n/**\n * @internal\n */\n// eslint-disable-next-line @rushstack/no-new-null\nexport type debuggerUIFactory = (controller: IDebuggerController) => IDebuggerUI | null;\n\n/**\n * Replay controller that uses pop-up window to control op playback\n * @internal\n */\nexport class DebugReplayController extends ReplayController implements IDebuggerController {\n\t// eslint-disable-next-line @rushstack/no-new-null\n\tpublic static create(createUi: debuggerUIFactory): DebugReplayController | null {\n\t\tif (typeof localStorage === \"object\" && localStorage?.FluidDebugger) {\n\t\t\tconst controller = new DebugReplayController();\n\t\t\tconst ui = createUi(controller);\n\t\t\tif (ui) {\n\t\t\t\treturn controller;\n\t\t\t}\n\t\t}\n\t\treturn null;\n\t}\n\n\tprotected static readonly WindowClosedSeq = -1; // Seq# to indicate that user closed window\n\n\tprotected static async seqFromTree(\n\t\tdocumentStorageService: IDocumentStorageService,\n\t\ttree: ISnapshotTree | null,\n\t): Promise<number> {\n\t\tif (!tree) {\n\t\t\treturn 0;\n\t\t}\n\n\t\t// TODO Why are we non null asserting here\n\t\tconst attributesHash = tree.trees[\".protocol\"]!.blobs.attributes!;\n\t\tconst attrib = await readAndParse<IDocumentAttributes>(\n\t\t\tdocumentStorageService,\n\t\t\tattributesHash,\n\t\t);\n\t\treturn attrib.sequenceNumber;\n\t}\n\n\tprotected ui: IDebuggerUI = null as any as IDebuggerUI; // Not to check on every line that it's not null\n\tprotected stepsDeferred?: Deferred<number>;\n\tprotected startSeqDeferred = new Deferred<number>();\n\n\t// True will cause us ping server indefinitely waiting for new ops\n\tprotected retryFetchOpsOnEndOfFile = false;\n\n\tprotected documentService?: IDocumentService;\n\tprotected documentStorageService?: IDocumentStorageService;\n\tprotected versions: IVersion[] = [];\n\tprotected stepsToPlay: number = 0;\n\tprotected lastOpReached = false;\n\tprotected versionCount = 0;\n\n\tprotected storage?: ReadDocumentStorageServiceBase;\n\n\t// Member to prevent repeated initialization in initStorage(...), which also\n\t// returns if this controller should be used or function as a passthrough\n\tprivate shouldUseController: boolean | undefined;\n\n\tpublic connectToUi(ui: IDebuggerUI): void {\n\t\tthis.ui = ui;\n\t}\n\n\tpublic onClose(): void {\n\t\tthis.startSeqDeferred.resolve(DebugReplayController.WindowClosedSeq);\n\t}\n\n\t// eslint-disable-next-line @typescript-eslint/no-misused-promises\n\tpublic async onVersionSelection(version: IVersion): Promise<void> {\n\t\tif (!this.documentStorageService) {\n\t\t\tthrow new Error(\"onVersionSelection: no storage\");\n\t\t}\n\n\t\tconst tree = await this.documentStorageService.getSnapshotTree(version);\n\t\tconst seq = await DebugReplayController.seqFromTree(this.documentStorageService, tree);\n\t\tthis.resolveStorage(seq, new SnapshotStorage(this.documentStorageService, tree), version);\n\t}\n\n\tpublic onOpButtonClick(steps: number): void {\n\t\tif (this.stepsDeferred && !Number.isNaN(steps) && steps > 0) {\n\t\t\tthis.stepsDeferred.resolve(steps);\n\t\t}\n\t}\n\n\tpublic onSnapshotFileSelection(file: File): void {\n\t\tif (!/^snapshot.*\\.json/.test(file.name)) {\n\t\t\talert(`Incorrect file name: ${file.name}`);\n\t\t\treturn;\n\t\t}\n\t\tif (/.*_expanded.*/.test(file.name)) {\n\t\t\talert(`Incorrect file name - please use non-extended files: ${file.name}`);\n\t\t\treturn;\n\t\t}\n\n\t\tconst reader = new FileReader();\n\t\treader.addEventListener(\"load\", () => {\n\t\t\tif (this.documentStorageService) {\n\t\t\t\tconst text = reader.result as string;\n\t\t\t\ttry {\n\t\t\t\t\tconst json: IFileSnapshot = JSON.parse(text) as IFileSnapshot;\n\t\t\t\t\t/*\n Const docStorage = this.documentStorageService;\n const storage = {\n read: (blobId: string) => this.read(docStorage, blobId),\n };\n const seq = await DebugReplayController.seqFromTree(\n storage as IDocumentStorageService,\n tree);\n this.startSeqDeferred.resolve(seq);\n */\n\t\t\t\t\t// No ability to load ops, so just say - pick up from infinite op.\n\t\t\t\t\tthis.retryFetchOpsOnEndOfFile = false;\n\t\t\t\t\tthis.lastOpReached = true;\n\t\t\t\t\tthis.resolveStorage(\n\t\t\t\t\t\tNumber.MAX_SAFE_INTEGER,\n\t\t\t\t\t\tnew FileSnapshotReader(json),\n\t\t\t\t\t\tfile.name,\n\t\t\t\t\t);\n\t\t\t\t} catch (error) {\n\t\t\t\t\talert(`Error parsing file: ${error}`);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t\treader.readAsText(file, \"utf-8\");\n\t}\n\n\tpublic async onDownloadOpsButtonClick(anonymize: boolean): Promise<string> {\n\t\tif (this.documentService === undefined) {\n\t\t\tthrow new Error(\"DocumentService required\");\n\t\t}\n\n\t\tconst documentDeltaStorageService = await this.documentService.connectToDeltaStorage();\n\t\tlet messages = await this.fetchOpsFromDeltaStorage(documentDeltaStorageService);\n\n\t\tif (anonymize) {\n\t\t\tconst sanitizer = new Sanitizer(messages, false /* fullScrub */, false /* noBail */);\n\t\t\tmessages = sanitizer.sanitize();\n\t\t}\n\n\t\treturn JSON.stringify(messages, undefined, 2);\n\t}\n\n\tprivate async fetchOpsFromDeltaStorage(\n\t\tdocumentDeltaStorageService,\n\t): Promise<ISequencedDocumentMessage[]> {\n\t\tconst deltaGenerator = generateSequencedMessagesFromDeltaStorage(\n\t\t\tdocumentDeltaStorageService,\n\t\t);\n\t\tlet messages: ISequencedDocumentMessage[] = [];\n\t\tfor await (const message of deltaGenerator) {\n\t\t\tmessages = messages.concat(message);\n\t\t}\n\t\treturn messages;\n\t}\n\n\tpublic fetchTo(currentOp: number): number | undefined {\n\t\treturn undefined;\n\t}\n\n\t// Returns true if version / file / ops selections is made.\n\tpublic isSelectionMade(): boolean {\n\t\treturn this.storage !== undefined;\n\t}\n\n\tpublic async downloadVersionInfo(\n\t\tdocumentStorageService: IDocumentStorageService,\n\t\tprevRequest: Promise<void>,\n\t\tindex: number,\n\t\tversion: IVersion,\n\t): Promise<void> {\n\t\tif (this.isSelectionMade()) {\n\t\t\treturn;\n\t\t}\n\n\t\tawait prevRequest;\n\n\t\tconst treeV = await documentStorageService.getSnapshotTree(version);\n\t\tconst seqV = await DebugReplayController.seqFromTree(documentStorageService, treeV);\n\n\t\tif (!this.isSelectionMade()) {\n\t\t\tthis.versionCount--;\n\t\t\tthis.ui.updateVersionText(this.versionCount);\n\t\t\tthis.ui.updateVersion(index, version, seqV);\n\t\t}\n\t}\n\n\tpublic async initStorage(documentService: IDocumentService): Promise<boolean> {\n\t\tif (this.shouldUseController !== undefined) {\n\t\t\treturn this.shouldUseController;\n\t\t}\n\n\t\tassert(!!documentService, 0x080 /* \"Invalid document service!\" */);\n\t\tassert(!this.documentService, 0x081 /* \"Document service already set!\" */);\n\t\tassert(!this.documentStorageService, 0x082 /* \"Document storage service already set!\" */);\n\t\tthis.documentService = documentService;\n\t\tthis.documentStorageService = await documentService.connectToStorage();\n\n\t\t// User can chose \"file\" at any moment in time!\n\t\tif (!this.isSelectionMade()) {\n\t\t\tthis.versions = await this.documentStorageService.getVersions(\"\", 50);\n\t\t\tif (!this.isSelectionMade()) {\n\t\t\t\tthis.ui.addVersions(this.versions);\n\t\t\t\tthis.ui.updateVersionText(this.versionCount);\n\t\t\t}\n\t\t}\n\n\t\tthis.versionCount = this.versions.length;\n\n\t\t// Download all versions - do 10 downloads in parallel to avoid being throttled\n\t\tconst buckets = 10;\n\t\tconst work: Promise<void>[] = [];\n\t\tfor (let i = 0; i < buckets; i++) {\n\t\t\tlet prevRequest = Promise.resolve();\n\t\t\tfor (let index = i; index < this.versions.length; index += buckets) {\n\t\t\t\t// Non null asserting here because we are iterating though versions\n\t\t\t\tconst version = this.versions[index]!;\n\t\t\t\tprevRequest = this.downloadVersionInfo(\n\t\t\t\t\tthis.documentStorageService,\n\t\t\t\t\tprevRequest,\n\t\t\t\t\tindex,\n\t\t\t\t\tversion,\n\t\t\t\t);\n\t\t\t}\n\t\t\twork.push(prevRequest);\n\t\t}\n\n\t\t// Don't wait for stuff to populate.\n\t\t// eslint-disable-next-line @typescript-eslint/no-floating-promises\n\t\tPromise.all(work).then(() => {\n\t\t\tthis.ui.updateVersionText(0);\n\t\t});\n\n\t\t// This hangs until the user makes a selection or closes the window.\n\t\tthis.shouldUseController =\n\t\t\t(await this.startSeqDeferred.promise) !== DebugReplayController.WindowClosedSeq;\n\n\t\tassert(\n\t\t\tthis.isSelectionMade() === this.shouldUseController,\n\t\t\t0x083 /* \"User selection status does not match replay controller use status!\" */,\n\t\t);\n\t\treturn this.shouldUseController;\n\t}\n\n\tpublic async readBlob(blobId: string): Promise<ArrayBufferLike> {\n\t\tif (this.storage !== undefined) {\n\t\t\treturn this.storage.readBlob(blobId);\n\t\t}\n\t\tthrow new Error(\"Reading blob before storage is setup properly\");\n\t}\n\n\t// eslint-disable-next-line @rushstack/no-new-null\n\tpublic async getVersions(versionId: string | null, count: number): Promise<IVersion[]> {\n\t\tif (this.storage !== undefined) {\n\t\t\treturn this.storage.getVersions(versionId, count);\n\t\t}\n\t\tthrow new Error(\"initStorage() was not called!\");\n\t}\n\n\t// eslint-disable-next-line @rushstack/no-new-null\n\tpublic async getSnapshotTree(versionRequested?: IVersion): Promise<ISnapshotTree | null> {\n\t\tif (this.storage !== undefined) {\n\t\t\treturn this.storage.getSnapshotTree(versionRequested);\n\t\t}\n\t\tthrow new Error(\"Reading snapshot tree before storage is setup properly\");\n\t}\n\n\tpublic async getStartingOpSequence(): Promise<number> {\n\t\treturn this.startSeqDeferred.promise;\n\t}\n\n\t/**\n\t * Return true if we are done processing ops\n\t */\n\tpublic isDoneFetch(currentOp: number, lastTimeStamp?: number): boolean {\n\t\tif (lastTimeStamp === undefined) {\n\t\t\tthis.lastOpReached = true;\n\t\t\tif (currentOp === Number.MAX_SAFE_INTEGER) {\n\t\t\t\tthis.ui.updateLastOpText(-1, false);\n\t\t\t} else {\n\t\t\t\tthis.ui.updateLastOpText(currentOp, false);\n\t\t\t}\n\t\t} else {\n\t\t\tthis.ui.updateLastOpText(currentOp, true);\n\t\t}\n\t\treturn this.lastOpReached && !this.retryFetchOpsOnEndOfFile;\n\t}\n\n\tpublic async replay(\n\t\temitter: (op: ISequencedDocumentMessage[]) => void,\n\t\tfetchedOps: ISequencedDocumentMessage[],\n\t): Promise<void> {\n\t\tlet _fetchedOps = fetchedOps;\n\t\twhile (true) {\n\t\t\tif (_fetchedOps.length === 0) {\n\t\t\t\tthis.ui.updateNextOpText([]);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (this.stepsToPlay === 0) {\n\t\t\t\tthis.ui.disableNextOpButton(false);\n\t\t\t\tthis.stepsDeferred = new Deferred<number>();\n\n\t\t\t\tthis.ui.updateNextOpText(_fetchedOps);\n\n\t\t\t\tthis.stepsToPlay = await this.stepsDeferred.promise;\n\n\t\t\t\tdelete this.stepsDeferred;\n\t\t\t\tthis.ui.disableNextOpButton(true);\n\t\t\t}\n\n\t\t\tlet playOps: ISequencedDocumentMessage[];\n\t\t\tif (this.stepsToPlay >= _fetchedOps.length) {\n\t\t\t\tplayOps = _fetchedOps;\n\t\t\t\tthis.stepsToPlay -= _fetchedOps.length;\n\t\t\t\t_fetchedOps = [];\n\t\t\t} else {\n\t\t\t\tplayOps = _fetchedOps.splice(0, this.stepsToPlay);\n\t\t\t\tthis.stepsToPlay = 0;\n\t\t\t}\n\t\t\temitter(playOps);\n\t\t}\n\t}\n\n\tprotected resolveStorage(\n\t\tseq: number,\n\t\tstorage: ReadDocumentStorageServiceBase,\n\t\tversion: IVersion | string,\n\t): void {\n\t\tassert(\n\t\t\t!this.isSelectionMade(),\n\t\t\t0x084 /* \"On storage resolve, user selection already made!\" */,\n\t\t);\n\t\tassert(!!storage, 0x085 /* \"On storage resolve, missing storage!\" */);\n\t\tthis.storage = storage;\n\t\tassert(\n\t\t\tthis.isSelectionMade(),\n\t\t\t0x086 /* \"After storage resolve, user selection status still false!\" */,\n\t\t);\n\n\t\tthis.ui.versionSelected(seq, version);\n\t\tthis.startSeqDeferred.resolve(seq);\n\t}\n}\n\nasync function* generateSequencedMessagesFromDeltaStorage(\n\tdeltaStorage: IDocumentDeltaStorageService,\n): AsyncGenerator<ISequencedDocumentMessage[], void, undefined> {\n\tconst stream = deltaStorage.fetchMessages(1, undefined);\n\twhile (true) {\n\t\tconst result = await stream.read();\n\t\tif (result.done) {\n\t\t\treturn;\n\t\t}\n\t\tyield result.value;\n\t}\n}\n"]}
@@ -138,7 +138,7 @@ export class DebuggerUI {
138
138
  ? `Playing ${version} file`
139
139
  : `Playing from ${version.id}, seq# ${seqNumber}`;
140
140
  this.wasVersionSelected = true;
141
- this.selector = undefined;
141
+ delete this.selector;
142
142
  const doc = this.debuggerWindow.document;
143
143
  doc.open();
144
144
  doc.write(debuggerWindowHtml2);
@@ -1 +1 @@
1
- {"version":3,"file":"fluidDebuggerUi.js","sourceRoot":"","sources":["../src/fluidDebuggerUi.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert } from \"@fluidframework/core-utils/internal\";\nimport type {\n\tIVersion,\n\tISequencedDocumentMessage,\n} from \"@fluidframework/driver-definitions/internal\";\n\n/**\n * @internal\n */\nexport interface IDebuggerUI {\n\t/**\n\t * Version information is provided.\n\t * Expect updates (information about seq#, timestamp) through updateVersion() calls\n\t */\n\taddVersions(version: IVersion[]): void;\n\n\t/**\n\t * Call when new version is downloaded from storage\n\t * Expect multiple callbacks.\n\t */\n\tupdateVersion(index: number, version: IVersion, seqNumber: number): void;\n\n\t/**\n\t * Called in response to successful onVersionSelection() or onSnapshotFileSelection() call\n\t * and provides extra information about selection.\n\t * It expected that UI layer would change its mode as result of this call, i.e. switch to\n\t * displaying op playback controls (if this is supported)\n\t * Note: There maybe no call to versionSelected() in response to onSnapshotFileSelection() call\n\t * if file does not exist, has wrong name of wrong format.\n\t * @param version - version, file name, or undefined if playing ops.\n\t */\n\tversionSelected(seqNumber: number, version: IVersion | string): void;\n\n\t/**\n\t * Called by controller in response to new ops being downloaded\n\t * Called with disable = true if there are no (currently) ops to play\n\t */\n\tdisableNextOpButton(disable: boolean): void;\n\n\t/**\n\t * Called by controller when new ops arrive (or we are done playing previous batch)\n\t * Indicates next batch of ops that would be played when UI calls controller's onOpButtonClick()\n\t * Called with ops=[] when there are no ops to play.\n\t */\n\tupdateNextOpText(ops: ISequencedDocumentMessage[]): void;\n\n\t/**\n\t * Called periodically when new versions are downloaded from server\n\t */\n\tupdateVersionText(versionsLeft: number): void;\n\n\t/**\n\t * Called periodically to notify about last known op\n\t * @param lastKnownOp - seq number of last known op. -1 if can't play ops in this mode (load from file)\n\t * @param stillLoading - true if we did not reach yet the end of the stream\n\t */\n\tupdateLastOpText(lastKnownOp: number, stillLoading: boolean): void;\n}\n\n/**\n * @internal\n */\nexport interface IDebuggerController {\n\t/**\n\t * Initialization. UI layers calls into controller to connect the two.\n\t * @param ui - UI layer\n\t */\n\tconnectToUi(ui: IDebuggerUI);\n\n\t/**\n\t * Called by UI layer when debugger window is closed by user\n\t * If called before user makes selection of snapshot/file, original\n\t * document service is returned to loader (instead of debugger service) and normal document load continues.\n\t */\n\tonClose(): void;\n\n\t/**\n\t * UI Layer notifies about selection of version to continue.\n\t * On successful load, versionSelected() is called.\n\t * @param version - Snapshot version to start from.\n\t */\n\tonVersionSelection(version: IVersion): void;\n\n\t/**\n\t * UI Layer notifies about selection of version to continue.\n\t * On successful load, versionSelected() is called.\n\t * @param version - File to load snapshot from\n\t */\n\tonSnapshotFileSelection(file: File): void;\n\n\t/**\n\t * \"next op\" button is clicked in the UI\n\t * @param steps - number of ops to play.\n\t */\n\tonOpButtonClick(steps: number): void;\n\n\t/**\n\t * \"Download ops\" option is clicked in the UI. Returns JSON of the full opStream when available.\n\t * @param anonymize - anonymize the ops json using the sanitization tool\n\t */\n\tonDownloadOpsButtonClick(anonymize: boolean): Promise<string>;\n}\n\nconst debuggerWindowHtml = `<Title>Fluid Debugger</Title>\n<body>\n<h3>Fluid Debugger</h3>\nPlease select snapshot or file to start with<br/>\nClose debugger window to proceed to live document<br/><br/>\n<select style='width:250px' id='selector'>\n</select>\n&nbsp; &nbsp; &nbsp;\n<button id='buttonVers' style='width:60px'>Go</button><br/>\n<input id='file' type='file' value='Load from file'/>\n<br/><br/>\n<h4>Download the current document's ops</h4>\n<input type='checkbox' id='anonymize' value='Anonymize'>\n<label for='anonymize'>Anonymize</label>\n<button type='button' id='downloadOps'>Download ops</button>\n<br/><br/><div id='versionText'></div>\n</body>`;\n\nconst debuggerWindowHtml2 = `<Title>Fluid Debugger</Title>\n<body>\n<h3>Fluid Debugger</h3>\n<div id='versionText'></div>\n<div id='lastOp'></div>\n<br/>\nStep to move: <input type='number' id='steps' value='1' min='1' style='width:50px'/>\n&nbsp; &nbsp; &nbsp;<button id='buttonOps' style='width:60px'>Go</button>\n<br/><br/>\n<div id='text1'></div><div id='text2'></div><div id='text3'></div>\n<br/>\n<h4>Download the current document's ops</h4>\n<input type='checkbox' id='anonymize' value='Anonymize'>\n<label for='anonymize'>Anonymize</label>\n<button type='button' id='downloadOps'>Download ops</button>\n</body>`;\n\n/**\n * @internal\n */\nexport class DebuggerUI {\n\tpublic static create(controller: IDebuggerController): DebuggerUI | null {\n\t\tif (\n\t\t\ttypeof window !== \"object\" ||\n\t\t\twindow === null ||\n\t\t\ttypeof window.document !== \"object\" ||\n\t\t\twindow.document === null\n\t\t) {\n\t\t\tconsole.log(\"Can't create debugger window - not running in browser!\");\n\t\t\treturn null;\n\t\t}\n\n\t\tconst debuggerWindow = window.open(\n\t\t\t\"\",\n\t\t\t\"\",\n\t\t\t\"width=400,height=400,resizable=yes,location=no,menubar=no,titlebar=no,status=no,toolbar=no\",\n\t\t);\n\t\tif (!debuggerWindow) {\n\t\t\tconsole.error(\n\t\t\t\t\"Can't create debugger window - please enable pop-up windows in your browser!\",\n\t\t\t);\n\t\t\treturn null;\n\t\t}\n\n\t\treturn new DebuggerUI(controller, debuggerWindow);\n\t}\n\n\tprivate static formatDate(date: number): string {\n\t\t// Alternative - without timezone\n\t\t// new Date().toLocaleString('default', { timeZone: 'UTC'}));\n\t\t// new Date().toLocaleString('default', { year: 'numeric', month: 'short',\n\t\t// day: 'numeric', hour: '2-digit', minute: 'numeric', second: 'numeric' }));\n\t\treturn new Date(date).toUTCString();\n\t}\n\n\tprotected selector?: HTMLSelectElement;\n\tprotected versionText: HTMLDivElement;\n\n\tprotected buttonOps?: HTMLButtonElement;\n\tprotected text1?: HTMLDivElement;\n\tprotected text2?: HTMLDivElement;\n\tprotected text3?: HTMLDivElement;\n\tprotected lastOpText?: HTMLDivElement;\n\tprotected wasVersionSelected = false;\n\tprotected versions: IVersion[] = [];\n\n\tprotected documentClosed = false;\n\n\tprotected constructor(\n\t\tprivate readonly controller: IDebuggerController,\n\t\tprivate readonly debuggerWindow: Window,\n\t) {\n\t\tconst doc = this.debuggerWindow.document;\n\t\tdoc.write(debuggerWindowHtml);\n\n\t\twindow.addEventListener(\n\t\t\t\"beforeunload\",\n\t\t\t(e) => {\n\t\t\t\tthis.documentClosed = true;\n\t\t\t\tthis.debuggerWindow.close();\n\t\t\t},\n\t\t\tfalse,\n\t\t);\n\n\t\tthis.debuggerWindow.addEventListener(\n\t\t\t\"beforeunload\",\n\t\t\t(e) => {\n\t\t\t\tif (!this.documentClosed) {\n\t\t\t\t\tthis.controller.onClose();\n\t\t\t\t}\n\t\t\t},\n\t\t\tfalse,\n\t\t);\n\n\t\tthis.selector = doc.querySelector(\"#selector\") as HTMLSelectElement;\n\n\t\tconst buttonVers = doc.querySelector(\"#buttonVers\") as HTMLDivElement;\n\t\tbuttonVers.addEventListener(\"click\", () => {\n\t\t\tconst index = this.selector!.selectedIndex;\n\t\t\t// TODO Why are we non null asserting here\n\t\t\tcontroller.onVersionSelection(this.versions[index]!);\n\t\t});\n\n\t\tconst fileSnapshot = doc.querySelector(\"#file\") as HTMLInputElement;\n\t\tfileSnapshot.addEventListener(\n\t\t\t\"change\",\n\t\t\t() => {\n\t\t\t\tconst files = fileSnapshot.files;\n\t\t\t\tif (files) {\n\t\t\t\t\t// TODO Why are we non null asserting here\n\t\t\t\t\tcontroller.onSnapshotFileSelection(files[0]!);\n\t\t\t\t}\n\t\t\t},\n\t\t\tfalse,\n\t\t);\n\n\t\tconst opDownloadButton = doc.querySelector(\"#downloadOps\") as HTMLElement;\n\t\tconst anonymizeCheckbox = doc.querySelector(\"#anonymize\") as HTMLInputElement;\n\t\tthis.attachDownloadOpsListener(opDownloadButton, anonymizeCheckbox);\n\n\t\tthis.versionText = doc.querySelector(\"#versionText\") as HTMLDivElement;\n\t\tthis.versionText.textContent = \"Fetching snapshots, please wait...\";\n\n\t\tcontroller.connectToUi(this);\n\t}\n\n\tprivate attachDownloadOpsListener(element: HTMLElement, anonymize: HTMLInputElement): void {\n\t\telement.addEventListener(\"click\", () => {\n\t\t\tthis.controller\n\t\t\t\t.onDownloadOpsButtonClick(anonymize.checked)\n\t\t\t\t.then((opJson) => {\n\t\t\t\t\tthis.download(\"opStream.json\", opJson);\n\t\t\t\t})\n\t\t\t\t.catch((error) => {\n\t\t\t\t\tconsole.log(`Error downloading ops: ${error}`);\n\t\t\t\t});\n\t\t});\n\t}\n\n\tpublic addVersions(versions: IVersion[]): void {\n\t\tif (this.selector) {\n\t\t\tthis.versions = versions;\n\t\t\tfor (const version of versions) {\n\t\t\t\tconst option = document.createElement(\"option\");\n\t\t\t\toption.text =\n\t\t\t\t\tversion.date === undefined\n\t\t\t\t\t\t? `id = ${version.id}`\n\t\t\t\t\t\t: `id = ${version.id}, time = ${version.date}`;\n\t\t\t\tthis.selector.add(option);\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic updateVersion(index: number, version: IVersion, seqNumber: number): void {\n\t\tif (this.selector) {\n\t\t\tconst option = this.selector[index] as HTMLOptionElement;\n\t\t\toption.text = `${option.text}, seq = ${seqNumber}`;\n\t\t\tthis.selector[index] = option;\n\t\t}\n\t}\n\n\tpublic versionSelected(seqNumber: number, version: IVersion | string): void {\n\t\tconst text =\n\t\t\ttypeof version === \"string\"\n\t\t\t\t? `Playing ${version} file`\n\t\t\t\t: `Playing from ${version.id}, seq# ${seqNumber}`;\n\n\t\tthis.wasVersionSelected = true;\n\t\tthis.selector = undefined;\n\n\t\tconst doc = this.debuggerWindow.document;\n\t\tdoc.open();\n\t\tdoc.write(debuggerWindowHtml2);\n\t\tdoc.close();\n\n\t\tthis.lastOpText = doc.querySelector(\"#lastOp\") as HTMLDivElement;\n\t\tthis.text1 = doc.querySelector(\"#text1\") as HTMLDivElement;\n\t\tthis.text2 = doc.querySelector(\"#text2\") as HTMLDivElement;\n\t\tthis.text3 = doc.querySelector(\"#text3\") as HTMLDivElement;\n\n\t\tconst steps = doc.querySelector(\"#steps\") as HTMLInputElement;\n\t\tthis.buttonOps = doc.querySelector(\"#buttonOps\") as HTMLButtonElement;\n\t\tthis.buttonOps.disabled = true;\n\t\tthis.buttonOps.addEventListener(\"click\", () => {\n\t\t\tthis.controller.onOpButtonClick(Number(steps.value));\n\t\t});\n\n\t\tthis.versionText = doc.querySelector(\"#versionText\") as HTMLDivElement;\n\t\tthis.versionText.textContent = text;\n\n\t\tconst opDownloadButton = doc.querySelector(\"#downloadOps\") as HTMLElement;\n\t\tconst anonymizeCheckbox = doc.querySelector(\"#anonymize\") as HTMLInputElement;\n\t\tthis.attachDownloadOpsListener(opDownloadButton, anonymizeCheckbox);\n\t}\n\n\tpublic disableNextOpButton(disable: boolean): void {\n\t\tassert(!!this.buttonOps, 0x088 /* \"Missing button ops button!\" */);\n\t\tthis.buttonOps.disabled = disable;\n\t}\n\n\tpublic updateNextOpText(ops: ISequencedDocumentMessage[]): void {\n\t\tif (ops.length === 0) {\n\t\t\tthis.text1!.textContent = \"\";\n\t\t\tthis.text2!.textContent = \"\";\n\t\t\tthis.text3!.textContent = \"\";\n\t\t} else {\n\t\t\t// Non null asserting here because of the length check above\n\t\t\tconst op = ops[0]!;\n\t\t\tconst seq = op.sequenceNumber;\n\t\t\tconst date = DebuggerUI.formatDate(op.timestamp);\n\t\t\tthis.text1!.textContent = `Next op seq#: ${seq}`;\n\t\t\tthis.text2!.textContent = `Type: ${op.type}`;\n\t\t\tthis.text3!.textContent = `${date}`;\n\t\t}\n\t}\n\n\tpublic updateVersionText(versionCount: number): void {\n\t\tif (!this.wasVersionSelected) {\n\t\t\tconst text =\n\t\t\t\tversionCount === 0 ? \"\" : `Fetching information about ${versionCount} snapshots...`;\n\t\t\tthis.versionText.textContent = text;\n\t\t}\n\t}\n\n\tpublic updateLastOpText(lastKnownOp: number, stillLoading: boolean): void {\n\t\tconst text = stillLoading\n\t\t\t? `Last op (still loading): ${lastKnownOp}`\n\t\t\t: `Document's last op seq#: ${lastKnownOp}`;\n\t\tthis.lastOpText!.textContent = text;\n\t}\n\n\tprivate download(filename: string, data: string): void {\n\t\tconst element = document.createElement(\"a\");\n\t\telement.setAttribute(\"href\", `data:text/plain;charset=utf-8,${encodeURIComponent(data)}`);\n\t\telement.setAttribute(\"download\", filename);\n\n\t\telement.style.display = \"none\";\n\t\tdocument.body.append(element);\n\n\t\telement.click();\n\n\t\telement.remove();\n\t}\n}\n"]}
1
+ {"version":3,"file":"fluidDebuggerUi.js","sourceRoot":"","sources":["../src/fluidDebuggerUi.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert } from \"@fluidframework/core-utils/internal\";\nimport type {\n\tIVersion,\n\tISequencedDocumentMessage,\n} from \"@fluidframework/driver-definitions/internal\";\n\n/**\n * @internal\n */\nexport interface IDebuggerUI {\n\t/**\n\t * Version information is provided.\n\t * Expect updates (information about seq#, timestamp) through updateVersion() calls\n\t */\n\taddVersions(version: IVersion[]): void;\n\n\t/**\n\t * Call when new version is downloaded from storage\n\t * Expect multiple callbacks.\n\t */\n\tupdateVersion(index: number, version: IVersion, seqNumber: number): void;\n\n\t/**\n\t * Called in response to successful onVersionSelection() or onSnapshotFileSelection() call\n\t * and provides extra information about selection.\n\t * It expected that UI layer would change its mode as result of this call, i.e. switch to\n\t * displaying op playback controls (if this is supported)\n\t * Note: There maybe no call to versionSelected() in response to onSnapshotFileSelection() call\n\t * if file does not exist, has wrong name of wrong format.\n\t * @param version - version, file name, or undefined if playing ops.\n\t */\n\tversionSelected(seqNumber: number, version: IVersion | string): void;\n\n\t/**\n\t * Called by controller in response to new ops being downloaded\n\t * Called with disable = true if there are no (currently) ops to play\n\t */\n\tdisableNextOpButton(disable: boolean): void;\n\n\t/**\n\t * Called by controller when new ops arrive (or we are done playing previous batch)\n\t * Indicates next batch of ops that would be played when UI calls controller's onOpButtonClick()\n\t * Called with ops=[] when there are no ops to play.\n\t */\n\tupdateNextOpText(ops: ISequencedDocumentMessage[]): void;\n\n\t/**\n\t * Called periodically when new versions are downloaded from server\n\t */\n\tupdateVersionText(versionsLeft: number): void;\n\n\t/**\n\t * Called periodically to notify about last known op\n\t * @param lastKnownOp - seq number of last known op. -1 if can't play ops in this mode (load from file)\n\t * @param stillLoading - true if we did not reach yet the end of the stream\n\t */\n\tupdateLastOpText(lastKnownOp: number, stillLoading: boolean): void;\n}\n\n/**\n * @internal\n */\nexport interface IDebuggerController {\n\t/**\n\t * Initialization. UI layers calls into controller to connect the two.\n\t * @param ui - UI layer\n\t */\n\tconnectToUi(ui: IDebuggerUI);\n\n\t/**\n\t * Called by UI layer when debugger window is closed by user\n\t * If called before user makes selection of snapshot/file, original\n\t * document service is returned to loader (instead of debugger service) and normal document load continues.\n\t */\n\tonClose(): void;\n\n\t/**\n\t * UI Layer notifies about selection of version to continue.\n\t * On successful load, versionSelected() is called.\n\t * @param version - Snapshot version to start from.\n\t */\n\tonVersionSelection(version: IVersion): void;\n\n\t/**\n\t * UI Layer notifies about selection of version to continue.\n\t * On successful load, versionSelected() is called.\n\t * @param version - File to load snapshot from\n\t */\n\tonSnapshotFileSelection(file: File): void;\n\n\t/**\n\t * \"next op\" button is clicked in the UI\n\t * @param steps - number of ops to play.\n\t */\n\tonOpButtonClick(steps: number): void;\n\n\t/**\n\t * \"Download ops\" option is clicked in the UI. Returns JSON of the full opStream when available.\n\t * @param anonymize - anonymize the ops json using the sanitization tool\n\t */\n\tonDownloadOpsButtonClick(anonymize: boolean): Promise<string>;\n}\n\nconst debuggerWindowHtml = `<Title>Fluid Debugger</Title>\n<body>\n<h3>Fluid Debugger</h3>\nPlease select snapshot or file to start with<br/>\nClose debugger window to proceed to live document<br/><br/>\n<select style='width:250px' id='selector'>\n</select>\n&nbsp; &nbsp; &nbsp;\n<button id='buttonVers' style='width:60px'>Go</button><br/>\n<input id='file' type='file' value='Load from file'/>\n<br/><br/>\n<h4>Download the current document's ops</h4>\n<input type='checkbox' id='anonymize' value='Anonymize'>\n<label for='anonymize'>Anonymize</label>\n<button type='button' id='downloadOps'>Download ops</button>\n<br/><br/><div id='versionText'></div>\n</body>`;\n\nconst debuggerWindowHtml2 = `<Title>Fluid Debugger</Title>\n<body>\n<h3>Fluid Debugger</h3>\n<div id='versionText'></div>\n<div id='lastOp'></div>\n<br/>\nStep to move: <input type='number' id='steps' value='1' min='1' style='width:50px'/>\n&nbsp; &nbsp; &nbsp;<button id='buttonOps' style='width:60px'>Go</button>\n<br/><br/>\n<div id='text1'></div><div id='text2'></div><div id='text3'></div>\n<br/>\n<h4>Download the current document's ops</h4>\n<input type='checkbox' id='anonymize' value='Anonymize'>\n<label for='anonymize'>Anonymize</label>\n<button type='button' id='downloadOps'>Download ops</button>\n</body>`;\n\n/**\n * @internal\n */\nexport class DebuggerUI {\n\tpublic static create(controller: IDebuggerController): DebuggerUI | null {\n\t\tif (\n\t\t\ttypeof window !== \"object\" ||\n\t\t\twindow === null ||\n\t\t\ttypeof window.document !== \"object\" ||\n\t\t\twindow.document === null\n\t\t) {\n\t\t\tconsole.log(\"Can't create debugger window - not running in browser!\");\n\t\t\treturn null;\n\t\t}\n\n\t\tconst debuggerWindow = window.open(\n\t\t\t\"\",\n\t\t\t\"\",\n\t\t\t\"width=400,height=400,resizable=yes,location=no,menubar=no,titlebar=no,status=no,toolbar=no\",\n\t\t);\n\t\tif (!debuggerWindow) {\n\t\t\tconsole.error(\n\t\t\t\t\"Can't create debugger window - please enable pop-up windows in your browser!\",\n\t\t\t);\n\t\t\treturn null;\n\t\t}\n\n\t\treturn new DebuggerUI(controller, debuggerWindow);\n\t}\n\n\tprivate static formatDate(date: number): string {\n\t\t// Alternative - without timezone\n\t\t// new Date().toLocaleString('default', { timeZone: 'UTC'}));\n\t\t// new Date().toLocaleString('default', { year: 'numeric', month: 'short',\n\t\t// day: 'numeric', hour: '2-digit', minute: 'numeric', second: 'numeric' }));\n\t\treturn new Date(date).toUTCString();\n\t}\n\n\tprotected selector?: HTMLSelectElement;\n\tprotected versionText: HTMLDivElement;\n\n\tprotected buttonOps?: HTMLButtonElement;\n\tprotected text1?: HTMLDivElement;\n\tprotected text2?: HTMLDivElement;\n\tprotected text3?: HTMLDivElement;\n\tprotected lastOpText?: HTMLDivElement;\n\tprotected wasVersionSelected = false;\n\tprotected versions: IVersion[] = [];\n\n\tprotected documentClosed = false;\n\n\tprotected constructor(\n\t\tprivate readonly controller: IDebuggerController,\n\t\tprivate readonly debuggerWindow: Window,\n\t) {\n\t\tconst doc = this.debuggerWindow.document;\n\t\tdoc.write(debuggerWindowHtml);\n\n\t\twindow.addEventListener(\n\t\t\t\"beforeunload\",\n\t\t\t(e) => {\n\t\t\t\tthis.documentClosed = true;\n\t\t\t\tthis.debuggerWindow.close();\n\t\t\t},\n\t\t\tfalse,\n\t\t);\n\n\t\tthis.debuggerWindow.addEventListener(\n\t\t\t\"beforeunload\",\n\t\t\t(e) => {\n\t\t\t\tif (!this.documentClosed) {\n\t\t\t\t\tthis.controller.onClose();\n\t\t\t\t}\n\t\t\t},\n\t\t\tfalse,\n\t\t);\n\n\t\tthis.selector = doc.querySelector(\"#selector\") as HTMLSelectElement;\n\n\t\tconst buttonVers = doc.querySelector(\"#buttonVers\") as HTMLDivElement;\n\t\tbuttonVers.addEventListener(\"click\", () => {\n\t\t\tconst index = this.selector!.selectedIndex;\n\t\t\t// TODO Why are we non null asserting here\n\t\t\tcontroller.onVersionSelection(this.versions[index]!);\n\t\t});\n\n\t\tconst fileSnapshot = doc.querySelector(\"#file\") as HTMLInputElement;\n\t\tfileSnapshot.addEventListener(\n\t\t\t\"change\",\n\t\t\t() => {\n\t\t\t\tconst files = fileSnapshot.files;\n\t\t\t\tif (files) {\n\t\t\t\t\t// TODO Why are we non null asserting here\n\t\t\t\t\tcontroller.onSnapshotFileSelection(files[0]!);\n\t\t\t\t}\n\t\t\t},\n\t\t\tfalse,\n\t\t);\n\n\t\tconst opDownloadButton = doc.querySelector(\"#downloadOps\") as HTMLElement;\n\t\tconst anonymizeCheckbox = doc.querySelector(\"#anonymize\") as HTMLInputElement;\n\t\tthis.attachDownloadOpsListener(opDownloadButton, anonymizeCheckbox);\n\n\t\tthis.versionText = doc.querySelector(\"#versionText\") as HTMLDivElement;\n\t\tthis.versionText.textContent = \"Fetching snapshots, please wait...\";\n\n\t\tcontroller.connectToUi(this);\n\t}\n\n\tprivate attachDownloadOpsListener(element: HTMLElement, anonymize: HTMLInputElement): void {\n\t\telement.addEventListener(\"click\", () => {\n\t\t\tthis.controller\n\t\t\t\t.onDownloadOpsButtonClick(anonymize.checked)\n\t\t\t\t.then((opJson) => {\n\t\t\t\t\tthis.download(\"opStream.json\", opJson);\n\t\t\t\t})\n\t\t\t\t.catch((error) => {\n\t\t\t\t\tconsole.log(`Error downloading ops: ${error}`);\n\t\t\t\t});\n\t\t});\n\t}\n\n\tpublic addVersions(versions: IVersion[]): void {\n\t\tif (this.selector) {\n\t\t\tthis.versions = versions;\n\t\t\tfor (const version of versions) {\n\t\t\t\tconst option = document.createElement(\"option\");\n\t\t\t\toption.text =\n\t\t\t\t\tversion.date === undefined\n\t\t\t\t\t\t? `id = ${version.id}`\n\t\t\t\t\t\t: `id = ${version.id}, time = ${version.date}`;\n\t\t\t\tthis.selector.add(option);\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic updateVersion(index: number, version: IVersion, seqNumber: number): void {\n\t\tif (this.selector) {\n\t\t\tconst option = this.selector[index] as HTMLOptionElement;\n\t\t\toption.text = `${option.text}, seq = ${seqNumber}`;\n\t\t\tthis.selector[index] = option;\n\t\t}\n\t}\n\n\tpublic versionSelected(seqNumber: number, version: IVersion | string): void {\n\t\tconst text =\n\t\t\ttypeof version === \"string\"\n\t\t\t\t? `Playing ${version} file`\n\t\t\t\t: `Playing from ${version.id}, seq# ${seqNumber}`;\n\n\t\tthis.wasVersionSelected = true;\n\t\tdelete this.selector;\n\n\t\tconst doc = this.debuggerWindow.document;\n\t\tdoc.open();\n\t\tdoc.write(debuggerWindowHtml2);\n\t\tdoc.close();\n\n\t\tthis.lastOpText = doc.querySelector(\"#lastOp\") as HTMLDivElement;\n\t\tthis.text1 = doc.querySelector(\"#text1\") as HTMLDivElement;\n\t\tthis.text2 = doc.querySelector(\"#text2\") as HTMLDivElement;\n\t\tthis.text3 = doc.querySelector(\"#text3\") as HTMLDivElement;\n\n\t\tconst steps = doc.querySelector(\"#steps\") as HTMLInputElement;\n\t\tthis.buttonOps = doc.querySelector(\"#buttonOps\") as HTMLButtonElement;\n\t\tthis.buttonOps.disabled = true;\n\t\tthis.buttonOps.addEventListener(\"click\", () => {\n\t\t\tthis.controller.onOpButtonClick(Number(steps.value));\n\t\t});\n\n\t\tthis.versionText = doc.querySelector(\"#versionText\") as HTMLDivElement;\n\t\tthis.versionText.textContent = text;\n\n\t\tconst opDownloadButton = doc.querySelector(\"#downloadOps\") as HTMLElement;\n\t\tconst anonymizeCheckbox = doc.querySelector(\"#anonymize\") as HTMLInputElement;\n\t\tthis.attachDownloadOpsListener(opDownloadButton, anonymizeCheckbox);\n\t}\n\n\tpublic disableNextOpButton(disable: boolean): void {\n\t\tassert(!!this.buttonOps, 0x088 /* \"Missing button ops button!\" */);\n\t\tthis.buttonOps.disabled = disable;\n\t}\n\n\tpublic updateNextOpText(ops: ISequencedDocumentMessage[]): void {\n\t\tif (ops.length === 0) {\n\t\t\tthis.text1!.textContent = \"\";\n\t\t\tthis.text2!.textContent = \"\";\n\t\t\tthis.text3!.textContent = \"\";\n\t\t} else {\n\t\t\t// Non null asserting here because of the length check above\n\t\t\tconst op = ops[0]!;\n\t\t\tconst seq = op.sequenceNumber;\n\t\t\tconst date = DebuggerUI.formatDate(op.timestamp);\n\t\t\tthis.text1!.textContent = `Next op seq#: ${seq}`;\n\t\t\tthis.text2!.textContent = `Type: ${op.type}`;\n\t\t\tthis.text3!.textContent = `${date}`;\n\t\t}\n\t}\n\n\tpublic updateVersionText(versionCount: number): void {\n\t\tif (!this.wasVersionSelected) {\n\t\t\tconst text =\n\t\t\t\tversionCount === 0 ? \"\" : `Fetching information about ${versionCount} snapshots...`;\n\t\t\tthis.versionText.textContent = text;\n\t\t}\n\t}\n\n\tpublic updateLastOpText(lastKnownOp: number, stillLoading: boolean): void {\n\t\tconst text = stillLoading\n\t\t\t? `Last op (still loading): ${lastKnownOp}`\n\t\t\t: `Document's last op seq#: ${lastKnownOp}`;\n\t\tthis.lastOpText!.textContent = text;\n\t}\n\n\tprivate download(filename: string, data: string): void {\n\t\tconst element = document.createElement(\"a\");\n\t\telement.setAttribute(\"href\", `data:text/plain;charset=utf-8,${encodeURIComponent(data)}`);\n\t\telement.setAttribute(\"download\", filename);\n\n\t\telement.style.display = \"none\";\n\t\tdocument.body.append(element);\n\n\t\telement.click();\n\n\t\telement.remove();\n\t}\n}\n"]}
@@ -129,7 +129,7 @@ export declare const attachContentsSchema: {
129
129
  id: {
130
130
  type: string;
131
131
  };
132
- entries?: undefined;
132
+ entries?: never;
133
133
  };
134
134
  required: string[];
135
135
  additionalProperties: boolean;
@@ -144,8 +144,8 @@ export declare const attachContentsSchema: {
144
144
  id: {
145
145
  type: string;
146
146
  };
147
- contents?: undefined;
148
- encoding?: undefined;
147
+ contents?: never;
148
+ encoding?: never;
149
149
  };
150
150
  required: string[];
151
151
  additionalProperties: boolean;
@@ -250,7 +250,7 @@ export declare const opContentsSchema: {
250
250
  id: {
251
251
  type: string;
252
252
  };
253
- entries?: undefined;
253
+ entries?: never;
254
254
  };
255
255
  required: string[];
256
256
  additionalProperties: boolean;
@@ -265,8 +265,8 @@ export declare const opContentsSchema: {
265
265
  id: {
266
266
  type: string;
267
267
  };
268
- contents?: undefined;
269
- encoding?: undefined;
268
+ contents?: never;
269
+ encoding?: never;
270
270
  };
271
271
  required: string[];
272
272
  additionalProperties: boolean;
@@ -303,7 +303,7 @@ export declare const opContentsSchema: {
303
303
  id: {
304
304
  type: string;
305
305
  };
306
- entries?: undefined;
306
+ entries?: never;
307
307
  };
308
308
  required: string[];
309
309
  additionalProperties: boolean;
@@ -318,8 +318,8 @@ export declare const opContentsSchema: {
318
318
  id: {
319
319
  type: string;
320
320
  };
321
- contents?: undefined;
322
- encoding?: undefined;
321
+ contents?: never;
322
+ encoding?: never;
323
323
  };
324
324
  required: string[];
325
325
  additionalProperties: boolean;
@@ -387,12 +387,12 @@ export declare const opContentsSchema: {
387
387
  };
388
388
  required: string[];
389
389
  additionalProperties: boolean;
390
- $ref?: undefined;
390
+ $ref?: never;
391
391
  } | {
392
392
  $ref: string;
393
- properties?: undefined;
394
- required?: undefined;
395
- additionalProperties?: undefined;
393
+ properties?: never;
394
+ required?: never;
395
+ additionalProperties?: never;
396
396
  })[];
397
397
  };
398
398
  export declare const opContentsAttachSchema: {
@@ -422,7 +422,7 @@ export declare const opContentsAttachSchema: {
422
422
  id: {
423
423
  type: string;
424
424
  };
425
- entries?: undefined;
425
+ entries?: never;
426
426
  };
427
427
  required: string[];
428
428
  additionalProperties: boolean;
@@ -437,8 +437,8 @@ export declare const opContentsAttachSchema: {
437
437
  id: {
438
438
  type: string;
439
439
  };
440
- contents?: undefined;
441
- encoding?: undefined;
440
+ contents?: never;
441
+ encoding?: never;
442
442
  };
443
443
  required: string[];
444
444
  additionalProperties: boolean;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fluidframework/debugger",
3
- "version": "2.103.0",
3
+ "version": "2.110.0",
4
4
  "description": "Fluid Debugger - a tool to play through history of a file",
5
5
  "homepage": "https://fluidframework.com",
6
6
  "repository": {
@@ -47,10 +47,10 @@
47
47
  "main": "lib/index.js",
48
48
  "types": "lib/public.d.ts",
49
49
  "dependencies": {
50
- "@fluidframework/core-utils": "~2.103.0",
51
- "@fluidframework/driver-definitions": "~2.103.0",
52
- "@fluidframework/driver-utils": "~2.103.0",
53
- "@fluidframework/replay-driver": "~2.103.0",
50
+ "@fluidframework/core-utils": "~2.110.0",
51
+ "@fluidframework/driver-definitions": "~2.110.0",
52
+ "@fluidframework/driver-utils": "~2.110.0",
53
+ "@fluidframework/replay-driver": "~2.110.0",
54
54
  "jsonschema": "^1.2.6"
55
55
  },
56
56
  "devDependencies": {
@@ -59,8 +59,8 @@
59
59
  "@fluid-tools/build-cli": "^0.65.0",
60
60
  "@fluidframework/build-common": "^2.0.3",
61
61
  "@fluidframework/build-tools": "^0.65.0",
62
- "@fluidframework/debugger-previous": "npm:@fluidframework/debugger@2.101.0",
63
- "@fluidframework/eslint-config-fluid": "^9.0.0",
62
+ "@fluidframework/debugger-previous": "npm:@fluidframework/debugger@2.103.0",
63
+ "@fluidframework/eslint-config-fluid": "^13.0.0",
64
64
  "@microsoft/api-extractor": "7.58.1",
65
65
  "@types/node": "~22.19.17",
66
66
  "concurrently": "^9.2.1",
@@ -337,7 +337,7 @@ export class DebugReplayController extends ReplayController implements IDebugger
337
337
 
338
338
  this.stepsToPlay = await this.stepsDeferred.promise;
339
339
 
340
- this.stepsDeferred = undefined;
340
+ delete this.stepsDeferred;
341
341
  this.ui.disableNextOpButton(true);
342
342
  }
343
343
 
@@ -292,7 +292,7 @@ export class DebuggerUI {
292
292
  : `Playing from ${version.id}, seq# ${seqNumber}`;
293
293
 
294
294
  this.wasVersionSelected = true;
295
- this.selector = undefined;
295
+ delete this.selector;
296
296
 
297
297
  const doc = this.debuggerWindow.document;
298
298
  doc.open();
package/tsconfig.json CHANGED
@@ -7,6 +7,5 @@
7
7
  "outDir": "./lib",
8
8
  "lib": ["ES2017", "ES2018.Promise", "ES2018.AsyncIterable", "DOM", "DOM.Iterable"],
9
9
  "types": ["node"],
10
- "exactOptionalPropertyTypes": false,
11
10
  },
12
11
  }