From 86b601484b04c20e2ef7c0f86af867f454110a4c Mon Sep 17 00:00:00 2001 From: "Craig Macomber (Microsoft)" <42876482+CraigMacomber@users.noreply.github.com> Date: Thu, 7 Nov 2024 14:07:16 -0800 Subject: [PATCH 1/5] More scope docs --- .../dds/tree/api-report/tree.alpha.api.md | 4 +-- packages/dds/tree/api-report/tree.beta.api.md | 4 +-- .../tree/api-report/tree.legacy.alpha.api.md | 4 +-- .../tree/api-report/tree.legacy.public.api.md | 4 +-- .../dds/tree/api-report/tree.public.api.md | 4 +-- .../tree/src/simple-tree/api/schemaFactory.ts | 34 ++++++++++++++++--- .../api-report/fluid-framework.alpha.api.md | 4 +-- .../api-report/fluid-framework.beta.api.md | 4 +-- .../fluid-framework.legacy.alpha.api.md | 4 +-- .../fluid-framework.legacy.public.api.md | 4 +-- .../api-report/fluid-framework.public.api.md | 4 +-- 11 files changed, 49 insertions(+), 25 deletions(-) diff --git a/packages/dds/tree/api-report/tree.alpha.api.md b/packages/dds/tree/api-report/tree.alpha.api.md index 8a5cefd238e4..3265e4a9b9aa 100644 --- a/packages/dds/tree/api-report/tree.alpha.api.md +++ b/packages/dds/tree/api-report/tree.alpha.api.md @@ -577,7 +577,8 @@ export interface SchemaCompatibilityStatus { // @public @sealed export class SchemaFactory { - constructor(scope: TScope); + constructor( + scope: TScope); array(allowedTypes: T): TreeNodeSchemaNonClass`>, NodeKind.Array, TreeArrayNode & WithType`>, NodeKind.Array>, Iterable>, true, T, undefined>; array(name: Name, allowedTypes: T): TreeNodeSchemaClass, NodeKind.Array, TreeArrayNode & WithType, NodeKind.Array>, Iterable>, true, T, undefined>; arrayRecursive>(name: Name, allowedTypes: T): TreeNodeSchemaClass, NodeKind.Array, TreeArrayNodeUnsafe & WithType, NodeKind.Array, unknown>, { @@ -602,7 +603,6 @@ export class SchemaFactory>(t: T, props?: Omit): FieldSchemaUnsafe; required(t: T, props?: Omit, "defaultProvider">): FieldSchema; requiredRecursive>(t: T, props?: Omit): FieldSchemaUnsafe; - // (undocumented) readonly scope: TScope; readonly string: TreeNodeSchemaNonClass<"com.fluidframework.leaf.string", NodeKind.Leaf, string, string, true, unknown, never>; } diff --git a/packages/dds/tree/api-report/tree.beta.api.md b/packages/dds/tree/api-report/tree.beta.api.md index 2130d8b61985..7c570d89640b 100644 --- a/packages/dds/tree/api-report/tree.beta.api.md +++ b/packages/dds/tree/api-report/tree.beta.api.md @@ -365,7 +365,8 @@ export interface SchemaCompatibilityStatus { // @public @sealed export class SchemaFactory { - constructor(scope: TScope); + constructor( + scope: TScope); array(allowedTypes: T): TreeNodeSchemaNonClass`>, NodeKind.Array, TreeArrayNode & WithType`>, NodeKind.Array>, Iterable>, true, T, undefined>; array(name: Name, allowedTypes: T): TreeNodeSchemaClass, NodeKind.Array, TreeArrayNode & WithType, NodeKind.Array>, Iterable>, true, T, undefined>; arrayRecursive>(name: Name, allowedTypes: T): TreeNodeSchemaClass, NodeKind.Array, TreeArrayNodeUnsafe & WithType, NodeKind.Array, unknown>, { @@ -390,7 +391,6 @@ export class SchemaFactory>(t: T, props?: Omit): FieldSchemaUnsafe; required(t: T, props?: Omit, "defaultProvider">): FieldSchema; requiredRecursive>(t: T, props?: Omit): FieldSchemaUnsafe; - // (undocumented) readonly scope: TScope; readonly string: TreeNodeSchemaNonClass<"com.fluidframework.leaf.string", NodeKind.Leaf, string, string, true, unknown, never>; } diff --git a/packages/dds/tree/api-report/tree.legacy.alpha.api.md b/packages/dds/tree/api-report/tree.legacy.alpha.api.md index 24a1cc4960cd..4df875307225 100644 --- a/packages/dds/tree/api-report/tree.legacy.alpha.api.md +++ b/packages/dds/tree/api-report/tree.legacy.alpha.api.md @@ -360,7 +360,8 @@ export interface SchemaCompatibilityStatus { // @public @sealed export class SchemaFactory { - constructor(scope: TScope); + constructor( + scope: TScope); array(allowedTypes: T): TreeNodeSchemaNonClass`>, NodeKind.Array, TreeArrayNode & WithType`>, NodeKind.Array>, Iterable>, true, T, undefined>; array(name: Name, allowedTypes: T): TreeNodeSchemaClass, NodeKind.Array, TreeArrayNode & WithType, NodeKind.Array>, Iterable>, true, T, undefined>; arrayRecursive>(name: Name, allowedTypes: T): TreeNodeSchemaClass, NodeKind.Array, TreeArrayNodeUnsafe & WithType, NodeKind.Array, unknown>, { @@ -385,7 +386,6 @@ export class SchemaFactory>(t: T, props?: Omit): FieldSchemaUnsafe; required(t: T, props?: Omit, "defaultProvider">): FieldSchema; requiredRecursive>(t: T, props?: Omit): FieldSchemaUnsafe; - // (undocumented) readonly scope: TScope; readonly string: TreeNodeSchemaNonClass<"com.fluidframework.leaf.string", NodeKind.Leaf, string, string, true, unknown, never>; } diff --git a/packages/dds/tree/api-report/tree.legacy.public.api.md b/packages/dds/tree/api-report/tree.legacy.public.api.md index 77991adaf27a..b2d24dd09fc8 100644 --- a/packages/dds/tree/api-report/tree.legacy.public.api.md +++ b/packages/dds/tree/api-report/tree.legacy.public.api.md @@ -360,7 +360,8 @@ export interface SchemaCompatibilityStatus { // @public @sealed export class SchemaFactory { - constructor(scope: TScope); + constructor( + scope: TScope); array(allowedTypes: T): TreeNodeSchemaNonClass`>, NodeKind.Array, TreeArrayNode & WithType`>, NodeKind.Array>, Iterable>, true, T, undefined>; array(name: Name, allowedTypes: T): TreeNodeSchemaClass, NodeKind.Array, TreeArrayNode & WithType, NodeKind.Array>, Iterable>, true, T, undefined>; arrayRecursive>(name: Name, allowedTypes: T): TreeNodeSchemaClass, NodeKind.Array, TreeArrayNodeUnsafe & WithType, NodeKind.Array, unknown>, { @@ -385,7 +386,6 @@ export class SchemaFactory>(t: T, props?: Omit): FieldSchemaUnsafe; required(t: T, props?: Omit, "defaultProvider">): FieldSchema; requiredRecursive>(t: T, props?: Omit): FieldSchemaUnsafe; - // (undocumented) readonly scope: TScope; readonly string: TreeNodeSchemaNonClass<"com.fluidframework.leaf.string", NodeKind.Leaf, string, string, true, unknown, never>; } diff --git a/packages/dds/tree/api-report/tree.public.api.md b/packages/dds/tree/api-report/tree.public.api.md index 77991adaf27a..b2d24dd09fc8 100644 --- a/packages/dds/tree/api-report/tree.public.api.md +++ b/packages/dds/tree/api-report/tree.public.api.md @@ -360,7 +360,8 @@ export interface SchemaCompatibilityStatus { // @public @sealed export class SchemaFactory { - constructor(scope: TScope); + constructor( + scope: TScope); array(allowedTypes: T): TreeNodeSchemaNonClass`>, NodeKind.Array, TreeArrayNode & WithType`>, NodeKind.Array>, Iterable>, true, T, undefined>; array(name: Name, allowedTypes: T): TreeNodeSchemaClass, NodeKind.Array, TreeArrayNode & WithType, NodeKind.Array>, Iterable>, true, T, undefined>; arrayRecursive>(name: Name, allowedTypes: T): TreeNodeSchemaClass, NodeKind.Array, TreeArrayNodeUnsafe & WithType, NodeKind.Array, unknown>, { @@ -385,7 +386,6 @@ export class SchemaFactory>(t: T, props?: Omit): FieldSchemaUnsafe; required(t: T, props?: Omit, "defaultProvider">): FieldSchema; requiredRecursive>(t: T, props?: Omit): FieldSchemaUnsafe; - // (undocumented) readonly scope: TScope; readonly string: TreeNodeSchemaNonClass<"com.fluidframework.leaf.string", NodeKind.Leaf, string, string, true, unknown, never>; } diff --git a/packages/dds/tree/src/simple-tree/api/schemaFactory.ts b/packages/dds/tree/src/simple-tree/api/schemaFactory.ts index 1564f0fa95c4..48cd2ef41764 100644 --- a/packages/dds/tree/src/simple-tree/api/schemaFactory.ts +++ b/packages/dds/tree/src/simple-tree/api/schemaFactory.ts @@ -223,12 +223,36 @@ export class SchemaFactory< * If each library exporting schema picks its own globally unique scope for its SchemaFactory, * then all schema an application might depend on, directly or transitively, * will end up with a unique fully qualified name which is required to refer to it in persisted data and errors. - * - * @param scope - Prefix appended to the identifiers of all {@link TreeNodeSchema} produced by this builder. - * Use of [Reverse domain name notation](https://en.wikipedia.org/wiki/Reverse_domain_name_notation) or a UUIDv4 is recommended to avoid collisions. - * You may opt out of using a scope by passing `undefined`, but note that this increases the risk of collisions. */ - public constructor(public readonly scope: TScope) {} + public constructor( + /** + * Prefix appended to the identifiers of all {@link TreeNodeSchema} produced by this builder. + * Use of [Reverse domain name notation](https://en.wikipedia.org/wiki/Reverse_domain_name_notation) or a UUIDv4 is recommended to avoid collisions. + * You may opt out of using a scope by passing `undefined`, but note that this increases the risk of collisions. + * + * @remarks + * Generally each library which is developed independently (possible a package, but could also be part of a package or multiple packages developed together) should get its own globally unique `scope`. + * This ensures that the given library can name its schema (via the name parameter passed to the schema building methods, or implicitly for structurally named schema) + * in a way that must only be unique within the library. + * Following this pattern allows a single application to depend on multiple libraries which define their own schema, and use them together in a single tree without risk of collisions. + * If a library logically contains sub-libraries with their own schema, they can be given a scope nested inside the parent scope, such as "ParentScope.ChildScope". + * + * @example + * Fluid Framework follows this pattern, placing the schema for the built in leaf types in the `com.fluidframework.leaf` scope. + * If Fluid Framework publishes more schema in the future, they would be under some other `com.fluidframework` scope. + * This ensures that any schema use by any other library will not conflict with Fluid Framework's schema + * as long as the library uses the recommended + * [Reverse domain name notation](https://en.wikipedia.org/wiki/Reverse_domain_name_notation) or a UUIDv4 based scopes. + * + * @example + * A library could generate a random UUIDv4, like `242c4397-49ed-47e6-8dd0-d5c3bc31778b` and use that as the scope. + * Note: do not use this UUID: a new one must be randomly generated when needed to ensure collision resistance. + * ```typescript + * const factory = new SchemaFactory("242c4397-49ed-47e6-8dd0-d5c3bc31778b"); + * ``` + */ + public readonly scope: TScope, + ) {} private scoped(name: Name): ScopedSchemaName { return ( diff --git a/packages/framework/fluid-framework/api-report/fluid-framework.alpha.api.md b/packages/framework/fluid-framework/api-report/fluid-framework.alpha.api.md index c300a3cccf9e..37eac2a1a112 100644 --- a/packages/framework/fluid-framework/api-report/fluid-framework.alpha.api.md +++ b/packages/framework/fluid-framework/api-report/fluid-framework.alpha.api.md @@ -930,7 +930,8 @@ export interface SchemaCompatibilityStatus { // @public @sealed export class SchemaFactory { - constructor(scope: TScope); + constructor( + scope: TScope); array(allowedTypes: T): TreeNodeSchemaNonClass`>, NodeKind.Array, TreeArrayNode & WithType`>, NodeKind.Array>, Iterable>, true, T, undefined>; array(name: Name, allowedTypes: T): TreeNodeSchemaClass, NodeKind.Array, TreeArrayNode & WithType, NodeKind.Array>, Iterable>, true, T, undefined>; arrayRecursive>(name: Name, allowedTypes: T): TreeNodeSchemaClass, NodeKind.Array, TreeArrayNodeUnsafe & WithType, NodeKind.Array, unknown>, { @@ -955,7 +956,6 @@ export class SchemaFactory>(t: T, props?: Omit): FieldSchemaUnsafe; required(t: T, props?: Omit, "defaultProvider">): FieldSchema; requiredRecursive>(t: T, props?: Omit): FieldSchemaUnsafe; - // (undocumented) readonly scope: TScope; readonly string: TreeNodeSchemaNonClass<"com.fluidframework.leaf.string", NodeKind.Leaf, string, string, true, unknown, never>; } diff --git a/packages/framework/fluid-framework/api-report/fluid-framework.beta.api.md b/packages/framework/fluid-framework/api-report/fluid-framework.beta.api.md index a56d27cd3862..267375e03fa0 100644 --- a/packages/framework/fluid-framework/api-report/fluid-framework.beta.api.md +++ b/packages/framework/fluid-framework/api-report/fluid-framework.beta.api.md @@ -715,7 +715,8 @@ export interface SchemaCompatibilityStatus { // @public @sealed export class SchemaFactory { - constructor(scope: TScope); + constructor( + scope: TScope); array(allowedTypes: T): TreeNodeSchemaNonClass`>, NodeKind.Array, TreeArrayNode & WithType`>, NodeKind.Array>, Iterable>, true, T, undefined>; array(name: Name, allowedTypes: T): TreeNodeSchemaClass, NodeKind.Array, TreeArrayNode & WithType, NodeKind.Array>, Iterable>, true, T, undefined>; arrayRecursive>(name: Name, allowedTypes: T): TreeNodeSchemaClass, NodeKind.Array, TreeArrayNodeUnsafe & WithType, NodeKind.Array, unknown>, { @@ -740,7 +741,6 @@ export class SchemaFactory>(t: T, props?: Omit): FieldSchemaUnsafe; required(t: T, props?: Omit, "defaultProvider">): FieldSchema; requiredRecursive>(t: T, props?: Omit): FieldSchemaUnsafe; - // (undocumented) readonly scope: TScope; readonly string: TreeNodeSchemaNonClass<"com.fluidframework.leaf.string", NodeKind.Leaf, string, string, true, unknown, never>; } diff --git a/packages/framework/fluid-framework/api-report/fluid-framework.legacy.alpha.api.md b/packages/framework/fluid-framework/api-report/fluid-framework.legacy.alpha.api.md index 2e56b7da7a2c..cb71efc1816b 100644 --- a/packages/framework/fluid-framework/api-report/fluid-framework.legacy.alpha.api.md +++ b/packages/framework/fluid-framework/api-report/fluid-framework.legacy.alpha.api.md @@ -1012,7 +1012,8 @@ export interface SchemaCompatibilityStatus { // @public @sealed export class SchemaFactory { - constructor(scope: TScope); + constructor( + scope: TScope); array(allowedTypes: T): TreeNodeSchemaNonClass`>, NodeKind.Array, TreeArrayNode & WithType`>, NodeKind.Array>, Iterable>, true, T, undefined>; array(name: Name, allowedTypes: T): TreeNodeSchemaClass, NodeKind.Array, TreeArrayNode & WithType, NodeKind.Array>, Iterable>, true, T, undefined>; arrayRecursive>(name: Name, allowedTypes: T): TreeNodeSchemaClass, NodeKind.Array, TreeArrayNodeUnsafe & WithType, NodeKind.Array, unknown>, { @@ -1037,7 +1038,6 @@ export class SchemaFactory>(t: T, props?: Omit): FieldSchemaUnsafe; required(t: T, props?: Omit, "defaultProvider">): FieldSchema; requiredRecursive>(t: T, props?: Omit): FieldSchemaUnsafe; - // (undocumented) readonly scope: TScope; readonly string: TreeNodeSchemaNonClass<"com.fluidframework.leaf.string", NodeKind.Leaf, string, string, true, unknown, never>; } diff --git a/packages/framework/fluid-framework/api-report/fluid-framework.legacy.public.api.md b/packages/framework/fluid-framework/api-report/fluid-framework.legacy.public.api.md index b44190210ce4..8b4ca68b0fba 100644 --- a/packages/framework/fluid-framework/api-report/fluid-framework.legacy.public.api.md +++ b/packages/framework/fluid-framework/api-report/fluid-framework.legacy.public.api.md @@ -746,7 +746,8 @@ export interface SchemaCompatibilityStatus { // @public @sealed export class SchemaFactory { - constructor(scope: TScope); + constructor( + scope: TScope); array(allowedTypes: T): TreeNodeSchemaNonClass`>, NodeKind.Array, TreeArrayNode & WithType`>, NodeKind.Array>, Iterable>, true, T, undefined>; array(name: Name, allowedTypes: T): TreeNodeSchemaClass, NodeKind.Array, TreeArrayNode & WithType, NodeKind.Array>, Iterable>, true, T, undefined>; arrayRecursive>(name: Name, allowedTypes: T): TreeNodeSchemaClass, NodeKind.Array, TreeArrayNodeUnsafe & WithType, NodeKind.Array, unknown>, { @@ -771,7 +772,6 @@ export class SchemaFactory>(t: T, props?: Omit): FieldSchemaUnsafe; required(t: T, props?: Omit, "defaultProvider">): FieldSchema; requiredRecursive>(t: T, props?: Omit): FieldSchemaUnsafe; - // (undocumented) readonly scope: TScope; readonly string: TreeNodeSchemaNonClass<"com.fluidframework.leaf.string", NodeKind.Leaf, string, string, true, unknown, never>; } diff --git a/packages/framework/fluid-framework/api-report/fluid-framework.public.api.md b/packages/framework/fluid-framework/api-report/fluid-framework.public.api.md index 2066318bd80d..8eedb915642f 100644 --- a/packages/framework/fluid-framework/api-report/fluid-framework.public.api.md +++ b/packages/framework/fluid-framework/api-report/fluid-framework.public.api.md @@ -710,7 +710,8 @@ export interface SchemaCompatibilityStatus { // @public @sealed export class SchemaFactory { - constructor(scope: TScope); + constructor( + scope: TScope); array(allowedTypes: T): TreeNodeSchemaNonClass`>, NodeKind.Array, TreeArrayNode & WithType`>, NodeKind.Array>, Iterable>, true, T, undefined>; array(name: Name, allowedTypes: T): TreeNodeSchemaClass, NodeKind.Array, TreeArrayNode & WithType, NodeKind.Array>, Iterable>, true, T, undefined>; arrayRecursive>(name: Name, allowedTypes: T): TreeNodeSchemaClass, NodeKind.Array, TreeArrayNodeUnsafe & WithType, NodeKind.Array, unknown>, { @@ -735,7 +736,6 @@ export class SchemaFactory>(t: T, props?: Omit): FieldSchemaUnsafe; required(t: T, props?: Omit, "defaultProvider">): FieldSchema; requiredRecursive>(t: T, props?: Omit): FieldSchemaUnsafe; - // (undocumented) readonly scope: TScope; readonly string: TreeNodeSchemaNonClass<"com.fluidframework.leaf.string", NodeKind.Leaf, string, string, true, unknown, never>; } From 3ba45b588bf8d5bb806ad761b1144003e083b714 Mon Sep 17 00:00:00 2001 From: "Craig Macomber (Microsoft)" <42876482+CraigMacomber@users.noreply.github.com> Date: Thu, 7 Nov 2024 16:32:38 -0800 Subject: [PATCH 2/5] Apply suggestions from code review Co-authored-by: Joshua Smithrud <54606601+Josmithr@users.noreply.github.com> --- packages/dds/tree/src/simple-tree/api/schemaFactory.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/dds/tree/src/simple-tree/api/schemaFactory.ts b/packages/dds/tree/src/simple-tree/api/schemaFactory.ts index 48cd2ef41764..91d858e89efd 100644 --- a/packages/dds/tree/src/simple-tree/api/schemaFactory.ts +++ b/packages/dds/tree/src/simple-tree/api/schemaFactory.ts @@ -227,7 +227,7 @@ export class SchemaFactory< public constructor( /** * Prefix appended to the identifiers of all {@link TreeNodeSchema} produced by this builder. - * Use of [Reverse domain name notation](https://en.wikipedia.org/wiki/Reverse_domain_name_notation) or a UUIDv4 is recommended to avoid collisions. + * Use of {@link https://en.wikipedia.org/wiki/Reverse_domain_name_notation | Reverse domain name notation} or a UUIDv4 is recommended to avoid collisions. * You may opt out of using a scope by passing `undefined`, but note that this increases the risk of collisions. * * @remarks @@ -242,7 +242,7 @@ export class SchemaFactory< * If Fluid Framework publishes more schema in the future, they would be under some other `com.fluidframework` scope. * This ensures that any schema use by any other library will not conflict with Fluid Framework's schema * as long as the library uses the recommended - * [Reverse domain name notation](https://en.wikipedia.org/wiki/Reverse_domain_name_notation) or a UUIDv4 based scopes. + * {@link https://en.wikipedia.org/wiki/Reverse_domain_name_notation | Reverse domain name notation} or a UUIDv4 based scopes. * * @example * A library could generate a random UUIDv4, like `242c4397-49ed-47e6-8dd0-d5c3bc31778b` and use that as the scope. From 0a2987d797c30091cc14f8fdf12f365751d74f10 Mon Sep 17 00:00:00 2001 From: "Craig Macomber (Microsoft)" <42876482+CraigMacomber@users.noreply.github.com> Date: Thu, 7 Nov 2024 16:59:30 -0800 Subject: [PATCH 3/5] Simplify sentences --- .../tree/src/simple-tree/api/schemaFactory.ts | 20 ++++++++----------- 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/packages/dds/tree/src/simple-tree/api/schemaFactory.ts b/packages/dds/tree/src/simple-tree/api/schemaFactory.ts index 91d858e89efd..8f9cac0c1062 100644 --- a/packages/dds/tree/src/simple-tree/api/schemaFactory.ts +++ b/packages/dds/tree/src/simple-tree/api/schemaFactory.ts @@ -216,13 +216,10 @@ export class SchemaFactory< private readonly structuralTypes: Map = new Map(); /** - * Construct a SchemaFactory with a given scope. + * Construct a SchemaFactory with a given {@link SchemaFactory.scope|scope}. * @remarks - * There are no restrictions on mixing schema from different schema factories: - * this is encouraged when a single schema references schema from different libraries. - * If each library exporting schema picks its own globally unique scope for its SchemaFactory, - * then all schema an application might depend on, directly or transitively, - * will end up with a unique fully qualified name which is required to refer to it in persisted data and errors. + * There are no restrictions on mixing schema from different schema factories. + * Typically each library will create one or more SchemaFactories and use them to define its schema. */ public constructor( /** @@ -231,18 +228,17 @@ export class SchemaFactory< * You may opt out of using a scope by passing `undefined`, but note that this increases the risk of collisions. * * @remarks - * Generally each library which is developed independently (possible a package, but could also be part of a package or multiple packages developed together) should get its own globally unique `scope`. - * This ensures that the given library can name its schema (via the name parameter passed to the schema building methods, or implicitly for structurally named schema) - * in a way that must only be unique within the library. + * Generally each developed independently library (possibly a package, but could also be part of a package or multiple packages developed together) should get its own globally unique `scope`. + * Then each schema the library get its own name which is unique within the library. + * These are joined (with a period) to form the globally unique {@link TreeNodeSchemaCore.identifier|schema identifier}. * Following this pattern allows a single application to depend on multiple libraries which define their own schema, and use them together in a single tree without risk of collisions. * If a library logically contains sub-libraries with their own schema, they can be given a scope nested inside the parent scope, such as "ParentScope.ChildScope". * * @example * Fluid Framework follows this pattern, placing the schema for the built in leaf types in the `com.fluidframework.leaf` scope. * If Fluid Framework publishes more schema in the future, they would be under some other `com.fluidframework` scope. - * This ensures that any schema use by any other library will not conflict with Fluid Framework's schema - * as long as the library uses the recommended - * {@link https://en.wikipedia.org/wiki/Reverse_domain_name_notation | Reverse domain name notation} or a UUIDv4 based scopes. + * This ensures that any schema defined by any other library will not conflict with Fluid Framework's schema + * as long as the library uses the recommended patterns for how to scope its schema.. * * @example * A library could generate a random UUIDv4, like `242c4397-49ed-47e6-8dd0-d5c3bc31778b` and use that as the scope. From b02ed69e6fbcbe0eba6918834950201b980a0754 Mon Sep 17 00:00:00 2001 From: "Craig Macomber (Microsoft)" <42876482+CraigMacomber@users.noreply.github.com> Date: Thu, 7 Nov 2024 17:00:29 -0800 Subject: [PATCH 4/5] Reorder docs --- packages/dds/tree/src/simple-tree/api/schemaFactory.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/dds/tree/src/simple-tree/api/schemaFactory.ts b/packages/dds/tree/src/simple-tree/api/schemaFactory.ts index 8f9cac0c1062..b564a0a41276 100644 --- a/packages/dds/tree/src/simple-tree/api/schemaFactory.ts +++ b/packages/dds/tree/src/simple-tree/api/schemaFactory.ts @@ -224,8 +224,6 @@ export class SchemaFactory< public constructor( /** * Prefix appended to the identifiers of all {@link TreeNodeSchema} produced by this builder. - * Use of {@link https://en.wikipedia.org/wiki/Reverse_domain_name_notation | Reverse domain name notation} or a UUIDv4 is recommended to avoid collisions. - * You may opt out of using a scope by passing `undefined`, but note that this increases the risk of collisions. * * @remarks * Generally each developed independently library (possibly a package, but could also be part of a package or multiple packages developed together) should get its own globally unique `scope`. @@ -234,6 +232,9 @@ export class SchemaFactory< * Following this pattern allows a single application to depend on multiple libraries which define their own schema, and use them together in a single tree without risk of collisions. * If a library logically contains sub-libraries with their own schema, they can be given a scope nested inside the parent scope, such as "ParentScope.ChildScope". * + * Use of {@link https://en.wikipedia.org/wiki/Reverse_domain_name_notation | Reverse domain name notation} or a UUIDv4 is recommended to avoid collisions. + * You may opt out of using a scope by passing `undefined`, but note that this increases the risk of collisions. + * * @example * Fluid Framework follows this pattern, placing the schema for the built in leaf types in the `com.fluidframework.leaf` scope. * If Fluid Framework publishes more schema in the future, they would be under some other `com.fluidframework` scope. From 03031e9c0ba77e63a79136695c284bdcba57c12d Mon Sep 17 00:00:00 2001 From: "Craig Macomber (Microsoft)" <42876482+CraigMacomber@users.noreply.github.com> Date: Fri, 8 Nov 2024 18:15:11 -0800 Subject: [PATCH 5/5] Editing --- .../dds/tree/src/simple-tree/api/schemaFactory.ts | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/packages/dds/tree/src/simple-tree/api/schemaFactory.ts b/packages/dds/tree/src/simple-tree/api/schemaFactory.ts index b564a0a41276..995ae0809407 100644 --- a/packages/dds/tree/src/simple-tree/api/schemaFactory.ts +++ b/packages/dds/tree/src/simple-tree/api/schemaFactory.ts @@ -226,13 +226,18 @@ export class SchemaFactory< * Prefix appended to the identifiers of all {@link TreeNodeSchema} produced by this builder. * * @remarks - * Generally each developed independently library (possibly a package, but could also be part of a package or multiple packages developed together) should get its own globally unique `scope`. - * Then each schema the library get its own name which is unique within the library. - * These are joined (with a period) to form the globally unique {@link TreeNodeSchemaCore.identifier|schema identifier}. + * Generally each independently developed library + * (possibly a package, but could also be part of a package or multiple packages developed together) + * should get its own unique `scope`. + * Then each schema in the library get a name which is unique within the library. + * The scope and name are joined (with a period) to form the {@link TreeNodeSchemaCore.identifier|schema identifier}. * Following this pattern allows a single application to depend on multiple libraries which define their own schema, and use them together in a single tree without risk of collisions. * If a library logically contains sub-libraries with their own schema, they can be given a scope nested inside the parent scope, such as "ParentScope.ChildScope". * - * Use of {@link https://en.wikipedia.org/wiki/Reverse_domain_name_notation | Reverse domain name notation} or a UUIDv4 is recommended to avoid collisions. + * To avoid collisions between the scopes of libraries + * it is recommended that the libraries use {@link https://en.wikipedia.org/wiki/Reverse_domain_name_notation | Reverse domain name notation} or a UUIDv4 for their scope. + * If this pattern is followed, application can safely use third party libraries without risk of the schema in them colliding. + * * You may opt out of using a scope by passing `undefined`, but note that this increases the risk of collisions. * * @example