@highstate/backend 0.9.3 → 0.9.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -29,21 +29,24 @@ async function loadLibrary(jiti2, logger2, modulePaths) {
29
29
  const modules = {};
30
30
  for (const modulePath of modulePaths) {
31
31
  try {
32
- logger2.debug("loading module", { modulePath });
32
+ logger2.debug({ modulePath }, "loading module");
33
33
  modules[modulePath] = await jiti2.import(modulePath);
34
- logger2.debug("module loaded", { modulePath });
35
- } catch (error) {
36
- logger2.error("module load failed", { modulePath, error });
34
+ logger2.debug({ modulePath }, "module loaded");
35
+ } catch (err) {
36
+ logger2.error({ modulePath, err }, "module load failed");
37
37
  }
38
38
  }
39
39
  const components = {};
40
40
  const entities = {};
41
41
  await _loadLibrary(modules, components, entities);
42
- logger2.info("library loaded", {
43
- componentCount: Object.keys(components).length,
44
- entityCount: Object.keys(entities).length
45
- });
46
- logger2.trace("library content", { components, entities });
42
+ logger2.info(
43
+ {
44
+ componentCount: Object.keys(components).length,
45
+ entityCount: Object.keys(entities).length
46
+ },
47
+ "library loaded"
48
+ );
49
+ logger2.trace({ components, entities }, "library content");
47
50
  return { components, entities };
48
51
  }
