Skip to content

Commit 5b39c46

Browse files
committed
[breaking] Parent and Child Publisher collections on Publisher now include Role data.
Fixes #38
1 parent c1628df commit 5b39c46

9 files changed

Lines changed: 104 additions & 94 deletions

src/IModifiablePublisher.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,6 @@
33
/// <summary>
44
/// Represents a content publisher that can be modified.
55
/// </summary>
6-
public interface IModifiablePublisher : IReadOnlyPublisher<IModifiablePublisherCollection<IReadOnlyPublisher>>, IReadOnlyPublisher, IModifiableEntity, IModifiableAccentColor, IModifiableUserRoleCollection, IModifiableProjectCollection<IReadOnlyProject>
6+
public interface IModifiablePublisher : IReadOnlyPublisher<IModifiablePublisherCollection<IReadOnlyPublisherRole>>, IReadOnlyPublisher, IModifiableEntity, IModifiableAccentColor, IModifiableUserRoleCollection, IModifiableProjectCollection<IReadOnlyProject>
77
{
88
}

src/IReadOnlyPublisher.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,15 @@ namespace WindowsAppCommunity.Sdk;
55
/// <summary>
66
/// Represents a publisher, a collection of projects and collaborators who publish content to users.
77
/// </summary>
8-
public interface IReadOnlyPublisher : IReadOnlyPublisher<IReadOnlyPublisherCollection>
8+
public interface IReadOnlyPublisher : IReadOnlyPublisher<IReadOnlyPublisherRoleCollection>
99
{
1010
}
1111

1212
/// <summary>
1313
/// Represents a publisher, a collection of projects and collaborators who publish content to users.
1414
/// </summary>
1515
public interface IReadOnlyPublisher<TPublisherCollection> : IReadOnlyEntity, IReadOnlyAccentColor, IReadOnlyUserRoleCollection, IReadOnlyProjectCollection, IHasId
16-
where TPublisherCollection : IReadOnlyPublisherCollection<IReadOnlyPublisher>
16+
where TPublisherCollection : IReadOnlyPublisherCollection<IReadOnlyPublisherRole>
1717
{
1818
/// <summary>
1919
/// The collection of publishers that this publisher belongs to.

src/Models/IPublisherRoleCollection.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,5 +26,5 @@ public record PublisherRole
2626
/// <summary>
2727
/// The role of the publisher.
2828
/// </summary>
29-
public required DagCid Role { get; init; }
29+
public required DagCid Role { get; init; }
3030
}

src/Models/Publisher.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,12 +52,12 @@ public record Publisher : IEntity, ILinkCollection, IProjectCollection, IUserRol
5252
/// <summary>
5353
/// A list of other publishers who are managed under this publisher.
5454
/// </summary>
55-
public PublisherCollection ParentPublishers { get; set; } = new();
55+
public PublisherRole[] ParentPublishers { get; set; } = [];
5656

5757
/// <summary>
5858
/// A list of other publishers who are managed under this publisher.
5959
/// </summary>
60-
public PublisherCollection ChildPublishers { get; set; } = new();
60+
public PublisherRole[] ChildPublishers { get; set; } = [];
6161

6262
/// <summary>
6363
/// Holds information about publisher assets that have been published for consumption by an end user, such as a Microsoft Store app, a package on nuget.org, a git repo, etc.

src/Nomad/ModifiablePublisher.cs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -118,12 +118,12 @@ public static ModifiablePublisher FromHandlerConfig(NomadKuboEventStreamHandlerC
118118
Sources = handlerConfig.Sources,
119119
};
120120

