ryde/source/logic/helpers/mvc.ts
2026-03-06 08:37:53 +01:00

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);
}
}
}