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

solid-js

Package Overview
Dependencies
Maintainers
1
Versions
463
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

solid-js - npm Package Compare versions

Comparing version 0.3.0 to 0.3.1

4

CHANGELOG.md
# Changelog
## 0.3.1 - 2018-12-29
- Remove operators from core package since are auxilliary with new API.
- Updated JSX Dom Expressions to use new control flow JSX.
## 0.3.0 - 2018-12-25

@@ -4,0 +8,0 @@ - New setState API inspired by Falcor paths to handle ranges.

52

dist/dom.js

@@ -13,16 +13,20 @@ import { createRuntime } from 'babel-plugin-jsx-dom-expressions';

const r = createRuntime({wrap: S.makeComputationNode});
const r = createRuntime({wrap: S.makeComputationNode, root: S.root, cleanup: S.cleanup, sample: S.sample});
function selectWhen(signal, handler) {
if (typeof handler === 'string') handler = createHandler(handler);
return list => {
const cached = S(list);
S.makeComputationNode(element => {
const model = signal();
if (element) handler(element, false);
if (element = model && S.sample(cached).find(el => el.model === model)) handler(element, true);
return element;
});
return cached;
}
let start, end;
S.makeComputationNode(element => {
const model = signal();
if (element) handler(element, false);
let marker = start;
while(marker && marker !== end) {
if (marker.model === model) {
handler(marker, true);
return marker;
}
marker = marker.nextSibling;
}
});
return (s, e) => (start = s, end = e);
}

@@ -32,16 +36,18 @@

if (typeof handler === 'string') handler = createHandler(handler);
return list => {
const cached = S(list);
S.makeComputationNode(elements => {
const models = signal(),
newElements = S.sample(cached).filter(el => models.indexOf(el.model) > -1),
[additions, removals] = shallowDiff(newElements, elements);
additions.forEach(el => handler(el, true));
removals.forEach(el => handler(el, false));
return newElements;
});
return cached;
}
let start, end;
S.makeComputationNode(elements => {
const models = signal(), newElements = [];
let marker = start;
while(marker && marker !== end) {
if (models.indexOf(marker.model) > -1) newElements.push(marker);
marker = marker.nextSibling;
}
const [additions, removals] = shallowDiff(newElements, elements);
additions.forEach(el => handler(el, true));
removals.forEach(el => handler(el, false));
return newElements;
});
return (s, e) => (start = s, end = e);
}
export { r, selectWhen, selectEach };

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

import S from 's-js';
import S$1 from 's-js';

@@ -79,2 +79,24 @@ function comparer(v, k, b, isArray, path, r) {

// export observable
function observable(input) {
if (Symbol.observable in input) return input[Symbol.observable]();
return {
subscribe(observer) {
if (!(observer instanceof Object) || observer == null) {
throw new TypeError('Expected the observer to be an object.');
}
observer = observer.next || observer;
let complete = false;
S.on(input, function next() {
if (complete) return;
observer(input());
});
return {
unsubscribe() { complete = true; }
};
},
[Symbol.observable]() { return this; }
};
}
const SNODE = Symbol('solid-node'),

@@ -87,3 +109,3 @@ SPROXY = Symbol('solid-proxy');

const value = target[property];
if (S.isListening() && typeof value !== 'function') track(target, property, value);
if (S$1.isListening() && typeof value !== 'function') track(target, property, value);
return (!isObject(value) || typeof value === 'function' || value instanceof Element) ? value : wrap(value);

@@ -109,3 +131,3 @@ },

if (node = getDataNode(value)) {
if (!node._self) node._self = S.makeDataNode();
if (!node._self) node._self = S$1.makeDataNode();
node._self.current();

@@ -115,3 +137,3 @@ }

node = getDataNode(target);
node[property] || (node[property] = S.makeDataNode());
node[property] || (node[property] = S$1.makeDataNode());
node[property].current();

@@ -129,3 +151,6 @@ }

const notify = Array.isArray(state) || !(property in state);
if (value === void 0) delete state[property];
if (value === void 0) {
delete state[property];
if (Array.isArray(state)) state.length -= 1;
}
else state[property] = value;

@@ -196,3 +221,3 @@ trigger(getDataNode(state), property, notify);

