Hot reload a component's constructor
I suppose that this could be implemented using the following clone function in the updatePrototype method. This was taken from here.
function clone(obj) {
var copy;
// Handle the 3 simple types, and null or undefined
if (null == obj || "object" != typeof obj) return obj;
// Handle Date
if (obj instanceof Date) {
copy = new Date();
copy.setTime(obj.getTime());
return copy;
}
// Handle Array
if (obj instanceof Array) {
copy = [];
for (var i = 0, len = obj.length; i < len; i++) {
copy[i] = clone(obj[i]);
}
return copy;
}
// Handle Object
if (obj instanceof Object) {
copy = {};
for (var attr in obj) {
if (obj.hasOwnProperty(attr)) copy[attr] = clone(obj[attr]);
}
return copy;
}
throw new Error("Unable to copy obj! Its type isn't supported.");
}
Yes, deep copy should work in this case. Once the component has been initialized we can extract the constructor from the new copy which was sent over WebSockets and patch the one which lives in the browser.
A working strategy for patching the component's constructor is:
- Keep the component's parents
- On change of the constructor do:
- Find all parents of the changed component
- Traverse their matadata:
- If the metadata is if type
RouteConfigthen patch the route associated to the changed component (i.e. update the component associated to the route)- Reset the
RouteRegistryassociated to this component
- Reset the
- If the metadata contains property
directives(i.e.ViewMetadata) then just patch the component inside of the array
- If the metadata is if type
Limitations:
RouteRegistrydoes not allow update of already existing routes. This means we need to touch private API.
Using your approach should also enable us to hot-reload only those components that have changed, keeping the overall state of the application. If we have a handle on the views containing the changed components it should be easy to destroy and reinstantiate them.