Skip to content

Commit 2ef95c9

Browse files
committed
do not set the author automatically when modifying Causal* types, even if there is a single writer
1 parent 6e075ab commit 2ef95c9

File tree

11 files changed

+97
-110
lines changed

11 files changed

+97
-110
lines changed

src/data/collections/causal/CausalArray.ts

Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import { ClassRegistry } from 'data/model/literals';
1515
import { MutableContentEvents } from 'data/model/mutable/MutableObject';
1616
import { MultiMap } from 'util/multimap';
1717
import { InvalidateAfterOp } from 'data/model/causal';
18-
import { AuthError, BaseCausalCollection, CausalCollection, CausalCollectionConfig, CausalCollectionOp } from './CausalCollection';
18+
import { AuthError, BaseCausalCollection, CausalCollection, CausalCollectionConfig } from './CausalCollection';
1919
import { Identity } from 'data/identity';
2020

2121
// A mutable list with a
@@ -29,11 +29,14 @@ class InsertOp<T> extends MutationOp {
2929
element?: T;
3030
ordinal?: Ordinal;
3131

32-
constructor(target?: CausalArray<T>, element?: T, ordinal?: Ordinal) {
32+
constructor(target?: CausalArray<T>, element?: T, ordinal?: Ordinal, author?: Identity) {
3333
super(target);
3434

3535
this.element = element;
3636
this.ordinal = ordinal;
37+
if (author !== undefined) {
38+
this.setAuthor(author);
39+
}
3740
}
3841

3942
getClassName(): string {
@@ -65,8 +68,12 @@ class DeleteOp<T> extends InvalidateAfterOp {
6568

6669
static className = 'hhs/v0/CausalArray/DeleteOp';
6770

68-
constructor(insertOp?: InsertOp<T>) {
71+
constructor(insertOp?: InsertOp<T>, author?: Identity) {
6972
super(insertOp);
73+
74+
if (author !== undefined) {
75+
this.setAuthor(author);
76+
}
7077
}
7178

7279
init() {
@@ -259,13 +266,7 @@ class CausalArray<T> extends BaseCausalCollection<T> implements CausalCollection
259266
oldInsertionOps = this._currentInsertOps.get(elementHash);
260267
}
261268

262-
const insertOp = new InsertOp(this, element, ordinal);
263-
264-
if (author !== undefined) {
265-
insertOp.setAuthor(author);
266-
} else if (this.getClassName() === CausalArray.className) {
267-
CausalCollectionOp.setSingleAuthorIfNecessary(insertOp);
268-
}
269+
const insertOp = new InsertOp(this, element, ordinal, author);
269270

270271
const auth = Authorization.chain(this.createInsertAuthorizer(insertOp.getAuthor()), extraAuth);
271272

@@ -416,13 +417,8 @@ class CausalArray<T> extends BaseCausalCollection<T> implements CausalCollection
416417
}
417418

418419
private async deleteOpForInsertOp(insertOp: InsertOp<T>, author?: Identity, extraAuth?: Authorizer) {
419-
const deleteOp = new DeleteOp(insertOp);
420-
421-
if (author !== undefined) {
422-
deleteOp.setAuthor(author);
423-
} else if (this.getClassName() === CausalArray.className) {
424-
CausalCollectionOp.setSingleAuthorIfNecessary(deleteOp);
425-
}
420+
421+
const deleteOp = new DeleteOp(insertOp, author);
426422

427423
const auth = Authorization.chain(this.createDeleteAuthorizer(deleteOp.getAuthor()), extraAuth);
428424

src/data/collections/causal/CausalCollection.ts

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -81,20 +81,6 @@ abstract class BaseCausalCollection<T> extends BaseCollection<T> {
8181
}
8282
}
8383

84-
abstract class CausalCollectionOp extends MutationOp {
8584

86-
static setSingleAuthorIfNecessary(op: MutationOp) {
87-
88-
const targetObject = op.getTargetObject();
89-
90-
if (targetObject instanceof BaseCausalCollection) {
91-
if (targetObject.hasSingleWriter()) {
92-
op.setAuthor(targetObject.getSingleWriter());
93-
}
94-
}
95-
96-
}
97-
}
98-
99-
export { CausalCollection, BaseCausalCollection, CausalCollectionOp, AuthError };
85+
export { CausalCollection, BaseCausalCollection, AuthError };
10086
export type { CausalCollectionConfig };

src/data/collections/causal/CausalSet.ts

Lines changed: 12 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { Authorization, Verification } from '../../model/causal/Authorization';
88
import { HashedSet } from '../../model/immutable/HashedSet';
99
import { MutableSetEvents } from '../../collections/mutable/MutableSet';
1010
import { MutableContentEvents } from '../../model/mutable/MutableObject';
11-
import { AuthError, BaseCausalCollection, CausalCollection, CausalCollectionConfig, CausalCollectionOp } from './CausalCollection';
11+
import { AuthError, BaseCausalCollection, CausalCollection, CausalCollectionConfig } from './CausalCollection';
1212
import { ClassRegistry } from 'data/model/literals';
1313

1414
/*
@@ -25,10 +25,13 @@ class AddOp<T> extends MutationOp {
2525

2626
element?: T;
2727

28-
constructor(targetObject?: CausalSet<T>, element?: T) {
28+
constructor(targetObject?: CausalSet<T>, element?: T, author?: Identity) {
2929
super(targetObject);
3030

3131
this.element = element;
32+
if (author !== undefined) {
33+
this.setAuthor(author);
34+
}
3235
}
3336

3437
getClassName(): string {
@@ -84,8 +87,12 @@ class AddOp<T> extends MutationOp {
8487
class DeleteOp<T> extends InvalidateAfterOp {
8588
static className = 'hss/v0/CausalSet/DeleteOp';
8689

87-
constructor(targetOp?: AddOp<T>) {
90+
constructor(targetOp?: AddOp<T>, author?: Identity) {
8891
super(targetOp);
92+
93+
if (author !== undefined) {
94+
this.setAuthor(author);
95+
}
8996
}
9097

9198
async validate(references: Map<Hash, HashedObject>): Promise<boolean> {
@@ -230,13 +237,7 @@ class CausalSet<T> extends BaseCausalCollection<T> implements CausalCollection<T
230237
throw new Error('CausalSet has type/element contraints that reject the element that is being added:' + elmt)
231238
}
232239

233-
const addOp = new AddOp(this, elmt);
234-
235-
if (author !== undefined) {
236-
addOp.setAuthor(author);
237-
} else {
238-
CausalCollectionOp.setSingleAuthorIfNecessary(addOp);
239-
}
240+
const addOp = new AddOp(this, elmt, author);
240241

241242
const auth = Authorization.chain(this.createAddAuthorizer(addOp.getAuthor()), extraAuth);
242243

@@ -263,13 +264,7 @@ class CausalSet<T> extends BaseCausalCollection<T> implements CausalCollection<T
263264

264265
for (const addOpHash of this._currentAddOpsPerElmt.get(hash)) {
265266
const addOp = this._currentAddOps.get(addOpHash) as AddOp<T>;
266-
const deleteOp = new DeleteOp(addOp);
267-
268-
if (author !== undefined) {
269-
deleteOp.setAuthor(author);
270-
} else {
271-
CausalCollectionOp.setSingleAuthorIfNecessary(deleteOp);
272-
}
267+
const deleteOp = new DeleteOp(addOp, author);
273268

274269
const auth = Authorization.chain(this.createDeleteAuthorizer(deleteOp.getAuthor()), extraAuth);
275270

src/data/collections/mutable/Collection.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { Hash} from '../../model/hashing'
55

66

77
type CollectionConfig = {
8+
author?: Identity,
89
writer?: Identity,
910
writers?: IterableIterator<Identity>,
1011
acceptedTypes?: Array<string>,
@@ -29,6 +30,10 @@ abstract class BaseCollection<T> extends MutableObject {
2930
constructor(acceptedOpClasses : Array<string>, config?: MutableObjectConfig & CollectionConfig) {
3031
super(acceptedOpClasses, config);
3132

33+
if (config?.author !== undefined) {
34+
this.setAuthor(config.author);
35+
}
36+
3237
if (config?.writers !== undefined) {
3338
this.writers = new HashedSet<Identity>(config.writers);
3439

@@ -103,10 +108,6 @@ abstract class BaseCollection<T> extends MutableObject {
103108
return true;
104109
}
105110

106-
validateWriteAccess() {
107-
108-
}
109-
110111
hasSingleWriter() {
111112
return this.writers !== undefined && this.writers.size() === 1;
112113
}

src/data/collections/mutable/GrowOnlySet.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,14 @@ class AddOp<T> extends CollectionOp<T> {
1616

1717
element?: T;
1818

19-
constructor(targetObject?: GrowOnlySet<T>, element?: T) {
19+
constructor(targetObject?: GrowOnlySet<T>, element?: T, author?: Identity) {
2020
super(targetObject);
2121

2222
this.element = element;
23+
24+
if (author !== undefined) {
25+
this.setAuthor(author);
26+
}
2327
}
2428

2529
getClassName(): string {
@@ -84,14 +88,12 @@ class GrowOnlySet<T> extends BaseCollection<T> {
8488
}
8589

8690
if (!this.has(element)) {
87-
let op = new AddOp<T>(this, element);
91+
let op = new AddOp<T>(this, element, author);
8892
if (author !== undefined) {
8993

9094
if (this.writers !== undefined && !this.writers.has(author)) {
9195
throw new Error('Identity ' + author.hash() + ' tried to add an element to GrowOnlySet ' + this.hash() + ', but it is not in the writers set.');
9296
}
93-
94-
op.setAuthor(author);
9597
} else {
9698
if (this.writers !== undefined) {
9799
throw new Error('Tried to add an element to GrowOnlySet ' + this.hash + ', but did not probide an author that can write to it.');

src/data/collections/mutable/MutableArray.ts

Lines changed: 31 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import { ClassRegistry } from 'data/model/literals';
1212
import { MutableContentEvents } from 'data/model/mutable/MutableObject';
1313
import { MultiMap } from 'util/multimap';
1414
import { BaseCollection, Collection, CollectionConfig, CollectionOp } from './Collection';
15+
import { Identity } from 'data/identity';
1516

1617
// a simple mutable list with a single writer
1718

@@ -24,11 +25,14 @@ class InsertOp<T> extends CollectionOp<T> {
2425
element?: T;
2526
ordinal?: Ordinal;
2627

27-
constructor(target?: MutableArray<T>, element?: T, ordinal?: Ordinal) {
28+
constructor(target?: MutableArray<T>, element?: T, ordinal?: Ordinal, author?: Identity) {
2829
super(target);
2930

3031
this.element = element;
3132
this.ordinal = ordinal;
33+
if (author !== undefined) {
34+
this.setAuthor(author);
35+
}
3236
}
3337

3438
getClassName(): string {
@@ -69,7 +73,7 @@ class DeleteOp<T> extends CollectionOp<T> {
6973
elementHash?: Hash;
7074
deletedOps?: HashedSet<HashReference<InsertOp<T>>>;
7175

72-
constructor(target?: MutableArray<T>, elementHash?: Hash, insertOps?: IterableIterator<HashReference<InsertOp<T>>>) {
76+
constructor(target?: MutableArray<T>, elementHash?: Hash, insertOps?: IterableIterator<HashReference<InsertOp<T>>>, author?: Identity) {
7377
super(target);
7478

7579
this.elementHash = elementHash;
@@ -85,6 +89,10 @@ class DeleteOp<T> extends CollectionOp<T> {
8589
this.deletedOps.add(insertOp);
8690
}
8791
}
92+
93+
if (author !== undefined) {
94+
this.setAuthor(author);
95+
}
8896
}
8997

9098
init() {
@@ -208,11 +216,11 @@ class MutableArray<T> extends BaseCollection<T> implements Collection<T> {
208216
this._ordinals = [];
209217
}
210218

211-
async insertAt(element: T, idx: number) {
212-
await this.insertManyAt([element], idx);
219+
async insertAt(element: T, idx: number, author?: Identity) {
220+
await this.insertManyAt([element], idx, author);
213221
}
214222

215-
async insertManyAt(elements: T[], idx: number) {
223+
async insertManyAt(elements: T[], idx: number, author?: Identity) {
216224
this.rebuild();
217225

218226
// In the "no duplicates" case, any items we insert will disappear from their old positions. So
@@ -262,7 +270,7 @@ class MutableArray<T> extends BaseCollection<T> implements Collection<T> {
262270
oldInsertionOps = this._currentInsertOpRefs.get(elementHash);
263271
}
264272

265-
const insertOp = new InsertOp(this, element, ordinal);
273+
const insertOp = new InsertOp(this, element, ordinal, author);
266274
await this.applyNewOp(insertOp);
267275

268276
// Note: in the "no duplicates" case, the delete -if necessary- has to come after the
@@ -280,52 +288,52 @@ class MutableArray<T> extends BaseCollection<T> implements Collection<T> {
280288
}
281289
}
282290

283-
async deleteAt(idx: number) {
284-
await this.deleteManyAt(idx, 1);
291+
async deleteAt(idx: number, author?: Identity) {
292+
await this.deleteManyAt(idx, 1, author);
285293
}
286294

287-
async deleteManyAt(idx: number, count: number) {
295+
async deleteManyAt(idx: number, count: number, author?: Identity) {
288296
this.rebuild();
289297

290298
while (idx < this._contents.length && count > 0) {
291299
let hash = this._hashes[idx];
292300

293301
if (this.duplicates) {
294-
await this.delete(hash, this._ordinals[idx]);
302+
await this.delete(hash, this._ordinals[idx], author);
295303
} else {
296-
await this.delete(hash);
304+
await this.delete(hash, undefined, author);
297305
}
298306

299307
idx = idx + 1;
300308
count = count - 1;
301309
}
302310
}
303311

304-
async deleteElement(element: T) {
305-
this.deleteElementByHash(HashedObject.hashElement(element));
312+
async deleteElement(element: T, author?: Identity) {
313+
this.deleteElementByHash(HashedObject.hashElement(element), author);
306314
}
307315

308-
async deleteElementByHash(hash: Hash) {
316+
async deleteElementByHash(hash: Hash, author?: Identity) {
309317
this.rebuild();
310-
this.delete(hash);
318+
this.delete(hash, undefined, author);
311319
}
312320

313-
async push(element: T) {
314-
await this.insertAt(element, this._contents.length);
321+
async push(element: T, author?: Identity) {
322+
await this.insertAt(element, this._contents.length, author);
315323
}
316324

317-
async pop(): Promise<T> {
325+
async pop(author?: Identity): Promise<T> {
318326
this.rebuild();
319327
const lastIdx = this._contents.length - 1;
320328
const last = this._contents[lastIdx];
321-
await this.deleteAt(lastIdx);
329+
await this.deleteAt(lastIdx, author);
322330

323331
return last;
324332
}
325333

326-
async concat(elements: T[]) {
334+
async concat(elements: T[], author?: Identity) {
327335
this.rebuild();
328-
await this.insertManyAt(elements, this._contents.length);
336+
await this.insertManyAt(elements, this._contents.length, author);
329337
}
330338

331339
contents() {
@@ -369,15 +377,15 @@ class MutableArray<T> extends BaseCollection<T> implements Collection<T> {
369377
return this._contents[idx];
370378
}
371379

372-
private async delete(hash: Hash, ordinal?: Ordinal) {
380+
private async delete(hash: Hash, ordinal?: Ordinal, author?: Identity) {
373381

374382
let deleteOp: DeleteOp<T>|undefined = undefined;
375383
const insertOpRefs = this._currentInsertOpRefs.get(hash);
376384

377385
if (ordinal !== undefined) {
378386
for (const insertOpRef of insertOpRefs.values()) {
379387
if (this._currentInsertOpOrds.get(insertOpRef.hash) === ordinal) {
380-
deleteOp = new DeleteOp(this, hash, [insertOpRef].values());
388+
deleteOp = new DeleteOp(this, hash, [insertOpRef].values(), author);
381389
break;
382390
}
383391
}

0 commit comments

Comments
 (0)