@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.
Files changed (122) hide show
  1. package/README.md +46 -21
  2. package/dist/board/items.d.ts +18 -0
  3. package/dist/board/items.d.ts.map +1 -0
  4. package/dist/board/items.js +46 -0
  5. package/dist/board/items.js.map +1 -0
  6. package/dist/board/projection.d.ts +6 -5
  7. package/dist/board/projection.d.ts.map +1 -1
  8. package/dist/board/projection.js +25 -65
  9. package/dist/board/projection.js.map +1 -1
  10. package/dist/board/tasks.d.ts +8 -0
  11. package/dist/board/tasks.d.ts.map +1 -0
  12. package/dist/board/tasks.js +86 -0
  13. package/dist/board/tasks.js.map +1 -0
  14. package/dist/credentials.d.ts +6 -6
  15. package/dist/credentials.d.ts.map +1 -1
  16. package/dist/credentials.js +6 -6
  17. package/dist/credentials.js.map +1 -1
  18. package/dist/exe-dev.d.ts +5 -4
  19. package/dist/exe-dev.d.ts.map +1 -1
  20. package/dist/exe-dev.js +5 -4
  21. package/dist/exe-dev.js.map +1 -1
  22. package/dist/idle-triggers.d.ts +1 -1
  23. package/dist/idle-triggers.d.ts.map +1 -1
  24. package/dist/idle-triggers.js +3 -1
  25. package/dist/idle-triggers.js.map +1 -1
  26. package/dist/label-reconciler.d.ts +30 -0
  27. package/dist/label-reconciler.d.ts.map +1 -0
  28. package/dist/label-reconciler.js +119 -0
  29. package/dist/label-reconciler.js.map +1 -0
  30. package/dist/local.d.ts +17 -12
  31. package/dist/local.d.ts.map +1 -1
  32. package/dist/local.js +20 -13
  33. package/dist/local.js.map +1 -1
  34. package/dist/operator/attempt.d.ts +69 -0
  35. package/dist/operator/attempt.d.ts.map +1 -0
  36. package/dist/operator/attempt.js +62 -0
  37. package/dist/operator/attempt.js.map +1 -0
  38. package/dist/operator/board.d.ts +119 -0
  39. package/dist/operator/board.d.ts.map +1 -0
  40. package/dist/operator/board.js +101 -0
  41. package/dist/operator/board.js.map +1 -0
  42. package/dist/operator/http.d.ts +180 -0
  43. package/dist/operator/http.d.ts.map +1 -0
  44. package/dist/operator/http.js +150 -0
  45. package/dist/operator/http.js.map +1 -0
  46. package/dist/operator/need.d.ts +66 -0
  47. package/dist/operator/need.d.ts.map +1 -0
  48. package/dist/operator/need.js +70 -0
  49. package/dist/operator/need.js.map +1 -0
  50. package/dist/operator/operator.d.ts +68 -0
  51. package/dist/operator/operator.d.ts.map +1 -0
  52. package/dist/operator/operator.js +402 -0
  53. package/dist/operator/operator.js.map +1 -0
  54. package/dist/operator/overview.d.ts +51 -0
  55. package/dist/operator/overview.d.ts.map +1 -0
  56. package/dist/operator/overview.js +48 -0
  57. package/dist/operator/overview.js.map +1 -0
  58. package/dist/operator/projection.d.ts +12 -9
  59. package/dist/operator/projection.d.ts.map +1 -1
  60. package/dist/operator/projection.js +44 -17
  61. package/dist/operator/projection.js.map +1 -1
  62. package/dist/operator/run.d.ts +62 -0
  63. package/dist/operator/run.d.ts.map +1 -0
  64. package/dist/operator/run.js +61 -0
  65. package/dist/operator/run.js.map +1 -0
  66. package/dist/operator/transcript.d.ts +59 -0
  67. package/dist/operator/transcript.d.ts.map +1 -0
  68. package/dist/operator/transcript.js +66 -0
  69. package/dist/operator/transcript.js.map +1 -0
  70. package/dist/orchestrator.d.ts +3 -2
  71. package/dist/orchestrator.d.ts.map +1 -1
  72. package/dist/orchestrator.js +1 -1
  73. package/dist/orchestrator.js.map +1 -1
  74. package/dist/polling/cycle.d.ts +51 -0
  75. package/dist/polling/cycle.d.ts.map +1 -0
  76. package/dist/polling/cycle.js +44 -0
  77. package/dist/polling/cycle.js.map +1 -0
  78. package/dist/polling/hints.d.ts +20 -0
  79. package/dist/polling/hints.d.ts.map +1 -0
  80. package/dist/polling/hints.js +54 -0
  81. package/dist/polling/hints.js.map +1 -0
  82. package/dist/polling/loop-evaluation.d.ts +21 -0
  83. package/dist/polling/loop-evaluation.d.ts.map +1 -0
  84. package/dist/polling/loop-evaluation.js +131 -0
  85. package/dist/polling/loop-evaluation.js.map +1 -0
  86. package/dist/polling/polling.d.ts +36 -0
  87. package/dist/polling/polling.d.ts.map +1 -0
  88. package/dist/polling/polling.js +296 -0
  89. package/dist/polling/polling.js.map +1 -0
  90. package/dist/polling/repository-sync.d.ts +45 -0
  91. package/dist/polling/repository-sync.d.ts.map +1 -0
  92. package/dist/polling/repository-sync.js +169 -0
  93. package/dist/polling/repository-sync.js.map +1 -0
  94. package/dist/polling-triggers.d.ts +3 -39
  95. package/dist/polling-triggers.d.ts.map +1 -1
  96. package/dist/polling-triggers.js +3 -393
  97. package/dist/polling-triggers.js.map +1 -1
  98. package/dist/schedule-triggers.d.ts +17 -15
  99. package/dist/schedule-triggers.d.ts.map +1 -1
  100. package/dist/schedule-triggers.js +53 -43
  101. package/dist/schedule-triggers.js.map +1 -1
  102. package/dist/scheduler.d.ts +5 -5
  103. package/dist/scheduler.d.ts.map +1 -1
  104. package/dist/scheduler.js +30 -44
  105. package/dist/scheduler.js.map +1 -1
  106. package/dist/trigger-submission.d.ts +33 -24
  107. package/dist/trigger-submission.d.ts.map +1 -1
  108. package/dist/trigger-submission.js +30 -37
  109. package/dist/trigger-submission.js.map +1 -1
  110. package/package.json +50 -14
  111. package/dist/index.d.ts +0 -11
  112. package/dist/index.d.ts.map +0 -1
  113. package/dist/index.js +0 -11
  114. package/dist/index.js.map +0 -1
  115. package/dist/operator/model.d.ts +0 -280
  116. package/dist/operator/model.d.ts.map +0 -1
  117. package/dist/operator/model.js +0 -242
  118. package/dist/operator/model.js.map +0 -1
  119. package/dist/operator/service.d.ts +0 -36
  120. package/dist/operator/service.d.ts.map +0 -1
  121. package/dist/operator/service.js +0 -248
  122. package/dist/operator/service.js.map +0 -1
