@fluidframework/odsp-driver 2.1.0-276326 → 2.1.0-281041

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 (186) hide show
  1. package/README.md +3 -1
  2. package/api-extractor/{api-extractor-lint-beta.cjs.json → api-extractor.current.json} +2 -2
  3. package/api-extractor/api-extractor.legacy.json +1 -1
  4. package/api-extractor.json +1 -1
  5. package/api-report/odsp-driver.legacy.public.api.md +9 -0
  6. package/dist/ReadBufferUtils.d.ts.map +1 -1
  7. package/dist/ReadBufferUtils.js +1 -0
  8. package/dist/ReadBufferUtils.js.map +1 -1
  9. package/dist/WriteBufferUtils.d.ts.map +1 -1
  10. package/dist/WriteBufferUtils.js +2 -0
  11. package/dist/WriteBufferUtils.js.map +1 -1
  12. package/dist/compactSnapshotParser.d.ts.map +1 -1
  13. package/dist/compactSnapshotParser.js +28 -5
  14. package/dist/compactSnapshotParser.js.map +1 -1
  15. package/dist/compactSnapshotWriter.d.ts.map +1 -1
  16. package/dist/compactSnapshotWriter.js +3 -1
  17. package/dist/compactSnapshotWriter.js.map +1 -1
  18. package/dist/createFile.d.ts.map +1 -1
  19. package/dist/createFile.js +1 -1
  20. package/dist/createFile.js.map +1 -1
  21. package/dist/createNewContainerOnExistingFile.d.ts.map +1 -1
  22. package/dist/createNewContainerOnExistingFile.js +2 -1
  23. package/dist/createNewContainerOnExistingFile.js.map +1 -1
  24. package/dist/createNewUtils.d.ts.map +1 -1
  25. package/dist/createNewUtils.js +4 -1
  26. package/dist/createNewUtils.js.map +1 -1
  27. package/dist/epochTracker.d.ts.map +1 -1
  28. package/dist/epochTracker.js +3 -3
  29. package/dist/epochTracker.js.map +1 -1
  30. package/dist/fetchSnapshot.d.ts +1 -1
  31. package/dist/fetchSnapshot.d.ts.map +1 -1
  32. package/dist/fetchSnapshot.js +8 -3
  33. package/dist/fetchSnapshot.js.map +1 -1
  34. package/dist/legacy.d.ts +1 -1
  35. package/dist/localOdspDriver/localOdspDeltaStorageService.d.ts.map +1 -1
  36. package/dist/localOdspDriver/localOdspDeltaStorageService.js +1 -0
  37. package/dist/localOdspDriver/localOdspDeltaStorageService.js.map +1 -1
  38. package/dist/odspDelayLoadedDeltaStream.d.ts.map +1 -1
  39. package/dist/odspDelayLoadedDeltaStream.js +2 -0
  40. package/dist/odspDelayLoadedDeltaStream.js.map +1 -1
  41. package/dist/odspDeltaStorageService.d.ts.map +1 -1
  42. package/dist/odspDeltaStorageService.js +4 -1
  43. package/dist/odspDeltaStorageService.js.map +1 -1
  44. package/dist/odspDocumentDeltaConnection.d.ts.map +1 -1
  45. package/dist/odspDocumentDeltaConnection.js +2 -0
  46. package/dist/odspDocumentDeltaConnection.js.map +1 -1
  47. package/dist/odspDocumentStorageManager.d.ts +1 -0
  48. package/dist/odspDocumentStorageManager.d.ts.map +1 -1
  49. package/dist/odspDocumentStorageManager.js +4 -3
  50. package/dist/odspDocumentStorageManager.js.map +1 -1
  51. package/dist/odspDocumentStorageServiceBase.d.ts.map +1 -1
  52. package/dist/odspDocumentStorageServiceBase.js +2 -0
  53. package/dist/odspDocumentStorageServiceBase.js.map +1 -1
  54. package/dist/odspDriverUrlResolver.d.ts +8 -0
  55. package/dist/odspDriverUrlResolver.d.ts.map +1 -1
  56. package/dist/odspDriverUrlResolver.js +4 -2
  57. package/dist/odspDriverUrlResolver.js.map +1 -1
  58. package/dist/odspSnapshotParser.d.ts.map +1 -1
  59. package/dist/odspSnapshotParser.js +7 -3
  60. package/dist/odspSnapshotParser.js.map +1 -1
  61. package/dist/odspSummaryUploadManager.d.ts.map +1 -1
  62. package/dist/odspSummaryUploadManager.js +3 -1
  63. package/dist/odspSummaryUploadManager.js.map +1 -1
  64. package/dist/odspUrlHelper.d.ts.map +1 -1
  65. package/dist/odspUrlHelper.js +5 -1
  66. package/dist/odspUrlHelper.js.map +1 -1
  67. package/dist/odspUtils.d.ts +3 -2
  68. package/dist/odspUtils.d.ts.map +1 -1
  69. package/dist/odspUtils.js +7 -3
  70. package/dist/odspUtils.js.map +1 -1
  71. package/dist/packageVersion.d.ts +1 -1
  72. package/dist/packageVersion.js +1 -1
  73. package/dist/packageVersion.js.map +1 -1
  74. package/dist/prefetchLatestSnapshot.d.ts.map +1 -1
  75. package/dist/prefetchLatestSnapshot.js +2 -2
  76. package/dist/prefetchLatestSnapshot.js.map +1 -1
  77. package/dist/public.d.ts +1 -1
  78. package/dist/zipItDataRepresentationUtils.d.ts.map +1 -1
  79. package/dist/zipItDataRepresentationUtils.js +9 -0
  80. package/dist/zipItDataRepresentationUtils.js.map +1 -1
  81. package/internal.d.ts +1 -1
  82. package/legacy.d.ts +1 -1
  83. package/lib/ReadBufferUtils.d.ts.map +1 -1
  84. package/lib/ReadBufferUtils.js +1 -0
  85. package/lib/ReadBufferUtils.js.map +1 -1
  86. package/lib/WriteBufferUtils.d.ts.map +1 -1
  87. package/lib/WriteBufferUtils.js +2 -0
  88. package/lib/WriteBufferUtils.js.map +1 -1
  89. package/lib/compactSnapshotParser.d.ts.map +1 -1
  90. package/lib/compactSnapshotParser.js +28 -5
  91. package/lib/compactSnapshotParser.js.map +1 -1
  92. package/lib/compactSnapshotWriter.d.ts.map +1 -1
  93. package/lib/compactSnapshotWriter.js +3 -1
  94. package/lib/compactSnapshotWriter.js.map +1 -1
  95. package/lib/createFile.d.ts.map +1 -1
  96. package/lib/createFile.js +3 -3
  97. package/lib/createFile.js.map +1 -1
  98. package/lib/createNewContainerOnExistingFile.d.ts.map +1 -1
  99. package/lib/createNewContainerOnExistingFile.js +3 -2
  100. package/lib/createNewContainerOnExistingFile.js.map +1 -1
  101. package/lib/createNewUtils.d.ts.map +1 -1
  102. package/lib/createNewUtils.js +5 -2
  103. package/lib/createNewUtils.js.map +1 -1
  104. package/lib/epochTracker.d.ts.map +1 -1
  105. package/lib/epochTracker.js +4 -4
  106. package/lib/epochTracker.js.map +1 -1
  107. package/lib/fetchSnapshot.d.ts +1 -1
  108. package/lib/fetchSnapshot.d.ts.map +1 -1
  109. package/lib/fetchSnapshot.js +8 -3
  110. package/lib/fetchSnapshot.js.map +1 -1
  111. package/lib/legacy.d.ts +1 -1
  112. package/lib/localOdspDriver/localOdspDeltaStorageService.d.ts.map +1 -1
  113. package/lib/localOdspDriver/localOdspDeltaStorageService.js +1 -0
  114. package/lib/localOdspDriver/localOdspDeltaStorageService.js.map +1 -1
  115. package/lib/odspDelayLoadedDeltaStream.d.ts.map +1 -1
  116. package/lib/odspDelayLoadedDeltaStream.js +2 -0
  117. package/lib/odspDelayLoadedDeltaStream.js.map +1 -1
  118. package/lib/odspDeltaStorageService.d.ts.map +1 -1
  119. package/lib/odspDeltaStorageService.js +4 -1
  120. package/lib/odspDeltaStorageService.js.map +1 -1
  121. package/lib/odspDocumentDeltaConnection.d.ts.map +1 -1
  122. package/lib/odspDocumentDeltaConnection.js +2 -0
  123. package/lib/odspDocumentDeltaConnection.js.map +1 -1
  124. package/lib/odspDocumentStorageManager.d.ts +1 -0
  125. package/lib/odspDocumentStorageManager.d.ts.map +1 -1
  126. package/lib/odspDocumentStorageManager.js +5 -4
  127. package/lib/odspDocumentStorageManager.js.map +1 -1
  128. package/lib/odspDocumentStorageServiceBase.d.ts.map +1 -1
  129. package/lib/odspDocumentStorageServiceBase.js +2 -0
  130. package/lib/odspDocumentStorageServiceBase.js.map +1 -1
  131. package/lib/odspDriverUrlResolver.d.ts +8 -0
  132. package/lib/odspDriverUrlResolver.d.ts.map +1 -1
  133. package/lib/odspDriverUrlResolver.js +3 -2
  134. package/lib/odspDriverUrlResolver.js.map +1 -1
  135. package/lib/odspSnapshotParser.d.ts.map +1 -1
  136. package/lib/odspSnapshotParser.js +7 -3
  137. package/lib/odspSnapshotParser.js.map +1 -1
  138. package/lib/odspSummaryUploadManager.d.ts.map +1 -1
  139. package/lib/odspSummaryUploadManager.js +3 -1
  140. package/lib/odspSummaryUploadManager.js.map +1 -1
  141. package/lib/odspUrlHelper.d.ts.map +1 -1
  142. package/lib/odspUrlHelper.js +5 -1
  143. package/lib/odspUrlHelper.js.map +1 -1
  144. package/lib/odspUtils.d.ts +3 -2
  145. package/lib/odspUtils.d.ts.map +1 -1
  146. package/lib/odspUtils.js +6 -3
  147. package/lib/odspUtils.js.map +1 -1
  148. package/lib/packageVersion.d.ts +1 -1
  149. package/lib/packageVersion.js +1 -1
  150. package/lib/packageVersion.js.map +1 -1
  151. package/lib/prefetchLatestSnapshot.d.ts.map +1 -1
  152. package/lib/prefetchLatestSnapshot.js +3 -3
  153. package/lib/prefetchLatestSnapshot.js.map +1 -1
  154. package/lib/public.d.ts +1 -1
  155. package/lib/zipItDataRepresentationUtils.d.ts.map +1 -1
  156. package/lib/zipItDataRepresentationUtils.js +9 -0
  157. package/lib/zipItDataRepresentationUtils.js.map +1 -1
  158. package/package.json +25 -35
  159. package/src/ReadBufferUtils.ts +2 -1
  160. package/src/WriteBufferUtils.ts +4 -2
  161. package/src/compactSnapshotParser.ts +41 -17
  162. package/src/compactSnapshotWriter.ts +4 -2
  163. package/src/createFile.ts +9 -1
  164. package/src/createNewContainerOnExistingFile.ts +16 -3
  165. package/src/createNewUtils.ts +7 -4
  166. package/src/epochTracker.ts +4 -3
  167. package/src/fetchSnapshot.ts +10 -3
  168. package/src/localOdspDriver/localOdspDeltaStorageService.ts +2 -1
  169. package/src/odspDelayLoadedDeltaStream.ts +4 -2
  170. package/src/odspDeltaStorageService.ts +4 -2
  171. package/src/odspDocumentDeltaConnection.ts +4 -2
  172. package/src/odspDocumentStorageManager.ts +18 -3
  173. package/src/odspDocumentStorageServiceBase.ts +4 -2
  174. package/src/odspDriverUrlResolver.ts +3 -2
  175. package/src/odspSnapshotParser.ts +10 -6
  176. package/src/odspSummaryUploadManager.ts +4 -2
  177. package/src/odspUrlHelper.ts +8 -4
  178. package/src/odspUtils.ts +13 -2
  179. package/src/packageVersion.ts +1 -1
  180. package/src/prefetchLatestSnapshot.ts +3 -4
  181. package/src/zipItDataRepresentationUtils.ts +18 -9
  182. package/tsconfig.json +0 -1
  183. package/api-extractor/api-extractor-lint-beta.esm.json +0 -5
  184. package/beta.d.ts +0 -11
  185. package/dist/beta.d.ts +0 -12
  186. package/lib/beta.d.ts +0 -12
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fluidframework/odsp-driver",
3
- "version": "2.1.0-276326",
3
+ "version": "2.1.0-281041",
4
4
  "description": "Socket storage implementation for SPO and ODC",
