Skip to content

Commit

Permalink
Allow takeSnapshot to specify specific stores
Browse files Browse the repository at this point in the history
- Resolves Issue #54
- This enables snapshotting a subset of the app data
- `takeSnapshot` returns stringified JSON containing just the subset
  of data specified. The new snapshot is merged with the LAST_SNAPSHOT data
  to ensure that the last snapshot of the stores not specified in the subset
  is not lost. This also means that rollbacks will just work.
  • Loading branch information
jdlehman committed Mar 19, 2015
1 parent c386348 commit 98b3c04
Show file tree
Hide file tree
Showing 8 changed files with 87 additions and 22 deletions.
4 changes: 2 additions & 2 deletions README.md
Expand Up @@ -529,12 +529,12 @@ Restart the loop by making your views kick off new actions.

### Snapshots

`takeSnapshot :: String`
`takeSnapshot :: ?...String -> String`

Snapshots are a core component of alt. The idea is that at any given point in time you can `takeSnapshot` and have your entire application's state
serialized for persistence, transferring, logging, or debugging.

Taking a snapshot is as easy as calling `alt.takeSnapshot()`.
Taking a snapshot is as easy as calling `alt.takeSnapshot()`. It can also take an optional number of arguments as strings which correspond to the store names you would like to include in the snapshot. This allows you to take a snapshot of a subset of your app's data.

### Bootstrapping

Expand Down
19 changes: 16 additions & 3 deletions dist/alt-browser-with-addons.js
Expand Up @@ -1258,7 +1258,12 @@ var setAppState = function (instance, data, onStore) {
};

