Skip to content

Commit

Permalink
tree: Move Json domain to test code, and port to simple-tree schema (m…
Browse files Browse the repository at this point in the history
…icrosoft#22324)

## Description

Move Json domain to test code, and port it to simple-tree schema.
Replace Json schema in test/utils.ts with Json domain.
Remove more schema aware typing logic.
Make a few tests use more concise ways to build the needed test trees.
  • Loading branch information
CraigMacomber authored Aug 28, 2024
1 parent 961c9e8 commit f92e29d
Show file tree
Hide file tree
Showing 44 changed files with 283 additions and 518 deletions.
10 changes: 0 additions & 10 deletions packages/dds/tree/src/domains/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,4 @@
* Licensed under the MIT License.
*/

export {
cursorToJsonObject,
jsonArray,
jsonObject,
jsonRoot,
jsonSchema,
singleJsonCursor,
fieldJsonCursor,
} from "./json/index.js";

export { leaf } from "./leafDomain.js";
5 changes: 0 additions & 5 deletions packages/dds/tree/src/domains/json/fence.json

This file was deleted.

52 changes: 0 additions & 52 deletions packages/dds/tree/src/domains/json/jsonDomainSchema.ts

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -276,9 +276,8 @@ export interface FlexTreeField extends FlexTreeEntity<FlexFieldSchema> {
* Additionally empty fields (those containing no nodes) are not distinguished from fields which do not exist.
* This differs from JavaScript Maps which have a subtle distinction between storing undefined as a value in the map and deleting an entry from the map.
*/
export interface FlexTreeMapNode<in out TSchema extends FlexMapNodeSchema>
extends FlexTreeNode {
readonly schema: TSchema;
export interface FlexTreeMapNode extends FlexTreeNode {
readonly schema: FlexMapNodeSchema;
}

/**
Expand Down
2 changes: 0 additions & 2 deletions packages/dds/tree/src/feature-libraries/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -140,8 +140,6 @@ export {
type FlexListToUnion,
type ExtractItemType,
isLazy,
type NormalizeObjectNodeFields,
type NormalizeField as NormalizeFieldSchema,
type FlexObjectNodeFields,
intoStoredSchema,
intoStoredSchemaCollection,
Expand Down
2 changes: 0 additions & 2 deletions packages/dds/tree/src/feature-libraries/typed-schema/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@ export {
schemaIsLeaf,
schemaIsMap,
schemaIsObjectNode,
type NormalizeObjectNodeFields,
type NormalizeField,
intoStoredSchema,
allowedTypesSchemaSet,
intoStoredSchemaCollection,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -167,11 +167,11 @@ export function validateSchemaCollection(
validateField(
lintConfiguration,
collection,
tree.info,
tree.info as FlexFieldSchema,
() => `Map fields of "${identifier}" schema from library "${tree.builder.name}"`,
errors,
);
if ((tree.info.kind.multiplicity as Multiplicity) === Multiplicity.Single) {
if ((tree.info as FlexFieldSchema).kind.multiplicity === Multiplicity.Single) {
errors.push(
`Map fields of "${identifier}" schema from library "${tree.builder.name}" has kind with multiplicity "Single". This is invalid since it requires all possible field keys to have a value under them.`,
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,6 @@ export interface FlexObjectNodeFields {
readonly [key: string]: FlexFieldSchema;
}

/**
*/
export type NormalizeObjectNodeFields<T extends FlexObjectNodeFields> = {
readonly [Property in keyof T]: NormalizeField<T[Property]>;
};

/**
* A placeholder to use in {@link https://www.typescriptlang.org/docs/handbook/2/generics.html#generic-constraints | extends constraints} when using the real type breaks compilation of some recursive types due to {@link https://github.com/microsoft/TypeScript/issues/55758 | a design limitation of TypeScript}.
*
Expand All @@ -66,14 +60,11 @@ export type Unenforced<_DesiredExtendsConstraint> = unknown;
* This can not be enforced using TypeScript since doing so breaks recursive type support.
* See note on SchemaBuilder.fieldRecursive.
*/
export abstract class TreeNodeSchemaBase<
const out Name extends string = string,
const out Specification = unknown,
> {
export abstract class TreeNodeSchemaBase<const out Specification = unknown> {
protected _typeCheck!: MakeNominal;
protected constructor(
public readonly builder: Named<string>,
public readonly name: TreeNodeSchemaIdentifier<Name>,
public readonly name: TreeNodeSchemaIdentifier,
public readonly info: Specification,
public readonly stored: TreeNodeStoredSchema,
) {}
Expand All @@ -82,23 +73,17 @@ export abstract class TreeNodeSchemaBase<

/**
*/
export class FlexMapNodeSchema<
const out Name extends string = string,
const out Specification extends Unenforced<FlexMapFieldSchema> = FlexMapFieldSchema,
> extends TreeNodeSchemaBase<Name, Specification> {
export class FlexMapNodeSchema extends TreeNodeSchemaBase {
public get mapFields(): FlexMapFieldSchema {
return this.info as FlexMapFieldSchema;
}

protected _typeCheck2?: MakeNominal;
public static create<
const Name extends string,
const Specification extends FlexMapFieldSchema,
>(
public static create<const Name extends string>(
builder: Named<string>,
name: TreeNodeSchemaIdentifier<Name>,
specification: Specification,
): FlexMapNodeSchema<Name, Specification> {
specification: FlexMapFieldSchema,
): FlexMapNodeSchema {
return new FlexMapNodeSchema(
builder,
name,
Expand All @@ -114,7 +99,7 @@ export class FlexMapNodeSchema<

/**
*/
export class LeafNodeSchema extends TreeNodeSchemaBase<string, ValueSchema> {
export class LeafNodeSchema extends TreeNodeSchemaBase<ValueSchema> {
public get leafValue(): ValueSchema {
return this.info;
}
Expand All @@ -140,7 +125,7 @@ export class LeafNodeSchema extends TreeNodeSchemaBase<string, ValueSchema> {

/**
*/
export class FlexObjectNodeSchema extends TreeNodeSchemaBase<string, FlexObjectNodeFields> {
export class FlexObjectNodeSchema extends TreeNodeSchemaBase {
protected _typeCheck2?: MakeNominal;
public readonly identifierFieldKeys: readonly FieldKey[] = [];

Expand All @@ -149,13 +134,9 @@ export class FlexObjectNodeSchema extends TreeNodeSchemaBase<string, FlexObjectN
name: TreeNodeSchemaIdentifier,
specification: FlexObjectNodeFields,
): FlexObjectNodeSchema {
const objectNodeFieldsObject: NormalizeObjectNodeFields<FlexObjectNodeFields> =
normalizeStructFields<FlexObjectNodeFields>(specification);
const objectNodeFields: ObjectToMap<
NormalizeObjectNodeFields<FlexObjectNodeFields>,
FieldKey,
FlexFieldSchema
> = objectToMapTyped(objectNodeFieldsObject);
const objectNodeFieldsObject = normalizeStructFields(specification);
const objectNodeFields: ObjectToMap<FlexObjectNodeFields, FieldKey, FlexFieldSchema> =
objectToMapTyped(objectNodeFieldsObject);
return new FlexObjectNodeSchema(
builder,
name,
Expand All @@ -169,7 +150,7 @@ export class FlexObjectNodeSchema extends TreeNodeSchemaBase<string, FlexObjectN
builder: Named<string>,
name: TreeNodeSchemaIdentifier,
info: FlexObjectNodeFields,
public readonly objectNodeFieldsObject: NormalizeObjectNodeFields<FlexObjectNodeFields>,
public readonly objectNodeFieldsObject: FlexObjectNodeFields,
// Allows reading fields through the normal map.
// Stricter typing caused Specification to no longer be covariant, so has been removed.
public readonly objectNodeFields: ReadonlyMap<FieldKey, FlexFieldSchema>,
Expand Down Expand Up @@ -199,16 +180,9 @@ export class FlexObjectNodeSchema extends TreeNodeSchemaBase<string, FlexObjectN
*/
export type FlexTreeNodeSchema = TreeNodeSchemaBase;

/**
* Convert FieldSchemaSpecification | undefined into TreeFieldSchema.
*/
export type NormalizeField<T extends FlexFieldSchema | undefined> = T extends FlexFieldSchema
? T
: FlexFieldSchema<typeof FieldKinds.forbidden>;

function normalizeStructFields<T extends FlexObjectNodeFields>(
fields: T,
): NormalizeObjectNodeFields<T> {
): FlexObjectNodeFields {
const out: Record<string, FlexFieldSchema> = {};
// eslint-disable-next-line no-restricted-syntax
for (const key in fields) {
Expand All @@ -217,16 +191,16 @@ function normalizeStructFields<T extends FlexObjectNodeFields>(
out[key] = normalizeField(element);
}
}
return out as NormalizeObjectNodeFields<T>;
return out;
}

function normalizeField<T extends FlexFieldSchema | undefined>(t: T): NormalizeField<T> {
function normalizeField(t: FlexFieldSchema | undefined): FlexFieldSchema {
if (t === undefined) {
return FlexFieldSchema.empty as unknown as NormalizeField<T>;
return FlexFieldSchema.empty;
}

assert(t instanceof FlexFieldSchema, 0x6ae /* invalid TreeFieldSchema */);
return t as NormalizeField<T>;
return t;
}

/**
Expand Down
2 changes: 1 addition & 1 deletion packages/dds/tree/src/simple-tree/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,4 +122,4 @@ export {
} from "./jsonSchema.js";
export { getJsonSchema } from "./getJsonSchema.js";
export { getSimpleSchema } from "./getSimpleSchema.js";
export { toStoredSchema, getStoredSchema } from "./toFlexSchema.js";
export { toStoredSchema, getStoredSchema, getFlexSchema } from "./toFlexSchema.js";
8 changes: 2 additions & 6 deletions packages/dds/tree/src/simple-tree/mapNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@
*/

import {
type FieldKinds,
type FlexFieldSchema,
type FlexMapNodeSchema,
type FlexTreeMapNode,
type FlexTreeNode,
Expand Down Expand Up @@ -145,10 +143,8 @@ abstract class CustomMapNodeBase<const T extends ImplicitAllowedTypes> extends T
return this.entries();
}

private get innerNode(): InnerNode &
FlexTreeMapNode<FlexMapNodeSchema<string, FlexFieldSchema<typeof FieldKinds.optional>>> {
return getOrCreateInnerNode(this) as InnerNode &
FlexTreeMapNode<FlexMapNodeSchema<string, FlexFieldSchema<typeof FieldKinds.optional>>>;
private get innerNode(): InnerNode & FlexTreeMapNode {
return getOrCreateInnerNode(this) as InnerNode & FlexTreeMapNode;
}

private editor(key: string): OptionalFieldEditBuilder<ExclusiveMapTree> {
Expand Down
8 changes: 7 additions & 1 deletion packages/dds/tree/src/simple-tree/toFlexSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,13 @@ export function convertNodeSchema(
);
// Lookup of cached schema is done here instead of before since walking the schema recursively to populate schemaMap is still required.
const cached = cachedFlexSchemaFromClassSchema(schema);
out = cached ?? FlexMapNodeSchema.create(builder, brand(schema.identifier), field);
out =
cached ??
FlexMapNodeSchema.create(
builder,
brand<TreeNodeSchemaIdentifier>(schema.identifier),
field,
);
break;
}
case NodeKind.Array: {
Expand Down
10 changes: 2 additions & 8 deletions packages/dds/tree/src/test/cursorTestSuite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,9 @@ import {
prefixPath,
} from "../feature-libraries/index.js";
import { brand } from "../util/index.js";

import {
expectEqualFieldPaths,
expectEqualPaths,
IdentifierSchema,
JsonArray,
JsonObject,
} from "./utils.js";
import { expectEqualFieldPaths, expectEqualPaths, IdentifierSchema } from "./utils.js";
import { SchemaFactory } from "../simple-tree/index.js";
import { JsonArray, JsonObject } from "./json/index.js";

const sf = new SchemaFactory("Cursor Test Suite");

Expand Down
4 changes: 2 additions & 2 deletions packages/dds/tree/src/test/domains/json/jsonCursor.bench.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import {
initializeForest,
moveToDetachedField,
} from "../../../core/index.js";
import { cursorToJsonObject, singleJsonCursor } from "../../../domains/index.js";
import {
basicChunkTree,
defaultChunkPolicy,
Expand All @@ -34,14 +33,15 @@ import {
} from "../../../feature-libraries/index.js";
import { brand, type JsonCompatible } from "../../../util/index.js";

import { JsonUnion, testIdCompressor, testRevisionTagCodec } from "../../utils.js";
import { testIdCompressor, testRevisionTagCodec } from "../../utils.js";
import { averageValues, sum, sumMap } from "./benchmarks.js";
import { Canada, generateCanada } from "./canada.js";
import { CitmCatalog, generateCitmJson } from "./citm.js";
import { clone } from "./jsObjectUtil.js";
import { generateTwitterJsonByByteSize } from "./twitter.js";
// eslint-disable-next-line import/no-internal-modules
import { toStoredSchema } from "../../../simple-tree/toFlexSchema.js";
import { JsonUnion, cursorToJsonObject, singleJsonCursor } from "../../json/index.js";

// Shared tree keys that map to the type used by the Twitter type/dataset
export const TwitterKey = {
Expand Down
3 changes: 1 addition & 2 deletions packages/dds/tree/src/test/domains/json/jsonCursor.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@
* Licensed under the MIT License.
*/

// eslint-disable-next-line import/no-internal-modules
import { cursorToJsonObject, singleJsonCursor } from "../../../domains/json/index.js";
import { cursorToJsonObject, singleJsonCursor } from "../../json/index.js";
import type { JsonCompatible } from "../../../util/index.js";
import { testSpecializedCursor } from "../../cursorTestSuite.js";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,9 @@ import {
testGeneralPurposeTreeCursor,
testSpecializedFieldCursor,
} from "../../cursorTestSuite.js";

import { numberSequenceField, validateChunkCursor } from "./fieldCursorTestUtilities.js";
import { emptyShape, testData } from "./uniformChunkTestData.js";
import { JsonObject } from "../../utils.js";
import { JsonObject } from "../../json/index.js";

describe("basic chunk", () => {
it("calling chunkTree on existing chunk adds a reference", () => {
Expand Down
Loading

0 comments on commit f92e29d

Please sign in to comment.