Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@endorphinjs/template-runtime

Package Overview
Dependencies
Maintainers
1
Versions
85
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@endorphinjs/template-runtime - npm Package Compare versions

Comparing version 0.1.12 to 0.1.13

dist/runtime.es copy.js

765

dist/runtime.cjs.js

@@ -6,2 +6,113 @@ 'use strict';

/**
* Creates linted list
* @return {LinkedList}
*/
function createList() {
return { head: null };
}
/**
* Creates linked list item
* @template T
* @param {T} value
* @returns {LinkedListItem<T>}
*/
function createListItem(value) {
return { value, next: null, prev: null };
}
/**
* Prepends given value to linked list
* @template T
* @param {LinkedList} list
* @param {T} value
* @return {LinkedListItem<T>}
*/
function listPrependValue(list, value) {
const item = createListItem(value);
if (item.next = list.head) {
item.next.prev = item;
}
return list.head = item;
}
/**
* Inserts given value after given `ref` item
* @template T
* @param {T} value
* @param {LinkedListItem<any>} ref
* @return {LinkedListItem<T>}
*/
function listInsertValueAfter(value, ref) {
const item = createListItem(value);
const { next } = ref;
ref.next = item;
item.prev = ref;
if (item.next = next) {
next.prev = item;
}
return item;
}
/**
* Moves list fragment with `start` and `end` bounds right after `ref` item
* @param {LinkedList} list
* @param {LinkedListItem} start
* @param {LinkedListItem} end
* @param {LinkedListItem} ref
*/
function listMoveFragmentAfter(list, start, end, ref) {
listDetachFragment(list, start, end);
if (end.next = ref.next) {
end.next.prev = end;
}
ref.next = start;
start.prev = ref;
}
/**
* Moves list fragment with `start` and `end` to list head
* @param {LinkedList} list
* @param {LinkedListItem} start
* @param {LinkedListItem} end
*/
function listMoveFragmentFirst(list, start, end) {
listDetachFragment(list, start, end);
if (end.next = list.head) {
end.next.prev = end;
}
list.head = start;
}
/**
* Detaches list fragment with `start` and `end` from list
* @param {LinkedList} list
* @param {LinkedListItem} start
* @param {LinkedListItem} end
*/
function listDetachFragment(list, start, end) {
const { prev } = start;
const { next } = end;
if (prev) {
prev.next = next;
} else {
list.head = next;
}
if (next) {
next.prev = prev;
}
start.prev = end.next = null;
}
/**
* Creates fast object

@@ -163,4 +274,2 @@ * @param {Object} [proto]

const blockKey = '&block';
/**

@@ -174,5 +283,5 @@ * Creates injector instance for given target, if required

parentNode: target,
items: [],
items: createList(),
ctx: null,
ptr: 0,
ptr: null,

@@ -189,43 +298,2 @@ // NB create `slots` placeholder to promote object to hidden class.

/**
* Creates block for given injector
* @param {Injector} injector
* @returns {Block}
*/
function block(injector) {
return add(injector, {
[blockKey]: true,
inserted: 0,
deleted: 0,
size: 0,
dispose: null
});
}
/**
* Runs `fn` template function in context of given `block`
* @param {Injector} injector
* @param {Block} block
* @param {Function} fn
* @param {Component} component
* @param {*} data
* @returns {*} Result of `fn` function call
*/
function run(injector, block, fn, component, data) {
let result;
const ix = injector.items.indexOf(block);
if (typeof fn === 'function') {
const ctx = injector.ctx;
injector.ptr = ix + 1;
injector.ctx = block;
result = fn(component, injector, data);
injector.ctx = ctx;
ctx ? consume(ctx, block) : reset(block);
}
injector.ptr = ix + block.size + 1;
return result;
}
/**
* Inserts given node into current context

@@ -238,3 +306,3 @@ * @param {Injector} injector

let target;
const { slots } = injector;
const { items, slots, ptr } = injector;

@@ -247,34 +315,73 @@ if (slots) {

domInsert(node, target, getAnchorNode(injector.items, injector.ptr, target));
return add(injector, node);
domInsert(node, target, ptr && getAnchorNode(ptr.next, target));
injector.ptr = ptr ? listInsertValueAfter(node, ptr) : listPrependValue(items, node);
return node;
}
/**
* Moves contents of given block at `pos` location, effectively updating
* inserted nodes in parent context
* Injects given block
* @template {BaseBlock} T
* @param {Injector} injector
* @param {Block} block
* @param {number} pos
* @param {T} block
* @returns {T}
*/
function move(injector, block, pos) {
const { items } = injector;
function injectBlock(injector, block) {
const { items, ptr } = injector;
if (items[pos] === block) {
return;
if (ptr) {
block.end = listInsertValueAfter(block, ptr);
block.start = listInsertValueAfter(block, ptr);
} else {
block.end = listPrependValue(items, block);
block.start = listPrependValue(items, block);
}
// Move block contents at given position
const curPos = items.indexOf(block);
const blockItems = items.splice(curPos, block.size + 1);
injector.ptr = block.end;
return block;
}
if (curPos < pos) {
pos -= blockItems.length;
/**
* Runs `fn` template function in context of given `block`
* @param {BaseBlock} block
* @param {Function} fn
* @param {*} data
* @returns {*} Result of `fn` function call
*/
function run(block, fn, data) {
const { host, injector } = block;
const { ctx } = injector;
injector.ctx = block;
injector.ptr = block.start;
const result = fn(host, injector, data);
injector.ptr = block.end;
injector.ctx = ctx;
return result;
}
/**
* Empties content of given block
* @param {BaseBlock} block
*/
function emptyBlockContent(block) {
if (block.dispose) {
block.dispose(block.scope);
block.dispose = null;
}
for (let i = blockItems.length - 1, item; i >= 0; i--) {
item = /** @type {Element} */ (blockItems[i]);
if (!isBlock(item)) {
domInsert(item, item.parentNode, getAnchorNode(items, pos, item.parentNode));
let item = block.start.next;
while (item && item !== block.end) {
let { value, next, prev } = item;
if (isBlock(value)) {
next = value.end.next;
disposeBlock(value);
} else {
domRemove(value);
}
items.splice(pos, 0, item);
prev.next = next;
next.prev = prev;
item = next;
}

@@ -284,22 +391,33 @@ }

/**
* Disposes contents of given block
* Moves contents of `block` after `ref` list item
* @param {Injector} injector
* @param {Block} block
* @param {Object} scope
* @param {boolean} self Remove block item as well
* @param {BaseBlock} block
* @param {LinkedListItem<any>} [ref]
*/
function dispose(injector, block, scope, self) {
disposeBlock(block, scope, self);
function move(injector, block, ref) {
if (ref && ref.next && ref.next.value === block) {
return;
}
const { items, ctx } = injector;
const ix = items.indexOf(block) + (self ? 0 : 1);
const size = block.deleted;
// Update linked list
const { start, end } = block;
if (size) {
ctx && consume(ctx, block);
const removed = items.splice(ix, size);
if (ref) {
listMoveFragmentAfter(injector.items, start, end, ref);
} else {
listMoveFragmentFirst(injector.items, start, end);
}
for (let i = 0; i < removed.length; i++) {
domRemove(removed[i]);
// Move block contents in DOM
let item = start.next, node;
while (item !== end) {
if (!isBlock(item.value)) {
/** @type {Node} */
node = item.value;
// NB it’s possible that a single block contains nodes from different
// slots so we have to find anchor for each node individually
domInsert(node, node.parentNode, getAnchorNode(end.next, node.parentNode));
}
item = item.next;
}

@@ -310,26 +428,17 @@ }

* Disposes given block
* @param {Block} block
* @param {Object} scope
* @param {boolean} self Dispose block itself
* @returns {void} Should return nothing since function result will be used
* as shorthand to reset cached value
* @param {BaseBlock} block
*/
function disposeBlock(block, scope, self) {
if (block.dispose) {
block.dispose(scope);
block.dispose = null;
}
block.deleted += block.size + (self ? 1 : 0);
block.size = 0;
function disposeBlock(block) {
emptyBlockContent(block);
listDetachFragment(block.injector.items, block.start, block.end);
block.start = block.end = null;
}
/**
* Adds given item into current injector position
* @param {Injector} injector
* @param {InjectorItem} item
* Check if given value is a block
* @param {*} obj
* @returns {boolean}
*/
function add(injector, item) {
injector.items.splice(injector.ptr++, 0, item);
injector.ctx && markInsert(injector.ctx);
return item;
function isBlock(obj$$1) {
return '$$block' in obj$$1;
}

@@ -339,13 +448,13 @@

* Get DOM node nearest to given position of items list
* @param {InjectorItem[]} items
* @param {number} ix
* @param {LinkedListItem} item
* @param {Node} parent Ensure element has given element as parent node
* @returns {Node}
*/
function getAnchorNode(items, ix, parent) {
while (ix < items.length) {
const item = /** @type {Node} */ (items[ix++]);
if (item.parentNode === parent) {
return item;
function getAnchorNode(item, parent) {
while (item) {
if (item.value.parentNode === parent) {
return item.value;
}
item = item.next;
}

@@ -355,38 +464,2 @@ }

/**
* @param {Block} block
*/
function markInsert(block) {
block.inserted++;
block.size++;
}
/**
* Consumes data from given `child` block by parent `block`
* @param {Block} block
*/
function consume(block, child) {
block.inserted += child.inserted;
block.deleted += child.deleted;
block.size += child.inserted - child.deleted;
reset(child);
}
/**
* Reset session data from given block
* @param {Block} block
*/
function reset(block) {
block.inserted = block.deleted = 0;
}
/**
* Check if given value is a block
* @param {*} obj
* @returns {boolean}
*/
function isBlock(obj$$1) {
return blockKey in obj$$1;
}
/**
* @param {Node} node

@@ -408,4 +481,4 @@ * @param {Node} parent

function domRemove(node) {
const parent = node.parentNode;
parent && parent.removeChild(node);
const { parentNode } = node;
parentNode && parentNode.removeChild(node);
}

@@ -446,2 +519,3 @@

* @param {Object} scope
* @returns {Object}
*/

@@ -502,21 +576,23 @@ function setScope(host, scope) {

/**
* Initial block rendering
* @param {Component} host
* @param {Injector} injector
* @param {Function} get
* @returns {BlockContext}
* @returns {FunctionBlock}
*/
function mountBlock(host, injector, get) {
/** @type {BlockContext} */
const ctx = {
/** @type {FunctionBlock} */
const block = injectBlock(injector, {
$$block: true,
host,
injector,
block: block(injector),
scope: getScope(host),
dispose: null,
get,
fn: undefined,
update: undefined
};
updateBlock(ctx);
return ctx;
update: undefined,
start: null,
end: null
});
updateBlock(block);
return block;
}

@@ -526,23 +602,24 @@

* Updated block, described in `ctx` object
* @param {BlockContext} ctx
* @param {FunctionBlock} block
* @returns {number} Returns `1` if block was updated, `0` otherwise
*/
function updateBlock(ctx) {
function updateBlock(block) {
let updated = 0;
const { host, injector, scope, block: block$$1, update } = ctx;
const fn = ctx.get(host, scope, injector);
const { scope } = block;
const fn = block.get(block.host, scope);
if (ctx.fn !== fn) {
if (block.fn !== fn) {
updated = 1;
// Unmount previously rendered content
ctx.fn && dispose(injector, block$$1, scope, false);
block.fn && emptyBlockContent(block);
// Mount new block content
ctx.update = fn ? run(injector, block$$1, fn, host, scope) : null;
ctx.fn = fn;
} else if (update) {
block.update = fn && run(block, fn, scope);
block.fn = fn;
} else if (block.update) {
// Update rendered result
updated = run(injector, block$$1, update, host, scope) ? 1 : 0;
updated = run(block, block.update, scope) ? 1 : 0;
}
block.injector.ptr = block.end;
return updated;

@@ -552,6 +629,6 @@ }

/**
* @param {BlockContext} ctx
* @param {FunctionBlock} block
*/
function unmountBlock(ctx) {
dispose(ctx.injector, ctx.block, ctx.scope, true);
function unmountBlock(block) {
disposeBlock(block);
}

@@ -565,19 +642,21 @@

* @param {Function} body A function that renders item of iterated collection
* @returns {IteratorContext}
* @returns {IteratorBlock}
*/
function mountIterator(host, injector, get, body) {
/** @type {IteratorContext} */
const ctx = {
/** @type {IteratorBlock} */
const block = injectBlock(injector, {
$$block: true,
host,
injector,
scope: getScope(host),
dispose: null,
get,
body,
block: block(injector),
scope: getScope(host),
index: 0,
rendered: [],
updated: 0
};
updateIterator(ctx);
return ctx;
updated: 0,
start: null,
end: null
});
updateIterator(block);
return block;
}

@@ -587,21 +666,15 @@

* Updates iterator block defined in `ctx`
* @param {IteratorContext} ctx
* @param {IteratorBlock} block
* @returns {number} Returns `1` if iterator was updated, `0` otherwise
*/
function updateIterator(ctx) {
run(ctx.injector, ctx.block, iteratorHost, ctx.host, ctx) ? 1 : 0;
return ctx.updated;
function updateIterator(block) {
run(block, iteratorHost, block);
return block.updated;
}
/**
*
* @param {IteratorContext} ctx
* @param {IteratorBlock} block
*/
function unmountIterator(ctx) {
const { rendered, injector } = ctx;
let item;
while (item = rendered.pop()) {
dispose(injector, item[0], item[2], true);
}
function unmountIterator(block) {
disposeBlock(block);
}

@@ -613,18 +686,27 @@

* @param {Injector} injector
* @param {IteratorContext} ctx
* @param {IteratorBlock} block
*/
function iteratorHost(host, injector, ctx) {
ctx.index = 0;
ctx.updated = 0;
const collection = ctx.get(host, ctx.scope);
function iteratorHost(host, injector, block) {
block.index = 0;
block.updated = 0;
const collection = block.get(host, block.scope);
if (collection && typeof collection.forEach === 'function') {
collection.forEach(iterator, ctx);
collection.forEach(iterator, block);
}
// Remove remaining blocks
let item;
while (ctx.rendered.length > ctx.index) {
ctx.updated = 1;
item = ctx.rendered.pop();
dispose(injector, item[0], item[2], true);
trimIteratorItems(block);
}
/**
* Removes remaining iterator items from current context
* @param {IteratorBlock} block
*/
function trimIteratorItems(block) {
/** @type {LinkedListItem<IteratorItemBlock>} */
let item = block.injector.ptr.next, listItem;
while (item.value.owner === block) {
block.updated = 1;
listItem = item.value;
item = listItem.end.next;
disposeBlock(listItem);
}

@@ -634,3 +716,3 @@ }

/**
* @this {IteratorContext}
* @this {IteratorBlock}
* @param {*} value

@@ -640,23 +722,39 @@ * @param {*} key

function iterator(value, key) {
const { host, injector, rendered, index } = this;
const { host, injector, index } = this;
const { ptr } = injector;
const localScope = { index, key, value };
if (index < rendered.length) {
// Update existing block
const [b, update, scope] = rendered[index];
setScope(host, assign(scope, localScope));
if (run(injector, b, update, host, scope)) {
this.updated = 1;
/** @type {IteratorItemBlock} */
let rendered = ptr.next.value;
if (rendered.owner === this) {
// We have rendered item, update it
if (rendered.update) {
setScope(host, assign(rendered.scope, localScope));
if (run(rendered, rendered.update, rendered.scope)) {
this.updated = 1;
}
exitScope(host);
}
exitScope(host);
} else {
// Create & render new block
const b = block(injector);
const scope = enterScope(host, localScope);
const update = run(injector, b, this.body, host, scope);
/** @type {IteratorItemBlock} */
rendered = injectBlock(injector, {
$$block: true,
host,
injector,
scope: enterScope(host, localScope),
dispose: null,
update: undefined,
owner: this,
start: null,
end: null
});
rendered.update = run(rendered, this.body, rendered.scope);
exitScope(host);
rendered.push([b, update, scope]);
this.updated = 1;
}
injector.ptr = rendered.end;
this.index++;

@@ -672,21 +770,24 @@ }

* @param {Function} body
* @returns {KeyIteratorContext}
* @returns {KeyIteratorBlock}
*/
function mountKeyIterator(host, injector, get, keyExpr, body) {
/** @type {KeyIteratorContext} */
const ctx = {
/** @type {KeyIteratorBlock} */
const block = injectBlock(injector, {
$$block: true,
host,
injector,
scope: getScope(host),
dispose: null,
get,
body,
keyExpr,
body,
get,
index: 0,
updated: 0,
rendered: obj(),
block: block(injector),
scope: getScope(host),
index: 0,
updated: 1,
used: null
};
updateKeyIterator(ctx);
return ctx;
used: null,
start: null,
end: null
});
updateKeyIterator(block);
return block;
}

@@ -696,23 +797,15 @@

* Updates iterator block defined in `ctx`
* @param {KeyIteratorContext} ctx
* @param {KeyIteratorBlock} block
* @returns {number} Returns `1` if iterator was updated, `0` otherwise
*/
function updateKeyIterator(ctx) {
run(ctx.injector, ctx.block, keyIteratorHost, ctx.host, ctx);
return ctx.updated;
function updateKeyIterator(block) {
run(block, keyIteratorHost, block);
return block.updated;
}
/**
* @param {KeyIteratorContext} ctx
* @param {KeyIteratorBlock} ctx
*/
function unmountKeyIterator(ctx) {
const { rendered, injector } = ctx;
let items, item;
for (let k in rendered) {
items = rendered[k];
while (item = items.pop()) {
dispose(injector, item[0], item[2], true);
}
}
disposeBlock(ctx);
}

@@ -724,27 +817,20 @@

* @param {Injector} injector
* @param {KeyIteratorContext} ctx
* @param {KeyIteratorBlock} block
*/
function keyIteratorHost(host, injector, ctx) {
ctx.used = obj();
ctx.index = 0;
ctx.updated = 1;
function keyIteratorHost(host, injector, block) {
block.used = obj();
block.index = 0;
block.updated = 0;
const collection = ctx.get(host, ctx.scope);
const collection = block.get(host, block.scope);
if (collection && typeof collection.forEach === 'function') {
collection.forEach(iterator$1, ctx);
collection.forEach(iterator$1, block);
}
// Remove remaining blocks
for (let k in ctx.rendered) {
for (let i = 0, items = ctx.rendered[k]; i < items.length; i++) {
ctx.updated = 1;
dispose(injector, items[i][0], items[i][2], true);
}
}
ctx.rendered = ctx.used;
trimIteratorItems(block);
block.rendered = block.used;
}
/**
* @this {KeyIteratorContext}
* @this {KeyIteratorBlock}
* @param {*} value

@@ -754,24 +840,35 @@ * @param {*} key

function iterator$1(value, key) {
const { host, injector, index, used, rendered, keyExpr, body } = this;
const { host, injector, index, rendered, used, body } = this;
const localScope = { index, key, value };
const id = keyExpr(value, createScope(host, localScope));
const id = this.keyExpr(value, createScope(host, localScope));
let entry = id in rendered ? rendered[id].shift() : null;
let entry = id in rendered && rendered[id].shift();
if (entry) {
// Update existing block
const [b, update, scope] = entry;
setScope(host, assign(scope, localScope));
move(injector, b, injector.ptr);
if (run(injector, b, update, host, scope)) {
this.updated = 1;
move(injector, entry, injector.ptr);
if (entry.update) {
setScope(host, assign(entry.scope, localScope));
if (run(entry, entry.update, entry.scope)) {
this.updated = 1;
}
exitScope(host);
}
exitScope(host);
} else {
// Create & render new block
const b = block(injector);
const scope = enterScope(host, localScope);
const update = run(injector, b, body, host, scope);
/** @type {IteratorItemBlock} */
entry = injectBlock(injector, {
$$block: true,
host,
injector,
scope: enterScope(host, localScope),
dispose: null,
update: undefined,
owner: this,
start: null,
end: null
});
entry.update = run(entry, body, entry.scope);
this.updated = 1;
exitScope(host);
entry = [b, update, scope];
}

@@ -787,2 +884,3 @@

injector.ptr = entry.end;
this.index++;

@@ -1020,9 +1118,5 @@ }

const { slots } = host.componentModel;
const injector = createInjector(elem);
/**
* @param {Component} host
* @param {Object} scope
* @param {Injector} injector
*/
function blockEntry(host, scope, injector) {
function blockEntry() {
ctx.isDefault = !renderSlot(host, injector);

@@ -1032,3 +1126,3 @@ return ctx.isDefault ? ctx.defaultContent : null;

slots[name] = mountBlock(host, createInjector(elem), blockEntry);
slots[name] = mountBlock(host, injector, blockEntry);

@@ -1411,6 +1505,7 @@ return ctx;

finalizeEvents(input);
updateSlots(elem$$1);
if (changes) {
renderNext(elem$$1, changes);
} else {
updateSlots(elem$$1);
}

@@ -1427,3 +1522,3 @@ }

const { componentModel } = elem$$1;
const { slots, input, dispose: dispose$$1 } = componentModel;
const { slots, input, dispose } = componentModel;
const scope = getScope(elem$$1);

@@ -1447,6 +1542,6 @@

dispose$$1 && dispose$$1(scope);
dispose && dispose(scope);
for (const slotName in slots) {
disposeBlock(slots[slotName].block, scope, true);
disposeBlock(slots[slotName]);
}

@@ -1494,4 +1589,6 @@

// (for example, if parent node updated component props).
// Check if it’s still queued then render
if (elem$$1.componentModel.queued) {
// Check if it’s still queued then render.
// Also, component can be unmounted after it’s rendering was scheduled
const { componentModel } = elem$$1;
if (componentModel && componentModel.queued) {
renderComponent(elem$$1, changes);

@@ -1531,2 +1628,3 @@ }

runHook(elem$$1, 'didUpdate', args);
updateSlots(elem$$1);
}

@@ -1670,17 +1768,20 @@

* @param {string} slotName
* @returns {InnerHtmlContext}
* @returns {InnerHtmlBlock}
*/
function mountInnerHTML(host, injector, get, slotName) {
/** @type {InnerHtmlContext} */
const ctx = {
/** @type {InnerHtmlBlock} */
const block = injectBlock(injector, {
$$block: true,
host,
injector,
block: block(injector),
scope: getScope(host),
dispose: null,
get,
code: null,
slotName
};
updateInnerHTML(ctx);
return ctx;
slotName,
start: null,
end: null
});
updateInnerHTML(block);
return block;
}

@@ -1690,25 +1791,25 @@

* Updates inner HTML of block, defined in `ctx`
* @param {InnerHtmlContext} ctx
* @param {InnerHtmlBlock} block
* @returns {number} Returns `1` if inner HTML was updated, `0` otherwise
*/
function updateInnerHTML(ctx) {
const { host, injector, block: block$$1, scope } = ctx;
const code = ctx.get(host, injector);
let updated = 0;
function updateInnerHTML(block) {
const code = block.get(block.host, block.scope);
if (code !== ctx.code) {
updated = 1;
ctx.code = code;
dispose(injector, block$$1, scope, false);
isDefined(code) && run(injector, block$$1, renderHTML, host, ctx);
if (code !== block.code) {
emptyBlockContent(block);
if (isDefined(block.code = code)) {
run(block, renderHTML, block);
}
block.injector.ptr = block.end;
return 1;
}
return updated;
return 0;
}
/**
* @param {InnerHtmlContext} ctx
* @param {InnerHtmlBlock} ctx
*/
function unmountInnerHTML(ctx) {
dispose(ctx.injector, ctx.block, ctx.scope, true);
disposeBlock(ctx);
}

@@ -1719,3 +1820,3 @@

* @param {Injector} injector
* @param {InnerHtmlContext} ctx
* @param {InnerHtmlBlock} ctx
*/

@@ -1725,3 +1826,3 @@ function renderHTML(host, injector, ctx) {

div.innerHTML = ctx.code;
const cssScope$$1 = host.componentModel.definition.cssScope;
const { cssScope: cssScope$$1 } = host.componentModel.definition;
cssScope$$1 && scopeDOM(div, cssScope$$1);

@@ -1755,17 +1856,20 @@ while (div.firstChild) {

* @param {Object} args
* @return {PartialContext}
* @return {PartialBlock}
*/
function mountPartial(host, injector, partial, args) {
/** @type {PartialContext} */
const ctx = {
/** @type {PartialBlock} */
const block = injectBlock(injector, {
$$block: true,
host,
injector,
block: block(injector),
baseScope: getScope(host),
scope: null,
scope: getScope(host),
dispose: null,
childScope: null,
update: null,
partial: null
};
updatePartial(ctx, partial, args);
return ctx;
partial: null,
start: null,
end: null
});
updatePartial(block, partial, args);
return block;
}

@@ -1775,3 +1879,3 @@

* Updates mounted partial
* @param {PartialContext} ctx
* @param {PartialBlock} ctx
* @param {Object} partial

@@ -1782,3 +1886,3 @@ * @param {Object} args

function updatePartial(ctx, partial, args) {
const { host, injector, block: block$$1, baseScope } = ctx;
const { host, injector } = ctx;
let updated = 0;

@@ -1788,8 +1892,8 @@

// Unmount previously rendered partial
ctx.partial && dispose(injector, block$$1, ctx.scope, false);
ctx.partial && emptyBlockContent(ctx);
// Mount new partial
const scope = ctx.scope = assign(obj(baseScope), partial.defaults, args);
const scope = ctx.childScope = assign(obj(ctx.scope), partial.defaults, args);
setScope(host, scope);
ctx.update = partial ? run(injector, block$$1, partial.body, host, scope) : null;
ctx.update = partial ? run(ctx, partial.body, scope) : null;
ctx.partial = partial;

@@ -1800,4 +1904,4 @@ exitScope(host);

// Update rendered partial
setScope(host, assign(ctx.scope, args));
if (run(injector, block$$1, ctx.update, host, ctx.scope)) {
const scope = setScope(host, assign(ctx.childScope, args));
if (run(ctx, ctx.update, scope)) {
updated = 1;

@@ -1808,2 +1912,3 @@ }

injector.ptr = ctx.end;
return updated;

@@ -1813,6 +1918,6 @@ }

/**
* @param {PartialContext} ctx
* @param {PartialBlock} ctx
*/
function unmountPartial(ctx) {
dispose(ctx.injector, ctx.block, ctx.scope, true);
disposeBlock(ctx);
}

@@ -1996,2 +2101,4 @@

exports.unmountIterator = unmountIterator;
exports.iteratorHost = iteratorHost;
exports.trimIteratorItems = trimIteratorItems;
exports.mountKeyIterator = mountKeyIterator;

@@ -2001,7 +2108,7 @@ exports.updateKeyIterator = updateKeyIterator;

exports.createInjector = createInjector;
exports.block = block;
exports.insert = insert;
exports.injectBlock = injectBlock;
exports.run = run;
exports.insert = insert;
exports.emptyBlockContent = emptyBlockContent;
exports.move = move;
exports.dispose = dispose;
exports.disposeBlock = disposeBlock;

@@ -2008,0 +2115,0 @@ exports.enterScope = enterScope;

/**
* Creates linted list
* @return {LinkedList}
*/
function createList() {
return { head: null };
}
/**
* Creates linked list item
* @template T
* @param {T} value
* @returns {LinkedListItem<T>}
*/
function createListItem(value) {
return { value, next: null, prev: null };
}
/**
* Prepends given value to linked list
* @template T
* @param {LinkedList} list
* @param {T} value
* @return {LinkedListItem<T>}
*/
function listPrependValue(list, value) {
const item = createListItem(value);
if (item.next = list.head) {
item.next.prev = item;
}
return list.head = item;
}
/**
* Inserts given value after given `ref` item
* @template T
* @param {T} value
* @param {LinkedListItem<any>} ref
* @return {LinkedListItem<T>}
*/
function listInsertValueAfter(value, ref) {
const item = createListItem(value);
const { next } = ref;
ref.next = item;
item.prev = ref;
if (item.next = next) {
next.prev = item;
}
return item;
}
/**
* Moves list fragment with `start` and `end` bounds right after `ref` item
* @param {LinkedList} list
* @param {LinkedListItem} start
* @param {LinkedListItem} end
* @param {LinkedListItem} ref
*/
function listMoveFragmentAfter(list, start, end, ref) {
listDetachFragment(list, start, end);
if (end.next = ref.next) {
end.next.prev = end;
}
ref.next = start;
start.prev = ref;
}
/**
* Moves list fragment with `start` and `end` to list head
* @param {LinkedList} list
* @param {LinkedListItem} start
* @param {LinkedListItem} end
*/
function listMoveFragmentFirst(list, start, end) {
listDetachFragment(list, start, end);
if (end.next = list.head) {
end.next.prev = end;
}
list.head = start;
}
/**
* Detaches list fragment with `start` and `end` from list
* @param {LinkedList} list
* @param {LinkedListItem} start
* @param {LinkedListItem} end
*/
function listDetachFragment(list, start, end) {
const { prev } = start;
const { next } = end;
if (prev) {
prev.next = next;
} else {
list.head = next;
}
if (next) {
next.prev = prev;
}
start.prev = end.next = null;
}
/**
* Creates fast object

@@ -158,4 +269,2 @@ * @param {Object} [proto]

const blockKey = '&block';
/**

@@ -169,5 +278,5 @@ * Creates injector instance for given target, if required

parentNode: target,
items: [],
items: createList(),
ctx: null,
ptr: 0,
ptr: null,

@@ -184,43 +293,2 @@ // NB create `slots` placeholder to promote object to hidden class.

/**
* Creates block for given injector
* @param {Injector} injector
* @returns {Block}
*/
function block(injector) {
return add(injector, {
[blockKey]: true,
inserted: 0,
deleted: 0,
size: 0,
dispose: null
});
}
/**
* Runs `fn` template function in context of given `block`
* @param {Injector} injector
* @param {Block} block
* @param {Function} fn
* @param {Component} component
* @param {*} data
* @returns {*} Result of `fn` function call
*/
function run(injector, block, fn, component, data) {
let result;
const ix = injector.items.indexOf(block);
if (typeof fn === 'function') {
const ctx = injector.ctx;
injector.ptr = ix + 1;
injector.ctx = block;
result = fn(component, injector, data);
injector.ctx = ctx;
ctx ? consume(ctx, block) : reset(block);
}
injector.ptr = ix + block.size + 1;
return result;
}
/**
* Inserts given node into current context

@@ -233,3 +301,3 @@ * @param {Injector} injector

let target;
const { slots } = injector;
const { items, slots, ptr } = injector;

@@ -242,34 +310,73 @@ if (slots) {

domInsert(node, target, getAnchorNode(injector.items, injector.ptr, target));
return add(injector, node);
domInsert(node, target, ptr && getAnchorNode(ptr.next, target));
injector.ptr = ptr ? listInsertValueAfter(node, ptr) : listPrependValue(items, node);
return node;
}
/**
* Moves contents of given block at `pos` location, effectively updating
* inserted nodes in parent context
* Injects given block
* @template {BaseBlock} T
* @param {Injector} injector
* @param {Block} block
* @param {number} pos
* @param {T} block
* @returns {T}
*/
function move(injector, block, pos) {
const { items } = injector;
function injectBlock(injector, block) {
const { items, ptr } = injector;
if (items[pos] === block) {
return;
if (ptr) {
block.end = listInsertValueAfter(block, ptr);
block.start = listInsertValueAfter(block, ptr);
} else {
block.end = listPrependValue(items, block);
block.start = listPrependValue(items, block);
}
// Move block contents at given position
const curPos = items.indexOf(block);
const blockItems = items.splice(curPos, block.size + 1);
injector.ptr = block.end;
return block;
}
if (curPos < pos) {
pos -= blockItems.length;
/**
* Runs `fn` template function in context of given `block`
* @param {BaseBlock} block
* @param {Function} fn
* @param {*} data
* @returns {*} Result of `fn` function call
*/
function run(block, fn, data) {
const { host, injector } = block;
const { ctx } = injector;
injector.ctx = block;
injector.ptr = block.start;
const result = fn(host, injector, data);
injector.ptr = block.end;
injector.ctx = ctx;
return result;
}
/**
* Empties content of given block
* @param {BaseBlock} block
*/
function emptyBlockContent(block) {
if (block.dispose) {
block.dispose(block.scope);
block.dispose = null;
}
for (let i = blockItems.length - 1, item; i >= 0; i--) {
item = /** @type {Element} */ (blockItems[i]);
if (!isBlock(item)) {
domInsert(item, item.parentNode, getAnchorNode(items, pos, item.parentNode));
let item = block.start.next;
while (item && item !== block.end) {
let { value, next, prev } = item;
if (isBlock(value)) {
next = value.end.next;
disposeBlock(value);
} else {
domRemove(value);
}
items.splice(pos, 0, item);
prev.next = next;
next.prev = prev;
item = next;
}

@@ -279,22 +386,33 @@ }

/**
* Disposes contents of given block
* Moves contents of `block` after `ref` list item
* @param {Injector} injector
* @param {Block} block
* @param {Object} scope
* @param {boolean} self Remove block item as well
* @param {BaseBlock} block
* @param {LinkedListItem<any>} [ref]
*/
function dispose(injector, block, scope, self) {
disposeBlock(block, scope, self);
function move(injector, block, ref) {
if (ref && ref.next && ref.next.value === block) {
return;
}
const { items, ctx } = injector;
const ix = items.indexOf(block) + (self ? 0 : 1);
const size = block.deleted;
// Update linked list
const { start, end } = block;
if (size) {
ctx && consume(ctx, block);
const removed = items.splice(ix, size);
if (ref) {
listMoveFragmentAfter(injector.items, start, end, ref);
} else {
listMoveFragmentFirst(injector.items, start, end);
}
for (let i = 0; i < removed.length; i++) {
domRemove(removed[i]);
// Move block contents in DOM
let item = start.next, node;
while (item !== end) {
if (!isBlock(item.value)) {
/** @type {Node} */
node = item.value;
// NB it’s possible that a single block contains nodes from different
// slots so we have to find anchor for each node individually
domInsert(node, node.parentNode, getAnchorNode(end.next, node.parentNode));
}
item = item.next;
}

@@ -305,26 +423,17 @@ }

* Disposes given block
* @param {Block} block
* @param {Object} scope
* @param {boolean} self Dispose block itself
* @returns {void} Should return nothing since function result will be used
* as shorthand to reset cached value
* @param {BaseBlock} block
*/
function disposeBlock(block, scope, self) {
if (block.dispose) {
block.dispose(scope);
block.dispose = null;
}
block.deleted += block.size + (self ? 1 : 0);
block.size = 0;
function disposeBlock(block) {
emptyBlockContent(block);
listDetachFragment(block.injector.items, block.start, block.end);
block.start = block.end = null;
}
/**
* Adds given item into current injector position
* @param {Injector} injector
* @param {InjectorItem} item
* Check if given value is a block
* @param {*} obj
* @returns {boolean}
*/
function add(injector, item) {
injector.items.splice(injector.ptr++, 0, item);
injector.ctx && markInsert(injector.ctx);
return item;
function isBlock(obj$$1) {
return '$$block' in obj$$1;
}

@@ -334,13 +443,13 @@

* Get DOM node nearest to given position of items list
* @param {InjectorItem[]} items
* @param {number} ix
* @param {LinkedListItem} item
* @param {Node} parent Ensure element has given element as parent node
* @returns {Node}
*/
function getAnchorNode(items, ix, parent) {
while (ix < items.length) {
const item = /** @type {Node} */ (items[ix++]);
if (item.parentNode === parent) {
return item;
function getAnchorNode(item, parent) {
while (item) {
if (item.value.parentNode === parent) {
return item.value;
}
item = item.next;
}

@@ -350,38 +459,2 @@ }

/**
* @param {Block} block
*/
function markInsert(block) {
block.inserted++;
block.size++;
}
/**
* Consumes data from given `child` block by parent `block`
* @param {Block} block
*/
function consume(block, child) {
block.inserted += child.inserted;
block.deleted += child.deleted;
block.size += child.inserted - child.deleted;
reset(child);
}
/**
* Reset session data from given block
* @param {Block} block
*/
function reset(block) {
block.inserted = block.deleted = 0;
}
/**
* Check if given value is a block
* @param {*} obj
* @returns {boolean}
*/
function isBlock(obj$$1) {
return blockKey in obj$$1;
}
/**
* @param {Node} node

@@ -403,4 +476,4 @@ * @param {Node} parent

function domRemove(node) {
const parent = node.parentNode;
parent && parent.removeChild(node);
const { parentNode } = node;
parentNode && parentNode.removeChild(node);
}

@@ -441,2 +514,3 @@

* @param {Object} scope
* @returns {Object}
*/

@@ -497,21 +571,23 @@ function setScope(host, scope) {

/**
* Initial block rendering
* @param {Component} host
* @param {Injector} injector
* @param {Function} get
* @returns {BlockContext}
* @returns {FunctionBlock}
*/
function mountBlock(host, injector, get) {
/** @type {BlockContext} */
const ctx = {
/** @type {FunctionBlock} */
const block = injectBlock(injector, {
$$block: true,
host,
injector,
block: block(injector),
scope: getScope(host),
dispose: null,
get,
fn: undefined,
update: undefined
};
updateBlock(ctx);
return ctx;
update: undefined,
start: null,
end: null
});
updateBlock(block);
return block;
}

@@ -521,23 +597,24 @@

* Updated block, described in `ctx` object
* @param {BlockContext} ctx
* @param {FunctionBlock} block
* @returns {number} Returns `1` if block was updated, `0` otherwise
*/
function updateBlock(ctx) {
function updateBlock(block) {
let updated = 0;
const { host, injector, scope, block: block$$1, update } = ctx;
const fn = ctx.get(host, scope, injector);
const { scope } = block;
const fn = block.get(block.host, scope);
if (ctx.fn !== fn) {
if (block.fn !== fn) {
updated = 1;
// Unmount previously rendered content
ctx.fn && dispose(injector, block$$1, scope, false);
block.fn && emptyBlockContent(block);
// Mount new block content
ctx.update = fn ? run(injector, block$$1, fn, host, scope) : null;
ctx.fn = fn;
} else if (update) {
block.update = fn && run(block, fn, scope);
block.fn = fn;
} else if (block.update) {
// Update rendered result
updated = run(injector, block$$1, update, host, scope) ? 1 : 0;
updated = run(block, block.update, scope) ? 1 : 0;
}
block.injector.ptr = block.end;
return updated;

@@ -547,6 +624,6 @@ }

/**
* @param {BlockContext} ctx
* @param {FunctionBlock} block
*/
function unmountBlock(ctx) {
dispose(ctx.injector, ctx.block, ctx.scope, true);
function unmountBlock(block) {
disposeBlock(block);
}

@@ -560,19 +637,21 @@

* @param {Function} body A function that renders item of iterated collection
* @returns {IteratorContext}
* @returns {IteratorBlock}
*/
function mountIterator(host, injector, get, body) {
/** @type {IteratorContext} */
const ctx = {
/** @type {IteratorBlock} */
const block = injectBlock(injector, {
$$block: true,
host,
injector,
scope: getScope(host),
dispose: null,
get,
body,
block: block(injector),
scope: getScope(host),
index: 0,
rendered: [],
updated: 0
};
updateIterator(ctx);
return ctx;
updated: 0,
start: null,
end: null
});
updateIterator(block);
return block;
}

@@ -582,21 +661,15 @@

* Updates iterator block defined in `ctx`
* @param {IteratorContext} ctx
* @param {IteratorBlock} block
* @returns {number} Returns `1` if iterator was updated, `0` otherwise
*/
function updateIterator(ctx) {
run(ctx.injector, ctx.block, iteratorHost, ctx.host, ctx) ? 1 : 0;
return ctx.updated;
function updateIterator(block) {
run(block, iteratorHost, block);
return block.updated;
}
/**
*
* @param {IteratorContext} ctx
* @param {IteratorBlock} block
*/
function unmountIterator(ctx) {
const { rendered, injector } = ctx;
let item;
while (item = rendered.pop()) {
dispose(injector, item[0], item[2], true);
}
function unmountIterator(block) {
disposeBlock(block);
}

@@ -608,18 +681,27 @@

* @param {Injector} injector
* @param {IteratorContext} ctx
* @param {IteratorBlock} block
*/
function iteratorHost(host, injector, ctx) {
ctx.index = 0;
ctx.updated = 0;
const collection = ctx.get(host, ctx.scope);
function iteratorHost(host, injector, block) {
block.index = 0;
block.updated = 0;
const collection = block.get(host, block.scope);
if (collection && typeof collection.forEach === 'function') {
collection.forEach(iterator, ctx);
collection.forEach(iterator, block);
}
// Remove remaining blocks
let item;
while (ctx.rendered.length > ctx.index) {
ctx.updated = 1;
item = ctx.rendered.pop();
dispose(injector, item[0], item[2], true);
trimIteratorItems(block);
}
/**
* Removes remaining iterator items from current context
* @param {IteratorBlock} block
*/
function trimIteratorItems(block) {
/** @type {LinkedListItem<IteratorItemBlock>} */
let item = block.injector.ptr.next, listItem;
while (item.value.owner === block) {
block.updated = 1;
listItem = item.value;
item = listItem.end.next;
disposeBlock(listItem);
}

@@ -629,3 +711,3 @@ }

/**
* @this {IteratorContext}
* @this {IteratorBlock}
* @param {*} value

@@ -635,23 +717,39 @@ * @param {*} key

function iterator(value, key) {
const { host, injector, rendered, index } = this;
const { host, injector, index } = this;
const { ptr } = injector;
const localScope = { index, key, value };
if (index < rendered.length) {
// Update existing block
const [b, update, scope] = rendered[index];
setScope(host, assign(scope, localScope));
if (run(injector, b, update, host, scope)) {
this.updated = 1;
/** @type {IteratorItemBlock} */
let rendered = ptr.next.value;
if (rendered.owner === this) {
// We have rendered item, update it
if (rendered.update) {
setScope(host, assign(rendered.scope, localScope));
if (run(rendered, rendered.update, rendered.scope)) {
this.updated = 1;
}
exitScope(host);
}
exitScope(host);
} else {
// Create & render new block
const b = block(injector);
const scope = enterScope(host, localScope);
const update = run(injector, b, this.body, host, scope);
/** @type {IteratorItemBlock} */
rendered = injectBlock(injector, {
$$block: true,
host,
injector,
scope: enterScope(host, localScope),
dispose: null,
update: undefined,
owner: this,
start: null,
end: null
});
rendered.update = run(rendered, this.body, rendered.scope);
exitScope(host);
rendered.push([b, update, scope]);
this.updated = 1;
}
injector.ptr = rendered.end;
this.index++;

@@ -667,21 +765,24 @@ }

* @param {Function} body
* @returns {KeyIteratorContext}
* @returns {KeyIteratorBlock}
*/
function mountKeyIterator(host, injector, get, keyExpr, body) {
/** @type {KeyIteratorContext} */
const ctx = {
/** @type {KeyIteratorBlock} */
const block = injectBlock(injector, {
$$block: true,
host,
injector,
scope: getScope(host),
dispose: null,
get,
body,
keyExpr,
body,
get,
index: 0,
updated: 0,
rendered: obj(),
block: block(injector),
scope: getScope(host),
index: 0,
updated: 1,
used: null
};
updateKeyIterator(ctx);
return ctx;
used: null,
start: null,
end: null
});
updateKeyIterator(block);
return block;
}

@@ -691,23 +792,15 @@

* Updates iterator block defined in `ctx`
* @param {KeyIteratorContext} ctx
* @param {KeyIteratorBlock} block
* @returns {number} Returns `1` if iterator was updated, `0` otherwise
*/
function updateKeyIterator(ctx) {
run(ctx.injector, ctx.block, keyIteratorHost, ctx.host, ctx);
return ctx.updated;
function updateKeyIterator(block) {
run(block, keyIteratorHost, block);
return block.updated;
}
/**
* @param {KeyIteratorContext} ctx
* @param {KeyIteratorBlock} ctx
*/
function unmountKeyIterator(ctx) {
const { rendered, injector } = ctx;
let items, item;
for (let k in rendered) {
items = rendered[k];
while (item = items.pop()) {
dispose(injector, item[0], item[2], true);
}
}
disposeBlock(ctx);
}

@@ -719,27 +812,20 @@

* @param {Injector} injector
* @param {KeyIteratorContext} ctx
* @param {KeyIteratorBlock} block
*/
function keyIteratorHost(host, injector, ctx) {
ctx.used = obj();
ctx.index = 0;
ctx.updated = 1;
function keyIteratorHost(host, injector, block) {
block.used = obj();
block.index = 0;
block.updated = 0;
const collection = ctx.get(host, ctx.scope);
const collection = block.get(host, block.scope);
if (collection && typeof collection.forEach === 'function') {
collection.forEach(iterator$1, ctx);
collection.forEach(iterator$1, block);
}
// Remove remaining blocks
for (let k in ctx.rendered) {
for (let i = 0, items = ctx.rendered[k]; i < items.length; i++) {
ctx.updated = 1;
dispose(injector, items[i][0], items[i][2], true);
}
}
ctx.rendered = ctx.used;
trimIteratorItems(block);
block.rendered = block.used;
}
/**
* @this {KeyIteratorContext}
* @this {KeyIteratorBlock}
* @param {*} value

@@ -749,24 +835,35 @@ * @param {*} key

function iterator$1(value, key) {
const { host, injector, index, used, rendered, keyExpr, body } = this;
const { host, injector, index, rendered, used, body } = this;
const localScope = { index, key, value };
const id = keyExpr(value, createScope(host, localScope));
const id = this.keyExpr(value, createScope(host, localScope));
let entry = id in rendered ? rendered[id].shift() : null;
let entry = id in rendered && rendered[id].shift();
if (entry) {
// Update existing block
const [b, update, scope] = entry;
setScope(host, assign(scope, localScope));
move(injector, b, injector.ptr);
if (run(injector, b, update, host, scope)) {
this.updated = 1;
move(injector, entry, injector.ptr);
if (entry.update) {
setScope(host, assign(entry.scope, localScope));
if (run(entry, entry.update, entry.scope)) {
this.updated = 1;
}
exitScope(host);
}
exitScope(host);
} else {
// Create & render new block
const b = block(injector);
const scope = enterScope(host, localScope);
const update = run(injector, b, body, host, scope);
/** @type {IteratorItemBlock} */
entry = injectBlock(injector, {
$$block: true,
host,
injector,
scope: enterScope(host, localScope),
dispose: null,
update: undefined,
owner: this,
start: null,
end: null
});
entry.update = run(entry, body, entry.scope);
this.updated = 1;
exitScope(host);
entry = [b, update, scope];
}

@@ -782,2 +879,3 @@

injector.ptr = entry.end;
this.index++;

@@ -1015,9 +1113,5 @@ }

const { slots } = host.componentModel;
const injector = createInjector(elem);
/**
* @param {Component} host
* @param {Object} scope
* @param {Injector} injector
*/
function blockEntry(host, scope, injector) {
function blockEntry() {
ctx.isDefault = !renderSlot(host, injector);

@@ -1027,3 +1121,3 @@ return ctx.isDefault ? ctx.defaultContent : null;

slots[name] = mountBlock(host, createInjector(elem), blockEntry);
slots[name] = mountBlock(host, injector, blockEntry);

@@ -1406,6 +1500,7 @@ return ctx;

finalizeEvents(input);
updateSlots(elem$$1);
if (changes) {
renderNext(elem$$1, changes);
} else {
updateSlots(elem$$1);
}

@@ -1422,3 +1517,3 @@ }

const { componentModel } = elem$$1;
const { slots, input, dispose: dispose$$1 } = componentModel;
const { slots, input, dispose } = componentModel;
const scope = getScope(elem$$1);

@@ -1442,6 +1537,6 @@

dispose$$1 && dispose$$1(scope);
dispose && dispose(scope);
for (const slotName in slots) {
disposeBlock(slots[slotName].block, scope, true);
disposeBlock(slots[slotName]);
}

@@ -1489,4 +1584,6 @@

// (for example, if parent node updated component props).
// Check if it’s still queued then render
if (elem$$1.componentModel.queued) {
// Check if it’s still queued then render.
// Also, component can be unmounted after it’s rendering was scheduled
const { componentModel } = elem$$1;
if (componentModel && componentModel.queued) {
renderComponent(elem$$1, changes);

@@ -1526,2 +1623,3 @@ }

runHook(elem$$1, 'didUpdate', args);
updateSlots(elem$$1);
}

@@ -1665,17 +1763,20 @@

* @param {string} slotName
* @returns {InnerHtmlContext}
* @returns {InnerHtmlBlock}
*/
function mountInnerHTML(host, injector, get, slotName) {
/** @type {InnerHtmlContext} */
const ctx = {
/** @type {InnerHtmlBlock} */
const block = injectBlock(injector, {
$$block: true,
host,
injector,
block: block(injector),
scope: getScope(host),
dispose: null,
get,
code: null,
slotName
};
updateInnerHTML(ctx);
return ctx;
slotName,
start: null,
end: null
});
updateInnerHTML(block);
return block;
}

@@ -1685,25 +1786,25 @@

* Updates inner HTML of block, defined in `ctx`
* @param {InnerHtmlContext} ctx
* @param {InnerHtmlBlock} block
* @returns {number} Returns `1` if inner HTML was updated, `0` otherwise
*/
function updateInnerHTML(ctx) {
const { host, injector, block: block$$1, scope } = ctx;
const code = ctx.get(host, injector);
let updated = 0;
function updateInnerHTML(block) {
const code = block.get(block.host, block.scope);
if (code !== ctx.code) {
updated = 1;
ctx.code = code;
dispose(injector, block$$1, scope, false);
isDefined(code) && run(injector, block$$1, renderHTML, host, ctx);
if (code !== block.code) {
emptyBlockContent(block);
if (isDefined(block.code = code)) {
run(block, renderHTML, block);
}
block.injector.ptr = block.end;
return 1;
}
return updated;
return 0;
}
/**
* @param {InnerHtmlContext} ctx
* @param {InnerHtmlBlock} ctx
*/
function unmountInnerHTML(ctx) {
dispose(ctx.injector, ctx.block, ctx.scope, true);
disposeBlock(ctx);
}

@@ -1714,3 +1815,3 @@

* @param {Injector} injector
* @param {InnerHtmlContext} ctx
* @param {InnerHtmlBlock} ctx
*/

@@ -1720,3 +1821,3 @@ function renderHTML(host, injector, ctx) {

div.innerHTML = ctx.code;
const cssScope$$1 = host.componentModel.definition.cssScope;
const { cssScope: cssScope$$1 } = host.componentModel.definition;
cssScope$$1 && scopeDOM(div, cssScope$$1);

@@ -1750,17 +1851,20 @@ while (div.firstChild) {

* @param {Object} args
* @return {PartialContext}
* @return {PartialBlock}
*/
function mountPartial(host, injector, partial, args) {
/** @type {PartialContext} */
const ctx = {
/** @type {PartialBlock} */
const block = injectBlock(injector, {
$$block: true,
host,
injector,
block: block(injector),
baseScope: getScope(host),
scope: null,
scope: getScope(host),
dispose: null,
childScope: null,
update: null,
partial: null
};
updatePartial(ctx, partial, args);
return ctx;
partial: null,
start: null,
end: null
});
updatePartial(block, partial, args);
return block;
}

@@ -1770,3 +1874,3 @@

* Updates mounted partial
* @param {PartialContext} ctx
* @param {PartialBlock} ctx
* @param {Object} partial

@@ -1777,3 +1881,3 @@ * @param {Object} args

function updatePartial(ctx, partial, args) {
const { host, injector, block: block$$1, baseScope } = ctx;
const { host, injector } = ctx;
let updated = 0;

@@ -1783,8 +1887,8 @@

// Unmount previously rendered partial
ctx.partial && dispose(injector, block$$1, ctx.scope, false);
ctx.partial && emptyBlockContent(ctx);
// Mount new partial
const scope = ctx.scope = assign(obj(baseScope), partial.defaults, args);
const scope = ctx.childScope = assign(obj(ctx.scope), partial.defaults, args);
setScope(host, scope);
ctx.update = partial ? run(injector, block$$1, partial.body, host, scope) : null;
ctx.update = partial ? run(ctx, partial.body, scope) : null;
ctx.partial = partial;

@@ -1795,4 +1899,4 @@ exitScope(host);

// Update rendered partial
setScope(host, assign(ctx.scope, args));
if (run(injector, block$$1, ctx.update, host, ctx.scope)) {
const scope = setScope(host, assign(ctx.childScope, args));
if (run(ctx, ctx.update, scope)) {
updated = 1;

@@ -1803,2 +1907,3 @@ }

injector.ptr = ctx.end;
return updated;

@@ -1808,6 +1913,6 @@ }

/**
* @param {PartialContext} ctx
* @param {PartialBlock} ctx
*/
function unmountPartial(ctx) {
dispose(ctx.injector, ctx.block, ctx.scope, true);
disposeBlock(ctx);
}

@@ -1982,3 +2087,3 @@

export { get, filter, addDisposeCallback, mountBlock, updateBlock, unmountBlock, mountIterator, updateIterator, unmountIterator, mountKeyIterator, updateKeyIterator, unmountKeyIterator, createInjector, block, run, insert, move, dispose, disposeBlock, enterScope, exitScope, createScope, setScope, getScope, getProp, getState, getVar, setVar, setAttribute, updateAttribute, updateProps, addClass, finalizeAttributes, normalizeClassName, addEvent, addStaticEvent, finalizeEvents, getEventHandler, mountSlot, unmountSlot, updateSlots, markSlotUpdate, setRef, setStaticRef, finalizeRefs, createComponent, mountComponent, updateComponent, unmountComponent, subscribeStore, scheduleRender, renderComponent, mountInnerHTML, updateInnerHTML, unmountInnerHTML, elem, elemNS, elemWithText, elemNSWithText, text, updateText, mountPartial, updatePartial, unmountPartial, Store };
export { get, filter, addDisposeCallback, mountBlock, updateBlock, unmountBlock, mountIterator, updateIterator, unmountIterator, iteratorHost, trimIteratorItems, mountKeyIterator, updateKeyIterator, unmountKeyIterator, createInjector, insert, injectBlock, run, emptyBlockContent, move, disposeBlock, enterScope, exitScope, createScope, setScope, getScope, getProp, getState, getVar, setVar, setAttribute, updateAttribute, updateProps, addClass, finalizeAttributes, normalizeClassName, addEvent, addStaticEvent, finalizeEvents, getEventHandler, mountSlot, unmountSlot, updateSlots, markSlotUpdate, setRef, setStaticRef, finalizeRefs, createComponent, mountComponent, updateComponent, unmountComponent, subscribeStore, scheduleRender, renderComponent, mountInnerHTML, updateInnerHTML, unmountInnerHTML, elem, elemNS, elemWithText, elemNSWithText, text, updateText, mountPartial, updatePartial, unmountPartial, Store };
//# sourceMappingURL=runtime.es.js.map
{
"name": "@endorphinjs/template-runtime",
"version": "0.1.12",
"version": "0.1.13",
"description": "EndorphinJS template runtime, embedded with template bundles",

@@ -5,0 +5,0 @@ "main": "./dist/runtime.cjs.js",

@@ -11,2 +11,6 @@ import { Store } from './lib/store';

interface BlockDisposeCallback {
(block: BaseBlock): void;
}
interface Component extends Element {

@@ -108,3 +112,3 @@ /**

slots: {
[name: string]: BlockContext
[name: string]: BaseBlock
}

@@ -279,3 +283,3 @@

*/
items: InjectorItem[];
items: LinkedList;

@@ -285,3 +289,3 @@ /**

*/
ptr: number;
ptr: LinkedListItem<any>;

@@ -291,3 +295,3 @@ /**

*/
ctx: Block;
ctx: BaseBlock;

@@ -312,29 +316,2 @@ /**

/**
* A structure that holds data about elements owned by given block context
* right below it in `Injector` list
*/
type Block = {
/** @private */
'&block': true;
/**
* Number of inserted items in block context
*/
inserted: number;
/**
* Number of deleted items in block context
*/
deleted: number;
/**
* Amount of items in current block
*/
size: number;
/** A function to dispose block contents */
dispose?: DisposeCallback;
}
interface AttachedEventsMap {

@@ -367,16 +344,49 @@ [event: string]: {

interface BaseContext {
interface SlotContext {
host: Component;
name: string;
isDefault: boolean;
defaultContent: Function;
}
interface StoreUpdateHandler {
(state: object, changes: object): void
}
interface StoreUpdateEntry {
keys?: string[];
component?: Component;
handler?: StoreUpdateHandler;
}
interface LinkedList {
head: LinkedListItem;
}
interface LinkedListItem<T> {
value: T;
next: LinkedListItem<any> | null;
prev: LinkedListItem<any> | null;
}
interface BaseBlock<T> {
$$block: true;
host: Component;
injector: Injector;
block: Block;
scope: Object;
/** A function to dispose block contents */
dispose: BlockDisposeCallback | null;
start: LinkedListItem<T>;
end: LinkedListItem<T>;
}
interface BlockContext extends BaseContext {
interface FunctionBlock extends BaseBlock<FunctionBlock> {
get: Function;
fn?: Function,
update?: Function,
fn: Function | undefined;
update: Function | undefined;
}
interface IteratorContext extends BaseContext {
interface IteratorBlock extends BaseBlock<IteratorBlock> {
get: Function;

@@ -386,43 +396,30 @@ body: Function;

updated: number;
rendered: Array<[Block, Function, Object]>;
}
interface KeyIteratorContext extends IteratorContext {
interface KeyIteratorBlock extends IteratorBlock {
keyExpr: Function;
used: {
[key: string]: Array<[Block, Function, Object]>
}
[key: string]: IteratorItemBlock[]
} | null;
rendered: {
[key: string]: Array<[Block, Function, Object]>
}
[key: string]: IteratorItemBlock[]
} | null;
}
interface SlotContext {
host: Component;
name: string;
isDefault: boolean;
defaultContent: Function;
interface IteratorItemBlock extends BaseBlock<IteratorItemBlock> {
update: Function | undefined;
owner: IteratorBlock | KeyIteratorBlock;
}
interface InnerHtmlContext extends BaseContext {
interface InnerHtmlBlock extends BaseBlock<InnerHtmlBlock> {
get: Function;
code?: string;
code: string | null;
slotName: string;
}
interface PartialContext extends BaseContext {
baseScope?: Object;
update?: Function;
partial?: Object;
interface PartialBlock extends BaseBlock<PartialBlock> {
childScope: Object;
update: Function | null;
partial: Object | null;
}
interface StoreUpdateHandler {
(state: object, changes: object): void
}
interface StoreUpdateEntry {
keys?: string[];
component?: Component;
handler?: StoreUpdateHandler;
}
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc