@usine/engine 0.1.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +39 -12
- package/dist/cursor/{store.d.ts → cursor.d.ts} +9 -7
- package/dist/cursor/cursor.d.ts.map +1 -0
- package/dist/cursor/{store.js → cursor.js} +8 -7
- package/dist/cursor/cursor.js.map +1 -0
- package/dist/cycle-budget/cycle-budget.d.ts +25 -0
- package/dist/cycle-budget/cycle-budget.d.ts.map +1 -0
- package/dist/cycle-budget/cycle-budget.js +117 -0
- package/dist/cycle-budget/cycle-budget.js.map +1 -0
- package/dist/cycle-budget/model.d.ts +26 -0
- package/dist/cycle-budget/model.d.ts.map +1 -0
- package/dist/cycle-budget/model.js +20 -0
- package/dist/cycle-budget/model.js.map +1 -0
- package/dist/cycle-budget/queries.d.ts +27 -0
- package/dist/cycle-budget/queries.d.ts.map +1 -0
- package/dist/cycle-budget/queries.js +175 -0
- package/dist/cycle-budget/queries.js.map +1 -0
- package/dist/database/database.d.ts +1 -1
- package/dist/database/database.d.ts.map +1 -1
- package/dist/database/local-sqlite.d.ts +32 -12
- package/dist/database/local-sqlite.d.ts.map +1 -1
- package/dist/database/local-sqlite.js +121 -16
- package/dist/database/local-sqlite.js.map +1 -1
- package/dist/database/schema.d.ts +302 -9
- package/dist/database/schema.d.ts.map +1 -1
- package/dist/database/schema.js +69 -12
- package/dist/database/schema.js.map +1 -1
- package/dist/engine/engine.d.ts +59 -0
- package/dist/engine/engine.d.ts.map +1 -0
- package/dist/{engine.js → engine/engine.js} +80 -32
- package/dist/engine/engine.js.map +1 -0
- package/dist/engine/error.d.ts +45 -0
- package/dist/engine/error.d.ts.map +1 -0
- package/dist/engine/error.js +49 -0
- package/dist/engine/error.js.map +1 -0
- package/dist/engine/lifecycle.d.ts +112 -0
- package/dist/engine/lifecycle.d.ts.map +1 -0
- package/dist/engine/lifecycle.js +132 -0
- package/dist/engine/lifecycle.js.map +1 -0
- package/dist/engine/shutdown.d.ts +12 -0
- package/dist/engine/shutdown.d.ts.map +1 -0
- package/dist/engine/shutdown.js +10 -0
- package/dist/engine/shutdown.js.map +1 -0
- package/dist/engine/submission.d.ts +58 -0
- package/dist/engine/submission.d.ts.map +1 -0
- package/dist/engine/submission.js +54 -0
- package/dist/engine/submission.js.map +1 -0
- package/dist/item-projection/{service.d.ts → item-projection.d.ts} +6 -6
- package/dist/item-projection/item-projection.d.ts.map +1 -0
- package/dist/item-projection/{service.js → item-projection.js} +7 -5
- package/dist/item-projection/item-projection.js.map +1 -0
- package/dist/item-projection/model.d.ts +2 -5
- package/dist/item-projection/model.d.ts.map +1 -1
- package/dist/item-projection/model.js +5 -5
- package/dist/item-projection/model.js.map +1 -1
- package/dist/loop-control/loop-control.d.ts +21 -0
- package/dist/loop-control/loop-control.d.ts.map +1 -0
- package/dist/{loop-control.js → loop-control/loop-control.js} +7 -5
- package/dist/loop-control/loop-control.js.map +1 -0
- package/dist/loop-control/model.d.ts +10 -0
- package/dist/loop-control/model.d.ts.map +1 -0
- package/dist/loop-control/model.js +9 -0
- package/dist/loop-control/model.js.map +1 -0
- package/dist/repository-label-projection/model.d.ts +12 -3
- package/dist/repository-label-projection/model.d.ts.map +1 -1
- package/dist/repository-label-projection/model.js +14 -5
- package/dist/repository-label-projection/model.js.map +1 -1
- package/dist/repository-label-projection/{service.d.ts → repository-label-projection.d.ts} +5 -5
- package/dist/repository-label-projection/repository-label-projection.d.ts.map +1 -0
- package/dist/repository-label-projection/{service.js → repository-label-projection.js} +17 -7
- package/dist/repository-label-projection/repository-label-projection.js.map +1 -0
- package/dist/run-reader/model.d.ts +46 -0
- package/dist/run-reader/model.d.ts.map +1 -0
- package/dist/run-reader/model.js +44 -0
- package/dist/run-reader/model.js.map +1 -0
- package/dist/run-reader/run-reader.d.ts +29 -0
- package/dist/run-reader/run-reader.d.ts.map +1 -0
- package/dist/run-reader/run-reader.js +44 -0
- package/dist/run-reader/run-reader.js.map +1 -0
- package/dist/step-executor.d.ts +36 -12
- package/dist/step-executor.d.ts.map +1 -1
- package/dist/step-executor.js +22 -5
- package/dist/step-executor.js.map +1 -1
- package/dist/store/codec.d.ts +278 -40
- package/dist/store/codec.d.ts.map +1 -1
- package/dist/store/codec.js +72 -44
- package/dist/store/codec.js.map +1 -1
- package/dist/store/queries.d.ts +49 -16
- package/dist/store/queries.d.ts.map +1 -1
- package/dist/store/queries.js +104 -91
- package/dist/store/queries.js.map +1 -1
- package/dist/store/store.d.ts +44 -26
- package/dist/store/store.d.ts.map +1 -1
- package/dist/store/store.js +199 -128
- package/dist/store/store.js.map +1 -1
- package/dist/store/transcript.d.ts +9 -0
- package/dist/store/transcript.d.ts.map +1 -0
- package/dist/store/transcript.js +71 -0
- package/dist/store/transcript.js.map +1 -0
- package/dist/transcript.d.ts +86 -0
- package/dist/transcript.d.ts.map +1 -0
- package/dist/transcript.js +77 -0
- package/dist/transcript.js.map +1 -0
- package/dist/workflow/admission.d.ts +13 -0
- package/dist/workflow/admission.d.ts.map +1 -0
- package/dist/workflow/admission.js +55 -0
- package/dist/workflow/admission.js.map +1 -0
- package/dist/workflow/command.d.ts +13 -0
- package/dist/workflow/command.d.ts.map +1 -0
- package/dist/workflow/command.js +17 -0
- package/dist/workflow/command.js.map +1 -0
- package/dist/workflow/workflow.d.ts +18 -0
- package/dist/workflow/workflow.d.ts.map +1 -0
- package/dist/workflow/workflow.js +108 -0
- package/dist/workflow/workflow.js.map +1 -0
- package/drizzle/20260903091940_queued_approved_runs/migration.sql +3 -0
- package/drizzle/20260903091940_queued_approved_runs/snapshot.json +1147 -0
- package/drizzle/20260905150403_item_cycle_budgets/migration.sql +58 -0
- package/drizzle/20260905150403_item_cycle_budgets/snapshot.json +1417 -0
- package/drizzle/20260905174009_item_run_history/migration.sql +1 -0
- package/drizzle/20260905174009_item_run_history/snapshot.json +1431 -0
- package/drizzle/20260912111855_operator_intervention/migration.sql +42 -0
- package/drizzle/20260912111855_operator_intervention/snapshot.json +1461 -0
- package/package.json +41 -5
- package/dist/cursor/model.d.ts +0 -5
- package/dist/cursor/model.d.ts.map +0 -1
- package/dist/cursor/model.js +0 -4
- package/dist/cursor/model.js.map +0 -1
- package/dist/cursor/store.d.ts.map +0 -1
- package/dist/cursor/store.js.map +0 -1
- package/dist/engine.d.ts +0 -39
- package/dist/engine.d.ts.map +0 -1
- package/dist/engine.js.map +0 -1
- package/dist/index.d.ts +0 -20
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -20
- package/dist/index.js.map +0 -1
- package/dist/item-projection/service.d.ts.map +0 -1
- package/dist/item-projection/service.js.map +0 -1
- package/dist/loop-control.d.ts +0 -16
- package/dist/loop-control.d.ts.map +0 -1
- package/dist/loop-control.js.map +0 -1
- package/dist/model.d.ts +0 -185
- package/dist/model.d.ts.map +0 -1
- package/dist/model.js +0 -174
- package/dist/model.js.map +0 -1
- package/dist/repository-label-projection/service.d.ts.map +0 -1
- package/dist/repository-label-projection/service.js.map +0 -1
- package/dist/run-reader.d.ts +0 -20
- package/dist/run-reader.d.ts.map +0 -1
- package/dist/run-reader.js +0 -19
- package/dist/run-reader.js.map +0 -1
- package/dist/workflow.d.ts +0 -14
- package/dist/workflow.d.ts.map +0 -1
- package/dist/workflow.js +0 -105
- package/dist/workflow.js.map +0 -1
|
@@ -5,7 +5,7 @@ interface RunDatabaseEffect extends QueryEffectHKTBase {
|
|
|
5
5
|
readonly context: never;
|
|
6
6
|
readonly error: EffectDrizzleQueryError;
|
|
7
7
|
}
|
|
8
|
-
/**
|
|
8
|
+
/** The Effect database the run projection store queries, independent of the SQLite driver. */
|
|
9
9
|
export type RunDatabaseClient = SQLiteEffectDatabase<RunDatabaseEffect, unknown>;
|
|
10
10
|
declare const RunDatabase_base: Context.ServiceClass<RunDatabase, "@usine/engine/internal/RunDatabase", RunDatabaseClient>;
|
|
11
11
|
export declare class RunDatabase extends RunDatabase_base {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../src/database/database.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC3F,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,gCAAgC,CAAC;AAC3E,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAExC,UAAU,iBAAkB,SAAQ,kBAAkB;IACpD,QAAQ,CAAC,OAAO,EAAE,KAAK,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,uBAAuB,CAAC;CACzC;AAED,
|
|
1
|
+
{"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../src/database/database.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC3F,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,gCAAgC,CAAC;AAC3E,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAExC,UAAU,iBAAkB,SAAQ,kBAAkB;IACpD,QAAQ,CAAC,OAAO,EAAE,KAAK,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,uBAAuB,CAAC;CACzC;AAED,8FAA8F;AAC9F,MAAM,MAAM,iBAAiB,GAAG,oBAAoB,CAAC,iBAAiB,EAAE,OAAO,CAAC,CAAC;;AAEjF,qBAAa,WAAY,SAAQ,gBAEhC;IACC,MAAM,CAAC,QAAQ,CAAC,KAAK,aAAc,iBAAiB,4CAA0C;CAC/F"}
|
|
@@ -1,17 +1,37 @@
|
|
|
1
1
|
import { SqliteClient } from "@effect/sql-sqlite-node";
|
|
2
|
-
import { Layer } from "effect";
|
|
3
|
-
import { CursorStore } from "../cursor/
|
|
4
|
-
import { ItemProjectionReader, ItemProjectionWriter } from "../item-projection/
|
|
5
|
-
import { RepositoryLabelProjectionReader, RepositoryLabelProjectionWriter } from "../repository-label-projection/
|
|
6
|
-
import { LoopControl } from "../loop-control.ts";
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
2
|
+
import { Effect, Layer, Schema } from "effect";
|
|
3
|
+
import { CursorStore } from "../cursor/cursor.ts";
|
|
4
|
+
import { ItemProjectionReader, ItemProjectionWriter } from "../item-projection/item-projection.ts";
|
|
5
|
+
import { RepositoryLabelProjectionReader, RepositoryLabelProjectionWriter } from "../repository-label-projection/repository-label-projection.ts";
|
|
6
|
+
import { LoopControl } from "../loop-control/loop-control.ts";
|
|
7
|
+
import { CycleBudgets } from "../cycle-budget/cycle-budget.ts";
|
|
8
|
+
import { type RunEngine } from "../engine/engine.ts";
|
|
9
|
+
import type { InstanceDirectory } from "@usine/core/instance";
|
|
10
|
+
import { EnginePersistenceError, type RunEngineError } from "../engine/error.ts";
|
|
11
|
+
import { RunReader } from "../run-reader/run-reader.ts";
|
|
10
12
|
import type { StepExecutor } from "../step-executor.ts";
|
|
11
13
|
import { RunDatabase } from "./database.ts";
|
|
12
14
|
export declare const localSqliteLayer: (instanceDirectory: InstanceDirectory) => Layer.Layer<RunDatabase | import("effect/unstable/sql/SqlClient").SqlClient | SqliteClient.SqliteClient, EnginePersistenceError, never>;
|
|
13
|
-
/**
|
|
14
|
-
export declare const layer: (instanceDirectory: InstanceDirectory) => Layer.Layer<CursorStore | ItemProjectionReader | ItemProjectionWriter | LoopControl | RepositoryLabelProjectionReader | RepositoryLabelProjectionWriter | RunEngine | RunReader, RunEngineError, StepExecutor>;
|
|
15
|
-
/**
|
|
16
|
-
export declare const observationLayer: (instanceDirectory: InstanceDirectory) => Layer.Layer<ItemProjectionReader | LoopControl | RepositoryLabelProjectionReader | RunReader, RunEngineError>;
|
|
15
|
+
/** The local runtime on `.usine/runtime.sqlite`. */
|
|
16
|
+
export declare const layer: (instanceDirectory: InstanceDirectory) => Layer.Layer<CursorStore | CycleBudgets | ItemProjectionReader | ItemProjectionWriter | LoopControl | RepositoryLabelProjectionReader | RepositoryLabelProjectionWriter | RunEngine | RunReader, RunEngineError, StepExecutor>;
|
|
17
|
+
/** Observation services initialize the local database but never reconcile workflows or start Attempts. */
|
|
18
|
+
export declare const observationLayer: (instanceDirectory: InstanceDirectory) => Layer.Layer<CycleBudgets | ItemProjectionReader | LoopControl | RepositoryLabelProjectionReader | RunReader, RunEngineError>;
|
|
19
|
+
/** Opens an existing `.usine/runtime.sqlite` in SQLite read-only mode, without initializing or migrating the database. */
|
|
20
|
+
export declare const runReaderLayer: (instanceDirectory: InstanceDirectory) => Layer.Layer<RunReader, EnginePersistenceError>;
|
|
21
|
+
declare const RuntimeStoreBackupError_base: Schema.Class<RuntimeStoreBackupError, Schema.TaggedStruct<"RuntimeStoreBackupError", {
|
|
22
|
+
readonly operation: Schema.Literals<readonly ["open", "stage", "copy", "publish"]>;
|
|
23
|
+
readonly source: Schema.String;
|
|
24
|
+
readonly destination: Schema.String;
|
|
25
|
+
readonly reason: Schema.String;
|
|
26
|
+
readonly cause: Schema.Defect;
|
|
27
|
+
}>, import("effect/Cause").YieldableError>;
|
|
28
|
+
/** A failed backup operation, with both paths because SQLite copy errors can come from either file. */
|
|
29
|
+
export declare class RuntimeStoreBackupError extends RuntimeStoreBackupError_base {
|
|
30
|
+
}
|
|
31
|
+
/** Copies `.usine/runtime.sqlite` to a new file while the orchestrator runs.
|
|
32
|
+
* The destination directory must exist and support hard links. Opens the source
|
|
33
|
+
* read-only and saves a complete backup without overwriting an existing file.
|
|
34
|
+
*/
|
|
35
|
+
export declare const backup: (instanceDirectory: string & import("effect/Brand").Brand<"InstanceDirectory">, destination: string) => Effect.Effect<void, RuntimeStoreBackupError, never>;
|
|
36
|
+
export {};
|
|
17
37
|
//# sourceMappingURL=local-sqlite.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"local-sqlite.d.ts","sourceRoot":"","sources":["../../src/database/local-sqlite.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAKvD,OAAO,
|
|
1
|
+
{"version":3,"file":"local-sqlite.d.ts","sourceRoot":"","sources":["../../src/database/local-sqlite.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAKvD,OAAO,EAAE,MAAM,EAAc,KAAK,EAA+B,MAAM,EAAE,MAAM,QAAQ,CAAC;AAExF,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,uCAAuC,CAAC;AACnG,OAAO,EACL,+BAA+B,EAC/B,+BAA+B,EAChC,MAAM,+DAA+D,CAAC;AACvE,OAAO,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AAC/D,OAAO,EAAqB,KAAK,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACxE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,sBAAsB,EAAE,KAAK,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACjF,OAAO,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AACxD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAuB5C,eAAO,MAAM,gBAAgB,sBAAuB,iBAAiB,4IAyBpE,CAAC;AAEF,oDAAoD;AACpD,eAAO,MAAM,KAAK,sBACG,iBAAiB,KACnC,KAAK,CAAC,KAAK,CACV,WAAW,GACX,YAAY,GACZ,oBAAoB,GACpB,oBAAoB,GACpB,WAAW,GACX,+BAA+B,GAC/B,+BAA+B,GAC/B,SAAS,GACT,SAAS,EACX,cAAc,EACd,YAAY,CACqF,CAAC;AAEpG,0GAA0G;AAC1G,eAAO,MAAM,gBAAgB,sBACR,iBAAiB,KACnC,KAAK,CAAC,KAAK,CACZ,YAAY,GAAG,oBAAoB,GAAG,WAAW,GAAG,+BAA+B,GAAG,SAAS,EAC/F,cAAc,CAUf,CAAC;AAiCF,0HAA0H;AAC1H,eAAO,MAAM,cAAc,sBACN,iBAAiB,KACnC,KAAK,CAAC,KAAK,CAAC,SAAS,EAAE,sBAAsB,CAM/C,CAAC;;;;;;;;AAEF,uGAAuG;AACvG,qBAAa,uBAAwB,SAAQ,4BAQ3C;CAAG;AAmBL;;;GAGG;AACH,eAAO,MAAM,MAAM,6JAuDlB,CAAC"}
|
|
@@ -4,42 +4,147 @@ import { fileURLToPath } from "node:url";
|
|
|
4
4
|
import * as SQLiteDrizzle from "drizzle-orm/effect-sqlite-node";
|
|
5
5
|
import { migrate } from "drizzle-orm/effect-sqlite-node/migrator";
|
|
6
6
|
import { sql } from "drizzle-orm";
|
|
7
|
-
import { Effect, FileSystem, Layer, Path } from "effect";
|
|
8
|
-
import { CursorStore } from "../cursor/
|
|
9
|
-
import { ItemProjectionReader, ItemProjectionWriter } from "../item-projection/
|
|
10
|
-
import { RepositoryLabelProjectionReader, RepositoryLabelProjectionWriter, } from "../repository-label-projection/
|
|
11
|
-
import { LoopControl } from "../loop-control.js";
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
7
|
+
import { Effect, FileSystem, Layer, Option, Path, PlatformError, Schema } from "effect";
|
|
8
|
+
import { CursorStore } from "../cursor/cursor.js";
|
|
9
|
+
import { ItemProjectionReader, ItemProjectionWriter } from "../item-projection/item-projection.js";
|
|
10
|
+
import { RepositoryLabelProjectionReader, RepositoryLabelProjectionWriter, } from "../repository-label-projection/repository-label-projection.js";
|
|
11
|
+
import { LoopControl } from "../loop-control/loop-control.js";
|
|
12
|
+
import { CycleBudgets } from "../cycle-budget/cycle-budget.js";
|
|
13
|
+
import { layerWithDatabase } from "../engine/engine.js";
|
|
14
|
+
import { EnginePersistenceError } from "../engine/error.js";
|
|
15
|
+
import { RunReader } from "../run-reader/run-reader.js";
|
|
15
16
|
import { RunDatabase } from "./database.js";
|
|
16
17
|
const migrationsFolder = fileURLToPath(new URL("../../drizzle", import.meta.url));
|
|
17
18
|
const startupError = (operation, cause) => new EnginePersistenceError({ operation, cause });
|
|
19
|
+
const runtimeStorePath = (path, instanceDirectory) => path.join(instanceDirectory, ".usine", "runtime.sqlite");
|
|
18
20
|
const sqliteClientLayer = (instanceDirectory) => Layer.unwrap(Effect.gen(function* () {
|
|
19
21
|
const fileSystem = yield* FileSystem.FileSystem;
|
|
20
22
|
const path = yield* Path.Path;
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
return SqliteClient.layer({ filename: path.join(runtimeDirectory, "runtime.sqlite") });
|
|
23
|
+
yield* fileSystem.makeDirectory(path.join(instanceDirectory, ".usine"), { recursive: true });
|
|
24
|
+
return SqliteClient.layer({ filename: runtimeStorePath(path, instanceDirectory) });
|
|
24
25
|
}).pipe(Effect.mapError((cause) => startupError("prepare local database directory", cause)), Effect.provide(NodeServices.layer)));
|
|
25
26
|
export const localSqliteLayer = (instanceDirectory) => {
|
|
26
27
|
const sqlClient = sqliteClientLayer(instanceDirectory);
|
|
27
28
|
const database = Layer.effect(RunDatabase, Effect.gen(function* () {
|
|
28
29
|
const drizzle = yield* SQLiteDrizzle.makeWithDefaults();
|
|
29
|
-
|
|
30
|
+
// SQLite ignores foreign_keys changes inside a transaction. Drizzle
|
|
31
|
+
// rebuilds referenced tables while migrating, so disable before its
|
|
32
|
+
// transaction and restore enforcement even when a migration fails.
|
|
33
|
+
yield* drizzle.run(sql `PRAGMA foreign_keys = OFF`).execute();
|
|
30
34
|
yield* migrate(drizzle, {
|
|
31
35
|
migrationsFolder,
|
|
32
36
|
migrationsTable: "usine_migrations",
|
|
33
|
-
})
|
|
37
|
+
}).pipe(Effect.ensuring(drizzle
|
|
38
|
+
.run(sql `PRAGMA foreign_keys = ON`)
|
|
39
|
+
.execute()
|
|
40
|
+
.pipe(Effect.orDie)));
|
|
34
41
|
return drizzle;
|
|
35
42
|
}).pipe(Effect.mapError((cause) => startupError("initialize local database", cause))));
|
|
36
43
|
return database.pipe(Layer.provideMerge(sqlClient));
|
|
37
44
|
};
|
|
38
|
-
/**
|
|
45
|
+
/** The local runtime on `.usine/runtime.sqlite`. */
|
|
39
46
|
export const layer = (instanceDirectory) => layerWithDatabase(localSqliteLayer(instanceDirectory)).pipe(Layer.provide(NodeServices.layer));
|
|
40
|
-
/**
|
|
47
|
+
/** Observation services initialize the local database but never reconcile workflows or start Attempts. */
|
|
41
48
|
export const observationLayer = (instanceDirectory) => {
|
|
42
49
|
const database = localSqliteLayer(instanceDirectory);
|
|
43
|
-
return Layer.mergeAll(ItemProjectionReader.layer, LoopControl.layer, RepositoryLabelProjectionReader.layer, RunReader.layer).pipe(Layer.provide(database));
|
|
50
|
+
return Layer.mergeAll(CycleBudgets.layer, ItemProjectionReader.layer, LoopControl.layer, RepositoryLabelProjectionReader.layer, RunReader.layer).pipe(Layer.provide(database));
|
|
51
|
+
};
|
|
52
|
+
const readableRuntimeStore = Effect.fn("LocalSqlite.readableRuntimeStore")(function* (filename) {
|
|
53
|
+
const fileSystem = yield* FileSystem.FileSystem;
|
|
54
|
+
yield* fileSystem.access(filename, { readable: true });
|
|
55
|
+
const info = yield* fileSystem.stat(filename);
|
|
56
|
+
if (info.type !== "File")
|
|
57
|
+
return yield* PlatformError.systemError({
|
|
58
|
+
_tag: "BadResource",
|
|
59
|
+
module: "FileSystem",
|
|
60
|
+
method: "stat",
|
|
61
|
+
pathOrDescriptor: filename,
|
|
62
|
+
description: `Expected a regular SQLite file, found ${info.type}`,
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
const readOnlySqliteLayer = (filename) => SqliteClient.layer({ filename, readonly: true, disableWAL: true });
|
|
66
|
+
const existingSqliteLayer = (instanceDirectory) => Layer.unwrap(Effect.gen(function* () {
|
|
67
|
+
const filename = runtimeStorePath(yield* Path.Path, instanceDirectory);
|
|
68
|
+
yield* readableRuntimeStore(filename);
|
|
69
|
+
return readOnlySqliteLayer(filename);
|
|
70
|
+
}).pipe(Effect.mapError((cause) => startupError("open existing local database", cause)), Effect.provide(NodeServices.layer)));
|
|
71
|
+
/** Opens an existing `.usine/runtime.sqlite` in SQLite read-only mode, without initializing or migrating the database. */
|
|
72
|
+
export const runReaderLayer = (instanceDirectory) => {
|
|
73
|
+
const sqlClient = existingSqliteLayer(instanceDirectory);
|
|
74
|
+
const database = Layer.effect(RunDatabase, SQLiteDrizzle.makeWithDefaults()).pipe(Layer.provide(sqlClient));
|
|
75
|
+
return RunReader.layer.pipe(Layer.provide(database));
|
|
44
76
|
};
|
|
77
|
+
/** A failed backup operation, with both paths because SQLite copy errors can come from either file. */
|
|
78
|
+
export class RuntimeStoreBackupError extends Schema.TaggedError("@usine/engine/RuntimeStoreBackupError")("RuntimeStoreBackupError", {
|
|
79
|
+
operation: Schema.Literals(["open", "stage", "copy", "publish"]),
|
|
80
|
+
source: Schema.String,
|
|
81
|
+
destination: Schema.String,
|
|
82
|
+
reason: Schema.String,
|
|
83
|
+
cause: Schema.Defect(),
|
|
84
|
+
}) {
|
|
85
|
+
}
|
|
86
|
+
const vendorMessage = Schema.decodeUnknownOption(Schema.Struct({ message: Schema.NonEmptyString }));
|
|
87
|
+
const errnoCode = Schema.decodeUnknownOption(Schema.Struct({ code: Schema.NonEmptyString }));
|
|
88
|
+
const failureReason = (cause) => {
|
|
89
|
+
if (cause._tag === "SqlError")
|
|
90
|
+
return Option.match(vendorMessage(cause.reason.cause), {
|
|
91
|
+
onNone: () => cause.reason._tag,
|
|
92
|
+
onSome: ({ message }) => message,
|
|
93
|
+
});
|
|
94
|
+
if (cause.reason.description !== undefined)
|
|
95
|
+
return cause.reason.description;
|
|
96
|
+
if (cause.reason._tag !== "Unknown")
|
|
97
|
+
return cause.reason._tag;
|
|
98
|
+
return Option.match(errnoCode(cause.reason.cause), {
|
|
99
|
+
onNone: () => cause.reason._tag,
|
|
100
|
+
onSome: ({ code }) => code,
|
|
101
|
+
});
|
|
102
|
+
};
|
|
103
|
+
/** Copies `.usine/runtime.sqlite` to a new file while the orchestrator runs.
|
|
104
|
+
* The destination directory must exist and support hard links. Opens the source
|
|
105
|
+
* read-only and saves a complete backup without overwriting an existing file.
|
|
106
|
+
*/
|
|
107
|
+
export const backup = Effect.fn("LocalSqlite.backup")(function* (instanceDirectory, destination) {
|
|
108
|
+
yield* Effect.annotateCurrentSpan({ instanceDirectory, destination });
|
|
109
|
+
yield* Effect.logInfo("Runtime store backup started", { instanceDirectory, destination });
|
|
110
|
+
const fileSystem = yield* FileSystem.FileSystem;
|
|
111
|
+
const path = yield* Path.Path;
|
|
112
|
+
const source = runtimeStorePath(path, instanceDirectory);
|
|
113
|
+
const failed = (operation) => Effect.mapError((cause) => new RuntimeStoreBackupError({
|
|
114
|
+
operation,
|
|
115
|
+
source,
|
|
116
|
+
destination,
|
|
117
|
+
reason: failureReason(cause),
|
|
118
|
+
cause,
|
|
119
|
+
}));
|
|
120
|
+
yield* readableRuntimeStore(source).pipe(failed("open"));
|
|
121
|
+
const { totalPages } = yield* Effect.scoped(Effect.gen(function* () {
|
|
122
|
+
const directory = path.dirname(destination);
|
|
123
|
+
const temporary = yield* fileSystem
|
|
124
|
+
.makeTempDirectoryScoped({ directory, prefix: ".usine-backup-" })
|
|
125
|
+
.pipe(failed("stage"));
|
|
126
|
+
const staged = path.join(temporary, "runtime.sqlite");
|
|
127
|
+
yield* fileSystem
|
|
128
|
+
.writeFile(staged, new Uint8Array(), { mode: 0o600 })
|
|
129
|
+
.pipe(failed("stage"));
|
|
130
|
+
const metadata = yield* Effect.flatMap(SqliteClient.SqliteClient, (client) =>
|
|
131
|
+
// Node's backup can't be canceled; wait before closing the database or deleting staging.
|
|
132
|
+
client.backup(staged).pipe(failed("copy"), Effect.uninterruptible)).pipe(Effect.provide(readOnlySqliteLayer(source)));
|
|
133
|
+
// A hard link atomically creates the destination without overwriting it.
|
|
134
|
+
yield* fileSystem.link(staged, destination).pipe(failed("publish"));
|
|
135
|
+
return metadata;
|
|
136
|
+
}));
|
|
137
|
+
yield* Effect.annotateCurrentSpan({ totalPages });
|
|
138
|
+
yield* Effect.logInfo("Runtime store backup completed", {
|
|
139
|
+
instanceDirectory,
|
|
140
|
+
destination,
|
|
141
|
+
totalPages,
|
|
142
|
+
});
|
|
143
|
+
}, Effect.tapError((error) => Effect.logWarning("Runtime store backup failed", {
|
|
144
|
+
errorTag: error._tag,
|
|
145
|
+
operation: error.operation,
|
|
146
|
+
source: error.source,
|
|
147
|
+
destination: error.destination,
|
|
148
|
+
reason: error.reason,
|
|
149
|
+
})), Effect.provide(NodeServices.layer));
|
|
45
150
|
//# sourceMappingURL=local-sqlite.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"local-sqlite.js","sourceRoot":"","sources":["../../src/database/local-sqlite.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,KAAK,aAAa,MAAM,gCAAgC,CAAC;AAChE,OAAO,EAAE,OAAO,EAAE,MAAM,yCAAyC,CAAC;AAClE,OAAO,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AAClC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"local-sqlite.js","sourceRoot":"","sources":["../../src/database/local-sqlite.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,KAAK,aAAa,MAAM,gCAAgC,CAAC;AAChE,OAAO,EAAE,OAAO,EAAE,MAAM,yCAAyC,CAAC;AAClE,OAAO,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AAClC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAExF,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,uCAAuC,CAAC;AACnG,OAAO,EACL,+BAA+B,EAC/B,+BAA+B,GAChC,MAAM,+DAA+D,CAAC;AACvE,OAAO,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AAC/D,OAAO,EAAE,iBAAiB,EAAkB,MAAM,qBAAqB,CAAC;AAExE,OAAO,EAAE,sBAAsB,EAAuB,MAAM,oBAAoB,CAAC;AACjF,OAAO,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAExD,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C,MAAM,gBAAgB,GAAG,aAAa,CAAC,IAAI,GAAG,CAAC,eAAe,EAAE,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAElF,MAAM,YAAY,GAAG,CAAC,SAAiB,EAAE,KAAc,EAAE,EAAE,CACzD,IAAI,sBAAsB,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC;AAEnD,MAAM,gBAAgB,GAAG,CAAC,IAAe,EAAE,iBAAoC,EAAE,EAAE,CACjF,IAAI,CAAC,IAAI,CAAC,iBAAiB,EAAE,QAAQ,EAAE,gBAAgB,CAAC,CAAC;AAE3D,MAAM,iBAAiB,GAAG,CAAC,iBAAoC,EAAE,EAAE,CACjE,KAAK,CAAC,MAAM,CACV,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IAClB,MAAM,UAAU,GAAG,KAAK,CAAC,CAAC,UAAU,CAAC,UAAU,CAAC;IAChD,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;IAC9B,KAAK,CAAC,CAAC,UAAU,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,iBAAiB,EAAE,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC7F,OAAO,YAAY,CAAC,KAAK,CAAC,EAAE,QAAQ,EAAE,gBAAgB,CAAC,IAAI,EAAE,iBAAiB,CAAC,EAAE,CAAC,CAAC;AACrF,CAAC,CAAC,CAAC,IAAI,CACL,MAAM,CAAC,QAAQ,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,YAAY,CAAC,kCAAkC,EAAE,KAAK,CAAC,CAAC,EACnF,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,KAAK,CAAC,CACnC,CACF,CAAC;AAEJ,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,iBAAoC,EAAE,EAAE;IACvE,MAAM,SAAS,GAAG,iBAAiB,CAAC,iBAAiB,CAAC,CAAC;IACvD,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,CAC3B,WAAW,EACX,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;QAClB,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,aAAa,CAAC,gBAAgB,EAAE,CAAC;QACxD,oEAAoE;QACpE,oEAAoE;QACpE,mEAAmE;QACnE,KAAK,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAA,2BAA2B,CAAC,CAAC,OAAO,EAAE,CAAC;QAC7D,KAAK,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE;YACtB,gBAAgB;YAChB,eAAe,EAAE,kBAAkB;SACpC,CAAC,CAAC,IAAI,CACL,MAAM,CAAC,QAAQ,CACb,OAAO;aACJ,GAAG,CAAC,GAAG,CAAA,0BAA0B,CAAC;aAClC,OAAO,EAAE;aACT,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CACtB,CACF,CAAC;QACF,OAAO,OAAO,CAAC;IACjB,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,YAAY,CAAC,2BAA2B,EAAE,KAAK,CAAC,CAAC,CAAC,CACtF,CAAC;IACF,OAAO,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC,CAAC;AACtD,CAAC,CAAC;AAEF,oDAAoD;AACpD,MAAM,CAAC,MAAM,KAAK,GAAG,CACnB,iBAAoC,EAapC,EAAE,CAAC,iBAAiB,CAAC,gBAAgB,CAAC,iBAAiB,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC;AAEpG,0GAA0G;AAC1G,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAC9B,iBAAoC,EAIpC,EAAE;IACF,MAAM,QAAQ,GAAG,gBAAgB,CAAC,iBAAiB,CAAC,CAAC;IACrD,OAAO,KAAK,CAAC,QAAQ,CACnB,YAAY,CAAC,KAAK,EAClB,oBAAoB,CAAC,KAAK,EAC1B,WAAW,CAAC,KAAK,EACjB,+BAA+B,CAAC,KAAK,EACrC,SAAS,CAAC,KAAK,CAChB,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;AAClC,CAAC,CAAC;AAEF,MAAM,oBAAoB,GAAG,MAAM,CAAC,EAAE,CAAC,kCAAkC,CAAC,CAAC,QAAQ,CAAC,EAClF,QAAgB;IAEhB,MAAM,UAAU,GAAG,KAAK,CAAC,CAAC,UAAU,CAAC,UAAU,CAAC;IAChD,KAAK,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,QAAQ,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;IACvD,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC9C,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM;QACtB,OAAO,KAAK,CAAC,CAAC,aAAa,CAAC,WAAW,CAAC;YACtC,IAAI,EAAE,aAAa;YACnB,MAAM,EAAE,YAAY;YACpB,MAAM,EAAE,MAAM;YACd,gBAAgB,EAAE,QAAQ;YAC1B,WAAW,EAAE,yCAAyC,IAAI,CAAC,IAAI,EAAE;SAClE,CAAC,CAAC;AACP,CAAC,CAAC,CAAC;AAEH,MAAM,mBAAmB,GAAG,CAAC,QAAgB,EAAE,EAAE,CAC/C,YAAY,CAAC,KAAK,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC;AAErE,MAAM,mBAAmB,GAAG,CAAC,iBAAoC,EAAE,EAAE,CACnE,KAAK,CAAC,MAAM,CACV,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IAClB,MAAM,QAAQ,GAAG,gBAAgB,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,iBAAiB,CAAC,CAAC;IACvE,KAAK,CAAC,CAAC,oBAAoB,CAAC,QAAQ,CAAC,CAAC;IACtC,OAAO,mBAAmB,CAAC,QAAQ,CAAC,CAAC;AACvC,CAAC,CAAC,CAAC,IAAI,CACL,MAAM,CAAC,QAAQ,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,YAAY,CAAC,8BAA8B,EAAE,KAAK,CAAC,CAAC,EAC/E,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,KAAK,CAAC,CACnC,CACF,CAAC;AAEJ,0HAA0H;AAC1H,MAAM,CAAC,MAAM,cAAc,GAAG,CAC5B,iBAAoC,EACY,EAAE;IAClD,MAAM,SAAS,GAAG,mBAAmB,CAAC,iBAAiB,CAAC,CAAC;IACzD,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,CAAC,WAAW,EAAE,aAAa,CAAC,gBAAgB,EAAE,CAAC,CAAC,IAAI,CAC/E,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,CACzB,CAAC;IACF,OAAO,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;AACvD,CAAC,CAAC;AAEF,uGAAuG;AACvG,MAAM,OAAO,uBAAwB,SAAQ,MAAM,CAAC,WAAW,CAC7D,uCAAuC,CACxC,CAAC,yBAAyB,EAAE;IAC3B,SAAS,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC;IAChE,MAAM,EAAE,MAAM,CAAC,MAAM;IACrB,WAAW,EAAE,MAAM,CAAC,MAAM;IAC1B,MAAM,EAAE,MAAM,CAAC,MAAM;IACrB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE;CACvB,CAAC;CAAG;AAEL,MAAM,aAAa,GAAG,MAAM,CAAC,mBAAmB,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC;AACpG,MAAM,SAAS,GAAG,MAAM,CAAC,mBAAmB,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC;AAE7F,MAAM,aAAa,GAAG,CAAC,KAA6C,EAAU,EAAE;IAC9E,IAAI,KAAK,CAAC,IAAI,KAAK,UAAU;QAC3B,OAAO,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;YACrD,MAAM,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI;YAC/B,MAAM,EAAE,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,OAAO;SACjC,CAAC,CAAC;IACL,IAAI,KAAK,CAAC,MAAM,CAAC,WAAW,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC;IAC5E,IAAI,KAAK,CAAC,MAAM,CAAC,IAAI,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC;IAC9D,OAAO,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;QACjD,MAAM,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI;QAC/B,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,IAAI;KAC3B,CAAC,CAAC;AACL,CAAC,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC,oBAAoB,CAAC,CACnD,QAAQ,CAAC,EAAE,iBAAoC,EAAE,WAAmB;IAClE,KAAK,CAAC,CAAC,MAAM,CAAC,mBAAmB,CAAC,EAAE,iBAAiB,EAAE,WAAW,EAAE,CAAC,CAAC;IACtE,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,8BAA8B,EAAE,EAAE,iBAAiB,EAAE,WAAW,EAAE,CAAC,CAAC;IAC1F,MAAM,UAAU,GAAG,KAAK,CAAC,CAAC,UAAU,CAAC,UAAU,CAAC;IAChD,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;IAC9B,MAAM,MAAM,GAAG,gBAAgB,CAAC,IAAI,EAAE,iBAAiB,CAAC,CAAC;IACzD,MAAM,MAAM,GAAG,CAAC,SAA+C,EAAE,EAAE,CACjE,MAAM,CAAC,QAAQ,CACb,CAAC,KAA6C,EAAE,EAAE,CAChD,IAAI,uBAAuB,CAAC;QAC1B,SAAS;QACT,MAAM;QACN,WAAW;QACX,MAAM,EAAE,aAAa,CAAC,KAAK,CAAC;QAC5B,KAAK;KACN,CAAC,CACL,CAAC;IACJ,KAAK,CAAC,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;IACzD,MAAM,EAAE,UAAU,EAAE,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,MAAM,CACzC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;QAClB,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;QAC5C,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,UAAU;aAChC,uBAAuB,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,gBAAgB,EAAE,CAAC;aAChE,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;QACzB,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,gBAAgB,CAAC,CAAC;QACtD,KAAK,CAAC,CAAC,UAAU;aACd,SAAS,CAAC,MAAM,EAAE,IAAI,UAAU,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;aACpD,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;QACzB,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,YAAY,EAAE,CAAC,MAAM,EAAE,EAAE;QAC3E,yFAAyF;QACzF,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,eAAe,CAAC,CACnE,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QACpD,yEAAyE;QACzE,KAAK,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC;QACpE,OAAO,QAAQ,CAAC;IAClB,CAAC,CAAC,CACH,CAAC;IACF,KAAK,CAAC,CAAC,MAAM,CAAC,mBAAmB,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC;IAClD,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,gCAAgC,EAAE;QACtD,iBAAiB;QACjB,WAAW;QACX,UAAU;KACX,CAAC,CAAC;AACL,CAAC,EACD,MAAM,CAAC,QAAQ,CAAC,CAAC,KAAK,EAAE,EAAE,CACxB,MAAM,CAAC,UAAU,CAAC,6BAA6B,EAAE;IAC/C,QAAQ,EAAE,KAAK,CAAC,IAAI;IACpB,SAAS,EAAE,KAAK,CAAC,SAAS;IAC1B,MAAM,EAAE,KAAK,CAAC,MAAM;IACpB,WAAW,EAAE,KAAK,CAAC,WAAW;IAC9B,MAAM,EAAE,KAAK,CAAC,MAAM;CACrB,CAAC,CACH,EACD,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,KAAK,CAAC,CACnC,CAAC"}
|