New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

hydro-js

Package Overview
Dependencies
Maintainers
1
Versions
63
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

hydro-js - npm Package Compare versions

Comparing version 1.3.5 to 1.4.0

6

CHANGELOG.md
# Changelog
## 1.4.0- 2021-05-06
- Refactor h function. Breaking Change: Does not really support SVG anymore. Use html function for this case.
- Performance improvements
- Add non-keyed solution and default to it
## 1.3.5- 2021-05-03

@@ -4,0 +10,0 @@

147

dist/library.cjs.js

@@ -19,2 +19,3 @@ // Safari Polyfills

const bindMap = new WeakMap(); // Bind an Element to Data. If the Data is being unset, the DOM Element disappears too.
const tmpSwap = new WeakMap(); // Take over keyToNodeMap if new value is a hydro Proxy. Save old reactivityMap entry here, in case for a swap operation. [if reuseElements]
const onRenderMap = new WeakMap(); // Lifecycle Hook that is being called after rendering

@@ -28,2 +29,3 @@ const onCleanupMap = new WeakMap(); // Lifecycle Hook that is being called when unmount function is being called

let shouldSetReactivity = true;
let viewElements = false;
const reactivityRegex = /\{\{((\s|.)*?)\}\}/;

@@ -177,3 +179,20 @@ const HTML_FIND_INVALID = /<(\/?)(html|head|body)(>|\s.*?>)/g;

