@fluidframework/debugger 2.0.0-dev.5.3.2.178189 → 2.0.0-dev.6.4.0.191258
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 +24 -0
- package/dist/fluidDebuggerController.d.ts +1 -1
- package/dist/fluidDebuggerController.d.ts.map +1 -1
- package/dist/fluidDebuggerController.js +20 -52
- package/dist/fluidDebuggerController.js.map +1 -1
- package/dist/fluidDebuggerUi.js +2 -2
- package/dist/fluidDebuggerUi.js.map +1 -1
- package/dist/sanitizer.js +9 -10
- package/dist/sanitizer.js.map +1 -1
- package/lib/fluidDebuggerController.d.ts +1 -1
- package/lib/fluidDebuggerController.d.ts.map +1 -1
- package/lib/fluidDebuggerController.js +11 -43
- package/lib/fluidDebuggerController.js.map +1 -1
- package/lib/fluidDebuggerUi.js +1 -1
- package/lib/fluidDebuggerUi.js.map +1 -1
- package/lib/sanitizer.js +4 -5
- package/lib/sanitizer.js.map +1 -1
- package/package.json +12 -15
- package/src/fluidDebuggerController.ts +1 -1
- package/src/fluidDebuggerUi.ts +1 -1
- package/src/sanitizer.ts +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,29 @@
|
|
|
1
1
|
# @fluidframework/debugger
|
|
2
2
|
|
|
3
|
+
## 2.0.0-internal.6.3.0
|
|
4
|
+
|
|
5
|
+
Dependency updates only.
|
|
6
|
+
|
|
7
|
+
## 2.0.0-internal.6.2.0
|
|
8
|
+
|
|
9
|
+
Dependency updates only.
|
|
10
|
+
|
|
11
|
+
## 2.0.0-internal.6.1.0
|
|
12
|
+
|
|
13
|
+
Dependency updates only.
|
|
14
|
+
|
|
15
|
+
## 2.0.0-internal.6.0.0
|
|
16
|
+
|
|
17
|
+
### Major Changes
|
|
18
|
+
|
|
19
|
+
- Upgraded typescript transpilation target to ES2020 [8abce8cdb4](https://github.com/microsoft/FluidFramework/commits/8abce8cdb4e2832fb6405fb44e393bef03d5648a)
|
|
20
|
+
|
|
21
|
+
Upgraded typescript transpilation target to ES2020. This is done in order to decrease the bundle sizes of Fluid Framework packages. This has provided size improvements across the board for ex. Loader, Driver, Runtime etc. Reduced bundle sizes helps to load lesser code in apps and hence also helps to improve the perf.If any app wants to target any older versions of browsers with which this target version is not compatible, then they can use packages like babel to transpile to a older target.
|
|
22
|
+
|
|
23
|
+
## 2.0.0-internal.5.4.0
|
|
24
|
+
|
|
25
|
+
Dependency updates only.
|
|
26
|
+
|
|
3
27
|
## 2.0.0-internal.5.3.0
|
|
4
28
|
|
|
5
29
|
Dependency updates only.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
|
-
import { Deferred } from "@fluidframework/
|
|
5
|
+
import { Deferred } from "@fluidframework/core-utils";
|
|
6
6
|
import { IDocumentService, IDocumentStorageService } from "@fluidframework/driver-definitions";
|
|
7
7
|
import { ISequencedDocumentMessage, ISnapshotTree, IVersion } from "@fluidframework/protocol-definitions";
|
|
8
8
|
import { ReadDocumentStorageServiceBase, ReplayController } from "@fluidframework/replay-driver";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fluidDebuggerController.d.ts","sourceRoot":"","sources":["../src/fluidDebuggerController.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAU,QAAQ,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"fluidDebuggerController.d.ts","sourceRoot":"","sources":["../src/fluidDebuggerController.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,28 +3,9 @@
|
|
|
3
3
|
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
4
4
|
* Licensed under the MIT License.
|
|
5
5
|
*/
|
|
6
|
-
var __asyncValues = (this && this.__asyncValues) || function (o) {
|
|
7
|
-
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
|
|
8
|
-
var m = o[Symbol.asyncIterator], i;
|
|
9
|
-
return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
|
|
10
|
-
function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
|
|
11
|
-
function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
|
|
12
|
-
};
|
|
13
|
-
var __await = (this && this.__await) || function (v) { return this instanceof __await ? (this.v = v, this) : new __await(v); }
|
|
14
|
-
var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) {
|
|
15
|
-
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
|
|
16
|
-
var g = generator.apply(thisArg, _arguments || []), i, q = [];
|
|
17
|
-
return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i;
|
|
18
|
-
function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }
|
|
19
|
-
function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }
|
|
20
|
-
function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }
|
|
21
|
-
function fulfill(value) { resume("next", value); }
|
|
22
|
-
function reject(value) { resume("throw", value); }
|
|
23
|
-
function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }
|
|
24
|
-
};
|
|
25
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
7
|
exports.DebugReplayController = void 0;
|
|
27
|
-
const
|
|
8
|
+
const core_utils_1 = require("@fluidframework/core-utils");
|
|
28
9
|
const driver_utils_1 = require("@fluidframework/driver-utils");
|
|
29
10
|
const replay_driver_1 = require("@fluidframework/replay-driver");
|
|
30
11
|
const sanitizer_1 = require("./sanitizer");
|
|
@@ -35,7 +16,7 @@ class DebugReplayController extends replay_driver_1.ReplayController {
|
|
|
35
16
|
constructor() {
|
|
36
17
|
super(...arguments);
|
|
37
18
|
this.ui = null; // Not to check on every line that it's not null
|
|
38
|
-
this.startSeqDeferred = new
|
|
19
|
+
this.startSeqDeferred = new core_utils_1.Deferred();
|
|
39
20
|
// True will cause us ping server indefinitely waiting for new ops
|
|
40
21
|
this.retryFetchOpsOnEndOfFile = false;
|
|
41
22
|
this.versions = [];
|
|
@@ -133,21 +114,10 @@ class DebugReplayController extends replay_driver_1.ReplayController {
|
|
|
133
114
|
return JSON.stringify(messages, undefined, 2);
|
|
134
115
|
}
|
|
135
116
|
async fetchOpsFromDeltaStorage(documentDeltaStorageService) {
|
|
136
|
-
var e_1, _a;
|
|
137
117
|
const deltaGenerator = generateSequencedMessagesFromDeltaStorage(documentDeltaStorageService);
|
|
138
118
|
let messages = [];
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
const message = deltaGenerator_1_1.value;
|
|
142
|
-
messages = messages.concat(message);
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
146
|
-
finally {
|
|
147
|
-
try {
|
|
148
|
-
if (deltaGenerator_1_1 && !deltaGenerator_1_1.done && (_a = deltaGenerator_1.return)) await _a.call(deltaGenerator_1);
|
|
149
|
-
}
|
|
150
|
-
finally { if (e_1) throw e_1.error; }
|
|
119
|
+
for await (const message of deltaGenerator) {
|
|
120
|
+
messages = messages.concat(message);
|
|
151
121
|
}
|
|
152
122
|
return messages;
|
|
153
123
|
}
|
|
@@ -175,9 +145,9 @@ class DebugReplayController extends replay_driver_1.ReplayController {
|
|
|
175
145
|
if (this.shouldUseController !== undefined) {
|
|
176
146
|
return this.shouldUseController;
|
|
177
147
|
}
|
|
178
|
-
(0,
|
|
179
|
-
(0,
|
|
180
|
-
(0,
|
|
148
|
+
(0, core_utils_1.assert)(!!documentService, 0x080 /* "Invalid document service!" */);
|
|
149
|
+
(0, core_utils_1.assert)(!this.documentService, 0x081 /* "Document service already set!" */);
|
|
150
|
+
(0, core_utils_1.assert)(!this.documentStorageService, 0x082 /* "Document storage service already set!" */);
|
|
181
151
|
this.documentService = documentService;
|
|
182
152
|
this.documentStorageService = await documentService.connectToStorage();
|
|
183
153
|
// User can chose "file" at any moment in time!
|
|
@@ -208,7 +178,7 @@ class DebugReplayController extends replay_driver_1.ReplayController {
|
|
|
208
178
|
// This hangs until the user makes a selection or closes the window.
|
|
209
179
|
this.shouldUseController =
|
|
210
180
|
(await this.startSeqDeferred.promise) !== DebugReplayController.WindowClosedSeq;
|
|
211
|
-
(0,
|
|
181
|
+
(0, core_utils_1.assert)(this.isSelectionMade() === this.shouldUseController, 0x083 /* "User selection status does not match replay controller use status!" */);
|
|
212
182
|
return this.shouldUseController;
|
|
213
183
|
}
|
|
214
184
|
async readBlob(blobId) {
|
|
@@ -260,7 +230,7 @@ class DebugReplayController extends replay_driver_1.ReplayController {
|
|
|
260
230
|
}
|
|
261
231
|
if (this.stepsToPlay === 0) {
|
|
262
232
|
this.ui.disableNextOpButton(false);
|
|
263
|
-
this.stepsDeferred = new
|
|
233
|
+
this.stepsDeferred = new core_utils_1.Deferred();
|
|
264
234
|
this.ui.updateNextOpText(_fetchedOps);
|
|
265
235
|
this.stepsToPlay = await this.stepsDeferred.promise;
|
|
266
236
|
this.stepsDeferred = undefined;
|
|
@@ -280,26 +250,24 @@ class DebugReplayController extends replay_driver_1.ReplayController {
|
|
|
280
250
|
}
|
|
281
251
|
}
|
|
282
252
|
resolveStorage(seq, storage, version) {
|
|
283
|
-
(0,
|
|
284
|
-
(0,
|
|
253
|
+
(0, core_utils_1.assert)(!this.isSelectionMade(), 0x084 /* "On storage resolve, user selection already made!" */);
|
|
254
|
+
(0, core_utils_1.assert)(!!storage, 0x085 /* "On storage resolve, missing storage!" */);
|
|
285
255
|
this.storage = storage;
|
|
286
|
-
(0,
|
|
256
|
+
(0, core_utils_1.assert)(this.isSelectionMade(), 0x086 /* "After storage resolve, user selection status still false!" */);
|
|
287
257
|
this.ui.versionSelected(seq, version);
|
|
288
258
|
this.startSeqDeferred.resolve(seq);
|
|
289
259
|
}
|
|
290
260
|
}
|
|
291
261
|
exports.DebugReplayController = DebugReplayController;
|
|
292
262
|
DebugReplayController.WindowClosedSeq = -1; // Seq# to indicate that user closed window
|
|
293
|
-
function generateSequencedMessagesFromDeltaStorage(deltaStorage) {
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
return yield __await(void 0);
|
|
300
|
-
}
|
|
301
|
-
yield yield __await(result.value);
|
|
263
|
+
async function* generateSequencedMessagesFromDeltaStorage(deltaStorage) {
|
|
264
|
+
const stream = deltaStorage.fetchMessages(1, undefined);
|
|
265
|
+
while (true) {
|
|
266
|
+
const result = await stream.read();
|
|
267
|
+
if (result.done) {
|
|
268
|
+
return;
|
|
302
269
|
}
|
|
303
|
-
|
|
270
|
+
yield result.value;
|
|
271
|
+
}
|
|
304
272
|
}
|
|
305
273
|
//# sourceMappingURL=fluidDebuggerController.js.map
|
|
@@ -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/common-utils\";\nimport {\n\tIDocumentService,\n\tIDocumentStorageService,\n\tIDocumentDeltaStorageService,\n} from \"@fluidframework/driver-definitions\";\nimport { readAndParse } from \"@fluidframework/driver-utils\";\nimport {\n\tIDocumentAttributes,\n\tISequencedDocumentMessage,\n\tISnapshotTree,\n\tIVersion,\n} from \"@fluidframework/protocol-definitions\";\nimport {\n\tFileSnapshotReader,\n\tIFileSnapshot,\n\tReadDocumentStorageServiceBase,\n\tReplayController,\n\tSnapshotStorage,\n} from \"@fluidframework/replay-driver\";\nimport { IDebuggerController, IDebuggerUI } from \"./fluidDebuggerUi\";\nimport { Sanitizer } from \"./sanitizer\";\n\nexport type debuggerUIFactory = (controller: IDebuggerController) => IDebuggerUI | null;\n\n/**\n * Replay controller that uses pop-up window to control op playback\n */\nexport class DebugReplayController extends ReplayController implements IDebuggerController {\n\tpublic static create(createUi: debuggerUIFactory): DebugReplayController | null {\n\t\tif (\n\t\t\ttypeof localStorage === \"object\" &&\n\t\t\tlocalStorage !== null &&\n\t\t\tlocalStorage.FluidDebugger\n\t\t) {\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\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() {\n\t\tthis.startSeqDeferred.resolve(DebugReplayController.WindowClosedSeq);\n\t}\n\n\tpublic async onVersionSelection(version: IVersion) {\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) {\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) {\n\t\tif (!/^snapshot.*\\.json/.exec(file.name)) {\n\t\t\talert(`Incorrect file name: ${file.name}`);\n\t\t\treturn;\n\t\t}\n\t\tif (/.*_expanded.*/.exec(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.onload = async () => {\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() {\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\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\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\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() {\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\t// eslint-disable-next-line no-constant-condition\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) {\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) {\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\";\nimport {\n\tIDocumentService,\n\tIDocumentStorageService,\n\tIDocumentDeltaStorageService,\n} from \"@fluidframework/driver-definitions\";\nimport { readAndParse } from \"@fluidframework/driver-utils\";\nimport {\n\tIDocumentAttributes,\n\tISequencedDocumentMessage,\n\tISnapshotTree,\n\tIVersion,\n} from \"@fluidframework/protocol-definitions\";\nimport {\n\tFileSnapshotReader,\n\tIFileSnapshot,\n\tReadDocumentStorageServiceBase,\n\tReplayController,\n\tSnapshotStorage,\n} from \"@fluidframework/replay-driver\";\nimport { IDebuggerController, IDebuggerUI } from \"./fluidDebuggerUi\";\nimport { Sanitizer } from \"./sanitizer\";\n\nexport type debuggerUIFactory = (controller: IDebuggerController) => IDebuggerUI | null;\n\n/**\n * Replay controller that uses pop-up window to control op playback\n */\nexport class DebugReplayController extends ReplayController implements IDebuggerController {\n\tpublic static create(createUi: debuggerUIFactory): DebugReplayController | null {\n\t\tif (\n\t\t\ttypeof localStorage === \"object\" &&\n\t\t\tlocalStorage !== null &&\n\t\t\tlocalStorage.FluidDebugger\n\t\t) {\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\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() {\n\t\tthis.startSeqDeferred.resolve(DebugReplayController.WindowClosedSeq);\n\t}\n\n\tpublic async onVersionSelection(version: IVersion) {\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) {\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) {\n\t\tif (!/^snapshot.*\\.json/.exec(file.name)) {\n\t\t\talert(`Incorrect file name: ${file.name}`);\n\t\t\treturn;\n\t\t}\n\t\tif (/.*_expanded.*/.exec(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.onload = async () => {\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() {\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\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\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\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() {\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\t// eslint-disable-next-line no-constant-condition\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) {\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) {\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"]}
|
package/dist/fluidDebuggerUi.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
7
|
exports.DebuggerUI = void 0;
|
|
8
|
-
const
|
|
8
|
+
const core_utils_1 = require("@fluidframework/core-utils");
|
|
9
9
|
const debuggerWindowHtml = `<Title>Fluid Debugger</Title>
|
|
10
10
|
<body>
|
|
11
11
|
<h3>Fluid Debugger</h3>
|
|
@@ -158,7 +158,7 @@ class DebuggerUI {
|
|
|
158
158
|
this.attachDownloadOpsListener(opDownloadButton, anonymizeCheckbox);
|
|
159
159
|
}
|
|
160
160
|
disableNextOpButton(disable) {
|
|
161
|
-
(0,
|
|
161
|
+
(0, core_utils_1.assert)(!!this.buttonOps, 0x088 /* "Missing button ops button!" */);
|
|
162
162
|
this.buttonOps.disabled = disable;
|
|
163
163
|
}
|
|
164
164
|
updateNextOpText(ops) {
|
|
@@ -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/common-utils\";\nimport { ISequencedDocumentMessage, IVersion } from \"@fluidframework/protocol-definitions\";\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\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 \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 <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\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) {\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.getElementById(\"selector\") as HTMLSelectElement;\n\n\t\tconst buttonVers = doc.getElementById(\"buttonVers\") as HTMLDivElement;\n\t\tbuttonVers.onclick = () => {\n\t\t\tconst index = this.selector!.selectedIndex;\n\t\t\tcontroller.onVersionSelection(this.versions[index]);\n\t\t};\n\n\t\tconst fileSnapshot = doc.getElementById(\"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\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.getElementById(\"downloadOps\") as HTMLElement;\n\t\tconst anonymizeCheckbox = doc.getElementById(\"anonymize\") as HTMLInputElement;\n\t\tthis.attachDownloadOpsListener(opDownloadButton, anonymizeCheckbox);\n\n\t\tthis.versionText = doc.getElementById(\"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) {\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[]) {\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}, time = ${version.date}`\n\t\t\t\t\t\t: `id = ${version.id}`;\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) {\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) {\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.getElementById(\"lastOp\") as HTMLDivElement;\n\t\tthis.text1 = doc.getElementById(\"text1\") as HTMLDivElement;\n\t\tthis.text2 = doc.getElementById(\"text2\") as HTMLDivElement;\n\t\tthis.text3 = doc.getElementById(\"text3\") as HTMLDivElement;\n\n\t\tconst steps = doc.getElementById(\"steps\") as HTMLInputElement;\n\t\tthis.buttonOps = doc.getElementById(\"buttonOps\") as HTMLButtonElement;\n\t\tthis.buttonOps.disabled = true;\n\t\tthis.buttonOps.onclick = () => {\n\t\t\tthis.controller.onOpButtonClick(Number(steps.value));\n\t\t};\n\n\t\tthis.versionText = doc.getElementById(\"versionText\") as HTMLDivElement;\n\t\tthis.versionText.textContent = text;\n\n\t\tconst opDownloadButton = doc.getElementById(\"downloadOps\") as HTMLElement;\n\t\tconst anonymizeCheckbox = doc.getElementById(\"anonymize\") as HTMLInputElement;\n\t\tthis.attachDownloadOpsListener(opDownloadButton, anonymizeCheckbox);\n\t}\n\n\tpublic disableNextOpButton(disable: boolean) {\n\t\tassert(!!this.buttonOps, 0x088 /* \"Missing button ops button!\" */);\n\t\tthis.buttonOps.disabled = disable;\n\t}\n\n\tpublic updateNextOpText(ops: ISequencedDocumentMessage[]) {\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\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) {\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) {\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.appendChild(element);\n\n\t\telement.click();\n\n\t\tdocument.body.removeChild(element);\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\";\nimport { ISequencedDocumentMessage, IVersion } from \"@fluidframework/protocol-definitions\";\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\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 \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 <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\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) {\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.getElementById(\"selector\") as HTMLSelectElement;\n\n\t\tconst buttonVers = doc.getElementById(\"buttonVers\") as HTMLDivElement;\n\t\tbuttonVers.onclick = () => {\n\t\t\tconst index = this.selector!.selectedIndex;\n\t\t\tcontroller.onVersionSelection(this.versions[index]);\n\t\t};\n\n\t\tconst fileSnapshot = doc.getElementById(\"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\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.getElementById(\"downloadOps\") as HTMLElement;\n\t\tconst anonymizeCheckbox = doc.getElementById(\"anonymize\") as HTMLInputElement;\n\t\tthis.attachDownloadOpsListener(opDownloadButton, anonymizeCheckbox);\n\n\t\tthis.versionText = doc.getElementById(\"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) {\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[]) {\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}, time = ${version.date}`\n\t\t\t\t\t\t: `id = ${version.id}`;\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) {\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) {\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.getElementById(\"lastOp\") as HTMLDivElement;\n\t\tthis.text1 = doc.getElementById(\"text1\") as HTMLDivElement;\n\t\tthis.text2 = doc.getElementById(\"text2\") as HTMLDivElement;\n\t\tthis.text3 = doc.getElementById(\"text3\") as HTMLDivElement;\n\n\t\tconst steps = doc.getElementById(\"steps\") as HTMLInputElement;\n\t\tthis.buttonOps = doc.getElementById(\"buttonOps\") as HTMLButtonElement;\n\t\tthis.buttonOps.disabled = true;\n\t\tthis.buttonOps.onclick = () => {\n\t\t\tthis.controller.onOpButtonClick(Number(steps.value));\n\t\t};\n\n\t\tthis.versionText = doc.getElementById(\"versionText\") as HTMLDivElement;\n\t\tthis.versionText.textContent = text;\n\n\t\tconst opDownloadButton = doc.getElementById(\"downloadOps\") as HTMLElement;\n\t\tconst anonymizeCheckbox = doc.getElementById(\"anonymize\") as HTMLInputElement;\n\t\tthis.attachDownloadOpsListener(opDownloadButton, anonymizeCheckbox);\n\t}\n\n\tpublic disableNextOpButton(disable: boolean) {\n\t\tassert(!!this.buttonOps, 0x088 /* \"Missing button ops button!\" */);\n\t\tthis.buttonOps.disabled = disable;\n\t}\n\n\tpublic updateNextOpText(ops: ISequencedDocumentMessage[]) {\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\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) {\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) {\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.appendChild(element);\n\n\t\telement.click();\n\n\t\tdocument.body.removeChild(element);\n\t}\n}\n"]}
|
package/dist/sanitizer.js
CHANGED
|
@@ -39,7 +39,7 @@ exports.Sanitizer = void 0;
|
|
|
39
39
|
* Messages must match known structures when scrubbing for Fluid Preview.
|
|
40
40
|
*/
|
|
41
41
|
const Validator = __importStar(require("jsonschema"));
|
|
42
|
-
const
|
|
42
|
+
const core_utils_1 = require("@fluidframework/core-utils");
|
|
43
43
|
const messageSchema_1 = require("./messageSchema");
|
|
44
44
|
var TextType;
|
|
45
45
|
(function (TextType) {
|
|
@@ -143,7 +143,7 @@ class ChunkedOpProcessor {
|
|
|
143
143
|
let stringified;
|
|
144
144
|
try {
|
|
145
145
|
stringified = JSON.stringify(contents);
|
|
146
|
-
(0,
|
|
146
|
+
(0, core_utils_1.assert)(stringified.length <= this.concatenatedLength, 0x089 /* "Stringified length of chunk contents > total starting length" */);
|
|
147
147
|
}
|
|
148
148
|
catch (e) {
|
|
149
149
|
this.debugMsg(e);
|
|
@@ -177,7 +177,7 @@ class ChunkedOpProcessor {
|
|
|
177
177
|
this.writtenBack = true;
|
|
178
178
|
}
|
|
179
179
|
reset() {
|
|
180
|
-
(0,
|
|
180
|
+
(0, core_utils_1.assert)(this.writtenBack, 0x08a /* "resetting ChunkedOpProcessor that never wrote back its contents" */);
|
|
181
181
|
this.messages = new Array();
|
|
182
182
|
this.parsedMessageContents = new Array();
|
|
183
183
|
this.writtenBack = false;
|
|
@@ -361,7 +361,6 @@ class Sanitizer {
|
|
|
361
361
|
}
|
|
362
362
|
}
|
|
363
363
|
fixPropose(message) {
|
|
364
|
-
var _a, _b, _c, _d;
|
|
365
364
|
if (!this.objectMatchesSchema(message.contents, messageSchema_1.proposeContentsSchema)) {
|
|
366
365
|
message.contents = this.replaceAny(message.contents);
|
|
367
366
|
}
|
|
@@ -370,11 +369,11 @@ class Sanitizer {
|
|
|
370
369
|
try {
|
|
371
370
|
const data = JSON.parse(message.contents);
|
|
372
371
|
if (this.fullScrub) {
|
|
373
|
-
const pkg =
|
|
374
|
-
if (pkg
|
|
372
|
+
const pkg = data.value?.package;
|
|
373
|
+
if (pkg?.name) {
|
|
375
374
|
pkg.name = this.replaceText(pkg.name, TextType.FluidObject);
|
|
376
375
|
}
|
|
377
|
-
if (Array.isArray(
|
|
376
|
+
if (Array.isArray(pkg?.fluid?.browser?.umd?.files)) {
|
|
378
377
|
pkg.fluid.browser.umd.files = this.replaceArray(pkg.fluid.browser.umd.files);
|
|
379
378
|
}
|
|
380
379
|
}
|
|
@@ -416,7 +415,7 @@ class Sanitizer {
|
|
|
416
415
|
* @param contents - contents object to fix
|
|
417
416
|
*/
|
|
418
417
|
fixAttachContents(contents) {
|
|
419
|
-
(0,
|
|
418
|
+
(0, core_utils_1.assert)(typeof contents === "object", 0x08b /* "Unexpected type on contents for fix of an attach!" */);
|
|
420
419
|
if (!this.objectMatchesSchema(contents, messageSchema_1.attachContentsSchema)) {
|
|
421
420
|
this.replaceObject(contents);
|
|
422
421
|
}
|
|
@@ -478,7 +477,7 @@ class Sanitizer {
|
|
|
478
477
|
contents.address = this.replaceText(contents.address, TextType.FluidObject);
|
|
479
478
|
}
|
|
480
479
|
const innerContent = contents.contents.content;
|
|
481
|
-
(0,
|
|
480
|
+
(0, core_utils_1.assert)(innerContent !== undefined, 0x08c /* "innerContent for fixing op contents is undefined!" */);
|
|
482
481
|
if (contents.contents.type === "attach") {
|
|
483
482
|
// attach op
|
|
484
483
|
// handle case where inner content is stringified json
|
|
@@ -650,7 +649,7 @@ class Sanitizer {
|
|
|
650
649
|
}
|
|
651
650
|
});
|
|
652
651
|
// make sure we don't miss an incomplete chunked op at the end
|
|
653
|
-
(0,
|
|
652
|
+
(0, core_utils_1.assert)(!this.chunkProcessor.isPendingProcessing(), 0x08d /* "After sanitize, pending incomplete ops!" */);
|
|
654
653
|
}
|
|
655
654
|
catch (error) {
|
|
656
655
|
this.debugMsg(`Error while processing sequenceNumber ${seq}`);
|