121-
var parentPublishers = new ModifiablePublisherCollection
121+
var parentPublishers = new ModifiablePublisherRoleCollection
122122
{
123123
Id = handlerConfig.RoamingKey.Id,
124-
Inner = (ReadOnlyPublisherCollection)readonlyPublisher.ParentPublishers,
125-
AddPublisherEventId = "AddParentPublisherAsync",
126-
RemovePublisherEventId = "RemoveParentPublisherAsync",
124+
Inner = (ReadOnlyPublisherRoleCollection)readonlyPublisher.ParentPublishers,
125+
AddPublisherRoleEventId = "AddParentPublisherAsync",
126+
RemovePublisherRoleEventId = "RemoveParentPublisherAsync",
127127
Client = client,
128128
KuboOptions = kuboOptions,
129129
PublisherRepository = publisherRepository,
@@ -134,12 +134,12 @@ public static ModifiablePublisher FromHandlerConfig(NomadKuboEventStreamHandlerC
134134
Sources = handlerConfig.Sources,
135135
};
136136

137-
var childPublishers = new ModifiablePublisherCollection
137+
var childPublishers = new ModifiablePublisherRoleCollection
138138
{
139139
Id = handlerConfig.RoamingKey.Id,
140-
Inner = (ReadOnlyPublisherCollection)readonlyPublisher.ChildPublishers,
141-
AddPublisherEventId = "AddChildPublisherAsync",
142-
RemovePublisherEventId = "RemoveChildPublisherAsync",
140+
Inner = (ReadOnlyPublisherRoleCollection)readonlyPublisher.ChildPublishers,
141+
AddPublisherRoleEventId = "AddChildPublisherAsync",
142+
RemovePublisherRoleEventId = "RemoveChildPublisherAsync",
143143
Client = client,
144144
KuboOptions = kuboOptions,
145145
PublisherRepository = publisherRepository,
@@ -218,16 +218,16 @@ public static ModifiablePublisher FromHandlerConfig(NomadKuboEventStreamHandlerC
218218
public Publisher Inner => InnerPublisher.Inner;
219219

220220
/// <inheritdoc/>
221-
public required IModifiablePublisherCollection<IReadOnlyPublisher> ParentPublishers { get; init; }
221+
public required IModifiablePublisherCollection<IReadOnlyPublisherRole> ParentPublishers { get; init; }
222222

223223
/// <inheritdoc/>
224-
public required IModifiablePublisherCollection<IReadOnlyPublisher> ChildPublishers { get; init; }
224+
public required IModifiablePublisherCollection<IReadOnlyPublisherRole> ChildPublishers { get; init; }
225225

226226
/// <inheritdoc/>
227-
IReadOnlyPublisherCollection IReadOnlyPublisher<IReadOnlyPublisherCollection>.ParentPublishers => (IReadOnlyPublisherCollection)ParentPublishers;
227+
IReadOnlyPublisherRoleCollection IReadOnlyPublisher<IReadOnlyPublisherRoleCollection>.ParentPublishers => (IReadOnlyPublisherRoleCollection)ParentPublishers;
228228

229229
/// <inheritdoc/>
230-
IReadOnlyPublisherCollection IReadOnlyPublisher<IReadOnlyPublisherCollection>.ChildPublishers => (IReadOnlyPublisherCollection)ChildPublishers;
230+
IReadOnlyPublisherRoleCollection IReadOnlyPublisher<IReadOnlyPublisherRoleCollection>.ChildPublishers => (IReadOnlyPublisherRoleCollection)ChildPublishers;
231231

232232
/// <inheritdoc/>
233233
public string Name => InnerEntity.Name;

src/Nomad/ModifiablePublisherRole.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,16 +43,16 @@ public class ModifiablePublisherRole : IModifiablePublisherRole
4343
public string? AccentColor => InnerPublisher.AccentColor;
4444

4545
/// <inheritdoc/>
46-
public IModifiablePublisherCollection<IReadOnlyPublisher> ParentPublishers => InnerPublisher.ParentPublishers;
46+
public IModifiablePublisherCollection<IReadOnlyPublisherRole> ParentPublishers => InnerPublisher.ParentPublishers;
4747

4848
/// <inheritdoc/>
49-
public IModifiablePublisherCollection<IReadOnlyPublisher> ChildPublishers => InnerPublisher.ChildPublishers;
49+
public IModifiablePublisherCollection<IReadOnlyPublisherRole> ChildPublishers => InnerPublisher.ChildPublishers;
5050

5151
/// <inheritdoc/>
52-
IReadOnlyPublisherCollection IReadOnlyPublisher<IReadOnlyPublisherCollection>.ParentPublishers => (IReadOnlyPublisherCollection)InnerPublisher.ParentPublishers;
52+
IReadOnlyPublisherRoleCollection IReadOnlyPublisher<IReadOnlyPublisherRoleCollection>.ParentPublishers => (IReadOnlyPublisherRoleCollection)InnerPublisher.ParentPublishers;
5353

5454
/// <inheritdoc/>
55-
IReadOnlyPublisherCollection IReadOnlyPublisher<IReadOnlyPublisherCollection>.ChildPublishers => (IReadOnlyPublisherCollection)InnerPublisher.ChildPublishers;
55+
IReadOnlyPublisherRoleCollection IReadOnlyPublisher<IReadOnlyPublisherRoleCollection>.ChildPublishers => (IReadOnlyPublisherRoleCollection)InnerPublisher.ChildPublishers;
5656

5757
/// <inheritdoc/>
5858
public event EventHandler<string>? NameUpdated;

src/Nomad/ModifiablePublisherRoleCollection.cs

Lines changed: 75 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,16 @@ public class ModifiablePublisherRoleCollection : NomadKuboEventStreamHandler<Val
1919
/// <inheritdoc/>
2020
public required ReadOnlyPublisherRoleCollection Inner { get; init; }
2121

22+
/// <summary>
23+
/// A unique identifier for add events, persistent across machines and reruns.
24+
/// </summary>
25+
public string AddPublisherRoleEventId { get; init; } = "AddPublisherRoleAsync";
26+
27+
/// <summary>
28+
/// A unique identifier for remove events, persistent across machines and reruns.
29+
/// </summary>
30+
public string RemovePublisherRoleEventId { get; init; } = "RemovePublisherRoleAsync";
31+
2232
/// <summary>
2333
/// The repository to use for getting modifiable or readonly publisher instances.
2434
/// </summary>
@@ -67,95 +77,96 @@ public override async Task ApplyEntryUpdateAsync(EventStreamEntry<DagCid> stream
6777
throw new ArgumentNullException("Key or Value in updateEvent cannot be null.");
6878
}
6979

70-
switch (streamEntry.EventId)
80+
if (streamEntry.EventId == AddPublisherRoleEventId)
7181
{
72-
case "AddPublisherRoleAsync":
73-
var publisherId = await Client.Dag.GetAsync<string>(updateEvent.Key, cancel: cancellationToken);
74-
var publisher = await PublisherRepository.GetAsync(publisherId, cancellationToken);
75-
if (publisher is ModifiablePublisher modifiablePublisher)
76-
{
77-
var publisherRole = await Client.Dag.GetAsync<Role>(updateEvent.Value, cancel: cancellationToken);
78-
var addedPublisherRole = new ModifiablePublisherRole
79-
{
80-
InnerPublisher = modifiablePublisher,
81-
Role = publisherRole
82-
};
83-
84-
await ApplyAddPublisherRoleEntryAsync(streamEntry, updateEvent, addedPublisherRole, cancellationToken);
85-
}
86-
else if (publisher is ReadOnlyPublisher readOnlyPublisher)
82+
var publisherId = await Client.Dag.GetAsync<string>(updateEvent.Key, cancel: cancellationToken);
83+
var publisher = await PublisherRepository.GetAsync(publisherId, cancellationToken);
84+
if (publisher is ModifiablePublisher modifiablePublisher)
85+
{
86+
var publisherRole = await Client.Dag.GetAsync<Role>(updateEvent.Value, cancel: cancellationToken);
87+
var addedPublisherRole = new ModifiablePublisherRole
8788
{
88-
var publisherRole = await Client.Dag.GetAsync<Role>(updateEvent.Value, cancel: cancellationToken);
89-
var addedPublisherRole = new ReadOnlyPublisherRole
90-
{
91-
InnerPublisher = readOnlyPublisher,
92-
Role = publisherRole
93-
};
94-
95-
await ApplyAddPublisherRoleEntryAsync(streamEntry, updateEvent, addedPublisherRole, cancellationToken);
96-
}
97-
else
89+
InnerPublisher = modifiablePublisher,
90+
Role = publisherRole
91+
};
92+
93+
await ApplyAddPublisherRoleEntryAsync(streamEntry, updateEvent, addedPublisherRole, cancellationToken);
94+
}
95+
else if (publisher is ReadOnlyPublisher readOnlyPublisher)
96+
{
97+
var publisherRole = await Client.Dag.GetAsync<Role>(updateEvent.Value, cancel: cancellationToken);
98+
var addedPublisherRole = new ReadOnlyPublisherRole
9899
{
99-
throw new InvalidOperationException("Publisher is of an unsupported type.");
100-
}
101-
break;
102-
103-
case "RemovePublisherRoleAsync":
104-
var removedPublisherId = await Client.Dag.GetAsync<string>(updateEvent.Key, cancel: cancellationToken);
105-
var removedPublisher = await PublisherRepository.GetAsync(removedPublisherId, cancellationToken);
106-
if (removedPublisher is ModifiablePublisher modifiableRemovedPublisher)
107-
{
108-
var removedPublisherRole = await Client.Dag.GetAsync<Role>(updateEvent.Value, cancel: cancellationToken);
109-
var removedPublisherRoleInstance = new ModifiablePublisherRole
110-
{
111-
InnerPublisher = modifiableRemovedPublisher,
112-
Role = removedPublisherRole
113-
};
114-
115-
await ApplyRemovePublisherRoleEntryAsync(streamEntry, updateEvent, removedPublisherRoleInstance, cancellationToken);
116-
}
117-
else if (removedPublisher is ReadOnlyPublisher readOnlyRemovedPublisher)
100+
InnerPublisher = readOnlyPublisher,
101+
Role = publisherRole
102+
};
103+
104+
await ApplyAddPublisherRoleEntryAsync(streamEntry, updateEvent, addedPublisherRole, cancellationToken);
105+
}
106+
else
107+
{
108+
throw new InvalidOperationException("Publisher is of an unsupported type.");
109+
}
110+
111+
return;
112+
}
113+
114+
if (streamEntry.EventId == RemovePublisherRoleEventId)
115+
{
116+
var removedPublisherId = await Client.Dag.GetAsync<string>(updateEvent.Key, cancel: cancellationToken);
117+
var removedPublisher = await PublisherRepository.GetAsync(removedPublisherId, cancellationToken);
118+
if (removedPublisher is ModifiablePublisher modifiableRemovedPublisher)
119+
{
120+
var removedPublisherRole = await Client.Dag.GetAsync<Role>(updateEvent.Value, cancel: cancellationToken);
121+
var removedPublisherRoleInstance = new ModifiablePublisherRole
118122
{
119-
var removedPublisherRole = await Client.Dag.GetAsync<Role>(updateEvent.Value, cancel: cancellationToken);
120-
var removedPublisherRoleInstance = new ReadOnlyPublisherRole
121-
{
122-
InnerPublisher = readOnlyRemovedPublisher,
123-
Role = removedPublisherRole
124-
};
125-
126-
await ApplyRemovePublisherRoleEntryAsync(streamEntry, updateEvent, removedPublisherRoleInstance, cancellationToken);
127-
}
128-
else
123+
InnerPublisher = modifiableRemovedPublisher,
124+
Role = removedPublisherRole
125+
};
126+
127+
await ApplyRemovePublisherRoleEntryAsync(streamEntry, updateEvent, removedPublisherRoleInstance, cancellationToken);
128+
}
129+
else if (removedPublisher is ReadOnlyPublisher readOnlyRemovedPublisher)
130+
{
131+
var removedPublisherRole = await Client.Dag.GetAsync<Role>(updateEvent.Value, cancel: cancellationToken);
132+
var removedPublisherRoleInstance = new ReadOnlyPublisherRole
129133
{
130-
throw new InvalidOperationException("Publisher is of an unsupported type.");
131-
}
132-
break;
133-
134-
default:
135-
throw new InvalidOperationException($"Unknown event id: {streamEntry.EventId}");
134+
InnerPublisher = readOnlyRemovedPublisher,
135+
Role = removedPublisherRole
136+
};
137+
138+
await ApplyRemovePublisherRoleEntryAsync(streamEntry, updateEvent, removedPublisherRoleInstance, cancellationToken);
139+
}
140+
else
141+
{
142+
throw new InvalidOperationException("Publisher is of an unsupported type.");
143+
}
144+
return;
136145
}
146+
147+
throw new InvalidOperationException($"Unknown event id: {streamEntry.EventId}");
137148
}
138149

