@smthrs/run-store 0.0.0-stage → 1.0.0-rc.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +112 -0
- package/LICENSE +21 -0
- package/README.md +195 -2
- package/dist/cjs/AttemptStore.d.ts +359 -0
- package/dist/cjs/AttemptStore.d.ts.map +1 -0
- package/dist/cjs/AttemptStore.js +731 -0
- package/dist/cjs/AttemptStore.js.map +7 -0
- package/dist/cjs/Heartbeat.d.ts +46 -0
- package/dist/cjs/Heartbeat.d.ts.map +1 -0
- package/dist/cjs/Heartbeat.js +28 -0
- package/dist/cjs/Heartbeat.js.map +7 -0
- package/dist/cjs/Migrations.d.ts +42 -0
- package/dist/cjs/Migrations.d.ts.map +1 -0
- package/dist/cjs/Migrations.js +55 -0
- package/dist/cjs/Migrations.js.map +7 -0
- package/dist/cjs/Ownership.d.ts +275 -0
- package/dist/cjs/Ownership.d.ts.map +1 -0
- package/dist/cjs/Ownership.js +129 -0
- package/dist/cjs/Ownership.js.map +7 -0
- package/dist/cjs/RunStore.d.ts +571 -0
- package/dist/cjs/RunStore.d.ts.map +1 -0
- package/dist/cjs/RunStore.js +1079 -0
- package/dist/cjs/RunStore.js.map +7 -0
- package/dist/cjs/RunStoreMetrics.d.ts +151 -0
- package/dist/cjs/RunStoreMetrics.d.ts.map +1 -0
- package/dist/cjs/RunStoreMetrics.js +91 -0
- package/dist/cjs/RunStoreMetrics.js.map +7 -0
- package/dist/cjs/index.d.ts +47 -0
- package/dist/cjs/index.d.ts.map +1 -0
- package/dist/cjs/index.js +43 -0
- package/dist/cjs/index.js.map +7 -0
- package/dist/cjs/internal/Boundary.d.ts +80 -0
- package/dist/cjs/internal/Boundary.d.ts.map +1 -0
- package/dist/cjs/internal/Boundary.js +92 -0
- package/dist/cjs/internal/Boundary.js.map +7 -0
- package/dist/cjs/internal/Companion.d.ts +44 -0
- package/dist/cjs/internal/Companion.d.ts.map +1 -0
- package/dist/cjs/internal/Companion.js +50 -0
- package/dist/cjs/internal/Companion.js.map +7 -0
- package/dist/cjs/internal/SpanOutcome.d.ts +37 -0
- package/dist/cjs/internal/SpanOutcome.d.ts.map +1 -0
- package/dist/cjs/internal/SpanOutcome.js +62 -0
- package/dist/cjs/internal/SpanOutcome.js.map +7 -0
- package/dist/cjs/migrations/0001_initial.d.ts +15 -0
- package/dist/cjs/migrations/0001_initial.d.ts.map +1 -0
- package/dist/cjs/migrations/0001_initial.js +110 -0
- package/dist/cjs/migrations/0001_initial.js.map +7 -0
- package/dist/cjs/migrations/0002_lineage.d.ts +27 -0
- package/dist/cjs/migrations/0002_lineage.d.ts.map +1 -0
- package/dist/cjs/migrations/0002_lineage.js +43 -0
- package/dist/cjs/migrations/0002_lineage.js.map +7 -0
- package/dist/cjs/migrations/0003_execution_revisions.d.ts +15 -0
- package/dist/cjs/migrations/0003_execution_revisions.d.ts.map +1 -0
- package/dist/cjs/migrations/0003_execution_revisions.js +77 -0
- package/dist/cjs/migrations/0003_execution_revisions.js.map +7 -0
- package/dist/cjs/migrations/0004_waiting_request.d.ts +32 -0
- package/dist/cjs/migrations/0004_waiting_request.d.ts.map +1 -0
- package/dist/cjs/migrations/0004_waiting_request.js +42 -0
- package/dist/cjs/migrations/0004_waiting_request.js.map +7 -0
- package/dist/cjs/package.json +1 -0
- package/dist/cjs/test/TestRunStore.d.ts +17 -0
- package/dist/cjs/test/TestRunStore.d.ts.map +1 -0
- package/dist/cjs/test/TestRunStore.js +42 -0
- package/dist/cjs/test/TestRunStore.js.map +7 -0
- package/dist/esm/AttemptStore.d.ts +359 -0
- package/dist/esm/AttemptStore.d.ts.map +1 -0
- package/dist/esm/AttemptStore.js +835 -0
- package/dist/esm/AttemptStore.js.map +1 -0
- package/dist/esm/Heartbeat.d.ts +46 -0
- package/dist/esm/Heartbeat.d.ts.map +1 -0
- package/dist/esm/Heartbeat.js +46 -0
- package/dist/esm/Heartbeat.js.map +1 -0
- package/dist/esm/Migrations.d.ts +42 -0
- package/dist/esm/Migrations.d.ts.map +1 -0
- package/dist/esm/Migrations.js +56 -0
- package/dist/esm/Migrations.js.map +1 -0
- package/dist/esm/Ownership.d.ts +275 -0
- package/dist/esm/Ownership.d.ts.map +1 -0
- package/dist/esm/Ownership.js +299 -0
- package/dist/esm/Ownership.js.map +1 -0
- package/dist/esm/RunStore.d.ts +571 -0
- package/dist/esm/RunStore.d.ts.map +1 -0
- package/dist/esm/RunStore.js +1287 -0
- package/dist/esm/RunStore.js.map +1 -0
- package/dist/esm/RunStoreMetrics.d.ts +151 -0
- package/dist/esm/RunStoreMetrics.d.ts.map +1 -0
- package/dist/esm/RunStoreMetrics.js +120 -0
- package/dist/esm/RunStoreMetrics.js.map +1 -0
- package/dist/esm/index.d.ts +47 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +47 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/internal/Boundary.d.ts +80 -0
- package/dist/esm/internal/Boundary.d.ts.map +1 -0
- package/dist/esm/internal/Boundary.js +109 -0
- package/dist/esm/internal/Boundary.js.map +1 -0
- package/dist/esm/internal/Companion.d.ts +44 -0
- package/dist/esm/internal/Companion.d.ts.map +1 -0
- package/dist/esm/internal/Companion.js +53 -0
- package/dist/esm/internal/Companion.js.map +1 -0
- package/dist/esm/internal/SpanOutcome.d.ts +37 -0
- package/dist/esm/internal/SpanOutcome.d.ts.map +1 -0
- package/dist/esm/internal/SpanOutcome.js +48 -0
- package/dist/esm/internal/SpanOutcome.js.map +1 -0
- package/dist/esm/migrations/0001_initial.d.ts +15 -0
- package/dist/esm/migrations/0001_initial.d.ts.map +1 -0
- package/dist/esm/migrations/0001_initial.js +88 -0
- package/dist/esm/migrations/0001_initial.js.map +1 -0
- package/dist/esm/migrations/0002_lineage.d.ts +27 -0
- package/dist/esm/migrations/0002_lineage.d.ts.map +1 -0
- package/dist/esm/migrations/0002_lineage.js +33 -0
- package/dist/esm/migrations/0002_lineage.js.map +1 -0
- package/dist/esm/migrations/0003_execution_revisions.d.ts +15 -0
- package/dist/esm/migrations/0003_execution_revisions.d.ts.map +1 -0
- package/dist/esm/migrations/0003_execution_revisions.js +58 -0
- package/dist/esm/migrations/0003_execution_revisions.js.map +1 -0
- package/dist/esm/migrations/0004_waiting_request.d.ts +32 -0
- package/dist/esm/migrations/0004_waiting_request.d.ts.map +1 -0
- package/dist/esm/migrations/0004_waiting_request.js +37 -0
- package/dist/esm/migrations/0004_waiting_request.js.map +1 -0
- package/dist/esm/test/TestRunStore.d.ts +17 -0
- package/dist/esm/test/TestRunStore.d.ts.map +1 -0
- package/dist/esm/test/TestRunStore.js +19 -0
- package/dist/esm/test/TestRunStore.js.map +1 -0
- package/docs/README.md +142 -0
- package/docs/api.md +901 -0
- package/docs/concepts/durable-values.md +140 -0
- package/docs/concepts/execution-revisions.md +53 -0
- package/docs/concepts/fencing.md +146 -0
- package/docs/concepts/leases.md +154 -0
- package/docs/concepts/liveness-evidence.md +142 -0
- package/docs/guides/cancel-a-run.md +156 -0
- package/docs/guides/claim-and-finish-a-run.md +175 -0
- package/docs/guides/compose-the-stores.md +142 -0
- package/docs/guides/observe-outcomes.md +182 -0
- package/docs/guides/record-step-attempts.md +170 -0
- package/docs/guides/recover-a-stalled-run.md +173 -0
- package/docs/guides/testing.md +141 -0
- package/docs/installation.md +109 -0
- package/docs/quickstart.md +201 -0
- package/docs/troubleshooting.md +255 -0
- package/package.json +183 -3
- package/src/AttemptStore.ts +1195 -0
- package/src/Heartbeat.ts +47 -0
- package/src/Migrations.ts +59 -0
- package/src/Ownership.ts +407 -0
- package/src/RunStore.ts +2063 -0
- package/src/RunStoreMetrics.ts +165 -0
- package/src/index.ts +51 -0
- package/src/internal/Boundary.ts +130 -0
- package/src/internal/Companion.ts +64 -0
- package/src/internal/SpanOutcome.ts +71 -0
- package/src/migrations/0001_initial.ts +114 -0
- package/src/migrations/0002_lineage.ts +38 -0
- package/src/migrations/0003_execution_revisions.ts +69 -0
- package/src/migrations/0004_waiting_request.ts +39 -0
- package/src/test/TestRunStore.ts +22 -0
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Trampoline lineage columns on `flows_runs`.
|
|
3
|
+
*
|
|
4
|
+
* A round is its own run row, chained to the previous round through the `parent_run_id`
|
|
5
|
+
* column this table already reserved for continue-as-new, and these two
|
|
6
|
+
* columns are what make the chain readable as a lineage rather than as an
|
|
7
|
+
* anonymous ancestry: which lineage a round belongs to, and which round of it
|
|
8
|
+
* this is. They are NOT `flows_run_parents` edges — that table is the subflow
|
|
9
|
+
* DAG cycle detection walks, and a lineage is a chain of successive
|
|
10
|
+
* executions of one run rather than a parent spawning a child.
|
|
11
|
+
*
|
|
12
|
+
* Append-only, as every migration after the first must be: both columns are
|
|
13
|
+
* nullable, so every row an earlier build wrote stays valid and reads back as
|
|
14
|
+
* "round 0 of its own lineage".
|
|
15
|
+
*
|
|
16
|
+
* @since 0.1.0
|
|
17
|
+
*/
|
|
18
|
+
import * as Effect from "effect/Effect";
|
|
19
|
+
import * as SqlClient from "effect/unstable/sql/SqlClient";
|
|
20
|
+
/**
|
|
21
|
+
* Adds `lineage_id` and `round_ordinal` to `flows_runs` and indexes the pair.
|
|
22
|
+
*
|
|
23
|
+
* @category migrations
|
|
24
|
+
* @since 0.1.0
|
|
25
|
+
*/
|
|
26
|
+
export declare const lineage: Effect.Effect<void, unknown, SqlClient.SqlClient>;
|
|
27
|
+
//# sourceMappingURL=0002_lineage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"0002_lineage.d.ts","sourceRoot":"","sources":["../../../src/migrations/0002_lineage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAGH,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,KAAK,SAAS,MAAM,+BAA+B,CAAA;AAE1D;;;;;GAKG;AACH,eAAO,MAAM,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,OAAO,EAAE,SAAS,CAAC,SAAS,CASpE,CAAA"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
var lineage_exports = {};
|
|
30
|
+
__export(lineage_exports, {
|
|
31
|
+
lineage: () => lineage
|
|
32
|
+
});
|
|
33
|
+
module.exports = __toCommonJS(lineage_exports);
|
|
34
|
+
var Dialect = __toESM(require("@smthrs/database/Dialect"), 1);
|
|
35
|
+
var Effect = __toESM(require("effect/Effect"), 1);
|
|
36
|
+
var SqlClient = __toESM(require("effect/unstable/sql/SqlClient"), 1);
|
|
37
|
+
const lineage = Effect.gen(function* () {
|
|
38
|
+
const sql = yield* SqlClient.SqlClient;
|
|
39
|
+
yield* sql`ALTER TABLE flows_runs ADD COLUMN lineage_id TEXT CHECK (lineage_id IS NULL OR length(lineage_id) > 0)`;
|
|
40
|
+
yield* sql`ALTER TABLE flows_runs ADD COLUMN round_ordinal ${Dialect.integer(sql)} CHECK (round_ordinal IS NULL OR (${Dialect.isInteger(sql, sql`round_ordinal`)} AND round_ordinal >= 0 AND round_ordinal <= 9007199254740991))`;
|
|
41
|
+
yield* sql`CREATE UNIQUE INDEX flows_runs_lineage_idx ON flows_runs (lineage_id, round_ordinal)`;
|
|
42
|
+
});
|
|
43
|
+
//# sourceMappingURL=0002_lineage.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/migrations/0002_lineage.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Trampoline lineage columns on `flows_runs`.\n *\n * A round is its own run row, chained to the previous round through the `parent_run_id`\n * column this table already reserved for continue-as-new, and these two\n * columns are what make the chain readable as a lineage rather than as an\n * anonymous ancestry: which lineage a round belongs to, and which round of it\n * this is. They are NOT `flows_run_parents` edges \u2014 that table is the subflow\n * DAG cycle detection walks, and a lineage is a chain of successive\n * executions of one run rather than a parent spawning a child.\n *\n * Append-only, as every migration after the first must be: both columns are\n * nullable, so every row an earlier build wrote stays valid and reads back as\n * \"round 0 of its own lineage\".\n *\n * @since 0.1.0\n */\n\nimport * as Dialect from \"@smthrs/database/Dialect\"\nimport * as Effect from \"effect/Effect\"\nimport * as SqlClient from \"effect/unstable/sql/SqlClient\"\n\n/**\n * Adds `lineage_id` and `round_ordinal` to `flows_runs` and indexes the pair.\n *\n * @category migrations\n * @since 0.1.0\n */\nexport const lineage: Effect.Effect<void, unknown, SqlClient.SqlClient> = Effect.gen(function*() {\n const sql = yield* SqlClient.SqlClient\n\n yield* sql`ALTER TABLE flows_runs ADD COLUMN lineage_id TEXT CHECK (lineage_id IS NULL OR length(lineage_id) > 0)`\n yield* sql`ALTER TABLE flows_runs ADD COLUMN round_ordinal ${Dialect.integer(sql)} CHECK (round_ordinal IS NULL OR (${\n Dialect.isInteger(sql, sql`round_ordinal`)\n } AND round_ordinal >= 0 AND round_ordinal <= 9007199254740991))`\n\n yield* sql`CREATE UNIQUE INDEX flows_runs_lineage_idx ON flows_runs (lineage_id, round_ordinal)`\n})\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAkBA,cAAyB;AACzB,aAAwB;AACxB,gBAA2B;AAQpB,MAAM,UAA6D,OAAO,IAAI,aAAY;AAC/F,QAAM,MAAM,OAAO,UAAU;AAE7B,SAAO;AACP,SAAO,sDAAsD,QAAQ,QAAQ,GAAG,CAAC,qCAC/E,QAAQ,UAAU,KAAK,kBAAkB,CAC3C;AAEA,SAAO;AACT,CAAC;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Durable database identity and coalesced execution change tracking.
|
|
3
|
+
*
|
|
4
|
+
* @since 1.0.0
|
|
5
|
+
*/
|
|
6
|
+
import * as Effect from "effect/Effect";
|
|
7
|
+
import * as SqlClient from "effect/unstable/sql/SqlClient";
|
|
8
|
+
/**
|
|
9
|
+
* Retains one current revision per run ID, including deleted IDs forever.
|
|
10
|
+
* Triggers participate in the mutating transaction, including raw SQL writes.
|
|
11
|
+
* @category migrations
|
|
12
|
+
* @since 1.0.0
|
|
13
|
+
*/
|
|
14
|
+
export declare const executionRevisions: Effect.Effect<void, unknown, SqlClient.SqlClient>;
|
|
15
|
+
//# sourceMappingURL=0003_execution_revisions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"0003_execution_revisions.d.ts","sourceRoot":"","sources":["../../../src/migrations/0003_execution_revisions.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,KAAK,SAAS,MAAM,+BAA+B,CAAA;AAE1D;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,OAAO,EAAE,SAAS,CAAC,SAAS,CAoD/E,CAAA"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
var execution_revisions_exports = {};
|
|
30
|
+
__export(execution_revisions_exports, {
|
|
31
|
+
executionRevisions: () => executionRevisions
|
|
32
|
+
});
|
|
33
|
+
module.exports = __toCommonJS(execution_revisions_exports);
|
|
34
|
+
var Dialect = __toESM(require("@smthrs/database/Dialect"), 1);
|
|
35
|
+
var Effect = __toESM(require("effect/Effect"), 1);
|
|
36
|
+
var SqlClient = __toESM(require("effect/unstable/sql/SqlClient"), 1);
|
|
37
|
+
const executionRevisions = Effect.gen(function* () {
|
|
38
|
+
const sql = yield* SqlClient.SqlClient;
|
|
39
|
+
yield* sql`CREATE TABLE flows_run_source (
|
|
40
|
+
singleton ${Dialect.integer(sql)} PRIMARY KEY CHECK (singleton = 1),
|
|
41
|
+
source TEXT NOT NULL CHECK (length(source) = 32 AND ${sql.literal(Dialect.isPostgres(sql) ? "source !~ '[^0-9a-f]'" : "source NOT GLOB '*[^0-9a-f]*'")}),
|
|
42
|
+
revision ${Dialect.integer(sql)} NOT NULL CHECK (${Dialect.isInteger(sql, sql`revision`)} AND revision >= 0 AND revision <= 9007199254740991)
|
|
43
|
+
)`;
|
|
44
|
+
yield* sql`INSERT INTO flows_run_source VALUES (1, ${sql.literal(Dialect.isPostgres(sql) ? "replace(gen_random_uuid()::text, '-', '')" : "lower(hex(randomblob(16)))")}, 0)`;
|
|
45
|
+
yield* sql`CREATE TABLE flows_run_changes (
|
|
46
|
+
run_id TEXT PRIMARY KEY NOT NULL CHECK (length(run_id) > 0),
|
|
47
|
+
revision ${Dialect.integer(sql)} NOT NULL UNIQUE CHECK (${Dialect.isInteger(sql, sql`revision`)} AND revision > 0 AND revision <= 9007199254740991),
|
|
48
|
+
deleted ${Dialect.integer(sql)} NOT NULL CHECK (deleted IN (0, 1))
|
|
49
|
+
)`;
|
|
50
|
+
yield* sql`ALTER TABLE flows_runs ADD COLUMN cancel_acknowledgement_json TEXT
|
|
51
|
+
CHECK (cancel_acknowledgement_json IS NULL OR ${Dialect.jsonValid(sql, sql`cancel_acknowledgement_json`)})`;
|
|
52
|
+
yield* sql`INSERT INTO flows_run_changes (run_id, revision, deleted)
|
|
53
|
+
SELECT run_id, ROW_NUMBER() OVER (ORDER BY created_at_ms, run_id), 0 FROM flows_runs`;
|
|
54
|
+
yield* sql`UPDATE flows_run_source SET revision = (SELECT COUNT(*) FROM flows_run_changes)`;
|
|
55
|
+
for (const [operation, row, deleted] of [["INSERT", "NEW", 0], ["UPDATE", "NEW", 0], ["DELETE", "OLD", 1]]) {
|
|
56
|
+
yield* Dialect.trigger(sql, {
|
|
57
|
+
name: `flows_runs_revision_${operation.toLowerCase()}`,
|
|
58
|
+
table: "flows_runs",
|
|
59
|
+
event: `AFTER ${operation}`,
|
|
60
|
+
body: `
|
|
61
|
+
${Dialect.isPostgres(sql) ? "IF NOT EXISTS (SELECT 1 FROM flows_run_source WHERE singleton = 1) THEN RAISE EXCEPTION 'execution source identity is missing' USING ERRCODE = '23514'; END IF;" : "SELECT CASE WHEN NOT EXISTS (SELECT 1 FROM flows_run_source WHERE singleton = 1) THEN RAISE(ABORT, 'execution source identity is missing') END;"}
|
|
62
|
+
UPDATE flows_run_source SET revision = revision + 1 WHERE singleton = 1;
|
|
63
|
+
INSERT INTO flows_run_changes (run_id, revision, deleted)
|
|
64
|
+
SELECT ${row}.run_id, revision, ${deleted} FROM flows_run_source WHERE singleton = 1
|
|
65
|
+
ON CONFLICT (run_id) DO UPDATE SET revision = excluded.revision, deleted = excluded.deleted;
|
|
66
|
+
`
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
yield* Dialect.trigger(sql, {
|
|
70
|
+
name: `flows_runs_identity_immutable`,
|
|
71
|
+
table: `flows_runs`,
|
|
72
|
+
event: "BEFORE UPDATE OF run_id",
|
|
73
|
+
when: `NEW.run_id <> OLD.run_id`,
|
|
74
|
+
reject: "run identity is immutable"
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
//# sourceMappingURL=0003_execution_revisions.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/migrations/0003_execution_revisions.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Durable database identity and coalesced execution change tracking.\n *\n * @since 1.0.0\n */\n\nimport * as Dialect from \"@smthrs/database/Dialect\"\nimport * as Effect from \"effect/Effect\"\nimport * as SqlClient from \"effect/unstable/sql/SqlClient\"\n\n/**\n * Retains one current revision per run ID, including deleted IDs forever.\n * Triggers participate in the mutating transaction, including raw SQL writes.\n * @category migrations\n * @since 1.0.0\n */\nexport const executionRevisions: Effect.Effect<void, unknown, SqlClient.SqlClient> = Effect.gen(function*() {\n const sql = yield* SqlClient.SqlClient\n yield* sql`CREATE TABLE flows_run_source (\n singleton ${Dialect.integer(sql)} PRIMARY KEY CHECK (singleton = 1),\n source TEXT NOT NULL CHECK (length(source) = 32 AND ${\n sql.literal(Dialect.isPostgres(sql) ? \"source !~ '[^0-9a-f]'\" : \"source NOT GLOB '*[^0-9a-f]*'\")\n }),\n revision ${Dialect.integer(sql)} NOT NULL CHECK (${\n Dialect.isInteger(sql, sql`revision`)\n } AND revision >= 0 AND revision <= 9007199254740991)\n )`\n yield* sql`INSERT INTO flows_run_source VALUES (1, ${\n sql.literal(Dialect.isPostgres(sql) ? \"replace(gen_random_uuid()::text, '-', '')\" : \"lower(hex(randomblob(16)))\")\n }, 0)`\n yield* sql`CREATE TABLE flows_run_changes (\n run_id TEXT PRIMARY KEY NOT NULL CHECK (length(run_id) > 0),\n revision ${Dialect.integer(sql)} NOT NULL UNIQUE CHECK (${\n Dialect.isInteger(sql, sql`revision`)\n } AND revision > 0 AND revision <= 9007199254740991),\n deleted ${Dialect.integer(sql)} NOT NULL CHECK (deleted IN (0, 1))\n )`\n yield* sql`ALTER TABLE flows_runs ADD COLUMN cancel_acknowledgement_json TEXT\n CHECK (cancel_acknowledgement_json IS NULL OR ${Dialect.jsonValid(sql, sql`cancel_acknowledgement_json`)})`\n // Old rows receive a real baseline revision; their prior mutation order is unknown.\n yield* sql`INSERT INTO flows_run_changes (run_id, revision, deleted)\n SELECT run_id, ROW_NUMBER() OVER (ORDER BY created_at_ms, run_id), 0 FROM flows_runs`\n yield* sql`UPDATE flows_run_source SET revision = (SELECT COUNT(*) FROM flows_run_changes)`\n for (const [operation, row, deleted] of [[\"INSERT\", \"NEW\", 0], [\"UPDATE\", \"NEW\", 0], [\"DELETE\", \"OLD\", 1]] as const) {\n yield* Dialect.trigger(sql, {\n name: `flows_runs_revision_${operation.toLowerCase()}`,\n table: \"flows_runs\",\n event: `AFTER ${operation}`,\n body: `\n ${\n Dialect.isPostgres(sql)\n ? \"IF NOT EXISTS (SELECT 1 FROM flows_run_source WHERE singleton = 1) THEN RAISE EXCEPTION 'execution source identity is missing' USING ERRCODE = '23514'; END IF;\"\n : \"SELECT CASE WHEN NOT EXISTS (SELECT 1 FROM flows_run_source WHERE singleton = 1) THEN RAISE(ABORT, 'execution source identity is missing') END;\"\n }\n UPDATE flows_run_source SET revision = revision + 1 WHERE singleton = 1;\n INSERT INTO flows_run_changes (run_id, revision, deleted)\n SELECT ${row}.run_id, revision, ${deleted} FROM flows_run_source WHERE singleton = 1\n ON CONFLICT (run_id) DO UPDATE SET revision = excluded.revision, deleted = excluded.deleted;\n `\n })\n }\n yield* Dialect.trigger(sql, {\n name: `flows_runs_identity_immutable`,\n table: `flows_runs`,\n event: \"BEFORE UPDATE OF run_id\",\n when: `NEW.run_id <> OLD.run_id`,\n reject: \"run identity is immutable\"\n })\n})\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAMA,cAAyB;AACzB,aAAwB;AACxB,gBAA2B;AAQpB,MAAM,qBAAwE,OAAO,IAAI,aAAY;AAC1G,QAAM,MAAM,OAAO,UAAU;AAC7B,SAAO;AAAA,gBACO,QAAQ,QAAQ,GAAG,CAAC;AAAA,0DAEhC,IAAI,QAAQ,QAAQ,WAAW,GAAG,IAAI,0BAA0B,+BAA+B,CACjG;AAAA,eACa,QAAQ,QAAQ,GAAG,CAAC,oBAC/B,QAAQ,UAAU,KAAK,aAAa,CACtC;AAAA;AAEA,SAAO,8CACL,IAAI,QAAQ,QAAQ,WAAW,GAAG,IAAI,8CAA8C,4BAA4B,CAClH;AACA,SAAO;AAAA;AAAA,eAEM,QAAQ,QAAQ,GAAG,CAAC,2BAC/B,QAAQ,UAAU,KAAK,aAAa,CACtC;AAAA,cACY,QAAQ,QAAQ,GAAG,CAAC;AAAA;AAEhC,SAAO;AAAA,oDAC2C,QAAQ,UAAU,KAAK,gCAAgC,CAAC;AAE1G,SAAO;AAAA;AAEP,SAAO;AACP,aAAW,CAAC,WAAW,KAAK,OAAO,KAAK,CAAC,CAAC,UAAU,OAAO,CAAC,GAAG,CAAC,UAAU,OAAO,CAAC,GAAG,CAAC,UAAU,OAAO,CAAC,CAAC,GAAY;AACnH,WAAO,QAAQ,QAAQ,KAAK;AAAA,MAC1B,MAAM,uBAAuB,UAAU,YAAY,CAAC;AAAA,MACpD,OAAO;AAAA,MACP,OAAO,SAAS,SAAS;AAAA,MACzB,MAAM;AAAA,UAEJ,QAAQ,WAAW,GAAG,IAClB,oKACA,iJACN;AAAA;AAAA;AAAA,mBAGa,GAAG,sBAAsB,OAAO;AAAA;AAAA;AAAA,IAG/C,CAAC;AAAA,EACH;AACA,SAAO,QAAQ,QAAQ,KAAK;AAAA,IAC1B,MAAM;AAAA,IACN,OAAO;AAAA,IACP,OAAO;AAAA,IACP,MAAM;AAAA,IACN,QAAQ;AAAA,EACV,CAAC;AACH,CAAC;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The question a parked run is waiting on an answer to.
|
|
3
|
+
*
|
|
4
|
+
* `waiting_reason` and `waiting_token` say THAT a run is parked on a human
|
|
5
|
+
* decision and which wait point holds it; neither says what was asked. A
|
|
6
|
+
* `HumanTask` park therefore left the prompt, the kind of answer it wants, and
|
|
7
|
+
* the attempt budget nowhere a reader could find them: the question lived only
|
|
8
|
+
* in the action payload of an execution that had already released its owner,
|
|
9
|
+
* so the approvals inbox could describe the gate as "something is waiting" and
|
|
10
|
+
* no more (run-3, `coding-clarification`).
|
|
11
|
+
*
|
|
12
|
+
* This column is that missing half. It is the JSON the wait declared about
|
|
13
|
+
* itself — for `HumanTask`, `{kind, name, prompt, attempt, maxAttempts}` — and
|
|
14
|
+
* it is written and cleared with the other three waiting columns, so it can
|
|
15
|
+
* never describe a wait the run is no longer holding.
|
|
16
|
+
*
|
|
17
|
+
* Append-only, as every migration after the first must be: the column is
|
|
18
|
+
* nullable, so every row an earlier build wrote stays valid and reads back as
|
|
19
|
+
* a park that declared no question.
|
|
20
|
+
*
|
|
21
|
+
* @since 1.0.0
|
|
22
|
+
*/
|
|
23
|
+
import * as Effect from "effect/Effect";
|
|
24
|
+
import * as SqlClient from "effect/unstable/sql/SqlClient";
|
|
25
|
+
/**
|
|
26
|
+
* Adds `waiting_request` to `flows_runs`.
|
|
27
|
+
*
|
|
28
|
+
* @category migrations
|
|
29
|
+
* @since 1.0.0
|
|
30
|
+
*/
|
|
31
|
+
export declare const waitingRequest: Effect.Effect<void, unknown, SqlClient.SqlClient>;
|
|
32
|
+
//# sourceMappingURL=0004_waiting_request.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"0004_waiting_request.d.ts","sourceRoot":"","sources":["../../../src/migrations/0004_waiting_request.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAGH,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,KAAK,SAAS,MAAM,+BAA+B,CAAA;AAE1D;;;;;GAKG;AACH,eAAO,MAAM,cAAc,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,OAAO,EAAE,SAAS,CAAC,SAAS,CAK3E,CAAA"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
var waiting_request_exports = {};
|
|
30
|
+
__export(waiting_request_exports, {
|
|
31
|
+
waitingRequest: () => waitingRequest
|
|
32
|
+
});
|
|
33
|
+
module.exports = __toCommonJS(waiting_request_exports);
|
|
34
|
+
var Dialect = __toESM(require("@smthrs/database/Dialect"), 1);
|
|
35
|
+
var Effect = __toESM(require("effect/Effect"), 1);
|
|
36
|
+
var SqlClient = __toESM(require("effect/unstable/sql/SqlClient"), 1);
|
|
37
|
+
const waitingRequest = Effect.gen(function* () {
|
|
38
|
+
const sql = yield* SqlClient.SqlClient;
|
|
39
|
+
yield* sql`ALTER TABLE flows_runs ADD COLUMN waiting_request TEXT
|
|
40
|
+
CHECK (waiting_request IS NULL OR ${Dialect.jsonValid(sql, sql`waiting_request`)})`;
|
|
41
|
+
});
|
|
42
|
+
//# sourceMappingURL=0004_waiting_request.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/migrations/0004_waiting_request.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * The question a parked run is waiting on an answer to.\n *\n * `waiting_reason` and `waiting_token` say THAT a run is parked on a human\n * decision and which wait point holds it; neither says what was asked. A\n * `HumanTask` park therefore left the prompt, the kind of answer it wants, and\n * the attempt budget nowhere a reader could find them: the question lived only\n * in the action payload of an execution that had already released its owner,\n * so the approvals inbox could describe the gate as \"something is waiting\" and\n * no more (run-3, `coding-clarification`).\n *\n * This column is that missing half. It is the JSON the wait declared about\n * itself \u2014 for `HumanTask`, `{kind, name, prompt, attempt, maxAttempts}` \u2014 and\n * it is written and cleared with the other three waiting columns, so it can\n * never describe a wait the run is no longer holding.\n *\n * Append-only, as every migration after the first must be: the column is\n * nullable, so every row an earlier build wrote stays valid and reads back as\n * a park that declared no question.\n *\n * @since 1.0.0\n */\n\nimport * as Dialect from \"@smthrs/database/Dialect\"\nimport * as Effect from \"effect/Effect\"\nimport * as SqlClient from \"effect/unstable/sql/SqlClient\"\n\n/**\n * Adds `waiting_request` to `flows_runs`.\n *\n * @category migrations\n * @since 1.0.0\n */\nexport const waitingRequest: Effect.Effect<void, unknown, SqlClient.SqlClient> = Effect.gen(function*() {\n const sql = yield* SqlClient.SqlClient\n\n yield* sql`ALTER TABLE flows_runs ADD COLUMN waiting_request TEXT\n CHECK (waiting_request IS NULL OR ${Dialect.jsonValid(sql, sql`waiting_request`)})`\n})\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAuBA,cAAyB;AACzB,aAAwB;AACxB,gBAA2B;AAQpB,MAAM,iBAAoE,OAAO,IAAI,aAAY;AACtG,QAAM,MAAM,OAAO,UAAU;AAE7B,SAAO;AAAA,wCAC+B,QAAQ,UAAU,KAAK,oBAAoB,CAAC;AACpF,CAAC;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"type":"commonjs"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deterministic bundle of the production run and attempt services.
|
|
3
|
+
*
|
|
4
|
+
* @since 0.1.0
|
|
5
|
+
*/
|
|
6
|
+
import * as Layer from "effect/Layer";
|
|
7
|
+
import * as AttemptStore from "../AttemptStore.ts";
|
|
8
|
+
import * as RunStore from "../RunStore.ts";
|
|
9
|
+
/**
|
|
10
|
+
* Provides the production SQLite run and attempt stores over an in-memory
|
|
11
|
+
* database. Migrations run before either service is exposed.
|
|
12
|
+
*
|
|
13
|
+
* @category layers
|
|
14
|
+
* @since 0.1.0
|
|
15
|
+
*/
|
|
16
|
+
export declare const layer: Layer.Layer<AttemptStore.AttemptStore | RunStore.RunStore, import("effect/unstable/sql/SqlError").SqlError | import("effect/unstable/sql/Migrator").MigrationError, never>;
|
|
17
|
+
//# sourceMappingURL=TestRunStore.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TestRunStore.d.ts","sourceRoot":"","sources":["../../../src/test/TestRunStore.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,KAAK,MAAM,cAAc,CAAA;AACrC,OAAO,KAAK,YAAY,MAAM,oBAAoB,CAAA;AAElD,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAA;AAE1C;;;;;;GAMG;AACH,eAAO,MAAM,KAAK,4KAEjB,CAAA"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
var TestRunStore_exports = {};
|
|
30
|
+
__export(TestRunStore_exports, {
|
|
31
|
+
layer: () => layer
|
|
32
|
+
});
|
|
33
|
+
module.exports = __toCommonJS(TestRunStore_exports);
|
|
34
|
+
var TestDatabase = __toESM(require("@smthrs/database/test/TestDatabase"), 1);
|
|
35
|
+
var Layer = __toESM(require("effect/Layer"), 1);
|
|
36
|
+
var AttemptStore = __toESM(require("../AttemptStore.js"), 1);
|
|
37
|
+
var Migrations = __toESM(require("../Migrations.js"), 1);
|
|
38
|
+
var RunStore = __toESM(require("../RunStore.js"), 1);
|
|
39
|
+
const layer = Layer.mergeAll(RunStore.layer, AttemptStore.layer).pipe(
|
|
40
|
+
Layer.provide(Layer.provideMerge(Migrations.layer, TestDatabase.layer))
|
|
41
|
+
);
|
|
42
|
+
//# sourceMappingURL=TestRunStore.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/test/TestRunStore.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Deterministic bundle of the production run and attempt services.\n *\n * @since 0.1.0\n */\n\nimport * as TestDatabase from \"@smthrs/database/test/TestDatabase\"\nimport * as Layer from \"effect/Layer\"\nimport * as AttemptStore from \"../AttemptStore.ts\"\nimport * as Migrations from \"../Migrations.ts\"\nimport * as RunStore from \"../RunStore.ts\"\n\n/**\n * Provides the production SQLite run and attempt stores over an in-memory\n * database. Migrations run before either service is exposed.\n *\n * @category layers\n * @since 0.1.0\n */\nexport const layer = Layer.mergeAll(RunStore.layer, AttemptStore.layer).pipe(\n Layer.provide(Layer.provideMerge(Migrations.layer, TestDatabase.layer))\n)\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAMA,mBAA8B;AAC9B,YAAuB;AACvB,mBAA8B;AAC9B,iBAA4B;AAC5B,eAA0B;AASnB,MAAM,QAAQ,MAAM,SAAS,SAAS,OAAO,aAAa,KAAK,EAAE;AAAA,EACtE,MAAM,QAAQ,MAAM,aAAa,WAAW,OAAO,aAAa,KAAK,CAAC;AACxE;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|