Skip to content

Commit

Permalink
tree: Add alpha tree configuration APIs (microsoft#22701)
Browse files Browse the repository at this point in the history
## Description

See changeset for details.

Based on changes from
microsoft#22566
  • Loading branch information
CraigMacomber authored Oct 3, 2024
1 parent 6a2b681 commit 40d3648
Show file tree
Hide file tree
Showing 13 changed files with 256 additions and 32 deletions.
32 changes: 32 additions & 0 deletions .changeset/clever-dancers-post.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
---
"fluid-framework": minor
"@fluidframework/tree": minor
---
---
"section": tree
---

Add alpha API for providing SharedTree configuration options

A new alpha `configuredSharedTree` had been added.
This allows providing configuration options, primarily for debugging, testing and evaluation of upcoming features.
The resulting configured `SharedTree` object can then be used in-place of the regular `SharedTree` imported from `fluid-framework`.

```typescript
import {
ForestType,
TreeCompressionStrategy,
configuredSharedTree,
typeboxValidator,
} from "@fluid-framework/alpha";
// Maximum debuggability and validation enabled:
const SharedTree = configuredSharedTree({
forest: ForestType.Expensive,
jsonValidator: typeboxValidator,
treeEncodeType: TreeCompressionStrategy.Uncompressed,
});
// Opts into the under development optimized tree storage planned to be the eventual default implementation:
const SharedTree = configuredSharedTree({
forest: ForestType.Optimized,
});
```
1 change: 1 addition & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
"cSpell.words": [
"boop",
"contoso",
"debuggability",
"denormalized",
"endregion",
"fluidframework",
Expand Down
58 changes: 58 additions & 0 deletions packages/dds/tree/api-report/tree.alpha.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,18 @@ type FlexList<Item = unknown> = readonly LazyItem<Item>[];
// @public
type FlexListToUnion<TList extends FlexList> = ExtractItemType<TList[number]>;

// @alpha
export interface ForestOptions {
readonly forest?: ForestType;
}

// @alpha
export enum ForestType {
Expensive = 2,
Optimized = 1,
Reference = 0
}

// @alpha
export function getBranch(tree: ITree): TreeBranch;

Expand All @@ -101,6 +113,11 @@ export function getBranch(view: TreeView<ImplicitFieldSchema>): TreeBranch;
// @alpha
export function getJsonSchema(schema: ImplicitFieldSchema): JsonTreeSchema;

// @alpha
export interface ICodecOptions {
readonly jsonValidator: JsonValidator;
}

// @public
export type ImplicitAllowedTypes = AllowedTypes | TreeNodeSchema;

Expand Down Expand Up @@ -272,6 +289,11 @@ export type JsonTreeSchema = JsonFieldSchema & {
readonly $defs: Record<JsonSchemaId, JsonNodeSchema>;
};

// @alpha
export interface JsonValidator {
compile<Schema extends TSchema>(schema: Schema): SchemaValidationFunction<Schema>;
}

// @public
export type LazyItem<Item = unknown> = Item | (() => Item);

Expand Down Expand Up @@ -325,6 +347,9 @@ export enum NodeKind {
Object = 2
}

// @alpha
export const noopValidator: JsonValidator;

// @public
type ObjectFromSchemaRecord<T extends RestrictiveStringRecord<ImplicitFieldSchema>> = {
-readonly [Property in keyof T]: Property extends string ? TreeFieldFromImplicitField<T[Property]> : unknown;
Expand Down Expand Up @@ -443,9 +468,33 @@ export class SchemaFactory<out TScope extends string | undefined = string | unde
readonly string: TreeNodeSchema<"com.fluidframework.leaf.string", NodeKind.Leaf, string, string>;
}

// @alpha
export interface SchemaValidationFunction<Schema extends TSchema> {
check(data: unknown): data is Static<Schema>;
}

// @public
type ScopedSchemaName<TScope extends string | undefined, TName extends number | string> = TScope extends undefined ? `${TName}` : `${TScope}.${TName}`;

// @alpha
export interface SharedTreeFormatOptions {
formatVersion: SharedTreeFormatVersion[keyof SharedTreeFormatVersion];
treeEncodeType: TreeCompressionStrategy;
}

// @alpha
export const SharedTreeFormatVersion: {
readonly v1: 1;
readonly v2: 2;
readonly v3: 3;
};

// @alpha
export type SharedTreeFormatVersion = typeof SharedTreeFormatVersion;

// @alpha
export type SharedTreeOptions = Partial<ICodecOptions> & Partial<SharedTreeFormatOptions> & ForestOptions;

// @public
export type TransactionConstraint = NodeInDocumentConstraint;

Expand Down Expand Up @@ -522,6 +571,12 @@ export interface TreeChangeEventsBeta<TNode extends TreeNode = TreeNode> extends
nodeChanged: (data: NodeChangedData<TNode> & (TNode extends WithType<string, NodeKind.Map | NodeKind.Object> ? Required<Pick<NodeChangedData<TNode>, "changedProperties">> : unknown)) => void;
}

// @alpha
export enum TreeCompressionStrategy {
Compressed = 0,
Uncompressed = 1
}

// @public
export type TreeFieldFromImplicitField<TSchema extends ImplicitFieldSchema = FieldSchema> = TSchema extends FieldSchema<infer Kind, infer Types> ? ApplyKind<TreeNodeFromImplicitAllowedTypes<Types>, Kind, false> : TSchema extends ImplicitAllowedTypes ? TreeNodeFromImplicitAllowedTypes<TSchema> : unknown;

Expand Down Expand Up @@ -641,6 +696,9 @@ export interface TreeViewEvents {
schemaChanged(): void;
}

// @alpha
export const typeboxValidator: JsonValidator;

// @public @deprecated
const typeNameSymbol: unique symbol;

Expand Down
8 changes: 4 additions & 4 deletions packages/dds/tree/src/codec/codec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,18 +35,18 @@ export interface IDecoder<TDecoded, TEncoded, TContext> {
/**
* Validates data complies with some particular schema.
* Implementations are typically created by a {@link JsonValidator}.
* @internal
* @alpha
*/
export interface SchemaValidationFunction<Schema extends TSchema> {
/**
* @returns Whether the data matches a schema.
* Returns whether the data matches a schema.
*/
check(data: unknown): data is Static<Schema>;
}

/**
* JSON schema validator compliant with draft 6 schema. See https://json-schema.org.
* @internal
* @alpha
*/
export interface JsonValidator {
/**
Expand All @@ -63,7 +63,7 @@ export interface JsonValidator {

/**
* Options relating to handling of persisted data.
* @internal
* @alpha
*/
export interface ICodecOptions {
/**
Expand Down
2 changes: 1 addition & 1 deletion packages/dds/tree/src/codec/noopValidator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import type { JsonValidator } from "./codec.js";
* A {@link JsonValidator} implementation which performs no validation and accepts all data as valid.
* @privateRemarks Having this as an option unifies opting out of validation with selection of
* validators, simplifying code performing validation.
* @internal
* @alpha
*/
export const noopValidator: JsonValidator = {
compile: <Schema extends TSchema>() => ({ check: (data): data is Static<Schema> => true }),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import type { JsonValidator } from "../codec/index.js";
*
* Defining this validator in its own file also helps to ensure it is tree-shakeable.
*
* @internal
* @alpha
*/
export const typeboxValidator: JsonValidator = {
compile: <Schema extends TSchema>(schema: Schema) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
* Selects which heuristics to use when encoding tree content.
* All encoding options here are compatible with the same decoder:
* the selection here does not impact compatibility.
* @internal
* @alpha
*/
export enum TreeCompressionStrategy {
/**
Expand Down
12 changes: 10 additions & 2 deletions packages/dds/tree/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ export {
type NodeInDocumentConstraint,
type RunTransaction,
rollback,
type ForestOptions,
getBranch,
type TreeBranch,
type TreeBranchFork,
Expand Down Expand Up @@ -150,9 +151,16 @@ export {
type JsonLeafSchemaType,
getJsonSchema,
} from "./simple-tree/index.js";
export { SharedTree, configuredSharedTree } from "./treeFactory.js";
export {
SharedTree,
configuredSharedTree,
} from "./treeFactory.js";

export type { ICodecOptions, JsonValidator, SchemaValidationFunction } from "./codec/index.js";
export type {
ICodecOptions,
JsonValidator,
SchemaValidationFunction,
} from "./codec/index.js";
export { noopValidator } from "./codec/index.js";
export { typeboxValidator } from "./external-utilities/index.js";

Expand Down
5 changes: 5 additions & 0 deletions packages/dds/tree/src/shared-tree/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ export {
type SharedTreeContentSnapshot,
type SharedTreeFormatOptions,
SharedTreeFormatVersion,
buildConfiguredForest,
defaultSharedTreeOptions,
type ForestOptions,
} from "./sharedTree.js";

export {
Expand All @@ -29,6 +32,8 @@ export {

export { type TreeStoredContent } from "./schematizeTree.js";

export { SchematizingSimpleTreeView } from "./schematizingTreeView.js";

export { CheckoutFlexTreeView } from "./checkoutFlexTreeView.js";

export type { ISharedTreeEditor, ISchemaEditor } from "./sharedTreeEditBuilder.js";
Expand Down
Loading

0 comments on commit 40d3648

Please sign in to comment.