var snapshot = function (instance) {
return JSON.stringify(Object.keys(instance.stores).reduce(function (obj, key) {
for (var _len = arguments.length, storeNames = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
storeNames[_key - 1] = arguments[_key];
}

var stores = storeNames.length ? storeNames : Object.keys(instance.stores);
return JSON.stringify(stores.reduce(function (obj, key) {
var store = instance.stores[key];
var customSnapshot = store[LIFECYCLE].serialize && store[LIFECYCLE].serialize();
obj[key] = customSnapshot ? customSnapshot : store.getState();
Expand Down Expand Up @@ -1509,8 +1514,16 @@ var Alt = (function () {
},
takeSnapshot: {
value: function takeSnapshot() {
var state = snapshot(this);
this[LAST_SNAPSHOT] = state;
for (var _len = arguments.length, storeNames = Array(_len), _key = 0; _key < _len; _key++) {
storeNames[_key] = arguments[_key];
}

var state = snapshot.apply(undefined, [this].concat(storeNames));
if (this[LAST_SNAPSHOT]) {
assign(this[LAST_SNAPSHOT], state);
} else {
this[LAST_SNAPSHOT] = state;
}
return state;
}
},
Expand Down
19 changes: 16 additions & 3 deletions dist/alt-browser.js
Expand Up @@ -1002,7 +1002,12 @@ var setAppState = function (instance, data, onStore) {
};

var snapshot = function (instance) {
return JSON.stringify(Object.keys(instance.stores).reduce(function (obj, key) {
for (var _len = arguments.length, storeNames = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
storeNames[_key - 1] = arguments[_key];
}

var stores = storeNames.length ? storeNames : Object.keys(instance.stores);
return JSON.stringify(stores.reduce(function (obj, key) {
var store = instance.stores[key];
var customSnapshot = store[LIFECYCLE].serialize && store[LIFECYCLE].serialize();
obj[key] = customSnapshot ? customSnapshot : store.getState();
Expand Down Expand Up @@ -1253,8 +1258,16 @@ var Alt = (function () {
},
takeSnapshot: {
value: function takeSnapshot() {
var state = snapshot(this);
this[LAST_SNAPSHOT] = state;
for (var _len = arguments.length, storeNames = Array(_len), _key = 0; _key < _len; _key++) {
storeNames[_key] = arguments[_key];
}

var state = snapshot.apply(undefined, [this].concat(storeNames));
if (this[LAST_SNAPSHOT]) {
assign(this[LAST_SNAPSHOT], state);
} else {
this[LAST_SNAPSHOT] = state;
}
return state;
}
},
Expand Down
19 changes: 16 additions & 3 deletions dist/alt-with-runtime.js
Expand Up @@ -257,7 +257,12 @@ var setAppState = function (instance, data, onStore) {
};

var snapshot = function (instance) {
return JSON.stringify(Object.keys(instance.stores).reduce(function (obj, key) {
for (var _len = arguments.length, storeNames = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
storeNames[_key - 1] = arguments[_key];
}

var stores = storeNames.length ? storeNames : Object.keys(instance.stores);
return JSON.stringify(stores.reduce(function (obj, key) {
var store = instance.stores[key];
var customSnapshot = store[LIFECYCLE].serialize && store[LIFECYCLE].serialize();
obj[key] = customSnapshot ? customSnapshot : store.getState();
Expand Down Expand Up @@ -503,8 +508,16 @@ var Alt = (function () {
},
takeSnapshot: {
value: function takeSnapshot() {
var state = snapshot(this);
this[LAST_SNAPSHOT] = state;
for (var _len = arguments.length, storeNames = Array(_len), _key = 0; _key < _len; _key++) {
storeNames[_key] = arguments[_key];
}

var state = snapshot.apply(undefined, [this].concat(storeNames));
if (this[LAST_SNAPSHOT]) {
assign(this[LAST_SNAPSHOT], state);
} else {
this[LAST_SNAPSHOT] = state;
}
return state;
}
},
Expand Down
19 changes: 16 additions & 3 deletions dist/alt.js
Expand Up @@ -271,7 +271,12 @@ var setAppState = function (instance, data, onStore) {
};

var snapshot = function (instance) {
return JSON.stringify(Object.keys(instance.stores).reduce(function (obj, key) {
for (var _len = arguments.length, storeNames = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
storeNames[_key - 1] = arguments[_key];
}

var stores = storeNames.length ? storeNames : Object.keys(instance.stores);
return JSON.stringify(stores.reduce(function (obj, key) {
var store = instance.stores[key];
var customSnapshot = store[LIFECYCLE].serialize && store[LIFECYCLE].serialize();
obj[key] = customSnapshot ? customSnapshot : store.getState();
Expand Down Expand Up @@ -520,8 +525,16 @@ var Alt = (function () {
},
takeSnapshot: {
value: function takeSnapshot() {
var state = snapshot(this);
this[LAST_SNAPSHOT] = state;
for (var _len = arguments.length, storeNames = Array(_len), _key = 0; _key < _len; _key++) {
storeNames[_key] = arguments[_key];
}

var state = snapshot.apply(undefined, [this].concat(storeNames));
if (this[LAST_SNAPSHOT]) {
assign(this[LAST_SNAPSHOT], state);
} else {
this[LAST_SNAPSHOT] = state;
}
return state;
}
},
Expand Down
7 changes: 4 additions & 3 deletions docs/takeSnapshot.md
Expand Up @@ -7,13 +7,14 @@ permalink: /docs/takeSnapshot/

# takeSnapshot

> (): string
> (...storeNames: ?string): string
Take snapshot provides you with the entire application's state serialized to JSON.
Take snapshot provides you with the entire application's state serialized to JSON, by default, but you may also pass in store names to take a snapshot of a subset of the application's state.

Snapshots are a core component of alt. The idea is that at any given point in time you can `takeSnapshot` and have your entire application's state
serialized for persistence, transfering, logging, or debugging.
serialized for persistence, transferring, logging, or debugging.

```js
var snapshot = alt.takeSnapshot();
var partialSnapshot = alt.takeSnapshot('Store1', 'Store3');
```
16 changes: 11 additions & 5 deletions src/alt.js
Expand Up @@ -239,9 +239,10 @@ const setAppState = (instance, data, onStore) => {
})
}

const snapshot = (instance) => {
const snapshot = (instance, ...storeNames) => {
const stores = storeNames.length ? storeNames : Object.keys(instance.stores)
return JSON.stringify(
Object.keys(instance.stores).reduce((obj, key) => {
stores.reduce((obj, key) => {
const store = instance.stores[key]
const customSnapshot = store[LIFECYCLE].serialize && store[LIFECYCLE].serialize()
obj[key] = customSnapshot ? customSnapshot : store.getState()
Expand Down Expand Up @@ -456,9 +457,14 @@ class Alt {
}, exportObj)
}

takeSnapshot() {
const state = snapshot(this)
this[LAST_SNAPSHOT] = state
takeSnapshot(...storeNames) {
const state = snapshot(this, ...storeNames)
if(this[LAST_SNAPSHOT]) {
assign(this[LAST_SNAPSHOT], state)
}
else {
this[LAST_SNAPSHOT] = state
}
return state
}

Expand Down
6 changes: 6 additions & 0 deletions test/index.js
Expand Up @@ -473,6 +473,12 @@ const tests = {
assert(JSON.parse(snapshot).MyStore.name === 'bear', 'the snapshot is not affected by action')
},

'specifying stores to snapshot'() {
const snapshot = alt.takeSnapshot('MyStore', 'AltSecondStore')
assert.deepEqual(Object.keys(JSON.parse(snapshot)), ['MyStore', 'AltSecondStore'], 'the snapshot includes specified stores')
assert.isFalse(Object.keys(JSON.parse(snapshot)).includes('LifeCycleStore'), 'the snapshot does not include unspecified stores')
},

'serializing/deserializing snapshot/bootstrap data'(){
myActions.updateAnotherVal(11)
const snapshot = alt.takeSnapshot()
Expand Down

0 comments on commit 98b3c04

Please sign in to comment.