Skip to content

Commit

Permalink
Updated docs / changelog
Browse files Browse the repository at this point in the history
  • Loading branch information
mweststrate committed Jun 11, 2017
1 parent 2de415b commit ceffe1d
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 23 deletions.
35 changes: 17 additions & 18 deletions README.md
Expand Up @@ -194,7 +194,7 @@ const TodoStore = types.model("TodoStore", { // 1
loaded: types.boolean // 2
endpoint: "http://localhost", // 3
todos: types.array(Todo), // 4
selectedTodo: types.reference(Todo, "todos"), // 5
selectedTodo: types.reference(Todo), // 5
get completedTodos() { // 6
return this.todos.filter(t => t.done)
},
Expand Down Expand Up @@ -369,7 +369,7 @@ const Todo = types.model({
const TodoStore = types.model({
todos: types.array(Todo),
selectedTodo: types.reference(Todo, "todos")
selectedTodo: types.reference(Todo)
})
// create a store with a normalized snapshot
Expand All @@ -390,24 +390,15 @@ console.log(storeInstance.selectedTodo.title)

- Each model can define zero or one `identifier()` properties
- The identifier property of an object cannot be modified after initialization
- Identifiers should be unique within their parent collection (`array` or `map`)
- Each identifiers / type combination should be unique within the entire tree
- Identifiers are used to reconcile items inside arrays and maps wherever possible when applying snapshots
- The `map.put()` method can be used to simplify adding objects to maps that have identifiers

TODO: when (not) to use identifiers
- The `map.put()` method can be used to simplify adding objects that have identifiers to maps
- The primary goal of identifiers is not validation, but reconciliation and reference resolving. For this reason identifiers cannot be defined or updated after creation. If you want to check if some value just looks as an identifier, without providing the above semantics; use something like: `types.refinement(types.string, v => v.match(/someregex/))`

#### References

References can be defined in two ways, generic or namespaces.

Namespaced references can only put to elements of the correct type, at a predefined location (namespace). Namespaced references always use the `identifier()` property of the targeted object.
The above example: `selectedTodo: types.reference(Todo, "todos")` is namespaced, and resolves it's target in the collection on the relative path `"todos"`. (`"../todos"` can be used to identify a namespace one level higher in the tree etc.)
Generic references can point to any element of the correct type in the current tree, and are stored behind the scenes as JSON path. The above example could also have been configured as `selectedTodo: types.reference(Todo)` to create a generic reference.
_Tip: It is recommended to use namespaced references; as those are more stable, since they always use immutable references and a preconfigured namespace._
**Note: The exact semantics of references are still under investigation, and might change before MST 1.0. One of the two forms might be dropped_**
References are defined by mentioning the type they should resolve to. The targetted type should have exactly one attribute of the type `identifier()`.
References are looked up through the entire tree, but per type. So identifiers need to be unique in the entire tree.

### Listening to observables, snapshots, patches or actions

Expand Down Expand Up @@ -505,7 +496,7 @@ These are the types available in MST. All types can be found in the `types` name

Property types can only be used as direct member of a `types.model` type and not further composed (for now).
* `types.identifier(subType?)` Only one such member can exist in a `types.model` and should uniquely identify the object. See [identifiers](#identifiers) for more details. `subType` should be either `types.string` or `types.number`, defaulting to the first if not specified.
* `types.reference(targetType, basePath?)` creates a property that is a reference to another item of the given `targetType` somewhere in the same tree. See [references](#references) for more details.
* `types.reference(targetType)` creates a property that is a reference to another item of the given `targetType` somewhere in the same tree. See [references](#references) for more details.

## LifeCycle hooks for `types.model`

Expand Down Expand Up @@ -637,10 +628,18 @@ const Temperature = types.union(...["Hot", "Cold"].map(types.literal))
### Storing non-serializable data with models
TODO
TODO `types.localState`
# FAQ
### How does reconcilation work?
* When applying snapshots, MST will always try to reuse existing object instances for snapshots with the same identifier (see `types.identifier()`).
* If no identifier is specified, but the type of the snapshot is correct, MST will reconcile objects as well if they are stored in a specific model property or under the same map key.
* In arrays, items without identifier are never reconciled
If an object is reconciled, the consequence is that localState is preserved and `postCreate` / `attach` life-cycle hooks are not fired because applying a snapshot results just in an existing tree node being updated.
### Creating async processes
For asynchronous processes, for each step that intends to modify a model you need a separate action. So for example one to kick off the process. And one to update the model. In a multi stage async process, consider postponing all updates until the last step is completed.
Expand Down
21 changes: 16 additions & 5 deletions changelog.md
@@ -1,13 +1,24 @@
# 0.7.0

The type system and internal administration has been refactoring, making the internals both simpler and more flexible.
Things like references and identifiers are now first class types, making them much better composable.

* **BREAKING** References with a predefined lookup path are no longer supported. Instead of that, identifiers are now looked up in the entire tree. For that reasons identifiers now have to be unique in the entire tree, per type.
* **BREAKING** `resolve` is renamed to `resolvePath`
* Introduced `resolveIdentifier(type, tree, identifier)` to find objects by identifier
* **BREAKING** `types.reference` is by default non-nullable. For nullable identifiers, use `types.maybe(types.reference(X))`
* Many, many improvements. Related open issues will be updated.

# 0.6.3

Fixed issue with array/maps of union types @abruzzihraig
Make types.extend support computed attributes @cpunion
Fixed issue with map of primitive types and applySnapshot @pioh
Better type declarations for union, up to 10 supported types
* Fixed issue with array/maps of union types @abruzzihraig
* Make types.extend support computed attributes @cpunion
* Fixed issue with map of primitive types and applySnapshot @pioh
* Better type declarations for union, up to 10 supported types

# 0.6.2

Fixed issue where arrays where not properly serialized as action argument
* Fixed issue where arrays where not properly serialized as action argument

# 0.6.1

Expand Down

0 comments on commit ceffe1d

Please sign in to comment.