Exemple #1
0
    function Main(sources: {state: StateSource<any>}) {
      sources.state.stream.addListener({
        next(x) {
          assert.deepEqual(x.list, expected.shift());
        },
        error(e) {
          done(e.message);
        },
        complete() {
          done('complete should not be called');
        },
      });

      const childSinks = isolate(List, 'list')(sources);
      const childReducer$ = childSinks.state;

      const initReducer$ = xs.of(function initReducer(prevState: any): any {
        return {list: [{val: 3}]};
      });

      const addReducer$ = xs
        .of(function addSecond(prev: any) {
          return {list: prev.list.concat({val: null})};
        })
        .compose(delay(100));

      const parentReducer$ = xs.merge(initReducer$, addReducer$);
      const reducer$ = xs.merge(parentReducer$, childReducer$) as Stream<
        Reducer<any>
      >;

      return {
        state: reducer$,
      };
    }
Exemple #2
0
function Client (sources) {
  const stateUpdate$ = sources.Socket.messages
    .filter(message => message.type === 'UPDATE_STATE')
    .map(message => message.data);

  const stateOverride$ = stateUpdate$
    .map(serverState => ({type: 'OVERRIDE', data: serverState}));

  const id$ = sources.Socket.messages
    .filter(message => message.type === 'SET_ID')
    .map(message => message.data)
    .remember();

  const move$ = sources.DOM
    .select('svg')
    .events('click')
    .map(mousePosition)
    .map(destination => ({type: 'MOVE', data: destination}));

  const attack$ = sources.DOM
    .select('.enemy')
    .events('click')
    .debug(event => event.stopPropagation())
    .map(event => ({type: 'ATTACK', data: event.target.id}));

  const chat$ = sources.DOM
    .select('document')
    .events('keydown')
    .map(event => ({type: 'CHAT', data: event.key}));

  const action$ = xs.merge(
    move$,
    chat$,
    attack$
  );

  const gameActionWithId$ = id$
    .map(id => action$.map(action => ({...action, id})))
    .flatten();

  const gameAction$ = xs.merge(gameActionWithId$, stateOverride$);

  const state$ = Game({
    Animation: sources.Animation,
    action$: gameAction$ as Stream<Action>
  });

  return {
    DOM: xs.combine(id$, state$).map(view),
    Socket: action$
  }
}
Exemple #3
0
function ProjectName(sources: IProjectNameSources): IProjectNameSinks {
  const startEditing$ = sources.DOM
    .select(".edit-project-name")
    .events("click")
    .mapTo(true);

  const save$ = sources.DOM
    .select(".save-project-name")
    .events("click")
    .mapTo(false);

  const cancelEditing$ = sources.DOM
    .select(".cancel-editing-project-name")
    .events("click")
    .mapTo(false);

  const editing$ = xs.merge(xs.of(false), startEditing$, save$, cancelEditing$);

  const newName$ = sources.DOM
    .select(".project-name-input")
    .events("input")
    .map((ev: any) => ev.currentTarget.value);

  const nameChange$ = newName$.map(name => save$.mapTo(name)).flatten();

  function view([name, editing]: [string, boolean]): VNode {
    if (editing) {
      return div(".project-name-container", [
        div([
          input(".project-name-input", { props: { value: name } }),
          a(".save-project-name", " ✓ "),
          a(".cancel-editing-project-name", " ✖ ")
        ])
      ]);
    }

    return div(".project-name-container", [
      div([span(".project-name", `${name}`), a(".edit-project-name", " ✎ ")])
    ]);
  }

  return {
    DOM: xs.combine(sources.name$, editing$).map(view),

    name$: xs.merge(sources.name$, nameChange$),

    nameChange$
  };
}
Exemple #4
0
  function DOMDriver(vnode$: Stream<VNode>, name = 'DOM'): MainDOMSource {
    domDriverInputGuard(vnode$);
    const sanitation$ = xs.create<null>();
    const rootElement$ = xs
      .merge(vnode$.endWhen(sanitation$), sanitation$)
      .map(vnode => vnodeWrapper.call(vnode))
      .fold(patch, toVNode(rootElement))
      .drop(1)
      .map(unwrapElementFromVNode)
      .compose(dropCompletion) // don't complete this stream
      .startWith(rootElement as any);

    // Start the snabbdom patching, over time
    const listener = {error: reportSnabbdomError};
    if (document.readyState === 'loading') {
      document.addEventListener('readystatechange', () => {
        if (document.readyState === 'interactive') {
          rootElement$.addListener(listener);
        }
      });
    } else {
      rootElement$.addListener(listener);
    }

    return new MainDOMSource(
      rootElement$,
      sanitation$,
      [],
      isolateModule,
      delegators,
      name,
    );
  }
