
Research
Two Malicious Rust Crates Impersonate Popular Logger to Steal Wallet Keys
Socket uncovers malicious Rust crates impersonating fast_log to steal Solana and Ethereum wallet keys from source code.
ember-state-manager
Advanced tools
An Ember.JS state management solution that is built upon the ideals of ember-state-services.
State management is one of the most complex aspects of large application design and when done wrong often leads to bugs and errors. EmberJS contains 2 high-level avenues for storing state: controllers (long-term state) and components (short-term state). Controllers are singletons and any state you set on them will stay there until your application is reloaded or you override the previous value. Components on the other hand are created and destroyed as they enter/leave the DOM and any state that is set on them will be removed/reset each time they are recreated. As you build more complex applications you will find yourself needing a way to have some sort of middle ground solution. Something that has properties of both long-term state and short-term state.
ember install ember-state-manager
If it is a bug please open an issue on GitHub.
The first thing you will need to do is create your state file(s). All states are expected
to be under app/states
and must export an Ember (like) Object. This addon ships with
a blueprint to make this pretty easy.
ember generate state <name> <options...>
Create a new state
--type (object, array, buffered-object, buffered-array)
# Create a state named 'foo' that is an Object
ember generate state foo
ember generate state foo --type=object
# Create a state named 'foo' that is an Array
ember generate state foo --type=array
# Create a state named 'foo' that is a Buffered Object Proxy (requires ember-buffered-proxy to be installed)
ember generate state foo --type=buffered-object
# Create a state named 'foo' that is a Buffered Array Proxy (requires ember-buffered-array-proxy to be installed)
ember generate state foo --type=buffered-array
Once you run the generate command, you will see a new file has been created:
// app/states/foo.js
import EmberObject from '@ember/object';
const State = EmberObject.extend();
State.reopenClass({
initialState(/* model */) {
return {};
}
});
export default State;
You can access a state via the provided service, template helper, or computed macro.
stateManager
ServiceThis service gives you full control on accessing and deleting states.
stateFor
Returns a state object for the given model with the specified state (file) name.
function stateFor(model: Object, stateName: String, options: Object);
Available Options:
bucketName: String
: The bucket name to store the state under (optional)createWithoutModel: Boolean
: Whether to return a valid
state object even if the model is falsy (defaulted to false).// Example Usage
this.get('stateManager').stateFor(model, '<STATE_NAME>', { bucketName: '<BUCKET_NAME>', createWithoutModel: true });
deleteStateFor
Delete the state object for the given model with the specified state (file) name.
Calling stateFor
after this method will return a new state object.
function deleteStateFor(model: Object, stateName: String, options: Object);
Available Options:
bucketName<String>
: The bucket name to store the state under (optional)// Example Usage
this.get('stateManager').stateFor(model, '<STATE_NAME>', { bucketName: '<BUCKET_NAME>' }); // old state
this.get('stateManager').deleteStateFor(model, '<STATE_NAME>', { bucketName: '<BUCKET_NAME>' });
this.get('stateManager').stateFor(model, '<STATE_NAME>', { bucketName: '<BUCKET_NAME>' }); // new state
{{state-for}}
Template HelperYou can access a state in your templates via the {{state-for}}
helper which is a
proxy to stateManager.stateFor
.
{{state-for model stateName bucketName=bucketName createWithoutModel=createWithoutModel}}
{{-- Example --}}
{{#with (state-for model '<STATE_NAME>' bucketName='<BUCKET_NAME>') as |state|}}
{{#if state.isEditing}}
Editing...
{{/if}}
{{/with}}
stateFor
Computed MacroThis addon provides a simple computed property macro which is a proxy to
stateManager.stateFor
.
Note: This macro requires container/owner access.
import Component from '@ember/component';
import { stateFor } from 'ember-state-manager';
export default Component.extend({
model: null,
/*
* `stateFor` returns a computed property that provides a given
* state object based on the 'model' property. Whenever model
* changes a new state object will be returned.
*/
state: stateFor('model', '<STATE_NAME>', { bucketName: '<BUCKET_NAME>', createWithoutModel: true })
})
In your state file, you can use the initialState
to setup your state object with
initial values.
// app/states/foo.js
import EmberObject from '@ember/object';
const State = EmberObject.extend();
State.reopenClass({
initialState(/* model */) {
return {
text: '',
isEditing: false
};
}
});
export default State;
State bucketing can be super handy if you want to create multiple states for the same model / stateName combo. Lets say we create a default buffered object state:
// app/states/buffered-object.js
import BufferedObjectProxy from 'ember-buffered-proxy/proxy';
const State = BufferedObjectProxy.extend();
State.reopenClass({
initialState(model) {
// Our state now becomes a buffer of the model!
return { content: model };
}
});
export default State;
We can create multiple long lived buffers for the same model.
const bufferA = stateManager.stateFor(model, 'buffered-object', { bucketName: 'A' });
const bufferB = stateManager.stateFor(model, 'buffered-object', { bucketName: 'B' });
We can make changes to either buffers, display them to the user, and let them select which one they like. Once selected, we can apply the changes and save the model.
We can easily create a validation backed buffered object so we can validate changes before we apply them.
// app/states/validated-buffered-object.js
import BufferedObjectProxy from 'ember-buffered-proxy/proxy';
import { buildValidations, validator } from 'ember-cp-validations';
const Validations = buildValidations({ /* ... */ });
const State = BufferedObjectProxy.extend(Validations);
State.reopenClass({
initialState(model) {
// Our state now becomes a buffer of the model!
return { content: model };
}
});
export default State;
const buffer = stateManager.stateFor(model, 'validated-buffered-object');
await buffer.validate();
if (buffer.get('validations.isValid')) {
buffer.applyChanges();
buffer.get('content').save();
}
FAQs
An Ember state management solution
We found that ember-state-manager demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Socket uncovers malicious Rust crates impersonating fast_log to steal Solana and Ethereum wallet keys from source code.
Research
A malicious package uses a QR code as steganography in an innovative technique.
Research
/Security News
Socket identified 80 fake candidates targeting engineering roles, including suspected North Korean operators, exposing the new reality of hiring as a security function.