@kronos-ts/postgres 0.1.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 +176 -0
- package/dist/adapter.d.ts +89 -0
- package/dist/adapter.d.ts.map +1 -0
- package/dist/adapter.js +29 -0
- package/dist/adapter.js.map +1 -0
- package/dist/adapters/bun-sql.d.ts +23 -0
- package/dist/adapters/bun-sql.d.ts.map +1 -0
- package/dist/adapters/bun-sql.js +175 -0
- package/dist/adapters/bun-sql.js.map +1 -0
- package/dist/adapters/pg.d.ts +24 -0
- package/dist/adapters/pg.d.ts.map +1 -0
- package/dist/adapters/pg.js +156 -0
- package/dist/adapters/pg.js.map +1 -0
- package/dist/adapters/postgres.d.ts +27 -0
- package/dist/adapters/postgres.d.ts.map +1 -0
- package/dist/adapters/postgres.js +99 -0
- package/dist/adapters/postgres.js.map +1 -0
- package/dist/advisory-locks.d.ts +56 -0
- package/dist/advisory-locks.d.ts.map +1 -0
- package/dist/advisory-locks.js +112 -0
- package/dist/advisory-locks.js.map +1 -0
- package/dist/criteria-sql.d.ts +29 -0
- package/dist/criteria-sql.d.ts.map +1 -0
- package/dist/criteria-sql.js +69 -0
- package/dist/criteria-sql.js.map +1 -0
- package/dist/errors.d.ts +30 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +41 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +26 -0
- package/dist/index.js.map +1 -0
- package/dist/postgres-event-store.d.ts +52 -0
- package/dist/postgres-event-store.d.ts.map +1 -0
- package/dist/postgres-event-store.js +496 -0
- package/dist/postgres-event-store.js.map +1 -0
- package/dist/postgres-snapshot-store.d.ts +34 -0
- package/dist/postgres-snapshot-store.d.ts.map +1 -0
- package/dist/postgres-snapshot-store.js +122 -0
- package/dist/postgres-snapshot-store.js.map +1 -0
- package/dist/postgres.d.ts +34 -0
- package/dist/postgres.d.ts.map +1 -0
- package/dist/postgres.js +42 -0
- package/dist/postgres.js.map +1 -0
- package/dist/schema.d.ts +96 -0
- package/dist/schema.d.ts.map +1 -0
- package/dist/schema.js +174 -0
- package/dist/schema.js.map +1 -0
- package/package.json +93 -0
- package/src/adapter.ts +104 -0
- package/src/adapters/bun-sql.ts +228 -0
- package/src/adapters/pg.ts +189 -0
- package/src/adapters/postgres.ts +134 -0
- package/src/advisory-locks.ts +139 -0
- package/src/criteria-sql.ts +89 -0
- package/src/errors.ts +47 -0
- package/src/index.ts +56 -0
- package/src/postgres-event-store.ts +593 -0
- package/src/postgres-snapshot-store.ts +153 -0
- package/src/postgres.ts +66 -0
- package/src/schema.ts +204 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"postgres-event-store.js","sourceRoot":"","sources":["../src/postgres-event-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Postgres-backed SnapshotStore implementation.
|
|
3
|
+
*
|
|
4
|
+
* Schema (from src/schema.ts):
|
|
5
|
+
* kronos_snapshots (
|
|
6
|
+
* state_name TEXT,
|
|
7
|
+
* state_id TEXT,
|
|
8
|
+
* position BIGINT,
|
|
9
|
+
* payload BYTEA,
|
|
10
|
+
* metadata JSONB,
|
|
11
|
+
* recorded_at TIMESTAMPTZ,
|
|
12
|
+
* PRIMARY KEY (state_name, state_id)
|
|
13
|
+
* )
|
|
14
|
+
*
|
|
15
|
+
* Payload roundtrip:
|
|
16
|
+
* store: Serializer.serialize(payload, type) -> SerializedObject { data, type, revision }
|
|
17
|
+
* .data goes to BYTEA, .type/.revision plus user metadata into JSONB.
|
|
18
|
+
* load: BYTEA + JSONB -> reconstruct SerializedObject -> Serializer.deserialize.
|
|
19
|
+
*
|
|
20
|
+
* State id stringification matches createInMemorySnapshotStore: objects are
|
|
21
|
+
* JSON-stringified, everything else gets String(). The eventsourcing protocol
|
|
22
|
+
* passes `unknown` ids, and the kronos_snapshots.state_id column is TEXT.
|
|
23
|
+
*/
|
|
24
|
+
import type { SnapshotStore } from "@kronos-ts/eventsourcing";
|
|
25
|
+
import type { Serializer } from "@kronos-ts/common";
|
|
26
|
+
import type { PostgresAdapter } from "./adapter.js";
|
|
27
|
+
import { type TableNames } from "./schema.js";
|
|
28
|
+
export interface PostgresSnapshotStoreConfig {
|
|
29
|
+
readonly adapter: PostgresAdapter;
|
|
30
|
+
readonly serializer: Serializer;
|
|
31
|
+
readonly tableNames?: TableNames;
|
|
32
|
+
}
|
|
33
|
+
export declare function createPostgresSnapshotStore(config: PostgresSnapshotStoreConfig): SnapshotStore;
|
|
34
|
+
//# sourceMappingURL=postgres-snapshot-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"postgres-snapshot-store.d.ts","sourceRoot":"","sources":["../src/postgres-snapshot-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,KAAK,EAAY,aAAa,EAAE,MAAM,0BAA0B,CAAA;AACvE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AACnD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAA;AACnD,OAAO,EAAE,KAAK,UAAU,EAAuB,MAAM,aAAa,CAAA;AAElE,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,CAAC,OAAO,EAAE,eAAe,CAAA;IACjC,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAA;IAC/B,QAAQ,CAAC,UAAU,CAAC,EAAE,UAAU,CAAA;CACjC;AAYD,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,2BAA2B,GAClC,aAAa,CAyGf"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Postgres-backed SnapshotStore implementation.
|
|
3
|
+
*
|
|
4
|
+
* Schema (from src/schema.ts):
|
|
5
|
+
* kronos_snapshots (
|
|
6
|
+
* state_name TEXT,
|
|
7
|
+
* state_id TEXT,
|
|
8
|
+
* position BIGINT,
|
|
9
|
+
* payload BYTEA,
|
|
10
|
+
* metadata JSONB,
|
|
11
|
+
* recorded_at TIMESTAMPTZ,
|
|
12
|
+
* PRIMARY KEY (state_name, state_id)
|
|
13
|
+
* )
|
|
14
|
+
*
|
|
15
|
+
* Payload roundtrip:
|
|
16
|
+
* store: Serializer.serialize(payload, type) -> SerializedObject { data, type, revision }
|
|
17
|
+
* .data goes to BYTEA, .type/.revision plus user metadata into JSONB.
|
|
18
|
+
* load: BYTEA + JSONB -> reconstruct SerializedObject -> Serializer.deserialize.
|
|
19
|
+
*
|
|
20
|
+
* State id stringification matches createInMemorySnapshotStore: objects are
|
|
21
|
+
* JSON-stringified, everything else gets String(). The eventsourcing protocol
|
|
22
|
+
* passes `unknown` ids, and the kronos_snapshots.state_id column is TEXT.
|
|
23
|
+
*/
|
|
24
|
+
import { DEFAULT_TABLE_NAMES } from "./schema.js";
|
|
25
|
+
function stateIdToString(id) {
|
|
26
|
+
return typeof id === "object" && id !== null ? JSON.stringify(id) : String(id);
|
|
27
|
+
}
|
|
28
|
+
// Internal envelope keys we co-locate in the metadata JSONB alongside any
|
|
29
|
+
// user-supplied snapshot.metadata entries. The "__kr_" prefix avoids
|
|
30
|
+
// colliding with user keys.
|
|
31
|
+
const SERIALIZER_TYPE_KEY = "__kr_serializer_type";
|
|
32
|
+
const SERIALIZER_REVISION_KEY = "__kr_serializer_revision";
|
|
33
|
+
export function createPostgresSnapshotStore(config) {
|
|
34
|
+
const { adapter, serializer } = config;
|
|
35
|
+
const tables = config.tableNames ?? DEFAULT_TABLE_NAMES;
|
|
36
|
+
return {
|
|
37
|
+
async store(stateName, id, snapshot) {
|
|
38
|
+
const stateId = stateIdToString(id);
|
|
39
|
+
const serialized = serializer.serialize(snapshot.payload, stateName, "");
|
|
40
|
+
const payloadBuf = Buffer.from(serialized.data);
|
|
41
|
+
const metadata = {
|
|
42
|
+
...snapshot.metadata,
|
|
43
|
+
[SERIALIZER_TYPE_KEY]: serialized.type,
|
|
44
|
+
[SERIALIZER_REVISION_KEY]: serialized.revision,
|
|
45
|
+
};
|
|
46
|
+
// recorded_at uses to_timestamp(epoch_seconds); snapshot.timestamp is milliseconds.
|
|
47
|
+
await adapter.query(`INSERT INTO ${tables.snapshots}
|
|
48
|
+
(state_name, state_id, position, payload, metadata, recorded_at)
|
|
49
|
+
VALUES ($1, $2, $3::bigint, $4, $5::jsonb, to_timestamp($6))
|
|
50
|
+
ON CONFLICT (state_name, state_id) DO UPDATE
|
|
51
|
+
SET position = EXCLUDED.position,
|
|
52
|
+
payload = EXCLUDED.payload,
|
|
53
|
+
metadata = EXCLUDED.metadata,
|
|
54
|
+
recorded_at = EXCLUDED.recorded_at`, [
|
|
55
|
+
stateName,
|
|
56
|
+
stateId,
|
|
57
|
+
String(snapshot.position),
|
|
58
|
+
payloadBuf,
|
|
59
|
+
JSON.stringify(metadata),
|
|
60
|
+
snapshot.timestamp / 1000,
|
|
61
|
+
]);
|
|
62
|
+
},
|
|
63
|
+
async load(stateName, id) {
|
|
64
|
+
const stateId = stateIdToString(id);
|
|
65
|
+
const row = await adapter.queryOne(`SELECT position::text AS position, payload, metadata, recorded_at
|
|
66
|
+
FROM ${tables.snapshots}
|
|
67
|
+
WHERE state_name = $1 AND state_id = $2`, [stateName, stateId]);
|
|
68
|
+
if (!row)
|
|
69
|
+
return undefined;
|
|
70
|
+
// Convert BYTEA result to Uint8Array for the deserializer
|
|
71
|
+
let payloadBytes;
|
|
72
|
+
if (row.payload instanceof Uint8Array) {
|
|
73
|
+
payloadBytes = row.payload;
|
|
74
|
+
}
|
|
75
|
+
else if (Buffer.isBuffer(row.payload)) {
|
|
76
|
+
payloadBytes = new Uint8Array(row.payload.buffer, row.payload.byteOffset, row.payload.byteLength);
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
payloadBytes = new Uint8Array(row.payload);
|
|
80
|
+
}
|
|
81
|
+
// bunSqlAdapter returns JSONB as a raw string; pgAdapter/postgresAdapter
|
|
82
|
+
// return it parsed. Normalise either way before key lookups.
|
|
83
|
+
const rawMetadata = typeof row.metadata === "string"
|
|
84
|
+
? JSON.parse(row.metadata)
|
|
85
|
+
: (row.metadata ?? {});
|
|
86
|
+
const serializedType = rawMetadata[SERIALIZER_TYPE_KEY] ?? stateName;
|
|
87
|
+
const serializedRevision = rawMetadata[SERIALIZER_REVISION_KEY] ?? "";
|
|
88
|
+
const userMetadata = {};
|
|
89
|
+
for (const [k, v] of Object.entries(rawMetadata)) {
|
|
90
|
+
if (k !== SERIALIZER_TYPE_KEY && k !== SERIALIZER_REVISION_KEY)
|
|
91
|
+
userMetadata[k] = v;
|
|
92
|
+
}
|
|
93
|
+
const payload = serializer.deserialize({
|
|
94
|
+
data: payloadBytes,
|
|
95
|
+
type: serializedType,
|
|
96
|
+
revision: serializedRevision,
|
|
97
|
+
});
|
|
98
|
+
// Reconstruct timestamp as milliseconds from what the DB returned
|
|
99
|
+
let timestamp;
|
|
100
|
+
if (row.recorded_at instanceof Date) {
|
|
101
|
+
timestamp = row.recorded_at.getTime();
|
|
102
|
+
}
|
|
103
|
+
else if (typeof row.recorded_at === "string") {
|
|
104
|
+
timestamp = new Date(row.recorded_at).getTime();
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
107
|
+
timestamp = Number(row.recorded_at);
|
|
108
|
+
}
|
|
109
|
+
return {
|
|
110
|
+
position: BigInt(row.position),
|
|
111
|
+
payload,
|
|
112
|
+
timestamp,
|
|
113
|
+
metadata: userMetadata,
|
|
114
|
+
};
|
|
115
|
+
},
|
|
116
|
+
async deleteSnapshots(stateName, id) {
|
|
117
|
+
const stateId = stateIdToString(id);
|
|
118
|
+
await adapter.query(`DELETE FROM ${tables.snapshots} WHERE state_name = $1 AND state_id = $2`, [stateName, stateId]);
|
|
119
|
+
},
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
//# sourceMappingURL=postgres-snapshot-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"postgres-snapshot-store.js","sourceRoot":"","sources":["../src/postgres-snapshot-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* postgres(config) — Extension factory for @kronos-ts/postgres.
|
|
3
|
+
*
|
|
4
|
+
* Populates two slots (D-12.01):
|
|
5
|
+
* - eventStore : EventStorageEngine via createPostgresEventStore
|
|
6
|
+
* - snapshotStore : SnapshotStore via createPostgresSnapshotStore
|
|
7
|
+
*
|
|
8
|
+
* Lifecycle (mirrors @kronos-ts/kronosdb extension shape):
|
|
9
|
+
* - app.onStart("connect", ...) — adapter.connect() with withRetry; then
|
|
10
|
+
* bootstrapSchema (skip if config.bootstrap === false so users running
|
|
11
|
+
* their own migration tooling are not surprised)
|
|
12
|
+
* - app.onStop("connect", ...) — adapter.disconnect()
|
|
13
|
+
*
|
|
14
|
+
* Does NOT populate eventBus, commandBus, queryBus, tokenStore, or
|
|
15
|
+
* transactionManager (D-12.01 — out of scope for this extension).
|
|
16
|
+
*/
|
|
17
|
+
import type { App } from "@kronos-ts/app";
|
|
18
|
+
import type { ResilienceConfig } from "@kronos-ts/common";
|
|
19
|
+
import type { PostgresAdapter } from "./adapter.js";
|
|
20
|
+
import { type TableNames } from "./schema.js";
|
|
21
|
+
export interface PostgresConfig {
|
|
22
|
+
/** Driver adapter — pg / postgres / bun-sql / custom. Created by the user. */
|
|
23
|
+
readonly adapter: PostgresAdapter;
|
|
24
|
+
/** Auto-create the schema on connect. Defaults to true. Set false when
|
|
25
|
+
* running your own migrations. */
|
|
26
|
+
readonly bootstrap?: boolean;
|
|
27
|
+
/** Override default table names (kronos_events / kronos_snapshots). */
|
|
28
|
+
readonly tableNames?: TableNames;
|
|
29
|
+
/** Retry policy for the initial connect + bootstrap. Defaults to
|
|
30
|
+
* framework defaults via withRetry. */
|
|
31
|
+
readonly resilience?: Partial<ResilienceConfig>;
|
|
32
|
+
}
|
|
33
|
+
export declare function postgres(config: PostgresConfig): (app: App) => void;
|
|
34
|
+
//# sourceMappingURL=postgres.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"postgres.d.ts","sourceRoot":"","sources":["../src/postgres.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAA;AACzC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AAEzD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAA;AAGnD,OAAO,EAAwC,KAAK,UAAU,EAAE,MAAM,aAAa,CAAA;AAEnF,MAAM,WAAW,cAAc;IAC7B,8EAA8E;IAC9E,QAAQ,CAAC,OAAO,EAAE,eAAe,CAAA;IACjC;uCACmC;IACnC,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAA;IAC5B,uEAAuE;IACvE,QAAQ,CAAC,UAAU,CAAC,EAAE,UAAU,CAAA;IAChC;4CACwC;IACxC,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC,gBAAgB,CAAC,CAAA;CAChD;AAED,wBAAgB,QAAQ,CAAC,MAAM,EAAE,cAAc,GAAG,CAAC,GAAG,EAAE,GAAG,KAAK,IAAI,CA2BnE"}
|
package/dist/postgres.js
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* postgres(config) — Extension factory for @kronos-ts/postgres.
|
|
3
|
+
*
|
|
4
|
+
* Populates two slots (D-12.01):
|
|
5
|
+
* - eventStore : EventStorageEngine via createPostgresEventStore
|
|
6
|
+
* - snapshotStore : SnapshotStore via createPostgresSnapshotStore
|
|
7
|
+
*
|
|
8
|
+
* Lifecycle (mirrors @kronos-ts/kronosdb extension shape):
|
|
9
|
+
* - app.onStart("connect", ...) — adapter.connect() with withRetry; then
|
|
10
|
+
* bootstrapSchema (skip if config.bootstrap === false so users running
|
|
11
|
+
* their own migration tooling are not surprised)
|
|
12
|
+
* - app.onStop("connect", ...) — adapter.disconnect()
|
|
13
|
+
*
|
|
14
|
+
* Does NOT populate eventBus, commandBus, queryBus, tokenStore, or
|
|
15
|
+
* transactionManager (D-12.01 — out of scope for this extension).
|
|
16
|
+
*/
|
|
17
|
+
import { withRetry } from "@kronos-ts/common";
|
|
18
|
+
import { createPostgresEventStore } from "./postgres-event-store.js";
|
|
19
|
+
import { createPostgresSnapshotStore } from "./postgres-snapshot-store.js";
|
|
20
|
+
import { bootstrapSchema, DEFAULT_TABLE_NAMES } from "./schema.js";
|
|
21
|
+
export function postgres(config) {
|
|
22
|
+
const { adapter, resilience } = config;
|
|
23
|
+
const bootstrap = config.bootstrap ?? true;
|
|
24
|
+
const tables = config.tableNames ?? DEFAULT_TABLE_NAMES;
|
|
25
|
+
return (app) => {
|
|
26
|
+
app.set("eventStore", ({ serializer, tagResolver }) => createPostgresEventStore({ adapter, serializer, tagResolver, tableNames: tables }));
|
|
27
|
+
app.set("snapshotStore", ({ serializer }) => createPostgresSnapshotStore({ adapter, serializer, tableNames: tables }));
|
|
28
|
+
app.onStart("connect", async () => {
|
|
29
|
+
await withRetry(() => adapter.connect(), { event: "initial-connect", ...resilience });
|
|
30
|
+
if (bootstrap) {
|
|
31
|
+
await withRetry(() => bootstrapSchema(adapter, { tableNames: tables }), {
|
|
32
|
+
event: "initial-connect",
|
|
33
|
+
...resilience,
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
app.onStop("connect", async () => {
|
|
38
|
+
await adapter.disconnect();
|
|
39
|
+
});
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=postgres.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"postgres.js","sourceRoot":"","sources":["../src/postgres.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAIH,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAA;AAE7C,OAAO,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAA;AACpE,OAAO,EAAE,2BAA2B,EAAE,MAAM,8BAA8B,CAAA;AAC1E,OAAO,EAAE,eAAe,EAAE,mBAAmB,EAAmB,MAAM,aAAa,CAAA;AAenF,MAAM,UAAU,QAAQ,CAAC,MAAsB;IAC7C,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,GAAG,MAAM,CAAA;IACtC,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,IAAI,IAAI,CAAA;IAC1C,MAAM,MAAM,GAAG,MAAM,CAAC,UAAU,IAAI,mBAAmB,CAAA;IAEvD,OAAO,CAAC,GAAQ,EAAE,EAAE;QAClB,GAAG,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC,EAAE,UAAU,EAAE,WAAW,EAAE,EAAE,EAAE,CACpD,wBAAwB,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,EAAE,CAAC,CACnF,CAAA;QACD,GAAG,CAAC,GAAG,CAAC,eAAe,EAAE,CAAC,EAAE,UAAU,EAAE,EAAE,EAAE,CAC1C,2BAA2B,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,EAAE,CAAC,CACzE,CAAA;QAED,GAAG,CAAC,OAAO,CAAC,SAAS,EAAE,KAAK,IAAI,EAAE;YAChC,MAAM,SAAS,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,iBAAiB,EAAE,GAAG,UAAU,EAAE,CAAC,CAAA;YACrF,IAAI,SAAS,EAAE,CAAC;gBACd,MAAM,SAAS,CAAC,GAAG,EAAE,CAAC,eAAe,CAAC,OAAO,EAAE,EAAE,UAAU,EAAE,MAAM,EAAE,CAAC,EAAE;oBACtE,KAAK,EAAE,iBAAiB;oBACxB,GAAG,UAAU;iBACd,CAAC,CAAA;YACJ,CAAC;QACH,CAAC,CAAC,CAAA;QAEF,GAAG,CAAC,MAAM,CAAC,SAAS,EAAE,KAAK,IAAI,EAAE;YAC/B,MAAM,OAAO,CAAC,UAAU,EAAE,CAAA;QAC5B,CAAC,CAAC,CAAA;IACJ,CAAC,CAAA;AACH,CAAC"}
|
package/dist/schema.d.ts
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Postgres event-store schema DDL builders + idempotent bootstrap.
|
|
3
|
+
*
|
|
4
|
+
* Plan 12-02 deliverable. Locks the table shape used by:
|
|
5
|
+
* - the append SP (Plan 04) — INSERT … RETURNING sequence_position, transaction_id
|
|
6
|
+
* - the streaming query (Plan 05) — WHERE (transaction_id, sequence_position) > $bookmark
|
|
7
|
+
* AND transaction_id < pg_snapshot_xmin(pg_current_snapshot())
|
|
8
|
+
* - the sourcing query (Plan 04) — WHERE tags @> $required AND type IN (...)
|
|
9
|
+
* - the snapshot store (Plan 05) — INSERT … ON CONFLICT (state_name, state_id) DO UPDATE
|
|
10
|
+
*
|
|
11
|
+
* Minimum Postgres version: 14 (xid8 + pg_snapshot_xmin require PG14, per D-12.13).
|
|
12
|
+
* Tag storage: `text[]` with GIN(fastupdate=off) — `@>` contains-all semantics in SQL.
|
|
13
|
+
* Payload storage: events use JSONB (queryable metadata, compressed); snapshots use BYTEA
|
|
14
|
+
* (Serializer returns Uint8Array; no JSONB roundtrip cost).
|
|
15
|
+
*/
|
|
16
|
+
export interface TableNames {
|
|
17
|
+
readonly events: string;
|
|
18
|
+
readonly snapshots: string;
|
|
19
|
+
}
|
|
20
|
+
export declare const DEFAULT_TABLE_NAMES: TableNames;
|
|
21
|
+
/**
|
|
22
|
+
* Session-scoped advisory lock key for the schema bootstrap.
|
|
23
|
+
*
|
|
24
|
+
* Value `-89001n` matches kraken-tech's `ensureInstalled()` key, so an
|
|
25
|
+
* operator running both libraries against the same database experiences
|
|
26
|
+
* serialised bootstraps instead of duplicate-key races. Held with
|
|
27
|
+
* `pg_advisory_lock` (session-scoped, NOT xact-scoped) because some
|
|
28
|
+
* Postgres versions implicitly commit DDL — xact-scoped locks would
|
|
29
|
+
* release mid-bootstrap.
|
|
30
|
+
*/
|
|
31
|
+
export declare const KRONOS_SCHEMA_LOCK_KEY: bigint;
|
|
32
|
+
export declare function buildEventsTableDDL(tables: TableNames): string;
|
|
33
|
+
export declare function buildEventsIndexesDDL(tables: TableNames): string;
|
|
34
|
+
export declare function buildSnapshotsTableDDL(tables: TableNames): string;
|
|
35
|
+
/**
|
|
36
|
+
* Minimal adapter contract bootstrapSchema needs. A subset of the full
|
|
37
|
+
* PostgresAdapter interface authored in Plan 12-03 — structurally
|
|
38
|
+
* compatible so Plan 12-04's adapter instance can be passed in directly.
|
|
39
|
+
* Kept local to schema.ts to keep this plan independent of Plan 03.
|
|
40
|
+
*/
|
|
41
|
+
export interface SchemaBootstrapAdapter {
|
|
42
|
+
query(sql: string, params?: unknown[]): Promise<unknown>;
|
|
43
|
+
}
|
|
44
|
+
export interface BootstrapSchemaOptions {
|
|
45
|
+
/** Override `kronos_events` / `kronos_snapshots`. */
|
|
46
|
+
readonly tableNames?: TableNames;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Append-with-DCB-check stored procedure.
|
|
50
|
+
*
|
|
51
|
+
* Called from `createPostgresEventStore.appendEvents` (Plan 04 Task 3)
|
|
52
|
+
* after advisory-lock acquisition. The SP is the single SQL statement
|
|
53
|
+
* that BOTH performs the conflict check AND inserts the new events —
|
|
54
|
+
* keeping them atomic without round-tripping a separate SELECT.
|
|
55
|
+
*
|
|
56
|
+
* Inputs (positional):
|
|
57
|
+
* $1 marker_position bigint — the AppendCondition.marker.position
|
|
58
|
+
* $2 has_condition boolean — false ⇒ skip the conflict check
|
|
59
|
+
* $3 criteria_where_sql text — Plan 04's criteria-sql builder output
|
|
60
|
+
* $4 criteria_params jsonb — parameter array for criteria_where_sql
|
|
61
|
+
* $5 event_ids uuid[] — N event identifiers (EventMessage.identifier, UUID v7)
|
|
62
|
+
* $6 event_types text[] — N event types (one per event)
|
|
63
|
+
* $7 event_tags text[][] — N tag arrays
|
|
64
|
+
* $8 event_payloads jsonb[] — N JSONB payloads
|
|
65
|
+
* $9 event_metadata jsonb[] — N metadata maps
|
|
66
|
+
*
|
|
67
|
+
* Returns: TABLE(out_position bigint, out_xid xid8) — one row per inserted event.
|
|
68
|
+
* The last row carries the consistency marker.
|
|
69
|
+
*
|
|
70
|
+
* On conflict: RAISE EXCEPTION USING ERRCODE = 'KR001' (D-12.12).
|
|
71
|
+
* On duplicate event_id (UNIQUE violation): Postgres raises SQLSTATE 23505;
|
|
72
|
+
* caller treats as idempotent no-op or surfaces per consumer policy.
|
|
73
|
+
*
|
|
74
|
+
* NOTE: dynamic-SQL is used (EXECUTE) because the criteria WHERE clause is
|
|
75
|
+
* parameter-shaped and varies per call. SQL injection is mitigated by the
|
|
76
|
+
* fact that criteria_where_sql is produced by buildCriteriaWhere — a typed
|
|
77
|
+
* builder that NEVER concatenates user data into the WHERE string (all user
|
|
78
|
+
* data flows through criteria_params as JSONB).
|
|
79
|
+
*/
|
|
80
|
+
export declare function buildAppendStoredProcedureDDL(tables: TableNames): string;
|
|
81
|
+
/**
|
|
82
|
+
* Idempotently create the event-store schema.
|
|
83
|
+
*
|
|
84
|
+
* Holds a session-scoped advisory lock (KRONOS_SCHEMA_LOCK_KEY) for the
|
|
85
|
+
* duration so concurrent bootstraps (e.g. two app instances starting
|
|
86
|
+
* simultaneously) serialise instead of racing on CREATE TABLE.
|
|
87
|
+
*
|
|
88
|
+
* The lock is RELEASED in a finally block — partial-DDL-then-throw must
|
|
89
|
+
* NEVER leak a session lock that would block all subsequent bootstraps
|
|
90
|
+
* on the same connection.
|
|
91
|
+
*
|
|
92
|
+
* The append stored procedure is applied as part of bootstrap so that
|
|
93
|
+
* the SP is always up-to-date with the schema version.
|
|
94
|
+
*/
|
|
95
|
+
export declare function bootstrapSchema(adapter: SchemaBootstrapAdapter, options?: BootstrapSchemaOptions): Promise<void>;
|
|
96
|
+
//# sourceMappingURL=schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;CAC3B;AAED,eAAO,MAAM,mBAAmB,EAAE,UAGjC,CAAA;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,sBAAsB,EAAE,MAAgB,CAAA;AAErD,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CAkB9D;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CAMhE;AAED,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CAUjE;AAED;;;;;GAKG;AACH,MAAM,WAAW,sBAAsB;IACrC,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;CACzD;AAED,MAAM,WAAW,sBAAsB;IACrC,qDAAqD;IACrD,QAAQ,CAAC,UAAU,CAAC,EAAE,UAAU,CAAA;CACjC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAgB,6BAA6B,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CAyCxE;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,sBAAsB,EAC/B,OAAO,GAAE,sBAA2B,GACnC,OAAO,CAAC,IAAI,CAAC,CAkBf"}
|
package/dist/schema.js
ADDED
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Postgres event-store schema DDL builders + idempotent bootstrap.
|
|
3
|
+
*
|
|
4
|
+
* Plan 12-02 deliverable. Locks the table shape used by:
|
|
5
|
+
* - the append SP (Plan 04) — INSERT … RETURNING sequence_position, transaction_id
|
|
6
|
+
* - the streaming query (Plan 05) — WHERE (transaction_id, sequence_position) > $bookmark
|
|
7
|
+
* AND transaction_id < pg_snapshot_xmin(pg_current_snapshot())
|
|
8
|
+
* - the sourcing query (Plan 04) — WHERE tags @> $required AND type IN (...)
|
|
9
|
+
* - the snapshot store (Plan 05) — INSERT … ON CONFLICT (state_name, state_id) DO UPDATE
|
|
10
|
+
*
|
|
11
|
+
* Minimum Postgres version: 14 (xid8 + pg_snapshot_xmin require PG14, per D-12.13).
|
|
12
|
+
* Tag storage: `text[]` with GIN(fastupdate=off) — `@>` contains-all semantics in SQL.
|
|
13
|
+
* Payload storage: events use JSONB (queryable metadata, compressed); snapshots use BYTEA
|
|
14
|
+
* (Serializer returns Uint8Array; no JSONB roundtrip cost).
|
|
15
|
+
*/
|
|
16
|
+
export const DEFAULT_TABLE_NAMES = {
|
|
17
|
+
events: "kronos_events",
|
|
18
|
+
snapshots: "kronos_snapshots",
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Session-scoped advisory lock key for the schema bootstrap.
|
|
22
|
+
*
|
|
23
|
+
* Value `-89001n` matches kraken-tech's `ensureInstalled()` key, so an
|
|
24
|
+
* operator running both libraries against the same database experiences
|
|
25
|
+
* serialised bootstraps instead of duplicate-key races. Held with
|
|
26
|
+
* `pg_advisory_lock` (session-scoped, NOT xact-scoped) because some
|
|
27
|
+
* Postgres versions implicitly commit DDL — xact-scoped locks would
|
|
28
|
+
* release mid-bootstrap.
|
|
29
|
+
*/
|
|
30
|
+
export const KRONOS_SCHEMA_LOCK_KEY = -89001n;
|
|
31
|
+
export function buildEventsTableDDL(tables) {
|
|
32
|
+
// event_id is sourced from EventMessage.identifier (UUID v7 per quick 260511-mks).
|
|
33
|
+
// UNIQUE auto-creates a btree; v7's time-ordered prefix keeps it compact under
|
|
34
|
+
// append load (a v4 random UUID would fragment the leaf pages over time).
|
|
35
|
+
return `CREATE TABLE IF NOT EXISTS ${tables.events} (
|
|
36
|
+
sequence_position BIGSERIAL PRIMARY KEY,
|
|
37
|
+
event_id UUID NOT NULL UNIQUE,
|
|
38
|
+
transaction_id xid8 NOT NULL DEFAULT pg_current_xact_id(),
|
|
39
|
+
type TEXT COLLATE "C" NOT NULL,
|
|
40
|
+
tags TEXT[] NOT NULL DEFAULT '{}',
|
|
41
|
+
payload JSONB NOT NULL,
|
|
42
|
+
metadata JSONB NOT NULL DEFAULT '{}',
|
|
43
|
+
recorded_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
|
44
|
+
) WITH (
|
|
45
|
+
autovacuum_freeze_min_age = 10000000,
|
|
46
|
+
autovacuum_freeze_table_age = 100000000,
|
|
47
|
+
FILLFACTOR = 100
|
|
48
|
+
);`;
|
|
49
|
+
}
|
|
50
|
+
export function buildEventsIndexesDDL(tables) {
|
|
51
|
+
return `CREATE UNIQUE INDEX IF NOT EXISTS ${tables.events}_type_pos_idx
|
|
52
|
+
ON ${tables.events} (type COLLATE "C", sequence_position DESC);
|
|
53
|
+
|
|
54
|
+
CREATE INDEX IF NOT EXISTS ${tables.events}_tags_gin
|
|
55
|
+
ON ${tables.events} USING GIN(tags) WITH (fastupdate = off);`;
|
|
56
|
+
}
|
|
57
|
+
export function buildSnapshotsTableDDL(tables) {
|
|
58
|
+
return `CREATE TABLE IF NOT EXISTS ${tables.snapshots} (
|
|
59
|
+
state_name TEXT COLLATE "C" NOT NULL,
|
|
60
|
+
state_id TEXT NOT NULL,
|
|
61
|
+
position BIGINT NOT NULL,
|
|
62
|
+
payload BYTEA NOT NULL,
|
|
63
|
+
metadata JSONB NOT NULL DEFAULT '{}',
|
|
64
|
+
recorded_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
65
|
+
PRIMARY KEY (state_name, state_id)
|
|
66
|
+
);`;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Append-with-DCB-check stored procedure.
|
|
70
|
+
*
|
|
71
|
+
* Called from `createPostgresEventStore.appendEvents` (Plan 04 Task 3)
|
|
72
|
+
* after advisory-lock acquisition. The SP is the single SQL statement
|
|
73
|
+
* that BOTH performs the conflict check AND inserts the new events —
|
|
74
|
+
* keeping them atomic without round-tripping a separate SELECT.
|
|
75
|
+
*
|
|
76
|
+
* Inputs (positional):
|
|
77
|
+
* $1 marker_position bigint — the AppendCondition.marker.position
|
|
78
|
+
* $2 has_condition boolean — false ⇒ skip the conflict check
|
|
79
|
+
* $3 criteria_where_sql text — Plan 04's criteria-sql builder output
|
|
80
|
+
* $4 criteria_params jsonb — parameter array for criteria_where_sql
|
|
81
|
+
* $5 event_ids uuid[] — N event identifiers (EventMessage.identifier, UUID v7)
|
|
82
|
+
* $6 event_types text[] — N event types (one per event)
|
|
83
|
+
* $7 event_tags text[][] — N tag arrays
|
|
84
|
+
* $8 event_payloads jsonb[] — N JSONB payloads
|
|
85
|
+
* $9 event_metadata jsonb[] — N metadata maps
|
|
86
|
+
*
|
|
87
|
+
* Returns: TABLE(out_position bigint, out_xid xid8) — one row per inserted event.
|
|
88
|
+
* The last row carries the consistency marker.
|
|
89
|
+
*
|
|
90
|
+
* On conflict: RAISE EXCEPTION USING ERRCODE = 'KR001' (D-12.12).
|
|
91
|
+
* On duplicate event_id (UNIQUE violation): Postgres raises SQLSTATE 23505;
|
|
92
|
+
* caller treats as idempotent no-op or surfaces per consumer policy.
|
|
93
|
+
*
|
|
94
|
+
* NOTE: dynamic-SQL is used (EXECUTE) because the criteria WHERE clause is
|
|
95
|
+
* parameter-shaped and varies per call. SQL injection is mitigated by the
|
|
96
|
+
* fact that criteria_where_sql is produced by buildCriteriaWhere — a typed
|
|
97
|
+
* builder that NEVER concatenates user data into the WHERE string (all user
|
|
98
|
+
* data flows through criteria_params as JSONB).
|
|
99
|
+
*/
|
|
100
|
+
export function buildAppendStoredProcedureDDL(tables) {
|
|
101
|
+
return `CREATE OR REPLACE FUNCTION kronos_append_with_check(
|
|
102
|
+
marker_position bigint,
|
|
103
|
+
has_condition boolean,
|
|
104
|
+
criteria_where_sql text,
|
|
105
|
+
criteria_params jsonb,
|
|
106
|
+
event_ids uuid[],
|
|
107
|
+
event_types text[],
|
|
108
|
+
event_tags text[][],
|
|
109
|
+
event_payloads jsonb[],
|
|
110
|
+
event_metadata jsonb[]
|
|
111
|
+
) RETURNS TABLE(out_position bigint, out_xid xid8) AS $$
|
|
112
|
+
DECLARE
|
|
113
|
+
conflict_count bigint;
|
|
114
|
+
i integer;
|
|
115
|
+
BEGIN
|
|
116
|
+
IF has_condition THEN
|
|
117
|
+
EXECUTE format(
|
|
118
|
+
'SELECT count(*) FROM ${tables.events} WHERE sequence_position > $1 AND (%s)',
|
|
119
|
+
criteria_where_sql
|
|
120
|
+
)
|
|
121
|
+
USING marker_position, criteria_params
|
|
122
|
+
INTO conflict_count;
|
|
123
|
+
|
|
124
|
+
IF conflict_count > 0 THEN
|
|
125
|
+
RAISE EXCEPTION 'Append condition violated: % conflicting event(s) after position %',
|
|
126
|
+
conflict_count, marker_position
|
|
127
|
+
USING ERRCODE = 'KR001';
|
|
128
|
+
END IF;
|
|
129
|
+
END IF;
|
|
130
|
+
|
|
131
|
+
FOR i IN 1 .. array_length(event_types, 1) LOOP
|
|
132
|
+
-- event_id UNIQUE constraint surfaces duplicates as SQLSTATE 23505 (D-12.12);
|
|
133
|
+
-- caller (Plan 04 Task 3) maps that to AppendConditionError or idempotent skip.
|
|
134
|
+
INSERT INTO ${tables.events} (event_id, type, tags, payload, metadata)
|
|
135
|
+
VALUES (event_ids[i], event_types[i], event_tags[i:i][1], event_payloads[i], event_metadata[i])
|
|
136
|
+
RETURNING sequence_position, transaction_id INTO out_position, out_xid;
|
|
137
|
+
RETURN NEXT;
|
|
138
|
+
END LOOP;
|
|
139
|
+
END;
|
|
140
|
+
$$ LANGUAGE plpgsql;`;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Idempotently create the event-store schema.
|
|
144
|
+
*
|
|
145
|
+
* Holds a session-scoped advisory lock (KRONOS_SCHEMA_LOCK_KEY) for the
|
|
146
|
+
* duration so concurrent bootstraps (e.g. two app instances starting
|
|
147
|
+
* simultaneously) serialise instead of racing on CREATE TABLE.
|
|
148
|
+
*
|
|
149
|
+
* The lock is RELEASED in a finally block — partial-DDL-then-throw must
|
|
150
|
+
* NEVER leak a session lock that would block all subsequent bootstraps
|
|
151
|
+
* on the same connection.
|
|
152
|
+
*
|
|
153
|
+
* The append stored procedure is applied as part of bootstrap so that
|
|
154
|
+
* the SP is always up-to-date with the schema version.
|
|
155
|
+
*/
|
|
156
|
+
export async function bootstrapSchema(adapter, options = {}) {
|
|
157
|
+
const tables = options.tableNames ?? DEFAULT_TABLE_NAMES;
|
|
158
|
+
// Acquire migration lock. Session-scoped is intentional: some Postgres
|
|
159
|
+
// versions implicitly commit DDL, which would release an xact-scoped
|
|
160
|
+
// lock mid-bootstrap.
|
|
161
|
+
await adapter.query(`SELECT pg_advisory_lock($1)`, [KRONOS_SCHEMA_LOCK_KEY]);
|
|
162
|
+
try {
|
|
163
|
+
await adapter.query(buildEventsTableDDL(tables));
|
|
164
|
+
await adapter.query(buildEventsIndexesDDL(tables));
|
|
165
|
+
await adapter.query(buildSnapshotsTableDDL(tables));
|
|
166
|
+
await adapter.query(buildAppendStoredProcedureDDL(tables));
|
|
167
|
+
}
|
|
168
|
+
finally {
|
|
169
|
+
// Release even on partial-DDL failure. The error (if any) propagates
|
|
170
|
+
// to the caller after the lock has been freed.
|
|
171
|
+
await adapter.query(`SELECT pg_advisory_unlock($1)`, [KRONOS_SCHEMA_LOCK_KEY]);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
//# sourceMappingURL=schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAOH,MAAM,CAAC,MAAM,mBAAmB,GAAe;IAC7C,MAAM,EAAE,eAAe;IACvB,SAAS,EAAE,kBAAkB;CAC9B,CAAA;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAW,CAAC,MAAM,CAAA;AAErD,MAAM,UAAU,mBAAmB,CAAC,MAAkB;IACpD,mFAAmF;IACnF,+EAA+E;IAC/E,0EAA0E;IAC1E,OAAO,8BAA8B,MAAM,CAAC,MAAM;;;;;;;;;;;;;GAajD,CAAA;AACH,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,MAAkB;IACtD,OAAO,qCAAqC,MAAM,CAAC,MAAM;OACpD,MAAM,CAAC,MAAM;;6BAES,MAAM,CAAC,MAAM;OACnC,MAAM,CAAC,MAAM,2CAA2C,CAAA;AAC/D,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,MAAkB;IACvD,OAAO,8BAA8B,MAAM,CAAC,SAAS;;;;;;;;GAQpD,CAAA;AACH,CAAC;AAiBD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,MAAM,UAAU,6BAA6B,CAAC,MAAkB;IAC9D,OAAO;;;;;;;;;;;;;;;;;8BAiBqB,MAAM,CAAC,MAAM;;;;;;;;;;;;;;;;kBAgBzB,MAAM,CAAC,MAAM;;;;;;qBAMV,CAAA;AACrB,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,OAA+B,EAC/B,UAAkC,EAAE;IAEpC,MAAM,MAAM,GAAG,OAAO,CAAC,UAAU,IAAI,mBAAmB,CAAA;IAExD,uEAAuE;IACvE,qEAAqE;IACrE,sBAAsB;IACtB,MAAM,OAAO,CAAC,KAAK,CAAC,6BAA6B,EAAE,CAAC,sBAAsB,CAAC,CAAC,CAAA;IAE5E,IAAI,CAAC;QACH,MAAM,OAAO,CAAC,KAAK,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC,CAAA;QAChD,MAAM,OAAO,CAAC,KAAK,CAAC,qBAAqB,CAAC,MAAM,CAAC,CAAC,CAAA;QAClD,MAAM,OAAO,CAAC,KAAK,CAAC,sBAAsB,CAAC,MAAM,CAAC,CAAC,CAAA;QACnD,MAAM,OAAO,CAAC,KAAK,CAAC,6BAA6B,CAAC,MAAM,CAAC,CAAC,CAAA;IAC5D,CAAC;YAAS,CAAC;QACT,qEAAqE;QACrE,+CAA+C;QAC/C,MAAM,OAAO,CAAC,KAAK,CAAC,+BAA+B,EAAE,CAAC,sBAAsB,CAAC,CAAC,CAAA;IAChF,CAAC;AACH,CAAC"}
|