@highstate/backend 0.4.5 → 0.5.0
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.d.ts
CHANGED
@@ -63,6 +63,7 @@ declare class LocalPulumiHost {
|
|
63
63
|
private passwords;
|
64
64
|
hasPassword(projectId: string): boolean;
|
65
65
|
setPassword(projectId: string, password: string): void;
|
66
|
+
removePassword(projectId: string): void;
|
66
67
|
private getPassword;
|
67
68
|
tryUnlockStack(stack: Stack, error: unknown): Promise<boolean>;
|
68
69
|
static create(logger: Logger): LocalPulumiHost;
|
@@ -209,6 +210,12 @@ interface ProjectBackend {
|
|
209
210
|
* @param projectId The ID of the project.
|
210
211
|
*/
|
211
212
|
getProject(projectId: string): Promise<ProjectModel>;
|
213
|
+
/**
|
214
|
+
* Create an empty project.
|
215
|
+
*
|
216
|
+
* @param projectId The ID of the project.
|
217
|
+
*/
|
218
|
+
createProject(projectId: string): Promise<void>;
|
212
219
|
/**
|
213
220
|
* Create the instance of the project.
|
214
221
|
*
|
package/dist/index.mjs
CHANGED
@@ -10,7 +10,7 @@ import Watcher from 'watcher';
|
|
10
10
|
import { resolve } from 'import-meta-resolve';
|
11
11
|
import { readdir, readFile, writeFile, mkdir } from 'node:fs/promises';
|
12
12
|
import { getInstanceId, isUnitModel, parseInstanceId } from '@highstate/contract';
|
13
|
-
import { h as hubModelSchema, i as instanceModelSchema, c as createInputResolver, a as createInputHashResolver, b as createInstanceState, d as instanceTerminalSchema, e as instancePageSchema, f as instanceFileSchema, g as instanceStatusFieldSchema, j as instanceTriggerSchema, k as compositeInstanceSchema, p as projectOperationSchema, l as instanceStateSchema, m as isFinalOperationStatus, t as terminalSessionSchema, n as applyPartialInstanceState, o as createInstanceStateFrontendPatch } from './terminal-
|
13
|
+
import { h as hubModelSchema, i as instanceModelSchema, c as createInputResolver, a as createInputHashResolver, b as createInstanceState, d as instanceTerminalSchema, e as instancePageSchema, f as instanceFileSchema, g as instanceStatusFieldSchema, j as instanceTriggerSchema, k as compositeInstanceSchema, p as projectOperationSchema, l as instanceStateSchema, m as isFinalOperationStatus, t as terminalSessionSchema, n as applyPartialInstanceState, o as createInstanceStateFrontendPatch } from './terminal-CkVAFPZo.mjs';
|
14
14
|
import { sha256 } from 'crypto-hash';
|
15
15
|
import 'ajv';
|
16
16
|
import { Readable, PassThrough } from 'node:stream';
|
@@ -162,6 +162,9 @@ class LocalPulumiHost {
|
|
162
162
|
setPassword(projectId, password) {
|
163
163
|
this.passwords.set(projectId, password);
|
164
164
|
}
|
165
|
+
removePassword(projectId) {
|
166
|
+
this.passwords.delete(projectId);
|
167
|
+
}
|
165
168
|
getPassword(projectId) {
|
166
169
|
return this.sharedPassword || this.passwords.get(projectId) || "";
|
167
170
|
}
|
@@ -253,7 +256,7 @@ class LocalSecretBackend {
|
|
253
256
|
projectId,
|
254
257
|
() => this.projectPath,
|
255
258
|
async (stack) => {
|
256
|
-
this.logger.debug("checking password"
|
259
|
+
this.logger.debug({ projectId }, "checking password");
|
257
260
|
await stack.info(true);
|
258
261
|
}
|
259
262
|
);
|
@@ -261,6 +264,8 @@ class LocalSecretBackend {
|
|
261
264
|
} catch (error) {
|
262
265
|
if (error instanceof Error) {
|
263
266
|
if (error.message.includes("incorrect passphrase")) {
|
267
|
+
this.logger.debug({ projectId, error }, "incorrect passphrase");
|
268
|
+
this.pulumiProjectHost.removePassword(projectId);
|
264
269
|
return false;
|
265
270
|
}
|
266
271
|
}
|
@@ -274,7 +279,7 @@ class LocalSecretBackend {
|
|
274
279
|
projectId,
|
275
280
|
() => this.projectPath,
|
276
281
|
async (stack) => {
|
277
|
-
this.logger.debug(
|
282
|
+
this.logger.debug({ projectId, instanceId }, "getting secrets");
|
278
283
|
const config = await stack.getAllConfig();
|
279
284
|
const prefix = this.getPrefix(projectId, instanceId);
|
280
285
|
const secrets = pickBy(config, (_, key) => key.startsWith(prefix));
|
@@ -290,7 +295,7 @@ class LocalSecretBackend {
|
|
290
295
|
projectId,
|
291
296
|
() => this.projectPath,
|
292
297
|
async (stack) => {
|
293
|
-
this.logger.debug(
|
298
|
+
this.logger.debug({ projectId, instanceId }, "setting secrets");
|
294
299
|
const componentSecrets = mapValues(
|
295
300
|
mapKeys(values, (key) => `${this.getPrefix(projectId, instanceId)}${key}`),
|
296
301
|
(value) => ({
|
@@ -305,7 +310,7 @@ class LocalSecretBackend {
|
|
305
310
|
);
|
306
311
|
}
|
307
312
|
getPrefix(projectId, instanceId) {
|
308
|
-
instanceId = instanceId.replace(/:/g, "
|
313
|
+
instanceId = instanceId.replace(/:/g, "_");
|
309
314
|
return `${this.projectName}:${projectId}/${instanceId}/`;
|
310
315
|
}
|
311
316
|
static async create(config, pulumiProjectHost, logger) {
|
@@ -484,6 +489,15 @@ class LocalProjectBackend {
|
|
484
489
|
throw new Error("Failed to get project instances", { cause: error });
|
485
490
|
}
|
486
491
|
}
|
492
|
+
async createProject(projectId) {
|
493
|
+
try {
|
494
|
+
await this.withProject(projectId, () => {
|
495
|
+
return { instances: {}, hubs: {} };
|
496
|
+
});
|
497
|
+
} catch (error) {
|
498
|
+
throw new Error("Failed to create project", { cause: error });
|
499
|
+
}
|
500
|
+
}
|
487
501
|
async createInstance(projectId, instance) {
|
488
502
|
try {
|
489
503
|
return await this.withProject(projectId, (project) => {
|
@@ -1209,7 +1223,7 @@ class LocalRunnerBackend {
|
|
1209
1223
|
return this.pulumiProjectHost.runEmpty(
|
1210
1224
|
options.projectId,
|
1211
1225
|
options.instanceType,
|
1212
|
-
options
|
1226
|
+
LocalRunnerBackend.getStackName(options),
|
1213
1227
|
async (stack) => {
|
1214
1228
|
const info = await stack.info();
|
1215
1229
|
const instanceId = getInstanceId(options.instanceType, options.instanceName);
|
@@ -1238,7 +1252,7 @@ class LocalRunnerBackend {
|
|
1238
1252
|
return this.pulumiProjectHost.runEmpty(
|
1239
1253
|
options.projectId,
|
1240
1254
|
options.instanceType,
|
1241
|
-
options
|
1255
|
+
LocalRunnerBackend.getStackName(options),
|
1242
1256
|
async (stack) => {
|
1243
1257
|
const outputs = await stack.outputs();
|
1244
1258
|
if (!outputs["$terminals"]) {
|
@@ -1257,7 +1271,7 @@ class LocalRunnerBackend {
|
|
1257
1271
|
return this.pulumiProjectHost.runEmpty(
|
1258
1272
|
options.projectId,
|
1259
1273
|
options.instanceType,
|
1260
|
-
options
|
1274
|
+
LocalRunnerBackend.getStackName(options),
|
1261
1275
|
async (stack) => {
|
1262
1276
|
const outputs = await stack.outputs();
|
1263
1277
|
if (!outputs["$pages"]) {
|
@@ -1276,7 +1290,7 @@ class LocalRunnerBackend {
|
|
1276
1290
|
return this.pulumiProjectHost.runEmpty(
|
1277
1291
|
options.projectId,
|
1278
1292
|
options.instanceType,
|
1279
|
-
options
|
1293
|
+
LocalRunnerBackend.getStackName(options),
|
1280
1294
|
async (stack) => {
|
1281
1295
|
const outputs = await stack.outputs();
|
1282
1296
|
if (!outputs["$files"]) {
|
@@ -1313,7 +1327,7 @@ class LocalRunnerBackend {
|
|
1313
1327
|
await this.pulumiProjectHost.runLocal(
|
1314
1328
|
options.projectId,
|
1315
1329
|
options.instanceType,
|
1316
|
-
options
|
1330
|
+
LocalRunnerBackend.getStackName(options),
|
1317
1331
|
() => this.resolveProjectPath(options.source),
|
1318
1332
|
async (stack) => {
|
1319
1333
|
await stack.setAllConfig(configMap);
|
@@ -1400,7 +1414,7 @@ class LocalRunnerBackend {
|
|
1400
1414
|
await this.pulumiProjectHost.runEmpty(
|
1401
1415
|
options.projectId,
|
1402
1416
|
options.instanceType,
|
1403
|
-
options
|
1417
|
+
LocalRunnerBackend.getStackName(options),
|
1404
1418
|
async (stack) => {
|
1405
1419
|
const summary = await stack.workspace.stack();
|
1406
1420
|
let currentResourceCount = summary?.resourceCount ?? 0;
|
@@ -1470,7 +1484,7 @@ class LocalRunnerBackend {
|
|
1470
1484
|
await this.pulumiProjectHost.runEmpty(
|
1471
1485
|
options.projectId,
|
1472
1486
|
options.instanceType,
|
1473
|
-
options
|
1487
|
+
LocalRunnerBackend.getStackName(options),
|
1474
1488
|
async (stack) => {
|
1475
1489
|
const summary = await stack.workspace.stack();
|
1476
1490
|
let currentResourceCount = 0;
|
@@ -1622,6 +1636,9 @@ class LocalRunnerBackend {
|
|
1622
1636
|
await ensureDependencyInstalled(packageName);
|
1623
1637
|
return true;
|
1624
1638
|
}
|
1639
|
+
static getStackName(options) {
|
1640
|
+
return `${options.projectId}_${options.instanceName}`;
|
1641
|
+
}
|
1625
1642
|
static async create(config, pulumiProjectHost) {
|
1626
1643
|
let sourceBasePath = config.HIGHSTATE_BACKEND_RUNNER_LOCAL_SOURCE_BASE_PATH;
|
1627
1644
|
if (!sourceBasePath) {
|
@@ -2071,6 +2088,9 @@ class RuntimeOperation {
|
|
2071
2088
|
childrenStateMap = /* @__PURE__ */ new Map();
|
2072
2089
|
dependentStateMap = /* @__PURE__ */ new Map();
|
2073
2090
|
library;
|
2091
|
+
inputHashLock = new BetterLock();
|
2092
|
+
inputHashPromiseCache = /* @__PURE__ */ new Map();
|
2093
|
+
inputHashNodes = /* @__PURE__ */ new Map();
|
2074
2094
|
resolveInputHash;
|
2075
2095
|
async operateSafe() {
|
2076
2096
|
try {
|
@@ -2156,9 +2176,8 @@ class RuntimeOperation {
|
|
2156
2176
|
this.tryAddStateToParent(state);
|
2157
2177
|
this.addDependentState(state);
|
2158
2178
|
}
|
2159
|
-
const inputHashNodes = /* @__PURE__ */ new Map();
|
2160
2179
|
for (const instance of allInstances) {
|
2161
|
-
inputHashNodes.set(instance.id, {
|
2180
|
+
this.inputHashNodes.set(instance.id, {
|
2162
2181
|
instance,
|
2163
2182
|
resolvedInputs: this.resolvedInstanceInputs.get(instance.id),
|
2164
2183
|
state: this.stateMap.get(instance.id),
|
@@ -2167,8 +2186,9 @@ class RuntimeOperation {
|
|
2167
2186
|
});
|
2168
2187
|
}
|
2169
2188
|
this.resolveInputHash = createInputHashResolver(
|
2170
|
-
inputHashNodes,
|
2171
|
-
this.logger.child({ resolver: "input-hash-resolver" })
|
2189
|
+
this.inputHashNodes,
|
2190
|
+
this.logger.child({ resolver: "input-hash-resolver" }),
|
2191
|
+
{ promiseCache: this.inputHashPromiseCache }
|
2172
2192
|
);
|
2173
2193
|
if (this.operation.type === "update") {
|
2174
2194
|
await this.extendWithNotCreatedDependencies();
|
@@ -2325,7 +2345,17 @@ class RuntimeOperation {
|
|
2325
2345
|
finalStatuses: ["created", "error"]
|
2326
2346
|
});
|
2327
2347
|
await this.watchStateStream(stream);
|
2328
|
-
const inputHash = await this.
|
2348
|
+
const inputHash = await this.inputHashLock.acquire(async () => {
|
2349
|
+
this.inputHashNodes.set(instance.id, {
|
2350
|
+
instance,
|
2351
|
+
resolvedInputs: this.resolvedInstanceInputs.get(instance.id),
|
2352
|
+
state: this.stateMap.get(instance.id),
|
2353
|
+
sourceHash: void 0
|
2354
|
+
// TODO: implement source hash
|
2355
|
+
});
|
2356
|
+
this.inputHashPromiseCache.clear();
|
2357
|
+
return await this.resolveInputHash(instance.id);
|
2358
|
+
});
|
2329
2359
|
this.updateInstanceState({ id: instance.id, inputHash });
|
2330
2360
|
logger.debug("input hash after update", { inputHash });
|
2331
2361
|
logger.info("unit updated");
|
package/dist/shared/index.d.ts
CHANGED
@@ -11,8 +11,8 @@ type GraphResolverOptions<TNode, TOutput> = {
|
|
11
11
|
};
|
12
12
|
interface GraphResolverBackend<TOutput> {
|
13
13
|
promiseCache: Map<string, Promise<TOutput>>;
|
14
|
-
setOutput(id: string, value: TOutput): void;
|
15
|
-
setDependencies(id: string, dependencies: string[]): void;
|
14
|
+
setOutput?(id: string, value: TOutput): void;
|
15
|
+
setDependencies?(id: string, dependencies: string[]): void;
|
16
16
|
}
|
17
17
|
type GraphResolverFactory<TNode, TOutput> = (nodes: ReadonlyMap<string, TNode>, logger: Logger, backend?: GraphResolverBackend<TOutput>) => GraphResolver<TOutput>;
|
18
18
|
type GraphResolver<TOutput> = (id: string) => Promise<TOutput>;
|
package/dist/shared/index.mjs
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
import { q as defineGraphResolver } from '../terminal-
|
2
|
-
export { J as CircularDependencyError, n as applyPartialInstanceState, k as compositeInstanceSchema, K as createDefaultGraphResolverBackend, a as createInputHashResolver, c as createInputResolver, b as createInstanceState, o as createInstanceStateFrontendPatch, O as getMatchedInjectionInstanceInputs, L as getResolvedHubInputs, N as getResolvedInjectionInstanceInputs, M as getResolvedInstanceInputs, u as hubInstanceInputSchema, w as hubModelPatchSchema, h as hubModelSchema, y as instanceFileMetaSchema, f as instanceFileSchema, s as instanceInputSchema, v as instanceModelPatchSchema, i as instanceModelSchema, z as instancePageBlockSchema, A as instancePageMetaSchema, e as instancePageSchema, F as instanceStatePatchSchema, l as instanceStateSchema, g as instanceStatusFieldSchema, x as instanceStatusSchema, C as instanceTerminalFileSchema, B as instanceTerminalMetaSchema, d as instanceTerminalSchema, E as instanceTriggerInvocationSchema, j as instanceTriggerSchema, D as instanceTriggerSpecSchema, m as isFinalOperationStatus, H as operationStatusSchema, G as operationTypeSchema, r as positionSchema, I as projectOperationRequestSchema, p as projectOperationSchema, t as terminalSessionSchema } from '../terminal-
|
1
|
+
import { q as defineGraphResolver } from '../terminal-CkVAFPZo.mjs';
|
2
|
+
export { J as CircularDependencyError, n as applyPartialInstanceState, k as compositeInstanceSchema, K as createDefaultGraphResolverBackend, a as createInputHashResolver, c as createInputResolver, b as createInstanceState, o as createInstanceStateFrontendPatch, O as getMatchedInjectionInstanceInputs, L as getResolvedHubInputs, N as getResolvedInjectionInstanceInputs, M as getResolvedInstanceInputs, u as hubInstanceInputSchema, w as hubModelPatchSchema, h as hubModelSchema, y as instanceFileMetaSchema, f as instanceFileSchema, s as instanceInputSchema, v as instanceModelPatchSchema, i as instanceModelSchema, z as instancePageBlockSchema, A as instancePageMetaSchema, e as instancePageSchema, F as instanceStatePatchSchema, l as instanceStateSchema, g as instanceStatusFieldSchema, x as instanceStatusSchema, C as instanceTerminalFileSchema, B as instanceTerminalMetaSchema, d as instanceTerminalSchema, E as instanceTriggerInvocationSchema, j as instanceTriggerSchema, D as instanceTriggerSpecSchema, m as isFinalOperationStatus, H as operationStatusSchema, G as operationTypeSchema, r as positionSchema, I as projectOperationRequestSchema, p as projectOperationSchema, t as terminalSessionSchema } from '../terminal-CkVAFPZo.mjs';
|
3
3
|
import { Ajv } from 'ajv';
|
4
4
|
import 'zod';
|
5
5
|
import 'remeda';
|
@@ -259,11 +259,7 @@ class CircularDependencyError extends Error {
|
|
259
259
|
function createDefaultGraphResolverBackend() {
|
260
260
|
const promiseCache = /* @__PURE__ */ new Map();
|
261
261
|
return {
|
262
|
-
promiseCache
|
263
|
-
setOutput() {
|
264
|
-
},
|
265
|
-
setDependencies() {
|
266
|
-
}
|
262
|
+
promiseCache
|
267
263
|
};
|
268
264
|
}
|
269
265
|
function defineGraphResolver(options) {
|
@@ -284,7 +280,7 @@ function defineGraphResolver(options) {
|
|
284
280
|
}
|
285
281
|
const resolve = async () => {
|
286
282
|
const dependencies = unique(options.getNodeDependencies(item));
|
287
|
-
backend.setDependencies(itemId, dependencies);
|
283
|
+
backend.setDependencies?.(itemId, dependencies);
|
288
284
|
logger.trace({ itemId, dependencies }, "resolving item dependencies");
|
289
285
|
const resolvedDependencies = /* @__PURE__ */ new Map();
|
290
286
|
const newChain = [...dependencyChain, itemId];
|
@@ -298,7 +294,7 @@ function defineGraphResolver(options) {
|
|
298
294
|
};
|
299
295
|
const promise = resolve().then((result) => {
|
300
296
|
if (backend.promiseCache.get(itemId) === promise) {
|
301
|
-
backend.setOutput(itemId, result);
|
297
|
+
backend.setOutput?.(itemId, result);
|
302
298
|
}
|
303
299
|
return result;
|
304
300
|
});
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@highstate/backend",
|
3
|
-
"version": "0.
|
3
|
+
"version": "0.5.0",
|
4
4
|
"type": "module",
|
5
5
|
"module": "dist/index.mjs",
|
6
6
|
"types": "dist/index.d.ts",
|
@@ -27,7 +27,7 @@
|
|
27
27
|
"build": "pkgroll --tsconfig=tsconfig.build.json"
|
28
28
|
},
|
29
29
|
"dependencies": {
|
30
|
-
"@highstate/contract": "^0.
|
30
|
+
"@highstate/contract": "^0.5.0",
|
31
31
|
"@types/node": "^22.10.1",
|
32
32
|
"ajv": "^8.17.1",
|
33
33
|
"better-lock": "^3.2.0",
|
@@ -65,5 +65,5 @@
|
|
65
65
|
"rollup": "^4.28.1",
|
66
66
|
"typescript": "^5.7.2"
|
67
67
|
},
|
68
|
-
"gitHead": "
|
68
|
+
"gitHead": "9ab4fc8f01c56df2c9ddf39eda57a3e00a2d17a8"
|
69
69
|
}
|