Giter VIP home page Giter VIP logo

runtime's Issues

createComponent

const slider = store.dispatch(actions.createComponent(
  'slider', 'scope',
  { value: { func: 'x' }, min: { value: 1 } },
  { change: { func: '{"x": value}' } },
));

This should follow the same pattern as #3 for taking an object.

This should simplify the scope/name issue. However, the default behavior should not name the component. Only set the scope.

This is getting overridden in the ink-basic packages. And components should not have names by default.

Arguments for properties

transform, for example, takes an argument scoped within the component.

export const InkRangeSpec = {
  name: 'range',
  description: 'Range input',
  properties: {
    value: { type: types.PropTypes.number, default: 0 },
    min: { type: types.PropTypes.number, default: 0 },
    max: { type: types.PropTypes.number, default: 100 },
    step: { type: types.PropTypes.number, default: 1 },
    transform: {type: types.PropTypes.string, default: '', args: ['value'], has:{func: true, value: false}}
  },
  events: {
    change: { args: ['value'] },
  },
};

createSpec

This doesn't actually work:

store.dispatch(actions.createComponentSpec(SliderSpec));

It requires you to break it out. The first arg should take a string or an object.

also:
createComponentSpec --> createSpec to match #2

Bring Spec/Components to base state

This allows for how I wrote the docs. :)

The flatter state is a bit more sensible, will require a few changes in the folder structure, but I think clearer overall.

How to do chart equation?

I am not really sure how to get the mapped function.

I want to return this:

() => Math.sin(x)

So that I can:

array.map((x) => [x, func(x)])

And get a chart ....
image

