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

literaljs

Package Overview
Dependencies
Maintainers
1
Versions
69
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

literaljs - npm Package Compare versions

Comparing version 2.0.3 to 2.0.5

build/index.js.map

262

build/index.js

@@ -1,260 +0,2 @@

'use strict';
var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
var Literal = {
component: component,
render: render
};
// Render takes components, string id of mounting point, and default state.
var render = function render(components, documentNodeID) {
var state = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
// Initialize Global Store For State
defineStore(state);
window.addEventListener('DOMContentLoaded', function () {
// Mounting Point For Application
var rootNode = document.getElementById(documentNodeID);
// TODO: Should parse HTML string into AST eventually?
// This will allow regular template markup to be
// used instead of only AST in components.
// Listens For State Update Event
stateListener(components, rootNode);
// Generate DOM Elements
var tree = createElements(components({ state: function state() {
return window.__LITERAL_STORE__;
} }));
// Append DOM Elements
rootNode.appendChild(tree);
});
};
var defineStore = function defineStore(state) {
return window.__LITERAL_STORE__ = state;
};
var stateListener = function stateListener(components, rootNode) {
// Listens For State Event And Diffs The AST And Modifies DOM
// Diff could be improved by batching state updates and then
// triggering diff.
// We can also improve this by moving the diff to a web worker
// to remove burden off of main thread when large state updates occur.
window.addEventListener('__LITERAL_UPDATE__', function (event) {
return Promise.all([components({ state: function state() {
return event.detail.oldState;
} }), components({ state: function state() {
return event.detail.newState;
} })]).then(function (_ref) {
var _ref2 = _slicedToArray(_ref, 2),
oldTree = _ref2[0],
newTree = _ref2[1];
return diffTrees(rootNode, newTree, oldTree);
}).catch(function () {});
});
};
var observeLifecycle = function observeLifecycle(node) {
// Responsible For Listening For And Triggering Mounted and Unmounted Events
var observer = new MutationObserver(function (mutations) {
mutations.forEach(function (mutation) {
var type = mutation.type;
if (type === 'childList') {
var addedNodes = mutation.addedNodes,
removedNodes = mutation.removedNodes;
Promise.all([triggerLifeCycleEvents('mounted', addedNodes), triggerLifeCycleEvents('unmounted', removedNodes)]);
}
});
});
var triggerLifeCycleEvents = function triggerLifeCycleEvents(lifeCycleName, nodes) {
if (nodes.length > 0) nodes.forEach(function (node) {
var event = new CustomEvent(lifeCycleName);
node.dispatchEvent(event);
});
};
observer.observe(node, { childList: true });
};
var createElements = function createElements(node) {
// Creates All DOM Elements Recursively
var mainKeys = ['children', 'element', 'text', 'events'];
var newNode = document.createElement(node.element);
// Observe LifeCycle Can possibly be improved by determining
// if mount or unmounted event listeners
// exist instead of applying to all nodes
observeLifecycle(newNode);
Object.entries(node).forEach(function (_ref3) {
var _ref4 = _slicedToArray(_ref3, 2),
key = _ref4[0],
value = _ref4[1];
if (key === 'text') createTextNode(value, newNode);
if (key === 'events') attachEvents(value, newNode);
if (key === 'children') value.map(createElements).forEach(newNode.appendChild.bind(newNode));
if (!mainKeys.includes(key)) newNode.setAttribute(key, value);
});
return newNode;
};
var createTextNode = function createTextNode(value, node) {
var textNode = document.createTextNode(value);
node.appendChild(textNode);
};
var attachEvents = function attachEvents(value, node) {
// Attach Array Or Object Events To Created Node
if (value instanceof Array) {
value.forEach(function (event) {
return node.addEventListener(event.type, event.action);
});
} else if (value instanceof Object) {
node.addEventListener(value.type, value.action);
}
};
var component = function component() {
var _ref5 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
_ref5$methods = _ref5.methods,
methods = _ref5$methods === undefined ? function () {} : _ref5$methods,
_ref5$render = _ref5.render,
render = _ref5$render === undefined ? function () {} : _ref5$render;
// This Function is a Thunk. Returns Markup with Updated State.
return function () {
var _ref6 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
_ref6$props = _ref6.props,
props = _ref6$props === undefined ? {} : _ref6$props,
_ref6$state = _ref6.state,
state = _ref6$state === undefined ? function () {
return window.__LITERAL_STORE__;
} : _ref6$state;
// getState is used directly in the view and pulls the state data and returns new object.
var getState = function getState() {
var currentState = state();
return Object.assign({}, currentState);
};
// setState pulls current state, modifies state, and returns and assigns new state object.
// setState calls can be improved by placing all changes into a stack/que like React does so
// updates can be batched.
// setState also dispatches the event to trigger diff. It passes the old and new state for diff.
var setState = function setState(object) {
var currentState = getState();
window.__LITERAL_STORE__ = Object.assign({}, currentState, object);
var storeChangeEvent = new CustomEvent('__LITERAL_UPDATE__', {
detail: {
newState: window.__LITERAL_STORE__,
oldState: currentState
}
});
return window.dispatchEvent(storeChangeEvent);
};
// Render passes getState, setState, props, and methods which can be created in the component
// And also have access to getState and setState.
return render({
getState: getState,
setState: setState,
props: props,
methods: methods({ getState: getState, setState: setState })
});
};
};
var diffTrees = function diffTrees(parent, newData, oldData) {
var index = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 0;
// This is responsible for diffing both AST and modifying DOM recursively.
// This could use a lot of work....lol
var targetNode = parent.childNodes[index];
if (!oldData && newData) {
if (oldData === false) {
parent.insertBefore(createElements(newData), targetNode);
} else if (oldData === undefined) {
parent.appendChild(createElements(newData));
}
} else if (!newData && oldData) {
parent.removeChild(targetNode);
} else if (newData) {
Promise.all([removeUndefinedKeys(targetNode, newData, oldData), updateNodes(parent, targetNode, newData, oldData)]);
if (newData.children || oldData.children) {
Promise.all([filterBooleanChildren(newData.children, oldData.children), filterBooleanChildren(oldData.children, newData.children)]).then(function (_ref7) {
var _ref8 = _slicedToArray(_ref7, 2),
newChildren = _ref8[0],
oldChildren = _ref8[1];
for (var i = 0; i < childrenLength(newChildren, oldChildren); i++) {
diffTrees(targetNode, newChildren[i], oldChildren[i], i);
}
});
}
}
};
var filterBooleanChildren = function filterBooleanChildren(firstChildrenBatch, secondChildrenBatch) {
return firstChildrenBatch.filter(function (n, i) {
return n !== false || secondChildrenBatch[i] !== false;
});
};
var childrenLength = function childrenLength(newChildren, oldChildren) {
var newLength = newChildren.length;
var oldLength = oldChildren.length;
return newLength >= oldLength ? newLength : oldLength;
};
var updateNodes = function updateNodes(parent, target, newNode, oldNode) {
Object.entries(newNode).forEach(function (_ref9) {
var _ref10 = _slicedToArray(_ref9, 2),
key = _ref10[0],
newVal = _ref10[1];
var oldVal = oldNode[key];
if (key === 'element' || key === 'text' && newVal !== oldVal) {
parent.replaceChild(createElements(newNode), target);
} else if (!['children', 'events', 'element', 'text'].includes(key) && (!oldVal || newVal !== oldVal)) {
updateAttr(target, key, newVal);
}
// else if (key === 'events') {
// Some events don't return the correct state like some console.logged state?
// Do I even need this in the diff ?
// }
});
};
var updateAttr = function updateAttr(target, name, value) {
target.setAttribute(name, value);
};
var removeUndefinedKeys = function removeUndefinedKeys(target, newData, oldData) {
Object.entries(oldData).forEach(function (_ref11) {
var _ref12 = _slicedToArray(_ref11, 2),
key = _ref12[0],
value = _ref12[1];
if (!newData[key]) removeAttr(target, key, value);
});
};
var removeAttr = function removeAttr(target, name, value) {
// Think about boolean types?
// if (typeof value === 'boolean') {
// removeBooleanProp(target, name);
target.removeAttribute(name);
};
module.exports.render = render;
module.exports.component = component;
module.exports = Literal;
var n={component:d,render:t},t=function(n,t,o){void 0===o&&(o={}),e(o),window.addEventListener("DOMContentLoaded",function(){var e=document.getElementById(t);i(n,e);var o=r(n({state:function(){return window.__LITERAL_STORE__}}));e.appendChild(o)})},e=function(n){return window.__LITERAL_STORE__=n},i=function(n,t){window.addEventListener("__LITERAL_UPDATE__",function(e){return Promise.all([n({state:function(){return e.detail.oldState}}),n({state:function(){return e.detail.newState}})]).then(function(n){return a(t,n[1],n[0])}).catch(function(){})})},r=function(n){var t=["children","element","text","events"],e=document.createElement(n.element);return function(n){var t=new MutationObserver(function(n){n.forEach(function(n){if("childList"===n.type){var t=n.removedNodes;Promise.all([e("mounted",n.addedNodes),e("unmounted",t)])}})}),e=function(n,t){t.length>0&&t.forEach(function(t){var e=new CustomEvent(n);t.dispatchEvent(e)})};t.observe(n,{childList:!0})}(e),Object.entries(n).forEach(function(n){var i=n[0],d=n[1];"text"===i&&o(d,e),"events"===i&&c(d,e),"children"===i&&d.map(r).forEach(e.appendChild.bind(e)),t.includes(i)||e.setAttribute(i,d)}),e},o=function(n,t){var e=document.createTextNode(n);t.appendChild(e)},c=function(n,t){n instanceof Array?n.forEach(function(n){return t.addEventListener(n.type,n.action)}):n instanceof Object&&t.addEventListener(n.type,n.action)},d=function(n){void 0===n&&(n={});var t=n.methods;void 0===t&&(t=function(){});var e=n.render;return void 0===e&&(e=function(){}),function(n){void 0===n&&(n={});var i=n.props;void 0===i&&(i={});var r=n.state;void 0===r&&(r=function(){return window.__LITERAL_STORE__});var o=function(){var n=r();return Object.assign({},n)},c=function(n){var t=o();window.__LITERAL_STORE__=Object.assign({},t,n);var e=new CustomEvent("__LITERAL_UPDATE__",{detail:{newState:window.__LITERAL_STORE__,oldState:t}});return window.dispatchEvent(e)};return e({getState:o,setState:c,props:i,methods:t({getState:o,setState:c})})}},a=function(n,t,e,i){void 0===i&&(i=0);var o=n.childNodes[i];!e&&t?!1===e?n.insertBefore(r(t),o):void 0===e&&n.appendChild(r(t)):!t&&e?n.removeChild(o):t&&(Promise.all([l(o,t,e),s(n,o,t,e)]),(t.children||e.children)&&Promise.all([u(t.children,e.children),u(e.children,t.children)]).then(function(n){for(var t=n[0],e=n[1],i=0;i<f(t,e);i++)a(o,t[i],e[i],i)}))},u=function(n,t){return n.filter(function(n,e){return!1!==n||!1!==t[e]})},f=function(n,t){var e=n.length,i=t.length;return e>=i?e:i},s=function(n,t,e,i){Object.entries(e).forEach(function(o){var c=o[0],d=o[1],a=i[c];"element"===c||"text"===c&&d!==a?n.replaceChild(r(e),t):["children","events","element","text"].includes(c)||a&&d===a||v(t,c,d)})},v=function(n,t,e){n.setAttribute(t,e)},l=function(n,t,e){Object.entries(e).forEach(function(e){var i=e[0];t[i]||h(n,i,e[1])})},h=function(n,t,e){n.removeAttribute(t)};module.exports=n;
//# sourceMappingURL=index.js.map
{
"name": "literaljs",
"version": "2.0.3",
"version": "2.0.5",
"description": "~1kb gzip JavaScript library for building user interfaces.",
"main": "build/index.js",
"scripts": {
"build": "babel index.js --out-file build/index.js",
"build": "microbundle",
"prepare": "npm run build",

@@ -16,4 +16,5 @@ "test": "echo \"Error: no test specified\" && exit 1"

"babel-cli": "^6.26.0",
"babel-preset-env": "^1.6.1"
"babel-preset-env": "^1.6.1",
"microbundle": "^0.4.3"
}
}

@@ -14,3 +14,2 @@ # LiteralJS

- **Babel Not Required**, just pick a mounting point and build stuff.
- **Small**: Only around 1kb in size.

@@ -26,49 +25,3 @@ - **Virtual DOM**: Diffing occurs on state update for more efficient DOM updates. Current and previous AST are diffed against each other.

## Getting Started
- [Example With CDN](#cdn-example)
- [Example With NPM](#npm-example)
### CDN Example
One of the easiest way to use LiteralJS is to use a CDN like so:
```html
<!DOCTYPE html>
<html>
<head>
<title>Literal JS</title>
<script src="http://unpkg.com/literaljs"></script>
</head>
<body>
<div id="app"></div>
<script>
var foo = Literal.component({
render: function(c) {
return {
element: 'div',
class: 'container',
text: `This is the Count: ${c.getState().count}`,
children: [
{
element: 'button',
text: 'Click Me!',
events: {
type: 'click',
action: function() {
var state = c.getState();
c.setState({ count: state.count + 1 });
}
}
}
]
};
}
});
Literal.render(foo, 'app', { count: 0 });
</script>
</body>
</html>
```
### NPM Example
#### Install

@@ -75,0 +28,0 @@ ```

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