const args = arguments;
S.freeze(() => {
S$1.freeze(() => {
if (Array.isArray(args[0])) {

@@ -216,176 +241,13 @@ for (let i = 0; i < args.length; i += 1)

function useMemo(fn, seed) { return S(fn, seed); }
function useMemo(fn, seed) { return S$1(fn, seed); }
function useSignal(value) { return S.data(value); }
function useSignal(value) { return S$1.data(value); }
function useEffect(fn, deps, defer) {
if (!deps) return S.effect(fn);
S.on(deps, fn, undefined, defer);
if (!deps) return S$1.effect(fn);
S$1.on(deps, fn, undefined, defer);
}
function pipe(input, ...fns) {
return compose(...fns)(input);
}
const { root, cleanup: useCleanup, sample, freeze } = S$1;
function compose(...fns) {
if (!fns) return i => i;
if (fns.length === 1) return fns[0];
return input => fns.reduce(((prev, fn) => fn(prev)), input);
}
function map(fn) {
return input => () => {
const value = input();
if (value === void 0) return;
return S.sample(() => fn(value));
}
}
function tap(fn) {
return input => () => {
const value = input();
if (value !== void 0) S.sample(() => fn(value));
return;
}
}
// memoized map that handles falsey rejection
function when(mapFn) {
let mapped, value, disposable;
S.cleanup(function dispose() {
disposable && disposable();
});
return map(function mapper(newValue) {
if (newValue == null || newValue === false) {
disposable && disposable();
return value = mapped = disposable = null;
}
if (value === newValue) return mapped;
disposable && disposable();
disposable = null;
value = newValue;
return mapped = S.root((d) => {
disposable = d;
return mapFn(value);
});
})
}
// Need to be able grab wrapped state internals so can't use S-Array
function each(mapFn) {
let mapped = [],
list = [],
disposables = [],
length = 0;
S.cleanup(function dispose() {
for (let i = 0; i < disposables.length; i++) disposables[i]();
});
return map(function mapper(newList) {
let i, j = 0,
newLength = (newList && newList.length) || 0;
if (newLength === 0) {
if (length !== 0) {
for (i = 0; i < length; i++) disposables[i]();
list = [];
mapped = [];
disposables = [];
length = 0;
}
} else if (length === 0) {
j = 0;
while (j < newLength) {
list[j] = newList[j];
mapped[j] = S.root(mappedFn);
j++;
}
length = newLength;
} else {
const newMapped = new Array(newLength),
tempDisposables = new Array(newLength),
indexedItems = new Map();
// reduce from both ends
let end = Math.min(length, newLength),
start = 0, item, itemIndex, newEnd;
while (start < end && newList[start] === list[start]) start++;
end = length - 1;
newEnd = newLength - 1;
while (end >= 0 && newEnd >= 0 && newList[newEnd] === list[end]) {
newMapped[newEnd] = mapped[end];
tempDisposables[newEnd] = disposables[end];
end--;
newEnd--;
}
// create indices
j = newEnd;
while (j >= start) {
item = newList[j];
itemIndex = indexedItems.get(item);
if (itemIndex != null) itemIndex.push(j);
else indexedItems.set(item, [j]);
j--;
}
// find old items
i = start;
while (i <= end) {
item = list[i];
itemIndex = indexedItems.get(item);
if (itemIndex != null && itemIndex.length > 0) {
j = itemIndex.pop();
newMapped[j] = mapped[i];
tempDisposables[j] = disposables[i];
} else disposables[i]();
i++;
}
// set all new values
j = start;
while (j < newLength) {
list[j] = newList[j];
if (newMapped.hasOwnProperty(j)) {
mapped[j] = newMapped[j];
disposables[j] = tempDisposables[j];
} else mapped[j] = S.root(mappedFn);
j++;
}
// truncate extra length
length = list.length = mapped.length = disposables.length = newLength;
}
return mapped;
function mappedFn(dispose) {
disposables[j] = dispose;
return mapFn(list[j], j);
}
});
}
// export observable
function observable(input) {
if (Symbol.observable in input) return input[Symbol.observable]();
return {
subscribe(observer) {
if (!(observer instanceof Object) || observer == null) {
throw new TypeError('Expected the observer to be an object.');
}
observer = observer.next || observer;
let complete = false;
S.on(input, function next() {
if (complete) return;
observer(input());
});
return {
unsubscribe() { complete = true; }
};
},
[Symbol.observable]() { return this; }
};
}
const { root, cleanup: useCleanup, sample, freeze } = S;
export { root, useCleanup, sample, freeze, unwrap, useState, reconcile, useMemo, useSignal, useEffect, pipe, compose, map, tap, when, each, observable };
export { root, useCleanup, sample, freeze, unwrap, observable, useState, reconcile, useMemo, useSignal, useEffect };
# API
## `root(disposer => <code>)`
### `root(disposer => <code>)`
Creates a new non-tracked context that doesn't auto-dispose. All Solid code should be wrapped in one of these top level as they ensure that all memory/computations are freed up.
## `useState(initValue): [state, setState]`
### `useState(initValue): [state, setState]`
Creates a new State object and setState pair that can be used to maintain your componenents state.
## `useEffect(() => <code>, dependencies, defer)`
### `useEffect(() => <code>, dependencies, defer)`
Creates a new effect that automatically tracks dependencies. The 2nd optional argument is an explicit array of dependencies. The 3rd optional argument is whether to defer initial execution of the effect until a value has changed (this only works with explicit dependencies).
## `useSignal(initialValue): signal`
### `useSignal(initialValue): signal`
Creates a new signal that can be used for reactive tracking.
## `useMemo(prev => <code>, initialValue): signal`
### `useMemo(prev => <code>, initialValue): signal`
Creates a readonly signal that recalculates it's value whenever the executed codes dependencies update.
## `useCleanup(() => <code>)`
### `useCleanup(() => <code>)`
Registers a cleanup method that performs that executes on disposal or recalculation of the current context.
## `sample(() => <code>): any`
### `sample(() => <code>): any`
Ignores tracking any of the dependencies in the executing code block and returns the value.
## `freeze(() => <code>): any`
### `freeze(() => <code>): any`
Ensures that all updates within the block happen at the same time to prevent unnecessary recalculation. Solid State's setState method and computations(useEffect, useMemo) automatically wrap their code in freeze blocks.

@@ -20,6 +20,21 @@ # Rendering

## Operators
## Control Flow
Most operators are general purpose. However there a couple included in this library to handle the common case of selection/multi-selection. These are often present through selection, hover effects etc.. The following operators optimize large lists down to one computation instead of n. They use the model property to identify context. And only execute their handler method on contexts that are entering or exiting selected state.
While you could use a map function for loops and raw ternary operators of conditionals they aren't optimized. While perhaps not as big of a deal in the VDOM since Solid is designed to not execute all the code from top down repeatedly we rely on techniques like isolated contexts and memoization. This is complicated and requires special methods. To keep things simple and optimizable the the renderer uses a special JSX tag (<$>) for control flow. Current 'each' and 'when' are supported.
```jsx
<ul>
<$ each={ state.users }>{
user => <li>
<div>{( user.firstName )}</div>
<$ when={ user.stars > 100 }>{
() => <div>Verified</div>
}</$>
</li>
}</$>
</ul>
```
The library also includes a couple afterRender hooks for this element.
### selectWhen(signal, handler)

@@ -26,0 +41,0 @@ ### selectEach(signal, handler)

# Signals
Signals are the glue that hold the library together. They often are invisible but interact in very powerful ways that you get more familiar with Solid they unlock a lot of potential. So consider this an intermediate topic.
Signals are the glue that hold the library together. They often are invisible but interact in very powerful ways that you get more familiar with Solid they unlock a lot of potential.

@@ -5,0 +5,0 @@ At it's core Solid uses [S.js](https://github.com/adamhaile/S) to propagate it's change detection. Signals are a simple primitive that contain values that change over time. With Signals you can track sorts of changes from various sources in your applications. Solid's State object is built from a Proxy over a tree of Signals. You can update a Signal manually or from any Async source.

@@ -19,16 +19,20 @@ 'use strict';

const r = babelPluginJsxDomExpressions.createRuntime({wrap: S.makeComputationNode});
const r = babelPluginJsxDomExpressions.createRuntime({wrap: S.makeComputationNode, root: S.root, cleanup: S.cleanup, sample: S.sample});
function selectWhen(signal, handler) {
if (typeof handler === 'string') handler = createHandler(handler);
return list => {
const cached = S(list);
S.makeComputationNode(element => {
const model = signal();
if (element) handler(element, false);
if (element = model && S.sample(cached).find(el => el.model === model)) handler(element, true);
return element;
});
return cached;
}
let start, end;
S.makeComputationNode(element => {
const model = signal();
if (element) handler(element, false);
let marker = start;
while(marker && marker !== end) {
if (marker.model === model) {
handler(marker, true);
return marker;
}
marker = marker.nextSibling;
}
});
return (s, e) => (start = s, end = e);
}

@@ -38,14 +42,16 @@

if (typeof handler === 'string') handler = createHandler(handler);
return list => {
const cached = S(list);
S.makeComputationNode(elements => {
const models = signal(),
newElements = S.sample(cached).filter(el => models.indexOf(el.model) > -1),
[additions, removals] = shallowDiff(newElements, elements);
additions.forEach(el => handler(el, true));
removals.forEach(el => handler(el, false));
return newElements;
});
return cached;
}
let start, end;
S.makeComputationNode(elements => {
const models = signal(), newElements = [];
let marker = start;
while(marker && marker !== end) {
if (models.indexOf(marker.model) > -1) newElements.push(marker);
marker = marker.nextSibling;
}
const [additions, removals] = shallowDiff(newElements, elements);
additions.forEach(el => handler(el, true));
removals.forEach(el => handler(el, false));
return newElements;
});
return (s, e) => (start = s, end = e);
}

@@ -52,0 +58,0 @@

@@ -7,3 +7,3 @@ 'use strict';

var S = _interopDefault(require('s-js'));
var S$1 = _interopDefault(require('s-js'));

@@ -86,2 +86,24 @@ function comparer(v, k, b, isArray, path, r) {

// export observable
function observable(input) {
if (Symbol.observable in input) return input[Symbol.observable]();
return {
subscribe(observer) {
if (!(observer instanceof Object) || observer == null) {
throw new TypeError('Expected the observer to be an object.');
}
observer = observer.next || observer;
let complete = false;
S.on(input, function next() {
if (complete) return;
observer(input());
});
return {
unsubscribe() { complete = true; }
};
},
[Symbol.observable]() { return this; }
};
}
const SNODE = Symbol('solid-node'),

@@ -94,3 +116,3 @@ SPROXY = Symbol('solid-proxy');

const value = target[property];
if (S.isListening() && typeof value !== 'function') track(target, property, value);
if (S$1.isListening() && typeof value !== 'function') track(target, property, value);
return (!isObject(value) || typeof value === 'function' || value instanceof Element) ? value : wrap(value);

@@ -116,3 +138,3 @@ },

if (node = getDataNode(value)) {
if (!node._self) node._self = S.makeDataNode();
if (!node._self) node._self = S$1.makeDataNode();
node._self.current();

@@ -122,3 +144,3 @@ }

node = getDataNode(target);
node[property] || (node[property] = S.makeDataNode());
node[property] || (node[property] = S$1.makeDataNode());
node[property].current();

@@ -136,3 +158,6 @@ }

const notify = Array.isArray(state) || !(property in state);
if (value === void 0) delete state[property];
if (value === void 0) {
delete state[property];
if (Array.isArray(state)) state.length -= 1;
}
else state[property] = value;

@@ -203,3 +228,3 @@ trigger(getDataNode(state), property, notify);

const args = arguments;
S.freeze(() => {
S$1.freeze(() => {
if (Array.isArray(args[0])) {

@@ -223,176 +248,13 @@ for (let i = 0; i < args.length; i += 1)

function useMemo(fn, seed) { return S(fn, seed); }
function useMemo(fn, seed) { return S$1(fn, seed); }
function useSignal(value) { return S.data(value); }
function useSignal(value) { return S$1.data(value); }
function useEffect(fn, deps, defer) {
if (!deps) return S.effect(fn);
S.on(deps, fn, undefined, defer);
if (!deps) return S$1.effect(fn);
S$1.on(deps, fn, undefined, defer);
}
function pipe(input, ...fns) {
return compose(...fns)(input);
}
const { root, cleanup: useCleanup, sample, freeze } = S$1;
function compose(...fns) {
if (!fns) return i => i;
if (fns.length === 1) return fns[0];
return input => fns.reduce(((prev, fn) => fn(prev)), input);
}
function map(fn) {
return input => () => {
const value = input();
if (value === void 0) return;
return S.sample(() => fn(value));
}
}
function tap(fn) {
return input => () => {
const value = input();
if (value !== void 0) S.sample(() => fn(value));
return;
}
}
// memoized map that handles falsey rejection
function when(mapFn) {
let mapped, value, disposable;
S.cleanup(function dispose() {
disposable && disposable();
});
return map(function mapper(newValue) {
if (newValue == null || newValue === false) {
disposable && disposable();
return value = mapped = disposable = null;
}
if (value === newValue) return mapped;
disposable && disposable();
disposable = null;
value = newValue;
return mapped = S.root((d) => {
disposable = d;
return mapFn(value);
});
})
}
// Need to be able grab wrapped state internals so can't use S-Array
function each(mapFn) {
let mapped = [],
list = [],
disposables = [],
length = 0;
S.cleanup(function dispose() {
for (let i = 0; i < disposables.length; i++) disposables[i]();
});
return map(function mapper(newList) {
let i, j = 0,
newLength = (newList && newList.length) || 0;
if (newLength === 0) {
if (length !== 0) {
for (i = 0; i < length; i++) disposables[i]();
list = [];
mapped = [];
disposables = [];
length = 0;
}
} else if (length === 0) {
j = 0;
while (j < newLength) {
list[j] = newList[j];
mapped[j] = S.root(mappedFn);
j++;
}
length = newLength;
} else {
const newMapped = new Array(newLength),
tempDisposables = new Array(newLength),
indexedItems = new Map();
// reduce from both ends
let end = Math.min(length, newLength),
start = 0, item, itemIndex, newEnd;
while (start < end && newList[start] === list[start]) start++;
end = length - 1;
newEnd = newLength - 1;
while (end >= 0 && newEnd >= 0 && newList[newEnd] === list[end]) {
newMapped[newEnd] = mapped[end];
tempDisposables[newEnd] = disposables[end];
end--;
newEnd--;
}
// create indices
j = newEnd;
while (j >= start) {
item = newList[j];
itemIndex = indexedItems.get(item);
if (itemIndex != null) itemIndex.push(j);
else indexedItems.set(item, [j]);
j--;
}
// find old items
i = start;
while (i <= end) {
item = list[i];
itemIndex = indexedItems.get(item);
if (itemIndex != null && itemIndex.length > 0) {
j = itemIndex.pop();
newMapped[j] = mapped[i];
tempDisposables[j] = disposables[i];
} else disposables[i]();
i++;
}
// set all new values
j = start;
while (j < newLength) {
list[j] = newList[j];
if (newMapped.hasOwnProperty(j)) {
mapped[j] = newMapped[j];
disposables[j] = tempDisposables[j];
} else mapped[j] = S.root(mappedFn);
j++;
}
// truncate extra length
length = list.length = mapped.length = disposables.length = newLength;
}
return mapped;
function mappedFn(dispose) {
disposables[j] = dispose;
return mapFn(list[j], j);
}
});
}
// export observable
function observable(input) {
if (Symbol.observable in input) return input[Symbol.observable]();
return {
subscribe(observer) {
if (!(observer instanceof Object) || observer == null) {
throw new TypeError('Expected the observer to be an object.');
}
observer = observer.next || observer;
let complete = false;
S.on(input, function next() {
if (complete) return;
observer(input());
});
return {
unsubscribe() { complete = true; }
};
},
[Symbol.observable]() { return this; }
};
}
const { root, cleanup: useCleanup, sample, freeze } = S;
exports.root = root;

@@ -403,2 +265,3 @@ exports.useCleanup = useCleanup;

exports.unwrap = unwrap;
exports.observable = observable;
exports.useState = useState;

@@ -409,8 +272,1 @@ exports.reconcile = reconcile;

exports.useEffect = useEffect;
exports.pipe = pipe;
exports.compose = compose;
exports.map = map;
exports.tap = tap;
exports.when = when;
exports.each = each;
exports.observable = observable;
{
"name": "solid-js",
"description": "A declarative JavaScript library for building user interfaces.",
"version": "0.3.0",
"version": "0.3.1",
"author": "Ryan Carniato",

@@ -20,3 +20,3 @@ "license": "MIT",

"peerDependencies": {
"babel-plugin-jsx-dom-expressions": "~0.2.0",
"babel-plugin-jsx-dom-expressions": "~0.3.0",
"s-js": "~0.4.9"

@@ -26,7 +26,6 @@ },

"jest": "~23.6.0",
"rollup": "^0.67.0",
"rollup-plugin-node-resolve": "^3.4.0",
"s-js": "~0.4.9",
"zen-observable": "^0.8.11"
"rollup": "^1.0.0",
"rollup-plugin-node-resolve": "^4.0.0",
"s-js": "~0.4.9"
}
}

@@ -12,9 +12,4 @@ # Solid.js

* ES6 Proxies to keep data access simple and POJO like
* Easy Promises and ES Observables interoptability:
* Easy interopt with existing libraries that manage services and state.
* Expandable custom operators and binding directives.
* Truly just a render library
* Unopinionated about how you set modularize/componentize your code
* The whole tree is only rendered once so statefulness is not a decider for the use of functional components
* Use familiar techniques like HOCs, Class inheritance, dependency injection as you see fit.
* Immutable interface with performance of mutability.
* Performance amongst the fastest libraries. See Solid on [JS Framework Benchmark](https://github.com/krausest/js-framework-benchmark)

@@ -26,22 +21,11 @@

```jsx
import { useState, root } from 'solid-js'
import { root } from 'solid-js'
function MyComponent() {
const [state, setState] = useState({
users: [{
id: 1, firstName: 'John', lastName: 'Smith'
}, {
id: 2, firstName: 'Jane', lastName: 'Smith'
}]
});
return (<>
const MyComponent = props =>
<>
<h1>Welcome</h1>
<ul>{
state.users.map(user => <li>{( user.firstName )} {( user.lastName )}</li>)
}</ul>
</>);
}
<p>Hello {props.name}</p>
</>
root(() => mountEl.appendChild(<MyComponent />));
root(() => mountEl.appendChild(<MyComponent name='Taylor' />));
```

@@ -59,7 +43,14 @@

```js
const [state, setState] = useState({counter: 0});
setState({
counter: state.counter + 1
});
```jsx
import { root, useState } from 'solid-js'
const CountingComponent = () => {
const [state, setState] = useState({counter: 0}),
interval = setInterval(() => setState({
counter: state.counter + 1
}), 1000);
useCleanup(() => clearInterval(interval));
return <div>{state.counter}</div>
}
```

@@ -114,3 +105,3 @@

JSX as a templating language brings a lot of benefits. The just being javascript goes beyond just not needing a DSL, but setting up closure based context instead of creating context objects. This is both much more performant and uses considerable less memory.
JSX as a templating language brings a lot of benefits. The just being javascript goes beyond just not needing a DSL, but setting up closure based context instead of creating context objects. This is more transparent and easier to follow and debug.

@@ -129,2 +120,39 @@ To get setup add this babel plugin config to your .babelrc, webpack, or rollup config:

## Components
Templates in Solid are just Pascal(Capital) cased functions. Their first argument is an props object and generally return their DOM nodes to render. Other than that nothing is special about them. Unlike Virtual Dom libraries these functions can contain state as they are not called repeatedly but only executed on initial creation.
Since the all nodes from JSX are actual DOM nodes the only responsibility of top level Templates/Components is appending to the DOM. Since contexts/lifecycle management is independent of code modularization through registering event handlers Solid Templates are sufficient as is to act as Components, or Solid fits easily into other Component structures like Web Components.
```jsx
import { useState, root } from 'solid-js'
class Component extends HTMLElement {
constructor () {
const [state, setState] = useState({}),
[props, __setProps] = useState({});
Object.assign(this, {state, setState, props, __setProps});
}
connectedCallback() {
this.attachShadow({mode: 'open'});
root(() => this.shadowRoot.appendChild(this.render());
}
attributeChangedCallback(attr, oldVal, newVal) {
this.__setProps({[attr]: newVal});
}
}
class MyComponent extends Component {
constuctor () {
super();
this.setState({greeting: 'World'});
}
render() {
return <div>Hello {(state.greeting)}</div>
}
}
```
## Why?

@@ -155,5 +183,3 @@

* [State](../master/documentation/state.md)
* [Components](../master/documentation/components.md)
* [Signals](../master/documentation/signals.md)
* [Operators](../master/documentation/operators.md)
* [Rendering](../master/documentation/rendering.md)

@@ -160,0 +186,0 @@ * [API](../master/documentation/api.md)

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

const { root, useState, useSignal, useEffect, reconcile, cleanup } = require('../lib/solid');
const { root, useState, useSignal, useEffect, reconcile } = require('../lib/solid');

@@ -3,0 +3,0 @@ describe('setState', () => {

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