infinnie / infinnie.github.io

https://infinnie.github.io/
Apache License 2.0
0 stars 1 forks source link

design of a sort of framework. #15

Open infinnie opened 4 years ago

infinnie commented 4 years ago
<script>
    export default function* (_, next) {
        var a = 233;
        function handleClick() {
            a++;
            next();
        }
        while (true) {
            // computed properties can be evaluated here.
            const minusA = a - 1;
            yield { a, handleClick, minusA };
        }
    };
</script>
<p>{a} - 1: {minusA}</p>
<button type="button" $click={handleClick}>Click me</button>
infinnie commented 4 years ago

JSX syntax:

import {
    h,
    inst,
    Fragment
} from "LIBRARY_NAME";

import Counter from "./counter";

export default function (_, next) {
    return inst([Counter], function (CounterInstance) {
        let value = 1;

        function handle() {
            value++;
            next();
        }

        function render() {
            return <>
                <h1>{value}</h1>
                <CounterInstance
                    value={value}
                    onChange={handle}
                />
            </>;
        }

        return {
            render,
            effect: null, // run after mount/update
            dispose: null
        };
    });
};
infinnie commented 4 years ago
<script>
    import Counter from "./counter";

    export default function (_, next) {
        const allCounts = [
            { id: 1, value: 0 },
            { id: 2, value: 1 }
            // ...
        ];

        function handle(item) {
            item.value++;
            next();
        }

        function run() {
            return { allCounts, handle };
        }

        return {
            components: { "counter-component": Counter },
            run
        };
    };
</script>

<!--
    I might as well use HTML templates that can
    get compiled into JavaScript, due to the
    reason stated in the following comment.
-->
<template>
    <h1>Multiple Counters</h1>
    <lib:block for="item, index: allCounts" key="item.id">
        <h2>{index} of {allCounts.length}: {item.value}</h2>
        <counter-component
            value={item.value}
            $change={() => { handle(item) }}
        />
    </lib:block>
</template>
infinnie commented 4 years ago

A problem exists that a component might exist when not referenced and it has no way to know that a reference to it is somehow lost or duplicated.

infinnie commented 4 years ago

In JSX again:

import {
    h,
    Fragment,
    decorate,
    inst,
    keyed
} from "LIBRARY_NAME";

import Counter from "./counter";

export default decorate(() => {
    const KeyedCounters = inst(keyed([Counter], item => item.id));

    return data => <>
        <h1>Multiple Counters</h1>
        <KeyedCounters
            items={data.allCounts}
            render={(item, index, CurrentCounter) => <>
                <h2>{index} of {data.allCounts.length}: {item.value}</h2>
                <CurrentCounter
                    value={item.value}
                    $change={() => { handle(item) }}
                />
            </>}
        />
    </>;
})(function (_, next) {
    const allCounts = [
        { id: 1, value: 0 },
        { id: 2, value: 1 }
        // ...
    ];

    function handle(item) {
        item.value++;
        next();
    }

    function run() {
        return { allCounts, handle };
    }

    return { run };
});
infinnie commented 4 years ago

The if block:

<lib:block if="cond">
    <counter-component />
    <!-- equivalent to
        <lib:block else>
            <p>Condition was not met.</p>
        </lib:block>
    -->
    <p lib:else>Condition was not met.</p>
</lib:block>
(() => {
    const ConditionalCounter = inst(conditional([Counter]));
    return data => <ConditionalCounter
        cond={data.cond}
        render={CurrentCounter => <CurrentCounter />}
        else={() => <p>Condition was not met.</p>}
    />;
})
infinnie commented 4 years ago

Chaining proposal:

const MyComponent = Block(Counter)
    .conditional(OtherComponent)
    .concat(Button) // Block(Button).component()
    .keyed(item => item.id)
    .render(KeyedCond => data => <>
        <p>Block chaining test</p>
        <KeyedCond
            items={data.items}
            render={(
                item,
                index,
                CondCounter,
                CurButton
            ) => <>
                <h2>{index}: {item.value}</h2>
                <CurButton $click={() => { data.reset(item); }}>
                    Reset
                </CurButton>
                <CondCounter
                    cond={item.cond}
                    render={CurCounter => <CurCounter
                        value={item.value}
                        $change={() =>{ data.handle(item); }}
                    />}
                    else={CurComp => <CurComp>
                        Condition was not met.
                    </CurComp>}
                />
            </>}
        />
    </>
).component((props, next) => {
    return { run: () => ({}) };
});