{"version":3,"file":"ProjectContainerResolver.cjs","sources":["../../../../../packages/engine-http/src/project/ProjectContainerResolver.ts"],"sourcesContent":["import { ProjectContainer, ProjectContainerFactory } from './ProjectContainer'\nimport { DatabaseContext, ProjectManager, ProjectWithSecrets } from '@contember/engine-tenant-api'\nimport { ProjectContainerStore } from './ProjectContainerStore'\nimport { ProjectConfigResolver } from '../config/projectConfigResolver'\nimport { TenantConfig } from '../config/config'\nimport { Logger } from '@contember/logger'\nimport { EventEmitter, EventManager } from '@contember/engine-common'\n\nexport type ProjectContainerResolverEvents = {\n\tcreate: (args: { container: ProjectContainer}) => (() => void) | void\n\tdestroy: (args: { container: ProjectContainer}) => void\n}\n\nexport class ProjectContainerResolver implements EventEmitter<ProjectContainerResolverEvents> {\n\tprivate projectContainers = new ProjectContainerStore()\n\tprivate eventManager = new EventManager<ProjectContainerResolverEvents>()\n\n\tpublic readonly on = this.eventManager.on.bind(this.eventManager)\n\n\tconstructor(\n\t\tprivate readonly projectContainerFactory: ProjectContainerFactory,\n\t\tprivate readonly projectConfigResolver: ProjectConfigResolver,\n\t\tprivate readonly projectManager: ProjectManager,\n\t\tprivate readonly tenantDatabase: DatabaseContext,\n\t\tprivate readonly tenantConfig: TenantConfig,\n\t) {}\n\n\n\tpublic async getProjectContainer(slug: string, { alias = false }: { alias?: boolean } = {}): Promise<ProjectContainer | undefined> {\n\t\tconst realSlug = this.projectContainers.resolveAlias(slug)\n\t\tif (realSlug) {\n\t\t\tslug = realSlug\n\t\t}\n\t\tconst existing = this.projectContainers.getContainer(slug)\n\t\tif (existing) {\n\t\t\tconst existingAwaited = await existing\n\t\t\tconst state = await this.projectManager.getProjectState(this.tenantDatabase, slug, existingAwaited.timestamp)\n\t\t\tif (state === 'valid') {\n\t\t\t\treturn existingAwaited.container\n\t\t\t}\n\t\t\tawait this.destroyContainer(slug)\n\t\t\tif (state === 'not_found') {\n\t\t\t\treturn undefined\n\t\t\t}\n\t\t}\n\t\tconst project = await this.projectManager.getProjectWithSecretsBySlug(this.tenantDatabase, slug, alias)\n\t\tif (!project) {\n\t\t\treturn undefined\n\t\t}\n\t\tconst container = await this.createProjectContainer(project)\n\t\tif (slug !== project.slug) {\n\t\t\tthis.projectContainers.setAlias(project.slug, slug)\n\t\t}\n\t\treturn container\n\t}\n\n\tpublic async createProjectContainer(project: ProjectWithSecrets, logger?: Logger): Promise<ProjectContainer> {\n\t\tconst projectConfig = this.projectConfigResolver(project.slug, project.config, project.secrets, this.tenantConfig)\n\t\treturn (await this.projectContainers.fetchContainer(project.slug, async slug => {\n\t\t\tconst projectContainer = this.projectContainerFactory.createContainer({\n\t\t\t\tproject: projectConfig,\n\t\t\t})\n\t\t\tawait projectContainer.projectInitializer.initialize(logger ?? projectContainer.logger)\n\n\t\t\tconst cleanups = this.eventManager.fire('create', { container: projectContainer }).map(it => it ?? (() => null))\n\t\t\treturn {\n\t\t\t\tcontainer: projectContainer,\n\t\t\t\tcleanups,\n\t\t\t\ttimestamp: project.updatedAt,\n\t\t\t}\n\t\t})).container\n\t}\n\n\tpublic async destroyContainer(slug: string): Promise<void> {\n\t\tconst existing = this.projectContainers.getContainer(slug)\n\t\tif (existing) {\n\t\t\tconst existingAwaited = await existing\n\t\t\texistingAwaited.cleanups.forEach(it => it())\n\t\t\tthis.eventManager.fire('destroy', ({ container: existingAwaited.container }))\n\t\t\texistingAwaited.container.project.alias?.forEach(it => this.projectContainers.removeAlias(it))\n\t\t\tthis.projectContainers.removeContainer(slug)\n\t\t}\n\t\tprocess.nextTick(() => {\n\t\t\tif (global.gc) {\n\t\t\t\tglobal.gc()\n\t\t\t}\n\t\t})\n\t}\n}\n"],"names":["ProjectContainerStore","EventManager"],"mappings":";;;;;;;AAaO,MAAM,yBAAiF;AAAA,EAM7F,YACkB,yBACA,uBACA,gBACA,gBACA,cAChB;AALgB,SAAA,0BAAA;AACA,SAAA,wBAAA;AACA,SAAA,iBAAA;AACA,SAAA,iBAAA;AACA,SAAA,eAAA;AAVV,kBAAA,MAAA,qBAAoB,IAAIA,sBAAsB,sBAAA,CAAA;AAC9C,kBAAA,MAAA,gBAAe,IAAIC,aAA6C,aAAA,CAAA;AAExE,kBAAA,MAAgB,MAAK,KAAK,aAAa,GAAG,KAAK,KAAK,YAAY,CAAA;AAAA,EAAA;AAAA,EAWhE,MAAa,oBAAoB,MAAc,EAAE,QAAQ,MAAM,IAAyB,CAAA,GAA2C;AAClI,UAAM,WAAW,KAAK,kBAAkB,aAAa,IAAI;AACzD,QAAI,UAAU;AACN,aAAA;AAAA,IAAA;AAER,UAAM,WAAW,KAAK,kBAAkB,aAAa,IAAI;AACzD,QAAI,UAAU;AACb,YAAM,kBAAkB,MAAM;AACxB,YAAA,QAAQ,MAAM,KAAK,eAAe,gBAAgB,KAAK,gBAAgB,MAAM,gBAAgB,SAAS;AAC5G,UAAI,UAAU,SAAS;AACtB,eAAO,gBAAgB;AAAA,MAAA;AAElB,YAAA,KAAK,iBAAiB,IAAI;AAChC,UAAI,UAAU,aAAa;AACnB,eAAA;AAAA,MAAA;AAAA,IACR;AAEK,UAAA,UAAU,MAAM,KAAK,eAAe,4BAA4B,KAAK,gBAAgB,MAAM,KAAK;AACtG,QAAI,CAAC,SAAS;AACN,aAAA;AAAA,IAAA;AAER,UAAM,YAAY,MAAM,KAAK,uBAAuB,OAAO;AACvD,QAAA,SAAS,QAAQ,MAAM;AAC1B,WAAK,kBAAkB,SAAS,QAAQ,MAAM,IAAI;AAAA,IAAA;AAE5C,WAAA;AAAA,EAAA;AAAA,EAGR,MAAa,uBAAuB,SAA6B,QAA4C;AACtG,UAAA,gBAAgB,KAAK,sBAAsB,QAAQ,MAAM,QAAQ,QAAQ,QAAQ,SAAS,KAAK,YAAY;AACjH,YAAQ,MAAM,KAAK,kBAAkB,eAAe,QAAQ,MAAM,OAAM,SAAQ;AACzE,YAAA,mBAAmB,KAAK,wBAAwB,gBAAgB;AAAA,QACrE,SAAS;AAAA,MAAA,CACT;AACD,YAAM,iBAAiB,mBAAmB,WAAW,UAAU,iBAAiB,MAAM;AAEtF,YAAM,WAAW,KAAK,aAAa,KAAK,UAAU,EAAE,WAAW,iBAAiB,CAAC,EAAE,IAAI,CAAM,OAAA,OAAO,MAAM,KAAK;AACxG,aAAA;AAAA,QACN,WAAW;AAAA,QACX;AAAA,QACA,WAAW,QAAQ;AAAA,MACpB;AAAA,IACA,CAAA,GAAG;AAAA,EAAA;AAAA,EAGL,MAAa,iBAAiB,MAA6B;AAC1D,UAAM,WAAW,KAAK,kBAAkB,aAAa,IAAI;AACzD,QAAI,UAAU;AACb,YAAM,kBAAkB,MAAM;AAC9B,sBAAgB,SAAS,QAAQ,CAAM,OAAA,GAAA,CAAI;AAC3C,WAAK,aAAa,KAAK,WAAY,EAAE,WAAW,gBAAgB,WAAY;AAC5D,sBAAA,UAAU,QAAQ,OAAO,QAAQ,QAAM,KAAK,kBAAkB,YAAY,EAAE,CAAC;AACxF,WAAA,kBAAkB,gBAAgB,IAAI;AAAA,IAAA;AAE5C,YAAQ,SAAS,MAAM;AACtB,UAAI,OAAO,IAAI;AACd,eAAO,GAAG;AAAA,MAAA;AAAA,IACX,CACA;AAAA,EAAA;AAEH;;"}