Last active
September 23, 2019 21:06
-
-
Save habdelra/d26a39f18ad699c60c649b2280ec3ed7 to your computer and use it in GitHub Desktop.
Card Data Service brainstorming
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Service from '@ember/service'; | |
export default class DataService extends Service { | |
cache = new Map(); | |
async getCard(id /*: string */, format /*: string*/) { | |
// if the card already exists in the cache, just return cached card | |
// return Card instance | |
} | |
async createCard() { | |
// return Card instance, and create cache entry for Card | |
} | |
async deleteCard(id /*: string */) { | |
// also make sure to remove cached Card | |
} | |
} | |
class Card { | |
isDirty = false; | |
id; // string | |
format; // could be either 'embedded' or 'isolated' | |
embeddedData; // ResourceObject | |
isolatedData; // SingleResourceDocument | |
constructor(id /*: string */, format /*: string */, embeddedData /* ResourceObject*/) { | |
// this can be instantiated with an optional embeddedData object, which will be the embedded form of this card | |
// that was included as an embedded relationship from another card. This gives us the ability to | |
// render embedded cards without having to pay a lookup cost if this card's was included from a | |
// 'needed-when-embedded' field of another card. | |
this.id = id; | |
this.format = format; | |
this.embeddedData = embeddedData; | |
} | |
async setField(field /*: string */, value /* any (including another Card) */) { | |
// this.format needs to be 'isolated' in order to update the card. If this.format is not isolated, | |
// then let's fetch the isolated form of the card first. | |
} | |
async getField(field /*: string */) { | |
// if this.isDirty, should we should save() first? as computed/metadata fields could be impacted | |
// or maybe we should throw if you try to getField but this.isDirty is true | |
// if this.embeddedData or this.isolatedData has the field, then return it. | |
// Do note that we need to respect the format of the card when getting a field. | |
// getting an isolated-only field when the card is in the embedded format should probably | |
// throw an error. | |
// if the field value is another Card then instantiate a new Card instance and return that | |
// this should only expose card metadata and not internal card fields | |
} | |
async addField(fieldDefinition /*: SingleResourceDocument*/) { | |
// the fieldDefinition is the fields JSONAPI document for the new field. | |
// If the field has a relationship (e.g. a relationship to a constraint), the additional | |
// resources necessary should be in the included for the field. | |
// this.format needs to be 'isolated' in order to update the card. If this.format is not isolated, | |
// then let's fetch the isolated form of the card first. | |
} | |
async removeField(field /*: string*/) { | |
// this removes the field and the field's data from the Card. | |
// this.format needs to be 'isolated' in order to update the card. If this.format is not isolated, | |
// then let's fetch the isolated form of the card first. | |
} | |
async allFields() { | |
// this returns all the Card's metadata fields in the correct order and the field types so we know how to render them. Perhaps, we just return | |
// the JSON:API ResourceObjects for each field to make it simple for now? | |
// We also need to think about how to invoke with for an embedded card. it would be nice to not have to make an extra | |
// trip over the wire for each embedded card in order to render it--which I think means that the embedded form of a card | |
// needs to have enough schema information about it's fields to be able to communicate to the client how to render the field. | |
} | |
async save() { | |
// perform a post or patch (depending on if this card already exists) | |
// update this.isolatedData with the response of the post/patch (those always return the isolated card format) | |
// set this.isDirty to false | |
// return this (which will have metadata fields set, and computeds resolved) | |
} | |
async reload(format /*: string */) { | |
// get the lastest version of the card from the hub, and update the data service cache. load the requested card format | |
// this is analogous to the card polling that we've done in other projects like cardfolio and tally | |
// in the case where there is an indexer that is feeding the card new field data | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment