167 lines
2.5 KiB
TypeScript
167 lines
2.5 KiB
TypeScript
|
|
namespace lib_mvc
|
||
|
|
{
|
||
|
|
|
||
|
|
/**
|
||
|
|
*/
|
||
|
|
export type type_event<type_data> = {
|
||
|
|
type : string;
|
||
|
|
data : type_data;
|
||
|
|
};
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
*/
|
||
|
|
export type type_model<type_state> =
|
||
|
|
{
|
||
|
|
listeners : Array<((event : type_event<any>) => Promise<void>)>;
|
||
|
|
state : type_state;
|
||
|
|
};
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
*/
|
||
|
|
export type type_view<type_state> =
|
||
|
|
{
|
||
|
|
setup : ((model : type_model<type_state>) => Promise<void>);
|
||
|
|
update : ((model : type_model<type_state>, event : type_event<any>) => Promise<void>);
|
||
|
|
};
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
*/
|
||
|
|
export type type_control<type_state> =
|
||
|
|
{
|
||
|
|
setup : ((model : type_model<type_state>) => Promise<void>);
|
||
|
|
};
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
*/
|
||
|
|
export type type_complex<type_state> =
|
||
|
|
{
|
||
|
|
model : type_model<type_state>;
|
||
|
|
views : Array<type_view<type_state>>;
|
||
|
|
controls : Array<type_control<type_state>>;
|
||
|
|
};
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
*/
|
||
|
|
export function model_make<type_state>
|
||
|
|
(
|
||
|
|
state : type_state
|
||
|
|
) : type_model<type_state>
|
||
|
|
{
|
||
|
|
return {
|
||
|
|
"listeners": [],
|
||
|
|
"state": state,
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
*/
|
||
|
|
export function model_listen<type_state, type_data>
|
||
|
|
(
|
||
|
|
model : type_model<type_state>,
|
||
|
|
action : ((event : type_event<type_data>) => Promise<void>)
|
||
|
|
) : void
|
||
|
|
{
|
||
|
|
model.listeners.push(action);
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
*/
|
||
|
|
export async function model_notify<type_state, type_data>
|
||
|
|
(
|
||
|
|
model : type_model<type_state>,
|
||
|
|
event : type_event<type_data>
|
||
|
|
) : Promise<void>
|
||
|
|
{
|
||
|
|
for await (const action of model.listeners)
|
||
|
|
{
|
||
|
|
action(event);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
*/
|
||
|
|
export async function view_setup<type_state>
|
||
|
|
(
|
||
|
|
view : type_view<type_state>,
|
||
|
|
model : type_model<type_state>,
|
||
|
|
options :
|
||
|
|
{
|
||
|
|
blocking ?: boolean;
|
||
|
|
} = {}
|
||
|
|
) : Promise<void>
|
||
|
|
{
|
||
|
|
options = Object.assign
|
||
|
|
(
|
||
|
|
{
|
||
|
|
"blocking": true,
|
||
|
|
},
|
||
|
|
options
|
||
|
|
);
|
||
|
|
await view.setup(model);
|
||
|
|
model_listen
|
||
|
|
(
|
||
|
|
model,
|
||
|
|
(info) =>
|
||
|
|
{
|
||
|
|
if (options.blocking)
|
||
|
|
{
|
||
|
|
return view.update(model, info);
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
view.update(model, info);
|
||
|
|
return Promise.resolve<void>(undefined);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
*/
|
||
|
|
export async function control_setup<type_state>
|
||
|
|
(
|
||
|
|
control : type_control<type_state>,
|
||
|
|
model : type_model<type_state>,
|
||
|
|
options :
|
||
|
|
{
|
||
|
|
} = {}
|
||
|
|
) : Promise<void>
|
||
|
|
{
|
||
|
|
options = Object.assign
|
||
|
|
(
|
||
|
|
{
|
||
|
|
},
|
||
|
|
options
|
||
|
|
);
|
||
|
|
await control.setup(model);
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
*/
|
||
|
|
export async function complex_setup<type_state>
|
||
|
|
(
|
||
|
|
complex : type_complex<type_state>
|
||
|
|
) : Promise<void>
|
||
|
|
{
|
||
|
|
for await (const view of complex.views)
|
||
|
|
{
|
||
|
|
await view_setup<type_state>(view, complex.model);
|
||
|
|
}
|
||
|
|
for await (const control of complex.controls)
|
||
|
|
{
|
||
|
|
await control_setup<type_state>(control, complex.model);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|