Giter VIP home page Giter VIP logo

it-depends's People

Contributors

gerich-home avatar vandalkvist avatar

Stargazers

 avatar

Watchers

 avatar  avatar  avatar

it-depends's Issues

promiseValue reject

When underlying promise in promiseValue is rejected, promiseValue should start throwing exception on access.

Publish typings to https://github.com/typings/registry

Typings are generated during the build now.
We need to publish them to the https://github.com/typings/registry so that it will be possible to run typings install it-depends, then edit your tsconfig.json in the following way:

{
    "compilerOptions": {
        "module": "commonjs",
        "target": "es5",
        "noImplicitAny": false,
        "sourceMap": false
    },
    "files": [
        "index.ts",
        "typings/main.d.ts"
    ]
}

and get compile error

index.ts(6,36): error TS2345: Argument of type '() => number' is not assignable to parameter of type 'ICalculator<string>'.
  Type 'number' is not assignable to type 'string'.

when running tsc for the following index.ts file:

import * as itDepends from 'it-depends'

var x = itDepends.value<number>(1);
x.onChange(()=>x.write(2));

var y = itDepends.computed<string>(()=>{
    return x();
});

I tried to install typings from local filesystem and they work great!
Just run smth like typings install it-depends=file:..\it-depends\out\definitions\it-depends.d.ts --save and it will generate typing file similar to this: https://gist.github.com/gerich-home/c23f5c81c1d5bd0c39df6cba5d68029c

We just need to automate it for release process.

Typescript lint error - ISubscription is not assignable to type {Function, Function}

I have typescript lint error in https://github.com/gerich-home/it-depends/blob/master/src/computed.ts#L153 line (ISubscription is not assignable to type {Function, Function}).

