Skip to content

Commit 6a8f200

Browse files
Pollepsjoepio
authored andcommitted
Merged #657 Simplify state stuff
1 parent 5be4f28 commit 6a8f200

File tree

3 files changed

+60
-65
lines changed

3 files changed

+60
-65
lines changed

browser/lib/src/commit.ts

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -491,11 +491,7 @@ export function parseAndApplyCommit(jsonAdObjStr: string, store: Store) {
491491
} else {
492492
resource.appliedCommitSignatures.add(signature);
493493

494-
if (isNew) {
495-
store.addResources(resource);
496-
} else {
497-
store.notify(resource.clone());
498-
}
494+
store.addResources(resource);
499495
}
500496
}
501497

browser/lib/src/resource.ts

Lines changed: 39 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ export const unknownSubject = 'unknown-subject';
3636
*/
3737
// eslint-disable-next-line @typescript-eslint/no-explicit-any
3838
export class Resource<C extends OptionalClass = any> {
39+
// WARNING: WHEN ADDING A PROPERTY, ALSO ADD IT TO THE CLONE METHOD
40+
3941
/** If the resource could not be fetched, we put that info here. */
4042
public error?: Error;
4143
/** If the commit could not be saved, we put that info here. */
@@ -57,8 +59,6 @@ export class Resource<C extends OptionalClass = any> {
5759
private subject: string;
5860
private propvals: PropVals;
5961

60-
private queuedFetch: Promise<unknown> | undefined;
61-
6262
public constructor(subject: string, newResource?: boolean) {
6363
if (typeof subject !== 'string') {
6464
throw new Error(
@@ -95,19 +95,39 @@ export class Resource<C extends OptionalClass = any> {
9595
return props;
9696
}
9797

98-
/** Checks if the content of two Resource instances is equal
99-
* Warning: does not check CommitBuilder, loading state
100-
*/
101-
public static compare(resourceA: Resource, resourceB: Resource): boolean {
102-
if (resourceA.error !== resourceB.error) {
98+
/** Checks if the content of two Resource instances is equal */
99+
public equals(resourceB: Resource): boolean {
100+
if (this.getSubject() !== resourceB.getSubject()) {
103101
return false;
104102
}
105103

106-
return (
107-
resourceA.getSubject() === resourceB.getSubject() &&
108-
JSON.stringify(Array.from(resourceA.propvals.entries())) ===
109-
JSON.stringify(Array.from(resourceB.propvals.entries()))
110-
);
104+
if (this.new !== resourceB.new) {
105+
return false;
106+
}
107+
108+
if (this.error !== resourceB.error) {
109+
return false;
110+
}
111+
112+
if (this.loading !== resourceB.loading) {
113+
return false;
114+
}
115+
116+
if (
117+
JSON.stringify(Array.from(this.propvals.entries())) ===
118+
JSON.stringify(Array.from(resourceB.propvals.entries()))
119+
) {
120+
return false;
121+
}
122+
123+
if (
124+
JSON.stringify(Array.from(this.commitBuilder.set.entries())) ===
125+
JSON.stringify(Array.from(resourceB.commitBuilder.set.entries()))
126+
) {
127+
return false;
128+
}
129+
130+
return true;
111131
}
112132

113133
/** Checks if the agent has write rights by traversing the graph. Recursive function. */
@@ -163,12 +183,10 @@ export class Resource<C extends OptionalClass = any> {
163183
res.propvals = structuredClone(this.propvals);
164184
res.loading = this.loading;
165185
res.new = this.new;
166-
// structured clone
167186
res.error = structuredClone(this.error);
168187
res.commitError = this.commitError;
169188
res.commitBuilder = this.commitBuilder.clone();
170189
res.appliedCommitSignatures = this.appliedCommitSignatures;
171-
res.queuedFetch = this.queuedFetch;
172190

173191
return res as Resource<C>;
174192
}
@@ -477,29 +495,16 @@ export class Resource<C extends OptionalClass = any> {
477495
const endpoint = new URL(this.getSubject()).origin + `/commit`;
478496

479497
try {
480-
// We optimistically update all viewed instances for snappy feedback
481-
store.addResources(this);
482-
store.notify(this);
483-
484-
// If a commit is already being posted we wait for it to finish
485-
// because the server can not guarantee the commits will be processed in the correct order.
486-
487-
if (this.queuedFetch) {
488-
try {
489-
await this.queuedFetch;
490-
} catch (e) {
491-
// Continue
492-
}
493-
}
494-
495498
this.commitError = undefined;
496-
const createdCommitPromise = store.postCommit(commit, endpoint);
497-
this.queuedFetch = createdCommitPromise;
498-
store.notify(this);
499-
const createdCommit = await createdCommitPromise;
500-
499+
store.addResources(this);
500+
const createdCommit = await store.postCommit(commit, endpoint);
501+
// const res = store.getResourceLoading(this.subject);
501502
this.setUnsafe(properties.commit.lastCommit, createdCommit.id!);
502503

504+
// Let all subscribers know that the commit has been applied
505+
// store.addResources(this);
506+
store.notifyResourceSaved(this);
507+
503508
if (wasNew) {
504509
// The first `SUBSCRIBE` message will not have worked, because the resource didn't exist yet.
505510
// That's why we need to repeat the process
@@ -510,9 +515,6 @@ export class Resource<C extends OptionalClass = any> {
510515
await store.saveBatchForParent(this.getSubject());
511516
}
512517

513-
// Let all subscribers know that the commit has been applied
514-
store.notifyResourceSaved(this);
515-
516518
return createdCommit.id as string;
517519
} catch (e) {
518520
// Logic for handling error if the previousCommit is wrong.
@@ -540,7 +542,6 @@ export class Resource<C extends OptionalClass = any> {
540542
this.commitBuilder = oldCommitBuilder;
541543
this.commitError = e;
542544
store.addResources(this);
543-
store.notify(this.clone());
544545
throw e;
545546
}
546547
}
@@ -582,15 +583,13 @@ export class Resource<C extends OptionalClass = any> {
582583

583584
if (value === undefined) {
584585
this.removePropVal(prop);
585-
store.notify(this.clone());
586586

587587
return;
588588
}
589589

590590
this.propvals.set(prop, value);
591591
// Add the change to the Commit Builder, so we can commit our changes later
592592
this.commitBuilder.addSetAction(prop, value);
593-
store.notify(this.clone());
594593
}
595594

596595
/**

browser/lib/src/store.ts

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -155,14 +155,16 @@ export class Store {
155155
const storeResource = this.resources.get(resource.getSubject());
156156

157157
if (storeResource) {
158-
if (Resource.compare(storeResource, resource)) {
158+
if (resource.equals(storeResource)) {
159159
return;
160160
}
161161
}
162162

163-
this.resources.set(resource.getSubject(), resource);
163+
const cloned = resource.clone();
164+
165+
this.resources.set(cloned.getSubject(), cloned);
164166

165-
this.notify(resource.clone());
167+
this.notify(cloned);
166168
}
167169

168170
/** Checks if a subject is free to use */
@@ -471,23 +473,6 @@ export class Store {
471473
return !window?.navigator?.onLine;
472474
}
473475

474-
/** Let's subscribers know that a resource has been changed. Time to update your views!
475-
* Note that when using this in React, we need the Resource to be Cloned in order to update.
476-
*/
477-
public async notify(resource: Resource): Promise<void> {
478-
const subject = resource.getSubject();
479-
const callbacks = this.subscribers.get(subject);
480-
481-
if (callbacks === undefined) {
482-
return;
483-
}
484-
485-
// We clone for react, because otherwise it won't rerender
486-
const cloned = resource.clone();
487-
this._resources.set(subject, cloned);
488-
Promise.allSettled(callbacks.map(async cb => cb(cloned)));
489-
}
490-
491476
public async notifyResourceSaved(resource: Resource): Promise<void> {
492477
await this.eventManager.emit(StoreEvents.ResourceSaved, resource);
493478
}
@@ -849,6 +834,21 @@ export class Store {
849834

850835
return url;
851836
}
837+
838+
/** Lets subscribers know that a resource has been changed. Time to update your views.
839+
* Make sure the resource is a new reference, otherwise React will not rerender.
840+
*/
841+
private async notify(resource: Resource): Promise<void> {
842+
const subject = resource.getSubject();
843+
const callbacks = this.subscribers.get(subject);
844+
845+
if (callbacks === undefined) {
846+
return;
847+
}
848+
849+
// We clone for react, because otherwise it won't rerender
850+
Promise.allSettled(callbacks.map(async cb => cb(resource)));
851+
}
852852
}
853853

854854
/**

0 commit comments

Comments
 (0)