Exemple #5
0
function Counter(sources: Sources): Sinks {
	const IncrementButton = isolate(Button);
	const DecrementButton = isolate(Button);

	let incrementButtonProps$ = xs.of<ButtonProps>({
    text: 'Increment', amount: 1
  }).remember();
	let decrementButtonProps$ = xs.of<ButtonProps>({
    text: 'Decrement', amount: -1
  }).remember();

	let incrementButton = IncrementButton({DOM: sources.DOM, props$: incrementButtonProps$});
	let decrementButton = DecrementButton({DOM: sources.DOM, props$: decrementButtonProps$});

	let count$ = xs.merge(incrementButton.delta$, decrementButton.delta$)
		.fold((acc, x) => acc + x, 0);

	return {
		DOM: xs.combine(count$, incrementButton.DOM, decrementButton.DOM)
      .map(([count, incrementVTree, decrementVTree]) =>
        div([
          incrementVTree,
					decrementVTree,
					h2('Clicks: ' + count),
        ])
      )
	};
}
Exemple #6
0
  return function (): Stream<Input> {
    return xs.merge(
      fromEvent(window, 'keydown')
        .map((e: KeyboardEvent) => {
          switch (e.keyCode) {
            case 74:
              return xs.of('up');
            case 75:
              return xs.of('down');
            default:
              return xs.empty();
          }
        }).flatten(),

      fromEvent(window, 'keyup')
        .map((e: KeyboardEvent) => {
          switch (e.keyCode) {
            case 188:
              return xs.of('decrement');
            case 190:
              return xs.of('increment');
            default:
              return xs.empty();
          }
        }).flatten()
    );
  }
Exemple #7
0
    function Main(sources: {state: StateSource<any>}) {
      sources.state.stream.addListener({
        next(x) {
          assert.deepEqual(x.wrap, expected.shift());
        },
        error(e) {
          done(e.message);
        },
        complete() {
          done('complete should not be called');
        },
      });

      const wrapperSinks = isolate(Wrapper, 'wrap')(sources);
      const wrapperReducer$ = wrapperSinks.state;

      const initReducer$ = xs.of(function initReducer(prevState: any): any {
        return {wrap: {key: 'a', val: null}};
      });

      const reducer$ = xs.merge(initReducer$, wrapperReducer$) as Stream<
        Reducer<any>
      >;

      return {
        state: reducer$,
      };
    }
Exemple #8
0
    function main(sources: {state: StateSource<any>}) {
      const expected = [7, 9];
      sources.state.stream.addListener({
        next(x) {
          assert.strictEqual(x.child.count, expected.shift());
          calledMain += 1;
        },
        error(e) {
          done(e);
        },
        complete() {},
      });

      const childSinks = child({state: isolateSource(sources.state, 'child')});
      assert(childSinks.state);
      const childReducer$ = isolateSink(childSinks.state, 'child');

      const parentReducer$ = xs.of(function initReducer(prevState: any): any {
        return {child: {count: 7}};
      });
      const reducer$ = xs.merge(parentReducer$, childReducer$);

      return {
        state: reducer$,
      };
    }
Exemple #9
0
    function main(sources: {state: StateSource<any>}) {
      assert(sources.state);
      assert(sources.state.stream);
      const expected = [1, 0, -1];
      sources.state.stream.addListener({
        next(x) {
          assert.strictEqual(x.count, expected.shift());
          calledMain += 1;
        },
        error(e) {
          done(e);
        },
        complete() {},
      });

      const childSinks = isolate(child, 'count')(sources);
      assert(childSinks.state);
      const childReducer$ = childSinks.state;

      const parentReducer$ = xs.of(function initReducer(prevState: any): any {
        return {count: 1};
      });
      const reducer$ = xs.merge(parentReducer$, childReducer$) as Stream<
        Reducer<any>
      >;

      return {
        state: reducer$,
      };
    }
Exemple #10
0
    function main(sources: {state: StateSource<any>}) {
      assert(sources.state);
      assert(sources.state.stream);
      const expected = [[3, 5, 6], [3, 15, 6], [3, 6]];
      sources.state.stream.addListener({
        next(x) {
          assert.deepEqual(x, expected.shift());
          calledMain += 1;
        },
        error(e) {
          done(e);
        },
        complete() {},
      });

      const childSinks = isolate(secondEntry, 1)(sources);
      assert(childSinks.state);
      const childReducer$ = childSinks.state;

      const parentReducer$ = xs.of(function initReducer(prevState: any): any {
        return [3, 5, 6];
      });
      const reducer$ = xs.merge(parentReducer$, childReducer$) as Stream<
        Reducer<any>
      >;

      return {
        state: reducer$,
      };
    }