Comparing version 0.0.9-beta.6 to 0.0.9-beta.7
@@ -1,6 +0,6 @@ | ||
import Solid, { ignore, onClean, unwrap, root } from 'solid-js'; | ||
import { S, ignore, onClean, unwrap, root } from 'solid-js'; | ||
function animate(obsv) { | ||
obsv = Solid(obsv); | ||
return Solid(async() => { | ||
obsv = S(obsv); | ||
return S(async() => { | ||
var v; | ||
@@ -27,4 +27,4 @@ if ((v = obsv.value) === void 0) { | ||
return function(obsv) { | ||
obsv = Solid(obsv); | ||
return Solid(async() => { | ||
obsv = S(obsv); | ||
return S(async() => { | ||
var v; | ||
@@ -44,4 +44,4 @@ if ((v = obsv.value) === void 0) { | ||
return function(obsv) { | ||
obsv = Solid(obsv); | ||
return Solid(() => { | ||
obsv = S(obsv); | ||
return S(() => { | ||
var v; | ||
@@ -65,4 +65,4 @@ if ((v = obsv.value) === void 0) { | ||
return function(obsv) { | ||
obsv = Solid(obsv); | ||
return Solid(() => { | ||
obsv = S(obsv); | ||
return S(() => { | ||
var v; | ||
@@ -251,4 +251,4 @@ if ((v = obsv.value) === void 0) { | ||
return function(obsv) { | ||
obsv = Solid(obsv); | ||
return Solid(() => { | ||
obsv = S(obsv); | ||
return S(() => { | ||
var v; | ||
@@ -267,2 +267,20 @@ if ((v = obsv.value) === void 0) { | ||
export { animate, delay$1 as delay, filter, map, memo, scan }; | ||
function tap(fn) { | ||
return function(obsv) { | ||
obsv = S(obsv); | ||
return S(() => { | ||
var v; | ||
if ((v = obsv.value) === void 0) { | ||
return; | ||
} | ||
ignore(() => { | ||
return fn(v); | ||
}); | ||
return v; | ||
}, { | ||
notifyAlways: true | ||
}); | ||
}; | ||
} | ||
export { animate, delay$1 as delay, filter, map, memo, scan, tap }; |
import $$observable from 'symbol-observable'; | ||
var Core, comparer; | ||
var Core, cancelTask, comparer, processUpdates; | ||
@@ -14,2 +14,47 @@ comparer = function(v, k, b, is_array, path, r) { | ||
cancelTask = function(handle, defer) { | ||
var index, q; | ||
q = defer ? Core.queues.deferred : Core.queues.current; | ||
index = handle - (q.nextHandle - q.tasks.length); | ||
if (q.nextIndex <= index) { | ||
return q.tasks[index] = null; | ||
} | ||
}; | ||
processUpdates = function(q, current) { | ||
var count, err, mark, task; | ||
count = 0; | ||
mark = 0; | ||
while (q.nextIndex < q.tasks.length) { | ||
if (!(task = q.tasks[q.nextIndex])) { | ||
q.nextIndex++; | ||
continue; | ||
} | ||
if (current && task.defer) { | ||
task.handle = void 0; | ||
queueTask(task, task.value); | ||
q.nextIndex++; | ||
continue; | ||
} | ||
if (q.nextIndex > mark) { | ||
if (count++ > 5000) { | ||
console.error('Exceeded max task recursion'); | ||
q.nextIndex = 0; | ||
return q.tasks = []; | ||
} | ||
mark = q.tasks.length; | ||
} | ||
try { | ||
task(task.value); | ||
task.handle = task.dhandle = task.value = void 0; | ||
} catch (error) { | ||
err = error; | ||
console.error(err); | ||
} | ||
q.nextIndex++; | ||
} | ||
q.nextIndex = 0; | ||
q.tasks = []; | ||
}; | ||
var Core$1 = Core = { | ||
@@ -58,47 +103,2 @@ context: null, | ||
var cancelTask = function(handle, defer) { | ||
var index, q; | ||
q = defer ? Core.queues.deferred : Core.queues.current; | ||
index = handle - (q.nextHandle - q.tasks.length); | ||
if (q.nextIndex <= index) { | ||
return q.tasks[index] = null; | ||
} | ||
}; | ||
var processUpdates = function(q, current) { | ||
var count, err, mark, task; | ||
count = 0; | ||
mark = 0; | ||
while (q.nextIndex < q.tasks.length) { | ||
if (!(task = q.tasks[q.nextIndex])) { | ||
q.nextIndex++; | ||
continue; | ||
} | ||
if (current && task.defer) { | ||
task.handle = void 0; | ||
queueTask(task, task.value); | ||
q.nextIndex++; | ||
continue; | ||
} | ||
if (q.nextIndex > mark) { | ||
if (count++ > 5000) { | ||
console.error('Exceeded max task recursion'); | ||
q.nextIndex = 0; | ||
return q.tasks = []; | ||
} | ||
mark = q.tasks.length; | ||
} | ||
try { | ||
task(task.value); | ||
task.handle = task.dhandle = task.value = void 0; | ||
} catch (error) { | ||
err = error; | ||
console.error(err); | ||
} | ||
q.nextIndex++; | ||
} | ||
q.nextIndex = 0; | ||
q.tasks = []; | ||
}; | ||
var run = function(fn) { | ||
@@ -144,3 +144,3 @@ var execute, prevQueue; | ||
} | ||
d = null; | ||
d = []; | ||
}); | ||
@@ -246,3 +246,3 @@ }); | ||
var S, Selector, Signal, Stream, counter, observableProvider, promiseProvider, resolveAsync$1, rxCompat, sequenceCounter; | ||
var S, Selector, Signal, Stream, counter, observableProvider, promiseProvider, resolveAsync, rxCompat, sequenceCounter; | ||
@@ -281,3 +281,3 @@ counter = 0; | ||
resolveAsync$1 = function(value, seq, obsv, fn) { | ||
resolveAsync = function(value, seq, obsv, fn) { | ||
if (!isObject(value)) { | ||
@@ -493,3 +493,3 @@ return fn(value); | ||
seq = ++sequenceCounter; | ||
return resolveAsync$1(value, seq, this, (value) => { | ||
return resolveAsync(value, seq, this, (value) => { | ||
if (this.__disposed || value === void 0 || (!this.notifyAlways && value === this._value && !isObject(value))) { | ||
@@ -1452,3 +1452,2 @@ return; | ||
export default Signal$1; | ||
export { index as State, index$1 as ImmutableState, Sync$1 as Sync, ignore, root, unwrap, isEqual, onClean, pipe }; | ||
export { index as State, index$1 as ImmutableState, Sync$1 as Sync, ignore, root, unwrap, isEqual, onClean, Signal$1 as S, pipe }; |
@@ -5,10 +5,7 @@ 'use strict'; | ||
function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } | ||
var solidJs = require('solid-js'); | ||
var Solid = require('solid-js'); | ||
var Solid__default = _interopDefault(Solid); | ||
function animate(obsv) { | ||
obsv = Solid__default(obsv); | ||
return Solid__default(async() => { | ||
obsv = solidJs.S(obsv); | ||
return solidJs.S(async() => { | ||
var v; | ||
@@ -35,4 +32,4 @@ if ((v = obsv.value) === void 0) { | ||
return function(obsv) { | ||
obsv = Solid__default(obsv); | ||
return Solid__default(async() => { | ||
obsv = solidJs.S(obsv); | ||
return solidJs.S(async() => { | ||
var v; | ||
@@ -52,4 +49,4 @@ if ((v = obsv.value) === void 0) { | ||
return function(obsv) { | ||
obsv = Solid__default(obsv); | ||
return Solid__default(() => { | ||
obsv = solidJs.S(obsv); | ||
return solidJs.S(() => { | ||
var v; | ||
@@ -59,3 +56,3 @@ if ((v = obsv.value) === void 0) { | ||
} | ||
if ((Solid.ignore(() => { | ||
if ((solidJs.ignore(() => { | ||
return fn(v); | ||
@@ -74,4 +71,4 @@ })) === void 0) { | ||
return function(obsv) { | ||
obsv = Solid__default(obsv); | ||
return Solid__default(() => { | ||
obsv = solidJs.S(obsv); | ||
return solidJs.S(() => { | ||
var v; | ||
@@ -81,3 +78,3 @@ if ((v = obsv.value) === void 0) { | ||
} | ||
return Solid.ignore(() => { | ||
return solidJs.ignore(() => { | ||
return fn(v); | ||
@@ -101,3 +98,3 @@ }); | ||
} | ||
Solid.onClean(function() { | ||
solidJs.onClean(function() { | ||
var d, k, len; | ||
@@ -113,3 +110,3 @@ for (k = 0, len = disposables.length; k < len; k++) { | ||
// non-arrays | ||
newListUnwrapped = Solid.unwrap(newList, true); | ||
newListUnwrapped = solidJs.unwrap(newList, true); | ||
if (!Array.isArray(newListUnwrapped)) { | ||
@@ -138,3 +135,3 @@ if ((newListUnwrapped == null) || newListUnwrapped === false) { | ||
list[0] = newListUnwrapped; | ||
return mapped[0] = Solid.root(function(dispose) { | ||
return mapped[0] = solidJs.root(function(dispose) { | ||
disposables[0] = dispose; | ||
@@ -163,3 +160,3 @@ return mapFn(newList); | ||
list[i] = newListUnwrapped[i]; | ||
mapped[i] = Solid.root(function(dispose) { | ||
mapped[i] = solidJs.root(function(dispose) { | ||
disposables[i] = dispose; | ||
@@ -240,3 +237,3 @@ if (trackIndex) { | ||
} else { | ||
mapped[j] = Solid.root(function(dispose) { | ||
mapped[j] = solidJs.root(function(dispose) { | ||
disposables[j] = dispose; | ||
@@ -266,4 +263,4 @@ if (trackIndex) { | ||
return function(obsv) { | ||
obsv = Solid__default(obsv); | ||
return Solid__default(() => { | ||
obsv = solidJs.S(obsv); | ||
return solidJs.S(() => { | ||
var v; | ||
@@ -273,3 +270,3 @@ if ((v = obsv.value) === void 0) { | ||
} | ||
return seed = Solid.ignore(() => { | ||
return seed = solidJs.ignore(() => { | ||
return fn(seed, v); | ||
@@ -283,2 +280,20 @@ }); | ||
function tap(fn) { | ||
return function(obsv) { | ||
obsv = solidJs.S(obsv); | ||
return solidJs.S(() => { | ||
var v; | ||
if ((v = obsv.value) === void 0) { | ||
return; | ||
} | ||
solidJs.ignore(() => { | ||
return fn(v); | ||
}); | ||
return v; | ||
}, { | ||
notifyAlways: true | ||
}); | ||
}; | ||
} | ||
exports.animate = animate; | ||
@@ -290,1 +305,2 @@ exports.delay = delay$1; | ||
exports.scan = scan; | ||
exports.tap = tap; |
102
lib/solid.js
@@ -9,3 +9,3 @@ 'use strict'; | ||
var Core, comparer; | ||
var Core, cancelTask, comparer, processUpdates; | ||
@@ -21,2 +21,47 @@ comparer = function(v, k, b, is_array, path, r) { | ||
cancelTask = function(handle, defer) { | ||
var index, q; | ||
q = defer ? Core.queues.deferred : Core.queues.current; | ||
index = handle - (q.nextHandle - q.tasks.length); | ||
if (q.nextIndex <= index) { | ||
return q.tasks[index] = null; | ||
} | ||
}; | ||
processUpdates = function(q, current) { | ||
var count, err, mark, task; | ||
count = 0; | ||
mark = 0; | ||
while (q.nextIndex < q.tasks.length) { | ||
if (!(task = q.tasks[q.nextIndex])) { | ||
q.nextIndex++; | ||
continue; | ||
} | ||
if (current && task.defer) { | ||
task.handle = void 0; | ||
queueTask(task, task.value); | ||
q.nextIndex++; | ||
continue; | ||
} | ||
if (q.nextIndex > mark) { | ||
if (count++ > 5000) { | ||
console.error('Exceeded max task recursion'); | ||
q.nextIndex = 0; | ||
return q.tasks = []; | ||
} | ||
mark = q.tasks.length; | ||
} | ||
try { | ||
task(task.value); | ||
task.handle = task.dhandle = task.value = void 0; | ||
} catch (error) { | ||
err = error; | ||
console.error(err); | ||
} | ||
q.nextIndex++; | ||
} | ||
q.nextIndex = 0; | ||
q.tasks = []; | ||
}; | ||
var Core$1 = Core = { | ||
@@ -65,47 +110,2 @@ context: null, | ||
var cancelTask = function(handle, defer) { | ||
var index, q; | ||
q = defer ? Core.queues.deferred : Core.queues.current; | ||
index = handle - (q.nextHandle - q.tasks.length); | ||
if (q.nextIndex <= index) { | ||
return q.tasks[index] = null; | ||
} | ||
}; | ||
var processUpdates = function(q, current) { | ||
var count, err, mark, task; | ||
count = 0; | ||
mark = 0; | ||
while (q.nextIndex < q.tasks.length) { | ||
if (!(task = q.tasks[q.nextIndex])) { | ||
q.nextIndex++; | ||
continue; | ||
} | ||
if (current && task.defer) { | ||
task.handle = void 0; | ||
queueTask(task, task.value); | ||
q.nextIndex++; | ||
continue; | ||
} | ||
if (q.nextIndex > mark) { | ||
if (count++ > 5000) { | ||
console.error('Exceeded max task recursion'); | ||
q.nextIndex = 0; | ||
return q.tasks = []; | ||
} | ||
mark = q.tasks.length; | ||
} | ||
try { | ||
task(task.value); | ||
task.handle = task.dhandle = task.value = void 0; | ||
} catch (error) { | ||
err = error; | ||
console.error(err); | ||
} | ||
q.nextIndex++; | ||
} | ||
q.nextIndex = 0; | ||
q.tasks = []; | ||
}; | ||
var run = function(fn) { | ||
@@ -151,3 +151,3 @@ var execute, prevQueue; | ||
} | ||
d = null; | ||
d = []; | ||
}); | ||
@@ -253,3 +253,3 @@ }); | ||
var S, Selector, Signal, Stream, counter, observableProvider, promiseProvider, resolveAsync$1, rxCompat, sequenceCounter; | ||
var S, Selector, Signal, Stream, counter, observableProvider, promiseProvider, resolveAsync, rxCompat, sequenceCounter; | ||
@@ -288,3 +288,3 @@ counter = 0; | ||
resolveAsync$1 = function(value, seq, obsv, fn) { | ||
resolveAsync = function(value, seq, obsv, fn) { | ||
if (!isObject(value)) { | ||
@@ -500,3 +500,3 @@ return fn(value); | ||
seq = ++sequenceCounter; | ||
return resolveAsync$1(value, seq, this, (value) => { | ||
return resolveAsync(value, seq, this, (value) => { | ||
if (this.__disposed || value === void 0 || (!this.notifyAlways && value === this._value && !isObject(value))) { | ||
@@ -1467,3 +1467,3 @@ return; | ||
exports.onClean = onClean; | ||
exports.default = Signal$1; | ||
exports.S = Signal$1; | ||
exports.pipe = pipe; |
{ | ||
"name": "solid-js", | ||
"description": "A declarative JavaScript library for building user interfaces.", | ||
"version": "0.0.9-beta.6", | ||
"version": "0.0.9-beta.7", | ||
"author": "Ryan Carniato", | ||
@@ -6,0 +6,0 @@ "license": "MIT", |
@@ -12,6 +12,7 @@ # Solid.js | ||
* ES6 Proxies to keep data access simple and POJO like | ||
* Promises and ES Observables are first class citizens: | ||
* Easy interopt with existing libraries that manage services and state | ||
* All computations and bindings when resolved to these automatically update asynchronously allowing for 100% pure data declarations. | ||
* In so Async Functions are first class citizens and computations can be written using them. | ||
* Promises and ES(RxJS) Observables are first class citizens: | ||
* Easy interopt with existing libraries that manage services and state. | ||
* All Solid Signals & Selectors are Observables and support RxJS pipeable operators | ||
* All Selectors and bindings when resolved to these automatically update asynchronously allowing for 100% pure data declarations. | ||
* Async Functions are first class citizens and Selectors can be written using them. | ||
* Truly just a render library | ||
@@ -21,3 +22,3 @@ * Unopinionated about how you set modularize/componentize your code | ||
* Use familiar techniques like HOCs, Class inheritance, dependency injection as you see fit. | ||
* Performance on par with the fastest Virtual DOM libraries | ||
* Performance exceeding the fastest Virtual DOM libraries. See Solid on [JS Framework Benchmark](https://github.com/krausest/js-framework-benchmark) | ||
@@ -27,4 +28,2 @@ <br /> | ||
import Solid, { State } from 'solid-js' | ||
function MyComponent() { | ||
@@ -47,5 +46,3 @@ state = new State({ | ||
Solid.root(=> | ||
mountEl.appendChild(MyComponent()) | ||
); | ||
root(() => mountEl.appendChild(MyComponent())); | ||
@@ -72,5 +69,5 @@ ## Solid State | ||
The use of the function allows for more control over the access to update the state object and is the key to reducing the use of unnecessary Proxies to allow for greater performance. | ||
This takes the form similar to ImmutableJS for set and setIn leaving all mutation control at the top level state object. | ||
But where the magic happens is with making computations. This done through State's select method which takes an Observable, a Promise, or a Function and maps it to a state property. The simplest form of passing a function will wrap it in an Observable which will automatically tracks dependencies. | ||
But where the magic happens is with making Selectors. This done through State's select method which takes an Observable, a Promise, or a Function and maps it to a state property. The simplest form of passing a function will wrap it in an Observable which will automatically tracks dependencies. | ||
@@ -83,5 +80,5 @@ state.select({ | ||
Whenever any dependency changes the State value will immediately update. Internally all JSX expressions also get wrapped in computations so for something as trivial as a display name you could just inline the expression in the template and have it update automatically. | ||
Whenever any dependency changes the State value will immediately update. Internally all JSX expressions also get wrapped in Selectors so for something as trivial as a display name you could just inline the expression in the template and have it update automatically. | ||
This is also primary mechanism to interopt with store technologies like Redux, Apollo, RxJS which expose themselves as Observables or Promises. When you hook up these selectors you can use standard methods to map the properties you want and the State object will automatically diff the changes to only affect the minimal amount. | ||
This is also primary mechanism to interopt with store technologies like Redux, Apollo, RxJS which expose themselves as Observables or Promises. When you hook up these Selectors you can use standard methods to map the properties you want and the State object will automatically diff the changes to only affect the minimal amount. | ||
@@ -96,11 +93,15 @@ props.select({ | ||
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. The well defined AST lends well to precompilation. This works so well it almost feels like cheating. I believe it's a big part of bringing the same level of tooling to fine grained change detection libraries already enjoyed by Virtual DOM libraries. | ||
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. | ||
To get setup add this babel plugin config to your .babelrc, webpack, or rollup config: | ||
"plugins": [["jsx-dom-expressions", {"moduleName": "Solid"}]] | ||
"plugins": ["jsx-dom-expressions"] | ||
And include at the top of your files: | ||
import r from 'solid-js/dom' | ||
## Why? | ||
This project started as trying to find a small performant library to work with Web Components, that had easy interopt with existing standards. It is very inspired by fine grain change detection libraries like Knockout.js and the radical approach taken by Cycle.js. I feel the API for those were a considerable barrier. At the same time, for all the really good things that came with React and the Virtual DOM evolution of UI frameworks it also felt like a bit of a step backwards. | ||
This project started as trying to find a small performant library to work with Web Components, that had easy interopt with existing standards. It is very inspired by fine grain change detection libraries like Knockout.js and the radical approach taken by Cycle.js. The idea here is to ease users into the world of Observable programming by keeping it transparent and starting simple. The Virtual DOM as seen in React for all it's advances has some signifigant trade offs: | ||
@@ -114,2 +115,3 @@ * The VDOM render while performant is still conceptually a constant re-render | ||
* Only served to make it more ambiguous when emerging best practices lead to specialized component classification anyway | ||
* Abstracts debugging to the point a <div /> is not longer just a div | ||
* VDOM libraries still are based around having a specialized data objects. | ||
@@ -127,14 +129,15 @@ | ||
* Renderer (JSX vs String Templates vs DOM Crawling, Virtual DOM vs Fine Grained vs Dirty Checking) | ||
* Change Management (Declarative Data vs Lifecycle, Mutable vs Immutable) | ||
* Container (JS Objects vs Web Components, Inheritance vs Function Composition) | ||
1. Renderer (JSX vs String Templates vs DOM Crawling, Virtual DOM vs Fine Grained vs Dirty Checking) | ||
2. Change Management (Declarative Data vs Lifecycle, Mutable vs Immutable) | ||
3. Container (JS Objects vs Web Components, Inheritance vs Function Composition) | ||
React takes care of all 3 and doesn't let you swap your solutions for each. Each these areas have different approaches and tradeoffs. Solid.js covers the first 2, but truthfully the focus is on the 2nd one, where the first is a separate project not specific to the library. Containers are not a concern here making it a great candidate for Web Components. | ||
React takes care of all 3 and doesn't let you swap your solutions for each. Each these areas have different approaches and tradeoffs. Solid.js focuses on 2, just touching on the first as needed. Containers are not a concern here making it a great candidate for Web Components. | ||
## Documentation | ||
* [Data Types](../master/documentation/data-types.md) | ||
* [State](../master/documentation/state.md) | ||
* [Components](../master/documentation/components.md) | ||
* [Mutability](../master/documentation/mutability.md) | ||
* [Scheduling](../master/documentation/scheduling.md) | ||
* [Observables](../master/documentation/observables.md) | ||
@@ -152,3 +155,3 @@ ## Related Projects | ||
This project is still a work in progress. Although I've been working on it for the past 2 years it's been evolving considerably. I've decided to open source this at this point to share the concept. It took discovering the approaches used by Surplus.js to fill the missing pieces this library needed to prove out it's concept. And now I believe we can have performance and a simple clean API. The focus has been API, correctness, performance, compatibility, in that order so there is a lot of work to be done. | ||
This project is still a work in progress. Although I've been working on it for the past 2 years it's been evolving considerably. I've decided to open source this at this point to share the concept. It took discovering the approaches used by Surplus.js to fill the missing pieces this library needed to prove out it's concept. And now I believe we can have performance and a simple clean API. | ||
@@ -155,0 +158,0 @@ Areas of Improvement: |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
142021
18
4077
151