exocore 0.1.11

Distributed applications framework
Documentation
import { exocore, Exocore, matchTrait, MutationBuilder, QueryBuilder, WatchedQueryWrapper } from 'exocore';
import React, { ChangeEvent } from 'react';

interface IListProps {
}

interface IListItem {
    entity: exocore.store.IEntity;
    trait: exocore.store.ITrait;
    message: exocore.test.ITestMessage;
}

interface IListState {
    items: IListItem[]
}

export default class List extends React.Component<IListProps, IListState> {
    private watchedQuery: WatchedQueryWrapper;

    constructor(props: IListProps) {
        super(props);

        this.state = {items: []};

        this.registerQuery();
    }

    render() {
        return (
            <div>
                <Input onAdd={this.onAdd.bind(this)}/>

                <ul>
                    {this.renderList()}
                </ul>
            </div>
        );
    }

    renderList() {
        const DeleteButton = (props: {item: IListItem}) => {
            return <button onClick={this.onDelete.bind(this, props.item)}>Delete</button>
        };

        return this.state.items.map(item =>
            <li key={item.entity.id}>{item.message.string1} (<DeleteButton item={item}/>)</li>
        );
    }

    async onAdd(text: string) {
        const mutation = MutationBuilder
            .createEntity()
            .putTrait(new exocore.test.TestMessage({
                string1: text,
            }))
            .build();

        await Exocore.store.mutate(mutation);
    }

    async onDelete(item: IListItem) {
        const mutation = MutationBuilder
            .updateEntity(item.entity.id)
            .deleteTrait(item.trait.id)
            .build();

        await Exocore.store.mutate(mutation);
    }

    registerQuery() {
        const query = QueryBuilder
            .withTrait(exocore.test.TestMessage)
            .count(100)
            .build();

        this.watchedQuery = Exocore.store.watchedQuery(query).onChange((results) => {
            let res = results.entities.flatMap((res) => {
                return matchTrait(res.entity.traits[0], {
                    [Exocore.registry.messageFullName(exocore.test.TestMessage)]: (trait, message) => {
                        return {entity: res.entity, trait: trait, message: message};
                    }
                })
            });

            this.setState({
                items: res
            })
        });
    }

    componentWillUnmount() {
        this.watchedQuery.free();
    }
}

interface IInputProps {
    onAdd: (text: string) => void;
}

interface IInputState {
    text: string;
}

class Input extends React.Component<IInputProps, IInputState> {
    constructor(props: IInputProps) {
        super(props);

        this.state = {
            text: ''
        }
    }

    render() {
        return (
            <div>
                <input value={this.state.text} onChange={this.onTextChange.bind(this)}/>
                <button onClick={this.onAddClick.bind(this)}>Add</button>
            </div>
        )
    }

    onTextChange(e: ChangeEvent<HTMLInputElement>) {
        this.setState({
            text: e.target.value
        });
    }

    onAddClick() {
        this.props.onAdd(this.state.text);

        this.setState({
            text: ''
        });
    }
}