@grlt-hub/app-compose
Advanced tools
Comparing version 1.1.0 to 1.2.0
@@ -75,7 +75,12 @@ import * as effector from 'effector'; | ||
declare const compose: { | ||
up: <T extends AnyContainer[]>(containers: T, config?: { | ||
up: <T extends AnyContainer[], C extends { | ||
apis?: true; | ||
debug?: boolean; | ||
}) => Promise<{ | ||
} | undefined>(containers: T, config?: C) => Promise<undefined extends C ? { | ||
hasErrors: boolean; | ||
statuses: { [K in T[number]["id"]]: ContainerStatus; }; | ||
} : { | ||
apis: { [K_1 in T[number] as K_1["id"]]?: Awaited<ReturnType<K_1["start"]>>["api"] | undefined; }; | ||
hasErrors: boolean; | ||
statuses: { [K in T[number]["id"]]: ContainerStatus; }; | ||
}>; | ||
@@ -82,0 +87,0 @@ graph: (containers: AnyContainer[]) => { |
@@ -1,5 +0,5 @@ | ||
import{createStore as h}from"effector";import"effector";var s={idle:"idle",pending:"pending",done:"done",fail:"fail",off:"off"};var S={CONTAINER_ID_EMPTY_STRING:"Container ID cannot be an empty string.",depsIntersection:(e,o)=>` | ||
Dependency conflict detected in container '${o}': | ||
import{createStore as g}from"effector";import"effector";var i={idle:"idle",pending:"pending",done:"done",fail:"fail",off:"off"};var T={CONTAINER_ID_EMPTY_STRING:"Container ID cannot be an empty string.",depsIntersection:(e,s)=>` | ||
Dependency conflict detected in container '${s}': | ||
The following dependencies are listed as both required and optional: [${e.join(", ")}]. | ||
Each dependency should be listed only once, as either required or optional.`},R=e=>{if(e.id==="")throw new Error(S.CONTAINER_ID_EMPTY_STRING)},x=e=>{if(!e.dependsOn||!e.optionalDependsOn)return;let o=new Set(e.dependsOn.map(i=>i.id)),r=new Set(e.optionalDependsOn.map(i=>i.id)),c=o.intersection(r);if(c.size>0)throw new Error(S.depsIntersection(Array.from(c),e.id))},T=e=>(R(e),x(e),e);var P=e=>{let o=T(e),r=h(s.idle);return{...o,$status:r}};var I=e=>{var y,p;let o=new Set,r=[],c=[],i=[];for((e.dependsOn||[]).forEach(t=>i.push([t,[e.id,t.id],"strict"])),(e.optionalDependsOn||[]).forEach(t=>i.push([t,[e.id,t.id],"optional"]));i.length>0;){let[t,a,l]=i.pop();o.has(t.id)||(o.add(t.id),!((y=e.dependsOn)!=null&&y.includes(t))&&!((p=e.optionalDependsOn)!=null&&p.includes(t))&&(l==="strict"?r.push({id:t.id,path:a.join(" -> ")}):c.push({id:t.id,path:a.join(" -> ")})),(t.dependsOn||[]).forEach(d=>{i.push([d,[...a,d.id],l])}),(t.optionalDependsOn||[]).forEach(d=>{i.push([d,[...a,d.id],"optional"])}))}return{strict:r,optional:c}};var O=e=>e.reduce((o,r)=>{let c=(r.dependsOn||[]).map(p=>p.id),i=(r.optionalDependsOn||[]).map(p=>p.id),y=I(r);return o[r.id]={strict:c,optional:i,transitive:{strict:y.strict,optional:y.optional}},o},{});import{clearNode as b,combine as D,createEffect as v,launch as w,sample as A}from"effector";var N=(e,o)=>{if(o.has(e))throw new Error(`Duplicate container ID found: ${e}`);o.add(e)},u={off:e=>e===s.off,fail:e=>e===s.fail,pending:e=>e===s.pending,done:e=>e===s.done,idle:e=>e===s.idle},g=async(e,o)=>{let r=new Set;for(let t of e)N(t.id,r);let c=e.reduce((t,a)=>(t[a.id]=a.$status,t),{}),i=D(c,t=>{let a=Object.values(t),l=a.every(f=>/^(done|fail|off)$/.test(f)),d=a.some(u.fail);return{done:l,hasErrors:d,statuses:t}});o!=null&&o.debug&&i.watch(t=>{console.debug(`[${new Date().toISOString()}] app-compose:`,JSON.stringify(t.statuses,null,2))});let y=[i],p={};return await Promise.all(e.map(async t=>{var m,C;let a=D(((m=t.dependsOn)!=null?m:[]).map(n=>n.$status),n=>n.some(u.off)?s.off:n.some(u.fail)?s.fail:n.some(u.pending)?s.pending:n.every(u.done)||n.length===0?s.done:s.idle),l=D(((C=t.optionalDependsOn)!=null?C:[]).map(n=>n.$status),n=>n.some(u.pending)?s.pending:n.some(u.idle)?s.idle:s.done),d=D([a,l],n=>n.every(u.done)),f=v(async()=>t.enable?await t.enable(p,p):!0),E=v(async()=>{p[t.id]=(await t.start(p,p)).api});A({clock:f.doneData,fn:n=>n?s.pending:s.off,target:t.$status}),A({clock:f.failData,fn:()=>s.fail,target:t.$status}),A({clock:t.$status,filter:u.pending,target:E}),A({clock:E.finally,fn:n=>n.status,target:t.$status}),a.watch(n=>{(u.off(n)||u.fail(n))&&w(t.$status,n)}),d.watch(n=>{n&&f()}),y=[...y,a,l,d,f,E]})),new Promise((t,a)=>{i.watch(l=>{if(l.done===!0){p={},y.forEach(f=>b(f,{deep:!0}));let d={hasErrors:l.hasErrors,statuses:l.statuses};l.hasErrors&&a(d),t(d)}})})};var $={up:g,graph:O};export{$ as compose,P as createContainer}; | ||
Each dependency should be listed only once, as either required or optional.`},R=e=>{if(e.id==="")throw new Error(T.CONTAINER_ID_EMPTY_STRING)},h=e=>{if(!e.dependsOn||!e.optionalDependsOn)return;let s=new Set(e.dependsOn.map(a=>a.id)),p=new Set(e.optionalDependsOn.map(a=>a.id)),y=s.intersection(p);if(y.size>0)throw new Error(T.depsIntersection(Array.from(y),e.id))},S=e=>(R(e),h(e),e);var P=e=>{let s=S(e),p=g(i.idle);return{...s,$status:p}};var I=e=>{var c,r;let s=new Set,p=[],y=[],a=[];for((e.dependsOn||[]).forEach(t=>a.push([t,[e.id,t.id],"strict"])),(e.optionalDependsOn||[]).forEach(t=>a.push([t,[e.id,t.id],"optional"]));a.length>0;){let[t,o,l]=a.pop();s.has(t.id)||(s.add(t.id),!((c=e.dependsOn)!=null&&c.includes(t))&&!((r=e.optionalDependsOn)!=null&&r.includes(t))&&(l==="strict"?p.push({id:t.id,path:o.join(" -> ")}):y.push({id:t.id,path:o.join(" -> ")})),(t.dependsOn||[]).forEach(d=>{a.push([d,[...o,d.id],l])}),(t.optionalDependsOn||[]).forEach(d=>{a.push([d,[...o,d.id],"optional"])}))}return{strict:p,optional:y}};var O=e=>e.reduce((s,p)=>{let y=(p.dependsOn||[]).map(r=>r.id),a=(p.optionalDependsOn||[]).map(r=>r.id),c=I(p);return s[p.id]={strict:y,optional:a,transitive:{strict:c.strict,optional:c.optional}},s},{});import{clearNode as b,combine as A,createEffect as v,launch as w,sample as E}from"effector";var N=(e,s)=>{if(s.has(e))throw new Error(`Duplicate container ID found: ${e}`);s.add(e)},u={off:e=>e===i.off,fail:e=>e===i.fail,pending:e=>e===i.pending,done:e=>e===i.done,idle:e=>e===i.idle},x=async(e,s)=>{let p=new Set;for(let t of e)N(t.id,p);let y=e.reduce((t,o)=>(t[o.id]=o.$status,t),{}),a=A(y,t=>{let o=Object.values(t),l=o.every(f=>/^(done|fail|off)$/.test(f)),d=o.some(u.fail);return{done:l,hasErrors:d,statuses:t}});s!=null&&s.debug&&a.watch(t=>{console.debug(`[${new Date().toISOString()}] app-compose:`,JSON.stringify(t.statuses,null,2))});let c=[a],r={};return await Promise.allSettled(e.map(t=>{var C,m;let o=A(((C=t.dependsOn)!=null?C:[]).map(n=>n.$status),n=>n.some(u.off)?i.off:n.some(u.fail)?i.fail:n.some(u.pending)?i.pending:n.every(u.done)||n.length===0?i.done:i.idle),l=A(((m=t.optionalDependsOn)!=null?m:[]).map(n=>n.$status),n=>n.some(u.pending)?i.pending:n.some(u.idle)?i.idle:i.done),d=A([o,l],n=>n.every(u.done)),f=v(async()=>t.enable?await t.enable(r,r):!0),D=v(async()=>{r[t.id]=(await t.start(r,r)).api});E({clock:f.doneData,fn:n=>n?i.pending:i.off,target:t.$status}),E({clock:f.failData,fn:()=>i.fail,target:t.$status}),E({clock:t.$status,filter:u.pending,target:D}),E({clock:D.finally,fn:n=>n.status,target:t.$status}),o.watch(n=>{(u.off(n)||u.fail(n))&&w(t.$status,n)}),d.watch(n=>{n&&f()}),c=[...c,o,l,d,f,D]})),new Promise((t,o)=>{a.watch(l=>{if(l.done===!0){c.forEach(D=>b(D,{deep:!0}));let d=(s==null?void 0:s.apis)===!0;d||(r={});let f={hasErrors:l.hasErrors,statuses:l.statuses,...d?{apis:r}:{}};l.hasErrors&&o(f),t(f)}})})};var $={up:x,graph:O};export{$ as compose,P as createContainer}; |
{ | ||
"name": "@grlt-hub/app-compose", | ||
"version": "1.1.0", | ||
"version": "1.2.0", | ||
"type": "module", | ||
@@ -26,3 +26,3 @@ "private": false, | ||
}, | ||
"homepage": "https://github.com/grlt-hub/app-compose/blob/main/README.md", | ||
"homepage": "https://grlt-hub.github.io/app-compose/", | ||
"description": "Create scalable, module-based applications with ease.", | ||
@@ -29,0 +29,0 @@ "keywords": [ |
13555
107