49
52
  async function _loadLibrary(value, components, entities) {
@@ -109,11 +112,12 @@ function evaluateModules(jiti2, logger2, modulePaths) {
109
112
  function evaluateInstances(logger2, library2, allInstances, resolvedInputs, instanceIds) {
110
113
  const results = [];
111
114
  const allInstancesMap = new Map(allInstances.map((instance) => [instance.id, instance]));
112
- const instanceOutputs = /* @__PURE__ */ new Map();
113
115
  for (const instanceId of instanceIds ?? []) {
116
+ const externalInstanceIds = new Set(allInstances.map((instance) => instance.id));
117
+ externalInstanceIds.delete(instanceId);
114
118
  try {
115
119
  logger2.debug({ instanceId }, "evaluating top-level instance");
116
- resetEvaluation();
120
+ resetEvaluation(externalInstanceIds);
117
121
  evaluateInstance(instanceId);
118
122
  results.push({
119
123
  success: true,
@@ -129,15 +133,15 @@ function evaluateInstances(logger2, library2, allInstances, resolvedInputs, inst
129
133
  }
130
134
  }
131
135
  return results;
132
- function evaluateInstance(instanceId) {
136
+ function evaluateInstance(instanceId, instanceOutputs = /* @__PURE__ */ new Map()) {
133
137
  let outputs = instanceOutputs.get(instanceId);
134
138
  if (!outputs) {
135
- outputs = _evaluateInstance(instanceId);
139
+ outputs = _evaluateInstance(instanceId, instanceOutputs);
136
140
  instanceOutputs.set(instanceId, outputs);
137
141
  }
138
142
  return outputs;
139
143
  }
140
- function _evaluateInstance(instanceId) {
144
+ function _evaluateInstance(instanceId, instanceOutputs) {
141
145
  const inputs = {};
142
146
  const instance = allInstancesMap.get(instanceId);
143
147
  logger2.info("evaluating instance", { instanceId });
@@ -146,7 +150,7 @@ function evaluateInstances(logger2, library2, allInstances, resolvedInputs, inst
146
150
  }
147
151
  for (const [inputName, input] of Object.entries(resolvedInputs[instanceId] ?? {})) {
148
152
  inputs[inputName] = input.map((input2) => {
149
- const evaluated = evaluateInstance(input2.input.instanceId);
153
+ const evaluated = evaluateInstance(input2.input.instanceId, instanceOutputs);
150
154
  return evaluated[input2.input.output];
151
155
  });
152
156
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/library/worker/main.ts","../../../src/library/worker/loader.ts","../../../src/library/worker/evaluator.ts"],"sourcesContent":["import type { WorkerData, WorkerRequest, WorkerResponse } from \"./protocol\"\nimport { parentPort, workerData } from \"node:worker_threads\"\nimport { createJiti, type Jiti } from \"jiti\"\nimport { pino } from \"pino\"\nimport { mapValues } from \"remeda\"\nimport { errorToString } from \"../../common\"\nimport { loadLibrary, type Library } from \"./loader\"\nimport { evaluateInstances, evaluateModules } from \"./evaluator\"\n\nconst data = workerData as WorkerData\n\nconst logger = pino({ name: \"library-worker\", level: data.logLevel })\nlet jiti: Jiti\nlet library: Library\n\ntry {\n logger.info(\"worker started\")\n logger.trace({ data }, \"worker data\")\n\n jiti = createJiti(import.meta.filename)\n logger.debug({ filename: import.meta.filename }, \"jiti created\")\n\n library = await loadLibrary(jiti, logger, data.modulePaths)\n\n parentPort!.postMessage({\n type: \"library\",\n library: {\n components: mapValues(library.components, component => component.model),\n entities: library.entities,\n },\n } satisfies WorkerResponse)\n\n logger.info(\"library loaded and sent\")\n} catch (error) {\n logger.error({ error }, \"failed to load library\")\n\n parentPort!.postMessage({\n type: \"error\",\n error: errorToString(error),\n })\n}\n\n// eslint-disable-next-line @typescript-eslint/no-misused-promises\nparentPort!.on(\"message\", async message => {\n try {\n const request = message as WorkerRequest\n\n switch (request.type) {\n case \"evaluate-composite-instances\": {\n const results = evaluateInstances(\n logger,\n library,\n request.allInstances,\n request.resolvedInputs,\n request.instanceIds,\n )\n\n parentPort!.postMessage({\n type: \"instance-evaluation-results\",\n results,\n } satisfies WorkerResponse)\n break\n }\n case \"evaluate-modules\": {\n const result = await evaluateModules(jiti, logger, request.modulePaths)\n\n parentPort!.postMessage({\n type: \"module-evaluation-result\",\n result,\n } satisfies WorkerResponse)\n break\n }\n }\n } catch (error) {\n logger.error({ error }, \"failed to evaluate\")\n\n parentPort!.postMessage({\n type: \"error\",\n error: errorToString(error),\n } satisfies WorkerResponse)\n }\n})\n","import type { Logger } from \"pino\"\nimport type { Jiti } from \"jiti\"\nimport Module from \"node:module\"\nimport {\n type Component,\n type Entity,\n isComponent,\n isEntity,\n isUnitModel,\n originalCreate,\n} from \"@highstate/contract\"\nimport { serializeFunction } from \"@pulumi/pulumi/runtime/index.js\"\nimport { sha256 } from \"crypto-hash\"\n\ndeclare module \"module\" {\n // eslint-disable-next-line @typescript-eslint/no-namespace\n namespace Module {\n function _load(request: unknown, parent: unknown, isMain: boolean): unknown\n }\n}\n\nconst originalLoad = Module._load\n\nModule._load = function (request: unknown, parent: unknown, isMain: boolean) {\n if (request === \"trace_events\") {\n return {}\n }\n\n return originalLoad(request, parent, isMain)\n}\n\nexport type Library = Readonly<{\n components: Readonly<Record<string, Component>>\n entities: Readonly<Record<string, Entity>>\n}>\n\nexport async function loadLibrary(\n jiti: Jiti,\n logger: Logger,\n modulePaths: string[],\n): Promise<Library> {\n const modules: Record<string, unknown> = {}\n for (const modulePath of modulePaths) {\n try {\n logger.debug(\"loading module\", { modulePath })\n modules[modulePath] = await jiti.import(modulePath)\n\n logger.debug(\"module loaded\", { modulePath })\n } catch (error) {\n logger.error(\"module load failed\", { modulePath, error })\n }\n }\n\n const components: Record<string, Component> = {}\n const entities: Record<string, Entity> = {}\n\n await _loadLibrary(modules, components, entities)\n\n logger.info(\"library loaded\", {\n componentCount: Object.keys(components).length,\n entityCount: Object.keys(entities).length,\n })\n\n logger.trace(\"library content\", { components, entities })\n\n return { components, entities }\n}\n\nasync function _loadLibrary(\n value: unknown,\n components: Record<string, Component>,\n entities: Record<string, Entity>,\n): Promise<void> {\n if (isComponent(value)) {\n components[value.model.type] = value\n value.model.definitionHash = await calculateComponentDefinitionHash(value)\n\n for (const entity of value.entities.values()) {\n entity.definitionHash ??= await calculateEntityDefinitionHash(entity)\n }\n return\n }\n\n if (isEntity(value)) {\n entities[value.type] = value\n entities[value.type].definitionHash ??= await calculateEntityDefinitionHash(value)\n return\n }\n\n if (typeof value !== \"object\" || value === null) {\n return\n }\n\n for (const key in value) {\n await _loadLibrary((value as Record<string, unknown>)[key], components, entities)\n }\n}\n\nasync function calculateComponentDefinitionHash(component: Component): Promise<string> {\n if (isUnitModel(component.model)) {\n return await sha256(JSON.stringify(component.model))\n }\n\n const serializedCreate = await serializeFunction(component[originalCreate])\n\n return await sha256(JSON.stringify(component.model) + serializedCreate.text)\n}\n\nasync function calculateEntityDefinitionHash(entity: Entity): Promise<string> {\n return await sha256(JSON.stringify(entity))\n}\n","import type { Logger } from \"pino\"\nimport type { Library } from \"./loader\"\nimport type { Jiti } from \"jiti\"\nimport type { InstanceEvaluationResult, ModuleEvaluationResult } from \"../abstractions\"\nimport type { ResolvedInstanceInput } from \"../../shared\"\nimport { getCompositeInstances, resetEvaluation, type InstanceModel } from \"@highstate/contract\"\nimport { BetterLock } from \"better-lock\"\nimport { errorToString } from \"../../common\"\n\nconst lock = new BetterLock()\n\nexport function evaluateModules(\n jiti: Jiti,\n logger: Logger,\n modulePaths: string[],\n): Promise<ModuleEvaluationResult> {\n return lock.acquire(async () => {\n resetEvaluation()\n let lastModulePath = \"\"\n\n try {\n for (const modulePath of modulePaths) {\n logger.info(\"loading module: %s\", modulePath)\n\n lastModulePath = modulePath\n await jiti.import(modulePath)\n\n logger.debug(\"module loaded: %s\", modulePath)\n }\n\n return {\n success: true,\n compositeInstances: getCompositeInstances(),\n }\n } catch (error) {\n return {\n success: false,\n modulePath: lastModulePath,\n error: errorToString(error),\n }\n }\n })\n}\n\nexport function evaluateInstances(\n logger: Logger,\n library: Library,\n allInstances: InstanceModel[],\n resolvedInputs: Record<string, Record<string, ResolvedInstanceInput[]>>,\n instanceIds: string[],\n): InstanceEvaluationResult[] {\n const results: InstanceEvaluationResult[] = []\n const allInstancesMap = new Map(allInstances.map(instance => [instance.id, instance]))\n const instanceOutputs = new Map<string, Record<string, unknown>>()\n\n for (const instanceId of instanceIds ?? []) {\n try {\n logger.debug({ instanceId }, \"evaluating top-level instance\")\n resetEvaluation()\n\n evaluateInstance(instanceId)\n\n results.push({\n success: true,\n instanceId,\n compositeInstances: getCompositeInstances(),\n })\n } catch (error) {\n results.push({\n success: false,\n instanceId,\n error: errorToString(error),\n })\n }\n }\n\n return results\n\n function evaluateInstance(instanceId: string): Record<string, unknown> {\n let outputs = instanceOutputs.get(instanceId)\n\n if (!outputs) {\n outputs = _evaluateInstance(instanceId)\n instanceOutputs.set(instanceId, outputs)\n }\n\n return outputs\n }\n\n function _evaluateInstance(instanceId: string): Record<string, unknown> {\n const inputs: Record<string, unknown> = {}\n const instance = allInstancesMap.get(instanceId)\n\n logger.info(\"evaluating instance\", { instanceId })\n\n if (!instance) {\n throw new Error(`Instance not found: ${instanceId}`)\n }\n\n for (const [inputName, input] of Object.entries(resolvedInputs[instanceId] ?? {})) {\n inputs[inputName] = input.map(input => {\n const evaluated = evaluateInstance(input.input.instanceId)\n\n return evaluated[input.input.output]\n })\n }\n\n const component = library.components[instance.type]\n if (!component) {\n throw new Error(`Component not found: ${instance.type}, required by instance: ${instanceId}`)\n }\n\n return component({\n name: instance.name,\n args: instance.args as Record<string, never>,\n inputs: inputs as Record<string, never>,\n })\n }\n}\n"],"mappings":";;;;;AACA,SAAS,YAAY,kBAAkB;AACvC,SAAS,kBAA6B;AACtC,SAAS,YAAY;AACrB,SAAS,iBAAiB;;;ACF1B,OAAO,YAAY;AACnB;AAAA,EAGE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,yBAAyB;AAClC,SAAS,cAAc;AASvB,IAAM,eAAe,OAAO;AAE5B,OAAO,QAAQ,SAAU,SAAkB,QAAiB,QAAiB;AAC3E,MAAI,YAAY,gBAAgB;AAC9B,WAAO,CAAC;AAAA,EACV;AAEA,SAAO,aAAa,SAAS,QAAQ,MAAM;AAC7C;AAOA,eAAsB,YACpBA,OACAC,SACA,aACkB;AAClB,QAAM,UAAmC,CAAC;AAC1C,aAAW,cAAc,aAAa;AACpC,QAAI;AACF,MAAAA,QAAO,MAAM,kBAAkB,EAAE,WAAW,CAAC;AAC7C,cAAQ,UAAU,IAAI,MAAMD,MAAK,OAAO,UAAU;AAElD,MAAAC,QAAO,MAAM,iBAAiB,EAAE,WAAW,CAAC;AAAA,IAC9C,SAAS,OAAO;AACd,MAAAA,QAAO,MAAM,sBAAsB,EAAE,YAAY,MAAM,CAAC;AAAA,IAC1D;AAAA,EACF;AAEA,QAAM,aAAwC,CAAC;AAC/C,QAAM,WAAmC,CAAC;AAE1C,QAAM,aAAa,SAAS,YAAY,QAAQ;AAEhD,EAAAA,QAAO,KAAK,kBAAkB;AAAA,IAC5B,gBAAgB,OAAO,KAAK,UAAU,EAAE;AAAA,IACxC,aAAa,OAAO,KAAK,QAAQ,EAAE;AAAA,EACrC,CAAC;AAED,EAAAA,QAAO,MAAM,mBAAmB,EAAE,YAAY,SAAS,CAAC;AAExD,SAAO,EAAE,YAAY,SAAS;AAChC;AAEA,eAAe,aACb,OACA,YACA,UACe;AACf,MAAI,YAAY,KAAK,GAAG;AACtB,eAAW,MAAM,MAAM,IAAI,IAAI;AAC/B,UAAM,MAAM,iBAAiB,MAAM,iCAAiC,KAAK;AAEzE,eAAW,UAAU,MAAM,SAAS,OAAO,GAAG;AAC5C,aAAO,mBAAmB,MAAM,8BAA8B,MAAM;AAAA,IACtE;AACA;AAAA,EACF;AAEA,MAAI,SAAS,KAAK,GAAG;AACnB,aAAS,MAAM,IAAI,IAAI;AACvB,aAAS,MAAM,IAAI,EAAE,mBAAmB,MAAM,8BAA8B,KAAK;AACjF;AAAA,EACF;AAEA,MAAI,OAAO,UAAU,YAAY,UAAU,MAAM;AAC/C;AAAA,EACF;AAEA,aAAW,OAAO,OAAO;AACvB,UAAM,aAAc,MAAkC,GAAG,GAAG,YAAY,QAAQ;AAAA,EAClF;AACF;AAEA,eAAe,iCAAiC,WAAuC;AACrF,MAAI,YAAY,UAAU,KAAK,GAAG;AAChC,WAAO,MAAM,OAAO,KAAK,UAAU,UAAU,KAAK,CAAC;AAAA,EACrD;AAEA,QAAM,mBAAmB,MAAM,kBAAkB,UAAU,cAAc,CAAC;AAE1E,SAAO,MAAM,OAAO,KAAK,UAAU,UAAU,KAAK,IAAI,iBAAiB,IAAI;AAC7E;AAEA,eAAe,8BAA8B,QAAiC;AAC5E,SAAO,MAAM,OAAO,KAAK,UAAU,MAAM,CAAC;AAC5C;;;ACzGA,SAAS,uBAAuB,uBAA2C;AAC3E,SAAS,kBAAkB;AAG3B,IAAM,OAAO,IAAI,WAAW;AAErB,SAAS,gBACdC,OACAC,SACA,aACiC;AACjC,SAAO,KAAK,QAAQ,YAAY;AAC9B,oBAAgB;AAChB,QAAI,iBAAiB;AAErB,QAAI;AACF,iBAAW,cAAc,aAAa;AACpC,QAAAA,QAAO,KAAK,sBAAsB,UAAU;AAE5C,yBAAiB;AACjB,cAAMD,MAAK,OAAO,UAAU;AAE5B,QAAAC,QAAO,MAAM,qBAAqB,UAAU;AAAA,MAC9C;AAEA,aAAO;AAAA,QACL,SAAS;AAAA,QACT,oBAAoB,sBAAsB;AAAA,MAC5C;AAAA,IACF,SAAS,OAAO;AACd,aAAO;AAAA,QACL,SAAS;AAAA,QACT,YAAY;AAAA,QACZ,OAAO,cAAc,KAAK;AAAA,MAC5B;AAAA,IACF;AAAA,EACF,CAAC;AACH;AAEO,SAAS,kBACdA,SACAC,UACA,cACA,gBACA,aAC4B;AAC5B,QAAM,UAAsC,CAAC;AAC7C,QAAM,kBAAkB,IAAI,IAAI,aAAa,IAAI,cAAY,CAAC,SAAS,IAAI,QAAQ,CAAC,CAAC;AACrF,QAAM,kBAAkB,oBAAI,IAAqC;AAEjE,aAAW,cAAc,eAAe,CAAC,GAAG;AAC1C,QAAI;AACF,MAAAD,QAAO,MAAM,EAAE,WAAW,GAAG,+BAA+B;AAC5D,sBAAgB;AAEhB,uBAAiB,UAAU;AAE3B,cAAQ,KAAK;AAAA,QACX,SAAS;AAAA,QACT;AAAA,QACA,oBAAoB,sBAAsB;AAAA,MAC5C,CAAC;AAAA,IACH,SAAS,OAAO;AACd,cAAQ,KAAK;AAAA,QACX,SAAS;AAAA,QACT;AAAA,QACA,OAAO,cAAc,KAAK;AAAA,MAC5B,CAAC;AAAA,IACH;AAAA,EACF;AAEA,SAAO;AAEP,WAAS,iBAAiB,YAA6C;AACrE,QAAI,UAAU,gBAAgB,IAAI,UAAU;AAE5C,QAAI,CAAC,SAAS;AACZ,gBAAU,kBAAkB,UAAU;AACtC,sBAAgB,IAAI,YAAY,OAAO;AAAA,IACzC;AAEA,WAAO;AAAA,EACT;AAEA,WAAS,kBAAkB,YAA6C;AACtE,UAAM,SAAkC,CAAC;AACzC,UAAM,WAAW,gBAAgB,IAAI,UAAU;AAE/C,IAAAA,QAAO,KAAK,uBAAuB,EAAE,WAAW,CAAC;AAEjD,QAAI,CAAC,UAAU;AACb,YAAM,IAAI,MAAM,uBAAuB,UAAU,EAAE;AAAA,IACrD;AAEA,eAAW,CAAC,WAAW,KAAK,KAAK,OAAO,QAAQ,eAAe,UAAU,KAAK,CAAC,CAAC,GAAG;AACjF,aAAO,SAAS,IAAI,MAAM,IAAI,CAAAE,WAAS;AACrC,cAAM,YAAY,iBAAiBA,OAAM,MAAM,UAAU;AAEzD,eAAO,UAAUA,OAAM,MAAM,MAAM;AAAA,MACrC,CAAC;AAAA,IACH;AAEA,UAAM,YAAYD,SAAQ,WAAW,SAAS,IAAI;AAClD,QAAI,CAAC,WAAW;AACd,YAAM,IAAI,MAAM,wBAAwB,SAAS,IAAI,2BAA2B,UAAU,EAAE;AAAA,IAC9F;AAEA,WAAO,UAAU;AAAA,MACf,MAAM,SAAS;AAAA,MACf,MAAM,SAAS;AAAA,MACf;AAAA,IACF,CAAC;AAAA,EACH;AACF;;;AF7GA,IAAM,OAAO;AAEb,IAAM,SAAS,KAAK,EAAE,MAAM,kBAAkB,OAAO,KAAK,SAAS,CAAC;AACpE,IAAI;AACJ,IAAI;AAEJ,IAAI;AACF,SAAO,KAAK,gBAAgB;AAC5B,SAAO,MAAM,EAAE,KAAK,GAAG,aAAa;AAEpC,SAAO,WAAW,YAAY,QAAQ;AACtC,SAAO,MAAM,EAAE,UAAU,YAAY,SAAS,GAAG,cAAc;AAE/D,YAAU,MAAM,YAAY,MAAM,QAAQ,KAAK,WAAW;AAE1D,aAAY,YAAY;AAAA,IACtB,MAAM;AAAA,IACN,SAAS;AAAA,MACP,YAAY,UAAU,QAAQ,YAAY,eAAa,UAAU,KAAK;AAAA,MACtE,UAAU,QAAQ;AAAA,IACpB;AAAA,EACF,CAA0B;AAE1B,SAAO,KAAK,yBAAyB;AACvC,SAAS,OAAO;AACd,SAAO,MAAM,EAAE,MAAM,GAAG,wBAAwB;AAEhD,aAAY,YAAY;AAAA,IACtB,MAAM;AAAA,IACN,OAAO,cAAc,KAAK;AAAA,EAC5B,CAAC;AACH;AAGA,WAAY,GAAG,WAAW,OAAM,YAAW;AACzC,MAAI;AACF,UAAM,UAAU;AAEhB,YAAQ,QAAQ,MAAM;AAAA,MACpB,KAAK,gCAAgC;AACnC,cAAM,UAAU;AAAA,UACd;AAAA,UACA;AAAA,UACA,QAAQ;AAAA,UACR,QAAQ;AAAA,UACR,QAAQ;AAAA,QACV;AAEA,mBAAY,YAAY;AAAA,UACtB,MAAM;AAAA,UACN;AAAA,QACF,CAA0B;AAC1B;AAAA,MACF;AAAA,MACA,KAAK,oBAAoB;AACvB,cAAM,SAAS,MAAM,gBAAgB,MAAM,QAAQ,QAAQ,WAAW;AAEtE,mBAAY,YAAY;AAAA,UACtB,MAAM;AAAA,UACN;AAAA,QACF,CAA0B;AAC1B;AAAA,MACF;AAAA,IACF;AAAA,EACF,SAAS,OAAO;AACd,WAAO,MAAM,EAAE,MAAM,GAAG,oBAAoB;AAE5C,eAAY,YAAY;AAAA,MACtB,MAAM;AAAA,MACN,OAAO,cAAc,KAAK;AAAA,IAC5B,CAA0B;AAAA,EAC5B;AACF,CAAC;","names":["jiti","logger","jiti","logger","library","input"]}
1
+ {"version":3,"sources":["../../../src/library/worker/main.ts","../../../src/library/worker/loader.ts","../../../src/library/worker/evaluator.ts"],"sourcesContent":["import type { WorkerData, WorkerRequest, WorkerResponse } from \"./protocol\"\nimport { parentPort, workerData } from \"node:worker_threads\"\nimport { createJiti, type Jiti } from \"jiti\"\nimport { pino } from \"pino\"\nimport { mapValues } from \"remeda\"\nimport { errorToString } from \"../../common\"\nimport { loadLibrary, type Library } from \"./loader\"\nimport { evaluateInstances, evaluateModules } from \"./evaluator\"\n\nconst data = workerData as WorkerData\n\nconst logger = pino({ name: \"library-worker\", level: data.logLevel })\nlet jiti: Jiti\nlet library: Library\n\ntry {\n logger.info(\"worker started\")\n logger.trace({ data }, \"worker data\")\n\n jiti = createJiti(import.meta.filename)\n logger.debug({ filename: import.meta.filename }, \"jiti created\")\n\n library = await loadLibrary(jiti, logger, data.modulePaths)\n\n parentPort!.postMessage({\n type: \"library\",\n library: {\n components: mapValues(library.components, component => component.model),\n entities: library.entities,\n },\n } satisfies WorkerResponse)\n\n logger.info(\"library loaded and sent\")\n} catch (error) {\n logger.error({ error }, \"failed to load library\")\n\n parentPort!.postMessage({\n type: \"error\",\n error: errorToString(error),\n })\n}\n\n// eslint-disable-next-line @typescript-eslint/no-misused-promises\nparentPort!.on(\"message\", async message => {\n try {\n const request = message as WorkerRequest\n\n switch (request.type) {\n case \"evaluate-composite-instances\": {\n const results = evaluateInstances(\n logger,\n library,\n request.allInstances,\n request.resolvedInputs,\n request.instanceIds,\n )\n\n parentPort!.postMessage({\n type: \"instance-evaluation-results\",\n results,\n } satisfies WorkerResponse)\n break\n }\n case \"evaluate-modules\": {\n const result = await evaluateModules(jiti, logger, request.modulePaths)\n\n parentPort!.postMessage({\n type: \"module-evaluation-result\",\n result,\n } satisfies WorkerResponse)\n break\n }\n }\n } catch (error) {\n logger.error({ error }, \"failed to evaluate\")\n\n parentPort!.postMessage({\n type: \"error\",\n error: errorToString(error),\n } satisfies WorkerResponse)\n }\n})\n","import type { Logger } from \"pino\"\nimport type { Jiti } from \"jiti\"\nimport Module from \"node:module\"\nimport {\n type Component,\n type Entity,\n isComponent,\n isEntity,\n isUnitModel,\n originalCreate,\n} from \"@highstate/contract\"\nimport { serializeFunction } from \"@pulumi/pulumi/runtime/index.js\"\nimport { sha256 } from \"crypto-hash\"\n\ndeclare module \"module\" {\n // eslint-disable-next-line @typescript-eslint/no-namespace\n namespace Module {\n function _load(request: unknown, parent: unknown, isMain: boolean): unknown\n }\n}\n\nconst originalLoad = Module._load\n\nModule._load = function (request: unknown, parent: unknown, isMain: boolean) {\n if (request === \"trace_events\") {\n return {}\n }\n\n return originalLoad(request, parent, isMain)\n}\n\nexport type Library = Readonly<{\n components: Readonly<Record<string, Component>>\n entities: Readonly<Record<string, Entity>>\n}>\n\nexport async function loadLibrary(\n jiti: Jiti,\n logger: Logger,\n modulePaths: string[],\n): Promise<Library> {\n const modules: Record<string, unknown> = {}\n for (const modulePath of modulePaths) {\n try {\n logger.debug({ modulePath }, \"loading module\")\n modules[modulePath] = await jiti.import(modulePath)\n\n logger.debug({ modulePath }, \"module loaded\")\n } catch (err) {\n logger.error({ modulePath, err }, \"module load failed\")\n }\n }\n\n const components: Record<string, Component> = {}\n const entities: Record<string, Entity> = {}\n\n await _loadLibrary(modules, components, entities)\n\n logger.info(\n {\n componentCount: Object.keys(components).length,\n entityCount: Object.keys(entities).length,\n },\n \"library loaded\",\n )\n\n logger.trace({ components, entities }, \"library content\")\n\n return { components, entities }\n}\n\nasync function _loadLibrary(\n value: unknown,\n components: Record<string, Component>,\n entities: Record<string, Entity>,\n): Promise<void> {\n if (isComponent(value)) {\n components[value.model.type] = value\n value.model.definitionHash = await calculateComponentDefinitionHash(value)\n\n for (const entity of value.entities.values()) {\n entity.definitionHash ??= await calculateEntityDefinitionHash(entity)\n }\n return\n }\n\n if (isEntity(value)) {\n entities[value.type] = value\n entities[value.type].definitionHash ??= await calculateEntityDefinitionHash(value)\n return\n }\n\n if (typeof value !== \"object\" || value === null) {\n return\n }\n\n for (const key in value) {\n await _loadLibrary((value as Record<string, unknown>)[key], components, entities)\n }\n}\n\nasync function calculateComponentDefinitionHash(component: Component): Promise<string> {\n if (isUnitModel(component.model)) {\n return await sha256(JSON.stringify(component.model))\n }\n\n const serializedCreate = await serializeFunction(component[originalCreate])\n\n return await sha256(JSON.stringify(component.model) + serializedCreate.text)\n}\n\nasync function calculateEntityDefinitionHash(entity: Entity): Promise<string> {\n return await sha256(JSON.stringify(entity))\n}\n","import type { Logger } from \"pino\"\nimport type { Library } from \"./loader\"\nimport type { Jiti } from \"jiti\"\nimport type { InstanceEvaluationResult, ModuleEvaluationResult } from \"../abstractions\"\nimport type { ResolvedInstanceInput } from \"../../shared\"\nimport { getCompositeInstances, resetEvaluation, type InstanceModel } from \"@highstate/contract\"\nimport { BetterLock } from \"better-lock\"\nimport { errorToString } from \"../../common\"\n\nconst lock = new BetterLock()\n\nexport function evaluateModules(\n jiti: Jiti,\n logger: Logger,\n modulePaths: string[],\n): Promise<ModuleEvaluationResult> {\n return lock.acquire(async () => {\n resetEvaluation()\n let lastModulePath = \"\"\n\n try {\n for (const modulePath of modulePaths) {\n logger.info(\"loading module: %s\", modulePath)\n\n lastModulePath = modulePath\n await jiti.import(modulePath)\n\n logger.debug(\"module loaded: %s\", modulePath)\n }\n\n return {\n success: true,\n compositeInstances: getCompositeInstances(),\n }\n } catch (error) {\n return {\n success: false,\n modulePath: lastModulePath,\n error: errorToString(error),\n }\n }\n })\n}\n\nexport function evaluateInstances(\n logger: Logger,\n library: Library,\n allInstances: InstanceModel[],\n resolvedInputs: Record<string, Record<string, ResolvedInstanceInput[]>>,\n instanceIds: string[],\n): InstanceEvaluationResult[] {\n const results: InstanceEvaluationResult[] = []\n const allInstancesMap = new Map(allInstances.map(instance => [instance.id, instance]))\n\n for (const instanceId of instanceIds ?? []) {\n const externalInstanceIds = new Set(allInstances.map(instance => instance.id))\n externalInstanceIds.delete(instanceId)\n\n try {\n logger.debug({ instanceId }, \"evaluating top-level instance\")\n resetEvaluation(externalInstanceIds)\n\n evaluateInstance(instanceId)\n\n results.push({\n success: true,\n instanceId,\n compositeInstances: getCompositeInstances(),\n })\n } catch (error) {\n results.push({\n success: false,\n instanceId,\n error: errorToString(error),\n })\n }\n }\n\n return results\n\n function evaluateInstance(\n instanceId: string,\n instanceOutputs: Map<string, Record<string, unknown>> = new Map(),\n ): Record<string, unknown> {\n let outputs = instanceOutputs.get(instanceId)\n\n if (!outputs) {\n outputs = _evaluateInstance(instanceId, instanceOutputs)\n instanceOutputs.set(instanceId, outputs)\n }\n\n return outputs\n }\n\n function _evaluateInstance(\n instanceId: string,\n instanceOutputs: Map<string, Record<string, unknown>>,\n ): Record<string, unknown> {\n const inputs: Record<string, unknown> = {}\n const instance = allInstancesMap.get(instanceId)\n\n logger.info(\"evaluating instance\", { instanceId })\n\n if (!instance) {\n throw new Error(`Instance not found: ${instanceId}`)\n }\n\n for (const [inputName, input] of Object.entries(resolvedInputs[instanceId] ?? {})) {\n inputs[inputName] = input.map(input => {\n const evaluated = evaluateInstance(input.input.instanceId, instanceOutputs)\n\n return evaluated[input.input.output]\n })\n }\n\n const component = library.components[instance.type]\n if (!component) {\n throw new Error(`Component not found: ${instance.type}, required by instance: ${instanceId}`)\n }\n\n return component({\n name: instance.name,\n args: instance.args as Record<string, never>,\n inputs: inputs as Record<string, never>,\n })\n }\n}\n"],"mappings":"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","names":["jiti","logger","jiti","logger","library","input"]}
@@ -31,6 +31,7 @@ import {
31
31
  instanceStateSchema,
32
32
  instanceStateUpdateSchema,
33
33
  instanceStatusFieldSchema,
34
+ instanceStatusFieldValueSchema,
34
35
  instanceStatusSchema,
35
36
  instanceTerminalFileSchema,
36
37
  instanceTerminalMetaSchema,
@@ -47,7 +48,7 @@ import {
47
48
  projectOperationSchema,
48
49
  resolverFactories,
49
50
  terminalSessionSchema
50
- } from "../chunk-I7NLZ54E.js";
51
+ } from "../chunk-NMGIUI6X.js";
51
52
  export {
52
53
  CircularDependencyError,
53
54
  applyLibraryUpdate,
@@ -81,6 +82,7 @@ export {
81
82
  instanceStateSchema,
82
83
  instanceStateUpdateSchema,
83
84
  instanceStatusFieldSchema,
85
+ instanceStatusFieldValueSchema,
84
86
  instanceStatusSchema,
85
87
  instanceTerminalFileSchema,
86
88
  instanceTerminalMetaSchema,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@highstate/backend",
3
- "version": "0.9.3",
3
+ "version": "0.9.5",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist",
@@ -26,7 +26,7 @@
26
26
  "build": "highstate build"
27
27
  },
28
28
  "dependencies": {
29
- "@highstate/contract": "^0.9.3",
29
+ "@highstate/contract": "^0.9.5",
30
30
  "@types/node": "^22.10.1",
31
31
  "ajv": "^8.17.1",
32
32
  "better-lock": "^3.2.0",
@@ -65,5 +65,5 @@
65
65
  "rollup": "^4.28.1",
66
66
  "typescript": "^5.7.2"
67
67
  },
68
- "gitHead": "cdd2bb1d9001ba4a39f64087eb29af6f50d82bec"
68
+ "gitHead": "93fa1e8b1189a5232055c852fd79a684d8b80444"
69
69
  }
@@ -110,7 +110,11 @@ export class LocalLibraryBackend implements LibraryBackend {
110
110
  return await this.lock.acquire(async () => {
111
111
  const [library] = await this.getLibrary()
112
112
 
113
- const units = unitTypes.map(type => library.components[type]).filter(isUnitModel)
113
+ const units = unitTypes
114
+ .map(type => library.components[type])
115
+ .filter(Boolean)
116
+ .filter(isUnitModel)
117
+
114
118
  const packageNames = Object.keys(groupBy(units, unit => unit.source.package))
115
119
 
116
120
  await this.ensureLibraryPackagesLoaded(packageNames, true)
@@ -213,11 +217,13 @@ export class LocalLibraryBackend implements LibraryBackend {
213
217
  private async reloadLibrary(): Promise<[LibraryModel, Worker]> {
214
218
  this.logger.info("reloading library")
215
219
 
220
+ this.eventEmitter.emit("library", [{ type: "reload-started" }])
221
+
216
222
  await this.ensureLibraryPackagesLoaded(this.libraryPackages, true)
217
223
 
218
224
  this.worker = this.createLibraryWorker({
219
225
  modulePaths: this.libraryPackages,
220
- logLevel: "silent",
226
+ logLevel: "warn",
221
227
  })
222
228
 
223
229
  for await (const [event] of on(this.worker, "message")) {
@@ -245,6 +251,8 @@ export class LocalLibraryBackend implements LibraryBackend {
245
251
 
246
252
  this.logger.info("library reloaded")
247
253
 
254
+ this.eventEmitter.emit("library", [{ type: "reload-completed" }])
255
+
248
256
  return [this.library, this.worker]
249
257
  }
250
258
 
@@ -51,12 +51,14 @@ export function evaluateInstances(
51
51
  ): InstanceEvaluationResult[] {
52
52
  const results: InstanceEvaluationResult[] = []
53
53
  const allInstancesMap = new Map(allInstances.map(instance => [instance.id, instance]))
54
- const instanceOutputs = new Map<string, Record<string, unknown>>()
55
54
 
56
55
  for (const instanceId of instanceIds ?? []) {
56
+ const externalInstanceIds = new Set(allInstances.map(instance => instance.id))
57
+ externalInstanceIds.delete(instanceId)
58
+
57
59
  try {
58
60
  logger.debug({ instanceId }, "evaluating top-level instance")
59
- resetEvaluation()
61
+ resetEvaluation(externalInstanceIds)
60
62
 
61
63
  evaluateInstance(instanceId)
62
64
 
@@ -76,18 +78,24 @@ export function evaluateInstances(
76
78
 
77
79
  return results
78
80
 
79
- function evaluateInstance(instanceId: string): Record<string, unknown> {
81
+ function evaluateInstance(
82
+ instanceId: string,
83
+ instanceOutputs: Map<string, Record<string, unknown>> = new Map(),
84
+ ): Record<string, unknown> {
80
85
  let outputs = instanceOutputs.get(instanceId)
81
86
 
82
87
  if (!outputs) {
83
- outputs = _evaluateInstance(instanceId)
88
+ outputs = _evaluateInstance(instanceId, instanceOutputs)
84
89
  instanceOutputs.set(instanceId, outputs)
85
90
  }
86
91
 
87
92
  return outputs
88
93
  }
89
94
 
90
- function _evaluateInstance(instanceId: string): Record<string, unknown> {
95
+ function _evaluateInstance(
96
+ instanceId: string,
97
+ instanceOutputs: Map<string, Record<string, unknown>>,
98
+ ): Record<string, unknown> {
91
99
  const inputs: Record<string, unknown> = {}
92
100
  const instance = allInstancesMap.get(instanceId)
93
101
 
@@ -99,7 +107,7 @@ export function evaluateInstances(
99
107
 
100
108
  for (const [inputName, input] of Object.entries(resolvedInputs[instanceId] ?? {})) {
101
109
  inputs[inputName] = input.map(input => {
102
- const evaluated = evaluateInstance(input.input.instanceId)
110
+ const evaluated = evaluateInstance(input.input.instanceId, instanceOutputs)
103
111
 
104
112
  return evaluated[input.input.output]
105
113
  })
@@ -42,12 +42,12 @@ export async function loadLibrary(
42
42
  const modules: Record<string, unknown> = {}
43
43
  for (const modulePath of modulePaths) {
44
44
  try {
45
- logger.debug("loading module", { modulePath })
45
+ logger.debug({ modulePath }, "loading module")
46
46
  modules[modulePath] = await jiti.import(modulePath)
47
47
 
48
- logger.debug("module loaded", { modulePath })
49
- } catch (error) {
50
- logger.error("module load failed", { modulePath, error })
48
+ logger.debug({ modulePath }, "module loaded")
49
+ } catch (err) {
50
+ logger.error({ modulePath, err }, "module load failed")
51
51
  }
52
52
  }
53
53
 
@@ -56,12 +56,15 @@ export async function loadLibrary(
56
56
 
57
57
  await _loadLibrary(modules, components, entities)
58
58
 
59
- logger.info("library loaded", {
60
- componentCount: Object.keys(components).length,
61
- entityCount: Object.keys(entities).length,
62
- })
59
+ logger.info(
60
+ {
61
+ componentCount: Object.keys(components).length,
62
+ entityCount: Object.keys(entities).length,
63
+ },
64
+ "library loaded",
65
+ )
63
66
 
64
- logger.trace("library content", { components, entities })
67
+ logger.trace({ components, entities }, "library content")
65
68
 
66
69
  return { components, entities }
67
70
  }
@@ -72,11 +72,13 @@ export class OperationManager {
72
72
  id: uuidv7(),
73
73
  projectId: request.projectId,
74
74
  type: request.type,
75
- instanceIds: request.instanceIds,
76
- affectedInstanceIds: request.instanceIds,
75
+ requestedInstanceIds: request.instanceIds,
76
+ instanceIdsToUpdate: [],
77
+ instanceIdsToDestroy: [],
77
78
  status: "pending",
78
79
  options: {
79
80
  forceUpdateDependencies: request.options?.forceUpdateDependencies ?? false,
81
+ forceUpdateChildren: request.options?.forceUpdateChildren ?? false,
80
82
  destroyDependentInstances: request.options?.destroyDependentInstances ?? true,
81
83
  invokeDestroyTriggers: request.options?.invokeDestroyTriggers ?? false,
82
84
  deleteUnreachableResources: request.options?.deleteUnreachableResources ?? false,