@fluidframework/merge-tree 2.4.0-294316 → 2.4.0-297027

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.
Files changed (98) hide show
  1. package/api-report/merge-tree.legacy.alpha.api.md +26 -5
  2. package/dist/attributionPolicy.d.ts.map +1 -1
  3. package/dist/attributionPolicy.js +10 -3
  4. package/dist/attributionPolicy.js.map +1 -1
  5. package/dist/client.d.ts +14 -4
  6. package/dist/client.d.ts.map +1 -1
  7. package/dist/client.js +97 -9
  8. package/dist/client.js.map +1 -1
  9. package/dist/index.d.ts +1 -1
  10. package/dist/index.d.ts.map +1 -1
  11. package/dist/index.js.map +1 -1
  12. package/dist/legacy.d.ts +1 -0
  13. package/dist/mergeTree.d.ts +15 -1
  14. package/dist/mergeTree.d.ts.map +1 -1
  15. package/dist/mergeTree.js +65 -19
  16. package/dist/mergeTree.js.map +1 -1
  17. package/dist/mergeTreeNodes.d.ts +6 -0
  18. package/dist/mergeTreeNodes.d.ts.map +1 -1
  19. package/dist/mergeTreeNodes.js +2 -1
  20. package/dist/mergeTreeNodes.js.map +1 -1
  21. package/dist/opBuilder.d.ts +15 -1
  22. package/dist/opBuilder.d.ts.map +1 -1
  23. package/dist/opBuilder.js +28 -1
  24. package/dist/opBuilder.js.map +1 -1
  25. package/dist/ops.d.ts +27 -1
  26. package/dist/ops.d.ts.map +1 -1
  27. package/dist/ops.js +1 -0
  28. package/dist/ops.js.map +1 -1
  29. package/dist/sequencePlace.d.ts +4 -0
  30. package/dist/sequencePlace.d.ts.map +1 -1
  31. package/dist/sequencePlace.js +17 -1
  32. package/dist/sequencePlace.js.map +1 -1
  33. package/dist/test/obliterate.concurrent.spec.js +18 -0
  34. package/dist/test/obliterate.concurrent.spec.js.map +1 -1
  35. package/dist/test/obliterate.rangeExpansion.spec.js +109 -53
  36. package/dist/test/obliterate.rangeExpansion.spec.js.map +1 -1
  37. package/dist/test/obliterate.spec.js +2 -2
  38. package/dist/test/obliterate.spec.js.map +1 -1
  39. package/dist/test/reconnectHelper.d.ts +8 -6
  40. package/dist/test/reconnectHelper.d.ts.map +1 -1
  41. package/dist/test/reconnectHelper.js +14 -13
  42. package/dist/test/reconnectHelper.js.map +1 -1
  43. package/dist/test/testClientLogger.d.ts.map +1 -1
  44. package/dist/test/testClientLogger.js +19 -8
  45. package/dist/test/testClientLogger.js.map +1 -1
  46. package/lib/attributionPolicy.d.ts.map +1 -1
  47. package/lib/attributionPolicy.js +10 -3
  48. package/lib/attributionPolicy.js.map +1 -1
  49. package/lib/client.d.ts +14 -4
  50. package/lib/client.d.ts.map +1 -1
  51. package/lib/client.js +98 -10
  52. package/lib/client.js.map +1 -1
  53. package/lib/index.d.ts +1 -1
  54. package/lib/index.d.ts.map +1 -1
  55. package/lib/index.js.map +1 -1
  56. package/lib/legacy.d.ts +1 -0
  57. package/lib/mergeTree.d.ts +15 -1
  58. package/lib/mergeTree.d.ts.map +1 -1
  59. package/lib/mergeTree.js +65 -19
  60. package/lib/mergeTree.js.map +1 -1
  61. package/lib/mergeTreeNodes.d.ts +6 -0
  62. package/lib/mergeTreeNodes.d.ts.map +1 -1
  63. package/lib/mergeTreeNodes.js +2 -1
  64. package/lib/mergeTreeNodes.js.map +1 -1
  65. package/lib/opBuilder.d.ts +15 -1
  66. package/lib/opBuilder.d.ts.map +1 -1
  67. package/lib/opBuilder.js +26 -0
  68. package/lib/opBuilder.js.map +1 -1
  69. package/lib/ops.d.ts +27 -1
  70. package/lib/ops.d.ts.map +1 -1
  71. package/lib/ops.js +1 -0
  72. package/lib/ops.js.map +1 -1
  73. package/lib/sequencePlace.d.ts +4 -0
  74. package/lib/sequencePlace.d.ts.map +1 -1
  75. package/lib/sequencePlace.js +15 -0
  76. package/lib/sequencePlace.js.map +1 -1
  77. package/lib/test/obliterate.concurrent.spec.js +18 -0
  78. package/lib/test/obliterate.concurrent.spec.js.map +1 -1
  79. package/lib/test/obliterate.rangeExpansion.spec.js +109 -53
  80. package/lib/test/obliterate.rangeExpansion.spec.js.map +1 -1
  81. package/lib/test/obliterate.spec.js +2 -2
  82. package/lib/test/obliterate.spec.js.map +1 -1
  83. package/lib/test/reconnectHelper.d.ts +8 -6
  84. package/lib/test/reconnectHelper.d.ts.map +1 -1
  85. package/lib/test/reconnectHelper.js +15 -14
  86. package/lib/test/reconnectHelper.js.map +1 -1
  87. package/lib/test/testClientLogger.d.ts.map +1 -1
  88. package/lib/test/testClientLogger.js +19 -8
  89. package/lib/test/testClientLogger.js.map +1 -1
  90. package/package.json +29 -16
  91. package/src/attributionPolicy.ts +5 -0
  92. package/src/client.ts +136 -21
  93. package/src/index.ts +1 -0
  94. package/src/mergeTree.ts +108 -22
  95. package/src/mergeTreeNodes.ts +9 -1
  96. package/src/opBuilder.ts +32 -0
  97. package/src/ops.ts +23 -1
  98. package/src/sequencePlace.ts +16 -0
@@ -3,22 +3,26 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
  import { strict as assert } from "node:assert";
6
- import { endpointPosAndSide } from "../index.js";
6
+ import { endpointPosAndSide, } from "../index.js";
7
7
  import { TestClientLogger, createClientsAtInitialState } from "./testClientLogger.js";
8
8
  const ClientIds = ["A", "B", "C", "D"];