139150
/// <inheritdoc/>
140151
public async Task ApplyAddPublisherRoleEntryAsync(EventStreamEntry<DagCid> streamEntry, ValueUpdateEvent updateEvent, IReadOnlyPublisherRole publisher, CancellationToken cancellationToken)
141152
{
142153
var roleCid = await Client.Dag.PutAsync(publisher.Role, pin: KuboOptions.ShouldPin, cancel: cancellationToken);
143-
Inner.Inner.Publishers = [.. Inner.Inner.Publishers, new PublisherRole { PublisherId = publisher.Id, Role = (DagCid)roleCid }];
154+
Inner.Inner = [.. Inner.Inner, new PublisherRole { PublisherId = publisher.Id, Role = (DagCid)roleCid }];
144155
PublishersAdded?.Invoke(this, [publisher]);
145156
}
146157

147158
/// <inheritdoc/>
148159
public async Task ApplyRemovePublisherRoleEntryAsync(EventStreamEntry<DagCid> streamEntry, ValueUpdateEvent updateEvent, IReadOnlyPublisherRole publisher, CancellationToken cancellationToken)
149160
{
150161
var roleCid = await Client.Dag.PutAsync(publisher.Role, pin: KuboOptions.ShouldPin, cancel: cancellationToken);
151-
Inner.Inner.Publishers = [.. Inner.Inner.Publishers.Where(x => x.PublisherId != publisher.Id && x.Role != (DagCid)roleCid)];
162+
Inner.Inner = [.. Inner.Inner.Where(x => x.PublisherId != publisher.Id && x.Role != (DagCid)roleCid)];
152163
PublishersRemoved?.Invoke(this, [publisher]);
153164
}
154165

