@earendil-works/chord 1.3.0 → 1.4.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/CHANGELOG.md +13 -0
- package/README.md +55 -1
- package/dist/context/index.d.ts +8 -0
- package/dist/context/index.d.ts.map +1 -1
- package/dist/context/index.js +15 -0
- package/dist/context/index.js.map +1 -1
- package/dist/output.d.ts +8 -2
- package/dist/output.d.ts.map +1 -1
- package/dist/output.js +17 -7
- package/dist/output.js.map +1 -1
- package/dist/sqlite/cloudflare.d.ts +52 -0
- package/dist/sqlite/cloudflare.d.ts.map +1 -0
- package/dist/sqlite/cloudflare.js +134 -0
- package/dist/sqlite/cloudflare.js.map +1 -0
- package/dist/sqlite/database.d.ts +37 -0
- package/dist/sqlite/database.d.ts.map +1 -0
- package/dist/sqlite/database.js +2 -0
- package/dist/sqlite/database.js.map +1 -0
- package/dist/sqlite/index.d.ts +4 -0
- package/dist/sqlite/index.d.ts.map +1 -0
- package/dist/sqlite/index.js +3 -0
- package/dist/sqlite/index.js.map +1 -0
- package/dist/sqlite/migrations.d.ts +10 -0
- package/dist/sqlite/migrations.d.ts.map +1 -0
- package/dist/sqlite/migrations.js +33 -0
- package/dist/sqlite/migrations.js.map +1 -0
- package/dist/sqlite/node.d.ts +38 -0
- package/dist/sqlite/node.d.ts.map +1 -0
- package/dist/sqlite/node.js +174 -0
- package/dist/sqlite/node.js.map +1 -0
- package/dist/sqlite/schema.d.ts +3 -0
- package/dist/sqlite/schema.d.ts.map +1 -0
- package/dist/sqlite/schema.js +10 -0
- package/dist/sqlite/schema.js.map +1 -0
- package/dist/telemetry-sqlite/index.d.ts +24 -0
- package/dist/telemetry-sqlite/index.d.ts.map +1 -0
- package/dist/telemetry-sqlite/index.js +273 -0
- package/dist/telemetry-sqlite/index.js.map +1 -0
- package/dist/telemetry-sqlite/store.d.ts +9 -0
- package/dist/telemetry-sqlite/store.d.ts.map +1 -0
- package/dist/telemetry-sqlite/store.js +110 -0
- package/dist/telemetry-sqlite/store.js.map +1 -0
- package/package.json +22 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [1.4.0] - 2026-10-21
|
|
4
|
+
|
|
5
|
+
### Breaking Changes
|
|
6
|
+
|
|
7
|
+
- Custom `Context` implementations must provide `telemetry: TelemetrySpan`; use the no-op span `NOOP_TELEMETRY_CONTEXT` when disabled. `withTelemetry()` accepts spans, not adapters.
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- `@earendil-works/chord/telemetry-sqlite`: portable SQLite telemetry recording with bounded settled-span queues, ten-second metric aggregates, periodic flushes, and retention cleanup.
|
|
12
|
+
- `Context.telemetry` is an explicit, non-optional telemetry parent (no-op by default). `withTelemetry(telemetry, context)` derives it without changing values or cancellation; `traceIn(context, options, fn)` starts a child span and passes its derived context to the callback.
|
|
13
|
+
- `@earendil-works/chord/sqlite`: portable SQLite interfaces, atomic migration runner, and schema-prefix validation, with Node (`/sqlite/node`) and Cloudflare Durable Object (`/sqlite/cloudflare`) drivers. Moved from Durable, which keeps its storage implementations and re-exports the moved public names.
|
|
14
|
+
- `@earendil-works/chord/output`: `Progress` takes an optional `ProgressClock` (`now`, `setTimer`) to pace commits on, by default `Date.now` and `setTimeout`.
|
|
15
|
+
|
|
3
16
|
## [1.3.0] - 2026-10-15
|
|
4
17
|
|
|
5
18
|
### Breaking Changes
|
package/README.md
CHANGED
|
@@ -16,9 +16,13 @@ Contracts are runtime values described with [TypeBox](https://github.com/sinclai
|
|
|
16
16
|
|--------|----------|---------|
|
|
17
17
|
| `@earendil-works/chord` | Contracts (`local`, `remote`, `method`, `opaque`), declarations (through the factory's `self`: `state`, `derive`, `resource`, `on`, `task`), hosts (`createHost`, `defineFacet`, `defineRegistry`), links (`memoryLinkPair`, `ipcLink`, `webSocketLink`, `acceptWebSockets`), errors (`ChordError`, `isChordError`, `forbidden`, `invalid`). Also the shared base: `Context`, `JsonValue`, `JsonRepresentation`, `Draft`, `copyJson`, `isJsonValue`, and `replicatedState` with its types. | Node and browsers |
|
|
18
18
|
| `@earendil-works/chord/node` | Child host processes: `createHostManager`, `forkDriver`, `childControl`, `processLock`; the facet module loader `nodeLoader`. | Node |
|
|
19
|
-
| `@earendil-works/chord/context` | Explicit cancellation and invocation values: `BACKGROUND_CONTEXT`, `withCancel`, `withAbortSignal`, `withoutAbortSignal`, `withContextValue`, `awaitWithContext`. | Node and browsers |
|
|
19
|
+
| `@earendil-works/chord/context` | Explicit cancellation, telemetry, and invocation values: `BACKGROUND_CONTEXT`, `withCancel`, `withAbortSignal`, `withoutAbortSignal`, `withTelemetry`, `traceIn`, `withContextValue`, `awaitWithContext`. | Node and browsers |
|
|
20
20
|
| `@earendil-works/chord/delta` | The transactional JSON tracker, structural diff, immutable apply, and the wire encoder/decoder for operation batches. | Node and browsers |
|
|
21
21
|
| `@earendil-works/chord/output` | Bounded output streams and paced progress: `OutputBuffer` (head or tail window of a stream, `OutputLimits`, `OutputSkip`), `boundOutput`, `sanitizeOutput`, `utf8ByteLength`, and `Progress` (adaptive commits of a changing value). | Node and browsers |
|
|
22
|
+
| `@earendil-works/chord/telemetry-sqlite` | `createSqliteTelemetry(db, { retentionMs?, maxQueuedSpans? })`: buffered recording and backend-independent `TelemetryStore` queries. | Any SQLite adapter |
|
|
23
|
+
| `@earendil-works/chord/sqlite` | Portable `SqliteDatabase`, `SqliteExecutor`, and `SqliteValue`, atomic `applySqliteMigrations(database, migrations, { table })`, and `validateSqliteSchemaPrefix`. The metadata table must be a valid, non-reserved SQLite identifier; migration versions start at 1 and are contiguous. | Any SQLite adapter |
|
|
24
|
+
| `@earendil-works/chord/sqlite/node` | `NodeSqliteDatabase`, `openNodeSqliteDatabase`, and `NodeSqliteDatabaseOptions`. | Node |
|
|
25
|
+
| `@earendil-works/chord/sqlite/cloudflare` | `DurableObjectSqliteDatabase` and the structural `DurableObjectSqliteStorage` binding type. | Cloudflare Durable Objects |
|
|
22
26
|
|
|
23
27
|
## Quick start
|
|
24
28
|
|
|
@@ -66,6 +70,56 @@ await host.root(async (ctx) => {
|
|
|
66
70
|
- [Specification](docs/spec.md): compatibility, lifetime, and reload semantics, plus known limitations and implementation decisions.
|
|
67
71
|
- [Delta guide](src/delta/README.md): ownership, lifecycle, operation, and replica contracts of `@earendil-works/chord/delta`.
|
|
68
72
|
|
|
73
|
+
## Explicit Context telemetry
|
|
74
|
+
|
|
75
|
+
`Context` always carries a `telemetry: TelemetrySpan`, alongside `abortSignal`. `BACKGROUND_CONTEXT` and `TODO_CONTEXT` use the shared no-op span `NOOP_TELEMETRY_CONTEXT`. Adapters (`TelemetryContext`) belong to hosts and start root spans; adapters are never placed in a `Context`.
|
|
76
|
+
|
|
77
|
+
```ts
|
|
78
|
+
import { BACKGROUND_CONTEXT, traceIn, withTelemetry } from '@earendil-works/chord/context';
|
|
79
|
+
import { InMemoryTelemetryContext } from '@earendil-works/pi-telemetry';
|
|
80
|
+
|
|
81
|
+
const telemetry = new InMemoryTelemetryContext();
|
|
82
|
+
await telemetry.startSpan({ name: 'app.request' }, async (span) => {
|
|
83
|
+
const context = withTelemetry(span, BACKGROUND_CONTEXT);
|
|
84
|
+
await traceIn(context, { name: 'app.load' }, async (child) => {
|
|
85
|
+
child.telemetry.addEvent('cache.miss');
|
|
86
|
+
return traceIn(child, { name: 'app.read' }, (nested) => readAccount(nested));
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
`withTelemetry(span, context)` derives a new context; it never changes its parent, cancellation, or typed values. `traceIn(context, options, fn)` creates a callback-managed child span, and `fn` receives its derived context. Every context already supports `telemetry.addEvent()` and `telemetry.addLink()`. Values, cancellation, callback results, and rejection identities are preserved. Concurrent calls keep independent parents; there is no ambient current span. `value()`, `ContextKey`, and `withContextValue()` remain supported.
|
|
92
|
+
|
|
93
|
+
These helpers operate on the standalone `Context` API. They do not yet instrument Chord hosts, methods, or network frames.
|
|
94
|
+
|
|
95
|
+
## SQLite telemetry
|
|
96
|
+
|
|
97
|
+
```ts
|
|
98
|
+
import { createSqliteTelemetry } from '@earendil-works/chord/telemetry-sqlite';
|
|
99
|
+
import { openNodeSqliteDatabase } from '@earendil-works/chord/sqlite/node';
|
|
100
|
+
import { renderTrace } from '@earendil-works/pi-telemetry/render';
|
|
101
|
+
|
|
102
|
+
const db = await openNodeSqliteDatabase('telemetry.db');
|
|
103
|
+
const telemetry = await createSqliteTelemetry(db);
|
|
104
|
+
try {
|
|
105
|
+
await telemetry.startSpan({ name: 'app.request' }, async (span) => {
|
|
106
|
+
span.addEvent('request.accepted');
|
|
107
|
+
await span.startSpan({ name: 'app.read' }, () => readAccount());
|
|
108
|
+
});
|
|
109
|
+
await telemetry.flush();
|
|
110
|
+
const { traces } = await telemetry.findTraces({ name: 'app.request', limit: 10 });
|
|
111
|
+
for (const trace of traces) console.log(renderTrace(trace.spans));
|
|
112
|
+
} finally {
|
|
113
|
+
try { await telemetry.close(); } finally { await db.close(); }
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
The adapter is portable over `SqliteDatabase` and owns no connection. Recording performs no SQL. A one-second timer flushes settled spans and completed ten-second metric intervals in one transaction, including retention cleanup. Metrics retain count, sum, minimum, and maximum per name/kind/unit/attribute series, not raw samples, buckets, or exemplars. `close()` stops recording and drains partial metric intervals without waiting for business callbacks or closing the database. Late span completions are ignored.
|
|
118
|
+
|
|
119
|
+
Retention defaults to seven days. `maxQueuedSpans` defaults to 10,000 and counts settled spans awaiting commit, including an in-flight batch. The same limit independently bounds pending metric interval/series pairs. Overflow increments `droppedSpans` or `droppedMeasurements`; the limits bound counts, not bytes or active spans. A write failure stops recording permanently: `flush()` and `close()` reject with the original error without retrying.
|
|
120
|
+
|
|
121
|
+
The adapter implements `TelemetryStore`: `findTraces()`, `getTrace()`, and `findMetrics()` read committed rows, including after adapter close while the database remains open. See [stored telemetry](../telemetry/README.md#stored-telemetry) for filters, pagination, and cross-process trace assembly. Schema tables are `telemetry_spans`, `telemetry_metrics`, and `telemetry_schema`.
|
|
122
|
+
|
|
69
123
|
## Tracking JSON deltas
|
|
70
124
|
|
|
71
125
|
Import the standalone transactional tracker from `@earendil-works/chord/delta`:
|
package/dist/context/index.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type SpanOptions, type TelemetrySpan } from "@earendil-works/pi-telemetry";
|
|
1
2
|
/** Typed identity for one value carried by a {@link Context}. */
|
|
2
3
|
export interface ContextKey<T> {
|
|
3
4
|
readonly token: symbol;
|
|
@@ -7,6 +8,7 @@ export interface ContextKey<T> {
|
|
|
7
8
|
/** Immutable invocation-scoped values passed explicitly through operations. */
|
|
8
9
|
export interface Context {
|
|
9
10
|
readonly abortSignal: AbortSignal | undefined;
|
|
11
|
+
readonly telemetry: TelemetrySpan;
|
|
10
12
|
value<T>(key: ContextKey<T>): T | undefined;
|
|
11
13
|
toString(): string;
|
|
12
14
|
}
|
|
@@ -15,6 +17,12 @@ export declare const TODO_CONTEXT: Context;
|
|
|
15
17
|
export declare function createContextKey<T>(description: string): ContextKey<T>;
|
|
16
18
|
/** Derive a context containing one additional or replaced value. */
|
|
17
19
|
export declare function withContextValue<T>(key: ContextKey<T>, value: T, parent: Context): Context;
|
|
20
|
+
/** Derive an explicit telemetry parent without changing cancellation or application values. */
|
|
21
|
+
export declare function withTelemetry<T extends TelemetrySpan>(telemetry: T, context: Context): Context & {
|
|
22
|
+
readonly telemetry: T;
|
|
23
|
+
};
|
|
24
|
+
/** Run a child span with a derived context whose telemetry member is that span. */
|
|
25
|
+
export declare function traceIn<T>(context: Context, options: SpanOptions, fn: (context: Context) => T | Promise<T>): Promise<T>;
|
|
18
26
|
/**
|
|
19
27
|
* Derive a context cancelled by either the parent signal or the supplied signal.
|
|
20
28
|
* The parent context remains unchanged.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/context/index.ts"],"names":[],"mappings":"AAAA,iEAAiE;AACjE,MAAM,WAAW,UAAU,CAAC,CAAC;IAC5B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,iGAAiG;IACjG,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,CAAC;CACrC;AAED,+EAA+E;AAC/E,MAAM,WAAW,OAAO;IACvB,QAAQ,CAAC,WAAW,EAAE,WAAW,GAAG,SAAS,CAAC;IAC9C,KAAK,CAAC,CAAC,EAAE,GAAG,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC;IAC5C,QAAQ,IAAI,MAAM,CAAC;CACnB;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/context/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAA0B,KAAK,WAAW,EAAE,KAAK,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAE5G,iEAAiE;AACjE,MAAM,WAAW,UAAU,CAAC,CAAC;IAC5B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,iGAAiG;IACjG,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,CAAC;CACrC;AAED,+EAA+E;AAC/E,MAAM,WAAW,OAAO;IACvB,QAAQ,CAAC,WAAW,EAAE,WAAW,GAAG,SAAS,CAAC;IAC9C,QAAQ,CAAC,SAAS,EAAE,aAAa,CAAC;IAClC,KAAK,CAAC,CAAC,EAAE,GAAG,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC;IAC5C,QAAQ,IAAI,MAAM,CAAC;CACnB;AA8DD,eAAO,MAAM,kBAAkB,EAAE,OAA0D,CAAC;AAC5F,eAAO,MAAM,YAAY,EAAE,OAAoD,CAAC;AAEhF,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,WAAW,EAAE,MAAM,GAAG,UAAU,CAAC,CAAC,CAAC,CAEtE;AAED,oEAAoE;AACpE,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,GAAG,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,OAAO,GAAG,OAAO,CAE1F;AAED,+FAA+F;AAC/F,wBAAgB,aAAa,CAAC,CAAC,SAAS,aAAa,EACpD,SAAS,EAAE,CAAC,EACZ,OAAO,EAAE,OAAO,GACd,OAAO,GAAG;IAAE,QAAQ,CAAC,SAAS,EAAE,CAAC,CAAA;CAAE,CAErC;AAED,mFAAmF;AACnF,wBAAgB,OAAO,CAAC,CAAC,EACxB,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,WAAW,EACpB,EAAE,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,GACtC,OAAO,CAAC,CAAC,CAAC,CAEZ;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAI9E;AAED,6GAA6G;AAC7G,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAE5D;AAED,yDAAyD;AACzD,wBAAgB,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG;IAC7C,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;CAC5C,CAMA;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,CAkBrF"}
|
package/dist/context/index.js
CHANGED
|
@@ -1,10 +1,17 @@
|
|
|
1
|
+
import { NOOP_TELEMETRY_CONTEXT } from "@earendil-works/pi-telemetry";
|
|
1
2
|
const ABORT_SIGNAL_CONTEXT_KEY = Object.freeze({
|
|
2
3
|
token: Symbol("chord.abortSignal"),
|
|
3
4
|
});
|
|
5
|
+
const TELEMETRY_CONTEXT_KEY = Object.freeze({
|
|
6
|
+
token: Symbol("chord.telemetry"),
|
|
7
|
+
});
|
|
4
8
|
class BaseContext {
|
|
5
9
|
get abortSignal() {
|
|
6
10
|
return this.value(ABORT_SIGNAL_CONTEXT_KEY);
|
|
7
11
|
}
|
|
12
|
+
get telemetry() {
|
|
13
|
+
return this.value(TELEMETRY_CONTEXT_KEY) ?? NOOP_TELEMETRY_CONTEXT;
|
|
14
|
+
}
|
|
8
15
|
}
|
|
9
16
|
class EmptyContext extends BaseContext {
|
|
10
17
|
#name;
|
|
@@ -47,6 +54,14 @@ export function createContextKey(description) {
|
|
|
47
54
|
export function withContextValue(key, value, parent) {
|
|
48
55
|
return new ContextValue(parent, key, value);
|
|
49
56
|
}
|
|
57
|
+
/** Derive an explicit telemetry parent without changing cancellation or application values. */
|
|
58
|
+
export function withTelemetry(telemetry, context) {
|
|
59
|
+
return withContextValue(TELEMETRY_CONTEXT_KEY, telemetry, context);
|
|
60
|
+
}
|
|
61
|
+
/** Run a child span with a derived context whose telemetry member is that span. */
|
|
62
|
+
export function traceIn(context, options, fn) {
|
|
63
|
+
return context.telemetry.startSpan(options, (span) => fn(withTelemetry(span, context)));
|
|
64
|
+
}
|
|
50
65
|
/**
|
|
51
66
|
* Derive a context cancelled by either the parent signal or the supplied signal.
|
|
52
67
|
* The parent context remains unchanged.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/context/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/context/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAwC,MAAM,8BAA8B,CAAC;AAiB5G,MAAM,wBAAwB,GAAwC,MAAM,CAAC,MAAM,CAAC;IACnF,KAAK,EAAE,MAAM,CAAC,mBAAmB,CAAC;CAClC,CAAC,CAAC;AAEH,MAAM,qBAAqB,GAA8B,MAAM,CAAC,MAAM,CAAC;IACtE,KAAK,EAAE,MAAM,CAAC,iBAAiB,CAAC;CAChC,CAAC,CAAC;AAEH,MAAe,WAAW;IAIzB,IAAI,WAAW;QACd,OAAO,IAAI,CAAC,KAAK,CAAC,wBAAwB,CAAC,CAAC;IAC7C,CAAC;IAED,IAAI,SAAS;QACZ,OAAO,IAAI,CAAC,KAAK,CAAC,qBAAqB,CAAC,IAAI,sBAAsB,CAAC;IACpE,CAAC;CACD;AAED,MAAM,YAAa,SAAQ,WAAW;IAC5B,KAAK,CAAS;IAEvB,YAAY,IAAY;QACvB,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;IACnB,CAAC;IAED,KAAK,CAAI,IAAmB;QAC3B,OAAO,SAAS,CAAC;IAClB,CAAC;IAED,QAAQ;QACP,OAAO,IAAI,CAAC,KAAK,CAAC;IACnB,CAAC;CACD;AAED,MAAM,YAAgB,SAAQ,WAAW;IAC/B,OAAO,CAAU;IACjB,IAAI,CAAgB;IACpB,MAAM,CAAI;IAEnB,YAAY,MAAe,EAAE,GAAkB,EAAE,KAAQ;QACxD,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC;QACtB,IAAI,CAAC,IAAI,GAAG,GAAG,CAAC;QAChB,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;IACrB,CAAC;IAED,KAAK,CAAQ,GAAsB;QAClC,IAAI,GAAG,CAAC,KAAK,KAAK,IAAI,CAAC,IAAI,CAAC,KAAK;YAAE,OAAO,IAAI,CAAC,MAA0B,CAAC;QAC1E,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAChC,CAAC;IAED,QAAQ;QACP,OAAO,GAAG,IAAI,CAAC,OAAO,cAAc,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,IAAI,WAAW,GAAG,CAAC;IACnF,CAAC;CACD;AAED,MAAM,CAAC,MAAM,kBAAkB,GAAY,IAAI,YAAY,CAAC,8BAA8B,CAAC,CAAC;AAC5F,MAAM,CAAC,MAAM,YAAY,GAAY,IAAI,YAAY,CAAC,wBAAwB,CAAC,CAAC;AAEhF,MAAM,UAAU,gBAAgB,CAAI,WAAmB;IACtD,OAAO,MAAM,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;AACtD,CAAC;AAED,oEAAoE;AACpE,MAAM,UAAU,gBAAgB,CAAI,GAAkB,EAAE,KAAQ,EAAE,MAAe;IAChF,OAAO,IAAI,YAAY,CAAC,MAAM,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;AAC7C,CAAC;AAED,+FAA+F;AAC/F,MAAM,UAAU,aAAa,CAC5B,SAAY,EACZ,OAAgB;IAEhB,OAAO,gBAAgB,CAAC,qBAAqB,EAAE,SAAS,EAAE,OAAO,CAAwC,CAAC;AAC3G,CAAC;AAED,mFAAmF;AACnF,MAAM,UAAU,OAAO,CACtB,OAAgB,EAChB,OAAoB,EACpB,EAAwC;IAExC,OAAO,OAAO,CAAC,SAAS,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,CAAC,aAAa,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;AACzF,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,MAAmB,EAAE,OAAgB;IACpE,MAAM,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC;IACzC,MAAM,QAAQ,GAAG,YAAY,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC,CAAC;IAC/F,OAAO,gBAAgB,CAAC,wBAAwB,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;AACtE,CAAC;AAED,6GAA6G;AAC7G,MAAM,UAAU,kBAAkB,CAAC,OAAgB;IAClD,OAAO,gBAAgB,CAAC,wBAAwB,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;AACvE,CAAC;AAED,yDAAyD;AACzD,MAAM,UAAU,UAAU,CAAC,OAAgB;IAI1C,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;IACzC,OAAO;QACN,OAAO,EAAE,eAAe,CAAC,UAAU,CAAC,MAAM,EAAE,OAAO,CAAC;QACpD,MAAM,EAAE,CAAC,MAAgB,EAAE,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,MAAM,CAAC;KACtD,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAI,OAAmB,EAAE,OAAgB;IACxE,MAAM,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IACnC,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO,OAAO,CAAC;IACzC,IAAI,MAAM,CAAC,OAAO;QAAE,OAAO,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC;IAC9D,OAAO,IAAI,OAAO,CAAI,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACzC,MAAM,OAAO,GAAG,GAAS,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC;QACvD,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QAC1D,KAAK,OAAO,CAAC,IAAI,CAChB,CAAC,KAAK,EAAE,EAAE;YACT,MAAM,CAAC,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YAC7C,OAAO,CAAC,KAAK,CAAC,CAAC;QAChB,CAAC,EACD,CAAC,KAAc,EAAE,EAAE;YAClB,MAAM,CAAC,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YAC7C,MAAM,CAAC,KAAK,CAAC,CAAC;QACf,CAAC,CACD,CAAC;IACH,CAAC,CAAC,CAAC;AACJ,CAAC;AAED,SAAS,UAAU,CAAC,MAAmB;IACtC,MAAM,MAAM,GAAY,MAAM,CAAC,MAAM,CAAC;IACtC,OAAO,MAAM,YAAY,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,YAAY,CAAC,2BAA2B,EAAE,YAAY,CAAC,CAAC;AACvG,CAAC","sourcesContent":["import { NOOP_TELEMETRY_CONTEXT, type SpanOptions, type TelemetrySpan } from \"@earendil-works/pi-telemetry\";\n\n/** Typed identity for one value carried by a {@link Context}. */\nexport interface ContextKey<T> {\n\treadonly token: symbol;\n\t/** Type-only marker that prevents keys with different value types from being interchangeable. */\n\treadonly valueType?: (value: T) => T;\n}\n\n/** Immutable invocation-scoped values passed explicitly through operations. */\nexport interface Context {\n\treadonly abortSignal: AbortSignal | undefined;\n\treadonly telemetry: TelemetrySpan;\n\tvalue<T>(key: ContextKey<T>): T | undefined;\n\ttoString(): string;\n}\n\nconst ABORT_SIGNAL_CONTEXT_KEY: ContextKey<AbortSignal | undefined> = Object.freeze({\n\ttoken: Symbol(\"chord.abortSignal\"),\n});\n\nconst TELEMETRY_CONTEXT_KEY: ContextKey<TelemetrySpan> = Object.freeze({\n\ttoken: Symbol(\"chord.telemetry\"),\n});\n\nabstract class BaseContext implements Context {\n\tabstract value<T>(key: ContextKey<T>): T | undefined;\n\tabstract toString(): string;\n\n\tget abortSignal(): AbortSignal | undefined {\n\t\treturn this.value(ABORT_SIGNAL_CONTEXT_KEY);\n\t}\n\n\tget telemetry(): TelemetrySpan {\n\t\treturn this.value(TELEMETRY_CONTEXT_KEY) ?? NOOP_TELEMETRY_CONTEXT;\n\t}\n}\n\nclass EmptyContext extends BaseContext {\n\treadonly #name: string;\n\n\tconstructor(name: string) {\n\t\tsuper();\n\t\tthis.#name = name;\n\t}\n\n\tvalue<T>(_key: ContextKey<T>): T | undefined {\n\t\treturn undefined;\n\t}\n\n\ttoString(): string {\n\t\treturn this.#name;\n\t}\n}\n\nclass ContextValue<T> extends BaseContext {\n\treadonly #parent: Context;\n\treadonly #key: ContextKey<T>;\n\treadonly #value: T;\n\n\tconstructor(parent: Context, key: ContextKey<T>, value: T) {\n\t\tsuper();\n\t\tthis.#parent = parent;\n\t\tthis.#key = key;\n\t\tthis.#value = value;\n\t}\n\n\tvalue<Value>(key: ContextKey<Value>): Value | undefined {\n\t\tif (key.token === this.#key.token) return this.#value as unknown as Value;\n\t\treturn this.#parent.value(key);\n\t}\n\n\ttoString(): string {\n\t\treturn `${this.#parent}.WithValue(${this.#key.token.description ?? \"anonymous\"})`;\n\t}\n}\n\nexport const BACKGROUND_CONTEXT: Context = new EmptyContext(\"[Context BACKGROUND_CONTEXT]\");\nexport const TODO_CONTEXT: Context = new EmptyContext(\"[Context TODO_CONTEXT]\");\n\nexport function createContextKey<T>(description: string): ContextKey<T> {\n\treturn Object.freeze({ token: Symbol(description) });\n}\n\n/** Derive a context containing one additional or replaced value. */\nexport function withContextValue<T>(key: ContextKey<T>, value: T, parent: Context): Context {\n\treturn new ContextValue(parent, key, value);\n}\n\n/** Derive an explicit telemetry parent without changing cancellation or application values. */\nexport function withTelemetry<T extends TelemetrySpan>(\n\ttelemetry: T,\n\tcontext: Context,\n): Context & { readonly telemetry: T } {\n\treturn withContextValue(TELEMETRY_CONTEXT_KEY, telemetry, context) as Context & { readonly telemetry: T };\n}\n\n/** Run a child span with a derived context whose telemetry member is that span. */\nexport function traceIn<T>(\n\tcontext: Context,\n\toptions: SpanOptions,\n\tfn: (context: Context) => T | Promise<T>,\n): Promise<T> {\n\treturn context.telemetry.startSpan(options, (span) => fn(withTelemetry(span, context)));\n}\n\n/**\n * Derive a context cancelled by either the parent signal or the supplied signal.\n * The parent context remains unchanged.\n */\nexport function withAbortSignal(signal: AbortSignal, context: Context): Context {\n\tconst parentSignal = context.abortSignal;\n\tconst combined = parentSignal === undefined ? signal : AbortSignal.any([parentSignal, signal]);\n\treturn withContextValue(ABORT_SIGNAL_CONTEXT_KEY, combined, context);\n}\n\n/** Derive a context retaining all values except caller cancellation. Intended for mandatory cleanup only. */\nexport function withoutAbortSignal(context: Context): Context {\n\treturn withContextValue(ABORT_SIGNAL_CONTEXT_KEY, undefined, context);\n}\n\n/** Derive an independently cancellable child context. */\nexport function withCancel(context: Context): {\n\treadonly context: Context;\n\treadonly cancel: (reason?: unknown) => void;\n} {\n\tconst controller = new AbortController();\n\treturn {\n\t\tcontext: withAbortSignal(controller.signal, context),\n\t\tcancel: (reason?: unknown) => controller.abort(reason),\n\t};\n}\n\n/**\n * Observe a promise until it settles or the invocation is cancelled.\n * Cancellation rejects only this waiter; it does not cancel the underlying promise.\n */\nexport function awaitWithContext<T>(promise: Promise<T>, context: Context): Promise<T> {\n\tconst signal = context.abortSignal;\n\tif (signal === undefined) return promise;\n\tif (signal.aborted) return Promise.reject(abortError(signal));\n\treturn new Promise<T>((resolve, reject) => {\n\t\tconst onAbort = (): void => reject(abortError(signal));\n\t\tsignal.addEventListener(\"abort\", onAbort, { once: true });\n\t\tvoid promise.then(\n\t\t\t(value) => {\n\t\t\t\tsignal.removeEventListener(\"abort\", onAbort);\n\t\t\t\tresolve(value);\n\t\t\t},\n\t\t\t(error: unknown) => {\n\t\t\t\tsignal.removeEventListener(\"abort\", onAbort);\n\t\t\t\treject(error);\n\t\t\t},\n\t\t);\n\t});\n}\n\nfunction abortError(signal: AbortSignal): Error {\n\tconst reason: unknown = signal.reason;\n\treturn reason instanceof Error ? reason : new DOMException(\"The operation was aborted\", \"AbortError\");\n}\n"]}
|
package/dist/output.d.ts
CHANGED
|
@@ -67,14 +67,20 @@ export declare class OutputBuffer {
|
|
|
67
67
|
export declare function utf8ByteLength(content: string): number;
|
|
68
68
|
/** Each progress commit also buys a pause proportional to what it wrote. */
|
|
69
69
|
export declare const PROGRESS_BYTES_PER_SECOND: number;
|
|
70
|
+
/** The clock and timer progress commits pace on. */
|
|
71
|
+
export type ProgressClock = {
|
|
72
|
+
readonly now: () => number;
|
|
73
|
+
/** Call `callback` once after about `delayMs`; returns a function that disarms it. */
|
|
74
|
+
readonly setTimer: (callback: () => void, delayMs: number) => () => void;
|
|
75
|
+
};
|
|
70
76
|
/**
|
|
71
77
|
* Adaptive progress commits: the first change after an idle period commits at once; each commit then delays the next
|
|
72
78
|
* by at least `minIntervalMs` and by its written size at 100 KiB/s. At most one commit is in flight; changes made
|
|
73
|
-
* meanwhile coalesce into the next one.
|
|
79
|
+
* meanwhile coalesce into the next one. Paces on `clock`, by default `Date.now` and `setTimeout`.
|
|
74
80
|
*/
|
|
75
81
|
export declare class Progress {
|
|
76
82
|
#private;
|
|
77
|
-
constructor(write: () => Promise<number>, onError: (error: unknown) => void, minIntervalMs: number);
|
|
83
|
+
constructor(write: () => Promise<number>, onError: (error: unknown) => void, minIntervalMs: number, clock?: ProgressClock);
|
|
78
84
|
/** Schedule a commit. */
|
|
79
85
|
mark(): void;
|
|
80
86
|
/** Schedule a commit; the promise settles with the commit that includes this change. */
|
package/dist/output.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../src/output.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,6CAA6C;AAC7C,MAAM,MAAM,YAAY,GAAG;IAAE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,CAAC;AAEtH,mDAAmD;AACnD,MAAM,MAAM,aAAa,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;CAAE,CAAC;AAEpH,2EAA2E;AAC3E,MAAM,MAAM,WAAW,GAAG;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;CAC9B,CAAC;AAEF;;;GAGG;AACH,MAAM,WAAW,UAAU;IAC1B,6CAA6C;IAC7C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,6CAA6C;IAC7C,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,oDAAoD;IACpD,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAC;CAClC;AAQD,4FAA4F;AAC5F,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,GAAG,WAAW,CAU3E;AA0CD,wDAAwD;AACxD,wBAAgB,YAAY,CAAC,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAIrE;AAgBD;;;;GAIG;AACH,qBAAa,YAAY;;IAkBxB,YAAY,MAAM,EAAE,YAAY,EAE/B;IAED,kEAAkE;IAClE,IAAI,WAAW,IAAI,MAAM,CAExB;IAED;;;OAGG;IACH,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,EAAE,OAAO,CAAC,EAAE,UAAU,GAAG,OAAO,CAa9D;IAaD,oGAAoG;IACpG,GAAG,IAAI,IAAI,CAEV;IAgCD,oFAAoF;IACpF,QAAQ,IAAI,aAAa,CAoBxB;CACD;AAkCD,sFAAsF;AACtF,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAkBtD;AAQD,4EAA4E;AAC5E,eAAO,MAAM,yBAAyB,QAAa,CAAC;AAEpD;;;;GAIG;AACH,qBAAa,QAAQ;;
|
|
1
|
+
{"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../src/output.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,6CAA6C;AAC7C,MAAM,MAAM,YAAY,GAAG;IAAE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,CAAC;AAEtH,mDAAmD;AACnD,MAAM,MAAM,aAAa,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;CAAE,CAAC;AAEpH,2EAA2E;AAC3E,MAAM,MAAM,WAAW,GAAG;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;CAC9B,CAAC;AAEF;;;GAGG;AACH,MAAM,WAAW,UAAU;IAC1B,6CAA6C;IAC7C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,6CAA6C;IAC7C,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,oDAAoD;IACpD,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAC;CAClC;AAQD,4FAA4F;AAC5F,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,GAAG,WAAW,CAU3E;AA0CD,wDAAwD;AACxD,wBAAgB,YAAY,CAAC,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAIrE;AAgBD;;;;GAIG;AACH,qBAAa,YAAY;;IAkBxB,YAAY,MAAM,EAAE,YAAY,EAE/B;IAED,kEAAkE;IAClE,IAAI,WAAW,IAAI,MAAM,CAExB;IAED;;;OAGG;IACH,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,EAAE,OAAO,CAAC,EAAE,UAAU,GAAG,OAAO,CAa9D;IAaD,oGAAoG;IACpG,GAAG,IAAI,IAAI,CAEV;IAgCD,oFAAoF;IACpF,QAAQ,IAAI,aAAa,CAoBxB;CACD;AAkCD,sFAAsF;AACtF,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAkBtD;AAQD,4EAA4E;AAC5E,eAAO,MAAM,yBAAyB,QAAa,CAAC;AAEpD,oDAAoD;AACpD,MAAM,MAAM,aAAa,GAAG;IAC3B,QAAQ,CAAC,GAAG,EAAE,MAAM,MAAM,CAAC;IAC3B,sFAAsF;IACtF,QAAQ,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,MAAM,IAAI,EAAE,OAAO,EAAE,MAAM,KAAK,MAAM,IAAI,CAAC;CACzE,CAAC;AAUF;;;;GAIG;AACH,qBAAa,QAAQ;;IAYpB,YACC,KAAK,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,EAC5B,OAAO,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,EACjC,aAAa,EAAE,MAAM,EACrB,KAAK,GAAE,aAA4B,EAMnC;IAED,yBAAyB;IACzB,IAAI,IAAI,IAAI,CAGX;IAED,wFAAwF;IACxF,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAK3B;IAED,2GAA2G;IACrG,IAAI,IAAI,OAAO,CAAC,oBAAoB,CAAC,IAAI,CAAC,EAAE,CAAC,CAMlD;CAoCD"}
|
package/dist/output.js
CHANGED
|
@@ -271,25 +271,34 @@ function countNewlines(text) {
|
|
|
271
271
|
}
|
|
272
272
|
/** Each progress commit also buys a pause proportional to what it wrote. */
|
|
273
273
|
export const PROGRESS_BYTES_PER_SECOND = 100 * 1024;
|
|
274
|
+
const SYSTEM_CLOCK = {
|
|
275
|
+
now: () => Date.now(),
|
|
276
|
+
setTimer: (callback, delayMs) => {
|
|
277
|
+
const timer = setTimeout(callback, delayMs);
|
|
278
|
+
return () => clearTimeout(timer);
|
|
279
|
+
},
|
|
280
|
+
};
|
|
274
281
|
/**
|
|
275
282
|
* Adaptive progress commits: the first change after an idle period commits at once; each commit then delays the next
|
|
276
283
|
* by at least `minIntervalMs` and by its written size at 100 KiB/s. At most one commit is in flight; changes made
|
|
277
|
-
* meanwhile coalesce into the next one.
|
|
284
|
+
* meanwhile coalesce into the next one. Paces on `clock`, by default `Date.now` and `setTimeout`.
|
|
278
285
|
*/
|
|
279
286
|
export class Progress {
|
|
280
287
|
#write;
|
|
281
288
|
#onError;
|
|
282
289
|
#minIntervalMs;
|
|
290
|
+
#clock;
|
|
283
291
|
#waiters = [];
|
|
284
292
|
#timer;
|
|
285
293
|
#inFlight;
|
|
286
294
|
#nextAt = 0;
|
|
287
295
|
#dirty = false;
|
|
288
296
|
#stopped = false;
|
|
289
|
-
constructor(write, onError, minIntervalMs) {
|
|
297
|
+
constructor(write, onError, minIntervalMs, clock = SYSTEM_CLOCK) {
|
|
290
298
|
this.#write = write;
|
|
291
299
|
this.#onError = onError;
|
|
292
300
|
this.#minIntervalMs = minIntervalMs;
|
|
301
|
+
this.#clock = clock;
|
|
293
302
|
}
|
|
294
303
|
/** Schedule a commit. */
|
|
295
304
|
mark() {
|
|
@@ -306,7 +315,7 @@ export class Progress {
|
|
|
306
315
|
/** Stop committing and wait for the commit in flight; returns the waiters the final commit must settle. */
|
|
307
316
|
async stop() {
|
|
308
317
|
this.#stopped = true;
|
|
309
|
-
|
|
318
|
+
this.#timer?.();
|
|
310
319
|
this.#timer = undefined;
|
|
311
320
|
await this.#inFlight;
|
|
312
321
|
return this.#waiters.splice(0);
|
|
@@ -314,13 +323,14 @@ export class Progress {
|
|
|
314
323
|
#schedule() {
|
|
315
324
|
if (this.#stopped || this.#timer !== undefined || this.#inFlight !== undefined)
|
|
316
325
|
return;
|
|
317
|
-
const wait = this.#nextAt -
|
|
326
|
+
const wait = this.#nextAt - this.#clock.now();
|
|
318
327
|
if (wait <= 0)
|
|
319
328
|
this.#flush();
|
|
320
329
|
else
|
|
321
|
-
this.#timer =
|
|
330
|
+
this.#timer = this.#clock.setTimer(() => {
|
|
322
331
|
this.#timer = undefined;
|
|
323
|
-
|
|
332
|
+
// Checks the clock again: a timer that fires early waits for the rest.
|
|
333
|
+
this.#schedule();
|
|
324
334
|
}, wait);
|
|
325
335
|
}
|
|
326
336
|
#flush() {
|
|
@@ -328,7 +338,7 @@ export class Progress {
|
|
|
328
338
|
return;
|
|
329
339
|
this.#dirty = false;
|
|
330
340
|
const waiters = this.#waiters.splice(0);
|
|
331
|
-
const started =
|
|
341
|
+
const started = this.#clock.now();
|
|
332
342
|
this.#inFlight = this.#write()
|
|
333
343
|
.then((bytes) => {
|
|
334
344
|
this.#nextAt = started + Math.max(this.#minIntervalMs, (bytes * 1000) / PROGRESS_BYTES_PER_SECOND);
|
package/dist/output.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"output.js","sourceRoot":"","sources":["../src/output.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Bounded output streams and adaptive progress commits: `OutputBuffer` keeps a head or tail window of a stream at a cost\n * proportional to each chunk, and `Progress` paces commits of a changing value by their size.\n */\n\n/** Retention limits of one output stream. */\nexport type OutputLimits = { readonly maxBytes: number; readonly maxLines: number; readonly retain: \"head\" | \"tail\" };\n\n/** Retained output and what the limits dropped. */\nexport type BoundedOutput = { readonly text: string; readonly droppedBytes: number; readonly droppedLines: number };\n\n/** An exact slice of the input within the limits, and what it left out. */\nexport type OutputSlice = {\n\treadonly text: string;\n\treadonly bytes: number;\n\treadonly droppedBytes: number;\n\treadonly droppedLines: number;\n};\n\n/**\n * Output a producer omitted before a chunk, measured on the decoded text: every U+FFFD counts as three bytes, and no\n * sanitizing is applied.\n */\nexport interface OutputSkip {\n\t/** UTF-8 byte length of the omitted text. */\n\treadonly bytes: number;\n\t/** Newlines (U+000A) in the omitted text. */\n\treadonly newlines: number;\n\t/** Whether the omitted text ends with a newline. */\n\treadonly endsWithNewline: boolean;\n}\n\nconst NEWLINE = 0x0a;\nconst INVALID_OUTPUT = /[\\x00-\\x08\\x0b-\\x1f\\ufff9-\\ufffb]/g;\nconst encoder = new TextEncoder();\n/** Slices decode exactly: a U+FEFF at a slice's start is text, not a byte-order mark. */\nconst decoder = new TextDecoder(\"utf-8\", { ignoreBOM: true });\n\n/** Remove control characters that break display and transcripts; tabs and newlines stay. */\nexport function sanitizeOutput(text: string): string {\n\treturn text.replace(INVALID_OUTPUT, \"\");\n}\n\n/**\n * Bound `text` to whole lines within the limits: the first lines for `head`, the last lines for `tail`. The result is an\n * exact slice, trailing newline included. A single line longer than `maxBytes` is cut at the byte limit on a character\n * boundary.\n */\nexport function boundOutput(text: string, limits: OutputLimits): OutputSlice {\n\tconst bytes = encoder.encode(text);\n\tconst [from, to] = limits.retain === \"head\" ? headRange(bytes, limits) : tailRange(bytes, limits);\n\tconst kept = bytes.subarray(from, to);\n\treturn {\n\t\ttext: kept.length === bytes.length ? text : decoder.decode(kept),\n\t\tbytes: kept.length,\n\t\tdroppedBytes: bytes.length - kept.length,\n\t\tdroppedLines: lineCount(bytes) - lineCount(kept),\n\t};\n}\n\nfunction headRange(bytes: Uint8Array, limits: OutputLimits): [number, number] {\n\tif (limits.maxLines === 0 || limits.maxBytes === 0) return [0, 0];\n\tlet end = bytes.length;\n\tlet lines = 0;\n\tfor (let index = bytes.indexOf(NEWLINE); index !== -1; index = bytes.indexOf(NEWLINE, index + 1)) {\n\t\tif (++lines === limits.maxLines) {\n\t\t\tend = index + 1;\n\t\t\tbreak;\n\t\t}\n\t}\n\tif (end > limits.maxBytes) {\n\t\tconst newline = bytes.lastIndexOf(NEWLINE, limits.maxBytes - 1);\n\t\tend = newline === -1 ? characterEnd(bytes, limits.maxBytes) : newline + 1;\n\t}\n\treturn [0, end];\n}\n\nfunction tailRange(bytes: Uint8Array, limits: OutputLimits): [number, number] {\n\tif (limits.maxLines === 0 || limits.maxBytes === 0) return [bytes.length, bytes.length];\n\t// A trailing newline ends the last line rather than starting another.\n\tconst last = bytes[bytes.length - 1] === NEWLINE ? bytes.length - 2 : bytes.length - 1;\n\tlet start = 0;\n\tlet lines = 1;\n\tfor (let index = last < 0 ? -1 : bytes.lastIndexOf(NEWLINE, last); index !== -1; ) {\n\t\tif (lines === limits.maxLines) {\n\t\t\tstart = index + 1;\n\t\t\tbreak;\n\t\t}\n\t\tlines++;\n\t\tindex = index === 0 ? -1 : bytes.lastIndexOf(NEWLINE, index - 1);\n\t}\n\tif (bytes.length - start > limits.maxBytes) {\n\t\tconst from = bytes.length - limits.maxBytes;\n\t\tconst newline = bytes.indexOf(NEWLINE, from - 1);\n\t\t// The first line starting inside the byte window, or a cut of the last line when it alone is too long.\n\t\tstart = newline !== -1 && newline + 1 < bytes.length ? newline + 1 : characterStart(bytes, from);\n\t}\n\treturn [start, bytes.length];\n}\n\n/** The last character boundary at or before `index`. */\nexport function characterEnd(bytes: Uint8Array, index: number): number {\n\tlet end = index;\n\twhile (end > 0 && ((bytes[end] ?? 0) & 0xc0) === 0x80) end--;\n\treturn end;\n}\n\n/** The first character boundary at or after `index`. */\nfunction characterStart(bytes: Uint8Array, index: number): number {\n\tlet start = index;\n\twhile (start < bytes.length && ((bytes[start] ?? 0) & 0xc0) === 0x80) start++;\n\treturn start;\n}\n\nfunction lineCount(bytes: Uint8Array): number {\n\tif (bytes.length === 0) return 0;\n\tlet newlines = 0;\n\tfor (let index = bytes.indexOf(NEWLINE); index !== -1; index = bytes.indexOf(NEWLINE, index + 1)) newlines++;\n\treturn newlines + (bytes[bytes.length - 1] === NEWLINE ? 0 : 1);\n}\n\n/**\n * Bounded running output of one stream, such as a tool call's or a process's. Accepting a chunk costs time proportional to the chunk: head retention stops\n * storing once the window is full, and tail retention drops stored text the window no longer needs when it snapshots.\n * Counts of the whole stream are kept so the dropped totals stay exact.\n */\nexport class OutputBuffer {\n\treadonly #limits: OutputLimits;\n\t/**\n\t * Decoder of byte chunks. A string chunk or a skip ends an incomplete character of earlier bytes (it becomes U+FFFD);\n\t * the next byte chunk then starts a new character. As in `StreamDecoder`, only a byte-order mark at the very start of\n\t * the output is dropped, never a U+FEFF later in it.\n\t */\n\treadonly #decoder = new TextDecoder(\"utf-8\", { ignoreBOM: true });\n\t#started = false;\n\t/** Stored chunks: for head the start of the stream, for tail a suffix that still contains the next window. */\n\t#chunks: { readonly text: string; readonly bytes: number; readonly newlines: number }[] = [];\n\t#storedBytes = 0;\n\t#storedNewlines = 0;\n\t#full = false;\n\t#totalBytes = 0;\n\t#totalNewlines = 0;\n\t#endsWithNewline = true;\n\n\tconstructor(limits: OutputLimits) {\n\t\tthis.#limits = limits;\n\t}\n\n\t/** Bytes currently held; bounded by the limits plus one chunk. */\n\tget storedBytes(): number {\n\t\treturn this.#storedBytes;\n\t}\n\n\t/**\n\t * Accept a chunk; returns whether anything was accepted. `skipped` is output omitted right before the chunk, which\n\t * must be more than the tail window by at least one byte or line; only tail retention accepts it.\n\t */\n\tpush(chunk: string | Uint8Array, skipped?: OutputSkip): boolean {\n\t\t// Bytes of an incomplete character from an earlier byte chunk come first.\n\t\tconst pending = typeof chunk === \"string\" || skipped !== undefined ? this.#decoder.decode() : \"\";\n\t\tlet text = typeof chunk === \"string\" ? chunk : this.#decoder.decode(chunk, { stream: true });\n\t\tconst first = !this.#started && pending === \"\" && skipped === undefined;\n\t\tif (pending !== \"\" || text !== \"\" || skipped !== undefined) this.#started = true;\n\t\tif (first && typeof chunk !== \"string\" && text.startsWith(\"\\ufeff\")) text = text.slice(1);\n\t\tif (skipped === undefined) return this.#accept(pending + text);\n\t\tif (this.#limits.retain !== \"tail\") throw new Error(\"Skipped output requires tail retention\");\n\t\tthis.#accept(pending);\n\t\tthis.#skip(skipped);\n\t\tthis.#accept(text);\n\t\treturn true;\n\t}\n\n\t/** Count omitted output; nothing stored before it can be in the window once the text after it arrives. */\n\t#skip(skipped: OutputSkip): void {\n\t\tif (skipped.bytes === 0) return;\n\t\tthis.#totalBytes += skipped.bytes;\n\t\tthis.#totalNewlines += skipped.newlines;\n\t\tthis.#endsWithNewline = skipped.endsWithNewline;\n\t\tthis.#chunks = [];\n\t\tthis.#storedBytes = 0;\n\t\tthis.#storedNewlines = 0;\n\t}\n\n\t/** Flush an incomplete trailing character as a replacement character; call when the stream ends. */\n\tend(): void {\n\t\tthis.#accept(this.#decoder.decode());\n\t}\n\n\t#accept(text: string): boolean {\n\t\tif (text.length === 0) return false;\n\t\tconst bytes = utf8ByteLength(text);\n\t\tconst newlines = countNewlines(text);\n\t\tthis.#totalBytes += bytes;\n\t\tthis.#totalNewlines += newlines;\n\t\tthis.#endsWithNewline = text.endsWith(\"\\n\");\n\t\tif (this.#full) return true;\n\t\tthis.#chunks.push({ text, bytes, newlines });\n\t\tthis.#storedBytes += bytes;\n\t\tthis.#storedNewlines += newlines;\n\t\tif (this.#limits.retain === \"head\") {\n\t\t\t// Nothing past a full window is ever needed.\n\t\t\tthis.#full = this.#storedBytes > this.#limits.maxBytes || this.#storedNewlines >= this.#limits.maxLines;\n\t\t\treturn true;\n\t\t}\n\t\t// Drop leading chunks while the rest still holds more than a window: more than `maxBytes` bytes or `maxLines`\n\t\t// newlines, plus one, so the window's line start can still be found. Each chunk is dropped once.\n\t\twhile (this.#chunks.length > 1) {\n\t\t\tconst first = this.#chunks[0]!;\n\t\t\tconst bytesAfter = this.#storedBytes - first.bytes;\n\t\t\tconst newlinesAfter = this.#storedNewlines - first.newlines;\n\t\t\tif (bytesAfter <= this.#limits.maxBytes + 1 && newlinesAfter <= this.#limits.maxLines + 1) break;\n\t\t\tthis.#chunks.shift();\n\t\t\tthis.#storedBytes = bytesAfter;\n\t\t\tthis.#storedNewlines = newlinesAfter;\n\t\t}\n\t\treturn true;\n\t}\n\n\t/** Retained, sanitized output and what the limits dropped from the whole stream. */\n\tsnapshot(): BoundedOutput {\n\t\tconst stored =\n\t\t\tthis.#chunks.length === 1 ? this.#chunks[0]!.text : this.#chunks.map((chunk) => chunk.text).join(\"\");\n\t\tconst kept = boundOutput(stored, this.#limits);\n\t\tconst storedLines = lines(this.#storedNewlines, stored === \"\" || stored.endsWith(\"\\n\"));\n\t\tconst keptLines = storedLines - kept.droppedLines;\n\t\t// Tail windows never reach back before this one, but finding a later window's first line needs what precedes it:\n\t\t// keep the shortest suffix longer than the window by a byte or a line, as `#accept` does.\n\t\tif (this.#limits.retain === \"tail\" || this.#chunks.length > 1) {\n\t\t\tconst text = this.#limits.retain === \"tail\" ? tailMargin(stored, this.#limits) : stored;\n\t\t\tconst bytes = this.#limits.retain === \"tail\" ? utf8ByteLength(text) : this.#storedBytes;\n\t\t\tthis.#chunks = text === \"\" ? [] : [{ text, bytes, newlines: countNewlines(text) }];\n\t\t\tthis.#storedBytes = bytes;\n\t\t\tthis.#storedNewlines = this.#chunks[0]?.newlines ?? 0;\n\t\t}\n\t\treturn {\n\t\t\ttext: sanitizeOutput(kept.text),\n\t\t\tdroppedBytes: this.#totalBytes - kept.bytes,\n\t\t\tdroppedLines: lines(this.#totalNewlines, this.#endsWithNewline) - keptLines,\n\t\t};\n\t}\n}\n\n/**\n * The shortest suffix of `text` with more than `maxBytes` bytes or more than `maxLines` newlines, or all of it. The\n * tail window of any text that ends with this suffix, followed by anything, is the same as of `text` followed by it.\n */\nfunction tailMargin(text: string, limits: OutputLimits): string {\n\tconst bytes = encoder.encode(text);\n\tconst byteStart = bytes.length > limits.maxBytes ? characterEnd(bytes, bytes.length - limits.maxBytes - 1) : 0;\n\tlet lineStart = 0;\n\tlet newlines = 0;\n\tfor (let index = bytes.lastIndexOf(NEWLINE); index !== -1; index = bytes.lastIndexOf(NEWLINE, index - 1)) {\n\t\tif (++newlines > limits.maxLines) {\n\t\t\tlineStart = index;\n\t\t\tbreak;\n\t\t}\n\t\tif (index === 0) break;\n\t}\n\tconst start = Math.max(byteStart, lineStart);\n\treturn start === 0 ? text : decoder.decode(bytes.subarray(start));\n}\n\n/** Lines of text with `newlines` newlines; a final unterminated line counts. */\nfunction lines(newlines: number, terminated: boolean): number {\n\treturn newlines + (terminated ? 0 : 1);\n}\n\ninterface RuntimeBuffer {\n\tbyteLength(content: string, encoding: \"utf8\"): number;\n}\n\nconst runtimeBuffer = (globalThis as { Buffer?: RuntimeBuffer }).Buffer;\nconst nonAsciiPattern = /[^\\x00-\\x7f]/;\n\n/** UTF-8 byte length of `content`; a lone surrogate counts as U+FFFD, three bytes. */\nexport function utf8ByteLength(content: string): number {\n\tif (runtimeBuffer) return runtimeBuffer.byteLength(content, \"utf8\");\n\tconst firstNonAscii = content.search(nonAsciiPattern);\n\tif (firstNonAscii === -1) return content.length;\n\tlet bytes = firstNonAscii;\n\tfor (let i = firstNonAscii; i < content.length; i++) {\n\t\tconst code = content.charCodeAt(i);\n\t\tif (code <= 0x7f) bytes += 1;\n\t\telse if (code <= 0x7ff) bytes += 2;\n\t\telse if (code >= 0xd800 && code <= 0xdbff && i + 1 < content.length) {\n\t\t\tconst next = content.charCodeAt(i + 1);\n\t\t\tif (next >= 0xdc00 && next <= 0xdfff) {\n\t\t\t\tbytes += 4;\n\t\t\t\ti++;\n\t\t\t} else bytes += 3;\n\t\t} else bytes += 3;\n\t}\n\treturn bytes;\n}\n\nfunction countNewlines(text: string): number {\n\tlet count = 0;\n\tfor (let index = text.indexOf(\"\\n\"); index !== -1; index = text.indexOf(\"\\n\", index + 1)) count++;\n\treturn count;\n}\n\n/** Each progress commit also buys a pause proportional to what it wrote. */\nexport const PROGRESS_BYTES_PER_SECOND = 100 * 1024;\n\n/**\n * Adaptive progress commits: the first change after an idle period commits at once; each commit then delays the next\n * by at least `minIntervalMs` and by its written size at 100 KiB/s. At most one commit is in flight; changes made\n * meanwhile coalesce into the next one.\n */\nexport class Progress {\n\treadonly #write: () => Promise<number>;\n\treadonly #onError: (error: unknown) => void;\n\treadonly #minIntervalMs: number;\n\t#waiters: PromiseWithResolvers<void>[] = [];\n\t#timer: ReturnType<typeof setTimeout> | undefined;\n\t#inFlight: Promise<void> | undefined;\n\t#nextAt = 0;\n\t#dirty = false;\n\t#stopped = false;\n\n\tconstructor(write: () => Promise<number>, onError: (error: unknown) => void, minIntervalMs: number) {\n\t\tthis.#write = write;\n\t\tthis.#onError = onError;\n\t\tthis.#minIntervalMs = minIntervalMs;\n\t}\n\n\t/** Schedule a commit. */\n\tmark(): void {\n\t\tthis.#dirty = true;\n\t\tthis.#schedule();\n\t}\n\n\t/** Schedule a commit; the promise settles with the commit that includes this change. */\n\tmarkAndWait(): Promise<void> {\n\t\tconst waiter = Promise.withResolvers<void>();\n\t\tthis.#waiters.push(waiter);\n\t\tthis.mark();\n\t\treturn waiter.promise;\n\t}\n\n\t/** Stop committing and wait for the commit in flight; returns the waiters the final commit must settle. */\n\tasync stop(): Promise<PromiseWithResolvers<void>[]> {\n\t\tthis.#stopped = true;\n\t\tclearTimeout(this.#timer);\n\t\tthis.#timer = undefined;\n\t\tawait this.#inFlight;\n\t\treturn this.#waiters.splice(0);\n\t}\n\n\t#schedule(): void {\n\t\tif (this.#stopped || this.#timer !== undefined || this.#inFlight !== undefined) return;\n\t\tconst wait = this.#nextAt - Date.now();\n\t\tif (wait <= 0) this.#flush();\n\t\telse\n\t\t\tthis.#timer = setTimeout(() => {\n\t\t\t\tthis.#timer = undefined;\n\t\t\t\tthis.#flush();\n\t\t\t}, wait);\n\t}\n\n\t#flush(): void {\n\t\tif (this.#stopped || !this.#dirty) return;\n\t\tthis.#dirty = false;\n\t\tconst waiters = this.#waiters.splice(0);\n\t\tconst started = Date.now();\n\t\tthis.#inFlight = this.#write()\n\t\t\t.then(\n\t\t\t\t(bytes) => {\n\t\t\t\t\tthis.#nextAt = started + Math.max(this.#minIntervalMs, (bytes * 1000) / PROGRESS_BYTES_PER_SECOND);\n\t\t\t\t\tfor (const waiter of waiters) waiter.resolve();\n\t\t\t\t},\n\t\t\t\t(error: unknown) => {\n\t\t\t\t\tthis.#nextAt = started + this.#minIntervalMs;\n\t\t\t\t\tfor (const waiter of waiters) waiter.reject(error);\n\t\t\t\t\tthis.#onError(error);\n\t\t\t\t},\n\t\t\t)\n\t\t\t.finally(() => {\n\t\t\t\tthis.#inFlight = undefined;\n\t\t\t\tif (this.#dirty) this.#schedule();\n\t\t\t});\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"output.js","sourceRoot":"","sources":["../src/output.ts"],"names":[],"mappings":"AAAA;;;GAGG;AA6BH,MAAM,OAAO,GAAG,IAAI,CAAC;AACrB,MAAM,cAAc,GAAG,oCAAoC,CAAC;AAC5D,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC;AAClC,yFAAyF;AACzF,MAAM,OAAO,GAAG,IAAI,WAAW,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;AAE9D,4FAA4F;AAC5F,MAAM,UAAU,cAAc,CAAC,IAAY;IAC1C,OAAO,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;AACzC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,WAAW,CAAC,IAAY,EAAE,MAAoB;IAC7D,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACnC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IAClG,MAAM,IAAI,GAAG,KAAK,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IACtC,OAAO;QACN,IAAI,EAAE,IAAI,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC;QAChE,KAAK,EAAE,IAAI,CAAC,MAAM;QAClB,YAAY,EAAE,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM;QACxC,YAAY,EAAE,SAAS,CAAC,KAAK,CAAC,GAAG,SAAS,CAAC,IAAI,CAAC;KAChD,CAAC;AACH,CAAC;AAED,SAAS,SAAS,CAAC,KAAiB,EAAE,MAAoB;IACzD,IAAI,MAAM,CAAC,QAAQ,KAAK,CAAC,IAAI,MAAM,CAAC,QAAQ,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAClE,IAAI,GAAG,GAAG,KAAK,CAAC,MAAM,CAAC;IACvB,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,KAAK,IAAI,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,KAAK,KAAK,CAAC,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,OAAO,EAAE,KAAK,GAAG,CAAC,CAAC,EAAE,CAAC;QAClG,IAAI,EAAE,KAAK,KAAK,MAAM,CAAC,QAAQ,EAAE,CAAC;YACjC,GAAG,GAAG,KAAK,GAAG,CAAC,CAAC;YAChB,MAAM;QACP,CAAC;IACF,CAAC;IACD,IAAI,GAAG,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAC;QAC3B,MAAM,OAAO,GAAG,KAAK,CAAC,WAAW,CAAC,OAAO,EAAE,MAAM,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC;QAChE,GAAG,GAAG,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,KAAK,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC;IAC3E,CAAC;IACD,OAAO,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;AACjB,CAAC;AAED,SAAS,SAAS,CAAC,KAAiB,EAAE,MAAoB;IACzD,IAAI,MAAM,CAAC,QAAQ,KAAK,CAAC,IAAI,MAAM,CAAC,QAAQ,KAAK,CAAC;QAAE,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IACxF,sEAAsE;IACtE,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;IACvF,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,KAAK,IAAI,KAAK,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC,OAAO,EAAE,IAAI,CAAC,EAAE,KAAK,KAAK,CAAC,CAAC,GAAI,CAAC;QACnF,IAAI,KAAK,KAAK,MAAM,CAAC,QAAQ,EAAE,CAAC;YAC/B,KAAK,GAAG,KAAK,GAAG,CAAC,CAAC;YAClB,MAAM;QACP,CAAC;QACD,KAAK,EAAE,CAAC;QACR,KAAK,GAAG,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC,OAAO,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC;IAClE,CAAC;IACD,IAAI,KAAK,CAAC,MAAM,GAAG,KAAK,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAC;QAC5C,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC;QAC5C,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,GAAG,CAAC,CAAC,CAAC;QACjD,uGAAuG;QACvG,KAAK,GAAG,OAAO,KAAK,CAAC,CAAC,IAAI,OAAO,GAAG,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IAClG,CAAC;IACD,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;AAC9B,CAAC;AAED,wDAAwD;AACxD,MAAM,UAAU,YAAY,CAAC,KAAiB,EAAE,KAAa;IAC5D,IAAI,GAAG,GAAG,KAAK,CAAC;IAChB,OAAO,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,IAAI;QAAE,GAAG,EAAE,CAAC;IAC7D,OAAO,GAAG,CAAC;AACZ,CAAC;AAED,wDAAwD;AACxD,SAAS,cAAc,CAAC,KAAiB,EAAE,KAAa;IACvD,IAAI,KAAK,GAAG,KAAK,CAAC;IAClB,OAAO,KAAK,GAAG,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,IAAI;QAAE,KAAK,EAAE,CAAC;IAC9E,OAAO,KAAK,CAAC;AACd,CAAC;AAED,SAAS,SAAS,CAAC,KAAiB;IACnC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC;IACjC,IAAI,QAAQ,GAAG,CAAC,CAAC;IACjB,KAAK,IAAI,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,KAAK,KAAK,CAAC,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,OAAO,EAAE,KAAK,GAAG,CAAC,CAAC;QAAE,QAAQ,EAAE,CAAC;IAC7G,OAAO,QAAQ,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACjE,CAAC;AAED;;;;GAIG;AACH,MAAM,OAAO,YAAY;IACf,OAAO,CAAe;IAC/B;;;;OAIG;IACM,QAAQ,GAAG,IAAI,WAAW,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAClE,QAAQ,GAAG,KAAK,CAAC;IACjB,8GAA8G;IAC9G,OAAO,GAAmF,EAAE,CAAC;IAC7F,YAAY,GAAG,CAAC,CAAC;IACjB,eAAe,GAAG,CAAC,CAAC;IACpB,KAAK,GAAG,KAAK,CAAC;IACd,WAAW,GAAG,CAAC,CAAC;IAChB,cAAc,GAAG,CAAC,CAAC;IACnB,gBAAgB,GAAG,IAAI,CAAC;IAExB,YAAY,MAAoB;QAC/B,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC;IACvB,CAAC;IAED,kEAAkE;IAClE,IAAI,WAAW;QACd,OAAO,IAAI,CAAC,YAAY,CAAC;IAC1B,CAAC;IAED;;;OAGG;IACH,IAAI,CAAC,KAA0B,EAAE,OAAoB;QACpD,0EAA0E;QAC1E,MAAM,OAAO,GAAG,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACjG,IAAI,IAAI,GAAG,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;QAC7F,MAAM,KAAK,GAAG,CAAC,IAAI,CAAC,QAAQ,IAAI,OAAO,KAAK,EAAE,IAAI,OAAO,KAAK,SAAS,CAAC;QACxE,IAAI,OAAO,KAAK,EAAE,IAAI,IAAI,KAAK,EAAE,IAAI,OAAO,KAAK,SAAS;YAAE,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QACjF,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC;YAAE,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAC1F,IAAI,OAAO,KAAK,SAAS;YAAE,OAAO,IAAI,CAAC,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;QAC/D,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,KAAK,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC;QAC9F,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QACtB,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACpB,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QACnB,OAAO,IAAI,CAAC;IACb,CAAC;IAED,0GAA0G;IAC1G,KAAK,CAAC,OAAmB;QACxB,IAAI,OAAO,CAAC,KAAK,KAAK,CAAC;YAAE,OAAO;QAChC,IAAI,CAAC,WAAW,IAAI,OAAO,CAAC,KAAK,CAAC;QAClC,IAAI,CAAC,cAAc,IAAI,OAAO,CAAC,QAAQ,CAAC;QACxC,IAAI,CAAC,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC;QAChD,IAAI,CAAC,OAAO,GAAG,EAAE,CAAC;QAClB,IAAI,CAAC,YAAY,GAAG,CAAC,CAAC;QACtB,IAAI,CAAC,eAAe,GAAG,CAAC,CAAC;IAC1B,CAAC;IAED,oGAAoG;IACpG,GAAG;QACF,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;IACtC,CAAC;IAED,OAAO,CAAC,IAAY;QACnB,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,KAAK,CAAC;QACpC,MAAM,KAAK,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;QACnC,MAAM,QAAQ,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;QACrC,IAAI,CAAC,WAAW,IAAI,KAAK,CAAC;QAC1B,IAAI,CAAC,cAAc,IAAI,QAAQ,CAAC;QAChC,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QAC5C,IAAI,IAAI,CAAC,KAAK;YAAE,OAAO,IAAI,CAAC;QAC5B,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;QAC7C,IAAI,CAAC,YAAY,IAAI,KAAK,CAAC;QAC3B,IAAI,CAAC,eAAe,IAAI,QAAQ,CAAC;QACjC,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;YACpC,6CAA6C;YAC7C,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,IAAI,IAAI,CAAC,eAAe,IAAI,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC;YACxG,OAAO,IAAI,CAAC;QACb,CAAC;QACD,8GAA8G;QAC9G,iGAAiG;QACjG,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAChC,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAE,CAAC;YAC/B,MAAM,UAAU,GAAG,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC,KAAK,CAAC;YACnD,MAAM,aAAa,GAAG,IAAI,CAAC,eAAe,GAAG,KAAK,CAAC,QAAQ,CAAC;YAC5D,IAAI,UAAU,IAAI,IAAI,CAAC,OAAO,CAAC,QAAQ,GAAG,CAAC,IAAI,aAAa,IAAI,IAAI,CAAC,OAAO,CAAC,QAAQ,GAAG,CAAC;gBAAE,MAAM;YACjG,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;YACrB,IAAI,CAAC,YAAY,GAAG,UAAU,CAAC;YAC/B,IAAI,CAAC,eAAe,GAAG,aAAa,CAAC;QACtC,CAAC;QACD,OAAO,IAAI,CAAC;IACb,CAAC;IAED,oFAAoF;IACpF,QAAQ;QACP,MAAM,MAAM,GACX,IAAI,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAE,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACtG,MAAM,IAAI,GAAG,WAAW,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;QAC/C,MAAM,WAAW,GAAG,KAAK,CAAC,IAAI,CAAC,eAAe,EAAE,MAAM,KAAK,EAAE,IAAI,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;QACxF,MAAM,SAAS,GAAG,WAAW,GAAG,IAAI,CAAC,YAAY,CAAC;QAClD,iHAAiH;QACjH,0FAA0F;QAC1F,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,KAAK,MAAM,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC/D,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;YACxF,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC;YACxF,IAAI,CAAC,OAAO,GAAG,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACnF,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC;YAC1B,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,QAAQ,IAAI,CAAC,CAAC;QACvD,CAAC;QACD,OAAO;YACN,IAAI,EAAE,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC;YAC/B,YAAY,EAAE,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,KAAK;YAC3C,YAAY,EAAE,KAAK,CAAC,IAAI,CAAC,cAAc,EAAE,IAAI,CAAC,gBAAgB,CAAC,GAAG,SAAS;SAC3E,CAAC;IACH,CAAC;CACD;AAED;;;GAGG;AACH,SAAS,UAAU,CAAC,IAAY,EAAE,MAAoB;IACrD,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACnC,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC,KAAK,EAAE,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/G,IAAI,SAAS,GAAG,CAAC,CAAC;IAClB,IAAI,QAAQ,GAAG,CAAC,CAAC;IACjB,KAAK,IAAI,KAAK,GAAG,KAAK,CAAC,WAAW,CAAC,OAAO,CAAC,EAAE,KAAK,KAAK,CAAC,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC,WAAW,CAAC,OAAO,EAAE,KAAK,GAAG,CAAC,CAAC,EAAE,CAAC;QAC1G,IAAI,EAAE,QAAQ,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAC;YAClC,SAAS,GAAG,KAAK,CAAC;YAClB,MAAM;QACP,CAAC;QACD,IAAI,KAAK,KAAK,CAAC;YAAE,MAAM;IACxB,CAAC;IACD,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;IAC7C,OAAO,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;AACnE,CAAC;AAED,gFAAgF;AAChF,SAAS,KAAK,CAAC,QAAgB,EAAE,UAAmB;IACnD,OAAO,QAAQ,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACxC,CAAC;AAMD,MAAM,aAAa,GAAI,UAAyC,CAAC,MAAM,CAAC;AACxE,MAAM,eAAe,GAAG,cAAc,CAAC;AAEvC,sFAAsF;AACtF,MAAM,UAAU,cAAc,CAAC,OAAe;IAC7C,IAAI,aAAa;QAAE,OAAO,aAAa,CAAC,UAAU,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IACpE,MAAM,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC;IACtD,IAAI,aAAa,KAAK,CAAC,CAAC;QAAE,OAAO,OAAO,CAAC,MAAM,CAAC;IAChD,IAAI,KAAK,GAAG,aAAa,CAAC;IAC1B,KAAK,IAAI,CAAC,GAAG,aAAa,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrD,MAAM,IAAI,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;QACnC,IAAI,IAAI,IAAI,IAAI;YAAE,KAAK,IAAI,CAAC,CAAC;aACxB,IAAI,IAAI,IAAI,KAAK;YAAE,KAAK,IAAI,CAAC,CAAC;aAC9B,IAAI,IAAI,IAAI,MAAM,IAAI,IAAI,IAAI,MAAM,IAAI,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;YACrE,MAAM,IAAI,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YACvC,IAAI,IAAI,IAAI,MAAM,IAAI,IAAI,IAAI,MAAM,EAAE,CAAC;gBACtC,KAAK,IAAI,CAAC,CAAC;gBACX,CAAC,EAAE,CAAC;YACL,CAAC;;gBAAM,KAAK,IAAI,CAAC,CAAC;QACnB,CAAC;;YAAM,KAAK,IAAI,CAAC,CAAC;IACnB,CAAC;IACD,OAAO,KAAK,CAAC;AACd,CAAC;AAED,SAAS,aAAa,CAAC,IAAY;IAClC,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,KAAK,IAAI,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,KAAK,CAAC,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,GAAG,CAAC,CAAC;QAAE,KAAK,EAAE,CAAC;IAClG,OAAO,KAAK,CAAC;AACd,CAAC;AAED,4EAA4E;AAC5E,MAAM,CAAC,MAAM,yBAAyB,GAAG,GAAG,GAAG,IAAI,CAAC;AASpD,MAAM,YAAY,GAAkB;IACnC,GAAG,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE;IACrB,QAAQ,EAAE,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE;QAC/B,MAAM,KAAK,GAAG,UAAU,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAC5C,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;IAClC,CAAC;CACD,CAAC;AAEF;;;;GAIG;AACH,MAAM,OAAO,QAAQ;IACX,MAAM,CAAwB;IAC9B,QAAQ,CAA2B;IACnC,cAAc,CAAS;IACvB,MAAM,CAAgB;IAC/B,QAAQ,GAAiC,EAAE,CAAC;IAC5C,MAAM,CAA2B;IACjC,SAAS,CAA4B;IACrC,OAAO,GAAG,CAAC,CAAC;IACZ,MAAM,GAAG,KAAK,CAAC;IACf,QAAQ,GAAG,KAAK,CAAC;IAEjB,YACC,KAA4B,EAC5B,OAAiC,EACjC,aAAqB,EACrB,KAAK,GAAkB,YAAY;QAEnC,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;QACpB,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC;QACxB,IAAI,CAAC,cAAc,GAAG,aAAa,CAAC;QACpC,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;IACrB,CAAC;IAED,yBAAyB;IACzB,IAAI;QACH,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QACnB,IAAI,CAAC,SAAS,EAAE,CAAC;IAClB,CAAC;IAED,wFAAwF;IACxF,WAAW;QACV,MAAM,MAAM,GAAG,OAAO,CAAC,aAAa,EAAQ,CAAC;QAC7C,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC3B,IAAI,CAAC,IAAI,EAAE,CAAC;QACZ,OAAO,MAAM,CAAC,OAAO,CAAC;IACvB,CAAC;IAED,2GAA2G;IAC3G,KAAK,CAAC,IAAI;QACT,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QACrB,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;QAChB,IAAI,CAAC,MAAM,GAAG,SAAS,CAAC;QACxB,MAAM,IAAI,CAAC,SAAS,CAAC;QACrB,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IAChC,CAAC;IAED,SAAS;QACR,IAAI,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS,IAAI,IAAI,CAAC,SAAS,KAAK,SAAS;YAAE,OAAO;QACvF,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC;QAC9C,IAAI,IAAI,IAAI,CAAC;YAAE,IAAI,CAAC,MAAM,EAAE,CAAC;;YAE5B,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,EAAE;gBACvC,IAAI,CAAC,MAAM,GAAG,SAAS,CAAC;gBACxB,uEAAuE;gBACvE,IAAI,CAAC,SAAS,EAAE,CAAC;YAClB,CAAC,EAAE,IAAI,CAAC,CAAC;IACX,CAAC;IAED,MAAM;QACL,IAAI,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,MAAM;YAAE,OAAO;QAC1C,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;QACpB,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QACxC,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC;QAClC,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,MAAM,EAAE;aAC5B,IAAI,CACJ,CAAC,KAAK,EAAE,EAAE;YACT,IAAI,CAAC,OAAO,GAAG,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC,KAAK,GAAG,IAAI,CAAC,GAAG,yBAAyB,CAAC,CAAC;YACnG,KAAK,MAAM,MAAM,IAAI,OAAO;gBAAE,MAAM,CAAC,OAAO,EAAE,CAAC;QAChD,CAAC,EACD,CAAC,KAAc,EAAE,EAAE;YAClB,IAAI,CAAC,OAAO,GAAG,OAAO,GAAG,IAAI,CAAC,cAAc,CAAC;YAC7C,KAAK,MAAM,MAAM,IAAI,OAAO;gBAAE,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACnD,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QACtB,CAAC,CACD;aACA,OAAO,CAAC,GAAG,EAAE;YACb,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;YAC3B,IAAI,IAAI,CAAC,MAAM;gBAAE,IAAI,CAAC,SAAS,EAAE,CAAC;QACnC,CAAC,CAAC,CAAC;IACL,CAAC;CACD","sourcesContent":["/**\n * Bounded output streams and adaptive progress commits: `OutputBuffer` keeps a head or tail window of a stream at a cost\n * proportional to each chunk, and `Progress` paces commits of a changing value by their size.\n */\n\n/** Retention limits of one output stream. */\nexport type OutputLimits = { readonly maxBytes: number; readonly maxLines: number; readonly retain: \"head\" | \"tail\" };\n\n/** Retained output and what the limits dropped. */\nexport type BoundedOutput = { readonly text: string; readonly droppedBytes: number; readonly droppedLines: number };\n\n/** An exact slice of the input within the limits, and what it left out. */\nexport type OutputSlice = {\n\treadonly text: string;\n\treadonly bytes: number;\n\treadonly droppedBytes: number;\n\treadonly droppedLines: number;\n};\n\n/**\n * Output a producer omitted before a chunk, measured on the decoded text: every U+FFFD counts as three bytes, and no\n * sanitizing is applied.\n */\nexport interface OutputSkip {\n\t/** UTF-8 byte length of the omitted text. */\n\treadonly bytes: number;\n\t/** Newlines (U+000A) in the omitted text. */\n\treadonly newlines: number;\n\t/** Whether the omitted text ends with a newline. */\n\treadonly endsWithNewline: boolean;\n}\n\nconst NEWLINE = 0x0a;\nconst INVALID_OUTPUT = /[\\x00-\\x08\\x0b-\\x1f\\ufff9-\\ufffb]/g;\nconst encoder = new TextEncoder();\n/** Slices decode exactly: a U+FEFF at a slice's start is text, not a byte-order mark. */\nconst decoder = new TextDecoder(\"utf-8\", { ignoreBOM: true });\n\n/** Remove control characters that break display and transcripts; tabs and newlines stay. */\nexport function sanitizeOutput(text: string): string {\n\treturn text.replace(INVALID_OUTPUT, \"\");\n}\n\n/**\n * Bound `text` to whole lines within the limits: the first lines for `head`, the last lines for `tail`. The result is an\n * exact slice, trailing newline included. A single line longer than `maxBytes` is cut at the byte limit on a character\n * boundary.\n */\nexport function boundOutput(text: string, limits: OutputLimits): OutputSlice {\n\tconst bytes = encoder.encode(text);\n\tconst [from, to] = limits.retain === \"head\" ? headRange(bytes, limits) : tailRange(bytes, limits);\n\tconst kept = bytes.subarray(from, to);\n\treturn {\n\t\ttext: kept.length === bytes.length ? text : decoder.decode(kept),\n\t\tbytes: kept.length,\n\t\tdroppedBytes: bytes.length - kept.length,\n\t\tdroppedLines: lineCount(bytes) - lineCount(kept),\n\t};\n}\n\nfunction headRange(bytes: Uint8Array, limits: OutputLimits): [number, number] {\n\tif (limits.maxLines === 0 || limits.maxBytes === 0) return [0, 0];\n\tlet end = bytes.length;\n\tlet lines = 0;\n\tfor (let index = bytes.indexOf(NEWLINE); index !== -1; index = bytes.indexOf(NEWLINE, index + 1)) {\n\t\tif (++lines === limits.maxLines) {\n\t\t\tend = index + 1;\n\t\t\tbreak;\n\t\t}\n\t}\n\tif (end > limits.maxBytes) {\n\t\tconst newline = bytes.lastIndexOf(NEWLINE, limits.maxBytes - 1);\n\t\tend = newline === -1 ? characterEnd(bytes, limits.maxBytes) : newline + 1;\n\t}\n\treturn [0, end];\n}\n\nfunction tailRange(bytes: Uint8Array, limits: OutputLimits): [number, number] {\n\tif (limits.maxLines === 0 || limits.maxBytes === 0) return [bytes.length, bytes.length];\n\t// A trailing newline ends the last line rather than starting another.\n\tconst last = bytes[bytes.length - 1] === NEWLINE ? bytes.length - 2 : bytes.length - 1;\n\tlet start = 0;\n\tlet lines = 1;\n\tfor (let index = last < 0 ? -1 : bytes.lastIndexOf(NEWLINE, last); index !== -1; ) {\n\t\tif (lines === limits.maxLines) {\n\t\t\tstart = index + 1;\n\t\t\tbreak;\n\t\t}\n\t\tlines++;\n\t\tindex = index === 0 ? -1 : bytes.lastIndexOf(NEWLINE, index - 1);\n\t}\n\tif (bytes.length - start > limits.maxBytes) {\n\t\tconst from = bytes.length - limits.maxBytes;\n\t\tconst newline = bytes.indexOf(NEWLINE, from - 1);\n\t\t// The first line starting inside the byte window, or a cut of the last line when it alone is too long.\n\t\tstart = newline !== -1 && newline + 1 < bytes.length ? newline + 1 : characterStart(bytes, from);\n\t}\n\treturn [start, bytes.length];\n}\n\n/** The last character boundary at or before `index`. */\nexport function characterEnd(bytes: Uint8Array, index: number): number {\n\tlet end = index;\n\twhile (end > 0 && ((bytes[end] ?? 0) & 0xc0) === 0x80) end--;\n\treturn end;\n}\n\n/** The first character boundary at or after `index`. */\nfunction characterStart(bytes: Uint8Array, index: number): number {\n\tlet start = index;\n\twhile (start < bytes.length && ((bytes[start] ?? 0) & 0xc0) === 0x80) start++;\n\treturn start;\n}\n\nfunction lineCount(bytes: Uint8Array): number {\n\tif (bytes.length === 0) return 0;\n\tlet newlines = 0;\n\tfor (let index = bytes.indexOf(NEWLINE); index !== -1; index = bytes.indexOf(NEWLINE, index + 1)) newlines++;\n\treturn newlines + (bytes[bytes.length - 1] === NEWLINE ? 0 : 1);\n}\n\n/**\n * Bounded running output of one stream, such as a tool call's or a process's. Accepting a chunk costs time proportional to the chunk: head retention stops\n * storing once the window is full, and tail retention drops stored text the window no longer needs when it snapshots.\n * Counts of the whole stream are kept so the dropped totals stay exact.\n */\nexport class OutputBuffer {\n\treadonly #limits: OutputLimits;\n\t/**\n\t * Decoder of byte chunks. A string chunk or a skip ends an incomplete character of earlier bytes (it becomes U+FFFD);\n\t * the next byte chunk then starts a new character. As in `StreamDecoder`, only a byte-order mark at the very start of\n\t * the output is dropped, never a U+FEFF later in it.\n\t */\n\treadonly #decoder = new TextDecoder(\"utf-8\", { ignoreBOM: true });\n\t#started = false;\n\t/** Stored chunks: for head the start of the stream, for tail a suffix that still contains the next window. */\n\t#chunks: { readonly text: string; readonly bytes: number; readonly newlines: number }[] = [];\n\t#storedBytes = 0;\n\t#storedNewlines = 0;\n\t#full = false;\n\t#totalBytes = 0;\n\t#totalNewlines = 0;\n\t#endsWithNewline = true;\n\n\tconstructor(limits: OutputLimits) {\n\t\tthis.#limits = limits;\n\t}\n\n\t/** Bytes currently held; bounded by the limits plus one chunk. */\n\tget storedBytes(): number {\n\t\treturn this.#storedBytes;\n\t}\n\n\t/**\n\t * Accept a chunk; returns whether anything was accepted. `skipped` is output omitted right before the chunk, which\n\t * must be more than the tail window by at least one byte or line; only tail retention accepts it.\n\t */\n\tpush(chunk: string | Uint8Array, skipped?: OutputSkip): boolean {\n\t\t// Bytes of an incomplete character from an earlier byte chunk come first.\n\t\tconst pending = typeof chunk === \"string\" || skipped !== undefined ? this.#decoder.decode() : \"\";\n\t\tlet text = typeof chunk === \"string\" ? chunk : this.#decoder.decode(chunk, { stream: true });\n\t\tconst first = !this.#started && pending === \"\" && skipped === undefined;\n\t\tif (pending !== \"\" || text !== \"\" || skipped !== undefined) this.#started = true;\n\t\tif (first && typeof chunk !== \"string\" && text.startsWith(\"\\ufeff\")) text = text.slice(1);\n\t\tif (skipped === undefined) return this.#accept(pending + text);\n\t\tif (this.#limits.retain !== \"tail\") throw new Error(\"Skipped output requires tail retention\");\n\t\tthis.#accept(pending);\n\t\tthis.#skip(skipped);\n\t\tthis.#accept(text);\n\t\treturn true;\n\t}\n\n\t/** Count omitted output; nothing stored before it can be in the window once the text after it arrives. */\n\t#skip(skipped: OutputSkip): void {\n\t\tif (skipped.bytes === 0) return;\n\t\tthis.#totalBytes += skipped.bytes;\n\t\tthis.#totalNewlines += skipped.newlines;\n\t\tthis.#endsWithNewline = skipped.endsWithNewline;\n\t\tthis.#chunks = [];\n\t\tthis.#storedBytes = 0;\n\t\tthis.#storedNewlines = 0;\n\t}\n\n\t/** Flush an incomplete trailing character as a replacement character; call when the stream ends. */\n\tend(): void {\n\t\tthis.#accept(this.#decoder.decode());\n\t}\n\n\t#accept(text: string): boolean {\n\t\tif (text.length === 0) return false;\n\t\tconst bytes = utf8ByteLength(text);\n\t\tconst newlines = countNewlines(text);\n\t\tthis.#totalBytes += bytes;\n\t\tthis.#totalNewlines += newlines;\n\t\tthis.#endsWithNewline = text.endsWith(\"\\n\");\n\t\tif (this.#full) return true;\n\t\tthis.#chunks.push({ text, bytes, newlines });\n\t\tthis.#storedBytes += bytes;\n\t\tthis.#storedNewlines += newlines;\n\t\tif (this.#limits.retain === \"head\") {\n\t\t\t// Nothing past a full window is ever needed.\n\t\t\tthis.#full = this.#storedBytes > this.#limits.maxBytes || this.#storedNewlines >= this.#limits.maxLines;\n\t\t\treturn true;\n\t\t}\n\t\t// Drop leading chunks while the rest still holds more than a window: more than `maxBytes` bytes or `maxLines`\n\t\t// newlines, plus one, so the window's line start can still be found. Each chunk is dropped once.\n\t\twhile (this.#chunks.length > 1) {\n\t\t\tconst first = this.#chunks[0]!;\n\t\t\tconst bytesAfter = this.#storedBytes - first.bytes;\n\t\t\tconst newlinesAfter = this.#storedNewlines - first.newlines;\n\t\t\tif (bytesAfter <= this.#limits.maxBytes + 1 && newlinesAfter <= this.#limits.maxLines + 1) break;\n\t\t\tthis.#chunks.shift();\n\t\t\tthis.#storedBytes = bytesAfter;\n\t\t\tthis.#storedNewlines = newlinesAfter;\n\t\t}\n\t\treturn true;\n\t}\n\n\t/** Retained, sanitized output and what the limits dropped from the whole stream. */\n\tsnapshot(): BoundedOutput {\n\t\tconst stored =\n\t\t\tthis.#chunks.length === 1 ? this.#chunks[0]!.text : this.#chunks.map((chunk) => chunk.text).join(\"\");\n\t\tconst kept = boundOutput(stored, this.#limits);\n\t\tconst storedLines = lines(this.#storedNewlines, stored === \"\" || stored.endsWith(\"\\n\"));\n\t\tconst keptLines = storedLines - kept.droppedLines;\n\t\t// Tail windows never reach back before this one, but finding a later window's first line needs what precedes it:\n\t\t// keep the shortest suffix longer than the window by a byte or a line, as `#accept` does.\n\t\tif (this.#limits.retain === \"tail\" || this.#chunks.length > 1) {\n\t\t\tconst text = this.#limits.retain === \"tail\" ? tailMargin(stored, this.#limits) : stored;\n\t\t\tconst bytes = this.#limits.retain === \"tail\" ? utf8ByteLength(text) : this.#storedBytes;\n\t\t\tthis.#chunks = text === \"\" ? [] : [{ text, bytes, newlines: countNewlines(text) }];\n\t\t\tthis.#storedBytes = bytes;\n\t\t\tthis.#storedNewlines = this.#chunks[0]?.newlines ?? 0;\n\t\t}\n\t\treturn {\n\t\t\ttext: sanitizeOutput(kept.text),\n\t\t\tdroppedBytes: this.#totalBytes - kept.bytes,\n\t\t\tdroppedLines: lines(this.#totalNewlines, this.#endsWithNewline) - keptLines,\n\t\t};\n\t}\n}\n\n/**\n * The shortest suffix of `text` with more than `maxBytes` bytes or more than `maxLines` newlines, or all of it. The\n * tail window of any text that ends with this suffix, followed by anything, is the same as of `text` followed by it.\n */\nfunction tailMargin(text: string, limits: OutputLimits): string {\n\tconst bytes = encoder.encode(text);\n\tconst byteStart = bytes.length > limits.maxBytes ? characterEnd(bytes, bytes.length - limits.maxBytes - 1) : 0;\n\tlet lineStart = 0;\n\tlet newlines = 0;\n\tfor (let index = bytes.lastIndexOf(NEWLINE); index !== -1; index = bytes.lastIndexOf(NEWLINE, index - 1)) {\n\t\tif (++newlines > limits.maxLines) {\n\t\t\tlineStart = index;\n\t\t\tbreak;\n\t\t}\n\t\tif (index === 0) break;\n\t}\n\tconst start = Math.max(byteStart, lineStart);\n\treturn start === 0 ? text : decoder.decode(bytes.subarray(start));\n}\n\n/** Lines of text with `newlines` newlines; a final unterminated line counts. */\nfunction lines(newlines: number, terminated: boolean): number {\n\treturn newlines + (terminated ? 0 : 1);\n}\n\ninterface RuntimeBuffer {\n\tbyteLength(content: string, encoding: \"utf8\"): number;\n}\n\nconst runtimeBuffer = (globalThis as { Buffer?: RuntimeBuffer }).Buffer;\nconst nonAsciiPattern = /[^\\x00-\\x7f]/;\n\n/** UTF-8 byte length of `content`; a lone surrogate counts as U+FFFD, three bytes. */\nexport function utf8ByteLength(content: string): number {\n\tif (runtimeBuffer) return runtimeBuffer.byteLength(content, \"utf8\");\n\tconst firstNonAscii = content.search(nonAsciiPattern);\n\tif (firstNonAscii === -1) return content.length;\n\tlet bytes = firstNonAscii;\n\tfor (let i = firstNonAscii; i < content.length; i++) {\n\t\tconst code = content.charCodeAt(i);\n\t\tif (code <= 0x7f) bytes += 1;\n\t\telse if (code <= 0x7ff) bytes += 2;\n\t\telse if (code >= 0xd800 && code <= 0xdbff && i + 1 < content.length) {\n\t\t\tconst next = content.charCodeAt(i + 1);\n\t\t\tif (next >= 0xdc00 && next <= 0xdfff) {\n\t\t\t\tbytes += 4;\n\t\t\t\ti++;\n\t\t\t} else bytes += 3;\n\t\t} else bytes += 3;\n\t}\n\treturn bytes;\n}\n\nfunction countNewlines(text: string): number {\n\tlet count = 0;\n\tfor (let index = text.indexOf(\"\\n\"); index !== -1; index = text.indexOf(\"\\n\", index + 1)) count++;\n\treturn count;\n}\n\n/** Each progress commit also buys a pause proportional to what it wrote. */\nexport const PROGRESS_BYTES_PER_SECOND = 100 * 1024;\n\n/** The clock and timer progress commits pace on. */\nexport type ProgressClock = {\n\treadonly now: () => number;\n\t/** Call `callback` once after about `delayMs`; returns a function that disarms it. */\n\treadonly setTimer: (callback: () => void, delayMs: number) => () => void;\n};\n\nconst SYSTEM_CLOCK: ProgressClock = {\n\tnow: () => Date.now(),\n\tsetTimer: (callback, delayMs) => {\n\t\tconst timer = setTimeout(callback, delayMs);\n\t\treturn () => clearTimeout(timer);\n\t},\n};\n\n/**\n * Adaptive progress commits: the first change after an idle period commits at once; each commit then delays the next\n * by at least `minIntervalMs` and by its written size at 100 KiB/s. At most one commit is in flight; changes made\n * meanwhile coalesce into the next one. Paces on `clock`, by default `Date.now` and `setTimeout`.\n */\nexport class Progress {\n\treadonly #write: () => Promise<number>;\n\treadonly #onError: (error: unknown) => void;\n\treadonly #minIntervalMs: number;\n\treadonly #clock: ProgressClock;\n\t#waiters: PromiseWithResolvers<void>[] = [];\n\t#timer: (() => void) | undefined;\n\t#inFlight: Promise<void> | undefined;\n\t#nextAt = 0;\n\t#dirty = false;\n\t#stopped = false;\n\n\tconstructor(\n\t\twrite: () => Promise<number>,\n\t\tonError: (error: unknown) => void,\n\t\tminIntervalMs: number,\n\t\tclock: ProgressClock = SYSTEM_CLOCK,\n\t) {\n\t\tthis.#write = write;\n\t\tthis.#onError = onError;\n\t\tthis.#minIntervalMs = minIntervalMs;\n\t\tthis.#clock = clock;\n\t}\n\n\t/** Schedule a commit. */\n\tmark(): void {\n\t\tthis.#dirty = true;\n\t\tthis.#schedule();\n\t}\n\n\t/** Schedule a commit; the promise settles with the commit that includes this change. */\n\tmarkAndWait(): Promise<void> {\n\t\tconst waiter = Promise.withResolvers<void>();\n\t\tthis.#waiters.push(waiter);\n\t\tthis.mark();\n\t\treturn waiter.promise;\n\t}\n\n\t/** Stop committing and wait for the commit in flight; returns the waiters the final commit must settle. */\n\tasync stop(): Promise<PromiseWithResolvers<void>[]> {\n\t\tthis.#stopped = true;\n\t\tthis.#timer?.();\n\t\tthis.#timer = undefined;\n\t\tawait this.#inFlight;\n\t\treturn this.#waiters.splice(0);\n\t}\n\n\t#schedule(): void {\n\t\tif (this.#stopped || this.#timer !== undefined || this.#inFlight !== undefined) return;\n\t\tconst wait = this.#nextAt - this.#clock.now();\n\t\tif (wait <= 0) this.#flush();\n\t\telse\n\t\t\tthis.#timer = this.#clock.setTimer(() => {\n\t\t\t\tthis.#timer = undefined;\n\t\t\t\t// Checks the clock again: a timer that fires early waits for the rest.\n\t\t\t\tthis.#schedule();\n\t\t\t}, wait);\n\t}\n\n\t#flush(): void {\n\t\tif (this.#stopped || !this.#dirty) return;\n\t\tthis.#dirty = false;\n\t\tconst waiters = this.#waiters.splice(0);\n\t\tconst started = this.#clock.now();\n\t\tthis.#inFlight = this.#write()\n\t\t\t.then(\n\t\t\t\t(bytes) => {\n\t\t\t\t\tthis.#nextAt = started + Math.max(this.#minIntervalMs, (bytes * 1000) / PROGRESS_BYTES_PER_SECOND);\n\t\t\t\t\tfor (const waiter of waiters) waiter.resolve();\n\t\t\t\t},\n\t\t\t\t(error: unknown) => {\n\t\t\t\t\tthis.#nextAt = started + this.#minIntervalMs;\n\t\t\t\t\tfor (const waiter of waiters) waiter.reject(error);\n\t\t\t\t\tthis.#onError(error);\n\t\t\t\t},\n\t\t\t)\n\t\t\t.finally(() => {\n\t\t\t\tthis.#inFlight = undefined;\n\t\t\t\tif (this.#dirty) this.#schedule();\n\t\t\t});\n\t}\n}\n"]}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { SqliteDatabase, SqliteExecutor, SqliteValue } from "./database.ts";
|
|
2
|
+
/** Values a Durable Object SQL binding accepts and returns. */
|
|
3
|
+
type DurableObjectSqlValue = ArrayBuffer | string | number | null;
|
|
4
|
+
/**
|
|
5
|
+
* The parts of a SQLite-backed Durable Object's `ctx.storage` this adapter uses, typed structurally so the package
|
|
6
|
+
* needs no Workers type dependency.
|
|
7
|
+
*/
|
|
8
|
+
export type DurableObjectSqliteStorage = {
|
|
9
|
+
readonly sql: {
|
|
10
|
+
exec(query: string, ...bindings: DurableObjectSqlValue[]): {
|
|
11
|
+
next(): {
|
|
12
|
+
readonly done?: false;
|
|
13
|
+
readonly value: Record<string, DurableObjectSqlValue>;
|
|
14
|
+
} | {
|
|
15
|
+
readonly done: true;
|
|
16
|
+
readonly value?: undefined;
|
|
17
|
+
};
|
|
18
|
+
toArray(): Record<string, DurableObjectSqlValue>[];
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
transaction<T>(closure: () => Promise<T>): Promise<T>;
|
|
22
|
+
};
|
|
23
|
+
/** Executes SQL through `ctx.storage.sql`, which has no separate prepare step. */
|
|
24
|
+
declare class DurableObjectSqliteExecutor implements SqliteExecutor {
|
|
25
|
+
protected readonly storage: DurableObjectSqliteStorage;
|
|
26
|
+
constructor(storage: DurableObjectSqliteStorage);
|
|
27
|
+
exec(sql: string): Promise<void>;
|
|
28
|
+
run(sql: string, ...params: SqliteValue[]): Promise<void>;
|
|
29
|
+
get<T extends object>(sql: string, ...params: SqliteValue[]): Promise<T | undefined>;
|
|
30
|
+
all<T extends object>(sql: string, ...params: SqliteValue[]): Promise<T[]>;
|
|
31
|
+
/** Throws when this handle may no longer run SQL. */
|
|
32
|
+
protected check(): void;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* `SqliteDatabase` adapter for the SQLite storage of a Cloudflare Durable Object. Adapters given the same storage
|
|
36
|
+
* object share a queue; direct calls to the underlying storage bypass it. Integers are JavaScript numbers; binding a
|
|
37
|
+
* `bigint` outside the safe integer range throws.
|
|
38
|
+
*/
|
|
39
|
+
export declare class DurableObjectSqliteDatabase extends DurableObjectSqliteExecutor implements SqliteDatabase {
|
|
40
|
+
private readonly queue;
|
|
41
|
+
constructor(storage: DurableObjectSqliteStorage);
|
|
42
|
+
exec(sql: string): Promise<void>;
|
|
43
|
+
run(sql: string, ...params: SqliteValue[]): Promise<void>;
|
|
44
|
+
get<T extends object>(sql: string, ...params: SqliteValue[]): Promise<T | undefined>;
|
|
45
|
+
all<T extends object>(sql: string, ...params: SqliteValue[]): Promise<T[]>;
|
|
46
|
+
/** `ctx.storage.transaction()` commits when the callback resolves and rolls back when it rejects. */
|
|
47
|
+
transaction<T>(callback: (transaction: SqliteExecutor) => Promise<T>): Promise<T>;
|
|
48
|
+
/** Waits for queued work. The Durable Object owns its storage, so nothing else closes. */
|
|
49
|
+
close(): Promise<void>;
|
|
50
|
+
}
|
|
51
|
+
export {};
|
|
52
|
+
//# sourceMappingURL=cloudflare.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cloudflare.d.ts","sourceRoot":"","sources":["../../src/sqlite/cloudflare.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAEjF,+DAA+D;AAC/D,KAAK,qBAAqB,GAAG,WAAW,GAAG,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;AAElE;;;GAGG;AACH,MAAM,MAAM,0BAA0B,GAAG;IACxC,QAAQ,CAAC,GAAG,EAAE;QACb,IAAI,CACH,KAAK,EAAE,MAAM,EACb,GAAG,QAAQ,EAAE,qBAAqB,EAAE,GAClC;YACF,IAAI,IACD;gBAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,KAAK,CAAC;gBAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,qBAAqB,CAAC,CAAA;aAAE,GAChF;gBAAE,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;gBAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,CAAA;aAAE,CAAC;YACvD,OAAO,IAAI,MAAM,CAAC,MAAM,EAAE,qBAAqB,CAAC,EAAE,CAAC;SACnD,CAAC;KACF,CAAC;IACF,WAAW,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;CACtD,CAAC;AAiEF,kFAAkF;AAClF,cAAM,2BAA4B,YAAW,cAAc;IAC1D,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,0BAA0B,CAAC;IAEvD,YAAY,OAAO,EAAE,0BAA0B,EAE9C;IAEK,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAGrC;IAEK,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAG9D;IAEK,GAAG,CAAC,CAAC,SAAS,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC,CAIzF;IAEK,GAAG,CAAC,CAAC,SAAS,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC,CAM/E;IAED,qDAAqD;IACrD,SAAS,CAAC,KAAK,IAAI,IAAI,CAAG;CAC1B;AAWD;;;;GAIG;AACH,qBAAa,2BAA4B,SAAQ,2BAA4B,YAAW,cAAc;IACrG,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAc;IAEpC,YAAY,OAAO,EAAE,0BAA0B,EAG9C;IAEQ,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAExC;IAEQ,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAEjE;IAEQ,GAAG,CAAC,CAAC,SAAS,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC,CAE5F;IAEQ,GAAG,CAAC,CAAC,SAAS,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC,CAElF;IAED,qGAAqG;IACrG,WAAW,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,WAAW,EAAE,cAAc,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAWhF;IAED,0FAA0F;IAC1F,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAErB;CACD"}
|