9
9
  export class ReconnectTestHelper {
10
- constructor() {
10
+ idxFromName(name) {
11
+ return (name.codePointAt(0) ?? 0) - ("A".codePointAt(0) ?? 0);
12
+ }
13
+ constructor(options = {}) {
14
+ this.ops = [];
15
+ this.seq = 0;
11
16
  this.clients = createClientsAtInitialState({
12
17
  initialState: "",
13
- options: { mergeTreeEnableObliterate: true, mergeTreeEnableObliterateReconnect: true },
18
+ options: {
19
+ mergeTreeEnableObliterate: true,
20
+ mergeTreeEnableObliterateReconnect: true,
21
+ ...options,
22
+ },
14
23
  }, ...ClientIds);
15
24
  this.logger = new TestClientLogger(this.clients.all);
16
- this.ops = [];
17
25
  this.perClientOps = this.clients.all.map(() => []);
18
- this.seq = 0;
19
- }
20
- idxFromName(name) {
21
- return (name.codePointAt(0) ?? 0) - ("A".codePointAt(0) ?? 0);
22
26
  }
23
27
  insertText(clientName, pos, text) {
24
28
  const client = this.clients[clientName];
@@ -30,12 +34,9 @@ export class ReconnectTestHelper {
30
34
  }
31
35
  obliterateRange(clientName, start, end) {
32
36
  const client = this.clients[clientName];
33
- let { startPos, endPos } = endpointPosAndSide(start, end);
34
- assert(startPos !== undefined && endPos !== undefined, "start and end positions must be defined");
35
- startPos = startPos === "start" ? 0 : startPos;
36
- endPos = endPos === "end" ? client.getLength() : endPos;
37
- assert(startPos !== "end" && endPos !== "start", "start cannot be end and end cannot be start");
38
- this.ops.push(client.makeOpMessage(client.obliterateRangeLocal(startPos, endPos), ++this.seq));
37
+ this.ops.push(client.makeOpMessage(
38
+ // TODO: remove type assertions when sidedness is enabled
39
+ client.obliterateRangeLocal(start, end), ++this.seq));
39
40
  }
40
41
  insertTextLocal(clientName, pos, text) {
41
42
  const client = this.clients[clientName];
@@ -1 +1 @@
1
- {"version":3,"file":"reconnectHelper.js","sourceRoot":"","sources":["../../src/test/reconnectHelper.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 { strict as assert } from \"node:assert\";\n\nimport { ISequencedDocumentMessage } from \"@fluidframework/driver-definitions/internal\";\n\nimport { SegmentGroup, endpointPosAndSide, type SequencePlace } from \"../index.js\";\nimport {\n\tIMergeTreeDeltaOp,\n\ttype IMergeTreeInsertMsg,\n\ttype IMergeTreeObliterateMsg,\n\ttype IMergeTreeRemoveMsg,\n} from \"../ops.js\";\n\nimport { TestClientLogger, createClientsAtInitialState } from \"./testClientLogger.js\";\n\nconst ClientIds = [\"A\", \"B\", \"C\", \"D\"] as const;\ntype ClientName = (typeof ClientIds)[number];\n\nexport class ReconnectTestHelper {\n\tclients = createClientsAtInitialState(\n\t\t{\n\t\t\tinitialState: \"\",\n\t\t\toptions: { mergeTreeEnableObliterate: true, mergeTreeEnableObliterateReconnect: true },\n\t\t},\n\t\t...ClientIds,\n\t);\n\n\tidxFromName(name: ClientName): number {\n\t\treturn (name.codePointAt(0) ?? 0) - (\"A\".codePointAt(0) ?? 0);\n\t}\n\n\tlogger = new TestClientLogger(this.clients.all);\n\n\tops: ISequencedDocumentMessage[] = [];\n\tperClientOps: ISequencedDocumentMessage[][] = this.clients.all.map(() => []);\n\n\tseq: number = 0;\n\n\tpublic insertText(clientName: ClientName, pos: number, text: string): void {\n\t\tconst client = this.clients[clientName];\n\t\tthis.ops.push(client.makeOpMessage(client.insertTextLocal(pos, text), ++this.seq));\n\t}\n\n\tpublic removeRange(clientName: ClientName, start: number, end: number): void {\n\t\tconst client = this.clients[clientName];\n\t\tthis.ops.push(client.makeOpMessage(client.removeRangeLocal(start, end), ++this.seq));\n\t}\n\n\tpublic obliterateRange(\n\t\tclientName: ClientName,\n\t\tstart: SequencePlace,\n\t\tend: SequencePlace,\n\t): void {\n\t\tconst client = this.clients[clientName];\n\t\tlet { startPos, endPos } = endpointPosAndSide(start, end);\n\t\tassert(\n\t\t\tstartPos !== undefined && endPos !== undefined,\n\t\t\t\"start and end positions must be defined\",\n\t\t);\n\t\tstartPos = startPos === \"start\" ? 0 : startPos;\n\t\tendPos = endPos === \"end\" ? client.getLength() : endPos;\n\t\tassert(\n\t\t\tstartPos !== \"end\" && endPos !== \"start\",\n\t\t\t\"start cannot be end and end cannot be start\",\n\t\t);\n\t\tthis.ops.push(\n\t\t\tclient.makeOpMessage(client.obliterateRangeLocal(startPos, endPos), ++this.seq),\n\t\t);\n\t}\n\n\tpublic insertTextLocal(\n\t\tclientName: ClientName,\n\t\tpos: number,\n\t\ttext: string,\n\t): {\n\t\top: IMergeTreeInsertMsg;\n\t\tseg: SegmentGroup;\n\t\trefSeq: number;\n\t} {\n\t\tconst client = this.clients[clientName];\n\t\tconst op = client.insertTextLocal(pos, text);\n\t\tassert(op);\n\t\tconst seg = client.peekPendingSegmentGroups();\n\t\tassert(seg);\n\t\treturn { op, seg, refSeq: client.getCollabWindow().currentSeq };\n\t}\n\n\tpublic removeRangeLocal(\n\t\tclientName: ClientName,\n\t\tstart: number,\n\t\tend: number,\n\t): {\n\t\top: IMergeTreeRemoveMsg;\n\t\tseg: SegmentGroup;\n\t\trefSeq: number;\n\t} {\n\t\tconst client = this.clients[clientName];\n\t\tconst op = client.removeRangeLocal(start, end);\n\t\tassert(op);\n\t\tconst seg = client.peekPendingSegmentGroups();\n\t\tassert(seg);\n\t\treturn { op, seg, refSeq: client.getCollabWindow().currentSeq };\n\t}\n\n\tpublic obliterateRangeLocal(\n\t\tclientName: ClientName,\n\t\tstart: SequencePlace,\n\t\tend: SequencePlace,\n\t): {\n\t\top: IMergeTreeObliterateMsg;\n\t\tseg: SegmentGroup;\n\t\trefSeq: number;\n\t} {\n\t\tconst client = this.clients[clientName];\n\t\tlet { startPos, endPos } = endpointPosAndSide(start, end);\n\t\tassert(\n\t\t\tstartPos !== undefined && endPos !== undefined,\n\t\t\t\"start and end positions must be defined\",\n\t\t);\n\t\tstartPos = startPos === \"start\" ? 0 : startPos;\n\t\tendPos = endPos === \"end\" ? client.getLength() : endPos;\n\t\tassert(\n\t\t\tstartPos !== \"end\" && endPos !== \"start\",\n\t\t\t\"start cannot be end and end cannot be start\",\n\t\t);\n\t\tconst op = client.obliterateRangeLocal(startPos, endPos);\n\t\tassert(op);\n\t\tconst seg = client.peekPendingSegmentGroups();\n\t\tassert(seg);\n\t\treturn { op, seg, refSeq: client.getCollabWindow().currentSeq };\n\t}\n\n\tpublic disconnect(clientNames: ClientName[]): void {\n\t\tconst clientIdxs = new Set(clientNames.map((element) => this.idxFromName(element)));\n\t\tfor (const op of this.ops.splice(0))\n\t\t\tfor (const [i, c] of this.clients.all.entries()) {\n\t\t\t\tif (clientIdxs.has(i)) {\n\t\t\t\t\tthis.perClientOps[i].push(op);\n\t\t\t\t} else {\n\t\t\t\t\tc.applyMsg(op);\n\t\t\t\t}\n\t\t\t}\n\t}\n\n\tpublic processAllOps(): void {\n\t\tfor (const op of this.ops.splice(0))\n\t\t\tfor (const c of this.clients.all) {\n\t\t\t\tc.applyMsg(op);\n\t\t\t}\n\t}\n\n\tpublic reconnect(clientNames: ClientName[]): void {\n\t\tconst clientIdxs = new Set(clientNames.map((element) => this.idxFromName(element)));\n\t\tfor (const [i, clientOps] of this.perClientOps.entries()) {\n\t\t\tif (clientIdxs.has(i)) {\n\t\t\t\tfor (const op of clientOps.splice(0)) this.clients.all[i].applyMsg(op);\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic submitDisconnectedOp(\n\t\tclientName: ClientName,\n\t\top: { op: IMergeTreeDeltaOp; seg: SegmentGroup | SegmentGroup[] },\n\t): void {\n\t\tconst client = this.clients[clientName];\n\t\tthis.ops.push(client.makeOpMessage(client.regeneratePendingOp(op.op, op.seg), ++this.seq));\n\t}\n}\n"]}
1
+ {"version":3,"file":"reconnectHelper.js","sourceRoot":"","sources":["../../src/test/reconnectHelper.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 { strict as assert } from \"node:assert\";\n\nimport { ISequencedDocumentMessage } from \"@fluidframework/driver-definitions/internal\";\n\nimport {\n\tSegmentGroup,\n\tendpointPosAndSide,\n\ttype IMergeTreeOptions,\n\ttype InteriorSequencePlace,\n\ttype SequencePlace,\n} from \"../index.js\";\nimport {\n\tIMergeTreeDeltaOp,\n\ttype IMergeTreeInsertMsg,\n\ttype IMergeTreeObliterateMsg,\n\ttype IMergeTreeObliterateSidedMsg,\n\ttype IMergeTreeRemoveMsg,\n} from \"../ops.js\";\n\nimport type { TestClient } from \"./testClient.js\";\nimport { TestClientLogger, createClientsAtInitialState } from \"./testClientLogger.js\";\n\nconst ClientIds = [\"A\", \"B\", \"C\", \"D\"] as const;\ntype ClientName = (typeof ClientIds)[number];\n\nexport class ReconnectTestHelper {\n\tclients: Record<ClientName, TestClient> & { all: TestClient[] };\n\n\tidxFromName(name: ClientName): number {\n\t\treturn (name.codePointAt(0) ?? 0) - (\"A\".codePointAt(0) ?? 0);\n\t}\n\n\tlogger: TestClientLogger;\n\n\tops: ISequencedDocumentMessage[] = [];\n\tperClientOps: ISequencedDocumentMessage[][];\n\n\tseq: number = 0;\n\n\tpublic constructor(options: IMergeTreeOptions = {}) {\n\t\tthis.clients = createClientsAtInitialState(\n\t\t\t{\n\t\t\t\tinitialState: \"\",\n\t\t\t\toptions: {\n\t\t\t\t\tmergeTreeEnableObliterate: true,\n\t\t\t\t\tmergeTreeEnableObliterateReconnect: true,\n\t\t\t\t\t...options,\n\t\t\t\t},\n\t\t\t},\n\t\t\t...ClientIds,\n\t\t);\n\t\tthis.logger = new TestClientLogger(this.clients.all);\n\t\tthis.perClientOps = this.clients.all.map(() => []);\n\t}\n\n\tpublic insertText(clientName: ClientName, pos: number, text: string): void {\n\t\tconst client = this.clients[clientName];\n\t\tthis.ops.push(client.makeOpMessage(client.insertTextLocal(pos, text), ++this.seq));\n\t}\n\n\tpublic removeRange(clientName: ClientName, start: number, end: number): void {\n\t\tconst client = this.clients[clientName];\n\t\tthis.ops.push(client.makeOpMessage(client.removeRangeLocal(start, end), ++this.seq));\n\t}\n\n\tpublic obliterateRange(\n\t\tclientName: ClientName,\n\t\tstart: number | InteriorSequencePlace,\n\t\tend: number | InteriorSequencePlace,\n\t): void {\n\t\tconst client = this.clients[clientName];\n\t\tthis.ops.push(\n\t\t\tclient.makeOpMessage(\n\t\t\t\t// TODO: remove type assertions when sidedness is enabled\n\t\t\t\tclient.obliterateRangeLocal(start as number, end as number),\n\t\t\t\t++this.seq,\n\t\t\t),\n\t\t);\n\t}\n\n\tpublic insertTextLocal(\n\t\tclientName: ClientName,\n\t\tpos: number,\n\t\ttext: string,\n\t): {\n\t\top: IMergeTreeInsertMsg;\n\t\tseg: SegmentGroup;\n\t\trefSeq: number;\n\t} {\n\t\tconst client = this.clients[clientName];\n\t\tconst op = client.insertTextLocal(pos, text);\n\t\tassert(op);\n\t\tconst seg = client.peekPendingSegmentGroups();\n\t\tassert(seg);\n\t\treturn { op, seg, refSeq: client.getCollabWindow().currentSeq };\n\t}\n\n\tpublic removeRangeLocal(\n\t\tclientName: ClientName,\n\t\tstart: number,\n\t\tend: number,\n\t): {\n\t\top: IMergeTreeRemoveMsg;\n\t\tseg: SegmentGroup;\n\t\trefSeq: number;\n\t} {\n\t\tconst client = this.clients[clientName];\n\t\tconst op = client.removeRangeLocal(start, end);\n\t\tassert(op);\n\t\tconst seg = client.peekPendingSegmentGroups();\n\t\tassert(seg);\n\t\treturn { op, seg, refSeq: client.getCollabWindow().currentSeq };\n\t}\n\n\tpublic obliterateRangeLocal(\n\t\tclientName: ClientName,\n\t\tstart: SequencePlace,\n\t\tend: SequencePlace,\n\t): {\n\t\top: IMergeTreeObliterateMsg | IMergeTreeObliterateSidedMsg;\n\t\tseg: SegmentGroup;\n\t\trefSeq: number;\n\t} {\n\t\tconst client = this.clients[clientName];\n\t\tlet { startPos, endPos } = endpointPosAndSide(start, end);\n\t\tassert(\n\t\t\tstartPos !== undefined && endPos !== undefined,\n\t\t\t\"start and end positions must be defined\",\n\t\t);\n\t\tstartPos = startPos === \"start\" ? 0 : startPos;\n\t\tendPos = endPos === \"end\" ? client.getLength() : endPos;\n\t\tassert(\n\t\t\tstartPos !== \"end\" && endPos !== \"start\",\n\t\t\t\"start cannot be end and end cannot be start\",\n\t\t);\n\t\tconst op = client.obliterateRangeLocal(startPos, endPos);\n\t\tassert(op);\n\t\tconst seg = client.peekPendingSegmentGroups();\n\t\tassert(seg);\n\t\treturn { op, seg, refSeq: client.getCollabWindow().currentSeq };\n\t}\n\n\tpublic disconnect(clientNames: ClientName[]): void {\n\t\tconst clientIdxs = new Set(clientNames.map((element) => this.idxFromName(element)));\n\t\tfor (const op of this.ops.splice(0))\n\t\t\tfor (const [i, c] of this.clients.all.entries()) {\n\t\t\t\tif (clientIdxs.has(i)) {\n\t\t\t\t\tthis.perClientOps[i].push(op);\n\t\t\t\t} else {\n\t\t\t\t\tc.applyMsg(op);\n\t\t\t\t}\n\t\t\t}\n\t}\n\n\tpublic processAllOps(): void {\n\t\tfor (const op of this.ops.splice(0))\n\t\t\tfor (const c of this.clients.all) {\n\t\t\t\tc.applyMsg(op);\n\t\t\t}\n\t}\n\n\tpublic reconnect(clientNames: ClientName[]): void {\n\t\tconst clientIdxs = new Set(clientNames.map((element) => this.idxFromName(element)));\n\t\tfor (const [i, clientOps] of this.perClientOps.entries()) {\n\t\t\tif (clientIdxs.has(i)) {\n\t\t\t\tfor (const op of clientOps.splice(0)) this.clients.all[i].applyMsg(op);\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic submitDisconnectedOp(\n\t\tclientName: ClientName,\n\t\top: { op: IMergeTreeDeltaOp; seg: SegmentGroup | SegmentGroup[] },\n\t): void {\n\t\tconst client = this.clients[clientName];\n\t\tthis.ops.push(client.makeOpMessage(client.regeneratePendingOp(op.op, op.seg), ++this.seq));\n\t}\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"testClientLogger.d.ts","sourceRoot":"","sources":["../../src/test/testClientLogger.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAQH,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAehD,OAAO,EAAE,WAAW,EAAmB,MAAM,kBAAkB,CAAC;AAGhE,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAmC7C,KAAK,SAAS,CAAC,WAAW,SAAS,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC,CAAC;AAEtF,wBAAgB,2BAA2B,CAC1C,QAAQ,SAAS,SAAS,CAAC,WAAW,CAAC,EACvC,WAAW,SAAS,MAAM,GAAG,MAAM,GAAG,MAAM,QAAQ,EAEpD,IAAI,EAAE;IACL,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,iBAAiB,GAAG,WAAW,CAAC;CAC1C,EACD,GAAG,SAAS,EAAE,WAAW,EAAE,GACzB,MAAM,CAAC,MAAM,QAAQ,EAAE,UAAU,CAAC,GAAG;IAAE,GAAG,EAAE,UAAU,EAAE,CAAA;CAAE,CAuB5D;AACD,qBAAa,gBAAgB;IA0C3B,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC;WA1CV,QAAQ,CAAC,OAAO,EAAE,SAAS,UAAU,EAAE,GAAG,MAAM;IAiB9D,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IAExC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAgB;IACzC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAkB;IAEhD,OAAO,CAAC,SAAS,CAAgB;IACjC,OAAO,CAAC,SAAS,CAAgB;IAEjC,OAAO,CAAC,aAAa,CAAoC;IAEzD,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAsB;IAEvD;;;OAGG;IACI,OAAO,IAAI,IAAI;gBAQJ,OAAO,EAAE,SAAS,UAAU,EAAE,EAC9B,KAAK,CAAC,oBAAQ;IA4DhC,OAAO,CAAC,aAAa;IA+Bd,QAAQ,CAAC,IAAI,CAAC,EAAE;QACtB,KAAK,CAAC,EAAE,OAAO,CAAC;QAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,WAAW,CAAC,EAAE,MAAM,CAAC;KACrB,GAAG,MAAM;IA+DV,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAE,SAAS,UAAU,EAAE,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM;IAOhE,QAAQ,CAAC,aAAa,GAAE,OAAe,GAAG,MAAM;IAuBhD,cAAc,CAAC,CAAC,EAAE,OAAO,GAAG,KAAK;IASxC,OAAO,CAAC,MAAM,CAAC,YAAY;CAkD3B"}
1
+ {"version":3,"file":"testClientLogger.d.ts","sourceRoot":"","sources":["../../src/test/testClientLogger.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAQH,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAehD,OAAO,EAAE,WAAW,EAAmB,MAAM,kBAAkB,CAAC;AAGhE,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AA4C7C,KAAK,SAAS,CAAC,WAAW,SAAS,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC,CAAC;AAEtF,wBAAgB,2BAA2B,CAC1C,QAAQ,SAAS,SAAS,CAAC,WAAW,CAAC,EACvC,WAAW,SAAS,MAAM,GAAG,MAAM,GAAG,MAAM,QAAQ,EAEpD,IAAI,EAAE;IACL,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,iBAAiB,GAAG,WAAW,CAAC;CAC1C,EACD,GAAG,SAAS,EAAE,WAAW,EAAE,GACzB,MAAM,CAAC,MAAM,QAAQ,EAAE,UAAU,CAAC,GAAG;IAAE,GAAG,EAAE,UAAU,EAAE,CAAA;CAAE,CAuB5D;AACD,qBAAa,gBAAgB;IA0C3B,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC;WA1CV,QAAQ,CAAC,OAAO,EAAE,SAAS,UAAU,EAAE,GAAG,MAAM;IAiB9D,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IAExC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAgB;IACzC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAkB;IAEhD,OAAO,CAAC,SAAS,CAAgB;IACjC,OAAO,CAAC,SAAS,CAAgB;IAEjC,OAAO,CAAC,aAAa,CAAoC;IAEzD,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAsB;IAEvD;;;OAGG;IACI,OAAO,IAAI,IAAI;gBAQJ,OAAO,EAAE,SAAS,UAAU,EAAE,EAC9B,KAAK,CAAC,oBAAQ;IA4DhC,OAAO,CAAC,aAAa;IA+Bd,QAAQ,CAAC,IAAI,CAAC,EAAE;QACtB,KAAK,CAAC,EAAE,OAAO,CAAC;QAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,WAAW,CAAC,EAAE,MAAM,CAAC;KACrB,GAAG,MAAM;IA+DV,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAE,SAAS,UAAU,EAAE,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM;IAOhE,QAAQ,CAAC,aAAa,GAAE,OAAe,GAAG,MAAM;IAyBhD,cAAc,CAAC,CAAC,EAAE,OAAO,GAAG,KAAK;IASxC,OAAO,CAAC,MAAM,CAAC,YAAY;CAkD3B"}
@@ -8,6 +8,7 @@ import { UnassignedSequenceNumber } from "../constants.js";
8
8
  import { MergeTreeMaintenanceType, } from "../mergeTreeDeltaCallback.js";
9
9
  import { depthFirstNodeWalk } from "../mergeTreeNodeWalk.js";
10
10
  import { Marker, seqLTE, toMoveInfo, toRemovalInfo, } from "../mergeTreeNodes.js";
11
+ import { MergeTreeDeltaType } from "../ops.js";
11
12
  import { matchProperties } from "../properties.js";
12
13
  import { TextSegment } from "../textSegment.js";
13
14
  import { TestClient } from "./testClient.js";
@@ -17,12 +18,20 @@ function getOpString(msg) {
17
18
  }
18
19
  const op = msg.contents;
19
20
  const opType = op.type.toString();
20
- const opPos =
21
- // eslint-disable-next-line @typescript-eslint/dot-notation
22
- op?.["pos1"] === undefined
23
- ? ""
24
- : // eslint-disable-next-line @typescript-eslint/dot-notation
25
- `@${op["pos1"]}${op["pos2"] === undefined ? "" : `,${op["pos2"]}`}`;
21
+ let opPos;
22
+ if (op.type === MergeTreeDeltaType.OBLITERATE_SIDED) {
23
+ const pos1Side = op.type === MergeTreeDeltaType.OBLITERATE_SIDED ? (op.pos1.before ? "[" : "(") : "";
24
+ const pos2Side = op.type === MergeTreeDeltaType.OBLITERATE_SIDED ? (op.pos2.before ? ")" : "]") : "";
25
+ opPos = `@${pos1Side}${op.pos1.pos},${op.pos2.pos}${pos2Side}`;
26
+ }
27
+ else {
28
+ opPos =
29
+ // eslint-disable-next-line @typescript-eslint/dot-notation
30
+ op?.["pos1"] === undefined
31
+ ? ""
32
+ : // eslint-disable-next-line @typescript-eslint/dot-notation
33
+ `@${op["pos1"]}${op["pos2"] === undefined ? "" : `,${op["pos2"]}`}`;
34
+ }
26
35
  const seq = msg.sequenceNumber < 0 ? "L" : msg.sequenceNumber.toString();
27
36
  const ref = msg.referenceSequenceNumber.toString();
28
37
  const client = msg.clientId;
@@ -203,9 +212,11 @@ export class TestClientLogger {
203
212
  `-: Deleted ~:Deleted <= MinSeq\n` +
204
213
  `*: Unacked Insert and Delete\n` +
205
214
  `${this.clients[0].getCollabWindow().minSeq}: msn/offset\n` +
206
- `Op format <seq>:<ref>:<client><type>@<pos1>,<pos2>\n` +
215
+ `Op format <seq>:<ref>:<client><type>@<side1><pos1>,<pos2><side2>\n` +
207
216
  `sequence number represented as offset from msn. L means local.\n` +
208
- `op types: 0) insert 1) remove 2) annotate 4) obliterate\n`;
217
+ `op types: 0) insert 1) remove 2) annotate 4) obliterate\n` +
218
+ `for obliterates: [] indicates that the range includes the position,\n` +
219
+ `and () indicates that the range excludes that position from the obliterate.\n`;
209
220
  if (this.title) {
210
221
  str += `${this.title}\n`;
211
222
  }
@@ -1 +1 @@
1
- {"version":3,"file":"testClientLogger.js","sourceRoot":"","sources":["../../src/test/testClientLogger.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 { strict as assert } from \"node:assert\";\n\nimport { ISequencedDocumentMessage } from \"@fluidframework/driver-definitions/internal\";\nimport { LoggingError } from \"@fluidframework/telemetry-utils/internal\";\n\nimport { UnassignedSequenceNumber } from \"../constants.js\";\nimport { IMergeTreeOptions } from \"../index.js\";\nimport {\n\tIMergeTreeDeltaOpArgs,\n\tMergeTreeMaintenanceType,\n\ttype IMergeTreeMaintenanceCallbackArgs,\n} from \"../mergeTreeDeltaCallback.js\";\nimport { depthFirstNodeWalk } from \"../mergeTreeNodeWalk.js\";\nimport {\n\tMarker,\n\tseqLTE,\n\ttoMoveInfo,\n\ttoRemovalInfo,\n\ttype ISegment,\n} from \"../mergeTreeNodes.js\";\nimport { IMergeTreeOp } from \"../ops.js\";\nimport { PropertySet, matchProperties } from \"../properties.js\";\nimport { TextSegment } from \"../textSegment.js\";\n\nimport { TestClient } from \"./testClient.js\";\n\nfunction getOpString(msg: ISequencedDocumentMessage | undefined): string {\n\tif (msg === undefined) {\n\t\treturn \"\";\n\t}\n\tconst op = msg.contents as IMergeTreeOp;\n\tconst opType = op.type.toString();\n\tconst opPos =\n\t\t// eslint-disable-next-line @typescript-eslint/dot-notation\n\t\top?.[\"pos1\"] === undefined\n\t\t\t? \"\"\n\t\t\t: // eslint-disable-next-line @typescript-eslint/dot-notation\n\t\t\t\t`@${op[\"pos1\"]}${op[\"pos2\"] === undefined ? \"\" : `,${op[\"pos2\"]}`}`;\n\n\tconst seq = msg.sequenceNumber < 0 ? \"L\" : msg.sequenceNumber.toString();\n\tconst ref = msg.referenceSequenceNumber.toString();\n\tconst client = msg.clientId;\n\treturn `${seq}:${ref}:${client}${opType}${opPos}`;\n}\n\nfunction arePropsEmpty(props: PropertySet | undefined): boolean {\n\treturn props === undefined || Object.entries(props).length === 0;\n}\n\n/**\n * Compare properties, allowing empty to match undefined\n */\nfunction matchPropertiesHandleEmpty(\n\ta: PropertySet | undefined,\n\tb: PropertySet | undefined,\n): boolean {\n\treturn matchProperties(a, b) || (arePropsEmpty(a) && arePropsEmpty(b));\n}\n\ntype ClientMap<TClientName extends string> = Partial<Record<TClientName, TestClient>>;\n\nexport function createClientsAtInitialState<\n\tTClients extends ClientMap<TClientName>,\n\tTClientName extends string = string & keyof TClients,\n>(\n\topts: {\n\t\tinitialState: string;\n\t\toptions?: IMergeTreeOptions & PropertySet;\n\t},\n\t...clientIds: TClientName[]\n): Record<keyof TClients, TestClient> & { all: TestClient[] } {\n\tconst setup = (c: TestClient): void => {\n\t\tif (opts.initialState.length > 0) {\n\t\t\tc.insertTextLocal(0, opts.initialState);\n\t\t\twhile (c.getText().includes(\"-\")) {\n\t\t\t\tconst index = c.getText().indexOf(\"-\");\n\t\t\t\tc.removeRangeLocal(index, index + 1);\n\t\t\t}\n\t\t}\n\t};\n\tconst all: TestClient[] = [];\n\tconst clients: Partial<Record<keyof TClients, TestClient>> = {};\n\tfor (const id of clientIds) {\n\t\tif (clients[id] === undefined) {\n\t\t\tconst client = new TestClient(opts.options);\n\t\t\tclients[id] = client;\n\t\t\tall.push(client);\n\t\t\tsetup(client);\n\t\t\tclient.startOrUpdateCollaboration(id);\n\t\t}\n\t}\n\n\treturn { ...(clients as Record<keyof TClients, TestClient>), all };\n}\nexport class TestClientLogger {\n\tpublic static toString(clients: readonly TestClient[]): string {\n\t\treturn (\n\t\t\tclients\n\t\t\t\t.map((c) => this.getSegString(c))\n\t\t\t\t// eslint-disable-next-line unicorn/no-array-reduce\n\t\t\t\t.reduce<[string, string]>(\n\t\t\t\t\t(pv, cv) => {\n\t\t\t\t\t\tpv[0] += `|${cv.acked.padEnd(cv.local.length, \"\")}`;\n\t\t\t\t\t\tpv[1] += `|${cv.local.padEnd(cv.acked.length, \"\")}`;\n\t\t\t\t\t\treturn pv;\n\t\t\t\t\t},\n\t\t\t\t\t[\"\", \"\"],\n\t\t\t\t)\n\t\t\t\t.join(\"\\n\")\n\t\t);\n\t}\n\n\tprivate readonly incrementalLog = false;\n\n\tprivate readonly paddings: number[] = [];\n\tprivate readonly roundLogLines: string[][] = [];\n\n\tprivate ackedLine: string[] = [];\n\tprivate localLine: string[] = [];\n\t// initialize to private instance, so first real edit will create a new line\n\tprivate lastDeltaArgs: IMergeTreeDeltaOpArgs | undefined;\n\n\tprivate readonly disposeCallbacks: (() => void)[] = [];\n\n\t/**\n\t * Unsubscribes this logger from its clients' events. Consider using this for tests with client lifetime\n\t * extending significantly past the logger's.\n\t */\n\tpublic dispose(): void {\n\t\tfor (const cb of this.disposeCallbacks) {\n\t\t\tcb();\n\t\t}\n\t\tthis.disposeCallbacks.length = 0;\n\t}\n\n\tconstructor(\n\t\tprivate readonly clients: readonly TestClient[],\n\t\tprivate readonly title?: string,\n\t) {\n\t\tconst logHeaders: string[] = [];\n\t\tfor (const [i, c] of clients.entries()) {\n\t\t\tlogHeaders.push(\"op\", `client ${c.longClientId}`);\n\t\t\tconst callback = (deltaArgs: IMergeTreeDeltaOpArgs | undefined): void => {\n\t\t\t\tif (\n\t\t\t\t\tthis.lastDeltaArgs?.sequencedMessage !== deltaArgs?.sequencedMessage ||\n\t\t\t\t\tthis.lastDeltaArgs?.op !== deltaArgs?.op\n\t\t\t\t) {\n\t\t\t\t\tthis.addNewLogLine();\n\t\t\t\t\tthis.lastDeltaArgs = deltaArgs;\n\t\t\t\t}\n\t\t\t\tconst clientLogIndex = i * 2;\n\n\t\t\t\tthis.ackedLine[clientLogIndex] =\n\t\t\t\t\tdeltaArgs === undefined\n\t\t\t\t\t\t? \"\"\n\t\t\t\t\t\t: getOpString(\n\t\t\t\t\t\t\t\tdeltaArgs.sequencedMessage === undefined\n\t\t\t\t\t\t\t\t\t? c.makeOpMessage(deltaArgs.op)\n\t\t\t\t\t\t\t\t\t: { ...deltaArgs.sequencedMessage, contents: deltaArgs.op },\n\t\t\t\t\t\t\t);\n\t\t\t\tconst segStrings = TestClientLogger.getSegString(c);\n\t\t\t\tthis.ackedLine[clientLogIndex + 1] = segStrings.acked;\n\t\t\t\tthis.localLine[clientLogIndex + 1] = segStrings.local;\n\n\t\t\t\tthis.paddings[clientLogIndex] = Math.max(\n\t\t\t\t\tthis.ackedLine[clientLogIndex].length,\n\t\t\t\t\tthis.localLine[clientLogIndex].length,\n\t\t\t\t\tthis.paddings[clientLogIndex],\n\t\t\t\t);\n\n\t\t\t\tthis.paddings[clientLogIndex + 1] = Math.max(\n\t\t\t\t\tthis.ackedLine[clientLogIndex + 1].length,\n\t\t\t\t\tthis.localLine[clientLogIndex + 1].length,\n\t\t\t\t\tthis.paddings[clientLogIndex + 1],\n\t\t\t\t);\n\t\t\t};\n\n\t\t\tconst maintenanceCallback = (\n\t\t\t\tmain: IMergeTreeMaintenanceCallbackArgs,\n\t\t\t\top: IMergeTreeDeltaOpArgs | undefined,\n\t\t\t): void => {\n\t\t\t\tif (main.operation === MergeTreeMaintenanceType.ACKNOWLEDGED) {\n\t\t\t\t\tcallback(op);\n\t\t\t\t}\n\t\t\t};\n\t\t\tc.on(\"delta\", callback);\n\t\t\tc.on(\"maintenance\", maintenanceCallback);\n\t\t\tthis.disposeCallbacks.push(() => {\n\t\t\t\tc.off(\"delta\", callback);\n\t\t\t\tc.off(\"maintenance\", maintenanceCallback);\n\t\t\t});\n\t\t}\n\t\tthis.roundLogLines.push(logHeaders);\n\t\tfor (const v of this.roundLogLines[0]) this.paddings.push(v.length);\n\t\tthis.addNewLogLine(); // capture initial state\n\t}\n\n\tprivate addNewLogLine(): void {\n\t\tif (this.incrementalLog) {\n\t\t\twhile (this.roundLogLines.length > 0) {\n\t\t\t\tconst logLine = this.roundLogLines.shift();\n\t\t\t\tif (logLine?.some((c) => c.trim().length > 0)) {\n\t\t\t\t\tconsole.log(logLine.map((v, i) => v.padEnd(this.paddings[i])).join(\" | \"));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tthis.ackedLine = [];\n\t\tthis.localLine = [];\n\t\tfor (const [clientLogIndex, cc] of this.clients.entries()) {\n\t\t\tconst segStrings = TestClientLogger.getSegString(cc);\n\t\t\tthis.ackedLine.push(\"\", segStrings.acked);\n\t\t\tthis.localLine.push(\"\", segStrings.local);\n\n\t\t\tthis.paddings[clientLogIndex] = Math.max(\n\t\t\t\tthis.ackedLine[clientLogIndex].length,\n\t\t\t\tthis.localLine[clientLogIndex].length,\n\t\t\t\tthis.paddings[clientLogIndex],\n\t\t\t);\n\n\t\t\tthis.paddings[clientLogIndex + 1] = Math.max(\n\t\t\t\tthis.ackedLine[clientLogIndex + 1].length,\n\t\t\t\tthis.localLine[clientLogIndex + 1].length,\n\t\t\t\tthis.paddings[clientLogIndex + 1],\n\t\t\t);\n\t\t}\n\t\tthis.roundLogLines.push(this.ackedLine, this.localLine);\n\t}\n\n\tpublic validate(opts?: {\n\t\tclear?: boolean;\n\t\tbaseText?: string;\n\t\terrorPrefix?: string;\n\t}): string {\n\t\tconst baseText = opts?.baseText ?? this.clients[0].getText();\n\t\tconst errorPrefix = opts?.errorPrefix ? `${opts?.errorPrefix}: ` : \"\";\n\t\t// cache all the properties of client 0 for faster look up\n\t\tconst properties = Array.from({ length: this.clients[0].getLength() }).map((_, i) =>\n\t\t\tthis.clients[0].getPropertiesAtPosition(i),\n\t\t);\n\t\tfor (const c of this.clients) {\n\t\t\tif (opts?.baseText === undefined && c === this.clients[0]) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\t// ensure all clients have seen the same ops\n\t\t\tassert.equal(\n\t\t\t\tc.getCurrentSeq(),\n\t\t\t\tthis.clients[0].getCurrentSeq(),\n\t\t\t\t`${errorPrefix}${c.longClientId} current seq does not match client ${this.clients[0].longClientId}`,\n\t\t\t);\n\t\t\t// Pre-check to avoid this.toString() in the string template\n\t\t\tif (c.getText() !== baseText) {\n\t\t\t\tassert.equal(\n\t\t\t\t\tc.getText(),\n\t\t\t\t\tbaseText,\n\t\t\t\t\t`${errorPrefix}\\n${this.toString()}\\nClient ${\n\t\t\t\t\t\tc.longClientId\n\t\t\t\t\t} does not match client ${\n\t\t\t\t\t\topts?.baseText ? \"baseText\" : this.clients[0].longClientId\n\t\t\t\t\t}`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tif (c === this.clients[0]) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tlet pos = 0;\n\t\t\tdepthFirstNodeWalk(c.mergeTree.root, c.mergeTree.root.children[0], undefined, (seg) => {\n\t\t\t\tif (toMoveOrRemove(seg) === undefined) {\n\t\t\t\t\tconst segProps = seg.properties;\n\t\t\t\t\tfor (let i = 0; i < seg.cachedLength; i++) {\n\t\t\t\t\t\tif (!matchPropertiesHandleEmpty(segProps, properties[pos + i])) {\n\t\t\t\t\t\t\tassert.deepStrictEqual(\n\t\t\t\t\t\t\t\tsegProps,\n\t\t\t\t\t\t\t\tproperties[pos + i],\n\t\t\t\t\t\t\t\t`${errorPrefix}\\n${this.toString()}\\nClient ${\n\t\t\t\t\t\t\t\t\tc.longClientId\n\t\t\t\t\t\t\t\t} does not match client ${this.clients[0].longClientId} properties at pos ${\n\t\t\t\t\t\t\t\t\tpos + i\n\t\t\t\t\t\t\t\t}`,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tpos += seg.cachedLength;\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tif (opts?.clear === true) {\n\t\t\tthis.roundLogLines.splice(1, this.roundLogLines.length);\n\t\t\tfor (const [i, v] of this.roundLogLines[0].entries()) this.paddings[i] = v.length;\n\t\t\tthis.addNewLogLine(); // capture initial state\n\t\t}\n\t\treturn baseText;\n\t}\n\n\tstatic validate(clients: readonly TestClient[], title?: string): string {\n\t\tconst logger = new TestClientLogger(clients, title);\n\t\tconst result = logger.validate();\n\t\tlogger.dispose();\n\t\treturn result;\n\t}\n\n\tpublic toString(excludeHeader: boolean = false): string {\n\t\tlet str = \"\";\n\t\tif (!excludeHeader) {\n\t\t\tstr +=\n\t\t\t\t`_: Local State\\n` +\n\t\t\t\t`-: Deleted ~:Deleted <= MinSeq\\n` +\n\t\t\t\t`*: Unacked Insert and Delete\\n` +\n\t\t\t\t`${this.clients[0].getCollabWindow().minSeq}: msn/offset\\n` +\n\t\t\t\t`Op format <seq>:<ref>:<client><type>@<pos1>,<pos2>\\n` +\n\t\t\t\t`sequence number represented as offset from msn. L means local.\\n` +\n\t\t\t\t`op types: 0) insert 1) remove 2) annotate 4) obliterate\\n`;\n\n\t\t\tif (this.title) {\n\t\t\t\tstr += `${this.title}\\n`;\n\t\t\t}\n\t\t}\n\t\tstr += this.roundLogLines\n\t\t\t.filter((line) => line.some((c) => c.trim().length > 0))\n\t\t\t.map((line) => line.map((v, i) => v.padEnd(this.paddings[i])).join(\" | \"))\n\t\t\t.join(\"\\n\");\n\t\treturn str;\n\t}\n\n\tpublic addLogsToError(e: unknown): Error {\n\t\tif (e instanceof Error) {\n\t\t\te.message += `\\n${this.toString()}`;\n\t\t\treturn e;\n\t\t}\n\n\t\treturn new LoggingError(`${e}\\n${this.toString()}`);\n\t}\n\n\tprivate static getSegString(client: TestClient): { acked: string; local: string } {\n\t\tlet acked: string = \"\";\n\t\tlet local: string = \"\";\n\t\tconst nodes = [...client.mergeTree.root.children];\n\t\tlet parent = nodes[0]?.parent;\n\t\twhile (nodes.length > 0) {\n\t\t\tconst node = nodes.shift();\n\t\t\tif (node) {\n\t\t\t\tif (node.isLeaf()) {\n\t\t\t\t\tif (node.parent !== parent) {\n\t\t\t\t\t\tif (acked.length > 0) {\n\t\t\t\t\t\t\tacked += \" \";\n\t\t\t\t\t\t\tlocal += \" \";\n\t\t\t\t\t\t}\n\t\t\t\t\t\tparent = node.parent;\n\t\t\t\t\t}\n\t\t\t\t\tconst text = TextSegment.is(node) ? node.text : Marker.is(node) ? \"¶\" : undefined;\n\t\t\t\t\tif (text !== undefined) {\n\t\t\t\t\t\tconst removedNode = toMoveOrRemove(node);\n\t\t\t\t\t\tif (removedNode === undefined) {\n\t\t\t\t\t\t\tif (node.seq === UnassignedSequenceNumber) {\n\t\t\t\t\t\t\t\tacked += \"_\".repeat(text.length);\n\t\t\t\t\t\t\t\tlocal += text;\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tacked += text;\n\t\t\t\t\t\t\t\tlocal += \" \".repeat(text.length);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tif (removedNode.seq === UnassignedSequenceNumber) {\n\t\t\t\t\t\t\t\tacked += \"_\".repeat(text.length);\n\t\t\t\t\t\t\t\tlocal +=\n\t\t\t\t\t\t\t\t\tnode.seq === UnassignedSequenceNumber\n\t\t\t\t\t\t\t\t\t\t? \"*\".repeat(text.length)\n\t\t\t\t\t\t\t\t\t\t: \"-\".repeat(text.length);\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tconst removedSymbol = seqLTE(removedNode.seq, client.getCollabWindow().minSeq)\n\t\t\t\t\t\t\t\t\t? \"~\"\n\t\t\t\t\t\t\t\t\t: \"-\";\n\t\t\t\t\t\t\t\tacked += removedSymbol.repeat(text.length);\n\t\t\t\t\t\t\t\tlocal += \" \".repeat(text.length);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tnodes.push(...node.children);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn { acked, local };\n\t}\n}\n\nfunction toMoveOrRemove(segment: ISegment): { seq: number } | undefined {\n\tconst mi = toMoveInfo(segment);\n\tconst ri = toRemovalInfo(segment);\n\tif (mi !== undefined || ri !== undefined) {\n\t\treturn {\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion, @typescript-eslint/no-non-null-asserted-optional-chain\n\t\t\tseq: mi?.movedSeq ?? ri?.removedSeq!,\n\t\t};\n\t}\n}\n"]}
1
+ {"version":3,"file":"testClientLogger.js","sourceRoot":"","sources":["../../src/test/testClientLogger.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 { strict as assert } from \"node:assert\";\n\nimport { ISequencedDocumentMessage } from \"@fluidframework/driver-definitions/internal\";\nimport { LoggingError } from \"@fluidframework/telemetry-utils/internal\";\n\nimport { UnassignedSequenceNumber } from \"../constants.js\";\nimport { IMergeTreeOptions } from \"../index.js\";\nimport {\n\tIMergeTreeDeltaOpArgs,\n\tMergeTreeMaintenanceType,\n\ttype IMergeTreeMaintenanceCallbackArgs,\n} from \"../mergeTreeDeltaCallback.js\";\nimport { depthFirstNodeWalk } from \"../mergeTreeNodeWalk.js\";\nimport {\n\tMarker,\n\tseqLTE,\n\ttoMoveInfo,\n\ttoRemovalInfo,\n\ttype ISegment,\n} from \"../mergeTreeNodes.js\";\nimport { IMergeTreeOp, MergeTreeDeltaType } from \"../ops.js\";\nimport { PropertySet, matchProperties } from \"../properties.js\";\nimport { TextSegment } from \"../textSegment.js\";\n\nimport { TestClient } from \"./testClient.js\";\n\nfunction getOpString(msg: ISequencedDocumentMessage | undefined): string {\n\tif (msg === undefined) {\n\t\treturn \"\";\n\t}\n\tconst op = msg.contents as IMergeTreeOp;\n\tconst opType = op.type.toString();\n\tlet opPos;\n\tif (op.type === MergeTreeDeltaType.OBLITERATE_SIDED) {\n\t\tconst pos1Side =\n\t\t\top.type === MergeTreeDeltaType.OBLITERATE_SIDED ? (op.pos1.before ? \"[\" : \"(\") : \"\";\n\t\tconst pos2Side =\n\t\t\top.type === MergeTreeDeltaType.OBLITERATE_SIDED ? (op.pos2.before ? \")\" : \"]\") : \"\";\n\t\topPos = `@${pos1Side}${op.pos1.pos},${op.pos2.pos}${pos2Side}`;\n\t} else {\n\t\topPos =\n\t\t\t// eslint-disable-next-line @typescript-eslint/dot-notation\n\t\t\top?.[\"pos1\"] === undefined\n\t\t\t\t? \"\"\n\t\t\t\t: // eslint-disable-next-line @typescript-eslint/dot-notation\n\t\t\t\t\t`@${op[\"pos1\"]}${op[\"pos2\"] === undefined ? \"\" : `,${op[\"pos2\"]}`}`;\n\t}\n\n\tconst seq = msg.sequenceNumber < 0 ? \"L\" : msg.sequenceNumber.toString();\n\tconst ref = msg.referenceSequenceNumber.toString();\n\tconst client = msg.clientId;\n\treturn `${seq}:${ref}:${client}${opType}${opPos}`;\n}\n\nfunction arePropsEmpty(props: PropertySet | undefined): boolean {\n\treturn props === undefined || Object.entries(props).length === 0;\n}\n\n/**\n * Compare properties, allowing empty to match undefined\n */\nfunction matchPropertiesHandleEmpty(\n\ta: PropertySet | undefined,\n\tb: PropertySet | undefined,\n): boolean {\n\treturn matchProperties(a, b) || (arePropsEmpty(a) && arePropsEmpty(b));\n}\n\ntype ClientMap<TClientName extends string> = Partial<Record<TClientName, TestClient>>;\n\nexport function createClientsAtInitialState<\n\tTClients extends ClientMap<TClientName>,\n\tTClientName extends string = string & keyof TClients,\n>(\n\topts: {\n\t\tinitialState: string;\n\t\toptions?: IMergeTreeOptions & PropertySet;\n\t},\n\t...clientIds: TClientName[]\n): Record<keyof TClients, TestClient> & { all: TestClient[] } {\n\tconst setup = (c: TestClient): void => {\n\t\tif (opts.initialState.length > 0) {\n\t\t\tc.insertTextLocal(0, opts.initialState);\n\t\t\twhile (c.getText().includes(\"-\")) {\n\t\t\t\tconst index = c.getText().indexOf(\"-\");\n\t\t\t\tc.removeRangeLocal(index, index + 1);\n\t\t\t}\n\t\t}\n\t};\n\tconst all: TestClient[] = [];\n\tconst clients: Partial<Record<keyof TClients, TestClient>> = {};\n\tfor (const id of clientIds) {\n\t\tif (clients[id] === undefined) {\n\t\t\tconst client = new TestClient(opts.options);\n\t\t\tclients[id] = client;\n\t\t\tall.push(client);\n\t\t\tsetup(client);\n\t\t\tclient.startOrUpdateCollaboration(id);\n\t\t}\n\t}\n\n\treturn { ...(clients as Record<keyof TClients, TestClient>), all };\n}\nexport class TestClientLogger {\n\tpublic static toString(clients: readonly TestClient[]): string {\n\t\treturn (\n\t\t\tclients\n\t\t\t\t.map((c) => this.getSegString(c))\n\t\t\t\t// eslint-disable-next-line unicorn/no-array-reduce\n\t\t\t\t.reduce<[string, string]>(\n\t\t\t\t\t(pv, cv) => {\n\t\t\t\t\t\tpv[0] += `|${cv.acked.padEnd(cv.local.length, \"\")}`;\n\t\t\t\t\t\tpv[1] += `|${cv.local.padEnd(cv.acked.length, \"\")}`;\n\t\t\t\t\t\treturn pv;\n\t\t\t\t\t},\n\t\t\t\t\t[\"\", \"\"],\n\t\t\t\t)\n\t\t\t\t.join(\"\\n\")\n\t\t);\n\t}\n\n\tprivate readonly incrementalLog = false;\n\n\tprivate readonly paddings: number[] = [];\n\tprivate readonly roundLogLines: string[][] = [];\n\n\tprivate ackedLine: string[] = [];\n\tprivate localLine: string[] = [];\n\t// initialize to private instance, so first real edit will create a new line\n\tprivate lastDeltaArgs: IMergeTreeDeltaOpArgs | undefined;\n\n\tprivate readonly disposeCallbacks: (() => void)[] = [];\n\n\t/**\n\t * Unsubscribes this logger from its clients' events. Consider using this for tests with client lifetime\n\t * extending significantly past the logger's.\n\t */\n\tpublic dispose(): void {\n\t\tfor (const cb of this.disposeCallbacks) {\n\t\t\tcb();\n\t\t}\n\t\tthis.disposeCallbacks.length = 0;\n\t}\n\n\tconstructor(\n\t\tprivate readonly clients: readonly TestClient[],\n\t\tprivate readonly title?: string,\n\t) {\n\t\tconst logHeaders: string[] = [];\n\t\tfor (const [i, c] of clients.entries()) {\n\t\t\tlogHeaders.push(\"op\", `client ${c.longClientId}`);\n\t\t\tconst callback = (deltaArgs: IMergeTreeDeltaOpArgs | undefined): void => {\n\t\t\t\tif (\n\t\t\t\t\tthis.lastDeltaArgs?.sequencedMessage !== deltaArgs?.sequencedMessage ||\n\t\t\t\t\tthis.lastDeltaArgs?.op !== deltaArgs?.op\n\t\t\t\t) {\n\t\t\t\t\tthis.addNewLogLine();\n\t\t\t\t\tthis.lastDeltaArgs = deltaArgs;\n\t\t\t\t}\n\t\t\t\tconst clientLogIndex = i * 2;\n\n\t\t\t\tthis.ackedLine[clientLogIndex] =\n\t\t\t\t\tdeltaArgs === undefined\n\t\t\t\t\t\t? \"\"\n\t\t\t\t\t\t: getOpString(\n\t\t\t\t\t\t\t\tdeltaArgs.sequencedMessage === undefined\n\t\t\t\t\t\t\t\t\t? c.makeOpMessage(deltaArgs.op)\n\t\t\t\t\t\t\t\t\t: { ...deltaArgs.sequencedMessage, contents: deltaArgs.op },\n\t\t\t\t\t\t\t);\n\t\t\t\tconst segStrings = TestClientLogger.getSegString(c);\n\t\t\t\tthis.ackedLine[clientLogIndex + 1] = segStrings.acked;\n\t\t\t\tthis.localLine[clientLogIndex + 1] = segStrings.local;\n\n\t\t\t\tthis.paddings[clientLogIndex] = Math.max(\n\t\t\t\t\tthis.ackedLine[clientLogIndex].length,\n\t\t\t\t\tthis.localLine[clientLogIndex].length,\n\t\t\t\t\tthis.paddings[clientLogIndex],\n\t\t\t\t);\n\n\t\t\t\tthis.paddings[clientLogIndex + 1] = Math.max(\n\t\t\t\t\tthis.ackedLine[clientLogIndex + 1].length,\n\t\t\t\t\tthis.localLine[clientLogIndex + 1].length,\n\t\t\t\t\tthis.paddings[clientLogIndex + 1],\n\t\t\t\t);\n\t\t\t};\n\n\t\t\tconst maintenanceCallback = (\n\t\t\t\tmain: IMergeTreeMaintenanceCallbackArgs,\n\t\t\t\top: IMergeTreeDeltaOpArgs | undefined,\n\t\t\t): void => {\n\t\t\t\tif (main.operation === MergeTreeMaintenanceType.ACKNOWLEDGED) {\n\t\t\t\t\tcallback(op);\n\t\t\t\t}\n\t\t\t};\n\t\t\tc.on(\"delta\", callback);\n\t\t\tc.on(\"maintenance\", maintenanceCallback);\n\t\t\tthis.disposeCallbacks.push(() => {\n\t\t\t\tc.off(\"delta\", callback);\n\t\t\t\tc.off(\"maintenance\", maintenanceCallback);\n\t\t\t});\n\t\t}\n\t\tthis.roundLogLines.push(logHeaders);\n\t\tfor (const v of this.roundLogLines[0]) this.paddings.push(v.length);\n\t\tthis.addNewLogLine(); // capture initial state\n\t}\n\n\tprivate addNewLogLine(): void {\n\t\tif (this.incrementalLog) {\n\t\t\twhile (this.roundLogLines.length > 0) {\n\t\t\t\tconst logLine = this.roundLogLines.shift();\n\t\t\t\tif (logLine?.some((c) => c.trim().length > 0)) {\n\t\t\t\t\tconsole.log(logLine.map((v, i) => v.padEnd(this.paddings[i])).join(\" | \"));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tthis.ackedLine = [];\n\t\tthis.localLine = [];\n\t\tfor (const [clientLogIndex, cc] of this.clients.entries()) {\n\t\t\tconst segStrings = TestClientLogger.getSegString(cc);\n\t\t\tthis.ackedLine.push(\"\", segStrings.acked);\n\t\t\tthis.localLine.push(\"\", segStrings.local);\n\n\t\t\tthis.paddings[clientLogIndex] = Math.max(\n\t\t\t\tthis.ackedLine[clientLogIndex].length,\n\t\t\t\tthis.localLine[clientLogIndex].length,\n\t\t\t\tthis.paddings[clientLogIndex],\n\t\t\t);\n\n\t\t\tthis.paddings[clientLogIndex + 1] = Math.max(\n\t\t\t\tthis.ackedLine[clientLogIndex + 1].length,\n\t\t\t\tthis.localLine[clientLogIndex + 1].length,\n\t\t\t\tthis.paddings[clientLogIndex + 1],\n\t\t\t);\n\t\t}\n\t\tthis.roundLogLines.push(this.ackedLine, this.localLine);\n\t}\n\n\tpublic validate(opts?: {\n\t\tclear?: boolean;\n\t\tbaseText?: string;\n\t\terrorPrefix?: string;\n\t}): string {\n\t\tconst baseText = opts?.baseText ?? this.clients[0].getText();\n\t\tconst errorPrefix = opts?.errorPrefix ? `${opts?.errorPrefix}: ` : \"\";\n\t\t// cache all the properties of client 0 for faster look up\n\t\tconst properties = Array.from({ length: this.clients[0].getLength() }).map((_, i) =>\n\t\t\tthis.clients[0].getPropertiesAtPosition(i),\n\t\t);\n\t\tfor (const c of this.clients) {\n\t\t\tif (opts?.baseText === undefined && c === this.clients[0]) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\t// ensure all clients have seen the same ops\n\t\t\tassert.equal(\n\t\t\t\tc.getCurrentSeq(),\n\t\t\t\tthis.clients[0].getCurrentSeq(),\n\t\t\t\t`${errorPrefix}${c.longClientId} current seq does not match client ${this.clients[0].longClientId}`,\n\t\t\t);\n\t\t\t// Pre-check to avoid this.toString() in the string template\n\t\t\tif (c.getText() !== baseText) {\n\t\t\t\tassert.equal(\n\t\t\t\t\tc.getText(),\n\t\t\t\t\tbaseText,\n\t\t\t\t\t`${errorPrefix}\\n${this.toString()}\\nClient ${\n\t\t\t\t\t\tc.longClientId\n\t\t\t\t\t} does not match client ${\n\t\t\t\t\t\topts?.baseText ? \"baseText\" : this.clients[0].longClientId\n\t\t\t\t\t}`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tif (c === this.clients[0]) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tlet pos = 0;\n\t\t\tdepthFirstNodeWalk(c.mergeTree.root, c.mergeTree.root.children[0], undefined, (seg) => {\n\t\t\t\tif (toMoveOrRemove(seg) === undefined) {\n\t\t\t\t\tconst segProps = seg.properties;\n\t\t\t\t\tfor (let i = 0; i < seg.cachedLength; i++) {\n\t\t\t\t\t\tif (!matchPropertiesHandleEmpty(segProps, properties[pos + i])) {\n\t\t\t\t\t\t\tassert.deepStrictEqual(\n\t\t\t\t\t\t\t\tsegProps,\n\t\t\t\t\t\t\t\tproperties[pos + i],\n\t\t\t\t\t\t\t\t`${errorPrefix}\\n${this.toString()}\\nClient ${\n\t\t\t\t\t\t\t\t\tc.longClientId\n\t\t\t\t\t\t\t\t} does not match client ${this.clients[0].longClientId} properties at pos ${\n\t\t\t\t\t\t\t\t\tpos + i\n\t\t\t\t\t\t\t\t}`,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tpos += seg.cachedLength;\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tif (opts?.clear === true) {\n\t\t\tthis.roundLogLines.splice(1, this.roundLogLines.length);\n\t\t\tfor (const [i, v] of this.roundLogLines[0].entries()) this.paddings[i] = v.length;\n\t\t\tthis.addNewLogLine(); // capture initial state\n\t\t}\n\t\treturn baseText;\n\t}\n\n\tstatic validate(clients: readonly TestClient[], title?: string): string {\n\t\tconst logger = new TestClientLogger(clients, title);\n\t\tconst result = logger.validate();\n\t\tlogger.dispose();\n\t\treturn result;\n\t}\n\n\tpublic toString(excludeHeader: boolean = false): string {\n\t\tlet str = \"\";\n\t\tif (!excludeHeader) {\n\t\t\tstr +=\n\t\t\t\t`_: Local State\\n` +\n\t\t\t\t`-: Deleted ~:Deleted <= MinSeq\\n` +\n\t\t\t\t`*: Unacked Insert and Delete\\n` +\n\t\t\t\t`${this.clients[0].getCollabWindow().minSeq}: msn/offset\\n` +\n\t\t\t\t`Op format <seq>:<ref>:<client><type>@<side1><pos1>,<pos2><side2>\\n` +\n\t\t\t\t`sequence number represented as offset from msn. L means local.\\n` +\n\t\t\t\t`op types: 0) insert 1) remove 2) annotate 4) obliterate\\n` +\n\t\t\t\t`for obliterates: [] indicates that the range includes the position,\\n` +\n\t\t\t\t`and () indicates that the range excludes that position from the obliterate.\\n`;\n\n\t\t\tif (this.title) {\n\t\t\t\tstr += `${this.title}\\n`;\n\t\t\t}\n\t\t}\n\t\tstr += this.roundLogLines\n\t\t\t.filter((line) => line.some((c) => c.trim().length > 0))\n\t\t\t.map((line) => line.map((v, i) => v.padEnd(this.paddings[i])).join(\" | \"))\n\t\t\t.join(\"\\n\");\n\t\treturn str;\n\t}\n\n\tpublic addLogsToError(e: unknown): Error {\n\t\tif (e instanceof Error) {\n\t\t\te.message += `\\n${this.toString()}`;\n\t\t\treturn e;\n\t\t}\n\n\t\treturn new LoggingError(`${e}\\n${this.toString()}`);\n\t}\n\n\tprivate static getSegString(client: TestClient): { acked: string; local: string } {\n\t\tlet acked: string = \"\";\n\t\tlet local: string = \"\";\n\t\tconst nodes = [...client.mergeTree.root.children];\n\t\tlet parent = nodes[0]?.parent;\n\t\twhile (nodes.length > 0) {\n\t\t\tconst node = nodes.shift();\n\t\t\tif (node) {\n\t\t\t\tif (node.isLeaf()) {\n\t\t\t\t\tif (node.parent !== parent) {\n\t\t\t\t\t\tif (acked.length > 0) {\n\t\t\t\t\t\t\tacked += \" \";\n\t\t\t\t\t\t\tlocal += \" \";\n\t\t\t\t\t\t}\n\t\t\t\t\t\tparent = node.parent;\n\t\t\t\t\t}\n\t\t\t\t\tconst text = TextSegment.is(node) ? node.text : Marker.is(node) ? \"¶\" : undefined;\n\t\t\t\t\tif (text !== undefined) {\n\t\t\t\t\t\tconst removedNode = toMoveOrRemove(node);\n\t\t\t\t\t\tif (removedNode === undefined) {\n\t\t\t\t\t\t\tif (node.seq === UnassignedSequenceNumber) {\n\t\t\t\t\t\t\t\tacked += \"_\".repeat(text.length);\n\t\t\t\t\t\t\t\tlocal += text;\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tacked += text;\n\t\t\t\t\t\t\t\tlocal += \" \".repeat(text.length);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tif (removedNode.seq === UnassignedSequenceNumber) {\n\t\t\t\t\t\t\t\tacked += \"_\".repeat(text.length);\n\t\t\t\t\t\t\t\tlocal +=\n\t\t\t\t\t\t\t\t\tnode.seq === UnassignedSequenceNumber\n\t\t\t\t\t\t\t\t\t\t? \"*\".repeat(text.length)\n\t\t\t\t\t\t\t\t\t\t: \"-\".repeat(text.length);\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tconst removedSymbol = seqLTE(removedNode.seq, client.getCollabWindow().minSeq)\n\t\t\t\t\t\t\t\t\t? \"~\"\n\t\t\t\t\t\t\t\t\t: \"-\";\n\t\t\t\t\t\t\t\tacked += removedSymbol.repeat(text.length);\n\t\t\t\t\t\t\t\tlocal += \" \".repeat(text.length);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tnodes.push(...node.children);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn { acked, local };\n\t}\n}\n\nfunction toMoveOrRemove(segment: ISegment): { seq: number } | undefined {\n\tconst mi = toMoveInfo(segment);\n\tconst ri = toRemovalInfo(segment);\n\tif (mi !== undefined || ri !== undefined) {\n\t\treturn {\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion, @typescript-eslint/no-non-null-asserted-optional-chain\n\t\t\tseq: mi?.movedSeq ?? ri?.removedSeq!,\n\t\t};\n\t}\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fluidframework/merge-tree",
3
- "version": "2.4.0-294316",
3
+ "version": "2.4.0-297027",
4
4
  "description": "Merge tree",
5
5
  "homepage": "https://fluidframework.com",
6
6
  "repository": {
@@ -79,30 +79,30 @@
79
79
  "temp-directory": "nyc/.nyc_output"
80
80
  },
81
81
  "dependencies": {
82
- "@fluid-internal/client-utils": "2.4.0-294316",
83
- "@fluidframework/container-definitions": "2.4.0-294316",
84
- "@fluidframework/core-interfaces": "2.4.0-294316",
85
- "@fluidframework/core-utils": "2.4.0-294316",
86
- "@fluidframework/datastore-definitions": "2.4.0-294316",
87
- "@fluidframework/driver-definitions": "2.4.0-294316",
88
- "@fluidframework/runtime-definitions": "2.4.0-294316",
89
- "@fluidframework/runtime-utils": "2.4.0-294316",
90
- "@fluidframework/shared-object-base": "2.4.0-294316",
91
- "@fluidframework/telemetry-utils": "2.4.0-294316"
82
+ "@fluid-internal/client-utils": "2.4.0-297027",
83
+ "@fluidframework/container-definitions": "2.4.0-297027",
84
+ "@fluidframework/core-interfaces": "2.4.0-297027",
85
+ "@fluidframework/core-utils": "2.4.0-297027",
86
+ "@fluidframework/datastore-definitions": "2.4.0-297027",
87
+ "@fluidframework/driver-definitions": "2.4.0-297027",
88
+ "@fluidframework/runtime-definitions": "2.4.0-297027",
89
+ "@fluidframework/runtime-utils": "2.4.0-297027",
90
+ "@fluidframework/shared-object-base": "2.4.0-297027",
91
+ "@fluidframework/telemetry-utils": "2.4.0-297027"
92
92
  },
93
93
  "devDependencies": {
94
94
  "@arethetypeswrong/cli": "^0.15.2",
95
95
  "@biomejs/biome": "~1.8.3",
96
- "@fluid-internal/mocha-test-setup": "2.4.0-294316",
97
- "@fluid-private/stochastic-test-utils": "2.4.0-294316",
98
- "@fluid-private/test-pairwise-generator": "2.4.0-294316",
96
+ "@fluid-internal/mocha-test-setup": "2.4.0-297027",
97
+ "@fluid-private/stochastic-test-utils": "2.4.0-297027",
98
+ "@fluid-private/test-pairwise-generator": "2.4.0-297027",
99
99
  "@fluid-tools/benchmark": "^0.50.0",
100
100
  "@fluid-tools/build-cli": "^0.46.0",
101
101
  "@fluidframework/build-common": "^2.0.3",
102
102
  "@fluidframework/build-tools": "^0.46.0",
103
103
  "@fluidframework/eslint-config-fluid": "^5.4.0",
104
104
  "@fluidframework/merge-tree-previous": "npm:@fluidframework/merge-tree@2.3.0",
105
- "@fluidframework/test-runtime-utils": "2.4.0-294316",
105
+ "@fluidframework/test-runtime-utils": "2.4.0-297027",
106
106
  "@microsoft/api-extractor": "7.47.8",
107
107
  "@types/diff": "^3.5.1",
108
108
  "@types/mocha": "^9.1.1",
@@ -123,7 +123,20 @@
123
123
  "typescript": "~5.4.5"
124
124
  },
125
125
  "typeValidation": {
126
- "broken": {},
126
+ "broken": {
127
+ "Interface_IMergeTreeDeltaOpArgs": {
128
+ "backCompat": false
129
+ },
130
+ "TypeAlias_IMergeTreeDeltaOp": {
131
+ "backCompat": false
132
+ },
133
+ "Interface_IMergeTreeGroupMsg": {
134
+ "backCompat": false
135
+ },
136
+ "TypeAlias_IMergeTreeOp": {
137
+ "backCompat": false
138
+ }
139
+ },
127
140
  "entrypoint": "internal"
128
141
  },
129
142
  "scripts": {
@@ -10,6 +10,7 @@ import { AttributionKey } from "@fluidframework/runtime-definitions/internal";
10
10
  import { AttributionCollection } from "./attributionCollection.js";
11
11
  // eslint-disable-next-line import/no-deprecated
12
12
  import { Client } from "./client.js";
13
+ // eslint-disable-next-line import/no-deprecated
13
14
  import { AttributionPolicy } from "./mergeTree.js";
14
15
  import {
15
16
  IMergeTreeDeltaCallbackArgs,
@@ -41,6 +42,7 @@ interface AttributionCallbacks {
41
42
  function createAttributionPolicyFromCallbacks({
42
43
  delta,
43
44
  maintenance,
45
+ // eslint-disable-next-line import/no-deprecated
44
46
  }: AttributionCallbacks): AttributionPolicy {
45
47
  let unsubscribe: undefined | (() => void);
46
48
  return {
@@ -202,6 +204,7 @@ function combineMergeTreeCallbacks(callbacks: AttributionCallbacks[]): Attributi
202
204
  * Creates an {@link AttributionPolicy} which only tracks initial insertion of content.
203
205
  * @internal
204
206
  */
207
+ // eslint-disable-next-line import/no-deprecated
205
208
  export function createInsertOnlyAttributionPolicy(): AttributionPolicy {
206
209
  return createAttributionPolicyFromCallbacks(
207
210
  combineMergeTreeCallbacks([
@@ -231,6 +234,7 @@ export function createInsertOnlyAttributionPolicy(): AttributionPolicy {
231
234
  */
232
235
  export function createPropertyTrackingAttributionPolicyFactory(
233
236
  ...propNames: string[]
237
+ // eslint-disable-next-line import/no-deprecated
234
238
  ): () => AttributionPolicy {
235
239
  return () =>
236
240
  createAttributionPolicyFromCallbacks(
@@ -249,6 +253,7 @@ export function createPropertyTrackingAttributionPolicyFactory(
249
253
  */
250
254
  export function createPropertyTrackingAndInsertionAttributionPolicyFactory(
251
255
  ...propNames: string[]
256
+ // eslint-disable-next-line import/no-deprecated
252
257
  ): () => AttributionPolicy {
253
258
  return () =>
254
259
  createAttributionPolicyFromCallbacks(