155166
/// <inheritdoc/>
156167
public override Task ResetEventStreamPositionAsync(CancellationToken cancellationToken)
157168
{
158-
Inner.Inner.Publishers = [];
169+
Inner.Inner = [];
159170
return Task.CompletedTask;
160171
}
161172
}

src/Nomad/ReadOnlyPublisher.cs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -66,15 +66,15 @@ public static ReadOnlyPublisher FromHandlerConfig(NomadKuboEventStreamHandlerCon
6666
Client = client,
6767
};
6868

69-
var parentPublishers = new ReadOnlyPublisherCollection
69+
var parentPublishers = new ReadOnlyPublisherRoleCollection
7070
{
7171
Id = handlerConfig.RoamingId,
7272
Inner = handlerConfig.RoamingValue.ParentPublishers,
7373
Client = client,
7474
PublisherRepository = publisherRepository,
7575
};
7676

77-
var childPublishers = new ReadOnlyPublisherCollection
77+
var childPublishers = new ReadOnlyPublisherRoleCollection
7878
{
7979
Id = handlerConfig.RoamingId,
8080
Inner = handlerConfig.RoamingValue.ChildPublishers,
@@ -133,11 +133,10 @@ public static ReadOnlyPublisher FromHandlerConfig(NomadKuboEventStreamHandlerCon
133133
public required ReadOnlyProjectCollection InnerProjectCollection { get; init; }
134134

135135
/// <inheritdoc/>
136-
public required IReadOnlyPublisherCollection ParentPublishers { get; init; }
136+
public required IReadOnlyPublisherRoleCollection ParentPublishers { get; init; }
137137

138138
/// <inheritdoc/>
139-
public required IReadOnlyPublisherCollection ChildPublishers { get; init; }
140-
139+
public required IReadOnlyPublisherRoleCollection ChildPublishers { get; init; }
141140
/// <inheritdoc/>
142141
public required Publisher Inner { get; init; }
143142

src/Nomad/ReadOnlyPublisherRoleCollection.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,13 @@ namespace WindowsAppCommunity.Sdk.Nomad;
1010
/// <summary>
1111
/// A read only handler for roaming publisher/role collection data.
1212
/// </summary>
13-
public class ReadOnlyPublisherRoleCollection : IReadOnlyPublisherRoleCollection, IDelegable<IPublisherRoleCollection>
13+
public class ReadOnlyPublisherRoleCollection : IReadOnlyPublisherRoleCollection, IDelegable<PublisherRole[]>
1414
{
1515
/// <inheritdoc/>
1616
public required string Id { get; init; }
1717

1818
/// <inheritdoc/>
19-
public required IPublisherRoleCollection Inner { get; init; }
19+
public required PublisherRole[] Inner { get; set; }
2020

2121
/// <summary>
2222
/// The client to use for communicating with IPFS.
@@ -37,7 +37,7 @@ public class ReadOnlyPublisherRoleCollection : IReadOnlyPublisherRoleCollection,
3737
/// <inheritdoc/>
3838
public async IAsyncEnumerable<IReadOnlyPublisherRole> GetPublishersAsync([EnumeratorCancellation] CancellationToken cancellationToken)
3939
{
40-
foreach (var publisherRole in Inner.Publishers)
40+
foreach (var publisherRole in Inner)
4141
{
4242
var role = await Client.Dag.GetAsync<Role>(publisherRole.Role, cancel: cancellationToken);
4343
var publisher = await PublisherRepository.GetAsync(publisherRole.PublisherId, cancellationToken);

0 commit comments

Comments
 (0)