Research
Security News
Malicious npm Packages Inject SSH Backdoors via Typosquatted Libraries
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
$ microbundle
Build output to build:
1.42 kB: index.js
1.44 kB: index.m.js
1.47 kB: index.umd.js
mounted
, updated
, and unmounted
lifecycle functions.The easiest way of getting started is by cloning the LiteralJS starter application located here:
Once you clone the project, you cd
to the directory and run the following commands:
$ npm install
$ npm run dev
// OR
$ yarn
$ yarn dev
This command is setup to launch a browser window and you should see a landing page. The project is also partially setup to deploy to Netlify if you want. Just make sure to use the build-netlify
command in the Netlify dashboard and set the deploy folder to dist
.
$ npm install literaljs
$ yarn add literaljs
const Literal = require('literaljs');
// OR
import Literal from 'literaljs';
// OR
import { component, render, h } from 'literaljs';
You can use 3 types of markup in the render!
const Foo = component({
render: ({ state, getState, setState }) => (
<div class='container'>
This is the Count: {state.count}
<button events={{ click: () => setState({ count: getState().count + 1 }) }}>
Click Me!
</button>
</div>
)
});
render(foo, 'app', { count: 0 });
const Foo = component({
render: ({ state, getState, setState }) =>
h('div', {
class: 'container',
text: `This is the Count: ${state.count}`
},
h('button', {
events: { click: () => setState({ count: getState().count + 1 }) }
})
);
});
render(foo, 'app', { count: 0 });
const Foo = component({
render: ({ state, getState, setState }) => ({
element: 'div',
class: 'container',
text: `This is the Count: ${state.count}`,
children: [
{
element: 'button',
text: 'Click Me!',
events: { click: () => setState({ count: getState().count + 1 }) }
}
]
})
});
render(foo, 'app', { count: 0 });
The component
function accepts objects with the following keys:
props
The props
of a component
is an object which can be passed with anything that is normally valid in a JavaScript Object. This can include any data or functions.
The only component that can not recieve props
is the root component that is passed to the Literal.render
function.
Example:
const Bar = component({
render: ({ props }) => (
<p>Total: {props.total}</p>
)
});
const Foo = component({
render: () => (
<div>{Bar({ total: 9 })}</div>
)
});
methods
The methods
key of a component
will accept a function which returns an object of other functions. Within the methods
, you also have access to a component
s getState
and setState
functions which can be used accordingly. You also, have access to created methods directly within the render
function.
getState
is a function which is accessible as a property of the methods
function.
Using the getState
function will pull the latest state objecty of your application. Once used, the specific state keys are accessible via dot notation.
setState
is a function which is accessible as a property of the methods
function.
Using the setState
function will cause the application state to update and diffing to occur.
Example:
component({
methods: ({ getState, setState }) => ({
increase: () => setState({ count: getState().count + 1 })
}),
render: ({ state, methods: { increase }}) => (
<button events={{ click: increase }}>
Current Count: {state.count}
</button>
)
});
render
The render
key of a component
accepts a function that returns an JavaScript Object.
JSX in LiteralJS has some differentiation when it comes to other implementations like JSX in React.
The biggest differentiator in syntax from React JSX is that the class
attribute is acceptable on JSX elements and events
are passed as either an Array or Objects or a single Object.
Event Objects need a key which is a DOM event name and function as a value. The events in LiteralJS are explained here.
Anything can be considered acceptable as attributes and any keys that work with LiteralJS Object Markup Syntax also work in LiteralJS JSX markup.
Example Of Single Event:
component({
methods: ({ getState, setState }) => ({
increase: () => setState({ count: getState().count + 1 })
}),
render: ({ state, methods: { increase }}) => (
<button events={{ click: () => increase() }}>
Current Count: {state.count}
</button>
)
});
Example Of Multiple Events:
component({
methods: ({ getState, setState }) => ({
increase: () => setState({ count: getState().count + 1 })
}),
render: ({ state, methods: { increase }}) => (
<button
events={{
mounted: () => console.log('Button Mounted'),
click: () => increase()
}}
>
Current Count: {state.count}
</button>
)
});
Object Markup is currently written with Objects with the following specified keys or strings and more not listed:
* = Required Key
The element
key in the render
function markup is the HTML node tag name as a String
. For example, an element
with the value
The element
key is required when generating a new DOM node.
Example:
component({
render: () => ({
element: 'div',
})
});
// Outputs: <div></div>
The text
key in the render
function markup accepts a String an will generate a text inside the element.
Example:
component({
render: () => ({
element: 'div',
text: 'Hello World!'
})
});
// Outputs: <div>Hello World!</div>
You can also include regular strings as children to create text nodes.
Example:
component({
render: () => ({
element: 'div',
children: ['Hello World!']
})
});
// Outputs: <div>Hello World!</div>
The class
key in the render
function markup is the HTML node class name as a String
.
Example:
component({
render: () => ({
element: 'div',
class: 'title'
})
});
// Outputs: <div class="title"></div>
The id
key in the render
function markup is the HTML node class name as a String
.
Example:
component({
render: () => ({
element: 'div',
id: '2'
})
});
// Outputs: <div id="2"></div>
The children
key in the render
function markup represet the childNodes
of a given element
or DOM Node. This key only accepts an Array of Objects or Strings. Each Object or in this Array can be another Object that represents a new DOM Node. You can also use Strings to represet Text nodes.
Example:
component({
render: () => ({
element: 'div',
children: [
'Count: ',
{
element: 'span'
text: '0'
}
]
})
});
// Outputs: <div>Count: <span>0</span></div>
The events
key in the render
function markup accepts either an Object.
An event object consists of the key
of the event name and the value
of a function to trigger:
Example:
// An Array Of Events
component({
render: () => ({
element: 'button',
text: 'Click Me!',
events: { click: () => console.log('Hello World!') }
})
});
// Output in Console: Hello World!
Besides the common event handlers like click
, there are two lifecycle events that LiteralJS
includes that can be attached to any DOM node.
To do so, just name the type
value unmounted
, updated
, or mounted
to trigger functions when a DOM node is first placed in the DOM or removed from the DOM.
Example: Example:
component({
render: () => ({
element: 'div',
text: 'I have a life!',
events: {
mounted: () => console.log('I\'m on the page!'),
updated: () => console.log('I\'m updated!'),
unmounted: () => console.log('I\'m off the page!')
}
})
});
Other typical keys are also accepted in a DOM object, such as data
, href
, and other custom keys depending on the element
.
Within the render
function of a component, you have access to other functions and objects:
state
(Object)The state
property is an Object of the current state and should only be used within markup and not functions or events.
getState
(Function -> Object)The getState
function of the component
s render
method will allow you to access the global store of your application within functions and events.
setState
(Function)The setState
function of the component
s render
method accepts an object which will allow you to set new values for particular pieces of state in the global store
props
(Object)The props
object of the component
s render method can contain any number of data types and functions. The only
componentthat cannot contain
propsis the root
componentthat is passed to the
Literal.render` method.
methods
(Object -> Functions)The methods
object allow you to access other functions defined directly in the component
. You can use this as a way to organize other pieces of logic and keep the render
function much cleaner.
The Literal.render
function is responsible for parsing the AST that is provided with component
s, injecting the generated markup into the specific DOM node, diffing any new changes based on state, and setting the default application state.
The Literal.render
function can accept 3 arguments, one of which is optional.
component
.id
of the DOM node to inject generated markup with.Example:
Literal.render(component, 'app', { count: 0 });
// or
render(component, 'app');
The Literal.h
function will generate specific LiteralJS Object Syntax.
If you want to use JSX, you can import the Literal.h
function and install the JSX transform plugin and add the pragma option to your .babelrc
file.
In .babelrc
:
{
"plugins": [["transform-react-jsx", { "pragma": "h" }]]
}
Some text editors and linters might also require the following at the top of the file to recognize that the file is using JSX:
/** @jsx h */
FAQs
A small JavaScript library for building reactive user interfaces.
The npm package literaljs receives a total of 6 weekly downloads. As such, literaljs popularity was classified as not popular.
We found that literaljs demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
Security News
MITRE's 2024 CWE Top 25 highlights critical software vulnerabilities like XSS, SQL Injection, and CSRF, reflecting shifts due to a refined ranking methodology.
Security News
In this segment of the Risky Business podcast, Feross Aboukhadijeh and Patrick Gray discuss the challenges of tracking malware discovered in open source softare.