Skip to content

Commit

Permalink
feat: add new HMR runtime
Browse files Browse the repository at this point in the history
  • Loading branch information
DylanPiercey committed Apr 30, 2021
1 parent 94caebb commit a873762
Show file tree
Hide file tree
Showing 394 changed files with 1,535 additions and 1,309 deletions.
1 change: 1 addition & 0 deletions packages/compiler/index.d.ts
Expand Up @@ -29,6 +29,7 @@ export type Config = {
hydrateIncludeImports?: RegExp | ((request: string) => boolean);
optimize?: boolean;
cache?: Map<unknown, unknown>;
hot?: boolean;
babelConfig?: {
ast?: boolean | null;
code?: boolean | null;
Expand Down
7 changes: 6 additions & 1 deletion packages/compiler/src/config.js
Expand Up @@ -137,7 +137,12 @@ if (globalThis[MARKO_CONFIG_KEY]) {
/**
* A regexp or function that receives an import path that matches file types known to be client side assets.
*/
hydrateIncludeImports: /\.(css|less|s[ac]ss|styl|png|jpe?g|gif|svg|ico|webp|avif|mp4|webm|ogg|mp3|wav|flac|aac|woff2?|eot|ttf|otf)$/
hydrateIncludeImports: /\.(css|less|s[ac]ss|styl|png|jpe?g|gif|svg|ico|webp|avif|mp4|webm|ogg|mp3|wav|flac|aac|woff2?|eot|ttf|otf)$/,

/**
* Set to true in order to bring in the hot module replacement runtime.
*/
hot: false
};

if (process.env.MARKO_CONFIG) {
Expand Down
Expand Up @@ -139,6 +139,7 @@ function createComponent(typeName, id) {
}

exports.r = register;
exports.___getComponentClass = getComponentClass;
exports.___createComponent = createComponent;
exports.___isRegistered = isRegistered;
exports.___addPendingDef = addPendingDef;
22 changes: 0 additions & 22 deletions packages/marko/src/runtime/html/Template.js

This file was deleted.

28 changes: 28 additions & 0 deletions packages/marko/src/runtime/html/hot-reload.js
@@ -0,0 +1,28 @@
var runtime = require(".");
var createTemplate = runtime.t;
var registered = {};

runtime.t = function (typeName) {
if (registered[typeName]) {
return registered[typeName];
}

var renderFn;
var template = (registered[typeName] = createTemplate(typeName));
Object.defineProperty(template, "_", {
get: function () {
return renderFn && proxyRenderFn;
},
set: function (v) {
renderFn = v;
}
});

return template;

function proxyRenderFn() {
return renderFn.apply(this, arguments);
}
};

module.exports = runtime;
32 changes: 17 additions & 15 deletions packages/marko/src/runtime/html/index.js
Expand Up @@ -6,24 +6,26 @@
* it is used to create a new Template instance.
* @private
*/
exports.t = function createTemplate(path) {
return new Template(path);
exports.t = function createTemplate(typeName) {
return new Template(typeName);
};

var AsyncStream = require("./AsyncStream");
var Template = require("./Template");

function createOut(globalData, parent, state, buffer) {
return new AsyncStream(globalData, parent, state, buffer);
function Template(typeName) {
this.___typeName = typeName;
}

exports.createWriter = function (writer) {
return new AsyncStream(null, writer);
};
Template.prototype.stream = require("./create-readable");

exports.Template = Template;
exports.___createOut = createOut;
exports.AsyncStream = AsyncStream;
exports.enableAsyncStackTrace = AsyncStream.enableAsyncStackTrace;
var AsyncStream = require("./AsyncStream");
require("../createOut").___setCreateOut(
(Template.prototype.createOut = function createOut(
globalData,
writer,
parentOut,
buffer
) {
return new AsyncStream(globalData, writer, parentOut, buffer);
})
);

require("../createOut").___setCreateOut(createOut);
require("../renderable")(Template.prototype);
117 changes: 117 additions & 0 deletions packages/marko/src/runtime/vdom/hot-reload.js
@@ -0,0 +1,117 @@
var runtime = require(".");
var queueMicrotask = require("../queueMicrotask");
var util = require("../components/util");
var registry = require("../components/registry");
var updateManager = require("../components/update-manager");

var createTemplate = runtime.t;
var createComponent = registry.___createComponent;
var registered = {};
var queue;

runtime.t = function (typeName) {
if (registered[typeName]) {
return registered[typeName];
}

var renderFn;
var template = (registered[typeName] = createTemplate(typeName));
var instances = (template.___instances = []);
Object.defineProperty(template, "_", {
get: function () {
return renderFn && proxyRenderer;
},
set: function (v) {
renderFn = v;

if (instances.length) {
if (!queue) {
queue = [];
queueMicrotask(batchUpdate);
}

queue.push(function () {
var newProto = registry.___getComponentClass(typeName).prototype;
instances.forEach(function (instance) {
if (hasLifecycleChanged(instance.__proto__, newProto)) {
var startNode = instance.___rootNode.startNode;
var endNode = instance.___rootNode.endNode;
var parentNode = startNode.parentNode;
var curNode;

instance.___hmrDestroyed = true;
instance.___emitDestroy();
instance.___removeDOMEventListeners();

if (instance.___subscriptions) {
instance.___subscriptions.removeAllListeners();
instance.___subscriptions = null;
}

while ((curNode = startNode.nextSibling) !== endNode) {
util.___destroyNodeRecursive(curNode);
parentNode.removeChild(curNode);
}

instance.___hmrDestroyed = false;
instance.___mounted = false;
}

instance.__proto__ = newProto;
instance
.___rerender(instance.___input, false)
.afterInsert(instance.___document);
});
});
}
}
});

return template;

function proxyRenderer() {
return renderFn.apply(this, arguments);
}
};

registry.___createComponent = function (typeName, id) {
var instances = registered[typeName].___instances;
var instance = createComponent(typeName, id);
instances.push(instance);
instance.once("destroy", function () {
if (!instance.___hmrDestroyed) {
instances.splice(1, instances.indexOf(instance));
}
});

return instance;
};

function hasLifecycleChanged(oldProto, newProto) {
return (
hasMethodChanged("onCreate") ||
hasMethodChanged("onInput") ||
hasMethodChanged("onRender") ||
hasMethodChanged("onMount")
);

function hasMethodChanged(method) {
return (
(oldProto[method] && oldProto[method].toString()) !==
(newProto[method] && newProto[method].toString())
);
}
}

function batchUpdate() {
updateManager.___batchUpdate(function () {
var pending = queue;
queue = undefined;

for (var i = 0; i < pending.length; i++) {
pending[i]();
}
});
}

module.exports = runtime;
41 changes: 16 additions & 25 deletions packages/marko/src/runtime/vdom/index.js
@@ -1,37 +1,28 @@
"use strict";

// helpers provide a core set of various utility methods
// that are available in every template
var AsyncVDOMBuilder = require("./AsyncVDOMBuilder");
var makeRenderable = require("../renderable");

/**
* Method is for internal usage only. This method
* is invoked by code in a compiled Marko template and
* it is used to create a new Template instance.
* @private
*/
exports.t = function createTemplate(path) {
return new Template(path);
exports.t = function createTemplate(typeName) {
return new Template(typeName);
};

function Template(path, func) {
this.path = path;
this._ = func;
this.meta = undefined;
}

function createOut(globalData, parent, parentOut) {
return new AsyncVDOMBuilder(globalData, parent, parentOut);
function Template(typeName) {
this.___typeName = typeName;
}

var Template_prototype = (Template.prototype = {
createOut: createOut
});

makeRenderable(Template_prototype);

exports.Template = Template;
exports.___createOut = createOut;

require("../createOut").___setCreateOut(createOut);
var AsyncVDOMBuilder = require("./AsyncVDOMBuilder");
require("../createOut").___setCreateOut(
(Template.prototype.createOut = function createOut(
globalData,
parent,
parentOut
) {
return new AsyncVDOMBuilder(globalData, parent, parentOut);
})
);

require("../renderable")(Template.prototype);

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

0 comments on commit a873762

Please sign in to comment.