@glimmer/runtime
Version:
Minimal runtime needed to render Glimmer templates
214 lines (175 loc) • 16.7 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = exports.Ref = void 0;
var _env = require("@glimmer/env");
var _util = require("@glimmer/util");
var _arguments = require("./vm/arguments");
let GUID = 0;
class Ref {
constructor(value) {
this.id = GUID++;
this.value = value;
}
get() {
return this.value;
}
release() {
if (_env.DEBUG && this.value === null) {
throw new Error('BUG: double release?');
}
this.value = null;
}
toString() {
let label = `Ref ${this.id}`;
if (this.value === null) {
return `${label} (released)`;
} else {
try {
return `${label}: ${this.value}`;
} catch (_a) {
return label;
}
}
}
}
exports.Ref = Ref;
class DebugRenderTreeImpl {
constructor() {
this.stack = new _util.Stack();
this.refs = new WeakMap();
this.roots = new Set();
this.nodes = new WeakMap();
}
begin() {
this.reset();
}
create(state, node) {
let internalNode = (0, _util.assign)({}, node, {
bounds: null,
refs: new Set()
});
this.nodes.set(state, internalNode);
this.appendChild(internalNode, state);
this.enter(state);
}
update(state) {
this.enter(state);
}
didRender(state, bounds) {
if (_env.DEBUG && this.stack.current !== state) {
throw new Error(`BUG: expecting ${this.stack.current}, got ${state}`);
}
this.nodeFor(state).bounds = bounds;
this.exit();
}
willDestroy(state) {
this.refs.get(state).release();
}
commit() {
this.reset();
}
capture() {
return this.captureRefs(this.roots);
}
reset() {
if (this.stack.size !== 0) {
// We probably encountered an error during the rendering loop. This will
// likely trigger undefined behavior and memory leaks as the error left
// things in an inconsistent state. It is recommended that the user
// refresh the page.
// TODO: We could warn here? But this happens all the time in our tests?
// Clean up the root reference to prevent errors from happening if we
// attempt to capture the render tree (Ember Inspector may do this)
let root = this.stack.toArray()[0];
let ref = this.refs.get(root);
if (ref !== undefined) {
this.roots.delete(ref);
}
while (!this.stack.isEmpty()) {
this.stack.pop();
}
}
}
enter(state) {
this.stack.push(state);
}
exit() {
if (_env.DEBUG && this.stack.size === 0) {
throw new Error('BUG: unbalanced pop');
}
this.stack.pop();
}
nodeFor(state) {
return this.nodes.get(state);
}
appendChild(node, state) {
if (_env.DEBUG && this.refs.has(state)) {
throw new Error('BUG: child already appended');
}
let parent = this.stack.current;
let ref = new Ref(state);
this.refs.set(state, ref);
if (parent) {
let parentNode = this.nodeFor(parent);
parentNode.refs.add(ref);
node.parent = parentNode;
} else {
this.roots.add(ref);
}
}
captureRefs(refs) {
let captured = [];
refs.forEach(ref => {
let state = ref.get();
if (state) {
captured.push(this.captureNode(`render-node:${ref.id}`, state));
} else {
refs.delete(ref);
}
});
return captured;
}
captureNode(id, state) {
let node = this.nodeFor(state);
let {
type,
name,
args,
instance,
refs
} = node;
let template = this.captureTemplate(node);
let bounds = this.captureBounds(node);
let children = this.captureRefs(refs);
return {
id,
type,
name,
args: (0, _arguments.reifyArgs)(args),
instance,
template,
bounds,
children
};
}
captureTemplate({
template
}) {
return template || null;
}
captureBounds(node) {
let bounds = node.bounds;
let parentElement = bounds.parentElement();
let firstNode = bounds.firstNode();
let lastNode = bounds.lastNode();
return {
parentElement,
firstNode,
lastNode
};
}
}
exports.default = DebugRenderTreeImpl;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3BhY2thZ2VzL0BnbGltbWVyL3J1bnRpbWUvbGliL2RlYnVnLXJlbmRlci10cmVlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7QUFRQTs7QUFDQTs7QUFRQSxJQUFJLElBQUksR0FBUixDQUFBOztBQUVNLE1BQUEsR0FBQSxDQUFVO0FBSWQsRUFBQSxXQUFBLENBQUEsS0FBQSxFQUFvQjtBQUhYLFNBQUEsRUFBQSxHQUFhLElBQWIsRUFBQTtBQUlQLFNBQUEsS0FBQSxHQUFBLEtBQUE7QUFDRDs7QUFFRCxFQUFBLEdBQUcsR0FBQTtBQUNELFdBQU8sS0FBUCxLQUFBO0FBQ0Q7O0FBRUQsRUFBQSxPQUFPLEdBQUE7QUFDTCxRQUFJLGNBQVMsS0FBQSxLQUFBLEtBQWIsSUFBQSxFQUFrQztBQUNoQyxZQUFNLElBQUEsS0FBQSxDQUFOLHNCQUFNLENBQU47QUFDRDs7QUFFRCxTQUFBLEtBQUEsR0FBQSxJQUFBO0FBQ0Q7O0FBRUQsRUFBQSxRQUFRLEdBQUE7QUFDTixRQUFJLEtBQUssR0FBRyxPQUFPLEtBQUssRUFBeEIsRUFBQTs7QUFFQSxRQUFJLEtBQUEsS0FBQSxLQUFKLElBQUEsRUFBeUI7QUFDdkIsYUFBTyxHQUFHLEtBQVYsYUFBQTtBQURGLEtBQUEsTUFFTztBQUNMLFVBQUk7QUFDRixlQUFPLEdBQUcsS0FBSyxLQUFLLEtBQUssS0FBekIsRUFBQTtBQURGLE9BQUEsQ0FFRSxPQUFBLEVBQUEsRUFBTTtBQUNOLGVBQUEsS0FBQTtBQUNEO0FBQ0Y7QUFDRjs7QUFoQ2E7Ozs7QUFtQ0YsTUFBQSxtQkFBQSxDQUEwQjtBQUF4QyxFQUFBLFdBQUEsR0FBQTtBQUVVLFNBQUEsS0FBQSxHQUFRLElBQVIsV0FBUSxFQUFSO0FBRUEsU0FBQSxJQUFBLEdBQU8sSUFBUCxPQUFPLEVBQVA7QUFDQSxTQUFBLEtBQUEsR0FBUSxJQUFSLEdBQVEsRUFBUjtBQUNBLFNBQUEsS0FBQSxHQUFRLElBQVIsT0FBUSxFQUFS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QUUsMEJBQXhCLElBQXdCLENBQXhCO0FBQUEsTUFBQSxRQUFBO0FBQUEsTUFBQSxRQUFBO0FBQUEsTUFBQSxNQUFBO0FBQXFFLE1BQUE7QUFBckUsS0FBUDtBQUNEOztBQUVPLEVBQUEsZUFBZSxDQUFDO0FBQUUsSUFBQTtBQUFGLEdBQUQsRUFBMEM7QUFDL0QsV0FBTyxRQUFRLElBQWYsSUFBQTtBQUNEOztBQUVPLEVBQUEsYUFBYSxDQUFBLElBQUEsRUFBa0M7QUFDckQsUUFBSSxNQUFNLEdBQVUsSUFBSSxDQUF4QixNQUFBO0FBQ0EsUUFBSSxhQUFhLEdBQUcsTUFBTSxDQUExQixhQUFvQixFQUFwQjtBQUNBLFFBQUksU0FBUyxHQUFHLE1BQU0sQ0FBdEIsU0FBZ0IsRUFBaEI7QUFDQSxRQUFJLFFBQVEsR0FBRyxNQUFNLENBQXJCLFFBQWUsRUFBZjtBQUNBLFdBQU87QUFBQSxNQUFBLGFBQUE7QUFBQSxNQUFBLFNBQUE7QUFBNEIsTUFBQTtBQUE1QixLQUFQO0FBQ0Q7O0FBN0lxQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IERFQlVHIH0gZnJvbSAnQGdsaW1tZXIvZW52JztcbmltcG9ydCB7XG4gIEJvdW5kcyxcbiAgQ2FwdHVyZWRSZW5kZXJOb2RlLFxuICBEZWJ1Z1JlbmRlclRyZWUsXG4gIE9wdGlvbixcbiAgUmVuZGVyTm9kZSxcbn0gZnJvbSAnQGdsaW1tZXIvaW50ZXJmYWNlcyc7XG5pbXBvcnQgeyBleHBlY3QsIGFzc2lnbiwgU3RhY2sgfSBmcm9tICdAZ2xpbW1lci91dGlsJztcbmltcG9ydCB7IHJlaWZ5QXJncyB9IGZyb20gJy4vdm0vYXJndW1lbnRzJztcblxuaW50ZXJmYWNlIEludGVybmFsUmVuZGVyTm9kZTxUIGV4dGVuZHMgb2JqZWN0PiBleHRlbmRzIFJlbmRlck5vZGUge1xuICBib3VuZHM6IE9wdGlvbjxCb3VuZHM+O1xuICByZWZzOiBTZXQ8UmVmPFQ+PjtcbiAgcGFyZW50PzogSW50ZXJuYWxSZW5kZXJOb2RlPFQ+O1xufVxuXG5sZXQgR1VJRCA9IDA7XG5cbmV4cG9ydCBjbGFzcyBSZWY8VCBleHRlbmRzIG9iamVjdD4ge1xuICByZWFkb25seSBpZDogbnVtYmVyID0gR1VJRCsrO1xuICBwcml2YXRlIHZhbHVlOiBPcHRpb248VD47XG5cbiAgY29uc3RydWN0b3IodmFsdWU6IFQpIHtcbiAgICB0aGlzLnZhbHVlID0gdmFsdWU7XG4gIH1cblxuICBnZXQoKTogT3B0aW9uPFQ+IHtcbiAgICByZXR1cm4gdGhpcy52YWx1ZTtcbiAgfVxuXG4gIHJlbGVhc2UoKTogdm9pZCB7XG4gICAgaWYgKERFQlVHICYmIHRoaXMudmFsdWUgPT09IG51bGwpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignQlVHOiBkb3VibGUgcmVsZWFzZT8nKTtcbiAgICB9XG5cbiAgICB0aGlzLnZhbHVlID0gbnVsbDtcbiAgfVxuXG4gIHRvU3RyaW5nKCk6IFN0cmluZyB7XG4gICAgbGV0IGxhYmVsID0gYFJlZiAke3RoaXMuaWR9YDtcblxuICAgIGlmICh0aGlzLnZhbHVlID09PSBudWxsKSB7XG4gICAgICByZXR1cm4gYCR7bGFiZWx9IChyZWxlYXNlZClgO1xuICAgIH0gZWxzZSB7XG4gICAgICB0cnkge1xuICAgICAgICByZXR1cm4gYCR7bGFiZWx9OiAke3RoaXMudmFsdWV9YDtcbiAgICAgIH0gY2F0Y2gge1xuICAgICAgICByZXR1cm4gbGFiZWw7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIERlYnVnUmVuZGVyVHJlZUltcGw8VEJ1Y2tldCBleHRlbmRzIG9iamVjdD5cbiAgaW1wbGVtZW50cyBEZWJ1Z1JlbmRlclRyZWU8VEJ1Y2tldD4ge1xuICBwcml2YXRlIHN0YWNrID0gbmV3IFN0YWNrPFRCdWNrZXQ+KCk7XG5cbiAgcHJpdmF0ZSByZWZzID0gbmV3IFdlYWtNYXA8VEJ1Y2tldCwgUmVmPFRCdWNrZXQ+PigpO1xuICBwcml2YXRlIHJvb3RzID0gbmV3IFNldDxSZWY8VEJ1Y2tldD4+KCk7XG4gIHByaXZhdGUgbm9kZXMgPSBuZXcgV2Vha01hcDxUQnVja2V0LCBJbnRlcm5hbFJlbmRlck5vZGU8VEJ1Y2tldD4+KCk7XG5cbiAgYmVnaW4oKTogdm9pZCB7XG4gICAgdGhpcy5yZXNldCgpO1xuICB9XG5cbiAgY3JlYXRlKHN0YXRlOiBUQnVja2V0LCBub2RlOiBSZW5kZXJOb2RlKTogdm9pZCB7XG4gICAgbGV0IGludGVybmFsTm9kZTogSW50ZXJuYWxSZW5kZXJOb2RlPFRCdWNrZXQ+ID0gYXNzaWduKHt9LCBub2RlLCB7XG4gICAgICBib3VuZHM6IG51bGwsXG4gICAgICByZWZzOiBuZXcgU2V0PFJlZjxUQnVja2V0Pj4oKSxcbiAgICB9KTtcbiAgICB0aGlzLm5vZGVzLnNldChzdGF0ZSwgaW50ZXJuYWxOb2RlKTtcbiAgICB0aGlzLmFwcGVuZENoaWxkKGludGVybmFsTm9kZSwgc3RhdGUpO1xuICAgIHRoaXMuZW50ZXIoc3RhdGUpO1xuICB9XG5cbiAgdXBkYXRlKHN0YXRlOiBUQnVja2V0KTogdm9pZCB7XG4gICAgdGhpcy5lbnRlcihzdGF0ZSk7XG4gIH1cblxuICBkaWRSZW5kZXIoc3RhdGU6IFRCdWNrZXQsIGJvdW5kczogQm91bmRzKTogdm9pZCB7XG4gICAgaWYgKERFQlVHICYmIHRoaXMuc3RhY2suY3VycmVudCAhPT0gc3RhdGUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgQlVHOiBleHBlY3RpbmcgJHt0aGlzLnN0YWNrLmN1cnJlbnR9LCBnb3QgJHtzdGF0ZX1gKTtcbiAgICB9XG5cbiAgICB0aGlzLm5vZGVGb3Ioc3RhdGUpLmJvdW5kcyA9IGJvdW5kcztcbiAgICB0aGlzLmV4aXQoKTtcbiAgfVxuXG4gIHdpbGxEZXN0cm95KHN0YXRlOiBUQnVja2V0KTogdm9pZCB7XG4gICAgZXhwZWN0KHRoaXMucmVmcy5nZXQoc3RhdGUpLCAnQlVHOiBtaXNzaW5nIHJlZicpLnJlbGVhc2UoKTtcbiAgfVxuXG4gIGNvbW1pdCgpOiB2b2lkIHtcbiAgICB0aGlzLnJlc2V0KCk7XG4gIH1cblxuICBjYXB0dXJlKCk6IENhcHR1cmVkUmVuZGVyTm9kZVtdIHtcbiAgICByZXR1cm4gdGhpcy5jYXB0dXJlUmVmcyh0aGlzLnJvb3RzKTtcbiAgfVxuXG4gIHByaXZhdGUgcmVzZXQoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuc3RhY2suc2l6ZSAhPT0gMCkge1xuICAgICAgLy8gV2UgcHJvYmFibHkgZW5jb3VudGVyZWQgYW4gZXJyb3IgZHVyaW5nIHRoZSByZW5kZXJpbmcgbG9vcC4gVGhpcyB3aWxsXG4gICAgICAvLyBsaWtlbHkgdHJpZ2dlciB1bmRlZmluZWQgYmVoYXZpb3IgYW5kIG1lbW9yeSBsZWFrcyBhcyB0aGUgZXJyb3IgbGVmdFxuICAgICAgLy8gdGhpbmdzIGluIGFuIGluY29uc2lzdGVudCBzdGF0ZS4gSXQgaXMgcmVjb21tZW5kZWQgdGhhdCB0aGUgdXNlclxuICAgICAgLy8gcmVmcmVzaCB0aGUgcGFnZS5cblxuICAgICAgLy8gVE9ETzogV2UgY291bGQgd2FybiBoZXJlPyBCdXQgdGhpcyBoYXBwZW5zIGFsbCB0aGUgdGltZSBpbiBvdXIgdGVzdHM/XG5cbiAgICAgIC8vIENsZWFuIHVwIHRoZSByb290IHJlZmVyZW5jZSB0byBwcmV2ZW50IGVycm9ycyBmcm9tIGhhcHBlbmluZyBpZiB3ZVxuICAgICAgLy8gYXR0ZW1wdCB0byBjYXB0dXJlIHRoZSByZW5kZXIgdHJlZSAoRW1iZXIgSW5zcGVjdG9yIG1heSBkbyB0aGlzKVxuICAgICAgbGV0IHJvb3QgPSBleHBlY3QodGhpcy5zdGFjay50b0FycmF5KClbMF0sICdleHBlY3RlZCByb290IHN0YXRlIHdoZW4gcmVzZXR0aW5nIHJlbmRlciB0cmVlJyk7XG4gICAgICBsZXQgcmVmID0gdGhpcy5yZWZzLmdldChyb290KTtcblxuICAgICAgaWYgKHJlZiAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHRoaXMucm9vdHMuZGVsZXRlKHJlZik7XG4gICAgICB9XG5cbiAgICAgIHdoaWxlICghdGhpcy5zdGFjay5pc0VtcHR5KCkpIHtcbiAgICAgICAgdGhpcy5zdGFjay5wb3AoKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGVudGVyKHN0YXRlOiBUQnVja2V0KTogdm9pZCB7XG4gICAgdGhpcy5zdGFjay5wdXNoKHN0YXRlKTtcbiAgfVxuXG4gIHByaXZhdGUgZXhpdCgpOiB2b2lkIHtcbiAgICBpZiAoREVCVUcgJiYgdGhpcy5zdGFjay5zaXplID09PSAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0JVRzogdW5iYWxhbmNlZCBwb3AnKTtcbiAgICB9XG5cbiAgICB0aGlzLnN0YWNrLnBvcCgpO1xuICB9XG5cbiAgcHJpdmF0ZSBub2RlRm9yKHN0YXRlOiBUQnVja2V0KTogSW50ZXJuYWxSZW5kZXJOb2RlPFRCdWNrZXQ+IHtcbiAgICByZXR1cm4gZXhwZWN0KHRoaXMubm9kZXMuZ2V0KHN0YXRlKSwgJ0JVRzogbWlzc2luZyBub2RlJyk7XG4gIH1cblxuICBwcml2YXRlIGFwcGVuZENoaWxkKG5vZGU6IEludGVybmFsUmVuZGVyTm9kZTxUQnVja2V0Piwgc3RhdGU6IFRCdWNrZXQpOiB2b2lkIHtcbiAgICBpZiAoREVCVUcgJiYgdGhpcy5yZWZzLmhhcyhzdGF0ZSkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignQlVHOiBjaGlsZCBhbHJlYWR5IGFwcGVuZGVkJyk7XG4gICAgfVxuXG4gICAgbGV0IHBhcmVudCA9IHRoaXMuc3RhY2suY3VycmVudDtcbiAgICBsZXQgcmVmID0gbmV3IFJlZihzdGF0ZSk7XG5cbiAgICB0aGlzLnJlZnMuc2V0KHN0YXRlLCByZWYpO1xuXG4gICAgaWYgKHBhcmVudCkge1xuICAgICAgbGV0IHBhcmVudE5vZGUgPSB0aGlzLm5vZGVGb3IocGFyZW50KTtcbiAgICAgIHBhcmVudE5vZGUucmVmcy5hZGQocmVmKTtcbiAgICAgIG5vZGUucGFyZW50ID0gcGFyZW50Tm9kZTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5yb290cy5hZGQocmVmKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGNhcHR1cmVSZWZzKHJlZnM6IFNldDxSZWY8VEJ1Y2tldD4+KTogQ2FwdHVyZWRSZW5kZXJOb2RlW10ge1xuICAgIGxldCBjYXB0dXJlZDogQ2FwdHVyZWRSZW5kZXJOb2RlW10gPSBbXTtcblxuICAgIHJlZnMuZm9yRWFjaCgocmVmKSA9PiB7XG4gICAgICBsZXQgc3RhdGUgPSByZWYuZ2V0KCk7XG5cbiAgICAgIGlmIChzdGF0ZSkge1xuICAgICAgICBjYXB0dXJlZC5wdXNoKHRoaXMuY2FwdHVyZU5vZGUoYHJlbmRlci1ub2RlOiR7cmVmLmlkfWAsIHN0YXRlKSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZWZzLmRlbGV0ZShyZWYpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgcmV0dXJuIGNhcHR1cmVkO1xuICB9XG5cbiAgcHJpdmF0ZSBjYXB0dXJlTm9kZShpZDogc3RyaW5nLCBzdGF0ZTogVEJ1Y2tldCk6IENhcHR1cmVkUmVuZGVyTm9kZSB7XG4gICAgbGV0IG5vZGUgPSB0aGlzLm5vZGVGb3Ioc3RhdGUpO1xuICAgIGxldCB7IHR5cGUsIG5hbWUsIGFyZ3MsIGluc3RhbmNlLCByZWZzIH0gPSBub2RlO1xuICAgIGxldCB0ZW1wbGF0ZSA9IHRoaXMuY2FwdHVyZVRlbXBsYXRlKG5vZGUpO1xuICAgIGxldCBib3VuZHMgPSB0aGlzLmNhcHR1cmVCb3VuZHMobm9kZSk7XG4gICAgbGV0IGNoaWxkcmVuID0gdGhpcy5jYXB0dXJlUmVmcyhyZWZzKTtcbiAgICByZXR1cm4geyBpZCwgdHlwZSwgbmFtZSwgYXJnczogcmVpZnlBcmdzKGFyZ3MpLCBpbnN0YW5jZSwgdGVtcGxhdGUsIGJvdW5kcywgY2hpbGRyZW4gfTtcbiAgfVxuXG4gIHByaXZhdGUgY2FwdHVyZVRlbXBsYXRlKHsgdGVtcGxhdGUgfTogSW50ZXJuYWxSZW5kZXJOb2RlPFRCdWNrZXQ+KTogT3B0aW9uPHN0cmluZz4ge1xuICAgIHJldHVybiB0ZW1wbGF0ZSB8fCBudWxsO1xuICB9XG5cbiAgcHJpdmF0ZSBjYXB0dXJlQm91bmRzKG5vZGU6IEludGVybmFsUmVuZGVyTm9kZTxUQnVja2V0Pik6IENhcHR1cmVkUmVuZGVyTm9kZVsnYm91bmRzJ10ge1xuICAgIGxldCBib3VuZHMgPSBleHBlY3Qobm9kZS5ib3VuZHMsICdCVUc6IG1pc3NpbmcgYm91bmRzJyk7XG4gICAgbGV0IHBhcmVudEVsZW1lbnQgPSBib3VuZHMucGFyZW50RWxlbWVudCgpO1xuICAgIGxldCBmaXJzdE5vZGUgPSBib3VuZHMuZmlyc3ROb2RlKCk7XG4gICAgbGV0IGxhc3ROb2RlID0gYm91bmRzLmxhc3ROb2RlKCk7XG4gICAgcmV0dXJuIHsgcGFyZW50RWxlbWVudCwgZmlyc3ROb2RlLCBsYXN0Tm9kZSB9O1xuICB9XG59XG4iXSwic291cmNlUm9vdCI6IiJ9