diff --git a/core/block/editor/smartblock/links.go b/core/block/editor/smartblock/links.go index efc09dcb5..2dce27421 100644 --- a/core/block/editor/smartblock/links.go +++ b/core/block/editor/smartblock/links.go @@ -29,7 +29,7 @@ func (sb *smartBlock) updateBackLinks(s *state.State) { func (sb *smartBlock) injectLinksDetails(s *state.State) { links := sb.navigationalLinks(s) links = slice.RemoveMut(links, sb.Id()) - s.SetLocalDetail(bundle.RelationKeyLinks.String(), pbtypes.StringList(links)) + s.SetLocalDetail(bundle.RelationKeyLinks, pbtypes.StringList(links)) } func (sb *smartBlock) navigationalLinks(s *state.State) (ids []string) { @@ -98,7 +98,7 @@ func (sb *smartBlock) collectRelationLinks(s *state.State) (ids []string) { } // Add all object relation values as dependents - for _, targetID := range pbtypes.GetStringList(det, rel.Key) { + for _, targetID := range det.GetStringListOrDefault(domain.RelationKey(rel.Key), nil) { if targetID != "" { ids = append(ids, targetID) } diff --git a/core/block/editor/smartblock/smartblock.go b/core/block/editor/smartblock/smartblock.go index 347cd1b07..ce4d2de38 100644 --- a/core/block/editor/smartblock/smartblock.go +++ b/core/block/editor/smartblock/smartblock.go @@ -16,7 +16,6 @@ import ( // nolint:misspell "github.com/anyproto/any-sync/commonspace/object/tree/objecttree" "github.com/anyproto/any-sync/commonspace/objecttreebuilder" - "github.com/gogo/protobuf/types" "github.com/anyproto/anytype-heart/core/block/editor/state" "github.com/anyproto/anytype-heart/core/block/editor/template" @@ -147,7 +146,7 @@ type SmartBlock interface { HasRelation(s *state.State, relationKey string) bool AddRelationLinks(ctx session.Context, relationIds ...string) (err error) AddRelationLinksToState(s *state.State, relationIds ...string) (err error) - RemoveExtraRelations(ctx session.Context, relationKeys []string) (err error) + RemoveExtraRelations(ctx session.Context, relationKeys []domain.RelationKey) (err error) SetVerticalAlign(ctx session.Context, align model.BlockVerticalAlign, ids ...string) error SetIsDeleted() IsDeleted() bool @@ -180,7 +179,7 @@ type DocInfo struct { Heads []string Creator string Type domain.TypeKey - Details *types.Struct + Details *domain.Details SmartblockType smartblock.SmartBlockType } @@ -225,7 +224,7 @@ type smartBlock struct { sessions map[string]session.Context undo undo.History source source.Source - lastDepDetails map[string]*pb.EventObjectDetailsSet + lastDepDetails map[string]*domain.Details restrictions restriction.Restrictions isDeleted bool disableLayouts bool @@ -321,7 +320,7 @@ func (sb *smartBlock) Init(ctx *InitContext) (err error) { } sb.undo = undo.NewHistory(0) sb.restrictions = sb.restrictionService.GetRestrictions(sb) - sb.lastDepDetails = map[string]*pb.EventObjectDetailsSet{} + sb.lastDepDetails = map[string]*domain.Details{} if ctx.State != nil { // need to store file keys in case we have some new files in the state sb.storeFileKeys(ctx.State) @@ -350,11 +349,12 @@ func (sb *smartBlock) Init(ctx *InitContext) (err error) { } // Add bundled relations var relKeys []domain.RelationKey - for k := range ctx.State.Details().GetFields() { + ctx.State.Details().Iterate(func(k domain.RelationKey, _ any) bool { if bundle.HasRelation(k) { - relKeys = append(relKeys, domain.RelationKey(k)) + relKeys = append(relKeys, k) } - } + return true + }) ctx.State.AddBundledRelationLinks(relKeys...) if ctx.IsNewObject && ctx.State != nil { source.NewSubObjectsAndProfileLinksMigration(sb.Type(), sb.space, sb.currentParticipantId, sb.objectStore).Migrate(ctx.State) @@ -469,7 +469,7 @@ func (sb *smartBlock) fetchMeta() (details []*model.ObjectViewDetailsSet, err er // add self details details = append(details, &model.ObjectViewDetailsSet{ Id: sb.Id(), - Details: sb.CombinedDetails(), + Details: sb.CombinedDetails().ToProto(), }) for _, rec := range records { @@ -509,10 +509,10 @@ func (sb *smartBlock) onMetaChange(details *domain.Details) { id := details.GetStringOrDefault(bundle.RelationKeyId, "") msgs := []*pb.EventMessage{} if v, exists := sb.lastDepDetails[id]; exists { - diff := pbtypes.StructDiff(v.Details, details) + diff := domain.StructDiff(v, details) if id == sb.Id() { // if we've got update for ourselves, we are only interested in local-only details, because the rest details changes will be appended when applying records in the current sb - diff = pbtypes.StructFilterKeys(diff, bundle.LocalRelationsKeys) + diff = diff.CopyOnlyWithKeys(bundle.LocalRelationsKeys) } msgs = append(msgs, state.StructDiffIntoEvents(id, diff)...) @@ -521,15 +521,12 @@ func (sb *smartBlock) onMetaChange(details *domain.Details) { Value: &pb.EventMessageValueOfObjectDetailsSet{ ObjectDetailsSet: &pb.EventObjectDetailsSet{ Id: id, - Details: details, + Details: details.ToProto(), }, }, }) } - sb.lastDepDetails[id] = &pb.EventObjectDetailsSet{ - Id: id, - Details: details, - } + sb.lastDepDetails[id] = details if len(msgs) == 0 { return @@ -630,7 +627,7 @@ func (sb *smartBlock) Apply(s *state.State, flags ...ApplyFlag) (err error) { if existingCreatedDate := s.LocalDetails().GetInt64OrDefault(bundle.RelationKeyCreatedDate, 0); existingCreatedDate == 0 || existingCreatedDate > lastModified.Unix() { // this can happen if we don't have creation date in the root change - s.SetLocalDetail(bundle.RelationKeyCreatedDate.String(), pbtypes.Int64(lastModified.Unix())) + s.SetLocalDetail(bundle.RelationKeyCreatedDate, pbtypes.Int64(lastModified.Unix())) } } @@ -672,15 +669,15 @@ func (sb *smartBlock) Apply(s *state.State, flags ...ApplyFlag) (err error) { pushChange := func() error { if !sb.source.ReadOnly() { // We can set details directly in object's state, they'll be indexed correctly - st.SetLocalDetail(bundle.RelationKeyLastModifiedBy.String(), pbtypes.String(sb.currentParticipantId)) - st.SetLocalDetail(bundle.RelationKeyLastModifiedDate.String(), pbtypes.Int64(lastModified.Unix())) + st.SetLocalDetail(bundle.RelationKeyLastModifiedBy, pbtypes.String(sb.currentParticipantId)) + st.SetLocalDetail(bundle.RelationKeyLastModifiedDate, pbtypes.Int64(lastModified.Unix())) } fileDetailsKeys := st.FileRelationKeys() - var fileDetailsKeysFiltered []string + var fileDetailsKeysFiltered []domain.RelationKey for _, ch := range changes { if ds := ch.GetDetailsSet(); ds != nil { - if slice.FindPos(fileDetailsKeys, ds.Key) != -1 { - fileDetailsKeysFiltered = append(fileDetailsKeysFiltered, ds.Key) + if slice.FindPos(fileDetailsKeys, domain.RelationKey(ds.Key)) != -1 { + fileDetailsKeysFiltered = append(fileDetailsKeysFiltered, domain.RelationKey(ds.Key)) } } } @@ -872,7 +869,7 @@ func (sb *smartBlock) injectLocalDetails(s *state.State) error { // so we don't need to traverse changes every time keys := bundle.LocalAndDerivedRelationKeys - localDetailsFromStore := pbtypes.StructFilterKeys(details, keys) + localDetailsFromStore := details.CopyOnlyWithKeys(keys) s.InjectLocalDetails(localDetailsFromStore) if p := s.ParentState(); p != nil && !hasPendingLocalDetails { @@ -887,21 +884,21 @@ func (sb *smartBlock) injectLocalDetails(s *state.State) error { return nil } -func (sb *smartBlock) getDetailsFromStore() (*types.Struct, error) { +func (sb *smartBlock) getDetailsFromStore() (*domain.Details, error) { storedDetails, err := sb.objectStore.GetDetails(sb.Id()) if err != nil || storedDetails == nil { return nil, err } - return pbtypes.CopyStruct(storedDetails.GetDetails(), true), nil + return storedDetails.ShallowCopy(), nil } -func (sb *smartBlock) appendPendingDetails(details *types.Struct) (resultDetails *types.Struct, hasPendingLocalDetails bool) { +func (sb *smartBlock) appendPendingDetails(details *domain.Details) (resultDetails *domain.Details, hasPendingLocalDetails bool) { // Consume pending details - err := sb.objectStore.UpdatePendingLocalDetails(sb.Id(), func(pending *types.Struct) (*types.Struct, error) { - if len(pending.GetFields()) > 0 { + err := sb.objectStore.UpdatePendingLocalDetails(sb.Id(), func(pending *domain.Details) (*domain.Details, error) { + if pending.Len() > 0 { hasPendingLocalDetails = true } - details = pbtypes.StructMerge(details, pending, false) + details = details.Merge(pending) return nil, nil }) if err != nil { @@ -933,7 +930,7 @@ func (sb *smartBlock) injectCreationInfo(s *state.State) error { } } else { // make sure we don't have this relation for other objects - s.RemoveLocalDetail(bundle.RelationKeyProfileOwnerIdentity.String()) + s.RemoveLocalDetail(bundle.RelationKeyProfileOwnerIdentity) } if s.LocalDetails().GetStringOrDefault(bundle.RelationKeyCreator, "") != "" && s.LocalDetails().GetInt64OrDefault(bundle.RelationKeyCreatedDate, 0) != 0 { @@ -979,7 +976,7 @@ func (sb *smartBlock) SetVerticalAlign(ctx session.Context, align model.BlockVer return sb.Apply(s) } -func (sb *smartBlock) RemoveExtraRelations(ctx session.Context, relationIds []string) (err error) { +func (sb *smartBlock) RemoveExtraRelations(ctx session.Context, relationIds []domain.RelationKey) (err error) { st := sb.NewStateCtx(ctx) st.RemoveRelation(relationIds...) @@ -1107,20 +1104,27 @@ func hasDepIds(relations pbtypes.RelationLinks, act *undo.Action) bool { if act.Details.Before == nil || act.Details.After == nil { return true } - for k, after := range act.Details.After.Fields { - rel := relations.Get(k) + + var changed bool + act.Details.After.Iterate(func(k domain.RelationKey, after any) bool { + rel := relations.Get(string(k)) if rel != nil && (rel.Format == model.RelationFormat_status || rel.Format == model.RelationFormat_tag || rel.Format == model.RelationFormat_object || rel.Format == model.RelationFormat_file || isCoverId(rel)) { - before := act.Details.Before.Fields[k] + before := act.Details.Before.Get(k) // Check that value is actually changed - if before == nil || !before.Equal(after) { - return true + if !before.Ok() || !before.EqualAny(after) { + changed = true + return false } } + return true + }) + if changed { + return true } } @@ -1152,7 +1156,7 @@ func isCoverId(rel *model.RelationLink) bool { return rel.Key == bundle.RelationKeyCoverId.String() } -func getChangedFileHashes(s *state.State, fileDetailKeys []string, act undo.Action) (hashes []string) { +func getChangedFileHashes(s *state.State, fileDetailKeys []domain.RelationKey, act undo.Action) (hashes []string) { for _, nb := range act.Add { if fh, ok := nb.(simple.FileHashes); ok { hashes = fh.FillFileHashes(hashes) @@ -1165,11 +1169,11 @@ func getChangedFileHashes(s *state.State, fileDetailKeys []string, act undo.Acti } if act.Details != nil { det := act.Details.After - if det != nil && det.Fields != nil { - for _, field := range fileDetailKeys { - if list := pbtypes.GetStringList(det, field); list != nil { + if det != nil { + for _, detKey := range fileDetailKeys { + if list := det.GetStringListOrDefault(detKey, nil); len(list) > 0 { hashes = append(hashes, list...) - } else if s := pbtypes.GetString(det, field); s != "" { + } else if s := det.GetStringOrDefault(detKey, ""); s != "" { hashes = append(hashes, s) } } @@ -1306,7 +1310,7 @@ func (sb *smartBlock) setRestrictionsDetail(s *state.State) { for i, r := range sb.Restrictions().Object { rawRestrictions[i] = int(r) } - s.SetLocalDetail(bundle.RelationKeyRestrictions.String(), pbtypes.IntList(rawRestrictions...)) + s.SetLocalDetail(bundle.RelationKeyRestrictions, pbtypes.IntList(rawRestrictions...)) // todo: verify this logic with clients if sb.Restrictions().Object.Check(model.Restrictions_Details) != nil && @@ -1385,8 +1389,8 @@ func (sb *smartBlock) injectDerivedDetails(s *state.State, spaceID string, sbt s s.SetDetailAndBundledRelation(bundle.RelationKeyId, pbtypes.String(id)) } - if v, ok := s.Details().GetFields()[bundle.RelationKeyFileBackupStatus.String()]; ok { - status := filesyncstatus.Status(v.GetNumberValue()) + if v, ok := s.Details().GetInt64(bundle.RelationKeyFileBackupStatus); ok { + status := filesyncstatus.Status(v) // Clients expect syncstatus constants in this relation s.SetDetailAndBundledRelation(bundle.RelationKeyFileSyncStatus, pbtypes.Int64(int64(status.ToSyncStatus()))) } @@ -1439,9 +1443,9 @@ func (sb *smartBlock) injectDerivedDetails(s *state.State, spaceID string, sbt s } // Set isDeleted relation only if isUninstalled is present in details - if isUninstalled := s.Details().GetFields()[bundle.RelationKeyIsUninstalled.String()]; isUninstalled != nil { + if isUninstalled, ok := s.Details().GetBool(bundle.RelationKeyIsUninstalled); ok { var isDeleted bool - if isUninstalled.GetBoolValue() { + if isUninstalled { isDeleted = true } s.SetDetailAndBundledRelation(bundle.RelationKeyIsDeleted, pbtypes.Bool(isDeleted)) diff --git a/core/block/editor/state/change.go b/core/block/editor/state/change.go index edd18adf1..2c8b32b7c 100644 --- a/core/block/editor/state/change.go +++ b/core/block/editor/state/change.go @@ -80,7 +80,7 @@ func NewDocFromSnapshot(rootId string, snapshot *pb.ChangeSnapshot, opts ...Snap removedCollectionKeysMap[t] = struct{}{} } - detailsFromSnapshot := pbtypes.StructCutKeys(snapshot.Data.Details, bundle.LocalAndDerivedRelationKeys) + detailsFromSnapshot := pbtypes.StructCutKeys(snapshot.Data.Details, slice.IntoStrings(bundle.LocalAndDerivedRelationKeys)) if err := pbtypes.ValidateStruct(detailsFromSnapshot); err != nil { log.Errorf("NewDocFromSnapshot details validation error: %v; details normalized", err) pbtypes.NormalizeStruct(detailsFromSnapshot) @@ -641,7 +641,7 @@ func (s *State) fillChanges(msgs []simple.EventMessage) { func (s *State) filterLocalAndDerivedRelations(newRelLinks pbtypes.RelationLinks) pbtypes.RelationLinks { var relLinksWithoutLocal pbtypes.RelationLinks for _, link := range newRelLinks { - if !slices.Contains(bundle.LocalAndDerivedRelationKeys, link.Key) { + if !slices.Contains(bundle.LocalAndDerivedRelationKeys, domain.RelationKey(link.Key)) { relLinksWithoutLocal = relLinksWithoutLocal.Append(link) } } @@ -651,7 +651,7 @@ func (s *State) filterLocalAndDerivedRelations(newRelLinks pbtypes.RelationLinks func (s *State) filterLocalAndDerivedRelationsByKey(relationKeys []string) []string { var relKeysWithoutLocal []string for _, key := range relationKeys { - if !slices.Contains(bundle.LocalAndDerivedRelationKeys, key) { + if !slices.Contains(bundle.LocalAndDerivedRelationKeys, domain.RelationKey(key)) { relKeysWithoutLocal = append(relKeysWithoutLocal, key) } } diff --git a/core/block/editor/state/event.go b/core/block/editor/state/event.go index 10c39223e..07fd5f9e3 100644 --- a/core/block/editor/state/event.go +++ b/core/block/editor/state/event.go @@ -318,7 +318,7 @@ func StructDiffIntoEvents(contextId string, diff *domain.Details) (msgs []*pb.Ev } // StructDiffIntoEvents converts map into events. nil map value converts to Remove event -func StructDiffIntoEventsWithSubIds(contextId string, diff *domain.Details, keys []string, subIds []string) (msgs []*pb.EventMessage) { +func StructDiffIntoEventsWithSubIds(contextId string, diff *domain.Details, keys []domain.RelationKey, subIds []string) (msgs []*pb.EventMessage) { if diff.Len() == 0 { return nil } @@ -329,7 +329,7 @@ func StructDiffIntoEventsWithSubIds(contextId string, diff *domain.Details, keys diff.Iterate(func(k domain.RelationKey, v any) bool { key := string(k) - if len(keys) > 0 && slice.FindPos(keys, key) == -1 { + if len(keys) > 0 && slice.FindPos(keys, k) == -1 { return true } if _, ok := v.(domain.Tombstone); ok { diff --git a/core/block/editor/state/state.go b/core/block/editor/state/state.go index 2f45ea6ce..aace911f7 100644 --- a/core/block/editor/state/state.go +++ b/core/block/editor/state/state.go @@ -896,14 +896,13 @@ func (s *State) SetDetails(d *domain.Details) *State { // shortenDetailsToLimit(s.rootId, d.Fields) // } - localKeys := slice.StringsInto[domain.RelationKey](bundle.LocalAndDerivedRelationKeys) - local := d.CopyOnlyWithKeys(localKeys) + local := d.CopyOnlyWithKeys(bundle.LocalAndDerivedRelationKeys) if local != nil && local.Len() > 0 { local.Iterate(func(k domain.RelationKey, v any) bool { s.SetLocalDetail(k, v) return true }) - s.details = d.CopyWithoutKeys(localKeys) + s.details = d.CopyWithoutKeys(bundle.LocalAndDerivedRelationKeys) return s } s.details = d @@ -967,7 +966,7 @@ func (s *State) SetDetail(key domain.RelationKey, value any) { // TODO: GO-2062 Need to refactor details shortening, as it could cut string incorrectly // value = shortenValueToLimit(s.rootId, key, value) - if slice.FindPos(bundle.LocalAndDerivedRelationKeys, string(key)) > -1 { + if slice.FindPos(bundle.LocalAndDerivedRelationKeys, key) > -1 { s.SetLocalDetail(key, value) return } @@ -1055,16 +1054,14 @@ func (s *State) SetObjectTypeKeys(objectTypeKeys []domain.TypeKey) *State { return s } -func (s *State) InjectLocalDetails(localDetails *types.Struct) { - for key, v := range localDetails.GetFields() { +func (s *State) InjectLocalDetails(localDetails *domain.Details) { + localDetails.Iterate(func(k domain.RelationKey, v any) bool { if v == nil { - continue + return true } - if _, isNull := v.Kind.(*types.Value_NullValue); isNull { - continue - } - s.SetDetailAndBundledRelation(domain.RelationKey(key), v) - } + s.SetDetailAndBundledRelation(k, v) + return true + }) } func (s *State) LocalDetails() *domain.Details { diff --git a/core/block/object/objectlink/dependent_objects.go b/core/block/object/objectlink/dependent_objects.go index a55781c4f..4e3656b21 100644 --- a/core/block/object/objectlink/dependent_objects.go +++ b/core/block/object/objectlink/dependent_objects.go @@ -70,7 +70,7 @@ func DependentObjectIDs(s *state.State, converter KeyToIDConverter, relations, o // handle corner cases first for specific formats if rel.Format == model.RelationFormat_date && - !lo.Contains(bundle.LocalAndDerivedRelationKeys, rel.Key) { + !lo.Contains(bundle.LocalAndDerivedRelationKeys, domain.RelationKey(rel.Key)) { relInt := det.GetInt64OrDefault(domain.RelationKey(rel.Key), 0) if relInt > 0 { t := time.Unix(relInt, 0) diff --git a/core/block/source/sub_object_links_migration.go b/core/block/source/sub_object_links_migration.go index 66ade8f11..a20177afd 100644 --- a/core/block/source/sub_object_links_migration.go +++ b/core/block/source/sub_object_links_migration.go @@ -53,7 +53,7 @@ func (m *subObjectsAndProfileLinksMigration) replaceLinksInDetails(s *state.Stat internalKey := s.UniqueKeyInternal() switch m.sbType { case smartblock.SmartBlockTypeRelation: - if bundle.HasRelation(internalKey) { + if bundle.HasRelation(domain.RelationKey(internalKey)) { s.SetDetail(bundle.RelationKeySourceObject, pbtypes.String(domain.RelationKey(internalKey).BundledURL())) } case smartblock.SmartBlockTypeObjectType: diff --git a/core/subscription/cache.go b/core/subscription/cache.go index 783ab833b..39bff770c 100644 --- a/core/subscription/cache.go +++ b/core/subscription/cache.go @@ -1,8 +1,7 @@ package subscription import ( - "github.com/gogo/protobuf/types" - + "github.com/anyproto/anytype-heart/core/domain" "github.com/anyproto/anytype-heart/util/slice" ) @@ -14,7 +13,7 @@ func newCache() *cache { type entry struct { id string - data *types.Struct + data *domain.Details subIds []string subIsActive []bool @@ -80,9 +79,9 @@ func (e *entry) SubIds() []string { return e.subIds } -func (e *entry) Get(key string) *types.Value { - return e.data.Fields[key] -} +// func (e *entry) Get(key string) *types.Value { +// return e.data.Fields[key] +// } type cache struct { entries map[string]*entry diff --git a/core/subscription/context.go b/core/subscription/context.go index e36f698fd..bb6783029 100644 --- a/core/subscription/context.go +++ b/core/subscription/context.go @@ -1,19 +1,17 @@ package subscription import ( - "github.com/gogo/protobuf/types" - "github.com/anyproto/anytype-heart/core/block/editor/state" + "github.com/anyproto/anytype-heart/core/domain" "github.com/anyproto/anytype-heart/pb" "github.com/anyproto/anytype-heart/pkg/lib/pb/model" - "github.com/anyproto/anytype-heart/util/pbtypes" "github.com/anyproto/anytype-heart/util/slice" ) type opChange struct { id string subId string - keys []string + keys []domain.RelationKey } type opRemove struct { @@ -25,7 +23,7 @@ type opPosition struct { id string subId string afterId string - keys []string + keys []domain.RelationKey isAdd bool } @@ -56,7 +54,7 @@ type opCtx struct { keysBuf []struct { id string subIds []string - keys []string + keys []domain.RelationKey } c *cache @@ -177,17 +175,17 @@ func (ctx *opCtx) detailsEvents() { continue } prev := ctx.c.Get(info.id) - var prevData *types.Struct + var prevData *domain.Details if prev != nil && prev.IsActive(info.subIds...) && prev.IsFullDetailsSent(info.subIds...) { prevData = prev.data - diff := pbtypes.StructDiff(prevData, curr.data) + diff := domain.StructDiff(prevData, curr.data) msgs = append(msgs, state.StructDiffIntoEventsWithSubIds(info.id, diff, info.keys, info.subIds)...) } else { msgs = append(msgs, &pb.EventMessage{ Value: &pb.EventMessageValueOfObjectDetailsSet{ ObjectDetailsSet: &pb.EventObjectDetailsSet{ Id: curr.id, - Details: pbtypes.StructFilterKeys(curr.data, info.keys), + Details: curr.data.CopyOnlyWithKeys(info.keys).ToProto(), SubIds: info.subIds, }, }, @@ -304,7 +302,7 @@ func (ctx *opCtx) groupEventsDetailsAmend(v *pb.EventObjectDetailsAmend) { } } -func (ctx *opCtx) collectKeys(id string, subId string, keys []string) { +func (ctx *opCtx) collectKeys(id string, subId string, keys []domain.RelationKey) { var found bool for i, kb := range ctx.keysBuf { if kb.id == id { @@ -321,12 +319,12 @@ func (ctx *opCtx) collectKeys(id string, subId string, keys []string) { } } if !found { - keysCopy := make([]string, len(keys)) + keysCopy := make([]domain.RelationKey, len(keys)) copy(keysCopy, keys) ctx.keysBuf = append(ctx.keysBuf, struct { id string subIds []string - keys []string + keys []domain.RelationKey }{id: id, keys: keysCopy, subIds: []string{subId}}) } } diff --git a/core/subscription/dep.go b/core/subscription/dep.go index 79b91ed87..7f4b8e3e5 100644 --- a/core/subscription/dep.go +++ b/core/subscription/dep.go @@ -3,6 +3,7 @@ package subscription import ( "strings" + "github.com/anyproto/anytype-heart/core/domain" "github.com/anyproto/anytype-heart/pkg/lib/bundle" "github.com/anyproto/anytype-heart/pkg/lib/pb/model" "github.com/anyproto/anytype-heart/util/pbtypes" @@ -12,17 +13,17 @@ import ( func newDependencyService(s *service) *dependencyService { return &dependencyService{ s: s, - isRelationObjMap: map[string]bool{}, + isRelationObjMap: map[domain.RelationKey]bool{}, } } type dependencyService struct { s *service - isRelationObjMap map[string]bool + isRelationObjMap map[domain.RelationKey]bool } -func (ds *dependencyService) makeSubscriptionByEntries(subId string, allEntries, activeEntries []*entry, keys, depKeys, filterDepIds []string) *simpleSub { +func (ds *dependencyService) makeSubscriptionByEntries(subId string, allEntries, activeEntries []*entry, keys, depKeys []domain.RelationKey, filterDepIds []string) *simpleSub { depSub := ds.s.newSimpleSub(subId, keys, true) depSub.forceIds = filterDepIds depEntries := ds.depEntriesByEntries(&opCtx{entries: allEntries}, ds.depIdsByEntries(activeEntries, depKeys, depSub.forceIds)) @@ -30,7 +31,7 @@ func (ds *dependencyService) makeSubscriptionByEntries(subId string, allEntries, return depSub } -func (ds *dependencyService) refillSubscription(ctx *opCtx, sub *simpleSub, entries []*entry, depKeys []string) { +func (ds *dependencyService) refillSubscription(ctx *opCtx, sub *simpleSub, entries []*entry, depKeys []domain.RelationKey) { depIds := ds.depIdsByEntries(entries, depKeys, sub.forceIds) if !sub.isEqualIds(depIds) { depEntries := ds.depEntriesByEntries(ctx, depIds) @@ -39,11 +40,11 @@ func (ds *dependencyService) refillSubscription(ctx *opCtx, sub *simpleSub, entr return } -func (ds *dependencyService) depIdsByEntries(entries []*entry, depKeys, forceIds []string) (depIds []string) { +func (ds *dependencyService) depIdsByEntries(entries []*entry, depKeys []domain.RelationKey, forceIds []string) (depIds []string) { depIds = forceIds for _, e := range entries { for _, k := range depKeys { - for _, depId := range pbtypes.GetStringList(e.data, k) { + for _, depId := range e.data.GetStringListOrDefault(k, nil) { if depId != "" && slice.FindPos(depIds, depId) == -1 && depId != e.id { depIds = append(depIds, depId) } @@ -105,17 +106,17 @@ func (ds *dependencyService) depEntriesByEntries(ctx *opCtx, depIds []string) (d return } -var ignoredKeys = map[string]struct{}{ - bundle.RelationKeyId.String(): {}, - bundle.RelationKeySpaceId.String(): {}, // relation format for spaceId has mistakenly set to Object instead of shorttext - bundle.RelationKeyFeaturedRelations.String(): {}, // relation format for featuredRelations has mistakenly set to Object instead of shorttext +var ignoredKeys = map[domain.RelationKey]struct{}{ + bundle.RelationKeyId: {}, + bundle.RelationKeySpaceId: {}, // relation format for spaceId has mistakenly set to Object instead of shorttext + bundle.RelationKeyFeaturedRelations: {}, // relation format for featuredRelations has mistakenly set to Object instead of shorttext } -func (ds *dependencyService) isRelationObject(key string) bool { +func (ds *dependencyService) isRelationObject(key domain.RelationKey) bool { if _, ok := ignoredKeys[key]; ok { return false } - if strings.ContainsRune(key, '.') { + if strings.ContainsRune(string(key), '.') { // skip nested keys like "assignee.type" return false } @@ -132,7 +133,7 @@ func (ds *dependencyService) isRelationObject(key string) bool { return isObj } -func (ds *dependencyService) depKeys(keys []string) (depKeys []string) { +func (ds *dependencyService) depKeys(keys []domain.RelationKey) (depKeys []domain.RelationKey) { for _, key := range keys { if ds.isRelationObject(key) { depKeys = append(depKeys, key) diff --git a/core/subscription/service.go b/core/subscription/service.go index 5ea32c763..c0142f1d5 100644 --- a/core/subscription/service.go +++ b/core/subscription/service.go @@ -12,8 +12,8 @@ import ( mb2 "github.com/cheggaaa/mb/v3" "github.com/globalsign/mgo/bson" "github.com/gogo/protobuf/types" - "golang.org/x/exp/slices" "github.com/valyala/fastjson" + "golang.org/x/exp/slices" "github.com/anyproto/anytype-heart/core/domain" @@ -305,7 +305,7 @@ func queryEntries(objectStore objectstore.ObjectStore, f *database.Filters) ([]* entries := make([]*entry, 0, len(records)) for _, r := range records { entries = append(entries, &entry{ - id: pbtypes.GetString(r.Details, "id"), + id: r.Details.GetStringOrDefault(bundle.RelationKeyId, ""), data: r.Details, }) } @@ -364,7 +364,7 @@ func (s *service) SubscribeIdsReq(req pb.RpcObjectSubscribeIdsRequest) (resp *pb entries := make([]*entry, 0, len(records)) for _, r := range records { entries = append(entries, &entry{ - id: pbtypes.GetString(r.Details, "id"), + id: r.Details.GetStringOrDefault(bundle.RelationKeyId, ""), data: r.Details, }) } @@ -465,7 +465,7 @@ func (s *service) SubscribeGroups(ctx session.Context, req pb.RpcObjectGroupsSub entries := make([]*entry, 0, len(tagGrouper.Records)) for _, r := range tagGrouper.Records { entries = append(entries, &entry{ - id: pbtypes.GetString(r.Details, "id"), + id: r.Details.GetStringOrDefault(bundle.RelationKeyId, ""), data: r.Details, }) } @@ -542,7 +542,7 @@ func (s *service) recordsHandler() { return } for _, rec := range records { - id := pbtypes.GetString(rec.(database.Record).Details, "id") + id := rec.(database.Record).Details.GetStringOrDefault(bundle.RelationKeyId, "") // nil previous version nilIfExists(id) entries = append(entries, &entry{ diff --git a/core/subscription/simple.go b/core/subscription/simple.go index c46ce4d0d..e970ee3cc 100644 --- a/core/subscription/simple.go +++ b/core/subscription/simple.go @@ -3,10 +3,10 @@ package subscription import ( "github.com/gogo/protobuf/types" - "github.com/anyproto/anytype-heart/util/pbtypes" + "github.com/anyproto/anytype-heart/core/domain" ) -func (s *service) newSimpleSub(id string, keys []string, isDep bool) *simpleSub { +func (s *service) newSimpleSub(id string, keys []domain.RelationKey, isDep bool) *simpleSub { sub := &simpleSub{ id: id, keys: keys, @@ -21,10 +21,10 @@ func (s *service) newSimpleSub(id string, keys []string, isDep bool) *simpleSub type simpleSub struct { id string set map[string]struct{} - keys []string + keys []domain.RelationKey forceIds []string - depKeys []string + depKeys []domain.RelationKey depSub *simpleSub activeEntriesBuf []*entry @@ -124,7 +124,7 @@ func (s *simpleSub) getActiveEntries() (res []*entry) { func (s *simpleSub) getActiveRecords() (res []*types.Struct) { for id := range s.set { - res = append(res, pbtypes.StructFilterKeys(s.cache.Get(id).data, s.keys)) + res = append(res, s.cache.Get(id).data.CopyOnlyWithKeys(s.keys).ToProto()) } return } diff --git a/pkg/lib/bundle/init.go b/pkg/lib/bundle/init.go index 0627372bc..e3119ebf8 100644 --- a/pkg/lib/bundle/init.go +++ b/pkg/lib/bundle/init.go @@ -55,18 +55,18 @@ var DefaultObjectTypePerSmartblockType = map[coresb.SmartBlockType]domain.TypeKe } // filled in init -var LocalRelationsKeys []string // stored only in localstore -var DerivedRelationsKeys []string // derived -var LocalAndDerivedRelationKeys []string +var LocalRelationsKeys []domain.RelationKey // stored only in localstore +var DerivedRelationsKeys []domain.RelationKey // derived +var LocalAndDerivedRelationKeys []domain.RelationKey var ErrNotFound = fmt.Errorf("not found") func init() { for _, r := range relations { if r.DataSource == model.Relation_account || r.DataSource == model.Relation_local { - LocalRelationsKeys = append(LocalRelationsKeys, r.Key) + LocalRelationsKeys = append(LocalRelationsKeys, domain.RelationKey(r.Key)) } else if r.DataSource == model.Relation_derived { - DerivedRelationsKeys = append(DerivedRelationsKeys, r.Key) + DerivedRelationsKeys = append(DerivedRelationsKeys, domain.RelationKey(r.Key)) } } LocalAndDerivedRelationKeys = slices.Clone(DerivedRelationsKeys) @@ -181,8 +181,8 @@ func ListRelationsUrls() []string { return keys } -func HasRelation(key string) bool { - _, exists := relations[domain.RelationKey(key)] +func HasRelation(key domain.RelationKey) bool { + _, exists := relations[key] return exists } diff --git a/pkg/lib/localstore/objectstore/oldstore/oldstore.go b/pkg/lib/localstore/objectstore/oldstore/oldstore.go index bbebdf273..2a04460fd 100644 --- a/pkg/lib/localstore/objectstore/oldstore/oldstore.go +++ b/pkg/lib/localstore/objectstore/oldstore/oldstore.go @@ -13,6 +13,7 @@ import ( "github.com/anyproto/anytype-heart/pkg/lib/datastore" "github.com/anyproto/anytype-heart/pkg/lib/pb/model" "github.com/anyproto/anytype-heart/util/pbtypes" + "github.com/anyproto/anytype-heart/util/slice" ) var pagesDetailsBase = ds.NewKey("/pages/details") @@ -75,7 +76,7 @@ func (s *service) GetLocalDetails(objectId string) (*types.Struct, error) { return nil, err } - details := pbtypes.StructFilterKeys(objDetails.Details, bundle.LocalRelationsKeys) + details := pbtypes.StructFilterKeys(objDetails.Details, slice.IntoStrings(bundle.LocalRelationsKeys)) return details, nil } diff --git a/util/internalflag/flag.go b/util/internalflag/flag.go index aa8c7cca6..cec0cd45f 100644 --- a/util/internalflag/flag.go +++ b/util/internalflag/flag.go @@ -15,10 +15,10 @@ type Set struct { flags []int } -func NewFromState(st *state.State) Set { +func NewFromState(st *state.State) *Set { flags := st.Details().GetIntListOrDefault(relationKey, nil) - return Set{ + return &Set{ flags: flags, } } diff --git a/util/pbtypes/relationlink.go b/util/pbtypes/relationlink.go index cc3cc5bc7..117c9233c 100644 --- a/util/pbtypes/relationlink.go +++ b/util/pbtypes/relationlink.go @@ -2,6 +2,7 @@ package pbtypes import "github.com/anyproto/anytype-heart/pkg/lib/pb/model" +// TODO Add domaain model for link type RelationLinks []*model.RelationLink func (rl RelationLinks) Get(key string) *model.RelationLink { diff --git a/util/slice/slice.go b/util/slice/slice.go index 408c79a99..10e144a66 100644 --- a/util/slice/slice.go +++ b/util/slice/slice.go @@ -245,3 +245,11 @@ func StringsInto[T ~string](from []string) []T { } return to } + +func IntoStrings[T ~string](from []T) []string { + to := make([]string, len(from)) + for i, v := range from { + to[i] = string(v) + } + return to +}