Repository: vigetlabs/microcosm
Pull request #520 (2018-06-19 12:12:13)

Add back max history option
**What**

This commit adds back the max history option to Microcosm, a feature of 12.x that controls how many actions Microcosm's history should hold on to.

This is based upon depth, not overall action count. This is so that you can checkout prior trees. For example:

```
          action-0__________
          /        \         \
      action-1  action-2  action-3__________
                         /        \         \
                     action-4  action-5  action-6__________
                                        /        \         \
                                    action-7  action-8  action-9___________
                                                       /        \          \
                                                   action-10 action-11  action-12___________
                                                                       /         \          \
                                                                   action-13  action-14  action-15
                                                                                        /         \
                                                                                    action-16  action-17
```

This is with a size of 10, though in this case, the overall depth hasn't hit higher than 6. With a size of 3, this would look like:

```
        action-0__________
          /        \         \
      action-1  action-2  action-3
                         /        \
                     action-4  action-5
```

This is zero by default in order to prevent memory leaks. However some apps (like email editors we have built in the past) may desire to hold on to a set number of actions for undo/redo and reporting features.

**Why**

I want to respect the 12.x API and keep this feature, which is extremely useful when you need it.


Patch:
diff --git a/packages/microcosm/src/history.js b/packages/microcosm/src/history.js
index 1df0d66f..c29be607 100644
--- a/packages/microcosm/src/history.js
+++ b/packages/microcosm/src/history.js
@@ -22,6 +22,7 @@ export class History extends Subject {
   _branch: Set<Subject>
   _tree: Tree<Subject>
   _debug: boolean
+  _limit: number
 
   constructor(options: Object) {
     super()
@@ -31,6 +32,7 @@ export class History extends Subject {
     this._branch = new Set()
     this._tree = new Tree()
     this._debug = !!options.debug
+    this._limit = Math.max(options.maxHistory, 0)
   }
 
   get size(): number {
@@ -43,7 +45,7 @@ export class History extends Subject {
   }
 
   archive() {
-    while (this.root && this.size > 1 && this.root.closed) {
+    while (this.root && this.size > this._limit && this.root.closed) {
       let last = this.root
       let next = this._tree.after(this.root)
 
diff --git a/packages/microcosm/src/microcosm.js b/packages/microcosm/src/microcosm.js
index 506e5e96..08c35f29 100644
--- a/packages/microcosm/src/microcosm.js
+++ b/packages/microcosm/src/microcosm.js
@@ -15,6 +15,7 @@ import { RESET, PATCH } from './lifecycle'
 
 const DEFAULTS = {
   debug: false,
+  maxHistory: 1,
   parent: null
 }
 
@@ -81,9 +82,8 @@ export class Microcosm extends Subject {
     )
 
     if (blueprint instanceof Observable) {
-      let domain = Subject.from(blueprint)
-      this.domains[key] = domain
-      this.subscribe({ complete: domain.complete })
+      this.domains[key] = Subject.from(blueprint)
+      this.subscribe({ complete: this.domains[key].complete })
     } else {
       let Entity = inherit(blueprint, Domain)
 


Test patch:
diff --git a/packages/microcosm/test/unit/history/archive.test.js b/packages/microcosm/test/unit/history/archive.test.js
index f013da9b..ad8220fb 100644
--- a/packages/microcosm/test/unit/history/archive.test.js
+++ b/packages/microcosm/test/unit/history/archive.test.js
@@ -69,4 +69,17 @@ describe('History::archive', function() {
     //   a rollback to the state of 1
     expect(repo.history.size).toBe(3)
   })
+
+  it('can maintain a specific size', function() {
+    const size = 3
+    const repo = new Microcosm({ maxHistory: size })
+
+    for (var i = 0; i < size * 2; i++) {
+      repo.push(`action-${i}`)
+    }
+
+    repo.history.archive()
+
+    expect(repo.history.size).toBe(size)
+  })
 })