@highstate/backend 0.7.2 → 0.7.3
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.
- package/dist/{index.mjs → index.js} +1254 -915
- package/dist/library/source-resolution-worker.js +55 -0
- package/dist/library/worker/main.js +207 -0
- package/dist/{terminal-CqIsctlZ.mjs → library-BW5oPM7V.js} +210 -87
- package/dist/shared/index.js +6 -0
- package/dist/utils-ByadNcv4.js +102 -0
- package/package.json +14 -18
- package/src/common/index.ts +3 -0
- package/src/common/local.ts +22 -0
- package/src/common/pulumi.ts +230 -0
- package/src/common/utils.ts +137 -0
- package/src/config.ts +40 -0
- package/src/index.ts +6 -0
- package/src/library/abstractions.ts +83 -0
- package/src/library/factory.ts +20 -0
- package/src/library/index.ts +2 -0
- package/src/library/local.ts +404 -0
- package/src/library/source-resolution-worker.ts +96 -0
- package/src/library/worker/evaluator.ts +119 -0
- package/src/library/worker/loader.ts +93 -0
- package/src/library/worker/main.ts +82 -0
- package/src/library/worker/protocol.ts +38 -0
- package/src/orchestrator/index.ts +1 -0
- package/src/orchestrator/manager.ts +165 -0
- package/src/orchestrator/operation-workset.ts +483 -0
- package/src/orchestrator/operation.ts +647 -0
- package/src/preferences/shared.ts +1 -0
- package/src/project/abstractions.ts +89 -0
- package/src/project/factory.ts +11 -0
- package/src/project/index.ts +4 -0
- package/src/project/local.ts +412 -0
- package/src/project/lock.ts +39 -0
- package/src/project/manager.ts +374 -0
- package/src/runner/abstractions.ts +146 -0
- package/src/runner/factory.ts +22 -0
- package/src/runner/index.ts +2 -0
- package/src/runner/local.ts +698 -0
- package/src/secret/abstractions.ts +59 -0
- package/src/secret/factory.ts +22 -0
- package/src/secret/index.ts +2 -0
- package/src/secret/local.ts +152 -0
- package/src/services.ts +133 -0
- package/src/shared/index.ts +10 -0
- package/src/shared/library.ts +77 -0
- package/src/shared/operation.ts +85 -0
- package/src/shared/project.ts +62 -0
- package/src/shared/resolvers/graph-resolver.ts +111 -0
- package/src/shared/resolvers/input-hash.ts +77 -0
- package/src/shared/resolvers/input.ts +314 -0
- package/src/shared/resolvers/registry.ts +10 -0
- package/src/shared/resolvers/validation.ts +94 -0
- package/src/shared/state.ts +262 -0
- package/src/shared/terminal.ts +13 -0
- package/src/state/abstractions.ts +222 -0
- package/src/state/factory.ts +22 -0
- package/src/state/index.ts +3 -0
- package/src/state/local.ts +605 -0
- package/src/state/manager.ts +33 -0
- package/src/terminal/docker.ts +90 -0
- package/src/terminal/factory.ts +20 -0
- package/src/terminal/index.ts +3 -0
- package/src/terminal/manager.ts +330 -0
- package/src/terminal/run.sh.ts +37 -0
- package/src/terminal/shared.ts +50 -0
- package/src/workspace/abstractions.ts +41 -0
- package/src/workspace/factory.ts +14 -0
- package/src/workspace/index.ts +2 -0
- package/src/workspace/local.ts +54 -0
- package/dist/index.d.ts +0 -760
- package/dist/library/worker/main.mjs +0 -164
- package/dist/runner/source-resolution-worker.mjs +0 -22
- package/dist/shared/index.d.ts +0 -85
- package/dist/shared/index.mjs +0 -54
- package/dist/terminal-Cm2WqcyB.d.ts +0 -1589
@@ -1,6 +1,8 @@
|
|
1
1
|
import { z } from 'zod';
|
2
|
-
import { omit, unique, fromEntries } from 'remeda';
|
2
|
+
import { omit, unique, mapValues, fromEntries } from 'remeda';
|
3
|
+
import { isUnitModel } from '@highstate/contract';
|
3
4
|
import { sha256 } from 'crypto-hash';
|
5
|
+
import { Ajv } from 'ajv';
|
4
6
|
|
5
7
|
const positionSchema = z.object({
|
6
8
|
x: z.number(),
|
@@ -25,12 +27,15 @@ const instanceModelSchema = z.object({
|
|
25
27
|
type: z.string(),
|
26
28
|
name: z.string(),
|
27
29
|
...instanceModelPatchSchema.shape,
|
30
|
+
resolvedInputs: z.record(z.array(instanceInputSchema)).optional(),
|
28
31
|
parentId: z.string().optional(),
|
29
|
-
outputs: z.record(z.array(instanceInputSchema)).optional()
|
32
|
+
outputs: z.record(z.array(instanceInputSchema)).optional(),
|
33
|
+
resolvedOutputs: z.record(z.array(instanceInputSchema)).optional()
|
30
34
|
});
|
31
35
|
const compositeInstanceSchema = z.object({
|
32
36
|
instance: instanceModelSchema,
|
33
|
-
children: z.array(instanceModelSchema)
|
37
|
+
children: z.array(instanceModelSchema),
|
38
|
+
inputHash: z.string().optional()
|
34
39
|
});
|
35
40
|
const hubModelPatchSchema = z.object({
|
36
41
|
position: positionSchema.optional(),
|
@@ -60,15 +65,17 @@ const instanceStatusFieldSchema = z.object({
|
|
60
65
|
value: z.string().optional(),
|
61
66
|
displayName: z.string().optional(),
|
62
67
|
sensitive: z.boolean().optional(),
|
63
|
-
url: z.string().optional()
|
68
|
+
url: z.string().optional(),
|
69
|
+
complementaryTo: z.string().optional()
|
64
70
|
});
|
65
71
|
const instanceFileMetaSchema = z.object({
|
66
72
|
name: z.string(),
|
67
73
|
contentType: z.string(),
|
74
|
+
size: z.number(),
|
68
75
|
isBinary: z.boolean().optional()
|
69
76
|
});
|
70
77
|
const instanceFileSchema = z.object({
|
71
|
-
|
78
|
+
meta: instanceFileMetaSchema,
|
72
79
|
content: z.string()
|
73
80
|
});
|
74
81
|
const instancePageBlockSchema = z.union([
|
@@ -142,13 +149,14 @@ const instanceStateSchema = z.object({
|
|
142
149
|
inputHash: z.string().nullable().default(null),
|
143
150
|
outputHash: z.string().nullable().default(null),
|
144
151
|
error: z.string().nullable().default(null),
|
152
|
+
evaluationError: z.string().nullable().default(null),
|
145
153
|
statusFields: z.array(instanceStatusFieldSchema).default(() => []),
|
146
154
|
files: z.array(instanceFileMetaSchema).default(() => []),
|
147
155
|
pages: z.array(instancePageMetaSchema).default(() => []),
|
148
156
|
terminals: z.array(instanceTerminalMetaSchema).default(() => []),
|
149
157
|
triggers: z.array(instanceTriggerSchema).default(() => [])
|
150
158
|
});
|
151
|
-
const
|
159
|
+
const instanceStateUpdateSchema = z.object({
|
152
160
|
...instanceStateSchema.shape,
|
153
161
|
// secrets updated by the unit
|
154
162
|
secrets: z.record(z.string()).nullable(),
|
@@ -167,6 +175,7 @@ function createInstanceState(id, status = "not_created", fields = {}) {
|
|
167
175
|
inputHash: null,
|
168
176
|
outputHash: null,
|
169
177
|
error: null,
|
178
|
+
evaluationError: null,
|
170
179
|
statusFields: [],
|
171
180
|
files: [],
|
172
181
|
pages: [],
|
@@ -179,54 +188,13 @@ function applyPartialInstanceState(states, patch) {
|
|
179
188
|
if (!patch.id) {
|
180
189
|
throw new Error("The ID of the instance state is required.");
|
181
190
|
}
|
182
|
-
let state = states.get(patch.id);
|
183
|
-
|
184
|
-
|
185
|
-
states.set(patch.id, state);
|
186
|
-
}
|
187
|
-
if (patch.status !== void 0) {
|
188
|
-
state.status = patch.status;
|
189
|
-
}
|
190
|
-
if (patch.dependencyIds !== void 0) {
|
191
|
-
state.dependencyIds = patch.dependencyIds;
|
192
|
-
}
|
193
|
-
if (patch.latestOperationId !== void 0) {
|
194
|
-
state.latestOperationId = patch.latestOperationId;
|
195
|
-
}
|
196
|
-
if (patch.currentResourceCount !== void 0) {
|
197
|
-
state.currentResourceCount = patch.currentResourceCount;
|
198
|
-
}
|
199
|
-
if (patch.totalResourceCount !== void 0) {
|
200
|
-
state.totalResourceCount = patch.totalResourceCount;
|
201
|
-
}
|
202
|
-
if (patch.inputHash !== void 0) {
|
203
|
-
state.inputHash = patch.inputHash;
|
204
|
-
}
|
205
|
-
if (patch.outputHash !== void 0) {
|
206
|
-
state.outputHash = patch.outputHash;
|
207
|
-
}
|
208
|
-
if (patch.error !== void 0) {
|
209
|
-
state.error = patch.error;
|
210
|
-
}
|
211
|
-
if (patch.statusFields !== void 0) {
|
212
|
-
state.statusFields = patch.statusFields;
|
213
|
-
}
|
214
|
-
if (patch.files !== void 0) {
|
215
|
-
state.files = patch.files;
|
216
|
-
}
|
217
|
-
if (patch.pages !== void 0) {
|
218
|
-
state.pages = patch.pages;
|
219
|
-
}
|
220
|
-
if (patch.terminals !== void 0) {
|
221
|
-
state.terminals = patch.terminals;
|
222
|
-
}
|
223
|
-
if (patch.triggers !== void 0) {
|
224
|
-
state.triggers = patch.triggers;
|
225
|
-
}
|
191
|
+
let state = states.get(patch.id) ?? createInstanceState(patch.id, "unknown");
|
192
|
+
state = { ...state, ...patch };
|
193
|
+
states.set(state.id, state);
|
226
194
|
return state;
|
227
195
|
}
|
228
|
-
function
|
229
|
-
return omit(
|
196
|
+
function createInstanceStatePatch(update) {
|
197
|
+
return omit(update, ["secrets", "logLine"]);
|
230
198
|
}
|
231
199
|
function buildDependentInstanceStateMap(instanceStates) {
|
232
200
|
const dependentMap = /* @__PURE__ */ new Map();
|
@@ -259,17 +227,9 @@ function getAllDependentInstanceIds(dependentMap, instanceId) {
|
|
259
227
|
return Array.from(result);
|
260
228
|
}
|
261
229
|
|
262
|
-
const operationTypeSchema = z.enum([
|
263
|
-
"update",
|
264
|
-
"preview",
|
265
|
-
"destroy",
|
266
|
-
"recreate",
|
267
|
-
"refresh",
|
268
|
-
"evaluate"
|
269
|
-
]);
|
230
|
+
const operationTypeSchema = z.enum(["update", "preview", "destroy", "recreate", "refresh"]);
|
270
231
|
const operationStatusSchema = z.enum([
|
271
232
|
"pending",
|
272
|
-
"evaluating",
|
273
233
|
"running",
|
274
234
|
"completed",
|
275
235
|
"failed",
|
@@ -323,6 +283,7 @@ const projectOperationSchema = z.object({
|
|
323
283
|
projectId: z.string(),
|
324
284
|
type: operationTypeSchema,
|
325
285
|
instanceIds: z.array(z.string()),
|
286
|
+
affectedInstanceIds: z.array(z.string()).default(() => []),
|
326
287
|
options: operationOptionsSchema.default(() => ({})),
|
327
288
|
error: z.string().nullable(),
|
328
289
|
startedAt: z.number(),
|
@@ -345,8 +306,10 @@ function createDefaultGraphResolverBackend() {
|
|
345
306
|
};
|
346
307
|
}
|
347
308
|
function defineGraphResolver(options) {
|
348
|
-
|
309
|
+
const factory = (nodes, logger, backend) => {
|
349
310
|
backend ??= createDefaultGraphResolverBackend();
|
311
|
+
logger = logger.child({ resolver: options.name });
|
312
|
+
const outputs = /* @__PURE__ */ new Map();
|
350
313
|
const resolver = (itemId, dependencyChain) => {
|
351
314
|
logger.trace({ itemId }, "resolving item");
|
352
315
|
const existingPromise = backend.promiseCache.get(itemId);
|
@@ -364,19 +327,16 @@ function defineGraphResolver(options) {
|
|
364
327
|
const dependencies = unique(options.getNodeDependencies(item));
|
365
328
|
backend.setDependencies?.(itemId, dependencies);
|
366
329
|
logger.trace({ itemId, dependencies }, "resolving item dependencies");
|
367
|
-
const resolvedDependencies = /* @__PURE__ */ new Map();
|
368
330
|
const newChain = [...dependencyChain, itemId];
|
369
331
|
for (const depId of dependencies) {
|
370
|
-
|
371
|
-
if (depResult !== void 0) {
|
372
|
-
resolvedDependencies.set(depId, depResult);
|
373
|
-
}
|
332
|
+
await resolver(depId, newChain);
|
374
333
|
}
|
375
|
-
return await options.process(item,
|
334
|
+
return await options.process(item, outputs, logger);
|
376
335
|
};
|
377
336
|
const promise = resolve().then((result) => {
|
378
337
|
if (backend.promiseCache.get(itemId) === promise) {
|
379
338
|
backend.setOutput?.(itemId, result);
|
339
|
+
outputs.set(itemId, result);
|
380
340
|
}
|
381
341
|
return result;
|
382
342
|
});
|
@@ -385,9 +345,12 @@ function defineGraphResolver(options) {
|
|
385
345
|
};
|
386
346
|
return (id) => resolver(id, []);
|
387
347
|
};
|
348
|
+
factory.factoryName = options.name;
|
349
|
+
return factory;
|
388
350
|
}
|
389
351
|
|
390
352
|
const createInputResolver = defineGraphResolver({
|
353
|
+
name: "input-resolver",
|
391
354
|
getNodeId(node) {
|
392
355
|
if (node.kind === "hub") {
|
393
356
|
return `hub:${node.hub.id}`;
|
@@ -405,6 +368,11 @@ const createInputResolver = defineGraphResolver({
|
|
405
368
|
}
|
406
369
|
return dependencies;
|
407
370
|
}
|
371
|
+
for (const inputs of Object.values(node.instance.inputs ?? {})) {
|
372
|
+
for (const input of inputs) {
|
373
|
+
dependencies.push(`instance:${input.instanceId}`);
|
374
|
+
}
|
375
|
+
}
|
408
376
|
for (const inputs of Object.values(node.instance.hubInputs ?? {})) {
|
409
377
|
for (const input of inputs) {
|
410
378
|
dependencies.push(`hub:${input.hubId}`);
|
@@ -429,12 +397,20 @@ const createInputResolver = defineGraphResolver({
|
|
429
397
|
const getInstanceOutput = (input) => {
|
430
398
|
const output = dependencies.get(`instance:${input.instanceId}`);
|
431
399
|
if (!output) {
|
432
|
-
return {
|
400
|
+
return {
|
401
|
+
component: null,
|
402
|
+
resolvedInputs: [],
|
403
|
+
resolvedOutputs: []
|
404
|
+
};
|
433
405
|
}
|
434
406
|
if (output.kind !== "instance") {
|
435
407
|
throw new Error("Expected instance node");
|
436
408
|
}
|
437
|
-
return
|
409
|
+
return {
|
410
|
+
component: output.component,
|
411
|
+
resolvedInputs: output.resolvedInputs[input.output] ?? [],
|
412
|
+
resolvedOutputs: output.resolvedOutputs[input.output] ?? []
|
413
|
+
};
|
438
414
|
};
|
439
415
|
if (node.kind === "hub") {
|
440
416
|
const hubResult = /* @__PURE__ */ new Map();
|
@@ -461,6 +437,27 @@ const createInputResolver = defineGraphResolver({
|
|
461
437
|
resolvedInputs: Array.from(hubResult.values())
|
462
438
|
};
|
463
439
|
}
|
440
|
+
if (node.instance.resolvedInputs) {
|
441
|
+
return {
|
442
|
+
kind: "instance",
|
443
|
+
component: node.component,
|
444
|
+
resolvedInputs: mapValues(node.instance.resolvedInputs, (inputs, inputName) => {
|
445
|
+
const componentInput = node.component.inputs[inputName];
|
446
|
+
if (!componentInput) {
|
447
|
+
logger.warn({
|
448
|
+
msg: "input not found in the component",
|
449
|
+
inputName,
|
450
|
+
component: node.component
|
451
|
+
});
|
452
|
+
return [];
|
453
|
+
}
|
454
|
+
return inputs.map((input) => ({ input, type: componentInput.type }));
|
455
|
+
}),
|
456
|
+
resolvedOutputs: node.instance.resolvedOutputs ?? {},
|
457
|
+
resolvedInjectionInputs: [],
|
458
|
+
matchedInjectionInputs: []
|
459
|
+
};
|
460
|
+
}
|
464
461
|
const resolvedInputsMap = /* @__PURE__ */ new Map();
|
465
462
|
const addInstanceResult = (inputName, input) => {
|
466
463
|
let inputs = resolvedInputsMap.get(inputName);
|
@@ -470,14 +467,28 @@ const createInputResolver = defineGraphResolver({
|
|
470
467
|
}
|
471
468
|
inputs.set(`${input.input.instanceId}:${input.input.output}`, input);
|
472
469
|
};
|
470
|
+
const addInstanceInput = (inputName, input) => {
|
471
|
+
const componentInput = node.component.inputs[inputName];
|
472
|
+
if (!componentInput) {
|
473
|
+
logger.warn({ msg: "input not found in the component", input, component: node.component });
|
474
|
+
return;
|
475
|
+
}
|
476
|
+
const { component, resolvedOutputs } = getInstanceOutput(input);
|
477
|
+
if (!component) {
|
478
|
+
logger.warn({ instanceId: node.instance.id, input }, "no output found for the input");
|
479
|
+
return;
|
480
|
+
}
|
481
|
+
if (isUnitModel(component)) {
|
482
|
+
addInstanceResult(inputName, { input, type: componentInput.type });
|
483
|
+
return;
|
484
|
+
}
|
485
|
+
for (const output of resolvedOutputs) {
|
486
|
+
addInstanceResult(inputName, { input: output, type: componentInput.type });
|
487
|
+
}
|
488
|
+
};
|
473
489
|
for (const [inputName, inputs] of Object.entries(node.instance.inputs ?? {})) {
|
474
490
|
for (const input of inputs) {
|
475
|
-
|
476
|
-
if (!componentInput) {
|
477
|
-
logger.warn({ msg: "input not found in the component", input, component: node.component });
|
478
|
-
continue;
|
479
|
-
}
|
480
|
-
addInstanceResult(inputName, { input, type: componentInput.type });
|
491
|
+
addInstanceInput(inputName, input);
|
481
492
|
}
|
482
493
|
}
|
483
494
|
const injectionInputs = /* @__PURE__ */ new Map();
|
@@ -499,7 +510,7 @@ const createInputResolver = defineGraphResolver({
|
|
499
510
|
}
|
500
511
|
for (const input of allInputs.values()) {
|
501
512
|
if (input.type === componentInput.type) {
|
502
|
-
|
513
|
+
addInstanceInput(inputName, input.input);
|
503
514
|
const key = `${input.input.instanceId}:${input.input.output}`;
|
504
515
|
if (injectionInputs.has(key)) {
|
505
516
|
matchedInjectionInputs.set(key, input);
|
@@ -517,6 +528,7 @@ const createInputResolver = defineGraphResolver({
|
|
517
528
|
kind: "instance",
|
518
529
|
component: node.component,
|
519
530
|
resolvedInputs,
|
531
|
+
resolvedOutputs: node.instance.resolvedOutputs ?? {},
|
520
532
|
resolvedInjectionInputs: Array.from(injectionInputs.values()),
|
521
533
|
matchedInjectionInputs: Array.from(matchedInjectionInputs.values())
|
522
534
|
};
|
@@ -548,6 +560,7 @@ function getMatchedInjectionInstanceInputs(output) {
|
|
548
560
|
}
|
549
561
|
|
550
562
|
const createInputHashResolver = defineGraphResolver({
|
563
|
+
name: "input-hash-resolver",
|
551
564
|
getNodeId: (node) => node.instance.id,
|
552
565
|
getNodeDependencies({ resolvedInputs }) {
|
553
566
|
const dependencies = [];
|
@@ -558,14 +571,11 @@ const createInputHashResolver = defineGraphResolver({
|
|
558
571
|
}
|
559
572
|
return dependencies;
|
560
573
|
},
|
561
|
-
async process({ instance, resolvedInputs, sourceHash, state }, dependencies) {
|
562
|
-
let sink = JSON.stringify(instance.args ?? {});
|
574
|
+
async process({ instance, component, resolvedInputs, sourceHash, state }, dependencies) {
|
575
|
+
let sink = component.definitionHash + JSON.stringify(instance.args ?? {});
|
563
576
|
if (sourceHash) {
|
564
577
|
sink += sourceHash;
|
565
578
|
}
|
566
|
-
if (state?.outputHash) {
|
567
|
-
sink += state.outputHash;
|
568
|
-
}
|
569
579
|
const sortedInputs = Object.entries(resolvedInputs).sort(([a], [b]) => a.localeCompare(b));
|
570
580
|
for (const [inputKey, inputs] of sortedInputs) {
|
571
581
|
if (Object.keys(inputs).length === 0) {
|
@@ -575,16 +585,129 @@ const createInputHashResolver = defineGraphResolver({
|
|
575
585
|
const instanceIds = inputs.map((input) => input.input.instanceId);
|
576
586
|
instanceIds.sort();
|
577
587
|
for (const instanceId of instanceIds) {
|
578
|
-
|
588
|
+
const dependency = dependencies.get(instanceId);
|
589
|
+
if (!dependency) continue;
|
590
|
+
sink += dependency.inputHash;
|
591
|
+
sink += dependency.outputHash;
|
579
592
|
}
|
580
593
|
}
|
581
|
-
return
|
594
|
+
return {
|
595
|
+
inputHash: await sha256(sink),
|
596
|
+
outputHash: state?.outputHash ?? ""
|
597
|
+
};
|
582
598
|
}
|
583
599
|
});
|
584
600
|
|
601
|
+
const createValidationResolver = defineGraphResolver({
|
602
|
+
name: "validation-resolver",
|
603
|
+
getNodeId: (node) => node.instance.id,
|
604
|
+
getNodeDependencies({ resolvedInputs }) {
|
605
|
+
const dependencies = [];
|
606
|
+
for (const inputs of Object.values(resolvedInputs)) {
|
607
|
+
for (const input of inputs) {
|
608
|
+
dependencies.push(input.input.instanceId);
|
609
|
+
}
|
610
|
+
}
|
611
|
+
return dependencies;
|
612
|
+
},
|
613
|
+
process({ instance, component, resolvedInputs }, dependencies, logger) {
|
614
|
+
const ajv = new Ajv();
|
615
|
+
logger.debug({ instanceId: instance.id }, "validating instance");
|
616
|
+
for (const [name, argument] of Object.entries(component.args)) {
|
617
|
+
if (!argument.required && !instance.args?.[name]) {
|
618
|
+
continue;
|
619
|
+
}
|
620
|
+
if (!ajv.validate(argument.schema, instance.args?.[name])) {
|
621
|
+
logger.debug({ instanceId: instance.id, argumentName: name }, "invalid argument");
|
622
|
+
return {
|
623
|
+
status: "invalid-args",
|
624
|
+
errorText: ajv.errorsText()
|
625
|
+
};
|
626
|
+
}
|
627
|
+
}
|
628
|
+
for (const inputs of Object.values(resolvedInputs)) {
|
629
|
+
for (const input of inputs) {
|
630
|
+
const inputInstance = dependencies.get(input.input.instanceId);
|
631
|
+
if (inputInstance?.status !== "ok") {
|
632
|
+
return {
|
633
|
+
status: "invalid-inputs",
|
634
|
+
errorText: `instance "${input.input.instanceId}" is invalid`
|
635
|
+
};
|
636
|
+
}
|
637
|
+
}
|
638
|
+
}
|
639
|
+
for (const [name, input] of Object.entries(component.inputs)) {
|
640
|
+
if (!input.required || input.multiple) {
|
641
|
+
continue;
|
642
|
+
}
|
643
|
+
if (!resolvedInputs[name] || !resolvedInputs[name].length) {
|
644
|
+
return {
|
645
|
+
status: "missing-inputs",
|
646
|
+
errorText: `input "${name}" is missing`
|
647
|
+
};
|
648
|
+
}
|
649
|
+
}
|
650
|
+
return { status: "ok" };
|
651
|
+
}
|
652
|
+
});
|
653
|
+
|
654
|
+
const resolverFactories = {
|
655
|
+
[createInputResolver.factoryName]: createInputResolver,
|
656
|
+
[createInputHashResolver.factoryName]: createInputHashResolver,
|
657
|
+
[createValidationResolver.factoryName]: createValidationResolver
|
658
|
+
};
|
659
|
+
|
585
660
|
const terminalSessionSchema = z.object({
|
586
|
-
id: z.string().
|
587
|
-
|
661
|
+
id: z.string().nanoid(),
|
662
|
+
projectId: z.string(),
|
663
|
+
instanceId: z.string(),
|
664
|
+
terminalName: z.string(),
|
665
|
+
terminalTitle: z.string(),
|
666
|
+
createdAt: z.coerce.date(),
|
667
|
+
finishedAt: z.coerce.date().optional()
|
588
668
|
});
|
589
669
|
|
590
|
-
|
670
|
+
function diffLibraries(oldLibrary, newLibrary) {
|
671
|
+
const updates = [];
|
672
|
+
for (const [componentType, newComponent] of Object.entries(newLibrary.components)) {
|
673
|
+
const existingComponent = oldLibrary.components[componentType];
|
674
|
+
if (existingComponent?.definitionHash !== newComponent.definitionHash) {
|
675
|
+
updates.push({ type: "component-updated", component: newComponent });
|
676
|
+
}
|
677
|
+
}
|
678
|
+
for (const componentType of Object.keys(oldLibrary.components)) {
|
679
|
+
if (!newLibrary.components[componentType]) {
|
680
|
+
updates.push({ type: "component-removed", componentType });
|
681
|
+
}
|
682
|
+
}
|
683
|
+
for (const [entityType, newEntity] of Object.entries(newLibrary.entities)) {
|
684
|
+
const existingEntity = oldLibrary.entities[entityType];
|
685
|
+
if (existingEntity?.definitionHash !== newEntity.definitionHash) {
|
686
|
+
updates.push({ type: "entity-updated", entity: newEntity });
|
687
|
+
}
|
688
|
+
}
|
689
|
+
for (const entityType of Object.keys(oldLibrary.entities)) {
|
690
|
+
if (!newLibrary.entities[entityType]) {
|
691
|
+
updates.push({ type: "entity-removed", entityType });
|
692
|
+
}
|
693
|
+
}
|
694
|
+
return updates;
|
695
|
+
}
|
696
|
+
function applyLibraryUpdate(components, entities, update) {
|
697
|
+
switch (update.type) {
|
698
|
+
case "component-updated":
|
699
|
+
components[update.component.type] = update.component;
|
700
|
+
break;
|
701
|
+
case "entity-updated":
|
702
|
+
entities[update.entity.type] = update.entity;
|
703
|
+
break;
|
704
|
+
case "component-removed":
|
705
|
+
delete components[update.componentType];
|
706
|
+
break;
|
707
|
+
case "entity-removed":
|
708
|
+
delete entities[update.entityType];
|
709
|
+
break;
|
710
|
+
}
|
711
|
+
}
|
712
|
+
|
713
|
+
export { buildDependentInstanceStateMap as A, getAllDependentInstanceIds as B, operationTypeSchema as C, operationStatusSchema as D, operationOptionsSchema as E, projectOperationRequestSchema as F, projectOperationSchema as G, isFinalOperationStatus as H, CircularDependencyError as I, createDefaultGraphResolverBackend as J, defineGraphResolver as K, resolverFactories as L, createInputResolver as M, getResolvedHubInputs as N, getResolvedInstanceInputs as O, getResolvedInjectionInstanceInputs as P, getMatchedInjectionInstanceInputs as Q, createInputHashResolver as R, createValidationResolver as S, terminalSessionSchema as T, diffLibraries as U, applyLibraryUpdate as V, instanceModelPatchSchema as a, instanceModelSchema as b, compositeInstanceSchema as c, hubModelPatchSchema as d, hubModelSchema as e, instanceStatusSchema as f, instanceStatusFieldSchema as g, hubInstanceInputSchema as h, instanceInputSchema as i, instanceFileMetaSchema as j, instanceFileSchema as k, instancePageBlockSchema as l, instancePageMetaSchema as m, instancePageSchema as n, instanceTerminalMetaSchema as o, positionSchema as p, instanceTerminalFileSchema as q, instanceTerminalSchema as r, instanceTriggerSpecSchema as s, instanceTriggerSchema as t, instanceTriggerInvocationSchema as u, instanceStateSchema as v, instanceStateUpdateSchema as w, createInstanceState as x, applyPartialInstanceState as y, createInstanceStatePatch as z };
|
@@ -0,0 +1,6 @@
|
|
1
|
+
export { I as CircularDependencyError, V as applyLibraryUpdate, y as applyPartialInstanceState, A as buildDependentInstanceStateMap, c as compositeInstanceSchema, J as createDefaultGraphResolverBackend, R as createInputHashResolver, M as createInputResolver, x as createInstanceState, z as createInstanceStatePatch, S as createValidationResolver, K as defineGraphResolver, U as diffLibraries, B as getAllDependentInstanceIds, Q as getMatchedInjectionInstanceInputs, N as getResolvedHubInputs, P as getResolvedInjectionInstanceInputs, O as getResolvedInstanceInputs, h as hubInstanceInputSchema, d as hubModelPatchSchema, e as hubModelSchema, j as instanceFileMetaSchema, k as instanceFileSchema, i as instanceInputSchema, a as instanceModelPatchSchema, b as instanceModelSchema, l as instancePageBlockSchema, m as instancePageMetaSchema, n as instancePageSchema, v as instanceStateSchema, w as instanceStateUpdateSchema, g as instanceStatusFieldSchema, f as instanceStatusSchema, q as instanceTerminalFileSchema, o as instanceTerminalMetaSchema, r as instanceTerminalSchema, u as instanceTriggerInvocationSchema, t as instanceTriggerSchema, s as instanceTriggerSpecSchema, H as isFinalOperationStatus, E as operationOptionsSchema, D as operationStatusSchema, C as operationTypeSchema, p as positionSchema, F as projectOperationRequestSchema, G as projectOperationSchema, L as resolverFactories, T as terminalSessionSchema } from '../library-BW5oPM7V.js';
|
2
|
+
import 'zod';
|
3
|
+
import 'remeda';
|
4
|
+
import '@highstate/contract';
|
5
|
+
import 'crypto-hash';
|
6
|
+
import 'ajv';
|
@@ -0,0 +1,102 @@
|
|
1
|
+
import { z } from 'zod';
|
2
|
+
|
3
|
+
async function runWithRetryOnError(runner, tryHandleError, maxRetries = 1) {
|
4
|
+
let lastError;
|
5
|
+
for (let i = 0; i < maxRetries + 1; i++) {
|
6
|
+
try {
|
7
|
+
return await runner();
|
8
|
+
} catch (e) {
|
9
|
+
lastError = e;
|
10
|
+
if (await tryHandleError(e)) {
|
11
|
+
continue;
|
12
|
+
}
|
13
|
+
throw e;
|
14
|
+
}
|
15
|
+
}
|
16
|
+
throw lastError;
|
17
|
+
}
|
18
|
+
class AbortError extends Error {
|
19
|
+
constructor(options) {
|
20
|
+
super("Operation aborted", options);
|
21
|
+
}
|
22
|
+
}
|
23
|
+
function isAbortError(error) {
|
24
|
+
return error instanceof Error && error.name === "AbortError";
|
25
|
+
}
|
26
|
+
const abortMessagePatterns = ["Operation aborted", "Command was killed with SIGINT"];
|
27
|
+
function isAbortErrorLike(error) {
|
28
|
+
if (error instanceof Error) {
|
29
|
+
return abortMessagePatterns.some((pattern) => error.message.includes(pattern));
|
30
|
+
}
|
31
|
+
return false;
|
32
|
+
}
|
33
|
+
function tryWrapAbortErrorLike(error) {
|
34
|
+
if (isAbortErrorLike(error)) {
|
35
|
+
return new AbortError({ cause: error });
|
36
|
+
}
|
37
|
+
return error;
|
38
|
+
}
|
39
|
+
const stringArrayType = z.string().transform((args) => args.split(",").map((arg) => arg.trim()));
|
40
|
+
function errorToString(error) {
|
41
|
+
if (error instanceof Error) {
|
42
|
+
return error.stack || error.message;
|
43
|
+
}
|
44
|
+
return JSON.stringify(error);
|
45
|
+
}
|
46
|
+
function createAsyncBatcher(fn, { waitMs = 100, maxWaitTimeMs = 1e3 } = {}) {
|
47
|
+
let batch = [];
|
48
|
+
let activeTimeout = null;
|
49
|
+
let maxWaitTimeout = null;
|
50
|
+
let firstCallTimestamp = null;
|
51
|
+
async function processBatch() {
|
52
|
+
if (batch.length === 0) return;
|
53
|
+
const currentBatch = batch;
|
54
|
+
batch = [];
|
55
|
+
await fn(currentBatch);
|
56
|
+
if (maxWaitTimeout) {
|
57
|
+
clearTimeout(maxWaitTimeout);
|
58
|
+
maxWaitTimeout = null;
|
59
|
+
}
|
60
|
+
firstCallTimestamp = null;
|
61
|
+
}
|
62
|
+
function schedule() {
|
63
|
+
if (activeTimeout) clearTimeout(activeTimeout);
|
64
|
+
activeTimeout = setTimeout(() => {
|
65
|
+
activeTimeout = null;
|
66
|
+
void processBatch();
|
67
|
+
}, waitMs);
|
68
|
+
if (!firstCallTimestamp) {
|
69
|
+
firstCallTimestamp = Date.now();
|
70
|
+
maxWaitTimeout = setTimeout(() => {
|
71
|
+
if (activeTimeout) clearTimeout(activeTimeout);
|
72
|
+
activeTimeout = null;
|
73
|
+
void processBatch();
|
74
|
+
}, maxWaitTimeMs);
|
75
|
+
}
|
76
|
+
}
|
77
|
+
return {
|
78
|
+
/**
|
79
|
+
* Add an item to the batch.
|
80
|
+
*/
|
81
|
+
call(item) {
|
82
|
+
batch.push(item);
|
83
|
+
schedule();
|
84
|
+
},
|
85
|
+
/**
|
86
|
+
* Immediately flush the pending batch (if any).
|
87
|
+
*/
|
88
|
+
async flush() {
|
89
|
+
if (activeTimeout) {
|
90
|
+
clearTimeout(activeTimeout);
|
91
|
+
activeTimeout = null;
|
92
|
+
}
|
93
|
+
if (maxWaitTimeout) {
|
94
|
+
clearTimeout(maxWaitTimeout);
|
95
|
+
maxWaitTimeout = null;
|
96
|
+
}
|
97
|
+
await processBatch();
|
98
|
+
}
|
99
|
+
};
|
100
|
+
}
|
101
|
+
|
102
|
+
export { AbortError as A, isAbortError as a, createAsyncBatcher as c, errorToString as e, isAbortErrorLike as i, runWithRetryOnError as r, stringArrayType as s, tryWrapAbortErrorLike as t };
|
package/package.json
CHANGED
@@ -1,36 +1,31 @@
|
|
1
1
|
{
|
2
2
|
"name": "@highstate/backend",
|
3
|
-
"version": "0.7.
|
3
|
+
"version": "0.7.3",
|
4
4
|
"type": "module",
|
5
|
-
"module": "dist/index.mjs",
|
6
|
-
"types": "dist/index.d.ts",
|
7
5
|
"files": [
|
8
|
-
"dist"
|
6
|
+
"dist",
|
7
|
+
"src"
|
9
8
|
],
|
10
9
|
"exports": {
|
11
10
|
".": {
|
12
|
-
"types": "./
|
13
|
-
"default": "./dist/index.
|
11
|
+
"types": "./src/index.ts",
|
12
|
+
"default": "./dist/index.js"
|
14
13
|
},
|
15
14
|
"./shared": {
|
16
|
-
"types": "./
|
17
|
-
"default": "./dist/shared/index.
|
15
|
+
"types": "./src/shared/index.ts",
|
16
|
+
"default": "./dist/shared/index.js"
|
18
17
|
},
|
19
|
-
"./library-worker":
|
20
|
-
|
21
|
-
},
|
22
|
-
"./source-resolution-worker": {
|
23
|
-
"default": "./dist/runner/source-resolution-worker.mjs"
|
24
|
-
}
|
18
|
+
"./library-worker": "./dist/library/worker/main.js",
|
19
|
+
"./source-resolution-worker": "./dist/library/source-resolution-worker.js"
|
25
20
|
},
|
26
21
|
"publishConfig": {
|
27
22
|
"access": "public"
|
28
23
|
},
|
29
24
|
"scripts": {
|
30
|
-
"build": "pkgroll --tsconfig=tsconfig.build.json"
|
25
|
+
"build": "pkgroll --clean --tsconfig=tsconfig.build.json"
|
31
26
|
},
|
32
27
|
"dependencies": {
|
33
|
-
"@highstate/contract": "^0.7.
|
28
|
+
"@highstate/contract": "^0.7.3",
|
34
29
|
"@types/node": "^22.10.1",
|
35
30
|
"ajv": "^8.17.1",
|
36
31
|
"better-lock": "^3.2.0",
|
@@ -44,6 +39,7 @@
|
|
44
39
|
"pino": "^9.6.0",
|
45
40
|
"pkg-types": "^1.2.1",
|
46
41
|
"remeda": "^2.21.0",
|
42
|
+
"rev-dep": "^1.5.4",
|
47
43
|
"uuidv7": "^1.0.2",
|
48
44
|
"watcher": "^2.3.1",
|
49
45
|
"zod": "^3.23.8"
|
@@ -61,12 +57,12 @@
|
|
61
57
|
}
|
62
58
|
},
|
63
59
|
"devDependencies": {
|
64
|
-
"@pulumi/pulumi": "
|
60
|
+
"@pulumi/pulumi": "patch:@pulumi/pulumi@npm%3A3.159.0#~/.yarn/patches/@pulumi-pulumi-npm-3.159.0-d07eefce5c.patch",
|
65
61
|
"classic-level": "^2.0.0",
|
66
62
|
"pino-pretty": "^13.0.0",
|
67
63
|
"pkgroll": "^2.5.1",
|
68
64
|
"rollup": "^4.28.1",
|
69
65
|
"typescript": "^5.7.2"
|
70
66
|
},
|
71
|
-
"gitHead": "
|
67
|
+
"gitHead": "5cf7cec27262c8fa1d96f6478833b94841459d64"
|
72
68
|
}
|
@@ -0,0 +1,22 @@
|
|
1
|
+
import { basename } from "node:path"
|
2
|
+
import { findWorkspaceDir, readPackageJSON } from "pkg-types"
|
3
|
+
|
4
|
+
export async function resolveMainLocalProject(
|
5
|
+
projectPath?: string,
|
6
|
+
projectName?: string,
|
7
|
+
): Promise<[projecPath: string, projectName: string]> {
|
8
|
+
if (!projectPath) {
|
9
|
+
projectPath = await findWorkspaceDir()
|
10
|
+
}
|
11
|
+
|
12
|
+
if (!projectName) {
|
13
|
+
const packageJson = await readPackageJSON(projectPath)
|
14
|
+
projectName = packageJson.name
|
15
|
+
}
|
16
|
+
|
17
|
+
if (!projectName) {
|
18
|
+
projectName = basename(projectPath)
|
19
|
+
}
|
20
|
+
|
21
|
+
return [projectPath, projectName]
|
22
|
+
}
|