Refactor ClientSchedule to mutable types
Use a single mutable location, event, slot, etc, for each unique resource that keeps track of the local editable client copy and the server copy of the data contained in it. This makes it much simpler to update these data structures as I can take advantage of the v-model bindings in Vue.js and work with the system instead of against it.
This commit is contained in:
parent
d48fb035b4
commit
e3ff872b5c
16 changed files with 1213 additions and 1125 deletions
82
utils/client-entity.ts
Normal file
82
utils/client-entity.ts
Normal file
|
@ -0,0 +1,82 @@
|
|||
import type { Entity, EntityLiving, Id } from "~/shared/types/common";
|
||||
import { DateTime, Zone } from "~/shared/utils/luxon";
|
||||
|
||||
export abstract class ClientEntity {
|
||||
/**
|
||||
Millisecond offset used to indicate this is a new entitity.
|
||||
*/
|
||||
static newEntityMillis = -1;
|
||||
/**
|
||||
Timestamp of the entity received from server. If this is
|
||||
a new entity this will have a millisecond offset equal to
|
||||
{@link ClientEntity.newEntityMillis}.
|
||||
*/
|
||||
serverUpdatedAt: DateTime;
|
||||
/**
|
||||
True if the server has deleted this entity, but the client
|
||||
is holding on to it in order to resolve an edit conflcit
|
||||
*/
|
||||
serverDeleted: boolean;
|
||||
|
||||
constructor(
|
||||
/**
|
||||
Server supplied id of this entity. Each kind of entity has its own namespace of ids.
|
||||
*/
|
||||
public readonly id: Id,
|
||||
/**
|
||||
Server's timestamp of this entity at the time it was modified. If the entity
|
||||
is unmodified this will track {@link serverUpdatedAt}. If this is a new entity
|
||||
it'll have a millesecond offset equal to {@link ClientEntity.newEntityMillis}.
|
||||
*/
|
||||
public updatedAt: DateTime,
|
||||
/**
|
||||
Flag indicating the client intends to delete this entity.
|
||||
*/
|
||||
public deleted: boolean,
|
||||
) {
|
||||
this.serverUpdatedAt = updatedAt;
|
||||
this.serverDeleted = deleted;
|
||||
}
|
||||
|
||||
/**
|
||||
True if this entity does not yet exist on the server.
|
||||
*/
|
||||
isNew() {
|
||||
return this.serverUpdatedAt.toMillis() === ClientEntity.newEntityMillis;
|
||||
}
|
||||
|
||||
/**
|
||||
True if both the server and the client have modified this entity
|
||||
independently of each other.
|
||||
*/
|
||||
isConflict() {
|
||||
return this.serverUpdatedAt.toMillis() !== this.updatedAt.toMillis();
|
||||
}
|
||||
|
||||
/**
|
||||
True if this entity has been modified on the client.
|
||||
*/
|
||||
isModified() {
|
||||
return (
|
||||
this.isNew()
|
||||
|| this.deleted
|
||||
|| this.serverDeleted
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
Discard any client side modifications to this entity. Not allowed if
|
||||
{@link serverDeleted} is true or this is a new entity.
|
||||
*/
|
||||
abstract discard(): void
|
||||
|
||||
/**
|
||||
Apply an update delivered from the API to this entity.
|
||||
*/
|
||||
abstract apiUpdate(api: EntityLiving, opts: { zone: Zone, locale: string }): void
|
||||
|
||||
/**
|
||||
Serialise this entity to the API format. Not allowed if {@link deleted} is true.
|
||||
*/
|
||||
abstract toApi(): Entity
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue