Skip to content

Commit c856a1d

Browse files
agarwal-navinanthony-murphy-agent
authored andcommitted
Add getStorageTree to implementation of IChannelStorageService (microsoft#25723)
`getSnapshotTree` was added to `IChannelStorageService` in microsoft#24970. This PR adds implementations of `getSnapshotTree` to the implementations of `IChannelStorageService`. It also removes `LocalChannelStorageService` which implemented this interface but is unused.
1 parent 854dcbd commit c856a1d

File tree

8 files changed

+223
-150
lines changed

8 files changed

+223
-150
lines changed

packages/runtime/datastore/src/localChannelStorageService.ts

Lines changed: 0 additions & 62 deletions
This file was deleted.

packages/runtime/datastore/src/test/localChannelStorageService.spec.ts

Lines changed: 0 additions & 83 deletions
This file was deleted.

packages/runtime/runtime-utils/src/objectstoragepartition.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
import { assert } from "@fluidframework/core-utils/internal";
77
import type { IChannelStorageService } from "@fluidframework/datastore-definitions/internal";
8+
import type { ISnapshotTree } from "@fluidframework/driver-definitions/internal";
89

910
/**
1011
* Returns a new IChannelStorageService that resolves the given `path` as root.
@@ -30,4 +31,8 @@ export class ObjectStoragePartition implements IChannelStorageService {
3031
public async list(path: string): Promise<string[]> {
3132
return this.storage.list(`${this.path}/${path}`);
3233
}
34+
35+
public getSnapshotTree(): ISnapshotTree | undefined {
36+
return this.storage.getSnapshotTree?.();
37+
}
3338
}

packages/runtime/test-runtime-utils/api-report/test-runtime-utils.legacy.beta.api.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -544,6 +544,8 @@ export class MockObjectStorageService implements IChannelStorageService {
544544
// (undocumented)
545545
contains(path: string): Promise<boolean>;
546546
// (undocumented)
547+
getSnapshotTree(): ISnapshotTree;
548+
// (undocumented)
547549
list(path: string): Promise<string[]>;
548550
// (undocumented)
549551
readBlob(path: string): Promise<ArrayBufferLike>;

packages/runtime/test-runtime-utils/package.json

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,14 @@
153153
"typescript": "~5.4.5"
154154
},
155155
"typeValidation": {
156-
"broken": {},
156+
"broken": {
157+
"Class_MockObjectStorageService": {
158+
"forwardCompat": false
159+
},
160+
"Class_MockSharedObjectServices": {
161+
"forwardCompat": false
162+
}
163+
},
157164
"entrypoint": "legacy"
158165
}
159166
}

packages/runtime/test-runtime-utils/src/mocks.ts

Lines changed: 58 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ import {
4545
ITreeEntry,
4646
MessageType,
4747
ISequencedDocumentMessage,
48+
type ISnapshotTree,
4849
} from "@fluidframework/driver-definitions/internal";
4950
import type { IIdCompressor } from "@fluidframework/id-compressor";
5051
import type {
@@ -1235,22 +1236,36 @@ export class MockEmptyDeltaConnection implements IDeltaConnection {
12351236
* @legacy @beta
12361237
*/
12371238
export class MockObjectStorageService implements IChannelStorageService {
1238-
public constructor(private readonly contents: { [key: string]: string }) {}
1239+
private readonly snapshotTree: ISnapshotTree;
1240+
1241+
/**
1242+
* @param contents - Key value pairs that represent a snapshot.
1243+
* The keys are the path to the contents of a blob in the snapshot tree. The corresponding values are its contents.
1244+
*
1245+
* @remarks
1246+
* The snapshot contents must not change after it has been passed here as the changes will not be reflected
1247+
* in the snapshot tree retrieved via `getSnapshotTree`.
1248+
*/
1249+
public constructor(private readonly contents: { [key: string]: string }) {
1250+
this.snapshotTree = createSnapshotTreeFromContents(contents);
1251+
}
12391252

12401253
public async readBlob(path: string): Promise<ArrayBufferLike> {
12411254
return stringToBuffer(this.contents[path], "utf8");
12421255
}
1243-
12441256
public async contains(path: string): Promise<boolean> {
12451257
return this.contents[path] !== undefined;
12461258
}
1247-
12481259
public async list(path: string): Promise<string[]> {
12491260
const pathPartsLength = getNormalizedObjectStoragePathParts(path).length;
12501261
return Object.keys(this.contents).filter(
12511262
(key) => key.startsWith(path) && key.split("/").length === pathPartsLength + 1,
12521263
);
12531264
}
1265+
1266+
public getSnapshotTree(): ISnapshotTree {
1267+
return this.snapshotTree;
1268+
}
12541269
}
12551270

12561271
/**
@@ -1297,3 +1312,43 @@ function setContentsFromSummaryTree(
12971312
}
12981313
}
12991314
}
1315+
1316+
/**
1317+
* Create an ISnapshotTree from contents object (reverse of setContentsFromSummaryTree)
1318+
* @param contents - Object with path/value pairs
1319+
* @returns ISnapshotTree representing the hierarchical structure
1320+
*/
1321+
export function createSnapshotTreeFromContents(contents: {
1322+
[key: string]: string;
1323+
}): ISnapshotTree {
1324+
const tree: ISnapshotTree = {
1325+
trees: {},
1326+
blobs: {},
1327+
};
1328+
1329+
for (const [path, content] of Object.entries(contents)) {
1330+
// Remove empty strings to handle leading, trailing, or consecutive slashes in the path.
1331+
const pathParts = path.split("/").filter((part) => part !== "");
1332+
let currentTree = tree;
1333+
1334+
// Navigate/create the tree structure for all but the last part
1335+
for (let i = 0; i < pathParts.length - 1; i++) {
1336+
const part = pathParts[i];
1337+
if (!currentTree.trees[part]) {
1338+
currentTree.trees[part] = {
1339+
trees: {},
1340+
blobs: {},
1341+
};
1342+
}
1343+
currentTree = currentTree.trees[part];
1344+
}
1345+
1346+
// Add the blob at the final location
1347+
const blobName = pathParts[pathParts.length - 1];
1348+
if (blobName !== undefined) {
1349+
currentTree.blobs[blobName] = content;
1350+
}
1351+
}
1352+
1353+
return tree;
1354+
}

0 commit comments

Comments
 (0)