5
5
  "homepage": "https://fluidframework.com",
6
6
  "repository": {
@@ -23,16 +23,6 @@
23
23
  "default": "./dist/index.js"
24
24
  }
25
25
  },
26
- "./beta": {
27
- "import": {
28
- "types": "./lib/beta.d.ts",
29
- "default": "./lib/index.js"
30
- },
31
- "require": {
32
- "types": "./dist/beta.d.ts",
33
- "default": "./dist/index.js"
34
- }
35
- },
36
26
  "./legacy": {
37
27
  "import": {
38
28
  "types": "./lib/legacy.d.ts",
@@ -77,28 +67,28 @@
77
67
  "temp-directory": "nyc/.nyc_output"
78
68
  },
79
69
  "dependencies": {
80
- "@fluid-internal/client-utils": "2.1.0-276326",
81
- "@fluidframework/core-interfaces": "2.1.0-276326",
82
- "@fluidframework/core-utils": "2.1.0-276326",
83
- "@fluidframework/driver-base": "2.1.0-276326",
84
- "@fluidframework/driver-definitions": "2.1.0-276326",
85
- "@fluidframework/driver-utils": "2.1.0-276326",
86
- "@fluidframework/odsp-doclib-utils": "2.1.0-276326",
87
- "@fluidframework/odsp-driver-definitions": "2.1.0-276326",
88
- "@fluidframework/telemetry-utils": "2.1.0-276326",
70
+ "@fluid-internal/client-utils": "2.1.0-281041",
71
+ "@fluidframework/core-interfaces": "2.1.0-281041",
72
+ "@fluidframework/core-utils": "2.1.0-281041",
73
+ "@fluidframework/driver-base": "2.1.0-281041",
74
+ "@fluidframework/driver-definitions": "2.1.0-281041",
75
+ "@fluidframework/driver-utils": "2.1.0-281041",
76
+ "@fluidframework/odsp-doclib-utils": "2.1.0-281041",
77
+ "@fluidframework/odsp-driver-definitions": "2.1.0-281041",
78
+ "@fluidframework/telemetry-utils": "2.1.0-281041",
89
79
  "node-fetch": "^2.6.9",
90
80
  "socket.io-client": "^4.7.3",
91
81
  "uuid": "^9.0.0"
92
82
  },
93
83
  "devDependencies": {
94
84
  "@arethetypeswrong/cli": "^0.15.2",
95
- "@biomejs/biome": "^1.7.3",
96
- "@fluid-internal/mocha-test-setup": "2.1.0-276326",
97
- "@fluid-tools/build-cli": "^0.39.0",
85
+ "@biomejs/biome": "~1.8.3",
86
+ "@fluid-internal/mocha-test-setup": "2.1.0-281041",
87
+ "@fluid-tools/build-cli": "^0.40.0",
98
88
  "@fluidframework/build-common": "^2.0.3",
99
- "@fluidframework/build-tools": "^0.39.0",
89
+ "@fluidframework/build-tools": "^0.40.0",
100
90
  "@fluidframework/eslint-config-fluid": "^5.3.0",
101
- "@fluidframework/odsp-driver-previous": "npm:@fluidframework/odsp-driver@2.0.0-rc.5.0.0",
91
+ "@fluidframework/odsp-driver-previous": "npm:@fluidframework/odsp-driver@2.0.0",
102
92
  "@microsoft/api-extractor": "^7.45.1",
103
93
  "@types/mocha": "^9.1.1",
104
94
  "@types/node": "^18.19.0",
@@ -127,36 +117,36 @@
127
117
  "api-extractor:commonjs": "flub generate entrypoints --outDir ./dist",
128
118
  "api-extractor:esnext": "flub generate entrypoints --outDir ./lib --node10TypeCompat",
129
119
  "build": "fluid-build . --task build",
120
+ "build:api-reports": "concurrently \"npm:build:api-reports:*\"",
121
+ "build:api-reports:current": "api-extractor run --local --config api-extractor/api-extractor.current.json",
122
+ "build:api-reports:legacy": "api-extractor run --local --config api-extractor/api-extractor.legacy.json",
130
123
  "build:commonjs": "fluid-build . --task commonjs",
131
124
  "build:compile": "fluid-build . --task compile",
132
- "build:docs": "concurrently \"npm:build:docs:*\"",
133
- "build:docs:current": "api-extractor run --local",
134
- "build:docs:legacy": "api-extractor run --local --config api-extractor/api-extractor.legacy.json",
125
+ "build:docs": "api-extractor run --local",
135
126
  "build:esnext": "tsc --project ./tsconfig.json",
136
127
  "build:genver": "gen-version",
137
128
  "build:test": "npm run build:test:esm && npm run build:test:cjs",
138
129
  "build:test:cjs": "fluid-tsc commonjs --project ./src/test/tsconfig.cjs.json",
139
130
  "build:test:esm": "tsc --project ./src/test/tsconfig.json",
140
131
  "check:are-the-types-wrong": "attw --pack .",
141
- "check:biome": "biome check . --formatter-enabled=true",
132
+ "check:biome": "biome check .",
142
133
  "check:exports": "concurrently \"npm:check:exports:*\"",
143
134
  "check:exports:bundle-release-tags": "api-extractor run --config api-extractor/api-extractor-lint-bundle.json",
144
- "check:exports:cjs:beta": "api-extractor run --config api-extractor/api-extractor-lint-beta.cjs.json",
145
135
  "check:exports:cjs:legacy": "api-extractor run --config api-extractor/api-extractor-lint-legacy.cjs.json",
146
136
  "check:exports:cjs:public": "api-extractor run --config api-extractor/api-extractor-lint-public.cjs.json",
147
- "check:exports:esm:beta": "api-extractor run --config api-extractor/api-extractor-lint-beta.esm.json",
148
137
  "check:exports:esm:legacy": "api-extractor run --config api-extractor/api-extractor-lint-legacy.esm.json",
149
138
  "check:exports:esm:public": "api-extractor run --config api-extractor/api-extractor-lint-public.esm.json",
150
139
  "check:format": "npm run check:biome",
151
140
  "check:prettier": "prettier --check . --cache --ignore-path ../../../.prettierignore",
152
- "ci:build:docs": "concurrently \"npm:ci:build:docs:*\"",
153
- "ci:build:docs:current": "api-extractor run",
154
- "ci:build:docs:legacy": "api-extractor run --config api-extractor/api-extractor.legacy.json",
141
+ "ci:build:api-reports": "concurrently \"npm:ci:build:api-reports:*\"",
142
+ "ci:build:api-reports:current": "api-extractor run --config api-extractor/api-extractor.current.json",
143
+ "ci:build:api-reports:legacy": "api-extractor run --config api-extractor/api-extractor.legacy.json",
144
+ "ci:build:docs": "api-extractor run",
155
145
  "clean": "rimraf --glob dist lib \"*.d.ts\" \"**/*.tsbuildinfo\" \"**/*.build.log\" _api-extractor-temp nyc",
156
146
  "eslint": "eslint --format stylish src",
157
147
  "eslint:fix": "eslint --format stylish src --fix --fix-type problem,suggestion,layout",
158
148
  "format": "npm run format:biome",
159
- "format:biome": "biome check . --formatter-enabled=true --apply",
149
+ "format:biome": "biome check . --write",
160
150
  "format:prettier": "prettier --write . --cache --ignore-path ../../../.prettierignore",
161
151
  "lint": "fluid-build . --task lint",
162
152
  "lint:fix": "fluid-build . --task eslint:fix --task format",
@@ -47,7 +47,8 @@ export class ReadBuffer {
47
47
  let length = lengthArg;
48
48
  while (length > 0) {
49
49
  assert(!this.eof, 0x223 /* "unexpected end of buffer" */);
50
- res += this.data[this.index] * multiplier;
50
+ // TODO Why are we non null asserting here?
51
+ res += this.data[this.index]! * multiplier;
51
52
  this.index++;
52
53
  multiplier *= 256;
53
54
  length--;
@@ -32,7 +32,8 @@ export class WriteBuffer {
32
32
  let index = 0;
33
33
  const oldData = this.data;
34
34
  while (index < length) {
35
- newData[index] = oldData[index];
35
+ // TODO Why are we non null asserting here?
36
+ newData[index] = oldData[index]!;
36
37
  index++;
37
38
  }
38
39
  this.data = newData;
@@ -252,7 +253,8 @@ function serializeNodeCore(
252
253
  buffer.write(child, len);
253
254
  }
254
255
  } else if (typeof child === "boolean") {
255
- buffer.write(boolToCodeMap[child ? 1 : 0]);
256
+ // TODO Why are we non null asserting here?
257
+ buffer.write(boolToCodeMap[child ? 1 : 0]!);
256
258
  } else {
257
259
  assert(child._stringElement, 0x3dd /* Unsupported node type */);
258
260
  if (child.dictionary) {
@@ -70,8 +70,10 @@ function readBlobSection(node: NodeTypes): {
70
70
  */
71
71
  slowBlobStructureCount += 1;
72
72
  const records = getNodeProps(blob);
73
- assertBlobCoreInstance(records.data, "data should be of BlobCore type");
74
- const id = getStringInstance(records.id, "blob id should be string");
73
+ // TODO why are we non null asserting here?
74
+ assertBlobCoreInstance(records.data!, "data should be of BlobCore type");
75
+ // TODO why are we non null asserting here?
76
+ const id = getStringInstance(records.id!, "blob id should be string");
75
77
  blobContents.set(id, records.data.arrayBuffer);
76
78
  }
77
79
  }
@@ -86,8 +88,10 @@ function readOpsSection(node: NodeTypes): ISequencedDocumentMessage[] {
86
88
  assertNodeCoreInstance(node, "Deltas should be of type NodeCore");
87
89
  const ops: ISequencedDocumentMessage[] = [];
88
90
  const records = getNodeProps(node);
89
- assertNumberInstance(records.firstSequenceNumber, "Seq number should be a number");
90
- assertNodeCoreInstance(records.deltas, "Deltas should be a Node");
91
+ // TODO Why are we non null asserting here?
92
+ assertNumberInstance(records.firstSequenceNumber!, "Seq number should be a number");
93
+ // TODO Why are we non null asserting here?
94
+ assertNodeCoreInstance(records.deltas!, "Deltas should be a Node");
91
95
  for (let i = 0; i < records.deltas.length; ++i) {
92
96
  // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
93
97
  ops.push(JSON.parse(records.deltas.getString(i)));
@@ -96,7 +100,8 @@ function readOpsSection(node: NodeTypes): ISequencedDocumentMessage[] {
96
100
  // when there are no ops. So just make the code resilient to that bug. Service has also
97
101
  // fixed that bug.
98
102
  assert(
99
- ops.length === 0 || records.firstSequenceNumber.valueOf() === ops[0].sequenceNumber,
103
+ // Non null asserting here because of the length check
104
+ ops.length === 0 || records.firstSequenceNumber.valueOf() === ops[0]!.sequenceNumber,
100
105
  0x280 /* "Validate first op seq number" */,
101
106
  );
102
107
  return ops;
@@ -109,8 +114,10 @@ function readOpsSection(node: NodeTypes): ISequencedDocumentMessage[] {
109
114
  function readTreeSection(node: NodeCore): {
110
115
  snapshotTree: ISnapshotTree;
111
116
  slowTreeStructureCount: number;
117
+ treeStructureCountWithGroupId: number;
112
118
  } {
113
119
  let slowTreeStructureCount = 0;
120
+ let treeStructureCountWithGroupId = 0;
114
121
  const trees: Record<string, ISnapshotTree> = {};
115
122
  const snapshotTree: ISnapshotTree = {
116
123
  blobs: {},
@@ -141,6 +148,7 @@ function readTreeSection(node: NodeCore): {
141
148
  const result = readTreeSection(treeNode.getNode(3));
142
149
  trees[treeNode.getString(1)] = result.snapshotTree;
143
150
  slowTreeStructureCount += result.slowTreeStructureCount;
151
+ treeStructureCountWithGroupId += result.treeStructureCountWithGroupId;
144
152
  continue;
145
153
  }
146
154
  // "name": <node name>
@@ -173,6 +181,7 @@ function readTreeSection(node: NodeCore): {
173
181
  const result = readTreeSection(treeNode.getNode(5));
174
182
  trees[treeNode.getString(1)] = result.snapshotTree;
175
183
  slowTreeStructureCount += result.slowTreeStructureCount;
184
+ treeStructureCountWithGroupId += result.treeStructureCountWithGroupId;
176
185
  assert(treeNode.getBool(3), 0x3db /* Unreferenced if present should be true */);
177
186
  snapshotTree.unreferenced = true;
178
187
  continue;
@@ -188,7 +197,7 @@ function readTreeSection(node: NodeCore): {
188
197
  /**
189
198
  * More generalized workflow
190
199
  */
191
- slowTreeStructureCount += 1;
200
+ slowTreeStructureCount++;
192
201
  const records = getNodeProps(treeNode);
193
202
 
194
203
  if (records.unreferenced !== undefined) {
@@ -197,7 +206,8 @@ function readTreeSection(node: NodeCore): {
197
206
  snapshotTree.unreferenced = true;
198
207
  }
199
208
 
200
- const path = getStringInstance(records.name, "Path name should be string");
209
+ // TODO Why are we non null asserting here?
210
+ const path = getStringInstance(records.name!, "Path name should be string");
201
211
  if (records.value !== undefined) {
202
212
  snapshotTree.blobs[path] = getStringInstance(
203
213
  records.value,
@@ -210,14 +220,17 @@ function readTreeSection(node: NodeCore): {
210
220
  trees[path] = result.snapshotTree;
211
221
  if (records.groupId !== undefined) {
212
222
  const groupId = getStringInstance(records.groupId, "groupId should be a string");
213
- trees[path].groupId = groupId;
223
+ // Non null asserting since trees[path] is already created
224
+ trees[path]!.groupId = groupId;
225
+ treeStructureCountWithGroupId++;
214
226
  }
215
227
  slowTreeStructureCount += result.slowTreeStructureCount;
228
+ treeStructureCountWithGroupId += result.treeStructureCountWithGroupId;
216
229
  } else {
217
230
  trees[path] = { blobs: {}, trees: {} };
218
231
  }
219
232
  }
220
- return { snapshotTree, slowTreeStructureCount };
233
+ return { snapshotTree, slowTreeStructureCount, treeStructureCountWithGroupId };
221
234
  }
222
235
 
223
236
  /**
@@ -228,19 +241,25 @@ function readSnapshotSection(node: NodeTypes): {
228
241
  sequenceNumber: number;
229
242
  snapshotTree: ISnapshotTree;
230
243
  slowTreeStructureCount: number;
244
+ treeStructureCountWithGroupId: number;
231
245
  } {
232
246
  assertNodeCoreInstance(node, "Snapshot should be of type NodeCore");
233
247
  const records = getNodeProps(node);
234
248
 
235
- assertNodeCoreInstance(records.treeNodes, "TreeNodes should be of type NodeCore");
236
- assertNumberInstance(records.sequenceNumber, "sequenceNumber should be of type number");
237
- const { snapshotTree, slowTreeStructureCount } = readTreeSection(records.treeNodes);
238
- snapshotTree.id = getStringInstance(records.id, "snapshotId should be string");
249
+ // TODO Why are we non null asserting here?
250
+ assertNodeCoreInstance(records.treeNodes!, "TreeNodes should be of type NodeCore");
251
+ // TODO Why are we non null asserting here?
252
+ assertNumberInstance(records.sequenceNumber!, "sequenceNumber should be of type number");
253
+ const { snapshotTree, slowTreeStructureCount, treeStructureCountWithGroupId } =
254
+ readTreeSection(records.treeNodes);
255
+ // TODO Why are we non null asserting here?
256
+ snapshotTree.id = getStringInstance(records.id!, "snapshotId should be string");
239
257
  const sequenceNumber = records.sequenceNumber.valueOf();
240
258
  return {
241
259
  sequenceNumber,
242
260
  snapshotTree,
243
261
  slowTreeStructureCount,
262
+ treeStructureCountWithGroupId,
244
263
  };
245
264
  }
246
265
 
@@ -260,8 +279,10 @@ export function parseCompactSnapshotResponse(
260
279
 
261
280
  const records = getNodeProps(root);
262
281
 
263
- const mrv = getStringInstance(records.mrv, "minReadVersion should be string");
264
- const cv = getStringInstance(records.cv, "createVersion should be string");
282
+ // TODO Why are we non null asserting here?
283
+ const mrv = getStringInstance(records.mrv!, "minReadVersion should be string");
284
+ // TODO Why are we non null asserting here?
285
+ const cv = getStringInstance(records.cv!, "createVersion should be string");
265
286
  if (records.lsn !== undefined) {
266
287
  assertNumberInstance(records.lsn, "lsn should be a number");
267
288
  }
@@ -280,9 +301,11 @@ export function parseCompactSnapshotResponse(
280
301
  );
281
302
 
282
303
  const [snapshot, durationSnapshotTree] = measure(() =>
283
- readSnapshotSection(records.snapshot),
304
+ // TODO Why are we non null asserting here?
305
+ readSnapshotSection(records.snapshot!),
284
306
  );
285
- const [blobContents, durationBlobs] = measure(() => readBlobSection(records.blobs));
307
+ // TODO Why are we non null asserting here?
308
+ const [blobContents, durationBlobs] = measure(() => readBlobSection(records.blobs!));
286
309
 
287
310
  return {
288
311
  ...snapshot,
@@ -296,6 +319,7 @@ export function parseCompactSnapshotResponse(
296
319
  durationBlobs,
297
320
  slowTreeStructureCount: snapshot.slowTreeStructureCount,
298
321
  slowBlobStructureCount: blobContents.slowBlobStructureCount,
322
+ treeStructureCountWithGroupId: snapshot.treeStructureCountWithGroupId,
299
323
  },
300
324
  };
301
325
  }
@@ -130,7 +130,8 @@ function writeSnapshotSection(
130
130
  function writeOpsSection(rootNode: NodeCore, ops: ISequencedDocumentMessage[]): void {
131
131
  let firstSequenceNumber: number | undefined;
132
132
  if (ops.length > 0) {
133
- firstSequenceNumber = ops[0].sequenceNumber;
133
+ // Non null asserting here because of the length check above
134
+ firstSequenceNumber = ops[0]!.sequenceNumber;
134
135
  }
135
136
  if (firstSequenceNumber !== undefined) {
136
137
  rootNode.addDictionaryString("deltas");
@@ -162,7 +163,8 @@ export function convertToCompactSnapshot(snapshotContents: ISnapshot): Uint8Arra
162
163
  if (latestSequenceNumber === undefined) {
163
164
  latestSequenceNumber =
164
165
  snapshotContents.ops.length > 0
165
- ? snapshotContents.ops[snapshotContents.ops.length - 1].sequenceNumber
166
+ ? // Non null asserting here because of the length check above
167
+ snapshotContents.ops[snapshotContents.ops.length - 1]!.sequenceNumber
166
168
  : snapshotContents.sequenceNumber;
167
169
  }
168
170
 
package/src/createFile.ts CHANGED
@@ -16,6 +16,7 @@ import {
16
16
  } from "@fluidframework/odsp-driver-definitions/internal";
17
17
  import {
18
18
  ITelemetryLoggerExt,
19
+ loggerToMonitoringContext,
19
20
  PerformanceEvent,
20
21
  } from "@fluidframework/telemetry-utils/internal";
21
22
 
@@ -36,6 +37,7 @@ import {
36
37
  buildOdspShareLinkReqParams,
37
38
  createCacheSnapshotKey,
38
39
  getWithRetryForTokenRefresh,
40
+ snapshotWithLoadingGroupIdSupported,
39
41
  } from "./odspUtils.js";
40
42
  import { pkgVersion as driverVersion } from "./packageVersion.js";
41
43
  import { runWithRetry } from "./retryUtils.js";
@@ -110,7 +112,13 @@ export async function createNewFluidFile(
110
112
  summaryHandle,
111
113
  );
112
114
  // caching the converted summary
113
- await epochTracker.put(createCacheSnapshotKey(odspResolvedUrl), snapshot);
115
+ await epochTracker.put(
116
+ createCacheSnapshotKey(
117
+ odspResolvedUrl,
118
+ snapshotWithLoadingGroupIdSupported(loggerToMonitoringContext(logger).config),
119
+ ),
120
+ snapshot,
121
+ );
114
122
  }
115
123
  return odspResolvedUrl;
116
124
  }
@@ -11,7 +11,10 @@ import {
11
11
  IOdspResolvedUrl,
12
12
  InstrumentedStorageTokenFetcher,
13
13
  } from "@fluidframework/odsp-driver-definitions/internal";
14
- import { ITelemetryLoggerExt } from "@fluidframework/telemetry-utils/internal";
14
+ import {
15
+ ITelemetryLoggerExt,
16
+ loggerToMonitoringContext,
17
+ } from "@fluidframework/telemetry-utils/internal";
15
18
 
16
19
  import { IWriteSummaryResponse } from "./contracts.js";
17
20
  import { ClpCompliantAppHeader } from "./contractsPublic.js";
@@ -24,7 +27,11 @@ import { createOdspUrl } from "./createOdspUrl.js";
24
27
  import { EpochTracker } from "./epochTracker.js";
25
28
  import { OdspDriverUrlResolver } from "./odspDriverUrlResolver.js";
26
29
  import { getApiRoot } from "./odspUrlHelper.js";
27
- import { IExistingFileInfo, createCacheSnapshotKey } from "./odspUtils.js";
30
+ import {
31
+ IExistingFileInfo,
32
+ createCacheSnapshotKey,
33
+ snapshotWithLoadingGroupIdSupported,
34
+ } from "./odspUtils.js";
28
35
 
29
36
  /**
30
37
  * Creates a new Fluid container on an existing file.
@@ -87,7 +94,13 @@ export async function createNewContainerOnExistingFile(
87
94
  summaryHandle,
88
95
  );
89
96
  // caching the converted summary
90
- await epochTracker.put(createCacheSnapshotKey(odspResolvedUrl), snapshot);
97
+ await epochTracker.put(
98
+ createCacheSnapshotKey(
99
+ odspResolvedUrl,
100
+ snapshotWithLoadingGroupIdSupported(loggerToMonitoringContext(logger).config),
101
+ ),
102
+ snapshot,
103
+ );
91
104
  }
92
105
 
93
106
  return odspResolvedUrl;
@@ -4,7 +4,7 @@
4
4
  */
5
5
 
6
6
  import { Uint8ArrayToString, stringToBuffer } from "@fluid-internal/client-utils";
7
- import { unreachableCase } from "@fluidframework/core-utils/internal";
7
+ import { assert, unreachableCase } from "@fluidframework/core-utils/internal";
8
8
  import {
9
9
  ISummaryBlob,
10
10
  ISummaryTree,
@@ -72,7 +72,8 @@ function convertCreateNewSummaryTreeToTreeAndBlobsCore(
72
72
  };
73
73
  const keys = Object.keys(summary.tree);
74
74
  for (const key of keys) {
75
- const summaryObject = summary.tree[key];
75
+ // Non null asserting for now this should change to Object.entries
76
+ const summaryObject = summary.tree[key]!;
76
77
 
77
78
  switch (summaryObject.type) {
78
79
  case SummaryType.Tree: {
@@ -149,7 +150,9 @@ function convertSummaryToSnapshotTreeForCreateNew(summary: ISummaryTree): IOdspS
149
150
 
150
151
  const keys = Object.keys(summary.tree);
151
152
  for (const key of keys) {
152
- const summaryObject = summary.tree[key];
153
+ assert(!key.includes("/"), "id should not include slashes");
154
+ // Non null asserting for now this should change to Object.entries
155
+ const summaryObject = summary.tree[key]!;
153
156
 
154
157
  let value: OdspSummaryTreeValue;
155
158
  // Tracks if an entry is unreferenced. Currently, only tree entries can be marked as unreferenced. If the
@@ -188,7 +191,7 @@ function convertSummaryToSnapshotTreeForCreateNew(summary: ISummaryTree): IOdspS
188
191
  }
189
192
 
190
193
  const entry: OdspSummaryTreeEntry = {
191
- path: encodeURIComponent(key),
194
+ path: key,
192
195
  type: getGitType(summaryObject),
193
196
  value,
194
197
  unreferenced,
@@ -21,6 +21,7 @@ import {
21
21
  OdspErrorTypes,
22
22
  maximumCacheDurationMs,
23
23
  snapshotKey,
24
+ snapshotWithLoadingGroupIdKey,
24
25
  } from "@fluidframework/odsp-driver-definitions/internal";
25
26
  import {
26
27
  ITelemetryLoggerExt,
@@ -149,7 +150,7 @@ export class EpochTracker implements IPersistedFileCache {
149
150
  }
150
151
  // Expire the cached snapshot if it's older than snapshotCacheExpiryTimeoutMs and immediately
151
152
  // expire all old caches that do not have cacheEntryTime
152
- if (entry.type === snapshotKey) {
153
+ if (entry.type === snapshotKey || entry.type === snapshotWithLoadingGroupIdKey) {
153
154
  // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access
154
155
  const cacheTime = value.value?.cacheEntryTime;
155
156
  const currentTime = Date.now();
@@ -180,7 +181,7 @@ export class EpochTracker implements IPersistedFileCache {
180
181
  assert(this._fluidEpoch !== undefined, 0x1dd /* "no epoch" */);
181
182
  // For snapshots, the value should have the cacheEntryTime.
182
183
  // This will be used to expire snapshots older than snapshotCacheExpiryTimeoutMs.
183
- if (entry.type === snapshotKey) {
184
+ if (entry.type === snapshotKey || entry.type === snapshotWithLoadingGroupIdKey) {
184
185
  // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access
185
186
  value.cacheEntryTime = value.cacheEntryTime ?? Date.now();
186
187
  }
@@ -522,7 +523,7 @@ export class EpochTrackerWithRedemption extends EpochTracker {
522
523
  let result = super.get(entry);
523
524
 
524
525
  // equivalence of what happens in fetchAndParseAsJSON()
525
- if (entry.type === snapshotKey) {
526
+ if (entry.type === snapshotKey || entry.type === snapshotWithLoadingGroupIdKey) {
526
527
  result = result
527
528
  .then((value) => {
528
529
  // If there is nothing in cache, we need to wait for network call to complete (and do redemption)
@@ -77,7 +77,7 @@ export enum SnapshotFormatSupportType {
77
77
  * @param snapshotUrl - snapshot url from where the odsp snapshot will be fetched
78
78
  * @param versionId - id of specific snapshot to be fetched
79
79
  * @param fetchFullSnapshot - whether we want to fetch full snapshot(with blobs)
80
- * @param forceAccessTokenViaAuthorizationHeader - @deprecated Not used, true value always used instead. Whether to force passing given token via authorization header
80
+ * @param forceAccessTokenViaAuthorizationHeader - Deprecated and not used, true value always used instead. Whether to force passing given token via authorization header
81
81
  * @param snapshotDownloader - Implementation of the get/post methods used to fetch the snapshot. snapshotDownloader is responsible for generating the appropriate headers (including Authorization header) as well as handling any token refreshes before retrying.
82
82
  * @returns A promise of the snapshot and the status code of the response
83
83
  */
@@ -453,11 +453,17 @@ async function fetchLatestSnapshotCore(
453
453
  const props = snapshotContents.telemetryProps;
454
454
  const slowTreeParseCodePaths = props.slowTreeStructureCount ?? 0;
455
455
  const slowBlobParseCodePaths = props.slowBlobStructureCount ?? 0;
456
- if (slowTreeParseCodePaths > 10 || slowBlobParseCodePaths > 10) {
456
+ const treeStructureCountWithGroupId = props.treeStructureCountWithGroupId ?? 0;
457
+ // As trees with groupId go through normal parsing, so exclude them.
458
+ if (
459
+ slowTreeParseCodePaths - treeStructureCountWithGroupId > 10 ||
460
+ slowBlobParseCodePaths > 10
461
+ ) {
457
462
  logger.sendErrorEvent({
458
463
  eventName: "SlowSnapshotParseCodePaths",
459
464
  slowTreeStructureCount: slowTreeParseCodePaths,
460
465
  slowBlobStructureCount: slowBlobParseCodePaths,
466
+ treeStructureCountWithGroupId,
461
467
  });
462
468
  }
463
469
  parsedSnapshotContents = { ...odspResponse, content: snapshotContents };
@@ -499,7 +505,8 @@ async function fetchLatestSnapshotCore(
499
505
  const sequenceNumber: number = snapshot.sequenceNumber ?? 0;
500
506
  const seqNumberFromOps =
501
507
  snapshot.ops && snapshot.ops.length > 0
502
- ? snapshot.ops[0].sequenceNumber - 1
508
+ ? // Non null asserting here because of the length check above
509
+ snapshot.ops[0]!.sequenceNumber - 1
503
510
  : undefined;
504
511
 
505
512
  if (
@@ -38,7 +38,8 @@ export class LocalOdspDeltaStorageService implements IDocumentDeltaStorageServic
38
38
  );
39
39
  validateMessages("cached", messages, from, this.logger);
40
40
 
41
- if (messages.length === 0 || messages[0].sequenceNumber !== from) {
41
+ // Non null asserting here because of the length check
42
+ if (messages.length === 0 || messages[0]!.sequenceNumber !== from) {
42
43
  this.snapshotOps = [];
43
44
  }
44
45
  this.snapshotOps = this.snapshotOps.filter(
@@ -472,7 +472,8 @@ export class OdspDelayLoadedDeltaStream {
472
472
  }
473
473
 
474
474
  private emitMetaDataUpdateEvent(metadata: Record<string, string>): void {
475
- const label = JSON.parse(metadata.sensitivityLabelsInfo) as {
475
+ // TODO Why are we non null asserting here?
476
+ const label = JSON.parse(metadata.sensitivityLabelsInfo!) as {
476
477
  labels: unknown;
477
478
  timestamp: number;
478
479
  };
@@ -481,7 +482,8 @@ export class OdspDelayLoadedDeltaStream {
481
482
  if (time > this.labelUpdateTimestamp) {
482
483
  this.labelUpdateTimestamp = time;
483
484
  this.metadataUpdateHandler({
484
- sensitivityLabelsInfo: metadata.sensitivityLabelsInfo,
485
+ // TODO Why are we non null asserting here?
486
+ sensitivityLabelsInfo: metadata.sensitivityLabelsInfo!,
485
487
  });
486
488
  }
487
489
  }
@@ -106,7 +106,8 @@ export class OdspDeltaStorageService {
106
106
  clearTimeout(timer);
107
107
  const deltaStorageResponse = response.content;
108
108
  const messages =
109
- deltaStorageResponse.value.length > 0 && "op" in deltaStorageResponse.value[0]
109
+ // Non null asserting here because of the length check
110
+ deltaStorageResponse.value.length > 0 && "op" in deltaStorageResponse.value[0]!
110
111
  ? (deltaStorageResponse.value as ISequencedDeltaOpMessage[]).map(
111
112
  (operation) => operation.op,
112
113
  )
@@ -187,7 +188,8 @@ export class OdspDeltaStorageWithCache implements IDocumentDeltaStorageService {
187
188
  (op) => op.sequenceNumber >= from && op.sequenceNumber < to,
188
189
  );
189
190
  validateMessages("cached", messages, from, this.logger);
190
- if (messages.length > 0 && messages[0].sequenceNumber === from) {
191
+ // Non null asserting here because of the length check
192
+ if (messages.length > 0 && messages[0]!.sequenceNumber === from) {
191
193
  this.snapshotOps = this.snapshotOps.filter((op) => op.sequenceNumber >= to);
192
194
  opsFromSnapshot += messages.length;
193
195
  return { messages, partialResult: true };
@@ -591,8 +591,10 @@ export class OdspDocumentDeltaConnection extends DocumentDeltaConnection {
591
591
  if (messages !== undefined && messages.length > 0) {
592
592
  this.logger.sendPerformanceEvent({
593
593
  ...common,
594
- first: messages[0].sequenceNumber,
595
- last: messages[messages.length - 1].sequenceNumber,
594
+ // Non null asserting here because of the length check above
595
+ first: messages[0]!.sequenceNumber,
596
+ // Non null asserting here because of the length check above
597
+ last: messages[messages.length - 1]!.sequenceNumber,
596
598
  length: messages.length,
597
599
  });
598
600
  this.emit("op", this.documentId, messages);
@@ -32,6 +32,7 @@ import {
32
32
  loggerToMonitoringContext,
33
33
  normalizeError,
34
34
  overwriteStack,
35
+ type IConfigProvider,
35
36
  } from "@fluidframework/telemetry-utils/internal";
36
37
 
37
38
  import {
@@ -62,6 +63,7 @@ import {
62
63
  getWithRetryForTokenRefresh,
63
64
  isInstanceOfISnapshot,
64
65
  isSnapshotFetchForLoadingGroup,
66
+ snapshotWithLoadingGroupIdSupported,
65
67
  useLegacyFlowWithoutGroupsForSnapshotFetch,
66
68
  type TokenFetchOptionsEx,
67
69
  } from "./odspUtils.js";
@@ -85,6 +87,7 @@ export class OdspDocumentStorageService extends OdspDocumentStorageServiceBase {
85
87
  private readonly snapshotUrl: string | undefined;
86
88
  private readonly attachmentPOSTUrl: string | undefined;
87
89
  private readonly attachmentGETUrl: string | undefined;
90
+ private readonly config: IConfigProvider;
88
91
  // Driver specified limits for snapshot size and time.
89
92
  /**
90
93
  * NOTE: While commit cfff6e3 added restrictions to prevent large payloads, snapshot failures will continue to
@@ -115,6 +118,7 @@ export class OdspDocumentStorageService extends OdspDocumentStorageServiceBase {
115
118
  this.snapshotUrl = this.odspResolvedUrl.endpoints.snapshotStorageUrl;
116
119
  this.attachmentPOSTUrl = this.odspResolvedUrl.endpoints.attachmentPOSTStorageUrl;
117
120
  this.attachmentGETUrl = this.odspResolvedUrl.endpoints.attachmentGETStorageUrl;
121
+ this.config = loggerToMonitoringContext(logger).config;
118
122
  }
119
123
 
120
124
  public get isFirstSnapshotFromNetwork(): boolean | undefined {
@@ -278,7 +282,12 @@ export class OdspDocumentStorageService extends OdspDocumentStorageServiceBase {
278
282
  // Here's the logic to grab the persistent cache snapshot implemented by the host
279
283
  // Epoch tracker is responsible for communicating with the persistent cache, handling epochs and cache versions
280
284
  const cachedSnapshotP: Promise<ISnapshot | undefined> = this.epochTracker
281
- .get(createCacheSnapshotKey(this.odspResolvedUrl))
285
+ .get(
286
+ createCacheSnapshotKey(
287
+ this.odspResolvedUrl,
288
+ snapshotWithLoadingGroupIdSupported(this.config),
289
+ ),
290
+ )
282
291
  .then(
283
292
  async (
284
293
  // eslint-disable-next-line import/no-deprecated
@@ -564,7 +573,10 @@ export class OdspDocumentStorageService extends OdspDocumentStorageServiceBase {
564
573
  // for initial snapshot, don't consult the prefetch cache.
565
574
  if (!this.hostPolicy.avoidPrefetchSnapshotCache && this.firstSnapshotFetchCall) {
566
575
  const prefetchCacheKey = getKeyForCacheEntry(
567
- createCacheSnapshotKey(this.odspResolvedUrl),
576
+ createCacheSnapshotKey(
577
+ this.odspResolvedUrl,
578
+ snapshotWithLoadingGroupIdSupported(this.config),
579
+ ),
568
580
  );
569
581
  const result = await this.cache.snapshotPrefetchResultCache
570
582
  ?.get(prefetchCacheKey)
@@ -627,7 +639,10 @@ export class OdspDocumentStorageService extends OdspDocumentStorageServiceBase {
627
639
  };
628
640
  const putInCache = async (valueWithEpoch: IVersionedValueWithEpoch): Promise<void> => {
629
641
  return this.cache.persistedCache.put(
630
- createCacheSnapshotKey(this.odspResolvedUrl),
642
+ createCacheSnapshotKey(
643
+ this.odspResolvedUrl,
644
+ snapshotWithLoadingGroupIdSupported(this.config),
645
+ ),
631
646
  // Epoch tracker will add the epoch and version to the value here. So just send value to cache.
632
647
  valueWithEpoch.value,
633
648
  );