@highstate/contract 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.
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "sourceHashes": {
3
- "./dist/index.js": "f7b0cc65c29d5fdc3bbfca9b60237a9a7b3afed6364ce7e0a4179c6fc739de15"
3
+ "./dist/index.js": "84c98ff0266f2f338d4df03889900ac30ee8e2d8bca1d08f2fbf13ac79a669d4"
4
4
  }
5
5
  }
package/dist/index.js CHANGED
@@ -52,19 +52,32 @@ import { isNonNullish, mapValues, pickBy } from "remeda";
52
52
  import { Ajv } from "ajv";
53
53
 
54
54
  // src/utils.ts
55
- function text(array, ...values) {
56
- const str = array.reduce(
57
- // eslint-disable-next-line @typescript-eslint/no-base-to-string
58
- (result, part, i) => result + part + (values[i] ? String(values[i]) : ""),
59
- ""
60
- );
61
- return trimIndentation(str);
55
+ function text(strings, ...values) {
56
+ const stringValues = values.map(String);
57
+ let result = "";
58
+ for (let i = 0; i < strings.length; i++) {
59
+ result += strings[i];
60
+ if (i < stringValues.length) {
61
+ const value = stringValues[i];
62
+ const lines = value.split("\n");
63
+ const lastLineIndentMatch = strings[i].match(/(?:^|\n)([ \t]*)$/);
64
+ const indent = lastLineIndentMatch ? lastLineIndentMatch[1] : "";
65
+ result += lines.map((line, j) => j === 0 ? line : indent + line).join("\n");
66
+ }
67
+ }
68
+ return trimIndentation(result);
62
69
  }
63
70
  function trimIndentation(text2) {
64
71
  const lines = text2.split("\n");
65
72
  const indent = lines.filter((line) => line.trim() !== "").map((line) => line.match(/^\s*/)?.[0].length ?? 0).reduce((min, indent2) => Math.min(min, indent2), Infinity);
66
73
  return lines.map((line) => line.slice(indent)).join("\n").trim();
67
74
  }
75
+ function bytesToHumanReadable(bytes) {
76
+ const sizes = ["Bytes", "KB", "MB", "GB", "TB"];
77
+ if (bytes === 0) return "0 Bytes";
78
+ const i = Math.floor(Math.log(bytes) / Math.log(1024));
79
+ return parseFloat((bytes / Math.pow(1024, i)).toFixed(2)) + " " + sizes[i];
80
+ }
68
81
 
69
82
  // src/component.ts
70
83
  var ajv = new Ajv({ strict: false });
@@ -125,7 +138,7 @@ function mapArgument(value) {
125
138
  if ("schema" in value) {
126
139
  return {
127
140
  schema: value.schema,
128
- required: value.required ?? (!value.schema[OptionalKind] && !value.schema.default),
141
+ required: value.required ?? (!value.schema[OptionalKind] && value.schema.default === void 0),
129
142
  meta: {
130
143
  displayName: value.displayName,
131
144
  description: value.description,
@@ -135,7 +148,7 @@ function mapArgument(value) {
135
148
  }
136
149
  return {
137
150
  schema: value,
138
- required: !value[OptionalKind] && !value.default,
151
+ required: !value[OptionalKind] && value.default === void 0,
139
152
  meta: {}
140
153
  };
141
154
  }
@@ -206,25 +219,39 @@ function defineUnit(options) {
206
219
  }
207
220
 
208
221
  // src/evaluation.ts
222
+ var _externalInstanceIds = /* @__PURE__ */ new Set();
209
223
  var compositeInstances = /* @__PURE__ */ new Map();
210
224
  var currentCompositeInstance = null;
211
- function resetEvaluation() {
225
+ function resetEvaluation(externalInstanceIds) {
212
226
  compositeInstances.clear();
213
227
  currentCompositeInstance = null;
228
+ _externalInstanceIds = externalInstanceIds ?? /* @__PURE__ */ new Set();
214
229
  }
215
230
  function getCompositeInstances() {
216
231
  return Array.from(compositeInstances.values());
217
232
  }
218
- function registerInstance(component, instance, fn) {
219
- if (currentCompositeInstance) {
220
- instance.parentId = currentCompositeInstance.instance.id;
221
- currentCompositeInstance.children.push(instance);
233
+ function isExternalInstance(instanceId) {
234
+ let currentId = instanceId;
235
+ while (currentId) {
236
+ if (_externalInstanceIds.has(currentId)) {
237
+ return true;
238
+ }
239
+ currentId = compositeInstances.get(currentId ?? "")?.instance.parentId;
222
240
  }
241
+ return false;
242
+ }
243
+ function registerInstance(component, instance, fn) {
223
244
  let previousParentInstance = null;
224
- if (!isUnitModel(component)) {
225
- previousParentInstance = currentCompositeInstance;
226
- currentCompositeInstance = { instance, children: [] };
227
- compositeInstances.set(currentCompositeInstance.instance.id, currentCompositeInstance);
245
+ if (!isExternalInstance(instance.id)) {
246
+ if (currentCompositeInstance) {
247
+ instance.parentId = currentCompositeInstance.instance.id;
248
+ currentCompositeInstance.children.push(instance);
249
+ }
250
+ if (!isUnitModel(component)) {
251
+ previousParentInstance = currentCompositeInstance;
252
+ currentCompositeInstance = { instance, children: [] };
253
+ compositeInstances.set(currentCompositeInstance.instance.id, currentCompositeInstance);
254
+ }
228
255
  }
229
256
  try {
230
257
  const outputs = fn();
@@ -262,7 +289,7 @@ function isEntity(value) {
262
289
  import "@sinclair/typebox";
263
290
 
264
291
  // src/index.ts
265
- import {} from "@sinclair/typebox";
292
+ export * from "@sinclair/typebox";
266
293
  import {
267
294
  Type as BaseType
268
295
  } from "@sinclair/typebox";
@@ -279,6 +306,7 @@ var Type = {
279
306
  };
280
307
  export {
281
308
  Type,
309
+ bytesToHumanReadable,
282
310
  defineComponent,
283
311
  defineEntity,
284
312
  defineUnit,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/instance.ts","../src/evaluation.ts","../src/unit.ts","../src/component.ts","../src/utils.ts","../src/entity.ts","../src/types.ts","../src/index.ts"],"sourcesContent":["declare const type: unique symbol\n\nexport type InstanceInput<TType extends string = string> = {\n [type]?: TType\n [boundaryInput]?: InstanceInput\n instanceId: string\n output: string\n}\n\nexport const boundaryInput = Symbol(\"boundaryInput\")\n\nexport type HubInput = {\n hubId: string\n}\n\nexport type Position = {\n x: number\n y: number\n}\n\nexport type InstanceModel = {\n /**\n * The id of the instance unique within the project.\n *\n * The format is `${instanceType}:${instanceName}`.\n */\n id: string\n\n /**\n * The type of the instance.\n */\n type: string\n\n /**\n * The name of the instance.\n *\n * Must be unique within instances of the same type in the project.\n */\n name: string\n\n /**\n * The static arguments passed to the instance.\n */\n args?: Record<string, unknown>\n\n /**\n * The direct instances passed as inputs to the instance.\n */\n inputs?: Record<string, InstanceInput[]>\n\n /**\n * The resolved unit inputs for the instance.\n *\n * Only for computed composite instances.\n */\n resolvedInputs?: Record<string, InstanceInput[]>\n\n /**\n * The inputs passed to the instance from the hubs.\n *\n * Only for designer-first instances.\n */\n hubInputs?: Record<string, HubInput[]>\n\n /**\n * The inputs injected to the instance from the hubs.\n *\n * While `hubInputs` allows to pass hubs to distinct inputs,\n * `injectionInputs` allows to pass hubs to the instance as a whole filling all inputs with matching types.\n *\n * Only for designer-first instances.\n */\n injectionInputs?: HubInput[]\n\n /**\n * The position of the instance on the canvas.\n *\n * Only for designer-first instances.\n */\n position?: Position\n\n /**\n * The id of the top level parent instance.\n *\n * Only for child instances of the composite instances.\n */\n parentId?: string\n\n /**\n * The direct instance inputs and same-level children outputs returned by the instance as outputs.\n *\n * Only for computed composite instances.\n */\n outputs?: Record<string, InstanceInput[]>\n\n /**\n * The resolved unit outputs for the instance.\n *\n * Only for computed composite instances.\n */\n resolvedOutputs?: Record<string, InstanceInput[]>\n}\n\n/**\n * Formats the instance id from the instance type and instance name.\n *\n * @param instanceType The type of the instance.\n * @param instanceName The name of the instance.\n *\n * @returns The formatted instance id.\n */\nexport function getInstanceId(instanceType: string, instanceName: string): string {\n return `${instanceType}:${instanceName}`\n}\n\n/**\n * Parses the instance id into the instance type and instance name.\n *\n * @param instanceId The instance id to parse.\n *\n * @returns The instance type and instance name.\n */\nexport function parseInstanceId(instanceId: string): [instanceType: string, instanceName: string] {\n const parts = instanceId.split(\":\")\n\n if (parts.length !== 2) {\n throw new Error(`Invalid instance key: ${instanceId}`)\n }\n\n return parts as [string, string]\n}\n\nexport function findInput<T extends string>(\n inputs: InstanceInput<T>[],\n name: string,\n): InstanceInput<T> | null {\n const matchedInputs = inputs.filter(\n input => parseInstanceId(input.instanceId)[1] === name || input.instanceId === name,\n )\n\n if (matchedInputs.length === 0) {\n return null\n }\n\n if (matchedInputs.length > 1) {\n throw new Error(\n `Multiple inputs found for \"${name}\": ${matchedInputs.map(input => input.instanceId).join(\", \")}. Specify the full instance id to disambiguate.`,\n )\n }\n\n return matchedInputs[0]\n}\n\nexport function findRequiredInput<T extends string>(\n inputs: InstanceInput<T>[],\n name: string,\n): InstanceInput<T> {\n const input = findInput(inputs, name)\n\n if (input === null) {\n throw new Error(`Required input \"${name}\" not found.`)\n }\n\n return input\n}\n\nexport function findInputs<T extends string>(\n inputs: InstanceInput<T>[],\n names: string[],\n): InstanceInput<T>[] {\n return names.map(name => findInput(inputs, name)).filter(Boolean) as InstanceInput<T>[]\n}\n\nexport function findRequiredInputs<T extends string>(\n inputs: InstanceInput<T>[],\n names: string[],\n): InstanceInput<T>[] {\n return names.map(name => findRequiredInput(inputs, name))\n}\n","import type { ComponentModel } from \"./component\"\nimport { mapValues } from \"remeda\"\nimport { boundaryInput, type InstanceInput, type InstanceModel } from \"./instance\"\nimport { isUnitModel } from \"./unit\"\n\nexport type CompositeInstance = {\n instance: InstanceModel\n children: InstanceModel[]\n}\n\nconst compositeInstances: Map<string, CompositeInstance> = new Map()\nlet currentCompositeInstance: CompositeInstance | null = null\n\nexport function resetEvaluation(): void {\n compositeInstances.clear()\n currentCompositeInstance = null\n}\n\nexport function getCompositeInstances(): CompositeInstance[] {\n return Array.from(compositeInstances.values())\n}\n\nexport function registerInstance<T>(\n component: ComponentModel,\n instance: InstanceModel,\n fn: () => T,\n): T {\n if (currentCompositeInstance) {\n instance.parentId = currentCompositeInstance.instance.id\n currentCompositeInstance.children.push(instance)\n }\n\n let previousParentInstance: CompositeInstance | null = null\n if (!isUnitModel(component)) {\n previousParentInstance = currentCompositeInstance\n currentCompositeInstance = { instance, children: [] }\n compositeInstances.set(currentCompositeInstance.instance.id, currentCompositeInstance)\n }\n\n try {\n const outputs = fn() as Record<string, InstanceInput[]>\n\n instance.resolvedOutputs = outputs\n instance.outputs = mapValues(outputs ?? {}, outputs =>\n outputs.map(output => output[boundaryInput] ?? output),\n )\n\n // mark all outputs with the boundary input of the instance\n return mapValues(outputs, (outputs, outputKey) =>\n outputs.map(output => ({\n ...output,\n [boundaryInput]: { instanceId: instance.id, output: outputKey },\n })),\n ) as T\n } finally {\n if (previousParentInstance) {\n currentCompositeInstance = previousParentInstance\n }\n }\n}\n","/* eslint-disable @typescript-eslint/no-unsafe-return */\n/* eslint-disable @typescript-eslint/no-unsafe-member-access */\n/* eslint-disable @typescript-eslint/no-explicit-any */\n/* eslint-disable @typescript-eslint/no-unsafe-assignment */\n\nimport type { ArgumentValue } from \"./types\"\nimport type { InstanceInput } from \"./instance\"\nimport { mapValues } from \"remeda\"\nimport {\n type ComponentArgumentSpec,\n type Component,\n type ComponentArgument,\n type ComponentArgumentOptions,\n type ComponentInputOptions,\n type ComponentInputOptionsMapToSpecMap,\n type ComponentInputSpec,\n type ComponentModel,\n type ComponentOptions,\n defineComponent,\n mapArgument,\n type ComponentArgumentOptionsMapToSpecMap,\n} from \"./component\"\n\ntype UnitOptions<\n TArgs extends Record<string, ComponentArgumentOptions>,\n TInputs extends Record<string, ComponentInputOptions>,\n TOutputs extends Record<string, ComponentInputOptions>,\n TSecrets extends Record<string, ComponentArgumentOptions>,\n> = Omit<ComponentOptions<TArgs, TInputs, TOutputs>, \"create\"> & {\n source: UnitSource\n\n secrets?: TSecrets\n}\n\nexport type UnitSource = {\n package: string\n path?: string\n version?: string\n}\n\nexport type UnitModel = ComponentModel & {\n /**\n * The source of the unit.\n */\n source: UnitSource\n\n /**\n * The record of the secret argument schemas.\n */\n secrets: Record<string, ComponentArgument>\n}\n\nexport type Unit<\n TArgs extends Record<string, ComponentArgumentSpec> = Record<string, never>,\n TInputs extends Record<string, ComponentInputSpec> = Record<string, never>,\n TOutputs extends Record<string, ComponentInputSpec> = Record<string, never>,\n TSecrets extends Record<string, ArgumentValue> = Record<string, never>,\n> = Component<TArgs, TInputs, TOutputs> & {\n __secrets: TSecrets\n\n model: UnitModel\n}\n\nexport function isUnitModel(model: ComponentModel): model is UnitModel {\n return \"source\" in model\n}\n\nexport function defineUnit<\n TArgs extends Record<string, ComponentArgumentOptions> = Record<string, never>,\n TInputs extends Record<string, ComponentInputOptions> = Record<string, never>,\n TOutputs extends Record<string, ComponentInputOptions> = Record<string, never>,\n TSecrets extends Record<string, ComponentArgumentOptions> = Record<string, never>,\n>(\n options: UnitOptions<TArgs, TInputs, TOutputs, TSecrets>,\n): Unit<\n ComponentArgumentOptionsMapToSpecMap<TArgs>,\n ComponentInputOptionsMapToSpecMap<TInputs>,\n ComponentInputOptionsMapToSpecMap<TOutputs>,\n ComponentArgumentOptionsMapToSpecMap<TSecrets>\n> {\n const component = defineComponent<TArgs, TInputs, TOutputs>({\n ...options,\n\n create({ id }) {\n const outputs: Record<string, InstanceInput[]> = {}\n for (const key in options.outputs ?? {}) {\n outputs[key] = [\n {\n instanceId: id,\n output: key,\n },\n ]\n }\n\n return outputs as any\n },\n }) as any\n\n component.model.source = options.source ?? {}\n component.model.secrets = mapValues(options.secrets ?? {}, mapArgument)\n\n return component\n}\n","/* eslint-disable @typescript-eslint/no-unsafe-member-access */\n/* eslint-disable @typescript-eslint/no-explicit-any */\n/* eslint-disable @typescript-eslint/no-unsafe-assignment */\n/* eslint-disable @typescript-eslint/no-unsafe-return */\n\nimport type { Entity } from \"./entity\"\nimport type { ArgumentValue, ArgumentValueSchema, Meta } from \"./types\"\nimport {\n type Static,\n type TObject,\n type TOptional,\n type TSchema,\n OptionalKind,\n} from \"@sinclair/typebox\"\nimport { isNonNullish, mapValues, pickBy } from \"remeda\"\nimport { Ajv } from \"ajv\"\nimport { boundaryInput, type InstanceInput } from \"./instance\"\nimport { type OptionalUndefinedFields, type OptionalEmptyRecords } from \"./utils\"\nimport { registerInstance } from \"./evaluation\"\n\nconst ajv = new Ajv({ strict: false })\n\n// Argument\nexport type ComponentArgument = {\n schema: ArgumentValueSchema\n required: boolean\n meta: Meta\n}\n\ntype ComponentArgumentFullOptions = Meta & {\n schema: ArgumentValueSchema\n required?: boolean\n}\n\nexport type ComponentArgumentOptions = ArgumentValueSchema | ComponentArgumentFullOptions\nexport type ComponentArgumentSpec = [schema: ArgumentValueSchema, required: boolean]\n\nexport type ComponentArgumentOptionsToSpec<T extends ComponentArgumentOptions> =\n T extends ArgumentValueSchema\n ? T extends { default: unknown }\n ? [T, false]\n : [T, true]\n : T extends ComponentArgumentFullOptions\n ? T[\"required\"] extends false\n ? [T[\"schema\"], false]\n : [T[\"schema\"], true]\n : never\n\nexport type ComponentArgumentOptionsMapToSpecMap<\n T extends Record<string, ComponentArgumentOptions>,\n> =\n T extends Record<string, never>\n ? Record<string, never>\n : { [K in keyof T]: ComponentArgumentOptionsToSpec<T[K]> }\n\nexport type ComponentArgumentSpecMapToInputStatic<T extends Record<string, ComponentArgumentSpec>> =\n T extends Record<string, never>\n ? Record<string, never>\n : Static<TObject<{ [K in keyof T]: T[K][1] extends true ? T[K][0] : TOptional<T[K][0]> }>>\n\nexport type ComponentArgumentSpecToStatic<T extends Record<string, ComponentArgumentSpec>> =\n T extends Record<string, never>\n ? Record<string, never>\n : Static<TObject<{ [K in keyof T]: T[K][0] }>>\n\nexport type ComponentArgumentOptionsToSchema<T extends ComponentArgumentOptions> = T extends TSchema\n ? T\n : T[\"required\"] extends false\n ? TOptional<T[\"schema\"]>\n : T[\"schema\"]\n\ntype ComponentArgumentMapToValue<T extends Record<string, ComponentArgumentOptions>> = {\n [K in keyof T]: Static<ComponentArgumentOptionsToSchema<T[K]>>\n}\n\n// Input\nexport type ComponentInput = {\n type: string\n required: boolean\n multiple: boolean\n meta: Meta\n}\n\ntype ComponentInputFullOptions = Meta & {\n entity: Entity\n required?: boolean\n multiple?: boolean\n}\n\nexport type ComponentInputOptions = Entity | ComponentInputFullOptions\n\ntype ComponentInputOptionsToOutputRef<T extends ComponentInputOptions> = T extends Entity\n ? InstanceInput<T[\"type\"]>\n : T extends ComponentInputFullOptions\n ? T[\"required\"] extends false\n ? T[\"multiple\"] extends true\n ? InstanceInput<T[\"entity\"][\"type\"]>[] | undefined\n : InstanceInput<T[\"entity\"][\"type\"]> | undefined\n : T[\"multiple\"] extends true\n ? InstanceInput<T[\"entity\"][\"type\"]>[]\n : InstanceInput<T[\"entity\"][\"type\"]>\n : never\n\nexport type ComponentInputSpec = [entity: Entity, required: boolean, multiple: boolean]\n\nexport type ComponentInputOptionsToSpec<T extends ComponentInputOptions> = T extends Entity\n ? [T, true, false] // [Entity, required, multiple]\n : T extends ComponentInputFullOptions\n ? T[\"required\"] extends false\n ? T[\"multiple\"] extends true\n ? [T[\"entity\"], false, true]\n : [T[\"entity\"], false, false]\n : T[\"multiple\"] extends true\n ? [T[\"entity\"], true, true]\n : [T[\"entity\"], true, false]\n : never\n\nexport type ComponentInputOptionsMapToSpecMap<T extends Record<string, ComponentInputOptions>> =\n T extends Record<string, never>\n ? Record<string, never>\n : { [K in keyof T]: ComponentInputOptionsToSpec<T[K]> }\n\ntype ComponentInputMapToValue<T extends Record<string, ComponentInputOptions>> =\n OptionalUndefinedFields<{\n [K in keyof T]: ComponentInputOptionsToOutputRef<T[K]>\n }>\n\ntype ComponentInputMapToReturnType<T extends Record<string, ComponentInputOptions>> =\n T extends Record<string, never> ? void : ComponentInputMapToValue<T>\n\n// Params & Options\nexport type ComponentParams<\n TArgs extends Record<string, ComponentArgumentOptions>,\n TInputs extends Record<string, ComponentInputOptions>,\n> = {\n id: string\n name: string\n args: ComponentArgumentMapToValue<TArgs>\n inputs: ComponentInputMapToValue<TInputs>\n}\n\nexport type InputComponentParams<\n TArgs extends Record<string, ArgumentValue>,\n TInputs extends Record<string, unknown>,\n> = {\n name: string\n} & OptionalEmptyRecords<{\n args: TArgs\n inputs: TInputs\n}>\n\nexport type ComponentOptions<\n TArgs extends Record<string, ComponentArgumentOptions>,\n TInputs extends Record<string, ComponentInputOptions>,\n TOutputs extends Record<string, ComponentInputOptions>,\n> = {\n type: string\n meta?: ComponentMeta\n\n args?: TArgs\n inputs?: TInputs\n outputs?: TOutputs\n\n create: (params: ComponentParams<TArgs, TInputs>) => ComponentInputMapToReturnType<TOutputs>\n}\n\n// Models\nexport type ComponentMeta = Meta & {\n primaryIcon?: string\n primaryIconColor?: string\n secondaryIcon?: string\n secondaryIconColor?: string\n category?: string\n defaultNamePrefix?: string\n}\n\nexport type ComponentModel = {\n /**\n * The type of the component.\n */\n type: string\n\n /**\n * The record of the argument schemas.\n */\n args: Record<string, ComponentArgument>\n\n /**\n * The record of the input schemas.\n */\n inputs: Record<string, ComponentInput>\n\n /**\n * The record of the output schemas.\n */\n outputs: Record<string, ComponentInput>\n\n /**\n * The extra metadata of the component.\n */\n meta: ComponentMeta\n\n /**\n * The hash of the component definition.\n */\n definitionHash: string\n}\n\ntype InputSpecToInputRef<T extends ComponentInputSpec> = T[1] extends true\n ? T[2] extends true\n ? InstanceInput<T[0][\"type\"]>[]\n : InstanceInput<T[0][\"type\"]>\n : T[2] extends true\n ? InstanceInput<T[0][\"type\"]>[] | undefined\n : InstanceInput<T[0][\"type\"]> | undefined\n\ntype InputSpecToOutputRef<T extends ComponentInputSpec> = T[2] extends true\n ? InstanceInput<T[0][\"type\"]>[]\n : InstanceInput<T[0][\"type\"]>\n\nexport type InputRefMap<TInputs extends Record<string, ComponentInputSpec>> =\n TInputs extends Record<string, [string, never, never]>\n ? Record<string, never>\n : { [K in keyof TInputs]: InputSpecToInputRef<TInputs[K]> }\n\nexport type OutputRefMap<TInputs extends Record<string, ComponentInputSpec>> =\n TInputs extends Record<string, [string, never, never]>\n ? Record<string, never>\n : { [K in keyof TInputs]: InputSpecToOutputRef<TInputs[K]> }\n\nexport const originalCreate = Symbol(\"originalCreate\")\n\nexport type Component<\n TArgs extends Record<string, ComponentArgumentSpec> = Record<string, never>,\n TInputs extends Record<string, ComponentInputSpec> = Record<string, never>,\n TOutputs extends Record<string, ComponentInputSpec> = Record<string, never>,\n> = {\n /**\n * The non-generic model of the component.\n */\n model: ComponentModel\n\n /**\n * The entities used in the inputs or outputs of the component.\n */\n entities: Map<string, Entity>\n\n /**\n * Creates the component at the evaluation time.\n */\n (\n context: InputComponentParams<\n ComponentArgumentSpecMapToInputStatic<TArgs>,\n InputRefMap<TInputs>\n >,\n ): OutputRefMap<TOutputs>\n\n /**\n * The original create function.\n *\n * Used to calculate the definition hash.\n */\n [originalCreate]: (params: InputComponentParams<any, any>) => any\n}\n\nexport function defineComponent<\n TArgs extends Record<string, ComponentArgumentOptions> = Record<string, never>,\n TInputs extends Record<string, ComponentInputOptions> = Record<string, never>,\n TOutputs extends Record<string, ComponentInputOptions> = Record<string, never>,\n>(\n options: ComponentOptions<TArgs, TInputs, TOutputs>,\n): Component<\n ComponentArgumentOptionsMapToSpecMap<TArgs>,\n ComponentInputOptionsMapToSpecMap<TInputs>,\n ComponentInputOptionsMapToSpecMap<TOutputs>\n> {\n function create(params: InputComponentParams<any, any>): any {\n const { name, args, inputs } = params\n const id = `${options.type}:${name}`\n\n const flatInputs = mapValues(pickBy(inputs ?? {}, isNonNullish), inputs => [inputs].flat(2))\n\n return registerInstance(\n create.model as ComponentModel,\n {\n id,\n type: options.type,\n name,\n args: args ?? {},\n inputs: mapValues(flatInputs, inputs => inputs.map(input => input[boundaryInput] ?? input)),\n resolvedInputs: flatInputs,\n },\n () => {\n const markedInputs = mapValues(flatInputs, (inputs, key) => {\n const result = inputs.map(input => ({\n ...input,\n [boundaryInput]: { instanceId: id, output: key },\n }))\n\n return (create.model as ComponentModel).inputs?.[key]?.multiple === false\n ? result[0]\n : result\n })\n\n const outputs: Record<string, InstanceInput[]> =\n options.create({\n id,\n name,\n args: validateArgsAndFillDefaults(\n id,\n create.model as ComponentModel,\n args ? { ...args } : {},\n ) as any,\n inputs: markedInputs as any,\n }) ?? {}\n\n return mapValues(pickBy(outputs, isNonNullish), outputs => [outputs].flat(2))\n },\n )\n }\n\n create.entities = new Map<string, Entity>()\n const mapInput = createInputMapper(create.entities)\n\n create.model = {\n type: options.type,\n args: mapValues(options.args ?? {}, mapArgument),\n inputs: mapValues(options.inputs ?? {}, mapInput),\n outputs: mapValues(options.outputs ?? {}, mapInput),\n meta: options.meta ?? {},\n }\n\n create[originalCreate] = options.create\n\n return create as any\n}\n\nexport function isComponent(value: unknown): value is Component {\n return typeof value === \"function\" && \"model\" in value\n}\n\nexport function mapArgument(value: ComponentArgumentOptions) {\n if (\"schema\" in value) {\n return {\n schema: value.schema,\n required: value.required ?? (!value.schema[OptionalKind] && !value.schema.default),\n meta: {\n displayName: value.displayName,\n description: value.description,\n color: value.color,\n },\n }\n }\n\n return {\n schema: value,\n required: !value[OptionalKind] && !value.default,\n meta: {},\n }\n}\n\nexport function createInputMapper(entities: Map<string, Entity>) {\n return (value: ComponentInputOptions) => {\n if (\"entity\" in value) {\n entities.set(value.entity.type, value.entity)\n\n return {\n type: value.entity.type,\n required: value.required ?? true,\n multiple: value.multiple ?? false,\n meta: {\n displayName: value.displayName,\n description: value.description,\n color: value.color,\n },\n }\n }\n\n entities.set(value.type, value)\n\n return {\n type: value.type,\n required: true,\n multiple: false,\n meta: {},\n }\n }\n}\n\nfunction validateArgsAndFillDefaults(\n instanceId: string,\n model: ComponentModel,\n args: Record<string, unknown>,\n) {\n for (const [key, argModel] of Object.entries(model.args)) {\n let value = args[key]\n if (!value) {\n if (argModel.required) {\n throw new Error(`Missing required argument \"${key}\" for instance \"${instanceId}\"`)\n }\n\n value = argModel.schema.default\n args[key] = value\n }\n\n if (value && !ajv.validate(argModel.schema, value)) {\n throw new Error(`Invalid argument \"${key}\" for instance \"${instanceId}\": ${ajv.errorsText()}`)\n }\n }\n\n return args as Record<string, ArgumentValue>\n}\n","export type EntityMap<T> = Record<string, T> & {\n default?: T\n}\n\nexport type PartialKeys<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>\nexport type RequiredKeys<T, K extends keyof T> = Omit<T, K> & Required<Pick<T, K>>\n\n// TODO: refactor this shit\n\ntype PickUndefinedKeys<T extends Record<string, unknown>> = T extends Record<string, never>\n ? never\n : Exclude<\n {\n [K in keyof T]: undefined extends T[K] ? K : never\n }[keyof T],\n undefined\n >\n\ntype AllOptionalKeys<T extends Record<string, unknown>> = T extends Record<string, never>\n ? never\n : Exclude<\n {\n [K in keyof T]: undefined extends T[K] ? K : never\n }[keyof T],\n undefined\n >\n\ntype HasRequired<T extends Record<string, unknown>> = T extends Record<string, never>\n ? false\n : [keyof T] extends [AllOptionalKeys<T>]\n ? false\n : true\n\ntype PickRecordsWithAnyRequired<T extends Record<string, Record<string, unknown>>> =\n T extends Record<string, never>\n ? never\n : Exclude<\n {\n [K in keyof T]: HasRequired<T[K]> extends true ? K : never\n }[keyof T],\n undefined\n >\n\nexport type OptionalEmptyRecords<T extends Record<string, Record<string, unknown>>> = {\n [K in Exclude<keyof T, PickRecordsWithAnyRequired<T>>]?: OptionalUndefinedFields<T[K]>\n} & {\n [K in PickRecordsWithAnyRequired<T>]: OptionalUndefinedFields<T[K]>\n}\n\nexport type OptionalUndefinedFields<T extends Record<string, unknown>> = {\n [K in PickUndefinedKeys<T>]?: T[K]\n} & {\n [K in Exclude<keyof T, PickUndefinedKeys<T>>]: T[K]\n}\n\n/**\n * Formats a multiline string and trims the indentation.\n *\n * @param str The string to trim.\n * @returns The trimmed string.\n */\nexport function text(array: TemplateStringsArray, ...values: unknown[]): string {\n const str = array.reduce(\n // eslint-disable-next-line @typescript-eslint/no-base-to-string\n (result, part, i) => result + part + (values[i] ? String(values[i]) : \"\"),\n \"\",\n )\n\n return trimIndentation(str)\n}\n\n/**\n * Removes the indentation from a multiline string.\n *\n * @param text The text to trim.\n * @returns The trimmed text.\n */\nexport function trimIndentation(text: string): string {\n const lines = text.split(\"\\n\")\n const indent = lines\n .filter(line => line.trim() !== \"\")\n .map(line => line.match(/^\\s*/)?.[0].length ?? 0)\n .reduce((min, indent) => Math.min(min, indent), Infinity)\n\n return lines\n .map(line => line.slice(indent))\n .join(\"\\n\")\n .trim()\n}\n","import type { TAnySchema, TSchema } from \"@sinclair/typebox\"\nimport type { Meta } from \"./types\"\nimport type { PartialKeys } from \"./utils\"\n\n/**\n * The entity is some abstract object which can be passed from one component to another through their inputs and outputs.\n * Every entity must have a type.\n * Every component inputs and outputs will reference such types and only entities of the same type can be passed.\n */\nexport type Entity<TType extends string = string, TEntitySchema extends TSchema = TSchema> = {\n /**\n * The static type of the entity.\n */\n type: TType\n\n /**\n * The JSON schema of the entity value.\n */\n schema: TEntitySchema\n\n /**\n * The extra metadata of the entity.\n */\n meta: Meta\n\n /**\n * The hash of the entity definition.\n */\n definitionHash: string\n}\n\nexport type EntityOptions<TType extends string, TSchema extends TAnySchema> = Omit<\n PartialKeys<Entity<TType, TSchema>, \"meta\">,\n \"definitionHash\"\n>\n\nexport function defineEntity<TType extends string, TSchema extends TAnySchema>(\n options: EntityOptions<TType, TSchema>,\n): Entity<TType, TSchema> {\n return {\n meta: {},\n ...options,\n } as Entity<TType, TSchema>\n}\n\nexport function isEntity(value: unknown): value is Entity {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"type\" in value &&\n \"schema\" in value &&\n \"meta\" in value\n )\n}\n","import {\n type Static,\n type TAny,\n type TArray,\n type TBoolean,\n type TLiteral,\n type TNumber,\n type TObject,\n type TRecordOrObject,\n type TString,\n type TUnion,\n} from \"@sinclair/typebox\"\n\nexport type ArgumentValueSchema =\n | TString\n | TNumber\n | TBoolean\n | TArray<TString>\n | TArray<TNumber>\n | TUnion<TLiteral[]>\n | TRecordOrObject<TString, TAny>\n | TObject\n | TArray\n | TUnion<TObject[]>\n\nexport type ArgumentValue = Static<ArgumentValueSchema>\n\n/**\n * The generic metadata of some contract.\n */\nexport type Meta = {\n /**\n * The display name of the entity which can be shown in the UI.\n */\n displayName?: string\n\n /**\n * The description of the entity which can be shown in the UI.\n */\n description?: string\n\n /**\n * The hex color of the entity which can be used in the UI.\n *\n * @example \"#ff0000\"\n */\n color?: string\n}\n","export {\n type InstanceInput,\n type HubInput,\n type InstanceModel,\n type Position,\n getInstanceId,\n parseInstanceId,\n findInput,\n findRequiredInput,\n findInputs,\n findRequiredInputs,\n} from \"./instance\"\nexport { getCompositeInstances, resetEvaluation, type CompositeInstance } from \"./evaluation\"\nexport { type Entity, defineEntity, isEntity } from \"./entity\"\nexport {\n type Component,\n type ComponentModel,\n type ComponentMeta,\n type ComponentArgument,\n type ComponentInput,\n type ComponentInputSpec,\n type ComponentArgumentSpec,\n type ComponentArgumentSpecToStatic,\n defineComponent,\n isComponent,\n originalCreate,\n} from \"./component\"\nexport { type Unit, type UnitModel, type UnitSource, defineUnit, isUnitModel } from \"./unit\"\nexport { type RequiredKeys, type PartialKeys, text, trimIndentation } from \"./utils\"\nexport { type ArgumentValue, type ArgumentValueSchema } from \"./types\"\nexport { type Static } from \"@sinclair/typebox\"\n\nimport {\n Type as BaseType,\n type Static,\n type TLiteral,\n type TSchema,\n type TUnion,\n} from \"@sinclair/typebox\"\n\ntype MapToLiteral<T extends readonly string[]> = {\n [K in keyof T]: T[K] extends string ? TLiteral<T[K]> : never\n}\n\nfunction StringEnum<T extends string[]>(values: [...T]): TUnion<MapToLiteral<T>> {\n return Type.Union(values.map(value => Type.Literal(value))) as TUnion<MapToLiteral<T>>\n}\n\nfunction Default<T extends TSchema>(\n schema: T,\n defaultValue: Static<T>,\n): T & { default: Static<T> } {\n return { ...schema, default: defaultValue }\n}\n\nexport const Type = {\n ...BaseType,\n StringEnum,\n Default,\n} as typeof BaseType & {\n StringEnum: typeof StringEnum\n Default: typeof Default\n}\n"],"mappings":"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","names":["mapValues","mapValues","text","indent","inputs","outputs","mapValues","mapValues","outputs"]}
1
+ {"version":3,"sources":["../src/instance.ts","../src/evaluation.ts","../src/unit.ts","../src/component.ts","../src/utils.ts","../src/entity.ts","../src/types.ts","../src/index.ts"],"sourcesContent":["declare const type: unique symbol\n\nexport type InstanceInput<TType extends string = string> = {\n [type]?: TType\n [boundaryInput]?: InstanceInput\n instanceId: string\n output: string\n}\n\nexport const boundaryInput = Symbol(\"boundaryInput\")\n\nexport type HubInput = {\n hubId: string\n}\n\nexport type Position = {\n x: number\n y: number\n}\n\nexport type InstanceModel = {\n /**\n * The id of the instance unique within the project.\n *\n * The format is `${instanceType}:${instanceName}`.\n */\n id: string\n\n /**\n * The type of the instance.\n */\n type: string\n\n /**\n * The name of the instance.\n *\n * Must be unique within instances of the same type in the project.\n */\n name: string\n\n /**\n * The static arguments passed to the instance.\n */\n args?: Record<string, unknown>\n\n /**\n * The direct instances passed as inputs to the instance.\n */\n inputs?: Record<string, InstanceInput[]>\n\n /**\n * The resolved unit inputs for the instance.\n *\n * Only for computed composite instances.\n */\n resolvedInputs?: Record<string, InstanceInput[]>\n\n /**\n * The inputs passed to the instance from the hubs.\n *\n * Only for designer-first instances.\n */\n hubInputs?: Record<string, HubInput[]>\n\n /**\n * The inputs injected to the instance from the hubs.\n *\n * While `hubInputs` allows to pass hubs to distinct inputs,\n * `injectionInputs` allows to pass hubs to the instance as a whole filling all inputs with matching types.\n *\n * Only for designer-first instances.\n */\n injectionInputs?: HubInput[]\n\n /**\n * The position of the instance on the canvas.\n *\n * Only for designer-first instances.\n */\n position?: Position\n\n /**\n * The id of the top level parent instance.\n *\n * Only for child instances of the composite instances.\n */\n parentId?: string\n\n /**\n * The direct instance inputs and same-level children outputs returned by the instance as outputs.\n *\n * Only for computed composite instances.\n */\n outputs?: Record<string, InstanceInput[]>\n\n /**\n * The resolved unit outputs for the instance.\n *\n * Only for computed composite instances.\n */\n resolvedOutputs?: Record<string, InstanceInput[]>\n}\n\n/**\n * Formats the instance id from the instance type and instance name.\n *\n * @param instanceType The type of the instance.\n * @param instanceName The name of the instance.\n *\n * @returns The formatted instance id.\n */\nexport function getInstanceId(instanceType: string, instanceName: string): string {\n return `${instanceType}:${instanceName}`\n}\n\n/**\n * Parses the instance id into the instance type and instance name.\n *\n * @param instanceId The instance id to parse.\n *\n * @returns The instance type and instance name.\n */\nexport function parseInstanceId(instanceId: string): [instanceType: string, instanceName: string] {\n const parts = instanceId.split(\":\")\n\n if (parts.length !== 2) {\n throw new Error(`Invalid instance key: ${instanceId}`)\n }\n\n return parts as [string, string]\n}\n\nexport function findInput<T extends string>(\n inputs: InstanceInput<T>[],\n name: string,\n): InstanceInput<T> | null {\n const matchedInputs = inputs.filter(\n input => parseInstanceId(input.instanceId)[1] === name || input.instanceId === name,\n )\n\n if (matchedInputs.length === 0) {\n return null\n }\n\n if (matchedInputs.length > 1) {\n throw new Error(\n `Multiple inputs found for \"${name}\": ${matchedInputs.map(input => input.instanceId).join(\", \")}. Specify the full instance id to disambiguate.`,\n )\n }\n\n return matchedInputs[0]\n}\n\nexport function findRequiredInput<T extends string>(\n inputs: InstanceInput<T>[],\n name: string,\n): InstanceInput<T> {\n const input = findInput(inputs, name)\n\n if (input === null) {\n throw new Error(`Required input \"${name}\" not found.`)\n }\n\n return input\n}\n\nexport function findInputs<T extends string>(\n inputs: InstanceInput<T>[],\n names: string[],\n): InstanceInput<T>[] {\n return names.map(name => findInput(inputs, name)).filter(Boolean) as InstanceInput<T>[]\n}\n\nexport function findRequiredInputs<T extends string>(\n inputs: InstanceInput<T>[],\n names: string[],\n): InstanceInput<T>[] {\n return names.map(name => findRequiredInput(inputs, name))\n}\n","import type { ComponentModel } from \"./component\"\nimport { mapValues } from \"remeda\"\nimport { boundaryInput, type InstanceInput, type InstanceModel } from \"./instance\"\nimport { isUnitModel } from \"./unit\"\n\nexport type CompositeInstance = {\n instance: InstanceModel\n children: InstanceModel[]\n}\n\nlet _externalInstanceIds = new Set<string>()\nconst compositeInstances: Map<string, CompositeInstance> = new Map()\nlet currentCompositeInstance: CompositeInstance | null = null\n\nexport function resetEvaluation(externalInstanceIds?: Set<string>): void {\n compositeInstances.clear()\n currentCompositeInstance = null\n\n _externalInstanceIds = externalInstanceIds ?? new Set<string>()\n}\n\nexport function getCompositeInstances(): CompositeInstance[] {\n return Array.from(compositeInstances.values())\n}\n\nfunction isExternalInstance(instanceId: string): boolean {\n let currentId: string | undefined = instanceId\n\n while (currentId) {\n if (_externalInstanceIds.has(currentId)) {\n return true\n }\n\n currentId = compositeInstances.get(currentId ?? \"\")?.instance.parentId\n }\n\n return false\n}\n\nexport function registerInstance<T>(\n component: ComponentModel,\n instance: InstanceModel,\n fn: () => T,\n): T {\n let previousParentInstance: CompositeInstance | null = null\n\n if (!isExternalInstance(instance.id)) {\n if (currentCompositeInstance) {\n instance.parentId = currentCompositeInstance.instance.id\n currentCompositeInstance.children.push(instance)\n }\n\n if (!isUnitModel(component)) {\n previousParentInstance = currentCompositeInstance\n currentCompositeInstance = { instance, children: [] }\n compositeInstances.set(currentCompositeInstance.instance.id, currentCompositeInstance)\n }\n }\n\n try {\n const outputs = fn() as Record<string, InstanceInput[]>\n\n instance.resolvedOutputs = outputs\n instance.outputs = mapValues(outputs ?? {}, outputs =>\n outputs.map(output => output[boundaryInput] ?? output),\n )\n\n // mark all outputs with the boundary input of the instance\n return mapValues(outputs, (outputs, outputKey) =>\n outputs.map(output => ({\n ...output,\n [boundaryInput]: { instanceId: instance.id, output: outputKey },\n })),\n ) as T\n } finally {\n if (previousParentInstance) {\n currentCompositeInstance = previousParentInstance\n }\n }\n}\n","/* eslint-disable @typescript-eslint/no-unsafe-return */\n/* eslint-disable @typescript-eslint/no-unsafe-member-access */\n/* eslint-disable @typescript-eslint/no-explicit-any */\n/* eslint-disable @typescript-eslint/no-unsafe-assignment */\n\nimport type { ArgumentValue } from \"./types\"\nimport type { InstanceInput } from \"./instance\"\nimport { mapValues } from \"remeda\"\nimport {\n type ComponentArgumentSpec,\n type Component,\n type ComponentArgument,\n type ComponentArgumentOptions,\n type ComponentInputOptions,\n type ComponentInputOptionsMapToSpecMap,\n type ComponentInputSpec,\n type ComponentModel,\n type ComponentOptions,\n defineComponent,\n mapArgument,\n type ComponentArgumentOptionsMapToSpecMap,\n} from \"./component\"\n\ntype UnitOptions<\n TArgs extends Record<string, ComponentArgumentOptions>,\n TInputs extends Record<string, ComponentInputOptions>,\n TOutputs extends Record<string, ComponentInputOptions>,\n TSecrets extends Record<string, ComponentArgumentOptions>,\n> = Omit<ComponentOptions<TArgs, TInputs, TOutputs>, \"create\"> & {\n source: UnitSource\n\n secrets?: TSecrets\n}\n\nexport type UnitSource = {\n package: string\n path?: string\n version?: string\n}\n\nexport type UnitModel = ComponentModel & {\n /**\n * The source of the unit.\n */\n source: UnitSource\n\n /**\n * The record of the secret argument schemas.\n */\n secrets: Record<string, ComponentArgument>\n}\n\nexport type Unit<\n TArgs extends Record<string, ComponentArgumentSpec> = Record<string, never>,\n TInputs extends Record<string, ComponentInputSpec> = Record<string, never>,\n TOutputs extends Record<string, ComponentInputSpec> = Record<string, never>,\n TSecrets extends Record<string, ArgumentValue> = Record<string, never>,\n> = Component<TArgs, TInputs, TOutputs> & {\n __secrets: TSecrets\n\n model: UnitModel\n}\n\nexport function isUnitModel(model: ComponentModel): model is UnitModel {\n return \"source\" in model\n}\n\nexport function defineUnit<\n TArgs extends Record<string, ComponentArgumentOptions> = Record<string, never>,\n TInputs extends Record<string, ComponentInputOptions> = Record<string, never>,\n TOutputs extends Record<string, ComponentInputOptions> = Record<string, never>,\n TSecrets extends Record<string, ComponentArgumentOptions> = Record<string, never>,\n>(\n options: UnitOptions<TArgs, TInputs, TOutputs, TSecrets>,\n // @ts-expect-error typescript bug\n): Unit<\n ComponentArgumentOptionsMapToSpecMap<TArgs>,\n ComponentInputOptionsMapToSpecMap<TInputs>,\n ComponentInputOptionsMapToSpecMap<TOutputs>,\n ComponentArgumentOptionsMapToSpecMap<TSecrets>\n> {\n const component = defineComponent<TArgs, TInputs, TOutputs>({\n ...options,\n\n create({ id }) {\n const outputs: Record<string, InstanceInput[]> = {}\n for (const key in options.outputs ?? {}) {\n outputs[key] = [\n {\n instanceId: id,\n output: key,\n },\n ]\n }\n\n return outputs as any\n },\n }) as any\n\n component.model.source = options.source ?? {}\n component.model.secrets = mapValues(options.secrets ?? {}, mapArgument)\n\n return component\n}\n","/* eslint-disable @typescript-eslint/no-unsafe-member-access */\n/* eslint-disable @typescript-eslint/no-explicit-any */\n/* eslint-disable @typescript-eslint/no-unsafe-assignment */\n/* eslint-disable @typescript-eslint/no-unsafe-return */\n\nimport type { Entity } from \"./entity\"\nimport type { ArgumentValue, ArgumentValueSchema, Meta } from \"./types\"\nimport {\n type Static,\n type TObject,\n type TOptional,\n type TSchema,\n OptionalKind,\n} from \"@sinclair/typebox\"\nimport { isNonNullish, mapValues, pickBy } from \"remeda\"\nimport { Ajv } from \"ajv\"\nimport { boundaryInput, type InstanceInput } from \"./instance\"\nimport { type OptionalUndefinedFields, type OptionalEmptyRecords } from \"./utils\"\nimport { registerInstance } from \"./evaluation\"\n\nconst ajv = new Ajv({ strict: false })\n\n// Argument\nexport type ComponentArgument = {\n schema: ArgumentValueSchema\n required: boolean\n meta: Meta\n}\n\ntype ComponentArgumentFullOptions = Meta & {\n schema: ArgumentValueSchema\n required?: boolean\n}\n\nexport type ComponentArgumentOptions = ArgumentValueSchema | ComponentArgumentFullOptions\nexport type ComponentArgumentSpec = [schema: ArgumentValueSchema, hasDefault: boolean]\n\nexport type ComponentArgumentOptionsToSpec<T extends ComponentArgumentOptions> =\n T extends ArgumentValueSchema\n ? [T, T extends { default: unknown } ? true : false]\n : T extends ComponentArgumentFullOptions\n ? T[\"schema\"] extends TOptional<TSchema>\n ? [T[\"schema\"], T[\"schema\"] extends { default: unknown } ? true : false]\n : [\n T[\"required\"] extends false ? TOptional<T[\"schema\"]> : T[\"schema\"],\n T[\"schema\"] extends { default: unknown } ? true : false,\n ]\n : never\n\nexport type ComponentArgumentOptionsMapToSpecMap<\n T extends Record<string, ComponentArgumentOptions>,\n> =\n T extends Record<string, never>\n ? Record<string, never>\n : { [K in keyof T]: ComponentArgumentOptionsToSpec<T[K]> }\n\nexport type ComponentArgumentSpecMapToInputStatic<T extends Record<string, ComponentArgumentSpec>> =\n T extends Record<string, never>\n ? Record<string, never>\n : Static<TObject<{ [K in keyof T]: T[K][1] extends false ? T[K][0] : TOptional<T[K][0]> }>>\n\nexport type ComponentArgumentSpecToStatic<T extends Record<string, ComponentArgumentSpec>> =\n T extends Record<string, never>\n ? Record<string, never>\n : Static<TObject<{ [K in keyof T]: T[K][0] }>>\n\nexport type ComponentArgumentOptionsToSchema<T extends ComponentArgumentOptions> = T extends TSchema\n ? T\n : T[\"required\"] extends false\n ? TOptional<T[\"schema\"]>\n : T[\"schema\"]\n\ntype ComponentArgumentMapToValue<T extends Record<string, ComponentArgumentOptions>> = {\n [K in keyof T]: Static<ComponentArgumentOptionsToSchema<T[K]>>\n}\n\n// Input\nexport type ComponentInput = {\n type: string\n required: boolean\n multiple: boolean\n meta: Meta\n}\n\ntype ComponentInputFullOptions = Meta & {\n entity: Entity\n required?: boolean\n multiple?: boolean\n}\n\nexport type ComponentInputOptions = Entity | ComponentInputFullOptions\n\ntype ComponentInputOptionsToOutputRef<T extends ComponentInputOptions> = T extends Entity\n ? InstanceInput<T[\"type\"]>\n : T extends ComponentInputFullOptions\n ? T[\"required\"] extends false\n ? T[\"multiple\"] extends true\n ? InstanceInput<T[\"entity\"][\"type\"]>[] | undefined\n : InstanceInput<T[\"entity\"][\"type\"]> | undefined\n : T[\"multiple\"] extends true\n ? InstanceInput<T[\"entity\"][\"type\"]>[]\n : InstanceInput<T[\"entity\"][\"type\"]>\n : never\n\nexport type ComponentInputSpec = [entity: Entity, required: boolean, multiple: boolean]\n\nexport type ComponentInputOptionsToSpec<T extends ComponentInputOptions> = T extends Entity\n ? [T, true, false] // [Entity, required, multiple]\n : T extends ComponentInputFullOptions\n ? T[\"required\"] extends false\n ? T[\"multiple\"] extends true\n ? [T[\"entity\"], false, true]\n : [T[\"entity\"], false, false]\n : T[\"multiple\"] extends true\n ? [T[\"entity\"], true, true]\n : [T[\"entity\"], true, false]\n : never\n\nexport type ComponentInputOptionsMapToSpecMap<T extends Record<string, ComponentInputOptions>> =\n T extends Record<string, never>\n ? Record<string, never>\n : { [K in keyof T]: ComponentInputOptionsToSpec<T[K]> }\n\ntype ComponentInputMapToValue<T extends Record<string, ComponentInputOptions>> =\n OptionalUndefinedFields<{\n [K in keyof T]: ComponentInputOptionsToOutputRef<T[K]>\n }>\n\ntype ComponentInputMapToReturnType<T extends Record<string, ComponentInputOptions>> =\n T extends Record<string, never> ? void : ComponentInputMapToValue<T>\n\n// Params & Options\nexport type ComponentParams<\n TArgs extends Record<string, ComponentArgumentOptions>,\n TInputs extends Record<string, ComponentInputOptions>,\n> = {\n id: string\n name: string\n args: ComponentArgumentMapToValue<TArgs>\n inputs: ComponentInputMapToValue<TInputs>\n}\n\nexport type InputComponentParams<\n TArgs extends Record<string, ArgumentValue>,\n TInputs extends Record<string, unknown>,\n> = {\n name: string\n} & OptionalEmptyRecords<{\n args: TArgs\n inputs: TInputs\n}>\n\nexport type ComponentOptions<\n TArgs extends Record<string, ComponentArgumentOptions>,\n TInputs extends Record<string, ComponentInputOptions>,\n TOutputs extends Record<string, ComponentInputOptions>,\n> = {\n type: string\n meta?: ComponentMeta\n\n args?: TArgs\n inputs?: TInputs\n outputs?: TOutputs\n\n create: (params: ComponentParams<TArgs, TInputs>) => ComponentInputMapToReturnType<TOutputs>\n}\n\n// Models\nexport type ComponentMeta = Meta & {\n primaryIcon?: string\n primaryIconColor?: string\n secondaryIcon?: string\n secondaryIconColor?: string\n category?: string\n defaultNamePrefix?: string\n}\n\nexport type ComponentModel = {\n /**\n * The type of the component.\n */\n type: string\n\n /**\n * The record of the argument schemas.\n */\n args: Record<string, ComponentArgument>\n\n /**\n * The record of the input schemas.\n */\n inputs: Record<string, ComponentInput>\n\n /**\n * The record of the output schemas.\n */\n outputs: Record<string, ComponentInput>\n\n /**\n * The extra metadata of the component.\n */\n meta: ComponentMeta\n\n /**\n * The hash of the component definition.\n */\n definitionHash: string\n}\n\ntype InputSpecToInputRef<T extends ComponentInputSpec> = T[1] extends true\n ? T[2] extends true\n ? InstanceInput<T[0][\"type\"]>[]\n : InstanceInput<T[0][\"type\"]>\n : T[2] extends true\n ? InstanceInput<T[0][\"type\"]>[] | undefined\n : InstanceInput<T[0][\"type\"]> | undefined\n\ntype InputSpecToOutputRef<T extends ComponentInputSpec> = T[2] extends true\n ? InstanceInput<T[0][\"type\"]>[]\n : InstanceInput<T[0][\"type\"]>\n\nexport type InputRefMap<TInputs extends Record<string, ComponentInputSpec>> =\n TInputs extends Record<string, [string, never, never]>\n ? Record<string, never>\n : { [K in keyof TInputs]: InputSpecToInputRef<TInputs[K]> }\n\nexport type OutputRefMap<TInputs extends Record<string, ComponentInputSpec>> =\n TInputs extends Record<string, [string, never, never]>\n ? Record<string, never>\n : { [K in keyof TInputs]: InputSpecToOutputRef<TInputs[K]> }\n\nexport const originalCreate = Symbol(\"originalCreate\")\n\nexport type Component<\n TArgs extends Record<string, ComponentArgumentSpec> = Record<string, never>,\n TInputs extends Record<string, ComponentInputSpec> = Record<string, never>,\n TOutputs extends Record<string, ComponentInputSpec> = Record<string, never>,\n> = {\n /**\n * The non-generic model of the component.\n */\n model: ComponentModel\n\n /**\n * The entities used in the inputs or outputs of the component.\n */\n entities: Map<string, Entity>\n\n /**\n * Creates the component at the evaluation time.\n */\n (\n context: InputComponentParams<\n ComponentArgumentSpecMapToInputStatic<TArgs>,\n InputRefMap<TInputs>\n >,\n ): OutputRefMap<TOutputs>\n\n /**\n * The original create function.\n *\n * Used to calculate the definition hash.\n */\n [originalCreate]: (params: InputComponentParams<any, any>) => any\n}\n\nexport function defineComponent<\n TArgs extends Record<string, ComponentArgumentOptions> = Record<string, never>,\n TInputs extends Record<string, ComponentInputOptions> = Record<string, never>,\n TOutputs extends Record<string, ComponentInputOptions> = Record<string, never>,\n>(\n options: ComponentOptions<TArgs, TInputs, TOutputs>,\n // @ts-expect-error typescript bug\n): Component<\n ComponentArgumentOptionsMapToSpecMap<TArgs>,\n ComponentInputOptionsMapToSpecMap<TInputs>,\n ComponentInputOptionsMapToSpecMap<TOutputs>\n> {\n function create(params: InputComponentParams<any, any>): any {\n const { name, args, inputs } = params\n const id = `${options.type}:${name}`\n\n const flatInputs = mapValues(pickBy(inputs ?? {}, isNonNullish), inputs => [inputs].flat(2))\n\n return registerInstance(\n create.model as ComponentModel,\n {\n id,\n type: options.type,\n name,\n args: args ?? {},\n inputs: mapValues(flatInputs, inputs => inputs.map(input => input[boundaryInput] ?? input)),\n resolvedInputs: flatInputs,\n },\n () => {\n const markedInputs = mapValues(flatInputs, (inputs, key) => {\n const result = inputs.map(input => ({\n ...input,\n [boundaryInput]: { instanceId: id, output: key },\n }))\n\n return (create.model as ComponentModel).inputs?.[key]?.multiple === false\n ? result[0]\n : result\n })\n\n const outputs: Record<string, InstanceInput[]> =\n options.create({\n id,\n name,\n args: validateArgsAndFillDefaults(\n id,\n create.model as ComponentModel,\n args ? { ...args } : {},\n ) as any,\n inputs: markedInputs as any,\n }) ?? {}\n\n return mapValues(pickBy(outputs, isNonNullish), outputs => [outputs].flat(2))\n },\n )\n }\n\n create.entities = new Map<string, Entity>()\n const mapInput = createInputMapper(create.entities)\n\n create.model = {\n type: options.type,\n args: mapValues(options.args ?? {}, mapArgument),\n inputs: mapValues(options.inputs ?? {}, mapInput),\n outputs: mapValues(options.outputs ?? {}, mapInput),\n meta: options.meta ?? {},\n }\n\n create[originalCreate] = options.create\n\n return create as any\n}\n\nexport function isComponent(value: unknown): value is Component {\n return typeof value === \"function\" && \"model\" in value\n}\n\nexport function mapArgument(value: ComponentArgumentOptions) {\n if (\"schema\" in value) {\n return {\n schema: value.schema,\n required:\n value.required ?? (!value.schema[OptionalKind] && value.schema.default === undefined),\n meta: {\n displayName: value.displayName,\n description: value.description,\n color: value.color,\n },\n }\n }\n\n return {\n schema: value,\n required: !value[OptionalKind] && value.default === undefined,\n meta: {},\n }\n}\n\nexport function createInputMapper(entities: Map<string, Entity>) {\n return (value: ComponentInputOptions) => {\n if (\"entity\" in value) {\n entities.set(value.entity.type, value.entity)\n\n return {\n type: value.entity.type,\n required: value.required ?? true,\n multiple: value.multiple ?? false,\n meta: {\n displayName: value.displayName,\n description: value.description,\n color: value.color,\n },\n }\n }\n\n entities.set(value.type, value)\n\n return {\n type: value.type,\n required: true,\n multiple: false,\n meta: {},\n }\n }\n}\n\nfunction validateArgsAndFillDefaults(\n instanceId: string,\n model: ComponentModel,\n args: Record<string, unknown>,\n) {\n for (const [key, argModel] of Object.entries(model.args)) {\n let value = args[key]\n if (!value) {\n if (argModel.required) {\n throw new Error(`Missing required argument \"${key}\" for instance \"${instanceId}\"`)\n }\n\n value = argModel.schema.default\n args[key] = value\n }\n\n if (value && !ajv.validate(argModel.schema, value)) {\n throw new Error(`Invalid argument \"${key}\" for instance \"${instanceId}\": ${ajv.errorsText()}`)\n }\n }\n\n return args as Record<string, ArgumentValue>\n}\n","export type EntityMap<T> = Record<string, T> & {\n default?: T\n}\n\nexport type PartialKeys<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>\nexport type RequiredKeys<T, K extends keyof T> = Omit<T, K> & Required<Pick<T, K>>\n\n// TODO: refactor this shit\n\ntype PickUndefinedKeys<T extends Record<string, unknown>> =\n T extends Record<string, never>\n ? never\n : Exclude<\n {\n [K in keyof T]: undefined extends T[K] ? K : never\n }[keyof T],\n undefined\n >\n\ntype AllOptionalKeys<T extends Record<string, unknown>> =\n T extends Record<string, never>\n ? never\n : Exclude<\n {\n [K in keyof T]: undefined extends T[K] ? K : never\n }[keyof T],\n undefined\n >\n\ntype HasRequired<T extends Record<string, unknown>> =\n T extends Record<string, never> ? false : [keyof T] extends [AllOptionalKeys<T>] ? false : true\n\ntype PickRecordsWithAnyRequired<T extends Record<string, Record<string, unknown>>> =\n T extends Record<string, never>\n ? never\n : Exclude<\n {\n [K in keyof T]: HasRequired<T[K]> extends true ? K : never\n }[keyof T],\n undefined\n >\n\nexport type OptionalEmptyRecords<T extends Record<string, Record<string, unknown>>> = {\n [K in Exclude<keyof T, PickRecordsWithAnyRequired<T>>]?: OptionalUndefinedFields<T[K]>\n} & {\n [K in PickRecordsWithAnyRequired<T>]: OptionalUndefinedFields<T[K]>\n}\n\nexport type OptionalUndefinedFields<T extends Record<string, unknown>> = {\n [K in PickUndefinedKeys<T>]?: T[K]\n} & {\n [K in Exclude<keyof T, PickUndefinedKeys<T>>]: T[K]\n}\n\n/**\n * Formats a multiline string and trims the indentation.\n *\n * @param str The string to trim.\n * @returns The trimmed string.\n */\nexport function text(strings: TemplateStringsArray, ...values: unknown[]): string {\n // Convert all values to strings\n const stringValues = values.map(String)\n\n // Build full string with values interpolated\n let result = \"\"\n for (let i = 0; i < strings.length; i++) {\n result += strings[i]\n if (i < stringValues.length) {\n const value = stringValues[i]\n const lines = value.split(\"\\n\")\n const lastLineIndentMatch = strings[i].match(/(?:^|\\n)([ \\t]*)$/)\n const indent = lastLineIndentMatch ? lastLineIndentMatch[1] : \"\"\n\n result += lines.map((line, j) => (j === 0 ? line : indent + line)).join(\"\\n\")\n }\n }\n\n return trimIndentation(result)\n}\n\n/**\n * Removes the indentation from a multiline string.\n *\n * @param text The text to trim.\n * @returns The trimmed text.\n */\nexport function trimIndentation(text: string): string {\n const lines = text.split(\"\\n\")\n const indent = lines\n .filter(line => line.trim() !== \"\")\n .map(line => line.match(/^\\s*/)?.[0].length ?? 0)\n .reduce((min, indent) => Math.min(min, indent), Infinity)\n\n return lines\n .map(line => line.slice(indent))\n .join(\"\\n\")\n .trim()\n}\n\nexport function bytesToHumanReadable(bytes: number): string {\n const sizes = [\"Bytes\", \"KB\", \"MB\", \"GB\", \"TB\"]\n if (bytes === 0) return \"0 Bytes\"\n\n const i = Math.floor(Math.log(bytes) / Math.log(1024))\n return parseFloat((bytes / Math.pow(1024, i)).toFixed(2)) + \" \" + sizes[i]\n}\n","import type { TAnySchema, TSchema } from \"@sinclair/typebox\"\nimport type { Meta } from \"./types\"\nimport type { PartialKeys } from \"./utils\"\n\n/**\n * The entity is some abstract object which can be passed from one component to another through their inputs and outputs.\n * Every entity must have a type.\n * Every component inputs and outputs will reference such types and only entities of the same type can be passed.\n */\nexport type Entity<TType extends string = string, TEntitySchema extends TSchema = TSchema> = {\n /**\n * The static type of the entity.\n */\n type: TType\n\n /**\n * The JSON schema of the entity value.\n */\n schema: TEntitySchema\n\n /**\n * The extra metadata of the entity.\n */\n meta: Meta\n\n /**\n * The hash of the entity definition.\n */\n definitionHash: string\n}\n\nexport type EntityOptions<TType extends string, TSchema extends TAnySchema> = Omit<\n PartialKeys<Entity<TType, TSchema>, \"meta\">,\n \"definitionHash\"\n>\n\nexport function defineEntity<TType extends string, TSchema extends TAnySchema>(\n options: EntityOptions<TType, TSchema>,\n): Entity<TType, TSchema> {\n return {\n meta: {},\n ...options,\n } as Entity<TType, TSchema>\n}\n\nexport function isEntity(value: unknown): value is Entity {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"type\" in value &&\n \"schema\" in value &&\n \"meta\" in value\n )\n}\n","import {\n type Static,\n type TAny,\n type TArray,\n type TBoolean,\n type TLiteral,\n type TNumber,\n type TObject,\n type TRecordOrObject,\n type TString,\n type TUnion,\n} from \"@sinclair/typebox\"\n\nexport type ArgumentValueSchema =\n | TString\n | TNumber\n | TBoolean\n | TArray<TString>\n | TArray<TNumber>\n | TUnion<TLiteral[]>\n | TRecordOrObject<TString, TAny>\n | TObject\n | TArray\n | TUnion<TObject[]>\n\nexport type ArgumentValue = Static<ArgumentValueSchema>\n\n/**\n * The generic metadata of some contract.\n */\nexport type Meta = {\n /**\n * The display name of the entity which can be shown in the UI.\n */\n displayName?: string\n\n /**\n * The description of the entity which can be shown in the UI.\n */\n description?: string\n\n /**\n * The hex color of the entity which can be used in the UI.\n *\n * @example \"#ff0000\"\n */\n color?: string\n}\n","export {\n type InstanceInput,\n type HubInput,\n type InstanceModel,\n type Position,\n getInstanceId,\n parseInstanceId,\n findInput,\n findRequiredInput,\n findInputs,\n findRequiredInputs,\n} from \"./instance\"\nexport { getCompositeInstances, resetEvaluation, type CompositeInstance } from \"./evaluation\"\nexport { type Entity, defineEntity, isEntity } from \"./entity\"\nexport {\n type Component,\n type ComponentModel,\n type ComponentMeta,\n type ComponentArgument,\n type ComponentInput,\n type ComponentInputSpec,\n type ComponentArgumentSpec,\n type ComponentArgumentSpecToStatic,\n defineComponent,\n isComponent,\n originalCreate,\n} from \"./component\"\nexport { type Unit, type UnitModel, type UnitSource, defineUnit, isUnitModel } from \"./unit\"\nexport {\n type RequiredKeys,\n type PartialKeys,\n text,\n trimIndentation,\n bytesToHumanReadable,\n} from \"./utils\"\nexport { type ArgumentValue, type ArgumentValueSchema } from \"./types\"\nexport * from \"@sinclair/typebox\"\n\nimport {\n Type as BaseType,\n type Static,\n type TLiteral,\n type TSchema,\n type TUnion,\n} from \"@sinclair/typebox\"\n\ntype MapToLiteral<T extends readonly string[]> = {\n [K in keyof T]: T[K] extends string ? TLiteral<T[K]> : never\n}\n\nfunction StringEnum<T extends string[]>(values: [...T]): TUnion<MapToLiteral<T>> {\n return Type.Union(values.map(value => Type.Literal(value))) as TUnion<MapToLiteral<T>>\n}\n\nfunction Default<T extends TSchema>(\n schema: T,\n defaultValue: Static<T>,\n): T & { default: Static<T> } {\n return { ...schema, default: defaultValue }\n}\n\nexport const Type = {\n ...BaseType,\n StringEnum,\n Default,\n} as typeof BaseType & {\n StringEnum: typeof StringEnum\n Default: typeof Default\n}\n"],"mappings":"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","names":["mapValues","mapValues","text","indent","inputs","outputs","mapValues","mapValues","outputs"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@highstate/contract",
3
- "version": "0.9.3",
3
+ "version": "0.9.5",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist",
@@ -16,8 +16,7 @@
16
16
  "access": "public"
17
17
  },
18
18
  "scripts": {
19
- "build": "highstate build",
20
- "test": "vitest run --coverage"
19
+ "build": "highstate build"
21
20
  },
22
21
  "dependencies": {
23
22
  "@sinclair/typebox": "^0.34.11",
@@ -29,5 +28,5 @@
29
28
  "highstate-cli-bootstrap": "npm:@highstate/cli@0.7.6",
30
29
  "vitest": "^2.1.8"
31
30
  },
32
- "gitHead": "cdd2bb1d9001ba4a39f64087eb29af6f50d82bec"
31
+ "gitHead": "93fa1e8b1189a5232055c852fd79a684d8b80444"
33
32
  }
package/src/component.ts CHANGED
@@ -33,17 +33,18 @@ type ComponentArgumentFullOptions = Meta & {
33
33
  }
34
34
 
35
35
  export type ComponentArgumentOptions = ArgumentValueSchema | ComponentArgumentFullOptions
36
- export type ComponentArgumentSpec = [schema: ArgumentValueSchema, required: boolean]
36
+ export type ComponentArgumentSpec = [schema: ArgumentValueSchema, hasDefault: boolean]
37
37
 
38
38
  export type ComponentArgumentOptionsToSpec<T extends ComponentArgumentOptions> =
39
39
  T extends ArgumentValueSchema
40
- ? T extends { default: unknown }
41
- ? [T, false]
42
- : [T, true]
40
+ ? [T, T extends { default: unknown } ? true : false]
43
41
  : T extends ComponentArgumentFullOptions
44
- ? T["required"] extends false
45
- ? [T["schema"], false]
46
- : [T["schema"], true]
42
+ ? T["schema"] extends TOptional<TSchema>
43
+ ? [T["schema"], T["schema"] extends { default: unknown } ? true : false]
44
+ : [
45
+ T["required"] extends false ? TOptional<T["schema"]> : T["schema"],
46
+ T["schema"] extends { default: unknown } ? true : false,
47
+ ]
47
48
  : never
48
49
 
49
50
  export type ComponentArgumentOptionsMapToSpecMap<
@@ -56,7 +57,7 @@ export type ComponentArgumentOptionsMapToSpecMap<
56
57
  export type ComponentArgumentSpecMapToInputStatic<T extends Record<string, ComponentArgumentSpec>> =
57
58
  T extends Record<string, never>
58
59
  ? Record<string, never>
59
- : Static<TObject<{ [K in keyof T]: T[K][1] extends true ? T[K][0] : TOptional<T[K][0]> }>>
60
+ : Static<TObject<{ [K in keyof T]: T[K][1] extends false ? T[K][0] : TOptional<T[K][0]> }>>
60
61
 
61
62
  export type ComponentArgumentSpecToStatic<T extends Record<string, ComponentArgumentSpec>> =
62
63
  T extends Record<string, never>
@@ -269,6 +270,7 @@ export function defineComponent<
269
270
  TOutputs extends Record<string, ComponentInputOptions> = Record<string, never>,
270
271
  >(
271
272
  options: ComponentOptions<TArgs, TInputs, TOutputs>,
273
+ // @ts-expect-error typescript bug
272
274
  ): Component<
273
275
  ComponentArgumentOptionsMapToSpecMap<TArgs>,
274
276
  ComponentInputOptionsMapToSpecMap<TInputs>,
@@ -343,7 +345,8 @@ export function mapArgument(value: ComponentArgumentOptions) {
343
345
  if ("schema" in value) {
344
346
  return {
345
347
  schema: value.schema,
346
- required: value.required ?? (!value.schema[OptionalKind] && !value.schema.default),
348
+ required:
349
+ value.required ?? (!value.schema[OptionalKind] && value.schema.default === undefined),
347
350
  meta: {
348
351
  displayName: value.displayName,
349
352
  description: value.description,
@@ -354,7 +357,7 @@ export function mapArgument(value: ComponentArgumentOptions) {
354
357
 
355
358
  return {
356
359
  schema: value,
357
- required: !value[OptionalKind] && !value.default,
360
+ required: !value[OptionalKind] && value.default === undefined,
358
361
  meta: {},
359
362
  }
360
363
  }
package/src/evaluation.ts CHANGED
@@ -8,33 +8,53 @@ export type CompositeInstance = {
8
8
  children: InstanceModel[]
9
9
  }
10
10
 
11
+ let _externalInstanceIds = new Set<string>()
11
12
  const compositeInstances: Map<string, CompositeInstance> = new Map()
12
13
  let currentCompositeInstance: CompositeInstance | null = null
13
14
 
14
- export function resetEvaluation(): void {
15
+ export function resetEvaluation(externalInstanceIds?: Set<string>): void {
15
16
  compositeInstances.clear()
16
17
  currentCompositeInstance = null
18
+
19
+ _externalInstanceIds = externalInstanceIds ?? new Set<string>()
17
20
  }
18
21
 
19
22
  export function getCompositeInstances(): CompositeInstance[] {
20
23
  return Array.from(compositeInstances.values())
21
24
  }
22
25
 
26
+ function isExternalInstance(instanceId: string): boolean {
27
+ let currentId: string | undefined = instanceId
28
+
29
+ while (currentId) {
30
+ if (_externalInstanceIds.has(currentId)) {
31
+ return true
32
+ }
33
+
34
+ currentId = compositeInstances.get(currentId ?? "")?.instance.parentId
35
+ }
36
+
37
+ return false
38
+ }
39
+
23
40
  export function registerInstance<T>(
24
41
  component: ComponentModel,
25
42
  instance: InstanceModel,
26
43
  fn: () => T,
27
44
  ): T {
28
- if (currentCompositeInstance) {
29
- instance.parentId = currentCompositeInstance.instance.id
30
- currentCompositeInstance.children.push(instance)
31
- }
32
-
33
45
  let previousParentInstance: CompositeInstance | null = null
34
- if (!isUnitModel(component)) {
35
- previousParentInstance = currentCompositeInstance
36
- currentCompositeInstance = { instance, children: [] }
37
- compositeInstances.set(currentCompositeInstance.instance.id, currentCompositeInstance)
46
+
47
+ if (!isExternalInstance(instance.id)) {
48
+ if (currentCompositeInstance) {
49
+ instance.parentId = currentCompositeInstance.instance.id
50
+ currentCompositeInstance.children.push(instance)
51
+ }
52
+
53
+ if (!isUnitModel(component)) {
54
+ previousParentInstance = currentCompositeInstance
55
+ currentCompositeInstance = { instance, children: [] }
56
+ compositeInstances.set(currentCompositeInstance.instance.id, currentCompositeInstance)
57
+ }
38
58
  }
39
59
 
40
60
  try {
package/src/index.ts CHANGED
@@ -26,9 +26,15 @@ export {
26
26
  originalCreate,
27
27
  } from "./component"
28
28
  export { type Unit, type UnitModel, type UnitSource, defineUnit, isUnitModel } from "./unit"
29
- export { type RequiredKeys, type PartialKeys, text, trimIndentation } from "./utils"
29
+ export {
30
+ type RequiredKeys,
31
+ type PartialKeys,
32
+ text,
33
+ trimIndentation,
34
+ bytesToHumanReadable,
35
+ } from "./utils"
30
36
  export { type ArgumentValue, type ArgumentValueSchema } from "./types"
31
- export { type Static } from "@sinclair/typebox"
37
+ export * from "@sinclair/typebox"
32
38
 
33
39
  import {
34
40
  Type as BaseType,
package/src/unit.ts CHANGED
@@ -72,6 +72,7 @@ export function defineUnit<
72
72
  TSecrets extends Record<string, ComponentArgumentOptions> = Record<string, never>,
73
73
  >(
74
74
  options: UnitOptions<TArgs, TInputs, TOutputs, TSecrets>,
75
+ // @ts-expect-error typescript bug
75
76
  ): Unit<
76
77
  ComponentArgumentOptionsMapToSpecMap<TArgs>,
77
78
  ComponentInputOptionsMapToSpecMap<TInputs>,
package/src/utils.ts CHANGED
@@ -7,29 +7,28 @@ export type RequiredKeys<T, K extends keyof T> = Omit<T, K> & Required<Pick<T, K
7
7
 
8
8
  // TODO: refactor this shit
9
9
 
10
- type PickUndefinedKeys<T extends Record<string, unknown>> = T extends Record<string, never>
11
- ? never
12
- : Exclude<
13
- {
14
- [K in keyof T]: undefined extends T[K] ? K : never
15
- }[keyof T],
16
- undefined
17
- >
18
-
19
- type AllOptionalKeys<T extends Record<string, unknown>> = T extends Record<string, never>
20
- ? never
21
- : Exclude<
22
- {
23
- [K in keyof T]: undefined extends T[K] ? K : never
24
- }[keyof T],
25
- undefined
26
- >
27
-
28
- type HasRequired<T extends Record<string, unknown>> = T extends Record<string, never>
29
- ? false
30
- : [keyof T] extends [AllOptionalKeys<T>]
31
- ? false
32
- : true
10
+ type PickUndefinedKeys<T extends Record<string, unknown>> =
11
+ T extends Record<string, never>
12
+ ? never
13
+ : Exclude<
14
+ {
15
+ [K in keyof T]: undefined extends T[K] ? K : never
16
+ }[keyof T],
17
+ undefined
18
+ >
19
+
20
+ type AllOptionalKeys<T extends Record<string, unknown>> =
21
+ T extends Record<string, never>
22
+ ? never
23
+ : Exclude<
24
+ {
25
+ [K in keyof T]: undefined extends T[K] ? K : never
26
+ }[keyof T],
27
+ undefined
28
+ >
29
+
30
+ type HasRequired<T extends Record<string, unknown>> =
31
+ T extends Record<string, never> ? false : [keyof T] extends [AllOptionalKeys<T>] ? false : true
33
32
 
34
33
  type PickRecordsWithAnyRequired<T extends Record<string, Record<string, unknown>>> =
35
34
  T extends Record<string, never>
@@ -59,14 +58,25 @@ export type OptionalUndefinedFields<T extends Record<string, unknown>> = {
59
58
  * @param str The string to trim.
60
59
  * @returns The trimmed string.
61
60
  */
62
- export function text(array: TemplateStringsArray, ...values: unknown[]): string {
63
- const str = array.reduce(
64
- // eslint-disable-next-line @typescript-eslint/no-base-to-string
65
- (result, part, i) => result + part + (values[i] ? String(values[i]) : ""),
66
- "",
67
- )
68
-
69
- return trimIndentation(str)
61
+ export function text(strings: TemplateStringsArray, ...values: unknown[]): string {
62
+ // Convert all values to strings
63
+ const stringValues = values.map(String)
64
+
65
+ // Build full string with values interpolated
66
+ let result = ""
67
+ for (let i = 0; i < strings.length; i++) {
68
+ result += strings[i]
69
+ if (i < stringValues.length) {
70
+ const value = stringValues[i]
71
+ const lines = value.split("\n")
72
+ const lastLineIndentMatch = strings[i].match(/(?:^|\n)([ \t]*)$/)
73
+ const indent = lastLineIndentMatch ? lastLineIndentMatch[1] : ""
74
+
75
+ result += lines.map((line, j) => (j === 0 ? line : indent + line)).join("\n")
76
+ }
77
+ }
78
+
79
+ return trimIndentation(result)
70
80
  }
71
81
 
72
82
  /**
@@ -87,3 +97,11 @@ export function trimIndentation(text: string): string {
87
97
  .join("\n")
88
98
  .trim()
89
99
  }
100
+
101
+ export function bytesToHumanReadable(bytes: number): string {
102
+ const sizes = ["Bytes", "KB", "MB", "GB", "TB"]
103
+ if (bytes === 0) return "0 Bytes"
104
+
105
+ const i = Math.floor(Math.log(bytes) / Math.log(1024))
106
+ return parseFloat((bytes / Math.pow(1024, i)).toFixed(2)) + " " + sizes[i]
107
+ }