@mcp-b/do-runtime 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -0
- package/LICENSE +110 -0
- package/LICENSE.workerd +176 -0
- package/NOTICE +7 -0
- package/README.md +282 -0
- package/dist/backends/node-sqlite.d.ts +38 -0
- package/dist/backends/node-sqlite.js +335 -0
- package/dist/backends/node-sqlite.js.map +1 -0
- package/dist/backends/sqlite-wasm.d.ts +130 -0
- package/dist/backends/sqlite-wasm.js +259 -0
- package/dist/backends/sqlite-wasm.js.map +1 -0
- package/dist/chunks/sqlite-DFg92Tgt.js +498 -0
- package/dist/chunks/sqlite-DFg92Tgt.js.map +1 -0
- package/dist/cloudflare-workers.js +351 -0
- package/dist/cloudflare-workers.js.map +1 -0
- package/dist/conformance/host.d.ts +58 -0
- package/dist/conformance.js +18 -0
- package/dist/conformance.js.map +1 -0
- package/dist/index.js +7184 -0
- package/dist/index.js.map +1 -0
- package/dist/server/alarm-scheduler.js +513 -0
- package/dist/server/alarm-scheduler.js.map +1 -0
- package/dist/src/api/actor-state.d.ts +396 -0
- package/dist/src/api/actor.d.ts +306 -0
- package/dist/src/api/cloudflare-workers.d.ts +259 -0
- package/dist/src/api/export-loopback.d.ts +264 -0
- package/dist/src/api/global-scope.d.ts +262 -0
- package/dist/src/api/http.d.ts +52 -0
- package/dist/src/api/sql.d.ts +188 -0
- package/dist/src/api/sync-kv.d.ts +51 -0
- package/dist/src/api/web-socket.d.ts +93 -0
- package/dist/src/api/worker-loader.d.ts +354 -0
- package/dist/src/index.d.ts +130 -0
- package/dist/src/io/actor-cache.d.ts +203 -0
- package/dist/src/io/actor-id.d.ts +74 -0
- package/dist/src/io/actor-sqlite.d.ts +298 -0
- package/dist/src/io/io-channels.d.ts +191 -0
- package/dist/src/io/io-context.d.ts +451 -0
- package/dist/src/io/io-gate.d.ts +298 -0
- package/dist/src/io/worker-source.d.ts +108 -0
- package/dist/src/io/worker.d.ts +88 -0
- package/dist/src/server/actor-container.d.ts +525 -0
- package/dist/src/server/actor-id-impl.d.ts +118 -0
- package/dist/src/server/alarm-scheduler.d.ts +201 -0
- package/dist/src/server/facet-deletion.d.ts +156 -0
- package/dist/src/server/facet-tree-index.d.ts +94 -0
- package/dist/src/server/sha256.d.ts +39 -0
- package/dist/src/transport/rpc-session.d.ts +34 -0
- package/dist/src/util/sqlite-kv.d.ts +98 -0
- package/dist/src/util/sqlite-metadata.d.ts +46 -0
- package/dist/src/util/sqlite.d.ts +291 -0
- package/package.json +111 -0
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ← workerd `src/workerd/api/sql.{h,c++}`
|
|
3
|
+
*
|
|
4
|
+
* `SqlStorage` and its two nested types. ~330 call sites depend on this — it is
|
|
5
|
+
* the real storage layer, not KV.
|
|
6
|
+
*
|
|
7
|
+
* Four things about the translation, in descending order of how much they cost:
|
|
8
|
+
*
|
|
9
|
+
* 1. **The cursor is materialised, not live.** Upstream's `Cursor` owns a
|
|
10
|
+
* running `SqliteDatabase::Query` and pulls one row at a time; the backend
|
|
11
|
+
* seam this package chose (`SqlDatabase.exec` → `SqlResult`) has already
|
|
12
|
+
* collected every row before a cursor exists. Everything downstream of that
|
|
13
|
+
* follows: there is no statement cache, so `CachedStatement`, the 1 MiB LRU
|
|
14
|
+
* and `reusedCachedQueryForTest` are absent with it; there is no live
|
|
15
|
+
* statement to cancel, so `Cursor::canceled` and `selfRef` — both already
|
|
16
|
+
* dead upstream, written but never assigned — have nothing to guard; and
|
|
17
|
+
* `endQuery`'s job of returning a statement to the cache is nothing here, so
|
|
18
|
+
* the counters it saves off are simply the counters. What is kept is every
|
|
19
|
+
* observable: the position is shared across `next`/`toArray`/`one`/`raw`,
|
|
20
|
+
* and a drained cursor keeps yielding done.
|
|
21
|
+
* 2. **`Cursor` and `Statement` must be constructible with no arguments**, or
|
|
22
|
+
* `SqlStorage` cannot satisfy workers-types without a cast: the interface
|
|
23
|
+
* types them `typeof SqlStorageCursor` / `typeof SqlStorageStatement`, and
|
|
24
|
+
* both are `abstract` there, so their construct signatures take none.
|
|
25
|
+
* Upstream's are unconstructible from JS for the same reason they are
|
|
26
|
+
* `abstract` in the types — JSG nested types have no JS constructor — so the
|
|
27
|
+
* faithful shape is a constructor that refuses. `sql.Cursor` exists for
|
|
28
|
+
* `instanceof`, which is all upstream exposes it for.
|
|
29
|
+
* 3. **The regulator is ported whole; what is missing is the authorizer that
|
|
30
|
+
* calls it.** All three callbacks are here and none of them needed the
|
|
31
|
+
* authorizer to compute anything — `isAllowedName` is a prefix test,
|
|
32
|
+
* `isAllowedTrigger` is `return true`, `allowTransactions` throws. What the
|
|
33
|
+
* authorizer supplied was the *identifiers*, not the decisions. With no
|
|
34
|
+
* authorizer the statement text is the only source, so `exec` tokenizes it
|
|
35
|
+
* and runs `isAllowedName` over every identifier-shaped token. That is
|
|
36
|
+
* deliberately STRICTER than upstream — see `SQL_RESERVED_PREFIX_MESSAGE`.
|
|
37
|
+
* 4. **`ingest` stays at upstream's SQLite seam.** `SqliteDatabase.ingest()`
|
|
38
|
+
* executes every complete statement and returns the partial tail, using the
|
|
39
|
+
* same compiled boundaries and regulator as `exec`.
|
|
40
|
+
*
|
|
41
|
+
* Spec: §1.4, §2.4 in docs/decisions.md.
|
|
42
|
+
*/
|
|
43
|
+
import type { IoContext } from "../io/io-context.js";
|
|
44
|
+
import type { SqlIngestResult, SqliteDatabase } from "../util/sqlite.js";
|
|
45
|
+
/**
|
|
46
|
+
* ← `SqlStorage::BindingValue`. JSG converts these public JavaScript values
|
|
47
|
+
* to workerd's `Maybe<OneOf<Array<byte>, String, double>>` before C++ sees them;
|
|
48
|
+
* `toSqlBindingValue()` is that conversion for this no-isolate runtime.
|
|
49
|
+
*/
|
|
50
|
+
export type BindingValue = ArrayBuffer | ArrayBufferView | string | number | boolean | null | undefined;
|
|
51
|
+
/** ← the `SqlStorageValue` `JSG_TS_DEFINE` on `Cursor`. */
|
|
52
|
+
export type SqlRow = Record<string, SqlStorageValue>;
|
|
53
|
+
/** ← `SqlStorage::IngestResult`. */
|
|
54
|
+
export type SqlStorageIngestResult = SqlIngestResult;
|
|
55
|
+
/**
|
|
56
|
+
* ← `SqlStorageRegulator::allowTransactions()`, copied verbatim. Users match on
|
|
57
|
+
* it and it is the one regulator callback our substrate can still answer.
|
|
58
|
+
*/
|
|
59
|
+
export declare const SQL_TRANSACTION_REFUSED_MESSAGE: string;
|
|
60
|
+
/** See translation 2 in the header: the class is exposed for `instanceof` only. */
|
|
61
|
+
export declare const CURSOR_NOT_CONSTRUCTIBLE_MESSAGE = "Illegal invocation: SqlStorage.Cursor cannot be constructed directly. Use sql.exec().";
|
|
62
|
+
/** Same, for the prepared-statement compatibility shim. */
|
|
63
|
+
export declare const STATEMENT_NOT_CONSTRUCTIBLE_MESSAGE = "Illegal invocation: SqlStorage.Statement cannot be constructed directly. Use sql.prepare().";
|
|
64
|
+
/**
|
|
65
|
+
* ← SQLite's own denial text, with the reason appended.
|
|
66
|
+
*
|
|
67
|
+
* There is no upstream string to copy here: `SqlStorageRegulator::onError` just
|
|
68
|
+
* rethrows whatever SQLite produced, and SQLite produces `not authorized` for an
|
|
69
|
+
* authorizer denial (`access to X.Y is prohibited` for the column-read case,
|
|
70
|
+
* which needs a resolved identifier we do not have). The prefix is kept so that
|
|
71
|
+
* anything matching upstream still matches; the rest is here because a bare
|
|
72
|
+
* `not authorized` is not debuggable.
|
|
73
|
+
*/
|
|
74
|
+
export declare const SQL_RESERVED_PREFIX_MESSAGE: string;
|
|
75
|
+
/**
|
|
76
|
+
* ← `SqlStorageRegulator` (`sql.h:15-22`, `sql.c++:143-173`), whole.
|
|
77
|
+
*
|
|
78
|
+
* Upstream reaches these through the SQLite authorizer while a statement is
|
|
79
|
+
* being compiled. `exec` calls them from the statement text instead, which is
|
|
80
|
+
* the same translation Section 3 made for the write classifier and for
|
|
81
|
+
* transaction state.
|
|
82
|
+
*/
|
|
83
|
+
export declare const SqlStorageRegulator: {
|
|
84
|
+
/**
|
|
85
|
+
* Upstream's body is `return !name.startsWith("_cf_")`, with an autogate that
|
|
86
|
+
* makes the comparison case-insensitive and logs a warning until it lands. The
|
|
87
|
+
* case-insensitive form is taken here: it is the direction upstream is moving,
|
|
88
|
+
* and there is no logger for the warning half.
|
|
89
|
+
*/
|
|
90
|
+
isAllowedName(name: string): boolean;
|
|
91
|
+
/** Upstream's body is `return true`. */
|
|
92
|
+
isAllowedTrigger(_name: string): boolean;
|
|
93
|
+
/** Upstream's body is a `JSG_FAIL_REQUIRE` with this message. */
|
|
94
|
+
allowTransactions(): never;
|
|
95
|
+
/** "Bill for queries executed from JavaScript." Nothing reads it — `SqliteObserver` has no port. */
|
|
96
|
+
shouldAddQueryStats(): boolean;
|
|
97
|
+
};
|
|
98
|
+
/**
|
|
99
|
+
* ← the `jsg::Ref<DurableObjectStorage>` `SqlStorage` holds, narrowed to the one
|
|
100
|
+
* member it reaches through (`SqlStorage::getDb`). `DurableObjectStorage`
|
|
101
|
+
* satisfies it; narrowing is what keeps this file free of a value-level import
|
|
102
|
+
* cycle, which upstream tolerates because C++ headers do not have one.
|
|
103
|
+
*/
|
|
104
|
+
export interface SqlStorageOwner {
|
|
105
|
+
/** ← `DurableObjectStorage::getSqliteDb`. Throws if not SQLite-backed. */
|
|
106
|
+
getSqliteDb(): SqliteDatabase;
|
|
107
|
+
}
|
|
108
|
+
/** The rows a cursor walks, plus the counters that outlive them. */
|
|
109
|
+
type CursorState = {
|
|
110
|
+
readonly columnNames: string[];
|
|
111
|
+
readonly rawRows: readonly (readonly SqlStorageValue[])[];
|
|
112
|
+
readonly rowsWritten: number;
|
|
113
|
+
};
|
|
114
|
+
/**
|
|
115
|
+
* ← `SqlStorage::Cursor`.
|
|
116
|
+
*
|
|
117
|
+
* `rowsRead` is the one counter that is not upstream's. Upstream reads
|
|
118
|
+
* `Query::getRowsRead()`, a billing counter sourced from libsql's
|
|
119
|
+
* `STMTSTATUS_ROWS_READ` that counts index rows and that neither backend
|
|
120
|
+
* exposes — the same absence the README already records for `SqlResult`. The
|
|
121
|
+
* interface requires a number, so this returns the rows the cursor has yielded,
|
|
122
|
+
* which is what today's browser host returns and what its tests assert. It
|
|
123
|
+
* undercounts any query that scans more rows than it returns.
|
|
124
|
+
*/
|
|
125
|
+
export declare class Cursor<T extends SqlRow = SqlRow> implements SqlStorageCursor<T> {
|
|
126
|
+
#private;
|
|
127
|
+
readonly columnNames: string[];
|
|
128
|
+
constructor(state?: CursorState);
|
|
129
|
+
/** ← `Cursor::next`, whose `RowIterator::Next` is this exact shape. */
|
|
130
|
+
next(): {
|
|
131
|
+
done?: false;
|
|
132
|
+
value: T;
|
|
133
|
+
} | {
|
|
134
|
+
done: true;
|
|
135
|
+
value?: never;
|
|
136
|
+
};
|
|
137
|
+
/** ← `Cursor::toArray`, which drains from the current position. */
|
|
138
|
+
toArray(): T[];
|
|
139
|
+
/** ← `Cursor::one`. Both messages are upstream's, verbatim. */
|
|
140
|
+
one(): T;
|
|
141
|
+
/** ← `Cursor::raw`, which shares this cursor's position rather than restarting. */
|
|
142
|
+
raw<U extends SqlStorageValue[]>(): IterableIterator<U>;
|
|
143
|
+
/** ← `JSG_ITERABLE(rows)`. */
|
|
144
|
+
[Symbol.iterator](): IterableIterator<T>;
|
|
145
|
+
get rowsRead(): number;
|
|
146
|
+
/** ← `Cursor::getRowsWritten`, which is `SqlResult.rowsWritten` here. */
|
|
147
|
+
get rowsWritten(): number;
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* ← `SqlStorage::Statement`, which upstream describes as "supported only for
|
|
151
|
+
* backwards compatibility ... it is actually just a wrapper around `exec()`".
|
|
152
|
+
* `JSG_CALLABLE(run)` makes the object itself callable, so `prepare()` returns a
|
|
153
|
+
* function wearing this prototype rather than an object with a `run` method.
|
|
154
|
+
*/
|
|
155
|
+
export declare class Statement {
|
|
156
|
+
constructor();
|
|
157
|
+
}
|
|
158
|
+
/** What `prepare()` hands back: `Statement::run`, reachable by calling it. */
|
|
159
|
+
export interface PreparedStatement {
|
|
160
|
+
<T extends SqlRow = SqlRow>(...bindings: BindingValue[]): Cursor<T>;
|
|
161
|
+
}
|
|
162
|
+
export declare class SqlStorage implements globalThis.SqlStorage {
|
|
163
|
+
#private;
|
|
164
|
+
constructor(ctx: IoContext, owner: SqlStorageOwner);
|
|
165
|
+
/** ← `JSG_NESTED_TYPE(Cursor)`. Exposed so `instanceof` works, as upstream's is. */
|
|
166
|
+
readonly Cursor: typeof Cursor;
|
|
167
|
+
/** ← `JSG_NESTED_TYPE(Statement)`. */
|
|
168
|
+
readonly Statement: typeof Statement;
|
|
169
|
+
exec<T extends SqlRow = SqlRow>(query: string, ...bindings: BindingValue[]): Cursor<T>;
|
|
170
|
+
/**
|
|
171
|
+
* ← `SqlStorage::getDatabaseSize`.
|
|
172
|
+
*
|
|
173
|
+
* Upstream's second query is `PRAGMA page_size;`, which `sqlite3_stmt_readonly()`
|
|
174
|
+
* reports read-only. With no such call the text is the only source and §1.7.1's
|
|
175
|
+
* rule is write-unless-provably-a-read, so a bare `PRAGMA` would open a
|
|
176
|
+
* transaction and take an output-gate lock to answer a size question. The
|
|
177
|
+
* `pragma_page_size` table-valued function is the same value read through the
|
|
178
|
+
* `SELECT` upstream already uses for the page count.
|
|
179
|
+
*/
|
|
180
|
+
get databaseSize(): number;
|
|
181
|
+
/** ← `SqlStorage::prepare`. Experimental and deprecated upstream; `exec` caches for you. */
|
|
182
|
+
prepare(query: string): PreparedStatement;
|
|
183
|
+
/** ← `SqlStorage::ingest`. */
|
|
184
|
+
ingest(query: string): SqlStorageIngestResult;
|
|
185
|
+
/** ← `SqlStorage::setMaxPageCountForTest`, which is what its name says. */
|
|
186
|
+
setMaxPageCountForTest(count: number): void;
|
|
187
|
+
}
|
|
188
|
+
export {};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ← workerd `src/workerd/api/sync-kv.{h,c++}`
|
|
3
|
+
*
|
|
4
|
+
* "Synchronous KV storage. Available as ctx.storage.kv on SQLite-backed DOs."
|
|
5
|
+
*
|
|
6
|
+
* This module is not in Section 5's brief and exists because
|
|
7
|
+
* `DurableObjectStorage` cannot satisfy workers-types without it: the interface
|
|
8
|
+
* declares `kv: SyncKvStorage` unconditionally, and §2.4's rule is that the
|
|
9
|
+
* surface is verified by the type system rather than by a cast. It is also a
|
|
10
|
+
* genuine part of the contract — a whole KV surface that skips the promise
|
|
11
|
+
* wrapper, over the same `SqliteKv` `DurableObjectStorage` writes through, with
|
|
12
|
+
* the same codec.
|
|
13
|
+
*
|
|
14
|
+
* Two things upstream has that are absent, both already absent below this file:
|
|
15
|
+
* the trace spans every method opens, and the billing counters. What is kept is
|
|
16
|
+
* the whole of the behaviour, including the one error that is neither of those:
|
|
17
|
+
* a `list()` iterator invalidated by a second `list()` says so rather than
|
|
18
|
+
* silently ending, which is `SqliteKv::ListCursor::wasCanceled()`.
|
|
19
|
+
*
|
|
20
|
+
* Spec: §2.4 in docs/decisions.md.
|
|
21
|
+
*/
|
|
22
|
+
import type { IoContext } from "../io/io-context.js";
|
|
23
|
+
import type { SqliteKv } from "../util/sqlite-kv.js";
|
|
24
|
+
/**
|
|
25
|
+
* ← the `jsg::Ref<DurableObjectStorage>` `SyncKvStorage` holds, narrowed to the
|
|
26
|
+
* one member it reaches through (`SyncKvStorage::getSqliteKv`).
|
|
27
|
+
*/
|
|
28
|
+
export interface SyncKvStorageOwner {
|
|
29
|
+
getSqliteKv(): SqliteKv;
|
|
30
|
+
}
|
|
31
|
+
/** ← `SyncKvStorage::ListOptions`, which is `ListOptions` minus the two gate flags. */
|
|
32
|
+
export type SyncKvListOptions = {
|
|
33
|
+
start?: string;
|
|
34
|
+
startAfter?: string;
|
|
35
|
+
end?: string;
|
|
36
|
+
prefix?: string;
|
|
37
|
+
reverse?: boolean;
|
|
38
|
+
limit?: number;
|
|
39
|
+
};
|
|
40
|
+
export declare class SyncKvStorage implements globalThis.SyncKvStorage {
|
|
41
|
+
#private;
|
|
42
|
+
constructor(ctx: IoContext, owner: SyncKvStorageOwner);
|
|
43
|
+
get<T = unknown>(key: string): T | undefined;
|
|
44
|
+
/**
|
|
45
|
+
* ← `SyncKvStorage::list`, which reuses `compileListOptions` — "This is public
|
|
46
|
+
* so that SyncKvStorage can reuse it."
|
|
47
|
+
*/
|
|
48
|
+
list<T = unknown>(options?: SyncKvListOptions): Iterable<[string, T]>;
|
|
49
|
+
put<T>(key: string, value: T): void;
|
|
50
|
+
delete(key: string): boolean;
|
|
51
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ← workerd `src/workerd/api/web-socket.{h,c++}` — the gating, and nothing else.
|
|
3
|
+
*
|
|
4
|
+
* A socket is the one primitive that is neither of the other two, and §1.8 says
|
|
5
|
+
* why in three lines: incoming frames "each take a fresh input lock via
|
|
6
|
+
* `context.run(...)`", the read loop "captures the critical section at
|
|
7
|
+
* `accept()` time", and outbound messages "each carry their own output-gate
|
|
8
|
+
* promise captured at `send()` time". Upstream states the first outright, on the
|
|
9
|
+
* line that does it (`web-socket.c++:1056-1059`):
|
|
10
|
+
*
|
|
11
|
+
* > "Re-enter the context with context.run(). This is arguably a bit unusual
|
|
12
|
+
* > compared to other I/O which is delivered by return from context.awaitIo(),
|
|
13
|
+
* > but the difference here is that we have a long stream of events over time.
|
|
14
|
+
* > It makes sense to use context.run() each time a new event arrives."
|
|
15
|
+
*
|
|
16
|
+
* So a socket cannot be `awaitIo`: there is no single result to resume from.
|
|
17
|
+
* `accept()` starts a loop, and the loop is the gate's caller.
|
|
18
|
+
*
|
|
19
|
+
* **What is ported and what is not.** The frame protocol, the hibernation
|
|
20
|
+
* states, auto-response, `WebSocketPair` and the byte accounting are all
|
|
21
|
+
* absent — the substrate ships a `WebSocket`, and hibernation is a recorded
|
|
22
|
+
* substrate boundary with no Chrome lifecycle to be faithful to. What is here is
|
|
23
|
+
* `WebSocket::Accepted`: the three gate properties above, over whatever socket
|
|
24
|
+
* the host hands in. That is the same division `api/http.ts` makes and for the
|
|
25
|
+
* same reason.
|
|
26
|
+
*
|
|
27
|
+
* **The accept contract, and the hole it leaves.** After `acceptWebSocket`, the
|
|
28
|
+
* gated view owns the raw socket's events. A consumer that keeps a reference to
|
|
29
|
+
* the raw socket and registers a listener on it directly gets that listener
|
|
30
|
+
* called ungated, and nothing here can prevent it — upstream cannot be reached
|
|
31
|
+
* that way because `accept()` moves the `kj::WebSocket` into `Accepted` and the
|
|
32
|
+
* JS object never had it. The refusal below covers the case that is detectable
|
|
33
|
+
* (accepting the same socket twice); the rest is the accept contract, stated.
|
|
34
|
+
*
|
|
35
|
+
* Spec: §1.1, §1.8 and decision 5 in
|
|
36
|
+
* docs/decisions.md.
|
|
37
|
+
*/
|
|
38
|
+
import type { IoContext } from "../io/io-context.js";
|
|
39
|
+
/**
|
|
40
|
+
* The socket beneath. Deliberately structural and minimal: a real `WebSocket`,
|
|
41
|
+
* the extension's `WebSocketFacade` over capnweb, and a test double all satisfy
|
|
42
|
+
* it, and none of them is a type this package should name.
|
|
43
|
+
*/
|
|
44
|
+
export interface RawWebSocket {
|
|
45
|
+
addEventListener(type: string, listener: (event: Event) => void): void;
|
|
46
|
+
send(data: string | ArrayBufferLike | ArrayBufferView | Blob): void;
|
|
47
|
+
close(code?: number, reason?: string): void;
|
|
48
|
+
}
|
|
49
|
+
/** ← the `JSG_REQUIRE(!native.state.is<Accepted>(), ...)` at the head of `accept()`. */
|
|
50
|
+
export declare const ALREADY_ACCEPTED_MESSAGE: string;
|
|
51
|
+
/**
|
|
52
|
+
* ← `WebSocket::Accepted` (`web-socket.h:~300-360`), reached through
|
|
53
|
+
* `accept()` → `internalAccept(js, IoContext::current().getCriticalSection())`
|
|
54
|
+
* → `startReadLoop` (`web-socket.c++:133`, `:426`, `:429-433`, `:507`).
|
|
55
|
+
*
|
|
56
|
+
* An `EventTarget`, so a consumer registers listeners the way it would on a real
|
|
57
|
+
* socket — but on THIS object rather than on the raw one, because this is what
|
|
58
|
+
* runs them inside a gated slice.
|
|
59
|
+
*/
|
|
60
|
+
export declare class AcceptedWebSocket extends EventTarget {
|
|
61
|
+
#private;
|
|
62
|
+
onopen: ((event: Event) => void) | null;
|
|
63
|
+
onmessage: ((event: MessageEvent) => void) | null;
|
|
64
|
+
onclose: ((event: CloseEvent) => void) | null;
|
|
65
|
+
onerror: ((event: Event) => void) | null;
|
|
66
|
+
constructor(ctx: IoContext, socket: RawWebSocket);
|
|
67
|
+
/**
|
|
68
|
+
* ← `WebSocket::send` (`web-socket.c++:~640`), which inserts a
|
|
69
|
+
* `GatedMessage{IoContext::current().waitForOutputLocksIfNecessary(), …}`.
|
|
70
|
+
*
|
|
71
|
+
* Synchronous, as upstream's is: the wait is the pump's, not the caller's. The
|
|
72
|
+
* output gate is what "blocks all outgoing messages from an actor that would
|
|
73
|
+
* allow the rest of the world to observe the actor's state" (§1.1), and a
|
|
74
|
+
* socket frame is exactly such a message.
|
|
75
|
+
*
|
|
76
|
+
* `waitForOutputLocksIfNecessary()` collapses to `waitForOutputLocks()` here
|
|
77
|
+
* for the reason the whole file collapses `kj::Maybe<Worker::Actor&>`: its
|
|
78
|
+
* body is `actor.map(…)` (`io-context.c++:383-386`) and every context in this
|
|
79
|
+
* runtime is an actor context.
|
|
80
|
+
*/
|
|
81
|
+
send(data: string | ArrayBufferLike | ArrayBufferView | Blob): void;
|
|
82
|
+
/** ← `WebSocket::close`, which enqueues a `Close` through the same gate. */
|
|
83
|
+
close(code?: number, reason?: string): void;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* ← `accept()` / `state.acceptWebSocket()`, as the one verb.
|
|
87
|
+
*
|
|
88
|
+
* Named for what upstream names it, because the critical-section capture is a
|
|
89
|
+
* property of accepting rather than of constructing: "a socket accepted inside a
|
|
90
|
+
* `blockConcurrencyWhile` delivers its messages inside that critical section"
|
|
91
|
+
* (§1.8).
|
|
92
|
+
*/
|
|
93
|
+
export declare function acceptWebSocket(ctx: IoContext, socket: RawWebSocket): AcceptedWebSocket;
|