Commit b84e42a0 by Vladislav Lagunoff

[update] Добавлен prepareUpdate

parent be3abc83
......@@ -6,6 +6,8 @@ import * as http from '../../http';
import { InputHTMLAttributes } from 'react';
type Err = http.HttpError;
type Props = {
};
......@@ -15,10 +17,10 @@ type State = {
response?: http.Response;
};
const U = Update.bind<State>();
const U = Update.bind<Err, State>();
class Widget extends Update.Component<Props, State> {
class Widget extends Update.Component<Err, Props, State> {
state: State = { search: '', pending: false };
handleNameChange: InputHTMLAttributes<HTMLInputElement>['onChange'] = (e) => this.setState({ search: e.target.value });
......
......@@ -102,7 +102,7 @@ export function go<Error, State, A>(
if (update instanceof Apply) {
let allInitialized = false;
let subscriptions: Array<Function|undefined|null> = new Array(update.args.length);
let cancellers: Array<Canceller|undefined|null> = new Array(update.args.length);
const initializedFlags: Array<true|undefined> = new Array(update.args.length);
const recentValues: unknown[] = new Array(update.args.length);
const next = idx => result => {
......@@ -116,46 +116,42 @@ export function go<Error, State, A>(
onNext(update.proj.apply(void 0, recentValues));
};
const complete = idx => () => {
subscriptions[idx] = null;
for (const unsub of subscriptions) if (unsub !== null) return;
cancellers[idx] = null;
for (const c of cancellers) if (c !== null) return;
onComplete();
};
update.args.forEach((u, idx) => {
const canceller = go(u, getState, setState, next(idx), onError, complete(idx));
if (subscriptions[idx] !== null) subscriptions[idx] = canceller;
if (cancellers[idx] !== null) cancellers[idx] = canceller;
});
return () => subscriptions.forEach(
funOrNull => funOrNull ? funOrNull() : void 0
);
return () => cancellers.forEach(canceller => canceller ? canceller() : void 0);
}
if (update instanceof Batch) {
if (update.steps.length === 0) { onNext(void 0 as any); onComplete(); return noopFunc; }
let subscriptions: Array<Function|null>;
let cancellers: Array<Canceller|null>;
const loop = idx => () => {
subscriptions[idx] = null;
for (const unsub of subscriptions) if (unsub !== null) return;
cancellers[idx] = null;
for (const unsub of cancellers) if (unsub !== null) return;
onNext(void 0 as any);
onComplete(); // If control flow reaches here, that means all nested commands are completed
};
subscriptions = update.steps.map((u, idx) => go(u, getState, setState, noopFunc, onError, loop(idx)));
cancellers = update.steps.map((u, idx) => go(u, getState, setState, noopFunc, onError, loop(idx)));
return () => subscriptions.forEach(
funOrNull => funOrNull ? funOrNull() : void 0
);
return () => cancellers.forEach(canceller => canceller ? canceller() : void 0);
}
if (update instanceof Concat) {
let unsubscribe: Function|null = null;
let canceller: Canceller|null = null;
const loop = idx => () => {
// If condition holds, then all nested effects are completed, therefore we're done
if (idx >= update.steps.length) { onNext(void 0 as any); onComplete(); return; }
unsubscribe = go(update.steps[idx], getState, setState, noopFunc, onError, loop(idx + 1));
canceller = go(update.steps[idx], getState, setState, noopFunc, onError, loop(idx + 1));
};
loop(0);
return () => unsubscribe ? unsubscribe() : void 0;
return () => canceller ? canceller() : void 0;
}
if (update instanceof Difference) {
......@@ -399,10 +395,11 @@ export class Component<Error, Props, State> extends React.Component<Props, State
setState(updateOrProjOrPatch, callback?) {
if (updateOrProjOrPatch instanceof UpdateBase) {
const onUpdate = this.props['onUpdate'] as unknown;
const update = this.prepareUpdate(updateOrProjOrPatch);
if (typeof(onUpdate) === 'function') {
onUpdate(updateOrProjOrPatch);
onUpdate(update);
} else {
updateOrProjOrPatch.run(this, callback);
update.run(this, callback);
}
return;
}
......@@ -413,6 +410,10 @@ export class Component<Error, Props, State> extends React.Component<Props, State
return this.setState(new Patch<Error, State, void>(updateOrProjOrPatch, callback))
}
}
prepareUpdate<A>(update: Update<Error, State, A>): Update<Error, State, A> {
return update;
}
}
export interface UpdateStatic {
......@@ -426,6 +427,7 @@ export interface UpdateStatic {
concat: typeof concat,
Component: typeof Component,
bind: typeof bind,
difference: typeof difference,
};
......@@ -440,6 +442,7 @@ export const Update = {
concat,
Component,
bind,
difference,
} as UpdateStatic;
export interface BoundStatics<Error, State> {
......@@ -460,6 +463,7 @@ export interface BoundStatics<Error, State> {
modify(proj: (x: State) => State, callback?: () => void): Modify<Error, State, void>;
effect<Error, Success>(eff: Eff<Error, Success>): Effect<Error, State, Success>;
get: Get<Error, State, State>;
difference<A>(update: Update<Error, State, A>, diff: (prev: State, next: State) => State|Update<Error, State, void>): Difference<Error, State, A>;
}
export function bind<Error, State>() {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment