Skip to content

Commit

Permalink
Automation: main-next integrate
Browse files Browse the repository at this point in the history
  • Loading branch information
sonalideshpandemsft committed Dec 12, 2023
2 parents a528075 + 29a0591 commit 425e143
Show file tree
Hide file tree
Showing 24 changed files with 1,790 additions and 25 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/*!
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
* Licensed under the MIT License.
*/

module.exports = {
extends: [require.resolve("@fluidframework/eslint-config-fluid/minimal"), "prettier"],
rules: {},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
dist
node_modules
lib
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
nyc
*.log
**/*.tsbuildinfo
dist/tests
**/_api-extractor-temp/**
21 changes: 21 additions & 0 deletions examples/service-clients/odsp-client/shared-tree-demo/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
Copyright (c) Microsoft Corporation and contributors. All rights reserved.

MIT License

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# @fluid-example/shared-tree-demo

**_This demo is a work-in-progress_**

This app demonstrates how to create a simple tree data structure and build a React app using that data. This app is designed to use Odsp Client backed by ODSP service.

## Gettting started

All the code required to set up the Fluid Framework and SharedTree data structure is in the `fluid.ts` source file. Most of this code will be the same for any app. However, because SharedTree is still in the alpha stage, the code to set it up isn't optimized yet.
90 changes: 90 additions & 0 deletions examples/service-clients/odsp-client/shared-tree-demo/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
{
"name": "@fluid-example/shared-tree-demo",
"version": "2.0.0-internal.8.0.0",
"private": true,
"description": "A shared tree demo using react and odsp client",
"homepage": "https://fluidframework.com",
"repository": {
"type": "git",
"url": "https://github.com/microsoft/FluidFramework.git",
"directory": "examples/service-clients/shared-tree-demo"
},
"license": "MIT",
"author": "Microsoft and contributors",
"main": "lib/index.js",
"module": "lib/index.js",
"types": "lib/index.d.ts",
"scripts": {
"build": "fluid-build . --task build",
"build:compile": "fluid-build . --task compile",
"build:esnext": "tsc",
"clean": "rimraf --glob dist lib \"**/*.tsbuildinfo\" \"**/*.build.log\" nyc",
"eslint": "eslint --format stylish src",
"eslint:fix": "eslint --format stylish src --fix --fix-type problem,suggestion,layout",
"format": "npm run prettier:fix",
"lint": "npm run prettier && npm run eslint",
"lint:fix": "npm run prettier:fix && npm run eslint:fix",
"prepack": "npm run webpack",
"prettier": "prettier --check . --cache --ignore-path ../../../.prettierignore",
"prettier:fix": "prettier --write . --cache --ignore-path ../../../.prettierignore",
"start": "webpack serve --config webpack.config.js",
"start:test": "webpack serve --config webpack.test.js",
"webpack": "webpack --env production",
"webpack:dev": "webpack --env development"
},
"dependencies": {
"@fluid-experimental/odsp-client": "workspace:~",
"@fluid-experimental/tree2": "workspace:~",
"@fluidframework/container-definitions": "workspace:~",
"@fluidframework/container-runtime-definitions": "workspace:~",
"@fluidframework/core-interfaces": "workspace:~",
"@fluidframework/fluid-static": "workspace:~",
"@fluidframework/odsp-doclib-utils": "workspace:~",
"@fluidframework/odsp-driver-definitions": "workspace:~",
"css-loader": "^1.0.0",
"react": "^17.0.1",
"react-dom": "^17.0.1",
"style-loader": "^1.0.0"
},
"devDependencies": {
"@fluid-tools/build-cli": "^0.28.0",
"@fluidframework/build-common": "^2.0.3",
"@fluidframework/build-tools": "^0.28.0",
"@fluidframework/eslint-config-fluid": "^3.1.0",
"@fluidframework/test-tools": "^1.0.195075",
"@fluidframework/test-utils": "workspace:~",
"@types/expect-puppeteer": "2.2.1",
"@types/node": "^18.19.0",
"@types/puppeteer": "1.3.0",
"@types/react": "^17.0.44",
"@types/react-dom": "^17.0.18",
"cross-env": "^7.0.3",
"eslint": "~8.50.0",
"html-webpack-plugin": "^5.5.0",
"prettier": "~3.0.3",
"process": "^0.11.10",
"puppeteer": "^17.1.3",
"rimraf": "^4.4.0",
"tailwindcss": "^3.3.2",
"ts-loader": "^9.3.0",
"typescript": "~5.1.6",
"webpack": "^5.82.0",
"webpack-cli": "^4.9.2",
"webpack-dev-server": "~4.6.0",
"webpack-merge": "^5.8.0"
},
"fluid": {
"browser": {
"umd": {
"files": [
"dist/main.bundle.js"
],
"library": "main"
}
}
},
"typeValidation": {
"disabled": true,
"broken": {}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/*!
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
* Licensed under the MIT License.
*/

module.exports = {
...require("@fluidframework/build-common/prettier.config.cjs"),
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*!
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
* Licensed under the MIT License.
*/
import { OdspClientProps, OdspConnectionConfig } from "@fluid-experimental/odsp-client";
import { OdspTestTokenProvider } from "./tokenProvider";

export interface OdspTestCredentials {
clientId: string;
clientSecret: string;
username: string;
password: string;
}

/**
* Default test credentials for odsp-client.
*/
const clientCreds: OdspTestCredentials = {
clientId: "<client_id>",
clientSecret: "<client_secret>",
username: "<email_id>",
password: "<password>",
};

const connectionConfig: OdspConnectionConfig = {
tokenProvider: new OdspTestTokenProvider(clientCreds), // Token provider using the provided test credentials.
siteUrl: "<site_url>",
driveId: "<raas_drive_id>",
};

export const clientProps: OdspClientProps = {
connection: connectionConfig,
};
56 changes: 56 additions & 0 deletions examples/service-clients/odsp-client/shared-tree-demo/src/fluid.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*!
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
* Licensed under the MIT License.
*/
import { OdspClient, OdspContainerServices } from "@fluid-experimental/odsp-client";
import { ContainerSchema, IFluidContainer } from "@fluidframework/fluid-static";
import { SharedTreeFactory } from "@fluid-experimental/tree2";
import { clientProps } from "./clientProps";

// eslint-disable-next-line @typescript-eslint/no-extraneous-class
class SharedTree {
public static getFactory(): SharedTreeFactory {
return new SharedTreeFactory();
}
}

const client = new OdspClient(clientProps);

/**
* This function will create a container if no item Id is passed on the hash portion of the URL.
* If a item Id is provided, it will load the container.
*
* @returns The loaded container and container services.
*/
export const loadFluidData = async (
itemId: string,
schema: ContainerSchema,
): Promise<{
services: OdspContainerServices;
container: IFluidContainer;
}> => {
const { container, services }: { container: IFluidContainer; services: OdspContainerServices } =
await client.getContainer(itemId, schema);

return { services, container };
};

export const createFluidData = async (
schema: ContainerSchema,
): Promise<{
services: OdspContainerServices;
container: IFluidContainer;
}> => {
// The client will create a new detached container using the schema
// A detached container will enable the app to modify the container before attaching it to the client
const { container, services }: { container: IFluidContainer; services: OdspContainerServices } =
await client.createContainer(schema);

return { services, container };
};

export const containerSchema: ContainerSchema = {
initialObjects: {
appData: SharedTree,
},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/*!
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
* Licensed under the MIT License.
*/

body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", "Ubuntu",
"Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}

code {
font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New", monospace;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/*!
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
* Licensed under the MIT License.
*/

import React from "react";
import ReactDOM from "react-dom";
import { ITree } from "@fluid-experimental/tree2";
import { IFluidContainer } from "@fluidframework/fluid-static";
import { loadFluidData, containerSchema, createFluidData } from "./fluid";
import { treeConfiguration, Letter } from "./schema";
// eslint-disable-next-line import/no-unassigned-import
import "./output.css";
import { ReactApp } from "./reactApp";

async function start() {
// create the root element for React
const app = document.createElement("div");
app.id = "app";
document.body.appendChild(app);

// Get the root item id from the URL
// If there is no item id, then the app will make
// a new container.
let itemId = location.hash.substring(1);
const createNew = itemId.length === 0;
let container: IFluidContainer;

if (createNew) {
({ container } = await createFluidData(containerSchema));
} else {
({ container } = await loadFluidData(itemId, containerSchema));
}

// Initialize the SharedTree Data Structure
const appData = (container.initialObjects.appData as ITree).schematize(treeConfiguration);

const cellSize = { x: 32, y: 32 };
const canvasSize = { x: 10, y: 10 }; // characters across and down

// Render the app - note we attach new containers after render so
// the app renders instantly on create new flow. The app will be
// interactive immediately.
ReactDOM.render(
<ReactApp
data={appData}
container={container}
canvasSize={canvasSize}
cellSize={cellSize}
/>,
app,
);

// If this is a new container, fill it with data
if (createNew) {
const used: { x: number; y: number }[] = [];
let id = 0;
"HELLOWORLD"
.repeat(500)
.split("")
.map((character) => {
const x = Math.round(
Math.floor((Math.random() * (canvasSize.x * cellSize.x)) / cellSize.x) *
cellSize.x,
);
const y = Math.round(
Math.floor((Math.random() * (canvasSize.y * cellSize.y)) / cellSize.y) *
cellSize.y,
);
if (!used.find((element) => element.x === x && element.y === y)) {
const pos = { x, y };
used.push(pos);
appData.root.letters.insertAtEnd(
// TODO: error when not adding wrapping [] is inscrutable
new Letter({
position: pos,
character,
id: id.toString(),
}),
);
id++;
}
});
// If the app is in a `createNew` state - no itemId, and the container is detached, we attach the container.
// This uploads the container to the service and connects to the collaboration session.
itemId = await container.attach();

// The newly attached container is given a unique ID that can be used to access the container in another session
location.hash = itemId;
}
}

start().catch(console.error);
Loading

0 comments on commit 425e143

Please sign in to comment.