Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Automation: main-next integrate #18699

Merged
merged 7 commits into from
Dec 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
// @alpha
export type ConnectionMode = "write" | "read";

// @internal (undocumented)
// @alpha (undocumented)
export enum FileMode {
// (undocumented)
Directory = "040000",
Expand All @@ -30,13 +30,13 @@ export type IApprovedProposal = {
approvalSequenceNumber: number;
} & ISequencedProposal;

// @internal (undocumented)
// @alpha (undocumented)
export interface IAttachment {
// (undocumented)
id: string;
}

// @internal
// @alpha
export interface IBlob {
contents: string;
encoding: "utf-8" | "base64";
Expand Down Expand Up @@ -381,7 +381,7 @@ export interface ISnapshotTreeEx extends ISnapshotTree {
// @alpha
export type IsoDate = string;

// @internal
// @alpha
export interface ISummaryAck {
handle: string;
summaryProposal: ISummaryProposal;
Expand Down Expand Up @@ -420,15 +420,15 @@ export interface ISummaryHandle {
type: SummaryType.Handle;
}

// @internal
// @alpha
export interface ISummaryNack {
code?: number;
message?: string;
retryAfter?: number;
summaryProposal: ISummaryProposal;
}

// @internal
// @alpha
export interface ISummaryProposal {
summarySequenceNumber: number;
}
Expand Down Expand Up @@ -484,15 +484,15 @@ export interface ITrace {
timestamp: number;
}

// @internal (undocumented)
// @alpha (undocumented)
export interface ITree {
// (undocumented)
entries: ITreeEntry[];
id?: string;
unreferenced?: true;
}

// @internal
// @alpha
export type ITreeEntry = {
path: string;
mode: FileMode;
Expand Down Expand Up @@ -590,7 +590,7 @@ export type SummaryType = SummaryType.Attachment | SummaryType.Blob | SummaryTyp
// @alpha
export type SummaryTypeNoHandle = SummaryType.Tree | SummaryType.Blob | SummaryType.Attachment;

// @internal
// @alpha
export enum TreeEntry {
// (undocumented)
Attachment = "Attachment",
Expand Down
6 changes: 3 additions & 3 deletions common/lib/protocol-definitions/src/protocol.ts
Original file line number Diff line number Diff line change
Expand Up @@ -437,7 +437,7 @@ export interface IServerError {

/**
* Data about the original proposed summary message.
* @internal
* @alpha
*/
export interface ISummaryProposal {
/**
Expand All @@ -448,7 +448,7 @@ export interface ISummaryProposal {

/**
* Contents of summary ack expected from the server.
* @internal
* @alpha
*/
export interface ISummaryAck {
/**
Expand All @@ -464,7 +464,7 @@ export interface ISummaryAck {

/**
* Contents of summary nack expected from the server.
* @internal
* @alpha
*/
export interface ISummaryNack {
/**
Expand Down
12 changes: 6 additions & 6 deletions common/lib/protocol-definitions/src/storage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export interface IDocumentAttributes {
}

/**
* @internal
* @alpha
*/
export enum FileMode {
File = "100644",
Expand All @@ -32,7 +32,7 @@ export enum FileMode {

/**
* Raw blob stored within the tree.
* @internal
* @alpha
*/
export interface IBlob {
/**
Expand All @@ -47,7 +47,7 @@ export interface IBlob {
}

/**
* @internal
* @alpha
*/
export interface IAttachment {
id: string;
Expand All @@ -62,7 +62,7 @@ export interface ICreateBlobResponse {

/**
* A tree entry wraps a path with a type of node.
* @internal
* @alpha
*/
export type ITreeEntry = {
/**
Expand Down Expand Up @@ -92,7 +92,7 @@ export type ITreeEntry = {

/**
* Type of entries that can be stored in a tree.
* @internal
* @alpha
*/
export enum TreeEntry {
Blob = "Blob",
Expand All @@ -101,7 +101,7 @@ export enum TreeEntry {
}

/**
* @internal
* @alpha
*/
export interface ITree {
entries: ITreeEntry[];
Expand Down
2 changes: 2 additions & 0 deletions experimental/dds/tree2/api-report/tree2.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -452,6 +452,7 @@ export interface FieldAnchor {
interface FieldChanges<TTree = ProtoNode> {
// @deprecated
readonly build?: readonly DetachedNodeBuild<TTree>[];
// @deprecated
readonly destroy?: readonly DetachedNodeDestruction[];
readonly global?: readonly DetachedNodeChanges<TTree>[];
readonly local?: readonly Mark<TTree>[];
Expand Down Expand Up @@ -1585,6 +1586,7 @@ export enum RevertResult {
// @alpha
interface Root<TTree = ProtoNode> {
readonly build?: readonly DetachedNodeBuild<TTree>[];
readonly destroy?: readonly DetachedNodeDestruction[];
readonly fields?: FieldMap<TTree>;
}

Expand Down
14 changes: 13 additions & 1 deletion experimental/dds/tree2/src/core/tree/delta.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,15 @@ export interface Root<TTree = ProtoNode> {
* then the build should be listed under ID A.
*/
readonly build?: readonly DetachedNodeBuild<TTree>[];
/**
* New detached nodes to be destroyed.
* The ordering has no significance.
*
* Destruction instructions for a root that is undergoing a rename should be listed under the final name.
* For example, if one wishes to destroy a tree which is being renamed from ID A to ID B,
* then the destruction should be listed under ID B.
*/
readonly destroy?: readonly DetachedNodeDestruction[];
}
/**
* The default representation for inserted content.
Expand Down Expand Up @@ -225,9 +234,12 @@ export interface FieldChanges<TTree = ProtoNode> {
*/
readonly build?: readonly DetachedNodeBuild<TTree>[];
/**
* New detached nodes to be constructed.
* New detached nodes to be destroyed.
* The ordering has no significance.
*
* @deprecated - Destroys should be set at the root.
* TODO:6308 migrate all reader/writers away from this and remove it.
*
* Destruction instructions for a root that is undergoing a rename should be listed under the final name.
* For example, if one wishes to destroy a tree which is being renamed from ID A to ID B,
* then the destruction should be listed under ID B.
Expand Down
14 changes: 11 additions & 3 deletions experimental/dds/tree2/src/core/tree/visitDelta.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ export function visitDelta(
};
visitFieldMarks(delta.fields, visitor, attachConfig);
fixedPointVisitOfRoots(visitor, attachPassRoots, attachConfig);
collectDestroys(delta.destroy, attachConfig);
for (const { id, count } of rootDestructions) {
for (let i = 0; i < count; i += 1) {
const offsetId = offsetDetachId(id, i);
Expand Down Expand Up @@ -355,9 +356,7 @@ function visitNode(
*/
function detachPass(delta: Delta.FieldChanges, visitor: DeltaVisitor, config: PassConfig): void {
processBuilds(delta.build, config, visitor);
if (delta.destroy !== undefined) {
config.rootDestructions.push(...delta.destroy);
}
collectDestroys(delta.destroy, config);
if (delta.global !== undefined) {
for (const { id, fields } of delta.global) {
const root = config.detachedFieldIndex.getEntry(id);
Expand Down Expand Up @@ -419,6 +418,15 @@ function processBuilds(
}
}

function collectDestroys(
destroys: readonly Delta.DetachedNodeDestruction[] | undefined,
config: PassConfig,
) {
if (destroys !== undefined) {
config.rootDestructions.push(...destroys);
}
}

/**
* Preforms the following:
* - Executes attaches (top-down) applying nested changes on the attached nodes
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,8 @@ export const optionalChangeRebaser: FieldChangeRebaser<OptionalChangeset> = {
}

for (const [id, childChange] of change.childChanges) {
const originalId = nextDstToSrc.get(withIntention(id)) ?? id;
const intentionedId = withIntention(id);
const originalId = current.dstToSrc.get(intentionedId) ?? intentionedId;
const existingChanges = childChangesByOriginalId.get(originalId);
const taggedChange = tagChange(childChange, revision);
if (existingChanges === undefined) {
Expand Down Expand Up @@ -278,7 +279,7 @@ export const optionalChangeRebaser: FieldChangeRebaser<OptionalChangeset> = {
build: composedBuilds,
moves: composedMoves,
childChanges: Array.from(childChangesByOriginalId.entries(), ([id, childChanges]) => [
current.srcToDst.get(id)?.[0] ?? id,
id,
composeChild(childChanges),
]),
};
Expand Down Expand Up @@ -306,7 +307,7 @@ export const optionalChangeRebaser: FieldChangeRebaser<OptionalChangeset> = {
return { revision: id.revision ?? revision, localId: id.localId };
};
for (const [src, dst] of moves) {
invertIdMap.set(dst, src);
invertIdMap.set(src, dst);
}

let inverseFillsSelf = false;
Expand Down Expand Up @@ -417,30 +418,14 @@ export const optionalChangeRebaser: FieldChangeRebaser<OptionalChangeset> = {

const overChildChangesBySrc = new RegisterMap<NodeChangeset>();
for (const [id, childChange] of overChange.childChanges ?? []) {
overChildChangesBySrc.set(overDstToSrc.get(withIntention(id)) ?? id, childChange);
}

// Maps the content occupying a given register id in the output context of `change` to the register id
// that content occupies in the output context of the rebased change.
// This is necessary since child changes to nodes are keyed on the register they occupy in the output
// context of the changeset, and `change` might make child changes to content which it doesn't move, but
// `over` does.
const renamedDsts = new RegisterMap<RegisterId>();
for (const [_, dst] of moves) {
renamedDsts.set(dst, dst);
}
for (const [src, dst] of overSrcToDst.entries()) {
if (!renamedDsts.has(src)) {
renamedDsts.set(src, dst);
}
overChildChangesBySrc.set(withIntention(id) ?? id, childChange);
}

const rebasedChildChanges: typeof childChanges = [];
for (const [id, childChange] of childChanges) {
const rebasedId = renamedDsts.get(id) ?? id;
// locate corresponding child change
const srcId = changeDstToSrc.get(id) ?? id;
const overChildChange = overChildChangesBySrc.get(srcId);
const overChildChange = overChildChangesBySrc.get(id);

const rebasedId = overSrcToDst.get(id) ?? id;
const rebasedChildChange = rebaseChild(
childChange,
overChildChange,
Expand Down Expand Up @@ -568,15 +553,12 @@ export function optionalFieldIntoDelta(
delta.build = builds;
}

const dstToSrc = new RegisterMap<RegisterId>();

let markIsANoop = true;
const mark: Mutable<Delta.Mark> = { count: 1 };

if (change.moves.length > 0) {
const renames: Delta.DetachedNodeRename[] = [];
for (const [src, dst] of change.moves) {
dstToSrc.set(dst, src);
if (src === "self" && dst !== "self") {
mark.detach = { major: dst.revision ?? revision, minor: dst.localId };
markIsANoop = false;
Expand All @@ -600,12 +582,11 @@ export function optionalFieldIntoDelta(
if (change.childChanges.length > 0) {
const globals: Delta.DetachedNodeChanges[] = [];
for (const [id, childChange] of change.childChanges) {
const srcId = dstToSrc.get(id) ?? id;
const childDelta = deltaFromChild(childChange);
if (srcId !== "self") {
if (id !== "self") {
const fields = childDelta;
globals.push({
id: { major: srcId.revision ?? revision, minor: srcId.localId },
id: { major: id.revision ?? revision, minor: id.localId },
fields,
});
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,7 @@ export interface OptionalChangeset {
/**
* Nested changes to nodes that occupy registers.
*
* Nodes are identified by the register they occupy in the *output* context of the changeset.
* Note that this is different from the delta format.
* Switching this to be consistent is tracked by AB#6296.
* Nodes are identified by the register they occupy in the *input* context of the changeset.
*/
childChanges: [register: RegisterId, childChange: NodeChangeset][];

Expand Down
2 changes: 0 additions & 2 deletions experimental/dds/tree2/src/simple-tree/proxies.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1095,8 +1095,6 @@ function extractContentIfProxy<T>(input: T): {
}

const classKind = content instanceof NodeBase ? getNodeKind(content) : undefined;
// TODO: This checking could be made stronger by using `class-tree/Tree.schema(content).kind`
// to get the type when `content` is a proxy. At the moment, importing `Tree.schema` causes a cycle.
let type: "object" | "list" | "map" | "leaf";
if (isFluidHandle(content)) {
type = "leaf";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ describe("defaultFieldKinds", () => {
[{ localId: brand(41) }, "self", "nodeTargeting"],
["self", { localId: brand(1) }, "cellTargeting"],
],
childChanges: [["self", nodeChange1]],
childChanges: [[{ localId: brand(41) }, nodeChange1]],
};

/**
Expand Down Expand Up @@ -167,7 +167,9 @@ describe("defaultFieldKinds", () => {
"cellTargeting",
],
],
childChanges: [["self", nodeChange1]],
childChanges: [
[{ localId: brand(41), revision: change1.revision }, nodeChange1],
],
};
const actual = fieldHandler.rebaser.compose(
[change1, taggedChildChange1],
Expand Down Expand Up @@ -206,9 +208,7 @@ describe("defaultFieldKinds", () => {
"cellTargeting",
],
],
childChanges: [
[{ revision: change1.revision, localId: brand(1) }, nodeChange1],
],
childChanges: [["self", nodeChange1]],
};
assertEqual(makeAnonChange(actual), makeAnonChange(expected2));
});
Expand Down Expand Up @@ -260,9 +260,7 @@ describe("defaultFieldKinds", () => {
"cellTargeting",
],
],
childChanges: [
[{ localId: brand(41), revision: taggedChange.revision }, nodeChange2],
],
childChanges: [["self", nodeChange2]],
}),
);
});
Expand Down
Loading
Loading