@dudousxd/nestjs-durable-transport-db 0.1.0 → 0.2.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.
@@ -1,241 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.DbTransport = exports.typeOrmExecutor = exports.mikroOrmExecutor = void 0;
4
- const nestjs_durable_core_1 = require("@dudousxd/nestjs-durable-core");
5
- var executors_1 = require("./executors");
6
- Object.defineProperty(exports, "mikroOrmExecutor", { enumerable: true, get: function () { return executors_1.mikroOrmExecutor; } });
7
- Object.defineProperty(exports, "typeOrmExecutor", { enumerable: true, get: function () { return executors_1.typeOrmExecutor; } });
8
- /**
9
- * A SQL-backed `Transport` — DBOS-style. Instead of a broker (Redis/SQS), remote steps are **rows**
10
- * in the same database the durable store already uses: `dispatch` inserts a task row, a worker
11
- * claims it with `SELECT … FOR UPDATE SKIP LOCKED` (so instances never double-claim), runs it, and
12
- * writes a result row the engine polls. Zero new infrastructure — the DB you already have IS the
13
- * queue.
14
- *
15
- * Trade-off vs a real broker: throughput is bounded by polling + row contention. Great for
16
- * workflow/pipeline scale (modest rate, long steps); not for high-fanout firehoses.
17
- *
18
- * Requires `FOR UPDATE SKIP LOCKED` — **MySQL 8+** or **Postgres 9.5+** (not SQLite). Run one
19
- * instance engine-side (`onResult`, dispatches) and one per worker process (`handle()` for its group).
20
- */
21
- class DbTransport {
22
- exec;
23
- group;
24
- tasksTable;
25
- resultsTable;
26
- pollMs;
27
- leaseMs;
28
- batchSize;
29
- autoCreate;
30
- instanceId;
31
- isPg;
32
- handlers = new Map();
33
- running = true;
34
- schemaReady;
35
- taskLoop;
36
- resultLoop;
37
- constructor(options) {
38
- this.exec = options.executor;
39
- this.group = options.group;
40
- const prefix = options.prefix ?? 'durable';
41
- this.tasksTable = `${prefix}_transport_tasks`;
42
- this.resultsTable = `${prefix}_transport_results`;
43
- this.pollMs = options.pollMs ?? 500;
44
- this.leaseMs = options.leaseMs ?? 30_000;
45
- this.batchSize = options.batchSize ?? 10;
46
- this.autoCreate = options.autoCreate ?? true;
47
- this.instanceId = options.instanceId ?? `db-${Math.floor(Date.now()).toString(36)}`;
48
- this.isPg = this.exec.dialect === 'postgres';
49
- }
50
- // ── dialect helpers ──────────────────────────────────────────────────────────────────────────
51
- /** Positional placeholder for param `i` (1-based): `$i` on Postgres, `?` elsewhere. */
52
- ph(i) {
53
- return this.isPg ? `$${i}` : '?';
54
- }
55
- q(id) {
56
- return this.exec.escapeId(id);
57
- }
58
- now() {
59
- return Math.floor(Date.now());
60
- }
61
- // ── schema ───────────────────────────────────────────────────────────────────────────────────
62
- ensureSchema() {
63
- if (!this.schemaReady)
64
- this.schemaReady = this.createTables();
65
- return this.schemaReady;
66
- }
67
- async createTables() {
68
- if (!this.autoCreate)
69
- return;
70
- const str = 'varchar(191)';
71
- const txt = this.isPg ? 'text' : 'longtext';
72
- const tasks = this.q(this.tasksTable);
73
- const results = this.q(this.resultsTable);
74
- await this.exec.query(`CREATE TABLE IF NOT EXISTS ${tasks} (
75
- ${this.q('step_id')} ${str} PRIMARY KEY,
76
- ${this.q('run_id')} ${str} NOT NULL,
77
- ${this.q('seq')} integer NOT NULL,
78
- ${this.q('name')} ${str} NOT NULL,
79
- ${this.q('grp')} ${str} NOT NULL,
80
- ${this.q('input')} ${txt},
81
- ${this.q('attempt')} integer NOT NULL,
82
- ${this.q('status')} varchar(32) NOT NULL,
83
- ${this.q('claimed_by')} ${str},
84
- ${this.q('claimed_at')} bigint,
85
- ${this.q('created_at')} bigint NOT NULL
86
- )`);
87
- await this.exec.query(`CREATE TABLE IF NOT EXISTS ${results} (
88
- ${this.q('step_id')} ${str} PRIMARY KEY,
89
- ${this.q('run_id')} ${str} NOT NULL,
90
- ${this.q('seq')} integer NOT NULL,
91
- ${this.q('status')} varchar(32) NOT NULL,
92
- ${this.q('output')} ${txt},
93
- ${this.q('error')} ${txt},
94
- ${this.q('claimed_by')} ${str},
95
- ${this.q('claimed_at')} bigint,
96
- ${this.q('created_at')} bigint NOT NULL
97
- )`);
98
- // Best-effort index for the group poll (MySQL has no CREATE INDEX IF NOT EXISTS < 8.0.13).
99
- await this.exec
100
- .query(`CREATE INDEX ${this.q(`${this.tasksTable}_grp_idx`)} ON ${tasks} (${this.q('grp')}, ${this.q('status')}, ${this.q('created_at')})`)
101
- .catch(() => { });
102
- }
103
- // ── engine → worker ────────────────────────────────────────────────────────────────────────
104
- async dispatch(task) {
105
- await this.ensureSchema();
106
- const t = this.q(this.tasksTable);
107
- // Idempotent: a redelivered dispatch for the same step_id is ignored (the row already exists).
108
- const ignore = this.isPg
109
- ? `INSERT INTO ${t} (...) ON CONFLICT (${this.q('step_id')}) DO NOTHING`
110
- : `INSERT IGNORE INTO ${t} (...)`;
111
- const cols = ['step_id', 'run_id', 'seq', 'name', 'grp', 'input', 'attempt', 'status', 'created_at'];
112
- const sql = ignore.replace('(...)', `(${cols.map((c) => this.q(c)).join(', ')}) VALUES (${cols.map((_, i) => this.ph(i + 1)).join(', ')})`);
113
- await this.exec.query(sql, [
114
- task.stepId,
115
- task.runId,
116
- task.seq,
117
- task.name,
118
- task.group,
119
- JSON.stringify(task.input ?? null),
120
- task.attempt,
121
- 'pending',
122
- this.now(),
123
- ]);
124
- }
125
- // ── worker → engine ────────────────────────────────────────────────────────────────────────
126
- handle(name, fn) {
127
- if (!this.group)
128
- throw new Error('DbTransport needs a `group` to register handlers');
129
- this.handlers.set(name, fn);
130
- if (!this.taskLoop)
131
- this.taskLoop = this.loop(() => this.drainTasks(this.group));
132
- }
133
- onResult(handler) {
134
- if (!this.resultLoop)
135
- this.resultLoop = this.loop(() => this.drainResults(handler));
136
- }
137
- onHeartbeat(_handler) {
138
- // Not modelled; the lease/reclaim on `claimed_at` is the liveness mechanism.
139
- }
140
- // ── polling ──────────────────────────────────────────────────────────────────────────────────
141
- /** Run `tick` repeatedly; sleep `pollMs` when it reports an empty queue. Stops on `close()`. */
142
- async loop(tick) {
143
- await this.ensureSchema();
144
- while (this.running) {
145
- let processed = 0;
146
- try {
147
- processed = await tick();
148
- }
149
- catch (err) {
150
- if (this.running)
151
- console.error('[DbTransport] poll failed', err);
152
- }
153
- if (processed === 0)
154
- await this.sleep(this.pollMs);
155
- }
156
- }
157
- /** Claim a batch of tasks (FOR UPDATE SKIP LOCKED), then run each outside the lock. */
158
- async drainTasks(group) {
159
- const claimed = await this.claim(this.tasksTable, `${this.q('grp')} = ${this.ph(1)}`, [group]);
160
- for (const row of claimed) {
161
- const task = {
162
- runId: row.run_id,
163
- seq: Number(row.seq),
164
- stepId: row.step_id,
165
- name: row.name,
166
- group,
167
- input: row.input == null ? undefined : JSON.parse(row.input),
168
- attempt: Number(row.attempt),
169
- };
170
- const result = await (0, nestjs_durable_core_1.runStepHandler)(task, this.handlers.get(task.name));
171
- await this.insertResult(result);
172
- await this.exec.query(`DELETE FROM ${this.q(this.tasksTable)} WHERE ${this.q('step_id')} = ${this.ph(1)}`, [task.stepId]);
173
- }
174
- return claimed.length;
175
- }
176
- /** Claim a batch of results, deliver each to the engine, then delete it. */
177
- async drainResults(handler) {
178
- const claimed = await this.claim(this.resultsTable, '1 = 1', []);
179
- for (const row of claimed) {
180
- const result = {
181
- runId: row.run_id,
182
- seq: Number(row.seq),
183
- stepId: row.step_id,
184
- status: row.status,
185
- output: row.output == null ? undefined : JSON.parse(row.output),
186
- error: row.error == null ? undefined : JSON.parse(row.error),
187
- };
188
- await handler(result);
189
- await this.exec.query(`DELETE FROM ${this.q(this.resultsTable)} WHERE ${this.q('step_id')} = ${this.ph(1)}`, [result.stepId]);
190
- }
191
- return claimed.length;
192
- }
193
- /**
194
- * Atomically claim up to `batchSize` un-leased rows matching `where` and stamp them with this
195
- * instance's lease. `SELECT … FOR UPDATE SKIP LOCKED` inside the txn means concurrent instances
196
- * skip each other's locked rows instead of blocking, so no row is claimed twice.
197
- */
198
- async claim(table, where, whereParams) {
199
- const t = this.q(table);
200
- const staleBefore = this.now() - this.leaseMs;
201
- return this.exec.transaction(async (tx) => {
202
- const leaseClause = `(${this.q('claimed_at')} IS NULL OR ${this.q('claimed_at')} < ${this.ph(whereParams.length + 1)})`;
203
- const rows = await tx.query(`SELECT * FROM ${t} WHERE ${where} AND ${leaseClause}
204
- ORDER BY ${this.q('created_at')} ASC LIMIT ${this.batchSize} FOR UPDATE SKIP LOCKED`, [...whereParams, staleBefore]);
205
- if (rows.length > 0) {
206
- const ids = rows.map((r) => r.step_id);
207
- const placeholders = ids.map((_, i) => this.ph(i + 3)).join(', ');
208
- await tx.query(`UPDATE ${t} SET ${this.q('claimed_by')} = ${this.ph(1)}, ${this.q('claimed_at')} = ${this.ph(2)}
209
- WHERE ${this.q('step_id')} IN (${placeholders})`, [this.instanceId, this.now(), ...ids]);
210
- }
211
- return rows;
212
- });
213
- }
214
- async insertResult(result) {
215
- const t = this.q(this.resultsTable);
216
- const cols = ['step_id', 'run_id', 'seq', 'status', 'output', 'error', 'created_at'];
217
- const head = this.isPg
218
- ? `INSERT INTO ${t} (...) ON CONFLICT (${this.q('step_id')}) DO NOTHING`
219
- : `INSERT IGNORE INTO ${t} (...)`;
220
- const sql = head.replace('(...)', `(${cols.map((c) => this.q(c)).join(', ')}) VALUES (${cols.map((_, i) => this.ph(i + 1)).join(', ')})`);
221
- await this.exec.query(sql, [
222
- result.stepId,
223
- result.runId,
224
- result.seq,
225
- result.status,
226
- result.output === undefined ? null : JSON.stringify(result.output),
227
- result.error === undefined ? null : JSON.stringify(result.error),
228
- this.now(),
229
- ]);
230
- }
231
- sleep(ms) {
232
- return new Promise((r) => setTimeout(r, ms));
233
- }
234
- /** Stop the pollers and wait for the current ticks to settle. Does not close the shared DataSource. */
235
- async close() {
236
- this.running = false;
237
- await Promise.allSettled([this.taskLoop, this.resultLoop]);
238
- }
239
- }
240
- exports.DbTransport = DbTransport;
241
- //# sourceMappingURL=db-transport.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"db-transport.js","sourceRoot":"","sources":["../src/db-transport.ts"],"names":[],"mappings":"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"}
@@ -1,61 +0,0 @@
1
- /**
2
- * The tiny SQL surface `DbTransport` needs, so it rides **whatever ORM/connection the app already
3
- * has** instead of forcing a specific one. Implement it for your ORM (adapters for TypeORM and
4
- * MikroORM ship below) and hand it to `new DbTransport({ executor })`. Mirrors how the durable
5
- * *store* is ORM-pluggable (store-typeorm / store-mikro-orm / …).
6
- */
7
- export interface SqlExecutor {
8
- /** Drives placeholder style (`$n` vs `?`) and a couple of DDL type choices. */
9
- readonly dialect: 'mysql' | 'postgres';
10
- /** Quote/escape an identifier (table/column name) for this dialect. */
11
- escapeId(id: string): string;
12
- /** Run a statement outside a transaction. */
13
- query<T = unknown>(sql: string, params?: unknown[]): Promise<T[]>;
14
- /** Run `fn` inside a transaction — the claim uses `FOR UPDATE SKIP LOCKED` within it. */
15
- transaction<T>(fn: (tx: SqlTx) => Promise<T>): Promise<T>;
16
- }
17
- export interface SqlTx {
18
- query<T = unknown>(sql: string, params?: unknown[]): Promise<T[]>;
19
- }
20
- /** Structural slice of a TypeORM `DataSource` — avoids a hard dependency on typeorm. */
21
- interface TypeOrmDataSourceLike {
22
- options: {
23
- type: string;
24
- };
25
- driver: {
26
- escape(id: string): string;
27
- };
28
- query(sql: string, params?: unknown[]): Promise<unknown>;
29
- createQueryRunner(): {
30
- connect(): Promise<void>;
31
- startTransaction(): Promise<void>;
32
- commitTransaction(): Promise<void>;
33
- rollbackTransaction(): Promise<void>;
34
- release(): Promise<void>;
35
- query(sql: string, params?: unknown[]): Promise<unknown>;
36
- };
37
- }
38
- /** Build an executor from a TypeORM `DataSource` (e.g. the one the durable store already uses). */
39
- export declare function typeOrmExecutor(ds: TypeOrmDataSourceLike): SqlExecutor;
40
- /** Structural slice of a MikroORM `EntityManager` — avoids a hard dependency on @mikro-orm/core. */
41
- interface MikroOrmEmLike {
42
- getPlatform(): {
43
- constructor: {
44
- name: string;
45
- };
46
- quoteIdentifier(id: string): string;
47
- };
48
- getConnection(): {
49
- execute(sql: string, params?: unknown[], method?: 'all', ctx?: unknown): Promise<unknown>;
50
- };
51
- getTransactionContext?(): unknown;
52
- transactional<T>(cb: (em: MikroOrmEmLike) => Promise<T>): Promise<T>;
53
- }
54
- /**
55
- * Build an executor from a MikroORM `EntityManager` — i.e. **the app's own configured ORM**. Runs
56
- * raw SQL through `em.getConnection().execute(...)` and wraps the claim in `em.transactional(...)`,
57
- * threading the transaction context so `FOR UPDATE SKIP LOCKED` locks within the tx.
58
- */
59
- export declare function mikroOrmExecutor(em: MikroOrmEmLike): SqlExecutor;
60
- export {};
61
- //# sourceMappingURL=executors.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"executors.d.ts","sourceRoot":"","sources":["../src/executors.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,WAAW,WAAW;IAC1B,+EAA+E;IAC/E,QAAQ,CAAC,OAAO,EAAE,OAAO,GAAG,UAAU,CAAC;IACvC,uEAAuE;IACvE,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC;IAC7B,6CAA6C;IAC7C,KAAK,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC;IAClE,yFAAyF;IACzF,WAAW,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,KAAK,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;CAC3D;AAED,MAAM,WAAW,KAAK;IACpB,KAAK,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC;CACnE;AAID,wFAAwF;AACxF,UAAU,qBAAqB;IAC7B,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1B,MAAM,EAAE;QAAE,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC;IACvC,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACzD,iBAAiB,IAAI;QACnB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;QACzB,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;QAClC,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;QACnC,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;QACrC,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;QACzB,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;KAC1D,CAAC;CACH;AAED,mGAAmG;AACnG,wBAAgB,eAAe,CAAC,EAAE,EAAE,qBAAqB,GAAG,WAAW,CAuBtE;AAID,oGAAoG;AACpG,UAAU,cAAc;IACtB,WAAW,IAAI;QAAE,WAAW,EAAE;YAAE,IAAI,EAAE,MAAM,CAAA;SAAE,CAAC;QAAC,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC;IACtF,aAAa,IAAI;QACf,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,EAAE,MAAM,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;KAC3F,CAAC;IACF,qBAAqB,CAAC,IAAI,OAAO,CAAC;IAClC,aAAa,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,cAAc,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;CACtE;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,cAAc,GAAG,WAAW,CAiBhE"}
package/dist/executors.js DELETED
@@ -1,50 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.typeOrmExecutor = typeOrmExecutor;
4
- exports.mikroOrmExecutor = mikroOrmExecutor;
5
- /** Build an executor from a TypeORM `DataSource` (e.g. the one the durable store already uses). */
6
- function typeOrmExecutor(ds) {
7
- return {
8
- dialect: /postgres/.test(String(ds.options.type)) ? 'postgres' : 'mysql',
9
- escapeId: (id) => ds.driver.escape(id),
10
- query: (sql, params) => ds.query(sql, params),
11
- transaction: async (fn) => {
12
- const qr = ds.createQueryRunner();
13
- await qr.connect();
14
- await qr.startTransaction();
15
- try {
16
- const result = await fn({
17
- query: (sql, params) => qr.query(sql, params),
18
- });
19
- await qr.commitTransaction();
20
- return result;
21
- }
22
- catch (err) {
23
- await qr.rollbackTransaction();
24
- throw err;
25
- }
26
- finally {
27
- await qr.release();
28
- }
29
- },
30
- };
31
- }
32
- /**
33
- * Build an executor from a MikroORM `EntityManager` — i.e. **the app's own configured ORM**. Runs
34
- * raw SQL through `em.getConnection().execute(...)` and wraps the claim in `em.transactional(...)`,
35
- * threading the transaction context so `FOR UPDATE SKIP LOCKED` locks within the tx.
36
- */
37
- function mikroOrmExecutor(em) {
38
- const platform = em.getPlatform();
39
- return {
40
- dialect: /postgre/i.test(platform.constructor.name) ? 'postgres' : 'mysql',
41
- escapeId: (id) => platform.quoteIdentifier(id),
42
- query: (sql, params) => em.getConnection().execute(sql, params ?? [], 'all'),
43
- transaction: (fn) => em.transactional((txEm) => fn({
44
- query: (sql, params) => txEm
45
- .getConnection()
46
- .execute(sql, params ?? [], 'all', txEm.getTransactionContext?.()),
47
- })),
48
- };
49
- }
50
- //# sourceMappingURL=executors.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"executors.js","sourceRoot":"","sources":["../src/executors.ts"],"names":[],"mappings":";;AAuCA,0CAuBC;AAmBD,4CAiBC;AA5DD,mGAAmG;AACnG,SAAgB,eAAe,CAAC,EAAyB;IACvD,OAAO;QACL,OAAO,EAAE,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,OAAO;QACxE,QAAQ,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;QACtC,KAAK,EAAE,CAAI,GAAW,EAAE,MAAkB,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,MAAM,CAAiB;QACpF,WAAW,EAAE,KAAK,EAAK,EAA6B,EAAE,EAAE;YACtD,MAAM,EAAE,GAAG,EAAE,CAAC,iBAAiB,EAAE,CAAC;YAClC,MAAM,EAAE,CAAC,OAAO,EAAE,CAAC;YACnB,MAAM,EAAE,CAAC,gBAAgB,EAAE,CAAC;YAC5B,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC;oBACtB,KAAK,EAAE,CAAI,GAAW,EAAE,MAAkB,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,MAAM,CAAiB;iBACrF,CAAC,CAAC;gBACH,MAAM,EAAE,CAAC,iBAAiB,EAAE,CAAC;gBAC7B,OAAO,MAAM,CAAC;YAChB,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,MAAM,EAAE,CAAC,mBAAmB,EAAE,CAAC;gBAC/B,MAAM,GAAG,CAAC;YACZ,CAAC;oBAAS,CAAC;gBACT,MAAM,EAAE,CAAC,OAAO,EAAE,CAAC;YACrB,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC;AAcD;;;;GAIG;AACH,SAAgB,gBAAgB,CAAC,EAAkB;IACjD,MAAM,QAAQ,GAAG,EAAE,CAAC,WAAW,EAAE,CAAC;IAClC,OAAO;QACL,OAAO,EAAE,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,OAAO;QAC1E,QAAQ,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,QAAQ,CAAC,eAAe,CAAC,EAAE,CAAC;QAC9C,KAAK,EAAE,CAAI,GAAW,EAAE,MAAkB,EAAE,EAAE,CAC5C,EAAE,CAAC,aAAa,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,IAAI,EAAE,EAAE,KAAK,CAAiB;QACtE,WAAW,EAAE,CAAI,EAA6B,EAAE,EAAE,CAChD,EAAE,CAAC,aAAa,CAAC,CAAC,IAAI,EAAE,EAAE,CACxB,EAAE,CAAC;YACD,KAAK,EAAE,CAAI,GAAW,EAAE,MAAkB,EAAE,EAAE,CAC5C,IAAI;iBACD,aAAa,EAAE;iBACf,OAAO,CAAC,GAAG,EAAE,MAAM,IAAI,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,qBAAqB,EAAE,EAAE,CAAiB;SACvF,CAAC,CACH;KACJ,CAAC;AACJ,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC"}