self.onChange = function(handler: IComputedValueChangeHandler<T>): ISubscription {

Actually, I don't have experience in TypeScript language. But after a little investigation I found that

export type IComputed<T> = IComputedValue<T> | IWritableComputedValue<T>

line is cause of the error. So, here is union operator with different constructors. So, my question is: Does it depend on version of TypeScript? Do you have an error there like me?

Parametric computeds?

Sometimes the list of all computed values in your program is not known apriori.
In that case you have to create an array that will store computeds for each value.
There is an idea to introduce parametric computeds. You will be able to "curry" some parametrs that will be passed to your computed.
The calculated value will be cached and associated with the passed parameters

var c = itDepends.value(1);
var d = itDepends.computed(function(a, b) {
    return Math.sqrt(b*b - 4*a*c());
});

console.log(d(2, 1)); // calculation
console.log(d(2, 1)); // cached value
console.log(d(10, 5)); // calculation
console.log(d(10, 5)); // cached value
console.log(d(2, 1)); // cached value
c(2);
console.log(d(10, 5)); // calculation
console.log(d(2, 1)); // calculation
console.log(d(2, 1)); // cached value

Concerns
Parametric syntax conflicts with writable computed syntax. Idea is to make a breaking changeand introduce explicit write method
There should be also some kind of curry method, so you will be able to get the child computed with fixed set of parameters

var d21 = d.with(2, 1);
console.log(d21());

Per scenario performance comparison tests

There should be an ability to compare performance of certain scenarios (not versus KnockoutJS)
For example I know at least 2 tests I want to write that way.

  • Example 1

Given the following definitions:

var x = [];
for (var j = 0; j < dependenciesCount; j++) {
    x.push(itDepends.value(-1));
}

var a = itDepends.computed(function() {
    var z = 0;
    for (var j = 0; j < dependenciesCount; j++) {
        z += x[j]();
    }
    return z;
});

var b = itDepends.value(true);

var c = itDepends.computed(function() {
    return b() ? a() : 0;
});

the scenario:

itDepends.bulkChange(function() {
    c.onChange(function() {});
    b.write(false);
});

should work faster than scenario with approximately the same performance as in the following scenario (see #68):

c.onChange(function() {});
b.write(false);
  • Example 2

Given the following definitions:

var x = [];
for (var j = 0; j < dependenciesCount; j++) {
    x.push(itDepends.value(-1));
}

var a = itDepends.computed(function() {
    var z = 0;
    for (var j = 0; j < dependenciesCount; j++) {
        z += x[j]();
    }
    return z;
});

var b = itDepends.value(6);
var c = itDepends.value(10);

var d = itDepends.computed(function() {
    return b() * c() === 60 ? a() : 0;
});

var s = d.onChange(function() {});

the scenario:

itDepends.bulkChange(function() {
    b.write(4);
    c.write(15);
});

should work faster than scenario:

b.write(4);
c.write(15);

Bulk changes block

There should be an ability to write:

var a = itDepends.value(10);
var b = itDepends.value(20);
var c = itDepends.computed(function() {
    return a() + b();
});

var subscription = c.onChange(function(newValue, oldValue) {
    console.log(oldValue + ' -> ' + newValue);
});

a(20); // outputs 30 -> 40
b(30); // outputs 40 -> 50

itDepends.bulkChange(function() {
    console.log('start');
    a(30);
    b(40);
    console.log('a = ' + a());
    console.log('b = ' + b());
    console.log('end');
}); // outputs start, a = 30, b = 40, end, 50 -> 70

a(40); // outputs 70 -> 80
b(50); // outputs 80 -> 90

Move `coveralls` gulp task to appveyor.yml?

During creating new Appveyor build I faced out with issue - I could not pass a build with unit-tests gulp task because it depends on coveralls task which should be configured for appveyor build previously. I am proposing move coveralls task somewhere to be executed after unit-tests are done.

Array computed

There should be an ability to build lazy computed collections

Explicit write method for observales and computeds

Instead of

var a = itDepends.value(10);
a(15);

I want to write

var a = itDepends.value(10);
a.write(15);

See #7 for why.
There should be an ability to get "writer" to allow old syntax

var aWriter = a.write();
aWriter(15);

optional onChange callbacks

There should be an ability to write:

var a = itDepends.value(10);
var b = itDepends.computed(function() {
    return a() > 30 ? 30 : a();
});

var subscription = b.onChange(function(newValue, oldValue) {
    console.log(oldValue + ' -> ' + newValue);
});

a(20); // outputs 10 -> 20
a(30); // outputs 20 -> 30
a(40); // outputs nothing

subscription.disable();

a(20); // outputs nothing

subscription.enable();

a(10); // outputs 20 -> 10

Fix and enable performance tests for AppVeyor

AppVeyor yields quite a different results that local performance tests:
https://ci.appveyor.com/project/gerich-home/it-depends/build/1.0.220

Compare to local run on my machine:

'subscribe to computed with 1000 subscribers and unsubscribe them'
  1.05x slower
'subscribe to computed with 1 subscribers and unsubscribe them'
  1.40x slower
'subscribe to computed with 3 subscribers and unsubscribe them'
  1.14x slower
'subscribe to computed with 500 subscribers and unsubscribe them'
  1.01x faster
'computed updated 1000 times with 1000 subscribers'
  2.09x faster
'computed updated 1000 times with 1 subscribers'
  2.73x faster
'computed updated 1000 times with 500 subscribers'
  2.62x faster
'computed updated 1 times with 1000 subscribers'
  10.05x faster
'computed updated 1 times with 1 subscribers'
  10.42x faster
'computed updated 1 times with 500 subscribers'
  10.05x faster
'computed updated 3 times with 1000 subscribers'
  2.20x faster
'computed updated 3 times with 1 subscribers'
  1.50x faster
'computed updated 3 times with 500 subscribers'
  2.22x faster
'computed updated 50 times with 1000 subscribers'
  2.15x faster
'computed updated 50 times with 1 subscribers'
  1.83x faster
'computed updated 50 times with 500 subscribers'
  2.29x faster
'read observable 1000 times'
  2.43x faster
'read observable 100 times'
  2.03x faster
'read observable 1 times'
  1.92x faster
'subscribe to observable with 1000 subscribers and unsubscribe them'
  1.09x slower
'subscribe to observable with 1 subscribers and unsubscribe them'
  1.30x slower
'subscribe to observable with 3 subscribers and unsubscribe them'
  1.19x slower
'subscribe to observable with 500 subscribers and unsubscribe them'
  1.09x slower
'write observable 1000 times with 1 subscribers'
  12.82x faster
'write observable 1000 times with 3 subscribers'
  8.28x faster
'write observable 1000 times with 50 subscribers'
  2.62x faster
'write observable 1 times with 1000 subscribers'
  9.91x faster
'write observable 1 times with 1 subscribers'
  10.32x faster
'write observable 3 times with 1000 subscribers'
  1.83x faster
'write observable 50 times with 1000 subscribers'
  1.87x faster

Slow tests are significantly slower than on my local machine (up to 5.5 times), while fast tests are significantly faster (up to 72 times).

Thus AppVeyor results are not representative. What I see is that the deviation is much higher on AppVeyor (up to +-40%) when on my local machine it is quite slow (up to +-4.5%).

This behavior needs further investigation.

One can compare the behavior on AppVeyor and some alternative CI server (TravisCI?)

Publish to NuGet

Need to discuss if it is needed for .Net projects to publish to NuGet.

General change callback

Need to have a way to know that any observable value just changed (in general)
Simalar to #3, but it will give you the way to do not subscribe to the concrete observable value, but subscribe just to the general event.

var a = itDepends.value(10);
var b = itDepends.computed(function() {
    return a() > 30 ? 30 : a();
});
var c = itDepends.value(10);

var subscription = itDepends.onChange(function(value, from, to) {
    console.log('a: ' + (value === a) + ' (' + from+ ' -> ' + to + ')');
});

a(20); // outputs a: true (10 -> 20)
a(30); // outputs a: true (20 -> 30)
a(30); // outputs nothing
c(20); // outputs a: false (10 -> 20)
a(40); // outputs a: true (30 -> 40)

subscription.disable();

a(50); // outputs nothing

subscription.enable();

a(60); // outputs a: true (50 -> 60)
Thoughts:

disable should not keep the registration in the library, so when you disable and throw away the reference to subscription it gets garbage collected

Exceptions handling in computeds

Avoid repetitive calls to computed function if exception has been thrown.
Rethrow exception that was called on the calculation.
Allow recalculation when some of dependencies was changed.

UMD support

Take a look into using something like gulp-umd to create and UMD wrapper for a library instead of placing all the code in one file

Postpone subscriptions/unsubscriptions

In certain situations there is no point in subscribing or unsubscribing immediately.
We should postpone deep subscriptions until a change was made.

For the case of bulkChange subscriptions/unsubscriptions should be postponed until the end of bulk change.

  • Example 1

Given the following definitions:

var x = [];
for (var j = 0; j < dependenciesCount; j++) {
    x.push(itDepends.value(-1));
}

var a = itDepends.computed(function() {
    var z = 0;
    for (var j = 0; j < dependenciesCount; j++) {
        z += x[j]();
    }
    return z;
});

var b = itDepends.value(true);

var c = itDepends.computed(function() {
    return b() ? a() : 0;
});

the following scenarios should work with approximately the same performance:

c.onChange(function() {}); // triggers massive subscriptions currently
b.write(false); // but all of them get disabled here
b.write(false);
c.onChange(function() {});
  • Example 2

Given the following definitions:

var x = [];
for (var j = 0; j < dependenciesCount; j++) {
    x.push(itDepends.value(-1));
}

var a = itDepends.computed(function() {
    var z = 0;
    for (var j = 0; j < dependenciesCount; j++) {
        z += x[j]();
    }
    return z;
});

var b = itDepends.value(false);

var c = itDepends.computed(function() {
    return b() ? a() : 0;
});

var s = a.onChange(function() {});
x[0].write(1);

the following scenarios should also work with approximately the same performance:

s.disable(); // should not unsubscribe from a and all x[i] immediately!
var s2 = c.onChange(function() {}); // because the replacement subscription is created here
b.write(true); // but becomes active only here
var s2 = c.onChange(function() {});
b.write(true);
s.disable(); // does not trigger massive unsubscriptions currently

Get/Set support

There should be an ability to create an object with computed fields and observable values with fancy syntax.

Writable computed

Writable computed can be used to encapsulate the logic of modifing its value, so it is vital to have such an ability

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.