@@ -0,0 +1,296 @@
1
+ import { ConfigParser } from "@usine/config/parser";
2
+ import { matchesSelector } from "@usine/config/selector";
3
+ import { canonicalRepositoryName } from "@usine/core/repository";
4
+ import { CursorKey, CursorStore } from "@usine/engine/cursor";
5
+ import { CycleBudgets } from "@usine/engine/cycle-budget";
6
+ import { RunEngine, } 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 { EntityTag, PollCursor, GitHubPolling } from "@usine/github/polling";
12
+ import { Clock, Context, DateTime, Duration, Effect, Layer, Option, Ref, Result, Schema, Semaphore, } from "effect";
13
+ import { LabelReconciler } from "../label-reconciler.js";
14
+ import { resolveTriggerLoops } from "../trigger-submission.js";
15
+ import { latestPollAt, PollCycle, RepositoryPollFailure, repositoryFailureLogFields, } from "./cycle.js";
16
+ import { evaluateItem } from "./loop-evaluation.js";
17
+ import { observeItem, synchronizeLabels } from "./repository-sync.js";
18
+ import { ItemHints } from "./hints.js";
19
+ /** GitHub tolerates a handful of parallel REST and GraphQL calls per token. */
20
+ const REPOSITORY_CONCURRENCY = 4;
21
+ const ITEM_CONCURRENCY = 4;
22
+ const WatchKey = Schema.NonEmptyString.pipe(Schema.brand("GitHubPollWatchKey"));
23
+ class StoredPollCursor extends Schema.Class("@usine/orchestrator/StoredPollCursor")({
24
+ boardVersion: Schema.Literal(4),
25
+ cursor: PollCursor,
26
+ labelEntityTag: Schema.OptionFromNullOr(EntityTag),
27
+ watches: Schema.Array(WatchKey).check(Schema.isUnique()),
28
+ }) {
29
+ }
30
+ const cursorKey = (repository) => CursorKey.make(`github-poll:${canonicalRepositoryName(repository.name)}`);
31
+ const watchKey = ({ loop }) => WatchKey.make(JSON.stringify([loop.name, loop.trigger.on, loop.trigger.if]));
32
+ const watchedRepositories = (instance, resolved) => instance.config.repos.map((repository) => {
33
+ const loops = resolved.filter(({ loop }) => loop.trigger.on !== "schedule" && matchesSelector(loop.selector, repository));
34
+ return {
35
+ repository,
36
+ declaredLabels: instance.config.labels,
37
+ loops,
38
+ watches: loops.map(watchKey).sort(),
39
+ };
40
+ });
41
+ const sameWatches = (left, right) => left.length === right.length && left.every((value, index) => value === right[index]);
42
+ /** Keeps managed repositories' Boards current and evaluates their active Loops against changed Items. */
43
+ export class PollingTriggers extends Context.Service()("@usine/orchestrator/PollingTriggers") {
44
+ static layer = Layer.effect(PollingTriggers, Effect.gen(function* () {
45
+ const cursors = yield* CursorStore;
46
+ const budgets = yield* CycleBudgets;
47
+ const github = yield* GitHubPolling;
48
+ const loops = yield* LoopControl;
49
+ const latest = yield* Ref.make(Option.none());
50
+ const hints = yield* ItemHints;
51
+ const ownership = yield* Semaphore.make(1);
52
+ const emptyCursor = (watches) => new StoredPollCursor({
53
+ boardVersion: 4,
54
+ cursor: PollCursor.empty,
55
+ labelEntityTag: Option.none(),
56
+ watches,
57
+ });
58
+ const readCursor = Effect.fn("PollingTriggers.readCursor")(function* (watched) {
59
+ yield* Effect.annotateCurrentSpan({ repository: watched.repository.name });
60
+ const stored = yield* cursors.read(cursorKey(watched.repository), StoredPollCursor);
61
+ if (Option.isNone(stored))
62
+ return emptyCursor(watched.watches);
63
+ if (!sameWatches(stored.value.watches, watched.watches)) {
64
+ yield* Effect.logInfo("Watched loops changed; re-polling the repository from scratch", {
65
+ repository: watched.repository.name,
66
+ previousWatches: stored.value.watches.length,
67
+ currentWatches: watched.watches.length,
68
+ });
69
+ return emptyCursor(watched.watches);
70
+ }
71
+ return stored.value;
72
+ });
73
+ const writeCursor = Effect.fn("PollingTriggers.writeCursor")(function* (watched, cursor) {
74
+ yield* Effect.annotateCurrentSpan({ repository: watched.repository.name });
75
+ yield* cursors.write(cursorKey(watched.repository), StoredPollCursor, cursor);
76
+ });
77
+ const pollRepository = Effect.fn("PollingTriggers.pollRepository")(function* (watched) {
78
+ yield* Effect.annotateCurrentSpan({ repository: watched.repository.name });
79
+ const resets = (yield* budgets.pendingResets()).filter(({ repository }) => canonicalRepositoryName(repository) ===
80
+ canonicalRepositoryName(watched.repository.name));
81
+ const stored = resets.length > 0 ? emptyCursor(watched.watches) : yield* readCursor(watched);
82
+ if (resets.length > 0)
83
+ yield* Effect.logInfo("Cycle budget reset requests fresh repository polling", {
84
+ repository: watched.repository.name,
85
+ items: resets.map(({ itemKey }) => itemKey),
86
+ });
87
+ const preflight = yield* synchronizeLabels(watched.repository.name, watched.declaredLabels, stored.labelEntityTag);
88
+ yield* hints.defer(preflight.nextPollAt);
89
+ return yield* Effect.gen(function* () {
90
+ // Label creation finishes before change detection and Item evaluation
91
+ // begin, including on the first cycle after `usine up`.
92
+ const detected = yield* github.changes(watched.repository.name, stored.cursor);
93
+ yield* hints.defer(detected.backoffUntil);
94
+ const nextCursor = new StoredPollCursor({
95
+ boardVersion: 4,
96
+ cursor: detected.cursor,
97
+ labelEntityTag: preflight.labelEntityTag,
98
+ watches: watched.watches,
99
+ });
100
+ const nextPollAt = latestPollAt([detected.nextPollAt, preflight.nextPollAt]);
101
+ if (detected._tag === "RepositoryNotModified") {
102
+ if (preflight.entityTagChanged) {
103
+ yield* writeCursor(watched, nextCursor);
104
+ }
105
+ yield* Effect.logDebug("Repository unchanged (304)", {
106
+ repository: watched.repository.name,
107
+ });
108
+ return {
109
+ changedItems: 0,
110
+ submissions: [],
111
+ revokedRuns: 0,
112
+ failures: preflight.failures,
113
+ preflightFindings: preflight.preflightFindings,
114
+ nextPollAt,
115
+ };
116
+ }
117
+ yield* Effect.logInfo("Repository changed", {
118
+ repository: watched.repository.name,
119
+ changedItems: detected.items.length,
120
+ backlog: detected.backlog,
121
+ });
122
+ const itemCycles = yield* Effect.forEach(detected.items, (item) => observeItem(watched.repository.name, item).pipe(Effect.flatMap((projection) => evaluateItem(watched.repository, watched.loops, projection))), { concurrency: ITEM_CONCURRENCY });
123
+ // Advancing the cursor is the commit point: every changed item was
124
+ // fetched, evaluated, and submitted or revoked. After a failure the
125
+ // old cursor stays so the next cycle re-polls.
126
+ yield* writeCursor(watched, nextCursor);
127
+ yield* Effect.forEach(resets, budgets.acknowledgeReset, { discard: true });
128
+ return {
129
+ changedItems: detected.items.length,
130
+ submissions: itemCycles.flatMap(({ submissions }) => submissions),
131
+ revokedRuns: itemCycles.reduce((sum, cycle) => sum + cycle.revokedRuns, 0),
132
+ failures: [...preflight.failures, ...itemCycles.flatMap(({ failures }) => failures)],
133
+ preflightFindings: preflight.preflightFindings,
134
+ nextPollAt,
135
+ };
136
+ }).pipe(Effect.mapError((error) => ({
137
+ _tag: "InterruptedRepositoryCycle",
138
+ error,
139
+ failures: preflight.failures,
140
+ preflightFindings: preflight.preflightFindings,
141
+ nextPollAt: preflight.nextPollAt,
142
+ })));
143
+ });
144
+ // Bind only dependencies, preserving the caller's clock, logging and
145
+ // tracing context on each cycle instead of capturing them at layer build.
146
+ const repositoryServices = (yield* Effect.context()).pipe(Context.pick(ConfigParser, CycleBudgets, ExpressionEngine, GitHubPolling, ItemProjectionWriter, LabelReconciler, RepositoryLabelProjectionReader, RepositoryLabelProjectionWriter, RunEngine));
147
+ const poll = Effect.fn("PollingTriggers.poll")(function* (instance) {
148
+ yield* hints.awaitBackoff;
149
+ const paused = new Set((yield* loops.states).filter((state) => state.paused).map((state) => state.loop));
150
+ for (const loop of instance.loops) {
151
+ if (loop.trigger.on !== "schedule" && paused.has(loop.name)) {
152
+ yield* Effect.logDebug("Paused Loop skipped during repository polling", {
153
+ loop: loop.name,
154
+ });
155
+ }
156
+ }
157
+ const resolved = (yield* resolveTriggerLoops(instance)).filter(({ loop }) => !paused.has(loop.name));
158
+ const watched = watchedRepositories(instance, resolved);
159
+ const settled = yield* Effect.forEach(watched, (repository) => Effect.result(pollRepository(repository)).pipe(Effect.map((result) => ({ repository, result }))), { concurrency: REPOSITORY_CONCURRENCY });
160
+ const cycles = [];
161
+ const failures = [];
162
+ const backoffs = [];
163
+ const preflightFindings = [];
164
+ for (const { repository, result } of settled) {
165
+ if (Result.isSuccess(result)) {
166
+ cycles.push(result.success);
167
+ preflightFindings.push(...result.success.preflightFindings);
168
+ continue;
169
+ }
170
+ const interrupted = result.failure._tag === "InterruptedRepositoryCycle";
171
+ const error = interrupted ? result.failure.error : result.failure;
172
+ if (interrupted) {
173
+ failures.push(...result.failure.failures);
174
+ preflightFindings.push(...result.failure.preflightFindings);
175
+ backoffs.push(result.failure.nextPollAt);
176
+ yield* hints.defer(result.failure.nextPollAt);
177
+ }
178
+ if (error._tag === "GitHubRateLimitError") {
179
+ // A rate-limit pause is scheduling input, not a repository failure.
180
+ yield* Effect.logWarning("GitHub rate limit reached; delaying the next cycle", {
181
+ repository: repository.repository.name,
182
+ operation: error.operation,
183
+ retryAt: DateTime.formatIso(error.retryAt),
184
+ });
185
+ backoffs.push(Option.some(error.retryAt));
186
+ yield* hints.defer(Option.some(error.retryAt));
187
+ continue;
188
+ }
189
+ yield* Effect.logError("Repository poll cycle failed; siblings were unaffected", {
190
+ repository: repository.repository.name,
191
+ ...repositoryFailureLogFields(error),
192
+ });
193
+ failures.push(new RepositoryPollFailure({
194
+ repository: repository.repository.name,
195
+ errorTag: error._tag,
196
+ message: error.message,
197
+ }));
198
+ }
199
+ const cycle = new PollCycle({
200
+ repositories: watched.length,
201
+ changedItems: cycles.reduce((sum, cycle) => sum + cycle.changedItems, 0),
202
+ submissions: cycles.flatMap(({ submissions }) => submissions),
203
+ revokedRuns: cycles.reduce((sum, cycle) => sum + cycle.revokedRuns, 0),
204
+ failures: [...cycles.flatMap(({ failures: isolated }) => isolated), ...failures],
205
+ preflightFindings,
206
+ nextPollAt: latestPollAt([...cycles.map(({ nextPollAt }) => nextPollAt), ...backoffs]),
207
+ });
208
+ yield* Ref.set(latest, Option.some(cycle));
209
+ return cycle;
210
+ }, Effect.provideContext(repositoryServices), ownership.withPermits(1));
211
+ const refreshHint = Effect.fn("PollingTriggers.refreshHint")(function* (instance, hint) {
212
+ yield* Effect.annotateCurrentSpan({
213
+ repository: hint.repository,
214
+ item: hint.item.number,
215
+ });
216
+ yield* hints.awaitBackoff;
217
+ const paused = new Set((yield* loops.states).filter((state) => state.paused).map((state) => state.loop));
218
+ const resolved = (yield* resolveTriggerLoops(instance)).filter(({ loop }) => !paused.has(loop.name));
219
+ const watched = watchedRepositories(instance, resolved).find(({ repository }) => canonicalRepositoryName(repository.name) === canonicalRepositoryName(hint.repository));
220
+ if (watched === undefined) {
221
+ yield* Effect.logInfo("Self-write Hint ignored for an unmanaged repository", {
222
+ repository: hint.repository,
223
+ item: hint.item.number,
224
+ });
225
+ return;
226
+ }
227
+ // Share the normal snapshot, projection and dedup path. Hints never
228
+ // advance a REST cursor or replace the latest complete cycle's findings.
229
+ const observed = yield* observeItem(watched.repository.name, hint.item);
230
+ const result = yield* evaluateItem(watched.repository, watched.loops, observed);
231
+ yield* Effect.logInfo("Self-write Hint refreshed the Item", {
232
+ repository: hint.repository,
233
+ item: hint.item.number,
234
+ submissions: result.submissions.length,
235
+ revokedRuns: result.revokedRuns,
236
+ failures: result.failures.length,
237
+ });
238
+ }, Effect.provideContext(repositoryServices), (effect, _instance, hint) => effect.pipe(Effect.catch((error) => Effect.gen(function* () {
239
+ if (error._tag === "GitHubRateLimitError")
240
+ yield* hints.defer(Option.some(error.retryAt));
241
+ yield* Effect.logWarning("Self-write Hint refresh failed; the normal poll will retry", {
242
+ repository: hint.repository,
243
+ item: hint.item.number,
244
+ ...repositoryFailureLogFields(error),
245
+ });
246
+ })), ownership.withPermits(1)));
247
+ const waitForNextPoll = (instance, target) => Effect.gen(function* () {
248
+ while (true) {
249
+ const remaining = target - (yield* Clock.currentTimeMillis);
250
+ if (remaining <= 0)
251
+ return;
252
+ const hint = yield* Effect.raceFirst(hints.take.pipe(Effect.map(Option.some)), Effect.sleep(Duration.millis(remaining)).pipe(Effect.as(Option.none())));
253
+ if (Option.isNone(hint))
254
+ return;
255
+ yield* refreshHint(instance, hint.value);
256
+ }
257
+ });
258
+ // `run` never returns, so wrapping it in Effect.fn would open a span that
259
+ // never closes; `poll` opens the span for each cycle.
260
+ const run = (instance) => Effect.gen(function* () {
261
+ const startedAt = yield* Clock.currentTimeMillis;
262
+ const result = yield* Effect.result(poll(instance));
263
+ if (Result.isFailure(result)) {
264
+ const sleepMs = instance.config.settings.pollInterval * 1_000;
265
+ yield* Effect.logError("Poll cycle could not read Loop runtime state; retrying", {
266
+ errorTag: result.failure._tag,
267
+ message: result.failure.message,
268
+ operation: result.failure.operation,
269
+ sleepMs,
270
+ });
271
+ yield* Effect.sleep(Duration.millis(sleepMs));
272
+ return;
273
+ }
274
+ const cycle = result.success;
275
+ const intervalAt = startedAt + instance.config.settings.pollInterval * 1_000;
276
+ const target = Option.match(cycle.nextPollAt, {
277
+ onNone: () => intervalAt,
278
+ onSome: (value) => Math.max(intervalAt, DateTime.toEpochMillis(value)),
279
+ });
280
+ const now = yield* Clock.currentTimeMillis;
281
+ const sleepMs = Math.max(0, target - now);
282
+ yield* Effect.logInfo("Poll cycle complete", {
283
+ repositories: cycle.repositories,
284
+ changedItems: cycle.changedItems,
285
+ submissions: cycle.submissions.length,
286
+ revokedRuns: cycle.revokedRuns,
287
+ failures: cycle.failures.length,
288
+ preflightFindings: cycle.preflightFindings.length,
289
+ sleepMs,
290
+ });
291
+ yield* waitForNextPoll(instance, target);
292
+ }).pipe(Effect.forever);
293
+ return { latest: Ref.get(latest), poll, run, hint: hints.offer };
294
+ })).pipe(Layer.provide(ItemHints.layer));
295
+ }
296
+ //# sourceMappingURL=polling.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"polling.js","sourceRoot":"","sources":["../../src/polling/polling.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,uBAAuB,EAAuB,MAAM,wBAAwB,CAAC;AACtF,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EACL,SAAS,GAGV,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,GAChC,MAAM,2CAA2C,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,qCAAqC,CAAC;AACvE,OAAO,EAAoB,SAAS,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC/F,OAAO,EACL,KAAK,EACL,OAAO,EACP,QAAQ,EACR,QAAQ,EACR,MAAM,EACN,KAAK,EACL,MAAM,EACN,GAAG,EACH,MAAM,EACN,MAAM,EACN,SAAS,GACV,MAAM,QAAQ,CAAC;AAChB,OAAO,EAAE,eAAe,EAA8B,MAAM,wBAAwB,CAAC;AACrF,OAAO,EAAqB,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAClF,OAAO,EAEL,YAAY,EACZ,SAAS,EAET,qBAAqB,EACrB,0BAA0B,GAC3B,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACtE,OAAO,EAAE,SAAS,EAAiB,MAAM,YAAY,CAAC;AAEtD,+EAA+E;AAC/E,MAAM,sBAAsB,GAAG,CAAC,CAAC;AAEjC,MAAM,gBAAgB,GAAG,CAAC,CAAC;AAE3B,MAAM,QAAQ,GAAG,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC,CAAC;AAGhF,MAAM,gBAAiB,SAAQ,MAAM,CAAC,KAAK,CACzC,sCAAsC,CACvC,CAAC;IACA,YAAY,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;IAC/B,MAAM,EAAE,UAAU;IAClB,cAAc,EAAE,MAAM,CAAC,gBAAgB,CAAC,SAAS,CAAC;IAClD,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;CACzD,CAAC;CAAG;AAkBL,MAAM,SAAS,GAAG,CAAC,UAAuB,EAAa,EAAE,CACvD,SAAS,CAAC,IAAI,CAAC,eAAe,uBAAuB,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AAE5E,MAAM,QAAQ,GAAG,CAAC,EAAE,IAAI,EAAgB,EAAY,EAAE,CACpD,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,EAAE,EAAE,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AAE/E,MAAM,mBAAmB,GAAG,CAC1B,QAAwB,EACxB,QAAqC,EACH,EAAE,CACpC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE;IACvC,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,CAC3B,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,KAAK,UAAU,IAAI,eAAe,CAAC,IAAI,CAAC,QAAQ,EAAE,UAAU,CAAC,CAC3F,CAAC;IACF,OAAO;QACL,UAAU;QACV,cAAc,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM;QACtC,KAAK;QACL,OAAO,EAAE,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,IAAI,EAAE;KACpC,CAAC;AACJ,CAAC,CAAC,CAAC;AAEL,MAAM,WAAW,GAAG,CAAC,IAA6B,EAAE,KAA8B,EAAW,EAAE,CAC7F,IAAI,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;AAEvF,yGAAyG;AACzG,MAAM,OAAO,eAAgB,SAAQ,OAAO,CAAC,OAAO,EAsBjD,CAAC,qCAAqC,CAAC;IACxC,MAAM,CAAU,KAAK,GAAG,KAAK,CAAC,MAAM,CAClC,eAAe,EACf,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;QAClB,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,WAAW,CAAC;QACnC,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,YAAY,CAAC;QACpC,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,aAAa,CAAC;QACpC,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,WAAW,CAAC;QACjC,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,EAAa,CAAC,CAAC;QACzD,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,SAAS,CAAC;QAC/B,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAE3C,MAAM,WAAW,GAAG,CAAC,OAAgC,EAAE,EAAE,CACvD,IAAI,gBAAgB,CAAC;YACnB,YAAY,EAAE,CAAC;YACf,MAAM,EAAE,UAAU,CAAC,KAAK;YACxB,cAAc,EAAE,MAAM,CAAC,IAAI,EAAE;YAC7B,OAAO;SACR,CAAC,CAAC;QAEL,MAAM,UAAU,GAAG,MAAM,CAAC,EAAE,CAAC,4BAA4B,CAAC,CAAC,QAAQ,CAAC,EAClE,OAA0B;YAE1B,KAAK,CAAC,CAAC,MAAM,CAAC,mBAAmB,CAAC,EAAE,UAAU,EAAE,OAAO,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC,CAAC;YAC3E,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,gBAAgB,CAAC,CAAC;YACpF,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC;gBAAE,OAAO,WAAW,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;YAC/D,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;gBACxD,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,+DAA+D,EAAE;oBACrF,UAAU,EAAE,OAAO,CAAC,UAAU,CAAC,IAAI;oBACnC,eAAe,EAAE,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM;oBAC5C,cAAc,EAAE,OAAO,CAAC,OAAO,CAAC,MAAM;iBACvC,CAAC,CAAC;gBACH,OAAO,WAAW,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;YACtC,CAAC;YACD,OAAO,MAAM,CAAC,KAAK,CAAC;QACtB,CAAC,CAAC,CAAC;QAEH,MAAM,WAAW,GAAG,MAAM,CAAC,EAAE,CAAC,6BAA6B,CAAC,CAAC,QAAQ,CAAC,EACpE,OAA0B,EAC1B,MAAwB;YAExB,KAAK,CAAC,CAAC,MAAM,CAAC,mBAAmB,CAAC,EAAE,UAAU,EAAE,OAAO,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC,CAAC;YAC3E,KAAK,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,gBAAgB,EAAE,MAAM,CAAC,CAAC;QAChF,CAAC,CAAC,CAAC;QAEH,MAAM,cAAc,GAAG,MAAM,CAAC,EAAE,CAAC,gCAAgC,CAAC,CAAC,QAAQ,CAAC,EAC1E,OAA0B;YAE1B,KAAK,CAAC,CAAC,MAAM,CAAC,mBAAmB,CAAC,EAAE,UAAU,EAAE,OAAO,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC,CAAC;YAC3E,MAAM,MAAM,GAAG,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC,MAAM,CACpD,CAAC,EAAE,UAAU,EAAE,EAAE,EAAE,CACjB,uBAAuB,CAAC,UAAU,CAAC;gBACnC,uBAAuB,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,CACnD,CAAC;YACF,MAAM,MAAM,GACV,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;YAChF,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC;gBACnB,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,sDAAsD,EAAE;oBAC5E,UAAU,EAAE,OAAO,CAAC,UAAU,CAAC,IAAI;oBACnC,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,OAAO,CAAC;iBAC5C,CAAC,CAAC;YACL,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,iBAAiB,CACxC,OAAO,CAAC,UAAU,CAAC,IAAI,EACvB,OAAO,CAAC,cAAc,EACtB,MAAM,CAAC,cAAc,CACtB,CAAC;YACF,KAAK,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;YACzC,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;gBAChC,sEAAsE;gBACtE,wDAAwD;gBACxD,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;gBAC/E,KAAK,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;gBAC1C,MAAM,UAAU,GAAG,IAAI,gBAAgB,CAAC;oBACtC,YAAY,EAAE,CAAC;oBACf,MAAM,EAAE,QAAQ,CAAC,MAAM;oBACvB,cAAc,EAAE,SAAS,CAAC,cAAc;oBACxC,OAAO,EAAE,OAAO,CAAC,OAAO;iBACzB,CAAC,CAAC;gBACH,MAAM,UAAU,GAAG,YAAY,CAAC,CAAC,QAAQ,CAAC,UAAU,EAAE,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC;gBAC7E,IAAI,QAAQ,CAAC,IAAI,KAAK,uBAAuB,EAAE,CAAC;oBAC9C,IAAI,SAAS,CAAC,gBAAgB,EAAE,CAAC;wBAC/B,KAAK,CAAC,CAAC,WAAW,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;oBAC1C,CAAC;oBACD,KAAK,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,4BAA4B,EAAE;wBACnD,UAAU,EAAE,OAAO,CAAC,UAAU,CAAC,IAAI;qBACpC,CAAC,CAAC;oBACH,OAAO;wBACL,YAAY,EAAE,CAAC;wBACf,WAAW,EAAE,EAAE;wBACf,WAAW,EAAE,CAAC;wBACd,QAAQ,EAAE,SAAS,CAAC,QAAQ;wBAC5B,iBAAiB,EAAE,SAAS,CAAC,iBAAiB;wBAC9C,UAAU;qBACe,CAAC;gBAC9B,CAAC;gBAED,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,oBAAoB,EAAE;oBAC1C,UAAU,EAAE,OAAO,CAAC,UAAU,CAAC,IAAI;oBACnC,YAAY,EAAE,QAAQ,CAAC,KAAK,CAAC,MAAM;oBACnC,OAAO,EAAE,QAAQ,CAAC,OAAO;iBAC1B,CAAC,CAAC;gBACH,MAAM,UAAU,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CACtC,QAAQ,CAAC,KAAK,EACd,CAAC,IAAI,EAAE,EAAE,CACP,WAAW,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,IAAI,CAC7C,MAAM,CAAC,OAAO,CAAC,CAAC,UAAU,EAAE,EAAE,CAC5B,YAAY,CAAC,OAAO,CAAC,UAAU,EAAE,OAAO,CAAC,KAAK,EAAE,UAAU,CAAC,CAC5D,CACF,EACH,EAAE,WAAW,EAAE,gBAAgB,EAAE,CAClC,CAAC;gBACF,mEAAmE;gBACnE,oEAAoE;gBACpE,+CAA+C;gBAC/C,KAAK,CAAC,CAAC,WAAW,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;gBACxC,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,gBAAgB,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;gBAC3E,OAAO;oBACL,YAAY,EAAE,QAAQ,CAAC,KAAK,CAAC,MAAM;oBACnC,WAAW,EAAE,UAAU,CAAC,OAAO,CAAC,CAAC,EAAE,WAAW,EAAE,EAAE,EAAE,CAAC,WAAW,CAAC;oBACjE,WAAW,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC,GAAG,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC;oBAC1E,QAAQ,EAAE,CAAC,GAAG,SAAS,CAAC,QAAQ,EAAE,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC;oBACpF,iBAAiB,EAAE,SAAS,CAAC,iBAAiB;oBAC9C,UAAU;iBACe,CAAC;YAC9B,CAAC,CAAC,CAAC,IAAI,CACL,MAAM,CAAC,QAAQ,CAAC,CAAC,KAAK,EAA8B,EAAE,CAAC,CAAC;gBACtD,IAAI,EAAE,4BAA4B;gBAClC,KAAK;gBACL,QAAQ,EAAE,SAAS,CAAC,QAAQ;gBAC5B,iBAAiB,EAAE,SAAS,CAAC,iBAAiB;gBAC9C,UAAU,EAAE,SAAS,CAAC,UAAU;aACjC,CAAC,CAAC,CACJ,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,qEAAqE;QACrE,0EAA0E;QAC1E,MAAM,kBAAkB,GAAG,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,EAE9C,CAAC,CAAC,IAAI,CACP,OAAO,CAAC,IAAI,CACV,YAAY,EACZ,YAAY,EACZ,gBAAgB,EAChB,aAAa,EACb,oBAAoB,EACpB,eAAe,EACf,+BAA+B,EAC/B,+BAA+B,EAC/B,SAAS,CACV,CACF,CAAC;QAEF,MAAM,IAAI,GAAG,MAAM,CAAC,EAAE,CAAC,sBAAsB,CAAC,CAC5C,QAAQ,CAAC,EAAE,QAAwB;YACjC,KAAK,CAAC,CAAC,KAAK,CAAC,YAAY,CAAC;YAC1B,MAAM,MAAM,GAAG,IAAI,GAAG,CACpB,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CACjF,CAAC;YACF,KAAK,MAAM,IAAI,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC;gBAClC,IAAI,IAAI,CAAC,OAAO,CAAC,EAAE,KAAK,UAAU,IAAI,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;oBAC5D,KAAK,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,+CAA+C,EAAE;wBACtE,IAAI,EAAE,IAAI,CAAC,IAAI;qBAChB,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;YACD,MAAM,QAAQ,GAAG,CAAC,KAAK,CAAC,CAAC,mBAAmB,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAC5D,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CACrC,CAAC;YACF,MAAM,OAAO,GAAG,mBAAmB,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;YACxD,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CACnC,OAAO,EACP,CAAC,UAAU,EAAE,EAAE,CACb,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAC5C,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,EAAE,UAAU,EAAE,MAAM,EAAE,CAAU,CAAC,CAC1D,EACH,EAAE,WAAW,EAAE,sBAAsB,EAAE,CACxC,CAAC;YAEF,MAAM,MAAM,GAA2B,EAAE,CAAC;YAC1C,MAAM,QAAQ,GAAiC,EAAE,CAAC;YAClD,MAAM,QAAQ,GAAuC,EAAE,CAAC;YACxD,MAAM,iBAAiB,GAAiC,EAAE,CAAC;YAC3D,KAAK,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,IAAI,OAAO,EAAE,CAAC;gBAC7C,IAAI,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC;oBAC7B,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;oBAC5B,iBAAiB,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;oBAC5D,SAAS;gBACX,CAAC;gBACD,MAAM,WAAW,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,KAAK,4BAA4B,CAAC;gBACzE,MAAM,KAAK,GAAwB,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC;gBACvF,IAAI,WAAW,EAAE,CAAC;oBAChB,QAAQ,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;oBAC1C,iBAAiB,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;oBAC5D,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;oBACzC,KAAK,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;gBAChD,CAAC;gBACD,IAAI,KAAK,CAAC,IAAI,KAAK,sBAAsB,EAAE,CAAC;oBAC1C,oEAAoE;oBACpE,KAAK,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,oDAAoD,EAAE;wBAC7E,UAAU,EAAE,UAAU,CAAC,UAAU,CAAC,IAAI;wBACtC,SAAS,EAAE,KAAK,CAAC,SAAS;wBAC1B,OAAO,EAAE,QAAQ,CAAC,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC;qBAC3C,CAAC,CAAC;oBACH,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;oBAC1C,KAAK,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;oBAC/C,SAAS;gBACX,CAAC;gBACD,KAAK,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,wDAAwD,EAAE;oBAC/E,UAAU,EAAE,UAAU,CAAC,UAAU,CAAC,IAAI;oBACtC,GAAG,0BAA0B,CAAC,KAAK,CAAC;iBACrC,CAAC,CAAC;gBACH,QAAQ,CAAC,IAAI,CACX,IAAI,qBAAqB,CAAC;oBACxB,UAAU,EAAE,UAAU,CAAC,UAAU,CAAC,IAAI;oBACtC,QAAQ,EAAE,KAAK,CAAC,IAAI;oBACpB,OAAO,EAAE,KAAK,CAAC,OAAO;iBACvB,CAAC,CACH,CAAC;YACJ,CAAC;YACD,MAAM,KAAK,GAAG,IAAI,SAAS,CAAC;gBAC1B,YAAY,EAAE,OAAO,CAAC,MAAM;gBAC5B,YAAY,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC,GAAG,GAAG,KAAK,CAAC,YAAY,EAAE,CAAC,CAAC;gBACxE,WAAW,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC,EAAE,WAAW,EAAE,EAAE,EAAE,CAAC,WAAW,CAAC;gBAC7D,WAAW,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC,GAAG,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC;gBACtE,QAAQ,EAAE,CAAC,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,QAAQ,CAAC,EAAE,GAAG,QAAQ,CAAC;gBAChF,iBAAiB;gBACjB,UAAU,EAAE,YAAY,CAAC,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC,UAAU,CAAC,EAAE,GAAG,QAAQ,CAAC,CAAC;aACvF,CAAC,CAAC;YACH,KAAK,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;YAC3C,OAAO,KAAK,CAAC;QACf,CAAC,EACD,MAAM,CAAC,cAAc,CAAC,kBAAkB,CAAC,EACzC,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,CACzB,CAAC;QAEF,MAAM,WAAW,GAAG,MAAM,CAAC,EAAE,CAAC,6BAA6B,CAAC,CAC1D,QAAQ,CAAC,EAAE,QAAwB,EAAE,IAAc;YACjD,KAAK,CAAC,CAAC,MAAM,CAAC,mBAAmB,CAAC;gBAChC,UAAU,EAAE,IAAI,CAAC,UAAU;gBAC3B,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM;aACvB,CAAC,CAAC;YACH,KAAK,CAAC,CAAC,KAAK,CAAC,YAAY,CAAC;YAC1B,MAAM,MAAM,GAAG,IAAI,GAAG,CACpB,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CACjF,CAAC;YACF,MAAM,QAAQ,GAAG,CAAC,KAAK,CAAC,CAAC,mBAAmB,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAC5D,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CACrC,CAAC;YACF,MAAM,OAAO,GAAG,mBAAmB,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,IAAI,CAC1D,CAAC,EAAE,UAAU,EAAE,EAAE,EAAE,CACjB,uBAAuB,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,uBAAuB,CAAC,IAAI,CAAC,UAAU,CAAC,CACxF,CAAC;YACF,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;gBAC1B,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,qDAAqD,EAAE;oBAC3E,UAAU,EAAE,IAAI,CAAC,UAAU;oBAC3B,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM;iBACvB,CAAC,CAAC;gBACH,OAAO;YACT,CAAC;YACD,oEAAoE;YACpE,yEAAyE;YACzE,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,WAAW,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;YACxE,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,YAAY,CAAC,OAAO,CAAC,UAAU,EAAE,OAAO,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;YAChF,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,oCAAoC,EAAE;gBAC1D,UAAU,EAAE,IAAI,CAAC,UAAU;gBAC3B,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM;gBACtB,WAAW,EAAE,MAAM,CAAC,WAAW,CAAC,MAAM;gBACtC,WAAW,EAAE,MAAM,CAAC,WAAW;gBAC/B,QAAQ,EAAE,MAAM,CAAC,QAAQ,CAAC,MAAM;aACjC,CAAC,CAAC;QACL,CAAC,EACD,MAAM,CAAC,cAAc,CAAC,kBAAkB,CAAC,EACzC,CAAC,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,CAC1B,MAAM,CAAC,IAAI,CACT,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CACrB,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;YAClB,IAAI,KAAK,CAAC,IAAI,KAAK,sBAAsB;gBACvC,KAAK,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;YACjD,KAAK,CAAC,CAAC,MAAM,CAAC,UAAU,CACtB,4DAA4D,EAC5D;gBACE,UAAU,EAAE,IAAI,CAAC,UAAU;gBAC3B,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM;gBACtB,GAAG,0BAA0B,CAAC,KAAK,CAAC;aACrC,CACF,CAAC;QACJ,CAAC,CAAC,CACH,EACD,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,CACzB,CACJ,CAAC;QAEF,MAAM,eAAe,GAAG,CAAC,QAAwB,EAAE,MAAc,EAAE,EAAE,CACnE,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;YAClB,OAAO,IAAI,EAAE,CAAC;gBACZ,MAAM,SAAS,GAAG,MAAM,GAAG,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;gBAC5D,IAAI,SAAS,IAAI,CAAC;oBAAE,OAAO;gBAC3B,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,SAAS,CAClC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,EACxC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,EAAY,CAAC,CAAC,CAClF,CAAC;gBACF,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC;oBAAE,OAAO;gBAChC,KAAK,CAAC,CAAC,WAAW,CAAC,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;YAC3C,CAAC;QACH,CAAC,CAAC,CAAC;QAEL,0EAA0E;QAC1E,sDAAsD;QACtD,MAAM,GAAG,GAAG,CAAC,QAAwB,EAAwB,EAAE,CAC7D,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;YAClB,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,KAAK,CAAC,iBAAiB,CAAC;YACjD,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;YACpD,IAAI,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC7B,MAAM,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,YAAY,GAAG,KAAK,CAAC;gBAC9D,KAAK,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,wDAAwD,EAAE;oBAC/E,QAAQ,EAAE,MAAM,CAAC,OAAO,CAAC,IAAI;oBAC7B,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,OAAO;oBAC/B,SAAS,EAAE,MAAM,CAAC,OAAO,CAAC,SAAS;oBACnC,OAAO;iBACR,CAAC,CAAC;gBACH,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;gBAC9C,OAAO;YACT,CAAC;YACD,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC;YAC7B,MAAM,UAAU,GAAG,SAAS,GAAG,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,YAAY,GAAG,KAAK,CAAC;YAC7E,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,UAAU,EAAE;gBAC5C,MAAM,EAAE,GAAG,EAAE,CAAC,UAAU;gBACxB,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;aACvE,CAAC,CAAC;YACH,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,KAAK,CAAC,iBAAiB,CAAC;YAC3C,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,GAAG,GAAG,CAAC,CAAC;YAC1C,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,qBAAqB,EAAE;gBAC3C,YAAY,EAAE,KAAK,CAAC,YAAY;gBAChC,YAAY,EAAE,KAAK,CAAC,YAAY;gBAChC,WAAW,EAAE,KAAK,CAAC,WAAW,CAAC,MAAM;gBACrC,WAAW,EAAE,KAAK,CAAC,WAAW;gBAC9B,QAAQ,EAAE,KAAK,CAAC,QAAQ,CAAC,MAAM;gBAC/B,iBAAiB,EAAE,KAAK,CAAC,iBAAiB,CAAC,MAAM;gBACjD,OAAO;aACR,CAAC,CAAC;YACH,KAAK,CAAC,CAAC,eAAe,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QAC3C,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAE1B,OAAO,EAAE,MAAM,EAAE,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC;IACnE,CAAC,CAAC,CACH,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;CACxC"}
@@ -0,0 +1,45 @@
1
+ import type { DeclaredLabel } from "@usine/config/label";
2
+ import { CycleGeneration } from "@usine/core/cycle-budget";
3
+ import { CycleBudgets } from "@usine/engine/cycle-budget";
4
+ import { ItemProjection, ItemProjectionWriter } from "@usine/engine/item-projection";
5
+ import { RepositoryLabelProjectionReader, RepositoryLabelProjectionWriter } from "@usine/engine/repository-label-projection";
6
+ import { GitHubPolling } from "@usine/github/polling";
7
+ import { DateTime, Effect, Option, Schema } from "effect";
8
+ import { LabelReconciler } from "../label-reconciler.ts";
9
+ import { type InterruptedRepositoryCycle, RepositoryPollFailure } from "./cycle.ts";
10
+ /**
11
+ * Identifies one GitHub issue or pull request across its changing snapshots.
12
+ * Encoding uses the canonical repository name and Item number; decoding lets
13
+ * Board consumers locate the Item associated with a Run. Schedule Runs identify
14
+ * the repository alone and do not decode as an Item.
15
+ */
16
+ export declare const GitHubItemKey: Schema.compose<Schema.fromJsonString<Schema.Tuple<readonly [Schema.Literal<"github">, Schema.brand<Schema.String, "RepositoryName">, Schema.brand<Schema.Int, "ItemNumber">]>>, Schema.toType<Schema.brand<Schema.NonEmptyString, "ItemKey">>>;
17
+ /**
18
+ * Refreshes and reconciles one repository's Board label catalog before change
19
+ * detection. Pass the catalog ETag from its stored poll cursor; the result gives
20
+ * the ETag to persist after Item processing, plus preflight findings and backoff.
21
+ * Failed catalog requests retain the stored projection and defer provisioning;
22
+ * persistence failures stop the repository for retry.
23
+ */
24
+ export declare const synchronizeLabels: (repository: string & import("effect/Brand").Brand<"RepositoryName">, declared: readonly DeclaredLabel[], entityTag: Option.Option<string & import("effect/Brand").Brand<"GitHubEntityTag">>) => Effect.Effect<{
25
+ labelEntityTag: Option.None<string & import("effect/Brand").Brand<"GitHubEntityTag">> | Option.Some<string & import("effect/Brand").Brand<"GitHubEntityTag">>;
26
+ entityTagChanged: boolean;
27
+ failures: never[] | RepositoryPollFailure[];
28
+ preflightFindings: readonly import("../label-reconciler.ts").LabelPreflightFinding[];
29
+ nextPollAt: Option.Option<DateTime.Utc>;
30
+ }, import("@usine/engine/engine").EnginePersistenceError | InterruptedRepositoryCycle, GitHubPolling | LabelReconciler | RepositoryLabelProjectionReader | RepositoryLabelProjectionWriter>;
31
+ /** A fetched snapshot paired with the allowance observed before its request began. */
32
+ export interface ObservedItem {
33
+ readonly projection: ItemProjection;
34
+ readonly cycleGeneration: CycleGeneration;
35
+ }
36
+ /**
37
+ * Fetches a detected Item and durably updates its Board projection regardless of
38
+ * whether any Loop applies. Evaluation uses the returned projection's snapshot,
39
+ * identity and content hash, so Board observation and Run decisions agree.
40
+ */
41
+ export declare const observeItem: (repository: string & import("effect/Brand").Brand<"RepositoryName">, changed: import("@usine/github/polling").ChangedIssue | import("@usine/github/polling").ChangedPullRequest) => Effect.Effect<{
42
+ projection: ItemProjection;
43
+ cycleGeneration: number & import("effect/Brand").Brand<"CycleGeneration">;
44
+ }, import("@usine/github/github-app").AppPermissionError | import("@usine/engine/engine").EnginePersistenceError | import("@usine/github/github-app").GitHubApiError | import("@usine/github/github-app").GitHubRateLimitError | import("@usine/github/github-app").InstallationDiscoveryError | import("@usine/github/github-app").InvalidGitHubResponseError, CycleBudgets | GitHubPolling | ItemProjectionWriter>;
45
+ //# sourceMappingURL=repository-sync.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"repository-sync.d.ts","sourceRoot":"","sources":["../../src/polling/repository-sync.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAG1D,OAAO,EAEL,cAAc,EAEd,oBAAoB,EACrB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAGL,+BAA+B,EAC/B,+BAA+B,EAChC,MAAM,2CAA2C,CAAC;AAEnD,OAAO,EAGL,aAAa,EAGd,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAU,MAAM,EAAE,MAAM,QAAQ,CAAC;AAClE,OAAO,EAA4B,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACnF,OAAO,EACL,KAAK,0BAA0B,EAE/B,qBAAqB,EAEtB,MAAM,YAAY,CAAC;AAEpB;;;;;GAKG;AACH,eAAO,MAAM,aAAa,gPAIzB,CAAC;AA8GF;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB;;;;;;2LAwC5B,CAAC;AAEH,sFAAsF;AACtF,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,UAAU,EAAE,cAAc,CAAC;IACpC,QAAQ,CAAC,eAAe,EAAE,eAAe,CAAC;CAC3C;AAED;;;;GAIG;AACH,eAAO,MAAM,WAAW;;;oZA+BtB,CAAC"}
@@ -0,0 +1,169 @@
1
+ import { CycleGeneration } from "@usine/core/cycle-budget";
2
+ import { CycleBudgets } from "@usine/engine/cycle-budget";
3
+ import { ItemKey, ItemNumber } from "@usine/core/item";
4
+ import { RepositoryName, canonicalRepositoryName } from "@usine/core/repository";
5
+ import { ItemContentHash, ItemProjection, ItemProjectionSource, ItemProjectionWriter, } from "@usine/engine/item-projection";
6
+ import { RepositoryLabel, RepositoryLabelProjection, RepositoryLabelProjectionReader, RepositoryLabelProjectionWriter, } from "@usine/engine/repository-label-projection";
7
+ import { EntityTag, GitHubPolling, RepositoryLabelCatalog, } from "@usine/github/polling";
8
+ import { DateTime, Effect, Option, Result, Schema } from "effect";
9
+ import { LabelReconciler } from "../label-reconciler.js";
10
+ import { latestPollAt, RepositoryPollFailure, repositoryFailureLogFields, } from "./cycle.js";
11
+ /**
12
+ * Identifies one GitHub issue or pull request across its changing snapshots.
13
+ * Encoding uses the canonical repository name and Item number; decoding lets
14
+ * Board consumers locate the Item associated with a Run. Schedule Runs identify
15
+ * the repository alone and do not decode as an Item.
16
+ */
17
+ export const GitHubItemKey = Schema.toType(ItemKey).pipe(Schema.decodeTo(Schema.fromJsonString(Schema.Tuple([Schema.Literal("github"), RepositoryName, ItemNumber]))));
18
+ // `toType` preserves the ItemKey brand on the encoded side, so the encoder
19
+ // produces the identity accepted by both the Board projection and Run engine.
20
+ const encodeGitHubItemKey = Schema.encodeSync(GitHubItemKey);
21
+ /** The reconciliation result when the cycle had no confirmed catalog to compare against. */
22
+ const DEFERRED_RECONCILIATION = {
23
+ labels: [],
24
+ findings: [],
25
+ catalogChanged: false,
26
+ nextPollAt: Option.none(),
27
+ };
28
+ /**
29
+ * Refreshes the stored label catalog that the Board and the label
30
+ * preflight read. A failed request keeps the stored catalog and ETag and
31
+ * defers provisioning; trigger evaluation runs from the change poll alone.
32
+ */
33
+ const applyLabelCatalog = Effect.fn("PollingTriggers.applyLabelCatalog")(function* (repository, labelEntityTag, result) {
34
+ yield* Effect.annotateCurrentSpan({ repository });
35
+ const repositoryLabelReader = yield* RepositoryLabelProjectionReader;
36
+ const repositoryLabelWriter = yield* RepositoryLabelProjectionWriter;
37
+ const unchanged = {
38
+ labelEntityTag,
39
+ entityTagChanged: false,
40
+ confirmedLabels: Option.none(),
41
+ failures: [],
42
+ nextPollAt: Option.none(),
43
+ };
44
+ if (Result.isFailure(result)) {
45
+ const error = result.failure;
46
+ if (error._tag === "GitHubRateLimitError") {
47
+ yield* Effect.logWarning("Label catalog rate-limited; kept the stored catalog and deferred label provisioning", {
48
+ repository,
49
+ operation: error.operation,
50
+ retryAt: DateTime.formatIso(error.retryAt),
51
+ });
52
+ return { ...unchanged, nextPollAt: Option.some(error.retryAt) };
53
+ }
54
+ yield* Effect.logError("Label catalog request failed; kept the stored catalog, deferred label provisioning, and evaluated items anyway", {
55
+ repository,
56
+ ...repositoryFailureLogFields(error),
57
+ });
58
+ return {
59
+ ...unchanged,
60
+ failures: [
61
+ new RepositoryPollFailure({
62
+ repository,
63
+ errorTag: error._tag,
64
+ message: error.message,
65
+ }),
66
+ ],
67
+ };
68
+ }
69
+ const detection = result.success;
70
+ if (!(detection instanceof RepositoryLabelCatalog)) {
71
+ const projection = yield* repositoryLabelReader.get(repository);
72
+ if (Option.isNone(projection)) {
73
+ // The ETag vouches for a projection that is no longer stored, so drop
74
+ // it and fetch the catalog in full next cycle.
75
+ yield* Effect.logWarning("Repository label catalog unchanged (304) but its projection is missing; refetching next cycle and deferring label provisioning", { repository });
76
+ return { ...unchanged, labelEntityTag: Option.none(), entityTagChanged: true };
77
+ }
78
+ yield* Effect.logDebug("Repository label catalog unchanged (304)", {
79
+ repository,
80
+ });
81
+ return { ...unchanged, confirmedLabels: Option.some(projection.value.labels) };
82
+ }
83
+ const labels = detection.labels.map(({ name, color, description }) => new RepositoryLabel({ name, color: Option.some(color), description }));
84
+ yield* repositoryLabelWriter.replace(new RepositoryLabelProjection({ repository, labels }));
85
+ return {
86
+ ...unchanged,
87
+ labelEntityTag: detection.entityTag,
88
+ entityTagChanged: true,
89
+ confirmedLabels: Option.some(labels),
90
+ };
91
+ });
92
+ /**
93
+ * Refreshes and reconciles one repository's Board label catalog before change
94
+ * detection. Pass the catalog ETag from its stored poll cursor; the result gives
95
+ * the ETag to persist after Item processing, plus preflight findings and backoff.
96
+ * Failed catalog requests retain the stored projection and defer provisioning;
97
+ * persistence failures stop the repository for retry.
98
+ */
99
+ export const synchronizeLabels = Effect.fn("PollingTriggers.synchronizeLabels")(function* (repository, declared, entityTag) {
100
+ yield* Effect.annotateCurrentSpan({ repository });
101
+ const github = yield* GitHubPolling;
102
+ const labelReconciler = yield* LabelReconciler;
103
+ const repositoryLabelWriter = yield* RepositoryLabelProjectionWriter;
104
+ const result = yield* Effect.result(github.labels(repository, entityTag));
105
+ const catalog = yield* applyLabelCatalog(repository, entityTag, result);
106
+ const reconciliation = yield* Option.match(catalog.confirmedLabels, {
107
+ onNone: () => Effect.succeed(DEFERRED_RECONCILIATION),
108
+ onSome: (confirmed) => labelReconciler.reconcile(repository, declared, confirmed),
109
+ });
110
+ const preflight = {
111
+ labelEntityTag: reconciliation.catalogChanged
112
+ ? Option.none()
113
+ : catalog.labelEntityTag,
114
+ entityTagChanged: catalog.entityTagChanged || reconciliation.catalogChanged,
115
+ failures: catalog.failures,
116
+ preflightFindings: reconciliation.findings,
117
+ nextPollAt: latestPollAt([catalog.nextPollAt, reconciliation.nextPollAt]),
118
+ };
119
+ if (reconciliation.catalogChanged) {
120
+ yield* repositoryLabelWriter
121
+ .replace(new RepositoryLabelProjection({ repository, labels: reconciliation.labels }))
122
+ .pipe(
123
+ // Provisioning may have reported failures before projection storage
124
+ // fails. Preserve those findings just as for a later Item failure.
125
+ Effect.mapError((error) => ({
126
+ _tag: "InterruptedRepositoryCycle",
127
+ error,
128
+ failures: preflight.failures,
129
+ preflightFindings: preflight.preflightFindings,
130
+ nextPollAt: preflight.nextPollAt,
131
+ })));
132
+ }
133
+ return preflight;
134
+ });
135
+ /**
136
+ * Fetches a detected Item and durably updates its Board projection regardless of
137
+ * whether any Loop applies. Evaluation uses the returned projection's snapshot,
138
+ * identity and content hash, so Board observation and Run decisions agree.
139
+ */
140
+ export const observeItem = Effect.fn("PollingTriggers.observeItem")(function* (repository, changed) {
141
+ yield* Effect.annotateCurrentSpan({ repository, item: changed.number });
142
+ const github = yield* GitHubPolling;
143
+ const items = yield* ItemProjectionWriter;
144
+ const budgets = yield* CycleBudgets;
145
+ const itemKey = encodeGitHubItemKey([
146
+ "github",
147
+ RepositoryName.make(canonicalRepositoryName(repository)),
148
+ ItemNumber.make(changed.number),
149
+ ]);
150
+ const cycleGeneration = yield* budgets.generation(itemKey);
151
+ const snapshot = yield* github.snapshot(repository, changed);
152
+ const projection = new ItemProjection({
153
+ itemKey,
154
+ repository,
155
+ source: ItemProjectionSource.make(changed._tag === "ChangedIssue" ? "issue" : "pr"),
156
+ number: ItemNumber.make(changed.number),
157
+ contentHash: ItemContentHash.make(snapshot.contentHash),
158
+ payload: snapshot.payload,
159
+ });
160
+ yield* items.upsert(projection);
161
+ yield* Effect.logDebug("Fetched changed-item snapshot", {
162
+ repository,
163
+ item: projection.number,
164
+ stream: projection.source,
165
+ contentHash: projection.contentHash,
166
+ });
167
+ return { projection, cycleGeneration };
168
+ });
169
+ //# sourceMappingURL=repository-sync.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"repository-sync.js","sourceRoot":"","sources":["../../src/polling/repository-sync.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACjF,OAAO,EACL,eAAe,EACf,cAAc,EACd,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EACL,eAAe,EACf,yBAAyB,EACzB,+BAA+B,EAC/B,+BAA+B,GAChC,MAAM,2CAA2C,CAAC;AAEnD,OAAO,EAEL,SAAS,EACT,aAAa,EACb,sBAAsB,GAEvB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAClE,OAAO,EAA4B,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACnF,OAAO,EAEL,YAAY,EACZ,qBAAqB,EACrB,0BAA0B,GAC3B,MAAM,YAAY,CAAC;AAEpB;;;;;GAKG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CACtD,MAAM,CAAC,QAAQ,CACb,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,cAAc,EAAE,UAAU,CAAC,CAAC,CAAC,CAC5F,CACF,CAAC;AACF,2EAA2E;AAC3E,8EAA8E;AAC9E,MAAM,mBAAmB,GAAG,MAAM,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;AAkB7D,4FAA4F;AAC5F,MAAM,uBAAuB,GAAwB;IACnD,MAAM,EAAE,EAAE;IACV,QAAQ,EAAE,EAAE;IACZ,cAAc,EAAE,KAAK;IACrB,UAAU,EAAE,MAAM,CAAC,IAAI,EAAE;CAC1B,CAAC;AAEF;;;;GAIG;AACH,MAAM,iBAAiB,GAAG,MAAM,CAAC,EAAE,CAAC,mCAAmC,CAAC,CAAC,QAAQ,CAAC,EAChF,UAA0B,EAC1B,cAAwC,EACxC,MAA+D;IAE/D,KAAK,CAAC,CAAC,MAAM,CAAC,mBAAmB,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC;IAClD,MAAM,qBAAqB,GAAG,KAAK,CAAC,CAAC,+BAA+B,CAAC;IACrE,MAAM,qBAAqB,GAAG,KAAK,CAAC,CAAC,+BAA+B,CAAC;IACrE,MAAM,SAAS,GAAG;QAChB,cAAc;QACd,gBAAgB,EAAE,KAAK;QACvB,eAAe,EAAE,MAAM,CAAC,IAAI,EAAE;QAC9B,QAAQ,EAAE,EAAE;QACZ,UAAU,EAAE,MAAM,CAAC,IAAI,EAAE;KACE,CAAC;IAC9B,IAAI,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC;QAC7B,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC;QAC7B,IAAI,KAAK,CAAC,IAAI,KAAK,sBAAsB,EAAE,CAAC;YAC1C,KAAK,CAAC,CAAC,MAAM,CAAC,UAAU,CACtB,qFAAqF,EACrF;gBACE,UAAU;gBACV,SAAS,EAAE,KAAK,CAAC,SAAS;gBAC1B,OAAO,EAAE,QAAQ,CAAC,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC;aAC3C,CACF,CAAC;YACF,OAAO,EAAE,GAAG,SAAS,EAAE,UAAU,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC;QAClE,CAAC;QACD,KAAK,CAAC,CAAC,MAAM,CAAC,QAAQ,CACpB,gHAAgH,EAChH;YACE,UAAU;YACV,GAAG,0BAA0B,CAAC,KAAK,CAAC;SACrC,CACF,CAAC;QACF,OAAO;YACL,GAAG,SAAS;YACZ,QAAQ,EAAE;gBACR,IAAI,qBAAqB,CAAC;oBACxB,UAAU;oBACV,QAAQ,EAAE,KAAK,CAAC,IAAI;oBACpB,OAAO,EAAE,KAAK,CAAC,OAAO;iBACvB,CAAC;aACH;SACF,CAAC;IACJ,CAAC;IACD,MAAM,SAAS,GAAG,MAAM,CAAC,OAAO,CAAC;IACjC,IAAI,CAAC,CAAC,SAAS,YAAY,sBAAsB,CAAC,EAAE,CAAC;QACnD,MAAM,UAAU,GAAG,KAAK,CAAC,CAAC,qBAAqB,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QAChE,IAAI,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC;YAC9B,sEAAsE;YACtE,+CAA+C;YAC/C,KAAK,CAAC,CAAC,MAAM,CAAC,UAAU,CACtB,gIAAgI,EAChI,EAAE,UAAU,EAAE,CACf,CAAC;YACF,OAAO,EAAE,GAAG,SAAS,EAAE,cAAc,EAAE,MAAM,CAAC,IAAI,EAAE,EAAE,gBAAgB,EAAE,IAAI,EAAE,CAAC;QACjF,CAAC;QACD,KAAK,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,0CAA0C,EAAE;YACjE,UAAU;SACX,CAAC,CAAC;QACH,OAAO,EAAE,GAAG,SAAS,EAAE,eAAe,EAAE,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC;IACjF,CAAC;IACD,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC,GAAG,CACjC,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,WAAW,EAAE,EAAE,EAAE,CAC/B,IAAI,eAAe,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,WAAW,EAAE,CAAC,CACxE,CAAC;IACF,KAAK,CAAC,CAAC,qBAAqB,CAAC,OAAO,CAAC,IAAI,yBAAyB,CAAC,EAAE,UAAU,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC;IAC5F,OAAO;QACL,GAAG,SAAS;QACZ,cAAc,EAAE,SAAS,CAAC,SAAS;QACnC,gBAAgB,EAAE,IAAI;QACtB,eAAe,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC;KACrC,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,MAAM,CAAC,EAAE,CAAC,mCAAmC,CAAC,CAAC,QAAQ,CAAC,EACvF,UAA0B,EAC1B,QAAsC,EACtC,SAAmC;IAEnC,KAAK,CAAC,CAAC,MAAM,CAAC,mBAAmB,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC;IAClD,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,aAAa,CAAC;IACpC,MAAM,eAAe,GAAG,KAAK,CAAC,CAAC,eAAe,CAAC;IAC/C,MAAM,qBAAqB,GAAG,KAAK,CAAC,CAAC,+BAA+B,CAAC;IACrE,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC,CAAC;IAC1E,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,iBAAiB,CAAC,UAAU,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;IACxE,MAAM,cAAc,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,eAAe,EAAE;QAClE,MAAM,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,uBAAuB,CAAC;QACrD,MAAM,EAAE,CAAC,SAAS,EAAE,EAAE,CAAC,eAAe,CAAC,SAAS,CAAC,UAAU,EAAE,QAAQ,EAAE,SAAS,CAAC;KAClF,CAAC,CAAC;IACH,MAAM,SAAS,GAAG;QAChB,cAAc,EAAE,cAAc,CAAC,cAAc;YAC3C,CAAC,CAAC,MAAM,CAAC,IAAI,EAAa;YAC1B,CAAC,CAAC,OAAO,CAAC,cAAc;QAC1B,gBAAgB,EAAE,OAAO,CAAC,gBAAgB,IAAI,cAAc,CAAC,cAAc;QAC3E,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,iBAAiB,EAAE,cAAc,CAAC,QAAQ;QAC1C,UAAU,EAAE,YAAY,CAAC,CAAC,OAAO,CAAC,UAAU,EAAE,cAAc,CAAC,UAAU,CAAC,CAAC;KAC1E,CAAC;IACF,IAAI,cAAc,CAAC,cAAc,EAAE,CAAC;QAClC,KAAK,CAAC,CAAC,qBAAqB;aACzB,OAAO,CAAC,IAAI,yBAAyB,CAAC,EAAE,UAAU,EAAE,MAAM,EAAE,cAAc,CAAC,MAAM,EAAE,CAAC,CAAC;aACrF,IAAI;QACH,oEAAoE;QACpE,mEAAmE;QACnE,MAAM,CAAC,QAAQ,CAAC,CAAC,KAAK,EAA8B,EAAE,CAAC,CAAC;YACtD,IAAI,EAAE,4BAA4B;YAClC,KAAK;YACL,QAAQ,EAAE,SAAS,CAAC,QAAQ;YAC5B,iBAAiB,EAAE,SAAS,CAAC,iBAAiB;YAC9C,UAAU,EAAE,SAAS,CAAC,UAAU;SACjC,CAAC,CAAC,CACJ,CAAC;IACN,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC,CAAC,CAAC;AAQH;;;;GAIG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,MAAM,CAAC,EAAE,CAAC,6BAA6B,CAAC,CAAC,QAAQ,CAAC,EAC3E,UAA0B,EAC1B,OAAoB;IAEpB,KAAK,CAAC,CAAC,MAAM,CAAC,mBAAmB,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IACxE,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,aAAa,CAAC;IACpC,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,oBAAoB,CAAC;IAC1C,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,YAAY,CAAC;IACpC,MAAM,OAAO,GAAG,mBAAmB,CAAC;QAClC,QAAQ;QACR,cAAc,CAAC,IAAI,CAAC,uBAAuB,CAAC,UAAU,CAAC,CAAC;QACxD,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC;KAChC,CAAC,CAAC;IACH,MAAM,eAAe,GAAG,KAAK,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;IAC3D,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;IAC7D,MAAM,UAAU,GAAG,IAAI,cAAc,CAAC;QACpC,OAAO;QACP,UAAU;QACV,MAAM,EAAE,oBAAoB,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,KAAK,cAAc,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;QACnF,MAAM,EAAE,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC;QACvC,WAAW,EAAE,eAAe,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC;QACvD,OAAO,EAAE,QAAQ,CAAC,OAAO;KAC1B,CAAC,CAAC;IACH,KAAK,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IAChC,KAAK,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,+BAA+B,EAAE;QACtD,UAAU;QACV,IAAI,EAAE,UAAU,CAAC,MAAM;QACvB,MAAM,EAAE,UAAU,CAAC,MAAM;QACzB,WAAW,EAAE,UAAU,CAAC,WAAW;KACpC,CAAC,CAAC;IACH,OAAO,EAAE,UAAU,EAAE,eAAe,EAAyB,CAAC;AAChE,CAAC,CAAC,CAAC"}
@@ -1,40 +1,4 @@
1
- import { ConfigParser, type LoadedInstance } from "@usine/config";
2
- import { CursorStore, type EnginePersistenceError, ItemProjectionWriter, LoopControl, RepositoryLabelProjectionWriter, RunEngine } from "@usine/engine";
3
- import { ExpressionEngine } from "@usine/expression";
4
- import { GitHubPolling } from "@usine/github";
5
- import { Context, Effect, Layer, Option, Schema } from "effect";
6
- declare const RepositoryPollFailure_base: Schema.Class<RepositoryPollFailure, Schema.Struct<{
7
- readonly repository: Schema.brand<Schema.String, "RepoName">;
8
- readonly errorTag: Schema.NonEmptyString;
9
- readonly message: Schema.String;
10
- }>, {}>;
11
- /** One repository whose cycle ended in a typed error; siblings were unaffected. */
12
- export declare class RepositoryPollFailure extends RepositoryPollFailure_base {
13
- }
14
- declare const PollCycle_base: Schema.Class<PollCycle, Schema.Struct<{
15
- readonly repositories: Schema.Int;
16
- readonly changedItems: Schema.Int;
17
- readonly submissions: Schema.$Array<Schema.Union<readonly [typeof import("@usine/engine").Claimed, typeof import("@usine/engine").Queued, typeof import("@usine/engine").Ignored]>>;
18
- /** Run ids actually revoked because their item stopped matching. */
19
- readonly revokedRuns: Schema.Int;
20
- readonly failures: Schema.$Array<typeof RepositoryPollFailure>;
21
- readonly nextPollAt: Schema.Option<Schema.DateTimeUtc>;
22
- }>, {}>;
23
- export declare class PollCycle extends PollCycle_base {
24
- }
25
- declare const PollingTriggers_base: Context.ServiceClass<PollingTriggers, "@usine/orchestrator/PollingTriggers", {
26
- /**
27
- * One cycle over every watched repository. Per-repository failures are
28
- * isolated, logged, and reported on the cycle — one bad repository never
29
- * stops its siblings, and only a defect stops the loop.
30
- */
31
- readonly poll: (instance: LoadedInstance) => Effect.Effect<PollCycle, EnginePersistenceError>;
32
- readonly run: (instance: LoadedInstance) => Effect.Effect<never>;
33
- readonly latest: Effect.Effect<Option.Option<PollCycle>>;
34
- }>;
35
- /** Full selector-pruned GitHub change → snapshot → CEL → Event composition. */
36
- export declare class PollingTriggers extends PollingTriggers_base {
37
- static readonly layer: Layer.Layer<PollingTriggers, never, ConfigParser | CursorStore | ExpressionEngine | GitHubPolling | ItemProjectionWriter | LoopControl | RepositoryLabelProjectionWriter | RunEngine>;
38
- }
39
- export {};
1
+ export { PollingTriggers } from "./polling/polling.ts";
2
+ export { PollCycle, RepositoryPollFailure } from "./polling/cycle.ts";
3
+ export { GitHubItemKey } from "./polling/repository-sync.ts";
40
4
  //# sourceMappingURL=polling-triggers.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"polling-triggers.d.ts","sourceRoot":"","sources":["../src/polling-triggers.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EAGZ,KAAK,cAAc,EAKpB,MAAM,eAAe,CAAC;AAEvB,OAAO,EAEL,WAAW,EACX,KAAK,sBAAsB,EAK3B,oBAAoB,EACpB,WAAW,EAEX,+BAA+B,EAC/B,SAAS,EAGV,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,gBAAgB,EAAwB,MAAM,mBAAmB,CAAC;AAC3E,OAAO,EACL,aAAa,EAQd,MAAM,eAAe,CAAC;AACvB,OAAO,EAEL,OAAO,EAGP,MAAM,EACN,KAAK,EACL,MAAM,EAGN,MAAM,EACP,MAAM,QAAQ,CAAC;;;;;;AA0BhB,mFAAmF;AACnF,qBAAa,qBAAsB,SAAQ,0BAMzC;CAAG;;;;;IAMH,oEAAoE;;;;;AAJtE,qBAAa,SAAU,SAAQ,cAQ7B;CAAG;;IAsGD;;;;OAIG;mBACY,CAAC,QAAQ,EAAE,cAAc,KAAK,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,sBAAsB,CAAC;kBAC/E,CAAC,QAAQ,EAAE,cAAc,KAAK,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC;qBAC/C,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;;AAX5D,+EAA+E;AAC/E,qBAAa,eAAgB,SAAQ,oBAYK;IACxC,MAAM,CAAC,QAAQ,CAAC,KAAK,wLAmYnB;CACH"}
1
+ {"version":3,"file":"polling-triggers.d.ts","sourceRoot":"","sources":["../src/polling-triggers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,SAAS,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AACtE,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC"}