@solidrt/flux-types 0.0.11 → 0.0.14

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.
@@ -0,0 +1,197 @@
1
+ declare module "flux:http" {
2
+ /** Path parameters captured from a route pattern (e.g. ":page"). */
3
+ type RouteParams = Record<string, string>
4
+
5
+ /**
6
+ * The request passed to a handler: a standard {@link Request} plus the route
7
+ * params captured from the matched pattern.
8
+ */
9
+ type FluxRequest = Request & {
10
+ /**
11
+ * Route params from the matched pattern (e.g. `:page` -> `params.page`). An
12
+ * empty object for the `fetch` fallback, which matches no pattern.
13
+ */
14
+ params: RouteParams
15
+ }
16
+
17
+ /**
18
+ * What a handler may return: a string (sent as a 200 text response), a
19
+ * {@link Response}, or a promise of either. Returning nothing is only valid
20
+ * after `server.upgrade(req)` accepted a websocket; otherwise it becomes a 500.
21
+ */
22
+ type HandlerResult = string | Response | void | Promise<string | Response | void>
23
+
24
+ /**
25
+ * Handles a matched route or the `fetch` fallback. Receives the request (with
26
+ * captured `params`) and the running {@link Server}.
27
+ */
28
+ type RouteHandler = (req: FluxRequest, server: Server) => HandlerResult
29
+
30
+ /**
31
+ * A per-method route object, e.g. `{ GET, POST }`. A request whose method has
32
+ * no entry gets a 405 with an `Allow` header listing the defined methods.
33
+ */
34
+ type MethodRoutes = {
35
+ GET?: RouteHandler
36
+ HEAD?: RouteHandler
37
+ POST?: RouteHandler
38
+ PUT?: RouteHandler
39
+ DELETE?: RouteHandler
40
+ PATCH?: RouteHandler
41
+ OPTIONS?: RouteHandler
42
+ }
43
+
44
+ /**
45
+ * A value in the route table: a handler function, a static {@link Response}
46
+ * (snapshotted once at registration and served on every request), or a
47
+ * per-method object.
48
+ */
49
+ type Route = RouteHandler | Response | MethodRoutes
50
+
51
+ /**
52
+ * The per-connection socket handle passed to the `websocket` callbacks.
53
+ * Returned send/publish counts are the bytes (or sockets) queued.
54
+ */
55
+ type ServerWebSocket = {
56
+ /**
57
+ * Arbitrary value attached via `upgrade(req, { data })`; `undefined` when
58
+ * none was given. Settable.
59
+ */
60
+ data: any
61
+ /**
62
+ * Queue a message: a string sends a text frame, a Uint8Array a binary frame.
63
+ * Returns the bytes queued, 0 if the socket is no longer open, or -1 when the
64
+ * queue exceeds `backpressureLimit` (the message is still queued and `drain`
65
+ * fires once the queue empties).
66
+ */
67
+ send(data: string | Uint8Array): number
68
+ /**
69
+ * Send a ping control frame; the peer's reply surfaces in the `pong`
70
+ * callback. Payload must be 125 bytes or fewer. Same return values as `send`.
71
+ */
72
+ ping(data?: string | Uint8Array): number
73
+ /** Send an unsolicited pong control frame (125 bytes or fewer). */
74
+ pong(data?: string | Uint8Array): number
75
+ /**
76
+ * Join a topic; `server.publish(topic)` and peers' `ws.publish(topic)` then
77
+ * reach this socket. No-op on a closing or closed socket.
78
+ */
79
+ subscribe(topic: string): void
80
+ /** Leave a topic. Closing the socket unsubscribes everything automatically. */
81
+ unsubscribe(topic: string): void
82
+ /** Whether this socket is currently subscribed to `topic`. */
83
+ isSubscribed(topic: string): boolean
84
+ /**
85
+ * Publish to every subscriber of `topic` except this socket. Returns the
86
+ * number of sockets the message was queued to.
87
+ */
88
+ publish(topic: string, data: string | Uint8Array): number
89
+ /**
90
+ * Send a close frame (default code 1000). The connection finishes once the
91
+ * peer echoes the close, or the grace period expires.
92
+ */
93
+ close(code?: number, reason?: string): void
94
+ /** Connection state: CONNECTING 0, OPEN 1, CLOSING 2, CLOSED 3. */
95
+ readonly readyState: number
96
+ }
97
+
98
+ /**
99
+ * The `websocket` serve option: per-server socket lifecycle callbacks, shared
100
+ * by every connection. Incoming pings are answered automatically by the
101
+ * protocol layer and never surface (so there is no `ping` callback).
102
+ */
103
+ type WebSocketHandlers = {
104
+ /** Fired once a connection is established (after `server.upgrade`). */
105
+ open?(ws: ServerWebSocket): void
106
+ /** Fired for each text (string) or binary (Uint8Array) message. */
107
+ message?(ws: ServerWebSocket, data: string | Uint8Array): void
108
+ /** Fired when a backpressured send queue empties. */
109
+ drain?(ws: ServerWebSocket): void
110
+ /** Fired when the peer replies to a `ws.ping()`. */
111
+ pong?(ws: ServerWebSocket, data: Uint8Array): void
112
+ /** Fired once when the connection closes, with the close code and reason. */
113
+ close?(ws: ServerWebSocket, code: number, reason: string): void
114
+ /**
115
+ * Queue-size threshold (bytes) at which `send` returns -1 and `drain` later
116
+ * fires. Defaults to the runtime's built-in limit.
117
+ */
118
+ backpressureLimit?: number
119
+ }
120
+
121
+ /** Options for {@link Server.upgrade}. */
122
+ type UpgradeOptions = {
123
+ /** Becomes `ws.data` on the upgraded socket. */
124
+ data?: any
125
+ /**
126
+ * Extra headers appended to the 101 response (e.g. `Set-Cookie`). An invalid
127
+ * header fails the upgrade.
128
+ */
129
+ headers?: Record<string, string> | Headers
130
+ }
131
+
132
+ type Server = {
133
+ /** The bound port. */
134
+ readonly port: number
135
+ /** The bound hostname/interface. */
136
+ readonly hostname: string
137
+ /** The server's base URL, e.g. `"http://0.0.0.0:3000/"`. */
138
+ readonly url: string
139
+ /**
140
+ * Accept a websocket handshake for `req`. On `true` the handler must return
141
+ * nothing: the held 101 response is sent when it returns and the `websocket`
142
+ * callbacks take over. `false` means the request cannot upgrade (not a
143
+ * websocket request, already upgraded, or no `websocket` option), so the
144
+ * handler can serve a normal response instead.
145
+ */
146
+ upgrade(req: FluxRequest, opts?: UpgradeOptions): boolean
147
+ /**
148
+ * Publish a message to every socket subscribed to `topic`. Returns the number
149
+ * of sockets the message was queued to.
150
+ */
151
+ publish(topic: string, data: string | Uint8Array): number
152
+ /** How many sockets are currently subscribed to `topic`. */
153
+ subscriberCount(topic: string): number
154
+ /**
155
+ * Stop accepting new connections and gracefully shut down open ones. Safe to
156
+ * call more than once.
157
+ */
158
+ stop(): void
159
+ }
160
+
161
+ type ServeOptions = {
162
+ /** Port to listen on. */
163
+ port: number
164
+ /** Hostname/interface to bind. Defaults to "0.0.0.0" (all interfaces). */
165
+ hostname?: string
166
+ /**
167
+ * Route table keyed by path pattern. Patterns may contain `:name` segments,
168
+ * exposed on `req.params`. Each value is a handler function, a static
169
+ * {@link Response}, or a per-method object.
170
+ */
171
+ routes?: Record<string, Route>
172
+ /**
173
+ * Fallback handler for requests no route matched. Without it (and with no
174
+ * matching route), unmatched requests get a 404.
175
+ */
176
+ fetch?: RouteHandler
177
+ /**
178
+ * Handles a throw or rejection from a handler; its result becomes the
179
+ * response. Without it, a handler error becomes a plaintext 500.
180
+ */
181
+ error?: (error: any) => string | Response | Promise<string | Response>
182
+ /**
183
+ * WebSocket lifecycle callbacks. Providing this enables `server.upgrade()`;
184
+ * without it `upgrade()` always returns false.
185
+ */
186
+ websocket?: WebSocketHandlers
187
+ }
188
+
189
+ /**
190
+ * Start an HTTP server. Loosely models Bun's `Bun.serve`.
191
+ *
192
+ * @param options Port, hostname, routes, fetch fallback, error handler, and
193
+ * websocket callbacks.
194
+ * @returns The running {@link Server}.
195
+ */
196
+ export function serve(options: ServeOptions): Server
197
+ }
@@ -0,0 +1,54 @@
1
+ declare module "flux:mdns" {
2
+ /** Options common to {@link resolve}, {@link browse}, and {@link services}. */
3
+ type MdnsOptions = {
4
+ /** How long (ms) to collect multicast answers before resolving. Default 1500. */
5
+ timeoutMs?: number
6
+ }
7
+
8
+ /** A reverse-resolved address, from {@link resolve}. */
9
+ type Resolved = {
10
+ /** The queried IPv4 address. */
11
+ ip: string
12
+ /** Its mDNS hostname, e.g. "printer.local". */
13
+ host: string
14
+ }
15
+
16
+ /** One discovered DNS-SD service instance, from {@link browse}. */
17
+ type ServiceInstance = {
18
+ /** The human instance label, e.g. "Office Printer". */
19
+ instance: string
20
+ /** The service type, e.g. "_ipp._tcp". */
21
+ service: string
22
+ /** The target host the SRV record points at, e.g. "printer.local". */
23
+ host: string
24
+ /** The advertised port. */
25
+ port: number
26
+ /** A/AAAA addresses for `host`, when the responder bundled them. */
27
+ addrs: string[]
28
+ /** TXT attributes (a bare flag attribute has an empty-string value). */
29
+ txt: Record<string, string>
30
+ }
31
+
32
+ /**
33
+ * Reverse-resolve IPv4 addresses to their mDNS `.local` hostnames over the
34
+ * link-local multicast group (a PTR query against `in-addr.arpa`). `.local`
35
+ * names are mDNS, not unicast DNS, so this works with no `nss-mdns` resolver and
36
+ * no external binary. Addresses that do not answer within the window — and any
37
+ * IPv6 inputs — are simply absent from the result; an empty input resolves to
38
+ * `[]` without touching the network. Needs a Bonjour/avahi responder on the LAN.
39
+ */
40
+ export function resolve(ips: string[], opts?: MdnsOptions): Promise<Resolved[]>
41
+
42
+ /**
43
+ * Browse a DNS-SD service type for the instances on the LAN. `service` may be
44
+ * bare (`"_http._tcp"`) or fully qualified. Resolves to `[]` if nothing answers
45
+ * within the window.
46
+ */
47
+ export function browse(service: string, opts?: MdnsOptions): Promise<ServiceInstance[]>
48
+
49
+ /**
50
+ * Enumerate the service types advertised on the LAN (the
51
+ * `_services._dns-sd._udp.local` meta-query), e.g. `["_http._tcp", "_ipp._tcp"]`.
52
+ */
53
+ export function services(opts?: MdnsOptions): Promise<string[]>
54
+ }
@@ -0,0 +1,139 @@
1
+ declare module "flux:net" {
2
+ /** Options for {@link probe} and {@link connect}. */
3
+ type ConnectOptions = {
4
+ /** Give up after this many ms. Default 1000 for {@link probe}, 10000 for {@link connect}. */
5
+ timeoutMs?: number
6
+ }
7
+
8
+ /** Options for {@link listen}. */
9
+ type ListenOptions = {
10
+ /** Local address to bind. Default "0.0.0.0" (all interfaces). */
11
+ host?: string
12
+ }
13
+
14
+ /** Options for {@link udp}. */
15
+ type UdpOptions = {
16
+ /** Local port to bind. Default 0 (OS-assigned). */
17
+ port?: number
18
+ /** Set SO_REUSEADDR/REUSEPORT so several sockets can share the port. */
19
+ reuse?: boolean
20
+ }
21
+
22
+ /**
23
+ * Outcome of a {@link probe}. `closed` (a refusal) still means the host is up —
24
+ * something answered; only `filtered` (a timeout/unreachable) is no evidence.
25
+ */
26
+ type Liveness = "open" | "closed" | "filtered"
27
+
28
+ /** One address on a {@link NetInterface}. */
29
+ type InterfaceAddr = {
30
+ /** The IP address. */
31
+ ip: string
32
+ /** CIDR prefix length (e.g. 24). */
33
+ prefix: number
34
+ /** Address family. */
35
+ family: "v4" | "v6"
36
+ }
37
+
38
+ /** A local network interface, from {@link interfaces}. */
39
+ type NetInterface = {
40
+ /** Interface name, e.g. "wlan0". */
41
+ name: string
42
+ /** Hardware (MAC) address, or `null` if none. */
43
+ mac: string | null
44
+ /** Whether the interface is up. */
45
+ up: boolean
46
+ /** Whether it is a loopback interface. */
47
+ loopback: boolean
48
+ /** Whether it supports multicast. */
49
+ multicast: boolean
50
+ /** The interface's bound addresses. */
51
+ addrs: InterfaceAddr[]
52
+ }
53
+
54
+ /** A received datagram, from {@link Udp.recv}. */
55
+ type Datagram = {
56
+ /** The payload bytes. */
57
+ data: Uint8Array
58
+ /** Sender IP. */
59
+ host: string
60
+ /** Sender port. */
61
+ port: number
62
+ }
63
+
64
+ /**
65
+ * A connected TCP stream: a byte duplex. It is its own async iterator, so
66
+ * `for await (let chunk of conn)` reads it until end-of-stream.
67
+ */
68
+ export class Conn implements AsyncIterable<Uint8Array> {
69
+ /** The remote peer's address, e.g. "192.168.2.37:445". */
70
+ readonly peer: string
71
+ /** Write all of `data`. Resolves once it is handed to the OS. */
72
+ write(data: string | Uint8Array): Promise<void>
73
+ /** Stop reading and close the connection. */
74
+ close(): void
75
+ [Symbol.asyncIterator](): AsyncIterator<Uint8Array>
76
+ }
77
+
78
+ /**
79
+ * A bound TCP listener: an async-iterable of incoming connections, so
80
+ * `for await (let conn of listener)` accepts them. Drop it to stop.
81
+ */
82
+ export class Listener implements AsyncIterable<Conn> {
83
+ /** The bound local address (with the OS-assigned port when 0 was requested). */
84
+ readonly localAddr: string
85
+ [Symbol.asyncIterator](): AsyncIterator<Conn>
86
+ }
87
+
88
+ /** A bound UDP socket with the broadcast/multicast controls a peer beacon needs. */
89
+ export class Udp {
90
+ /** The bound local address (with the OS-assigned port when 0 was requested). */
91
+ readonly localAddr: string
92
+ /** Send a datagram to `host:port` — a unicast peer, a broadcast address, or a multicast group. */
93
+ send(data: string | Uint8Array, host: string, port: number): Promise<void>
94
+ /** Receive the next datagram. */
95
+ recv(): Promise<Datagram>
96
+ /** Allow sending to the broadcast address (SO_BROADCAST). */
97
+ setBroadcast(on: boolean): void
98
+ /** TTL for outgoing multicast (1 keeps it on the local link). */
99
+ setMulticastTtl(ttl: number): void
100
+ /** Whether multicast this socket sends loops back to sockets on this host. */
101
+ setMulticastLoop(on: boolean): void
102
+ /**
103
+ * Join multicast `group` on the interface with address `iface`
104
+ * (default "0.0.0.0", OS-chosen). Required to receive that group's datagrams.
105
+ */
106
+ joinMulticast(group: string, iface?: string): void
107
+ /** Leave a multicast group previously joined with {@link joinMulticast}. */
108
+ leaveMulticast(group: string, iface?: string): void
109
+ }
110
+
111
+ /**
112
+ * Probe `host:port` with a TCP connect and report what it says about the host.
113
+ * Infallible — every outcome maps to a {@link Liveness}, so a sweep never has to
114
+ * catch. The connect-scan primitive: count `open` or `closed` as a live host.
115
+ *
116
+ * @param opts timeoutMs (default 1000).
117
+ */
118
+ export function probe(host: string, port: number, opts?: ConnectOptions): Promise<Liveness>
119
+
120
+ /**
121
+ * Open a TCP connection. Unlike {@link probe} this returns a live {@link Conn}
122
+ * for app protocols / banner grabs.
123
+ *
124
+ * @param opts timeoutMs (default 10000).
125
+ */
126
+ export function connect(host: string, port: number, opts?: ConnectOptions): Promise<Conn>
127
+
128
+ /** Bind a TCP {@link Listener} on `port` (0 = OS-assigned). */
129
+ export function listen(port: number, opts?: ListenOptions): Promise<Listener>
130
+
131
+ /** Bind a {@link Udp} socket. */
132
+ export function udp(opts?: UdpOptions): Promise<Udp>
133
+
134
+ /**
135
+ * Enumerate local network interfaces and their addresses — the no-subprocess
136
+ * way to find the subnet to scan (replaces parsing `ip addr`). Synchronous.
137
+ */
138
+ export function interfaces(): NetInterface[]
139
+ }
@@ -0,0 +1,85 @@
1
+ declare module "flux:p2p" {
2
+ /** Options for {@link Endpoint.create}. */
3
+ type EndpointOptions = {
4
+ /**
5
+ * 64 hex chars (32 bytes) for a stable identity across restarts. Omit for an
6
+ * ephemeral key.
7
+ */
8
+ secretKey?: string
9
+ /** A self-hosted relay URL. Omit to use the public n0 relays. */
10
+ relayUrl?: string
11
+ /** Protocols this endpoint will {@link Endpoint.accept}. */
12
+ protocols?: string[]
13
+ }
14
+
15
+ /** One transport address from {@link Endpoint.connInfo}. */
16
+ type ConnAddr = {
17
+ /** "relay", "direct" (an IP path), or "custom". */
18
+ kind: "relay" | "direct" | "custom"
19
+ /** The address string. */
20
+ addr: string
21
+ /** Whether this path is currently active. */
22
+ active: boolean
23
+ }
24
+
25
+ /** A snapshot of how a connection is currently carried. */
26
+ type ConnInfo = {
27
+ /**
28
+ * "direct" (a direct IP path is active), "relay" (only a relay path),
29
+ * "mixed" (both), or "none".
30
+ */
31
+ path: "direct" | "relay" | "mixed" | "none"
32
+ /** Every known transport address. */
33
+ addrs: ConnAddr[]
34
+ }
35
+
36
+ /**
37
+ * A single bidirectional p2p stream: a byte duplex. It is its own async
38
+ * iterator, so `for await (let chunk of stream)` reads the recv half.
39
+ */
40
+ export class P2pStream implements AsyncIterable<Uint8Array> {
41
+ /** The remote peer's endpoint id. */
42
+ readonly remoteId: string
43
+ /** Queue bytes on the send half. */
44
+ write(data: string | Uint8Array): void
45
+ /** Finish the send half (QUIC FIN) after queued writes flush. The recv half stays open. */
46
+ finish(): void
47
+ /** Tear the stream down: finish the send half and stop reading. */
48
+ close(): void
49
+ [Symbol.asyncIterator](): AsyncIterator<Uint8Array>
50
+ }
51
+
52
+ /** A bound iroh endpoint with a stable keypair. */
53
+ export class Endpoint {
54
+ /**
55
+ * Bind an endpoint.
56
+ *
57
+ * @param opts secretKey, relayUrl, protocols.
58
+ */
59
+ static create(opts?: EndpointOptions): Promise<Endpoint>
60
+ /** This endpoint's dial address: the string peers pass to {@link connect}. */
61
+ readonly id: string
62
+ /** The secret key as 64 hex chars, for the caller to persist and feed back to {@link create}. */
63
+ readonly secretKey: string
64
+ /**
65
+ * A self-contained dial token (`id|relay|ips`) so a peer can {@link connect}
66
+ * without relying on discovery.
67
+ */
68
+ ticket(): Promise<string>
69
+ /**
70
+ * Dial a peer and open one bidirectional stream over `protocol`. `peer` is
71
+ * either a `ticket` (preferred; connects directly) or a bare endpoint `id`
72
+ * (needs discovery to resolve the address).
73
+ */
74
+ connect(peer: string, protocol: string): Promise<P2pStream>
75
+ /**
76
+ * An async-iterable of incoming streams whose protocol matches `protocol`.
77
+ * Iterating ends when the endpoint is closed.
78
+ */
79
+ accept(protocol: string): AsyncIterable<P2pStream>
80
+ /** Snapshot of how the connection to `id` is currently carried. */
81
+ connInfo(id: string): Promise<ConnInfo>
82
+ /** Close the endpoint, ending any {@link accept} iteration. */
83
+ close(): Promise<void>
84
+ }
85
+ }
@@ -0,0 +1,26 @@
1
+ declare module "flux:path" {
2
+ /**
3
+ * Resolves `path` against the trusted base directory `base`, returning the
4
+ * absolute result only if it stays inside `base`; otherwise `null`. Fusing
5
+ * normalization and containment means a `..`-laden or absolute `path` that
6
+ * would escape `base` is rejected rather than silently resolved.
7
+ *
8
+ * Purely lexical: it does not resolve symlinks, so a symlink inside `base`
9
+ * pointing out of it is not caught.
10
+ *
11
+ * @param base Trusted root directory. Relative values resolve against cwd.
12
+ * @param path Untrusted path to place within `base`.
13
+ * @returns The contained absolute path, or `null` if it would escape `base`.
14
+ *
15
+ * @example
16
+ * let target = resolveWithin(".", req.params.page)
17
+ * if (!target) return new Response("Not found", { status: 404 })
18
+ */
19
+ export function resolveWithin(base: string, path: string): string | null
20
+
21
+ /**
22
+ * Joins and normalizes path `segments`. Lexical only, with no containment
23
+ * guarantee; use `resolveWithin` when a segment is untrusted.
24
+ */
25
+ export function join(...segments: string[]): string
26
+ }
@@ -0,0 +1,36 @@
1
+ declare module "flux:process" {
2
+ /**
3
+ * The program's command-line arguments. `argv[0]` is the script path;
4
+ * `argv[1]` onward are the user-supplied arguments.
5
+ */
6
+ export let argv: string[]
7
+ /** The host OS: "darwin", "win32", "linux", "android", ... */
8
+ export let platform: string
9
+ /** The CPU architecture: "x64", "arm64", ... */
10
+ export let arch: string
11
+ /**
12
+ * Current-process memory usage. `rss` is the resident set size in bytes.
13
+ * (Node also reports heapTotal/heapUsed/external/arrayBuffers; only rss is
14
+ * provided for now.)
15
+ */
16
+ export function memoryUsage(): { rss: number }
17
+ /**
18
+ * Listen for an OS signal. The callback receives the signal name. Returns an
19
+ * unsubscribe function. Unix only; a no-op elsewhere.
20
+ *
21
+ * @param signal One of "SIGINT", "SIGTERM", "SIGHUP", "SIGQUIT", "SIGUSR1",
22
+ * "SIGUSR2".
23
+ * @param callback Invoked on each delivery with the signal name.
24
+ * @returns An unsubscribe function.
25
+ */
26
+ export function on(signal: string, callback: (signal: string) => void): () => void
27
+ /**
28
+ * Like {@link on}, but the listener fires at most once and then unsubscribes.
29
+ *
30
+ * @param signal One of "SIGINT", "SIGTERM", "SIGHUP", "SIGQUIT", "SIGUSR1",
31
+ * "SIGUSR2".
32
+ * @param callback Invoked once with the signal name.
33
+ * @returns An unsubscribe function.
34
+ */
35
+ export function once(signal: string, callback: (signal: string) => void): () => void
36
+ }
@@ -0,0 +1,53 @@
1
+ declare module "flux:sqlite" {
2
+ /** Values accepted as bound parameters. booleans bind as 0/1. */
3
+ type SqlParam = null | boolean | number | string | Uint8Array
4
+ /** Values returned in result rows. BLOB comes back as Uint8Array. */
5
+ type SqlValue = null | number | string | Uint8Array
6
+ type Row = Record<string, SqlValue>
7
+
8
+ /** The outcome of a write. */
9
+ type RunResult = { changes: number; lastInsertRowid: number }
10
+
11
+ /**
12
+ * A reusable prepared statement. Created with {@link Database.query}; its
13
+ * executions reuse the compiled statement (cached on the connection).
14
+ */
15
+ export class Statement {
16
+ /** Run the statement and resolve to all matching rows. */
17
+ all(params?: SqlParam[]): Promise<Row[]>
18
+ /** Run the statement and resolve to the first row, or `undefined`. */
19
+ get(params?: SqlParam[]): Promise<Row | undefined>
20
+ /** Run the statement as a write and resolve to its {@link RunResult}. */
21
+ run(params?: SqlParam[]): Promise<RunResult>
22
+ }
23
+
24
+ /**
25
+ * Open mode: "ro" (default, read-only, must exist), "rw" (read-write, must
26
+ * exist), "rw+" (read-write, create if missing).
27
+ */
28
+ type OpenMode = "ro" | "rw" | "rw+"
29
+
30
+ export class Database {
31
+ /**
32
+ * Open a connection to the database at `path`.
33
+ *
34
+ * @param path Database file path.
35
+ * @param mode Open mode; defaults to "ro".
36
+ */
37
+ static connect(path: string, mode?: OpenMode): Promise<Database>
38
+ /** Create a reusable prepared statement (synchronous; compiles on first run). */
39
+ query(sql: string): Statement
40
+ /** One-shot write; uses plain prepare (no caching). */
41
+ run(sql: string, params?: SqlParam[]): Promise<RunResult>
42
+ /** Run a multi-statement script (no params), e.g. schema setup / migrations. */
43
+ exec(sql: string): Promise<void>
44
+ /**
45
+ * Run a batch of [sql, params] statements in one transaction (BEGIN/COMMIT,
46
+ * ROLLBACK on any error). Resolves to one result per statement. Statements
47
+ * must be writes/DDL. Cannot branch on intermediate results.
48
+ */
49
+ transaction(statements: [string, SqlParam[]?][]): Promise<RunResult[]>
50
+ /** Close the connection. */
51
+ close(): Promise<void>
52
+ }
53
+ }
@@ -0,0 +1,89 @@
1
+ declare module "flux:subprocess" {
2
+ /** Options for {@link command}. */
3
+ type CommandOptions = {
4
+ /** Working directory for the child. */
5
+ cwd?: string
6
+ /** Extra env vars, added to / overriding the inherited environment. */
7
+ env?: Record<string, string>
8
+ /** Bytes written to the child's stdin, after which stdin is closed. */
9
+ stdin?: string | Uint8Array
10
+ /** Kill the child if it has not exited within this many milliseconds. */
11
+ timeoutMs?: number
12
+ /**
13
+ * "buffer" returns stdout/stderr as `Uint8Array`; the default returns them
14
+ * as UTF-8 strings.
15
+ */
16
+ encoding?: "buffer" | "utf8"
17
+ }
18
+
19
+ /** The buffered result of a child run to completion via {@link Command.output}. */
20
+ type CommandOutput = {
21
+ /** Exit code, or `null` if the child was killed by a signal. */
22
+ code: number | null
23
+ /** Signal name that killed the child (Unix), or `null`. */
24
+ signal: string | null
25
+ /** `true` when `code` is 0. */
26
+ success: boolean
27
+ /** Captured stdout. `Uint8Array` when `encoding` is "buffer", else a string. */
28
+ stdout: string | Uint8Array
29
+ /** Captured stderr. `Uint8Array` when `encoding` is "buffer", else a string. */
30
+ stderr: string | Uint8Array
31
+ }
32
+
33
+ /** The exit status of a spawned child (the {@link CommandOutput} shape without buffered streams). */
34
+ type CommandStatus = {
35
+ /** Exit code, or `null` if the child was killed by a signal. */
36
+ code: number | null
37
+ /** Signal name that killed the child (Unix), or `null`. */
38
+ signal: string | null
39
+ /** `true` when `code` is 0. */
40
+ success: boolean
41
+ }
42
+
43
+ /** A running child process, returned by {@link Command.spawn}. */
44
+ type Child = {
45
+ /** The OS process id, if available. */
46
+ pid: number | undefined
47
+ /** Live stdout as an async-iterable of byte chunks. */
48
+ stdout: AsyncIterable<Uint8Array>
49
+ /** Live stderr as an async-iterable of byte chunks. */
50
+ stderr: AsyncIterable<Uint8Array>
51
+ /** Queue bytes to the child's stdin. Writes serialize and respect backpressure. */
52
+ write(data: string | Uint8Array): Promise<void>
53
+ /** Close the child's stdin (after queued writes drain) so it sees EOF. */
54
+ endStdin(): Promise<void>
55
+ /** Request termination (portable; SIGKILL / TerminateProcess). */
56
+ kill(): void
57
+ /** Resolves with the exit status when the child exits. */
58
+ status(): Promise<CommandStatus>
59
+ }
60
+
61
+ /** A parsed, reusable command spec. Created with {@link command}; runnable more than once. */
62
+ type Command = {
63
+ cmd: string
64
+ args: string[]
65
+ /** Run the child to completion, buffering stdout/stderr. */
66
+ output(): Promise<CommandOutput>
67
+ /** Spawn the child and return a handle with live streams, stdin, and control. */
68
+ spawn(): Child
69
+ }
70
+
71
+ /**
72
+ * Build a command. Arguments are always passed as an array and never through a
73
+ * shell, so there is no shell quoting or injection to reason about, and the JS
74
+ * is identical on every OS.
75
+ *
76
+ * @param cmd The program to run.
77
+ * @param args Arguments, passed verbatim (no shell).
78
+ * @param opts cwd, env, stdin, timeoutMs, encoding.
79
+ */
80
+ export function command(cmd: string, args?: string[], opts?: CommandOptions): Command
81
+
82
+ /**
83
+ * Cross-platform PATH lookup (handles Windows PATHEXT / .exe).
84
+ *
85
+ * @param cmd Binary name to resolve.
86
+ * @returns The absolute path to the resolved executable, or `null` if not found.
87
+ */
88
+ export function which(cmd: string): string | null
89
+ }