Problem is that that requires a function type? And the array doesn't exist on the object, so it can't really be a property remap. :(

Needs more thought.

Feature suggestion: reactive aggregate r-var

I'm not sure if this is the correct repo to post this feature request, I'm sorry if it's not, I can repost elsewhere if necessary.

First off, I am very impressed at the concise expressivity iooxa offers in terms of reactive components, it's very easy and reliable once you understand how it's meant to be used! Awesome work, it's even better than the already great ink-components predecessor package :-D

I would like to suggest an extension on how variables are handled to make some of them reactive, just like r-display for example. This would be especially useful for variables that are defined as an aggregate of other variables, in other words are dependent on other variables, which is often useful for complex calculations to store and reuse intermediate results.

Currently, the only way to propagate changes is "top-down": the parent variables must update the children's variables values using the :change attribute. But this leads to an unnatural writing style in complex applications. This could be improved with a "bottom-up" approach where we directly define inside the children's variables definition what are the parent/dependent variables, similarly to what is done with r-display.

Let me show an example to clarify: let's say we make an app with 5 r-vars: a, b, c, the sum of a+b+c and the sum squared.

Here is what we currently need to write:

<script src="https://unpkg.com/@iooxa/article"></script>
<link rel="stylesheet" href="https://unpkg.com/@iooxa/article/dist/iooxa.css">

<div style="display: flex; flex-direction: column">
<r-var name="a" value="1" type="Number"></r-var>
<r-var name="b" value="10" type="Number"></r-var>
<r-var name="c" value="100" type="Number"></r-var>
<r-var name="sum" value="111" type="Number"></r-var>
<r-var name="sum_squared" value="12321" type="Number"></r-var>

<r-input label="a" :value="a" :change="{a: parseFloat(value), sum: parseFloat(value)+b+c, sum_squared: (parseFloat(value)+b+c)**2}"></r-input>
<r-input label="b" :value="b" :change="{b: parseFloat(value), sum: a+parseFloat(value)+c, sum_squared: (a+parseFloat(value)+c)**2}"></r-input>
<r-input label="c" :value="c" :change="{c: parseFloat(value), sum: a+b+parseFloat(value), sum_squared: (a+b+parseFloat(value))**2}"></r-input>
<r-input label="Sum" :value="sum" :change="{sum: value, a: value-b-c, sum_squared: value**2}"></r-input> <!-- Simply change one variable so that the input sum is correct -->
<r-input label="Sum squared" bind="sum_squared"></r-input>
</div>

Beside the issues with parseFloat which I mentioned in another issue elsewhere, the current approach leads to a lot of redundancy. Basically, the children r-var sum needs to be redefined inside each parent r-var's :change attribute, with pretty much the same code copy/pasted except that the current parent variable becomes value. Not only that, but all children of sum itself, such as sum_squared here, also need to be redefined at the level of each parents at all levels, hence here in both a, b, c and sum. We have only a 3 level depth tree here, the more depth the more redundancy.

Here is my "bottom-up" suggestion:

<script src="https://unpkg.com/@iooxa/article"></script>
<link rel="stylesheet" href="https://unpkg.com/@iooxa/article/dist/iooxa.css">

<div style="display: flex; flex-direction: column">
<r-var name="a" value="1" type="Number"></r-var>
<r-var name="b" value="10" type="Number"></r-var>
<r-var name="c" value="100" type="Number"></r-var>
<r-var name="sum" value="a+b+c" type="Number"></r-var>
<r-var name="sum_squared" value="sum**2" type="Number"></r-var>

<r-input label="a" :value="a" :change="{a: parseFloat(value)}"></r-input>
<r-input label="b" :value="b" :change="{b: parseFloat(value)}"></r-input>
<r-input label="c" :value="c" :change="{c: parseFloat(value)}"></r-input>
<r-input label="Sum" :value="sum" :change="{a: value-b-c}"></r-input> <!-- Simply change one variable so that the input sum is correct -->
<r-input label="Sum squared" bind="sum_squared"></r-input>
</div>

As you can see now the aggregate variables, sum and sum_squared, are now defined directly in r-var. The idea is that the value of sum should always reflect a+b+c. Hence in the :change attribute of the r-input of sum, we do not need to update the value of sum as it is always defined by the sum of a+b+c, we only need to change one of these parent variables (here I chose a for the sake of this example). Also I guess that in the runtime, if we make something reactive, it's then tied to these variables, so I guess that trying to set {sum: value} wouldn't work anyway.

So to summarize, sum and sum_squared are in this case a bit different variables than the standard r-var: whereas the r-var are meant to be directly set by user inputs, sum and sum_squared are only indirectly set, and are directly tied to other r-vars. That's why I call them "aggregate variables". In the above example I used :value="a+b+c" to define the dependency to the parents, but if it's simpler from an implementation standpoint to use a differently named attribute I see no issue.

About potential issues: it seems infinite recursion may be possible when updating reactive aggregate variables. In the example above, updating r-var a should update sum but then in cascade it should also update sum_squared. We could imagine two aggregates variables like: <r-var name="b1" value="a*b2"></r-var> and <r-var name="b2" value="a*b1"></r-var> with r-var a being a standard r-var that can be set with a r-input for example. Updating a would trigger an infinite loop between b1 and b2 in theory. I'm honestly not very experienced with javascript so I don't know how reactivity works technically, so I'm not sure how this could be handled, maybe with a list of variables to update to ensure the cascading only updates each children variable once when a is updated? Or just throw an error, that would work too.

Maybe this is not possible to implement, so in that case please disregard this ticket :-) It just spawned from my experiments to see how far iooxa could go, and as I found it can be used to make not just explorable explorations but even calculators and probably more when combined with custom javascript (or Brython) :-) The root of my thought started as very simple question, I was just wondering why I could not store a r-var for an intermediate result just like values of r-display while keeping the reactivity. In the end, as you can see in the concrete case that is the calculator I linked above, I used a mix of the first approach of duplicating code in all parent r-vars' inputs, and of avoiding the declaration of unnecessary intermediate resultst r-vars to minimize the depth of the dependency tree.

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.