Skip to content

Instantly share code, notes, and snippets.

@far-blue
Created June 30, 2017 10:20
Show Gist options
  • Save far-blue/05c679b4e4cb5fe1df1d36006e8a21fa to your computer and use it in GitHub Desktop.
Save far-blue/05c679b4e4cb5fe1df1d36006e8a21fa to your computer and use it in GitHub Desktop.
Example extension of Type-R (or even MixtureJS) to support a minimal TC39 compatible Observable interface.
<html>
<head>
<title></title>
</head>
<body>
<script src="most.js"></script>
<script src="type-r.js"></script>
<script>
// Support environments without Symbol support.
// ---------
// return an existing named symbol, a new named symbol or the compat '@@observable' string.
Nested.symbolCompat = function() {
return (typeof Symbol === 'function' ? (Symbol.observable ? Symbol.observable : Symbol('observable')) : '@@observable');
};
// Requirements for being Observable
// --------
// Named symbol for observable. Holds a function that returns a subscription object.
Nested.Record.prototype[Nested.symbolCompat()] = function() {
return { subscribe: this.subscription.bind(this) };
};
// Create a subscription and return a function that can dispose of the subscription
Nested.Record.prototype.subscription = function (thingObserving) {
let f = (eventName, ...rest) => thingObserving.next([eventName, ...rest]);
this.on('all', f);
return function() { this.off('all', f); };
};
// Requirements for being an Observer
// --------
// To be an Observer, a next() function is required.
Nested.Record.prototype.next = function (newValues) { this.set(newValues); };
// Example usage:
// Create 2 user instances, Observe the first, filter the
// stream for only 'change' events and then only the changed properties.
// Set the second user to Observe the stream of property changes.
// console log in various places to show the workings.
// --------
var ExampleUser = Nested.Record.extend({
attributes: {
username: ''
}
});
let user1 = new ExampleUser();
let user2 = new ExampleUser();
let user1Observable = most.from(user1);
let user2Observable = most.from(user2);
// Log all events in the stream from user1
user1Observable.observe((value) => console.log('user1', value));
// create a stream of only 'change' events
let filteredUser1 = user1Observable
.filter( (e) => e[0] === 'change' );
// log the stream of 'change' events
filteredUser1.observe((value) => console.log('filtered user1', value));
// Create a stream containing only the key/value pairs and then
// map those pairs to append 'Yeah!' to each value.
let mappedUser1 = filteredUser1
.map( (e) => e[1].changedAttributes() )
.map(function (e) {
let result = Object.assign({}, e);
for (let prop in result) {
result[prop] += 'Yeah!';
}
return result;
});
// log the stream of remapped key/value pairs
mappedUser1.observe((value) => console.log('mapped user1', value));
// Subscribe to the change stream with user2
// so user2's properties are updated
mappedUser1.subscribe(user2);
// Actually change the username property on user1 to see the
// chains of streams in action
user1.username = 'greenback';
user1.username = 'penfold';
// Show the resulting content of the 2 records.
console.log(user1, user2);
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment