diff --git a/core/block/editor/state/change.go b/core/block/editor/state/change.go index 7383f5b23..c22b5cf4b 100644 --- a/core/block/editor/state/change.go +++ b/core/block/editor/state/change.go @@ -77,7 +77,6 @@ func NewDocFromSnapshot(rootId string, snapshot *pb.ChangeSnapshot, opts ...Snap rootId: rootId, blocks: blocks, details: detailsToSave, - extraRelations: snapshot.Data.ExtraRelations, relationLinks: snapshot.Data.RelationLinks, objectTypes: snapshot.Data.ObjectTypes, fileKeys: fileKeys, diff --git a/core/block/editor/state/state.go b/core/block/editor/state/state.go index 7510e820f..db6f83b55 100644 --- a/core/block/editor/state/state.go +++ b/core/block/editor/state/state.go @@ -826,6 +826,13 @@ func (s *State) SetDetailAndBundledRelation(key bundle.RelationKey, value *types func (s *State) SetLocalDetail(key string, value *types.Value) { if s.localDetails == nil && s.parent != nil { + d := s.parent.Details() + if d.GetFields() != nil { + // optimisation so we don't need to copy the struct if nothing has changed + if prev, exists := d.Fields[key]; exists && prev.Equal(value) { + return + } + } s.localDetails = pbtypes.CopyStruct(s.parent.LocalDetails()) } if s.localDetails == nil || s.localDetails.Fields == nil { @@ -861,7 +868,14 @@ func (s *State) SetDetail(key string, value *types.Value) { } if s.details == nil && s.parent != nil { - s.details = pbtypes.CopyStruct(s.parent.Details()) + d := s.parent.Details() + if d.GetFields() != nil { + // optimisation so we don't need to copy the struct if nothing has changed + if prev, exists := d.Fields[key]; exists && prev.Equal(value) { + return + } + } + s.details = pbtypes.CopyStruct(d) } if s.details == nil || s.details.Fields == nil { s.details = &types.Struct{Fields: map[string]*types.Value{}} @@ -910,16 +924,18 @@ func (s *State) SetObjectTypesToMigrate(objectTypes []string) *State { } func (s *State) InjectDerivedDetails() { - if s.IsTheHeaderChange() { - return + id := s.RootId() + if id != "" { + s.SetDetailAndBundledRelation(bundle.RelationKeyId, pbtypes.String(id)) } - s.SetDetailAndBundledRelation(bundle.RelationKeyId, pbtypes.String(s.RootId())) - if ot := s.ObjectType(); ot != "" { s.SetDetailAndBundledRelation(bundle.RelationKeyType, pbtypes.String(ot)) } - s.SetDetailAndBundledRelation(bundle.RelationKeySnippet, pbtypes.String(s.Snippet())) + snippet := s.Snippet() + if snippet != "" || s.LocalDetails() != nil { + s.SetDetailAndBundledRelation(bundle.RelationKeySnippet, pbtypes.String(snippet)) + } } func ListSmartblockTypes(objectId string) ([]int, error) { @@ -946,9 +962,6 @@ func ListSmartblockTypes(objectId string) ([]int, error) { } func (s *State) InjectLocalDetails(localDetails *types.Struct) { - if s.IsTheHeaderChange() { - return - } for key, v := range localDetails.GetFields() { if v == nil { continue @@ -1387,7 +1400,11 @@ func (s *State) ParentState() *State { // IsTheHeaderChange return true if the state is the initial header change // header change is the empty change without any blocks or details except protocol data func (s *State) IsTheHeaderChange() bool { - return s.changeId == s.rootId || s.changeId == "" && s.parent == nil + b := s.changeId == s.rootId || s.changeId == "" && s.parent == nil + if b { + return true + } + return false } func (s *State) RemoveDetail(keys ...string) (ok bool) { diff --git a/core/block/source/bundledrelation.go b/core/block/source/bundledrelation.go index ad7408126..59c51e88e 100644 --- a/core/block/source/bundledrelation.go +++ b/core/block/source/bundledrelation.go @@ -62,6 +62,7 @@ func (v *bundledRelation) getDetails(id string) (p *types.Struct, err error) { details.Fields[bundle.RelationKeyWorkspaceId.String()] = pbtypes.String(addr.AnytypeMarketplaceWorkspace) details.Fields[bundle.RelationKeyIsReadonly.String()] = pbtypes.Bool(true) details.Fields[bundle.RelationKeyType.String()] = pbtypes.String(bundle.TypeKeyRelation.BundledURL()) + details.Fields[bundle.RelationKeyId.String()] = pbtypes.String(id) return details, nil } diff --git a/util/builtinobjects/builtinobjects.go b/util/builtinobjects/builtinobjects.go index 4db9b573f..46494d75f 100644 --- a/util/builtinobjects/builtinobjects.go +++ b/util/builtinobjects/builtinobjects.go @@ -306,13 +306,13 @@ func (b *builtinObjects) createObject(rd io.ReadCloser) (err error) { if isArchived { return fmt.Errorf("object has isarchived == true") } - st := state.NewDocFromSnapshot("", snapshot).(*state.State) - oldId := st.RootId() + oldId := pbtypes.GetString(snapshot.Data.Details, bundle.RelationKeyId.String()) newId, exists := b.idsMap[oldId] if !exists { - return fmt.Errorf("new id not found for '%s'", st.RootId()) + return fmt.Errorf("new id not found for '%s'", oldId) } + st := state.NewDocFromSnapshot(oldId, snapshot).(*state.State) st.SetRootId(newId) a := st.Get(newId) m := a.Model() diff --git a/util/builtintemplate/builtintemplate.go b/util/builtintemplate/builtintemplate.go index 115160198..64a23edf3 100644 --- a/util/builtintemplate/builtintemplate.go +++ b/util/builtintemplate/builtintemplate.go @@ -5,6 +5,7 @@ import ( "bytes" "context" "crypto/md5" + _ "embed" "encoding/binary" "encoding/hex" "fmt" @@ -23,8 +24,6 @@ import ( "github.com/anytypeio/go-anytype-middleware/pkg/lib/localstore/addr" "github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/model" "github.com/anytypeio/go-anytype-middleware/util/pbtypes" - - _ "embed" ) const CName = "builtintemplate" @@ -96,7 +95,9 @@ func (b *builtinTemplate) registerBuiltin(rd io.ReadCloser) (err error) { if err = snapshot.Unmarshal(data); err != nil { return } + st := state.NewDocFromSnapshot("", snapshot, state.DoNotMigrateTypes).(*state.State) + st = st.NewState() id := st.RootId() st = st.Copy() st.SetLocalDetail(bundle.RelationKeyTemplateIsBundled.String(), pbtypes.Bool(true))