rename .config to .values and _emitter to _config

This commit is contained in:
Jeff McAffer 2016-12-29 14:10:36 -08:00
Родитель ad49597fd6
Коммит 2c78b71d54
4 изменённых файлов: 79 добавлений и 31 удалений

48
.vscode/launch.json поставляемый Normal file
Просмотреть файл

@ -0,0 +1,48 @@
{
// Use IntelliSense to learn about possible Node.js debug attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Mocha",
"type": "node",
"request": "launch",
"program": "${workspaceRoot}/node_modules/mocha/bin/_mocha",
"stopOnEntry": false,
"args": [
"${workspaceRoot}/test/*.js"
],
"cwd": "${workspaceRoot}",
"runtimeExecutable": null,
"runtimeArgs": [
"--nolazy"
],
"env": {
"NODE_ENV": "localhost"
},
"console": "internalConsole"
},
{
"name": "Coverage",
"type": "node",
"request": "launch",
"program": "${workspaceRoot}/node_modules/istanbul/lib/cli.js",
"stopOnEntry": false,
"args": [
"cover",
"${workspaceRoot}/node_modules/mocha/bin/_mocha",
"${workspaceRoot}/test/*.js"
],
"cwd": "${workspaceRoot}",
"runtimeExecutable": null,
"runtimeArgs": [
"--nolazy"
],
"env": {
"NODE_ENV": "localhost"
},
"console": "internalConsole"
}
]
}

Просмотреть файл

@ -35,10 +35,9 @@ the changes that were detected.
* ```refresh(config)```: Emitted whenever the configuration is refreshed from the store where ```config```
is the configuration after the refresh.
The object returned from ```getAll()``` also has an event emitter in the ```_emitter``` property. This
event emitter will emit the same ```changed(config, patch)``` event as ```RefreshingConfig```. This can
be useful if you want to pass the configuration object around you application and allow different parts
of your application to subscribe to updates to the configuration.
The object returned from ```getAll()``` also has the ```RefreshingConfig``` instance itself in the ```_config``` property. This is
useful if you want to pass the configuration object around your application and allowing it to subscribe to updates or otherwise
manage the configuration.
# Extensions
You can extend refreshing-config's behavior by attaching extensions using ```withExtension```:
@ -50,7 +49,7 @@ const config = new RefreshingConfig.RefreshingConfig(store)
```
## Refresh policies
Refresh policies define when refreshing-config should go back to the store to get updated configuration values. Refresh policies can either be reactive (refreshing-config asks them if it should go back to the store)
Refresh policies define when refreshing-config should go back to the store to get updated configuration values. Refresh policies can either be reactive (refreshing-config asks them if it should go back to the store)
or proactive (they notify refreshing-config that it needs to refresh). If there are multiple refresh policies attached then refreshing-config will go back to the store if **any** of them say a refresh is required.
Refresh policies are bypassed in the following scenarios:
@ -113,6 +112,6 @@ be ```set``` or ```delete```, the ```name``` will be the name of the configurati
# Contributing
Pull requests will gladly be considered!
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see
the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com)
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see
the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com)
with any additional questions or comments.

Просмотреть файл

@ -25,8 +25,8 @@ class RefreshingConfig extends EventEmitter {
this.store = store;
this.refreshPolicies = [];
this.changePublishers = [];
this.config = {};
this.config._emitter = this;
this.values = {};
this.values._config = this;
this.firstTime = true;
}
@ -35,13 +35,13 @@ class RefreshingConfig extends EventEmitter {
throw new Error('Missing name');
}
return this.refreshIfNeeded().then(() => {
return this.config[name];
return this.values[name];
});
}
getAll() {
return this.refreshIfNeeded().then(() => {
return this.config;
return this.values;
});
}
@ -82,14 +82,14 @@ class RefreshingConfig extends EventEmitter {
apply(patches) {
// Snapshot the properties/name and apply the patches. If a changed property is still present,
// it was changed so set. If it is now missing, delete it.
const newConfig = Object.assign({}, this.config);
patch.apply(newConfig, patches);
const newValues = Object.assign({}, this.values);
patch.apply(newValues, patches);
const affected = this._getAffectedProperties(patches);
return Q.all(affected.map(key => {
if (newConfig[key] === undefined) {
if (newValues[key] === undefined) {
return this.delete(key);
} else {
return this.set(key, newConfig[key]);
return this.set(key, newValues[key]);
}
}));
}
@ -123,20 +123,20 @@ class RefreshingConfig extends EventEmitter {
}
const self = this;
this.refreshPromise = this.store.getAll()
.then(newConfig => {
.then(newValues => {
self.refreshPromise = null;
const configPatch = patch.compare(self.config, newConfig);
const emitterPatchIndex = configPatch.findIndex(patch => patch.path === '/_emitter');
const configPatch = patch.compare(self.values, newValues);
const emitterPatchIndex = configPatch.findIndex(patch => patch.path === '/_config');
/* istanbul ignore else */
if (emitterPatchIndex >= 0) {
configPatch.splice(emitterPatchIndex, 1);
}
if (configPatch.length !== 0) {
patch.apply(self.config, configPatch);
self.emit('changed', self.config, configPatch);
patch.apply(self.values, configPatch);
self.emit('changed', self.values, configPatch);
}
self.emit('refresh', self.config);
return self.config;
self.emit('refresh', self.values);
return self.values;
});
return this.refreshPromise;
}
@ -156,7 +156,7 @@ class RefreshingConfig extends EventEmitter {
if (shouldRefresh) {
return this.refresh();
}
return Q(this.config);
return Q(this.values);
}
}

Просмотреть файл

@ -82,8 +82,8 @@ describe('RefreshingConfig', () => {
};
const target = new config.RefreshingConfig(store);
return target.getAll().then(value => {
value._emitter.should.be.instanceof(events.EventEmitter);
delete value._emitter;
value._config.should.be.instanceof(events.EventEmitter);
delete value._config;
value.should.deep.equal(values);
});
});
@ -108,7 +108,8 @@ describe('RefreshingConfig', () => {
const target = new config.RefreshingConfig(store)
.withExtension(yesRefreshPolicy)
.withExtension(noRefreshPolicy);
return Q.all([target.get('foo'), target.get('bar')])
// chain the gets here as concurrent gets will get coalesced
return target.get('foo').then(() => target.get('bar'))
.then(() => {
store.getAll.calledTwice.should.be.true;
yesRefreshPolicy.shouldRefresh.should.be.calledOnce;
@ -165,7 +166,7 @@ describe('RefreshingConfig', () => {
target.on('changed', (newValues, diff) => {
invokeCount += 1;
newValues = clone(newValues);
delete newValues._emitter;
delete newValues._config;
if (invokeCount === 1) {
newValues.should.deep.equal(firstResponse);
diff.length.should.equal(1);
@ -178,21 +179,21 @@ describe('RefreshingConfig', () => {
});
const getAllPromise = target.getAll()
.then(values => {
values._emitter.on('changed', (newValues, diff) => {
values._config.on('changed', (newValues, diff) => {
newValues = clone(newValues);
delete newValues._emitter;
delete newValues._config;
newValues.should.deep.equal(secondResponse);
diff.length.should.equal(2);
valuesEmitDeferand.resolve();
});
values = clone(values);
delete values._emitter;
delete values._config;
values.should.deep.equal(firstResponse);
})
.then(target.getAll.bind(target))
.then(values => {
values = clone(values);
delete values._emitter;
delete values._config;
values.should.deep.equal(secondResponse);
});