@usine/orchestrator 0.1.0 → 0.2.1
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/README.md +46 -21
- package/dist/board/items.d.ts +18 -0
- package/dist/board/items.d.ts.map +1 -0
- package/dist/board/items.js +46 -0
- package/dist/board/items.js.map +1 -0
- package/dist/board/projection.d.ts +6 -5
- package/dist/board/projection.d.ts.map +1 -1
- package/dist/board/projection.js +25 -65
- package/dist/board/projection.js.map +1 -1
- package/dist/board/tasks.d.ts +8 -0
- package/dist/board/tasks.d.ts.map +1 -0
- package/dist/board/tasks.js +86 -0
- package/dist/board/tasks.js.map +1 -0
- package/dist/credentials.d.ts +6 -6
- package/dist/credentials.d.ts.map +1 -1
- package/dist/credentials.js +6 -6
- package/dist/credentials.js.map +1 -1
- package/dist/exe-dev.d.ts +5 -4
- package/dist/exe-dev.d.ts.map +1 -1
- package/dist/exe-dev.js +5 -4
- package/dist/exe-dev.js.map +1 -1
- package/dist/idle-triggers.d.ts +1 -1
- package/dist/idle-triggers.d.ts.map +1 -1
- package/dist/idle-triggers.js +3 -1
- package/dist/idle-triggers.js.map +1 -1
- package/dist/label-reconciler.d.ts +30 -0
- package/dist/label-reconciler.d.ts.map +1 -0
- package/dist/label-reconciler.js +119 -0
- package/dist/label-reconciler.js.map +1 -0
- package/dist/local.d.ts +17 -12
- package/dist/local.d.ts.map +1 -1
- package/dist/local.js +20 -13
- package/dist/local.js.map +1 -1
- package/dist/operator/attempt.d.ts +69 -0
- package/dist/operator/attempt.d.ts.map +1 -0
- package/dist/operator/attempt.js +62 -0
- package/dist/operator/attempt.js.map +1 -0
- package/dist/operator/board.d.ts +119 -0
- package/dist/operator/board.d.ts.map +1 -0
- package/dist/operator/board.js +101 -0
- package/dist/operator/board.js.map +1 -0
- package/dist/operator/http.d.ts +180 -0
- package/dist/operator/http.d.ts.map +1 -0
- package/dist/operator/http.js +150 -0
- package/dist/operator/http.js.map +1 -0
- package/dist/operator/need.d.ts +66 -0
- package/dist/operator/need.d.ts.map +1 -0
- package/dist/operator/need.js +70 -0
- package/dist/operator/need.js.map +1 -0
- package/dist/operator/operator.d.ts +68 -0
- package/dist/operator/operator.d.ts.map +1 -0
- package/dist/operator/operator.js +402 -0
- package/dist/operator/operator.js.map +1 -0
- package/dist/operator/overview.d.ts +51 -0
- package/dist/operator/overview.d.ts.map +1 -0
- package/dist/operator/overview.js +48 -0
- package/dist/operator/overview.js.map +1 -0
- package/dist/operator/projection.d.ts +12 -9
- package/dist/operator/projection.d.ts.map +1 -1
- package/dist/operator/projection.js +44 -17
- package/dist/operator/projection.js.map +1 -1
- package/dist/operator/run.d.ts +62 -0
- package/dist/operator/run.d.ts.map +1 -0
- package/dist/operator/run.js +61 -0
- package/dist/operator/run.js.map +1 -0
- package/dist/operator/transcript.d.ts +59 -0
- package/dist/operator/transcript.d.ts.map +1 -0
- package/dist/operator/transcript.js +66 -0
- package/dist/operator/transcript.js.map +1 -0
- package/dist/orchestrator.d.ts +3 -2
- package/dist/orchestrator.d.ts.map +1 -1
- package/dist/orchestrator.js +1 -1
- package/dist/orchestrator.js.map +1 -1
- package/dist/polling/cycle.d.ts +51 -0
- package/dist/polling/cycle.d.ts.map +1 -0
- package/dist/polling/cycle.js +44 -0
- package/dist/polling/cycle.js.map +1 -0
- package/dist/polling/hints.d.ts +20 -0
- package/dist/polling/hints.d.ts.map +1 -0
- package/dist/polling/hints.js +54 -0
- package/dist/polling/hints.js.map +1 -0
- package/dist/polling/loop-evaluation.d.ts +21 -0
- package/dist/polling/loop-evaluation.d.ts.map +1 -0
- package/dist/polling/loop-evaluation.js +131 -0
- package/dist/polling/loop-evaluation.js.map +1 -0
- package/dist/polling/polling.d.ts +36 -0
- package/dist/polling/polling.d.ts.map +1 -0
- package/dist/polling/polling.js +296 -0
- package/dist/polling/polling.js.map +1 -0
- package/dist/polling/repository-sync.d.ts +45 -0
- package/dist/polling/repository-sync.d.ts.map +1 -0
- package/dist/polling/repository-sync.js +169 -0
- package/dist/polling/repository-sync.js.map +1 -0
- package/dist/polling-triggers.d.ts +3 -39
- package/dist/polling-triggers.d.ts.map +1 -1
- package/dist/polling-triggers.js +3 -393
- package/dist/polling-triggers.js.map +1 -1
- package/dist/schedule-triggers.d.ts +17 -15
- package/dist/schedule-triggers.d.ts.map +1 -1
- package/dist/schedule-triggers.js +53 -43
- package/dist/schedule-triggers.js.map +1 -1
- package/dist/scheduler.d.ts +5 -5
- package/dist/scheduler.d.ts.map +1 -1
- package/dist/scheduler.js +30 -44
- package/dist/scheduler.js.map +1 -1
- package/dist/trigger-submission.d.ts +33 -24
- package/dist/trigger-submission.d.ts.map +1 -1
- package/dist/trigger-submission.js +30 -37
- package/dist/trigger-submission.js.map +1 -1
- package/package.json +50 -14
- package/dist/index.d.ts +0 -11
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -11
- package/dist/index.js.map +0 -1
- package/dist/operator/model.d.ts +0 -280
- package/dist/operator/model.d.ts.map +0 -1
- package/dist/operator/model.js +0 -242
- package/dist/operator/model.js.map +0 -1
- package/dist/operator/service.d.ts +0 -36
- package/dist/operator/service.d.ts.map +0 -1
- package/dist/operator/service.js +0 -248
- package/dist/operator/service.js.map +0 -1
package/dist/orchestrator.d.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import type { LoadedInstance } from "@usine/config";
|
|
1
|
+
import type { LoadedInstance } from "@usine/config/instance";
|
|
2
2
|
import { Context, Effect, Layer } from "effect";
|
|
3
3
|
import { PollingTriggers } from "./polling-triggers.ts";
|
|
4
4
|
import { ScheduleTriggers } from "./schedule-triggers.ts";
|
|
5
5
|
declare const Orchestrator_base: Context.ServiceClass<Orchestrator, "@usine/orchestrator/Orchestrator", {
|
|
6
|
+
/** Evaluates the supplied instance's triggers until interrupted, using that snapshot of its Loops and roster. */
|
|
6
7
|
readonly run: (instance: LoadedInstance) => Effect.Effect<never>;
|
|
7
8
|
}>;
|
|
8
|
-
/**
|
|
9
|
+
/** Coordinates polling and schedule triggers for one loaded factory instance. */
|
|
9
10
|
export declare class Orchestrator extends Orchestrator_base {
|
|
10
11
|
static readonly layer: Layer.Layer<Orchestrator, never, PollingTriggers | ScheduleTriggers>;
|
|
11
12
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"orchestrator.d.ts","sourceRoot":"","sources":["../src/orchestrator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"orchestrator.d.ts","sourceRoot":"","sources":["../src/orchestrator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAChD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;;IAgBtD,iHAAiH;kBACnG,CAAC,QAAQ,EAAE,cAAc,KAAK,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC;;AALpE,iFAAiF;AACjF,qBAAa,YAAa,SAAQ,iBAMK;IACrC,MAAM,CAAC,QAAQ,CAAC,KAAK,uEAAgD;CACtE"}
|
package/dist/orchestrator.js
CHANGED
|
@@ -7,7 +7,7 @@ const makeOrchestrator = Effect.gen(function* () {
|
|
|
7
7
|
const run = (instance) => Effect.raceFirst(polling.run(instance), schedules.run(instance));
|
|
8
8
|
return { run };
|
|
9
9
|
});
|
|
10
|
-
/**
|
|
10
|
+
/** Coordinates polling and schedule triggers for one loaded factory instance. */
|
|
11
11
|
export class Orchestrator extends Context.Service()("@usine/orchestrator/Orchestrator") {
|
|
12
12
|
static layer = Layer.effect(Orchestrator, makeOrchestrator);
|
|
13
13
|
}
|
package/dist/orchestrator.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"orchestrator.js","sourceRoot":"","sources":["../src/orchestrator.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAChD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE1D,MAAM,gBAAgB,GAAG,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IAC3C,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,eAAe,CAAC;IACvC,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,gBAAgB,CAAC;IAE1C,MAAM,GAAG,GAAG,CAAC,QAAwB,EAAwB,EAAE,CAC7D,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC;IAEnE,OAAO,EAAE,GAAG,EAAW,CAAC;AAC1B,CAAC,CAAC,CAAC;AAEH,
|
|
1
|
+
{"version":3,"file":"orchestrator.js","sourceRoot":"","sources":["../src/orchestrator.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAChD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE1D,MAAM,gBAAgB,GAAG,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IAC3C,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,eAAe,CAAC;IACvC,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,gBAAgB,CAAC;IAE1C,MAAM,GAAG,GAAG,CAAC,QAAwB,EAAwB,EAAE,CAC7D,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC;IAEnE,OAAO,EAAE,GAAG,EAAW,CAAC;AAC1B,CAAC,CAAC,CAAC;AAEH,iFAAiF;AACjF,MAAM,OAAO,YAAa,SAAQ,OAAO,CAAC,OAAO,EAM9C,CAAC,kCAAkC,CAAC;IACrC,MAAM,CAAU,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,YAAY,EAAE,gBAAgB,CAAC,CAAC;CACtE"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { ConfigFileError } from "@usine/config/file";
|
|
2
|
+
import { type RunEngineError } from "@usine/engine/engine";
|
|
3
|
+
import type { ExpressionError } from "@usine/expression/expression-engine";
|
|
4
|
+
import type { GitHubAppError } from "@usine/github/github-app";
|
|
5
|
+
import { DateTime, Option, Schema } from "effect";
|
|
6
|
+
import { LabelPreflightFinding } from "../label-reconciler.ts";
|
|
7
|
+
declare const RepositoryPollFailure_base: Schema.Class<RepositoryPollFailure, Schema.Struct<{
|
|
8
|
+
readonly repository: Schema.brand<Schema.String, "RepositoryName">;
|
|
9
|
+
readonly errorTag: Schema.NonEmptyString;
|
|
10
|
+
readonly message: Schema.String;
|
|
11
|
+
}>, {}>;
|
|
12
|
+
/** One repository whose cycle failed; its siblings finished normally. */
|
|
13
|
+
export declare class RepositoryPollFailure extends RepositoryPollFailure_base {
|
|
14
|
+
}
|
|
15
|
+
declare const PollCycle_base: Schema.Class<PollCycle, Schema.Struct<{
|
|
16
|
+
readonly repositories: Schema.Int;
|
|
17
|
+
readonly changedItems: Schema.Int;
|
|
18
|
+
readonly submissions: Schema.$Array<Schema.Union<readonly [typeof import("@usine/engine/engine").Claimed, typeof import("@usine/engine/engine").Queued, typeof import("@usine/engine/engine").Ignored, typeof import("@usine/engine/engine").CycleBlocked]>>;
|
|
19
|
+
/** How many Runs this cycle revoked because their item stopped matching. */
|
|
20
|
+
readonly revokedRuns: Schema.Int;
|
|
21
|
+
readonly failures: Schema.$Array<typeof RepositoryPollFailure>;
|
|
22
|
+
readonly preflightFindings: Schema.$Array<typeof LabelPreflightFinding>;
|
|
23
|
+
readonly nextPollAt: Schema.Option<Schema.DateTimeUtc>;
|
|
24
|
+
}>, {}>;
|
|
25
|
+
/** Outcomes of one poll over all managed repositories, including isolated failures and backoff. */
|
|
26
|
+
export declare class PollCycle extends PollCycle_base {
|
|
27
|
+
}
|
|
28
|
+
/** Recoverable failures that leave a repository eligible for another poll. */
|
|
29
|
+
export type RepositoryPollError = ConfigFileError | ExpressionError | GitHubAppError | RunEngineError;
|
|
30
|
+
/** Safe diagnostic fields for a failed repository operation. */
|
|
31
|
+
export declare const repositoryFailureLogFields: (error: RepositoryPollError) => {
|
|
32
|
+
errorTag: "AppPermissionError" | "AttemptCancellationError" | "ConfigFileError" | "EnginePersistenceError" | "ExpressionCheckError" | "ExpressionEvaluationError" | "GitHubApiError" | "GitHubRateLimitError" | "InstallationDiscoveryError" | "InvalidGitHubResponseError" | "RunInterventionRejectedError" | "RunNotFoundError" | "RunOperationRejectedError";
|
|
33
|
+
message: string;
|
|
34
|
+
} | {
|
|
35
|
+
errorTag: "AppPermissionError" | "AttemptCancellationError" | "ConfigFileError" | "EnginePersistenceError" | "ExpressionCheckError" | "ExpressionEvaluationError" | "GitHubApiError" | "GitHubRateLimitError" | "InstallationDiscoveryError" | "InvalidGitHubResponseError" | "RunInterventionRejectedError" | "RunNotFoundError" | "RunOperationRejectedError";
|
|
36
|
+
message: string;
|
|
37
|
+
expression: string & import("effect/Brand").Brand<"ExpressionSource">;
|
|
38
|
+
};
|
|
39
|
+
/** A cycle whose preflight finished but whose repository poll failed. */
|
|
40
|
+
export interface InterruptedRepositoryCycle {
|
|
41
|
+
readonly _tag: "InterruptedRepositoryCycle";
|
|
42
|
+
readonly error: RepositoryPollError;
|
|
43
|
+
/** Preflight failures such as a failed catalog request, kept through the interruption. */
|
|
44
|
+
readonly failures: ReadonlyArray<RepositoryPollFailure>;
|
|
45
|
+
readonly preflightFindings: ReadonlyArray<LabelPreflightFinding>;
|
|
46
|
+
readonly nextPollAt: Option.Option<DateTime.Utc>;
|
|
47
|
+
}
|
|
48
|
+
/** The latest requested backoff; no recommendation leaves the configured interval in charge. */
|
|
49
|
+
export declare const latestPollAt: (values: ReadonlyArray<Option.Option<DateTime.Utc>>) => Option.Option<DateTime.Utc>;
|
|
50
|
+
export {};
|
|
51
|
+
//# sourceMappingURL=cycle.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cycle.d.ts","sourceRoot":"","sources":["../../src/polling/cycle.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAE1D,OAAO,EAAE,KAAK,cAAc,EAAoB,MAAM,sBAAsB,CAAC;AAC7E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qCAAqC,CAAC;AAC3E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAClD,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;;;;;;AAG/D,yEAAyE;AACzE,qBAAa,qBAAsB,SAAQ,0BAMzC;CAAG;;;;;IAOH,4EAA4E;;;;;;AAL9E,mGAAmG;AACnG,qBAAa,SAAU,SAAQ,cAS7B;CAAG;AAEL,8EAA8E;AAC9E,MAAM,MAAM,mBAAmB,GAC3B,eAAe,GACf,eAAe,GACf,cAAc,GACd,cAAc,CAAC;AAEnB,gEAAgE;AAChE,eAAO,MAAM,0BAA0B,UAAW,mBAAmB;;;;;;;CASpE,CAAC;AAEF,yEAAyE;AACzE,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,IAAI,EAAE,4BAA4B,CAAC;IAC5C,QAAQ,CAAC,KAAK,EAAE,mBAAmB,CAAC;IACpC,0FAA0F;IAC1F,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC,qBAAqB,CAAC,CAAC;IACxD,QAAQ,CAAC,iBAAiB,EAAE,aAAa,CAAC,qBAAqB,CAAC,CAAC;IACjE,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;CAClD;AAED,gGAAgG;AAChG,eAAO,MAAM,YAAY,WACf,aAAa,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,KACjD,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAQ5B,CAAC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { RepositoryName } from "@usine/core/repository";
|
|
2
|
+
import { SubmissionResult } from "@usine/engine/engine";
|
|
3
|
+
import { DateTime, Option, Schema } from "effect";
|
|
4
|
+
import { LabelPreflightFinding } from "../label-reconciler.js";
|
|
5
|
+
import { configFileErrorLogFields } from "../trigger-submission.js";
|
|
6
|
+
/** One repository whose cycle failed; its siblings finished normally. */
|
|
7
|
+
export class RepositoryPollFailure extends Schema.Class("@usine/orchestrator/RepositoryPollFailure")({
|
|
8
|
+
repository: RepositoryName,
|
|
9
|
+
errorTag: Schema.NonEmptyString,
|
|
10
|
+
message: Schema.String,
|
|
11
|
+
}) {
|
|
12
|
+
}
|
|
13
|
+
/** Outcomes of one poll over all managed repositories, including isolated failures and backoff. */
|
|
14
|
+
export class PollCycle extends Schema.Class("@usine/orchestrator/PollCycle")({
|
|
15
|
+
repositories: Schema.Int.check(Schema.isGreaterThanOrEqualTo(0)),
|
|
16
|
+
changedItems: Schema.Int.check(Schema.isGreaterThanOrEqualTo(0)),
|
|
17
|
+
submissions: Schema.Array(SubmissionResult),
|
|
18
|
+
/** How many Runs this cycle revoked because their item stopped matching. */
|
|
19
|
+
revokedRuns: Schema.Int.check(Schema.isGreaterThanOrEqualTo(0)),
|
|
20
|
+
failures: Schema.Array(RepositoryPollFailure),
|
|
21
|
+
preflightFindings: Schema.Array(LabelPreflightFinding),
|
|
22
|
+
nextPollAt: Schema.Option(Schema.DateTimeUtc),
|
|
23
|
+
}) {
|
|
24
|
+
}
|
|
25
|
+
/** Safe diagnostic fields for a failed repository operation. */
|
|
26
|
+
export const repositoryFailureLogFields = (error) => {
|
|
27
|
+
const common = { errorTag: error._tag, message: error.message };
|
|
28
|
+
if (error._tag === "ConfigFileError") {
|
|
29
|
+
return { ...common, ...configFileErrorLogFields(error) };
|
|
30
|
+
}
|
|
31
|
+
if (error._tag === "ExpressionCheckError" || error._tag === "ExpressionEvaluationError") {
|
|
32
|
+
return { ...common, expression: error.source };
|
|
33
|
+
}
|
|
34
|
+
return common;
|
|
35
|
+
};
|
|
36
|
+
/** The latest requested backoff; no recommendation leaves the configured interval in charge. */
|
|
37
|
+
export const latestPollAt = (values) => {
|
|
38
|
+
const epochs = values.flatMap((value) => Option.match(value, {
|
|
39
|
+
onNone: () => [],
|
|
40
|
+
onSome: (dateTime) => [DateTime.toEpochMillis(dateTime)],
|
|
41
|
+
}));
|
|
42
|
+
return epochs.length === 0 ? Option.none() : DateTime.make(Math.max(...epochs));
|
|
43
|
+
};
|
|
44
|
+
//# sourceMappingURL=cycle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cycle.js","sourceRoot":"","sources":["../../src/polling/cycle.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAuB,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAG7E,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAClD,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAC;AAEpE,yEAAyE;AACzE,MAAM,OAAO,qBAAsB,SAAQ,MAAM,CAAC,KAAK,CACrD,2CAA2C,CAC5C,CAAC;IACA,UAAU,EAAE,cAAc;IAC1B,QAAQ,EAAE,MAAM,CAAC,cAAc;IAC/B,OAAO,EAAE,MAAM,CAAC,MAAM;CACvB,CAAC;CAAG;AAEL,mGAAmG;AACnG,MAAM,OAAO,SAAU,SAAQ,MAAM,CAAC,KAAK,CAAY,+BAA+B,CAAC,CAAC;IACtF,YAAY,EAAE,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC;IAChE,YAAY,EAAE,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC;IAChE,WAAW,EAAE,MAAM,CAAC,KAAK,CAAC,gBAAgB,CAAC;IAC3C,4EAA4E;IAC5E,WAAW,EAAE,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC;IAC/D,QAAQ,EAAE,MAAM,CAAC,KAAK,CAAC,qBAAqB,CAAC;IAC7C,iBAAiB,EAAE,MAAM,CAAC,KAAK,CAAC,qBAAqB,CAAC;IACtD,UAAU,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC;CAC9C,CAAC;CAAG;AASL,gEAAgE;AAChE,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAC,KAA0B,EAAE,EAAE;IACvE,MAAM,MAAM,GAAG,EAAE,QAAQ,EAAE,KAAK,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC;IAChE,IAAI,KAAK,CAAC,IAAI,KAAK,iBAAiB,EAAE,CAAC;QACrC,OAAO,EAAE,GAAG,MAAM,EAAE,GAAG,wBAAwB,CAAC,KAAK,CAAC,EAAE,CAAC;IAC3D,CAAC;IACD,IAAI,KAAK,CAAC,IAAI,KAAK,sBAAsB,IAAI,KAAK,CAAC,IAAI,KAAK,2BAA2B,EAAE,CAAC;QACxF,OAAO,EAAE,GAAG,MAAM,EAAE,UAAU,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC;IACjD,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC;AAYF,gGAAgG;AAChG,MAAM,CAAC,MAAM,YAAY,GAAG,CAC1B,MAAkD,EACrB,EAAE;IAC/B,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,CACtC,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE;QAClB,MAAM,EAAE,GAAG,EAAE,CAAC,EAAE;QAChB,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;KACzD,CAAC,CACH,CAAC;IACF,OAAO,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC;AAClF,CAAC,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type RepositoryName } from "@usine/core/repository";
|
|
2
|
+
import type { ChangedItem } from "@usine/github/polling";
|
|
3
|
+
import { Context, DateTime, Effect, Layer, Option } from "effect";
|
|
4
|
+
/** A self-write identifies an Item to fetch; its payload still comes from GitHub. */
|
|
5
|
+
export interface ItemHint {
|
|
6
|
+
readonly repository: RepositoryName;
|
|
7
|
+
readonly item: ChangedItem;
|
|
8
|
+
}
|
|
9
|
+
declare const ItemHints_base: Context.ServiceClass<ItemHints, "@usine/orchestrator/ItemHints", {
|
|
10
|
+
offer: (repository: string & import("effect/Brand").Brand<"RepositoryName">, item: import("@usine/github/polling").ChangedIssue | import("@usine/github/polling").ChangedPullRequest, requestBackoff?: Option.Option<DateTime.Utc> | undefined) => Effect.Effect<void, never, never>;
|
|
11
|
+
take: Effect.Effect<ItemHint, never, never>;
|
|
12
|
+
defer: (until: Option.Option<DateTime.Utc>) => Effect.Effect<void, never, never>;
|
|
13
|
+
awaitBackoff: Effect.Effect<void, never, never>;
|
|
14
|
+
}>;
|
|
15
|
+
/** Private pending Hint and request-backoff state owned by a polling runtime. */
|
|
16
|
+
export declare class ItemHints extends ItemHints_base {
|
|
17
|
+
static readonly layer: Layer.Layer<ItemHints, never, never>;
|
|
18
|
+
}
|
|
19
|
+
export {};
|
|
20
|
+
//# sourceMappingURL=hints.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hints.d.ts","sourceRoot":"","sources":["../../src/polling/hints.ts"],"names":[],"mappings":"AAAA,OAAO,EAA2B,KAAK,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACtF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAS,OAAO,EAAE,QAAQ,EAAY,MAAM,EAAE,KAAK,EAAE,MAAM,EAAc,MAAM,QAAQ,CAAC;AAE/F,qFAAqF;AACrF,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,UAAU,EAAE,cAAc,CAAC;IACpC,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;CAC5B;;;;mBAUuB,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC;;;AAwDnD,iFAAiF;AACjF,qBAAa,SAAU,SAAQ,cAE9B;IACC,MAAM,CAAC,QAAQ,CAAC,KAAK,uCAAiC;CACvD"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { canonicalRepositoryName } from "@usine/core/repository";
|
|
2
|
+
import { Clock, Context, DateTime, Duration, Effect, Layer, Option, Queue, Ref } from "effect";
|
|
3
|
+
/** Pending Hints are bounded and coalesced; the normal poll repairs dropped nudges. */
|
|
4
|
+
const make = Effect.gen(function* () {
|
|
5
|
+
const pending = new Set();
|
|
6
|
+
const queue = yield* Queue.make({ capacity: 128, strategy: "dropping" });
|
|
7
|
+
const backoffUntil = yield* Ref.make(0);
|
|
8
|
+
const key = ({ repository, item }) => `${canonicalRepositoryName(repository)}:${item.number}`;
|
|
9
|
+
const defer = (until) => Option.match(until, {
|
|
10
|
+
onNone: () => Effect.void,
|
|
11
|
+
onSome: (value) => Ref.update(backoffUntil, (current) => Math.max(current, DateTime.toEpochMillis(value))),
|
|
12
|
+
});
|
|
13
|
+
const offer = Effect.fn("PollingTriggers.hint")(function* (repository, item, requestBackoff = Option.none()) {
|
|
14
|
+
yield* Effect.annotateCurrentSpan({ repository, item: item.number });
|
|
15
|
+
yield* defer(requestBackoff);
|
|
16
|
+
const hint = { repository, item };
|
|
17
|
+
const id = key(hint);
|
|
18
|
+
if (pending.has(id)) {
|
|
19
|
+
yield* Effect.logDebug("Self-write Hint coalesced with a pending Item fetch", {
|
|
20
|
+
repository,
|
|
21
|
+
item: item.number,
|
|
22
|
+
});
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
pending.add(id);
|
|
26
|
+
if (yield* Queue.offer(queue, hint)) {
|
|
27
|
+
yield* Effect.logDebug("Self-write Hint queued", { repository, item: item.number });
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
pending.delete(id);
|
|
31
|
+
yield* Effect.logWarning("Self-write Hint queue full; the normal poll will refresh the Item", { repository, item: item.number });
|
|
32
|
+
}
|
|
33
|
+
}, Effect.uninterruptible);
|
|
34
|
+
const take = Effect.uninterruptibleMask((restore) => restore(Queue.take(queue)).pipe(Effect.tap((hint) => Effect.sync(() => pending.delete(key(hint))))));
|
|
35
|
+
const awaitBackoff = Effect.gen(function* () {
|
|
36
|
+
while (true) {
|
|
37
|
+
const until = yield* Ref.get(backoffUntil);
|
|
38
|
+
const now = yield* Clock.currentTimeMillis;
|
|
39
|
+
if (until <= now)
|
|
40
|
+
return;
|
|
41
|
+
yield* Effect.logInfo("GitHub request backoff delays polling and self-write Hints", {
|
|
42
|
+
sleepMs: until - now,
|
|
43
|
+
});
|
|
44
|
+
yield* Effect.sleep(Duration.millis(until - now));
|
|
45
|
+
// An operator write can extend the deadline while this consumer waits.
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
return { offer, take, defer, awaitBackoff };
|
|
49
|
+
});
|
|
50
|
+
/** Private pending Hint and request-backoff state owned by a polling runtime. */
|
|
51
|
+
export class ItemHints extends Context.Service()("@usine/orchestrator/ItemHints") {
|
|
52
|
+
static layer = Layer.effect(ItemHints, make);
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=hints.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hints.js","sourceRoot":"","sources":["../../src/polling/hints.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { ManagedRepo } from "@usine/config/factory";
|
|
2
|
+
import { ConfigParser } from "@usine/config/parser";
|
|
3
|
+
import { RunEngine } from "@usine/engine/engine";
|
|
4
|
+
import type { ObservedItem } from "./repository-sync.ts";
|
|
5
|
+
import { ExpressionEngine } from "@usine/expression/expression-engine";
|
|
6
|
+
import { InvalidGitHubResponseError } from "@usine/github/github-app";
|
|
7
|
+
import { Effect } from "effect";
|
|
8
|
+
import { type ResolvedLoop } from "../trigger-submission.ts";
|
|
9
|
+
import { RepositoryPollFailure } from "./cycle.ts";
|
|
10
|
+
/**
|
|
11
|
+
* Evaluates an already projected Item against its repository's active Loops,
|
|
12
|
+
* renders matching prompts, and submits or revokes Runs. Prompt-render failures
|
|
13
|
+
* are reported per Loop; expression and Run failures stop the repository before
|
|
14
|
+
* its cursor commits. Schedule Ticks have separate evaluation semantics.
|
|
15
|
+
*/
|
|
16
|
+
export declare const evaluateItem: (repository: ManagedRepo, resolved: readonly ResolvedLoop[], observed: ObservedItem) => Effect.Effect<{
|
|
17
|
+
submissions: (import("@usine/engine/engine").Claimed | import("@usine/engine/engine").CycleBlocked | import("@usine/engine/engine").Ignored | import("@usine/engine/engine").Queued)[];
|
|
18
|
+
revokedRuns: number;
|
|
19
|
+
failures: RepositoryPollFailure[];
|
|
20
|
+
}, import("@usine/engine/engine").AttemptCancellationError | import("@usine/engine/engine").EnginePersistenceError | import("@usine/expression/expression-engine").ExpressionCheckError | import("@usine/expression/expression-engine").ExpressionEvaluationError | InvalidGitHubResponseError | import("@usine/engine/engine").RunInterventionRejectedError | import("@usine/engine/engine").RunNotFoundError | import("@usine/engine/engine").RunOperationRejectedError, ConfigParser | ExpressionEngine | RunEngine>;
|
|
21
|
+
//# sourceMappingURL=loop-evaluation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loop-evaluation.d.ts","sourceRoot":"","sources":["../../src/polling/loop-evaluation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAEzD,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAKpD,OAAO,EAAE,SAAS,EAAyB,MAAM,sBAAsB,CAAC;AACxE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,qCAAqC,CAAC;AACvE,OAAO,EAAE,0BAA0B,EAAE,MAAM,0BAA0B,CAAC;AACtE,OAAO,EAAY,MAAM,EAAkB,MAAM,QAAQ,CAAC;AAC1D,OAAO,EAGL,KAAK,YAAY,EAGlB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AA0BnD;;;;;GAKG;AACH,eAAO,MAAM,YAAY;;;;ufA4HvB,CAAC"}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { ConfigParser } from "@usine/config/parser";
|
|
2
|
+
import { environmentFor, repositoryContext } from "@usine/config/payload-slices";
|
|
3
|
+
import { AttemptTask } from "@usine/core/attempt";
|
|
4
|
+
import { DedupKey } from "@usine/core/event";
|
|
5
|
+
import { CommitSha, RepositoryRevision, canonicalRepositoryName } from "@usine/core/repository";
|
|
6
|
+
import { RunEngine } from "@usine/engine/engine";
|
|
7
|
+
import { ExpressionEngine } from "@usine/expression/expression-engine";
|
|
8
|
+
import { InvalidGitHubResponseError } from "@usine/github/github-app";
|
|
9
|
+
import { DateTime, Effect, Result, Schema } from "effect";
|
|
10
|
+
import { configFileErrorLogFields, DEFAULT_BRANCH_REVISION, submissionLogFields, triggerSubmission, } from "../trigger-submission.js";
|
|
11
|
+
import { RepositoryPollFailure } from "./cycle.js";
|
|
12
|
+
const eventKey = (loop, repository, { projection: item, cycleGeneration }) => DedupKey.make(JSON.stringify([
|
|
13
|
+
loop.name,
|
|
14
|
+
canonicalRepositoryName(repository.name),
|
|
15
|
+
item.number,
|
|
16
|
+
item.contentHash,
|
|
17
|
+
// Preserve pre-budget identities while making every reset a fresh Event
|
|
18
|
+
// with the current rendered task, Agent and authored limit.
|
|
19
|
+
...(cycleGeneration === 0 ? [] : [cycleGeneration]),
|
|
20
|
+
]));
|
|
21
|
+
/**
|
|
22
|
+
* Evaluates an already projected Item against its repository's active Loops,
|
|
23
|
+
* renders matching prompts, and submits or revokes Runs. Prompt-render failures
|
|
24
|
+
* are reported per Loop; expression and Run failures stop the repository before
|
|
25
|
+
* its cursor commits. Schedule Ticks have separate evaluation semantics.
|
|
26
|
+
*/
|
|
27
|
+
export const evaluateItem = Effect.fn("PollingTriggers.evaluateItem")(function* (repository, resolved, observed) {
|
|
28
|
+
const { projection: item, cycleGeneration } = observed;
|
|
29
|
+
yield* Effect.annotateCurrentSpan({
|
|
30
|
+
repository: repository.name,
|
|
31
|
+
item: item.number,
|
|
32
|
+
});
|
|
33
|
+
const config = yield* ConfigParser;
|
|
34
|
+
const expressions = yield* ExpressionEngine;
|
|
35
|
+
const runs = yield* RunEngine;
|
|
36
|
+
const loops = resolved.filter(({ loop }) => loop.trigger.on === item.source);
|
|
37
|
+
const payload = item.payload;
|
|
38
|
+
const context = { repo: repositoryContext(repository), item: payload };
|
|
39
|
+
if (loops.length === 0) {
|
|
40
|
+
yield* Effect.logDebug("Item projected without any matching repository Loop", {
|
|
41
|
+
repository: repository.name,
|
|
42
|
+
item: item.number,
|
|
43
|
+
stream: item.source,
|
|
44
|
+
});
|
|
45
|
+
return { submissions: [], revokedRuns: 0, failures: [] };
|
|
46
|
+
}
|
|
47
|
+
const submissions = [];
|
|
48
|
+
// Projections store generic JSON; decode the GitHub PR revision at this boundary.
|
|
49
|
+
const revision = item.source === "pr"
|
|
50
|
+
? RepositoryRevision.make(yield* Schema.decodeUnknownEffect(CommitSha)(payload.headRefOid).pipe(Effect.mapError(() => new InvalidGitHubResponseError({
|
|
51
|
+
operation: "fetch-pull-request-snapshot",
|
|
52
|
+
message: "The pull request payload has no valid head commit",
|
|
53
|
+
detail: `PR ${item.number} requires a full headRefOid`,
|
|
54
|
+
}))))
|
|
55
|
+
: DEFAULT_BRANCH_REVISION;
|
|
56
|
+
const failures = [];
|
|
57
|
+
let revokedRuns = 0;
|
|
58
|
+
for (const { agent, loop, parentModel } of loops) {
|
|
59
|
+
yield* Effect.annotateCurrentSpan({ loop: loop.name, agent: agent.name });
|
|
60
|
+
const matches = yield* expressions.evaluateBoolean(loop.trigger.if, environmentFor(loop.trigger.on), context);
|
|
61
|
+
if (!matches) {
|
|
62
|
+
yield* Effect.logDebug("Item did not match its loop expression", {
|
|
63
|
+
repository: repository.name,
|
|
64
|
+
loop: loop.name,
|
|
65
|
+
agent: agent.name,
|
|
66
|
+
item: item.number,
|
|
67
|
+
});
|
|
68
|
+
const revoked = yield* runs.revoke(loop.name, item.itemKey);
|
|
69
|
+
revokedRuns += revoked.length;
|
|
70
|
+
if (revoked.length > 0) {
|
|
71
|
+
yield* Effect.logInfo("Item stopped matching; revoked its unstarted runs", {
|
|
72
|
+
repository: repository.name,
|
|
73
|
+
loop: loop.name,
|
|
74
|
+
agent: agent.name,
|
|
75
|
+
item: item.number,
|
|
76
|
+
runIds: revoked.join(", "),
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
continue;
|
|
80
|
+
}
|
|
81
|
+
const dedupKey = eventKey(loop, repository, observed);
|
|
82
|
+
const receivedAt = yield* DateTime.now;
|
|
83
|
+
// A render failure comes from the loop's authoring, not transport, so
|
|
84
|
+
// re-polling would fail the same way. It is scoped to this loop so the
|
|
85
|
+
// sibling loops and the cursor still advance.
|
|
86
|
+
const rendered = yield* Effect.result(config.renderPrompt(loop, context));
|
|
87
|
+
if (Result.isFailure(rendered)) {
|
|
88
|
+
yield* Effect.logError("Loop prompt rendering failed; sibling loops were unaffected", {
|
|
89
|
+
loop: loop.name,
|
|
90
|
+
repository: repository.name,
|
|
91
|
+
agent: agent.name,
|
|
92
|
+
item: item.number,
|
|
93
|
+
errorTag: rendered.failure._tag,
|
|
94
|
+
message: rendered.failure.message,
|
|
95
|
+
...configFileErrorLogFields(rendered.failure),
|
|
96
|
+
});
|
|
97
|
+
failures.push(new RepositoryPollFailure({
|
|
98
|
+
repository: repository.name,
|
|
99
|
+
errorTag: rendered.failure._tag,
|
|
100
|
+
message: rendered.failure.message,
|
|
101
|
+
}));
|
|
102
|
+
continue;
|
|
103
|
+
}
|
|
104
|
+
const submitted = yield* runs.submit(triggerSubmission({
|
|
105
|
+
dedupKey,
|
|
106
|
+
cycleGeneration,
|
|
107
|
+
itemKey: item.itemKey,
|
|
108
|
+
loop,
|
|
109
|
+
payload,
|
|
110
|
+
receivedAt,
|
|
111
|
+
repository,
|
|
112
|
+
revision,
|
|
113
|
+
task: AttemptTask.make(rendered.success),
|
|
114
|
+
agent,
|
|
115
|
+
parentModel,
|
|
116
|
+
}));
|
|
117
|
+
yield* Effect.logInfo("Submitted matching item state", {
|
|
118
|
+
repository: repository.name,
|
|
119
|
+
loop: loop.name,
|
|
120
|
+
agent: agent.name,
|
|
121
|
+
item: item.number,
|
|
122
|
+
contentHash: item.contentHash,
|
|
123
|
+
revision,
|
|
124
|
+
result: submitted._tag,
|
|
125
|
+
...submissionLogFields(submitted),
|
|
126
|
+
});
|
|
127
|
+
submissions.push(submitted);
|
|
128
|
+
}
|
|
129
|
+
return { submissions, revokedRuns, failures };
|
|
130
|
+
});
|
|
131
|
+
//# sourceMappingURL=loop-evaluation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loop-evaluation.js","sourceRoot":"","sources":["../../src/polling/loop-evaluation.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { LoadedInstance } from "@usine/config/instance";
|
|
2
|
+
import { ConfigParser } from "@usine/config/parser";
|
|
3
|
+
import { type RepositoryName } from "@usine/core/repository";
|
|
4
|
+
import { CursorStore } from "@usine/engine/cursor";
|
|
5
|
+
import { CycleBudgets } from "@usine/engine/cycle-budget";
|
|
6
|
+
import { RunEngine, type EnginePersistenceError } from "@usine/engine/engine";
|
|
7
|
+
import { ItemProjectionWriter } from "@usine/engine/item-projection";
|
|
8
|
+
import { LoopControl } from "@usine/engine/loop-control";
|
|
9
|
+
import { RepositoryLabelProjectionReader, RepositoryLabelProjectionWriter } from "@usine/engine/repository-label-projection";
|
|
10
|
+
import { ExpressionEngine } from "@usine/expression/expression-engine";
|
|
11
|
+
import { type ChangedItem, GitHubPolling } from "@usine/github/polling";
|
|
12
|
+
import { Context, DateTime, Effect, Layer, Option } from "effect";
|
|
13
|
+
import { LabelReconciler } from "../label-reconciler.ts";
|
|
14
|
+
import { PollCycle } from "./cycle.ts";
|
|
15
|
+
declare const PollingTriggers_base: Context.ServiceClass<PollingTriggers, "@usine/orchestrator/PollingTriggers", {
|
|
16
|
+
/**
|
|
17
|
+
* Polls every managed repository, including those without active Loops.
|
|
18
|
+
* Label preflight precedes change detection; each changed Item is projected
|
|
19
|
+
* before its Run decisions. A repository commits its cursor only after all
|
|
20
|
+
* Items finish. Repository failures are reported while siblings continue;
|
|
21
|
+
* failure to read Loop runtime state fails the whole cycle.
|
|
22
|
+
*/
|
|
23
|
+
readonly poll: (instance: LoadedInstance) => Effect.Effect<PollCycle, EnginePersistenceError>;
|
|
24
|
+
/** Nudges an authoritative Item fetch after a self-write, retaining any request backoff from the writer. Pending duplicates coalesce; polling repairs loss. */
|
|
25
|
+
readonly hint: (repository: RepositoryName, item: ChangedItem, backoffUntil?: Option.Option<DateTime.Utc>) => Effect.Effect<void>;
|
|
26
|
+
/** Repeats cycles at the configured interval and processes self-write Hints, respecting GitHub request backoff. */
|
|
27
|
+
readonly run: (instance: LoadedInstance) => Effect.Effect<never>;
|
|
28
|
+
/** The last completed cycle, including its isolated failures; absent until the first cycle completes. */
|
|
29
|
+
readonly latest: Effect.Effect<Option.Option<PollCycle>>;
|
|
30
|
+
}>;
|
|
31
|
+
/** Keeps managed repositories' Boards current and evaluates their active Loops against changed Items. */
|
|
32
|
+
export declare class PollingTriggers extends PollingTriggers_base {
|
|
33
|
+
static readonly layer: Layer.Layer<PollingTriggers, never, ConfigParser | CursorStore | CycleBudgets | ExpressionEngine | GitHubPolling | ItemProjectionWriter | LabelReconciler | LoopControl | RepositoryLabelProjectionReader | RepositoryLabelProjectionWriter | RunEngine>;
|
|
34
|
+
}
|
|
35
|
+
export {};
|
|
36
|
+
//# sourceMappingURL=polling.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"polling.d.ts","sourceRoot":"","sources":["../../src/polling/polling.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAE7D,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEpD,OAAO,EAA2B,KAAK,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACtF,OAAO,EAAa,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EACL,SAAS,EACT,KAAK,sBAAsB,EAE5B,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AACrE,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AACzD,OAAO,EACL,+BAA+B,EAC/B,+BAA+B,EAChC,MAAM,2CAA2C,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,qCAAqC,CAAC;AACvE,OAAO,EAAE,KAAK,WAAW,EAAyB,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC/F,OAAO,EAEL,OAAO,EACP,QAAQ,EAER,MAAM,EACN,KAAK,EACL,MAAM,EAKP,MAAM,QAAQ,CAAC;AAChB,OAAO,EAAE,eAAe,EAA8B,MAAM,wBAAwB,CAAC;AAErF,OAAO,EAGL,SAAS,EAIV,MAAM,YAAY,CAAC;;IAmEhB;;;;;;OAMG;mBACY,CAAC,QAAQ,EAAE,cAAc,KAAK,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,sBAAsB,CAAC;IAC7F,+JAA+J;mBAChJ,CACb,UAAU,EAAE,cAAc,EAC1B,IAAI,EAAE,WAAW,EACjB,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,KACvC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC;IACxB,mHAAmH;kBACrG,CAAC,QAAQ,EAAE,cAAc,KAAK,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC;IAChE,yGAAyG;qBACxF,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;;AArB5D,yGAAyG;AACzG,qBAAa,eAAgB,SAAQ,oBAsBK;IACxC,MAAM,CAAC,QAAQ,CAAC,KAAK,2PAyVkB;CACxC"}
|