const DOM = parser(DOMString);
const root = document.createNodeIterator(DOM, NodeFilter.SHOW_ELEMENT, {
// Delay Elemen iteration and manipulation after the elements have been added to the DOM.
if (viewElements) {
onRender(fillDOM, DOM.firstChild, DOM.firstChild, insertNodes, eventFunctions);
}
else {
fillDOM(DOM, insertNodes, eventFunctions);
}
// Return DocumentFragment
if (DOM.childNodes.length > 1)
return DOM;
// Return Text Node
if (!DOM.firstChild)
return document.createTextNode("");
// Return Element
return DOM.firstChild;
}
function fillDOM(elem, insertNodes, eventFunctions) {
const root = document.createNodeIterator(elem, NodeFilter.SHOW_ELEMENT, {
acceptNode(element) {

@@ -185,23 +204,18 @@ return element.localName.endsWith("-dummy" /* dummy */)

});
let elem;
while ((elem = root.nextNode())) {
const tag = elem.localName.replace("-dummy" /* dummy */, "");
let nextNode;
while ((nextNode = root.nextNode())) {
const tag = nextNode.localName.replace("-dummy" /* dummy */, "");
const replacement = document.createElement(tag);
//@ts-ignore
replacement.append(...elem.childNodes);
elem.replaceWith(replacement);
replacement.append(...nextNode.childNodes);
nextNode.replaceWith(replacement);
}
// Insert HTML Elements, which were stored in insertNodes
DOM.querySelectorAll("template[id^=lbInsertNodes]").forEach((template) => template.replaceWith(insertNodes.shift()));
elem
.querySelectorAll("template[id^=lbInsertNodes]")
.forEach((template) => template.replaceWith(insertNodes.shift()));
if (shouldSetReactivity)
setReactivity(DOM, eventFunctions);
// Return DocumentFragment
if (DOM.childNodes.length > 1)
return DOM;
// Return Text Node
if (!DOM.firstChild)
return document.createTextNode("");
// Return Element
return DOM.firstChild;
setReactivity(elem, eventFunctions);
}
/* c8 ignore start */
function h(name, props, ...children) {

@@ -211,8 +225,14 @@ if (isFunction(name))

const flatChildren = children
.map((child) =>
/* c8 ignore next 1 */
isObject(child) && !isNode(child) ? Object.values(child) : child)
.map((child) => isObject(child) && !isNode(child) ? Object.values(child) : child)
.flat();
return html `<${name} ${props || {}}>${flatChildren}</${name}>`;
const elem = document.createElement(name);
for (let i in props) {
//@ts-ignore
i in elem ? (elem[i] = props[i]) : setAttribute(elem, i, props[i]);
}
elem.append(...flatChildren);
onRender(setReactivity, elem, elem);
return elem;
}
/* c8 ignore end */
function setReactivity(DOM, eventFunctions) {

@@ -569,6 +589,9 @@ // Set events and reactive behaviour(checks for {{ key }} where key is on hydro)

const fn = lifecyleMap.get(node);
/* c8 ignore next 3 */
if (globalSchedule) {
if (viewElements) {
schedule(fn);
/* c8 ignore next 3 */
}
else if (globalSchedule) {
window.requestIdleCallback(fn);
}
else {

@@ -948,2 +971,3 @@ fn();

// Remove item from array
/* c8 ignore next 4 */
if (!internReset && Array.isArray(receiver)) {

@@ -967,4 +991,5 @@ receiver.splice(key, 1);

let subItem = receiver[key][i];
/* c8 ignore next 3 */
if (isObject(subItem) && isProxy(subItem)) {
subItem = null;
receiver[key][i] = null;
}

@@ -1002,5 +1027,7 @@ }

else {
if (Array.isArray(receiver) &&
if (!reuseElements &&
Array.isArray(receiver) &&
receiver.includes(oldVal) &&
receiver.includes(val) &&
/* c8 ignore start */
bindMap.has(val)) {

@@ -1023,2 +1050,3 @@ const [elem] = bindMap.get(val);

else {
/* c8 ignore end */
returnSet = Reflect.set(target, key, val, receiver);

@@ -1039,3 +1067,11 @@ }

if (reactivityMap.has(oldVal)) {
reactivityMap.set(oldVal, reactivityMap.get(val));
// Store old reactivityMap if it is a swap operation
reuseElements && tmpSwap.set(oldVal, reactivityMap.get(oldVal));
if (tmpSwap.has(val)) {
reactivityMap.set(oldVal, tmpSwap.get(val));
tmpSwap.delete(val);
}
else {
reactivityMap.set(oldVal, reactivityMap.get(val));
}
}

@@ -1050,3 +1086,3 @@ }

// If oldVal is a Proxy - clean it
schedule(cleanProxy, oldVal);
!reuseElements && cleanProxy(oldVal);
return returnSet;

@@ -1116,2 +1152,3 @@ },

}
/* c8 ignore next 3 */
}

@@ -1136,2 +1173,3 @@ else {

reactivityMap.delete(proxy);
/* c8 ignore next 4 */
if (bindMap.has(proxy)) {

@@ -1262,31 +1300,40 @@ bindMap.get(proxy).forEach(removeElement);

}
function template(elem, placeholders, events) {
let wrapper = elem.content.cloneNode(true).firstChild;
let innerHTML = wrapper.innerHTML;
for (const [key, value] of Object.entries(placeholders)) {
innerHTML = innerHTML.replace(key, String(value));
}
wrapper.innerHTML = innerHTML;
setReactivity(wrapper.firstChild, events);
return wrapper.firstChild;
}
function view(root, data, renderFunction) {
getValue(data).forEach((item, i) => {
const elem = renderFunction(item, i);
$(root).appendChild(elem);
});
viewElements = true;
const rootElem = $(root);
const elements = getValue(data).map(renderFunction);
rootElem.append(...elements);
elements.forEach((elem) => runLifecyle(elem, onRenderMap));
viewElements = false;
observe(data, (newData, oldData) => {
const rootElem = $(root);
if (!newData?.length || oldData?.[0] !== newData?.[0]) {
rootElem.innerHTML = "";
/* c8 ignore start */
viewElements = true;
// Reset or re-use
if (!newData?.length ||
(!reuseElements && newData?.length === oldData?.length)) {
rootElem.textContent = "";
}
else if (reuseElements) {
for (let i = 0; i < oldData?.length && newData?.length; i++) {
oldData[i].id = newData[i].id;
oldData[i].label = newData[i].label;
newData[i] = oldData[i];
}
}
// Add to existing
if (oldData?.length && newData?.length > oldData?.length) {
rootElem.append(...newData.slice(oldData.length).map(renderFunction));
const length = oldData.length;
const slicedData = newData.slice(length);
const newElements = slicedData.map((item, i) => renderFunction(item, i + length));
rootElem.append(...newElements);
newElements.forEach((elem) => runLifecyle(elem, onRenderMap));
}
else {
newData?.forEach((item, i) => {
const elem = renderFunction(item, i);
rootElem.insertBefore(elem, null);
});
// Add new
else if (oldData?.length === 0 || (!reuseElements && newData?.length)) {
const elements = newData.map(renderFunction);
rootElem.append(...elements);
elements.forEach((elem) => runLifecyle(elem, onRenderMap));
}
viewElements = false;
/* c8 ignore end */
});

@@ -1300,2 +1347,2 @@ }

};
module.exports = { render, html, h, hydro, setGlobalSchedule, setReuseElements, setInsertDiffing, setShouldSetReactivity, reactive, unset, setAsyncUpdate, unobserve, observe, ternary, emit, watchEffect, internals, getValue, onRender, onCleanup, setReactivity, $, $$, template, view, };
module.exports = { render, html, h, hydro, setGlobalSchedule, setReuseElements, setInsertDiffing, setShouldSetReactivity, reactive, unset, setAsyncUpdate, unobserve, observe, ternary, emit, watchEffect, internals, getValue, onRender, onCleanup, setReactivity, $, $$, view, };

@@ -67,3 +67,2 @@ declare global {

declare function onCleanup(fn: Function, elem: ReturnType<typeof html>, ...args: Array<any>): void;
declare function template(elem: HTMLTemplateElement, placeholders: Record<string, any>, events: Record<string, any>): Element;
declare function view(root: string, data: reactiveObject<Array<any>>, renderFunction: (value: any, index: number) => Node): void;

@@ -84,2 +83,2 @@ declare const hydro: hydroObject;

};
export { render, html, h, hydro, setGlobalSchedule, setReuseElements, setInsertDiffing, setShouldSetReactivity, reactive, unset, setAsyncUpdate, unobserve, observe, ternary, emit, watchEffect, internals, getValue, onRender, onCleanup, setReactivity, $, $$, template, view, };
export { render, html, h, hydro, setGlobalSchedule, setReuseElements, setInsertDiffing, setShouldSetReactivity, reactive, unset, setAsyncUpdate, unobserve, observe, ternary, emit, watchEffect, internals, getValue, onRender, onCleanup, setReactivity, $, $$, view, };

@@ -19,2 +19,3 @@ // Safari Polyfills

const bindMap = new WeakMap(); // Bind an Element to Data. If the Data is being unset, the DOM Element disappears too.
const tmpSwap = new WeakMap(); // Take over keyToNodeMap if new value is a hydro Proxy. Save old reactivityMap entry here, in case for a swap operation. [if reuseElements]
const onRenderMap = new WeakMap(); // Lifecycle Hook that is being called after rendering

@@ -28,2 +29,3 @@ const onCleanupMap = new WeakMap(); // Lifecycle Hook that is being called when unmount function is being called

let shouldSetReactivity = true;
let viewElements = false;
const reactivityRegex = /\{\{((\s|.)*?)\}\}/;

@@ -177,3 +179,20 @@ const HTML_FIND_INVALID = /<(\/?)(html|head|body)(>|\s.*?>)/g;

const DOM = parser(DOMString);
const root = document.createNodeIterator(DOM, NodeFilter.SHOW_ELEMENT, {
// Delay Elemen iteration and manipulation after the elements have been added to the DOM.
if (viewElements) {
onRender(fillDOM, DOM.firstChild, DOM.firstChild, insertNodes, eventFunctions);
}
else {
fillDOM(DOM, insertNodes, eventFunctions);
}
// Return DocumentFragment
if (DOM.childNodes.length > 1)
return DOM;
// Return Text Node
if (!DOM.firstChild)
return document.createTextNode("");
// Return Element
return DOM.firstChild;
}
function fillDOM(elem, insertNodes, eventFunctions) {
const root = document.createNodeIterator(elem, NodeFilter.SHOW_ELEMENT, {
acceptNode(element) {

@@ -185,23 +204,18 @@ return element.localName.endsWith("-dummy" /* dummy */)

});
let elem;
while ((elem = root.nextNode())) {
const tag = elem.localName.replace("-dummy" /* dummy */, "");
let nextNode;
while ((nextNode = root.nextNode())) {
const tag = nextNode.localName.replace("-dummy" /* dummy */, "");
const replacement = document.createElement(tag);
//@ts-ignore
replacement.append(...elem.childNodes);
elem.replaceWith(replacement);
replacement.append(...nextNode.childNodes);
nextNode.replaceWith(replacement);
}
// Insert HTML Elements, which were stored in insertNodes
DOM.querySelectorAll("template[id^=lbInsertNodes]").forEach((template) => template.replaceWith(insertNodes.shift()));
elem
.querySelectorAll("template[id^=lbInsertNodes]")
.forEach((template) => template.replaceWith(insertNodes.shift()));
if (shouldSetReactivity)
setReactivity(DOM, eventFunctions);
// Return DocumentFragment
if (DOM.childNodes.length > 1)
return DOM;
// Return Text Node
if (!DOM.firstChild)
return document.createTextNode("");
// Return Element
return DOM.firstChild;
setReactivity(elem, eventFunctions);
}
/* c8 ignore start */
function h(name, props, ...children) {

@@ -211,8 +225,14 @@ if (isFunction(name))

const flatChildren = children
.map((child) =>
/* c8 ignore next 1 */
isObject(child) && !isNode(child) ? Object.values(child) : child)
.map((child) => isObject(child) && !isNode(child) ? Object.values(child) : child)
.flat();
return html `<${name} ${props || {}}>${flatChildren}</${name}>`;
const elem = document.createElement(name);
for (let i in props) {
//@ts-ignore
i in elem ? (elem[i] = props[i]) : setAttribute(elem, i, props[i]);
}
elem.append(...flatChildren);
onRender(setReactivity, elem, elem);
return elem;
}
/* c8 ignore end */
function setReactivity(DOM, eventFunctions) {

@@ -569,6 +589,9 @@ // Set events and reactive behaviour(checks for {{ key }} where key is on hydro)

const fn = lifecyleMap.get(node);
/* c8 ignore next 3 */
if (globalSchedule) {
if (viewElements) {
schedule(fn);
/* c8 ignore next 3 */
}
else if (globalSchedule) {
window.requestIdleCallback(fn);
}
else {

@@ -948,2 +971,3 @@ fn();

// Remove item from array
/* c8 ignore next 4 */
if (!internReset && Array.isArray(receiver)) {

@@ -967,4 +991,5 @@ receiver.splice(key, 1);

let subItem = receiver[key][i];
/* c8 ignore next 3 */
if (isObject(subItem) && isProxy(subItem)) {
subItem = null;
receiver[key][i] = null;
}

@@ -1002,5 +1027,7 @@ }

else {
if (Array.isArray(receiver) &&
if (!reuseElements &&
Array.isArray(receiver) &&
receiver.includes(oldVal) &&
receiver.includes(val) &&
/* c8 ignore start */
bindMap.has(val)) {

@@ -1023,2 +1050,3 @@ const [elem] = bindMap.get(val);

else {
/* c8 ignore end */
returnSet = Reflect.set(target, key, val, receiver);

@@ -1039,3 +1067,11 @@ }

if (reactivityMap.has(oldVal)) {
reactivityMap.set(oldVal, reactivityMap.get(val));
// Store old reactivityMap if it is a swap operation
reuseElements && tmpSwap.set(oldVal, reactivityMap.get(oldVal));
if (tmpSwap.has(val)) {
reactivityMap.set(oldVal, tmpSwap.get(val));
tmpSwap.delete(val);
}
else {
reactivityMap.set(oldVal, reactivityMap.get(val));
}
}

@@ -1050,3 +1086,3 @@ }

// If oldVal is a Proxy - clean it
schedule(cleanProxy, oldVal);
!reuseElements && cleanProxy(oldVal);
return returnSet;

@@ -1116,2 +1152,3 @@ },

}
/* c8 ignore next 3 */
}

@@ -1136,2 +1173,3 @@ else {

reactivityMap.delete(proxy);
/* c8 ignore next 4 */
if (bindMap.has(proxy)) {

@@ -1262,31 +1300,40 @@ bindMap.get(proxy).forEach(removeElement);

}
function template(elem, placeholders, events) {
let wrapper = elem.content.cloneNode(true).firstChild;
let innerHTML = wrapper.innerHTML;
for (const [key, value] of Object.entries(placeholders)) {
innerHTML = innerHTML.replace(key, String(value));
}
wrapper.innerHTML = innerHTML;
setReactivity(wrapper.firstChild, events);
return wrapper.firstChild;
}
function view(root, data, renderFunction) {
getValue(data).forEach((item, i) => {
const elem = renderFunction(item, i);
$(root).appendChild(elem);
});
viewElements = true;
const rootElem = $(root);
const elements = getValue(data).map(renderFunction);
rootElem.append(...elements);
elements.forEach((elem) => runLifecyle(elem, onRenderMap));
viewElements = false;
observe(data, (newData, oldData) => {
const rootElem = $(root);
if (!newData?.length || oldData?.[0] !== newData?.[0]) {
rootElem.innerHTML = "";
/* c8 ignore start */
viewElements = true;
// Reset or re-use
if (!newData?.length ||
(!reuseElements && newData?.length === oldData?.length)) {
rootElem.textContent = "";
}
else if (reuseElements) {
for (let i = 0; i < oldData?.length && newData?.length; i++) {
oldData[i].id = newData[i].id;
oldData[i].label = newData[i].label;
newData[i] = oldData[i];
}
}
// Add to existing
if (oldData?.length && newData?.length > oldData?.length) {
rootElem.append(...newData.slice(oldData.length).map(renderFunction));
const length = oldData.length;
const slicedData = newData.slice(length);
const newElements = slicedData.map((item, i) => renderFunction(item, i + length));
rootElem.append(...newElements);
newElements.forEach((elem) => runLifecyle(elem, onRenderMap));
}
else {
newData?.forEach((item, i) => {
const elem = renderFunction(item, i);
rootElem.insertBefore(elem, null);
});
// Add new
else if (oldData?.length === 0 || (!reuseElements && newData?.length)) {
const elements = newData.map(renderFunction);
rootElem.append(...elements);
elements.forEach((elem) => runLifecyle(elem, onRenderMap));
}
viewElements = false;
/* c8 ignore end */
});

@@ -1300,2 +1347,2 @@ }

};
export { render, html, h, hydro, setGlobalSchedule, setReuseElements, setInsertDiffing, setShouldSetReactivity, reactive, unset, setAsyncUpdate, unobserve, observe, ternary, emit, watchEffect, internals, getValue, onRender, onCleanup, setReactivity, $, $$, template, view, };
export { render, html, h, hydro, setGlobalSchedule, setReuseElements, setInsertDiffing, setShouldSetReactivity, reactive, unset, setAsyncUpdate, unobserve, observe, ternary, emit, watchEffect, internals, getValue, onRender, onCleanup, setReactivity, $, $$, view, };
{
"name": "hydro-js",
"version": "1.3.5",
"version": "1.4.0",
"description": "A lightweight reactive library",

@@ -33,3 +33,3 @@ "type": "module",

"@types/concurrently": "^6.0.1",
"@web/test-runner": "^0.13.3",
"@web/test-runner": "^0.13.4",
"@web/test-runner-playwright": "^0.8.5",

@@ -36,0 +36,0 @@ "concurrently": "^6.0.2",

@@ -1,6 +0,6 @@

<img align="right" alt="97% Coverage" src="coverage.svg">
<img align="right" alt="100% Coverage" src="coverage.svg">
# hydro-js
> A lightweight (~4.5K <em>compressed</em>) reactive UI library via template literal tags.<br> Support in all modern Browsers.
> A lightweight (below 5K <em>compressed</em>) reactive UI library via template literal tags.<br> Support in all modern Browsers.

@@ -300,2 +300,19 @@ ## Installation

### view
Render the elements whenever the data changes. It will handle the operation for deletion, addition, swapping etc. This defaults to a non-keyed solution but it can be changed by calling `setReuseElements` with false.
args:
- root: `string` (CSS selector)<br>
- data: `ReturnType<typeof reactive>`<br>
- renderFunction: `function`, args: item: `any`, i: `number`<br>
#### Example
```js
const data = reactive([{ id: 4, label: "Red Onions" }])
view('.table', data, (item, i) => <tr>Reactive: {data[i].id}, Non-reactive: {item.id}<tr>)
```
### emit

@@ -302,0 +319,0 @@

@@ -101,2 +101,3 @@ declare const window: any;

const bindMap = new WeakMap<hydroObject, Array<Element>>(); // Bind an Element to Data. If the Data is being unset, the DOM Element disappears too.
const tmpSwap = new WeakMap<hydroObject, keyToNodeMap>(); // Take over keyToNodeMap if new value is a hydro Proxy. Save old reactivityMap entry here, in case for a swap operation. [if reuseElements]
const onRenderMap = new WeakMap<ReturnType<typeof html>, Function>(); // Lifecycle Hook that is being called after rendering

@@ -111,2 +112,3 @@ const onCleanupMap = new WeakMap<ReturnType<typeof html>, Function>(); // Lifecycle Hook that is being called when unmount function is being called

let shouldSetReactivity = true;
let viewElements = false;

@@ -285,3 +287,30 @@ const reactivityRegex = /\{\{((\s|.)*?)\}\}/;

const root = document.createNodeIterator(DOM, NodeFilter.SHOW_ELEMENT, {
// Delay Elemen iteration and manipulation after the elements have been added to the DOM.
if (viewElements) {
onRender(
fillDOM,
DOM.firstChild as Element,
DOM.firstChild,
insertNodes,
eventFunctions
);
} else {
fillDOM(DOM, insertNodes, eventFunctions);
}
// Return DocumentFragment
if (DOM.childNodes.length > 1) return DOM;
// Return Text Node
if (!DOM.firstChild) return document.createTextNode("");
// Return Element
return DOM.firstChild as Element;
}
function fillDOM(
elem: DocumentFragment | Element,
insertNodes: Node[],
eventFunctions: eventFunctions
) {
const root = document.createNodeIterator(elem, NodeFilter.SHOW_ELEMENT, {
acceptNode(element: Element) {

@@ -293,28 +322,20 @@ return element.localName.endsWith(Placeholder.dummy)

});
let elem;
while ((elem = root.nextNode())) {
const tag = (elem as Element).localName.replace(Placeholder.dummy, "");
let nextNode;
while ((nextNode = root.nextNode())) {
const tag = (nextNode as Element).localName.replace(Placeholder.dummy, "");
const replacement = document.createElement(tag);
//@ts-ignore
replacement.append(...(elem as Element).childNodes);
(elem as Element).replaceWith(replacement);
replacement.append(...(nextNode as Element).childNodes);
(nextNode as Element).replaceWith(replacement);
}
// Insert HTML Elements, which were stored in insertNodes
DOM.querySelectorAll("template[id^=lbInsertNodes]").forEach((template) =>
template.replaceWith(insertNodes.shift()!)
);
elem
.querySelectorAll("template[id^=lbInsertNodes]")
.forEach((template) => template.replaceWith(insertNodes.shift()!));
if (shouldSetReactivity) setReactivity(DOM, eventFunctions);
// Return DocumentFragment
if (DOM.childNodes.length > 1) return DOM;
// Return Text Node
if (!DOM.firstChild) return document.createTextNode("");
// Return Element
return DOM.firstChild as Element;
if (shouldSetReactivity) setReactivity(elem, eventFunctions);
}
/* c8 ignore start */
function h(

@@ -328,9 +349,17 @@ name: string | ((...args: any[]) => ReturnType<typeof h>),

const flatChildren = children
.map((child) =>
/* c8 ignore next 1 */
.map((child: any) =>
isObject(child) && !isNode(child as Node) ? Object.values(child) : child
)
.flat();
return html`<${name} ${props || {}}>${flatChildren}</${name}>`;
const elem = document.createElement(name);
for (let i in props) {
//@ts-ignore
i in elem ? (elem[i] = props[i]) : setAttribute(elem, i, props[i]);
}
elem.append(...flatChildren);
onRender(setReactivity, elem, elem);
return elem;
}
/* c8 ignore end */
function setReactivity(DOM: Node, eventFunctions?: eventFunctions) {

@@ -776,5 +805,7 @@ // Set events and reactive behaviour(checks for {{ key }} where key is on hydro)

/* c8 ignore next 3 */
if (globalSchedule) {
if (viewElements) {
schedule(fn);
/* c8 ignore next 3 */
} else if (globalSchedule) {
window.requestIdleCallback(fn);
} else {

@@ -1226,2 +1257,3 @@ fn();

// Remove item from array
/* c8 ignore next 4 */
if (!internReset && Array.isArray(receiver)) {

@@ -1249,4 +1281,5 @@ receiver.splice((key as unknown) as number, 1);

let subItem = receiver[key][i];
/* c8 ignore next 3 */
if (isObject(subItem) && isProxy(subItem)) {
subItem = null;
receiver[key][i] = null;
}

@@ -1284,5 +1317,7 @@ }

if (
!reuseElements &&
Array.isArray(receiver) &&
receiver.includes(oldVal) &&
receiver.includes(val) &&
/* c8 ignore start */
bindMap.has(val)

@@ -1308,2 +1343,3 @@ ) {

} else {
/* c8 ignore end */
returnSet = Reflect.set(target, key, val, receiver);

@@ -1326,3 +1362,11 @@ }

if (reactivityMap.has(oldVal)) {
reactivityMap.set(oldVal, reactivityMap.get(val)!);
// Store old reactivityMap if it is a swap operation
reuseElements && tmpSwap.set(oldVal, reactivityMap.get(oldVal)!);
if (tmpSwap.has(val)) {
reactivityMap.set(oldVal, tmpSwap.get(val)!);
tmpSwap.delete(val);
} else {
reactivityMap.set(oldVal, reactivityMap.get(val)!);
}
}

@@ -1339,3 +1383,3 @@ }

// If oldVal is a Proxy - clean it
schedule(cleanProxy, oldVal);
!reuseElements && cleanProxy(oldVal);

@@ -1408,2 +1452,3 @@ return returnSet;

}
/* c8 ignore next 3 */
} else {

@@ -1429,2 +1474,3 @@ map.clear();

reactivityMap.delete(proxy);
/* c8 ignore next 4 */
if (bindMap.has(proxy)) {

@@ -1566,16 +1612,2 @@ bindMap.get(proxy)!.forEach(removeElement);

}
function template(
elem: HTMLTemplateElement,
placeholders: Record<string, any>,
events: Record<string, any>
) {
let wrapper = elem.content.cloneNode(true).firstChild as HTMLElement;
let innerHTML = wrapper.innerHTML;
for (const [key, value] of Object.entries(placeholders)) {
innerHTML = innerHTML.replace(key, String(value));
}
wrapper.innerHTML = innerHTML;
setReactivity(wrapper.firstChild!, events);
return wrapper.firstChild as Element;
}
function view(

@@ -1586,21 +1618,45 @@ root: string,

) {
getValue(data).forEach((item: any, i: number) => {
const elem = renderFunction(item, i);
$(root)!.appendChild(elem);
});
viewElements = true;
const rootElem = $(root)!;
const elements = getValue(data).map(renderFunction);
rootElem.append(...elements);
elements.forEach((elem) => runLifecyle(elem as Element, onRenderMap));
viewElements = false;
observe(data, (newData: typeof data, oldData: typeof data) => {
/* c8 ignore start */
viewElements = true;
observe(data, (newData: Array<any>, oldData: Array<any>) => {
const rootElem = $(root)!;
if (!newData?.length || oldData?.[0] !== newData?.[0]) {
rootElem.innerHTML = "";
// Reset or re-use
if (
!newData?.length ||
(!reuseElements && newData?.length === oldData?.length)
) {
rootElem.textContent = "";
} else if (reuseElements) {
for (let i = 0; i < oldData?.length && newData?.length; i++) {
oldData[i].id = newData[i].id;
oldData[i].label = newData[i].label;
newData[i] = oldData[i];
}
}
// Add to existing
if (oldData?.length && newData?.length > oldData?.length) {
rootElem.append(...newData.slice(oldData.length).map(renderFunction));
} else {
newData?.forEach((item, i) => {
const elem = renderFunction(item, i);
rootElem.insertBefore(elem, null);
});
const length = oldData.length;
const slicedData = newData.slice(length);
const newElements = slicedData.map((item, i) =>
renderFunction(item, i + length)
);
rootElem.append(...newElements);
newElements.forEach((elem) => runLifecyle(elem as Element, onRenderMap));
}
// Add new
else if (oldData?.length === 0 || (!reuseElements && newData?.length)) {
const elements = newData.map(renderFunction);
rootElem.append(...elements);
elements.forEach((elem) => runLifecyle(elem as Element, onRenderMap));
}
viewElements = false;
/* c8 ignore end */
});

@@ -1640,4 +1696,3 @@ }

$$,
template,
view,
};

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

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