Skip to content

Commit 954adff

Browse files
authored
Add tree-comparison demo (#17735)
1 parent 9a4d61b commit 954adff

32 files changed

+2013
-157
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
/*!
2+
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3+
* Licensed under the MIT License.
4+
*/
5+
6+
module.exports = {
7+
extends: [require.resolve("@fluidframework/eslint-config-fluid/minimal"), "prettier"],
8+
rules: {},
9+
};
+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
dist
2+
node_modules
3+
lib
+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
nyc
2+
*.log
3+
**/*.tsbuildinfo
4+
src/test
5+
dist/test
6+
**/_api-extractor-temp/**

examples/apps/tree-comparison/LICENSE

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
Copyright (c) Microsoft Corporation and contributors. All rights reserved.
2+
3+
MIT License
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.
+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# @fluid-example/tree-comparison
2+
3+
This example compares usage of the legacy SharedTree with the new SharedTree to build the same inventory list application.
4+
5+
<!-- AUTO-GENERATED-CONTENT:START (README_EXAMPLE_GETTING_STARTED_SECTION:usesTinylicious=TRUE) -->
6+
7+
<!-- prettier-ignore-start -->
8+
<!-- NOTE: This section is automatically generated using @fluid-tools/markdown-magic. Do not update these generated contents directly. -->
9+
10+
## Getting Started
11+
12+
You can run this example using the following steps:
13+
14+
1. Enable [corepack](https://nodejs.org/docs/latest-v16.x/api/corepack.html) by running `corepack enable`.
15+
1. Run `pnpm install` and `pnpm run build:fast --nolint` from the `FluidFramework` root directory.
16+
- For an even faster build, you can add the package name to the build command, like this:
17+
`pnpm run build:fast --nolint @fluid-example/tree-comparison`
18+
1. In a separate terminal, start a Tinylicious server by following the instructions in [Tinylicious](https://github.com/microsoft/FluidFramework/tree/main/server/tinylicious).
19+
1. Run `pnpm start` from this directory and open <http://localhost:8080> in a web browser to see the app running.
20+
21+
<!-- prettier-ignore-end -->
22+
23+
<!-- AUTO-GENERATED-CONTENT:END -->
24+
25+
## Testing
26+
27+
```bash
28+
npm run test:jest
29+
```
30+
31+
For in browser testing update `./jest-puppeteer.config.js` to:
32+
33+
```javascript
34+
launch: {
35+
dumpio: true, // output browser console to cmd line
36+
slowMo: 500,
37+
headless: false,
38+
},
39+
```
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/*!
2+
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3+
* Licensed under the MIT License.
4+
*/
5+
6+
module.exports = {
7+
server: {
8+
command: `npm run start:test -- --no-live-reload --port ${process.env["PORT"]}`,
9+
port: process.env["PORT"],
10+
launchTimeout: 10000,
11+
usedPortAction: "error",
12+
},
13+
launch: {
14+
args: ["--no-sandbox", "--disable-setuid-sandbox"], // https://github.com/puppeteer/puppeteer/blob/master/docs/troubleshooting.md#setting-up-chrome-linux-sandbox
15+
dumpio: process.env.FLUID_TEST_VERBOSE !== undefined, // output browser console to cmd line
16+
// slowMo: 500, // slows down process for easier viewing
17+
// headless: false, // run in the browser
18+
},
19+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/*!
2+
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3+
* Licensed under the MIT License.
4+
*/
5+
6+
// Get the test port from the global map and set it in env for this test
7+
const testTools = require("@fluidframework/test-tools");
8+
const { name } = require("./package.json");
9+
10+
mappedPort = testTools.getTestPort(name);
11+
process.env["PORT"] = mappedPort;
12+
13+
module.exports = {
14+
preset: "jest-puppeteer",
15+
globals: {
16+
PATH: `http://localhost:${mappedPort}`,
17+
},
18+
testMatch: ["**/?(*.)+(spec|test).[t]s"],
19+
testPathIgnorePatterns: ["/node_modules/", "dist"],
20+
transform: {
21+
"^.+\\.ts?$": "ts-jest",
22+
},
23+
reporters: [
24+
"default",
25+
[
26+
"jest-junit",
27+
{
28+
outputDirectory: "nyc",
29+
outputName: "jest-junit-report.xml",
30+
},
31+
],
32+
],
33+
};
+112
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
{
2+
"name": "@fluid-example/tree-comparison",
3+
"version": "2.0.0-internal.7.1.0",
4+
"private": true,
5+
"description": "Comparing API usage in legacy SharedTree and new SharedTree.",
6+
"homepage": "https://fluidframework.com",
7+
"repository": {
8+
"type": "git",
9+
"url": "https://github.com/microsoft/FluidFramework.git",
10+
"directory": "examples/apps/tree-comparison"
11+
},
12+
"license": "MIT",
13+
"author": "Microsoft and contributors",
14+
"main": "lib/index.js",
15+
"module": "lib/index.js",
16+
"types": "lib/index.d.ts",
17+
"scripts": {
18+
"build": "fluid-build . --task build",
19+
"build:compile": "fluid-build . --task compile",
20+
"build:esnext": "tsc",
21+
"clean": "rimraf --glob 'dist' 'lib' '*.tsbuildinfo' '*.build.log' 'nyc'",
22+
"eslint": "eslint --format stylish src",
23+
"eslint:fix": "eslint --format stylish src --fix --fix-type problem,suggestion,layout",
24+
"format": "npm run prettier:fix",
25+
"lint": "npm run prettier && npm run eslint",
26+
"lint:fix": "npm run prettier:fix && npm run eslint:fix",
27+
"prepack": "npm run webpack",
28+
"prettier": "prettier --check . --ignore-path ../../../.prettierignore",
29+
"prettier:fix": "prettier --write . --ignore-path ../../../.prettierignore",
30+
"start": "webpack serve",
31+
"start:test": "webpack serve --config webpack.test.js",
32+
"test": "npm run test:jest",
33+
"test:jest": "jest",
34+
"test:jest:verbose": "cross-env FLUID_TEST_VERBOSE=1 jest",
35+
"webpack": "webpack --env production",
36+
"webpack:dev": "webpack --env development"
37+
},
38+
"dependencies": {
39+
"@fluid-example/example-utils": "workspace:~",
40+
"@fluid-experimental/react-inputs": "workspace:~",
41+
"@fluid-experimental/tree": "workspace:~",
42+
"@fluid-experimental/tree2": "workspace:~",
43+
"@fluid-internal/client-utils": "workspace:~",
44+
"@fluidframework/aqueduct": "workspace:~",
45+
"@fluidframework/container-definitions": "workspace:~",
46+
"@fluidframework/container-loader": "workspace:~",
47+
"@fluidframework/container-runtime-definitions": "workspace:~",
48+
"@fluidframework/core-interfaces": "workspace:~",
49+
"@fluidframework/driver-definitions": "workspace:~",
50+
"@fluidframework/driver-utils": "workspace:~",
51+
"@fluidframework/request-handler": "workspace:~",
52+
"@fluidframework/routerlicious-driver": "workspace:~",
53+
"@fluidframework/runtime-utils": "workspace:~",
54+
"@fluidframework/sequence": "workspace:~",
55+
"@fluidframework/task-manager": "workspace:~",
56+
"@fluidframework/telemetry-utils": "workspace:~",
57+
"@fluidframework/tinylicious-driver": "workspace:~",
58+
"events": "^3.1.0",
59+
"react": "^17.0.1",
60+
"react-dom": "^17.0.1",
61+
"tiny-typed-emitter": "^2.1.0",
62+
"uuid": "^9.0.0"
63+
},
64+
"devDependencies": {
65+
"@fluid-tools/build-cli": "^0.25.0",
66+
"@fluidframework/build-common": "^2.0.1",
67+
"@fluidframework/build-tools": "^0.25.0",
68+
"@fluidframework/eslint-config-fluid": "^3.0.0",
69+
"@fluidframework/test-tools": "^1.0.195075",
70+
"@types/expect-puppeteer": "2.2.1",
71+
"@types/jest": "29.5.3",
72+
"@types/jest-environment-puppeteer": "2.2.0",
73+
"@types/node": "^16.18.38",
74+
"@types/puppeteer": "1.3.0",
75+
"@types/react": "^17.0.44",
76+
"@types/react-dom": "^17.0.18",
77+
"@types/uuid": "^9.0.2",
78+
"cross-env": "^7.0.3",
79+
"css-loader": "^1.0.0",
80+
"eslint": "~8.50.0",
81+
"html-webpack-plugin": "^5.5.0",
82+
"jest": "^29.6.2",
83+
"jest-junit": "^10.0.0",
84+
"jest-puppeteer": "^6.2.0",
85+
"prettier": "~3.0.3",
86+
"process": "^0.11.10",
87+
"puppeteer": "^17.1.3",
88+
"rimraf": "^4.4.0",
89+
"style-loader": "^1.0.0",
90+
"ts-jest": "^29.1.1",
91+
"ts-loader": "^9.3.0",
92+
"typescript": "~5.1.6",
93+
"webpack": "^5.82.0",
94+
"webpack-cli": "^4.9.2",
95+
"webpack-dev-server": "~4.6.0",
96+
"webpack-merge": "^5.8.0"
97+
},
98+
"fluid": {
99+
"browser": {
100+
"umd": {
101+
"files": [
102+
"main.bundle.js"
103+
],
104+
"library": "main"
105+
}
106+
}
107+
},
108+
"typeValidation": {
109+
"disabled": true,
110+
"broken": {}
111+
}
112+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
/*!
2+
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3+
* Licensed under the MIT License.
4+
*/
5+
6+
module.exports = {
7+
...require("@fluidframework/build-common/prettier.config.cjs"),
8+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<!-- Copyright (c) Microsoft Corporation and contributors. All rights reserved. -->
2+
<!-- Licensed under the MIT License. -->
3+
4+
<!doctype html>
5+
<html lang="en" style="height: 100%">
6+
<head>
7+
<meta charset="UTF-8" />
8+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
9+
<title>Test application</title>
10+
</head>
11+
<body style="margin: 0">
12+
<div id="app"></div>
13+
<div id="debug"></div>
14+
</body>
15+
</html>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
/*!
2+
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3+
* Licensed under the MIT License.
4+
*/
5+
6+
import type { IInventoryListAppModel, IInventoryList } from "../modelInterfaces";
7+
8+
/**
9+
* The InventoryListAppModel provides two inventory lists, one using legacy SharedTree
10+
* and the other using new SharedTree. They function the same and share the same interface.
11+
*/
12+
export class InventoryListAppModel implements IInventoryListAppModel {
13+
public constructor(
14+
public readonly legacyTreeInventoryList: IInventoryList,
15+
public readonly treeInventoryList: IInventoryList,
16+
) {}
17+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/*!
2+
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3+
* Licensed under the MIT License.
4+
*/
5+
6+
import { ModelContainerRuntimeFactory } from "@fluid-example/example-utils";
7+
import type { IContainer } from "@fluidframework/container-definitions";
8+
import type { IContainerRuntime } from "@fluidframework/container-runtime-definitions";
9+
// eslint-disable-next-line import/no-deprecated
10+
import { requestFluidObject } from "@fluidframework/runtime-utils";
11+
12+
import type { IInventoryList, IInventoryListAppModel } from "../modelInterfaces";
13+
import { InventoryListAppModel } from "./appModel";
14+
import { LegacyTreeInventoryListFactory } from "./legacyTreeInventoryList";
15+
import { TreeInventoryListFactory } from "./treeInventoryList";
16+
17+
export const legacyTreeInventoryListId = "legacy-tree-inventory-list";
18+
export const treeInventoryListId = "tree-inventory-list";
19+
20+
export class InventoryListContainerRuntimeFactory extends ModelContainerRuntimeFactory<IInventoryListAppModel> {
21+
public constructor() {
22+
super(
23+
new Map([
24+
LegacyTreeInventoryListFactory.registryEntry,
25+
TreeInventoryListFactory.registryEntry,
26+
]), // registryEntries
27+
);
28+
}
29+
30+
/**
31+
* {@inheritDoc ModelContainerRuntimeFactory.containerInitializingFirstTime}
32+
*/
33+
protected async containerInitializingFirstTime(runtime: IContainerRuntime) {
34+
const legacyTreeInventoryList = await runtime.createDataStore(
35+
LegacyTreeInventoryListFactory.type,
36+
);
37+
await legacyTreeInventoryList.trySetAlias(legacyTreeInventoryListId);
38+
const treeInventoryList = await runtime.createDataStore(TreeInventoryListFactory.type);
39+
await treeInventoryList.trySetAlias(treeInventoryListId);
40+
}
41+
42+
/**
43+
* {@inheritDoc ModelContainerRuntimeFactory.createModel}
44+
*/
45+
protected async createModel(runtime: IContainerRuntime, container: IContainer) {
46+
// eslint-disable-next-line import/no-deprecated
47+
const legacyTreeInventoryList = await requestFluidObject<IInventoryList>(
48+
await runtime.getRootDataStore(legacyTreeInventoryListId),
49+
"",
50+
);
51+
// eslint-disable-next-line import/no-deprecated
52+
const treeInventoryList = await requestFluidObject<IInventoryList>(
53+
await runtime.getRootDataStore(treeInventoryListId),
54+
"",
55+
);
56+
return new InventoryListAppModel(legacyTreeInventoryList, treeInventoryList);
57+
}
58+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
/*!
2+
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3+
* Licensed under the MIT License.
4+
*/
5+
6+
export { InventoryListContainerRuntimeFactory } from "./containerCode";

0 commit comments

Comments
 (0)