From f23e497d5ad05b9af0f90b69f9a383deed0c1e39 Mon Sep 17 00:00:00 2001 From: bobzel Date: Sun, 7 Mar 2021 21:20:53 -0500 Subject: added start of Git functionality within Dash. --- src/fields/Doc.ts | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) (limited to 'src/fields/Doc.ts') diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts index e24821116..c82c05c28 100644 --- a/src/fields/Doc.ts +++ b/src/fields/Doc.ts @@ -503,13 +503,13 @@ export namespace Doc { return alias; } - export async function makeClone(doc: Doc, cloneMap: Map, rtfs: { copy: Doc, key: string, field: RichTextField }[], exclusions: string[], dontCreate: boolean): Promise { + export async function makeClone(doc: Doc, cloneMap: Map, rtfs: { copy: Doc, key: string, field: RichTextField }[], exclusions: string[], dontCreate: boolean, asBranch: boolean): Promise { if (Doc.IsBaseProto(doc)) return doc; if (cloneMap.get(doc[Id])) return cloneMap.get(doc[Id])!; - const copy = dontCreate ? doc : new Doc(undefined, true); + const copy = dontCreate ? asBranch ? (Cast(doc.branchMaster, Doc, null) || doc) : doc : new Doc(undefined, true); cloneMap.set(doc[Id], copy); if (LinkManager.Instance.getAllLinks().includes(doc) && LinkManager.Instance.getAllLinks().indexOf(copy) === -1) LinkManager.Instance.addLink(copy); - const filter = Cast(doc.cloneFieldFilter, listSpec("string"), exclusions); + const filter = Cast(doc.cloneFieldFilter, listSpec("string"), ["branches", ...exclusions]); await Promise.all(Object.keys(doc).map(async key => { if (filter.includes(key)) return; const assignKey = (val: any) => !dontCreate && (copy[key] = val); @@ -519,12 +519,12 @@ export namespace Doc { const list = Cast(doc[key], listSpec(Doc)); const docs = list && (await DocListCastAsync(list))?.filter(d => d instanceof Doc); if (docs !== undefined && docs.length) { - const clones = await Promise.all(docs.map(async d => Doc.makeClone(d, cloneMap, rtfs, exclusions, dontCreate))); + const clones = await Promise.all(docs.map(async d => Doc.makeClone(d, cloneMap, rtfs, exclusions, dontCreate, asBranch))); !dontCreate && assignKey(new List(clones)); } else if (doc[key] instanceof Doc) { - assignKey(key.includes("layout[") ? undefined : key.startsWith("layout") ? doc[key] as Doc : await Doc.makeClone(doc[key] as Doc, cloneMap, rtfs, exclusions, dontCreate)); // reference documents except copy documents that are expanded teplate fields + assignKey(key.includes("layout[") ? undefined : key.startsWith("layout") ? doc[key] as Doc : await Doc.makeClone(doc[key] as Doc, cloneMap, rtfs, exclusions, dontCreate, asBranch)); // reference documents except copy documents that are expanded teplate fields } else { - assignKey(ObjectField.MakeCopy(field)); + !dontCreate && assignKey(ObjectField.MakeCopy(field)); if (field instanceof RichTextField) { if (field.Data.includes('"docid":') || field.Data.includes('"targetId":') || field.Data.includes('"linkId":')) { rtfs.push({ copy, key, field }); @@ -534,7 +534,7 @@ export namespace Doc { }; if (key === "proto") { if (doc[key] instanceof Doc) { - assignKey(await Doc.makeClone(doc[key]!, cloneMap, rtfs, exclusions, dontCreate)); + assignKey(await Doc.makeClone(doc[key]!, cloneMap, rtfs, exclusions, dontCreate, asBranch)); } } else { if (field instanceof RefField) { @@ -552,16 +552,17 @@ export namespace Doc { } })); if (!dontCreate) { - Doc.SetInPlace(copy, "title", "CLONE: " + doc.title, true); - copy.cloneOf = doc; + Doc.SetInPlace(copy, "title", (asBranch ? "BRANCH: " : "CLONE: ") + doc.title, true); + asBranch ? (copy.branchOf = doc) : (copy.cloneOf = doc); + if (!Doc.IsPrototype(copy)) Doc.AddDocToList(doc, "branches", Doc.GetProto(copy)); cloneMap.set(doc[Id], copy); } return copy; } - export async function MakeClone(doc: Doc, dontCreate: boolean = false) { + export async function MakeClone(doc: Doc, dontCreate: boolean = false, asBranch = false) { const cloneMap = new Map(); const rtfMap: { copy: Doc, key: string, field: RichTextField }[] = []; - const copy = await Doc.makeClone(doc, cloneMap, rtfMap, ["context", "annotationOn", "cloneOf"], dontCreate); + const copy = await Doc.makeClone(doc, cloneMap, rtfMap, ["context", "annotationOn", "cloneOf", "branchOf"], dontCreate, asBranch); rtfMap.map(({ copy, key, field }) => { const replacer = (match: any, attr: string, id: string, offset: any, string: any) => { const mapped = cloneMap.get(id); @@ -586,7 +587,7 @@ export namespace Doc { // a.click(); const { clone, map } = await Doc.MakeClone(doc, true); function replacer(key: any, value: any) { - if (["cloneOf", "context", "cursors"].includes(key)) return undefined; + if (["branchOf", "cloneOf", "context", "cursors"].includes(key)) return undefined; else if (value instanceof Doc) { if (key !== "field" && Number.isNaN(Number(key))) { const __fields = value[FieldsSym](); -- cgit v1.2.3-70-g09d2 From 81cfcf5ab5caed1ab5cd052b3e8f00829631018f Mon Sep 17 00:00:00 2001 From: bobzel Date: Mon, 8 Mar 2021 12:03:32 -0500 Subject: fixed bug with branch/clone --- src/client/documents/Gitlike.ts | 15 +++++++-------- src/fields/Doc.ts | 9 ++++++--- 2 files changed, 13 insertions(+), 11 deletions(-) (limited to 'src/fields/Doc.ts') diff --git a/src/client/documents/Gitlike.ts b/src/client/documents/Gitlike.ts index 0ab2df8cd..fddf317bc 100644 --- a/src/client/documents/Gitlike.ts +++ b/src/client/documents/Gitlike.ts @@ -8,8 +8,8 @@ import { Cast, DateCast } from "../../fields/Types"; // we don't have individual timestamps for all fields -- this is a problematic design issue. function GitlikeSynchDocs(bd: Doc, md: Doc) { const fieldKey = Doc.LayoutFieldKey(md); - let bdate = DateCast(bd[`${fieldKey}-lastModified`])?.date; - let mdate = DateCast(md[`${fieldKey}-lastModified`])?.date; + const bdate = DateCast(bd[`${fieldKey}-lastModified`])?.date; + const mdate = DateCast(md[`${fieldKey}-lastModified`])?.date; if (bdate === mdate || bdate > mdate) return; const bdproto = bd && Doc.GetProto(bd); if (bdproto && md) { @@ -35,7 +35,7 @@ async function GitlikePullFromMaster(branch: Doc, suffix = "") { oldDocsFromMaster?.forEach(md => { const bd = branchMainDocs?.find(bd => (Cast(bd.branchOf, Doc, null) || bd) === md); bd && GitlikeSynchDocs(bd, md); - }) + }); // make branch clones of them, then add them to the branch const newlyBranchedDocs = await Promise.all(newDocsFromMaster?.map(async md => (await Doc.MakeClone(md, false, true)).clone) || []); newlyBranchedDocs.forEach(nd => { @@ -55,7 +55,7 @@ async function GitlikeMergeWithMaster(master: Doc, suffix = "") { const branches = await DocListCastAsync(master.branches); branches?.map(async branch => { const branchChildren = await DocListCastAsync(branch[Doc.LayoutFieldKey(branch) + suffix]); - branchChildren?.forEach(async bd => { + branchChildren && await Promise.all(branchChildren.map(async bd => { // see if the branch's child exists on master. const masterChild = Cast(bd.branchOf, Doc, null) || (await Doc.MakeClone(bd, false, true)).clone; // if the branch's child didn't exist on master, we make a branch clone of the child to add to master. @@ -72,9 +72,9 @@ async function GitlikeMergeWithMaster(master: Doc, suffix = "") { Doc.AddDocToList(master, Doc.LayoutFieldKey(master) + suffix, masterChild); // add the masterChild to master (if it's already there, this is a no-op) masterChild.context = master; GitlikeSynchDocs(Doc.GetProto(masterChild), bd); - }); + })); const masterChildren = await DocListCastAsync(master[Doc.LayoutFieldKey(master) + suffix]); - masterChildren?.forEach(async mc => { // see if any master children + masterChildren?.forEach(mc => { // see if any master children if (!branchChildren?.find(bc => bc.branchOf === mc)) { // are not in the list of children for this branch. Doc.RemoveDocFromList(master, Doc.LayoutFieldKey(master) + suffix, mc); // if so, delete the master child since the branch has deleted it. mc.context = undefined; // NOTE if we merge a branch that didn't do a pull, it will look like the branch deleted documents -- need edit timestamps that prevent merging if branch isn't up-to-date with last edit timestamp @@ -92,8 +92,7 @@ async function GitlikeMergeWithMaster(master: Doc, suffix = "") { export async function BranchTask(target: Doc, action: "pull" | "merge") { const func = action === "pull" ? GitlikePullFromMaster : GitlikeMergeWithMaster; await func(target, ""); - const targetChildren = await DocListCast(target[Doc.LayoutFieldKey(target)]); - targetChildren.forEach(async targetChild => await func(targetChild, "-annotations")); + await DocListCast(target[Doc.LayoutFieldKey(target)]).forEach(async targetChild => func(targetChild, "-annotations")); } export async function BranchCreate(target: Doc) { diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts index c82c05c28..05acaf39d 100644 --- a/src/fields/Doc.ts +++ b/src/fields/Doc.ts @@ -509,7 +509,7 @@ export namespace Doc { const copy = dontCreate ? asBranch ? (Cast(doc.branchMaster, Doc, null) || doc) : doc : new Doc(undefined, true); cloneMap.set(doc[Id], copy); if (LinkManager.Instance.getAllLinks().includes(doc) && LinkManager.Instance.getAllLinks().indexOf(copy) === -1) LinkManager.Instance.addLink(copy); - const filter = Cast(doc.cloneFieldFilter, listSpec("string"), ["branches", ...exclusions]); + const filter = [...exclusions, ...Cast(doc.cloneFieldFilter, listSpec("string"), [])]; await Promise.all(Object.keys(doc).map(async key => { if (filter.includes(key)) return; const assignKey = (val: any) => !dontCreate && (copy[key] = val); @@ -554,7 +554,10 @@ export namespace Doc { if (!dontCreate) { Doc.SetInPlace(copy, "title", (asBranch ? "BRANCH: " : "CLONE: ") + doc.title, true); asBranch ? (copy.branchOf = doc) : (copy.cloneOf = doc); - if (!Doc.IsPrototype(copy)) Doc.AddDocToList(doc, "branches", Doc.GetProto(copy)); + if (!Doc.IsPrototype(copy)) { + console.log("ADDING: " + copy.title + " to " + doc.title + "'s branches"); + Doc.AddDocToList(doc, "branches", Doc.GetProto(copy)); + } cloneMap.set(doc[Id], copy); } return copy; @@ -562,7 +565,7 @@ export namespace Doc { export async function MakeClone(doc: Doc, dontCreate: boolean = false, asBranch = false) { const cloneMap = new Map(); const rtfMap: { copy: Doc, key: string, field: RichTextField }[] = []; - const copy = await Doc.makeClone(doc, cloneMap, rtfMap, ["context", "annotationOn", "cloneOf", "branchOf"], dontCreate, asBranch); + const copy = await Doc.makeClone(doc, cloneMap, rtfMap, ["context", "annotationOn", "cloneOf", "branches", "branchOf"], dontCreate, asBranch); rtfMap.map(({ copy, key, field }) => { const replacer = (match: any, attr: string, id: string, offset: any, string: any) => { const mapped = cloneMap.get(id); -- cgit v1.2.3-70-g09d2